1 /* Copyright 2007-2012 Fredrik Wikstrom. All rights reserved.
3 ** Redistribution and use in source and binary forms, with or without
4 ** modification, are permitted provided that the following conditions
7 ** 1. Redistributions of source code must retain the above copyright
8 ** notice, this list of conditions and the following disclaimer.
10 ** 2. Redistributions in binary form must reproduce the above copyright
11 ** notice, this list of conditions and the following disclaimer in the
12 ** documentation and/or other materials provided with the distribution.
14 ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
15 ** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 ** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 ** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
18 ** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19 ** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20 ** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 ** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22 ** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23 ** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24 ** POSSIBILITY OF SUCH DAMAGE.
27 #include "diskimagegui.h"
28 #include <proto/exec.h>
29 #include <proto/dos.h>
30 #include <proto/intuition.h>
31 #include <proto/muimaster.h>
32 #include <proto/icon.h>
33 #include <proto/commodities.h>
34 #include <proto/diskimage.h>
35 #include <clib/alib_protos.h>
39 #include "rev/DiskImageGUI_rev.h"
43 #include <aros/debug.h>
48 CONST TEXT USED verstag
[] = VERSTAG
;
50 struct LocaleInfo LocaleInfo
;
51 BYTE DiskChangeSignal
= -1;
52 BYTE ReloadPluginsSignal
= -1;
53 struct DiskObject
*Icon
;
54 struct FileRequester
*FileReq
;
55 struct MUI_CustomClass
*DriveListClass
;
56 struct MUI_CustomClass
*PluginListClass
;
58 HOOKPROTO(BrokerFunc
, IPTR
, Object
*app
, CxMsg
*msg
);
59 MakeHook(BrokerHook
, BrokerFunc
);
60 HOOKPROTO(MenuFunc
, IPTR
, Object
*app
, IPTR
*params
);
61 MakeHook(MenuHook
, MenuFunc
);
62 HOOKPROTO(SignalFunc
, IPTR
, APTR unused
, IPTR
*params
);
63 MakeHook(SignalHook
, SignalFunc
);
66 IPTR DiskChangeParams
[2];
67 struct Hook
*DiskChangeHook
= NULL
;
68 IPTR ReloadPluginsParams
[2];
69 struct Hook
*ReloadPluginsHook
= NULL
;
72 InitLocaleInfo((struct Library
*)SysBase
, &LocaleInfo
, "System/System/"PROGNAME
".catalog");
74 DiskChangeSignal
= AllocSignal(-1);
75 if (DiskChangeSignal
== -1) {
79 ReloadPluginsSignal
= AllocSignal(-1);
80 if (ReloadPluginsSignal
== -1) {
84 Icon
= GetDiskObjectNew("PROGDIR:"PROGNAME
);
91 FileReq
= MUI_AllocAslRequestTags(ASL_FileRequest
,
92 ASLFR_SleepWindow
, TRUE
,
93 ASLFR_InitialDrawer
, TTString(Icon
, "FILEDIR", ""),
94 ASLFR_DoSaveMode
, FALSE
,
95 ASLFR_DoPatterns
, TRUE
,
96 ASLFR_InitialPattern
, TTString(Icon
, "PATTERN", "#?"),
102 DriveListClass
= DriveList_CreateClass();
103 if (!DriveListClass
) {
107 PluginListClass
= PluginList_CreateClass();
108 if (!PluginListClass
) {
112 D(bug("Got Classes\n"));
114 if (!OpenDiskImageDevice(~0)) {
118 D(bug("diskimage.device opened\n"));
124 D(bug("GUI Created\n"));
126 DiskChangeParams
[0] = (IPTR
)FindTask(NULL
);
127 DiskChangeParams
[1] = (1UL << DiskChangeSignal
);
128 DiskChangeHook
= CreateHook((HOOKFUNC
)SignalFunc
, DiskChangeParams
);
129 if (!DiskChangeHook
) {
132 AddDiskChangeHook(DiskChangeHook
, TRUE
);
134 ReloadPluginsParams
[0] = (IPTR
)FindTask(NULL
);
135 ReloadPluginsParams
[1] = (1UL << ReloadPluginsSignal
);
136 ReloadPluginsHook
= CreateHook((HOOKFUNC
)SignalFunc
, ReloadPluginsParams
);
137 if (!ReloadPluginsHook
) {
140 AddReloadPluginsHook(ReloadPluginsHook
, TRUE
);
145 if (TTBoolean(Icon
, "CX_POPUP")) {
146 set(Gui
.wnd
[WID_MAIN
], MUIA_Window_Open
, TRUE
);
147 if (!XGET(Gui
.wnd
[WID_MAIN
], MUIA_Window_Open
)) {
150 DoMethod(Gui
.gad
[GID_DRIVELIST
], MUIM_List_Redraw
, MUIV_List_Redraw_All
);
153 while ((LONG
)DoMethod(Gui
.app
, MUIM_Application_NewInput
, (IPTR
)&sigs
) !=
154 MUIV_Application_ReturnID_Quit
)
157 sigs
|= (1UL << DiskChangeSignal
);
158 sigs
|= (1UL << ReloadPluginsSignal
);
159 sigs
= Wait(sigs
|SIGBREAKF_CTRL_C
);
161 if (sigs
& SIGBREAKF_CTRL_C
) {
165 if (sigs
& (1UL << DiskChangeSignal
)) {
169 if (sigs
& (1UL << ReloadPluginsSignal
)) {
175 D(bug("DiskImageGUI ending...\n"));
178 D(bug("In error/cleanup section\n"));
180 PluginList_FreeClass(PluginListClass
);
181 DriveList_FreeClass(DriveListClass
);
182 MUI_FreeAslRequest(FileReq
);
183 if (ReloadPluginsHook
) {
184 AddReloadPluginsHook(ReloadPluginsHook
, FALSE
);
185 FreeHook(ReloadPluginsHook
);
187 FreeSignal(ReloadPluginsSignal
);
188 if (DiskChangeHook
) {
189 AddDiskChangeHook(DiskChangeHook
, FALSE
);
190 FreeHook(DiskChangeHook
);
192 CloseDiskImageDevice();
193 FreeDiskObject(Icon
);
194 FreeSignal(DiskChangeSignal
);
195 FreeLocaleInfo((struct Library
*)SysBase
, &LocaleInfo
);
200 void ScanUnits (void) {
201 Object
*listview
= Gui
.gad
[GID_DRIVELIST
];
202 const ULONG dosflags
= LDF_DEVICES
|LDF_READ
;
204 struct FileSysStartupMsg
*fssm
;
207 struct DriveEntry
**entries
, *e
;
208 ULONG selected_unit
= ~0;
209 struct DriveEntry
*selected_entry
= NULL
;
211 DoMethod(listview
, MUIM_List_GetEntry
, MUIV_List_GetEntry_Active
, &e
);
212 if (e
) selected_unit
= e
->unit_num
;
214 set(listview
, MUIA_List_Quiet
, TRUE
);
216 DoMethod(listview
, MUIM_List_Clear
);
219 dl
= LockDosList(dosflags
);
220 while ((dl
= NextDosEntry(dl
, dosflags
))) {
221 if (CheckBPTR(dl
->dol_Name
) && (fssm
= CheckBPTR(dl
->dol_misc
.dol_handler
.dol_Startup
))
222 && CheckBPTR(fssm
->fssm_Device
))
224 const int ln
= strlen("diskimage.device");
225 if (AROS_BSTR_strlen(fssm
->fssm_Device
) == ln
&&
226 !memcmp(AROS_BSTR_ADDR(fssm
->fssm_Device
), "diskimage.device", ln
))
232 UnLockDosList(dosflags
);
234 entries
= AllocVecPooled(Gui
.pool
, sizeof(APTR
) * num_entries
);
236 set(listview
, MUIA_List_Quiet
, FALSE
);
239 for (i
= 0; i
< num_entries
; i
++) {
240 entries
[i
] = AllocVecPooled(Gui
.pool
, sizeof(*e
));
243 for (i
= 0; i
< num_entries
; i
++) {
244 FreeVecPooled(Gui
.pool
, entries
[i
]);
246 FreeVecPooled(Gui
.pool
, entries
);
247 set(listview
, MUIA_List_Quiet
, FALSE
);
253 dl
= LockDosList(dosflags
);
254 while ((dl
= NextDosEntry(dl
, dosflags
))) {
255 if (CheckBPTR(dl
->dol_Name
) && (fssm
= CheckBPTR(dl
->dol_misc
.dol_handler
.dol_Startup
))
256 && CheckBPTR(fssm
->fssm_Device
))
258 const int ln
= strlen("diskimage.device");
259 if (AROS_BSTR_strlen(fssm
->fssm_Device
) == ln
&&
260 !memcmp(AROS_BSTR_ADDR(fssm
->fssm_Device
), "diskimage.device", ln
))
262 if (i
< num_entries
) {
263 CopyStringBSTRToC(dl
->dol_Name
, devicename
, sizeof(devicename
));
265 e
->unit_num
= fssm
->fssm_Unit
;
266 e
->device_type
= DG_DIRECT_ACCESS
;
267 e
->writeprotect
= FALSE
;
268 e
->unit
= ASPrintfPooled(Gui
.pool
, "%ld", e
->unit_num
);
269 e
->drive
= ASPrintfPooled(Gui
.pool
, "%s", devicename
);
271 if (selected_unit
== e
->unit_num
) {
279 UnLockDosList(dosflags
);
281 DoMethod(listview
, MUIM_List_Insert
, entries
, i
, MUIV_List_Insert_Sorted
);
282 set(listview
, MUIA_List_Quiet
, FALSE
);
283 if (selected_entry
) {
284 set(listview
, MUIA_List_Active
, selected_entry
->list_pos
);
287 for (; i
< num_entries
; i
++) {
288 FreeVecPooled(Gui
.pool
, entries
[i
]);
290 FreeVecPooled(Gui
.pool
, entries
);
293 HOOKPROTO(ListviewPluginFunc
, IPTR
, struct DiskImagePlugin
*plugin
, APTR unused
) {
294 struct PluginEntry
*e
;
295 e
= AllocVecPooled(Gui
.pool
, sizeof(*e
));
297 e
->pri_num
= plugin
->Node
.ln_Pri
;
298 e
->is_builtin
= (plugin
->Flags
& PLUGIN_FLAG_BUILTIN
) ? TRUE
: FALSE
;
299 e
->has_write
= plugin
->plugin_Write
? TRUE
: FALSE
;
301 e
->name
= plugin
->Node
.ln_Name
;
302 DoMethod(Gui
.gad
[GID_PLUGINLIST
], MUIM_List_InsertSingle
, e
, MUIV_List_Insert_Bottom
);
306 MakeStaticHook(ListviewPluginHook
, ListviewPluginFunc
);
308 void ScanPlugins (void) {
309 Object
*listview
= Gui
.gad
[GID_PLUGINLIST
];
311 set(listview
, MUIA_List_Quiet
, TRUE
);
313 DoMethod(listview
, MUIM_List_Clear
);
315 DoHookPlugins(&ListviewPluginHook
);
317 set(listview
, MUIA_List_Quiet
, FALSE
);
320 void ChangeTempDir (void) {
322 struct FileRequester
*freq
;
323 tmpdir
= GetEnvVar(TEMPDIR_VAR
);
324 freq
= MUI_AllocAslRequestTags(ASL_FileRequest
,
325 ASLFR_InitialDrawer
, tmpdir
? tmpdir
: (STRPTR
)"T:",
326 ASLFR_DoSaveMode
, FALSE
,
327 ASLFR_DrawersOnly
, TRUE
,
330 SetWindowBusy(~0, TRUE
);
331 if (MUI_AslRequest(freq
, NULL
)) {
332 SetEnvVar(TEMPDIR_VAR
, freq
->fr_Drawer
, FALSE
);
334 SetWindowBusy(~0, FALSE
);
335 MUI_FreeAslRequest(freq
);
340 void SaveSettings (void) {
342 tmpdir
= GetEnvVar(TEMPDIR_VAR
);
343 SetEnvVar(TEMPDIR_VAR
, tmpdir
, TRUE
);
347 HOOKPROTO(BrokerFunc
, IPTR
, Object
*app
, CxMsg
*msg
) {
348 Object
**wnd
= Gui
.wnd
;
349 switch (CxMsgType(msg
)) {
351 switch (CxMsgID(msg
)) {
353 set(wnd
[WID_MAIN
], MUIA_Window_Open
, TRUE
);
354 set(app
, MUIA_Application_Iconified
, FALSE
);
355 DoMethod(Gui
.gad
[GID_DRIVELIST
], MUIM_List_Redraw
, MUIV_List_Redraw_All
);
360 switch (CxMsgID(msg
)) {
362 ActivateCxObj((CxObj
*)XGET(app
, MUIA_Application_Broker
), FALSE
);
365 ActivateCxObj((CxObj
*)XGET(app
, MUIA_Application_Broker
), TRUE
);
369 set(wnd
[WID_MAIN
], MUIA_Window_Open
, TRUE
);
370 set(app
, MUIA_Application_Iconified
, FALSE
);
371 DoMethod(Gui
.gad
[GID_DRIVELIST
], MUIM_List_Redraw
, MUIV_List_Redraw_All
);
373 case CXCMD_DISAPPEAR
:
374 set(wnd
[WID_MAIN
], MUIA_Window_Open
, FALSE
);
377 DoMethod(app
, MUIM_Application_ReturnID
, MUIV_Application_ReturnID_Quit
);
385 HOOKPROTO(MenuFunc
, IPTR
, Object
*app
, IPTR
*params
) {
386 ULONG menu_id
= (ULONG
)params
[0];
387 Object
**wnd
= Gui
.wnd
;
390 set(wnd
[WID_ABOUT
], MUIA_Window_Open
, TRUE
);
393 set(wnd
[WID_MAIN
], MUIA_Window_Open
, FALSE
);
396 set(app
, MUIA_Application_Iconified
, TRUE
);
399 DoMethod(wnd
[WID_MAIN
], MUIM_Window_Snapshot
, TRUE
);
402 DoMethod(app
, MUIM_Application_ReturnID
, MUIV_Application_ReturnID_Quit
);
404 case MID_CHANGETEMPDIR
:
408 set(wnd
[WID_PLUGINS
], MUIA_Window_Open
, TRUE
);
409 DoMethod(Gui
.gad
[GID_PLUGINLIST
], MUIM_List_Redraw
, MUIV_List_Redraw_All
);
411 case MID_SAVESETTINGS
:
418 HOOKPROTO(SignalFunc
, IPTR
, APTR unused
, IPTR
*params
) {
419 struct Task
*task
= (struct Task
*)params
[0];
420 ULONG sigmask
= (ULONG
)params
[1];
421 Signal(task
, sigmask
);