void XWaylandManager::setupVisualAndColormap() { xcb_depth_iterator_t depthIterator = xcb_screen_allowed_depths_iterator(Xcb::screen()); xcb_visualtype_t *visualType = Q_NULLPTR; xcb_visualtype_iterator_t visualTypeIterator; while (depthIterator.rem > 0) { if (depthIterator.data->depth == 32) { visualTypeIterator = xcb_depth_visuals_iterator(depthIterator.data); visualType = visualTypeIterator.data; break; } xcb_depth_next(&depthIterator); } if (!visualType) { qCDebug(XWAYLAND) << "No 32-bit visualtype"; return; } m_visualId = visualType->visual_id; m_colorMap = xcb_generate_id(Xcb::connection()); xcb_create_colormap(Xcb::connection(), XCB_COLORMAP_ALLOC_NONE, m_colorMap, Xcb::rootWindow(), m_visualId); }
void createColorMap() { /* Create XID's for colormap and window */ colormap = xcb_generate_id(connection); window = xcb_generate_id(connection); /* Create colormap */ xcb_create_colormap( connection, XCB_COLORMAP_ALLOC_NONE, colormap, screen->root, visualID); }
/* * Initialize yabar */ void ya_init() { signal(SIGTERM, ya_sighandler); signal(SIGINT, ya_sighandler); signal(SIGKILL, ya_sighandler); signal(SIGHUP, ya_sighandler); ya.depth = 32; ya.c = xcb_connect(NULL, NULL); ya.scr = xcb_setup_roots_iterator(xcb_get_setup(ya.c)).data; ya.visualtype = ya_get_visualtype(); if (ya.visualtype == NULL) { // if depth=32 not found, fallback to depth=24 ya.depth = 24; ya.visualtype = ya_get_visualtype(); } ya.colormap = xcb_generate_id(ya.c); xcb_create_colormap(ya.c, XCB_COLORMAP_ALLOC_NONE, ya.colormap, ya.scr->root, ya.visualtype->visual_id); const xcb_query_extension_reply_t *ya_reply; ya_reply = xcb_get_extension_data(ya.c, &xcb_randr_id); if (ya_reply->present) { ya.gen_flag |= GEN_RANDR; ya_init_randr(); } #ifdef YA_INTERNAL_EWMH ya.ewmh = malloc(sizeof(xcb_ewmh_connection_t)); if (xcb_ewmh_init_atoms_replies(ya.ewmh, xcb_ewmh_init_atoms(ya.c, ya.ewmh), NULL)==0) { fprintf(stderr, "Cannot use EWMH\n"); //Should exit program or not? //To be decided. } ya.lstwin = XCB_NONE; uint32_t evm = XCB_EVENT_MASK_PROPERTY_CHANGE; xcb_change_window_attributes(ya.c, ya.curwin, XCB_CW_EVENT_MASK, &evm); xcb_change_window_attributes(ya.c, ya.scr->root, XCB_CW_EVENT_MASK, &evm); xcb_get_property_cookie_t prop_ck = xcb_ewmh_get_active_window(ya.ewmh, 0); xcb_ewmh_get_active_window_reply(ya.ewmh, prop_ck, &ya.curwin, NULL); xcb_get_property_cookie_t ws_ck = xcb_ewmh_get_current_desktop(ya.ewmh, 0); xcb_ewmh_get_current_desktop_reply(ya.ewmh, ws_ck, &ya.curws, NULL); //fprintf(stderr, "WINNN = %x DESK= %x\n", ya.curwin, ya.curws); #endif //YA_INTERNAL_EWMH ya_config_parse(); }
GlxContext::GlxContext(GlxContext* shared) : m_window (0), m_context (NULL), m_ownsWindow(true) { // Open a connection with the X server m_display = OpenDisplay(); m_connection = XGetXCBConnection(m_display); xcb_screen_t* screen = XCBScreenOfDisplay(m_connection, DefaultScreen(m_display)); // Choose the visual according to the context settings XVisualInfo visualInfo = selectBestVisual(m_display, VideoMode::getDesktopMode().bitsPerPixel, ContextSettings()); // Define the window attributes xcb_colormap_t colormap = xcb_generate_id(m_connection); xcb_create_colormap(m_connection, XCB_COLORMAP_ALLOC_NONE, colormap, screen->root, visualInfo.visualid); const uint32_t value_list[] = {colormap}; // Create a dummy window (disabled and hidden) m_window = xcb_generate_id(m_connection); xcb_create_window( m_connection, static_cast<uint8_t>(visualInfo.depth), m_window, screen->root, 0, 0, 1, 1, 0, XCB_WINDOW_CLASS_INPUT_OUTPUT, visualInfo.visualid, XCB_CW_COLORMAP, value_list ); // Create the context createContext(shared, VideoMode::getDesktopMode().bitsPerPixel, ContextSettings()); }
bool GlxBackend::initBuffer() { if (!initFbConfig()) return false; if (overlayWindow()->create()) { xcb_connection_t * const c = connection(); // Try to create double-buffered window in the overlay xcb_visualid_t visual; glXGetFBConfigAttrib(display(), fbconfig, GLX_VISUAL_ID, (int *) &visual); if (!visual) { qCCritical(KWIN_CORE) << "The GLXFBConfig does not have an associated X visual"; return false; } xcb_colormap_t colormap = xcb_generate_id(c); xcb_create_colormap(c, false, colormap, rootWindow(), visual); const QSize size = screens()->size(); window = xcb_generate_id(c); xcb_create_window(c, visualDepth(visual), window, overlayWindow()->window(), 0, 0, size.width(), size.height(), 0, XCB_WINDOW_CLASS_INPUT_OUTPUT, visual, XCB_CW_COLORMAP, &colormap); glxWindow = glXCreateWindow(display(), fbconfig, window, NULL); overlayWindow()->setup(window); } else { qCCritical(KWIN_CORE) << "Failed to create overlay window"; return false; } return true; }
struct rtb_window * window_impl_open(struct rutabaga *rtb, int w, int h, const char *title, intptr_t parent) { struct xcb_rutabaga *xrtb = (void *) rtb; struct xrtb_window *self; Display *dpy; xcb_connection_t *xcb_conn; int default_screen; GLXFBConfig *fb_configs, fb_config; XVisualInfo *visual; int nfb_configs; uint32_t event_mask = XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_VISIBILITY_CHANGE | XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE | XCB_EVENT_MASK_POINTER_MOTION | XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_LEAVE_WINDOW | XCB_EVENT_MASK_KEY_PRESS | XCB_EVENT_MASK_KEY_RELEASE | XCB_EVENT_MASK_KEYMAP_STATE; uint32_t value_mask = XCB_CW_BORDER_PIXEL | XCB_CW_BACK_PIXMAP | XCB_CW_BIT_GRAVITY | XCB_CW_EVENT_MASK | XCB_CW_COLORMAP; uint32_t value_list[6]; xcb_colormap_t colormap; xcb_void_cookie_t ck_window, ck_map; xcb_generic_error_t *err; assert(rtb); assert(h > 0); assert(w > 0); if (!(self = calloc(1, sizeof(*self)))) goto err_malloc; self->xrtb = xrtb; dpy = xrtb->dpy; xcb_conn = xrtb->xcb_conn; default_screen = DefaultScreen(dpy); self->screen = find_xcb_screen(xcb_conn, default_screen); if (!self->screen) { ERR("couldn't find XCB screen\n"); goto err_screen; } /** * gl configuration */ fb_configs = glXGetFBConfigs(dpy, default_screen, &nfb_configs); if (!fb_configs || !nfb_configs) { ERR("no GL configurations, bailing out\n"); goto err_gl_config; } fb_config = find_reasonable_fb_config(dpy, xcb_conn, fb_configs, nfb_configs, 0); if (!fb_config) { ERR("no reasonable GL configurations, bailing out\n"); goto err_gl_config; } visual = glXGetVisualFromFBConfig(dpy, fb_config); self->gl_ctx = new_gl_context(dpy, fb_config); if (!self->gl_ctx) { ERR("couldn't create GLX context\n"); goto err_gl_ctx; } /** * window setup */ colormap = xcb_generate_id(xcb_conn); self->xcb_win = xcb_generate_id(xcb_conn); xcb_create_colormap( xcb_conn, XCB_COLORMAP_ALLOC_NONE, colormap, self->screen->root, visual->visualid); value_list[0] = 0; value_list[1] = 0; value_list[2] = XCB_GRAVITY_STATIC; value_list[3] = event_mask; value_list[4] = colormap; value_list[5] = 0; ck_window = xcb_create_window_checked( xcb_conn, visual->depth, self->xcb_win, parent ? (xcb_window_t) parent : self->screen->root, 0, 0, w, h, 0, XCB_WINDOW_CLASS_INPUT_OUTPUT, visual->visualid, value_mask, value_list); free(visual); if ((err = xcb_request_check(xcb_conn, ck_window))) { ERR("can't create XCB window: %d\n", err->error_code); goto err_xcb_win; } get_dpi(dpy, default_screen, &self->dpi.x, &self->dpi.y); self->gl_win = glXCreateWindow(dpy, fb_config, self->xcb_win, 0); if (!self->gl_win) { ERR("couldn't create GL window\n"); goto err_gl_win; } if (set_xprop(xcb_conn, self->xcb_win, XCB_ATOM_WM_NAME, title)) set_xprop(xcb_conn, self->xcb_win, XCB_ATOM_WM_NAME, "oh no"); self->gl_draw = self->gl_win; if (!glXMakeContextCurrent( dpy, self->gl_draw, self->gl_draw, self->gl_ctx)) { ERR("couldn't activate GLX context\n"); goto err_gl_make_current; } ck_map = xcb_map_window_checked(xcb_conn, self->xcb_win); if ((err = xcb_request_check(xcb_conn, ck_map))) { ERR("can't map XCB window: %d\n", err->error_code); goto err_win_map; } if (parent) raise_window(xcb_conn, self->xcb_win); else xcb_icccm_set_wm_protocols(xcb_conn, self->xcb_win, xrtb->atoms.wm_protocols, 1, &xrtb->atoms.wm_delete_window); free(fb_configs); uv_mutex_init(&self->lock); return RTB_WINDOW(self); err_win_map: err_gl_make_current: err_gl_win: xcb_destroy_window(xcb_conn, self->xcb_win); err_xcb_win: glXDestroyContext(dpy, self->gl_ctx); err_gl_ctx: err_gl_config: free(fb_configs); err_screen: free(self); err_malloc: return NULL; }
/** * Probe the X server. */ static int Open(vout_display_t *vd, const vout_display_cfg_t *cfg, video_format_t *fmtp, vlc_video_context *ctx) { vlc_object_t *obj = VLC_OBJECT(vd); vout_display_sys_t *sys = vlc_obj_malloc(obj, sizeof (*sys)); if (unlikely(sys == NULL)) return VLC_ENOMEM; vd->sys = sys; /* Connect to X */ xcb_connection_t *conn; const xcb_screen_t *screen; if (vlc_xcb_parent_Create(vd, cfg, &conn, &screen) == NULL) return VLC_EGENERIC; sys->conn = conn; sys->root = screen->root; sys->format.argb = 0; sys->format.alpha = 0; if (!CheckRender(vd, conn)) goto error; xcb_render_query_pict_formats_cookie_t pic_fmt_ck = xcb_render_query_pict_formats(conn); xcb_render_query_pict_formats_reply_t *pic_fmt_r = xcb_render_query_pict_formats_reply(conn, pic_fmt_ck, NULL); if (pic_fmt_r == NULL) goto error; const xcb_setup_t *setup = xcb_get_setup(conn); const xcb_render_pictforminfo_t *const pic_fmts = xcb_render_query_pict_formats_formats(pic_fmt_r); xcb_visualid_t visual = 0; for (unsigned i = 0; i < pic_fmt_r->num_formats; i++) { const xcb_render_pictforminfo_t *const pic_fmt = pic_fmts + i; const xcb_render_directformat_t *const d = &pic_fmt->direct; if (pic_fmt->depth == 8 && pic_fmt->direct.alpha_mask == 0xff) { /* Alpha mask format */ sys->format.alpha = pic_fmt->id; continue; } xcb_visualid_t vid = FindVisual(setup, screen, pic_fmt_r, pic_fmt->id); if (vid == 0) continue; /* Use only ARGB for now. 32-bits is guaranteed to work. */ if (pic_fmt->depth != 32) continue; vlc_fourcc_t chroma = ParseFormat(setup, pic_fmt); if (chroma == 0) continue; fmtp->i_chroma = chroma; fmtp->i_rmask = ((uint32_t)d->red_mask) << d->red_shift; fmtp->i_gmask = ((uint32_t)d->green_mask) << d->green_shift; fmtp->i_bmask = ((uint32_t)d->blue_mask) << d->blue_shift; sys->format.argb = pic_fmt->id; visual = vid; } free(pic_fmt_r); if (unlikely(sys->format.argb == 0 || sys->format.alpha == 0)) goto error; /* Buggy server */ msg_Dbg(obj, "using RENDER picture format %u", sys->format.argb); msg_Dbg(obj, "using X11 visual 0x%"PRIx32, visual); char *filter = var_InheritString(obj, "x11-render-filter"); if (filter != NULL) { msg_Dbg(obj, "using filter \"%s\"", filter); sys->filter = ToCharset("ISO 8859-1", filter, &(size_t){ 0 }); free(filter); } else sys->filter = NULL; sys->drawable.source = xcb_generate_id(conn); sys->drawable.crop = xcb_generate_id(conn); sys->drawable.scale = xcb_generate_id(conn); sys->drawable.subpic = xcb_generate_id(conn); sys->drawable.alpha = xcb_generate_id(conn); sys->drawable.dest = xcb_generate_id(conn); sys->picture.source = xcb_generate_id(conn); sys->picture.crop = xcb_generate_id(conn); sys->picture.scale = xcb_generate_id(conn); sys->picture.subpic = xcb_generate_id(conn); sys->picture.alpha = xcb_generate_id(conn); sys->picture.dest = xcb_generate_id(conn); sys->gc = xcb_generate_id(conn); if (XCB_shm_Check(obj, conn)) sys->segment = xcb_generate_id(conn); else sys->segment = 0; xcb_colormap_t cmap = xcb_generate_id(conn); uint32_t cw_mask = XCB_CW_BACK_PIXEL | XCB_CW_BORDER_PIXEL | XCB_CW_EVENT_MASK | XCB_CW_COLORMAP; const uint32_t cw_list[] = { /* XCB_CW_BACK_PIXEL */ screen->black_pixel, /* XCB_CW_BORDER_PIXEL */ screen->black_pixel, /* XCB_CW_EVENT_MASK */ 0, /* XCB_CW_COLORMAP */ cmap, }; xcb_create_colormap(conn, XCB_COLORMAP_ALLOC_NONE, cmap, screen->root, visual); xcb_create_pixmap(conn, 32, sys->drawable.source, screen->root, vd->source.i_width, vd->source.i_height); xcb_create_gc(conn, sys->gc, sys->drawable.source, 0, NULL); xcb_create_window(conn, 32, sys->drawable.dest, cfg->window->handle.xid, 0, 0, cfg->display.width, cfg->display.height, 0, XCB_WINDOW_CLASS_INPUT_OUTPUT, visual, cw_mask, cw_list); xcb_render_create_picture(conn, sys->picture.source, sys->drawable.source, sys->format.argb, 0, NULL); xcb_render_create_picture(conn, sys->picture.dest, sys->drawable.dest, sys->format.argb, 0, NULL); CreateBuffers(vd, cfg); xcb_map_window(conn, sys->drawable.dest); sys->spu_chromas[0] = fmtp->i_chroma; sys->spu_chromas[1] = 0; vd->info.subpicture_chromas = sys->spu_chromas; vd->prepare = Prepare; vd->display = Display; vd->control = Control; (void) ctx; return VLC_SUCCESS; error: xcb_disconnect(conn); return VLC_EGENERIC; }
/** * Probe the X server. */ static int Open (vlc_object_t *obj) { vout_display_t *vd = (vout_display_t *)obj; vout_display_sys_t *sys = malloc (sizeof (*sys)); if (unlikely(sys == NULL)) return VLC_ENOMEM; vd->sys = sys; sys->pool = NULL; /* Get window, connect to X server */ xcb_connection_t *conn; const xcb_screen_t *scr; uint16_t width, height; sys->embed = XCB_parent_Create (vd, &conn, &scr, &width, &height); if (sys->embed == NULL) { free (sys); return VLC_EGENERIC; } sys->conn = conn; const xcb_setup_t *setup = xcb_get_setup (conn); /* Determine our pixel format */ video_format_t fmt_pic; xcb_visualid_t vid; sys->depth = 0; for (const xcb_format_t *fmt = xcb_setup_pixmap_formats (setup), *end = fmt + xcb_setup_pixmap_formats_length (setup); fmt < end; fmt++) { if (fmt->depth <= sys->depth) continue; /* no better than earlier format */ fmt_pic = vd->fmt; /* Check that the pixmap format is supported by VLC. */ switch (fmt->depth) { case 32: if (fmt->bits_per_pixel != 32) continue; fmt_pic.i_chroma = VLC_CODEC_ARGB; break; case 24: if (fmt->bits_per_pixel == 32) fmt_pic.i_chroma = VLC_CODEC_RGB32; else if (fmt->bits_per_pixel == 24) fmt_pic.i_chroma = VLC_CODEC_RGB24; else continue; break; case 16: if (fmt->bits_per_pixel != 16) continue; fmt_pic.i_chroma = VLC_CODEC_RGB16; break; case 15: if (fmt->bits_per_pixel != 16) continue; fmt_pic.i_chroma = VLC_CODEC_RGB15; break; case 8: if (fmt->bits_per_pixel != 8) continue; fmt_pic.i_chroma = VLC_CODEC_RGB8; break; default: continue; } /* Byte sex is a non-issue for 8-bits. It can be worked around with * RGB masks for 24-bits. Too bad for 15-bits and 16-bits. */ if (fmt->bits_per_pixel == 16 && setup->image_byte_order != ORDER) continue; /* Make sure the X server is sane */ assert (fmt->bits_per_pixel > 0); if (unlikely(fmt->scanline_pad % fmt->bits_per_pixel)) continue; /* Check that the selected screen supports this depth */ const xcb_depth_t *d = FindDepth (scr, fmt->depth); if (d == NULL) continue; /* Find a visual type for the selected depth */ const xcb_visualtype_t *vt = xcb_depth_visuals (d); /* First try True Color class */ for (int i = xcb_depth_visuals_length (d); i > 0; i--) { if (vt->_class == XCB_VISUAL_CLASS_TRUE_COLOR) { fmt_pic.i_rmask = vt->red_mask; fmt_pic.i_gmask = vt->green_mask; fmt_pic.i_bmask = vt->blue_mask; found_visual: vid = vt->visual_id; msg_Dbg (vd, "using X11 visual ID 0x%"PRIx32, vid); sys->depth = fmt->depth; msg_Dbg (vd, " %"PRIu8" bits depth", sys->depth); msg_Dbg (vd, " %"PRIu8" bits per pixel", fmt->bits_per_pixel); msg_Dbg (vd, " %"PRIu8" bits line pad", fmt->scanline_pad); goto found_format; } vt++; } /* Then try Static Gray class */ if (fmt->depth != 8) continue; vt = xcb_depth_visuals (d); for (int i = xcb_depth_visuals_length (d); i > 0 && !vid; i--) { if (vt->_class == XCB_VISUAL_CLASS_STATIC_GRAY) { fmt_pic.i_chroma = VLC_CODEC_GREY; goto found_visual; } vt++; } } msg_Err (obj, "no supported pixel format & visual"); goto error; found_format:; /* Create colormap (needed to select non-default visual) */ xcb_colormap_t cmap; if (vid != scr->root_visual) { cmap = xcb_generate_id (conn); xcb_create_colormap (conn, XCB_COLORMAP_ALLOC_NONE, cmap, scr->root, vid); } else cmap = scr->default_colormap; /* Create window */ sys->window = xcb_generate_id (conn); sys->gc = xcb_generate_id (conn); xcb_pixmap_t pixmap = xcb_generate_id (conn); { const uint32_t mask = XCB_CW_BACK_PIXMAP | XCB_CW_BACK_PIXEL | XCB_CW_BORDER_PIXMAP | XCB_CW_BORDER_PIXEL | XCB_CW_EVENT_MASK | XCB_CW_COLORMAP; const uint32_t values[] = { /* XCB_CW_BACK_PIXMAP */ pixmap, /* XCB_CW_BACK_PIXEL */ scr->black_pixel, /* XCB_CW_BORDER_PIXMAP */ pixmap, /* XCB_CW_BORDER_PIXEL */ scr->black_pixel, /* XCB_CW_EVENT_MASK */ XCB_EVENT_MASK_VISIBILITY_CHANGE, /* XCB_CW_COLORMAP */ cmap, }; xcb_void_cookie_t c; xcb_create_pixmap (conn, sys->depth, pixmap, scr->root, 1, 1); c = xcb_create_window_checked (conn, sys->depth, sys->window, sys->embed->handle.xid, 0, 0, width, height, 0, XCB_WINDOW_CLASS_INPUT_OUTPUT, vid, mask, values); xcb_map_window (conn, sys->window); /* Create graphic context (I wonder why the heck do we need this) */ xcb_create_gc (conn, sys->gc, sys->window, 0, NULL); if (XCB_error_Check (vd, conn, "cannot create X11 window", c)) goto error; } msg_Dbg (vd, "using X11 window %08"PRIx32, sys->window); msg_Dbg (vd, "using X11 graphic context %08"PRIx32, sys->gc); sys->cursor = XCB_cursor_Create (conn, scr); sys->visible = false; if (XCB_shm_Check (obj, conn)) { sys->seg_base = xcb_generate_id (conn); for (unsigned i = 1; i < MAX_PICTURES; i++) xcb_generate_id (conn); } else sys->seg_base = 0; /* Setup vout_display_t once everything is fine */ vd->info.has_pictures_invalid = true; vd->info.has_event_thread = true; vd->fmt = fmt_pic; vd->pool = Pool; vd->prepare = NULL; vd->display = Display; vd->control = Control; vd->manage = Manage; /* */ bool is_fullscreen = vd->cfg->is_fullscreen; if (is_fullscreen && vout_window_SetFullScreen (sys->embed, true)) is_fullscreen = false; vout_display_SendEventFullscreen (vd, is_fullscreen); vout_display_SendEventDisplaySize (vd, width, height, is_fullscreen); return VLC_SUCCESS; error: Close (obj); return VLC_EGENERIC; }
/** * Probe the X server. */ static int Open (vlc_object_t *obj) { vout_display_t *vd = (vout_display_t *)obj; vout_display_sys_t *p_sys = malloc (sizeof (*p_sys)); if (p_sys == NULL) return VLC_ENOMEM; vd->sys = p_sys; p_sys->pool = NULL; /* Get window, connect to X server */ const xcb_screen_t *scr; p_sys->embed = GetWindow (vd, &p_sys->conn, &scr, &(uint8_t){ 0 }); if (p_sys->embed == NULL) { free (p_sys); return VLC_EGENERIC; } const xcb_setup_t *setup = xcb_get_setup (p_sys->conn); p_sys->byte_order = setup->image_byte_order; /* Determine our pixel format */ xcb_visualid_t vid = 0; p_sys->depth = 0; for (const xcb_format_t *fmt = xcb_setup_pixmap_formats (setup), *end = fmt + xcb_setup_pixmap_formats_length (setup); fmt < end; fmt++) { if (fmt->depth <= p_sys->depth) continue; /* no better than earlier format */ video_format_t fmt_pic = vd->fmt; /* Check that the pixmap format is supported by VLC. */ switch (fmt->depth) { case 32: if (fmt->bits_per_pixel != 32) continue; #ifdef FIXED_VLC_RGBA_MASK fmt_pic.i_chroma = VLC_CODEC_RGBA; break; #else msg_Dbg (vd, "X11 visual with alpha-channel not supported"); continue; #endif case 24: if (fmt->bits_per_pixel == 32) fmt_pic.i_chroma = VLC_CODEC_RGB32; else if (fmt->bits_per_pixel == 24) fmt_pic.i_chroma = VLC_CODEC_RGB24; else continue; break; case 16: if (fmt->bits_per_pixel != 16) continue; fmt_pic.i_chroma = VLC_CODEC_RGB16; break; case 15: if (fmt->bits_per_pixel != 16) continue; fmt_pic.i_chroma = VLC_CODEC_RGB15; break; case 8: if (fmt->bits_per_pixel != 8) continue; fmt_pic.i_chroma = VLC_CODEC_RGB8; break; default: continue; } /* VLC pads lines to 16 pixels internally */ if ((fmt->bits_per_pixel << 4) % fmt->scanline_pad) continue; /* Byte sex is a non-issue for 8-bits. It can be worked around with * RGB masks for 24-bits. Too bad for 15-bits and 16-bits. */ if (fmt->bits_per_pixel == 16 && setup->image_byte_order != ORDER) continue; /* Check that the selected screen supports this depth */ const xcb_depth_t *d = FindDepth (scr, fmt->depth); if (d == NULL) continue; /* Find a visual type for the selected depth */ const xcb_visualtype_t *vt = xcb_depth_visuals (d); /* First try True Color class */ for (int i = xcb_depth_visuals_length (d); i > 0; i--) { if (vt->_class == XCB_VISUAL_CLASS_TRUE_COLOR) { fmt_pic.i_rmask = vt->red_mask; fmt_pic.i_gmask = vt->green_mask; fmt_pic.i_bmask = vt->blue_mask; goto found_visual; } vt++; } /* Then try Static Gray class */ if (fmt->depth == 8) for (int i = xcb_depth_visuals_length (d); i > 0 && !vid; i--) { if (vt->_class == XCB_VISUAL_CLASS_STATIC_GRAY) goto found_grey; vt++; } continue; /* Fail: unusable pixel format */ found_grey: fmt_pic.i_chroma = VLC_CODEC_GREY; found_visual: p_sys->bpp = fmt->bits_per_pixel; p_sys->pad = fmt->scanline_pad; p_sys->depth = fmt->depth; vd->fmt = fmt_pic; vid = vt->visual_id; } if (!vid) { msg_Err (obj, "no supported pixel format & visual"); goto error; } msg_Dbg (vd, "using X11 visual ID 0x%"PRIx32, vid); msg_Dbg (vd, " %"PRIu8" bits depth", p_sys->depth); msg_Dbg (vd, " %"PRIu8" bits per pixel", p_sys->bpp); msg_Dbg (vd, " %"PRIu8" bits line pad", p_sys->pad); /* Create colormap (needed to select non-default visual) */ xcb_colormap_t cmap; if (vid != scr->root_visual) { cmap = xcb_generate_id (p_sys->conn); xcb_create_colormap (p_sys->conn, XCB_COLORMAP_ALLOC_NONE, cmap, scr->root, vid); } else cmap = scr->default_colormap; /* Create window */ unsigned width, height; if (GetWindowSize (p_sys->embed, p_sys->conn, &width, &height)) goto error; p_sys->window = xcb_generate_id (p_sys->conn); p_sys->gc = xcb_generate_id (p_sys->conn); xcb_pixmap_t pixmap = xcb_generate_id (p_sys->conn); { const uint32_t mask = XCB_CW_BACK_PIXMAP | XCB_CW_BACK_PIXEL | XCB_CW_BORDER_PIXMAP | XCB_CW_BORDER_PIXEL | XCB_CW_EVENT_MASK | XCB_CW_COLORMAP; const uint32_t values[] = { /* XCB_CW_BACK_PIXMAP */ pixmap, /* XCB_CW_BACK_PIXEL */ scr->black_pixel, /* XCB_CW_BORDER_PIXMAP */ pixmap, /* XCB_CW_BORDER_PIXEL */ scr->black_pixel, /* XCB_CW_EVENT_MASK */ XCB_EVENT_MASK_VISIBILITY_CHANGE, /* XCB_CW_COLORMAP */ cmap, }; xcb_void_cookie_t c; xcb_create_pixmap (p_sys->conn, p_sys->depth, pixmap, scr->root, 1, 1); c = xcb_create_window_checked (p_sys->conn, p_sys->depth, p_sys->window, p_sys->embed->handle.xid, 0, 0, width, height, 0, XCB_WINDOW_CLASS_INPUT_OUTPUT, vid, mask, values); xcb_map_window (p_sys->conn, p_sys->window); /* Create graphic context (I wonder why the heck do we need this) */ xcb_create_gc (p_sys->conn, p_sys->gc, p_sys->window, 0, NULL); if (CheckError (vd, p_sys->conn, "cannot create X11 window", c)) goto error; } msg_Dbg (vd, "using X11 window %08"PRIx32, p_sys->window); msg_Dbg (vd, "using X11 graphic context %08"PRIx32, p_sys->gc); p_sys->cursor = CreateBlankCursor (p_sys->conn, scr); p_sys->visible = false; CheckSHM (obj, p_sys->conn, &p_sys->shm); /* */ vout_display_info_t info = vd->info; info.has_pictures_invalid = true; /* Setup vout_display_t once everything is fine */ vd->info = info; vd->pool = Pool; vd->prepare = NULL; vd->display = Display; vd->control = Control; vd->manage = Manage; /* */ vout_display_SendEventFullscreen (vd, false); vout_display_SendEventDisplaySize (vd, width, height, false); return VLC_SUCCESS; error: Close (obj); return VLC_EGENERIC; }
extern bool gl_platform_init_swapchain(struct gs_swap_chain *swap) { Display *display = swap->device->plat->display; xcb_connection_t *xcb_conn = XGetXCBConnection(display); xcb_window_t wid = xcb_generate_id(xcb_conn); xcb_window_t parent = swap->info.window.id; xcb_get_geometry_reply_t *geometry = get_window_geometry(xcb_conn, parent); bool status = false; int screen_num; int visual; GLXFBConfig *fb_config; if (!geometry) goto fail_geometry_request; screen_num = get_screen_num_from_root(xcb_conn, geometry->root); if (screen_num == -1) { goto fail_screen; } /* ...fetch the best match... */ { int num_configs; fb_config = glXChooseFBConfig(display, screen_num, ctx_visual_attribs, &num_configs); if (!fb_config || !num_configs) { blog(LOG_ERROR, "Failed to find FBConfig!"); goto fail_fb_config; } } /* ...then fetch matching visual info for xcb. */ { int error = glXGetFBConfigAttrib(display, fb_config[0], GLX_VISUAL_ID, &visual); if (error) { blog(LOG_ERROR, "Bad call to GetFBConfigAttrib!"); goto fail_visual_id; } } xcb_colormap_t colormap = xcb_generate_id(xcb_conn); uint32_t mask = XCB_CW_BORDER_PIXEL | XCB_CW_COLORMAP; uint32_t mask_values[] = { 0, colormap, 0 }; xcb_create_colormap(xcb_conn, XCB_COLORMAP_ALLOC_NONE, colormap, parent, visual ); xcb_create_window( xcb_conn, 24 /* Hardcoded? */, wid, parent, 0, 0, geometry->width, geometry->height, 0, 0, visual, mask, mask_values ); swap->wi->config = fb_config[0]; swap->wi->window = wid; xcb_map_window(xcb_conn, wid); XFree(fb_config); status = true; goto success; fail_visual_id: XFree(fb_config); fail_fb_config: fail_screen: fail_geometry_request: success: free(geometry); return status; }
void GlxContext::createSurface(GlxContext* shared, unsigned int width, unsigned int height, unsigned int bitsPerPixel) { m_display = OpenDisplay(); m_connection = XGetXCBConnection(m_display); // Choose the visual according to the context settings XVisualInfo visualInfo = selectBestVisual(m_display, bitsPerPixel, m_settings); // Check if the shared context already exists and pbuffers are supported if (shared && (sfglx_ext_SGIX_pbuffer == sfglx_LOAD_SUCCEEDED)) { // There are no GLX versions prior to 1.0 int major = 0; int minor = 0; glXQueryVersion(m_display, &major, &minor); // Check if glXCreatePbuffer is available (requires GLX 1.3 or greater) bool hasCreatePbuffer = ((major > 1) || (minor >= 3)); if (hasCreatePbuffer) { // Get a GLXFBConfig that matches the visual GLXFBConfig* config = NULL; // We don't supply attributes to match against, since // the visual we are matching against was already // deemed suitable in selectBestVisual() int nbConfigs = 0; GLXFBConfig* configs = glXChooseFBConfig(m_display, DefaultScreen(m_display), NULL, &nbConfigs); for (int i = 0; configs && (i < nbConfigs); ++i) { XVisualInfo* visual = glXGetVisualFromFBConfig(m_display, configs[i]); if (!visual) continue; if (visual->visualid == visualInfo.visualid) { config = &configs[i]; break; } } if (config) { int attributes[] = { GLX_PBUFFER_WIDTH, static_cast<int>(width), GLX_PBUFFER_HEIGHT, static_cast<int>(height), 0, 0 }; m_pbuffer = glXCreatePbuffer(m_display, *config, attributes); updateSettingsFromVisualInfo(&visualInfo); XFree(configs); return; } if (configs) XFree(configs); } } // If pbuffers are not available we use a hidden window as the off-screen surface to draw to xcb_screen_t* screen = XCBScreenOfDisplay(m_connection, DefaultScreen(m_display)); // Define the window attributes xcb_colormap_t colormap = xcb_generate_id(m_connection); xcb_create_colormap(m_connection, XCB_COLORMAP_ALLOC_NONE, colormap, screen->root, visualInfo.visualid); const uint32_t value_list[] = {colormap}; // Create a dummy window (disabled and hidden) m_window = xcb_generate_id(m_connection); xcb_create_window( m_connection, static_cast<uint8_t>(visualInfo.depth), m_window, screen->root, 0, 0, width, height, 0, XCB_WINDOW_CLASS_INPUT_OUTPUT, visualInfo.visualid, XCB_CW_COLORMAP, value_list ); m_ownsWindow = true; updateSettingsFromWindow(); }
extern bool gl_platform_init_swapchain(struct gs_swap_chain *swap) { Display *display = swap->device->plat->display; struct gs_init_data *info = &swap->info; xcb_connection_t *xcb_conn = XGetXCBConnection(display); xcb_window_t wid = xcb_generate_id(xcb_conn); xcb_window_t parent = swap->info.window.id; xcb_get_geometry_reply_t *geometry = get_window_geometry(xcb_conn, parent); bool status = false; int screen_num; int visual; GLXFBConfig *fb_config; if (!geometry) goto fail_geometry_request; screen_num = get_screen_num_from_root(xcb_conn, geometry->root); if (screen_num == -1) { goto fail_screen; } /* NOTE: * So GLX is odd. You can have different extensions per screen, * not just per video card or visual. * * Because of this, it makes sense to call LoadGLX everytime * we open a frackin' window. In Windows, entry points can change * so it makes more sense there. Here, despite it virtually never * having the possibility of changing unless the user is intentionally * being an asshole to cause this behavior, we still have to give it * the correct screen num just out of good practice. *sigh* */ if (!gladLoadGLX(display, screen_num)) { blog(LOG_ERROR, "Unable to load GLX entry functions."); goto fail_load_glx; } /* Define our FBConfig hints for GLX... */ const int fb_attribs[] = { GLX_STENCIL_SIZE, get_stencil_format_bits(info->zsformat), GLX_DEPTH_SIZE, get_depth_format_bits(info->zsformat), GLX_BUFFER_SIZE, get_color_format_bits(info->format), GLX_DOUBLEBUFFER, true, GLX_X_RENDERABLE, true, None }; /* ...fetch the best match... */ { int num_configs; fb_config = glXChooseFBConfig(display, screen_num, fb_attribs, &num_configs); if (!fb_config || !num_configs) { blog(LOG_ERROR, "Failed to find FBConfig!"); goto fail_fb_config; } } /* ...then fetch matching visual info for xcb. */ { int error = glXGetFBConfigAttrib(display, fb_config[0], GLX_VISUAL_ID, &visual); if (error) { blog(LOG_ERROR, "Bad call to GetFBConfigAttrib!"); goto fail_visual_id; } } xcb_colormap_t colormap = xcb_generate_id(xcb_conn); uint32_t mask = XCB_CW_BORDER_PIXEL | XCB_CW_COLORMAP; uint32_t mask_values[] = { 0, colormap, 0 }; xcb_create_colormap(xcb_conn, XCB_COLORMAP_ALLOC_NONE, colormap, parent, visual ); xcb_create_window( xcb_conn, 24 /* Hardcoded? */, wid, parent, 0, 0, geometry->width, geometry->height, 0, 0, visual, mask, mask_values ); swap->wi->config = fb_config[0]; swap->wi->window = wid; xcb_map_window(xcb_conn, wid); XFree(fb_config); status = true; goto success; fail_visual_id: XFree(fb_config); fail_fb_config: fail_load_glx: fail_screen: fail_geometry_request: success: free(geometry); return status; }
int setup_and_run(Display *display, xcb_connection_t *connection, int default_screen, xcb_screen_t *screen) { int visualID = 0; /*Query framebuffer configurations */ GLXFBConfig *fb_configs = 0; int num_fb_configs = 0; fb_configs = glXGetFBConfigs(display, default_screen, &num_fb_configs); if (!fb_configs || num_fb_configs == 0) { fprintf(stderr, "glXGetFBConfigs failed\n"); return -1; } /* Select first framebuffer config and query visualID */ GLXFBConfig fb_config = fb_configs[0]; glXGetFBConfigAttrib(display, fb_config, GLX_VISUAL_ID, &visualID); GLXContext context; /* Create OpenGL context */ context = glXCreateNewContext(display, fb_config, GLX_RGBA_TYPE, 0, True); if (!context) { fprintf(stderr, "glXCreateNewContext failed\n"); return -1; } /* Create XID's for colormap and window */ xcb_colormap_t colormap = xcb_generate_id(connection); xcb_window_t window = xcb_generate_id(connection); /* Create colormap */ xcb_create_colormap( connection, XCB_COLORMAP_ALLOC_NONE, colormap, screen->root, visualID); /* Create window */ uint32_t eventmask = XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_KEY_PRESS; uint32_t valuelist[] = {eventmask, colormap, 0}; uint32_t valuemask = XCB_CW_EVENT_MASK | XCB_CW_COLORMAP; xcb_create_window( connection, XCB_COPY_FROM_PARENT, window, screen->root, 0, 0, window_width, window_height, 0, XCB_WINDOW_CLASS_INPUT_OUTPUT, visualID, valuemask, valuelist); /* NOTE: window must be mapped before glXMakeContextCurrent */ xcb_map_window(connection, window); /* Create GLX window */ GLXDrawable drawable = 0; GLXWindow glxwindow = glXCreateWindow(display, fb_config, window, 0); if (!glxwindow) { xcb_destroy_window(connection, window); glXDestroyContext(display, context); fprintf(stderr, "glXCreateWindow failed\n"); return -1; } drawable = glxwindow; /* make OpenGL context current */ #if 1 if (!glXMakeContextCurrent(display, drawable, drawable, context)) { xcb_destroy_window(connection, window); glXDestroyContext(display, context); fprintf(stderr, "glXMakeContextCurrent failed\n"); return -1; } #else if (!glXMakeCurrent(display, drawable, context)) { xcb_destroy_window(connection, window); glXDestroyContext(display, context); fprintf(stderr, "glXMakeContextCurrent failed\n"); return -1; } #endif /* run main loop */ int retval = main_loop (display, connection, screen, window, drawable); /* Cleanup */ glXDestroyWindow(display, glxwindow); xcb_destroy_window(connection, window); glXDestroyContext(display, context); return retval; }
/** Hello, this is main. * \param argc Who knows. * \param argv Who knows. * \return EXIT_SUCCESS I hope. */ int main(int argc, char **argv) { char *confpath = NULL; int xfd, i, opt; ssize_t cmdlen = 1; xdgHandle xdg; bool no_argb = false; xcb_generic_event_t *event; xcb_query_tree_cookie_t tree_c; static struct option long_options[] = { { "help", 0, NULL, 'h' }, { "version", 0, NULL, 'v' }, { "config", 1, NULL, 'c' }, { "check", 0, NULL, 'k' }, { "no-argb", 0, NULL, 'a' }, { NULL, 0, NULL, 0 } }; /* event loop watchers */ ev_io xio = { .fd = -1 }; ev_check xcheck; ev_prepare a_refresh; ev_signal sigint; ev_signal sigterm; ev_signal sighup; /* clear the globalconf structure */ p_clear(&globalconf, 1); globalconf.keygrabber = LUA_REFNIL; globalconf.mousegrabber = LUA_REFNIL; buffer_init(&globalconf.startup_errors); /* save argv */ for(i = 0; i < argc; i++) cmdlen += a_strlen(argv[i]) + 1; awesome_argv = p_new(char, cmdlen); a_strcpy(awesome_argv, cmdlen, argv[0]); for(i = 1; i < argc; i++) { a_strcat(awesome_argv, cmdlen, " "); a_strcat(awesome_argv, cmdlen, argv[i]); } /* Text won't be printed correctly otherwise */ setlocale(LC_CTYPE, ""); /* Get XDG basedir data */ xdgInitHandle(&xdg); /* init lua */ luaA_init(&xdg); /* check args */ while((opt = getopt_long(argc, argv, "vhkc:a", long_options, NULL)) != -1) switch(opt) { case 'v': eprint_version(); break; case 'h': exit_help(EXIT_SUCCESS); break; case 'k': if(!luaA_parserc(&xdg, confpath, false)) { fprintf(stderr, "✘ Configuration file syntax error.\n"); return EXIT_FAILURE; } else { fprintf(stderr, "✔ Configuration file syntax OK.\n"); return EXIT_SUCCESS; } case 'c': if(a_strlen(optarg)) confpath = a_strdup(optarg); else fatal("-c option requires a file name"); break; case 'a': no_argb = true; break; } globalconf.loop = ev_default_loop(EVFLAG_NOSIGFD); /* register function for signals */ ev_signal_init(&sigint, exit_on_signal, SIGINT); ev_signal_init(&sigterm, exit_on_signal, SIGTERM); ev_signal_init(&sighup, restart_on_signal, SIGHUP); ev_signal_start(globalconf.loop, &sigint); ev_signal_start(globalconf.loop, &sigterm); ev_signal_start(globalconf.loop, &sighup); ev_unref(globalconf.loop); ev_unref(globalconf.loop); ev_unref(globalconf.loop); struct sigaction sa = { .sa_handler = signal_fatal, .sa_flags = 0 }; sigemptyset(&sa.sa_mask); sigaction(SIGSEGV, &sa, 0); /* X stuff */ globalconf.connection = xcb_connect(NULL, &globalconf.default_screen); if(xcb_connection_has_error(globalconf.connection)) fatal("cannot open display"); globalconf.screen = xcb_aux_get_screen(globalconf.connection, globalconf.default_screen); /* FIXME The following two assignments were swapped on purpose */ if(!no_argb) globalconf.visual = a_default_visual(globalconf.screen); if(!globalconf.visual) globalconf.visual = a_argb_visual(globalconf.screen); globalconf.default_depth = a_visual_depth(globalconf.screen, globalconf.visual->visual_id); globalconf.default_cmap = globalconf.screen->default_colormap; if(globalconf.default_depth != globalconf.screen->root_depth) { // We need our own color map if we aren't using the default depth globalconf.default_cmap = xcb_generate_id(globalconf.connection); xcb_create_colormap(globalconf.connection, XCB_COLORMAP_ALLOC_NONE, globalconf.default_cmap, globalconf.screen->root, globalconf.visual->visual_id); } /* Prefetch all the extensions we might need */ xcb_prefetch_extension_data(globalconf.connection, &xcb_big_requests_id); xcb_prefetch_extension_data(globalconf.connection, &xcb_test_id); xcb_prefetch_extension_data(globalconf.connection, &xcb_randr_id); xcb_prefetch_extension_data(globalconf.connection, &xcb_xinerama_id); /* initialize dbus */ a_dbus_init(); /* Get the file descriptor corresponding to the X connection */ xfd = xcb_get_file_descriptor(globalconf.connection); ev_io_init(&xio, &a_xcb_io_cb, xfd, EV_READ); ev_io_start(globalconf.loop, &xio); ev_check_init(&xcheck, &a_xcb_check_cb); ev_check_start(globalconf.loop, &xcheck); ev_unref(globalconf.loop); ev_prepare_init(&a_refresh, &a_refresh_cb); ev_prepare_start(globalconf.loop, &a_refresh); ev_unref(globalconf.loop); /* Grab server */ xcb_grab_server(globalconf.connection); /* Make sure there are no pending events. Since we didn't really do anything * at all yet, we will just discard all events which we received so far. * The above GrabServer should make sure no new events are generated. */ xcb_aux_sync(globalconf.connection); while ((event = xcb_poll_for_event(globalconf.connection)) != NULL) { /* Make sure errors are printed */ uint8_t response_type = XCB_EVENT_RESPONSE_TYPE(event); if(response_type == 0) event_handle(event); p_delete(&event); } { const uint32_t select_input_val = XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT; /* This causes an error if some other window manager is running */ xcb_change_window_attributes(globalconf.connection, globalconf.screen->root, XCB_CW_EVENT_MASK, &select_input_val); } /* Need to xcb_flush to validate error handler */ xcb_aux_sync(globalconf.connection); /* Process all errors in the queue if any. There can be no events yet, so if * this function returns something, it must be an error. */ if (xcb_poll_for_event(globalconf.connection) != NULL) fatal("another window manager is already running"); /* Prefetch the maximum request length */ xcb_prefetch_maximum_request_length(globalconf.connection); /* check for xtest extension */ const xcb_query_extension_reply_t *xtest_query; xtest_query = xcb_get_extension_data(globalconf.connection, &xcb_test_id); globalconf.have_xtest = xtest_query->present; /* Allocate the key symbols */ globalconf.keysyms = xcb_key_symbols_alloc(globalconf.connection); xcb_get_modifier_mapping_cookie_t xmapping_cookie = xcb_get_modifier_mapping_unchecked(globalconf.connection); /* init atom cache */ atoms_init(globalconf.connection); /* init screens information */ screen_scan(); xutil_lock_mask_get(globalconf.connection, xmapping_cookie, globalconf.keysyms, &globalconf.numlockmask, &globalconf.shiftlockmask, &globalconf.capslockmask, &globalconf.modeswitchmask); /* do this only for real screen */ ewmh_init(); systray_init(); /* init spawn (sn) */ spawn_init(); /* The default GC is just a newly created associated with a window with * depth globalconf.default_depth */ xcb_window_t tmp_win = xcb_generate_id(globalconf.connection); globalconf.gc = xcb_generate_id(globalconf.connection); xcb_create_window(globalconf.connection, globalconf.default_depth, tmp_win, globalconf.screen->root, -1, -1, 1, 1, 0, XCB_COPY_FROM_PARENT, globalconf.visual->visual_id, XCB_CW_BACK_PIXEL | XCB_CW_BORDER_PIXEL | XCB_CW_COLORMAP, (const uint32_t []) { globalconf.screen->black_pixel, globalconf.screen->black_pixel, globalconf.default_cmap }); xcb_create_gc(globalconf.connection, globalconf.gc, tmp_win, XCB_GC_FOREGROUND | XCB_GC_BACKGROUND, (const uint32_t[]) { globalconf.screen->black_pixel, globalconf.screen->white_pixel }); xcb_destroy_window(globalconf.connection, tmp_win); /* Get the window tree associated to this screen */ tree_c = xcb_query_tree_unchecked(globalconf.connection, globalconf.screen->root); xcb_change_window_attributes(globalconf.connection, globalconf.screen->root, XCB_CW_EVENT_MASK, ROOT_WINDOW_EVENT_MASK); /* we will receive events, stop grabbing server */ xcb_ungrab_server(globalconf.connection); /* Parse and run configuration file */ if (!luaA_parserc(&xdg, confpath, true)) fatal("couldn't find any rc file"); p_delete(&confpath); xdgWipeHandle(&xdg); /* scan existing windows */ scan(tree_c); xcb_flush(globalconf.connection); /* main event loop */ ev_loop(globalconf.loop, 0); /* cleanup event loop */ ev_ref(globalconf.loop); ev_check_stop(globalconf.loop, &xcheck); ev_ref(globalconf.loop); ev_prepare_stop(globalconf.loop, &a_refresh); ev_ref(globalconf.loop); ev_io_stop(globalconf.loop, &xio); awesome_atexit(false); return EXIT_SUCCESS; }
xcbosd *xcbosd_create(xine_t *xine, xcb_connection_t *connection, xcb_screen_t *screen, xcb_window_t window, enum xcbosd_mode mode) { xcbosd *osd; xcb_get_geometry_cookie_t get_geometry_cookie; xcb_get_geometry_reply_t *get_geometry_reply; xcb_void_cookie_t generic_cookie; xcb_generic_error_t *generic_error; osd = calloc(1, sizeof(xcbosd)); if (!osd) return NULL; osd->mode = mode; osd->xine = xine; osd->connection = connection; osd->screen = screen; osd->window = window; osd->visual = osd->screen->root_visual; get_geometry_cookie = xcb_get_geometry(osd->connection, osd->window); get_geometry_reply = xcb_get_geometry_reply(osd->connection, get_geometry_cookie, NULL); osd->depth = get_geometry_reply->depth; osd->width = get_geometry_reply->width; osd->height = get_geometry_reply->height; free(get_geometry_reply); assert(osd->width); assert(osd->height); switch (mode) { case XCBOSD_SHAPED: { const xcb_query_extension_reply_t *query_extension_reply = xcb_get_extension_data(osd->connection, &xcb_shape_id); if (!query_extension_reply || !query_extension_reply->present) { xprintf(osd->xine, XINE_VERBOSITY_LOG, _("x11osd: XShape extension not available. unscaled overlay disabled.\n")); goto error2; } unsigned int window_params[] = { osd->screen->black_pixel, 1, XCB_EVENT_MASK_EXPOSURE }; osd->u.shaped.window = xcb_generate_id(osd->connection); generic_cookie = xcb_create_window_checked(osd->connection, XCB_COPY_FROM_PARENT, osd->u.shaped.window, osd->window, 0, 0, osd->width, osd->height, 0, XCB_COPY_FROM_PARENT, XCB_COPY_FROM_PARENT, XCB_CW_BACK_PIXEL | XCB_CW_OVERRIDE_REDIRECT | XCB_CW_EVENT_MASK, window_params); generic_error = xcb_request_check(osd->connection, generic_cookie); if (generic_error != NULL) { xprintf(osd->xine, XINE_VERBOSITY_LOG, _("x11osd: error creating window. unscaled overlay disabled.\n")); free(generic_error); goto error_window; } osd->u.shaped.mask_bitmap = xcb_generate_id(osd->connection); generic_cookie = xcb_create_pixmap_checked(osd->connection, 1, osd->u.shaped.mask_bitmap, osd->u.shaped.window, osd->width, osd->height); generic_error = xcb_request_check(osd->connection, generic_cookie); if (generic_error != NULL) { xprintf(osd->xine, XINE_VERBOSITY_LOG, _("x11osd: error creating pixmap. unscaled overlay disabled.\n")); free(generic_error); goto error_aftermaskbitmap; } osd->bitmap = xcb_generate_id(osd->connection); xcb_create_pixmap(osd->connection, osd->depth, osd->bitmap, osd->u.shaped.window, osd->width, osd->height); osd->gc = xcb_generate_id(osd->connection); xcb_create_gc(osd->connection, osd->gc, osd->u.shaped.window, 0, NULL); osd->u.shaped.mask_gc = xcb_generate_id(osd->connection); xcb_create_gc(osd->connection, osd->u.shaped.mask_gc, osd->u.shaped.mask_bitmap, XCB_GC_FOREGROUND, &osd->screen->white_pixel); osd->u.shaped.mask_gc_back = xcb_generate_id(osd->connection); xcb_create_gc(osd->connection, osd->u.shaped.mask_gc_back, osd->u.shaped.mask_bitmap, XCB_GC_FOREGROUND, &osd->screen->black_pixel); osd->u.shaped.mapped = 0; osd->cmap = xcb_generate_id(osd->connection); xcb_create_colormap(osd->connection, XCB_COLORMAP_ALLOC_NONE, osd->cmap, osd->u.shaped.window, osd->visual); break; } case XCBOSD_COLORKEY: osd->bitmap = xcb_generate_id(osd->connection); xcb_create_pixmap(osd->connection, osd->depth, osd->bitmap, osd->window, osd->width, osd->height); osd->gc = xcb_generate_id(osd->connection); xcb_create_gc(osd->connection, osd->gc, osd->window, 0, NULL); osd->cmap = xcb_generate_id(osd->connection); xcb_create_colormap(osd->connection, XCB_COLORMAP_ALLOC_NONE, osd->cmap, osd->window, osd->visual); /* FIXME: the expose event doesn't seem to happen? */ /*XSelectInput (osd->display, osd->window, ExposureMask);*/ break; default: goto error2; } osd->clean = UNDEFINED; xcbosd_expose(osd); xprintf(osd->xine, XINE_VERBOSITY_DEBUG, _("x11osd: unscaled overlay created (%s mode).\n"), (mode==XCBOSD_SHAPED) ? "XShape" : "Colorkey" ); return osd; /* XFreeGC (osd->display, osd->gc); XFreeGC (osd->display, osd->mask_gc); XFreeGC (osd->display, osd->mask_gc_back); */ error_aftermaskbitmap: if(mode==XCBOSD_SHAPED) xcb_free_pixmap(osd->connection, osd->u.shaped.mask_bitmap); error_window: if(mode==XCBOSD_SHAPED) xcb_destroy_window(osd->connection, osd->u.shaped.window); error2: free (osd); return NULL; }
void xcbosd_drawable_changed(xcbosd *osd, xcb_window_t window) { xcb_get_geometry_cookie_t get_geometry_cookie; xcb_get_geometry_reply_t *get_geometry_reply; assert (osd); lprintf("drawable changed\n"); /* Do I need to recreate the GC's?? XFreeGC (osd->display, osd->gc); XFreeGC (osd->display, osd->mask_gc); XFreeGC (osd->display, osd->mask_gc_back); */ xcb_free_pixmap(osd->connection, osd->bitmap); xcb_free_colormap(osd->connection, osd->cmap); /* we need to call XSync(), because otherwise, calling XDestroyWindow() on the parent window could destroy our OSD window twice !! */ /* XSync (osd->display, False); FIXME don't think that we need that --pfister */ osd->window = window; get_geometry_cookie = xcb_get_geometry(osd->connection, osd->window); get_geometry_reply = xcb_get_geometry_reply(osd->connection, get_geometry_cookie, NULL); osd->depth = get_geometry_reply->depth; osd->width = get_geometry_reply->width; osd->height = get_geometry_reply->height; free(get_geometry_reply); assert(osd->width); assert(osd->height); switch(osd->mode) { case XCBOSD_SHAPED: { xcb_free_pixmap(osd->connection, osd->u.shaped.mask_bitmap); xcb_destroy_window(osd->connection, osd->u.shaped.window); unsigned int window_params[] = { osd->screen->black_pixel, 1, XCB_EVENT_MASK_EXPOSURE }; osd->u.shaped.window = xcb_generate_id(osd->connection); xcb_create_window(osd->connection, XCB_COPY_FROM_PARENT, osd->u.shaped.window, osd->window, 0, 0, osd->width, osd->height, 0, XCB_COPY_FROM_PARENT, XCB_COPY_FROM_PARENT, XCB_CW_BACK_PIXEL | XCB_CW_OVERRIDE_REDIRECT | XCB_CW_EVENT_MASK, window_params); osd->u.shaped.mapped = 0; osd->u.shaped.mask_bitmap = xcb_generate_id(osd->connection); xcb_create_pixmap(osd->connection, 1, osd->u.shaped.mask_bitmap, osd->u.shaped.window, osd->width, osd->height); osd->bitmap = xcb_generate_id(osd->connection); xcb_create_pixmap(osd->connection, osd->depth, osd->bitmap, osd->u.shaped.window, osd->width, osd->height); osd->cmap = xcb_generate_id(osd->connection); xcb_create_colormap(osd->connection, XCB_COLORMAP_ALLOC_NONE, osd->cmap, osd->u.shaped.window, osd->visual); break; } case XCBOSD_COLORKEY: osd->bitmap = xcb_generate_id(osd->connection); xcb_create_pixmap(osd->connection, osd->depth, osd->bitmap, osd->window, osd->width, osd->height); osd->cmap = xcb_generate_id(osd->connection); xcb_create_colormap(osd->connection, XCB_COLORMAP_ALLOC_NONE, osd->cmap, osd->window, osd->visual); break; } osd->clean = UNDEFINED; /* do not xcbosd_clear() here: osd->u.colorkey.sc has not being updated yet */ }
static int CreateWindowAndContext( Display* display, xcb_connection_t* connection, int default_screen, xcb_screen_t* screen, int width, int height, ae3d::WindowCreateFlags flags ) { GLXFBConfig* fb_configs = nullptr; int num_fb_configs = 0; fb_configs = glXGetFBConfigs( display, default_screen, &num_fb_configs ); if (!fb_configs || num_fb_configs == 0) { std::cerr << "glXGetFBConfigs failed." << std::endl; return -1; } /* Select first framebuffer config and query visualID */ int visualID = 0; GLXFBConfig fb_config = fb_configs[ 0 ]; glXGetFBConfigAttrib( display, fb_config, GLX_VISUAL_ID, &visualID ); GLXContext context = glXCreateNewContext( display, fb_config, GLX_RGBA_TYPE, nullptr, True ); if (!context) { std::cerr << "glXCreateNewContext failed." << std::endl; return -1; } /* Create XID's for colormap and window */ xcb_colormap_t colormap = xcb_generate_id( connection ); WindowGlobal::window = xcb_generate_id( connection ); WindowGlobal::windowWidth = width == 0 ? screen->width_in_pixels : width; WindowGlobal::windowHeight = height == 0 ? screen->height_in_pixels : height; xcb_create_colormap( connection, XCB_COLORMAP_ALLOC_NONE, colormap, screen->root, visualID ); const uint32_t eventmask = XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_KEY_PRESS | XCB_EVENT_MASK_KEY_RELEASE | XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE | XCB_EVENT_MASK_POINTER_MOTION; const uint32_t valuelist[] = { eventmask, colormap, 0 }; const uint32_t valuemask = XCB_CW_EVENT_MASK | XCB_CW_COLORMAP; xcb_create_window( connection, XCB_COPY_FROM_PARENT, WindowGlobal::window, screen->root, 0, 0, WindowGlobal::windowWidth, WindowGlobal::windowHeight, 0, XCB_WINDOW_CLASS_INPUT_OUTPUT, visualID, valuemask, valuelist ); xcb_map_window( connection, WindowGlobal::window ); if ((flags & ae3d::WindowCreateFlags::Fullscreen) != 0) { WindowGlobal::EWMHCookie = xcb_ewmh_init_atoms( WindowGlobal::connection, &WindowGlobal::EWMH ); if (!xcb_ewmh_init_atoms_replies( &WindowGlobal::EWMH, WindowGlobal::EWMHCookie, nullptr )) { std::cout << "Fullscreen not supported." << std::endl; } xcb_ewmh_request_change_wm_state( &WindowGlobal::EWMH, XDefaultScreen( display ), WindowGlobal::window, XCB_EWMH_WM_STATE_ADD, WindowGlobal::EWMH._NET_WM_STATE_FULLSCREEN, 0, XCB_EWMH_CLIENT_SOURCE_TYPE_NORMAL ); xcb_ewmh_request_change_active_window( &WindowGlobal::EWMH, XDefaultScreen( display ), WindowGlobal::window, XCB_EWMH_CLIENT_SOURCE_TYPE_NORMAL, XCB_CURRENT_TIME, XCB_WINDOW_NONE ); xcb_generic_error_t* error; xcb_get_window_attributes_reply_t* reply = xcb_get_window_attributes_reply( WindowGlobal::connection, xcb_get_window_attributes( WindowGlobal::connection, WindowGlobal::window ), &error ); if (!reply) { std::cerr << "Full screen reply failed" << std::endl; } } //xcb_change_property( WindowGlobal::connection, XCB_PROP_MODE_REPLACE, WindowGlobal::window, WindowGlobal::EWMH._NET_WM_STATE, XCB_ATOM, 32, 1, &(WindowGlobal::EWMH._NET_WM_STATE_FULLSCREEN)); // End test GLXWindow glxwindow = glXCreateWindow( display, fb_config, WindowGlobal::window, nullptr ); if (!glxwindow) { xcb_destroy_window( connection, WindowGlobal::window ); glXDestroyContext( display, context ); std::cerr << "glXDestroyContext failed" << std::endl; return -1; } WindowGlobal::drawable = glxwindow; if (!glXMakeContextCurrent( display, WindowGlobal::drawable, WindowGlobal::drawable, context )) { xcb_destroy_window( connection, WindowGlobal::window ); glXDestroyContext( display, context ); std::cerr << "glXMakeContextCurrent failed" << std::endl; return -1; } return 0; }