Cleanup indentation with clang-format and changed a few variable names
This commit is contained in:
292
src/util/area.c
292
src/util/area.c
@@ -32,23 +32,24 @@
|
||||
|
||||
Area *mouse_over_area = NULL;
|
||||
|
||||
void initialize_positions(void *obj, int pos)
|
||||
void init_background(Background *bg)
|
||||
{
|
||||
Area *a = (Area*)obj;
|
||||
|
||||
// initialize fixed position/size
|
||||
GList *l;
|
||||
for (l = a->children; l ; l = l->next) {
|
||||
Area *child = ((Area*)l->data);
|
||||
memset(bg, 0, sizeof(Background));
|
||||
}
|
||||
|
||||
void initialize_positions(void *obj, int offset)
|
||||
{
|
||||
Area *a = (Area *)obj;
|
||||
for (GList *l = a->children; l; l = l->next) {
|
||||
Area *child = ((Area *)l->data);
|
||||
if (panel_horizontal) {
|
||||
child->posy = pos + a->bg->border.width + a->paddingy;
|
||||
child->posy = offset + a->bg->border.width + a->paddingy;
|
||||
child->height = a->height - (2 * (a->bg->border.width + a->paddingy));
|
||||
if (child->_on_change_layout)
|
||||
child->_on_change_layout(child);
|
||||
initialize_positions(child, child->posy);
|
||||
}
|
||||
else {
|
||||
child->posx = pos + a->bg->border.width + a->paddingy;
|
||||
} else {
|
||||
child->posx = offset + a->bg->border.width + a->paddingy;
|
||||
child->width = a->width - (2 * (a->bg->border.width + a->paddingy));
|
||||
if (child->_on_change_layout)
|
||||
child->_on_change_layout(child);
|
||||
@@ -57,17 +58,16 @@ void initialize_positions(void *obj, int pos)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void _relayout_fixed(Area *a)
|
||||
void relayout_fixed(Area *a)
|
||||
{
|
||||
if (!a->on_screen)
|
||||
return;
|
||||
|
||||
// Children are resized before the parent
|
||||
GList *l;
|
||||
for (l = a->children; l ; l = l->next)
|
||||
_relayout_fixed(l->data);
|
||||
|
||||
for (l = a->children; l; l = l->next)
|
||||
relayout_fixed(l->data);
|
||||
|
||||
// Recalculate size
|
||||
a->_changed = 0;
|
||||
if (a->resize_needed && a->size_mode == LAYOUT_FIXED) {
|
||||
@@ -77,44 +77,40 @@ void _relayout_fixed(Area *a)
|
||||
if (a->_resize(a)) {
|
||||
// The size hash changed => resize needed for the parent
|
||||
if (a->parent)
|
||||
((Area*)a->parent)->resize_needed = 1;
|
||||
((Area *)a->parent)->resize_needed = 1;
|
||||
a->_changed = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void _relayout_dynamic(Area *a, int level)
|
||||
void relayout_dynamic(Area *a, int level)
|
||||
{
|
||||
// don't resize hiden objects
|
||||
if (!a->on_screen)
|
||||
return;
|
||||
|
||||
// parent node is resized before its children
|
||||
// calculate area's size
|
||||
GList *l;
|
||||
// Area is resized before its children
|
||||
if (a->resize_needed && a->size_mode == LAYOUT_DYNAMIC) {
|
||||
a->resize_needed = 0;
|
||||
|
||||
if (a->_resize) {
|
||||
a->_resize(a);
|
||||
// resize children with LAYOUT_DYNAMIC
|
||||
for (l = a->children; l ; l = l->next) {
|
||||
Area *child = ((Area*)l->data);
|
||||
for (GList *l = a->children; l; l = l->next) {
|
||||
Area *child = ((Area *)l->data);
|
||||
if (child->size_mode == LAYOUT_DYNAMIC && child->children)
|
||||
child->resize_needed = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// update position of children
|
||||
// Layout children
|
||||
if (a->children) {
|
||||
if (a->alignment == ALIGN_LEFT) {
|
||||
int pos = (panel_horizontal ? a->posx : a->posy) + a->bg->border.width + a->paddingxlr;
|
||||
|
||||
for (l = a->children; l ; l = l->next) {
|
||||
Area *child = ((Area*)l->data);
|
||||
for (GList *l = a->children; l; l = l->next) {
|
||||
Area *child = ((Area *)l->data);
|
||||
if (!child->on_screen)
|
||||
continue;
|
||||
|
||||
@@ -132,15 +128,15 @@ void _relayout_dynamic(Area *a, int level)
|
||||
}
|
||||
}
|
||||
|
||||
_relayout_dynamic(child, level+1);
|
||||
relayout_dynamic(child, level + 1);
|
||||
|
||||
pos += panel_horizontal ? child->width + a->paddingx : child->height + a->paddingx;
|
||||
}
|
||||
} else if (a->alignment == ALIGN_RIGHT) {
|
||||
int pos = (panel_horizontal ? a->posx + a->width : a->posy + a->height) - a->bg->border.width - a->paddingxlr;
|
||||
|
||||
for (l = g_list_last(a->children); l ; l = l->prev) {
|
||||
Area *child = ((Area*)l->data);
|
||||
for (GList *l = g_list_last(a->children); l; l = l->prev) {
|
||||
Area *child = ((Area *)l->data);
|
||||
if (!child->on_screen)
|
||||
continue;
|
||||
|
||||
@@ -160,7 +156,7 @@ void _relayout_dynamic(Area *a, int level)
|
||||
}
|
||||
}
|
||||
|
||||
_relayout_dynamic(child, level+1);
|
||||
relayout_dynamic(child, level + 1);
|
||||
|
||||
pos -= a->paddingx;
|
||||
}
|
||||
@@ -168,8 +164,8 @@ void _relayout_dynamic(Area *a, int level)
|
||||
|
||||
int children_size = 0;
|
||||
|
||||
for (l = a->children; l ; l = l->next) {
|
||||
Area *child = ((Area*)l->data);
|
||||
for (GList *l = a->children; l; l = l->next) {
|
||||
Area *child = ((Area *)l->data);
|
||||
if (!child->on_screen)
|
||||
continue;
|
||||
|
||||
@@ -180,8 +176,8 @@ void _relayout_dynamic(Area *a, int level)
|
||||
int pos = (panel_horizontal ? a->posx : a->posy) + a->bg->border.width + a->paddingxlr;
|
||||
pos += ((panel_horizontal ? a->width : a->height) - children_size) / 2;
|
||||
|
||||
for (l = a->children; l ; l = l->next) {
|
||||
Area *child = ((Area*)l->data);
|
||||
for (GList *l = a->children; l; l = l->next) {
|
||||
Area *child = ((Area *)l->data);
|
||||
if (!child->on_screen)
|
||||
continue;
|
||||
|
||||
@@ -199,7 +195,7 @@ void _relayout_dynamic(Area *a, int level)
|
||||
}
|
||||
}
|
||||
|
||||
_relayout_dynamic(child, level+1);
|
||||
relayout_dynamic(child, level + 1);
|
||||
|
||||
pos += panel_horizontal ? child->width + a->paddingx : child->height + a->paddingx;
|
||||
}
|
||||
@@ -208,79 +204,71 @@ void _relayout_dynamic(Area *a, int level)
|
||||
|
||||
if (a->_changed) {
|
||||
// pos/size changed
|
||||
a->redraw_needed = 1;
|
||||
a->redraw_needed = TRUE;
|
||||
if (a->_on_change_layout)
|
||||
a->_on_change_layout (a);
|
||||
a->_on_change_layout(a);
|
||||
}
|
||||
}
|
||||
|
||||
void relayout(Area *a)
|
||||
{
|
||||
relayout_fixed(a);
|
||||
relayout_dynamic(a, 1);
|
||||
}
|
||||
|
||||
void draw_tree (Area *a)
|
||||
void draw_tree(Area *a)
|
||||
{
|
||||
if (!a->on_screen)
|
||||
return;
|
||||
|
||||
// don't draw transparent objects (without foreground and without background)
|
||||
if (a->redraw_needed) {
|
||||
a->redraw_needed = 0;
|
||||
// force redraw of child
|
||||
//GList *l;
|
||||
//for (l = a->children ; l ; l = l->next)
|
||||
//((Area*)l->data)->redraw_needed = 1;
|
||||
|
||||
//printf("draw area posx %d, width %d\n", a->posx, a->width);
|
||||
draw(a);
|
||||
}
|
||||
|
||||
// draw current Area
|
||||
if (a->pix == 0)
|
||||
printf("empty area posx %d, width %d\n", a->posx, a->width);
|
||||
XCopyArea(server.dsp, a->pix, ((Panel *)a->panel)->temp_pmap, server.gc, 0, 0, a->width, a->height, a->posx, a->posy);
|
||||
if (a->pix)
|
||||
XCopyArea(server.dsp, a->pix, ((Panel *)a->panel)->temp_pmap, server.gc, 0, 0, a->width, a->height, a->posx, a->posy);
|
||||
|
||||
// and then draw child objects
|
||||
GList *l;
|
||||
for (l = a->children; l ; l = l->next)
|
||||
draw_tree((Area*)l->data);
|
||||
for (GList *l = a->children; l; l = l->next)
|
||||
draw_tree((Area *)l->data);
|
||||
}
|
||||
|
||||
|
||||
int relayout_with_constraint(Area *a, int maximum_size)
|
||||
{
|
||||
Area *child;
|
||||
int size, nb_by_content=0, nb_by_layout=0;
|
||||
int fixed_children_count = 0;
|
||||
int dynamic_children_count = 0;
|
||||
|
||||
if (panel_horizontal) {
|
||||
// detect free size for LAYOUT_DYNAMIC's Area
|
||||
size = a->width - (2 * (a->paddingxlr + a->bg->border.width));
|
||||
GList *l;
|
||||
for (l = a->children ; l ; l = l->next) {
|
||||
child = (Area*)l->data;
|
||||
if (panel_horizontal) {
|
||||
// detect free size for LAYOUT_DYNAMIC Areas
|
||||
int size = a->width - (2 * (a->paddingxlr + a->bg->border.width));
|
||||
for (GList *l = a->children; l; l = l->next) {
|
||||
Area *child = (Area *)l->data;
|
||||
if (child->on_screen && child->size_mode == LAYOUT_FIXED) {
|
||||
size -= child->width;
|
||||
nb_by_content++;
|
||||
fixed_children_count++;
|
||||
}
|
||||
if (child->on_screen && child->size_mode == LAYOUT_DYNAMIC)
|
||||
nb_by_layout++;
|
||||
dynamic_children_count++;
|
||||
}
|
||||
//printf(" resize_by_layout Deb %d, %d\n", nb_by_content, nb_by_layout);
|
||||
if (nb_by_content+nb_by_layout)
|
||||
size -= ((nb_by_content+nb_by_layout-1) * a->paddingx);
|
||||
if (fixed_children_count + dynamic_children_count > 0)
|
||||
size -= (fixed_children_count + dynamic_children_count - 1) * a->paddingx;
|
||||
|
||||
int width=0, modulo=0, old_width;
|
||||
if (nb_by_layout) {
|
||||
width = size / nb_by_layout;
|
||||
modulo = size % nb_by_layout;
|
||||
if (width > maximum_size && maximum_size != 0) {
|
||||
int width = 0;
|
||||
int modulo = 0;
|
||||
if (dynamic_children_count > 0) {
|
||||
width = size / dynamic_children_count;
|
||||
modulo = size % dynamic_children_count;
|
||||
if (width > maximum_size && maximum_size > 0) {
|
||||
width = maximum_size;
|
||||
modulo = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// resize LAYOUT_DYNAMIC objects
|
||||
for (l = a->children ; l ; l = l->next) {
|
||||
child = (Area*)l->data;
|
||||
// Resize LAYOUT_DYNAMIC objects
|
||||
for (GList *l = a->children; l; l = l->next) {
|
||||
Area *child = (Area *)l->data;
|
||||
if (child->on_screen && child->size_mode == LAYOUT_DYNAMIC) {
|
||||
old_width = child->width;
|
||||
int old_width = child->width;
|
||||
child->width = width;
|
||||
if (modulo) {
|
||||
child->width++;
|
||||
@@ -290,36 +278,35 @@ int relayout_with_constraint(Area *a, int maximum_size)
|
||||
child->_changed = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// detect free size for LAYOUT_DYNAMIC's Area
|
||||
size = a->height - (2 * (a->paddingxlr + a->bg->border.width));
|
||||
GList *l;
|
||||
for (l = a->children ; l ; l = l->next) {
|
||||
child = (Area*)l->data;
|
||||
int size = a->height - (2 * (a->paddingxlr + a->bg->border.width));
|
||||
for (GList *l = a->children; l; l = l->next) {
|
||||
Area *child = (Area *)l->data;
|
||||
if (child->on_screen && child->size_mode == LAYOUT_FIXED) {
|
||||
size -= child->height;
|
||||
nb_by_content++;
|
||||
fixed_children_count++;
|
||||
}
|
||||
if (child->on_screen && child->size_mode == LAYOUT_DYNAMIC)
|
||||
nb_by_layout++;
|
||||
dynamic_children_count++;
|
||||
}
|
||||
if (nb_by_content+nb_by_layout)
|
||||
size -= ((nb_by_content+nb_by_layout-1) * a->paddingx);
|
||||
if (fixed_children_count + dynamic_children_count > 0)
|
||||
size -= (fixed_children_count + dynamic_children_count - 1) * a->paddingx;
|
||||
|
||||
int height=0, modulo=0;
|
||||
if (nb_by_layout) {
|
||||
height = size / nb_by_layout;
|
||||
modulo = size % nb_by_layout;
|
||||
int height = 0;
|
||||
int modulo = 0;
|
||||
if (dynamic_children_count) {
|
||||
height = size / dynamic_children_count;
|
||||
modulo = size % dynamic_children_count;
|
||||
if (height > maximum_size && maximum_size != 0) {
|
||||
height = maximum_size;
|
||||
modulo = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// resize LAYOUT_DYNAMIC objects
|
||||
for (l = a->children ; l ; l = l->next) {
|
||||
child = (Area*)l->data;
|
||||
// Resize LAYOUT_DYNAMIC objects
|
||||
for (GList *l = a->children; l; l = l->next) {
|
||||
Area *child = (Area *)l->data;
|
||||
if (child->on_screen && child->size_mode == LAYOUT_DYNAMIC) {
|
||||
int old_height = child->height;
|
||||
child->height = height;
|
||||
@@ -335,21 +322,19 @@ int relayout_with_constraint(Area *a, int maximum_size)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void schedule_redraw(Area *a)
|
||||
{
|
||||
a->redraw_needed = 1;
|
||||
a->redraw_needed = TRUE;
|
||||
|
||||
GList *l;
|
||||
for (l = a->children ; l ; l = l->next)
|
||||
schedule_redraw((Area*)l->data);
|
||||
for (GList *l = a->children; l; l = l->next)
|
||||
schedule_redraw((Area *)l->data);
|
||||
}
|
||||
|
||||
void hide(Area *a)
|
||||
{
|
||||
Area *parent = (Area*)a->parent;
|
||||
Area *parent = (Area *)a->parent;
|
||||
|
||||
a->on_screen = 0;
|
||||
a->on_screen = FALSE;
|
||||
if (parent)
|
||||
parent->resize_needed = 1;
|
||||
if (panel_horizontal)
|
||||
@@ -360,9 +345,9 @@ void hide(Area *a)
|
||||
|
||||
void show(Area *a)
|
||||
{
|
||||
Area *parent = (Area*)a->parent;
|
||||
Area *parent = (Area *)a->parent;
|
||||
|
||||
a->on_screen = 1;
|
||||
a->on_screen = TRUE;
|
||||
if (parent)
|
||||
parent->resize_needed = 1;
|
||||
a->resize_needed = 1;
|
||||
@@ -374,16 +359,13 @@ void draw(Area *a)
|
||||
XFreePixmap(server.dsp, a->pix);
|
||||
a->pix = XCreatePixmap(server.dsp, server.root_win, a->width, a->height, server.depth);
|
||||
|
||||
// add layer of root pixmap (or clear pixmap if real_transparency==true)
|
||||
// Add layer of root pixmap (or clear pixmap if real_transparency==true)
|
||||
if (server.real_transparency)
|
||||
clear_pixmap(a->pix, 0 ,0, a->width, a->height);
|
||||
clear_pixmap(a->pix, 0, 0, a->width, a->height);
|
||||
XCopyArea(server.dsp, ((Panel *)a->panel)->temp_pmap, a->pix, server.gc, a->posx, a->posy, a->width, a->height, 0, 0);
|
||||
|
||||
cairo_surface_t *cs;
|
||||
cairo_t *c;
|
||||
|
||||
cs = cairo_xlib_surface_create (server.dsp, a->pix, server.visual, a->width, a->height);
|
||||
c = cairo_create (cs);
|
||||
cairo_surface_t *cs = cairo_xlib_surface_create(server.dsp, a->pix, server.visual, a->width, a->height);
|
||||
cairo_t *c = cairo_create(cs);
|
||||
|
||||
draw_background(a, c);
|
||||
|
||||
@@ -394,43 +376,74 @@ void draw(Area *a)
|
||||
cairo_surface_destroy(cs);
|
||||
}
|
||||
|
||||
|
||||
void draw_background (Area *a, cairo_t *c)
|
||||
void draw_background(Area *a, cairo_t *c)
|
||||
{
|
||||
if (a->bg->fill_color.alpha > 0.0 ||
|
||||
(panel_config.mouse_effects && (a->has_mouse_over_effect || a->has_mouse_press_effect))) {
|
||||
//printf(" draw_background (%d %d) RGBA (%lf, %lf, %lf, %lf)\n", a->posx, a->posy, pix->fill_color.rgb[0], pix->fill_color.rgb[1], pix->fill_color.rgb[2], pix->fill_color.alpha);
|
||||
if (a->mouse_state == MOUSE_OVER)
|
||||
cairo_set_source_rgba(c, a->bg->fill_color_hover.rgb[0], a->bg->fill_color_hover.rgb[1], a->bg->fill_color_hover.rgb[2], a->bg->fill_color_hover.alpha);
|
||||
cairo_set_source_rgba(c,
|
||||
a->bg->fill_color_hover.rgb[0],
|
||||
a->bg->fill_color_hover.rgb[1],
|
||||
a->bg->fill_color_hover.rgb[2],
|
||||
a->bg->fill_color_hover.alpha);
|
||||
else if (a->mouse_state == MOUSE_DOWN)
|
||||
cairo_set_source_rgba(c, a->bg->fill_color_pressed.rgb[0], a->bg->fill_color_pressed.rgb[1], a->bg->fill_color_pressed.rgb[2], a->bg->fill_color_pressed.alpha);
|
||||
cairo_set_source_rgba(c,
|
||||
a->bg->fill_color_pressed.rgb[0],
|
||||
a->bg->fill_color_pressed.rgb[1],
|
||||
a->bg->fill_color_pressed.rgb[2],
|
||||
a->bg->fill_color_pressed.alpha);
|
||||
else
|
||||
cairo_set_source_rgba(c, a->bg->fill_color.rgb[0], a->bg->fill_color.rgb[1], a->bg->fill_color.rgb[2], a->bg->fill_color.alpha);
|
||||
draw_rect(c, a->bg->border.width, a->bg->border.width, a->width-(2.0 * a->bg->border.width), a->height-(2.0*a->bg->border.width), a->bg->border.radius - a->bg->border.width/1.571);
|
||||
cairo_set_source_rgba(c,
|
||||
a->bg->fill_color.rgb[0],
|
||||
a->bg->fill_color.rgb[1],
|
||||
a->bg->fill_color.rgb[2],
|
||||
a->bg->fill_color.alpha);
|
||||
draw_rect(c,
|
||||
a->bg->border.width,
|
||||
a->bg->border.width,
|
||||
a->width - (2.0 * a->bg->border.width),
|
||||
a->height - (2.0 * a->bg->border.width),
|
||||
a->bg->border.radius - a->bg->border.width / 1.571);
|
||||
cairo_fill(c);
|
||||
}
|
||||
|
||||
if (a->bg->border.width > 0) {
|
||||
cairo_set_line_width (c, a->bg->border.width);
|
||||
cairo_set_line_width(c, a->bg->border.width);
|
||||
|
||||
// draw border inside (x, y, width, height)
|
||||
if (a->mouse_state == MOUSE_OVER)
|
||||
cairo_set_source_rgba(c, a->bg->border_color_hover.rgb[0], a->bg->border_color_hover.rgb[1], a->bg->border_color_hover.rgb[2], a->bg->border_color_hover.alpha);
|
||||
cairo_set_source_rgba(c,
|
||||
a->bg->border_color_hover.rgb[0],
|
||||
a->bg->border_color_hover.rgb[1],
|
||||
a->bg->border_color_hover.rgb[2],
|
||||
a->bg->border_color_hover.alpha);
|
||||
else if (a->mouse_state == MOUSE_DOWN)
|
||||
cairo_set_source_rgba(c, a->bg->border_color_pressed.rgb[0], a->bg->border_color_pressed.rgb[1], a->bg->border_color_pressed.rgb[2], a->bg->border_color_pressed.alpha);
|
||||
cairo_set_source_rgba(c,
|
||||
a->bg->border_color_pressed.rgb[0],
|
||||
a->bg->border_color_pressed.rgb[1],
|
||||
a->bg->border_color_pressed.rgb[2],
|
||||
a->bg->border_color_pressed.alpha);
|
||||
else
|
||||
cairo_set_source_rgba(c, a->bg->border.color.rgb[0], a->bg->border.color.rgb[1], a->bg->border.color.rgb[2], a->bg->border.color.alpha);
|
||||
draw_rect(c, a->bg->border.width/2.0, a->bg->border.width/2.0, a->width - a->bg->border.width, a->height - a->bg->border.width, a->bg->border.radius);
|
||||
cairo_set_source_rgba(c,
|
||||
a->bg->border.color.rgb[0],
|
||||
a->bg->border.color.rgb[1],
|
||||
a->bg->border.color.rgb[2],
|
||||
a->bg->border.color.alpha);
|
||||
draw_rect(c,
|
||||
a->bg->border.width / 2.0,
|
||||
a->bg->border.width / 2.0,
|
||||
a->width - a->bg->border.width,
|
||||
a->height - a->bg->border.width,
|
||||
a->bg->border.radius);
|
||||
|
||||
cairo_stroke(c);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void remove_area(Area *a)
|
||||
{
|
||||
Area *area = (Area*)a;
|
||||
Area *parent = (Area*)area->parent;
|
||||
Area *area = (Area *)a;
|
||||
Area *parent = (Area *)area->parent;
|
||||
|
||||
if (parent) {
|
||||
parent->children = g_list_remove(parent->children, area);
|
||||
@@ -443,7 +456,6 @@ void remove_area(Area *a)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void add_area(Area *a, Area *parent)
|
||||
{
|
||||
g_assert_null(a->parent);
|
||||
@@ -455,22 +467,20 @@ void add_area(Area *a, Area *parent)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void free_area (Area *a)
|
||||
void free_area(Area *a)
|
||||
{
|
||||
if (!a)
|
||||
return;
|
||||
|
||||
GList *l0;
|
||||
for (l0 = a->children; l0 ; l0 = l0->next)
|
||||
free_area (l0->data);
|
||||
for (GList *l = a->children; l; l = l->next)
|
||||
free_area(l->data);
|
||||
|
||||
if (a->children) {
|
||||
g_list_free(a->children);
|
||||
a->children = 0;
|
||||
}
|
||||
if (a->pix) {
|
||||
XFreePixmap (server.dsp, a->pix);
|
||||
XFreePixmap(server.dsp, a->pix);
|
||||
a->pix = 0;
|
||||
}
|
||||
if (mouse_over_area == a) {
|
||||
@@ -478,7 +488,6 @@ void free_area (Area *a)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void mouse_over(Area *area, int pressed)
|
||||
{
|
||||
if (mouse_over_area == area && !area)
|
||||
@@ -506,7 +515,7 @@ void mouse_over(Area *area, int pressed)
|
||||
|
||||
mouse_over_area->mouse_state = new_state;
|
||||
schedule_redraw(mouse_over_area);
|
||||
panel_refresh = 1;
|
||||
panel_refresh = TRUE;
|
||||
}
|
||||
|
||||
void mouse_out()
|
||||
@@ -515,17 +524,6 @@ void mouse_out()
|
||||
return;
|
||||
mouse_over_area->mouse_state = MOUSE_NORMAL;
|
||||
schedule_redraw(mouse_over_area);
|
||||
panel_refresh = 1;
|
||||
panel_refresh = TRUE;
|
||||
mouse_over_area = NULL;
|
||||
}
|
||||
|
||||
void init_background(Background *bg)
|
||||
{
|
||||
memset(bg, 0, sizeof(Background));
|
||||
}
|
||||
|
||||
void relayout(Area *a)
|
||||
{
|
||||
_relayout_fixed(a);
|
||||
_relayout_dynamic(a, 1);
|
||||
}
|
||||
|
||||
@@ -147,21 +147,23 @@ typedef struct Background {
|
||||
|
||||
typedef enum Layout {
|
||||
LAYOUT_DYNAMIC,
|
||||
LAYOUT_FIXED
|
||||
LAYOUT_FIXED,
|
||||
} Layout;
|
||||
|
||||
typedef enum Alignment {
|
||||
ALIGN_LEFT = 0,
|
||||
ALIGN_CENTER = 1,
|
||||
ALIGN_RIGHT = 2
|
||||
ALIGN_RIGHT = 2,
|
||||
} Alignment;
|
||||
|
||||
typedef enum MouseState {
|
||||
MOUSE_NORMAL = 0,
|
||||
MOUSE_OVER = 1,
|
||||
MOUSE_DOWN = 2
|
||||
MOUSE_DOWN = 2,
|
||||
} MouseState;
|
||||
|
||||
struct Panel;
|
||||
|
||||
typedef struct Area {
|
||||
// Position relative to the panel window
|
||||
int posx, posy;
|
||||
@@ -202,7 +204,7 @@ typedef struct Area {
|
||||
|
||||
// Called on resize, obj = pointer to the Area
|
||||
// Returns 1 if the new size is different than the previous size.
|
||||
int (*_resize)(void *obj);
|
||||
gboolean (*_resize)(void *obj);
|
||||
|
||||
// Implemented only to override the default layout algorithm for this widget.
|
||||
// For example, if this widget is a cell in a table, its position and size should be computed here.
|
||||
@@ -210,10 +212,9 @@ typedef struct Area {
|
||||
|
||||
// Returns a copy of the tooltip to be displayed for this widget.
|
||||
// The caller takes ownership of the pointer.
|
||||
char* (*_get_tooltip_text)(void *obj);
|
||||
char *(*_get_tooltip_text)(void *obj);
|
||||
} Area;
|
||||
|
||||
|
||||
// Initializes the Background member to default values.
|
||||
void init_background(Background *bg);
|
||||
|
||||
@@ -222,10 +223,12 @@ void init_background(Background *bg);
|
||||
// Called on startup to initialize the positions of all Areas in the Area tree.
|
||||
// Parameters:
|
||||
// * obj: pointer to Area
|
||||
// * pos: offset in pixels from left/top
|
||||
void initialize_positions(void *obj, int pos);
|
||||
// * offset: offset in pixels from left/top, relative to the window
|
||||
void initialize_positions(void *obj, int offset);
|
||||
|
||||
// Relayouts the Area and its children. Normally called on the root of the tree (i.e. the Panel).
|
||||
void relayout(Area *a);
|
||||
|
||||
// Distributes the Area's size to its children, repositioning them as needed.
|
||||
// If maximum_size > 0, it is an upper limit for the child size.
|
||||
int relayout_with_constraint(Area *a, int maximum_size);
|
||||
@@ -234,15 +237,20 @@ int relayout_with_constraint(Area *a, int maximum_size);
|
||||
|
||||
// Sets the redraw_needed flag on the area and its descendants
|
||||
void schedule_redraw(Area *a);
|
||||
|
||||
// Recreates the Area pixmap and draws the background and the foreground
|
||||
void draw(Area *a);
|
||||
|
||||
// Draws the background of the Area
|
||||
void draw_background(Area *a, cairo_t *c);
|
||||
|
||||
// Explores the entire Area subtree (only if the on_screen flag set)
|
||||
// and draws the areas with the redraw_needed flag set
|
||||
void draw_tree(Area *a);
|
||||
|
||||
// Clears the on_screen flag, sets the size to zero and triggers a parent resize
|
||||
void hide(Area *a);
|
||||
|
||||
// Sets the on_screen flag and triggers a parent and area resize
|
||||
void show(Area *a);
|
||||
|
||||
|
||||
@@ -37,67 +37,69 @@
|
||||
#include <librsvg/rsvg.h>
|
||||
#endif
|
||||
|
||||
|
||||
void copy_file(const char *pathSrc, const char *pathDest)
|
||||
void copy_file(const char *path_src, const char *path_dest)
|
||||
{
|
||||
if (g_str_equal(pathSrc, pathDest))
|
||||
if (g_str_equal(path_src, path_dest))
|
||||
return;
|
||||
|
||||
FILE *fileSrc, *fileDest;
|
||||
char buffer[100];
|
||||
int nb;
|
||||
FILE *file_src, *file_dest;
|
||||
char buffer[4096];
|
||||
int nb;
|
||||
|
||||
fileSrc = fopen(pathSrc, "rb");
|
||||
if (fileSrc == NULL) return;
|
||||
file_src = fopen(path_src, "rb");
|
||||
if (file_src == NULL)
|
||||
return;
|
||||
|
||||
fileDest = fopen(pathDest, "wb");
|
||||
if (fileDest == NULL) return;
|
||||
file_dest = fopen(path_dest, "wb");
|
||||
if (file_dest == NULL) {
|
||||
fclose(file_src);
|
||||
return;
|
||||
}
|
||||
|
||||
while ((nb = fread(buffer, 1, sizeof(buffer), fileSrc)) > 0) {
|
||||
if ( nb != fwrite(buffer, 1, nb, fileDest)) {
|
||||
printf("Error while copying file %s to %s\n", pathSrc, pathDest);
|
||||
while ((nb = fread(buffer, 1, sizeof(buffer), file_src)) > 0) {
|
||||
if (nb != fwrite(buffer, 1, nb, file_dest)) {
|
||||
printf("Error while copying file %s to %s\n", path_src, path_dest);
|
||||
}
|
||||
}
|
||||
|
||||
fclose (fileDest);
|
||||
fclose (fileSrc);
|
||||
fclose(file_dest);
|
||||
fclose(file_src);
|
||||
}
|
||||
|
||||
|
||||
int parse_line (const char *line, char **key, char **value)
|
||||
int parse_line(const char *line, char **key, char **value)
|
||||
{
|
||||
char *a, *b;
|
||||
|
||||
/* Skip useless lines */
|
||||
if ((line[0] == '#') || (line[0] == '\n')) return 0;
|
||||
if (!(a = strchr (line, '='))) return 0;
|
||||
if ((line[0] == '#') || (line[0] == '\n'))
|
||||
return 0;
|
||||
if (!(a = strchr(line, '=')))
|
||||
return 0;
|
||||
|
||||
/* overwrite '=' with '\0' */
|
||||
a[0] = '\0';
|
||||
*key = strdup (line);
|
||||
*key = strdup(line);
|
||||
a++;
|
||||
|
||||
/* overwrite '\n' with '\0' if '\n' present */
|
||||
if ((b = strchr (a, '\n'))) b[0] = '\0';
|
||||
if ((b = strchr(a, '\n')))
|
||||
b[0] = '\0';
|
||||
|
||||
*value = strdup (a);
|
||||
*value = strdup(a);
|
||||
|
||||
g_strstrip(*key);
|
||||
g_strstrip(*value);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
void tint_exec(const char *command)
|
||||
{
|
||||
if (command) {
|
||||
pid_t pid;
|
||||
pid = fork();
|
||||
if (pid == 0) {
|
||||
if (fork() == 0) {
|
||||
// change for the fork the signal mask
|
||||
// sigset_t sigset;
|
||||
// sigprocmask(SIG_SETMASK, &sigset, 0);
|
||||
// sigprocmask(SIG_UNBLOCK, &sigset, 0);
|
||||
// sigset_t sigset;
|
||||
// sigprocmask(SIG_SETMASK, &sigset, 0);
|
||||
// sigprocmask(SIG_UNBLOCK, &sigset, 0);
|
||||
execl("/bin/sh", "/bin/sh", "-c", command, NULL);
|
||||
_exit(0);
|
||||
}
|
||||
@@ -107,9 +109,7 @@ void tint_exec(const char *command)
|
||||
char *expand_tilde(char *s)
|
||||
{
|
||||
const gchar *home = g_get_home_dir();
|
||||
if (home &&
|
||||
(strcmp(s, "~") == 0 ||
|
||||
strstr(s, "~/") == s)) {
|
||||
if (home && (strcmp(s, "~") == 0 || strstr(s, "~/") == s)) {
|
||||
char *result = calloc(strlen(home) + strlen(s), 1);
|
||||
strcat(result, home);
|
||||
strcat(result, s + 1);
|
||||
@@ -129,8 +129,7 @@ char *contract_tilde(char *s)
|
||||
strcat(home_slash, home);
|
||||
strcat(home_slash, "/");
|
||||
|
||||
if ((strcmp(s, home) == 0 ||
|
||||
strstr(s, home_slash) == s)) {
|
||||
if ((strcmp(s, home) == 0 || strstr(s, home_slash) == s)) {
|
||||
char *result = calloc(strlen(s) - strlen(home) + 2, 1);
|
||||
strcat(result, "~");
|
||||
strcat(result, s + strlen(home));
|
||||
@@ -142,98 +141,96 @@ char *contract_tilde(char *s)
|
||||
}
|
||||
}
|
||||
|
||||
int hex_char_to_int (char c)
|
||||
int hex_char_to_int(char c)
|
||||
{
|
||||
int r;
|
||||
|
||||
if (c >= '0' && c <= '9') r = c - '0';
|
||||
else if (c >= 'a' && c <= 'f') r = c - 'a' + 10;
|
||||
else if (c >= 'A' && c <= 'F') r = c - 'A' + 10;
|
||||
else r = 0;
|
||||
if (c >= '0' && c <= '9')
|
||||
r = c - '0';
|
||||
else if (c >= 'a' && c <= 'f')
|
||||
r = c - 'a' + 10;
|
||||
else if (c >= 'A' && c <= 'F')
|
||||
r = c - 'A' + 10;
|
||||
else
|
||||
r = 0;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
int hex_to_rgb (char *hex, int *r, int *g, int *b)
|
||||
int hex_to_rgb(char *hex, int *r, int *g, int *b)
|
||||
{
|
||||
int len;
|
||||
if (hex == NULL || hex[0] != '#')
|
||||
return (0);
|
||||
|
||||
if (hex == NULL || hex[0] != '#') return (0);
|
||||
|
||||
len = strlen (hex);
|
||||
int len = strlen(hex);
|
||||
if (len == 3 + 1) {
|
||||
*r = hex_char_to_int (hex[1]);
|
||||
*g = hex_char_to_int (hex[2]);
|
||||
*b = hex_char_to_int (hex[3]);
|
||||
}
|
||||
else if (len == 6 + 1) {
|
||||
*r = hex_char_to_int (hex[1]) * 16 + hex_char_to_int (hex[2]);
|
||||
*g = hex_char_to_int (hex[3]) * 16 + hex_char_to_int (hex[4]);
|
||||
*b = hex_char_to_int (hex[5]) * 16 + hex_char_to_int (hex[6]);
|
||||
}
|
||||
else if (len == 12 + 1) {
|
||||
*r = hex_char_to_int (hex[1]) * 16 + hex_char_to_int (hex[2]);
|
||||
*g = hex_char_to_int (hex[5]) * 16 + hex_char_to_int (hex[6]);
|
||||
*b = hex_char_to_int (hex[9]) * 16 + hex_char_to_int (hex[10]);
|
||||
}
|
||||
else return 0;
|
||||
*r = hex_char_to_int(hex[1]);
|
||||
*g = hex_char_to_int(hex[2]);
|
||||
*b = hex_char_to_int(hex[3]);
|
||||
} else if (len == 6 + 1) {
|
||||
*r = hex_char_to_int(hex[1]) * 16 + hex_char_to_int(hex[2]);
|
||||
*g = hex_char_to_int(hex[3]) * 16 + hex_char_to_int(hex[4]);
|
||||
*b = hex_char_to_int(hex[5]) * 16 + hex_char_to_int(hex[6]);
|
||||
} else if (len == 12 + 1) {
|
||||
*r = hex_char_to_int(hex[1]) * 16 + hex_char_to_int(hex[2]);
|
||||
*g = hex_char_to_int(hex[5]) * 16 + hex_char_to_int(hex[6]);
|
||||
*b = hex_char_to_int(hex[9]) * 16 + hex_char_to_int(hex[10]);
|
||||
} else
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
void get_color (char *hex, double *rgb)
|
||||
void get_color(char *hex, double *rgb)
|
||||
{
|
||||
int r, g, b;
|
||||
r = g = b = 0;
|
||||
hex_to_rgb (hex, &r, &g, &b);
|
||||
hex_to_rgb(hex, &r, &g, &b);
|
||||
|
||||
rgb[0] = (r / 255.0);
|
||||
rgb[1] = (g / 255.0);
|
||||
rgb[2] = (b / 255.0);
|
||||
}
|
||||
|
||||
|
||||
void extract_values (const char *value, char **value1, char **value2, char **value3)
|
||||
void extract_values(const char *value, char **value1, char **value2, char **value3)
|
||||
{
|
||||
char *b=0, *c=0;
|
||||
char *b = 0, *c = 0;
|
||||
|
||||
if (*value1) free (*value1);
|
||||
if (*value2) free (*value2);
|
||||
if (*value3) free (*value3);
|
||||
if (*value1)
|
||||
free(*value1);
|
||||
if (*value2)
|
||||
free(*value2);
|
||||
if (*value3)
|
||||
free(*value3);
|
||||
|
||||
if ((b = strchr (value, ' '))) {
|
||||
if ((b = strchr(value, ' '))) {
|
||||
b[0] = '\0';
|
||||
b++;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
*value2 = 0;
|
||||
*value3 = 0;
|
||||
}
|
||||
*value1 = strdup (value);
|
||||
*value1 = strdup(value);
|
||||
g_strstrip(*value1);
|
||||
|
||||
if (b) {
|
||||
if ((c = strchr (b, ' '))) {
|
||||
if ((c = strchr(b, ' '))) {
|
||||
c[0] = '\0';
|
||||
c++;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
c = 0;
|
||||
*value3 = 0;
|
||||
}
|
||||
*value2 = strdup (b);
|
||||
*value2 = strdup(b);
|
||||
g_strstrip(*value2);
|
||||
}
|
||||
|
||||
if (c) {
|
||||
*value3 = strdup (c);
|
||||
*value3 = strdup(c);
|
||||
g_strstrip(*value3);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void adjust_asb(DATA32 *data, int w, int h, int alpha, float satur, float bright)
|
||||
{
|
||||
unsigned int x, y;
|
||||
@@ -244,21 +241,24 @@ void adjust_asb(DATA32 *data, int w, int h, int alpha, float satur, float bright
|
||||
float hue, saturation, brightness;
|
||||
float redc, greenc, bluec;
|
||||
|
||||
for(y = 0; y < h; y++) {
|
||||
for(id = y * w, x = 0; x < w; x++, id++) {
|
||||
for (y = 0; y < h; y++) {
|
||||
for (id = y * w, x = 0; x < w; x++, id++) {
|
||||
argb = data[id];
|
||||
a = (argb >> 24) & 0xff;
|
||||
// transparent => nothing to do.
|
||||
if (a == 0) continue;
|
||||
if (a == 0)
|
||||
continue;
|
||||
r = (argb >> 16) & 0xff;
|
||||
g = (argb >> 8) & 0xff;
|
||||
b = (argb) & 0xff;
|
||||
b = (argb)&0xff;
|
||||
|
||||
// convert RGB to HSB
|
||||
cmax = (r > g) ? r : g;
|
||||
if (b > cmax) cmax = b;
|
||||
if (b > cmax)
|
||||
cmax = b;
|
||||
cmin = (r < g) ? r : g;
|
||||
if (b < cmin) cmin = b;
|
||||
if (b < cmin)
|
||||
cmin = b;
|
||||
brightness = ((float)cmax) / 255.0f;
|
||||
if (cmax != 0)
|
||||
saturation = ((float)(cmax - cmin)) / ((float)cmax);
|
||||
@@ -283,13 +283,17 @@ void adjust_asb(DATA32 *data, int w, int h, int alpha, float satur, float bright
|
||||
|
||||
// adjust
|
||||
saturation += satur;
|
||||
if (saturation < 0.0) saturation = 0.0;
|
||||
if (saturation > 1.0) saturation = 1.0;
|
||||
if (saturation < 0.0)
|
||||
saturation = 0.0;
|
||||
if (saturation > 1.0)
|
||||
saturation = 1.0;
|
||||
brightness += bright;
|
||||
if (brightness < 0.0) brightness = 0.0;
|
||||
if (brightness > 1.0) brightness = 1.0;
|
||||
if (brightness < 0.0)
|
||||
brightness = 0.0;
|
||||
if (brightness > 1.0)
|
||||
brightness = 1.0;
|
||||
if (alpha != 100)
|
||||
a = (a * alpha)/100;
|
||||
a = (a * alpha) / 100;
|
||||
|
||||
// convert HSB to RGB
|
||||
if (saturation == 0) {
|
||||
@@ -300,7 +304,7 @@ void adjust_asb(DATA32 *data, int w, int h, int alpha, float satur, float bright
|
||||
p = brightness * (1.0f - saturation);
|
||||
q = brightness * (1.0f - saturation * f);
|
||||
t = brightness * (1.0f - (saturation * (1.0f - f)));
|
||||
switch ((int) h2) {
|
||||
switch ((int)h2) {
|
||||
case 0:
|
||||
r = (int)(brightness * 255.0f + 0.5f);
|
||||
g = (int)(t * 255.0f + 0.5f);
|
||||
@@ -343,34 +347,33 @@ void adjust_asb(DATA32 *data, int w, int h, int alpha, float satur, float bright
|
||||
}
|
||||
}
|
||||
|
||||
void createHeuristicMask(DATA32* data, int w, int h)
|
||||
void create_heuristic_mask(DATA32 *data, int w, int h)
|
||||
{
|
||||
// first we need to find the mask color, therefore we check all 4 edge pixel and take the color which
|
||||
// appears most often (we only need to check three edges, the 4th is implicitly clear)
|
||||
unsigned int topLeft = data[0], topRight = data[w-1], bottomLeft = data[w*h-w], bottomRight = data[w*h-1];
|
||||
unsigned int topLeft = data[0], topRight = data[w - 1], bottomLeft = data[w * h - w], bottomRight = data[w * h - 1];
|
||||
int max = (topLeft == topRight) + (topLeft == bottomLeft) + (topLeft == bottomRight);
|
||||
int maskPos = 0;
|
||||
if ( max < (topRight == topLeft) + (topRight == bottomLeft) + (topRight == bottomRight) ) {
|
||||
if (max < (topRight == topLeft) + (topRight == bottomLeft) + (topRight == bottomRight)) {
|
||||
max = (topRight == topLeft) + (topRight == bottomLeft) + (topRight == bottomRight);
|
||||
maskPos = w-1;
|
||||
maskPos = w - 1;
|
||||
}
|
||||
if ( max < (bottomLeft == topRight) + (bottomLeft == topLeft) + (bottomLeft == bottomRight) )
|
||||
maskPos = w*h-w;
|
||||
if (max < (bottomLeft == topRight) + (bottomLeft == topLeft) + (bottomLeft == bottomRight))
|
||||
maskPos = w * h - w;
|
||||
|
||||
// now mask out every pixel which has the same color as the edge pixels
|
||||
unsigned char* udata = (unsigned char*)data;
|
||||
unsigned char b = udata[4*maskPos];
|
||||
unsigned char g = udata[4*maskPos+1];
|
||||
unsigned char r = udata[4*maskPos+1];
|
||||
int i;
|
||||
for (i=0; i<h*w; ++i) {
|
||||
if ( b-udata[0] == 0 && g-udata[1] == 0 && r-udata[2] == 0 )
|
||||
unsigned char *udata = (unsigned char *)data;
|
||||
unsigned char b = udata[4 * maskPos];
|
||||
unsigned char g = udata[4 * maskPos + 1];
|
||||
unsigned char r = udata[4 * maskPos + 1];
|
||||
for (int i = 0; i < h * w; ++i) {
|
||||
if (b - udata[0] == 0 && g - udata[1] == 0 && r - udata[2] == 0)
|
||||
udata[3] = 0;
|
||||
udata += 4;
|
||||
}
|
||||
}
|
||||
|
||||
int pixelEmpty(DATA32 argb)
|
||||
int pixel_empty(DATA32 argb)
|
||||
{
|
||||
|
||||
DATA32 a = (argb >> 24) & 0xff;
|
||||
@@ -381,29 +384,27 @@ int pixelEmpty(DATA32 argb)
|
||||
return rgb == 0;
|
||||
}
|
||||
|
||||
int imageEmpty(DATA32* data, int w, int h)
|
||||
int image_empty(DATA32 *data, int w, int h)
|
||||
{
|
||||
unsigned int x, y;
|
||||
|
||||
if (w > 0 && h > 0) {
|
||||
x = w / 2;
|
||||
y = h / 2;
|
||||
if (!pixelEmpty(data[y * w + x])) {
|
||||
//fprintf(stderr, "Non-empty pixel: [%u, %u] = %x\n", x, y, data[y * w + x]);
|
||||
int x = w / 2;
|
||||
int y = h / 2;
|
||||
if (!pixel_empty(data[y * w + x])) {
|
||||
// fprintf(stderr, "Non-empty pixel: [%u, %u] = %x\n", x, y, data[y * w + x]);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
for (y = 0; y < h; y++) {
|
||||
for (x = 0; x < w; x++) {
|
||||
if (!pixelEmpty(data[y * w + x])) {
|
||||
//fprintf(stderr, "Non-empty pixel: [%u, %u] = %x\n", x, y, data[y * w + x]);
|
||||
for (int y = 0; y < h; y++) {
|
||||
for (int x = 0; x < w; x++) {
|
||||
if (!pixel_empty(data[y * w + x])) {
|
||||
// fprintf(stderr, "Non-empty pixel: [%u, %u] = %x\n", x, y, data[y * w + x]);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//fprintf(stderr, "All pixels are empty\n");
|
||||
// fprintf(stderr, "All pixels are empty\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -430,7 +431,7 @@ void render_image(Drawable d, int x, int y)
|
||||
|
||||
Picture pict = XRenderCreatePicture(server.dsp, pixmap, XRenderFindStandardFormat(server.dsp, PictStandardARGB32), 0, 0);
|
||||
Picture pict_drawable = XRenderCreatePicture(server.dsp, d, XRenderFindVisualFormat(server.dsp, server.visual), 0, 0);
|
||||
Picture pict_mask = XRenderCreatePicture(server.dsp, mask, XRenderFindStandardFormat(server.dsp, PictStandardARGB32), 0, 0);
|
||||
Picture pict_mask = XRenderCreatePicture(server.dsp, mask, XRenderFindStandardFormat(server.dsp, PictStandardARGB32), 0, 0);
|
||||
XRenderComposite(server.dsp, PictOpOver, pict, pict_mask, pict_drawable, 0, 0, 0, 0, x, y, w, h);
|
||||
|
||||
XRenderFreePicture(server.dsp, pict_mask);
|
||||
@@ -448,17 +449,23 @@ void draw_text(PangoLayout *layout, cairo_t *c, int posx, int posy, Color *color
|
||||
int i, j;
|
||||
for (i = -shadow_size; i <= shadow_size; i++) {
|
||||
for (j = -shadow_size; j <= shadow_size; j++) {
|
||||
cairo_set_source_rgba(c, 0.0, 0.0, 0.0, 1.0 - (1.0 - shadow_edge_alpha) * sqrt((i*i + j*j)/(double)(shadow_size*shadow_size)));
|
||||
cairo_set_source_rgba(c,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
1.0 -
|
||||
(1.0 - shadow_edge_alpha) *
|
||||
sqrt((i * i + j * j) / (double)(shadow_size * shadow_size)));
|
||||
pango_cairo_update_layout(c, layout);
|
||||
cairo_move_to(c, posx + i, posy + j);
|
||||
pango_cairo_show_layout(c, layout);
|
||||
}
|
||||
}
|
||||
}
|
||||
cairo_set_source_rgba (c, color->rgb[0], color->rgb[1], color->rgb[2], color->alpha);
|
||||
pango_cairo_update_layout (c, layout);
|
||||
cairo_move_to (c, posx, posy);
|
||||
pango_cairo_show_layout (c, layout);
|
||||
cairo_set_source_rgba(c, color->rgb[0], color->rgb[1], color->rgb[2], color->alpha);
|
||||
pango_cairo_update_layout(c, layout);
|
||||
cairo_move_to(c, posx, posy);
|
||||
pango_cairo_show_layout(c, layout);
|
||||
}
|
||||
|
||||
Imlib_Image load_image(const char *path, int cached)
|
||||
@@ -477,8 +484,8 @@ Imlib_Image load_image(const char *path, int cached)
|
||||
pid_t pid = fork();
|
||||
if (pid == 0) {
|
||||
// Child
|
||||
GError* err = NULL;
|
||||
RsvgHandle* svg = rsvg_handle_new_from_file(path, &err);
|
||||
GError *err = NULL;
|
||||
RsvgHandle *svg = rsvg_handle_new_from_file(path, &err);
|
||||
|
||||
if (err != NULL) {
|
||||
fprintf(stderr, "Could not load svg image!: %s", err->message);
|
||||
@@ -519,8 +526,13 @@ Imlib_Image adjust_icon(Imlib_Image original, int alpha, int saturation, int bri
|
||||
|
||||
imlib_context_set_image(copy);
|
||||
imlib_image_set_has_alpha(1);
|
||||
DATA32* data = imlib_image_get_data();
|
||||
adjust_asb(data, imlib_image_get_width(), imlib_image_get_height(), alpha, (float)saturation/100, (float)brightness/100);
|
||||
DATA32 *data = imlib_image_get_data();
|
||||
adjust_asb(data,
|
||||
imlib_image_get_width(),
|
||||
imlib_image_get_height(),
|
||||
alpha,
|
||||
(float)saturation / 100,
|
||||
(float)brightness / 100);
|
||||
imlib_image_put_back_data(data);
|
||||
return copy;
|
||||
}
|
||||
@@ -530,25 +542,62 @@ void draw_rect(cairo_t *c, double x, double y, double w, double h, double r)
|
||||
if (r > 0.0) {
|
||||
double c1 = 0.55228475 * r;
|
||||
|
||||
cairo_move_to(c, x+r, y);
|
||||
cairo_rel_line_to(c, w-2*r, 0);
|
||||
cairo_move_to(c, x + r, y);
|
||||
cairo_rel_line_to(c, w - 2 * r, 0);
|
||||
cairo_rel_curve_to(c, c1, 0.0, r, c1, r, r);
|
||||
cairo_rel_line_to(c, 0, h-2*r);
|
||||
cairo_rel_curve_to(c, 0.0, c1, c1-r, r, -r, r);
|
||||
cairo_rel_line_to (c, -w +2*r, 0);
|
||||
cairo_rel_curve_to (c, -c1, 0, -r, -c1, -r, -r);
|
||||
cairo_rel_line_to (c, 0, -h + 2 * r);
|
||||
cairo_rel_curve_to (c, 0, -c1, r - c1, -r, r, -r);
|
||||
}
|
||||
else
|
||||
cairo_rel_line_to(c, 0, h - 2 * r);
|
||||
cairo_rel_curve_to(c, 0.0, c1, c1 - r, r, -r, r);
|
||||
cairo_rel_line_to(c, -w + 2 * r, 0);
|
||||
cairo_rel_curve_to(c, -c1, 0, -r, -c1, -r, -r);
|
||||
cairo_rel_line_to(c, 0, -h + 2 * r);
|
||||
cairo_rel_curve_to(c, 0, -c1, r - c1, -r, r, -r);
|
||||
} else
|
||||
cairo_rectangle(c, x, y, w, h);
|
||||
}
|
||||
|
||||
|
||||
void clear_pixmap(Pixmap p, int x, int y, int w, int h)
|
||||
{
|
||||
Picture pict = XRenderCreatePicture(server.dsp, p, XRenderFindVisualFormat(server.dsp, server.visual), 0, 0);
|
||||
XRenderColor col = { .red=0, .green=0, .blue=0, .alpha=0 };
|
||||
XRenderColor col;
|
||||
col.red = col.green = col.blue = col.alpha = 0;
|
||||
XRenderFillRectangle(server.dsp, PictOpSrc, pict, &col, x, y, w, h);
|
||||
XRenderFreePicture(server.dsp, pict);
|
||||
}
|
||||
|
||||
void get_text_size2(PangoFontDescription *font,
|
||||
int *height_ink,
|
||||
int *height,
|
||||
int *width,
|
||||
int panel_height,
|
||||
int panel_width,
|
||||
char *text,
|
||||
int len,
|
||||
PangoWrapMode wrap,
|
||||
PangoEllipsizeMode ellipsis)
|
||||
{
|
||||
PangoRectangle rect_ink, rect;
|
||||
|
||||
Pixmap pmap = XCreatePixmap(server.dsp, server.root_win, panel_height, panel_width, server.depth);
|
||||
|
||||
cairo_surface_t *cs = cairo_xlib_surface_create(server.dsp, pmap, server.visual, panel_height, panel_width);
|
||||
cairo_t *c = cairo_create(cs);
|
||||
|
||||
PangoLayout *layout = pango_cairo_create_layout(c);
|
||||
pango_layout_set_width(layout, panel_width * PANGO_SCALE);
|
||||
pango_layout_set_height(layout, panel_height * PANGO_SCALE);
|
||||
pango_layout_set_wrap(layout, wrap);
|
||||
pango_layout_set_ellipsize(layout, ellipsis);
|
||||
pango_layout_set_font_description(layout, font);
|
||||
pango_layout_set_text(layout, text, len);
|
||||
|
||||
pango_layout_get_pixel_extents(layout, &rect_ink, &rect);
|
||||
*height_ink = rect_ink.height;
|
||||
*height = rect.height;
|
||||
*width = rect.width;
|
||||
// printf("dimension : %d - %d\n", rect_ink.height, rect.height);
|
||||
|
||||
g_object_unref(layout);
|
||||
cairo_destroy(c);
|
||||
cairo_surface_destroy(cs);
|
||||
XFreePixmap(server.dsp, pmap);
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#ifndef COMMON_H
|
||||
#define COMMON_H
|
||||
|
||||
#define WM_CLASS_TINT "panel"
|
||||
#define WM_CLASS_TINT "panel"
|
||||
|
||||
#include <Imlib2.h>
|
||||
#include <pango/pangocairo.h>
|
||||
@@ -18,71 +18,83 @@
|
||||
#define BLUE "\033[1;34m"
|
||||
#define RESET "\033[0m"
|
||||
|
||||
/*
|
||||
void fxfree(void** ptr){
|
||||
if (*ptr){
|
||||
free(*ptr);
|
||||
*ptr=NULL;
|
||||
}
|
||||
}
|
||||
FXint fxmalloc(void** ptr,unsigned long size){
|
||||
*ptr=NULL;
|
||||
if (size!=0){
|
||||
if ((*ptr=malloc(size))==NULL) return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
*/
|
||||
|
||||
// mouse actions
|
||||
enum { NONE=0, CLOSE, TOGGLE, ICONIFY, SHADE, TOGGLE_ICONIFY, MAXIMIZE_RESTORE, MAXIMIZE, RESTORE, DESKTOP_LEFT, DESKTOP_RIGHT, NEXT_TASK, PREV_TASK };
|
||||
typedef enum MouseAction {
|
||||
NONE = 0,
|
||||
CLOSE,
|
||||
TOGGLE,
|
||||
ICONIFY,
|
||||
SHADE,
|
||||
TOGGLE_ICONIFY,
|
||||
MAXIMIZE_RESTORE,
|
||||
MAXIMIZE,
|
||||
RESTORE,
|
||||
DESKTOP_LEFT,
|
||||
DESKTOP_RIGHT,
|
||||
NEXT_TASK,
|
||||
PREV_TASK
|
||||
} MouseAction;
|
||||
|
||||
#define ALLDESKTOP 0xFFFFFFFF
|
||||
|
||||
// Copies a file to another path
|
||||
void copy_file(const char *path_src, const char *path_dest);
|
||||
|
||||
// copy file source to file dest
|
||||
void copy_file(const char *pathSrc, const char *pathDest);
|
||||
// Parses lines with the format 'key = value' into key and value.
|
||||
// Strips key and value.
|
||||
// Values may contain spaces and the equal sign.
|
||||
// Returns 1 if both key and value could be read, zero otherwise.
|
||||
int parse_line(const char *line, char **key, char **value);
|
||||
|
||||
// extract key = value
|
||||
int parse_line (const char *line, char **key, char **value);
|
||||
void extract_values(const char *value, char **value1, char **value2, char **value3);
|
||||
|
||||
// execute a command by calling fork
|
||||
void tint_exec(const char* command);
|
||||
// Executes a command in a shell.
|
||||
void tint_exec(const char *command);
|
||||
|
||||
// Returns a copy of s in which "~" is expanded to the path to the user's home directory.
|
||||
// The returned string must be freed by the caller.
|
||||
// The caller takes ownership of the string.
|
||||
char *expand_tilde(char *s);
|
||||
|
||||
// The opposite of expand_tilde: replaces the path to the user's home directory with "~".
|
||||
// The returned string must be freed by the caller.
|
||||
// The caller takes ownership of the string.
|
||||
char *contract_tilde(char *s);
|
||||
|
||||
// conversion
|
||||
int hex_char_to_int (char c);
|
||||
int hex_to_rgb (char *hex, int *r, int *g, int *b);
|
||||
void get_color (char *hex, double *rgb);
|
||||
|
||||
void extract_values (const char *value, char **value1, char **value2, char **value3);
|
||||
|
||||
// adjust Alpha/Saturation/Brightness on an ARGB icon
|
||||
// alpha from 0 to 100, satur from 0 to 1, bright from 0 to 1.
|
||||
void adjust_asb(DATA32 *data, int w, int h, int alpha, float satur, float bright);
|
||||
void createHeuristicMask(DATA32* data, int w, int h);
|
||||
int imageEmpty(DATA32* data, int w, int h);
|
||||
|
||||
void render_image(Drawable d, int x, int y);
|
||||
|
||||
void draw_text(PangoLayout *layout, cairo_t *c, int posx, int posy, Color *color, int font_shadow);
|
||||
// Color
|
||||
int hex_char_to_int(char c);
|
||||
int hex_to_rgb(char *hex, int *r, int *g, int *b);
|
||||
void get_color(char *hex, double *rgb);
|
||||
|
||||
Imlib_Image load_image(const char *path, int cached);
|
||||
|
||||
// Adjusts the alpha/saturation/brightness on an ARGB image.
|
||||
// Parameters: alpha from 0 to 100, satur from 0 to 1, bright from 0 to 1.
|
||||
void adjust_asb(DATA32 *data, int w, int h, int alpha, float satur, float bright);
|
||||
Imlib_Image adjust_icon(Imlib_Image original, int alpha, int saturation, int brightness);
|
||||
|
||||
// draw rounded rectangle
|
||||
void create_heuristic_mask(DATA32 *data, int w, int h);
|
||||
|
||||
int image_empty(DATA32 *data, int w, int h);
|
||||
|
||||
// Renders the current Imlib image to a drawable. Wrapper around imlib_render_image_on_drawable.
|
||||
void render_image(Drawable d, int x, int y);
|
||||
|
||||
void get_text_size2(PangoFontDescription *font,
|
||||
int *height_ink,
|
||||
int *height,
|
||||
int *width,
|
||||
int panel_height,
|
||||
int panel_with,
|
||||
char *text,
|
||||
int len,
|
||||
PangoWrapMode wrap,
|
||||
PangoEllipsizeMode ellipsis);
|
||||
|
||||
void draw_text(PangoLayout *layout, cairo_t *c, int posx, int posy, Color *color, int font_shadow);
|
||||
|
||||
// Draws a rounded rectangle
|
||||
void draw_rect(cairo_t *c, double x, double y, double w, double h, double r);
|
||||
|
||||
// clear pixmap with transparent color
|
||||
// Clears the pixmap (with transparent color)
|
||||
void clear_pixmap(Pixmap p, int x, int y, int w, int h);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
|
||||
/* partial change history:
|
||||
*
|
||||
* 2004-10-10 mbp: Lift out character type dependencies into macros.
|
||||
@@ -37,142 +36,129 @@
|
||||
|
||||
#include "strnatcmp.h"
|
||||
|
||||
|
||||
/* These are defined as macros to make it easier to adapt this code to
|
||||
* different characters types or comparison functions. */
|
||||
static inline int
|
||||
nat_isdigit(nat_char a)
|
||||
static inline int nat_isdigit(nat_char a)
|
||||
{
|
||||
return isdigit((unsigned char) a);
|
||||
return isdigit((unsigned char)a);
|
||||
}
|
||||
|
||||
|
||||
static inline int
|
||||
nat_isspace(nat_char a)
|
||||
static inline int nat_isspace(nat_char a)
|
||||
{
|
||||
return isspace((unsigned char) a);
|
||||
return isspace((unsigned char)a);
|
||||
}
|
||||
|
||||
|
||||
static inline nat_char
|
||||
nat_toupper(nat_char a)
|
||||
static inline nat_char nat_toupper(nat_char a)
|
||||
{
|
||||
return toupper((unsigned char) a);
|
||||
return toupper((unsigned char)a);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int
|
||||
compare_right(nat_char const *a, nat_char const *b)
|
||||
static int compare_right(nat_char const *a, nat_char const *b)
|
||||
{
|
||||
int bias = 0;
|
||||
|
||||
/* The longest run of digits wins. That aside, the greatest
|
||||
value wins, but we can't know that it will until we've scanned
|
||||
both numbers to know that they have the same magnitude, so we
|
||||
remember it in BIAS. */
|
||||
for (;; a++, b++) {
|
||||
if (!nat_isdigit(*a) && !nat_isdigit(*b))
|
||||
return bias;
|
||||
else if (!nat_isdigit(*a))
|
||||
return -1;
|
||||
else if (!nat_isdigit(*b))
|
||||
return +1;
|
||||
else if (*a < *b) {
|
||||
if (!bias)
|
||||
bias = -1;
|
||||
} else if (*a > *b) {
|
||||
if (!bias)
|
||||
bias = +1;
|
||||
} else if (!*a && !*b)
|
||||
return bias;
|
||||
}
|
||||
int bias = 0;
|
||||
|
||||
return 0;
|
||||
/* The longest run of digits wins. That aside, the greatest
|
||||
* value wins, but we can't know that it will until we've scanned
|
||||
* both numbers to know that they have the same magnitude, so we
|
||||
* remember it in BIAS. */
|
||||
for (;; a++, b++) {
|
||||
if (!nat_isdigit(*a) && !nat_isdigit(*b))
|
||||
return bias;
|
||||
else if (!nat_isdigit(*a))
|
||||
return -1;
|
||||
else if (!nat_isdigit(*b))
|
||||
return +1;
|
||||
else if (*a < *b) {
|
||||
if (!bias)
|
||||
bias = -1;
|
||||
} else if (*a > *b) {
|
||||
if (!bias)
|
||||
bias = +1;
|
||||
} else if (!*a && !*b)
|
||||
return bias;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
compare_left(nat_char const *a, nat_char const *b)
|
||||
static int compare_left(nat_char const *a, nat_char const *b)
|
||||
{
|
||||
/* Compare two left-aligned numbers: the first to have a
|
||||
different value wins. */
|
||||
for (;; a++, b++) {
|
||||
if (!nat_isdigit(*a) && !nat_isdigit(*b))
|
||||
return 0;
|
||||
else if (!nat_isdigit(*a))
|
||||
return -1;
|
||||
else if (!nat_isdigit(*b))
|
||||
return +1;
|
||||
else if (*a < *b)
|
||||
return -1;
|
||||
else if (*a > *b)
|
||||
return +1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
/* Compare two left-aligned numbers: the first to have a different value wins. */
|
||||
for (;; a++, b++) {
|
||||
if (!nat_isdigit(*a) && !nat_isdigit(*b))
|
||||
return 0;
|
||||
else if (!nat_isdigit(*a))
|
||||
return -1;
|
||||
else if (!nat_isdigit(*b))
|
||||
return +1;
|
||||
else if (*a < *b)
|
||||
return -1;
|
||||
else if (*a > *b)
|
||||
return +1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int strnatcmp0(nat_char const *a, nat_char const *b, int fold_case)
|
||||
{
|
||||
int ai, bi;
|
||||
nat_char ca, cb;
|
||||
int fractional, result;
|
||||
|
||||
assert(a && b);
|
||||
ai = bi = 0;
|
||||
while (1) {
|
||||
ca = a[ai]; cb = b[bi];
|
||||
int ai, bi;
|
||||
nat_char ca, cb;
|
||||
int fractional, result;
|
||||
|
||||
/* skip over leading spaces or zeros */
|
||||
while (nat_isspace(ca))
|
||||
ca = a[++ai];
|
||||
assert(a && b);
|
||||
ai = bi = 0;
|
||||
while (1) {
|
||||
ca = a[ai];
|
||||
cb = b[bi];
|
||||
|
||||
while (nat_isspace(cb))
|
||||
cb = b[++bi];
|
||||
/* skip over leading spaces or zeros */
|
||||
while (nat_isspace(ca))
|
||||
ca = a[++ai];
|
||||
|
||||
/* process run of digits */
|
||||
if (nat_isdigit(ca) && nat_isdigit(cb)) {
|
||||
fractional = (ca == '0' || cb == '0');
|
||||
while (nat_isspace(cb))
|
||||
cb = b[++bi];
|
||||
|
||||
if (fractional) {
|
||||
if ((result = compare_left(a+ai, b+bi)) != 0)
|
||||
return result;
|
||||
} else {
|
||||
if ((result = compare_right(a+ai, b+bi)) != 0)
|
||||
return result;
|
||||
}
|
||||
}
|
||||
/* process run of digits */
|
||||
if (nat_isdigit(ca) && nat_isdigit(cb)) {
|
||||
fractional = (ca == '0' || cb == '0');
|
||||
|
||||
if (!ca && !cb) {
|
||||
/* The strings compare the same. Perhaps the caller
|
||||
will want to call strcmp to break the tie. */
|
||||
return 0;
|
||||
}
|
||||
if (fractional) {
|
||||
if ((result = compare_left(a + ai, b + bi)) != 0)
|
||||
return result;
|
||||
} else {
|
||||
if ((result = compare_right(a + ai, b + bi)) != 0)
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
if (fold_case) {
|
||||
ca = nat_toupper(ca);
|
||||
cb = nat_toupper(cb);
|
||||
}
|
||||
|
||||
if (ca < cb)
|
||||
return -1;
|
||||
else if (ca > cb)
|
||||
return +1;
|
||||
if (!ca && !cb) {
|
||||
/* The strings compare the same. Perhaps the caller will want to call strcmp to break the tie. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
++ai; ++bi;
|
||||
}
|
||||
if (fold_case) {
|
||||
ca = nat_toupper(ca);
|
||||
cb = nat_toupper(cb);
|
||||
}
|
||||
|
||||
if (ca < cb)
|
||||
return -1;
|
||||
else if (ca > cb)
|
||||
return +1;
|
||||
|
||||
++ai;
|
||||
++bi;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
int strnatcmp(nat_char const *a, nat_char const *b) {
|
||||
return strnatcmp0(a, b, 0);
|
||||
int strnatcmp(nat_char const *a, nat_char const *b)
|
||||
{
|
||||
return strnatcmp0(a, b, 0);
|
||||
}
|
||||
|
||||
|
||||
/* Compare, recognizing numeric string and ignoring case. */
|
||||
int strnatcasecmp(nat_char const *a, nat_char const *b) {
|
||||
return strnatcmp0(a, b, 1);
|
||||
int strnatcasecmp(nat_char const *a, nat_char const *b)
|
||||
{
|
||||
return strnatcmp0(a, b, 1);
|
||||
}
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
|
||||
/* CUSTOMIZATION SECTION
|
||||
*
|
||||
* You can change this typedef, but must then also change the inline
|
||||
|
||||
191
src/util/timer.c
191
src/util/timer.c
@@ -22,10 +22,9 @@
|
||||
|
||||
#include "timer.h"
|
||||
|
||||
GSList* timeout_list;
|
||||
GSList *timeout_list;
|
||||
struct timeval next_timeout;
|
||||
GHashTable* multi_timeouts;
|
||||
|
||||
GHashTable *multi_timeouts;
|
||||
|
||||
// functions and structs for multi timeouts
|
||||
typedef struct {
|
||||
@@ -34,32 +33,31 @@ typedef struct {
|
||||
} multi_timeout;
|
||||
|
||||
typedef struct {
|
||||
GSList* timeout_list;
|
||||
timeout* parent_timeout;
|
||||
GSList *timeout_list;
|
||||
timeout *parent_timeout;
|
||||
} multi_timeout_handler;
|
||||
|
||||
struct _timeout {
|
||||
int interval_msec;
|
||||
struct timespec timeout_expires;
|
||||
void (*_callback)(void*);
|
||||
void* arg;
|
||||
multi_timeout* multi_timeout;
|
||||
void (*_callback)(void *);
|
||||
void *arg;
|
||||
multi_timeout *multi_timeout;
|
||||
timeout **self;
|
||||
};
|
||||
|
||||
void add_timeout_intern(int value_msec, int interval_msec, void(*_callback)(void*), void* arg, timeout* t);
|
||||
void add_timeout_intern(int value_msec, int interval_msec, void (*_callback)(void *), void *arg, timeout *t);
|
||||
gint compare_timeouts(gconstpointer t1, gconstpointer t2);
|
||||
int timespec_subtract(struct timespec* result, struct timespec* x, struct timespec* y);
|
||||
int timespec_subtract(struct timespec *result, struct timespec *x, struct timespec *y);
|
||||
|
||||
|
||||
int align_with_existing_timeouts(timeout* t);
|
||||
void create_multi_timeout(timeout* t1, timeout* t2);
|
||||
void append_multi_timeout(timeout* t1, timeout* t2);
|
||||
int calc_multi_timeout_interval(multi_timeout_handler* mth);
|
||||
void update_multi_timeout_values(multi_timeout_handler* mth);
|
||||
void callback_multi_timeout(void* mth);
|
||||
void remove_from_multi_timeout(timeout* t);
|
||||
void stop_multi_timeout(timeout* t);
|
||||
int align_with_existing_timeouts(timeout *t);
|
||||
void create_multi_timeout(timeout *t1, timeout *t2);
|
||||
void append_multi_timeout(timeout *t1, timeout *t2);
|
||||
int calc_multi_timeout_interval(multi_timeout_handler *mth);
|
||||
void update_multi_timeout_values(multi_timeout_handler *mth);
|
||||
void callback_multi_timeout(void *mth);
|
||||
void remove_from_multi_timeout(timeout *t);
|
||||
void stop_multi_timeout(timeout *t);
|
||||
|
||||
void default_timeout()
|
||||
{
|
||||
@@ -70,7 +68,7 @@ void default_timeout()
|
||||
void cleanup_timeout()
|
||||
{
|
||||
while (timeout_list) {
|
||||
timeout* t = timeout_list->data;
|
||||
timeout *t = timeout_list->data;
|
||||
if (t->multi_timeout)
|
||||
stop_multi_timeout(t);
|
||||
if (t->self)
|
||||
@@ -84,28 +82,27 @@ void cleanup_timeout()
|
||||
}
|
||||
}
|
||||
|
||||
/** Implementation notes for timeouts: The timeouts are kept in a GSList sorted by their
|
||||
* expiration time.
|
||||
* That means that update_next_timeout() only have to consider the first timeout in the list,
|
||||
* and callback_timeout_expired() only have to consider the timeouts as long as the expiration time
|
||||
* is in the past to the current time.
|
||||
* As time measurement we use clock_gettime(CLOCK_MONOTONIC) because this refers to a timer, which
|
||||
* reference point lies somewhere in the past and cannot be changed, but just queried.
|
||||
* If a single shot timer is installed it will be automatically deleted. I.e. the returned value
|
||||
* of add_timeout will not be valid anymore. You do not need to call stop_timeout for these timeouts,
|
||||
* however it's save to call it.
|
||||
**/
|
||||
// Implementation notes for timeouts
|
||||
//
|
||||
// The timeouts are kept in a GSList sorted by their expiration time.
|
||||
// That means that update_next_timeout() only have to consider the first timeout in the list,
|
||||
// and callback_timeout_expired() only have to consider the timeouts as long as the expiration time
|
||||
// is in the past to the current time.
|
||||
// As time measurement we use clock_gettime(CLOCK_MONOTONIC) because this refers to a timer, which
|
||||
// reference point lies somewhere in the past and cannot be changed, but just queried.
|
||||
// If a single shot timer is installed it will be automatically deleted. I.e. the returned value
|
||||
// of add_timeout will not be valid anymore. You do not need to call stop_timeout for these timeouts,
|
||||
// however it's save to call it.
|
||||
|
||||
timeout* add_timeout(int value_msec, int interval_msec, void (*_callback)(void*), void* arg, timeout **self)
|
||||
timeout *add_timeout(int value_msec, int interval_msec, void (*_callback)(void *), void *arg, timeout **self)
|
||||
{
|
||||
timeout* t = calloc(1, sizeof(timeout));
|
||||
timeout *t = calloc(1, sizeof(timeout));
|
||||
t->self = self;
|
||||
add_timeout_intern(value_msec, interval_msec, _callback, arg, t);
|
||||
return t;
|
||||
}
|
||||
|
||||
|
||||
void change_timeout(timeout **t, int value_msec, int interval_msec, void(*_callback)(), void* arg)
|
||||
void change_timeout(timeout **t, int value_msec, int interval_msec, void (*_callback)(), void *arg)
|
||||
{
|
||||
if (!((timeout_list && g_slist_find(timeout_list, *t)) ||
|
||||
(multi_timeouts && g_hash_table_lookup(multi_timeouts, *t))))
|
||||
@@ -119,32 +116,28 @@ void change_timeout(timeout **t, int value_msec, int interval_msec, void(*_callb
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void update_next_timeout()
|
||||
{
|
||||
if (timeout_list) {
|
||||
timeout* t = timeout_list->data;
|
||||
timeout *t = timeout_list->data;
|
||||
struct timespec cur_time;
|
||||
struct timespec next_timeout2 = { .tv_sec=next_timeout.tv_sec, .tv_nsec=next_timeout.tv_usec*1000 };
|
||||
struct timespec next_timeout2 = {.tv_sec = next_timeout.tv_sec, .tv_nsec = next_timeout.tv_usec * 1000};
|
||||
clock_gettime(CLOCK_MONOTONIC, &cur_time);
|
||||
if (timespec_subtract(&next_timeout2, &t->timeout_expires, &cur_time)) {
|
||||
next_timeout.tv_sec = 0;
|
||||
next_timeout.tv_usec = 0;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
next_timeout.tv_sec = next_timeout2.tv_sec;
|
||||
next_timeout.tv_usec = next_timeout2.tv_nsec/1000;
|
||||
next_timeout.tv_usec = next_timeout2.tv_nsec / 1000;
|
||||
}
|
||||
}
|
||||
else
|
||||
} else
|
||||
next_timeout.tv_sec = -1;
|
||||
}
|
||||
|
||||
|
||||
void callback_timeout_expired()
|
||||
{
|
||||
struct timespec cur_time;
|
||||
timeout* t;
|
||||
timeout *t;
|
||||
while (timeout_list) {
|
||||
clock_gettime(CLOCK_MONOTONIC, &cur_time);
|
||||
t = timeout_list->data;
|
||||
@@ -170,14 +163,12 @@ void callback_timeout_expired()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void stop_timeout(timeout* t)
|
||||
void stop_timeout(timeout *t)
|
||||
{
|
||||
if (!t)
|
||||
return;
|
||||
// if not in the list, it was deleted in callback_timeout_expired
|
||||
if ((timeout_list && g_slist_find(timeout_list, t)) ||
|
||||
(multi_timeouts && g_hash_table_lookup(multi_timeouts, t))) {
|
||||
if ((timeout_list && g_slist_find(timeout_list, t)) || (multi_timeouts && g_hash_table_lookup(multi_timeouts, t))) {
|
||||
if (multi_timeouts && t->multi_timeout)
|
||||
remove_from_multi_timeout(t);
|
||||
if (timeout_list)
|
||||
@@ -188,8 +179,7 @@ void stop_timeout(timeout* t)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void add_timeout_intern(int value_msec, int interval_msec, void(*_callback)(), void* arg, timeout *t)
|
||||
void add_timeout_intern(int value_msec, int interval_msec, void (*_callback)(), void *arg, timeout *t)
|
||||
{
|
||||
t->interval_msec = interval_msec;
|
||||
t->_callback = _callback;
|
||||
@@ -205,15 +195,12 @@ void add_timeout_intern(int value_msec, int interval_msec, void(*_callback)(), v
|
||||
timeout_list = g_slist_insert_sorted(timeout_list, t, compare_timeouts);
|
||||
}
|
||||
|
||||
|
||||
gint compare_timeouts(gconstpointer t1, gconstpointer t2)
|
||||
{
|
||||
return compare_timespecs(&((timeout*)t1)->timeout_expires,
|
||||
&((timeout*)t2)->timeout_expires);
|
||||
return compare_timespecs(&((const timeout *)t1)->timeout_expires, &((const timeout *)t2)->timeout_expires);
|
||||
}
|
||||
|
||||
|
||||
gint compare_timespecs(const struct timespec* t1, const struct timespec* t2)
|
||||
gint compare_timespecs(const struct timespec *t1, const struct timespec *t2)
|
||||
{
|
||||
if (t1->tv_sec < t2->tv_sec)
|
||||
return -1;
|
||||
@@ -224,12 +211,11 @@ gint compare_timespecs(const struct timespec* t1, const struct timespec* t2)
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
} else
|
||||
return 1;
|
||||
}
|
||||
|
||||
int timespec_subtract(struct timespec* result, struct timespec* x, struct timespec* y)
|
||||
int timespec_subtract(struct timespec *result, struct timespec *x, struct timespec *y)
|
||||
{
|
||||
/* Perform the carry for the later subtraction by updating y. */
|
||||
if (x->tv_nsec < y->tv_nsec) {
|
||||
@@ -251,27 +237,25 @@ int timespec_subtract(struct timespec* result, struct timespec* x, struct timesp
|
||||
return x->tv_sec < y->tv_sec;
|
||||
}
|
||||
|
||||
|
||||
struct timespec add_msec_to_timespec(struct timespec ts, int msec)
|
||||
{
|
||||
ts.tv_sec += msec / 1000;
|
||||
ts.tv_nsec += (msec % 1000)*1000000;
|
||||
if (ts.tv_nsec >= 1000000000) { // 10^9
|
||||
ts.tv_nsec += (msec % 1000) * 1000000;
|
||||
if (ts.tv_nsec >= 1000000000) { // 10^9
|
||||
ts.tv_sec++;
|
||||
ts.tv_nsec -= 1000000000;
|
||||
}
|
||||
return ts;
|
||||
}
|
||||
|
||||
|
||||
int align_with_existing_timeouts(timeout *t)
|
||||
{
|
||||
GSList* it = timeout_list;
|
||||
GSList *it = timeout_list;
|
||||
while (it) {
|
||||
timeout* t2 = it->data;
|
||||
timeout *t2 = it->data;
|
||||
if (t2->interval_msec > 0) {
|
||||
if (t->interval_msec % t2->interval_msec == 0 || t2->interval_msec % t->interval_msec == 0) {
|
||||
if (multi_timeouts == 0)
|
||||
if (!multi_timeouts)
|
||||
multi_timeouts = g_hash_table_new(0, 0);
|
||||
if (!t->multi_timeout && !t2->multi_timeout) {
|
||||
// both timeouts can be aligned, but there is no multi timeout for them
|
||||
@@ -288,11 +272,10 @@ int align_with_existing_timeouts(timeout *t)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int calc_multi_timeout_interval(multi_timeout_handler* mth)
|
||||
int calc_multi_timeout_interval(multi_timeout_handler *mth)
|
||||
{
|
||||
GSList* it = mth->timeout_list;
|
||||
timeout* t = it->data;
|
||||
GSList *it = mth->timeout_list;
|
||||
timeout *t = it->data;
|
||||
int min_interval = t->interval_msec;
|
||||
it = it->next;
|
||||
while (it) {
|
||||
@@ -304,13 +287,12 @@ int calc_multi_timeout_interval(multi_timeout_handler* mth)
|
||||
return min_interval;
|
||||
}
|
||||
|
||||
|
||||
void create_multi_timeout(timeout* t1, timeout* t2)
|
||||
void create_multi_timeout(timeout *t1, timeout *t2)
|
||||
{
|
||||
multi_timeout* mt1 = calloc(1, sizeof(multi_timeout));
|
||||
multi_timeout* mt2 = calloc(1, sizeof(multi_timeout));
|
||||
multi_timeout_handler* mth = calloc(1, sizeof(multi_timeout_handler));
|
||||
timeout* real_timeout = calloc(1, sizeof(timeout));
|
||||
multi_timeout *mt1 = calloc(1, sizeof(multi_timeout));
|
||||
multi_timeout *mt2 = calloc(1, sizeof(multi_timeout));
|
||||
multi_timeout_handler *mth = calloc(1, sizeof(multi_timeout_handler));
|
||||
timeout *real_timeout = calloc(1, sizeof(timeout));
|
||||
|
||||
mth->timeout_list = 0;
|
||||
mth->timeout_list = g_slist_prepend(mth->timeout_list, t1);
|
||||
@@ -325,7 +307,7 @@ void create_multi_timeout(timeout* t1, timeout* t2)
|
||||
t2->multi_timeout = mt2;
|
||||
// set real_timeout->multi_timeout to something, such that we see in add_timeout_intern that
|
||||
// it is already a multi_timeout (we never use it, except of checking for 0 ptr)
|
||||
real_timeout->multi_timeout = (void*)real_timeout;
|
||||
real_timeout->multi_timeout = (void *)real_timeout;
|
||||
|
||||
timeout_list = g_slist_remove(timeout_list, t1);
|
||||
timeout_list = g_slist_remove(timeout_list, t2);
|
||||
@@ -333,18 +315,17 @@ void create_multi_timeout(timeout* t1, timeout* t2)
|
||||
update_multi_timeout_values(mth);
|
||||
}
|
||||
|
||||
|
||||
void append_multi_timeout(timeout* t1, timeout* t2)
|
||||
void append_multi_timeout(timeout *t1, timeout *t2)
|
||||
{
|
||||
if (t2->multi_timeout) {
|
||||
// swap t1 and t2 such that t1 is the multi timeout
|
||||
timeout* tmp = t2;
|
||||
timeout *tmp = t2;
|
||||
t2 = t1;
|
||||
t1 = tmp;
|
||||
}
|
||||
|
||||
multi_timeout* mt = calloc(1, sizeof(multi_timeout));
|
||||
multi_timeout_handler* mth = g_hash_table_lookup(multi_timeouts, t1);
|
||||
multi_timeout *mt = calloc(1, sizeof(multi_timeout));
|
||||
multi_timeout_handler *mth = g_hash_table_lookup(multi_timeouts, t1);
|
||||
|
||||
mth->timeout_list = g_slist_prepend(mth->timeout_list, t2);
|
||||
g_hash_table_insert(multi_timeouts, t2, mth);
|
||||
@@ -354,8 +335,7 @@ void append_multi_timeout(timeout* t1, timeout* t2)
|
||||
update_multi_timeout_values(mth);
|
||||
}
|
||||
|
||||
|
||||
void update_multi_timeout_values(multi_timeout_handler* mth)
|
||||
void update_multi_timeout_values(multi_timeout_handler *mth)
|
||||
{
|
||||
int interval = calc_multi_timeout_interval(mth);
|
||||
int next_timeout_msec = interval;
|
||||
@@ -363,14 +343,14 @@ void update_multi_timeout_values(multi_timeout_handler* mth)
|
||||
struct timespec cur_time;
|
||||
clock_gettime(CLOCK_MONOTONIC, &cur_time);
|
||||
|
||||
GSList* it = mth->timeout_list;
|
||||
GSList *it = mth->timeout_list;
|
||||
struct timespec diff_time;
|
||||
while (it) {
|
||||
timeout* t = it->data;
|
||||
timeout *t = it->data;
|
||||
t->multi_timeout->count_to_expiration = t->interval_msec / interval;
|
||||
timespec_subtract(&diff_time, &t->timeout_expires, &cur_time);
|
||||
int msec_to_expiration = diff_time.tv_sec*1000 + diff_time.tv_nsec/1000000;
|
||||
int count_left = msec_to_expiration / interval + (msec_to_expiration%interval != 0);
|
||||
int msec_to_expiration = diff_time.tv_sec * 1000 + diff_time.tv_nsec / 1000000;
|
||||
int count_left = msec_to_expiration / interval + (msec_to_expiration % interval != 0);
|
||||
t->multi_timeout->current_count = t->multi_timeout->count_to_expiration - count_left;
|
||||
if (msec_to_expiration < next_timeout_msec)
|
||||
next_timeout_msec = msec_to_expiration;
|
||||
@@ -382,15 +362,14 @@ void update_multi_timeout_values(multi_timeout_handler* mth)
|
||||
add_timeout_intern(next_timeout_msec, interval, callback_multi_timeout, mth, mth->parent_timeout);
|
||||
}
|
||||
|
||||
|
||||
void callback_multi_timeout(void* arg)
|
||||
void callback_multi_timeout(void *arg)
|
||||
{
|
||||
multi_timeout_handler* mth = arg;
|
||||
multi_timeout_handler *mth = arg;
|
||||
struct timespec cur_time;
|
||||
clock_gettime(CLOCK_MONOTONIC, &cur_time);
|
||||
GSList* it = mth->timeout_list;
|
||||
GSList *it = mth->timeout_list;
|
||||
while (it) {
|
||||
timeout* t = it->data;
|
||||
timeout *t = it->data;
|
||||
if (++t->multi_timeout->current_count >= t->multi_timeout->count_to_expiration) {
|
||||
t->_callback(t->arg);
|
||||
if (multi_timeouts && g_hash_table_lookup(multi_timeouts, t)) {
|
||||
@@ -405,10 +384,9 @@ void callback_multi_timeout(void* arg)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void remove_from_multi_timeout(timeout* t)
|
||||
void remove_from_multi_timeout(timeout *t)
|
||||
{
|
||||
multi_timeout_handler* mth = g_hash_table_lookup(multi_timeouts, t);
|
||||
multi_timeout_handler *mth = g_hash_table_lookup(multi_timeouts, t);
|
||||
g_hash_table_remove(multi_timeouts, t);
|
||||
|
||||
mth->timeout_list = g_slist_remove(mth->timeout_list, t);
|
||||
@@ -416,7 +394,7 @@ void remove_from_multi_timeout(timeout* t)
|
||||
t->multi_timeout = 0;
|
||||
|
||||
if (g_slist_length(mth->timeout_list) == 1) {
|
||||
timeout* last_timeout = mth->timeout_list->data;
|
||||
timeout *last_timeout = mth->timeout_list->data;
|
||||
mth->timeout_list = g_slist_remove(mth->timeout_list, last_timeout);
|
||||
free(last_timeout->multi_timeout);
|
||||
last_timeout->multi_timeout = 0;
|
||||
@@ -429,20 +407,22 @@ void remove_from_multi_timeout(timeout* t)
|
||||
struct timespec cur_time, diff_time;
|
||||
clock_gettime(CLOCK_MONOTONIC, &cur_time);
|
||||
timespec_subtract(&diff_time, &t->timeout_expires, &cur_time);
|
||||
int msec_to_expiration = diff_time.tv_sec*1000 + diff_time.tv_nsec/1000000;
|
||||
add_timeout_intern(msec_to_expiration, last_timeout->interval_msec, last_timeout->_callback, last_timeout->arg, last_timeout);
|
||||
}
|
||||
else
|
||||
int msec_to_expiration = diff_time.tv_sec * 1000 + diff_time.tv_nsec / 1000000;
|
||||
add_timeout_intern(msec_to_expiration,
|
||||
last_timeout->interval_msec,
|
||||
last_timeout->_callback,
|
||||
last_timeout->arg,
|
||||
last_timeout);
|
||||
} else
|
||||
update_multi_timeout_values(mth);
|
||||
}
|
||||
|
||||
|
||||
void stop_multi_timeout(timeout* t)
|
||||
void stop_multi_timeout(timeout *t)
|
||||
{
|
||||
multi_timeout_handler* mth = g_hash_table_lookup(multi_timeouts, t);
|
||||
multi_timeout_handler *mth = g_hash_table_lookup(multi_timeouts, t);
|
||||
g_hash_table_remove(multi_timeouts, mth->parent_timeout);
|
||||
while (mth->timeout_list) {
|
||||
timeout* t1 = mth->timeout_list->data;
|
||||
timeout *t1 = mth->timeout_list->data;
|
||||
mth->timeout_list = g_slist_remove(mth->timeout_list, t1);
|
||||
g_hash_table_remove(multi_timeouts, t1);
|
||||
free(t1->multi_timeout);
|
||||
@@ -452,6 +432,7 @@ void stop_multi_timeout(timeout* t)
|
||||
}
|
||||
|
||||
double profiling_get_time_old_time = 0;
|
||||
|
||||
double profiling_get_time()
|
||||
{
|
||||
struct timespec cur_time;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/**************************************************************************
|
||||
/*************************************************************************
|
||||
*
|
||||
* Copyright (C) 2009 Andreas.Fink (Andreas.Fink85@gmail.com)
|
||||
*
|
||||
@@ -15,7 +15,6 @@
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
**************************************************************************/
|
||||
|
||||
|
||||
#ifndef TIMER_H
|
||||
#define TIMER_H
|
||||
|
||||
@@ -23,59 +22,51 @@
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
// Single shot timers (i.e. timers with interval_msec == 0) are deleted automatically as soon as they expire,
|
||||
// i.e. you do not need to stop them, however it is safe to call stop_timeout for these timers.
|
||||
// You can pass the address of the variable storing the pointer to the timer as 'self' in add_timeout, in which
|
||||
// case it is used to clear the pointer if the timer is destroyed automatically. This enforces the timeout pointers
|
||||
// to be either valid or NULL.
|
||||
// Periodic timeouts are aligned to each other whenever possible, i.e. one interval_msec is an
|
||||
// integral multiple of the other.
|
||||
|
||||
extern struct timeval next_timeout;
|
||||
|
||||
|
||||
typedef struct _timeout timeout;
|
||||
|
||||
|
||||
// timer functions
|
||||
/**
|
||||
* Single shot timers (i.e. timers with interval_msec == 0) are deleted automatically as soon as they expire,
|
||||
* i.e. you do not need to stop them, however it is safe to call stop_timeout for these timers.
|
||||
* You can pass the address of the variable storing the pointer to the timer as 'self' in add_timeout, in which
|
||||
* case it is used to clear the pointer if the timer is destroyed automatically. This enforces the timeout pointers
|
||||
* to be either valid or NULL.
|
||||
* Periodic timeouts are aligned to each other whenever possible, i.e. one interval_msec is an
|
||||
* integral multiple of the other.
|
||||
**/
|
||||
|
||||
/** Initializes default global data. **/
|
||||
// Initializes default global data.
|
||||
void default_timeout();
|
||||
|
||||
/** Cleans up: stops all timers and frees memory. **/
|
||||
// Cleans up: stops all timers and frees memory.
|
||||
void cleanup_timeout();
|
||||
|
||||
/** Installs a timer with the first timeout after 'value_msec' and then an optional periodic timeout every
|
||||
* 'interval_msec' (set it to 0 to prevent periodic timeouts).
|
||||
* '_callback' is the function called when the timer reaches the timeout.
|
||||
* 'arg' is the argument passed to the callback function.
|
||||
* 'self' is an optional pointer to a timeout* variable. If non-NULL, the variable is set to NULL when the timer
|
||||
* is destroyed (with stop_timeout, cleanup_timeout or when the timer expires and it is single-shot).
|
||||
* Returns a pointer to the timer, which is needed for stopping/changing it.
|
||||
**/
|
||||
timeout* add_timeout(int value_msec, int interval_msec, void (*_callback)(void*), void* arg, timeout **self);
|
||||
// Installs a timer with the first timeout after 'value_msec' and then an optional periodic timeout every
|
||||
// 'interval_msec' (set it to 0 to prevent periodic timeouts).
|
||||
// '_callback' is the function called when the timer reaches the timeout.
|
||||
// 'arg' is the argument passed to the callback function.
|
||||
// 'self' is an optional pointer to a timeout* variable. If non-NULL, the variable is set to NULL when the timer
|
||||
// is destroyed (with stop_timeout, cleanup_timeout or when the timer expires and it is single-shot).
|
||||
// Returns a pointer to the timer, which is needed for stopping/changing it.
|
||||
timeout *add_timeout(int value_msec, int interval_msec, void (*_callback)(void *), void *arg, timeout **self);
|
||||
|
||||
/** Changes timer 't'. If it does not exist, a new timer is created, with self set to 't'. **/
|
||||
void change_timeout(timeout** t, int value_msec, int interval_msec, void (*_callback)(void*), void* arg);
|
||||
// Changes timer 't'. If it does not exist, a new timer is created, with self set to 't'.
|
||||
void change_timeout(timeout **t, int value_msec, int interval_msec, void (*_callback)(void *), void *arg);
|
||||
|
||||
/** stops the timeout 't' **/
|
||||
void stop_timeout(timeout* t);
|
||||
// Stops the timer 't'
|
||||
void stop_timeout(timeout *t);
|
||||
|
||||
/** update_next_timeout updates next_timeout to the value, when the next installed timeout will expire **/
|
||||
// Updates next_timeout to the value, when the next installed timeout will expire
|
||||
void update_next_timeout();
|
||||
|
||||
/** Callback of all expired timeouts **/
|
||||
// Callback of all expired timeouts
|
||||
void callback_timeout_expired();
|
||||
|
||||
/** Returns -1 if t1 < t2, 0 if t1 == t2, 1 if t1 > t2 **/
|
||||
gint compare_timespecs(const struct timespec* t1, const struct timespec* t2);
|
||||
// Returns -1 if t1 < t2, 0 if t1 == t2, 1 if t1 > t2
|
||||
gint compare_timespecs(const struct timespec *t1, const struct timespec *t2);
|
||||
|
||||
struct timespec add_msec_to_timespec(struct timespec ts, int msec);
|
||||
|
||||
/** Returns the time difference in seconds between the current time and the last time this function was called.
|
||||
* At the first call returns zero.
|
||||
**/
|
||||
// Returns the time difference in seconds between the current time and the last time this function was called.
|
||||
// At the first call returns zero.
|
||||
double profiling_get_time();
|
||||
|
||||
#endif // TIMER_H
|
||||
|
||||
@@ -36,8 +36,9 @@ static int ueventfd = -1;
|
||||
static struct sockaddr_nl nls;
|
||||
static GList *notifiers = NULL;
|
||||
|
||||
static const char* has_prefix(const char *str, const char *end, const char *prefix, size_t prefixlen) {
|
||||
if ((end-str) < prefixlen)
|
||||
static const char *has_prefix(const char *str, const char *end, const char *prefix, size_t prefixlen)
|
||||
{
|
||||
if ((end - str) < prefixlen)
|
||||
return NULL;
|
||||
|
||||
if (!memcmp(str, prefix, prefixlen))
|
||||
@@ -46,38 +47,40 @@ static const char* has_prefix(const char *str, const char *end, const char *pref
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#define HAS_CONST_PREFIX(str,end,prefix) has_prefix((str),end,prefix,sizeof(prefix)-1)
|
||||
#define HAS_CONST_PREFIX(str, end, prefix) has_prefix((str), end, prefix, sizeof(prefix) - 1)
|
||||
|
||||
static void uevent_param_free(gpointer data) {
|
||||
static void uevent_param_free(gpointer data)
|
||||
{
|
||||
struct uevent_parameter *param = data;
|
||||
free(param->key);
|
||||
free(param->val);
|
||||
free(param);
|
||||
}
|
||||
|
||||
static void uevent_free(struct uevent *ev) {
|
||||
static void uevent_free(struct uevent *ev)
|
||||
{
|
||||
free(ev->path);
|
||||
free(ev->subsystem);
|
||||
g_list_free_full(ev->params, uevent_param_free);
|
||||
free(ev);
|
||||
}
|
||||
|
||||
static struct uevent *uevent_new(char *buffer, int size) {
|
||||
struct uevent *ev;
|
||||
const char* s = buffer;
|
||||
const char* end = s + size;
|
||||
static struct uevent *uevent_new(char *buffer, int size)
|
||||
{
|
||||
gboolean first = TRUE;
|
||||
|
||||
if (size == 0)
|
||||
return NULL;
|
||||
|
||||
ev = calloc(1, sizeof(*ev));
|
||||
struct uevent *ev = calloc(1, sizeof(*ev));
|
||||
if (!ev)
|
||||
return NULL;
|
||||
|
||||
/* ensure nul termination required by strlen() */
|
||||
buffer[size-1] = '\0';
|
||||
buffer[size - 1] = '\0';
|
||||
|
||||
const char *s = buffer;
|
||||
const char *end = s + size;
|
||||
for (; s < end; s += strlen(s) + 1) {
|
||||
if (first) {
|
||||
const char *p = strchr(s, '@');
|
||||
@@ -87,10 +90,10 @@ static struct uevent *uevent_new(char *buffer, int size) {
|
||||
free(ev);
|
||||
return NULL;
|
||||
}
|
||||
ev->path = strdup(p+1);
|
||||
ev->path = strdup(p + 1);
|
||||
first = FALSE;
|
||||
} else {
|
||||
const char* val;
|
||||
const char *val;
|
||||
if ((val = HAS_CONST_PREFIX(s, end, "ACTION=")) != NULL) {
|
||||
if (!strcmp(val, "add"))
|
||||
ev->action = UEVENT_ADD;
|
||||
@@ -109,8 +112,8 @@ static struct uevent *uevent_new(char *buffer, int size) {
|
||||
if (val) {
|
||||
struct uevent_parameter *param = malloc(sizeof(*param));
|
||||
if (param) {
|
||||
param->key = strndup(s, val-s);
|
||||
param->val = strdup(val+1);
|
||||
param->key = strndup(s, val - s);
|
||||
param->val = strdup(val + 1);
|
||||
ev->params = g_list_append(ev->params, param);
|
||||
}
|
||||
}
|
||||
@@ -121,11 +124,13 @@ static struct uevent *uevent_new(char *buffer, int size) {
|
||||
return ev;
|
||||
}
|
||||
|
||||
void uevent_register_notifier(struct uevent_notify *nb) {
|
||||
void uevent_register_notifier(struct uevent_notify *nb)
|
||||
{
|
||||
notifiers = g_list_append(notifiers, nb);
|
||||
}
|
||||
|
||||
void uevent_unregister_notifier(struct uevent_notify *nb) {
|
||||
void uevent_unregister_notifier(struct uevent_notify *nb)
|
||||
{
|
||||
GList *l = notifiers;
|
||||
|
||||
while (l != NULL) {
|
||||
@@ -139,21 +144,19 @@ void uevent_unregister_notifier(struct uevent_notify *nb) {
|
||||
}
|
||||
}
|
||||
|
||||
void uevent_handler() {
|
||||
struct uevent *ev;
|
||||
char buf[512];
|
||||
GList *l;
|
||||
|
||||
void uevent_handler()
|
||||
{
|
||||
if (ueventfd < 0)
|
||||
return;
|
||||
|
||||
char buf[512];
|
||||
int len = recv(ueventfd, buf, sizeof(buf), MSG_DONTWAIT);
|
||||
if (len < 0)
|
||||
return;
|
||||
|
||||
ev = uevent_new(buf, len);
|
||||
struct uevent *ev = uevent_new(buf, len);
|
||||
if (ev) {
|
||||
for (l = notifiers; l != NULL; l = l->next) {
|
||||
for (GList *l = notifiers; l; l = l->next) {
|
||||
struct uevent_notify *nb = l->data;
|
||||
|
||||
if (!(ev->action & nb->action))
|
||||
@@ -169,9 +172,10 @@ void uevent_handler() {
|
||||
}
|
||||
}
|
||||
|
||||
int uevent_init() {
|
||||
int uevent_init()
|
||||
{
|
||||
/* Open hotplug event netlink socket */
|
||||
memset(&nls,0,sizeof(struct sockaddr_nl));
|
||||
memset(&nls, 0, sizeof(struct sockaddr_nl));
|
||||
nls.nl_family = AF_NETLINK;
|
||||
nls.nl_pid = getpid();
|
||||
nls.nl_groups = -1;
|
||||
@@ -194,7 +198,8 @@ int uevent_init() {
|
||||
return ueventfd;
|
||||
}
|
||||
|
||||
void uevent_cleanup() {
|
||||
void uevent_cleanup()
|
||||
{
|
||||
if (ueventfd >= 0)
|
||||
close(ueventfd);
|
||||
}
|
||||
|
||||
@@ -35,97 +35,88 @@
|
||||
#include "panel.h"
|
||||
#include "taskbar.h"
|
||||
|
||||
|
||||
|
||||
void set_active (Window win)
|
||||
void activate_window(Window win)
|
||||
{
|
||||
send_event32 (win, server.atom._NET_ACTIVE_WINDOW, 2, CurrentTime, 0);
|
||||
send_event32(win, server.atom._NET_ACTIVE_WINDOW, 2, CurrentTime, 0);
|
||||
}
|
||||
|
||||
|
||||
void set_desktop (int desktop)
|
||||
void change_desktop(int desktop)
|
||||
{
|
||||
send_event32 (server.root_win, server.atom._NET_CURRENT_DESKTOP, desktop, 0, 0);
|
||||
send_event32(server.root_win, server.atom._NET_CURRENT_DESKTOP, desktop, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
void windows_set_desktop (Window win, int desktop)
|
||||
void change_window_desktop(Window win, int desktop)
|
||||
{
|
||||
send_event32 (win, server.atom._NET_WM_DESKTOP, desktop, 2, 0);
|
||||
send_event32(win, server.atom._NET_WM_DESKTOP, desktop, 2, 0);
|
||||
}
|
||||
|
||||
|
||||
void set_close (Window win)
|
||||
void close_window(Window win)
|
||||
{
|
||||
send_event32 (win, server.atom._NET_CLOSE_WINDOW, 0, 2, 0);
|
||||
send_event32(win, server.atom._NET_CLOSE_WINDOW, 0, 2, 0);
|
||||
}
|
||||
|
||||
|
||||
void window_toggle_shade (Window win)
|
||||
void toggle_window_shade(Window win)
|
||||
{
|
||||
send_event32 (win, server.atom._NET_WM_STATE, 2, server.atom._NET_WM_STATE_SHADED, 0);
|
||||
send_event32(win, server.atom._NET_WM_STATE, 2, server.atom._NET_WM_STATE_SHADED, 0);
|
||||
}
|
||||
|
||||
|
||||
void window_maximize_restore (Window win)
|
||||
void toggle_window_maximized(Window win)
|
||||
{
|
||||
send_event32 (win, server.atom._NET_WM_STATE, 2, server.atom._NET_WM_STATE_MAXIMIZED_VERT, 0);
|
||||
send_event32 (win, server.atom._NET_WM_STATE, 2, server.atom._NET_WM_STATE_MAXIMIZED_HORZ, 0);
|
||||
send_event32(win, server.atom._NET_WM_STATE, 2, server.atom._NET_WM_STATE_MAXIMIZED_VERT, 0);
|
||||
send_event32(win, server.atom._NET_WM_STATE, 2, server.atom._NET_WM_STATE_MAXIMIZED_HORZ, 0);
|
||||
}
|
||||
|
||||
|
||||
int window_is_hidden (Window win)
|
||||
gboolean window_is_hidden(Window win)
|
||||
{
|
||||
Window window;
|
||||
Atom *at;
|
||||
int count, i;
|
||||
int count;
|
||||
|
||||
at = server_get_property (win, server.atom._NET_WM_STATE, XA_ATOM, &count);
|
||||
for (i = 0; i < count; i++) {
|
||||
Atom *at = server_get_property(win, server.atom._NET_WM_STATE, XA_ATOM, &count);
|
||||
for (int i = 0; i < count; i++) {
|
||||
if (at[i] == server.atom._NET_WM_STATE_SKIP_TASKBAR) {
|
||||
XFree(at);
|
||||
return 1;
|
||||
return TRUE;
|
||||
}
|
||||
// do not add transient_for windows if the transient window is already in the taskbar
|
||||
window=win;
|
||||
while ( XGetTransientForHint(server.dsp, window, &window) ) {
|
||||
if ( task_get_tasks(window) ) {
|
||||
window = win;
|
||||
while (XGetTransientForHint(server.dsp, window, &window)) {
|
||||
if (task_get_tasks(window)) {
|
||||
XFree(at);
|
||||
return 1;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
XFree(at);
|
||||
|
||||
at = server_get_property (win, server.atom._NET_WM_WINDOW_TYPE, XA_ATOM, &count);
|
||||
for (i = 0; i < count; i++) {
|
||||
if (at[i] == server.atom._NET_WM_WINDOW_TYPE_DOCK || at[i] == server.atom._NET_WM_WINDOW_TYPE_DESKTOP || at[i] == server.atom._NET_WM_WINDOW_TYPE_TOOLBAR || at[i] == server.atom._NET_WM_WINDOW_TYPE_MENU || at[i] == server.atom._NET_WM_WINDOW_TYPE_SPLASH) {
|
||||
at = server_get_property(win, server.atom._NET_WM_WINDOW_TYPE, XA_ATOM, &count);
|
||||
for (int i = 0; i < count; i++) {
|
||||
if (at[i] == server.atom._NET_WM_WINDOW_TYPE_DOCK || at[i] == server.atom._NET_WM_WINDOW_TYPE_DESKTOP ||
|
||||
at[i] == server.atom._NET_WM_WINDOW_TYPE_TOOLBAR || at[i] == server.atom._NET_WM_WINDOW_TYPE_MENU ||
|
||||
at[i] == server.atom._NET_WM_WINDOW_TYPE_SPLASH) {
|
||||
XFree(at);
|
||||
return 1;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
XFree(at);
|
||||
|
||||
for (i=0 ; i < nb_panel ; i++) {
|
||||
if (panel1[i].main_win == win) {
|
||||
return 1;
|
||||
for (int i = 0; i < num_panels; i++) {
|
||||
if (panels[i].main_win == win) {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
// specification
|
||||
// Windows with neither _NET_WM_WINDOW_TYPE nor WM_TRANSIENT_FOR set
|
||||
// MUST be taken as top-level window.
|
||||
return 0;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
int window_get_desktop (Window win)
|
||||
int get_window_desktop(Window win)
|
||||
{
|
||||
return get_property32(win, server.atom._NET_WM_DESKTOP, XA_CARDINAL);
|
||||
}
|
||||
|
||||
|
||||
int window_get_monitor (Window win)
|
||||
int get_window_monitor(Window win)
|
||||
{
|
||||
int i, x, y;
|
||||
Window src;
|
||||
@@ -136,14 +127,12 @@ int window_get_monitor (Window win)
|
||||
int match_bottom = 0;
|
||||
// There is an ambiguity when a window is right on the edge between screens.
|
||||
// In that case, prefer the monitor which is on the right and bottom of the window's top-left corner.
|
||||
for (i = 0; i < server.nb_monitor; i++) {
|
||||
for (i = 0; i < server.num_monitors; i++) {
|
||||
if (x >= server.monitor[i].x && x <= (server.monitor[i].x + server.monitor[i].width))
|
||||
if (y >= server.monitor[i].y && y <= (server.monitor[i].y + server.monitor[i].height)) {
|
||||
int current_right = x < (server.monitor[i].x + server.monitor[i].width);
|
||||
int current_bottom = y < (server.monitor[i].y + server.monitor[i].height);
|
||||
if (best_match < 0 ||
|
||||
(!match_right && current_right) ||
|
||||
(!match_bottom && current_bottom)) {
|
||||
if (best_match < 0 || (!match_right && current_right) || (!match_bottom && current_bottom)) {
|
||||
best_match = i;
|
||||
}
|
||||
}
|
||||
@@ -155,81 +144,73 @@ int window_get_monitor (Window win)
|
||||
return best_match;
|
||||
}
|
||||
|
||||
void window_get_coordinates (Window win, int *x, int *y, int *w, int *h)
|
||||
void get_window_coordinates(Window win, int *x, int *y, int *w, int *h)
|
||||
{
|
||||
int dummy_int;
|
||||
unsigned ww, wh, bw, bh;
|
||||
Window src;
|
||||
XTranslateCoordinates(server.dsp, win, server.root_win, 0, 0, x, y, &src);
|
||||
Window src;
|
||||
XTranslateCoordinates(server.dsp, win, server.root_win, 0, 0, x, y, &src);
|
||||
XGetGeometry(server.dsp, win, &src, &dummy_int, &dummy_int, &ww, &wh, &bw, &bh);
|
||||
*w = ww + bw;
|
||||
*h = wh + bh;
|
||||
}
|
||||
|
||||
int window_is_iconified (Window win)
|
||||
gboolean window_is_iconified(Window win)
|
||||
{
|
||||
// EWMH specification : minimization of windows use _NET_WM_STATE_HIDDEN.
|
||||
// WM_STATE is not accurate for shaded window and in multi_desktop mode.
|
||||
Atom *at;
|
||||
int count, i;
|
||||
at = server_get_property (win, server.atom._NET_WM_STATE, XA_ATOM, &count);
|
||||
for (i = 0; i < count; i++) {
|
||||
int count;
|
||||
Atom *at = server_get_property(win, server.atom._NET_WM_STATE, XA_ATOM, &count);
|
||||
for (int i = 0; i < count; i++) {
|
||||
if (at[i] == server.atom._NET_WM_STATE_HIDDEN) {
|
||||
XFree(at);
|
||||
return 1;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
XFree(at);
|
||||
return 0;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
int window_is_urgent (Window win)
|
||||
gboolean window_is_urgent(Window win)
|
||||
{
|
||||
Atom *at;
|
||||
int count, i;
|
||||
int count;
|
||||
|
||||
at = server_get_property (win, server.atom._NET_WM_STATE, XA_ATOM, &count);
|
||||
for (i = 0; i < count; i++) {
|
||||
Atom *at = server_get_property(win, server.atom._NET_WM_STATE, XA_ATOM, &count);
|
||||
for (int i = 0; i < count; i++) {
|
||||
if (at[i] == server.atom._NET_WM_STATE_DEMANDS_ATTENTION) {
|
||||
XFree(at);
|
||||
return 1;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
XFree(at);
|
||||
return 0;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
int window_is_skip_taskbar (Window win)
|
||||
gboolean window_is_skip_taskbar(Window win)
|
||||
{
|
||||
Atom *at;
|
||||
int count, i;
|
||||
int count;
|
||||
|
||||
at = server_get_property(win, server.atom._NET_WM_STATE, XA_ATOM, &count);
|
||||
for (i=0; i<count; i++) {
|
||||
Atom *at = server_get_property(win, server.atom._NET_WM_STATE, XA_ATOM, &count);
|
||||
for (int i = 0; i < count; i++) {
|
||||
if (at[i] == server.atom._NET_WM_STATE_SKIP_TASKBAR) {
|
||||
XFree(at);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
XFree(at);
|
||||
return 0;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
GSList *server_get_name_of_desktop ()
|
||||
GSList *get_desktop_names()
|
||||
{
|
||||
int count, j;
|
||||
int count;
|
||||
GSList *list = NULL;
|
||||
gchar *data_ptr, *ptr;
|
||||
data_ptr = server_get_property (server.root_win, server.atom._NET_DESKTOP_NAMES, server.atom.UTF8_STRING, &count);
|
||||
gchar *data_ptr = server_get_property(server.root_win, server.atom._NET_DESKTOP_NAMES, server.atom.UTF8_STRING, &count);
|
||||
if (data_ptr) {
|
||||
list = g_slist_append(list, g_strdup(data_ptr));
|
||||
for (j = 0; j < count-1; j++) {
|
||||
if (*(data_ptr + j) == '\0') {
|
||||
ptr = (gchar*)data_ptr + j + 1;
|
||||
for (int j = 0; j < count - 1; j++) {
|
||||
if (*(data_ptr + j) == '\0') {
|
||||
gchar *ptr = (gchar *)data_ptr + j + 1;
|
||||
list = g_slist_append(list, g_strdup(ptr));
|
||||
}
|
||||
}
|
||||
@@ -238,44 +219,40 @@ GSList *server_get_name_of_desktop ()
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
int server_get_current_desktop ()
|
||||
int get_current_desktop()
|
||||
{
|
||||
return get_property32(server.root_win, server.atom._NET_CURRENT_DESKTOP, XA_CARDINAL);
|
||||
}
|
||||
|
||||
|
||||
Window window_get_active ()
|
||||
Window get_active_window()
|
||||
{
|
||||
return get_property32(server.root_win, server.atom._NET_ACTIVE_WINDOW, XA_WINDOW);
|
||||
}
|
||||
|
||||
|
||||
int window_is_active (Window win)
|
||||
gboolean window_is_active(Window win)
|
||||
{
|
||||
return (win == get_property32(server.root_win, server.atom._NET_ACTIVE_WINDOW, XA_WINDOW));
|
||||
}
|
||||
|
||||
|
||||
int get_icon_count (gulong *data, int num)
|
||||
int get_icon_count(gulong *data, int num)
|
||||
{
|
||||
int count, pos, w, h;
|
||||
|
||||
count = 0;
|
||||
pos = 0;
|
||||
while (pos+2 < num) {
|
||||
while (pos + 2 < num) {
|
||||
w = data[pos++];
|
||||
h = data[pos++];
|
||||
pos += w * h;
|
||||
if (pos > num || w <= 0 || h <= 0) break;
|
||||
if (pos > num || w <= 0 || h <= 0)
|
||||
break;
|
||||
count++;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
gulong *get_best_icon (gulong *data, int icon_count, int num, int *iw, int *ih, int best_icon_size)
|
||||
gulong *get_best_icon(gulong *data, int icon_count, int num, int *iw, int *ih, int best_icon_size)
|
||||
{
|
||||
int width[icon_count], height[icon_count], pos, i, w, h;
|
||||
gulong *icon_data[icon_count];
|
||||
@@ -286,7 +263,8 @@ gulong *get_best_icon (gulong *data, int icon_count, int num, int *iw, int *ih,
|
||||
while (i--) {
|
||||
w = data[pos++];
|
||||
h = data[pos++];
|
||||
if (pos + w * h > num) break;
|
||||
if (pos + w * h > num)
|
||||
break;
|
||||
|
||||
width[i] = w;
|
||||
height[i] = h;
|
||||
@@ -309,8 +287,8 @@ gulong *get_best_icon (gulong *data, int icon_count, int num, int *iw, int *ih,
|
||||
int highest = 0;
|
||||
for (i = 0; i < icon_count; i++) {
|
||||
if (width[i] > highest) {
|
||||
icon_num = i;
|
||||
highest = width[i];
|
||||
icon_num = i;
|
||||
highest = width[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -319,44 +297,3 @@ gulong *get_best_icon (gulong *data, int icon_count, int num, int *iw, int *ih,
|
||||
*ih = height[icon_num];
|
||||
return icon_data[icon_num];
|
||||
}
|
||||
|
||||
|
||||
void get_text_size2(PangoFontDescription *font,
|
||||
int *height_ink,
|
||||
int *height,
|
||||
int *width,
|
||||
int panel_height,
|
||||
int panel_width,
|
||||
char *text,
|
||||
int len,
|
||||
PangoWrapMode wrap,
|
||||
PangoEllipsizeMode ellipsis)
|
||||
{
|
||||
PangoRectangle rect_ink, rect;
|
||||
|
||||
Pixmap pmap = XCreatePixmap (server.dsp, server.root_win, panel_height, panel_width, server.depth);
|
||||
|
||||
cairo_surface_t *cs = cairo_xlib_surface_create (server.dsp, pmap, server.visual, panel_height, panel_width);
|
||||
cairo_t *c = cairo_create (cs);
|
||||
|
||||
PangoLayout *layout = pango_cairo_create_layout (c);
|
||||
pango_layout_set_width(layout, panel_width * PANGO_SCALE);
|
||||
pango_layout_set_height(layout, panel_height * PANGO_SCALE);
|
||||
pango_layout_set_wrap(layout, wrap);
|
||||
pango_layout_set_ellipsize(layout, ellipsis);
|
||||
pango_layout_set_font_description (layout, font);
|
||||
pango_layout_set_text (layout, text, len);
|
||||
|
||||
pango_layout_get_pixel_extents(layout, &rect_ink, &rect);
|
||||
*height_ink = rect_ink.height;
|
||||
*height = rect.height;
|
||||
*width = rect.width;
|
||||
//printf("dimension : %d - %d\n", rect_ink.height, rect.height);
|
||||
|
||||
g_object_unref (layout);
|
||||
cairo_destroy (c);
|
||||
cairo_surface_destroy (cs);
|
||||
XFreePixmap (server.dsp, pmap);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -11,38 +11,30 @@
|
||||
|
||||
#include <glib.h>
|
||||
#include <pango/pangocairo.h>
|
||||
#include <X11/Xlib.h>
|
||||
|
||||
GSList *get_desktop_names();
|
||||
int get_current_desktop();
|
||||
void change_desktop(int desktop);
|
||||
|
||||
void set_active (Window win);
|
||||
void set_desktop (int desktop);
|
||||
void set_close (Window win);
|
||||
int server_get_current_desktop ();
|
||||
GSList *server_get_name_of_desktop ();
|
||||
void window_get_coordinates (Window win, int *x, int *y, int *w, int *h);
|
||||
int window_is_iconified (Window win);
|
||||
int window_is_urgent (Window win);
|
||||
int window_is_hidden (Window win);
|
||||
int window_is_active (Window win);
|
||||
int window_is_skip_taskbar (Window win);
|
||||
int get_icon_count (gulong *data, int num);
|
||||
gulong *get_best_icon (gulong *data, int icon_count, int num, int *iw, int *ih, int best_icon_size);
|
||||
void window_maximize_restore (Window win);
|
||||
void window_toggle_shade (Window win);
|
||||
int window_get_desktop (Window win);
|
||||
void windows_set_desktop (Window win, int desktop);
|
||||
int window_get_monitor (Window win);
|
||||
Window window_get_active ();
|
||||
Window get_active_window();
|
||||
|
||||
void get_text_size2(PangoFontDescription *font,
|
||||
int *height_ink,
|
||||
int *height,
|
||||
int *width,
|
||||
int panel_height,
|
||||
int panel_with,
|
||||
char *text,
|
||||
int len,
|
||||
PangoWrapMode wrap,
|
||||
PangoEllipsizeMode ellipsis);
|
||||
gboolean window_is_iconified(Window win);
|
||||
gboolean window_is_urgent(Window win);
|
||||
gboolean window_is_hidden(Window win);
|
||||
gboolean window_is_active(Window win);
|
||||
gboolean window_is_skip_taskbar(Window win);
|
||||
int get_window_desktop(Window win);
|
||||
int get_window_monitor(Window win);
|
||||
|
||||
void activate_window(Window win);
|
||||
void close_window(Window win);
|
||||
void get_window_coordinates(Window win, int *x, int *y, int *w, int *h);
|
||||
void toggle_window_maximized(Window win);
|
||||
void toggle_window_shade(Window win);
|
||||
void change_window_desktop(Window win, int desktop);
|
||||
|
||||
int get_icon_count(gulong *data, int num);
|
||||
gulong *get_best_icon(gulong *data, int icon_count, int num, int *iw, int *ih, int best_icon_size);
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user