- Now puts cursor position in window title properly instead of overwriting
[tangerine.git] / workbench / libs / desktop / newhandler.c
blob422a861e312f54e1965e78119d8852949150fd99
1 /*
2 Copyright © 1995-2007, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #define MUIMASTER_YES_INLINE_STDARG
8 #define DEBUG 1
9 #include <aros/debug.h>
11 #include <exec/types.h>
12 #include <exec/memory.h>
13 #include <intuition/classes.h>
14 #include <libraries/mui.h>
16 #include <proto/exec.h>
17 #include <proto/dos.h>
18 #include <proto/intuition.h>
19 #include <proto/icon.h>
21 #include "desktop_intern.h"
22 #include "support.h"
23 #include "worker.h"
25 #include "desktop_intern_protos.h"
26 #include "worker_protos.h"
27 #include "iconcontainerobserver.h"
29 #include <string.h>
31 // Handler states
32 #define HS_STARTING 1
33 #define HS_RUNNING 2
34 #define HS_STOPPING 3
36 void startedMessage(void)
38 struct Message *m;
40 m = (struct Message *) AllocVec(sizeof(struct Message), MEMF_ANY);
41 m->mn_Node.ln_Type = NT_MESSAGE;
42 m->mn_ReplyPort = DesktopBase->db_HandlerPort;
43 m->mn_Length = sizeof(struct Message);
45 PutMsg((struct MsgPort *) ((struct Process *) FindTask(NULL))->pr_Task.
46 tc_UserData, m);
49 ULONG desktopHandler(void)
51 struct DesktopInternMsg *msg,
52 *finalMsg;
53 ULONG handlerState = HS_STARTING;
54 BOOL replyNow = TRUE,
55 running = TRUE;
56 ULONG userCount = 0,
57 appCount = 0;
58 ULONG idCount = 0;
59 struct MinList workingMessages;
61 NEWLIST((struct List *) &workingMessages);
63 // The library's OPEN vector gets a mutex on the library
64 // base. Trouble will come our way if someone started this
65 // handler elsewhere
66 DesktopBase->db_HandlerPort = CreateMsgPort();
68 kprintf("--- starting desktop handler\n");
70 // let the creater know that it's now safe to send the handler
71 // messages
72 startedMessage();
74 kprintf("--- desktop handler accepting messages\n");
76 while (running)
78 WaitPort(DesktopBase->db_HandlerPort);
79 while ((msg =
80 ((struct DesktopInternMsg *)
81 GetMsg(DesktopBase->db_HandlerPort))))
83 if (msg->di_Message.mn_Node.ln_Type == NT_MESSAGE)
85 if (handlerState == HS_STARTING)
87 switch (msg->di_Command)
89 case DIMC_ADDUSER:
90 userCount++;
91 replyNow = TRUE;
92 handlerState = HS_RUNNING;
93 break;
94 default:
95 break;
98 else if (handlerState == HS_STOPPING)
100 switch (msg->di_Command)
102 case DIMC_ADDUSER:
103 userCount++;
104 replyNow = TRUE;
105 handlerState = HS_RUNNING;
106 break;
107 default:
108 break;
111 else if (handlerState == HS_RUNNING)
113 switch (msg->di_Command)
115 case DIMC_ADDUSER:
117 userCount++;
118 replyNow = TRUE;
119 break;
121 case DIMC_SUBUSER:
123 kprintf("--- DIMC_SUBUSER\n");
124 userCount--;
125 if (userCount == 0 && appCount == 0)
127 kprintf("--- time to exit...\n");
128 handlerState = HS_STOPPING;
129 replyNow = TRUE;
130 kprintf("--- attempting semaphore\n");
131 if (AttemptSemaphore
132 (&DesktopBase->db_BaseMutex))
134 if (AttemptSemaphore
135 (&DesktopBase->db_HandlerSafety))
137 running = FALSE;
138 replyNow = FALSE;
139 finalMsg = msg;
141 else
142 ReleaseSemaphore(&DesktopBase->
143 db_BaseMutex);
146 break;
148 case DIMC_SCANDIRECTORY:
150 struct HandlerScanRequest *scanMsg =
151 (struct HandlerScanRequest *) msg;
152 struct WorkingMessageNode *wmn;
154 wmn =
155 AllocVec(sizeof
156 (struct WorkingMessageNode),
157 MEMF_ANY);
158 wmn->wm_Working =
159 (struct DesktopInternMsg *) scanMsg;
160 wmn->wm_ID = ++idCount;
161 AddTail((struct List *) &workingMessages,
162 (struct Node *) wmn);
164 wmn->wm_Port =
165 startScannerWorker(idCount,
166 scanMsg->hsr_DirLock,
167 DesktopBase->
168 db_HandlerPort);
170 replyNow = TRUE;
172 break;
174 case DIMC_TOPLEVEL:
176 struct TempNode
178 struct Node t_Node;
179 UBYTE *t_Name;
181 struct HandlerTopLevelRequest *htl =
182 (struct HandlerTopLevelRequest *) msg;
183 struct DosList *dl;
184 struct TempNode *tn;
185 struct List tnList;
186 UWORD i = 0,
187 j = 0;
188 struct SingleResult *sr;
189 UBYTE *fullPath;
191 NEWLIST(&tnList);
193 dl = LockDosList(htl->htl_Types | LDF_READ);
194 while
196 (dl = NextDosEntry(dl, htl->htl_Types))
199 ULONG length = strlen(dl->dol_Ext.dol_AROS.dol_DevName) + 1;
201 tn = (struct TempNode *) AllocVec
203 sizeof(struct TempNode), MEMF_ANY
205 tn->t_Name = AllocVec
207 length + 1, MEMF_ANY
209 strlcpy(tn->t_Name, dl->dol_Ext.dol_AROS.dol_DevName, length);
210 AddTail(&tnList, (struct Node *) tn);
211 i++;
214 UnLockDosList(htl->htl_Types | LDF_READ);
216 sr = (struct SingleResult *)
217 AllocVec(sizeof(struct SingleResult) * i,
218 MEMF_ANY);
219 tn = tnList.lh_Head;
220 while (tn->t_Node.ln_Succ)
222 ULONG length = strlen(tn->t_Name) + 2;
224 sr[j].sr_Name = tn->t_Name;
226 fullPath = AllocVec(length + 2, MEMF_ANY);
228 strlcpy(fullPath, tn->t_Name, length);
229 strlcat(fullPath, ":", length);
231 sr[j].sr_DiskObject = GetDiskObjectNew
233 fullPath
235 tn = (struct TempNode *) tn->t_Node.ln_Succ;
236 j++;
239 DoMethod
241 htl->htl_Application,
242 MUIM_Application_PushMethod,
243 htl->htl_CallBack, 3,
244 ICOM_AddIcons, i, sr
247 break;
249 default:
250 break;
254 if (replyNow)
255 ReplyMsg((struct Message *) msg);
257 else if (msg->di_Message.mn_Node.ln_Type == NT_REPLYMSG)
259 struct WorkerMessage *wm = (struct WorkerMessage *) msg;
261 switch (wm->w_Action)
263 case WA_SCANNER:
265 struct WorkerMessage *newMsg;
266 struct WorkingMessageNode *wmn;
267 struct WorkerScanRequest *wsr =
268 (struct WorkerScanRequest *) wm;
270 wmn =
271 findWorkedMessage(&workingMessages,
272 wsr->wsr_WMessage.w_ID);
274 DoMethod(((struct HandlerScanRequest *) wmn->
275 wm_Working)->hsr_Application,
276 MUIM_Application_PushMethod,
277 ((struct HandlerScanRequest *) wmn->
278 wm_Working)->hsr_CallBack, 3,
279 ICOM_AddIcons, wsr->wsr_Results,
280 wsr->wsr_ResultsArray);
281 DoMethod(((struct HandlerScanRequest *) wmn->
282 wm_Working)->hsr_Application,
283 MUIM_Application_PushMethod,
284 ((struct HandlerScanRequest *) wmn->
285 wm_Working)->hsr_CallBack, 2,
286 OM_FreeList_Add, wsr->wsr_ExAllBuffer);
288 if (wsr->wsr_More)
290 newMsg =
291 createWorkerScanMessage(WM_RESUME,
292 WA_SCANNER,
293 wmn->wm_ID,
294 DesktopBase->
295 db_HandlerPort,
296 wsr->wsr_DirLock);
297 PutMsg(wmn->wm_Port,
298 (struct Message *) newMsg);
300 else
302 Remove((struct Node *) wmn);
303 ReplyMsg((struct Message *) wmn->wm_Working);
306 FreeVec(wsr);
308 break;
311 // FreeVec(msg);
316 kprintf("deleting port\n");
317 DeleteMsgPort(DesktopBase->db_HandlerPort);
318 DesktopBase->db_HandlerPort = NULL;
320 kprintf("releasing semaphores\n");
321 ReleaseSemaphore(&DesktopBase->db_HandlerSafety);
322 ReleaseSemaphore(&DesktopBase->db_BaseMutex);
324 kprintf("replying to msg\n");
325 ReplyMsg((struct Message *) finalMsg);
327 kprintf("--- shutting down desktop handler\n");
329 return 0;