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);
/ Listen event /
NSRunLoop *loop = [NSRunLoop currentRunLoop];
int xEventQueueFd = XConnectionNumber(dpy);
[loop addEvent: (void*)(gsaddr)xEventQueueFd
type: ET_RDESC
watcher: (id)self
forMode: NSDefaultRunLoopMode];
}
Then application delegate can listen to the event:
- (void)receivedEvent:(void *)data
type:(RunLoopEventType)type
extra:(void *)extra
forMode:(NSString *)mode
{
XEvent event;
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];
}
}
}
After [NSApp run], X window events will go into -receivedEvent:type:extra:forMode: and application delegate can make use of it.
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.