void XCompcapMain::updateSettings(obs_data_t *settings) { PLock lock(&p->lock); XErrorLock xlock; ObsGsContextHolder obsctx; blog(LOG_DEBUG, "Settings updating"); Window prevWin = p->win; xcc_cleanup(p); if (settings) { const char *windowName = obs_data_get_string(settings, "capture_window"); p->windowName = windowName; p->win = getWindowFromString(windowName); p->cut_top = obs_data_get_int(settings, "cut_top"); p->cut_left = obs_data_get_int(settings, "cut_left"); p->cut_right = obs_data_get_int(settings, "cut_right"); p->cut_bot = obs_data_get_int(settings, "cut_bot"); p->lockX = obs_data_get_bool(settings, "lock_x"); p->swapRedBlue = obs_data_get_bool(settings, "swap_redblue"); p->show_cursor = obs_data_get_bool(settings, "show_cursor"); p->include_border = obs_data_get_bool(settings, "include_border"); } else { p->win = prevWin; } xlock.resetError(); XCompositeRedirectWindow(xdisp, p->win, CompositeRedirectAutomatic); if (xlock.gotError()) { blog(LOG_ERROR, "XCompositeRedirectWindow failed: %s", xlock.getErrorText().c_str()); return; } XSelectInput(xdisp, p->win, StructureNotifyMask | ExposureMask); XSync(xdisp, 0); XWindowAttributes attr; if (!XGetWindowAttributes(xdisp, p->win, &attr)) { p->win = 0; p->width = 0; p->height = 0; return; } if (p->cursor && p->show_cursor) { Window child; int x, y; XTranslateCoordinates(xdisp, p->win, attr.root, 0, 0, &x, &y, &child); xcursor_offset(p->cursor, x, y); } gs_color_format cf = GS_RGBA; p->border = attr.border_width; if (p->include_border) { p->width = attr.width + p->border * 2; p->height = attr.height + p->border * 2; } else { p->width = attr.width; p->height = attr.height; } if (p->cut_top + p->cut_bot < (int)p->height) { p->cur_cut_top = p->cut_top; p->cur_cut_bot = p->cut_bot; } else { p->cur_cut_top = 0; p->cur_cut_bot = 0; } if (p->cut_left + p->cut_right < (int)p->width) { p->cur_cut_left = p->cut_left; p->cur_cut_right = p->cut_right; } else { p->cur_cut_left = 0; p->cur_cut_right = 0; } if (p->tex) gs_texture_destroy(p->tex); uint8_t *texData = new uint8_t[width() * height() * 4]; for (unsigned int i = 0; i < width() * height() * 4; i += 4) { texData[i + 0] = p->swapRedBlue ? 0 : 0xFF; texData[i + 1] = 0; texData[i + 2] = p->swapRedBlue ? 0xFF : 0; texData[i + 3] = 0xFF; } const uint8_t* texDataArr[] = { texData, 0 }; p->tex = gs_texture_create(width(), height(), cf, 1, texDataArr, 0); delete[] texData; if (p->swapRedBlue) { GLuint tex = *(GLuint*)gs_texture_get_obj(p->tex); glBindTexture(GL_TEXTURE_2D, tex); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_RED); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_BLUE); glBindTexture(GL_TEXTURE_2D, 0); } const int attrs[] = { GLX_BIND_TO_TEXTURE_RGBA_EXT, GL_TRUE, GLX_DRAWABLE_TYPE, GLX_PIXMAP_BIT, GLX_BIND_TO_TEXTURE_TARGETS_EXT, GLX_TEXTURE_2D_BIT_EXT, GLX_DOUBLEBUFFER, GL_FALSE, None }; int nelem = 0; GLXFBConfig* configs = glXChooseFBConfig(xdisp, XCompcap::getRootWindowScreen(attr.root), attrs, &nelem); if (nelem <= 0) { blog(LOG_ERROR, "no matching fb config found"); p->win = 0; p->height = 0; p->width = 0; return; } glXGetFBConfigAttrib(xdisp, configs[0], GLX_Y_INVERTED_EXT, &nelem); p->inverted = nelem != 0; xlock.resetError(); p->pixmap = XCompositeNameWindowPixmap(xdisp, p->win); if (xlock.gotError()) { blog(LOG_ERROR, "XCompositeNameWindowPixmap failed: %s", xlock.getErrorText().c_str()); p->pixmap = 0; XFree(configs); return; } const int attribs[] = { GLX_TEXTURE_TARGET_EXT, GLX_TEXTURE_2D_EXT, GLX_TEXTURE_FORMAT_EXT, GLX_TEXTURE_FORMAT_RGBA_EXT, None }; p->glxpixmap = glXCreatePixmap(xdisp, configs[0], p->pixmap, attribs); if (xlock.gotError()) { blog(LOG_ERROR, "glXCreatePixmap failed: %s", xlock.getErrorText().c_str()); XFreePixmap(xdisp, p->pixmap); XFree(configs); p->pixmap = 0; p->glxpixmap = 0; return; } XFree(configs); p->gltex = gs_texture_create(p->width, p->height, cf, 1, 0, GS_GL_DUMMYTEX); GLuint gltex = *(GLuint*)gs_texture_get_obj(p->gltex); glBindTexture(GL_TEXTURE_2D, gltex); glXBindTexImageEXT(xdisp, p->glxpixmap, GLX_FRONT_LEFT_EXT, NULL); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); }
static int x11_reset(struct vidisp_st *st, const struct vidsz *sz) { XWindowAttributes attrs; XGCValues gcv; size_t bufsz, pixsz; int err = 0; if (!XGetWindowAttributes(st->disp, st->win, &attrs)) { warning("x11: cant't get window attributes\n"); return EINVAL; } switch (attrs.depth) { case 24: st->pixfmt = VID_FMT_RGB32; pixsz = 4; break; case 16: st->pixfmt = VID_FMT_RGB565; pixsz = 2; break; case 15: st->pixfmt = VID_FMT_RGB555; pixsz = 2; break; default: warning("x11: colordepth not supported: %d\n", attrs.depth); return ENOSYS; } bufsz = sz->w * sz->h * pixsz; if (st->image) { XDestroyImage(st->image); st->image = NULL; } if (st->xshmat) XShmDetach(st->disp, &st->shm); if (st->shm.shmaddr != (char *)-1) shmdt(st->shm.shmaddr); if (st->shm.shmid >= 0) shmctl(st->shm.shmid, IPC_RMID, NULL); st->shm.shmid = shmget(IPC_PRIVATE, bufsz, IPC_CREAT | 0777); if (st->shm.shmid < 0) { warning("x11: failed to allocate shared memory\n"); return ENOMEM; } st->shm.shmaddr = shmat(st->shm.shmid, NULL, 0); if (st->shm.shmaddr == (char *)-1) { warning("x11: failed to attach to shared memory\n"); return ENOMEM; } st->shm.readOnly = true; x11.shm_error = 0; x11.errorh = XSetErrorHandler(error_handler); if (!XShmAttach(st->disp, &st->shm)) { warning("x11: failed to attach X to shared memory\n"); return ENOMEM; } XSync(st->disp, False); XSetErrorHandler(x11.errorh); if (x11.shm_error) info("x11: shared memory disabled\n"); else st->xshmat = true; gcv.graphics_exposures = false; st->gc = XCreateGC(st->disp, st->win, GCGraphicsExposures, &gcv); if (!st->gc) { warning("x11: failed to create graphics context\n"); return ENOMEM; } if (st->xshmat) { st->image = XShmCreateImage(st->disp, attrs.visual, attrs.depth, ZPixmap, st->shm.shmaddr, &st->shm, sz->w, sz->h); } else { st->image = XCreateImage(st->disp, attrs.visual, attrs.depth, ZPixmap, 0, st->shm.shmaddr, sz->w, sz->h, 32, 0); } if (!st->image) { warning("x11: Failed to create X image\n"); return ENOMEM; } XResizeWindow(st->disp, st->win, sz->w, sz->h); st->size = *sz; return err; }
/** * Grabs keys on the Xserver level via XGrabKey(), * so they can be intercepted and interpreted by * our application, thus having global hotkeys. * * If mk, uk and dk parameters are -1, then * this function will just ungrab everything. * * @param mk mutekey * @param uk volume up key * @param dk volume down key * @param mm volume mute mod key * @param um volume up mod key * @param dm volume down mod key * @param step hotkey volume step */ void grab_keys(int mk, int uk, int dk, int mm, int um, int dm, int step) { Display *disp = gdk_x11_get_default_xdisplay(); // ungrab any previous keys XUngrabKey(disp, AnyKey, AnyModifier, GDK_ROOT_WINDOW()); volMuteKey = mk; volUpKey = uk; volDownKey = dk; volMuteMods = mm; volUpMods = um; volDownMods = dm; volStep = step; if (mk < 0 && uk < 0 && dk < 0) return; xErr = 0; errBuf = g_malloc(errBufSize * sizeof(gchar)); printBuf = errBuf + snprintf(errBuf, errBufSize, _("Could not bind the following hotkeys:\n")); errBufSize -= (printBuf - errBuf); if (muteSymStr) g_free(muteSymStr); if (upSymStr) g_free(upSymStr); if (downSymStr) g_free(downSymStr); muteSymStr = gtk_accelerator_name( XkbKeycodeToKeysym(gdk_x11_get_default_xdisplay(), volMuteKey, 0, 0), volMuteMods); upSymStr = gtk_accelerator_name( XkbKeycodeToKeysym(gdk_x11_get_default_xdisplay(), volUpKey, 0, 0), volUpMods); downSymStr = gtk_accelerator_name( XkbKeycodeToKeysym(gdk_x11_get_default_xdisplay(), volDownKey, 0, 0), volDownMods); XErrorHandler old_hdlr = XSetErrorHandler(errhdl); guint i; for (i = 0; i < G_N_ELEMENTS(keymasks); i++) { if (volMuteKey > 0) { muteSerial = NextRequest(disp); XGrabKey(disp, volMuteKey, volMuteMods | keymasks[i], GDK_ROOT_WINDOW(), 1, GrabModeAsync, GrabModeAsync); } if (volUpKey > 0) { upSerial = NextRequest(disp); XGrabKey(disp, volUpKey, volUpMods | keymasks[i], GDK_ROOT_WINDOW(), 1, GrabModeAsync, GrabModeAsync); } if (volDownKey > 0) { downSerial = NextRequest(disp); XGrabKey(disp, volDownKey, volDownMods | keymasks[i], GDK_ROOT_WINDOW(), 1, GrabModeAsync, GrabModeAsync); } } XFlush(disp); XSync(disp, False); (void) XSetErrorHandler(old_hdlr); if (xErr) g_idle_add(idle_report_error, NULL); else g_free(errBuf); }
static int select_region(Display *dpy, Window root, Region *region) { XEvent ev; GC sel_gc; XGCValues sel_gv; int done = 0, btn_pressed = 0; int x = 0, y = 0; unsigned int width = 0, height = 0; int start_x = 0, start_y = 0; Cursor cursor; cursor = XCreateFontCursor(dpy, XC_crosshair); XGrabPointer( dpy, root, True, PointerMotionMask | ButtonPressMask | ButtonReleaseMask, GrabModeAsync, GrabModeAsync, None, cursor, CurrentTime ); sel_gv.function = GXinvert; sel_gv.subwindow_mode = IncludeInferiors; sel_gv.line_width = 1; sel_gc = XCreateGC(dpy, root, GCFunction | GCSubwindowMode | GCLineWidth, &sel_gv); for (;;) { XNextEvent(dpy, &ev); switch (ev.type) { case ButtonPress: btn_pressed = 1; x = start_x = ev.xbutton.x_root; y = start_y = ev.xbutton.y_root; width = height = 0; break; case MotionNotify: /* Draw only if button is pressed */ if (btn_pressed) { /* Re-draw last Rectangle to clear it */ XDrawRectangle(dpy, root, sel_gc, x, y, width, height); x = ev.xbutton.x_root; y = ev.xbutton.y_root; if (x > start_x) { width = x - start_x; x = start_x; } else { width = start_x - x; } if (y > start_y) { height = y - start_y; y = start_y; } else { height = start_y - y; } /* Draw Rectangle */ XDrawRectangle(dpy, root, sel_gc, x, y, width, height); XFlush(dpy); } break; case ButtonRelease: done = 1; break; default: break; } if (done) break; } /* Re-draw last Rectangle to clear it */ XDrawRectangle(dpy, root, sel_gc, x, y, width, height); XFlush(dpy); XUngrabPointer(dpy, CurrentTime); XFreeCursor(dpy, cursor); XFreeGC(dpy, sel_gc); XSync(dpy, 1); Region rr; /* root region */ Region sr; /* selected region */ if (False == XGetGeometry(dpy, root, &rr.root, &rr.x, &rr.y, &rr.w, &rr.h, &rr.b, &rr.d)) { error("failed to get root window geometry\n"); return EXIT_FAILURE; } sr.x = x; sr.y = y; sr.w = width; sr.h = height; /* calculate right and bottom offset */ sr.X = rr.w - sr.x - sr.w; sr.Y = rr.h - sr.y - sr.h; /* those doesn't really make sense but should be set */ sr.b = rr.b; sr.d = rr.d; *region = sr; return EXIT_SUCCESS; }
static void getMyXImage(void) { #ifdef HAVE_SHM if (mLocalDisplay && XShmQueryExtension(mDisplay)) Shmem_Flag = 1; else { Shmem_Flag = 0; mp_msg(MSGT_VO, MSGL_WARN, "Shared memory not supported\nReverting to normal Xlib\n"); } if (Shmem_Flag) CompletionType = XShmGetEventBase(mDisplay) + ShmCompletion; if (Shmem_Flag) { myximage = XShmCreateImage(mDisplay, vinfo.visual, depth, ZPixmap, NULL, &Shminfo[0], image_width, image_height); if (myximage == NULL) { mp_msg(MSGT_VO, MSGL_WARN, "Shared memory error,disabling ( Ximage error )\n"); goto shmemerror; } Shminfo[0].shmid = shmget(IPC_PRIVATE, myximage->bytes_per_line * myximage->height, IPC_CREAT | 0777); if (Shminfo[0].shmid < 0) { XDestroyImage(myximage); mp_msg(MSGT_VO, MSGL_V, "%s\n", strerror(errno)); //perror( strerror( errno ) ); mp_msg(MSGT_VO, MSGL_WARN, "Shared memory error,disabling ( seg id error )\n"); goto shmemerror; } Shminfo[0].shmaddr = (char *) shmat(Shminfo[0].shmid, 0, 0); if (Shminfo[0].shmaddr == ((char *) -1)) { XDestroyImage(myximage); if (Shminfo[0].shmaddr != ((char *) -1)) shmdt(Shminfo[0].shmaddr); mp_msg(MSGT_VO, MSGL_WARN, "Shared memory error,disabling ( address error )\n"); goto shmemerror; } myximage->data = Shminfo[0].shmaddr; ImageData = (unsigned char *) myximage->data; Shminfo[0].readOnly = False; XShmAttach(mDisplay, &Shminfo[0]); XSync(mDisplay, False); if (gXErrorFlag) { XDestroyImage(myximage); shmdt(Shminfo[0].shmaddr); mp_msg(MSGT_VO, MSGL_WARN, "Shared memory error,disabling.\n"); gXErrorFlag = 0; goto shmemerror; } else shmctl(Shminfo[0].shmid, IPC_RMID, 0); { static int firstTime = 1; if (firstTime) { mp_msg(MSGT_VO, MSGL_V, "Sharing memory.\n"); firstTime = 0; } } } else { shmemerror: Shmem_Flag = 0; #endif myximage = XCreateImage(mDisplay, vinfo.visual, depth, ZPixmap, 0, NULL, image_width, image_height, 8, 0); ImageDataOrig = malloc(myximage->bytes_per_line * image_height + 32); myximage->data = ImageDataOrig + 16 - ((long)ImageDataOrig & 15); memset(myximage->data, 0, myximage->bytes_per_line * image_height); ImageData = myximage->data; #ifdef HAVE_SHM } #endif }
void dgaux_gauy_filter(float sigma){ int i,j,k,length_gaussian,length_deriv; float gaussian[SIZE1],deriv_gaussian[SIZE1]; matrix dgaux, dgaux_gauy, total_resul, m; float rmin,rmax,rng; /* Fill in the image with background color */ for(i=0; i<IMAGE_WIDTH; i++) for(j=0; j<IMAGE_HEIGHT; j++) XPutPixel(theXImage_2,i,j,bg); /* Clear the drawing window so the image is displayed again */ XClearArea(XtDisplay(draw_1),XtWindow(draw_2),0,0,0,0,True); /* Associate the watch cursor with the main window */ XDefineCursor(XtDisplay(draw_1), XtWindow(main_window), theCursor); /* Flush the request buffer and wait for all events */ /* and errors to be processed by the server. */ XSync(XtDisplay(draw_1), False); get_gaussian(sigma,gaussian,&length_gaussian); fprintf(stderr,"long de gaussian es %i \n",length_gaussian); for(i=0;i<=length_gaussian;i++) fprintf(stderr,"el gaussian de [%i] es %f \n",i,gaussian[i]); get_derigaussian(sigma,deriv_gaussian,&length_deriv); fprintf(stderr,"long de deriv gaussian es %i \n",length_deriv); for(i=0;i<=length_deriv;i++) fprintf(stderr,"el deriv_gaussian de [%i] es %f \n",i,deriv_gaussian[i]); for(i=0;i<IMAGE_WIDTH;i++) for(j=0;j<IMAGE_HEIGHT;j++) m[i][j]= XGetPixel(theXImage_1,i,j); /* calculates the convolution of the image with the derivative of a */ /* gaussian for the rows */ convo_vectorx(m,deriv_gaussian,length_deriv,&rmax,&rmin,dgaux); /* calculate the smoothing of a gaussian(x) in y direction.*/ convo_vectory(dgaux,gaussian,length_gaussian,&rmax,&rmin, dgaux_gauy); fprintf(stderr,"Maximum is %f, Minimum is %f\n",rmax,rmin); rng=(rmax-rmin); for(i=0;i<IMAGE_WIDTH;i++) for(j=0;j<IMAGE_HEIGHT;j++) total_resul[i][j]=sqrt(pow(dgaux_gauy[i][j],2)); for(i=0;i<IMAGE_WIDTH;i++) for(j=0;j<IMAGE_HEIGHT;j++) XPutPixel(theXImage_2,i,j,(unsigned long) (((float)(total_resul[i][j]-rmin)/rng)*255.0)); /* Copy image into pixmap */ XPutImage(XtDisplay(draw_2), thePixmap_2,image_gc_2, theXImage_2, 0, 0, 0, 0, theXImage_2->width, theXImage_2->height); /* Disassociate the watch cursor from the main window */ XUndefineCursor(XtDisplay(draw_1), XtWindow(main_window)); /* Clear the drawing window so the image is displayed again */ XClearArea(XtDisplay(draw_2),XtWindow(draw_2),0,0,0,0,True); }
int main(int argc, char *argv[]) { unsigned int moment; unsigned int node_index; node_t *node; Display *display; GC gc; int screen_number; int window_x; int window_y; unsigned int each_x; unsigned int each_y; unsigned int window_border_width; unsigned int window_height; unsigned int window_width; unsigned long gc_value_mask; unsigned long window_background_color; unsigned long window_border_color; Window root_window; Window window; XGCValues gc_values; Visual* default_visual; Colormap colormap; XColor system_color; XColor exact_color; unsigned int window_display_modulus; unsigned int window_x_pixel; display = XOpenDisplay(NULL); screen_number = DefaultScreen(display); root_window = RootWindow(display, screen_number); window_x = 0; window_y = 0; window_width = XWINDOW_WIDTH; window_height = TIME; window_border_width = 0; window_border_color = BlackPixel(display, screen_number); window_background_color = WhitePixel(display, screen_number); window = XCreateSimpleWindow(display, root_window, window_x, window_y, window_width, window_height, window_border_width, window_border_color, window_background_color); XMapWindow(display, window); XFlush(display); gc_value_mask = 0; gc = XCreateGC(display, window, gc_value_mask, &gc_values); default_visual = DefaultVisual(display, DefaultScreen(display)); colormap = XCreateColormap(display, window, default_visual, AllocNone); XSync(display, False); window_display_modulus = NODES / XWINDOW_WIDTH; srandom(SEED); /* init_action_tables(); */ network = create_network(); for (moment = 0; moment < TIME; moment++) { window_x_pixel = 0; for (node_index = 0; node_index < NODES; node_index++) { if (0 != (node_index % window_display_modulus)) { continue; } node = network->nodes_display_order[node_index]; system_color.red = 0; if (2 == node->link_count) { system_color.green = USHRT_MAX / 4; } else if (3 == node->link_count) { system_color.green = USHRT_MAX; } else { exit(99); } /* system_color.green = 0; */ if (0 == node->value) { system_color.blue = USHRT_MAX / 4; } else if (1 == node->value) { system_color.blue = USHRT_MAX; } else { exit(100); } /* system_color.blue = 0; */ XAllocColor(display, colormap, &system_color); XSetForeground(display, gc, system_color.pixel); XDrawPoint(display, window, gc, window_x_pixel, moment); window_x_pixel++; } XFlush(display); iterate_network(network); } while (1) { usleep(SLEEP); } destroy_network(network); XUnmapWindow(display, window); XDestroyWindow(display, window); XCloseDisplay(display); return 0; }
// Reserves an area for the X11 window 'w' in one of the sides of the desktop depending // on the value of 'where'. If 'where== NON_DOCKED' or area== 0 then the area is freed. static void SetStrutArea (Window w, WXAppBar::EDocking where, int area) { Display* dd= (Display *) wxGetDisplay(); // // Get desktop working area dimensions // int xDesktop, yDesktop, widthDesktop, heightDesktop, screenWidth, screenHeight; GetDesktopDimensions (dd, xDesktop, yDesktop, widthDesktop, heightDesktop, screenWidth, screenHeight); // // Reserves an area in the desktop. // // It seems that for older GNOME version (ex: 2.22.3 on Debian, using a partial strut // doesn't work properly, more TESTING NEEDED) // unsigned long strut[4] = {0, 0, 0, 0}; //unsigned long strut_p[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; /* left, right, top, bottom, left_start_y, left_end_y, right_start_y, right_end_y, top_start_x, top_end_x, bottom_start_x, bottom_end_x*/ if (area) { switch (where) { case WXAppBar::TOP_DOCKED: strut[2]= area + yDesktop; //strut_p[2]= strut[2]; break; case WXAppBar::BOTTOM_DOCKED: strut[3]= screenHeight - heightDesktop - yDesktop + area; //strut_p[3]= strut[3]; break; case WXAppBar::LEFT_DOCKED: strut[0]= area + xDesktop; //strut_p[0]= strut[0]; break; case WXAppBar::RIGHT_DOCKED: strut[1]= screenWidth - widthDesktop - xDesktop + area; //strut_p[1]= strut[1]; break; case WXAppBar::NON_DOCKED: break; default: assert (false); } } //atomTmp = XInternAtom (dd, "_NET_WM_STRUT_PARTIAL", False); //XChangeProperty (dd, w, atomTmp, XA_CARDINAL, 32, PropModeReplace, (unsigned char *) &strut_p, 12); Atom atomTmp = XInternAtom (dd, "_NET_WM_STRUT", False); XChangeProperty (dd, w, atomTmp, XA_CARDINAL, 32, PropModeReplace, (unsigned char *) &strut, 4); XSync(dd, False); // If window mapped, then wait until strut applied // TODO: is there a better way to do this? if (IsMappedWindow(dd, w)) { int new_xDesktop, new_yDesktop, new_widthDesktop, new_heightDesktop, count= 0; for (;;) { GetDesktopDimensions (dd, new_xDesktop, new_yDesktop, new_widthDesktop, new_heightDesktop, screenWidth, screenHeight); ++count; if (!(count< 20 && new_xDesktop== xDesktop && new_yDesktop== yDesktop && new_widthDesktop== widthDesktop && new_heightDesktop == heightDesktop)) break; usleep (100000); } } }
void WXAppBar::SetAutohideModeStep () { //CheckCreateWindow(); // // Get X11 display // Display* dd= (Display *) wxGetDisplay(); assert (dd); // // Get desktop working area dimensions // int xDesktop, yDesktop, widthDesktop, heightDesktop, screenWidth, screenHeight; GetDesktopDimensions (dd, xDesktop, yDesktop, widthDesktop, heightDesktop, screenWidth, screenHeight); // // As we need to dock the window disable decorations // m_dialogHadBorderDecorations= GetBorderDecorations(); SetBorderDecorations(false); // // Get X11 handle for our window // GtkWidget *gtkWidget= (GtkWidget *) this->GetHandle(); Window w= GDK_WINDOW_XWINDOW (gtkWidget->window); // Get original dimensions of the bar wxSize proposedSize= GetBestSize(); // Compute bar position and size depending on docking mode m_Width= proposedSize.GetWidth(); m_Height= proposedSize.GetHeight(); switch (m_currentDockingMode) { case TOP_DOCKED: m_X= (screenWidth - proposedSize.GetWidth())/2; m_Y= 0 - proposedSize.GetHeight() + AUTOHIDE_FLANGE; break; case BOTTOM_DOCKED: m_X= (screenWidth - proposedSize.GetWidth())/2; m_Y= screenHeight - AUTOHIDE_FLANGE; break; case LEFT_DOCKED: m_X= 0 - proposedSize.GetWidth() + AUTOHIDE_FLANGE; m_Y= (screenHeight - proposedSize.GetHeight())/2; break; case RIGHT_DOCKED: m_X= screenWidth - AUTOHIDE_FLANGE; m_Y= (screenHeight - proposedSize.GetHeight())/2; break; case NON_DOCKED: default: assert (false); } // // Functional type of the window (_NET_WM_WINDOW_TYPE) // Atom atomTmp= XInternAtom (dd, "_NET_WM_WINDOW_TYPE", False); Atom atom_NET_WM_WINDOW_TYPE_DOCK= XInternAtom (dd, "_NET_WM_WINDOW_TYPE_DOCK", False); Atom atom_NET_WM_WINDOW_TYPE_NORMAL= XInternAtom (dd, "_NET_WM_WINDOW_TYPE_NORMAL", False); unsigned long propInfo[2]; propInfo[0]= atom_NET_WM_WINDOW_TYPE_DOCK; propInfo[1]= atom_NET_WM_WINDOW_TYPE_NORMAL; XChangeProperty (dd, w, atomTmp, XA_ATOM, 32, PropModeReplace, (unsigned char *) &propInfo[0], 2); SetSticky(true); XSync(dd, False); // Set desired location and dimensions SetSize(m_X, m_Y, m_Width, m_Height); }
/* ** 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; XSizeHints sizehints; unsigned long mask; int colorbits, depthbits, stencilbits; int tcolorbits, tdepthbits, tstencilbits; int dga_MajorVersion, dga_MinorVersion; int actualWidth, actualHeight; int i; const char* glstring; // bk001130 - from cvs1.17 (mkv) 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 #ifdef HAVE_XF86DGA if (!XF86VidModeQueryVersion(dpy, &vidmode_MajorVersion, &vidmode_MinorVersion)) { #endif /* HAVE_XF86DGA */ vidmode_ext = qfalse; #ifdef HAVE_XF86DGA } else { ri.Printf(PRINT_ALL, "Using XFree86-VidModeExtension Version %d.%d\n", vidmode_MajorVersion, vidmode_MinorVersion); vidmode_ext = qtrue; } #endif /* HAVE_XF86DGA */ // Check for DGA dga_MajorVersion = 0, dga_MinorVersion = 0; #ifdef HAVE_XF86DGA if (in_dgamouse->value) { if (!XF86DGAQueryVersion(dpy, &dga_MajorVersion, &dga_MinorVersion)) { // unable to query, probably 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", dga_MajorVersion, dga_MinorVersion); } } #endif /* HAVE_XF86DGA */ #ifdef HAVE_XF86DGA 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) { 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); ri.Printf(PRINT_ALL, "XFree86-VidModeExtension Activated at %dx%d\n", actualWidth, actualHeight); } else { fullscreen = 0; ri.Printf(PRINT_ALL, "XFree86-VidModeExtension: No acceptable modes found\n"); } } else { ri.Printf(PRINT_ALL, "XFree86-VidModeExtension: Ignored on non-fullscreen/Voodoo\n"); } } #endif /* HAVE_XF86DGA */ 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; visinfo = qglXChooseVisual(dpy, scrnum, attrib); if (!visinfo) { continue; } 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); XStoreName( dpy, win, CLIENT_WINDOW_TITLE ); /* GH: Don't let the window be resized */ sizehints.flags = PMinSize | PMaxSize; sizehints.min_width = sizehints.max_width = actualWidth; sizehints.min_height = sizehints.max_height = actualHeight; XSetWMNormalHints( dpy, win, &sizehints ); XMapWindow( dpy, win ); if (vidmode_active) XMoveWindow(dpy, win, 0, 0); XFlush(dpy); XSync(dpy,False); // bk001130 - from cvs1.17 (mkv) ctx = qglXCreateContext(dpy, visinfo, NULL, True); XSync(dpy,False); // bk001130 - from cvs1.17 (mkv) /* GH: Free the visinfo after we're done with it */ XFree( visinfo ); qglXMakeCurrent(dpy, win, ctx); // bk001130 - from cvs1.17 (mkv) glstring = (char *)qglGetString (GL_RENDERER); ri.Printf( PRINT_ALL, "GL_RENDERER: %s\n", glstring ); // bk010122 - new software token (Indirect) if ( !Q_stricmp( glstring, "Mesa X11") || !Q_stricmp( glstring, "Mesa GLX Indirect") ) { if ( !r_allowSoftwareGL->integer ) { ri.Printf( PRINT_ALL, "\n\n***********************************************************\n" ); ri.Printf( PRINT_ALL, " You are using software Mesa (no hardware acceleration)! \n" ); ri.Printf( PRINT_ALL, " Driver DLL used: %s\n", drivername ); ri.Printf( PRINT_ALL, " If this is intentional, add\n" ); ri.Printf( PRINT_ALL, " \"+set r_allowSoftwareGL 1\"\n" ); ri.Printf( PRINT_ALL, " to the command line when starting the game.\n" ); ri.Printf( PRINT_ALL, "***********************************************************\n"); GLimp_Shutdown( ); return RSERR_INVALID_MODE; } else { ri.Printf( PRINT_ALL, "...using software Mesa (r_allowSoftwareGL==1).\n" ); } } return RSERR_OK; }
void main(int argc, char* argv[]) { Display* display; /* pointer to X Display structure. */ int screen_num; /* number of screen to place the window on. */ Window win; /* pointer to the newly created window. */ unsigned int display_width, display_height; /* height and width of the X display. */ unsigned int width, height; /* height and width for the new window. */ char *display_name = getenv("DISPLAY"); /* address of the X display. */ GC gc; /* GC (graphics context) used for drawing */ /* in our window. */ Colormap screen_colormap; /* color map to use for allocating colors. */ XColor red, brown, blue, yellow, green; /* used for allocation of the given color */ /* map entries. */ Status rc; /* return status of various Xlib functions. */ /* open connection with the X server. */ display = XOpenDisplay(display_name); if (display == NULL) { fprintf(stderr, "%s: cannot connect to X server '%s'\n", argv[0], display_name); exit(1); } /* get the geometry of the default screen for our display. */ screen_num = DefaultScreen(display); display_width = DisplayWidth(display, screen_num); display_height = DisplayHeight(display, screen_num); /* make the new window occupy 1/9 of the screen's size. */ width = (display_width / 3); height = (display_height / 3); printf("window width - '%d'; height - '%d'\n", width, height); /* create a simple window, as a direct child of the screen's */ /* root window. Use the screen's white color as the background */ /* color of the window. Place the new window's top-left corner */ /* at the given 'x,y' coordinates. */ win = create_simple_window(display, width, height, 0, 0); /* allocate a new GC (graphics context) for drawing in the window. */ gc = create_gc(display, win, 0); XSync(display, False); /* get access to the screen's color map. */ screen_colormap = DefaultColormap(display, DefaultScreen(display)); /* allocate the set of colors we will want to use for the drawing. */ rc = XAllocNamedColor(display, screen_colormap, "red", &red, &red); if (rc == 0) { fprintf(stderr, "XAllocNamedColor - failed to allocated 'red' color.\n"); exit(1); } rc = XAllocNamedColor(display, screen_colormap, "brown", &brown, &brown); if (rc == 0) { fprintf(stderr, "XAllocNamedColor - failed to allocated 'brown' color.\n"); exit(1); } rc = XAllocNamedColor(display, screen_colormap, "blue", &blue, &blue); if (rc == 0) { fprintf(stderr, "XAllocNamedColor - failed to allocated 'blue' color.\n"); exit(1); } rc = XAllocNamedColor(display, screen_colormap, "yellow", &yellow, &yellow); if (rc == 0) { fprintf(stderr, "XAllocNamedColor - failed to allocated 'yellow' color.\n"); exit(1); } rc = XAllocNamedColor(display, screen_colormap, "green", &green, &green); if (rc == 0) { fprintf(stderr, "XAllocNamedColor - failed to allocated 'green' color.\n"); exit(1); } /* draw one pixel near each corner of the window */ /* draw the pixels in a red color. */ XSetForeground(display, gc, red.pixel); XDrawPoint(display, win, gc, 5, 5); XDrawPoint(display, win, gc, 5, height-5); XDrawPoint(display, win, gc, width-5, 5); XDrawPoint(display, win, gc, width-5, height-5); /* draw two intersecting lines, one horizontal and one vertical, */ /* which intersect at point "50,100". */ /* draw the line in a brown color. */ XSetForeground(display, gc, brown.pixel); XDrawLine(display, win, gc, 50, 0, 50, 200); XDrawLine(display, win, gc, 0, 100, 200, 100); /* now use the XDrawArc() function to draw a circle whose diameter */ /* is 30 pixels, and whose center is at location '50,100'. */ /* draw the arc in a blue color. */ XSetForeground(display, gc, blue.pixel); XDrawArc(display, win, gc, 50-(30/2), 100-(30/2), 30, 30, 0, 360*64); { XPoint points[] = { {0, 0}, {15, 15}, {0, 15}, {0, 0} }; int npoints = sizeof(points)/sizeof(XPoint); /* draw a small triangle at the top-left corner of the window. */ /* the triangle is made of a set of consecutive lines, whose */ /* end-point pixels are specified in the 'points' array. */ /* draw the triangle in a yellow color. */ XSetForeground(display, gc, yellow.pixel); XDrawLines(display, win, gc, points, npoints, CoordModeOrigin); } /* draw a rectangle whose top-left corner is at '120,150', its width is */ /* 50 pixels, and height is 60 pixels. */ /* draw the rectangle in a black color. */ XSetForeground(display, gc, BlackPixel(display, screen_num)); XDrawRectangle(display, win, gc, 120, 150, 50, 60); /* draw a filled rectangle of the same size as above, to the left of the */ /* previous rectangle. */ /* draw the rectangle in a green color. */ XSetForeground(display, gc, green.pixel); XFillRectangle(display, win, gc, 60, 150, 50, 60); /* flush all pending requests to the X server. */ XFlush(display); /* make a delay for a short period. */ sleep(4); /* close the connection to the X server. */ XCloseDisplay(display); }
HGLRC OpenGLGetContext(Tcl_Interp* interp,char* name) #endif { Tcl_CmdInfo info; OpenGLClientData* OpenGLPtr; #ifdef _WIN32 HWND hWnd; #endif if(!Tcl_GetCommandInfo(interp, name, &info)) return 0; OpenGLPtr=(OpenGLClientData*)info.clientData; if (OpenGLPtr->tkwin != Tk_NameToWindow(interp, name, Tk_MainWindow(interp))) return 0; if (OpenGLPtr->display != Tk_Display(OpenGLPtr->tkwin)) return 0; if (OpenGLPtr->display) XSync(OpenGLPtr->display, False); if (!OpenGLPtr->x11_win) { Tk_MakeWindowExist(OpenGLPtr->tkwin); XSync(OpenGLPtr->display, False); OpenGLPtr->x11_win = Tk_WindowId(OpenGLPtr->tkwin); } if (!OpenGLPtr->x11_win) return 0; #ifndef _WIN32 OpenGLPtr->glx_win = OpenGLPtr->x11_win; if (!OpenGLPtr->cx) { OpenGLPtr->cx = glXCreateContext(OpenGLPtr->display, OpenGLPtr->vi, first_context, OpenGLPtr->direct); if (!first_context) { first_context = OpenGLPtr->cx; } } if (!OpenGLPtr->cx) { Tcl_AppendResult(interp, "Error making GL context", (char*)NULL); return 0; } if (!OpenGLPtr->glx_win) return 0; #else hWnd = TkWinGetHWND(Tk_WindowId(OpenGLPtr->tkwin)); OpenGLPtr->hDC = GetDC(hWnd); if (!OpenGLPtr->cx) { OpenGLPtr->cx = wglCreateContext(OpenGLPtr->hDC); wglShareLists(first_context,OpenGLPtr->cx); if (!first_context) first_context = OpenGLPtr->cx; } if (!OpenGLPtr->cx) { Tcl_AppendResult(interp, "Error making GL context", (char*)NULL); printf("wglCreateContext() returned NULL; Error code: %d\n", (int)GetLastError()); return 0; } #endif return OpenGLPtr->cx; }
SCISHARE int OpenGLCmd(ClientData clientData, Tcl_Interp *interp, int argc, CONST84 char **argv) { Tk_Window mainwin = (Tk_Window) clientData; OpenGLClientData *OpenGLPtr; Colormap cmap; Tk_Window tkwin; XVisualInfo temp_vi; int tempid; int n; #ifndef _WIN32 int attributes[50]; int idx = 0; #endif if (argc < 2) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " pathName ?options?\"", (char *) NULL); return TCL_ERROR; } tkwin = Tk_CreateWindowFromPath(interp, mainwin, argv[1], (char *) NULL); if (tkwin == NULL) { return TCL_ERROR; } Tk_SetClass(tkwin, "OpenGL"); /* Allocate and initialize the widget record. */ OpenGLPtr = (OpenGLClientData *) ckalloc(sizeof(OpenGLClientData)); OpenGLPtr->geometry = 0; OpenGLPtr->cursor = 0; OpenGLPtr->interp = interp; OpenGLPtr->tkwin = tkwin; OpenGLPtr->display = Tk_Display(tkwin); OpenGLPtr->x11_win=0; OpenGLPtr->screen_number = Tk_ScreenNumber(tkwin); #ifndef _WIN32 OpenGLPtr->glx_win=0; OpenGLPtr->fb_configs=glXGetFBConfigs(OpenGLPtr->display, OpenGLPtr->screen_number, &(OpenGLPtr->num_fb)); #else OpenGLPtr->hDC = 0; #endif OpenGLPtr->vi=0; OpenGLPtr->cx=0; Tk_CreateEventHandler(OpenGLPtr->tkwin, StructureNotifyMask, OpenGLEventProc, (ClientData) OpenGLPtr); Tcl_CreateCommand(interp, Tk_PathName(OpenGLPtr->tkwin), OpenGLWidgetCmd, (ClientData) OpenGLPtr, (Tcl_CmdDeleteProc *)0); if (OpenGLConfigure(interp, OpenGLPtr, argc-2, argv+2, 0) != TCL_OK) { return TCL_ERROR; } tempid = OpenGLPtr->visualid; if (OpenGLPtr->visualid) { temp_vi.visualid = OpenGLPtr->visualid; OpenGLPtr->vi = XGetVisualInfo(OpenGLPtr->display, VisualIDMask, &temp_vi, &n); if(!OpenGLPtr->vi || n!=1) { Tcl_AppendResult(interp, "Error finding visual", NULL); return TCL_ERROR; } } else { /* * Pick the right visual... */ #ifndef _WIN32 attributes[idx++]=GLX_BUFFER_SIZE; attributes[idx++]=OpenGLPtr->buffersize; attributes[idx++]=GLX_LEVEL; attributes[idx++]=OpenGLPtr->level; if(OpenGLPtr->rgba) attributes[idx++]=GLX_RGBA; if(OpenGLPtr->doublebuffer) attributes[idx++]=GLX_DOUBLEBUFFER; if(OpenGLPtr->stereo) attributes[idx++]=GLX_STEREO; attributes[idx++]=GLX_AUX_BUFFERS; attributes[idx++]=OpenGLPtr->auxbuffers; attributes[idx++]=GLX_RED_SIZE; attributes[idx++]=OpenGLPtr->redsize; attributes[idx++]=GLX_GREEN_SIZE; attributes[idx++]=OpenGLPtr->greensize; attributes[idx++]=GLX_BLUE_SIZE; attributes[idx++]=OpenGLPtr->bluesize; attributes[idx++]=GLX_ALPHA_SIZE; attributes[idx++]=OpenGLPtr->alphasize; attributes[idx++]=GLX_DEPTH_SIZE; attributes[idx++]=OpenGLPtr->depthsize; attributes[idx++]=GLX_STENCIL_SIZE; attributes[idx++]=OpenGLPtr->stencilsize; attributes[idx++]=GLX_ACCUM_RED_SIZE; attributes[idx++]=OpenGLPtr->accumredsize; attributes[idx++]=GLX_ACCUM_GREEN_SIZE; attributes[idx++]=OpenGLPtr->accumgreensize; attributes[idx++]=GLX_ACCUM_BLUE_SIZE; attributes[idx++]=OpenGLPtr->accumbluesize; attributes[idx++]=GLX_ACCUM_ALPHA_SIZE; attributes[idx++]=OpenGLPtr->accumalphasize; attributes[idx++]=None; OpenGLPtr->vi = glXChooseVisual(OpenGLPtr->display, OpenGLPtr->screen_number, attributes); OpenGLPtr->visualid=tempid; #else // WIN32 // I am using the *PixelFormat commands from win32 because according // to the Windows page, we should prefer this to wgl*PixelFormatARB. // Unfortunately, this means that the Windows code will differ // substantially from that of other platforms. However, it has the // advantage that we don't have to use the wglGetProc to get // the procedure address, or test to see if the applicable extension // is supported. WM:VI HWND hWnd = TkWinGetHWND(Tk_WindowId(OpenGLPtr->tkwin)); // a little ugly, but we need this to be defined before pfd, and // we need to follow C initialization rules DWORD dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | (OpenGLPtr->doublebuffer ? PFD_DOUBLEBUFFER : 0) | (OpenGLPtr->stereo ? PFD_STEREO : 0); int iPixelFormat; XVisualInfo xvi; int n_ret; PIXELFORMATDESCRIPTOR pfd = { sizeof(PIXELFORMATDESCRIPTOR), // size of this pfd 1, // version number dwFlags, PFD_TYPE_RGBA, // RGBA type OpenGLPtr->buffersize, // color depth OpenGLPtr->redsize, 0, OpenGLPtr->greensize, 0, OpenGLPtr->bluesize, 0, // color bits OpenGLPtr->alphasize,0, // alpha buffer OpenGLPtr->accumredsize+ OpenGLPtr->accumgreensize+ OpenGLPtr->accumbluesize,// accumulation buffer OpenGLPtr->accumredsize, OpenGLPtr->accumgreensize, OpenGLPtr->accumbluesize, OpenGLPtr->accumalphasize,// accum bits OpenGLPtr->depthsize, // 32-bit z-buffer OpenGLPtr->stencilsize,// no stencil buffer OpenGLPtr->auxbuffers, // no auxiliary buffer PFD_MAIN_PLANE, // main layer 0, // reserved 0, 0, 0 // layer masks ignored }; iPixelFormat = ChoosePixelFormat(OpenGLPtr->hDC, &pfd); SetPixelFormat(OpenGLPtr->hDC, iPixelFormat, &pfd); OpenGLPtr->visualid = iPixelFormat; OpenGLPtr->hDC = GetDC(hWnd); xvi.screen = OpenGLPtr->screen_number; n_ret=0; OpenGLPtr->vi = XGetVisualInfo(OpenGLPtr->display, VisualScreenMask, &xvi, &n_ret); #endif if (!OpenGLPtr->vi) { Tcl_AppendResult(interp, "Error selecting visual", (char*)NULL); return TCL_ERROR; } } cmap = XCreateColormap(OpenGLPtr->display, Tk_WindowId(Tk_MainWindow(OpenGLPtr->interp)), OpenGLPtr->vi->visual, AllocNone); if(Tk_SetWindowVisual(OpenGLPtr->tkwin, OpenGLPtr->vi->visual, OpenGLPtr->vi->depth, cmap) != 1) { Tcl_AppendResult(interp, "Error setting visual for window", (char*)NULL); return TCL_ERROR; } XSync(OpenGLPtr->display, False); Tcl_SetResult(interp,Tk_PathName(OpenGLPtr->tkwin),TCL_STATIC); return TCL_OK; }
void XCompcapMain::tick(float seconds) { UNUSED_PARAMETER(seconds); if (!obs_source_showing(p->source)) return; PLock lock(&p->lock, true); if (!lock.isLocked()) return; XCompcap::processEvents(); if (XCompcap::windowWasReconfigured(p->win)) updateSettings(0); XErrorLock xlock; xlock.resetError(); XWindowAttributes attr; if (!XGetWindowAttributes(xdisp, p->win, &attr)) { Window newWin = getWindowFromString(p->windowName); if (XGetWindowAttributes(xdisp, newWin, &attr)) { p->win = newWin; updateSettings(0); } return; } if (!p->tex || !p->gltex) return; obs_enter_graphics(); if (p->lockX) { XLockDisplay(xdisp); XSync(xdisp, 0); } if (p->include_border) { gs_copy_texture_region( p->tex, 0, 0, p->gltex, p->cur_cut_left, p->cur_cut_top, width(), height()); } else { gs_copy_texture_region( p->tex, 0, 0, p->gltex, p->cur_cut_left + p->border, p->cur_cut_top + p->border, width(), height()); } if (p->cursor && p->show_cursor) { xcursor_tick(p->cursor); p->cursor_outside = p->cursor->x < p->cur_cut_left || p->cursor->y < p->cur_cut_top || p->cursor->x > int(p->width - p->cur_cut_right) || p->cursor->y > int(p->height - p->cur_cut_bot); } if (p->lockX) XUnlockDisplay(xdisp); obs_leave_graphics(); }
/* pow(gradient,2) = pow(differencex,2)+pow(differencey,2) */ void gradient_filter(){ int i,j,first; matrix m; float mask[2]={1,-1}; matrix dx, dy, gradient; float rmax, rmin, rng; /* Fill in the image with background color */ for(i=0; i<IMAGE_WIDTH; i++) for(j=0; j<IMAGE_HEIGHT; j++) XPutPixel(theXImage_2,i,j,bg); /* Clear the drawing window so the image is displayed again */ XClearArea(XtDisplay(draw_1),XtWindow(draw_2),0,0,0,0,True); /* Associate the watch cursor with the main window */ XDefineCursor(XtDisplay(draw_1), XtWindow(main_window), theCursor); /* Flush the request buffer and wait for all events */ /* and errors to be processed by the server. */ XSync(XtDisplay(draw_1), False); /* Storing the image in a matrix */ for(i=0;i<IMAGE_WIDTH;i++) for(j=0;j<IMAGE_HEIGHT;j++) m[i][j]= XGetPixel(theXImage_1,i,j); /* Taking differences between the values of horizontally adjacent pixels */ convo_vectorx(m, mask, 1, &rmax, &rmin, dx); /* Taking differences between the values of vertical adjacent pixels */ convo_vectory(m, mask, 1, &rmax, &rmin, dy); first=1; for(i=0;i<IMAGE_WIDTH;i++) for(j=0;j<IMAGE_HEIGHT;j++){ gradient[i][j] = sqrt(pow(dx[i][j],2)+pow(dy[i][j],2)); if (first==1){ rmax = gradient[i][j]; rmin = rmax; first = 2;} if (gradient[i][j]<rmin) rmin = gradient[i][j]; if (gradient[i][j]>rmax) rmax = gradient[i][j]; } rng = (rmax-rmin); for(i=0;i<512;i++) for(j=0;j<511;j++) XPutPixel(theXImage_2,i,j,(unsigned long) (((float)(gradient[i][j]-rmin)/rng)*255.0)); /* Copy image into pixmap */ XPutImage(XtDisplay(draw_2), thePixmap_2, image_gc_2, theXImage_2, 0, 0, 0, 0, theXImage_2->width, theXImage_2->height); /* Disassociate the watch cursor from the main window */ XUndefineCursor(XtDisplay(draw_1), XtWindow(main_window)); /* Clear the drawing window so the image is displayed again */ XClearArea(XtDisplay(draw_2),XtWindow(draw_2),0,0,0,0,True); }
void CL_DisplayWindow_OpenGL::create_window(const CL_DisplayWindowDescription &desc) { const CL_OpenGLWindowDescription_Generic *gl_desc = 0; gl_desc = dynamic_cast<const CL_OpenGLWindowDescription_Generic*>(desc.impl.get()); fullscreen_width = desc.get_size().width; fullscreen_height = desc.get_size().height; XVisualInfo *vi; Colormap cmap; if (disp == 0) { disp = XOpenDisplay(0); if (disp == 0) throw CL_Error("Could not open X11 display!"); } disp_ref_count++; int gl_attribs_single[] = { GLX_RGBA, GLX_RED_SIZE, 4, GLX_GREEN_SIZE, 4, GLX_BLUE_SIZE, 4, GLX_DEPTH_SIZE, 16, None }; int gl_attribs[32]; int i = 0; if( gl_desc ) { if( gl_desc->rgba ) gl_attribs[i++] = GLX_RGBA; if( gl_desc->doublebuffer ) gl_attribs[i++] = GLX_DOUBLEBUFFER; if( gl_desc->stereo ) gl_attribs[i++] = GLX_STEREO; gl_attribs[i++] = GLX_BUFFER_SIZE; gl_attribs[i++] = gl_desc->buffer_size; gl_attribs[i++] = GLX_LEVEL; gl_attribs[i++] = gl_desc->level; gl_attribs[i++] = GLX_AUX_BUFFERS; gl_attribs[i++] = gl_desc->aux_buffers; gl_attribs[i++] = GLX_RED_SIZE; gl_attribs[i++] = gl_desc->red_size; gl_attribs[i++] = GLX_GREEN_SIZE; gl_attribs[i++] = gl_desc->green_size; gl_attribs[i++] = GLX_BLUE_SIZE; gl_attribs[i++] = gl_desc->blue_size; gl_attribs[i++] = GLX_DEPTH_SIZE; gl_attribs[i++] = gl_desc->depth_size; gl_attribs[i++] = GLX_STENCIL_SIZE; gl_attribs[i++] = gl_desc->stencil_size; gl_attribs[i++] = GLX_ACCUM_RED_SIZE; gl_attribs[i++] = gl_desc->accum_red_size; gl_attribs[i++] = GLX_ACCUM_GREEN_SIZE; gl_attribs[i++] = gl_desc->accum_green_size; gl_attribs[i++] = GLX_ACCUM_BLUE_SIZE; gl_attribs[i++] = gl_desc->accum_blue_size; gl_attribs[i++] = GLX_ACCUM_ALPHA_SIZE; gl_attribs[i++] = gl_desc->accum_alpha_size; gl_attribs[i++] = GLX_ACCUM_RED_SIZE; gl_attribs[i++] = gl_desc->accum_red_size; gl_attribs[i++] = None; } else { gl_attribs[i++] = GLX_RGBA; gl_attribs[i++] = GLX_DOUBLEBUFFER; gl_attribs[i++] = GLX_RED_SIZE; gl_attribs[i++] = 4; gl_attribs[i++] = GLX_GREEN_SIZE; gl_attribs[i++] = 4; gl_attribs[i++] = GLX_BLUE_SIZE; gl_attribs[i++] = 4; gl_attribs[i++] = GLX_DEPTH_SIZE; gl_attribs[i++] = 16; gl_attribs[i++] = None; } // get an appropriate visual vi = glXChooseVisual(disp, DefaultScreen(disp), gl_attribs); if (vi == NULL) { vi = glXChooseVisual(disp, window, gl_attribs_single); printf("Requested visual not supported by your OpenGL implementation. Falling back on singlebuffered Visual!\n"); } // create a GLX context context = glXCreateContext(disp, vi, share_context, True); if( share_context == NULL ) share_context = context; glXGetConfig(disp, vi, GLX_BUFFER_SIZE, &glx_bpp); // create a color map cmap = XCreateColormap( disp, RootWindow(disp, vi->screen), vi->visual, AllocNone); attributes.colormap = cmap; attributes.border_pixel = 0; attributes.override_redirect = False; // create a window in window mode attributes.event_mask = ExposureMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | StructureNotifyMask | PointerMotionMask | EnterWindowMask | LeaveWindowMask | FocusChangeMask; window = XCreateWindow(disp, RootWindow(disp, vi->screen), 0, 0, desc.get_size().width, desc.get_size().height, 0, vi->depth, InputOutput, vi->visual, CWBorderPixel | CWColormap | CWOverrideRedirect | CWEventMask, &attributes); XSelectInput(disp, window, FocusChangeMask | KeyPressMask | KeyReleaseMask | PropertyChangeMask | StructureNotifyMask | KeymapStateMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask); // set title of window: set_title(desc.get_title()); // setup size hints: XSizeHints size_hints; memset(&size_hints, 0, sizeof(XSizeHints)); size_hints.width = desc.get_size().width; size_hints.height = desc.get_size().height; size_hints.base_width = desc.get_size().width; size_hints.base_height = desc.get_size().height; size_hints.min_width = size_hints.width; size_hints.min_height = size_hints.height; size_hints.max_width = size_hints.width; size_hints.max_height = size_hints.height; size_hints.flags = PSize|PBaseSize; if (!desc.get_allow_resize()) size_hints.flags |= PMinSize | PMaxSize; XSetWMNormalHints(disp, window, &size_hints); // handle wm_delete_events if in windowed mode: Atom wm_delete = XInternAtom(disp, "WM_DELETE_WINDOW", True); XSetWMProtocols(disp, window, &wm_delete, 1); // make window visible: XMapRaised(disp, window); if (!glXIsDirect(disp, context)) printf("No hardware acceleration available. I hope you got a really fast machine..\n"); // Create input devices for window: keyboard = CL_InputDevice(new CL_InputDevice_X11Keyboard(this)); mouse = CL_InputDevice(new CL_InputDevice_X11Mouse(this)); get_ic()->clear(); get_ic()->add_keyboard(keyboard); get_ic()->add_mouse(mouse); setup_joysticks(); // setup_usb_mice(); // setup_xinput(); // setup_event(); XSync(disp, True); focus = true; system_cursor = XCreateFontCursor(disp, XC_left_ptr); char *data = (char*)malloc(64); // 8x8 memset(data, 0, 64); XColor black_color; memset(&black_color, 0, sizeof(black_color)); cursor_bitmap = XCreateBitmapFromData(disp, window, data, 8, 8); hidden_cursor = XCreatePixmapCursor(disp, cursor_bitmap, cursor_bitmap, &black_color, &black_color, 0,0 ); if (desc.is_fullscreen()) set_fullscreen(desc.get_size().width, desc.get_size().height, desc.get_bpp(), desc.get_refresh_rate()); }
void d2gaussian_filter(float sigma){ int i,j,length_d2gaussian,lon,start; float rmax, rmin, rng, value, mask_d2gaussian[SIZE2][SIZE2]; float d2gaussian[SIZE1]; matrix m,resul,d2erix,d2eriy; /* Fill in the image with background color */ for(i=0; i<IMAGE_WIDTH; i++) for(j=0; j<IMAGE_HEIGHT; j++) XPutPixel(theXImage_2,i,j,bg); /* Clear the drawing window so the image is displayed again */ XClearArea(XtDisplay(draw_1),XtWindow(draw_2),0,0,0,0,True); /* Associate the watch cursor with the main window */ XDefineCursor(XtDisplay(draw_1), XtWindow(main_window), theCursor); /* Flush the request buffer and wait for all events */ /* and errors to be processed by the server. */ XSync(XtDisplay(draw_1), False); /* Storing the matrix we want to process in m */ for(i=0;i<IMAGE_WIDTH;i++) for(j=0;j<IMAGE_HEIGHT;j++) m[i][j]= XGetPixel(theXImage_1,i,j); get_2derigaussian(sigma, d2gaussian, &length_d2gaussian); fprintf(stderr,"la long es %i \n",length_d2gaussian); /* Only the values higher than 0.01 are desirable */ start=0; value=pow(d2gaussian[0],2); fprintf(stderr,"el top es %f\n",top); while (value<0.01*pow(top,2)){ start += 1; value = pow(d2gaussian[start],2); } for(i=start;i<=length_d2gaussian-start;i++) for(j=start;j<=length_d2gaussian-start;j++){ mask_d2gaussian[i-start][j-start]= d2gaussian[i]*d2gaussian[j]; fprintf(stderr,"la %i,%i es %f, \n",i-start,j-start, mask_d2gaussian[i-start][j-start]); } length_d2gaussian = length_d2gaussian - (2*start); fprintf(stderr,"la long es %i \n",length_d2gaussian); convolution(m,mask_d2gaussian,length_d2gaussian,&rmax,&rmin,resul); /* convo_vectorx(m,d2gaussian,length_d2gaussian,&rmax,&rmin,d2erix); convo_vectory(m,d2gaussian,length_d2gaussian,&rmax,&rmin,d2eriy); for(i=0;i<IMAGE_WIDTH;i++) for(j=0;j<IMAGE_HEIGHT;j++){ resul[i][j]=sqrt(pow(d2erix[i][j],2)+pow(d2eriy[i][j],2)); if (i==0 && j==0){rmax=resul[0][0]; rmin=rmax;} if (resul[i][j]>rmax) rmax=resul[i][j]; if (resul[i][j]<rmin) rmin=resul[i][j]; } rng=(rmax-rmin); for(i=0;i<IMAGE_WIDTH;i++) for(j=0;j<IMAGE_HEIGHT;j++) XPutPixel(theXImage_2,i,j,(unsigned long) (((float)(resul[i][j]-rmin)/rng)*255.0));*/ rng = (float) (rmax - rmin); lon = length_d2gaussian/2; /* Now compute the convolution, scaling. */ for (i=lon; i<IMAGE_WIDTH-lon; i++) for (j=lon; j<IMAGE_HEIGHT-lon; j++) XPutPixel(theXImage_2,i,j, (unsigned long) (((float)(resul[i][j]-rmin)/rng)*255.0)); /* Copy image into pixmap. */ XPutImage(XtDisplay(draw_2), thePixmap_2,image_gc_2, theXImage_2, 0, 0, 0, 0, theXImage_2->width, theXImage_2->height); /* Disassociate the watch cursor from the main window */ XUndefineCursor(XtDisplay(draw_1), XtWindow(main_window)); /* Clear the drawing window so the image is displayed again */ XClearArea(XtDisplay(draw_2),XtWindow(draw_2),0,0,0,0,True); }
void CL_DisplayWindow_OpenGL::set_fullscreen(int width, int height, int bpp, int refresh_rate) { if(fullscreen) return; // Vid-mode Switching XF86VidModeModeLine cur_mode; XF86VidModeGetModeLine(disp, 0, &dotclock, &cur_mode); old_mode.dotclock = dotclock; old_mode.hdisplay = cur_mode.hdisplay; old_mode.hsyncstart = cur_mode.hsyncstart; old_mode.hsyncend = cur_mode.hsyncend; old_mode.htotal = cur_mode.htotal; old_mode.vdisplay = cur_mode.vdisplay; old_mode.vsyncstart = cur_mode.vsyncstart; old_mode.vsyncend = cur_mode.vsyncend; old_mode.vtotal = cur_mode.vtotal; old_mode.flags = cur_mode.flags; old_mode.privsize = 0; int num_modes; XF86VidModeModeInfo **modes; XF86VidModeGetAllModeLines(disp, 0, &num_modes, &modes); std::list<XF86VidModeModeInfo *> usable_modes; for(int i = 0; i < num_modes; i++) { if(modes[i]->hdisplay == width && modes[i]->vdisplay == height) { CL_Log::log("debug", "Useable fullscreen mode found: %1x%2", width, height); usable_modes.push_back(modes[i]); } } if (usable_modes.empty()) { CL_Log::log("debug", "No useable fullscreen modes available!"); } else { if(!width) width = get_width(); if(!height) height = get_height(); if(!bpp) bpp = glx_bpp; //Hide Window if (0) { // FIXME: allow_override doesn't play together with // GrabPointer, not sure what is wrong but it simply doesn't // work. // // The code outside the 'if(0)' as it is now, works mostly, // however it doesn't work when the window or a part of it is // outside of the screen, since the window isn't moved // fullscreen will only show half the window, shouldn't be a // problem for most of the time, but will be tricky if the // window has equal size as the desktop. // Move the window into the right position, this must happen // BEFORE we remove control from the window manager XMoveResizeWindow(disp, window, 0, 0, width, height); // Move the mouse and switch moves XWarpPointer(disp, None, None, 0, 0, 0, 0, width/2, height/2); XUnmapWindow(disp, window); { // Wait for window to disapear XEvent event; do { XMaskEvent(disp, StructureNotifyMask, &event); } while ( (event.type != UnmapNotify) || (event.xunmap.event != window) ); } // Turn off WM control attributes.override_redirect = True; XChangeWindowAttributes(disp, window, CWBorderPixel | CWColormap | CWOverrideRedirect, &attributes); // Re-appear window XMapRaised(disp, window); } // Get input focus //XSetInputFocus(disp,window, RevertToNone, CurrentTime); while (1) { int result = XGrabPointer(disp, window, True, 0, GrabModeAsync, GrabModeAsync, window, None, CurrentTime); if ( result == GrabSuccess ) { break; } CL_System::sleep(100); } XF86VidModeGetViewPort(disp, DefaultScreen(disp), &old_x, &old_y); XF86VidModeSwitchToMode(disp, 0, *(usable_modes.begin())); Window child_window; int x, y; // Get the windows absolute position (aka relative to // the root window) XTranslateCoordinates(disp, window, DefaultRootWindow(disp), 0, 0, &x, &y, &child_window); XF86VidModeSetViewPort(disp, DefaultScreen(disp), x, y); XSync(disp, True); fullscreen = true; } }
/* Gradient_x_y = sqrt(pow(gaussian_x,2)+pow(gaussian_y,2) */ void gradient_x_y_filter(float sigma){ int i,j,k,length_deriv; float deriv_gaussian[SIZE1]; matrix dgaux, dgauy, gradient_x_y, m; float rmin,rmax,rng; /* Fill in the image with background color */ for(i=0; i<IMAGE_WIDTH; i++) for(j=0; j<IMAGE_HEIGHT; j++) XPutPixel(theXImage_2,i,j,bg); /* Clear the drawing window so the image is displayed again */ XClearArea(XtDisplay(draw_1),XtWindow(draw_2),0,0,0,0,True); /* Associate the watch cursor with the main window */ XDefineCursor(XtDisplay(draw_1), XtWindow(main_window), theCursor); /* Flush the request buffer and wait for all events */ /* and errors to be processed by the server. */ XSync(XtDisplay(draw_1), False); get_derigaussian(sigma,deriv_gaussian,&length_deriv); for(i=0;i<IMAGE_WIDTH;i++) for(j=0;j<IMAGE_HEIGHT;j++) m[i][j]= XGetPixel(theXImage_1,i,j); /* Apply convolution with derivative of a gaussian to the rows */ convo_vectorx(m,deriv_gaussian,length_deriv,&rmax,&rmin,dgaux); /* Apply convolution with derivative of a gaussian to the columns */ convo_vectory(m,deriv_gaussian,length_deriv,&rmax,&rmin,dgauy); for(i=0;i<IMAGE_WIDTH;i++) for(j=0;j<IMAGE_HEIGHT;j++){ gradient_x_y[i][j]=sqrt(pow(dgaux[i][j],2)+ pow(dgauy[i][j],2)); if (i==0 && j==0){rmax=gradient_x_y[0][0]; rmin=rmax;} if (gradient_x_y[i][j]>rmax) rmax=gradient_x_y[i][j]; if (gradient_x_y[i][j]<rmin) rmin=gradient_x_y[i][j]; } rng=(rmax-rmin); for(i=0;i<IMAGE_WIDTH;i++) for(j=0;j<IMAGE_HEIGHT;j++) XPutPixel(theXImage_2,i,j,(unsigned long) (((float)(gradient_x_y[i][j]-rmin)/rng)*255.0)); /* Copy image into pixmap */ XPutImage(XtDisplay(draw_2), thePixmap_2,image_gc_2, theXImage_2, 0, 0, 0, 0, theXImage_2->width, theXImage_2->height); /* Disassociate the watch cursor from the main window */ XUndefineCursor(XtDisplay(draw_1), XtWindow(main_window)); /* Clear the drawing window so the image is displayed again */ XClearArea(XtDisplay(draw_2),XtWindow(draw_2),0,0,0,0,True); }
int main(int argc,char* argv[]) { XtAppContext app; int sig_Number; int sig_Signal[] = { SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGTRAP, #if defined(SIGIOT) SIGIOT, #endif SIGABRT, #if defined(SIGEMT) SIGEMT, #endif SIGFPE, SIGBUS, SIGSEGV, #if defined(SIGSYS) SIGSYS, #endif SIGTERM, #if defined(SIGXCPU) SIGXCPU, #endif #if defined(SIGXFSZ) SIGXFSZ, #endif #if defined(SIGDANGER) SIGDANGER, #endif -1 }; Widget app_App; Display* dpy; Window win_Root; XWindowAttributes attr_Win; XGCValues gc_ValFore; XGCValues gc_ValBack; GC gc_GcFore; GC gc_GcBack; XFontStruct* font_Font; char* font_List[] = { "-*-character-*-r-*-*-*-600-*-*-p-*-*-*", "-*-helvetica-*-r-*-*-*-600-*-*-p-*-*-*", "-*-lucida-*-r-*-*-*-600-*-*-p-*-*-*", "-*-*-*-r-*-sans-*-600-*-*-p-*-*-*", "-*-*-*-r-*-*-*-600-*-*-m-*-*-*", "-*-helvetica-*-r-*-*-*-240-*-*-p-*-*-*", "-*-lucida-*-r-*-*-*-240-*-*-p-*-*-*", "-*-*-*-r-*-sans-*-240-*-*-p-*-*-*", "-*-*-*-r-*-*-*-240-*-*-m-*-*-*", "fixed", NULL }; int font_Index; int text_Length; int text_X; int text_Y; int text_Width; int text_Height; char* text_List[XSUBLIM_TEXT_COUNT]; int text_Used[XSUBLIM_TEXT_COUNT]; char text_Text[XSUBLIM_TEXT_LENGTH+1]; char* text_Phrase; char* text_Word; int text_Index; int text_Item; int text_Count; struct { int outline_X; int outline_Y; } text_Outline[] = { { -1,-1 }, { 1,-1 }, { -1, 1 }, { 1, 1 }, { 0, 0 } }; int text_OutlineIndex; XImage* image_Image = NULL; int image_X = 0; int image_Y = 0; int image_Width = 0; int image_Height = 0; int arg_Count; int arg_FlagCenter; int arg_FlagOutline; int arg_FlagScreensaver; int arg_FlagRandom; int arg_DelayShow; int arg_DelayWord; int arg_DelayPhraseMin; int arg_DelayPhraseMax; char* arg_Text; char* arg_Source; /* Set-up ---------------------------------------------------------- */ /* Catch signals */ Xsublim_Sig_Last = -1; for (sig_Number = 0;sig_Signal[sig_Number] != -1;sig_Number++) { signal(sig_Number,xsublim_Sig_Catch); } /* Randomize -- only need to do this here because this program doesn't use the `screenhack.h' or `lockmore.h' APIs. */ # undef ya_rand_init ya_rand_init (0); /* Handle all the X nonsense */ #if defined(__sgi) SgiUseSchemes("none"); #endif for (arg_Count = 0;options[arg_Count].option != NULL;arg_Count++) { ; } app_App = XtAppInitialize(&app,progclass,options,arg_Count,&argc,argv, defaults,0,0); /* jwz */ if (argc > 1) { int x = 18; int end = 78; int i; int count = (sizeof(options)/sizeof(*options))-1; fprintf(stderr, "Unrecognised option: %s\n", argv[1]); fprintf (stderr, "Options include: "); for (i = 0; i < count; i++) { char *sw = options [i].option; Bool argp = (options [i].argKind == XrmoptionSepArg); int size = strlen (sw) + (argp ? 6 : 0) + 2; if (x + size >= end) { fprintf (stderr, "\n\t\t "); x = 18; } x += size; fprintf (stderr, "%s", sw); if (argp) fprintf (stderr, " <arg>"); if (i != count-1) fprintf (stderr, ", "); } fprintf (stderr, ".\n"); exit (-1); } dpy = XtDisplay(app_App); XtGetApplicationNameAndClass(dpy,&progname,&progclass); win_Root = RootWindowOfScreen(XtScreen(app_App)); XtDestroyWidget(app_App); /* Get the arguments */ arg_FlagCenter = get_boolean_resource(dpy, XSUBLIM_ARG_CENTER,"Boolean"); arg_FlagOutline = get_boolean_resource(dpy, XSUBLIM_ARG_OUTLINE,"Boolean"); arg_FlagScreensaver = get_boolean_resource(dpy, XSUBLIM_ARG_SCREENSAVER, "Boolean"); arg_FlagRandom = get_boolean_resource(dpy, XSUBLIM_ARG_RANDOM,"Boolean"); arg_DelayShow = get_integer_resource(dpy, XSUBLIM_ARG_DELAYSHOW,"Integer"); arg_DelayWord = get_integer_resource(dpy, XSUBLIM_ARG_DELAYWORD,"Integer"); arg_DelayPhraseMin = get_integer_resource(dpy, XSUBLIM_ARG_DELAYPHRASEMIN, "Integer"); arg_DelayPhraseMax = get_integer_resource(dpy, XSUBLIM_ARG_DELAYPHRASEMAX, "Integer"); if (arg_DelayPhraseMax < arg_DelayPhraseMin) { arg_DelayPhraseMax = arg_DelayPhraseMin; } /* Get the phrases */ text_Index = 0; text_Item = 0; text_Count = 0; memset(text_Used,0,sizeof(text_Used)); arg_Source = get_string_resource(dpy, XSUBLIM_ARG_FILE,"Filename"); if (arg_Source != NULL) { FILE* file_Fs; struct stat file_Stat; file_Fs = fopen(arg_Source,"rb"); if (file_Fs == NULL) { fprintf(stderr,"%s: Could not open '%s'\n",progname, arg_Source); exit(-1); } if (fstat(fileno(file_Fs),&file_Stat) != 0) { fprintf(stderr,"%s: Could not stat '%s'\n",progname, arg_Source); exit(-1); } arg_Text = calloc(1,file_Stat.st_size+1); if (arg_Text != NULL) { if (fread(arg_Text,file_Stat.st_size,1,file_Fs) != 1) { fprintf(stderr,"%s: Could not read '%s'\n", progname,arg_Source); exit(-1); } } fclose(file_Fs); } else { arg_Source = get_string_resource(dpy, XSUBLIM_ARG_PROGRAM, "Executable"); if (arg_Source != NULL) { char* exe_Command = calloc(1,strlen(arg_Source)+10); FILE* exe_Fs; if (exe_Command == NULL) { fprintf(stderr, "%s: Could not allocate space for '%s'\n", progname,arg_Source); exit(-1); } sprintf(exe_Command,"( %s ) 2>&1",arg_Source); exe_Fs = popen(exe_Command,"r"); if (exe_Fs == NULL) { fprintf(stderr,"%s: Could not run '%s'\n", progname,arg_Source); exit(-1); } arg_Text = calloc(1,XSUBLIM_PROGRAM_SIZE); if (arg_Text != NULL) { if (fread(arg_Text,1,XSUBLIM_PROGRAM_SIZE, exe_Fs) <= 0) { fprintf(stderr, "%s: Could not read output of '%s'\n", progname,arg_Source); exit(-1); } if ( strstr(arg_Text,": not found") || strstr(arg_Text,": Not found") || strstr(arg_Text,": command not found") || strstr(arg_Text,": Command not found")) { fprintf(stderr, "%s: Could not find '%s'\n", progname,arg_Source); exit(-1); } } fclose(exe_Fs); } else { arg_Text = get_string_resource(dpy, XSUBLIM_ARG_PHRASES,"Phrases"); if (arg_Text != NULL) { arg_Text = strdup(arg_Text); } } } if (arg_Text != NULL) { while (((text_Phrase = strtok(arg_Text,"\n")) != NULL) && (text_Count < XSUBLIM_TEXT_COUNT)) { arg_Text = NULL; text_List[text_Count] = text_Phrase; text_Count++; } text_List[text_Count] = NULL; } if (text_Count == 0) { fprintf(stderr,"%s: No text to display\n",progname); exit(-1); } /* Load the font */ font_Font = load_font_retry(dpy, get_string_resource(dpy, XSUBLIM_ARG_FONT,"Font")); font_Index = 0; while ((font_Font == NULL) && (font_List[font_Index] != NULL)) { font_Font = load_font_retry(dpy,font_List[font_Index]); font_Index++; } if (font_Font == NULL) { fprintf(stderr,"%s: Couldn't load a font\n",progname); exit(-1); } /* Create the GCs */ XGetWindowAttributes(dpy,win_Root,&attr_Win); gc_ValFore.font = font_Font->fid; gc_ValFore.foreground = get_pixel_resource(dpy, attr_Win.colormap, "foreground","Foreground"); gc_ValFore.background = get_pixel_resource(dpy, attr_Win.colormap, "background","Background"); gc_ValFore.subwindow_mode = IncludeInferiors; gc_GcFore = XCreateGC(dpy,win_Root, (GCFont|GCForeground|GCBackground|GCSubwindowMode),&gc_ValFore); gc_ValBack.font = font_Font->fid; gc_ValBack.foreground = get_pixel_resource(dpy, attr_Win.colormap, "background","Background"); gc_ValBack.background = get_pixel_resource(dpy, attr_Win.colormap, "foreground","Foreground"); gc_ValBack.subwindow_mode = IncludeInferiors; gc_GcBack = XCreateGC(dpy,win_Root, (GCFont|GCForeground|GCBackground|GCSubwindowMode),&gc_ValBack); /* Loop ------------------------------------------------------------ */ while (Xsublim_Sig_Last == -1) { /* Once-per-phrase stuff ----------------------------------- */ /* If we're waiting for a screensaver... */ if (arg_FlagScreensaver != FALSE) { /* Find the screensaver's window */ win_Root = xsublim_Ss_GetWindow(dpy); if (win_Root == 0) { usleep(30000000); continue; } } /* Pick the next phrase */ if (arg_FlagRandom != FALSE) { text_Item = random()%text_Count; text_Index = 0; } while (text_Used[text_Item] != FALSE) { text_Index++; text_Item++; if (text_Index == text_Count) { text_Index = 0; memset(text_Used,0,sizeof(text_Used)); } if (text_List[text_Item] == NULL) { text_Item = 0; } } text_Used[text_Item] = TRUE; strncpy(text_Text,text_List[text_Item], XSUBLIM_TEXT_LENGTH); text_Phrase = text_Text; /* Run through the phrase */ while (((text_Word = strtok(text_Phrase," \t")) != NULL) && (Xsublim_Sig_Last == -1)) { text_Phrase = NULL; /* Once-per-word stuff ----------------------------- */ /* Find the text's position */ XGetWindowAttributes(dpy,win_Root,&attr_Win); text_Length = strlen(text_Word); text_Width = XTextWidth(font_Font,text_Word, text_Length)+XSUBLIM_TEXT_OUTLINE*2; text_Height = font_Font->ascent+font_Font->descent+1+ XSUBLIM_TEXT_OUTLINE*2; if (arg_FlagCenter == FALSE) { text_X = random()%(attr_Win.width-text_Width); text_Y = random()%(attr_Win.height- text_Height); } else { text_X = (attr_Win.width/2)-(text_Width/2); text_Y = (attr_Win.height/2)-(text_Height/2); } /* Find the image's position (and pad it out slightly, otherwise bits of letter get left behind -- are there boundry issues I don't know about?) */ image_X = text_X-16; image_Y = text_Y; image_Width = text_Width+32; image_Height = text_Height; if (image_X < 0) { image_X = 0; } if (image_Y < 0) { image_Y = 0; } if (image_X+image_Width > attr_Win.width) { image_Width = attr_Win.width-image_X; } if (image_Y+image_Height > attr_Win.height) { image_Height = attr_Win.height-image_Y; } /* Influence people for our own ends --------------- */ /* Grab the server -- we can't let anybody draw over us */ XSync(dpy,FALSE); XGrabServer(dpy); XSync(dpy,FALSE); /* Set up an error handler that ignores BadMatches -- since the screensaver can take its window away at any time, any call that uses it might choke */ Xsublim_Sh_Status = 0; Xsublim_Sh_Handler = XSetErrorHandler(xsublim_Sh_Handler); /* Save the current background */ image_Image = XGetImage(dpy,win_Root,image_X, image_Y,image_Width,image_Height,~0L,ZPixmap); /* If we've successfully saved the background... */ if (image_Image != NULL) { if (Xsublim_Sh_Status == 0) { /* Draw the outline */ if (arg_FlagOutline != FALSE) { for (text_OutlineIndex = 0; text_Outline[ text_OutlineIndex].outline_X != 0;text_OutlineIndex++) { /* Y'know, eight character tabs and descriptive variable names become annoying at some point... */ XDrawString( dpy, win_Root,gc_GcBack, text_X+text_Outline[ text_OutlineIndex]. outline_X* XSUBLIM_TEXT_OUTLINE, text_Y+ (font_Font->ascent)+ text_Outline[ text_OutlineIndex]. outline_Y* XSUBLIM_TEXT_OUTLINE, text_Word, text_Length); } } /* Draw the word */ XDrawString(dpy,win_Root, gc_GcFore,text_X, text_Y+(font_Font->ascent),text_Word, text_Length); } if (Xsublim_Sh_Status == 0) { /* Wait a bit */ XSync(dpy,FALSE); if (Xsublim_Sig_Last == -1) { usleep(arg_DelayShow); } /* Restore the background */ XPutImage(dpy,win_Root, gc_GcFore,image_Image,0,0,image_X, image_Y,image_Width,image_Height); } /* Free the image */ XDestroyImage(image_Image); } /* Restore the error handler, ungrab the server */ XSync(dpy,FALSE); XSetErrorHandler(Xsublim_Sh_Handler); XUngrabServer(dpy); XSync(dpy,FALSE); /* Pause between words */ if (Xsublim_Sig_Last == -1) { usleep(arg_DelayWord); } } /* Pause between phrases */ if (Xsublim_Sig_Last == -1) { usleep(random()%(arg_DelayPhraseMax- arg_DelayPhraseMin+1)+arg_DelayPhraseMin); } } /* Exit ------------------------------------------------------------ */ for (sig_Number = 0;sig_Signal[sig_Number] != -1;sig_Number++) { signal(sig_Number,SIG_DFL); } kill(getpid(),Xsublim_Sig_Last); return 0; }
int main (void) { { Display *display = XOpenDisplay(NULL); if (! display) { abort (); } int major = 3; int minor = 1; XSyncInitialize(display, &major, &minor); XSyncValue value; XSyncIntToValue(&value, 0); XSyncCounter counter = XSyncCreateCounter(display, value); static XSyncWaitCondition wait_list[1]; XSyncIntToValue(&value, 123); wait_list[0].trigger.counter = counter; wait_list[0].trigger.value_type = XSyncAbsolute; wait_list[0].trigger.wait_value = value; wait_list[0].trigger.test_type = XSyncPositiveTransition; printf ("XSyncAwait call\n"); XSyncAwait(display, wait_list, 1); printf ("XSyncAwait return\n"); printf ("XSync call\n"); XSync(display, 0); printf ("XSync return\n"); return 0; } { Display *display = XOpenDisplay (NULL); if (! display) { abort (); } int major = 3; int minor = 1; XSyncInitialize(display, &major, &minor); XSyncValue value; XSyncIntToValue(&value, 0); XSyncCounter counter = XSyncCreateCounter(display, value); static XSyncWaitCondition wait_list[1]; XSyncIntToValue(&value, 123); wait_list[0].trigger.counter = counter; wait_list[0].trigger.value_type = XSyncAbsolute; wait_list[0].trigger.wait_value = value; wait_list[0].trigger.test_type = XSyncPositiveTransition; printf ("XSyncAwait call\n"); XSyncAwait(display, wait_list, 1); printf ("XSyncAwait return\n"); printf ("XSync call\n"); XSync(display, 0); printf ("XSync return\n"); return 0; } }
static Bool mb_wm_decor_sync_window (MBWMDecor *decor) { MBWindowManager *wm; XSetWindowAttributes attr; if (decor->parent_client == NULL) return False; wm = decor->parent_client->wmref; if (decor->xwin == None) { if (!decor->geom.width || !decor->geom.height) /* Don't bother creating 1-dimension windows, X would reject it * anyway, but we wouldn't notice the error. */ return False; attr.override_redirect = True; /*attr.background_pixel = WhitePixel(wm->xdpy, wm->xscreen);*/ attr.background_pixmap = None; attr.event_mask = ButtonPressMask|ButtonReleaseMask|ButtonMotionMask; XSync(wm->xdpy, False); mb_wm_util_trap_x_errors(); decor->xwin = XCreateWindow(wm->xdpy, wm->root_win->xwindow, decor->geom.x, decor->geom.y, decor->geom.width, decor->geom.height, 0, CopyFromParent, CopyFromParent, CopyFromParent, CWOverrideRedirect/*|CWBackPixel*/|CWEventMask, &attr); mb_wm_rename_window (wm, decor->xwin, "decor"); MBWM_DBG("g is +%i+%i %ix%i", decor->geom.x, decor->geom.y, decor->geom.width, decor->geom.height); if (mb_wm_util_untrap_x_errors()) return False; mb_wm_decor_resize(decor); mb_wm_util_list_foreach(decor->buttons, (MBWMListForEachCB)mb_wm_decor_button_sync_window, NULL); /* * If this is a decor with buttons, then we install button press handler * so we can drag the window, if it is movable. */ if (decor->type == MBWMDecorTypeNorth && decor->parent_client->layout_hints & LayoutPrefMovable) { /* g_debug ("%s: add ButtonPress handler for %lx", __FUNCTION__, decor->xwin); */ decor->press_cb_id = mb_wm_main_context_x_event_handler_add (wm->main_ctx, decor->xwin, ButtonPress, (MBWMXEventFunc)mb_wm_decor_press_handler, decor); } return mb_wm_decor_reparent (decor); } else { /* Resize */ mb_wm_util_async_trap_x_errors_warn(wm->xdpy, "XMoveResizeWindow"); XMoveResizeWindow(wm->xdpy, decor->xwin, decor->geom.x, decor->geom.y, decor->geom.width, decor->geom.height); mb_wm_util_async_untrap_x_errors(); /* Next up sort buttons */ mb_wm_util_list_foreach(decor->buttons, (MBWMListForEachCB)mb_wm_decor_button_sync_window, NULL); } return True; }
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; int (*old_handler)(Display*, XErrorEvent*) = NULL; 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); RARCH_LOG("[X/EGL]: Created context: %p.\n", (void*)g_egl_ctx); 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; RARCH_LOG("[X/EGL]: Current context: %p.\n", (void*)eglGetCurrentContext()); x11_set_window_attr(g_dpy, g_win); if (fullscreen) x11_show_mouse(g_dpy, g_win, false); if (true_full) { RARCH_LOG("[X/EGL]: 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); 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); // This can blow up on some drivers. It's not fatal, so override errors for this call. old_handler = XSetErrorHandler(nul_handler); XSetInputFocus(g_dpy, g_win, RevertToNone, CurrentTime); XSync(g_dpy, False); XSetErrorHandler(old_handler); 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; }
static Bool mb_wm_decor_button_press_handler (XButtonEvent *xev, void *userdata) { MBWMDecorButton *button = (MBWMDecorButton *)userdata; MBWMDecor *decor = button->decor; MBWindowManager *wm; MBWMList *transients = NULL; Bool retval = True; Bool unref_parent_client = False; if (!button->realized || !decor || !decor->parent_client) return False; wm = decor->parent_client->wmref; mb_wm_object_ref (MB_WM_OBJECT(button)); if (xev->window == decor->xwin) { int xmin, ymin, xmax, ymax; MBWMList *l; transients = l = mb_wm_client_get_transients (decor->parent_client); /* Ignore events on the main window decor if transients other than * input methods are present */ while (l) { MBWindowManagerClient * c = l->data; if (MB_WM_CLIENT_CLIENT_TYPE (c) != MBWMClientTypeInput && mb_wm_client_is_modal (c)) { retval = True; goto done; } l = l->next; } xmin = button->geom.x; ymin = button->geom.y; xmax = button->geom.x + button->geom.width; ymax = button->geom.y + button->geom.height; if (xev->x < xmin || xev->x > xmax || xev->y < ymin || xev->y > ymax) { XUngrabPointer(wm->xdpy, CurrentTime); retval = True; if (xev->type != ButtonRelease || xev->x < decor->geom.x || xev->x > decor->geom.x+decor->geom.width || xev->y < decor->geom.y || xev->y > decor->geom.x+decor->geom.height) goto done; g_debug("%s not on button -- send GRAB_TRANSFER", __FUNCTION__); mb_wm_client_deliver_message (decor->parent_client, wm->atoms[MBWM_ATOM_MB_GRAB_TRANSFER], xev->time, xev->subwindow, xev->button, 0, 0); XSync (wm->xdpy, False); /* Necessary */ goto done; } if (xev->type != ButtonPress) { retval = True; goto done; } g_debug("%s on button", __FUNCTION__); if (button->state != MBWMDecorButtonStatePressed) { button->state = MBWMDecorButtonStatePressed; mb_wm_theme_paint_button (wm->theme, button); } if (button->press_activated) { XUngrabPointer(wm->xdpy, CurrentTime); mb_wm_client_deliver_message (decor->parent_client, wm->atoms[MBWM_ATOM_MB_GRAB_TRANSFER], xev->time, xev->subwindow, xev->button, 0, 0); XSync (wm->xdpy, False); /* Necessary */ if (button->press) button->press(wm, button, button->userdata); else mb_wm_decor_button_stock_button_action (button); } else { XEvent ev; int status; /* * First, call the custom function if any. */ if (button->press) button->press(wm, button, button->userdata); mb_wm_util_async_trap_x_errors(wm->xdpy); status = XGrabPointer(wm->xdpy, xev->subwindow, False, ButtonPressMask|ButtonReleaseMask| PointerMotionMask|EnterWindowMask|LeaveWindowMask, GrabModeAsync, GrabModeAsync, None, None, CurrentTime); mb_wm_util_async_untrap_x_errors(); if (status == GrabSuccess) { /* set up release handler to catch ButtonRelease while we * are spinning the main loop */ decor->release_cb_id = mb_wm_main_context_x_event_handler_add ( wm->main_ctx, xev->subwindow, ButtonRelease, (MBWMXEventFunc)mb_wm_decor_release_handler, decor); if (button->state == MBWMDecorButtonStateInactive) { button->state = MBWMDecorButtonStatePressed; mb_wm_theme_paint_button (wm->theme, button); } /* reference the client for the loop, since it could be * unreffed while we are handling events there */ mb_wm_object_ref (MB_WM_OBJECT(decor->parent_client)); unref_parent_client = True; for (;;) { /* * First of all, we make sure that all events are flushed * out (this is necessary to ensure that all the events we * are interested in are actually intercepted here). */ XSync (wm->xdpy, False); /* * Someone might destroy the window while we are waiting for * the events here. */ if (!button->realized) { /* if the window disappeared, ungrab was done by X. Just remove the handler */ mb_wm_main_context_x_event_handler_remove ( wm->main_ctx, ButtonRelease, decor->release_cb_id); decor->release_cb_id = 0; retval = False; goto done; } if (!decor->release_cb_id) { /* the handler was called while we spinned the loop */ if (button->state == MBWMDecorButtonStatePressed) { button->state = MBWMDecorButtonStateInactive; mb_wm_theme_paint_button (wm->theme, button); } retval = False; goto done; } if (XCheckMaskEvent(wm->xdpy, ButtonPressMask|ButtonReleaseMask| PointerMotionMask|EnterWindowMask| LeaveWindowMask, &ev)) { switch (ev.type) { case MotionNotify: { XMotionEvent *pev = (XMotionEvent*)&ev; if (pev->x < xmin || pev->x > xmax || pev->y < ymin || pev->y > ymax) { if (button->state == MBWMDecorButtonStatePressed) { button->state = MBWMDecorButtonStateInactive; mb_wm_theme_paint_button (wm->theme,button); } } else { if (button->state != MBWMDecorButtonStatePressed) { button->state = MBWMDecorButtonStatePressed; mb_wm_theme_paint_button (wm->theme,button); } } } break; case EnterNotify: if (button->state == MBWMDecorButtonStateInactive) { button->state = MBWMDecorButtonStatePressed; mb_wm_theme_paint_button (wm->theme, button); } break; case LeaveNotify: if (button->state != MBWMDecorButtonStateInactive) { button->state = MBWMDecorButtonStateInactive; mb_wm_theme_paint_button (wm->theme, button); } break; case ButtonRelease: { XButtonEvent *pev = (XButtonEvent*)&ev; if (button->state != MBWMDecorButtonStateInactive) { button->state = MBWMDecorButtonStateInactive; mb_wm_theme_paint_button (wm->theme, button); } XUngrabPointer (wm->xdpy, CurrentTime); XSync (wm->xdpy, False); /* necessary */ mb_wm_main_context_x_event_handler_remove ( wm->main_ctx, ButtonRelease, decor->release_cb_id); decor->release_cb_id = 0; if (pev->x < xmin || pev->x > xmax || pev->y < ymin || pev->y > ymax) { retval = False; goto done; } if (button->release) button->release(wm, button, button->userdata); else mb_wm_decor_button_stock_button_action (button); retval = False; goto done; } } } else { /* * No pending X event, so spin the main loop (this allows * things like timers to work. */ if (!mb_wm_main_context_spin_loop (wm->main_ctx)) /* no events, sleep a while so we don't busy loop */ g_usleep (1000 * 100); } } } } retval = False; } done: mb_wm_util_list_free (transients); mb_wm_object_unref (MB_WM_OBJECT(button)); if (unref_parent_client) mb_wm_object_unref (MB_WM_OBJECT(decor->parent_client)); return retval; }
static void flip_page(void) { Display_Image(myximage, ImageData); XSync(mDisplay, False); }
UIOHOOK_API void hook_post_event(uiohook_event * const event) { XLockDisplay(properties_disp); #ifdef USE_XTEST // XTest does not have modifier support, so we fake it by depressing the // appropriate modifier keys. for (unsigned int i = 0; i < sizeof(keymask_lookup) / sizeof(KeySym); i++) { if (event->mask & 1 << i) { XTestFakeKeyEvent(properties_disp, XKeysymToKeycode(properties_disp, keymask_lookup[i]), True, 0); } } for (unsigned int i = 0; i < sizeof(btnmask_lookup) / sizeof(unsigned int); i++) { if (event->mask & btnmask_lookup[i]) { XTestFakeButtonEvent(properties_disp, i + 1, True, 0); } } #endif switch (event->type) { case EVENT_KEY_PRESSED: case EVENT_KEY_RELEASED: case EVENT_KEY_TYPED: post_key_event(event); break; case EVENT_MOUSE_PRESSED: case EVENT_MOUSE_RELEASED: case EVENT_MOUSE_WHEEL: case EVENT_MOUSE_CLICKED: post_mouse_button_event(event); break; case EVENT_MOUSE_DRAGGED: case EVENT_MOUSE_MOVED: post_mouse_motion_event(event); break; case EVENT_HOOK_ENABLED: case EVENT_HOOK_DISABLED: // Ignore hook enabled / disabled events. default: // Ignore any other garbage. logger(LOG_LEVEL_WARN, "%s [%u]: Ignoring post event type %#X\n", __FUNCTION__, __LINE__, event->type); break; } #ifdef USE_XTEST // Release the previously held modifier keys used to fake the event mask. for (unsigned int i = 0; i < sizeof(keymask_lookup) / sizeof(KeySym); i++) { if (event->mask & 1 << i) { XTestFakeKeyEvent(properties_disp, XKeysymToKeycode(properties_disp, keymask_lookup[i]), False, 0); } } for (unsigned int i = 0; i < sizeof(btnmask_lookup) / sizeof(unsigned int); i++) { if (event->mask & btnmask_lookup[i]) { XTestFakeButtonEvent(properties_disp, i + 1, False, 0); } } #endif // Don't forget to flush! XSync(properties_disp, True); XUnlockDisplay(properties_disp); }
static int display(struct vidisp_st *st, const char *title, const struct vidframe *frame) { struct vidframe frame_rgb; int err = 0; if (!st->disp) return ENODEV; /* * check for window delete - without blocking */ while (XPending(st->disp)) { XEvent e; XNextEvent(st->disp, &e); if (e.type == ClientMessage) { if ((Atom) e.xclient.data.l[0] == st->XwinDeleted) { info("x11: window deleted\n"); /* * we have to bail as all of the display * pointers are bad. */ close_window(st); return ENODEV; } } } if (!vidsz_cmp(&st->size, &frame->size)) { char capt[256]; if (st->size.w && st->size.h) { info("x11: reset: %u x %u ---> %u x %u\n", st->size.w, st->size.h, frame->size.w, frame->size.h); } if (st->internal && !st->win) err = create_window(st, &frame->size); err |= x11_reset(st, &frame->size); if (err) return err; if (title) { re_snprintf(capt, sizeof(capt), "%s - %u x %u", title, frame->size.w, frame->size.h); } else { re_snprintf(capt, sizeof(capt), "%u x %u", frame->size.w, frame->size.h); } XStoreName(st->disp, st->win, capt); } /* Convert from YUV420P to RGB */ vidframe_init_buf(&frame_rgb, st->pixfmt, &frame->size, (uint8_t *)st->shm.shmaddr); vidconv(&frame_rgb, frame, 0); /* draw */ if (st->xshmat) XShmPutImage(st->disp, st->win, st->gc, st->image, 0, 0, 0, 0, st->size.w, st->size.h, false); else XPutImage(st->disp, st->win, st->gc, st->image, 0, 0, 0, 0, st->size.w, st->size.h); XSync(st->disp, false); return err; }
/* Resize the text window for a terminal screen, modifying the * appropriate WM_SIZE_HINTS and taking advantage of bit gravity. */ void DoResizeScreen(XtermWidget xw) { TScreen *screen = TScreenOf(xw); int border = 2 * screen->border; int min_wide = border + screen->fullVwin.sb_info.width; int min_high = border; XtGeometryResult geomreqresult; Dimension reqWidth, reqHeight, repWidth, repHeight; #ifndef NO_ACTIVE_ICON VTwin *saveWin = WhichVWin(screen); /* all units here want to be in the normal font units */ WhichVWin(screen) = &screen->fullVwin; #endif /* NO_ACTIVE_ICON */ /* * I'm going to try to explain, as I understand it, why we * have to do XGetWMNormalHints and XSetWMNormalHints here, * although I can't guarantee that I've got it right. * * In a correctly written toolkit program, the Shell widget * parses the user supplied geometry argument. However, * because of the way xterm does things, the VT100 widget does * the parsing of the geometry option, not the Shell widget. * The result of this is that the Shell widget doesn't set the * correct window manager hints, and doesn't know that the * user has specified a geometry. * * The XtVaSetValues call below tells the Shell widget to * change its hints. However, since it's confused about the * hints to begin with, it doesn't get them all right when it * does the SetValues -- it undoes some of what the VT100 * widget did when it originally set the hints. * * To fix this, we do the following: * * 1. Get the sizehints directly from the window, going around * the (confused) shell widget. * 2. Call XtVaSetValues to let the shell widget know which * hints have changed. Note that this may not even be * necessary, since we're going to right ahead after that * and set the hints ourselves, but it's good to put it * here anyway, so that when we finally do fix the code so * that the Shell does the right thing with hints, we * already have the XtVaSetValues in place. * 3. We set the sizehints directly, this fixing up whatever * damage was done by the Shell widget during the * XtVaSetValues. * * Gross, huh? * * The correct fix is to redo VTRealize, VTInitialize and * VTSetValues so that font processing happens early enough to * give back responsibility for the size hints to the Shell. * * Someday, we hope to have time to do this. Someday, we hope * to have time to completely rewrite xterm. */ TRACE(("DoResizeScreen\n")); #if 1 /* ndef nothack */ /* * NOTE: the hints and the XtVaSetValues() must match. */ TRACE(("%s@%d -- ", __FILE__, __LINE__)); TRACE_WM_HINTS(xw); getXtermSizeHints(xw); xtermSizeHints(xw, ScrollbarWidth(screen)); /* These are obsolete, but old clients may use them */ xw->hints.width = MaxCols(screen) * FontWidth(screen) + xw->hints.min_width; xw->hints.height = MaxRows(screen) * FontHeight(screen) + xw->hints.min_height; #if OPT_MAXIMIZE /* assure single-increment resize for fullscreen */ if (xw->work.ewmh[0].mode) { xw->hints.width_inc = 1; xw->hints.height_inc = 1; } #endif /* OPT_MAXIMIZE */ #endif XSetWMNormalHints(screen->display, VShellWindow(xw), &xw->hints); reqWidth = (Dimension) (MaxCols(screen) * FontWidth(screen) + min_wide); reqHeight = (Dimension) (MaxRows(screen) * FontHeight(screen) + min_high); #if OPT_MAXIMIZE /* compensate for fullscreen mode */ if (xw->work.ewmh[0].mode) { Screen *xscreen = DefaultScreenOfDisplay(xw->screen.display); reqWidth = (Dimension) WidthOfScreen(xscreen); reqHeight = (Dimension) HeightOfScreen(xscreen); ScreenResize(xw, reqWidth, reqHeight, &xw->flags); } #endif /* OPT_MAXIMIZE */ TRACE(("...requesting screensize chars %dx%d, pixels %dx%d\n", MaxRows(screen), MaxCols(screen), reqHeight, reqWidth)); geomreqresult = REQ_RESIZE((Widget) xw, reqWidth, reqHeight, &repWidth, &repHeight); if (geomreqresult == XtGeometryAlmost) { TRACE(("...almost, retry screensize %dx%d\n", repHeight, repWidth)); geomreqresult = REQ_RESIZE((Widget) xw, repWidth, repHeight, NULL, NULL); } if (geomreqresult != XtGeometryYes) { /* The resize wasn't successful, so we might need to adjust our idea of how large the screen is. */ TRACE(("...still no (%d) - resize the core-class\n", geomreqresult)); xw->core.widget_class->core_class.resize((Widget) xw); } #if 1 /* ndef nothack */ /* * XtMakeResizeRequest() has the undesirable side-effect of clearing * the window manager's hints, even on a failed request. This would * presumably be fixed if the shell did its own work. */ if (xw->hints.flags && repHeight && repWidth) { xw->hints.height = repHeight; xw->hints.width = repWidth; TRACE_HINTS(&xw->hints); XSetWMNormalHints(screen->display, VShellWindow(xw), &xw->hints); } #endif XSync(screen->display, False); /* synchronize */ if (xtermAppPending()) xevents(); #ifndef NO_ACTIVE_ICON WhichVWin(screen) = saveWin; #endif /* NO_ACTIVE_ICON */ }
SDL_Overlay *X11_CreateYUVOverlay(_THIS, int width, int height, Uint32 format, SDL_Surface *display) { SDL_Overlay *overlay; struct private_yuvhwdata *hwdata; int xv_port; unsigned int i, j, k; unsigned int adaptors; SDL_NAME(XvAdaptorInfo) *ainfo; int bpp; #ifndef NO_SHARED_MEMORY XShmSegmentInfo *yuvshm; #endif /* Look for the XVideo extension with a valid port for this format */ xv_port = -1; if ( (Success == SDL_NAME(XvQueryExtension)(GFX_Display, &j, &j, &j, &j, &j)) && (Success == SDL_NAME(XvQueryAdaptors)(GFX_Display, RootWindow(GFX_Display, SDL_Screen), &adaptors, &ainfo)) ) { #ifdef USE_LAST_ADAPTOR for ( i=0; i < adaptors; ++i ) #else for ( i=0; (i < adaptors) && (xv_port == -1); ++i ) #endif /* USE_LAST_ADAPTOR */ { /* Check to see if the visual can be used */ if ( BUGGY_XFREE86(<=, 4001) ) { int visual_ok = 0; for ( j=0; j<ainfo[i].num_formats; ++j ) { if ( ainfo[i].formats[j].visual_id == SDL_Visual->visualid ) { visual_ok = 1; break; } } if ( ! visual_ok ) { continue; } } if ( (ainfo[i].type & XvInputMask) && (ainfo[i].type & XvImageMask) ) { int num_formats; SDL_NAME(XvImageFormatValues) *formats; formats = SDL_NAME(XvListImageFormats)(GFX_Display, ainfo[i].base_id, &num_formats); #ifdef USE_LAST_ADAPTOR for ( j=0; j < num_formats; ++j ) #else for ( j=0; (j < num_formats) && (xv_port == -1); ++j ) #endif /* USE_LAST_ADAPTOR */ { if ( (Uint32)formats[j].id == format ) { for ( k=0; k < ainfo[i].num_ports; ++k ) { if ( Success == SDL_NAME(XvGrabPort)(GFX_Display, ainfo[i].base_id+k, CurrentTime) ) { xv_port = ainfo[i].base_id+k; break; } } } } if ( formats ) { XFree(formats); } } } SDL_NAME(XvFreeAdaptorInfo)(ainfo); } /* Precalculate the bpp for the pitch workaround below */ switch (format) { /* Add any other cases we need to support... */ case SDL_YUY2_OVERLAY: case SDL_UYVY_OVERLAY: case SDL_YVYU_OVERLAY: bpp = 2; break; default: bpp = 1; break; } #if 0 /* * !!! FIXME: * "Here are some diffs for X11 and yuv. Note that the last part 2nd * diff should probably be a new call to XvQueryAdaptorFree with ainfo * and the number of adaptors, instead of the loop through like I did." * * ACHTUNG: This is broken! It looks like XvFreeAdaptorInfo does this * for you, so we end up with a double-free. I need to look at this * more closely... --ryan. */ for ( i=0; i < adaptors; ++i ) { if (ainfo[i].name != NULL) Xfree(ainfo[i].name); if (ainfo[i].formats != NULL) Xfree(ainfo[i].formats); } Xfree(ainfo); #endif if ( xv_port == -1 ) { SDL_SetError("No available video ports for requested format"); return(NULL); } /* Enable auto-painting of the overlay colorkey */ { static const char *attr[] = { "XV_AUTOPAINT_COLORKEY", "XV_AUTOPAINT_COLOURKEY" }; unsigned int i; SDL_NAME(XvSelectPortNotify)(GFX_Display, xv_port, True); X_handler = XSetErrorHandler(xv_errhandler); for ( i=0; i < sizeof(attr)/(sizeof attr[0]); ++i ) { Atom a; xv_error = False; a = XInternAtom(GFX_Display, attr[i], True); if ( a != None ) { SDL_NAME(XvSetPortAttribute)(GFX_Display, xv_port, a, 1); XSync(GFX_Display, True); if ( ! xv_error ) { break; } } } XSetErrorHandler(X_handler); SDL_NAME(XvSelectPortNotify)(GFX_Display, xv_port, False); } /* Create the overlay structure */ overlay = (SDL_Overlay *)SDL_malloc(sizeof *overlay); if ( overlay == NULL ) { SDL_NAME(XvUngrabPort)(GFX_Display, xv_port, CurrentTime); SDL_OutOfMemory(); return(NULL); } SDL_memset(overlay, 0, (sizeof *overlay)); /* Fill in the basic members */ overlay->format = format; overlay->w = width; overlay->h = height; /* Set up the YUV surface function structure */ overlay->hwfuncs = &x11_yuvfuncs; overlay->hw_overlay = 1; /* Create the pixel data and lookup tables */ hwdata = (struct private_yuvhwdata *)SDL_malloc(sizeof *hwdata); overlay->hwdata = hwdata; if ( hwdata == NULL ) { SDL_NAME(XvUngrabPort)(GFX_Display, xv_port, CurrentTime); SDL_OutOfMemory(); SDL_FreeYUVOverlay(overlay); return(NULL); } hwdata->port = xv_port; #ifndef NO_SHARED_MEMORY yuvshm = &hwdata->yuvshm; SDL_memset(yuvshm, 0, sizeof(*yuvshm)); hwdata->image = SDL_NAME(XvShmCreateImage)(GFX_Display, xv_port, format, 0, width, height, yuvshm); #ifdef PITCH_WORKAROUND if ( hwdata->image != NULL && hwdata->image->pitches[0] != (width*bpp) ) { /* Ajust overlay width according to pitch */ XFree(hwdata->image); width = hwdata->image->pitches[0] / bpp; hwdata->image = SDL_NAME(XvShmCreateImage)(GFX_Display, xv_port, format, 0, width, height, yuvshm); } #endif /* PITCH_WORKAROUND */ hwdata->yuv_use_mitshm = (hwdata->image != NULL); if ( hwdata->yuv_use_mitshm ) { yuvshm->shmid = shmget(IPC_PRIVATE, hwdata->image->data_size, IPC_CREAT | 0777); if ( yuvshm->shmid >= 0 ) { yuvshm->shmaddr = (char *)shmat(yuvshm->shmid, 0, 0); yuvshm->readOnly = False; if ( yuvshm->shmaddr != (char *)-1 ) { shm_error = False; X_handler = XSetErrorHandler(shm_errhandler); XShmAttach(GFX_Display, yuvshm); XSync(GFX_Display, True); XSetErrorHandler(X_handler); if ( shm_error ) shmdt(yuvshm->shmaddr); } else { shm_error = True; } shmctl(yuvshm->shmid, IPC_RMID, NULL); } else { shm_error = True; } if ( shm_error ) { XFree(hwdata->image); hwdata->yuv_use_mitshm = 0; } else { hwdata->image->data = yuvshm->shmaddr; } } if ( !hwdata->yuv_use_mitshm ) #endif /* NO_SHARED_MEMORY */ { hwdata->image = SDL_NAME(XvCreateImage)(GFX_Display, xv_port, format, 0, width, height); #ifdef PITCH_WORKAROUND if ( hwdata->image != NULL && hwdata->image->pitches[0] != (width*bpp) ) { /* Ajust overlay width according to pitch */ XFree(hwdata->image); width = hwdata->image->pitches[0] / bpp; hwdata->image = SDL_NAME(XvCreateImage)(GFX_Display, xv_port, format, 0, width, height); } #endif /* PITCH_WORKAROUND */ if ( hwdata->image == NULL ) { SDL_SetError("Couldn't create XVideo image"); SDL_FreeYUVOverlay(overlay); return(NULL); } hwdata->image->data = SDL_malloc(hwdata->image->data_size); if ( hwdata->image->data == NULL ) { SDL_OutOfMemory(); SDL_FreeYUVOverlay(overlay); return(NULL); } } /* Find the pitch and offset values for the overlay */ overlay->planes = hwdata->image->num_planes; overlay->pitches = (Uint16 *)SDL_malloc(overlay->planes * sizeof(Uint16)); overlay->pixels = (Uint8 **)SDL_malloc(overlay->planes * sizeof(Uint8 *)); if ( !overlay->pitches || !overlay->pixels ) { SDL_OutOfMemory(); SDL_FreeYUVOverlay(overlay); return(NULL); } for ( i=0; i<overlay->planes; ++i ) { overlay->pitches[i] = hwdata->image->pitches[i]; overlay->pixels[i] = (Uint8 *)hwdata->image->data + hwdata->image->offsets[i]; } #ifdef XFREE86_REFRESH_HACK /* Work around an XFree86 X server bug (?) We can't perform normal updates in windows that have video being output to them. See SDL_x11image.c for more details. */ X11_DisableAutoRefresh(this); #endif /* We're all done.. */ return(overlay); }
int main(int argc, char* argv[]) { Display *display = XOpenDisplay(NULL); if (!display) { printf("Failed to open X display\n"); exit(1); } // Get a matching FB config static int visual_attribs[] = { GLX_X_RENDERABLE , True, GLX_DRAWABLE_TYPE , GLX_WINDOW_BIT, GLX_RENDER_TYPE , GLX_RGBA_BIT, GLX_X_VISUAL_TYPE , GLX_TRUE_COLOR, 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, //GLX_SAMPLE_BUFFERS , 1, //GLX_SAMPLES , 4, None }; int glx_major, glx_minor; // FBConfigs were added in GLX version 1.3. if ( !glXQueryVersion( display, &glx_major, &glx_minor ) || ( ( glx_major == 1 ) && ( glx_minor < 3 ) ) || ( glx_major < 1 ) ) { printf("Invalid GLX version"); exit(1); } printf( "Getting matching framebuffer configs\n" ); int fbcount; GLXFBConfig* fbc = glXChooseFBConfig(display, DefaultScreen(display), visual_attribs, &fbcount); if (!fbc) { printf( "Failed to retrieve a framebuffer config\n" ); exit(1); } printf( "Found %d matching FB configs.\n", fbcount ); // Pick the FB config/visual with the most samples per pixel printf( "Getting XVisualInfos\n" ); int best_fbc = -1, worst_fbc = -1, best_num_samp = -1, worst_num_samp = 999; int i; for (i=0; i<fbcount; ++i) { XVisualInfo *vi = glXGetVisualFromFBConfig( display, fbc[i] ); if ( vi ) { int samp_buf, samples; glXGetFBConfigAttrib( display, fbc[i], GLX_SAMPLE_BUFFERS, &samp_buf ); glXGetFBConfigAttrib( display, fbc[i], GLX_SAMPLES , &samples ); printf( " Matching fbconfig %d, visual ID 0x%2x: SAMPLE_BUFFERS = %d," " SAMPLES = %d\n", i, 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 ); } GLXFBConfig bestFbc = fbc[ best_fbc ]; // Be sure to free the FBConfig list allocated by glXChooseFBConfig() XFree( fbc ); // Get a visual XVisualInfo *vi = glXGetVisualFromFBConfig( display, bestFbc ); printf( "Chosen visual ID = 0x%x\n", vi->visualid ); printf( "Creating colormap\n" ); XSetWindowAttributes swa; Colormap cmap; swa.colormap = cmap = XCreateColormap( display, RootWindow( display, vi->screen ), vi->visual, AllocNone ); swa.background_pixmap = None ; swa.border_pixel = 0; swa.event_mask = StructureNotifyMask; printf( "Creating window\n" ); Window win = XCreateWindow( display, RootWindow( display, vi->screen ), 0, 0, 400, 400, 0, vi->depth, InputOutput, vi->visual, CWBorderPixel|CWColormap|CWEventMask, &swa ); if ( !win ) { printf( "Failed to create window.\n" ); exit(1); } // Done with the visual info data XFree( vi ); char windowName[50]; sprintf(windowName, "GL ES %d.%d Window", DESIRED_GL_ES_MAJOR_VERSION, DESIRED_GL_ES_MINOR_VERSION); XStoreName( display, win, windowName ); printf( "Mapping window\n" ); XMapWindow( display, win ); // Get the default screen's GLX extension list const char *glxExts = glXQueryExtensionsString( display, DefaultScreen( display ) ); // NOTE: It is not necessary to create or make current to a context before // calling glXGetProcAddressARB glXCreateContextAttribsARBProc glXCreateContextAttribsARB = 0; glXCreateContextAttribsARB = (glXCreateContextAttribsARBProc) glXGetProcAddressARB( (const GLubyte *) "glXCreateContextAttribsARB" ); GLXContext ctx = 0; // Install an X error handler so the application won't exit if GL 3.0 // context allocation fails. // // Note this error handler is global. All display connections in all threads // of a process use the same error handler, so be sure to guard against other // threads issuing X commands while this code is running. ctxErrorOccurred = false; int (*oldHandler)(Display*, XErrorEvent*) = XSetErrorHandler(&ctxErrorHandler); // Check for the GLX_ARB_create_context extension string and the function. // If either is not present, use GLX 1.3 context creation method. if ( !isExtensionSupported( glxExts, "GLX_ARB_create_context" ) || !glXCreateContextAttribsARB ) { printf( "glXCreateContextAttribsARB() not found" " ... using old-style GLX context\n" ); ctx = glXCreateNewContext( display, bestFbc, GLX_RGBA_TYPE, 0, True ); } // If it does, try to get a GL DESIRED_GL_ES_MAJOR_VERSION.DESIRED_GL_ES_MINOR_VERSION context! else { int context_attribs[] = { GLX_CONTEXT_MAJOR_VERSION_ARB, DESIRED_GL_ES_MAJOR_VERSION, GLX_CONTEXT_MINOR_VERSION_ARB, DESIRED_GL_ES_MINOR_VERSION, GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_ES_PROFILE_BIT_EXT, None }; printf( "Creating context\n" ); ctx = glXCreateContextAttribsARB( display, bestFbc, 0, True, context_attribs ); // Sync to ensure any errors generated are processed. XSync( display, False ); if ( !ctxErrorOccurred && ctx ) printf( "Created GL ES %d.%d context\n", DESIRED_GL_ES_MAJOR_VERSION, DESIRED_GL_ES_MINOR_VERSION ); else { // Couldn't create GL 3.0 context. Fall back to old-style 2.x context. // When a context version below 3.0 is requested, implementations will // return the newest context version compatible with OpenGL versions less // than version 3.0. // GLX_CONTEXT_MAJOR_VERSION_ARB = 1 context_attribs[1] = DESIRED_GL_ES_MAJOR_VERSION; // GLX_CONTEXT_MINOR_VERSION_ARB = 0 context_attribs[3] = DESIRED_GL_ES_MINOR_VERSION; ctxErrorOccurred = false; printf( "Failed to create GL ES %d.%d context" " ... using old-style GLX context\n", DESIRED_GL_ES_MAJOR_VERSION, DESIRED_GL_ES_MINOR_VERSION ); ctx = glXCreateContextAttribsARB( display, bestFbc, 0, True, context_attribs ); } } // Sync to ensure any errors generated are processed. XSync( display, False ); // Restore the original error handler XSetErrorHandler( oldHandler ); if ( ctxErrorOccurred || !ctx ) { printf( "Failed to create an OpenGL ES %d.%d context\n", DESIRED_GL_ES_MAJOR_VERSION, DESIRED_GL_ES_MINOR_VERSION ); exit(1); } // Verifying that context is a direct context if ( ! glXIsDirect ( display, ctx ) ) { printf( "Indirect GLX rendering context obtained\n" ); } else { printf( "Direct GLX rendering context obtained\n" ); } printf( "Making context current\n" ); glXMakeCurrent( display, win, ctx ); glClearColor( 0, 0.5, 1, 1 ); glClear( GL_COLOR_BUFFER_BIT ); glXSwapBuffers ( display, win ); sleep( 2 ); glClearColor ( 1, 0.5, 0, 1 ); glClear ( GL_COLOR_BUFFER_BIT ); glXSwapBuffers ( display, win ); sleep( 2 ); glClearColor( 1, 0.5, 1, 1 ); glClear( GL_COLOR_BUFFER_BIT ); glXSwapBuffers ( display, win ); sleep( 2 ); glXMakeCurrent( display, 0, 0 ); glXDestroyContext( display, ctx ); XDestroyWindow( display, win ); XFreeColormap( display, cmap ); XCloseDisplay( display ); return 0; }