]> Pileus Git - wmpus/blobdiff - sys-x11.c
Add command line option parsing
[wmpus] / sys-x11.c
index 415742186b5eebc2422e960229f7b89822157d8c..6c43780979ef3491dc96d380867453721ea959c7 100644 (file)
--- a/sys-x11.c
+++ b/sys-x11.c
@@ -1,20 +1,19 @@
 /*
- * Copyright (C) 2011 Andy Spencer <andy753421@gmail.com>
- * 
- * This program 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 3 of the License, or
- * (at your option) any later version.
- * 
- * This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+ * Copyright (c) 2011, Andy Spencer <andy753421@gmail.com>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  */
 
+#define _GNU_SOURCE
 #include <stdio.h>
 #include <stdlib.h>
 #include <search.h>
@@ -57,6 +56,7 @@ typedef enum {
 } color_t;
 
 /* Global data */
+static int   running;
 static void *cache;
 static Atom atoms[natoms];
 static int (*xerrorxlib)(Display *, XErrorEvent *);
@@ -243,13 +243,18 @@ static win_t *win_find(Display *dpy, Window xid, int create)
        return new;
 }
 
-static void win_remove(win_t *win)
+static void win_free(win_t *win)
 {
-       tdelete(win, &cache, win_cmp);
        free(win->sys);
        free(win);
 }
 
+static void win_remove(win_t *win)
+{
+       tdelete(win, &cache, win_cmp);
+       win_free(win);
+}
+
 static int win_viewable(win_t *win)
 {
        XWindowAttributes attr;
@@ -277,7 +282,7 @@ static void process_event(int type, XEvent *ev, win_t *root)
        //printf("event: %d\n", type);
 
        /* Common data for all these events ... */
-       ptr_t ptr; mod_t mod;
+       ptr_t ptr = {}; mod_t mod = {};
        if (type == KeyPress    || type == KeyRelease    ||
            type == ButtonPress || type == ButtonRelease ||
            type == MotionNotify) {
@@ -458,6 +463,7 @@ void sys_show(win_t *win, state_t state)
        case st_show:
                printf("sys_show: show\n");
                XMapWindow(win->sys->dpy, win->sys->xid);
+               XSync(win->sys->dpy, False);
                return;
        case st_full:
                printf("sys_show: full\n");
@@ -506,15 +512,11 @@ list_t *sys_info(win_t *win)
 {
        /* Use global copy of screens so we can add struts */
        if (screens == NULL) {
-               int n;
+               /* Add Xinerama screens */
+               int n = 0;
                XineramaScreenInfo *info = NULL;
                if (XineramaIsActive(win->sys->dpy))
                        info = XineramaQueryScreens(win->sys->dpy, &n);
-               if (!info) {
-                       win_t *screen = new0(win_t);
-                       *screen = *win;
-                       return list_insert(NULL, screen);
-               }
                for (int i = 0; i < n; i++) {
                        win_t *screen = new0(win_t);
                        screen->x = info[i].x_org;
@@ -524,6 +526,12 @@ list_t *sys_info(win_t *win)
                        screens = list_append(screens, screen);
                }
        }
+       if (screens == NULL) {
+               /* No xinerama support */
+               win_t *screen = new0(win_t);
+               *screen = *win;
+               screens = list_insert(NULL, screen);
+       }
        return screens;
 }
 
@@ -562,19 +570,35 @@ void sys_run(win_t *root)
        unsigned int nkids;
        Window par, xid, *kids = NULL;
        if (XQueryTree(root->sys->dpy, root->sys->xid,
-                               &par, &xid, &kids, &nkids))
+                               &par, &xid, &kids, &nkids)) {
                for(int i = 0; i < nkids; i++) {
                        win_t *win = win_find(root->sys->dpy, kids[i], 1);
                        if (win && win_viewable(win) && !strut_add(root,win))
                                wm_insert(win);
                }
+               XFree(kids);
+       }
        wm_update(); // For struts
 
        /* Main loop */
-       for(;;)
+       running = 1;
+       while (running)
        {
                XEvent ev;
                XNextEvent(root->sys->dpy, &ev);
                process_event(ev.type, &ev, root);
        }
 }
+
+void sys_exit(void)
+{
+       running = 0;
+}
+
+void sys_free(win_t *root)
+{
+       XCloseDisplay(root->sys->dpy);
+       while (screens)
+               screens = list_remove(screens, screens, 1);
+       tdestroy(cache, (void(*)(void*))win_free);
+}