/* Copyright (c) 1999 Decklin Foster Copyright (c) 2000 Linus Nilsson */ #include "yawm.h" #include Client *find_client(Window w, int from_parent) { Client *c; if (w && w != root) { for (c = head_client; c; c = c->next) { if (from_parent == -1 && (w == c->parent || w == c->window)) { return c; } else if (w == (from_parent ? c->parent : c->window)) { return c; } } } return NULL; } void set_wm_state(Client *c, int state) { long data[2]; data[0] = (long) state; data[1] = None; /* icon window */ if (c && c->window) { XChangeProperty(dpy, c->window, xa_wm_state, xa_wm_state, 32, PropModeReplace, (unsigned char *)data, 2); } } int wm_state(Client *c) { Atom real_type; int real_format, state; unsigned long n, extra; unsigned char *data; if ((XGetWindowProperty(dpy, c->window, xa_wm_state, 0L, 2L, False, AnyPropertyType, &real_type, &real_format, &n, &extra, &data) == Success) && n) { state = *(int *)data; XFree(data); return state; } else { return WithdrawnState; } } void send_config(Client *c) { XConfigureEvent ce; ce.type = ConfigureNotify; ce.event = c->window; ce.window = c->window; ce.x = c->x; ce.y = c->y; ce.width = c->width; ce.height = c->height; ce.border_width = 0; ce.above = None; ce.override_redirect = 0; XSendEvent(dpy, c->window, False, StructureNotifyMask, (XEvent *) &ce); } void remove_client(Client *c, int from_cleanup) { Client *p; XGrabServer(dpy); if (from_cleanup) { if (wm_state(c) == IconicState); XMapWindow(dpy, c->window); } else { set_wm_state(c, WithdrawnState); } XRemoveFromSaveSet(dpy, c->window); XReparentWindow(dpy, c->window, root, c->x, c->y); if (c->window) XSetWindowBorderWidth(dpy, c->window, 1); XDestroyWindow(dpy, c->parent); if (head_client == c) { head_client = c->next; if (c->next) { c->next->prev = c->prev; } } else { for (p = head_client; p && p->next; p = p->next) { if (p->next == c) { p->next = c->next; } } if (c && p) { p->prev = c->prev; } } if (c->name) { XFree(c->name); } if (c->size) { XFree(c->size); } free(c); XSync(dpy, False); XUngrabServer(dpy); } void redraw(Client *c) { GC tmp_gc; if (c == focused_client) { XSetWindowBackground(dpy, c->parent, focus_bg.pixel); XClearWindow(dpy, c->parent); tmp_gc = focus_string_gc; } else { XSetWindowBackground(dpy, c->parent, bg.pixel); XClearWindow(dpy, c->parent); tmp_gc = string_gc; } XDrawLine(dpy, c->parent, border_gc, 0, theight(c) - opt_bw + opt_bw/2, c->width, theight(c) - opt_bw + opt_bw/2); /* Draw maximize-button */ XDrawRectangle(dpy, c->parent, tmp_gc, c->width - theight(c) + 4, 2, theight(c)-6, 3); XDrawRectangle(dpy, c->parent, tmp_gc, c->width - theight(c) + 4, 2, theight(c)-6, theight(c)-6); /* Draw minimize-button */ XDrawRectangle(dpy, c->parent, tmp_gc, c->width - 2*theight(c)+5, 2 + theight(c) - 9, theight(c)-6, 3); /* Draw close/killbutton */ XDrawLine(dpy, c->parent, tmp_gc, 2, 2, theight(c)-5, theight(c)-5); XDrawLine(dpy, c->parent, tmp_gc, 2, theight(c)-5, theight(c)-5, 2); /* Write name */ if (c == focused_client) { tmp_gc = focus_string_gc; } else { tmp_gc = string_gc; } if (c->name) { XDrawString(dpy, c->parent, tmp_gc, SPACE + theight(c), SPACE + font->ascent, c->name, strlen(c->name)); } } #ifdef SHAPE void set_shape(Client *c) { int n, order; XRectangle *rect; rect = XShapeGetRectangles(dpy, c->window, ShapeBounding, &n, &order); if (n > 1) XShapeCombineShape(dpy, c->parent, ShapeBounding, 0, theight(c), c->window, ShapeBounding, ShapeSet); XFree(rect); } #endif void send_wm_delete(Client *c) { int i, n, found = 0; Atom *protocols; if (c) { if (XGetWMProtocols(dpy, c->window, &protocols, &n)) { for (i=0; iwindow) { send_xmessage(c->window, xa_wm_protos, xa_wm_delete); } else if (c->window) { XKillClient(dpy, c->window); } } } int send_xmessage(Window w, Atom a, long x) { XEvent ev; ev.type = ClientMessage; ev.xclient.window = w; ev.xclient.message_type = a; ev.xclient.format = 32; ev.xclient.data.l[0] = x; ev.xclient.data.l[1] = CurrentTime; return XSendEvent(dpy, w, False, NoEventMask, &ev); }