~khurshid-alam/notify-osd/leolik-patches

« back to all changes in this revision

Viewing changes to main.c

  • Committer: Mirco Müller
  • Date: 2008-11-20 16:43:23 UTC
  • Revision ID: mirco.mueller@ubuntu.com-20081120164323-do8f2fxr2qb2avs0
initial commit, moved from lp:~bling-brigade/dx-prototypes/trunk

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*******************************************************************************
 
2
**3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789
 
3
**      10        20        30        40        50        60        70        80
 
4
**
 
5
** project:
 
6
**    notification-test-cairo
 
7
**
 
8
** file:
 
9
**    main.c
 
10
**
 
11
** author:
 
12
**    Mirco "MacSlow" Mueller <mirco.mueller@ubuntu.com>
 
13
**
 
14
** copyright (C) Mirco Mueller, oct. 2008, placed under the terms of the LGPL
 
15
**
 
16
*******************************************************************************/
 
17
 
 
18
#include <string.h>
 
19
#include <stdlib.h>
 
20
#include <glib.h>
 
21
#include <gtk/gtk.h>
 
22
#include <gdk/gdkkeysyms.h>
 
23
 
 
24
double   g_alpha   = 0.95f;
 
25
gboolean g_entered = FALSE;
 
26
gboolean g_left    = FALSE;
 
27
gint     g_pointer[2];
 
28
 
 
29
void
 
30
draw_round_rect (cairo_t* cr,
 
31
                 double   aspect,         /* aspect-ratio            */
 
32
                 double   x,              /* top-left corner         */
 
33
                 double   y,              /* top-left corner         */
 
34
                 double   corner_radius,  /* "size" of the corners   */
 
35
                 double   width,          /* width of the rectangle  */
 
36
                 double   height          /* height of the rectangle */)
 
37
{
 
38
        double radius = corner_radius / aspect;
 
39
 
 
40
        /* top-left, right of the corner */
 
41
        cairo_move_to (cr, x + radius, y);
 
42
 
 
43
        /* top-right, left of the corner */
 
44
        cairo_line_to (cr,
 
45
                       x + width - radius,
 
46
                       y);
 
47
 
 
48
        /* top-right, below the corner */
 
49
        cairo_arc (cr,
 
50
                   x + width - radius,
 
51
                   y + radius,
 
52
                   radius,
 
53
                   -90.0f * G_PI / 180.0f,
 
54
                   0.0f * G_PI / 180.0f);
 
55
 
 
56
        /* bottom-right, above the corner */
 
57
        cairo_line_to (cr,
 
58
                       x + width,
 
59
                       y + height - radius);
 
60
 
 
61
        /* bottom-right, left of the corner */
 
62
        cairo_arc (cr,
 
63
                   x + width - radius,
 
64
                   y + height - radius,
 
65
                   radius,
 
66
                   0.0f * G_PI / 180.0f,
 
67
                   90.0f * G_PI / 180.0f);
 
68
 
 
69
        /* bottom-left, right of the corner */
 
70
        cairo_line_to (cr,
 
71
                       x + radius,
 
72
                       y + height);
 
73
 
 
74
        /* bottom-left, above the corner */
 
75
        cairo_arc (cr,
 
76
                   x + radius,
 
77
                   y + height - radius,
 
78
                   radius,
 
79
                   90.0f * G_PI / 180.0f,
 
80
                   180.0f * G_PI / 180.0f);
 
81
 
 
82
        /* top-left, below the corner */
 
83
        cairo_line_to (cr,
 
84
                       x,
 
85
                       y + radius);
 
86
 
 
87
        /* top-left, right of the corner */
 
88
        cairo_arc (cr,
 
89
                   x + radius,
 
90
                   y + radius,
 
91
                   radius,
 
92
                   180.0f * G_PI / 180.0f,
 
93
                   270.0f * G_PI / 180.0f);
 
94
}
 
