2 * TinyPTC x11 v0.7.3 X Double Buffer Extension target
3 * Copyright (C) 2001-2002 Alessandro Gatti <a.gatti@tiscali.it>
5 * http://www.sourceforge.net/projects/tinyptc/
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
12 * This library 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
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 #include <X11/Xutil.h>
27 #include <X11/extensions/Xdbe.h>
35 #define __PTC_FROM_SOURCE
42 ptc_open (char *title, int width, int height)
44 /* Open a display on the current root window */
45 ptc_display = XOpenDisplay (NULL);
46 if (ptc_display == NULL)
50 /* Get the default screen associated with the previously opened display */
51 ptc_screen = DefaultScreen (ptc_display);
52 /* Get screen bitdepth */
53 ptc_depth = DefaultDepth (ptc_display, ptc_screen);
54 /* Get a pointer to the supported pixmap formats */
56 XListPixmapFormats (ptc_display, &ptc_pixmap_format_count);
57 /* Check if there's one that's suitable */
58 for (ptc_pixmap_counter = 0; ptc_pixmap_counter < ptc_pixmap_format_count;
61 if (ptc_depth == ptc_pixmap_formats[ptc_pixmap_counter].depth)
63 /* Set the right value */
65 ptc_pixmap_formats[ptc_pixmap_counter].bits_per_pixel;
68 XFree (ptc_pixmap_formats);
69 #ifdef __PTC_ENABLE_CONVERSIONS__
70 /* Get the default visual */
71 ptc_visual = DefaultVisual (ptc_display, ptc_screen);
72 /* Check if a converter is avaliable */
74 ptc_request_converter (ptc_converter_depth, ptc_visual->red_mask,
75 ptc_visual->green_mask, ptc_visual->blue_mask);
78 /* Close the display */
79 XCloseDisplay (ptc_display);
82 /* Get the actual bytes-per-pixel value */
83 switch (ptc_converter_depth)
101 /* Allocate the temporary buffer */
102 ptc_buffer = (char *) malloc (width * height * ptc_output_pitch);
103 if (ptc_buffer == NULL)
105 XCloseDisplay (ptc_display);
109 /* It runs only on a 32bpp display if no conversions were activated */
110 if (ptc_converter_depth != 32)
112 XCloseDisplay (ptc_display);
115 #endif /* __PTC_ENABLE_CONVERSIONS__ */
117 /* Check for Xdbe extension */
118 if (!XdbeQueryExtension
119 (ptc_display, &ptc_dbe_major_version, &ptc_dbe_minor_version))
121 XCloseDisplay (ptc_display);
124 /* Get Xdbe visual info */
125 ptc_dbe_drawables = 0;
126 ptc_dbe_visual_infoptr =
127 XdbeGetVisualInfo (ptc_display, &ptc_root_window, &ptc_dbe_drawables);
128 if (ptc_dbe_visual_infoptr == NULL)
130 XCloseDisplay (ptc_display);
133 /* Choose the best visual */
134 ptc_dbe_best_performance = INT_MIN;
135 ptc_dbe_best_visual = 0;
136 ptc_dbe_visualptr = ptc_dbe_visual_infoptr->visinfo;
137 for (ptc_dbe_counter = 0; ptc_dbe_counter < ptc_dbe_visual_infoptr->count;
140 if (ptc_dbe_visualptr[ptc_dbe_counter].depth == ptc_depth)
142 if (ptc_dbe_visualptr[ptc_dbe_counter].perflevel >
143 ptc_dbe_best_performance)
145 ptc_dbe_best_performance =
146 ptc_dbe_visualptr[ptc_dbe_counter].perflevel;
147 ptc_dbe_best_visual = ptc_dbe_visualptr[ptc_dbe_counter].visual;
151 /* Deallocate visual info data */
152 XdbeFreeVisualInfo (ptc_dbe_visual_infoptr);
153 /* No suitable visuals */
154 if (ptc_dbe_best_visual == 0)
156 XCloseDisplay (ptc_display);
159 /* Get screen dimensions */
160 ptc_screen_width = DisplayWidth (ptc_display, ptc_screen);
161 ptc_screen_height = DisplayHeight (ptc_display, ptc_screen);
162 /* Get the default root window */
163 ptc_root_window = DefaultRootWindow (ptc_display);
164 /* Initialize window's attribute structure */
165 ptc_window_attributes.border_pixel = BlackPixel (ptc_display, ptc_screen);
166 ptc_window_attributes.background_pixel =
167 BlackPixel (ptc_display, ptc_screen);
168 ptc_window_attributes.backing_store = NotUseful;
169 #ifdef __PTC_CENTER_WINDOW__
170 /* Center the window on the screen */
171 ptc_x_position = (ptc_screen_width - width) / 2;
172 ptc_y_position = (ptc_screen_height - height) / 2;
174 /* Dock the window on the top-left corner */
177 #endif /* __PTC_CENTER_WINDOW__ */
178 /* Create the window */
180 XCreateWindow (ptc_display, ptc_root_window, ptc_x_position,
181 ptc_y_position, width, height, 0, ptc_depth, InputOutput,
182 (Visual *) & ptc_dbe_best_visual,
183 CWBackPixel | CWBorderPixel | CWBackingStore,
184 &ptc_window_attributes);
185 /* Set the window's name */
186 XStoreName (ptc_display, ptc_window, title);
187 /* Tell the server to report only keypress-related events */
188 XSelectInput (ptc_display, ptc_window, KeyPressMask | KeyReleaseMask);
189 /* Initialize window's sizehint definition structure */
190 ptc_window_sizehints.flags = PPosition | PMinSize | PMaxSize;
191 ptc_window_sizehints.x = 0;
192 ptc_window_sizehints.y = 0;
193 ptc_window_sizehints.min_width = width;
194 ptc_window_sizehints.max_width = width;
195 ptc_window_sizehints.min_height = height;
196 ptc_window_sizehints.max_height = height;
197 /* Set the window's sizehint */
198 XSetWMNormalHints (ptc_display, ptc_window, &ptc_window_sizehints);
199 /* Clear the window */
200 XClearWindow (ptc_display, ptc_window);
201 /* Put the window on top of the others */
202 XMapRaised (ptc_display, ptc_window);
203 /* Clear event queue */
204 XFlush (ptc_display);
205 /* Get the default graphic context */
206 ptc_window_gc = DefaultGC (ptc_display, ptc_screen);
207 /* Create an XImage */
209 XCreateImage (ptc_display, CopyFromParent, ptc_depth, ZPixmap, 0, NULL,
210 width, height, 32, width * 4);
211 /* Allocate the back buffers */
213 XdbeAllocateBackBufferName (ptc_display, ptc_window, XdbeBackground);
214 ptc_dbe_swapinfo.swap_window = ptc_window;
215 ptc_dbe_swapinfo.swap_action = XdbeBackground;
216 /* Save windowsize values */
217 ptc_viewport_width = width;
218 ptc_viewport_height = height;
222 /* Update the screen */
225 ptc_update (void *buffer)
229 ptc_buffer=(char *)buffer;
230 #ifdef __PTC_ENABLE_CONVERSIONS__
231 ptc_ximage->data = ptc_buffer;
232 ptc_source_index = 0;
233 ptc_destination_index = 0;
234 /* Convert the image line by line */
235 for (ptc_blitcounter = 0; ptc_blitcounter < ptc_viewport_height;
239 ptc_convert (ptc_buffer + ptc_source_index,
240 (ptc_ximage->data) + ptc_destination_index,
242 /* Pointers update */
243 ptc_source_index += ptc_viewport_width * sizeof (int);
244 ptc_destination_index += ptc_viewport_width * ptc_output_pitch;
247 /* Set XImage's data buffer value with the supplied buffer pointer */
248 ptc_ximage->data = ptc_buffer;
249 #endif /* __PTC_ENABLE_CONVERSIONS__ */
250 /* Put the buffer on the back buffer */
251 XPutImage (ptc_display, ptc_dbe_backbuffer, ptc_window_gc, ptc_ximage, 0, 0,
252 0, 0, ptc_viewport_width, ptc_viewport_height);
253 /* Start the swap operation */
254 XdbeBeginIdiom (ptc_display);
256 XdbeSwapBuffers (ptc_display, &ptc_dbe_swapinfo, 1);
257 /* End the swap operation */
258 XdbeEndIdiom (ptc_display);
259 /* Check for incoming events */
260 XFlush (ptc_display);
261 /* Process incoming events */
262 if (ptc_process_events ())
264 #ifdef __PTC_CLEANUP_CALLBACK__
265 ptc_cleanup_callback ();
266 #endif /* __PTC_CLEANUP_CALLBACK__ */
276 ptc_process_events (void)
280 /* Check if there are events waiting in the display's queue */
281 if (XPending (ptc_display))
283 /* Get the next event in queue */
284 XNextEvent (ptc_display, &ptc_xevent);
285 /* Check if it's a keypress event */
286 if (ptc_xevent.type == KeyPress)
289 ptc_keysym = XLookupKeysym (&ptc_xevent.xkey, 0);
290 /* Check if the key pressed was a function one */
291 if ((ptc_keysym >> 8) == __PTC_FUNCTION_KEY__)
293 /* Check if it was the escape key */
294 if ((ptc_keysym & 0xFF) == __PTC_ESCAPE_KEY__)
304 /* Close the screen */
309 /* Deallocate the back buffer */
310 XdbeDeallocateBackBufferName (ptc_display, ptc_dbe_backbuffer);
311 /* Restore XImage's buffer pointer */
312 ptc_ximage->data = NULL;
313 /* Destroy the XImage */
314 XDestroyImage (ptc_ximage);
315 /* Close the window */
316 XDestroyWindow (ptc_display, ptc_window);
317 /* Close the display */
318 XCloseDisplay (ptc_display);
319 /* Deallocate the buffer */
326 #endif /* __PTC_XDBE__ */