major refactor

This commit is contained in:
Christopher Jeffrey 2012-02-08 04:20:22 -06:00
parent c451c08058
commit 2424980f22
1 changed files with 234 additions and 172 deletions

406
compton.c
View File

@ -2274,11 +2274,7 @@ main(int argc, char **argv) {
unsigned int nchildren;
int i;
XRenderPictureAttributes pa;
XRectangle *expose_rects = 0;
int size_expose = 0;
int n_expose = 0;
struct pollfd ufd;
int p;
int composite_major, composite_minor;
char *display = 0;
int o;
@ -2290,9 +2286,6 @@ main(int argc, char **argv) {
win_type_opacity[i] = 1.0;
}
/* don't bother to draw a shadow for the desktop */
win_type_shadow[WINTYPE_DESKTOP] = False;
while ((o = getopt(argc, argv, "D:I:O:d:r:o:m:l:t:i:e:scnfFCaSz")) != -1) {
switch (o) {
case 'd':
@ -2421,44 +2414,7 @@ main(int argc, char **argv) {
}
register_cm(scr);
/* get atoms */
extents_atom = XInternAtom(dpy,
"_NET_FRAME_EXTENTS", False);
opacity_atom = XInternAtom(dpy,
"_NET_WM_WINDOW_OPACITY", False);
win_type_atom = XInternAtom(dpy,
"_NET_WM_WINDOW_TYPE", False);
win_type[WINTYPE_UNKNOWN] = 0;
win_type[WINTYPE_DESKTOP] = XInternAtom(dpy,
"_NET_WM_WINDOW_TYPE_DESKTOP", False);
win_type[WINTYPE_DOCK] = XInternAtom(dpy,
"_NET_WM_WINDOW_TYPE_DOCK", False);
win_type[WINTYPE_TOOLBAR] = XInternAtom(dpy,
"_NET_WM_WINDOW_TYPE_TOOLBAR", False);
win_type[WINTYPE_MENU] = XInternAtom(dpy,
"_NET_WM_WINDOW_TYPE_MENU", False);
win_type[WINTYPE_UTILITY] = XInternAtom(dpy,
"_NET_WM_WINDOW_TYPE_UTILITY", False);
win_type[WINTYPE_SPLASH] = XInternAtom(dpy,
"_NET_WM_WINDOW_TYPE_SPLASH", False);
win_type[WINTYPE_DIALOG] = XInternAtom(dpy,
"_NET_WM_WINDOW_TYPE_DIALOG", False);
win_type[WINTYPE_NORMAL] = XInternAtom(dpy,
"_NET_WM_WINDOW_TYPE_NORMAL", False);
win_type[WINTYPE_DROPDOWN_MENU] = XInternAtom(dpy,
"_NET_WM_WINDOW_TYPE_DROPDOWN_MENU", False);
win_type[WINTYPE_POPUP_MENU] = XInternAtom(dpy,
"_NET_WM_WINDOW_TYPE_POPUP_MENU", False);
win_type[WINTYPE_TOOLTIP] = XInternAtom(dpy,
"_NET_WM_WINDOW_TYPE_TOOLTIP", False);
win_type[WINTYPE_NOTIFY] = XInternAtom(dpy,
"_NET_WM_WINDOW_TYPE_NOTIFICATION", False);
win_type[WINTYPE_COMBO] = XInternAtom(dpy,
"_NET_WM_WINDOW_TYPE_COMBO", False);
win_type[WINTYPE_DND] = XInternAtom(dpy,
"_NET_WM_WINDOW_TYPE_DND", False);
get_atoms();
pa.subwindow_mode = IncludeInferiors;
@ -2514,134 +2470,8 @@ main(int argc, char **argv) {
XNextEvent(dpy, &ev);
if ((ev.type & 0x7f) != KeymapNotify) {
discard_ignore(dpy, ev.xany.serial);
}
handle_event((XEvent *)&ev);
#if DEBUG_EVENTS
if (ev.type != damage_event + XDamageNotify) {
printf("event %10.10s serial 0x%08x window 0x%08x\n",
ev_name(&ev), ev_serial(&ev), ev_window(&ev));
}
#endif
switch (ev.type) {
case FocusIn: {
if (!inactive_opacity) break;
win *fw = find_win(dpy, ev.xfocus.window);
if (IS_NORMAL_WIN(fw)) {
set_opacity(dpy, fw, OPAQUE);
}
break;
}
case FocusOut: {
if (!inactive_opacity) break;
if (ev.xfocus.mode == NotifyGrab
|| (ev.xfocus.mode == NotifyNormal
&& (ev.xfocus.detail == NotifyNonlinear
|| ev.xfocus.detail == NotifyNonlinearVirtual))) {
;
} else {
break;
}
win *fw = find_win(dpy, ev.xfocus.window);
if (IS_NORMAL_WIN(fw)) {
set_opacity(dpy, fw, INACTIVE_OPACITY);
}
break;
}
case CreateNotify:
add_win(dpy, ev.xcreatewindow.window, 0,
ev.xcreatewindow.override_redirect);
break;
case ConfigureNotify:
configure_win(dpy, &ev.xconfigure);
break;
case DestroyNotify:
destroy_win(dpy, ev.xdestroywindow.window, True);
break;
case MapNotify:
map_win(dpy, ev.xmap.window, ev.xmap.serial, True,
ev.xmap.override_redirect);
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,
ev.xreparent.override_redirect);
} else {
destroy_win(dpy, ev.xreparent.window, 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; background_props[p]; p++) {
if (ev.xproperty.atom ==
XInternAtom(dpy, background_props[p], False)) {
if (root_tile) {
XClearArea(dpy, root, 0, 0, 0, 0, True);
XRenderFreePicture(dpy, root_tile);
root_tile = None;
break;
}
}
}
/* check if Trans property was changed */
if (ev.xproperty.atom == opacity_atom) {
/* reset mode and redraw window */
win *w = find_win(dpy, ev.xproperty.window);
if (w) {
double def = win_type_opacity[w->window_type];
set_opacity(dpy, w,
get_opacity_prop(dpy, w, (unsigned long)(OPAQUE * def)));
}
}
if (frame_opacity && ev.xproperty.atom == extents_atom) {
win *w = find_toplevel(dpy, ev.xproperty.window);
if (w) {
get_frame_extents(dpy, w->client_win,
&w->left_width, &w->right_width,
&w->top_width, &w->bottom_width);
}
}
break;
default:
if (ev.type == damage_event + XDamageNotify) {
damage_win(dpy, (XDamageNotifyEvent *)&ev);
}
break;
}
} while (QLength(dpy));
if (all_damage) {
@ -2654,3 +2484,235 @@ main(int argc, char **argv) {
}
}
}
static void
get_atoms() {
extents_atom = XInternAtom(dpy,
"_NET_FRAME_EXTENTS", False);
opacity_atom = XInternAtom(dpy,
"_NET_WM_WINDOW_OPACITY", False);
win_type_atom = XInternAtom(dpy,
"_NET_WM_WINDOW_TYPE", False);
win_type[WINTYPE_UNKNOWN] = 0;
win_type[WINTYPE_DESKTOP] = XInternAtom(dpy,
"_NET_WM_WINDOW_TYPE_DESKTOP", False);
win_type[WINTYPE_DOCK] = XInternAtom(dpy,
"_NET_WM_WINDOW_TYPE_DOCK", False);
win_type[WINTYPE_TOOLBAR] = XInternAtom(dpy,
"_NET_WM_WINDOW_TYPE_TOOLBAR", False);
win_type[WINTYPE_MENU] = XInternAtom(dpy,
"_NET_WM_WINDOW_TYPE_MENU", False);
win_type[WINTYPE_UTILITY] = XInternAtom(dpy,
"_NET_WM_WINDOW_TYPE_UTILITY", False);
win_type[WINTYPE_SPLASH] = XInternAtom(dpy,
"_NET_WM_WINDOW_TYPE_SPLASH", False);
win_type[WINTYPE_DIALOG] = XInternAtom(dpy,
"_NET_WM_WINDOW_TYPE_DIALOG", False);
win_type[WINTYPE_NORMAL] = XInternAtom(dpy,
"_NET_WM_WINDOW_TYPE_NORMAL", False);
win_type[WINTYPE_DROPDOWN_MENU] = XInternAtom(dpy,
"_NET_WM_WINDOW_TYPE_DROPDOWN_MENU", False);
win_type[WINTYPE_POPUP_MENU] = XInternAtom(dpy,
"_NET_WM_WINDOW_TYPE_POPUP_MENU", False);
win_type[WINTYPE_TOOLTIP] = XInternAtom(dpy,
"_NET_WM_WINDOW_TYPE_TOOLTIP", False);
win_type[WINTYPE_NOTIFY] = XInternAtom(dpy,
"_NET_WM_WINDOW_TYPE_NOTIFICATION", False);
win_type[WINTYPE_COMBO] = XInternAtom(dpy,
"_NET_WM_WINDOW_TYPE_COMBO", False);
win_type[WINTYPE_DND] = XInternAtom(dpy,
"_NET_WM_WINDOW_TYPE_DND", False);
}
inline static void
ev_focus_in(XFocusChangeEvent *ev) {
if (!inactive_opacity) return;
win *fw = find_win(dpy, ev->window);
if (IS_NORMAL_WIN(fw)) {
set_opacity(dpy, fw, OPAQUE);
}
}
inline static void
ev_focus_out(XFocusChangeEvent *ev) {
if (!inactive_opacity) return;
if (ev->mode == NotifyGrab
|| (ev->mode == NotifyNormal
&& (ev->detail == NotifyNonlinear
|| ev->detail == NotifyNonlinearVirtual))) {
;
} else {
return;
}
win *fw = find_win(dpy, ev->window);
if (IS_NORMAL_WIN(fw)) {
set_opacity(dpy, fw, INACTIVE_OPACITY);
}
}
inline static void
ev_create_notify(XCreateWindowEvent *ev) {
add_win(dpy, ev->window, 0, ev->override_redirect);
}
inline static void
ev_configure_notify(XConfigureEvent *ev) {
configure_win(dpy, ev);
}
inline static void
ev_destroy_notify(XDestroyWindowEvent *ev) {
destroy_win(dpy, ev->window, True);
}
inline static void
ev_map_notify(XMapEvent *ev) {
map_win(dpy, ev->window, ev->serial, True, ev->override_redirect);
}
inline static void
ev_unmap_notify(XUnmapEvent *ev) {
unmap_win(dpy, ev->window, True);
}
inline static void
ev_reparent_notify(XReparentEvent *ev) {
if (ev->parent == root) {
add_win(dpy, ev->window, 0, ev->override_redirect);
} else {
destroy_win(dpy, ev->window, True);
}
}
inline static void
ev_circulate_notify(XCirculateEvent *ev) {
circulate_win(dpy, ev);
}
inline static void
ev_expose(XExposeEvent *ev) {
if (ev->window == root) {
int more = ev->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->x;
expose_rects[n_expose].y = ev->y;
expose_rects[n_expose].width = ev->width;
expose_rects[n_expose].height = ev->height;
n_expose++;
if (ev->count == 0) {
expose_root(dpy, root, expose_rects, n_expose);
n_expose = 0;
}
}
}
inline static void
ev_property_notify(XPropertyEvent *ev) {
int p;
for (p = 0; background_props[p]; p++) {
if (ev->atom == XInternAtom(dpy, background_props[p], False)) {
if (root_tile) {
XClearArea(dpy, root, 0, 0, 0, 0, True);
XRenderFreePicture(dpy, root_tile);
root_tile = None;
break;
}
}
}
/* check if Trans property was changed */
if (ev->atom == opacity_atom) {
/* reset mode and redraw window */
win *w = find_win(dpy, ev->window);
if (w) {
double def = win_type_opacity[w->window_type];
set_opacity(dpy, w,
get_opacity_prop(dpy, w, (unsigned long)(OPAQUE * def)));
}
}
if (frame_opacity && ev->atom == extents_atom) {
win *w = find_toplevel(dpy, ev->window);
if (w) {
get_frame_extents(dpy, w->client_win,
&w->left_width, &w->right_width,
&w->top_width, &w->bottom_width);
}
}
}
inline static void
ev_damage_notify(XDamageNotifyEvent *ev) {
damage_win(dpy, ev);
}
inline static void
handle_event(XEvent *ev) {
if ((ev->type & 0x7f) != KeymapNotify) {
discard_ignore(dpy, ev->xany.serial);
}
#if DEBUG_EVENTS
if (ev->type != damage_event + XDamageNotify) {
printf("event %10.10s serial 0x%08x window 0x%08x\n",
ev_name(ev), ev_serial(ev), ev_window(ev));
}
#endif
switch (ev->type) {
case FocusIn:
ev_focus_in((XFocusChangeEvent *)ev);
break;
case FocusOut:
ev_focus_out((XFocusChangeEvent *)ev);
break;
case CreateNotify:
ev_create_notify((XCreateWindowEvent *)ev);
break;
case ConfigureNotify:
ev_configure_notify((XConfigureEvent *)ev);
break;
case DestroyNotify:
ev_destroy_notify((XDestroyWindowEvent *)ev);
break;
case MapNotify:
ev_map_notify((XMapEvent *)ev);
break;
case UnmapNotify:
ev_unmap_notify((XUnmapEvent *)ev);
break;
case ReparentNotify:
ev_reparent_notify((XReparentEvent *)ev);
break;
case CirculateNotify:
ev_circulate_notify((XCirculateEvent *)ev);
break;
case Expose:
ev_expose((XExposeEvent *)ev);
break;
case PropertyNotify:
ev_property_notify((XPropertyEvent *)ev);
break;
default:
if (ev->type == damage_event + XDamageNotify) {
ev_damage_notify((XDamageNotifyEvent *)ev);
}
break;
}
}