Update to lasso handling. Adjust scroll amount based on difference between mouse...
[AROS.git] / rom / intuition / menutask_morphos.c
blob9bbf793e4fd98f8d671fa55855b6ea5918f9de39
1 /*
2 Copyright © 1995-2003, 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 "inputhandler.h"
26 #include "intuition_intern.h"
27 #include "intuition_customize.h"
28 #include "menus.h"
29 #include "menutask.h"
30 #include "smallmenu.h"
31 #include "smallmenu_menusupport.h"
32 #include "smallmenu_render.h"
33 #include "intuition_customizesupport.h"
34 #include "mosmisc.h"
36 #include <cybergraphx/cybergraphics.h>
38 #undef DEBUG
39 #define DEBUG 0
40 #include <aros/debug.h>
42 extern ULONG HookEntry();
44 #define DEBUG_CLICK(x) ;
45 #define DEBUG_ADDTO(x) ;
47 #define CLOCKTICKS 1
49 /**************************************************************************************************/
51 /* this #defines are taken from workbench/libs/gadtools/menus.c!! */
53 #define TEXT_AMIGAKEY_SPACING 6
55 #define ITEXT_EXTRA_LEFT 2
56 #define ITEXT_EXTRA_RIGHT 2
57 #define ITEXT_EXTRA_TOP 1
58 #define ITEXT_EXTRA_BOTTOM 1
60 //static const char *subitemindicator = "»";
62 /**************************************************************************************************/
64 void HandleMouseMove(struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase);
65 void HandleMouseClick(struct InputEvent *ie, struct MenuHandlerData *mhd,
66 struct IntuitionBase *IntuitionBase);
68 /**************************************************************************************************/
70 /******************************
71 ** CreateMenuHandlerTask() **
72 ******************************/
73 struct Task *CreateMenuHandlerTask(APTR taskparams, struct IntuitionBase *IntuitionBase)
75 struct Task *task;
76 APTR stack;
78 task = AllocMem(sizeof (struct Task), MEMF_PUBLIC|MEMF_CLEAR);
79 if (task)
81 stack = AllocMem(MENUTASK_STACKSIZE, MEMF_PUBLIC);
82 if (stack)
84 NEWLIST(&task->tc_MemEntry);
85 task->tc_Node.ln_Type = NT_TASK;
86 task->tc_Node.ln_Name = MENUTASK_NAME;
87 task->tc_Node.ln_Pri = MENUTASK_PRIORITY;
89 task->tc_SPLower=stack;
90 task->tc_SPUpper=(BYTE *)stack + MENUTASK_STACKSIZE;
92 #ifdef __MORPHOS__
93 task->tc_SPReg = task->tc_SPUpper;
96 struct TaskInitExtension taskext;
97 struct TagItem tags[4];
99 taskext.Trap = TRAP_PPCTASK;
100 taskext.Extension = 0;
101 taskext.Tags = tags;
103 tags[0].ti_Tag = TASKTAG_CODETYPE;
104 tags[0].ti_Data = CODETYPE_PPC;
105 tags[1].ti_Tag = TASKTAG_PC;
106 tags[1].ti_Data = (ULONG)DefaultMenuHandler;
107 tags[2].ti_Tag = TASKTAG_PPC_ARG1;
108 tags[2].ti_Data = (ULONG)taskparams;
109 tags[3].ti_Tag = TAG_END;
111 if(AddTask(task, (APTR)&taskext, NULL) != NULL)
113 /* Everything went OK */
114 return (task);
117 #else
119 #if AROS_STACK_GROWS_DOWNWARDS
120 task->tc_SPReg = (BYTE *)task->tc_SPUpper-SP_OFFSET - sizeof(APTR);
121 ((APTR *)task->tc_SPUpper)[-1] = taskparams;
122 #else
123 task->tc_SPReg=(BYTE *)task->tc_SPLower-SP_OFFSET + sizeof(APTR);
124 *(APTR *)task->tc_SPLower = taskparams;
125 #endif
127 if(AddTask(task, DefaultMenuHandler, NULL) != NULL)
129 /* Everything went OK */
130 return (task);
132 #endif
133 FreeMem(stack, MENUTASK_STACKSIZE);
135 } /* if(stack != NULL) */
136 FreeMem(task,sizeof(struct Task));
138 } /* if (task) */
139 return (NULL);
143 #undef DefaultMenuHandler
146 /**************************************************************************************************/
148 /***************************
149 ** DefaultMenuHandler() **
150 ***************************/
151 void DefaultMenuHandler(struct MenuTaskParams *taskparams)
153 struct IntuitionBase *IntuitionBase = taskparams->intuitionBase;
155 struct MenuHandlerData *mhd = NULL;
156 UBYTE *mem;
157 struct MsgPort *port = NULL;
158 struct MsgPort TimerPort;
159 struct timerequest *timerio = NULL;
160 ULONG mpmask = 0, timermask = 0;
162 BOOL success = FALSE;
163 BOOL timeron = FALSE;
165 if ((mem = AllocMem(sizeof(struct MsgPort) +
166 sizeof(struct MenuHandlerData), MEMF_PUBLIC | MEMF_CLEAR)))
168 port = (struct MsgPort *)mem;
170 port->mp_SigBit = AllocSignal(-1);
171 if (port->mp_SigBit != (UBYTE) -1)
173 port->mp_Node.ln_Type = NT_MSGPORT;
174 port->mp_Flags = PA_SIGNAL;
175 port->mp_SigTask = FindTask(NULL);
176 NEWLIST(&port->mp_MsgList);
178 mpmask = 1L << port->mp_SigBit;
180 mhd = (struct MenuHandlerData *)(mem + sizeof(struct MsgPort));
182 success = TRUE;
185 } /* if ((mem = AllocMem(sizeof(struct MsgPort), MEMF_PUBLIC | MEMF_CLEAR))) */
187 if (success)
189 taskparams->MenuHandlerPort = port;
190 taskparams->success = TRUE;
193 Signal(taskparams->Caller, SIGF_INTUITION);
195 if (!success)
197 D(bug("DefaultMenuHandler: initialization failed. waiting for parent task to kill me.\n"));
199 if (mem)
201 FreeMem(mem, sizeof(struct MsgPort) + sizeof(struct MenuHandlerData));
204 Wait(0);
207 D(bug("DefaultMenuHandler: initialization ok. Now waiting for messages from Intuition.\n"));
209 for(;;)
211 ULONG sigs;
212 struct MenuMessage *msg;
214 sigs = Wait(mpmask | timermask);
216 D(bug("DefaultMenuHandler: got sigmask 0x%lx (timermask %lx)\n",sigs,timermask));
218 if (sigs & mpmask)
219 while((msg = GetMenuMessage(port, IntuitionBase)))
221 switch(msg->code)
223 case MMCODE_START:
225 #ifdef USEWINDOWLOCK
226 // let's prevent other windows from opening while menus are on
227 ObtainSemaphore(&GetPrivIBase(IntuitionBase)->WindowLock);
228 mhd->windowlock = TRUE;
229 #endif
231 mhd->win = msg->win;
232 mhd->scr = mhd->win->WScreen;
233 mhd->dri = (struct IntDrawInfo *)GetScreenDrawInfo(mhd->scr);
235 mhd->menu = msg->win->MenuStrip;
237 /* lend menus */
238 if (((struct IntWindow *)msg->win)->menulendwindow)
240 mhd->menu = ((struct IntWindow *)msg->win)->menulendwindow->MenuStrip;
243 mhd->scrmousex = mhd->scr->MouseX;
244 mhd->scrmousey = mhd->scr->MouseY;
245 mhd->firstmenupick = MENUNULL;
246 mhd->keepmenuup = TRUE;
248 mhd->backfillhook.h_Entry = (HOOKFUNC)HookEntry;
249 mhd->backfillhook.h_SubEntry = (HOOKFUNC)CustomizeBackfillFunc;
250 mhd->backfillhook.h_Data = &mhd->hookdata;
251 mhd->hookdata.intuitionBase = IntuitionBase;
252 mhd->isundermouse = FALSE;
254 mhd->openseconds = msg->ie.ie_TimeStamp.tv_secs;
255 mhd->openmicros = msg->ie.ie_TimeStamp.tv_micro;
257 mhd->delayedopen = 0;
260 if ((GetPrivIBase(IntuitionBase)->IControlPrefs.ic_Flags & ICF_MENUUNDERMOUSE) || ((GetPrivIBase(IntuitionBase)->IControlPrefs.ic_Flags & ICF_MENUMOUSEPOS) && (mhd->scr->MouseY >= mhd->scr->BarHeight) ))
261 mhd->isundermouse = TRUE;
264 /* close windows in the back first because
265 this is faster */
266 MakeMenuBarWin(mhd, IntuitionBase);
267 HandleMouseMove(mhd, IntuitionBase);
269 mhd->active = TRUE;
270 break;
272 case MMCODE_EVENT:
273 /* there might come additional messages from Intuition
274 even when we have already told it to make the menus
275 inactive, but since everything is async, this cannot
276 be avoided, so check if we are really active */
278 if (mhd->active)
280 switch(msg->ie.ie_Class)
282 case IECLASS_RAWMOUSE:
283 if (msg->ie.ie_Code == IECODE_NOBUTTON)
285 HandleMouseMove(mhd, IntuitionBase);
287 else
289 HandleMouseClick(&msg->ie, mhd, IntuitionBase);
291 break;
292 case IECLASS_RAWKEY:
293 HandleRawKey(&msg->ie,mhd,IntuitionBase);
294 break;
296 /* case IECLASS_TIMER:
297 if (mhd->delayedopen)
299 UQUAD currenttime,delaytime;
301 currenttime = ((UQUAD)msg->ie.ie_TimeStamp.tv_secs) * 50;
302 currenttime += msg->ie.ie_TimeStamp.tv_micro / 20000;
304 delaytime = ((UQUAD)mhd->delayedopenseconds) * 50;
305 delaytime += mhd->delayedopenmicros / 20000;
307 if (currenttime >= delaytime + 10)
309 CreateMenuWindow(mhd->delayedopen,mhd->scr,(struct MsgPort *)-1,CalcSubWindowXPos(mhd->delayedopen->parent,IntuitionBase),CalcSubWindowYPos(mhd->delayedopen->parent,IntuitionBase),FALSE,IntuitionBase);
310 mhd->delayedopen = 0;
314 break; */
316 #ifdef __MORPHOS__
317 case IECLASS_NEWTIMER:
318 if (mhd->delayedopen)
320 if (WindowsReplied(mhd->scr,IntuitionBase))
322 CreateMenuWindow(mhd->delayedopen,mhd->scr,(struct MsgPort *)-1,CalcSubWindowXPos(mhd->delayedopen->parent,IntuitionBase),CalcSubWindowYPos(mhd->delayedopen->parent,IntuitionBase),FALSE,IntuitionBase);
323 mhd->delayedopen = 0;
326 break;
327 #endif /* __MORPHOS__ */
330 } /* if (mhd->active) */
331 break;
333 case MMCODE_STARTCLOCK:
334 if (!timeron && (GetPrivIBase(IntuitionBase)->IControlPrefs.ic_Flags & ICF_SCREENBARCLOCK))
336 TimerPort.mp_Node.ln_Type = NT_MSGPORT;
337 TimerPort.mp_Flags = PA_SIGNAL;
338 TimerPort.mp_SigBit = AllocSignal(-1);
339 TimerPort.mp_SigTask = FindTask(0);
340 NEWLIST(&TimerPort.mp_MsgList);
342 timermask = 1L << TimerPort.mp_SigBit;
344 if ((timerio = CreateIORequest(&TimerPort,sizeof(struct timerequest))))
347 if (!OpenDevice("timer.device",UNIT_VBLANK,(struct IORequest *)timerio,0))
349 timerio->tr_node.io_Command = TR_ADDREQUEST;
350 timerio->tr_time.tv_secs = 0; // let's start to tick ;)
351 timerio->tr_time.tv_micro = 1;
352 SendIO((struct IORequest *)timerio);
353 timeron = TRUE;
355 else
357 DeleteIORequest(timerio);
361 if (!timeron) FreeSignal(TimerPort.mp_SigBit);
362 } else if (timeron)
364 WaitIO((struct IORequest *)timerio);
365 timerio->tr_node.io_Command = TR_ADDREQUEST;
366 timerio->tr_time.tv_secs = CLOCKTICKS;
367 timerio->tr_time.tv_micro = 0;
369 D(bug("DefaultMenuHandler: starting new SendIO()\n"));
371 //jDc: tick only when user wants us to tick
372 if (GetPrivIBase(IntuitionBase)->IControlPrefs.ic_Flags & ICF_SCREENBARCLOCK)
373 SendIO((struct IORequest *)timerio);
375 break;
377 } /* switch(msg->code) */
379 ReplyMenuMessage(msg, IntuitionBase);
381 } /* while((msg = (struct MenuMessage *)GetMsg(port))) */
383 D(bug("DefaultMenuHandler: Checking timermask\n"));
385 if (sigs & timermask && timeron)
387 D(bug("DefaultMenuHandler: WaitIO()\n"));
389 WaitIO((struct IORequest *)timerio);
391 timerio->tr_node.io_Command = TR_ADDREQUEST;
392 timerio->tr_time.tv_secs = CLOCKTICKS;
393 timerio->tr_time.tv_micro = 0;
395 D(bug("DefaultMenuHandler: starting new SendIO()\n"));
397 //jDc: tick only when user wants us to tick
398 if (GetPrivIBase(IntuitionBase)->IControlPrefs.ic_Flags & ICF_SCREENBARCLOCK)
399 SendIO((struct IORequest *)timerio);
401 D(bug("DefaultMenuHandler: Rendering ScreenBar clock\n"));
403 if (IntuitionBase->FirstScreen) //there are some opened screens
404 RenderScreenBarClock(NULL,IntuitionBase);
407 D(bug("DefaultMenuHandler: Restarting loop.\n"));
409 } /* for(;;) */
412 /**************************************************************************************************/
414 /*******************************
415 ** InitDefaultMenuHandler() **
416 *******************************/
417 BOOL InitDefaultMenuHandler(struct IntuitionBase *IntuitionBase)
419 struct MenuTaskParams params;
420 struct Task *task;
421 BOOL result = FALSE;
423 params.intuitionBase = IntuitionBase;
424 params.Caller = FindTask(NULL);
425 params.success = FALSE;
427 SetSignal(0, SIGF_INTUITION);
429 if ((task = CreateMenuHandlerTask(&params, IntuitionBase)))
431 Wait(SIGF_INTUITION);
433 if (params.success)
435 result = TRUE;
436 GetPrivIBase(IntuitionBase)->MenuHandlerPort = params.MenuHandlerPort;
438 else
440 RemTask(task);
443 } /* if ((task = CreateMenuHandlerTask(&params, IntuitionBase))) */
445 return result;
448 /**************************************************************************************************/
450 void HandleMouseMove(struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase)
452 struct Layer *lay = 0;
453 struct Window *win = NULL;
454 struct SmallMenuEntry *sel = 0;
456 mhd->scrmousex = mhd->scr->MouseX;
457 mhd->scrmousey = mhd->scr->MouseY;
459 LockLayerInfo(&mhd->scr->LayerInfo);
460 lay = WhichLayer(&mhd->scr->LayerInfo, mhd->scrmousex, mhd->scrmousey);
461 UnlockLayerInfo(&mhd->scr->LayerInfo);
463 if (lay)
465 win = (struct Window *)lay->Window;
467 if (win)
469 sel = FindEntryWindow(win,mhd->entries,IntuitionBase);
470 if (sel)
472 struct SmallMenuEntry *work;
474 work = sel->parent ? sel->parent->submenu : mhd->entries;
476 for (; work; work = work->next)
478 if ((work != sel) && (work->flags & SMF_SELECTED))
480 work->flags &= ~SMF_SELECTED;
481 RenderItem(work->smk->window->RPort,work,REALX(work),REALY(work),IntuitionBase);
482 if (work->submenu) CloseMenuWindow(work->submenu,IntuitionBase);
483 mhd->delayedopen = 0;
487 if (!(sel->flags & SMF_NOTSELECTABLE))
489 sel->flags |= SMF_SELECTED;
490 RenderItem(sel->smk->window->RPort,sel,REALX(sel),REALY(sel),IntuitionBase);
492 if ((sel->smk->flags & SMK_NEEDSDELAY) && sel->submenu)
494 if (sel->submenu != mhd->delayedopen)
496 mhd->delayedopenseconds = IntuitionBase->Seconds;
497 mhd->delayedopenmicros = IntuitionBase->Micros;
498 mhd->delayedopen = sel->submenu;
500 } else {
501 if (sel->submenu) CreateMenuWindow(sel->submenu,mhd->scr,(struct MsgPort *)-1,CalcSubWindowXPos(sel->submenu->parent,IntuitionBase),CalcSubWindowYPos(sel->submenu->parent,IntuitionBase),FALSE,IntuitionBase);
508 if (!win || !sel)
510 sel = FindLastEntry(mhd->entries,IntuitionBase);
511 if (sel && !sel->submenu)
513 sel->flags &= ~SMF_SELECTED;
514 RenderItem(sel->smk->window->RPort,sel,REALX(sel),REALY(sel),IntuitionBase);
519 /**************************************************************************************************/
521 #define STICKY (GetPrivIBase(IntuitionBase)->IControlPrefs.ic_Flags & ICF_STICKYMENUS)
522 #define DELAYEDSTICKY (GetPrivIBase(IntuitionBase)->IControlPrefs.ic_Flags & ICF_STICKYDELAY)
523 #define DELAYVALID (DoubleClick(mhd->openseconds,mhd->openmicros,ie->ie_TimeStamp.tv_secs,ie->ie_TimeStamp.tv_micro))
525 void HandleMouseClick(struct InputEvent *ie, struct MenuHandlerData *mhd,
526 struct IntuitionBase *IntuitionBase)
528 BOOL die = TRUE;
530 switch (ie->ie_Code)
532 case MENUUP:
533 case SELECTDOWN:
535 struct Layer *lay;
537 LockLayerInfo(&mhd->scr->LayerInfo);
538 lay = WhichLayer(&mhd->scr->LayerInfo, mhd->scrmousex, mhd->scrmousey);
539 UnlockLayerInfo(&mhd->scr->LayerInfo);
541 if (lay)
543 struct Window *win = (struct Window *)lay->Window;
545 if (win)
547 struct SmallMenuEntry *sel = FindEntryWindow(win,mhd->entries,IntuitionBase);
548 if (sel)
550 if (sel->submenu || (sel->flags & SMF_NOTSELECTABLE) || !sel->parent)
552 if (STICKY) die = FALSE;
553 if (DELAYEDSTICKY && DELAYVALID) die = TRUE;
554 mhd->keepmenuup = FALSE;
555 break;
558 DEBUG_CLICK(dprintf("HandleMouseClick: AddToSelection\n"));
560 if (sel->flags & SMF_CHECKMARK)
562 HandleCheckItem(mhd,sel,IntuitionBase);
565 AddToSelection(mhd,sel,IntuitionBase);
568 #ifdef NOCBMPATENTS
569 if ((ie->ie_Code == SELECTDOWN) && (ie->ie_Qualifier & IEQUALIFIER_RBUTTON))
571 die = FALSE;
573 #endif
575 break;
579 if (mhd->keepmenuup && STICKY) die = FALSE;
580 if (DELAYEDSTICKY && DELAYVALID) die = TRUE;
581 mhd->keepmenuup = FALSE;
583 break;
585 default:
586 if (mhd->keepmenuup) die = FALSE;
587 mhd->keepmenuup = FALSE;
588 break;
591 if (die)
593 KillMenus(mhd,IntuitionBase);
598 /**************************************************************************************************/
600 BOOL HandleCheckItem(struct MenuHandlerData *mhd, struct SmallMenuEntry *entry,
601 struct IntuitionBase *IntuitionBase)
603 /* Note: If you change something here, you probably must also change
604 menus.c/CheckMenuItemWasClicked() which is used when the
605 user uses the menu key shortcuts! */
607 struct MenuItem *item = (struct MenuItem *)entry->reference;
608 struct SmallMenuEntry *work;
609 BOOL re_render = FALSE;
610 BOOL changed = FALSE;
612 if (item->Flags & MENUTOGGLE)
614 item->Flags ^= CHECKED;
615 entry->flags ^= SMF_CHECKED;
616 re_render = TRUE;
617 changed = TRUE;
619 else
621 if (!(item->Flags & CHECKED))
623 item->Flags |= CHECKED;
624 entry->flags |= SMF_CHECKED;
625 re_render = TRUE;
626 changed = TRUE;
627 } else {
628 if (!(item->MutualExclude))
630 item->Flags &= ~CHECKED;
631 entry->flags &= ~SMF_CHECKED;
632 re_render = TRUE;
633 changed = TRUE;
638 if (re_render)
640 RenderItem(entry->smk->window->RPort,entry,REALX(entry),REALY(entry),IntuitionBase);
643 if (item->MutualExclude)
645 struct MenuItem *checkitem = 0;
646 WORD i,itemnum = entry->referencenumber;
648 work = entry->parent->submenu;
650 for(i = 0; (i < 32) && work; i++, work = work->next)
652 checkitem = work->reference;
653 if ((i != itemnum) && (item->MutualExclude & (1L << i)) &&
654 ((checkitem->Flags & (CHECKED | CHECKIT)) == (CHECKIT | CHECKED)))
656 checkitem->Flags &= ~CHECKED;
657 work->flags &= ~SMF_CHECKED;
658 RenderItem(work->smk->window->RPort,work,REALX(work),REALY(work),IntuitionBase);
662 } /* if (item->MutualExclude) */
664 return changed;
667 /**************************************************************************************************/
669 /**************************************************************************************************/
670 void AddToSelection(struct MenuHandlerData *mhd, struct SmallMenuEntry *entry, struct IntuitionBase *IntuitionBase)
672 ULONG menunum=-1,menuitemnum=-1,submenunum=-1;
673 struct SmallMenuEntry *work;
675 DEBUG_ADDTO(dprintf("AddToSelection: called\n"));
677 if (entry)
679 //check if we're not disabled (checking whole family isn't really necessary, but oh well... ;)
680 for (work = entry; work; work = work->parent)
682 if (work->flags & SMF_DISABLED) return;
686 DEBUG_ADDTO(dprintf("AddToSelection: disable passed ok\n"));
689 Now we need to get the FULLMENUNUM. god, this cbm-crap-menu-API sucks so much!!!
690 too bad this doesn't allow unlimited menu depth :(
693 if (entry->parent->flags & SMF_MENUSTRIP)
695 menuitemnum = entry->referencenumber;
696 menunum = entry->parent->referencenumber;
697 } else {
698 submenunum = entry->referencenumber;
699 menuitemnum = entry->parent->referencenumber;
700 if (entry->parent->parent) //null should never happen here anyway, but.. ;)
702 menunum = entry->parent->parent->referencenumber;
706 DEBUG_ADDTO(dprintf("AddToSelection: menu %ld menuitem %ld submenuitem %ld\n",menunum,menuitemnum,submenunum));
708 if ((menunum != -1) && (menuitemnum != -1))
710 struct MenuItem *item = NULL;
711 UWORD men = FULLMENUNUM(menunum, menuitemnum, submenunum);
713 item = (struct MenuItem *)entry->reference;
715 if (item && (ItemAddress(mhd->menu, men) == item))
717 UWORD men = FULLMENUNUM(menunum, menuitemnum, submenunum);
719 DEBUG_ADDTO(dprintf("AddToSelection: adding item %lx\n",item));
721 if (mhd->firstmenupick == MENUNULL)
723 mhd->firstmenupick = men;
725 else if (men != mhd->lastmenupick)
727 struct MenuItem *checkitem, *prevcheckitem = NULL;
728 UWORD checkmen = mhd->firstmenupick;
730 /* Remove men from pick queue, if it was already in there
731 and then add it at the end of the pick queue */
733 while(checkmen != MENUNULL)
735 checkitem = ItemAddress(mhd->menu, checkmen);
737 if (checkmen == men)
739 if (prevcheckitem == NULL)
741 mhd->firstmenupick = checkitem->NextSelect;
743 else
745 prevcheckitem->NextSelect = checkitem->NextSelect;
749 checkmen = checkitem->NextSelect;
750 prevcheckitem = checkitem;
752 } /* while(checkmen != MENUNULL) */
754 checkitem->NextSelect = men;
756 } /* else if (men != mhd->lastmenupick) */
758 mhd->lastmenupick = men;
759 item->NextSelect = MENUNULL;
761 } /* if (item) */
763 } /* if ((menunum != -1) && (menuitemnum != -1)) */
767 /**************************************************************************************************/