Search code examples
cxlib

The line wasn't shown up even though the buffer was flushed in Xlib


/* Draw_Red_Line.c */

#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <stdio.h>
#include <stdlib.h>

Window     Win;
Display    *Dsp;
GC         Gc;
XGCValues  Gc_Values;
XEvent     Event;
Colormap   Color_Map;
XColor     Screen_RGB, Exact_RGB;

unsigned int Win_Size;

int main (void)
{
  /* Set window size */
  Win_Size = 625;

  /* Open a connection to the X server that controls a display */
  Dsp = XOpenDisplay(NULL);

  /* Create an unmapped subwindow of root window */
  Win = XCreateWindow(Dsp, XDefaultRootWindow(Dsp), 0, 0, Win_Size, Win_Size, 0,
                      XDefaultDepth(Dsp, 0), InputOutput, CopyFromParent, 0, 0);

  /* Map the window on the screen */
  XMapWindow(Dsp, Win);

  /* Wait until the window appears */
  do
    XNextEvent(Dsp, &Event);
  while
    (Event.type != MapNotify);

  /* Draw a red line */
  Color_Map = DefaultColormap(Dsp, DefaultScreen(Dsp));
  XAllocNamedColor(Dsp, Color_Map, "Red", &Screen_RGB, &Exact_RGB);
  Gc_Values.foreground = Screen_RGB.pixel;
  Gc_Values.line_width = 1;
  Gc = XCreateGC(Dsp, Win, GCForeground | GCLineWidth, &Gc_Values);
  XDrawLine (Dsp, Win, Gc, 0, 0, 624, 624);
  XFlush(Dsp);

  /* Exit */
  fprintf(stdout, "Exit the process");
  return EXIT_SUCCESS;
}

I tried to compile and run it in (Gnome-)terminal:

EXECUTABLENAME="Draw_Red_Line"
gcc "$EXECUTABLENAME.c" -o "$EXECUTABLENAME" -std=c99 -Wall -lX11
./"$EXECUTABLENAME"

No warnings and errors are reported by GCC. Regardless of the background, the red line wasn't shown up, and even the message string, "Exit the process", didn't print to the stdout (the terminal which run the script). Why?


Solution

  • You need to have your drawing code in Expose event handler. Likely content is invalidated somehow after call to XDrawLine and because of this is not visible. If you replace XFlush with following code everything works as expected:

      //XFlush(Dsp);
      XSelectInput(Dsp, Win, ExposureMask);
      while(1) {
        XDrawLine (Dsp, Win, Gc, 0, 0, 624, 624);
        XNextEvent(Dsp, &Event);
      }