X11 Why I can't draw any text?

2019-07-10 20:02发布


I'm trying to learn X11. It's very hard to me, because I don't have experience with window applications on Linux.
I wrote some simple code and I can't resolve this not visible text problem. Everything is working good probably, when I was trying to draw rectangle with DrawRectangle function it was working.
Here is the code:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <X11/Xlib.h>
int main()
{
Display* myDisplay;
Window myWindow;
int myScreen;
GC myGC;
XEvent myEvent;
unsigned long black, white;
char* hello = "Hello world!";
XFontStruct* myFont;

if((myDisplay = XOpenDisplay(NULL)) == NULL)
{
    puts("Error in conneting to X Server!");
    return -1;
}
myScreen = DefaultScreen(myDisplay);
black = BlackPixel(myDisplay, myScreen);
white = WhitePixel(myDisplay, myScreen);

myWindow = XCreateSimpleWindow(myDisplay, RootWindow(myDisplay, myScreen), 0, 0, 640, 320, 5, black, white);

XSelectInput(myDisplay, myWindow, ExposureMask);

XClearWindow(myDisplay, myWindow);
XMapWindow(myDisplay, myWindow);

myGC = XCreateGC(myDisplay, myWindow, 0, 0);
XSetForeground(myDisplay, myGC, black);
XSetBackground(myDisplay, myGC, white);

myFont = XLoadQueryFont(myDisplay, "-Misc-Fixed-Medium-R-Normal--7-70-75-75-C-50-ISO10646-1");
XSetFont(myDisplay, myGC, myFont->fid);

while(1)
{
    XNextEvent(myDisplay, &myEvent);

    if(myEvent.type == Expose)
    {
        XClearWindow(myDisplay, myWindow);
// HERE I DONT KNOW WHY IT DOESNT WORK!
        XDrawString(myDisplay, myWindow, myGC, 0, 0, hello, strlen(hello)); 
    }   
}

XFreeGC(myDisplay, myGC);
XDestroyWindow(myDisplay, myWindow);
XCloseDisplay(myDisplay);

return 0;
}

Thank you for help!

标签: c linux text x11
1条回答
做个烂人
2楼-- · 2019-07-10 20:48

Your font path argument to XLoadQueryFont is wrong (on my Linux/Debian desktop). Check with the xlsfonts command the right ones (they are all lowercases).

With

  myFont = XLoadQueryFont 
      (myDisplay,
        "-misc-fixed-medium-r-normal--9-90-75-75-c-60-iso10646-1");

it could work better. Try also with "lucidasanstypewriter-bold-14"

And most importantly the coordinates passed to XDrawString are wrong. Remember that they are the coordinates of the baseline of your text. And x=0, y=0 is the top left corner of the window, and y is growing downwards and x is growing to the right. Hence your text is drawn off-window, above its top. So y should be positive and more than the font height.

Try

  XDrawString (myDisplay, myWindow, myGC, 15, 20, hello,
           strlen (hello));

As I commented, you need to handle a lot more events.


I don't have experience with window applications on Linux.

And to learn about GUI programming, I strongly recommend first using some toolkit like GTK or Qt or perhaps SDL.

Raw X11 programming is too hard (and by the time you'll learn it is will be obsolete, e.g. by Wayland), in particular because an X11 application needs to be ICCCM & EWMH compliant. Notice that the entire X11 documentation requires nearly ten thousand pages.

See also https://tronche.com/gui/x/xlib/

BTW, most Linux GUI applications are drawing pixmap client side and sending it to the X11 server. Read about compositing window managers. Drawing requests like XDrawString are no more used anymore in practice. Recent font related libraries like libfontconfig, libXft, etc are working on the client side.

查看更多
登录 后发表回答