static int GGI_helper_x_dbe_setup(struct ggi_helper *helper, const char *args, void *argptr) { ggi_x_priv *priv = GGIX_PRIV(helper->visual); int major_version, minor_version; Status rc; /* Check if DBE is present before initialising */ rc = XdbeQueryExtension(priv->disp, &major_version, &minor_version); if (rc != True) return GGI_ENOFUNC; DPRINT_LIBS("X: DOUBLE-BUFFER: DBE version %i.%i\n", major_version, minor_version); return GGI_OK; }
/* function: queryextensions_x11display * Initializes extension variables of <x11display_t>. * It is expected that memory of all extension variables is set to zero * before you call this function. */ static int queryextensions_x11display(x11display_t * x11disp) { int major ; int minor ; int dummy ; Bool isSupported ; isSupported = XQueryExtension(x11disp->sys_display, "DOUBLE-BUFFER", &dummy, &x11disp->xdbe.eventbase, &x11disp->xdbe.errorbase) ; if (isSupported) { isSupported = XdbeQueryExtension(x11disp->sys_display, &major, &minor) ; if (isSupported) { x11disp->xdbe.isSupported = true ; x11disp->xdbe.version_major = (uint16_t) major ; x11disp->xdbe.version_minor = (uint16_t) minor ; } } isSupported = XQueryExtension(x11disp->sys_display, "RANDR", &dummy, &x11disp->xrandr.eventbase, &x11disp->xrandr.errorbase) ; if (isSupported) { isSupported = XRRQueryVersion(x11disp->sys_display, &major, &minor) ; if (isSupported) { x11disp->xrandr.isSupported = true ; x11disp->xrandr.version_major = (uint16_t) major ; x11disp->xrandr.version_minor = (uint16_t) minor ; // prepare receiving events for (int i = ScreenCount(x11disp->sys_display); (--i) >= 0 ;) { XRRSelectInput(x11disp->sys_display, RootWindow(x11disp->sys_display,i), RRScreenChangeNotifyMask) ; } } } isSupported = XQueryExtension(x11disp->sys_display, "RENDER", &dummy, &x11disp->xrender.eventbase, &x11disp->xrender.errorbase) ; if (isSupported) { isSupported = XRenderQueryVersion(x11disp->sys_display, &major, &minor) ; if (isSupported) { x11disp->xrender.isSupported = true ; x11disp->xrender.version_major = (uint16_t) major ; x11disp->xrender.version_minor = (uint16_t) minor ; } } return 0 ; }
bool x11_init(XRESOURCES* res, CFG* config){ Window root; XSetWindowAttributes window_attributes; unsigned width, height; Atom wm_state_fullscreen; int xdbe_major, xdbe_minor; XTextProperty window_name; pid_t pid = getpid(); //allocate some structures XSizeHints* size_hints = XAllocSizeHints(); XWMHints* wm_hints = XAllocWMHints(); XClassHint* class_hints = XAllocClassHint(); if(!size_hints || !wm_hints || !class_hints){ fprintf(stderr, "Failed to allocate X data structures\n"); return false; } //x data initialization res->display = XOpenDisplay(NULL); if(!(res->display)){ fprintf(stderr, "Failed to open display\n"); XFree(size_hints); XFree(wm_hints); XFree(class_hints); return false; } if(config->double_buffer){ config->double_buffer = (XdbeQueryExtension(res->display, &xdbe_major, &xdbe_minor) != 0); } else{ config->double_buffer = false; } errlog(config, LOG_INFO, "Double buffering %s\n", config->double_buffer ? "enabled":"disabled"); res->screen = DefaultScreen(res->display); root = RootWindow(res->display, res->screen); //start xft if(!XftInit(NULL)){ fprintf(stderr, "Failed to initialize Xft\n"); XFree(size_hints); XFree(wm_hints); XFree(class_hints); return false; } //set up colors res->text_color = colorspec_parse(config->text_color, res->display, res->screen); res->bg_color = colorspec_parse(config->bg_color, res->display, res->screen); res->debug_color = colorspec_parse(config->debug_color, res->display, res->screen); //set up window params window_attributes.background_pixel = res->bg_color.pixel; window_attributes.cursor = None; window_attributes.event_mask = ExposureMask | KeyPressMask | ButtonPressMask | StructureNotifyMask; width = DisplayWidth(res->display, res->screen); height = DisplayHeight(res->display, res->screen); //create window res->main = XCreateWindow(res->display, root, 0, 0, width, height, 0, CopyFromParent, InputOutput, CopyFromParent, CWBackPixel | CWCursor | CWEventMask, &window_attributes); //set window properties if(XStringListToTextProperty(&(config->window_name), 1, &window_name) == 0){ fprintf(stderr, "Failed to create string list, aborting\n"); return false; } wm_hints->flags = 0; class_hints->res_name = "xecho"; class_hints->res_class = "xecho"; XSetWMProperties(res->display, res->main, &window_name, NULL, NULL, 0, NULL, wm_hints, class_hints); XFree(window_name.value); XFree(size_hints); XFree(wm_hints); XFree(class_hints); //set fullscreen mode if(!config->windowed){ wm_state_fullscreen = XInternAtom(res->display, "_NET_WM_STATE_FULLSCREEN", False); XChangeProperty(res->display, res->main, XInternAtom(res->display, "_NET_WM_STATE", False), XA_ATOM, 32, PropModeReplace, (unsigned char*) &wm_state_fullscreen, 1); } XChangeProperty(res->display, res->main, XInternAtom(res->display, "_NET_WM_PID", False), XA_CARDINAL, 32, PropModeReplace, (unsigned char*)&pid, 1); //allocate back drawing buffer if(config->double_buffer){ res->back_buffer = XdbeAllocateBackBufferName(res->display, res->main, XdbeBackground); } //make xft drawable from window res->drawable = XftDrawCreate(res->display, (config->double_buffer?res->back_buffer:res->main), DefaultVisual(res->display, res->screen), DefaultColormap(res->display, res->screen)); if(!res->drawable){ fprintf(stderr, "Failed to allocate drawable\n"); return false; } //register for WM_DELETE_WINDOW messages res->wm_delete = XInternAtom(res->display, "WM_DELETE_WINDOW", False); XSetWMProtocols(res->display, res->main, &(res->wm_delete), 1); //map window XMapRaised(res->display, res->main); //get x socket fds if(!xfd_add(&(res->xfds), XConnectionNumber(res->display))){ fprintf(stderr, "Failed to allocate xfd memory\n"); return false; } if(XAddConnectionWatch(res->display, xconn_watch, (void*)(&(res->xfds))) == 0){ fprintf(stderr, "Failed to register connection watch procedure\n"); return false; } return true; }