1#define GF_EXPOSE_DRAW_PLATFORM
21#ifdef DO_SWAP_INTERVAL
22#ifndef GLX_MESA_swap_control
23#define GLX_MESA_swap_control 1
24typedef int (*PFNGLXGETSWAPINTERVALMESAPROC)(void);
25typedef void (*PFNGLXSWAPINTERVALMESAPROC)(int);
28#ifndef GLX_EXT_swap_control
29#define GLX_EXT_swap_control 1
30typedef void (*PFNGLXSWAPINTERVALEXTPROC)(Display*, GLXDrawable, int);
33#ifndef GLX_SGI_swap_control
34#define GLX_SGI_swap_control 1
35typedef void (*PFNGLXSWAPINTERVALSGIPROC)(int);
39void gf_draw_platform_begin(
void) {}
40void gf_draw_platform_end(
void) {}
42int gf_draw_platform_has_extension(
gf_draw_t* draw,
const char* query) {
43 const char* ext = NULL;
45 const int len = strlen(query);
49 ext = glXQueryExtensionsString(draw->
platform->display, DefaultScreen(draw->
platform->display));
50 ptr = strstr(ext, query);
51 return ((ptr != NULL) && ((ptr[len] ==
' ') || (ptr[len] ==
'\0')));
60 XSetWindowAttributes attr;
64 memset(platform, 0,
sizeof(*platform));
65 platform->engine = engine;
67 platform->display = XOpenDisplay(NULL);
68 if(platform->display == NULL) {
70 gf_draw_platform_destroy(platform);
73 attribs[i++] = GLX_RGBA;
74 attribs[i++] = GLX_DOUBLEBUFFER;
76 attribs[i++] = GLX_RED_SIZE;
78 attribs[i++] = GLX_GREEN_SIZE;
80 attribs[i++] = GLX_BLUE_SIZE;
82 attribs[i++] = GLX_DEPTH_SIZE;
87 screen = DefaultScreen(platform->display);
88 root = RootWindow(platform->display, screen);
90 visual = glXChooseVisual(platform->display, screen, attribs);
93 gf_draw_platform_destroy(platform);
97 attr.colormap = XCreateColormap(platform->display, root, visual->visual, AllocNone);
98 attr.event_mask = StructureNotifyMask | ExposureMask | PointerMotionMask;
99 platform->window = XCreateWindow(platform->display, root, draw->
width, draw->
height, draw->
width, draw->
height, 0, visual->depth, InputOutput, visual->visual, CWColormap | CWEventMask, &attr);
103 hints.width = draw->
width;
104 hints.height = draw->
height;
105 hints.flags = USSize | USPosition;
106 XSetNormalHints(platform->display, platform->window, &hints);
107 XSetStandardProperties(platform->display, platform->window, draw->
title,
"GoldFish", None, (
char**)NULL, 0, &hints);
109 platform->wm_delete_window = XInternAtom(platform->display,
"WM_DELETE_WINDOW", False);
110 XSetWMProtocols(platform->display, platform->window, &platform->wm_delete_window, 1);
112 platform->context = glXCreateContext(platform->display, visual, NULL, True);
113 if(platform->context == NULL) {
116 gf_draw_platform_destroy(platform);
122 XMapWindow(platform->display, platform->window);
123 glXMakeCurrent(platform->display, platform->window, platform->context);
125#ifdef DO_SWAP_INTERVAL
126 if(gf_draw_platform_has_extension(draw,
"GLX_EXT_swap_control")) {
127 unsigned int tmp = -1;
128 PFNGLXSWAPINTERVALEXTPROC proc = (PFNGLXSWAPINTERVALEXTPROC)glXGetProcAddressARB(
"glXSwapIntervalEXT");
130 proc(platform->display, platform->window, 1);
132 glXQueryDrawable(platform->display, platform->window, GLX_SWAP_INTERVAL_EXT, &tmp);
134 }
else if(gf_draw_platform_has_extension(draw,
"GLX_MESA_swap_control")) {
135 PFNGLXGETSWAPINTERVALMESAPROC proc = (PFNGLXGETSWAPINTERVALMESAPROC)glXGetProcAddressARB(
"glXGetSwapIntervalMESA");
136 PFNGLXSWAPINTERVALMESAPROC proc2 = (PFNGLXSWAPINTERVALMESAPROC)glXGetProcAddressARB(
"glXSwapIntervalMESA");
141 }
else if(gf_draw_platform_has_extension(draw,
"GLX_SGI_swap_control")) {
142 PFNGLXSWAPINTERVALSGIPROC proc = (PFNGLXSWAPINTERVALSGIPROC)glXGetProcAddressARB(
"glXSwapIntervalSGI");
153int gf_draw_platform_step(
gf_draw_t* draw) {
156 while(XPending(draw->
platform->display) > 0) {
158 XNextEvent(draw->
platform->display, &event);
159 if(event.type == Expose) {
161 }
else if(event.type == ConfigureNotify) {
162 draw->
x =
event.xconfigure.x;
163 draw->
y =
event.xconfigure.y;
164 draw->
width =
event.xconfigure.width;
165 draw->
height =
event.xconfigure.height;
167 gf_draw_reshape(draw);
168 }
else if(event.type == ClientMessage) {
169 if(event.xclient.data.l[0] == draw->
platform->wm_delete_window) {
176 gf_draw_driver_before(draw);
178 gf_draw_driver_after(draw);
186 if(platform->context != NULL) {
187 glXMakeCurrent(platform->display, None, NULL);
188 glXDestroyContext(platform->display, platform->context);
190 if(platform->display != NULL) {
191 XDestroyWindow(platform->display, platform->window);
192 XCloseDisplay(platform->display);
194 gf_log_function(platform->engine,
"Destroyed platform-dependent part of drawing driver",
"");
#define gf_log_function(engine, fmt,...)
Output log with line number and function name.
Required headers before anything.
char title[128]
Window title.
int close
1 if it was requested to be closed, otherwise 0
gf_draw_platform_t * platform
Platform-dependent part of drawing driver.
int width
Width of window.
int height
Height of window.