7 /*--------------------------------------------------------------------*/
11 static XVisualInfo
*xvi
;
13 static XSizeHints
*siz
;
14 static GLXContext ctx
;
16 static int center_x
= 0;
17 static int center_y
= 0;
19 static int last_x
= 0;
20 static int last_y
= 0;
21 static int height
= 0;
23 /*--------------------------------------------------------------------*/
25 static int glx_init_dpy(void)
27 if ((dpy
= XOpenDisplay(NULL
)) == NULL
)
30 if (glXQueryExtension(dpy
, NULL
, NULL
) == False
)
36 static int glx_init_xvi(int e
)
46 int *p
= (e
== 2) ? attributes
: attributes
+ 1;
48 if ((xvi
= glXChooseVisual(dpy
, DefaultScreen(dpy
), p
)) == NULL
)
51 if (xvi
->class != TrueColor
)
58 static GLboolean
glx_init_dec(void)
60 unsigned long hint
[5] = { 2, 0, 0, 0, 0 };
63 if (!(prop
= XInternAtom(dpy
, "_MOTIF_WM_HINTS", True
)))
66 XChangeProperty(dpy
, win
, prop
, prop
, 32, PropModeReplace
,
67 (unsigned char *) hint
, 5);
72 static int glx_init_win(int w
, int h
)
74 int W
= w
? w
: DisplayWidth (dpy
, xvi
->screen
);
75 int H
= h
? h
: DisplayHeight(dpy
, xvi
->screen
);
77 Window root
= RootWindow(dpy
, xvi
->screen
);
78 Visual
*vis
= xvi
->visual
;
79 XSetWindowAttributes wa
;
81 unsigned long valuemask
= CWBorderPixel
86 wa
.colormap
= XCreateColormap(dpy
, root
, vis
, AllocNone
);
87 wa
.event_mask
= StructureNotifyMask
95 del
= XInternAtom(dpy
, "WM_DELETE_WINDOW", False
);
96 win
= XCreateWindow(dpy
, root
, 0, 0, W
, H
, 0, xvi
->depth
,
97 InputOutput
, vis
, valuemask
, &wa
);
99 XSetWMProtocols(dpy
, win
, &del
, 1);
101 return (w
|| h
) ? 1 : glx_init_dec();
104 static int glx_init_hnt(const char *s
)
106 int w
= DisplayWidth (dpy
, DefaultScreen(dpy
));
107 int h
= DisplayHeight(dpy
, DefaultScreen(dpy
));
109 siz
= XAllocSizeHints();
113 siz
->min_width
= 160;
114 siz
->min_height
= 120;
118 siz
->flags
= PMinSize
| PMaxSize
;
120 XmbSetWMProperties(dpy
, win
, s
, s
, NULL
, 0, siz
, NULL
, NULL
);
127 static int glx_init_crs(void)
129 char bit
[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
138 pix
= XCreateBitmapFromData(dpy
, win
, bit
, 8, 8);
139 crs
= XCreatePixmapCursor(dpy
, pix
, pix
, &rgb
, &rgb
, 0, 0);
141 XDefineCursor(dpy
, win
, crs
);
142 XFreePixmap(dpy
, pix
);
147 static int glx_init_ctx(void)
149 if ((ctx
= glXCreateContext(dpy
, xvi
, NULL
, True
)) == NULL
)
152 if (glXMakeCurrent(dpy
, win
, ctx
) == True
)
158 /*--------------------------------------------------------------------*/
160 static int glx_client(XClientMessageEvent
*e
)
162 if (e
->data
.l
[0] == del
)
168 static int glx_render(XExposeEvent
*e
)
176 static int glx_resize(XConfigureEvent
*e
)
182 center_x
= e
->width
/ 2;
183 center_y
= e
->height
/ 2;
188 /*--------------------------------------------------------------------*/
190 static int glx_point(XMotionEvent
*e
)
192 last_x
= e
->x
- center_x
;
193 last_y
= e
->y
- center_y
;
195 XWarpPointer(dpy
, None
, win
, 0, 0, 0, 0, center_x
, center_y
);
200 static int glx_btn_d(XButtonEvent
*e
)
207 case 1: return GLW_L_BTN_D
;
208 case 2: return GLW_M_BTN_D
;
209 case 3: return GLW_R_BTN_D
;
210 case 4: return GLW_WHEEL_D
;
211 case 5: return GLW_WHEEL_U
;
216 static int glx_btn_u(XButtonEvent
*e
)
223 case 1: return GLW_L_BTN_U
;
224 case 2: return GLW_M_BTN_U
;
225 case 3: return GLW_R_BTN_U
;
230 /*--------------------------------------------------------------------*/
232 static int glx_key_d(XKeyEvent
*e
)
236 XLookupString(e
, &c
, 1, NULL
, NULL
);
242 static int glx_key_u(XKeyEvent
*e
)
246 XLookupString(e
, &c
, 1, NULL
, NULL
);
252 /*--------------------------------------------------------------------*/
254 int glw_create(const char *s
, int w
, int h
, int e
)
258 if (!glx_init_dpy()) return 0;
259 if (!glx_init_xvi(e
)) return 0;
260 if (!glx_init_win(w
, h
)) return 0;
261 if (!glx_init_hnt(s
)) return 0;
262 if (!glx_init_crs()) return 0;
263 if (!glx_init_ctx()) return 0;
265 XMapWindow(dpy
, win
);
270 void glw_delete(void)
274 glXMakeCurrent(dpy
, None
, NULL
);
275 glXDestroyContext(dpy
, ctx
);
277 XDestroyWindow(dpy
, win
);
284 /*--------------------------------------------------------------------*/
286 int glw_update(int dirty
, int wait
)
290 if (dirty
) glXSwapBuffers(dpy
, win
);
292 if (wait
|| XPending(dpy
) > 0)
298 case ClientMessage
: return glx_client(&e
.xclient
);
299 case Expose
: return glx_render(&e
.xexpose
);
300 case ConfigureNotify
: return glx_resize(&e
.xconfigure
);
302 case MotionNotify
: return glx_point(&e
.xmotion
);
303 case ButtonPress
: return glx_btn_d(&e
.xbutton
);
304 case ButtonRelease
: return glx_btn_u(&e
.xbutton
);
305 case KeyPress
: return glx_key_d(&e
.xkey
);
306 case KeyRelease
: return glx_key_u(&e
.xkey
);