Mercurial > pidgin
view console/libgnt/gntwidget.c @ 13873:77a50840d9e2
[gaim-migrate @ 16344]
Fix some bugs that Relan (resver) tracked down. Basically we were
attempting to convert various strings from some encoding to UTF8
twice. The strings were mostly in ICQ buddy info. He submitted
sf patch #1503955, but I like my approach better.
committer: Tailor Script <tailor@pidgin.im>
author | Mark Doliner <mark@kingant.net> |
---|---|
date | Mon, 26 Jun 2006 03:55:24 +0000 |
parents | 5642f4658b59 |
children | 0d0ab1e39d0a |
line wrap: on
line source
/* Stuff brutally ripped from Gflib */ #include "gntwidget.h" #include "gntutils.h" #include "gnt.h" enum { SIG_DESTROY, SIG_DRAW, SIG_GIVE_FOCUS, SIG_LOST_FOCUS, SIG_KEY_PRESSED, SIG_MAP, SIG_ACTIVATE, SIG_EXPOSE, SIG_SIZE_REQUEST, SIG_POSITION, SIGS }; static GObjectClass *parent_class = NULL; static guint signals[SIGS] = { 0 }; static void gnt_widget_init(GTypeInstance *instance, gpointer class) { GntWidget *widget = GNT_WIDGET(instance); widget->priv.name = NULL; DEBUG; } static void gnt_widget_map(GntWidget *widget) { /* Get some default size for the widget */ DEBUG; g_signal_emit(widget, signals[SIG_MAP], 0); GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_MAPPED); } static void gnt_widget_dispose(GObject *obj) { GntWidget *self = GNT_WIDGET(obj); if(!(GNT_WIDGET_FLAGS(self) & GNT_WIDGET_DESTROYING)) { GNT_WIDGET_SET_FLAGS(self, GNT_WIDGET_DESTROYING); g_signal_emit(self, signals[SIG_DESTROY], 0); GNT_WIDGET_UNSET_FLAGS(self, GNT_WIDGET_DESTROYING); } parent_class->dispose(obj); DEBUG; } static void gnt_widget_focus_change(GntWidget *widget) { if (GNT_WIDGET_FLAGS(widget) & GNT_WIDGET_MAPPED) gnt_widget_draw(widget); } static void gnt_widget_class_init(GntWidgetClass *klass) { GObjectClass *obj_class = G_OBJECT_CLASS(klass); parent_class = g_type_class_peek_parent(klass); obj_class->dispose = gnt_widget_dispose; klass->destroy = gnt_widget_destroy; klass->show = gnt_widget_show; klass->draw = gnt_widget_draw; klass->expose = gnt_widget_expose; klass->map = gnt_widget_map; klass->lost_focus = gnt_widget_focus_change; klass->gained_focus = gnt_widget_focus_change; klass->key_pressed = NULL; klass->activate = NULL; signals[SIG_DESTROY] = g_signal_new("destroy", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET(GntWidgetClass, destroy), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); signals[SIG_GIVE_FOCUS] = g_signal_new("gained-focus", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET(GntWidgetClass, gained_focus), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); signals[SIG_LOST_FOCUS] = g_signal_new("lost-focus", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET(GntWidgetClass, lost_focus), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); signals[SIG_ACTIVATE] = g_signal_new("activate", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET(GntWidgetClass, activate), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); signals[SIG_MAP] = g_signal_new("map", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET(GntWidgetClass, map), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); signals[SIG_DRAW] = g_signal_new("draw", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET(GntWidgetClass, draw), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); signals[SIG_EXPOSE] = g_signal_new("expose", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET(GntWidgetClass, expose), NULL, NULL, gnt_closure_marshal_VOID__INT_INT_INT_INT, G_TYPE_NONE, 4, G_TYPE_INT, G_TYPE_INT, G_TYPE_INT, G_TYPE_INT); signals[SIG_POSITION] = g_signal_new("position-set", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET(GntWidgetClass, set_position), NULL, NULL, gnt_closure_marshal_VOID__INT_INT, G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_INT); signals[SIG_SIZE_REQUEST] = g_signal_new("size_request", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET(GntWidgetClass, size_request), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); signals[SIG_KEY_PRESSED] = g_signal_new("key_pressed", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET(GntWidgetClass, key_pressed), NULL, NULL, gnt_closure_marshal_BOOLEAN__STRING, G_TYPE_BOOLEAN, 1, G_TYPE_STRING); DEBUG; } /****************************************************************************** * GntWidget API *****************************************************************************/ GType gnt_widget_get_gtype(void) { static GType type = 0; if(type == 0) { static const GTypeInfo info = { sizeof(GntWidgetClass), NULL, /* base_init */ NULL, /* base_finalize */ (GClassInitFunc)gnt_widget_class_init, NULL, /* class_finalize */ NULL, /* class_data */ sizeof(GntWidget), 0, /* n_preallocs */ gnt_widget_init, /* instance_init */ }; type = g_type_register_static(G_TYPE_OBJECT, "GntWidget", &info, G_TYPE_FLAG_ABSTRACT); } return type; } static void gnt_widget_take_focus(GntWidget *widget) { gnt_screen_take_focus(widget); } void gnt_widget_set_take_focus(GntWidget *widget, gboolean can) { if (can) GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_CAN_TAKE_FOCUS); else GNT_WIDGET_UNSET_FLAGS(widget, GNT_WIDGET_CAN_TAKE_FOCUS); } /** * gnt_widget_destroy: * @obj: The #GntWidget instance. * * Emits the "destroy" signal notifying all reference holders that they * should release @obj. */ void gnt_widget_destroy(GntWidget *obj) { g_return_if_fail(GNT_IS_WIDGET(obj)); gnt_widget_hide(obj); delwin(obj->window); if(!(GNT_WIDGET_FLAGS(obj) & GNT_WIDGET_DESTROYING)) g_object_run_dispose(G_OBJECT(obj)); DEBUG; } void gnt_widget_show(GntWidget *widget) { /* Draw the widget and take focus */ gnt_widget_draw(widget); if (GNT_WIDGET_FLAGS(widget) & GNT_WIDGET_CAN_TAKE_FOCUS) { gnt_widget_take_focus(widget); } } void gnt_widget_draw(GntWidget *widget) { /* Draw the widget */ DEBUG; if (!(GNT_WIDGET_FLAGS(widget) & GNT_WIDGET_MAPPED)) gnt_widget_map(widget); if (widget->window) { delwin(widget->window); } widget->window = newwin(widget->priv.height, widget->priv.width, widget->priv.y, widget->priv.x); wbkgd(widget->window, COLOR_PAIR(GNT_COLOR_NORMAL)); if (!(GNT_WIDGET_FLAGS(widget) & GNT_WIDGET_NO_BORDER)) { box(widget->window, 0, 0); } else werase(widget->window); #if 0 /* XXX: No shadow for now :( */ if (!(GNT_WIDGET_FLAGS(widget) & GNT_WIDGET_NO_SHADOW)) { widget->back = newwin(widget->priv.height, widget->priv.width, widget->priv.y + 1, widget->priv.x + 1); wbkgd(widget->back, COLOR_PAIR(GNT_COLOR_SHADOW)); werase(widget->back); mvwchgat(widget->back, 0, 0, widget->priv.height, A_REVERSE | A_BLINK, 0, 0); touchline(widget->back, 0, widget->priv.height); wrefresh(widget->back); } #endif wrefresh(widget->window); g_signal_emit(widget, signals[SIG_DRAW], 0); } gboolean gnt_widget_key_pressed(GntWidget *widget, const char *keys) { gboolean ret; if (!GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_CAN_TAKE_FOCUS)) return FALSE; g_signal_emit(widget, signals[SIG_KEY_PRESSED], 0, keys, &ret); return ret; } void gnt_widget_expose(GntWidget *widget, int x, int y, int width, int height) { g_signal_emit(widget, signals[SIG_EXPOSE], 0, x, y, width, height); } void gnt_widget_hide(GntWidget *widget) { int i; /* XXX: Currently it simply empties the window. Ideally, it will * detect what windows are immediately beneath this one, and cause * those windows to redraw themselves by emitting the approrpiate * expose signal. */ wbkgdset(widget->window, '\0' | COLOR_PAIR(GNT_COLOR_NORMAL)); werase(widget->window); wrefresh(widget->window); } void gnt_widget_set_position(GntWidget *wid, int x, int y) { /* XXX: Need to install properties for these and g_object_notify */ wid->priv.x = x; wid->priv.y = y; g_signal_emit(wid, signals[SIG_POSITION], 0, x, y); } void gnt_widget_get_position(GntWidget *wid, int *x, int *y) { if (x) *x = wid->priv.x; if (y) *y = wid->priv.y; } void gnt_widget_size_request(GntWidget *widget) { g_signal_emit(widget, signals[SIG_SIZE_REQUEST], 0); } void gnt_widget_get_size(GntWidget *wid, int *width, int *height) { if (width) *width = wid->priv.width; if (height) *height = wid->priv.height; } void gnt_widget_set_size(GntWidget *widget, int width, int height) { widget->priv.width = width; widget->priv.height = height; } gboolean gnt_widget_set_focus(GntWidget *widget, gboolean set) { if (!(GNT_WIDGET_FLAGS(widget) & GNT_WIDGET_CAN_TAKE_FOCUS)) return FALSE; if (set && !GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_HAS_FOCUS)) { g_signal_emit(widget->parent, signals[SIG_LOST_FOCUS], 0); GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_HAS_FOCUS); g_signal_emit(widget, signals[SIG_GIVE_FOCUS], 0); } else if (!set) { GNT_WIDGET_UNSET_FLAGS(widget, GNT_WIDGET_HAS_FOCUS); g_signal_emit(widget, signals[SIG_LOST_FOCUS], 0); } else return FALSE; return TRUE; } void gnt_widget_set_name(GntWidget *widget, const char *name) { g_free(widget->priv.name); widget->priv.name = g_strdup(name); } void gnt_widget_activate(GntWidget *widget) { g_signal_emit(widget, signals[SIG_ACTIVATE], 0); }