95
 
 
96
void
 
97
screen_changed_handler (GtkWidget* window,
 
98
                        GdkScreen* old_screen,
 
99
                        gpointer   data)
 
100
{                       
 
101
        GdkScreen*   screen   = gtk_widget_get_screen (window);
 
102
        GdkColormap* colormap = gdk_screen_get_rgba_colormap (screen);
 
103
      
 
104
        if (!colormap)
 
105
                colormap = gdk_screen_get_rgb_colormap (screen);
 
106
 
 
107
        gtk_widget_set_colormap (window, colormap);
 
108
}
 
109
 
 
110
gboolean
 
111
delete_handler (GtkWidget* window,
 
112
                GdkEvent*  event,
 
113
                gpointer   data)
 
114
{
 
115
        gtk_main_quit ();
 
116
        return TRUE;
 
117
}
 
118
 
 
119
gboolean
 
120
key_press_handler (GtkWidget*   window,
 
121
                   GdkEventKey* event,
 
122
                   gpointer     data)
 
123
{
 
124
        if (event->type   == GDK_KEY_PRESS &&
 
125
            (event->keyval == GDK_q || event->keyval == GDK_Escape))
 
126
        {
 
127
                delete_handler (window, NULL, NULL);
 
128
        }
 
129
 
 
130
        return TRUE;
 
131
}
 
132
 
 
133
void
 
134
update_input_shape (GtkWidget* window,
 
135
                    gint       width,
 
136
                    gint       height)
 
137
{
 
138
        GdkBitmap* mask = NULL;
 
139
        cairo_t*   cr   = NULL;
 
140
 
 
141
        mask = (GdkBitmap*) gdk_pixmap_new (NULL, width, height, 1);
 
142
        if (mask)
 
143
        {
 
144
                cr = gdk_cairo_create (mask);
 
145
                if (cairo_status (cr) == CAIRO_STATUS_SUCCESS)
 
146
                {
 
147
                        cairo_scale (cr, 1.0f, 1.0f);
 
148
                        cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
 
149
                        cairo_paint (cr);
 
150
                        cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
 
151
                        cairo_set_source_rgb (cr, 1.0f, 1.0f, 1.0f);
 
152
 
 
153
                        draw_round_rect (cr,
 
154
                                         1.0f,
 
155
                                         0.0f, 0.0f,
 
156
                                         10.0f,
 
157
                                         10.0f, 10.0f);
 
158
 
 
159
                        cairo_fill (cr);
 
160
 
 
161
                        cairo_destroy (cr);
 
162
 
 
163
                        gtk_widget_input_shape_combine_mask (window,
 
164
                                                             NULL,
 
165
                                                             0,
 
166
                                                             0);
 
167
                        gtk_widget_input_shape_combine_mask (window,
 
168
                                                             mask,
 
169
                                                             0,
 
170
                                                             0);
 
171
                }
 
172
 
 
173
                g_object_unref ((gpointer) mask);
 
174
        }
 
175
}
 
176
 
 
177
gboolean
 
178
expose_handler (GtkWidget*      window,
 
179
                GdkEventExpose* event,
 
180
                gpointer        data)
 
181
{
 
182
        cairo_t* cr;
 
183
 
 
184
        cr = gdk_cairo_create (window->window);
 
185
 
 
186
        cairo_scale (cr, 1.0f, 1.0f);
 
187
        cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
 
188
        cairo_paint (cr);
 
189
        cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
 
190
        cairo_set_source_rgba (cr, 0.05f, 0.05f, 0.05f, g_alpha);
 
191
 
 
192
        draw_round_rect (cr,
 
193
                         1.0f,
 
194
                         0.0f, 0.0f,
 
195
                         10.0f,
 
196
                         (double) window->allocation.width,
 
197
                         (double) window->allocation.height);
 
198
 
 
199
        cairo_fill (cr);
 
200
 
 
201
        cairo_select_font_face (cr,
 
202
                                "DejaVu Sans",
 
203
                                CAIRO_FONT_SLANT_NORMAL,
 
204
                                CAIRO_FONT_WEIGHT_NORMAL);
 
205
        cairo_set_font_size (cr, 24.0f);
 
206
        cairo_move_to (cr, 50.0f, 50.0f);
 
207
        cairo_text_path (cr, "GTK+ bubble");
 
208
        cairo_set_source_rgba (cr, 1.0f, 1.0f, 1.0f, 0.5f);
 
209
        cairo_fill (cr);
 
210
 
 
211
        cairo_destroy (cr);
 
212
 
 
213
        return TRUE;
 
214
}
 
