News
Tutorial: Accessing X window system from GNUstep, part I
Posted on 1 September 2006 by
While GNUstep is a portable development environment, some applications do need to access the underneath X window system. This tutorial illustrates a simple way to do so.
Note: the codes may not be executable. It is only used as demostration
First, application delegate needs to register itself for X window event:
- (void) applicationWillFinishLaunching:(NSNotification *)aNotification { Display *dpy = (Display *)[GSCurrentServer() serverDevice]; int screen = [[NSScreen mainScreen] screenNumber]; Window root_win = RootWindow(dpy, screen);Then application delegate can listen to the event:/* Listen event */ NSRunLoop *loop = [NSRunLoop currentRunLoop]; int xEventQueueFd = XConnectionNumber(dpy);
[loop addEvent: (void*)(gsaddr)xEventQueueFd type: ET_RDESC watcher: (id
)self forMode: NSDefaultRunLoopMode]; }
- (void)receivedEvent:(void *)data type:(RunLoopEventType)type extra:(void *)extra forMode:(NSString *)mode { XEvent event;After [NSApp run], X window events will go into -receivedEvent:type:extra:forMode: and application delegate can make use of it.while (XPending(dpy)) { XNextEvent (dpy, &event); /* Intercept event here / switch (event.type) { case Expose: case DestroyNotify: case PropertyNotify: case FocusIn: default: / Go back to GNUstep */ [server processEvent: &event]; } } }
If applications need listen to root window, use XSelectInput() in the end of -applicationWillFinishLaunching:. For example:
/* Listen to root window for window closing and opening */ XSelectInput(dpy, root_win, PropertyChangeMask);By default, applications only receive events acting on their windows. If they listen to other windows, such as root window, do not pass the events belonging to other windows into applications ([server processEvent: &event]). Otherwise, it will behaves weird.