~ubuntu-branches/ubuntu/karmic/xfce4-session/karmic

« back to all changes in this revision

Viewing changes to engines/mice/mice.c

  • Committer: Bazaar Package Importer
  • Author(s): Yves-Alexis Perez
  • Date: 2005-11-06 22:01:12 UTC
  • mto: (4.1.1 lenny) (1.3.1 upstream)
  • mto: This revision was merged to the branch mainline in revision 4.
  • Revision ID: james.westby@ubuntu.com-20051106220112-5rusox237ymjghsp
Tags: upstream-4.2.3
ImportĀ upstreamĀ versionĀ 4.2.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $Id: mice.c 4711 2004-11-01 16:10:55Z benny $ */
 
2
/*-
 
3
 * Copyright (c) 2003-2004 Benedikt Meurer <benny@xfce.org>
 
4
 * All rights reserved.
 
5
 *
 
6
 * This program is free software; you can redistribute it and/or modify
 
7
 * it under the terms of the GNU General Public License as published by
 
8
 * the Free Software Foundation; either version 2, or (at your option)
 
9
 * any later version.
 
10
 *                                                                              
 
11
 * This program is distributed in the hope that it will be useful,
 
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
 * GNU General Public License for more details.
 
15
 *                                                                              
 
16
 * You should have received a copy of the GNU General Public License
 
17
 * along with this program; if not, write to the Free Software
 
18
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 
19
 * 02111-1307, USA.
 
20
 */
 
21
 
 
22
#ifdef HAVE_CONFIG_H
 
23
#include <config.h>
 
24
#endif
 
25
 
 
26
#include <X11/Xlib.h>
 
27
 
 
28
#include <gdk-pixbuf/gdk-pixdata.h>
 
29
#include <gmodule.h>
 
30
 
 
31
#include <libxfsm/xfsm-splash-engine.h>
 
32
 
 
33
#include <engines/mice/preview.h>
 
34
#include <engines/mice/slide.h>
 
35
 
 
36
 
 
37
#define BORDER  2
 
38
#define COLOR   "#DAE7FE"
 
39
#define STEPS   8
 
40
 
 
41
 
 
42
#define MICE_WINDOW(obj)  ((MiceWindow *)(obj))
 
43
#define MICE(obj)         ((Mice *)(obj))
 
44
 
 
45
 
 
46
typedef struct _MiceWindow MiceWindow;
 
47
typedef struct _Mice       Mice;
 
48
 
 
49
 
 
50
struct _MiceWindow
 
51
{
 
52
  GdkWindow *window;
 
53
  GdkPixmap *pixmap;
 
54
  GdkGC     *gc;
 
55
  int        x;
 
56
  int        y;
 
57
  Mice      *mice;
 
58
};
 
59
 
 
60
 
 
61
struct _Mice
 
62
{
 
63
  gboolean     dialog_active;
 
64
  GList       *windows;
 
65
  MiceWindow  *mainwin;
 
66
  int          base_width;
 
67
  int          base_height;
 
68
  int          step;
 
69
  int          direction;
 
70
  guint        timeout_id;
 
71
};
 
72
 
 
73
 
 
74
static GdkFilterReturn
 
75
mice_filter (GdkXEvent *xevent, GdkEvent *event, gpointer user_data)
 
76
{
 
77
  MiceWindow *mice_window = MICE_WINDOW (user_data);
 
78
  XVisibilityEvent *xvisev = (XVisibilityEvent *) xevent;
 
79
 
 
80
  switch (xvisev->type)
 
81
    {
 
82
    case VisibilityNotify:
 
83
      if (!mice_window->mice->dialog_active)
 
84
        {
 
85
          gdk_window_raise (mice_window->window);
 
86
          return GDK_FILTER_REMOVE;
 
87
        }
 
88
      break;
 
89
    }
 
90
 
 
91
  return GDK_FILTER_CONTINUE;
 
92
}
 
