2 * TinyPTC x11 v0.7.3 X Shared Memory Extension target
3 * Copyright (C) 2000-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/XShm.h>
38 #define __PTC_FROM_SOURCE
45 ptc_open (char *title, int width, int height)
47 /* Open a display on the current root window */
48 ptc_display = XOpenDisplay (NULL);
49 if (ptc_display == NULL)
53 /* Get the default screen associated with the previously opened display */
54 ptc_screen = DefaultScreen (ptc_display);
55 /* Get the default visual */
56 ptc_visual = DefaultVisual (ptc_display, ptc_screen);
57 /* Get screen bitdepth */
58 ptc_depth = DefaultDepth (ptc_display, ptc_screen);
59 /* Get a pointer to the supported pixmap formats */
61 XListPixmapFormats (ptc_display, &ptc_pixmap_format_count);
62 /* Check if there's one that's suitable */
63 for (ptc_pixmap_counter = 0; ptc_pixmap_counter < ptc_pixmap_format_count;
66 if (ptc_depth == ptc_pixmap_formats[ptc_pixmap_counter].depth)
68 /* Set the right value */
70 ptc_pixmap_formats[ptc_pixmap_counter].bits_per_pixel;
73 XFree (ptc_pixmap_formats);
74 #ifdef __PTC_ENABLE_CONVERSIONS__
75 /* Check if a converter is avaliable */
77 ptc_request_converter (ptc_converter_depth, ptc_visual->red_mask,
78 ptc_visual->green_mask, ptc_visual->blue_mask);
81 /* Close the display */
82 XCloseDisplay (ptc_display);
85 /* Get the actual bytes-per-pixel value */
86 switch (ptc_converter_depth)
101 ptc_output_pitch = 4;
104 /* Allocate the temporary buffer */
105 ptc_buffer = (char *) malloc (width * height * ptc_output_pitch);
106 if (ptc_buffer == NULL)
108 XCloseDisplay (ptc_display);
112 /* It runs only on a 32bpp display if no conversions were activated */
113 if (ptc_converter_depth != 32)
115 XCloseDisplay (ptc_display);
118 #endif /* __PTC_ENABLE_CONVERSIONS__ */
119 /* Check for XShm extension */
120 if (!XShmQueryExtension (ptc_display))
122 XCloseDisplay (ptc_display);
125 /* Get screen dimensions */
126 ptc_screen_width = DisplayWidth (ptc_display, ptc_screen);
127 ptc_screen_height = DisplayHeight (ptc_display, ptc_screen);
128 /* Get the default root window */
129 ptc_root_window = DefaultRootWindow (ptc_display);
130 /* Initialize window's attribute structure */
131 ptc_window_attributes.border_pixel = BlackPixel (ptc_display, ptc_screen);
132 ptc_window_attributes.background_pixel =
133 BlackPixel (ptc_display, ptc_screen);
134 ptc_window_attributes.backing_store = NotUseful;
135 #ifdef __PTC_CENTER_WINDOW__
136 /* Center the window on the screen */
137 ptc_x_position = (ptc_screen_width - width) / 2;
138 ptc_y_position = (ptc_screen_height - height) / 2;
140 /* Dock the window on the top-left corner */
143 #endif /* __PTC_CENTER_WINDOW__ */
144 /* Create the window */
146 XCreateWindow (ptc_display, ptc_root_window, ptc_x_position,
147 ptc_y_position, width, height, 0, ptc_depth, InputOutput,
148 ptc_visual, CWBackPixel | CWBorderPixel | CWBackingStore,
149 &ptc_window_attributes);
150 /* Set the window's name */
151 XStoreName (ptc_display, ptc_window, title);
152 /* Tell the server to report only keypress-related events */
153 XSelectInput (ptc_display, ptc_window, KeyPressMask | KeyReleaseMask);
154 /* Initialize window's sizehint definition structure */
155 ptc_window_sizehints.flags = PPosition | PMinSize | PMaxSize;
156 ptc_window_sizehints.x = 0;
157 ptc_window_sizehints.y = 0;
158 ptc_window_sizehints.min_width = width;
159 ptc_window_sizehints.max_width = width;
160 ptc_window_sizehints.min_height = height;
161 ptc_window_sizehints.max_height = height;
162 /* Set the window's sizehint */
163 XSetWMNormalHints (ptc_display, ptc_window, &ptc_window_sizehints);
164 /* Clear the window */
165 XClearWindow (ptc_display, ptc_window);
166 /* Put the window on top of the others */
167 XMapRaised (ptc_display, ptc_window);
168 /* Clear event queue */
169 XFlush (ptc_display);
170 /* Get the default graphic context */
171 ptc_window_gc = DefaultGC (ptc_display, ptc_screen);
172 /* Create an XShmImage */
174 XShmCreateImage (ptc_display, ptc_visual, ptc_depth, ZPixmap, 0,
175 &ptc_shm_segment, width, height);
176 /* Get a shared segment */
177 ptc_shm_segment.shmid =
178 shmget (IPC_PRIVATE, ptc_ximage->bytes_per_line * ptc_ximage->height,
180 /* Initialize XShmImage data buffer pointer */
181 ptc_ximage->data = (char *)shmat (ptc_shm_segment.shmid, 0, 0);
182 /* Save buffer address */
183 ptc_shm_segment.shmaddr = ptc_ximage->data;
184 /* Put the segment in read/write */
185 ptc_shm_segment.readOnly = False;
186 /* Attach the segment to the display */
187 if (!XShmAttach (ptc_display, &ptc_shm_segment))
189 /* Destroy the image */
190 XDestroyImage (ptc_ximage);
191 /* Detach the buffer from the segment */
192 shmdt (ptc_shm_segment.shmaddr);
193 /* Remove the segment */
194 shmctl (ptc_shm_segment.shmid, IPC_RMID, 0);
195 /* Destroy the window */
196 XDestroyWindow (ptc_display, ptc_window);
197 /* Close the display */
198 XCloseDisplay (ptc_display);
201 /* Save windowsize values */
202 ptc_viewport_width = width;
203 ptc_viewport_height = height;
207 /* Update the screen */
210 ptc_update (void *buffer)
214 ptc_buffer=(char *)buffer;
215 /* Copy buffer data into the XShmImage */
216 #ifdef __PTC_ENABLE_CONVERSIONS__
217 ptc_source_index = 0;
218 ptc_destination_index = 0;
219 /* Convert the image line by line */
220 for (ptc_blitcounter = 0; ptc_blitcounter < ptc_viewport_height;
224 ptc_convert (ptc_buffer + ptc_source_index,
225 (ptc_ximage->data) + ptc_destination_index,
227 /* Pointers update */
228 ptc_source_index += ptc_viewport_width * sizeof (int);
229 ptc_destination_index += ptc_viewport_width * ptc_output_pitch;
233 memcpy (ptc_ximage->data, buffer,
234 ptc_viewport_width * ptc_viewport_height * sizeof (int));
235 #endif /* __PTC_ENABLE_CONVERSIONS__ */
236 /* Synchronize the event queue */
237 XSync (ptc_display, 0);
238 /* Put the buffer on the window */
239 XShmPutImage (ptc_display, ptc_window, ptc_window_gc, ptc_ximage, 0, 0, 0,
240 0, ptc_viewport_width, ptc_viewport_height, False);
241 /* Process incoming events */
242 if (ptc_process_events ())
244 #ifdef __PTC_CLEANUP_CALLBACK__
245 ptc_cleanup_callback ();
246 #endif /* __PTC_CLEANUP_CALLBACK__ */
256 ptc_process_events (void)
260 /* Check if there are events waiting in the display's queue */
261 if (XPending (ptc_display))
263 /* Get the next event in queue */
264 XNextEvent (ptc_display, &ptc_xevent);
265 /* Check if it's a keypress event */
266 if (ptc_xevent.type == KeyPress)
269 ptc_keysym = XLookupKeysym (&ptc_xevent.xkey, 0);
270 /* Check if the key pressed was a function one */
271 if ((ptc_keysym >> 8) == __PTC_FUNCTION_KEY__)
273 /* Check if it was the escape key */
274 if ((ptc_keysym & 0xFF) == __PTC_ESCAPE_KEY__)
284 /* Close the screen */
289 /* Detach the segment from the display */
290 XShmDetach (ptc_display, &ptc_shm_segment);
291 /* Destroy the XShmImage */
292 XDestroyImage (ptc_ximage);
293 /* Detach the buffer from the segment */
294 shmdt (ptc_shm_segment.shmaddr);
295 /* Remove the segment */
296 shmctl (ptc_shm_segment.shmid, IPC_RMID, 0);
297 /* Close the window */
298 XDestroyWindow (ptc_display, ptc_window);
299 /* Close the display */
300 XCloseDisplay (ptc_display);
301 /* Deallocate the buffer */
308 #endif /* __PTC_XSHM__ */