/[dotgnu-pnet]/pnetlib/Xsharp/DoubleBuffer.cs
ViewVC logotype

Contents of /pnetlib/Xsharp/DoubleBuffer.cs

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.5 - (show annotations) (download)
Thu Mar 10 17:30:02 2005 UTC (19 years, 1 month ago) by darkdust
Branch: MAIN
CVS Tags: r_0_7_4, r_0_7_2, r_0_7_0
Changes since 1.4: +6 -1 lines
- Xsharp/DoubleBuffer.cs: clear background either when not using Xdbe or when
  using Xdbe and background is transparent

1 /*
2 * DoubleBuffer.cs - Double buffer drawable for widgets.
3 *
4 * Copyright (C) 2004 Southern Storm Software, Pty Ltd.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21 namespace Xsharp
22 {
23
24 using System;
25 using OpenSystem.Platform.X11;
26
27 /// <summary>
28 /// <para>The <see cref="T:Xsharp.DoubleBuffer"/> class manages a
29 /// background buffer for an input-output widget, to streamline
30 /// paint operations and reduce flicker.</para>
31 ///
32 /// <para>To draw into a double-buffer, create a
33 /// <see cref="T:Xsharp.Graphics"/> object, passing the double buffer
34 /// as the argument. When the graphics object is disposed, the contents
35 /// of the buffer will be flushed to the on-screen widget.</para>
36 /// </summary>
37 public class DoubleBuffer : Drawable
38 {
39 // Internal state.
40 private InputOutputWidget widget;
41 private bool usesXdbe;
42
43 /// <summary>
44 /// <para>Constructs a new <see cref="T:Xsharp.DoubleBuffer"/>
45 /// instance.</para>
46 /// </summary>
47 ///
48 /// <param name="widget">
49 /// <para>The widget to attach the double buffer to.</para>
50 /// </param>
51 ///
52 /// <exception cref="T:System.ArgumentNullException">
53 /// <para>Raised if <paramref name="widget"/> is <see langword="null"/>.
54 /// </para>
55 /// </exception>
56 public DoubleBuffer(InputOutputWidget widget)
57 : base(GetDisplay(widget), GetScreen(widget),
58 DrawableKind.DoubleBuffer)
59 {
60 this.widget = widget;
61 this.width = widget.width;
62 this.height = widget.height;
63 try
64 {
65 IntPtr display = dpy.Lock();
66
67 // Determine if the X server supports double buffering.
68 try
69 {
70 Xlib.Xint major, minor;
71 if(Xlib.XdbeQueryExtension
72 (display, out major, out minor)
73 != XStatus.Zero)
74 {
75 usesXdbe = true;
76 }
77 else
78 {
79 usesXdbe = false;
80 }
81 }
82 catch(Exception)
83 {
84 // Xdbe functions are not present in "Xext".
85 usesXdbe = false;
86 }
87
88 // Create the back buffer or pixmap, as appropriate.
89 if(usesXdbe)
90 {
91 handle = Xlib.XdbeAllocateBackBufferName
92 (display, widget.GetWidgetHandle(),
93 Xlib.XdbeSwapAction.Background);
94 }
95 else
96 {
97 handle = (XDrawable)
98 Xlib.XCreatePixmap
99 (display, (XDrawable)
100 Xlib.XRootWindowOfScreen(screen.screen),
101 (uint)width, (uint)height,
102 (uint)Xlib.XDefaultDepthOfScreen
103 (screen.screen));
104 }
105 }
106 finally
107 {
108 dpy.Unlock();
109 }
110 }
111
112 // Get the display and screen from a widget, after checking for null.
113 private static Display GetDisplay(InputOutputWidget widget)
114 {
115 if(widget == null)
116 {
117 throw new ArgumentNullException("widget");
118 }
119 return widget.dpy;
120 }
121 private static Screen GetScreen(InputOutputWidget widget)
122 {
123 if(widget == null)
124 {
125 throw new ArgumentNullException("widget");
126 }
127 return widget.screen;
128 }
129
130 /// <summary>
131 /// <para>Destroy this drawable if it is currently active.</para>
132 /// </summary>
133 public override void Destroy()
134 {
135 try
136 {
137 IntPtr display = dpy.Lock();
138 if(handle != XDrawable.Zero)
139 {
140 if(usesXdbe)
141 {
142 Xlib.XdbeDeallocateBackBufferName(display, handle);
143 }
144 else
145 {
146 Xlib.XFreePixmap(display, (XPixmap)handle);
147 }
148 handle = XDrawable.Zero;
149 }
150 }
151 finally
152 {
153 dpy.Unlock();
154 }
155 }
156
157 /// <summary>
158 /// <para>Get the widget that underlies this double buffer.</para>
159 /// </summary>
160 ///
161 /// <value>
162 /// <para>Returns the widget object.</para>
163 /// </value>
164 public InputOutputWidget Widget
165 {
166 get
167 {
168 return widget;
169 }
170 }
171
172 // Start a double buffer drawing operation.
173 internal void Start(Graphics graphics)
174 {
175 // Re-create the pixmap object if the widget size has changed.
176 if(!usesXdbe)
177 {
178 if(widget.width != width || widget.height != height)
179 {
180 try
181 {
182 IntPtr display = dpy.Lock();
183 if(handle != XDrawable.Zero)
184 {
185 Xlib.XFreePixmap(display, (XPixmap)handle);
186 }
187 handle = (XDrawable)
188 Xlib.XCreatePixmap
189 (display, (XDrawable)
190 Xlib.XRootWindowOfScreen(screen.screen),
191 (uint)(widget.Width),
192 (uint)(widget.Height),
193 (uint)Xlib.XDefaultDepthOfScreen
194 (screen.screen));
195 }
196 finally
197 {
198 dpy.Unlock();
199 }
200 }
201 }
202
203 // Copy the width and height values from the widget.
204 width = widget.Width;
205 height = widget.Height;
206 }
207
208 // Clear a double buffer at the start of a drawing operation.
209 internal void ClearAtStart(Graphics graphics)
210 {
211 // Fill the pixmap with the background color if necessary.
212 // We don't have to do this with Xdbe buffers because the
213 // X server should have already taken care of it for us
214 // during the last expose operation on the widget.
215
216 // [Marc Haisenko] I'm experiencing a strange bug if double
217 // buffering is enabled and certain widgets use a transparent
218 // background color... this is fixed by clearing the buffer.
219 // But I don't think this is the cause...
220 if ((!usesXdbe) || (widget.Background.Index == StandardColor.Inherit))
221 {
222 graphics.Clear();
223 }
224 }
225
226 // End a double buffer drawing operation.
227 internal void End(Graphics graphics)
228 {
229 try
230 {
231 IntPtr display = dpy.Lock();
232 if(handle != XDrawable.Zero)
233 {
234 if(usesXdbe)
235 {
236 Xlib.XdbeSwapInfo info = new Xlib.XdbeSwapInfo();
237 info.swap_window = widget.GetWidgetHandle();
238 info.swap_action = Xlib.XdbeSwapAction.Background;
239 Xlib.XdbeSwapBuffers(display, ref info, 1);
240 }
241 else
242 {
243 using(Graphics g = new Graphics(widget))
244 {
245 Xlib.XCopyArea
246 (display, handle,
247 widget.GetGCHandle(), g.gc, 0, 0,
248 (uint)width, (uint)height, 0, 0);
249 }
250 }
251 }
252 }
253 finally
254 {
255 dpy.Unlock();
256 }
257 }
258
259 } // class DoubleBuffer
260
261 } // namespace Xsharp

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26