fixed icon on 64 bit system by benjaminfranzke

git-svn-id: http://tint2.googlecode.com/svn/trunk@151 121b4492-b84c-0410-8b4c-0d4edfb3f3cc
This commit is contained in:
lorthiois@bbsoft.fr 2009-07-26 13:46:50 +00:00
parent 54188b9c0c
commit 5017fae290
4 changed files with 146 additions and 148 deletions

View file

@ -1,3 +1,6 @@
2009-07-26
- fixed icon on 64 bit system by benjaminfranzke
2009-07-19 2009-07-19
- fixed systray crash by mart1987 - fixed systray crash by mart1987

View file

@ -1,6 +1,6 @@
# -*- Autoconf -*- # -*- Autoconf -*-
# Process this file with autoconf to produce a configure script. # Process this file with autoconf to produce a configure script.
AC_INIT([tint2], [0.7], [http://code.google.com/p/tint2/issues]) AC_INIT([tint2], [0.7.1], [http://code.google.com/p/tint2/issues])
LT_INIT LT_INIT
AM_INIT_AUTOMAKE AM_INIT_AUTOMAKE

View file

@ -36,48 +36,48 @@
Task *add_task (Window win) Task *add_task (Window win)
{ {
if (!win) return 0; if (!win) return 0;
if (window_is_hidden(win)) return 0; if (window_is_hidden(win)) return 0;
int monitor; int monitor;
Task new_tsk; Task new_tsk;
new_tsk.win = win; new_tsk.win = win;
new_tsk.area.panel = &panel1[0]; new_tsk.area.panel = &panel1[0];
new_tsk.desktop = window_get_desktop (win); new_tsk.desktop = window_get_desktop (win);
if (nb_panel > 1) monitor = window_get_monitor (win); if (nb_panel > 1) monitor = window_get_monitor (win);
else monitor = 0; else monitor = 0;
// allocate only one title and one icon // allocate only one title and one icon
// even with task_on_all_desktop and with task_on_all_panel // even with task_on_all_desktop and with task_on_all_panel
new_tsk.title = 0; new_tsk.title = 0;
new_tsk.icon_data = 0; new_tsk.icon_data = 0;
get_title(&new_tsk); get_title(&new_tsk);
get_icon(&new_tsk); get_icon(&new_tsk);
//printf("task %s : desktop %d, monitor %d\n", new_tsk->title, desktop, monitor); //printf("task %s : desktop %d, monitor %d\n", new_tsk->title, desktop, monitor);
XSelectInput (server.dsp, new_tsk.win, PropertyChangeMask|StructureNotifyMask); XSelectInput (server.dsp, new_tsk.win, PropertyChangeMask|StructureNotifyMask);
Taskbar *tskbar; Taskbar *tskbar;
Task *new_tsk2=0; Task *new_tsk2=0;
int i, j; int i, j;
for (i=0 ; i < nb_panel ; i++) { for (i=0 ; i < nb_panel ; i++) {
for (j=0 ; j < panel1[i].nb_desktop ; j++) { for (j=0 ; j < panel1[i].nb_desktop ; j++) {
if (new_tsk.desktop != ALLDESKTOP && new_tsk.desktop != j) continue; if (new_tsk.desktop != ALLDESKTOP && new_tsk.desktop != j) continue;
if (nb_panel > 1 && panel1[i].monitor != monitor) continue; if (nb_panel > 1 && panel1[i].monitor != monitor) continue;
tskbar = &panel1[i].taskbar[j]; tskbar = &panel1[i].taskbar[j];
new_tsk2 = malloc(sizeof(Task)); new_tsk2 = malloc(sizeof(Task));
memcpy(&new_tsk2->area, &panel1[i].g_task.area, sizeof(Area)); memcpy(&new_tsk2->area, &panel1[i].g_task.area, sizeof(Area));
new_tsk2->area.parent = tskbar; new_tsk2->area.parent = tskbar;
new_tsk2->win = new_tsk.win; new_tsk2->win = new_tsk.win;
new_tsk2->desktop = new_tsk.desktop; new_tsk2->desktop = new_tsk.desktop;
new_tsk2->title = new_tsk.title; new_tsk2->title = new_tsk.title;
new_tsk2->icon_data = new_tsk.icon_data; new_tsk2->icon_data = new_tsk.icon_data;
new_tsk2->icon_width = new_tsk.icon_width; new_tsk2->icon_width = new_tsk.icon_width;
new_tsk2->icon_height = new_tsk.icon_height; new_tsk2->icon_height = new_tsk.icon_height;
tskbar->area.list = g_slist_append(tskbar->area.list, new_tsk2); tskbar->area.list = g_slist_append(tskbar->area.list, new_tsk2);
tskbar->area.resize = 1; tskbar->area.resize = 1;
//printf("add_task panel %d, desktop %d, task %s\n", i, j, new_tsk2->title); //printf("add_task panel %d, desktop %d, task %s\n", i, j, new_tsk2->title);
} }
} }
@ -87,10 +87,10 @@ Task *add_task (Window win)
void remove_task (Task *tsk) void remove_task (Task *tsk)
{ {
if (!tsk) return; if (!tsk) return;
Window win = tsk->win; Window win = tsk->win;
int desktop = tsk->desktop; int desktop = tsk->desktop;
// free title and icon just for the first task // free title and icon just for the first task
// even with task_on_all_desktop and with task_on_all_panel // even with task_on_all_desktop and with task_on_all_panel
@ -101,8 +101,8 @@ void remove_task (Task *tsk)
free (tsk->icon_data); free (tsk->icon_data);
int i, j; int i, j;
Task *tsk2; Task *tsk2;
Taskbar *tskbar; Taskbar *tskbar;
for (i=0 ; i < nb_panel ; i++) { for (i=0 ; i < nb_panel ; i++) {
for (j=0 ; j < panel1[i].nb_desktop ; j++) { for (j=0 ; j < panel1[i].nb_desktop ; j++) {
if (desktop != ALLDESKTOP && desktop != j) continue; if (desktop != ALLDESKTOP && desktop != j) continue;
@ -114,7 +114,7 @@ void remove_task (Task *tsk)
l0 = l0->next; l0 = l0->next;
if (win == tsk2->win) { if (win == tsk2->win) {
tskbar->area.list = g_slist_remove(tskbar->area.list, tsk2); tskbar->area.list = g_slist_remove(tskbar->area.list, tsk2);
tskbar->area.resize = 1; tskbar->area.resize = 1;
if (tsk2 == task_active) if (tsk2 == task_active)
task_active = 0; task_active = 0;
@ -128,69 +128,77 @@ void remove_task (Task *tsk)
} }
} }
} }
} }
void get_title(Task *tsk) void get_title(Task *tsk)
{ {
Panel *panel = tsk->area.panel; Panel *panel = tsk->area.panel;
char *title, *name; char *title, *name;
if (!panel->g_task.text) return; if (!panel->g_task.text) return;
name = server_get_property (tsk->win, server.atom._NET_WM_VISIBLE_NAME, server.atom.UTF8_STRING, 0); name = server_get_property (tsk->win, server.atom._NET_WM_VISIBLE_NAME, server.atom.UTF8_STRING, 0);
if (!name || !strlen(name)) { if (!name || !strlen(name)) {
name = server_get_property (tsk->win, server.atom._NET_WM_NAME, server.atom.UTF8_STRING, 0); name = server_get_property (tsk->win, server.atom._NET_WM_NAME, server.atom.UTF8_STRING, 0);
if (!name || !strlen(name)) { if (!name || !strlen(name)) {
name = server_get_property (tsk->win, server.atom.WM_NAME, XA_STRING, 0); name = server_get_property (tsk->win, server.atom.WM_NAME, XA_STRING, 0);
if (!name || !strlen(name)) { if (!name || !strlen(name)) {
name = malloc(10); name = malloc(10);
strcpy(name, "Untitled"); strcpy(name, "Untitled");
} }
} }
} }
// add space before title // add space before title
title = malloc(strlen(name)+2); title = malloc(strlen(name)+2);
if (panel->g_task.icon) strcpy(title, " "); if (panel->g_task.icon) strcpy(title, " ");
else title[0] = 0; else title[0] = 0;
strcat(title, name); strcat(title, name);
if (name) XFree (name); if (name) XFree (name);
tsk->area.redraw = 1; tsk->area.redraw = 1;
if (tsk->title) if (tsk->title)
free(tsk->title); free(tsk->title);
tsk->title = title; tsk->title = title;
} }
void get_icon (Task *tsk) void get_icon (Task *tsk)
{ {
Panel *panel = tsk->area.panel; Panel *panel = tsk->area.panel;
if (!panel->g_task.icon) return; if (!panel->g_task.icon) return;
if (tsk->icon_data) { if (tsk->icon_data) {
free (tsk->icon_data); free (tsk->icon_data);
tsk->icon_data = 0; tsk->icon_data = 0;
} }
tsk->area.redraw = 1; tsk->area.redraw = 1;
long *data; long *data;
int num; int num;
data = server_get_property (tsk->win, server.atom._NET_WM_ICON, XA_CARDINAL, &num); data = server_get_property (tsk->win, server.atom._NET_WM_ICON, XA_CARDINAL, &num);
if (data) { if (data) {
// get ARGB icon // get ARGB icon
int w, h; int w, h;
long *tmp_data; long *tmp_data;
tmp_data = get_best_icon (data, get_icon_count (data, num), num, &w, &h, panel->g_task.icon_size1); tmp_data = get_best_icon (data, get_icon_count (data, num), num, &w, &h, panel->g_task.icon_size1);
tsk->icon_width = w; tsk->icon_width = w;
tsk->icon_height = h; tsk->icon_height = h;
tsk->icon_data = malloc (w * h * sizeof (long)); // DATA32 is provided by imlib2
memcpy (tsk->icon_data, tmp_data, w * h * sizeof (long)); tsk->icon_data = malloc (w * h * sizeof (DATA32));
XFree (data); #ifdef __x86_64__
int length = tsk->icon_width * tsk->icon_height;
int i;
for (i = 0; i < length; ++i)
tsk->icon_data[i] = tmp_data[i];
#else
memcpy (tsk->icon_data, tmp_data, w * h * sizeof (DATA32));
#endif
XFree (data);
} }
else { else {
// get Pixmap icon // get Pixmap icon
@ -216,8 +224,8 @@ void get_icon (Task *tsk)
} }
tsk->icon_width = imlib_image_get_width(); tsk->icon_width = imlib_image_get_width();
tsk->icon_height = imlib_image_get_height(); tsk->icon_height = imlib_image_get_height();
tsk->icon_data = malloc (tsk->icon_width * tsk->icon_height * sizeof (long)); tsk->icon_data = malloc (tsk->icon_width * tsk->icon_height * sizeof (DATA32));
memcpy (tsk->icon_data, data, tsk->icon_width * tsk->icon_height * sizeof (long)); memcpy (tsk->icon_data, data, tsk->icon_width * tsk->icon_height * sizeof (DATA32));
imlib_free_image(); imlib_free_image();
} }
XFree(hints); XFree(hints);
@ -228,71 +236,58 @@ void get_icon (Task *tsk)
void draw_task_icon (Task *tsk, int text_width, int active) void draw_task_icon (Task *tsk, int text_width, int active)
{ {
if (tsk->icon_data == 0) return; if (tsk->icon_data == 0) return;
Pixmap *pmap = (active == 0) ? (&tsk->area.pix.pmap) : (&tsk->area.pix_active.pmap); Pixmap *pmap = (active == 0) ? (&tsk->area.pix.pmap) : (&tsk->area.pix_active.pmap);
/* Find pos */ /* Find pos */
int pos_x; int pos_x;
Panel *panel = (Panel*)tsk->area.panel; Panel *panel = (Panel*)tsk->area.panel;
if (panel->g_task.centered) { if (panel->g_task.centered) {
if (panel->g_task.text) if (panel->g_task.text)
pos_x = (tsk->area.width - text_width - panel->g_task.icon_size1) / 2; pos_x = (tsk->area.width - text_width - panel->g_task.icon_size1) / 2;
else else
pos_x = (tsk->area.width - panel->g_task.icon_size1) / 2; pos_x = (tsk->area.width - panel->g_task.icon_size1) / 2;
} }
else pos_x = panel->g_task.area.paddingxlr + panel->g_task.area.pix.border.width; else pos_x = panel->g_task.area.paddingxlr + panel->g_task.area.pix.border.width;
/* Render */ /* Render */
Imlib_Image icon; Imlib_Image icon;
Imlib_Color_Modifier cmod; Imlib_Color_Modifier cmod;
DATA8 red[256], green[256], blue[256], alpha[256]; DATA8 red[256], green[256], blue[256], alpha[256];
// TODO: cpu improvement : compute only when icon changed icon = imlib_create_image_using_data (tsk->icon_width, tsk->icon_height, tsk->icon_data);
DATA32 *data; imlib_context_set_image (icon);
/* do we have 64bit? => long = 8bit */ imlib_context_set_drawable (*pmap);
if (sizeof(long) != 4) {
int length = tsk->icon_width * tsk->icon_height;
data = malloc(sizeof(DATA32) * length);
int i;
for (i = 0; i < length; ++i)
data[i] = tsk->icon_data[i];
}
else data = (DATA32 *) tsk->icon_data;
icon = imlib_create_image_using_data (tsk->icon_width, tsk->icon_height, data); cmod = imlib_create_color_modifier ();
imlib_context_set_image (icon); imlib_context_set_color_modifier (cmod);
imlib_context_set_drawable (*pmap); imlib_image_set_has_alpha (1);
imlib_get_color_modifier_tables (red, green, blue, alpha);
cmod = imlib_create_color_modifier (); int i, opacity;
imlib_context_set_color_modifier (cmod); opacity = (active == 0) ? (255*panel->g_task.font.alpha) : (255*panel->g_task.font_active.alpha);
imlib_image_set_has_alpha (1); for (i = 127; i < 256; i++) alpha[i] = opacity;
imlib_get_color_modifier_tables (red, green, blue, alpha);
int i, opacity; imlib_set_color_modifier_tables (red, green, blue, alpha);
opacity = (active == 0) ? (255*panel->g_task.font.alpha) : (255*panel->g_task.font_active.alpha);
for (i = 127; i < 256; i++) alpha[i] = opacity;
imlib_set_color_modifier_tables (red, green, blue, alpha); //imlib_render_image_on_drawable (pos_x, pos_y);
imlib_render_image_on_drawable_at_size (pos_x, panel->g_task.icon_posy, panel->g_task.icon_size1, panel->g_task.icon_size1);
//imlib_render_image_on_drawable (pos_x, pos_y); imlib_free_color_modifier ();
imlib_render_image_on_drawable_at_size (pos_x, panel->g_task.icon_posy, panel->g_task.icon_size1, panel->g_task.icon_size1); imlib_free_image ();
imlib_free_color_modifier ();
imlib_free_image ();
if (sizeof(long) != 4) free(data);
} }
void draw_task (void *obj, cairo_t *c, int active) void draw_task (void *obj, cairo_t *c, int active)
{ {
Task *tsk = obj; Task *tsk = obj;
PangoLayout *layout; PangoLayout *layout;
config_color *config_text; config_color *config_text;
int width=0, height; int width=0, height;
Panel *panel = (Panel*)tsk->area.panel; Panel *panel = (Panel*)tsk->area.panel;
if (panel->g_task.text) { if (panel->g_task.text) {
/* Layout */ /* Layout */
layout = pango_cairo_create_layout (c); layout = pango_cairo_create_layout (c);
pango_layout_set_font_description (layout, panel->g_task.font_desc); pango_layout_set_font_description (layout, panel->g_task.font_desc);
@ -325,11 +320,11 @@ void draw_task (void *obj, cairo_t *c, int active)
pango_cairo_show_layout (c, layout); pango_cairo_show_layout (c, layout);
} }
g_object_unref (layout); g_object_unref (layout);
} }
if (panel->g_task.icon) { if (panel->g_task.icon) {
// icon use same opacity as text // icon use same opacity as text
draw_task_icon (tsk, width, active); draw_task_icon (tsk, width, active);
} }
} }

View file

@ -15,38 +15,38 @@
// -------------------------------------------------- // --------------------------------------------------
// global task parameter // global task parameter
typedef struct { typedef struct {
Area area; Area area;
int text; int text;
int icon; int icon;
int centered; int centered;
int icon_posy; int icon_posy;
int icon_size1; int icon_size1;
int maximum_width; int maximum_width;
int maximum_height; int maximum_height;
// starting position for text ~ task_padding + task_border + icon_size // starting position for text ~ task_padding + task_border + icon_size
double text_posx, text_posy; double text_posx, text_posy;
int font_shadow; int font_shadow;
PangoFontDescription *font_desc; PangoFontDescription *font_desc;
config_color font; config_color font;
config_color font_active; config_color font_active;
} Global_task; } Global_task;
typedef struct { typedef struct {
// always start with area // always start with area
Area area; Area area;
// TODO: group task with list of windows here // TODO: group task with list of windows here
Window win; Window win;
int desktop; int desktop;
long *icon_data; unsigned int *icon_data;
int icon_width; int icon_width;
int icon_height; int icon_height;
char *title; char *title;
} Task; } Task;