home *** CD-ROM | disk | FTP | other *** search
- /* > $.CLIB.C.pointer
- *
- * HASWIN Graphics Library
- * =========================
- *
- * Copyright (C) H.A.Shaw 1990.
- * Howard A. Shaw.
- * The Unit for Space Sciences,
- * Room 165,
- * Physics Building,
- * University of Kent at Canterbury.
- * Canterbury.
- * Kent. CT2 7NJ
- * You may use and distribute this code freely, however please leave
- * it alone. If you find bugs (and there will be many) please contact
- * me and the master source can be modified. If you keep me informed
- * of who you give copies of this to then I can get release upgrades
- * to them.
- *
- * Since the WIMP has but one pointer HASWIN impliments a pointer stack
- * to simplify coding of complex pointer switching. HASWIN uses this
- * to allow each window to have its own pointer, but the code for that
- * is not here.
- */
- #include "includes.h"
-
- /*
- * this variable keeps things about the current pointer that we
- * well need to know, but the WIMP cannot tell us. Note:
- * We determine mx, my, buttons, palette when required, and so don't
- * need to store them.
- */
- static pointer haswin_pointer;
-
- /*
- * When the program starts up we must load up the default pointer
- * information so that we get everything correct later on. We assume
- * that at the moment of startup the pointer is the default one
- * "ptr_default". This is a big assumption, but how else can we work?
- * This assumption allows us to put the pointer back corrently if we
- * terminate later after changing the pointer. The clearup routines
- * call haswin_poppointer() until the stack is clear, and "ptr_default"
- * is always on the bottom of the stack.
- */
- int haswin_initpointerinfo() {
-
- haswin_pointer.mx = 0;
- haswin_pointer.my = 0;
- haswin_pointer.ihandle = 0;
- haswin_pointer.whandle = 0;
- haswin_pointer.win = 0;
- haswin_pointer.ic = 0;
- strncpy(haswin_pointer.name, "ptr_default", POINTER_MAXDATA);
- haswin_pointer.activex = 0;
- haswin_pointer.activey = 0;
- haswin_pointer.number = 1;
- haswin_pointer.buttons = 0;
- haswin_pointer.palette = haswin_malloc(sizeof(palette), "haswin_initpointerinfo", "new palette");
- haswin_getpalette(haswin_pointer.palette);
- return(HASWIN_TRUE);
- }
-
- /*
- * this is given a pointer and fills it in. If the given block is
- * a null pointer then a pointer structure is created.
- * The WIMP routine gives us the X/Y coords, window/icon handles and
- * the button state. We turn the handles into window/icon pointers
- * and add the name, active x/y point and palette.
- */
- pointer *haswin_getpointerinfo(pointer *point) {
-
- register int i;
- _kernel_swi_regs regs;
- buffer buff;
-
- if (!point) {
- if ((point=haswin_malloc(sizeof(pointer), "haswin_getpointerinfo", "new pointer")) == 0)
- return(0);
- point->palette = 0;
- }
- regs.r[1] = (int)&buff;
- if (!haswin_swi(HASWIN_Get_pointer_info, ®s))
- return(0);
- point->mx = buff.i[0];
- point->my = buff.i[1];
- point->buttons = buff.i[2] & POINTER_MOUSEBUTTONS;
- /* get keyboard status and update mouse buttons from it */
- regs.r[0] = 0xCA;
- regs.r[1] = 0x00;
- regs.r[2] = 0xFF;
- haswin_swi(OS_Byte, ®s);
- if (regs.r[1] & 0x01)
- point->buttons |= POINTER_MOUSE_A;
- if (regs.r[1] & 0x08)
- point->buttons |= POINTER_MOUSE_S;
- if (regs.r[1] & 0x40)
- point->buttons |= POINTER_MOUSE_C;
- point->whandle = buff.i[3];
- point->ihandle = buff.i[4];
- if (buff.i[3] == -1) {
- /* pointer over background */
- point->win = (window *)0;
- point->ic = (icon *)0;
- } else {
- point->win = haswin_findwindowhandle(buff.i[3]);
- point->ic = haswin_findiconhandle(point->win, buff.i[4]);
- }
- strncpy(point->name, haswin_pointer.name, POINTER_MAXDATA);
- point->activex = haswin_pointer.activex;
- point->activey = haswin_pointer.activey;
- point->number = haswin_pointer.number;
- if (haswin_pointer.palette) {
- if (!point->palette)
- point->palette = haswin_malloc(sizeof(palette), "haswin_getpointerinfo", "new palette");
- for (i=0; i<20; i++)
- point->palette->colour[i] = haswin_pointer.palette->colour[i];
- } else
- point->palette = 0;
- return(point);
- }
-
- /*
- * move the pointer to the correct place
- */
- int haswin_placepointer(window *wptr, int x, int y) {
-
- char pbuf[5];
- _kernel_swi_regs regs;
- int placeok, *iptr;
-
- placeok = HASWIN_TRUE;
- if ((int)wptr > 0) {
- haswin_updatewindowinfo(wptr);
- iptr = ((int *)wptr->win);
- x += iptr[0]-iptr[4];
- y += iptr[3]-iptr[5];
- if (x < iptr[0]) {
- x = iptr[0];
- placeok = HASWIN_FALSE;
- } else if (x > iptr[2]) {
- x = iptr[2];
- placeok = HASWIN_FALSE;
- }
- if (y < iptr[1]) {
- y = iptr[1];
- placeok = HASWIN_FALSE;
- } else if (y > iptr[3]) {
- y = iptr[3];
- placeok = HASWIN_FALSE;
- }
- }
- pbuf[0] = 3; /* move the pointer OS_Word 21,3 */
- pbuf[1] = (x%256) & 0xff;
- pbuf[2] = (x/256) & 0xff;
- pbuf[3] = (y%256) & 0xff;
- pbuf[4] = (y/256) & 0xff;
- regs.r[0] = 21;
- regs.r[1] = (int)pbuf;
- if (!haswin_swi(OS_Word, ®s))
- return(HASWIN_FALSE);
- return(placeok);
- }
-
- /*
- * Given a pointer structure change the pointer to the new shape
- * and select the pointer. If move is HASWIN_TRUE then move to
- * the coords given by the pointer as well.
- * If we ask for an icon that is outside a window then move as close
- * as we can get, and return HASWIN_FALSE. If we ask for a window
- * not on screen then do nothing and return HASWIN_FALSE.
- */
- int haswin_setpointer(pointer *point, int move) {
-
- window *win;
- icon *ic;
- int i;
- _kernel_swi_regs regs;
-
- if (!point)
- return(HASWIN_FALSE);
- if (point->name[0]) {
- /* have a name, so set the pointer shape */
- /* first look for sprite palette */
- regs.r[0] = 0x18;
- if (!haswin_spriteop(point->name, ®s)) {
- haswin_interrorprintf("haswin_setpointer: cannot set pointer to sprite '%s'", point->name);
- return(HASWIN_FALSE);
- }
- if (regs.r[1] == 0) {
- haswin_interrorprintf("haswin_setpointer: cannot set pointer to sprite '%s' in system area", point->name);
- return(HASWIN_FALSE);
- }
- regs.r[3] = point->number & 0x0F;
- if (regs.r[1] != 1) {
- /*
- If the sprite is in the WIMP area we cannot get
- the sprite pointer, therefore we have to assume
- that the screen mode is OK, otherwise for the
- pointer we MUST have a 2 bits per pixel mode.
- Check the sprite was defined in one of modes
- 1,5,8,11,19,26
- */
- switch (((int *)(regs.r[2]))[10]) {
- case 1:
- case 5:
- case 8:
- case 11:
- case 19:
- case 26:
- break;
- default:
- haswin_interrorprintf("haswin_setpointer: cannot set pointer to sprite '%s', screen mode %d", point->name, ((int *)(regs.r[2]))[10]);
- return(HASWIN_FALSE);
- }
- /*
- regs.r[2] points to sprite. See RISCOS P.R.M.
- Vol I page 390 to see why if regs.r[2]+8words
- contains 0x2C there is no palette.
- */
- if (((int *)(regs.r[2]))[8] == 0x2C) {
- /* we will not change the palette for the
- pointer so we MUST reset the colours to
- what they were when the pointer was set
- up.
- */
- if (point->palette)
- haswin_setpalette(point->palette);
- regs.r[3] |= 0x20;
- /* stop sprite palette use */
- }
- }
- regs.r[4] = point->activex;
- regs.r[5] = point->activey;
- regs.r[6] = 0;
- regs.r[7] = 0;
- regs.r[0] = 0x24;
- if (!haswin_spriteop(point->name, ®s)) {
- haswin_interrorprintf("haswin_setpointer: cannot set pointer to sprite '%s'", point->name);
- return(HASWIN_FALSE);
- }
- }
- if (move) {
- if (point->ic) {
- ic = point->ic;
- win = haswin_findwindowhandle(point->ic->whandle);
- if ((point->win) && (point->win != win)) {
- /* something odd, icon not in window given */
- return(HASWIN_FALSE);
- }
- } else if (point->win) {
- win = point->win;
- ic = 0;
- } else {
- win = 0;
- ic = 0;
- }
- if (win) {
- haswin_updatewindowinfo(win);
- i = haswin_getwindowflags(win);
- if ((i & WINDOW_OPEN) == 0) {
- /* can't put pointer in closed window ! */
- return(HASWIN_FALSE);
- }
- if (ic)
- i = haswin_placepointer(win, (ic->ic[0]+ic->ic[2])/2, (ic->ic[1]+ic->ic[3])/2);
- else
- i = haswin_placepointer(win, point->mx, point->my);
- } else
- i = haswin_placepointer(0, point->mx, point->my);
- }
- strncpy(haswin_pointer.name, point->name, POINTER_MAXDATA);
- haswin_pointer.activex = point->activex;
- haswin_pointer.activey = point->activey;
- haswin_pointer.number = point->number;
- haswin_getpalette(haswin_pointer.palette);
-
- /* update pointer structure with real mouse position */
- haswin_getpointerinfo(point);
- return(HASWIN_TRUE);
- }
-
- /*
- * we can stack pointers up to HASWIN_MAXPOINTERS levels
- */
- #define HASWIN_MAXPOINTERS 16
- static pointer haswin_pointerstack[HASWIN_MAXPOINTERS];
- static int haswin_pointerstackptr = 0;
-
- /*
- * push the current pointer onto the pointer stack and set a
- * new pointer if we can.
- */
- int haswin_pushpointer(pointer *point, int move) {
-
- if ((!point) || (haswin_pointerstackptr == HASWIN_MAXPOINTERS))
- return(HASWIN_FALSE);
- haswin_getpointerinfo(&haswin_pointerstack[haswin_pointerstackptr++]);
- haswin_setpointer(point, move);
- return(HASWIN_TRUE);
- }
-
- /*
- * pull a pointer from the pointer stack if we can
- */
- int haswin_poppointer(int move) {
-
- if (haswin_pointerstackptr <= 0)
- return(HASWIN_FALSE);
- haswin_setpointer(&haswin_pointerstack[--haswin_pointerstackptr], move);
- return(HASWIN_TRUE);
- }
-
- /*
- * create a new pointer structure
- */
- pointer *haswin_makepointer(char *name, int actx, int acty) {
-
- _kernel_swi_regs regs;
- pointer *point;
-
- if (name) {
- regs.r[0] = 0x18;
- if (!haswin_spriteop(name, ®s)) {
- haswin_interrorprintf("haswin_makepointer: cannot make pointer from sprite '%s' - not found", name);
- return(0);
- }
- if (regs.r[1] == 0) {
- haswin_interrorprintf("haswin_makepointer: cannot make pointer from sprite '%s' - in system area", name);
- return(0);
- }
- /*
- for pointer we MUST have a 2 bits per pixel mode. Check
- the sprite was defined in one of 1,5,8,11,19,26
- */
- switch (((int *)(regs.r[2]))[10]) {
- case 1:
- case 5:
- case 8:
- case 11:
- case 19:
- case 26:
- break;
- default:
- haswin_interrorprintf("haswin_makepointer: cannot make pointer from sprite '%s' - screen mode %d", name, ((int *)(regs.r[2]))[10]);
- return(0);
- }
- }
- point = (pointer *)haswin_malloc(sizeof(pointer), "haswin_makepointer", "pointer block");
- if (name)
- strncpy(point->name, name, POINTER_MAXDATA);
- else
- point->name[0] = 0;
- point->activex = actx;
- point->activey = acty;
- point->number = 2; /* by default use pointer 2 */
- point->palette = (palette *)0;
- point->win = 0;
- point->ic = 0;
- point->ihandle = 0;
- point->whandle = 0;
- return(point);
- }
-
- /*
- * the WIMP returns different codes for the three mouse buttons
- * depending upon the work area button type, or icon button type
- * beneath the pointer when the button was pressed. This is a real
- * pain, and so HASWIN uses internal button codes that are always
- * the same. The next two routines convert between the types.
- */
- /*
- * this table contains entries for each button type. If it
- * can SELECT, DRAG, DOUBLE or is WRITABLE
- */
- #define SELECT 0
- #define DRAG 1
- #define DOUBLE 2
- #define WRITABLE 3
- static char haswin_buttoncodes[16][4] = {
- /* 0 never */ { 0, 0, 0, 0 },
- /* 1 always */ { 1, 0, 0, 0 },
- /* 2 auto-repeat */ { 1, 0, 0, 0 },
- /* 3 click */ { 1, 0, 0, 0 },
- /* 4 release */ { 1, 0, 0, 0 },
- /* 5 Double click */ { 0, 0, 1, 0 },
- /* 6 Click/Drag */ { 1, 1, 0, 0 },
- /* 7 Release/Drag */ { 1, 1, 0, 0 },
- /* 8 Double/Drag */ { 0, 1, 1, 0 },
- /* 9 Menu */ { 1, 0, 0, 0 },
- /* 10 Double/Click/Drag */ { 1, 1, 1, 0 },
- /* 11 Radio */ { 1, 1, 0, 0 },
- /* 12 Silent */ { 0, 0, 0, 0 },
- /* 13 */ { 0, 0, 0, 0 },
- /* 14 Write/Click/Drag */ { 1, 1, 0, 1 },
- /* 15 Writeable */ { 1, 0, 0, 1 }
- };
-
- int haswin_canbuttondouble(int button) {
-
- return(haswin_buttoncodes[button&0x0F][DOUBLE]);
- }
-
- int haswin_canbuttondrag(int button) {
-
- return(haswin_buttoncodes[button&0x0F][DRAG]);
- }
-
- int haswin_canbuttonselect(int button) {
-
- return(haswin_buttoncodes[button&0x0F][SELECT]);
- }
-
- int haswin_canbuttonwrite(int button) {
-
- return(haswin_buttoncodes[button&0x0F][WRITABLE]);
- }
-
- /*
- * given a returned button code return HASWIN_TRUE if the type
- * allows double clicks or drags.
- */
- int haswin_canbuttontwice(int button) {
-
- return(haswin_buttoncodes[button&0x0F][DOUBLE] ||
- haswin_buttoncodes[button&0x0F][DRAG]);
- }
-
- /*
- * given a window, an icon and an internal button code work out
- * which button was really pressed and return HASWIN button type
- * codes. The icon takes priority over the window.
- */
- int haswin_buttonHASWINtoWIMP(window *wptr, icon *iptr, int button) {
-
- int tmp;
-
- if (button == 0)
- return(0);
- if (iptr)
- tmp = iptr->button;
- else if ((int)wptr > 0)
- tmp = wptr->button;
- else
- tmp = 0;
- switch (tmp) {
- case 0:
- case 12:
- return(0);
- break;
- case 13:
- break;
- case 1:
- case 2:
- case 3:
- case 4:
- case 9:
- switch (button) {
- case HASWIN_MOUSE_L: return(0x004);
- case HASWIN_MOUSE_M: return(0x002);
- case HASWIN_MOUSE_R: return(0x001);
- }
- break;
- case 5:
- switch (button) {
- case HASWIN_MOUSE_LDOUB: return(0x004);
- case HASWIN_MOUSE_M: return(0x002);
- case HASWIN_MOUSE_RDOUB: return(0x001);
- }
- break;
- case 6:
- case 7:
- case 11:
- case 14:
- case 15:
- switch (button) {
- case HASWIN_MOUSE_L: return(0x004);
- case HASWIN_MOUSE_M: return(0x002);
- case HASWIN_MOUSE_R: return(0x001);
- case HASWIN_MOUSE_LDRAG: return(0x040);
- case HASWIN_MOUSE_RDRAG: return(0x010);
- }
- break;
- case 8:
- switch (button) {
- case HASWIN_MOUSE_LDOUB: return(0x004);
- case HASWIN_MOUSE_M: return(0x002);
- case HASWIN_MOUSE_RDOUB: return(0x001);
- case HASWIN_MOUSE_LDRAG: return(0x040);
- case HASWIN_MOUSE_RDRAG: return(0x010);
- }
- break;
- case 10:
- switch (button) {
- case HASWIN_MOUSE_LDOUB: return(0x004);
- case HASWIN_MOUSE_M: return(0x002);
- case HASWIN_MOUSE_RDOUB: return(0x001);
- case HASWIN_MOUSE_LDRAG: return(0x040);
- case HASWIN_MOUSE_RDRAG: return(0x010);
- case HASWIN_MOUSE_L: return(0x400);
- case HASWIN_MOUSE_R: return(0x100);
- }
- break;
- }
- return(0);
- }
-
- /*
- * given a window, an icon and a WIMP button code
- * work out which button was really pressed and return HASWIN button
- * type codes.
- */
- int haswin_buttonWIMPtoHASWIN(window *wptr, icon *iptr, int button) {
-
- int tmp;
-
- if (iptr)
- tmp = iptr->button;
- else if ((int)wptr > 0)
- tmp = wptr->button;
- else
- tmp = 0;
- /*
- * determine the codes for the button type we have
- */
- switch (tmp) {
- case 0:
- case 12:
- return(0);
- break;
- case 13:
- break;
- case 1:
- case 2:
- case 3:
- case 4:
- case 9:
- switch (button) {
- case 0x004: return(HASWIN_MOUSE_L);
- case 0x002: return(HASWIN_MOUSE_M);
- case 0x001: return(HASWIN_MOUSE_R);
- }
- break;
- case 5:
- switch (button) {
- case 0x004: return(HASWIN_MOUSE_LDOUB);
- case 0x002: return(HASWIN_MOUSE_M);
- case 0x001: return(HASWIN_MOUSE_RDOUB);
- }
- break;
- case 6:
- case 7:
- case 11:
- case 14:
- case 15:
- switch (button) {
- case 0x004: return(HASWIN_MOUSE_L);
- case 0x002: return(HASWIN_MOUSE_M);
- case 0x001: return(HASWIN_MOUSE_R);
- case 0x040: return(HASWIN_MOUSE_LDRAG);
- case 0x010: return(HASWIN_MOUSE_RDRAG);
- }
- break;
- case 8:
- switch (button) {
- case 0x004: return(HASWIN_MOUSE_LDOUB);
- case 0x002: return(HASWIN_MOUSE_M);
- case 0x001: return(HASWIN_MOUSE_RDOUB);
- case 0x040: return(HASWIN_MOUSE_LDRAG);
- case 0x010: return(HASWIN_MOUSE_RDRAG);
- }
- break;
- case 10:
- switch (button) {
- case 0x004: return(HASWIN_MOUSE_LDOUB);
- case 0x002: return(HASWIN_MOUSE_M);
- case 0x001: return(HASWIN_MOUSE_RDOUB);
- case 0x040: return(HASWIN_MOUSE_LDRAG);
- case 0x010: return(HASWIN_MOUSE_RDRAG);
- case 0x400: return(HASWIN_MOUSE_L);
- case 0x100: return(HASWIN_MOUSE_R);
- }
- break;
- }
- return(0);
- }
-
-
-