~focus-follows-mouse/ubuntu/oneiric/compiz/fix-883383

« back to all changes in this revision

Viewing changes to unity/unity_window_decorator/src/frames.c

  • Committer: Bazaar Package Importer
  • Author(s): Didier Roche
  • Date: 2011-07-19 08:00:29 UTC
  • mto: This revision was merged to the branch mainline in revision 235.
  • Revision ID: james.westby@ubuntu.com-20110719080029-lxt3wxch8uqkxro0
Tags: upstream-0.9.5.0
Import upstream version 0.9.5.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright © 2011 Canonical Ltd.
 
3
 *
 
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.
 
8
 *
 
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.
 
13
 *
 
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.
 
18
 *
 
19
 * Authored by:
 
20
 *     Sam Spilsbury <sam.spilsbury@canonical.com>
 
21
 */
 
22
 
 
23
#include "gtk-window-decorator.h"
 
24
 
 
25
typedef struct _decor_frame_type_info
 
26
{
 
27
    create_frame_proc create_func;
 
28
    destroy_frame_proc destroy_func;
 
29
} decor_frame_type_info_t;
 
30
 
 
31
GHashTable    *frame_info_table;
 
32
GHashTable    *frames_table;
 
33
 
 
34
void
 
35
decor_frame_refresh (decor_frame_t *frame)
 
36
{
 
37
    decor_shadow_options_t active_o, inactive_o;
 
38
    decor_shadow_info_t *info;
 
39
 
 
40
    gwd_decor_frame_ref (frame);
 
41
 
 
42
    update_style (frame->style_window_rgba);
 
43
    update_style (frame->style_window_rgb);
 
44
 
 
45
    gchar *str = settings->font;
 
46
 
 
47
    set_frame_scale (frame, str);
 
48
 
 
49
    str = NULL;
 
50
 
 
51
    frame_update_titlebar_font (frame);
 
52
 
 
53
    if (strcmp (frame->type, "switcher") != 0 &&
 
54
        strcmp (frame->type, "bare") != 0)
 
55
        (*theme_update_border_extents) (frame);
 
56
 
 
57
    (*theme_get_shadow) (frame, &active_o, TRUE);
 
58
    (*theme_get_shadow) (frame, &inactive_o, FALSE);
 
59
 
 
60
    info = malloc (sizeof (decor_shadow_info_t));
 
61
 
 
62
    if (!info)
 
63
        return;
 
64
 
 
65
    info->frame = frame;
 
66
    info->state = 0;
 
67
 
 
68
    frame_update_shadow (frame, info, &active_o, &inactive_o);
 
69
 
 
70
    gwd_decor_frame_unref (frame);
 
71
 
 
72
    free (info);
 
73
    info = NULL;
 
74
}
 
75
 
 
76
decor_frame_t *
 
77
gwd_get_decor_frame (const gchar *frame_name)
 
78
{
 
79
    decor_frame_t *frame = g_hash_table_lookup (frames_table, frame_name);
 
80
 
 
81
    if (!frame)
 
82
    {
 
83
        /* Frame not found, look up frame type in the frame types
 
84
         * hash table and create a new one */
 
85
 
 
86
        decor_frame_type_info_t *info = g_hash_table_lookup (frame_info_table, frame_name);
 
87
 
 
88
        if (!info)
 
89
            g_critical ("Could not find frame info %s in frame type table", frame_name);
 
90
 
 
91
        frame = (*info->create_func) (frame_name);
 
92
 
 
93
        if (!frame)
 
94
            g_critical ("Could not allocate frame %s", frame_name);
 
95
 
 
96
        g_hash_table_insert (frames_table, frame->type, frame);
 
97
 
 
98
        gwd_decor_frame_ref (frame);
 
99
 
 
100
        decor_frame_refresh (frame);
 
101
    }
 
102
    else
 
103
        gwd_decor_frame_ref (frame);
 
104
 
 
105
    return frame;
 
106
}
 
107
 
 
108
decor_frame_t *
 
109
gwd_decor_frame_ref (decor_frame_t *frame)
 
110
{
 
111
    frame->refcount++;
 
112
    return frame;
 
113
}
 
114
 
 
115
decor_frame_t *
 
116
gwd_decor_frame_unref (decor_frame_t *frame)
 
117
{
 
118
    frame->refcount--;
 
119
 
 
120
    if (frame->refcount == 0)
 
121
    {
 
122
        decor_frame_type_info_t *info = g_hash_table_lookup (frame_info_table, frame->type);
 
123
 
 
124
        if (!info)
 
125
            g_critical ("Couldn't find %s in frame info table", frame->type);
 
126
 
 
127
        if(!g_hash_table_remove (frames_table, frame->type))
 
128
            g_critical ("Could not remove frame type %s from hash_table!", frame->type);
 
129
 
 
130
        (*info->destroy_func) (frame);
 
131
    }
 
132
    return frame;
 
133
}
 
134
 
 
135
gboolean
 
136
gwd_decor_frame_add_type (const gchar        *name,
 
137
                          create_frame_proc  create_func,
 
138
                          destroy_frame_proc destroy_func)
 
139
{
 
140
    decor_frame_type_info_t *frame_type = malloc (sizeof (decor_frame_type_info_t));
 
141
 
 
142
    if (!frame_type)
 
143
        return FALSE;
 
144
 
 
145
    frame_type->create_func = create_func;
 
146
    frame_type->destroy_func = destroy_func;
 
147
 
 
148
    g_hash_table_insert (frame_info_table, strdup (name), frame_type);
 
149
 
 
150
    return TRUE;
 
151
}
 
