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); }
std::vector<int> get_character_widths ( std::string text ) { // GContext gc_id = XGContextFromGC ( (GC)gc.id() ); std::vector<int> char_widths; XFontStruct * font = XQueryFont ( m_display, (GContext)id() ); for ( std::string::const_iterator it = text.begin(); it != text.end(); it++ ) { std::string temp; temp += *it; int width = XTextWidth ( font, temp.c_str(), 1 ); char_widths.push_back ( width ); } return char_widths; }
/* * Pøipojit k serveru, zjistit o nìm informace */ static void open_display(void) { display_name = XDisplayName(NULL); if(!(display = XOpenDisplay(display_name))) { fprintf(stderr, "Cannot connect to X server \"%s\"\n", display_name); exit(1); } debug("Connected to X server \"%s\"\n", display_name); screen_num = DefaultScreen(display); screen = DefaultScreenOfDisplay(display); debug("Default screen number is %d\n", screen_num); screen_width = DisplayWidth(display, screen_num); screen_height = DisplayHeight(display, screen_num); screen_width_mm = DisplayWidthMM(display, screen_num); screen_height_mm = DisplayHeightMM(display, screen_num); debug("Screen size is %ux%u pixels, %ux%u mm\n", screen_width, screen_height, screen_width_mm, screen_height_mm); root = RootWindow(display, screen_num); black = BlackPixel(display, screen_num); white = WhitePixel(display, screen_num); debug("Root window ID is %#lx, black is %#lx, white is %#lx\n", root, black, white); def_gc = DefaultGC(display, screen_num); /* Toto volání XQueryFont() do def_font->fid neulo¾í ID fontu, ale * grafického kontextu! Nevím, jak získat ID nebo jméno standardního * fontu. */ if(!(def_font = XQueryFont(display, XGContextFromGC(def_gc)))) { fprintf(stderr, "XQueryFont() failed\n"); exit(1); } }
NSString::NSString(const char* str) : _label(str), _resizable(false) { if (!stringInitialized) { stringInitialized = true; fontStruct = XQueryFont(NSdpy, font); } { XCharStruct* charStruct = &fontStruct->max_bounds; _fontWindowHeight = charStruct->ascent + charStruct->descent + fontGap * 2; } { int direction, ascent, descent; XCharStruct charStruct; XTextExtents(fontStruct, _label.c_str(), _label.length(), &direction, &ascent, &descent, &charStruct); _fontWindowWidth = charStruct.rbearing - charStruct.lbearing + fontGap * 2; _vGap = (_fontWindowHeight - (charStruct.ascent + charStruct.descent)) / 2; _hGap = fontGap; } }
/* * Pøipojit k serveru, zjistit o nìm informace */ static void open_display(void) { display_name = XDisplayName(NULL); if(!(display = XOpenDisplay(display_name))) { fprintf(stderr, "Cannot connect to X server \"%s\"\n", display_name); exit(1); } debug("Connected to X server \"%s\"\n", display_name); screen_num = DefaultScreen(display); screen = DefaultScreenOfDisplay(display); debug("Default screen number is %d\n", screen_num); screen_width = DisplayWidth(display, screen_num); screen_height = DisplayHeight(display, screen_num); screen_width_mm = DisplayWidthMM(display, screen_num); screen_height_mm = DisplayHeightMM(display, screen_num); debug("Screen size is %ux%u pixels, %ux%u mm\n", screen_width, screen_height, screen_width_mm, screen_height_mm); root = RootWindow(display, screen_num); black = BlackPixel(display, screen_num); white = WhitePixel(display, screen_num); debug("Root window ID is %#lx, black is %#lx, white is %#lx\n", root, black, white); def_gc = DefaultGC(display, screen_num); if(!(def_font = XQueryFont(display, XGContextFromGC(def_gc)))) { fprintf(stderr, "XQueryFont() failed\n"); exit(1); } }
NSTextField::NSTextField(unsigned int arg, NSTextListener* bl, void* la, NSTextCallback* bc, void* ca) : NSPlate(down), _listener(bl), _callback(bc), _listenerArg(la), _callbackArg(ca) { if (!initialized) { initialized = true; fontStruct = XQueryFont(NSdpy, font); gc = XCreateGC(NSdpy, window(), 0, 0); XSetForeground(NSdpy, gc, bgPixel() ^ BlackPixel(NSdpy, 0)); XSetFunction(NSdpy, gc, GXxor); } cursorPos = 0; strStart = 0; mode = down; cursorOnTF = false; width(arg); height(fontStruct->max_bounds.ascent + fontStruct->max_bounds.descent + gap * 2); selectInput(EnterWindowMask | LeaveWindowMask | KeyPressMask | ExposureMask | ButtonPressMask); // charWidth = fontStruct->max_bounds.rbearing - fontStruct->min_bounds.lbearing; charWidth = fontStruct->max_bounds.width - 1; // Can't figure out why, but this works. charHeight = fontStruct->max_bounds.ascent + fontStruct->max_bounds.descent; maxCharNum = width() / charWidth; selectIndex = SELEC_NONE; }
// Set up a window. int initWindow( long width, long height ) { int defScreen; XSetWindowAttributes wAttr; XGCValues gcValues; char buffer[64] = "Graphics"; XTextProperty xtp = {(unsigned char *)buffer, 125, 8, strlen(buffer)}; /* * connect to the X server. uses the server specified in the * DISPLAY environment variable */ curDisplay = XOpenDisplay((char *) NULL); if ((Display *) NULL == curDisplay) { fprintf(stderr, "Fish School Stats Display: could not open display.\n"); exit(-1); } /* * begin to create a window */ defdepth = DefaultDepth(curDisplay,0); bytesPerPixel = defdepth/8; bytesPerPixel = bytesPerPixel == 3 ? 4 : bytesPerPixel; defScreen = DefaultScreen(curDisplay); curWindow = XCreateWindow(curDisplay, DefaultRootWindow(curDisplay), 10, 10, width, height, 0, defdepth, InputOutput, DefaultVisual(curDisplay, defScreen), 0, &wAttr); /* * request mouse button and keypress events */ wAttr.event_mask = ButtonPressMask | KeyPressMask | ExposureMask; XChangeWindowAttributes(curDisplay, curWindow, CWEventMask, &wAttr); /* * force it to appear on the screen */ XSetWMName(curDisplay, curWindow, &xtp); XMapWindow(curDisplay, curWindow); /* * create a graphics context. this stores a drawing state; stuff like * current color and line width. this gc is for drawing into our * window. */ curGC = XCreateGC(curDisplay, curWindow, 0, &gcValues); defaultFont = XQueryFont(curDisplay, XGContextFromGC(curGC)); XSetWindowColormap( curDisplay, curWindow, DefaultColormapOfScreen(DefaultScreenOfDisplay(curDisplay))); return(bytesPerPixel); }
void load_font(){ char *font_name=conf_get_string("font",FONT); Font font=XLoadFont(dpy,font_name); XSetFont(dpy,gc,font); XGCValues v; XGetGCValues(dpy,gc,GCFont,&v); sfont=XQueryFont(dpy,v.font); }
void HelloWorld::_drawStringCentered(const GC& gc, const char* str, int x, int y, int w, int h) { int direction, ascent, descent; XCharStruct strDimensions; XTextExtents(XQueryFont(_display, XGContextFromGC(gc)), str, strlen(str), &direction, &ascent, &descent, &strDimensions); int newX = x + (w - strDimensions.width) / 2; int newY = y + (h + strDimensions.ascent - strDimensions.descent) / 2; _drawString(gc, str, newX, newY); }
// Return XFontStruct for given font name NAME XFontStruct *FontTable::operator[](const string& name) { int i = hash(name.chars()); while (table[i].font != 0 && name != table[i].name) { assert (i < MAX_FONTS); // Too many fonts i = (i >= MAX_FONTS) ? 0 : i + 1; } if (table[i].font == 0 && name != table[i].name) { // Insert new font table[i].name = name; table[i].font = XLoadQueryFont(_display, name.chars()); if (table[i].font == 0) { std::cerr << "Warning: Could not load font \"" << name << "\""; // Try default font GC default_gc = DefaultGCOfScreen(DefaultScreenOfDisplay(_display)); XGCValues gc_values; if (XGetGCValues(_display, default_gc, GCFont, &gc_values)) { const Font& font_id = gc_values.font; XFontStruct *font = XQueryFont(_display, font_id); if (font != 0) { std::cerr << ", using default font instead\n"; table[i].font = font; } } } if (table[i].font == 0) { // Try "fixed" font XFontStruct *font = XLoadQueryFont(_display, "fixed"); if (font != 0) { std::cerr << ", using font \"fixed\" instead\n"; table[i].font = font; } } if (table[i].font == 0) std::cerr << "\n"; } return table[i].font; }
int get_text_height () { XFontStruct * font = XQueryFont ( m_display, (GContext)id() ); if ( font ) { return font->max_bounds.ascent + font->max_bounds.descent; } else { return 0; } }
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 load_font(XFontStruct **font_info, char *fontname) { if ((*font_info = XLoadQueryFont(gXDisplay, fontname)) == NULL) { fprintf(stderr, "(HyperDoc) Cannot load font %s ; using default.\n", fontname); if ((*font_info = XQueryFont(gXDisplay, XGContextFromGC(DefaultGC(gXDisplay, gXScreenNumber)))) == NULL) { fprintf(stderr, "(HyperDoc) Cannot get default font ; exiting.\n"); exit(-1); } } }
/* * Set specified font for that GC. * Return font that is used for this GC, even if setting a new * font failed (return default font in that case). */ static XFontStruct* Set_font(Display* display, GC gc, const char* fontName, const char *resName) { XFontStruct* font; if ((font = XLoadQueryFont(display, fontName)) == NULL) { error("Couldn't find font '%s' for %s, using default font", fontName, resName); font = XQueryFont(display, XGContextFromGC(gc)); } else XSetFont(display, gc, font->fid); return font; }
PyObject * PaxFont_FromFont(Display *display, Font fid) { PaxFontObject *f = PyObject_New(PaxFontObject, &PaxFontType); if (f == NULL) return NULL; f->from_id = 1; f->display = display; f->font_struct = XQueryFont(display, fid); if (f->font_struct == NULL) { PyObject_Del(f); PyErr_SetString(PyExc_RuntimeError, "no such font"); return NULL; } return (PyObject *)f; }
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); }
void XPSDrawText(Display *display, Drawable drawable, GC context, int x, int y, char *s) { XFontStruct *finfo; int height; if (s == NULL) return; if (output_flag == XOUT) { XDrawImageString(display, drawable, context, x, y, s, strlen(s)); } else { finfo = XQueryFont(display, context->gid); height = finfo->ascent + finfo->descent; PSFont(height); PSMoveto(x, y); PSShow(s); } }
/* * 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 int X_init(__AA_CONST struct aa_hardware_params *p, __AA_CONST void *none,struct aa_hardware_params *dest, void **driverdata) { const char *font = "8x13bold"; static int registered; static aa_font aafont; __AA_CONST static struct aa_hardware_params def= {&aa_fontX13B, AA_DIM_MASK | AA_REVERSE_MASK | AA_NORMAL_MASK | AA_BOLD_MASK | AA_BOLDFONT_MASK | AA_EXTENDED, 0, 0, 0, 0, 80, 32, 0, 0}; struct xdriverdata *d; *dest=def; *driverdata=d=calloc(1,sizeof(*d)); d->previoust=NULL; d->previousa=NULL; d->cvisible=1; d->width=80; d->height=32; if ((d->dp = XOpenDisplay(NULL)) == NULL) return 0; d->screen = DefaultScreen(d->dp); if (getenv ("AAFont")) font = getenv ("AAFont"); d->font = XLoadFont(d->dp, font); if (!d->font) { XCloseDisplay(d->dp); return 0; } d->font_s = XQueryFont(d->dp, d->font); if (!d->font_s) { XCloseDisplay(d->dp); return 0; } d->fontheight = d->font_s->max_bounds.ascent + d->font_s->max_bounds.descent; d->fontwidth = d->font_s->max_bounds.rbearing - d->font_s->min_bounds.lbearing; d->realfontwidth = d->font_s->max_bounds.width; d->cmap = DefaultColormap(d->dp, d->screen); /*c.flags=DoRed | DoGreen | DoBlue; */ X_AllocColors (d); if (d->bold == d->normal) dest->supported &= ~AA_BOLD_MASK; if (d->dim == d->normal) dest->supported &= ~AA_DIM_MASK; d->attr.event_mask = ExposureMask; d->attr.override_redirect = False; if (p->width) d->width = p->width; if (p->height) d->height = p->height; if (p->maxwidth && d->width > p->maxwidth) d->width = p->maxwidth; if (p->minwidth && d->width < p->minwidth) d->width = p->minwidth; if (p->maxheight && d->height > p->maxheight) d->height = p->maxheight; if (p->minheight && d->height < p->minheight) d->height = p->minheight; d->wi = XCreateWindow(d->dp, RootWindow(d->dp, d->screen), 0, 0, d->width * d->realfontwidth, d->height * d->fontheight, 0, DefaultDepth(d->dp, d->screen), InputOutput, DefaultVisual(d->dp, d->screen), CWBackPixel | CWBorderPixel | CWEventMask, &d->attr); if (!registered) { d->pi = XCreatePixmap(d->dp, d->wi, d->fontwidth, d->fontheight * 256, 1); if (d->pi) { int i; unsigned char c; unsigned char *data; XImage *image; registered = 1; d->specialGC = XCreateGC(d->dp, d->pi, 0L, NULL); XSetForeground(d->dp, d->specialGC, 0); XSetBackground(d->dp, d->specialGC, 0); XFillRectangle(d->dp, d->pi, d->specialGC, 0, 0, d->fontwidth, 256 * d->fontheight); XSetForeground(d->dp, d->specialGC, 1); XSetFont(d->dp, d->specialGC, d->font); for (i = 0; i < 256; i++) { c = i; XDrawString(d->dp, d->pi, d->specialGC, 0, (i + 1) * d->fontheight - d->font_s->descent, (char *)&c, 1); } image = XGetImage(d->dp, d->pi, 0, 0, d->fontwidth, 256 * d->fontheight, 1, XYPixmap); if (image != NULL) { data = malloc(256 * d->fontheight); for (i = 0; i < 256; i++) { int y; font_error = 0; for (y = 0; y < d->fontheight; y++) { int o; o = ((mygetpixel(image, 0, i * d->fontheight + y) != 0) << 7) + ((mygetpixel(image, 1, i * d->fontheight + y) != 0) << 6) + ((mygetpixel(image, 2, i * d->fontheight + y) != 0) << 5) + ((mygetpixel(image, 3, i * d->fontheight + y) != 0) << 4) + ((mygetpixel(image, 4, i * d->fontheight + y) != 0) << 3) + ((mygetpixel(image, 5, i * d->fontheight + y) != 0) << 2) + ((mygetpixel(image, 6, i * d->fontheight + y) != 0) << 1) + ((mygetpixel(image, 7, i * d->fontheight + y) != 0) << 0); data[i * d->fontheight + y] = o; } } aafont.name = "Font used by X server"; aafont.shortname = "current"; aafont.height = d->fontheight; aafont.data = data; aa_registerfont(&aafont); dest->font = &aafont; } } } XStoreName(d->dp, d->wi, "aa for X"); XMapWindow(d->dp, d->wi); X_setinversionmode (getenv ("AAInverted") != NULL, d); d->pixelwidth = -1; d->pixelheight = -1; XSync(d->dp, 0); aa_recommendlowkbd("X11"); return 1; }
XFontStruct* GWindow::queryFont(Font fontID) { return XQueryFont(m_Display, fontID); }
int xinit() { if (!(dsp = XOpenDisplay(""))) { printf("Couldn't open display\n"); exit(1); } if (!(bigfont = XLoadFont(dsp, "fixed"))) { printf("Couldn't load font 12x24\n"); exit(1); } if (!(smallfont = XLoadFont(dsp, "fixed"))) { printf("Couldn't load font\n"); exit(1); } bfs = XQueryFont(dsp, bigfont); bwidth = bfs->max_bounds.width; bheight = bfs->ascent + bfs->descent + bfs->descent / 2; bdescent = bfs->descent; bascent = bfs->ascent + bfs->descent / 2; sfs = XQueryFont(dsp, smallfont); swidth = sfs->max_bounds.width; sheight = sfs->ascent + sfs->descent + sfs->descent / 2; sdescent = sfs->descent; sascent = sfs->ascent + sfs->descent / 2; cmap = DefaultColormap(dsp, 0); /* black.red=65535; black.green=65535; black.blue=65535; XAllocColor(dsp,cmap,&black); white.red=0; white.green=0; white.blue=0; XAllocColor(dsp,cmap,&white); yellow.pixel=white.pixel; blue.pixel=black.pixel; red.pixel=black.pixel; hred.pixel=black.pixel; hblue.pixel=black.pixel; */ black.red = 0; black.green = 0; black.blue = 0; XAllocColor(dsp, cmap, &black); white.red = 65535; white.green = 65535; white.blue = 65535; XAllocColor(dsp, cmap, &white); red.red = 65535; red.green = 0; red.blue = 0; XAllocColor(dsp, cmap, &red); green.red = 0; green.green = 65535; green.blue = 0; XAllocColor(dsp, cmap, &green); blue.red = 0; blue.green = 0; blue.blue = 65535; XAllocColor(dsp, cmap, &blue); yellow.red = 65535; yellow.green = 65535; yellow.blue = 0; XAllocColor(dsp, cmap, &yellow); magenta.red = 65535; magenta.green = 0; magenta.blue = 65535; XAllocColor(dsp, cmap, &magenta); cyan.red = 0; cyan.green = 65535; cyan.blue = 65535; XAllocColor(dsp, cmap, &cyan); hwhite.red = 45768; hwhite.green = 45768; hwhite.blue = 45768; XAllocColor(dsp, cmap, &hwhite); hred.red = 45768; hred.green = 0; hred.blue = 0; XAllocColor(dsp, cmap, &hred); hgreen.red = 0; hgreen.green = 45768; hgreen.blue = 0; XAllocColor(dsp, cmap, &hgreen); hblue.red = 0; hblue.green = 0; hblue.blue = 45768; XAllocColor(dsp, cmap, &hblue); hyellow.red = 45768; hyellow.green = 45768; hyellow.blue = 0; XAllocColor(dsp, cmap, &hyellow); hmagenta.red = 45768; hmagenta.green = 0; hmagenta.blue = 45768; XAllocColor(dsp, cmap, &hmagenta); hcyan.red = 0; hcyan.green = 45768; hcyan.blue = 45768; XAllocColor(dsp, cmap, &hcyan); }
/** * 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); }
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); }
/* ARGSUSED */ static void Initialize ( Widget greq, Widget gnew, ArgList args, Cardinal *num_args) { LoginWidget w = (LoginWidget)gnew; XtGCMask valuemask, xvaluemask; XGCValues myXGCV; Arg position[2]; Position x, y; #ifdef USE_XINERAMA XineramaScreenInfo *screens; int s_num; #endif #ifdef XPM myXGCV.foreground = w->login.hipixel; myXGCV.background = w->core.background_pixel; valuemask = GCForeground | GCBackground; w->login.hiGC = XtGetGC(gnew, valuemask, &myXGCV); myXGCV.foreground = w->login.shdpixel; myXGCV.background = w->core.background_pixel; valuemask = GCForeground | GCBackground; w->login.shdGC = XtGetGC(gnew, valuemask, &myXGCV); #endif /* XPM */ myXGCV.foreground = w->login.textpixel; myXGCV.background = w->core.background_pixel; valuemask = GCForeground | GCBackground; if (w->login.font) { myXGCV.font = w->login.font->fid; valuemask |= GCFont; } w->login.textGC = XtGetGC(gnew, valuemask, &myXGCV); myXGCV.foreground = w->core.background_pixel; w->login.bgGC = XtGetGC(gnew, valuemask, &myXGCV); myXGCV.foreground = w->login.textpixel ^ w->core.background_pixel; myXGCV.function = GXxor; xvaluemask = valuemask | GCFunction; w->login.xorGC = XtGetGC (gnew, xvaluemask, &myXGCV); /* * Note that the second argument is a GCid -- QueryFont accepts a GCid and * returns the curently contained font. */ if (w->login.font == NULL) w->login.font = XQueryFont (XtDisplay (w), XGContextFromGC (XDefaultGCOfScreen (XtScreen (w)))); xvaluemask = valuemask; if (w->login.promptFont == NULL) w->login.promptFont = w->login.font; else xvaluemask |= GCFont; myXGCV.foreground = w->login.promptpixel; myXGCV.font = w->login.promptFont->fid; w->login.promptGC = XtGetGC (gnew, xvaluemask, &myXGCV); xvaluemask = valuemask; if (w->login.greetFont == NULL) w->login.greetFont = w->login.font; else xvaluemask |= GCFont; myXGCV.foreground = w->login.greetpixel; myXGCV.font = w->login.greetFont->fid; w->login.greetGC = XtGetGC (gnew, xvaluemask, &myXGCV); xvaluemask = valuemask; if (w->login.failFont == NULL) w->login.failFont = w->login.font; else xvaluemask |= GCFont; myXGCV.foreground = w->login.failpixel; myXGCV.font = w->login.failFont->fid; w->login.failGC = XtGetGC (gnew, xvaluemask, &myXGCV); #ifdef XPM w->login.logoValid = False; if (NULL != w->login.logoFileName) { XpmAttributes myAttributes = { 0 }; Window tmpWindow = { 0 }; struct stat myBuffer = { 0 }; unsigned int myPixmapDepth = 0; if (0 != stat(w->login.logoFileName, &myBuffer)) { LogError("Unable to stat() pixmap file %s\n", w->login.logoFileName); w->login.logoValid = False; goto SkipXpmLoad; } else myAttributes.valuemask |= XpmReturnPixels; myAttributes.valuemask |= XpmReturnExtensions; XpmReadFileToPixmap(XtDisplay(w), /* display */ RootWindowOfScreen(XtScreen(w)), /* window */ w->login.logoFileName, /* XPM filename */ &(w->login.logoPixmap), /* pixmap */ &(w->login.logoMask), /* pixmap mask */ &myAttributes); /* XPM attributes */ w->login.logoValid = True; XGetGeometry(XtDisplay(w), w->login.logoPixmap, &tmpWindow, &(w->login.logoX), &(w->login.logoY), &(w->login.logoWidth), &(w->login.logoHeight), &(w->login.logoBorderWidth), &myPixmapDepth); } else { w->login.logoX = 0; w->login.logoY = 0; w->login.logoWidth = 0; w->login.logoHeight = 0; w->login.logoBorderWidth = 0; } SkipXpmLoad: #endif /* XPM */ w->login.data.name[0] = '\0'; w->login.data.passwd[0] = '\0'; w->login.state = GET_NAME; w->login.cursor = 0; w->login.failUp = 0; if (w->core.width == 0) w->core.width = max (GREET_W(w), FAIL_W(w)) + PAD_X(w); if (w->core.height == 0) { int fy = FAIL_Y(w); int pady = PAD_Y(w); #ifndef XPM w->core.height = fy + pady; /* for stupid compilers */ #else /* w->core.height = fy + pady; * for stupid compilers */ w->core.height = max(fy + pady, (w->login.logoHeight + (2*w->login.logoPadding)) + pady); #endif /* XPM */ } #ifdef USE_XINERAMA if ( XineramaIsActive(XtDisplay(w)) && (screens = XineramaQueryScreens(XtDisplay(w), &s_num)) != NULL ) { if ((x = w->core.x) == -1) x = screens[0].x_org + (int)(screens[0].width - w->core.width) / 2; if ((y = w->core.y) == -1) y = screens[0].y_org + (int)(screens[0].height - w->core.height) / 3; XFree(screens); } else #endif { if ((x = w->core.x) == -1) x = (int)(XWidthOfScreen (XtScreen (w)) - w->core.width) / 2; if ((y = w->core.y) == -1) y = (int)(XHeightOfScreen (XtScreen (w)) - w->core.height) / 3; } XtSetArg (position[0], XtNx, x); XtSetArg (position[1], XtNy, y); XtSetValues (XtParent (w), position, (Cardinal) 2); }
void screen(int width, int height) { int a,r; if ((display=XOpenDisplay(NULL)) == NULL) { fprintf(stderr,"Could not connect to X server; not using X.\n"); exit(1); } scr_ptr = DefaultScreenOfDisplay(display); screen_num = DefaultScreen(display); for(a=0; a<32; a++) { r=XAllocNamedColor(display,DefaultColormap(display,screen_num),\ colornames[a],&screen_color,&exact_color); if(r==0) { fprintf(stderr,"Could not allocate color '%s'.\n",colornames[a]); exit(1); } colors[a]=screen_color.pixel; if(a==0) cursorbg=screen_color; if(a==1) cursorfg=screen_color; } totalw=width*mag; totalh=height*mag; fontwidth=0; fontheight=0; font=XLoadFont(display,fontname); if(font==BadName) { fprintf(stderr,"Font %s not found, trying \"fixed\".\n",fontname); font=XLoadFont(display,"fixed"); if(font==BadName) { fprintf(stderr,"Fixed font not found. Giving up.\n"); exit(1); } } fontinfo=XQueryFont(display,font); fontwidth=XTextWidth(fontinfo,"Z",1); fontheight=fontinfo->ascent+fontinfo->descent; if(statusline) { totalh+=fontheight+2; } main_pixmap=XCreatePixmap(display,DefaultRootWindow(display),\ totalw,totalh,DefaultDepth(display,screen_num)); main_win = XCreateSimpleWindow(display,DefaultRootWindow(display), \ 0,0,totalw,totalh,1,colors[1],colors[0]); the_GC = XCreateGC(display,main_win,0,0); XSetForeground(display,the_GC,0); XSetFont(display,the_GC,font); XStoreName(display,main_win,"xmaze"); XMapWindow(display,main_win); XSelectInput(display, main_win, ButtonReleaseMask|ButtonPressMask|ExposureMask|VisibilityChangeMask); XSetGraphicsExposures(display,the_GC,True); XSetForeground(display,the_GC,colors[bg]); XSetBackground(display,the_GC,colors[bg]); XFillRectangle(display,main_pixmap,the_GC,0,0,totalw,totalh); XFillRectangle(display,main_win,the_GC,0,0,totalw,totalh); XSetForeground(display,the_GC,colors[fg]); // cursor = XCreateFontCursor(display,XC_crosshair); // XDefineCursor(display,main_win,cursor); // // This is why X11 turns off a many budding programmers: // Make the cursor a simple red box: // cursorsource=XCreatePixmap(display,DefaultRootWindow(display),\ mag,mag,1); cursormask=XCreatePixmap(display,DefaultRootWindow(display),\ mag,mag,1); XAllocNamedColor(display,DefaultColormap(display,screen_num),\ colornames[1],&screen_color,&exact_color); cursorbg=screen_color; XAllocNamedColor(display,DefaultColormap(display,screen_num),\ colornames[0],&screen_color,&exact_color); cursorbg=screen_color; gc_mask = GCForeground; xgcv.foreground = 0; gcbg=XCreateGC(display,cursorsource,gc_mask,&xgcv); gc_mask = GCForeground; xgcv.foreground = 1; gcfg=XCreateGC(display,cursorsource,gc_mask,&xgcv); XFillRectangle(display,cursormask,gcfg,0,0,mag,mag); XFillRectangle(display,cursorsource,gcfg,0,0,mag,mag); cursor=XCreatePixmapCursor(display,cursorsource,cursormask,&cursorfg,&cursorbg,mag/2,mag/2); XDefineCursor(display,main_win,cursor); // See how simple that was? wmDeleteMessage = XInternAtom(display, "WM_DELETE_WINDOW", False); XSetWMProtocols(display, main_win, &wmDeleteMessage, 1); expose(); }
void captureXFont(Display * dpy, Font font, char *xfont, char *name) { int first, last, count; int cnt, len; Pixmap offscreen; Window drawable; XFontStruct *fontinfo; XImage *image; GC xgc; XGCValues values; int width, height; int i, j, k; XCharStruct *charinfo; XChar2b character; GLubyte *bitmapData; int x, y; int spanLength; int charWidth, charHeight, maxSpanLength, pixwidth; int grabList[MAX_GLYPHS_PER_GRAB]; int glyphsPerGrab = MAX_GLYPHS_PER_GRAB; int numToGrab; int rows, pages, byte1, byte2, index; int nullBitmap; drawable = RootWindow(dpy, DefaultScreen(dpy)); fontinfo = XQueryFont(dpy, font); pages = fontinfo->max_char_or_byte2 - fontinfo->min_char_or_byte2 + 1; first = (fontinfo->min_byte1 << 8) + fontinfo->min_char_or_byte2; last = (fontinfo->max_byte1 << 8) + fontinfo->max_char_or_byte2; count = last - first + 1; width = fontinfo->max_bounds.rbearing - fontinfo->min_bounds.lbearing; height = fontinfo->max_bounds.ascent + fontinfo->max_bounds.descent; /* 16-bit fonts have more than one row; indexing into per_char is trickier. */ rows = fontinfo->max_byte1 - fontinfo->min_byte1 + 1; maxSpanLength = (width + 7) / 8; /* For portability reasons we don't use alloca for bitmapData, but we could. */ bitmapData = malloc(height * maxSpanLength); /* Be careful determining the width of the pixmap; the X protocol allows pixmaps of width 2^16-1 (unsigned short size) but drawing coordinates max out at 2^15-1 (signed short size). If the width is too large, we need to limit the glyphs per grab. */ if ((glyphsPerGrab * 8 * maxSpanLength) >= (1 << 15)) { glyphsPerGrab = (1 << 15) / (8 * maxSpanLength); } pixwidth = glyphsPerGrab * 8 * maxSpanLength; offscreen = XCreatePixmap(dpy, drawable, pixwidth, height, 1); values.font = font; values.background = 0; values.foreground = 0; xgc = XCreateGC(dpy, offscreen, GCFont | GCBackground | GCForeground, &values); XFillRectangle(dpy, offscreen, xgc, 0, 0, 8 * maxSpanLength * glyphsPerGrab, height); XSetForeground(dpy, xgc, 1); numToGrab = 0; if (fontinfo->per_char == NULL) { charinfo = &(fontinfo->min_bounds); charWidth = charinfo->rbearing - charinfo->lbearing; charHeight = charinfo->ascent + charinfo->descent; spanLength = (charWidth + 7) / 8; } printf("\n/* GENERATED FILE -- DO NOT MODIFY */\n\n"); printf("#include \"glutbitmap.h\"\n\n"); for (i = first; count; i++, count--) { int undefined; if (rows == 1) { undefined = (fontinfo->min_char_or_byte2 > i || fontinfo->max_char_or_byte2 < i); } else { byte2 = i & 0xff; byte1 = i >> 8; undefined = (fontinfo->min_char_or_byte2 > byte2 || fontinfo->max_char_or_byte2 < byte2 || fontinfo->min_byte1 > byte1 || fontinfo->max_byte1 < byte1); } if (undefined) { goto PossiblyDoGrab; } if (fontinfo->per_char != NULL) { if (rows == 1) { index = i - fontinfo->min_char_or_byte2; } else { byte2 = i & 0xff; byte1 = i >> 8; index = (byte1 - fontinfo->min_byte1) * pages + (byte2 - fontinfo->min_char_or_byte2); } charinfo = &(fontinfo->per_char[index]); charWidth = charinfo->rbearing - charinfo->lbearing; charHeight = charinfo->ascent + charinfo->descent; if (charWidth == 0 || charHeight == 0) { if (charinfo->width != 0) { /* Still must move raster pos even if empty character */ outputChar(i, 0, 0, 0, 0, charinfo->width, 0); } goto PossiblyDoGrab; } } grabList[numToGrab] = i; character.byte2 = i & 255; character.byte1 = i >> 8; /* XXX We could use XDrawImageString16 which would also paint the backing rectangle but X server bugs in some scalable font rasterizers makes it more effective to do XFillRectangles to clear the pixmap and then XDrawImage16 for the text. */ XDrawString16(dpy, offscreen, xgc, -charinfo->lbearing + 8 * maxSpanLength * numToGrab, charinfo->ascent, &character, 1); numToGrab++; PossiblyDoGrab: if (numToGrab >= glyphsPerGrab || count == 1) { image = XGetImage(dpy, offscreen, 0, 0, pixwidth, height, 1, XYPixmap); for (j = numToGrab - 1; j >= 0; j--) { if (fontinfo->per_char != NULL) { byte2 = grabList[j] & 0xff; byte1 = grabList[j] >> 8; index = (byte1 - fontinfo->min_byte1) * pages + (byte2 - fontinfo->min_char_or_byte2); charinfo = &(fontinfo->per_char[index]); charWidth = charinfo->rbearing - charinfo->lbearing; charHeight = charinfo->ascent + charinfo->descent; spanLength = (charWidth + 7) / 8; } memset(bitmapData, 0, height * spanLength); for (y = 0; y < charHeight; y++) { for (x = 0; x < charWidth; x++) { if (XGetPixel(image, j * maxSpanLength * 8 + x, charHeight - 1 - y)) { /* Little endian machines (such as DEC Alpha) could benefit from reversing the bit order here and changing the GL_UNPACK_LSB_FIRST parameter in glutBitmapCharacter to GL_TRUE. */ bitmapData[y * spanLength + x / 8] |= (1 << (7 - (x & 7))); } } } if (PRINTABLE(grabList[j])) { printf("/* char: 0x%x '%c' */\n\n", grabList[j], grabList[j]); } else { printf("/* char: 0x%x */\n\n", grabList[j]); } /* Determine if the bitmap is null. */ nullBitmap = 1; len = (charinfo->ascent + charinfo->descent) * ((charinfo->rbearing - charinfo->lbearing + 7) / 8); cnt = 0; while (cnt < len) { for (k = 0; k < 16 && cnt < len; k++, cnt++) { if (bitmapData[cnt] != 0) { nullBitmap = 0; } } } if (!nullBitmap) { printf("static const GLubyte ch%ddata[] = {\n", grabList[j]); len = (charinfo->ascent + charinfo->descent) * ((charinfo->rbearing - charinfo->lbearing + 7) / 8); cnt = 0; while (cnt < len) { for (k = 0; k < 16 && cnt < len; k++, cnt++) { printf("0x%x,", bitmapData[cnt]); } printf("\n"); } printf("};\n\n"); } else { charWidth = 0; charHeight = 0; } outputChar(grabList[j], charWidth, charHeight, -charinfo->lbearing, charinfo->descent, charinfo->width, !nullBitmap); } XDestroyImage(image); numToGrab = 0; if (count > 0) { XSetForeground(dpy, xgc, 0); XFillRectangle(dpy, offscreen, xgc, 0, 0, 8 * maxSpanLength * glyphsPerGrab, height); XSetForeground(dpy, xgc, 1); } }
void InitWindow(int argc, char **argv) { XGCValues gc_values; XWMHints wmhints; Widget w; XClassHint classHint; GC iconGC; progName = (char *)rindex(argv[0], '/'); if (progName) progName++; else progName = argv[0]; /* * We cheat here by using the Toolkit to do the initialization work. * We just ignore the top-level widget that gets created. */ w = XtAppInitialize(&app_con, progName, opTable, XtNumber(opTable), &argc, argv, default_resources, NULL, ZERO); if ((argc > 1) && (strcmp("-robot", argv[1]) == 0)) { argc--; app_resources.robotic = TRUE; } else {app_resources.robotic = FALSE;} printf("set robot. "); dpy = XtDisplay(w); screen = DefaultScreen(dpy); printf("set Xscreen. "); XtGetApplicationResources(w, (caddr_t) &app_resources, resources, XtNumber(resources), NULL, (Cardinal) 0); printf("set XResource. "); if (!app_resources.scoreFont) MWError("cannot open font"); scoreFontInfo = XQueryFont(dpy, app_resources.scoreFont); printf("set XQueue. "); cur_width = MIN_X_DIM; cur_height = MIN_Y_DIM + (MAX_RATS+1) * (scoreFontInfo->max_bounds.ascent + scoreFontInfo->max_bounds.descent); mwWindow = XCreateSimpleWindow(dpy, RootWindow(dpy, screen), 0, 0, cur_width, cur_height, app_resources.borderWidth, 0, app_resources.bg_pixel); XStoreName(dpy, mwWindow, "MazeWar"); XSetIconName(dpy, mwWindow, "MazeWar"); classHint.res_name = "cs244Bmazewar"; classHint.res_class = "cs244Bmazewar"; XSetClassHint(dpy, mwWindow, &classHint); gc_values.function = GXcopy; gc_values.foreground = app_resources.fg_pixel; gc_values.background = app_resources.bg_pixel; gc_values.font = app_resources.scoreFont; gc_values.line_width = 0; copyGC = XCreateGC(dpy, mwWindow, GCFunction | GCForeground | GCBackground | GCLineWidth | GCFont, &gc_values); gc_values.function = GXxor; gc_values.plane_mask = AllPlanes; gc_values.foreground = app_resources.fg_pixel ^ app_resources.bg_pixel; gc_values.background = 0; xorGC = XCreateGC(dpy, mwWindow, GCFunction | GCForeground | GCBackground | GCPlaneMask, &gc_values); icon_pixmap = XCreatePixmapFromBitmapData( dpy, mwWindow, (char *)icon_bits, icon_width, icon_height, app_resources.fg_pixel, app_resources.bg_pixel, XDefaultDepth(dpy, screen)); /* is this even used? */ gc_values.function = GXclear; gc_values.plane_mask = AllPlanes; iconGC = XCreateGC(dpy, mwWindow, GCFunction | GCPlaneMask, &gc_values); iconmask_pixmap = XCreatePixmap(dpy, mwWindow, icon_width, icon_height, XDefaultDepth(dpy, screen)); XFillRectangle(dpy, iconmask_pixmap, iconGC, 0, 0, icon_width, icon_height); icon_reverse_pixmap = XCreatePixmapFromBitmapData(dpy, mwWindow, (char *)icon_bits, icon_width, icon_height, app_resources.bg_pixel, app_resources.fg_pixel, XDefaultDepth(dpy, screen)); wmhints.input = TRUE; wmhints.flags = IconPixmapHint | IconMaskHint | InputHint; wmhints.icon_pixmap = icon_pixmap; wmhints.icon_mask = iconmask_pixmap; XSetWMHints(dpy, mwWindow, &wmhints); initCursors(); arrowImage = XCreateImage(dpy, DefaultVisual(dpy, DefaultScreen(dpy)), 1, XYBitmap, 0, NULL, 16, 16, 8, 2); arrowImage->byte_order = MSBFirst; arrowImage->bitmap_bit_order = MSBFirst; }
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)); }
FontInfoPtr SuckGlyphsFromServer(Display * dpy, Font font) { Pixmap offscreen; XFontStruct *fontinfo; XImage *image; GC xgc; XGCValues values; int numchars; int width, height, pixwidth; int i, j; XCharStruct *charinfo; XChar2b character; char *bitmapData; int x, y; int spanLength; int charWidth, charHeight, maxSpanLength; int grabList[MAX_GLYPHS_PER_GRAB]; int glyphsPerGrab = MAX_GLYPHS_PER_GRAB; int numToGrab, thisglyph; FontInfoPtr myfontinfo; fontinfo = XQueryFont(dpy, font); if (!fontinfo) return NULL; numchars = fontinfo->max_char_or_byte2 - fontinfo->min_char_or_byte2 + 1; if (numchars < 1) return NULL; myfontinfo = (FontInfoPtr) malloc(sizeof(FontInfo) + (numchars - 1) * sizeof(PerCharInfo)); if (!myfontinfo) return NULL; myfontinfo->min_char = fontinfo->min_char_or_byte2; myfontinfo->max_char = fontinfo->max_char_or_byte2; myfontinfo->max_ascent = fontinfo->max_bounds.ascent; myfontinfo->max_descent = fontinfo->max_bounds.descent; myfontinfo->dlist_base = 0; width = fontinfo->max_bounds.rbearing - fontinfo->min_bounds.lbearing; height = fontinfo->max_bounds.ascent + fontinfo->max_bounds.descent; maxSpanLength = (width + 7) / 8; /* * Be careful determining the width of the pixmap; the X protocol allows * pixmaps of width 2^16-1 (unsigned short size) but drawing coordinates * max out at 2^15-1 (signed short size). If the width is too large, * we need to limit the glyphs per grab. */ if ((glyphsPerGrab * 8 * maxSpanLength) >= (1 << 15)) { glyphsPerGrab = (1 << 15) / (8 * maxSpanLength); } pixwidth = glyphsPerGrab * 8 * maxSpanLength; offscreen = XCreatePixmap(dpy, RootWindow(dpy, DefaultScreen(dpy)), pixwidth, height, 1); values.font = font; values.background = 0; values.foreground = 0; xgc = XCreateGC(dpy, offscreen, GCFont | GCBackground | GCForeground, &values); XFillRectangle(dpy, offscreen, xgc, 0, 0, 8 * maxSpanLength * glyphsPerGrab, height); XSetForeground(dpy, xgc, 1); numToGrab = 0; if (fontinfo->per_char == NULL) { charinfo = &(fontinfo->min_bounds); charWidth = charinfo->rbearing - charinfo->lbearing; charHeight = charinfo->ascent + charinfo->descent; spanLength = (charWidth + 7) / 8; } for (i = 0; i < numchars; i++) { if (fontinfo->per_char != NULL) { charinfo = &(fontinfo->per_char[i]); charWidth = charinfo->rbearing - charinfo->lbearing; charHeight = charinfo->ascent + charinfo->descent; if (charWidth == 0 || charHeight == 0) { /* Still must move raster pos even if empty character */ myfontinfo->glyph[i].width = 0; myfontinfo->glyph[i].height = 0; myfontinfo->glyph[i].xoffset = 0; myfontinfo->glyph[i].yoffset = 0; myfontinfo->glyph[i].advance = charinfo->width; myfontinfo->glyph[i].bitmap = NULL; goto PossiblyDoGrab; } } grabList[numToGrab] = i; /* XXX is this right for large fonts? */ character.byte2 = (i + fontinfo->min_char_or_byte2) & 255; character.byte1 = (i + fontinfo->min_char_or_byte2) >> 8; /* * XXX we could use XDrawImageString16 which would also paint the * backing rectangle but X server bugs in some scalable font * rasterizers makes it more effective to do XFillRectangles to clear * the pixmap and XDrawImage16 for the text. */ XDrawString16(dpy, offscreen, xgc, -charinfo->lbearing + 8 * maxSpanLength * numToGrab, charinfo->ascent, &character, 1); numToGrab++; PossiblyDoGrab: if (numToGrab >= glyphsPerGrab || i == numchars - 1) { image = XGetImage(dpy, offscreen, 0, 0, pixwidth, height, 1, XYPixmap); for (j = 0; j < numToGrab; j++) { thisglyph = grabList[j]; if (fontinfo->per_char != NULL) { charinfo = &(fontinfo->per_char[thisglyph]); charWidth = charinfo->rbearing - charinfo->lbearing; charHeight = charinfo->ascent + charinfo->descent; spanLength = (charWidth + 7) / 8; } bitmapData = calloc(height * spanLength, sizeof(char)); if (!bitmapData) goto FreeFontAndReturn; DEBUG_GLYPH4("index %d, glyph %d (%d by %d)\n", j, thisglyph + fontinfo->min_char_or_byte2, charWidth, charHeight); for (y = 0; y < charHeight; y++) { for (x = 0; x < charWidth; x++) { /* * XXX The algorithm used to suck across the font ensures * that each glyph begins on a byte boundary. In theory * this would make it convienent to copy the glyph into * a byte oriented bitmap. We actually use the XGetPixel * function to extract each pixel from the image which is * not that efficient. We could either do tighter packing * in the pixmap or more efficient extraction from the * image. Oh well. */ if (XGetPixel(image, j * maxSpanLength * 8 + x, charHeight - 1 - y)) { DEBUG_GLYPH("x"); bitmapData[y * spanLength + x / 8] |= (1 << (x & 7)); } else { DEBUG_GLYPH(" "); } } DEBUG_GLYPH("\n"); } myfontinfo->glyph[thisglyph].width = charWidth; myfontinfo->glyph[thisglyph].height = charHeight; myfontinfo->glyph[thisglyph].xoffset = -charinfo->lbearing; myfontinfo->glyph[thisglyph].yoffset = charinfo->descent; myfontinfo->glyph[thisglyph].advance = charinfo->width; myfontinfo->glyph[thisglyph].bitmap = bitmapData; } XDestroyImage(image); numToGrab = 0; /* do we need to clear the offscreen pixmap to get more? */ if (i < numchars - 1) { XSetForeground(dpy, xgc, 0); XFillRectangle(dpy, offscreen, xgc, 0, 0, 8 * maxSpanLength * glyphsPerGrab, height); XSetForeground(dpy, xgc, 1); } } } XFreeGC(dpy, xgc); XFreePixmap(dpy, offscreen); return myfontinfo; FreeFontAndReturn: XDestroyImage(image); XFreeGC(dpy, xgc); XFreePixmap(dpy, offscreen); for (j = i - 1; j >= 0; j--) { if (myfontinfo->glyph[j].bitmap) free(myfontinfo->glyph[j].bitmap); } free(myfontinfo); return NULL; }
/** * 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); }