New bitmap method SetRGBConversionFunction which can be used to
[tangerine.git] / workbench / tools / ScreenGrabber / main.c
blobe60794050b9fcd33a862398c9e19813b1752179a
1 /*
2 Copyright © 2004-2006, 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>
17 #include <proto/dos.h>
18 #include <proto/datatypes.h>
19 #include <proto/intuition.h>
20 #include <proto/cybergraphics.h>
21 #include <proto/muimaster.h>
22 #include <proto/graphics.h>
24 #include <stdio.h>
25 #include "locale.h"
27 #define APPNAME "ScreenGrabber"
28 #define VERSION "ScreenGrabber 0.4 (29.06.2006)"
30 static const char version[] = "$VER: " VERSION " ©2006 AROS Dev Team";
32 static Object *app, *MainWindow, *ScreenList, *FilenameString, *SaveButton, *RefreshButton, *GrabButton;
33 static Object *Size, *Title, *DefTitle, *Delay, *Hide, *Progress;
35 static Object *DTImage = NULL;
37 static struct Hook display_hook;
38 static struct Hook refresh_hook;
39 static struct Hook select_hook;
40 static struct Hook grab_hook;
41 static struct Hook save_hook;
43 AROS_UFH3(void, display_function,
44 AROS_UFHA(struct Hook *, h, A0),
45 AROS_UFHA(char **, strings, A2),
46 AROS_UFHA(struct PubScreenNode *, psn, A1))
48 AROS_USERFUNC_INIT
50 static char buff[200];
52 if (psn)
54 snprintf(buff, sizeof(buff)-1, "%s", psn->psn_Node.ln_Name);
55 strings[0] = buff;
58 AROS_USERFUNC_EXIT
61 static void RefreshScreens()
63 struct List *list;
64 struct PubScreenNode *psn;
66 DoMethod(ScreenList, MUIM_List_Clear);
68 list = LockPubScreenList();
70 ForeachNode(list, psn)
72 DoMethod(ScreenList, MUIM_List_InsertSingle, (IPTR)psn, MUIV_List_Insert_Bottom);
75 UnlockPubScreenList();
78 AROS_UFH3(void, refresh_function,
79 AROS_UFHA(struct Hook *, h, A0),
80 AROS_UFHA(char **, dummy, A2),
81 AROS_UFHA(struct Screen *, dummy2, A1))
83 AROS_USERFUNC_INIT
85 RefreshScreens();
87 AROS_USERFUNC_EXIT
90 AROS_UFH3(void, select_function,
91 AROS_UFHA(struct Hook *, h, A0),
92 AROS_UFHA(Object *, object, A2),
93 AROS_UFHA(APTR, msg, A1))
95 AROS_USERFUNC_INIT
97 ULONG active = XGET(object, MUIA_List_Active);
99 if (active != MUIV_List_Active_Off)
101 struct PubScreenNode *psn;
102 struct Screen *screen;
103 char buff[200];
105 DoMethod(object, MUIM_List_GetEntry, active, (IPTR)&psn);
106 screen=psn->psn_Screen;
108 snprintf(buff, sizeof(buff)-1, _(MSG_SCREEN_PARM),
109 screen->Width, screen->Height, GetBitMapAttr(screen->RastPort.BitMap,BMA_DEPTH));
110 set(Size, MUIA_Text_Contents, buff);
111 set(Title, MUIA_Text_Contents, screen->Title);
112 set(DefTitle, MUIA_Text_Contents, screen->DefaultTitle);
114 set(GrabButton, MUIA_Disabled, FALSE);
116 else
118 set(GrabButton, MUIA_Disabled, TRUE);
119 set(Size, MUIA_Text_Contents, "");
120 set(Title, MUIA_Text_Contents, "");
121 set(DefTitle, MUIA_Text_Contents, "");
124 AROS_USERFUNC_EXIT
127 AROS_UFH3(void, grab_function,
128 AROS_UFHA(struct Hook *, h, A0),
129 AROS_UFHA(char **, dummy, A2),
130 AROS_UFHA(struct Screen *, dummy2, A1))
132 AROS_USERFUNC_INIT
134 ULONG delay,active;
135 BOOL hide_win;
136 struct PubScreenNode *psn;
137 struct Screen *screen;
139 delay = XGET(Delay, MUIA_Numeric_Value) * 10;
140 hide_win = XGET(Hide, MUIA_Selected);
142 active = XGET(ScreenList, MUIA_List_Active);
143 DoMethod(ScreenList, MUIM_List_GetEntry, active, (IPTR)&psn);
144 screen = LockPubScreen(psn->psn_Node.ln_Name);
146 D(bug("delay=%d, hide=%d\n", delay, hide_win));
148 if (screen)
150 APTR dst;
152 if (delay)
154 set(Progress, MUIA_Gauge_Current, delay);
155 set(Progress, MUIA_Gauge_Max, delay);
157 else if (hide_win) set(MainWindow, MUIA_Window_Open, FALSE);
159 while(delay) {
160 delay--;
161 set(Progress, MUIA_Gauge_Current, delay);
162 Delay(5);
163 if ((delay < 5) && hide_win) set(MainWindow, MUIA_Window_Open, FALSE);
166 dst = AllocVec(4*screen->Width, MEMF_ANY);
167 if (dst)
170 if (DTImage) DisposeDTObject(DTImage);
172 DTImage = NewDTObject((APTR)NULL,
173 DTA_SourceType, DTST_RAM,
174 DTA_BaseName, (IPTR)"png",
175 PDTA_DestMode, PMODE_V43,
176 TAG_DONE);
178 if (DTImage)
180 struct BitMapHeader *bmhd;
182 if ((GetDTAttrs(DTImage, PDTA_BitMapHeader, (IPTR)&bmhd, TAG_DONE)))
184 ULONG y;
185 struct pdtBlitPixelArray dtb;
186 dtb.MethodID = PDTM_WRITEPIXELARRAY;
187 dtb.pbpa_PixelData = dst;
188 dtb.pbpa_PixelFormat = PBPAFMT_ARGB;
189 dtb.pbpa_PixelArrayMod = screen->Width;
190 dtb.pbpa_Left = 0;
191 dtb.pbpa_Width = screen->Width;
192 dtb.pbpa_Height = 1;
194 bmhd->bmh_Width = screen->Width;
195 bmhd->bmh_Height = screen->Height;
196 bmhd->bmh_Depth = 24;
197 bmhd->bmh_PageWidth = 320;
198 bmhd->bmh_PageHeight = 240;
200 for (y=0; y < screen->Height; y++)
202 ReadPixelArray(dst, 0, 0, 4*screen->Width, &screen->RastPort, 0, y, screen->Width, 1, RECTFMT_ARGB);
203 dtb.pbpa_Top = y;
205 DoMethodA(DTImage, (Msg) &dtb);
208 set(SaveButton, MUIA_Disabled, FALSE);
211 else
213 MUI_Request(app, MainWindow, 0, _(MSG_ERROR_TITLE), _(MSG_GAD_OK), _(MSG_ERR_DATATYPE), NULL );
216 FreeVec(dst);
218 else
220 MUI_Request(app, MainWindow, 0, _(MSG_ERROR_TITLE), _(MSG_GAD_OK), _(MSG_NORAM), NULL);
224 if (hide_win)
225 set(MainWindow, MUIA_Window_Open, TRUE);
227 UnlockPubScreen(NULL, screen);
230 AROS_USERFUNC_EXIT
233 AROS_UFH3(void, save_function,
234 AROS_UFHA(struct Hook *, h, A0),
235 AROS_UFHA(char **, dummy, A2),
236 AROS_UFHA(struct Screen *, dummy2, A1))
238 AROS_USERFUNC_INIT
240 struct dtWrite dtw;
241 UBYTE *filename;
242 UBYTE *infofilename;
243 BPTR fh;
244 BPTR oldfile;
245 BPTR oldinfofile;
247 filename = (UBYTE*)XGET(FilenameString, MUIA_String_Contents);
249 // Does file or icon already exist?
250 infofilename = AllocVec(strlen(filename) + 6, MEMF_ANY);
251 if ( infofilename == NULL )
253 MUI_Request(app, MainWindow, 0, _(MSG_ERROR_TITLE), _(MSG_GAD_OK), _(MSG_NORAM), NULL);
254 return;
256 strcpy(infofilename, filename);
257 strcat(infofilename, ".info");
259 oldfile = Open(filename, MODE_OLDFILE);
260 oldinfofile = Open(infofilename, MODE_OLDFILE);
261 if (oldfile || oldinfofile)
263 if (oldfile) Close(oldfile);
264 if (oldinfofile) Close(oldinfofile);
265 if (MUI_Request(app, MainWindow, 0, _(MSG_ERROR_TITLE), _(MSG_GAD_YESNO), _(MSG_OVERWRITE), filename ) == 0)
267 FreeVec(infofilename);
268 return;
271 FreeVec(infofilename);
273 if ((fh = Open(filename, MODE_NEWFILE)))
275 dtw.MethodID = DTM_WRITE;
276 dtw.dtw_GInfo = NULL;
277 dtw.dtw_FileHandle = fh;
278 dtw.dtw_Mode = DTWM_RAW;
279 dtw.dtw_AttrList = NULL;
281 DoMethodA(DTImage, (Msg) &dtw);
282 if (IoErr())
284 MUI_Request(app, MainWindow, 0, _(MSG_ERROR_TITLE), _(MSG_GAD_OK), _(MSG_ERR_DATATYPEIO), filename, IoErr() );
287 Close(fh);
289 else
291 MUI_Request(app, MainWindow, 0, _(MSG_ERROR_TITLE), _(MSG_GAD_OK), _(MSG_ERR_OPENFILE), filename);
294 AROS_USERFUNC_EXIT
300 BOOL GUIInit()
302 BOOL retval = FALSE;
303 D(bug("GUIInit()\n"));
305 app = ApplicationObject,
306 MUIA_Application_Title, (IPTR)APPNAME,
307 MUIA_Application_Version, (IPTR)VERSION,
308 MUIA_Application_Copyright, (IPTR)"© 2004-2006, The AROS Development Team",
309 MUIA_Application_Author, (IPTR)"Michal Schulz",
310 MUIA_Application_Description, _(MSG_WINDOW_TITLE),
311 MUIA_Application_Base, (IPTR)"SCREENGRABBER",
313 SubWindow, MainWindow = WindowObject,
314 MUIA_Window_Title, _(MSG_WINDOW_TITLE),
315 MUIA_Window_ID, MAKE_ID('S','G','W','N'),
316 WindowContents, HGroup,
317 MUIA_Group_SameWidth, FALSE,
318 Child, VGroup,
319 MUIA_Weight, 100,
320 Child, ListviewObject,
321 MUIA_Listview_List, ScreenList = ListObject,
322 InputListFrame,
323 MUIA_List_AdjustWidth, FALSE,
324 MUIA_List_DisplayHook, &display_hook,
325 End,
326 End,
327 Child, RefreshButton = MUI_MakeObject(MUIO_Button, _(MSG_REFRESH)),
328 End, // VGroup
329 Child, VGroup,
330 MUIA_Weight, 200,
331 Child, VGroup,
332 TextFrame,
333 MUIA_Background, MUII_PageBack,
334 InnerSpacing(5,5),
335 Child, VGroup, GroupFrameT(_(MSG_SCREEN_INFO)),
336 Child, ColGroup(2),
337 Child, Label(_(MSG_SIZE)),
338 Child, Size = TextObject,
339 StringFrame,
340 MUIA_Text_SetMax, FALSE,
341 MUIA_Text_Contents, "",
342 End,
343 End,
344 Child, ColGroup(2),
345 Child, Label(_(MSG_TITLE)),
346 Child, Title = TextObject,
347 StringFrame,
348 MUIA_Text_SetMax, FALSE,
349 MUIA_Text_Contents, "",
350 End,
351 End,
352 Child, ColGroup(2),
353 Child, Label(_(MSG_DEFAULT_TITLE)),
354 Child, DefTitle = TextObject,
355 StringFrame,
356 MUIA_Text_SetMax, FALSE,
357 MUIA_Text_Contents, "",
358 End,
359 End,
360 End,
361 Child, VGroup, GroupFrameT(_(MSG_GRABBING_OPTIONS)),
362 Child, ColGroup(2),
363 Child, Label(_(MSG_DELAY)),
364 Child, Delay = SliderObject,
365 MUIA_Numeric_Min, 0,
366 MUIA_Numeric_Max, 30,
367 MUIA_Numeric_Value, 0,
368 End,
369 End,
370 Child, HGroup,
371 Child, HVSpace,
372 Child, Label(_(MSG_HIDE)),
373 Child, Hide = MUI_MakeObject(MUIO_Checkmark, "aaaa"),
374 End,
375 End,
376 Child, VGroup, GroupFrameT(_(MSG_SAVE_OPTIONS)),
377 Child, PopaslObject,
378 ASLFR_DoSaveMode, TRUE,
379 MUIA_Popstring_String, FilenameString = MUI_MakeObject(MUIO_String, NULL, 200),
380 MUIA_Popstring_Button, PopButton(MUII_PopFile),
381 End,
382 Child, SaveButton = MUI_MakeObject(MUIO_Button, _(MSG_SAVE_FILE)),
383 End,
384 Child, Progress = GaugeObject,
385 GaugeFrame,
386 MUIA_Gauge_Horiz, TRUE,
387 MUIA_FixHeight, 8,
388 MUIA_Gauge_Current, 0,
389 End,
390 End,
392 Child, GrabButton = MUI_MakeObject(MUIO_Button, _(MSG_SCREENSHOT)),
393 End,
394 End, // WindowContents
395 End, // WindowObject
396 End; // ApplicationObject
398 if (app)
400 D(bug("app=%p\n",app));
401 set(SaveButton, MUIA_Disabled, TRUE);
402 set(GrabButton, MUIA_Disabled, TRUE);
404 DoMethod(RefreshButton, MUIM_Notify, MUIA_Pressed, FALSE,
405 (IPTR)app, 2, MUIM_CallHook, (IPTR)&refresh_hook);
407 DoMethod(GrabButton, MUIM_Notify, MUIA_Pressed, FALSE,
408 (IPTR)app, 2, MUIM_CallHook, (IPTR)&grab_hook);
410 DoMethod(SaveButton, MUIM_Notify, MUIA_Pressed, FALSE,
411 (IPTR)app, 2, MUIM_CallHook, (IPTR)&save_hook);
413 DoMethod(ScreenList, MUIM_Notify, MUIA_List_Active, MUIV_EveryTime,
414 (IPTR)ScreenList, 2, MUIM_CallHook, (IPTR)&select_hook);
416 DoMethod(MainWindow, MUIM_Notify, MUIA_Window_CloseRequest, TRUE,
417 (IPTR)app, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit);
419 retval = TRUE;
422 return retval;
425 int main()
427 display_hook.h_Entry = (APTR)display_function;
428 refresh_hook.h_Entry = (APTR)refresh_function;
429 select_hook.h_Entry = (APTR)select_function;
430 grab_hook.h_Entry = (APTR)grab_function;
431 save_hook.h_Entry = (APTR)save_function;
432 if (GUIInit())
434 set(MainWindow, MUIA_Window_Open, TRUE);
435 if (XGET(MainWindow, MUIA_Window_Open))
437 RefreshScreens();
438 DoMethod(app, MUIM_Application_Execute);
440 set(MainWindow, MUIA_Window_Open, FALSE);
441 MUI_DisposeObject(app);
442 if (DTImage) DisposeDTObject(DTImage);
443 DTImage = NULL;
445 else
447 MUI_Request(NULL, NULL, 0, _(MSG_ERROR_TITLE), _(MSG_GAD_OK), _(MSG_ERR_APP), NULL);
448 return RETURN_FAIL;
451 return RETURN_OK;