adjust the memheader is necessary when adding blocks to tlsf. alter debug for consist...
[AROS.git] / workbench / system / Workbook / wbapp.c
blobf485b57d04ff80a513728868babd1b5affcbbd0a
1 /*
2 Copyright © 2011, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Workbook Application Class
6 Lang: english
7 */
9 #define DEBUG 0
10 #include <aros/debug.h>
12 #include <string.h>
13 #include <limits.h>
15 #include <proto/dos.h>
16 #include <proto/exec.h>
17 #include <proto/intuition.h>
18 #include <proto/utility.h>
19 #include <proto/gadtools.h>
20 #include <proto/workbench.h>
21 #include <proto/graphics.h>
23 #include <intuition/classusr.h>
24 #include <libraries/gadtools.h>
25 #include <workbench/handler.h>
27 #include "workbook_intern.h"
28 #include "workbook_menu.h"
29 #include "classes.h"
31 struct wbApp {
32 struct MsgPort *WinPort;
33 ULONG WinMask; /* Mask of our port(s) */
34 struct MsgPort *AppPort;
35 ULONG AppMask; /* Mask of our port(s) */
36 Object *Root; /* Background 'root' window */
37 struct MinList Windows; /* Subwindows */
40 static void wbOpenDrawer(Class *cl, Object *obj, CONST_STRPTR path)
42 struct WorkbookBase *wb = (APTR)cl->cl_UserData;
43 struct wbApp *my = INST_DATA(cl, obj);
44 Object *win;
46 win = NewObject(WBWindow, NULL,
47 WBWA_UserPort, my->WinPort,
48 WBWA_Path, path,
49 TAG_END);
51 if (win)
52 DoMethod(obj, OM_ADDMEMBER, win);
55 // OM_NEW
56 static IPTR WBAppNew(Class *cl, Object *obj, struct opSet *ops)
58 struct WorkbookBase *wb = (APTR)cl->cl_UserData;
59 struct wbApp *my;
60 IPTR rc;
62 rc = DoSuperMethodA(cl, obj, (Msg)ops);
63 if (rc == 0)
64 return 0;
66 my = INST_DATA(cl, rc);
68 NEWLIST(&my->Windows);
70 /* Create our Workbench message port */
71 my->AppPort = CreatePort(NULL, 0);
73 if (my->AppPort == NULL) {
74 DoSuperMethod(cl, (Object *)rc, OM_DISPOSE);
75 return 0;
78 /* Create our Window message port */
79 my->WinPort = CreatePort(NULL, 0);
81 if (my->WinPort == NULL) {
82 DeleteMsgPort(my->AppPort);
83 DoSuperMethod(cl, (Object *)rc, OM_DISPOSE);
84 return 0;
87 my->AppMask |= (1UL << my->AppPort->mp_SigBit);
88 my->WinMask |= (1UL << my->WinPort->mp_SigBit);
90 /* Create our root window */
91 my->Root = NewObject(WBWindow, NULL,
92 WBWA_Path, NULL,
93 WBWA_UserPort, my->WinPort,
94 TAG_END);
96 if (my->Root == NULL) {
97 DeleteMsgPort(my->WinPort);
98 DeleteMsgPort(my->AppPort);
99 DoSuperMethod(cl, (Object *)rc, OM_DISPOSE);
100 return 0;
103 return rc;
106 // OM_DISPOSE
107 static IPTR WBAppDispose(Class *cl, Object *obj, Msg msg)
109 struct WorkbookBase *wb = (APTR)cl->cl_UserData;
110 struct wbApp *my = INST_DATA(cl, obj);
111 Object *tstate = (Object *)my->Windows.mlh_Head;
112 Object *tmp;
114 /* Get rid of the subwindows */
115 while ((tmp = NextObject(&tstate))) {
116 DoMethod(tmp, OM_REMOVE);
117 DisposeObject(obj);
120 /* Get rid of the main window */
121 DisposeObject(my->Root);
123 DeleteMsgPort(my->AppPort);
124 DeleteMsgPort(my->WinPort);
126 return DoSuperMethodA(cl, obj, msg);
129 // OM_ADDMEMBER
130 static IPTR WBAppAddMember(Class *cl, Object *obj, struct opMember *opm)
132 struct wbApp *my = INST_DATA(cl, obj);
134 return DoMethod(opm->opam_Object, OM_ADDTAIL, &my->Windows);
137 // OM_REMMEMBER
138 static IPTR WBAppRemMember(Class *cl, Object *obj, struct opMember *opm)
140 return DoMethod(opm->opam_Object, OM_REMOVE);
144 static Object *wbLookupWindow(Class *cl, Object *obj, struct Window *win)
146 struct WorkbookBase *wb = (APTR)cl->cl_UserData;
147 struct wbApp *my = INST_DATA(cl, obj);
148 Object *ostate = (Object *)my->Windows.mlh_Head;
149 Object *owin;
150 struct Window *match = NULL;
152 /* Is it the root window? */
153 GetAttr(WBWA_Window, my->Root, (IPTR *)&match);
154 if (match == win)
155 return my->Root;
157 while ((owin = NextObject(&ostate))) {
158 match = NULL;
159 GetAttr(WBWA_Window, owin, (IPTR *)&match);
160 if (match == win)
161 return owin;
164 return NULL;
167 static void wbRefreshWindow(Class *cl, Object *obj, struct Window *win)
169 Object *owin;
171 if ((owin = wbLookupWindow(cl, obj, win))) {
172 DoMethod(owin, WBWM_REFRESH);
176 static void wbNewSizeWindow(Class *cl, Object *obj, struct Window *win)
178 Object *owin;
180 if ((owin = wbLookupWindow(cl, obj, win))) {
181 DoMethod(owin, WBWM_NEWSIZE);
185 static void wbCloseWindow(Class *cl, Object *obj, struct Window *win)
187 struct WorkbookBase *wb = (APTR)cl->cl_UserData;
188 Object *owin;
190 if ((owin = wbLookupWindow(cl, obj, win))) {
191 DoMethod(obj, OM_REMMEMBER, owin);
192 DisposeObject(owin);
196 static BOOL wbMenuPick(Class *cl, Object *obj, struct Window *win, UWORD menuNumber)
198 struct WorkbookBase *wb = (APTR)cl->cl_UserData;
199 Object *owin;
200 struct MenuItem *item;
201 BOOL quit = FALSE;
203 owin = wbLookupWindow(cl, obj, win);
205 D(bug("Menu: %x\n", menuNumber));
206 while (menuNumber != MENUNULL) {
207 BOOL handled = FALSE;
209 item = ItemAddress(win->MenuStrip, menuNumber);
211 /* Let the window have first opportunity */
212 if (owin)
213 handled = DoMethod(owin, WBWM_MENUPICK, item, menuNumber);
215 if (!handled) {
216 switch (WBMENU_ITEM_ID(item)) {
217 case WBMENU_ID(WBMENU_WB_QUIT):
218 quit = TRUE;
219 break;
220 case WBMENU_ID(WBMENU_WB_SHUTDOWN):
221 /* TODO: Ask if the user wants a shutdown or reboot */
222 ShutdownA(SD_ACTION_POWEROFF);
223 /* Can't power off. Try to reboot. */
224 ShutdownA(SD_ACTION_COLDREBOOT);
225 break;
229 menuNumber = item->NextSelect;
232 return quit;
235 static void wbIntuiTick(Class *cl, Object *obj, struct Window *win)
237 Object *owin;
239 if ((owin = wbLookupWindow(cl, obj, win))) {
240 DoMethod(owin, WBWM_INTUITICK);
244 static void wbHideAllWindows(Class *cl, Object *obj)
246 struct WorkbookBase *wb = (APTR)cl->cl_UserData;
247 struct wbApp *my = INST_DATA(cl, obj);
248 Object *ostate = (Object *)my->Windows.mlh_Head;
249 Object *owin;
251 while ((owin = NextObject(&ostate))) {
252 DoMethod(owin, WBWM_HIDE);
256 static void wbShowAllWindows(Class *cl, Object *obj)
258 struct WorkbookBase *wb = (APTR)cl->cl_UserData;
259 struct wbApp *my = INST_DATA(cl, obj);
260 Object *ostate = (Object *)my->Windows.mlh_Head;
261 Object *owin;
263 while ((owin = NextObject(&ostate))) {
264 DoMethod(owin, WBWM_SHOW);
268 static void wbCloseAllWindows(Class *cl, Object *obj)
270 struct WorkbookBase *wb = (APTR)cl->cl_UserData;
271 struct wbApp *my = INST_DATA(cl, obj);
272 Object *ostate = (Object *)my->Windows.mlh_Head;
273 Object *owin;
275 while ((owin = NextObject(&ostate))) {
276 DoMethod(obj, OM_REMMEMBER, owin);
277 DisposeObject(owin);
281 // WBAM_WORKBENCH - Register and handle all workbench events
282 static IPTR WBAppWorkbench(Class *cl, Object *obj, Msg msg)
284 struct WorkbookBase *wb = (APTR)cl->cl_UserData;
285 struct wbApp *my = INST_DATA(cl, obj);
286 BOOL done = FALSE;
288 CurrentDir(BNULL);
290 if (RegisterWorkbench(my->AppPort)) {
291 while (!done) {
292 ULONG mask;
294 mask = Wait(my->AppMask | my->WinMask);
296 if (mask & my->AppMask) {
297 struct WBHandlerMessage *wbhm;
298 wbhm = (APTR)GetMsg(my->AppPort);
300 switch (wbhm->wbhm_Type) {
301 case WBHM_TYPE_SHOW:
302 /* Show all windows */
303 wbShowAllWindows(cl, obj);
304 break;
305 case WBHM_TYPE_HIDE:
306 /* Hide all windows */
307 wbHideAllWindows(cl, obj);
308 break;
309 case WBHM_TYPE_OPEN:
310 /* Open a drawer */
311 wbOpenDrawer(cl, obj, wbhm->wbhm_Data.Open.Name);
312 break;
313 case WBHM_TYPE_UPDATE:
314 /* Refresh an open window/object */
315 break;
317 ReplyMsg((APTR)wbhm);
320 if (mask & my->WinMask) {
321 struct IntuiMessage *im;
323 im = GT_GetIMsg(my->WinPort);
325 D(bug("im=%p, Class=%d, Code=%d\n", im, im->Class, im->Code));
326 switch (im->Class) {
327 case IDCMP_CLOSEWINDOW:
328 /* Dispose the window */
329 wbCloseWindow(cl, obj, im->IDCMPWindow);
330 break;
331 case IDCMP_REFRESHWINDOW:
332 /* call WBWM_REFRESH on the window */
333 wbRefreshWindow(cl, obj, im->IDCMPWindow);
334 break;
335 case IDCMP_NEWSIZE:
336 /* call WBWM_NEWSIZE on the window */
337 wbNewSizeWindow(cl, obj, im->IDCMPWindow);
338 break;
339 case IDCMP_MENUPICK:
340 done = wbMenuPick(cl, obj, im->IDCMPWindow, im->Code);
341 break;
342 case IDCMP_INTUITICKS:
343 wbIntuiTick(cl, obj, im->IDCMPWindow);
344 break;
347 GT_ReplyIMsg(im);
351 wbCloseAllWindows(cl, obj);
353 UnregisterWorkbench(my->AppPort);
356 return FALSE;
359 static IPTR dispatcher(Class *cl, Object *obj, Msg msg)
361 IPTR rc = 0;
363 switch (msg->MethodID) {
364 case OM_NEW: rc = WBAppNew(cl, obj, (APTR)msg); break;
365 case OM_DISPOSE: rc = WBAppDispose(cl, obj, (APTR)msg); break;
366 case OM_ADDMEMBER: rc = WBAppAddMember(cl, obj, (APTR)msg); break;
367 case OM_REMMEMBER: rc = WBAppRemMember(cl, obj, (APTR)msg); break;
368 case WBAM_WORKBENCH:rc = WBAppWorkbench(cl, obj, (APTR)msg); break;
369 default: rc = DoSuperMethodA(cl, obj, msg); break;
372 return rc;
375 Class *WBApp_MakeClass(struct WorkbookBase *wb)
377 Class *cl;
379 cl = MakeClass( NULL, "rootclass", NULL,
380 sizeof(struct wbApp),
382 if (cl != NULL) {
383 cl->cl_Dispatcher.h_Entry = HookEntry;
384 cl->cl_Dispatcher.h_SubEntry = dispatcher;
385 cl->cl_Dispatcher.h_Data = NULL;
386 cl->cl_UserData = (IPTR)wb;
389 return cl;