2
* Copyright © 2011 Canonical Ltd.
4
* This library is free software; you can redistribute it and/or
5
* modify it under the terms of the GNU Lesser General Public
6
* License as published by the Free Software Foundation; either
7
* version 2 of the License, or (at your option) any later version.
9
* This library is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
* Lesser General Public License for more details.
14
* You should have received a copy of the GNU Lesser General Public
15
* License along with this library; if not, write to the
16
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17
* Boston, MA 02111-1307, USA.
20
* Sam Spilsbury <sam.spilsbury@canonical.com>
23
#include "gtk-window-decorator.h"
25
typedef struct _decor_frame_type_info
27
create_frame_proc create_func;
28
destroy_frame_proc destroy_func;
29
} decor_frame_type_info_t;
31
GHashTable *frame_info_table;
32
GHashTable *frames_table;
35
decor_frame_refresh (decor_frame_t *frame)
37
decor_shadow_options_t active_o, inactive_o;
38
decor_shadow_info_t *info;
40
gwd_decor_frame_ref (frame);
42
update_style (frame->style_window_rgba);
43
update_style (frame->style_window_rgb);
45
gchar *str = settings->font;
47
set_frame_scale (frame, str);
51
frame_update_titlebar_font (frame);
53
if (strcmp (frame->type, "switcher") != 0 &&
54
strcmp (frame->type, "bare") != 0)
55
(*theme_update_border_extents) (frame);
57
(*theme_get_shadow) (frame, &active_o, TRUE);
58
(*theme_get_shadow) (frame, &inactive_o, FALSE);
60
info = malloc (sizeof (decor_shadow_info_t));
68
frame_update_shadow (frame, info, &active_o, &inactive_o);
70
gwd_decor_frame_unref (frame);
77
gwd_get_decor_frame (const gchar *frame_name)
79
decor_frame_t *frame = g_hash_table_lookup (frames_table, frame_name);
83
/* Frame not found, look up frame type in the frame types
84
* hash table and create a new one */
86
decor_frame_type_info_t *info = g_hash_table_lookup (frame_info_table, frame_name);
89
g_critical ("Could not find frame info %s in frame type table", frame_name);
91
frame = (*info->create_func) (frame_name);
94
g_critical ("Could not allocate frame %s", frame_name);
96
g_hash_table_insert (frames_table, frame->type, frame);
98
gwd_decor_frame_ref (frame);
100
decor_frame_refresh (frame);
103
gwd_decor_frame_ref (frame);
109
gwd_decor_frame_ref (decor_frame_t *frame)
116
gwd_decor_frame_unref (decor_frame_t *frame)
120
if (frame->refcount == 0)
122
decor_frame_type_info_t *info = g_hash_table_lookup (frame_info_table, frame->type);
125
g_critical ("Couldn't find %s in frame info table", frame->type);
127
if(!g_hash_table_remove (frames_table, frame->type))
128
g_critical ("Could not remove frame type %s from hash_table!", frame->type);
130
(*info->destroy_func) (frame);
136
gwd_decor_frame_add_type (const gchar *name,
137
create_frame_proc create_func,
138
destroy_frame_proc destroy_func)
140
decor_frame_type_info_t *frame_type = malloc (sizeof (decor_frame_type_info_t));
145
frame_type->create_func = create_func;
146
frame_type->destroy_func = destroy_func;
148
g_hash_table_insert (frame_info_table, strdup (name), frame_type);
154
gwd_decor_frame_remove_type (const gchar *name)
156
g_hash_table_remove (frame_info_table, name);
160
gwd_frames_foreach (GHFunc foreach_func,
163
g_hash_table_foreach (frames_table, foreach_func, user_data);
167
gwd_process_frames (GHFunc foreach_func,
168
const gchar *frame_keys[],
174
for (; i < frame_keys_num; i++)
176
gpointer frame = g_hash_table_lookup (frames_table, frame_keys[i]);
181
(*foreach_func) ((gpointer) frame_keys[i], frame, user_data);
186
destroy_frame_type (gpointer data)
188
decor_frame_type_info_t *info = (decor_frame_type_info_t *) data;
192
/* TODO: Destroy all frames with this type using
193
* the frame destroy function */
200
decor_frame_new (const gchar *type)
202
GdkScreen *gdkscreen = gdk_screen_get_default ();
203
GdkColormap *colormap;
204
decor_frame_t *frame = malloc (sizeof (decor_frame_t));
208
g_critical ("Couldn't allocate frame!");
212
frame->type = strdup (type);
214
frame->titlebar_height = 17;
215
frame->max_titlebar_height = 17;
216
frame->border_shadow_active = NULL;
217
frame->border_shadow_inactive = NULL;
218
frame->border_no_shadow = NULL;
219
frame->max_border_no_shadow = NULL;
220
frame->max_border_shadow_active = NULL;
221
frame->max_border_shadow_inactive = NULL;
222
frame->titlebar_font = NULL;
224
frame->style_window_rgba = gtk_window_new (GTK_WINDOW_POPUP);
226
colormap = gdk_screen_get_rgba_colormap (gdkscreen);
228
gtk_widget_set_colormap (frame->style_window_rgba, colormap);
230
gtk_widget_realize (frame->style_window_rgba);
232
gtk_widget_set_size_request (frame->style_window_rgba, 0, 0);
233
gtk_window_move (GTK_WINDOW (frame->style_window_rgba), -100, -100);
234
gtk_widget_show_all (frame->style_window_rgba);
236
frame->pango_context = gtk_widget_create_pango_context (frame->style_window_rgba);
238
g_signal_connect_data (frame->style_window_rgba, "style-set",
239
G_CALLBACK (style_changed),
240
(gpointer) frame->pango_context, 0, 0);
242
frame->style_window_rgb = gtk_window_new (GTK_WINDOW_POPUP);
244
colormap = gdk_screen_get_rgb_colormap (gdkscreen);
246
gtk_widget_set_colormap (frame->style_window_rgb, colormap);
248
gtk_widget_realize (frame->style_window_rgb);
250
gtk_widget_set_size_request (frame->style_window_rgb, 0, 0);
251
gtk_window_move (GTK_WINDOW (frame->style_window_rgb), -100, -100);
252
gtk_widget_show_all (frame->style_window_rgb);
254
g_signal_connect_data (frame->style_window_rgb, "style-set",
255
G_CALLBACK (style_changed),
256
(gpointer) frame->pango_context, 0, 0);
262
decor_frame_destroy (decor_frame_t *frame)
264
Display *xdisplay = gdk_x11_get_default_xdisplay ();
266
if (frame->border_shadow_active)
267
decor_shadow_destroy (xdisplay, frame->border_shadow_active);
269
if (frame->border_shadow_inactive)
270
decor_shadow_destroy (xdisplay, frame->border_shadow_inactive);
272
if (frame->border_no_shadow)
273
decor_shadow_destroy (xdisplay, frame->border_no_shadow);
275
if (frame->max_border_shadow_inactive)
276
decor_shadow_destroy (xdisplay, frame->max_border_shadow_inactive);
278
if (frame->max_border_no_shadow)
279
decor_shadow_destroy (xdisplay, frame->max_border_no_shadow);
281
if (frame->style_window_rgba)
282
gtk_widget_destroy (GTK_WIDGET (frame->style_window_rgba));
284
if (frame->style_window_rgb)
285
gtk_widget_destroy (GTK_WIDGET (frame->style_window_rgb));
287
if (frame->pango_context)
288
g_object_unref (G_OBJECT (frame->pango_context));
290
if (frame->titlebar_font)
291
pango_font_description_free (frame->titlebar_font);
300
initialize_decorations ()
302
frame_info_table = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, destroy_frame_type);
304
gwd_decor_frame_add_type ("normal", create_normal_frame, destroy_normal_frame);
305
gwd_decor_frame_add_type ("dialog", create_normal_frame, destroy_normal_frame);
306
gwd_decor_frame_add_type ("modal_dialog", create_normal_frame, destroy_normal_frame);
307
gwd_decor_frame_add_type ("menu", create_normal_frame, destroy_normal_frame);
308
gwd_decor_frame_add_type ("utility", create_normal_frame, destroy_normal_frame);
309
gwd_decor_frame_add_type ("switcher", create_switcher_frame, destroy_switcher_frame);
310
gwd_decor_frame_add_type ("bare", create_bare_frame, destroy_bare_frame);
312
frames_table = g_hash_table_new (g_str_hash, g_str_equal);