215
 
 
216
gboolean
 
217
redraw_handler (GtkWidget* window)
 
218
{
 
219
        if (g_left && g_alpha < 0.95f)
 
220
                g_alpha += 0.05f;
 
221
 
 
222
        if (g_entered && g_alpha > 0.1f)
 
223
                g_alpha -= 0.05f;
 
224
 
 
225
        gtk_window_set_opacity (GTK_WINDOW (window), g_alpha);
 
226
 
 
227
        return TRUE;
 
228
}
 
229
 
 
230
gboolean
 
231
pointer_update (GtkWidget* window)
 
232
{
 
233
        gint pointer_rel_x;
 
234
        gint pointer_rel_y;
 
235
        gint pointer_abs_x;
 
236
        gint pointer_abs_y;
 
237
        gint win_x;
 
238
        gint win_y;
 
239
        gint width;
 
240
        gint height;
 
241
 
 
242
        if (GTK_WIDGET_REALIZED (window))
 
243
        {
 
244
                gtk_widget_get_pointer (window, &pointer_rel_x, &pointer_rel_y);
 
245
                gtk_window_get_position (GTK_WINDOW (window), &win_x, &win_y);
 
246
                pointer_abs_x = win_x + pointer_rel_x;
 
247
                pointer_abs_y = win_y + pointer_rel_y;
 
248
                gtk_window_get_size (GTK_WINDOW (window), &width, &height);
 
249
                if (pointer_abs_x >= win_x &&
 
250
                    pointer_abs_x <= win_x + width &&
 
251
                    pointer_abs_y >= win_y &&
 
252
                    pointer_abs_y <= win_y + height)
 
253
                {
 
254
                        g_entered = TRUE;
 
255
                        g_left    = FALSE;
 
256
                }
 
257
                else
 
258
                {
 
259
                        g_entered = FALSE;
 
260
                        g_left    = TRUE;
 
261
                }
 
262
        }
 
263
 
 
264
        return TRUE;
 
265
}
 
266
 
 
267
int 
 
268
main (int    argc,
 
269
      char** argv)
 
