home *** CD-ROM | disk | FTP | other *** search
- /* $Revision Header *** Header built automatically - do not edit! ***********
- *
- * (C) Copyright 1990 by MXM
- *
- * Name .....: MXMSub.c
- * Created ..: Saturday 06-Jan-90 23:30
- * Revision .: 5
- *
- * Date Author Comment
- * ========= ======== ====================
- * 09-Mar-90 Olsen Rework for Aztec 5.0
- * 14-Jan-90 Olsen Renamed to mxm.library
- * 07-Jan-90 Olsen Added InvertKeyMap
- * 07-Jan-90 Olsen - Empty log message -
- * 06-Jan-90 Olsen Created this file!
- *
- * $Revision Header ********************************************************/
- #define REVISION 4
-
- VOID
- CalcDimensions(cd_String,cd_Width,cd_Height,cd_MaxWidth)
- UBYTE *cd_String;
- LONG *cd_Width,*cd_Height,cd_MaxWidth;
- {
- LONG i,cd_InLine = 0,cd_NumLines = 0;
-
- *cd_Width = *cd_Height = 0;
-
- for(i = 0 ; i < strlen(cd_String) ; i++)
- {
- if(cd_String[i] == '\n' || cd_InLine == cd_MaxWidth)
- {
- if(cd_InLine > *cd_Width)
- *cd_Width = cd_InLine;
-
- cd_NumLines++;
- cd_InLine = 0;
-
- continue;
- }
-
- if(cd_String[i] == '\33')
- {
- while(cd_String[i] != 'm' && cd_String[i] != 'w' && i < strlen(cd_String))
- i++;
-
- if(i >= strlen(cd_String))
- i = strlen(cd_String) - 1;
-
- continue;
- }
-
- if(cd_String[i] < ' ')
- continue;
-
- cd_InLine++;
- }
-
- *cd_Height = cd_NumLines;
-
- if(cd_InLine > *cd_Width)
- *cd_Width = cd_InLine;
- }
-
- SHORT pop_computestate();
- VOID pop_do_highlighting();
- VOID pop_render();
- VOID pop_draw_menuitem();
- struct MenuItem *pop_getitem();
- SHORT pop_strlen();
-
- #define SETX 2
- #define SETY 1
-
- /*
- * pop_computestate()
- *
- * This function checks to see where the mouse pointer is in relation to
- * the various menu items in the menu. If it is inside one of them, it
- * returns which one (indexed by its linear position in the MenuItem list
- * with 0 being the first one). If not, returns -1.
- *
- * Possible future enhancement: keep a set of state variables containing
- * the UL and LR corners of the last-known select box; this would make
- * a quick check possible and would cut down the computation for short
- * mouse movements (the most common).
- */
-
- SHORT
- pop_computestate(win, menu)
- struct Window *win;
- struct Menu *menu;
- {
- register SHORT current = 0;
- register SHORT xval, yval;
- register struct MenuItem *item;
-
- /* Get the x and y vals of the mouse position */
-
- xval = win->MouseX - SETX;
- yval = win->MouseY - SETY;
-
- /* If there is a title, decrement the yval by the correct amount */
-
- if(menu->MenuName)
- yval -= POPTITLEHEIGHT;
-
- /* First, see if the pointer is even in the window */
-
- if((xval < 0) || (yval < 0) ||
- (xval > win->Width - SETX) || (yval > win->Height - SETY))
- return(-1);
-
- /* search through the list of menu items, checking the select box */
- /* of each. If containment is detected, the job is done. */
-
- item = menu->FirstItem;
- while(item) {
- if((xval >= item->LeftEdge) && (yval >= item->TopEdge) &&
- (xval <= item->LeftEdge + item->Width) &&
- (yval <= item->TopEdge + item->Height)) {
-
- /* We have found the quarry; now, the result only */
- /* depends on the MenuItem's ITEMENABLED flag. */
-
- if(item->Flags & ITEMENABLED)
- return(current);
- else
- return(-1);
- }
- current++;
- item = item->NextItem;
- }
-
- /* If the list is exhausted, return the sad news */
-
- return(-1);
- }
-
- /*
- * pop_highlight()
- *
- * highlight a menu item
- */
-
- #define pop_highlight(win, menu, state) pop_do_highlighting(win, menu, state, 0)
-
- /*
- * pop_unhighlight()
- *
- * unhighlight a menu item
- */
-
- #define pop_unhighlight(win, menu, state) pop_do_highlighting(win, menu, state, 1)
-
- /*
- * pop_do_highlighting()
- *
- * Highlight or unhighlight a menu item, given its traversal number. Assumes
- * this is a rational value -- if it isn't, Watch Out.
- */
-
- VOID
- pop_do_highlighting(win, menu, state, mode)
- struct Window *win;
- struct Menu *menu;
- SHORT state;
- SHORT mode; /* 0 means to highlight, 1 means to unhighlight */
- {
- register struct MenuItem *item;
- struct RastPort *rp;
- SHORT offset = 0;
-
- if(menu->MenuName)
- offset = POPTITLEHEIGHT;
-
- /* Get the correct MenuItem structure */
-
- item = pop_getitem(menu, state);
-
- rp = win->RPort;
-
- /* Now, do the highlighting! The action to be taken depends on */
- /* the type of highlighting desired for this item. */
- /* The way that the flags for highlighting works is truly bizarre */
-
- if((item->Flags & HIGHNONE) == HIGHNONE)
- return;
-
- if(item->Flags & HIGHCOMP) {
- SetDrMd(rp, COMPLEMENT);
- RectFill(rp, (LONG) item->LeftEdge + SETX, (LONG) (item->TopEdge +
- offset + SETY), (LONG) (item->LeftEdge + item->Width - 1 + SETX),
- (LONG) (item->TopEdge + item->Height + offset + SETY));
- }
- else if(item->Flags & HIGHBOX) {
- SetDrMd(rp, COMPLEMENT);
- Move(rp, (LONG) item->LeftEdge + SETX, (LONG) (item->TopEdge +
- offset + SETY));
-
- Draw(rp, (LONG) (item->LeftEdge + item->Width - 1 + SETX),
- (LONG) (item->TopEdge + offset + SETY));
- Draw(rp, (LONG) (item->LeftEdge + item->Width - 1 + SETX),
- (LONG) (item->TopEdge + item->Height + offset + SETY));
- Move(rp, (LONG) (item->LeftEdge + item->Width - 2 + SETX),
- (LONG) (item->TopEdge + offset + 1 + SETY));
- Draw(rp, (LONG) (item->LeftEdge + item->Width - 2 + SETX),
- (LONG) (item->TopEdge + item->Height + offset + SETY));
-
- Draw(rp, (LONG) item->LeftEdge + SETX,
- (LONG) (item->TopEdge + item->Height + offset + SETY));
- Draw(rp, (LONG) item->LeftEdge + SETX, (LONG)
- (item->TopEdge + offset + 1 + SETY));
-
- Move(rp, (LONG) item->LeftEdge + 1 + SETX, (LONG)
- (item->TopEdge + offset + 1 + SETY));
- Draw(rp, (LONG) item->LeftEdge + 1 + SETX,
- (LONG) (item->TopEdge + item->Height + offset - 1 + SETY));
- }
-
- /* Otherwise, the mode is HIGHIMAGE */
-
- else
- pop_draw_menuitem(win, item, !mode, offset);
- }
-
- /*
- * pop_render()
- *
- * renders the menu title (if existent) and the menu items
- */
-
- VOID
- pop_render(win, menu)
- struct Window *win;
- struct Menu *menu;
- {
- struct MenuItem *item;
- struct RastPort *rp;
- SHORT offset = 0;
-
- rp = win->RPort;
-
- /* Fill the background with color 1, like Intuition Menus */
-
- SetAPen(rp, 1L);
- RectFill(rp, 0L + SETX, 0L + SETY, (LONG) win->Width - SETX - 1, (LONG) win->Height - 2 - SETY);
-
- /* First, if there is a Title for this menu, render it in the top */
- /* of the menu. */
-
- if(menu->MenuName) {
- SetDrMd(rp, JAM1);
- SetAPen(rp, 1L);
- RectFill(rp, 0L, 0L, (LONG) win->Width - 1, (LONG) POPTITLEHEIGHT - 1);
- SetAPen(rp, 0L);
- SetBPen(rp, 1L);
- Move(rp, 4L + SETX, 7L);
- Text(rp, menu->MenuName, (LONG) pop_strlen(menu->MenuName));
- SetDrMd(rp, COMPLEMENT);
- RectFill(rp, 0L, 0L, (LONG) win->Width - 1, (LONG) POPTITLEHEIGHT - 1);
- SetDrMd(rp, JAM1);
- offset = POPTITLEHEIGHT;
- SetAPen(rp, 0);
- Move(rp, 0, POPTITLEHEIGHT);
- Draw(rp, win->Width - 1, POPTITLEHEIGHT);
- }
-
- /* now render all of the menu items */
-
- item = menu->FirstItem;
- while(item) {
- pop_draw_menuitem(win, item, 0, offset);
- item = item->NextItem;
- }
- }
-
- /*
- * pop_draw_menuitem()
- *
- * Draws the specified menuitem in the given rastport. The mode argument
- * says what to draw -- 0 means draw the ItemFill, 1 the SelectFill.
- */
-
- VOID
- pop_draw_menuitem(win, item, mode, offset)
- struct Window *win;
- struct MenuItem *item;
- SHORT mode;
- SHORT offset;
- {
- /* Area fill patterns */
-
- static USHORT pop_ghost_pattern[] = {
- 0x1111, 0x4444
- };
- static USHORT pop_normal_pattern[] = {
- 0xffff, 0xffff
- };
-
- APTR fill;
- struct RastPort *rp;
-
- /* first, figure out what to do, and return if it is a NULL thing */
-
- if(!mode)
- fill = item->ItemFill;
- else
- fill = item->SelectFill;
-
- if(!fill)
- return;
-
- rp = win->RPort;
-
- /* First, erase what may already be there, just to be sure that */
- /* everything works out all right. */
-
- SetAPen(rp, 1L);
- SetDrMd(rp, JAM1);
- RectFill(rp, (LONG) item->LeftEdge + SETX, (LONG) (item->TopEdge +
- offset + SETY), (LONG) (item->LeftEdge + item->Width + SETX - 1), (LONG)
- (item->TopEdge + item->Height + offset + SETY));
-
- /* If the item is checkmarked, draw the checkmark. Intuition made */
- /* sure that the CheckMark field of the window structure exists */
-
- if(item->Flags & CHECKIT)
- if(item->Flags & CHECKED)
- DrawImage(rp, win->CheckMark, (LONG) item->LeftEdge + SETX,
- (LONG) (item->TopEdge + offset + 1 + SETY));
-
- /* Now, draw the item itself -- depending on the Flag value, it */
- /* could be either an Image or an IntuiText */
-
- if(item->Flags & ITEMTEXT)
- PrintIText(rp, fill, (LONG) item->LeftEdge + SETX,
- (LONG) (item->TopEdge + offset + SETY));
- else
- DrawImage(rp, fill, (LONG) item->LeftEdge + SETX,
- (LONG) (item->TopEdge + offset + SETY));
-
- /* If the ITEMENABLED flag is not set, "ghost" the item. */
-
- if(!(item->Flags & ITEMENABLED)) {
- SetAPen(rp, 1L);
- SetDrMd(rp, JAM1);
- SetAfPt(rp, (USHORT *) pop_ghost_pattern, 1L);
- RectFill(rp, (LONG) item->LeftEdge + SETX, (LONG) (item->TopEdge +
- offset + SETY), (LONG) (item->LeftEdge + item->Width + SETX - 1), (LONG)
- (item->TopEdge + item->Height + offset + SETY));
- SetAfPt(rp, (USHORT *) pop_normal_pattern, 1L);
- }
- }
-
- /*
- * pop_getitem()
- *
- * given the traversal number of a menu item in a menu (assumes, BTW, that
- * the arguments are valid), return a pointer to the MenuItem structure
- */
-
- struct MenuItem *
- pop_getitem(menu, which)
- struct Menu *menu;
- SHORT which;
- {
- struct MenuItem *item;
-
- item = menu->FirstItem;
- while(which--)
- item = item->NextItem;
- return(item);
- }
-
- /*
- * pop_strlen()
- *
- * a home-brewed strlen to prevent it being necessary to hook in whatever
- * huge object file in which the c library's strlen() resides.
- */
-
- SHORT
- pop_strlen(str)
- char *str;
- {
- register SHORT count = 0;
-
- for(; *str++; count++);
- return(count);
- }
-
- #define CONTROLBITS ( (1 << 5) | (1 << 6) )
-
- ULONG
- InvertKeyMap(ansicode,ie,km)
- ULONG ansicode;
- register struct InputEvent *ie;
- struct KeyMap *km;
- {
- LONG kindex;
- UBYTE code = 0;
-
- ie -> ie_Class = IECLASS_RAWKEY;
- ie -> ie_EventAddress = 0;
-
- /* check for codes in (default) high map first */
-
- switch(ansicode)
- {
- case ' ': code = 0x40; /* space */
- break;
-
- case 0x08: code = 0x41; /* backspace */
- break;
-
- case '\t': code = 0x42; /* tab */
- break;
-
- case 0x0D: code = 0x44; /* return */
- break;
-
- case 0x1B: code = 0x45; /* esc */
- break;
-
- case 0x7F: code = 0x46; /* del */
- break;
- }
-
- ie -> ie_Code = 0;
- ie -> ie_Qualifier = 0;
-
- if(code)
- {
- ie -> ie_Code = code;
- ie -> ie_Qualifier = 0;
-
- return(TRUE);
- }
-
- LowKeyInvert((UBYTE)ansicode,km,&ie -> ie_Code,&ie -> ie_Qualifier,&kindex);
-
- if(!ie -> ie_Code && !ie -> ie_Qualifier)
- return(FALSE);
-
- return(TRUE);
- }
-
- #define KEYMAPSIZE 64
-
- /* LowKeyInvert returns good code else <0 if no find
- *
- * regarding keymap as many-to-one mapping:
- * -entries for a given key are scanned so that
- * the minimum number of qualifiers are associated
- * with the keystroke.
- * -passing a character value of zero corresponds, in
- * the default keymap, to CTRL-`, which is probably a bug.
- * -numerals are matched with numeric pad keystrokes (no
- * qualifiers) on standard keymap. The way to specify
- * a key on the number row is via its shifted value;
- * specify explicitly that the qualifier is to be unshifted,
- * or a "don't care."
- */
-
- LowKeyInvert(value,km,codep,qualp,indexp)
- register UBYTE value; /* translation value from low keymap */
- struct KeyMap *km;
- UWORD *codep; /* pointers where answers are to be put */
- UWORD *qualp;
- ULONG *indexp; /* dead-key index information (put into ie?) */
- {
- register UWORD code = KEYMAPSIZE - 1; /* last entry */
- register unsigned int type;
- register LONG *p; /* points to four-byte lokeymap entry */
- int found_it = 0;
-
- *indexp = *qualp = 0;
-
- p = (LONG *)km -> km_LoKeyMap + code;
-
- do
- {
- /* determine type of key */
-
- if((type = km -> km_LoKeyMapTypes[code]) == KC_VANILLA)
- found_it = CheckVanilla(p,value,qualp);
- else
- if(!(type & KCF_NOP))
- found_it = CheckNormal(p,value,type,qualp);
-
- --p;
- }
- while(!found_it && code--);
-
- *codep = code;
-
- return(code);
- }
-
- CheckNormal(four_bytesp, val, type, qualp)
- LONG four_bytesp;
- UBYTE val;
- UWORD type;
- UWORD *qualp;
- {
- register UBYTE *p = (UBYTE *)four_bytesp; /* codes held in long word */
- register long position;
-
- /* start with last of four bytes, "more vanilla" */
-
- p += 3;
-
- for(position = 3 ; position >= 0 ; --position, --p)
- {
- if(*p == val)
- {
- switch(type)
- {
- case KC_NOQUAL: if(position != 3)
- goto NOT_THIS;
-
- break;
-
- case KCF_SHIFT: if(!(position & 2))
- goto NOT_THIS;
-
- if(position == 2)
- *qualp |= IEQUALIFIER_LSHIFT;
-
- break;
-
- case KCF_ALT: if(!(position & 2))
- goto NOT_THIS;
-
- if(position == 2)
- *qualp |= IEQUALIFIER_LALT;
-
- break;
-
-
- case KCF_CONTROL:
-
- if(!(position & 2))
- goto NOT_THIS;
-
- if(position == 2)
- *qualp |= IEQUALIFIER_CONTROL;
-
- break;
-
- case KCF_ALT | KCF_CONTROL:
-
- if(!(position & 1))
- *qualp |= IEQUALIFIER_LALT;
-
- if(!(position & 2))
- *qualp |= IEQUALIFIER_CONTROL;
-
- break;
-
- case KCF_SHIFT | KCF_CONTROL:
-
- if(!(position & 1))
- *qualp |= IEQUALIFIER_LSHIFT;
-
- if(!(position & 2))
- *qualp |= IEQUALIFIER_CONTROL;
-
- break;
-
-
- case KCF_SHIFT | KCF_ALT:
-
- if(!(position & 1))
- *qualp |= IEQUALIFIER_LSHIFT;
-
- if(!(position & 2))
- *qualp |= IEQUALIFIER_LALT;
-
- break;
-
- default: break;
- }
-
- return(TRUE);
- }
- NOT_THIS: ;
- }
-
- return(FALSE);
- }
-
- CheckVanilla(p,val,qualp)
- UBYTE *p; /* note: byte pointer */
- UBYTE val;
- UWORD *qualp;
- {
- register int i;
-
- /* only one way to match a vanilla control key */
-
- if(!(val & CONTROLBITS))
- {
- /* is a control code */
-
- if((p[3] & ~CONTROLBITS) == val)
- {
- *qualp |= IEQUALIFIER_CONTROL;
- return(TRUE);
- }
- }
- else
- {
- /* not a control */
-
- for(i = 3 ; i >= 0 ; --i)
- {
- if(p[i] == val)
- {
- if(!(i & 1))
- *qualp |= IEQUALIFIER_LSHIFT;
-
- if(!(i & 2))
- *qualp |= IEQUALIFIER_LALT;
-
- return(TRUE);
- }
- }
- }
-
- return(FALSE);
- }
-