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
- fixed systray crash by mart1987

View file

@ -1,6 +1,6 @@
# -*- Autoconf -*-
# 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
AM_INIT_AUTOMAKE

View file

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

View file

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