270
{
 
271
        GtkWidget*      window            = NULL;
 
272
        GError*         error             = NULL;
 
273
        guint           draw_handler_id   = 0;
 
274
        guint           pointer_update_id = 0;
 
275
        gint            x                 = 0;
 
276
        gint            y                 = 0;
 
277
        gint            width             = 0;
 
278
        gint            height            = 0;
 
279
        GOptionContext* option_context    = NULL;
 
280
        GOptionEntry    options[]         = {{"xposition",
 
281
                                              'x',
 
282
                                              0,
 
283
                                              G_OPTION_ARG_INT,
 
284
                                              &x,
 
285
                                              "x-pos of the top-left corner",
 
286
                                              "X"},
 
287
                                             {"yposition",
 
288
                                              'y',
 
289
                                              0,
 
290
                                              G_OPTION_ARG_INT,
 
291
                                              &y,
 
292
                                              "y-pos of the top-left corner",
 
293
                                              "Y"},
 
294
                                             {"width",
 
295
                                              'w',
 
296
                                              0,
 
297
                                              G_OPTION_ARG_INT,
 
298
                                              &width,
 
299
                                              "open window with this width",
 
300
                                              "WIDTH"},
 
301
                                             {"height",
 
302
                                              'h',
 
303
                                              0,
 
304
                                              G_OPTION_ARG_INT,
 
305
                                              &height,
 
306
                                              "open window with this height",
 
307
                                              "HEIGHT"},
 
308
                                             {NULL}};
 
309
 
 
310
        gtk_init (&argc, &argv);
 
311
 
 
312
        window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
 
313
        if (!window)
 
314
                return 1;
 
315
 
 
316
        gtk_widget_add_events (window,
 
317
                               GDK_POINTER_MOTION_MASK |
 
318
                               GDK_BUTTON_PRESS_MASK |
 
319
                               GDK_BUTTON_RELEASE_MASK);
 
320
 
 
321
        /* hook up input-event handlers to window */
 
322
        g_signal_connect (G_OBJECT (window),
 
323
                          "delete-event",
 
324
                          G_CALLBACK (delete_handler),
 
325
                          NULL);
 
326
        g_signal_connect (G_OBJECT (window),
 
327
                          "key-press-event",
 
328
                          G_CALLBACK (key_press_handler),
 
329
                          NULL);
 
330
        g_signal_connect (G_OBJECT (window),
 
331
                          "screen-changed",
 
332
                          G_CALLBACK (screen_changed_handler),
 
333
                          NULL);
 
334
 
 
335
        /* handle commandline options */
 
336
        x      = 30;
 
337
        y      = 30;
 
338
        width  = 300;
 
339
        height = 100;
 
340
        option_context = g_option_context_new ("- prototype for some new tech");
 
341
        g_option_context_add_main_entries (option_context,
 
342
                                           options,
 
343
                                           "notification test");
 
344
        g_option_context_parse (option_context, &argc, &argv, NULL);
 
345
        g_option_context_free (option_context);
 
346
 
 
347
        gtk_widget_set_size_request (window, width, height);
 
348
        gtk_window_move (GTK_WINDOW (window), x, y);
 
349
 
 
350
        /* make sure the window opens with a RGBA-visual */
 
351
        screen_changed_handler (window, NULL, NULL);
 
352
        gtk_widget_realize (window);
 
353
        gdk_window_set_back_pixmap (window->window, NULL, FALSE);
 
354
 
 
355
        /* hook up window-event handlers to window */
 
356
        g_signal_connect (G_OBJECT (window),
 
357
                          "expose-event",
 
358
                          G_CALLBACK (expose_handler),
 
359
                          NULL);
 
360
 
 
361
        /* do nasty busy-polling rendering in the drawing-area */
 
362
        draw_handler_id = g_timeout_add (1000/60,
 
363
                                         (GSourceFunc) redraw_handler,
 
364
                                         window);
 
365
 
 
366
        /* read out current mouse-pointer position every 1/10 second */
 
367
        pointer_update_id = g_timeout_add (100,
 
368
                                           (GSourceFunc) pointer_update,
 
369
                                           window);
 
370
 
 
371
        /*  "clear" input-mask, set title/icon/attributes */
 
372
        update_input_shape (window, 1, 1);
 
373
        gtk_widget_set_app_paintable (window, TRUE);
 
374
        gtk_window_set_title (GTK_WINDOW (window), "notification-test-cairo");
 
375
        gtk_window_set_icon_from_file (GTK_WINDOW (window),
 
376
                                       "cairo-logo.png",
 
377
                                       &error);
 
378
        gtk_window_set_decorated (GTK_WINDOW (window), FALSE);
 
379
        gtk_window_set_keep_above (GTK_WINDOW (window), TRUE);
 
380
        gtk_window_set_resizable (GTK_WINDOW (window), FALSE);
 
381
        gtk_widget_show_all (window);
 
382
 
 
383
        gtk_main ();
 
384
 
 
385
        return 0;
 
386
}
 
387