arosc.library: Centralized exit handling code in __arosc_startup.c
[AROS.git] / rom / intuition / menus.c
blob88953f627d3d03ed455f4edb3dc4cc2340d0c904
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/utility.h>
14 #include <clib/macros.h>
15 #include <exec/memory.h>
16 #include <exec/alerts.h>
17 #include <exec/interrupts.h>
18 #include <exec/ports.h>
19 #include <intuition/intuition.h>
20 #include <intuition/intuitionbase.h>
21 #include <intuition/gadgetclass.h>
22 #include <devices/inputevent.h>
23 #include <devices/input.h>
24 #include "inputhandler.h"
26 #include "intuition_intern.h"
27 #include "menus.h"
29 #define DEBUG_FINDMENUSHORTCUT(x) ;
31 /**************************************************************************************************/
33 struct MenuMessage *AllocMenuMessage(struct IntuitionBase *IntuitionBase)
35 struct MenuMessage *msg;
37 msg = AllocVec(sizeof(struct MenuMessage), MEMF_PUBLIC | MEMF_CLEAR);
39 return msg;
42 /**************************************************************************************************/
44 void FreeMenuMessage(struct MenuMessage *msg, struct IntuitionBase *IntuitionBase)
46 if (msg) FreeVec(msg);
50 /**************************************************************************************************/
52 void SendMenuMessage(struct MenuMessage *msg, struct IntuitionBase *IntuitionBase)
54 PutMsg(GetPrivIBase(IntuitionBase)->MenuHandlerPort, &msg->msg);
57 /**************************************************************************************************/
59 struct MenuMessage *GetMenuMessage(struct MsgPort *port, struct IntuitionBase *IntuitionBase)
61 return (struct MenuMessage *)GetMsg(port);
65 /**************************************************************************************************/
67 void ReplyMenuMessage(struct MenuMessage *msg, struct IntuitionBase *IntuitionBase)
69 FreeMenuMessage(msg, IntuitionBase);
72 /**************************************************************************************************/
76 void MH2Int_MakeMenusInactive(struct Window *win, UWORD menupick, struct IntuitionBase *IntuitionBase)
78 struct InputEvent ie;
79 struct IOStdReq ior;
80 struct MsgPort replyport;
82 ie.ie_NextEvent = 0;
83 ie.ie_Class = IECLASS_MENU;
84 ie.ie_SubClass = IESUBCLASS_MENUSTOP;
85 ie.ie_Code = menupick;
86 ie.ie_EventAddress = win;
88 replyport.mp_Node.ln_Type = NT_MSGPORT;
89 replyport.mp_Flags = PA_SIGNAL;
90 replyport.mp_SigBit = SIGB_INTUITION;
91 replyport.mp_SigTask = FindTask(NULL);
92 NEWLIST(&replyport.mp_MsgList);
94 ior = *(GetPrivIBase(IntuitionBase)->InputIO);
95 ior.io_Message.mn_ReplyPort = &replyport;
97 ior.io_Command = IND_WRITEEVENT;
98 ior.io_Data = &ie;
99 ior.io_Length = sizeof(struct InputEvent);
101 DoIO((struct IORequest *)&ior);
104 /**************************************************************************************************/
105 /**************************************************************************************************/
106 /**************************************************************************************************/
108 void GetMenuBox(struct Window *win, struct MenuItem *item,
109 WORD *xmin, WORD *ymin, WORD *xmax, WORD *ymax)
112 WORD left, right, top, bottom;
114 left = top = 0x7fff;
115 right = bottom = -0x7fff;
117 while(item != NULL)
119 left = min(left, item->LeftEdge);
120 top = min(top, item->TopEdge);
121 right = max(right, item->LeftEdge + item->Width - 1);
122 bottom = max(bottom, item->TopEdge + item->Height - 1);
124 item = item->NextItem;
127 if (xmin) *xmin = left - win->WScreen->MenuHBorder;
128 if (ymin) *ymin = top - win->WScreen->MenuVBorder;
129 if (xmax) *xmax = right + win->WScreen->MenuHBorder;
130 if (ymax) *ymax = bottom + win->WScreen->MenuVBorder;
134 /**************************************************************************************************/
136 UWORD FindMenuShortCut(struct Menu *menu, UBYTE key, BOOL do_click_op,
137 struct IntuitionBase *IntuitionBase)
139 struct Library *UtilityBase = GetPrivIBase(IntuitionBase)->UtilityBase;
140 struct MenuItem *item, *sub;
141 UWORD menunum, itemnum = 0, subnum = 0;
142 BOOL found = FALSE;
144 DEBUG_FINDMENUSHORTCUT(dprintf("FindMenuShortCut: Menu 0x%lx key 0x%lx <%c> do_click_op 0x%lx\n",menu,key,key,do_click_op));
146 key = ToUpper(key);
148 DEBUG_FINDMENUSHORTCUT(dprintf("FindMenuShortCut: Upperkey 0x%lx <%c>\n",key));
150 for(menunum = 0; menu; menu = menu->NextMenu, menunum ++)
152 DEBUG_FINDMENUSHORTCUT(dprintf("FindMenuShortCut: Menu 0x%lx Menunum %ld\n",menu,menunum));
154 for(item = menu->FirstItem, itemnum = 0; item; item = item->NextItem, itemnum++)
156 DEBUG_FINDMENUSHORTCUT(dprintf("FindMenuShortCut: Item 0x%lx itemnum %ld\n",item,itemnum));
157 if ((sub = item->SubItem))
159 DEBUG_FINDMENUSHORTCUT(dprintf("FindMenuShortCut: Sub 0x%lx\n",sub));
160 for(subnum = 0; sub; sub = sub->NextItem, subnum++)
162 DEBUG_FINDMENUSHORTCUT(dprintf("FindMenuShortCut: Sub 0x%lx subnum %ld Flags 0x%lx Cmd 0x%lx <%c>\n",sub,subnum,sub->Flags,sub->Command,sub->Command));
163 if ((sub->Flags & COMMSEQ) &&
164 (ToUpper((UBYTE)sub->Command) == key))
166 DEBUG_FINDMENUSHORTCUT(dprintf("FindMenuShortCut: found\n"));
167 if (do_click_op)
169 DEBUG_FINDMENUSHORTCUT(dprintf("FindMenuShortCut: click_op\n"));
170 if (sub->Flags & CHECKIT)
172 DEBUG_FINDMENUSHORTCUT(dprintf("FindMenuShortCut: CheckIt change\n"));
173 CheckMenuItemWasClicked(sub, subnum, item);
175 sub->NextSelect = MENUNULL;
177 found = TRUE;
178 break;
181 if (found) break;
184 else
186 DEBUG_FINDMENUSHORTCUT(dprintf("FindMenuShortCut: Item 0x%lx itemnum %ld Flags 0x%lx Cmd 0x%lx <%c>\n",item,itemnum,item->Flags,item->Command,item->Command));
188 if ((item->Flags & COMMSEQ) &&
189 (ToUpper((UBYTE)item->Command) == key))
191 DEBUG_FINDMENUSHORTCUT(dprintf("FindMenuShortCut: found\n"));
192 if (do_click_op)
194 DEBUG_FINDMENUSHORTCUT(dprintf("FindMenuShortCut: click_op\n"));
195 if (item->Flags & CHECKIT)
197 DEBUG_FINDMENUSHORTCUT(dprintf("FindMenuShortCut: CheckIt change\n"));
198 CheckMenuItemWasClicked(item, itemnum, menu->FirstItem);
200 item->NextSelect = MENUNULL;
202 found = TRUE;
203 subnum = NOSUB;
204 break;
208 } /* for each item */
210 if (found) break;
212 } /* for each menu */
214 return found ? FULLMENUNUM(menunum, itemnum, subnum) : MENUNULL;
217 /**************************************************************************************************/
219 void CheckMenuItemWasClicked(struct MenuItem *item, UWORD itemnum, struct MenuItem *parentitem)
221 /* Note: If you change something here, you probably must also change
222 menutask.c/HandleCheckItem() which is used when the
223 user uses the menus with the mouse! */
225 if (item->Flags & MENUTOGGLE)
227 item->Flags ^= CHECKED;
229 else
231 item->Flags |= CHECKED;
234 if (item->MutualExclude)
236 WORD i;
238 for(i = 0; (i < 32) && parentitem; i++, parentitem = parentitem->NextItem)
240 if ((i != itemnum) && (item->MutualExclude & (1L << i)) &&
241 ((parentitem->Flags & (CHECKED | CHECKIT)) == (CHECKIT | CHECKED)))
243 parentitem->Flags &= ~CHECKED;
247 } /* if (item->MutualExclude) */
251 /**************************************************************************************************/