News: Stay up to date

The Étoilé community is an active group of developers, designers, testers and users. New work is being done every day. Visit often to find out what we've been up to.

News

Tutorial: Accessing X window system from GNUstep, part I

Posted on 1 September 2006 by Yen-Ju Chen

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.