Initial import of Scalos. To decrease size I have
[AROS-Contrib.git] / scalos / Plugins / OOP / wb39_plugin / AppWindow.c
blob709b2e016c48d65e4a4b6f947a74457e92391ade
1 // AppWindow.c
2 // $Date$
3 // $Revision$
6 #include <stdlib.h>
7 #include <string.h>
8 #include <stdarg.h>
9 #include <exec/types.h>
10 #include <intuition/classes.h>
11 #include <intuition/intuitionbase.h>
12 #include <datatypes/iconobject.h>
13 #include <dos/dos.h>
14 #include <dos/dosextens.h>
15 #include <dos/dostags.h>
16 #include <scalos/scalos.h>
17 #include <workbench/workbench.h>
18 #include <exec/nodes.h>
20 #include <clib/alib_protos.h>
22 #include <proto/exec.h>
23 #include <proto/iconobject.h>
24 #include <proto/utility.h>
25 #include <proto/dos.h>
26 #include <proto/exec.h>
27 #include <proto/scalos.h>
28 #include <proto/intuition.h>
29 #include <proto/layers.h>
30 #include <proto/wb.h>
32 #include <defs.h>
34 #include "wb39.h"
35 #include "wb39proto.h"
37 //-------------------------------------------------------------------------------------
39 struct ProcessData
41 struct NotifyRequest pd_NotifyReq;
42 BOOL pd_NotifyOk;
45 //-------------------------------------------------------------------------------------
47 static void GetDropZoneDropBox(struct myAppWindowDropZone *dz);
48 static struct Layer *WhichMouseLayer(WORD x, WORD y);
49 static BOOL PointInDropZone(const struct myAppWindowDropZone *dzz, WORD x, WORD y);
50 static void SignalDropzoneMouseEnterLeave(APTR draghandle,
51 const struct myAppWindowDropZone *dzz, ULONG EnterLeave);
52 static SAVEDS(void) myProcess(void);
53 static BOOL myProcessInit(struct ProcessData *pd);
54 static void myProcessCleanup(struct ProcessData *pd);
55 static void ServiceMyPort(void);
57 //-------------------------------------------------------------------------------------
59 static struct Task *HandshakeTask;
60 static ULONG HandshakeSignal = -1;
61 static struct MsgPort *myPort = NULL;
62 static BOOL myProcessRunning = FALSE;
63 static struct Process *myProc = NULL;
65 static const ULONG Maw_ID = MAKE_ID('M','A','W','X');
67 //-------------------------------------------------------------------------------------
69 // aus wb39.c
70 extern struct List AppWindowList; // list of all AppWindows
71 extern struct SignalSemaphore AppWindowSema;
74 #ifdef __AROS__
75 extern APTR origAddAppWindowA;
76 extern APTR origRemoveAppWindow;
77 extern APTR origSCA_DrawDrag;
78 #else
79 extern LIBFUNC_P6_DPROTO(struct ScaAppObjNode *, (*origAddAppWindowA),
80 D0, ULONG, id,
81 D1, ULONG, userdata,
82 A0, struct Window *, window,
83 A1, struct MsgPort *, msgport,
84 A2, struct TagItem *, taglist,
85 A6, struct Library *, WorkbenchBase);
86 extern LIBFUNC_P2_DPROTO(BOOL, (*origRemoveAppWindow),
87 A0, struct ScaAppObjNode *, appWindow,
88 A6, struct Library *, WorkbenchBase);
89 extern LIBFUNC_P5_DPROTO(void, (*origSCA_DrawDrag),
90 A0, struct DragHandle *, draghandle,
91 D0, LONG, X,
92 D1, LONG, Y,
93 D2, LONG, Flags,
94 A6, struct Library *, ScalosBase);
95 #endif
97 //-------------------------------------------------------------------------------------
99 // AddAppWindowDropZoneA
100 LIBFUNC_P5(struct myAppWindowDropZone *, myAddAppWindowDropZoneA,
101 A0, struct myAppWindow *, maw,
102 D0, ULONG, id,
103 D1, ULONG, userdata,
104 A1, struct TagItem *, tags,
105 A6, struct Library *, WorkbenchBase)
107 struct myAppWindowDropZone *dz;
108 struct TagItem *ti;
110 (void)WorkbenchBase;
112 d1(kprintf(__FUNC__ "/%ld: AppWindow=%08lx id=%08lx userdata=%08lx tags=%08lx\n", \
113 __LINE__, maw, id, userdata, tags));
115 if (NULL == maw)
116 return NULL;
118 if (Maw_ID != maw->maw_Magic)
119 return NULL;
121 dz = malloc(sizeof(struct myAppWindowDropZone));
122 if (NULL == dz)
123 return NULL;
125 dz->awz_AppWindow = maw;
126 dz->awz_ID = id;
127 dz->awz_UserData = userdata;
128 dz->awz_Hook = (struct Hook *) GetTagData(WBDZA_Hook, (ULONG)NULL, tags);
130 if (ti = FindTagItem(WBDZA_Box, tags))
132 dz->awz_MeasureBox = *((struct IBox *) (ti->ti_Data));
134 d1(kprintf(__FUNC__ "/%ld: MeasureBox left=%ld top=%ld width=%ld height=%ld\n", \
135 __LINE__, dz->awz_MeasureBox.Left, dz->awz_MeasureBox.Top, dz->awz_MeasureBox.Width, dz->awz_MeasureBox.Height));
137 dz->awz_RelRight = FALSE;
138 dz->awz_RelBottom = FALSE;
139 dz->awz_RelWidth = FALSE;
140 dz->awz_RelHeight = FALSE;
142 else
144 if (ti = FindTagItem(WBDZA_RelRight, tags))
146 dz->awz_MeasureBox.Left = ti->ti_Data;
147 dz->awz_RelRight = TRUE;
149 else
151 if (ti = FindTagItem(WBDZA_Left, tags))
153 dz->awz_MeasureBox.Left = ti->ti_Data;
155 else
157 // no LEFT
158 free(dz);
159 return NULL;
161 dz->awz_RelRight = FALSE;
163 if (ti = FindTagItem(WBDZA_RelBottom, tags))
165 dz->awz_MeasureBox.Top = ti->ti_Data;
166 dz->awz_RelBottom = TRUE;
168 else
170 if (ti = FindTagItem(WBDZA_Top, tags))
172 dz->awz_MeasureBox.Top = ti->ti_Data;
174 else
176 // no TOP
177 free(dz);
178 return NULL;
180 dz->awz_RelBottom = FALSE;
182 if (ti = FindTagItem(WBDZA_RelWidth, tags))
184 dz->awz_MeasureBox.Width = ti->ti_Data;
185 dz->awz_RelWidth = TRUE;
187 else
189 if (ti = FindTagItem(WBDZA_Width, tags))
191 dz->awz_MeasureBox.Width = ti->ti_Data;
193 else
195 // no WIDTH
196 free(dz);
197 return NULL;
199 dz->awz_RelWidth = FALSE;
201 if (ti = FindTagItem(WBDZA_RelHeight, tags))
203 dz->awz_MeasureBox.Height = ti->ti_Data;
204 dz->awz_RelHeight = TRUE;
206 else
208 if (ti = FindTagItem(WBDZA_Height, tags))
210 dz->awz_MeasureBox.Height = ti->ti_Data;
212 else
214 // no HEIGHT
215 free(dz);
216 return NULL;
218 dz->awz_RelHeight = FALSE;
222 dz->awz_DropBox = dz->awz_MeasureBox;
224 GetDropZoneDropBox(dz);
226 d1(kprintf(__FUNC__ "/%ld: dz=%08lx left=%ld top=%ld width=%ld height=%ld\n", \
227 __LINE__, dz, dz->awz_DropBox.Left, dz->awz_DropBox.Top, \
228 dz->awz_DropBox.Width, dz->awz_DropBox.Height));
230 ObtainSemaphore(&maw->maw_Sema);
232 AddTail(&maw->maw_DropZoneList, &dz->awz_Node);
234 ReleaseSemaphore(&maw->maw_Sema);
236 return dz;
238 LIBFUNC_END
241 // RemoveAppWindowDropZone
242 LIBFUNC_P3(BOOL, myRemoveAppWindowDropZone,
243 A0, struct myAppWindow *, maw,
244 A1, struct myAppWindowDropZone *, dz,
245 A6, struct Library *, WorkbenchBase)
247 struct myAppWindowDropZone *dzz;
248 BOOL Found = FALSE;
250 (void)WorkbenchBase;
252 d1(kprintf(__FUNC__ "/%ld: AppWindow=%08lx dropZone=%08lx\n", \
253 __LINE__, maw, dz));
255 if (NULL== maw)
256 return TRUE;
257 if (Maw_ID != maw->maw_Magic)
258 return FALSE;
259 if (NULL == dz)
260 return TRUE;
262 ObtainSemaphore(&maw->maw_Sema);
264 for (dzz = (struct myAppWindowDropZone *) maw->maw_DropZoneList.lh_Head;
265 !Found && dzz != (struct myAppWindowDropZone *) &maw->maw_DropZoneList.lh_Tail;
266 dzz = (struct myAppWindowDropZone *) dzz->awz_Node.ln_Succ)
268 d1(kprintf(__FUNC__ "/%ld: dz=%08lx dzz=%08lx\n", __LINE__, dz, dzz));
269 if (dz == dzz)
270 Found = TRUE;
273 if (Found)
275 Remove(&dz->awz_Node); // remove dropzone from list
276 free(dz);
279 ReleaseSemaphore(&maw->maw_Sema);
281 d1(kprintf(__FUNC__ "/%ld: Found=%ld\n", __LINE__, Found));
283 return Found;
285 LIBFUNC_END
288 // AddAppWindowA
289 LIBFUNC_P6(struct myAppWindow *, myAddAppWindowA,
290 D0, ULONG, id,
291 D1, ULONG, userdata,
292 A0, struct Window *, window,
293 A1, struct MsgPort *, msgport,
294 A2, struct TagItem *, taglist,
295 A6, struct Library *, WorkbenchBase)
297 struct ScaAppObjNode *aw;
298 struct myAppWindow *maw;
300 d1(KPrintF(__FUNC__ "/%ld: id=%08lx userdata=%08lx\n", __LINE__, id, userdata));
302 maw = calloc(sizeof(struct myAppWindow), 1);
303 d1(KPrintF(__FUNC__ "/%ld: maw=%08lx\n", __LINE__, maw));
304 if (NULL == maw)
306 return NULL;
309 maw->maw_Magic = Maw_ID;
310 maw->maw_AppWindow = NULL;
311 maw->maw_ActiveDropZone = NULL;
312 maw->maw_origUserData = userdata;
313 maw->maw_origMsgPort = msgport;
315 NewList(&maw->maw_DropZoneList);
316 InitSemaphore(&maw->maw_Sema);
318 d1(KPrintF(__FUNC__ "/%ld: origAddAppWindowA=%08lx\n", __LINE__, origAddAppWindowA));
320 // all AppWindow Messages will be relayed to myPort
321 #ifdef __AROS__
322 aw = (struct ScaAppObjNode *)AROS_CALL5(struct AppWindow *, origAddAppWindowA,
323 AROS_LDA(ULONG, id, D0),
324 AROS_LDA(ULONG, (ULONG)maw, D1),
325 AROS_LDA(struct Window *, window, A0),
326 AROS_LDA(struct MsgPort *, msgport, A1),
327 AROS_LDA(struct TagItem *, taglist, A2),
328 struct Library *, WorkbenchBase);
329 #else
330 aw = (struct ScaAppObjNode *) CALLLIBFUNC_P6(origAddAppWindowA,
331 D0, id,
332 D1, (ULONG) maw,
333 A0, window,
334 A1, myPort,
335 A2, taglist,
336 A6, WorkbenchBase);
337 #endif
339 d1(KPrintF(__FUNC__ "/%ld: aw=%08lx\n", __LINE__, aw));
340 if (NULL == aw)
342 return NULL;
345 maw->maw_AppWindow = aw;
347 ObtainSemaphore(&AppWindowSema);
348 AddTail(&AppWindowList, &maw->maw_Node);
349 ReleaseSemaphore(&AppWindowSema);
351 d1(KPrintF(__FUNC__ "/%ld: maw=%08lx\n", __LINE__, maw));
353 return maw;
355 LIBFUNC_END
358 LIBFUNC_P2(BOOL, myRemoveAppWindow,
359 A0, struct myAppWindow *, maw,
360 A6, struct Library *, WorkbenchBase)
362 BOOL Result;
363 struct myAppWindowDropZone *dz;
365 d1(KPrintF(__FUNC__ "/%ld: maw=%08lx\n", __LINE__, maw));
367 if (NULL == maw || 0 == TypeOfMem(maw))
368 return TRUE;
369 if (Maw_ID != maw->maw_Magic)
371 #ifdef __AROS__
372 return AROS_CALL1(BOOL, origRemoveAppWindow,
373 AROS_LDA(struct AppWindow *, maw, A0),
374 struct Library *, WorkbenchBase);
375 #else
376 return CALLLIBFUNC_P2(origRemoveAppWindow,
377 A0, (struct ScaAppObjNode *) maw,
378 A6, WorkbenchBase);
379 #endif
382 d1(KPrintF(__FUNC__ "/%ld: maw=%08lx\n", __LINE__, maw));
384 ObtainSemaphore(&AppWindowSema);
385 Remove(&maw->maw_Node);
386 ReleaseSemaphore(&AppWindowSema);
388 ObtainSemaphore(&maw->maw_Sema);
390 #ifdef __AROS__
391 Result = AROS_CALL1(BOOL, origRemoveAppWindow,
392 AROS_LDA(struct AppWindow *, maw->maw_AppWindow, A0),
393 struct Library *, WorkbenchBase);
394 #else
395 Result = CALLLIBFUNC_P2(origRemoveAppWindow,
396 A0, maw->maw_AppWindow,
397 A6, WorkbenchBase);
398 #endif
400 d1(KPrintF(__FUNC__ "/%ld: Result=%08lx\n", __LINE__, Result));
402 // Cleanup all added dropzones
403 while (dz = (struct myAppWindowDropZone *) RemHead(&maw->maw_DropZoneList))
405 free(dz);
408 ReleaseSemaphore(&maw->maw_Sema);
410 free(maw);
412 return Result;
414 LIBFUNC_END
417 LIBFUNC_P5(void, mySCA_DrawDrag,
418 A0, APTR, draghandle,
419 D0, LONG, X,
420 D1, LONG, Y,
421 D2, LONG, Flags,
422 A6, struct Library *, ScalosBase)
424 struct Layer *mLayer;
426 d1(kprintf(__FUNC__ "/%ld: draghandle=%08lx x=%ld y=%ld\n", __LINE__, draghandle, X, Y));
428 mLayer = WhichMouseLayer(X, Y);
429 if (mLayer && mLayer->Window)
431 struct myAppWindow *maw, *mmaw = NULL;
433 ObtainSemaphore(&AppWindowSema);
435 for (maw = (struct myAppWindow *) AppWindowList.lh_Head;
436 maw != (struct myAppWindow *) &AppWindowList.lh_Tail;
437 maw = (struct myAppWindow *) maw->maw_Node.ln_Succ)
439 if ((struct Window *) maw->maw_AppWindow->an_object == mLayer->Window)
441 mmaw = maw;
442 break;
446 ReleaseSemaphore(&AppWindowSema);
448 d1(kprintf(__FUNC__ "/%ld: AppWindow=%08lx\n", __LINE__, mmaw));
450 // Mouse is inside AppWindow, now check DropZones
451 if (mmaw && !IsListEmpty(&mmaw->maw_DropZoneList))
453 struct myAppWindowDropZone *dzz;
454 WORD wx, wy;
455 struct Window *win = (struct Window *) mmaw->maw_AppWindow->an_object;
456 BOOL Found = FALSE;
458 wx = X - win->LeftEdge;
459 wy = Y - win->TopEdge;
461 for (dzz = (struct myAppWindowDropZone *) maw->maw_DropZoneList.lh_Head;
462 dzz != (struct myAppWindowDropZone *) &maw->maw_DropZoneList.lh_Tail;
463 dzz = (struct myAppWindowDropZone *) dzz->awz_Node.ln_Succ)
465 d1(kprintf(__FUNC__ "/%ld: DropZone=%08lx\n", __LINE__, dzz));
467 GetDropZoneDropBox(dzz);
469 if (PointInDropZone(dzz, wx, wy))
471 d1(kprintf(__FUNC__ "/%ld: INSIDE \n", __LINE__));
472 if (mmaw->maw_ActiveDropZone != dzz)
474 #ifdef __AROS__
475 AROS_CALL4(VOID, origSCA_DrawDrag,
476 AROS_LDA(struct DragHandle *, draghandle, A0),
477 AROS_LDA(LONG, 400 + win->WScreen->Width, D0),
478 AROS_LDA(LONG, 400 + win->WScreen->Height, D1),
479 AROS_LDA(ULONG, (Flags | SCAF_Drag_Hide), D2),
480 struct Library *, ScalosBase); // Hide Bobs
481 #else
482 CALLLIBFUNC_P5(origSCA_DrawDrag,
483 A0, draghandle,
484 D0, 400 + win->WScreen->Width,
485 D1, 400 + win->WScreen->Height,
486 D2, (Flags | SCAF_Drag_Hide),
487 A6, ScalosBase); // Hide Bobs
488 #endif
490 if (mmaw->maw_ActiveDropZone)
492 SignalDropzoneMouseEnterLeave(draghandle, mmaw->maw_ActiveDropZone, ADZMACTION_Leave);
495 mmaw->maw_ActiveDropZone = dzz;
496 SignalDropzoneMouseEnterLeave(draghandle, dzz, ADZMACTION_Enter);
499 Found = TRUE;
500 break;
504 if (!Found && mmaw->maw_ActiveDropZone)
506 d1(kprintf(__FUNC__ "/%ld: OUTSIDE \n", __LINE__));
508 #ifdef __AROS__
509 AROS_CALL4(VOID, origSCA_DrawDrag,
510 AROS_LDA(struct DragHandle *, draghandle, A0),
511 AROS_LDA(LONG, 400 + win->WScreen->Width, D0),
512 AROS_LDA(LONG, 400 + win->WScreen->Height, D1),
513 AROS_LDA(ULONG, (Flags | SCAF_Drag_Hide), D2),
514 struct Library *, ScalosBase);
515 #else
516 CALLLIBFUNC_P5(origSCA_DrawDrag,
517 A0, draghandle,
518 D0, 400 + win->WScreen->Width,
519 D1, 400 + win->WScreen->Height,
520 D2, (Flags | SCAF_Drag_Hide),
521 A6, ScalosBase); // Hide Bobs
522 #endif
524 SignalDropzoneMouseEnterLeave(draghandle, mmaw->maw_ActiveDropZone, ADZMACTION_Leave);
525 mmaw->maw_ActiveDropZone = NULL;
530 #ifdef __AROS__
531 AROS_CALL4(VOID, origSCA_DrawDrag,
532 AROS_LCA(struct DragHandle *, draghandle, A0),
533 AROS_LCA(LONG, X, D0),
534 AROS_LCA(LONG, Y, D1),
535 AROS_LCA(ULONG, Flags, D2),
536 struct Library *, ScalosBase);
537 #else
538 CALLLIBFUNC_P5(origSCA_DrawDrag,
539 A0, draghandle,
540 D0, X,
541 D1, Y,
542 D2, Flags,
543 A6, ScalosBase);
544 #endif
546 LIBFUNC_END
549 // Calculate awz_DropBox from awz_MeasureBox, taking into account window-relative coordinates
550 static void GetDropZoneDropBox(struct myAppWindowDropZone *dz)
552 struct Window *win = (struct Window *) dz->awz_AppWindow->maw_AppWindow->an_object;
554 d1(kprintf(__FUNC__ "/%ld: AppWindow=%08lx win=%08lx\n", \
555 __LINE__, dz->awz_AppWindow->maw_AppWindow, win));
557 d1(kprintf(__FUNC__ "/%ld: relright=%ld relbottom=%ld relwidth=%ld relheight=%ld\n", \
558 __LINE__, dz->awz_RelRight, dz->awz_RelBottom, dz->awz_RelWidth, dz->awz_RelHeight));
560 if (dz->awz_RelRight)
561 dz->awz_DropBox.Left = win->Width + dz->awz_MeasureBox.Left;
562 if (dz->awz_RelBottom)
563 dz->awz_DropBox.Top = win->Height + dz->awz_MeasureBox.Top;
564 if (dz->awz_RelWidth)
565 dz->awz_DropBox.Width = win->Width + dz->awz_MeasureBox.Width;
566 if (dz->awz_RelHeight)
567 dz->awz_DropBox.Height = win->Height + dz->awz_MeasureBox.Height;
571 static struct Layer *WhichMouseLayer(WORD x, WORD y)
573 struct Layer *layer = NULL;
574 struct Screen *scr;
575 extern struct IntuitionBase *IntuitionBase;
577 Forbid();
579 for (scr = IntuitionBase->FirstScreen; scr; scr = scr->NextScreen)
581 d1( kprintf("screen=%lx Offsetx=%ld ", scr, scr->ViewPort.DyOffset) );
582 d1( kprintf("x=%ld y=%ld\n", scr->MouseX, scr->MouseY) );
584 if (scr->MouseY >= 0 && scr->MouseY < scr->Height)
585 break;
588 Permit();
590 if (scr)
592 layer = WhichLayer(&scr->LayerInfo, x, y);
595 d1(kprintf("Screen=%lx x=%3ld y=%3ld\n", scr, IntuitionBase->MouseX,
596 IntuitionBase->MouseY) );
598 return(layer);
602 static BOOL PointInDropZone(const struct myAppWindowDropZone *dzz, WORD x, WORD y)
604 if (x < dzz->awz_DropBox.Left || y < dzz->awz_DropBox.Top)
605 return FALSE;
606 if (x >= dzz->awz_DropBox.Left + dzz->awz_DropBox.Width)
607 return FALSE;
608 if (y >= dzz->awz_DropBox.Top + dzz->awz_DropBox.Height)
609 return FALSE;
611 return TRUE;
615 static void SignalDropzoneMouseEnterLeave(APTR draghandle,
616 const struct myAppWindowDropZone *dzz, ULONG EnterLeave)
618 d1(kprintf(__FUNC__ "/%ld: DropZone=%08lx Hook=%08lx Action=%ld x=%ld y=%ld w=%ld h=%ld\n", \
619 __LINE__, dzz, dzz->awz_Hook, EnterLeave, dzz->awz_DropBox.Left, \
620 dzz->awz_DropBox.Top, dzz->awz_DropBox.Width, dzz->awz_DropBox.Height));
622 if (dzz->awz_Hook)
624 struct AppWindowDropZoneMsg msg;
625 ULONG WasLocked;
627 msg.adzm_RastPort = ((struct Window *) dzz->awz_AppWindow->maw_AppWindow->an_object)->RPort;
628 msg.adzm_Action = EnterLeave;
629 msg.adzm_DropZoneBox = dzz->awz_DropBox;
630 msg.adzm_ID = dzz->awz_ID;
631 msg.adzm_UserData = dzz->awz_UserData;
633 WasLocked = SCA_UnlockDrag(draghandle);
634 CallHookPkt(dzz->awz_Hook, NULL, &msg);
635 if (WasLocked)
636 SCA_LockDrag(draghandle);
640 /* ====================================================== */
642 BOOL DetachMyProcess(void)
644 STATIC_PATCHFUNC(myProcess);
645 HandshakeTask = FindTask(NULL);
646 HandshakeSignal = AllocSignal(-1);
647 if (-1 == HandshakeSignal)
649 // alarm("AllocSignal() failed");
650 return FALSE;
653 myProc = CreateNewProcTags(NP_Name, (ULONG) "wb39_plugin",
654 NP_Priority, 0,
655 NP_Entry, (ULONG) PATCH_NEWFUNC(myProcess),
656 NP_StackSize, 16384,
657 TAG_END);
658 if (myProc == NULL)
660 // alarm("TNC_INit: CreateProc() failed");
661 return FALSE;
664 Wait(1 << HandshakeSignal); /* Warten auf Ergebnis */
666 FreeSignal(HandshakeSignal);
667 HandshakeSignal = -1;
669 if (!myProcessRunning)
670 myProc = NULL;
672 return myProcessRunning;
676 void ShutdownMyProcess(void)
678 if (NULL == myProc)
679 return;
681 HandshakeTask = FindTask(NULL);
682 HandshakeSignal = AllocSignal(-1);
683 if (-1 == HandshakeSignal)
685 // alarm("AllocSignal() failed");
686 return;
689 myProcessRunning = FALSE;
691 Signal(&myProc->pr_Task, 1 << myPort->mp_SigBit); // Signal myProc
693 Wait(1 << HandshakeSignal); /* Warten auf Ergebnis */
695 FreeSignal(HandshakeSignal);
696 HandshakeSignal = -1;
698 myProc = NULL;
702 /* ====================================================== */
704 static SAVEDS(void) myProcess(void)
706 struct ProcessData pd =
708 { NULL },
709 FALSE,
712 d1(kprintf("%s/%s/%ld Start TNCProcess\n", __FILE__, __FUNC__, __LINE__);)
714 if (myProcessInit(&pd))
716 ULONG myPortMask = 1UL << myPort->mp_SigBit;
717 ULONG NotifyMask = 1UL << pd.pd_NotifyReq.nr_stuff.nr_Signal.nr_SignalNum;
718 ULONG Event;
720 d1(kprintf("%s/%s/%ld: myPortMask=%08lx NotifyMask=%08lx\n", __FILE__, __FUNC__, __LINE__,
721 myPortMask, NotifyMask));
723 myProcessRunning = TRUE;
725 if (HandshakeSignal != -1)
726 Signal(HandshakeTask, 1 << HandshakeSignal);
728 while (myProcessRunning)
730 Event = Wait(myPortMask | NotifyMask);
732 d1(kprintf("%s/%s/%ld: Event=%08lx\n", __FILE__, __FUNC__, __LINE__,
733 Event));
735 if (Event & myPortMask)
737 ServiceMyPort();
739 if (Event & NotifyMask)
741 ParseWBPrefs("ENV:sys/Workbench.prefs");
746 myProcessRunning = FALSE;
748 myProcessCleanup(&pd);
750 d1(kprintf("%s/%s/%ld End TNCProcess\n", __FILE__, __FUNC__, __LINE__);)
752 Forbid();
753 if (HandshakeSignal != -1)
754 Signal(HandshakeTask, 1 << HandshakeSignal);
758 static BOOL myProcessInit(struct ProcessData *pd)
760 myPort = CreateMsgPort();
761 if (!myPort)
763 // alarm(__FUNC__ ": CreateMsgPort() failed");
764 return FALSE;
767 memset(&pd->pd_NotifyReq, 0, sizeof(pd->pd_NotifyReq));
769 pd->pd_NotifyReq.nr_Name = "ENV:sys/Workbench.prefs";
770 pd->pd_NotifyReq.nr_UserData = 0;
771 pd->pd_NotifyReq.nr_Flags = NRF_SEND_SIGNAL;
772 pd->pd_NotifyReq.nr_stuff.nr_Signal.nr_Task = FindTask(NULL);
773 pd->pd_NotifyReq.nr_stuff.nr_Signal.nr_SignalNum = AllocSignal(-1);
775 pd->pd_NotifyOk = StartNotify(&pd->pd_NotifyReq);
777 d1(kprintf(__FUNC__ "/%ld: NotifyOk=%ld\n", __LINE__, pd->pd_NotifyOk));
779 return TRUE;
783 static void myProcessCleanup(struct ProcessData *pd)
785 if (myPort)
787 struct Message *Msg;
789 while (Msg = GetMsg(myPort))
791 switch (Msg->mn_Node.ln_Type)
793 case NT_MESSAGE:
794 ReplyMsg(Msg);
795 break;
797 case NT_REPLYMSG:
798 free(Msg);
799 break;
803 DeleteMsgPort(myPort);
804 myPort = NULL;
807 if (pd->pd_NotifyOk)
809 EndNotify(&pd->pd_NotifyReq);
810 pd->pd_NotifyOk = FALSE;
815 static void ServiceMyPort(void)
817 struct AppMessage *Msg;
819 while (Msg = (struct AppMessage *) GetMsg(myPort))
821 struct AppMessage *myMsg;
822 struct myAppWindow *maw;
824 switch (Msg->am_Message.mn_Node.ln_Type)
826 case NT_MESSAGE:
827 switch (Msg->am_Type)
829 case AMTYPE_APPWINDOW:
830 maw = (struct myAppWindow *) Msg->am_UserData;
832 d1(kprintf(__FUNC__ "/%ld: Msg=%08lx maw=%08lx ID=%08lx\n", __LINE__, Msg, maw, Msg->am_ID));
834 myMsg = malloc(sizeof(struct AppMessage));
835 if (myMsg)
837 *myMsg = *Msg;
838 myMsg->am_Message.mn_ReplyPort = myPort;
839 myMsg->am_UserData = maw->maw_origUserData;
840 myMsg->am_Reserved[7] = (ULONG) Msg; // Remember original Msg for Replying
842 if (maw->maw_ActiveDropZone)
844 d1(kprintf(__FUNC__ "/%ld: DropZone dzz=%08lx\n", __LINE__, maw->maw_ActiveDropZone));
846 if (PointInDropZone(maw->maw_ActiveDropZone,
847 Msg->am_MouseX, Msg->am_MouseY))
849 d1(kprintf(__FUNC__ "/%ld: DropZone dzz=%08lx\n", __LINE__, maw->maw_ActiveDropZone));
851 myMsg->am_Type = AMTYPE_APPWINDOWZONE;
852 myMsg->am_UserData = maw->maw_ActiveDropZone->awz_UserData;
853 myMsg->am_ID = maw->maw_ActiveDropZone->awz_ID;
855 else
857 maw->maw_ActiveDropZone = NULL;
861 PutMsg(maw->maw_origMsgPort, (struct Message *) myMsg);
863 break;
864 default:
865 ReplyMsg((struct Message *) Msg);
866 break;
868 break;
870 case NT_REPLYMSG:
871 if (MAKE_ID('A','P','P','M') == Msg->am_Reserved[0] && Msg->am_Reserved[7])
873 // Reply original Msg
874 ReplyMsg((struct Message *) Msg->am_Reserved[7]);
876 free(Msg);
877 break;
882 #ifdef __amigaos4__
883 LIBFUNC_P4VA(struct AppWindowDropZone *, myAddAppWindowDropZone,
884 A0, struct AppWindow *, maw,
885 D0, ULONG, id,
886 D1, ULONG, userdata,
887 A6, struct Library *, WorkbenchBase)
889 struct AppWindowDropZone *ret;
890 struct WorkbenchIFace *IWorkbench = (struct WorkbenchIFace *)self;
891 va_list args;
892 va_startlinear(args, userdata);
894 (void)WorkbenchBase;
896 ret = AddAppWindowDropZoneA(maw, id, userdata, va_getlinearva(args, const struct TagItem *));
898 va_end(args);
900 return(ret);
902 LIBFUNC_END
904 LIBFUNC_P5VA(struct AppWindow *, myAddAppWindow,
905 D0, ULONG, id,
906 D1, ULONG, userdata,
907 A0, struct Window *, window,
908 A1, struct MsgPort *, msgport,
909 A6, struct Library *, WorkbenchBase)
911 struct AppWindow *ret;
912 struct WorkbenchIFace *IWorkbench = (struct WorkbenchIFace *)self;
913 va_list args;
914 va_startlinear(args, msgport);
916 (void)WorkbenchBase;
918 ret = AddAppWindowA(id, userdata, window, msgport, va_getlinearva(args, const struct TagItem *));
920 va_end(args);
922 return(ret);
924 LIBFUNC_END
925 #endif