Prefs/ScreenMode: change the way depth is selected
[AROS.git] / workbench / tools / ScreenGrabber / main.c
blobd0d0486f2e9d842db3ea585088928443ac9c4979
1 /*
2 Copyright © 2004-2011, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 //#define DEBUG 1
8 #include <aros/debug.h>
9 #include <datatypes/datatypes.h>
10 #include <datatypes/pictureclass.h>
11 #include <intuition/classes.h>
12 #include <dos/bptr.h>
13 #include <cybergraphx/cybergraphics.h>
14 #include <libraries/mui.h>
15 #include <libraries/asl.h>
16 #include <workbench/startup.h>
18 #include <proto/alib.h>
19 #include <proto/dos.h>
20 #include <proto/datatypes.h>
21 #include <proto/intuition.h>
22 #include <proto/cybergraphics.h>
23 #include <proto/muimaster.h>
24 #include <proto/graphics.h>
25 #include <proto/icon.h>
27 #include <stdio.h>
28 #include "locale.h"
30 #define APPNAME "ScreenGrabber"
31 #define VERSION "ScreenGrabber 0.4 (29.06.2006)"
33 static const char version[] = "$VER: " VERSION " ©2006 AROS Dev Team";
35 static Object *app, *MainWindow, *ScreenList, *FilenameString, *SaveButton, *RefreshButton, *GrabButton;
36 static Object *Size, *Title, *DefTitle, *Pause, *Hide, *Progress;
38 static Object *DTImage = NULL;
39 static struct DiskObject *disko;
41 static struct Hook display_hook;
42 static struct Hook refresh_hook;
43 static struct Hook select_hook;
44 static struct Hook grab_hook;
45 static struct Hook save_hook;
47 AROS_UFH3(void, display_function,
48 AROS_UFHA(struct Hook *, h, A0),
49 AROS_UFHA(char **, strings, A2),
50 AROS_UFHA(struct PubScreenNode *, psn, A1))
52 AROS_USERFUNC_INIT
54 static char buff[200];
56 if (psn)
58 snprintf(buff, sizeof(buff)-1, "%s", psn->psn_Node.ln_Name);
59 strings[0] = buff;
62 AROS_USERFUNC_EXIT
65 static void RefreshScreens()
67 struct List *list;
68 struct PubScreenNode *psn;
70 DoMethod(ScreenList, MUIM_List_Clear);
72 list = LockPubScreenList();
74 ForeachNode(list, psn)
76 DoMethod(ScreenList, MUIM_List_InsertSingle, (IPTR)psn, MUIV_List_Insert_Bottom);
79 UnlockPubScreenList();
82 AROS_UFH3(void, refresh_function,
83 AROS_UFHA(struct Hook *, h, A0),
84 AROS_UFHA(char **, dummy, A2),
85 AROS_UFHA(struct Screen *, dummy2, A1))
87 AROS_USERFUNC_INIT
89 RefreshScreens();
91 AROS_USERFUNC_EXIT
94 AROS_UFH3(void, select_function,
95 AROS_UFHA(struct Hook *, h, A0),
96 AROS_UFHA(Object *, object, A2),
97 AROS_UFHA(APTR, msg, A1))
99 AROS_USERFUNC_INIT
101 ULONG active = XGET(object, MUIA_List_Active);
103 if (active != MUIV_List_Active_Off)
105 struct PubScreenNode *psn;
106 struct Screen *screen;
107 char buff[200];
109 DoMethod(object, MUIM_List_GetEntry, active, (IPTR)&psn);
110 screen=psn->psn_Screen;
112 snprintf(buff, sizeof(buff)-1, _(MSG_SCREEN_PARM),
113 screen->Width, screen->Height, GetBitMapAttr(screen->RastPort.BitMap,BMA_DEPTH));
114 set(Size, MUIA_Text_Contents, buff);
115 set(Title, MUIA_Text_Contents, screen->Title);
116 set(DefTitle, MUIA_Text_Contents, screen->DefaultTitle);
118 set(GrabButton, MUIA_Disabled, FALSE);
120 else
122 set(GrabButton, MUIA_Disabled, TRUE);
123 set(Size, MUIA_Text_Contents, "");
124 set(Title, MUIA_Text_Contents, "");
125 set(DefTitle, MUIA_Text_Contents, "");
128 AROS_USERFUNC_EXIT
131 AROS_UFH3(void, grab_function,
132 AROS_UFHA(struct Hook *, h, A0),
133 AROS_UFHA(char **, dummy, A2),
134 AROS_UFHA(struct Screen *, dummy2, A1))
136 AROS_USERFUNC_INIT
138 ULONG delay,active;
139 BOOL hide_win;
140 struct PubScreenNode *psn;
141 struct Screen *screen;
143 delay = XGET(Pause, MUIA_Numeric_Value) * 10;
144 hide_win = XGET(Hide, MUIA_Selected);
146 active = XGET(ScreenList, MUIA_List_Active);
147 DoMethod(ScreenList, MUIM_List_GetEntry, active, (IPTR)&psn);
148 screen = LockPubScreen(psn->psn_Node.ln_Name);
150 D(bug("delay=%d, hide=%d\n", delay, hide_win));
152 if (screen)
154 APTR dst;
156 if (delay)
158 set(Progress, MUIA_Gauge_Current, delay);
159 set(Progress, MUIA_Gauge_Max, delay);
161 else if (hide_win) set(MainWindow, MUIA_Window_Open, FALSE);
163 while(delay) {
164 delay--;
165 set(Progress, MUIA_Gauge_Current, delay);
166 Delay(5);
167 if ((delay < 5) && hide_win) set(MainWindow, MUIA_Window_Open, FALSE);
170 dst = AllocVec(4*screen->Width, MEMF_ANY);
171 if (dst)
174 if (DTImage) DisposeDTObject(DTImage);
176 DTImage = NewDTObject((APTR)NULL,
177 DTA_SourceType, DTST_RAM,
178 DTA_BaseName, (IPTR)"png",
179 PDTA_DestMode, PMODE_V43,
180 TAG_DONE);
182 if (DTImage)
184 struct BitMapHeader *bmhd;
186 if ((GetDTAttrs(DTImage, PDTA_BitMapHeader, (IPTR)&bmhd, TAG_DONE)))
188 ULONG y;
189 struct pdtBlitPixelArray dtb;
190 dtb.MethodID = PDTM_WRITEPIXELARRAY;
191 dtb.pbpa_PixelData = dst;
192 dtb.pbpa_PixelFormat = PBPAFMT_ARGB;
193 dtb.pbpa_PixelArrayMod = screen->Width;
194 dtb.pbpa_Left = 0;
195 dtb.pbpa_Width = screen->Width;
196 dtb.pbpa_Height = 1;
198 bmhd->bmh_Width = screen->Width;
199 bmhd->bmh_Height = screen->Height;
200 bmhd->bmh_Depth = 24;
201 bmhd->bmh_PageWidth = 320;
202 bmhd->bmh_PageHeight = 240;
204 for (y=0; y < screen->Height; y++)
206 ReadPixelArray(dst, 0, 0, 4*screen->Width, &screen->RastPort, 0, y, screen->Width, 1, RECTFMT_ARGB);
207 dtb.pbpa_Top = y;
209 DoMethodA(DTImage, (Msg) &dtb);
212 set(SaveButton, MUIA_Disabled, FALSE);
215 else
217 MUI_Request(app, MainWindow, 0, _(MSG_ERROR_TITLE), _(MSG_GAD_OK), _(MSG_ERR_DATATYPE), NULL );
220 FreeVec(dst);
222 else
224 MUI_Request(app, MainWindow, 0, _(MSG_ERROR_TITLE), _(MSG_GAD_OK), _(MSG_NORAM), NULL);
228 if (hide_win)
229 set(MainWindow, MUIA_Window_Open, TRUE);
231 UnlockPubScreen(NULL, screen);
234 AROS_USERFUNC_EXIT
237 AROS_UFH3(void, save_function,
238 AROS_UFHA(struct Hook *, h, A0),
239 AROS_UFHA(char **, dummy, A2),
240 AROS_UFHA(struct Screen *, dummy2, A1))
242 AROS_USERFUNC_INIT
244 struct dtWrite dtw;
245 UBYTE *filename;
246 UBYTE *infofilename;
247 BPTR fh;
248 BPTR oldfile;
249 BPTR oldinfofile;
251 filename = (UBYTE*)XGET(FilenameString, MUIA_String_Contents);
253 // Does file or icon already exist?
254 infofilename = AllocVec(strlen(filename) + 6, MEMF_ANY);
255 if ( infofilename == NULL )
257 MUI_Request(app, MainWindow, 0, _(MSG_ERROR_TITLE), _(MSG_GAD_OK), _(MSG_NORAM), NULL);
258 return;
260 strcpy(infofilename, filename);
261 strcat(infofilename, ".info");
263 oldfile = Open(filename, MODE_OLDFILE);
264 oldinfofile = Open(infofilename, MODE_OLDFILE);
265 if (oldfile || oldinfofile)
267 if (oldfile) Close(oldfile);
268 if (oldinfofile) Close(oldinfofile);
269 if (MUI_Request(app, MainWindow, 0, _(MSG_ERROR_TITLE), _(MSG_GAD_YESNO), _(MSG_OVERWRITE), filename ) == 0)
271 FreeVec(infofilename);
272 return;
275 FreeVec(infofilename);
277 if ((fh = Open(filename, MODE_NEWFILE)))
279 dtw.MethodID = DTM_WRITE;
280 dtw.dtw_GInfo = NULL;
281 dtw.dtw_FileHandle = fh;
282 dtw.dtw_Mode = DTWM_RAW;
283 dtw.dtw_AttrList = NULL;
285 DoMethodA(DTImage, (Msg) &dtw);
286 if (IoErr())
288 MUI_Request(app, MainWindow, 0, _(MSG_ERROR_TITLE), _(MSG_GAD_OK), _(MSG_ERR_DATATYPEIO), filename, IoErr() );
291 Close(fh);
293 else
295 MUI_Request(app, MainWindow, 0, _(MSG_ERROR_TITLE), _(MSG_GAD_OK), _(MSG_ERR_OPENFILE), filename);
298 AROS_USERFUNC_EXIT
304 BOOL GUIInit()
306 BOOL retval = FALSE;
307 D(bug("GUIInit()\n"));
309 app = ApplicationObject,
310 MUIA_Application_Title, (IPTR)APPNAME,
311 MUIA_Application_Version, (IPTR)VERSION,
312 MUIA_Application_Copyright, (IPTR)"© 2004-2006, The AROS Development Team",
313 MUIA_Application_Author, (IPTR)"Michal Schulz",
314 MUIA_Application_Description, _(MSG_WINDOW_TITLE),
315 disko ? MUIA_Application_DiskObject : TAG_IGNORE, (IPTR)disko,
316 MUIA_Application_Base, (IPTR)"SCREENGRABBER",
318 SubWindow, MainWindow = WindowObject,
319 MUIA_Window_Title, _(MSG_WINDOW_TITLE),
320 MUIA_Window_ID, MAKE_ID('S','G','W','N'),
321 WindowContents, HGroup,
322 MUIA_Group_SameWidth, FALSE,
323 Child, VGroup,
324 MUIA_Weight, 100,
325 Child, ListviewObject,
326 MUIA_Listview_List, ScreenList = ListObject,
327 InputListFrame,
328 MUIA_List_AdjustWidth, FALSE,
329 MUIA_List_DisplayHook, &display_hook,
330 End,
331 End,
332 Child, RefreshButton = MUI_MakeObject(MUIO_Button, _(MSG_REFRESH)),
333 End, // VGroup
334 Child, VGroup,
335 MUIA_Weight, 200,
336 Child, VGroup,
337 TextFrame,
338 MUIA_Background, MUII_PageBack,
339 InnerSpacing(5,5),
340 Child, VGroup, GroupFrameT(_(MSG_SCREEN_INFO)),
341 Child, ColGroup(2),
342 Child, Label(_(MSG_SIZE)),
343 Child, Size = TextObject,
344 StringFrame,
345 MUIA_Text_SetMax, FALSE,
346 MUIA_Text_Contents, "",
347 End,
348 End,
349 Child, ColGroup(2),
350 Child, Label(_(MSG_TITLE)),
351 Child, Title = TextObject,
352 StringFrame,
353 MUIA_Text_SetMax, FALSE,
354 MUIA_Text_Contents, "",
355 End,
356 End,
357 Child, ColGroup(2),
358 Child, Label(_(MSG_DEFAULT_TITLE)),
359 Child, DefTitle = TextObject,
360 StringFrame,
361 MUIA_Text_SetMax, FALSE,
362 MUIA_Text_Contents, "",
363 End,
364 End,
365 End,
366 Child, VGroup, GroupFrameT(_(MSG_GRABBING_OPTIONS)),
367 Child, ColGroup(2),
368 Child, Label(_(MSG_DELAY)),
369 Child, Pause = SliderObject,
370 MUIA_Numeric_Min, 0,
371 MUIA_Numeric_Max, 30,
372 MUIA_Numeric_Value, 0,
373 End,
374 End,
375 Child, HGroup,
376 Child, HVSpace,
377 Child, Label(_(MSG_HIDE)),
378 Child, Hide = MUI_MakeObject(MUIO_Checkmark, "aaaa"),
379 End,
380 End,
381 Child, VGroup, GroupFrameT(_(MSG_SAVE_OPTIONS)),
382 Child, PopaslObject,
383 ASLFR_DoSaveMode, TRUE,
384 MUIA_Popstring_String, FilenameString = MUI_MakeObject(MUIO_String, NULL, 200),
385 MUIA_Popstring_Button, PopButton(MUII_PopFile),
386 End,
387 Child, SaveButton = MUI_MakeObject(MUIO_Button, _(MSG_SAVE_FILE)),
388 End,
389 Child, Progress = GaugeObject,
390 GaugeFrame,
391 MUIA_Gauge_Horiz, TRUE,
392 MUIA_FixHeight, 8,
393 MUIA_Gauge_Current, 0,
394 End,
395 End,
397 Child, GrabButton = MUI_MakeObject(MUIO_Button, _(MSG_SCREENSHOT)),
398 End,
399 End, // WindowContents
400 End, // WindowObject
401 End; // ApplicationObject
403 if (app)
405 D(bug("app=%p\n",app));
406 set(SaveButton, MUIA_Disabled, TRUE);
407 set(GrabButton, MUIA_Disabled, TRUE);
409 DoMethod(RefreshButton, MUIM_Notify, MUIA_Pressed, FALSE,
410 (IPTR)app, 2, MUIM_CallHook, (IPTR)&refresh_hook);
412 DoMethod(GrabButton, MUIM_Notify, MUIA_Pressed, FALSE,
413 (IPTR)app, 2, MUIM_CallHook, (IPTR)&grab_hook);
415 DoMethod(SaveButton, MUIM_Notify, MUIA_Pressed, FALSE,
416 (IPTR)app, 2, MUIM_CallHook, (IPTR)&save_hook);
418 DoMethod(ScreenList, MUIM_Notify, MUIA_List_Active, MUIV_EveryTime,
419 (IPTR)ScreenList, 2, MUIM_CallHook, (IPTR)&select_hook);
421 DoMethod(MainWindow, MUIM_Notify, MUIA_Window_CloseRequest, TRUE,
422 (IPTR)app, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit);
424 retval = TRUE;
427 return retval;
430 int main(int argc, char **argv)
432 static struct WBStartup *wbstartup;
433 static struct WBArg *wb_arg;
434 static STRPTR cxname;
435 int result = RETURN_OK;
436 if (argc)
438 cxname=argv[0];
440 else
442 wbstartup = (struct WBStartup *)argv;
443 wb_arg = wbstartup->sm_ArgList;
444 cxname = wb_arg->wa_Name;
446 disko = GetDiskObject(cxname);
448 display_hook.h_Entry = (APTR)display_function;
449 refresh_hook.h_Entry = (APTR)refresh_function;
450 select_hook.h_Entry = (APTR)select_function;
451 grab_hook.h_Entry = (APTR)grab_function;
452 save_hook.h_Entry = (APTR)save_function;
453 if (GUIInit())
455 set(MainWindow, MUIA_Window_Open, TRUE);
456 if (XGET(MainWindow, MUIA_Window_Open))
458 RefreshScreens();
459 DoMethod(app, MUIM_Application_Execute);
461 set(MainWindow, MUIA_Window_Open, FALSE);
462 MUI_DisposeObject(app);
463 if (DTImage) DisposeDTObject(DTImage);
464 DTImage = NULL;
466 else
468 MUI_Request(NULL, NULL, 0, _(MSG_ERROR_TITLE), _(MSG_GAD_OK), _(MSG_ERR_APP), NULL);
469 result = RETURN_FAIL;
471 if (disko) FreeDiskObject(disko);
472 return result;