// // // Copyright 2002 Rob Tougher // // This file is part of xlib++. // // xlib++ is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // xlib++ is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with xlib++; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // // definition of the xlib::window class #ifndef _xlib_window_class_ #define _xlib_window_class_ #include #include "display.hpp" #include #include #include "window_base.hpp" #include "event_dispatcher.hpp" #include "color.hpp" #include "shapes.hpp" namespace xlib { const int event_mask = ExposureMask | ButtonPressMask | ButtonReleaseMask | EnterWindowMask | LeaveWindowMask | PointerMotionMask | FocusChangeMask | KeyPressMask | KeyReleaseMask | SubstructureNotifyMask | StructureNotifyMask | SubstructureRedirectMask; class window : public window_base { public: // // To create a window // window ( event_dispatcher& e, rectangle r = rectangle(point(0,0),300,200) ) : m_display ( e.get_display() ), // m_background ( e.get_display(), 213, 206, 189 ), // sand m_background ( e.get_display(), 197, 194, 197 ), // grey m_event_dispatcher ( e ), m_border ( e.get_display(), 255, 255, 255 ), m_is_child ( false ), m_rect ( r ), m_parent ( 0 ) { m_window = 0; m_atom[0] = 0; show(); } // // For existing windows // window ( event_dispatcher& e, int id ) : m_display ( e.get_display() ), // m_background ( e.get_display(), 213, 206, 189 ), // sand m_background ( e.get_display(), 197, 194, 197 ), // grey m_event_dispatcher ( e ), m_border ( e.get_display(), 255, 255, 255 ), m_is_child ( false ), m_rect ( point(0,0), 0, 0 ), m_parent ( 0 ), m_window ( id ) { m_atom[0] = 0; } // // For a child window. 'w' is its parent. // window ( window& w ) : m_display ( w.get_event_dispatcher().get_display() ), m_background ( m_display, 213, 206, 189 ), m_event_dispatcher ( w.get_event_dispatcher() ), m_border ( m_display, 255, 255, 255 ), m_is_child ( true ), m_rect ( w.get_rect() ), m_parent ( w.id() ) { m_window = 0; m_atom[0] = 0; show(); } virtual ~window() { destroy(); } // // From window_base: // virtual void show() { create(); XSelectInput ( m_display, m_window, event_mask ); XMapWindow ( m_display, m_window ); XFlush ( m_display ); } virtual void on_show(){} virtual void hide() { XUnmapWindow ( m_display, m_window ); XFlush ( m_display ); } virtual void on_hide() {} virtual void create() { if ( ! m_window ) { m_window = XCreateSimpleWindow ( m_display, RootWindow((void*)m_display,0), m_rect.origin().x(), m_rect.origin().y(), m_rect.width(), m_rect.height(), 0, WhitePixel((void*)m_display,0), WhitePixel((void*)m_display,0)); set_background ( m_background ); if ( m_is_child ) { // keeps this window in front of its parent at all times XSetTransientForHint ( m_display, id(), m_parent ); // make sure the app doesn't get killed when this // window gets destroyed m_atom[0] = XInternAtom ( m_display, "WM_DELETE_WINDOW", false ); XSetWMProtocols ( m_display, m_window, m_atom, 1 ); } if ( m_window == 0 ) { throw create_window_exception ( "could not create the window" ); } on_create(); } m_event_dispatcher.register_window ( this ); } virtual void on_create(){} virtual void destroy() { hide(); if ( m_window ) { XDestroyWindow ( m_display, m_window ); m_window = 0; } m_event_dispatcher.unregister_window ( this ); on_destroy(); } virtual void set_background ( color& c ) { // hold a ref to the alloc'ed color m_background.set ( c ); XSetWindowBackground ( m_display, m_window, c.pixel() ); refresh(); } virtual void set_focus() { XSetInputFocus ( m_display, id(), RevertToParent, CurrentTime ); refresh(); } virtual void refresh () { XClearWindow ( m_display, m_window ); XFlush ( m_display ); on_expose(); } virtual rectangle get_rect() { Window root; int x = 0, y = 0; unsigned int width = 0, height = 0, border_width = 0, depth = 0; XGetGeometry ( m_display, m_window, &root, &x, &y, &width, &height, &border_width, &depth ); return rectangle ( point(x,y), width, height ); } virtual long id() { return m_window; } virtual void on_expose() {} virtual void on_left_button_down ( int x, int y ) {} virtual void on_right_button_down ( int x, int y ) {} virtual void on_left_button_up ( int x, int y ) {} virtual void on_right_button_up ( int x, int y ) {} virtual void on_mouse_enter ( int x, int y ) {}; virtual void on_mouse_exit ( int x, int y ) {}; virtual void on_mouse_move ( int x, int y ) {}; virtual void on_got_focus() {}; virtual void on_lost_focus() {}; virtual void on_key_press ( character c ) {}; virtual void on_key_release( character c ) {}; virtual void on_destroy (){} display& get_display() { return m_display; } virtual event_dispatcher& get_event_dispatcher() { return m_event_dispatcher; } private: // // Not copyable // window ( const window& ); void operator = ( window& ); display& m_display; Window m_window; Window m_parent; color m_background, m_border; event_dispatcher& m_event_dispatcher; Atom m_atom[1]; bool m_is_child; rectangle m_rect; }; }; #endif