Cleanup indentation with clang-format and changed a few variable names

This commit is contained in:
o9000
2015-11-20 23:28:37 +01:00
parent c0e62e2e79
commit 4a6937826c
51 changed files with 4145 additions and 3789 deletions

View File

@@ -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);
}

View File

@@ -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);

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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;

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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