2


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!

y3v4d
  • 195
  • 14
  • 1
    As a sidenote: you are aware X11 is currently being replaced by Wayland? (es, I know this will take years, if not decades) I don't want to talk you into something, but wouldn't learning a more modern graphics system be better? – too honest for this site Jun 10 '17 at 18:32
  • 1
    @Olaf Ooo, good to know it. But i saw many application wroted in X11, and it is probably the basic of basics in linux window programming, and I wanna learn it. Do you see resolve of my problem? – y3v4d Jun 10 '17 at 18:44
  • 1
    Today, X11 is not much used that way. In practice, toolkits (like GTK or Qt) are drawing pixmaps client-side, and transmitting that pixmap to the X11 server. – Basile Starynkevitch Jun 10 '17 at 18:52
  • BTW, I guess that your font path (argument to `XLoadQueryFont`) is incorrect. Check with `xlsfonts`. And you should handle all sorts of events, including those for errors ([`XErrorEvent`](ftp://www.x.org/pub/current/doc/man/man3/XErrorEvent.3.xhtml)) – Basile Starynkevitch Jun 10 '17 at 18:53
  • BTW, I recommend first learning how to develop GUI applications with a toolkit (like [GTK](http://gtk.org/) or [Qt](http://qt.io/)) and only later dive into X11 internals. – Basile Starynkevitch Jun 10 '17 at 18:59
  • 1
    @Davey: As others pointed out, X11 is hardly programmed directly. Use a toolkit (I can recommend QT, others prefer GTK). They abstract from the grapfic system, QT e.g. runs on Windows, Mac and Linux/Framebuffer (typical on embedded devices). Btw.: That covers Wayland, too. Also note that the drawing primitives of X11 are not used by thoses toolkits. Some more research would be a good idea. – too honest for this site Jun 10 '17 at 19:31
  • @Olaf Thanks, i probably should learn API first – y3v4d Jun 10 '17 at 20:04
  • @Davey: what do you mean by learning an API? "everything" is an API! Even libX11... (whose API contains `XDrawString`) – Basile Starynkevitch Jun 11 '17 at 11:14

1 Answers1

6

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.

Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547