]> git.sesse.net Git - ccbs/blob - bigscreen/tinyptc/xlib.c
Fixed a misleading comment.
[ccbs] / bigscreen / tinyptc / xlib.c
1 /*
2  * TinyPTC x11 v0.7.3 Raw XLib target
3  * Copyright (C) 2000-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 <stdio.h>
28 #include <stdlib.h>
29 #include <limits.h>
30 #include "tinyptc.h"
31
32 #ifdef __PTC_XLIB__
33
34 #define __PTC_FROM_SOURCE
35
36 #include "xlib.h"
37
38 /* Open the screen */
39
40 int
41 ptc_open (char *title, int width, int height)
42 {
43   /* Open a display on the current root window */
44   ptc_display = XOpenDisplay (NULL);
45   if (ptc_display == NULL)
46     {
47       return PTC_FAILURE;
48     }
49   /* Get the default screen associated with the previously opened display */
50   ptc_screen = DefaultScreen (ptc_display);
51   /* Get the default visual */
52   ptc_visual = DefaultVisual (ptc_display, ptc_screen);
53   /* Get screen bitdepth */
54   ptc_depth = DefaultDepth (ptc_display, ptc_screen);
55   /* Get a pointer to the supported pixmap formats */
56   ptc_pixmap_formats =
57     XListPixmapFormats (ptc_display, &ptc_pixmap_format_count);
58   /* Check if there's one that's suitable */
59   for (ptc_pixmap_counter = 0; ptc_pixmap_counter < ptc_pixmap_format_count;
60        ptc_pixmap_counter++)
61     {
62       if (ptc_depth == ptc_pixmap_formats[ptc_pixmap_counter].depth)
63         {
64           /* Set the right value */
65           ptc_converter_depth =
66             ptc_pixmap_formats[ptc_pixmap_counter].bits_per_pixel;
67         }
68     }
69   XFree (ptc_pixmap_formats);
70 #ifdef __PTC_ENABLE_CONVERSIONS__
71   /* Check if a converter is avaliable */
72   ptc_convert =
73     ptc_request_converter (ptc_converter_depth, ptc_visual->red_mask,
74                            ptc_visual->green_mask, ptc_visual->blue_mask);
75   if (!ptc_convert)
76     {
77       /* Close the display */
78       XCloseDisplay (ptc_display);
79       return 0;
80     }
81   /* Get the actual bytes-per-pixel value */
82   switch (ptc_converter_depth)
83     {
84     case 8:
85       ptc_output_pitch = 1;
86       break;
87     case 15:
88       ptc_output_pitch = 2;
89       break;
90     case 16:
91       ptc_output_pitch = 2;
92       break;
93     case 24:
94       ptc_output_pitch = 3;
95       break;
96     case 32:
97       ptc_output_pitch = 4;
98       break;
99     }
100   /* Allocate the temporary buffer */
101   ptc_buffer = (char *) malloc (width * height * ptc_output_pitch);
102   if (ptc_buffer == NULL)
103     {
104       XCloseDisplay (ptc_display);
105       return PTC_FAILURE;
106     }
107 #else
108   /* It runs only on a 32bpp display if no conversions were activated */
109   if (ptc_converter_depth != 32)
110     {
111       XCloseDisplay (ptc_display);
112       return PTC_FAILURE;
113     }
114 #endif /* __PTC_ENABLE_CONVERSIONS__ */
115   /* Get screen dimensions */
116   ptc_screen_width = DisplayWidth (ptc_display, ptc_screen);
117   ptc_screen_height = DisplayHeight (ptc_display, ptc_screen);
118   /* Get the default root window */
119   ptc_root_window = DefaultRootWindow (ptc_display);
120   /* Initialize window's attribute structure */
121   ptc_window_attributes.border_pixel = BlackPixel (ptc_display, ptc_screen);
122   ptc_window_attributes.background_pixel =
123     BlackPixel (ptc_display, ptc_screen);
124   ptc_window_attributes.backing_store = NotUseful;
125 #ifdef __PTC_CENTER_WINDOW__
126   /* Center the window on the screen */
127   ptc_x_position = (ptc_screen_width - width) / 2;
128   ptc_y_position = (ptc_screen_height - height) / 2;
129 #else
130   /* Dock the window on the top-left corner */
131   ptc_x_position = 0;
132   ptc_y_position = 0;
133 #endif /* __PTC_CENTER_WINDOW__ */
134   /* Create the window */
135   ptc_window =
136     XCreateWindow (ptc_display, ptc_root_window, ptc_x_position,
137                    ptc_y_position, width, height, 0, ptc_depth, InputOutput,
138                    ptc_visual, CWBackPixel | CWBorderPixel | CWBackingStore,
139                    &ptc_window_attributes);
140   /* Set the window's name */
141   XStoreName (ptc_display, ptc_window, title);
142   /* Tell the server to report only keypress-related events */
143   XSelectInput (ptc_display, ptc_window, KeyPressMask | KeyReleaseMask);
144   /* Initialize window's sizehint definition structure */
145   ptc_window_sizehints.flags = PPosition | PMinSize | PMaxSize;
146   ptc_window_sizehints.x = 0;
147   ptc_window_sizehints.y = 0;
148   ptc_window_sizehints.min_width = width;
149   ptc_window_sizehints.max_width = width;
150   ptc_window_sizehints.min_height = height;
151   ptc_window_sizehints.max_height = height;
152   /* Set the window's sizehint */
153   XSetWMNormalHints (ptc_display, ptc_window, &ptc_window_sizehints);
154   /* Clear the window */
155   XClearWindow (ptc_display, ptc_window);
156   /* Put the window on top of the others */
157   XMapRaised (ptc_display, ptc_window);
158   /* Clear event queue */
159   XFlush (ptc_display);
160   /* Get the default graphic context */
161   ptc_window_gc = DefaultGC (ptc_display, ptc_screen);
162   /* Create an XImage */
163   ptc_ximage =
164     XCreateImage (ptc_display, CopyFromParent, ptc_depth, ZPixmap, 0, NULL,
165                   width, height, 32, width * ptc_output_pitch);
166   /* Save windowsize values */
167   ptc_viewport_width = width;
168   ptc_viewport_height = height;
169   return PTC_SUCCESS;
170 }
171
172 /* Update the screen */
173
174 int
175 ptc_update (void *buffer)
176 {
177   char *ptc_buffer;
178
179   ptc_buffer=(char *)buffer;
180 #ifdef __PTC_ENABLE_CONVERSIONS__
181   ptc_ximage->data = ptc_buffer;
182   ptc_source_index = 0;
183   ptc_destination_index = 0;
184   /* Convert the image line by line */
185   for (ptc_blitcounter = 0; ptc_blitcounter < ptc_viewport_height;
186        ptc_blitcounter++)
187     {
188       /* Conversion */
189       ptc_convert (ptc_buffer + ptc_source_index,
190                    (ptc_ximage->data) + ptc_destination_index,
191                    ptc_viewport_width);
192       /* Pointers update */
193       ptc_source_index += ptc_viewport_width * sizeof (int);
194       ptc_destination_index += ptc_viewport_width * ptc_output_pitch;
195     }
196 #else
197   /* Set XImage's data buffer value with the supplied buffer pointer */
198   ptc_ximage->data = ptc_buffer;
199 #endif /* __PTC_ENABLE_CONVERSIONS__ */
200   /* Put the buffer on the window */
201   XPutImage (ptc_display, ptc_window, ptc_window_gc, ptc_ximage, 0, 0, 0, 0,
202              ptc_viewport_width, ptc_viewport_height);
203   /* Check for incoming events */
204   XFlush (ptc_display);
205   /* Process incoming events */
206   if (ptc_process_events ())
207     {
208 #ifdef __PTC_CLEANUP_CALLBACK__
209       ptc_cleanup_callback ();
210 #endif /* __PTC_CLEANUP_CALLBACK__ */
211       ptc_close ();
212       exit (0);
213     }
214   return PTC_SUCCESS;
215 }
216
217 /* Process events */
218
219 int
220 ptc_process_events (void)
221 {
222   XEvent ptc_xevent;
223   KeySym ptc_keysym;
224   /* Check if there are events waiting in the display's queue */
225   if (XPending (ptc_display))
226     {
227       /* Get the next event in queue */
228       XNextEvent (ptc_display, &ptc_xevent);
229       /* Check if it's a keypress event */
230       if (ptc_xevent.type == KeyPress)
231         {
232           /* Get the keysym */
233           ptc_keysym = XLookupKeysym (&ptc_xevent.xkey, 0);
234           /* Check if the key pressed was a function one */
235           if ((ptc_keysym >> 8) == __PTC_FUNCTION_KEY__)
236             {
237               /* Check if it was the escape key */
238               if ((ptc_keysym & 0xFF) == __PTC_ESCAPE_KEY__)
239                 {
240                   return PTC_SUCCESS;
241                 }
242             }
243         }
244     }
245   return PTC_FAILURE;
246 }
247
248 /* Close the screen */
249
250 void
251 ptc_close (void)
252 {
253   /* Restore XImage's buffer pointer */
254   ptc_ximage->data = NULL;
255   /* Destroy the XImage */
256   XDestroyImage (ptc_ximage);
257   /* Close the window */
258   XDestroyWindow (ptc_display, ptc_window);
259   /* Close the display */
260   XCloseDisplay (ptc_display);
261   /* Deallocate the buffer */
262   if (ptc_buffer)
263     {
264       free (ptc_buffer);
265     }
266 }
267
268 #endif /* __PTC_XLIB__ */