add a -quick target for -create-patch
[AROS.git] / workbench / tools / GraphicDump.c
blob5eeeb24470d7098e165d4d457bd07f6294833ad3
1 /*
2 Copyright © 2012, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Dump screen to printer
6 Lang: English
7 */
9 #include <exec/types.h>
10 #include <exec/memory.h>
11 #include <exec/ports.h>
12 #include <devices/printer.h>
13 #include <devices/prtbase.h>
14 #include <dos/dos.h>
15 #include <intuition/intuition.h>
16 #include <intuition/screens.h>
17 #include <graphics/displayinfo.h>
18 #include <workbench/startup.h>
20 #include <proto/dos.h>
21 #include <proto/exec.h>
22 #include <proto/alib.h>
23 #include <proto/graphics.h>
24 #include <proto/intuition.h>
25 #include <proto/utility.h>
26 #include <proto/icon.h>
28 //#define DEBUG 1
29 #include <aros/debug.h>
32 const char *vers = "$VER: GraphicDump 1.2 (13.03.2012)";
34 char __stdiowin[]="CON:/30/400/100/GraphicDump/AUTO/CLOSE/WAIT";
36 #define ARG_TEMPLATE "SIZE/K,TINY/S,SMALL/S,MEDIUM/S,LARGE/S,DELAY/N/K,UNIT/N/K,DOTS"
38 enum
40 ARG_SIZE,
41 ARG_TINY,
42 ARG_SMALL,
43 ARG_MEDIUM,
44 ARG_LARGE,
45 ARG_DELAY,
46 ARG_UNIT,
47 ARG_DOTS,
48 ARG_COUNT
51 enum
53 SIZE_TINY, // 1/4
54 SIZE_SMALL, // 1/2
55 SIZE_MEDIUM,// 3/4
56 SIZE_LARGE, // 1/1
57 SIZE_DOTS, // X:Y
58 SIZE_COUNT
61 // scale factors as fraction x/0xffffffff
62 static ULONG scale[] =
64 0x3fffffff, // TINY
65 0x7fffffff, // SMALL
66 0xbfffffff, // MEDIUM
67 0xffffffff, // LARGE
68 0 // DOTS
71 /* Possible printer.device and I/O errors */
72 static UBYTE *ErrorText[] =
74 "PDERR_NOERR",
75 "PDERR_CANCEL",
76 "PDERR_NOTGRAPHICS",
77 "INVERTHAM", /* OBSOLETE */
78 "BADDIMENSION",
79 "DIMENSIONOVFLOW", /* OBSOLETE */
80 "INTERNALMEMORY",
81 "BUFFERMEMORY",
82 /* IO_ERRs */
83 "IOERR_OPENFAIL",
84 "IOERR_ABORTED",
85 "IOERR_NOCMD",
86 "IOERR_BADLENGTH"
89 // check if frontmost screen is a Pubscreen
90 // if yes lock it, otherwise return NULL
91 static struct Screen *lock_front_pubscreen(void)
93 struct Screen *screen = NULL;
94 struct PubScreenNode *psn = NULL;
95 struct List *psl = LockPubScreenList();
96 // FIXME: must or must not to do LockIBase()
97 ForeachNode(psl, psn)
99 if (psn->psn_Screen == IntuitionBase->FirstScreen)
101 screen = LockPubScreen(psn->psn_Node.ln_Name);
102 break;
105 UnlockPubScreenList();
106 D(bug("[GraphicDump/lock_front_pubscreen] screen %p\n", screen));
108 return screen;
112 static void dump(ULONG unit, ULONG size, ULONG width, ULONG height)
114 struct MsgPort *PrinterMP;
115 union printerIO *PIO;
116 struct Screen *screen;
117 struct ViewPort *viewport;
118 LONG modeID;
119 ULONG signal;
121 // sanity
122 if (size >= SIZE_COUNT)
123 size = SIZE_SMALL;
125 D(bug("[GraphicDump/dump] unit %u size %u\n", unit, size));
127 if ((PrinterMP = CreateMsgPort()) != NULL)
129 if ((PIO = (union printerIO *)CreateExtIO(PrinterMP, sizeof(union printerIO))) != NULL)
131 if (!(OpenDevice("printer.device", 0, (struct IORequest *)PIO, unit)))
133 if ((screen = lock_front_pubscreen()) != NULL)
135 viewport = &(screen->ViewPort);
136 if ((modeID = GetVPModeID(viewport)) != INVALID_ID)
138 PIO->iodrp.io_Command = PRD_DUMPRPORT;
139 PIO->iodrp.io_RastPort = &(screen->RastPort);
140 PIO->iodrp.io_ColorMap = viewport->ColorMap;
141 PIO->iodrp.io_Modes = modeID;
142 PIO->iodrp.io_SrcX = screen->LeftEdge;
143 PIO->iodrp.io_SrcY = screen->TopEdge;
144 PIO->iodrp.io_SrcWidth = screen->Width;
145 PIO->iodrp.io_SrcHeight = screen->Height;
147 if (size == SIZE_DOTS)
149 PIO->iodrp.io_DestCols = width;
150 PIO->iodrp.io_DestRows = height;
152 else
154 PIO->iodrp.io_Special = SPECIAL_ASPECT | SPECIAL_FRACCOLS;
155 PIO->iodrp.io_DestCols = scale[size];
156 PIO->iodrp.io_DestRows = 0;
159 SendIO((struct IORequest *)PIO);
160 signal = Wait(1 << PrinterMP->mp_SigBit | SIGBREAKF_CTRL_C);
161 if (signal & SIGBREAKF_CTRL_C)
163 AbortIO((struct IORequest *)PIO);
164 WaitIO((struct IORequest *)PIO);
166 if (signal & (1 << PrinterMP->mp_SigBit))
168 while (GetMsg(PrinterMP)) ;
170 if (PIO->iodrp.io_Error != 0)
172 Printf("GraphicsDump: Error %s\n", ErrorText[PIO->iodrp.io_Error]);
175 else
177 PutStr("GraphicsDump: Invalid ModeID\n");
179 UnlockPubScreen(NULL, screen);
181 else
183 PutStr("GraphicsDump: Can't lock Pubscreen\n");
185 CloseDevice((struct IORequest *)PIO);
187 else
189 PutStr("GraphicsDump: Can't open printer.device\n");
191 DeleteExtIO((struct IORequest *)PIO);
193 else
195 PutStr("GraphicsDump: Can't create Extented I/O Request\n");
197 DeleteMsgPort(PrinterMP);
199 else
201 PutStr("GraphicsDump: Can't create Message port\n");
206 // split a string with the pattern x:y
207 // if no colon exists the actual values are kept
208 static CONST_STRPTR split_xy(CONST_STRPTR string, ULONG *x, ULONG *y)
210 // search for :
211 const char *colon = NULL;
212 const char *str = string;
215 if ((unsigned char)*str == ':')
217 colon = str;
219 } while (*(str++));
221 // get x and y value
222 if (colon)
224 StrToLong(string, x);
225 StrToLong(colon + 1, y);
228 D(bug("[GraphicDump/split_xy] x %u y %u\n", *x, *y));
230 return colon;
234 // parse tooltypes
235 static void read_icon(struct WBArg *wbarg, ULONG *unit, ULONG *delay, ULONG *size, ULONG *width, ULONG *height)
237 struct DiskObject *dobj;
238 STRPTR *toolarray;
239 STRPTR result;
241 dobj = GetDiskObject(wbarg->wa_Name);
242 if (dobj)
244 toolarray = dobj->do_ToolTypes;
245 result = FindToolType(toolarray, "SIZE");
246 if (result)
248 if (Stricmp(result, "TINY") == 0)
250 *size = SIZE_TINY;
252 else if (Stricmp(result, "SMALL") == 0)
254 *size = SIZE_SMALL;
256 else if (Stricmp(result, "MEDIUM") == 0)
258 *size = SIZE_MEDIUM;
260 else if (Stricmp(result, "LARGE") == 0)
262 *size = SIZE_LARGE;
264 else
266 *size = SIZE_DOTS;
267 split_xy(result, width, height);
270 if (FindToolType(toolarray, "TINY"))
272 *size = SIZE_TINY;
274 if (FindToolType(toolarray, "SMALL"))
276 *size = SIZE_SMALL;
278 if (FindToolType(toolarray, "MEDIUM"))
280 *size = SIZE_MEDIUM;
282 if (FindToolType(toolarray, "LARGE"))
284 *size = SIZE_LARGE;
286 result = FindToolType(toolarray, "DELAY");
287 if (result)
289 StrToLong(result, delay);
291 result = FindToolType(toolarray, "UNIT");
292 if (result)
294 StrToLong(result, unit);
296 result = FindToolType(toolarray, "DOTS");
297 if (result)
299 *size = SIZE_DOTS;
300 split_xy(result, width, height);
302 FreeDiskObject(dobj);
307 int main(int argc, char **argv)
309 ULONG unit = 0;
310 ULONG delay = 10;
311 ULONG size = SIZE_SMALL;
312 ULONG width = 300;
313 ULONG height = 300;
315 if (argc == 0)
317 // started from Wanderer
318 struct WBStartup *wbmsg = (struct WBStartup *)argv;
319 struct WBArg *wbarg = wbmsg->sm_ArgList;
320 BPTR olddir = (BPTR)-1;
322 if ((wbmsg->sm_NumArgs > 0) && (wbarg[0].wa_Lock) && (*wbarg[0].wa_Name))
324 olddir = CurrentDir(wbarg[0].wa_Lock);
325 read_icon(wbarg, &unit, &delay, &size, &width, &height);
326 if (olddir != (BPTR)-1)
328 CurrentDir(olddir);
332 else
334 // started from CLI
335 IPTR args[ARG_COUNT] = {0};
337 struct RDArgs *rda = ReadArgs(ARG_TEMPLATE, args, NULL);
338 if (!rda)
340 PrintFault(IoErr(), argv[0]);
341 return RETURN_ERROR;
344 if (args[ARG_SIZE])
346 if (Stricmp((STRPTR)args[ARG_SIZE], "TINY") == 0)
348 size = SIZE_TINY;
350 else if (Stricmp((STRPTR)args[ARG_SIZE], "SMALL") == 0)
352 size = SIZE_SMALL;
354 else if (Stricmp((STRPTR)args[ARG_SIZE], "MEDIUM") == 0)
356 size = SIZE_MEDIUM;
358 else if (Stricmp((STRPTR)args[ARG_SIZE], "LARGE") == 0)
360 size = SIZE_LARGE;
362 else
364 size = SIZE_DOTS;
365 split_xy((CONST_STRPTR)args[ARG_SIZE], &width, &height);
368 if (args[ARG_TINY])
370 size = SIZE_TINY;
372 if (args[ARG_SMALL])
374 size = SIZE_SMALL;
376 if (args[ARG_MEDIUM])
378 size = SIZE_MEDIUM;
380 if (args[ARG_LARGE])
382 size = SIZE_LARGE;
384 if (args[ARG_DELAY])
386 delay = *(LONG *)args[ARG_DELAY];
388 if (args[ARG_UNIT])
390 unit = *(LONG *)args[ARG_UNIT];
392 if (args[ARG_DOTS])
394 size = SIZE_DOTS;
395 split_xy((CONST_STRPTR)args[ARG_DOTS], &width, &height);
397 FreeArgs(rda);
400 Delay(delay * 50);
402 dump(unit, size, width, height);
404 return 0;