Login
Immutable PageDiscussionInfoAttachments

Please use a more selective search term instead of ""

Clear message
clear/wm_devel/2011-08-23

MMA

テキストの描画

"hello, world."とか表示してみる。

GC

何かを描画するには、なにはともあれGC(Graphics Context)が必要になる。ということで作る。

XCreateGC
グラフィクスコンテキストを作成する

GC XCreateGC(Display *display, Drawable d, unsigned long valuemask, XGCValues *values);

ということで何も考えずに作るとこんな感じ。

   1 Display *d;
   2 Window w;
   3 GC gc = XCreateGC(d, w, 0, NULL);

破棄はXFreeGC()で行う。

文字列描画

とりあえず非マルチバイト文字のみ。一番単純なのはこれ。

XDrawString
文字列を描画する

int XDrawString(Display *display, Drawable d, GC gc, int x, int y, char *string, int length);

これだけでは物足りないのでフォントを設定する。といっても難しくない。

   1 GC gc;
   2 /* ... */
   3 XFontStruct *fn;
   4 fn = XLoadQueryFont(d, "-adobe-helvetica-medium-r-normal--14-*-*-*-*-*-*-*"); /* XLFD */
   5 XSetFont(d, gc, fn->fid);
   6 /* ... */
   7 XFreeFont(d, fn); /* 破棄 */

hello, world

ということで、ウィンドウの中央に"hello, world."と表示するだけのプログラム。

   1 #include <X11/Xlib.h>
   2 #include <X11/Xutil.h>
   3 #include <stdio.h>
   4 #include <stdlib.h>
   5 #include <string.h>
   6 #include <locale.h>
   7 
   8 /* functions */
   9 int event_loop(void);
  10 GC initgc(void);
  11 void draw(GC gc);
  12 
  13 /* global variables */
  14 Display *d;
  15 Window w;
  16 Atom wm_delete_window;
  17 XFontStruct *fn;
  18 
  19 int main(int argc, char **argv)
  20 {
  21     int status;
  22 
  23     if (!setlocale(LC_CTYPE, "") || !XSupportsLocale())
  24         fputs("warning: locale not supported", stderr);
  25 
  26     d = XOpenDisplay(NULL);
  27     if (!d) {
  28         fprintf(stderr, "failed to open display\n");
  29         exit(1);
  30     }
  31     w = XCreateSimpleWindow(
  32             d, DefaultRootWindow(d), 0, 0, 400, 300, 1,
  33             BlackPixel(d, 0), WhitePixel(d, 0));
  34     XmbSetWMProperties(d, w, "文字列の描画", NULL, argv, argc, NULL, NULL, NULL);
  35 
  36     wm_delete_window = XInternAtom(d, "WM_DELETE_WINDOW", False);
  37     XSetWMProtocols(d, w, &wm_delete_window, 1);
  38 
  39     XMapWindow(d, w);
  40     XFlush(d);
  41 
  42     XSelectInput(d, w, ExposureMask | StructureNotifyMask);
  43     status = event_loop();
  44     XCloseDisplay(d);
  45 
  46     return status;
  47 }
  48 
  49 int event_loop(void)
  50 {
  51     XEvent event;
  52     GC gc;
  53 
  54     if (!(gc = initgc())) {
  55         fputs("failed to initialize GC", stderr);
  56         return 1;
  57     }
  58     fn = XLoadQueryFont(d, "-adobe-helvetica-medium-r-normal--14-*-*-*-*-*-*-*");
  59     if (!fn) {
  60         fputs("failed to load fn", stderr);
  61     } else {
  62         XSetFont(d, gc, fn->fid);
  63     }
  64     for (;;) {
  65         XNextEvent(d, &event);
  66 
  67         switch (event.type) {
  68         case Expose:
  69             draw(gc);
  70             break;
  71 
  72         case ClientMessage:
  73             if ((Atom)event.xclient.data.l[0] == wm_delete_window)
  74                 XDestroyWindow(d, w);
  75             break;
  76 
  77         case DestroyNotify:
  78             return 0;
  79         }
  80     }
  81     XFreeGC(d, gc);
  82     XFreeFont(d, fn);
  83 }
  84 
  85 GC initgc(void)
  86 {
  87     GC gc = XCreateGC(d, w, 0, NULL);
  88     return gc;
  89 }
  90 
  91 void draw(GC gc)
  92 {
  93     char *text = "hello, world.";
  94     int len = strlen(text);
  95     XWindowAttributes att;
  96     int t_width, t_height;
  97     int x, y;
  98 
  99     XGetWindowAttributes(d, w, &att);
 100     t_width = XTextWidth(fn, text, len);
 101     t_height = fn->ascent + fn->descent;
 102 
 103     x = (att.width - t_width) / 2;
 104     y = (att.height - t_height) / 2;
 105 
 106     XDrawString(d, w, gc, x, y, text, len);
 107 }

問題点