93
 
 
94
 
 
95
static MiceWindow*
 
96
mice_window_new (GdkScreen      *screen,
 
97
                 int             monitor,
 
98
                 GdkPixmap      *pixmap,
 
99
                 GdkGC          *gc,
 
100
                 const GdkColor *color,
 
101
                 GdkCursor      *cursor,
 
102
                 Mice           *mice)
 
103
{
 
104
  GdkRectangle  geometry;
 
105
  GdkWindowAttr attr;
 
106
  MiceWindow   *mice_window;
 
107
 
 
108
  gdk_screen_get_monitor_geometry (screen, monitor, &geometry);
 
109
 
 
110
  mice_window = g_new0 (MiceWindow, 1);
 
111
  mice_window->mice = mice;
 
112
  mice_window->pixmap = GDK_PIXMAP (g_object_ref (pixmap));
 
113
  mice_window->gc = GDK_GC (g_object_ref (gc));
 
114
 
 
115
  /* init win attributes */
 
116
  attr.x = geometry.x;
 
117
  attr.y = geometry.y;
 
118
  attr.event_mask = GDK_VISIBILITY_NOTIFY_MASK;
 
119
  attr.width = geometry.width;
 
120
  attr.height = geometry.height;
 
121
  attr.wclass = GDK_INPUT_OUTPUT;
 
122
  attr.window_type = GDK_WINDOW_TEMP;
 
123
  attr.cursor = cursor;
 
124
  attr.override_redirect = TRUE;
 
125
 
 
126
  mice_window->window = gdk_window_new (gdk_screen_get_root_window (screen),
 
127
                                        &attr, GDK_WA_X | GDK_WA_Y
 
128
                                        | GDK_WA_NOREDIR | GDK_WA_CURSOR);
 
129
 
 
130
  gdk_window_set_background (mice_window->window, color);
 
131
 
 
132
  /* center pixmap */
 
133
  mice_window->x = (geometry.width - mice->base_width) / 2;
 
134
  mice_window->y = (geometry.height - mice->base_height) / 2;
 
135
 
 
136
  return mice_window;
 
137
}
 
138
 
 
139
 
 
140
static void
 
141
mice_step (Mice *mice)
 
142
{
 
143
  MiceWindow *mice_window;
 
144
  GList      *lp;
 
145
  int         sx;
 
146
  int         sy;
 
147
 
 
148
  sx = mice->step * mice->base_width;
 
149
  sy = 0;
 
150
 
 
151
  for (lp = mice->windows; lp != NULL; lp = lp->next)
 
152
    {
 
153
      mice_window = MICE_WINDOW (lp->data);
 
154
      gdk_draw_drawable (mice_window->window,
 
155
                         mice_window->gc,
 
156
                         mice_window->pixmap,
 
157
                         sx, sy,
 
158
                         mice_window->x,
 
159
                         mice_window->y,
 
160
                         mice->base_width,
 
161
                         mice->base_height);
 
162
    }
 
163
 
 
164
  if (mice->step == 0 && mice->direction < 0)
 
165
    {
 
166
      mice->step++;
 
167
      mice->direction = 1;
 
168
    }
 
169
  else if (mice->step == STEPS - 1 && mice->direction > 0)
 
170
    {
 
171
      mice->step--;
 
172
      mice->direction = -1;
 
173
    }
 
174
  else
 
175
    {
 
176
      mice->step += mice->direction;
 
177
    }
 
178
}
 
179
 
 
180
 
 
181
static gboolean
 
182
mice_timeout (gpointer user_data)
 
183
{
 
184
  Mice *mice = MICE (user_data);
 
185
 
 
186
  if (!mice->dialog_active)
 
187
    mice_step (mice);
 
188
 
 
189
  return TRUE;
 
190
}
 
191
 
 
192
 
 
193
static void
 
194
mice_setup (XfsmSplashEngine *engine,
 
195
            XfsmSplashRc     *rc)
 
