/* Copyright (c) 1999 Decklin Foster <fosterd@hartwick.edu>
Copyright (c) 2000 Linus Nilsson <d96ln@efd.lth.se> */
#include "yawm.h"
#include <stdio.h>
#include <time.h>
#include <sys/time.h>
#define DYN_HEIGHT (!c->shaded ? c->height + 3*opt_bw : 2*opt_bw)
void draw_outline(Client *c) {
char buf[40];
XDrawRectangle(dpy, root, invert_gc,
c->x + opt_bw/2,
c->y - theight(c) + opt_bw/2,
c->width + opt_bw,
c->height + theight(c) + opt_bw);
XDrawLine(dpy, root, invert_gc,
c->x + opt_bw,
c->y + opt_bw/2,
c->x + c->width + opt_bw,
c->y + opt_bw/2);
sprintf(buf, "%dx%d+%d+%d", c->width, c->height, c->x, c->y);
XDrawString(dpy, root, invert_gc,
c->x + c->width - XTextWidth(font, buf, strlen(buf)) -
SPACE,
c->y + c->height - SPACE,
buf,
strlen(buf));
}
void get_mouse_position(int *x, int *y) {
Window dw1, dw2;
int t1, t2;
unsigned int t3;
XQueryPointer(dpy, root, &dw1, &dw2, x, y, &t1, &t2, &t3);
}
void fix_size(Client *c) {
int basex;
int basey;
if (c->size->flags & PResizeInc) {
basex = (c->size->flags & PBaseSize) ? c->size->base_width :
(c->size->flags & PMinSize) ? c->size->min_width : 0;
basey = (c->size->flags & PBaseSize) ? c->size->base_height :
(c->size->flags & PMinSize) ? c->size->min_height : 0;
c->width -= (c->width - basex) % c->size->width_inc;
c->height -= (c->height - basey) % c->size->height_inc;
}
if (c->size->flags & PMinSize) {
if (c->width < c->size->min_width) {
c->width = c->size->min_width;
}
if (c->height < c->size->min_height) {
c->height = c->size->min_height;
}
}
if (c->size->flags & PMaxSize) {
if (c->width > c->size->max_width) {
c->width = c->size->max_width;
}
if (c->height > c->size->max_height) {
c->height = c->size->max_height;
}
}
}
void recalculate_sweep(Client *c, int x1, int y1, int x2, int y2) {
int basex, basey;
c->width = abs(x1 - x2) - opt_bw;
c->height = abs(y1 - y2) - opt_bw;
if (c->size->flags & PResizeInc) {
basex = (c->size->flags & PBaseSize) ? c->size->base_width :
(c->size->flags & PMinSize) ? c->size->min_width : 0;
basey = (c->size->flags & PBaseSize) ? c->size->base_height :
(c->size->flags & PMinSize) ? c->size->min_height : 0;
c->width -= (c->width - basex) % c->size->width_inc;
c->height -= (c->height - basey) % c->size->height_inc;
}
if (c->size->flags & PMinSize) {
if (c->width < c->size->min_width) {
c->width = c->size->min_width;
}
if (c->height < c->size->min_height) {
c->height = c->size->min_height;
}
}
if (c->size->flags & PMaxSize) {
if (c->width > c->size->max_width) {
c->width = c->size->max_width;
}
if (c->height > c->size->max_height) {
c->height = c->size->max_height;
}
}
c->x = (x1 <= x2) ? x1 : x1 - c->width;
c->y = (y1 <= y2) ? y1 : y1 - c->height;
}
void sweep(Client *c) {
XEvent ev;
int old_cx = c->x;
int old_cy = c->y;
if (!grab(root, MouseMask, resize_curs)) {
return;
}
XGrabServer(dpy);
draw_outline(c);
setmouse(c->window, c->width, c->height);
for (;;) {
XMaskEvent(dpy, MouseMask, &ev);
switch (ev.type) {
case MotionNotify:
draw_outline(c); /* clear */
recalculate_sweep(c, old_cx, old_cy,
ev.xmotion.x, ev.xmotion.y);
draw_outline(c);
break;
case ButtonRelease:
draw_outline(c); /* clear */
XUngrabServer(dpy);
ungrab();
return;
}
}
}
void move(Client *c) {
XEvent ev;
int x1, y1;
int old_cx = c->x;
int old_cy = c->y;
int first_motion = 1;
int stepx;
int stepy;
int moved = 0;
long old_time;
long new_time;
struct timeval mytp;
if (!grab(root, MouseMask, move_curs)) {
return;
}
get_mouse_position(&x1, &y1);
gettimeofday(&mytp, NULL);
old_time = mytp.tv_usec;
for (;;) {
XMaskEvent(dpy, MouseMask | ExposureMask | PropertyChangeMask | SubstructureRedirectMask, &ev);
switch (ev.type) {
case MotionNotify:
moved = 1;
stepx = old_cx + (ev.xmotion.x - x1);
stepy = old_cy + (ev.xmotion.y - y1);
if (stepx < 0 &&
stepx > -EDGE_RESISTANCE) {
c->x = 0;
}
else if (stepx + c->width + 2*opt_bw >
DisplayWidth(dpy, 0) &&
stepx + c->width < DisplayWidth(dpy, 0) +
EDGE_RESISTANCE) {
c->x = DisplayWidth(dpy, 0) - c->width -
2*opt_bw;
}
else {
c->x = stepx;
}
if (stepy < theight(c) &&
stepy > -EDGE_RESISTANCE) {
c->y = theight(c);
}
else if (stepy + DYN_HEIGHT +
TASKBAR_HEIGHT + opt_bw >
DisplayHeight(dpy, 0) &&
stepy + DYN_HEIGHT +
TASKBAR_HEIGHT <
DisplayHeight(dpy, 0) + EDGE_RESISTANCE) {
c->y = DisplayHeight(dpy, 0) - TASKBAR_HEIGHT -
DYN_HEIGHT - opt_bw;
}
else {
c->y = stepy;
}
if (first_motion) {
first_motion = 0;
}
else {
XMoveWindow(dpy, c->parent, c->x, c->y -
theight(c));
send_config(c);
}
break;
case ButtonRelease:
gettimeofday(&mytp, NULL);
new_time = mytp.tv_usec;
if (!moved && (new_time - old_time) < 1000*175) {
XRaiseWindow(dpy, c->parent);
}
ungrab();
return;
case Expose:
handle_expose_event(&ev.xexpose);
break;
case PropertyNotify:
handle_property_change(&ev.xproperty);
case ConfigureRequest:
handle_configure_request(&ev.xconfigurerequest);
default:
#ifdef DEBUG
show_event(ev);
#endif
break;
}
}
}
void resize(Client *c) {
if (c) {
sweep(c);
XMoveResizeWindow(dpy, c->parent,
c->x, c->y - theight(c), c->width,
c->height + theight(c));
XMoveResizeWindow(dpy, c->window,
0, theight(c), c->width, c->height);
c->stored_x = c->x;
c->stored_y = c->y;
c->stored_width = c->width;
c->stored_height = c->height;
c->maximized = 0;
send_config(c);
}
}
void shade(Client *c) {
if (c) {
if (!c->shaded) {
XResizeWindow(dpy, c->parent,
c->width, theight(c) - opt_bw);
c->shaded = 1;
}
else {
XResizeWindow(dpy, c->parent,
c->width, c->height + theight(c));
c->shaded = 0;
}
send_config(c);
}
}
void maximize(Client *c)
{
if (c) {
if (!c->maximized) {
c->stored_x = c->x;
c->stored_y = c->y;
c->stored_width = c->width;
c->stored_height = c->height;
c->x = 0;
c->y = theight(c);
c->width = DisplayWidth(dpy, 0) - 2*opt_bw;
c->height = DisplayHeight(dpy, 0) - TASKBAR_HEIGHT -
theight(c) - 4*opt_bw;
fix_size(c);
XMoveResizeWindow(dpy, c->parent,
c->x, c->y - theight(c),
c->width, c->height + theight(c));
XMoveResizeWindow(dpy, c->window,
0, theight(c),
c->width, c->height);
c->maximized = 1;
c->shaded = 0;
}
else {
c->x = c->stored_x;
c->y = c->stored_y;
c->width = c->stored_width;
c->height = c->stored_height;
c->maximized = 0;
XMoveResizeWindow(dpy, c->parent,
c->x, c->y - theight(c),
c->width, c->height + theight(c));
XMoveResizeWindow(dpy, c->window,
0, theight(c),
c->width, c->height);
}
send_config(c);
}
}
void maximize_vertically(Client *c) {
if (c) {
if (!c->maximized) {
c->stored_x = c->x;
c->stored_y = c->y;
c->stored_width = c->width;
c->stored_height = c->height;
c->y = theight(c);
c->height = DisplayHeight(dpy, 0) - TASKBAR_HEIGHT -
theight(c) - 3*opt_bw;
fix_size(c);
XMoveResizeWindow(dpy, c->parent,
c->x, c->y - theight(c),
c->width, c->height + theight(c));
XMoveResizeWindow(dpy, c->window,
0, theight(c),
c->width, c->height);
c->maximized = 1;
}
else {
c->x = c->stored_x;
c->y = c->stored_y;
c->width = c->stored_width;
c->height = c->stored_height;
c->maximized = 0;
XMoveResizeWindow(dpy, c->parent,
c->x, c->y - theight(c),
c->width, c->height + theight(c));
XMoveResizeWindow(dpy, c->window,
0, theight(c),
c->width, c->height);
}
send_config(c);
}
}
void hide(Client *c) {
if (c) {
c->ignore_unmap++;
XUnmapWindow(dpy, c->parent);
XUnmapWindow(dpy, c->window);
set_wm_state(c, IconicState);
c->minimized = 1;
}
}
void unhide(Client *c) {
if (c) {
XMapWindow(dpy, c->window);
XMapRaised(dpy, c->parent);
set_wm_state(c, NormalState);
c->minimized = 0;
}
}
syntax highlighted by Code2HTML, v. 0.9.1