static void Resize (XtcwpAxesWidget w) { XtcwpAxesCallbackStruct cb; XFontStruct *fa,*ft; XCharStruct cs; int labelch,labelcw,titlech,bl,bt,br,bb,ticsize,dummy; /* get fonts and determine character dimensions */ fa = XQueryFont(XtDisplay(w),w->axes.labelfont); XTextExtents(fa,"2",1,&dummy,&dummy,&dummy,&cs); labelch = cs.ascent+cs.descent; labelcw = cs.width; ft = XQueryFont(XtDisplay(w),w->axes.titlefont); titlech = ft->max_bounds.ascent+ft->max_bounds.descent; /* determine axes rectangle position and dimensions */ ticsize = labelcw; bl = labelch+7*labelcw; br = w->core.width-5*labelcw; while (br<bl) { br += labelcw; bl -= labelcw; } if (bl<0) bl = 0; if (br>((int) w->core.width)) br = w->core.width; if (w->axes.style==XtcwpNORMAL) { bt = labelch+labelch/2+titlech; bb = w->core.height-3*ticsize/2-2*labelch; } else { bt = 3*ticsize/2+2*labelch; bb = w->core.height-labelch-labelch/2-titlech; } while (bb<bt) { bb += labelch; bt -= labelch; } if (bt<0) bt = 0; if (bb>((int) w->core.height)) bb = w->core.height; w->axes.x = bl; w->axes.y = bt; w->axes.width = br-bl; w->axes.height = bb-bt; /* Free font info */ XFreeFontInfo(NULL,fa,1); XFreeFontInfo(NULL,ft,1); /* call callbacks */ fillCallbackStruct(w,XtcwpCR_RESIZE,NULL,NULL,&cb); XtCallCallbacks ((Widget) w,XtNresizeCallback,&cb); }
PetscErrorCode XiInitFonts(PetscDraw_X *XBWin) { char **names; int cnt,i,j; XFontStruct *info; PetscFunctionBegin; /* This just gets the most basic fixed-width fonts */ names = XListFontsWithInfo(XBWin->disp,"?x??",NFONTS,&cnt,&info); j = 0; for (i=0; i<cnt; i++) { names[i][1] = '\0'; nfonts[j].w = info[i].max_bounds.width ; nfonts[j].h = info[i].ascent + info[i].descent; nfonts[j].descent = info[i].descent; if (nfonts[j].w <= 0 || nfonts[j].h <= 0) continue; j++; if (j >= NFONTS) break; } act_nfonts = j; if (cnt > 0) { XFreeFontInfo(names,info,cnt); } /* If the above fails,try this: */ if (!act_nfonts) { /* This just gets the most basic fixed-width fonts */ names = XListFontsWithInfo(XBWin->disp,"?x",NFONTS,&cnt,&info); j = 0; for (i=0; i<cnt; i++) { PetscErrorCode ierr; size_t len; ierr = PetscStrlen(names[i],&len);CHKERRQ(ierr); if (len != 2) continue; names[i][1] = '\0'; nfonts[j].w = info[i].max_bounds.width ; /* nfonts[j].w = info[i].max_bounds.lbearing + info[i].max_bounds.rbearing; */ nfonts[j].h = info[i].ascent + info[i].descent; nfonts[j].descent = info[i].descent; if (nfonts[j].w <= 0 || nfonts[j].h <= 0) continue; j++; if (j >= NFONTS) break; } act_nfonts = j; XFreeFontInfo(names,info,cnt); } PetscFunctionReturn(0); }
static void Dealloc(PaxFontObject *self) { if (self->from_id) XFreeFontInfo(NULL, self->font_struct, 1); else XFreeFont(self->display, self->font_struct); PyObject_Del(self); }
static void get_list(char *pattern) { int available = nnames+1, i; char **fonts; XFontStruct *info; /* Get list of fonts matching pattern */ for (;;) { if (open_instead_of_list) { info = XLoadQueryFont (dpy, pattern); if (info) { fonts = &pattern; available = 1; XUnloadFont (dpy, info->fid); } else { fonts = NULL; } break; } if (long_list == L_MEDIUM) fonts = XListFontsWithInfo(dpy, pattern, nnames, &available, &info); else fonts = XListFonts(dpy, pattern, nnames, &available); if (fonts == NULL || available < nnames) break; if (long_list == L_MEDIUM) XFreeFontInfo(fonts, info, available); else XFreeFontNames(fonts); nnames = available * 2; } if (fonts == NULL) { fprintf(stderr, "%s: pattern \"%s\" unmatched\n", program_name, pattern); return; } font_list = (FontList *)Realloc((char *)font_list, (font_cnt + available) * sizeof(FontList)); for (i=0; i<available; i++) { font_list[font_cnt].name = fonts[i]; if (long_list == L_MEDIUM) font_list[font_cnt].info = info + i; else font_list[font_cnt].info = NULL; font_cnt++; } }
static int init_xfont(void) { XFontStruct *xfs; xfs = find_font(XFixedFontList, NULL); if (xfs == NULL) { fprintf(stderr, "Could not load fixed font"); return 0; } if (FontName[FT_FIXED]) XFree(FontName[FT_FIXED]); FontName[FT_FIXED] = get_font_name(xfs); FontId[FT_FIXED] = xfs->fid; FixedFontAscent = xfs->ascent; FixedFontDescent = xfs->descent; FixedFontWidth = (xfs->min_bounds).width; FontHeight[FT_FIXED] = FixedFontAscent + FixedFontDescent; XFreeFontInfo(NULL, xfs, 1); xfs = find_font(XVarFontList, NULL); if (FontName[FT_VAR]) XFree(FontName[FT_VAR]); if (xfs == NULL) { fprintf(stderr, "Unable to load variable font - fixed font will be used"); FontName[FT_VAR] = strdup(FontName[FT_FIXED]); FontId[FT_VAR] = FontId[FT_FIXED]; } else { FontName[FT_VAR] = get_font_name(xfs); FontHeight[FT_VAR] = xfs->ascent + xfs->descent; FontId[FT_VAR] = xfs->fid; XFreeFontInfo(NULL, xfs, 1); } return 1; }
static int query_font_geometry (Display *dpy, GC gc, const char *txt, int *w, int *h, int *a, int *d) { XCharStruct text_structure; int font_direction, font_ascent, font_descent; XFontStruct *fontinfo = XQueryFont (dpy, XGContextFromGC (gc)); if (!fontinfo) { return -1; } XTextExtents (fontinfo, txt, strlen (txt), &font_direction, &font_ascent, &font_descent, &text_structure); if (w) *w = XTextWidth (fontinfo, txt, strlen (txt)); if (h) *h = text_structure.ascent + text_structure.descent; if (a) *a = text_structure.ascent; if (d) *d = text_structure.descent; XFreeFontInfo (NULL, fontinfo, 1); return 0; }
static void do_query_font (Display *dpy, char *name) { register int i; register XFontStruct *info = XLoadQueryFont (dpy, name); if (!info) { fprintf (stderr, "%s: unable to get info about font \"%s\"\n", program_name, name); return; } printf ("name: %s\n", name ? name : "(nil)"); printf (" direction:\t\t%s\n", ((info->direction == FontLeftToRight) ? "left to right" : "right to left")); printf (" indexing:\t\t%s\n", ((info->min_byte1 == 0 && info->max_byte1 == 0) ? "linear" : "matrix")); printf (" rows:\t\t\t0x%02x thru 0x%02x (%d thru %d)\n", info->min_byte1, info->max_byte1, info->min_byte1, info->max_byte1); printf (" columns:\t\t0x%02x thru 0x%02x (%d thru %d)\n", info->min_char_or_byte2, info->max_char_or_byte2, info->min_char_or_byte2, info->max_char_or_byte2); printf (" all chars exist:\t%s\n", (info->all_chars_exist) ? "yes" : "no"); printf (" default char:\t\t0x%04x (%d)\n", info->default_char, info->default_char); printf (" ascent:\t\t%d\n", info->ascent); printf (" descent:\t\t%d\n", info->descent); ComputeFontType (info); printf (" bounds:\t\t%s", bounds_metrics_title); PrintBounds ("min", &info->min_bounds); PrintBounds ("max", &info->max_bounds); if (info->per_char && long_list >= L_VERYLONG) print_character_metrics (info); printf (" properties:\t\t%d\n", info->n_properties); for (i = 0; i < info->n_properties; i++) PrintProperty (&info->properties[i]); printf ("\n"); XFreeFontInfo (NULL, info, 1); }
PetscErrorCode XiLoadFont(PetscDraw_X *XBWin,XiFont *font) { char font_name[100]; XFontStruct *FontInfo; XGCValues values ; PetscFunctionBegin; (void) sprintf(font_name,"%dx%d",font->font_w,font->font_h); font->fnt = XLoadFont(XBWin->disp,font_name); /* The font->descent may not have been set correctly; get it now that the font has been loaded */ FontInfo = XQueryFont(XBWin->disp,font->fnt); font->font_descent = FontInfo->descent; XFreeFontInfo(0,FontInfo,1); /* Set the current font in the CG */ values.font = font->fnt ; XChangeGC(XBWin->disp,XBWin->gc.set,GCFont,&values); PetscFunctionReturn(0); }
static void draw_xor_rect (MetaScreen *screen, const MetaRectangle *rect, int width, int height) { /* The lines in the center can't overlap the rectangle or each * other, or the XOR gets reversed. So we have to draw things * a bit oddly. */ XSegment segments[8]; MetaRectangle shrunk_rect; int i; #define LINE_WIDTH META_WIREFRAME_XOR_LINE_WIDTH /* We don't want the wireframe going outside the window area. * It makes it harder for the user to position windows and it exposes other * annoying bugs. */ shrunk_rect = *rect; shrunk_rect.x += LINE_WIDTH / 2 + LINE_WIDTH % 2; shrunk_rect.y += LINE_WIDTH / 2 + LINE_WIDTH % 2; shrunk_rect.width -= LINE_WIDTH + 2 * (LINE_WIDTH % 2); shrunk_rect.height -= LINE_WIDTH + 2 * (LINE_WIDTH % 2); XDrawRectangle (screen->display->xdisplay, screen->xroot, screen->root_xor_gc, shrunk_rect.x, shrunk_rect.y, shrunk_rect.width, shrunk_rect.height); /* Don't put lines inside small rectangles where they won't fit */ if (shrunk_rect.width < (LINE_WIDTH * 4) || shrunk_rect.height < (LINE_WIDTH * 4)) return; if ((width >= 0) && (height >= 0)) { XGCValues gc_values = { 0 }; if (XGetGCValues (screen->display->xdisplay, screen->root_xor_gc, GCFont, &gc_values)) { char *text; int text_length; XFontStruct *font_struct; int text_width, text_height; int box_x, box_y; int box_width, box_height; font_struct = XQueryFont (screen->display->xdisplay, gc_values.font); if (font_struct != NULL) { text = g_strdup_printf ("%d x %d", width, height); text_length = strlen (text); text_width = text_length * font_struct->max_bounds.width; text_height = font_struct->max_bounds.descent + font_struct->max_bounds.ascent; box_width = text_width + 2 * LINE_WIDTH; box_height = text_height + 2 * LINE_WIDTH; box_x = shrunk_rect.x + (shrunk_rect.width - box_width) / 2; box_y = shrunk_rect.y + (shrunk_rect.height - box_height) / 2; if ((box_width < shrunk_rect.width) && (box_height < shrunk_rect.height)) { XFillRectangle (screen->display->xdisplay, screen->xroot, screen->root_xor_gc, box_x, box_y, box_width, box_height); XDrawString (screen->display->xdisplay, screen->xroot, screen->root_xor_gc, box_x + LINE_WIDTH, box_y + LINE_WIDTH + font_struct->max_bounds.ascent, text, text_length); } g_free (text); XFreeFontInfo (NULL, font_struct, 1); if ((box_width + LINE_WIDTH) >= (shrunk_rect.width / 3)) return; if ((box_height + LINE_WIDTH) >= (shrunk_rect.height / 3)) return; } } } /* Two vertical lines at 1/3 and 2/3 */ segments[0].x1 = shrunk_rect.x + shrunk_rect.width / 3; segments[0].y1 = shrunk_rect.y + LINE_WIDTH / 2 + LINE_WIDTH % 2; segments[0].x2 = segments[0].x1; segments[0].y2 = shrunk_rect.y + shrunk_rect.height - LINE_WIDTH / 2; segments[1] = segments[0]; segments[1].x1 = shrunk_rect.x + (shrunk_rect.width / 3) * 2; segments[1].x2 = segments[1].x1; /* Now make two horizontal lines at 1/3 and 2/3, but not * overlapping the verticals */ segments[2].x1 = shrunk_rect.x + LINE_WIDTH / 2 + LINE_WIDTH % 2; segments[2].x2 = segments[0].x1 - LINE_WIDTH / 2; segments[2].y1 = shrunk_rect.y + shrunk_rect.height / 3; segments[2].y2 = segments[2].y1; segments[3] = segments[2]; segments[3].x1 = segments[2].x2 + LINE_WIDTH; segments[3].x2 = segments[1].x1 - LINE_WIDTH / 2; segments[4] = segments[3]; segments[4].x1 = segments[3].x2 + LINE_WIDTH; segments[4].x2 = shrunk_rect.x + shrunk_rect.width - LINE_WIDTH / 2; /* Second horizontal line is just like the first, but * shifted down */ i = 5; while (i < 8) { segments[i] = segments[i - 3]; segments[i].y1 = shrunk_rect.y + (shrunk_rect.height / 3) * 2; segments[i].y2 = segments[i].y1; ++i; } XDrawSegments (screen->display->xdisplay, screen->xroot, screen->root_xor_gc, segments, G_N_ELEMENTS (segments)); }
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; } }
/** * Just like glXUseXFont() but with a rotation parameter. * \param rotation may be 0, 90, 180 or 270 only. */ void glXUseRotatedXFontMESA(Font font, int first, int count, int listbase, int rotation) { Display *dpy; Window win; Pixmap pixmap; GC gc; XFontStruct *fs; GLint swapbytes, lsbfirst, rowlength; GLint skiprows, skippixels, alignment; unsigned int maxCharWidth, maxCharHeight; GLubyte *bm; int i; if (rotation != 0 && rotation != 90 && rotation != 180 && rotation != 270) return; dpy = glXGetCurrentDisplay(); if (!dpy) return; /* I guess glXMakeCurrent wasn't called */ win = RootWindow(dpy, DefaultScreen(dpy)); fs = XQueryFont(dpy, font); if (!fs) { fprintf(stderr, "XQueryFont failed"); return; } /* Allocate a GL bitmap that can fit any character */ maxCharWidth = fs->max_bounds.rbearing - fs->min_bounds.lbearing; maxCharHeight = fs->max_bounds.ascent + fs->max_bounds.descent; /* use max, in case we're rotating */ if (rotation == 90 || rotation == 270) { /* swap width/height */ bm = (GLubyte *) malloc((maxCharHeight + 7) / 8 * maxCharWidth); } else { /* normal or upside down */ bm = (GLubyte *) malloc((maxCharWidth + 7) / 8 * maxCharHeight); } if (!bm) { XFreeFontInfo(NULL, fs, 1); fprintf(stderr, "Out of memory in glXUseRotatedXFontMESA"); return; } /* 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); /* Create pixmap and GC */ pixmap = XCreatePixmap(dpy, win, maxCharWidth, maxCharHeight, 1); { XGCValues values; unsigned long valuemask; 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); } for (i = 0; i < count; i++) { const unsigned int c = first + i; const int list = listbase + i; unsigned int charWidth, charHeight; unsigned int bitmapWidth, bitmapHeight; GLfloat xOrig, yOrig, xStep, yStep, dtemp; const XCharStruct *ch; int xPos, yPos; 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; } /* glBitmap()' parameters: straight from the glXUseXFont(3) manpage. */ charWidth = ch->rbearing - ch->lbearing; charHeight = ch->ascent + ch->descent; xOrig = -ch->lbearing; yOrig = ch->descent; xStep = ch->width; yStep = 0; /* X11's starting point. */ xPos = -ch->lbearing; yPos = ch->ascent; /* Apply rotation */ switch (rotation) { case 0: /* nothing */ bitmapWidth = charWidth; bitmapHeight = charHeight; break; case 90: /* xStep, yStep */ dtemp = xStep; xStep = -yStep; yStep = dtemp; /* xOrig, yOrig */ yOrig = xOrig; xOrig = charHeight - (charHeight - yPos); /* width, height */ bitmapWidth = charHeight; bitmapHeight = charWidth; break; case 180: /* xStep, yStep */ xStep = -xStep; yStep = -yStep; /* xOrig, yOrig */ xOrig = charWidth - xOrig - 1; yOrig = charHeight - yOrig - 1; bitmapWidth = charWidth; bitmapHeight = charHeight; break; case 270: /* xStep, yStep */ dtemp = xStep; xStep = yStep; yStep = -dtemp; /* xOrig, yOrig */ dtemp = yOrig; yOrig = charWidth - xOrig; xOrig = dtemp; /* width, height */ bitmapWidth = charHeight; bitmapHeight = charWidth; break; default: /* should never get here */ ; } glNewList(list, GL_COMPILE); if (valid && bitmapWidth > 0 && bitmapHeight > 0) { fill_bitmap(dpy, pixmap, gc, bitmapWidth, bitmapHeight, charWidth, charHeight, xPos, yPos, c, bm, rotation); glBitmap(bitmapWidth, bitmapHeight, xOrig, yOrig, xStep, yStep, bm); } else { glBitmap(0, 0, 0.0, 0.0, xStep, yStep, NULL); } glEndList(); } free(bm); XFreeFontInfo(NULL, fs, 1); XFreePixmap(dpy, pixmap); 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 void FreeFontList() { int i; for( i= 0; i< LastFontList; i++ ){ XFreeFontInfo( FontList[i].name_list, FontList[i].font_list, FontList[i].font_count ); } }
/* * General text formatting routine which does wrap around * if necessary at whitespaces. The function returns the * vertical position it ended at. */ int DrawShadowText(Display *display, Window w, GC gc, int x_border, int y_start, const char *str, unsigned long fg, unsigned long bg) { XFontStruct *font = XQueryFont(display, XGContextFromGC(gc)); int y, x, tmp; int count = 1; XWindowAttributes wattr; if (str == NULL || *str == '\0') return 0; /* Get width of window */ XGetWindowAttributes(display, w, &wattr); /* Start position */ x = x_border; y = y_start + font->ascent; do { char word[LINE_MAX]; int wordLen, i; for (i = 0; *str && !isspace(*str) && i < LINE_MAX-1; str++, i++) word[i] = *str; word[i] = '\0'; /* Word length in pixels */ wordLen = XTextWidth(font, word, i); /* We need a linebreak? */ if (x + wordLen > wattr.width - BORDER) { x = x_border; y += font->ascent + font->descent + 1; } /* Draw word and move cursor to point to after this word */ ShadowDrawString(display, w, gc, x, y, word, fg, bg); x += wordLen; /* Handle whitespace */ for (; isspace(*str); str++) switch (*str) { /* New paragraph */ case '\n': x = x_border; y += font->ascent + font->descent + 1; break; /* Just a space */ default: x += XTextWidth(font, " ", 1); break; } } while (*str != '\0'); tmp = font->descent+1; XFreeFontInfo(NULL, font, count); return y + tmp; }
static void Redisplay (XtcwpAxesWidget w, XEvent *event, Region region) { Display *dpy=XtDisplay(w); Window win=XtWindow(w); int x=w->axes.x; int y=w->axes.y; int width=w->axes.width; int height=w->axes.height; float x1beg=w->axes.x1beg; float x1end=w->axes.x1end; float x2beg=w->axes.x2beg; float x2end=w->axes.x2end; float p1beg=w->axes.p1beg; float p1end=w->axes.p1end; float p2beg=w->axes.p2beg; float p2end=w->axes.p2end; int n1tic=w->axes.n1tic; int n2tic=w->axes.n2tic; int grid1=w->axes.grid1; int grid2=w->axes.grid2; char *label1=w->axes.label1; char *label2=w->axes.label2; char *title=w->axes.title; Font labelfont=w->axes.labelfont; Font titlefont=w->axes.titlefont; Pixel axescolor=w->axes.axescolor; Pixel gridcolor=w->axes.gridcolor; Pixel titlecolor=w->axes.titlecolor; int style=w->axes.style; XGCValues values; GC gca,gcg,gct; XtcwpAxesCallbackStruct cb; XFontStruct *fa,*ft; XCharStruct cs; int labelca,labelcd,labelch,labelcw,titleca,titlech, ntic,xa,ya,tw,ticsize,ticb,numb,labelb,grided,grid, n1num,n2num,dummy; size_t lstr; float dnum,fnum,dtic,amin,amax,base,scale,anum,atic,azero; float d1num=0.0,f1num=0.0,d2num=0.0,f2num=0.0; char str[256],dash[2],*label; /* if not visible, then simply return */ if (!w->core.visible) return; /* call callbacks before drawing axes (so grid will be on top) */ fillCallbackStruct(w,XtcwpCR_EXPOSE,event,region,&cb); XtCallCallbacks ((Widget) w,XtNexposeCallback,&cb); /* create GCs */ gca = XCreateGC(dpy,win,0,&values); gcg = XCreateGC(dpy,win,0,&values); gct = XCreateGC(dpy,win,0,&values); /* set colors */ XSetForeground(dpy,gca,axescolor); XSetForeground(dpy,gcg,gridcolor); XSetForeground(dpy,gct,titlecolor); /* set fonts and determine character dimensions */ XSetFont(dpy,gca,labelfont); XSetFont(dpy,gct,titlefont); fa = XQueryFont(dpy,labelfont); XTextExtents(fa,"2",1,&dummy,&dummy,&dummy,&cs); labelca = cs.ascent; labelcd = cs.descent; labelch = labelca+labelcd; labelcw = cs.width; ft = XQueryFont(dpy,titlefont); titleca = ft->max_bounds.ascent; titlech = ft->max_bounds.ascent+ft->max_bounds.descent; /* determine tic size */ ticsize = labelcw; /* determine numbered tic intervals */ n1num = (style==XtcwpNORMAL ? width : height)/(8*labelcw); scaxis(x1beg,x1end,&n1num,&d1num,&f1num); n2num = (style==XtcwpNORMAL ? height : width)/(8*labelcw); scaxis(x2beg,x2end,&n2num,&d2num,&f2num); /* draw horizontal axis */ if (style==XtcwpNORMAL) { amin = (x1beg<x1end)?x1beg:x1end; amax = (x1beg>x1end)?x1beg:x1end; dnum = d1num; fnum = f1num; ntic = n1tic; scale = width/(x1end+p1end-x1beg-p1beg); base = x-scale*(x1beg+p1beg); ya = y+height; ticb = ticsize; numb = ticb+labelca+ticsize/4; labelb = numb+labelch+ticsize/4; grid = grid1; label = label1; } else { amin = (x2beg<x2end)?x2beg:x2end; amax = (x2beg>x2end)?x2beg:x2end; dnum = d2num; fnum = f2num; ntic = n2tic; scale = width/(x2end+p2end-x2beg-p2beg); base = x-scale*(x2beg+p2beg); ya = y; ticb = -ticsize; numb = ticb-labelcd-ticsize/4; labelb = numb-labelch-ticsize/4; grid = grid2; label = label2; } if (grid==XtcwpSOLID) { XSetLineAttributes(dpy,gcg,1L,LineSolid,CapButt,JoinMiter); grided = True; } else if (grid==XtcwpDASH) { grided = True; XSetLineAttributes(dpy,gcg,1L,LineOnOffDash,CapButt,JoinMiter); dash[0] = 8; dash[1] = 4; XSetDashes(dpy,gcg,0,dash,2); } else if (grid==XtcwpDOT) { grided = True; XSetLineAttributes(dpy,gcg,1L,LineOnOffDash,CapButt,JoinMiter); dash[0] = 1; dash[1] = 4; XSetDashes(dpy,gcg,0,dash,2); } else grided = False; azero = 0.0001*(amax-amin); for (anum=fnum; anum<=amax; anum+=dnum) { if (anum<amin) continue; xa = base+scale*anum; if (grided) XDrawLine(dpy,win,gcg,xa,y,xa,y+height); XDrawLine(dpy,win,gca,xa,ya,xa,ya+ticb); if (anum>-azero && anum<azero) sprintf(str,"%1.5g",0.0); else sprintf(str,"%1.5g",anum); lstr = strlen(str); tw = XTextWidth(fa,str,(int)lstr); XDrawString(dpy,win,gca,xa-tw/2,ya+numb,str,(int)lstr); } dtic = dnum/ntic; for (atic=fnum-ntic*dtic-dtic; atic<=amax; atic+=dtic) { if (atic<amin) continue; xa = base+scale*atic; XDrawLine(dpy,win,gca,xa,ya,xa,ya+ticb/2); } lstr = strlen(label); tw = XTextWidth(fa,label,(int)lstr); XDrawString(dpy,win,gca,x+width/2-tw/2,ya+labelb,label,(int)lstr); /* draw vertical axis */ if (style==XtcwpNORMAL) { amin = (x2beg<x2end)?x2beg:x2end; amax = (x2beg>x2end)?x2beg:x2end; dnum = d2num; fnum = f2num; ntic = n2tic; scale = -height/(x2end+p2end-x2beg-p2beg); base = y+height-scale*(x2beg+p2beg); grid = grid2; label = label2; } else { amin = (x1beg<x1end)?x1beg:x1end; amax = (x1beg>x1end)?x1beg:x1end; dnum = d1num; fnum = f1num; ntic = n1tic; scale = height/(x1end+p1end-x1beg-p1beg); base = y-scale*(x1beg+p1beg); grid = grid1; label = label1; } xa = x; ticb = -ticsize; numb = ticb-ticsize/4; if (grid==XtcwpSOLID) { XSetLineAttributes(dpy,gcg,1L,LineSolid,CapButt,JoinMiter); grided = True; } else if (grid==XtcwpDASH) { grided = True; XSetLineAttributes(dpy,gcg,1L,LineOnOffDash,CapButt,JoinMiter); dash[0] = 8; dash[1] = 4; XSetDashes(dpy,gcg,0,dash,2); } else if (grid==XtcwpDOT) { grided = True; XSetLineAttributes(dpy,gcg,1L,LineOnOffDash,CapButt,JoinMiter); dash[0] = 1; dash[1] = 4; XSetDashes(dpy,gcg,0,dash,2); } else grided = False; azero = 0.0001*(amax-amin); for (anum=fnum; anum<=amax; anum+=dnum) { if (anum<amin) continue; ya = base+scale*anum; if (grided) XDrawLine(dpy,win,gcg,x,ya,x+width,ya); XDrawLine(dpy,win,gca,xa,ya,xa+ticb,ya); if (anum>-azero && anum<azero) sprintf(str,"%1.5g",0.0); else sprintf(str,"%1.5g",anum); lstr = strlen(str); tw = XTextWidth(fa,str,(int)lstr); XDrawString(dpy,win,gca,xa+numb-tw,ya+labelca/4,str,(int)lstr); } dtic = dnum/ntic; for (atic=fnum-ntic*dtic-dtic; atic<=amax; atic+=dtic) { if (atic<amin) continue; ya = base+scale*atic; XDrawLine(dpy,win,gca,xa,ya,xa+ticb/2,ya); } lstr = strlen(label); tw = XTextWidth(fa,label,(int)lstr); xa = x+ticb-5*labelcw-ticsize/2; if (xa<labelch+1) xa = labelch+1; XtcwpDrawString90(dpy,win,gca,xa,y+height/2+tw/2,label,(int)lstr); /* draw title */ lstr = strlen(title); tw = XTextWidth(ft,title,(int)lstr); if (style==XtcwpNORMAL) { XClearArea(dpy,win,0,y+labelca/4-labelch-labelch-titleca, w->core.width,titlech,False); XDrawString(dpy,win,gct, x+width/2-tw/2, y+labelca/4-labelch-labelch,title,(int)lstr); } else { XClearArea(dpy,win,0,y+height+labelca/4+labelch, w->core.width,titlech,False); XDrawString(dpy,win,gct, x+width/2-tw/2, y+height+labelca/4+labelch+titleca,title,(int)lstr); } /* draw axes box */ XDrawRectangle(dpy,win,gca,x,y,width,height); /* free GCs and font info */ XFreeGC(dpy,gca); XFreeGC(dpy,gcg); XFreeGC(dpy,gct); XFreeFontInfo(NULL,fa,1); XFreeFontInfo(NULL,ft,1); }
/* Finds the set of scalable fonts on the system; picks one; and loads that font in a random pixel size. Returns False if something went wrong. */ static Bool pick_font_1 (state *s, sentence *se) { Bool ok = False; char pattern[1024]; # ifndef HAVE_COCOA /* real Xlib */ char **names = 0; char **names2 = 0; XFontStruct *info = 0; int count = 0, count2 = 0; int i; if (se->font) { XFreeFont (s->dpy, se->font); free (se->font_name); se->font = 0; se->font_name = 0; } if (s->font_override) sprintf (pattern, "%.200s", s->font_override); else sprintf (pattern, "-%s-%s-%s-%s-%s-%s-%s-%s-%s-%s-%s-%s-%s", "*", /* foundry */ "*", /* family */ "*", /* weight */ "*", /* slant */ "*", /* swidth */ "*", /* adstyle */ "0", /* pixel size */ "0", /* point size */ "0", /* resolution x */ "0", /* resolution y */ "p", /* spacing */ "0", /* avg width */ s->charset); /* registry + encoding */ names = XListFonts (s->dpy, pattern, 1000, &count); if (count <= 0) { if (s->font_override) fprintf (stderr, "%s: -font option bogus: %s\n", progname, pattern); else fprintf (stderr, "%s: no scalable fonts found! (pattern: %s)\n", progname, pattern); exit (1); } i = random() % count; names2 = XListFontsWithInfo (s->dpy, names[i], 1000, &count2, &info); if (count2 <= 0) { fprintf (stderr, "%s: pattern %s\n" " gave unusable %s\n\n", progname, pattern, names[i]); goto FAIL; } { XFontStruct *font = &info[0]; unsigned long value = 0; char *foundry=0, *family=0, *weight=0, *slant=0, *setwidth=0, *add_style=0; unsigned long pixel=0, point=0, res_x=0, res_y=0; char *spacing=0; unsigned long avg_width=0; char *registry=0, *encoding=0; Atom a; char *bogus = "\"?\""; # define STR(ATOM,VAR) \ bogus = (ATOM); \ a = XInternAtom (s->dpy, (ATOM), False); \ if (XGetFontProperty (font, a, &value)) \ VAR = XGetAtomName (s->dpy, value); \ else \ goto FAIL2 # define INT(ATOM,VAR) \ bogus = (ATOM); \ a = XInternAtom (s->dpy, (ATOM), False); \ if (!XGetFontProperty (font, a, &VAR) || \ VAR > 9999) \ goto FAIL2 STR ("FOUNDRY", foundry); STR ("FAMILY_NAME", family); STR ("WEIGHT_NAME", weight); STR ("SLANT", slant); STR ("SETWIDTH_NAME", setwidth); STR ("ADD_STYLE_NAME", add_style); INT ("PIXEL_SIZE", pixel); INT ("POINT_SIZE", point); INT ("RESOLUTION_X", res_x); INT ("RESOLUTION_Y", res_y); STR ("SPACING", spacing); INT ("AVERAGE_WIDTH", avg_width); STR ("CHARSET_REGISTRY", registry); STR ("CHARSET_ENCODING", encoding); #undef INT #undef STR pixel = pick_font_size (s); #if 0 /* Occasionally change the aspect ratio of the font, by increasing either the X or Y resolution (while leaving the other alone.) #### Looks like this trick doesn't really work that well: the metrics of the individual characters are ok, but the overall font ascent comes out wrong (unscaled.) */ if (! (random() % 8)) { double n = 2.5 / 3; double scale = 1 + (frand(n) + frand(n) + frand(n)); if (random() % 2) res_x *= scale; else res_y *= scale; } # endif sprintf (pattern, "-%s-%s-%s-%s-%s-%s-%ld-%s-%ld-%ld-%s-%s-%s-%s", foundry, family, weight, slant, setwidth, add_style, pixel, "*", /* point, */ res_x, res_y, spacing, "*", /* avg_width */ registry, encoding); ok = True; FAIL2: if (!ok) fprintf (stderr, "%s: font has bogus %s property: %s\n", progname, bogus, names[i]); if (foundry) XFree (foundry); if (family) XFree (family); if (weight) XFree (weight); if (slant) XFree (slant); if (setwidth) XFree (setwidth); if (add_style) XFree (add_style); if (spacing) XFree (spacing); if (registry) XFree (registry); if (encoding) XFree (encoding); } FAIL: XFreeFontInfo (names2, info, count2); XFreeFontNames (names); # else /* HAVE_COCOA */ if (s->font_override) sprintf (pattern, "%.200s", s->font_override); else { const char *family = "random"; const char *weight = ((random() % 2) ? "normal" : "bold"); const char *slant = ((random() % 2) ? "o" : "r"); int size = 10 * pick_font_size (s); sprintf (pattern, "*-%s-%s-%s-*-%d-*", family, weight, slant, size); } ok = True; # endif /* HAVE_COCOA */ if (! ok) return False; se->font = XLoadQueryFont (s->dpy, pattern); if (! se->font) { if (s->debug_p) fprintf (stderr, "%s: unable to load font %s\n", progname, pattern); return False; } if (se->font->min_bounds.width == se->font->max_bounds.width && !s->font_override) { /* This is to weed out "-urw-nimbus mono l-medium-o-normal--*-*-*-*-p-*-iso8859-1" and "-urw-courier-medium-r-normal--*-*-*-*-p-*-iso8859-1". We asked for only proportional fonts, but this fixed-width font shows up anyway -- but it has goofy metrics (see below) so it looks terrible anyway. */ if (s->debug_p) fprintf (stderr, "%s: skipping bogus monospace non-charcell font: %s\n", progname, pattern); return False; } if (s->debug_p) fprintf(stderr, "%s: %s\n", progname, pattern); se->font_name = strdup (pattern); XSetFont (s->dpy, se->fg_gc, se->font->fid); return True; }
void Fake_glXUseXFont(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 = glXGetCurrentDisplay(); if (!dpy) return; /* I guess glXMakeCurrent wasn't called */ win = RootWindow(dpy, DefaultScreen(dpy)); fs = XQueryFont(dpy, font); if (!fs) { _mesa_error(NULL, GL_INVALID_VALUE, "Couldn't get font structure information"); 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 = malloc((max_bm_width * max_bm_height) * sizeof(GLubyte)); if (!bm) { XFreeFontInfo(NULL, fs, 1); _mesa_error(NULL, GL_OUT_OF_MEMORY, "Couldn't allocate bitmap in glXUseXFont()"); 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 - 0; /* XXX used to subtract 1 here */ /* but that caused a conformace failure */ 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(); } free(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); }
int main(int argc, char *argv[]) { /* default values for -f, -i, -r, -c, -b, -g */ char *fontname = "*"; char *filename = "font.pcx"; int start_char = 32, end_char = 255; int ccolor = 000000000; int bcolor = 255255255; int gcolor = 255000255; /* X11 variables */ Display *display; int screen_number; int default_depth; Window window; Font font; GC gc, gc2; Pixmap pixmap; XImage *image; XCharStruct overall; /* misc variables */ int bitmap_width, bitmap_height; int max_ascent, max_descent; int max_width, max_height; int i, opt, x, y, cx, cy, sx, sy, lines; unsigned long black, white; BITMAP *bitmap; RGB palette[256]; /* show usage if no options */ if (argc == 1) { usage(argv[0]); exit(EXIT_SUCCESS); } /* only to access bitmap operations */ install_allegro(SYSTEM_NONE, &errno, atexit); /* parse options */ opterr = 0; while ((opt = getopt(argc, argv, "f:o:z:c:b:g:r:h")) != EOF) { switch (opt) { case 'f': fontname = optarg; break; case 'o': filename = optarg; break; case 'c': ccolor = atol(optarg); break; case 'b': bcolor = atol(optarg); break; case 'g': gcolor = atol(optarg); break; case 'r': { char *str; start_char = strtol(optarg, &str, 0); end_char = strtol(str + 1, NULL, 0); break; } case 'h': usage(argv[0]); exit(EXIT_SUCCESS); default: fprintf(stderr, "%s: unrecognized option -- '%c'\n", argv[0], optopt); fprintf(stderr, "%s: try '%s -h' for more information\n", argv[0], argv[0]); exit(EXIT_FAILURE); } } /* open display */ display = XOpenDisplay(0); if (display == 0) { fprintf(stderr, "%s: XOpenDisplay failed\n", argv[0]); exit(EXIT_FAILURE); } /* default screen number and window */ screen_number = XDefaultScreen(display); default_depth = XDefaultDepth(display, screen_number); window = XDefaultRootWindow(display); /* load font */ font = XLoadFont(display, fontname); /* create gcs */ { unsigned long val_mask; XGCValues val_bits; val_mask = GCForeground | GCBackground | GCFont | GCFunction; val_bits.function = GXcopy; val_bits.foreground = white = WhitePixel(display, screen_number); val_bits.background = black = BlackPixel(display, screen_number); val_bits.font = font; gc = XCreateGC(display, window, val_mask, &val_bits); val_mask = GCForeground; val_bits.foreground = black; gc2 = XCreateGC(display, window, val_mask, &val_bits); } /* query font ascent and descent */ { XFontStruct *xfs; int min, max; xfs = XQueryFont(display, font); max_ascent = xfs->ascent; max_descent = xfs->descent; if (xfs->min_byte1 == 0 && xfs->max_byte1 == 0) { min = xfs->min_char_or_byte2; max = xfs->max_char_or_byte2; } else { min = (xfs->min_byte1 << 8) + xfs->min_char_or_byte2; max = (xfs->max_byte1 << 8) + xfs->max_char_or_byte2; } if (start_char < min || end_char > max) fprintf(stderr, "You specified characters %04x-%04x, but this font " "only has the range %04x-%04x\n", start_char, end_char, min, max); XFreeFontInfo(NULL, xfs, 0); } /* calculate bitmap width and maximum ascent and descent of characters * (can exceed the font ascent/descent queried above!) */ max_width = 0; lines = 1 + (end_char - start_char) / 16; for (cy = 0; cy < lines; cy++) { for (cx = 0; cx < 16 && start_char + cy * 16 + cx <= end_char; cx++) { int dir, ascent, descent; int width; XChar2b string[2] = { {0, 0}, {0, 0} }; /* query character size */ string[0].byte1 = (start_char + cy * 16 + cx) >> 8; string[0].byte2 = (start_char + cy * 16 + cx) & 255; XQueryTextExtents16(display, font, string, 1, &dir, &ascent, &descent, &overall); width = overall.width; if (width < 1) width = 1; if (width > max_width) max_width = width; if (max_ascent < overall.ascent) max_ascent = overall.ascent; if (max_descent < overall.descent) max_descent = overall.descent; } } max_height = max_ascent + max_descent; bitmap_width = (max_width + 1) * 16 + 1; bitmap_height = (max_height + 1) * lines + 1; /* create bitmap */ bitmap = create_bitmap(bitmap_width, bitmap_height); if (bitmap == 0) { fprintf(stderr, "%s: can not create bitmap\n", argv[0]); exit(EXIT_FAILURE); } /* fill with filler color */ clear_to_color(bitmap, 255); /* process all characters */ sy = 1; for (cy = 0; cy < lines; cy++) { sx = 1; for (cx = 0; cx < 16 && start_char + cy * 16 + cx <= end_char; cx++) { int dir, ascent, descent; XChar2b string[2] = { {0, 0}, {0, 0} }; /* query character size */ string[0].byte1 = (start_char + cy * 16 + cx) >> 8; string[0].byte2 = (start_char + cy * 16 + cx) & 255; XQueryTextExtents16(display, font, string, 1, &dir, &ascent, &descent, &overall); if (overall.width < 1) overall.width = 1; /* create pixmap and draw character there */ pixmap = XCreatePixmap(display, window, overall.width, max_height, default_depth); /* some fonts draw outside their ascent/descent, so we need to clear * the pixmap before drawing the glyph */ XFillRectangle(display, pixmap, gc2, 0, 0, overall.width, max_height); XDrawImageString16(display, pixmap, gc, 0, max_ascent, string, 1); /* create image with pixmap contents */ image = XGetImage(display, pixmap, 0, 0, overall.width, max_height, AllPlanes, ZPixmap); if (image == 0) { fprintf(stderr, "%s: can not get image\n", argv[0]); exit(EXIT_FAILURE); } /* copy image to bitmap */ for (y = 0; y < max_height; y++) for (x = 0; x < overall.width; x++) { if (XGetPixel(image, x, y) == white) putpixel(bitmap, sx + x, sy + y, 1); else putpixel(bitmap, sx + x, sy + y, 0); } XDestroyImage(image); XFreePixmap(display, pixmap); sx += max_width + 1; } sy += max_height + 1; } /* initialize palette */ for (i = 0; i < 256; i++) palette[i].r = palette[i].g = palette[i].b = 0; #define CLAMP_COL(v) (((v / 4) > 63) ? 63 : (v / 4)) palette[0].r = CLAMP_COL(bcolor / 1000000); palette[0].g = CLAMP_COL((bcolor % 1000000) / 1000); palette[0].b = CLAMP_COL(bcolor % 1000); palette[1].r = CLAMP_COL(ccolor / 1000000); palette[1].g = CLAMP_COL((ccolor % 1000000) / 1000); palette[1].b = CLAMP_COL(ccolor % 1000); palette[255].r = CLAMP_COL(gcolor / 1000000); palette[255].g = CLAMP_COL((gcolor % 1000000) / 1000); palette[255].b = CLAMP_COL(gcolor % 1000); #undef CLAMP_COL save_pcx(filename, bitmap, palette); /* clean up */ destroy_bitmap(bitmap); XFreeGC(display, gc); XFreeGC(display, gc2); XUnloadFont(display, font); XCloseDisplay(display); exit(EXIT_SUCCESS); }