Belarusian
[AROS.git] / rom / intuition / menus.c
blobdbb724a182edebe08871611e2d9382929b827cd0
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/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 MenuItem *item, *sub;
140 UWORD menunum, itemnum = 0, subnum = 0;
141 BOOL found = FALSE;
143 DEBUG_FINDMENUSHORTCUT(dprintf("FindMenuShortCut: Menu 0x%lx key 0x%lx <%c> do_click_op 0x%lx\n",menu,key,key,do_click_op));
145 key = ToUpper(key);
147 DEBUG_FINDMENUSHORTCUT(dprintf("FindMenuShortCut: Upperkey 0x%lx <%c>\n",key));
149 for(menunum = 0; menu; menu = menu->NextMenu, menunum ++)
151 DEBUG_FINDMENUSHORTCUT(dprintf("FindMenuShortCut: Menu 0x%lx Menunum %ld\n",menu,menunum));
153 for(item = menu->FirstItem, itemnum = 0; item; item = item->NextItem, itemnum++)
155 DEBUG_FINDMENUSHORTCUT(dprintf("FindMenuShortCut: Item 0x%lx itemnum %ld\n",item,itemnum));
156 if ((sub = item->SubItem))
158 DEBUG_FINDMENUSHORTCUT(dprintf("FindMenuShortCut: Sub 0x%lx\n",sub));
159 for(subnum = 0; sub; sub = sub->NextItem, subnum++)
161 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));
162 if ((sub->Flags & COMMSEQ) &&
163 (ToUpper((UBYTE)sub->Command) == key))
165 DEBUG_FINDMENUSHORTCUT(dprintf("FindMenuShortCut: found\n"));
166 if (do_click_op)
168 DEBUG_FINDMENUSHORTCUT(dprintf("FindMenuShortCut: click_op\n"));
169 if (sub->Flags & CHECKIT)
171 DEBUG_FINDMENUSHORTCUT(dprintf("FindMenuShortCut: CheckIt change\n"));
172 CheckMenuItemWasClicked(sub, subnum, item);
174 sub->NextSelect = MENUNULL;
176 found = TRUE;
177 break;
180 if (found) break;
183 else
185 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));
187 if ((item->Flags & COMMSEQ) &&
188 (ToUpper((UBYTE)item->Command) == key))
190 DEBUG_FINDMENUSHORTCUT(dprintf("FindMenuShortCut: found\n"));
191 if (do_click_op)
193 DEBUG_FINDMENUSHORTCUT(dprintf("FindMenuShortCut: click_op\n"));
194 if (item->Flags & CHECKIT)
196 DEBUG_FINDMENUSHORTCUT(dprintf("FindMenuShortCut: CheckIt change\n"));
197 CheckMenuItemWasClicked(item, itemnum, menu->FirstItem);
199 item->NextSelect = MENUNULL;
201 found = TRUE;
202 subnum = NOSUB;
203 break;
207 } /* for each item */
209 if (found) break;
211 } /* for each menu */
213 return found ? FULLMENUNUM(menunum, itemnum, subnum) : MENUNULL;
216 /**************************************************************************************************/
218 void CheckMenuItemWasClicked(struct MenuItem *item, UWORD itemnum, struct MenuItem *parentitem)
220 /* Note: If you change something here, you probably must also change
221 menutask.c/HandleCheckItem() which is used when the
222 user uses the menus with the mouse! */
224 if (item->Flags & MENUTOGGLE)
226 item->Flags ^= CHECKED;
228 else
230 item->Flags |= CHECKED;
233 if (item->MutualExclude)
235 WORD i;
237 for(i = 0; (i < 32) && parentitem; i++, parentitem = parentitem->NextItem)
239 if ((i != itemnum) && (item->MutualExclude & (1L << i)) &&
240 ((parentitem->Flags & (CHECKED | CHECKIT)) == (CHECKIT | CHECKED)))
242 parentitem->Flags &= ~CHECKED;
246 } /* if (item->MutualExclude) */
250 /**************************************************************************************************/