673 lines
21 KiB
C
673 lines
21 KiB
C
|
/* Copyright 1989 GROUPE BULL -- See license conditions in file COPYRIGHT
|
||
|
* Copyright 1989 Massachusetts Institute of Technology
|
||
|
*/
|
||
|
/*********************************************\
|
||
|
* *
|
||
|
* BULL WINDOW MANAGER for X11 . *
|
||
|
* *
|
||
|
* MODULE defining the Bar Wob class. *
|
||
|
* *
|
||
|
\*********************************************/
|
||
|
|
||
|
/* include */
|
||
|
#include "EXTERN.h"
|
||
|
#include "wool.h"
|
||
|
#include "wl_atom.h"
|
||
|
#include "gwm.h"
|
||
|
#include "wl_fsm.h"
|
||
|
#include "wl_pixmap.h"
|
||
|
#include "wl_cursor.h"
|
||
|
#include "wl_bar.h"
|
||
|
|
||
|
/* local constants */
|
||
|
|
||
|
/* external */
|
||
|
extern Wob NewWob();
|
||
|
extern Plug NewPlug();
|
||
|
extern WOOL_METHOD WLMenu[];
|
||
|
extern Bar BarOpen();
|
||
|
extern BarEventHandler(), BarClose(), UpdateBarGeometry(), ReconfigureBar();
|
||
|
|
||
|
#ifdef SHAPE /* compile with -I/usr/include/X11 AND
|
||
|
-I/usr/include/X11/extensions to work on
|
||
|
machines having shapes.h in either place */
|
||
|
#include <shape.h>
|
||
|
extern BarIsShaped(), UpdateBarShape();
|
||
|
#define TileIsShaped(tile) \
|
||
|
(tile && (tile)->type == WLPixmap) && ((WOOL_Pixmap) (tile)) -> mask
|
||
|
|
||
|
#endif /* SHAPE */
|
||
|
|
||
|
WOB_METHOD BarClass[] = {
|
||
|
0, /* METHODS_ARRAY */
|
||
|
WobEval,
|
||
|
WobPrint,
|
||
|
WobRelease,
|
||
|
WobExecute,
|
||
|
WobSet,
|
||
|
WobGetCValue,
|
||
|
(WOB_METHOD) BarOpen,
|
||
|
BarClose,
|
||
|
BarEventHandler,
|
||
|
(WOB_METHOD) wool_undefined_method_1,
|
||
|
WobGetDimensions,
|
||
|
(WOB_METHOD) wool_undefined_method_2,
|
||
|
(WOB_METHOD) wool_undefined_method_2,
|
||
|
ReconfigureBar,
|
||
|
(WOB_METHOD) wool_undefined_method_2,
|
||
|
(WOB_METHOD) wool_undefined_method_1,
|
||
|
(WOB_METHOD) wool_undefined_method_1,
|
||
|
(WOB_METHOD) wool_undefined_method_1,
|
||
|
(WOB_METHOD) wool_undefined_method_1,
|
||
|
(WOB_METHOD) wool_undefined_method_1
|
||
|
};
|
||
|
|
||
|
/* routines */
|
||
|
|
||
|
/*
|
||
|
* NewBar
|
||
|
* Creates a new bar object from a WOOL_Bar description
|
||
|
* Warning: a plug may be NULL to indicate an extensible space
|
||
|
*/
|
||
|
|
||
|
Bar
|
||
|
NewBar(parent, wl_bar, dir)
|
||
|
Wob parent;
|
||
|
WOOL_Bar wl_bar;
|
||
|
short dir;
|
||
|
{
|
||
|
Bar bar = (Bar) NewWob(sizeof(struct _Bar)
|
||
|
+ sizeof(Plug) * Max(0, (wl_bar -> plugs_size - 1)));
|
||
|
int i;
|
||
|
WOOL_OBJECT object;
|
||
|
|
||
|
wl_bar = (WOOL_Bar) wool_type_or_evaluate(wl_bar, WLBar);
|
||
|
bar -> type = BarClass;
|
||
|
bar -> parent = parent;
|
||
|
bar -> direction = dir;
|
||
|
bar -> elength = 0;
|
||
|
bar -> ewidth = (wl_bar -> plugs_size ? 1 : 0);
|
||
|
|
||
|
/* set up the box info */
|
||
|
bar -> box.width = bar -> box.height = wl_bar -> min_width;
|
||
|
bar -> min_width = wl_bar -> min_width;
|
||
|
bar -> max_width = wl_bar -> max_width;
|
||
|
bar -> box.borderwidth = wl_bar -> borderwidth;
|
||
|
bar -> box.borderpixel = wl_bar -> borderpixel;
|
||
|
bar -> box.background = wl_bar -> background;
|
||
|
bar -> plug_separator = wl_bar -> plug_separator;
|
||
|
increase_reference(bar -> menu =
|
||
|
wool_type_or_evaluate(wl_bar -> menu, WLMenu));
|
||
|
increase_reference(bar -> property = (WOOL_OBJECT) wl_bar -> property);
|
||
|
increase_reference(bar -> bordertile =
|
||
|
wool_type_or_evaluate(wl_bar -> bordertile, WLPixmap));
|
||
|
increase_reference(bar -> fsm =
|
||
|
wool_type_or_evaluate(wl_bar -> fsm, WLFsm));
|
||
|
increase_reference(bar -> cursor =
|
||
|
wool_type_or_evaluate(wl_bar -> cursor, WLCursor));
|
||
|
increase_reference(bar -> tile = (wl_bar -> tile == TRU ? wl_bar -> tile :
|
||
|
wool_type_or_evaluate(wl_bar -> tile, WLPixmap)));
|
||
|
|
||
|
/* then recursively sets plug infos */
|
||
|
bar -> nplugs = wl_bar -> plugs_size;
|
||
|
for (i = 0; i < wl_bar -> plugs_size; i++) {
|
||
|
object = (WOOL_OBJECT) wl_bar -> plugs[i];
|
||
|
if ((object != NIL) &&
|
||
|
(object -> type != WLBar) &&
|
||
|
(object -> type != WLPlug)) {
|
||
|
object = WOOL_send(WOOL_eval, object, (object));
|
||
|
if (object == UNDEFINED_WOOL_VALUE)
|
||
|
wool_error(UNDEFINED_VARIABLE, "");
|
||
|
else if ((object != NIL) &&
|
||
|
(object -> type != WLBar) &&
|
||
|
(object -> type != WLPlug))
|
||
|
bad_argument(object, 0, "PLUG or BAR");
|
||
|
}
|
||
|
if (object -> type == WLPlug) {
|
||
|
bar -> plugs[i] = (Wob) NewPlug(bar, object);
|
||
|
bar -> ewidth = 0;
|
||
|
}
|
||
|
else if (object -> type == WLBar) {
|
||
|
bar -> plugs[i] = (Wob) NewBar(bar, object, !dir);
|
||
|
if (((Bar) bar -> plugs[i]) -> ewidth) bar -> elength = 1;
|
||
|
if (!(((Bar) bar -> plugs[i]) -> elength))
|
||
|
bar -> ewidth = 0;
|
||
|
}
|
||
|
else {
|
||
|
bar -> plugs[i] = (Wob) NULL;
|
||
|
bar -> elength = 1;
|
||
|
}
|
||
|
}
|
||
|
return bar;
|
||
|
}
|
||
|
|
||
|
BarClose(bar)
|
||
|
Bar bar;
|
||
|
{
|
||
|
int i;
|
||
|
|
||
|
if(!bar) return;
|
||
|
for (i = 0; i < bar -> nplugs; i++) {
|
||
|
if (bar -> plugs[i])
|
||
|
if (bar -> plugs[i] -> type == PlugClass)
|
||
|
PlugClose(bar -> plugs[i]);
|
||
|
else if (bar -> plugs[i] -> type == BarClass)
|
||
|
BarClose(bar -> plugs[i]);
|
||
|
}
|
||
|
WobRelease(bar);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Open a Bar
|
||
|
*/
|
||
|
|
||
|
Bar
|
||
|
BarOpen(bar)
|
||
|
Bar bar;
|
||
|
{
|
||
|
int i;
|
||
|
|
||
|
if(!bar)
|
||
|
return bar;
|
||
|
check_window_size(bar);
|
||
|
bar -> hook = XCreateSimpleWindow(dpy, bar -> parent -> hook,
|
||
|
bar -> box.x, bar -> box.y,
|
||
|
bar -> box.width, bar -> box.height,
|
||
|
bar -> box.borderwidth,
|
||
|
bar -> box.borderpixel,
|
||
|
bar -> box.background);
|
||
|
if (bar -> parent -> type == ScreenClass)
|
||
|
bar -> status |= TopLevelXWindowStatus;
|
||
|
WobRecordHook(bar);
|
||
|
if (bar -> cursor != NIL)
|
||
|
XDefineCursor(dpy, bar -> hook,
|
||
|
((WOOL_Cursor) bar -> cursor) -> cursor);
|
||
|
if (bar -> tile != NIL && bar -> tile != TRU)
|
||
|
XSetWindowBackgroundPixmap(dpy, bar -> hook,
|
||
|
((WOOL_Pixmap) bar -> tile) -> pixmap);
|
||
|
if (bar -> bordertile != NIL)
|
||
|
XSetWindowBorderPixmap(dpy, bar -> hook,
|
||
|
((WOOL_Pixmap) bar -> bordertile) -> pixmap);
|
||
|
|
||
|
bar -> curstate = (int) WOOL_send(WOOL_open, bar -> fsm, (bar -> fsm));
|
||
|
for (i = 0; i < bar -> nplugs; i++) {
|
||
|
if (bar -> plugs[i])
|
||
|
WOOL_send(WOOL_open, bar -> plugs[i], (bar -> plugs[i]));
|
||
|
}
|
||
|
bar -> input_mask = WobMask | ((WOOL_Fsm) bar -> fsm) -> mask;
|
||
|
XSelectInput(dpy, bar -> hook, bar -> input_mask);
|
||
|
#ifdef SHAPE
|
||
|
if (BarIsShaped(bar)) {
|
||
|
bar -> shaped = 1;
|
||
|
UpdateBarShape(bar);
|
||
|
}
|
||
|
#endif /* SHAPE */
|
||
|
XMapWindow(dpy, bar -> hook);
|
||
|
XMapSubwindows(dpy, bar -> hook);
|
||
|
return bar;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
CalcNaturalBarWidth(bar)
|
||
|
Bar bar;
|
||
|
{
|
||
|
Plug *plugs;
|
||
|
int i, curr_width = 1;
|
||
|
|
||
|
plugs = (Plug *) & ((bar -> plugs)[0]);
|
||
|
|
||
|
if (bar -> direction == HORIZONTAL) {
|
||
|
if (!bar -> nplugs && bar -> tile != NIL && bar -> tile != TRU)
|
||
|
curr_width = ((WOOL_Pixmap) bar -> tile) -> height;
|
||
|
for (i = 0; i < bar -> nplugs; i++) {
|
||
|
if (plugs[i])
|
||
|
if (plugs[i] -> type == PlugClass) {
|
||
|
UpdatePlugGeometry(plugs[i]);
|
||
|
curr_width = Max(curr_width,
|
||
|
plugs[i] -> box.height + 2 * plugs[i] -> box.borderwidth);
|
||
|
} else {
|
||
|
curr_width = Max(curr_width,
|
||
|
CalcNaturalBarLength(plugs[i]) + 2 * plugs[i] -> box.borderwidth);
|
||
|
}
|
||
|
}
|
||
|
curr_width = Min(bar -> max_width, Max(bar -> min_width, curr_width));
|
||
|
return curr_width;
|
||
|
} else {
|
||
|
if (!bar -> nplugs && bar -> tile != NIL && bar -> tile != TRU)
|
||
|
curr_width = ((WOOL_Pixmap) bar -> tile) -> width;
|
||
|
for (i = 0; i < bar -> nplugs; i++) {
|
||
|
if (plugs[i])
|
||
|
if (plugs[i] -> type == PlugClass) {
|
||
|
UpdatePlugGeometry(plugs[i]);
|
||
|
curr_width = Max(curr_width,
|
||
|
plugs[i] -> box.width + 2 * plugs[i] -> box.borderwidth);
|
||
|
} else {
|
||
|
curr_width = Max(curr_width,
|
||
|
CalcNaturalBarLength(plugs[i]) + 2 * plugs[i] -> box.borderwidth);
|
||
|
}
|
||
|
}
|
||
|
curr_width = Min(bar -> max_width, Max(bar -> min_width, curr_width));
|
||
|
return curr_width;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
int
|
||
|
CalcNaturalBarLength(bar)
|
||
|
Bar bar;
|
||
|
{
|
||
|
Plug *plugs;
|
||
|
int i, tmp;
|
||
|
int current_pos = 0;
|
||
|
int space_len = 0, n_spaces = 0;
|
||
|
|
||
|
plugs = (Plug *) & ((bar -> plugs)[0]);
|
||
|
if (bar -> direction == HORIZONTAL) {
|
||
|
for (i = 0; i < bar -> nplugs; i++)
|
||
|
if (!plugs[i]) {
|
||
|
n_spaces++;
|
||
|
current_pos += space_len;
|
||
|
} else if (plugs[i] -> type == PlugClass) {
|
||
|
UpdatePlugGeometry(plugs[i]);
|
||
|
current_pos += plugs[i] -> box.width
|
||
|
+ bar -> plug_separator + 2 * plugs[i] -> box.borderwidth;
|
||
|
} else {
|
||
|
tmp = CalcNaturalBarWidth(plugs[i]);
|
||
|
if (((Bar) plugs[i]) -> ewidth)
|
||
|
if (tmp > space_len) {
|
||
|
current_pos += n_spaces * (tmp - space_len);
|
||
|
n_spaces++;
|
||
|
space_len = tmp;
|
||
|
} else {
|
||
|
n_spaces++;
|
||
|
tmp = space_len;
|
||
|
}
|
||
|
current_pos += tmp
|
||
|
+ bar -> plug_separator + 2 * plugs[i] -> box.borderwidth;
|
||
|
}
|
||
|
if (current_pos)
|
||
|
current_pos -= bar -> plug_separator;
|
||
|
else if (!bar -> nplugs && bar -> tile != NIL && bar -> tile != TRU)
|
||
|
current_pos = ((WOOL_Pixmap) bar -> tile) -> width;
|
||
|
else
|
||
|
current_pos = 1;
|
||
|
} else {
|
||
|
for (i = 0; i < bar -> nplugs; i++)
|
||
|
if (!plugs[i]) {
|
||
|
n_spaces++;
|
||
|
current_pos += space_len;
|
||
|
} else if (plugs[i] -> type == PlugClass) {
|
||
|
UpdatePlugGeometry(plugs[i]);
|
||
|
current_pos += plugs[i] -> box.height
|
||
|
+ bar -> plug_separator + 2 * plugs[i] -> box.borderwidth;
|
||
|
} else {
|
||
|
tmp = CalcNaturalBarWidth(plugs[i]);
|
||
|
if (((Bar) plugs[i]) -> ewidth)
|
||
|
if (tmp > space_len) {
|
||
|
current_pos += n_spaces * (tmp - space_len);
|
||
|
n_spaces++;
|
||
|
space_len = tmp;
|
||
|
} else {
|
||
|
n_spaces++;
|
||
|
tmp = space_len;
|
||
|
}
|
||
|
current_pos += tmp
|
||
|
+ bar -> plug_separator + 2 * plugs[i] -> box.borderwidth;
|
||
|
}
|
||
|
if (current_pos)
|
||
|
current_pos -= bar -> plug_separator;
|
||
|
else if (!bar -> nplugs && bar -> tile != NIL && bar -> tile != TRU)
|
||
|
current_pos = ((WOOL_Pixmap) bar -> tile) -> height;
|
||
|
else
|
||
|
current_pos = 1;
|
||
|
}
|
||
|
return current_pos;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
CalcMinBarLength(bar)
|
||
|
Bar bar;
|
||
|
{
|
||
|
Plug *plugs;
|
||
|
int i, current_pos = 0;
|
||
|
|
||
|
plugs = (Plug *) & ((bar -> plugs)[0]);
|
||
|
if (bar -> direction == HORIZONTAL) {
|
||
|
for (i = 0; i < bar -> nplugs; i++)
|
||
|
if (plugs[i])
|
||
|
if (plugs[i] -> type == PlugClass) {
|
||
|
UpdatePlugGeometry(plugs[i]);
|
||
|
current_pos += plugs[i] -> box.width
|
||
|
+ bar -> plug_separator + 2 * plugs[i] -> box.borderwidth;
|
||
|
} else {
|
||
|
current_pos += bar -> plug_separator + 2 * plugs[i] -> box.borderwidth
|
||
|
+ (((Bar) plugs[i]) -> ewidth ? 1 : CalcNaturalBarWidth(plugs[i]));
|
||
|
}
|
||
|
if (current_pos) {
|
||
|
current_pos -= bar -> plug_separator;
|
||
|
}
|
||
|
} else {
|
||
|
for (i = 0; i < bar -> nplugs; i++)
|
||
|
if (plugs[i])
|
||
|
if (plugs[i] -> type == PlugClass) {
|
||
|
UpdatePlugGeometry(plugs[i]);
|
||
|
current_pos += plugs[i] -> box.height
|
||
|
+ bar -> plug_separator + 2 * plugs[i] -> box.borderwidth;
|
||
|
} else {
|
||
|
current_pos += bar -> plug_separator + 2 * plugs[i] -> box.borderwidth
|
||
|
+ (((Bar) plugs[i]) -> ewidth ? 1 : CalcNaturalBarWidth(plugs[i]));
|
||
|
}
|
||
|
if (current_pos) {
|
||
|
current_pos -= bar -> plug_separator;
|
||
|
}
|
||
|
}
|
||
|
return current_pos;
|
||
|
}
|
||
|
|
||
|
|
||
|
/*
|
||
|
* Called BEFORE adjusting the client
|
||
|
* Here we take a bar setup, and suppose that its box data is updated.
|
||
|
* Then we ask for the dimension of plugs and proceed to position them.
|
||
|
* Adjust the width of the bars
|
||
|
*/
|
||
|
|
||
|
int
|
||
|
UpdateBarWidth(bar)
|
||
|
Bar bar;
|
||
|
{
|
||
|
Plug *plugs;
|
||
|
int i;
|
||
|
|
||
|
if (!bar)
|
||
|
return 0;
|
||
|
|
||
|
if (bar -> direction == HORIZONTAL) {
|
||
|
bar -> box.height = CalcNaturalBarWidth(bar);
|
||
|
} else {
|
||
|
bar -> box.width = CalcNaturalBarWidth(bar);
|
||
|
}
|
||
|
|
||
|
return 2 * bar -> box.borderwidth + (bar -> direction == HORIZONTAL ?
|
||
|
bar -> box.height : bar -> box.width);
|
||
|
}
|
||
|
|
||
|
|
||
|
/*
|
||
|
* Called AFTER adjusting the client
|
||
|
* Adjust space in the length of the bar.
|
||
|
* If we encounter a NULL plug, treat it as an extensible space
|
||
|
*/
|
||
|
|
||
|
UpdateBarLength(bar)
|
||
|
Bar bar;
|
||
|
{
|
||
|
Plug *plugs;
|
||
|
int i, n = 0, current_pos = 0, n_spaces = 0;
|
||
|
int total_space, delta = 0, shift = 0;
|
||
|
|
||
|
if (!bar)
|
||
|
return;
|
||
|
plugs = (Plug *) & ((bar -> plugs)[0]);
|
||
|
for (i = 0; i < bar -> nplugs; i++)
|
||
|
if (!plugs[i])
|
||
|
n_spaces++;
|
||
|
else if ((plugs[i] -> type == BarClass) && ((Bar) plugs[i]) -> ewidth)
|
||
|
n_spaces++;
|
||
|
total_space = (bar -> direction == HORIZONTAL ? bar -> box.width
|
||
|
: bar -> box.height) - CalcMinBarLength(bar);
|
||
|
if (n_spaces && (total_space > 0)) {
|
||
|
shift = total_space / n_spaces;
|
||
|
delta = total_space % n_spaces;
|
||
|
}
|
||
|
|
||
|
if (bar -> direction == HORIZONTAL) {
|
||
|
for (i = 0; i < bar -> nplugs; i++)
|
||
|
if (plugs[i])
|
||
|
if (plugs[i] -> type == PlugClass) {
|
||
|
plugs[i] -> box.x = current_pos;
|
||
|
plugs[i] -> box.y = (bar -> box.height
|
||
|
- plugs[i]->box.height - 2 * plugs[i] -> box.borderwidth) / 2;
|
||
|
current_pos += plugs[i] -> box.width
|
||
|
+ bar -> plug_separator + 2 * plugs[i] -> box.borderwidth;
|
||
|
} else {
|
||
|
plugs[i] -> box.x = current_pos;
|
||
|
plugs[i] -> box.y = 0;
|
||
|
if (((Bar) plugs[i]) -> ewidth)
|
||
|
plugs[i] -> box.width = 1 + (++n == n_spaces ? shift+delta : shift);
|
||
|
else if (bar -> nplugs == 1)
|
||
|
plugs[i] -> box.width = bar -> box.width - 2 * plugs[i] -> box.borderwidth;
|
||
|
else
|
||
|
plugs[i] -> box.width = CalcNaturalBarWidth(plugs[i]);
|
||
|
plugs[i] -> box.height = bar -> box.height - 2 * plugs[i] -> box.borderwidth;
|
||
|
UpdateBarLength(plugs[i]);
|
||
|
current_pos += plugs[i] -> box.width
|
||
|
+ bar -> plug_separator + 2 * plugs[i] -> box.borderwidth;
|
||
|
}
|
||
|
else {
|
||
|
current_pos += (++n == n_spaces ? shift+delta : shift);
|
||
|
}
|
||
|
} else {
|
||
|
for (i = 0; i < bar -> nplugs; i++)
|
||
|
if (plugs[i])
|
||
|
if (plugs[i] -> type == PlugClass) {
|
||
|
plugs[i] -> box.y = current_pos;
|
||
|
plugs[i] -> box.x = (bar -> box.width
|
||
|
- plugs[i]->box.width - 2 * plugs[i] -> box.borderwidth) / 2;
|
||
|
current_pos += plugs[i] -> box.height
|
||
|
+ bar -> plug_separator + 2 * plugs[i] -> box.borderwidth;
|
||
|
} else {
|
||
|
plugs[i] -> box.y = current_pos;
|
||
|
plugs[i] -> box.x = 0;
|
||
|
if (((Bar) plugs[i]) -> ewidth)
|
||
|
plugs[i] -> box.height = 1 + (++n == n_spaces ? shift+delta : shift);
|
||
|
else if (bar -> nplugs == 1)
|
||
|
plugs[i] -> box.height = bar -> box.height - 2 * plugs[i] -> box.borderwidth;
|
||
|
else
|
||
|
plugs[i] -> box.height = CalcNaturalBarWidth(plugs[i]);
|
||
|
plugs[i] -> box.width = bar -> box.width - 2 * plugs[i] -> box.borderwidth;
|
||
|
UpdateBarLength(plugs[i]);
|
||
|
current_pos += plugs[i] -> box.height
|
||
|
+ bar -> plug_separator + 2 * plugs[i] -> box.borderwidth;
|
||
|
}
|
||
|
else {
|
||
|
current_pos += (++n == n_spaces ? shift+delta : shift);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
int
|
||
|
NaturalBarLength(bar)
|
||
|
Bar bar;
|
||
|
{
|
||
|
Plug *plugs;
|
||
|
int i;
|
||
|
|
||
|
if (!bar)
|
||
|
return 0;
|
||
|
if (bar -> direction == HORIZONTAL) {
|
||
|
bar -> box.width = CalcNaturalBarLength(bar);
|
||
|
} else {
|
||
|
bar -> box.height = CalcNaturalBarLength(bar);
|
||
|
}
|
||
|
return 2 * bar -> box.borderwidth + (bar -> direction == HORIZONTAL ?
|
||
|
bar -> box.width : bar -> box.height);
|
||
|
}
|
||
|
|
||
|
BarEventHandler(bar, evt)
|
||
|
Bar bar;
|
||
|
XEvent *evt;
|
||
|
{
|
||
|
int i;
|
||
|
|
||
|
switch (evt -> type) {
|
||
|
case Expose:
|
||
|
XClearWindow(dpy, bar -> hook);
|
||
|
break;
|
||
|
case GWMUserEvent: /* TODO: no more test on plugs masks*/
|
||
|
WLFsm_action(bar -> fsm, bar, evt);
|
||
|
if (GWM_Propagate_user_events)
|
||
|
for (i = 0; i < bar -> nplugs; i++)
|
||
|
if ((bar -> plugs[i])) {
|
||
|
WOOL_send(WOOL_process_event, bar -> plugs[i],
|
||
|
(bar -> plugs[i], evt));
|
||
|
}
|
||
|
break;
|
||
|
default:
|
||
|
WLFsm_action(bar -> fsm, bar, evt);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
ReconfigureBar(bar, culprit)
|
||
|
Bar bar;
|
||
|
Wob culprit; /* parent or plug */
|
||
|
{
|
||
|
int i, width, height, must_resize = 1;
|
||
|
|
||
|
if (!bar)
|
||
|
return;
|
||
|
width = bar -> box.width;
|
||
|
height = bar -> box.height;
|
||
|
if (culprit != (Wob) bar -> parent) { /* from plug or bar below */
|
||
|
UpdateBarWidth(bar);
|
||
|
WOOL_send(WOOL_reconfigure, bar -> parent, (bar -> parent, bar));
|
||
|
}
|
||
|
else { /* from above */
|
||
|
if (culprit && culprit -> type != BarClass)
|
||
|
UpdateBarLength(bar);
|
||
|
XMoveResizeWindow(dpy, bar -> hook, bar -> box.x, bar -> box.y,
|
||
|
bar -> box.width, bar -> box.height);
|
||
|
for (i = 0; i < bar -> nplugs; i++)
|
||
|
if (bar -> plugs[i])
|
||
|
if (bar -> plugs[i] -> type == PlugClass)
|
||
|
ReconfigurePlug(bar -> plugs[i], bar);
|
||
|
else
|
||
|
ReconfigureBar(bar -> plugs[i], bar);
|
||
|
#ifdef SHAPE
|
||
|
if (bar -> shaped || (bar -> shaped = BarIsShaped(bar)))
|
||
|
UpdateBarShape(bar);
|
||
|
#endif /* SHAPE */
|
||
|
XClearWindow(dpy, bar -> hook);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
set_bar_bitmap(bar, wl_pixmap)
|
||
|
Bar bar;
|
||
|
WOOL_OBJECT wl_pixmap;
|
||
|
{
|
||
|
int shaped_tile = 0;
|
||
|
if (((wl_pixmap -> type == WLAtom) && (wl_pixmap != TRU) && (wl_pixmap != NIL))
|
||
|
|| wl_pixmap -> type == WLList)
|
||
|
return;
|
||
|
if (bar -> tile == TRU)
|
||
|
shaped_tile = -1;
|
||
|
else if (TileIsShaped(bar -> tile))
|
||
|
shaped_tile = 1;
|
||
|
decrease_reference(bar -> tile);
|
||
|
increase_reference(bar -> tile = wl_pixmap);
|
||
|
if ((shaped_tile == -1) && (bar -> tile == TRU))
|
||
|
shaped_tile = 0; /* No reconfigure necessary if it remains TRU */
|
||
|
else if ((bar -> tile == TRU) || TileIsShaped(bar -> tile))
|
||
|
shaped_tile = 1;
|
||
|
if (wl_pixmap == NIL)
|
||
|
XSetWindowBackground(dpy, bar->hook, bar -> box.background);
|
||
|
else if (wl_pixmap -> type == WLPixmap)
|
||
|
XSetWindowBackgroundPixmap(dpy, bar->hook,
|
||
|
((WOOL_Pixmap) wl_pixmap) -> pixmap);
|
||
|
/* Reconfigure only if anything will change */
|
||
|
if (shaped_tile ||
|
||
|
((!bar -> nplugs) &&
|
||
|
((bar -> direction == HORIZONTAL ? bar -> box.height : bar -> box.width) != CalcNaturalBarWidth(bar) ||
|
||
|
(bar -> direction == HORIZONTAL ? bar -> box.width : bar -> box.height) != CalcNaturalBarLength(bar)))) {
|
||
|
ReconfigureBar(bar, 0);
|
||
|
}
|
||
|
XClearWindow(dpy, bar -> hook);
|
||
|
}
|
||
|
|
||
|
#ifdef SHAPE
|
||
|
/* non-rectangular extension */
|
||
|
|
||
|
int
|
||
|
BarIsShaped(bar)
|
||
|
Bar bar;
|
||
|
{
|
||
|
int i;
|
||
|
if ((bar -> tile == TRU) || TileIsShaped(bar -> tile))
|
||
|
return 1;
|
||
|
for (i = 0; i < bar -> nplugs; i++)
|
||
|
if (bar -> plugs[i])
|
||
|
if (bar -> plugs[i] -> type == PlugClass) {
|
||
|
if (((Plug) bar -> plugs[i]) -> graphic -> type == WLPixmap
|
||
|
&& (((WOOL_Pixmap) (((Plug) bar -> plugs[i]) -> graphic))->mask))
|
||
|
return 1;
|
||
|
} else {
|
||
|
if (((Bar) bar -> plugs[i]) -> shaped)
|
||
|
return 1;
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
UpdateBarShape(bar)
|
||
|
Bar bar;
|
||
|
{
|
||
|
XRectangle rect, rect2;
|
||
|
Plug *plugs;
|
||
|
int i;
|
||
|
int shaped_tile = TileIsShaped(bar -> tile);
|
||
|
|
||
|
rect.x = - bar -> box.borderwidth;
|
||
|
rect.y = - bar -> box.borderwidth;
|
||
|
rect.width = bar -> box.width + 2 * bar -> box.borderwidth;
|
||
|
rect.height = bar -> box.height + 2 * bar -> box.borderwidth;
|
||
|
XShapeCombineRectangles(dpy, bar -> hook, ShapeBounding,
|
||
|
0, 0,
|
||
|
&rect, 1, ShapeSet, 0);
|
||
|
/* transparent tile */
|
||
|
if (bar -> tile == TRU || shaped_tile) {
|
||
|
rect2.x = 0;
|
||
|
rect2.y = 0;
|
||
|
rect2.width = bar -> box.width;
|
||
|
rect2.height = bar -> box.height;
|
||
|
XShapeCombineRectangles(dpy, bar -> hook, ShapeBounding,
|
||
|
0, 0,
|
||
|
&rect2, 1, ShapeSubtract, 0);
|
||
|
}
|
||
|
/* shaped tile */
|
||
|
if (shaped_tile) {
|
||
|
int x_offset, y_offset;
|
||
|
/* we do the tiling ourselves by hand */
|
||
|
for (x_offset = 0; x_offset < bar -> box.width;
|
||
|
x_offset += ((WOOL_Pixmap) (bar -> tile)) -> width) {
|
||
|
for (y_offset = 0; y_offset < bar -> box.height;
|
||
|
y_offset += ((WOOL_Pixmap) (bar -> tile))->height) {
|
||
|
XShapeCombineMask(dpy, bar -> hook, ShapeBounding,
|
||
|
x_offset, y_offset,
|
||
|
((WOOL_Pixmap) (bar -> tile)) -> mask,
|
||
|
ShapeUnion);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
plugs = (Plug *) & ((bar -> plugs)[0]);
|
||
|
for (i = 0; i < bar -> nplugs; i++)
|
||
|
if (plugs[i]) {
|
||
|
rect2.x = plugs[i] -> box.x + plugs[i] -> box.borderwidth;
|
||
|
rect2.y = plugs[i] -> box.y + plugs[i] -> box.borderwidth;
|
||
|
rect2.width = plugs[i] -> box.width;
|
||
|
rect2.height = plugs[i] -> box.height;
|
||
|
XShapeCombineRectangles(dpy, bar -> hook, ShapeBounding,
|
||
|
0, 0,
|
||
|
&rect2, 1, ShapeSubtract, 0);
|
||
|
XShapeCombineShape(dpy, bar -> hook, ShapeBounding,
|
||
|
rect2.x,
|
||
|
rect2.y,
|
||
|
plugs[i] -> hook, ShapeBounding,
|
||
|
ShapeUnion);
|
||
|
}
|
||
|
XShapeCombineRectangles(dpy, bar -> hook, ShapeBounding,
|
||
|
0, 0,
|
||
|
&rect, 1, ShapeIntersect, 0);
|
||
|
}
|
||
|
|
||
|
#endif /* SHAPE */
|
||
|
|