static Window createWindow(Display *dpy, int width, int height) { GLXFBConfig *fbc; XVisualInfo *vi; Colormap cmap; XSetWindowAttributes swa; GLXContext cx; XEvent event; int nElements; int attr[] = { GLX_DOUBLEBUFFER, True, None }; fbc = glXChooseFBConfig(dpy, DefaultScreen(dpy), attr, &nElements); vi = glXGetVisualFromFBConfig(dpy, fbc[0]); cx = glXCreateNewContext(dpy, fbc[0], GLX_RGBA_TYPE, 0, GL_FALSE); cmap = XCreateColormap(dpy, RootWindow(dpy, vi->screen), vi->visual, AllocNone); swa.colormap = cmap; swa.border_pixel = 0; swa.event_mask = 0; Window win = XCreateWindow(dpy, RootWindow(dpy, vi->screen), 0, 0, width, height, 0, vi->depth, InputOutput, vi->visual, CWBorderPixel | CWColormap | CWEventMask, &swa); XSelectInput(dpy, win, StructureNotifyMask | KeyPressMask | KeyReleaseMask); XMapWindow(dpy, win); XIfEvent(dpy, &event, waitMapNotify, (char *)win); XMoveWindow(dpy, win, 100, 100); XIfEvent(dpy, &event, waitConfigureNotify, (char *)win); glXMakeCurrent(dpy, win, cx); return win; }
void XWindow::openWindow(const Pnt2f& ScreenPosition, const Vec2f& Size, const std::string& WindowName) { int argc(1); char **argv = new char*[1]; (*argv)= "Bla"; XSetStandardProperties(this->getDisplay(), this->getWindow(), WindowName.c_str(), WindowName.c_str(), None, argv, argc, NULL); attachWindow(); this->init(); XMapWindow(this->getDisplay(), this->getWindow()); XEvent event; XIfEvent(this->getDisplay(), &event, wait_for_map_notify, (char *)(this->getWindow())); produceWindowOpened(); this->activate(); setPosition(ScreenPosition); setSize(Vec2us(Size[0], Size[1])); //Set things up to capture the delete window event Atom wm_delete_window=XInternAtom(this->getDisplay(), "WM_DELETE_WINDOW", False); XSetWMProtocols(this->getDisplay(), this->getWindow(), &wm_delete_window, 1); Atom wm_protocols=XInternAtom(this->getDisplay(), "WM_PROTOCOLS", False); }
void PrintableWindow::xmove(int left1, int top) { const Display& d = *display(); XEvent event; int x = 0, y = 0; static int xoff = 0, yoff = 0; WindowRep& w = *((Window*)this)->rep(); get_position(d.rep()->display_, w.xwindow_, &x, &y); for (int i= 0; (left1 != x || top != y) && i < 10; i++) { XMoveWindow(d.rep()->display_, w.xwindow_, left1+xoff, top+yoff); XPeekIfEvent(d.rep()->display_, &event, WaitForEvent, (char *)ConfigureNotify); get_position(d.rep()->display_, w.xwindow_, &x, &y); if (left1 != x || top != y) { XIfEvent(d.rep()->display_, &event, WaitForEvent, (char *)ConfigureNotify); xoff = left1 - x; yoff = top - y; } printf("x=%d y=%d, left1=%d top=%d xoff = %d yoff = %d\n", x, y, left1, top, xoff, yoff); } }
void wsMainLoop( void ) { int delay=20; mp_msg( MSGT_GPLAYER,MSGL_V,"[ws] init threads: %d\n",XInitThreads() ); XSynchronize( wsDisplay,False ); XLockDisplay( wsDisplay ); // XIfEvent( wsDisplay,&wsEvent,wsEvents,NULL ); #if 1 while(wsTrue){ // handle pending events while ( XPending(wsDisplay) ){ XNextEvent( wsDisplay,&wsEvent ); wsEvents( wsDisplay,&wsEvent,NULL ); delay=0; } usleep(delay*1000); // FIXME! if(delay<10*20) delay+=20; // pump up delay up to 0.2 sec (low activity) } #else while( wsTrue ) { XIfEvent( wsDisplay,&wsEvent,wsDummyEvents,NULL ); wsEvents( wsDisplay,&wsEvent,NULL ); } #endif XUnlockDisplay( wsDisplay ); }
void X11WindowImpl::show() { XMapWindow(factory->xdisplay, xwindow); XEvent ev; XIfEvent(factory->xdisplay, &ev, IsMapNotify, (XPointer) xwindow ); factory->processEvents(); update(); }
static void openWindow(Display *&display, Window &window, unsigned int windowX, unsigned int windowY, char *title) // ////////////////////////////////////////////////////////////// { XVisualInfo *vi; Colormap cmap; XSetWindowAttributes swa; GLXContext cx; XEvent event; static int attributeList[] = { GLX_RGBA, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1, GLX_DEPTH_SIZE, 1, None, // May be replaced w/GLX_DOUBLEBUFFER None, }; display = XOpenDisplay(0); vi = glXChooseVisual(display, DefaultScreen(display), attributeList); cx = glXCreateContext(display, vi, 0, GL_TRUE); cmap = XCreateColormap(display, RootWindow(display, vi->screen), vi->visual, AllocNone); swa.colormap = cmap; swa.border_pixel = 0; swa.event_mask = StructureNotifyMask; window = XCreateWindow(display, RootWindow(display, vi->screen), 10, 10, windowX, windowY, 0, vi->depth, InputOutput, vi->visual, (CWBorderPixel | CWColormap | CWEventMask), &swa); // Make the window appear in the lower left corner XSizeHints *xsh = XAllocSizeHints(); xsh->flags = USPosition; XSetWMNormalHints(display, window, xsh); XSetStandardProperties(display, window, title, title, None, 0, 0, 0); XFree(xsh); XMapWindow(display, window); XIfEvent(display, &event, waitForNotify, (char *) window); glXMakeCurrent(display, window, cx); glEnable(GL_DEPTH_TEST); glClearColor(0.5, 0.5, 0.5, 1); // clear the graphics window and depth planes glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); }
static void get_server_info (Window *server_window, Display **display, string identity) { int scr; /* Open our own connection to the X server, since sending messages through the server's connection hangs. */ *display = XOpenDisplay (NULL); if (*display == NULL) FATAL1 ("limn: Could not open display `%s'", getenv ("DISPLAY")); /* Get the identity atom. Create it if it doesn't exist. */ foserver_identity_atom = XInternAtom (*display, FOSERVER_IDENTITY_ATOM, False); /* Ask to be told about most window events. */ XSelectInput (*display, DefaultRootWindow (*display), SubstructureNotifyMask); /* Remove potential race condition below -- if our server has already had its window realized, we wouldn't find it otherwise. Search all windows first. We might just as well search all screens too. */ *server_window = None; for (scr = ScreenCount (*display); scr > 0 && *server_window == None; scr--) { Window root = RootWindow (*display, scr - 1); *server_window = search_children (*display, root, identity); } while (*server_window == None) { XEvent event; Window w; /* Wait for an event that might mean our server is ready. */ XIfEvent (*display, &event, window_change_p, NULL); /* We look for some property on the window, and rely on our server setting that property. */ switch (event.type) { case MapNotify: w = event.xmap.window; *server_window = search_children (*display, w, identity); break; default: FATAL1 ("limn: Unexpected event (type %d)", event.type); } } /* We don't want to see any events any more. */ XSelectInput (*display, DefaultRootWindow (*display), NoEventMask); }
XEvent Clipboard::checkEvent() { XEvent e; XIfEvent(resourceManager->dpy, &e, &clipboardPredicate, reinterpret_cast<XPointer>(window.get())); DEBUG_CLIP("A selection notify has arrived!"); DEBUG_CLIP("Requester = 0x" << hex << e.xselectionrequest.requestor << dec); DEBUG_CLIP("Target atom = " << getAtomName(resourceManager->dpy, e.xselection.target)); DEBUG_CLIP("Property atom = " << getAtomName(resourceManager->dpy, e.xselection.property)); DEBUG_CLIP("Selection atom = " << getAtomName(resourceManager->dpy, e.xselection.selection)); return e; }
Time get_server_time(Display* dpy, Window win) { unsigned char c = 'a'; TimeStampInfo info; XEvent xev; info.timestamp_prop_atom = XInternAtom(dpy, "_TIMESTAMP_PROP", False); info.window = win; XChangeProperty(dpy, win, info.timestamp_prop_atom, info.timestamp_prop_atom, 8, PropModeReplace, &c, 1); XIfEvent(dpy, &xev, timestamp_predicate, (XPointer)&info); return xev.xproperty.time; }
void Close_OGLwin(void) { // // wait for the window to be unmapped // XEvent e; XUnmapWindow(Dsp, XWindow); XIfEvent(Dsp, &e, WaitForUnmapNotify, (char *) XWindow); glXDestroyContext(Dsp, Cxt); XDestroyWindow(Dsp, XWindow); }
void xtime_kludge(void) { Window *w; WinAttr wa; XEvent e; long l; w = createwindow(&scr.root, Rect(0, 0, 1, 1), 0, InputOnly, &wa, 0); XSelectInput(display, w->xid, PropertyChangeMask); changeprop_long(w, "ATOM", "ATOM", &l, 0); XIfEvent(display, &e, findtime, (void*)w); destroywindow(w); }
static char * ECommsWaitForMessage(void) { XEvent ev; char *msg = NULL; while ((!msg) && (comms_win)) { XIfEvent(dd, &ev, ev_check, NULL); if (ev.type == DestroyNotify) comms_win = 0; else msg = ECommsGet(&ev); } return msg; }
Time xfce_xsettings_get_server_time (Display *xdisplay, Window window) { Atom timestamp_atom; guchar c = 'a'; XEvent xevent; /* get the current xserver timestamp */ timestamp_atom = XInternAtom (xdisplay, "_TIMESTAMP_PROP", False); XChangeProperty (xdisplay, window, timestamp_atom, timestamp_atom, 8, PropModeReplace, &c, 1); XIfEvent (xdisplay, &xevent, xfce_xsettings_helper_timestamp_predicate, GUINT_TO_POINTER (window)); return xevent.xproperty.time; }
bool Window::configInitGLXWindow( GLXFBConfig* fbConfig ) { if( !_impl->xDisplay ) { sendError( ERROR_GLXWINDOW_NO_DISPLAY ); return false; } PixelViewport pvp = getPixelViewport(); if( getIAttribute( IATTR_HINT_FULLSCREEN ) == ON ) { const int screen = DefaultScreen( _impl->xDisplay ); pvp.h = DisplayHeight( _impl->xDisplay, screen ); pvp.w = DisplayWidth( _impl->xDisplay, screen ); pvp.x = 0; pvp.y = 0; setPixelViewport( pvp ); } XID drawable = _createGLXWindow( fbConfig, pvp ); if( !drawable ) return false; // map and wait for MapNotify event XMapWindow( _impl->xDisplay, drawable ); XEvent event; XIfEvent( _impl->xDisplay, &event, WaitForNotify, (XPointer)(drawable) ); XMoveResizeWindow( _impl->xDisplay, drawable, pvp.x, pvp.y, pvp.w, pvp.h ); XFlush( _impl->xDisplay ); // Grab keyboard focus in fullscreen mode if( getIAttribute( IATTR_HINT_FULLSCREEN ) == ON || getIAttribute( IATTR_HINT_DECORATION ) == OFF ) { XGrabKeyboard( _impl->xDisplay, drawable, True, GrabModeAsync, GrabModeAsync, CurrentTime ); } setXDrawable( drawable ); LBVERB << "Created X11 drawable " << drawable << std::endl; return true; }
slop::GLSelectRectangle::~GLSelectRectangle() { if ( m_window == None ) { return; } xengine->freeCRTCS( m_monitors ); delete m_framebuffer; // Try to erase the window before destroying it. glClearColor( 0, 0, 0, 0 ); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); glXSwapBuffers( xengine->m_display, m_glxWindow ); // Sleep for 0.1 seconds in hope that the rectangle was erased. usleep( 10000 ); XDestroyWindow( xengine->m_display, m_window ); XEvent event; // Block until the window is actually completely removed. XIfEvent( xengine->m_display, &event, &isDestroyNotify, (XPointer)&m_window ); // Sleep for 0.1 seconds in hope that the screen actually cleared the window. usleep( 10000 ); }
void X11Window::setVisible(bool isVisible) { if (isVisible) { XMapWindow(mDisplay, mWindow); // Wait until we get an event saying this window is mapped so that the // code calling setVisible can assume the window is visible. // This is important when creating a framebuffer as the framebuffer content // is undefined when the window is not visible. XEvent dummyEvent; XIfEvent(mDisplay, &dummyEvent, WaitForMapNotify, reinterpret_cast<XPointer>(mWindow)); } else { XUnmapWindow(mDisplay, mWindow); XFlush(mDisplay); } }
EGLNativeWindowType createSubWindow(FBNativeWindowType p_window, EGLNativeDisplayType display, int x, int y,int width, int height) { /* krnlyng */ printf("creating sub window\n"); #ifndef X11 if(get_server_references(display) < 0) return NULL; surface = wl_compositor_create_surface(compositor); if(surface == NULL) { fprintf(stderr, "Cannot create wl surface\n"); return NULL; } shell_surface = wl_shell_get_shell_surface(shell, surface); wl_shell_surface_set_toplevel(shell_surface); create_opaque_region(width, height); EGLNativeWindowType win = wl_egl_window_create(surface, width, height); if(win == EGL_NO_SURFACE || win == NULL) { fprintf(stderr, "wl_egl_window_create failed\n"); } printf("created sub window\n"); return win; #else XSetWindowAttributes wa; wa.event_mask = StructureNotifyMask; Window win = XCreateWindow(display,p_window,x,y, width,height,0,CopyFromParent,CopyFromParent,CopyFromParent,CWEventMask,&wa); XMapWindow(display,win); XEvent e; XIfEvent(display, &e, WaitForMapNotify, (char *)win); return win; #endif }
static void meta_sync_free (MetaSync *self) { /* When our assumptions don't hold, something has gone wrong but we * don't know what, so we reboot the ring. While doing that, we * trigger fences before deleting them to try to get ourselves out * of a potentially stuck GPU state. */ switch (self->state) { case META_SYNC_STATE_WAITING: meta_gl_delete_sync (self->gpu_fence); break; case META_SYNC_STATE_DONE: /* nothing to do */ break; case META_SYNC_STATE_RESET_PENDING: { XEvent event; XIfEvent (self->xdisplay, &event, alarm_event_predicate, (XPointer) self); meta_sync_handle_event (self, (XSyncAlarmNotifyEvent *) &event); } /* fall through */ case META_SYNC_STATE_READY: XSyncTriggerFence (self->xdisplay, self->xfence); XFlush (self->xdisplay); break; default: break; } meta_gl_delete_sync (self->gl_x11_sync); XSyncDestroyFence (self->xdisplay, self->xfence); XSyncDestroyCounter (self->xdisplay, self->xcounter); XSyncDestroyAlarm (self->xdisplay, self->xalarm); g_free (self); }
void init(int w, int h) { display = XOpenDisplay( NULL ); if ( display == NULL ) { fprintf( stderr, "Bad DISPLAY (%s).\n", getenv( "DISPLAY" ) ); exit( 1 ); } int pbuffer_attributes[] = { GLX_RED_SIZE, 8, GLX_GREEN_SIZE, 8, GLX_BLUE_SIZE, 8, GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT, 0 }; int attributes[] = { GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT, GLX_RENDER_TYPE, GLX_RGBA_BIT, GLX_RED_SIZE, 8, /* Request a single buffered color buffer */ GLX_GREEN_SIZE, 8, /* with the maximum number of color bits */ GLX_BLUE_SIZE, 8, /* for each component */ None }; int pb_nconfigs = 0; GLXFBConfig *pb_configs = glXChooseFBConfig( display, DefaultScreen( display ), pbuffer_attributes, &pb_nconfigs ); int nconfigs = 0; GLXFBConfig *configs = glXChooseFBConfig( display, DefaultScreen( display ), attributes, &nconfigs ); if ( !configs || !pb_configs) { fprintf( stderr, "Num configs: %d.\n", nconfigs ); fprintf( stderr, "Num pbconfigs: %d.\n", pb_nconfigs ); exit( 1 ); } Window root = DefaultRootWindow(display); XVisualInfo* vi = glXGetVisualFromFBConfig(display, configs[0] ); XSetWindowAttributes swa; swa.border_pixel = 0; swa.event_mask = StructureNotifyMask; swa.colormap = XCreateColormap( display, root, vi->visual, AllocNone ); win = XCreateWindow(display, root, 0, 0, w, h, 0, vi->depth, InputOutput, vi->visual, CWEventMask | CWColormap, &swa); int pbuffer_create_attributes[] = { GLX_PBUFFER_WIDTH, w, GLX_PBUFFER_HEIGHT, h, 0 }; XMapWindow(display, win); XStoreName(display, win, "Trajectory Visualizer"); XEvent event; XIfEvent( display, &event, WaitForNotify, (XPointer) win); GLXPbuffer pbuffer = glXCreatePbuffer( display, configs[ 0 ], pbuffer_create_attributes ); if ( !pbuffer ) { perror( "glXCreatePbuffer" ); exit( 1 ); } GLXWindow glxwin = glXCreateWindow( display, configs[0], win, NULL ); GLXContext context = glXCreateNewContext( display, configs[ 0 ], GLX_RGBA_TYPE, 0, GL_TRUE ); GLXContext pbuffercontext = glXCreateNewContext( display, pb_configs[ 0 ], GLX_RGBA_TYPE, 0, GL_TRUE ); if ( glXMakeCurrent( display, pbuffer, context ) == 0 ) { perror( "glXMakeCurrent" ); exit( 1 ); } if (glXMakeContextCurrent( display, glxwin, glxwin, context ) == 0) { perror( "glXMakeContextCurrent" ); exit( 1 ); } glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); }
int ui_loop(int argc, char **argv, const char *name) { XVisualInfo *vi; Colormap cmap; XSetWindowAttributes swa; XSizeHints hint; GLXContext cx; XEvent event; int k, width, height; char buf[80]; XEvent xev; KeySym keysym; XComposeStatus status; /* get a connection */ dpy = XOpenDisplay(NULL); if (dpy == NULL) { fprintf(stderr, "Could not open X display\n"); exit(1); } /* get an appropriate visual */ vi = glXChooseVisual(dpy, DefaultScreen(dpy), attributeList); if (vi == NULL) { fprintf(stderr, "No suitable visual for glx\n"); exit(1); } /* create a GLX context */ cx = glXCreateContext(dpy, vi, 0, GL_TRUE); /* create a color map */ cmap = XCreateColormap(dpy, RootWindow(dpy, vi->screen), vi->visual, AllocNone); /* create a window */ width = 400; height = 300; hint.x = 0; hint.y = 0; hint.width = width; hint.height = height; hint.flags = PPosition | PSize; swa.colormap = cmap; swa.border_pixel = 0; swa.event_mask = StructureNotifyMask; win = XCreateWindow(dpy, RootWindow(dpy, vi->screen), 0, 0, width, height, 0, vi->depth, InputOutput, vi->visual, CWBorderPixel | CWColormap | CWEventMask, &swa); XSetStandardProperties(dpy, win, name, name, None, NULL, 0, &hint); XMapWindow(dpy, win); XIfEvent(dpy, &event, WaitForNotify, (char *)win); XSelectInput(dpy, win, KeyPressMask | StructureNotifyMask | ExposureMask); /* connect the context to the window */ glXMakeCurrent(dpy, win, cx); init(); reshape(width, height); while (1) { if (XPending(dpy) > 0) { XNextEvent(dpy, &xev); switch (xev.type) { case KeyPress: XLookupString((XKeyEvent *)&xev, buf, 80, &keysym, &status); switch (keysym) { case XK_Up: k = KEY_UP; break; case XK_Down: k = KEY_DOWN; break; case XK_Left: k = KEY_LEFT; break; case XK_Right: k = KEY_RIGHT; break; case XK_Escape: k = KEY_ESCAPE; break; default: k = keysym; } key(k, 0); break; case ConfigureNotify: { int width, height; width = xev.xconfigure.width; height = xev.xconfigure.height; glXWaitX(); reshape(width, height); } break; } } else { idle(); } } return 0; }
static bool gfx_ctx_glx_set_video_mode(void *data, unsigned width, unsigned height, bool fullscreen) { XEvent event; bool true_full = false, windowed_full; int val, x_off = 0, y_off = 0; XVisualInfo *vi = NULL; XSetWindowAttributes swa = {0}; int (*old_handler)(Display*, XErrorEvent*) = NULL; driver_t *driver = driver_get_ptr(); gfx_ctx_glx_data_t *glx = (gfx_ctx_glx_data_t*)driver->video_context_data; struct sigaction sa = {{0}}; settings_t *settings = config_get_ptr(); sa.sa_handler = glx_sighandler; sa.sa_flags = SA_RESTART; sigemptyset(&sa.sa_mask); sigaction(SIGINT, &sa, NULL); sigaction(SIGTERM, &sa, NULL); if (!glx) return false; windowed_full = settings->video.windowed_fullscreen; true_full = false; vi = glXGetVisualFromFBConfig(glx->g_dpy, glx->g_fbc); if (!vi) goto error; swa.colormap = glx->g_cmap = XCreateColormap(glx->g_dpy, RootWindow(glx->g_dpy, vi->screen), vi->visual, AllocNone); swa.event_mask = StructureNotifyMask | KeyPressMask | KeyReleaseMask | ButtonReleaseMask | ButtonPressMask; swa.override_redirect = fullscreen ? True : False; if (fullscreen && !windowed_full) { if (x11_enter_fullscreen(glx->g_dpy, width, height, &glx->g_desktop_mode)) { glx->g_should_reset_mode = true; true_full = true; } else RARCH_ERR("[GLX]: Entering true fullscreen failed. Will attempt windowed mode.\n"); } if (settings->video.monitor_index) glx->g_screen = settings->video.monitor_index - 1; #ifdef HAVE_XINERAMA if (fullscreen || glx->g_screen != 0) { unsigned new_width = width; unsigned new_height = height; if (x11_get_xinerama_coord(glx->g_dpy, glx->g_screen, &x_off, &y_off, &new_width, &new_height)) RARCH_LOG("[GLX]: Using Xinerama on screen #%u.\n", glx->g_screen); else RARCH_LOG("[GLX]: Xinerama is not active on screen.\n"); if (fullscreen) { width = new_width; height = new_height; } } #endif RARCH_LOG("[GLX]: X = %d, Y = %d, W = %u, H = %u.\n", x_off, y_off, width, height); glx->g_win = XCreateWindow(glx->g_dpy, RootWindow(glx->g_dpy, vi->screen), x_off, y_off, width, height, 0, vi->depth, InputOutput, vi->visual, CWBorderPixel | CWColormap | CWEventMask | (true_full ? CWOverrideRedirect : 0), &swa); XSetWindowBackground(glx->g_dpy, glx->g_win, 0); glx->g_glx_win = glXCreateWindow(glx->g_dpy, glx->g_fbc, glx->g_win, 0); x11_set_window_attr(glx->g_dpy, glx->g_win); if (fullscreen) x11_show_mouse(glx->g_dpy, glx->g_win, false); if (true_full) { RARCH_LOG("[GLX]: Using true fullscreen.\n"); XMapRaised(glx->g_dpy, glx->g_win); } else if (fullscreen) /* We attempted true fullscreen, but failed. Attempt using windowed fullscreen. */ { XMapRaised(glx->g_dpy, glx->g_win); RARCH_LOG("[GLX]: Using windowed fullscreen.\n"); /* We have to move the window to the screen we want to go fullscreen on first. * x_off and y_off usually get ignored in XCreateWindow(). */ x11_move_window(glx->g_dpy, glx->g_win, x_off, y_off, width, height); x11_windowed_fullscreen(glx->g_dpy, glx->g_win); } else { XMapWindow(glx->g_dpy, glx->g_win); // If we want to map the window on a different screen, we'll have to do it by force. // Otherwise, we should try to let the window manager sort it out. // x_off and y_off usually get ignored in XCreateWindow(). if (glx->g_screen) x11_move_window(glx->g_dpy, glx->g_win, x_off, y_off, width, height); } XIfEvent(glx->g_dpy, &event, glx_wait_notify, NULL); if (!glx->g_ctx) { if (glx->g_core_es || glx->g_debug) { int attribs[16]; int *aptr = attribs; if (glx->g_core_es) { *aptr++ = GLX_CONTEXT_MAJOR_VERSION_ARB; *aptr++ = g_major; *aptr++ = GLX_CONTEXT_MINOR_VERSION_ARB; *aptr++ = g_minor; if (glx->g_core_es_core) { /* Technically, we don't have core/compat until 3.2. * Version 3.1 is either compat or not depending on GL_ARB_compatibility. */ *aptr++ = GLX_CONTEXT_PROFILE_MASK_ARB; #ifdef HAVE_OPENGLES2 *aptr++ = GLX_CONTEXT_ES_PROFILE_BIT_EXT; #else *aptr++ = GLX_CONTEXT_CORE_PROFILE_BIT_ARB; #endif } } if (glx->g_debug) { *aptr++ = GLX_CONTEXT_FLAGS_ARB; *aptr++ = GLX_CONTEXT_DEBUG_BIT_ARB; } *aptr = None; glx->g_ctx = glx_create_context_attribs(glx->g_dpy, glx->g_fbc, NULL, True, attribs); if (glx->g_use_hw_ctx) { RARCH_LOG("[GLX]: Creating shared HW context.\n"); glx->g_hw_ctx = glx_create_context_attribs(glx->g_dpy, glx->g_fbc, glx->g_ctx, True, attribs); if (!glx->g_hw_ctx) RARCH_ERR("[GLX]: Failed to create new shared context.\n"); } } else { glx->g_ctx = glXCreateNewContext(glx->g_dpy, glx->g_fbc, GLX_RGBA_TYPE, 0, True); if (glx->g_use_hw_ctx) { glx->g_hw_ctx = glXCreateNewContext(glx->g_dpy, glx->g_fbc, GLX_RGBA_TYPE, glx->g_ctx, True); if (!glx->g_hw_ctx) RARCH_ERR("[GLX]: Failed to create new shared context.\n"); } } if (!glx->g_ctx) { RARCH_ERR("[GLX]: Failed to create new context.\n"); goto error; } } else { driver->video_cache_context_ack = true; RARCH_LOG("[GLX]: Using cached GL context.\n"); } glXMakeContextCurrent(glx->g_dpy, glx->g_glx_win, glx->g_glx_win, glx->g_ctx); XSync(glx->g_dpy, False); g_quit_atom = XInternAtom(glx->g_dpy, "WM_DELETE_WINDOW", False); if (g_quit_atom) XSetWMProtocols(glx->g_dpy, glx->g_win, &g_quit_atom, 1); glXGetConfig(glx->g_dpy, vi, GLX_DOUBLEBUFFER, &val); glx->g_is_double = val; if (glx->g_is_double) { const char *swap_func = NULL; g_pglSwapIntervalEXT = (void (*)(Display*, GLXDrawable, int))glXGetProcAddress((const GLubyte*)"glXSwapIntervalEXT"); g_pglSwapIntervalSGI = (int (*)(int))glXGetProcAddress((const GLubyte*)"glXSwapIntervalSGI"); g_pglSwapInterval = (int (*)(int))glXGetProcAddress((const GLubyte*)"glXSwapIntervalMESA"); if (g_pglSwapIntervalEXT) swap_func = "glXSwapIntervalEXT"; else if (g_pglSwapInterval) swap_func = "glXSwapIntervalMESA"; else if (g_pglSwapIntervalSGI) swap_func = "glXSwapIntervalSGI"; if (!g_pglSwapInterval && !g_pglSwapIntervalEXT && !g_pglSwapIntervalSGI) RARCH_WARN("[GLX]: Cannot find swap interval call.\n"); else RARCH_LOG("[GLX]: Found swap function: %s.\n", swap_func); } else RARCH_WARN("[GLX]: Context is not double buffered!.\n"); gfx_ctx_glx_swap_interval(data, glx->g_interval); /* This can blow up on some drivers. It's not fatal, so override errors for this call. */ old_handler = XSetErrorHandler(glx_nul_handler); XSetInputFocus(glx->g_dpy, glx->g_win, RevertToNone, CurrentTime); XSync(glx->g_dpy, False); XSetErrorHandler(old_handler); XFree(vi); glx->g_has_focus = true; if (!x11_create_input_context(glx->g_dpy, glx->g_win, &glx->g_xim, &glx->g_xic)) goto error; driver->display_type = RARCH_DISPLAY_X11; driver->video_display = (uintptr_t)glx->g_dpy; driver->video_window = (uintptr_t)glx->g_win; glx->g_true_full = true_full; return true; error: if (vi) XFree(vi); ctx_glx_destroy_resources(glx); if (glx) free(glx); return false; }
// Initialize GLUT & OpenSG and start the cluster server int main(int argc,char **argv) { const char *name = "ClusterServer"; const char *connectionType = "StreamSock"; bool fullscreen = true; std::string address = ""; bool doStereo = false; std::string serviceGroup = "224.245.211.234"; // evaluate params for(int a=1 ; a<argc ; ++a) { if(argv[a][0] == '-') { switch(argv[a][1]) { case 'm': connectionType="Multicast"; break; case 's': doStereo=true; break; case 'w': fullscreen=false; break; case 'e': exitOnError=true; break; case 'a': address = argv[a][2] ? argv[a]+2 : argv[++a]; if(address == argv[argc]) { SLOG << "address missing" << OSG::endLog; return 0; } std::cout << address << OSG::endLog; break; case 'j': if(argv[a][2] != '\0') serviceGroup=argv[a]+2; else serviceGroup=argv[++a]; break; case 'h': default: std::cout << argv[0] << "-m " << "-s " << "-w " << "-e " << "-a Address " << "-j group " << std::endl; std::cout << "-m use multicast" << std::endl; std::cout << "-s enable stereo" << std::endl; std::cout << "-w no fullscreen" << std::endl; std::cout << "-e exit after closed connection" << std::endl; std::cout << "-a Address Server network address" << std::endl; std::cout << "-m Address wait for requests on " << "multicast group" << std::endl; std::cout << "-p port wait for requests on port" << std::endl; return 0; } } else { name=argv[a]; } } try { // init OpenSG OSG::osgInit(argc, argv); int snglBuf[] = {GLX_RGBA, GLX_DEPTH_SIZE, 16, None}; int dblBuf[16]; dblBuf[0] = GLX_RGBA; dblBuf[1] = GLX_DEPTH_SIZE; dblBuf[2] = 16; dblBuf[3] = GLX_DOUBLEBUFFER; dblBuf[4] = (doStereo == true) ? GLX_STEREO : None; dblBuf[5] = None; // X init OSG::DisplayP dpy = XOpenDisplay(NULL); if(dpy == NULL) { std::cerr << "Error: Could not open display!" << std::endl; } int dummy; if(!glXQueryExtension( dpy, &dummy, &dummy)) { std::cerr << "Error: X server has no OpenGL GLX extension" << std::endl; } XVisualInfo *vi = glXChooseVisual(dpy, DefaultScreen(dpy), dblBuf); if(vi == NULL) { vi = glXChooseVisual(dpy, DefaultScreen(dpy), snglBuf); if(vi == NULL) { std::cerr << "no RGB visual with depth buffer" << std::endl; } } if(vi->c_class != TrueColor) { std::cerr << "TrueColor visual required for this program" << std::endl; } Colormap cmap = XCreateColormap(dpy, RootWindow(dpy, vi->screen), vi->visual, AllocNone); XSetWindowAttributes swa; swa.colormap = cmap; swa.border_pixel = 0; swa.event_mask = ExposureMask | ButtonPressMask | ButtonReleaseMask | KeyPressMask | Button1MotionMask | Button2MotionMask | Button3MotionMask | StructureNotifyMask; // Create Window // Create a Window and connect it to the main display dpy OSG::X11Window hwin = XCreateWindow(dpy, RootWindow(dpy, vi->screen), 0, 0, 300, 300, 0, vi->depth, InputOutput, vi->visual, CWBorderPixel | CWColormap | CWEventMask, &swa ); XSetStandardProperties(dpy, hwin, "testWindowX", "testWindowX", None, argv, argc, NULL); if(fullscreen == true) { Atom noDecorAtom = XInternAtom(dpy, "_MOTIF_WM_HINTS", 0); if(noDecorAtom == None) { fprintf(stderr, "Could not intern X atom for _MOTIF_WM_HINTS.\n"); } struct NoDecorHints { long flags; long functions; long decorations; long input_mode; }; NoDecorHints oHints; oHints.flags = 2; oHints.decorations = 0; XChangeProperty(dpy, hwin, noDecorAtom, noDecorAtom, 32, PropModeReplace, reinterpret_cast<unsigned char *>(&oHints), 4); } // create the render action ract = OSG::RenderAction::create(); // setup the OpenSG Glut window window = OSG::XWindow::create(); window->setDisplay ( dpy ); window->setWindow ( hwin ); window->init(); XEvent event; XMapWindow(dpy, hwin); XIfEvent(dpy, &event, wait_for_map_notify, reinterpret_cast<char *>(hwin)); if(fullscreen == true) { XMoveWindow (dpy, hwin, 0, 0); XResizeWindow(dpy, hwin, DisplayWidth (dpy, vi->screen), DisplayHeight(dpy, vi->screen)); static char data[1] = {0}; Cursor cursor; Pixmap blank; XColor dummyCol; blank = XCreateBitmapFromData(dpy, hwin, data, 1, 1); cursor = XCreatePixmapCursor(dpy, blank, blank, &dummyCol, &dummyCol, 0, 0); XFreePixmap(dpy, blank); XDefineCursor(dpy, hwin, cursor); XFlush(dpy); } window->activate(); glEnable( GL_LIGHTING ); glEnable( GL_LIGHT0 ); glEnable( GL_NORMALIZE ); // create the cluster server server = new OSG::ClusterServer(window,name,connectionType,address); // start the server server->start(); bool stopIt = false; int ip; while(!stopIt) { while((ip = XPending(dpy)) != 0) { XNextEvent(dpy, &event); switch (event.type) { case ConfigureNotify: { reshape(event.xconfigure.width, event.xconfigure.height); } break; case Expose: display(); break; } } display(); } } catch(OSG_STDEXCEPTION_NAMESPACE::exception &e) { SLOG << e.what() << OSG::endLog; delete server; ract = NULL; window = NULL; OSG::osgExit(); } return 0; }
/*!*********************************************************************** @Function OpenX11Window @Return true on success @Description Opens an X11 window. This must be called after SelectEGLConfiguration() for gEglConfig to be valid *************************************************************************/ int PVRShellInitOS::OpenX11Window(const PVRShell &shell) { XSetWindowAttributes WinAttibutes; XSizeHints sh; XEvent event; unsigned long mask; #ifdef BUILD_OGL XF86VidModeModeInfo **modes; // modes of display int numModes; // number of modes of display int chosenMode; int edimx,edimy; //established width and height of the chosen modeline int i; #endif int depth = DefaultDepth(m_X11Display, m_X11Screen); m_X11Visual = new XVisualInfo; XMatchVisualInfo( m_X11Display, m_X11Screen, depth, TrueColor, m_X11Visual); if( !m_X11Visual ) { shell.PVRShellOutputDebug( "Unable to acquire visual" ); return false; } m_X11ColorMap = XCreateColormap( m_X11Display, RootWindow(m_X11Display, m_X11Screen), m_X11Visual->visual, AllocNone ); #ifdef BUILD_OGL m_i32OriginalModeDotClock = XF86VidModeBadClock; if(shell.m_pShellData->bFullScreen) { // Get mode lines to see if there is requested modeline XF86VidModeGetAllModeLines(m_X11Display, m_X11Screen, &numModes, &modes); // look for mode with requested resolution chosenMode = -1; i=0; while((chosenMode == -1)&&(i<numModes)) { if ((modes[i]->hdisplay == shell.m_pShellData->nShellDimX) && (modes[i]->vdisplay == shell.m_pShellData->nShellDimY)) { chosenMode = i; } ++i; } // If there is no requested resolution among modelines then terminate if(chosenMode == -1) { shell.PVRShellOutputDebug( "Chosen resolution for full screen mode does not match any modeline available.\n" ); return false; } // save desktop-resolution before switching modes XF86VidModeGetModeLine(m_X11Display,m_X11Screen, &m_i32OriginalModeDotClock, &m_OriginalMode ); XF86VidModeSwitchToMode(m_X11Display, m_X11Screen, modes[chosenMode]); XF86VidModeSetViewPort(m_X11Display, m_X11Screen, 0, 0); edimx = modes[chosenMode]->hdisplay; edimy = modes[chosenMode]->vdisplay; printf("Fullscreen Resolution %dx%d (chosen mode = %d)\n", edimx, edimy,chosenMode); XFree(modes); WinAttibutes.colormap = m_X11ColorMap; WinAttibutes.background_pixel = 0xFFFFFFFF; WinAttibutes.border_pixel = 0; WinAttibutes.override_redirect = true; // add to these for handling other events WinAttibutes.event_mask = StructureNotifyMask | ExposureMask | ButtonPressMask | ButtonReleaseMask | Button1MotionMask | KeyPressMask | KeyReleaseMask; // The diffrence is that we want to ignore influence of window manager for our fullscreen window mask = CWBackPixel | CWBorderPixel | CWEventMask | CWColormap | CWOverrideRedirect; m_X11Window = XCreateWindow( m_X11Display, RootWindow(m_X11Display, m_X11Screen), 0, 0, edimx, edimy, 0, CopyFromParent, InputOutput, CopyFromParent, mask, &WinAttibutes); // keeping the pointer of mouse and keyboard in window to prevent from scrolling the virtual screen XWarpPointer(m_X11Display, None ,m_X11Window, 0, 0, 0, 0, 0, 0); // Map and then wait till mapped, grabbing should be after mapping the window XMapWindow( m_X11Display, m_X11Window ); XGrabKeyboard(m_X11Display, m_X11Window, True, GrabModeAsync, GrabModeAsync, CurrentTime); XGrabPointer(m_X11Display, m_X11Window, True, ButtonPressMask, GrabModeAsync, GrabModeAsync, m_X11Window, None, CurrentTime); XIfEvent( m_X11Display, &event, WaitForMapNotify, (char*)m_X11Window ); } else #endif { // For OGLES we assume that chaning of video mode is not available (freedesktop does not allow to do it) // so if requested resolution differs from the display dims then we quit #ifndef BUILD_OGL int display_width = XDisplayWidth(m_X11Display,m_X11Screen); int display_height = XDisplayHeight(m_X11Display,m_X11Screen); if((shell.m_pShellData->bFullScreen)&&((shell.m_pShellData->nShellDimX != display_width)||(shell.m_pShellData->nShellDimY != display_height)) ) { shell.PVRShellOutputDebug( "Chosen resolution for full screen mode does not match available modeline.\n" ); return false; } #endif WinAttibutes.colormap = m_X11ColorMap; WinAttibutes.background_pixel = 0xFFFFFFFF; WinAttibutes.border_pixel = 0; // add to these for handling other events WinAttibutes.event_mask = StructureNotifyMask | ExposureMask | ButtonPressMask | ButtonReleaseMask | Button1MotionMask | KeyPressMask | KeyReleaseMask; // The attribute mask mask = CWBackPixel | CWBorderPixel | CWEventMask | CWColormap ; m_X11Window = XCreateWindow( m_X11Display, // Display RootWindow(m_X11Display, m_X11Screen), // Parent shell.m_pShellData->nShellPosX, // X position of window shell.m_pShellData->nShellPosY, // Y position of window shell.m_pShellData->nShellDimX, // Window width shell.m_pShellData->nShellDimY, // Window height 0, // Border width CopyFromParent, // Depth (taken from parent) InputOutput, // Window class CopyFromParent, // Visual type (taken from parent) mask, // Attributes mask &WinAttibutes); // Attributes // Set the window position sh.flags = USPosition; sh.x = shell.m_pShellData->nShellPosX; sh.y = shell.m_pShellData->nShellPosY; XSetStandardProperties( m_X11Display, m_X11Window, shell.m_pShellData->pszAppName, shell.m_pShellData->pszAppName, None, 0, 0, &sh ); // Map and then wait till mapped XMapWindow( m_X11Display, m_X11Window ); XIfEvent( m_X11Display, &event, WaitForMapNotify, (char*)m_X11Window ); // An attempt to hide a border for fullscreen on non OGL apis (OGLES,OGLES2) if(shell.m_pShellData->bFullScreen) { XEvent xev; Atom wmState = XInternAtom(m_X11Display, "_NET_WM_STATE", False); Atom wmStateFullscreen = XInternAtom(m_X11Display, "_NET_WM_STATE_FULLSCREEN", False); memset(&xev, 0, sizeof(XEvent)); xev.type = ClientMessage; xev.xclient.window = m_X11Window; xev.xclient.message_type = wmState; xev.xclient.format = 32; xev.xclient.data.l[0] = 1; xev.xclient.data.l[1] = wmStateFullscreen; xev.xclient.data.l[2] = 0; XSendEvent(m_X11Display, RootWindow(m_X11Display, m_X11Screen), False, SubstructureNotifyMask, &xev); } Atom wmDelete = XInternAtom(m_X11Display, "WM_DELETE_WINDOW", True); XSetWMProtocols(m_X11Display, m_X11Window, &wmDelete, 1); XSetWMColormapWindows( m_X11Display, m_X11Window, &m_X11Window, 1 ); } XFlush( m_X11Display ); return true; }
///////////////////////////////////////////////////////// // createMess // ///////////////////////////////////////////////////////// bool gemglxwindow :: create(void) { bool success=true; /* * hmm, this crashes when enabled * when disabled, we don't get textures on two screens */ //~#warning context-sharing disabled bool context_sharing=false; if(!m_context && context_sharing) { /* gemglxwindow::PIMPL::s_shared.count(m_display)>0 */ gemglxwindow::PIMPL*sharedPimpl=&gemglxwindow::PIMPL::s_shared[m_display]; if(!sharedPimpl->glxcontext) { try { int x=0, y=0; unsigned int w=1, h=1; success=sharedPimpl->create(m_display, 2, false, false, x, y, w, h, m_transparent); } catch (GemException&ex) { error("creation of shared glxcontext failed: %s", ex.what()); verbose(0, "continuing at your own risk!"); } if(!sharedPimpl->gemcontext) { try { sharedPimpl->gemcontext = createContext(); } catch (GemException&ex) { sharedPimpl->gemcontext = NULL; error("creation of shared gem::context failed: %s", ex.what()); } } } m_context=sharedPimpl->gemcontext; } else { // no context sharing /* creation of gem::Context is deferred until *after* window creation */ } int modeNum=4; #ifdef HAVE_LIBXXF86VM XF86VidModeModeInfo **modes; #endif char svalue[3]; snprintf(svalue, 3, "%d", m_fsaa); svalue[2]=0; if (m_fsaa!=0) { setenv("__GL_FSAA_MODE", svalue, 1); // this works only for NVIDIA-cards } try { success=m_pimpl->create(m_display, m_buffer, m_fullscreen, m_border, m_xoffset, m_yoffset, m_width, m_height, m_transparent); } catch (GemException&x) { x.report(); success=false; } if(!success) { return false; } /* create a gem::context if we don't already have (a shared) one */ if(!m_context) { try { m_context = createContext(); } catch (GemException&x) { m_context = NULL; error("creation of gem::context failed: %s", x.what()); } } XMapRaised(m_pimpl->dpy, m_pimpl->win); // XMapWindow(m_pimpl->dpy, m_pimpl->win); XEvent report; XIfEvent(m_pimpl->dpy, &report, WaitForNotify, (char*)m_pimpl->win); if (glXIsDirect(m_pimpl->dpy, m_pimpl->glxcontext)) { post("Direct Rendering enabled!"); } cursorMess(m_cursor); titleMess(m_title); return createGemWindow(); }
int main(int argc, char **argv) { XVisualInfo *vi; Colormap cmap; XSetWindowAttributes swa; Window win; GLXContext cx; XEvent event; fd_set readfds; struct timeval timeout; int xServerFD; int nselected; /* get a connection */ xDisplay = XOpenDisplay(0); if (xDisplay == NULL) { fprintf(stderr, "can't open display\n"); exit(1); } /* get an appropriate visual */ vi = glXChooseVisual(xDisplay, DefaultScreen(xDisplay), attributeList); if (vi == NULL) { fprintf(stderr, "can't get visual\n"); exit(1); } /* create a GLX context */ cx = glXCreateContext(xDisplay, vi, 0, GL_FALSE); if (cx == NULL) { fprintf(stderr, "can't create GL context\n"); exit(1); } /* create a color map */ cmap = XCreateColormap(xDisplay, RootWindow(xDisplay, vi->screen), vi->visual, AllocNone); /* create a window */ swa.colormap = cmap; swa.border_pixel = 0; swa.event_mask = StructureNotifyMask; windowWidth = 500; windowHeight = 500; win = XCreateWindow(xDisplay, RootWindow(xDisplay, vi->screen), 0, 0, windowWidth, windowHeight, 0, vi->depth, InputOutput, vi->visual, CWBorderPixel|CWColormap|CWEventMask, &swa); XSelectInput(xDisplay, win, KeyPressMask | ExposureMask | StructureNotifyMask); XMapWindow(xDisplay, win); // wait for the window to be mapped XIfEvent(xDisplay, &event, WaitForNotify, (char*)win); /* connect the context to the window */ glXMakeCurrent(xDisplay, win, cx); quad = gluNewQuadric(); if (quad == NULL) { fprintf(stderr, "can't allocate quadric\n"); exit(1); } resetEye(); xServerFD = ConnectionNumber(xDisplay); XFlush(xDisplay); while (1) { while (processX()) { } if (needRepaint) { doPaint(); } FD_ZERO(&readfds); if (!atEOF) { FD_SET(0, &readfds); } FD_SET(xServerFD, &readfds); timeout.tv_sec = 5; timeout.tv_usec = 0; nselected = select(xServerFD+1, &readfds, NULL, NULL, atEOF ? &timeout : NULL); if (nselected < 0) { perror("select"); continue; } if (nselected == 0) { continue; } if (FD_ISSET(0, &readfds)) { processStdin(); } } }
// needs to be run after SelectEGLConfiguration() // for gEglConfig to be valid int PVRShellInitOS::OpenX11Window(const PVRShell &shell) { XSetWindowAttributes wa; XSizeHints sh; XEvent event; unsigned long mask; #ifdef BUILD_OGL XF86VidModeModeInfo **modes; // modes of display int numModes; // number of modes of display int chosenMode; int edimx,edimy; //established width and height of the chosen modeline int i; #endif MyHints mwmhints; Atom prop; int depth = DefaultDepth(x11display, x11screen); x11visual = new XVisualInfo; XMatchVisualInfo( x11display, x11screen, depth, TrueColor, x11visual); if( !x11visual ) { shell.PVRShellOutputDebug( "Unable to acquire visual" ); return false; } x11colormap = XCreateColormap( x11display, RootWindow(x11display, x11screen), x11visual->visual, AllocNone ); #ifdef BUILD_OGL originalMode_dotclock = XF86VidModeBadClock; if(shell.m_pShellData->bFullScreen) { // Get mode lines to see if there is requested modeline XF86VidModeGetAllModeLines(x11display, x11screen, &numModes, &modes); /* look for mode with requested resolution */ chosenMode = -1; i=0; while((chosenMode == -1)&&(i<numModes)) { if ((modes[i]->hdisplay == shell.m_pShellData->nShellDimX) && (modes[i]->vdisplay == shell.m_pShellData->nShellDimY)) { chosenMode = i; } ++i; } // If there is no requested resolution among modelines then terminate if(chosenMode == -1) { shell.PVRShellOutputDebug( "Chosen resolution for full screen mode does not match any modeline available.\n" ); return false; } /* save desktop-resolution before switching modes */ XF86VidModeGetModeLine(x11display,x11screen, &originalMode_dotclock, &originalMode ); XF86VidModeSwitchToMode(x11display, x11screen, modes[chosenMode]); XF86VidModeSetViewPort(x11display, x11screen, 0, 0); edimx = modes[chosenMode]->hdisplay; edimy = modes[chosenMode]->vdisplay; printf("Fullscreen Resolution %dx%d (chosen mode = %d)\n", edimx, edimy,chosenMode); XFree(modes); //to musi byc globalne wa.colormap = x11colormap; wa.background_pixel = 0xFFFFFFFF; wa.border_pixel = 0; wa.override_redirect = true; // add to these for handling other events wa.event_mask = StructureNotifyMask | ExposureMask | ButtonPressMask | ButtonReleaseMask | KeyPressMask | KeyReleaseMask; // The diffrence is that we want to ignore influence of window manager for outr fullscreen window mask = CWBackPixel | CWBorderPixel | CWEventMask | CWColormap | CWOverrideRedirect; x11window = XCreateWindow( x11display, RootWindow(x11display, x11screen), 0, 0, edimx, edimy, 0, CopyFromParent, InputOutput, CopyFromParent, mask, &wa); // keeping the pointer of mouse and keyboard in window to prevent from scrolling the virtual screen XWarpPointer(x11display, None ,x11window, 0, 0, 0, 0, 0, 0); // Map and then wait till mapped, grabbing should be after mapping the window XMapWindow( x11display, x11window ); XGrabKeyboard(x11display, x11window, True, GrabModeAsync, GrabModeAsync, CurrentTime); XGrabPointer(x11display, x11window, True, ButtonPressMask, GrabModeAsync, GrabModeAsync, x11window, None, CurrentTime); XIfEvent( x11display, &event, WaitForMapNotify, (char*)x11window ); } else { #endif wa.colormap = x11colormap; wa.background_pixel = 0xFFFFFFFF; wa.border_pixel = 0; // add to these for handling other events wa.event_mask = StructureNotifyMask | ExposureMask | ButtonPressMask | ButtonReleaseMask | KeyPressMask | KeyReleaseMask; mask = CWBackPixel | CWBorderPixel | CWEventMask | CWColormap ; x11window = XCreateWindow( x11display, RootWindow(x11display, x11screen), shell.m_pShellData->nShellPosX, shell.m_pShellData->nShellPosY, shell.m_pShellData->nShellDimX, shell.m_pShellData->nShellDimY, 0, CopyFromParent, InputOutput, CopyFromParent, mask, &wa); // todo:meh remove this? sh.flags = USPosition; sh.x = shell.m_pShellData->nShellPosX; sh.y = shell.m_pShellData->nShellPosY; XSetStandardProperties( x11display, x11window, szTitle, szTitle, None, 0, 0, &sh ); // Map and then wait till mapped XMapWindow( x11display, x11window ); XIfEvent( x11display, &event, WaitForMapNotify, (char*)x11window ); // An attempt to hide a border for fullscreen on non OGL apis (OGLES,OGLES2) if(shell.m_pShellData->bFullScreen) { memset(&mwmhints, 0, sizeof(mwmhints)); prop = XInternAtom(x11display, "_MOTIF_WM_HINTS", False); mwmhints.flags = 2;//MWM_HINTS_DECORATIONS; mwmhints.decorations = 0; XChangeProperty(x11display, x11window, prop, prop, 32, PropModeReplace, (unsigned char *) &mwmhints,5); } // Atom wmDelete = XInternAtom(x11display, "WM_DELETE_WINDOW", True); XSetWMProtocols(x11display, x11window, &wmDelete, 1); XSetWMColormapWindows( x11display, x11window, &x11window, 1 ); #ifdef BUILD_OGL } #endif XFlush( x11display ); return true; }
int MFDisplay_CreateDisplay(int width, int height, int bpp, int rate, bool vsync, bool triplebuffer, bool wide, bool progressive) { MFCALLSTACK; MFZeroMemory(gXKeys, sizeof(gXKeys)); MFZeroMemory(&gXMouse, sizeof(gXMouse)); gXMouse.x = -1; gDisplay.fullscreenWidth = gDisplay.width = width; gDisplay.fullscreenHeight = gDisplay.height = height; gDisplay.refreshRate = 0; gDisplay.colourDepth = 0; /* Use default. Chances are, it's something sane */ gDisplay.windowed = true; gDisplay.wide = false; gDisplay.progressive = true; if(!(xdisplay = XOpenDisplay(NULL))) { MFDebug_Error("Unable to open display"); MFDisplay_DestroyDisplay(); return 1; } screen = DefaultScreen(xdisplay); rootWindow = RootWindow(xdisplay, screen); // build our internal list of available video modes GetModes(&modes, !gDisplay.windowed); while(!FindMode(modes, width, height)) { if(!gDisplay.windowed) { // no fullscreen mode, try windowed mode instead MFDebug_Warn(1, "No suitable modes for fullscreen mode, trying windowed mode"); gDisplay.windowed = true; FreeModes(); GetModes(&modes, false); } else { // default is some sort of custom mode that doesn't appear in the windowed mode list // HACK: we'll add it to the end.. modes[numModes].width = width; modes[numModes].height = height; currentMode = numModes; ++numModes; break; } } DebugMenu_AddItem("Resolution", "Display Options", &resSelect, ChangeResCallback); DebugMenu_AddItem("Apply", "Display Options", &applyDisplayMode, ApplyDisplayModeCallback); // Set full screen mode, if necessary if(!gDisplay.windowed && numModes > 1) { if(!XF86VidModeSwitchToMode(xdisplay, screen, vidModes[currentMode])) { MFDebug_Error("Unable to switch screenmodes, defaulting to windowed mode"); MFDisplay_DestroyDisplay(); return 1; } } XVisualInfo *MFRenderer_GetVisualInfo(); XVisualInfo *visualInfo = MFRenderer_GetVisualInfo(); if(!visualInfo) return 1; if(!(colorMap = XCreateColormap(xdisplay, rootWindow, visualInfo->visual, AllocNone))) { MFDebug_Error("Unable to create colourmap"); XFree(visualInfo); MFDisplay_DestroyDisplay(); return 1; } XSetWindowAttributes windowAttrs; windowAttrs.colormap = colorMap; windowAttrs.cursor = None; windowAttrs.event_mask = StructureNotifyMask; windowAttrs.border_pixel = BlackPixel(xdisplay, screen); windowAttrs.background_pixel = BlackPixel(xdisplay, screen); if(!(window = XCreateWindow(xdisplay, rootWindow, 0, 0, width, height, 0, visualInfo->depth, InputOutput, visualInfo->visual, CWBackPixel | CWBorderPixel | CWCursor | CWColormap | CWEventMask, &windowAttrs))) { MFDebug_Error("Unable to create X Window"); XFree(visualInfo); MFDisplay_DestroyDisplay(); return 1; } // Tell the window manager not to allow our window to be resized. But some window managers can ignore me and do it anyway. Typical X-Windows. if((sizeHints = XAllocSizeHints()) == NULL) { MFDebug_Error("Unable to alloc XSizeHints structure, out of memory?"); XFree(visualInfo); MFDisplay_DestroyDisplay(); return 1; } sizeHints->flags = PSize | PMinSize | PMaxSize; sizeHints->min_width = sizeHints->max_width = sizeHints->base_width = width; sizeHints->min_height = sizeHints->max_height = sizeHints->base_height = height; XSetWMNormalHints(xdisplay, window, sizeHints); // Window title XStoreName(xdisplay, window, gDefaults.display.pWindowTitle); XWMHints *wmHints; if((wmHints = XAllocWMHints()) == NULL) { MFDebug_Error("Unable to alloc XWMHints structure, out of memory?"); XFree(visualInfo); MFDisplay_DestroyDisplay(); return 1; } wmHints->flags = InputHint | StateHint; wmHints->input = true; wmHints->initial_state = NormalState; if(!XSetWMHints(xdisplay, window, wmHints)) { MFDebug_Error("Unable to set WM hints for window"); XFree(visualInfo); MFDisplay_DestroyDisplay(); return 1; } XFree(wmHints); XFree(visualInfo); // Tell the window manager that I want to be notified if the window's closed wm_delete_window = XInternAtom(xdisplay, "WM_DELETE_WINDOW", false); if(!XSetWMProtocols(xdisplay, window, &wm_delete_window, 1)) { MFDebug_Error("Unable to set Window Manager protocols"); MFDisplay_DestroyDisplay(); return 1; } XSelectInput(xdisplay, window, KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask | StructureNotifyMask | ExposureMask); if(!XMapRaised(xdisplay, window)) { MFDebug_Error("Unable to map new window"); MFDisplay_DestroyDisplay(); return 1; } // Wait for the window to be mapped, etc. The documentation doesn't indicate that this is necessary, but every GLX program I've ever seen does it, so I assume it is. XEvent event; XIfEvent(xdisplay, &event, WaitForNotify, (char *)window); MFRenderer_CreateDisplay(); if(!gDisplay.windowed && numModes > 1) { if(!XF86VidModeSwitchToMode(xdisplay, screen, vidModes[currentMode])) { MFDebug_Error("Unable to set screen mode"); MFDisplay_DestroyDisplay(); return 1; } XGrabPointer(xdisplay, window, True, ButtonPressMask, GrabModeAsync, GrabModeAsync, window, None, CurrentTime); XFlush(xdisplay); // A little trick to make sure the entire window is on the screen XWarpPointer(xdisplay, None, window, 0, 0, 0, 0, width - 1, height - 1); XWarpPointer(xdisplay, None, window, 0, 0, 0, 0, 0, 0); XFlush(xdisplay); } return 0; }
int wincreat( int x, int y, int width, int height, char *title) { XSetWindowAttributes swa; Colormap cmap; XVisualInfo *vi; int dummy; GLXContext glcx; XEvent event; int attributes[] = { GLX_RGBA, GLX_DEPTH_SIZE, 16, GLX_RED_SIZE, 8, GLX_GREEN_SIZE, 8, GLX_BLUE_SIZE, 8, GLX_ALPHA_SIZE, 8, GLX_DOUBLEBUFFER, None }; if( !(dpy = XOpenDisplay( NULL )) ) /* defaults to $DISPLAY */ { fprintf( stderr, "Unable to open display.\n" ); exit( 1 ); } else { /*printf( "Connected to display... %s (%s).\n", dpy->display_name, dpy->vendor );*/ } /* end if( ) */ if( !glXQueryExtension( dpy, &dummy, &dummy ) ) { fprintf( stderr, "Unable to query GLX extensions.\n" ); exit( 1 ); } /* end if( ) */ if( !(vi = glXChooseVisual( dpy, DefaultScreen( dpy ), attributes )) ) { fprintf( stderr, "Unable get a visual.\n" ); exit( 1 ); } /* end if( ) */ if( vi->class != TrueColor ) { fprintf( stderr, "Need TrueColor class.\n" ); exit( 1 ); } if( !(glcx = glXCreateContext( dpy, vi, None, GL_TRUE )) ) { fprintf( stderr, "Unable create a GL context.\n" ); exit( 1 ); } /* end if( ) */ cmap = XCreateColormap( dpy, RootWindow( dpy, vi->screen ), vi->visual, AllocNone ); swa.colormap = cmap; swa.border_pixel = 0; swa.event_mask = ExposureMask | KeyPressMask | StructureNotifyMask; glwin = XCreateWindow( dpy, RootWindow( dpy, vi->screen ), x, y, width, height, 0, vi->depth, InputOutput, vi->visual, CWBorderPixel | CWColormap | CWEventMask, &swa ); /* Make a clear cursor so it looks like we have none. */ { Pixmap pixmap; Cursor cursor; XColor color; char clear_bits[32]; memset(clear_bits, 0, sizeof(clear_bits)); pixmap = XCreatePixmapFromBitmapData(dpy, glwin, clear_bits, 16, 16, 1, 0, 1); cursor = XCreatePixmapCursor(dpy, pixmap, pixmap, &color, &color, 8, 8); XDefineCursor(dpy, glwin, cursor); XFreePixmap(dpy, pixmap); } XSetStandardProperties( dpy, glwin, title, title, None, NULL, 0, NULL ); if( !glXMakeCurrent( dpy, glwin, glcx ) ) { fprintf( stderr, "Failed to make the GL context current.\n" ); exit( 1 ); } XMapWindow( dpy, glwin ); XIfEvent( dpy, &event, WaitForMapNotify, (char *)glwin ); return( 1 ); } /* end int APIENTRY pglc_wincreat( ) */
/** Prepare the connection. */ void StartupConnection(void) { XSetWindowAttributes attr; #ifdef USE_SHAPE int shapeError; #endif #ifdef USE_XRENDER int renderEvent; int renderError; #endif struct sigaction sa; char name[32]; Window win; XEvent event; int revert; initializing = 1; OpenConnection(); #if 0 XSynchronize(display, True); #endif /* Create the supporting window used to verify JWM is running. */ supportingWindow = JXCreateSimpleWindow(display, rootWindow, 0, 0, 1, 1, 0, 0, 0); /* Get the atom used for the window manager selection. */ snprintf(name, 32, "WM_S%d", rootScreen); managerSelection = JXInternAtom(display, name, False); /* Get the current window manager and take the selection. */ GrabServer(); win = JXGetSelectionOwner(display, managerSelection); if(win != None) { JXSelectInput(display, win, StructureNotifyMask); } JXSetSelectionOwner(display, managerSelection, supportingWindow, CurrentTime); UngrabServer(); /* Wait for the current selection owner to give up the selection. */ if(win != None) { /* Note that we need to wait for the current selection owner * to exit before we can expect to select SubstructureRedirectMask. */ XIfEvent(display, &event, SelectionReleased, (XPointer)&win); JXSync(display, False); } event.xclient.display = display; event.xclient.type = ClientMessage; event.xclient.window = rootWindow; event.xclient.message_type = JXInternAtom(display, managerProperty, False); event.xclient.format = 32; event.xclient.data.l[0] = CurrentTime; event.xclient.data.l[1] = managerSelection; event.xclient.data.l[2] = supportingWindow; event.xclient.data.l[3] = 2; event.xclient.data.l[4] = 0; JXSendEvent(display, rootWindow, False, StructureNotifyMask, &event); JXSync(display, False); JXSetErrorHandler(ErrorHandler); clientContext = XUniqueContext(); frameContext = XUniqueContext(); /* Set the events we want for the root window. * Note that asking for SubstructureRedirect will fail * if another window manager is already running. */ attr.event_mask = SubstructureRedirectMask | SubstructureNotifyMask | StructureNotifyMask | PropertyChangeMask | ColormapChangeMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask | PointerMotionHintMask; JXChangeWindowAttributes(display, rootWindow, CWEventMask, &attr); memset(&sa, 0, sizeof(sa)); sa.sa_flags = 0; sa.sa_handler = HandleExit; sigaction(SIGTERM, &sa, NULL); sigaction(SIGINT, &sa, NULL); sigaction(SIGHUP, &sa, NULL); sa.sa_flags = SA_NOCLDWAIT; sa.sa_handler = SIG_DFL; sigaction(SIGCHLD, &sa, NULL); #ifdef USE_SHAPE haveShape = JXShapeQueryExtension(display, &shapeEvent, &shapeError); if (haveShape) { Debug("shape extension enabled"); } else { Debug("shape extension disabled"); } #endif #ifdef USE_XRENDER haveRender = JXRenderQueryExtension(display, &renderEvent, &renderError); if(haveRender) { Debug("render extension enabled"); } else { Debug("render extension disabled"); } #endif /* Make sure we have input focus. */ win = None; JXGetInputFocus(display, &win, &revert); if(win == None) { JXSetInputFocus(display, rootWindow, RevertToParent, CurrentTime); } initializing = 0; }
// Create the X11 window (and its colormap) // static GLboolean createWindow(_GLFWwindow* window, const _GLFWwndconfig* wndconfig) { unsigned long wamask; XSetWindowAttributes wa; XVisualInfo* visual = _GLFW_X11_CONTEXT_VISUAL; // Every window needs a colormap // Create one based on the visual used by the current context // TODO: Decouple this from context creation window->x11.colormap = XCreateColormap(_glfw.x11.display, _glfw.x11.root, visual->visual, AllocNone); // Create the actual window { wamask = CWBorderPixel | CWColormap | CWEventMask; wa.colormap = window->x11.colormap; wa.border_pixel = 0; wa.event_mask = StructureNotifyMask | KeyPressMask | KeyReleaseMask | PointerMotionMask | ButtonPressMask | ButtonReleaseMask | ExposureMask | FocusChangeMask | VisibilityChangeMask | EnterWindowMask | LeaveWindowMask | PropertyChangeMask; _glfwGrabXErrorHandler(); window->x11.handle = XCreateWindow(_glfw.x11.display, _glfw.x11.root, 0, 0, wndconfig->width, wndconfig->height, 0, // Border width visual->depth, // Color depth InputOutput, visual->visual, wamask, &wa); _glfwReleaseXErrorHandler(); if (!window->x11.handle) { _glfwInputXError(GLFW_PLATFORM_ERROR, "X11: Failed to create window"); return GL_FALSE; } if (!wndconfig->decorated) { MotifWmHints hints; hints.flags = MWM_HINTS_DECORATIONS; hints.decorations = 0; XChangeProperty(_glfw.x11.display, window->x11.handle, _glfw.x11.MOTIF_WM_HINTS, _glfw.x11.MOTIF_WM_HINTS, 32, PropModeReplace, (unsigned char*) &hints, sizeof(MotifWmHints) / sizeof(long)); } XSaveContext(_glfw.x11.display, window->x11.handle, _glfw.x11.context, (XPointer) window); } if (window->monitor && !_glfw.x11.hasEWMH) { // This is the butcher's way of removing window decorations // Setting the override-redirect attribute on a window makes the window // manager ignore the window completely (ICCCM, section 4) // The good thing is that this makes undecorated fullscreen windows // easy to do; the bad thing is that we have to do everything manually // and some things (like iconify/restore) won't work at all, as those // are tasks usually performed by the window manager XSetWindowAttributes attributes; attributes.override_redirect = True; XChangeWindowAttributes(_glfw.x11.display, window->x11.handle, CWOverrideRedirect, &attributes); window->x11.overrideRedirect = GL_TRUE; } // Declare the WM protocols supported by GLFW { int count = 0; Atom protocols[2]; // The WM_DELETE_WINDOW ICCCM protocol // Basic window close notification protocol if (_glfw.x11.WM_DELETE_WINDOW) protocols[count++] = _glfw.x11.WM_DELETE_WINDOW; // The _NET_WM_PING EWMH protocol // Tells the WM to ping the GLFW window and flag the application as // unresponsive if the WM doesn't get a reply within a few seconds if (_glfw.x11.NET_WM_PING) protocols[count++] = _glfw.x11.NET_WM_PING; if (count > 0) { XSetWMProtocols(_glfw.x11.display, window->x11.handle, protocols, count); } } if (_glfw.x11.NET_WM_PID) { const pid_t pid = getpid(); XChangeProperty(_glfw.x11.display, window->x11.handle, _glfw.x11.NET_WM_PID, XA_CARDINAL, 32, PropModeReplace, (unsigned char*) &pid, 1); } // Set ICCCM WM_HINTS property { XWMHints* hints = XAllocWMHints(); if (!hints) { _glfwInputError(GLFW_OUT_OF_MEMORY, "X11: Failed to allocate WM hints"); return GL_FALSE; } hints->flags = StateHint; hints->initial_state = NormalState; XSetWMHints(_glfw.x11.display, window->x11.handle, hints); XFree(hints); } // Set ICCCM WM_NORMAL_HINTS property (even if no parts are set) { XSizeHints* hints = XAllocSizeHints(); hints->flags = 0; if (wndconfig->monitor) { hints->flags |= PPosition; _glfwPlatformGetMonitorPos(wndconfig->monitor, &hints->x, &hints->y); } else { // HACK: Explicitly setting PPosition to any value causes some WMs, // notably Compiz and Metacity, to honor the position of // unmapped windows set by XMoveWindow hints->flags |= PPosition; hints->x = hints->y = 0; } if (!wndconfig->resizable) { hints->flags |= (PMinSize | PMaxSize); hints->min_width = hints->max_width = wndconfig->width; hints->min_height = hints->max_height = wndconfig->height; } XSetWMNormalHints(_glfw.x11.display, window->x11.handle, hints); XFree(hints); } // Set ICCCM WM_CLASS property // HACK: Until a mechanism for specifying the application name is added, the // initial window title is used as the window class name if (strlen(wndconfig->title)) { XClassHint* hint = XAllocClassHint(); hint->res_name = (char*) wndconfig->title; hint->res_class = (char*) wndconfig->title; XSetClassHint(_glfw.x11.display, window->x11.handle, hint); XFree(hint); } if (_glfw.x11.xi.available) { // Select for XInput2 events XIEventMask eventmask; unsigned char mask[] = { 0 }; eventmask.deviceid = 2; eventmask.mask_len = sizeof(mask); eventmask.mask = mask; XISetMask(mask, XI_Motion); XISelectEvents(_glfw.x11.display, window->x11.handle, &eventmask, 1); } if (_glfw.x11.XdndAware) { // Announce support for Xdnd (drag and drop) const Atom version = 5; XChangeProperty(_glfw.x11.display, window->x11.handle, _glfw.x11.XdndAware, XA_ATOM, 32, PropModeReplace, (unsigned char*) &version, 1); } if (_glfw.x11.NET_REQUEST_FRAME_EXTENTS) { // Ensure _NET_FRAME_EXTENTS is set, allowing glfwGetWindowFrameSize to // function before the window is mapped XEvent event; memset(&event, 0, sizeof(event)); event.type = ClientMessage; event.xclient.window = window->x11.handle; event.xclient.format = 32; // Data is 32-bit longs event.xclient.message_type = _glfw.x11.NET_REQUEST_FRAME_EXTENTS; XSendEvent(_glfw.x11.display, _glfw.x11.root, False, SubstructureNotifyMask | SubstructureRedirectMask, &event); XIfEvent(_glfw.x11.display, &event, isFrameExtentsEvent, (XPointer) window); } _glfwPlatformSetWindowTitle(window, wndconfig->title); XRRSelectInput(_glfw.x11.display, window->x11.handle, RRScreenChangeNotifyMask); _glfwPlatformGetWindowPos(window, &window->x11.xpos, &window->x11.ypos); _glfwPlatformGetWindowSize(window, &window->x11.width, &window->x11.height); return GL_TRUE; }