summaryrefslogtreecommitdiffstats
path: root/twin/kompmgr/kompmgr.c
diff options
context:
space:
mode:
Diffstat (limited to 'twin/kompmgr/kompmgr.c')
-rw-r--r--twin/kompmgr/kompmgr.c3960
1 files changed, 0 insertions, 3960 deletions
diff --git a/twin/kompmgr/kompmgr.c b/twin/kompmgr/kompmgr.c
deleted file mode 100644
index 150c06bb8..000000000
--- a/twin/kompmgr/kompmgr.c
+++ /dev/null
@@ -1,3960 +0,0 @@
-/*
- * $Id$
- *
- * Copyright © 2003 Keith Packard
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of Keith Packard not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission. Keith Packard makes no
- * representations about the suitability of this software for any purpose. It
- * is provided "as is" without express or implied warranty.
- *
- * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, 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 OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-
-/* Modified by Matthew Hawn. I don't know what to say here so follow what it
- says above. Not that I can really do anything about it
-*/
-
-/* Modified by Dan Doel*/
-
-/* Modified by Timothy Pearson
- *
- * CHANGELOG:
- * http://patchwork.freedesktop.org/patch/1049/ [Add default background color option] 08/11/2011
- * http://patchwork.freedesktop.org/patch/1052/ [Prevent flicker on root pixmap change] 08/11/2011
- * Added SIGUSR1 handler to change process UID [Prevent flicker on login] 08/12/2011
- * Added ability to write PID of process to home directory 08/14/2011
- * Added SIGUSR2 handler to reload settings [Prevent flicker on settings change] 08/14/2011
- * Added SIGTERM handler to clean up stale PID files on exit 08/14/2011
- * Added hack to work around ATI fglrx XDamage event generation bugs [WORK_AROUND_FGLRX] 09/01/2011
- * Redraw root window automatically when X damage events are detected (this fixes xsetroot) 10/23/2011
- *
- * TODO:
- * http://patchwork.freedesktop.org/patch/1053/ [Fix window mapping with re-used window ids]
-*/
-
-/*
-Version 2.x of xcompmgr, kompmgr changes by Thomas L�bking and Heiko Przybyl
-check baghira.sf.net for more infos
-*/
-
-#define _VERSION_ 2.02
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <math.h>
-#include <sys/poll.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <signal.h>
-#include <time.h>
-#include <unistd.h>
-#include <libgen.h>
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
-#include <X11/Xatom.h>
-#include <X11/extensions/Xcomposite.h>
-#include <X11/extensions/Xdamage.h>
-#include <X11/extensions/Xrender.h>
-#include <X11/extensions/shape.h>
-
-#if COMPOSITE_MAJOR > 0 || COMPOSITE_MINOR >= 2
-#define HAS_NAME_WINDOW_PIXMAP 1
-#endif
-
-#define CAN_DO_USABLE 1
-
-#define WORK_AROUND_FGLRX 1
-
-#define _TOPHEIGHT_(x) ((x >> 24) & 0xff)
-#define _RIGHTWIDTH_(x) ((x >> 16) & 0xff)
-#define _BOTTOMHEIGHT_(x) ((x >> 8) & 0xff)
-#define _LEFTWIDTH_(x) (x & 0xff)
-
-/* #define USE_ENV_HOME 1 */
-#define WRITE_PID_FILE 1
-
-#ifndef USE_ENV_HOME
-#include <pwd.h>
-#endif
-
-typedef enum {
- WINTYPE_DESKTOP,
- WINTYPE_DOCK,
- WINTYPE_TOOLBAR,
- WINTYPE_MENU,
- WINTYPE_UTILITY,
- WINTYPE_SPLASH,
- WINTYPE_DIALOG,
- WINTYPE_NORMAL,
- WINTYPE_DROPDOWN_MENU,
- WINTYPE_POPUP_MENU,
- WINTYPE_TOOLTIP,
- WINTYPE_NOTIFY,
- WINTYPE_COMBO,
- WINTYPE_DND,
- NUM_WINTYPES
-} wintype;
-
-typedef struct _ignore {
- struct _ignore *next;
- unsigned long sequence;
-} ignore;
-
-typedef struct _win {
- struct _win *next;
- Window id;
-#if HAS_NAME_WINDOW_PIXMAP
- Pixmap pixmap;
-#endif
- XWindowAttributes a;
- XWindowAttributes a_prev;
-#if CAN_DO_USABLE
- Bool usable; /* mapped and all damaged at one point */
- XRectangle damage_bounds; /* bounds of damage */
-#endif
- Bool isInFade;
- int mode;
- int damaged;
- Damage damage;
- Picture picture;
- Picture alphaPict;
- Picture shadowPict;
- XserverRegion borderSize;
- XserverRegion decoRegion;
- XserverRegion contentRegion;
- XserverRegion extents;
- unsigned int preShadeOpacity;
- Picture shadow;
- /*Picture alpha;*/
- int shadow_dx;
- int shadow_dy;
- int shadow_width;
- int shadow_height;
- unsigned int opacity;
- unsigned int shadowSize;
- wintype windowType;
- unsigned long damage_sequence; /* sequence when damage was created */
- int destroyed;
- Bool destruct_queued;
- Bool destruct_requested;
- int destruct_request_time;
- Bool shapable; /* this will allow window managers to exclude windows if just the deco is shaped*/
- Bool shaped;
- XRectangle shape_bounds;
- XRectangle shape_bounds_prev;
- unsigned int decoHash;
- Picture dimPicture;
-
- /* for drawing translucent windows */
- XserverRegion borderClip;
- struct _win *prev_trans;
-
- /* setting whether a window will be transparent to the desktop or the windows below it */
- Bool show_root_tile;
-
- /* setting whether a window will be transparent to a black background or something else */
- Bool show_black_background;
-} win;
-
-typedef struct _conv {
- int size;
- double *data;
-} conv;
-
-typedef struct _fade {
- struct _fade *next;
- win *w;
- double cur;
- double finish;
- double step;
- void (*callback) (Display *dpy, win *w, Bool gone);
- Display *dpy;
- unsigned int decoHash;
- Bool gone;
-} fade;
-
-struct sigaction usr_action;
-sigset_t block_mask;
-
-int my_exit_code = 3;
-
-win *list;
-fade *fades;
-Display *dpy;
-char *display = 0;
-int scr;
-Window root;
-Picture rootPicture;
-Picture rootBuffer;
-Picture blackPicture;
-Picture transBlackPicture;
-Picture rootTile;
-XserverRegion allDamage;
-Bool clipChanged;
-#if HAS_NAME_WINDOW_PIXMAP
-Bool hasNamePixmap;
-#endif
-XRenderColor fill_color;
-int root_height, root_width;
-ignore *ignore_head, **ignore_tail = &ignore_head;
-int xfixes_event, xfixes_error;
-int damage_event, damage_error;
-int composite_event, composite_error;
-int render_event, render_error;
-int xshape_event, xshape_error;
-Bool synchronize;
-int composite_opcode;
-Bool screen_damaged = False;
-Bool disable_argb = False;
-
-int shapeEvent;
-
-/* find these once and be done with it */
-Atom opacityAtom;
-Atom shadowAtom;
-Atom shadeAtom;
-Atom shapableAtom;
-Atom decoHashAtom;
-Atom dimAtom;
-Atom deskChangeAtom;
-Atom winTypeAtom;
-Atom winTDETTDAtom;
-Atom winTDETTBAtom;
-Atom winType[NUM_WINTYPES];
-double winTypeOpacity[NUM_WINTYPES];
-Bool winTypeShadow[NUM_WINTYPES];
-Bool winTypeFade[NUM_WINTYPES];
-
-/* opacity property name; sometime soon I'll write up an EWMH spec for it */
-#define OPACITY_PROP "_TDE_WM_WINDOW_OPACITY"
-#define SHADOW_PROP "_TDE_WM_WINDOW_SHADOW"
-#define SHADE_PROP "_TDE_WM_WINDOW_SHADE"
-#define SHAPABLE_PROP "_TDE_WM_WINDOW_SHAPABLE"
-#define DECOHASH_PROP "_TDE_WM_WINDOW_DECOHASH"
-#define DIM_PROP "_TDE_WM_WINDOW_DIM"
-#define DESKCHANGE_PROP "_TDE_WM_DESKTOP_CHANGE"
-
-#define TRANSLUCENT 0xe0000000
-#define OPAQUE 0xffffffff
-
-conv *gaussianMap;
-
-#define WINDOW_SOLID 0
-#define WINDOW_TRANS 1
-#define WINDOW_ARGB 2
-
-#define TRANS_OPACITY 0.75
-
-#define NDEBUG 1
-#define DEBUG_REPAINT 0
-#define DEBUG_WINDOWS 0
-#define DEBUG_EVENTS 0
-#define MONITOR_REPAINT 0
-
-#define SHADOWS 1
-#define SHARP_SHADOW 0
-
-typedef enum _compMode {
- CompSimple, /* looks like a regular X server */
- CompServerShadows, /* use window alpha for shadow; sharp, but precise */
- CompClientShadows /* use window extents for shadow, blurred */
-} CompMode;
-
-static void
-determine_mode(Display *dpy, win *w);
-
-static double
-get_opacity_percent(Display *dpy, win *w);
-
-static XserverRegion
-win_extents (Display *dpy, win *w);
-
-static void
-presum_gaussian (conv *map);
-
-static conv *
-make_gaussian_map (Display *dpy, double r);
-
-Picture
-solid_picture (Display *dpy, Bool argb, double a, double r, double g, double b);
-
-CompMode compMode = CompSimple;
-
-int shadowRadius = 12;
-int shadowOffsetX = 0;
-int shadowOffsetY = 0;
-double shadowOpacity = .75;
-XRenderColor shadowColor;
-
-double fade_in_step = 0.028;
-double fade_out_step = 0.03;
-int fade_delta = 10;
-int fade_time = 0;
-Bool fadeTrans = False;
-
-Bool autoRedirect = False;
-
-#if WORK_AROUND_FGLRX
-Bool restartOnSigterm = True;
-#endif
-
-/* For shadow precomputation */
-int Gsize = -1;
-unsigned char *shadowCorner = NULL;
-unsigned char *shadowTop = NULL;
-
-XRenderPictFormat* sXRenderFindVisualFormat(Display *dpy, _Xconst Visual *visual)
-{
- XRenderPictFormat* format = XRenderFindVisualFormat(dpy,visual);
- if (format)
- return format;
- else
- return XRenderFindStandardFormat (dpy, PictStandardRGB24);
-}
-
-int
-get_time_in_milliseconds ()
-{
- struct timeval tv;
-
- gettimeofday (&tv, NULL);
- return tv.tv_sec * 1000 + tv.tv_usec / 1000;
-}
-
-void write_pid_file(pid_t pid)
-{
-#ifdef WRITE_PID_FILE
-#ifdef USE_ENV_HOME
- const char *home = getenv("HOME");
-#else
- const char *home;
- struct passwd *p;
- p = getpwuid(getuid());
- if (p)
- home = p->pw_dir;
- else
- home = getenv("HOME");
-#endif
- const char *filename;
- const char *configfile = "/.kompmgr.pid";
- int n = strlen(home)+strlen(configfile)+1;
- filename = (char*)malloc(n*sizeof(char));
- memset(filename,0,n);
- strcat(filename, home);
- strcat(filename, configfile);
-
- printf("writing '%s' as pidfile\n\n", filename);
-
- /* now that we did all that by way of introduction...write the file! */
- FILE *pFile;
- char buffer[255];
- sprintf(buffer, "%d", pid);
- pFile = fopen(filename, "w");
- if (pFile) {
- fwrite(buffer,1,strlen(buffer), pFile);
- fclose(pFile);
- }
-
- free(filename);
- filename = NULL;
-#endif
-}
-
-void delete_pid_file()
-{
-#ifdef WRITE_PID_FILE
-#ifdef USE_ENV_HOME
- const char *home = getenv("HOME");
-#else
- const char *home;
- struct passwd *p;
- p = getpwuid(getuid());
- if (p)
- home = p->pw_dir;
- else
- home = getenv("HOME");
-#endif
- const char *filename;
- const char *configfile = "/.kompmgr.pid";
- int n = strlen(home)+strlen(configfile)+1;
- filename = (char*)malloc(n*sizeof(char));
- memset(filename,0,n);
- strcat(filename, home);
- strcat(filename, configfile);
-
- printf("deleting '%s' as pidfile\n\n", filename);
-
- /* now that we did all that by way of introduction...delete the file! */
- unlink(filename);
-
- free(filename);
- filename = NULL;
-#endif
-
-#if WORK_AROUND_FGLRX
- if ((my_exit_code == 3) && (restartOnSigterm)) {
- printf("kompmgr lost connection to X server, restarting...\n"); fflush(stdout);
- sleep(1);
- char me[2048];
- int chars = readlink("/proc/self/exe", me, sizeof(me));
- me[chars] = 0;
- me[2047] = 0;
- execl(me, basename(me), (char*)NULL);
- }
-#endif
-}
-
-void clear_shadow_cache()
-{
- win *w;
-
- for (w = list; w; w = w->next) {
- if (w->shadow)
- {
- XRenderFreePicture (dpy, w->shadow);
- w->shadow = None;
- if (w->opacity != OPAQUE && !w->alphaPict)
- w->alphaPict = solid_picture (dpy, False,
- (double) w->opacity / OPAQUE, shadowColor.red, shadowColor.green, shadowColor.blue);
- if( w->extents != None ) {
- XFixesDestroyRegion( dpy, w->extents );
- }
- w->extents = win_extents (dpy, w);
- w->damaged = 1; /* redraw */
- }
- }
-}
-
-void handle_siguser (int sig)
-{
- int uidnum;
- if (sig == SIGTERM) {
- my_exit_code=0;
- delete_pid_file();
- exit(0);
- }
- if (sig == SIGUSR1) {
- char newuid[1024];
-#ifndef NDEBUG
- printf("Enter the new user ID:\n"); fflush(stdout);
-#endif
- char *eof;
- newuid[0] = '\0';
- newuid[sizeof(newuid)-1] = '\0';
- eof = fgets(newuid, sizeof(newuid), stdin);
- uidnum = atoi(newuid);
-#ifndef NDEBUG
- printf("Setting kompmgr process uid to %d...\n", uidnum); fflush(stdout);
-#endif
-
- my_exit_code=4;
- delete_pid_file();
- my_exit_code=3;
- setuid(uidnum);
- write_pid_file(getpid());
-
- }
- else {
- uidnum = getuid();
- }
- if ((sig == SIGUSR1) || (sig == SIGUSR2)) {
-#ifdef USE_ENV_HOME
- const char *home = getenv("HOME");
-#else
- const char *home;
- struct passwd *p;
- p = getpwuid(uidnum);
- if (p)
- home = p->pw_dir;
- else
- home = getenv("HOME");
-#endif
- const char *filename;
- const char *configfile = "/.xcompmgrrc";
- int n = strlen(home)+strlen(configfile)+1;
- filename = (char*)malloc(n*sizeof(char));
- memset(filename,0,n);
- strcat(filename, home);
- strcat(filename, configfile);
-
- loadConfig(filename); /* reload the configuration file */
-
- /* set background/shadow picture using the new settings */
- blackPicture = solid_picture (dpy, True, 1, (double)(shadowColor.red)/0xff, (double)(shadowColor.green)/0xff, (double)(shadowColor.blue)/0xff);
- if (compMode == CompServerShadows)
- transBlackPicture = solid_picture (dpy, True, 0.3, 0, 0, 0);
-
- /* regenerate shadows using the new settings */
- if (compMode == CompClientShadows)
- {
- gaussianMap = make_gaussian_map(dpy, shadowRadius);
- presum_gaussian (gaussianMap);
- }
- clear_shadow_cache();
-
- free(filename);
- filename = NULL;
- }
-}
-
-fade *
-find_fade (win *w)
-{
- fade *f;
-
- for (f = fades; f; f = f->next)
- {
- if (f->w == w)
- return f;
- }
- return 0;
-}
-
-void dequeue_fade (Display *dpy, fade *f)
-{
- fade **prev;
- f->w->isInFade = False;
- f->w->decoHash = f->decoHash;
-
- for (prev = &fades; *prev; prev = &(*prev)->next)
- if (*prev == f)
- {
- *prev = f->next;
- if (f->callback)
- {
- (*f->callback) (dpy, f->w, f->gone);
- }
- free (f);
- break;
- }
-}
-
-void
-cleanup_fade (Display *dpy, win *w)
-{
- fade *f = find_fade (w);
- if (f)
- dequeue_fade (dpy, f);
-}
-
-void
-enqueue_fade (Display *dpy, fade *f)
-{
- f->w->isInFade = True;
- if (!fades)
- fade_time = get_time_in_milliseconds () + fade_delta;
- f->next = fades;
- fades = f;
-}
-
-static void unmap_callback (Display *dpy, win *w, Bool gone);
-
-static void
-set_fade (Display *dpy, win *w, double start, double finish, double step,
- void (*callback) (Display *dpy, win *w, Bool gone),
- Bool gone, Bool exec_callback, Bool override, Bool wholeWin)
-{
- fade *f;
-
- f = find_fade (w);
- if (!f)
- {
- if (start == finish)
- return;
- f = malloc (sizeof (fade));
- f->next = 0;
- f->w = w;
- f->decoHash = w->decoHash;
- f->cur = start;
- enqueue_fade (dpy, f);
- }
- else if(!override)
- return;
- else
- {
- if (exec_callback && f->callback)
- (*f->callback)(dpy, f->w, f->gone);
- }
- if (finish < 0)
- finish = 0;
- if (finish > 1)
- finish = 1;
- f->finish = finish;
- if (f->cur < finish)
- f->step = step;
- else if (f->cur > finish)
- f->step = -step;
- f->gone = gone && (exec_callback || f->callback != unmap_callback);
- f->callback = callback;
- w->opacity = f->cur * OPAQUE;
- if (wholeWin)
- w->decoHash = 0;
-#if 0
- printf ("set_fade start %g step %g\n", f->cur, f->step);
-#endif
- determine_mode (dpy, w);
- if (w->shadow)
- {
- XRenderFreePicture (dpy, w->shadow);
- w->shadow = None;
- if( w->extents != None )
- XFixesDestroyRegion( dpy, w->extents );
- w->extents = win_extents (dpy, w);
- }
-
- /* fading windows need to be drawn, mark them as damaged.
- when a window maps, if it tries to fade in but it already at the right
- opacity (map/unmap/map fast) then it will never get drawn without this
- until it repaints */
- w->damaged = 1;
-}
-
- int
-fade_timeout (void)
-{
- int now;
- int delta;
- if (!fades)
- return -1;
- now = get_time_in_milliseconds();
- delta = fade_time - now;
- if (delta < 0)
- delta = 0;
- /* printf ("timeout %d\n", delta); */
- return delta;
-}
-
- void
-run_fades (Display *dpy)
-{
- int now = get_time_in_milliseconds();
- fade *f, *next;
- int steps;
- Bool need_dequeue;
-
-#if 0
- printf ("run fades\n");
-#endif
- if (fade_time - now > 0)
- return;
- steps = 1 + (now - fade_time) / fade_delta;
- for (next = fades; (f = next); )
- {
- win *w = f->w;
- next = f->next;
- f->cur += f->step * steps;
- if (f->cur >= 1)
- f->cur = 1;
- else if (f->cur < 0)
- f->cur = 0;
-#if 0
- printf ("opacity now %g -> %g\n", f->cur, f->finish);
-#endif
- w->opacity = f->cur * OPAQUE;
- need_dequeue = False;
- if (f->step > 0)
- {
- if (f->cur >= f->finish)
- {
- w->opacity = f->finish*OPAQUE;
- need_dequeue = True;
- }
- }
- else
- {
- if (f->cur <= f->finish)
- {
- w->opacity = f->finish*OPAQUE;
- need_dequeue = True;
- }
- }
- if (w->shadow)
- {
- XRenderFreePicture (dpy, w->shadow);
- w->shadow = None;
- if( w->extents != None )
- XFixesDestroyRegion( dpy, w->extents );
- w->extents = win_extents(dpy, w);
- }
- determine_mode (dpy, w);
- /* Must do this last as it might destroy f->w in callbacks */
- if (need_dequeue)
- dequeue_fade (dpy, f);
- }
- fade_time = now + fade_delta;
-}
-
-#define SHADOW_OFFSET_X ((-shadowRadius * 7 / 5) - shadowOffsetX * shadowRadius / 100) * w->shadowSize
-#define SHADOW_OFFSET_Y ((-shadowRadius * 7 / 5) - shadowOffsetY * shadowRadius / 100) * w->shadowSize
-/*#define SHADOW_OFFSET_X (w->shadowSize * -shadowRadius * 7 / 500) - w->shadowSize * shadowOffsetX * shadowRadius / 10000
-#define SHADOW_OFFSET_Y (w->shadowSize * -shadowRadius * 7 / 500) - w->shadowSize * shadowOffsetY * shadowRadius / 10000*/
-
- static double
-gaussian (double r, double x, double y)
-{
- return ((1 / (sqrt (2 * M_PI * r))) *
- exp ((- (x * x + y * y)) / (2 * r * r)));
-}
-
-
- static conv *
-make_gaussian_map (Display *dpy, double r)
-{
- conv *c;
- int size = ((int) ceil ((r * 3)) + 1) & ~1;
- int center = size / 2;
- int x, y;
- double t;
- double g;
-
- c = malloc (sizeof (conv) + size * size * sizeof (double));
- c->size = size;
- c->data = (double *) (c + 1);
- t = 0.0;
- for (y = 0; y < size; y++)
- for (x = 0; x < size; x++)
- {
- g = gaussian (r, (double) (x - center), (double) (y - center));
- t += g;
- c->data[y * size + x] = g;
- }
- /* printf ("gaussian total %f\n", t); */
- for (y = 0; y < size; y++)
- for (x = 0; x < size; x++)
- {
- c->data[y*size + x] /= t;
- }
- return c;
-}
-
-/*
- * A picture will help
- *
- * -center 0 width width+center
- * -center +-----+-------------------+-----+
- * | | | |
- * | | | |
- * 0 +-----+-------------------+-----+
- * | | | |
- * | | | |
- * | | | |
- * height +-----+-------------------+-----+
- * | | | |
- * height+ | | | |
- * center +-----+-------------------+-----+
- */
-
- static unsigned char
-sum_gaussian (conv *map, double opacity, int x, int y, int width, int height)
-{
- int fx, fy;
- double *g_data;
- double *g_line = map->data;
- int g_size = map->size;
- int center = g_size / 2;
- int fx_start, fx_end;
- int fy_start, fy_end;
- double v;
-
- /*
- * Compute set of filter values which are "in range",
- * that's the set with:
- * 0 <= x + (fx-center) && x + (fx-center) < width &&
- * 0 <= y + (fy-center) && y + (fy-center) < height
- *
- * 0 <= x + (fx - center) x + fx - center < width
- * center - x <= fx fx < width + center - x
- */
-
- fx_start = center - x;
- if (fx_start < 0)
- fx_start = 0;
- fx_end = width + center - x;
- if (fx_end > g_size)
- fx_end = g_size;
-
- fy_start = center - y;
- if (fy_start < 0)
- fy_start = 0;
- fy_end = height + center - y;
- if (fy_end > g_size)
- fy_end = g_size;
-
- g_line = g_line + fy_start * g_size + fx_start;
-
- v = 0;
- for (fy = fy_start; fy < fy_end; fy++)
- {
- g_data = g_line;
- g_line += g_size;
-
- for (fx = fx_start; fx < fx_end; fx++)
- v += *g_data++;
- }
- if (v > 1)
- v = 1;
-
- return ((unsigned char) (v * opacity * 255.0));
-}
-
-/* precompute shadow corners and sides to save time for large windows */
- static void
-presum_gaussian (conv *map)
-{
- int center = map->size/2;
- int opacity, x, y;
-
- Gsize = map->size;
-
- if (shadowCorner)
- free ((void *)shadowCorner);
- if (shadowTop)
- free ((void *)shadowTop);
-
- shadowCorner = (unsigned char *)(malloc ((Gsize + 1) * (Gsize + 1) * 26));
- shadowTop = (unsigned char *)(malloc ((Gsize + 1) * 26));
-
- for (x = 0; x <= Gsize; x++)
- {
- shadowTop[25 * (Gsize + 1) + x] = sum_gaussian (map, 1, x - center, center, Gsize * 2, Gsize * 2);
- for(opacity = 0; opacity < 25; opacity++)
- shadowTop[opacity * (Gsize + 1) + x] = shadowTop[25 * (Gsize + 1) + x] * opacity / 25;
- for(y = 0; y <= x; y++)
- {
- shadowCorner[25 * (Gsize + 1) * (Gsize + 1) + y * (Gsize + 1) + x]
- = sum_gaussian (map, 1, x - center, y - center, Gsize * 2, Gsize * 2);
- shadowCorner[25 * (Gsize + 1) * (Gsize + 1) + x * (Gsize + 1) + y]
- = shadowCorner[25 * (Gsize + 1) * (Gsize + 1) + y * (Gsize + 1) + x];
- for(opacity = 0; opacity < 25; opacity++)
- shadowCorner[opacity * (Gsize + 1) * (Gsize + 1) + y * (Gsize + 1) + x]
- = shadowCorner[opacity * (Gsize + 1) * (Gsize + 1) + x * (Gsize + 1) + y]
- = shadowCorner[25 * (Gsize + 1) * (Gsize + 1) + y * (Gsize + 1) + x] * opacity / 25;
- }
- }
-}
-
- static XImage *
-make_shadow (Display *dpy, double opacity, int width, int height)
-{
- XImage *ximage;
- unsigned char *data;
- int gsize = gaussianMap->size;
- int ylimit, xlimit;
- int swidth = width + gsize;
- int sheight = height + gsize;
- int center = gsize / 2;
- int x, y;
- unsigned char d;
- int x_diff;
- int opacity_int = (int)(opacity * 25);
- data = malloc (swidth * sheight * sizeof (unsigned char));
- if (!data)
- return 0;
- ximage = XCreateImage (dpy,
- DefaultVisual(dpy, DefaultScreen(dpy)),
- 8,
- ZPixmap,
- 0,
- (char *) data,
- swidth, sheight, 8, swidth * sizeof (unsigned char));
- if (!ximage)
- {
- free (data);
- return 0;
- }
- /*
- * Build the gaussian in sections
- */
-
- /*
- * center (fill the complete data array)
- */
- if (Gsize > 0)
- d = shadowTop[opacity_int * (Gsize + 1) + Gsize];
- else
- d = sum_gaussian (gaussianMap, opacity, center, center, width, height);
- memset(data, d, sheight * swidth);
-
- /*
- * corners
- */
- ylimit = gsize;
- if (ylimit > sheight / 2)
- ylimit = (sheight + 1) / 2;
- xlimit = gsize;
- if (xlimit > swidth / 2)
- xlimit = (swidth + 1) / 2;
-
- for (y = 0; y < ylimit; y++)
- for (x = 0; x < xlimit; x++)
- {
- if (xlimit == Gsize && ylimit == Gsize)
- d = shadowCorner[opacity_int * (Gsize + 1) * (Gsize + 1) + y * (Gsize + 1) + x];
- else
- d = sum_gaussian (gaussianMap, opacity, x - center, y - center, width, height);
- data[y * swidth + x] = d;
- data[(sheight - y - 1) * swidth + x] = d;
- data[(sheight - y - 1) * swidth + (swidth - x - 1)] = d;
- data[y * swidth + (swidth - x - 1)] = d;
- }
-
- /*
- * top/bottom
- */
- x_diff = swidth - (gsize * 2);
- if (x_diff > 0 && ylimit > 0)
- {
- for (y = 0; y < ylimit; y++)
- {
- if (ylimit == Gsize)
- d = shadowTop[opacity_int * (Gsize + 1) + y];
- else
- d = sum_gaussian (gaussianMap, opacity, center, y - center, width, height);
- memset (&data[y * swidth + gsize], d, x_diff);
- memset (&data[(sheight - y - 1) * swidth + gsize], d, x_diff);
- }
- }
-
- /*
- * sides
- */
-
- for (x = 0; x < xlimit; x++)
- {
- if (xlimit == Gsize)
- d = shadowTop[opacity_int * (Gsize + 1) + x];
- else
- d = sum_gaussian (gaussianMap, opacity, x - center, center, width, height);
- for (y = gsize; y < sheight - gsize; y++)
- {
- data[y * swidth + x] = d;
- data[y * swidth + (swidth - x - 1)] = d;
- }
- }
-
- return ximage;
-}
-
- static Picture
-shadow_picture (Display *dpy, double opacity, Picture alpha_pict, int width, int height, int *wp, int *hp)
-{
- XImage *shadowImage;
- Pixmap shadowPixmap;
- Pixmap finalPixmap;
- Picture shadowPicture;
- Picture finalPicture;
- GC gc;
-
- shadowImage = make_shadow (dpy, opacity, width, height);
- if (!shadowImage)
- return None;
- shadowPixmap = XCreatePixmap (dpy, root,
- shadowImage->width,
- shadowImage->height,
- 8);
- if (!shadowPixmap)
- {
- XDestroyImage (shadowImage);
- return None;
- }
-
- shadowPicture = XRenderCreatePicture (dpy, shadowPixmap,
- XRenderFindStandardFormat (dpy, PictStandardA8),
- 0, 0);
- if (!shadowPicture)
- {
- XDestroyImage (shadowImage);
- XFreePixmap (dpy, shadowPixmap);
- return None;
- }
-
- gc = XCreateGC (dpy, shadowPixmap, 0, 0);
- if (!gc)
- {
- XDestroyImage (shadowImage);
- XFreePixmap (dpy, shadowPixmap);
- XRenderFreePicture (dpy, shadowPicture);
- return None;
- }
-
- XPutImage (dpy, shadowPixmap, gc, shadowImage, 0, 0, 0, 0,
- shadowImage->width,
- shadowImage->height);
- *wp = shadowImage->width;
- *hp = shadowImage->height;
- XFreeGC (dpy, gc);
- XDestroyImage (shadowImage);
- XFreePixmap (dpy, shadowPixmap);
- return shadowPicture;
-}
-
- Picture
-solid_picture (Display *dpy, Bool argb, double a, double r, double g, double b)
-{
- Pixmap pixmap;
- Picture picture;
- XRenderPictureAttributes pa;
- XRenderColor c;
-
- pixmap = XCreatePixmap (dpy, root, 1, 1, argb ? 32 : 8);
- if (!pixmap)
- return None;
-
- pa.repeat = True;
- picture = XRenderCreatePicture (dpy, pixmap,
- XRenderFindStandardFormat (dpy, argb ? PictStandardARGB32 : PictStandardA8),
- CPRepeat,
- &pa);
- if (!picture)
- {
- XFreePixmap (dpy, pixmap);
- return None;
- }
-
- c.alpha = a * 0xffff;
- c.red = r * 0xffff;
- c.green = g * 0xffff;
- c.blue = b * 0xffff;
- XRenderFillRectangle (dpy, PictOpSrc, picture, &c, 0, 0, 1, 1);
- XFreePixmap (dpy, pixmap);
- return picture;
-}
-
- void
-discard_ignore (Display *dpy, unsigned long sequence)
-{
- while (ignore_head)
- {
- if ((long) (sequence - ignore_head->sequence) > 0)
- {
- ignore *next = ignore_head->next;
- free (ignore_head);
- ignore_head = next;
- if (!ignore_head)
- ignore_tail = &ignore_head;
- }
- else
- break;
- }
-}
-
- void
-set_ignore (Display *dpy, unsigned long sequence)
-{
- ignore *i = malloc (sizeof (ignore));
- if (!i) {
- return;
- }
- i->sequence = sequence;
- i->next = 0;
- *ignore_tail = i;
- ignore_tail = &i->next;
-}
-
- int
-should_ignore (Display *dpy, unsigned long sequence)
-{
- discard_ignore (dpy, sequence);
- return ignore_head && ignore_head->sequence == sequence;
-}
-
- static win *
-find_win (Display *dpy, Window id)
-{
- win *w;
-
- for (w = list; w; w = w->next) {
- if ((!w->destroyed) && (w->id == id)) {
- return w;
- }
- }
- return 0;
-}
-
-static char *backgroundProps[] = {
- "_XROOTPMAP_ID",
- "_XSETROOT_ID",
- 0,
-};
-
-static Bool
-determine_window_transparent_to_black(Display *dpy, Window w);
-
-static Bool
-determine_window_transparent_to_desktop(Display *dpy, Window w);
-
-static Picture
-root_tile (Display *dpy)
-{
- Picture picture;
- Atom actual_type;
- Pixmap pixmap;
- int actual_format;
- unsigned long nitems;
- unsigned long bytes_after;
- unsigned char *prop;
- Bool fill;
- XRenderPictureAttributes pa;
- int p;
-
- pixmap = None;
- for (p = 0; backgroundProps[p]; p++)
- {
- if (XGetWindowProperty (dpy, root, XInternAtom (dpy, backgroundProps[p], False),
- 0, 4, False, AnyPropertyType,
- &actual_type, &actual_format, &nitems, &bytes_after, &prop) == Success &&
- actual_type == XInternAtom (dpy, "PIXMAP", False) && actual_format == 32 && nitems == 1)
- {
- pixmap = *(long*)prop;
- XFree (prop);
- fill = False;
- break;
- }
- }
- if (!pixmap)
- {
- pixmap = XCreatePixmap (dpy, root, 1, 1, DefaultDepth (dpy, scr));
- fill = True;
- }
- pa.repeat = True;
- picture = XRenderCreatePicture (dpy, pixmap,
- sXRenderFindVisualFormat (dpy,
- DefaultVisual (dpy, scr)),
- CPRepeat, &pa);
- if (fill)
- {
- XRenderFillRectangle (dpy, PictOpSrc, picture, &fill_color,
- 0, 0, 1, 1);
- }
- return picture;
-}
-
-static void
-paint_root (Display *dpy)
-{
- if (!rootTile)
- rootTile = root_tile (dpy);
-
- XRenderComposite (dpy, PictOpSrc,
- rootTile, None, rootBuffer,
- 0, 0, 0, 0, 0, 0, root_width, root_height);
-}
-
-static XserverRegion
-win_extents (Display *dpy, win *w)
-{
- XRectangle r;
-
- r.x = w->a.x;
- r.y = w->a.y;
- r.width = w->a.width + w->a.border_width * 2;
- r.height = w->a.height + w->a.border_width * 2;
- if (winTypeShadow[w->windowType])
- {
- if (compMode == CompServerShadows || w->mode != WINDOW_ARGB)
- {
- XRectangle sr;
-
- if (compMode == CompServerShadows)
- {
- w->shadow_dx = 2;
- w->shadow_dy = 7;
- w->shadow_width = w->a.width;
- w->shadow_height = w->a.height;
- }
- else
- {
- w->shadow_dx = SHADOW_OFFSET_X;
- w->shadow_dx = w->shadow_dx / 100;
- w->shadow_dy = SHADOW_OFFSET_Y;
- w->shadow_dy = w->shadow_dy / 100;
- if (!w->shadow)
- {
- double opacity = shadowOpacity;
- if (w->shadowSize > 100)
- opacity = opacity/(w->shadowSize*0.015);
- if (w->mode == WINDOW_TRANS)
- opacity = opacity * ((double)w->opacity)/((double)OPAQUE);
- w->shadow = shadow_picture (dpy, opacity, w->alphaPict,
- w->a.width + w->a.border_width * 2 - 2*(shadowRadius - (w->shadowSize*shadowRadius/100)) ,
- w->a.height + w->a.border_width * 2 - 2*(shadowRadius - (w->shadowSize*shadowRadius/100)),
- &w->shadow_width, &w->shadow_height);
- /*int kill;
- w->alpha = shadow_picture (dpy, 0.9, w->alphaPict,
- w->a.width + w->a.border_width * 2,
- w->a.height + w->a.border_width * 2,
- &kill, &kill);*/
- }
- }
- sr.x = w->a.x + w->shadow_dx;
- sr.y = w->a.y + w->shadow_dy;
- sr.width = w->shadow_width;
- sr.height = w->shadow_height;
- if (sr.x < r.x)
- {
- r.width = (r.x + r.width) - sr.x;
- r.x = sr.x;
- }
- if (sr.y < r.y)
- {
- r.height = (r.y + r.height) - sr.y;
- r.y = sr.y;
- }
- if (sr.x + sr.width > r.x + r.width)
- r.width = sr.x + sr.width - r.x;
- if (sr.y + sr.height > r.y + r.height)
- r.height = sr.y + sr.height - r.y;
- }
- }
- return XFixesCreateRegion (dpy, &r, 1);
-}
-
- static XserverRegion
-border_size (Display *dpy, win *w)
-{
- XserverRegion border;
- /*
- * if window doesn't exist anymore, this will generate an error
- * as well as not generate a region. Perhaps a better XFixes
- * architecture would be to have a request that copies instead
- * of creates, that way you'd just end up with an empty region
- * instead of an invalid XID.
- */
- set_ignore (dpy, NextRequest (dpy));
- border = XFixesCreateRegionFromWindow (dpy, w->id, WindowRegionBounding);
- /* translate this */
- set_ignore (dpy, NextRequest (dpy));
- XFixesTranslateRegion (dpy, border,
- w->a.x + w->a.border_width,
- w->a.y + w->a.border_width);
- return border;
-}
-
- static XserverRegion
-deco_region (Display *dpy, win *w)
-{
- XserverRegion title;
- XRectangle r; /*titlebounding rect*/
- /*
- * if window doesn't exist anymore, this will generate an error
- * as well as not generate a region. Perhaps a better XFixes
- * architecture would be to have a request that copies instead
- * of creates, that way you'd just end up with an empty region
- * instead of an invalid XID.
- */
- r.x = w->a.x - w->a.border_width + _LEFTWIDTH_(w->decoHash);
- r.y = w->a.y - w->a.border_width + _TOPHEIGHT_(w->decoHash);
- r.width = w->a.width + w->a.border_width * 2 - _LEFTWIDTH_(w->decoHash) - _RIGHTWIDTH_(w->decoHash);
- r.height = w->a.height + w->a.border_width - _TOPHEIGHT_(w->decoHash) - _BOTTOMHEIGHT_(w->decoHash);
- set_ignore (dpy, NextRequest (dpy));
- title = XFixesCreateRegion (dpy, &r, 1);
- if (!w->borderSize)
- w->borderSize = border_size (dpy, w);
- set_ignore (dpy, NextRequest (dpy));
- XFixesSubtractRegion(dpy, title, w->borderSize, title);
- return title;
-}
-
-static void finish_destroy_win (Display *dpy, Window id, Bool gone);
-
- static XserverRegion
-content_region (Display *dpy, win *w)
-{
- XserverRegion content;
- XRectangle r; /*contentbounding rect*/
- /*
- * if window doesn't exist anymore, this will generate an error
- * as well as not generate a region. Perhaps a better XFixes
- * architecture would be to have a request that copies instead
- * of creates, that way you'd just end up with an empty region
- * instead of an invalid XID.
- */
- r.x = w->a.x - w->a.border_width + _LEFTWIDTH_(w->decoHash);
- r.y = w->a.y - w->a.border_width + _TOPHEIGHT_(w->decoHash);
- r.width = w->a.width + w->a.border_width * 2 - _LEFTWIDTH_(w->decoHash) - _RIGHTWIDTH_(w->decoHash);
- r.height = w->a.height + w->a.border_width - _TOPHEIGHT_(w->decoHash) - _BOTTOMHEIGHT_(w->decoHash);
- set_ignore (dpy, NextRequest (dpy));
- content = XFixesCreateRegion (dpy, &r, 1);
- if (!w->borderSize)
- w->borderSize = border_size (dpy, w);
- set_ignore (dpy, NextRequest (dpy));
- XFixesIntersectRegion(dpy, content, w->borderSize, content);
- return content;
-}
-
- static void
-paint_all (Display *dpy, XserverRegion region)
-{
- win *w;
- win *t = 0;
-
-#if DEBUG_WINDOWS
- int window_count = 0;
-#endif
-
- if (!region)
- {
- XRectangle r;
- r.x = 0;
- r.y = 0;
- r.width = root_width;
- r.height = root_height;
- region = XFixesCreateRegion (dpy, &r, 1);
- }
-#if MONITOR_REPAINT
- rootBuffer = rootPicture;
-#else
- if (!rootBuffer)
- {
- Pixmap rootPixmap = XCreatePixmap (dpy, root, root_width, root_height,
- DefaultDepth (dpy, scr));
- rootBuffer = XRenderCreatePicture (dpy, rootPixmap,
- sXRenderFindVisualFormat (dpy,
- DefaultVisual (dpy, scr)),
- 0, 0);
- XFreePixmap (dpy, rootPixmap);
- }
-#endif
- XFixesSetPictureClipRegion (dpy, rootPicture, 0, 0, region);
-#if MONITOR_REPAINT
- XRenderComposite (dpy, PictOpSrc, blackPicture, None, rootPicture,
- 0, 0, 0, 0, 0, 0, root_width, root_height);
-#endif
-#if DEBUG_REPAINT
- printf ("paint:");
-#endif
-
- // Time delayed garbage collect
- // It waits 10 seconds before destroying window data
- // This allows the fade out to perform smoothly under all conditions
- // Yes, this code is somewhat inefficient!
- // But it shouldn't matter unless someone has tens of thousands of windows open...
- // If the user can set a fade out that is longer than 10 seconds,
- // then the value must be increased. I am assuming that 10 seconds
- // is far too long for any normal human being to wait... ;-)
- for (w = list; w; w = w->next)
- {
- if (w->destruct_requested) {
- int curtime = get_time_in_milliseconds();
- if ((curtime - w->destruct_request_time) > 10000) {
- finish_destroy_win (dpy, w->id, True);
- w = list;
- }
- }
- }
-
- for (w = list; w; w = w->next)
- {
-#if DEBUG_WINDOWS
- window_count++;
-#endif
-#if CAN_DO_USABLE
- if (!w->usable)
- continue;
-#endif
-
- /* never painted, ignore it */
- if ((!screen_damaged) && (!w->damaged)) {
-#if DEBUG_REPAINT
- printf(" [not damaged: 0x%x]", w->id);
-#endif
- continue;
- }
-
- /* skip invisible windows */
- if (w->a.x + w->a.width < 1 || w->a.y + w->a.height < 1 || w->a.x >= root_width || w->a.y >= root_height) {
-#if DEBUG_REPAINT
- printf(" [invisible: 0x%x]", w->id);
-#endif
- continue;
- }
-
- if (!w->picture)
- {
- XRenderPictureAttributes pa;
- XRenderPictFormat *format;
- Drawable draw = w->id;
-
-#if HAS_NAME_WINDOW_PIXMAP
- if (hasNamePixmap && !w->pixmap)
- w->pixmap = XCompositeNameWindowPixmap (dpy, w->id);
- if (w->pixmap)
- draw = w->pixmap;
-#endif
- format = sXRenderFindVisualFormat (dpy, w->a.visual);
- pa.subwindow_mode = IncludeInferiors;
- w->picture = XRenderCreatePicture (dpy, draw,
- format,
- CPSubwindowMode,
- &pa);
- }
-#if DEBUG_REPAINT
- printf (" [painting 0x%x]", w->id);
-#endif
- if (clipChanged)
- {
- if (w->borderSize)
- {
- set_ignore (dpy, NextRequest (dpy));
- XFixesDestroyRegion (dpy, w->borderSize);
- w->borderSize = None;
- }
- if (w->decoRegion)
- {
- set_ignore (dpy, NextRequest (dpy));
- XFixesDestroyRegion (dpy, w->decoRegion);
- w->decoRegion = None;
- }
- if (w->contentRegion)
- {
- set_ignore (dpy, NextRequest (dpy));
- XFixesDestroyRegion (dpy, w->contentRegion);
- w->contentRegion = None;
- }
- if (w->extents)
- {
- XFixesDestroyRegion (dpy, w->extents);
- w->extents = None;
- }
- if (w->borderClip)
- {
- XFixesDestroyRegion (dpy, w->borderClip);
- w->borderClip = None;
- }
- }
- if (!w->borderSize)
- w->borderSize = border_size (dpy, w);
- if (!w->extents)
- w->extents = win_extents (dpy, w);
- if ((w->mode == WINDOW_SOLID) || ((w->mode == WINDOW_TRANS) && w->decoHash))
- {
- int x, y, wid, hei;
-#if HAS_NAME_WINDOW_PIXMAP
- x = w->a.x;
- y = w->a.y;
- wid = w->a.width + w->a.border_width * 2;
- hei = w->a.height + w->a.border_width * 2;
-#else
- x = w->a.x + w->a.border_width;
- y = w->a.y + w->a.border_width;
- wid = w->a.width;
- hei = w->a.height;
-#endif
- XFixesSetPictureClipRegion (dpy, rootBuffer, 0, 0, region);
- set_ignore (dpy, NextRequest (dpy));
- /*XFixesSubtractRegion (dpy, region, region, w->borderSize);
- set_ignore (dpy, NextRequest (dpy));*/
- if (w->mode == WINDOW_SOLID)
- {
- XFixesSubtractRegion (dpy, region, region, w->borderSize);
- set_ignore (dpy, NextRequest (dpy));
- XRenderComposite (dpy, PictOpSrc, w->picture, None, rootBuffer,
- 0, 0, 0, 0, x, y, wid, hei);
- if (w->dimPicture)
- XRenderComposite (dpy, PictOpOver, w->dimPicture, None, rootBuffer, 0, 0, 0, 0, x, y, wid, hei);
- }
- else
- {
- if (!w->contentRegion)
- w->contentRegion = content_region (dpy, w);
- XFixesSubtractRegion (dpy, region, region, w->contentRegion);
- set_ignore (dpy, NextRequest (dpy));
- /*solid part*/
- XRenderComposite (dpy, PictOpSrc, w->picture, None, rootBuffer,
- _LEFTWIDTH_(w->decoHash), _TOPHEIGHT_(w->decoHash), 0, 0,
- x + _LEFTWIDTH_(w->decoHash),
- y + _TOPHEIGHT_(w->decoHash),
- wid - _LEFTWIDTH_(w->decoHash) - _RIGHTWIDTH_(w->decoHash),
- hei - _TOPHEIGHT_(w->decoHash) - _BOTTOMHEIGHT_(w->decoHash));
- }
- }
- if (!w->borderClip)
- {
- w->borderClip = XFixesCreateRegion (dpy, 0, 0);
- XFixesCopyRegion (dpy, w->borderClip, region);
- }
- w->prev_trans = t;
- t = w;
- }
-#if DEBUG_WINDOWS
- printf("window count: %d\n", window_count);
-#endif
-#if DEBUG_REPAINT
- printf ("\n");
- fflush (stdout);
-#endif
- XFixesSetPictureClipRegion (dpy, rootBuffer, 0, 0, region);
- paint_root (dpy);
- for (w = t; w; w = w->prev_trans)
- {
- if (w->shadowSize > 0){
- if (winTypeShadow[w->windowType]) {
- switch (compMode) {
- case CompSimple:
- break;
- case CompServerShadows:
- XFixesSetPictureClipRegion (dpy, rootBuffer, 0, 0, w->borderClip);
- set_ignore (dpy, NextRequest (dpy));
- if (w->opacity != OPAQUE && !w->shadowPict)
- w->shadowPict = solid_picture (dpy, True,
- (double) w->opacity / OPAQUE * 0.3,
- 0, 0, 0);
- XRenderComposite (dpy, PictOpOver,
- w->shadowPict ? w->shadowPict : transBlackPicture,
- w->picture, rootBuffer,
- 0, 0, 0, 0,
- w->a.x + w->shadow_dx,
- w->a.y + w->shadow_dy,
- w->shadow_width, w->shadow_height);
- break;
- case CompClientShadows:
- if (w->shadow)
- {
- XFixesSetPictureClipRegion (dpy, rootBuffer, 0, 0, w->borderClip);
- XRenderComposite (dpy, PictOpOver, blackPicture, w->shadow, rootBuffer,
- 0, 0, 0, 0,
- w->a.x + w->shadow_dx,
- w->a.y + w->shadow_dy,
- w->shadow_width, w->shadow_height);
- }
- break;
- }
- }
- }
- if (w->opacity != OPAQUE && !w->alphaPict)
- w->alphaPict = solid_picture (dpy, False,
- (double) w->opacity / OPAQUE, shadowColor.red, shadowColor.green, shadowColor.blue);
- if (w->mode == WINDOW_TRANS)
- {
- int x, y, wid, hei;
- XFixesIntersectRegion (dpy, w->borderClip, w->borderClip, w->borderSize);
- XFixesSetPictureClipRegion (dpy, rootBuffer, 0, 0, w->borderClip);
-#if HAS_NAME_WINDOW_PIXMAP
- x = w->a.x;
- y = w->a.y;
- wid = w->a.width + w->a.border_width * 2;
- hei = w->a.height + w->a.border_width * 2;
-#else
- x = w->a.x + w->a.border_width;
- y = w->a.y + w->a.border_width;
- wid = w->a.width;
- hei = w->a.height;
-#endif
- set_ignore (dpy, NextRequest (dpy));
- if (!w->decoHash)
- {
- XRenderComposite (dpy, PictOpOver, w->picture, w->alphaPict, rootBuffer,
- 0, 0, 0, 0, x, y, wid, hei);
- }
- else
- {
- /*trans part*/
- /* PICTURE ;)
- |-----------------------------|
- | top |
- |-----------------------------|
- |l | | r|
- |e | | i|
- |f | | g|
- |t | | h|
- |--------------------------| t|
- | bottom | |
- |--------------------------|--|*/
- /*top*/
- XRenderComposite (dpy, PictOpOver, w->picture, w->alphaPict, rootBuffer,
- 0, 0, 0, 0, x, y, wid, _TOPHEIGHT_(w->decoHash));
- /*right*/
- XRenderComposite (dpy, PictOpOver, w->picture, w->alphaPict, rootBuffer,
- wid - _RIGHTWIDTH_(w->decoHash), _TOPHEIGHT_(w->decoHash),
- 0, 0,
- x + wid - _RIGHTWIDTH_(w->decoHash),
- y + _TOPHEIGHT_(w->decoHash), _RIGHTWIDTH_(w->decoHash),
- hei - _TOPHEIGHT_(w->decoHash));
- /*bottom*/
- XRenderComposite (dpy, PictOpOver, w->picture, w->alphaPict, rootBuffer,
- 0, hei - _BOTTOMHEIGHT_(w->decoHash), 0, 0,
- x, y + hei - _BOTTOMHEIGHT_(w->decoHash),
- wid - _RIGHTWIDTH_(w->decoHash), _BOTTOMHEIGHT_(w->decoHash));
- /*left*/
- XRenderComposite (dpy, PictOpOver, w->picture, w->alphaPict, rootBuffer,
- 0, _TOPHEIGHT_(w->decoHash), 0, 0,
- x, y + _TOPHEIGHT_(w->decoHash),
- _LEFTWIDTH_(w->decoHash), hei - _TOPHEIGHT_(w->decoHash) - _BOTTOMHEIGHT_(w->decoHash));
- }
- }
- else if (w->mode == WINDOW_ARGB)
- {
- int x, y, wid, hei;
- XFixesIntersectRegion (dpy, w->borderClip, w->borderClip, w->borderSize);
- XFixesSetPictureClipRegion (dpy, rootBuffer, 0, 0, w->borderClip);
-#if HAS_NAME_WINDOW_PIXMAP
- x = w->a.x;
- y = w->a.y;
- wid = w->a.width + w->a.border_width * 2;
- hei = w->a.height + w->a.border_width * 2;
-#else
- x = w->a.x + w->a.border_width;
- y = w->a.y + w->a.border_width;
- wid = w->a.width;
- hei = w->a.height;
-#endif
- set_ignore (dpy, NextRequest (dpy));
- /* Here we redraw the background of the transparent window if we want
- to do anything special (i.e. anything other than showing the
- windows and desktop prestacked behind of the window).
- For example, if you want to blur the background or show another
- background pixmap entirely here is the place to do it; simply
- draw the new background onto rootBuffer before continuing! */
- if (w->isInFade == False) {
- if (w->show_black_background == True) {
- XRenderComposite (dpy, PictOpSrc, blackPicture, None, rootBuffer,
- x, y, x, y,
- x, y, wid, hei);
- }
- else if (w->show_root_tile == True) {
- XRenderComposite (dpy, PictOpSrc, rootTile, None, rootBuffer,
- x, y, x, y,
- x, y, wid, hei);
- }
- }
- XRenderComposite (dpy, PictOpOver, w->picture, w->alphaPict, rootBuffer,
- 0, 0, 0, 0,
- x, y, wid, hei);
- }
- XFixesDestroyRegion (dpy, w->borderClip);
- w->borderClip = None;
- }
- XFixesDestroyRegion (dpy, region);
- if (rootBuffer != rootPicture)
- {
-#if 0
- XTransform t;
- t.matrix[0][0] = XDoubleToFixed (3.0 /*/ scale*/);
- t.matrix[0][1] = 0.0;
- t.matrix[0][2] = 0.0;
-
- t.matrix[1][0] = 0.0;
- t.matrix[1][1] = XDoubleToFixed (1.0 /*/ scale*/);
- t.matrix[1][2] = 0.0;
-
- t.matrix[2][0] = 0.0;
- t.matrix[2][1] = 0.0;
- t.matrix[2][2] = XDoubleToFixed (1.0);
-
- XRenderSetPictureTransform (dpy, rootBuffer, &t);
-#endif
- XFixesSetPictureClipRegion (dpy, rootBuffer, 0, 0, None);
- XRenderComposite (dpy, PictOpSrc, rootBuffer, None, rootPicture,
- 0, 0, 0, 0, 0, 0, root_width, root_height);
- }
- screen_damaged = False;
-}
-
-static void
-add_damage (Display *dpy, XserverRegion damage)
-{
- if (allDamage)
- {
- XFixesUnionRegion (dpy, allDamage, allDamage, damage);
- XFixesDestroyRegion (dpy, damage);
- }
- else
- allDamage = damage;
-}
-
-static void damage_win (Display *dpy, XDamageNotifyEvent *de);
-
-static void
-repair_win (Display *dpy, win *w)
-{
- XserverRegion parts;
-
- if (!w->damaged)
- {
- parts = win_extents (dpy, w);
- set_ignore (dpy, NextRequest (dpy));
- XDamageSubtract (dpy, w->damage, None, None);
- }
- else
- {
- XserverRegion o;
- parts = XFixesCreateRegion (dpy, 0, 0);
- set_ignore (dpy, NextRequest (dpy));
- XDamageSubtract (dpy, w->damage, None, parts);
- XFixesTranslateRegion (dpy, parts,
- w->a.x + w->a.border_width,
- w->a.y + w->a.border_width);
- if (compMode == CompServerShadows)
- {
- o = XFixesCreateRegion (dpy, 0, 0);
- XFixesCopyRegion (dpy, o, parts);
- XFixesTranslateRegion (dpy, o, w->shadow_dx, w->shadow_dy);
- XFixesUnionRegion (dpy, parts, parts, o);
- XFixesDestroyRegion (dpy, o);
- }
- }
- add_damage (dpy, parts);
- w->damaged = 1;
-}
-
-static const char*
-wintype_name(wintype type)
-{
- const char *t;
- switch (type) {
- case WINTYPE_DESKTOP: t = "desktop"; break;
- case WINTYPE_DOCK: t = "dock"; break;
- case WINTYPE_TOOLBAR: t = "toolbar"; break;
- case WINTYPE_MENU: t = "menu"; break;
- case WINTYPE_UTILITY: t = "utility"; break;
- case WINTYPE_SPLASH: t = "slash"; break;
- case WINTYPE_DIALOG: t = "dialog"; break;
- case WINTYPE_NORMAL: t = "normal"; break;
- case WINTYPE_DROPDOWN_MENU: t = "dropdown"; break;
- case WINTYPE_POPUP_MENU: t = "popup"; break;
- case WINTYPE_TOOLTIP: t = "tooltip"; break;
- case WINTYPE_NOTIFY: t = "notification"; break;
- case WINTYPE_COMBO: t = "combo"; break;
- case WINTYPE_DND: t = "dnd"; break;
- default: t = "unknown"; break;
- }
- return t;
-}
-
-void repaint_root_overlay_window ()
-{
- XRectangle r;
- r.x = 0;
- r.y = 0;
- r.width = root_width;
- r.height = root_height;
- XserverRegion region = XFixesCreateRegion (dpy, &r, 1);
- add_damage (dpy, region);
-}
-
-static wintype
-get_wintype_prop(Display * dpy, Window w)
-{
- Atom actual;
- wintype ret;
- int format;
- unsigned long n, left, off;
- unsigned char *data;
-
- ret = (wintype)-1;
- off = 0;
-
- do {
- set_ignore (dpy, NextRequest (dpy));
- int result = XGetWindowProperty (dpy, w, winTypeAtom, off, 1L, False,
- XA_ATOM, &actual, &format,
- &n, &left, &data);
-
- if (result != Success)
- break;
- if (data != None)
- {
- int i;
-
- for (i = 0; i < NUM_WINTYPES; ++i) {
- Atom a;
- memcpy (&a, data, sizeof (Atom));
- if (a == winType[i]) {
- /* known type */
- ret = i;
- break;
- }
- }
-
- XFree ( (void *) data);
- }
-
- ++off;
- } while (left >= 4 && ret == (wintype)-1);
-
- return ret;
-}
-
-static wintype
-determine_wintype (Display *dpy, Window w, Window top)
-{
- Window root_return, parent_return;
- Window *children = NULL;
- unsigned int nchildren, i;
- wintype type;
-
- type = get_wintype_prop (dpy, w);
- if (type != (wintype)-1)
- return type;
-
- set_ignore (dpy, NextRequest (dpy));
- if (!XQueryTree (dpy, w, &root_return, &parent_return, &children,
- &nchildren))
- {
- /* XQueryTree failed. */
- if (children)
- XFree ((void *)children);
- return (wintype)-1;
- }
-
- for (i = 0;i < nchildren;i++)
- {
- type = determine_wintype (dpy, children[i], top);
- if (type != (wintype)-1)
- return type;
- }
-
- if (children)
- XFree ((void *)children);
-
- if (w != top)
- return (wintype)-1;
- else
- return WINTYPE_NORMAL;
-}
-
-static unsigned int
-get_opacity_prop(Display *dpy, win *w, unsigned int def);
-
-static void
-map_win (Display *dpy, Window id, unsigned long sequence, Bool fade)
-{
- win *w = find_win (dpy, id);
- Drawable back;
-
-#if DEBUG_WINDOWS
- printf("map_win: 0x%x 0x%x\n", w, id);
-#endif
-
- if (!w) {
- return;
- }
-
- w->a.map_state = IsViewable;
-
- /* This needs to be here or else we lose transparency messages */
- XSelectInput (dpy, id, PropertyChangeMask);
-
- /* This needs to be here since we don't get PropertyNotify when unmapped */
- w->opacity = get_opacity_prop (dpy, w, OPAQUE);
- w->show_root_tile = determine_window_transparent_to_desktop(dpy, id);
- w->show_black_background = determine_window_transparent_to_black(dpy, id);
- determine_mode (dpy, w);
-
- w->windowType = determine_wintype (dpy, w->id, w->id);
- if ((w->windowType < 0) || (w->windowType > NUM_WINTYPES)) w->windowType = WINTYPE_NORMAL;
-#if 0
- printf("window 0x%x type %s\n", w->id, wintype_name(w->windowType));
-#endif
-
-#if CAN_DO_USABLE
- w->damage_bounds.x = w->damage_bounds.y = 0;
- w->damage_bounds.width = w->damage_bounds.height = 0;
-#endif
- w->damaged = 0;
-
-#if WORK_AROUND_FGLRX
- if (w->a.x != 0) {
- XserverRegion extents = win_extents (dpy, w);
- XDamageNotifyEvent de;
- de.drawable = w->id;
- de.area.x = 0;
- de.area.y = 0;
- de.area.width = w->a.width + w->a.border_width * 2;
- de.area.height = w->a.height + w->a.border_width * 2;
- damage_win(dpy, &de);
- XFixesDestroyRegion (dpy, extents);
- }
-#endif
- w->a_prev = w->a;
-
- if (fade && winTypeFade[w->windowType]) {
- set_fade (dpy, w, 0, get_opacity_prop(dpy, w, OPAQUE)*1.0/OPAQUE, fade_in_step, 0, False, True, True, True);
- }
-}
-
-static void
-finish_unmap_win (Display *dpy, win *w)
-{
-#if DEBUG_WINDOWS
- printf("finish_unmap_win: 0x%x\n", w->id);
-#endif
- w->damaged = 0;
-#if CAN_DO_USABLE
- w->usable = False;
-#endif
- if (w->extents != None)
- {
- add_damage (dpy, w->extents); /* destroys region */
- w->extents = None;
- }
-
-#if HAS_NAME_WINDOW_PIXMAP
- if (w->pixmap)
- {
- XFreePixmap (dpy, w->pixmap);
- w->pixmap = None;
- }
-#endif
-
- if (w->picture)
- {
- set_ignore (dpy, NextRequest (dpy));
- XRenderFreePicture (dpy, w->picture);
- w->picture = None;
- }
-
- /* don't care about properties anymore */
- set_ignore (dpy, NextRequest (dpy));
- XSelectInput(dpy, w->id, 0);
-
- if (w->borderSize)
- {
- set_ignore (dpy, NextRequest (dpy));
- XFixesDestroyRegion (dpy, w->borderSize);
- w->borderSize = None;
- }
-
- if (w->decoRegion)
- {
- set_ignore (dpy, NextRequest (dpy));
- XFixesDestroyRegion (dpy, w->decoRegion);
- w->decoRegion = None;
- }
-
- if (w->contentRegion)
- {
- set_ignore (dpy, NextRequest (dpy));
- XFixesDestroyRegion (dpy, w->contentRegion);
- w->contentRegion = None;
- }
-
- if (w->shadow)
- {
- XRenderFreePicture (dpy, w->shadow);
- w->shadow = None;
- }
- if (w->borderClip)
- {
- XFixesDestroyRegion (dpy, w->borderClip);
- w->borderClip = None;
- }
-
- clipChanged = True;
-}
-
-#if HAS_NAME_WINDOW_PIXMAP
-static void
-unmap_callback (Display *dpy, win *w, Bool gone)
-{
- finish_unmap_win (dpy, w);
-}
-#endif
-
-static void
-unmap_win (Display *dpy, Window id, Bool fade)
-{
- win *w = find_win (dpy, id);
-
-#if DEBUG_WINDOWS
- printf("unmap_win: 0x%x 0x%x\n", w, id);
-#endif
-
- if (!w)
- return;
-
- if (w->a.map_state != IsUnmapped) {
- w->a.map_state = IsUnmapped;
-#if HAS_NAME_WINDOW_PIXMAP
- if (w->pixmap && fade && winTypeFade[w->windowType]) {
- set_fade (dpy, w, w->opacity*1.0/OPAQUE, 0.0, fade_out_step, unmap_callback, False, False, True, True);
- }
- else
-#endif
- finish_unmap_win (dpy, w);
- }
-}
-
-/* Get the opacity prop from window
- not found: default
- otherwise the value
- */
- static unsigned int
-get_opacity_prop(Display *dpy, win *w, unsigned int def)
-{
- Atom actual;
- int format;
- unsigned long n, left;
-
- unsigned char *data;
- int result = XGetWindowProperty(dpy, w->id, opacityAtom, 0L, 1L, False,
- XA_CARDINAL, &actual, &format,
- &n, &left, &data);
- if (result == Success && data != NULL && format == 32 )
- {
- unsigned int i;
- i = *(long*)data;
- XFree( (void *) data);
- return i;
- }
- return def;
-}
-
- static unsigned int
-get_shadow_prop(Display *dpy, win *w)
-{
- Atom actual;
- int format;
- unsigned long n, left;
-
- unsigned char *data = NULL;
- int result = XGetWindowProperty(dpy, w->id, shadowAtom, 0L, 1L, False,
- XA_CARDINAL, &actual, &format,
- &n, &left, &data);
- if (result == Success && data != NULL && format == 32 )
- {
- unsigned int i;
- i = *(long*)data;
- XFree( (void *) data);
- /*i added this for security reaons but limiting a value to 200% is somewhat indiscriminate
- if (i > 200)
- return 200;
- else*/
- return i;
- }
- return 100;
-}
-
- static unsigned int
-get_shade_prop(Display *dpy, win *w)
-{
- Atom actual;
- int format;
- unsigned long n, left;
-
- unsigned char *data = NULL;
- int result = XGetWindowProperty(dpy, w->id, shadeAtom, 0L, 1L, False,
- XA_CARDINAL, &actual, &format,
- &n, &left, &data);
- if (result == Success && data != NULL && format == 32 )
- {
- unsigned int i;
- i = *(long*)data;
- XFree( (void *) data);
- return i;
- }
- return 0;
-}
-
- static Bool
-get_shapable_prop(Display *dpy, win *w)
-{
- Atom actual;
- int format;
- unsigned long n, left;
-
- unsigned char *data = NULL;
- int result = XGetWindowProperty(dpy, w->id, shapableAtom, 0L, 1L, False,
- XA_CARDINAL, &actual, &format,
- &n, &left, &data);
- if (result == Success && data != NULL && format == 32 )
- {
- unsigned int i;
- i = *(long*)data;
- XFree( (void *) data);
- return i==1;
- }
- return True; /*in general, the window should be shapable*/
-}
-
-static unsigned int
-get_decoHash_prop(Display *dpy, win *w)
-{
- Atom actual;
- int format;
- unsigned long n, left;
-
- unsigned char *data = NULL;
- int result = XGetWindowProperty(dpy, w->id, decoHashAtom, 0L, 1L, False,
- XA_CARDINAL, &actual, &format,
- &n, &left, &data);
- if (result == Success && data != NULL && format == 32 )
- {
- unsigned int i;
- i = *(long*)data;
- XFree( (void *) data);
- return i;
- }
- return 0; /*no titlebar*/
-}
-
-static unsigned int
-get_dim_prop(Display *dpy, win *w)
-{
- Atom actual;
- int format;
- unsigned long n, left;
-
- unsigned char *data = NULL;
- int result = XGetWindowProperty(dpy, w->id, dimAtom, 0L, 1L, False,
- XA_CARDINAL, &actual, &format,
- &n, &left, &data);
- if (result == Success && data != NULL)
- {
- unsigned int i;
- memcpy (&i, data, sizeof (unsigned int));
- XFree( (void *) data);
- if (i == 0) i = 1;
- return i;
- }
- return OPAQUE; /*in general, the window is not dimmed*/
-}
-
-static unsigned int
-get_deskchange_prop(Display *dpy, Window id)
-{
- Atom actual;
- int format;
- unsigned long n, left;
-
- unsigned char *data = NULL;
- int result = XGetWindowProperty(dpy, id, deskChangeAtom, 0L, 1L, False,
- XA_CARDINAL, &actual, &format,
- &n, &left, &data);
- if (result == Success && data != NULL)
- {
- unsigned int i;
- memcpy (&i, data, sizeof (unsigned int));
- XFree( (void *) data);
- if (i < 3)
- return i;
- }
- return 0; /*no valid change state*/
-}
-
-/* Get the opacity property from the window in a percent format
- not found: default
-otherwise: the value
-*/
- static double
-get_opacity_percent(Display *dpy, win *w)
-{
- if (w && w->isInFade)
- {
- fade *f = find_fade(w);
- return f->finish;
- }
- else
- {
- double def = winTypeOpacity[w->windowType];
- unsigned int opacity = get_opacity_prop (dpy, w, (unsigned int)(OPAQUE*def));
- return opacity*1.0/OPAQUE;
- }
-}
-#if 0
-static void
-damage_shape(Display *dpy, win *w, XRectangle *shape_damage)
-{
- set_ignore (dpy, NextRequest (dpy));
- XserverRegion region = XFixesCreateRegion (dpy, shape_damage, 1);
- set_ignore (dpy, NextRequest (dpy));
- XserverRegion tmpRegion;
- add_damage(dpy, region);
- win *i;
- XRectangle *rect;
- int n;
- for (i = w; i; i = i->next)
- {
- XFixesIntersectRegion (dpy, tmpRegion, region, w->extents);
- rect = XFixesFetchRegion (dpy, region, &n);
- free(rect);
- printf("%d\n",n);
- if (n != 1)
- {
- w->damage = True;
- XFixesSubtractRegion (dpy, region, region, w->extents);
- }
- else
- break;
- }
- set_ignore (dpy, NextRequest (dpy));
- XFixesDestroyRegion (dpy, tmpRegion);
- set_ignore (dpy, NextRequest (dpy));
- XFixesDestroyRegion (dpy, region);
-}
-#endif
-
-static Bool
-get_window_transparent_to_desktop(Display * dpy, Window w)
-{
- Atom actual;
- int format;
- unsigned long n, left;
-
- unsigned char *data;
- int result = XGetWindowProperty (dpy, w, winTDETTDAtom, 0L, 1L, False,
- XA_ATOM, &actual, &format,
- &n, &left, &data);
-
- if (result == Success && data != None && format == 32 )
- {
- Atom a;
- a = *(long*)data;
- XFree ( (void *) data);
- return True;
- }
- return False;
-}
-
-static Bool
-get_window_transparent_to_black(Display * dpy, Window w)
-{
- Atom actual;
- int format;
- unsigned long n, left;
-
- unsigned char *data;
- int result = XGetWindowProperty (dpy, w, winTDETTBAtom, 0L, 1L, False,
- XA_ATOM, &actual, &format,
- &n, &left, &data);
-
- if (result == Success && data != None && format == 32 )
- {
- Atom a;
- a = *(long*)data;
- XFree ( (void *) data);
- return True;
- }
- return False;
-}
-
- static void
-determine_mode(Display *dpy, win *w)
-{
- int mode;
- XRenderPictFormat *format;
- unsigned int default_opacity;
-
- /* if trans prop == -1 fall back on previous tests*/
-
- if (w->alphaPict)
- {
- XRenderFreePicture (dpy, w->alphaPict);
- w->alphaPict = None;
- }
- if (w->shadowPict)
- {
- XRenderFreePicture (dpy, w->shadowPict);
- w->shadowPict = None;
- }
-
- if (w->a.class == InputOnly)
- {
- format = 0;
- }
- else
- {
- format = XRenderFindVisualFormat (dpy, w->a.visual);
- }
-
- if (!disable_argb && format && format->type == PictTypeDirect && format->direct.alphaMask)
- {
- mode = WINDOW_ARGB;
- }
- else if (w->opacity != OPAQUE)
- {
- mode = WINDOW_TRANS;
- }
- else
- {
- mode = WINDOW_SOLID;
- }
- w->mode = mode;
- if (w->extents)
- {
- XserverRegion damage;
- damage = XFixesCreateRegion (dpy, 0, 0);
- XFixesCopyRegion (dpy, damage, w->extents);
- add_damage (dpy, damage);
- }
-}
-
-static Bool
-determine_window_transparent_to_desktop (Display *dpy, Window w)
-{
- Window root_return, parent_return;
- Window *children = NULL;
- unsigned int nchildren, i;
- Bool type;
-
- type = get_window_transparent_to_desktop (dpy, w);
- if (type == True) {
- return True;
- }
-
- if (!XQueryTree (dpy, w, &root_return, &parent_return, &children,
- &nchildren))
- {
- /* XQueryTree failed. */
- if (children)
- XFree ((void *)children);
- return False;
- }
-
- for (i = 0;i < nchildren;i++)
- {
- type = determine_window_transparent_to_desktop (dpy, children[i]);
- if (type == True)
- return True;
- }
-
- if (children)
- XFree ((void *)children);
-
- return False;
-}
-
-static Bool
-determine_window_transparent_to_black (Display *dpy, Window w)
-{
- Window root_return, parent_return;
- Window *children = NULL;
- unsigned int nchildren, i;
- Bool type;
- Bool ret = False;
-
- type = get_window_transparent_to_black (dpy, w);
- if (type == True) {
- return True;
- }
-
- if (!XQueryTree (dpy, w, &root_return, &parent_return, &children,
- &nchildren))
- {
- /* XQueryTree failed. */
- if (children) {
- XFree ((void *)children);
- }
- return False;
- }
-
- for (i = 0;i < nchildren;i++)
- {
- type = determine_window_transparent_to_black (dpy, children[i]);
- if (type == True) {
- ret = True;
- break;
- }
- }
-
- if (children) {
- XFree ((void *)children);
- }
-
- return ret;
-}
-
- static void
-add_win (Display *dpy, Window id, Window prev)
-{
- win *new = malloc (sizeof (win));
- win **p;
- unsigned int tmp;
-
-#if DEBUG_WINDOWS
- printf("add_win: 0x%x\n", id);
-#endif
-
- if (!new) {
-#if DEBUG_WINDOWS
- printf("add_win: malloc() failed!\n", id);
-#endif
- return;
- }
- if (prev) {
- for (p = &list; *p; p = &(*p)->next) {
- if (((*p)->id == prev) && (!(*p)->destroyed)) {
- break;
- }
- }
- }
- else {
- p = &list;
- }
- new->id = id;
- set_ignore (dpy, NextRequest (dpy));
- if (!XGetWindowAttributes (dpy, id, &new->a))
- {
-#if DEBUG_WINDOWS
- printf("not adding 0x%x: failed to get attributes\n", new->id);
-#endif
- free (new);
- return;
- }
- new->shaped = False;
- new->shape_bounds.x = new->a.x;
- new->shape_bounds.y = new->a.y;
- new->shape_bounds_prev = new->shape_bounds;
- new->shape_bounds.width = new->a.width;
- new->shape_bounds.height = new->a.height;
- new->a_prev = new->a;
- new->damaged = 0;
-#if CAN_DO_USABLE
- new->usable = False;
-#endif
-#if HAS_NAME_WINDOW_PIXMAP
- new->pixmap = None;
-#endif
- new->picture = None;
- if (new->a.class == InputOnly)
- {
- new->damage_sequence = 0;
- new->damage = None;
- }
- else
- {
- new->damage_sequence = NextRequest (dpy);
- new->damage = XDamageCreate (dpy, id, XDamageReportNonEmpty);
- XShapeSelectInput (dpy, id, ShapeNotifyMask);
- }
- new->isInFade = False;
- new->alphaPict = None;
- new->shadowPict = None;
- new->borderSize = None;
- new->decoRegion = None;
- new->contentRegion = None;
- new->extents = None;
- new->shadow = None;
- new->shadow_dx = 0;
- new->shadow_dy = 0;
- new->shadow_width = 0;
- new->shadow_height = 0;
- new->opacity = OPAQUE;
- new->destroyed = False;
- new->destruct_queued = False;
- new->destruct_requested = False;
- new->destruct_request_time = 0;
- new->shadowSize = 100;
- new->decoHash = 0;
- new->show_root_tile = determine_window_transparent_to_desktop(dpy, id);
- new->show_black_background = determine_window_transparent_to_black(dpy, id);
-
- new->windowType = determine_wintype (dpy, new->id, new->id);
- if ((new->windowType < 0) || (new->windowType > NUM_WINTYPES)) new->windowType = WINTYPE_NORMAL;
-
- new->borderClip = None;
- new->prev_trans = 0;
-
- XShapeSelectInput( dpy, id, ShapeNotifyMask );
-
- new->shadowSize = get_shadow_prop (dpy, new);
- new->shapable = get_shapable_prop(dpy, new);
- new->decoHash = get_decoHash_prop(dpy, new);
- tmp = get_dim_prop(dpy, new);
- new->dimPicture = (tmp < OPAQUE) ? solid_picture (dpy, True, (double)tmp/OPAQUE, 0.1, 0.1, 0.1) : None;
-
- new->next = *p;
- *p = new;
-#if DEBUG_WINDOWS
- printf("adding 0x%x\n", new->id);
-#endif
- if (new->a.map_state == IsViewable) {
- map_win (dpy, id, new->damage_sequence - 1, True);
-#if DEBUG_WINDOWS
- printf("mapped 0x%x\n", new->id);
-#endif
- }
-}
-
- void
-restack_win (Display *dpy, win *w, Window new_above)
-{
- Window old_above;
-
-#if DEBUG_WINDOWS
- printf("restack_win: 0x%x\n", w->id);
-#endif
-
- if (w->next) {
- old_above = w->next->id;
- }
- else {
- old_above = None;
- }
- if (old_above != new_above) {
- win **prev;
-
- /* unhook */
- for (prev = &list; *prev; prev = &(*prev)->next) {
- if ((*prev) == w) {
- break;
- }
- }
- *prev = w->next;
-
- /* rehook */
- for (prev = &list; *prev; prev = &(*prev)->next) {
- if ((!(*prev)->destroyed) && ((*prev)->id == new_above)) {
- break;
- }
- }
- w->next = *prev;
- *prev = w;
- }
-}
-
- static void
-configure_win (Display *dpy, XConfigureEvent *ce)
-{
- win *w = find_win (dpy, ce->window);
- Window above;
- XserverRegion damage = None;
-
- if (!w)
- {
- if (ce->window == root)
- {
- if (rootBuffer)
- {
- XRenderFreePicture (dpy, rootBuffer);
- rootBuffer = None;
- }
- root_width = ce->width;
- root_height = ce->height;
- }
- return;
- }
-
-#if CAN_DO_USABLE
- if (w->usable)
-#endif
- {
- damage = XFixesCreateRegion (dpy, 0, 0);
- if (w->extents != None)
- XFixesCopyRegion (dpy, damage, w->extents);
- }
- w->shape_bounds.x -= w->a.x;
- w->shape_bounds.y -= w->a.y;
- w->a.x = ce->x;
- w->a.y = ce->y;
- /* Only destroy the pixmap if the window is mapped */
- if (w->a.map_state != IsUnmapped &&
- (w->a.width != ce->width || w->a.height != ce->height))
- {
-#if HAS_NAME_WINDOW_PIXMAP
- if (w->pixmap)
- {
- XFreePixmap (dpy, w->pixmap);
- w->pixmap = None;
- if (w->picture)
- {
- XRenderFreePicture (dpy, w->picture);
- w->picture = None;
- }
- }
-#endif
- if (w->shadow)
- {
- XRenderFreePicture (dpy, w->shadow);
- w->shadow = None;
- }
- }
- w->a.width = ce->width;
- w->a.height = ce->height;
- w->a.border_width = ce->border_width;
- w->a.override_redirect = ce->override_redirect;
- restack_win (dpy, w, ce->above);
- if (w->a.map_state != IsUnmapped && damage)
- {
- XserverRegion extents = win_extents (dpy, w);
- XFixesUnionRegion (dpy, damage, damage, extents);
- XFixesDestroyRegion (dpy, extents);
- add_damage (dpy, damage);
- }
- w->shape_bounds.x += w->a.x;
- w->shape_bounds.y += w->a.y;
- if (!w->shaped)
- {
- w->shape_bounds.width = w->a.width;
- w->shape_bounds.height = w->a.height;
- }
-
- if (w->a.map_state != IsUnmapped)
- clipChanged = True;
-}
-
- static void
-circulate_win (Display *dpy, XCirculateEvent *ce)
-{
- win *w = find_win (dpy, ce->window);
- Window new_above;
-
- if (!w)
- return;
-
- if (ce->place == PlaceOnTop)
- new_above = list->id;
- else
- new_above = None;
- restack_win (dpy, w, new_above);
- clipChanged = True;
-}
-
- static void
-finish_destroy_win (Display *dpy, Window id, Bool gone)
-{
- win **prev, *w;
-
-#if DEBUG_WINDOWS
- printf("finish_destroy_win: 0x%x\n", id);
-#endif
-
- for (prev = &list; (w = *prev); prev = &w->next) {
- if (w->id == id && w->destroyed) {
- if (gone) {
- finish_unmap_win (dpy, w);
- }
- *prev = w->next;
- if (w->picture)
- {
- set_ignore (dpy, NextRequest (dpy));
- XRenderFreePicture (dpy, w->picture);
- w->picture = None;
- }
- if (w->alphaPict)
- {
- XRenderFreePicture (dpy, w->alphaPict);
- w->alphaPict = None;
- }
- if (w->shadowPict)
- {
- XRenderFreePicture (dpy, w->shadowPict);
- w->shadowPict = None;
- }
- if (w->shadow)
- {
- XRenderFreePicture (dpy, w->shadow);
- w->shadow = None;
- }
- if (w->damage != None)
- {
- set_ignore (dpy, NextRequest (dpy));
- XDamageDestroy (dpy, w->damage);
- w->damage = None;
- }
- cleanup_fade (dpy, w);
- free (w);
- break;
- }
- }
-}
-
-#if HAS_NAME_WINDOW_PIXMAP
-static void
-destroy_callback (Display *dpy, win *w, Bool gone)
-{
- finish_destroy_win (dpy, w->id, gone);
-}
-#endif
-
-static void
-destroy_win (Display *dpy, Window id, Bool gone, Bool fadeout)
-{
- fade *f;
- win *w = find_win (dpy, id);
-
-#if DEBUG_WINDOWS
- printf("destroy_win: 0x%x 0x%x\n", w, id);
-#endif
-
- if (w) {
- w->destroyed = True;
- }
-
- if (w && w->destruct_queued == False) {
- f = find_fade (w);
- if (f) {
- w->destruct_queued = True;
- f->callback = destroy_callback;
- }
- else {
-#if HAS_NAME_WINDOW_PIXMAP
- if (w->pixmap && fadeout && winTypeFade[w->windowType]) {
- set_fade (dpy, w, w->opacity*1.0/OPAQUE, 0.0, fade_out_step, destroy_callback, gone, False, True, True);
- }
- else
-#endif
- {
- if (!gone) {
- finish_destroy_win (dpy, id, gone);
- }
- else {
- w->destruct_queued = True;
- w->destruct_requested = True;
- w->destruct_request_time = get_time_in_milliseconds();
- }
- }
- }
- }
-}
-
-#if DEBUG_WINDOWS
- static void
-dump_win (win *w)
-{
- printf ("\t%08lx: %d x %d + %d + %d (%d)\n", w->id,
- w->a.width, w->a.height, w->a.x, w->a.y, w->a.border_width);
-}
-
-
- static void
-dump_wins (void)
-{
- win *w;
-
- printf ("windows:\n");
- for (w = list; w; w = w->next) {
- dump_win (w);
- }
-}
-#endif
-
- static void
-damage_win (Display *dpy, XDamageNotifyEvent *de)
-{
- win *w = find_win (dpy, de->drawable);
-
- if (!w)
- return;
-
-#if WORK_AROUND_FGLRX
- if (w->a.map_state != IsViewable)
- return;
-#endif
-
-#if CAN_DO_USABLE
- if (!w->usable)
- {
- if (w->damage_bounds.width == 0 || w->damage_bounds.height == 0)
- {
- w->damage_bounds = de->area;
- }
- else
- {
- if (de->area.x < w->damage_bounds.x)
- {
- w->damage_bounds.width += (w->damage_bounds.x - de->area.x);
- w->damage_bounds.x = de->area.x;
- }
- if (de->area.y < w->damage_bounds.y)
- {
- w->damage_bounds.height += (w->damage_bounds.y - de->area.y);
- w->damage_bounds.y = de->area.y;
- }
- if (de->area.x + de->area.width > w->damage_bounds.x + w->damage_bounds.width)
- w->damage_bounds.width = de->area.x + de->area.width - w->damage_bounds.x;
- if (de->area.y + de->area.height > w->damage_bounds.y + w->damage_bounds.height)
- w->damage_bounds.height = de->area.y + de->area.height - w->damage_bounds.y;
- }
-#if 0
- printf ("unusable damage [%d] %d, %d: %d x %d bounds %d, %d: %d x %d\n",
- de->drawable,
- de->area.x,
- de->area.y,
- de->area.width,
- de->area.height,
- w->damage_bounds.x,
- w->damage_bounds.y,
- w->damage_bounds.width,
- w->damage_bounds.height);
-#endif
- if (w->damage_bounds.x <= 0 &&
- w->damage_bounds.y <= 0 &&
- w->a.width <= w->damage_bounds.x + w->damage_bounds.width &&
- w->a.height <= w->damage_bounds.y + w->damage_bounds.height)
- {
- clipChanged = True;
- if (winTypeFade[w->windowType]) {
- set_fade (dpy, w, 0, get_opacity_percent (dpy, w), fade_in_step, 0, False, True, True, False);
- }
- w->usable = True;
- }
- }
- if (w->usable)
-#endif
- repair_win (dpy, w);
-}
-
-static const char *
-shape_kind(int kind)
-{
- static char buf[128];
-
- switch(kind){
- case ShapeBounding:
- return "ShapeBounding";
- case ShapeClip:
- return "ShapeClip";
- case ShapeInput:
- return "ShapeInput";
- default:
- sprintf (buf, "Shape %d", kind);
- return buf;
- }
-}
-
-static void
-shape_win (Display *dpy, XShapeEvent *se)
-{
- win *w = find_win (dpy, se->window);
-
- if (!w)
- return;
-
- if (w->a.map_state == IsUnmapped)
- return;
-
- if (w->isInFade)
- return;
-
- if (se->kind == ShapeClip || se->kind == ShapeBounding)
- {
- XserverRegion region0;
- XserverRegion region1;
-
-#if 0
- printf("win 0x%lx %s:%s %ux%u+%d+%d (@%d+%d)\n",
- (unsigned long) se->window,
- shape_kind(se->kind),
- (se->shaped == True) ? "true" : "false",
- se->width, se->height,
- se->x, se->y,
- w->a.x, w->a.y);
- printf("\told %s %d+%d (@%d+%d)\n",
- (w->shaped == True) ? "true" : "false",
- w->shape_bounds_prev.width, w->shape_bounds_prev.height,
- w->shape_bounds_prev.x, w->shape_bounds_prev.y);
-#endif
-
- clipChanged = True;
-
- region0 = XFixesCreateRegion (dpy, &w->shape_bounds_prev, 1);
-
- if (se->shaped == True)
- {
- w->shaped = True;
- w->shape_bounds.x = w->a.x + se->x;
- w->shape_bounds.y = w->a.y + se->y;
- w->shape_bounds.width = se->width;
- w->shape_bounds.height = se->height;
- }
- else
- {
- w->shaped = False;
- w->shape_bounds.x = w->a.x;
- w->shape_bounds.y = w->a.y;
- w->shape_bounds.width = w->a.width;
- w->shape_bounds.height = w->a.height;
- }
-
- region1 = XFixesCreateRegion (dpy, &w->shape_bounds, 1);
- XFixesUnionRegion (dpy, region0, region0, region1);
- XFixesDestroyRegion (dpy, region1);
-
- /* ask for repaint of the old and new region */
- paint_all (dpy, region0);
- }
-
- w->shape_bounds_prev = w->shape_bounds;
-}
-
-static void
-damage_screen (Display *dpy)
-{
- XserverRegion region;
- XRectangle r;
-
- r.x = 0;
- r.y = 0;
- r.width = root_width;
- r.height = root_height;
-
- region = XFixesCreateRegion (dpy, &r, 1);
- add_damage (dpy, region);
- screen_damaged = True;
-}
-
-static int
-error (Display *dpy, XErrorEvent *ev)
-{
- int o;
- char *name = 0;
-
- if (should_ignore (dpy, ev->serial))
- return 0;
-
- if (ev->request_code == composite_opcode &&
- ev->minor_code == X_CompositeRedirectSubwindows)
- {
- fprintf (stderr, "Another composite manager is already running\n");
- my_exit_code=2;
- exit (2);
- }
-
- o = ev->error_code - xfixes_error;
- switch (o) {
- case BadRegion: name = "BadRegion"; break;
- default: break;
- }
- o = ev->error_code - damage_error;
- switch (o) {
- case BadDamage: name = "BadDamage"; break;
- default: break;
- }
- o = ev->error_code - render_error;
- switch (o) {
- case BadPictFormat: name ="BadPictFormat"; break;
- case BadPicture: name ="BadPicture"; break;
- case BadPictOp: name ="BadPictOp"; break;
- case BadGlyphSet: name ="BadGlyphSet"; break;
- case BadGlyph: name ="BadGlyph"; break;
- default: break;
- }
-
-#ifndef NDEBUG
- fprintf (stderr,"error %d request %d minor %d serial %d\n",
- ev->error_code, ev->request_code, ev->minor_code, ev->serial);
-#endif
-
- /* abort (); this is just annoying to most people */
- return 0;
-}
-
- static void
-expose_root (Display *dpy, Window root, XRectangle *rects, int nrects)
-{
- XserverRegion region = XFixesCreateRegion (dpy, rects, nrects);
-
- add_damage (dpy, region);
-}
-
-
- static int
-ev_serial (XEvent *ev)
-{
- if ((ev->type & 0x7f) != KeymapNotify)
- return ev->xany.serial;
- return NextRequest (ev->xany.display);
-}
-
-
- static char *
-ev_name (XEvent *ev)
-{
- static char buf[128];
- switch (ev->type & 0x7f) {
- case Expose:
- return "Expose";
- case MapNotify:
- return "Map";
- case UnmapNotify:
- return "Unmap";
- case ReparentNotify:
- return "Reparent";
- case CirculateNotify:
- return "Circulate";
- default:
- if (ev->type == damage_event + XDamageNotify) {
- return "Damage";
- }
- else if (ev->type == xshape_event + ShapeNotify)
- {
- return "Shape";
- }
- sprintf (buf, "Event %d", ev->type);
- return buf;
- }
-}
-
- static Window
-ev_window (XEvent *ev)
-{
- switch (ev->type) {
- case Expose:
- return ev->xexpose.window;
- case MapNotify:
- return ev->xmap.window;
- case UnmapNotify:
- return ev->xunmap.window;
- case ReparentNotify:
- return ev->xreparent.window;
- case CirculateNotify:
- return ev->xcirculate.window;
- default:
- if (ev->type == damage_event + XDamageNotify) {
-// fprintf(stderr, "%d", ev->type);
- return ((XDamageNotifyEvent *) ev)->drawable;
- }
- else if (ev->type == xshape_event + ShapeNotify)
- {
-// fprintf(stderr, "%d", ev->type);
- return ((XShapeEvent *) ev)->window;
- }
- return 0;
- }
-}
-
-void
-setShadowColor(char *value){ /*format nach #xxxxxx (html) �ndern?*/
- unsigned int tmp;
- char **res = NULL;
- tmp = strtoul(value, res, 16);
- if( !value || strlen(value) < 6 || strlen(value) > 8 || (*(value+1) == 'x' && strlen(value) < 8) || res != NULL ){
- shadowColor.red = 0;
- shadowColor.green = 0;
- shadowColor.blue = 0;
- printf("wrong hexadecimal (use 0xXXXXXX or XXXXXX)! defaulting to black...\n");
- return;
- }
- shadowColor.blue = tmp&0xff;
- tmp >>= 8;
- shadowColor.green = tmp&0xff;
- tmp >>= 8;
- shadowColor.red = tmp&0xff;
-}
-
-typedef enum _option{
- Display_=0,
- Compmode,
- ExcludeDockShadows,
- FadeWindows,
- FadeTrans,
- AutoRedirect,
- Synchronize,
- ShadowColor,
- ShadowRadius,
- ShadowOpacity,
- ShadowOffsetX,
- ShadowOffsetY,
- FadeOutStep,
- FadeInStep,
- FadeDelta,
- DisableARGB,
- FadeMenuWindows,
- NUMBEROFOPTIONS
-} Option;
-
-const char *
-options[NUMBEROFOPTIONS] = {
- "Display", /*0*/
- "Compmode", /*1*/
- "ExcludeDockShadows", /*2*/
- "FadeWindows", /*3*/
- "FadeTrans", /*4*/
- "AutoRedirect", /*5*/
- "Synchronize", /*6*/
- "ShadowColor", /*7*/
- "ShadowRadius", /*8*/
- "ShadowOpacity", /*9*/
- "ShadowOffsetX", /*10*/
- "ShadowOffsetY", /*11*/
- "FadeOutStep", /*12*/
- "FadeInStep", /*13*/
- "FadeDelta", /*14*/
- "DisableARGB", /*15*/
- "FadeMenuWindows", /*16*/
- /*put your thingy in here...*/
-};
-
-void
-setValue(Option option, char *value ){
- int i;
-
- switch(option){ /*please keep that upside-down, because this way adding a new option is easier (all in one view)*/
-
- case FadeDelta:
- fade_delta = atoi(value);
- if (fade_delta < 1)
- fade_delta = 10;
- break;
- case FadeInStep:
- fade_in_step = atof(value);
- if (fade_in_step <= 0)
- fade_in_step = 0.01;
- break;
- case FadeOutStep:
- fade_out_step = atof(value);
- if (fade_out_step <= 0)
- fade_out_step = 0.01;
- break;
- case ShadowOffsetY:
- shadowOffsetY = atoi(value);
- break;
- case ShadowOffsetX:
- shadowOffsetX = atoi(value);
- break;
- case ShadowOpacity:
- shadowOpacity = atof(value);
- break;
- case ShadowRadius:
- shadowRadius = atoi(value);
- break;
- case ShadowColor:
- setShadowColor(value);
- break;
- case Synchronize:
- synchronize = ( strcasecmp(value, "true") == 0 );
- break;
- case AutoRedirect:
- autoRedirect = ( strcasecmp(value, "true") == 0 );
- break;
- case FadeTrans:
- fadeTrans = ( strcasecmp(value, "true") == 0 );
- break;
- case FadeWindows:
- if ( strcasecmp(value, "true") == 0 ) {
- int i;
- for (i = 0; i < NUM_WINTYPES; ++i) {
- if (i != WINTYPE_POPUP_MENU)
- winTypeFade[i] = True;
- }
- }
- break;
- case FadeMenuWindows:
- if ( strcasecmp(value, "true") == 0 ) {
- winTypeFade[WINTYPE_POPUP_MENU] = True;
- }
- break;
- case ExcludeDockShadows:
- if ( strcasecmp(value, "true") == 0 ) {
- winTypeShadow[WINTYPE_DOCK] = False;
- }
- break;
- case Compmode:
- if( strcasecmp(value, "CompClientShadows") == 0 ){
- compMode = CompClientShadows;
- for (i = 0; i < NUM_WINTYPES; ++i)
- winTypeShadow[i] = True;
- }
- else if( strcasecmp(value, "CompServerShadows") == 0 ){
- compMode = CompServerShadows;
- for (i = 0; i < NUM_WINTYPES; ++i)
- winTypeShadow[i] = True;
- }
- else{
- compMode = CompSimple; /*default*/
- for (i = 0; i < NUM_WINTYPES; ++i)
- winTypeShadow[i] = False;
- }
- break;
- case Display_:
- break;
- display = strdup(value);
- break;
- case DisableARGB:
- disable_argb = ( strcasecmp(value, "true") == 0 );
- break;
- default:
- break;
- }
-}
-
-int
-setParameter(char *line){
- char *name = strtok(line, "=");
- char *value = line+strlen(name)+1;
- Option i;
- for(i=Display_; i < NUMBEROFOPTIONS; i++){
- if( strcasecmp(name, *(options+i) ) == 0 ){
- setValue(i, value);
- name = value = NULL;
- return 1;
- }
- }
- printf("ignored unknown option: <%s>\n", name);
- name = value = NULL;
- return 0;
-}
-
-void
-loadConfig(char *filename){
- FILE *file = NULL;
- char line[ 1024 ];
- size_t length = 0;
- Bool wasNull = False;
- Bool section = False;
-
- if( filename == NULL ){
-#ifdef USE_ENV_HOME
- const char *home = getenv("HOME");
-#else
- const char *home;
- struct passwd *p;
- p = getpwuid(getuid());
- if (p)
- home = p->pw_dir;
- else
- home = getenv("HOME");
-#endif
- const char *configfile = "/.xcompmgrrc";
- int n = strlen(home)+strlen(configfile)+1;
- filename = (char*)malloc(n*sizeof(char));
- memset(filename,0,n);
- wasNull = True;
-
- strcat(filename, home);
- strcat(filename, configfile);
- }
-
- printf("trying '%s' as configfile\n\n", filename);
-
- if( (file = fopen(filename, "r")) == NULL ){
- printf("failed to open config file. does it exist?\n");
- if( wasNull ){
- free(filename);
- filename = NULL;
- }
- return;
- }
-
- /*find section*/
- while( !section && fgets(line, 1023, file) != NULL ){
- if( strcmp(line, "[xcompmgr]\n") == 0 )
- section = True;
- }
- /*read and set values*/
- while( section && fgets(line, 1023, file) != NULL ){
- int ret = strlen( line );
- if( ret > 1 ){
- if( *line == '[' )/*found new section - maybe check for '\n'?*/
- break;
- *(line+ret-1) = '\0';
- setParameter(line);
- }
- }
- printf("\nfinished parsing the config file\n");
- fclose(file);
- if( wasNull ){
- free(filename);
- filename = NULL;
- }
-}
-
- void
-usage (char *program)
-{
- fprintf (stderr, "%s v1.0\n", program);
- fprintf (stderr, "usage: %s [options]\n", program);
- fprintf (stderr, "Options\n");
- fprintf (stderr, " -d display\n Specifies which display should be managed.\n");
- fprintf (stderr, " -r radius\n Specifies the blur radius for client-side shadows. (default 12)\n");
- fprintf (stderr, " -o opacity\n Specifies the translucency for client-side shadows. (default .75)\n");
- fprintf (stderr, " -l left-offset\n Specifies the left offset for client-side shadows. (default -15)\n");
- fprintf (stderr, " -t top-offset\n Specifies the top offset for clinet-side shadows. (default -15)\n");
- fprintf (stderr, " -b color\n Specifies the background color to use if no root pixmap is set. (default is black)\n");
- fprintf (stderr, " -I fade-in-step\n Specifies the opacity change between steps while fading in. (default 0.028)\n");
- fprintf (stderr, " -O fade-out-step\n Specifies the opacity change between steps while fading out. (default 0.03)\n");
- fprintf (stderr, " -D fade-delta-time\n Specifies the time between steps in a fade in milliseconds. (default 10)\n");
- fprintf (stderr, " -a\n Use automatic server-side compositing. Faster, but no special effects.\n");
- fprintf (stderr, " -c\n Draw client-side shadows with fuzzy edges.\n");
- fprintf (stderr, " -C\n Avoid drawing shadows on dock/panel windows.\n");
- fprintf (stderr, " -f\n Fade windows in/out when opening/closing.\n");
- fprintf (stderr, " -F\n Fade windows during opacity changes.\n");
- fprintf (stderr, " -n\n Normal client-side compositing with transparency support\n");
- fprintf (stderr, " -s\n Draw server-side shadows with sharp edges.\n");
- fprintf (stderr, " -S\n Enable synchronous operation (for debugging).\n");
- fprintf (stderr, " -x [0x]XXXXXX\n Choose Custom Color in hex format\n");
- fprintf (stderr, " -v\n Print version Number and exit\n");
- fprintf (stderr, " -h\n Print this help\n");
- my_exit_code=2;
- exit (2);
-}
-
-static Bool
-register_cm (void)
-{
- Window w;
- Atom a;
- static char net_wm_cm[] = "_NET_WM_CM_Sxx";
-
- snprintf (net_wm_cm, sizeof (net_wm_cm), "_NET_WM_CM_S%d", scr);
- a = XInternAtom (dpy, net_wm_cm, False);
-
-/* w = XGetSelectionOwner (dpy, a);
- if (w != None)
- {
- XTextProperty tp;
- char **strs;
- int count;
- Atom winNameAtom = XInternAtom (dpy, "_NET_WM_NAME", False);
-
- if (!XGetTextProperty (dpy, w, &tp, winNameAtom) &&
- !XGetTextProperty (dpy, w, &tp, XA_WM_NAME))
- {
- fprintf (stderr,
- "Another composite manager is already running (0x%lx)\n",
- (unsigned long) w);
- return False;
- }
- if (XmbTextPropertyToTextList (dpy, &tp, &strs, &count) == Success)
- {
- fprintf (stderr,
- "Another composite manager is already running (%s)\n",
- strs[0]);
-
- XFreeStringList (strs);
- }
-
- XFree (tp.value);
-
- return False;
- }*/
-
- w = XCreateSimpleWindow (dpy, RootWindow (dpy, scr), 0, 0, 1, 1, 0, None,
- None);
- Xutf8SetWMProperties(dpy, w, "kcompmgr", "kcompmgr", NULL, 0, NULL, NULL,
- NULL);
-
- /* setting this causes kompmgr to abort on TDE login */
- /* XSetSelectionOwner (dpy, a, w, 0); */
-
- return True;
-}
-
-int
-main (int argc, char **argv)
-{
- XEvent ev;
- Window root_return, parent_return;
- Window *children;
- Pixmap transPixmap;
- Pixmap blackPixmap;
- unsigned int nchildren;
- int i;
- XRenderPictureAttributes pa;
- XRenderColor c;
- XRectangle *expose_rects = 0;
- int size_expose = 0;
- int n_expose = 0;
- struct pollfd ufd;
- int n;
- int last_update;
- int now;
- int p;
- int composite_major, composite_minor;
- Bool noDockShadow = False;
-
- for (i = 0; i < NUM_WINTYPES; ++i) {
- winTypeFade[i] = False;
- winTypeShadow[i] = False;
- winTypeOpacity[i] = 1.0;
- }
-
- int o;
- char *fill_color_name = NULL;
- char **res = NULL;
-
- shadowColor.red = 0;
- shadowColor.green = 0;
- shadowColor.blue = 0;
-
- // Initialize signal handlers
- sigfillset(&block_mask);
- usr_action.sa_handler = handle_siguser;
- usr_action.sa_mask = block_mask;
- usr_action.sa_flags = 0;
- sigaction(SIGUSR1, &usr_action, NULL);
- sigaction(SIGUSR2, &usr_action, NULL);
- sigaction(SIGTERM, &usr_action, NULL);
-
- loadConfig(NULL); /*we do that before cmdline-parsing, so config-values can be overridden*/
- /*used for shadow colors*/
-
- while ((o = getopt (argc, argv, "D:I:O:d:r:o:l:t:b:scnfFmCaSx:vhk")) != -1)
- {
- switch (o) {
- case 'd':
- display = optarg;
- break;
- case 'D':
- fade_delta = atoi (optarg);
- if (fade_delta < 1)
- fade_delta = 10;
- break;
- case 'I':
- fade_in_step = atof (optarg);
- if (fade_in_step <= 0)
- fade_in_step = 0.01;
- break;
- case 'O':
- fade_out_step = atof (optarg);
- if (fade_out_step <= 0)
- fade_out_step = 0.01;
- break;
- case 's':
- compMode = CompServerShadows;
- for (i = 0; i < NUM_WINTYPES; ++i)
- winTypeShadow[i] = True;
- break;
- case 'c':
- compMode = CompClientShadows;
- for (i = 0; i < NUM_WINTYPES; ++i)
- winTypeShadow[i] = True;
- break;
- case 'C':
- winTypeShadow[WINTYPE_DOCK] = False;
- break;
- case 'n':
- compMode = CompSimple;
- for (i = 0; i < NUM_WINTYPES; ++i)
- winTypeShadow[i] = False;
- break;
- case 'f':
- for (i = 0; i < NUM_WINTYPES; ++i) {
- if (i != WINTYPE_POPUP_MENU)
- winTypeFade[i] = True;
- }
- break;
- case 'm':
- winTypeFade[WINTYPE_POPUP_MENU] = True;
- break;
- case 'F':
- fadeTrans = True;
- break;
- case 'a':
- autoRedirect = True;
- break;
- case 'S':
- synchronize = True;
- break;
- case 'r':
- shadowRadius = atoi (optarg);
- break;
- case 'o':
- shadowOpacity = atof (optarg);
- break;
- case 'l':
- shadowOffsetX = atoi (optarg);
- break;
- case 't':
- shadowOffsetY = atoi (optarg);
- break;
- case 'b':
- fill_color_name = optarg;
- break;
- case 'x':
- if( compMode != CompClientShadows ){
- fprintf(stderr, "sorry, but we need ClientShadows (-c) for coloring to work properly!\ndefaulting to black...\n");
- break;
- }
- setShadowColor(optarg);
- break;
- case 'v': fprintf (stderr, "%s v%-3.2f\n", argv[0], _VERSION_); my_exit_code=0; exit (0);
- case 'k':
- restartOnSigterm = False;
- break;
- case 'h':
- default:
- usage (argv[0]);
- break;
- }
- }
-
- /* don't bother to do anything for the desktop */
- winTypeOpacity[WINTYPE_DESKTOP] = 1.0;
- winTypeShadow[WINTYPE_DESKTOP] = False;
- winTypeFade[WINTYPE_DESKTOP] = False;
-
- dpy = XOpenDisplay (display);
- if (!dpy)
- {
- fprintf (stderr, "Can't open display\n");
- my_exit_code=2;
- exit (2);
- }
- XSetErrorHandler (error);
- if (synchronize)
- XSynchronize (dpy, 1);
- scr = DefaultScreen (dpy);
- root = RootWindow (dpy, scr);
-
- if (!XRenderQueryExtension (dpy, &render_event, &render_error))
- {
- fprintf (stderr, "No render extension\n");
- my_exit_code=2;
- exit (2);
- }
- if (!XQueryExtension (dpy, COMPOSITE_NAME, &composite_opcode,
- &composite_event, &composite_error))
- {
- fprintf (stderr, "No composite extension\n");
- my_exit_code=2;
- exit (2);
- }
- XCompositeQueryVersion (dpy, &composite_major, &composite_minor);
-#if HAS_NAME_WINDOW_PIXMAP
- if (composite_major > 0 || composite_minor >= 2)
- hasNamePixmap = True;
-#endif
-
- if (!XDamageQueryExtension (dpy, &damage_event, &damage_error))
- {
- fprintf (stderr, "No damage extension\n");
- my_exit_code=2;
- exit (2);
- }
- if (!XFixesQueryExtension (dpy, &xfixes_event, &xfixes_error))
- {
- fprintf (stderr, "No XFixes extension\n");
- my_exit_code=2;
- exit (2);
- }
- if (!XShapeQueryExtension (dpy, &xshape_event, &xshape_error))
- {
- fprintf (stderr, "No XShape extension\n");
- my_exit_code=2;
- exit (2);
- }
-
- fprintf(stderr, "Started\n");
-
- if (!register_cm())
- {
- my_exit_code=2;
- exit (2);
- }
-
- /* get atoms */
- shadowAtom = XInternAtom (dpy, SHADOW_PROP, False);
- opacityAtom = XInternAtom (dpy, OPACITY_PROP, False);
- shadeAtom = XInternAtom (dpy, SHADE_PROP, False);
- shapableAtom = XInternAtom (dpy, SHAPABLE_PROP, False);
- decoHashAtom = XInternAtom (dpy, DECOHASH_PROP, False);
- dimAtom = XInternAtom (dpy, DIM_PROP, False);
- deskChangeAtom = XInternAtom (dpy, DESKCHANGE_PROP, False);
- winTypeAtom = XInternAtom (dpy, "_NET_WM_WINDOW_TYPE", False);
- winTDETTDAtom = XInternAtom (dpy, "_TDE_TRANSPARENT_TO_DESKTOP", False);
- winTDETTBAtom = XInternAtom (dpy, "_TDE_TRANSPARENT_TO_BLACK", False);
- winType[WINTYPE_DESKTOP] = XInternAtom (dpy, "_NET_WM_WINDOW_TYPE_DESKTOP", False);
- winType[WINTYPE_DOCK] = XInternAtom (dpy, "_NET_WM_WINDOW_TYPE_DOCK", False);
- winType[WINTYPE_TOOLBAR] = XInternAtom (dpy, "_NET_WM_WINDOW_TYPE_TOOLBAR", False);
- winType[WINTYPE_MENU] = XInternAtom (dpy, "_NET_WM_WINDOW_TYPE_MENU", False);
- winType[WINTYPE_UTILITY] = XInternAtom (dpy, "_NET_WM_WINDOW_TYPE_UTILITY", False);
- winType[WINTYPE_SPLASH] = XInternAtom (dpy, "_NET_WM_WINDOW_TYPE_SPLASH", False);
- winType[WINTYPE_DIALOG] = XInternAtom (dpy, "_NET_WM_WINDOW_TYPE_DIALOG", False);
- winType[WINTYPE_NORMAL] = XInternAtom (dpy, "_NET_WM_WINDOW_TYPE_NORMAL", False);
- winType[WINTYPE_DROPDOWN_MENU] = XInternAtom (dpy, "_NET_WM_WINDOW_TYPE_DROPDOWN_MENU", False);
- winType[WINTYPE_POPUP_MENU] = XInternAtom (dpy, "_NET_WM_WINDOW_TYPE_POPUP_MENU", False);
- winType[WINTYPE_TOOLTIP] = XInternAtom (dpy, "_NET_WM_WINDOW_TYPE_TOOLTIP", False);
- winType[WINTYPE_NOTIFY] = XInternAtom (dpy, "_NET_WM_WINDOW_TYPE_NOTIFICATION", False);
- winType[WINTYPE_COMBO] = XInternAtom (dpy, "_NET_WM_WINDOW_TYPE_COMBO", False);
- winType[WINTYPE_DND] = XInternAtom (dpy, "_NET_WM_WINDOW_TYPE_DND", False);
-
- pa.subwindow_mode = IncludeInferiors;
-
- if (compMode == CompClientShadows)
- {
- gaussianMap = make_gaussian_map(dpy, shadowRadius);
- presum_gaussian (gaussianMap);
- }
-
- if (fill_color_name)
- {
- XColor c;
- if (! XParseColor (dpy, DefaultColormap (dpy, scr),
- fill_color_name, &c))
- {
- fprintf (stderr, "Could not parse fill color.\n");
- my_exit_code=2;
- exit (2);
- }
- if (! XAllocColor (dpy, DefaultColormap (dpy, scr), &c))
- {
- fprintf (stderr, "Could not allocate color.\n");
- my_exit_code=2;
- exit (2);
- }
-
- fill_color.red = c.red;
- fill_color.green = c.green;
- fill_color.blue = c.blue;
- }
- else
- {
- fill_color.red = fill_color.green = fill_color.blue = 0x0;
- }
- fill_color.alpha = 0xffff;
-
- root_width = DisplayWidth (dpy, scr);
- root_height = DisplayHeight (dpy, scr);
-
- rootPicture = XRenderCreatePicture (dpy, root,
- sXRenderFindVisualFormat (dpy,
- DefaultVisual (dpy, scr)),
- CPSubwindowMode,
- &pa);
- blackPicture = solid_picture (dpy, True, 1, (double)(shadowColor.red)/0xff, (double)(shadowColor.green)/0xff, (double)(shadowColor.blue)/0xff);
- if (compMode == CompServerShadows)
- transBlackPicture = solid_picture (dpy, True, 0.3, 0, 0, 0);
- allDamage = None;
- clipChanged = True;
- XGrabServer (dpy);
- if (autoRedirect) {
- XCompositeRedirectSubwindows (dpy, root, CompositeRedirectAutomatic);
- }
- else
- {
- int dummy;
- XCompositeRedirectSubwindows (dpy, root, CompositeRedirectManual);
- XSelectInput (dpy, root,
- SubstructureNotifyMask|
- ExposureMask|
- StructureNotifyMask|
- PropertyChangeMask |
- VisibilityChangeMask);
-
- /*shaping stuff*/
- XShapeQueryExtension(dpy, &shapeEvent, &dummy);
-
- XShapeSelectInput (dpy, root, ShapeNotifyMask);
- XQueryTree (dpy, root, &root_return, &parent_return, &children, &nchildren);
- for (i = 0; i < nchildren; i++) {
- add_win (dpy, children[i], i ? children[i-1] : None);
- }
- XFree (children);
- }
- XUngrabServer (dpy);
- ufd.fd = ConnectionNumber (dpy);
- ufd.events = POLLIN;
- if (!autoRedirect) {
- paint_all (dpy, None);
- }
-
- /* Under no circumstances should these two lines EVER be moved earlier in main() than this point */
- atexit(delete_pid_file);
- write_pid_file(getpid());
-
- for (;;)
- {
-#if DEBUG_WINDOWS
- dump_wins ();
-#endif
- do {
- if (autoRedirect) {
- XFlush (dpy);
- }
- if (!QLength (dpy))
- {
- if (poll (&ufd, 1, fade_timeout()) == 0)
- {
- run_fades (dpy);
- break;
- }
- }
-
- XNextEvent (dpy, &ev);
- if ((ev.type & 0x7f) != KeymapNotify) {
- discard_ignore (dpy, ev.xany.serial);
- }
-#if DEBUG_EVENTS
- printf ("event %10.10s serial 0x%08x window 0x%08x\n",
- ev_name(&ev), ev_serial (&ev), ev_window (&ev));
-#endif
- if (!autoRedirect) switch (ev.type) {
- case CreateNotify:
- add_win (dpy, ev.xcreatewindow.window, 0);
- break;
- case ConfigureNotify:
- configure_win (dpy, &ev.xconfigure);
- break;
- case DestroyNotify:
- destroy_win (dpy, ev.xdestroywindow.window, True, True);
- break;
- case MapNotify:
- map_win (dpy, ev.xmap.window, ev.xmap.serial, True);
- break;
- case UnmapNotify:
- unmap_win (dpy, ev.xunmap.window, True);
- break;
- case ReparentNotify:
- if (ev.xreparent.parent == root)
- add_win (dpy, ev.xreparent.window, 0);
- else
- destroy_win (dpy, ev.xreparent.window, False, True);
- break;
- case CirculateNotify:
- circulate_win (dpy, &ev.xcirculate);
- break;
- case Expose:
- if (ev.xexpose.window == root)
- {
- int more = ev.xexpose.count + 1;
- if (n_expose == size_expose)
- {
- if (expose_rects)
- {
- expose_rects = realloc (expose_rects,
- (size_expose + more) *
- sizeof (XRectangle));
- size_expose += more;
- }
- else
- {
- expose_rects = malloc (more * sizeof (XRectangle));
- size_expose = more;
- }
- }
- expose_rects[n_expose].x = ev.xexpose.x;
- expose_rects[n_expose].y = ev.xexpose.y;
- expose_rects[n_expose].width = ev.xexpose.width;
- expose_rects[n_expose].height = ev.xexpose.height;
- n_expose++;
- if (ev.xexpose.count == 0)
- {
- expose_root (dpy, root, expose_rects, n_expose);
- n_expose = 0;
- }
- }
- break;
- case PropertyNotify:
- for (p = 0; backgroundProps[p]; p++)
- {
- if (ev.xproperty.atom == XInternAtom (dpy, backgroundProps[p], False))
- {
- if (rootTile)
- {
- XRenderFreePicture (dpy, rootTile);
- rootTile = None;
- damage_screen (dpy);
- break;
- }
- }
- }
- /* Window set shade? */
- if (ev.xproperty.atom == shadeAtom)
- {
- win * w = find_win(dpy, ev.xproperty.window);
- if (w){
- unsigned int tmp = get_shade_prop(dpy, w);
- if (tmp)
- {
- if (tmp == 1)
- {
- w->preShadeOpacity = w->opacity;
- w->opacity = w->opacity-1; /*assuming that no human being will ever be able to shade an invisable window ;) */
- determine_mode(dpy, w);
- }
- else if (tmp == 2)
- {
- w->opacity = w->preShadeOpacity;
- determine_mode(dpy, w);
- }
- }
- break;
- }
- }
- else if (ev.xproperty.atom == shapableAtom)
- {
- win * w = find_win(dpy, ev.xproperty.window);
- if (w)
- {
- w->shapable = get_shapable_prop(dpy, w);
- /* printf("%u is %s shapable\n",w->id,w->shapable?"":"not");*/
- }
- else
- printf("arrrg, window not found\n");
- }
- else if (ev.xproperty.atom == decoHashAtom)
- {
- win * w = find_win(dpy, ev.xproperty.window);
- if (w)
- {
- w->decoHash = get_decoHash_prop(dpy, w);
- }
- else
- printf("arrrg, window not found\n");
- }
- else if (ev.xproperty.atom == dimAtom)
- {
- win * w = find_win(dpy, ev.xproperty.window);
- if (w)
- {
- unsigned int tmp = get_dim_prop(dpy, w);
- if (w->dimPicture)
- {
- XRenderFreePicture (dpy, w->dimPicture);
- w->dimPicture = None;
- }
- if (tmp < OPAQUE)
- w->dimPicture = solid_picture (dpy, True, (double)tmp/OPAQUE, 0.1, 0.1, 0.1);
- }
- else
- printf("arrrg, window not found\n");
- }
- /* check if Trans or Shadow property was changed */
- else if (ev.xproperty.atom == opacityAtom || ev.xproperty.atom == shadowAtom)
- {
- /* reset mode and redraw window */
- win * w = find_win(dpy, ev.xproperty.window);
- if (w)
- {
- unsigned int tmp;
- unsigned int oldShadowSize = w->shadowSize;
- if (ev.xproperty.atom == opacityAtom)
- {
- tmp = get_opacity_prop(dpy, w, OPAQUE);
- /*This will most probably happen if window is in fade - resulting in that the fade process isn't updated or broken -> we may have a wrong opacity in the future*/
- /*if (tmp == w->opacity)
- break;*/ /*skip if opacity does not change*/
- if (fadeTrans)
- {
- static double start, finish, step;
- start = w->opacity*1.0/OPAQUE;
- finish = (tmp*1.0)/OPAQUE;
-
- if ( start > finish )
- step = fade_out_step;
- else
- step = fade_in_step;
-
- set_fade (dpy, w, start, finish, step, 0, False, True, True, False);
- break;
- }
- else {
- w->opacity = tmp;
- }
- }
- else
- {
- tmp = get_shadow_prop(dpy, w);
- if (tmp == w->shadowSize)
- break; /*skip if shadow does not change*/
- w->shadowSize = tmp;
- /* if (w->isInFade)
- break; */
- }
- if (w->shadow)
- {
- XRenderFreePicture (dpy, w->shadow);
- w->shadow = None;
- }
- if (oldShadowSize < w->shadowSize) /* this is important to catch size changes on cleanup with determine_mode*/
- {
- if( w->extents != None )
- XFixesDestroyRegion( dpy, w->extents );
- w->extents = win_extents (dpy, w);
- determine_mode(dpy, w);
- }
- else
- {
- determine_mode(dpy, w);
- if( w->extents != None )
- XFixesDestroyRegion( dpy, w->extents );
- w->extents = win_extents (dpy, w);
- }
- }
- }
- else if (ev.xproperty.atom == deskChangeAtom)
- {
- /*just set global variable*/
- unsigned int tmp = get_deskchange_prop(dpy, ev.xproperty.window);
- printf("desk change, state:%d\n",tmp);
- }
- else if (ev.xproperty.atom == winTDETTDAtom)
- {
- win * w = find_win(dpy, ev.xproperty.window);
- if (w)
- {
- w->show_root_tile = determine_window_transparent_to_desktop(dpy, ev.xproperty.window);
- }
- }
- else if (ev.xproperty.atom == winTDETTBAtom)
- {
- win * w = find_win(dpy, ev.xproperty.window);
- if (w)
- {
- w->show_black_background = determine_window_transparent_to_black(dpy, ev.xproperty.window);
- }
- }
- break;
- default:
- if (ev.type == damage_event + XDamageNotify)
- {
- /* printf("damaging win: %u\n",ev.xany.window);*/
- damage_win (dpy, (XDamageNotifyEvent *) &ev);
- repaint_root_overlay_window();
- }
- if (ev.type == xshape_event + ShapeNotify)
- {
- shape_win (dpy, (XShapeEvent *) &ev);
- }
- if (ev.type == shapeEvent)
- {
- win * w = find_win(dpy, ev.xany.window);
-#if 1
- if (w && w->shapable)
-#endif
-#if 0
- if (w)
-#endif
- {
-#if 0
- XRectangle rect;
- rect.x = ((XShapeEvent*)&ev)->x;
- rect.y = ((XShapeEvent*)&ev)->y;
- rect.width = ((XShapeEvent*)&ev)->width;
- rect.height = ((XShapeEvent*)&ev)->height;
- damage_shape(dpy, w, &rect);
-#endif
-#if 0
- if (w->shadowSize != 0)
- {
- w->shadowSize = 0;
- XRenderFreePicture (dpy, w->shadow);
- w->shadow = None;
- determine_mode(dpy, w);
- if( w->extents != None )
- XFixesDestroyRegion( dpy, w->extents );
- w->extents = win_extents (dpy, w);
- }
-#endif
- /*this is hardly efficient, but a current workaraound
- shaping support isn't that good so far (e.g. we lack shaped shadows)
- IDEA: use XRender to scale/shift a copy of the window and then blur it*/
-#if 1
- if (w->picture)
- {
- clipChanged = True;
- repair_win (dpy, w);
- }
-#endif
- }
- }
- break;
- }
- } while (QLength (dpy));
- if (allDamage && !autoRedirect)
- {
- paint_all (dpy, allDamage);
- XSync (dpy, False);
- allDamage = None;
- clipChanged = False;
- }
- }
-
- XClearArea (dpy, root, 0, 0, 0, 0, True);
- XSync (dpy, False);
-}