/* Copyright (c) 1999 Decklin Foster <fosterd@hartwick.edu>
Copyright (c) 2000 Linus Nilsson <d96ln@efd.lth.se> */
#include "yawm.h"
#include <stdlib.h>
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; i<n; i++) {
if (protocols[i] == xa_wm_delete) {
found++;
}
}
}
if (found && c->window) {
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);
}
syntax highlighted by Code2HTML, v. 0.9.1