152
 
 
153
void
 
154
gwd_decor_frame_remove_type (const gchar             *name)
 
155
{
 
156
    g_hash_table_remove (frame_info_table, name);
 
157
}
 
158
 
 
159
void
 
160
gwd_frames_foreach (GHFunc   foreach_func,
 
161
                    gpointer user_data)
 
162
{
 
163
    g_hash_table_foreach (frames_table, foreach_func, user_data);
 
164
}
 
165
 
 
166
void
 
167
gwd_process_frames (GHFunc      foreach_func,
 
168
                    const gchar *frame_keys[],
 
169
                    gint        frame_keys_num,
 
170
                    gpointer    user_data)
 
171
{
 
172
    gint   i = 0;
 
173
 
 
174
    for (; i < frame_keys_num; i++)
 
175
    {
 
176
        gpointer frame = g_hash_table_lookup (frames_table, frame_keys[i]);
 
177
 
 
178
        if (!frame)
 
179
            continue;
 
180
 
 
181
        (*foreach_func) ((gpointer) frame_keys[i], frame, user_data);
 
182
    }
 
183
}
 
184
 
 
185
void
 
186
destroy_frame_type (gpointer data)
 
187
{
 
188
    decor_frame_type_info_t *info = (decor_frame_type_info_t *) data;
 
189
 
 
190
    if (info)
 
191
    {
 
192
        /* TODO: Destroy all frames with this type using
 
193
         * the frame destroy function */
 
194
    }
 
195
 
 
196
    free (info);
 
197
}
 
198
 
 
199
decor_frame_t *
 
200
decor_frame_new (const gchar *type)
 
201
{
 
202
    GdkScreen     *gdkscreen = gdk_screen_get_default ();
 
203
    GdkColormap   *colormap;
 
204
    decor_frame_t *frame = malloc (sizeof (decor_frame_t));
 
205
 
 
206
    if (!frame)
 
207
    {
 
208
        g_critical ("Couldn't allocate frame!");
 
209
        return NULL;
 
210
    }
 
211
 
 
212
    frame->type = strdup (type);
 
213
    frame->refcount = 0;
 
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;
 
223
 
 
224
    frame->style_window_rgba = gtk_window_new (GTK_WINDOW_POPUP);
 
225
 
 
226
    colormap = gdk_screen_get_rgba_colormap (gdkscreen);
 
227
    if (colormap)
 
228
        gtk_widget_set_colormap (frame->style_window_rgba, colormap);
 
229
 
 
230
    gtk_widget_realize (frame->style_window_rgba);
 
231
 
 
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);
 
235
 
 
236
    frame->pango_context = gtk_widget_create_pango_context (frame->style_window_rgba);
 
237
 
 
238
    g_signal_connect_data (frame->style_window_rgba, "style-set",
 
239
                           G_CALLBACK (style_changed),
 
240
                           (gpointer) frame->pango_context, 0, 0);
 
241
 
 
242
    frame->style_window_rgb = gtk_window_new (GTK_WINDOW_POPUP);
 
243
 
 
244
    colormap = gdk_screen_get_rgb_colormap (gdkscreen);
 
245
    if (colormap)
 
246
        gtk_widget_set_colormap (frame->style_window_rgb, colormap);
 
247
 
 
248
    gtk_widget_realize (frame->style_window_rgb);
 
249
 
 
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);
 
253
 
 
254
    g_signal_connect_data (frame->style_window_rgb, "style-set",
 
255
                           G_CALLBACK (style_changed),
 
256
                           (gpointer) frame->pango_context, 0, 0);
 
257
 
 
258
    return frame;
 
259
}
 
260
 
 
261
void
 
262
decor_frame_destroy (decor_frame_t *frame)
 
263
{
 
264
    Display *xdisplay = gdk_x11_get_default_xdisplay ();
 
265
 
 
266
    if (frame->border_shadow_active)
 
267
        decor_shadow_destroy (xdisplay, frame->border_shadow_active);
 
268
 
 
269
    if (frame->border_shadow_inactive)
 
270
        decor_shadow_destroy (xdisplay, frame->border_shadow_inactive);
 
271
 
 
272
    if (frame->border_no_shadow)
 
273
        decor_shadow_destroy (xdisplay, frame->border_no_shadow);
 
274
 
 
275
    if (frame->max_border_shadow_inactive)
 
276
        decor_shadow_destroy (xdisplay, frame->max_border_shadow_inactive);
 
277
 
 
278
    if (frame->max_border_no_shadow)
 
279
        decor_shadow_destroy (xdisplay, frame->max_border_no_shadow);
 
280
 
 
281
    if (frame->style_window_rgba)
 
282
        gtk_widget_destroy (GTK_WIDGET (frame->style_window_rgba));
 
283
 
 
284
    if (frame->style_window_rgb)
 
285
        gtk_widget_destroy (GTK_WIDGET (frame->style_window_rgb));
 
286
 
 
287
    if (frame->pango_context)
 
288
        g_object_unref (G_OBJECT (frame->pango_context));
 
289
 
 
290
    if (frame->titlebar_font)
 
291
        pango_font_description_free (frame->titlebar_font);
 
292
 
 
293
    if (frame)
 
294
        free (frame->type);
 
295
 
 
296
    free (frame);
 
297
}
 
298
 
 
299
void
 
300
initialize_decorations ()
 
301
{
 
302
    frame_info_table = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, destroy_frame_type);
 
303
 
 
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);
 
311
 
 
312
    frames_table = g_hash_table_new (g_str_hash, g_str_equal);
 
313
}