source: golgotha/src/i4/video/x11/mitshm.cc @ 80

Last change on this file since 80 was 80, checked in by Sam Hocevar, 15 years ago
  • Adding the Golgotha source code. Not sure what's going to be interesting in there, but since it's all public domain, there's certainly stuff to pick up.
File size: 6.1 KB
Line 
1/********************************************************************** <BR>
2  This file is part of Crack dot Com's free source code release of
3  Golgotha. <a href="http://www.crack.com/golgotha_release"> <BR> for
4  information about compiling & licensing issues visit this URL</a>
5  <PRE> If that doesn't help, contact Jonathan Clark at
6  golgotha_source@usa.net (Subject should have "GOLG" in it)
7***********************************************************************/
8
9#include "video/x11/mitshm.hh"
10#include "video/x11/x11devs.hh"
11#include "error/error.hh"
12
13#include <X11/Xlib.h>
14#include <X11/Xutil.h>
15#include <X11/keysym.h>
16
17#include <sys/ipc.h>
18#include <sys/shm.h>
19#include <X11/extensions/XShm.h>
20#include <signal.h>
21#include <string.h>
22
23class x11_shm_image_actual_class : public x11_shm_image_class
24{
25  public :
26
27  XShmSegmentInfo X_shminfo;   
28  XImage *im;
29  Display *display;
30  GC gc;
31  Window window; 
32
33  x11_shm_image_actual_class(Display *display, Window window, GC gc) :
34    display(display),
35    window(window),
36    gc(gc)
37  { ; }
38
39  i4_bool copy_part_to_vram(x11_shm_extension_class *use,
40                            i4_coord x, i4_coord y,
41                            i4_coord x1, i4_coord y1,
42                            i4_coord x2, i4_coord y2);
43
44  ~x11_shm_image_actual_class();
45} ;
46
47
48
49class x11_shm_extension_actual_class : public x11_shm_extension_class
50{
51  public :
52  virtual void init()
53  {
54    x11_display_instance.shm_extension=this;   // tell the display this extension exsist
55  }
56
57  void note_event(XEvent &ev)
58  {
59    if (ev.type==shm_base+ShmCompletion)
60      need_sync_event=i4_F;
61  }
62
63  virtual i4_bool available(Display *display, char *display_name);
64
65   // actual width and height set by X are returned
66  x11_shm_image_class *create_shm_image(Display *display,
67                                          Window window,
68                                          GC gc,
69                                          Visual *X_visual,
70                                          int visual_depth,
71                                          w16 &width, w16 &height);
72
73  virtual void shutdown(Display *display)
74  {
75    XFlush(display);
76    XSync(display,False);  // maker sure anything with this image is drawn!
77    need_sync_event=i4_F;
78  }
79
80
81  void destroy_shm_image(Display *display, x11_shm_image_class *im);
82} shm_instance;
83
84x11_shm_extension_class::x11_shm_extension_class()
85{
86  need_sync_event=i4_F;
87}
88
89i4_bool x11_shm_extension_actual_class::available(Display *display, char *display_name)
90
91  int major_op;
92
93  if (XQueryExtension(display,"MIT-SHM",&major_op,&shm_base,&shm_error_base))
94  {
95    char *d = display_name;             // make sure the display is local
96    while (*d && (*d != ':')) d++;
97    if (*d) *d = 0;
98    if (strcasecmp(display_name, "unix") && display_name[0]!=0)
99      return i4_F;
100
101    return i4_T;
102  } else return i4_F;
103}
104
105void x11_shm_extension_actual_class::destroy_shm_image(Display *display, x11_shm_image_class *im)
106{
107  XFlush(display);
108  XSync(display,False);  // maker sure anything with this image is drawn!
109
110  // Dettach the memory from the server
111  XShmDetach(display, &((x11_shm_image_actual_class *)im)->X_shminfo);
112
113  // detach the memory from us, it will be deleted!
114  shmdt(((x11_shm_image_actual_class *)im)->X_shminfo.shmaddr);
115
116  delete im;
117}
118
119x11_shm_image_class *x11_shm_extension_actual_class::create_shm_image(Display *display,
120                                                   Window window,
121                                                   GC gc,
122                                                   Visual *X_visual,
123                                                   int visual_depth,
124                                                   w16 &width, w16 &height)   // actual width and height set by X are returned
125{
126  width=(width+3)&(~3);
127  x11_shm_image_actual_class *im=new x11_shm_image_actual_class(display,window,gc);
128 
129
130  im->im = XShmCreateImage(display,
131                           X_visual,
132                           visual_depth,
133                           ZPixmap,
134                           0,
135                           &im->X_shminfo,
136                           width,
137                           height );
138
139  // create the shared memory segment
140  im->X_shminfo.shmid = shmget (IPC_PRIVATE, width*height*I4_BYTES_PER_PIXEL, IPC_CREAT | 0777);
141  if (im->X_shminfo.shmid<0) 
142    i4_error("shmget() failed, go figure");
143
144  im->X_shminfo.readOnly=False;
145 
146
147  // attach to the shared memory segment to us
148  im->im->data = im->X_shminfo.shmaddr = (char *) shmat(im->X_shminfo.shmid, 0, 0);
149  if (!im->im->data)
150    i4_error("shmat() failed, go figure");
151
152
153  // get the X server to attach to it to the X server
154  if (!XShmAttach(display, &im->X_shminfo))
155    i4_error("XShmAttach() failed, go figure");
156
157  XSync(display,False); // make sure segment gets attached
158
159  if (shmctl(im->X_shminfo.shmid,IPC_RMID,NULL)!=0)
160    i4_error("shmctl failed, why?");
161
162  im->data=(w8 *) (im->im->data);
163  return im;
164}
165
166x11_shm_image_actual_class::~x11_shm_image_actual_class()
167{
168  XFlush(display);
169  XSync(display,False);  // maker sure anything with this image is drawn!
170
171  // Dettach the memory from the server
172  if (!XShmDetach(display, &X_shminfo))
173    i4_error("XShmDetach() failed, go figure");
174
175  XSync(display,False);  // maker sure server detached
176
177  // detach the memory from us, it will be deleted!
178  if (shmdt(X_shminfo.shmaddr)<0)
179    i4_error("shmdt failed, oops");
180
181  im->data=0;  // tell X not to try to free the memory, cause we already did.
182
183  XDestroyImage(im);
184}
185
186#include <stdio.h>
187
188i4_bool x11_shm_image_actual_class::copy_part_to_vram(x11_shm_extension_class *use,
189                                                   i4_coord x, i4_coord y,
190                                                   i4_coord x1, i4_coord y1,
191                                                   i4_coord x2, i4_coord y2)
192{
193  XEvent ev;
194  XSync(display,False);
195
196  if (y1>y2 || x1>x2)
197    return i4_T;
198
199
200  if (use->need_sync_event)
201  {
202    XEvent ev;
203    while (XCheckTypedEvent(display,use->shm_base+ShmCompletion,&ev)==False)
204      XSync(display,False);
205    use->need_sync_event=i4_F;
206  }
207
208  if (XCheckTypedEvent(display, ConfigureNotify,&ev)==False)
209  {
210    XShmPutImage(display,window,gc,im,x1,y1,x,y,x2-x1+1,y2-y1+1,True);
211    XSync(display,False);
212    use->need_sync_event=i4_T;
213    return i4_T;
214  } else     // screen size changed,  better wait till this event is handled cause put might be invalid
215  {
216    XPutBackEvent(display,&ev);
217    return i4_F;
218  }
219   
220}
221
Note: See TracBrowser for help on using the repository browser.