]> git.sesse.net Git - ccbs/blob - bigscreen/tinyptc/xdbe.c
Port to pqxx3, where we need the widestring traits available at parse time.
[ccbs] / bigscreen / tinyptc / xdbe.c
1 /*
2  * TinyPTC x11 v0.7.3 X Double Buffer Extension target
3  * Copyright (C) 2001-2002 Alessandro Gatti <a.gatti@tiscali.it>
4  * 
5  * http://www.sourceforge.net/projects/tinyptc/
6  * 
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.
11  *
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.
16  *
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
20  *
21  */
22
23 /* #includes */
24
25 #include <X11/Xlib.h>
26 #include <X11/Xutil.h>
27 #include <X11/extensions/Xdbe.h>
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <limits.h>
31 #include "tinyptc.h"
32
33 #ifdef __PTC_XDBE__
34
35 #define __PTC_FROM_SOURCE
36
37 #include "xdbe.h"
38
39 /* Open the screen */
40
41 int
42 ptc_open (char *title, int width, int height)
43 {
44   /* Open a display on the current root window */
45   ptc_display = XOpenDisplay (NULL);
46   if (ptc_display == NULL)
47     {
48       return PTC_FAILURE;
49     }
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 */
55   ptc_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;
59        ptc_pixmap_counter++)
60     {
61       if (ptc_depth == ptc_pixmap_formats[ptc_pixmap_counter].depth)
62         {
63           /* Set the right value */
64           ptc_converter_depth =
65             ptc_pixmap_formats[ptc_pixmap_counter].bits_per_pixel;
66         }
67     }
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 */
73   ptc_convert =
74     ptc_request_converter (ptc_converter_depth, ptc_visual->red_mask,
75                            ptc_visual->green_mask, ptc_visual->blue_mask);
76   if (!ptc_convert)
77     {
78       /* Close the display */
79       XCloseDisplay (ptc_display);
80       return 0;
81     }
82   /* Get the actual bytes-per-pixel value */
83   switch (ptc_converter_depth)
84     {
85     case 8:
86       ptc_output_pitch = 1;
87       break;
88     case 15:
89       ptc_output_pitch = 2;
90       break;
91     case 16:
92       ptc_output_pitch = 2;
93       break;
94     case 24:
95       ptc_output_pitch = 3;
96       break;
97     case 32:
98       ptc_output_pitch = 4;
99       break;
100     }
101   /* Allocate the temporary buffer */
102   ptc_buffer = (char *) malloc (width * height * ptc_output_pitch);
103   if (ptc_buffer == NULL)
104     {
105       XCloseDisplay (ptc_display);
106       return PTC_FAILURE;
107     }
108 #else
109   /* It runs only on a 32bpp display if no conversions were activated */
110   if (ptc_converter_depth != 32)
111     {
112       XCloseDisplay (ptc_display);
113       return PTC_FAILURE;
114     }
115 #endif /* __PTC_ENABLE_CONVERSIONS__ */
116
117   /* Check for Xdbe extension */
118   if (!XdbeQueryExtension
119       (ptc_display, &ptc_dbe_major_version, &ptc_dbe_minor_version))
120     {
121       XCloseDisplay (ptc_display);
122       return PTC_FAILURE;
123     }
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)
129     {
130       XCloseDisplay (ptc_display);
131       return PTC_FAILURE;
132     }
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;
138        ptc_dbe_counter++)
139     {
140       if (ptc_dbe_visualptr[ptc_dbe_counter].depth == ptc_depth)
141         {
142           if (ptc_dbe_visualptr[ptc_dbe_counter].perflevel >
143               ptc_dbe_best_performance)
144             {
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;
148             }
149         }
150     }
151   /* Deallocate visual info data */
152   XdbeFreeVisualInfo (ptc_dbe_visual_infoptr);
153   /* No suitable visuals */
154   if (ptc_dbe_best_visual == 0)
155     {
156       XCloseDisplay (ptc_display);
157       return PTC_FAILURE;
158     }
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;
173 #else
174   /* Dock the window on the top-left corner */
175   ptc_x_position = 0;
176   ptc_y_position = 0;
177 #endif /* __PTC_CENTER_WINDOW__ */
178   /* Create the window */
179   ptc_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 */
208   ptc_ximage =
209     XCreateImage (ptc_display, CopyFromParent, ptc_depth, ZPixmap, 0, NULL,
210                   width, height, 32, width * 4);
211   /* Allocate the back buffers */
212   ptc_dbe_backbuffer =
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;
219   return PTC_SUCCESS;
220 }
221
222 /* Update the screen */
223
224 int
225 ptc_update (void *buffer)
226 {
227   char *ptc_buffer;
228
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;
236        ptc_blitcounter++)
237     {
238       /* Conversion */
239       ptc_convert (ptc_buffer + ptc_source_index,
240                    (ptc_ximage->data) + ptc_destination_index,
241                    ptc_viewport_width);
242       /* Pointers update */
243       ptc_source_index += ptc_viewport_width * sizeof (int);
244       ptc_destination_index += ptc_viewport_width * ptc_output_pitch;
245     }
246 #else
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);
255   /* Swap */
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 ())
263     {
264 #ifdef __PTC_CLEANUP_CALLBACK__
265       ptc_cleanup_callback ();
266 #endif /* __PTC_CLEANUP_CALLBACK__ */
267       ptc_close ();
268       exit (0);
269     }
270   return PTC_SUCCESS;
271 }
272
273 /* Process events */
274
275 int
276 ptc_process_events (void)
277 {
278   XEvent ptc_xevent;
279   KeySym ptc_keysym;
280   /* Check if there are events waiting in the display's queue */
281   if (XPending (ptc_display))
282     {
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)
287         {
288           /* Get the keysym */
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__)
292             {
293               /* Check if it was the escape key */
294               if ((ptc_keysym & 0xFF) == __PTC_ESCAPE_KEY__)
295                 {
296                   return PTC_SUCCESS;
297                 }
298             }
299         }
300     }
301   return PTC_FAILURE;
302 }
303
304 /* Close the screen */
305
306 void
307 ptc_close (void)
308 {
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 */
320   if (ptc_buffer)
321     {
322       free (ptc_buffer);
323     }
324 }
325
326 #endif /* __PTC_XDBE__ */