compiler/clib/__arosc_userdata.c: Typo
[AROS.git] / rom / intuition / menutask.c
blob7c74628c4cf2c59bcefb11d3fa21563e6429423d
1 /*
2 Copyright 1995-2011, 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 UBYTE *mem;
114 struct MsgPort *port = NULL;
115 BOOL success = FALSE;
117 if ((mem = AllocMem(sizeof(struct MsgPort) +
118 sizeof(struct MenuHandlerData), MEMF_PUBLIC | MEMF_CLEAR)))
120 port = (struct MsgPort *)mem;
122 port->mp_Node.ln_Type = NT_MSGPORT;
123 port->mp_Flags = PA_SIGNAL;
124 port->mp_SigBit = AllocSignal(-1);
125 port->mp_SigTask = FindTask(0);
126 NEWLIST(&port->mp_MsgList);
128 mhd = (struct MenuHandlerData *)(mem + sizeof(struct MsgPort));
130 success = TRUE;
132 } /* if ((mem = AllocMem(sizeof(struct MsgPort), MEMF_PUBLIC | MEMF_CLEAR))) */
134 if (success)
136 taskparams->MenuHandlerPort = port;
137 taskparams->success = TRUE;
140 Signal(taskparams->Caller, SIGF_INTUITION);
142 if (!success)
144 D(bug("DefaultMenuHandler: initialization failed. waiting for parent task to kill me.\n"));
145 Wait(0);
148 D(bug("DefaultMenuHandler: initialization ok. Now waiting for messages from Intuition.\n"));
150 for(;;)
152 struct MenuMessage *msg;
154 WaitPort(port);
155 while((msg = GetMenuMessage(port, IntuitionBase)))
157 switch(msg->code)
159 case MMCODE_START:
160 mhd->win = msg->win;
161 mhd->scr = mhd->win->WScreen;
162 mhd->dri = GetScreenDrawInfo(mhd->scr);
163 mhd->menu = msg->win->MenuStrip;
164 mhd->activemenunum = -1;
165 mhd->activeitemnum = -1;
166 mhd->activesubitemnum = -1;
167 mhd->checkmark = ((struct IntWindow *)mhd->win)->Checkmark;
168 mhd->amigakey = ((struct IntWindow *)mhd->win)->AmigaKey;
169 mhd->submenuimage = ((struct IntWindow *)mhd->win)->SubMenuImage;
170 mhd->scrmousex = mhd->scr->MouseX;
171 mhd->scrmousey = mhd->scr->MouseY;
172 mhd->firstmenupick = MENUNULL;
173 mhd->keepmenuup = TRUE;
174 mhd->TrueColor = GetBitMapAttr(&mhd->scr->BitMap, BMA_DEPTH) > 8 ? TRUE: FALSE;
176 /* close windows in the back first because
177 this is faster */
178 MakeMenuBarWin(mhd, IntuitionBase);
179 HandleMouseMove(mhd, IntuitionBase);
180 mhd->active = TRUE;
181 break;
183 case MMCODE_EVENT:
184 /* there might come additional messages from Intuition
185 even when we have already told it to make the menus
186 inactive, but since everything is async, this cannot
187 be avoided, so check if we are really active */
189 if (mhd->active)
191 switch(msg->ie.ie_Class)
193 case IECLASS_RAWMOUSE:
194 if (msg->ie.ie_Code == IECODE_NOBUTTON)
196 HandleMouseMove(mhd, IntuitionBase);
198 else
200 HandleMouseClick(&msg->ie, mhd, IntuitionBase);
202 break;
205 } /* if (mhd->active) */
206 break;
208 } /* switch(msg->code) */
210 ReplyMenuMessage(msg, IntuitionBase);
212 } /* while((msg = (struct MenuMessage *)GetMsg(port))) */
214 } /* for(;;) */
217 /**************************************************************************************************/
219 /*******************************
220 ** InitDefaultMenuHandler() **
221 *******************************/
222 BOOL InitDefaultMenuHandler(struct IntuitionBase *IntuitionBase)
224 struct MenuTaskParams params;
225 struct Task *task;
226 BOOL result = FALSE;
228 params.intuitionBase = IntuitionBase;
229 params.Caller = FindTask(NULL);
230 params.success = FALSE;
232 SetSignal(0, SIGF_INTUITION);
234 task = NewCreateTask(TASKTAG_NAME, "Intuition menu handler",
235 TASKTAG_PC , DefaultMenuHandler,
236 TASKTAG_ARG1, &params,
237 TAG_DONE);
239 if (task)
241 Wait(SIGF_INTUITION);
243 if (params.success)
245 result = TRUE;
246 GetPrivIBase(IntuitionBase)->MenuHandlerPort = params.MenuHandlerPort;
248 else
250 RemTask(task);
253 } /* if ((task = CreateMenuHandlerTask(&params, IntuitionBase))) */
255 return result;
259 /**************************************************************************************************/
261 static void HandleMouseMove(struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase)
263 struct LayersBase *LayersBase = GetPrivIBase(IntuitionBase)->LayersBase;
264 struct Layer *lay;
265 struct Window *win = NULL;
266 struct Menu *menu;
267 struct MenuItem *item;
268 WORD new_activemenunum = mhd->activemenunum;
269 WORD new_activeitemnum = mhd->activeitemnum;
270 WORD new_activesubitemnum = mhd->activesubitemnum;
272 mhd->scrmousex = mhd->scr->MouseX;
273 mhd->scrmousey = mhd->scr->MouseY;
275 if ((lay = WhichLayer(&mhd->scr->LayerInfo, mhd->scrmousex, mhd->scrmousey)))
277 win = (struct Window *)lay->Window;
279 if (win && (win == mhd->submenuwin))
281 /* Mouse over submenu box */
282 item = FindSubItem(&new_activesubitemnum, mhd);
284 if (new_activesubitemnum != mhd->activesubitemnum)
286 if (mhd->activesubitemnum != -1)
288 HighlightItem(mhd->activesubitem, ITEM_SUBITEM, mhd, IntuitionBase);
291 mhd->activesubitemnum = new_activesubitemnum;
292 mhd->activesubitem = item;
294 if (item)
296 HighlightItem(mhd->activesubitem, ITEM_SUBITEM, mhd, IntuitionBase);
301 else if (win && (win == mhd->menuwin))
303 item = FindItem(&new_activeitemnum, mhd);
305 if (new_activeitemnum != mhd->activeitemnum)
307 if (mhd->activeitemnum != -1)
309 HighlightItem(mhd->activeitem, ITEM_ITEM, mhd, IntuitionBase);
310 KillSubMenuWin(mhd, IntuitionBase);
313 mhd->activeitemnum = new_activeitemnum;
314 mhd->activeitem = item;
316 if (item)
318 HighlightItem(mhd->activeitem, ITEM_ITEM, mhd, IntuitionBase);
320 if (item->SubItem)
322 MakeSubMenuWin(mhd, IntuitionBase);
326 } /* if (win && (win == mhd->menuwin)) */
327 else if (win && (win == mhd->menubarwin))
329 /* Mouse over menu box */
331 menu = FindMenu(&new_activemenunum, mhd, IntuitionBase);
333 if (new_activemenunum != mhd->activemenunum)
336 if (mhd->activemenunum != -1)
338 HighlightMenuTitle(mhd->activemenu, mhd, IntuitionBase);
339 KillMenuWin(mhd, IntuitionBase);
340 KillSubMenuWin(mhd, IntuitionBase);
343 mhd->activemenunum = new_activemenunum;
344 mhd->activemenu = menu;
346 if (menu)
348 HighlightMenuTitle(mhd->activemenu, mhd, IntuitionBase);
349 MakeMenuWin(mhd, IntuitionBase);
353 if ((mhd->activeitemnum != -1) && (!mhd->submenuwin))
355 HighlightItem(mhd->activeitem, ITEM_ITEM, mhd, IntuitionBase);
356 mhd->activeitemnum = -1;
357 mhd->activeitem = NULL;
360 } /* if (win && (win == mhd->menubarwin)) */
361 else
363 win = NULL;
365 } /* if ((lay = WhichLayer(&mhd->scr->LayerInfo, mhd->scrmousex, mhd->scrmousey))) */
367 if (!win)
369 /* mouse outside any menu window */
371 if ((mhd->activeitemnum != -1) && (!mhd->submenuwin))
373 HighlightItem(mhd->activeitem, ITEM_ITEM, mhd, IntuitionBase);
374 mhd->activeitemnum = -1;
375 mhd->activeitem = NULL;
377 else if (mhd->activesubitemnum != -1)
379 HighlightItem(mhd->activesubitem, ITEM_SUBITEM, mhd, IntuitionBase);
380 mhd->activesubitemnum = -1;
381 mhd->activesubitem = NULL;
387 /**************************************************************************************************/
389 static void HandleSelection(struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase)
391 struct LayersBase *LayersBase = GetPrivIBase(IntuitionBase)->LayersBase;
392 struct Layer *lay;
394 LockLayerInfo(&mhd->scr->LayerInfo);
395 lay = WhichLayer(&mhd->scr->LayerInfo, mhd->scrmousex, mhd->scrmousey);
396 UnlockLayerInfo(&mhd->scr->LayerInfo);
398 if (lay)
400 struct Window *win = (struct Window *)lay->Window;
401 struct MenuItem *item = NULL;
403 if (win && (win == mhd->submenuwin) && (mhd->activesubitemnum != -1))
404 item = mhd->activesubitem;
405 else if (win && (win == mhd->menuwin) && (mhd->activeitemnum != -1))
406 item = mhd->activeitem;
408 if (item) {
409 if (item->Flags & CHECKIT)
410 HandleCheckItem(win, item, mhd, IntuitionBase);
413 AddToSelection(mhd, IntuitionBase);
417 /**************************************************************************************************/
419 static void HandleMouseClick(struct InputEvent *ie, struct MenuHandlerData *mhd,
420 struct IntuitionBase *IntuitionBase)
422 BOOL die = FALSE;
423 ULONG sticky = GetPrivIBase(IntuitionBase)->IControlPrefs.ic_Flags & ICF_STICKYMENUS; /* ic_Flags is ULONG */
425 switch(ie->ie_Code)
427 case MENUUP:
428 case SELECTDOWN:
429 if (!sticky)
431 HandleSelection(mhd, IntuitionBase);
433 if (ie->ie_Code == MENUUP)
434 die = TRUE;
437 break;
439 case SELECTUP:
440 if (sticky)
442 HandleSelection(mhd, IntuitionBase);
443 die = TRUE;
445 break;
447 case MENUDOWN:
448 if (sticky)
450 if (mhd->keepmenuup)
451 mhd->keepmenuup = FALSE;
452 else {
453 HandleSelection(mhd, IntuitionBase);
454 die = TRUE;
457 break;
458 } /* switch(ie->ie_Code) */
460 if (die)
462 KillMenuBarWin(mhd, IntuitionBase);
463 KillMenuWin(mhd, IntuitionBase);
464 KillSubMenuWin(mhd, IntuitionBase);
466 if (mhd->dri)
468 FreeScreenDrawInfo(mhd->scr, mhd->dri);
469 mhd->dri = 0;
471 MH2Int_MakeMenusInactive(mhd->win, mhd->firstmenupick, IntuitionBase);
472 mhd->active = FALSE;
476 /**************************************************************************************************/
478 static void HandleCheckItem(struct Window *win, struct MenuItem *item,
479 struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase)
481 /* Note: If you change something here, you probably must also change
482 menus.c/CheckMenuItemWasClicked() which is used when the
483 user uses the menu key shortcuts! */
485 WORD itemtype = ((win == mhd->menuwin) ? ITEM_ITEM : ITEM_SUBITEM);
487 BOOL re_render = FALSE;
489 if (item->Flags & MENUTOGGLE)
491 item->Flags ^= CHECKED;
492 re_render = TRUE;
494 else
496 if (!(item->Flags & CHECKED))
498 item->Flags |= CHECKED;
499 re_render = TRUE;
503 if (re_render)
505 BOOL toggle_hi = FALSE;
507 if ((item->Flags & HIGHITEM) &&
508 ((item->Flags & HIGHFLAGS) == HIGHCOMP)) toggle_hi = TRUE;
510 if (toggle_hi) HighlightItem(item, itemtype, mhd, IntuitionBase);
511 RenderCheckMark(item, itemtype, mhd, IntuitionBase);
512 if (toggle_hi) HighlightItem(item, itemtype, mhd, IntuitionBase);
516 if (item->MutualExclude)
518 struct MenuItem *checkitem = (itemtype == ITEM_ITEM) ? mhd->activemenu->FirstItem :
519 mhd->activeitem->SubItem;
520 BOOL toggle_hi = FALSE;
521 WORD i;
523 if ((item->Flags & HIGHITEM) &&
524 ((item->Flags & HIGHFLAGS) == HIGHBOX)) toggle_hi = TRUE;
526 if (toggle_hi) HighlightItem(item, itemtype, mhd, IntuitionBase);
528 for(i = 0; (i < 32) && checkitem; i++, checkitem = checkitem->NextItem)
530 if ((item->MutualExclude & (1L << i)) &&
531 ((checkitem->Flags & (CHECKED | CHECKIT)) == (CHECKIT | CHECKED)))
533 checkitem->Flags &= ~CHECKED;
534 RenderCheckMark(checkitem, itemtype, mhd, IntuitionBase);
538 if (toggle_hi) HighlightItem(item, itemtype, mhd, IntuitionBase);
540 } /* if (item->MutualExclude) */
543 /**************************************************************************************************/
545 static inline BOOL CustomDrawBackground(struct RastPort *rp, struct Window *win,
546 LONG itemleft, LONG itemtop, LONG itemwidth, LONG itemheight, UWORD flags,
547 struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase)
549 struct mdpDrawBackground msg;
551 msg.MethodID = MDM_DRAWBACKGROUND;
552 msg.mdp_RPort = rp;
553 msg.mdp_TrueColor = mhd->TrueColor;
554 msg.mdp_X = 0;
555 msg.mdp_Y = 0;
556 msg.mdp_Width = win->Width - 1;
557 msg.mdp_Height = win->Height - 1;
558 msg.mdp_ItemLeft = itemleft;
559 msg.mdp_ItemTop = itemtop;
560 msg.mdp_ItemWidth = itemwidth;
561 msg.mdp_ItemHeight = itemheight;
562 msg.mdp_Flags = flags;
564 msg.mdp_MenuDecorFlags = (MENUS_UNDERMOUSE(IntuitionBase)) ? MDP_MDF_MENUS_UNDERMOUSE : 0;
565 if (win == mhd->submenuwin) { msg.mdp_UserBuffer = mhd->SubDecorUserBuffer; msg.mdp_MenuDecorFlags |= MDP_MDF_SUBITEM; }
566 else if (win == mhd->menuwin) { msg.mdp_UserBuffer = mhd->DecorUserBuffer; msg.mdp_MenuDecorFlags |= MDP_MDF_ITEM; }
567 else { msg.mdp_UserBuffer = mhd->BarDecorUserBuffer; msg.mdp_MenuDecorFlags |= MDP_MDF_MENU; }
569 return DoMethodA(((struct IntScreen *)(mhd->scr))->MenuDecorObj, (Msg)&msg);
572 /**************************************************************************************************/
574 static void HighlightMenuTitle(struct Menu *menu, struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase)
576 struct GfxBase *GfxBase = GetPrivIBase(IntuitionBase)->GfxBase;
578 if ((menu->Flags & MENUENABLED) && mhd->menubarwin)
580 struct RastPort *rp = mhd->menubarwin->RPort;
581 WORD x1, x2, y1, y2;
583 if (MENUS_UNDERMOUSE(IntuitionBase))
585 WORD i;
586 struct Menu *m = mhd->menu;
588 x1 = mhd->innerleft;
590 x2 = x1 + mhd->menubaritemwidth - 1;
592 for(i = 0; m != menu; m = m->NextMenu) i++;
594 y1 = mhd->innertop + i * mhd->menubaritemheight;
595 y2 = y1 + mhd->menubaritemheight - 1;
598 else
600 x1 = menu->LeftEdge + mhd->scr->BarHBorder - mhd->scr->MenuHBorder;
601 if (x1 < 0) x1 = 0;
602 y1 = 0;
603 x2 = x1 + menu->Width - 1;
604 y2 = mhd->scr->BarHeight - 1;
607 menu->Flags ^= HIGHITEM;
608 if (CustomDrawBackground(rp, mhd->win, x1, y1, x2 - x1 + 1, y2 - y1 + 1, menu->Flags, mhd, IntuitionBase))
610 RenderMenuTitle(menu, mhd, IntuitionBase);
611 return;
614 if (MENUS_AMIGALOOK(IntuitionBase))
616 SetDrMd(rp, COMPLEMENT);
617 RectFill(rp, x1, y1, x2, y2);
619 else
621 if (!MENUS_UNDERMOUSE(IntuitionBase)) y1++;
623 SetDrMd(rp, JAM1);
624 SetAPen(rp, mhd->dri->dri_Pens[(menu->Flags & HIGHITEM) ? FILLPEN : BACKGROUNDPEN]);
625 RectFill(rp, x1, y1, x2, y2);
626 RenderMenuTitle(menu, mhd, IntuitionBase);
628 if ((menu->Flags & HIGHITEM))
630 if (MENUS_UNDERMOUSE(IntuitionBase))
632 RenderFrame(rp, x1, y1, x2, y2, IDS_SELECTED, mhd, IntuitionBase);
634 else
636 SetAPen(rp, mhd->dri->dri_Pens[SHINEPEN]);
637 RectFill(rp, x1, y1, x1, y2);
638 SetAPen(rp, mhd->dri->dri_Pens[SHADOWPEN]);
639 RectFill(rp, x2, y1, x2, y2);
646 /**************************************************************************************************/
648 static struct Menu *FindMenu(WORD *var, struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase)
650 struct Menu *menu = NULL;
651 WORD mouse_x, mouse_y, i;
653 if(mhd->menubarwin)
655 mouse_x = mhd->scrmousex - mhd->menubarwin->LeftEdge;
656 mouse_y = mhd->scrmousey - mhd->menubarwin->TopEdge;
658 if (MENUS_UNDERMOUSE(IntuitionBase))
660 menu = NULL;
662 mouse_x -= mhd->innerleft;
663 mouse_y -= mhd->innertop;
665 if ((mouse_x >= 0) && (mouse_x < mhd->menubaritemwidth) && (mouse_y >= 0))
667 i = mouse_y / mhd->menubaritemheight;
669 if ((i >= 0) && (i < mhd->nummenubaritems))
671 WORD i2 = i;
673 menu = mhd->menu;
674 while(i && menu)
676 i--;
677 menu = menu->NextMenu;
680 if (menu && (i == 0))
682 *var = i2;
687 else
689 for(menu = mhd->menu, i = 0; menu; menu = menu->NextMenu, i++)
691 if ((mouse_x >= menu->LeftEdge) &&
692 (mouse_x < menu->LeftEdge + menu->Width) &&
693 (mouse_y >= 0) &&
694 (mouse_y <= mhd->scr->BarHeight))
696 *var = i;
697 break;
702 return menu;
705 /**************************************************************************************************/
707 static struct MenuItem *FindItem(WORD *var, struct MenuHandlerData *mhd)
709 struct MenuItem *item = NULL;
710 WORD mouse_x, mouse_y, i;
712 if (mhd->menuwin)
714 mouse_x = mhd->scrmousex - mhd->menuwin->LeftEdge
715 + mhd->activemenu->JazzX - mhd->innerleft - mhd->menuinnerleft;
716 mouse_y = mhd->scrmousey - mhd->menuwin->TopEdge
717 + mhd->activemenu->JazzY - mhd->innertop - mhd->menuinnertop;
719 for(item = mhd->activemenu->FirstItem, i = 0; item; item = item->NextItem, i++)
721 if ((mouse_x >= item->LeftEdge) &&
722 (mouse_x < item->LeftEdge + item->Width) &&
723 (mouse_y >= item->TopEdge) &&
724 (mouse_y < item->TopEdge + item->Height))
726 *var = i;
727 break;
730 } /* if (mhd->menuwin) */
732 if ((item == NULL) && !mhd->submenuwin) *var = -1;
734 return item;
737 /**************************************************************************************************/
739 static struct MenuItem *FindSubItem(WORD *var, struct MenuHandlerData *mhd)
741 struct MenuItem *item = NULL;
742 WORD mouse_x, mouse_y, i;
744 if (mhd->submenuwin)
746 mouse_x = mhd->scrmousex - mhd->submenuwin->LeftEdge + mhd->submenubox.MinX - mhd->menuinnerleft;
747 mouse_y = mhd->scrmousey - mhd->submenuwin->TopEdge + mhd->submenubox.MinY - mhd->menuinnertop;
749 *var = -1;
751 for(item = mhd->activeitem->SubItem, i = 0; item; item = item->NextItem, i++)
753 if ((mouse_x >= item->LeftEdge) &&
754 (mouse_x < item->LeftEdge + item->Width) &&
755 (mouse_y >= item->TopEdge) &&
756 (mouse_y < item->TopEdge + item->Height))
758 *var = i;
759 break;
763 } /* if (mhd->menuwin) */
765 return item;
768 /**************************************************************************************************/
770 static void MakeMenuBarWin(struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase)
772 struct GfxBase *GfxBase = GetPrivIBase(IntuitionBase)->GfxBase;
773 struct TagItem win_tags[] =
775 {WA_Left , 0 },
776 {WA_Top , 0 },
777 {WA_Width , mhd->scr->Width },
778 {WA_Height , mhd->scr->BarHeight + 1},
779 {WA_AutoAdjust , TRUE },
780 {WA_Borderless , TRUE },
781 {WA_CustomScreen, (IPTR)mhd->scr },
782 {WA_BackFill , (IPTR)LAYERS_NOBACKFILL},
783 {TAG_DONE , 0 }
785 struct Menu *menu;
787 mhd->menubarwin = NULL;
788 /* No entry to draw ? */
789 if(mhd->menu == NULL) return;
791 if (MENUS_UNDERMOUSE(IntuitionBase))
793 struct RastPort *temprp;
794 WORD w, maxw = 0;
796 if (!(temprp = CloneRastPort(&mhd->scr->RastPort))) return;
798 mhd->nummenubaritems = 0;
799 for(menu = mhd->menu; menu; menu = menu->NextMenu)
801 w = TextLength(temprp, menu->MenuName, strlen(menu->MenuName));
802 if (w > maxw) maxw = w;
803 mhd->nummenubaritems++;
806 mhd->menubaritemwidth = maxw + mhd->submenuimage->Width +
807 TEXT_AMIGAKEY_SPACING +
808 ITEXT_EXTRA_LEFT +
809 ITEXT_EXTRA_RIGHT;
811 if (temprp->TxHeight > mhd->submenuimage->Height)
813 mhd->menubaritemheight = temprp->TxHeight;
815 else
817 mhd->menubaritemheight = mhd->submenuimage->Height;
820 mhd->menubaritemheight += (ITEXT_EXTRA_TOP + ITEXT_EXTRA_BOTTOM);
822 struct mdpGetMenuSpaces msg;
824 msg.MethodID = MDM_GETMENUSPACES;
825 msg.mdp_TrueColor = mhd->TrueColor;
826 msg.mdp_InnerLeft = mhd->scr->MenuHBorder;
827 msg.mdp_InnerTop = mhd->scr->MenuVBorder;
828 msg.mdp_InnerRight = mhd->scr->MenuHBorder;
829 msg.mdp_InnerBottom = mhd->scr->MenuVBorder;
830 msg.mdp_ItemInnerLeft = 0;
831 msg.mdp_ItemInnerTop = 0;
832 msg.mdp_ItemInnerRight = 0;
833 msg.mdp_ItemInnerBottom = 0;
834 msg.mdp_MinWidth = 0;
835 msg.mdp_MinHeight = 0;
836 DoMethodA(((struct IntScreen *)(mhd->scr))->MenuDecorObj, (Msg)&msg);
837 mhd->innerleft = msg.mdp_InnerLeft;
838 mhd->innerright = msg.mdp_InnerRight;
839 mhd->innertop = msg.mdp_InnerTop;
840 mhd->innerbottom = msg.mdp_InnerBottom;
841 mhd->iteminnerleft = msg.mdp_ItemInnerLeft;
842 mhd->iteminnerright = msg.mdp_ItemInnerRight;
843 mhd->iteminnertop = msg.mdp_ItemInnerTop;
844 mhd->iteminnerbottom = msg.mdp_ItemInnerBottom;
845 mhd->menubaritemwidth += (mhd->iteminnerleft + mhd->iteminnerright);
846 mhd->menubaritemheight += (mhd->iteminnertop + mhd->iteminnerbottom);
848 win_tags[2].ti_Data = mhd->menubaritemwidth + mhd->innerleft + mhd->innerright;
849 win_tags[3].ti_Data = mhd->menubaritemheight * mhd->nummenubaritems + mhd->innertop + mhd->innerbottom;
851 if (win_tags[2].ti_Data < msg.mdp_MinWidth)
853 mhd->menubaritemwidth += (msg.mdp_MinWidth - win_tags[2].ti_Data);
854 win_tags[2].ti_Data = msg.mdp_MinWidth;
857 if (win_tags[3].ti_Data < msg.mdp_MinHeight)
859 win_tags[3].ti_Data = msg.mdp_MinHeight;
862 WORD PosX = mhd->scr->MouseX - win_tags[2].ti_Data / 2;
863 win_tags[1].ti_Data = mhd->scr->MouseY;
865 if ((PosX + win_tags[2].ti_Data) > mhd->scr->Width) PosX = mhd->scr->Width - win_tags[2].ti_Data;
866 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;
867 if (PosX < 0) PosX = 0;
868 if (win_tags[1].ti_Data > 32000) win_tags[1].ti_Data = 0;
870 win_tags[0].ti_Data = PosX;
872 FreeRastPort(temprp);
876 IPTR userbuffersize;
877 struct mdpInitMenu msg;
879 GetAttr(MDA_UserBuffer, ((struct IntScreen *)(mhd->scr))->MenuDecorObj, &userbuffersize);
881 if (userbuffersize)
883 mhd->DecorUserBufferSize = userbuffersize;
884 mhd->BarDecorUserBuffer = (IPTR) AllocMem(userbuffersize, MEMF_ANY | MEMF_CLEAR);
885 if (0 == mhd->BarDecorUserBuffer) return;
888 msg.MethodID = MDM_INITMENU;
889 msg.mdp_TrueColor = mhd->TrueColor;
890 msg.mdp_RPort = &mhd->scr->RastPort;
891 msg.mdp_Left = win_tags[0].ti_Data;
892 msg.mdp_Top = win_tags[1].ti_Data;
893 msg.mdp_Width = win_tags[2].ti_Data;
894 msg.mdp_Height = win_tags[3].ti_Data;
895 msg.mdp_UserBuffer = mhd->BarDecorUserBuffer;
896 msg.mdp_ScreenUserBuffer = ((struct IntScreen *) mhd->scr)->DecorUserBuffer;
897 msg.mdp_MenuDecorFlags = (MENUS_UNDERMOUSE(IntuitionBase)) ? MDP_MDF_MENUS_UNDERMOUSE : 0;
898 msg.mdp_MenuDecorFlags |= MDP_MDF_MENU;
900 msg.mdp_Screen = mhd->scr;
902 DoMethodA(((struct IntScreen *)(mhd->scr))->MenuDecorObj, (Msg)&msg);
906 D(bug("MakeMenuBarWin: mhd 0x%lx\n", mhd));
908 mhd->menubarwin = OpenWindowTagList(0, win_tags);
910 for(menu = mhd->menu; menu; menu = menu->NextMenu)
912 menu->Flags &= ~HIGHITEM;
915 RenderMenuBar(mhd, IntuitionBase);
918 /**************************************************************************************************/
920 static void KillMenuBarWin(struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase)
922 if (mhd->menubarwin)
924 struct mdpExitMenu msg;
926 CloseWindow(mhd->menubarwin);
927 mhd->menubarwin = NULL;
929 msg.MethodID = MDM_EXITMENU;
930 msg.mdp_UserBuffer = mhd->BarDecorUserBuffer;
931 msg.mdp_TrueColor = mhd->TrueColor;
932 DoMethodA(((struct IntScreen *)(mhd->scr))->MenuDecorObj, (Msg)&msg);
934 if (mhd->BarDecorUserBuffer)
936 FreeMem((void *)mhd->BarDecorUserBuffer, mhd->DecorUserBufferSize);
938 mhd->BarDecorUserBuffer = 0;
943 /**************************************************************************************************/
945 static void RenderMenuBar(struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase)
947 struct GfxBase *GfxBase = GetPrivIBase(IntuitionBase)->GfxBase;
948 if (mhd->menubarwin)
950 struct Menu *menu = mhd->menu;
951 struct Window *win = mhd->menubarwin;
952 struct RastPort *rp = win->RPort;
954 SetFont(rp, mhd->dri->dri_Font);
956 /* Bar renders using different pens in Amiga mode than rest of menu */
957 if (MENUS_UNDERMOUSE(IntuitionBase))
959 RenderMenuBG(win, mhd, IntuitionBase);
961 else
963 if (!CustomDrawBackground(rp, win, 0, 0, win->Width - 1, win->Height - 1, 0, mhd, IntuitionBase))
965 if (MENUS_AMIGALOOK(IntuitionBase))
967 SetABPenDrMd(rp, mhd->dri->dri_Pens[BARBLOCKPEN], 0, JAM1);
969 else
971 SetABPenDrMd(rp, mhd->dri->dri_Pens[BACKGROUNDPEN], 0, JAM1);
974 RectFill(rp, 0, 0, win->Width - 1, win->Height - 2);
976 SetAPen(rp, mhd->dri->dri_Pens[BARTRIMPEN]);
977 RectFill(rp, 0, win->Height - 1, win->Width - 1, win->Height - 1);
979 if (!MENUS_AMIGALOOK(IntuitionBase))
981 SetAPen(rp, mhd->dri->dri_Pens[SHINEPEN]);
982 RectFill(rp, 0, 0, 0, win->Height - 2);
983 RectFill(rp, 1, 0, win->Width - 1, 0);
984 SetAPen(rp, mhd->dri->dri_Pens[SHADOWPEN]);
985 RectFill(rp, win->Width - 1, 1, win->Width - 1, win->Height - 2);
990 for(; menu; menu = menu->NextMenu)
992 RenderMenuTitle(menu, mhd, IntuitionBase);
997 /**************************************************************************************************/
999 static void RenderMenuTitle(struct Menu *menu, struct MenuHandlerData *mhd,
1000 struct IntuitionBase *IntuitionBase)
1002 struct GfxBase *GfxBase = GetPrivIBase(IntuitionBase)->GfxBase;
1003 struct RastPort *rp;
1004 WORD len = strlen(menu->MenuName);
1005 WORD x, y;
1007 if(mhd->menubarwin)
1009 rp = mhd->menubarwin->RPort;
1010 SetDrMd(rp, JAM1);
1012 if (MENUS_UNDERMOUSE(IntuitionBase))
1014 struct Menu *m;
1015 WORD yoff;
1017 yoff = 0;
1018 for(m = mhd->menu; m && (m != menu);m = m ->NextMenu)
1020 yoff++;
1023 x = mhd->innerleft + ITEXT_EXTRA_LEFT;
1024 y = mhd->innertop + ITEXT_EXTRA_TOP + yoff * mhd->menubaritemheight;
1026 else
1028 x = mhd->scr->BarHBorder + menu->LeftEdge;
1029 y = mhd->scr->BarVBorder + ((mhd->scr->BarHeight - rp->Font->tf_YSize) / 2);
1032 if (MENUS_AMIGALOOK(IntuitionBase))
1034 SetAPen(rp, mhd->dri->dri_Pens[BARDETAILPEN]);
1036 else
1038 SetAPen(rp, mhd->dri->dri_Pens[(menu->Flags & HIGHITEM) ? FILLTEXTPEN : TEXTPEN]);
1041 Move(rp, x, y + rp->TxBaseline);
1042 Text(rp, menu->MenuName, len);
1044 if (MENUS_UNDERMOUSE(IntuitionBase))
1046 if (menu->FirstItem)
1048 WORD x2 = mhd->scr->MenuHBorder + mhd->menubaritemwidth - ITEXT_EXTRA_RIGHT - mhd->submenuimage->Width;
1050 DrawImageState(rp, mhd->submenuimage, x2, y + ((mhd->menubaritemheight - mhd->submenuimage->Height) >> 1), IDS_NORMAL, mhd->dri);
1054 if (!(menu->Flags & MENUENABLED))
1056 WORD y2 = y + rp->TxHeight - 1;
1057 WORD x2;
1059 if (MENUS_UNDERMOUSE(IntuitionBase))
1061 x2 = mhd->scr->MenuHBorder + mhd->menubaritemwidth - 1;
1063 else
1065 x2 = x + TextLength(rp, menu->MenuName, len) - 1;
1068 RenderDisabledPattern(rp, x, y, x2, y2, mhd, IntuitionBase);
1073 /**************************************************************************************************/
1075 static void MakeMenuWin(struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase)
1077 struct MenuItem *item;
1079 WORD width = mhd->activemenu->BeatX - mhd->activemenu->JazzX + 1;
1080 WORD height = mhd->activemenu->BeatY - mhd->activemenu->JazzY + 1;
1081 WORD xpos,ypos;
1083 struct mdpGetMenuSpaces msg;
1085 msg.MethodID = MDM_GETMENUSPACES;
1086 msg.mdp_TrueColor = mhd->TrueColor;
1087 msg.mdp_InnerLeft = 0;
1088 msg.mdp_InnerTop = 0;
1089 msg.mdp_InnerRight = 0;
1090 msg.mdp_InnerBottom = 0;
1091 msg.mdp_ItemInnerLeft = 0;
1092 msg.mdp_ItemInnerTop = 0;
1093 msg.mdp_ItemInnerRight = 0;
1094 msg.mdp_ItemInnerBottom = 0;
1095 DoMethodA(((struct IntScreen *)(mhd->scr))->MenuDecorObj, (Msg)&msg);
1096 mhd->menuinnerleft = msg.mdp_InnerLeft;
1097 mhd->menuinnerright = msg.mdp_InnerRight;
1098 mhd->menuinnertop = msg.mdp_InnerTop;
1099 mhd->menuinnerbottom = msg.mdp_InnerBottom;
1101 width += (mhd->menuinnerleft + mhd->menuinnerright);
1102 height += (mhd->menuinnertop + mhd->menuinnerbottom);
1104 if (MENUS_UNDERMOUSE(IntuitionBase))
1106 xpos = mhd->menubarwin->LeftEdge + mhd->menubarwin->Width - 16;
1107 ypos = mhd->menubarwin->TopEdge;
1109 else
1111 xpos = mhd->activemenu->LeftEdge + mhd->scr->BarHBorder + mhd->activemenu->JazzX;
1113 if (MENUS_AMIGALOOK(IntuitionBase))
1115 ypos = mhd->scr->BarHeight + 1 + mhd->activemenu->JazzY;
1117 else
1119 ypos = mhd->scr->BarHeight + 1;
1124 struct TagItem win_tags[] =
1126 {WA_Left , xpos },
1127 {WA_Top , ypos },
1128 {WA_Width , width },
1129 {WA_Height , height },
1130 {WA_AutoAdjust , TRUE },
1131 {WA_Borderless , TRUE },
1132 {WA_CustomScreen, (IPTR)mhd->scr },
1133 {WA_BackFill , (IPTR)LAYERS_NOBACKFILL},
1134 {TAG_DONE , 0 }
1137 if (MENUS_UNDERMOUSE(IntuitionBase))
1139 win_tags[1].ti_Data += (mhd->menubaritemheight * mhd->activemenunum + mhd->scr->MenuVBorder) -
1140 height / 2;
1141 if (xpos + width > mhd->scr->Width)
1143 win_tags[0].ti_Data = mhd->menubarwin->LeftEdge - width + 16;
1147 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;
1148 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;
1149 if (((LONG) win_tags[0].ti_Data) < 0) win_tags[0].ti_Data = 0;
1150 if (((LONG) win_tags[1].ti_Data) < 0) win_tags[1].ti_Data = 0;
1152 if ((item = mhd->activemenu->FirstItem))
1155 while(item)
1157 item->Flags &= ~HIGHITEM;
1158 item = item->NextItem;
1161 IPTR userbuffersize;
1163 GetAttr(MDA_UserBuffer, ((struct IntScreen *)(mhd->scr))->MenuDecorObj, &userbuffersize);
1165 if (userbuffersize)
1167 mhd->DecorUserBufferSize = userbuffersize;
1168 mhd->DecorUserBuffer = (IPTR) AllocMem(userbuffersize, MEMF_ANY | MEMF_CLEAR);
1169 if (0 == mhd->DecorUserBuffer) return;
1172 struct mdpInitMenu msg;
1174 msg.MethodID = MDM_INITMENU;
1175 msg.mdp_TrueColor = mhd->TrueColor;
1176 msg.mdp_RPort = &mhd->scr->RastPort;
1177 msg.mdp_Left = win_tags[0].ti_Data;
1178 msg.mdp_Top = win_tags[1].ti_Data;
1179 msg.mdp_Width = width;
1180 msg.mdp_Height = height;
1181 msg.mdp_UserBuffer = mhd->DecorUserBuffer;
1182 msg.mdp_ScreenUserBuffer = ((struct IntScreen *) mhd->scr)->DecorUserBuffer;
1183 msg.mdp_Screen = mhd->scr;
1184 msg.mdp_MenuDecorFlags = (MENUS_UNDERMOUSE(IntuitionBase)) ? MDP_MDF_MENUS_UNDERMOUSE : 0;
1185 msg.mdp_MenuDecorFlags |= MDP_MDF_ITEM;
1187 DoMethodA(((struct IntScreen *)(mhd->scr))->MenuDecorObj, (Msg)&msg);
1189 mhd->menuwin = OpenWindowTagList(0, win_tags);
1191 mhd->maxcommkeywidth_menu = CalcMaxCommKeyWidth(mhd->menuwin, mhd, IntuitionBase);
1193 RenderMenu(mhd, IntuitionBase);
1195 mhd->activemenu->Flags |= MIDRAWN;
1200 /**************************************************************************************************/
1202 static void KillMenuWin(struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase)
1204 if (mhd->menuwin)
1206 struct MenuItem *item;
1208 CloseWindow(mhd->menuwin);
1209 mhd->menuwin = NULL;
1211 TimeDelay(UNIT_VBLANK,0,20000);
1213 for(item = mhd->activemenu->FirstItem; item; item = item->NextItem)
1215 item->Flags &= ~ISDRAWN;
1217 struct mdpExitMenu msg;
1219 msg.MethodID = MDM_EXITMENU;
1220 msg.mdp_TrueColor = mhd->TrueColor;
1221 msg.mdp_UserBuffer = mhd->DecorUserBuffer;
1222 DoMethodA(((struct IntScreen *)(mhd->scr))->MenuDecorObj, (Msg)&msg);
1224 if (mhd->DecorUserBuffer)
1226 FreeMem((void *)mhd->DecorUserBuffer, mhd->DecorUserBufferSize);
1228 mhd->DecorUserBuffer = 0;
1230 mhd->activemenu->Flags &= ~MIDRAWN;
1232 mhd->activeitemnum = -1;
1233 mhd->activeitem = NULL;
1237 /**************************************************************************************************/
1239 static void RenderMenu(struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase)
1241 struct GfxBase *GfxBase = GetPrivIBase(IntuitionBase)->GfxBase;
1243 if (mhd->menuwin)
1245 struct MenuItem *item;
1247 RenderMenuBG(mhd->menuwin, mhd, IntuitionBase);
1249 SetFont(mhd->menuwin->RPort, mhd->dri->dri_Font);
1251 for(item = mhd->activemenu->FirstItem; item; item = item->NextItem)
1253 RenderItem(item, ITEM_ITEM, (struct Rectangle *)(&mhd->activemenu->JazzX), mhd, IntuitionBase);
1256 } /* if (mhd->menuwin) */
1259 /**************************************************************************************************/
1261 static void MakeSubMenuWin(struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase)
1263 struct MenuItem *item = mhd->activeitem->SubItem;
1265 struct TagItem win_tags[] =
1267 {WA_Left , 0 },
1268 {WA_Top , 0 },
1269 {WA_Width , 0 },
1270 {WA_Height , 0 },
1271 {WA_AutoAdjust , TRUE },
1272 {WA_Borderless , TRUE },
1273 {WA_CustomScreen, (IPTR)mhd->scr },
1274 {WA_BackFill , (IPTR)LAYERS_NOBACKFILL },
1275 {TAG_DONE }
1278 if(mhd->menubarwin)
1280 GetMenuBox(mhd->menubarwin, item, &mhd->submenubox.MinX,
1281 &mhd->submenubox.MinY,
1282 &mhd->submenubox.MaxX,
1283 &mhd->submenubox.MaxY);
1286 struct mdpGetMenuSpaces msg;
1288 msg.MethodID = MDM_GETMENUSPACES;
1289 msg.mdp_TrueColor = mhd->TrueColor;
1290 msg.mdp_InnerLeft = 0;
1291 msg.mdp_InnerTop = 0;
1292 msg.mdp_InnerRight = 0;
1293 msg.mdp_InnerBottom = 0;
1295 DoMethodA(((struct IntScreen *)(mhd->scr))->MenuDecorObj, (Msg)&msg);
1296 mhd->menuinnerleft = msg.mdp_InnerLeft;
1297 mhd->menuinnerright = msg.mdp_InnerRight;
1298 mhd->menuinnertop = msg.mdp_InnerTop;
1299 mhd->menuinnerbottom = msg.mdp_InnerBottom;
1302 win_tags[0].ti_Data = mhd->menuwin->LeftEdge +
1303 mhd->activeitem->LeftEdge - mhd->activemenu->JazzX +
1304 mhd->submenubox.MinX;
1306 win_tags[1].ti_Data = mhd->menuwin->TopEdge +
1307 mhd->activeitem->TopEdge - mhd->activemenu->JazzY +
1308 mhd->submenubox.MinY;
1310 win_tags[2].ti_Data = mhd->submenubox.MaxX - mhd->submenubox.MinX + 1 + mhd->menuinnerleft + mhd->menuinnerright;
1311 win_tags[3].ti_Data = mhd->submenubox.MaxY - mhd->submenubox.MinY + 1 + mhd->menuinnertop + mhd->menuinnerbottom;
1313 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;
1314 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;
1315 if (((LONG) win_tags[0].ti_Data) < 0) win_tags[0].ti_Data = 0;
1316 if (((LONG) win_tags[1].ti_Data) < 0) win_tags[1].ti_Data = 0;
1318 while(item)
1320 item->Flags &= ~HIGHITEM;
1321 item = item->NextItem;
1324 IPTR userbuffersize;
1326 GetAttr(MDA_UserBuffer, ((struct IntScreen *)(mhd->scr))->MenuDecorObj, &userbuffersize);
1328 if (userbuffersize)
1330 mhd->DecorUserBufferSize = userbuffersize;
1331 mhd->SubDecorUserBuffer = (IPTR) AllocMem(userbuffersize, MEMF_ANY | MEMF_CLEAR);
1332 if (0 == mhd->SubDecorUserBuffer) return;
1336 struct mdpInitMenu msg;
1337 msg.MethodID = MDM_INITMENU;
1338 msg.mdp_TrueColor = mhd->TrueColor;
1339 msg.mdp_RPort = &mhd->scr->RastPort;
1340 msg.mdp_Left = win_tags[0].ti_Data;
1341 msg.mdp_Top = win_tags[1].ti_Data;
1342 msg.mdp_Width = win_tags[2].ti_Data;
1343 msg.mdp_Height = win_tags[3].ti_Data;
1344 msg.mdp_UserBuffer = mhd->SubDecorUserBuffer;
1345 msg.mdp_ScreenUserBuffer = ((struct IntScreen *) mhd->scr)->DecorUserBuffer;
1346 msg.mdp_TrueColor = mhd->TrueColor;
1347 msg.mdp_Screen = mhd->scr;
1348 msg.mdp_MenuDecorFlags = (MENUS_UNDERMOUSE(IntuitionBase)) ? MDP_MDF_MENUS_UNDERMOUSE : 0;
1349 msg.mdp_MenuDecorFlags |= MDP_MDF_SUBITEM;
1351 DoMethodA(((struct IntScreen *)(mhd->scr))->MenuDecorObj, (Msg)&msg);
1353 mhd->submenuwin = OpenWindowTagList(0, win_tags);
1355 mhd->maxcommkeywidth_submenu = CalcMaxCommKeyWidth(mhd->submenuwin, mhd, IntuitionBase);
1357 RenderSubMenu(mhd, IntuitionBase);
1361 /**************************************************************************************************/
1363 static void KillSubMenuWin(struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase)
1365 if (mhd->submenuwin)
1367 CloseWindow(mhd->submenuwin);
1369 TimeDelay(UNIT_VBLANK,0,20000);
1370 struct mdpExitMenu msg;
1372 msg.MethodID = MDM_EXITMENU;
1373 msg.mdp_TrueColor = mhd->TrueColor;
1374 msg.mdp_UserBuffer = mhd->SubDecorUserBuffer;
1375 DoMethodA(((struct IntScreen *)(mhd->scr))->MenuDecorObj, (Msg)&msg);
1377 if (mhd->SubDecorUserBuffer)
1379 FreeMem((void *)mhd->SubDecorUserBuffer, mhd->DecorUserBufferSize);
1381 mhd->SubDecorUserBuffer = 0;
1383 mhd->submenuwin = NULL;
1385 mhd->activesubitemnum = -1;
1386 mhd->activesubitem = NULL;
1390 /**************************************************************************************************/
1392 static void RenderSubMenu(struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase)
1394 struct GfxBase *GfxBase = GetPrivIBase(IntuitionBase)->GfxBase;
1396 if (mhd->submenuwin)
1398 struct MenuItem *item;
1400 RenderMenuBG(mhd->submenuwin, mhd, IntuitionBase);
1402 SetFont(mhd->submenuwin->RPort, mhd->dri->dri_Font);
1404 for(item = mhd->activeitem->SubItem; item; item = item->NextItem)
1406 RenderItem(item, ITEM_SUBITEM, (struct Rectangle *)(&mhd->submenubox), mhd, IntuitionBase);
1409 } /* if (mhd->submenuwin) */
1412 /**************************************************************************************************/
1414 static void RenderItem(struct MenuItem *item, WORD itemtype, struct Rectangle *box,
1415 struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase)
1417 struct GfxBase *GfxBase = GetPrivIBase(IntuitionBase)->GfxBase;
1418 struct Window *win = ((itemtype == ITEM_ITEM) ? mhd->menuwin : mhd->submenuwin);
1419 struct RastPort *rp = win->RPort;
1420 WORD offx = -box->MinX + mhd->menuinnerleft;
1421 WORD offy = -box->MinY + mhd->menuinnertop;
1422 BOOL enabled = ((item->Flags & ITEMENABLED) &&
1423 (mhd->activemenu->Flags & MENUENABLED) &&
1424 ((itemtype == ITEM_ITEM) || (mhd->activeitem->Flags & ITEMENABLED)));
1425 BOOL item_supports_disable = FALSE;
1427 SetDrMd(rp, JAM1);
1429 if (item->ItemFill)
1432 if (item->Flags & ITEMTEXT)
1434 struct IntuiText *save = ((struct IntuiText*) item->ItemFill)->NextText;
1436 if (item->SubItem)
1438 Forbid();
1439 ((struct IntuiText*) item->ItemFill)->NextText = NULL;
1442 struct IntuiText *it = (struct IntuiText *)item->ItemFill;
1444 if (MENUS_AMIGALOOK(IntuitionBase))
1446 PrintIText(rp, it, offx + item->LeftEdge, offy + item->TopEdge);
1448 else
1450 it->FrontPen = mhd->dri->dri_Pens[(item->Flags & HIGHITEM) ? FILLTEXTPEN : TEXTPEN];
1451 it->DrawMode = JAM1;
1453 PrintIText(rp, it, offx + item->LeftEdge, offy + item->TopEdge);
1455 if (item->SubItem)
1457 DrawImageState(rp, mhd->submenuimage, offx + item->Width - mhd->submenuimage->Width, offy + item->TopEdge + ((item->Height - mhd->submenuimage->Height) >> 1), IDS_NORMAL, mhd->dri);
1458 ((struct IntuiText*) item->ItemFill)->NextText = save;
1459 Permit();
1462 else
1464 struct Image *im = (struct Image *)item->ItemFill;
1465 LONG state = IDS_NORMAL;
1467 if (!enabled && (im->Depth == CUSTOMIMAGEDEPTH))
1469 IPTR val = 0;
1471 GetAttr(IA_SupportsDisable, (Object *)im, &val);
1472 if (val)
1474 item_supports_disable = TRUE;
1475 state = IDS_DISABLED;
1479 DrawImageState(rp, im, offx + item->LeftEdge, offy + item->TopEdge, state, mhd->dri);
1482 } /* if (item->ItemFill) */
1484 RenderCheckMark(item, itemtype, mhd, IntuitionBase);
1485 RenderAmigaKey(item, itemtype, mhd, IntuitionBase);
1487 if (!enabled && !item_supports_disable)
1489 RenderDisabledPattern(rp, offx + item->LeftEdge,
1490 offy + item->TopEdge,
1491 offx + item->LeftEdge + item->Width - 1,
1492 offy + item->TopEdge + item->Height - 1,
1493 mhd,
1494 IntuitionBase);
1499 /**************************************************************************************************/
1501 static void RenderMenuBG(struct Window *win, struct MenuHandlerData *mhd,
1502 struct IntuitionBase *IntuitionBase)
1505 struct GfxBase *GfxBase = GetPrivIBase(IntuitionBase)->GfxBase;
1506 struct RastPort *rp = win->RPort;
1507 WORD borderx, bordery;
1509 if (CustomDrawBackground(rp, win, 0, 0, win->Width - 1, win->Height - 1, 0, mhd, IntuitionBase)) return;
1511 if (MENUS_AMIGALOOK(IntuitionBase))
1513 borderx = mhd->scr->MenuHBorder / 2;
1514 bordery = mhd->scr->MenuVBorder / 2;
1516 else
1518 borderx = 1;
1519 bordery = 1;
1522 /* White background */
1524 if (MENUS_AMIGALOOK(IntuitionBase))
1526 SetABPenDrMd(rp, mhd->dri->dri_Pens[BARBLOCKPEN], 0, JAM1);
1528 else
1530 SetABPenDrMd(rp, mhd->dri->dri_Pens[BACKGROUNDPEN], 0, JAM1);
1533 RectFill(rp, borderx,
1534 bordery,
1535 win->Width - 1 - borderx,
1536 win->Height - 1 - bordery);
1538 /* Black border frame */
1540 if (MENUS_AMIGALOOK(IntuitionBase))
1542 SetAPen(rp, mhd->dri->dri_Pens[BARDETAILPEN]);
1543 RectFill(rp, 0, 0, win->Width - 1, bordery - 1);
1544 RectFill(rp, 0, bordery, borderx - 1, win->Height - 1 - bordery);
1545 RectFill(rp, win->Width - borderx, bordery, win->Width - 1, win->Height - 1);
1546 RectFill(rp, 0, win->Height - bordery, win->Width - 1 - borderx, win->Height - 1);
1548 else
1550 RenderFrame(rp, 0, 0, win->Width - 1, win->Height - 1, IDS_NORMAL, mhd, IntuitionBase);
1554 /**************************************************************************************************/
1556 static void RenderCheckMark(struct MenuItem *item, WORD itemtype, struct MenuHandlerData *mhd,
1557 struct IntuitionBase *IntuitionBase)
1559 struct GfxBase *GfxBase = GetPrivIBase(IntuitionBase)->GfxBase;
1560 struct Window *win = ((itemtype == ITEM_ITEM) ? mhd->menuwin : mhd->submenuwin);
1561 struct RastPort *rp = win->RPort;
1562 struct Rectangle *box = ((itemtype == ITEM_ITEM) ? ((struct Rectangle *)&mhd->activemenu->JazzX) : &mhd->submenubox);
1563 WORD offx = -box->MinX + mhd->menuinnerleft;
1564 WORD offy = -box->MinY + mhd->menuinnertop;
1565 WORD state = ((item->Flags & HIGHITEM) &&
1566 ((item->Flags & HIGHFLAGS) == HIGHCOMP)) ? IDS_SELECTED : IDS_NORMAL;
1568 if (item->Flags & CHECKIT)
1570 WORD x1, y1, x2, y2;
1572 x1 = item->LeftEdge + offx;
1573 y1 = item->TopEdge + offy + (item->Height - mhd->checkmark->Height) / 2;
1574 x2 = x1 + mhd->checkmark->Width - 1;
1575 y2 = y1 + mhd->checkmark->Height - 1;
1577 SetDrMd(rp, JAM1);
1579 if (item->Flags & CHECKED)
1581 DrawImageState(rp, mhd->checkmark, x1, y1, state, mhd->dri);
1583 else
1585 if (MENUS_AMIGALOOK(IntuitionBase))
1587 SetAPen(rp, mhd->dri->dri_Pens[BARBLOCKPEN]);
1589 else
1591 SetAPen(rp, mhd->dri->dri_Pens[(state == IDS_SELECTED) ? FILLPEN : BACKGROUNDPEN]);
1594 if (!CustomDrawBackground(rp, win, x1, y1, x2 - x1 + 1, y2 - y1 + 1, item->Flags, mhd, IntuitionBase)) RectFill(rp, x1, y1, x2, y2);
1600 /**************************************************************************************************/
1602 static void RenderAmigaKey(struct MenuItem *item, WORD itemtype, struct MenuHandlerData *mhd,
1603 struct IntuitionBase *IntuitionBase)
1605 struct GfxBase *GfxBase = GetPrivIBase(IntuitionBase)->GfxBase;
1606 struct Window *win = ((itemtype == ITEM_ITEM) ? mhd->menuwin : mhd->submenuwin);
1607 struct RastPort *rp = win->RPort;
1608 struct Rectangle *box = ((itemtype == ITEM_ITEM) ? ((struct Rectangle *)&mhd->activemenu->JazzX) : &mhd->submenubox);
1609 WORD commkeywidth = ((itemtype == ITEM_ITEM) ? mhd->maxcommkeywidth_menu : mhd->maxcommkeywidth_submenu);
1610 WORD offx = -box->MinX + mhd->menuinnerleft;
1611 WORD offy = -box->MinY + mhd->menuinnertop;
1612 WORD state = ((item->Flags & HIGHITEM) &&
1613 ((item->Flags & HIGHFLAGS) == HIGHCOMP)) ? IDS_SELECTED : IDS_NORMAL;
1615 if (item->Flags & COMMSEQ)
1617 struct TextFont *oldfont = rp->Font;
1618 struct TextFont *newfont = NULL;
1620 WORD x1, y1;
1622 if (item->Flags & ITEMTEXT)
1624 struct IntuiText *it = (struct IntuiText *)item->ItemFill;
1626 if (it->ITextFont)
1628 if ((newfont = OpenFont(it->ITextFont)))
1630 SetFont(rp, newfont);
1635 x1 = item->LeftEdge + offx + item->Width - AMIGAKEY_BORDER_SPACING -
1636 mhd->amigakey->Width - AMIGAKEY_KEY_SPACING - commkeywidth;
1637 y1 = item->TopEdge + offy + (item->Height - mhd->amigakey->Height + 1) / 2;
1639 SetDrMd(rp, JAM1);
1641 DrawImageState(rp, mhd->amigakey, x1, y1, state, mhd->dri);
1643 x1 += mhd->amigakey->Width + AMIGAKEY_KEY_SPACING;
1645 if (MENUS_AMIGALOOK(IntuitionBase))
1647 SetAPen(rp, mhd->dri->dri_Pens[BARDETAILPEN]);
1649 else
1651 SetAPen(rp, mhd->dri->dri_Pens[(item->Flags & HIGHITEM) ? FILLTEXTPEN : TEXTPEN]);
1654 Move(rp, x1, item->TopEdge + offy + (item->Height - rp->TxHeight) / 2 +
1655 rp->TxBaseline);
1656 Text(rp, &item->Command, 1);
1658 if (newfont)
1660 CloseFont(newfont);
1661 SetFont(rp, oldfont);
1664 } /* if (item->Flags & COMMSEQ) */
1667 /**************************************************************************************************/
1669 static void RenderDisabledPattern(struct RastPort *rp, WORD x1, WORD y1, WORD x2, WORD y2,
1670 struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase)
1672 struct GfxBase *GfxBase = GetPrivIBase(IntuitionBase)->GfxBase;
1673 static CONST UWORD pattern [] = {0x8888, 0x2222};
1675 SetDrMd(rp, JAM1);
1677 if (MENUS_AMIGALOOK(IntuitionBase))
1679 SetAPen(rp, mhd->dri->dri_Pens[BARBLOCKPEN]);
1681 else
1683 SetAPen(rp, mhd->dri->dri_Pens[BACKGROUNDPEN]);
1686 SetAfPt(rp, pattern, 1);
1688 RectFill(rp, x1, y1, x2, y2);
1690 SetAfPt(rp, NULL, 0);
1694 /**************************************************************************************************/
1696 static void RenderFrame(struct RastPort *rp, WORD x1, WORD y1, WORD x2, WORD y2, WORD state,
1697 struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase)
1699 struct GfxBase *GfxBase = GetPrivIBase(IntuitionBase)->GfxBase;
1701 SetAPen(rp, mhd->dri->dri_Pens[(state == IDS_SELECTED) ? SHADOWPEN : SHINEPEN]);
1703 RectFill(rp, x1, y1, x2, y1);
1704 RectFill(rp, x1, y1 + 1, x1, y2);
1706 SetAPen(rp, mhd->dri->dri_Pens[(state == IDS_SELECTED) ? SHINEPEN : SHADOWPEN]);
1707 RectFill(rp, x2, y1 + 1, x2, y2);
1708 RectFill(rp, x1 + 1, y2, x2 - 1, y2);
1710 /**************************************************************************************************/
1712 static void HighlightItem(struct MenuItem *item, WORD itemtype, struct MenuHandlerData *mhd,
1713 struct IntuitionBase *IntuitionBase)
1715 struct GfxBase *GfxBase = GetPrivIBase(IntuitionBase)->GfxBase;
1716 struct Window *win = ((itemtype == ITEM_ITEM) ? mhd->menuwin : mhd->submenuwin);
1717 struct RastPort *rp = win->RPort;
1718 struct Rectangle *box = ((itemtype == ITEM_ITEM) ? ((struct Rectangle *)&mhd->activemenu->JazzX) : &mhd->submenubox);
1719 APTR fill;
1720 WORD offx = -box->MinX + mhd->menuinnerleft;
1721 WORD offy = -box->MinY + mhd->menuinnertop;
1722 WORD x1, y1, x2, y2;
1723 BOOL enabled;
1725 enabled = (item->Flags & ITEMENABLED) ? TRUE : FALSE;
1726 if (!(mhd->activemenu->Flags & MENUENABLED)) enabled = FALSE;
1727 if ((itemtype == ITEM_SUBITEM) && !(mhd->activeitem->Flags & ITEMENABLED)) enabled = FALSE;
1729 if (enabled)
1731 item->Flags ^= HIGHITEM;
1733 fill = item->ItemFill;
1734 if ((item->Flags & HIGHITEM) && (item->SelectFill)) fill = item->SelectFill;
1736 x1 = offx + item->LeftEdge;
1737 y1 = offy + item->TopEdge;
1738 x2 = x1 + item->Width - 1;
1739 y2 = y1 + item->Height - 1;
1741 if (CustomDrawBackground(rp, win, x1, y1, x2 - x1 + 1, y2 - y1 + 1, item->Flags, mhd, IntuitionBase)) {
1742 SetDrMd(rp, JAM1);
1744 if(item->Flags & ITEMTEXT)
1746 struct IntuiText *save = ((struct IntuiText*) fill)->NextText;
1748 if (item->SubItem)
1750 Forbid();
1751 ((struct IntuiText*) fill)->NextText = NULL;
1754 if (MENUS_AMIGALOOK(IntuitionBase))
1756 PrintIText(rp, (struct IntuiText *)fill, x1, y1);
1758 else
1760 struct IntuiText *it = (struct IntuiText *)fill;
1762 it->FrontPen = mhd->dri->dri_Pens[TEXTPEN];
1763 it->DrawMode = JAM1;
1765 PrintIText(rp, it, x1, y1);
1767 if (item->SubItem)
1769 DrawImageState(rp, mhd->submenuimage, offx + item->Width - mhd->submenuimage->Width, offy + item->TopEdge + ((item->Height - mhd->submenuimage->Height) >> 1), IDS_NORMAL, mhd->dri);
1770 ((struct IntuiText*) fill)->NextText = save;
1771 Permit();
1774 else
1776 EraseImage(rp, (struct Image *)fill, x1, y1);
1777 DrawImageState(rp, (struct Image *)fill, x1, y1, IDS_SELECTED, mhd->dri);
1779 RenderItem(item, itemtype, box, mhd, IntuitionBase);
1780 return;
1783 switch(item->Flags & HIGHFLAGS)
1785 case HIGHIMAGE:
1786 SetDrMd(rp, JAM1);
1788 if(item->Flags & ITEMTEXT)
1790 struct IntuiText *save = ((struct IntuiText*) fill)->NextText;
1792 if (item->SubItem)
1794 Forbid();
1795 ((struct IntuiText*) fill)->NextText = NULL;
1797 if (MENUS_AMIGALOOK(IntuitionBase))
1799 PrintIText(rp, (struct IntuiText *)fill, x1, y1);
1801 else
1803 struct IntuiText *it = (struct IntuiText *)fill;
1805 it->FrontPen = mhd->dri->dri_Pens[TEXTPEN];
1806 it->DrawMode = JAM1;
1808 PrintIText(rp, it, x1, y1);
1810 if (item->SubItem)
1812 DrawImageState(rp, mhd->submenuimage, offx + item->Width - mhd->submenuimage->Width, offy + item->TopEdge + ((item->Height - mhd->submenuimage->Height) >> 1), IDS_NORMAL, mhd->dri);
1813 ((struct IntuiText*) fill)->NextText = save;
1814 Permit();
1817 else
1819 EraseImage(rp, (struct Image *)fill, x1, y1);
1820 DrawImageState(rp, (struct Image *)fill, x1, y1, IDS_SELECTED, mhd->dri);
1822 break;
1824 case HIGHCOMP:
1825 if (MENUS_AMIGALOOK(IntuitionBase))
1827 SetDrMd(rp, COMPLEMENT);
1828 RectFill(rp, x1, y1, x2, y2);
1830 else
1832 WORD state = (item->Flags & HIGHITEM) ? IDS_SELECTED : IDS_NORMAL;
1834 SetDrMd(rp, JAM1);
1835 SetAPen(rp, mhd->dri->dri_Pens[(state == IDS_SELECTED) ? FILLPEN : BACKGROUNDPEN]);
1836 RectFill(rp, x1, y1, x2, y2);
1838 RenderItem(item, itemtype, box, mhd, IntuitionBase);
1840 if (state == IDS_SELECTED)
1842 RenderFrame(rp, x1, y1, x2, y2, state, mhd, IntuitionBase);
1845 break;
1847 case HIGHBOX:
1848 SetDrMd(rp, COMPLEMENT);
1849 offx = mhd->scr->MenuHBorder;
1850 offy = mhd->scr->MenuVBorder;
1852 x1 -= offx;
1853 x2 += offx;
1854 y1 -= offy;
1855 y2 += offy;
1857 RectFill(rp, x1, y1, x2, y1 + offy - 1);
1858 RectFill(rp, x2 - offx + 1, y1 + offy, x2, y2);
1859 RectFill(rp, x1, y2 - offy + 1, x2 - offx, y2);
1860 RectFill(rp, x1, y1 + offy, x1 + offx - 1,y2 - offy);
1861 break;
1863 case HIGHNONE:
1864 /* Do nothing */
1865 break;
1867 } /* switch(item->Flags & HIGHFLAGS) */
1869 } /* if (enabled) */
1873 /**************************************************************************************************/
1875 static WORD CalcMaxCommKeyWidth(struct Window *win, struct MenuHandlerData *mhd,
1876 struct IntuitionBase *IntuitionBase)
1878 struct GfxBase *GfxBase = GetPrivIBase(IntuitionBase)->GfxBase;
1879 struct TextExtent te;
1880 WORD maxwidth;
1882 FontExtent(mhd->dri->dri_Font, &te);
1883 maxwidth = te.te_Width;
1885 if (win)
1887 struct MenuItem *item;
1889 if ((win == mhd->menuwin))
1891 item = mhd->activemenu->FirstItem;
1893 else
1895 item = mhd->activeitem->SubItem;
1898 for(; item; item = item->NextItem)
1900 if (item->Flags & ITEMTEXT)
1902 struct IntuiText *it = (struct IntuiText *)item->ItemFill;
1904 if (it->ITextFont)
1906 struct TextFont *font;
1908 if ((font = OpenFont(it->ITextFont)))
1910 FontExtent(font, &te);
1911 if (te.te_Width > maxwidth) maxwidth = te.te_Width;
1913 CloseFont(font);
1917 } /* if (item->Flags & ITEMTEXT) */
1919 } /* for(; item; item = item->NextItem); */
1921 } /* if (win) */
1923 return maxwidth;
1926 /**************************************************************************************************/
1928 static void AddToSelection(struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase)
1930 if ((mhd->activemenunum != -1) && (mhd->activemenu->Flags & MENUENABLED) &&
1931 (mhd->activeitemnum != -1) && (mhd->activeitem->Flags & ITEMENABLED))
1933 struct MenuItem *item = NULL;
1934 UWORD men = FULLMENUNUM(mhd->activemenunum, mhd->activeitemnum, mhd->activesubitemnum);
1936 if (mhd->activesubitemnum != -1)
1938 if (mhd->activesubitem->Flags & ITEMENABLED) item = mhd->activesubitem;
1940 else if (!mhd->activeitem->SubItem)
1942 item = mhd->activeitem;
1945 if (item && (ItemAddress(mhd->menu, men) == item))
1947 UWORD men = FULLMENUNUM(mhd->activemenunum, mhd->activeitemnum, mhd->activesubitemnum);
1949 if (mhd->firstmenupick == MENUNULL)
1951 mhd->firstmenupick = men;
1953 else if (men != mhd->lastmenupick)
1955 struct MenuItem *checkitem, *prevcheckitem = NULL;
1956 UWORD checkmen = mhd->firstmenupick;
1958 /* Remove men from pick queue, if it was already in there
1959 and then add it at the end of the pick queue */
1961 while(checkmen != MENUNULL)
1963 checkitem = ItemAddress(mhd->menu, checkmen);
1965 if (checkmen == men)
1967 if (prevcheckitem == NULL)
1969 mhd->firstmenupick = checkitem->NextSelect;
1971 else
1973 prevcheckitem->NextSelect = checkitem->NextSelect;
1977 checkmen = checkitem->NextSelect;
1978 prevcheckitem = checkitem;
1980 } /* while(checkmen != MENUNULL) */
1982 checkitem->NextSelect = men;
1984 } /* else if (men != mhd->lastmenupick) */
1986 mhd->lastmenupick = men;
1987 item->NextSelect = MENUNULL;
1989 } /* if (item) */
1991 } /* if ((mhd->activemenunum != -1) && (mhd->activeitemnum != -1)) */