#include #include #include #include #include #include struct data { Display *dpy; Window w; GLXContext ctx; GLXWindow glxw; }; static Bool send_make_current_request(Display *dpy, GLXContextID gc_id, GLXDrawable glxwin) { xGLXMakeCurrentReply reply; xGLXMakeCurrentReq *req; Bool ret; XExtCodes *codes; codes = XInitExtension(dpy, GLX_EXTENSION_NAME); LockDisplay(dpy); GetReq(GLXMakeCurrent, req); req->reqType = codes->major_opcode; req->glxCode = X_GLXMakeCurrent; req->drawable = glxwin; req->context = gc_id; req->oldContextTag = 0; ret = _XReply(dpy, (xReply *) & reply, 0, False); UnlockDisplay(dpy); SyncHandle(); return ret; } static GLXFBConfig choose_fb_config(struct data *data) { GLXFBConfig *configs; GLXFBConfig ret; int n_configs; static const int attrib_list[] = { GLX_DOUBLEBUFFER, True, GLX_RED_SIZE, 8, GLX_GREEN_SIZE, 8, GLX_BLUE_SIZE, 8, 0 }; configs = glXChooseFBConfig(data->dpy, DefaultScreen(data->dpy), attrib_list, &n_configs); if (configs == NULL) return NULL; if (n_configs < 1) ret = NULL; else ret = configs[0]; XFree(configs); return ret; } /* Hack so we can extract the xid from a GLXContext */ struct dummy_context { void *four_pointers[4]; int an_int; void *a_pointer; XID xid; }; static Window make_window(struct data *data, unsigned int width, unsigned int height) { int scrnum = 0; XSetWindowAttributes attr; unsigned long mask; Window root; Window win; GLXFBConfig fb_config; XVisualInfo *visinfo, visual_template; GLXContextID context_id; int visid, n_items; root = RootWindow(data->dpy, scrnum); fb_config = choose_fb_config(data); if (fb_config == NULL) { printf ("Error: couldn't get an RGB, " "double-buffered FB config\n"); return None; } glXGetFBConfigAttrib(data->dpy, fb_config, GLX_VISUAL_ID, &visid); visual_template.visualid = visid; visinfo = XGetVisualInfo(data->dpy, VisualIDMask, &visual_template, &n_items); if (visinfo == NULL || n_items < 1) { printf("Couldn't get visual for FB config\n"); exit(1); } data->ctx = glXCreateContext(data->dpy, visinfo, NULL, True); if (data->ctx == NULL) { printf("Error: glXCreateContext failed\n"); exit(1); } /* window attributes */ attr.background_pixel = 0; attr.border_pixel = 0; attr.colormap = XCreateColormap(data->dpy, root, visinfo->visual, AllocNone); attr.event_mask = StructureNotifyMask | ExposureMask | PointerMotionMask | KeyPressMask; mask = CWBorderPixel | CWColormap | CWEventMask; win = XCreateWindow(data->dpy, root, 0, 0, width, height, 0, visinfo->depth, InputOutput, visinfo->visual, mask, &attr); data->glxw = glXCreateWindow(data->dpy, fb_config, win, NULL); /* Hack to get the GC id out of Mesa's GLXContext pointer */ context_id = ((struct dummy_context *) data->ctx)->xid; send_make_current_request(data->dpy, context_id, data->glxw); return win; } int main(int argc, char *argv[]) { struct data data; data.dpy = XOpenDisplay(NULL); if (!data.dpy) { printf("Error: XOpenDisplay failed\n"); return 1; } data.w = make_window(&data, 640, 480); if (data.w == None) return 1; return 0; }