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