diff --git a/Makefile b/Makefile index 1c82113..7559f53 100644 --- a/Makefile +++ b/Makefile @@ -21,6 +21,7 @@ dist: $(RM) -r $(PACKAGE)-$(VERSION) $(LN) -s . $(PACKAGE)-$(VERSION) @$(TAR) $(PACKAGE)-$(VERSION).tar.gz \ + $(PACKAGE)-$(VERSION)/src/framer.c \ $(PACKAGE)-$(VERSION)/src/main.c \ $(PACKAGE)-$(VERSION)/src/Makefile \ $(PACKAGE)-$(VERSION)/src/project.conf \ diff --git a/src/Makefile b/src/Makefile index 12754c8..f738cf4 100644 --- a/src/Makefile +++ b/src/Makefile @@ -16,13 +16,16 @@ INSTALL = install all: $(TARGETS) -framer_OBJS = main.o +framer_OBJS = framer.o main.o framer_CFLAGS = $(CPPFLAGSF) $(CPPFLAGS) $(CFLAGSF) $(CFLAGS) framer_LDFLAGS = $(LDFLAGSF) $(LDFLAGS) framer: $(framer_OBJS) $(CC) -o framer $(framer_OBJS) $(framer_LDFLAGS) +framer.o: framer.c + $(CC) $(framer_CFLAGS) -c framer.c + main.o: main.c $(CC) $(framer_CFLAGS) -c main.c diff --git a/src/framer.c b/src/framer.c new file mode 100644 index 0000000..77190f8 --- /dev/null +++ b/src/framer.c @@ -0,0 +1,333 @@ +/* $Id$ */ +/* Copyright (c) 2009 Pierre Pronchery */ +/* This file is part of DeforaOS Desktop Framer */ +/* 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, version 3 of the License. + * + * 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 . */ + + + +#include +#include +#include +#include +#include +#include +#include +#include "framer.h" +#include "../config.h" + +#define max(a, b) ((a) > (b) ? (a) : (b)) +#define min(a, b) ((a) < (b) ? (a) : (b)) + + +/* Framer */ +/* private */ +/* types */ +typedef enum _FramerAtom +{ + FA_NET_CURRENT_DESKTOP = 0, + FA_NET_NUMBER_OF_DESKTOPS +} FramerAtom; +#define FA_LAST FA_NET_NUMBER_OF_DESKTOPS +#define FA_COUNT (FA_LAST + 1) + +struct _Framer +{ + GdkDisplay * display; + GdkScreen * screen; + GdkWindow * root; + int width; + int height; + Atom atom[FA_COUNT]; +}; + + +/* constants */ +static char const * _framer_atom[FA_COUNT] = +{ + "_NET_CURRENT_DESKTOP", + "_NET_NUMBER_OF_DESKTOPS" +}; + + +/* prototypes */ +static int _framer_error(char const * message, int ret); + +/* callbacks */ +static GdkFilterReturn _framer_filter(GdkXEvent * xevent, GdkEvent * event, + gpointer data); + + +/* public */ +/* functions */ +/* framer */ +Framer * framer_new(void) +{ + Framer * framer; + int i; + long cnt = 1; + long cur = 0; + + if((framer = malloc(sizeof(*framer))) == NULL) + { + _framer_error(strerror(errno), 1); + return NULL; + } + if((framer->display = gdk_display_get_default()) == NULL) + { + _framer_error("There is no default display", 1); + free(framer); + return NULL; + } + framer->screen = gdk_display_get_default_screen(framer->display); + framer->root = gdk_screen_get_root_window(framer->screen); + framer->width = gdk_screen_get_width(framer->screen); + framer->height = gdk_screen_get_height(framer->screen); + /* atoms */ + for(i = 0; i < FA_COUNT; i++) + framer->atom[i] = gdk_x11_get_xatom_by_name_for_display( + framer->display, _framer_atom[i]); + /* NETWM compliance */ + XChangeProperty(GDK_DISPLAY_XDISPLAY(framer->display), + GDK_WINDOW_XWINDOW(framer->root), + framer->atom[FA_NET_NUMBER_OF_DESKTOPS], XA_CARDINAL, + 32, PropModeReplace, (unsigned char *)&cnt, 1); + XChangeProperty(GDK_DISPLAY_XDISPLAY(framer->display), + GDK_WINDOW_XWINDOW(framer->root), + framer->atom[FA_NET_CURRENT_DESKTOP], XA_CARDINAL, + 32, PropModeReplace, (unsigned char *)&cur, 1); + /* register as window manager */ + XSelectInput(gdk_x11_display_get_xdisplay(framer->display), + GDK_WINDOW_XWINDOW(framer->root), NoEventMask + | SubstructureRedirectMask); + gdk_window_add_filter(framer->root, _framer_filter, framer); + return framer; +} + + +/* framer_delete */ +void framer_delete(Framer * framer) +{ + int i; + + for(i = 0; i < FA_COUNT; i++) + XDeleteProperty(GDK_DISPLAY_XDISPLAY(framer->display), + GDK_WINDOW_XWINDOW(framer->root), + framer->atom[i]); + free(framer); +} + + +/* framer error */ +static int _framer_error(char const * message, int ret) +{ + fprintf(stderr, "%s: %s\n", PACKAGE, message); + return ret; +} + + +/* callbacks */ +/* framer_filter */ +static GdkFilterReturn _filter_client_message(XClientMessageEvent * xclient, + Framer * framer); +static GdkFilterReturn _filter_configure_notify(XConfigureEvent * xconfigure); +static GdkFilterReturn _filter_configure_request( + XConfigureRequestEvent * xconfigure, Framer * framer); +static GdkFilterReturn _filter_create_notify(XCreateWindowEvent * xcreate); +static GdkFilterReturn _filter_destroy_notify(XDestroyWindowEvent * xdestroy); +static GdkFilterReturn _filter_leave_notify(XCrossingEvent * xleave); +static GdkFilterReturn _filter_map_notify(XMapEvent * xmap, Framer * framer); +static GdkFilterReturn _filter_map_request(XMapRequestEvent * xmap, + Framer * framer); +static GdkFilterReturn _filter_motion_notify(XMotionEvent * xmotion); +static GdkFilterReturn _filter_property_notify(XPropertyEvent * xproperty, + Framer * framer); +static GdkFilterReturn _filter_unmap_notify(XUnmapEvent * xmap); + +static GdkFilterReturn _framer_filter(GdkXEvent * xevent, GdkEvent * event, + gpointer data) +{ + Framer * framer = data; + XEvent * xev = xevent; + + switch(xev->type) + { + case ClientMessage: + return _filter_client_message(&xev->xclient, framer); + case ConfigureNotify: + return _filter_configure_notify(&xev->xconfigure); + case ConfigureRequest: + return _filter_configure_request( + &xev->xconfigurerequest, framer); + case CreateNotify: + return _filter_create_notify(&xev->xcreatewindow); + case DestroyNotify: + return _filter_destroy_notify(&xev->xdestroywindow); + case LeaveNotify: + return _filter_leave_notify(&xev->xcrossing); + case MapNotify: + return _filter_map_notify(&xev->xmap, framer); + case MapRequest: + return _filter_map_request(&xev->xmaprequest, framer); + case MotionNotify: + return _filter_motion_notify(&xev->xmotion); + case PropertyNotify: + return _filter_property_notify(&xev->xproperty, + framer); + case UnmapNotify: + return _filter_unmap_notify(&xev->xunmap); + default: + fprintf(stderr, "DEBUG: %s() type=%d\n", __func__, + xev->type); + break; + } + return GDK_FILTER_CONTINUE; +} + +static GdkFilterReturn _filter_client_message(XClientMessageEvent * xclient, + Framer * framer) +{ + GdkAtom atom; + char * name; + + atom = gdk_x11_xatom_to_atom_for_display(framer->display, + xclient->message_type); + name = gdk_atom_name(atom); +#ifdef DEBUG + fprintf(stderr, "DEBUG: %s() %s\n", __func__, name); +#endif + g_free(name); + return GDK_FILTER_CONTINUE; +} + +static GdkFilterReturn _filter_configure_notify(XConfigureEvent * xconfigure) +{ +#ifdef DEBUG + fprintf(stderr, "DEBUG: %s()\n", __func__); +#endif + return GDK_FILTER_CONTINUE; +} + +static GdkFilterReturn _filter_configure_request( + XConfigureRequestEvent * xconfigure, Framer * framer) +{ + XWindowChanges wc; + unsigned long mask = xconfigure->value_mask; + +#ifdef DEBUG + fprintf(stderr, "DEBUG: %s() (%d,%d) %dx%d %lu\n", __func__, + xconfigure->x, xconfigure->y, xconfigure->width, + xconfigure->height, xconfigure->value_mask); +#endif + memset(&wc, 0, sizeof(wc)); +#ifndef EMBEDDED + if(xconfigure->value_mask & CWX) + wc.x = max(xconfigure->x, 0); + if(xconfigure->value_mask & CWY) + wc.y = max(xconfigure->y, 0); + if(xconfigure->value_mask & CWWidth) + wc.width = min(xconfigure->width, framer->width); + if(xconfigure->value_mask & CWHeight) + wc.height = min(xconfigure->height, framer->height - 64); +#else + if(xconfigure->value_mask & (CWX | CWWidth)) + { + wc.x = 0; + wc.width = framer->width; + mask |= CWX | CWWidth; + } + if(xconfigure->value_mask & (CWY | CWHeight)) + { + wc.y = 0; + wc.height = framer->height - 64; + mask |= CWY | CWHeight; + } + if(xconfigure->value_mask & CWBorderWidth) + wc.border_width = 0; +#endif + XConfigureWindow(xconfigure->display, xconfigure->window, mask, &wc); + return GDK_FILTER_REMOVE; +} + +static GdkFilterReturn _filter_create_notify(XCreateWindowEvent * xcreate) +{ +#ifdef DEBUG + fprintf(stderr, "DEBUG: %s()\n", __func__); +#endif + return GDK_FILTER_CONTINUE; +} + +static GdkFilterReturn _filter_destroy_notify(XDestroyWindowEvent * xdestroy) +{ +#ifdef DEBUG + fprintf(stderr, "DEBUG: %s()\n", __func__); +#endif + return GDK_FILTER_CONTINUE; +} + +static GdkFilterReturn _filter_leave_notify(XCrossingEvent * xleave) +{ +#ifdef DEBUG + fprintf(stderr, "DEBUG: %s()\n", __func__); +#endif + return GDK_FILTER_CONTINUE; +} + +static GdkFilterReturn _filter_map_notify(XMapEvent * xmap, Framer * framer) +{ +#ifdef DEBUG + fprintf(stderr, "DEBUG: %s()\n", __func__); +#endif + return GDK_FILTER_CONTINUE; +} + +static GdkFilterReturn _filter_map_request(XMapRequestEvent * xmap, + Framer * framer) +{ +#ifdef DEBUG + fprintf(stderr, "DEBUG: %s()\n", __func__); +#endif + XMapWindow(xmap->display, xmap->window); + return GDK_FILTER_CONTINUE; +} + +static GdkFilterReturn _filter_motion_notify(XMotionEvent * xmotion) +{ +#ifdef DEBUG + fprintf(stderr, "DEBUG: %s()\n", __func__); +#endif + return GDK_FILTER_CONTINUE; +} + +static GdkFilterReturn _filter_property_notify(XPropertyEvent * xproperty, + Framer * framer) +{ + GdkAtom atom; + char * name; + + atom = gdk_x11_xatom_to_atom_for_display(framer->display, + xproperty->atom); + name = gdk_atom_name(atom); +#ifdef DEBUG + fprintf(stderr, "DEBUG: %s() %s\n", __func__, name); +#endif + g_free(name); + return GDK_FILTER_CONTINUE; +} + +static GdkFilterReturn _filter_unmap_notify(XUnmapEvent * xmap) +{ +#ifdef DEBUG + fprintf(stderr, "DEBUG: %s()\n", __func__); +#endif + return GDK_FILTER_CONTINUE; +} diff --git a/src/framer.h b/src/framer.h new file mode 100644 index 0000000..33a8728 --- /dev/null +++ b/src/framer.h @@ -0,0 +1,31 @@ +/* $Id$ */ +/* Copyright (c) 2009 Pierre Pronchery */ +/* This file is part of DeforaOS Desktop Framer */ +/* 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, version 3 of the License. + * + * 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 . */ + + + +#ifndef FRAMER_FRAMER_H +# define FRAMER_FRAMER_H + + +/* Framer */ +/* types */ +typedef struct _Framer Framer; + + +/* functions */ +Framer * framer_new(void); +void framer_delete(Framer * framer); + +#endif /* !FRAMER_FRAMER_H */ diff --git a/src/main.c b/src/main.c index 6291426..3aee63f 100644 --- a/src/main.c +++ b/src/main.c @@ -16,320 +16,9 @@ #include -#include #include -#include -#include #include -#include -#include -#include "../config.h" - -#define max(a, b) ((a) > (b) ? (a) : (b)) -#define min(a, b) ((a) < (b) ? (a) : (b)) - - -/* Framer */ -/* types */ -typedef enum _FramerAtom -{ - FA_NET_CURRENT_DESKTOP = 0, - FA_NET_NUMBER_OF_DESKTOPS -} FramerAtom; -#define FA_LAST FA_NET_NUMBER_OF_DESKTOPS -#define FA_COUNT (FA_LAST + 1) - -typedef struct _Framer -{ - GdkDisplay * display; - GdkScreen * screen; - GdkWindow * root; - int width; - int height; - Atom atom[FA_COUNT]; -} Framer; - - -/* constants */ -static char const * _framer_atom[FA_COUNT] = -{ - "_NET_CURRENT_DESKTOP", - "_NET_NUMBER_OF_DESKTOPS" -}; - - -/* prototypes */ -static Framer * _framer_new(void); -static void _framer_delete(Framer * framer); -static int _framer_error(char const * message, int ret); - -/* callbacks */ -static GdkFilterReturn _framer_filter(GdkXEvent * xevent, GdkEvent * event, - gpointer data); - - -/* functions */ -/* framer */ -static Framer * _framer_new(void) -{ - Framer * framer; - int i; - long cnt = 1; - long cur = 0; - - if((framer = malloc(sizeof(*framer))) == NULL) - { - _framer_error(strerror(errno), 1); - return NULL; - } - if((framer->display = gdk_display_get_default()) == NULL) - { - _framer_error("There is no default display", 1); - free(framer); - return NULL; - } - framer->screen = gdk_display_get_default_screen(framer->display); - framer->root = gdk_screen_get_root_window(framer->screen); - framer->width = gdk_screen_get_width(framer->screen); - framer->height = gdk_screen_get_height(framer->screen); - /* atoms */ - for(i = 0; i < FA_COUNT; i++) - framer->atom[i] = gdk_x11_get_xatom_by_name_for_display( - framer->display, _framer_atom[i]); - /* NETWM compliance */ - XChangeProperty(GDK_DISPLAY_XDISPLAY(framer->display), - GDK_WINDOW_XWINDOW(framer->root), - framer->atom[FA_NET_NUMBER_OF_DESKTOPS], XA_CARDINAL, - 32, PropModeReplace, (unsigned char *)&cnt, 1); - XChangeProperty(GDK_DISPLAY_XDISPLAY(framer->display), - GDK_WINDOW_XWINDOW(framer->root), - framer->atom[FA_NET_CURRENT_DESKTOP], XA_CARDINAL, - 32, PropModeReplace, (unsigned char *)&cur, 1); - /* register as window manager */ - XSelectInput(gdk_x11_display_get_xdisplay(framer->display), - GDK_WINDOW_XWINDOW(framer->root), NoEventMask - | SubstructureRedirectMask); - gdk_window_add_filter(framer->root, _framer_filter, framer); - return framer; -} - - -static void _framer_delete(Framer * framer) -{ - int i; - - for(i = 0; i < FA_COUNT; i++) - XDeleteProperty(GDK_DISPLAY_XDISPLAY(framer->display), - GDK_WINDOW_XWINDOW(framer->root), - framer->atom[i]); - free(framer); -} - - -/* framer error */ -static int _framer_error(char const * message, int ret) -{ - fprintf(stderr, "%s: %s\n", PACKAGE, message); - return ret; -} - - -/* callbacks */ -/* framer_filter */ -static GdkFilterReturn _filter_client_message(XClientMessageEvent * xclient, - Framer * framer); -static GdkFilterReturn _filter_configure_notify(XConfigureEvent * xconfigure); -static GdkFilterReturn _filter_configure_request( - XConfigureRequestEvent * xconfigure, Framer * framer); -static GdkFilterReturn _filter_create_notify(XCreateWindowEvent * xcreate); -static GdkFilterReturn _filter_destroy_notify(XDestroyWindowEvent * xdestroy); -static GdkFilterReturn _filter_leave_notify(XCrossingEvent * xleave); -static GdkFilterReturn _filter_map_notify(XMapEvent * xmap, Framer * framer); -static GdkFilterReturn _filter_map_request(XMapRequestEvent * xmap, - Framer * framer); -static GdkFilterReturn _filter_motion_notify(XMotionEvent * xmotion); -static GdkFilterReturn _filter_property_notify(XPropertyEvent * xproperty, - Framer * framer); -static GdkFilterReturn _filter_unmap_notify(XUnmapEvent * xmap); - -static GdkFilterReturn _framer_filter(GdkXEvent * xevent, GdkEvent * event, - gpointer data) -{ - Framer * framer = data; - XEvent * xev = xevent; - - switch(xev->type) - { - case ClientMessage: - return _filter_client_message(&xev->xclient, framer); - case ConfigureNotify: - return _filter_configure_notify(&xev->xconfigure); - case ConfigureRequest: - return _filter_configure_request( - &xev->xconfigurerequest, framer); - case CreateNotify: - return _filter_create_notify(&xev->xcreatewindow); - case DestroyNotify: - return _filter_destroy_notify(&xev->xdestroywindow); - case LeaveNotify: - return _filter_leave_notify(&xev->xcrossing); - case MapNotify: - return _filter_map_notify(&xev->xmap, framer); - case MapRequest: - return _filter_map_request(&xev->xmaprequest, framer); - case MotionNotify: - return _filter_motion_notify(&xev->xmotion); - case PropertyNotify: - return _filter_property_notify(&xev->xproperty, - framer); - case UnmapNotify: - return _filter_unmap_notify(&xev->xunmap); - default: - fprintf(stderr, "DEBUG: %s() type=%d\n", __func__, - xev->type); - break; - } - return GDK_FILTER_CONTINUE; -} - -static GdkFilterReturn _filter_client_message(XClientMessageEvent * xclient, - Framer * framer) -{ - GdkAtom atom; - char * name; - - atom = gdk_x11_xatom_to_atom_for_display(framer->display, - xclient->message_type); - name = gdk_atom_name(atom); -#ifdef DEBUG - fprintf(stderr, "DEBUG: %s() %s\n", __func__, name); -#endif - g_free(name); - return GDK_FILTER_CONTINUE; -} - -static GdkFilterReturn _filter_configure_notify(XConfigureEvent * xconfigure) -{ -#ifdef DEBUG - fprintf(stderr, "DEBUG: %s()\n", __func__); -#endif - return GDK_FILTER_CONTINUE; -} - -static GdkFilterReturn _filter_configure_request( - XConfigureRequestEvent * xconfigure, Framer * framer) -{ - XWindowChanges wc; - unsigned long mask = xconfigure->value_mask; - -#ifdef DEBUG - fprintf(stderr, "DEBUG: %s() (%d,%d) %dx%d %lu\n", __func__, - xconfigure->x, xconfigure->y, xconfigure->width, - xconfigure->height, xconfigure->value_mask); -#endif - memset(&wc, 0, sizeof(wc)); -#ifndef EMBEDDED - if(xconfigure->value_mask & CWX) - wc.x = max(xconfigure->x, 0); - if(xconfigure->value_mask & CWY) - wc.y = max(xconfigure->y, 0); - if(xconfigure->value_mask & CWWidth) - wc.width = min(xconfigure->width, framer->width); - if(xconfigure->value_mask & CWHeight) - wc.height = min(xconfigure->height, framer->height - 64); -#else - if(xconfigure->value_mask & (CWX | CWWidth)) - { - wc.x = 0; - wc.width = framer->width; - mask |= CWX | CWWidth; - } - if(xconfigure->value_mask & (CWY | CWHeight)) - { - wc.y = 0; - wc.height = framer->height - 64; - mask |= CWY | CWHeight; - } - if(xconfigure->value_mask & CWBorderWidth) - wc.border_width = 0; -#endif - XConfigureWindow(xconfigure->display, xconfigure->window, mask, &wc); - return GDK_FILTER_REMOVE; -} - -static GdkFilterReturn _filter_create_notify(XCreateWindowEvent * xcreate) -{ -#ifdef DEBUG - fprintf(stderr, "DEBUG: %s()\n", __func__); -#endif - return GDK_FILTER_CONTINUE; -} - -static GdkFilterReturn _filter_destroy_notify(XDestroyWindowEvent * xdestroy) -{ -#ifdef DEBUG - fprintf(stderr, "DEBUG: %s()\n", __func__); -#endif - return GDK_FILTER_CONTINUE; -} - -static GdkFilterReturn _filter_leave_notify(XCrossingEvent * xleave) -{ -#ifdef DEBUG - fprintf(stderr, "DEBUG: %s()\n", __func__); -#endif - return GDK_FILTER_CONTINUE; -} - -static GdkFilterReturn _filter_map_notify(XMapEvent * xmap, Framer * framer) -{ -#ifdef DEBUG - fprintf(stderr, "DEBUG: %s()\n", __func__); -#endif - return GDK_FILTER_CONTINUE; -} - -static GdkFilterReturn _filter_map_request(XMapRequestEvent * xmap, - Framer * framer) -{ -#ifdef DEBUG - fprintf(stderr, "DEBUG: %s()\n", __func__); -#endif - XMapWindow(xmap->display, xmap->window); - return GDK_FILTER_CONTINUE; -} - -static GdkFilterReturn _filter_motion_notify(XMotionEvent * xmotion) -{ -#ifdef DEBUG - fprintf(stderr, "DEBUG: %s()\n", __func__); -#endif - return GDK_FILTER_CONTINUE; -} - -static GdkFilterReturn _filter_property_notify(XPropertyEvent * xproperty, - Framer * framer) -{ - GdkAtom atom; - char * name; - - atom = gdk_x11_xatom_to_atom_for_display(framer->display, - xproperty->atom); - name = gdk_atom_name(atom); -#ifdef DEBUG - fprintf(stderr, "DEBUG: %s() %s\n", __func__, name); -#endif - g_free(name); - return GDK_FILTER_CONTINUE; -} - -static GdkFilterReturn _filter_unmap_notify(XUnmapEvent * xmap) -{ -#ifdef DEBUG - fprintf(stderr, "DEBUG: %s()\n", __func__); -#endif - return GDK_FILTER_CONTINUE; -} +#include "framer.h" /* usage */ @@ -353,9 +42,9 @@ int main(int argc, char * argv[]) default: return _usage(); } - if((framer = _framer_new()) == NULL) + if((framer = framer_new()) == NULL) return 2; gtk_main(); - _framer_delete(framer); + framer_delete(framer); return 0; } diff --git a/src/project.conf b/src/project.conf index f86dc40..d725476 100644 --- a/src/project.conf +++ b/src/project.conf @@ -9,5 +9,5 @@ dist=Makefile [framer] type=binary -sources=main.c +sources=framer.c,main.c install=$(BINDIR)