2 Copyright © 2012, The AROS Development Team. All rights reserved.
5 Desc: Dump screen to printer
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>
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>
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"
61 // scale factors as fraction x/0xffffffff
62 static ULONG scale
[] =
71 /* Possible printer.device and I/O errors */
72 static UBYTE
*ErrorText
[] =
77 "INVERTHAM", /* OBSOLETE */
79 "DIMENSIONOVFLOW", /* OBSOLETE */
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()
99 if (psn
->psn_Screen
== IntuitionBase
->FirstScreen
)
101 screen
= LockPubScreen(psn
->psn_Node
.ln_Name
);
105 UnlockPubScreenList();
106 D(bug("[GraphicDump/lock_front_pubscreen] screen %p\n", 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
;
122 if (size
>= SIZE_COUNT
)
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
;
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
]);
177 PutStr("GraphicsDump: Invalid ModeID\n");
179 UnlockPubScreen(NULL
, screen
);
183 PutStr("GraphicsDump: Can't lock Pubscreen\n");
185 CloseDevice((struct IORequest
*)PIO
);
189 PutStr("GraphicsDump: Can't open printer.device\n");
191 DeleteExtIO((struct IORequest
*)PIO
);
195 PutStr("GraphicsDump: Can't create Extented I/O Request\n");
197 DeleteMsgPort(PrinterMP
);
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
)
211 const char *colon
= NULL
;
212 const char *str
= string
;
215 if ((unsigned char)*str
== ':')
224 StrToLong(string
, x
);
225 StrToLong(colon
+ 1, y
);
228 D(bug("[GraphicDump/split_xy] x %u y %u\n", *x
, *y
));
235 static void read_icon(struct WBArg
*wbarg
, ULONG
*unit
, ULONG
*delay
, ULONG
*size
, ULONG
*width
, ULONG
*height
)
237 struct DiskObject
*dobj
;
241 dobj
= GetDiskObject(wbarg
->wa_Name
);
244 toolarray
= dobj
->do_ToolTypes
;
245 result
= FindToolType(toolarray
, "SIZE");
248 if (Stricmp(result
, "TINY") == 0)
252 else if (Stricmp(result
, "SMALL") == 0)
256 else if (Stricmp(result
, "MEDIUM") == 0)
260 else if (Stricmp(result
, "LARGE") == 0)
267 split_xy(result
, width
, height
);
270 if (FindToolType(toolarray
, "TINY"))
274 if (FindToolType(toolarray
, "SMALL"))
278 if (FindToolType(toolarray
, "MEDIUM"))
282 if (FindToolType(toolarray
, "LARGE"))
286 result
= FindToolType(toolarray
, "DELAY");
289 StrToLong(result
, delay
);
291 result
= FindToolType(toolarray
, "UNIT");
294 StrToLong(result
, unit
);
296 result
= FindToolType(toolarray
, "DOTS");
300 split_xy(result
, width
, height
);
302 FreeDiskObject(dobj
);
307 int main(int argc
, char **argv
)
311 ULONG size
= SIZE_SMALL
;
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)
335 IPTR args
[ARG_COUNT
] = {0};
337 struct RDArgs
*rda
= ReadArgs(ARG_TEMPLATE
, args
, NULL
);
340 PrintFault(IoErr(), argv
[0]);
346 if (Stricmp((STRPTR
)args
[ARG_SIZE
], "TINY") == 0)
350 else if (Stricmp((STRPTR
)args
[ARG_SIZE
], "SMALL") == 0)
354 else if (Stricmp((STRPTR
)args
[ARG_SIZE
], "MEDIUM") == 0)
358 else if (Stricmp((STRPTR
)args
[ARG_SIZE
], "LARGE") == 0)
365 split_xy((CONST_STRPTR
)args
[ARG_SIZE
], &width
, &height
);
376 if (args
[ARG_MEDIUM
])
386 delay
= *(LONG
*)args
[ARG_DELAY
];
390 unit
= *(LONG
*)args
[ARG_UNIT
];
395 split_xy((CONST_STRPTR
)args
[ARG_DOTS
], &width
, &height
);
402 dump(unit
, size
, width
, height
);