diff options
| author | Ivan Kanakarakis <ivan.kanak@gmail.com> | 2011-11-25 17:57:17 +0200 |
|---|---|---|
| committer | Ivan Kanakarakis <ivan.kanak@gmail.com> | 2011-11-25 18:52:19 +0200 |
| commit | 9471c8095373df357d2a4185ca8de26290faa72c (patch) | |
| tree | cfaff9428e4325d55a01fc41902c13de612feae8 /src/dminiwm.c | |
| parent | 544de8a8e3d2940043b982454fa80340a7461f21 (diff) | |
move everything to top level
Diffstat (limited to 'src/dminiwm.c')
| -rw-r--r-- | src/dminiwm.c | 1011 |
1 files changed, 0 insertions, 1011 deletions
diff --git a/src/dminiwm.c b/src/dminiwm.c deleted file mode 100644 index 1c1b0ff..0000000 --- a/src/dminiwm.c +++ /dev/null @@ -1,1011 +0,0 @@ -/* dminiwm.c [ 0.1.7 ] -* -* I started this from catwm 31/12/10 -* Bad window error checking and numlock checking used from -* 2wm at http://hg.suckless.org/2wm/ -* -* 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/>. -*/ - -#include <X11/Xlib.h> -#include <X11/keysym.h> -//#include <X11/XF86keysym.h> -#include <X11/Xproto.h> -#include <X11/Xutil.h> -#include <X11/Xatom.h> -#include <stdio.h> -#include <unistd.h> -#include <stdlib.h> -#include <signal.h> -#include <sys/wait.h> -#include <string.h> - -#define TABLENGTH(X) (sizeof(X)/sizeof(*X)) - -typedef union { - const char** com; - const int i; -} Arg; - -// Structs -typedef struct { - unsigned int mod; - KeySym keysym; - void (*function)(const Arg arg); - const Arg arg; -} key; - -typedef struct client client; -struct client{ - // Prev and next client - client *next; - client *prev; - - // The window - Window win; -}; - -typedef struct desktop desktop; -struct desktop{ - int master_size; - int mode; - int growth; - client *head; - client *current; -}; - -typedef struct { - const char *class; - int preferredd; - int followwin; -} Convenience; - -typedef enum { - ATOM_NET_WM_WINDOW_TYPE, - ATOM_NET_WM_WINDOW_TYPE_UTILITY, - ATOM_NET_WM_WINDOW_TYPE_DOCK, - ATOM_NET_WM_WINDOW_TYPE_SPLASH, - ATOM_NET_WM_WINDOW_TYPE_DIALOG, - ATOM_NET_WM_WINDOW_TYPE_NOTIFICATION, - ATOM_COUNT -} AtomType; - -typedef struct { - Atom *atom; - const char *name; -} AtomNode; - -Atom atoms[ATOM_COUNT]; - -static const AtomNode atomList[] = { - { &atoms[ATOM_NET_WM_WINDOW_TYPE], "_NET_WM_WINDOW_TYPE" }, - { &atoms[ATOM_NET_WM_WINDOW_TYPE_UTILITY], "_NET_WM_WINDOW_TYPE_UTILITY" }, - { &atoms[ATOM_NET_WM_WINDOW_TYPE_DOCK], "_NET_WM_WINDOW_TYPE_DOCK" }, - { &atoms[ATOM_NET_WM_WINDOW_TYPE_SPLASH], "_NET_WM_WINDOW_TYPE_SPLASH" }, - { &atoms[ATOM_NET_WM_WINDOW_TYPE_DIALOG], "_NET_WM_WINDOW_TYPE_DIALOG" }, - { &atoms[ATOM_NET_WM_WINDOW_TYPE_NOTIFICATION], "_NET_WM_WINDOW_TYPE_NOTIFICATION"}, -}; - -// Functions -static void add_window(Window w); -static void change_desktop(const Arg arg); -static void client_to_desktop(const Arg arg); -static void configurenotify(XEvent *e); -static void configurerequest(XEvent *e); -static void destroynotify(XEvent *e); -static void enternotify(XEvent *e); -static void logger(const char* e); -static unsigned long getcolor(const char* color); -static void grabkeys(); -static void keypress(XEvent *e); -static void kill_client(); -static void maprequest(XEvent *e); -static void move_down(); -static void move_up(); -static void next_desktop(); -static void next_win(); -static void prev_desktop(); -static void prev_win(); -static void quit(); -static void remove_window(Window w); -static void resize_master(const Arg arg); -static void resize_stack(const Arg arg); -static void save_desktop(int i); -static void select_desktop(int i); -static void send_kill_signal(Window w); -static void setup(); -static void sigchld(int unused); -static void spawn(const Arg arg); -static void start(); -static void swap_master(); -static void tile(); -static void switch_fullscreen(); -static void switch_grid(); -static void switch_horizontal(); -static void switch_vertical(); -static void update_current(); - -// Include configuration file (need struct key) -#include "config.h" - -// Variable -static Display *dis; -static int bool_quit; -static int current_desktop; -static int growth; -static int master_size; -static int mode; -static int sh; -static int sw; -static int screen; -static int xerror(Display *dis, XErrorEvent *ee); -static int (*xerrorxlib)(Display *, XErrorEvent *); -static unsigned int win_focus; -static unsigned int win_unfocus; -unsigned int numlockmask; /* dynamic key lock mask */ -static Window root; -static client *head; -static client *current; - -// Events array -static void (*events[LASTEvent])(XEvent *e) = { - [KeyPress] = keypress, - [MapRequest] = maprequest, - [EnterNotify] = enternotify, - [DestroyNotify] = destroynotify, - [ConfigureNotify] = configurenotify, - [ConfigureRequest] = configurerequest -}; - -// Desktop array -static desktop desktops[DESKTOPS]; - -/* ***************************** Window Management ******************************* */ -void add_window(Window w) { - client *c,*t; - - if(!(c = (client *)calloc(1,sizeof(client)))) { - logger("\033[0;31mError calloc!"); - exit(1); - } - - if(head == NULL) { - c->next = NULL; - c->prev = NULL; - c->win = w; - head = c; - } - else { - if(ATTACH_ASIDE == 0) { - for(t=head;t->next;t=t->next); - - c->next = NULL; - c->prev = t; - c->win = w; - - t->next = c; - } - else { - for(t=head;t->prev;t=t->prev); - - c->prev = NULL; - c->next = t; - c->win = w; - - t->prev = c; - - head = c; - } - } - - current = c; - save_desktop(current_desktop); - // for folow mouse - if(FOLLOW_MOUSE == 0) - XSelectInput(dis, c->win, EnterWindowMask); -} - -void remove_window(Window w) { - client *c; - - // CHANGE THIS UGLY CODE - for(c=head;c;c=c->next) { - - if(c->win == w) { - if(c->prev == NULL && c->next == NULL) { - free(head); - head = NULL; - current = NULL; - save_desktop(current_desktop); - return; - } - - if(c->prev == NULL) { - head = c->next; - c->next->prev = NULL; - current = c->next; - } - else if(c->next == NULL) { - c->prev->next = NULL; - current = c->prev; - } - else { - c->prev->next = c->next; - c->next->prev = c->prev; - current = c->prev; - } - - free(c); - save_desktop(current_desktop); - tile(); - update_current(); - return; - } - } -} - -void kill_client() { - if(current != NULL) { - //send delete signal to window - XEvent ke; - ke.type = ClientMessage; - ke.xclient.window = current->win; - ke.xclient.message_type = XInternAtom(dis, "WM_PROTOCOLS", True); - ke.xclient.format = 32; - ke.xclient.data.l[0] = XInternAtom(dis, "WM_DELETE_WINDOW", True); - ke.xclient.data.l[1] = CurrentTime; - XSendEvent(dis, current->win, False, NoEventMask, &ke); - send_kill_signal(current->win); - remove_window(current->win); - } -} - -void next_win() { - client *c; - - if(current != NULL && head != NULL) { - if(current->next == NULL) - c = head; - else - c = current->next; - - current = c; - if(mode == 1) - tile(); - update_current(); - } -} - -void prev_win() { - client *c; - - if(current != NULL && head != NULL) { - if(current->prev == NULL) - for(c=head;c->next;c=c->next); - else - c = current->prev; - - current = c; - if(mode == 1) - tile(); - update_current(); - } -} - -void move_down() { - Window tmp; - if(current == NULL || current->next == NULL || current->win == head->win || current->prev == NULL) - return; - - tmp = current->win; - current->win = current->next->win; - current->next->win = tmp; - //keep the moved window activated - next_win(); - save_desktop(current_desktop); - tile(); -} - -void move_up() { - Window tmp; - if(current == NULL || current->prev == head || current->win == head->win) { - return; - } - tmp = current->win; - current->win = current->prev->win; - current->prev->win = tmp; - prev_win(); - save_desktop(current_desktop); - tile(); -} - -void swap_master() { - Window tmp; - - if(head->next != NULL && current != NULL && mode != 1) { - if(current == head) { - tmp = head->next->win; - head->next->win = head->win; - head->win = tmp; - } else { - tmp = head->win; - head->win = current->win; - current->win = tmp; - current = head; - } - save_desktop(current_desktop); - tile(); - update_current(); - } -} - -/* **************************** Desktop Management ************************************* */ -void change_desktop(const Arg arg) { - client *c; - - if(arg.i == current_desktop) - return; - - // Save current "properties" - save_desktop(current_desktop); - - // Unmap all window - if(head != NULL) - for(c=head;c;c=c->next) - XUnmapWindow(dis,c->win); - - // Take "properties" from the new desktop - select_desktop(arg.i); - - // Map all windows - if(head != NULL) - for(c=head;c;c=c->next) - XMapWindow(dis,c->win); - - tile(); - update_current(); -} - -void next_desktop() { - int tmp = current_desktop; - if(tmp == TABLENGTH(desktops)-1) - tmp = 0; - else - tmp++; - - Arg a = {.i = tmp}; - change_desktop(a); -} - -void prev_desktop() { - int tmp = current_desktop; - if(tmp == 0) - tmp = TABLENGTH(desktops)-1; - else - tmp--; - - Arg a = {.i = tmp}; - change_desktop(a); -} - -void client_to_desktop(const Arg arg) { - client *tmp = current; - int tmp2 = current_desktop; - - if(arg.i == current_desktop || current == NULL) - return; - - // Add client to desktop - select_desktop(arg.i); - add_window(tmp->win); - save_desktop(arg.i); - - // Remove client from current desktop - select_desktop(tmp2); - XUnmapWindow(dis,tmp->win); - remove_window(tmp->win); - save_desktop(tmp2); - tile(); - update_current(); - if(FOLLOW_WINDOW == 0) - change_desktop(arg); -} - -void save_desktop(int i) { - desktops[i].master_size = master_size; - desktops[i].mode = mode; - desktops[i].growth = growth; - desktops[i].head = head; - desktops[i].current = current; -} - -void select_desktop(int i) { - master_size = desktops[i].master_size; - mode = desktops[i].mode; - growth = desktops[i].growth; - head = desktops[i].head; - current = desktops[i].current; - current_desktop = i; -} - -void tile() { - client *c; - int n = 0; - int x = 0; - int y = 0; - - // For a top panel - if(TOP_PANEL == 0) - y = PANEL_HEIGHT; - - // If only one window - if(head != NULL && head->next == NULL) { - XMoveResizeWindow(dis,head->win,0,y,sw+2*BORDER_WIDTH,sh+2*BORDER_WIDTH); - } - else if(head != NULL) { - switch(mode) { - case 0: /* Vertical */ - // Master window - XMoveResizeWindow(dis,head->win,0,y,master_size - BORDER_WIDTH,sh - BORDER_WIDTH); - - // Stack - for(c=head->next;c;c=c->next) ++n; - if(n == 1) growth = 0; - XMoveResizeWindow(dis,head->next->win,master_size + BORDER_WIDTH,y,sw-master_size-(2*BORDER_WIDTH),(sh/n)+growth - BORDER_WIDTH); - y += (sh/n)+growth; - for(c=head->next->next;c;c=c->next) { - XMoveResizeWindow(dis,c->win,master_size + BORDER_WIDTH,y,sw-master_size-(2*BORDER_WIDTH),(sh/n)-(growth/(n-1)) - BORDER_WIDTH); - y += (sh/n)-(growth/(n-1)); - } - break; - case 1: /* Fullscreen */ - for(c=head;c;c=c->next) { - XMoveResizeWindow(dis,c->win,0,y,sw+2*BORDER_WIDTH,sh+2*BORDER_WIDTH); - } - break; - case 2: /* Horizontal */ - // Master window - XMoveResizeWindow(dis,head->win,0,y,sw-BORDER_WIDTH,master_size - BORDER_WIDTH); - - // Stack - for(c=head->next;c;c=c->next) ++n; - if(n == 1) growth = 0; - XMoveResizeWindow(dis,head->next->win,0,y+master_size + BORDER_WIDTH,(sw/n)+growth-BORDER_WIDTH,sh-master_size-(2*BORDER_WIDTH)); - x = (sw/n)+growth; - for(c=head->next->next;c;c=c->next) { - XMoveResizeWindow(dis,c->win,x,y+master_size + BORDER_WIDTH,(sw/n)-(growth/(n-1)) - BORDER_WIDTH,sh-master_size-(2*BORDER_WIDTH)); - x += (sw/n)-(growth/(n-1)); - } - break; - case 3: { // Grid - int xpos = 0; - int wdt = 0; - int ht = 0; - - for(c=head;c;c=c->next) ++x; - - for(c=head;c;c=c->next) { - ++n; - if(x >= 7) { - wdt = (sw/3) - BORDER_WIDTH; - ht = (sh/3) - BORDER_WIDTH; - if((n == 1) || (n == 4) || (n == 7)) - xpos = 0; - if((n == 2) || (n == 5) || (n == 8)) - xpos = (sw/3) + BORDER_WIDTH; - if((n == 3) || (n == 6) || (n == 9)) - xpos = (2*(sw/3)) + BORDER_WIDTH; - if((n == 4) || (n == 7)) - y += (sh/3) + BORDER_WIDTH; - if((n == x) && (n == 7)) - wdt = sw - BORDER_WIDTH; - if((n == x) && (n == 8)) - wdt = 2*sw/3 - BORDER_WIDTH; - } else - if(x >= 5) { - wdt = (sw/3) - BORDER_WIDTH; - ht = (sh/2) - BORDER_WIDTH; - if((n == 1) || (n == 4)) - xpos = 0; - if((n == 2) || (n == 5)) - xpos = (sw/3) + BORDER_WIDTH; - if((n == 3) || (n == 6)) - xpos = (2*(sw/3)) + BORDER_WIDTH; - if(n == 4) - y += (sh/2); // + BORDER_WIDTH; - if((n == x) && (n == 5)) - wdt = 2*sw/3 - BORDER_WIDTH; - - } else { - if(x > 2) { - if((n == 1) || (n == 2)) - ht = (sh/2) + growth - BORDER_WIDTH; - if(n >= 3) - ht = (sh/2) - growth - 2*BORDER_WIDTH; - } - else - ht = sh - BORDER_WIDTH; - if((n == 1) || (n == 3)) { - xpos = 0; - wdt = master_size - BORDER_WIDTH; - } - if((n == 2) || (n == 4)) { - xpos = master_size+BORDER_WIDTH; - wdt = (sw - master_size) - 2*BORDER_WIDTH; - } - if(n == 3) - y += (sh/2) + growth + BORDER_WIDTH; - if((n == x) && (n == 3)) - wdt = sw - BORDER_WIDTH; - } - XMoveResizeWindow(dis,c->win,xpos,y,wdt,ht); - } - } - break; - default: - break; - } - } -} - -void update_current() { - client *c; - - for(c=head;c;c=c->next) { - if((head->next == NULL) || (mode == 1)) - XSetWindowBorderWidth(dis,c->win,0); - else - XSetWindowBorderWidth(dis,c->win,BORDER_WIDTH); - - if(current == c) { - // "Enable" current window - XSetWindowBorder(dis,c->win,win_focus); - XSetInputFocus(dis,c->win,RevertToParent,CurrentTime); - XRaiseWindow(dis,c->win); - } - else - XSetWindowBorder(dis,c->win,win_unfocus); - } - XSync(dis, False); -} - -void switch_vertical() { - if(mode != 0) { - mode = 0; - master_size = sw * MASTER_SIZE; - tile(); - update_current(); - } -} - -void switch_fullscreen() { - if(mode != 1) { - mode = 1; - tile(); - update_current(); - } -} - -void switch_horizontal() { - if(mode != 2) { - mode = 2; - master_size = sh * MASTER_SIZE; - tile(); - update_current(); - } -} - -void switch_grid() { - if(mode != 3) { - mode = 3; - master_size = sw * MASTER_SIZE; - tile(); - update_current(); - } -} - -void resize_master(const Arg arg) { - master_size += arg.i; - tile(); -} - -void resize_stack(const Arg arg) { - growth += arg.i; - tile(); -} - -/* ********************** Keyboard Management ********************** */ -void grabkeys() { - int i; - KeyCode code; - - XUngrabKey(dis, AnyKey, AnyModifier, root); - // For each shortcuts - for(i=0;i<TABLENGTH(keys);++i) { - code = XKeysymToKeycode(dis,keys[i].keysym); - XGrabKey(dis, code, keys[i].mod, root, True, GrabModeAsync, GrabModeAsync); - XGrabKey(dis, code, keys[i].mod | LockMask, root, True, GrabModeAsync, GrabModeAsync); - XGrabKey(dis, code, keys[i].mod | numlockmask, root, True, GrabModeAsync, GrabModeAsync); - XGrabKey(dis, code, keys[i].mod | numlockmask | LockMask, root, True, GrabModeAsync, GrabModeAsync); - } -} - -void keypress(XEvent *e) { - static unsigned int len = sizeof keys / sizeof keys[0]; - unsigned int i; - KeySym keysym; - XKeyEvent *ev = &e->xkey; - - keysym = XKeycodeToKeysym(dis, (KeyCode)ev->keycode, 0); - for(i = 0; i < len; i++) { - if(keysym == keys[i].keysym && CLEANMASK(keys[i].mod) == CLEANMASK(ev->state)) { - if(keys[i].function) - keys[i].function(keys[i].arg); - } - } -} - -void configurenotify(XEvent *e) { - // Do nothing for the moment -} - -/* ********************** Signal Management ************************** */ -void configurerequest(XEvent *e) { - // Paste from DWM, thx again \o/ - XConfigureRequestEvent *ev = &e->xconfigurerequest; - XWindowChanges wc; - - wc.x = ev->x; - wc.y = ev->y; - if(ev->width < sw-BORDER_WIDTH) - wc.width = ev->width; - else - wc.width = sw-BORDER_WIDTH; - if(ev->height < sh-BORDER_WIDTH) - wc.height = ev->height; - else - wc.height = sh-BORDER_WIDTH; - wc.border_width = ev->border_width; - wc.sibling = ev->above; - wc.stack_mode = ev->detail; - XConfigureWindow(dis, ev->window, ev->value_mask, &wc); - XSync(dis, False); -} - -void maprequest(XEvent *e) { - XMapRequestEvent *ev = &e->xmaprequest; - - // For fullscreen mplayer (and maybe some other program) - client *c; - - for(c=head;c;c=c->next) - if(ev->window == c->win) { - XMapWindow(dis,ev->window); - XMoveResizeWindow(dis,c->win,-BORDER_WIDTH,-BORDER_WIDTH,sw+BORDER_WIDTH,sh+BORDER_WIDTH); - return; - } - - Window trans = None; - if (XGetTransientForHint(dis, ev->window, &trans) && trans != None) { - add_window(ev->window); - XMapWindow(dis, ev->window); - XSetInputFocus(dis,ev->window,RevertToParent,CurrentTime); - XRaiseWindow(dis,ev->window); - return; - } - - unsigned long count, j, extra; - Atom realType; - int realFormat; - unsigned char *temp; - Atom *type; - - if(XGetWindowProperty(dis, ev->window, atoms[ATOM_NET_WM_WINDOW_TYPE], 0, 32, False, XA_ATOM, &realType, &realFormat, &count, &extra, &temp) == Success) { - if(count > 0) { - type = (unsigned long*)temp; - for(j=0; j<count; j++) { - if((type[j] == atoms[ATOM_NET_WM_WINDOW_TYPE_UTILITY]) || - (type[j] == atoms[ATOM_NET_WM_WINDOW_TYPE_NOTIFICATION]) || - (type[j] == atoms[ATOM_NET_WM_WINDOW_TYPE_SPLASH]) || - (type[j] == atoms[ATOM_NET_WM_WINDOW_TYPE_DIALOG]) || - (type[j] == atoms[ATOM_NET_WM_WINDOW_TYPE_DOCK])) { - add_window(ev->window); - XMapWindow(dis, ev->window); - XSetInputFocus(dis,ev->window,RevertToParent,CurrentTime); - XRaiseWindow(dis,ev->window); - return; - } - } - } - if(temp) - XFree(temp); - } - - XClassHint ch = {0}; - static unsigned int len = sizeof convenience / sizeof convenience[0]; - int i = 0; - int tmp = current_desktop; - if(XGetClassHint(dis, ev->window, &ch)) - for(i=0;i<len;i++) - if(strcmp(ch.res_class, convenience[i].class) == 0) { - save_desktop(tmp); - select_desktop(convenience[i].preferredd-1); - add_window(ev->window); - if(tmp == convenience[i].preferredd-1) { - XMapWindow(dis, ev->window); - tile(); - update_current(); - } else { - select_desktop(tmp); - } - if(convenience[i].followwin != 0) { - Arg a = {.i = convenience[i].preferredd-1}; - change_desktop(a); - } - if(ch.res_class) - XFree(ch.res_class); - if(ch.res_name) - XFree(ch.res_name); - return; - } - - add_window(ev->window); - XMapWindow(dis,ev->window); - tile(); - update_current(); -} - -void destroynotify(XEvent *e) { - int i = 0; - int j = 0; - int tmp = current_desktop; - client *c; - XDestroyWindowEvent *ev = &e->xdestroywindow; - - save_desktop(tmp); - for(j=0;j<TABLENGTH(desktops);++j) { - select_desktop(j); - for(c=head;c;c=c->next) - if(ev->window == c->win) - i++; - - if(i != 0) { - remove_window(ev->window); - select_desktop(tmp); - return; - } - - i = 0; - } - select_desktop(tmp); -} - -void enternotify(XEvent *e) { - client *c; - XCrossingEvent *ev = &e->xcrossing; - - if(FOLLOW_MOUSE == 0) { - if((ev->mode != NotifyNormal || ev->detail == NotifyInferior) && ev->window != root) - return; - for(c=head;c;c=c->next) - if(ev->window == c->win) { - current = c; - update_current(); - return; - } - } -} - -void send_kill_signal(Window w) { - XEvent ke; - ke.type = ClientMessage; - ke.xclient.window = w; - ke.xclient.message_type = XInternAtom(dis, "WM_PROTOCOLS", True); - ke.xclient.format = 32; - ke.xclient.data.l[0] = XInternAtom(dis, "WM_DELETE_WINDOW", True); - ke.xclient.data.l[1] = CurrentTime; - XSendEvent(dis, w, False, NoEventMask, &ke); -} - -unsigned long getcolor(const char* color) { - XColor c; - Colormap map = DefaultColormap(dis,screen); - - if(!XAllocNamedColor(dis,map,color,&c,&c)) { - logger("\033[0;31mError parsing color!"); - exit(1); - } - return c.pixel; -} - -void quit() { - Window root_return, parent; - Window *children; - int i; - unsigned int nchildren; - XEvent ev; - - /* - * if a client refuses to terminate itself, - * we kill every window remaining the brutal way. - * Since we're stuck in the while(nchildren > 0) { ... } loop - * we can't exit through the main method. - * This all happens if MOD+q is pushed a second time. - */ - if(bool_quit == 1) { - XUngrabKey(dis, AnyKey, AnyModifier, root); - XDestroySubwindows(dis, root); - logger(" \033[0;33mThanks for using!"); - XCloseDisplay(dis); - logger("\033[0;31mforced shutdown"); - } - - bool_quit = 1; - XQueryTree(dis, root, &root_return, &parent, &children, &nchildren); - for(i = 0; i < nchildren; i++) { - send_kill_signal(children[i]); - } - //keep alive until all windows are killed - while(nchildren > 0) { - XQueryTree(dis, root, &root_return, &parent, &children, &nchildren); - XNextEvent(dis,&ev); - if(events[ev.type]) - events[ev.type](&ev); - } - - XUngrabKey(dis,AnyKey,AnyModifier,root); - logger("\033[0;34mYou Quit : Thanks for using!"); -} - -void logger(const char* e) { - fprintf(stdout,"\n\033[0;34m:: dminiwm : %s \033[0;m\n", e); -} - -void setup() { - // Install a signal - sigchld(0); - - // Screen and root window - screen = DefaultScreen(dis); - root = RootWindow(dis,screen); - - // Screen width and height - sw = XDisplayWidth(dis,screen) - BORDER_WIDTH; - sh = (XDisplayHeight(dis,screen) - PANEL_HEIGHT) - BORDER_WIDTH; - - // Colors - win_focus = getcolor(FOCUS); - win_unfocus = getcolor(UNFOCUS); - - // numlock workaround - int j, k; - XModifierKeymap *modmap; - numlockmask = 0; - modmap = XGetModifierMapping(dis); - for (k = 0; k < 8; k++) { - for (j = 0; j < modmap->max_keypermod; j++) { - if(modmap->modifiermap[k * modmap->max_keypermod + j] == XKeysymToKeycode(dis, XK_Num_Lock)) - numlockmask = (1 << k); - } - } - XFreeModifiermap(modmap); - - // Shortcuts - grabkeys(); - - // Default stack - mode = DEFAULT_MODE; - growth = 0; - - // For exiting - bool_quit = 0; - - // List of client - head = NULL; - current = NULL; - - // Master size - if(mode == 2) - master_size = sh*MASTER_SIZE; - else - master_size = sw*MASTER_SIZE; - - // Set up all desktop - int i; - for(i=0;i<TABLENGTH(desktops);++i) { - desktops[i].master_size = master_size; - desktops[i].mode = mode; - desktops[i].growth = growth; - desktops[i].head = head; - desktops[i].current = current; - } - - // Select first dekstop by default - const Arg arg = {.i = 0}; - current_desktop = arg.i; - change_desktop(arg); - // Set up atoms for dialog/notification windows - int x; - for(x = 0; x < ATOM_COUNT; x++) - *atomList[x].atom = XInternAtom(dis, atomList[x].name, False); - // To catch maprequest and destroynotify (if other wm running) - XSelectInput(dis,root,SubstructureNotifyMask|SubstructureRedirectMask); - XSetErrorHandler(xerror); - logger("\033[0;32mWe're up and running!"); -} - -void sigchld(int unused) { - // Again, thx to dwm ;) - if(signal(SIGCHLD, sigchld) == SIG_ERR) { - logger("\033[0;31mCan't install SIGCHLD handler"); - exit(1); - } - while(0 < waitpid(-1, NULL, WNOHANG)); -} - -void spawn(const Arg arg) { - if(fork() == 0) { - if(fork() == 0) { - if(dis) - close(ConnectionNumber(dis)); - - setsid(); - execvp((char*)arg.com[0],(char**)arg.com); - } - exit(0); - } -} - -/* There's no way to check accesses to destroyed windows, thus those cases are ignored (especially on UnmapNotify's). Other types of errors call Xlibs default error handler, which may call exit. */ -int xerror(Display *dis, XErrorEvent *ee) { - if(ee->error_code == BadWindow - || (ee->request_code == X_SetInputFocus && ee->error_code == BadMatch) - || (ee->request_code == X_PolyText8 && ee->error_code == BadDrawable) - || (ee->request_code == X_PolyFillRectangle && ee->error_code == BadDrawable) - || (ee->request_code == X_PolySegment && ee->error_code == BadDrawable) - || (ee->request_code == X_ConfigureWindow && ee->error_code == BadMatch) - || (ee->request_code == X_GrabKey && ee->error_code == BadAccess) - || (ee->request_code == X_CopyArea && ee->error_code == BadDrawable)) - return 0; - logger("\033[0;31mBad Window Error!"); - return xerrorxlib(dis, ee); /* may call exit */ -} - -void start() { - XEvent ev; - - // Main loop, just dispatch events (thx to dwm ;) - while(!bool_quit && !XNextEvent(dis,&ev)) { - if(events[ev.type]) - events[ev.type](&ev); - } -} - - -int main(int argc, char **argv) { - // Open display - if(!(dis = XOpenDisplay(NULL))) { - logger("\033[0;31mCannot open display!"); - exit(1); - } - - // Setup env - setup(); - - // Start wm - start(); - - // Close display - XCloseDisplay(dis); - - return 0; -} |
