]> git.imager.perl.org - imager-screenshot.git/blame - Screenshot.pm
0.009 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);
136a3eae 13 $VERSION = '0.009';
967e4c21
TC
14 eval {
15 # try XSLoader first, DynaLoader has annoying baggage
16 require XSLoader;
17 XSLoader::load('Imager::Screenshot' => $VERSION);
18 1;
19 } or do {
20 require DynaLoader;
21 push @ISA, 'DynaLoader';
22 bootstrap Imager::Screenshot $VERSION;
23 }
24}
25
26sub screenshot {
27 # lose the class if called as a method
28 @_ % 2 == 1 and shift;
29
87cd516f
TC
30 my %opts =
31 (
32 decor => 0,
33 display => 0,
34 left => 0,
35 top => 0,
36 right => 0,
37 bottom => 0,
38 @_);
967e4c21
TC
39
40 my $result;
967e4c21
TC
41 if (defined $opts{hwnd}) {
42 defined &_win32
43 or die "Win32 driver not enabled\n";
87cd516f
TC
44 $result = _win32($opts{hwnd}, $opts{decor}, $opts{left}, $opts{top},
45 $opts{right}, $opts{bottom});
967e4c21
TC
46 }
47 elsif (defined $opts{id}) { # X11 window id
48 defined &_x11
49 or die "X11 driver not enabled\n";
87cd516f
TC
50 $result = _x11($opts{display}, $opts{id}, $opts{left}, $opts{top},
51 $opts{right}, $opts{bottom});
967e4c21
TC
52 }
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},
85 $opts{right}, $opts{bottom}) :
86 defined &_x11 ? _x11($opts{display}, 0, $opts{left}, $opts{top},
87 $opts{right}, $opts{bottom}) :
88 die "No drivers enabled\n";
89 }
967e4c21
TC
90
91 unless ($result) {
92 Imager->_set_error(Imager->_error_as_msg());
93 return;
94 }
cd684d4f
TC
95
96 # RT #24992 - the Imager typemap entry is broken pre-0.56, so
97 # wrap it here
98 return bless { IMG => $result }, "Imager";
967e4c21
TC
99}
100
101sub have_win32 {
102 defined &_win32;
103}
104
105sub have_x11 {
106 defined &_x11;
107}
108
109sub x11_open {
110 my $display = _x11_open(@_);
111 unless ($display) {
112 Imager->_set_error(Imager->_error_as_msg);
113 return;
114 }
115
116 return $display;
117}
118
119sub x11_close {
120 _x11_close(shift);
121}
122
1231;
124
125__END__
126
127=head1 NAME
128
129Imager::Screenshot - screenshot to an Imager image
130
131=head1 SYNOPSIS
132
133 use Imager::Screenshot 'screenshot';
134
135 # whole screen
136 my $img = screenshot();
137
138 # Win32 window
139 my $img2 = screenshot(hwnd => $hwnd);
140
141 # X11 window
142 my $img3 = screenshot(display => $display, id => $window_id);
143
144 # X11 tools
145 my $display = Imager::Screenshot::x11_open();
146 Imager::Screenshot::x11_close($display);
147
148 # test for win32 support
149 if (Imager::Screenshot->have_win32) { ... }
150
151 # test for x11 support
152 if (Imager::Screenshot->have_x11) { ... }
153
154
155=head1 DESCRIPTION
156
157Imager::Screenshot captures either a desktop or a specified window and
158returns the result as an Imager image.
159
160Currently the image is always returned as a 24-bit image.
161
162=over
163
164=item screenshot hwnd => I<window handle>
165
166=item screenshot hwnd => I<window handle>, decor => <capture decorations>
167
168Retrieve a screenshot under Win32, if I<window handle> is zero,
169capture the desktop.
170
171By default, window decorations are not captured, if the C<decor>
172parameter is set to true then window decorations are included.
173
174=item screenshot id => I<window id>
175
176=item screenshot id => I<window id>, display => I<display object>
177
178Retrieve a screenshot under X11, if I<id> is zero, capture the root
179window. I<display object> is a integer version of an X11 C< Display *
180>, if this isn't supplied C<screenshot()> will attempt connect to the
181the display specified by $ENV{DISPLAY}.
182
f04a72ea
TC
183Note: taking a screenshot of a remote display is slow.
184
9d2a775a
TC
185=item screenshot widget => I<widget>
186
187=item screenshot widget => I<widget>, display => I<display>
188
189=item screenshot widget => I<widget>, decor => I<capture decorations>
190
191Retrieve a screenshot of a Tk widget, under Win32 or X11, depending on
192how Tk has been built.
193
194If Tk was built for X11 then the display parameter applies.
195
196If Tk was built for Win32 then the decor parameter applies.
197
967e4c21
TC
198=item screenshot
199
9d2a775a 200If no C<id>, C<hwnd> or C<widget> parameter is supplied:
967e4c21
TC
201
202=over
203
204=item *
205
206if Win32 support is compiled, return screenshot(hwnd => 0).
207
208=item *
209
210if X11 support is compiled, return screenshot(id => 0).
211
212=item *
213
214otherwise, die.
215
216=back
217
87cd516f
TC
218You can also supply the following parameters to retrieve a subset of
219the window:
220
221=over
222
223=item *
224
225left
226
227=item *
228
229top
230
231=item *
232
233right
234
235=item *
236
237bottom
238
239=back
240
241If left or top is negative, then treat that as from the right/bottom
242edge of the window.
243
244If right ot bottom is zero or negative then treat as from the
245right/bottom edge of the window.
246
247So setting all 4 values to 0 retrieves the whole window.
248
249 # a 10-pixel wide right edge of the window
250 my $right_10 = screenshot(left => -10, ...);
251
252 # the top-left 100x100 portion of the window
253 my $topleft_100 = screenshot(right => 100, bottom => 100, ...);
254
255 # 10x10 pixel at the bottom right corner
256 my $bott_right_10 = screenshot(left => -10, top => -10, ...);
257
06bbf244
TC
258If screenshot() fails, it will return nothing, and the cause of the
259failure can be retrieved via Imager->errstr, so typical use could be:
260
261 my $img = screenshot(...) or die Imager->errstr;
262
967e4c21
TC
263=item have_win32
264
265Returns true if Win32 support is available.
266
267=item have_x11
268
269Returns true if X11 support is available.
270
271=item Imager::Screenshot::x11_open
272
273=item Imager::Screenshot::x11_open I<display name>
274
275Attempts to open a connection to either the display name in
276$ENV{DISPLAY} or the supplied display name. Returns a value suitable
277for the I<display> parameter of screenshot, or undef.
278
279=item Imager::Screenshot::x11_close I<display>
280
281Closes a display returned by Imager::Screenshot::x11_open().
282
283=back
284
62b84c46
TC
285=head1 TAGS
286
287screenshot() sets a number of tags in the images it returns, these are:
288
289=over
290
291=item *
292
293ss_left - the distance between the left side of the window and the
294left side of the captured area. The same value as the I<left>
295parameter when that is positive.
296
297=item *
298
299ss_top - the distance between the top side of the window the top side
300of the captured area. The same value at the I<top> parameter when
301that is positive.
302
303=item *
304
305ss_window_width - the full width of the window.
306
307=item *
308
309ss_window_height - the full height of the window.
310
311=item *
312
313ss_type - the type of capture done, either "Win32" or "X11".
314
315=back
316
317To cheaply get the window size you can capture a single pixel:
318
319 my $im = screenshot(right => 1, bottom => 1);
320 my $window_width = $im->tags(name => 'ss_window_width');
321 my $window_height = $im->tags(name => 'ss_window_height');
322
87cd516f
TC
323=head1 CAVEATS
324
325It's possible to have more than one grab driver available, for
326example, Win32 and X11, and which is used can have an effect on the
327result.
328
329Under Win32, if there's a screesaver running, then you grab the
330results of the screensaver.
331
332Grabbing the root window on a rootless server (eg. Cygwin/X) may not
62b84c46
TC
333grab the background that you see. In fact, when I tested under
334Cygwin/X I got the xterm window contents even when the Windows
335screensaver was running. The root window captured appeared to be that
336generated by my window manager.
87cd516f 337
54f11a66
TC
338Grabbing a window with other windows overlaying it will capture the
339content of those windows where they hide the window you want to
340capture. You may want to raise the window to top. This may be a
341security concern if the overlapping windows contain any sensitive
342information - true for any screen capture.
343
967e4c21
TC
344=head1 LICENSE
345
346Imager::Screenshot is licensed under the same terms as Perl itself.
347
33f803d8
TC
348=head1 TODO
349
350Future plans include:
351
352=over
353
354=item *
355
54f11a66
TC
356OS X support - I need to find out which APIs to use to do this. I
357found some information on the APIs used for this, but don't have a Mac
358I can test on.
33f803d8
TC
359
360=item *
361
362window name searches - currently screenshot() requires a window
363identifier of some sort, it would be more usable if we could supply
364some other identifier, either a window title or a window class name.
365
366=back
367
967e4c21
TC
368=head1 AUTHOR
369
370Tony Cook <tonyc@cpan.org>
371
372=cut
373
374