static void gdk_imlib_set_fast_render(ImlibData * id, Display * disp) { /* Turn off fastrender if there is an endianess diff between */ /* client and Xserver in all but 24 bit mode */ int byt, bit; byt = ImageByteOrder(id->x.disp); /* LSBFirst | MSBFirst */ bit = BitmapBitOrder(id->x.disp); /* LSBFirst | MSBFirst */ id->x.byte_order = byt; id->x.bit_order = bit; /* We ignore this for now in the fastrend */ /* if little endian && server big */ if (htonl(1) != 1 && byt == MSBFirst) id->fastrend = 0; /* if big endian && server little */ if (htonl(1) == 1 && byt == LSBFirst) id->fastrend = 0; }
void InitOutput(ScreenInfo *screenInfo, int argc, char *argv[]) { int i, j; xnestOpenDisplay(argc, argv); screenInfo->imageByteOrder = ImageByteOrder(xnestDisplay); screenInfo->bitmapScanlineUnit = BitmapUnit(xnestDisplay); screenInfo->bitmapScanlinePad = BitmapPad(xnestDisplay); screenInfo->bitmapBitOrder = BitmapBitOrder(xnestDisplay); screenInfo->numPixmapFormats = 0; for (i = 0; i < xnestNumPixmapFormats; i++) for (j = 0; j < xnestNumDepths; j++) if ((xnestPixmapFormats[i].depth == 1) || (xnestPixmapFormats[i].depth == xnestDepths[j])) { screenInfo->formats[screenInfo->numPixmapFormats].depth = xnestPixmapFormats[i].depth; screenInfo->formats[screenInfo->numPixmapFormats].bitsPerPixel = xnestPixmapFormats[i].bits_per_pixel; screenInfo->formats[screenInfo->numPixmapFormats].scanlinePad = xnestPixmapFormats[i].scanline_pad; screenInfo->numPixmapFormats++; break; } xnestWindowPrivateIndex = AllocateWindowPrivateIndex(); xnestGCPrivateIndex = AllocateGCPrivateIndex(); xnestFontPrivateIndex = AllocateFontPrivateIndex(); if (!xnestNumScreens) xnestNumScreens = 1; for (i = 0; i < xnestNumScreens; i++) AddScreen(xnestOpenScreen, argc, argv); xnestNumScreens = screenInfo->numScreens; xnestDoFullGeneration = xnestFullGeneration; }
/* initiate connection with X server */ static unsigned char * x_init_driver(unsigned char *param, unsigned char *display) { XGCValues gcv; XSetWindowAttributes win_attr; XVisualInfo vinfo; int misordered=-1; n_wins=0; #if defined(HAVE_SETLOCALE) && defined(LC_ALL) setlocale(LC_ALL,""); #endif #ifdef X_DEBUG { unsigned char txt[256]; sprintf(txt,"x_init_driver(%s, %s)\n",param, display); MESSAGE(txt); } #endif x_input_encoding=-1; #if defined(HAVE_NL_LANGINFO) && defined(HAVE_LANGINFO_H) && defined(CODESET) { unsigned char *cp; cp=nl_langinfo(CODESET); x_input_encoding=get_cp_index(cp); } #endif if (x_input_encoding<0)x_driver.flags|=GD_NEED_CODEPAGE; if (!display||!(*display))display=0; /* X documentation says on XOpenDisplay(display_name) : display_name Specifies the hardware display name, which determines the dis- play and communications domain to be used. On a POSIX-confor- mant system, if the display_name is NULL, it defaults to the value of the DISPLAY environment variable. But OS/2 has problems when display_name is NULL ... */ if (!display)display=getenv("DISPLAY"); #ifndef __linux__ /* on Linux, do not assume XWINDOW present if $DISPLAY is not set --- rather open links on svgalib or framebuffer console */ if (!display)display=":0.0"; /* needed for MacOS X */ #endif x_display=XOpenDisplay(display); if (!x_display) { unsigned char *err=init_str(); int l=0; add_to_str(&err,&l,"Can't open display \""); add_to_str(&err,&l,display?display:(unsigned char *)"(null)"); add_to_str(&err,&l,"\"\n"); return err; } x_hash_table_init(); x_bitmap_bit_order=BitmapBitOrder(x_display); x_fd=XConnectionNumber(x_display); x_screen=DefaultScreen(x_display); x_display_height=DisplayHeight(x_display,x_screen); x_display_width=DisplayWidth(x_display,x_screen); x_root_window=RootWindow(x_display,x_screen); x_default_window_width=x_display_width-50; x_default_window_height=x_display_height-50; x_driver_param=NULL; if (param) { char *p, *e, *f; int w,h; x_driver_param=stracpy(param); for (p=x_driver_param;(*p)&&(*p)!='x'&&(*p)!='X';p++); if (!(*p))goto done; *p=0; w=strtoul(x_driver_param,&e,10); h=strtoul(p+1,&f,10); if (!(*e)&&!(*f)&&w&&h){x_default_window_width=w;x_default_window_height=h;} *p='x'; done:; } /* find best visual */ { #define DEPTHS 5 #define CLASSES 2 int depths[DEPTHS]={24, 16, 15, 8, 4}; int classes[CLASSES]={TrueColor, PseudoColor}; /* FIXME: dodelat DirectColor */ int a,b; for (a=0;a<DEPTHS;a++) for (b=0;b<CLASSES;b++) { if (XMatchVisualInfo(x_display, x_screen,depths[a],classes[b], &vinfo)) { x_default_visual=vinfo.visual; x_depth=vinfo.depth; /* determine bytes per pixel */ { XPixmapFormatValues *pfm; int n,i; pfm=XListPixmapFormats(x_display,&n); for (i=0;i<n;i++) if (pfm[i].depth==x_depth) { x_bitmap_bpp=pfm[i].bits_per_pixel<8?1:((pfm[i].bits_per_pixel)>>3); x_bitmap_scanline_pad=(pfm[i].scanline_pad)>>3; XFree(pfm); goto bytes_per_pixel_found; } if(n) XFree(pfm); continue; } bytes_per_pixel_found: /* test misordered flag */ switch(x_depth) { case 4: case 8: if (x_bitmap_bpp!=1)break; if (vinfo.red_mask>=vinfo.green_mask&&vinfo.green_mask>=vinfo.blue_mask) { misordered=0; goto visual_found; } break; case 15: case 16: if (x_bitmap_bpp!=2)break; if (x_bitmap_bit_order==MSBFirst&&vinfo.red_mask>vinfo.green_mask&&vinfo.green_mask>vinfo.blue_mask) { misordered=256; goto visual_found; } if (x_bitmap_bit_order==MSBFirst)break; if (vinfo.red_mask>vinfo.green_mask&&vinfo.green_mask>vinfo.blue_mask) { misordered=0; goto visual_found; } break; case 24: if (x_bitmap_bpp!=3&&x_bitmap_bpp!=4) break; if (vinfo.red_mask<vinfo.green_mask&&vinfo.green_mask<vinfo.blue_mask) { misordered=256; goto visual_found; } if (x_bitmap_bit_order==MSBFirst&&vinfo.red_mask>vinfo.green_mask&&vinfo.green_mask>vinfo.blue_mask) { misordered=512; goto visual_found; } if (vinfo.red_mask>vinfo.green_mask&&vinfo.green_mask>vinfo.blue_mask) { misordered=0; goto visual_found; } break; } } }
static Bool init_x11( char * error_buf ) { /*XXX*/ /* Namely, support for -display host:0.0 etc. */ XrmQuark common_quarks_list[20]; /*XXX change number of elements if necessary */ XrmQuarkList ql = common_quarks_list; XGCValues gcv; char *common_quarks = "String." "Blinkinvisibletime.blinkinvisibletime." "Blinkvisibletime.blinkvisibletime." "Clicktimeframe.clicktimeframe." "Doubleclicktimeframe.doubleclicktimeframe." "Wheeldown.wheeldown." "Wheelup.wheelup." "Submenudelay.submenudelay." "Scrollfirst.scrollfirst." "Scrollnext.scrollnext"; char * atom_names[AI_count] = { "RESOLUTION_X", "RESOLUTION_Y", "PIXEL_SIZE", "SPACING", "RELATIVE_WEIGHT", "FOUNDRY", "AVERAGE_WIDTH", "CHARSET_REGISTRY", "CHARSET_ENCODING", "CREATE_EVENT", "WM_DELETE_WINDOW", "WM_PROTOCOLS", "WM_TAKE_FOCUS", "_NET_WM_STATE", "_NET_WM_STATE_SKIP_TASKBAR", "_NET_WM_STATE_MAXIMIZED_VERT", "_NET_WM_STATE_MAXIMIZED_HORZ", "_NET_WM_NAME", "_NET_WM_ICON_NAME", "UTF8_STRING", "TARGETS", "INCR", "PIXEL", "FOREGROUND", "BACKGROUND", "_MOTIF_WM_HINTS", "_NET_WM_STATE_MODAL", "_NET_SUPPORTED", "_NET_WM_STATE_MAXIMIZED_HORIZ", "text/plain;charset=UTF-8", "_NET_WM_STATE_STAYS_ON_TOP", "_NET_CURRENT_DESKTOP", "_NET_WORKAREA", "_NET_WM_STATE_ABOVE" }; char hostname_buf[256], *hostname = hostname_buf; guts. click_time_frame = 200; guts. double_click_time_frame = 200; guts. visible_timeout = 500; guts. invisible_timeout = 500; guts. insert = true; guts. last_time = CurrentTime; guts. ri_head = guts. ri_tail = 0; DISP = XOpenDisplay( do_display); if (!DISP) { char * disp = getenv("DISPLAY"); snprintf( error_buf, 256, "Error: Can't open display '%s'", do_display ? do_display : (disp ? disp : "")); free( do_display); do_display = nil; return false; } free( do_display); do_display = nil; XSetErrorHandler( x_error_handler); guts.main_error_handler = x_error_handler; (void)x_io_error_handler; XCHECKPOINT; guts.connection = ConnectionNumber( DISP); { struct sockaddr name; unsigned int l = sizeof( name); guts. local_connection = getsockname( guts.connection, &name, &l) >= 0 && l == 0; } #ifdef HAVE_X11_EXTENSIONS_SHAPE_H if ( XShapeQueryExtension( DISP, &guts.shape_event, &guts.shape_error)) { guts. shape_extension = true; } else { guts. shape_extension = false; } #else guts. shape_extension = false; #endif #ifdef USE_MITSHM if ( !do_no_shmem && XShmQueryExtension( DISP)) { guts. shared_image_extension = true; guts. shared_image_completion_event = XShmGetEventBase( DISP) + ShmCompletion; } else { guts. shared_image_extension = false; guts. shared_image_completion_event = -1; } #else guts. shared_image_extension = false; guts. shared_image_completion_event = -1; #endif guts. randr_extension = false; #ifdef HAVE_X11_EXTENSIONS_XRANDR_H { int dummy; if ( XRRQueryExtension( DISP, &dummy, &dummy)) guts. randr_extension = true; } #endif #ifdef HAVE_X11_EXTENSIONS_XRENDER_H { int dummy; if ( XRenderQueryExtension( DISP, &dummy, &dummy)) guts. render_extension = true; } #endif #ifdef HAVE_X11_EXTENSIONS_XCOMPOSITE_H { int dummy; if (XQueryExtension(DISP, COMPOSITE_NAME, &guts.composite_opcode, &dummy, &dummy)) guts. composite_extension = true; } #endif XrmInitialize(); guts.db = get_database(); XrmStringToQuarkList( common_quarks, common_quarks_list); guts.qString = *ql++; guts.qBlinkinvisibletime = *ql++; guts.qblinkinvisibletime = *ql++; guts.qBlinkvisibletime = *ql++; guts.qblinkvisibletime = *ql++; guts.qClicktimeframe = *ql++; guts.qclicktimeframe = *ql++; guts.qDoubleclicktimeframe = *ql++; guts.qdoubleclicktimeframe = *ql++; guts.qWheeldown = *ql++; guts.qwheeldown = *ql++; guts.qWheelup = *ql++; guts.qwheelup = *ql++; guts.qSubmenudelay = *ql++; guts.qsubmenudelay = *ql++; guts.qScrollfirst = *ql++; guts.qscrollfirst = *ql++; guts.qScrollnext = *ql++; guts.qscrollnext = *ql++; guts. mouse_buttons = XGetPointerMapping( DISP, guts. buttons_map, 256); XCHECKPOINT; guts. limits. request_length = XMaxRequestSize( DISP); guts. limits. XDrawLines = guts. limits. request_length - 3; guts. limits. XFillPolygon = guts. limits. request_length - 4; guts. limits. XDrawSegments = (guts. limits. request_length - 3) / 2; guts. limits. XDrawRectangles = (guts. limits. request_length - 3) / 2; guts. limits. XFillRectangles = (guts. limits. request_length - 3) / 2; guts. limits. XFillArcs = guts. limits. XDrawArcs = (guts. limits. request_length - 3) / 3; XCHECKPOINT; SCREEN = DefaultScreen( DISP); /* XXX - return code? */ guts. root = RootWindow( DISP, SCREEN); guts. displaySize. x = DisplayWidth( DISP, SCREEN); guts. displaySize. y = DisplayHeight( DISP, SCREEN); XQueryBestCursor( DISP, guts. root, guts. displaySize. x, /* :-) */ guts. displaySize. y, &guts. cursor_width, &guts. cursor_height); XCHECKPOINT; TAILQ_INIT( &guts.paintq); TAILQ_INIT( &guts.peventq); TAILQ_INIT( &guts.bitmap_gc_pool); TAILQ_INIT( &guts.screen_gc_pool); TAILQ_INIT( &guts.argb_gc_pool); guts. currentFocusTime = CurrentTime; guts. windows = hash_create(); guts. menu_windows = hash_create(); guts. ximages = hash_create(); gcv. graphics_exposures = false; guts. menugc = XCreateGC( DISP, guts. root, GCGraphicsExposures, &gcv); guts. resolution. x = 25.4 * guts. displaySize. x / DisplayWidthMM( DISP, SCREEN) + .5; guts. resolution. y = 25.4 * DisplayHeight( DISP, SCREEN) / DisplayHeightMM( DISP, SCREEN) + .5; guts. depth = DefaultDepth( DISP, SCREEN); guts. idepth = get_idepth(); if ( guts.depth == 1) guts. qdepth = 1; else if ( guts.depth <= 4) guts. qdepth = 4; else if ( guts.depth <= 8) guts. qdepth = 8; else guts. qdepth = 24; guts. byte_order = ImageByteOrder( DISP); guts. bit_order = BitmapBitOrder( DISP); if ( BYTEORDER == LSB32 || BYTEORDER == LSB64) guts. machine_byte_order = LSBFirst; else if ( BYTEORDER == MSB32 || BYTEORDER == MSB64) guts. machine_byte_order = MSBFirst; else { sprintf( error_buf, "UAA_001: weird machine byte order: %08x", BYTEORDER); return false; } XInternAtoms( DISP, atom_names, AI_count, 0, guts. atoms); guts. null_pointer = nilHandle; guts. pointer_invisible_count = 0; guts. files = plist_create( 16, 16); prima_rebuild_watchers(); guts. wm_event_timeout = 100; guts. menu_timeout = 200; guts. scroll_first = 200; guts. scroll_next = 50; apc_timer_create( CURSOR_TIMER); apc_timer_set_timeout(CURSOR_TIMER, 2); apc_timer_create( MENU_TIMER); apc_timer_set_timeout( MENU_TIMER, guts. menu_timeout); apc_timer_create( MENU_UNFOCUS_TIMER); apc_timer_set_timeout( MENU_UNFOCUS_TIMER, 50); if ( !prima_init_clipboard_subsystem( error_buf)) return false; if ( !prima_init_color_subsystem( error_buf)) return false; if ( !prima_init_font_subsystem( error_buf)) return false; #ifdef WITH_GTK2 if (!prima_gtk_init()) return false; #endif bzero( &guts. cursor_gcv, sizeof( guts. cursor_gcv)); guts. cursor_gcv. cap_style = CapButt; guts. cursor_gcv. function = GXcopy; gethostname( hostname, 256); hostname[255] = '\0'; XStringListToTextProperty((char **)&hostname, 1, &guts. hostname); guts. net_wm_maximization = prima_wm_net_state_read_maximization( guts. root, NET_SUPPORTED); if ( do_sync) XSynchronize( DISP, true); return true; }
/* Renders a scaled, cropped version of the RGBA XImage onto the window. */ static void draw_image (Display *dpy, Window window, Visual *v, GC gc, int w, int h, int depth, XImage *in) { XImage *out; int x, y, w2, h2, xoff, yoff; double xs, ys, s; unsigned long crpos=0, cgpos=0, cbpos=0, capos=0; /* bitfield positions */ unsigned long srpos=0, sgpos=0, sbpos=0; unsigned long srmsk=0, sgmsk=0, sbmsk=0; unsigned long srsiz=0, sgsiz=0, sbsiz=0; # ifdef HAVE_JWXYZ // BlackPixel has alpha: 0xFF000000. unsigned long black = BlackPixelOfScreen (DefaultScreenOfDisplay (dpy)); #else unsigned long black = 0; # endif xs = in->width / (double) w; ys = in->height / (double) h; s = (xs > ys ? ys : xs); w2 = in->width / s; h2 = in->height / s; xoff = (w - w2) / 2; yoff = (h - h2) / 2; /* Create a new image in the depth and bit-order of the server. */ out = XCreateImage (dpy, v, depth, ZPixmap, 0, 0, w, h, 8, 0); out->bitmap_bit_order = in->bitmap_bit_order; out->byte_order = in->byte_order; out->bitmap_bit_order = BitmapBitOrder (dpy); out->byte_order = ImageByteOrder (dpy); out->data = (char *) malloc (out->height * out->bytes_per_line); if (!out->data) abort(); /* Find the server's color masks. We could cache this and just do it once, but it's a small number of instructions compared to the per-pixel operations happening next. */ srmsk = out->red_mask; sgmsk = out->green_mask; sbmsk = out->blue_mask; if (!(srmsk && sgmsk && sbmsk)) abort(); /* No server color masks? */ decode_mask (srmsk, &srpos, &srsiz); decode_mask (sgmsk, &sgpos, &sgsiz); decode_mask (sbmsk, &sbpos, &sbsiz); /* 'in' is RGBA in client endianness. Convert to what the server wants. */ if (bigendian()) crpos = 24, cgpos = 16, cbpos = 8, capos = 0; else crpos = 0, cgpos = 8, cbpos = 16, capos = 24; /* Iterate the destination rectangle and pull in the corresponding scaled and cropped source pixel, or black. Nearest-neighbor is fine. */ for (y = 0; y < out->height; y++) { int iy = (out->height - y - yoff - 1) * s; for (x = 0; x < out->width; x++) { int ix = (x - xoff) * s; unsigned long p = (ix >= 0 && ix < in->width && iy >= 0 && iy < in->height ? XGetPixel (in, ix, iy) : black); /* unsigned char a = (p >> capos) & 0xFF; */ unsigned char b = (p >> cbpos) & 0xFF; unsigned char g = (p >> cgpos) & 0xFF; unsigned char r = (p >> crpos) & 0xFF; XPutPixel (out, x, y, ((r << srpos) | (g << sgpos) | (b << sbpos) | black)); } } XPutImage (dpy, window, gc, out, 0, 0, 0, 0, out->width, out->height); XDestroyImage (out); }
int main(int argc, char **argv) { Atom atomWMDeleteWindow; int screenNumber; Screen *screen; Window window; XWindowAttributes windowAttributes; Colormap colormap; PaletteInfo paletteInfo; Image image; XImage *xImage; int x, y; int captureFrame; XEvent event; bool sizeChanged; // ProgramExit initialization display = NULL; v4l = -1; captureBuf = NULL; on_exit(ProgramExit, NULL); // Get command line options magnification = 1; if (argc > 1) { magnification = atoi(argv[1]); } // end if magnification = max(1, magnification); printf("Magnification is %i\n", magnification); // Open display if ((display = XOpenDisplay(NULL)) == NULL) { // NULL for DISPLAY printf("Error: XOpenDisplay() failed\n"); exit(1); } // end if screenNumber = DefaultScreen(display); screen = XScreenOfDisplay(display, screenNumber); // Obtain WM protocols atom for ClientMessage exit event if ((atomWMDeleteWindow = XInternAtom(display, AtomWMDeleteWindowName, True)) == None) { printf("Error: %s atom does not exist\n", AtomWMDeleteWindowName); exit(1); } // end if // Create window, inheriting depth and visual from root window window = XCreateSimpleWindow( display, RootWindowOfScreen(screen), 0, // x 0, // y 640, // width 480, // height 0, // border width BlackPixelOfScreen(screen), // border BlackPixelOfScreen(screen) // background ); XStoreName(display, window, "V4L RGB Test"); XGetWindowAttributes(display, window, &windowAttributes); if (((windowAttributes.depth == 8) && (windowAttributes.visual->c_class != PseudoColor)) || ((windowAttributes.depth > 8) && (windowAttributes.visual->c_class != TrueColor))) { printf("Error: Visual not supported\n"); exit(1); } // end if // Create PseudoColor HI240 colormap, if needed if (windowAttributes.depth == 8) { colormap = XCreateColormap(display, window, windowAttributes.visual, AllocAll); paletteInfo.display = display; paletteInfo.colormap = colormap; Hi240BuildPalette((ulong) 0x10000, (Hi240StorePaletteEntry *) StoreColormapEntry, &paletteInfo); XSetWindowColormap(display, window, colormap); } // end if // Create image if (image.Create( display, window, // Defines visual, depth MaxImageWidth, MaxImageHeight, True // MITSHM ) < 0) { printf("Error: image.Create() failed\n"); exit(1); } // end if image.Clear(); #if (1) printf("\nDisplay:\n"); printf("Image byte order = %s\n", ByteOrderName(ImageByteOrder(display))); printf("Bitmap unit = %i\n", BitmapUnit(display)); printf("Bitmap bit order = %s\n", ByteOrderName(BitmapBitOrder(display))); printf("Bitmap pad = %i\n", BitmapPad(display)); printf("\nWindow:\n"); printf("Depth = %i\n", windowAttributes.depth); printf("Visual ID = 0x%02x\n", windowAttributes.visual->visualid); printf("Visual class = %s\n", VisualClassName(windowAttributes.visual->c_class)); printf("Red mask = 0x%08lx\n", windowAttributes.visual->red_mask); printf("Green mask = 0x%08lx\n", windowAttributes.visual->green_mask); printf("Blue mask = 0x%08lx\n", windowAttributes.visual->blue_mask); printf("Bits per R/G/B = %i\n", windowAttributes.visual->bits_per_rgb); // log2 # colors xImage = image.X(); printf("\nImage:\n"); printf("Image byte order = %s\n", ByteOrderName(xImage->byte_order)); printf("Bitmap unit = %i\n", xImage->bitmap_unit); printf("Bitmap bit order = %s\n", ByteOrderName(xImage->bitmap_bit_order)); printf("Bitmap pad = %i\n", xImage->bitmap_pad); printf("Depth = %i\n", xImage->depth); printf("Red mask = 0x%08lx\n", xImage->red_mask); printf("Green mask = 0x%08lx\n", xImage->green_mask); printf("Blue mask = 0x%08lx\n", xImage->blue_mask); printf("Bits per pixel = %i\n", xImage->bits_per_pixel); // ZPixmap printf("Bytes per line = %i\n", xImage->bytes_per_line); printf("IsShared = %s\n", image.IsShared() ? "True" : "False"); printf("HasSharedPixmap = %s\n", image.HasSharedPixmap() ? "True" : "False"); #endif // V4L stuff if ((v4l = open(BigPictureDevice, O_RDWR)) < 0) { printf("Error: Can't open %s: %s\n", BigPictureDevice, strerror(errno)); exit(1); } // end if if (V4LMGetMMInfo(v4l, &v4lMMInfo) < 0) { printf("Error: V4LMGetMMInfo: %s\n", strerror(errno)); exit(1); } // end if #if (0) printf("Capture buffer size = %i\n", v4lMMInfo.size); printf("Capture buffer frames = %i\n", v4lMMInfo.frames); #endif if (v4lMMInfo.frames < 2) { printf("Error: V4LMGetMMInfo: frames < 2\n"); exit(1); } // end if if ((captureBuf = (bits8 *) mmap(0, v4lMMInfo.size, PROT_READ | PROT_WRITE, MAP_SHARED, v4l, 0)) == MAP_FAILED) { printf("Error: mmap(): %s\n", strerror(errno)); exit(1); } // end if if (V4LSetSource(v4l, BigPictureCompositeSource, VIDEO_MODE_NTSC) < 0) { printf("Error: V4LSetSource: %s\n", strerror(errno)); exit(1); } // end if if (V4LGetCaps(v4l, &v4lCaps) < 0) { printf("Error: V4LGetCaps: %s\n", strerror(errno)); exit(1); } // end if // Select V4L RGB capture format to exactly match image/visual (no LUTs!) if ((captureFormat = XImageCaptureFormat(image.X())) < 0) { printf("Error: No match for visual/image\n"); exit(1); } // end if // Initialize capture size based on window size windowWidth = windowAttributes.width; windowHeight = windowAttributes.height;; WindowResize(v4l, windowWidth, windowHeight, magnification); // Does V4LMSetFormat(). // Initialize picture attributes to mid-range V4LSetBrightness(v4l, 65535 / 2); V4LSetContrast(v4l, 65535 / 2); V4LSetSaturation(v4l, 65535 / 2); V4LSetHue(v4l, 65535 / 2); // Ready to start: Display window, select events, and initiate capture sequence XMapRaised(display, window); XSetWMProtocols(display, window, &atomWMDeleteWindow, 1); XSelectInput(display, window, StructureNotifyMask | ExposureMask); captureFrame = 0; if (V4LMCapture(v4l, captureFrame) < 0) { printf("Error: V4LMCapture: %s\n", strerror(errno)); exit(1); } // end if while (1) { if (XPending(display) > 0) { XNextEvent(display, &event); switch (event.type) { case ClientMessage: // From WM if (event.xclient.data.l[0] == atomWMDeleteWindow) { exit(0); } // end if break; case ConfigureNotify: sizeChanged = false; if (event.xconfigure.width != windowWidth) { sizeChanged = true; windowWidth = event.xconfigure.width; } // end if if (event.xconfigure.height != windowHeight) { sizeChanged = true; windowHeight = event.xconfigure.height; } // end if if (sizeChanged) { image.Clear(); XClearWindow(display, window); WindowResize(v4l, windowWidth, windowHeight, magnification); } // end if break; case Expose: if (event.xexpose.count == 0) { Put(window, image); } // end if break; } // end switch } else { // Wait for this frame if (V4LMSync(v4l, captureFrame) < 0) { printf("Error: V4LMSync: %s\n", strerror(errno)); exit(1); } // end if // Start capture for next frame if (V4LMCapture(v4l, 1 - captureFrame) < 0) { printf("Error: V4LMCapture: %s\n", strerror(errno)); exit(1); } // end if Draw(image, captureBuf + v4lMMInfo.offsets[captureFrame], magnification); Put(window, image); captureFrame = 1 - captureFrame; // 0<->1 } // endif } // end while printf("Error: Fell out of event loop!\n"); exit(1); } // end main
int XBitmapBitOrder(Display *dpy) { return (BitmapBitOrder(dpy)); }
uint2 MCScreenDC::getbitorder() { return BitmapBitOrder(dpy); }
static int _ggi_xshm_create_ximage(struct ggi_visual *vis) { char target[GGI_MAX_APILEN]; ggi_mode tm; ggi_x_priv *priv; int err, i; XShmSegmentInfo *myshminfo; size_t shmsize; err = GGI_OK; priv = GGIX_PRIV(vis); DPRINT_MODE("X: MIT-SHM: Creating shared MIT-SHM buffer\n"); _ggi_xshm_free_ximage(vis); priv->priv = calloc(1, sizeof(XShmSegmentInfo)); if (!priv->priv) return GGI_ENOMEM; myshminfo = priv->priv; priv->ximage = XShmCreateImage(priv->disp, priv->vilist[priv->viidx].vi->visual, (unsigned)priv->vilist[priv->viidx].vi->depth, ZPixmap, /* format */ NULL, /* data */ myshminfo, /* shm object */ (unsigned)LIBGGI_VIRTX(vis), (unsigned)(LIBGGI_VIRTY(vis) * LIBGGI_MODE(vis)->frames)); if (priv->ximage == NULL) { DPRINT("XShmCreateImage() failed."); err = GGI_ENOMEM; goto err0; } shmsize = priv->ximage->bytes_per_line * LIBGGI_VIRTY(vis) * LIBGGI_MODE(vis)->frames; DPRINT_MODE("X: MIT-SHM: Try to shmget() a buffer of %lu (0x%lx) size bytes\n", shmsize, shmsize); myshminfo->shmid = shmget(IPC_PRIVATE, shmsize, IPC_CREAT | 0777); if (myshminfo->shmid == -1) { DPRINT("shmget() failed.\n"); priv->fb = NULL; err = GGI_ENOMEM; goto err1; } priv->fb = shmat(myshminfo->shmid,0,0); if (priv->fb == (void *)-1) { DPRINT("shmat() failed.\n"); priv->fb = NULL; err = GGI_ENOMEM; goto err1; } myshminfo->shmaddr = priv->ximage->data = (char *)priv->fb; DPRINT_MODE("X: MIT-SHM: shmat success at %p.\n", priv->fb); myshminfo->readOnly = False; ggLock(_ggi_global_lock); /* Entering protected section */ shmerror = 0; DPRINT_MODE("X: MIT-SHM: install error handler\n"); oldshmerrorhandler = XSetErrorHandler(shmerrorhandler); DPRINT_MODE("X: MIT-SHM: Attach shm to display\n"); XShmAttach(priv->disp, myshminfo); XSync(priv->disp, 0); DPRINT_MODE("X: MIT-SHM: restore error handler\n"); XSetErrorHandler(oldshmerrorhandler); if (shmerror) { ggUnlock(_ggi_global_lock); /* Exiting protected section */ DPRINT("can not access XSHM.\n"); err = GGI_ENOMEM; goto err2; } else { /* Take the shmid away so noone else can get it. */ shmctl(myshminfo->shmid, IPC_RMID, 0); DPRINT_MODE("X: MIT-SHM: ShmImage allocated\n"); } ggUnlock(_ggi_global_lock); /* Exiting protected section */ err = _ggi_create_dbs(vis); if (err) goto err3; /* We assume LIBGGI_MODE(vis) structure has already been filled out */ memcpy(&tm, LIBGGI_MODE(vis), sizeof(ggi_mode)); /* Make sure we do not fail due to physical size constraints, * which are meaningless on a memory visual. */ tm.size.x = tm.size.y = GGI_AUTO; i = 0; memset(target, '\0', sizeof(target)); i += snprintf(target, sizeof(target), "display-memory:-pixfmt="); _ggi_build_pixfmtstr(vis, target + i, sizeof(target) - i, 1); i = strlen(target); snprintf(target + i, sizeof(target) - i, ":-layout=%iplb%i:-physz=%i,%i:pointer", priv->ximage->bytes_per_line * LIBGGI_VIRTY(vis), priv->ximage->bytes_per_line, LIBGGI_MODE(vis)->size.x, LIBGGI_MODE(vis)->size.y); err = _ggi_openslave(vis, target, &tm); if (err) goto err3; priv->ximage->byte_order = ImageByteOrder(priv->disp); priv->ximage->bitmap_bit_order = BitmapBitOrder(priv->disp); vis->opdisplay->flush = GGI_XSHM_flush_ximage_child; DPRINT_MODE("X: MIT-SHM: XSHMImage and slave visual %p share buffer at %p\n", priv->slave, priv->fb); return GGI_OK; err3: fprintf(stderr, "XSHM extension failed to initialize. Retry with -noshm\n"); _ggi_xshm_free_ximage(vis); return err; err2: XShmDetach(priv->disp, myshminfo); shmdt(priv->fb); priv->fb = NULL; err1: XDestroyImage(priv->ximage); priv->ximage = NULL; err0: fprintf(stderr, "XSHM extension failed to initialize. Retry with -noshm\n"); return err; }