196
{
 
197
  MiceWindow   *mice_window;
 
198
  GdkGCValues   gc_values;
 
199
  GdkColormap  *cmap;
 
200
  GdkWindow    *root;
 
201
  GdkPixmap    *pixmap;
 
202
  GdkPixbuf    *pixbuf;
 
203
  GdkColor      color;
 
204
  GdkCursor    *cursor;
 
205
  GdkScreen    *screen;
 
206
  GdkGC        *gc;
 
207
  GList        *lp;
 
208
  Mice         *mice = MICE (engine->user_data);
 
209
  int           pw, ph;
 
210
  int           nscreens;
 
211
  int           nmonitors;
 
212
  int           n, m;
 
213
 
 
214
  gdk_color_parse (COLOR, &color);
 
215
  cursor = gdk_cursor_new (GDK_WATCH);
 
216
 
 
217
  /* load slide pixbuf */
 
218
  pixbuf = gdk_pixbuf_from_pixdata (&slide, FALSE, NULL);
 
219
  pw = gdk_pixbuf_get_width (pixbuf);
 
220
  ph = gdk_pixbuf_get_height (pixbuf);
 
221
 
 
222
  mice->base_width = pw / STEPS;
 
223
  mice->base_height = ph;
 
224
  mice->step = 0;
 
225
  mice->direction = 1;
 
226
 
 
227
  nscreens = gdk_display_get_n_screens (engine->display);
 
228
  for (n = 0; n < nscreens; ++n)
 
229
    {
 
230
      screen = gdk_display_get_screen (engine->display, n);
 
231
      nmonitors = gdk_screen_get_n_monitors (screen);
 
232
      root = gdk_screen_get_root_window (screen);
 
233
 
 
234
      /* allocate color */
 
235
      cmap = gdk_drawable_get_colormap (root);
 
236
      gdk_rgb_find_color (cmap, &color);
 
237
 
 
238
      /* create graphics context for this screen */
 
239
      gc_values.function = GDK_COPY;
 
240
      gc_values.graphics_exposures = FALSE;
 
241
      gc_values.foreground = color;
 
242
      gc = gdk_gc_new_with_values (root, &gc_values, GDK_GC_FUNCTION
 
243
                                  | GDK_GC_EXPOSURES | GDK_GC_FOREGROUND);
 
244
 
 
245
      /* create pixmap for this screen */
 
246
      pixmap = gdk_pixmap_new (root, pw, ph, -1);
 
247
      gdk_draw_rectangle (pixmap, gc, TRUE, 0, 0, pw, ph);
 
248
      gdk_draw_pixbuf (pixmap, gc, pixbuf, 0, 0, 0, 0,
 
249
                       pw, ph, GDK_RGB_DITHER_NONE, 0, 0);
 
250
 
 
251
      for (m = 0; m < nmonitors; ++m)
 
252
        {
 
253
          mice_window = mice_window_new (screen, m, pixmap, gc,
 
254
                                         &color, cursor, mice);
 
255
          mice->windows = g_list_append (mice->windows, mice_window);
 
256
 
 
257
          if (screen == engine->primary_screen && m == engine->primary_monitor)
 
258
            mice->mainwin = mice_window;
 
259
        }
 
260
 
 
261
      /* cleanup for this screen */
 
262
      g_object_unref (pixmap);
 
263
      g_object_unref (gc);
 
264
    }
 
265
 
 
266
  /* show all windows and connect filters */
 
267
  for (lp = mice->windows; lp != NULL; lp = lp->next)
 
268
    {
 
269
      mice_window = MICE_WINDOW (lp->data);
 
270
      gdk_window_show (mice_window->window);
 
271
      gdk_window_add_filter (mice_window->window, mice_filter, mice_window);
 
272
    }
 
273
 
 
274
  /* start timer */
 
275
  mice->timeout_id = g_timeout_add (100, mice_timeout, mice);
 
276
 
 
277
  /* cleanup */
 
278
  g_object_unref (pixbuf);
 
279
  gdk_cursor_unref (cursor);
 
280
}
 
