try to make sure compiler/include/mmakefile is always refreshed correctly.
[AROS.git] / rom / intuition / menutask.c
blob7374b05333faced207a13c70bdc102e4b4e50ba0
1 /*
2 Copyright © 1995-2017, 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);
103 /**************************************************************************************************/
105 /***************************
106 ** DefaultMenuHandler() **
107 ***************************/
108 void DefaultMenuHandler(struct MenuTaskParams *taskparams)
110 struct IntuitionBase *IntuitionBase = taskparams->intuitionBase;
111 struct GfxBase *GfxBase = GetPrivIBase(IntuitionBase)->GfxBase;
112 struct MenuHandlerData *mhd = NULL;
113 struct MsgPort *port = NULL;
114 BOOL success = FALSE;
116 if ((mhd = (struct MenuHandlerData *)AllocMem(sizeof(struct MenuHandlerData), MEMF_PUBLIC | MEMF_CLEAR)))
118 port = CreateMsgPort();
120 success = TRUE;
121 } /* if ((mem = AllocMem(sizeof(struct MsgPort), MEMF_PUBLIC | MEMF_CLEAR))) */
123 if (success)
125 taskparams->MenuHandlerPort = port;
126 taskparams->success = TRUE;
129 Signal(taskparams->Caller, SIGF_INTUITION);
131 if (!success)
133 D(bug("DefaultMenuHandler: initialization failed. waiting for parent task to kill me.\n"));
134 Wait(0);
137 D(bug("DefaultMenuHandler: initialization ok. Now waiting for messages from Intuition.\n"));
139 for(;;)
141 struct MenuMessage *msg;
143 WaitPort(port);
144 while((msg = GetMenuMessage(port, IntuitionBase)))
146 switch(msg->code)
148 case MMCODE_START:
149 mhd->win = msg->win;
150 mhd->scr = mhd->win->WScreen;
151 mhd->dri = GetScreenDrawInfo(mhd->scr);
152 mhd->menu = msg->win->MenuStrip;
153 mhd->activemenunum = -1;
154 mhd->activeitemnum = -1;
155 mhd->activesubitemnum = -1;
156 mhd->checkmark = ((struct IntWindow *)mhd->win)->Checkmark;
157 mhd->amigakey = ((struct IntWindow *)mhd->win)->AmigaKey;
158 mhd->submenuimage = ((struct IntWindow *)mhd->win)->SubMenuImage;
159 mhd->scrmousex = mhd->scr->MouseX;
160 mhd->scrmousey = mhd->scr->MouseY;
161 mhd->firstmenupick = MENUNULL;
162 mhd->keepmenuup = TRUE;
163 mhd->TrueColor = GetBitMapAttr(mhd->scr->RastPort.BitMap, BMA_DEPTH) > 8 ? TRUE: FALSE;
165 /* close windows in the back first because
166 this is faster */
167 MakeMenuBarWin(mhd, IntuitionBase);
168 HandleMouseMove(mhd, IntuitionBase);
169 mhd->active = TRUE;
170 break;
172 case MMCODE_EVENT:
173 /* there might come additional messages from Intuition
174 even when we have already told it to make the menus
175 inactive, but since everything is async, this cannot
176 be avoided, so check if we are really active */
178 if (mhd->active)
180 switch(msg->ie.ie_Class)
182 case IECLASS_RAWMOUSE:
183 if (msg->ie.ie_Code == IECODE_NOBUTTON)
185 HandleMouseMove(mhd, IntuitionBase);
187 else
189 HandleMouseClick(&msg->ie, mhd, IntuitionBase);
191 break;
194 } /* if (mhd->active) */
195 break;
197 } /* switch(msg->code) */
199 ReplyMenuMessage(msg, IntuitionBase);
201 } /* while((msg = (struct MenuMessage *)GetMsg(port))) */
203 } /* for(;;) */
205 /* should never reach here but just incase.. */
206 if (port)
207 DeleteMsgPort(port);
210 /**************************************************************************************************/
212 /*******************************
213 ** InitDefaultMenuHandler() **
214 *******************************/
215 BOOL InitDefaultMenuHandler(struct IntuitionBase *IntuitionBase)
217 struct MenuTaskParams params;
218 struct Task *task;
219 BOOL result = FALSE;
221 params.intuitionBase = IntuitionBase;
222 params.Caller = FindTask(NULL);
223 params.success = FALSE;
225 SetSignal(0, SIGF_INTUITION);
227 task = NewCreateTask(TASKTAG_NAME, "Intuition menu handler",
228 TASKTAG_PC , DefaultMenuHandler,
229 TASKTAG_ARG1, &params,
230 TAG_DONE);
232 if (task)
234 Wait(SIGF_INTUITION);
236 if (params.success)
238 result = TRUE;
239 GetPrivIBase(IntuitionBase)->MenuHandlerPort = params.MenuHandlerPort;
241 else
243 RemTask(task);
246 } /* if ((task = CreateMenuHandlerTask(&params, IntuitionBase))) */
248 return result;
252 /**************************************************************************************************/
254 static void HandleMouseMove(struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase)
256 struct LayersBase *LayersBase = GetPrivIBase(IntuitionBase)->LayersBase;
257 struct Layer *lay;
258 struct Window *win = NULL;
259 struct Menu *menu;
260 struct MenuItem *item;
261 WORD new_activemenunum = mhd->activemenunum;
262 WORD new_activeitemnum = mhd->activeitemnum;
263 WORD new_activesubitemnum = mhd->activesubitemnum;
265 mhd->scrmousex = mhd->scr->MouseX;
266 mhd->scrmousey = mhd->scr->MouseY;
268 LockLayerInfo(&mhd->scr->LayerInfo);
269 lay = WhichLayer(&mhd->scr->LayerInfo, mhd->scrmousex, mhd->scrmousey);
270 UnlockLayerInfo(&mhd->scr->LayerInfo);
272 if (lay)
274 win = (struct Window *)lay->Window;
276 if (win && (win == mhd->submenuwin))
278 /* Mouse over submenu box */
279 item = FindSubItem(&new_activesubitemnum, mhd);
281 if (new_activesubitemnum != mhd->activesubitemnum)
283 if (mhd->activesubitemnum != -1)
285 HighlightItem(mhd->activesubitem, ITEM_SUBITEM, mhd, IntuitionBase);
288 mhd->activesubitemnum = new_activesubitemnum;
289 mhd->activesubitem = item;
291 if (item)
293 HighlightItem(mhd->activesubitem, ITEM_SUBITEM, mhd, IntuitionBase);
298 else if (win && (win == mhd->menuwin))
300 item = FindItem(&new_activeitemnum, mhd);
302 if (new_activeitemnum != mhd->activeitemnum)
304 if (mhd->activeitemnum != -1)
306 HighlightItem(mhd->activeitem, ITEM_ITEM, mhd, IntuitionBase);
307 KillSubMenuWin(mhd, IntuitionBase);
310 mhd->activeitemnum = new_activeitemnum;
311 mhd->activeitem = item;
313 if (item)
315 HighlightItem(mhd->activeitem, ITEM_ITEM, mhd, IntuitionBase);
317 if (item->SubItem)
319 MakeSubMenuWin(mhd, IntuitionBase);
323 } /* if (win && (win == mhd->menuwin)) */
324 else if (win && (win == mhd->menubarwin))
326 /* Mouse over menu box */
328 menu = FindMenu(&new_activemenunum, mhd, IntuitionBase);
330 if (new_activemenunum != mhd->activemenunum)
333 if (mhd->activemenunum != -1)
335 HighlightMenuTitle(mhd->activemenu, mhd, IntuitionBase);
336 KillMenuWin(mhd, IntuitionBase);
337 KillSubMenuWin(mhd, IntuitionBase);
340 mhd->activemenunum = new_activemenunum;
341 mhd->activemenu = menu;
343 if (menu)
345 HighlightMenuTitle(mhd->activemenu, mhd, IntuitionBase);
346 MakeMenuWin(mhd, IntuitionBase);
350 if ((mhd->activeitemnum != -1) && (!mhd->submenuwin))
352 HighlightItem(mhd->activeitem, ITEM_ITEM, mhd, IntuitionBase);
353 mhd->activeitemnum = -1;
354 mhd->activeitem = NULL;
357 } /* if (win && (win == mhd->menubarwin)) */
358 else
360 win = NULL;
362 } /* if ((lay = WhichLayer(&mhd->scr->LayerInfo, mhd->scrmousex, mhd->scrmousey))) */
364 if (!win)
366 /* mouse outside any menu window */
368 if ((mhd->activeitemnum != -1) && (!mhd->submenuwin))
370 HighlightItem(mhd->activeitem, ITEM_ITEM, mhd, IntuitionBase);
371 mhd->activeitemnum = -1;
372 mhd->activeitem = NULL;
374 else if (mhd->activesubitemnum != -1)
376 HighlightItem(mhd->activesubitem, ITEM_SUBITEM, mhd, IntuitionBase);
377 mhd->activesubitemnum = -1;
378 mhd->activesubitem = NULL;
384 /**************************************************************************************************/
386 static void HandleSelection(struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase)
388 struct LayersBase *LayersBase = GetPrivIBase(IntuitionBase)->LayersBase;
389 struct Layer *lay;
391 LockLayerInfo(&mhd->scr->LayerInfo);
392 lay = WhichLayer(&mhd->scr->LayerInfo, mhd->scrmousex, mhd->scrmousey);
393 UnlockLayerInfo(&mhd->scr->LayerInfo);
395 if (lay)
397 struct Window *win = (struct Window *)lay->Window;
398 struct MenuItem *item = NULL;
400 if (win && (win == mhd->submenuwin) && (mhd->activesubitemnum != -1))
401 item = mhd->activesubitem;
402 else if (win && (win == mhd->menuwin) && (mhd->activeitemnum != -1))
403 item = mhd->activeitem;
405 if (item) {
406 if (item->Flags & CHECKIT)
407 HandleCheckItem(win, item, mhd, IntuitionBase);
410 AddToSelection(mhd, IntuitionBase);
414 /**************************************************************************************************/
416 static void HandleMouseClick(struct InputEvent *ie, struct MenuHandlerData *mhd,
417 struct IntuitionBase *IntuitionBase)
419 BOOL die = FALSE;
420 ULONG sticky = GetPrivIBase(IntuitionBase)->IControlPrefs.ic_Flags & ICF_STICKYMENUS; /* ic_Flags is ULONG */
422 switch(ie->ie_Code)
424 case MENUUP:
425 sticky = sticky && (DoubleClick(
426 GetPrivIBase(IntuitionBase)->LastMenuDownSecs,
427 GetPrivIBase(IntuitionBase)->LastMenuDownMicro,
428 ie->ie_TimeStamp.tv_secs, ie->ie_TimeStamp.tv_micro)
429 || mhd->keepmenuup);
430 if (sticky)
431 break;
433 case SELECTDOWN:
434 if (!sticky)
436 HandleSelection(mhd, IntuitionBase);
438 if (ie->ie_Code == MENUUP)
439 die = TRUE;
442 break;
444 case SELECTUP:
445 if (sticky)
447 HandleSelection(mhd, IntuitionBase);
448 die = TRUE;
450 break;
452 case MENUDOWN:
453 if (sticky)
455 if (mhd->keepmenuup)
456 mhd->keepmenuup = FALSE;
457 else {
458 HandleSelection(mhd, IntuitionBase);
459 die = TRUE;
461 GetPrivIBase(IntuitionBase)->LastMenuDownSecs =
462 ie->ie_TimeStamp.tv_secs;
463 GetPrivIBase(IntuitionBase)->LastMenuDownMicro =
464 ie->ie_TimeStamp.tv_micro;
466 break;
467 } /* switch(ie->ie_Code) */
469 if (die)
471 KillMenuBarWin(mhd, IntuitionBase);
472 KillMenuWin(mhd, IntuitionBase);
473 KillSubMenuWin(mhd, IntuitionBase);
475 if (mhd->dri)
477 FreeScreenDrawInfo(mhd->scr, mhd->dri);
478 mhd->dri = 0;
480 MH2Int_MakeMenusInactive(mhd->win, mhd->firstmenupick, IntuitionBase);
481 mhd->active = FALSE;
485 /**************************************************************************************************/
487 static void HandleCheckItem(struct Window *win, struct MenuItem *item,
488 struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase)
490 /* Note: If you change something here, you probably must also change
491 menus.c/CheckMenuItemWasClicked() which is used when the
492 user uses the menu key shortcuts! */
494 WORD itemtype = ((win == mhd->menuwin) ? ITEM_ITEM : ITEM_SUBITEM);
496 BOOL re_render = FALSE;
498 if (item->Flags & MENUTOGGLE)
500 item->Flags ^= CHECKED;
501 re_render = TRUE;
503 else
505 if (!(item->Flags & CHECKED))
507 item->Flags |= CHECKED;
508 re_render = TRUE;
512 if (re_render)
514 BOOL toggle_hi = FALSE;
516 if ((item->Flags & HIGHITEM) &&
517 ((item->Flags & HIGHFLAGS) == HIGHCOMP)) toggle_hi = TRUE;
519 if (toggle_hi) HighlightItem(item, itemtype, mhd, IntuitionBase);
520 RenderCheckMark(item, itemtype, mhd, IntuitionBase);
521 if (toggle_hi) HighlightItem(item, itemtype, mhd, IntuitionBase);
525 if (item->MutualExclude)
527 struct MenuItem *checkitem = (itemtype == ITEM_ITEM) ? mhd->activemenu->FirstItem :
528 mhd->activeitem->SubItem;
529 BOOL toggle_hi = FALSE;
530 WORD i;
532 if ((item->Flags & HIGHITEM) &&
533 ((item->Flags & HIGHFLAGS) == HIGHBOX)) toggle_hi = TRUE;
535 if (toggle_hi) HighlightItem(item, itemtype, mhd, IntuitionBase);
537 for(i = 0; (i < 32) && checkitem; i++, checkitem = checkitem->NextItem)
539 if ((item->MutualExclude & (1L << i)) &&
540 ((checkitem->Flags & (CHECKED | CHECKIT)) == (CHECKIT | CHECKED)))
542 checkitem->Flags &= ~CHECKED;
543 RenderCheckMark(checkitem, itemtype, mhd, IntuitionBase);
547 if (toggle_hi) HighlightItem(item, itemtype, mhd, IntuitionBase);
549 } /* if (item->MutualExclude) */
552 /**************************************************************************************************/
554 static inline BOOL CustomDrawBackground(struct RastPort *rp, struct Window *win,
555 LONG itemleft, LONG itemtop, LONG itemwidth, LONG itemheight, UWORD flags,
556 struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase)
558 struct mdpDrawBackground msg;
560 msg.MethodID = MDM_DRAWBACKGROUND;
561 msg.mdp_RPort = rp;
562 msg.mdp_TrueColor = mhd->TrueColor;
563 msg.mdp_X = 0;
564 msg.mdp_Y = 0;
565 msg.mdp_Width = win->Width - 1;
566 msg.mdp_Height = win->Height - 1;
567 msg.mdp_ItemLeft = itemleft;
568 msg.mdp_ItemTop = itemtop;
569 msg.mdp_ItemWidth = itemwidth;
570 msg.mdp_ItemHeight = itemheight;
571 msg.mdp_Flags = flags;
573 msg.mdp_MenuDecorFlags = (MENUS_UNDERMOUSE(IntuitionBase)) ? MDP_MDF_MENUS_UNDERMOUSE : 0;
574 if (win == mhd->submenuwin) { msg.mdp_UserBuffer = mhd->SubDecorUserBuffer; msg.mdp_MenuDecorFlags |= MDP_MDF_SUBITEM; }
575 else if (win == mhd->menuwin) { msg.mdp_UserBuffer = mhd->DecorUserBuffer; msg.mdp_MenuDecorFlags |= MDP_MDF_ITEM; }
576 else { msg.mdp_UserBuffer = mhd->BarDecorUserBuffer; msg.mdp_MenuDecorFlags |= MDP_MDF_MENU; }
578 return DoMethodA(((struct IntScreen *)(mhd->scr))->MenuDecorObj, (Msg)&msg);
581 /**************************************************************************************************/
583 static void HighlightMenuTitle(struct Menu *menu, struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase)
585 struct GfxBase *GfxBase = GetPrivIBase(IntuitionBase)->GfxBase;
587 if ((menu->Flags & MENUENABLED) && mhd->menubarwin)
589 struct RastPort *rp = mhd->menubarwin->RPort;
590 WORD x1, x2, y1, y2;
592 if (MENUS_UNDERMOUSE(IntuitionBase))
594 WORD i;
595 struct Menu *m = mhd->menu;
597 x1 = mhd->innerleft;
599 x2 = x1 + mhd->menubaritemwidth - 1;
601 for(i = 0; m != menu; m = m->NextMenu) i++;
603 y1 = mhd->innertop + i * mhd->menubaritemheight;
604 y2 = y1 + mhd->menubaritemheight - 1;
607 else
609 x1 = menu->LeftEdge + mhd->scr->BarHBorder - mhd->scr->MenuHBorder;
610 if (x1 < 0) x1 = 0;
611 y1 = 0;
612 x2 = x1 + menu->Width - 1;
613 y2 = mhd->scr->BarHeight - 1;
616 menu->Flags ^= HIGHITEM;
617 if (CustomDrawBackground(rp, mhd->win, x1, y1, x2 - x1 + 1, y2 - y1 + 1, menu->Flags, mhd, IntuitionBase))
619 RenderMenuTitle(menu, mhd, IntuitionBase);
620 return;
623 if (MENUS_AMIGALOOK(IntuitionBase))
625 SetDrMd(rp, COMPLEMENT);
626 RectFill(rp, x1, y1, x2, y2);
628 else
630 if (!MENUS_UNDERMOUSE(IntuitionBase))
631 y1++;
633 SetDrMd(rp, JAM1);
634 SetAPen(rp, mhd->dri->dri_Pens[(menu->Flags & HIGHITEM) ? FILLPEN : BACKGROUNDPEN]);
635 RectFill(rp, x1, y1, x2, y2);
636 RenderMenuTitle(menu, mhd, IntuitionBase);
638 if ((menu->Flags & HIGHITEM))
640 if (MENUS_UNDERMOUSE(IntuitionBase))
642 RenderFrame(rp, x1, y1, x2, y2, IDS_SELECTED, mhd, IntuitionBase);
644 else
646 SetAPen(rp, mhd->dri->dri_Pens[SHINEPEN]);
647 RectFill(rp, x1, y1, x1, y2);
648 SetAPen(rp, mhd->dri->dri_Pens[SHADOWPEN]);
649 RectFill(rp, x2, y1, x2, y2);
656 /**************************************************************************************************/
658 static struct Menu *FindMenu(WORD *var, struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase)
660 struct Menu *menu = NULL;
661 WORD mouse_x, mouse_y, i;
663 if(mhd->menubarwin)
665 mouse_x = mhd->scrmousex - mhd->menubarwin->LeftEdge;
666 mouse_y = mhd->scrmousey - mhd->menubarwin->TopEdge;
668 if (MENUS_UNDERMOUSE(IntuitionBase))
670 menu = NULL;
672 mouse_x -= mhd->innerleft;
673 mouse_y -= mhd->innertop;
675 if ((mouse_x >= 0) && (mouse_x < mhd->menubaritemwidth) && (mouse_y >= 0))
677 i = mouse_y / mhd->menubaritemheight;
679 if ((i >= 0) && (i < mhd->nummenubaritems))
681 WORD i2 = i;
683 menu = mhd->menu;
684 while(i && menu)
686 i--;
687 menu = menu->NextMenu;
690 if (menu && (i == 0))
692 *var = i2;
697 else
699 for(menu = mhd->menu, i = 0; menu; menu = menu->NextMenu, i++)
701 if ((mouse_x >= menu->LeftEdge) &&
702 (mouse_x < menu->LeftEdge + menu->Width) &&
703 (mouse_y >= 0) &&
704 (mouse_y <= mhd->scr->BarHeight))
706 *var = i;
707 break;
712 return menu;
715 /**************************************************************************************************/
717 static struct MenuItem *FindItem(WORD *var, struct MenuHandlerData *mhd)
719 struct MenuItem *item = NULL;
720 WORD mouse_x, mouse_y, i;
722 if (mhd->menuwin)
724 mouse_x = mhd->scrmousex - mhd->menuwin->LeftEdge
725 + mhd->activemenu->JazzX - mhd->menuinnerleft;
726 mouse_y = mhd->scrmousey - mhd->menuwin->TopEdge
727 + mhd->activemenu->JazzY - mhd->menuinnertop;
729 for(item = mhd->activemenu->FirstItem, i = 0; item; item = item->NextItem, i++)
731 if ((mouse_x >= item->LeftEdge) &&
732 (mouse_x < item->LeftEdge + item->Width) &&
733 (mouse_y >= item->TopEdge) &&
734 (mouse_y < item->TopEdge + item->Height))
736 *var = i;
737 break;
740 } /* if (mhd->menuwin) */
742 if ((item == NULL) && !mhd->submenuwin) *var = -1;
744 return item;
747 /**************************************************************************************************/
749 static struct MenuItem *FindSubItem(WORD *var, struct MenuHandlerData *mhd)
751 struct MenuItem *item = NULL;
752 WORD mouse_x, mouse_y, i;
754 if (mhd->submenuwin)
756 mouse_x = mhd->scrmousex - mhd->submenuwin->LeftEdge + mhd->submenubox.MinX - mhd->menuinnerleft;
757 mouse_y = mhd->scrmousey - mhd->submenuwin->TopEdge + mhd->submenubox.MinY - mhd->menuinnertop;
759 *var = -1;
761 for(item = mhd->activeitem->SubItem, i = 0; item; item = item->NextItem, i++)
763 if ((mouse_x >= item->LeftEdge) &&
764 (mouse_x < item->LeftEdge + item->Width) &&
765 (mouse_y >= item->TopEdge) &&
766 (mouse_y < item->TopEdge + item->Height))
768 *var = i;
769 break;
773 } /* if (mhd->menuwin) */
775 return item;
778 /**************************************************************************************************/
780 static void MakeMenuBarWin(struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase)
782 struct GfxBase *GfxBase = GetPrivIBase(IntuitionBase)->GfxBase;
783 struct TagItem win_tags[] =
785 {WA_Left , 0 },
786 {WA_Top , 0 },
787 {WA_Width , mhd->scr->Width },
788 {WA_Height , mhd->scr->BarHeight + 1},
789 {WA_AutoAdjust , TRUE },
790 {WA_Borderless , TRUE },
791 {WA_CustomScreen, (IPTR)mhd->scr },
792 {WA_BackFill , (IPTR)LAYERS_NOBACKFILL},
793 {TAG_DONE , 0 }
795 struct Menu *menu;
797 mhd->menubarwin = NULL;
798 /* No entry to draw ? */
799 if(mhd->menu == NULL) return;
801 if (MENUS_UNDERMOUSE(IntuitionBase))
803 struct RastPort *temprp;
804 WORD w, maxw = 0;
806 if (!(temprp = CloneRastPort(&mhd->scr->RastPort))) return;
808 mhd->nummenubaritems = 0;
809 for(menu = mhd->menu; menu; menu = menu->NextMenu)
811 w = TextLength(temprp, menu->MenuName, strlen(menu->MenuName));
812 if (w > maxw) maxw = w;
813 mhd->nummenubaritems++;
816 mhd->menubaritemwidth = maxw + mhd->submenuimage->Width +
817 TEXT_AMIGAKEY_SPACING +
818 ITEXT_EXTRA_LEFT +
819 ITEXT_EXTRA_RIGHT;
821 if (temprp->TxHeight > mhd->submenuimage->Height)
823 mhd->menubaritemheight = temprp->TxHeight;
825 else
827 mhd->menubaritemheight = mhd->submenuimage->Height;
830 mhd->menubaritemheight += (ITEXT_EXTRA_TOP + ITEXT_EXTRA_BOTTOM);
832 struct mdpGetMenuSpaces msg;
834 msg.MethodID = MDM_GETMENUSPACES;
835 msg.mdp_TrueColor = mhd->TrueColor;
836 msg.mdp_InnerLeft = mhd->scr->MenuHBorder;
837 msg.mdp_InnerTop = mhd->scr->MenuVBorder;
838 msg.mdp_InnerRight = mhd->scr->MenuHBorder;
839 msg.mdp_InnerBottom = mhd->scr->MenuVBorder;
840 msg.mdp_ItemInnerLeft = 0;
841 msg.mdp_ItemInnerTop = 0;
842 msg.mdp_ItemInnerRight = 0;
843 msg.mdp_ItemInnerBottom = 0;
844 msg.mdp_MinWidth = 0;
845 msg.mdp_MinHeight = 0;
846 DoMethodA(((struct IntScreen *)(mhd->scr))->MenuDecorObj, (Msg)&msg);
847 mhd->innerleft = msg.mdp_InnerLeft;
848 mhd->innerright = msg.mdp_InnerRight;
849 mhd->innertop = msg.mdp_InnerTop;
850 mhd->innerbottom = msg.mdp_InnerBottom;
851 mhd->iteminnerleft = msg.mdp_ItemInnerLeft;
852 mhd->iteminnerright = msg.mdp_ItemInnerRight;
853 mhd->iteminnertop = msg.mdp_ItemInnerTop;
854 mhd->iteminnerbottom = msg.mdp_ItemInnerBottom;
855 mhd->menubaritemwidth += (mhd->iteminnerleft + mhd->iteminnerright);
856 mhd->menubaritemheight += (mhd->iteminnertop + mhd->iteminnerbottom);
858 win_tags[2].ti_Data = mhd->menubaritemwidth + mhd->innerleft + mhd->innerright;
859 win_tags[3].ti_Data = mhd->menubaritemheight * mhd->nummenubaritems + mhd->innertop + mhd->innerbottom;
861 if (win_tags[2].ti_Data < msg.mdp_MinWidth)
863 mhd->menubaritemwidth += (msg.mdp_MinWidth - win_tags[2].ti_Data);
864 win_tags[2].ti_Data = msg.mdp_MinWidth;
867 if (win_tags[3].ti_Data < msg.mdp_MinHeight)
869 win_tags[3].ti_Data = msg.mdp_MinHeight;
872 WORD PosX = mhd->scr->MouseX - win_tags[2].ti_Data / 2;
873 win_tags[1].ti_Data = mhd->scr->MouseY;
875 if ((PosX + win_tags[2].ti_Data) > mhd->scr->Width) PosX = mhd->scr->Width - win_tags[2].ti_Data;
876 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;
877 if (PosX < 0) PosX = 0;
878 if (win_tags[1].ti_Data > 32000) win_tags[1].ti_Data = 0;
880 win_tags[0].ti_Data = PosX;
882 FreeRastPort(temprp);
886 IPTR userbuffersize;
887 struct mdpInitMenu msg;
889 GetAttr(MDA_UserBuffer, ((struct IntScreen *)(mhd->scr))->MenuDecorObj, &userbuffersize);
891 if (userbuffersize)
893 mhd->DecorUserBufferSize = userbuffersize;
894 mhd->BarDecorUserBuffer = (IPTR) AllocMem(userbuffersize, MEMF_ANY | MEMF_CLEAR);
895 if (0 == mhd->BarDecorUserBuffer) return;
898 msg.MethodID = MDM_INITMENU;
899 msg.mdp_TrueColor = mhd->TrueColor;
900 msg.mdp_RPort = &mhd->scr->RastPort;
901 msg.mdp_Left = win_tags[0].ti_Data;
902 msg.mdp_Top = win_tags[1].ti_Data;
903 msg.mdp_Width = win_tags[2].ti_Data;
904 msg.mdp_Height = win_tags[3].ti_Data;
905 msg.mdp_UserBuffer = mhd->BarDecorUserBuffer;
906 msg.mdp_ScreenUserBuffer = ((struct IntScreen *) mhd->scr)->DecorUserBuffer;
907 msg.mdp_MenuDecorFlags = (MENUS_UNDERMOUSE(IntuitionBase)) ? MDP_MDF_MENUS_UNDERMOUSE : 0;
908 msg.mdp_MenuDecorFlags |= MDP_MDF_MENU;
910 msg.mdp_Screen = mhd->scr;
912 DoMethodA(((struct IntScreen *)(mhd->scr))->MenuDecorObj, (Msg)&msg);
916 D(bug("MakeMenuBarWin: mhd 0x%lx\n", mhd));
918 mhd->menubarwin = OpenWindowTagList(0, win_tags);
920 for(menu = mhd->menu; menu; menu = menu->NextMenu)
922 menu->Flags &= ~HIGHITEM;
925 RenderMenuBar(mhd, IntuitionBase);
928 /**************************************************************************************************/
930 static void KillMenuBarWin(struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase)
932 if (mhd->menubarwin)
934 struct mdpExitMenu msg;
936 CloseWindow(mhd->menubarwin);
937 mhd->menubarwin = NULL;
939 msg.MethodID = MDM_EXITMENU;
940 msg.mdp_UserBuffer = mhd->BarDecorUserBuffer;
941 msg.mdp_TrueColor = mhd->TrueColor;
942 DoMethodA(((struct IntScreen *)(mhd->scr))->MenuDecorObj, (Msg)&msg);
944 if (mhd->BarDecorUserBuffer)
946 FreeMem((void *)mhd->BarDecorUserBuffer, mhd->DecorUserBufferSize);
948 mhd->BarDecorUserBuffer = 0;
953 /**************************************************************************************************/
955 static void RenderMenuBar(struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase)
957 struct GfxBase *GfxBase = GetPrivIBase(IntuitionBase)->GfxBase;
958 if (mhd->menubarwin)
960 struct Menu *menu = mhd->menu;
961 struct Window *win = mhd->menubarwin;
962 struct RastPort *rp = win->RPort;
964 SetFont(rp, mhd->dri->dri_Font);
966 /* Bar renders using different pens in Amiga mode than rest of menu */
967 if (MENUS_UNDERMOUSE(IntuitionBase))
969 RenderMenuBG(win, mhd, IntuitionBase);
971 else
973 if (!CustomDrawBackground(rp, win, 0, 0, win->Width - 1, win->Height - 1, 0, mhd, IntuitionBase))
975 if (MENUS_AMIGALOOK(IntuitionBase))
977 SetABPenDrMd(rp, mhd->dri->dri_Pens[BARBLOCKPEN], 0, JAM1);
979 else
981 SetABPenDrMd(rp, mhd->dri->dri_Pens[BACKGROUNDPEN], 0, JAM1);
984 RectFill(rp, 0, 0, win->Width - 1, win->Height - 2);
986 SetAPen(rp, mhd->dri->dri_Pens[BARTRIMPEN]);
987 RectFill(rp, 0, win->Height - 1, win->Width - 1, win->Height - 1);
989 if (!MENUS_AMIGALOOK(IntuitionBase))
991 SetAPen(rp, mhd->dri->dri_Pens[SHINEPEN]);
992 RectFill(rp, 0, 0, 0, win->Height - 2);
993 RectFill(rp, 1, 0, win->Width - 1, 0);
994 SetAPen(rp, mhd->dri->dri_Pens[SHADOWPEN]);
995 RectFill(rp, win->Width - 1, 1, win->Width - 1, win->Height - 2);
1000 for(; menu; menu = menu->NextMenu)
1002 RenderMenuTitle(menu, mhd, IntuitionBase);
1007 /**************************************************************************************************/
1009 static void RenderMenuTitle(struct Menu *menu, struct MenuHandlerData *mhd,
1010 struct IntuitionBase *IntuitionBase)
1012 struct GfxBase *GfxBase = GetPrivIBase(IntuitionBase)->GfxBase;
1013 struct RastPort *rp;
1014 WORD len = 0;
1015 WORD x, y;
1017 if (menu->MenuName)
1018 len = strlen(menu->MenuName);
1019 else
1021 bug("Intuition: MenuEntry with missing string @ 0x%p\n", menu);
1024 if(mhd->menubarwin)
1026 rp = mhd->menubarwin->RPort;
1027 SetDrMd(rp, JAM1);
1029 if (MENUS_UNDERMOUSE(IntuitionBase))
1031 struct Menu *m;
1032 WORD yoff;
1034 yoff = 0;
1035 for(m = mhd->menu; m && (m != menu);m = m ->NextMenu)
1037 yoff++;
1040 x = mhd->innerleft + ITEXT_EXTRA_LEFT;
1041 y = mhd->innertop + ITEXT_EXTRA_TOP + yoff * mhd->menubaritemheight;
1043 else
1045 x = mhd->scr->BarHBorder + menu->LeftEdge;
1046 y = mhd->scr->BarVBorder + ((mhd->scr->BarHeight - rp->Font->tf_YSize) / 2);
1049 if (menu->MenuName)
1051 if (MENUS_AMIGALOOK(IntuitionBase))
1053 SetAPen(rp, mhd->dri->dri_Pens[BARDETAILPEN]);
1055 else
1057 SetAPen(rp, mhd->dri->dri_Pens[(menu->Flags & HIGHITEM) ? FILLTEXTPEN : TEXTPEN]);
1060 Move(rp, x, y + rp->TxBaseline);
1061 Text(rp, menu->MenuName, len);
1064 if (MENUS_UNDERMOUSE(IntuitionBase))
1066 if (menu->FirstItem)
1068 WORD x2 = mhd->scr->MenuHBorder + mhd->menubaritemwidth - ITEXT_EXTRA_RIGHT - mhd->submenuimage->Width;
1070 DrawImageState(rp, mhd->submenuimage, x2, y + ((mhd->menubaritemheight - mhd->submenuimage->Height) >> 1), IDS_NORMAL, mhd->dri);
1074 if (!(menu->Flags & MENUENABLED))
1076 WORD y2 = y + rp->TxHeight - 1;
1077 WORD x2;
1079 if (MENUS_UNDERMOUSE(IntuitionBase))
1081 x2 = mhd->scr->MenuHBorder + mhd->menubaritemwidth - 1;
1083 else if (menu->MenuName)
1085 x2 = x + TextLength(rp, menu->MenuName, len) - 1;
1086 } else {
1087 x2 = x + TextLength(rp, " ", 1) - 1;
1090 RenderDisabledPattern(rp, x, y, x2, y2, mhd, IntuitionBase);
1095 /**************************************************************************************************/
1097 static void MakeMenuWin(struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase)
1099 struct MenuItem *item;
1101 WORD width = mhd->activemenu->BeatX - mhd->activemenu->JazzX + 1;
1102 WORD height = mhd->activemenu->BeatY - mhd->activemenu->JazzY + 1;
1103 WORD xpos,ypos;
1105 struct mdpGetMenuSpaces msg;
1107 msg.MethodID = MDM_GETMENUSPACES;
1108 msg.mdp_TrueColor = mhd->TrueColor;
1109 msg.mdp_InnerLeft = 0;
1110 msg.mdp_InnerTop = 0;
1111 msg.mdp_InnerRight = 0;
1112 msg.mdp_InnerBottom = 0;
1113 msg.mdp_ItemInnerLeft = 0;
1114 msg.mdp_ItemInnerTop = 0;
1115 msg.mdp_ItemInnerRight = 0;
1116 msg.mdp_ItemInnerBottom = 0;
1117 DoMethodA(((struct IntScreen *)(mhd->scr))->MenuDecorObj, (Msg)&msg);
1118 mhd->menuinnerleft = msg.mdp_InnerLeft;
1119 mhd->menuinnerright = msg.mdp_InnerRight;
1120 mhd->menuinnertop = msg.mdp_InnerTop;
1121 mhd->menuinnerbottom = msg.mdp_InnerBottom;
1123 width += (mhd->menuinnerleft + mhd->menuinnerright);
1124 height += (mhd->menuinnertop + mhd->menuinnerbottom);
1126 if (MENUS_UNDERMOUSE(IntuitionBase))
1128 xpos = mhd->menubarwin->LeftEdge + mhd->menubarwin->Width - 16;
1129 ypos = mhd->menubarwin->TopEdge;
1131 else
1133 xpos = mhd->activemenu->LeftEdge + mhd->scr->BarHBorder + mhd->activemenu->JazzX;
1135 if (MENUS_AMIGALOOK(IntuitionBase))
1137 ypos = mhd->scr->BarHeight + 1 + mhd->activemenu->JazzY;
1139 else
1141 ypos = mhd->scr->BarHeight + 1;
1146 struct TagItem win_tags[] =
1148 {WA_Left , xpos },
1149 {WA_Top , ypos },
1150 {WA_Width , width },
1151 {WA_Height , height },
1152 {WA_AutoAdjust , TRUE },
1153 {WA_Borderless , TRUE },
1154 {WA_CustomScreen, (IPTR)mhd->scr },
1155 {WA_BackFill , (IPTR)LAYERS_NOBACKFILL},
1156 {TAG_DONE , 0 }
1159 if (MENUS_UNDERMOUSE(IntuitionBase))
1161 win_tags[1].ti_Data += (mhd->menubaritemheight * mhd->activemenunum + mhd->scr->MenuVBorder) -
1162 height / 2;
1163 if (xpos + width > mhd->scr->Width)
1165 win_tags[0].ti_Data = mhd->menubarwin->LeftEdge - width + 16;
1169 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;
1170 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;
1171 if (((LONG) win_tags[0].ti_Data) < 0) win_tags[0].ti_Data = 0;
1172 if (((LONG) win_tags[1].ti_Data) < 0) win_tags[1].ti_Data = 0;
1174 if ((item = mhd->activemenu->FirstItem))
1177 while(item)
1179 item->Flags &= ~HIGHITEM;
1180 item = item->NextItem;
1183 IPTR userbuffersize;
1185 GetAttr(MDA_UserBuffer, ((struct IntScreen *)(mhd->scr))->MenuDecorObj, &userbuffersize);
1187 if (userbuffersize)
1189 mhd->DecorUserBufferSize = userbuffersize;
1190 mhd->DecorUserBuffer = (IPTR) AllocMem(userbuffersize, MEMF_ANY | MEMF_CLEAR);
1191 if (0 == mhd->DecorUserBuffer) return;
1194 struct mdpInitMenu msg;
1196 msg.MethodID = MDM_INITMENU;
1197 msg.mdp_TrueColor = mhd->TrueColor;
1198 msg.mdp_RPort = &mhd->scr->RastPort;
1199 msg.mdp_Left = win_tags[0].ti_Data;
1200 msg.mdp_Top = win_tags[1].ti_Data;
1201 msg.mdp_Width = width;
1202 msg.mdp_Height = height;
1203 msg.mdp_UserBuffer = mhd->DecorUserBuffer;
1204 msg.mdp_ScreenUserBuffer = ((struct IntScreen *) mhd->scr)->DecorUserBuffer;
1205 msg.mdp_Screen = mhd->scr;
1206 msg.mdp_MenuDecorFlags = (MENUS_UNDERMOUSE(IntuitionBase)) ? MDP_MDF_MENUS_UNDERMOUSE : 0;
1207 msg.mdp_MenuDecorFlags |= MDP_MDF_ITEM;
1209 DoMethodA(((struct IntScreen *)(mhd->scr))->MenuDecorObj, (Msg)&msg);
1211 mhd->menuwin = OpenWindowTagList(0, win_tags);
1213 mhd->maxcommkeywidth_menu = CalcMaxCommKeyWidth(mhd->menuwin, mhd, IntuitionBase);
1215 RenderMenu(mhd, IntuitionBase);
1217 mhd->activemenu->Flags |= MIDRAWN;
1222 /**************************************************************************************************/
1224 static void KillMenuWin(struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase)
1226 if (mhd->menuwin)
1228 struct MenuItem *item;
1230 CloseWindow(mhd->menuwin);
1231 mhd->menuwin = NULL;
1233 TimeDelay(UNIT_VBLANK,0,20000);
1235 for(item = mhd->activemenu->FirstItem; item; item = item->NextItem)
1237 item->Flags &= ~ISDRAWN;
1239 struct mdpExitMenu msg;
1241 msg.MethodID = MDM_EXITMENU;
1242 msg.mdp_TrueColor = mhd->TrueColor;
1243 msg.mdp_UserBuffer = mhd->DecorUserBuffer;
1244 DoMethodA(((struct IntScreen *)(mhd->scr))->MenuDecorObj, (Msg)&msg);
1246 if (mhd->DecorUserBuffer)
1248 FreeMem((void *)mhd->DecorUserBuffer, mhd->DecorUserBufferSize);
1250 mhd->DecorUserBuffer = 0;
1252 mhd->activemenu->Flags &= ~MIDRAWN;
1254 mhd->activeitemnum = -1;
1255 mhd->activeitem = NULL;
1259 /**************************************************************************************************/
1261 static void RenderMenu(struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase)
1263 struct GfxBase *GfxBase = GetPrivIBase(IntuitionBase)->GfxBase;
1265 if (mhd->menuwin)
1267 struct MenuItem *item;
1269 RenderMenuBG(mhd->menuwin, mhd, IntuitionBase);
1271 SetFont(mhd->menuwin->RPort, mhd->dri->dri_Font);
1273 for(item = mhd->activemenu->FirstItem; item; item = item->NextItem)
1275 RenderItem(item, ITEM_ITEM, (struct Rectangle *)(&mhd->activemenu->JazzX), mhd, IntuitionBase);
1278 } /* if (mhd->menuwin) */
1281 /**************************************************************************************************/
1283 static void MakeSubMenuWin(struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase)
1285 struct MenuItem *item = mhd->activeitem->SubItem;
1287 struct TagItem win_tags[] =
1289 {WA_Left , 0 },
1290 {WA_Top , 0 },
1291 {WA_Width , 0 },
1292 {WA_Height , 0 },
1293 {WA_AutoAdjust , TRUE },
1294 {WA_Borderless , TRUE },
1295 {WA_CustomScreen, (IPTR)mhd->scr },
1296 {WA_BackFill , (IPTR)LAYERS_NOBACKFILL },
1297 {TAG_DONE }
1300 if(mhd->menubarwin)
1302 GetMenuBox(mhd->menubarwin, item, &mhd->submenubox.MinX,
1303 &mhd->submenubox.MinY,
1304 &mhd->submenubox.MaxX,
1305 &mhd->submenubox.MaxY);
1308 struct mdpGetMenuSpaces msg;
1310 msg.MethodID = MDM_GETMENUSPACES;
1311 msg.mdp_TrueColor = mhd->TrueColor;
1312 msg.mdp_InnerLeft = 0;
1313 msg.mdp_InnerTop = 0;
1314 msg.mdp_InnerRight = 0;
1315 msg.mdp_InnerBottom = 0;
1317 DoMethodA(((struct IntScreen *)(mhd->scr))->MenuDecorObj, (Msg)&msg);
1318 mhd->menuinnerleft = msg.mdp_InnerLeft;
1319 mhd->menuinnerright = msg.mdp_InnerRight;
1320 mhd->menuinnertop = msg.mdp_InnerTop;
1321 mhd->menuinnerbottom = msg.mdp_InnerBottom;
1324 win_tags[0].ti_Data = mhd->menuwin->LeftEdge +
1325 mhd->activeitem->LeftEdge - mhd->activemenu->JazzX +
1326 mhd->submenubox.MinX;
1328 win_tags[1].ti_Data = mhd->menuwin->TopEdge +
1329 mhd->activeitem->TopEdge - mhd->activemenu->JazzY +
1330 mhd->submenubox.MinY;
1332 win_tags[2].ti_Data = mhd->submenubox.MaxX - mhd->submenubox.MinX + 1 + mhd->menuinnerleft + mhd->menuinnerright;
1333 win_tags[3].ti_Data = mhd->submenubox.MaxY - mhd->submenubox.MinY + 1 + mhd->menuinnertop + mhd->menuinnerbottom;
1335 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;
1336 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;
1337 if (((LONG) win_tags[0].ti_Data) < 0) win_tags[0].ti_Data = 0;
1338 if (((LONG) win_tags[1].ti_Data) < 0) win_tags[1].ti_Data = 0;
1340 while(item)
1342 item->Flags &= ~HIGHITEM;
1343 item = item->NextItem;
1346 IPTR userbuffersize;
1348 GetAttr(MDA_UserBuffer, ((struct IntScreen *)(mhd->scr))->MenuDecorObj, &userbuffersize);
1350 if (userbuffersize)
1352 mhd->DecorUserBufferSize = userbuffersize;
1353 mhd->SubDecorUserBuffer = (IPTR) AllocMem(userbuffersize, MEMF_ANY | MEMF_CLEAR);
1354 if (0 == mhd->SubDecorUserBuffer) return;
1358 struct mdpInitMenu msg;
1359 msg.MethodID = MDM_INITMENU;
1360 msg.mdp_TrueColor = mhd->TrueColor;
1361 msg.mdp_RPort = &mhd->scr->RastPort;
1362 msg.mdp_Left = win_tags[0].ti_Data;
1363 msg.mdp_Top = win_tags[1].ti_Data;
1364 msg.mdp_Width = win_tags[2].ti_Data;
1365 msg.mdp_Height = win_tags[3].ti_Data;
1366 msg.mdp_UserBuffer = mhd->SubDecorUserBuffer;
1367 msg.mdp_ScreenUserBuffer = ((struct IntScreen *) mhd->scr)->DecorUserBuffer;
1368 msg.mdp_TrueColor = mhd->TrueColor;
1369 msg.mdp_Screen = mhd->scr;
1370 msg.mdp_MenuDecorFlags = (MENUS_UNDERMOUSE(IntuitionBase)) ? MDP_MDF_MENUS_UNDERMOUSE : 0;
1371 msg.mdp_MenuDecorFlags |= MDP_MDF_SUBITEM;
1373 DoMethodA(((struct IntScreen *)(mhd->scr))->MenuDecorObj, (Msg)&msg);
1375 mhd->submenuwin = OpenWindowTagList(0, win_tags);
1377 mhd->maxcommkeywidth_submenu = CalcMaxCommKeyWidth(mhd->submenuwin, mhd, IntuitionBase);
1379 RenderSubMenu(mhd, IntuitionBase);
1383 /**************************************************************************************************/
1385 static void KillSubMenuWin(struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase)
1387 if (mhd->submenuwin)
1389 CloseWindow(mhd->submenuwin);
1391 TimeDelay(UNIT_VBLANK,0,20000);
1392 struct mdpExitMenu msg;
1394 msg.MethodID = MDM_EXITMENU;
1395 msg.mdp_TrueColor = mhd->TrueColor;
1396 msg.mdp_UserBuffer = mhd->SubDecorUserBuffer;
1397 DoMethodA(((struct IntScreen *)(mhd->scr))->MenuDecorObj, (Msg)&msg);
1399 if (mhd->SubDecorUserBuffer)
1401 FreeMem((void *)mhd->SubDecorUserBuffer, mhd->DecorUserBufferSize);
1403 mhd->SubDecorUserBuffer = 0;
1405 mhd->submenuwin = NULL;
1407 mhd->activesubitemnum = -1;
1408 mhd->activesubitem = NULL;
1412 /**************************************************************************************************/
1414 static void RenderSubMenu(struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase)
1416 struct GfxBase *GfxBase = GetPrivIBase(IntuitionBase)->GfxBase;
1418 if (mhd->submenuwin)
1420 struct MenuItem *item;
1422 RenderMenuBG(mhd->submenuwin, mhd, IntuitionBase);
1424 SetFont(mhd->submenuwin->RPort, mhd->dri->dri_Font);
1426 for(item = mhd->activeitem->SubItem; item; item = item->NextItem)
1428 RenderItem(item, ITEM_SUBITEM, (struct Rectangle *)(&mhd->submenubox), mhd, IntuitionBase);
1431 } /* if (mhd->submenuwin) */
1434 /**************************************************************************************************/
1436 static void RenderItem(struct MenuItem *item, WORD itemtype, struct Rectangle *box,
1437 struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase)
1439 struct GfxBase *GfxBase = GetPrivIBase(IntuitionBase)->GfxBase;
1440 struct Window *win = ((itemtype == ITEM_ITEM) ? mhd->menuwin : mhd->submenuwin);
1441 struct RastPort *rp = win->RPort;
1442 WORD offx = -box->MinX + mhd->menuinnerleft;
1443 WORD offy = -box->MinY + mhd->menuinnertop;
1444 BOOL enabled = ((item->Flags & ITEMENABLED) &&
1445 (mhd->activemenu->Flags & MENUENABLED) &&
1446 ((itemtype == ITEM_ITEM) || (mhd->activeitem->Flags & ITEMENABLED)));
1447 BOOL item_supports_disable = FALSE;
1449 SetDrMd(rp, JAM1);
1451 if (item->ItemFill)
1454 if (item->Flags & ITEMTEXT)
1456 struct IntuiText *save = ((struct IntuiText*) item->ItemFill)->NextText;
1458 if (item->SubItem)
1460 Forbid();
1461 ((struct IntuiText*) item->ItemFill)->NextText = NULL;
1464 struct IntuiText *it = (struct IntuiText *)item->ItemFill;
1466 if (MENUS_AMIGALOOK(IntuitionBase))
1468 PrintIText(rp, it, offx + item->LeftEdge, offy + item->TopEdge);
1470 else
1472 it->FrontPen = mhd->dri->dri_Pens[(item->Flags & HIGHITEM) ? FILLTEXTPEN : TEXTPEN];
1473 it->DrawMode = JAM1;
1475 PrintIText(rp, it, offx + item->LeftEdge, offy + item->TopEdge);
1477 if (item->SubItem)
1479 DrawImageState(rp, mhd->submenuimage, offx + item->Width - mhd->submenuimage->Width, offy + item->TopEdge + ((item->Height - mhd->submenuimage->Height) >> 1), IDS_NORMAL, mhd->dri);
1480 ((struct IntuiText*) item->ItemFill)->NextText = save;
1481 Permit();
1484 else
1486 struct Image *im = (struct Image *)item->ItemFill;
1487 LONG state = IDS_NORMAL;
1489 if (!enabled && (im->Depth == CUSTOMIMAGEDEPTH))
1491 IPTR val = 0;
1493 GetAttr(IA_SupportsDisable, (Object *)im, &val);
1494 if (val)
1496 item_supports_disable = TRUE;
1497 state = IDS_DISABLED;
1501 DrawImageState(rp, im, offx + item->LeftEdge, offy + item->TopEdge, state, mhd->dri);
1504 } /* if (item->ItemFill) */
1506 RenderCheckMark(item, itemtype, mhd, IntuitionBase);
1507 RenderAmigaKey(item, itemtype, mhd, IntuitionBase);
1509 if (!enabled && !item_supports_disable)
1511 RenderDisabledPattern(rp, offx + item->LeftEdge,
1512 offy + item->TopEdge,
1513 offx + item->LeftEdge + item->Width - 1,
1514 offy + item->TopEdge + item->Height - 1,
1515 mhd,
1516 IntuitionBase);
1521 /**************************************************************************************************/
1523 static void RenderMenuBG(struct Window *win, struct MenuHandlerData *mhd,
1524 struct IntuitionBase *IntuitionBase)
1527 struct GfxBase *GfxBase = GetPrivIBase(IntuitionBase)->GfxBase;
1528 struct RastPort *rp = win->RPort;
1529 WORD borderx, bordery;
1531 if (CustomDrawBackground(rp, win, 0, 0, win->Width - 1, win->Height - 1, 0, mhd, IntuitionBase)) return;
1533 if (MENUS_AMIGALOOK(IntuitionBase))
1535 borderx = mhd->scr->MenuHBorder / 2;
1536 bordery = mhd->scr->MenuVBorder / 2;
1538 else
1540 borderx = 1;
1541 bordery = 1;
1544 /* White background */
1546 if (MENUS_AMIGALOOK(IntuitionBase))
1548 SetABPenDrMd(rp, mhd->dri->dri_Pens[BARBLOCKPEN], 0, JAM1);
1550 else
1552 SetABPenDrMd(rp, mhd->dri->dri_Pens[BACKGROUNDPEN], 0, JAM1);
1555 RectFill(rp, borderx,
1556 bordery,
1557 win->Width - 1 - borderx,
1558 win->Height - 1 - bordery);
1560 /* Black border frame */
1562 if (MENUS_AMIGALOOK(IntuitionBase))
1564 SetAPen(rp, mhd->dri->dri_Pens[BARDETAILPEN]);
1565 RectFill(rp, 0, 0, win->Width - 1, bordery - 1);
1566 RectFill(rp, 0, bordery, borderx - 1, win->Height - 1 - bordery);
1567 RectFill(rp, win->Width - borderx, bordery, win->Width - 1, win->Height - 1);
1568 RectFill(rp, 0, win->Height - bordery, win->Width - 1 - borderx, win->Height - 1);
1570 else
1572 RenderFrame(rp, 0, 0, win->Width - 1, win->Height - 1, IDS_NORMAL, mhd, IntuitionBase);
1576 /**************************************************************************************************/
1578 static void RenderCheckMark(struct MenuItem *item, WORD itemtype, struct MenuHandlerData *mhd,
1579 struct IntuitionBase *IntuitionBase)
1581 struct GfxBase *GfxBase = GetPrivIBase(IntuitionBase)->GfxBase;
1582 struct Window *win = ((itemtype == ITEM_ITEM) ? mhd->menuwin : mhd->submenuwin);
1583 struct RastPort *rp = win->RPort;
1584 struct Rectangle *box = ((itemtype == ITEM_ITEM) ? ((struct Rectangle *)&mhd->activemenu->JazzX) : &mhd->submenubox);
1585 WORD offx = -box->MinX + mhd->menuinnerleft;
1586 WORD offy = -box->MinY + mhd->menuinnertop;
1587 WORD state = ((item->Flags & HIGHITEM) &&
1588 ((item->Flags & HIGHFLAGS) == HIGHCOMP)) ? IDS_SELECTED : IDS_NORMAL;
1590 if (item->Flags & CHECKIT)
1592 WORD x1, y1, x2, y2;
1594 x1 = item->LeftEdge + offx;
1595 y1 = item->TopEdge + offy + (item->Height - mhd->checkmark->Height) / 2;
1596 x2 = x1 + mhd->checkmark->Width - 1;
1597 y2 = y1 + mhd->checkmark->Height - 1;
1599 SetDrMd(rp, JAM1);
1601 if (item->Flags & CHECKED)
1603 DrawImageState(rp, mhd->checkmark, x1, y1, state, mhd->dri);
1605 else
1607 if (MENUS_AMIGALOOK(IntuitionBase))
1609 SetAPen(rp, mhd->dri->dri_Pens[BARBLOCKPEN]);
1611 else
1613 SetAPen(rp, mhd->dri->dri_Pens[(state == IDS_SELECTED) ? FILLPEN : BACKGROUNDPEN]);
1616 if (!CustomDrawBackground(rp, win, x1, y1, x2 - x1 + 1, y2 - y1 + 1, item->Flags, mhd, IntuitionBase)) RectFill(rp, x1, y1, x2, y2);
1622 /**************************************************************************************************/
1624 static void RenderAmigaKey(struct MenuItem *item, WORD itemtype, struct MenuHandlerData *mhd,
1625 struct IntuitionBase *IntuitionBase)
1627 struct GfxBase *GfxBase = GetPrivIBase(IntuitionBase)->GfxBase;
1628 struct Window *win = ((itemtype == ITEM_ITEM) ? mhd->menuwin : mhd->submenuwin);
1629 struct RastPort *rp = win->RPort;
1630 struct Rectangle *box = ((itemtype == ITEM_ITEM) ? ((struct Rectangle *)&mhd->activemenu->JazzX) : &mhd->submenubox);
1631 WORD commkeywidth = ((itemtype == ITEM_ITEM) ? mhd->maxcommkeywidth_menu : mhd->maxcommkeywidth_submenu);
1632 WORD offx = -box->MinX + mhd->menuinnerleft;
1633 WORD offy = -box->MinY + mhd->menuinnertop;
1634 WORD state = ((item->Flags & HIGHITEM) &&
1635 ((item->Flags & HIGHFLAGS) == HIGHCOMP)) ? IDS_SELECTED : IDS_NORMAL;
1637 if (item->Flags & COMMSEQ)
1639 struct TextFont *oldfont = rp->Font;
1640 struct TextFont *newfont = NULL;
1642 WORD x1, y1;
1644 if (item->Flags & ITEMTEXT)
1646 struct IntuiText *it = (struct IntuiText *)item->ItemFill;
1648 if (it->ITextFont)
1650 if ((newfont = OpenFont(it->ITextFont)))
1652 SetFont(rp, newfont);
1657 x1 = item->LeftEdge + offx + item->Width - AMIGAKEY_BORDER_SPACING -
1658 mhd->amigakey->Width - AMIGAKEY_KEY_SPACING - commkeywidth;
1659 y1 = item->TopEdge + offy + (item->Height - mhd->amigakey->Height + 1) / 2;
1661 SetDrMd(rp, JAM1);
1663 DrawImageState(rp, mhd->amigakey, x1, y1, state, mhd->dri);
1665 x1 += mhd->amigakey->Width + AMIGAKEY_KEY_SPACING;
1667 if (MENUS_AMIGALOOK(IntuitionBase))
1669 SetAPen(rp, mhd->dri->dri_Pens[BARDETAILPEN]);
1671 else
1673 SetAPen(rp, mhd->dri->dri_Pens[(item->Flags & HIGHITEM) ? FILLTEXTPEN : TEXTPEN]);
1676 Move(rp, x1, item->TopEdge + offy + (item->Height - rp->TxHeight) / 2 +
1677 rp->TxBaseline);
1678 Text(rp, &item->Command, 1);
1680 if (newfont)
1682 CloseFont(newfont);
1683 SetFont(rp, oldfont);
1686 } /* if (item->Flags & COMMSEQ) */
1689 /**************************************************************************************************/
1691 static void RenderDisabledPattern(struct RastPort *rp, WORD x1, WORD y1, WORD x2, WORD y2,
1692 struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase)
1694 struct GfxBase *GfxBase = GetPrivIBase(IntuitionBase)->GfxBase;
1695 static CONST UWORD pattern [] = {0x8888, 0x2222};
1697 SetDrMd(rp, JAM1);
1699 if (MENUS_AMIGALOOK(IntuitionBase))
1701 SetAPen(rp, mhd->dri->dri_Pens[BARBLOCKPEN]);
1703 else
1705 SetAPen(rp, mhd->dri->dri_Pens[BACKGROUNDPEN]);
1708 SetAfPt(rp, pattern, 1);
1710 RectFill(rp, x1, y1, x2, y2);
1712 SetAfPt(rp, NULL, 0);
1716 /**************************************************************************************************/
1718 static void RenderFrame(struct RastPort *rp, WORD x1, WORD y1, WORD x2, WORD y2, WORD state,
1719 struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase)
1721 struct GfxBase *GfxBase = GetPrivIBase(IntuitionBase)->GfxBase;
1723 SetAPen(rp, mhd->dri->dri_Pens[(state == IDS_SELECTED) ? SHADOWPEN : SHINEPEN]);
1725 RectFill(rp, x1, y1, x2, y1);
1726 RectFill(rp, x1, y1 + 1, x1, y2);
1728 SetAPen(rp, mhd->dri->dri_Pens[(state == IDS_SELECTED) ? SHINEPEN : SHADOWPEN]);
1729 RectFill(rp, x2, y1 + 1, x2, y2);
1730 RectFill(rp, x1 + 1, y2, x2 - 1, y2);
1732 /**************************************************************************************************/
1734 static void HighlightItem(struct MenuItem *item, WORD itemtype, struct MenuHandlerData *mhd,
1735 struct IntuitionBase *IntuitionBase)
1737 struct GfxBase *GfxBase = GetPrivIBase(IntuitionBase)->GfxBase;
1738 struct Window *win = ((itemtype == ITEM_ITEM) ? mhd->menuwin : mhd->submenuwin);
1739 struct RastPort *rp = win->RPort;
1740 struct Rectangle *box = ((itemtype == ITEM_ITEM) ? ((struct Rectangle *)&mhd->activemenu->JazzX) : &mhd->submenubox);
1741 APTR fill;
1742 WORD offx = -box->MinX + mhd->menuinnerleft;
1743 WORD offy = -box->MinY + mhd->menuinnertop;
1744 WORD x1, y1, x2, y2;
1745 BOOL enabled;
1747 enabled = (item->Flags & ITEMENABLED) ? TRUE : FALSE;
1748 if (!(mhd->activemenu->Flags & MENUENABLED)) enabled = FALSE;
1749 if ((itemtype == ITEM_SUBITEM) && !(mhd->activeitem->Flags & ITEMENABLED)) enabled = FALSE;
1751 if (enabled)
1753 item->Flags ^= HIGHITEM;
1755 fill = item->ItemFill;
1756 if ((item->Flags & HIGHITEM) && (item->SelectFill)) fill = item->SelectFill;
1758 x1 = offx + item->LeftEdge;
1759 y1 = offy + item->TopEdge;
1760 x2 = x1 + item->Width - 1;
1761 y2 = y1 + item->Height - 1;
1763 if (CustomDrawBackground(rp, win, x1, y1, x2 - x1 + 1, y2 - y1 + 1, item->Flags, mhd, IntuitionBase)) {
1764 SetDrMd(rp, JAM1);
1766 if(item->Flags & ITEMTEXT)
1768 struct IntuiText *save = ((struct IntuiText*) fill)->NextText;
1770 if (item->SubItem)
1772 Forbid();
1773 ((struct IntuiText*) fill)->NextText = NULL;
1776 if (MENUS_AMIGALOOK(IntuitionBase))
1778 PrintIText(rp, (struct IntuiText *)fill, x1, y1);
1780 else
1782 struct IntuiText *it = (struct IntuiText *)fill;
1784 it->FrontPen = mhd->dri->dri_Pens[TEXTPEN];
1785 it->DrawMode = JAM1;
1787 PrintIText(rp, it, x1, y1);
1789 if (item->SubItem)
1791 DrawImageState(rp, mhd->submenuimage, offx + item->Width - mhd->submenuimage->Width, offy + item->TopEdge + ((item->Height - mhd->submenuimage->Height) >> 1), IDS_NORMAL, mhd->dri);
1792 ((struct IntuiText*) fill)->NextText = save;
1793 Permit();
1796 else
1798 EraseImage(rp, (struct Image *)fill, x1, y1);
1799 DrawImageState(rp, (struct Image *)fill, x1, y1, IDS_SELECTED, mhd->dri);
1801 RenderItem(item, itemtype, box, mhd, IntuitionBase);
1802 return;
1805 switch(item->Flags & HIGHFLAGS)
1807 case HIGHIMAGE:
1808 SetDrMd(rp, JAM1);
1810 if(item->Flags & ITEMTEXT)
1812 struct IntuiText *save = ((struct IntuiText*) fill)->NextText;
1814 if (item->SubItem)
1816 Forbid();
1817 ((struct IntuiText*) fill)->NextText = NULL;
1819 if (MENUS_AMIGALOOK(IntuitionBase))
1821 PrintIText(rp, (struct IntuiText *)fill, x1, y1);
1823 else
1825 struct IntuiText *it = (struct IntuiText *)fill;
1827 it->FrontPen = mhd->dri->dri_Pens[TEXTPEN];
1828 it->DrawMode = JAM1;
1830 PrintIText(rp, it, x1, y1);
1832 if (item->SubItem)
1834 DrawImageState(rp, mhd->submenuimage, offx + item->Width - mhd->submenuimage->Width, offy + item->TopEdge + ((item->Height - mhd->submenuimage->Height) >> 1), IDS_NORMAL, mhd->dri);
1835 ((struct IntuiText*) fill)->NextText = save;
1836 Permit();
1839 else
1841 EraseImage(rp, (struct Image *)fill, x1, y1);
1842 DrawImageState(rp, (struct Image *)fill, x1, y1, IDS_SELECTED, mhd->dri);
1844 break;
1846 case HIGHCOMP:
1847 if (MENUS_AMIGALOOK(IntuitionBase))
1849 SetDrMd(rp, COMPLEMENT);
1850 RectFill(rp, x1, y1, x2, y2);
1852 else
1854 WORD state = (item->Flags & HIGHITEM) ? IDS_SELECTED : IDS_NORMAL;
1856 SetDrMd(rp, JAM1);
1857 SetAPen(rp, mhd->dri->dri_Pens[(state == IDS_SELECTED) ? FILLPEN : BACKGROUNDPEN]);
1858 RectFill(rp, x1, y1, x2, y2);
1860 RenderItem(item, itemtype, box, mhd, IntuitionBase);
1862 if (state == IDS_SELECTED)
1864 RenderFrame(rp, x1, y1, x2, y2, state, mhd, IntuitionBase);
1867 break;
1869 case HIGHBOX:
1870 SetDrMd(rp, COMPLEMENT);
1871 offx = mhd->scr->MenuHBorder;
1872 offy = mhd->scr->MenuVBorder;
1874 x1 -= offx;
1875 x2 += offx;
1876 y1 -= offy;
1877 y2 += offy;
1879 RectFill(rp, x1, y1, x2, y1 + offy - 1);
1880 RectFill(rp, x2 - offx + 1, y1 + offy, x2, y2);
1881 RectFill(rp, x1, y2 - offy + 1, x2 - offx, y2);
1882 RectFill(rp, x1, y1 + offy, x1 + offx - 1,y2 - offy);
1883 break;
1885 case HIGHNONE:
1886 /* Do nothing */
1887 break;
1889 } /* switch(item->Flags & HIGHFLAGS) */
1891 } /* if (enabled) */
1895 /**************************************************************************************************/
1897 static WORD CalcMaxCommKeyWidth(struct Window *win, struct MenuHandlerData *mhd,
1898 struct IntuitionBase *IntuitionBase)
1900 struct GfxBase *GfxBase = GetPrivIBase(IntuitionBase)->GfxBase;
1901 struct TextExtent te;
1902 WORD maxwidth;
1904 FontExtent(mhd->dri->dri_Font, &te);
1905 maxwidth = te.te_Width;
1907 if (win)
1909 struct MenuItem *item;
1911 if ((win == mhd->menuwin))
1913 item = mhd->activemenu->FirstItem;
1915 else
1917 item = mhd->activeitem->SubItem;
1920 for(; item; item = item->NextItem)
1922 if (item->Flags & ITEMTEXT)
1924 struct IntuiText *it = (struct IntuiText *)item->ItemFill;
1926 if (it->ITextFont)
1928 struct TextFont *font;
1930 if ((font = OpenFont(it->ITextFont)))
1932 FontExtent(font, &te);
1933 if (te.te_Width > maxwidth) maxwidth = te.te_Width;
1935 CloseFont(font);
1939 } /* if (item->Flags & ITEMTEXT) */
1941 } /* for(; item; item = item->NextItem); */
1943 } /* if (win) */
1945 return maxwidth;
1948 /**************************************************************************************************/
1950 static void AddToSelection(struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase)
1952 if ((mhd->activemenunum != -1) && (mhd->activemenu->Flags & MENUENABLED) &&
1953 (mhd->activeitemnum != -1) && (mhd->activeitem->Flags & ITEMENABLED))
1955 struct MenuItem *item = NULL;
1956 UWORD men = FULLMENUNUM(mhd->activemenunum, mhd->activeitemnum, mhd->activesubitemnum);
1958 if (mhd->activesubitemnum != -1)
1960 if (mhd->activesubitem->Flags & ITEMENABLED) item = mhd->activesubitem;
1962 else if (!mhd->activeitem->SubItem)
1964 item = mhd->activeitem;
1967 if (item && (ItemAddress(mhd->menu, men) == item))
1969 UWORD men = FULLMENUNUM(mhd->activemenunum, mhd->activeitemnum, mhd->activesubitemnum);
1971 if (mhd->firstmenupick == MENUNULL)
1973 mhd->firstmenupick = men;
1975 else if (men != mhd->lastmenupick)
1977 struct MenuItem *checkitem, *prevcheckitem = NULL;
1978 UWORD checkmen = mhd->firstmenupick;
1980 /* Remove men from pick queue, if it was already in there
1981 and then add it at the end of the pick queue */
1983 while(checkmen != MENUNULL)
1985 checkitem = ItemAddress(mhd->menu, checkmen);
1987 if (checkmen == men)
1989 if (prevcheckitem == NULL)
1991 mhd->firstmenupick = checkitem->NextSelect;
1993 else
1995 prevcheckitem->NextSelect = checkitem->NextSelect;
1999 checkmen = checkitem->NextSelect;
2000 prevcheckitem = checkitem;
2002 } /* while(checkmen != MENUNULL) */
2004 checkitem->NextSelect = men;
2006 } /* else if (men != mhd->lastmenupick) */
2008 mhd->lastmenupick = men;
2009 item->NextSelect = MENUNULL;
2011 } /* if (item) */
2013 } /* if ((mhd->activemenunum != -1) && (mhd->activeitemnum != -1)) */