1 //============================================================================
5 //============================================================================
12 \class X11Window x11window.h
13 \brief The X11Window class
15 Note that most methods will not take effect until a call to XPending,
16 XNextEvent, or XWindowEvent. If you want to make sure a method takes
17 effect before your program continues use sync();
21 char* X11Window::ErrorMessage[] =
24 "Can't open X display"
29 The specified name is used as the class and window/icon property name.
32 X11Window::X11Window( const char* name, Display* dis, int scr,
33 int swidth, int sheight, long inputMask )
39 _nullCursor = (Cursor) -1;
47 _display = XOpenDisplay( 0 );
53 _set( kOpenedDisplay );
62 _screen = DefaultScreen( _display );
68 unsigned long black = BlackPixel( _display, _screen );
69 _win = XCreateSimpleWindow( _display, DefaultRootWindow( _display ),
70 0, 0, _width, _height, 0, black, black );
73 // Enable the delete window protocol.
75 _wmDeleteAtom = XInternAtom( _display, "WM_DELETE_WINDOW", False );
76 XSetWMProtocols( _display, _win, &_wmDeleteAtom, 1 );
80 // Set the window manager properties
83 XClassHint classHints;
85 XTextProperty nameProp;
86 char* argv[ 2 ] = { (char*) name, NULL };
88 wmHints.flags = InputHint | StateHint;
90 wmHints.initial_state = NormalState;
92 sizeHints.flags = PSize;
93 sizeHints.width = _width;
94 sizeHints.height = _height;
96 classHints.res_name = (char*) name;
97 classHints.res_class = (char*) name;
99 if( XStringListToTextProperty( (char**) &name, 1, &nameProp ) )
101 XSetWMProperties( _display, _win, &nameProp, &nameProp, argv, 1,
102 &sizeHints, &wmHints, &classHints );
106 // Set up the events to wait for.
107 XSelectInput( _display, _win, inputMask );
111 X11Window::~X11Window()
117 if( _nullCursor != (Cursor) -1 )
118 XFreeCursor( _display, _nullCursor );
120 XDestroyWindow( _display, _win );
123 if( _flags & kOpenedDisplay )
125 XCloseDisplay( _display );
131 void X11Window::setTitle( const char* title )
133 XStoreName( _display, _win, title );
137 void X11Window::setIconName( const char* text )
139 XSetIconName( _display, _win, text );
143 void X11Window::move( int x, int y )
145 XMoveWindow( _display, _win, x, y );
149 void X11Window::moveResize( int x, int y, unsigned int w, unsigned int h )
151 XMoveResizeWindow( _display, _win, x, y, w, h );
155 void X11Window::resize( unsigned int w, unsigned int h )
157 XResizeWindow( _display, _win, w, h );
161 void X11Window::setSizeHints( int minW, int minH, int maxW, int maxH )
163 XSizeHints* hints = XAllocSizeHints();
166 hints->flags = PMinSize | PMaxSize;
167 hints->min_width = minW;
168 hints->min_height = minH;
169 hints->max_width = maxW;
170 hints->max_height = maxH;
172 XSetWMNormalHints( _display, _win, hints );
178 void X11Window::raise()
180 XRaiseWindow( _display, _win );
184 void X11Window::show()
186 XMapWindow( _display, _win );
189 // Wait for the window to be mapped.
193 XNextEvent( _display, &event );
195 while( event.type != MapNotify );
200 void X11Window::hide()
202 XUnmapWindow( _display, _win );
206 void X11Window::iconify()
209 XWMHints* hints = XAllocWMHints();
212 hints->flags = StateHint;
213 hints->initial_state = IconicState;
214 XSetWMHints( _display, _win, hints );
217 XIconifyWindow( _display, _win, _screen );
221 XIconifyWindow( _display, _win, _screen );
225 void X11Window::unIconify()
228 XWMHints* hints = XAllocWMHints();
231 hints->flags = StateHint;
232 hints->initial_state = NormalState;
233 XSetWMHints( _display, _win, hints );
244 int X11Window::isIconified()
251 Calls XNextEvent() and then the appropriate virtual funtion based on event
255 void X11Window::handleNextEvent()
259 XNextEvent( _display, &event );
264 if( event.xclient.format == 32 &&
265 event.xclient.data.l[ 0 ] == (int) _wmDeleteAtom )
267 deleteEvent( &event );
271 unknownEvent( &event );
275 case ConfigureNotify:
276 if( event.xconfigure.window == _win )
278 _width = event.xconfigure.width;
279 _height = event.xconfigure.height;
280 configureEvent( &event.xconfigure );
285 buttonDown( &event.xbutton );
289 buttonUp( &event.xbutton );
293 motionEvent( &event.xmotion );
297 keyDown( &event.xkey );
301 keyUp( &event.xkey );
305 focusIn( &event.xfocus );
309 focusOut( &event.xfocus );
313 exposeEvent( &event.xexpose );
317 unknownEvent( &event );
324 All events not passed to other virtual event methods are sent here.
327 void X11Window::unknownEvent( XEvent* ) {}
330 void X11Window::deleteEvent( XEvent* ) {}
332 void X11Window::focusIn( XFocusChangeEvent* ) {}
334 void X11Window::focusOut( XFocusChangeEvent* ) {}
336 void X11Window::exposeEvent( XExposeEvent* ) {}
340 Called when the window is moved or resized by the user.
341 width() and height() can be used to check the new size.
344 void X11Window::configureEvent( XConfigureEvent* ) {}
348 From XButtonEvent structure in Xlib.h:
351 int x, y; // pointer x, y coordinates in event window
352 int x_root, y_root; // coordinates relative to root
353 unsigned int state; // key or button mask
354 unsigned int button; // detail
358 void X11Window::buttonDown( XButtonEvent* ) {}
359 void X11Window::buttonUp( XButtonEvent* ) {}
362 void X11Window::motionEvent( XMotionEvent* ) {}
365 void X11Window::keyDown( XKeyEvent* ) {}
366 void X11Window::keyUp( XKeyEvent* ) {}
369 KeySym X11Window::keysym( XKeyEvent* e )
371 return XKeycodeToKeysym( display(), e->keycode, 0 );
377 XLookupString( event, buf, 1, &sym, NULL );
378 //printf( "XLookupString %x: %x %x\n", event->keycode, buf[ 0 ], sym );
384 void X11Window::hideCursor()
386 if( _nullCursor == (Cursor) -1 )
387 _nullCursor = _createNullCursor();
389 XDefineCursor( _display, _win, _nullCursor );
393 void X11Window::showCursor()
395 XUndefineCursor( _display, _win );
399 Cursor X11Window::_createNullCursor()
407 cursormask = XCreatePixmap( _display, _win, 1, 1, 1/*depth*/);
408 xgc.function = GXclear;
409 gc = XCreateGC( _display, cursormask, GCFunction, &xgc );
410 XFillRectangle( _display, cursormask, gc, 0, 0, 1, 1 );
411 dummycolour.pixel = 0;
413 dummycolour.flags = 04;
414 cursor = XCreatePixmapCursor( _display, cursormask, cursormask,
415 &dummycolour, &dummycolour, 0, 0 );
416 XFreePixmap( _display, cursormask );
417 XFreeGC( _display, gc );
424 void X11Window::enableBackingStore()
426 if( DoesBackingStore( ScreenOfDisplay( _display, _screen ) ) == Always )
428 XSetWindowAttributes attr;
429 winattr.backing_store = Always;
430 XChangeWindowAttributes( _display, _win, CWBackingStore, &attr );
437 // g++ x11window.cpp -g -L/usr/X11R6/lib -lX11
443 class TestWindow : public X11Window
447 TestWindow( const char* name, Display* dis = 0 )
448 : X11Window( name, dis )
471 printf( "resize\n" );
475 printf( "hiding\n" );
478 printf( "showing\n" );
482 printf( "iconifying\n" );
485 printf( "showing\n" );
493 while( _exit == false )
497 while( eventsPending() )
501 printf( " events %d\n", _ecnt );
509 void deleteEvent( XEvent* )
511 printf( "delete\n" );
516 void configureEvent( XConfigureEvent* )
518 printf( "configure %d %d\n", width(), height() );
522 void unknownEvent( XEvent* e )
524 printf( "Unknown XEvent: %d\n", e->type );
528 void buttonDown( XButtonEvent* e )
530 printf( "buttonDown: %d %d,%d\n", e->button, e->x, e->y );
534 void buttonUp( XButtonEvent* e )
536 printf( "buttonUp: %d %d,%d\n", e->button, e->x, e->y );
540 void motionEvent( XMotionEvent* e )
542 printf( "motion: %lx %d %d\n", e->time, e->x, e->y );
546 void keyDown( XKeyEvent* e )
550 printf( "keyDown: %lx %x %x (%c)\n", e->time, e->state, e->keycode, (char) a );
552 printf( "keyDown: %lx %x %x %x\n", e->time, e->state, e->keycode, a );
555 if( a == 0x1b ) // ASCII ESC
563 void keyUp( XKeyEvent* e )
567 printf( "keyUp: %lx %x %x (%c)\n", e->time, e->state, e->keycode, (char) a );
569 printf( "keyUp: %lx %x %x %x\n", e->time, e->state, e->keycode, a );
582 TestWindow win( "X11Window Test" );
586 printf( "error %d\n", win.error() );
590 printf( "sizeof X11Window: %d\n", sizeof( X11Window ) );
591 printf( "screen size: %d %d\n", win.displayWidth(), win.displayHeight() );