#include #include #include #include "patch.h" #ifndef DEBUG #include #endif #define PROGRAM_NAME "SmartIcon 2.0" #define RCFILE "s:.sirc" struct Window *theEventWindow; BOOL Sleeping = FALSE; USHORT WindowX = 40, WindowY = 20; ULONG PatchSignal = -1; struct WindowPatch PList; struct HiddenWindow HList; struct ListSupport *DList; struct Library *GfxBase, *IntuitionBase, *LayersBase; struct MsgPort *DefaultPort, *WakeupPort, *IDCMPReplyPort; struct Task *PatchTask; VOID ReadRCFile() { USHORT x, y; register struct FileHandle *file = (struct FileHandle *)Open(RCFILE, MODE_OLDFILE); if (file) { if (Read(file, &x, 2)==2 && Read(file, &y, 2)==2) { WindowX = x; WindowY = y; } else DisplayBeep(NULL); Close(file); } } VOID WriteRCFile() { register struct FileHandle *file = (struct FileHandle *)Open(RCFILE, MODE_NEWFILE); if (file) { Write(file, &DList->LRWindow->LeftEdge, 2); Write(file, &DList->LRWindow->TopEdge, 2); Close(file); } else DisplayBeep(NULL); } VOID Cleanup(code) register UBYTE code; { register struct IntuiMessage *msg; Forbid(); while (PList.NextPatch) UnPatchWindow(PList.NextPatch, TRUE); Permit(); if (DList) ReleaseList(DList); if (DefaultPort) { while(msg = (struct IntuiMessage *)GetMsg(DefaultPort)) ReplyMsg(msg); DeletePort(DefaultPort); } if (WakeupPort) DeletePort(WakeupPort); if (IDCMPReplyPort) DeletePort(IDCMPReplyPort); if (PatchSignal!=-1) FreeSignal(PatchSignal); if (GfxBase) CloseLibrary(GfxBase); if (IntuitionBase) CloseLibrary(IntuitionBase); if (LayersBase) CloseLibrary(LayersBase); exit(code); } VOID ControlLoop() { BOOL mousemoved; SHORT x, y, code, itemnum; LONG seconds, micros; ULONG class, mask, PatchEvent = 1 << PatchSignal, DefPortEvent = 1 << DefaultPort->mp_SigBit, WakeupEvent = 1 << WakeupPort->mp_SigBit, ReqEvent = 1 << DList->LRWindow->UserPort->mp_SigBit; register struct Window *window; register struct IntuiMessage *msg; register struct Gadget *gadget; FOREVER { WAIT: mask = Wait(SIGBREAKF_CTRL_C | DefPortEvent | PatchEvent | ReqEvent | WakeupEvent); if (mask & SIGBREAKF_CTRL_C) return; if (mask & DefPortEvent) while(msg=(struct IntuiMessage *)GetMsg(DefaultPort)) ReplyMsg(msg); if (mask & WakeupEvent) { #ifdef DEBUG printf("wake up event received\n"); #endif /* A wake up signal here means that another SmartIcon task was launched */ /* and that it is telling us. Time to wake up if we were asleep. */ if (Sleeping) { FixDisplay(FALSE); if (!ls_StartRequester(DList, NULL, WindowX, WindowY)) DisplayBeep(NULL); else Sleeping = FALSE; } } if (mask & PatchEvent) { Forbid(); window = theEventWindow; Permit(); #ifdef DEBUG printf("patch event received: window [%s]\n", window->Title); #endif Iconify(window, !Sleeping); } if (mask & ReqEvent) { mousemoved = FALSE; while (msg = (struct IntuiMessage *)GetMsg(DList->LRWindow->UserPort)) { gadget = (struct Gadget *)msg->IAddress; class = msg->Class; code = msg->Code; x = msg->MouseX; y = msg->MouseY; seconds = msg->Seconds; micros = msg->Micros; ReplyMsg(msg); switch(class) { case MOUSEMOVE: mousemoved = TRUE; break; case GADGETDOWN: case GADGETUP: if (ls_HandleGadget(DList, gadget, x, y, seconds, micros)) UnIconify(DList->Pick, TRUE); break; case CLOSEWINDOW: /* go to sleep... */ Sleeping = TRUE; WindowX = DList->LRWindow->LeftEdge; WindowY = DList->LRWindow->TopEdge; ls_EndRequester(DList); goto WAIT; case MENUPICK: while (code != MENUNULL && code != 252) { itemnum = ITEMNUM(code); switch(itemnum) { case 3: WriteRCFile(); break; case 5: return; } code = ((struct MenuItem *)ItemAddress(DList->LRWindow->MenuStrip, code))->NextSelect; } break; } } if (mousemoved) ls_PropMouseMoves(DList); } } } VOID main(argc, argv) UBYTE argc, **argv; { extern struct Library *OpenLibrary(); extern struct MsgPort *CreatePort(); struct MsgPort *port; /* First check if we already have a port somewhere. If yes, then there is */ /* already a task running, just signal that we saw it and exit. */ if (port = (struct MsgPort *)FindPort("SM2.0")) { Signal(port->mp_SigTask, 1 << port->mp_SigBit); exit(0); } /* Still here? Just do our normal stuff. */ if ( (GfxBase = OpenLibrary("graphics.library", 0)) && (IntuitionBase = OpenLibrary("intuition.library", 0)) && (LayersBase = OpenLibrary("layers.library", 0)) && (WakeupPort = CreatePort("SM2.0", 0)) && (DefaultPort = CreatePort(0, 0)) && (IDCMPReplyPort = CreatePort(0, 0)) && ((PatchSignal = AllocSignal(-1))!=-1) && (DList = GetListSupport(NULL, NULL, NULL)) ) { ReadRCFile(); PatchTask = (struct Task *)FindTask(0); SetHooks(); PatchCurrentWindows(); DList->ReqTitle = "Windows "; DList->MaxChars = 14; DList->MaxLines = 5; if (ls_AllocateData(DList) && ls_StartRequester(DList, NULL, WindowX, WindowY)) { ControlLoop(); /* Put this here so we get display feedback */ while (HList.Next) UnIconify(HList.Next, !Sleeping); if (!Sleeping) ls_EndRequester(DList); ls_DeleteData(DList); } ClearHooks(); Cleanup(0); } Cleanup(10); }