1 /*
2  *
3  *  Copyright (C) 2010-2011  Colomban Wendling <ban@herbesfolles.org>
4  *
5  *  This program is free software: you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation, either version 3 of the License, or
8  *  (at your option) any later version.
9  *
10  *  This program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
17  *
18  */
19 
20 #include "gwh-utils.h"
21 
22 #include <glib.h>
23 #include <gio/gio.h>
24 #include <gdk-pixbuf/gdk-pixbuf.h>
25 
26 
27 
28 GdkPixbuf *
gwh_pixbuf_new_from_uri(const gchar * uri,GError ** error)29 gwh_pixbuf_new_from_uri (const gchar *uri,
30                          GError     **error)
31 {
32   GdkPixbuf        *pixbuf = NULL;
33   GFile            *file;
34   GInputStream     *stream;
35 
36   file = g_file_new_for_uri (uri);
37   stream = G_INPUT_STREAM (g_file_read (file, NULL, error));
38   if (stream) {
39     GdkPixbufLoader  *loader;
40     guchar            buf[BUFSIZ];
41     gboolean          success = TRUE;
42 
43     loader = gdk_pixbuf_loader_new ();
44     while (success) {
45       gssize n_read;
46 
47       n_read = g_input_stream_read (stream, buf, sizeof (buf), NULL, error);
48       if (n_read < 0) {
49         success = FALSE;
50       } else {
51         if (n_read > 0) {
52           success = gdk_pixbuf_loader_write (loader, buf, (gsize)n_read, error);
53         }
54         if (success && (gsize)n_read < sizeof (buf)) {
55           success = gdk_pixbuf_loader_close (loader, error);
56           break;
57         }
58       }
59     }
60     if (success) {
61       pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
62       if (pixbuf) {
63         g_object_ref (pixbuf);
64       } else {
65         g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Unknown error");
66       }
67     }
68     g_object_unref (loader);
69     g_object_unref (stream);
70   }
71   g_object_unref (file);
72 
73   return pixbuf;
74 }
75 
76 /**
77  * gwh_get_window_geometry:
78  * @window: A #GtkWindow
79  * @default_x: Default position on X if not computable
80  * @default_y: Default position on Y if not computable
81  *
82  * Gets the XWindow-style geometry of a #GtkWindow
83  *
84  * Returns: A newly-allocated string representing the window geometry.
85  */
86 gchar *
gwh_get_window_geometry(GtkWindow * window,gint default_x,gint default_y)87 gwh_get_window_geometry (GtkWindow *window,
88                          gint       default_x,
89                          gint       default_y)
90 {
91   gint width;
92   gint height;
93   gint x;
94   gint y;
95 
96   gtk_window_get_size (window, &width, &height);
97   if (gtk_widget_get_visible (GTK_WIDGET (window))) {
98     gtk_window_get_position (window, &x, &y);
99   } else {
100     x = default_x;
101     y = default_y;
102   }
103 
104   return g_strdup_printf ("%dx%d%+d%+d", width, height, x, y);
105 }
106 
107 /**
108  * gwh_set_window_geometry:
109  * @window: A #GtkWindow
110  * @geometry: a XWindow-style geometry
111  * @x_: (out): return location for the window's X coordinate
112  * @y_: (out): return location for the window's Y coordinate
113  *
114  * Sets the geometry of a window from a XWindow-style geometry.
115  */
116 void
gwh_set_window_geometry(GtkWindow * window,const gchar * geometry,gint * x_,gint * y_)117 gwh_set_window_geometry (GtkWindow   *window,
118                          const gchar *geometry,
119                          gint        *x_,
120                          gint        *y_)
121 {
122   gint            width;
123   gint            height;
124   gint            x;
125   gint            y;
126   gchar           dummy;
127   GdkWindowHints  hints_mask = 0;
128 
129   g_return_if_fail (geometry != NULL);
130 
131   gtk_window_get_size (window, &width, &height);
132   gtk_window_get_position (window, &x, &y);
133   switch (sscanf (geometry, "%dx%d%d%d%c", &width, &height, &x, &y, &dummy)) {
134     case 4:
135     case 3:
136       if (x_) *x_ = x;
137       if (y_) *y_ = y;
138       gtk_window_move (window, x, y);
139       hints_mask |= GDK_HINT_USER_POS;
140       /* fallthrough */
141     case 2:
142     case 1:
143       gtk_window_resize (window, width, height);
144       hints_mask |= GDK_HINT_USER_SIZE;
145       break;
146 
147     default:
148       g_warning ("Invalid window geometry \"%s\"", geometry);
149   }
150   gtk_window_set_geometry_hints (window, NULL, NULL, hints_mask);
151 }
152