mirror of
https://github.com/ctm/executor.git
synced 2024-11-27 01:49:33 +00:00
475 lines
12 KiB
C
475 lines
12 KiB
C
/* Copyright 1986-1996 by Abacus Research and
|
|
* Development, Inc. All rights reserved.
|
|
*/
|
|
|
|
#if !defined (OMIT_RCSID_STRINGS)
|
|
char ROMlib_rcsid_qCursor[] =
|
|
"$Id: qCursor.c 87 2005-05-25 01:57:33Z ctm $";
|
|
#endif
|
|
|
|
/* Forward declarations in QuickDraw.h (DO NOT DELETE THIS LINE) */
|
|
|
|
#include "rsys/common.h"
|
|
#include "QuickDraw.h"
|
|
/* ack */
|
|
#include "WindowMgr.h"
|
|
#include "CQuickDraw.h"
|
|
#include "EventMgr.h"
|
|
#include "OSEvent.h"
|
|
#include "MemoryMgr.h"
|
|
|
|
#include "rsys/notmac.h"
|
|
#include "rsys/cquick.h"
|
|
#include "rsys/mman.h"
|
|
#include "rsys/resource.h"
|
|
#include "rsys/host.h"
|
|
|
|
#include "rsys/osevent.h"
|
|
|
|
#include "rsys/quick.h"
|
|
|
|
#if !defined (CURSOR_DEBUG)
|
|
|
|
#define HOST_SET_CURSOR(d,m,x,y) host_set_cursor (d,m,x,y)
|
|
|
|
#else
|
|
|
|
#include "rsys/dirtyrect.h"
|
|
#include "rsys/vdriver.h"
|
|
|
|
PRIVATE void
|
|
cursor_debug (const uint8 *datap, const uint8 *maskp, int hot_x, int hot_y)
|
|
{
|
|
int y;
|
|
uint8 *pixel;
|
|
int offset;
|
|
|
|
pixel = vdriver_fbuf;
|
|
offset = vdriver_row_bytes - 16;
|
|
for (y = 0; y < 16; ++y)
|
|
{
|
|
uint16 u, bit;
|
|
|
|
u = *datap++;
|
|
u = (u << 8) | *datap++;
|
|
for (bit = 1 << 15; bit; bit >>= 1)
|
|
*pixel++ = u & bit ? 0 : 255;
|
|
pixel += offset;
|
|
}
|
|
dirty_rect_accrue (0, 0, 16, 16);
|
|
dirty_rect_update_screen ();
|
|
vdriver_flush_display();
|
|
}
|
|
|
|
#define HOST_SET_CURSOR(d,m,x,y) \
|
|
do \
|
|
{ \
|
|
cursor_debug (d, m, x, y); \
|
|
host_set_cursor (d, m, x, y); \
|
|
} \
|
|
while (FALSE)
|
|
|
|
#endif
|
|
|
|
|
|
static CCrsrHandle current_ccrsr;
|
|
static Cursor current_crsr;
|
|
|
|
static boolean_t current_cursor_valid_p = FALSE;
|
|
static int current_cursor_color_p;
|
|
|
|
void
|
|
cursor_reset_current_cursor (void)
|
|
{
|
|
current_cursor_valid_p = FALSE;
|
|
if (current_cursor_color_p)
|
|
SetCCursor (current_ccrsr);
|
|
else
|
|
SetCursor (¤t_crsr);
|
|
}
|
|
|
|
A0 (PUBLIC, void, ROMlib_showcursor)
|
|
{
|
|
if (!CrsrVis)
|
|
{
|
|
host_set_cursor_visible (TRUE);
|
|
CrsrVis = TRUE;
|
|
}
|
|
}
|
|
|
|
A0 (PUBLIC, void, ROMlib_restorecursor)
|
|
{
|
|
if (CrsrVis)
|
|
{
|
|
host_set_cursor_visible (FALSE);
|
|
CrsrVis = FALSE;
|
|
}
|
|
}
|
|
|
|
A0(PUBLIC, void, ROMlib_showhidecursor) /* INTERNAL */
|
|
{
|
|
if (CrsrState == 0)
|
|
ROMlib_showcursor();
|
|
else
|
|
ROMlib_restorecursor();
|
|
}
|
|
|
|
P1(PUBLIC pascal trap, void, SetCursor, Cursor *, cp)
|
|
{
|
|
if (current_cursor_valid_p
|
|
&& !current_cursor_color_p
|
|
&& ! memcmp (¤t_crsr, cp, sizeof (Cursor)))
|
|
return;
|
|
|
|
if (host_cursor_depth == 1)
|
|
{
|
|
HOST_SET_CURSOR ((char *) cp->data, (unsigned short *) cp->mask,
|
|
CW (cp->hotSpot.h), CW (cp->hotSpot.v));
|
|
}
|
|
else
|
|
{
|
|
PixMap data_pixmap, target_pixmap;
|
|
char *data_baseaddr;
|
|
/* rowbytes of expanded cursor data */
|
|
int rowbytes;
|
|
|
|
data_pixmap.baseAddr = RM ((Ptr) cp->data);
|
|
data_pixmap.rowBytes = CWC (2);
|
|
data_pixmap.bounds = ROMlib_cursor_rect;
|
|
data_pixmap.cmpCount = CWC (1);
|
|
data_pixmap.pixelType = CWC (0);
|
|
data_pixmap.pixelSize = data_pixmap.cmpSize = CWC (1);
|
|
data_pixmap.pmTable = RM (validate_relative_bw_ctab ());
|
|
|
|
rowbytes = (16 * host_cursor_depth) / 8;
|
|
data_baseaddr = alloca (16 * rowbytes);
|
|
|
|
target_pixmap.baseAddr = (Ptr) RM (data_baseaddr);
|
|
target_pixmap.rowBytes = CWC (rowbytes);
|
|
target_pixmap.bounds = ROMlib_cursor_rect;
|
|
target_pixmap.cmpCount = CWC (1);
|
|
target_pixmap.pixelType = CWC (0);
|
|
target_pixmap.pixelSize = target_pixmap.cmpSize
|
|
= CW (host_cursor_depth);
|
|
/* the target pixmap colortable is not used by `convert_pixmap ()'
|
|
target_pixmap.pmTable = ...; */
|
|
|
|
convert_pixmap (&data_pixmap, &target_pixmap,
|
|
&ROMlib_cursor_rect, NULL);
|
|
|
|
HOST_SET_CURSOR (data_baseaddr, (unsigned short *) cp->mask,
|
|
CW (cp->hotSpot.h), CW (cp->hotSpot.v));
|
|
}
|
|
|
|
current_crsr = *cp;
|
|
current_cursor_color_p = FALSE;
|
|
current_cursor_valid_p = TRUE;
|
|
|
|
if (CrsrState == 0)
|
|
{
|
|
CrsrVis = FALSE;
|
|
ROMlib_showcursor();
|
|
}
|
|
}
|
|
|
|
P0(PUBLIC pascal trap, void, InitCursor)
|
|
{
|
|
CrsrState = 0;
|
|
SetCursor(&arrowX);
|
|
CrsrVis = FALSE;
|
|
ROMlib_showcursor();
|
|
}
|
|
|
|
P0(PUBLIC pascal trap, void, HideCursor) /* IMI-168 */
|
|
{
|
|
ROMlib_restorecursor();
|
|
CrsrState = CW(CW(CrsrState) - 1);
|
|
}
|
|
|
|
P0(PUBLIC pascal trap, void, ShowCursor) /* IMI-168 */
|
|
{
|
|
if ( (CrsrState = CW(CW(CrsrState) + 1)) == 0 )
|
|
ROMlib_showcursor();
|
|
if (CW(CrsrState) > 0)
|
|
CrsrState = 0;
|
|
}
|
|
|
|
A1(PRIVATE, void, wewantpointermovements, INTEGER, x)
|
|
{
|
|
CrsrState = CW(CW(CrsrState) + x);
|
|
ROMlib_bewaremovement = TRUE;
|
|
}
|
|
|
|
P0(PUBLIC pascal trap, void, ObscureCursor) /* IMI-168 */
|
|
{
|
|
ROMlib_restorecursor();
|
|
wewantpointermovements(0);
|
|
}
|
|
|
|
P2(PUBLIC pascal trap, void, ShieldCursor, Rect *, rp, Point, p) /* IMI-474 */
|
|
{
|
|
EventRecord evt;
|
|
|
|
GetOSEvent(0, &evt);
|
|
evt.where.v = CW(evt.where.v) + p.v;
|
|
evt.where.h = CW(evt.where.h) + p.h;
|
|
if (PtInRect(evt.where, rp))
|
|
HideCursor();
|
|
else
|
|
wewantpointermovements(-1);
|
|
}
|
|
|
|
MAKE_HIDDEN(ccrsr_res_ptr);
|
|
typedef HIDDEN_ccrsr_res_ptr *ccrsr_res_handle;
|
|
|
|
P1 (PUBLIC pascal trap, CCrsrHandle, GetCCursor, INTEGER, crsr_id)
|
|
{
|
|
CCrsrHandle ccrsr_handle;
|
|
ccrsr_res_handle res_handle;
|
|
|
|
ccrsr_handle = (CCrsrHandle) NewHandle (sizeof (CCrsr));
|
|
|
|
res_handle = (ccrsr_res_handle) ROMlib_getrestid (TICK ("crsr"), crsr_id);
|
|
if (res_handle == NULL)
|
|
return NULL;
|
|
|
|
LOCK_HANDLE_EXCURSION_2
|
|
(ccrsr_handle, res_handle,
|
|
{
|
|
ccrsr_res_ptr resource;
|
|
CCrsrPtr ccrsr;
|
|
CTabPtr tmp_ctab;
|
|
int ccrsr_data_size;
|
|
int ccrsr_data_offset;
|
|
int ccrsr_ctab_size;
|
|
int ccrsr_ctab_offset;
|
|
|
|
int cursor_pixel_map_offset;
|
|
PixMapPtr cursor_pixel_map_resource;
|
|
PixMapHandle cursor_pixel_map;
|
|
|
|
Handle h;
|
|
|
|
resource = STARH (res_handle);
|
|
ccrsr = STARH (ccrsr_handle);
|
|
|
|
BlockMove ((Ptr) &resource->crsr, (Ptr) ccrsr,
|
|
sizeof (CCrsr));
|
|
|
|
/* NOTE: use CL below instead of MR because they're overloading
|
|
crsrMap to have an offset rather than a handle */
|
|
|
|
cursor_pixel_map_offset = CL ((uint32) ccrsr->crsrMap);
|
|
cursor_pixel_map_resource
|
|
= (PixMapPtr) ((char *) resource + cursor_pixel_map_offset);
|
|
|
|
cursor_pixel_map = NewPixMap ();
|
|
ccrsr->crsrMap = RM (cursor_pixel_map);
|
|
BlockMove ((Ptr) cursor_pixel_map_resource,
|
|
(Ptr) STARH (cursor_pixel_map),
|
|
sizeof *cursor_pixel_map_resource);
|
|
|
|
ccrsr_data_offset = CL ((long) ccrsr->crsrData);
|
|
|
|
ccrsr_ctab_offset = (int) PIXMAP_TABLE_AS_OFFSET (MR (ccrsr->crsrMap));
|
|
ccrsr_data_size = ccrsr_ctab_offset - ccrsr_data_offset;
|
|
|
|
ccrsr->crsrData = RM (NewHandle (ccrsr_data_size));
|
|
BlockMove ((Ptr) resource + ccrsr_data_offset,
|
|
STARH (MR (ccrsr->crsrData)),
|
|
ccrsr_data_size);
|
|
|
|
tmp_ctab = (CTabPtr) ((char *) resource + ccrsr_ctab_offset);
|
|
ccrsr_ctab_size = CTAB_STORAGE_FOR_SIZE (CW (tmp_ctab->ctSize));
|
|
h = RM (NewHandle (ccrsr_ctab_size));
|
|
PIXMAP_TABLE_X (MR (ccrsr->crsrMap)) = (CTabHandle) h;
|
|
BlockMove ((Ptr) tmp_ctab,
|
|
(Ptr) STARH (PIXMAP_TABLE (MR (ccrsr->crsrMap))),
|
|
ccrsr_ctab_size);
|
|
});
|
|
|
|
return ccrsr_handle;
|
|
}
|
|
|
|
Rect ROMlib_cursor_rect =
|
|
{
|
|
CWC (0), CWC (0), CWC (16), CWC (16),
|
|
};
|
|
|
|
/* ### this isn't a cursor specific routine, and it may be helpful
|
|
elsewhere, but since it isn't clear exactly what to compare, we'll
|
|
leave it here for now */
|
|
|
|
static boolean_t
|
|
pixmap_eq_p (PixMapHandle pm0, PixMapHandle pm1)
|
|
{
|
|
return (PIXMAP_PIXEL_SIZE_X (pm0) == PIXMAP_PIXEL_SIZE_X (pm1)
|
|
&& PIXMAP_PIXEL_TYPE_X (pm0) == PIXMAP_PIXEL_TYPE_X (pm1)
|
|
&& PIXMAP_CMP_COUNT_X (pm0) == PIXMAP_CMP_COUNT_X (pm1)
|
|
&& PIXMAP_CMP_SIZE_X (pm0) == PIXMAP_CMP_SIZE_X (pm1)
|
|
&& (CTAB_SEED_X
|
|
(PIXMAP_TABLE (pm0)) == CTAB_SEED_X (PIXMAP_TABLE (pm1)))
|
|
&& !memcmp (&PIXMAP_BOUNDS (pm0),
|
|
&PIXMAP_BOUNDS (pm1),
|
|
sizeof (Rect)));
|
|
}
|
|
|
|
P1 (PUBLIC pascal trap, void, SetCCursor,
|
|
CCrsrHandle, ccrsr)
|
|
{
|
|
if (current_cursor_valid_p
|
|
&& current_cursor_color_p)
|
|
{
|
|
int current_ccrsr_data_size, ccrsr_data_size;
|
|
|
|
current_ccrsr_data_size = GetHandleSize (CCRSR_DATA (current_ccrsr));
|
|
ccrsr_data_size = GetHandleSize (CCRSR_DATA (ccrsr));
|
|
|
|
if (current_ccrsr_data_size == ccrsr_data_size
|
|
&& !memcmp (STARH (CCRSR_DATA (current_ccrsr)),
|
|
STARH (CCRSR_DATA (ccrsr)),
|
|
ccrsr_data_size)
|
|
&& CCRSR_TYPE_X (current_ccrsr) == CCRSR_TYPE_X (ccrsr)
|
|
&& !memcmp (CCRSR_1DATA (current_ccrsr),
|
|
CCRSR_1DATA (ccrsr),
|
|
sizeof (Bits16))
|
|
&& !memcmp (CCRSR_MASK (current_ccrsr),
|
|
CCRSR_MASK (ccrsr),
|
|
sizeof (Bits16))
|
|
&& !memcmp (&CCRSR_HOT_SPOT (current_ccrsr),
|
|
&CCRSR_HOT_SPOT (ccrsr),
|
|
sizeof (Point))
|
|
&& pixmap_eq_p (CCRSR_MAP (current_ccrsr),
|
|
CCRSR_MAP (ccrsr)))
|
|
return;
|
|
}
|
|
|
|
LOCK_HANDLE_EXCURSION_1
|
|
((Handle) ccrsr,
|
|
{
|
|
GDHandle gdev;
|
|
PixMapHandle gd_pmap;
|
|
Point *hot_spot;
|
|
|
|
gdev = MR (MainDevice);
|
|
gd_pmap = GD_PMAP (gdev);
|
|
|
|
hot_spot = &CCRSR_HOT_SPOT (ccrsr);
|
|
|
|
if (host_cursor_depth > 2)
|
|
{
|
|
Handle ccrsr_xdata;
|
|
|
|
ccrsr_xdata = CCRSR_XDATA (ccrsr);
|
|
if (!ccrsr_xdata)
|
|
{
|
|
ccrsr_xdata = NewHandle (32 * host_cursor_depth);
|
|
CCRSR_XDATA_X (ccrsr) = RM (ccrsr_xdata);
|
|
}
|
|
|
|
if (CCRSR_XVALID_X (ccrsr) == CWC (0)
|
|
|| (CCRSR_XVALID (ccrsr) != host_cursor_depth)
|
|
|| (CCRSR_ID_X (ccrsr) != CTAB_SEED_X (PIXMAP_TABLE (gd_pmap))))
|
|
{
|
|
SetHandleSize (ccrsr_xdata, 32 * host_cursor_depth);
|
|
|
|
LOCK_HANDLE_EXCURSION_2
|
|
(CCRSR_MAP (ccrsr), CCRSR_DATA (ccrsr),
|
|
{
|
|
PixMap src;
|
|
PixMap ccrsr_xmap;
|
|
|
|
/* only fields used by `convert_pixmap ()',
|
|
baseAddr is filled in below */
|
|
memset (&ccrsr_xmap, 0, sizeof ccrsr_xmap);
|
|
ccrsr_xmap.rowBytes = CW (2 * host_cursor_depth);
|
|
ccrsr_xmap.pixelSize = CW (host_cursor_depth);
|
|
|
|
src = *STARH (CCRSR_MAP (ccrsr));
|
|
src.baseAddr = CCRSR_DATA (ccrsr)->p;
|
|
LOCK_HANDLE_EXCURSION_1
|
|
(ccrsr_xdata,
|
|
{
|
|
ccrsr_xmap.baseAddr = ccrsr_xdata->p;
|
|
convert_pixmap (&src, &ccrsr_xmap,
|
|
&ROMlib_cursor_rect, NULL);
|
|
});
|
|
});
|
|
CCRSR_XVALID_X (ccrsr) = CW (host_cursor_depth);
|
|
CCRSR_ID_X (ccrsr) = CTAB_SEED_X (PIXMAP_TABLE (gd_pmap));
|
|
}
|
|
|
|
/* Actually set the current cursor. */
|
|
LOCK_HANDLE_EXCURSION_1
|
|
(ccrsr_xdata,
|
|
{
|
|
HOST_SET_CURSOR ((char *) STARH (ccrsr_xdata),
|
|
(unsigned short *) CCRSR_MASK (ccrsr),
|
|
CW (hot_spot->h), CW (hot_spot->v));
|
|
});
|
|
}
|
|
else
|
|
{
|
|
HOST_SET_CURSOR ((char *) CCRSR_1DATA (ccrsr),
|
|
(unsigned short *) CCRSR_MASK (ccrsr),
|
|
CW (hot_spot->h), CW (hot_spot->v));
|
|
}
|
|
});
|
|
|
|
/* copy the cursor so if there is a depth change, we have the cursor
|
|
data around to reset the cursor; a pain in the butt */
|
|
if (current_ccrsr != ccrsr)
|
|
{
|
|
int data_size;
|
|
|
|
if (!current_ccrsr)
|
|
{
|
|
ZONE_SAVE_EXCURSION
|
|
(SysZone,
|
|
{
|
|
current_ccrsr = (CCrsrHandle) NewHandle (sizeof (CCrsr));
|
|
CCRSR_DATA_X (current_ccrsr) = RM (NewHandle (0));
|
|
CCRSR_XDATA_X (current_ccrsr) = RM (NULL);
|
|
CCRSR_MAP_X (current_ccrsr) = RM (NewPixMap ());
|
|
});
|
|
}
|
|
|
|
/* copy the cursor structure */
|
|
CCRSR_TYPE_X (current_ccrsr) = CCRSR_TYPE_X (ccrsr);
|
|
memcpy (CCRSR_1DATA (current_ccrsr), CCRSR_1DATA (ccrsr),
|
|
sizeof (Bits16));
|
|
memcpy (CCRSR_MASK (current_ccrsr), CCRSR_MASK (ccrsr),
|
|
sizeof (Bits16));
|
|
CCRSR_HOT_SPOT (current_ccrsr) = CCRSR_HOT_SPOT (ccrsr);
|
|
|
|
/* copy the pixmap */
|
|
CopyPixMap (CCRSR_MAP (ccrsr), CCRSR_MAP (current_ccrsr));
|
|
|
|
/* copy the cursor data */
|
|
data_size = GetHandleSize (CCRSR_DATA (ccrsr));
|
|
SetHandleSize (CCRSR_DATA (current_ccrsr), data_size);
|
|
memcpy (STARH (CCRSR_DATA (current_ccrsr)),
|
|
STARH (CCRSR_DATA (ccrsr)), data_size);
|
|
|
|
/* invalidate this cursor */
|
|
CCRSR_XVALID_X (current_ccrsr) = CWC (0);
|
|
CCRSR_ID_X (current_ccrsr) = CLC (-1);
|
|
|
|
current_cursor_valid_p = TRUE;
|
|
current_cursor_color_p = TRUE;
|
|
}
|
|
}
|
|
|
|
P1 (PUBLIC pascal trap, void, DisposCCursor,
|
|
CCrsrHandle, ccrsr)
|
|
{
|
|
/* #warning "implement DisposCCursor" */
|
|
warning_unimplemented (NULL_STRING);
|
|
}
|
|
|
|
P0 (PUBLIC pascal trap, void, AllocCursor)
|
|
{
|
|
/* This function is a NOP for us as far as I know. */
|
|
warning_unexpected ("AllocCursor called -- this is unusual");
|
|
}
|