1 /* Copyright (C) 2011 Edward Der-Hua Liu, Hsin-Chu, Taiwan
2 *
3 * This library is free software; you can redistribute it and/or
4 * modify it under the terms of the GNU Lesser General Public
5 * License as published by the Free Software Foundation version 2.1
6 * of the License.
7 *
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public
14 * License along with this library; if not, write to the Free Software
15 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16 */
17
18 #include "hime.h"
19
timeout_destroy_window(GtkWidget * win)20 static gboolean timeout_destroy_window (GtkWidget *win) {
21 gtk_widget_destroy (win);
22 return FALSE;
23 }
24
25 #if TRAY_ENABLED
26 extern GtkStatusIcon *tray_icon;
27 extern GtkStatusIcon *icon_main;
28
29 extern gboolean is_exist_tray ();
30 extern gboolean is_exist_tray_double ();
31 #endif
32
create_win_message(char * icon,char * text,int duration)33 static void create_win_message (char *icon, char *text, int duration) {
34 GtkWidget *gwin_message = gtk_window_new (GTK_WINDOW_TOPLEVEL);
35 gtk_window_set_has_resize_grip (GTK_WINDOW (gwin_message), FALSE);
36 gtk_container_set_border_width (GTK_CONTAINER (gwin_message), 0);
37 gtk_widget_realize (gwin_message);
38 set_no_focus (gwin_message);
39
40 GtkWidget *hbox = gtk_hbox_new (FALSE, 0);
41 gtk_container_add (GTK_CONTAINER (gwin_message), hbox);
42
43 if (icon[0] != '-') {
44 GtkWidget *image = gtk_image_new_from_file (icon);
45 if (text[0] == '-') {
46 #if GTK_CHECK_VERSION(2, 91, 0)
47 GdkPixbuf *pixbuf = NULL;
48 GdkPixbufAnimation *anime = NULL;
49 switch (gtk_image_get_storage_type (GTK_IMAGE (image))) {
50 case GTK_IMAGE_PIXBUF:
51 pixbuf = gtk_image_get_pixbuf (GTK_IMAGE (image));
52 break;
53 case GTK_IMAGE_ANIMATION:
54 anime = gtk_image_get_animation (GTK_IMAGE (image));
55 pixbuf = gdk_pixbuf_animation_get_static_image (anime);
56 break;
57 default:
58 break;
59 }
60 cairo_surface_t *img = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, gdk_pixbuf_get_width (pixbuf), gdk_pixbuf_get_height (pixbuf));
61 cairo_t *cr = cairo_create (img);
62 gdk_cairo_set_source_pixbuf (cr, pixbuf, 0, 0);
63 cairo_paint (cr);
64 cairo_region_t *mask = gdk_cairo_region_create_from_surface (img);
65 gtk_widget_shape_combine_region (gwin_message, mask);
66 cairo_region_destroy (mask);
67 cairo_destroy (cr);
68 cairo_surface_destroy (img);
69 #else
70 GdkBitmap *bitmap = NULL;
71 gdk_pixbuf_render_pixmap_and_mask (gdk_pixbuf_new_from_file (icon, NULL), NULL, &bitmap, 128);
72 gtk_widget_shape_combine_mask (gwin_message, bitmap, 0, 0);
73 #endif
74 }
75 gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, FALSE, 0);
76 }
77
78 if (text[0] != '-') {
79 GtkWidget *label = gtk_label_new (text);
80 gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
81 }
82
83 gtk_widget_show_all (gwin_message);
84
85 int width, height;
86 get_win_size (gwin_message, &width, &height);
87
88 int ox = -1, oy;
89 #if TRAY_ENABLED
90 GdkRectangle rect;
91 GtkOrientation ori;
92 if ((is_exist_tray () && gtk_status_icon_get_geometry (tray_icon, NULL, &rect, &ori)) || (is_exist_tray_double () && gtk_status_icon_get_geometry (icon_main, NULL, &rect, &ori))) {
93 dbg ("rect %d,%d\n", rect.x, rect.y, rect.width, rect.height);
94 if (ori == GTK_ORIENTATION_HORIZONTAL) {
95 ox = rect.x;
96 if (rect.y > 100)
97 oy = rect.y - height;
98 else
99 oy = rect.y + rect.height;
100 } else {
101 oy = rect.y;
102 if (rect.x > 100)
103 ox = rect.x - width;
104 else
105 ox = rect.x + rect.width;
106 }
107 }
108 #endif
109 if (ox < 0) {
110 ox = dpy_xl - width;
111 oy = dpy_yl - height;
112 }
113
114 gtk_window_move (GTK_WINDOW (gwin_message), ox, oy);
115
116 g_timeout_add (duration, (GSourceFunc) timeout_destroy_window, gwin_message);
117 }
118
execute_message(char * message)119 void execute_message (char *message) {
120 char head[32];
121 char icon[128];
122 char text[128];
123 int duration = 3000;
124
125 icon[0] = text[0] = 0;
126
127 sscanf (message, "%s %s %s %d", head, icon, text, &duration);
128
129 create_win_message (icon, text, duration);
130 }
131