void wsCreateWindow( wsTWindow * win,int X,int Y,int wX,int hY,int bW,int cV,unsigned char D,char * label ) { int depth; win->Property=D; if ( D & wsShowFrame ) win->Decorations=1; wsHGC=DefaultGC( wsDisplay,wsScreen ); // The window position and size. switch ( X ) { case -1: win->X=( wsMaxX / 2 ) - ( wX / 2 ) + wsOrgX; break; case -2: win->X=wsMaxX - wX - 1 + wsOrgX; break; default: win->X=X; break; } switch ( Y ) { case -1: win->Y=( wsMaxY / 2 ) - ( hY / 2 ) + wsOrgY; break; case -2: win->Y=wsMaxY - hY - 1 + wsOrgY; break; default: win->Y=Y; break; } win->Width=wX; win->Height=hY; win->OldX=win->X; win->OldY=win->Y; win->OldWidth=win->Width; win->OldHeight=win->Height; // Border size for window. win->BorderWidth=bW; // Hide Mouse Cursor win->wsCursor=None; win->wsMouseEventType=cV; win->wsCursorData[0]=0; win->wsCursorPixmap=XCreateBitmapFromData( wsDisplay,wsRootWin,win->wsCursorData,1,1 ); if ( !(cV & wsShowMouseCursor) ) win->wsCursor=XCreatePixmapCursor( wsDisplay,win->wsCursorPixmap,win->wsCursorPixmap,&win->wsColor,&win->wsColor,0,0 ); depth = vo_find_depth_from_visuals( wsDisplay,wsScreen,NULL ); if ( depth < 15 ) { mp_msg( MSGT_GPLAYER,MSGL_FATAL,MSGTR_WS_ColorDepthTooLow ); exit( 0 ); } XMatchVisualInfo( wsDisplay,wsScreen,depth,TrueColor,&win->VisualInfo ); // --- win->AtomLeaderClient=XInternAtom( wsDisplay,"WM_CLIENT_LEADER",False ); win->AtomDeleteWindow=XInternAtom( wsDisplay,"WM_DELETE_WINDOW",False ); win->AtomTakeFocus=XInternAtom( wsDisplay,"WM_TAKE_FOCUS",False ); win->AtomRolle=XInternAtom( wsDisplay,"WM_WINDOW_ROLE",False ); win->AtomWMSizeHint=XInternAtom( wsDisplay,"WM_SIZE_HINT",False ); win->AtomWMNormalHint=XInternAtom( wsDisplay,"WM_NORMAL_HINT",False ); win->AtomProtocols=XInternAtom( wsDisplay,"WM_PROTOCOLS",False ); win->AtomsProtocols[0]=win->AtomDeleteWindow; win->AtomsProtocols[1]=win->AtomTakeFocus; win->AtomsProtocols[2]=win->AtomRolle; // --- win->WindowAttrib.background_pixel=BlackPixel( wsDisplay,wsScreen ); win->WindowAttrib.border_pixel=WhitePixel( wsDisplay,wsScreen ); win->WindowAttrib.colormap=XCreateColormap( wsDisplay,wsRootWin,win->VisualInfo.visual,AllocNone ); win->WindowAttrib.event_mask=StructureNotifyMask | FocusChangeMask | ExposureMask | PropertyChangeMask | EnterWindowMask | LeaveWindowMask | VisibilityChangeMask | KeyPressMask | KeyReleaseMask; if ( ( cV & wsHandleMouseButton ) ) win->WindowAttrib.event_mask|=ButtonPressMask | ButtonReleaseMask; if ( ( cV & wsHandleMouseMove ) ) win->WindowAttrib.event_mask|=PointerMotionMask; win->WindowAttrib.cursor=win->wsCursor; win->WindowAttrib.override_redirect=False; if ( D & wsOverredirect ) win->WindowAttrib.override_redirect=True; win->WindowMask=CWBackPixel | CWBorderPixel | CWColormap | CWEventMask | CWCursor | CWOverrideRedirect; win->WindowID=XCreateWindow( wsDisplay, (win->Parent != 0?win->Parent:wsRootWin), win->X,win->Y,win->Width,win->Height,win->BorderWidth, win->VisualInfo.depth, InputOutput, win->VisualInfo.visual, win->WindowMask,&win->WindowAttrib ); wsClassHint.res_name="MPlayer"; wsClassHint.res_class="MPlayer"; XSetClassHint( wsDisplay,win->WindowID,&wsClassHint ); win->SizeHint.flags=PPosition | PSize | PResizeInc | PWinGravity;// | PBaseSize; win->SizeHint.x=win->X; win->SizeHint.y=win->Y; win->SizeHint.width=win->Width; win->SizeHint.height=win->Height; if ( D & wsMinSize ) { win->SizeHint.flags|=PMinSize; win->SizeHint.min_width=win->Width; win->SizeHint.min_height=win->Height; } if ( D & wsMaxSize ) { win->SizeHint.flags|=PMaxSize; win->SizeHint.max_width=win->Width; win->SizeHint.max_height=win->Height; } win->SizeHint.height_inc=1; win->SizeHint.width_inc=1; win->SizeHint.base_width=win->Width; win->SizeHint.base_height=win->Height; win->SizeHint.win_gravity=StaticGravity; XSetWMNormalHints( wsDisplay,win->WindowID,&win->SizeHint ); win->WMHints.flags=InputHint | StateHint; win->WMHints.input=True; win->WMHints.initial_state=NormalState; XSetWMHints( wsDisplay,win->WindowID,&win->WMHints ); wsWindowDecoration( win,win->Decorations ); XStoreName( wsDisplay,win->WindowID,label ); XmbSetWMProperties( wsDisplay,win->WindowID,label,label,NULL,0,NULL,NULL,NULL ); XSetWMProtocols( wsDisplay,win->WindowID,win->AtomsProtocols,3 ); XChangeProperty( wsDisplay,win->WindowID, win->AtomLeaderClient, XA_WINDOW,32,PropModeReplace, (unsigned char *)&LeaderWindow,1 ); wsTextProperty.value=label; wsTextProperty.encoding=XA_STRING; wsTextProperty.format=8; wsTextProperty.nitems=strlen( label ); XSetWMIconName( wsDisplay,win->WindowID,&wsTextProperty ); win->wGC=XCreateGC( wsDisplay,win->WindowID, GCForeground | GCBackground, &win->wGCV ); win->Visible=0; win->Focused=0; win->Mapped=0; win->Rolled=0; if ( D & wsShowWindow ) XMapWindow( wsDisplay,win->WindowID ); wsCreateImage( win,win->Width,win->Height ); // --- End of creating -------------------------------------------------------------------------- { int i; for ( i=0;i < wsWLCount;i++ ) if ( wsWindowList[i] == NULL ) break; if ( i == wsWLCount ) { mp_msg( MSGT_GPLAYER,MSGL_FATAL,MSGTR_WS_TooManyOpenWindows ); exit( 0 ); } wsWindowList[i]=win; } XFlush( wsDisplay ); XSync( wsDisplay,False ); win->ReDraw=NULL; win->ReSize=NULL; win->Idle=NULL; win->MouseHandler=NULL; win->KeyHandler=NULL; mp_dbg( MSGT_GPLAYER,MSGL_DBG2,"[ws] window is created. ( %s ).\n",label ); }
static void print_screen_info(Display *dpy, int scrnum, Bool allowDirect, GLboolean limits) { Window win; int attribSingle[] = { GLX_RGBA, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1, None }; int attribDouble[] = { GLX_RGBA, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1, GLX_DOUBLEBUFFER, None }; XSetWindowAttributes attr; unsigned long mask; Window root; GLXContext ctx = NULL; XVisualInfo *visinfo; int width = 100, height = 100; root = RootWindow(dpy, scrnum); /* * Find a basic GLX visual. We'll then create a rendering context and * query various info strings. */ visinfo = glXChooseVisual(dpy, scrnum, attribSingle); if (!visinfo) visinfo = glXChooseVisual(dpy, scrnum, attribDouble); if (visinfo) ctx = glXCreateContext( dpy, visinfo, NULL, allowDirect ); #ifdef GLX_VERSION_1_3 /* Try glXChooseFBConfig() if glXChooseVisual didn't work. * XXX when would that happen? */ if (!visinfo) { int fbAttribSingle[] = { GLX_RENDER_TYPE, GLX_RGBA_BIT, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1, GLX_DOUBLEBUFFER, GL_FALSE, None }; int fbAttribDouble[] = { GLX_RENDER_TYPE, GLX_RGBA_BIT, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1, GLX_DOUBLEBUFFER, GL_TRUE, None }; GLXFBConfig *configs = NULL; int nConfigs; configs = glXChooseFBConfig(dpy, scrnum, fbAttribSingle, &nConfigs); if (!configs) configs = glXChooseFBConfig(dpy, scrnum, fbAttribDouble, &nConfigs); if (configs) { visinfo = glXGetVisualFromFBConfig(dpy, configs[0]); ctx = glXCreateNewContext(dpy, configs[0], GLX_RGBA_TYPE, NULL, allowDirect); XFree(configs); } } #endif if (!visinfo) { fprintf(stderr, "Error: couldn't find RGB GLX visual or fbconfig\n"); return; } if (!ctx) { fprintf(stderr, "Error: glXCreateContext failed\n"); XFree(visinfo); return; } attr.background_pixel = 0; attr.border_pixel = 0; attr.colormap = XCreateColormap(dpy, root, visinfo->visual, AllocNone); attr.event_mask = StructureNotifyMask | ExposureMask; mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask; win = XCreateWindow(dpy, root, 0, 0, width, height, 0, visinfo->depth, InputOutput, visinfo->visual, mask, &attr); if (glXMakeCurrent(dpy, win, ctx)) { const char *serverVendor = glXQueryServerString(dpy, scrnum, GLX_VENDOR); const char *serverVersion = glXQueryServerString(dpy, scrnum, GLX_VERSION); const char *serverExtensions = glXQueryServerString(dpy, scrnum, GLX_EXTENSIONS); const char *clientVendor = glXGetClientString(dpy, GLX_VENDOR); const char *clientVersion = glXGetClientString(dpy, GLX_VERSION); const char *clientExtensions = glXGetClientString(dpy, GLX_EXTENSIONS); const char *glxExtensions = glXQueryExtensionsString(dpy, scrnum); const char *glVendor = (const char *) glGetString(GL_VENDOR); const char *glRenderer = (const char *) glGetString(GL_RENDERER); const char *glVersion = (const char *) glGetString(GL_VERSION); const char *glExtensions = (const char *) glGetString(GL_EXTENSIONS); int glxVersionMajor; int glxVersionMinor; char *displayName = NULL; char *colon = NULL, *period = NULL; if (! glXQueryVersion( dpy, & glxVersionMajor, & glxVersionMinor )) { fprintf(stderr, "Error: glXQueryVersion failed\n"); exit(1); } /* Strip the screen number from the display name, if present. */ if (!(displayName = (char *) malloc(strlen(DisplayString(dpy)) + 1))) { fprintf(stderr, "Error: malloc() failed\n"); exit(1); } strcpy(displayName, DisplayString(dpy)); colon = strrchr(displayName, ':'); if (colon) { period = strchr(colon, '.'); if (period) *period = '\0'; } printf("display: %s screen: %d\n", displayName, scrnum); free(displayName); printf("direct rendering: "); if (glXIsDirect(dpy, ctx)) { printf("Yes\n"); } else { if (!allowDirect) { printf("No (-i specified)\n"); } else if (getenv("LIBGL_ALWAYS_INDIRECT")) { printf("No (LIBGL_ALWAYS_INDIRECT set)\n"); } else { printf("No (If you want to find out why, try setting " "LIBGL_DEBUG=verbose)\n"); } } printf("server glx vendor string: %s\n", serverVendor); printf("server glx version string: %s\n", serverVersion); printf("server glx extensions:\n"); print_extension_list(serverExtensions); printf("client glx vendor string: %s\n", clientVendor); printf("client glx version string: %s\n", clientVersion); printf("client glx extensions:\n"); print_extension_list(clientExtensions); printf("GLX version: %u.%u\n", glxVersionMajor, glxVersionMinor); printf("GLX extensions:\n"); print_extension_list(glxExtensions); printf("OpenGL vendor string: %s\n", glVendor); printf("OpenGL renderer string: %s\n", glRenderer); printf("OpenGL version string: %s\n", glVersion); #ifdef GL_VERSION_2_0 if (glVersion[0] >= '2' && glVersion[1] == '.') { char *v = (char *) glGetString(GL_SHADING_LANGUAGE_VERSION); printf("OpenGL shading language version string: %s\n", v); } #endif printf("OpenGL extensions:\n"); print_extension_list(glExtensions); if (limits) print_limits(glExtensions); } else { fprintf(stderr, "Error: glXMakeCurrent failed\n"); } glXDestroyContext(dpy, ctx); XFree(visinfo); XDestroyWindow(dpy, win); }
bool video::init_window(int xsize, int ysize) { { //enclose local variables before fail label g_sizex = xsize; g_sizey = ysize; // Open the display if (!dpy) { dpy = XOpenDisplay(display_name); if (!dpy) { fprintf(stderr, "Can't open X11 display %s\n", XDisplayName(display_name)); goto fail; } } int theScreen = DefaultScreen(dpy); scrn = ScreenOfDisplay(dpy, theScreen); dispdepth = DefaultDepth(dpy, theScreen); XVisualInfo vinfo; if (!( (dispdepth >= 15 && dispdepth <= 32 && XMatchVisualInfo(dpy, theScreen, dispdepth, TrueColor, &vinfo) ) || XMatchVisualInfo(dpy, theScreen, 24, TrueColor, &vinfo) || XMatchVisualInfo(dpy, theScreen, 32, TrueColor, &vinfo) || XMatchVisualInfo(dpy, theScreen, 16, TrueColor, &vinfo) || XMatchVisualInfo(dpy, theScreen, 15, TrueColor, &vinfo) )) { fprintf(stderr, "Display has no appropriate True Color visual\n"); goto fail; } vis = vinfo.visual; depth = dispdepth = vinfo.depth; mask2bits(vinfo.red_mask, red_mask, red_shift); mask2bits(vinfo.green_mask, green_mask, green_shift); mask2bits(vinfo.blue_mask, blue_mask, blue_shift); rootW = RootWindow(dpy, theScreen); cmap = XCreateColormap(dpy, rootW, vis, AllocNone); XSetWindowAttributes attrs; attrs.backing_store = Always; attrs.colormap = cmap; attrs.event_mask = StructureNotifyMask|KeyPressMask|ButtonPressMask|ButtonReleaseMask; attrs.background_pixel = BlackPixelOfScreen(scrn); attrs.border_pixel = WhitePixelOfScreen(scrn); win = XCreateWindow(dpy, rootW, 0, 0, xsize, ysize, 2, dispdepth, InputOutput, vis, CWBackingStore | CWColormap | CWEventMask | CWBackPixel | CWBorderPixel, &attrs); if(!win) { fprintf(stderr, "Can't create the window\n"); goto fail; } XSizeHints sh; sh.flags = PSize | PMinSize | PMaxSize; sh.width = sh.min_width = sh.max_width = xsize; sh.height = sh.min_height = sh.max_height = ysize; XSetStandardProperties( dpy, win, g_video->title, g_video->title, None, NULL, 0, &sh ); _XA_WM_DELETE_WINDOW = XInternAtom(dpy, "WM_DELETE_WINDOW", false); XSetWMProtocols(dpy, win, &_XA_WM_DELETE_WINDOW, 1); gc = XCreateGC(dpy, win, 0L, &xgcv); XMapRaised(dpy, win); XFlush(dpy); #ifdef X_FULLSYNC XSynchronize(dpy, true); #endif XSetErrorHandler(xerr_handler); int imgbytes = xsize*ysize*(dispdepth<=16?2:4); const char *vidstr; #ifndef X_NOSHMEM int major, minor, pixmaps; if(XShmQueryExtension(dpy) && XShmQueryVersion(dpy, &major, &minor, &pixmaps)) { // Shared memory shmseginfo.shmid = shmget(IPC_PRIVATE, imgbytes, IPC_CREAT|0777); if(shmseginfo.shmid < 0) { fprintf(stderr, "Warning: Can't get shared memory: %s\n", strerror(errno)); goto generic; } g_pImg = (unsigned int*)(shmseginfo.shmaddr = (char*)shmat(shmseginfo.shmid, 0, 0)); if(g_pImg == (unsigned int*)-1) { fprintf(stderr, "Warning: Can't attach to shared memory: %s\n", strerror(errno)); shmctl(shmseginfo.shmid, IPC_RMID, NULL); goto generic; } shmseginfo.readOnly = false; if(!XShmAttach(dpy, &shmseginfo) || x_error) { char err[256]; XGetErrorText(dpy, x_error, err, 255); fprintf(stderr, "Warning: Can't attach shared memory to display: %s (%d)\n", err, x_error); shmdt(shmseginfo.shmaddr); shmctl(shmseginfo.shmid, IPC_RMID, NULL); goto generic; } #ifndef X_NOSHMPIX if(pixmaps && XShmPixmapFormat(dpy) == ZPixmap) { // Pixmaps vidtype = 2; vidstr = "X11 shared memory pixmap"; pixmap = XShmCreatePixmap(dpy, win, (char*)g_pImg, &shmseginfo, xsize, ysize, dispdepth); XSetWindowBackgroundPixmap(dpy, win, pixmap); } else #endif//!X_NOSHMPIX { // Standart vidtype = 1; vidstr = "X11 shared memory"; ximage = XShmCreateImage(dpy, vis, dispdepth, ZPixmap, 0, &shmseginfo, xsize, ysize); if(!ximage) { fprintf(stderr, "Can't create the shared image\n"); goto fail; } assert(ximage->bytes_per_line == xsize*(dispdepth<=16?2:4)); ximage->data = shmseginfo.shmaddr; } } else #endif { generic: vidtype = 0; vidstr = "generic X11"; g_pImg = new unsigned int[imgbytes/sizeof(int)]; ximage = XCreateImage(dpy, vis, dispdepth, ZPixmap, 0, (char*)g_pImg, xsize, ysize, 32, imgbytes/ysize); if(!ximage) { fprintf(stderr, "Can't create the image\n"); goto fail; } } printf("Note: using %s with %s visual for %d-bit color depth\n", vidstr, vis==DefaultVisual(dpy, theScreen)?"default":"non-default", dispdepth); running = true; return true; } // end of enclosing local varables fail: terminate(); init_console(); return false; }
GLboolean glewCreateContext (struct createParams *params) { int attrib[] = { GLX_RGBA, GLX_DOUBLEBUFFER, None }; int erb, evb; XSetWindowAttributes swa; /* open display */ dpy = XOpenDisplay(params->display); if (NULL == dpy) return GL_TRUE; /* query for glx */ if (!glXQueryExtension(dpy, &erb, &evb)) return GL_TRUE; /* choose visual */ if (params->visual == -1) { vi = glXChooseVisual(dpy, DefaultScreen(dpy), attrib); if (NULL == vi) return GL_TRUE; params->visual = (int)XVisualIDFromVisual(vi->visual); } else { int n_vis, i; vis = XGetVisualInfo(dpy, 0, NULL, &n_vis); for (i=0; i<n_vis; i++) { if ((int)XVisualIDFromVisual(vis[i].visual) == params->visual) vi = &vis[i]; } if (vi == NULL) return GL_TRUE; } /* create context */ ctx = glXCreateContext(dpy, vi, None, True); if (NULL == ctx) return GL_TRUE; /* create window */ /*wnd = XCreateSimpleWindow(dpy, RootWindow(dpy, vi->screen), 0, 0, 1, 1, 1, 0, 0);*/ cmap = XCreateColormap(dpy, RootWindow(dpy, vi->screen), vi->visual, AllocNone); swa.border_pixel = 0; swa.colormap = cmap; wnd = XCreateWindow(dpy, RootWindow(dpy, vi->screen), 0, 0, 1, 1, 0, vi->depth, InputOutput, vi->visual, CWBorderPixel | CWColormap, &swa); /* make context current */ if (!glXMakeCurrent(dpy, wnd, ctx)) return GL_TRUE; if (params->major || params->profile || params->flags) { GLXContext oldCtx = ctx; GLXFBConfig *FBConfigs; int FBConfigAttrs[] = { GLX_FBCONFIG_ID, 0, None }; int contextAttrs[20]; int nelems, i; glxewInit(); if (!glxewGetExtension("GLX_ARB_create_context")) return GL_TRUE; if (glXQueryContext(dpy, oldCtx, GLX_FBCONFIG_ID, &FBConfigAttrs[1])) return GL_TRUE; FBConfigs = glXChooseFBConfig(dpy, vi->screen, FBConfigAttrs, &nelems); if (nelems < 1) return GL_TRUE; i = 0; if (params->major) { contextAttrs[i++] = GLX_CONTEXT_MAJOR_VERSION_ARB; contextAttrs[i++] = params->major; contextAttrs[i++] = GLX_CONTEXT_MINOR_VERSION_ARB; contextAttrs[i++] = params->minor; } if (params->profile) { contextAttrs[i++] = GLX_CONTEXT_PROFILE_MASK_ARB; contextAttrs[i++] = params->profile; } if (params->flags) { contextAttrs[i++] = GLX_CONTEXT_FLAGS_ARB; contextAttrs[i++] = params->flags; } contextAttrs[i++] = None; ctx = glXCreateContextAttribsARB(dpy, *FBConfigs, NULL, True, contextAttrs); if (NULL == ctx) return GL_TRUE; if (!glXMakeCurrent(dpy, wnd, ctx)) return GL_TRUE; glXDestroyContext(dpy, oldCtx); XFree(FBConfigs); } return GL_FALSE; }
// NOTE: The X11 version of createSurface will re-create the native drawable if it's visual doesn't // match the one for the passed in EGLConfig EGLSurface QEgl::createSurface(QPaintDevice *device, EGLConfig config, const QEglProperties *unusedProperties) { Q_UNUSED(unusedProperties); int devType = device->devType(); if (devType == QInternal::Pbuffer) { // TODO return EGL_NO_SURFACE; } QX11PixmapData *x11PixmapData = 0; if (devType == QInternal::Pixmap) { QPixmapData *pmd = static_cast<QPixmap*>(device)->data_ptr().data(); if (pmd->classId() == QPixmapData::X11Class) x11PixmapData = static_cast<QX11PixmapData*>(pmd); else { // TODO: Replace the pixmap's data with a new QX11PixmapData qWarning("WARNING: Creating an EGL surface on a QPixmap is only supported for QX11PixmapData"); return EGL_NO_SURFACE; } } else if ((devType != QInternal::Widget) && (devType != QInternal::Pbuffer)) { qWarning("WARNING: Creating an EGLSurface for device type %d isn't supported", devType); return EGL_NO_SURFACE; } VisualID visualId = QEgl::getCompatibleVisualId(config); EGLint alphaSize; eglGetConfigAttrib(QEgl::display(), config, EGL_ALPHA_SIZE, &alphaSize); if (devType == QInternal::Widget) { QWidget *widget = static_cast<QWidget*>(device); VisualID currentVisualId = 0; if (widget->testAttribute(Qt::WA_WState_Created)) currentVisualId = XVisualIDFromVisual((Visual*)widget->x11Info().visual()); if (currentVisualId != visualId) { // The window is either not created or has the wrong visual. Either way, we need // to create a window with the correct visual and call create() on the widget: bool visible = widget->isVisible(); if (visible) widget->hide(); XVisualInfo visualInfo; visualInfo.visualid = visualId; { XVisualInfo *visualInfoPtr; int matchingCount = 0; visualInfoPtr = XGetVisualInfo(widget->x11Info().display(), VisualIDMask, &visualInfo, &matchingCount); Q_ASSERT(visualInfoPtr); // visualId really should be valid! visualInfo = *visualInfoPtr; XFree(visualInfoPtr); } Window parentWindow = RootWindow(widget->x11Info().display(), widget->x11Info().screen()); if (widget->parentWidget()) parentWindow = widget->parentWidget()->winId(); XSetWindowAttributes windowAttribs; QColormap colmap = QColormap::instance(widget->x11Info().screen()); windowAttribs.background_pixel = colmap.pixel(widget->palette().color(widget->backgroundRole())); windowAttribs.border_pixel = colmap.pixel(Qt::black); unsigned int valueMask = CWBackPixel|CWBorderPixel; if (alphaSize > 0) { windowAttribs.colormap = XCreateColormap(widget->x11Info().display(), parentWindow, visualInfo.visual, AllocNone); valueMask |= CWColormap; } Window window = XCreateWindow(widget->x11Info().display(), parentWindow, widget->x(), widget->y(), widget->width(), widget->height(), 0, visualInfo.depth, InputOutput, visualInfo.visual, valueMask, &windowAttribs); // This is a nasty hack to get round the fact that we can't be a friend of QWidget: qt_set_winid_on_widget(widget, window); if (visible) widget->show(); } // At this point, the widget's window should be created and have the correct visual. Now we // just need to create the EGL surface for it: EGLSurface surf = eglCreateWindowSurface(QEgl::display(), config, (EGLNativeWindowType)widget->winId(), 0); if (surf == EGL_NO_SURFACE) qWarning("QEglContext::createSurface(): Unable to create EGL surface, error = 0x%x", eglGetError()); return surf; } if (x11PixmapData) { // X11 Pixmaps are only created with a depth, so that's all we need to check EGLint configDepth; eglGetConfigAttrib(QEgl::display(), config, EGL_BUFFER_SIZE , &configDepth); if (x11PixmapData->depth() != configDepth) { // The bit depths are wrong which means the EGLConfig isn't compatable with // this pixmap. So we need to replace the pixmap's existing data with a new // one which is created with the correct depth: #ifndef QT_NO_XRENDER if (configDepth == 32) { qWarning("Warning: EGLConfig's depth (32) != pixmap's depth (%d), converting to ARGB32", x11PixmapData->depth()); x11PixmapData->convertToARGB32(true); } else #endif { qWarning("Warning: EGLConfig's depth (%d) != pixmap's depth (%d)", configDepth, x11PixmapData->depth()); } } QEglProperties surfaceAttribs; // If the pixmap can't be bound to a texture, it's pretty useless surfaceAttribs.setValue(EGL_TEXTURE_TARGET, EGL_TEXTURE_2D); if (alphaSize > 0) surfaceAttribs.setValue(EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA); else surfaceAttribs.setValue(EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGB); EGLSurface surf = eglCreatePixmapSurface(QEgl::display(), config, (EGLNativePixmapType) x11PixmapData->handle(), surfaceAttribs.properties()); x11PixmapData->gl_surface = (void*)surf; QImagePixmapCleanupHooks::enableCleanupHooks(x11PixmapData); return surf; } return EGL_NO_SURFACE; }
// FIXME: Siempre trabajamos en 16 bits bool Window::Open(char *Title, int x, int y, int Width, int Height, int Depth, bool FullScreen) { XSetWindowAttributes attr; XVisualInfo *vi; Colormap cmap; int dpyWidth, dpyHeight; int i; XF86VidModeModeInfo **modes; int modeNum; int bestMode; Atom wmDelete; ::Window winDummy; unsigned int borderDummy; // Atributos para el "single buffer" int attrListSgl[]={GLX_RGBA, GLX_RED_SIZE, 4, GLX_GREEN_SIZE, 4, GLX_BLUE_SIZE, 4, GLX_DEPTH_SIZE, 16, None}; // Atributos para "double buffer" int attrListDbl[]={GLX_RGBA, GLX_DOUBLEBUFFER, GLX_RED_SIZE, 4, GLX_GREEN_SIZE, 4, GLX_BLUE_SIZE, 4, GLX_DEPTH_SIZE, 16, None}; // FIXME: A piñón... prefiero trabajar en ventana. this->fs=false; //this->fs = FullScreen; // Mejor modo el actual bestMode=0; // Conectar al servidor this->dpy = XOpenDisplay(0); this->screen = DefaultScreen(this->dpy); // Escoger la visual vi = glXChooseVisual(this->dpy, this->screen, attrListDbl); // No hay doble buffer if (vi==NULL) vi= glXChooseVisual(this->dpy, this->screen, attrListSgl); // Crear un contexto glx this->ctx = glXCreateContext(this->dpy, vi, 0, GL_TRUE); cmap = XCreateColormap(this->dpy, RootWindow(this->dpy, vi->screen), vi->visual, AllocNone); attr.colormap = cmap; attr.border_pixel= 0; if (this->fs) { XF86VidModeGetAllModeLines(this->dpy, this->screen, &modeNum, &modes); // Guardamos la resoluci para luego restablecerla this->deskMode = *modes[0]; // Buscamos un modo con la resolucion adecuada for (i=0; i<modeNum; i++) { if((modes[i]->hdisplay==Width) && (modes[i]->vdisplay==Height)) { bestMode = i; } } XF86VidModeSwitchToMode(this->dpy, this->screen, modes[bestMode]); XF86VidModeSetViewPort(this->dpy, this->screen, 0 ,0); dpyWidth = modes[bestMode]->hdisplay; dpyHeight = modes[bestMode]->vdisplay; XFree(modes); // Creamos la ventana attr.override_redirect=True; // La mascara de eventos a recibir. Todavia faltan unos cuantos (movimiento del raton, etc) attr.event_mask= ExposureMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | StructureNotifyMask | FocusChangeMask | PointerMotionMask; this->win = XCreateWindow(this->dpy, RootWindow(this->dpy, vi->screen), 0, 0, dpyWidth, dpyHeight, 0, vi->depth, InputOutput, vi->visual, CWBorderPixel | CWColormap | CWEventMask | CWOverrideRedirect, &attr); XWarpPointer(this->dpy, None, this->win, 0,0,0,0,0,0); XMapRaised(this->dpy, this->win); XGrabKeyboard(this->dpy, this->win, True, GrabModeAsync, GrabModeAsync, CurrentTime); XGrabPointer(this->dpy, this->win, True, ButtonPressMask, GrabModeAsync, GrabModeAsync, this->win, None, CurrentTime); } else { attr.event_mask = ExposureMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | StructureNotifyMask | FocusChangeMask | PointerMotionMask; this->win = XCreateWindow(this->dpy, RootWindow(this->dpy, vi->screen), 0, 0, Width, Height, 0, vi->depth, InputOutput, vi->visual, CWBorderPixel | CWColormap | CWEventMask, &attr); wmDelete = XInternAtom(this->dpy, "WM_DELETE_WINDOW", True); XSetWMProtocols(this->dpy, this->win, &wmDelete, 1); XSetStandardProperties(this->dpy, this->win, Title, Title, None, NULL, 0, NULL); XMapRaised(this->dpy, this->win); // Colocamos el ratón en la ventana XGrabPointer(this->dpy, this->win, true, 0, GrabModeAsync, GrabModeAsync, this->win, None, CurrentTime); } // Situamos el ratón en el centro de la ventana XWarpPointer(this->dpy, None, this->win, 0, 0, 0, 0, this->width/2, this->height/2); // Ocultamos el puntero del ratón glXMakeCurrent(this->dpy, this->win, this->ctx); XGetGeometry(this->dpy, this->win, &winDummy, &this->x, &this->y, &this->width, &this->height, &borderDummy, &this->depth); Drawing3D::Instance().Init();//InitGL(); return true; };
/* * Opens a window. Requires a SFG_Window object created and attached * to the freeglut structure. OpenGL context is created here. */ void fgOpenWindow( SFG_Window* window, const char* title, int x, int y, int w, int h, GLboolean gameMode, GLboolean isSubWindow ) { #if TARGET_HOST_UNIX_X11 XSetWindowAttributes winAttr; XTextProperty textProperty; XSizeHints sizeHints; XWMHints wmHints; unsigned long mask; freeglut_assert_ready; /* * XXX fgChooseVisual() is a common part of all three. * XXX With a little thought, we should be able to greatly * XXX simplify this. */ if( !window->IsMenu ) window->Window.VisualInfo = fgChooseVisual( ); else if( fgStructure.MenuContext ) window->Window.VisualInfo = fgChooseVisual( ); else { /* XXX Why are menus double- and depth-buffered? */ unsigned int current_DisplayMode = fgState.DisplayMode ; fgState.DisplayMode = GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH ; window->Window.VisualInfo = fgChooseVisual( ); fgState.DisplayMode = current_DisplayMode ; } if( ! window->Window.VisualInfo ) { /* * The "fgChooseVisual" returned a null meaning that the visual * context is not available. * Try a couple of variations to see if they will work. */ if( !( fgState.DisplayMode & GLUT_DOUBLE ) ) { fgState.DisplayMode |= GLUT_DOUBLE ; window->Window.VisualInfo = fgChooseVisual( ); fgState.DisplayMode &= ~GLUT_DOUBLE; } /* * GLUT also checks for multi-sampling, but I don't see that * anywhere else in FREEGLUT so I won't bother with it for the moment. */ } /* * XXX This seems to be abusing an assert() for error-checking. * XXX It is possible that the visual simply can't be found, * XXX in which case we should print an error and return a 0 * XXX for the window id, I think. */ assert( window->Window.VisualInfo != NULL ); /* * XXX HINT: the masks should be updated when adding/removing callbacks. * XXX This might speed up message processing. Is that true? * XXX * XXX A: Not appreciably, but it WILL make it easier to debug. * XXX Try tracing old GLUT and try tracing freeglut. Old GLUT * XXX turns off events that it doesn't need and is a whole lot * XXX more pleasant to trace. (Think mouse-motion! Tons of * XXX ``bonus'' GUI events stream in.) */ winAttr.event_mask = StructureNotifyMask | SubstructureNotifyMask | ExposureMask | ButtonPressMask | ButtonReleaseMask | KeyPressMask | KeyRelease | VisibilityChangeMask | EnterWindowMask | LeaveWindowMask | PointerMotionMask | ButtonMotionMask; winAttr.background_pixmap = None; winAttr.background_pixel = 0; winAttr.border_pixel = 0; winAttr.colormap = XCreateColormap( fgDisplay.Display, fgDisplay.RootWindow, window->Window.VisualInfo->visual, AllocNone ); mask = CWBackPixmap | CWBorderPixel | CWColormap | CWEventMask; if( window->IsMenu ) { winAttr.override_redirect = True; mask |= CWOverrideRedirect; } window->Window.Handle = XCreateWindow( fgDisplay.Display, window->Parent == NULL ? fgDisplay.RootWindow : window->Parent->Window.Handle, x, y, w, h, 0, window->Window.VisualInfo->depth, InputOutput, window->Window.VisualInfo->visual, mask, &winAttr ); /* * The GLX context creation, possibly trying the direct context rendering * or else use the current context if the user has so specified */ if( window->IsMenu ) { /* * If there isn't already an OpenGL rendering context for menu * windows, make one */ if( !fgStructure.MenuContext ) { fgStructure.MenuContext = (SFG_MenuContext *)malloc( sizeof(SFG_MenuContext) ); fgStructure.MenuContext->VisualInfo = window->Window.VisualInfo; fgStructure.MenuContext->Context = glXCreateContext( fgDisplay.Display, fgStructure.MenuContext->VisualInfo, NULL, ( fgState.DirectContext != GLUT_FORCE_INDIRECT_CONTEXT ) ); } /* window->Window.Context = fgStructure.MenuContext->Context; */ window->Window.Context = glXCreateContext( fgDisplay.Display, window->Window.VisualInfo, NULL, ( fgState.DirectContext != GLUT_FORCE_INDIRECT_CONTEXT ) ); } else if( fgState.UseCurrentContext ) { window->Window.Context = glXGetCurrentContext( ); if( ! window->Window.Context ) window->Window.Context = glXCreateContext( fgDisplay.Display, window->Window.VisualInfo, NULL, ( fgState.DirectContext != GLUT_FORCE_INDIRECT_CONTEXT ) ); } else window->Window.Context = glXCreateContext( fgDisplay.Display, window->Window.VisualInfo, NULL, ( fgState.DirectContext != GLUT_FORCE_INDIRECT_CONTEXT ) ); if( !glXIsDirect( fgDisplay.Display, window->Window.Context ) ) { if( fgState.DirectContext == GLUT_FORCE_DIRECT_CONTEXT ) fgError( "Unable to force direct context rendering for window '%s'", title ); else if( fgState.DirectContext == GLUT_TRY_DIRECT_CONTEXT ) fgWarning( "Unable to create direct context rendering for window '%s'\nThis may hurt performance.", title ); } glXMakeCurrent( fgDisplay.Display, window->Window.Handle, window->Window.Context ); /* * XXX Assume the new window is visible by default * XXX Is this a safe assumption? */ window->State.Visible = GL_TRUE; sizeHints.flags = 0; if ( fgState.Position.Use ) sizeHints.flags |= USPosition; if ( fgState.Size.Use ) sizeHints.flags |= USSize; /* * Fill in the size hints values now (the x, y, width and height * settings are obsolote, are there any more WMs that support them?) * Unless the X servers actually stop supporting these, we should * continue to fill them in. It is *not* our place to tell the user * that they should replace a window manager that they like, and which * works, just because *we* think that it's not "modern" enough. */ #if TARGET_HOST_WINCE sizeHints.x = 0; sizeHints.y = 0; sizeHints.width = 320; sizeHints.height = 240; #else sizeHints.x = x; sizeHints.y = y; sizeHints.width = w; sizeHints.height = h; #endif /* TARGET_HOST_WINCE */ wmHints.flags = StateHint; wmHints.initial_state = fgState.ForceIconic ? IconicState : NormalState; /* * Prepare the window and iconified window names... */ XStringListToTextProperty( (char **) &title, 1, &textProperty ); XSetWMProperties( fgDisplay.Display, window->Window.Handle, &textProperty, &textProperty, 0, 0, &sizeHints, &wmHints, NULL ); XSetWMProtocols( fgDisplay.Display, window->Window.Handle, &fgDisplay.DeleteWindow, 1 ); XMapWindow( fgDisplay.Display, window->Window.Handle ); #elif TARGET_HOST_WIN32 || TARGET_HOST_WINCE WNDCLASS wc; DWORD flags; DWORD exFlags = 0; ATOM atom; freeglut_assert_ready; /* * Grab the window class we have registered on glutInit(): */ atom = GetClassInfo( fgDisplay.Instance, _T("FREEGLUT"), &wc ); assert( atom != 0 ); if( gameMode ) { assert( window->Parent == NULL ); /* * Set the window creation flags appropriately to make the window * entirely visible: */ flags = WS_POPUP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_VISIBLE; } else { #if !TARGET_HOST_WINCE if ( ( ! isSubWindow ) && ( ! window->IsMenu ) ) { /* * Update the window dimensions, taking account of window * decorations. "freeglut" is to create the window with the * outside of its border at (x,y) and with dimensions (w,h). */ w += (GetSystemMetrics( SM_CXSIZEFRAME ) )*2; h += (GetSystemMetrics( SM_CYSIZEFRAME ) )*2 + GetSystemMetrics( SM_CYCAPTION ); } #endif /* TARGET_HOST_WINCE */ if( ! fgState.Position.Use ) { x = CW_USEDEFAULT; y = CW_USEDEFAULT; } if( ! fgState.Size.Use ) { w = CW_USEDEFAULT; h = CW_USEDEFAULT; } /* * There's a small difference between creating the top, child and * game mode windows */ flags = WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_VISIBLE; if ( window->IsMenu ) { flags |= WS_POPUP; exFlags |= WS_EX_TOOLWINDOW; } #if !TARGET_HOST_WINCE else if( window->Parent == NULL ) flags |= WS_OVERLAPPEDWINDOW; #endif else flags |= WS_CHILD; } #if TARGET_HOST_WINCE { wchar_t* wstr = wstr_from_str(title); window->Window.Handle = CreateWindow( _T("FREEGLUT"), wstr, WS_VISIBLE | WS_POPUP, 0,0, 240,320, NULL, NULL, fgDisplay.Instance, (LPVOID) window ); free(wstr); SHFullScreen(window->Window.Handle, SHFS_HIDESTARTICON); SHFullScreen(window->Window.Handle, SHFS_HIDESIPBUTTON); SHFullScreen(window->Window.Handle, SHFS_HIDETASKBAR); MoveWindow(window->Window.Handle, 0, 0, 240, 320, TRUE); ShowWindow(window->Window.Handle, SW_SHOW); UpdateWindow(window->Window.Handle); } #else window->Window.Handle = CreateWindowEx( exFlags, "FREEGLUT", title, flags, x, y, w, h, (HWND) window->Parent == NULL ? NULL : window->Parent->Window.Handle, (HMENU) NULL, fgDisplay.Instance, (LPVOID) window ); #endif /* TARGET_HOST_WINCE */ if( !( window->Window.Handle ) ) fgError( "Failed to create a window (%s)!", title ); #if TARGET_HOST_WINCE ShowWindow( window->Window.Handle, SW_SHOW ); #else ShowWindow( window->Window.Handle, fgState.ForceIconic ? SW_SHOWMINIMIZED : SW_SHOW ); #endif /* TARGET_HOST_WINCE */ UpdateWindow( window->Window.Handle ); ShowCursor( TRUE ); /* XXX Old comments say "hide cusror"! */ #endif fgSetWindow( window ); window->Window.DoubleBuffered = ( fgState.DisplayMode & GLUT_DOUBLE ) ? 1 : 0; if ( ! window->Window.DoubleBuffered ) { glDrawBuffer ( GL_FRONT ); glReadBuffer ( GL_FRONT ); } }
static Q3ListViewItem *get_gl_info(Display *dpy, int scrnum, Bool allowDirect,Q3ListViewItem *l1, Q3ListViewItem *after) { Window win; int attribSingle[] = { GLX_RGBA, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1, None }; int attribDouble[] = { GLX_RGBA, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1, GLX_DOUBLEBUFFER, None }; XSetWindowAttributes attr; unsigned long mask; Window root; GLXContext ctx; XVisualInfo *visinfo; int width = 100, height = 100; Q3ListViewItem *result = after; root = RootWindow(dpy, scrnum); visinfo = glXChooseVisual(dpy, scrnum, attribSingle); if (!visinfo) { visinfo = glXChooseVisual(dpy, scrnum, attribDouble); if (!visinfo) { kDebug() << "Error: couldn't find RGB GLX visual\n"; return result; } } attr.background_pixel = 0; attr.border_pixel = 0; attr.colormap = XCreateColormap(dpy, root, visinfo->visual, AllocNone); attr.event_mask = StructureNotifyMask | ExposureMask; mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask; win = XCreateWindow(dpy, root, 0, 0, width, height, 0, visinfo->depth, InputOutput, visinfo->visual, mask, &attr); ctx = glXCreateContext( dpy, visinfo, NULL, allowDirect ); if (!ctx) { kDebug() << "Error: glXCreateContext failed\n"; XDestroyWindow(dpy, win); return result; } if (glXMakeCurrent(dpy, win, ctx)) { gli.serverVendor = glXQueryServerString(dpy, scrnum, GLX_VENDOR); gli.serverVersion = glXQueryServerString(dpy, scrnum, GLX_VERSION); gli.serverExtensions = glXQueryServerString(dpy, scrnum, GLX_EXTENSIONS); gli.clientVendor = glXGetClientString(dpy, GLX_VENDOR); gli.clientVersion = glXGetClientString(dpy, GLX_VERSION); gli.clientExtensions = glXGetClientString(dpy, GLX_EXTENSIONS); gli.glxExtensions = glXQueryExtensionsString(dpy, scrnum); gli.glVendor = (const char *) glGetString(GL_VENDOR); gli.glRenderer = (const char *) glGetString(GL_RENDERER); gli.glVersion = (const char *) glGetString(GL_VERSION); gli.glExtensions = (const char *) glGetString(GL_EXTENSIONS); gli.displayName = NULL; #ifdef KCMGL_DO_GLU gli.gluVersion = (const char *) gluGetString(GLU_VERSION); gli.gluExtensions = (const char *) gluGetString(GLU_EXTENSIONS); #endif IsDirect = glXIsDirect(dpy, ctx); result = print_screen_info(l1, after); } else { kDebug() << "Error: glXMakeCurrent failed\n"; glXDestroyContext(dpy, ctx); } glXDestroyContext(dpy, ctx); XDestroyWindow(dpy, win); return result; }
bool CWindowUnix::Init(int width, int height, int bpp, axelynx::WindowMode wm, int samples) { XVisualInfo *vi; Colormap cmap; XSetWindowAttributes swa; int dummy; width_ = width; height_ = height; /*** (1) open a connection to the X server ***/ dpy_ = XOpenDisplay(NULL); if (dpy_ == NULL) fatalError("could not open display"); int nelements; GLXFBConfig *fbc = glXChooseFBConfig(dpy_, DefaultScreen(dpy_), 0, &nelements); /*** (2) make sure OpenGL's GLX extension supported ***/ if(!glXQueryExtension(dpy_, &dummy, &dummy)) fatalError("X server has no OpenGL GLX extension"); /*** (3) find an appropriate visual ***/ /* find an OpenGL-capable RGB visual with depth buffer */ vi = glXChooseVisual(dpy_, DefaultScreen(dpy_), dblBuf); if (vi == NULL) { vi = glXChooseVisual(dpy_, DefaultScreen(dpy_), snglBuf); if (vi == NULL) fatalError("no RGB visual with depth buffer"); doubleBuffer_ = GL_FALSE; } //if(vi->class != TrueColor) // fatalError("TrueColor visual required for this program"); /*** (4) create an OpenGL rendering context ***/ /* create an OpenGL rendering context */ // cx_ = glXCreateContext(dpy_, vi, /* no shared dlists */ None, /* direct rendering if possible */ GL_TRUE); /*** (5) create an X window with the selected visual ***/ /* create an X colormap since probably not using default visual */ cmap = XCreateColormap(dpy_, RootWindow(dpy_, vi->screen), vi->visual, AllocNone); swa.colormap = cmap; swa.border_pixel = 0; swa.event_mask = KeyPressMask | ExposureMask | ButtonPressMask | StructureNotifyMask | FocusChangeMask; win_ = XCreateWindow(dpy_, RootWindow(dpy_, vi->screen), 0, 0, width_, height_, 0, vi->depth, InputOutput, vi->visual, CWBorderPixel | CWColormap | CWEventMask, &swa); XSetStandardProperties(dpy_, win_, "main", "main", None, 0, 0, NULL); PFNGLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribsARB = (PFNGLXCREATECONTEXTATTRIBSARBPROC) glXGetProcAddress((const GLubyte*)"glXCreateContextAttribsARB"); int attribs[] = { GLX_CONTEXT_MAJOR_VERSION_ARB, 3, GLX_CONTEXT_MINOR_VERSION_ARB, 3, 0}; cx_ = glXCreateContextAttribsARB(dpy_, *fbc, 0, true, attribs); //glXMakeCurrent (dpy, win, ctx); /*** (6) bind the rendering context to the window ***/ glXMakeCurrent(dpy_, win_, cx_); /*** (7) request the X window to be displayed on the screen ***/ XMapWindow(dpy_, win_); /*** (8) configure the OpenGL context for rendering ***/ glEnable(GL_DEPTH_TEST); /* enable depth buffering */ glDepthFunc(GL_LESS); /* pedantic, GL_LESS is the default */ glClearDepth(1.0); /* pedantic, 1.0 is the default */ /* frame buffer clears should be to black */ glClearColor(0.0, 0.0, 0.0, 0.0); /* set up projection transform */ /* establish initial viewport */ /* pedantic, full window size is default viewport */ isFullscreen_ = false; Resize(width,height,wm); fprintf(stderr, "succers: %d\n", width); return true; }
void X11_Init (void) { int attributes[] = { GLX_RGBA, GLX_RED_SIZE, 8, GLX_GREEN_SIZE, 8, GLX_BLUE_SIZE, 8, GLX_DOUBLEBUFFER, None }; Colormap color_map; XSetWindowAttributes attr; XEvent event; char* p; XInitThreads (); X11_display = XOpenDisplay (0); if (!X11_display) { const char* displayName = getenv ("DISPLAY"); errx (EXIT_FAILURE, "Failed to open X11_display %s", displayName ? displayName : ":0"); } XSynchronize (X11_display, True); if (!glXQueryExtension (X11_display, 0, 0)) errx (EXIT_FAILURE, "No GLX extension present"); if (!(X11_visual = glXChooseVisual (X11_display, DefaultScreen (X11_display), attributes))) errx (EXIT_FAILURE, "glXChooseVisual failed"); if (!(X11_glxContext = glXCreateContext (X11_display, X11_visual, 0, GL_TRUE))) errx (EXIT_FAILURE, "Failed creating OpenGL context"); color_map = XCreateColormap (X11_display, RootWindow (X11_display, X11_visual->screen), X11_visual->visual, AllocNone); attr.colormap = color_map; attr.border_pixel = 0; attr.event_mask = KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask | StructureNotifyMask | ExposureMask | FocusChangeMask; X11_window = XCreateWindow (X11_display, RootWindow (X11_display, X11_visual->screen), 0, 0, X11_window_width, X11_window_height, 0, X11_visual->depth, InputOutput, X11_visual->visual, CWBorderPixel | CWColormap | CWEventMask, &attr); XMapRaised (X11_display, X11_window); if ((p = XSetLocaleModifiers ("")) && *p) X11_xim = XOpenIM (X11_display, 0, 0, 0); if (!X11_xim && (p = XSetLocaleModifiers ("@im=none")) && *p) X11_xim = XOpenIM (X11_display, 0, 0, 0); if (!X11_xim) errx (EXIT_FAILURE, "Failed to open X Input Method"); X11_xic = XCreateIC (X11_xim, XNInputStyle, XIMPreeditNothing | XIMStatusNothing, XNClientWindow, X11_window, XNFocusWindow, X11_window, NULL); if (!X11_xic) errx (EXIT_FAILURE, "Failed to create X Input Context"); while (!x11_gotMapNotify) { XEvent event; XNextEvent (X11_display, &event); x11_ProcessEvent (&event); } if (!glXMakeCurrent (X11_display, X11_window, X11_glxContext)) errx (EXIT_FAILURE, "glXMakeCurrent returned false"); glewInit (); X11_xa_wm_delete_window = XInternAtom (X11_display, "WM_DELETE_WINDOW", False); XSynchronize (X11_display, False); }
int main(int argc, char** argv) { int attrib[] = { GLX_RENDER_TYPE, GLX_RGBA_BIT, GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT, GLX_DOUBLEBUFFER, True, GLX_RED_SIZE, 8, GLX_GREEN_SIZE, 8, GLX_BLUE_SIZE, 8, GLX_ALPHA_SIZE, 8, GLX_DEPTH_SIZE, 24, None }; PlatformContext context; context.MainDisplay = XOpenDisplay(NULL); int screenIndex = DefaultScreen(context.MainDisplay); Window root = RootWindow(context.MainDisplay, screenIndex); int fbcount; PFNGLXCHOOSEFBCONFIGPROC glXChooseFBConfig = (PFNGLXCHOOSEFBCONFIGPROC)glXGetProcAddress((GLubyte*)"glXChooseFBConfig"); GLXFBConfig *fbc = glXChooseFBConfig(context.MainDisplay, screenIndex, attrib, &fbcount); if (!fbc) pezFatal("Failed to retrieve a framebuffer config\n"); PFNGLXGETVISUALFROMFBCONFIGPROC glXGetVisualFromFBConfig = (PFNGLXGETVISUALFROMFBCONFIGPROC) glXGetProcAddress((GLubyte*)"glXGetVisualFromFBConfig"); if (!glXGetVisualFromFBConfig) pezFatal("Failed to get a GLX function pointer\n"); PFNGLXGETFBCONFIGATTRIBPROC glXGetFBConfigAttrib = (PFNGLXGETFBCONFIGATTRIBPROC) glXGetProcAddress((GLubyte*)"glXGetFBConfigAttrib"); if (!glXGetFBConfigAttrib) pezFatal("Failed to get a GLX function pointer\n"); if (PezGetConfig().Multisampling) { int best_fbc = -1, worst_fbc = -1, best_num_samp = -1, worst_num_samp = 999; for ( int i = 0; i < fbcount; i++ ) { XVisualInfo *vi = glXGetVisualFromFBConfig( context.MainDisplay, fbc[i] ); if (!vi) { continue; } int samp_buf, samples; glXGetFBConfigAttrib( context.MainDisplay, fbc[i], GLX_SAMPLE_BUFFERS, &samp_buf ); glXGetFBConfigAttrib( context.MainDisplay, fbc[i], GLX_SAMPLES , &samples ); //printf( " Matching fbconfig %d, visual ID 0x%2x: SAMPLE_BUFFERS = %d," // " SAMPLES = %d\n", // i, (unsigned int) vi->visualid, samp_buf, samples ); if ( best_fbc < 0 || (samp_buf && samples > best_num_samp) ) best_fbc = i, best_num_samp = samples; if ( worst_fbc < 0 || !samp_buf || samples < worst_num_samp ) worst_fbc = i, worst_num_samp = samples; XFree( vi ); } fbc[0] = fbc[ best_fbc ]; } XVisualInfo *visinfo = glXGetVisualFromFBConfig(context.MainDisplay, fbc[0]); if (!visinfo) pezFatal("Error: couldn't create OpenGL window with this pixel format.\n"); XSetWindowAttributes attr; attr.background_pixel = 0; attr.border_pixel = 0; attr.colormap = XCreateColormap(context.MainDisplay, root, visinfo->visual, AllocNone); attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask | KeyReleaseMask | PointerMotionMask | ButtonPressMask | ButtonReleaseMask; context.MainWindow = XCreateWindow( context.MainDisplay, root, 0, 0, PezGetConfig().Width, PezGetConfig().Height, 0, visinfo->depth, InputOutput, visinfo->visual, CWBackPixel | /*CWBorderPixel |*/ CWColormap | CWEventMask, &attr ); int borderless = 1; if (borderless) { Atom mwmHintsProperty = XInternAtom(context.MainDisplay, "_MOTIF_WM_HINTS", 0); MwmHints hints = {0}; hints.flags = MWM_HINTS_DECORATIONS; hints.decorations = 0; XChangeProperty(context.MainDisplay, context.MainWindow, mwmHintsProperty, mwmHintsProperty, 32, PropModeReplace, (unsigned char *)&hints, PROP_MWM_HINTS_ELEMENTS); } XMapWindow(context.MainDisplay, context.MainWindow); int centerWindow = 1; if (centerWindow) { Screen* pScreen = XScreenOfDisplay(context.MainDisplay, screenIndex); int left = XWidthOfScreen(pScreen)/2 - PezGetConfig().Width/2; int top = XHeightOfScreen(pScreen)/2 - PezGetConfig().Height/2; XMoveWindow(context.MainDisplay, context.MainWindow, left, top); } GLXContext glcontext = 0; if (PEZ_FORWARD_COMPATIBLE_GL) { PFNGLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribs = (PFNGLXCREATECONTEXTATTRIBSARBPROC)glXGetProcAddress((GLubyte*)"glXCreateContextAttribsARB"); if (!glXCreateContextAttribs) { pezFatal("Your platform does not support OpenGL 4.0.\n" "Try changing PEZ_FORWARD_COMPATIBLE_GL to 0.\n"); } int attribs[] = { GLX_CONTEXT_MAJOR_VERSION_ARB, 4, GLX_CONTEXT_MINOR_VERSION_ARB, 0, GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB, GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB, 0 }; glcontext = glXCreateContextAttribs(context.MainDisplay, fbc[0], NULL, True, attribs); } else { glcontext = glXCreateContext(context.MainDisplay, visinfo, NULL, True); } glXMakeCurrent(context.MainDisplay, context.MainWindow, glcontext); PFNGLXSWAPINTERVALSGIPROC glXSwapIntervalSGI = (PFNGLXSWAPINTERVALSGIPROC) glXGetProcAddress((GLubyte*)"glXSwapIntervalSGI"); if (glXSwapIntervalSGI) { glXSwapIntervalSGI(PezGetConfig().VerticalSync ? 1 : 0); } /* GLenum err = glewInit(); if (GLEW_OK != err) pezFatal("GLEW Error: %s\n", glewGetErrorString(err)); // Work around some GLEW issues: #define glewGetProcAddress(name) (*glXGetProcAddressARB)(name) glPatchParameteri = (PFNGLPATCHPARAMETERIPROC)glewGetProcAddress((const GLubyte*)"glPatchParameteri"); glBindVertexArray = (PFNGLBINDVERTEXARRAYPROC)glewGetProcAddress((const GLubyte*)"glBindVertexArray"); glDeleteVertexArrays = (PFNGLDELETEVERTEXARRAYSPROC)glewGetProcAddress((const GLubyte*)"glDeleteVertexArrays"); glGenVertexArrays = (PFNGLGENVERTEXARRAYSPROC)glewGetProcAddress((const GLubyte*)"glGenVertexArrays"); glIsVertexArray = (PFNGLISVERTEXARRAYPROC)glewGetProcAddress((const GLubyte*)"glIsVertexArray"); */ // Reset OpenGL error state: glGetError(); // Lop off the trailing .c bstring name = bfromcstr(PezGetConfig().Title); bstring shaderPrefix = bmidstr(name, 0, blength(name) - 1); pezSwInit(bdata(shaderPrefix)); bdestroy(shaderPrefix); // Set up the Shader Wrangler pezSwAddPath("./", ".glsl"); pezSwAddPath("../", ".glsl"); char qualifiedPath[128]; strcpy(qualifiedPath, pezResourcePath()); strcat(qualifiedPath, "/"); pezSwAddPath(qualifiedPath, ".glsl"); pezSwAddDirective("*", "#version 420"); // Perform user-specified intialization pezPrintString("OpenGL Version: %s\n", glGetString(GL_VERSION)); PezInitialize(); bstring windowTitle = bmidstr(name, 5, blength(name) - 7); XStoreName(context.MainDisplay, context.MainWindow, bdata(windowTitle)); bdestroy(windowTitle); bdestroy(name); // ------------------- // Start the Game Loop // ------------------- unsigned int previousTime = GetMicroseconds(); int done = 0; while (!done) { if (glGetError() != GL_NO_ERROR) pezFatal("OpenGL error.\n"); if (XPending(context.MainDisplay)) { XEvent event; XNextEvent(context.MainDisplay, &event); switch (event.type) { case Expose: //redraw(display, event.xany.window); break; case ConfigureNotify: //resize(event.xconfigure.width, event.xconfigure.height); break; #ifdef PEZ_MOUSE_HANDLER case ButtonPress: PezHandleMouse(event.xbutton.x, event.xbutton.y, PEZ_DOWN); break; case ButtonRelease: PezHandleMouse(event.xbutton.x, event.xbutton.y, PEZ_UP); break; case MotionNotify: PezHandleMouse(event.xmotion.x, event.xmotion.y, PEZ_MOVE); break; #endif case KeyRelease: case KeyPress: { XComposeStatus composeStatus; char asciiCode[32]; KeySym keySym; int len; len = XLookupString(&event.xkey, asciiCode, sizeof(asciiCode), &keySym, &composeStatus); switch (asciiCode[0]) { case 'x': case 'X': case 'q': case 'Q': case 0x1b: done = 1; break; } } } } unsigned int currentTime = GetMicroseconds(); unsigned int deltaTime = currentTime - previousTime; previousTime = currentTime; PezUpdate((float) deltaTime / 1000000.0f); PezRender(0); glXSwapBuffers(context.MainDisplay, context.MainWindow); } pezSwShutdown(); return 0; }
//-------------------------------------------------------------------------------------------------// void GLXWindow::create(const String& name, uint width, uint height, bool fullScreen, const NameValuePairList *miscParams) { Display *xDisplay = mGLSupport->getXDisplay(); String title = name; uint samples = 0; short frequency = 0; bool vsync = false; bool hidden = false; unsigned int vsyncInterval = 1; int gamma = 0; ::GLXContext glxContext = 0; ::GLXDrawable glxDrawable = 0; Window externalWindow = 0; Window parentWindow = DefaultRootWindow(xDisplay); int left = DisplayWidth(xDisplay, DefaultScreen(xDisplay))/2 - width/2; int top = DisplayHeight(xDisplay, DefaultScreen(xDisplay))/2 - height/2; String border; mIsFullScreen = fullScreen; if(miscParams) { NameValuePairList::const_iterator opt; NameValuePairList::const_iterator end = miscParams->end(); // NB: Do not try to implement the externalGLContext option. // // Accepting a non-current context would expose us to the // risk of segfaults when we made it current. Since the // application programmers would be responsible for these // segfaults, they are better discovering them in their code. if ((opt = miscParams->find("currentGLContext")) != end && StringConverter::parseBool(opt->second)) { if (! glXGetCurrentContext()) { OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "currentGLContext was specified with no current GL context", "GLXWindow::create"); } glxContext = glXGetCurrentContext(); glxDrawable = glXGetCurrentDrawable(); } // Note: Some platforms support AA inside ordinary windows if((opt = miscParams->find("FSAA")) != end) samples = StringConverter::parseUnsignedInt(opt->second); if((opt = miscParams->find("displayFrequency")) != end) frequency = (short)StringConverter::parseInt(opt->second); if((opt = miscParams->find("vsync")) != end) vsync = StringConverter::parseBool(opt->second); if((opt = miscParams->find("hidden")) != end) hidden = StringConverter::parseBool(opt->second); if((opt = miscParams->find("vsyncInterval")) != end) vsyncInterval = StringConverter::parseUnsignedInt(opt->second); if ((opt = miscParams->find("gamma")) != end) gamma = StringConverter::parseBool(opt->second); if((opt = miscParams->find("left")) != end) left = StringConverter::parseInt(opt->second); if((opt = miscParams->find("top")) != end) top = StringConverter::parseInt(opt->second); if((opt = miscParams->find("title")) != end) title = opt->second; if ((opt = miscParams->find("externalGLControl")) != end) mIsExternalGLControl = StringConverter::parseBool(opt->second); if((opt = miscParams->find("parentWindowHandle")) != end) { vector<String>::type tokens = StringUtil::split(opt->second, " :"); if (tokens.size() == 3) { // deprecated display:screen:xid format parentWindow = StringConverter::parseUnsignedLong(tokens[2]); } else { // xid format parentWindow = StringConverter::parseUnsignedLong(tokens[0]); } } else if((opt = miscParams->find("externalWindowHandle")) != end) { vector<String>::type tokens = StringUtil::split(opt->second, " :"); LogManager::getSingleton().logMessage( "GLXWindow::create: The externalWindowHandle parameter is deprecated.\n" "Use the parentWindowHandle or currentGLContext parameter instead."); if (tokens.size() == 3) { // Old display:screen:xid format // The old GLX code always created a "parent" window in this case: parentWindow = StringConverter::parseUnsignedLong(tokens[2]); } else if (tokens.size() == 4) { // Old display:screen:xid:visualinfo format externalWindow = StringConverter::parseUnsignedLong(tokens[2]); } else { // xid format externalWindow = StringConverter::parseUnsignedLong(tokens[0]); } } if ((opt = miscParams->find("border")) != end) border = opt->second; } // Ignore fatal XErrorEvents during parameter validation: oldXErrorHandler = XSetErrorHandler(safeXErrorHandler); // Validate parentWindowHandle if (parentWindow != DefaultRootWindow(xDisplay)) { XWindowAttributes windowAttrib; if (! XGetWindowAttributes(xDisplay, parentWindow, &windowAttrib) || windowAttrib.root != DefaultRootWindow(xDisplay)) { OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Invalid parentWindowHandle (wrong server or screen)", "GLXWindow::create"); } } // Validate externalWindowHandle if (externalWindow != 0) { XWindowAttributes windowAttrib; if (! XGetWindowAttributes(xDisplay, externalWindow, &windowAttrib) || windowAttrib.root != DefaultRootWindow(xDisplay)) { OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Invalid externalWindowHandle (wrong server or screen)", "GLXWindow::create"); } glxDrawable = externalWindow; } // Derive fbConfig ::GLXFBConfig fbConfig = 0; if (glxDrawable) { fbConfig = mGLSupport->getFBConfigFromDrawable (glxDrawable, &width, &height); } if (! fbConfig && glxContext) { fbConfig = mGLSupport->getFBConfigFromContext (glxContext); } mIsExternal = (glxDrawable != 0); XSetErrorHandler(oldXErrorHandler); if (! fbConfig) { int minAttribs[] = { GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT, GLX_RENDER_TYPE, GLX_RGBA_BIT, GLX_RED_SIZE, 1, GLX_BLUE_SIZE, 1, GLX_GREEN_SIZE, 1, None }; int maxAttribs[] = { GLX_SAMPLES, samples, GLX_DOUBLEBUFFER, 1, GLX_STENCIL_SIZE, INT_MAX, GLX_FRAMEBUFFER_SRGB_CAPABLE_EXT, 1, None }; fbConfig = mGLSupport->selectFBConfig(minAttribs, maxAttribs); if (gamma != 0) { mGLSupport->getFBConfigAttrib(fbConfig, GL_FRAMEBUFFER_SRGB_CAPABLE_EXT, &gamma); } mHwGamma = (gamma != 0); } if (! fbConfig) { // This should never happen. OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Unexpected failure to determine a GLXFBConfig","GLXWindow::create"); } mIsTopLevel = (! mIsExternal && parentWindow == DefaultRootWindow(xDisplay)); if (! mIsTopLevel) { mIsFullScreen = false; left = top = 0; } if (mIsFullScreen) { mGLSupport->switchMode (width, height, frequency); } if (! mIsExternal) { XSetWindowAttributes attr; ulong mask; XVisualInfo *visualInfo = mGLSupport->getVisualFromFBConfig (fbConfig); attr.background_pixel = 0; attr.border_pixel = 0; attr.colormap = XCreateColormap(xDisplay, DefaultRootWindow(xDisplay), visualInfo->visual, AllocNone); attr.event_mask = StructureNotifyMask | VisibilityChangeMask | FocusChangeMask; mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask; if(mIsFullScreen && mGLSupport->mAtomFullScreen == None) { LogManager::getSingleton().logMessage("GLXWindow::switchFullScreen: Your WM has no fullscreen support"); // A second best approach for outdated window managers attr.backing_store = NotUseful; attr.save_under = False; attr.override_redirect = True; mask |= CWSaveUnder | CWBackingStore | CWOverrideRedirect; left = top = 0; } // Create window on server mWindow = XCreateWindow(xDisplay, parentWindow, left, top, width, height, 0, visualInfo->depth, InputOutput, visualInfo->visual, mask, &attr); XFree(visualInfo); if(!mWindow) { OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Unable to create an X Window", "GLXWindow::create"); } if (mIsTopLevel) { XWMHints *wmHints; XSizeHints *sizeHints; if ((wmHints = XAllocWMHints()) != NULL) { wmHints->initial_state = NormalState; wmHints->input = True; wmHints->flags = StateHint | InputHint; int depth = DisplayPlanes(xDisplay, DefaultScreen(xDisplay)); // Check if we can give it an icon if(depth == 24 || depth == 32) { if(mGLSupport->loadIcon("GLX_icon.png", &wmHints->icon_pixmap, &wmHints->icon_mask)) { wmHints->flags |= IconPixmapHint | IconMaskHint; } } } if ((sizeHints = XAllocSizeHints()) != NULL) { // Is this really necessary ? Which broken WM might need it? sizeHints->flags = USPosition; if(!fullScreen && border == "fixed") { sizeHints->min_width = sizeHints->max_width = width; sizeHints->min_height = sizeHints->max_height = height; sizeHints->flags |= PMaxSize | PMinSize; } } XTextProperty titleprop; char *lst = (char*)title.c_str(); XStringListToTextProperty((char **)&lst, 1, &titleprop); XSetWMProperties(xDisplay, mWindow, &titleprop, NULL, NULL, 0, sizeHints, wmHints, NULL); XFree(titleprop.value); XFree(wmHints); XFree(sizeHints); XSetWMProtocols(xDisplay, mWindow, &mGLSupport->mAtomDeleteWindow, 1); XWindowAttributes windowAttrib; XGetWindowAttributes(xDisplay, mWindow, &windowAttrib); left = windowAttrib.x; top = windowAttrib.y; width = windowAttrib.width; height = windowAttrib.height; } glxDrawable = mWindow; // setHidden takes care of mapping or unmapping the window // and also calls setFullScreen if appropriate. setHidden(hidden); XFlush(xDisplay); WindowEventUtilities::_addRenderWindow(this); } mContext = new GLXContext(mGLSupport, fbConfig, glxDrawable, glxContext); // apply vsync settings. call setVSyncInterval first to avoid // setting vsync more than once. setVSyncInterval(vsyncInterval); setVSyncEnabled(vsync); int fbConfigID; mGLSupport->getFBConfigAttrib(fbConfig, GLX_FBCONFIG_ID, &fbConfigID); LogManager::getSingleton().logMessage("GLXWindow::create used FBConfigID = " + StringConverter::toString(fbConfigID)); mName = name; mWidth = width; mHeight = height; mLeft = left; mTop = top; mActive = true; mClosed = false; }
XID Window::_createGLXWindow( GLXFBConfig* fbConfig, const PixelViewport& pvp ) { LBASSERT( getIAttribute( IATTR_HINT_DRAWABLE ) != PBUFFER ); if( !_impl->xDisplay ) { sendError( ERROR_GLXWINDOW_NO_DISPLAY ); return 0; } if( !fbConfig ) { sendError( ERROR_SYSTEMWINDOW_NO_PIXELFORMAT ); return 0; } XVisualInfo* visInfo = GLXEW_VERSION_1_3 ? glXGetVisualFromFBConfig( _impl->xDisplay, fbConfig[0] ) : glXGetVisualFromFBConfigSGIX( _impl->xDisplay, fbConfig[0]); if( !visInfo ) { sendError( ERROR_GLXWINDOW_NO_VISUAL ); return 0; } const int screen = DefaultScreen( _impl->xDisplay ); XID parent = RootWindow( _impl->xDisplay, screen ); XSetWindowAttributes wa; wa.colormap = XCreateColormap( _impl->xDisplay, parent, visInfo->visual, AllocNone ); wa.background_pixmap = None; wa.border_pixel = 0; wa.event_mask = StructureNotifyMask | VisibilityChangeMask | ExposureMask | KeyPressMask | KeyReleaseMask | PointerMotionMask | ButtonPressMask | ButtonReleaseMask; switch( getIAttribute( IATTR_HINT_DECORATION )) { case ON: wa.override_redirect = False; break; case OFF: wa.override_redirect = True; break; case AUTO: default: wa.override_redirect = getIAttribute( IATTR_HINT_FULLSCREEN ) == ON ? True : False; break; } XID drawable = XCreateWindow( _impl->xDisplay, parent, pvp.x, pvp.y, pvp.w, pvp.h, 0, visInfo->depth, InputOutput, visInfo->visual, CWBackPixmap | CWBorderPixel | CWEventMask | CWColormap | CWOverrideRedirect, &wa ); XFree( visInfo ); if( !drawable ) { sendError( ERROR_GLXWINDOW_CREATEWINDOW_FAILED ); return 0; } std::stringstream windowTitle; const std::string& name = getName(); if( name.empty( )) { windowTitle << "Equalizer"; #ifndef NDEBUG windowTitle << " (" << getpid() << ")"; #endif } else windowTitle << name; XStoreName( _impl->xDisplay, drawable, windowTitle.str().c_str( )); // Register for close window request from the window manager Atom deleteAtom = XInternAtom( _impl->xDisplay, "WM_DELETE_WINDOW", False ); XSetWMProtocols( _impl->xDisplay, drawable, &deleteAtom, 1 ); return drawable; }
static void x11_init(void) { memset(keys, 0, KEYMAX); memset(mouse, 0, 3); display = XOpenDisplay(0); screen = DefaultScreen(display); xvis = glXChooseVisual(display, screen, xAttrList); if(!xvis) { printf("glXChooseVisual() failed.\n"); exit(1); } glx_context = glXCreateContext(display, xvis, 0, GL_TRUE); memset(&xwin_attr, 0, sizeof(XSetWindowAttributes)); xwin_attr.colormap = XCreateColormap(display, RootWindow(display, xvis->screen), xvis->visual, AllocNone); xwin_attr.event_mask = ExposureMask | StructureNotifyMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask | KeyPressMask | KeyReleaseMask; x11_window(); static char buf[] = { 0,0,0,0,0,0,0,0 }; XColor black = { .red=0, .green=0, .blue=0 }; Pixmap bitmap = XCreateBitmapFromData(display, window, buf, 2, 2); cursor_none = XCreatePixmapCursor(display, bitmap, bitmap, &black, &black, 0, 0); int event, error; if (!XQueryExtension(display, "XInputExtension", &opcode, &event, &error)) { printf("X Input extension not available.\n"); return; } #ifdef ASD /* Which version of XI2? We support 2.0 */ int major = 2, minor = 0; if (XIQueryVersion(display, &major, &minor) == BadRequest) { printf("XI2 not available. Server supports %d.%d\n", major, minor); return; } XIEventMask eventmask; unsigned char mask[3] = { 0,0,0 }; /* the actual mask */ eventmask.deviceid = XIAllDevices; eventmask.mask_len = sizeof(mask); /* always in bytes */ eventmask.mask = mask; /* now set the mask */ // XISetMask(mask, XI_ButtonPress); // XISetMask(mask, XI_ButtonRelease); XISetMask(mask, XI_RawMotion); // XISetMask(mask, XI_KeyPress); // mask = mask | KeyReleaseMask | KeyPressMask; /* select on the window */ Window root = DefaultRootWindow(display); XISelectEvents(display, root, &eventmask, 1); // XSetDeviceMode(display, mouse, Relative); #endif } void print_rawmotion(XIRawEvent *event) { int i; double *raw_valuator = event->raw_values, *valuator = event->valuators.values; for (i = 0; i < event->valuators.mask_len * 8; i++) { if (XIMaskIsSet(event->valuators.mask, i)) { switch(i) { case 0: mickey_x += *valuator; break; case 1: mickey_y += *valuator; break; default: break; } valuator++; raw_valuator++; } } }
/* * Class: jogamp_nativewindow_x11_X11Lib * Method: CreateDummyWindow * Signature: (JIIII)J */ JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_x11_X11Lib_CreateDummyWindow (JNIEnv *env, jclass unused, jlong display, jint screen_index, jint visualID, jint width, jint height) { Display * dpy = (Display *)(intptr_t)display; int scrn_idx = (int)screen_index; Window windowParent = 0; Window window = 0; XVisualInfo visualTemplate; XVisualInfo *pVisualQuery = NULL; Visual *visual = NULL; int depth; XSetWindowAttributes xswa; unsigned long attrMask; int n; Screen* scrn; if(NULL==dpy) { NativewindowCommon_FatalError(env, "invalid display connection.."); return 0; } if(visualID<0) { NativewindowCommon_throwNewRuntimeException(env, "invalid VisualID .."); return 0; } NativewindowCommon_x11ErrorHandlerEnable(env, dpy, 1, 0, 0); scrn = ScreenOfDisplay(dpy, scrn_idx); // try given VisualID on screen memset(&visualTemplate, 0, sizeof(XVisualInfo)); visualTemplate.screen = scrn_idx; visualTemplate.visualid = (VisualID)visualID; pVisualQuery = XGetVisualInfo(dpy, VisualIDMask|VisualScreenMask, &visualTemplate,&n); if(pVisualQuery!=NULL) { visual = pVisualQuery->visual; depth = pVisualQuery->depth; visualID = (jint)pVisualQuery->visualid; XFree(pVisualQuery); pVisualQuery=NULL; } DBG_PRINT( "X11: [CreateWindow] trying given (dpy %p, screen %d, visualID: %d, parent %p) found: %p\n", dpy, scrn_idx, (int)visualID, windowParent, visual); if (visual==NULL) { NativewindowCommon_x11ErrorHandlerEnable(env, dpy, 0, 0, 1); NativewindowCommon_throwNewRuntimeException(env, "could not query Visual by given VisualID, bail out!"); return 0; } if(pVisualQuery!=NULL) { XFree(pVisualQuery); pVisualQuery=NULL; } if(0==windowParent) { windowParent = XRootWindowOfScreen(scrn); } attrMask = ( CWBackingStore | CWBackingPlanes | CWBackingPixel | CWBackPixmap | CWBorderPixel | CWColormap | CWOverrideRedirect ) ; memset(&xswa, 0, sizeof(xswa)); xswa.override_redirect = False; // use the window manager, always xswa.border_pixel = 0; xswa.background_pixmap = None; xswa.backing_store=NotUseful; /* NotUseful, WhenMapped, Always */ xswa.backing_planes=0; /* planes to be preserved if possible */ xswa.backing_pixel=0; /* value to use in restoring planes */ xswa.colormap = XCreateColormap(dpy, XRootWindow(dpy, scrn_idx), visual, AllocNone); window = XCreateWindow(dpy, windowParent, 0, 0, width, height, 0, // border width depth, InputOutput, visual, attrMask, &xswa); XSync(dpy, False); XSelectInput(dpy, window, 0); // no events NativewindowCommon_x11ErrorHandlerEnable(env, dpy, 0, 0, 1); DBG_PRINT( "X11: [CreateWindow] created window %p on display %p\n", window, dpy); return (jlong) window; }
CStdWindow *CStdWindow::Init(CStdApp *pApp, const char *Title, CStdWindow *pParent, bool HideCursor) { #ifndef USE_X11 return this; #else Active = true; dpy = pApp->dpy; if (!FindInfo()) return 0; // Various properties XSetWindowAttributes attr; attr.border_pixel = 0; attr.background_pixel = 0; // Which events we want to receive attr.event_mask = // EnterWindowMask | // LeaveWindowMask | StructureNotifyMask | FocusChangeMask | KeyPressMask | KeyReleaseMask | PointerMotionMask | ButtonPressMask | ButtonReleaseMask; attr.colormap = XCreateColormap(dpy, DefaultRootWindow(dpy), ((XVisualInfo *)Info)->visual, AllocNone); unsigned long attrmask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask; Pixmap bitmap; if (HideCursor) { // Hide the mouse cursor XColor cursor_color; // We do not care what color the invisible cursor has memset(&cursor_color, 0, sizeof(cursor_color)); bitmap = XCreateBitmapFromData(dpy, DefaultRootWindow(dpy), "\000", 1, 1); attr.cursor = XCreatePixmapCursor(dpy, bitmap, bitmap, &cursor_color, &cursor_color, 0, 0); attrmask |= CWCursor; } wnd = XCreateWindow(dpy, DefaultRootWindow(dpy), 0, 0, 640, 480, 0, ((XVisualInfo *)Info)->depth, InputOutput, ((XVisualInfo *)Info)->visual, attrmask, &attr); if (HideCursor) { XFreeCursor(dpy, attr.cursor); XFreePixmap(dpy, bitmap); } if (!wnd) { Log("Error creating window."); return 0; } // Update the XWindow->CStdWindow-Map CStdAppPrivate::SetWindow(wnd, this); if (!pApp->Priv->xic && pApp->Priv->xim) { pApp->Priv->xic = XCreateIC( pApp->Priv->xim, XNClientWindow, wnd, XNFocusWindow, wnd, XNInputStyle, XIMPreeditNothing | XIMStatusNothing, XNResourceName, STD_PRODUCT, XNResourceClass, STD_PRODUCT, NULL); if (!pApp->Priv->xic) { Log("Failed to create input context."); XCloseIM(pApp->Priv->xim); pApp->Priv->xim = 0; } else { long ic_event_mask; if (XGetICValues(pApp->Priv->xic, XNFilterEvents, &ic_event_mask, NULL) == NULL) attr.event_mask |= ic_event_mask; XSelectInput(dpy, wnd, attr.event_mask); XSetICFocus(pApp->Priv->xic); } } // We want notification of closerequests and be killed if we hang Atom WMProtocols[2]; char *WMProtocolnames[] = {"WM_DELETE_WINDOW", "_NET_WM_PING"}; XInternAtoms(dpy, WMProtocolnames, 2, false, WMProtocols); XSetWMProtocols(dpy, wnd, WMProtocols, 2); // Let the window manager know our pid so it can kill us Atom PID = XInternAtom(pApp->dpy, "_NET_WM_PID", false); int32_t pid = getpid(); if (PID != None) XChangeProperty(pApp->dpy, wnd, PID, XA_CARDINAL, 32, PropModeReplace, reinterpret_cast<const unsigned char *>(&pid), 1); // Title and stuff XTextProperty title_property; StdStrBuf tbuf; tbuf.Copy(Title ? Title : ""); char *tbufstr = tbuf.getMData(); // char * title = "Clonk Endeavour"; XStringListToTextProperty(&tbufstr, 1, &title_property); // State and Icon XWMHints *wm_hint = XAllocWMHints(); wm_hint->flags = StateHint | InputHint | IconPixmapHint | IconMaskHint; wm_hint->initial_state = NormalState; wm_hint->input = True; // Trust XpmCreatePixmapFromData to not modify the xpm... XpmCreatePixmapFromData(dpy, wnd, const_cast<char **>(c4x_xpm), &wm_hint->icon_pixmap, &wm_hint->icon_mask, 0); // Window class XClassHint *class_hint = XAllocClassHint(); class_hint->res_name = STD_PRODUCT; class_hint->res_class = STD_PRODUCT; XSetWMProperties(dpy, wnd, &title_property, &title_property, pApp->Priv->argv, pApp->Priv->argc, 0, wm_hint, class_hint); // Set "parent". Clonk does not use "real" parent windows, but multiple // toplevel windows. if (pParent) XSetTransientForHint(dpy, wnd, pParent->wnd); // Show window XMapWindow(dpy, wnd); // Clean up // The pixmap has to stay as long as the window exists, so it does not hurt to // never free it. // XFreePixmap(dpy,xwmh->icon_pixmap); // XFreePixmap(dpy,xwmh->icon_mask); XFree(title_property.value); Hints = wm_hint; XFree(class_hint); // Render into whole window renderwnd = wnd; return this; #endif // USE_X11 }
int main(int argc, char **argv) { XVisualInfo *vi; Colormap cmap; XSetWindowAttributes swa; GLXContext cx; XEvent event; GLboolean needRedraw = GL_FALSE, recalcModelView = GL_TRUE; int dummy; /*** (1) open a connection to the X server ***/ dpy = XOpenDisplay(NULL); if (dpy == NULL) fatalError("could not open display"); /*** (2) make sure OpenGL's GLX extension supported ***/ if(!glXQueryExtension(dpy, &dummy, &dummy)) fatalError("X server has no OpenGL GLX extension"); /*** (3) find an appropriate visual ***/ /* find an OpenGL-capable RGB visual with depth buffer */ vi = glXChooseVisual(dpy, DefaultScreen(dpy), dblBuf); if (vi == NULL) { vi = glXChooseVisual(dpy, DefaultScreen(dpy), snglBuf); if (vi == NULL) fatalError("no RGB visual with depth buffer"); doubleBuffer = GL_FALSE; } if(vi->class != TrueColor) fatalError("TrueColor visual required for this program"); /*** (4) create an OpenGL rendering context ***/ /* create an OpenGL rendering context */ cx = glXCreateContext(dpy, vi, /* no shared dlists */ None, /* direct rendering if possible */ GL_TRUE); if (cx == NULL) fatalError("could not create rendering context"); /*** (5) create an X window with the selected visual ***/ /* create an X colormap since probably not using default visual */ cmap = XCreateColormap(dpy, RootWindow(dpy, vi->screen), vi->visual, AllocNone); swa.colormap = cmap; swa.border_pixel = 0; swa.event_mask = KeyPressMask | ExposureMask | ButtonPressMask | StructureNotifyMask; win = XCreateWindow(dpy, RootWindow(dpy, vi->screen), 0, 0, 300, 300, 0, vi->depth, InputOutput, vi->visual, CWBorderPixel | CWColormap | CWEventMask, &swa); XSetStandardProperties(dpy, win, "main", "main", None, argv, argc, NULL); /*** (6) bind the rendering context to the window ***/ glXMakeCurrent(dpy, win, cx); /*** (7) request the X window to be displayed on the screen ***/ XMapWindow(dpy, win); /*** (8) configure the OpenGL context for rendering ***/ glEnable(GL_DEPTH_TEST); /* enable depth buffering */ glDepthFunc(GL_LESS); /* pedantic, GL_LESS is the default */ glClearDepth(1.0); /* pedantic, 1.0 is the default */ /* frame buffer clears should be to black */ glClearColor(0.0, 0.0, 0.0, 0.0); /* set up projection transform */ glMatrixMode(GL_PROJECTION); glLoadIdentity(); glFrustum(-1.0, 1.0, -1.0, 1.0, 1.0, 10.0); /* establish initial viewport */ /* pedantic, full window size is default viewport */ glViewport(0, 0, 300, 300); printf( "Press left mouse button to rotate around X axis\n" ); printf( "Press middle mouse button to rotate around Y axis\n" ); printf( "Press right mouse button to rotate around Z axis\n" ); printf( "Press ESC to quit the application\n" ); /*** (9) dispatch X events ***/ while (1) { do { XNextEvent(dpy, &event); switch (event.type) { case KeyPress: { KeySym keysym; XKeyEvent *kevent; char buffer[1]; /* It is necessary to convert the keycode to a * keysym before checking if it is an escape */ kevent = (XKeyEvent *) &event; if ( (XLookupString((XKeyEvent *)&event,buffer,1,&keysym,NULL) == 1) && (keysym == (KeySym)XK_Escape) ) exit(0); break; } case ButtonPress: recalcModelView = GL_TRUE; switch (event.xbutton.button) { case 1: xAngle += 10.0; break; case 2: yAngle += 10.0; break; case 3: zAngle += 10.0; break; } break; case ConfigureNotify: glViewport(0, 0, event.xconfigure.width, event.xconfigure.height); /* fall through... */ case Expose: needRedraw = GL_TRUE; break; } } while(XPending(dpy)); /* loop to compress events */ if (recalcModelView) { glMatrixMode(GL_MODELVIEW); /* reset modelview matrix to the identity matrix */ glLoadIdentity(); /* move the camera back three units */ glTranslatef(0.0, 0.0, -3.0); /* rotate by X, Y, and Z angles */ glRotatef(xAngle, 0.1, 0.0, 0.0); glRotatef(yAngle, 0.0, 0.1, 0.0); glRotatef(zAngle, 0.0, 0.0, 1.0); recalcModelView = GL_FALSE; needRedraw = GL_TRUE; } if (needRedraw) { redraw(); needRedraw = GL_FALSE; } } return 0; }
static void X11_GL_InitExtensions(_THIS) { Display *display = ((SDL_VideoData *) _this->driverdata)->display; int screen = DefaultScreen(display); XVisualInfo *vinfo; XSetWindowAttributes xattr; Window w; GLXContext context; const char *(*glXQueryExtensionsStringFunc) (Display *, int); const char *extensions; vinfo = X11_GL_GetVisual(_this, display, screen); if (!vinfo) { return; } xattr.background_pixel = 0; xattr.border_pixel = 0; xattr.colormap = XCreateColormap(display, RootWindow(display, screen), vinfo->visual, AllocNone); w = XCreateWindow(display, RootWindow(display, screen), 0, 0, 32, 32, 0, vinfo->depth, InputOutput, vinfo->visual, (CWBackPixel | CWBorderPixel | CWColormap), &xattr); context = _this->gl_data->glXCreateContext(display, vinfo, NULL, True); if (context) { _this->gl_data->glXMakeCurrent(display, w, context); } XFree(vinfo); glXQueryExtensionsStringFunc = (const char *(*)(Display *, int)) X11_GL_GetProcAddress(_this, "glXQueryExtensionsString"); if (glXQueryExtensionsStringFunc) { extensions = glXQueryExtensionsStringFunc(display, screen); } else { extensions = NULL; } /* Check for GLX_EXT_swap_control(_tear) */ _this->gl_data->HAS_GLX_EXT_swap_control_tear = SDL_FALSE; if (HasExtension("GLX_EXT_swap_control", extensions)) { _this->gl_data->glXSwapIntervalEXT = (void (*)(Display*,GLXDrawable,int)) X11_GL_GetProcAddress(_this, "glXSwapIntervalEXT"); if (HasExtension("GLX_EXT_swap_control_tear", extensions)) { _this->gl_data->HAS_GLX_EXT_swap_control_tear = SDL_TRUE; } } /* Check for GLX_MESA_swap_control */ if (HasExtension("GLX_MESA_swap_control", extensions)) { _this->gl_data->glXSwapIntervalMESA = (int(*)(int)) X11_GL_GetProcAddress(_this, "glXSwapIntervalMESA"); _this->gl_data->glXGetSwapIntervalMESA = (int(*)(void)) X11_GL_GetProcAddress(_this, "glXGetSwapIntervalMESA"); } /* Check for GLX_SGI_swap_control */ if (HasExtension("GLX_SGI_swap_control", extensions)) { _this->gl_data->glXSwapIntervalSGI = (int (*)(int)) X11_GL_GetProcAddress(_this, "glXSwapIntervalSGI"); } /* Check for GLX_EXT_visual_rating */ if (HasExtension("GLX_EXT_visual_rating", extensions)) { _this->gl_data->HAS_GLX_EXT_visual_rating = SDL_TRUE; } /* Check for GLX_EXT_visual_info */ if (HasExtension("GLX_EXT_visual_info", extensions)) { _this->gl_data->HAS_GLX_EXT_visual_info = SDL_TRUE; } if (context) { _this->gl_data->glXMakeCurrent(display, None, NULL); _this->gl_data->glXDestroyContext(display, context); } XDestroyWindow(display, w); X11_PumpEvents(_this); }
static EGLBoolean create_x_window(EGLmanager *eglman, const char *name) { EGLint scrnum, num_conf, num_visuals; Window root; EGLint vid; XVisualInfo *visInfo, visTemplate; XSetWindowAttributes attr; unsigned long mask; EGLint config_attrib[] = { EGL_RED_SIZE, 1, EGL_GREEN_SIZE, 1, EGL_BLUE_SIZE, 1, EGL_DEPTH_SIZE, 1, EGL_SURFACE_TYPE, EGL_WINDOW_BIT|EGL_PBUFFER_BIT, EGL_RENDERABLE_TYPE, EGL_OPENVG_BIT | EGL_OPENGL_BIT, EGL_NONE }; scrnum = DefaultScreen(eglman->xdpy); root = RootWindow(eglman->xdpy, scrnum); if (!eglChooseConfig(eglman->dpy, config_attrib, &eglman->conf, 1, &num_conf) || num_conf == 0 || eglGetError() != EGL_SUCCESS) { printf("Error: couldn't get an EGL visual config\n"); return EGL_FALSE; } if (!eglGetConfigAttrib(eglman->dpy, eglman->conf, EGL_NATIVE_VISUAL_ID, &vid) || eglGetError() != EGL_SUCCESS) { printf("Error: eglGetConfigAttrib() failed\n"); return EGL_FALSE; } /* The X window visual must match the EGL config */ visTemplate.visualid = vid; visInfo = XGetVisualInfo(eglman->xdpy, VisualIDMask, &visTemplate, &num_visuals); if (!visInfo) { printf("Error: couldn't get X visual\n"); return EGL_FALSE; } /* window attributes */ attr.background_pixel = 0; attr.border_pixel = 0; attr.colormap = XCreateColormap(eglman->xdpy, root, visInfo->visual, AllocNone); attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask; mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask; eglman->xwin = XCreateWindow(eglman->xdpy, root, 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, 0, visInfo->depth, InputOutput, visInfo->visual, mask, &attr); if (!eglman->xwin) { printf("Error: couldn't create X Window\n"); return EGL_FALSE; } /* set hints and properties */ { XSizeHints sizehints; sizehints.x = 0; sizehints.y = 0; sizehints.width = WINDOW_WIDTH; sizehints.height = WINDOW_HEIGHT; sizehints.flags = USSize | USPosition; XSetNormalHints(eglman->xdpy, eglman->xwin, &sizehints); XSetStandardProperties(eglman->xdpy, eglman->xwin, name, name, None, (char **)NULL, 0, &sizehints); } XFree(visInfo); return EGL_TRUE; }
/* * Create an RGB, double-buffered X window. * Return the window and context handles. */ static void make_x_window(Display *x_dpy, EGLDisplay egl_dpy, const char *name, int x, int y, int width, int height, Window *winRet, EGLContext *ctxRet, EGLSurface *surfRet) { static const EGLint attribs[] = { EGL_RED_SIZE, 1, EGL_GREEN_SIZE, 1, EGL_BLUE_SIZE, 1, EGL_DEPTH_SIZE, 1, EGL_NONE }; int scrnum; XSetWindowAttributes attr; unsigned long mask; Window root; Window win; XVisualInfo *visInfo, visTemplate; int num_visuals; EGLContext ctx; EGLConfig config; EGLint num_configs; EGLint vid; scrnum = DefaultScreen( x_dpy ); root = RootWindow( x_dpy, scrnum ); if (!eglChooseConfig( egl_dpy, attribs, &config, 1, &num_configs)) { printf("Error: couldn't get an EGL visual config\n"); exit(1); } assert(config); assert(num_configs > 0); if (!eglGetConfigAttrib(egl_dpy, config, EGL_NATIVE_VISUAL_ID, &vid)) { printf("Error: eglGetConfigAttrib() failed\n"); exit(1); } /* The X window visual must match the EGL config */ visTemplate.visualid = vid; visInfo = XGetVisualInfo(x_dpy, VisualIDMask, &visTemplate, &num_visuals); if (!visInfo) { printf("Error: couldn't get X visual\n"); exit(1); } /* window attributes */ attr.background_pixel = 0; attr.border_pixel = 0; attr.colormap = XCreateColormap( x_dpy, root, visInfo->visual, AllocNone); attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask; mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask; win = XCreateWindow( x_dpy, root, x, y, width, height, 0, visInfo->depth, InputOutput, visInfo->visual, mask, &attr ); /* set hints and properties */ { XSizeHints sizehints; sizehints.x = x; sizehints.y = y; sizehints.width = width; sizehints.height = height; sizehints.flags = USSize | USPosition; XSetNormalHints(x_dpy, win, &sizehints); XSetStandardProperties(x_dpy, win, name, name, None, (char **)NULL, 0, &sizehints); } #if USE_FULL_GL eglBindAPI(EGL_OPENGL_API); #else eglBindAPI(EGL_OPENGL_ES_API); #endif if (ctxRet) { ctx = eglCreateContext(egl_dpy, config, EGL_NO_CONTEXT, NULL ); if (!ctx) { printf("Error: eglCreateContext failed\n"); exit(1); } *ctxRet = ctx; } *surfRet = eglCreateWindowSurface(egl_dpy, config, win, NULL); if (!*surfRet) { printf("Error: eglCreateWindowSurface failed\n"); exit(1); } XFree(visInfo); *winRet = win; }
/* ** GLW_SetMode */ int GLW_SetMode( const char *drivername, int mode, qboolean fullscreen ) { int attrib[] = { GLX_RGBA, // 0 GLX_RED_SIZE, 4, // 1, 2 GLX_GREEN_SIZE, 4, // 3, 4 GLX_BLUE_SIZE, 4, // 5, 6 GLX_DOUBLEBUFFER, // 7 GLX_DEPTH_SIZE, 1, // 8, 9 GLX_STENCIL_SIZE, 1, // 10, 11 None }; // these match in the array #define ATTR_RED_IDX 2 #define ATTR_GREEN_IDX 4 #define ATTR_BLUE_IDX 6 #define ATTR_DEPTH_IDX 9 #define ATTR_STENCIL_IDX 11 Window root; XVisualInfo *visinfo; XSetWindowAttributes attr; unsigned long mask; int colorbits, depthbits, stencilbits; int tcolorbits, tdepthbits, tstencilbits; int MajorVersion, MinorVersion; int actualWidth, actualHeight; int i; r_fakeFullscreen = ri.Cvar_Get( "r_fakeFullscreen", "0", CVAR_ARCHIVE); ri.Printf( PRINT_ALL, "Initializing OpenGL display\n"); ri.Printf (PRINT_ALL, "...setting mode %d:", mode ); if ( !R_GetModeInfo( &glConfig.vidWidth, &glConfig.vidHeight, &glConfig.windowAspect, mode ) ) { ri.Printf( PRINT_ALL, " invalid mode\n" ); return RSERR_INVALID_MODE; } ri.Printf( PRINT_ALL, " %d %d\n", glConfig.vidWidth, glConfig.vidHeight); if (!(dpy = XOpenDisplay(NULL))) { fprintf(stderr, "Error couldn't open the X display\n"); return RSERR_INVALID_MODE; } scrnum = DefaultScreen(dpy); root = RootWindow(dpy, scrnum); actualWidth = glConfig.vidWidth; actualHeight = glConfig.vidHeight; // Get video mode list MajorVersion = MinorVersion = 0; if (!XF86VidModeQueryVersion(dpy, &MajorVersion, &MinorVersion)) { vidmode_ext = qfalse; } else { ri.Printf(PRINT_ALL, "Using XFree86-VidModeExtension Version %d.%d\n", MajorVersion, MinorVersion); vidmode_ext = qtrue; } if (vidmode_ext) { int best_fit, best_dist, dist, x, y; XF86VidModeGetAllModeLines(dpy, scrnum, &num_vidmodes, &vidmodes); // Are we going fullscreen? If so, let's change video mode if (fullscreen && !r_fakeFullscreen->integer) { best_dist = 9999999; best_fit = -1; for (i = 0; i < num_vidmodes; i++) { if (glConfig.vidWidth > vidmodes[i]->hdisplay || glConfig.vidHeight > vidmodes[i]->vdisplay) continue; x = glConfig.vidWidth - vidmodes[i]->hdisplay; y = glConfig.vidHeight - vidmodes[i]->vdisplay; dist = (x * x) + (y * y); if (dist < best_dist) { best_dist = dist; best_fit = i; } } if (best_fit != -1) { actualWidth = vidmodes[best_fit]->hdisplay; actualHeight = vidmodes[best_fit]->vdisplay; // change to the mode XF86VidModeSwitchToMode(dpy, scrnum, vidmodes[best_fit]); vidmode_active = qtrue; // Move the viewport to top left XF86VidModeSetViewPort(dpy, scrnum, 0, 0); } else fullscreen = 0; } } if (!r_colorbits->value) colorbits = 24; else colorbits = r_colorbits->value; if ( !Q_stricmp( r_glDriver->string, _3DFX_DRIVER_NAME ) ) colorbits = 16; if (!r_depthbits->value) depthbits = 24; else depthbits = r_depthbits->value; stencilbits = r_stencilbits->value; for (i = 0; i < 16; i++) { // 0 - default // 1 - minus colorbits // 2 - minus depthbits // 3 - minus stencil if ((i % 4) == 0 && i) { // one pass, reduce switch (i / 4) { case 2 : if (colorbits == 24) colorbits = 16; break; case 1 : if (depthbits == 24) depthbits = 16; else if (depthbits == 16) depthbits = 8; case 3 : if (stencilbits == 24) stencilbits = 16; else if (stencilbits == 16) stencilbits = 8; } } tcolorbits = colorbits; tdepthbits = depthbits; tstencilbits = stencilbits; if ((i % 4) == 3) { // reduce colorbits if (tcolorbits == 24) tcolorbits = 16; } if ((i % 4) == 2) { // reduce depthbits if (tdepthbits == 24) tdepthbits = 16; else if (tdepthbits == 16) tdepthbits = 8; } if ((i % 4) == 1) { // reduce stencilbits if (tstencilbits == 24) tstencilbits = 16; else if (tstencilbits == 16) tstencilbits = 8; else tstencilbits = 0; } if (tcolorbits == 24) { attrib[ATTR_RED_IDX] = 8; attrib[ATTR_GREEN_IDX] = 8; attrib[ATTR_BLUE_IDX] = 8; } else { // must be 16 bit attrib[ATTR_RED_IDX] = 4; attrib[ATTR_GREEN_IDX] = 4; attrib[ATTR_BLUE_IDX] = 4; } attrib[ATTR_DEPTH_IDX] = tdepthbits; // default to 24 depth attrib[ATTR_STENCIL_IDX] = tstencilbits; #if 0 ri.Printf( PRINT_DEVELOPER, "Attempting %d/%d/%d Color bits, %d depth, %d stencil display...", attrib[ATTR_RED_IDX], attrib[ATTR_GREEN_IDX], attrib[ATTR_BLUE_IDX], attrib[ATTR_DEPTH_IDX], attrib[ATTR_STENCIL_IDX]); #endif visinfo = qglXChooseVisual(dpy, scrnum, attrib); if (!visinfo) { #if 0 ri.Printf( PRINT_DEVELOPER, "failed\n"); #endif continue; } #if 0 ri.Printf( PRINT_DEVELOPER, "Successful\n"); #endif ri.Printf( PRINT_ALL, "Using %d/%d/%d Color bits, %d depth, %d stencil display.\n", attrib[ATTR_RED_IDX], attrib[ATTR_GREEN_IDX], attrib[ATTR_BLUE_IDX], attrib[ATTR_DEPTH_IDX], attrib[ATTR_STENCIL_IDX]); glConfig.colorBits = tcolorbits; glConfig.depthBits = tdepthbits; glConfig.stencilBits = tstencilbits; break; } if (!visinfo) { ri.Printf( PRINT_ALL, "Couldn't get a visual\n" ); return RSERR_INVALID_MODE; } /* window attributes */ attr.background_pixel = BlackPixel(dpy, scrnum); attr.border_pixel = 0; attr.colormap = XCreateColormap(dpy, root, visinfo->visual, AllocNone); attr.event_mask = X_MASK; if (vidmode_active) { mask = CWBackPixel | CWColormap | CWSaveUnder | CWBackingStore | CWEventMask | CWOverrideRedirect; attr.override_redirect = True; attr.backing_store = NotUseful; attr.save_under = False; } else mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask; win = XCreateWindow(dpy, root, 0, 0, actualWidth, actualHeight, 0, visinfo->depth, InputOutput, visinfo->visual, mask, &attr); XMapWindow(dpy, win); if (vidmode_active) XMoveWindow(dpy, win, 0, 0); // Check for DGA if (in_dgamouse->value) { if (!XF86DGAQueryVersion(dpy, &MajorVersion, &MinorVersion)) { // unable to query, probalby not supported ri.Printf( PRINT_ALL, "Failed to detect XF86DGA Mouse\n" ); ri.Cvar_Set( "in_dgamouse", "0" ); } else ri.Printf( PRINT_ALL, "XF86DGA Mouse (Version %d.%d) initialized\n", MajorVersion, MinorVersion); } XFlush(dpy); ctx = qglXCreateContext(dpy, visinfo, NULL, True); qglXMakeCurrent(dpy, win, ctx); return RSERR_OK; }
bool WaylandX11WindowSystem::createNativeContext() { bool result = true; Window rootWindow = 0; XSetWindowAttributes windowAttributes; unsigned int windowMask = 0; int colorDepth = 0; int widthCorrected = 0; int heightCorrected = 0; LOG_DEBUG("WaylandX11WindowSystem", "createNativeContext IN"); m_x11Window = 0; m_x11Display = NULL; m_x11Screen = 0; m_x11Visual = NULL; m_x11Display = XOpenDisplay(0); if (!m_x11Display) { printf("Error: Unable to open X display\n"); return false; } m_x11Screen = XDefaultScreen(m_x11Display); // Get the root window parameters rootWindow = RootWindow(m_x11Display, m_x11Screen); colorDepth = 32; // TODO: DefaultDepth(m_x11Display, m_x11Screen); // Alloc memory for the visual info m_x11Visual = (XVisualInfo*)malloc(sizeof(XVisualInfo)); // Try to find a visual which is matching the needed parameters if (!XMatchVisualInfo(m_x11Display, m_x11Screen, colorDepth, TrueColor, m_x11Visual)) { printf("Error: Unable to acquire visual\n"); //destroyX11Context(); return false; } // Create the rendercontext color map m_x11Colormap = XCreateColormap( m_x11Display, rootWindow, m_x11Visual->visual, AllocNone); windowAttributes.colormap = m_x11Colormap; // Add to these for handling other events windowAttributes.event_mask = StructureNotifyMask | ExposureMask | ButtonPressMask | ButtonReleaseMask | KeyPressMask | KeyReleaseMask | Button1MotionMask | PointerMotionMask | FocusChangeMask; windowAttributes.backing_store = Always; // Set the window mask attributes windowMask = CWBackPixel | CWBorderPixel | CWEventMask | CWColormap | CWBackingStore; // get the corrected window dimensions widthCorrected = m_width < XDisplayWidth(m_x11Display, m_x11Screen) ? m_width : XDisplayWidth( m_x11Display, m_x11Screen); heightCorrected = m_height < XDisplayHeight(m_x11Display, m_x11Screen) ? m_height : XDisplayHeight( m_x11Display, m_x11Screen); // Creates the X11 window m_x11Window = XCreateWindow( m_x11Display, RootWindow(m_x11Display, m_x11Screen), 0, 0, widthCorrected, heightCorrected, 0, m_x11Visual->depth, InputOutput, m_x11Visual->visual, windowMask, &windowAttributes); // map the window XMapWindow(m_x11Display, m_x11Window); XFlush(m_x11Display); LOG_DEBUG("WaylandX11WindowSystem", "createNativeContext OUT"); return result; }
static bool gfx_ctx_set_video_mode( unsigned width, unsigned height, bool fullscreen) { struct sigaction sa = {{0}}; sa.sa_handler = sighandler; sa.sa_flags = SA_RESTART; sigemptyset(&sa.sa_mask); sigaction(SIGINT, &sa, NULL); sigaction(SIGTERM, &sa, NULL); XVisualInfo temp = {0}; XSetWindowAttributes swa = {0}; XVisualInfo *vi = NULL; bool windowed_full = g_settings.video.windowed_fullscreen; bool true_full = false; int x_off = 0; int y_off = 0; EGLint vid; if (!eglGetConfigAttrib(g_egl_dpy, g_config, EGL_NATIVE_VISUAL_ID, &vid)) goto error; temp.visualid = vid; EGLint num_visuals; vi = XGetVisualInfo(g_dpy, VisualIDMask, &temp, &num_visuals); if (!vi) goto error; swa.colormap = g_cmap = XCreateColormap(g_dpy, RootWindow(g_dpy, vi->screen), vi->visual, AllocNone); swa.event_mask = StructureNotifyMask | KeyPressMask | KeyReleaseMask; swa.override_redirect = fullscreen ? True : False; if (fullscreen && !windowed_full) { if (x11_enter_fullscreen(g_dpy, width, height, &g_desktop_mode)) { g_should_reset_mode = true; true_full = true; } else RARCH_ERR("[X/EGL]: Entering true fullscreen failed. Will attempt windowed mode.\n"); } if (g_settings.video.monitor_index) g_screen = g_settings.video.monitor_index - 1; #ifdef HAVE_XINERAMA if (fullscreen || g_screen != 0) { unsigned new_width = width; unsigned new_height = height; if (x11_get_xinerama_coord(g_dpy, g_screen, &x_off, &y_off, &new_width, &new_height)) RARCH_LOG("[X/EGL]: Using Xinerama on screen #%u.\n", g_screen); else RARCH_LOG("[X/EGL]: Xinerama is not active on screen.\n"); if (fullscreen) { width = new_width; height = new_height; } } #endif RARCH_LOG("[X/EGL]: X = %d, Y = %d, W = %u, H = %u.\n", x_off, y_off, width, height); g_win = XCreateWindow(g_dpy, RootWindow(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(g_dpy, g_win, 0); // GLES 2.0. Don't use for any other API. static const EGLint egl_ctx_gles_attribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE, }; g_egl_ctx = eglCreateContext(g_egl_dpy, g_config, EGL_NO_CONTEXT, (g_api == GFX_CTX_OPENGL_ES_API) ? egl_ctx_gles_attribs : NULL); if (!g_egl_ctx) goto error; g_egl_surf = eglCreateWindowSurface(g_egl_dpy, g_config, (EGLNativeWindowType)g_win, NULL); if (!g_egl_surf) goto error; if (!eglMakeCurrent(g_egl_dpy, g_egl_surf, g_egl_surf, g_egl_ctx)) goto error; gfx_ctx_update_window_title(true); x11_set_window_attr(g_dpy, g_win); if (fullscreen) x11_hide_mouse(g_dpy, g_win); if (true_full) { RARCH_LOG("[GLX]: Using true fullscreen.\n"); XMapRaised(g_dpy, g_win); } else if (fullscreen) // We attempted true fullscreen, but failed. Attempt using windowed fullscreen. { XMapRaised(g_dpy, g_win); RARCH_LOG("[X/EGL]: 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(g_dpy, g_win, x_off, y_off, width, height); x11_windowed_fullscreen(g_dpy, g_win); } else { XMapWindow(g_dpy, 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 (g_screen) x11_move_window(g_dpy, g_win, x_off, y_off, width, height); } XEvent event; XIfEvent(g_dpy, &event, egl_wait_notify, NULL); XSetInputFocus(g_dpy, g_win, RevertToNone, CurrentTime); g_quit_atom = XInternAtom(g_dpy, "WM_DELETE_WINDOW", False); if (g_quit_atom) XSetWMProtocols(g_dpy, g_win, &g_quit_atom, 1); gfx_ctx_swap_interval(g_interval); XFree(vi); g_has_focus = true; g_inited = true; driver.display_type = RARCH_DISPLAY_X11; driver.video_display = (uintptr_t)g_dpy; driver.video_window = (uintptr_t)g_win; g_true_full = true_full; return true; error: if (vi) XFree(vi); gfx_ctx_destroy(); return false; }
Error ContextGL_X11::initialize() { GLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribsARB = NULL; // const char *extensions = glXQueryExtensionsString(x11_display, DefaultScreen(x11_display)); glXCreateContextAttribsARB = (GLXCREATECONTEXTATTRIBSARBPROC)glXGetProcAddress((const GLubyte*)"glXCreateContextAttribsARB"); ERR_FAIL_COND_V( !glXCreateContextAttribsARB, ERR_UNCONFIGURED ); static int visual_attribs[] = { GLX_RENDER_TYPE, GLX_RGBA_BIT, GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT, GLX_DOUBLEBUFFER, true, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1, GLX_DEPTH_SIZE, 24, None }; int fbcount; GLXFBConfig *fbc = glXChooseFBConfig(x11_display, DefaultScreen(x11_display), visual_attribs, &fbcount); ERR_FAIL_COND_V(!fbc,ERR_UNCONFIGURED); XVisualInfo *vi = glXGetVisualFromFBConfig(x11_display, fbc[0]); XSetWindowAttributes swa; swa.colormap = XCreateColormap(x11_display, RootWindow(x11_display, vi->screen), vi->visual, AllocNone); swa.border_pixel = 0; swa.event_mask = StructureNotifyMask; /* char* windowid = getenv("GODOT_WINDOWID"); if (windowid) { //freopen("/home/punto/stdout", "w", stdout); //reopen("/home/punto/stderr", "w", stderr); x11_window = atol(windowid); } else { */ x11_window = XCreateWindow(x11_display, RootWindow(x11_display, vi->screen), 0, 0, OS::get_singleton()->get_video_mode().width, OS::get_singleton()->get_video_mode().height, 0, vi->depth, InputOutput, vi->visual, CWBorderPixel|CWColormap|CWEventMask, &swa); ERR_FAIL_COND_V(!x11_window,ERR_UNCONFIGURED); XMapWindow(x11_display, x11_window); while(true) { // wait for mapnotify (window created) XEvent e; XNextEvent(x11_display, &e); if (e.type == MapNotify) break; } //}; if (!OS::get_singleton()->get_video_mode().resizable) { XSizeHints *xsh; xsh = XAllocSizeHints(); xsh->flags = PMinSize | PMaxSize; xsh->min_width = OS::get_singleton()->get_video_mode().width; xsh->max_width = OS::get_singleton()->get_video_mode().width; xsh->min_height = OS::get_singleton()->get_video_mode().height; xsh->max_height = OS::get_singleton()->get_video_mode().height; XSetWMNormalHints(x11_display, x11_window, xsh); } if (!opengl_3_context) { //oldstyle context: p->glx_context = glXCreateContext(x11_display, vi, 0, GL_TRUE); } else { static int context_attribs[] = { GLX_CONTEXT_MAJOR_VERSION_ARB, 3, GLX_CONTEXT_MINOR_VERSION_ARB, 0, None }; p->glx_context = glXCreateContextAttribsARB(x11_display, fbc[0], NULL, true, context_attribs); ERR_FAIL_COND_V(!p->glx_context,ERR_UNCONFIGURED); } glXMakeCurrent(x11_display, x11_window, p->glx_context); /* glWrapperInit(wrapper_get_proc_address); glFlush(); glXSwapBuffers(x11_display,x11_window); */ //glXMakeCurrent(x11_display, None, NULL); return OK; }
int main() { hvLogInit(HV_LOG_INFO, stdout); hvPrint("HyperVision design approach test programme: X + GLX + OpenGL"); /* Open X Display */ Display *x_dsp = XOpenDisplay(NULL); hvErrorCheck(!x_dsp, "Failed to open X display"); /* Check and report GLX version*/ int glx_maj = 0, glx_min = 0; glXQueryVersion(x_dsp, &glx_maj, &glx_min); hvErrorCheck(glx_maj * 10 + glx_min < 14, "Invalid GLX version (1.4 required)"); //*1 hvInfo("GLX version: ", glXGetClientString(x_dsp, GLX_VERSION)); /* Choose best GLX FB configuration and get the GLX visual */ static int glx_fb_atr[] = { GLX_X_RENDERABLE , True, GLX_DRAWABLE_TYPE , GLX_WINDOW_BIT, GLX_RENDER_TYPE , GLX_RGBA_BIT, GLX_X_VISUAL_TYPE , GLX_TRUE_COLOR, GLX_CONFIG_CAVEAT , GLX_NONE, GLX_RED_SIZE , 8, GLX_GREEN_SIZE , 8, GLX_BLUE_SIZE , 8, GLX_ALPHA_SIZE , 8, GLX_DEPTH_SIZE , 24, GLX_STENCIL_SIZE , 8, GLX_DOUBLEBUFFER , True, None }; int glx_fb_cnt; GLXFBConfig *glx_fb_cfg = glXChooseFBConfig(x_dsp, DefaultScreen(x_dsp), glx_fb_atr, &glx_fb_cnt); hvErrorCheck(!glx_fb_cfg, "Failed to retrieve a framebuffer config"); // Pick the FB config with the most samples per pixel int top_fbc = 0, top_smp = 0, smp; for (int i = 0; i < glx_fb_cnt; i++) { glXGetFBConfigAttrib(x_dsp, glx_fb_cfg[i], GLX_SAMPLES, &smp); if (smp > top_smp) top_fbc = i, top_smp = smp; } GLXFBConfig glx_fbc = glx_fb_cfg[top_fbc]; XFree(glx_fb_cfg); XVisualInfo *glx_vsl = glXGetVisualFromFBConfig(x_dsp, glx_fbc); hvInfo("Chosen visual ID = ", hvHex(glx_vsl->visualid)); /* Create and map X window */ Colormap x_cmap = XCreateColormap(x_dsp, RootWindow(x_dsp, glx_vsl->screen), glx_vsl->visual, AllocNone); XSetWindowAttributes x_swa; x_swa.colormap = x_cmap; x_swa.background_pixmap = None; x_swa.border_pixel = 0; x_swa.event_mask = StructureNotifyMask; Window x_wnd = XCreateWindow(x_dsp, RootWindow(x_dsp, glx_vsl->screen), 0, 0, 100, 100, 0, glx_vsl->depth, InputOutput, glx_vsl->visual, CWBorderPixel|CWColormap|CWEventMask, &x_swa); hvErrorCheck(!x_wnd, "Failed to create window"); XFree(glx_vsl); XStoreName(x_dsp, x_wnd, "HyperVision GLX test"); XMapWindow(x_dsp, x_wnd); /* Retreive GLX_ARB_create_context extension and create OpenGL 3.0 context */ int context_attribs[] = { GLX_CONTEXT_MAJOR_VERSION_ARB, 3, GLX_CONTEXT_MINOR_VERSION_ARB, 0, GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB, GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB, None }; const char *glx_exts = glXQueryExtensionsString(x_dsp, DefaultScreen(x_dsp)); glXCreateContextAttribsARBProc glXCreateContextAttribsARB = NULL; glXCreateContextAttribsARB = (glXCreateContextAttribsARBProc) glXGetProcAddress((const GLubyte*) "glXCreateContextAttribsARB"); hvErrorCheck(!hvInSet(glx_exts, "GLX_ARB_create_context") || !glXCreateContextAttribsARB, "GLX_ARB_create_context extension missing"); GLXContext glx_ctx = glXCreateContextAttribsARB(x_dsp, glx_fbc, 0, True, context_attribs ); if (!glXIsDirect(x_dsp, glx_ctx)) { hvInfo("GLX rendering context: indirect"); } else { hvInfo("GLX rendering context: DRI"); } /* Render OpenGL scene */ glXMakeCurrent(x_dsp, x_wnd, glx_ctx); glClearColor(0, 0.5, 1, 1); glClear (GL_COLOR_BUFFER_BIT); glXSwapBuffers(x_dsp, x_wnd); sleep(1); glClearColor(1, 0.5, 0, 1); glClear(GL_COLOR_BUFFER_BIT); glXSwapBuffers(x_dsp, x_wnd); sleep(1); glXMakeCurrent(x_dsp, 0, 0); /* Release used resources */ glXDestroyContext(x_dsp, glx_ctx); XDestroyWindow(x_dsp, x_wnd); XFreeColormap(x_dsp, x_cmap); XCloseDisplay(x_dsp); }
static cairo_surface_t * _cairo_boilerplate_gl_create_window_db (const char *name, cairo_content_t content, double width, double height, double max_width, double max_height, cairo_boilerplate_mode_t mode, int id, void **closure) { int rgba_attribs[] = { GLX_RGBA, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1, GLX_ALPHA_SIZE, 1, GLX_DOUBLEBUFFER, None }; XVisualInfo *vi; GLXContext ctx; gl_target_closure_t *gltc; cairo_surface_t *surface; Display *dpy; XSetWindowAttributes attr; cairo_status_t status; gltc = calloc (1, sizeof (gl_target_closure_t)); *closure = gltc; if (width == 0) width = 1; if (height == 0) height = 1; dpy = XOpenDisplay (NULL); gltc->dpy = dpy; if (!gltc->dpy) { fprintf (stderr, "Failed to open display: %s\n", XDisplayName(0)); free (gltc); return NULL; } if (mode == CAIRO_BOILERPLATE_MODE_TEST) XSynchronize (gltc->dpy, 1); vi = glXChooseVisual (dpy, DefaultScreen (dpy), rgba_attribs); if (vi == NULL) { fprintf (stderr, "Failed to create RGBA, double-buffered visual\n"); XCloseDisplay (dpy); free (gltc); return NULL; } attr.colormap = XCreateColormap (dpy, RootWindow (dpy, vi->screen), vi->visual, AllocNone); attr.border_pixel = 0; attr.override_redirect = True; gltc->drawable = XCreateWindow (dpy, DefaultRootWindow (dpy), 0, 0, width, height, 0, vi->depth, InputOutput, vi->visual, CWOverrideRedirect | CWBorderPixel | CWColormap, &attr); XMapWindow (dpy, gltc->drawable); ctx = glXCreateContext (dpy, vi, NULL, True); XFree (vi); gltc->ctx = ctx; gltc->device = cairo_glx_device_create (dpy, ctx); gltc->surface = cairo_gl_surface_create_for_window (gltc->device, gltc->drawable, ceil (width), ceil (height)); surface = cairo_surface_create_similar (gltc->surface, content, width, height); status = cairo_surface_set_user_data (surface, &gl_closure_key, gltc, NULL); if (status == CAIRO_STATUS_SUCCESS) return surface; cairo_surface_destroy (surface); _cairo_boilerplate_gl_cleanup (gltc); return cairo_boilerplate_surface_create_in_error (status); }
/* * Create an RGB, double-buffered window. * Return the window and context handles. */ static void make_window( Display *dpy, const char *name, int x, int y, int width, int height, Window *winRet, GLXContext *ctxRet) { int attribs[] = { GLX_RGBA, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1, GLX_DOUBLEBUFFER, GLX_DEPTH_SIZE, 1, None }; int stereoAttribs[] = { GLX_RGBA, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1, GLX_DOUBLEBUFFER, GLX_DEPTH_SIZE, 1, GLX_STEREO, None }; int scrnum; XSetWindowAttributes attr; unsigned long mask; Window root; Window win; GLXContext ctx; XVisualInfo *visinfo; scrnum = DefaultScreen( dpy ); root = RootWindow( dpy, scrnum ); if (fullscreen) { x = 0; y = 0; width = DisplayWidth( dpy, scrnum ); height = DisplayHeight( dpy, scrnum ); } if (stereo) visinfo = glXChooseVisual( dpy, scrnum, stereoAttribs ); else visinfo = glXChooseVisual( dpy, scrnum, attribs ); if (!visinfo) { if (stereo) { printf("Error: couldn't get an RGB, " "Double-buffered, Stereo visual\n"); } else printf("Error: couldn't get an RGB, Double-buffered visual\n"); exit(1); } /* window attributes */ attr.background_pixel = 0; attr.border_pixel = 0; attr.colormap = XCreateColormap( dpy, root, visinfo->visual, AllocNone); attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask; /* XXX this is a bad way to get a borderless window! */ mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask; win = XCreateWindow( dpy, root, x, y, width, height, 0, visinfo->depth, InputOutput, visinfo->visual, mask, &attr ); if (fullscreen) no_border(dpy, win); /* set hints and properties */ { XSizeHints sizehints; sizehints.x = x; sizehints.y = y; sizehints.width = width; sizehints.height = height; sizehints.flags = USSize | USPosition; XSetNormalHints(dpy, win, &sizehints); XSetStandardProperties(dpy, win, name, name, None, (char **)NULL, 0, &sizehints); } ctx = glXCreateContext( dpy, visinfo, NULL, True ); if (!ctx) { printf("Error: glXCreateContext failed\n"); exit(1); } XFree(visinfo); *winRet = win; *ctxRet = ctx; }
static bool xdpy_create_display_window(ALLEGRO_SYSTEM_XGLX *system, ALLEGRO_DISPLAY_XGLX *d, int w, int h, int adapter) { ALLEGRO_DISPLAY *display = (ALLEGRO_DISPLAY *)d; /* Create a colormap. */ Colormap cmap = XCreateColormap(system->x11display, RootWindow(system->x11display, d->xvinfo->screen), d->xvinfo->visual, AllocNone); /* Create an X11 window */ XSetWindowAttributes swa; int mask = CWBorderPixel | CWColormap | CWEventMask; swa.colormap = cmap; swa.border_pixel = 0; swa.event_mask = KeyPressMask | KeyReleaseMask | StructureNotifyMask | EnterWindowMask | LeaveWindowMask | FocusChangeMask | ExposureMask | PropertyChangeMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask; /* For a non-compositing window manager, a black background can look * less broken if the application doesn't react to expose events fast * enough. However in some cases like resizing, the black background * causes horrible flicker. */ if (!(display->flags & ALLEGRO_RESIZABLE)) { mask |= CWBackPixel; swa.background_pixel = BlackPixel(system->x11display, d->xvinfo->screen); } int x_off = INT_MAX; int y_off = INT_MAX; if (display->flags & ALLEGRO_FULLSCREEN) { _al_xglx_get_display_offset(system, d->adapter, &x_off, &y_off); } else { /* We want new_display_adapter's offset to add to the * new_window_position. */ int xscr_x = 0; int xscr_y = 0; al_get_new_window_position(&x_off, &y_off); if (adapter >= 0) { /* Non default adapter. I'm assuming this means the user wants the * window to be placed on the adapter offset by new display pos. */ _al_xglx_get_display_offset(system, d->adapter, &xscr_x, &xscr_y); if (x_off != INT_MAX) x_off += xscr_x; if (y_off != INT_MAX) y_off += xscr_y; } } d->window = XCreateWindow(system->x11display, RootWindow(system->x11display, d->xvinfo->screen), x_off != INT_MAX ? x_off : 0, y_off != INT_MAX ? y_off : 0, w, h, 0, d->xvinfo->depth, InputOutput, d->xvinfo->visual, mask, &swa); ALLEGRO_DEBUG("Window ID: %ld\n", (long)d->window); /* Try to set full screen mode if requested, fail if we can't. */ if (display->flags & ALLEGRO_FULLSCREEN) { /* According to the spec, the window manager is supposed to disable * window decorations when _NET_WM_STATE_FULLSCREEN is in effect. * However, some WMs may not be fully compliant, e.g. Fluxbox. */ _al_xwin_set_frame(display, false); _al_xwin_set_above(display, 1); if (!_al_xglx_fullscreen_set_mode(system, d, w, h, 0, display->refresh_rate)) { ALLEGRO_DEBUG("xdpy: failed to set fullscreen mode.\n"); return false; } } if (display->flags & ALLEGRO_FRAMELESS) { _al_xwin_set_frame(display, false); } ALLEGRO_DEBUG("X11 window created.\n"); /* Set the PID related to the window. */ Atom _NET_WM_PID = XInternAtom(system->x11display, "_NET_WM_PID", False); int pid = getpid(); XChangeProperty(system->x11display, d->window, _NET_WM_PID, XA_CARDINAL, 32, PropModeReplace, (unsigned char *)&pid, 1); _al_xwin_set_size_hints(display, x_off, y_off); /* Let the window manager know we're a "normal" window */ Atom _NET_WM_WINDOW_TYPE; Atom _NET_WM_WINDOW_TYPE_NORMAL; _NET_WM_WINDOW_TYPE = XInternAtom(system->x11display, "_NET_WM_WINDOW_TYPE", False); _NET_WM_WINDOW_TYPE_NORMAL = XInternAtom(system->x11display, "_NET_WM_WINDOW_TYPE_NORMAL", False); XChangeProperty(system->x11display, d->window, _NET_WM_WINDOW_TYPE, XA_ATOM, 32, PropModeReplace, (unsigned char *)&_NET_WM_WINDOW_TYPE_NORMAL, 1); /* This seems like a good idea */ const long _NET_WM_BYPASS_COMPOSITOR_HINT_ON = 1; Atom _NET_WM_BYPASS_COMPOSITOR; _NET_WM_BYPASS_COMPOSITOR = XInternAtom(system->x11display, "_NET_WM_BYPASS_COMPOSITOR", False); XChangeProperty(system->x11display, d->window, _NET_WM_BYPASS_COMPOSITOR, XA_CARDINAL, 32, PropModeReplace, (unsigned char *)&_NET_WM_BYPASS_COMPOSITOR_HINT_ON, 1); #ifdef ALLEGRO_XWINDOWS_WITH_XINPUT2 /* listen for touchscreen events */ XIEventMask event_mask; event_mask.deviceid = XIAllMasterDevices; event_mask.mask_len = XIMaskLen(XI_TouchEnd); event_mask.mask = (unsigned char*)al_calloc(3, sizeof(char)); XISetMask(event_mask.mask, XI_TouchBegin); XISetMask(event_mask.mask, XI_TouchUpdate); XISetMask(event_mask.mask, XI_TouchEnd); XISelectEvents(system->x11display, d->window, &event_mask, 1); al_free(event_mask.mask); #endif return true; }
bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const std::string &output) { bool changeWindow = false; bool changeSize = false; float mouseX = 0.5; float mouseY = 0.5; if (!m_mainWindow) { CInputManager::GetInstance().SetMouseActive(false); } if (m_mainWindow && ((m_bFullScreen != fullscreen) || m_currentOutput.compare(output) != 0 || m_windowDirty)) { // set mouse to last known position // we can't trust values after an xrr event if (m_bIsInternalXrr && m_MouseX >= 0 && m_MouseY >= 0) { mouseX = (float)m_MouseX/m_nWidth; mouseY = (float)m_MouseY/m_nHeight; } else if (!m_windowDirty) { Window root_return, child_return; int root_x_return, root_y_return; int win_x_return, win_y_return; unsigned int mask_return; bool isInWin = XQueryPointer(m_dpy, m_mainWindow, &root_return, &child_return, &root_x_return, &root_y_return, &win_x_return, &win_y_return, &mask_return); if (isInWin) { mouseX = (float)win_x_return/m_nWidth; mouseY = (float)win_y_return/m_nHeight; } } CInputManager::GetInstance().SetMouseActive(false); OnLostDevice(); DestroyWindow(); m_windowDirty = true; } // create main window if (!m_mainWindow) { EnableSystemScreenSaver(false); #if defined(HAS_GLX) GLint att[] = { GLX_RGBA, GLX_RED_SIZE, 8, GLX_GREEN_SIZE, 8, GLX_BLUE_SIZE, 8, GLX_ALPHA_SIZE, 8, GLX_DEPTH_SIZE, 24, GLX_DOUBLEBUFFER, None }; #endif #if defined(HAS_EGL) EGLint att[] = { EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8, EGL_ALPHA_SIZE, 8, EGL_BUFFER_SIZE, 32, EGL_DEPTH_SIZE, 24, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL_NONE }; #endif Colormap cmap; XSetWindowAttributes swa; XVisualInfo *vi; int x0 = 0; int y0 = 0; XOutput *out = g_xrandr.GetOutput(output); if (!out) out = g_xrandr.GetOutput(m_currentOutput); if (out) { m_nScreen = out->screen; x0 = out->x; y0 = out->y; } #if defined(HAS_GLX) vi = glXChooseVisual(m_dpy, m_nScreen, att); #endif #if defined(HAS_EGL) if (m_eglDisplay == EGL_NO_DISPLAY) { m_eglDisplay = eglGetDisplay((EGLNativeDisplayType)m_dpy); if (m_eglDisplay == EGL_NO_DISPLAY) { CLog::Log(LOGERROR, "failed to get egl display\n"); return false; } if (!eglInitialize(m_eglDisplay, NULL, NULL)) { CLog::Log(LOGERROR, "failed to initialize egl display\n"); return false; } } EGLint numConfigs; EGLConfig eglConfig = 0; if (!eglChooseConfig(m_eglDisplay, att, &eglConfig, 1, &numConfigs) || numConfigs == 0) { CLog::Log(LOGERROR, "Failed to choose a config %d\n", eglGetError()); } EGLint eglVisualid; if (!eglGetConfigAttrib(m_eglDisplay, eglConfig, EGL_NATIVE_VISUAL_ID, &eglVisualid)) { CLog::Log(LOGERROR, "Failed to query native visual id\n"); } XVisualInfo x11_visual_info_template; x11_visual_info_template.visualid = eglVisualid; int num_visuals; vi = XGetVisualInfo(m_dpy, VisualIDMask, &x11_visual_info_template, &num_visuals); #endif if(!vi) { CLog::Log(LOGERROR, "Failed to find matching visual"); return false; } cmap = XCreateColormap(m_dpy, RootWindow(m_dpy, vi->screen), vi->visual, AllocNone); bool hasWM = HasWindowManager(); int def_vis = (vi->visual == DefaultVisual(m_dpy, vi->screen)); swa.override_redirect = hasWM ? False : True; swa.border_pixel = fullscreen ? 0 : 5; swa.background_pixel = def_vis ? BlackPixel(m_dpy, vi->screen) : 0; swa.colormap = cmap; swa.event_mask = FocusChangeMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask | PropertyChangeMask | StructureNotifyMask | KeymapStateMask | EnterWindowMask | LeaveWindowMask | ExposureMask; unsigned long mask = CWBackPixel | CWBorderPixel | CWColormap | CWOverrideRedirect | CWEventMask; m_mainWindow = XCreateWindow(m_dpy, RootWindow(m_dpy, vi->screen), x0, y0, width, height, 0, vi->depth, InputOutput, vi->visual, mask, &swa); swa.override_redirect = False; swa.border_pixel = 0; swa.event_mask = ExposureMask; mask = CWBackPixel | CWBorderPixel | CWColormap | CWOverrideRedirect | CWColormap | CWEventMask; m_glWindow = XCreateWindow(m_dpy, m_mainWindow, 0, 0, width, height, 0, vi->depth, InputOutput, vi->visual, mask, &swa); if (fullscreen && hasWM) { Atom fs = XInternAtom(m_dpy, "_NET_WM_STATE_FULLSCREEN", True); XChangeProperty(m_dpy, m_mainWindow, XInternAtom(m_dpy, "_NET_WM_STATE", True), XA_ATOM, 32, PropModeReplace, (unsigned char *) &fs, 1); // disable desktop compositing for KDE, when Kodi is in full-screen mode int one = 1; XChangeProperty(m_dpy, m_mainWindow, XInternAtom(m_dpy, "_KDE_NET_WM_BLOCK_COMPOSITING", True), XA_CARDINAL, 32, PropModeReplace, (unsigned char*) &one, 1); } // define invisible cursor Pixmap bitmapNoData; XColor black; static char noData[] = { 0,0,0,0,0,0,0,0 }; black.red = black.green = black.blue = 0; bitmapNoData = XCreateBitmapFromData(m_dpy, m_mainWindow, noData, 8, 8); m_invisibleCursor = XCreatePixmapCursor(m_dpy, bitmapNoData, bitmapNoData, &black, &black, 0, 0); XFreePixmap(m_dpy, bitmapNoData); XDefineCursor(m_dpy,m_mainWindow, m_invisibleCursor); //init X11 events CWinEventsX11Imp::Init(m_dpy, m_mainWindow); changeWindow = true; changeSize = true; #if defined(HAS_EGL) m_eglSurface = eglCreateWindowSurface(m_eglDisplay, eglConfig, m_glWindow, NULL); if (m_eglSurface == EGL_NO_SURFACE) { CLog::Log(LOGERROR, "failed to create egl window surface\n"); return false; } #endif } if (!CWinEventsX11Imp::HasStructureChanged() && ((width != m_nWidth) || (height != m_nHeight))) { changeSize = true; } if (changeSize || changeWindow) { XResizeWindow(m_dpy, m_mainWindow, width, height); } if ((width != m_nWidth) || (height != m_nHeight) || changeWindow) { XResizeWindow(m_dpy, m_glWindow, width, height); } if (changeWindow) { m_icon = None; { CreateIconPixmap(); XWMHints *wm_hints; XClassHint *class_hints; XTextProperty windowName, iconName; std::string titleString = CCompileInfo::GetAppName(); std::string classString = titleString; char *title = (char*)titleString.c_str(); XStringListToTextProperty(&title, 1, &windowName); XStringListToTextProperty(&title, 1, &iconName); wm_hints = XAllocWMHints(); wm_hints->initial_state = NormalState; wm_hints->icon_pixmap = m_icon; wm_hints->flags = StateHint | IconPixmapHint; class_hints = XAllocClassHint(); class_hints->res_class = (char*)classString.c_str(); class_hints->res_name = (char*)classString.c_str(); XSetWMProperties(m_dpy, m_mainWindow, &windowName, &iconName, NULL, 0, NULL, wm_hints, class_hints); XFree(class_hints); XFree(wm_hints); // register interest in the delete window message Atom wmDeleteMessage = XInternAtom(m_dpy, "WM_DELETE_WINDOW", False); XSetWMProtocols(m_dpy, m_mainWindow, &wmDeleteMessage, 1); } // placement of window may follow mouse XWarpPointer(m_dpy, None, m_mainWindow, 0, 0, 0, 0, mouseX*width, mouseY*height); XMapRaised(m_dpy, m_glWindow); XMapRaised(m_dpy, m_mainWindow); // discard events generated by creating the window, i.e. xrr events XSync(m_dpy, TRUE); CDirtyRegionList dr; RefreshGlxContext(m_currentOutput.compare(output) != 0); XSync(m_dpy, FALSE); g_graphicsContext.Clear(0); g_graphicsContext.Flip(dr); #if defined(HAS_GLX) g_Windowing.ResetVSync(); #endif m_windowDirty = false; m_bIsInternalXrr = false; // what's this??? #if defined(HAS_GLX) CSingleLock lock(m_resourceSection); // tell any shared resources for (std::vector<IDispResource *>::iterator i = m_resources.begin(); i != m_resources.end(); ++i) (*i)->OnResetDevice(); #endif } UpdateCrtc(); return true; }
int main (int argc, char **argv) { XEvent event; XSizeHints xsh; XSetWindowAttributes xswa; XVisualInfo *vinfo; glitz_drawable_format_t templ; glitz_drawable_format_t *dformat; unsigned long mask = 0; unsigned int width, height, window_width, window_height; int i; program_name = argv[0]; for (i = 1; i < argc; i++) { if (!strcasecmp ("-image", argv[i])) output_type = IMAGE_TYPE; #ifdef CAIRO_HAS_XLIB_SURFACE else if (!strcasecmp ("-xrender", argv[i])) { output_type = XRENDER_TYPE; } #endif else if (!strcasecmp ("-glx", argv[i])) { output_type = GLX_TYPE; } else if (!strcasecmp ("-noaa", argv[i])) { aa = 0; } else if (!strcasecmp ("-swaa", argv[i])) { aa = 1; } else if (!strcasecmp ("-hwaa", argv[i])) { aa = 3; } else { test_type = get_test_type (argv[i]); } } if (!test_type) { usage(); exit(1); } if (output_type != GLX_TYPE && test_type >= OPENGL_TYPE) { printf ("Sorry, this test only works with OpenGL!\n"); usage(); exit(1); } window_width = width = WINDOW_WIDTH; window_height = height = WINDOW_HEIGHT; if (aa == 3) templ.samples = 4; else templ.samples = 1; templ.depth_size = 16; if (test_type == CUBE_TYPE) mask |= GLITZ_FORMAT_DEPTH_SIZE_MASK; mask |= GLITZ_FORMAT_SAMPLES_MASK; if ((dpy = XOpenDisplay (NULL)) == NULL) { fprintf(stderr, "%s: can't open display: %s\n", argv[0], XDisplayName (NULL)); exit(1); } if (output_type != GLX_TYPE) { xsh.flags = PSize; xsh.width = width; xsh.height = height; xsh.x = 0; xsh.y = 0; win = XCreateWindow (dpy, RootWindow (dpy, DefaultScreen (dpy)), xsh.x, xsh.y, xsh.width, xsh.height, 0, CopyFromParent, CopyFromParent, CopyFromParent, 0, &xswa); XSetStandardProperties (dpy, win, PACKAGE, PACKAGE, None, argv, argc, &xsh); XSetWMHints (dpy, win, &xwmh); XSelectInput (dpy, win, StructureNotifyMask); } else { xsh.flags = PSize; xsh.width = width; xsh.height = height; xsh.x = 0; xsh.y = 0; mask = 0; templ.doublebuffer = 1; mask |= GLITZ_FORMAT_DOUBLEBUFFER_MASK; dformat = glitz_glx_find_window_format (dpy, DefaultScreen (dpy), mask, &templ, 0); vinfo = glitz_glx_get_visual_info_from_format (dpy, DefaultScreen (dpy), dformat); xswa.colormap = XCreateColormap (dpy, RootWindow (dpy, DefaultScreen (dpy)), vinfo->visual, AllocNone); win = XCreateWindow (dpy, RootWindow (dpy, DefaultScreen (dpy)), xsh.x, xsh.y, xsh.width, xsh.height, 0, vinfo->depth, CopyFromParent, vinfo->visual, CWColormap, &xswa); XSetStandardProperties (dpy, win, PACKAGE, PACKAGE, None, argv, argc, &xsh); XSetWMHints (dpy, win, &xwmh); XSelectInput (dpy, win, StructureNotifyMask); } switch (output_type) { case XRENDER_TYPE: resize_pixmap (width, height); break; case IMAGE_TYPE: resize_image (width, height); break; case GLX_TYPE: drawable = glitz_glx_create_drawable_for_window (dpy, 0, dformat, win, width, height); if (!drawable) { printf ("failed to create glitz drawable\n"); exit (1); } break; } if (aa == 3 && dformat->samples < 2) { fprintf (stderr, "hardware multi-sampling not available\n"); exit (1); } if (drawable) { surface = resize_glitz_drawable (drawable, dformat, width, height); } cr = cairo_create (surface); cairo_set_tolerance (cr, 0.5); setup (test_type); XMapWindow (dpy, win); for (;;) { if (XPending (dpy)) { XNextEvent (dpy, &event); if (event.type == ConfigureNotify) { width = event.xconfigure.width; height = event.xconfigure.height; switch (output_type) { #ifdef CAIRO_HAS_XLIB_SURFACE case XRENDER_TYPE: resize_pixmap (width, height); cairo_destroy (cr); cr = cairo_create (surface); cairo_set_tolerance (cr, 0.5); break; #endif case IMAGE_TYPE: resize_image (width, height); cairo_destroy (cr); cr = cairo_create (surface); cairo_set_tolerance (cr, 0.5); break; case GLX_TYPE: cairo_surface_destroy (surface); surface = resize_glitz_drawable (drawable, dformat, width, height); cairo_destroy (cr); cr = cairo_create (surface); cairo_set_tolerance (cr, 0.5); break; } } } else { render (test_type, output_type == GLX_TYPE); switch (output_type) { #ifdef CAIRO_HAS_XLIB_SURFACE case XRENDER_TYPE: XSetWindowBackgroundPixmap (dpy, win, pixmap); XClearWindow (dpy, win); break; #endif case IMAGE_TYPE: { GC gc; XImage *xim; pixmap = XCreatePixmap (dpy, DefaultRootWindow (dpy), width, height, DefaultDepth (dpy, DefaultScreen (dpy))); xim = XCreateImage(dpy, DefaultVisual (dpy, DefaultScreen (dpy)), DefaultDepth(dpy, DefaultScreen (dpy)), ZPixmap, 0, (char *) image, width, height, 32, 0); gc = XCreateGC (dpy, pixmap, 0, NULL); XPutImage (dpy, pixmap, gc, xim, 0, 0, 0, 0, width, height); XFreeGC (dpy, gc); xim->data = NULL; XDestroyImage (xim); XSetWindowBackgroundPixmap (dpy, win, pixmap); XClearWindow (dpy, win); XFreePixmap (dpy, pixmap); } break; } XSync (dpy, 0); } } exit (1); }