0.013 release
[imager-screenshot.git] / Screenshot.pm
CommitLineData
967e4c21
TC
1package Imager::Screenshot;
2use strict;
3use vars qw(@ISA $VERSION @EXPORT_OK);
4use Imager;
5require Exporter;
6
7push @ISA, 'Exporter';
8@EXPORT_OK = 'screenshot';
9
10BEGIN {
11 require Exporter;
12 @ISA = qw(Exporter);
9d7d0690 13 $VERSION = '0.013';
e5b8f93d
TC
14
15 require XSLoader;
16 XSLoader::load('Imager::Screenshot' => $VERSION);
967e4c21
TC
17}
18
19sub screenshot {
20 # lose the class if called as a method
21 @_ % 2 == 1 and shift;
22
87cd516f
TC
23 my %opts =
24 (
25 decor => 0,
26 display => 0,
27 left => 0,
28 top => 0,
29 right => 0,
30 bottom => 0,
0690a451 31 monitor => 0,
87cd516f 32 @_);
967e4c21
TC
33
34 my $result;
967e4c21
TC
35 if (defined $opts{hwnd}) {
36 defined &_win32
37 or die "Win32 driver not enabled\n";
87cd516f 38 $result = _win32($opts{hwnd}, $opts{decor}, $opts{left}, $opts{top},
0690a451 39 $opts{right}, $opts{bottom}, $opts{monitor});
967e4c21
TC
40 }
41 elsif (defined $opts{id}) { # X11 window id
4e6ce56a 42 exists $opts{display} or $opts{display} = 0;
967e4c21
TC
43 defined &_x11
44 or die "X11 driver not enabled\n";
87cd516f
TC
45 $result = _x11($opts{display}, $opts{id}, $opts{left}, $opts{top},
46 $opts{right}, $opts{bottom});
967e4c21 47 }
0cc0b6d7
TC
48 elsif (defined $opts{darwin}) { # as long as it's there
49 defined &_darwin
50 or die "Darwin driver not enabled\n";
51 $result = _darwin($opts{left}, $opts{top}, $opts{right}, $opts{bottom});
52 }
967e4c21
TC
53 elsif ($opts{widget}) {
54 # Perl/Tk widget
55 my $top = $opts{widget}->toplevel;
56 my $sys = $top->windowingsystem;
57 if ($sys eq 'win32') {
58 unless (defined &_win32) {
59 Imager->_set_error("Win32 Tk and Win32 support not built");
60 return;
61 }
87cd516f
TC
62 $result = _win32(hex($opts{widget}->id), $opts{decor},
63 $opts{left}, $opts{top}, $opts{right}, $opts{bottom});
967e4c21
TC
64 }
65 elsif ($sys eq 'x11') {
66 unless (defined &_x11) {
67 Imager->_set_error("X11 Tk and X11 support not built");
68 return;
69 }
70
71 my $id_hex = $opts{widget}->id;
967e4c21
TC
72
73 # is there a way to get the display pointer from Tk?
87cd516f
TC
74 $result = _x11($opts{display}, hex($id_hex), $opts{left}, $opts{top},
75 $opts{right}, $opts{bottom});
967e4c21
TC
76 }
77 else {
78 Imager->_set_error("Unsupported windowing system '$sys'");
79 return;
80 }
81 }
87cd516f
TC
82 else {
83 $result =
84 defined &_win32 ? _win32(0, $opts{decor}, $opts{left}, $opts{top},
0690a451 85 $opts{right}, $opts{bottom}, $opts{monitor}) :
bc99c241
TC
86 defined &_darwin ? _darwin($opts{left}, $opts{top},
87 $opts{right}, $opts{bottom}) :
88 defined &_x11 ? _x11($opts{display}, 0, $opts{left}, $opts{top},
87cd516f
TC
89 $opts{right}, $opts{bottom}) :
90 die "No drivers enabled\n";
91 }
967e4c21
TC
92
93 unless ($result) {
94 Imager->_set_error(Imager->_error_as_msg());
95 return;
96 }
cd684d4f
TC
97
98 # RT #24992 - the Imager typemap entry is broken pre-0.56, so
99 # wrap it here
100 return bless { IMG => $result }, "Imager";
967e4c21
TC
101}
102
103sub have_win32 {
104 defined &_win32;
105}
106
107sub have_x11 {
108 defined &_x11;
109}
110
0cc0b6d7
TC
111sub have_darwin {
112 defined &_darwin;
113}
114
967e4c21
TC
115sub x11_open {
116 my $display = _x11_open(@_);
117 unless ($display) {
118 Imager->_set_error(Imager->_error_as_msg);
119 return;
120 }
121
122 return $display;
123}
124
125sub x11_close {
126 _x11_close(shift);
127}
128
1291;
130
131__END__
132
133=head1 NAME
134
135Imager::Screenshot - screenshot to an Imager image
136
137=head1 SYNOPSIS
138
139 use Imager::Screenshot 'screenshot';
140
141 # whole screen
142 my $img = screenshot();
143
144 # Win32 window
145 my $img2 = screenshot(hwnd => $hwnd);
146
147 # X11 window
148 my $img3 = screenshot(display => $display, id => $window_id);
149
150 # X11 tools
151 my $display = Imager::Screenshot::x11_open();
152 Imager::Screenshot::x11_close($display);
153
154 # test for win32 support
155 if (Imager::Screenshot->have_win32) { ... }
156
157 # test for x11 support
158 if (Imager::Screenshot->have_x11) { ... }
159
0cc0b6d7
TC
160 # test for Darwin (Mac OS X) support
161 if (Imager::Screenshot->have_darwin) { ... }
162
967e4c21
TC
163
164=head1 DESCRIPTION
165
166Imager::Screenshot captures either a desktop or a specified window and
167returns the result as an Imager image.
168
169Currently the image is always returned as a 24-bit image.
170
171=over
172
173=item screenshot hwnd => I<window handle>
174
175=item screenshot hwnd => I<window handle>, decor => <capture decorations>
176
6f00ec2f
TC
177=item screenshot hwnd => "active"
178
967e4c21
TC
179Retrieve a screenshot under Win32, if I<window handle> is zero,
180capture the desktop.
181
182By default, window decorations are not captured, if the C<decor>
183parameter is set to true then window decorations are included.
184
6f00ec2f
TC
185As of 0.010 hwnd can also be C<"active"> to capture the active (or
186"foreground") window.
187
188=item screenshot hwnd => 0
189
190Retrieve a screeshot of the default desktop under Win32.
191
0690a451 192=item screenshot hwnd => 0, monitor => -1
6f00ec2f
TC
193
194Retrieve a screenshot of all attached monitors under Win32.
195
196Note: this returns an image with an alpha channel, since there can be
197regions in the bounding rectangle of all monitors that no particular
198monitor covers.
199
0690a451 200=item screenshot hwnd => 0, monitor => I<index>
6f00ec2f
TC
201
202Retrieve a screenshot from a particular monitor under Win32. A
0690a451
TC
203I<monitor> of zero is always treated as the primary monitor.
204
205If the given monitor is not active screenshot() will fail.
6f00ec2f 206
967e4c21
TC
207=item screenshot id => I<window id>
208
209=item screenshot id => I<window id>, display => I<display object>
210
211Retrieve a screenshot under X11, if I<id> is zero, capture the root
212window. I<display object> is a integer version of an X11 C< Display *
213>, if this isn't supplied C<screenshot()> will attempt connect to the
214the display specified by $ENV{DISPLAY}.
215
f04a72ea
TC
216Note: taking a screenshot of a remote display is slow.
217
0cc0b6d7
TC
218=item screenshot darwin => 0
219
220Retrieve a screenshot under Mac OS X. The only supported value for
221the C<darwin> parameter is C<0>.
222
223For a screen capture to be taken, the current user using
224Imager:Screenshot must be the currently logged in user on the display.
225
226If you're using fast user switching, the current user must be the
227active user.
228
229Note: this means you can ssh into a Mac OS X box and screenshot from
230the ssh session, if you're the current user on the display.
231
9d2a775a
TC
232=item screenshot widget => I<widget>
233
234=item screenshot widget => I<widget>, display => I<display>
235
236=item screenshot widget => I<widget>, decor => I<capture decorations>
237
238Retrieve a screenshot of a Tk widget, under Win32 or X11, depending on
239how Tk has been built.
240
241If Tk was built for X11 then the display parameter applies.
242
243If Tk was built for Win32 then the decor parameter applies.
244
967e4c21
TC
245=item screenshot
246
9d2a775a 247If no C<id>, C<hwnd> or C<widget> parameter is supplied:
967e4c21
TC
248
249=over
250
251=item *
252
253if Win32 support is compiled, return screenshot(hwnd => 0).
254
255=item *
256
0cc0b6d7
TC
257if Darwin support is compiled, return screenshot(darwin => 0).
258
259=item *
260
967e4c21
TC
261if X11 support is compiled, return screenshot(id => 0).
262
263=item *
264
265otherwise, die.
266
267=back
268
87cd516f
TC
269You can also supply the following parameters to retrieve a subset of
270the window:
271
272=over
273
274=item *
275
276left
277
278=item *
279
280top
281
282=item *
283
284right
285
286=item *
287
288bottom
289
290=back
291
292If left or top is negative, then treat that as from the right/bottom
293edge of the window.
294
295If right ot bottom is zero or negative then treat as from the
296right/bottom edge of the window.
297
298So setting all 4 values to 0 retrieves the whole window.
299
300 # a 10-pixel wide right edge of the window
301 my $right_10 = screenshot(left => -10, ...);
302
303 # the top-left 100x100 portion of the window
304 my $topleft_100 = screenshot(right => 100, bottom => 100, ...);
305
306 # 10x10 pixel at the bottom right corner
307 my $bott_right_10 = screenshot(left => -10, top => -10, ...);
308
06bbf244
TC
309If screenshot() fails, it will return nothing, and the cause of the
310failure can be retrieved via Imager->errstr, so typical use could be:
311
312 my $img = screenshot(...) or die Imager->errstr;
313
967e4c21
TC
314=item have_win32
315
316Returns true if Win32 support is available.
317
318=item have_x11
319
320Returns true if X11 support is available.
321
0cc0b6d7
TC
322=item have_darwin
323
324Returns true if Darwin support is available.
325
967e4c21
TC
326=item Imager::Screenshot::x11_open
327
328=item Imager::Screenshot::x11_open I<display name>
329
330Attempts to open a connection to either the display name in
331$ENV{DISPLAY} or the supplied display name. Returns a value suitable
332for the I<display> parameter of screenshot, or undef.
333
334=item Imager::Screenshot::x11_close I<display>
335
336Closes a display returned by Imager::Screenshot::x11_open().
337
338=back
339
62b84c46
TC
340=head1 TAGS
341
342screenshot() sets a number of tags in the images it returns, these are:
343
344=over
345
346=item *
347
348ss_left - the distance between the left side of the window and the
349left side of the captured area. The same value as the I<left>
350parameter when that is positive.
351
352=item *
353
354ss_top - the distance between the top side of the window the top side
355of the captured area. The same value at the I<top> parameter when
356that is positive.
357
358=item *
359
360ss_window_width - the full width of the window.
361
362=item *
363
364ss_window_height - the full height of the window.
365
366=item *
367
368ss_type - the type of capture done, either "Win32" or "X11".
369
370=back
371
372To cheaply get the window size you can capture a single pixel:
373
374 my $im = screenshot(right => 1, bottom => 1);
375 my $window_width = $im->tags(name => 'ss_window_width');
376 my $window_height = $im->tags(name => 'ss_window_height');
377
87cd516f
TC
378=head1 CAVEATS
379
380It's possible to have more than one grab driver available, for
381example, Win32 and X11, and which is used can have an effect on the
382result.
383
0cc0b6d7
TC
384Under Win32 or OS X, if there's a screesaver running, then you grab
385the results of the screensaver.
386
387On OS X, you can grab the display from an ssh session as long as the
388ssh session is under the same user as the currently active user on the
389display.
87cd516f
TC
390
391Grabbing the root window on a rootless server (eg. Cygwin/X) may not
62b84c46
TC
392grab the background that you see. In fact, when I tested under
393Cygwin/X I got the xterm window contents even when the Windows
394screensaver was running. The root window captured appeared to be that
395generated by my window manager.
87cd516f 396
54f11a66
TC
397Grabbing a window with other windows overlaying it will capture the
398content of those windows where they hide the window you want to
399capture. You may want to raise the window to top. This may be a
400security concern if the overlapping windows contain any sensitive
401information - true for any screen capture.
402
967e4c21
TC
403=head1 LICENSE
404
405Imager::Screenshot is licensed under the same terms as Perl itself.
406
33f803d8
TC
407=head1 TODO
408
409Future plans include:
410
411=over
412
413=item *
414
33f803d8
TC
415window name searches - currently screenshot() requires a window
416identifier of some sort, it would be more usable if we could supply
417some other identifier, either a window title or a window class name.
418
419=back
420
967e4c21
TC
421=head1 AUTHOR
422
423Tony Cook <tonyc@cpan.org>
424
425=cut
426
427