revert between 56095 -> 55830 in arch
[AROS.git] / rom / usb / poseidon / popo.gui.c
blob145b786eb77494c23c1bdbc52c10ac50d6e172b5
1 /*
2 * GUI
3 */
5 #include "debug.h"
6 #include "poseidon.library.h"
8 #include <libraries/mui.h>
9 #include <intuition/intuition.h>
10 #include <intuition/intuitionbase.h>
11 #include <libraries/gadtools.h>
12 #include <datatypes/soundclass.h>
14 #include <proto/exec.h>
16 #define __NOLIBBASE__
17 #include <proto/alib.h>
18 #include <proto/muimaster.h>
19 #include <proto/dos.h>
20 #include <proto/datatypes.h>
21 #include <proto/intuition.h>
22 #include <proto/utility.h>
23 #include <proto/usbclass.h>
25 #include "numtostr.h"
27 #define NewList NEWLIST
29 #include "popo.gui.h"
31 #include <stdarg.h>
33 #define MUIMasterBase po->po_MUIBase
34 #define DataTypesBase po->po_DTBase
35 #define IntuitionBase po->po_IntBase
37 /* /// "pPoPoGUITask()" */
38 AROS_UFH0(void, pPoPoGUITask)
40 AROS_USERFUNC_INIT
41 struct Task *thistask;
42 LIBBASETYPEPTR ps;
43 struct PsdPoPo *po;
44 struct List *scrlist;
45 struct PubScreenNode *pubscr;
46 BOOL hasworkbench = FALSE;
48 thistask = FindTask(NULL);
50 ps = thistask->tc_UserData;
51 SetTaskPri(thistask, 0);
52 po = &ps->ps_PoPo;
54 NewList(&po->po_GadgetList);
55 NewList(&po->po_Sounds);
57 if(!(IntuitionBase = OpenLibrary("intuition.library", 39)))
59 KPRINTF(10, ("Couldn't open intuition.library.\n"));
60 pPoPoGUITaskCleanup(ps);
61 return;
64 scrlist = LockPubScreenList();
65 pubscr = (struct PubScreenNode *) scrlist->lh_Head;
66 while(pubscr->psn_Node.ln_Succ)
68 if(strcmp(pubscr->psn_Node.ln_Name, "Workbench") == 0)
70 if(pubscr->psn_Screen)
72 hasworkbench = TRUE;
74 break;
76 pubscr = (struct PubScreenNode *) pubscr->psn_Node.ln_Succ;
78 UnlockPubScreenList();
80 if(!hasworkbench)
82 KPRINTF(10, ("No screen open yet.\n"));
83 pPoPoGUITaskCleanup(ps);
84 return;
87 if(!(MUIMasterBase = OpenLibrary(MUIMASTER_NAME, MUIMASTER_VMIN)))
89 KPRINTF(10, ("Couldn't open muimaster.library.\n"));
90 pPoPoGUITaskCleanup(ps);
91 return;
94 if(!(DataTypesBase = OpenLibrary("datatypes.library", 39)))
96 KPRINTF(10, ("Couldn't open datatypes.library.\n"));
97 pPoPoGUITaskCleanup(ps);
98 return;
101 if(!(po->po_MsgPort = CreateMsgPort()))
103 KPRINTF(10, ("Couldn't create MsgPort.\n"));
104 pPoPoGUITaskCleanup(ps);
105 return;
108 po->po_EventHandler = psdAddEventHandler(po->po_MsgPort, EHMF_ADDDEVICE|EHMF_REMDEVICE|EHMF_ADDBINDING|EHMF_CONFIGCHG|EHMF_DEVICEDEAD|EHMF_DEVICELOWPW);
109 if(!po->po_EventHandler)
111 KPRINTF(10, ("Couldn't add EventHandler.\n"));
112 pPoPoGUITaskCleanup(ps);
113 return;
116 if(!(po->po_TimerMsgPort = CreateMsgPort()))
118 KPRINTF(10, ("Couldn't create MsgPort.\n"));
119 pPoPoGUITaskCleanup(ps);
120 return;
123 if(!(po->po_TimerIOReq = (struct timerequest *) CreateIORequest(po->po_TimerMsgPort, sizeof(struct timerequest))))
125 KPRINTF(10, ("Couldn't create TimerIOReq.\n"));
126 pPoPoGUITaskCleanup(ps);
127 return;
130 if(OpenDevice("timer.device", UNIT_VBLANK, (struct IORequest *) po->po_TimerIOReq, 0))
132 KPRINTF(10, ("Couldn't open timer.device.\n"));
133 pPoPoGUITaskCleanup(ps);
134 return;
136 po->po_TimerIOReq->tr_node.io_Message.mn_Node.ln_Type = NT_REPLYMSG;
137 po->po_TimerIOReq->tr_node.io_Message.mn_Node.ln_Name = "PoPo";
138 po->po_TimerIOReq->tr_node.io_Command = TR_ADDREQUEST;
140 if(!(po->po_PoPoClass = MUI_CreateCustomClass(NULL, MUIC_Area, NULL, sizeof(struct PoPoData), PoPoDispatcher)))
142 KPRINTF(10, ("Couldn't create PoPo Class\n"));
143 pPoPoGUITaskCleanup(ps);
144 return;
146 po->po_PoPoClass->mcc_Class->cl_UserData = (IPTR) ps;
148 po->po_AppObj = ApplicationObject,
149 MUIA_Application_Title , (IPTR)"PoPo -- Poseidon Popup Provider",
150 MUIA_Application_Version , (IPTR)VERSION_STRING,
151 MUIA_Application_Copyright , (IPTR)"©2004-2009 Chris Hodges",
152 MUIA_Application_Author , (IPTR)"Chris Hodges <chrisly@platon42.de>",
153 MUIA_Application_Description, (IPTR)"Opens annoying windows",
154 MUIA_Application_Base , (IPTR)"POPO",
155 MUIA_Application_HelpFile , (IPTR)"HELP:Poseidon.guide",
156 MUIA_Application_Menustrip , (IPTR)MenustripObject,
157 Child, (IPTR)MenuObjectT((IPTR)"Project"),
158 Child, (IPTR)(po->po_AboutMI = MenuitemObject,
159 MUIA_Menuitem_Title, (IPTR)"About...",
160 MUIA_Menuitem_Shortcut, (IPTR)"?",
161 End),
162 Child, (IPTR)MenuitemObject,
163 MUIA_Menuitem_Title, (IPTR)NM_BARLABEL,
164 End,
165 Child, (IPTR)(po->po_CloseMI = MenuitemObject,
166 MUIA_Menuitem_Title, (IPTR)"Close",
167 MUIA_Menuitem_Shortcut, (IPTR)"Q",
168 End),
169 End,
170 Child, (IPTR)MenuObjectT((IPTR)"Settings"),
171 Child, (IPTR)(po->po_TridentMI = MenuitemObject,
172 MUIA_Menuitem_Title, (IPTR)"Open Trident",
173 MUIA_Menuitem_Shortcut, (IPTR)"O",
174 End),
175 Child, (IPTR)MenuitemObject,
176 MUIA_Menuitem_Title, (IPTR)NM_BARLABEL,
177 End,
178 Child, (IPTR)(po->po_MUIPrefsMI = MenuitemObject,
179 MUIA_Menuitem_Title, (IPTR)"MUI Settings",
180 MUIA_Menuitem_Shortcut, (IPTR)"M",
181 End),
182 End,
183 End,
185 SubWindow, (IPTR)(po->po_WindowObj = WindowObject,
186 MUIA_Window_ID , MAKE_ID('P','O','P','O'),
187 MUIA_Window_Title, (IPTR)"Poseidon Popups",
188 MUIA_HelpNode, (IPTR)"main",
190 WindowContents, (IPTR)VGroup,
191 Child, (IPTR)(po->po_PoPoObj = NewObject(po->po_PoPoClass->mcc_Class, 0, MUIA_ShowMe, FALSE, TAG_END)),
192 Child, (IPTR)(po->po_GroupObj = VGroup,
193 Child, (IPTR)HGroup,
194 Child, (IPTR)HSpace(0),
195 Child, (IPTR)Label("Messages"),
196 Child, (IPTR)HSpace(0),
197 End,
198 End),
199 Child, (IPTR)HGroup,
200 Child, (IPTR)(po->po_StickyObj = ImageObject, ImageButtonFrame,
201 MUIA_Background, MUII_ButtonBack,
202 MUIA_CycleChain, 1,
203 MUIA_InputMode, MUIV_InputMode_Toggle,
204 MUIA_Image_Spec, MUII_CheckMark,
205 MUIA_Image_FreeVert, TRUE,
206 MUIA_Selected, FALSE,
207 MUIA_ShowSelState, FALSE,
208 End),
209 Child, (IPTR)Label("Hold on"),
210 Child, (IPTR)HGroup,
211 MUIA_Group_SameWidth, TRUE,
212 Child, (IPTR)(po->po_SaveObj = TextObject, ButtonFrame,
213 MUIA_Disabled, (ps->ps_SavedConfigHash == ps->ps_ConfigHash),
214 MUIA_Background, MUII_ButtonBack,
215 MUIA_CycleChain, 1,
216 MUIA_InputMode, MUIV_InputMode_RelVerify,
217 MUIA_Text_Contents, (IPTR)"\33c Save Prefs ",
218 End),
219 Child, (IPTR)(po->po_CloseObj = TextObject, ButtonFrame,
220 MUIA_Background, MUII_ButtonBack,
221 MUIA_CycleChain, 1,
222 MUIA_InputMode, MUIV_InputMode_RelVerify,
223 MUIA_Text_Contents, (IPTR)"\33c Close ",
224 End),
225 End,
226 End,
227 End,
228 End),
229 End;
231 if(!po->po_AppObj)
233 KPRINTF(10, ("Couldn't create application\n"));
234 pPoPoGUITaskCleanup(ps);
235 return;
238 DoMethod(po->po_WindowObj, MUIM_Notify, MUIA_Window_CloseRequest, TRUE,
239 po->po_AppObj, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit);
240 DoMethod(po->po_SaveObj, MUIM_Notify, MUIA_Pressed, FALSE,
241 po->po_PoPoObj, 1, MUIM_PoPo_SavePrefs);
242 DoMethod(po->po_CloseObj, MUIM_Notify, MUIA_Pressed, FALSE,
243 po->po_AppObj, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit);
244 DoMethod(po->po_StickyObj, MUIM_Notify, MUIA_Selected, MUIV_EveryTime,
245 po->po_PoPoObj, 1, MUIM_PoPo_Sticky);
247 DoMethod(po->po_AboutMI, MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime,
248 po->po_PoPoObj, 1, MUIM_PoPo_About);
249 DoMethod(po->po_CloseMI, MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime,
250 po->po_AppObj, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit);
251 DoMethod(po->po_TridentMI, MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime,
252 po->po_PoPoObj, 1, MUIM_PoPo_OpenTrident);
253 DoMethod(po->po_MUIPrefsMI, MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime,
254 po->po_AppObj, 2, MUIM_Application_OpenConfigWindow, 0);
258 BOOL isopen = FALSE;
259 ULONG sigs;
260 ULONG sigmask;
261 LONG retid;
262 struct PsdPoPoGadgets *pog;
263 struct timeval currtime;
265 po->po_Task = thistask;
266 Forbid();
267 if(po->po_ReadySigTask)
269 Signal(po->po_ReadySigTask, 1L<<po->po_ReadySignal);
271 Permit();
273 //set(po->po_WindowObj, MUIA_Window_Open, TRUE);
274 po->po_TimerIOReq->tr_time.tv_micro = 500*1000;
275 SendIO(&po->po_TimerIOReq->tr_node);
276 sigmask = (1UL<<po->po_MsgPort->mp_SigBit)|(1UL<<po->po_TimerMsgPort->mp_SigBit);
279 retid = DoMethod(po->po_AppObj, MUIM_Application_NewInput, &sigs);
280 if(sigs)
282 pEventHandler(ps);
283 if(CheckIO(&po->po_TimerIOReq->tr_node))
285 WaitIO(&po->po_TimerIOReq->tr_node);
286 po->po_TimerIOReq->tr_time.tv_micro = 500*1000;
287 SendIO(&po->po_TimerIOReq->tr_node);
289 CurrentTime(&currtime.tv_secs, &currtime.tv_micro);
290 pog = (struct PsdPoPoGadgets *) po->po_GadgetList.lh_Head;
291 while(pog->pog_Node.ln_Succ)
293 if((currtime.tv_secs > pog->pog_TimeoutTime.tv_secs) ||
294 ((currtime.tv_secs == pog->pog_TimeoutTime.tv_secs) &&
295 (currtime.tv_micro > pog->pog_TimeoutTime.tv_micro)))
297 pFreePoPoGadgets(ps, pog);
298 pog = (struct PsdPoPoGadgets *) po->po_GadgetList.lh_Head;
299 } else {
300 pog = (struct PsdPoPoGadgets *) pog->pog_Node.ln_Succ;
304 if(po->po_GadgetList.lh_Head->ln_Succ)
306 if(po->po_OpenRequest)
308 if(!isopen)
310 if(ps->ps_GlobalCfg->pgc_PopupActivateWin)
312 set(po->po_WindowObj, MUIA_Window_Activate, TRUE);
313 } else {
314 set(po->po_WindowObj, MUIA_Window_Activate, FALSE);
316 set(po->po_StickyObj, MUIA_Selected, FALSE);
317 set(po->po_WindowObj, MUIA_Window_Open, TRUE);
318 isopen = TRUE;
319 } else {
320 if(ps->ps_GlobalCfg->pgc_PopupWinToFront)
322 DoMethod(po->po_WindowObj, MUIM_Window_ToFront);
325 po->po_OpenRequest = FALSE;
327 } else {
328 if(isopen)
330 set(po->po_WindowObj, MUIA_Window_Open, FALSE);
331 isopen = FALSE;
335 sigs = Wait(sigs | sigmask | SIGBREAKF_CTRL_C);
336 if(sigs & SIGBREAKF_CTRL_C)
338 break;
341 if(retid == MUIV_Application_ReturnID_Quit)
343 set(po->po_WindowObj, MUIA_Window_Open, FALSE);
344 /* remove all thingies */
345 pog = (struct PsdPoPoGadgets *) po->po_GadgetList.lh_Head;
346 while(pog->pog_Node.ln_Succ)
348 pFreePoPoGadgets(ps, pog);
349 pog = (struct PsdPoPoGadgets *) po->po_GadgetList.lh_Head;
352 if((ps->ps_GlobalCfg->pgc_PopupDeviceNew == PGCP_NEVER) &&
353 (!ps->ps_GlobalCfg->pgc_PopupDeviceDeath) &&
354 (!ps->ps_GlobalCfg->pgc_PopupDeviceGone))
356 psdAddErrorMsg0(RETURN_OK, (STRPTR) "PoPo", "PoPo has been abandoned (is it you, stuntzi?).");
357 break;
360 } while(TRUE);
361 set(po->po_WindowObj, MUIA_Window_Open, FALSE);
363 pPoPoGUITaskCleanup(ps);
364 AROS_USERFUNC_EXIT
366 /* \\\ */
368 /* /// "pPoPoGUITaskCleanup()" */
369 void pPoPoGUITaskCleanup(LIBBASETYPEPTR ps)
371 struct PsdPoPo *po = &ps->ps_PoPo;
372 struct PsdPoPoGadgets *pog;
373 struct PsdPoPoSound *pps;
375 pog = (struct PsdPoPoGadgets *) po->po_GadgetList.lh_Head;
376 while(pog->pog_Node.ln_Succ)
378 pFreePoPoGadgets(ps, pog);
379 pog = (struct PsdPoPoGadgets *) po->po_GadgetList.lh_Head;
382 pps = (struct PsdPoPoSound *) po->po_Sounds.lh_Head;
383 while(pps->pps_Node.ln_Succ)
385 pPoPoFreeSound(ps, pps);
386 pps = (struct PsdPoPoSound *) po->po_Sounds.lh_Head;
389 if(po->po_TimerIOReq)
391 if(po->po_TimerIOReq->tr_node.io_Device)
393 AbortIO(&po->po_TimerIOReq->tr_node);
394 WaitIO(&po->po_TimerIOReq->tr_node);
395 CloseDevice((struct IORequest *) po->po_TimerIOReq);
397 DeleteIORequest((struct IORequest *) po->po_TimerIOReq);
398 po->po_TimerIOReq = NULL;
400 if(po->po_TimerMsgPort)
402 DeleteMsgPort(po->po_TimerMsgPort);
403 po->po_TimerMsgPort = NULL;
406 if(po->po_EventHandler)
408 psdRemEventHandler(po->po_EventHandler);
409 po->po_EventHandler = NULL;
411 if(po->po_MsgPort)
413 DeleteMsgPort(po->po_MsgPort);
414 po->po_MsgPort = NULL;
416 if(po->po_AppObj)
418 MUI_DisposeObject(po->po_AppObj);
419 po->po_AppObj = NULL;
421 if(po->po_PoPoClass)
423 MUI_DeleteCustomClass(po->po_PoPoClass);
424 po->po_PoPoClass = NULL;
426 if(DataTypesBase)
428 CloseLibrary(DataTypesBase);
429 DataTypesBase = NULL;
431 if(MUIMasterBase)
433 CloseLibrary(MUIMasterBase);
434 MUIMasterBase = NULL;
436 if(IntuitionBase)
438 CloseLibrary(IntuitionBase);
439 IntuitionBase = NULL;
441 Forbid();
442 po->po_Task = NULL;
443 if(po->po_ReadySigTask)
445 Signal(po->po_ReadySigTask, 1L<<po->po_ReadySignal);
448 /* \\\ */
450 /* /// "pPoPoLoadSound()" */
451 struct PsdPoPoSound * pPoPoLoadSound(LIBBASETYPEPTR ps, STRPTR name)
453 struct PsdPoPo *po = &ps->ps_PoPo;
454 struct PsdPoPoSound *pps;
455 if((pps = psdAllocVec(sizeof(struct PsdPoPoSound))))
457 if((pps->pps_Node.ln_Name = psdCopyStr(name)))
459 AddTail(&po->po_Sounds, &pps->pps_Node);
460 pps->pps_DTHandle = NewDTObject(name,
461 DTA_SourceType, DTST_FILE,
462 DTA_GroupID, GID_SOUND,
463 SDTA_Cycles, 1L,
464 TAG_END);
465 if(!pps->pps_DTHandle)
467 psdAddErrorMsg(RETURN_ERROR, "PoPo", "Could not load soundfile '%s'.", name);
469 return(pps);
471 psdFreeVec(pps);
473 return(NULL);
475 /* \\\ */
477 /* /// "pPoPoPlaySound()" */
478 BOOL pPoPoPlaySound(LIBBASETYPEPTR ps, STRPTR name)
480 struct PsdPoPo *po = &ps->ps_PoPo;
481 struct PsdPoPoSound *pps;
482 struct dtTrigger playmsg;
484 pps = (struct PsdPoPoSound *) FindName(&po->po_Sounds, name);
485 if(!pps)
487 pps = pPoPoLoadSound(ps, name);
489 if(!pps)
491 return(FALSE);
493 if(!pps->pps_DTHandle)
495 return(FALSE);
498 SetAttrs(pps->pps_DTHandle,
499 SDTA_Volume, 64,
500 TAG_END);
501 playmsg.MethodID = DTM_TRIGGER;
502 playmsg.dtt_GInfo = NULL;
503 playmsg.dtt_Function = STM_PLAY;
504 playmsg.dtt_Data = NULL;
505 DoMethodA(pps->pps_DTHandle, (Msg) &playmsg);
506 return(TRUE);
508 /* \\\ */
510 /* /// "pPoPoFreeSound()" */
511 void pPoPoFreeSound(LIBBASETYPEPTR ps, struct PsdPoPoSound *pps)
513 struct PsdPoPo *po = &ps->ps_PoPo;
514 Remove(&pps->pps_Node);
515 if(pps->pps_DTHandle)
517 DisposeDTObject(pps->pps_DTHandle);
519 psdFreeVec(pps->pps_Node.ln_Name);
520 psdFreeVec(pps);
522 /* \\\ */
524 /* /// "pIsDeviceStillValid()" */
525 BOOL pIsDeviceStillValid(LIBBASETYPEPTR ps, struct PsdDevice *pd)
527 struct PsdDevice *tmppd = NULL;
528 while((tmppd = psdGetNextDevice(tmppd)))
530 if(tmppd == pd)
532 return(TRUE);
535 return(FALSE);
537 /* \\\ */
539 /* /// "pIsClassStillValid()" */
540 BOOL pIsClassStillValid(LIBBASETYPEPTR ps, struct Library *ucb)
542 struct PsdUsbClass *puc = (struct PsdUsbClass *) ps->ps_Classes.lh_Head;
543 while(puc->puc_Node.ln_Succ)
545 if(puc->puc_ClassBase == ucb)
547 return(TRUE);
549 puc = (struct PsdUsbClass *) puc->puc_Node.ln_Succ;
551 return(FALSE);
553 /* \\\ */
555 /* /// "pRemoveOldBox()" */
556 void pRemoveOldBox(LIBBASETYPEPTR ps, struct PsdDevice *pd)
558 struct PsdPoPo *po = &ps->ps_PoPo;
559 struct PsdPoPoGadgets *pog;
560 // try to remove adding message, if it still existing
561 pog = (struct PsdPoPoGadgets *) po->po_GadgetList.lh_Head;
562 while(pog->pog_Node.ln_Succ)
564 if(pog->pog_Device == pd)
566 pFreePoPoGadgets(ps, pog);
567 pog = (struct PsdPoPoGadgets *) po->po_GadgetList.lh_Head;
568 } else {
569 pog = (struct PsdPoPoGadgets *) pog->pog_Node.ln_Succ;
573 /* \\\ */
575 /* /// "pGenerateAddBox()" */
576 struct PsdPoPoGadgets * pGenerateAddBox(LIBBASETYPEPTR ps, struct PsdDevice *pd, struct PsdPoPoGadgets *pog)
578 struct PsdPoPo *po = &ps->ps_PoPo;
579 STRPTR body = NULL;
580 STRPTR bindingsstr;
581 STRPTR bindinginfo;
582 STRPTR bodyinfo;
583 STRPTR wholebodyinfo;
584 STRPTR gad[4] = { NULL, NULL, NULL, NULL };
585 STRPTR lpwarn;
586 STRPTR deadwarn;
587 ULONG configstate;
588 BOOL lowpower = FALSE;
589 BOOL isdead = FALSE;
590 BOOL updatetime = FALSE;
591 STRPTR oldbody = NULL;
592 UWORD cnt;
593 ULONG methods[4] = { MUIM_PoPo_ConfigureBinding, MUIM_PoPo_ConfigureClass, MUIM_PoPo_ShutUp, MUIM_PoPo_RemInfo };
595 bindingsstr = pBindingsString(ps, pd);
596 configstate = pCheckConfigurable(ps, pd);
598 lowpower = pd->pd_Flags & PDFF_LOWPOWER;
599 isdead = pd->pd_Flags & PDFF_DEAD;
601 body = "A new USB device was detected:\n\n\33b%s\33n\n\n";
602 if(lowpower)
604 lpwarn = "\n\n\33bWARNING: Detected low power situation!";
605 } else {
606 lpwarn = "";
608 if(isdead)
610 deadwarn = "\n\n\33bWARNING: Device seems to be dead!";
611 } else {
612 deadwarn = "";
615 if(bindingsstr)
617 bindinginfo = psdCopyStrFmt("It is bound to \33b%s\33n", bindingsstr);
618 } else {
619 bindinginfo = psdCopyStr("No class seems responsible (yet)!");
621 if(!bindinginfo)
623 psdFreeVec(bindingsstr);
624 return(NULL);
626 if(!(bodyinfo = psdCopyStrFmt(body, pd->pd_ProductStr)))
628 psdFreeVec(bindingsstr);
629 psdFreeVec(bindinginfo);
630 return(NULL);
632 if(!(wholebodyinfo = psdCopyStrFmt("%s%s%s%s", bodyinfo, bindinginfo, lpwarn, deadwarn)))
634 psdFreeVec(bindingsstr);
635 psdFreeVec(bindinginfo);
636 psdFreeVec(bodyinfo);
637 return(NULL);
639 if(configstate & PPF_HasBindingGUI)
641 gad[0] = "Set Device Prefs";
643 if(configstate & PPF_HasBindConfig)
645 gad[0] = "Change Device Prefs";
647 if(configstate & PPF_HasClassGUI)
649 gad[1] = "Set Class Prefs";
651 if(configstate & PPF_HasClsConfig)
653 gad[1] = "Change Class Prefs";
655 if(isdead || lowpower)
657 gad[0] = "Disable Port";
658 methods[0] = MUIM_PoPo_DisablePort;
659 gad[1] = NULL;
661 if(isdead && (!lowpower))
663 gad[1] = "Powercycle Port";
664 methods[1] = MUIM_PoPo_PowerCyclePort;
666 gad[2] = "No PopUps!";
667 gad[3] = "Continue";
668 if(!pog)
670 pog = pAllocPoPoGadgets(ps, wholebodyinfo, gad);
671 if(pog)
673 pog->pog_Device = pd;
675 } else {
676 get(pog->pog_BodyObj, MUIA_Text_Contents, &oldbody);
677 if(strcmp(oldbody, wholebodyinfo))
679 set(pog->pog_BodyObj, MUIA_Text_Contents, wholebodyinfo);
680 updatetime = TRUE;
682 for(cnt = 0; cnt < 4; cnt++)
684 if(gad[cnt])
686 set(pog->pog_GadgetObj[cnt], MUIA_Text_Contents, gad[cnt]);
687 set(pog->pog_GadgetObj[cnt], MUIA_ShowMe, TRUE);
688 } else {
689 set(pog->pog_GadgetObj[cnt], MUIA_ShowMe, FALSE);
693 if(pog)
695 for(cnt = 0; cnt < 4; cnt++)
697 DoMethod(pog->pog_GadgetObj[cnt], MUIM_KillNotify, MUIA_Pressed);
698 if(gad[cnt])
700 DoMethod(pog->pog_GadgetObj[cnt], MUIM_Notify, MUIA_Pressed,
701 FALSE, po->po_AppObj, 5, MUIM_Application_PushMethod,
702 po->po_PoPoObj, 2, methods[cnt], pog);
707 psdFreeVec(bindingsstr);
708 psdFreeVec(bindinginfo);
709 psdFreeVec(bodyinfo);
710 psdFreeVec(wholebodyinfo);
712 /* Everything after this depends on having gadgets */
713 if(!pog)
714 return NULL;
716 /* update delay */
717 if(updatetime && pog)
719 CurrentTime(&pog->pog_TimeoutTime.tv_secs, &pog->pog_TimeoutTime.tv_micro);
720 if(ps->ps_GlobalCfg->pgc_PopupCloseDelay)
722 pog->pog_TimeoutTime.tv_secs += ps->ps_GlobalCfg->pgc_PopupCloseDelay;
723 } else {
724 pog->pog_TimeoutTime.tv_secs += 60*60*24;
728 if((ps->ps_GlobalCfg->pgc_PopupDeviceNew >= PGCP_ISNEW) && pd->pd_IsNewToMe)
730 pog->pog_ShowMe = TRUE;
732 if((ps->ps_GlobalCfg->pgc_PopupDeviceNew >= PGCP_ERROR) && (isdead || lowpower))
734 pog->pog_ShowMe = TRUE;
736 switch(ps->ps_GlobalCfg->pgc_PopupDeviceNew)
738 case PGCP_NEVER:
739 case PGCP_ERROR:
740 case PGCP_ISNEW:
741 break;
743 case PGCP_NOBINDING:
744 if(configstate & PPF_HasBinding)
746 break;
748 // break missing on purpose
749 case PGCP_HASBINDING:
750 if(configstate & PPF_HasBinding)
752 pog->pog_ShowMe = TRUE;
754 break;
756 case PGCP_ASKCONFIG:
757 if(configstate & PPF_HasBindingGUI)
759 if(!(configstate & PPF_HasBindConfig))
761 pog->pog_ShowMe = TRUE;
763 break; // don't ask, if there is an unset default class config
765 if(configstate & PPF_HasClassGUI)
767 if(!(configstate & PPF_HasClsConfig))
769 pog->pog_ShowMe = TRUE;
772 break;
774 case PGCP_CANCONFIG:
775 if(configstate & (PPF_HasClassGUI|PPF_HasBindingGUI))
777 pog->pog_ShowMe = TRUE;
779 break;
781 case PGCP_ALWAYS:
782 pog->pog_ShowMe = TRUE;
783 break;
785 default:
786 break;
788 return(pog);
790 /* \\\ */
792 /* /// "pEventHandler()" */
793 void pEventHandler(LIBBASETYPEPTR ps)
795 struct PsdPoPo *po = &ps->ps_PoPo;
796 struct PsdDevice *pd;
797 struct PsdEventNote *pen;
798 struct PsdPoPoGadgets *pog;
799 ULONG eventmask;
800 STRPTR body = NULL;
801 BOOL addsound = FALSE;
802 BOOL remsound = FALSE;
803 BOOL cfgchanged = FALSE;
805 /* delete removed devices first */
806 psdLockReadPBase();
808 pog = (struct PsdPoPoGadgets *) po->po_GadgetList.lh_Head;
809 while(pog->pog_Node.ln_Succ)
811 if(pog->pog_Device)
813 /* verify that device is still there */
814 if(!pIsDeviceStillValid(ps, pog->pog_Device))
816 /* huh, gone! */
817 pFreePoPoGadgets(ps, pog);
818 pog = (struct PsdPoPoGadgets *) po->po_GadgetList.lh_Head;
819 continue;
822 pog = (struct PsdPoPoGadgets *) pog->pog_Node.ln_Succ;
825 eventmask = 0;
826 while((pen = (struct PsdEventNote *) GetMsg(po->po_MsgPort)))
828 eventmask |= (1L<<pen->pen_Event);
829 switch(pen->pen_Event)
831 case EHMB_ADDDEVICE:
833 pd = (struct PsdDevice *) pen->pen_Param1;
834 if(pIsDeviceStillValid(ps, pd))
836 pRemoveOldBox(ps, pd);
837 if(pd->pd_PoPoCfg.poc_InhibitPopup)
839 break;
841 addsound = TRUE;
842 pog = pGenerateAddBox(ps, pd, NULL);
843 if(!pog)
845 break;
847 pog->pog_Device = pd;
848 if(pog->pog_ShowMe && (!pog->pog_WaitBinding))
850 po->po_OpenRequest = TRUE;
853 break;
856 case EHMB_DEVICEDEAD:
857 case EHMB_DEVICELOWPW:
859 BOOL lowpower = FALSE;
860 BOOL isdead = FALSE;
861 BOOL autodis = FALSE;
862 STRPTR body;
863 STRPTR devname;
864 STRPTR gads[4] = { NULL, NULL, NULL, "Ignore" };
865 STRPTR autodismsg = "";
867 pd = (struct PsdDevice *) pen->pen_Param1;
868 if(!pIsDeviceStillValid(ps, pd))
870 break;
872 lowpower = pd->pd_Flags & PDFF_LOWPOWER;
873 isdead = pd->pd_Flags & PDFF_DEAD;
874 if(!(lowpower || isdead))
876 break;
878 if((ps->ps_GlobalCfg->pgc_AutoDisableLP && lowpower) ||
879 (ps->ps_GlobalCfg->pgc_AutoDisableDead && isdead) ||
880 (ps->ps_GlobalCfg->pgc_AutoRestartDead && isdead))
882 struct Library *UsbClsBase;
883 struct PsdDevice *hubpd = pd->pd_Hub;
884 Forbid();
885 if(hubpd->pd_DevBinding)
887 UsbClsBase = hubpd->pd_ClsBinding->puc_ClassBase;
888 if(pIsClassStillValid(ps, UsbClsBase))
890 if(ps->ps_GlobalCfg->pgc_AutoRestartDead && isdead)
892 usbDoMethod((ULONG) UCM_HubPowerCyclePort, hubpd, pd->pd_HubPort);
893 psdAddErrorMsg(RETURN_WARN, ps->ps_Library.lib_Node.ln_Name,
894 "Automatically powercycling port for '%s' due to death event.",
895 pd->pd_ProductStr);
896 autodismsg = "\n\n\33bAutomatically powercycling port!\33n";
897 } else {
898 usbDoMethod((ULONG) UCM_HubDisablePort, hubpd, pd->pd_HubPort);
899 psdAddErrorMsg(RETURN_WARN, ps->ps_Library.lib_Node.ln_Name,
900 "Automatically disabling port for '%s' due lowpower/death event.",
901 pd->pd_ProductStr);
902 autodismsg = "\n\n\33bAutomatically disabling port!\33n";
904 autodis = TRUE;
907 Permit();
909 if(pd->pd_PoPoCfg.poc_InhibitPopup)
911 break;
914 remsound = TRUE;
915 if((ps->ps_GlobalCfg->pgc_PopupDeviceNew < PGCP_ERROR) && (!ps->ps_GlobalCfg->pgc_PopupDeviceDeath))
917 break;
920 pRemoveOldBox(ps, pd);
921 gads[0] = "Disable Port";
922 devname = pd->pd_ProductStr;
923 if(!devname)
925 devname = "Unknown Soldier";
927 if(lowpower && isdead)
929 body = psdCopyStrFmt("\33bWARNING: Detected LOW POWER situation\33n\n\nfor USB device\n\n\33b%s\33n\n\nand it has \33bdropped dead already\33n!%s", devname, autodismsg);
931 else if(lowpower)
933 body = psdCopyStrFmt("\33bWARNING: Detected LOW POWER situation\33n\n\nfor USB device\n\n\33b%s\33n\n\nand this might cause failures!%s", devname, autodismsg);
934 } else {
935 body = psdCopyStrFmt("\33bWARNING: DEAD DEVICE!\33n\n\nUSB device\n\n\33b%s\33n\n\ndropped dead for no apparent reason!%s", devname, autodismsg);
936 gads[1] = "Powercycle Port";
938 pog = pAllocPoPoGadgets(ps, body, gads);
939 psdFreeVec(body);
940 if(!pog)
942 break;
945 if(autodis)
947 set(pog->pog_GadgetObj[0], MUIA_Disabled, TRUE);
948 pog->pog_Device = NULL; // to keep the message on the screen
949 } else {
950 pog->pog_Device = pd;
952 DoMethod(pog->pog_GadgetObj[0], MUIM_Notify, MUIA_Pressed, FALSE,
953 po->po_AppObj, 5, MUIM_Application_PushMethod, po->po_PoPoObj, 2, MUIM_PoPo_DisablePort, pog);
954 if(gads[1])
956 DoMethod(pog->pog_GadgetObj[1], MUIM_Notify, MUIA_Pressed, FALSE,
957 po->po_AppObj, 5, MUIM_Application_PushMethod, po->po_PoPoObj, 2, MUIM_PoPo_PowerCyclePort, pog);
959 DoMethod(pog->pog_GadgetObj[3], MUIM_Notify, MUIA_Pressed, FALSE,
960 po->po_AppObj, 5, MUIM_Application_PushMethod, po->po_PoPoObj, 2, MUIM_PoPo_RemInfo, pog);
961 po->po_OpenRequest = TRUE;
962 break;
965 case EHMB_REMDEVICE:
967 pd = (struct PsdDevice *) pen->pen_Param1;
968 pRemoveOldBox(ps, pd);
969 if(pd->pd_PoPoCfg.poc_InhibitPopup)
971 break;
973 remsound = TRUE;
974 if(!ps->ps_GlobalCfg->pgc_PopupDeviceGone)
976 break;
978 if(pd->pd_ProductStr)
980 body = psdCopyStrFmt("The USB device\n\n\33b%s\33n\n\nhas been removed!", pd->pd_ProductStr);
981 /* late free */
982 //psdFreeVec(pd->pd_ProductStr);
983 //pd->pd_ProductStr = NULL;
984 } else {
985 body = psdCopyStr("An USB device has been removed,\nbut I cannot recall its name.");
987 if(body)
989 STRPTR gads[4] = { NULL, NULL, NULL, "Bye bye!" };
990 pog = pAllocPoPoGadgets(ps, body, gads);
991 psdFreeVec(body);
992 if(!pog)
994 break;
996 DoMethod(pog->pog_GadgetObj[3], MUIM_Notify, MUIA_Pressed, FALSE,
997 po->po_AppObj, 5, MUIM_Application_PushMethod, po->po_PoPoObj, 2, MUIM_PoPo_RemInfo, pog);
998 po->po_OpenRequest = TRUE;
1000 break;
1003 case EHMB_ADDBINDING:
1004 case EHMB_REMBINDING:
1006 pog = (struct PsdPoPoGadgets *) po->po_GadgetList.lh_Head;
1007 while(pog->pog_Node.ln_Succ)
1009 if(pog->pog_Device == (struct PsdDevice *) pen->pen_Param1)
1011 if(!pIsDeviceStillValid(ps, pog->pog_Device))
1013 break;
1015 if(pog->pog_Device->pd_PoPoCfg.poc_InhibitPopup)
1017 break;
1019 pGenerateAddBox(ps, pog->pog_Device, pog);
1020 if(pog->pog_ShowMe)
1022 po->po_OpenRequest = TRUE;
1024 break;
1026 pog = (struct PsdPoPoGadgets *) pog->pog_Node.ln_Succ;
1028 break;
1031 case EHMB_CONFIGCHG:
1032 if(!cfgchanged)
1034 psdDelayMS(100);
1035 cfgchanged = TRUE;
1037 break;
1040 ReplyMsg(&pen->pen_Msg);
1042 psdUnlockPBase();
1043 if(addsound)
1045 if(po->po_InsertSndFile)
1047 if(*po->po_InsertSndFile)
1049 pPoPoPlaySound(ps, po->po_InsertSndFile);
1053 if(remsound)
1055 if(po->po_RemoveSndFile)
1057 if(*po->po_RemoveSndFile)
1059 pPoPoPlaySound(ps, po->po_RemoveSndFile);
1063 if(cfgchanged)
1065 set(po->po_SaveObj, MUIA_Disabled, (ps->ps_SavedConfigHash == ps->ps_ConfigHash));
1068 /* \\\ */
1070 /* /// "pBindingsString()" */
1071 STRPTR pBindingsString(LIBBASETYPEPTR ps, struct PsdDevice *pd)
1073 STRPTR oldstr = NULL;
1074 STRPTR newstr = NULL;
1075 struct PsdConfig *pc;
1076 struct PsdInterface *pif;
1078 if(pd->pd_DevBinding)
1080 if(pd->pd_Flags & PDFF_APPBINDING)
1082 return(psdCopyStr(((struct PsdAppBinding *) pd->pd_DevBinding)->pab_Task->tc_Node.ln_Name));
1083 } else {
1084 return(psdCopyStr(pd->pd_ClsBinding->puc_ClassBase->lib_Node.ln_Name));
1086 } else {
1087 pc = (struct PsdConfig *) pd->pd_Configs.lh_Head;
1088 while(pc->pc_Node.ln_Succ)
1090 pif = (struct PsdInterface *) pc->pc_Interfaces.lh_Head;
1091 while(pif->pif_Node.ln_Succ)
1093 if(pif->pif_IfBinding)
1095 if(oldstr)
1097 newstr = psdCopyStrFmt("%s, %s", oldstr, pif->pif_ClsBinding->puc_ClassBase->lib_Node.ln_Name);
1098 psdFreeVec(oldstr),
1099 oldstr = newstr;
1100 } else {
1101 oldstr = psdCopyStr(pif->pif_ClsBinding->puc_ClassBase->lib_Node.ln_Name);
1104 pif = (struct PsdInterface *) pif->pif_Node.ln_Succ;
1106 pc = (struct PsdConfig *) pc->pc_Node.ln_Succ;
1109 return(oldstr);
1111 /* \\\ */
1113 /* /// "pCheckConfigurable()" */
1114 ULONG pCheckConfigurable(LIBBASETYPEPTR ps, struct PsdDevice *pd)
1116 ULONG hasclassgui;
1117 ULONG hasbindinggui;
1118 ULONG noconfig;
1119 struct PsdConfig *pc;
1120 struct PsdInterface *pif;
1121 struct Library *UsbClsBase;
1122 ULONG result = 0;
1124 psdLockReadPBase();
1125 if(pd->pd_DevBinding)
1127 if(!(pd->pd_Flags & PDFF_APPBINDING))
1129 UsbClsBase = pd->pd_ClsBinding->puc_ClassBase;
1130 noconfig = FALSE;
1131 hasclassgui = FALSE;
1132 hasbindinggui = FALSE;
1133 if(pIsClassStillValid(ps, UsbClsBase))
1135 usbGetAttrs(UGA_CLASS, NULL,
1136 UCCA_HasClassCfgGUI, &hasclassgui,
1137 UCCA_HasBindingCfgGUI, &hasbindinggui,
1138 UCCA_UsingDefaultCfg, &noconfig,
1139 TAG_END);
1140 result |= PPF_HasBinding;
1141 if(hasclassgui)
1143 result |= PPF_HasClassGUI;
1144 if(!noconfig)
1146 result |= PPF_HasClsConfig;
1149 if(hasbindinggui)
1151 result |= PPF_HasBindingGUI;
1152 usbGetAttrs(UGA_BINDING, pd->pd_DevBinding,
1153 UCBA_UsingDefaultCfg, &noconfig,
1154 TAG_END);
1155 if(!noconfig)
1157 result |= PPF_HasBindConfig;
1162 } else {
1163 pc = (struct PsdConfig *) pd->pd_Configs.lh_Head;
1164 while(pc->pc_Node.ln_Succ)
1166 pif = (struct PsdInterface *) pc->pc_Interfaces.lh_Head;
1167 while(pif->pif_Node.ln_Succ)
1169 if(pif->pif_IfBinding)
1171 UsbClsBase = pif->pif_ClsBinding->puc_ClassBase;
1172 noconfig = FALSE;
1173 hasclassgui = FALSE;
1174 hasbindinggui = FALSE;
1175 if(pIsClassStillValid(ps, UsbClsBase))
1177 usbGetAttrs(UGA_CLASS, NULL,
1178 UCCA_HasClassCfgGUI, &hasclassgui,
1179 UCCA_HasBindingCfgGUI, &hasbindinggui,
1180 UCCA_UsingDefaultCfg, &noconfig,
1181 TAG_END);
1182 result |= PPF_HasBinding;
1183 if(hasclassgui)
1185 result |= PPF_HasClassGUI;
1186 if(!noconfig)
1188 result |= PPF_HasClsConfig;
1191 if(hasbindinggui)
1193 result |= PPF_HasBindingGUI;
1194 usbGetAttrs(UGA_BINDING, pif->pif_IfBinding,
1195 UCBA_UsingDefaultCfg, &noconfig,
1196 TAG_END);
1197 if(!noconfig)
1199 result |= PPF_HasBindConfig;
1204 pif = (struct PsdInterface *) pif->pif_Node.ln_Succ;
1206 pc = (struct PsdConfig *) pc->pc_Node.ln_Succ;
1209 psdUnlockPBase();
1210 return(result);
1212 /* \\\ */
1214 /* /// "pOpenBindingsConfigGUI()" */
1215 void pOpenBindingsConfigGUI(LIBBASETYPEPTR ps, struct PsdDevice *pd)
1217 struct PsdConfig *pc;
1218 struct PsdInterface *pif;
1219 struct Library *UsbClsBase;
1220 ULONG hascfggui;
1221 psdLockReadPBase();
1222 if(!pIsDeviceStillValid(ps, pd))
1224 psdUnlockPBase();
1225 return;
1227 if(pd->pd_DevBinding)
1229 if(!(pd->pd_Flags & PDFF_APPBINDING))
1231 UsbClsBase = pd->pd_ClsBinding->puc_ClassBase;
1232 if(pIsClassStillValid(ps, UsbClsBase))
1234 usbGetAttrs(UGA_CLASS, NULL,
1235 UCCA_HasBindingCfgGUI, &hascfggui,
1236 TAG_END);
1237 if(hascfggui)
1239 usbDoMethod(UCM_OpenBindingCfgWindow, pd->pd_DevBinding);
1243 } else {
1244 pc = (struct PsdConfig *) pd->pd_Configs.lh_Head;
1245 while(pc->pc_Node.ln_Succ)
1247 pif = (struct PsdInterface *) pc->pc_Interfaces.lh_Head;
1248 while(pif->pif_Node.ln_Succ)
1250 if(pif->pif_IfBinding)
1252 UsbClsBase = pif->pif_ClsBinding->puc_ClassBase;
1253 if(pIsClassStillValid(ps, UsbClsBase))
1255 usbGetAttrs(UGA_CLASS, NULL,
1256 UCCA_HasBindingCfgGUI, &hascfggui,
1257 TAG_END);
1258 if(hascfggui)
1260 usbDoMethod(UCM_OpenBindingCfgWindow, pif->pif_IfBinding);
1264 pif = (struct PsdInterface *) pif->pif_Node.ln_Succ;
1266 pc = (struct PsdConfig *) pc->pc_Node.ln_Succ;
1269 psdUnlockPBase();
1271 /* \\\ */
1273 /* /// "pOpenClassesConfigGUI()" */
1274 void pOpenClassesConfigGUI(LIBBASETYPEPTR ps, struct PsdDevice *pd)
1276 struct PsdConfig *pc;
1277 struct PsdInterface *pif;
1278 struct Library *UsbClsBase;
1279 ULONG hascfggui;
1281 psdLockReadPBase();
1282 if(!pIsDeviceStillValid(ps, pd))
1284 psdUnlockPBase();
1285 return;
1288 if(pd->pd_DevBinding)
1290 if(!(pd->pd_Flags & PDFF_APPBINDING))
1292 UsbClsBase = pd->pd_ClsBinding->puc_ClassBase;
1293 if(pIsClassStillValid(ps, UsbClsBase))
1295 usbGetAttrs(UGA_CLASS, NULL,
1296 UCCA_HasClassCfgGUI, &hascfggui,
1297 TAG_END);
1298 if(hascfggui)
1300 usbDoMethod(UCM_OpenCfgWindow);
1304 } else {
1305 pc = (struct PsdConfig *) pd->pd_Configs.lh_Head;
1306 while(pc->pc_Node.ln_Succ)
1308 pif = (struct PsdInterface *) pc->pc_Interfaces.lh_Head;
1309 while(pif->pif_Node.ln_Succ)
1311 if(pif->pif_IfBinding)
1313 UsbClsBase = pif->pif_ClsBinding->puc_ClassBase;
1314 if(pIsClassStillValid(ps, UsbClsBase))
1316 usbGetAttrs(UGA_CLASS, NULL,
1317 UCCA_HasClassCfgGUI, &hascfggui,
1318 TAG_END);
1319 if(hascfggui)
1321 usbDoMethod(UCM_OpenCfgWindow);
1325 pif = (struct PsdInterface *) pif->pif_Node.ln_Succ;
1327 pc = (struct PsdConfig *) pc->pc_Node.ln_Succ;
1330 psdUnlockPBase();
1332 /* \\\ */
1334 /* /// "pDisableDevicePopup()" */
1335 void pDisableDevicePopup(LIBBASETYPEPTR ps, struct PsdDevice *pd)
1337 if(!pIsDeviceStillValid(ps, pd))
1339 return;
1341 psdSetAttrs(PGA_DEVICE, pd, DA_InhibitPopup, TRUE, TAG_END);
1343 /* \\\ */
1345 /* /// "pAllocPoPoGadgets()" */
1346 struct PsdPoPoGadgets * pAllocPoPoGadgets(LIBBASETYPEPTR ps, STRPTR body, STRPTR *gad)
1348 struct PsdPoPo *po = &ps->ps_PoPo;
1349 struct PsdPoPoGadgets *pog;
1350 if((pog = (struct PsdPoPoGadgets *) psdAllocVec(sizeof(struct PsdPoPoGadgets))))
1352 pog->pog_GroupObj =
1353 VGroup,
1354 Child, (IPTR)(pog->pog_BodyObj = TextObject,
1355 MUIA_Frame, MUIV_Frame_Text,
1356 MUIA_Background, MUII_TextBack,
1357 MUIA_Text_PreParse, (IPTR)"\33c",
1358 MUIA_Text_Contents, (IPTR)body,
1359 End),
1360 Child, (IPTR)(HGroup,
1361 MUIA_Group_SameWidth, TRUE,
1362 Child, (IPTR)(pog->pog_GadgetObj[0] = TextObject, ButtonFrame,
1363 MUIA_Background, MUII_ButtonBack,
1364 MUIA_CycleChain, 1,
1365 MUIA_InputMode, MUIV_InputMode_RelVerify,
1366 MUIA_Text_PreParse, (IPTR)"\33c",
1367 MUIA_Text_Contents, (IPTR)(gad[0] ? gad[0] : (STRPTR) ""),
1368 MUIA_ShowMe, (IPTR)gad[0],
1369 End),
1370 Child, (IPTR)(pog->pog_GadgetObj[1] = TextObject, ButtonFrame,
1371 MUIA_Background, MUII_ButtonBack,
1372 MUIA_CycleChain, 1,
1373 MUIA_InputMode, MUIV_InputMode_RelVerify,
1374 MUIA_Text_PreParse, (IPTR)"\33c",
1375 MUIA_Text_Contents, (IPTR)(gad[1] ? gad[1] : (STRPTR) ""),
1376 MUIA_ShowMe, (IPTR)gad[1],
1377 End),
1378 Child, (IPTR)(pog->pog_GadgetObj[2] = TextObject, ButtonFrame,
1379 MUIA_Background, MUII_ButtonBack,
1380 MUIA_CycleChain, 1,
1381 MUIA_InputMode, MUIV_InputMode_RelVerify,
1382 MUIA_Text_PreParse, (IPTR)"\33c",
1383 MUIA_Text_Contents, (IPTR)(gad[2] ? gad[2] : (STRPTR) ""),
1384 MUIA_ShowMe, (IPTR)gad[2],
1385 End),
1386 Child, (IPTR)(pog->pog_GadgetObj[3] = TextObject, ButtonFrame,
1387 MUIA_Background, MUII_ButtonBack,
1388 MUIA_CycleChain, 1,
1389 MUIA_InputMode, MUIV_InputMode_RelVerify,
1390 MUIA_Text_PreParse, (IPTR)"\33c",
1391 MUIA_Text_Contents, (IPTR)(gad[3] ? gad[3] : (STRPTR) ""),
1392 MUIA_ShowMe, (IPTR)gad[3],
1393 End),
1394 End),
1395 //Child, VSpace(0),
1396 Child, (IPTR)(BalanceObject,
1397 End),
1398 //Child, VSpace(0),
1399 End;
1401 if(!pog->pog_GroupObj)
1403 psdFreeVec(pog);
1404 return(NULL);
1406 DoMethod(po->po_GroupObj, MUIM_Group_InitChange);
1407 DoMethod(po->po_GroupObj, OM_ADDMEMBER, pog->pog_GroupObj);
1408 DoMethod(po->po_GroupObj, MUIM_Group_ExitChange);
1409 AddTail(&po->po_GadgetList, &pog->pog_Node);
1410 CurrentTime(&pog->pog_TimeoutTime.tv_secs, &pog->pog_TimeoutTime.tv_micro);
1411 if(ps->ps_GlobalCfg->pgc_PopupCloseDelay && (!po->po_Sticky))
1413 pog->pog_TimeoutTime.tv_secs += ps->ps_GlobalCfg->pgc_PopupCloseDelay;
1414 } else {
1415 pog->pog_TimeoutTime.tv_secs += 60*60*24;
1418 return(pog);
1420 /* \\\ */
1422 /* /// "pFreePoPoGadgets()" */
1423 void pFreePoPoGadgets(LIBBASETYPEPTR ps, struct PsdPoPoGadgets *pog)
1425 struct PsdPoPo *po = &ps->ps_PoPo;
1426 Remove(&pog->pog_Node);
1427 DoMethod(po->po_GroupObj, MUIM_Group_InitChange);
1428 DoMethod(po->po_GroupObj, OM_REMMEMBER, pog->pog_GroupObj);
1429 DoMethod(po->po_GroupObj, MUIM_Group_ExitChange);
1430 MUI_DisposeObject(pog->pog_GroupObj);
1431 psdFreeVec(pog);
1433 /* \\\ */
1435 /* /// "PoPoDispatcher()" */
1436 AROS_UFH3(IPTR, PoPoDispatcher,
1437 AROS_UFHA(struct IClass *, cl, A0),
1438 AROS_UFHA(Object *, obj, A2),
1439 AROS_UFHA(Msg, msg, A1))
1441 AROS_USERFUNC_INIT
1442 struct PsdPoPoGadgets *pog;
1443 struct PsdPoPoGadgets *tmppog;
1444 LIBBASETYPEPTR ps = (LIBBASETYPEPTR) cl->cl_UserData;
1445 struct PsdPoPo *po = &ps->ps_PoPo;
1446 ULONG sticky = 0;
1448 switch(msg->MethodID)
1450 case OM_NEW:
1451 if(!(obj = (Object *)DoSuperMethodA(cl,obj,msg)))
1452 return(0);
1453 return((IPTR)obj);
1455 case MUIM_PoPo_SavePrefs:
1456 psdSaveCfgToDisk(NULL, FALSE);
1457 set(po->po_SaveObj, MUIA_Disabled, (ps->ps_SavedConfigHash == ps->ps_ConfigHash));
1458 return(0);
1460 case MUIM_PoPo_Sticky:
1461 get(po->po_StickyObj, MUIA_Selected, &sticky);
1462 po->po_Sticky = sticky;
1463 pog = (struct PsdPoPoGadgets *) po->po_GadgetList.lh_Head;
1464 while(pog->pog_Node.ln_Succ)
1466 CurrentTime(&pog->pog_TimeoutTime.tv_secs, &pog->pog_TimeoutTime.tv_micro);
1467 if(ps->ps_GlobalCfg->pgc_PopupCloseDelay && (!po->po_Sticky))
1469 pog->pog_TimeoutTime.tv_secs += ps->ps_GlobalCfg->pgc_PopupCloseDelay;
1470 } else {
1471 pog->pog_TimeoutTime.tv_secs += 60*60*24;
1473 pog = (struct PsdPoPoGadgets *) pog->pog_Node.ln_Succ;
1475 return(0);
1477 case MUIM_PoPo_ConfigureBinding:
1478 pog = (struct PsdPoPoGadgets *) ((IPTR *) msg)[1];
1479 //KPRINTF(20, ("Config Po=%08lx, Pog=%08lx, PS=%08lx\n", po, pog, ps));
1480 pog->pog_TimeoutTime.tv_secs += 60*60*24;
1481 pOpenBindingsConfigGUI(ps, pog->pog_Device);
1482 return(0);
1484 case MUIM_PoPo_ConfigureClass:
1485 pog = (struct PsdPoPoGadgets *) ((IPTR *) msg)[1];
1486 //KPRINTF(20, ("Config Po=%08lx, Pog=%08lx, PS=%08lx\n", po, pog, ps));
1487 pog->pog_TimeoutTime.tv_secs += 60*60*24;
1488 pOpenClassesConfigGUI(ps, pog->pog_Device);
1489 return(0);
1491 case MUIM_PoPo_ShutUp:
1492 pog = (struct PsdPoPoGadgets *) ((IPTR *) msg)[1];
1493 pDisableDevicePopup(ps, pog->pog_Device);
1494 pRemoveOldBox(ps, pog->pog_Device);
1495 return(0);
1497 case MUIM_PoPo_RemInfo:
1498 pog = (struct PsdPoPoGadgets *) ((IPTR *) msg)[1];
1499 //KPRINTF(20, ("RemInfo Po=%08lx, Pog=%08lx, PS=%08lx\n", po, pog, ps));
1500 tmppog = (struct PsdPoPoGadgets *) po->po_GadgetList.lh_Head;
1501 while(tmppog->pog_Node.ln_Succ)
1503 if(tmppog == pog)
1505 pFreePoPoGadgets(ps, pog);
1506 break;
1508 tmppog = (struct PsdPoPoGadgets *) tmppog->pog_Node.ln_Succ;
1510 return(0);
1512 case MUIM_PoPo_DisablePort:
1513 case MUIM_PoPo_PowerCyclePort:
1515 struct PsdDevice *pd;
1516 struct Library *UsbClsBase;
1517 BOOL disable = (msg->MethodID == MUIM_PoPo_DisablePort);
1519 pog = (struct PsdPoPoGadgets *) ((IPTR *) msg)[1];
1520 pd = pog->pog_Device;
1521 set(pog->pog_GadgetObj[0], MUIA_Disabled, TRUE);
1522 if(pog->pog_GadgetObj[1] && (!disable))
1524 set(pog->pog_GadgetObj[1], MUIA_Disabled, TRUE);
1526 Forbid();
1527 if(pIsDeviceStillValid(ps, pd))
1529 struct PsdDevice *hubpd = pd->pd_Hub;
1530 if(hubpd->pd_DevBinding)
1532 UsbClsBase = hubpd->pd_ClsBinding->puc_ClassBase;
1533 if(pIsClassStillValid(ps, UsbClsBase))
1535 usbDoMethod((ULONG) (disable ? UCM_HubDisablePort : UCM_HubPowerCyclePort), hubpd, pd->pd_HubPort);
1539 Permit();
1540 pog->pog_TimeoutTime.tv_secs += 60*60*24;
1542 return(0);
1545 case MUIM_PoPo_About:
1546 MUI_RequestA(po->po_AppObj, po->po_WindowObj, 0, NULL, "Blimey!", "PoPo -- The Poseidon Popup Provider\n\nWritten by Chris Hodges.\n\nWichtig ist, was hinten rauskommt (Helmut Kohl).", NULL);
1547 return(0);
1549 case MUIM_PoPo_OpenTrident:
1551 struct Library *DOSBase;
1552 if((DOSBase = OpenLibrary("dos.library", 39)))
1554 BPTR fhandle;
1555 if((fhandle = Open("NIL:", MODE_READWRITE)))
1557 if(SystemTags("Trident",
1558 NP_StackSize, 32*1024,
1559 SYS_Input, fhandle,
1560 SYS_Output, NULL,
1561 SYS_Asynch, TRUE,
1562 TAG_END))
1564 Close(fhandle);
1565 MUI_RequestA(po->po_AppObj, po->po_WindowObj, 0, NULL, "Oh no!", "Bugger!\n\nI tried hard to load Trident,\nbut there was Cryptonite somewhere!", NULL);
1568 CloseLibrary(DOSBase);
1570 return(0);
1573 return(DoSuperMethodA(cl,obj,msg));
1574 AROS_USERFUNC_EXIT
1576 /* \\\ */