Don't dereference null pointer if gadgets can't be allocated.
[AROS.git] / rom / usb / poseidon / popo.gui.c
blob75d987f3aaed1e2d56e59535fcef0430a6047fc0
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 #define __NOLIBBASE__
15 #include <proto/alib.h>
16 #include <proto/muimaster.h>
17 #include <proto/exec.h>
18 #include <proto/dos.h>
19 #include <proto/datatypes.h>
20 #include <proto/intuition.h>
21 #include <proto/utility.h>
22 #include <proto/usbclass.h>
24 #include "numtostr.h"
26 #define NewList NEWLIST
28 #include "popo.gui.h"
30 #include <stdarg.h>
32 #define MUIMasterBase po->po_MUIBase
33 #define DataTypesBase po->po_DTBase
34 #define IntuitionBase po->po_IntBase
36 extern struct ExecBase *SysBase;
38 /* /// "pPoPoGUITask()" */
39 AROS_UFH0(void, pPoPoGUITask)
41 AROS_USERFUNC_INIT
42 struct Task *thistask;
43 LIBBASETYPEPTR ps;
44 struct PsdPoPo *po;
45 struct List *scrlist;
46 struct PubScreenNode *pubscr;
47 BOOL hasworkbench = FALSE;
49 thistask = FindTask(NULL);
51 ps = thistask->tc_UserData;
52 SetTaskPri(thistask, 0);
53 po = &ps->ps_PoPo;
55 NewList(&po->po_GadgetList);
56 NewList(&po->po_Sounds);
58 if(!(IntuitionBase = OpenLibrary("intuition.library", 39)))
60 KPRINTF(10, ("Couldn't open intuition.library.\n"));
61 pPoPoGUITaskCleanup(ps);
62 return;
65 scrlist = LockPubScreenList();
66 pubscr = (struct PubScreenNode *) scrlist->lh_Head;
67 while(pubscr->psn_Node.ln_Succ)
69 if(strcmp(pubscr->psn_Node.ln_Name, "Workbench") == 0)
71 if(pubscr->psn_Screen)
73 hasworkbench = TRUE;
75 break;
77 pubscr = (struct PubScreenNode *) pubscr->psn_Node.ln_Succ;
79 UnlockPubScreenList();
81 if(!hasworkbench)
83 KPRINTF(10, ("No screen open yet.\n"));
84 pPoPoGUITaskCleanup(ps);
85 return;
88 if(!(MUIMasterBase = OpenLibrary(MUIMASTER_NAME, MUIMASTER_VMIN)))
90 KPRINTF(10, ("Couldn't open muimaster.library.\n"));
91 pPoPoGUITaskCleanup(ps);
92 return;
95 if(!(DataTypesBase = OpenLibrary("datatypes.library", 39)))
97 KPRINTF(10, ("Couldn't open datatypes.library.\n"));
98 pPoPoGUITaskCleanup(ps);
99 return;
102 if(!(po->po_MsgPort = CreateMsgPort()))
104 KPRINTF(10, ("Couldn't create MsgPort.\n"));
105 pPoPoGUITaskCleanup(ps);
106 return;
109 po->po_EventHandler = psdAddEventHandler(po->po_MsgPort, EHMF_ADDDEVICE|EHMF_REMDEVICE|EHMF_ADDBINDING|EHMF_CONFIGCHG|EHMF_DEVICEDEAD|EHMF_DEVICELOWPW);
110 if(!po->po_EventHandler)
112 KPRINTF(10, ("Couldn't add EventHandler.\n"));
113 pPoPoGUITaskCleanup(ps);
114 return;
117 if(!(po->po_TimerMsgPort = CreateMsgPort()))
119 KPRINTF(10, ("Couldn't create MsgPort.\n"));
120 pPoPoGUITaskCleanup(ps);
121 return;
124 if(!(po->po_TimerIOReq = (struct timerequest *) CreateIORequest(po->po_TimerMsgPort, sizeof(struct timerequest))))
126 KPRINTF(10, ("Couldn't create TimerIOReq.\n"));
127 pPoPoGUITaskCleanup(ps);
128 return;
131 if(OpenDevice("timer.device", UNIT_VBLANK, (struct IORequest *) po->po_TimerIOReq, 0))
133 KPRINTF(10, ("Couldn't open timer.device.\n"));
134 pPoPoGUITaskCleanup(ps);
135 return;
137 po->po_TimerIOReq->tr_node.io_Message.mn_Node.ln_Type = NT_REPLYMSG;
138 po->po_TimerIOReq->tr_node.io_Message.mn_Node.ln_Name = "PoPo";
139 po->po_TimerIOReq->tr_node.io_Command = TR_ADDREQUEST;
141 if(!(po->po_PoPoClass = MUI_CreateCustomClass(NULL, MUIC_Area, NULL, sizeof(struct PoPoData), PoPoDispatcher)))
143 KPRINTF(10, ("Couldn't create PoPo Class\n"));
144 pPoPoGUITaskCleanup(ps);
145 return;
147 po->po_PoPoClass->mcc_Class->cl_UserData = (IPTR) ps;
149 po->po_AppObj = ApplicationObject,
150 MUIA_Application_Title , (IPTR)"PoPo -- Poseidon Popup Provider",
151 MUIA_Application_Version , (IPTR)VERSION_STRING,
152 MUIA_Application_Copyright , (IPTR)"©2004-2009 Chris Hodges",
153 MUIA_Application_Author , (IPTR)"Chris Hodges <chrisly@platon42.de>",
154 MUIA_Application_Description, (IPTR)"Opens annoying windows",
155 MUIA_Application_Base , (IPTR)"POPO",
156 MUIA_Application_HelpFile , (IPTR)"HELP:Poseidon.guide",
157 MUIA_Application_Menustrip , (IPTR)MenustripObject,
158 Child, (IPTR)MenuObjectT((IPTR)"Project"),
159 Child, (IPTR)(po->po_AboutMI = MenuitemObject,
160 MUIA_Menuitem_Title, (IPTR)"About...",
161 MUIA_Menuitem_Shortcut, (IPTR)"?",
162 End),
163 Child, (IPTR)MenuitemObject,
164 MUIA_Menuitem_Title, (IPTR)NM_BARLABEL,
165 End,
166 Child, (IPTR)(po->po_CloseMI = MenuitemObject,
167 MUIA_Menuitem_Title, (IPTR)"Close",
168 MUIA_Menuitem_Shortcut, (IPTR)"Q",
169 End),
170 End,
171 Child, (IPTR)MenuObjectT((IPTR)"Settings"),
172 Child, (IPTR)(po->po_TridentMI = MenuitemObject,
173 MUIA_Menuitem_Title, (IPTR)"Open Trident",
174 MUIA_Menuitem_Shortcut, (IPTR)"O",
175 End),
176 Child, (IPTR)MenuitemObject,
177 MUIA_Menuitem_Title, (IPTR)NM_BARLABEL,
178 End,
179 Child, (IPTR)(po->po_MUIPrefsMI = MenuitemObject,
180 MUIA_Menuitem_Title, (IPTR)"MUI Settings",
181 MUIA_Menuitem_Shortcut, (IPTR)"M",
182 End),
183 End,
184 End,
186 SubWindow, (IPTR)(po->po_WindowObj = WindowObject,
187 MUIA_Window_ID , MAKE_ID('P','O','P','O'),
188 MUIA_Window_Title, (IPTR)"Poseidon Popups",
189 MUIA_HelpNode, (IPTR)"main",
191 WindowContents, (IPTR)VGroup,
192 Child, (IPTR)(po->po_PoPoObj = NewObject(po->po_PoPoClass->mcc_Class, 0, MUIA_ShowMe, FALSE, TAG_END)),
193 Child, (IPTR)(po->po_GroupObj = VGroup,
194 Child, (IPTR)HGroup,
195 Child, (IPTR)HSpace(0),
196 Child, (IPTR)Label("Messages"),
197 Child, (IPTR)HSpace(0),
198 End,
199 End),
200 Child, (IPTR)HGroup,
201 Child, (IPTR)(po->po_StickyObj = ImageObject, ImageButtonFrame,
202 MUIA_Background, MUII_ButtonBack,
203 MUIA_CycleChain, 1,
204 MUIA_InputMode, MUIV_InputMode_Toggle,
205 MUIA_Image_Spec, MUII_CheckMark,
206 MUIA_Image_FreeVert, TRUE,
207 MUIA_Selected, FALSE,
208 MUIA_ShowSelState, FALSE,
209 End),
210 Child, (IPTR)Label("Hold on"),
211 Child, (IPTR)HGroup,
212 MUIA_Group_SameWidth, TRUE,
213 Child, (IPTR)(po->po_SaveObj = TextObject, ButtonFrame,
214 MUIA_Disabled, (ps->ps_SavedConfigHash == ps->ps_ConfigHash),
215 MUIA_Background, MUII_ButtonBack,
216 MUIA_CycleChain, 1,
217 MUIA_InputMode, MUIV_InputMode_RelVerify,
218 MUIA_Text_Contents, (IPTR)"\33c Save Prefs ",
219 End),
220 Child, (IPTR)(po->po_CloseObj = TextObject, ButtonFrame,
221 MUIA_Background, MUII_ButtonBack,
222 MUIA_CycleChain, 1,
223 MUIA_InputMode, MUIV_InputMode_RelVerify,
224 MUIA_Text_Contents, (IPTR)"\33c Close ",
225 End),
226 End,
227 End,
228 End,
229 End),
230 End;
232 if(!po->po_AppObj)
234 KPRINTF(10, ("Couldn't create application\n"));
235 pPoPoGUITaskCleanup(ps);
236 return;
239 DoMethod(po->po_WindowObj, MUIM_Notify, MUIA_Window_CloseRequest, TRUE,
240 po->po_AppObj, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit);
241 DoMethod(po->po_SaveObj, MUIM_Notify, MUIA_Pressed, FALSE,
242 po->po_PoPoObj, 1, MUIM_PoPo_SavePrefs);
243 DoMethod(po->po_CloseObj, MUIM_Notify, MUIA_Pressed, FALSE,
244 po->po_AppObj, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit);
245 DoMethod(po->po_StickyObj, MUIM_Notify, MUIA_Selected, MUIV_EveryTime,
246 po->po_PoPoObj, 1, MUIM_PoPo_Sticky);
248 DoMethod(po->po_AboutMI, MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime,
249 po->po_PoPoObj, 1, MUIM_PoPo_About);
250 DoMethod(po->po_CloseMI, MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime,
251 po->po_AppObj, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit);
252 DoMethod(po->po_TridentMI, MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime,
253 po->po_PoPoObj, 1, MUIM_PoPo_OpenTrident);
254 DoMethod(po->po_MUIPrefsMI, MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime,
255 po->po_AppObj, 2, MUIM_Application_OpenConfigWindow, 0);
259 BOOL isopen = FALSE;
260 ULONG sigs;
261 ULONG sigmask;
262 LONG retid;
263 struct PsdPoPoGadgets *pog;
264 struct timeval currtime;
266 po->po_Task = thistask;
267 Forbid();
268 if(po->po_ReadySigTask)
270 Signal(po->po_ReadySigTask, 1L<<po->po_ReadySignal);
272 Permit();
274 //set(po->po_WindowObj, MUIA_Window_Open, TRUE);
275 po->po_TimerIOReq->tr_time.tv_micro = 500*1000;
276 SendIO(&po->po_TimerIOReq->tr_node);
277 sigmask = (1UL<<po->po_MsgPort->mp_SigBit)|(1UL<<po->po_TimerMsgPort->mp_SigBit);
280 retid = DoMethod(po->po_AppObj, MUIM_Application_NewInput, &sigs);
281 if(sigs)
283 pEventHandler(ps);
284 if(CheckIO(&po->po_TimerIOReq->tr_node))
286 WaitIO(&po->po_TimerIOReq->tr_node);
287 po->po_TimerIOReq->tr_time.tv_micro = 500*1000;
288 SendIO(&po->po_TimerIOReq->tr_node);
290 CurrentTime(&currtime.tv_secs, &currtime.tv_micro);
291 pog = (struct PsdPoPoGadgets *) po->po_GadgetList.lh_Head;
292 while(pog->pog_Node.ln_Succ)
294 if((currtime.tv_secs > pog->pog_TimeoutTime.tv_secs) ||
295 ((currtime.tv_secs == pog->pog_TimeoutTime.tv_secs) &&
296 (currtime.tv_micro > pog->pog_TimeoutTime.tv_micro)))
298 pFreePoPoGadgets(ps, pog);
299 pog = (struct PsdPoPoGadgets *) po->po_GadgetList.lh_Head;
300 } else {
301 pog = (struct PsdPoPoGadgets *) pog->pog_Node.ln_Succ;
305 if(po->po_GadgetList.lh_Head->ln_Succ)
307 if(po->po_OpenRequest)
309 if(!isopen)
311 if(ps->ps_GlobalCfg->pgc_PopupActivateWin)
313 set(po->po_WindowObj, MUIA_Window_Activate, TRUE);
314 } else {
315 set(po->po_WindowObj, MUIA_Window_Activate, FALSE);
317 set(po->po_StickyObj, MUIA_Selected, FALSE);
318 set(po->po_WindowObj, MUIA_Window_Open, TRUE);
319 isopen = TRUE;
320 } else {
321 if(ps->ps_GlobalCfg->pgc_PopupWinToFront)
323 DoMethod(po->po_WindowObj, MUIM_Window_ToFront);
326 po->po_OpenRequest = FALSE;
328 } else {
329 if(isopen)
331 set(po->po_WindowObj, MUIA_Window_Open, FALSE);
332 isopen = FALSE;
336 sigs = Wait(sigs | sigmask | SIGBREAKF_CTRL_C);
337 if(sigs & SIGBREAKF_CTRL_C)
339 break;
342 if(retid == MUIV_Application_ReturnID_Quit)
344 set(po->po_WindowObj, MUIA_Window_Open, FALSE);
345 /* remove all thingies */
346 pog = (struct PsdPoPoGadgets *) po->po_GadgetList.lh_Head;
347 while(pog->pog_Node.ln_Succ)
349 pFreePoPoGadgets(ps, pog);
350 pog = (struct PsdPoPoGadgets *) po->po_GadgetList.lh_Head;
353 if((ps->ps_GlobalCfg->pgc_PopupDeviceNew == PGCP_NEVER) &&
354 (!ps->ps_GlobalCfg->pgc_PopupDeviceDeath) &&
355 (!ps->ps_GlobalCfg->pgc_PopupDeviceGone))
357 psdAddErrorMsg0(RETURN_OK, (STRPTR) "PoPo", "PoPo has been abandoned (is it you, stuntzi?).");
358 break;
361 } while(TRUE);
362 set(po->po_WindowObj, MUIA_Window_Open, FALSE);
364 pPoPoGUITaskCleanup(ps);
365 AROS_USERFUNC_EXIT
367 /* \\\ */
369 /* /// "pPoPoGUITaskCleanup()" */
370 void pPoPoGUITaskCleanup(LIBBASETYPEPTR ps)
372 struct PsdPoPo *po = &ps->ps_PoPo;
373 struct PsdPoPoGadgets *pog;
374 struct PsdPoPoSound *pps;
376 pog = (struct PsdPoPoGadgets *) po->po_GadgetList.lh_Head;
377 while(pog->pog_Node.ln_Succ)
379 pFreePoPoGadgets(ps, pog);
380 pog = (struct PsdPoPoGadgets *) po->po_GadgetList.lh_Head;
383 pps = (struct PsdPoPoSound *) po->po_Sounds.lh_Head;
384 while(pps->pps_Node.ln_Succ)
386 pPoPoFreeSound(ps, pps);
387 pps = (struct PsdPoPoSound *) po->po_Sounds.lh_Head;
390 if(po->po_TimerIOReq)
392 if(po->po_TimerIOReq->tr_node.io_Device)
394 AbortIO(&po->po_TimerIOReq->tr_node);
395 WaitIO(&po->po_TimerIOReq->tr_node);
396 CloseDevice((struct IORequest *) po->po_TimerIOReq);
398 DeleteIORequest((struct IORequest *) po->po_TimerIOReq);
399 po->po_TimerIOReq = NULL;
401 if(po->po_TimerMsgPort)
403 DeleteMsgPort(po->po_TimerMsgPort);
404 po->po_TimerMsgPort = NULL;
407 if(po->po_EventHandler)
409 psdRemEventHandler(po->po_EventHandler);
410 po->po_EventHandler = NULL;
412 if(po->po_MsgPort)
414 DeleteMsgPort(po->po_MsgPort);
415 po->po_MsgPort = NULL;
417 if(po->po_AppObj)
419 MUI_DisposeObject(po->po_AppObj);
420 po->po_AppObj = NULL;
422 if(po->po_PoPoClass)
424 MUI_DeleteCustomClass(po->po_PoPoClass);
425 po->po_PoPoClass = NULL;
427 if(DataTypesBase)
429 CloseLibrary(DataTypesBase);
430 DataTypesBase = NULL;
432 if(MUIMasterBase)
434 CloseLibrary(MUIMasterBase);
435 MUIMasterBase = NULL;
437 if(IntuitionBase)
439 CloseLibrary(IntuitionBase);
440 IntuitionBase = NULL;
442 Forbid();
443 po->po_Task = NULL;
444 if(po->po_ReadySigTask)
446 Signal(po->po_ReadySigTask, 1L<<po->po_ReadySignal);
449 /* \\\ */
451 /* /// "pPoPoLoadSound()" */
452 struct PsdPoPoSound * pPoPoLoadSound(LIBBASETYPEPTR ps, STRPTR name)
454 struct PsdPoPo *po = &ps->ps_PoPo;
455 struct PsdPoPoSound *pps;
456 if((pps = psdAllocVec(sizeof(struct PsdPoPoSound))))
458 if((pps->pps_Node.ln_Name = psdCopyStr(name)))
460 AddTail(&po->po_Sounds, &pps->pps_Node);
461 pps->pps_DTHandle = NewDTObject(name,
462 DTA_SourceType, DTST_FILE,
463 DTA_GroupID, GID_SOUND,
464 SDTA_Cycles, 1L,
465 TAG_END);
466 if(!pps->pps_DTHandle)
468 psdAddErrorMsg(RETURN_ERROR, "PoPo", "Could not load soundfile '%s'.", name);
470 return(pps);
472 psdFreeVec(pps);
474 return(NULL);
476 /* \\\ */
478 /* /// "pPoPoPlaySound()" */
479 BOOL pPoPoPlaySound(LIBBASETYPEPTR ps, STRPTR name)
481 struct PsdPoPo *po = &ps->ps_PoPo;
482 struct PsdPoPoSound *pps;
483 struct dtTrigger playmsg;
485 pps = (struct PsdPoPoSound *) FindName(&po->po_Sounds, name);
486 if(!pps)
488 pps = pPoPoLoadSound(ps, name);
490 if(!pps)
492 return(FALSE);
494 if(!pps->pps_DTHandle)
496 return(FALSE);
499 SetAttrs(pps->pps_DTHandle,
500 SDTA_Volume, 64,
501 TAG_END);
502 playmsg.MethodID = DTM_TRIGGER;
503 playmsg.dtt_GInfo = NULL;
504 playmsg.dtt_Function = STM_PLAY;
505 playmsg.dtt_Data = NULL;
506 DoMethodA(pps->pps_DTHandle, (Msg) &playmsg);
507 return(TRUE);
509 /* \\\ */
511 /* /// "pPoPoFreeSound()" */
512 void pPoPoFreeSound(LIBBASETYPEPTR ps, struct PsdPoPoSound *pps)
514 struct PsdPoPo *po = &ps->ps_PoPo;
515 Remove(&pps->pps_Node);
516 if(pps->pps_DTHandle)
518 DisposeDTObject(pps->pps_DTHandle);
520 psdFreeVec(pps->pps_Node.ln_Name);
521 psdFreeVec(pps);
523 /* \\\ */
525 /* /// "pIsDeviceStillValid()" */
526 BOOL pIsDeviceStillValid(LIBBASETYPEPTR ps, struct PsdDevice *pd)
528 struct PsdDevice *tmppd = NULL;
529 while((tmppd = psdGetNextDevice(tmppd)))
531 if(tmppd == pd)
533 return(TRUE);
536 return(FALSE);
538 /* \\\ */
540 /* /// "pIsClassStillValid()" */
541 BOOL pIsClassStillValid(LIBBASETYPEPTR ps, struct Library *ucb)
543 struct PsdUsbClass *puc = (struct PsdUsbClass *) ps->ps_Classes.lh_Head;
544 while(puc->puc_Node.ln_Succ)
546 if(puc->puc_ClassBase == ucb)
548 return(TRUE);
550 puc = (struct PsdUsbClass *) puc->puc_Node.ln_Succ;
552 return(FALSE);
554 /* \\\ */
556 /* /// "pRemoveOldBox()" */
557 void pRemoveOldBox(LIBBASETYPEPTR ps, struct PsdDevice *pd)
559 struct PsdPoPo *po = &ps->ps_PoPo;
560 struct PsdPoPoGadgets *pog;
561 // try to remove adding message, if it still existing
562 pog = (struct PsdPoPoGadgets *) po->po_GadgetList.lh_Head;
563 while(pog->pog_Node.ln_Succ)
565 if(pog->pog_Device == pd)
567 pFreePoPoGadgets(ps, pog);
568 pog = (struct PsdPoPoGadgets *) po->po_GadgetList.lh_Head;
569 } else {
570 pog = (struct PsdPoPoGadgets *) pog->pog_Node.ln_Succ;
574 /* \\\ */
576 /* /// "pGenerateAddBox()" */
577 struct PsdPoPoGadgets * pGenerateAddBox(LIBBASETYPEPTR ps, struct PsdDevice *pd, struct PsdPoPoGadgets *pog)
579 struct PsdPoPo *po = &ps->ps_PoPo;
580 STRPTR body = NULL;
581 STRPTR bindingsstr;
582 STRPTR bindinginfo;
583 STRPTR bodyinfo;
584 STRPTR wholebodyinfo;
585 STRPTR gad[4] = { NULL, NULL, NULL, NULL };
586 STRPTR lpwarn;
587 STRPTR deadwarn;
588 ULONG configstate;
589 BOOL lowpower = FALSE;
590 BOOL isdead = FALSE;
591 BOOL updatetime = FALSE;
592 STRPTR oldbody = NULL;
593 UWORD cnt;
594 ULONG methods[4] = { MUIM_PoPo_ConfigureBinding, MUIM_PoPo_ConfigureClass, MUIM_PoPo_ShutUp, MUIM_PoPo_RemInfo };
596 bindingsstr = pBindingsString(ps, pd);
597 configstate = pCheckConfigurable(ps, pd);
599 lowpower = pd->pd_Flags & PDFF_LOWPOWER;
600 isdead = pd->pd_Flags & PDFF_DEAD;
602 body = "A new USB device was detected:\n\n\33b%s\33n\n\n";
603 if(lowpower)
605 lpwarn = "\n\n\33bWARNING: Detected low power situation!";
606 } else {
607 lpwarn = "";
609 if(isdead)
611 deadwarn = "\n\n\33bWARNING: Device seems to be dead!";
612 } else {
613 deadwarn = "";
616 if(bindingsstr)
618 bindinginfo = psdCopyStrFmt("It is bound to \33b%s\33n", bindingsstr);
619 } else {
620 bindinginfo = psdCopyStr("No class seems responsible (yet)!");
622 if(!bindinginfo)
624 psdFreeVec(bindingsstr);
625 return(NULL);
627 if(!(bodyinfo = psdCopyStrFmt(body, pd->pd_ProductStr)))
629 psdFreeVec(bindingsstr);
630 psdFreeVec(bindinginfo);
631 return(NULL);
633 if(!(wholebodyinfo = psdCopyStrFmt("%s%s%s%s", bodyinfo, bindinginfo, lpwarn, deadwarn)))
635 psdFreeVec(bindingsstr);
636 psdFreeVec(bindinginfo);
637 psdFreeVec(bodyinfo);
638 return(NULL);
640 if(configstate & PPF_HasBindingGUI)
642 gad[0] = "Set Device Prefs";
644 if(configstate & PPF_HasBindConfig)
646 gad[0] = "Change Device Prefs";
648 if(configstate & PPF_HasClassGUI)
650 gad[1] = "Set Class Prefs";
652 if(configstate & PPF_HasClsConfig)
654 gad[1] = "Change Class Prefs";
656 if(isdead || lowpower)
658 gad[0] = "Disable Port";
659 methods[0] = MUIM_PoPo_DisablePort;
660 gad[1] = NULL;
662 if(isdead && (!lowpower))
664 gad[1] = "Powercycle Port";
665 methods[1] = MUIM_PoPo_PowerCyclePort;
667 gad[2] = "No PopUps!";
668 gad[3] = "Continue";
669 if(!pog)
671 pog = pAllocPoPoGadgets(ps, wholebodyinfo, gad);
672 if(pog)
674 pog->pog_Device = pd;
676 } else {
677 get(pog->pog_BodyObj, MUIA_Text_Contents, &oldbody);
678 if(strcmp(oldbody, wholebodyinfo))
680 set(pog->pog_BodyObj, MUIA_Text_Contents, wholebodyinfo);
681 updatetime = TRUE;
683 for(cnt = 0; cnt < 4; cnt++)
685 if(gad[cnt])
687 set(pog->pog_GadgetObj[cnt], MUIA_Text_Contents, gad[cnt]);
688 set(pog->pog_GadgetObj[cnt], MUIA_ShowMe, TRUE);
689 } else {
690 set(pog->pog_GadgetObj[cnt], MUIA_ShowMe, FALSE);
694 if(pog)
696 for(cnt = 0; cnt < 4; cnt++)
698 DoMethod(pog->pog_GadgetObj[cnt], MUIM_KillNotify, MUIA_Pressed);
699 if(gad[cnt])
701 DoMethod(pog->pog_GadgetObj[cnt], MUIM_Notify, MUIA_Pressed,
702 FALSE, po->po_AppObj, 5, MUIM_Application_PushMethod,
703 po->po_PoPoObj, 2, methods[cnt], pog);
708 psdFreeVec(bindingsstr);
709 psdFreeVec(bindinginfo);
710 psdFreeVec(bodyinfo);
711 psdFreeVec(wholebodyinfo);
713 /* Everything after this depends on having gadgets */
714 if(!pog)
715 return NULL;
717 /* update delay */
718 if(updatetime && pog)
720 CurrentTime(&pog->pog_TimeoutTime.tv_secs, &pog->pog_TimeoutTime.tv_micro);
721 if(ps->ps_GlobalCfg->pgc_PopupCloseDelay)
723 pog->pog_TimeoutTime.tv_secs += ps->ps_GlobalCfg->pgc_PopupCloseDelay;
724 } else {
725 pog->pog_TimeoutTime.tv_secs += 60*60*24;
729 if((ps->ps_GlobalCfg->pgc_PopupDeviceNew >= PGCP_ISNEW) && pd->pd_IsNewToMe)
731 pog->pog_ShowMe = TRUE;
733 if((ps->ps_GlobalCfg->pgc_PopupDeviceNew >= PGCP_ERROR) && (isdead || lowpower))
735 pog->pog_ShowMe = TRUE;
737 switch(ps->ps_GlobalCfg->pgc_PopupDeviceNew)
739 case PGCP_NEVER:
740 case PGCP_ERROR:
741 case PGCP_ISNEW:
742 break;
744 case PGCP_NOBINDING:
745 if(configstate & PPF_HasBinding)
747 break;
749 // break missing on purpose
750 case PGCP_HASBINDING:
751 if(configstate & PPF_HasBinding)
753 pog->pog_ShowMe = TRUE;
755 break;
757 case PGCP_ASKCONFIG:
758 if(configstate & PPF_HasBindingGUI)
760 if(!(configstate & PPF_HasBindConfig))
762 pog->pog_ShowMe = TRUE;
764 break; // don't ask, if there is an unset default class config
766 if(configstate & PPF_HasClassGUI)
768 if(!(configstate & PPF_HasClsConfig))
770 pog->pog_ShowMe = TRUE;
773 break;
775 case PGCP_CANCONFIG:
776 if(configstate & (PPF_HasClassGUI|PPF_HasBindingGUI))
778 pog->pog_ShowMe = TRUE;
780 break;
782 case PGCP_ALWAYS:
783 pog->pog_ShowMe = TRUE;
784 break;
786 default:
787 break;
789 return(pog);
791 /* \\\ */
793 /* /// "pEventHandler()" */
794 void pEventHandler(LIBBASETYPEPTR ps)
796 struct PsdPoPo *po = &ps->ps_PoPo;
797 struct PsdDevice *pd;
798 struct PsdEventNote *pen;
799 struct PsdPoPoGadgets *pog;
800 ULONG eventmask;
801 STRPTR body = NULL;
802 BOOL addsound = FALSE;
803 BOOL remsound = FALSE;
804 BOOL cfgchanged = FALSE;
806 /* delete removed devices first */
807 psdLockReadPBase();
809 pog = (struct PsdPoPoGadgets *) po->po_GadgetList.lh_Head;
810 while(pog->pog_Node.ln_Succ)
812 if(pog->pog_Device)
814 /* verify that device is still there */
815 if(!pIsDeviceStillValid(ps, pog->pog_Device))
817 /* huh, gone! */
818 pFreePoPoGadgets(ps, pog);
819 pog = (struct PsdPoPoGadgets *) po->po_GadgetList.lh_Head;
820 continue;
823 pog = (struct PsdPoPoGadgets *) pog->pog_Node.ln_Succ;
826 eventmask = 0;
827 while((pen = (struct PsdEventNote *) GetMsg(po->po_MsgPort)))
829 eventmask |= (1L<<pen->pen_Event);
830 switch(pen->pen_Event)
832 case EHMB_ADDDEVICE:
834 pd = (struct PsdDevice *) pen->pen_Param1;
835 if(pIsDeviceStillValid(ps, pd))
837 pRemoveOldBox(ps, pd);
838 if(pd->pd_PoPoCfg.poc_InhibitPopup)
840 break;
842 addsound = TRUE;
843 pog = pGenerateAddBox(ps, pd, NULL);
844 if(!pog)
846 break;
848 pog->pog_Device = pd;
849 if(pog->pog_ShowMe && (!pog->pog_WaitBinding))
851 po->po_OpenRequest = TRUE;
854 break;
857 case EHMB_DEVICEDEAD:
858 case EHMB_DEVICELOWPW:
860 BOOL lowpower = FALSE;
861 BOOL isdead = FALSE;
862 BOOL autodis = FALSE;
863 STRPTR body;
864 STRPTR devname;
865 STRPTR gads[4] = { NULL, NULL, NULL, "Ignore" };
866 STRPTR autodismsg = "";
868 pd = (struct PsdDevice *) pen->pen_Param1;
869 if(!pIsDeviceStillValid(ps, pd))
871 break;
873 lowpower = pd->pd_Flags & PDFF_LOWPOWER;
874 isdead = pd->pd_Flags & PDFF_DEAD;
875 if(!(lowpower || isdead))
877 break;
879 if((ps->ps_GlobalCfg->pgc_AutoDisableLP && lowpower) ||
880 (ps->ps_GlobalCfg->pgc_AutoDisableDead && isdead) ||
881 (ps->ps_GlobalCfg->pgc_AutoRestartDead && isdead))
883 struct Library *UsbClsBase;
884 struct PsdDevice *hubpd = pd->pd_Hub;
885 Forbid();
886 if(hubpd->pd_DevBinding)
888 UsbClsBase = hubpd->pd_ClsBinding->puc_ClassBase;
889 if(pIsClassStillValid(ps, UsbClsBase))
891 if(ps->ps_GlobalCfg->pgc_AutoRestartDead && isdead)
893 usbDoMethod((ULONG) UCM_HubPowerCyclePort, hubpd, pd->pd_HubPort);
894 psdAddErrorMsg(RETURN_WARN, ps->ps_Library.lib_Node.ln_Name,
895 "Automatically powercycling port for '%s' due to death event.",
896 pd->pd_ProductStr);
897 autodismsg = "\n\n\33bAutomatically powercycling port!\33n";
898 } else {
899 usbDoMethod((ULONG) UCM_HubDisablePort, hubpd, pd->pd_HubPort);
900 psdAddErrorMsg(RETURN_WARN, ps->ps_Library.lib_Node.ln_Name,
901 "Automatically disabling port for '%s' due lowpower/death event.",
902 pd->pd_ProductStr);
903 autodismsg = "\n\n\33bAutomatically disabling port!\33n";
905 autodis = TRUE;
908 Permit();
910 if(pd->pd_PoPoCfg.poc_InhibitPopup)
912 break;
915 remsound = TRUE;
916 if((ps->ps_GlobalCfg->pgc_PopupDeviceNew < PGCP_ERROR) && (!ps->ps_GlobalCfg->pgc_PopupDeviceDeath))
918 break;
921 pRemoveOldBox(ps, pd);
922 gads[0] = "Disable Port";
923 devname = pd->pd_ProductStr;
924 if(!devname)
926 devname = "Unknown Soldier";
928 if(lowpower && isdead)
930 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);
932 else if(lowpower)
934 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);
935 } else {
936 body = psdCopyStrFmt("\33bWARNING: DEAD DEVICE!\33n\n\nUSB device\n\n\33b%s\33n\n\ndropped dead for no apparent reason!%s", devname, autodismsg);
937 gads[1] = "Powercycle Port";
939 pog = pAllocPoPoGadgets(ps, body, gads);
940 psdFreeVec(body);
941 if(!pog)
943 break;
946 if(autodis)
948 set(pog->pog_GadgetObj[0], MUIA_Disabled, TRUE);
949 pog->pog_Device = NULL; // to keep the message on the screen
950 } else {
951 pog->pog_Device = pd;
953 DoMethod(pog->pog_GadgetObj[0], MUIM_Notify, MUIA_Pressed, FALSE,
954 po->po_AppObj, 5, MUIM_Application_PushMethod, po->po_PoPoObj, 2, MUIM_PoPo_DisablePort, pog);
955 if(gads[1])
957 DoMethod(pog->pog_GadgetObj[1], MUIM_Notify, MUIA_Pressed, FALSE,
958 po->po_AppObj, 5, MUIM_Application_PushMethod, po->po_PoPoObj, 2, MUIM_PoPo_PowerCyclePort, pog);
960 DoMethod(pog->pog_GadgetObj[3], MUIM_Notify, MUIA_Pressed, FALSE,
961 po->po_AppObj, 5, MUIM_Application_PushMethod, po->po_PoPoObj, 2, MUIM_PoPo_RemInfo, pog);
962 po->po_OpenRequest = TRUE;
963 break;
966 case EHMB_REMDEVICE:
968 pd = (struct PsdDevice *) pen->pen_Param1;
969 pRemoveOldBox(ps, pd);
970 if(pd->pd_PoPoCfg.poc_InhibitPopup)
972 break;
974 remsound = TRUE;
975 if(!ps->ps_GlobalCfg->pgc_PopupDeviceGone)
977 break;
979 if(pd->pd_ProductStr)
981 body = psdCopyStrFmt("The USB device\n\n\33b%s\33n\n\nhas been removed!", pd->pd_ProductStr);
982 /* late free */
983 //psdFreeVec(pd->pd_ProductStr);
984 //pd->pd_ProductStr = NULL;
985 } else {
986 body = psdCopyStr("An USB device has been removed,\nbut I cannot recall its name.");
988 if(body)
990 STRPTR gads[4] = { NULL, NULL, NULL, "Bye bye!" };
991 pog = pAllocPoPoGadgets(ps, body, gads);
992 psdFreeVec(body);
993 if(!pog)
995 break;
997 DoMethod(pog->pog_GadgetObj[3], MUIM_Notify, MUIA_Pressed, FALSE,
998 po->po_AppObj, 5, MUIM_Application_PushMethod, po->po_PoPoObj, 2, MUIM_PoPo_RemInfo, pog);
999 po->po_OpenRequest = TRUE;
1001 break;
1004 case EHMB_ADDBINDING:
1005 case EHMB_REMBINDING:
1007 pog = (struct PsdPoPoGadgets *) po->po_GadgetList.lh_Head;
1008 while(pog->pog_Node.ln_Succ)
1010 if(pog->pog_Device == (struct PsdDevice *) pen->pen_Param1)
1012 if(!pIsDeviceStillValid(ps, pog->pog_Device))
1014 break;
1016 if(pog->pog_Device->pd_PoPoCfg.poc_InhibitPopup)
1018 break;
1020 pGenerateAddBox(ps, pog->pog_Device, pog);
1021 if(pog->pog_ShowMe)
1023 po->po_OpenRequest = TRUE;
1025 break;
1027 pog = (struct PsdPoPoGadgets *) pog->pog_Node.ln_Succ;
1029 break;
1032 case EHMB_CONFIGCHG:
1033 if(!cfgchanged)
1035 psdDelayMS(100);
1036 cfgchanged = TRUE;
1038 break;
1041 ReplyMsg(&pen->pen_Msg);
1043 psdUnlockPBase();
1044 if(addsound)
1046 if(po->po_InsertSndFile)
1048 if(*po->po_InsertSndFile)
1050 pPoPoPlaySound(ps, po->po_InsertSndFile);
1054 if(remsound)
1056 if(po->po_RemoveSndFile)
1058 if(*po->po_RemoveSndFile)
1060 pPoPoPlaySound(ps, po->po_RemoveSndFile);
1064 if(cfgchanged)
1066 set(po->po_SaveObj, MUIA_Disabled, (ps->ps_SavedConfigHash == ps->ps_ConfigHash));
1069 /* \\\ */
1071 /* /// "pBindingsString()" */
1072 STRPTR pBindingsString(LIBBASETYPEPTR ps, struct PsdDevice *pd)
1074 STRPTR oldstr = NULL;
1075 STRPTR newstr = NULL;
1076 struct PsdConfig *pc;
1077 struct PsdInterface *pif;
1079 if(pd->pd_DevBinding)
1081 if(pd->pd_Flags & PDFF_APPBINDING)
1083 return(psdCopyStr(((struct PsdAppBinding *) pd->pd_DevBinding)->pab_Task->tc_Node.ln_Name));
1084 } else {
1085 return(psdCopyStr(pd->pd_ClsBinding->puc_ClassBase->lib_Node.ln_Name));
1087 } else {
1088 pc = (struct PsdConfig *) pd->pd_Configs.lh_Head;
1089 while(pc->pc_Node.ln_Succ)
1091 pif = (struct PsdInterface *) pc->pc_Interfaces.lh_Head;
1092 while(pif->pif_Node.ln_Succ)
1094 if(pif->pif_IfBinding)
1096 if(oldstr)
1098 newstr = psdCopyStrFmt("%s, %s", oldstr, pif->pif_ClsBinding->puc_ClassBase->lib_Node.ln_Name);
1099 psdFreeVec(oldstr),
1100 oldstr = newstr;
1101 } else {
1102 oldstr = psdCopyStr(pif->pif_ClsBinding->puc_ClassBase->lib_Node.ln_Name);
1105 pif = (struct PsdInterface *) pif->pif_Node.ln_Succ;
1107 pc = (struct PsdConfig *) pc->pc_Node.ln_Succ;
1110 return(oldstr);
1112 /* \\\ */
1114 /* /// "pCheckConfigurable()" */
1115 ULONG pCheckConfigurable(LIBBASETYPEPTR ps, struct PsdDevice *pd)
1117 ULONG hasclassgui;
1118 ULONG hasbindinggui;
1119 ULONG noconfig;
1120 struct PsdConfig *pc;
1121 struct PsdInterface *pif;
1122 struct Library *UsbClsBase;
1123 ULONG result = 0;
1125 psdLockReadPBase();
1126 if(pd->pd_DevBinding)
1128 if(!(pd->pd_Flags & PDFF_APPBINDING))
1130 UsbClsBase = pd->pd_ClsBinding->puc_ClassBase;
1131 noconfig = FALSE;
1132 hasclassgui = FALSE;
1133 hasbindinggui = FALSE;
1134 if(pIsClassStillValid(ps, UsbClsBase))
1136 usbGetAttrs(UGA_CLASS, NULL,
1137 UCCA_HasClassCfgGUI, &hasclassgui,
1138 UCCA_HasBindingCfgGUI, &hasbindinggui,
1139 UCCA_UsingDefaultCfg, &noconfig,
1140 TAG_END);
1141 result |= PPF_HasBinding;
1142 if(hasclassgui)
1144 result |= PPF_HasClassGUI;
1145 if(!noconfig)
1147 result |= PPF_HasClsConfig;
1150 if(hasbindinggui)
1152 result |= PPF_HasBindingGUI;
1153 usbGetAttrs(UGA_BINDING, pd->pd_DevBinding,
1154 UCBA_UsingDefaultCfg, &noconfig,
1155 TAG_END);
1156 if(!noconfig)
1158 result |= PPF_HasBindConfig;
1163 } else {
1164 pc = (struct PsdConfig *) pd->pd_Configs.lh_Head;
1165 while(pc->pc_Node.ln_Succ)
1167 pif = (struct PsdInterface *) pc->pc_Interfaces.lh_Head;
1168 while(pif->pif_Node.ln_Succ)
1170 if(pif->pif_IfBinding)
1172 UsbClsBase = pif->pif_ClsBinding->puc_ClassBase;
1173 noconfig = FALSE;
1174 hasclassgui = FALSE;
1175 hasbindinggui = FALSE;
1176 if(pIsClassStillValid(ps, UsbClsBase))
1178 usbGetAttrs(UGA_CLASS, NULL,
1179 UCCA_HasClassCfgGUI, &hasclassgui,
1180 UCCA_HasBindingCfgGUI, &hasbindinggui,
1181 UCCA_UsingDefaultCfg, &noconfig,
1182 TAG_END);
1183 result |= PPF_HasBinding;
1184 if(hasclassgui)
1186 result |= PPF_HasClassGUI;
1187 if(!noconfig)
1189 result |= PPF_HasClsConfig;
1192 if(hasbindinggui)
1194 result |= PPF_HasBindingGUI;
1195 usbGetAttrs(UGA_BINDING, pif->pif_IfBinding,
1196 UCBA_UsingDefaultCfg, &noconfig,
1197 TAG_END);
1198 if(!noconfig)
1200 result |= PPF_HasBindConfig;
1205 pif = (struct PsdInterface *) pif->pif_Node.ln_Succ;
1207 pc = (struct PsdConfig *) pc->pc_Node.ln_Succ;
1210 psdUnlockPBase();
1211 return(result);
1213 /* \\\ */
1215 /* /// "pOpenBindingsConfigGUI()" */
1216 void pOpenBindingsConfigGUI(LIBBASETYPEPTR ps, struct PsdDevice *pd)
1218 struct PsdConfig *pc;
1219 struct PsdInterface *pif;
1220 struct Library *UsbClsBase;
1221 ULONG hascfggui;
1222 psdLockReadPBase();
1223 if(!pIsDeviceStillValid(ps, pd))
1225 psdUnlockPBase();
1226 return;
1228 if(pd->pd_DevBinding)
1230 if(!(pd->pd_Flags & PDFF_APPBINDING))
1232 UsbClsBase = pd->pd_ClsBinding->puc_ClassBase;
1233 if(pIsClassStillValid(ps, UsbClsBase))
1235 usbGetAttrs(UGA_CLASS, NULL,
1236 UCCA_HasBindingCfgGUI, &hascfggui,
1237 TAG_END);
1238 if(hascfggui)
1240 usbDoMethod(UCM_OpenBindingCfgWindow, pd->pd_DevBinding);
1244 } else {
1245 pc = (struct PsdConfig *) pd->pd_Configs.lh_Head;
1246 while(pc->pc_Node.ln_Succ)
1248 pif = (struct PsdInterface *) pc->pc_Interfaces.lh_Head;
1249 while(pif->pif_Node.ln_Succ)
1251 if(pif->pif_IfBinding)
1253 UsbClsBase = pif->pif_ClsBinding->puc_ClassBase;
1254 if(pIsClassStillValid(ps, UsbClsBase))
1256 usbGetAttrs(UGA_CLASS, NULL,
1257 UCCA_HasBindingCfgGUI, &hascfggui,
1258 TAG_END);
1259 if(hascfggui)
1261 usbDoMethod(UCM_OpenBindingCfgWindow, pif->pif_IfBinding);
1265 pif = (struct PsdInterface *) pif->pif_Node.ln_Succ;
1267 pc = (struct PsdConfig *) pc->pc_Node.ln_Succ;
1270 psdUnlockPBase();
1272 /* \\\ */
1274 /* /// "pOpenClassesConfigGUI()" */
1275 void pOpenClassesConfigGUI(LIBBASETYPEPTR ps, struct PsdDevice *pd)
1277 struct PsdConfig *pc;
1278 struct PsdInterface *pif;
1279 struct Library *UsbClsBase;
1280 ULONG hascfggui;
1282 psdLockReadPBase();
1283 if(!pIsDeviceStillValid(ps, pd))
1285 psdUnlockPBase();
1286 return;
1289 if(pd->pd_DevBinding)
1291 if(!(pd->pd_Flags & PDFF_APPBINDING))
1293 UsbClsBase = pd->pd_ClsBinding->puc_ClassBase;
1294 if(pIsClassStillValid(ps, UsbClsBase))
1296 usbGetAttrs(UGA_CLASS, NULL,
1297 UCCA_HasClassCfgGUI, &hascfggui,
1298 TAG_END);
1299 if(hascfggui)
1301 usbDoMethod(UCM_OpenCfgWindow);
1305 } else {
1306 pc = (struct PsdConfig *) pd->pd_Configs.lh_Head;
1307 while(pc->pc_Node.ln_Succ)
1309 pif = (struct PsdInterface *) pc->pc_Interfaces.lh_Head;
1310 while(pif->pif_Node.ln_Succ)
1312 if(pif->pif_IfBinding)
1314 UsbClsBase = pif->pif_ClsBinding->puc_ClassBase;
1315 if(pIsClassStillValid(ps, UsbClsBase))
1317 usbGetAttrs(UGA_CLASS, NULL,
1318 UCCA_HasClassCfgGUI, &hascfggui,
1319 TAG_END);
1320 if(hascfggui)
1322 usbDoMethod(UCM_OpenCfgWindow);
1326 pif = (struct PsdInterface *) pif->pif_Node.ln_Succ;
1328 pc = (struct PsdConfig *) pc->pc_Node.ln_Succ;
1331 psdUnlockPBase();
1333 /* \\\ */
1335 /* /// "pDisableDevicePopup()" */
1336 void pDisableDevicePopup(LIBBASETYPEPTR ps, struct PsdDevice *pd)
1338 if(!pIsDeviceStillValid(ps, pd))
1340 return;
1342 psdSetAttrs(PGA_DEVICE, pd, DA_InhibitPopup, TRUE, TAG_END);
1344 /* \\\ */
1346 /* /// "pAllocPoPoGadgets()" */
1347 struct PsdPoPoGadgets * pAllocPoPoGadgets(LIBBASETYPEPTR ps, STRPTR body, STRPTR *gad)
1349 struct PsdPoPo *po = &ps->ps_PoPo;
1350 struct PsdPoPoGadgets *pog;
1351 if((pog = (struct PsdPoPoGadgets *) psdAllocVec(sizeof(struct PsdPoPoGadgets))))
1353 pog->pog_GroupObj =
1354 VGroup,
1355 Child, (IPTR)(pog->pog_BodyObj = TextObject,
1356 MUIA_Frame, MUIV_Frame_Text,
1357 MUIA_Background, MUII_TextBack,
1358 MUIA_Text_PreParse, (IPTR)"\33c",
1359 MUIA_Text_Contents, (IPTR)body,
1360 End),
1361 Child, (IPTR)(HGroup,
1362 MUIA_Group_SameWidth, TRUE,
1363 Child, (IPTR)(pog->pog_GadgetObj[0] = TextObject, ButtonFrame,
1364 MUIA_Background, MUII_ButtonBack,
1365 MUIA_CycleChain, 1,
1366 MUIA_InputMode, MUIV_InputMode_RelVerify,
1367 MUIA_Text_PreParse, (IPTR)"\33c",
1368 MUIA_Text_Contents, (IPTR)(gad[0] ? gad[0] : (STRPTR) ""),
1369 MUIA_ShowMe, (IPTR)gad[0],
1370 End),
1371 Child, (IPTR)(pog->pog_GadgetObj[1] = TextObject, ButtonFrame,
1372 MUIA_Background, MUII_ButtonBack,
1373 MUIA_CycleChain, 1,
1374 MUIA_InputMode, MUIV_InputMode_RelVerify,
1375 MUIA_Text_PreParse, (IPTR)"\33c",
1376 MUIA_Text_Contents, (IPTR)(gad[1] ? gad[1] : (STRPTR) ""),
1377 MUIA_ShowMe, (IPTR)gad[1],
1378 End),
1379 Child, (IPTR)(pog->pog_GadgetObj[2] = TextObject, ButtonFrame,
1380 MUIA_Background, MUII_ButtonBack,
1381 MUIA_CycleChain, 1,
1382 MUIA_InputMode, MUIV_InputMode_RelVerify,
1383 MUIA_Text_PreParse, (IPTR)"\33c",
1384 MUIA_Text_Contents, (IPTR)(gad[2] ? gad[2] : (STRPTR) ""),
1385 MUIA_ShowMe, (IPTR)gad[2],
1386 End),
1387 Child, (IPTR)(pog->pog_GadgetObj[3] = TextObject, ButtonFrame,
1388 MUIA_Background, MUII_ButtonBack,
1389 MUIA_CycleChain, 1,
1390 MUIA_InputMode, MUIV_InputMode_RelVerify,
1391 MUIA_Text_PreParse, (IPTR)"\33c",
1392 MUIA_Text_Contents, (IPTR)(gad[3] ? gad[3] : (STRPTR) ""),
1393 MUIA_ShowMe, (IPTR)gad[3],
1394 End),
1395 End,
1396 //Child, VSpace(0),
1397 Child, (IPTR)BalanceObject,
1398 End),
1399 //Child, VSpace(0),
1400 End;
1402 if(!pog->pog_GroupObj)
1404 psdFreeVec(pog);
1405 return(NULL);
1407 DoMethod(po->po_GroupObj, MUIM_Group_InitChange);
1408 DoMethod(po->po_GroupObj, OM_ADDMEMBER, pog->pog_GroupObj);
1409 DoMethod(po->po_GroupObj, MUIM_Group_ExitChange);
1410 AddTail(&po->po_GadgetList, &pog->pog_Node);
1411 CurrentTime(&pog->pog_TimeoutTime.tv_secs, &pog->pog_TimeoutTime.tv_micro);
1412 if(ps->ps_GlobalCfg->pgc_PopupCloseDelay && (!po->po_Sticky))
1414 pog->pog_TimeoutTime.tv_secs += ps->ps_GlobalCfg->pgc_PopupCloseDelay;
1415 } else {
1416 pog->pog_TimeoutTime.tv_secs += 60*60*24;
1419 return(pog);
1421 /* \\\ */
1423 /* /// "pFreePoPoGadgets()" */
1424 void pFreePoPoGadgets(LIBBASETYPEPTR ps, struct PsdPoPoGadgets *pog)
1426 struct PsdPoPo *po = &ps->ps_PoPo;
1427 Remove(&pog->pog_Node);
1428 DoMethod(po->po_GroupObj, MUIM_Group_InitChange);
1429 DoMethod(po->po_GroupObj, OM_REMMEMBER, pog->pog_GroupObj);
1430 DoMethod(po->po_GroupObj, MUIM_Group_ExitChange);
1431 MUI_DisposeObject(pog->pog_GroupObj);
1432 psdFreeVec(pog);
1434 /* \\\ */
1436 /* /// "PoPoDispatcher()" */
1437 AROS_UFH3(IPTR, PoPoDispatcher,
1438 AROS_UFHA(struct IClass *, cl, A0),
1439 AROS_UFHA(Object *, obj, A2),
1440 AROS_UFHA(Msg, msg, A1))
1442 AROS_USERFUNC_INIT
1443 struct PsdPoPoGadgets *pog;
1444 struct PsdPoPoGadgets *tmppog;
1445 LIBBASETYPEPTR ps = (LIBBASETYPEPTR) cl->cl_UserData;
1446 struct PsdPoPo *po = &ps->ps_PoPo;
1447 ULONG sticky = 0;
1449 switch(msg->MethodID)
1451 case OM_NEW:
1452 if(!(obj = (Object *)DoSuperMethodA(cl,obj,msg)))
1453 return(0);
1454 return((IPTR)obj);
1456 case MUIM_PoPo_SavePrefs:
1457 psdSaveCfgToDisk(NULL, FALSE);
1458 set(po->po_SaveObj, MUIA_Disabled, (ps->ps_SavedConfigHash == ps->ps_ConfigHash));
1459 return(0);
1461 case MUIM_PoPo_Sticky:
1462 get(po->po_StickyObj, MUIA_Selected, &sticky);
1463 po->po_Sticky = sticky;
1464 pog = (struct PsdPoPoGadgets *) po->po_GadgetList.lh_Head;
1465 while(pog->pog_Node.ln_Succ)
1467 CurrentTime(&pog->pog_TimeoutTime.tv_secs, &pog->pog_TimeoutTime.tv_micro);
1468 if(ps->ps_GlobalCfg->pgc_PopupCloseDelay && (!po->po_Sticky))
1470 pog->pog_TimeoutTime.tv_secs += ps->ps_GlobalCfg->pgc_PopupCloseDelay;
1471 } else {
1472 pog->pog_TimeoutTime.tv_secs += 60*60*24;
1474 pog = (struct PsdPoPoGadgets *) pog->pog_Node.ln_Succ;
1476 return(0);
1478 case MUIM_PoPo_ConfigureBinding:
1479 pog = (struct PsdPoPoGadgets *) ((IPTR *) msg)[1];
1480 //KPRINTF(20, ("Config Po=%08lx, Pog=%08lx, PS=%08lx\n", po, pog, ps));
1481 pog->pog_TimeoutTime.tv_secs += 60*60*24;
1482 pOpenBindingsConfigGUI(ps, pog->pog_Device);
1483 return(0);
1485 case MUIM_PoPo_ConfigureClass:
1486 pog = (struct PsdPoPoGadgets *) ((IPTR *) msg)[1];
1487 //KPRINTF(20, ("Config Po=%08lx, Pog=%08lx, PS=%08lx\n", po, pog, ps));
1488 pog->pog_TimeoutTime.tv_secs += 60*60*24;
1489 pOpenClassesConfigGUI(ps, pog->pog_Device);
1490 return(0);
1492 case MUIM_PoPo_ShutUp:
1493 pog = (struct PsdPoPoGadgets *) ((IPTR *) msg)[1];
1494 pDisableDevicePopup(ps, pog->pog_Device);
1495 pRemoveOldBox(ps, pog->pog_Device);
1496 return(0);
1498 case MUIM_PoPo_RemInfo:
1499 pog = (struct PsdPoPoGadgets *) ((IPTR *) msg)[1];
1500 //KPRINTF(20, ("RemInfo Po=%08lx, Pog=%08lx, PS=%08lx\n", po, pog, ps));
1501 tmppog = (struct PsdPoPoGadgets *) po->po_GadgetList.lh_Head;
1502 while(tmppog->pog_Node.ln_Succ)
1504 if(tmppog == pog)
1506 pFreePoPoGadgets(ps, pog);
1507 break;
1509 tmppog = (struct PsdPoPoGadgets *) tmppog->pog_Node.ln_Succ;
1511 return(0);
1513 case MUIM_PoPo_DisablePort:
1514 case MUIM_PoPo_PowerCyclePort:
1516 struct PsdDevice *pd;
1517 struct Library *UsbClsBase;
1518 BOOL disable = (msg->MethodID == MUIM_PoPo_DisablePort);
1520 pog = (struct PsdPoPoGadgets *) ((IPTR *) msg)[1];
1521 pd = pog->pog_Device;
1522 set(pog->pog_GadgetObj[0], MUIA_Disabled, TRUE);
1523 if(pog->pog_GadgetObj[1] && (!disable))
1525 set(pog->pog_GadgetObj[1], MUIA_Disabled, TRUE);
1527 Forbid();
1528 if(pIsDeviceStillValid(ps, pd))
1530 struct PsdDevice *hubpd = pd->pd_Hub;
1531 if(hubpd->pd_DevBinding)
1533 UsbClsBase = hubpd->pd_ClsBinding->puc_ClassBase;
1534 if(pIsClassStillValid(ps, UsbClsBase))
1536 usbDoMethod((ULONG) (disable ? UCM_HubDisablePort : UCM_HubPowerCyclePort), hubpd, pd->pd_HubPort);
1540 Permit();
1541 pog->pog_TimeoutTime.tv_secs += 60*60*24;
1543 return(0);
1546 case MUIM_PoPo_About:
1547 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);
1548 return(0);
1550 case MUIM_PoPo_OpenTrident:
1552 struct Library *DOSBase;
1553 if((DOSBase = OpenLibrary("dos.library", 39)))
1555 BPTR fhandle;
1556 if((fhandle = Open("NIL:", MODE_READWRITE)))
1558 if(SystemTags("Trident",
1559 NP_StackSize, 32*1024,
1560 SYS_Input, fhandle,
1561 SYS_Output, NULL,
1562 SYS_Asynch, TRUE,
1563 TAG_END))
1565 Close(fhandle);
1566 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);
1569 CloseLibrary(DOSBase);
1571 return(0);
1574 return(DoSuperMethodA(cl,obj,msg));
1575 AROS_USERFUNC_EXIT
1577 /* \\\ */