Added kernel module for starting the usb stack at boot time. It's not activated thoug...
[cake.git] / rom / intuition / menutask_aros.c
blob90dfbbf3b7f139bf26308de9c1239967479d1af6
1 /*
2 Copyright 1995-2007, The AROS Development Team. All rights reserved.
3 Copyright 2001-2003, The MorphOS Development Team. All Rights Reserved.
4 $Id$
5 */
7 #include <proto/exec.h>
8 #include <proto/intuition.h>
9 #include <proto/alib.h>
10 #include <proto/layers.h>
11 #include <proto/graphics.h>
12 #include <proto/keymap.h>
13 #include <proto/cybergraphics.h>
14 #include <exec/memory.h>
15 #include <exec/alerts.h>
16 #include <exec/interrupts.h>
17 #include <exec/ports.h>
18 #include <intuition/intuition.h>
19 #include <intuition/intuitionbase.h>
20 #include <intuition/imageclass.h>
21 #include <graphics/gfxmacros.h>
22 #include <graphics/rpattr.h>
23 #include <devices/inputevent.h>
24 #include <devices/input.h>
25 #include <devices/timer.h>
26 #include "inputhandler.h"
27 #include "intuition_intern.h"
28 #include <string.h>
30 #ifdef SKINS
31 #include "intuition_customize.h"
32 #endif
34 #include "menus.h"
35 #include "menutask.h"
36 #include <cybergraphx/cybergraphics.h>
38 #undef DEBUG
39 #define DEBUG 0
40 #include <aros/debug.h>
42 extern IPTR HookEntry();
44 /**************************************************************************************************/
46 /* this #defines are taken from workbench/libs/gadtools/menus.c!! */
48 #define TEXT_AMIGAKEY_SPACING 6
50 #define ITEXT_EXTRA_LEFT 2
51 #define ITEXT_EXTRA_RIGHT 2
52 #define ITEXT_EXTRA_TOP 1
53 #define ITEXT_EXTRA_BOTTOM 1
55 /**************************************************************************************************/
57 static void HandleMouseMove(struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase);
58 static void HandleMouseClick(struct InputEvent *ie, struct MenuHandlerData *mhd,
59 struct IntuitionBase *IntuitionBase);
60 static void HandleCheckItem(struct Window *win, struct MenuItem *item,
61 struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase);
63 static void HighlightMenuTitle(struct Menu *menu, struct MenuHandlerData *mhd,
64 struct IntuitionBase *IntuitionBase);
66 static struct Menu *FindMenu(WORD *var, struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase);
67 static struct MenuItem *FindItem(WORD *var, struct MenuHandlerData *mhd);
68 static struct MenuItem *FindSubItem(WORD *var, struct MenuHandlerData *mhd);
70 static void MakeMenuBarWin(struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase);
71 static void KillMenuBarWin(struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase);
72 static void RenderMenuBar(struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase);
74 static void MakeMenuWin(struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase);
75 static void KillMenuWin(struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase);
76 static void RenderMenu(struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase);
77 static void RenderMenuTitle(struct Menu *menu, struct MenuHandlerData *mhd,
78 struct IntuitionBase *IntuitionBase);
80 static void MakeSubMenuWin(struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase);
81 static void KillSubMenuWin(struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase);
82 static void RenderSubMenu(struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase);
84 static void RenderItem(struct MenuItem *item, WORD itemtype, struct Rectangle *box,
85 struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase);
87 static void RenderMenuBG(struct Window *win, struct MenuHandlerData *mhd,
88 struct IntuitionBase *IntuitionBase);
89 static void RenderCheckMark(struct MenuItem *item, WORD itemtype, struct MenuHandlerData *mhd,
90 struct IntuitionBase *IntuitionBase);
91 static void RenderAmigaKey(struct MenuItem *item, WORD itemtype, struct MenuHandlerData *mhd,
92 struct IntuitionBase *IntuitionBase);
93 static void RenderDisabledPattern(struct RastPort *rp, WORD x1, WORD y1, WORD x2, WORD y2,
94 struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase);
95 static void RenderFrame(struct RastPort *rp, WORD x1, WORD y1, WORD x2, WORD y2, WORD state,
96 struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase);
97 static void HighlightItem(struct MenuItem *item, WORD itemtype, struct MenuHandlerData *mhd,
98 struct IntuitionBase *IntuitionBase);
99 static WORD CalcMaxCommKeyWidth(struct Window *win, struct MenuHandlerData *mhd,
100 struct IntuitionBase *IntuitionBase);
101 static void AddToSelection(struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase);
104 /**************************************************************************************************/
105 /******************************
106 ** CreateMenuHandlerTask() **
107 ******************************/
108 struct Task *CreateMenuHandlerTask(APTR taskparams, struct IntuitionBase *IntuitionBase)
110 struct Task *task;
111 APTR stack;
113 task = AllocMem(sizeof (struct Task), MEMF_PUBLIC|MEMF_CLEAR);
114 if (task)
116 NEWLIST(&task->tc_MemEntry);
117 task->tc_Node.ln_Type = NT_TASK;
118 task->tc_Node.ln_Name = MENUTASK_NAME;
119 task->tc_Node.ln_Pri = MENUTASK_PRIORITY;
121 stack = AllocMem(MENUTASK_STACKSIZE, MEMF_PUBLIC);
122 if(stack != NULL)
124 task->tc_SPLower=stack;
125 task->tc_SPUpper=(UBYTE *)stack + MENUTASK_STACKSIZE;
127 #ifdef __MORPHOS__
128 task->tc_SPReg = task->tc_SPUpper;
131 struct TaskInitExtension taskext;
132 struct TagItem tags[4];
134 taskext.Trap = TRAP_PPCTASK;
135 taskext.Extension = 0;
136 taskext.Tags = tags;
138 tags[0].ti_Tag = TASKTAG_CODETYPE;
139 tags[0].ti_Data = CODETYPE_PPC;
140 tags[1].ti_Tag = TASKTAG_PC;
141 tags[1].ti_Data = (ULONG)DefaultMenuHandler;
142 tags[2].ti_Tag = TASKTAG_PPC_ARG1;
143 tags[2].ti_Data = (ULONG)taskparams;
144 tags[3].ti_Tag = TAG_END;
146 if(AddTask(task, (APTR)&taskext, NULL) != NULL)
148 /* Everything went OK */
149 return (task);
152 #else
154 struct TagItem tags[] =
156 {TASKTAG_ARG1, (IPTR)taskparams },
157 {TAG_DONE }
160 #if AROS_STACK_GROWS_DOWNWARDS
161 task->tc_SPReg = (UBYTE *)task->tc_SPUpper-SP_OFFSET;
162 #else
163 task->tc_SPReg=(UBYTE *)task->tc_SPLower+SP_OFFSET;
164 #endif
166 if(NewAddTask(task, DefaultMenuHandler, NULL, tags) != NULL)
168 /* Everything went OK */
169 return (task);
173 #endif
174 FreeMem(stack, MENUTASK_STACKSIZE);
176 } /* if(stack != NULL) */
177 FreeMem(task,sizeof(struct Task));
179 } /* if (task) */
180 return (NULL);
184 #undef DefaultMenuHandler
187 /**************************************************************************************************/
189 /***************************
190 ** DefaultMenuHandler() **
191 ***************************/
192 void DefaultMenuHandler(struct MenuTaskParams *taskparams)
194 struct IntuitionBase *IntuitionBase = taskparams->intuitionBase;
195 struct MenuHandlerData *mhd = NULL;
196 UBYTE *mem;
197 struct MsgPort *port = NULL;
198 BOOL success = FALSE;
200 if ((mem = AllocMem(sizeof(struct MsgPort) +
201 sizeof(struct MenuHandlerData), MEMF_PUBLIC | MEMF_CLEAR)))
203 port = (struct MsgPort *)mem;
205 port->mp_Node.ln_Type = NT_MSGPORT;
206 port->mp_Flags = PA_SIGNAL;
207 port->mp_SigBit = AllocSignal(-1);
208 port->mp_SigTask = FindTask(0);
209 NEWLIST(&port->mp_MsgList);
211 mhd = (struct MenuHandlerData *)(mem + sizeof(struct MsgPort));
213 success = TRUE;
215 } /* if ((mem = AllocMem(sizeof(struct MsgPort), MEMF_PUBLIC | MEMF_CLEAR))) */
217 if (success)
219 taskparams->MenuHandlerPort = port;
220 taskparams->success = TRUE;
223 Signal(taskparams->Caller, SIGF_INTUITION);
225 if (!success)
227 D(bug("DefaultMenuHandler: initialization failed. waiting for parent task to kill me.\n"));
228 Wait(0);
231 D(bug("DefaultMenuHandler: initialization ok. Now waiting for messages from Intuition.\n"));
233 for(;;)
235 struct MenuMessage *msg;
237 WaitPort(port);
238 while((msg = GetMenuMessage(port, IntuitionBase)))
240 switch(msg->code)
242 case MMCODE_START:
243 mhd->win = msg->win;
244 mhd->scr = mhd->win->WScreen;
245 mhd->dri = GetScreenDrawInfo(mhd->scr);
246 mhd->menu = msg->win->MenuStrip;
247 mhd->activemenunum = -1;
248 mhd->activeitemnum = -1;
249 mhd->activesubitemnum = -1;
250 mhd->checkmark = ((struct IntWindow *)mhd->win)->Checkmark;
251 mhd->amigakey = ((struct IntWindow *)mhd->win)->AmigaKey;
252 mhd->submenuimage = ((struct IntWindow *)mhd->win)->SubMenuImage;
253 mhd->scrmousex = mhd->scr->MouseX;
254 mhd->scrmousey = mhd->scr->MouseY;
255 mhd->firstmenupick = MENUNULL;
256 mhd->TrueColor = GetBitMapAttr(&mhd->scr->BitMap, BMA_DEPTH) > 8 ? TRUE: FALSE;
258 /* close windows in the back first because
259 this is faster */
260 MakeMenuBarWin(mhd, IntuitionBase);
261 HandleMouseMove(mhd, IntuitionBase);
263 mhd->active = TRUE;
264 break;
266 case MMCODE_EVENT:
267 /* there might come additional messages from Intuition
268 even when we have already told it to make the menus
269 inactive, but since everything is async, this cannot
270 be avoided, so check if we are really active */
272 if (mhd->active)
274 switch(msg->ie.ie_Class)
276 case IECLASS_RAWMOUSE:
277 if (msg->ie.ie_Code == IECODE_NOBUTTON)
279 HandleMouseMove(mhd, IntuitionBase);
281 else
283 HandleMouseClick(&msg->ie, mhd, IntuitionBase);
285 break;
289 } /* if (mhd->active) */
290 break;
292 } /* switch(msg->code) */
294 ReplyMenuMessage(msg, IntuitionBase);
296 } /* while((msg = (struct MenuMessage *)GetMsg(port))) */
298 } /* for(;;) */
301 /**************************************************************************************************/
303 /*******************************
304 ** InitDefaultMenuHandler() **
305 *******************************/
306 BOOL InitDefaultMenuHandler(struct IntuitionBase *IntuitionBase)
308 struct MenuTaskParams params;
309 struct Task *task;
310 BOOL result = FALSE;
312 params.intuitionBase = IntuitionBase;
313 params.Caller = FindTask(NULL);
314 params.success = FALSE;
316 SetSignal(0, SIGF_INTUITION);
318 if ((task = CreateMenuHandlerTask(&params, IntuitionBase)))
320 Wait(SIGF_INTUITION);
322 if (params.success)
324 result = TRUE;
325 GetPrivIBase(IntuitionBase)->MenuHandlerPort = params.MenuHandlerPort;
327 else
329 RemTask(task);
332 } /* if ((task = CreateMenuHandlerTask(&params, IntuitionBase))) */
334 return result;
338 /**************************************************************************************************/
340 static void HandleMouseMove(struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase)
342 struct Layer *lay;
343 struct Window *win = NULL;
344 struct Menu *menu;
345 struct MenuItem *item;
346 WORD new_activemenunum = mhd->activemenunum;
347 WORD new_activeitemnum = mhd->activeitemnum;
348 WORD new_activesubitemnum = mhd->activesubitemnum;
350 mhd->scrmousex = mhd->scr->MouseX;
351 mhd->scrmousey = mhd->scr->MouseY;
353 if ((lay = WhichLayer(&mhd->scr->LayerInfo, mhd->scrmousex, mhd->scrmousey)))
355 win = (struct Window *)lay->Window;
357 if (win && (win == mhd->submenuwin))
359 /* Mouse over submenu box */
360 item = FindSubItem(&new_activesubitemnum, mhd);
362 if (new_activesubitemnum != mhd->activesubitemnum)
364 if (mhd->activesubitemnum != -1)
366 HighlightItem(mhd->activesubitem, ITEM_SUBITEM, mhd, IntuitionBase);
369 mhd->activesubitemnum = new_activesubitemnum;
370 mhd->activesubitem = item;
372 if (item)
374 HighlightItem(mhd->activesubitem, ITEM_SUBITEM, mhd, IntuitionBase);
379 else if (win && (win == mhd->menuwin))
381 item = FindItem(&new_activeitemnum, mhd);
383 if (new_activeitemnum != mhd->activeitemnum)
385 if (mhd->activeitemnum != -1)
387 HighlightItem(mhd->activeitem, ITEM_ITEM, mhd, IntuitionBase);
388 KillSubMenuWin(mhd, IntuitionBase);
391 mhd->activeitemnum = new_activeitemnum;
392 mhd->activeitem = item;
394 if (item)
396 HighlightItem(mhd->activeitem, ITEM_ITEM, mhd, IntuitionBase);
398 if (item->SubItem)
400 MakeSubMenuWin(mhd, IntuitionBase);
404 } /* if (win && (win == mhd->menuwin)) */
405 else if (win && (win == mhd->menubarwin))
407 /* Mouse over menu box */
409 menu = FindMenu(&new_activemenunum, mhd, IntuitionBase);
411 if (new_activemenunum != mhd->activemenunum)
414 if (mhd->activemenunum != -1)
417 HighlightMenuTitle(mhd->activemenu, mhd, IntuitionBase);
418 KillMenuWin(mhd, IntuitionBase);
419 KillSubMenuWin(mhd, IntuitionBase);
422 mhd->activemenunum = new_activemenunum;
423 mhd->activemenu = menu;
425 if (menu)
427 HighlightMenuTitle(mhd->activemenu, mhd, IntuitionBase);
428 MakeMenuWin(mhd, IntuitionBase);
432 if ((mhd->activeitemnum != -1) && (!mhd->submenuwin))
434 HighlightItem(mhd->activeitem, ITEM_ITEM, mhd, IntuitionBase);
435 mhd->activeitemnum = -1;
436 mhd->activeitem = NULL;
439 } /* if (win && (win == mhd->menubarwin)) */
440 else
442 win = NULL;
444 } /* if ((lay = WhichLayer(&mhd->scr->LayerInfo, mhd->scrmousex, mhd->scrmousey))) */
446 if (!win)
448 /* mouse outside any menu window */
450 if ((mhd->activeitemnum != -1) && (!mhd->submenuwin))
452 HighlightItem(mhd->activeitem, ITEM_ITEM, mhd, IntuitionBase);
453 mhd->activeitemnum = -1;
454 mhd->activeitem = NULL;
456 else if (mhd->activesubitemnum != -1)
458 HighlightItem(mhd->activesubitem, ITEM_SUBITEM, mhd, IntuitionBase);
459 mhd->activesubitemnum = -1;
460 mhd->activesubitem = NULL;
466 /**************************************************************************************************/
468 static void HandleMouseClick(struct InputEvent *ie, struct MenuHandlerData *mhd,
469 struct IntuitionBase *IntuitionBase)
471 switch(ie->ie_Code)
473 case MENUUP:
474 case SELECTDOWN:
476 struct Layer *lay;
478 if ((lay = WhichLayer(&mhd->scr->LayerInfo, mhd->scrmousex, mhd->scrmousey)))
480 struct Window *win = (struct Window *)lay->Window;
481 struct MenuItem *item = NULL;
483 win = (struct Window *)lay->Window;
485 if (win && (win == mhd->submenuwin) && (mhd->activesubitemnum != -1))
487 item = mhd->activesubitem;
490 else if (win && (win == mhd->menuwin) && (mhd->activeitemnum != -1))
492 item = mhd->activeitem;
495 if (item) if (item->Flags & CHECKIT)
497 HandleCheckItem(win, item, mhd, IntuitionBase);
500 AddToSelection(mhd, IntuitionBase);
502 } /* if ((lay = WhichLayer(&mhd->scr->LayerInfo, mhd->scrmousex, mhd->scrmousey))) */
504 if (ie->ie_Code == MENUUP)
506 KillMenuBarWin(mhd, IntuitionBase);
507 KillMenuWin(mhd, IntuitionBase);
508 KillSubMenuWin(mhd, IntuitionBase);
510 if (mhd->dri)
512 FreeScreenDrawInfo(mhd->scr, mhd->dri);
513 mhd->dri = 0;
515 MH2Int_MakeMenusInactive(mhd->win, mhd->firstmenupick, IntuitionBase);
516 mhd->active = FALSE;
519 break;
522 } /* switch(ie->ie_Code) */
525 /**************************************************************************************************/
527 static void HandleCheckItem(struct Window *win, struct MenuItem *item,
528 struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase)
530 /* Note: If you change something here, you probably must also change
531 menus.c/CheckMenuItemWasClicked() which is used when the
532 user uses the menu key shortcuts! */
534 WORD itemtype = ((win == mhd->menuwin) ? ITEM_ITEM : ITEM_SUBITEM);
536 BOOL re_render = FALSE;
538 if (item->Flags & MENUTOGGLE)
540 item->Flags ^= CHECKED;
541 re_render = TRUE;
543 else
545 if (!(item->Flags & CHECKED))
547 item->Flags |= CHECKED;
548 re_render = TRUE;
552 if (re_render)
554 BOOL toggle_hi = FALSE;
556 if ((item->Flags & HIGHITEM) &&
557 ((item->Flags & HIGHFLAGS) == HIGHCOMP)) toggle_hi = TRUE;
559 if (toggle_hi) HighlightItem(item, itemtype, mhd, IntuitionBase);
560 RenderCheckMark(item, itemtype, mhd, IntuitionBase);
561 if (toggle_hi) HighlightItem(item, itemtype, mhd, IntuitionBase);
565 if (item->MutualExclude)
567 struct MenuItem *checkitem = (itemtype == ITEM_ITEM) ? mhd->activemenu->FirstItem :
568 mhd->activeitem->SubItem;
569 BOOL toggle_hi = FALSE;
570 WORD i;
572 if ((item->Flags & HIGHITEM) &&
573 ((item->Flags & HIGHFLAGS) == HIGHBOX)) toggle_hi = TRUE;
575 if (toggle_hi) HighlightItem(item, itemtype, mhd, IntuitionBase);
577 for(i = 0; (i < 32) && checkitem; i++, checkitem = checkitem->NextItem)
579 if ((item->MutualExclude & (1L << i)) &&
580 ((checkitem->Flags & (CHECKED | CHECKIT)) == (CHECKIT | CHECKED)))
582 checkitem->Flags &= ~CHECKED;
583 RenderCheckMark(checkitem, itemtype, mhd, IntuitionBase);
587 if (toggle_hi) HighlightItem(item, itemtype, mhd, IntuitionBase);
589 } /* if (item->MutualExclude) */
592 /**************************************************************************************************/
594 static void HighlightMenuTitle(struct Menu *menu, struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase)
596 BOOL customdraw = FALSE;
598 if (menu->Flags & MENUENABLED)
600 struct RastPort *rp = mhd->menubarwin->RPort;
601 WORD x1, x2, y1, y2;
603 if (MENUS_UNDERMOUSE)
605 WORD i;
606 struct Menu *m = mhd->menu;
608 x1 = mhd->innerleft;
610 x2 = x1 + mhd->menubaritemwidth - 1;
612 for(i = 0; m != menu; m = m->NextMenu) i++;
614 y1 = mhd->innertop + i * mhd->menubaritemheight;
615 y2 = y1 + mhd->menubaritemheight - 1;
618 else
620 x1 = menu->LeftEdge + mhd->scr->BarHBorder - mhd->scr->MenuHBorder;
621 y1 = 0;
622 x2 = x1 + menu->Width - 1;
623 y2 = mhd->scr->BarHeight - 1;
627 if (MENUS_AMIGALOOK)
629 SetDrMd(rp, COMPLEMENT);
630 RectFill(rp, x1, y1, x2, y2);
632 else
634 menu->Flags ^= HIGHITEM;
635 if (MENUS_UNDERMOUSE)
637 struct mdpDrawBackground msg;
639 msg.MethodID = MDM_DRAWBACKGROUND;
640 msg.mdp_RPort = rp;
641 msg.mdp_TrueColor = mhd->TrueColor;
642 msg.mdp_X = 0;
643 msg.mdp_Y = 0;
644 msg.mdp_Width = mhd->win->Width - 1;
645 msg.mdp_Height = mhd->win->Height - 1;
646 msg.mdp_ItemLeft = x1;
647 msg.mdp_ItemTop = y1;
648 msg.mdp_ItemWidth = x2 - x1 + 1;
649 msg.mdp_ItemHeight = y2 - y1 + 1;
650 msg.mdp_Flags = menu->Flags;
651 if (mhd->win == mhd->submenuwin) msg.mdp_UserBuffer = mhd->SubDecorUserBuffer;
652 else if (mhd->win == mhd->menuwin) msg.mdp_UserBuffer = mhd->DecorUserBuffer;
653 else msg.mdp_UserBuffer = mhd->BarDecorUserBuffer;
654 customdraw = DoMethodA(((struct IntScreen *)(mhd->scr))->MenuDecorObj, (Msg)&msg);
657 if (!MENUS_UNDERMOUSE) y1++;
659 if (!customdraw) {
660 SetDrMd(rp, JAM1);
661 SetAPen(rp, mhd->dri->dri_Pens[(menu->Flags & HIGHITEM) ? FILLPEN : BACKGROUNDPEN]);
662 RectFill(rp, x1, y1, x2, y2);
664 RenderMenuTitle(menu, mhd, IntuitionBase);
666 if ((menu->Flags & HIGHITEM) && !customdraw)
668 if (MENUS_UNDERMOUSE)
670 RenderFrame(rp, x1, y1, x2, y2, IDS_SELECTED, mhd, IntuitionBase);
672 else
674 SetAPen(rp, mhd->dri->dri_Pens[SHINEPEN]);
675 RectFill(rp, x1, y1, x1, y2);
676 SetAPen(rp, mhd->dri->dri_Pens[SHADOWPEN]);
677 RectFill(rp, x2, y1, x2, y2);
684 /**************************************************************************************************/
686 static struct Menu *FindMenu(WORD *var, struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase)
688 struct Menu *menu;
689 WORD mouse_x, mouse_y, i;
691 mouse_x = mhd->scrmousex - mhd->menubarwin->LeftEdge;
692 mouse_y = mhd->scrmousey - mhd->menubarwin->TopEdge;
694 if (MENUS_UNDERMOUSE)
696 menu = NULL;
698 mouse_x -= mhd->innerleft;
699 mouse_y -= mhd->innertop;
701 if ((mouse_x >= 0) && (mouse_x < mhd->menubaritemwidth) && (mouse_y >= 0))
703 i = mouse_y / mhd->menubaritemheight;
705 if ((i >= 0) && (i < mhd->nummenubaritems))
707 WORD i2 = i;
709 menu = mhd->menu;
710 while(i && menu)
712 i--;
713 menu = menu->NextMenu;
716 if (menu && (i == 0))
718 *var = i2;
723 else
725 for(menu = mhd->menu, i = 0; menu; menu = menu->NextMenu, i++)
727 if ((mouse_x >= menu->LeftEdge) &&
728 (mouse_x < menu->LeftEdge + menu->Width) &&
729 (mouse_y >= 0) &&
730 (mouse_y <= mhd->scr->BarHeight))
732 *var = i;
733 break;
738 return menu;
741 /**************************************************************************************************/
743 static struct MenuItem *FindItem(WORD *var, struct MenuHandlerData *mhd)
745 struct MenuItem *item = NULL;
746 WORD mouse_x, mouse_y, i;
748 if (mhd->menuwin)
750 mouse_x = mhd->scrmousex - mhd->menuwin->LeftEdge + mhd->activemenu->JazzX - mhd->innerleft;
751 mouse_y = mhd->scrmousey - mhd->menuwin->TopEdge + mhd->activemenu->JazzY - mhd->innertop;
753 for(item = mhd->activemenu->FirstItem, i = 0; item; item = item->NextItem, i++)
755 if ((mouse_x >= item->LeftEdge) &&
756 (mouse_x < item->LeftEdge + item->Width) &&
757 (mouse_y >= item->TopEdge) &&
758 (mouse_y < item->TopEdge + item->Height))
760 *var = i;
761 break;
764 } /* if (mhd->menuwin) */
766 if ((item == NULL) && !mhd->submenuwin) *var = -1;
768 return item;
771 /**************************************************************************************************/
773 static struct MenuItem *FindSubItem(WORD *var, struct MenuHandlerData *mhd)
775 struct MenuItem *item = NULL;
776 WORD mouse_x, mouse_y, i;
778 if (mhd->submenuwin)
780 mouse_x = mhd->scrmousex - mhd->submenuwin->LeftEdge + mhd->submenubox.MinX - mhd->menuinnerleft;
781 mouse_y = mhd->scrmousey - mhd->submenuwin->TopEdge + mhd->submenubox.MinY - mhd->menuinnertop;
783 *var = -1;
785 for(item = mhd->activeitem->SubItem, i = 0; item; item = item->NextItem, i++)
787 if ((mouse_x >= item->LeftEdge) &&
788 (mouse_x < item->LeftEdge + item->Width) &&
789 (mouse_y >= item->TopEdge) &&
790 (mouse_y < item->TopEdge + item->Height))
792 *var = i;
793 break;
797 } /* if (mhd->menuwin) */
799 return item;
802 /**************************************************************************************************/
804 static void MakeMenuBarWin(struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase)
806 struct TagItem win_tags[] =
808 {WA_Left , 0 },
809 {WA_Top , 0 },
810 {WA_Width , mhd->scr->Width },
811 {WA_Height , mhd->scr->BarHeight + 1 },
812 {WA_AutoAdjust , TRUE },
813 {WA_Borderless , TRUE },
814 {WA_CustomScreen, (ULONG)mhd->scr },
815 {WA_BackFill , (IPTR)LAYERS_NOBACKFILL },
816 {TAG_DONE }
818 struct Menu *menu;
820 if (MENUS_UNDERMOUSE)
822 struct RastPort *temprp;
823 WORD w, maxw = 0;
825 if (!(temprp = CloneRastPort(&mhd->scr->RastPort))) return;
827 mhd->nummenubaritems = 0;
828 for(menu = mhd->menu; menu; menu = menu->NextMenu)
830 w = TextLength(temprp, menu->MenuName, strlen(menu->MenuName));
831 if (w > maxw) maxw = w;
832 mhd->nummenubaritems++;
835 mhd->menubaritemwidth = maxw + mhd->submenuimage->Width +
836 TEXT_AMIGAKEY_SPACING +
837 ITEXT_EXTRA_LEFT +
838 ITEXT_EXTRA_RIGHT;
840 if (temprp->TxHeight > mhd->submenuimage->Height) mhd->menubaritemheight = temprp->TxHeight; else mhd->menubaritemheight = mhd->submenuimage->Height;
842 mhd->menubaritemheight += (ITEXT_EXTRA_TOP + ITEXT_EXTRA_BOTTOM);
844 struct mdpGetMenuSpaces msg;
846 msg.MethodID = MDM_GETMENUSPACES;
847 msg.mdp_TrueColor = mhd->TrueColor;
848 msg.mdp_InnerLeft = mhd->scr->MenuHBorder;
849 msg.mdp_InnerTop = mhd->scr->MenuVBorder;
850 msg.mdp_InnerRight = mhd->scr->MenuHBorder;
851 msg.mdp_InnerBottom = mhd->scr->MenuVBorder;
852 msg.mdp_ItemInnerLeft = 0;
853 msg.mdp_ItemInnerTop = 0;
854 msg.mdp_ItemInnerRight = 0;
855 msg.mdp_ItemInnerBottom = 0;
856 msg.mdp_MinWidth = 0;
857 msg.mdp_MinHeight = 0;
858 DoMethodA(((struct IntScreen *)(mhd->scr))->MenuDecorObj, (Msg)&msg);
859 mhd->innerleft = msg.mdp_InnerLeft;
860 mhd->innerright = msg.mdp_InnerRight;
861 mhd->innertop = msg.mdp_InnerTop;
862 mhd->innerbottom = msg.mdp_InnerBottom;
863 mhd->iteminnerleft = msg.mdp_ItemInnerLeft;
864 mhd->iteminnerright = msg.mdp_ItemInnerRight;
865 mhd->iteminnertop = msg.mdp_ItemInnerTop;
866 mhd->iteminnerbottom = msg.mdp_ItemInnerBottom;
867 mhd->menubaritemwidth += (mhd->iteminnerleft + mhd->iteminnerright);
868 mhd->menubaritemheight += (mhd->iteminnertop + mhd->iteminnerbottom);
870 win_tags[2].ti_Data = mhd->menubaritemwidth + mhd->innerleft + mhd->innerright;
871 win_tags[3].ti_Data = mhd->menubaritemheight * mhd->nummenubaritems + mhd->innertop + mhd->innerbottom;
873 if (win_tags[2].ti_Data < msg.mdp_MinWidth)
875 mhd->menubaritemwidth += (msg.mdp_MinWidth - win_tags[2].ti_Data);
876 win_tags[2].ti_Data = msg.mdp_MinWidth;
879 if (win_tags[3].ti_Data < msg.mdp_MinHeight)
881 win_tags[3].ti_Data = msg.mdp_MinHeight;
884 WORD PosX = mhd->scr->MouseX - win_tags[2].ti_Data / 2;
885 win_tags[1].ti_Data = mhd->scr->MouseY;
888 if ((PosX + win_tags[2].ti_Data) > mhd->scr->Width) PosX = mhd->scr->Width - win_tags[2].ti_Data;
889 if ((win_tags[1].ti_Data + win_tags[3].ti_Data) > mhd->scr->Height) win_tags[1].ti_Data = mhd->scr->Height - win_tags[3].ti_Data;
890 if (PosX < 0) PosX = 0;
891 if (win_tags[1].ti_Data > 32000) win_tags[1].ti_Data = 0;
893 win_tags[0].ti_Data = PosX;
895 FreeRastPort(temprp);
897 IPTR userbuffersize;
899 GetAttr(MDA_UserBuffer, ((struct IntScreen *)(mhd->scr))->MenuDecorObj, &userbuffersize);
901 if (userbuffersize)
903 mhd->DecorUserBufferSize = userbuffersize;
904 mhd->BarDecorUserBuffer = (IPTR) AllocMem(userbuffersize, MEMF_ANY | MEMF_CLEAR);
905 if (0 == mhd->BarDecorUserBuffer) return;
909 struct mdpInitMenu msg;
911 msg.MethodID = MDM_INITMENU;
912 msg.mdp_TrueColor = mhd->TrueColor;
913 msg.mdp_RPort = &mhd->scr->RastPort;
914 msg.mdp_Left = win_tags[0].ti_Data;
915 msg.mdp_Top = win_tags[1].ti_Data;
916 msg.mdp_Width = win_tags[2].ti_Data;
917 msg.mdp_Height = win_tags[3].ti_Data;
918 msg.mdp_UserBuffer = mhd->BarDecorUserBuffer;
919 msg.mdp_ScreenUserBuffer = ((struct IntScreen *) mhd->scr)->DecorUserBuffer;
921 msg.mdp_Screen = mhd->scr;
923 DoMethodA(((struct IntScreen *)(mhd->scr))->MenuDecorObj, (Msg)&msg);
927 D(bug("MakeMenuBarWin: mhd 0x%lx\n",
928 mhd));
930 mhd->menubarwin = OpenWindowTagList(0, win_tags);
932 for(menu = mhd->menu; menu; menu = menu->NextMenu)
934 menu->Flags &= ~HIGHITEM;
937 RenderMenuBar(mhd, IntuitionBase);
940 /**************************************************************************************************/
942 static void KillMenuBarWin(struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase)
944 if (mhd->menubarwin)
946 CloseWindow(mhd->menubarwin);
947 mhd->menubarwin = NULL;
949 if (MENUS_UNDERMOUSE)
951 struct mdpExitMenu msg;
953 msg.MethodID = MDM_EXITMENU;
954 msg.mdp_UserBuffer = mhd->BarDecorUserBuffer;
955 msg.mdp_TrueColor = mhd->TrueColor;
956 DoMethodA(((struct IntScreen *)(mhd->scr))->MenuDecorObj, (Msg)&msg);
958 if (mhd->BarDecorUserBuffer)
960 FreeMem((void *)mhd->BarDecorUserBuffer, mhd->DecorUserBufferSize);
962 mhd->BarDecorUserBuffer = 0;
969 /**************************************************************************************************/
971 static void RenderMenuBar(struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase)
973 if (mhd->menubarwin)
975 struct Menu *menu = mhd->menu;
976 struct RastPort *rp = mhd->menubarwin->RPort;
978 SetFont(rp, mhd->dri->dri_Font);
980 if (MENUS_UNDERMOUSE)
982 RenderMenuBG(mhd->menubarwin, mhd, IntuitionBase);
984 else
986 if (MENUS_AMIGALOOK)
988 SetABPenDrMd(rp, mhd->dri->dri_Pens[BARBLOCKPEN], 0, JAM1);
990 else
992 SetABPenDrMd(rp, mhd->dri->dri_Pens[BACKGROUNDPEN], 0, JAM1);
995 RectFill(rp, 0, 0, mhd->menubarwin->Width - 1, mhd->menubarwin->Height - 2);
997 SetAPen(rp, mhd->dri->dri_Pens[BARTRIMPEN]);
998 RectFill(rp, 0, mhd->menubarwin->Height - 1, mhd->menubarwin->Width - 1, mhd->menubarwin->Height - 1);
1000 if (!MENUS_AMIGALOOK)
1002 SetAPen(rp, mhd->dri->dri_Pens[SHINEPEN]);
1003 RectFill(rp, 0, 0, 0, mhd->menubarwin->Height - 2);
1004 RectFill(rp, 1, 0, mhd->menubarwin->Width - 1, 0);
1005 SetAPen(rp, mhd->dri->dri_Pens[SHADOWPEN]);
1006 RectFill(rp, mhd->menubarwin->Width - 1, 1, mhd->menubarwin->Width - 1, mhd->menubarwin->Height - 2);
1010 for(; menu; menu = menu->NextMenu)
1012 RenderMenuTitle(menu, mhd, IntuitionBase);
1017 /**************************************************************************************************/
1019 static void RenderMenuTitle(struct Menu *menu, struct MenuHandlerData *mhd,
1020 struct IntuitionBase *IntuitionBase)
1022 struct RastPort *rp = mhd->menubarwin->RPort;
1023 WORD len = strlen(menu->MenuName);
1024 WORD x, y;
1026 SetDrMd(rp, JAM1);
1028 if (MENUS_UNDERMOUSE)
1030 struct Menu *m;
1031 WORD yoff;
1033 yoff = 0;
1034 for(m = mhd->menu; m && (m != menu);m = m ->NextMenu)
1036 yoff++;
1039 x = mhd->innerleft + ITEXT_EXTRA_LEFT;
1040 y = mhd->innertop + ITEXT_EXTRA_TOP + yoff * mhd->menubaritemheight;
1042 else
1044 x = mhd->scr->BarHBorder + menu->LeftEdge;
1045 y = mhd->scr->BarVBorder;
1048 if (MENUS_AMIGALOOK)
1050 SetAPen(rp, mhd->dri->dri_Pens[BARDETAILPEN]);
1052 else
1054 SetAPen(rp, mhd->dri->dri_Pens[(menu->Flags & HIGHITEM) ? FILLTEXTPEN : TEXTPEN]);
1057 Move(rp, x, y + rp->TxBaseline);
1058 Text(rp, menu->MenuName, len);
1060 if (MENUS_UNDERMOUSE)
1062 if (menu->FirstItem)
1064 WORD x2 = mhd->scr->MenuHBorder + mhd->menubaritemwidth - ITEXT_EXTRA_RIGHT - mhd->submenuimage->Width;
1066 DrawImageState(rp, mhd->submenuimage, x2, y + ((mhd->menubaritemheight - mhd->submenuimage->Height) >> 1), IDS_NORMAL, mhd->dri);
1070 if (!(menu->Flags & MENUENABLED))
1072 WORD y2 = y + rp->TxHeight - 1;
1073 WORD x2;
1075 if (MENUS_UNDERMOUSE)
1077 x2 = mhd->scr->MenuHBorder + mhd->menubaritemwidth - 1;
1079 else
1081 x2 = x + TextLength(rp, menu->MenuName, len) - 1;
1084 RenderDisabledPattern(rp, x, y, x2, y2, mhd, IntuitionBase);
1088 /**************************************************************************************************/
1090 static void MakeMenuWin(struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase)
1092 struct MenuItem *item;
1094 WORD width = mhd->activemenu->BeatX - mhd->activemenu->JazzX + 1;
1095 WORD height = mhd->activemenu->BeatY - mhd->activemenu->JazzY + 1;
1096 WORD xpos,ypos;
1098 struct mdpGetMenuSpaces msg;
1100 msg.MethodID = MDM_GETMENUSPACES;
1101 msg.mdp_TrueColor = mhd->TrueColor;
1102 msg.mdp_InnerLeft = 0;
1103 msg.mdp_InnerTop = 0;
1104 msg.mdp_InnerRight = 0;
1105 msg.mdp_InnerBottom = 0;
1106 msg.mdp_ItemInnerLeft = 0;
1107 msg.mdp_ItemInnerTop = 0;
1108 msg.mdp_ItemInnerRight = 0;
1109 msg.mdp_ItemInnerBottom = 0;
1110 DoMethodA(((struct IntScreen *)(mhd->scr))->MenuDecorObj, (Msg)&msg);
1111 mhd->menuinnerleft = msg.mdp_InnerLeft;
1112 mhd->menuinnerright = msg.mdp_InnerRight;
1113 mhd->menuinnertop = msg.mdp_InnerTop;
1114 mhd->menuinnerbottom = msg.mdp_InnerBottom;
1116 width += (mhd->menuinnerleft + mhd->menuinnerright);
1117 height += (mhd->menuinnertop + mhd->menuinnerbottom);
1119 if (MENUS_UNDERMOUSE)
1121 xpos = mhd->menubarwin->LeftEdge + mhd->menubarwin->Width - 16;
1122 ypos = mhd->menubarwin->TopEdge;
1124 else
1126 xpos = mhd->activemenu->LeftEdge + mhd->scr->BarHBorder + mhd->activemenu->JazzX;
1128 if (MENUS_AMIGALOOK)
1130 ypos = mhd->scr->BarHeight + 1 + mhd->activemenu->JazzY;
1132 else
1134 ypos = mhd->scr->BarHeight + 1;
1139 struct TagItem win_tags[] =
1141 {WA_Left , xpos },
1142 {WA_Top , ypos },
1143 {WA_Width , width },
1144 {WA_Height , height },
1145 {WA_AutoAdjust , TRUE },
1146 {WA_Borderless , TRUE },
1147 {WA_CustomScreen, (ULONG)mhd->scr },
1148 {WA_BackFill , (IPTR)LAYERS_NOBACKFILL },
1149 {TAG_DONE }
1152 if (MENUS_UNDERMOUSE)
1154 win_tags[1].ti_Data += (mhd->menubaritemheight * mhd->activemenunum + mhd->scr->MenuVBorder) -
1155 height / 2;
1156 if (xpos + width > mhd->scr->Width)
1158 win_tags[0].ti_Data = mhd->menubarwin->LeftEdge - width + 16;
1162 if ((win_tags[0].ti_Data + win_tags[2].ti_Data) > mhd->scr->Width) win_tags[0].ti_Data = mhd->scr->Width - win_tags[2].ti_Data;
1163 if ((win_tags[1].ti_Data + win_tags[3].ti_Data) > mhd->scr->Height) win_tags[1].ti_Data = mhd->scr->Height - win_tags[3].ti_Data;
1164 if (((LONG) win_tags[0].ti_Data) < 0) win_tags[0].ti_Data = 0;
1165 if (((LONG) win_tags[1].ti_Data) < 0) win_tags[1].ti_Data = 0;
1167 if ((item = mhd->activemenu->FirstItem))
1170 while(item)
1172 item->Flags &= ~HIGHITEM;
1173 item = item->NextItem;
1176 IPTR userbuffersize;
1178 GetAttr(MDA_UserBuffer, ((struct IntScreen *)(mhd->scr))->MenuDecorObj, &userbuffersize);
1180 if (userbuffersize)
1182 mhd->DecorUserBufferSize = userbuffersize;
1183 mhd->DecorUserBuffer = (IPTR) AllocMem(userbuffersize, MEMF_ANY | MEMF_CLEAR);
1184 if (0 == mhd->DecorUserBuffer) return;
1187 struct mdpInitMenu msg;
1189 msg.MethodID = MDM_INITMENU;
1190 msg.mdp_TrueColor = mhd->TrueColor;
1191 msg.mdp_RPort = &mhd->scr->RastPort;
1192 msg.mdp_Left = win_tags[0].ti_Data;
1193 msg.mdp_Top = win_tags[1].ti_Data;
1194 msg.mdp_Width = width;
1195 msg.mdp_Height = height;
1196 msg.mdp_UserBuffer = mhd->DecorUserBuffer;
1197 msg.mdp_ScreenUserBuffer = ((struct IntScreen *) mhd->scr)->DecorUserBuffer;
1199 msg.mdp_Screen = mhd->scr;
1201 DoMethodA(((struct IntScreen *)(mhd->scr))->MenuDecorObj, (Msg)&msg);
1203 mhd->menuwin = OpenWindowTagList(0, win_tags);
1205 mhd->maxcommkeywidth_menu = CalcMaxCommKeyWidth(mhd->menuwin, mhd, IntuitionBase);
1207 RenderMenu(mhd, IntuitionBase);
1209 mhd->activemenu->Flags |= MIDRAWN;
1214 /**************************************************************************************************/
1216 static void KillMenuWin(struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase)
1218 if (mhd->menuwin)
1220 struct MenuItem *item;
1222 CloseWindow(mhd->menuwin);
1223 mhd->menuwin = NULL;
1225 TimeDelay(UNIT_VBLANK,0,20000);
1227 for(item = mhd->activemenu->FirstItem; item; item = item->NextItem)
1229 item->Flags &= ~ISDRAWN;
1231 struct mdpExitMenu msg;
1233 msg.MethodID = MDM_EXITMENU;
1234 msg.mdp_TrueColor = mhd->TrueColor;
1235 msg.mdp_UserBuffer = mhd->DecorUserBuffer;
1236 DoMethodA(((struct IntScreen *)(mhd->scr))->MenuDecorObj, (Msg)&msg);
1238 if (mhd->DecorUserBuffer)
1240 FreeMem((void *)mhd->DecorUserBuffer, mhd->DecorUserBufferSize);
1242 mhd->DecorUserBuffer = 0;
1244 mhd->activemenu->Flags &= ~MIDRAWN;
1246 mhd->activeitemnum = -1;
1247 mhd->activeitem = NULL;
1251 /**************************************************************************************************/
1253 static void RenderMenu(struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase)
1256 if (mhd->menuwin)
1258 struct MenuItem *item;
1260 RenderMenuBG(mhd->menuwin, mhd, IntuitionBase);
1262 SetFont(mhd->menuwin->RPort, mhd->dri->dri_Font);
1264 for(item = mhd->activemenu->FirstItem; item; item = item->NextItem)
1266 RenderItem(item, ITEM_ITEM, (struct Rectangle *)(&mhd->activemenu->JazzX), mhd, IntuitionBase);
1269 } /* if (mhd->menuwin) */
1272 /**************************************************************************************************/
1274 static void MakeSubMenuWin(struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase)
1276 struct MenuItem *item = mhd->activeitem->SubItem;
1278 struct TagItem win_tags[] =
1280 {WA_Left , 0 },
1281 {WA_Top , 0 },
1282 {WA_Width , 0 },
1283 {WA_Height , 0 },
1284 {WA_AutoAdjust , TRUE },
1285 {WA_Borderless , TRUE },
1286 {WA_CustomScreen, (ULONG)mhd->scr },
1287 {WA_BackFill , (IPTR)LAYERS_NOBACKFILL },
1288 {TAG_DONE }
1291 GetMenuBox(mhd->menubarwin, item, &mhd->submenubox.MinX,
1292 &mhd->submenubox.MinY,
1293 &mhd->submenubox.MaxX,
1294 &mhd->submenubox.MaxY);
1297 struct mdpGetMenuSpaces msg;
1299 msg.MethodID = MDM_GETMENUSPACES;
1300 msg.mdp_TrueColor = mhd->TrueColor;
1301 msg.mdp_InnerLeft = 0;
1302 msg.mdp_InnerTop = 0;
1303 msg.mdp_InnerRight = 0;
1304 msg.mdp_InnerBottom = 0;
1306 DoMethodA(((struct IntScreen *)(mhd->scr))->MenuDecorObj, (Msg)&msg);
1307 mhd->menuinnerleft = msg.mdp_InnerLeft;
1308 mhd->menuinnerright = msg.mdp_InnerRight;
1309 mhd->menuinnertop = msg.mdp_InnerTop;
1310 mhd->menuinnerbottom = msg.mdp_InnerBottom;
1313 win_tags[0].ti_Data = mhd->menuwin->LeftEdge +
1314 mhd->activeitem->LeftEdge - mhd->activemenu->JazzX +
1315 mhd->submenubox.MinX;
1317 win_tags[1].ti_Data = mhd->menuwin->TopEdge +
1318 mhd->activeitem->TopEdge - mhd->activemenu->JazzY +
1319 mhd->submenubox.MinY;
1321 win_tags[2].ti_Data = mhd->submenubox.MaxX - mhd->submenubox.MinX + 1 + mhd->menuinnerleft + mhd->menuinnerright;
1322 win_tags[3].ti_Data = mhd->submenubox.MaxY - mhd->submenubox.MinY + 1 + mhd->menuinnertop + mhd->menuinnerbottom;
1324 if ((win_tags[0].ti_Data + win_tags[2].ti_Data) > mhd->scr->Width) win_tags[0].ti_Data = mhd->scr->Width - win_tags[2].ti_Data;
1325 if ((win_tags[1].ti_Data + win_tags[3].ti_Data) > mhd->scr->Height) win_tags[1].ti_Data = mhd->scr->Height - win_tags[3].ti_Data;
1326 if (((LONG) win_tags[0].ti_Data) < 0) win_tags[0].ti_Data = 0;
1327 if (((LONG) win_tags[1].ti_Data) < 0) win_tags[1].ti_Data = 0;
1329 while(item)
1331 item->Flags &= ~HIGHITEM;
1332 item = item->NextItem;
1335 IPTR userbuffersize;
1337 GetAttr(MDA_UserBuffer, ((struct IntScreen *)(mhd->scr))->MenuDecorObj, &userbuffersize);
1339 if (userbuffersize)
1341 mhd->DecorUserBufferSize = userbuffersize;
1342 mhd->SubDecorUserBuffer = (IPTR) AllocMem(userbuffersize, MEMF_ANY | MEMF_CLEAR);
1343 if (0 == mhd->SubDecorUserBuffer) return;
1347 struct mdpInitMenu msg;
1348 msg.MethodID = MDM_INITMENU;
1349 msg.mdp_TrueColor = mhd->TrueColor;
1350 msg.mdp_RPort = &mhd->scr->RastPort;
1351 msg.mdp_Left = win_tags[0].ti_Data;
1352 msg.mdp_Top = win_tags[1].ti_Data;
1353 msg.mdp_Width = win_tags[2].ti_Data;
1354 msg.mdp_Height = win_tags[3].ti_Data;
1355 msg.mdp_UserBuffer = mhd->SubDecorUserBuffer;
1356 msg.mdp_ScreenUserBuffer = ((struct IntScreen *) mhd->scr)->DecorUserBuffer;
1358 msg.mdp_TrueColor = mhd->TrueColor;
1359 msg.mdp_Screen = mhd->scr;
1361 DoMethodA(((struct IntScreen *)(mhd->scr))->MenuDecorObj, (Msg)&msg);
1363 mhd->submenuwin = OpenWindowTagList(0, win_tags);
1365 mhd->maxcommkeywidth_submenu = CalcMaxCommKeyWidth(mhd->submenuwin, mhd, IntuitionBase);
1367 RenderSubMenu(mhd, IntuitionBase);
1370 /**************************************************************************************************/
1372 static void KillSubMenuWin(struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase)
1374 if (mhd->submenuwin)
1376 CloseWindow(mhd->submenuwin);
1378 TimeDelay(UNIT_VBLANK,0,20000);
1379 struct mdpExitMenu msg;
1381 msg.MethodID = MDM_EXITMENU;
1382 msg.mdp_TrueColor = mhd->TrueColor;
1383 msg.mdp_UserBuffer = mhd->SubDecorUserBuffer;
1384 DoMethodA(((struct IntScreen *)(mhd->scr))->MenuDecorObj, (Msg)&msg);
1386 if (mhd->SubDecorUserBuffer)
1388 FreeMem((void *)mhd->SubDecorUserBuffer, mhd->DecorUserBufferSize);
1390 mhd->SubDecorUserBuffer = 0;
1392 mhd->submenuwin = NULL;
1394 mhd->activesubitemnum = -1;
1395 mhd->activesubitem = NULL;
1399 /**************************************************************************************************/
1401 static void RenderSubMenu(struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase)
1404 if (mhd->submenuwin)
1406 struct MenuItem *item;
1408 RenderMenuBG(mhd->submenuwin, mhd, IntuitionBase);
1410 SetFont(mhd->submenuwin->RPort, mhd->dri->dri_Font);
1412 for(item = mhd->activeitem->SubItem; item; item = item->NextItem)
1414 RenderItem(item, ITEM_SUBITEM, (struct Rectangle *)(&mhd->submenubox), mhd, IntuitionBase);
1417 } /* if (mhd->submenuwin) */
1420 /**************************************************************************************************/
1422 static void RenderItem(struct MenuItem *item, WORD itemtype, struct Rectangle *box,
1423 struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase)
1426 struct Window *win = ((itemtype == ITEM_ITEM) ? mhd->menuwin : mhd->submenuwin);
1427 struct RastPort *rp = win->RPort;
1428 WORD offx = -box->MinX + mhd->menuinnerleft;
1429 WORD offy = -box->MinY + mhd->menuinnertop;
1430 BOOL enabled = ((item->Flags & ITEMENABLED) &&
1431 (mhd->activemenu->Flags & MENUENABLED) &&
1432 ((itemtype == ITEM_ITEM) || (mhd->activeitem->Flags & ITEMENABLED)));
1433 BOOL item_supports_disable = FALSE;
1435 SetDrMd(rp, JAM1);
1437 if (item->ItemFill)
1440 if (item->Flags & ITEMTEXT)
1442 struct IntuiText *save = ((struct IntuiText*) item->ItemFill)->NextText;
1444 if (item->SubItem)
1446 Forbid();
1447 ((struct IntuiText*) item->ItemFill)->NextText = NULL;
1450 struct IntuiText *it = (struct IntuiText *)item->ItemFill;
1452 if (MENUS_AMIGALOOK)
1454 PrintIText(rp, it, offx + item->LeftEdge, offy + item->TopEdge);
1456 else
1458 it->FrontPen = mhd->dri->dri_Pens[(item->Flags & HIGHITEM) ? FILLTEXTPEN : TEXTPEN];
1459 it->DrawMode = JAM1;
1461 PrintIText(rp, it, offx + item->LeftEdge, offy + item->TopEdge);
1463 if (item->SubItem)
1465 DrawImageState(rp, mhd->submenuimage, offx + item->Width - mhd->submenuimage->Width, offy + item->TopEdge + ((item->Height - mhd->submenuimage->Height) >> 1), IDS_NORMAL, mhd->dri);
1466 ((struct IntuiText*) item->ItemFill)->NextText = save;
1467 Permit();
1470 else
1472 struct Image *im = (struct Image *)item->ItemFill;
1473 LONG state = IDS_NORMAL;
1475 if (!enabled && (im->Depth == CUSTOMIMAGEDEPTH))
1477 IPTR val = 0;
1479 GetAttr(IA_SupportsDisable, (Object *)im, &val);
1480 if (val)
1482 item_supports_disable = TRUE;
1483 state = IDS_DISABLED;
1487 DrawImageState(rp, im, offx + item->LeftEdge, offy + item->TopEdge, state, mhd->dri);
1490 } /* if (item->ItemFill) */
1492 RenderCheckMark(item, itemtype, mhd, IntuitionBase);
1493 RenderAmigaKey(item, itemtype, mhd, IntuitionBase);
1495 if (!enabled && !item_supports_disable)
1497 RenderDisabledPattern(rp, offx + item->LeftEdge,
1498 offy + item->TopEdge,
1499 offx + item->LeftEdge + item->Width - 1,
1500 offy + item->TopEdge + item->Height - 1,
1501 mhd,
1502 IntuitionBase);
1507 /**************************************************************************************************/
1509 static void RenderMenuBG(struct Window *win, struct MenuHandlerData *mhd,
1510 struct IntuitionBase *IntuitionBase)
1512 struct RastPort *rp = win->RPort;
1513 WORD borderx, bordery;
1514 BOOL customdraw = FALSE;
1515 struct mdpDrawBackground msg;
1517 msg.MethodID = MDM_DRAWBACKGROUND;
1518 msg.mdp_TrueColor = mhd->TrueColor;
1519 msg.mdp_RPort = rp;
1520 msg.mdp_X = 0;
1521 msg.mdp_Y = 0;
1522 msg.mdp_Width = win->Width - 1;
1523 msg.mdp_Height = win->Height - 1;
1524 msg.mdp_ItemLeft = 0;
1525 msg.mdp_ItemTop = 0;
1526 msg.mdp_ItemWidth = win->Width - 1;
1527 msg.mdp_ItemHeight = win->Height - 1;
1528 msg.mdp_Flags = 0;
1529 if (win == mhd->submenuwin) msg.mdp_UserBuffer = mhd->SubDecorUserBuffer;
1530 else if (win == mhd->menuwin) msg.mdp_UserBuffer = mhd->DecorUserBuffer;
1531 else msg.mdp_UserBuffer = mhd->BarDecorUserBuffer;
1532 customdraw = DoMethodA(((struct IntScreen *)(mhd->scr))->MenuDecorObj, (Msg)&msg);
1534 if (customdraw) return;
1536 if (MENUS_AMIGALOOK)
1538 borderx = mhd->scr->MenuHBorder / 2;
1539 bordery = mhd->scr->MenuVBorder / 2;
1541 else
1543 borderx = 1;
1544 bordery = 1;
1547 /* White background */
1549 if (MENUS_AMIGALOOK)
1551 SetABPenDrMd(rp, mhd->dri->dri_Pens[BARBLOCKPEN], 0, JAM1);
1553 else
1555 SetABPenDrMd(rp, mhd->dri->dri_Pens[BACKGROUNDPEN], 0, JAM1);
1558 RectFill(rp, borderx,
1559 bordery,
1560 win->Width - 1 - borderx,
1561 win->Height - 1 - bordery);
1563 /* Black border frame */
1565 if (MENUS_AMIGALOOK)
1567 SetAPen(rp, mhd->dri->dri_Pens[BARDETAILPEN]);
1568 RectFill(rp, 0, 0, win->Width - 1, bordery - 1);
1569 RectFill(rp, 0, bordery, borderx - 1, win->Height - 1 - bordery);
1570 RectFill(rp, win->Width - borderx, bordery, win->Width - 1, win->Height - 1);
1571 RectFill(rp, 0, win->Height - bordery, win->Width - 1 - borderx, win->Height - 1);
1573 else
1575 RenderFrame(rp, 0, 0, win->Width - 1, win->Height - 1, IDS_NORMAL, mhd, IntuitionBase);
1579 /**************************************************************************************************/
1581 static void RenderCheckMark(struct MenuItem *item, WORD itemtype, struct MenuHandlerData *mhd,
1582 struct IntuitionBase *IntuitionBase)
1584 struct Window *win = ((itemtype == ITEM_ITEM) ? mhd->menuwin : mhd->submenuwin);
1585 struct RastPort *rp = win->RPort;
1586 struct Rectangle *box = ((itemtype == ITEM_ITEM) ? ((struct Rectangle *)&mhd->activemenu->JazzX) : &mhd->submenubox);
1587 WORD offx = -box->MinX + mhd->menuinnerleft;
1588 WORD offy = -box->MinY + mhd->menuinnertop;
1589 WORD state = ((item->Flags & HIGHITEM) &&
1590 ((item->Flags & HIGHFLAGS) == HIGHCOMP)) ? IDS_SELECTED : IDS_NORMAL;
1592 if (item->Flags & CHECKIT)
1594 WORD x1, y1, x2, y2;
1596 x1 = item->LeftEdge + offx;
1597 y1 = item->TopEdge + offy + (item->Height - mhd->checkmark->Height) / 2;
1598 x2 = x1 + mhd->checkmark->Width - 1;
1599 y2 = y1 + mhd->checkmark->Height - 1;
1601 SetDrMd(rp, JAM1);
1603 if (item->Flags & CHECKED)
1605 DrawImageState(rp, mhd->checkmark, x1, y1, state, mhd->dri);
1607 else
1609 if (MENUS_AMIGALOOK)
1611 SetAPen(rp, mhd->dri->dri_Pens[BARBLOCKPEN]);
1613 else
1615 SetAPen(rp, mhd->dri->dri_Pens[(state == IDS_SELECTED) ? FILLPEN : BACKGROUNDPEN]);
1617 BOOL customdraw = FALSE;
1619 struct mdpDrawBackground msg;
1621 msg.MethodID = MDM_DRAWBACKGROUND;
1622 msg.mdp_TrueColor = mhd->TrueColor;
1623 msg.mdp_RPort = rp;
1624 msg.mdp_X = 0;
1625 msg.mdp_Y = 0;
1626 msg.mdp_Width = win->Width - 1;
1627 msg.mdp_Height = win->Height - 1;
1628 msg.mdp_ItemLeft = x1;
1629 msg.mdp_ItemTop = y1;
1630 msg.mdp_ItemWidth = x2 - x1 + 1;
1631 msg.mdp_ItemHeight = y2 - y1 + 1;
1632 msg.mdp_Flags = item->Flags;
1633 if (win == mhd->submenuwin) msg.mdp_UserBuffer = mhd->SubDecorUserBuffer;
1634 else if (win == mhd->menuwin) msg.mdp_UserBuffer = mhd->DecorUserBuffer;
1635 else msg.mdp_UserBuffer = mhd->BarDecorUserBuffer;
1637 customdraw = DoMethodA(((struct IntScreen *)(mhd->scr))->MenuDecorObj, (Msg)&msg);
1639 if (!customdraw) RectFill(rp, x1, y1, x2, y2);
1645 /**************************************************************************************************/
1647 static void RenderAmigaKey(struct MenuItem *item, WORD itemtype, struct MenuHandlerData *mhd,
1648 struct IntuitionBase *IntuitionBase)
1650 struct Window *win = ((itemtype == ITEM_ITEM) ? mhd->menuwin : mhd->submenuwin);
1651 struct RastPort *rp = win->RPort;
1652 struct Rectangle *box = ((itemtype == ITEM_ITEM) ? ((struct Rectangle *)&mhd->activemenu->JazzX) : &mhd->submenubox);
1653 WORD commkeywidth = ((itemtype == ITEM_ITEM) ? mhd->maxcommkeywidth_menu : mhd->maxcommkeywidth_submenu);
1654 WORD offx = -box->MinX + mhd->menuinnerleft;
1655 WORD offy = -box->MinY + mhd->menuinnertop;
1656 WORD state = ((item->Flags & HIGHITEM) &&
1657 ((item->Flags & HIGHFLAGS) == HIGHCOMP)) ? IDS_SELECTED : IDS_NORMAL;
1659 if (item->Flags & COMMSEQ)
1661 struct TextFont *oldfont = rp->Font;
1662 struct TextFont *newfont = NULL;
1664 WORD x1, y1, x2, y2;
1666 if (item->Flags & ITEMTEXT)
1668 struct IntuiText *it = (struct IntuiText *)item->ItemFill;
1670 if (it->ITextFont)
1672 if ((newfont = OpenFont(it->ITextFont)))
1674 SetFont(rp, newfont);
1679 x1 = item->LeftEdge + offx + item->Width - AMIGAKEY_BORDER_SPACING -
1680 mhd->amigakey->Width - AMIGAKEY_KEY_SPACING - commkeywidth;
1681 y1 = item->TopEdge + offy + (item->Height - mhd->amigakey->Height + 1) / 2;
1682 x2 = x1 + mhd->amigakey->Width - 1;
1683 y2 = y1 + mhd->amigakey->Height - 1;
1685 SetDrMd(rp, JAM1);
1687 DrawImageState(rp, mhd->amigakey, x1, y1, state, mhd->dri);
1689 x1 += mhd->amigakey->Width + AMIGAKEY_KEY_SPACING;
1691 if (MENUS_AMIGALOOK)
1693 SetAPen(rp, mhd->dri->dri_Pens[BARDETAILPEN]);
1695 else
1697 SetAPen(rp, mhd->dri->dri_Pens[(item->Flags & HIGHITEM) ? FILLTEXTPEN : TEXTPEN]);
1700 Move(rp, x1, item->TopEdge + offy + (item->Height - rp->TxHeight) / 2 +
1701 rp->TxBaseline);
1702 Text(rp, &item->Command, 1);
1704 if (newfont)
1706 CloseFont(newfont);
1707 SetFont(rp, oldfont);
1710 } /* if (item->Flags & COMMSEQ) */
1713 /**************************************************************************************************/
1715 static void RenderDisabledPattern(struct RastPort *rp, WORD x1, WORD y1, WORD x2, WORD y2,
1716 struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase)
1718 static UWORD pattern [] = {0x8888, 0x2222};
1720 SetDrMd(rp, JAM1);
1722 if (MENUS_AMIGALOOK)
1724 SetAPen(rp, mhd->dri->dri_Pens[BARBLOCKPEN]);
1726 else
1728 SetAPen(rp, mhd->dri->dri_Pens[BACKGROUNDPEN]);
1731 SetAfPt(rp, pattern, 1);
1733 RectFill(rp, x1, y1, x2, y2);
1735 SetAfPt(rp, NULL, 0);
1739 /**************************************************************************************************/
1741 static void RenderFrame(struct RastPort *rp, WORD x1, WORD y1, WORD x2, WORD y2, WORD state,
1742 struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase)
1744 SetAPen(rp, mhd->dri->dri_Pens[(state == IDS_SELECTED) ? SHADOWPEN : SHINEPEN]);
1746 RectFill(rp, x1, y1, x2, y1);
1747 RectFill(rp, x1, y1 + 1, x1, y2);
1749 SetAPen(rp, mhd->dri->dri_Pens[(state == IDS_SELECTED) ? SHINEPEN : SHADOWPEN]);
1750 RectFill(rp, x2, y1 + 1, x2, y2);
1751 RectFill(rp, x1 + 1, y2, x2 - 1, y2);
1753 /**************************************************************************************************/
1755 static void HighlightItem(struct MenuItem *item, WORD itemtype, struct MenuHandlerData *mhd,
1756 struct IntuitionBase *IntuitionBase)
1758 struct Window *win = ((itemtype == ITEM_ITEM) ? mhd->menuwin : mhd->submenuwin);
1759 struct RastPort *rp = win->RPort;
1760 struct Rectangle *box = ((itemtype == ITEM_ITEM) ? ((struct Rectangle *)&mhd->activemenu->JazzX) : &mhd->submenubox);
1761 APTR fill;
1762 WORD offx = -box->MinX + mhd->menuinnerleft;
1763 WORD offy = -box->MinY + mhd->menuinnertop;
1764 WORD x1, y1, x2, y2;
1765 BOOL enabled, customdraw;
1767 enabled = (item->Flags & ITEMENABLED) ? TRUE : FALSE;
1768 if (!(mhd->activemenu->Flags & MENUENABLED)) enabled = FALSE;
1769 if ((itemtype == ITEM_SUBITEM) && !(mhd->activeitem->Flags & ITEMENABLED)) enabled = FALSE;
1771 if (enabled)
1773 item->Flags ^= HIGHITEM;
1775 fill = item->ItemFill;
1776 if ((item->Flags & HIGHITEM) && (item->SelectFill)) fill = item->SelectFill;
1778 x1 = offx + item->LeftEdge;
1779 y1 = offy + item->TopEdge;
1780 x2 = x1 + item->Width - 1;
1781 y2 = y1 + item->Height - 1;
1783 struct mdpDrawBackground msg;
1785 msg.MethodID = MDM_DRAWBACKGROUND;
1786 msg.mdp_TrueColor = mhd->TrueColor;
1787 msg.mdp_RPort = rp;
1788 msg.mdp_X = 0;
1789 msg.mdp_Y = 0;
1790 msg.mdp_Width = win->Width - 1;
1791 msg.mdp_Height = win->Height - 1;
1792 msg.mdp_ItemLeft = x1;
1793 msg.mdp_ItemTop = y1;
1794 msg.mdp_ItemWidth = x2 - x1 + 1;
1795 msg.mdp_ItemHeight = y2 - y1 + 1;
1796 msg.mdp_Flags = item->Flags;
1798 if (win == mhd->submenuwin) msg.mdp_UserBuffer = mhd->SubDecorUserBuffer;
1799 else if (win == mhd->menuwin) msg.mdp_UserBuffer = mhd->DecorUserBuffer;
1800 else msg.mdp_UserBuffer = mhd->BarDecorUserBuffer;
1801 customdraw = DoMethodA(((struct IntScreen *)(mhd->scr))->MenuDecorObj, (Msg)&msg);
1803 if (customdraw) {
1804 SetDrMd(rp, JAM1);
1806 if(item->Flags & ITEMTEXT)
1808 struct IntuiText *save = ((struct IntuiText*) fill)->NextText;
1810 if (item->SubItem)
1812 Forbid();
1813 ((struct IntuiText*) fill)->NextText = NULL;
1816 if (MENUS_AMIGALOOK)
1818 PrintIText(rp, (struct IntuiText *)fill, x1, y1);
1820 else
1822 struct IntuiText *it = (struct IntuiText *)fill;
1824 it->FrontPen = mhd->dri->dri_Pens[TEXTPEN];
1825 it->DrawMode = JAM1;
1827 PrintIText(rp, it, x1, y1);
1829 if (item->SubItem)
1831 DrawImageState(rp, mhd->submenuimage, offx + item->Width - mhd->submenuimage->Width, offy + item->TopEdge + ((item->Height - mhd->submenuimage->Height) >> 1), IDS_NORMAL, mhd->dri);
1832 ((struct IntuiText*) fill)->NextText = save;
1833 Permit();
1836 else
1838 EraseImage(rp, (struct Image *)fill, x1, y1);
1839 DrawImageState(rp, (struct Image *)fill, x1, y1, IDS_SELECTED, mhd->dri);
1841 RenderItem(item, itemtype, box, mhd, IntuitionBase);
1842 return;
1845 switch(item->Flags & HIGHFLAGS)
1847 case HIGHIMAGE:
1848 SetDrMd(rp, JAM1);
1850 if(item->Flags & ITEMTEXT)
1852 struct IntuiText *save = ((struct IntuiText*) fill)->NextText;
1854 if (item->SubItem)
1856 Forbid();
1857 ((struct IntuiText*) fill)->NextText = NULL;
1859 if (MENUS_AMIGALOOK)
1861 PrintIText(rp, (struct IntuiText *)fill, x1, y1);
1863 else
1865 struct IntuiText *it = (struct IntuiText *)fill;
1867 it->FrontPen = mhd->dri->dri_Pens[TEXTPEN];
1868 it->DrawMode = JAM1;
1870 PrintIText(rp, it, x1, y1);
1872 if (item->SubItem)
1874 DrawImageState(rp, mhd->submenuimage, offx + item->Width - mhd->submenuimage->Width, offy + item->TopEdge + ((item->Height - mhd->submenuimage->Height) >> 1), IDS_NORMAL, mhd->dri);
1875 ((struct IntuiText*) fill)->NextText = save;
1876 Permit();
1879 else
1881 EraseImage(rp, (struct Image *)fill, x1, y1);
1882 DrawImageState(rp, (struct Image *)fill, x1, y1, IDS_SELECTED, mhd->dri);
1884 break;
1886 case HIGHCOMP:
1887 if (MENUS_AMIGALOOK)
1889 SetDrMd(rp, COMPLEMENT);
1890 RectFill(rp, x1, y1, x2, y2);
1892 else
1894 WORD state = (item->Flags & HIGHITEM) ? IDS_SELECTED : IDS_NORMAL;
1896 SetDrMd(rp, JAM1);
1897 SetAPen(rp, mhd->dri->dri_Pens[(state == IDS_SELECTED) ? FILLPEN : BACKGROUNDPEN]);
1898 RectFill(rp, x1, y1, x2, y2);
1900 RenderItem(item, itemtype, box, mhd, IntuitionBase);
1902 if (state == IDS_SELECTED)
1904 RenderFrame(rp, x1, y1, x2, y2, state, mhd, IntuitionBase);
1907 break;
1909 case HIGHBOX:
1910 SetDrMd(rp, COMPLEMENT);
1911 offx = mhd->scr->MenuHBorder;
1912 offy = mhd->scr->MenuVBorder;
1914 x1 -= offx;
1915 x2 += offx;
1916 y1 -= offy;
1917 y2 += offy;
1919 RectFill(rp, x1, y1, x2, y1 + offy - 1);
1920 RectFill(rp, x2 - offx + 1, y1 + offy, x2, y2);
1921 RectFill(rp, x1, y2 - offy + 1, x2 - offx, y2);
1922 RectFill(rp, x1, y1 + offy, x1 + offx - 1,y2 - offy);
1923 break;
1925 case HIGHNONE:
1926 /* Do nothing */
1927 break;
1929 } /* switch(item->Flags & HIGHFLAGS) */
1931 } /* if (enabled) */
1935 /**************************************************************************************************/
1937 static WORD CalcMaxCommKeyWidth(struct Window *win, struct MenuHandlerData *mhd,
1938 struct IntuitionBase *IntuitionBase)
1940 struct TextExtent te;
1941 WORD maxwidth;
1943 FontExtent(mhd->dri->dri_Font, &te);
1944 maxwidth = te.te_Width;
1946 if (win)
1948 struct MenuItem *item;
1950 if ((win == mhd->menuwin))
1952 item = mhd->activemenu->FirstItem;
1954 else
1956 item = mhd->activeitem->SubItem;
1959 for(; item; item = item->NextItem)
1961 if (item->Flags & ITEMTEXT)
1963 struct IntuiText *it = (struct IntuiText *)item->ItemFill;
1965 if (it->ITextFont)
1967 struct TextFont *font;
1969 if ((font = OpenFont(it->ITextFont)))
1971 FontExtent(font, &te);
1972 if (te.te_Width > maxwidth) maxwidth = te.te_Width;
1974 CloseFont(font);
1978 } /* if (item->Flags & ITEMTEXT) */
1980 } /* for(; item; item = item->NextItem); */
1982 } /* if (win) */
1984 return maxwidth;
1987 /**************************************************************************************************/
1989 static void AddToSelection(struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase)
1991 if ((mhd->activemenunum != -1) && (mhd->activemenu->Flags & MENUENABLED) &&
1992 (mhd->activeitemnum != -1) && (mhd->activeitem->Flags & ITEMENABLED))
1994 struct MenuItem *item = NULL;
1995 UWORD men = FULLMENUNUM(mhd->activemenunum, mhd->activeitemnum, mhd->activesubitemnum);
1997 if (mhd->activesubitemnum != -1)
1999 if (mhd->activesubitem->Flags & ITEMENABLED) item = mhd->activesubitem;
2001 else if (!mhd->activeitem->SubItem)
2003 item = mhd->activeitem;
2006 if (item && (ItemAddress(mhd->menu, men) == item))
2008 UWORD men = FULLMENUNUM(mhd->activemenunum, mhd->activeitemnum, mhd->activesubitemnum);
2010 if (mhd->firstmenupick == MENUNULL)
2012 mhd->firstmenupick = men;
2014 else if (men != mhd->lastmenupick)
2016 struct MenuItem *checkitem, *prevcheckitem = NULL;
2017 UWORD checkmen = mhd->firstmenupick;
2019 /* Remove men from pick queue, if it was already in there
2020 and then add it at the end of the pick queue */
2022 while(checkmen != MENUNULL)
2024 checkitem = ItemAddress(mhd->menu, checkmen);
2026 if (checkmen == men)
2028 if (prevcheckitem == NULL)
2030 mhd->firstmenupick = checkitem->NextSelect;
2032 else
2034 prevcheckitem->NextSelect = checkitem->NextSelect;
2038 checkmen = checkitem->NextSelect;
2039 prevcheckitem = checkitem;
2041 } /* while(checkmen != MENUNULL) */
2043 checkitem->NextSelect = men;
2045 } /* else if (men != mhd->lastmenupick) */
2047 mhd->lastmenupick = men;
2048 item->NextSelect = MENUNULL;
2050 } /* if (item) */
2052 } /* if ((mhd->activemenunum != -1) && (mhd->activeitemnum != -1)) */