_X_HIDDEN void DRI_glXUseXFont(struct glx_context *CC, Font font, int first, int count, int listbase) { Display *dpy; Window win; Pixmap pixmap; GC gc; XGCValues values; unsigned long valuemask; XFontStruct *fs; GLint swapbytes, lsbfirst, rowlength; GLint skiprows, skippixels, alignment; unsigned int max_width, max_height, max_bm_width, max_bm_height; GLubyte *bm; int i; dpy = CC->currentDpy; win = CC->currentDrawable; fs = XQueryFont(dpy, font); if (!fs) { __glXSetError(CC, GL_INVALID_VALUE); return; } /* Allocate a bitmap that can fit all characters. */ max_width = fs->max_bounds.rbearing - fs->min_bounds.lbearing; max_height = fs->max_bounds.ascent + fs->max_bounds.descent; max_bm_width = (max_width + 7) / 8; max_bm_height = max_height; bm = (GLubyte *) Xmalloc((max_bm_width * max_bm_height) * sizeof(GLubyte)); if (!bm) { XFreeFontInfo(NULL, fs, 1); __glXSetError(CC, GL_OUT_OF_MEMORY); return; } #if 0 /* get the page info */ pages = fs->max_char_or_byte2 - fs->min_char_or_byte2 + 1; firstchar = (fs->min_byte1 << 8) + fs->min_char_or_byte2; lastchar = (fs->max_byte1 << 8) + fs->max_char_or_byte2; rows = fs->max_byte1 - fs->min_byte1 + 1; unsigned int first_char, last_char, pages, rows; #endif /* Save the current packing mode for bitmaps. */ glGetIntegerv(GL_UNPACK_SWAP_BYTES, &swapbytes); glGetIntegerv(GL_UNPACK_LSB_FIRST, &lsbfirst); glGetIntegerv(GL_UNPACK_ROW_LENGTH, &rowlength); glGetIntegerv(GL_UNPACK_SKIP_ROWS, &skiprows); glGetIntegerv(GL_UNPACK_SKIP_PIXELS, &skippixels); glGetIntegerv(GL_UNPACK_ALIGNMENT, &alignment); /* Enforce a standard packing mode which is compatible with fill_bitmap() from above. This is actually the default mode, except for the (non)alignment. */ glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE); glPixelStorei(GL_UNPACK_LSB_FIRST, GL_FALSE); glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); pixmap = XCreatePixmap(dpy, win, 10, 10, 1); values.foreground = BlackPixel(dpy, DefaultScreen(dpy)); values.background = WhitePixel(dpy, DefaultScreen(dpy)); values.font = fs->fid; valuemask = GCForeground | GCBackground | GCFont; gc = XCreateGC(dpy, pixmap, valuemask, &values); XFreePixmap(dpy, pixmap); #ifdef DEBUG if (debug_xfonts) dump_font_struct(fs); #endif for (i = 0; i < count; i++) { unsigned int width, height, bm_width, bm_height; GLfloat x0, y0, dx, dy; XCharStruct *ch; int x, y; unsigned int c = first + i; int list = listbase + i; int valid; /* check on index validity and get the bounds */ ch = isvalid(fs, c); if (!ch) { ch = &fs->max_bounds; valid = 0; } else { valid = 1; } #ifdef DEBUG if (debug_xfonts) { char s[7]; sprintf(s, isprint(c) ? "%c> " : "\\%03o> ", c); dump_char_struct(ch, s); } #endif /* glBitmap()' parameters: straight from the glXUseXFont(3) manpage. */ width = ch->rbearing - ch->lbearing; height = ch->ascent + ch->descent; x0 = -ch->lbearing; y0 = ch->descent - 1; dx = ch->width; dy = 0; /* X11's starting point. */ x = -ch->lbearing; y = ch->ascent; /* Round the width to a multiple of eight. We will use this also for the pixmap for capturing the X11 font. This is slightly inefficient, but it makes the OpenGL part real easy. */ bm_width = (width + 7) / 8; bm_height = height; glNewList(list, GL_COMPILE); if (valid && (bm_width > 0) && (bm_height > 0)) { memset(bm, '\0', bm_width * bm_height); fill_bitmap(dpy, win, gc, bm_width, bm_height, x, y, c, bm); glBitmap(width, height, x0, y0, dx, dy, bm); #ifdef DEBUG if (debug_xfonts) { printf("width/height = %u/%u\n", width, height); printf("bm_width/bm_height = %u/%u\n", bm_width, bm_height); dump_bitmap(bm_width, bm_height, bm); } #endif } else { glBitmap(0, 0, 0.0, 0.0, dx, dy, NULL); } glEndList(); } Xfree(bm); XFreeFontInfo(NULL, fs, 1); XFreeGC(dpy, gc); /* Restore saved packing modes. */ glPixelStorei(GL_UNPACK_SWAP_BYTES, swapbytes); glPixelStorei(GL_UNPACK_LSB_FIRST, lsbfirst); glPixelStorei(GL_UNPACK_ROW_LENGTH, rowlength); glPixelStorei(GL_UNPACK_SKIP_ROWS, skiprows); glPixelStorei(GL_UNPACK_SKIP_PIXELS, skippixels); glPixelStorei(GL_UNPACK_ALIGNMENT, alignment); }
static DFBResult x11AllocateKey( CoreSurfacePool *pool, void *pool_data, void *pool_local, CoreSurfaceBuffer *buffer, const char *key, u64 handle, CoreSurfaceAllocation *allocation, void *alloc_data ) { CoreSurface *surface; x11AllocationData *alloc = alloc_data; x11PoolLocalData *local = pool_local; DFBX11 *x11 = local->x11; D_DEBUG_AT( X11_Surfaces, "%s( %s, 0x%08llx )\n", __FUNCTION__, key, (unsigned long long) handle ); D_DEBUG_AT( X11_Surfaces, " -> allocation: %s\n", ToString_CoreSurfaceAllocation( allocation ) ); D_MAGIC_ASSERT( pool, CoreSurfacePool ); D_MAGIC_ASSERT( buffer, CoreSurfaceBuffer ); surface = buffer->surface; D_MAGIC_ASSERT( surface, CoreSurface ); if (!strcmp( key, "Pixmap/X11" )) { D_DEBUG_AT( X11_Surfaces, " -> Pixmap/X11\n" ); alloc->type = X11_ALLOC_PIXMAP; } else if (!strcmp( key, "Window/X11" )) { D_DEBUG_AT( X11_Surfaces, " -> Window/X11\n" ); alloc->type = X11_ALLOC_WINDOW; } else { D_BUG( "unexpected key '%s'", key ); return DFB_BUG; } dfb_surface_calc_buffer_size( surface, 8, 8, &alloc->pitch, &allocation->size ); // alloc->depth = DefaultDepthOfScreen( x11->screenptr ); // alloc->visual = DefaultVisualOfScreen( x11->screenptr ); alloc->visual = x11->visuals[DFB_PIXELFORMAT_INDEX(buffer->format)]; alloc->depth = DFB_COLOR_BITS_PER_PIXEL( buffer->format ) + DFB_ALPHA_BITS_PER_PIXEL( buffer->format ); if (alloc->depth == DefaultDepthOfScreen( x11->screenptr )) alloc->visual = DefaultVisualOfScreen( x11->screenptr ); D_DEBUG_AT( X11_Surfaces, " -> visual %p (id %lu), depth %d\n", alloc->visual, alloc->visual->visualid, alloc->depth ); if (handle) { switch (alloc->type) { case X11_ALLOC_PIXMAP: XLockDisplay( x11->display ); alloc->xid = (unsigned long) handle; x11->Sync( x11 ); D_DEBUG_AT( X11_Surfaces, " -> pixmap 0x%08lx\n", (long) alloc->xid ); XUnlockDisplay( x11->display ); D_INFO( "X11/Windows: Import Pixmap 0x%08lx\n", alloc->xid ); break; case X11_ALLOC_WINDOW: { XLockDisplay( x11->display ); alloc->window = (unsigned long) handle; x11->Sync( x11 ); D_DEBUG_AT( X11_Surfaces, " -> window 0x%08lx\n", (long) alloc->window ); XCompositeRedirectWindow( x11->display, alloc->window, CompositeRedirectManual ); x11->Sync( x11 ); D_DEBUG_AT( X11_Surfaces, " -> redirected\n" ); alloc->xid = XCompositeNameWindowPixmap( x11->display, alloc->window ); // alloc->xid = alloc->window; x11->Sync( x11 ); D_DEBUG_AT( X11_Surfaces, " -> pixmap 0x%08lx\n", (long) alloc->xid ); XUnmapWindow( x11->display, alloc->window ); x11->Sync( x11 ); D_DEBUG_AT( X11_Surfaces, " -> unmapped\n" ); XUnlockDisplay( x11->display ); D_INFO( "X11/Windows: Import Window 0x%08lx with Pixmap handle 0x%08lx\n", alloc->window, alloc->xid ); break; } default: D_BUG( "unexpected allocation type %d\n", alloc->type ); return DFB_BUG; } } else { // alloc->type = X11_ALLOC_PIXMAP; switch (alloc->type) { case X11_ALLOC_PIXMAP: XLockDisplay( x11->display ); x11->Sync( x11 ); D_DEBUG_AT( X11_Surfaces, " -> creating pixmap...\n" ); alloc->xid = XCreatePixmap( x11->display, DefaultRootWindow(x11->display), allocation->config.size.w, allocation->config.size.h, alloc->depth ); x11->Sync( x11 ); XSync( x11->display, False ); D_DEBUG_AT( X11_Surfaces, " -> pixmap 0x%08lx\n", (long) alloc->xid ); XUnlockDisplay( x11->display ); D_INFO( "X11/Windows: New Pixmap 0x%08lx\n", alloc->xid ); alloc->created = true; break; case X11_ALLOC_WINDOW: { Window w = (Window) (long) buffer->surface->data; XSetWindowAttributes attr; attr.event_mask = ButtonPressMask | ButtonReleaseMask | PointerMotionMask | KeyPressMask | KeyReleaseMask | ExposureMask | StructureNotifyMask; attr.background_pixmap = 0; XLockDisplay( x11->display ); x11->Sync( x11 ); D_DEBUG_AT( X11_Surfaces, " -> creating window...\n" ); alloc->window = w?:XCreateWindow( x11->display, DefaultRootWindow(x11->display), 600, 200, allocation->config.size.w, allocation->config.size.h, 0, alloc->depth, InputOutput, alloc->visual, CWEventMask, &attr ); x11->Sync( x11 ); D_DEBUG_AT( X11_Surfaces, " -> window 0x%08lx\n", (long) alloc->window ); buffer->surface->data = (void*) (long) alloc->window; XMapRaised( x11->display, alloc->window ); x11->Sync( x11 ); D_DEBUG_AT( X11_Surfaces, " -> raised\n" ); XCompositeRedirectWindow( x11->display, alloc->window, CompositeRedirectManual ); x11->Sync( x11 ); D_DEBUG_AT( X11_Surfaces, " -> redirected\n" ); alloc->xid = XCompositeNameWindowPixmap( x11->display, alloc->window ); // alloc->xid = alloc->window; x11->Sync( x11 ); D_DEBUG_AT( X11_Surfaces, " -> pixmap 0x%08lx\n", (long) alloc->xid ); XUnmapWindow( x11->display, alloc->window ); x11->Sync( x11 ); D_DEBUG_AT( X11_Surfaces, " -> unmapped\n" ); XUnlockDisplay( x11->display ); D_INFO( "X11/Windows: New Window 0x%08lx with Pixmap handle 0x%08lx\n", alloc->window, alloc->xid ); alloc->created = !w; break; } default: D_BUG( "unexpected allocation type %d\n", alloc->type ); return DFB_BUG; } } alloc->gc = XCreateGC( x11->display, alloc->xid, 0, NULL ); allocation->offset = alloc->type; return DFB_OK; }
/* draw background to root */ void drawbg(void) { int i, w, h, nx, ny, nh, nw, tmp; double factor; Pixmap pm; Imlib_Image tmpimg, buffer; pm = XCreatePixmap(dpy, root, sw, sh, DefaultDepth(dpy, DefaultScreen(dpy))); if(!(buffer = imlib_create_image(sw, sh))) die("Error: Cannot allocate buffer.\n"); imlib_context_set_image(buffer); imlib_image_fill_rectangle(0, 0, sw, sh); imlib_context_set_blend(1); for(i = 0; i < nmonitor; i++) { imlib_context_set_image(images[i % nimage]); w = imlib_image_get_width(); h = imlib_image_get_height(); if(!(tmpimg = imlib_clone_image())) die("Error: Cannot clone image.\n"); imlib_context_set_image(tmpimg); if(rotate && ((monitors[i].w > monitors[i].h && w < h) || (monitors[i].w < monitors[i].h && w > h))) { imlib_image_orientate(1); tmp = w; w = h; h = tmp; } imlib_context_set_image(buffer); switch(mode) { case ModeCenter: nw = (monitors[i].w - w) / 2; nh = (monitors[i].h - h) / 2; nx = monitors[i].x + (monitors[i].w - nw) / 2; ny = monitors[i].y + (monitors[i].h - nh) / 2; break; case ModeZoom: nw = monitors[i].w; nh = monitors[i].h; if(w > h && (w / h > (monitors[i].w / monitors[i].h))) { nx = monitors[i].x + (monitors[i].w - nw) / 2; ny = monitors[i].y + (int)ceil(h * nx / w) / 2; } else { ny = monitors[i].y + (monitors[i].h - nh) / 2; nx = monitors[i].x + (int)ceil(w * ny / h) / 2; } break; default: /* ModeScale */ factor = MAX((double)w / monitors[i].w, (double)h / monitors[i].h); nw = w / factor; nh = h / factor; nx = monitors[i].x + (monitors[i].w - nw) / 2; ny = monitors[i].y + (monitors[i].h - nh) / 2; } imlib_blend_image_onto_image(tmpimg, 0, 0, 0, w, h, nx, ny, nw, nh); imlib_context_set_image(tmpimg); imlib_free_image(); } imlib_context_set_blend(0); imlib_context_set_image(buffer); imlib_context_set_drawable(root); imlib_render_image_on_drawable(0, 0); imlib_context_set_drawable(pm); imlib_render_image_on_drawable(0, 0); XSetWindowBackgroundPixmap(dpy, root, pm); imlib_context_set_image(buffer); imlib_free_image_and_decache(); XFreePixmap(dpy, pm); }
main() { Window w2; Display *dpy = XOpenDisplay(NIL); assert(dpy); Screen *scr = DefaultScreenOfDisplay(dpy); // CreateWindow Window w = XCreateWindow(dpy, RootWindowOfScreen(scr), 10, 100, 200, 300, 0, CopyFromParent, CopyFromParent, CopyFromParent, 0, NIL); XDestroyWindow(dpy, w); // CreateWindow with arguments XSetWindowAttributes swa; swa.background_pixel = WhitePixelOfScreen(scr); swa.bit_gravity = NorthWestGravity; swa.border_pixel = BlackPixelOfScreen(scr); swa.colormap = DefaultColormapOfScreen(scr); swa.cursor = None; swa.win_gravity = NorthGravity; w = XCreateWindow(dpy, RootWindowOfScreen(scr), 10, 100, 200, 300, 0, CopyFromParent, CopyFromParent, CopyFromParent, CWBackPixel | CWBitGravity | CWBorderPixel | CWColormap | CWCursor | CWWinGravity, &swa); // CreateWindow with other arguments XDestroyWindow(dpy, w); Pixmap pixmap = XCreatePixmap(dpy, RootWindowOfScreen(scr), 45, 25, DefaultDepthOfScreen(scr)); assert(pixmap); swa.background_pixmap = pixmap; swa.border_pixmap = pixmap; w = XCreateWindow(dpy, RootWindowOfScreen(scr), 10, 100, 200, 300, 0, CopyFromParent, CopyFromParent, CopyFromParent, CWBackPixmap | CWBorderPixmap, &swa); // ChangeWindowAttributes swa.backing_planes = 0x1; swa.backing_pixel = WhitePixelOfScreen(scr); swa.save_under = True; swa.event_mask = KeyPressMask | KeyReleaseMask; swa.do_not_propagate_mask = ButtonPressMask | Button4MotionMask; swa.override_redirect = False; XChangeWindowAttributes(dpy, w, CWBackingPlanes | CWBackingPixel | CWSaveUnder | CWEventMask | CWDontPropagate | CWOverrideRedirect, &swa); // GetWindowAttributes XWindowAttributes wa; Status success = XGetWindowAttributes(dpy, w, &wa); // DestroyWindow (done) // DestroySubwindows w2 = XCreateWindow(dpy, w, 20, 30, 40, 50, 3, CopyFromParent, CopyFromParent, CopyFromParent, 0, NIL); XDestroySubwindows(dpy, w); // ChangeSaveSet // Display *dpy2 = XOpenDisplay(NIL); // assert(dpy2); // XAddToSaveSet(dpy2, w); // XCloseDisplay(dpy2); // ReparentWindow w2 = XCreateWindow(dpy, RootWindowOfScreen(scr), 20, 30, 40, 50, 3, CopyFromParent, CopyFromParent, CopyFromParent, 0, NIL); XReparentWindow(dpy, w2, w, 10, 5); // MapWindow XMapWindow(dpy, w); // MapSubwindows XMapSubwindows(dpy, w); // UnmapWindow XUnmapWindow(dpy, w); // UnmapSubwindows XMapWindow(dpy, w); XUnmapSubwindows(dpy, w2); XMapSubwindows(dpy, w); // ConfigureWindow Window w3 = XCreateWindow(dpy, w, 10, 50, 100, 10, 2, CopyFromParent, CopyFromParent, CopyFromParent, 0, NIL); XMapWindow(dpy, w3); XWindowChanges wc; wc.x = -5; wc.y = -10; wc.width = 50; wc.height = 40; wc.border_width = 7; wc.sibling = w2; wc.stack_mode = Opposite; XConfigureWindow(dpy, w3, CWX | CWY | CWWidth | CWHeight | CWBorderWidth | CWSibling | CWStackMode, &wc); // CirculateWindow XCirculateSubwindows(dpy, w, RaiseLowest); // GetGeometry Window root; int x, y; unsigned width, height, border_width, depth; XGetGeometry(dpy, w, &root, &x, &y, &width, &height, &border_width, &depth); // QueryTree Window parent; Window *children; unsigned nchildren; success = XQueryTree(dpy, w, &root, &parent, &children, &nchildren); XFree(children); // InternAtom Atom a = XInternAtom(dpy, "WM_PROTOCOLS", True); // GetAtomName char *string = XGetAtomName(dpy, XA_PRIMARY); XFree(string); // ChangeProperty XStoreName(dpy, w, "test window"); // DeleteProperty XDeleteProperty(dpy, w, XA_WM_NAME); // GetProperty // TODO // ListProperties int num_prop; Atom *list = XListProperties(dpy, w, &num_prop); XFree(list); // SetSelectionOwner XSetSelectionOwner(dpy, XA_PRIMARY, w, 12000); XSetSelectionOwner(dpy, XA_SECONDARY, w, CurrentTime); // GetSelectionOwner Window wx = XGetSelectionOwner(dpy, XA_PRIMARY); // ConvertSelection XConvertSelection(dpy, XA_SECONDARY, XA_CURSOR, XA_POINT, w, CurrentTime); // SendEvent // GrabPointer std::cerr << "Grabbing" << std::endl; int res = XGrabPointer(dpy, w, False, Button5MotionMask | PointerMotionHintMask, GrabModeSync, GrabModeAsync, w, None, CurrentTime); XSync(dpy, False); // sleep(5); // UngrabPointer std::cerr << "Ungrabbing" << std::endl; XUngrabPointer(dpy, CurrentTime); // GrabButton XGrabButton(dpy, 3, ShiftMask | ControlMask, w, False, PointerMotionHintMask | Button2MotionMask, GrabModeAsync, GrabModeSync, None, None); XGrabButton(dpy, 2, AnyModifier, w, False, PointerMotionHintMask | Button2MotionMask, GrabModeAsync, GrabModeSync, None, None); // UngrabButton XUngrabButton(dpy, 2, LockMask, w); // ChangeActivePointerGrab XChangeActivePointerGrab(dpy, ButtonPressMask, None, CurrentTime); // GrabKeyboard XGrabKeyboard(dpy, w, True, GrabModeSync, GrabModeSync, 12000); // UngrabKeyboard XUngrabKeyboard(dpy, 13000); // GrabKey XGrabKey(dpy, XKeysymToKeycode(dpy, XK_Tab), ShiftMask | Mod3Mask, w, True, GrabModeSync, GrabModeSync); // UngrabKey XUngrabKey(dpy, AnyKey, AnyModifier, w); // AllowEvents XAllowEvents(dpy, AsyncPointer, 14000); // GrabServer XGrabServer(dpy); // UngrabServer XUngrabServer(dpy); // QueryPointer Window child; int root_x, root_y, win_x, win_y; unsigned mask; Bool bres = XQueryPointer(dpy, w, &root, &child, &root_x, &root_y, &win_x, &win_y, &mask); // GetMotionEvents int nevents; XGetMotionEvents(dpy, w, 15000, 16000, &nevents); // TranslateCoordinates int dest_x, dest_y; XTranslateCoordinates(dpy, w, w2, 10, 20, &dest_x, &dest_y, &child); // WarpPointer XWarpPointer(dpy, w, w2, 0, 0, 100, 100, 20, 30); // SetInputFocus XSetInputFocus(dpy,w, RevertToPointerRoot, 17000); XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, 17000); // GetInputFocus Window focus; int revert_to; XGetInputFocus(dpy, &focus, &revert_to); // QueryKeymap char keys_return[32]; XQueryKeymap(dpy, keys_return); // OpenFont Font fid = XLoadFont(dpy, "cursor"); // CloseFont XUnloadFont(dpy, fid); // QueryFont XFontStruct *fs = XLoadQueryFont(dpy, "cursor"); assert(fs); // QueryTextExtents int direction, font_ascent, font_descent; XCharStruct overall; XQueryTextExtents(dpy, fs -> fid, "toto", 4, &direction, &font_ascent, &font_descent, &overall); XQueryTextExtents(dpy, fs -> fid, "odd__length", 11, &direction, &font_ascent, &font_descent, &overall); XChar2b c2bs; c2bs.byte1 = '$'; c2bs.byte2 = 'B'; XQueryTextExtents16(dpy, fs -> fid, &c2bs, 1, &direction, &font_ascent, &font_descent, &overall); XQueryTextExtents(dpy, fs -> fid, longString, strlen(longString), &direction, &font_ascent, &font_descent, &overall); // ListFonts int actual_count; char **fontList = XListFonts(dpy, "*", 100, &actual_count); XFree((char *)fontList); // ListFontsWithInfo int count; XFontStruct *info; char **names = XListFontsWithInfo(dpy, "*", 100, &count, &info); XFreeFontInfo(names, info, count); // SetFontPath // GetFontPath int npaths; char **charList = XGetFontPath(dpy, &npaths); char **charList2 = new char *[npaths + 1]; memcpy(charList2, charList, npaths * sizeof(char *)); charList2[npaths] = charList2[0]; XSetFontPath(dpy, charList2, npaths + 1); XSetFontPath(dpy, charList, npaths); // Reset to some reasonnable value XFreeFontPath(charList); delete [] charList2; // CreatePixmap Pixmap pix2 = XCreatePixmap(dpy, w, 100, 200, DefaultDepthOfScreen(scr)); // FreePixmap XFreePixmap(dpy, pix2); // CreateGC Pixmap bitmap = XCreateBitmapFromData(dpy, RootWindowOfScreen(scr), "\000\000\001\000\000\001\000\000\001\377\377\377", 3, 4); XGCValues gcv; gcv.function = GXand; gcv.plane_mask = 0x1; gcv.foreground = WhitePixelOfScreen(scr); gcv.background = BlackPixelOfScreen(scr); gcv.line_width = 2; gcv.line_style = LineDoubleDash; gcv.cap_style = CapProjecting; gcv.join_style = JoinRound; gcv.fill_style = FillStippled; gcv.fill_rule = EvenOddRule; gcv.arc_mode = ArcPieSlice; gcv.tile = pixmap; gcv.stipple = bitmap; gcv.ts_x_origin = 3; gcv.ts_y_origin = 4; gcv.font = fs -> fid; gcv.subwindow_mode = ClipByChildren; gcv.graphics_exposures = True; gcv.clip_x_origin = 5; gcv.clip_y_origin = 6; gcv.clip_mask = bitmap; gcv.dash_offset = 1; gcv.dashes = 0xc2; GC gc = XCreateGC(dpy, w, GCFunction | GCPlaneMask | GCForeground | GCBackground | GCLineWidth | GCLineStyle | GCCapStyle | GCJoinStyle | GCFillStyle | GCFillRule | GCTile | GCStipple | GCTileStipXOrigin | GCTileStipYOrigin | GCFont | GCSubwindowMode | GCGraphicsExposures | GCClipXOrigin | GCClipYOrigin | GCClipMask | GCDashOffset | GCDashList | GCArcMode, &gcv); // ChangeGC gcv.function = GXandReverse; // Only a few of these should appear, since the values are cached on the client side by the Xlib. XChangeGC(dpy, gc, GCFunction | GCLineStyle | GCStipple | GCGraphicsExposures | GCDashList, &gcv); // CopyGC GC gc2 = XCreateGC(dpy, w, 0, NIL); XCopyGC(dpy, gc, GCFunction | GCLineStyle | GCStipple | GCGraphicsExposures | GCDashList, gc2); // SetDashes XSetDashes(dpy, gc, 3, "\001\377\001", 3); // SetClipRectangles XRectangle rectangles[] = { { 10, 20, 30, 40 }, { 100, 200, 5, 3 }, { -5, 1, 12, 24 } }; XSetClipRectangles(dpy, gc, 12, 9, rectangles, SIZEOF(rectangles), Unsorted); // FreeGC // done already // ClearArea XClearArea(dpy, w, 30, 10, 10, 100, False); // CopyArea XCopyArea(dpy, w, pixmap, gc, 0, 0, 100, 100, 10, 10); // CopyPlane // This won't work if the Screen doesn't have at least 3 planes XCopyPlane(dpy, pixmap, w, gc, 20, 10, 40, 30, 0, 0, 0x4); // PolyPoint XDrawPoint(dpy, w, gc, 1, 2); XPoint points[] = { { 3, 4 }, { 5, 6 } }; XDrawPoints(dpy, w, gc, points, SIZEOF(points), CoordModeOrigin); // PolyLine XDrawLines(dpy, w, gc, points, SIZEOF(points), CoordModePrevious); // PolySegment XSegment segments[] = { { 7, 8, 9, 10 }, { 11, 12, 13, 14 }, { 15, 16, 17, 18 } }; XDrawSegments(dpy, w, gc, segments, SIZEOF(segments)); // PolyRectangle XDrawRectangles(dpy, w, gc, rectangles, SIZEOF(rectangles)); // PolyArc XArc arcs[] = { { 10, 20, 30, 40, 50, 60 }, { -70, 80, 90, 100, 110, 120 }, { 10, 20, 30, 40, 50, -30 } }; XDrawArcs(dpy, w, gc, arcs, SIZEOF(arcs)); // FillPoly XFillPolygon(dpy, w, gc, points, SIZEOF(points), Convex, CoordModePrevious); // PolyFillRectangle XFillRectangles(dpy, w, gc, rectangles, SIZEOF(rectangles)); // PolyFillArc XFillArcs(dpy, w, gc, arcs, SIZEOF(arcs)); // PutImage // GetImage XImage *image = XGetImage(dpy, w, 10, 20, 40, 30, AllPlanes, ZPixmap); XPutImage(dpy, w, gc, image, 0, 0, 50, 60, 40, 30); XSync(dpy, False); // Make the next request starts at the beginning of a packet // PolyText8 XTextItem textItems[3]; textItems[0].chars = "toto"; textItems[0].nchars = strlen(textItems[0].chars); textItems[0].delta = -3; textItems[0].font = fs->fid; textItems[1].chars = "titi"; textItems[1].nchars = strlen(textItems[1].chars); textItems[1].delta = 3; textItems[1].font = None; textItems[2].chars = "tutu"; textItems[2].nchars = strlen(textItems[2].chars); textItems[2].delta = 0; textItems[2].font = fs->fid; XDrawText(dpy, w, gc, 10, 10, textItems, 3); XTextItem textItems2[3]; textItems2[0].chars = "totox"; textItems2[0].nchars = strlen(textItems2[0].chars); textItems2[0].delta = -3; textItems2[0].font = fs->fid; textItems2[1].chars = "titi"; textItems2[1].nchars = strlen(textItems2[1].chars); textItems2[1].delta = 3; textItems2[1].font = None; textItems2[2].chars = "tutu"; textItems2[2].nchars = strlen(textItems2[2].chars); textItems2[2].delta = 0; textItems2[2].font = fs->fid; XDrawText(dpy, w, gc, 10, 10, textItems2, 3); // PolyText16 XChar2b c2b2[] = { 0, 't', 0, 'x' }; XTextItem16 items16[] = { { &c2bs, 1, -5, None }, { NULL, 0, 0, None }, { c2b2, 2, 0, fs -> fid } }; XDrawText16(dpy, w, gc, 10, 0, items16, SIZEOF(items16)); // ImageText8 XDrawImageString(dpy, w, gc, 10, 10, "toto", 4); // ImageText16 XDrawImageString16(dpy, w, gc, 10, 10, &c2bs, 1); XDrawImageString16(dpy, w, gc, 10, 20, c2b2, 2); // CreateColormap // Don't forget to tell the kids how it was when we had only 8 bits per pixel. Colormap colormap = XCreateColormap(dpy, w, DefaultVisualOfScreen(scr), None); // FreeColormap XFreeColormap(dpy, colormap); colormap = XCreateColormap(dpy, w, DefaultVisualOfScreen(scr), None); // CopyColormapAndFree Colormap colormap2 = XCopyColormapAndFree(dpy, colormap); // InstallColormap XInstallColormap(dpy, colormap2); // UninstallColormap XUninstallColormap(dpy, colormap2); // ListInstalledColormaps int num; Colormap *colormapList = XListInstalledColormaps(dpy, w, &num); // AllocColor XColor screen; screen.red = 0; screen.green = 32767; screen.blue = 65535; screen.flags = DoRed | DoGreen | DoBlue; success = XAllocColor(dpy, colormap, &screen); // AllocNamedColor XColor screen2, exact; success = XAllocNamedColor(dpy, colormap, "Wheat", &screen2, &exact); // AllocColorCells unsigned long plane_masks, pixels; success = XAllocColorCells(dpy, colormap, False, &plane_masks, 1, &pixels, 1); // AllocColorPlanes unsigned long rmask, gmask, bmask; success = XAllocColorPlanes(dpy, colormap, False, &pixels, 1, 0, 0, 0, &rmask, &gmask, &bmask); // FreeColors unsigned long pixels2[2] = { screen.pixel, screen2.pixel }; XFreeColors(dpy, colormap, pixels2, 2, 0); // StoreColors success = XAllocColorCells(dpy, colormap, False, NIL, 0, pixels2, 2); // On many contemporary (that is, year 2000) video cards, you can't allocate read / write cells // I want my requests to be sent, however. if (!success) { XSetErrorHandler(errorHandler); } XColor colors[2]; colors[0] = screen; colors[0].pixel = pixels2[0]; colors[1] = screen2; colors[1].pixel = pixels2[1]; XStoreColors(dpy, colormap, colors, 2); // StoreNamedColor XStoreNamedColor(dpy, colormap, "Wheat", colors[0].pixel, DoBlue); XSync(dpy, False); XSetErrorHandler(NIL); // Restore the default handler // QueryColors screen2.pixel = WhitePixelOfScreen(scr); XQueryColor(dpy, colormap, &screen2); // LookupColor success = XLookupColor(dpy, colormap, "DarkCyan", &exact, &screen); // CreateCursor Cursor cursor = XCreatePixmapCursor(dpy, pixmap, None, &exact, colors, 10, 10); // CreateGlyphCursor Cursor cursor2 = XCreateGlyphCursor(dpy, fs -> fid, fs -> fid, 'X', 0, &exact, colors); // FreeCursor XFreeCursor(dpy, cursor2); // RecolorCursor XRecolorCursor(dpy, cursor, colors, &exact); // QueryBestSize success = XQueryBestSize(dpy, CursorShape, RootWindowOfScreen(scr), 100, 20, &width, &height); // QueryExtension int major_opcode, first_event, first_error; XQueryExtension(dpy, "toto", &major_opcode, &first_event, &first_error); // ListExtensions int nextensions; char **extensionList = XListExtensions(dpy, &nextensions); for(char **p = extensionList; nextensions; nextensions--, p++) std::cout << *p << std::endl; XFree(extensionList); // ChangeKeyboardMapping // GetKeyboardMapping int min_keycodes, max_keycodes; XDisplayKeycodes(dpy, &min_keycodes, &max_keycodes); int keysyms_per_keycode; KeySym *keysyms = XGetKeyboardMapping(dpy, min_keycodes, max_keycodes - min_keycodes + 1, &keysyms_per_keycode); XChangeKeyboardMapping(dpy, min_keycodes, keysyms_per_keycode, keysyms, max_keycodes - min_keycodes + 1); // ChangeKeyboardControl // GetKeyboardControl XKeyboardState keyboardState; XGetKeyboardControl(dpy, &keyboardState); XKeyboardControl keyboardValues; keyboardValues.key_click_percent = keyboardState.key_click_percent; keyboardValues.bell_percent = keyboardState.bell_percent; keyboardValues.bell_pitch = keyboardState.bell_pitch; keyboardValues.bell_duration = keyboardState.bell_duration; keyboardValues.led = 1; keyboardValues.led_mode = LedModeOn; keyboardValues.key = min_keycodes; keyboardValues.auto_repeat_mode = AutoRepeatModeDefault; XChangeKeyboardControl(dpy, KBKeyClickPercent | KBBellPercent | KBBellPitch | KBBellDuration | KBLed | KBLedMode | KBKey | KBAutoRepeatMode, &keyboardValues); // Bell XBell(dpy, 90); // ChangePointerControl // GetPointerControl int accel_numerator, accel_denominator, threshold; XGetPointerControl(dpy, &accel_numerator, &accel_denominator, &threshold); XChangePointerControl(dpy, True, True, accel_numerator, accel_denominator, threshold); // SetScreenSaver // GetScreenSaver int timeout, interval, prefer_blanking, allow_exposures; XGetScreenSaver(dpy, &timeout, &interval, &prefer_blanking, &allow_exposures); XSetScreenSaver(dpy, timeout, interval, prefer_blanking, allow_exposures); // ChangeHosts // ListHosts int nhosts; Bool state; XHostAddress *hostList = XListHosts(dpy, &nhosts, &state); XHostAddress host; host.family = FamilyInternet; host.length = 4; host.address = "\001\002\003\004"; XAddHost(dpy, &host); // SetAccessControl XSetAccessControl(dpy, EnableAccess); // SetCloseDownMode XSetCloseDownMode(dpy, RetainTemporary); // KillClient XKillClient(dpy, AllTemporary); // RotateProperties Atom properties[] = { XInternAtom(dpy, "CUT_BUFFER0", False), XInternAtom(dpy, "CUT_BUFFER1", False), XInternAtom(dpy, "CUT_BUFFER2", False) }; XRotateWindowProperties(dpy, RootWindowOfScreen(scr), properties, SIZEOF(properties), -1); // ForceScreenSaver XForceScreenSaver(dpy, ScreenSaverReset); // SetPointerMapping // GetPointerMapping unsigned char map[64]; int map_length = XGetPointerMapping(dpy, map, 64); XSetPointerMapping(dpy, map, map_length); // SetModifierMapping // GetModifierMapping XModifierKeymap *modmap = XGetModifierMapping(dpy); XSetModifierMapping(dpy, modmap); // NoOperation XNoOp(dpy); for(;;) { XEvent e; XNextEvent(dpy, &e); std::cout << "Got an event of type " << e.type << std::endl; } }
void resize(unt w, unt h) { if(canvas) { XFreePixmap(disp, canvas); } canvas=XCreatePixmap(disp,DefaultRootWindow(disp),w,h,depth); }
static void * whirlygig_init (Display *dpy, Window window) { struct state *st = (struct state *) calloc (1, sizeof(*st)); st->dpy = dpy; st->window = window; st->ncolors = NCOLORS; st->dbuf = get_boolean_resource (st->dpy, "doubleBuffer", "Boolean"); # ifdef HAVE_COCOA /* Don't second-guess Quartz's double-buffering */ st->dbuf = False; # endif st->start_time = st->current_time; st->info = (struct info *)malloc(sizeof(struct info)); st->screen = DefaultScreen(st->dpy); XGetWindowAttributes (st->dpy, st->window, &st->xgwa); if (st->dbuf) { #ifdef HAVE_DOUBLE_BUFFER_EXTENSION if (get_boolean_resource(st->dpy,"useDBE","Boolean")) { st->dbeclear_p = get_boolean_resource (st->dpy, "useDBEClear", "Boolean"); if (st->dbeclear_p) st->b = xdbe_get_backbuffer (st->dpy, st->window, XdbeBackground); else st->b = xdbe_get_backbuffer (st->dpy, st->window, XdbeUndefined); st->backb = st->b; } #endif /* HAVE_DOUBLE_BUFFER_EXTENSION */ if (!st->b) { st->ba = XCreatePixmap (st->dpy, st->window, st->xgwa.width, st->xgwa.height,st->xgwa.depth); st->b = st->ba; } } else { st->b = st->window; } st->gcv.foreground = get_pixel_resource(st->dpy, st->xgwa.colormap, "foreground", "Foreground"); st->fgc = XCreateGC (st->dpy, st->b, GCForeground, &st->gcv); st->gcv.foreground = get_pixel_resource(st->dpy, st->xgwa.colormap, "background", "Background"); st->bgc = XCreateGC (st->dpy, st->b, GCForeground, &st->gcv); #ifdef HAVE_COCOA /* #### should turn off double-buffering instead */ jwxyz_XSetAntiAliasing (dpy, st->fgc, False); jwxyz_XSetAntiAliasing (dpy, st->bgc, False); #endif { Bool writable_p = False; make_uniform_colormap (st->dpy, st->xgwa.visual, st->xgwa.colormap, st->colors, &st->ncolors, True, &writable_p, True); } if (st->ba) XFillRectangle (st->dpy, st->ba, st->bgc, 0, 0, st->xgwa.width, st->xgwa.height); /* info is a structure holding all the random pieces of information I may want to pass to my baby functions -- much of it I may never use, but it is nice to have around just in case I want it to make a funky function funkier */ /* info->writable = get_boolean_resource (dpy, "cycle", "Boolean"); */ st->info->xspeed = get_float_resource(st->dpy, "xspeed" , "Float"); st->info->yspeed = get_float_resource(st->dpy, "yspeed" , "Float"); st->info->xamplitude = get_float_resource(st->dpy, "xamplitude", "Float"); st->info->yamplitude = get_float_resource(st->dpy, "yamplitude", "Float"); st->info->offset_period = get_float_resource(st->dpy, "offset_period", "Float"); st->info->whirlies = get_integer_resource(st->dpy, "whirlies", "Integer"); st->info->nlines = get_integer_resource(st->dpy, "nlines", "Integer"); st->info->half_width = st->xgwa.width / 2; st->info->half_height = st->xgwa.height / 2; st->info->speed = get_integer_resource(st->dpy, "speed" , "Integer"); st->info->trail = get_boolean_resource(st->dpy, "trail", "Integer"); st->info->color_modifier = get_integer_resource(st->dpy, "color_modifier", "Integer"); st->info->xoffset = get_float_resource(st->dpy, "xoffset", "Float"); st->info->yoffset = get_float_resource(st->dpy, "yoffset", "Float"); st->xmode_str = get_string_resource(st->dpy, "xmode", "Mode"); st->ymode_str = get_string_resource(st->dpy, "ymode", "Mode"); st->wrap = get_boolean_resource(st->dpy, "wrap", "Boolean"); st->modifier = 3000.0 + frand(1500.0); if (! st->xmode_str) st->xmode = spin_mode; else if (! strcmp (st->xmode_str, "spin")) st->xmode = spin_mode; else if (! strcmp (st->xmode_str, "funky")) st->xmode = funky_mode; else if (! strcmp (st->xmode_str, "circle")) st->xmode = circle_mode; else if (! strcmp (st->xmode_str, "linear")) st->xmode = linear_mode; else if (! strcmp (st->xmode_str, "test")) st->xmode = test_mode; else if (! strcmp (st->xmode_str, "fun")) st->xmode = fun_mode; else if (! strcmp (st->xmode_str, "innie")) st->xmode = innie_mode; else if (! strcmp (st->xmode_str, "lissajous")) st->xmode = lissajous_mode; else { st->xmode = random() % (int) lissajous_mode; } if (! st->ymode_str) st->ymode = spin_mode; else if (! strcmp (st->ymode_str, "spin")) st->ymode = spin_mode; else if (! strcmp (st->ymode_str, "funky")) st->ymode = funky_mode; else if (! strcmp (st->ymode_str, "circle")) st->ymode = circle_mode; else if (! strcmp (st->ymode_str, "linear")) st->ymode = linear_mode; else if (! strcmp (st->ymode_str, "test")) st->ymode = test_mode; else if (! strcmp (st->ymode_str, "fun")) st->ymode = fun_mode; else if (! strcmp (st->ymode_str, "innie")) st->ymode = innie_mode; else if (! strcmp (st->ymode_str, "lissajous")) st->ymode = lissajous_mode; else { st->ymode = random() % (int) lissajous_mode; } if (get_integer_resource(st->dpy, "start_time", "Integer") == -1) st->current_time = (unsigned long int)(random()); else st->current_time = get_integer_resource(st->dpy, "start_time", "Integer"); if (st->info->whirlies == -1) st->info->whirlies = 1 + (random() % 15); if (st->info->nlines == -1) st->info->nlines = 1 + (random() % 5); if (st->info->color_modifier == -1) st->info->color_modifier = 1 + (random() % 25); if (get_boolean_resource(st->dpy, "explain", "Integer")) st->explaining = 1; st->current_color = 1 + (random() % NCOLORS); return st; }
int video_set(PLOT *plot) { struct videodata *plotdata = (struct videodata *)plot->plotdata; GROUP *group = plot->group; Display *dpy = XtDisplay(plot->plot_widget); Widget w = (Widget)plot->plot_widget; Dimension height, width; Window root_return; int x_return, y_return; unsigned int pixwidth, pixheight, border_width_return, depth_return; unsigned long long ntime; int haschanged = 0; /* ** We do this here because the window must be realized to grab the mouse ** it isn't realized during the call to video_open(). */ if (plotdata->butgrabbed == FALSE) { XGrabButton(dpy, AnyButton, AnyModifier, XtWindow(w), TRUE, ButtonPressMask | ButtonReleaseMask | Button2MotionMask, GrabModeAsync, GrabModeAsync, XtWindow(w), XCreateFontCursor(dpy, XC_crosshair)); plotdata->butgrabbed = TRUE; } /* ** Retrieve the window size ** ** The check here for height > 65000 is a workaround for a Motif bug. ** When I select 2 files and draw a video for each, then the second one ** gets a size of 65518 - which is presumably an error */ XtVaGetValues(w, XmNheight, &height, XmNwidth, &width, NULL); if ((height > 65000) || (height < 10)) return SUCCESS; plot->width = width; plot->height = height; /* ** If the window size has changed, we need to reallocate the ** pixmap. */ XGetGeometry(dpy, plotdata->pixmap, &root_return, &x_return, &y_return, &pixwidth, &pixheight, &border_width_return, &depth_return); if ((pixheight != height) || (pixwidth != width)) { if (plotdata->pixmapalloced) XFreePixmap(dpy, plotdata->pixmap); plotdata->pixmap = XCreatePixmap(dpy, DefaultRootWindow(dpy), width, height, plot->depth); plotdata->pixmapalloced = TRUE; haschanged++; } XFillRectangle(dpy, plotdata->pixmap, plotdata->inverse_GC, 0, 0, width, height); /* ** Clear any marks */ plot->playmark = -1; plot->markx1 = -1; plot->markx2 = -1; /* ** Load the desired frame */ if (plotdata->framenum != plotdata->loadedframenum) { if (vid_read(group->vidfp, plotdata->framenum, plotdata->framedata, &ntime) != 0) { fprintf(stderr, "Error reading frame #%d for file '%s'\n", plotdata->framenum, group->loadedfilename); } plotdata->loadedframenum = plotdata->framenum; haschanged++; } /* ** Do the rendering to an off-screen pixmap, then copy to the window. */ if (haschanged) { cursor_set_busy(toplevel); XPutImage(dpy, plotdata->pixmap, plotdata->drawing_GC, plotdata->image, 0, 0, 0, 0, width, height); XCopyArea(dpy, plotdata->pixmap, XtWindow(w), plotdata->drawing_GC, 0, 0, width, height, 0, 0); cursor_unset_busy(toplevel); } return SUCCESS; }
static void * compass_init (Display *dpy, Window window) { struct state *st = (struct state *) calloc (1, sizeof(*st)); XGCValues gcv; st->dpy = dpy; st->window = window; st->delay = get_integer_resource (st->dpy, "delay", "Integer"); st->dbuf = get_boolean_resource (st->dpy, "doubleBuffer", "Boolean"); # ifdef HAVE_JWXYZ /* Don't second-guess Quartz's double-buffering */ st->dbuf = False; # endif XGetWindowAttributes (st->dpy, st->window, &st->xgwa); st->size2 = MIN(st->xgwa.width, st->xgwa.height); if (st->xgwa.width > st->xgwa.height * 5 || /* goofy aspect ratio */ st->xgwa.height > st->xgwa.width * 5) st->size2 = MAX(st->xgwa.width, st->xgwa.height); { int max = 600; if (st->xgwa.width > 2560) max *= 2; /* Retina displays */ if (st->size2 > max) st->size2 = max; } st->size = (st->size2 / 2) * 0.8; st->x = st->xgwa.width/2; st->y = st->xgwa.height/2; if (st->dbuf) { #ifdef HAVE_DOUBLE_BUFFER_EXTENSION st->b = st->backb = xdbe_get_backbuffer (st->dpy, st->window, XdbeUndefined); #endif /* HAVE_DOUBLE_BUFFER_EXTENSION */ if (!st->b) { st->x = st->size2/2; st->y = st->size2/2; st->ba = XCreatePixmap (st->dpy, st->window, st->size2, st->size2, st->xgwa.depth); st->bb = XCreatePixmap (st->dpy, st->window, st->size2, st->size2, st->xgwa.depth); st->b = st->ba; } } else { st->b = st->window; } st->discs[0] = (struct disc *) calloc (1, sizeof (struct disc)); st->discs[1] = (struct disc *) calloc (1, sizeof (struct disc)); st->discs[2] = (struct disc *) calloc (1, sizeof (struct disc)); st->discs[3] = 0; gcv.foreground = get_pixel_resource (st->dpy, st->xgwa.colormap, "foreground", "Foreground"); gcv.line_width = MAX(2, (st->size/60)); gcv.join_style = JoinBevel; st->discs[0]->draw = draw_ticks; st->discs[0]->gc = XCreateGC (st->dpy, st->b, GCForeground|GCLineWidth|GCJoinStyle, &gcv); init_spin (st->discs[0]); gcv.foreground = get_pixel_resource (st->dpy, st->xgwa.colormap, "arrow2Foreground", "Foreground"); gcv.line_width = MAX(4, (st->size / 30)); st->discs[1]->draw = draw_thick_arrow; st->discs[1]->gc = XCreateGC (st->dpy, st->b, GCForeground|GCLineWidth, &gcv); init_spin (st->discs[1]); gcv.foreground = get_pixel_resource (st->dpy, st->xgwa.colormap, "arrow1Foreground", "Foreground"); gcv.line_width = MAX(4, (st->size / 30)); st->discs[2]->draw = draw_thin_arrow; st->discs[2]->gc = XCreateGC (st->dpy, st->b, GCForeground|GCLineWidth, &gcv); init_spin (st->discs[2]); gcv.foreground = get_pixel_resource (st->dpy, st->xgwa.colormap, "pointerForeground", "Foreground"); st->ptr_gc = XCreateGC (st->dpy, st->b, GCForeground|GCLineWidth, &gcv); gcv.foreground = get_pixel_resource (st->dpy, st->xgwa.colormap, "background", "Background"); st->erase_gc = XCreateGC (st->dpy, st->b, GCForeground, &gcv); if (st->ba) XFillRectangle (st->dpy, st->ba, st->erase_gc, 0, 0, st->size2, st->size2); if (st->bb) XFillRectangle (st->dpy, st->bb, st->erase_gc, 0, 0, st->size2, st->size2); return st; }
void process_event(XEvent *xe) { KeySym keysym; char keystring[4]; switch (xe->type) { case KeyPress: keysym = XKeycodeToKeysym(dpy,xe->xkey.keycode,0); /* first, consider the raw keysyms, to catch a few combinations of keys with shift/alt */ switch (keysym) { case XK_1: if (xe->xkey.state & ShiftMask) { key='!'; return; } case XK_2: if (xe->xkey.state & ShiftMask) { key='@'; return; } case XK_3: if (xe->xkey.state & ShiftMask) { key='#'; return; } case XK_4: if (xe->xkey.state & ShiftMask) { key='$'; return; } case XK_d: case XK_D: if (xe->xkey.state & Mod1Mask) { key=160; return; } case XK_m: case XK_M: if (xe->xkey.state & Mod1Mask) { key=178; return; } case XK_o: case XK_O: if (xe->xkey.state & Mod1Mask) { key=152; return; } case XK_p: case XK_P: if (xe->xkey.state & Mod1Mask) { key=153; return; } case XK_s: case XK_S: if (xe->xkey.state & Mod1Mask) { key=159; return; } } /* for the rest, first process the keysym further, in which things like shift, ctrl and numlock are taken into account */ if (XLookupString((XKeyEvent*)xe, keystring, 4, &keysym, NULL)!=0) { /* normal ASCII characters, and ctrl-codes, go here: */ key=keystring[0]; return; } /* remaining keys (cursor, function, etc.) go here: */ switch (keysym) { case XK_KP_Up: case XK_Up: key= (xe->xkey.state & ShiftMask) ? 184 : 200; return; case XK_KP_Down: case XK_Down: key= (xe->xkey.state & ShiftMask) ? 178 : 208; return; case XK_KP_Left: case XK_Left: key= (xe->xkey.state & ShiftMask) ? 180 : 203; return; case XK_KP_Right: case XK_Right: key= (xe->xkey.state & ShiftMask) ? 182 : 205; return; case XK_KP_Page_Up: case XK_Prior: key= 201; /* page up ? */ return; case XK_KP_Page_Down: case XK_Next: key= 209; /* page down ? */ return; case XK_F1: key= 187; return; case XK_F2: key= 188; return; case XK_F3: key= 189; return; case XK_F4: key= 190; return; case XK_F5: key= (xe->xkey.state & ShiftMask) ? 216 : 191; return; case XK_F6: key= 192; return; case XK_F10: key= 196; return; case XK_KP_Insert: case XK_Insert: key= 210; return; case XK_KP_Delete: case XK_Delete: key= 211; return; } break; case ConfigureNotify: { XConfigureEvent *xrre=(XConfigureEvent*)xe; int ww,hh; ww=ScreenWidth; hh=ScreenHeight; ScreenWidth=xrre->width; ScreenHeight=xrre->height; if (ww>ScreenWidth) ww=ScreenWidth; if (hh>ScreenHeight) hh=ScreenHeight; // we notify the pascal code about the resize by sending a "virtual" keypress key=255; // this constant is screenresize in the pascal code // need to update the background pixmap Pixmap oldpm=pm; pm=XCreatePixmap(dpy, RootWindow(dpy,scr),ScreenWidth,ScreenHeight,wa.depth); XFillRectangle(dpy, pm, gcfill, 0,0,ScreenWidth,ScreenHeight); XCopyArea(dpy, oldpm, pm, gc, 0, 0, ww, hh, 0, 0); XFreePixmap(dpy, oldpm); XSetWindowBackgroundPixmap(dpy,w,pm); return; } } }
ocpCursor::ocpCursor ( const wxString& cursorName, long type, int hotSpotX, int hotSpotY ) : wxCursor ( wxCURSOR_CROSS ) { wxImage cImage; if ( !cImage.CanRead ( cursorName ) ) ::wxInitAllImageHandlers(); cImage.LoadFile ( cursorName ); int width = cImage.GetWidth(); int height = cImage.GetHeight(); // m_refData = new wxCursorRefData(); // Get some X parameters int xscreen = DefaultScreen ( ( Display* ) wxGlobalDisplay() ); Window xroot = RootWindow ( ( Display* ) wxGlobalDisplay(), xscreen ); Visual* xvisual = DefaultVisual ( ( Display* ) wxGlobalDisplay(), xscreen ); M_CURSORDATA->m_display = wxGlobalDisplay(); wxASSERT_MSG ( M_CURSORDATA->m_display, wxT ( "No display" ) ); // Make a pixmap Pixmap cpixmap = XCreatePixmap ( ( Display* ) wxGlobalDisplay(), xroot, width, height, 1 ); // Make an Ximage XImage *data_image = XCreateImage ( ( Display* ) wxGlobalDisplay(), xvisual, 1, ZPixmap, 0, 0, width, height, 32, 0 ); data_image->data = ( char* ) malloc ( data_image->bytes_per_line * data_image->height ); int index = 0; int pixel = 0; unsigned char* data = cImage.GetData(); // Create mask Pixmap cmask; unsigned char mr, mg, mb; if ( cImage.HasMask() ) { XImage *mask_image = XCreateImage ( ( Display* ) wxGlobalDisplay(), xvisual, 1, ZPixmap, 0, 0, width, height, 32, 0 ); mask_image->data = ( char* ) malloc ( mask_image->bytes_per_line * mask_image->height ); cImage.GetOrFindMaskColour ( &mr, &mg, &mb ); int rit = ( mr << 16 ) + ( mg << 8 ) + mb; for ( int y = 0; y < height; y++ ) { for ( int x = 0; x < width; x++ ) { int ri = ( int ) data[index++]; ri += data[index++] << 8; ri += data[index++] << 16; /* int ri = *(int *)(&data[index]); ri &= 0x00ffffff; index++; index++; index++; */ pixel = 1; if ( ri == rit ) // if data is mask value, mask pixel gets 0 pixel = 0; XPutPixel ( mask_image, x, y, pixel ); } } cmask = XCreatePixmap ( ( Display* ) wxGlobalDisplay(), xroot, width, height, 1 ); GC gc = XCreateGC ( ( Display* ) wxGlobalDisplay(), cmask, 0, NULL ); XPutImage ( ( Display* ) wxGlobalDisplay(), cmask, gc, mask_image, 0, 0, 0, 0, width, height ); XDestroyImage ( mask_image ); XFreeGC ( ( Display* ) wxGlobalDisplay(), gc ); } // Render the wxImage cImage onto the Ximage // Simple black/white cursors only, please index = 0; for ( int y = 0; y < height; y++ ) { for ( int x = 0; x < width; x++ ) { int ri = ( int ) data[index++]; ri += data[index++] << 8; ri += data[index++] << 16; /* int ri = *(int *)(&data[index]); ri &= 0x00ffffff; index++; index++; index++; */ pixel = 0; if ( ri ) pixel = 1; XPutPixel ( data_image, x, y, pixel ); } } // Put the Ximage into the pixmap GC gc = XCreateGC ( ( Display* ) wxGlobalDisplay(), cpixmap, 0, NULL ); XPutImage ( ( Display* ) wxGlobalDisplay(), cpixmap, gc, data_image, 0, 0, 0, 0, width, height ); // Free the Ximage stuff XDestroyImage ( data_image ); XFreeGC ( ( Display* ) wxGlobalDisplay(), gc ); // Make a X cursor from the pixmap XColor fg, bg; fg.red = fg.blue = fg.green = 0xffff; bg.red = bg.blue = bg.green = 0; M_CURSORDATA->m_cursor = ( WXCursor ) XCreatePixmapCursor ( ( Display* ) wxGlobalDisplay(), cpixmap, cmask, &fg, &bg, hotSpotX, hotSpotY ); }
void* iupdrvImageCreateImage(Ihandle *ih, const char* bgcolor, int make_inactive) { int y, x, bpp, bgcolor_depend = 0, width = ih->currentwidth, height = ih->currentheight; unsigned char *imgdata = (unsigned char*)iupAttribGetStr(ih, "WID"); Pixmap pixmap; unsigned char bg_r=0, bg_g=0, bg_b=0; GC gc; Pixel color2pixel[256]; bpp = iupAttribGetInt(ih, "BPP"); iupStrToRGB(bgcolor, &bg_r, &bg_g, &bg_b); if (bpp == 8) { int i, colors_count = 0; iupColor colors[256]; iupImageInitColorTable(ih, colors, &colors_count); for (i=0;i<colors_count;i++) { if (colors[i].a == 0) { colors[i].r = bg_r; colors[i].g = bg_g; colors[i].b = bg_b; colors[i].a = 255; bgcolor_depend = 1; } if (make_inactive) iupImageColorMakeInactive(&(colors[i].r), &(colors[i].g), &(colors[i].b), bg_r, bg_g, bg_b); color2pixel[i] = iupmotColorGetPixel(colors[i].r, colors[i].g, colors[i].b); } } pixmap = XCreatePixmap(iupmot_display, RootWindow(iupmot_display,iupmot_screen), width, height, iupdrvGetScreenDepth()); if (!pixmap) return NULL; gc = XCreateGC(iupmot_display,pixmap,0,NULL); for (y=0;y<height;y++) { for(x=0;x<width;x++) { unsigned long p; if (bpp == 8) p = color2pixel[imgdata[y*width+x]]; else { int channels = (bpp==24)? 3: 4; unsigned char *pixel_data = imgdata + y*width*channels + x*channels; unsigned char r = *(pixel_data), g = *(pixel_data+1), b = *(pixel_data+2); if (bpp == 32) { unsigned char a = *(pixel_data+3); if (a != 255) { /* flat alpha */ r = iupALPHABLEND(r, bg_r, a); g = iupALPHABLEND(g, bg_g, a); b = iupALPHABLEND(b, bg_b, a); bgcolor_depend = 1; } } if (make_inactive) iupImageColorMakeInactive(&r, &g, &b, bg_r, bg_g, bg_b); p = iupmotColorGetPixel(r, g, b); } XSetForeground(iupmot_display,gc,p); XDrawPoint(iupmot_display,pixmap,gc,x,y); } } XFreeGC(iupmot_display,gc); if (bgcolor_depend || make_inactive) iupAttribSet(ih, "_IUP_BGCOLOR_DEPEND", "1"); return (void*)pixmap; }
/** * main application method * * usage / command line arguments * xgravity [planet count] [calculation threads] * * @param argc * @param argv */ int main(int argc, char *argv[]) { pthread_t calcThreads[MAX_THREADS]; pthread_barrier_t calcBarrier; pthread_mutex_t calcMutex = PTHREAD_MUTEX_INITIALIZER; calcArgs calcThreadArgs; int threads; // number of calculation threads to run planet *planets[MAXCOUNT]; planet *aPlanet; double minx, maxx, miny, maxy, cx, cy, massMax, massMin, timeFactor, forceMultiplier, radiusScale; int pi, count; // planet iterator long int zoomFactor; // zoom factor int centerID; // id of object to use for auto centering int radius; // radius in pixels double fg, td, dist; // temporary accelerating force and direction int shownum; // show stat numbers flag int showforce; // show force lines flag int winw, winh; // window dimensions Display *display; int screen; Window window; XEvent event; KeySym key; char text[255]; Pixmap pixmap; GC gc; Colormap colormap; XGCValues values_return; XFontStruct *font_info; GContext gid; // check for planet count in arguments if( argc > 1 ) { // first argument is planet count count = atoi(argv[1]); if( count > MAXCOUNT ) count = MAXCOUNT; } else { count = COUNT; } // check for thread count in arguments if( argc > 2 ) { // first argument is planet count threads = atoi(argv[2]); if ( threads < 1 ) { threads = THREAD_COUNT; } else if ( threads > MAX_THREADS ) { threads = MAX_THREADS; } } else { threads = THREAD_COUNT; } // set default control values timeFactor = 1; // calculation time factor in seconds zoomFactor = 4; // start zoomed out a bit forceMultiplier = 1e-8; // need a small multiplier to shrink force lines shownum = 0; // do not show numbers showforce = 0; // do not show force lines centerID = -1; // not centered on any planets winw = WINW; winh = WINH; cx = 0; cy = 0; // setup Xwindow display = XOpenDisplay(NULL); if( display == NULL) { printf("Cannot open display\n"); exit(1); } screen = DefaultScreen(display); window = XCreateSimpleWindow( display, RootWindow(display, screen), 10, 10, winw, winh, 1, WhitePixel(display, screen), BlackPixel(display, screen)); XMapWindow(display, window); XFlush(display); // show the window ID in case need to use for screen grab / cast printf("Window ID:%d\r\n", window); XSelectInput (display, window, KeyPressMask | StructureNotifyMask | ButtonPressMask); pixmap = XCreatePixmap(display, window, winw, winh, DefaultDepth(display, screen)); XFlush(display); colormap = DefaultColormap(display, 0); gc = XCreateGC(display, pixmap, 0, 0); // define color codes char *colorCodes[] = { "#009900", "#4444FF", "#FF4400", "#FFFFFF", "#000000", "#FFFF00", "#A0A0A0", "#E0D1FF" }; // create colors for palette XColor drawColors[COLOR_COUNT]; for(pi = 0; pi < COLOR_COUNT; pi++) { XParseColor(display, colormap, colorCodes[pi], &drawColors[pi]); XAllocColor(display, colormap, &drawColors[pi]); } gid = XGContextFromGC(gc); font_info = XQueryFont(display, gid); XSetForeground(display, gc, drawColors[COLOR_BACKGROUND].pixel); XFillRectangle(display, pixmap, gc, 0, 0, winw, winh); XCopyArea(display, pixmap, window, gc, 0, 0, winw, winh, 0, 0); XFlush(display); // allocate memory for planet data for ( pi = 0; pi < count; pi++ ) { planets[pi] = (planet *) malloc(sizeof(planet)); } // initialize planets randomizePlanets(planets, count); // initialize the thread barrier to thread count plus main pthread_barrier_init(&calcBarrier, NULL, threads + 1); // collect thread arguments into struct calcThreadArgs.planetData = planets; calcThreadArgs.count = count; calcThreadArgs.calcBarrier = &calcBarrier; calcThreadArgs.calcMutex = &calcMutex; // initialize threads for(pi = 0; pi < threads; pi++) { pthread_create(&calcThreads[pi], NULL, &calcWorker, &calcThreadArgs); } // main application loop while(1) { // keyboard events if( XCheckMaskEvent(display, KeyPressMask, &event) && XLookupString(&event.xkey, text, 255, &key, 0)==1 ) { // quit if (text[0]=='q') { XCloseDisplay(display); exit(0); } // toggle show force lines if( text[0] == 'f' ) { showforce += 1; if( showforce > 3 ) showforce = 0; } // adjust force line multiplier dimension if( text[0] == 'd' ) forceMultiplier = forceMultiplier / 10; if( text[0] == 'D' ) forceMultiplier = forceMultiplier * 10; // toggle show stat numbers if( text[0] == 'o' ) { shownum += 1; if( shownum > 6 ) shownum = 0; } // toggle calculation time factor in seconds else if( text[0] == 't' ) timeFactor = timeFactor / 10; else if( text[0] == 'T' ) timeFactor = timeFactor * 10; // zoom in else if( text[0] == 'z' ) { zoomFactor -= 1; if( zoomFactor < 1 ) zoomFactor = 1; } else if( text[0] == 'Z' ) { zoomFactor = zoomFactor / 2; if( zoomFactor < 1 ) zoomFactor = 1; } // zoom out else if( text[0] == 'x' ) zoomFactor += 1; else if( text[0] == 'X' ) zoomFactor = 2 * zoomFactor; // reset view to no zoom else if( text[0] == 'v' ) zoomFactor = 1; // reset center else if( text[0] == 'c' ) { cx = 0; cy = 0; } // auto zoom to show all planets else if( text[0] == 'a' ) { minx = 0; maxx = 0; miny = 0; maxy = 0; // use planets to find minimum and maximum position values for zoom window for(pi = 0; pi < count; pi++) { if( planets[pi]->mass > 0 ) { if( planets[pi]->x < minx ) minx = planets[pi]->x - 500; if( planets[pi]->x > maxx ) maxx = planets[pi]->x + 500; if( planets[pi]->y < miny ) miny = planets[pi]->y - 500; if( planets[pi]->y > maxy ) maxy = planets[pi]->y + 500; } } // calculate zoom factor if( (maxx - minx) / (double)winw > (maxy - miny) / (double)winh ) zoomFactor = (long int)((maxx - minx) / (double)winw); else zoomFactor = (long int)((maxy - miny) / (double)winh) + 1; // fractional zoom not allowed if( zoomFactor < 1 ) zoomFactor = 1; // recenter view cx = (double)-1.0 * (minx + (maxx - minx) / (double)2.0); cy = (double)-1.0 * (miny + (maxy - miny) / (double)2.0); } // re-randomize planets else if( text[0] == 'r' ) { randomizePlanets(planets, count); } // wipe all planets else if( text[0] == 'w' ) { massMax = 0; massMin = DBL_MAX; clearPlanets(planets, count); } else if( text[0] == 's' ) { // create a gravitation well createGravityWell(planets, count, cx, cy); } else if( text[0] == 'b' ) { // create a binary gravitation well createBinaryWell(planets, count, cx, cy); } else if( text[0] == 'h' ) { // create a heliocentric system createHeliocentricSystem(planets, count, cx, cy); } else if( text[0] == 'g' ) { // create some geocentric nonsense createGeocentricSystem(planets, count, cx, cy); } else if( text[0] == 'p' ) { // create Sol planetary system createPlanetarySystem(planets, count, cx, cy); } else if( text[0] == 'm' ) { // create molniya orbit createMolniyaOrbit(planets, count, cx, cy); } } // end of keyboard events // window config events if( XCheckMaskEvent(display, StructureNotifyMask, &event) && event.type == ConfigureNotify ) { if (event.xconfigure.window == window) { winw = event.xconfigure.width; winh = event.xconfigure.height; XFreePixmap(display, pixmap); XFlush(display); pixmap = XCreatePixmap(display, window, winw, winh, DefaultDepth(display, screen)); XFlush(display); } } // mouse button events if( XCheckMaskEvent(display, ButtonPressMask, &event) ) { centerID = -1; // if clicked on planet then select as centerID for auto centering for(pi = 0; pi < count; pi++) { dist = sqrt(pow((cx + planets[pi]->x) / zoomFactor + (winw / 2) - event.xbutton.x, 2) + pow((cy + planets[pi]->y) / zoomFactor + (winh / 2) - event.xbutton.y, 2)); if( dist < 4 ) { centerID = pi; continue; } } // if not centered on a planet then recenter to click point if( centerID == -1 ) { cx += zoomFactor * (winw / 2 - event.xbutton.x); cy += zoomFactor * (winh / 2 - event.xbutton.y); } // keep in mind that cx, cy is not the center coordinate, it is the direction to shift } // set calculation state on for each planet that has mass for(pi = 0; pi < count; pi++) { if ( planets[pi]->mass > 0 ) { planets[pi]->calc = 1; } } // wait for all threads to start calculations pthread_barrier_wait(&calcBarrier); // wait for all threads to end calculations pthread_barrier_wait(&calcBarrier); // move planets after calculations movePlanets(timeFactor, planets, count); // calculate collisions calculateCollisions(planets, count); massMax = getMassMax(planets, count); massMin = getMassMin(planets, count); // clear display XSetForeground(display, gc, drawColors[COLOR_BACKGROUND].pixel); XFillRectangle(display, pixmap, gc, 0, 0, winw, winh); // if following a planet then recenter display on the planet if( centerID > -1 ) { cx = -1 * planets[centerID]->x; cy = -1 * planets[centerID]->y; } // set radius scale of kg per pixel radiusScale = (massMax - massMin) / (MAX_PIXEL_RADIUS - MIN_PIXEL_RADIUS); // draw each planet for(pi = 0; pi < count; pi++) { // if planet has mass and is within the display area then we draw if( planets[pi]->mass > 0 && (cx + planets[pi]->x) / zoomFactor > -1 * (winw / 2) && (cx + planets[pi]->x) / zoomFactor < (winw / 2) && (cy + planets[pi]->y) / zoomFactor > -1 * (winh / 2) && (cy + planets[pi]->y) / zoomFactor < (winh / 2) ) { // calculate radius relative to mass and other planets radius = (int)(planets[pi]->mass / radiusScale) + MIN_PIXEL_RADIUS; // determine color by flash or radius divisions if( planets[pi]->flash ) { XSetForeground(display, gc, drawColors[COLOR_FLASH].pixel); radius = radius * planets[pi]->flash; planets[pi]->flash -= 1; } else if( radius > 16 ) { // size is color for a star XSetForeground(display, gc, drawColors[COLOR_STAR].pixel); } else if( radius <= 16 && radius > 12 ) { // size is color of blue planet XSetForeground(display, gc, drawColors[COLOR_BLUE].pixel); } else { // default color for smallest is green XSetForeground(display, gc, drawColors[COLOR_GREEN].pixel); } // draw planet dot XFillArc(display, pixmap, gc, ((cx + planets[pi]->x) / zoomFactor + (winw / 2) - radius / 2), ((cy + planets[pi]->y) / zoomFactor + (winh / 2) - radius / 2), radius, radius, 0, 360 * 64); // draw black border XSetForeground(display, gc, drawColors[COLOR_BLACK].pixel); XDrawArc(display, pixmap, gc, ((cx + planets[pi]->x) / zoomFactor + (winw / 2) - radius / 2), ((cy + planets[pi]->y) / zoomFactor + (winh / 2) - radius / 2), radius, radius, 0, 360 * 64); // show force vectors if( showforce > 0 ) { switch( showforce ) { case 1: //draw gravitational force XSetForeground(display, gc, drawColors[COLOR_RED].pixel); XDrawLine(display, pixmap, gc, ((cx + planets[pi]->x) / zoomFactor + (winw / 2)), ((cy + planets[pi]->y) / zoomFactor + (winh / 2)), ((cx + planets[pi]->x + (planets[pi]->mass * planets[pi]->acceleration.accelerationX) * forceMultiplier) / zoomFactor + (winw / 2)), ((cy + planets[pi]->y + (planets[pi]->mass * planets[pi]->acceleration.accelerationY) * forceMultiplier) / zoomFactor + (winh / 2))); XSetForeground(display, gc, drawColors[COLOR_BLUE].pixel); XDrawLine(display, pixmap, gc, ((cx + planets[pi]->x) / zoomFactor + (winw / 2)), ((cy + planets[pi]->y) / zoomFactor + (winh / 2)), ((cx + planets[pi]->x + (planets[pi]->mass * planets[pi]->velocityX * forceMultiplier / 10)) / zoomFactor + (winw / 2)), ((cy + planets[pi]->y + (planets[pi]->mass * planets[pi]->velocityY * forceMultiplier / 10)) / zoomFactor + (winh / 2))); break; case 2: //draw gravitational acceleration XSetForeground(display, gc, drawColors[COLOR_WHITE].pixel); XDrawLine(display, pixmap, gc, ((cx + planets[pi]->x) / zoomFactor + (winw / 2)), ((cy + planets[pi]->y) / zoomFactor + (winh / 2)), ((cx + planets[pi]->x + (planets[pi]->acceleration.accelerationX) * forceMultiplier) / zoomFactor + (winw / 2)), ((cy + planets[pi]->y + (planets[pi]->acceleration.accelerationY) * forceMultiplier) / zoomFactor + (winh / 2))); break; } } // show stat values if( shownum > 0 ) { // set text color XSetForeground(display, gc, drawColors[COLOR_WHITE].pixel); switch( shownum ) { // show planet id number case 1: sprintf(text, "ID:%d", pi); break; // show planet mass case 2: sprintf(text, "%2.2E kg", planets[pi]->mass); break; // show planet velocity case 3: fg = sqrt(pow(planets[pi]->velocityX, 2) + pow(planets[pi]->velocityY, 2)); td = atan2(planets[pi]->velocityY, planets[pi]->velocityX); if( isinf(td) ) td = M_PI / 2; if( isnan(td) && (planets[pi]->velocityX - planets[pi]->velocityX) > 0 ) td = 0; if( isnan(td) && (planets[pi]->velocityX - planets[pi]->velocityX) < 0 ) td = M_PI; td = td * 180 / M_PI + 180; sprintf(text, "%2.2G m/s %3.0f degrees", fg, td); break; // show planet coordinates case 4: sprintf(text, "%G, %G", planets[pi]->x, planets[pi]->y); break; // show mass and velocity case 5: fg = sqrt(pow(planets[pi]->velocityX, 2) + pow(planets[pi]->velocityY, 2)); td = atan2(planets[pi]->velocityY, planets[pi]->velocityX); if( isinf(td) ) td = M_PI / 2; if( isnan(td) && (planets[pi]->velocityX - planets[pi]->velocityX) > 0 ) td = 0; if( isnan(td) && (planets[pi]->velocityX - planets[pi]->velocityX) < 0 ) td = M_PI; td = td * 180 / M_PI + 180; //font_info //font_height = font_info->max_bounds.ascent + //font_info->max_bounds.descent; sprintf(text, "%2.2E kg", planets[pi]->mass); XDrawString(display, pixmap, gc, (cx + planets[pi]->x) / zoomFactor + (winw / 2), (cy + planets[pi]->y) / zoomFactor + (winh / 2) + font_info->max_bounds.ascent + font_info->max_bounds.descent, text, strlen(text)); sprintf(text, "%2.2G m/s %3.0f degrees", fg, td); break; // show inertia and acting gravitational force case 6: fg = planets[pi]->mass * sqrt(pow(planets[pi]->velocityX, 2) + pow(planets[pi]->velocityY, 2)); td = atan2(planets[pi]->velocityY, planets[pi]->velocityX); if( isinf(td) ) td = M_PI / 2; if( isnan(td) && (planets[pi]->velocityX - planets[pi]->velocityX) > 0 ) td = 0; if( isnan(td) && (planets[pi]->velocityX - planets[pi]->velocityX) < 0 ) td = M_PI; td = td * 180 / M_PI + 180; sprintf(text, " P = %2.2G Ns %3.0f degrees", fg, td); XDrawString(display, pixmap, gc, (cx + planets[pi]->x) / zoomFactor + (winw / 2), (cy + planets[pi]->y) / zoomFactor + (winh / 2) + font_info->max_bounds.ascent + font_info->max_bounds.descent, text, strlen(text)); fg = planets[pi]->mass * sqrt(pow(planets[pi]->acceleration.accelerationX, 2) + pow(planets[pi]->acceleration.accelerationY, 2)); td = atan2(planets[pi]->acceleration.accelerationY, planets[pi]->acceleration.accelerationX); if( isinf(td) ) td = M_PI / 2; if( isnan(td) && (planets[pi]->velocityX - planets[pi]->velocityX) > 0 ) td = 0; if( isnan(td) && (planets[pi]->velocityX - planets[pi]->velocityX) < 0 ) td = M_PI; td = td * 180 / M_PI + 180; sprintf(text, " Fg = %2.2G N %3.0f degrees", fg, td); break; } XDrawString(display, pixmap, gc, (cx + planets[pi]->x) / zoomFactor + (winw / 2), (cy + planets[pi]->y) / zoomFactor + (winh / 2), text, strlen(text)); } } } // apply drawn bitmap XCopyArea(display, pixmap, window, gc, 0, 0, winw, winh, 0, 0); XFlush(display); } XCloseDisplay(display); }
char * parse_line(const char *line, int lnr, int align, int reverse, int nodraw) { /* bitmaps */ unsigned int bm_w, bm_h; int bm_xh, bm_yh; /* rectangles, cirlcles*/ int rectw, recth, rectx, recty; /* positioning */ int n_posx, n_posy, set_posy=0; int px=0, py=0, opx=0; int i, next_pos=0, j=0, h=0, tw=0; /* buffer pos */ const char *linep=NULL; /* fonts */ int font_was_set=0; /* position */ int pos_is_fixed = 0; /* block alignment */ int block_align = -1; int block_width = -1; /* clickable area y tracking */ int max_y=-1; /* temp buffers */ char lbuf[MAX_LINE_LEN], *rbuf = NULL; /* parser state */ int t=-1, nobg=0; char *tval=NULL; /* X stuff */ long lastfg = dzen.norm[ColFG], lastbg = dzen.norm[ColBG]; Fnt *cur_fnt = NULL; #ifndef DZEN_XFT XGCValues gcv; #endif Drawable pm=0, bm; #ifdef DZEN_XPM int free_xpm_attrib = 0; Pixmap xpm_pm; XpmAttributes xpma; XpmColorSymbol xpms; #endif #ifdef DZEN_XFT XftDraw *xftd=NULL; XftColor xftc; char *xftcs; int xftcs_f=0; char *xftcs_bg; int xftcs_bgf=0; xftcs = (char *)dzen.fg; xftcs_bg = (char *)dzen.bg; #endif /* icon cache */ int ip; /* parse line and return the text without control commands */ if(nodraw) { rbuf = emalloc(MAX_LINE_LEN); rbuf[0] = '\0'; if( (lnr + dzen.slave_win.first_line_vis) >= dzen.slave_win.tcnt) line = NULL; else line = dzen.slave_win.tbuf[dzen.slave_win.first_line_vis+lnr]; } /* parse line and render text */ else { h = dzen.font.height; py = (dzen.line_height - h) / 2; xorig[LNR2WINDOW(lnr)] = 0; if(lnr != -1) { pm = XCreatePixmap(dzen.dpy, RootWindow(dzen.dpy, DefaultScreen(dzen.dpy)), dzen.slave_win.width, dzen.line_height, DefaultDepth(dzen.dpy, dzen.screen)); } else { pm = XCreatePixmap(dzen.dpy, RootWindow(dzen.dpy, DefaultScreen(dzen.dpy)), dzen.title_win.width, dzen.line_height, DefaultDepth(dzen.dpy, dzen.screen)); } #ifdef DZEN_XFT xftd = XftDrawCreate(dzen.dpy, pm, DefaultVisual(dzen.dpy, dzen.screen), DefaultColormap(dzen.dpy, dzen.screen)); #endif if(!reverse) { XSetForeground(dzen.dpy, dzen.tgc, dzen.norm[ColBG]); #ifdef DZEN_XPM xpms.pixel = dzen.norm[ColBG]; #endif #ifdef DZEN_XFT xftcs_bg = (char *)dzen.bg; xftcs_bgf = 0; #endif } else { XSetForeground(dzen.dpy, dzen.tgc, dzen.norm[ColFG]); #ifdef DZEN_XPM xpms.pixel = dzen.norm[ColFG]; #endif } XFillRectangle(dzen.dpy, pm, dzen.tgc, 0, 0, dzen.w, dzen.h); if(!reverse) { XSetForeground(dzen.dpy, dzen.tgc, dzen.norm[ColFG]); } else { XSetForeground(dzen.dpy, dzen.tgc, dzen.norm[ColBG]); } #ifdef DZEN_XPM xpms.name = NULL; xpms.value = (char *)"none"; xpma.colormap = DefaultColormap(dzen.dpy, dzen.screen); xpma.depth = DefaultDepth(dzen.dpy, dzen.screen); xpma.visual = DefaultVisual(dzen.dpy, dzen.screen); xpma.colorsymbols = &xpms; xpma.numsymbols = 1; xpma.valuemask = XpmColormap|XpmDepth|XpmVisual|XpmColorSymbols; #endif #ifndef DZEN_XFT if(!dzen.font.set){ gcv.font = dzen.font.xfont->fid; XChangeGC(dzen.dpy, dzen.tgc, GCFont, &gcv); } #endif cur_fnt = &dzen.font; if( lnr != -1 && (lnr + dzen.slave_win.first_line_vis >= dzen.slave_win.tcnt)) { XCopyArea(dzen.dpy, pm, dzen.slave_win.drawable[lnr], dzen.gc, 0, 0, px, dzen.line_height, xorig[LNR2WINDOW(lnr)], 0); XFreePixmap(dzen.dpy, pm); return NULL; } } linep = line; while(1) { if(*linep == ESC_CHAR || *linep == '\0') { lbuf[j] = '\0'; /* clear _lock_x at EOL so final width is correct */ if(*linep=='\0') pos_is_fixed=0; if(nodraw) { strcat(rbuf, lbuf); } else { if(t != -1 && tval) { switch(t) { case icon: if(MAX_ICON_CACHE && (ip=search_icon_cache(tval)) != -1) { int y; XCopyArea(dzen.dpy, icons[ip].p, pm, dzen.tgc, 0, 0, icons[ip].w, icons[ip].h, px, y=(set_posy ? py : (dzen.line_height >= (signed)icons[ip].h ? (dzen.line_height - icons[ip].h)/2 : 0))); px += !pos_is_fixed ? icons[ip].w : 0; max_y = MAX(max_y, y+icons[ip].h); } else { int y; if(XReadBitmapFile(dzen.dpy, pm, tval, &bm_w, &bm_h, &bm, &bm_xh, &bm_yh) == BitmapSuccess && (h/2 + px + (signed)bm_w < dzen.w)) { setcolor(&pm, px, bm_w, lastfg, lastbg, reverse, nobg); XCopyPlane(dzen.dpy, bm, pm, dzen.tgc, 0, 0, bm_w, bm_h, px, y=(set_posy ? py : (dzen.line_height >= (int)bm_h ? (dzen.line_height - (int)bm_h)/2 : 0)), 1); XFreePixmap(dzen.dpy, bm); px += !pos_is_fixed ? bm_w : 0; max_y = MAX(max_y, y+bm_h); } #ifdef DZEN_XPM else if(XpmReadFileToPixmap(dzen.dpy, dzen.title_win.win, tval, &xpm_pm, NULL, &xpma) == XpmSuccess) { setcolor(&pm, px, xpma.width, lastfg, lastbg, reverse, nobg); if(MAX_ICON_CACHE) cache_icon(tval, xpm_pm, xpma.width, xpma.height); XCopyArea(dzen.dpy, xpm_pm, pm, dzen.tgc, 0, 0, xpma.width, xpma.height, px, y=(set_posy ? py : (dzen.line_height >= (int)xpma.height ? (dzen.line_height - (int)xpma.height)/2 : 0))); px += !pos_is_fixed ? xpma.width : 0; max_y = MAX(max_y, y+xpma.height); /* freed by cache_icon() */ //XFreePixmap(dzen.dpy, xpm_pm); free_xpm_attrib = 1; } #endif } break; case rect: get_rect_vals(tval, &rectw, &recth, &rectx, &recty); recth = recth > dzen.line_height ? dzen.line_height : recth; if(set_posy) py += recty; recty = recty == 0 ? (dzen.line_height - recth)/2 : (dzen.line_height - recth)/2 + recty; px += !pos_is_fixed ? rectx : 0; setcolor(&pm, px, rectw, lastfg, lastbg, reverse, nobg); XFillRectangle(dzen.dpy, pm, dzen.tgc, px, set_posy ? py : ((int)recty < 0 ? dzen.line_height + recty : recty), rectw, recth); px += !pos_is_fixed ? rectw : 0; break; case recto: get_rect_vals(tval, &rectw, &recth, &rectx, &recty); if (!rectw) break; recth = recth > dzen.line_height ? dzen.line_height-2 : recth-1; if(set_posy) py += recty; recty = recty == 0 ? (dzen.line_height - recth)/2 : (dzen.line_height - recth)/2 + recty; px = (rectx == 0) ? px : rectx+px; /* prevent from stairs effect when rounding recty */ if (!((dzen.line_height - recth) % 2)) recty--; setcolor(&pm, px, rectw, lastfg, lastbg, reverse, nobg); XDrawRectangle(dzen.dpy, pm, dzen.tgc, px, set_posy ? py : ((int)recty<0 ? dzen.line_height + recty : recty), rectw-1, recth); px += !pos_is_fixed ? rectw : 0; break; case circle: rectx = get_circle_vals(tval, &rectw, &recth); setcolor(&pm, px, rectw, lastfg, lastbg, reverse, nobg); XFillArc(dzen.dpy, pm, dzen.tgc, px, set_posy ? py :(dzen.line_height - rectw)/2, rectw, rectw, 90*64, rectx>1?recth*64:64*360); px += !pos_is_fixed ? rectw : 0; break; case circleo: rectx = get_circle_vals(tval, &rectw, &recth); setcolor(&pm, px, rectw, lastfg, lastbg, reverse, nobg); XDrawArc(dzen.dpy, pm, dzen.tgc, px, set_posy ? py : (dzen.line_height - rectw)/2, rectw, rectw, 90*64, rectx>1?recth*64:64*360); px += !pos_is_fixed ? rectw : 0; break; case pos: if(tval[0]) { int r=0; r = get_pos_vals(tval, &n_posx, &n_posy); if( (r == 1 && !set_posy)) set_posy=0; else if (r == 5) { switch(n_posx) { case LOCK_X: pos_is_fixed = 1; break; case UNLOCK_X: pos_is_fixed = 0; break; case LEFT: px = 0; break; case RIGHT: px = dzen.w; break; case CENTER: px = dzen.w/2; break; case BOTTOM: set_posy = 1; py = dzen.line_height; break; case TOP: set_posy = 1; py = 0; break; } } else set_posy=1; if(r != 2) px = px+n_posx<0? 0 : px + n_posx; if(r != 1) py += n_posy; } else { set_posy = 0; py = (dzen.line_height - dzen.font.height) / 2; } break; case abspos: if(tval[0]) { int r=0; if( (r=get_pos_vals(tval, &n_posx, &n_posy)) == 1 && !set_posy) set_posy=0; else set_posy=1; n_posx = n_posx < 0 ? n_posx*-1 : n_posx; if(r != 2) px = n_posx; if(r != 1) py = n_posy; } else { set_posy = 0; py = (dzen.line_height - dzen.font.height) / 2; } break; case ibg: nobg = atoi(tval); break; case bg: lastbg = tval[0] ? (unsigned)getcolor(tval) : dzen.norm[ColBG]; #ifdef DZEN_XFT if(xftcs_bgf) free(xftcs_bg); if(tval[0]) { xftcs_bg = estrdup(tval); xftcs_bgf = 1; } else { xftcs_bg = (char *)dzen.bg; xftcs_bgf = 0; } #endif break; case fg: lastfg = tval[0] ? (unsigned)getcolor(tval) : dzen.norm[ColFG]; XSetForeground(dzen.dpy, dzen.tgc, lastfg); #ifdef DZEN_XFT if(tval[0]) { xftcs = estrdup(tval); xftcs_f = 1; } else { xftcs = (char *)dzen.fg; xftcs_f = 0; } #endif break; case fn: if(tval[0]) { #ifndef DZEN_XFT if(!strncmp(tval, "dfnt", 4)) { cur_fnt = &(dzen.fnpl[atoi(tval+4)]); if(!cur_fnt->set) { gcv.font = cur_fnt->xfont->fid; XChangeGC(dzen.dpy, dzen.tgc, GCFont, &gcv); } } else #endif setfont(tval); } else { cur_fnt = &dzen.font; #ifndef DZEN_XFT if(!cur_fnt->set){ gcv.font = cur_fnt->xfont->fid; XChangeGC(dzen.dpy, dzen.tgc, GCFont, &gcv); } #else setfont(dzen.fnt ? dzen.fnt : FONT); #endif } py = set_posy ? py : (dzen.line_height - cur_fnt->height) / 2; font_was_set = 1; break; case ca: { sens_w *w = &window_sens[LNR2WINDOW(lnr)]; if(tval[0]) { click_a *area = &((*w).sens_areas[(*w).sens_areas_cnt]); if((*w).sens_areas_cnt < MAX_CLICKABLE_AREAS) { get_sens_area(tval, &(*area).button, LNR2WINDOW(lnr)*MAX_CLICKABLE_AREAS+(*w).sens_areas_cnt); (*area).start_x = px; (*area).start_y = py; (*area).end_y = py; max_y = py; (*area).active = 0; if(lnr == -1) { (*area).win = dzen.title_win.win; } else { (*area).win = dzen.slave_win.line[lnr]; } (*w).sens_areas_cnt++; } } else { //find most recent unclosed area for(i = (*w).sens_areas_cnt - 1; i >= 0; i--) if(!(*w).sens_areas[i].active) break; if(i >= 0 && i < MAX_CLICKABLE_AREAS) { (*w).sens_areas[i].end_x = px; (*w).sens_areas[i].end_y = max_y; (*w).sens_areas[i].active = 1; } } } break; case ba: if(tval[0]) get_block_align_vals(tval, &block_align, &block_width); else block_align=block_width=-1; break; } free(tval); } /* check if text is longer than window's width */ tw = textnw(cur_fnt, lbuf, strlen(lbuf)); while((((tw + px) > (dzen.w)) || (block_align!=-1 && tw>block_width)) && j>=0) { lbuf[--j] = '\0'; tw = textnw(cur_fnt, lbuf, strlen(lbuf)); } opx = px; /* draw background for block */ if(block_align!=-1 && !nobg) { setcolor(&pm, px, rectw, lastbg, lastbg, 0, nobg); XFillRectangle(dzen.dpy, pm, dzen.tgc, px, 0, block_width, dzen.line_height); } if(block_align==ALIGNRIGHT) px += (block_width - tw); else if(block_align==ALIGNCENTER) px += (block_width/2) - (tw/2); if(!nobg) setcolor(&pm, px, tw, lastfg, lastbg, reverse, nobg); #ifndef DZEN_XFT if(cur_fnt->set) XmbDrawString(dzen.dpy, pm, cur_fnt->set, dzen.tgc, px, py + cur_fnt->ascent, lbuf, strlen(lbuf)); else XDrawString(dzen.dpy, pm, dzen.tgc, px, py+dzen.font.ascent, lbuf, strlen(lbuf)); #else if(reverse) { XftColorAllocName(dzen.dpy, DefaultVisual(dzen.dpy, dzen.screen), DefaultColormap(dzen.dpy, dzen.screen), xftcs_bg, &xftc); } else { XftColorAllocName(dzen.dpy, DefaultVisual(dzen.dpy, dzen.screen), DefaultColormap(dzen.dpy, dzen.screen), xftcs, &xftc); } XftDrawStringUtf8(xftd, &xftc, cur_fnt->xftfont, px, py + dzen.font.xftfont->ascent, (const FcChar8 *)lbuf, strlen(lbuf)); if(xftcs_f) { free(xftcs); xftcs_f = 0; } if(xftcs_bgf) { free(xftcs_bg); xftcs_bgf = 0; } #endif max_y = MAX(max_y, py+dzen.font.height); if(block_align==-1) { if(!pos_is_fixed || *linep =='\0') px += tw; } else { if(pos_is_fixed) px = opx; else px = opx+block_width; } block_align=block_width=-1; } if(*linep=='\0') break; j=0; t=-1; tval=NULL; next_pos = get_token(linep, &t, &tval); linep += next_pos; /* ^^ escapes */ if(next_pos == 0) lbuf[j++] = *linep++; } else lbuf[j++] = *linep; linep++; } if(!nodraw) { /* expand/shrink dynamically */ if(dzen.title_win.expand && lnr == -1){ i = px; switch(dzen.title_win.expand) { case left: /* grow left end */ otx = dzen.title_win.x_right_corner - i > dzen.title_win.x ? dzen.title_win.x_right_corner - i : dzen.title_win.x; XMoveResizeWindow(dzen.dpy, dzen.title_win.win, otx, dzen.title_win.y, px, dzen.line_height); break; case right: XResizeWindow(dzen.dpy, dzen.title_win.win, px, dzen.line_height); break; } } else { if(align == ALIGNLEFT) xorig[LNR2WINDOW(lnr)] = 0; if(align == ALIGNCENTER) { xorig[LNR2WINDOW(lnr)] = (lnr != -1) ? (dzen.slave_win.width - px)/2 : (dzen.title_win.width - px)/2; } else if(align == ALIGNRIGHT) { xorig[LNR2WINDOW(lnr)] = (lnr != -1) ? (dzen.slave_win.width - px) : (dzen.title_win.width - px); } } if(lnr != -1) { XCopyArea(dzen.dpy, pm, dzen.slave_win.drawable[lnr], dzen.gc, 0, 0, dzen.w, dzen.line_height, xorig[LNR2WINDOW(lnr)], 0); } else { XCopyArea(dzen.dpy, pm, dzen.title_win.drawable, dzen.gc, 0, 0, dzen.w, dzen.line_height, xorig[LNR2WINDOW(lnr)], 0); } XFreePixmap(dzen.dpy, pm); /* reset font to default */ if(font_was_set) setfont(dzen.fnt ? dzen.fnt : FONT); #ifdef DZEN_XPM if(free_xpm_attrib) { XFreeColors(dzen.dpy, xpma.colormap, xpma.pixels, xpma.npixels, xpma.depth); XpmFreeAttributes(&xpma); } #endif #ifdef DZEN_XFT XftDrawDestroy(xftd); #endif } return nodraw ? rbuf : NULL; }
int main(int argc, char* argv[]) { int sockfd, oldsockfd, portno, n; socklen_t clilen; struct sockaddr_in serv_addr, cli_addr; struct hostent *server; pthread_t recv_thread; Colormap map; Display* display; int screen_num; Window win; unsigned int display_width, display_height; unsigned int width, height; char *display_name = getenv("DISPLAY"); GC gc, his_gc, refresh_gc; if(argc == 2) { // We are server sending = 1; if(argc < 2) { fprintf(stderr,"ERROR, no port provided\n"); exit(1); } oldsockfd = socket(AF_INET, SOCK_STREAM, 0); if(oldsockfd < 0) error("ERROR opening socket"); bzero((char *) &serv_addr, sizeof(serv_addr)); portno = atoi(argv[1]); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = INADDR_ANY; serv_addr.sin_port = htons(portno); int on = 1; if(setsockopt(oldsockfd, SOL_SOCKET, SO_REUSEADDR, (char*)&on, sizeof(on)) < 0) error("ERROR on sockopt"); if(bind(oldsockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) error("ERROR on binding"); listen(oldsockfd,5); clilen = sizeof(cli_addr); sockfd = accept(oldsockfd, (struct sockaddr *) &cli_addr, &clilen); if (sockfd < 0) error("ERROR on accept"); } else if(argc == 3) { // We are client sending = 1; portno = atoi(argv[2]); sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd < 0) error("ERROR opening socket"); server = gethostbyname(argv[1]); if(server == NULL) { fprintf(stderr,"ERROR, no such host\n"); exit(0); } bzero((char *) &serv_addr, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; bcopy((char *)(server->h_addr), (char *)(&serv_addr.sin_addr.s_addr), server->h_length); serv_addr.sin_port = htons(portno); if (connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0) error("ERROR connecting"); } else { server = 0; } display = XOpenDisplay(display_name); if (display == NULL) { fprintf(stderr, "%s: cannot connect to X server '%s'\n", argv[0], display_name); exit(1); } screen_num = DefaultScreen(display); display_width = DisplayWidth(display, screen_num); display_height = DisplayHeight(display, screen_num); width = (display_width / 3); height = (display_height / 3); Atom wm_delete; win = create_simple_window(display, &wm_delete, width, height, 0, 0); XGCValues values; values.graphics_exposures = 0; gc = create_gc(display, win); his_gc = create_gc(display, win); refresh_gc = XCreateGC(display, win, GCGraphicsExposures, &values); XSetForeground(display, refresh_gc, WhitePixel(display, screen_num)); XSetBackground(display, refresh_gc, WhitePixel(display, screen_num)); map = DefaultColormap(display, 0); XParseColor(display, map, "#FFFFFF", &cols[0]); XAllocColor(display, map, &cols[0]); XParseColor(display, map, "#000000", &cols[1]); XAllocColor(display, map, &cols[1]); XParseColor(display, map, "#FF0000", &cols[2]); XAllocColor(display, map, &cols[2]); XParseColor(display, map, "#00FF00", &cols[3]); XAllocColor(display, map, &cols[3]); XParseColor(display, map, "#0000FF", &cols[4]); XAllocColor(display, map, &cols[4]); XParseColor(display, map, "#FFFF00", &cols[5]); XAllocColor(display, map, &cols[5]); XParseColor(display, map, "#FF00FF", &cols[6]); XAllocColor(display, map, &cols[6]); XParseColor(display, map, "#00FFFF", &cols[7]); XAllocColor(display, map, &cols[7]); XParseColor(display, map, "#999999", &cols[8]); XAllocColor(display, map, &cols[8]); XParseColor(display, map, "#666666", &cols[9]); XAllocColor(display, map, &cols[9]); set_title(display, win); back_buffer = XCreatePixmap(display, win, MAX_WIDTH, MAX_HEIGHT, DefaultDepth(display, screen_num)); XFillRectangle(display, back_buffer, refresh_gc, 0, 0, MAX_WIDTH, MAX_HEIGHT); if(sending) { recv_info_t info; info.display = display; info.window = win; info.gc = gc; info.his_gc = his_gc; info.refresh_gc = refresh_gc; info.sockfd = sockfd; pthread_create(&recv_thread, NULL, recv_line, &info); } XSelectInput(display, win, ExposureMask | KeyPressMask | ButtonPressMask | Button1MotionMask | StructureNotifyMask); XEvent an_event; while(1) { XNextEvent(display, &an_event); switch(an_event.type) { case ClientMessage: if(an_event.xclient.data.l[0] == wm_delete) quitme(display, gc, his_gc, refresh_gc, sockfd, 0); break; case Expose: handle_expose(display, refresh_gc, (XExposeEvent*)&an_event.xexpose); break; case ConfigureNotify: width = an_event.xconfigure.width; height = an_event.xconfigure.height; break; case ButtonPress: handle_button_down(display, gc, (XButtonEvent*)&an_event.xbutton, width, height); break; case MotionNotify: handle_drag(display, gc, (XButtonEvent*)&an_event.xbutton, width, height, sockfd); break; case KeyPress: handle_key(display, win, gc, his_gc, refresh_gc, map, (XKeyEvent*)&an_event.xkey, sockfd); break; default: break; } } quitme(display, gc, his_gc, refresh_gc, sockfd, 0); }
PP_Resource ppb_graphics3d_create(PP_Instance instance, PP_Resource share_context, const int32_t attrib_list[]) { struct pp_instance_s *pp_i = tables_get_pp_instance(instance); if (!pp_i) { trace_error("%s, bad instance\n", __func__); return 0; } PP_Resource context = pp_resource_allocate(PP_RESOURCE_GRAPHICS3D, pp_i); struct pp_graphics3d_s *g3d = pp_resource_acquire(context, PP_RESOURCE_GRAPHICS3D); if (!g3d) { trace_error("%s, can't create context\n", __func__); return 0; } int attrib_len = 0; while (attrib_list[attrib_len] != PP_GRAPHICS3DATTRIB_NONE) { attrib_len += 2; } attrib_len ++; EGLint *egl_attribute_list = calloc(attrib_len + 3 * 2, sizeof(EGLint)); int done = 0, k1 = 0, k2 = 0; egl_attribute_list[k2++] = EGL_SURFACE_TYPE; egl_attribute_list[k2++] = EGL_PIXMAP_BIT | EGL_WINDOW_BIT; egl_attribute_list[k2++] = EGL_RENDERABLE_TYPE; egl_attribute_list[k2++] = EGL_OPENGL_ES2_BIT; while (!done) { switch (attrib_list[k1]) { case PP_GRAPHICS3DATTRIB_HEIGHT: g3d->height = attrib_list[k1 + 1]; k1 += 2; break; case PP_GRAPHICS3DATTRIB_WIDTH: g3d->width = attrib_list[k1 + 1]; k1 += 2; break; case PP_GRAPHICS3DATTRIB_GPU_PREFERENCE: case PP_GRAPHICS3DATTRIB_SWAP_BEHAVIOR: // TODO: save these values k1 += 2; break; case PP_GRAPHICS3DATTRIB_NONE: egl_attribute_list[k2++] = EGL_NONE; done = 1; break; case PP_GRAPHICS3DATTRIB_ALPHA_SIZE: egl_attribute_list[k2++] = EGL_ALPHA_SIZE; egl_attribute_list[k2++] = attrib_list[k1 + 1]; k1 += 2; break; case PP_GRAPHICS3DATTRIB_BLUE_SIZE: egl_attribute_list[k2++] = EGL_BLUE_SIZE; egl_attribute_list[k2++] = attrib_list[k1 + 1]; k1 += 2; break; case PP_GRAPHICS3DATTRIB_GREEN_SIZE: egl_attribute_list[k2++] = EGL_GREEN_SIZE; egl_attribute_list[k2++] = attrib_list[k1 + 1]; k1 += 2; break; case PP_GRAPHICS3DATTRIB_RED_SIZE: egl_attribute_list[k2++] = EGL_RED_SIZE; egl_attribute_list[k2++] = attrib_list[k1 + 1]; k1 += 2; break; case PP_GRAPHICS3DATTRIB_DEPTH_SIZE: egl_attribute_list[k2++] = EGL_DEPTH_SIZE; egl_attribute_list[k2++] = attrib_list[k1 + 1]; k1 += 2; break; case PP_GRAPHICS3DATTRIB_STENCIL_SIZE: egl_attribute_list[k2++] = EGL_STENCIL_SIZE; egl_attribute_list[k2++] = attrib_list[k1 + 1]; k1 += 2; break; case PP_GRAPHICS3DATTRIB_SAMPLES: egl_attribute_list[k2++] = EGL_SAMPLES; egl_attribute_list[k2++] = attrib_list[k1 + 1]; k1 += 2; break; case PP_GRAPHICS3DATTRIB_SAMPLE_BUFFERS: egl_attribute_list[k2++] = EGL_SAMPLE_BUFFERS; egl_attribute_list[k2++] = attrib_list[k1 + 1]; k1 += 2; break; default: // skip unknown attribute trace_error("%s, unknown attribute 0x%x\n", __func__, attrib_list[k1]); k1 += 1; break; } } pthread_mutex_lock(&display.lock); int nconfigs = 0; EGLBoolean ret = eglChooseConfig(display.egl, egl_attribute_list, &g3d->egl_config, 1, &nconfigs); free(egl_attribute_list); if (!ret) { trace_error("%s, eglChooseConfig returned FALSE\n", __func__); goto err; } if (nconfigs != 1) { trace_error("%s, eglChooseConfig returned %d configs, expected 1\n", __func__, nconfigs); goto err; } // TODO: support shared_context EGLint ctxattr[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; g3d->glc = eglCreateContext(display.egl, g3d->egl_config, EGL_NO_CONTEXT, ctxattr); if (g3d->glc == EGL_NO_CONTEXT) { trace_error("%s, eglCreateContext returned EGL_NO_CONTEXT\n", __func__); goto err; } g3d->pixmap = XCreatePixmap(display.x, DefaultRootWindow(display.x), g3d->width, g3d->height, DefaultDepth(display.x, 0)); g3d->egl_surf = eglCreatePixmapSurface(display.egl, g3d->egl_config, g3d->pixmap, NULL); if (g3d->egl_surf == EGL_NO_SURFACE) { trace_error("%s, failed to create EGL pixmap surface\n", __func__); goto err; } ret = eglMakeCurrent(display.egl, g3d->egl_surf, g3d->egl_surf, g3d->glc); if (!ret) { trace_error("%s, eglMakeCurrent failed\n", __func__); goto err; } // clear surface glClearColor(0.0, 0.0, 0.0, 1.0); glClear(GL_COLOR_BUFFER_BIT); if (pp_i->is_transparent) { // create texture for plugin content glGenTextures(1, &g3d->tex_front); glBindTexture(GL_TEXTURE_2D, g3d->tex_front); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); if (create_presentation_egl_context(g3d) != 0) { trace_error("%s, can't create EGL context for transparency processing\n", __func__); goto err; } } eglMakeCurrent(display.egl, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); g3d->sub_maps = g_hash_table_new(g_direct_hash, g_direct_equal); pthread_mutex_unlock(&display.lock); pp_resource_release(context); return context; err: pthread_mutex_unlock(&display.lock); pp_resource_release(context); pp_resource_expunge(context); return 0; }
void init_x(void) { XGCValues xgcv; XFontStruct *fontinfo; int i; dpy=XOpenDisplay(NULL); if (dpy==NULL) { fprintf(stderr,"Could not open display; is the DISPLAY variable set correctly?\n"); exit(1); } scr=DefaultScreen(dpy); width=900; height=600; ScreenWidth=width; ScreenHeight=height; vp.x2=width-1; vp.y2=height-1; // create our window w=XCreateWindow(dpy,RootWindow(dpy,scr),-1,-1, width, height, 0, CopyFromParent, InputOutput, CopyFromParent, 0, NULL); XMapWindow(dpy,w); XStoreName(dpy,w,"puff"); // create a background pixmap, that we're actually going to use for everything, because then the xserver takes care of redrawing the window when it is uncovered XGetWindowAttributes(dpy,w,&wa); pm=XCreatePixmap(dpy, RootWindow(dpy,scr),wa.width,wa.height,wa.depth); XSetWindowBackgroundPixmap(dpy,w,pm); // tell the window manager that we don't want to be resized to less than 640x480 (the old VGA resolution) XSizeHints* win_size_hints = XAllocSizeHints(); win_size_hints->flags = PMinSize; win_size_hints->min_width = 640; win_size_hints->min_height = 480; XSetWMNormalHints(dpy, w, win_size_hints); XFree(win_size_hints); // allocate 16 memory places to temporarily store pieces of the drawing for (i=0;i<16;i++) boxes[i]=XCreatePixmap(dpy, RootWindow(dpy,scr),32,32,wa.depth); // create several graphics contexts xgcv.foreground=WhitePixel(dpy,scr); xgcv.background=BlackPixel(dpy,scr); xgcv.function=GXcopy; gc = XCreateGC(dpy, w, GCForeground|GCBackground|GCFunction, &xgcv); XSetLineAttributes(dpy, gc, 1, LineSolid, CapRound, JoinRound); xgcv.foreground=BlackPixel(dpy,scr); xgcv.background=WhitePixel(dpy,scr); xgcv.function=GXcopy; gcclear = XCreateGC(dpy, w, GCForeground|GCBackground|GCFunction, &xgcv); gcpixel = XCreateGC(dpy, w, 0, &xgcv); xgcv.foreground=WhitePixel(dpy,scr); xgcv.background=BlackPixel(dpy,scr); xgcv.function=GXcopy; gctext = XCreateGC(dpy, w, GCForeground|GCBackground|GCFunction, &xgcv); xgcv.background=WhitePixel(dpy,scr); xgcv.foreground=BlackPixel(dpy,scr); xgcv.function=GXcopy; gcfill = XCreateGC(dpy, w, GCForeground|GCBackground|GCFunction, &xgcv); XSetLineAttributes(dpy, gcfill, 1000, LineSolid, CapRound, JoinRound); // very thick line, see FloodFill() for explanation // clear the screen XFillRectangle(dpy, pm, gcfill, 0,0,ScreenWidth,ScreenHeight); XClearWindow(dpy,w); // load an 8x13 font; the VGA font on which the partitioning of the screen is based is an 8x14 font fontinfo=XLoadQueryFont(dpy,"8x13"); XSetFont(dpy,gctext,fontinfo->fid); XSetFont(dpy,gc,fontinfo->fid); fontyoffs=fontinfo->ascent; // allocate a set of colours corresponding to those of the VGA mode originally used by puff getpascalcolours(); XSelectInput(dpy,w,KeyPressMask|KeyReleaseMask|StructureNotifyMask); XFlush(dpy); }
/** * Creates a Pixmap and GLXPixmap with tex_data as the contents. */ static GLXPixmap create_pixmap(GLenum format) { static const int rgb_fb_config_attribs[] = { GLX_RENDER_TYPE, GLX_RGBA_BIT, GLX_RED_SIZE, 8, GLX_GREEN_SIZE, 8, GLX_BLUE_SIZE, 8, GLX_ALPHA_SIZE, 0, GLX_DRAWABLE_TYPE, GLX_PIXMAP_BIT, GLX_BIND_TO_TEXTURE_RGB_EXT, 1, None }; static const int rgba_fb_config_attribs[] = { GLX_RENDER_TYPE, GLX_RGBA_BIT, GLX_RED_SIZE, 8, GLX_GREEN_SIZE, 8, GLX_BLUE_SIZE, 8, GLX_ALPHA_SIZE, 8, GLX_DRAWABLE_TYPE, GLX_PIXMAP_BIT, GLX_BIND_TO_TEXTURE_RGBA_EXT, 1, None }; static const int rgb_pixmap_attribs[] = { GLX_TEXTURE_TARGET_EXT, GLX_TEXTURE_2D_EXT, GLX_TEXTURE_FORMAT_EXT, GLX_TEXTURE_FORMAT_RGB_EXT, None }; static const int rgba_pixmap_attribs[] = { GLX_TEXTURE_TARGET_EXT, GLX_TEXTURE_2D_EXT, GLX_TEXTURE_FORMAT_EXT, GLX_TEXTURE_FORMAT_RGBA_EXT, None }; static const int *fb_config_attribs, *pixmap_attribs; GLXFBConfig *fb_configs; GLXFBConfig fb_config; int n_fb_configs; Pixmap pixmap; GLXPixmap glx_pixmap; XVisualInfo *vis; XRenderPictFormat *render_format; Picture picture; if (format == GL_RGBA) { fb_config_attribs = rgba_fb_config_attribs; pixmap_attribs = rgba_pixmap_attribs; render_format = XRenderFindStandardFormat(dpy, PictStandardARGB32); } else { fb_config_attribs = rgb_fb_config_attribs; pixmap_attribs = rgb_pixmap_attribs; render_format = XRenderFindStandardFormat(dpy, PictStandardRGB24); } fb_configs = glXChooseFBConfig(dpy, DefaultScreen(dpy), fb_config_attribs, &n_fb_configs); if (fb_configs == NULL || n_fb_configs < 1) { fprintf(stderr, "No %s TFP FB config found\n", format == GL_RGBA ? "RGBA" : "RGB"); return None; } fb_config = fb_configs[n_fb_configs - 1]; pixmap = XCreatePixmap(dpy, RootWindow(dpy, DefaultScreen(dpy)), 2, 2, render_format->depth); picture = XRenderCreatePicture(dpy, pixmap, render_format, 0, NULL); glx_pixmap = glXCreatePixmap(dpy, fb_config, pixmap, pixmap_attribs); vis = glXGetVisualFromFBConfig(dpy, fb_config); set_pixel(dpy, picture, 0, 0, tex_data[0]); set_pixel(dpy, picture, 1, 0, tex_data[1]); set_pixel(dpy, picture, 0, 1, tex_data[2]); set_pixel(dpy, picture, 1, 1, tex_data[3]); XFree(fb_configs); XFree(vis); return glx_pixmap; }
/** * Create a pbuffer. * * This function is used to implement \c glXCreatePbuffer and * \c glXCreateGLXPbufferSGIX. * * \note * This function dynamically determines whether to use the SGIX_pbuffer * version of the protocol or the GLX 1.3 version of the protocol. */ static GLXDrawable CreatePbuffer(Display * dpy, struct glx_config *config, unsigned int width, unsigned int height, const int *attrib_list, GLboolean size_in_attribs) { struct glx_display *priv = __glXInitialize(dpy); GLXDrawable id = 0; CARD32 *data; CARD8 opcode; unsigned int i; Pixmap pixmap; GLboolean glx_1_3 = GL_FALSE; i = 0; if (attrib_list) { while (attrib_list[i * 2]) i++; } opcode = __glXSetupForCommand(dpy); if (!opcode) return None; LockDisplay(dpy); id = XAllocID(dpy); if ((priv->majorVersion > 1) || (priv->minorVersion >= 3)) { xGLXCreatePbufferReq *req; unsigned int extra = (size_in_attribs) ? 0 : 2; glx_1_3 = GL_TRUE; GetReqExtra(GLXCreatePbuffer, (8 * (i + extra)), req); data = (CARD32 *) (req + 1); req->reqType = opcode; req->glxCode = X_GLXCreatePbuffer; req->screen = config->screen; req->fbconfig = config->fbconfigID; req->pbuffer = id; req->numAttribs = i + extra; if (!size_in_attribs) { data[(2 * i) + 0] = GLX_PBUFFER_WIDTH; data[(2 * i) + 1] = width; data[(2 * i) + 2] = GLX_PBUFFER_HEIGHT; data[(2 * i) + 3] = height; data += 4; } } else { xGLXVendorPrivateReq *vpreq; GetReqExtra(GLXVendorPrivate, 20 + (8 * i), vpreq); data = (CARD32 *) (vpreq + 1); vpreq->reqType = opcode; vpreq->glxCode = X_GLXVendorPrivate; vpreq->vendorCode = X_GLXvop_CreateGLXPbufferSGIX; data[0] = config->screen; data[1] = config->fbconfigID; data[2] = id; data[3] = width; data[4] = height; data += 5; } (void) memcpy(data, attrib_list, sizeof(CARD32) * 2 * i); UnlockDisplay(dpy); SyncHandle(); pixmap = XCreatePixmap(dpy, RootWindow(dpy, config->screen), width, height, config->rgbBits); if (!CreateDRIDrawable(dpy, config, pixmap, id, attrib_list, i)) { CARD32 o = glx_1_3 ? X_GLXDestroyPbuffer : X_GLXvop_DestroyGLXPbufferSGIX; XFreePixmap(dpy, pixmap); protocolDestroyDrawable(dpy, id, o); id = None; } return id; }
/********************************************************************************** * FUNCTIONS **********************************************************************************/ int video_open(PLOT *plot) { struct videodata *plotdata; Display *dpy; Screen *scr; Widget w, mw, m0, m1, m2, m3; int status = SUCCESS; Dimension width, height; int depth; XGCValues values; unsigned long foreground, background; XmString xmstr, xmstr1; Arg args[10]; int n; plot->plotdata = (void *)calloc(1, sizeof(struct videodata)); plotdata = (struct videodata *)plot->plotdata; plotdata->image = (XImage *)calloc(sizeof(XImage), 1); plotdata->framedata = NULL; plotdata->width = 0; plotdata->height = 0; plotdata->ncomps = 0; plotdata->microsecs_per_frame = 0; plotdata->colormap = defaults.colormap; plotdata->framenum = 0; plotdata->loadedframenum = -1; plot->plot_widget = XtVaCreateManagedWidget("video", xmDrawingAreaWidgetClass, plot->panel->panel_container, XmNheight, defaults.video_height, XmNwidth, defaults.width, XmNmarginHeight, 0, XmNmarginWidth, 0, NULL); XtAddCallback(plot->plot_widget, XmNexposeCallback, video_expose_callback, (XtPointer)plot); XtAddCallback(plot->plot_widget, XmNresizeCallback, video_resize_callback, (XtPointer)plot); w = (Widget)plot->plot_widget; dpy = XtDisplay(w); scr = XtScreen(w); XtVaGetValues(w, XmNheight, &height, XmNwidth, &width, XmNdepth, &depth, XmNforeground, &foreground, XmNbackground, &background, NULL); /* ** Get the font; also, calculate the margins for the axes (this depends on the font size!). ** Store these margins for use later (we might start off without axes, and turn them on later. */ plot->ticklblfont = XmFontListCopy(_XmGetDefaultFontList(w, XmLABEL_FONTLIST)); plot->minoffx = 6 + XmStringWidth(plot->ticklblfont, xmstr = XmStringCreateSimple("-32768")); XmStringFree(xmstr); plot->minoffx2 = 0; plot->minoffy = 0; plot->minoffy2 = 6 + XmStringHeight(plot->ticklblfont, xmstr = XmStringCreateSimple("1")); XmStringFree(xmstr); plot->offx = 0; plot->offy = 0; plot->offx2 = 0; plot->offy2 = 0; plot->width = width; plot->height = height; plot->depth = depth; /* ** Allocate our colors. We use the XCC code that is: ** Copyright 1994,1995 John L. Cwikla ** This allows us to work on any visual, etc. The danger is that ** we may not get the exact colors we ask for... meaning that things ** may not really be as we see them. This is unfortunate, but the ** alternative is to not run at all (the old code crashed). So... */ plotdata->ncolors = MIN(SONO_DEFAULT_MAX_COLORS, MIN(XDisplayCells(dpy, XDefaultScreen(dpy)), MAXCOLORS - RESERVED_COLORS)); plotdata->xcc = XCCCreate(dpy, DefaultVisual(dpy, DefaultScreen(dpy)), TRUE, TRUE, XA_RGB_GRAY_MAP, &(plotdata->cmap)); if (XCCGetNumColors(plotdata->xcc) < plotdata->ncolors) { plotdata->ncolors = XCCGetNumColors(plotdata->xcc); printf("Warning. Using only %d colors.\n", plotdata->ncolors); } (*((colormap[plotdata->colormap]).cmap))(dpy, plotdata->ncolors, plotdata->colors, NULL); /* ** Create the Graphics contexts. ** drawing_GC is for the picture itself. inverse_GC is for erasing. mark_GC is for the subregion marks. */ values.font = getFontStruct(plot->ticklblfont)->fid; values.function = GXcopy; values.plane_mask = AllPlanes; values.foreground = foreground; values.background = background; plotdata->drawing_GC = XtGetGC(w, GCFunction | GCPlaneMask | GCForeground | GCBackground | GCFont, &values); values.foreground = background; values.background = background; plotdata->inverse_GC = XtGetGC(w, GCForeground | GCBackground, &values); values.function = GXxor; values.plane_mask = foreground ^ background; values.foreground = 0xffffffff; values.background = 0x0; values.line_style = LineSolid; plotdata->mark_GC = XtGetGC(w, GCFunction | GCPlaneMask | GCForeground | GCBackground | GCLineStyle, &values); plotdata->pixmap = XCreatePixmap(dpy, DefaultRootWindow(dpy), width, height, depth); plotdata->pixmapalloced = TRUE; XFillRectangle(dpy, plotdata->pixmap, plotdata->inverse_GC, 0, 0, width, height); /* ** Create the popup menu ** */ n = 0; XtSetArg(args[n], XmNmenuPost, "<Btn3Down>"); n++; mw = plot->plot_popupmenu_widget = XmCreatePopupMenu(w, "popupmenu", args, n); m0 = XtVaCreateManagedWidget("m0", xmLabelGadgetClass, mw, XmNlabelString, xmstr1 = XmStringCreateSimple("Options"), NULL); XmStringFree(xmstr1); m1 = XtVaCreateManagedWidget("m1", xmSeparatorGadgetClass, mw, NULL); CreateMenuButton(m2, mw, "save", "Save", "Save"); CreateMenuButton(m3, mw, "print", "Print EPS", "Print EPS"); /* ** Register an event handler */ XtAddEventHandler(w, KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | Button1MotionMask | Button2MotionMask, FALSE, (XtEventHandler) video_event_handler, (XtPointer)plot); plot->plot_display = video_display; plot->plot_set = video_set; plot->plot_close = video_close; plot->plot_print = video_print; plot->plot_playmarker = NULL; plot->plot_showvideoframe = video_showvideoframe; plot->plot_clearmarks = NULL; plot->plot_drawstartmark = NULL; plot->plot_drawstopmark = NULL; plot->plot_conv_pixel_to_time = NULL; plot->plot_save = video_save; plot->plot_event_handler = video_event_handler; plot->plot_play = video_play; plotdata->butgrabbed = FALSE; plot->playmark = -1; plot->markx1 = -1; plot->markx2 = -1; plot->group->needpcm = 1; return status; }
void OS_X11::initialize(const VideoMode& p_desired,int p_video_driver,int p_audio_driver) { last_button_state=0; dpad_last[0]=0; dpad_last[1]=0; xmbstring=NULL; event_id=0; x11_window=0; last_click_ms=0; args=OS::get_singleton()->get_cmdline_args(); current_videomode=p_desired; main_loop=NULL; last_timestamp=0; last_mouse_pos_valid=false; last_keyrelease_time=0; if (get_render_thread_mode()==RENDER_SEPARATE_THREAD) { XInitThreads(); } /** XLIB INITIALIZATION **/ x11_display = XOpenDisplay(NULL); char * modifiers = XSetLocaleModifiers ("@im=none"); ERR_FAIL_COND( modifiers == NULL ); xim = XOpenIM (x11_display, NULL, NULL, NULL); if (xim == NULL) { WARN_PRINT("XOpenIM failed"); xim_style=NULL; } else { ::XIMStyles *xim_styles=NULL; xim_style=0; char *imvalret=NULL; imvalret = XGetIMValues(xim, XNQueryInputStyle, &xim_styles, NULL); if (imvalret != NULL || xim_styles == NULL) { fprintf (stderr, "Input method doesn't support any styles\n"); } if (xim_styles) { xim_style = 0; for (int i=0;i<xim_styles->count_styles;i++) { if (xim_styles->supported_styles[i] == (XIMPreeditNothing | XIMStatusNothing)) { xim_style = xim_styles->supported_styles[i]; break; } } XFree (xim_styles); } } /* char* windowid = getenv("GODOT_WINDOWID"); if (windowid) { //freopen("/home/punto/stdout", "w", stdout); //reopen("/home/punto/stderr", "w", stderr); x11_window = atol(windowid); XWindowAttributes xwa; XGetWindowAttributes(x11_display,x11_window,&xwa); current_videomode.width = xwa.width; current_videomode.height = xwa.height; }; */ // maybe contextgl wants to be in charge of creating the window //print_line("def videomode "+itos(current_videomode.width)+","+itos(current_videomode.height)); #if defined(OPENGL_ENABLED) || defined(LEGACYGL_ENABLED) context_gl = memnew( ContextGL_X11( x11_display, x11_window,current_videomode, false ) ); context_gl->initialize(); if (p_video_driver == 0) { rasterizer = memnew( RasterizerGLES2 ); } else { rasterizer = memnew( RasterizerGLES1 ); }; #endif visual_server = memnew( VisualServerRaster(rasterizer) ); if (get_render_thread_mode()!=RENDER_THREAD_UNSAFE) { visual_server =memnew(VisualServerWrapMT(visual_server,get_render_thread_mode()==RENDER_SEPARATE_THREAD)); } AudioDriverManagerSW::get_driver(p_audio_driver)->set_singleton(); if (AudioDriverManagerSW::get_driver(p_audio_driver)->init()!=OK) { ERR_PRINT("Initializing audio failed."); } sample_manager = memnew( SampleManagerMallocSW ); audio_server = memnew( AudioServerSW(sample_manager) ); audio_server->init(); spatial_sound_server = memnew( SpatialSoundServerSW ); spatial_sound_server->init(); spatial_sound_2d_server = memnew( SpatialSound2DServerSW ); spatial_sound_2d_server->init(); ERR_FAIL_COND(!visual_server); ERR_FAIL_COND(x11_window==0); XSetWindowAttributes new_attr; new_attr.event_mask=KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | EnterWindowMask | LeaveWindowMask | PointerMotionMask | Button1MotionMask | Button2MotionMask | Button3MotionMask | Button4MotionMask | Button5MotionMask | ButtonMotionMask | KeymapStateMask | ExposureMask | VisibilityChangeMask | StructureNotifyMask | SubstructureNotifyMask | SubstructureRedirectMask | FocusChangeMask | PropertyChangeMask | ColormapChangeMask | OwnerGrabButtonMask; XChangeWindowAttributes(x11_display, x11_window,CWEventMask,&new_attr); wm_delete = XInternAtom(x11_display, "WM_DELETE_WINDOW", true); XSetWMProtocols(x11_display, x11_window, &wm_delete, 1); if (xim && xim_style) { xic = XCreateIC (xim,XNInputStyle, xim_style,XNClientWindow,x11_window,XNFocusWindow, x11_window, (char*)NULL); } else { xic=NULL; WARN_PRINT("XCreateIC couldn't create xic"); } XcursorSetTheme(x11_display,"default"); cursor_size = XcursorGetDefaultSize(x11_display); cursor_theme = XcursorGetTheme(x11_display); if (!cursor_theme) { print_line("not found theme"); cursor_theme="default"; } for(int i=0;i<CURSOR_MAX;i++) { cursors[i]=None; } current_cursor=CURSOR_ARROW; if (cursor_theme) { //print_line("cursor theme: "+String(cursor_theme)); for(int i=0;i<CURSOR_MAX;i++) { static const char *cursor_file[]={ "left_ptr", "xterm", "hand2", "cross", "watch", "left_ptr_watch", "fleur", "hand1", "X_cursor", "sb_v_double_arrow", "sb_h_double_arrow", "size_bdiag", "size_fdiag", "hand1", "sb_v_double_arrow", "sb_h_double_arrow", "question_arrow" }; XcursorImage *img = XcursorLibraryLoadImage(cursor_file[i],cursor_theme,cursor_size); if (img) { cursors[i]=XcursorImageLoadCursor(x11_display,img); //print_line("found cursor: "+String(cursor_file[i])+" id "+itos(cursors[i])); } else { if (OS::is_stdout_verbose()) print_line("failed cursor: "+String(cursor_file[i])); } } } { Pixmap cursormask; XGCValues xgc; GC gc; XColor col; Cursor cursor; cursormask = XCreatePixmap(x11_display, RootWindow(x11_display,DefaultScreen(x11_display)), 1, 1, 1); xgc.function = GXclear; gc = XCreateGC(x11_display, cursormask, GCFunction, &xgc); XFillRectangle(x11_display, cursormask, gc, 0, 0, 1, 1); col.pixel = 0; col.red = 0; col.flags = 4; cursor = XCreatePixmapCursor(x11_display, cursormask, cursormask, &col, &col, 0, 0); XFreePixmap(x11_display, cursormask); XFreeGC(x11_display, gc); if (cursor == None) { ERR_PRINT("FAILED CREATING CURSOR"); } null_cursor=cursor; } set_cursor_shape(CURSOR_BUSY); visual_server->init(); // physics_server = memnew( PhysicsServerSW ); physics_server->init(); physics_2d_server = memnew( Physics2DServerSW ); physics_2d_server->init(); input = memnew( InputDefault ); probe_joystick(); _ensure_data_dir(); net_wm_icon = XInternAtom(x11_display, "_NET_WM_ICON", False); //printf("got map notify\n"); }
void XImlib2Background::SetMultiImage(Imlib_Image image) { Pixmap pmap = None, mask = None; GC gc; XGCValues gcv; XColor xcolor; int w, h, x, y, widthOfScreen, heightOfScreen, screen, depth; char *bgcolor = NULL; Colormap colormap; Display* display; Window rootWindow; string mode; DesktopConfig * dConfig = dynamic_cast<DesktopConfig *>(config); XDesktopContainer * xContainer = dynamic_cast<XDesktopContainer *>(container); display = xContainer->getDisplay(); rootWindow = xContainer->getRootWindow(); screen = DefaultScreen(display); depth = DefaultDepth(display, screen); colormap = DefaultColormap(display, screen); widthOfScreen = xContainer->widthOfScreen(); heightOfScreen = xContainer->heightOfScreen(); mode = dConfig->getModeBackground(); pixmap = XCreatePixmap(display, rootWindow , widthOfScreen, heightOfScreen, depth); string color = dConfig->getColorBackground(); if(color != "None"){ gcv.foreground = gcv.background = BlackPixel(display, screen); bgcolor = (char*)dConfig->getColorBackground().c_str(); if (bgcolor && XParseColor(display, colormap , bgcolor, &xcolor) && XAllocColor(display, colormap, &xcolor)) { gcv.foreground = gcv.background = xcolor.pixel; } } gc = XCreateGC(display, pixmap, (GCForeground | GCBackground), &gcv); if(image){ imlib_context_set_image(image); if (mode == "SCALE") { w = widthOfScreen; h = heightOfScreen; } else if (mode == "MIRROR") { w = imlib_image_get_width() * 2; h = imlib_image_get_height() * 2; } else if (mode == "FIT") { double x_ratio, y_ratio; x_ratio = ((double) widthOfScreen) / ((double) imlib_image_get_width()); y_ratio = ((double) heightOfScreen) / ((double) imlib_image_get_height()); if (x_ratio > y_ratio) { x_ratio = y_ratio; } w = (int) (imlib_image_get_width() * x_ratio); h = (int) (imlib_image_get_height() * x_ratio); } else { w = imlib_image_get_width(); h = imlib_image_get_height(); } if (mode == "SCALE") { XFillRectangle(display, pixmap, gc, 0, 0, w, h); } if (mode == "CENTER" || mode == "FIT") { XFillRectangle(display, pixmap, gc, 0, 0, widthOfScreen, heightOfScreen); x = (widthOfScreen - w) >> 1; y = (heightOfScreen - h) >> 1; } else {
void xsplot ( int *iret ) /************************************************************************ * xsplot * * * * This subroutine increases the pixmap pointer by 1 and creates the * * next pixmap if the incr_pxmCnt is set to TRUE (the default). * * * * xsplot ( iret ) * * * * Input parameters: * * None * * * * Output parameters: * * *iret int Return code * * G_NORMAL = Normal return * * G_NMAXFR = Too many frames * ** * * Log: * * C. Lin/EAI 7/94 Multi-window & Multi-pixmap * * C. Lin/EAI 8/94 Added call to XCLEAR * * C. Lin/EAI 6/97 Use pixmap size, use cwin * * S. Jacobs/NCEP 12/98 Fixed cast of NULL for LINUX * * E. Safford/GSC 02/99 use incr_pxmCnt to control pxm advance * * S. Law/GSC 10/99 added loop changes in gemwindow * * E. Safford/GSC 12/99 update for new xwcmn.h * * S. Law/GSC 01/00 changed curpxm to an array * * S. Law/GSC 08/00 cwin->pixmaps -> cwin->pxms[lp] * * E. Safford/GSC 08/00 fix npxms increment error * ***********************************************************************/ { int ipxm, xwdth, xhght, xdpth, lp, ier; Window_str *cwin; winloop_t *cloop; /*---------------------------------------------------------------------*/ *iret = G_NORMAL; if ( gemwindow[current_window].npxms < MAX_PIXMAP ) { cwin = &(gemwindow[current_window]); lp = cwin->curr_loop; cloop = &(cwin->loop[lp]); ipxm = cwin->curpxm[lp]; if (!cwin->nmap2 && cwin->incr_pxmCnt) { /* * advance the curpxm index */ (cwin->curpxm[lp])++; ipxm = cwin->curpxm[lp]; } xwdth = cloop->pxm_wdth; xhght = cloop->pxm_hght; xdpth = cwin->depth; if (cwin->pxms[lp][ipxm] == (Pixmap) NULL) { cwin->pxms[lp][ipxm] = XCreatePixmap(gemdisplay, root, xwdth, xhght, xdpth); xclrpxm( &ipxm, &ier); } if (cwin->nmap2 || cwin->incr_pxmCnt) { cwin->npxms++; } } else { /* * number of pixmaps exceeds maximum */ *iret = G_NMAXFR; } }
void JXImage::JXImageFromDrawable ( JXDisplay* display, JXColormap* colormap, Drawable source, const JRect& origRect ) { JXImageX(display, colormap); JRect rect = origRect; { Window rootWindow; int x,y; unsigned int w,h, bw, depth; XGetGeometry(*itsDisplay, source, &rootWindow, &x, &y, &w, &h, &bw, &depth); itsDepth = depth; if (rect.IsEmpty()) { SetDimensions(w,h); rect = GetBounds(); } } itsPixmap = XCreatePixmap(*itsDisplay, itsDisplay->GetRootWindow(), GetWidth(), GetHeight(), itsDepth); assert( itsPixmap != None ); if (itsDepth != itsDisplay->GetDepth()) { itsGC = new JXGC(itsDisplay, itsColormap, itsPixmap); assert( itsGC != NULL ); } (GetGC())->CopyPixels(source, rect.left, rect.top, rect.width(), rect.height(), itsPixmap, 0,0); // register the colors that are used in the drawable const JBoolean needRegister = JConvertToBoolean( itsDepth > 1 && !itsColormap->AllColorsPreallocated() ); if (needRegister && itsColormap->GetVisualClass() == DirectColor) { // With DirectColor, there could be just as many colors as pixels, // so we actually waste time (and memory!) by building a list of // X pixel values before converting them to JColorIndices. ConvertToImage(); const JCoordinate w = GetWidth(); const JCoordinate h = GetHeight(); for (JCoordinate y=0; y<=h; y++) { for (JCoordinate x=0; x<=w; x++) { JColorIndex color; const unsigned long xPixel = XGetPixel(itsImage, x,y); itsColormap->AllocateStaticColor(xPixel, &color); RegisterColor(color, kJFalse); } } } else if (needRegister) // using PseudoColor => small # of X pixels { // By building a list of unique X pixel values and then converting // each once, we reduce O(W H (alloc)) to O(W H) + O(P (alloc)), // where W=width, H=height, P=# of distinct pixels in Drawable. // Typically, W*H is much larger than P. Alloc usually requires // a server call. JIndex i; // build boolean array telling which X pixel values are used ConvertToImage(); const JSize maxColorCount = itsColormap->GetMaxColorCount(); char* pixelUsed = new char [ maxColorCount ]; assert( pixelUsed != NULL ); for (i=0; i<maxColorCount; i++) { pixelUsed[i] = 0; } const JCoordinate w = GetWidth(); const JCoordinate h = GetHeight(); for (JCoordinate y=0; y<=h; y++) { for (JCoordinate x=0; x<=w; x++) { const unsigned long xPixel = XGetPixel(itsImage, x,y); assert( xPixel < maxColorCount ); pixelUsed [ xPixel ] = 1; } } // register each X pixel value that is used JColorIndex color; for (i=0; i<maxColorCount; i++) { if (pixelUsed[i]) { itsColormap->AllocateStaticColor(i, &color); RegisterColor(color, kJFalse); } } delete [] pixelUsed; } }
static void setbrushstyle (wmfAPI* API,wmfDC* dc) { wmf_x_t* ddata = WMF_X_GetData (API); wmfBMP* bmp = 0; wmfRGB pixel; wmfBrush* brush = 0; int opacity; int fill_style; U16 i; U16 j; XGCValues values; brush = WMF_DC_BRUSH (dc); values.function = Our_XROPfunction[WMF_DC_ROP (dc) - 1]; if (values.function == GXinvert) { values.function = GXxor; values.foreground = ddata->black; } else { values.foreground = get_color (API,WMF_BRUSH_COLOR (brush)); } values.background = get_color (API,WMF_DC_BACKGROUND (dc)); switch (WMF_BRUSH_STYLE (brush)) { /* TODO: these arrays are convenient but how SEG-safe are they? */ case BS_HATCHED: if (ddata->hatch != None) XFreePixmap (ddata->display,ddata->hatch); ddata->hatch = XCreateBitmapFromData (ddata->display,ddata->root, HatchBrushes[WMF_BRUSH_HATCH (brush)],8,8); fill_style = ((WMF_DC_OPAQUE (dc)) ? FillOpaqueStippled : FillStippled); XSetStipple (ddata->display,ddata->gc,ddata->hatch); break; case BS_DIBPATTERN: setdefaultstyle (API); bmp = WMF_BRUSH_BITMAP (brush); if (ddata->brush != None) { XFreePixmap (ddata->display,ddata->brush); ddata->brush = None; } if (bmp->data == 0) { fill_style = FillSolid; break; } ddata->brush = XCreatePixmap (ddata->display,ddata->root, bmp->width,bmp->height,ddata->depth); if (ddata->brush == None) { fill_style = FillSolid; break; } for (j = 0; j < bmp->height; j++) { for (i = 0; i < bmp->width; i++) { opacity = wmf_ipa_bmp_color (API,bmp,&pixel,i,j); XSetForeground (ddata->display,ddata->gc,get_color (API,&pixel)); XDrawPoint (ddata->display,ddata->brush,ddata->gc,i,j); } } XSetTile (ddata->display,ddata->gc,ddata->brush); fill_style = FillTiled; break; case BS_NULL: case BS_SOLID: case BS_PATTERN: default: fill_style = FillSolid; break; } XSetFillStyle (ddata->display,ddata->gc,fill_style); switch (WMF_DC_POLYFILL (dc)) { case ALTERNATE: values.fill_rule = EvenOddRule; break; case WINDING: values.fill_rule = WindingRule; break; default: values.fill_rule = EvenOddRule; break; } XChangeGC (ddata->display,ddata->gc,GCFunction|GCForeground|GCBackground|GCFillRule,&values); }
static Bool GradientLoader(XawParams *params, Screen *screen, Colormap colormap, int depth, Pixmap *pixmap_return, Pixmap *mask_return, Dimension *width_return, Dimension *height_return) { double ired, igreen, iblue, red, green, blue; XColor start, end, color; XGCValues values; GC gc; double i, inc, x, y, xend, yend; Pixmap pixmap; XawArgVal *argval; int orientation, dimension, steps; char *value; if (XmuCompareISOLatin1(params->name, "vertical") == 0) orientation = VERTICAL; else if (XmuCompareISOLatin1(params->name, "horizontal") == 0) orientation = HORIZONTAL; else return (False); if ((argval = XawFindArgVal(params, "dimension")) != NULL && argval->value) { dimension = atoi(argval->value); if (dimension <= 0) return (False); } else dimension = 50; if ((argval = XawFindArgVal(params, "steps")) != NULL && argval->value) { steps = atoi(argval->value); if (steps <= 0) return (False); } else steps = dimension; steps = XawMin(steps, dimension); value = NULL; if ((argval = XawFindArgVal(params, "start")) != NULL) value = argval->value; if (value && !XAllocNamedColor(DisplayOfScreen(screen), colormap, value, &start, &color)) return (False); else if (!value) { start.pixel = WhitePixelOfScreen(screen); XQueryColor(DisplayOfScreen(screen), colormap, &start); } value = NULL; if ((argval = XawFindArgVal(params, "end")) != NULL) value = argval->value; if (value && !XAllocNamedColor(DisplayOfScreen(screen), colormap, value, &end, &color)) return (False); else if (!value) { end.pixel = BlackPixelOfScreen(screen); XQueryColor(DisplayOfScreen(screen), colormap, &end); } if ((pixmap = XCreatePixmap(DisplayOfScreen(screen), RootWindowOfScreen(screen), orientation == VERTICAL ? 1 : dimension, orientation == VERTICAL ? dimension : 1, depth)) == 0) return (False); ired = (double)(end.red - start.red) / (double)steps; igreen = (double)(end.green - start.green) / (double)steps; iblue = (double)(end.blue - start.blue) / (double)steps; red = color.red = start.red; green = color.green = start.green; blue = color.blue = start.blue; inc = (double)dimension / (double)steps; gc = XCreateGC(DisplayOfScreen(screen), pixmap, 0, &values); x = y = 0.0; if (orientation == VERTICAL) { xend = 1; yend = 0; } else { xend = 0; yend = 1; } color.flags = DoRed | DoGreen | DoBlue; XSetForeground(DisplayOfScreen(screen), gc, start.pixel); for (i = 0.0; i < dimension; i += inc) { if ((int)color.red != (int)red || (int)color.green != (int)green || (int)color.blue != (int)blue) { XFillRectangle(DisplayOfScreen(screen), pixmap, gc, (int)x, (int)y, (unsigned int)xend, (unsigned int)yend); color.red = (unsigned short)red; color.green = (unsigned short)green; color.blue = (unsigned short)blue; if (!XAllocColor(DisplayOfScreen(screen), colormap, &color)) { XFreePixmap(DisplayOfScreen(screen), pixmap); return (False); } XSetForeground(DisplayOfScreen(screen), gc, color.pixel); if (orientation == VERTICAL) y = yend; else x = xend; } red += ired; green += igreen; blue += iblue; if (orientation == VERTICAL) yend += inc; else xend += inc; } XFillRectangle(DisplayOfScreen(screen), pixmap, gc, (int)x, (int)y, (unsigned int)xend, (unsigned int)yend); *pixmap_return = pixmap; *mask_return = None; *width_return = orientation == VERTICAL ? 1 : dimension; *height_return = orientation == VERTICAL ? dimension : 1; XFreeGC(DisplayOfScreen(screen), gc); return (True); }
static int capture(char *dev_name, int x_res, int y_res, int n_frames, char *out_dir) { struct v4l2_format fmt; struct v4l2_buffer buf; struct v4l2_requestbuffers req; enum v4l2_buf_type type; fd_set fds; struct timeval tv; int r, fd = -1; unsigned int i, j, n_buffers; struct buffer *buffers; Display *dpy; Window win; int num_textures = 1; GLuint texture_id[num_textures]; Window root; XVisualInfo *vi; XSetWindowAttributes swa; GLXContext glc; GLint att[] = { GLX_RGBA, GLX_DEPTH_SIZE, 24, GLX_DOUBLEBUFFER, None }; dpy = XOpenDisplay(NULL); if (!dpy) { printf("tcannot open display.\n"); exit(EXIT_FAILURE); } root = DefaultRootWindow(dpy); vi = glXChooseVisual(dpy, 0, att); if (!vi) { printf("no appropriate visual found.\n"); exit(EXIT_FAILURE); } swa.event_mask = ExposureMask | KeyPressMask; swa.colormap = XCreateColormap(dpy, root, vi->visual, AllocNone); fd = v4l2_open(dev_name, O_RDWR | O_NONBLOCK, 0); if (fd < 0) { perror("Cannot open device"); exit(EXIT_FAILURE); } CLEAR(fmt); fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; fmt.fmt.pix.width = x_res; fmt.fmt.pix.height = y_res; fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_RGB24; fmt.fmt.pix.field = V4L2_FIELD_INTERLACED; xioctl(fd, VIDIOC_S_FMT, &fmt); if ((fmt.fmt.pix.width != x_res) || (fmt.fmt.pix.height != y_res)) printf("Warning: driver is sending image at %dx%d\n", fmt.fmt.pix.width, fmt.fmt.pix.height); printf("Fourcc format: %c%c%c%c\n", fmt.fmt.pix.pixelformat & 0xff, (fmt.fmt.pix.pixelformat >> 8) &0xff, (fmt.fmt.pix.pixelformat >> 16) &0xff, (fmt.fmt.pix.pixelformat >> 24) &0xff); win = XCreateWindow(dpy, root, 0, 0, fmt.fmt.pix.width, fmt.fmt.pix.height, 0, vi->depth, InputOutput, vi->visual, CWEventMask | CWColormap, &swa); XMapWindow(dpy, win); XStoreName(dpy, win, dev_name); glc = glXCreateContext(dpy, vi, NULL, GL_TRUE); if (glc == NULL) { printf("\n\tcannot create gl context\n\n"); exit(0); } glXMakeCurrent(dpy, win, glc); glEnable(GL_DEPTH_TEST); XCreatePixmap(dpy, root, fmt.fmt.pix.width, fmt.fmt.pix.height, vi->depth); glEnable(GL_TEXTURE_2D); glGenTextures(1, texture_id); for (j = 0; j < num_textures; j++) { glActiveTexture(GL_TEXTURE0 + j); glBindTexture(GL_TEXTURE_2D, texture_id[j]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glEnable(GL_TEXTURE_2D); } CLEAR(req); req.count = 2; req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; req.memory = V4L2_MEMORY_MMAP; xioctl(fd, VIDIOC_REQBUFS, &req); buffers = calloc(req.count, sizeof(*buffers)); for (n_buffers = 0; n_buffers < req.count; ++n_buffers) { CLEAR(buf); buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; buf.memory = V4L2_MEMORY_MMAP; buf.index = n_buffers; xioctl(fd, VIDIOC_QUERYBUF, &buf); buffers[n_buffers].length = buf.length; buffers[n_buffers].start = v4l2_mmap(NULL, buf.length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, buf.m.offset); if (MAP_FAILED == buffers[n_buffers].start) { perror("mmap"); exit(EXIT_FAILURE); } } for (i = 0; i < n_buffers; ++i) { CLEAR(buf); buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; buf.memory = V4L2_MEMORY_MMAP; buf.index = i; xioctl(fd, VIDIOC_QBUF, &buf); } type = V4L2_BUF_TYPE_VIDEO_CAPTURE; xioctl(fd, VIDIOC_STREAMON, &type); i = 0; while (i < n_frames || n_frames <= 0) { /* Request new buffer */ if (i) xioctl(fd, VIDIOC_QBUF, &buf); do { FD_ZERO(&fds); FD_SET(fd, &fds); /* Timeout. */ tv.tv_sec = 2; tv.tv_usec = 0; r = select(fd + 1, &fds, NULL, NULL, &tv); } while ((r == -1 && (errno = EINTR))); if (r == -1) { perror("select"); return errno; } CLEAR(buf); buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; buf.memory = V4L2_MEMORY_MMAP; xioctl(fd, VIDIOC_DQBUF, &buf); /* * Display the image via GL - for RGB, only one texture is enough */ for (j = 0; j < num_textures; j++) { glActiveTexture(GL_TEXTURE0 + j); glBindTexture(GL_TEXTURE_2D, texture_id[j]); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, fmt.fmt.pix.width, fmt.fmt.pix.height, 0, GL_RGB, GL_UNSIGNED_BYTE, ((char *)buffers[buf.index].start) + j); } Redraw(dpy, win); i++; } type = V4L2_BUF_TYPE_VIDEO_CAPTURE; xioctl(fd, VIDIOC_STREAMOFF, &type); for (i = 0; i < n_buffers; ++i) v4l2_munmap(buffers[i].start, buffers[i].length); v4l2_close(fd); return 0; }
const GrGLInterface* SkNativeGLContext::createGLContext() { fDisplay = XOpenDisplay(0); if (!fDisplay) { SkDebugf("Failed to open X display.\n"); this->destroyGLContext(); return NULL; } // Get a matching FB config static int visual_attribs[] = { GLX_X_RENDERABLE , True, GLX_DRAWABLE_TYPE , GLX_PIXMAP_BIT, None }; int glx_major, glx_minor; // FBConfigs were added in GLX version 1.3. if (!glXQueryVersion(fDisplay, &glx_major, &glx_minor) || ( (glx_major == 1) && (glx_minor < 3) ) || (glx_major < 1)) { SkDebugf("Invalid GLX version."); this->destroyGLContext(); return NULL; } //SkDebugf("Getting matching framebuffer configs.\n"); int fbcount; GLXFBConfig *fbc = glXChooseFBConfig(fDisplay, DefaultScreen(fDisplay), visual_attribs, &fbcount); if (!fbc) { SkDebugf("Failed to retrieve a framebuffer config.\n"); this->destroyGLContext(); return NULL; } //SkDebugf("Found %d matching FB configs.\n", fbcount); // Pick the FB config/visual with the most samples per pixel //SkDebugf("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(fDisplay, fbc[i]); if (vi) { int samp_buf, samples; glXGetFBConfigAttrib(fDisplay, fbc[i], GLX_SAMPLE_BUFFERS, &samp_buf); glXGetFBConfigAttrib(fDisplay, fbc[i], GLX_SAMPLES, &samples); //SkDebugf(" Matching fbconfig %d, visual ID 0x%2x: SAMPLE_BUFFERS = %d," // " SAMPLES = %d\n", // i, (unsigned int)vi->visualid, samp_buf, samples); if (best_fbc < 0 || (samp_buf && samples > best_num_samp)) best_fbc = i, best_num_samp = samples; if (worst_fbc < 0 || !samp_buf || samples < worst_num_samp) worst_fbc = i, worst_num_samp = samples; } XFree(vi); } GLXFBConfig bestFbc = fbc[best_fbc]; // Be sure to free the FBConfig list allocated by glXChooseFBConfig() XFree(fbc); // Get a visual XVisualInfo *vi = glXGetVisualFromFBConfig(fDisplay, bestFbc); //SkDebugf("Chosen visual ID = 0x%x\n", (unsigned int)vi->visualid); fPixmap = XCreatePixmap(fDisplay, RootWindow(fDisplay, vi->screen), 10, 10, vi->depth); if (!fPixmap) { SkDebugf("Failed to create pixmap.\n"); this->destroyGLContext(); return NULL; } fGlxPixmap = glXCreateGLXPixmap(fDisplay, vi, fPixmap); // Done with the visual info data XFree(vi); // Create the context // 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); // Get the default screen's GLX extension list const char *glxExts = glXQueryExtensionsString( fDisplay, DefaultScreen(fDisplay) ); // 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 (!gluCheckExtension( reinterpret_cast<const GLubyte*>("GLX_ARB_create_context") , reinterpret_cast<const GLubyte*>(glxExts))) { //SkDebugf("GLX_ARB_create_context not found." // " Using old-style GLX context.\n"); fContext = glXCreateNewContext(fDisplay, bestFbc, GLX_RGBA_TYPE, 0, True); } else { //SkDebugf("Creating context.\n"); PFNGLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribsARB = (PFNGLXCREATECONTEXTATTRIBSARBPROC) glXGetProcAddressARB((GrGLubyte*)"glXCreateContextAttribsARB"); int context_attribs[] = { GLX_CONTEXT_MAJOR_VERSION_ARB, 3, GLX_CONTEXT_MINOR_VERSION_ARB, 0, //GLX_CONTEXT_FLAGS_ARB , GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB, None }; fContext = glXCreateContextAttribsARB( fDisplay, bestFbc, 0, True, context_attribs ); // Sync to ensure any errors generated are processed. XSync(fDisplay, False); if (!ctxErrorOccurred && fContext) { //SkDebugf( "Created GL 3.0 context.\n" ); } 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] = 1; // GLX_CONTEXT_MINOR_VERSION_ARB = 0 context_attribs[3] = 0; ctxErrorOccurred = false; //SkDebugf("Failed to create GL 3.0 context." // " Using old-style GLX context.\n"); fContext = glXCreateContextAttribsARB( fDisplay, bestFbc, 0, True, context_attribs ); } } // Sync to ensure any errors generated are processed. XSync(fDisplay, False); // Restore the original error handler XSetErrorHandler(oldHandler); if (ctxErrorOccurred || !fContext) { SkDebugf("Failed to create an OpenGL context.\n"); this->destroyGLContext(); return NULL; } // Verify that context is a direct context if (!glXIsDirect(fDisplay, fContext)) { //SkDebugf("Indirect GLX rendering context obtained.\n"); } else { //SkDebugf("Direct GLX rendering context obtained.\n"); } //SkDebugf("Making context current.\n"); if (!glXMakeCurrent(fDisplay, fGlxPixmap, fContext)) { SkDebugf("Could not set the context.\n"); this->destroyGLContext(); return NULL; } const GrGLInterface* interface = GrGLCreateNativeInterface(); if (!interface) { SkDebugf("Failed to create gl interface"); this->destroyGLContext(); return NULL; } return interface; }
/* Returns an XImage structure containing the string rendered in the font. This XImage will be 32 bits per pixel, 8 each per R, G, and B, with the extra byte set to 0xFF. Foregroune and background are GL-style color specifiers: 4 floats from 0.0-1.0. */ XImage * text_to_ximage (Screen *screen, Visual *visual, const char *font, const char *text_lines, GLfloat *texture_fg, GLfloat *texture_bg) { Display *dpy = DisplayOfScreen (screen); int width, height; XFontStruct *f; Pixmap bitmap; f = XLoadQueryFont(dpy, font); if (!f) { f = XLoadQueryFont(dpy, "fixed"); if (f) fprintf (stderr, "%s: unable to load font \"%s\"; using \"fixed\".\n", progname, font); else { fprintf (stderr, "%s: unable to load fonts \"%s\" or \"fixed\"!\n", progname, font); exit (1); } } /* Parse the text, and render it to `bitmap' */ { char *text, *text2, *line, *token; int lines; XCharStruct overall; XGCValues gcv; GC gc; int margin = 2; int fg = 1; int bg = 0; int xoff, yoff; text = strdup (text_lines); while (*text && (text[strlen(text)-1] == '\r' || text[strlen(text)-1] == '\n')) text[strlen(text)-1] = 0; text2 = strdup (text); memset(&overall, 0, sizeof(overall)); token = text; lines = 0; while ((line = strtok (token, "\r\n"))) { XCharStruct o2; int ascent, descent, direction; token = 0; XTextExtents (f, line, strlen(line), &direction, &ascent, &descent, &o2); overall.lbearing = MAX(overall.lbearing, o2.lbearing); overall.rbearing = MAX(overall.rbearing, o2.rbearing); lines++; } free (text); text = 0; width = overall.lbearing + overall.rbearing + margin + margin + 1; height = ((f->ascent + f->descent) * lines) + margin + margin; /* GL texture sizes must be powers of two. */ { int w2 = to_pow2(width); int h2 = to_pow2(height); xoff = (w2 - width) / 2; yoff = (h2 - height) / 2; width = w2; height = h2; } bitmap = XCreatePixmap(dpy, RootWindowOfScreen (screen), width, height, 1); gcv.font = f->fid; gcv.foreground = bg; gc = XCreateGC (dpy, bitmap, (GCFont | GCForeground), &gcv); XFillRectangle(dpy, bitmap, gc, 0, 0, width, height); XSetForeground(dpy, gc, fg); token = text2; lines = 0; while ((line = strtok(token, "\r\n"))) { XCharStruct o2; int ascent, descent, direction; token = 0; XTextExtents(f, line, strlen(line), &direction, &ascent, &descent, &o2); XDrawString(dpy, bitmap, gc, overall.lbearing + margin + xoff, ((f->ascent * (lines + 1)) + (f->descent * lines) + margin + yoff), line, strlen(line)); lines++; } free(text2); XUnloadFont(dpy, f->fid); XFree((XPointer) f); XFreeGC(dpy, gc); } /* Convert the server-side Pixmap to a client-side GL-ordered XImage. */ { XImage *ximage1, *ximage2; unsigned long fg, bg; int x, y; ximage1 = XGetImage (dpy, bitmap, 0, 0, width, height, ~0L, ZPixmap); XFreePixmap(dpy, bitmap); ximage2 = XCreateImage (dpy, visual, 32, ZPixmap, 0, 0, width, height, 32, 0); ximage2->data = (char *) malloc (height * ximage2->bytes_per_line); /* Translate the 1-bit image to a deep image: first figure out what the colors are. */ { int rpos, gpos, bpos, apos; /* bitfield positions */ /* Note that unlike X, which is endianness-agnostic (since any XImage can have its own specific bit ordering, with the server reversing things as necessary) OpenGL pretends everything is client-side, so we need to pack things in the right order for the client machine. */ #if 0 /* #### Cherub says that the little-endian case must be taken on MacOSX, or else the colors/alpha are the wrong way around. How can that be the case? */ if (bigendian()) rpos = 24, gpos = 16, bpos = 8, apos = 0; else #endif rpos = 0, gpos = 8, bpos = 16, apos = 24; fg = (((unsigned long) (texture_fg[0] * 255.0) << rpos) | ((unsigned long) (texture_fg[1] * 255.0) << gpos) | ((unsigned long) (texture_fg[2] * 255.0) << bpos) | ((unsigned long) (texture_fg[3] * 255.0) << apos)); bg = (((unsigned long) (texture_bg[0] * 255.0) << rpos) | ((unsigned long) (texture_bg[1] * 255.0) << gpos) | ((unsigned long) (texture_bg[2] * 255.0) << bpos) | ((unsigned long) (texture_bg[3] * 255.0) << apos)); } for (y = 0; y < height; y++) { int y2 = (height-1-y); /* Texture maps are upside down. */ for (x = 0; x < width; x++) XPutPixel (ximage2, x, y, XGetPixel (ximage1, x, y2) ? fg : bg); } XDestroyImage (ximage1); #if 0 for (y = 0; y < height; y++) { int y2 = (height-1-y); /* Texture maps are upside down. */ for (x = 0; x < width; x++) fputc ((XGetPixel (ximage2, x, y2) == fg ? '#' : ' '), stdout); fputc ('\n', stdout); } fputc ('\n', stdout); #endif /* 0 */ return ximage2; } }
/* Return true if an error occurred. */ bool apple_glx_pbuffer_create(Display * dpy, GLXFBConfig config, int width, int height, int *errorcode, GLXPbuffer * result) { struct apple_glx_drawable *d; struct apple_glx_pbuffer *pbuf = NULL; CGLError err; Window root; int screen; Pixmap xid; struct glx_config *modes = (struct glx_config *) config; root = DefaultRootWindow(dpy); screen = DefaultScreen(dpy); /* * This pixmap is only used for a persistent XID. * The XC-MISC extension cleans up XIDs and reuses them transparently, * so we need to retain a server-side reference. */ xid = XCreatePixmap(dpy, root, (unsigned int) 1, (unsigned int) 1, DefaultDepth(dpy, screen)); if (None == xid) { *errorcode = BadAlloc; return true; } if (apple_glx_drawable_create(dpy, screen, xid, &d, &callbacks)) { *errorcode = BadAlloc; return true; } /* The lock is held in d from create onward. */ pbuf = &d->types.pbuffer; pbuf->xid = xid; pbuf->width = width; pbuf->height = height; err = apple_cgl.create_pbuffer(width, height, GL_TEXTURE_RECTANGLE_EXT, (modes->alphaBits > 0) ? GL_RGBA : GL_RGB, 0, &pbuf->buffer_obj); if (kCGLNoError != err) { d->unlock(d); d->destroy(d); *errorcode = BadMatch; return true; } pbuf->fbconfigID = modes->fbconfigID; pbuf->event_mask = 0; *result = pbuf->xid; d->unlock(d); return false; }
/* * TextLayer::render * * Renders some text without a background, without automatically * binding the text pixmap to a texture (since we need to bind it later) * */ void TextLayer::render () { int twidth, theight; Pixmap pixmap = None; GROUP_SCREEN (screen); if (!HAS_TOP_WIN (mGroup)) return; /* Maximum text width is the tab bar width */ twidth = mGroup->mTabBar->mRegion.boundingRect ().width (); theight = mGroup->mTabBar->mRegion.boundingRect ().height (); if (mGroup->mTabBar->mTextSlot && mGroup->mTabBar->mTextSlot->mWindow && gTextAvailable) { CompText::Attrib textAttrib; textAttrib.family = "Sans"; textAttrib.size = gs->optionGetTabbarFontSize (); /* Bold text, ellipsize if there is not enough room and do not * automatically bind pixmap to texture */ textAttrib.flags = CompText::StyleBold | CompText::Ellipsized | CompText::NoAutoBinding; textAttrib.color[0] = gs->optionGetTabbarFontColorRed (); textAttrib.color[1] = gs->optionGetTabbarFontColorGreen (); textAttrib.color[2] = gs->optionGetTabbarFontColorBlue (); textAttrib.color[3] = gs->optionGetTabbarFontColorAlpha (); textAttrib.maxWidth = twidth; textAttrib.maxHeight = theight; /* Render title of the top window */ if (gs->mText.renderWindowTitle ( mGroup->mTabBar->mTextSlot->mWindow->id (), false, textAttrib)) { pixmap = gs->mText.getPixmap (); twidth = gs->mText.getWidth (); theight = gs->mText.getHeight (); } } if (!pixmap) { /* getting the pixmap failed, so create an empty one */ pixmap = XCreatePixmap (screen->dpy (), screen->root (), twidth, theight, 32); if (pixmap) { XGCValues gcv; GC gc; gcv.foreground = 0x00000000; gcv.plane_mask = 0xffffffff; gc = XCreateGC (screen->dpy (), pixmap, GCForeground, &gcv); XFillRectangle (screen->dpy (), pixmap, gc, 0, 0, twidth, theight); XFreeGC (screen->dpy (), gc); } } setWidth (twidth); setHeight (theight); if (pixmap) { mTexture.clear (); mPixmap = pixmap; /* Text layer's texture is bound here, this can be re used * in TextureLayer::paint */ mTexture = GLTexture::bindPixmapToTexture (mPixmap, width (), height (), 32); } }