1#!/usr/local/bin/perl -w
2
3# Copyright 2011, 2017 Kevin Ryde
4
5# This file is part of X11-Protocol-Other.
6#
7# X11-Protocol-Other is free software; you can redistribute it and/or
8# modify it under the terms of the GNU General Public License as published
9# by the Free Software Foundation; either version 3, or (at your option) any
10# later version.
11#
12# X11-Protocol-Other is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
15# Public License for more details.
16#
17# You should have received a copy of the GNU General Public License along
18# with X11-Protocol-Other.  If not, see <http://www.gnu.org/licenses/>.
19
20
21# Usage: perl dbe-swap.pl
22#
23# This is a simple example of double buffer swapping for drawing.  In the
24# loop below drawing is done to the back buffer then swapped to the front to
25# display.
26#
27# The drawing shows alternately a circle and square.  The new figure is
28# drawn to the back buffer and then swapped to the front so it changes
29# immediately, without a separate clear and draw which the user might see as
30# a flash or flicker.  Of course a circle or square will draw fast enough
31# that double buffering is hardly needed, but more complex contents can
32# benefit.
33#
34# When a window gets an "expose", as happens here on the initial MapWindow,
35# the back buffer is cleared to the window background the same as the window
36# itself.  So if the buffer is allocated before the first expose then
37# there's no need to explicitly erase the back buffer.
38#
39# In a realistic program of course you'd listen and read events from the
40# server in between drawing, and might wait for at least one server
41# round-trip between drawing so as not to hammer the server it it's under a
42# heavy load.  Could wait a certain time or certain number of frames for a
43# synchronizing reply, in case it's network latency rather than server load.
44#
45
46use strict;
47use X11::Protocol;
48
49my $X = X11::Protocol->new;
50if (! $X->init_extension('DOUBLE-BUFFER')) {
51  print "DOUBLE-BUFFER not available on the server\n";
52  exit 1;
53}
54
55my $visual = $X->root_visual;
56my ($info_aref) = $X->DbeGetVisualInfo ($X->root);
57my %hash = @$info_aref;
58if (! $hash{$visual}) {
59  print "DOUBLE-BUFFER not available for root visual\n";
60  exit 1;
61}
62
63my $window = $X->new_rsrc;
64$X->CreateWindow ($window,
65                  $X->root,         # parent
66                  'InputOutput',    # class
67                  0,                # depth, from parent
68                  'CopyFromParent', # visual
69                  0,0,              # x,y
70                  50,50,            # width,height
71                  0,                # border
72                  background_pixel => $X->black_pixel);
73
74my $gc = $X->new_rsrc;
75$X->CreateGC ($gc, $window, foreground => $X->white_pixel);
76
77my $buffer = $X->new_rsrc;
78$X->DbeAllocateBackBufferName ($window, $buffer, 'Background');
79
80$X->MapWindow ($window);
81sleep 1;
82
83for (;;) {
84  $X->PolyRectangle ($buffer, $gc, [ 10,10, 29,29 ]);
85  $X->DbeSwapBuffers ($window, 'Background');
86  $X->flush;
87  sleep 1;
88
89  $X->PolyArc ($buffer, $gc, [7,7, 35,35, 0, 360*64]);
90  $X->DbeSwapBuffers ($window, 'Background');
91  $X->flush;
92  sleep 1;
93}
94
95exit 0;
96