grim/guifications1

This should fix the Mdk 9.1 RPM building bug reported on the forums a while ago
/*
Guifications - The notification plugin to end all notification plugins!
Copyright (C) 2003 Gary Kramlich
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <glib.h>
#include <gtk/gtk.h>
#include <pango/pango.h>
#include <string.h>
#include "account.h"
#include "blist.h"
#include "gaim.h"
#include "prefs.h"
#include "prpl.h"
#include "debug.h"
#ifdef _WIN32
# include "win32dep.h"
#endif
#include "gf_utils.h"
#include "gf_types.h"
#include "gf_prefs.h"
/**********************************************************************/
void
gf_resize(GtkWidget *window, GtkWidget *box) {
if (window != NULL) {
gtk_window_resize(GTK_WINDOW(window), get_window_width(box), get_window_height(box));
gtk_window_move(GTK_WINDOW(window), get_window_x(window), get_window_y(window));
}
}
/**********************************************************************/
gint
get_window_x(GtkWidget *window) {
GtkRequisition req;
gtk_widget_size_request(window, &req);
switch(gaim_prefs_get_int(GF_PREF_BEHAVIOR_WINDOW_POS)) {
case window_position_nw:
case window_position_sw:
return gaim_prefs_get_int(GF_PREF_BEHAVIOR_X);;
break;
case window_position_ne:
case window_position_se:
return gdk_screen_width() - (req.width + gaim_prefs_get_int(GF_PREF_BEHAVIOR_X));
break;
}
return 0;
}
/**********************************************************************/
gint
get_window_y(GtkWidget *window) {
GtkRequisition req;
gtk_widget_size_request(window, &req);
switch(gaim_prefs_get_int(GF_PREF_BEHAVIOR_WINDOW_POS)) {
case window_position_ne:
case window_position_nw:
return gaim_prefs_get_int(GF_PREF_BEHAVIOR_Y);
break;
case window_position_se:
case window_position_sw:
return gdk_screen_height() - (req.height + gaim_prefs_get_int(GF_PREF_BEHAVIOR_Y));
break;
}
return 0;
}
/**********************************************************************/
gint
get_window_width(GtkWidget *box) {
GtkWidget *child;
GtkRequisition req;
GList *children;
gint new_size = 0;
children = gtk_container_get_children(GTK_CONTAINER(box));
if (gaim_prefs_get_bool(GF_PREF_BEHAVIOR_WINDOW_VERTICAL)) {
child = children->data;
gtk_widget_size_request(child, &req);
return req.width;
}
else {
while (children) {
child = children->data;
children = children->next;
gtk_widget_size_request(child, &req);
new_size += req.width;
}
g_list_free(children);
return new_size;
}
}
/**********************************************************************/
gint
get_window_height(GtkWidget *box) {
GtkWidget *child;
GtkRequisition req;
GList *children;
gint new_size = 0;
children = gtk_container_get_children(GTK_CONTAINER(box));
if (gaim_prefs_get_bool(GF_PREF_BEHAVIOR_WINDOW_VERTICAL)) {
while (children) {
child = children->data;
children = children->next;
gtk_widget_size_request(child, &req);
new_size += req.height;
}
g_list_free(children);
return new_size;
}
else {
child = children->data;
gtk_widget_size_request(child, &req);
return req.height;
}
}
/**********************************************************************/
void
get_image_size(dimensions *image_size) {
GdkPixbuf *image = NULL;
if (gaim_prefs_get_bool(GF_PREF_APPEARANCE_IMAGE)) {
image = gdk_pixbuf_new_from_file(gaim_prefs_get_string(GF_PREF_APPEARANCE_IMAGE_FILE), NULL);
if (image == NULL) {
gaim_prefs_set_bool(GF_PREF_APPEARANCE_IMAGE, FALSE);
gaim_prefs_set_string(GF_PREF_APPEARANCE_IMAGE_FILE, "");
image_size->width = 140;
image_size->height = 120;
}
else {
image_size->width = gdk_pixbuf_get_width(image);
image_size->height = gdk_pixbuf_get_height(image);
g_object_unref(image);
}
}
else {
image_size->width = 140;
image_size->height = 120;
}
}
/**********************************************************************/
void
get_zoom_size(dimensions image_size, dimensions *zoom_size) {
gfloat width = 0, height = 0;
gfloat owidth = image_size.width, oheight = image_size.height;
switch(gaim_prefs_get_int(GF_PREF_BEHAVIOR_ZOOM)) {
case window_zoom_200:
width = owidth * 2.0f;
height = oheight * 2.0f;
break;
case window_zoom_175:
width = owidth * 1.75f;
height = oheight * 1.75f;
break;
case window_zoom_150:
width = owidth * 1.5f;
height = oheight * 1.5f;
break;
case window_zoom_125:
width = owidth * 1.25f;
height = oheight * 1.25f;
break;
case window_zoom_75:
width = owidth * 0.75f;
height = oheight * 0.75f;
break;
case window_zoom_50:
width = owidth * 0.5f;
height = oheight * 0.5f;
break;
case window_zoom_25:
width = owidth * 0.25f;
height = oheight * 0.25f;
break;
case window_zoom_100:
default:
width = owidth;
height = oheight;
}
zoom_size->width = width;
zoom_size->height = height;
}
/**********************************************************************/
void
clip_layout(PangoLayout **layout, gboolean use_color, const gchar *text_x, const gchar *text_color) {
PangoLayout *lay = (*layout), *ellipsis = NULL;
gboolean loop = TRUE;
const gchar *text = NULL;
gchar *new_text = NULL, *left_text = NULL, *right_text = NULL;
gint width = 0, ewidth = 0, offset = 0, mid = 0;
dimensions dim;
offset = gaim_prefs_get_int(text_x);
get_image_size(&dim);
ellipsis = pango_layout_copy(lay);
pango_layout_set_text(ellipsis, "...", -1);
pango_layout_get_pixel_size(ellipsis, &ewidth, NULL);
g_object_unref(G_OBJECT(ellipsis));
pango_layout_get_pixel_size(lay, &width, NULL);
if ((width + offset) > dim.width) {
switch (gaim_prefs_get_int(GF_PREF_APPEARANCE_TEXT_CLIPPING)) {
case text_clipping_truncate:
while (loop) {
pango_layout_get_pixel_size(lay, &width, NULL);
if ((width + offset) <= dim.width)
loop = FALSE;
else {
text = pango_layout_get_text(lay);
new_text = g_strndup(text, strlen(text) - 1);
pango_layout_set_text(lay, new_text, -1);
g_free(new_text);
}
}
break;
case text_clipping_ellipsis_start:
while (loop) {
pango_layout_get_pixel_size(lay, &width, NULL);
if ((width + offset + ewidth) <= dim.width)
loop = FALSE;
else {
text = pango_layout_get_text(lay);
new_text = g_strrndup(text, strlen(text) - 1);
pango_layout_set_text(lay, new_text, -1);
g_free(new_text);
}
}
text = pango_layout_get_text(lay);
new_text = g_strdup_printf("...%s", text);
pango_layout_set_text(lay, new_text, -1);
g_free(new_text);
break;
case text_clipping_ellipsis_middle:
while (loop) {
pango_layout_get_pixel_size(lay, &width, NULL);
if ((width + offset + ewidth) <= dim.width)
loop = FALSE;
else {
text = pango_layout_get_text(lay);
mid = strlen(text) / 2;
if (is_even(strlen(text))) {
left_text = g_strndup(text, mid);
right_text = g_strrndup(text, mid - 1);
}
else {
left_text = g_strndup(text, mid);
right_text = g_strrndup(text, mid);
}
new_text = g_strdup_printf("%s%s", left_text, right_text);
g_free(left_text);
g_free(right_text);
pango_layout_set_text(lay, new_text, -1);
g_free(new_text);
}
}
text = pango_layout_get_text(lay);
mid = strlen(text) / 2;
if(is_even(strlen(text))) {
left_text = g_strndup(text, mid);
right_text = g_strrndup(text, mid - 1);
} else {
left_text = g_strndup(text, mid);
right_text = g_strrndup(text, mid);
}
new_text = g_strdup_printf("%s...%s", left_text, right_text);
g_free(left_text);
g_free(right_text);
pango_layout_set_text(lay, new_text, -1);
g_free(new_text);
break;
case text_clipping_ellipsis_end:
while (loop) {
pango_layout_get_pixel_size(lay, &width, NULL);
if ((width + offset + ewidth) <= dim.width)
loop = FALSE;
else {
text = pango_layout_get_text(lay);
new_text = g_strndup(text, strlen(text) - 1);
pango_layout_set_text(lay, new_text, -1);
g_free(new_text);
}
}
text = pango_layout_get_text(lay);
new_text = g_strdup_printf("%s...", text);
pango_layout_set_text(lay, new_text, -1);
g_free(new_text);
break;
}
}
text = pango_layout_get_text(lay);
new_text = g_markup_escape_text(text, -1);
pango_layout_set_text(lay, new_text, -1);
g_free(new_text);
set_color(&lay, use_color, text_color);
}
/**********************************************************************/
gchar *
g_strrndup(const gchar *src, gint n) {
gchar *dest = g_malloc(strlen(src));
gint i = 0, j = 0;
for (i = strlen(src) - n; i < strlen(src); i++) {
dest[j] = src[i];
j++;
}
dest[j] = '\0';
return dest;
}
/**********************************************************************/
void
set_color(PangoLayout **layout, gboolean custom_color, const gchar *pref) {
PangoLayout *lay = (*layout);
const gchar *text;
text = pango_layout_get_text(lay);
if (custom_color)
pango_layout_set_markup(lay, set_text_color(text, pref), -1);
else
pango_layout_set_markup(lay, g_strdup_printf("<span foreground=\"%s\">%s</span>", "#000000000000", text), -1);
}
/**********************************************************************/
gchar *
set_text_color(const gchar *text, const gchar *pref) {
gchar *ret = NULL;
ret = g_strdup_printf("<span foreground=\"%s\">%s</span>", gaim_prefs_get_string(pref), text);
return ret;
}
/**********************************************************************/
gint
get_icon_size() {
switch (gaim_prefs_get_int(GF_PREF_APPEARANCE_PROT_SIZE)) {
case icon_size_tiny: return 16; break;
case icon_size_small: return 24; break;
case icon_size_normal: return 48; break;
case icon_size_large: return 96; break;
case icon_size_huge: return 144; break;
}
return 0;
}
/**********************************************************************/
void
get_text_pos(gint *x, gint *y, gboolean line, PangoLayout *layout) {
dimensions dim;
gint height, width;
gint dhh, dhw;
gint hh, hw;
gint ox, oy;
gint ohx, ohy;
gint north, east, south, west, lat, lon;
get_image_size(&dim);
pango_layout_get_pixel_size(layout, &width, &height);
dhh = dim.height / 2;
dhw = dim.width / 2;
hh = height / 2;
hw = width / 2;
ox = gaim_prefs_get_int(GF_PREF_APPEARANCE_TEXT_X);
oy = gaim_prefs_get_int(GF_PREF_APPEARANCE_TEXT_Y);
ohx = ox / 2;
ohy = oy / 2;
north = line ? oy: height + oy;
east = dim.width - (width + ox);
south = line ? dim.height - (height * 2 + oy): dim.height - (height + oy);
west = ox;
lat = line ? dhh - (height + ohy): dhh + ohy; /* y */
lon = dhw - (hw + ohx); /* x */
switch (gaim_prefs_get_int(GF_PREF_APPEARANCE_TEXT_POS)) {
case item_position_nw: (*x) = west; (*y) = north; break;
case item_position_n: (*x) = lon; (*y) = north; break;
case item_position_ne: (*x) = east; (*y) = north; break;
case item_position_w: (*x) = west; (*y) = lat; break;
case item_position_c: (*x) = lon; (*y) = lat; break;
case item_position_e: (*x) = east; (*y) = lat; break;
case item_position_sw: (*x) = west; (*y) = south; break;
case item_position_s: (*x) = lon; (*y) = south; break;
case item_position_se: (*x) = east; (*y) = south; break;
}
}
/**********************************************************************/
void
get_icon_pos(gint *x, gint *y) {
dimensions dim;
gint height, width;
gint dhh, dhw;
gint hh, hw;
gint ox, oy;
gint ohx, ohy;
gint north, east, south, west, lat, lon;
get_image_size(&dim);
dhh = dim.height / 2;
dhw = dim.width / 2;
width = height = get_icon_size();
hw = hh = width / 2;
ox = gaim_prefs_get_int(GF_PREF_APPEARANCE_PROT_X);
oy = gaim_prefs_get_int(GF_PREF_APPEARANCE_PROT_Y);
ohx = ox / 2;
ohy = oy / 2;
north = oy;
east = dim.width - (width + ox);
south = dim.height - (height + oy);
west = ox;
lat = dhh - (hh + ohy); /* y */
lon = dhw - (hw + ohx); /* x */
switch (gaim_prefs_get_int(GF_PREF_APPEARANCE_PROT_POS)) {
case item_position_nw: (*x) = west; (*y) = north; break;
case item_position_n: (*x) = lon; (*y) = north; break;
case item_position_ne: (*x) = east; (*y) = north; break;
case item_position_w: (*x) = west; (*y) = lat; break;
case item_position_c: (*x) = lon; (*y) = lat; break;
case item_position_e: (*x) = east; (*y) = lat; break;
case item_position_sw: (*x) = west; (*y) = south; break;
case item_position_s: (*x) = lon; (*y) = south; break;
case item_position_se: (*x) = east; (*y) = south; break;
}
}
/**********************************************************************/
gboolean
is_even(gint number) {
if ((number & 1) == 1)
return FALSE;
else
return TRUE;
}
/**********************************************************************/