# HG changeset patch # User Eris Caffee # Date 1334590379 18000 # Node ID 008e28de2870f59717256f12d5cd7a5680dbedb5 # Parent c6dce2064bfbc1fa8147bb4c09229b1932f25ad8 Saving work diff -r c6dce2064bfb -r 008e28de2870 include/App.h --- a/include/App.h Sun Apr 15 01:52:09 2012 -0500 +++ b/include/App.h Mon Apr 16 10:32:59 2012 -0500 @@ -31,13 +31,22 @@ }; ///////////////////////////////////// - typedef struct + // TODO: Need to be able to support child windows. + class WindowData { public: + WindowData(const std::string & n, Window w, App::BitMap * i) : + name(n), win(w), icon(i) {}; + ~WindowData() + { + if (icon) { delete icon; icon = NULL; } + } + + std::string name; Window win; App::BitMap * icon; - } WindowData; + }; ///////////////////////////////////// @@ -60,10 +69,14 @@ inline int display_width(void) const { return DisplayWidth(dpy, DefaultScreen(dpy)); }; + void run(void); + private: App(); App(const App & a); Display * dpy; WindowMap windows; + Atom wm_delete_window; // Need this in contructor and run(). + }; diff -r c6dce2064bfb -r 008e28de2870 src/App.cpp --- a/src/App.cpp Sun Apr 15 01:52:09 2012 -0500 +++ b/src/App.cpp Mon Apr 16 10:32:59 2012 -0500 @@ -32,11 +32,18 @@ // Create the main window create_window("main", 0, 0 , - this->display_width()/3, this->display_height()/4, + this->display_width()/2, this->display_height()/2, icon); - // Even though we are not passing any actual size_hints, the Xlib programming - // manual says to pass the flags below anyway. + // Get a reference to our WindowData structure. We need the Window handle from it for a few things. + App::WindowData * wd = windows["main"]; + + + + + // We need to set the window manager hints, size hints, window name, and icon name + + // Even though we are not passing any actual size_hints, the Xlib programming manual says to pass the flags below anyway. XSizeHints *size_hints; if (!(size_hints = XAllocSizeHints())) { @@ -45,6 +52,7 @@ } size_hints->flags = PPosition | PSize; + // Get X Properties for the window and icon names. XTextProperty windowName, iconName; const char * ptr = appname.c_str(); if (XStringListToTextProperty(const_cast(&ptr), 1, &windowName) == 0) @@ -70,18 +78,51 @@ wm_hints->icon_pixmap = icon->pixmap; wm_hints->flags = StateHint | IconPixmapHint | InputHint; - App::WindowData * wd = windows["main"]; - XSetWMProperties(dpy, wd->win, &windowName, &iconName, - NULL, 0, size_hints, wm_hints, - NULL); + XSetWMProperties(dpy, wd->win, &windowName, &iconName, + NULL, 0, size_hints, wm_hints, + NULL); + + + + // Select the event types we want to receive. + //Other interesting events include KeyReleaseMask and ButtonReleaseMask + XSelectInput(dpy, wd->win, ExposureMask | KeyPressMask | ButtonPressMask | StructureNotifyMask); + + + + // Make sure we get delete events from the window manager. + // "wm_delete_window" is the Atom which corresponds to the delete + // window message sent by the window manager. + + wm_delete_window = XInternAtom (dpy, "WM_DELETE_WINDOW", False); + XSetWMProtocols(dpy, wd->win, &wm_delete_window, 1); + + + // This give BadMatch and I don't know why. + // XSetWindowAttributes setwinattr; + // setwinattr.background_pixmap = bg_pixmap->pixmap; + // XChangeWindowAttributes(dpy, wd->win, CWBackPixmap, &setwinattr); + + // Also BadMatch + // XSetWindowBackgroundPixmap(dpy, wd->win, icon->pixmap); + + + // XSetWindowBackgroundPixmap(dpy, wd->win, None); + + + // Map the window. Remember: this does not display the window immediately. + // The request is queued until events are read, or we call XFlush or XSync. + XMapWindow(dpy, wd->win); } //////////////////////////////////////////////////////////////////////////////// App::~App() { + // Ugh. I really wish I could figure out why I can't make a map of string + // to WindowData instead of having ton use WindowData * + // I'd like to eliminate this next loop. for( WindowMap::iterator i = windows.begin(); i != windows.end(); ++i) { - delete (*i).second->icon; App::WindowData * wp = (*i).second; windows.erase(i); delete wp; @@ -126,20 +167,48 @@ x, y, width, height, border_width, - BlackPixel(dpy, screen_num), - WhitePixel(dpy, screen_num)); + None, None); + // BlackPixel(dpy, screen_num), + // WhitePixel(dpy, screen_num)); icon->make_pixmap(dpy, win); // Add it to the window list - App::WindowData * win_data = new App::WindowData; - win_data->name = win_name; - win_data->win = win; - win_data->icon = icon; + App::WindowData * win_data = new App::WindowData(win_name, win, icon); windows.insert(win_pair(win_name, win_data)); } //////////////////////////////////////////////////////////////////////////////// +void App::run(void) + { + XEvent e; + int done = 0; + while (!done) + { + XNextEvent(dpy, &e); + switch (e.type) + { + case Expose: + // We'll only redraw the entire window at a time, so unless this is + // the last contiguous expose, don't draw the window. + if (e.xexpose.count != 0) + break; + // Draw the window contents here + break; + case ClientMessage: + if ((Atom)e.xclient.data.l[0] == wm_delete_window) + done = 1; + break; + case ButtonPress: + case KeyPress: + done = 1; + default: + break; + } + } + } + +//////////////////////////////////////////////////////////////////////////////// // App::BitMap //////////////////////////////////////////////////////////////////////////////// App::BitMap::BitMap(const std::string & file) @@ -150,7 +219,7 @@ //////////////////////////////////////////////////////////////////////////////// App::BitMap::~BitMap() { - if (data) XFree(data); + if (data) { XFree(data); data = NULL; } } //////////////////////////////////////////////////////////////////////////////// diff -r c6dce2064bfb -r 008e28de2870 src/main.cpp --- a/src/main.cpp Sun Apr 15 01:52:09 2012 -0500 +++ b/src/main.cpp Mon Apr 16 10:32:59 2012 -0500 @@ -7,7 +7,6 @@ int main(void) { App * app = new App("xlib_App"); - - sleep(5); + app->run(); exit(0); }