/* Copyright (c) 1999 Decklin Foster <fosterd@hartwick.edu>
Copyright (c) 2000 Linus Nilsson <d96ln@efd.lth.se> */
#include "yawm.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
void make_new_client(Window w) {
Client *c;
int i;
XGrabServer(dpy);
c = (Client *) malloc(sizeof(Client));
c->window = (int) NULL;
c->next = head_client;
c->prev = NULL;
if (head_client) {
head_client->prev = c;
}
c->name = "Untitled";
c->barname = "Untitled";
c->minimized = 0;
c->maximized = 0;
c->shaded = 0;
head_client = c;
initialize(c, w);
c->y += theight(c);
reparent(c);
if (wm_state(c) == IconicState) {
c->ignore_unmap++;
XUnmapWindow(dpy, c->parent);
XUnmapWindow(dpy, c->window);
c->minimized = 1;
} else {
XMapWindow(dpy, c->window);
XMapRaised(dpy, c->parent);
set_wm_state(c, NormalState);
}
#ifdef DEBUG
err("%s (%d, %d): %#x (%#x) @ %dx%d+%d+%d", c->name, wm_state(c),
c->ignore_unmap, c->window, c->parent,
c->width, c->height, c->x, c->y);
#endif
XSync(dpy, False);
XUngrabServer(dpy);
}
void initialize(Client *c, Window w) {
XWindowAttributes attr;
long dummy;
XWMHints *hints = XGetWMHints(dpy, w);
c->window = w;
c->ignore_unmap = 0;
XGetTransientForHint(dpy, c->window, &c->trans);
XFetchName(dpy, c->window, &c->name);
XGetWindowAttributes(dpy, c->window, &attr);
c->x = attr.x;
c->y = attr.y;
c->width = attr.width;
c->height = attr.height;
c->cmap = attr.colormap;
c->size = XAllocSizeHints();
XGetWMNormalHints(dpy, c->window, c->size, &dummy);
if (attr.map_state == IsViewable) {
c->ignore_unmap++;
}
else {
init_position(c);
if (hints && hints->flags & StateHint)
set_wm_state(c, hints->initial_state);
}
if (hints) {
XFree(hints);
}
}
void init_position(Client *c) {
int x, y;
int xmax = DisplayWidth(dpy, screen);
int ymax = DisplayHeight(dpy, screen);
if (c->size->flags & (/*PSize | */USSize)) {
c->width = c->size->width;
c->height = c->size->height;
}
if (c->width < MINSIZE) c->width = MINSIZE;
if (c->height < MINSIZE) c->height = MINSIZE;
if (c->width > xmax) c->width = xmax;
if (c->height > ymax) c->height = ymax;
if (c->size->flags & (/*PPosition | */USPosition)) {
c->x = c->size->x;
c->y = c->size->y;
if (c->x < 0 || c->y < 0 || c->x > xmax || c->y > ymax)
c->x = c->y = 1;
} else {
get_mouse_position(&x, &y);
c->x = (x / (float)xmax) * (xmax - c->width);
c->y = (y / (float)ymax) * (ymax - theight(c) - c->height);
}
}
void reparent(Client *c) {
XSetWindowAttributes p_attr;
XSelectInput(dpy, c->window, ColormapChangeMask | EnterWindowMask |
LeaveWindowMask | PropertyChangeMask | KeyPressMask |
ExposureMask);
p_attr.override_redirect = True;
p_attr.background_pixel = bg.pixel;
p_attr.border_pixel = bd.pixel;
p_attr.event_mask = ChildMask | ButtonPressMask | ExposureMask |
CWBackingPixel | CWBackPixel | EnterWindowMask | KeyPressMask;
c->parent = XCreateWindow(dpy, root, c->x, c->y - theight(c),
c->width, c->height + theight(c),
opt_bw, DefaultDepth(dpy, screen),
CopyFromParent, DefaultVisual(dpy, screen),
CWOverrideRedirect | CWBackPixel |
CWBackingPixel | CWBorderPixel |
CWBackingStore | CWEventMask,
&p_attr);
#ifdef SHAPE
if (shape) {
XShapeSelectInput(dpy, c->window, ShapeNotifyMask);
set_shape(c);
}
#endif
XAddToSaveSet(dpy, c->window);
XSetWindowBorderWidth(dpy, c->window, 0);
XResizeWindow(dpy, c->window, c->width, c->height);
XReparentWindow(dpy, c->window, c->parent, 0, theight(c));
send_config(c);
}
syntax highlighted by Code2HTML, v. 0.9.1