281
 
 
282
 
 
283
static void
 
284
mice_next (XfsmSplashEngine *engine, const gchar *text)
 
285
{
 
286
  /* nothing to be done here */
 
287
}
 
288
 
 
289
 
 
290
static int
 
291
mice_run (XfsmSplashEngine *engine,
 
292
          GtkWidget        *dialog)
 
293
{
 
294
  Mice *mice = MICE (engine->user_data);
 
295
  MiceWindow *mainwin = mice->mainwin;
 
296
  GtkRequisition requisition;
 
297
  int result;
 
298
  int x, y;
 
299
  int wx, wy;
 
300
  int ww, wh;
 
301
 
 
302
  mice->dialog_active = TRUE;
 
303
 
 
304
  gdk_window_get_origin (mainwin->window, &wx, &wy);
 
305
  gdk_drawable_get_size (mainwin->window, &ww, &wh);
 
306
  gtk_window_set_screen (GTK_WINDOW (dialog),
 
307
                         gdk_drawable_get_screen (mainwin->window));
 
308
  gtk_widget_size_request (dialog, &requisition);
 
309
  x = wx + (ww - requisition.width) / 2;
 
310
  y = wy + (wh - requisition.height) / 2;
 
311
  gtk_window_move (GTK_WINDOW (dialog), x, y);
 
312
  result = gtk_dialog_run (GTK_DIALOG (dialog));
 
313
 
 
314
  mice->dialog_active = FALSE;
 
315
 
 
316
  return result;
 
317
}
 
318
 
 
319
 
 
320
static void
 
321
mice_destroy (XfsmSplashEngine *engine)
 
322
{
 
323
  MiceWindow *mice_window;
 
324
  Mice       *mice = MICE (engine->user_data);
 
325
  GList      *lp;
 
326
 
 
327
  for (lp = mice->windows; lp != NULL; lp = lp->next)
 
328
    {
 
329
      mice_window = MICE_WINDOW (lp->data);
 
330
      gdk_window_remove_filter (mice_window->window, mice_filter, mice);
 
331
      gdk_window_destroy (mice_window->window);
 
332
      g_object_unref (mice_window->pixmap);
 
333
      g_object_unref (mice_window->gc);
 
334
      g_free (mice_window);
 
335
    }
 
336
 
 
337
  g_source_remove (mice->timeout_id);
 
338
  g_list_free (mice->windows);
 
339
  g_free (mice);
 
340
}
 
341
 
 
342
 
 
343
G_MODULE_EXPORT void
 
344
engine_init (XfsmSplashEngine *engine)
 
345
{
 
346
  Mice *mice;
 
347
 
 
348
  mice = g_new0 (Mice, 1);
 
349
 
 
350
  engine->user_data = mice;
 
351
  engine->setup = mice_setup;
 
352
  engine->next = mice_next;
 
353
  engine->run = mice_run;
 
354
  engine->destroy = mice_destroy;
 
355
}
 
356
 
 
357
 
 
358
 
 
359
static GdkPixbuf*
 
360
config_preview (XfsmSplashConfig *config)
 
361
{
 
362
  return gdk_pixbuf_from_pixdata (&preview, FALSE, NULL);
 
363
}
 
364
 
 
365
 
 
366
G_MODULE_EXPORT void
 
367
config_init (XfsmSplashConfig *config)
 
368
{
 
369
  config->name        = g_strdup ("Mice");
 
370
  config->description = g_strdup ("Mice Splash Engine");
 
371
  config->version     = g_strdup (VERSION);
 
372
  config->author      = g_strdup ("Benedikt Meurer");
 
373
  config->homepage    = g_strdup ("http://www.xfce.org/");
 
374
 
 
375
  config->preview     = config_preview;
 
376
}
 
377
 
 
378