Reputation: 2992
I have an application that that I was trying to modify so that a worker thread can tell a window to update itself with new data.
Variables are defined as follows:
Display *d;
Window w;
XEvent exppp;
The window is started with the following code:
XEvent e;
d = XOpenDisplay(NULL);
if (d == NULL)
return 0;
s = DefaultScreen(d);
w = XCreateSimpleWindow(d, RootWindow(d, s), 10, 10, 200, 800, 1,
BlackPixel(d, s), WhitePixel(d, s));
XSelectInput(d, w, ExposureMask | KeyPressMask);
XMapWindow(d, w);
while (1) {
XNextEvent(d, &e);
if (e.type == Expose || e.type == KeyPress) {
// redraw routine goes here
}
}
What I was attempting to use to get the window to redraw is a function that can be called by another thread:
void graphical_out::redraw()
{
exppp.type = Expose;
XSendEvent(d, w, false, Expose, &exppp);
}
And the window only updates itself when it is re-sized or receives a key-press. This seems a bit like a newbie question but Google has failed me on this one. Any suggestions to what I am doing wrong?
Upvotes: 3
Views: 5673
Reputation: 119877
XSendEvent
are wrong. You need to pass the mask (ExposureMask
), not the event type.exppp.xexpose.window = w;
is mandatory (the window argument of XSendEvent
is not the window of the XEvent
structure).memset(&exppp, 0, sizeof(exppp));
, just in case.UPDATE In a multithreaded program one needs to call XFlush
here and there (though multithreading is never guaranteed to work with Xlib).
This code works for me:
#include <X11/Xlib.h>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <memory.h>
Display *d;
Window w;
int s;
void* tp (void* q)
{
XEvent exppp;
while (1)
{
sleep (3);
printf ("Sending event of type Expose\n");
memset(&exppp, 0, sizeof(exppp));
exppp.type = Expose;
exppp.xexpose.window = w;
XSendEvent(d,w,False,ExposureMask,&exppp);
XFlush(d);
}
return NULL;
}
int main ()
{
XEvent e;
pthread_t thread;
d = XOpenDisplay(NULL);
if (d == NULL)
return 0;
s = DefaultScreen(d);
w = XCreateSimpleWindow(d, RootWindow(d, s), 10, 10, 200, 800, 1,
BlackPixel(d, s), WhitePixel(d, s));
XSelectInput(d, w, ExposureMask | KeyPressMask);
XMapWindow(d, w);
pthread_create(&thread, NULL, tp, NULL);
while (1) {
XNextEvent(d, &e);
if (e.type == Expose) {
printf ("Got Expose event%s\n", e.xexpose.send_event ? " (SendEvent)" : "");
}
else if (e.type == KeyPress) {
printf ("Got KeyPress event%s\n", e.xkey.send_event ? " (SendEvent)" : "");
}
}
}
It might work for you, or it might bomb. Xlib is not thread safe, use at your own risk.
Upvotes: 6