csuyk@warwick.ac.uk (FUNG Wai Wa) (01/09/91)
Hi, there, I am new to Xlib programming. I am now stuck at a very funny(?) problem that I can't solve. Would any Xlib expert give me a hand? Thanks. The following few statements attempt to create a window and draw a line with some strings. I found that the sleep(1) statement is very crucial for its success. Its presence can make the program work as I expect but its absence make the program map the windows only. No drawing at all, if I run this program from another machine. Occasionally I can get it running in the same workstation where I started X. Would any guru give me some hints to get around this nasty problem? Regards, FUNG W.W. ----cut here #include <stdio.h> #include <X11/Xlib.h> main() { Display *dpy; int scr; Window win; GC gc; XGCValues gcvalues; XSetWindowAttributes attributes; Visual *visual = CopyFromParent; dpy = XOpenDisplay(NULL); /* connect to the default display */ if (dpy != (Display*)NULL) scr = DefaultScreen(dpy); else { printf("Cannot connect to server\n"); exit(0); } /* creating a very simple window */ attributes.background_pixel = BlackPixel(dpy, scr); win = XCreateWindow(dpy, RootWindow(dpy, scr), 100, 100, 500, 500, 1, CopyFromParent, InputOutput, visual, CWBackPixel, &attributes); XMapRaised(dpy, win); XFlush(dpy); /* create the pen */ gcvalues.foreground = WhitePixel(dpy, scr); gc = XCreateGC(dpy, win, GCForeground, &gcvalues); /* nasty stmt that its existence is crucial if this stmt is omitted, there is chance to get the program working in the same workstation that I started X. However, if I compile and execute this program in another machine over the network, only a blank window appeared but no drawing will be done. However, with this sleep stmt, everything OK. Why??? */ sleep(1); XDrawLine(dpy, win, gc, 0, 0, 300, 300); XDrawString(dpy, win, gc, 100, 100, "Xlib", 4); XDrawString(dpy, win, gc, 200, 200, "Hello", 5); XDrawString(dpy, win, gc, 300, 300, "Xlib", 4); XFlush(dpy); while (1); }
jon@infonode.ingr.com (Jon Stone) (01/10/91)
In article <1991Jan9.150326.6248@warwick.ac.uk> csuyk@warwick.ac.uk (FUNG Wai Wa) writes: >The following few statements attempt to create a window and draw a line >with some strings. I found that the sleep(1) statement is very crucial >for its success. Its presence can make the program work as I expect but >its absence make the program map the windows only. No drawing at all, if >I run this program from another machine. Occasionally I can get it running >in the same workstation where I started X. I'm no x-spert, but I think you need to wait for an Expose event before doing any drawing. X automagically queues up an Expose event when you map your window. This code is far from perfect. Try reading Chapter 3 of the Xlib Programming Manual. It should fill you in on the details. Try something like this: all your init stuff. XMapRaised XSelectInput (dpy, win, ExposureMask); while (1) { XNextEvent (dpy, &event); if (event.type == Expose) draw } Jon -- _______________________________________________________________________________ Jon D. Stone jon@ingr.com -or- ..!uunet!ingr!jon Intergraph Corporation, Huntsville, AL (205)730-8594 _______________________________________________________________________________
klee@wsl.dec.com (Ken Lee) (01/10/91)
In article <1991Jan9.150326.6248@warwick.ac.uk>, csuyk@warwick.ac.uk (FUNG Wai Wa) writes: |> The following few statements attempt to create a window and draw a line |> with some strings. I found that the sleep(1) statement is very crucial |> for its success. This is one of the most common X beginners problems. X is asynchronous, so there is no guarantee that your window is mapped before you start drawing. Instead, you should only draw on a window after receiving an expose event. Most people use the X Toolkit, which worries about this for you. -- Ken Lee DEC Western Software Laboratory, Palo Alto, Calif. Internet: klee@wsl.dec.com uucp: uunet!decwrl!klee
mouse@larry.mcrcim.mcgill.EDU (01/10/91)
>> The following few statements attempt to create a window and draw a >> line with some strings. I found that the sleep(1) statement is very >> crucial for its success. Its presence can make the program work as >> I expect but its absence make the program map the windows only. No >> drawing at all, if I run this program from another machine. >> Occasionally I can get it running in the same workstation where I >> started X. I haven't seen the original posting, but I would guess this is the common problem about not waiting for the Expose event. I will append the response to question 74 from the FAQ posting, which addresses this. > Try something like this: > all your init stuff. > XMapRaised > XSelectInput (dpy, win, ExposureMask); Whoops. The XSelectInput should be before the XMapRaised. I would recommend that you set the event mask when you create the window. der Mouse old: mcgill-vision!mouse new: mouse@larry.mcrcim.mcgill.edu ---------------------------------------------------------------------- Subject: 74) Why doesn't anything appear when I run this simple program? > ... > the_window = XCreateSimpleWindow(the_display, > root_window,size_hints.x,size_hints.y, > size_hints.width,size_hints.height,BORDER_WIDTH, > BlackPixel(the_display,the_screen), > WhitePixel(the_display,the_screen)); > ... > XSelectInput(the_display,the_window,ExposureMask|ButtonPressMask| > ButtonReleaseMask); > XMapWindow(the_display,the_window); > ... > XDrawLine(the_display,the_window,the_GC,5,5,100,100); > ... You are right to map the window before drawing into it. However, the window is not ready to be drawn into until it actually appears on the screen -- until your application receives an Expose event. Drawing done before that will generally not appear. You'll see code like this in many programs; this code would appear after window was created and mapped: while (!done) { XNextEvent(the_display,&the_event); switch (the_event.type) { case Expose: /* On expose events, redraw */ XDrawLine(the_display,the_window,the_GC,5,5,100,100); break; ... } } Note that there is a second problem: some X servers don't set up the default graphics context to have reasonable foreground/background colors, and your program should not assume that the server does, so this program could previously include this code to prevent the case of having the foreground and background colors the same: ... the_GC_values.foreground=BlackPixel(the_display,the_screen); /* e.g. */ the_GC_values.background=WhitePixel(the_display,the_screen); /* e.g. */ the_GC = XCreateGC(the_display,the_window, GCForeground|GCBackground,&the_GC_values); ... Note: the code uses BlackPixel and WhitePixel to avoid assuming that 1 is black and 0 is white or vice-versa. The relationship between pixels 0 and 1 and the colors black and white is implementation-dependent. They may be reversed, or they may not even correspond to black and white at all. ----------------------------------------------------------------------