~ubuntu-branches/debian/jessie/cheese/jessie

« back to all changes in this revision

Viewing changes to libcheese/cheese-flash.c

  • Committer: Bazaar Package Importer
  • Author(s): Michael Biebl
  • Date: 2010-05-04 17:37:18 UTC
  • mfrom: (1.1.13 upstream)
  • Revision ID: james.westby@ubuntu.com-20100504173718-k2rx3nryi4vd0xyx
Tags: 2.30.1-1
* New upstream release.
  - HAL dependency has been dropped. Use (g)udev for v4l capability probing
    on Linux. Closes: #573774
  - Split code into separate libraries.
* debian/control.in
  - Drop Build-Depends on libhal-dev.
  - Drop Build-Depends on libebook1.2-dev.
  - Bump Build-Depends on libgtk2.0-dev to (>= 2.19.1).
  - Bump Build-Depends on libgstreamer*-dev to (>= 0.10.23).
  - Add Build-Depends on libcanberra-gtk-dev.
  - Add Build-Depends on libxtst-dev.
  - Add Build-Depends on libgudev-1.0-dev on Linux.
  - Bump Standards-Version to 3.8.4. No further changes.
* Switch to source format 3.0 (quilt)
  - Add debian/source/format.
* debian/rules
  - Drop lpia specific configure flags, lpia is dead.
* Update package layout (based on work by Ubuntu)
  - Move data files into new cheese-common package.
  - Keep binary along with its desktop and dbus service file in the cheese
    package.
  - Add libcheese-gtk18 and libcheese-gtk-dev package for the new
    libcheese-gtk library. Use a symbols file for improved shlibs
    dependencies.
  - Add Conflicts/Replaces to cheese-common to ensure proper upgrades from
    previous versions.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright © 2008 Alexander “weej” Jones <alex@weej.com>
 
3
 * Copyright © 2008 Thomas Perl <thp@thpinfo.com>
 
4
 * Copyright © 2009 daniel g. siegel <dgsiegel@gnome.org>
 
5
 *
 
6
 * Licensed under the GNU General Public License Version 2
 
7
 *
 
8
 * This program is free software; you can redistribute it and/or modify
 
9
 * it under the terms of the GNU General Public License as published by
 
10
 * the Free Software Foundation; either version 2 of the License, or
 
11
 * (at your option) any later version.
 
12
 *
 
13
 * This program is distributed in the hope that it will be useful,
 
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
16
 * GNU General Public License for more details.
 
17
 *
 
18
 * You should have received a copy of the GNU General Public License
 
19
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
20
 */
 
21
 
 
22
/* This is a "flash" object that you can create and invoke a method "flash" on to
 
23
 * flood the screen with white temporarily */
 
24
 
 
25
#include <gtk/gtk.h>
 
26
 
 
27
#include <cheese-camera.h>
 
28
#include "cheese-flash.h"
 
29
 
 
30
enum
 
31
{
 
32
  PROP_0,
 
33
  PROP_PARENT
 
34
};
 
35
 
 
36
/* How long to hold the flash for */
 
37
#define FLASH_DURATION 250
 
38
 
 
39
/* The factor which defines how much the flash fades per frame */
 
40
#define FLASH_FADE_FACTOR 0.95
 
41
 
 
42
/* How many frames per second */
 
43
#define FLASH_ANIMATION_RATE 50
 
44
 
 
45
/* When to consider the flash finished so we can stop fading */
 
46
#define FLASH_LOW_THRESHOLD 0.01
 
47
 
 
48
G_DEFINE_TYPE (CheeseFlash, cheese_flash, G_TYPE_OBJECT);
 
49
 
 
50
#define CHEESE_FLASH_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), CHEESE_TYPE_FLASH, CheeseFlashPrivate))
 
51
 
 
52
typedef struct
 
53
{
 
54
  GtkWidget *parent;
 
55
  GtkWindow *window;
 
56
  guint flash_timeout_tag;
 
57
  guint fade_timeout_tag;
 
58
} CheeseFlashPrivate;
 
59
 
 
60
static gboolean
 
61
cheese_flash_window_expose_event_cb (GtkWidget *widget, GdkEventExpose *event, gpointer user_data)
 
62
{
 
63
  cairo_t *cr;
 
64
 
 
65
  cr = gdk_cairo_create (gtk_widget_get_window (widget));
 
66
  cairo_set_source_rgb (cr, 1, 1, 1);
 
67
  cairo_rectangle (cr, event->area.x, event->area.y, event->area.width, event->area.height);
 
68
  cairo_fill (cr);
 
69
  cairo_destroy (cr);
 
70
 
 
71
  return TRUE;
 
72
}
 
73
 
 
74
static void
 
75
cheese_flash_init (CheeseFlash *self)
 
76
{
 
77
  CheeseFlashPrivate *priv = CHEESE_FLASH_GET_PRIVATE (self);
 
78
 
 
79
  GtkWindow *window;
 
80
 
 
81
  priv->flash_timeout_tag = 0;
 
82
  priv->fade_timeout_tag  = 0;
 
83
 
 
84
  window = GTK_WINDOW (gtk_window_new (GTK_WINDOW_POPUP));
 
85
 
 
86
  /* make it so it doesn't look like a window on the desktop (+fullscreen) */
 
87
  gtk_window_set_decorated (window, FALSE);
 
88
  gtk_window_set_skip_taskbar_hint (window, TRUE);
 
89
  gtk_window_set_skip_pager_hint (window, TRUE);
 
90
  gtk_window_set_keep_above (window, TRUE);
 
91
 
 
92
  /* Don't take focus */
 
93
  gtk_window_set_accept_focus (window, FALSE);
 
94
  gtk_window_set_focus_on_map (window, FALSE);
 
95
 
 
96
  /* Don't consume input */
 
97
  gtk_widget_realize (GTK_WIDGET (window));
 
98
  GdkRegion *input_region;
 
99
  input_region = gdk_region_new ();
 
100
  gdk_window_input_shape_combine_region (gtk_widget_get_window (GTK_WIDGET (window)), input_region, 0, 0);
 
101
  gdk_region_destroy (input_region);
 
102
 
 
103
  g_signal_connect (G_OBJECT (window), "expose-event", G_CALLBACK (cheese_flash_window_expose_event_cb), NULL);
 
104
  priv->window = window;
 
105
}
 
106
 
 
107
static void
 
108
cheese_flash_dispose (GObject *object)
 
109
{
 
110
  CheeseFlashPrivate *priv = CHEESE_FLASH_GET_PRIVATE (object);
 
111
 
 
112
  if (priv->window != NULL)
 
113
  {
 
114
    gtk_widget_destroy (GTK_WIDGET (priv->window));
 
115
    priv->window = NULL;
 
116
  }
 
117
  if (priv->parent != NULL)
 
118
  {
 
119
    g_object_unref (priv->parent);
 
120
    priv->parent = NULL;
 
121
  }
 
122
 
 
123
  if (G_OBJECT_CLASS (cheese_flash_parent_class)->dispose)
 
124
    G_OBJECT_CLASS (cheese_flash_parent_class)->dispose (object);
 
125
}
 
126
 
 
127
static void
 
128
cheese_flash_finalize (GObject *object)
 
129
{
 
130
  if (G_OBJECT_CLASS (cheese_flash_parent_class)->finalize)
 
131
    G_OBJECT_CLASS (cheese_flash_parent_class)->finalize (object);
 
132
}
 
133
 
 
134
static void
 
135
cheese_flash_set_property (GObject      *object,
 
136
                           guint         prop_id,
 
137
                           const GValue *value,
 
138
                           GParamSpec   *pspec)
 
139
{
 
140
  CheeseFlashPrivate *priv = CHEESE_FLASH_GET_PRIVATE (object);
 
141
 
 
142
  switch (prop_id)
 
143
  {
 
144
    case PROP_PARENT: {
 
145
      GObject *object;
 
146
      object = g_value_get_object (value);
 
147
      if (object != NULL)
 
148
        priv->parent = g_object_ref (object);
 
149
      else
 
150
        priv->parent = NULL;
 
151
    }
 
152
    break;
 
153
    default:
 
154
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 
155
      break;
 
156
  }
 
157
}
 
158
 
 
159
static void
 
160
cheese_flash_class_init (CheeseFlashClass *klass)
 
161
{
 
162
  GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
163
 
 
164
  g_type_class_add_private (klass, sizeof (CheeseFlashPrivate));
 
165
 
 
166
  object_class->set_property = cheese_flash_set_property;
 
167
  object_class->dispose      = cheese_flash_dispose;
 
168
  object_class->finalize     = cheese_flash_finalize;
 
169
 
 
170
  g_object_class_install_property (object_class, PROP_PARENT,
 
171
                                   g_param_spec_object ("parent",
 
172
                                                        NULL,
 
173
                                                        NULL,
 
174
                                                        GTK_TYPE_WIDGET,
 
175
                                                        G_PARAM_WRITABLE));
 
176
}
 
177
 
 
178
static gboolean
 
179
cheese_flash_opacity_fade (gpointer data)
 
180
{
 
181
  CheeseFlash        *flash        = data;
 
182
  CheeseFlashPrivate *flash_priv   = CHEESE_FLASH_GET_PRIVATE (flash);
 
183
  GtkWindow          *flash_window = flash_priv->window;
 
184
  double              opacity      = gtk_window_get_opacity (flash_window);
 
185
 
 
186
  /* exponentially decrease */
 
187
  gtk_window_set_opacity (flash_window, opacity * FLASH_FADE_FACTOR);
 
188
 
 
189
  if (opacity <= FLASH_LOW_THRESHOLD)
 
190
  {
 
191
    /* the flasher has finished when we reach the quit value */
 
192
    gtk_widget_hide (GTK_WIDGET (flash_window));
 
193
    return FALSE;
 
194
  }
 
195
 
 
196
  return TRUE;
 
197
}
 
198
 
 
199
static gboolean
 
200
cheese_flash_start_fade (gpointer data)
 
201
{
 
202
  CheeseFlashPrivate *flash_priv = CHEESE_FLASH_GET_PRIVATE (CHEESE_FLASH (data));
 
203
 
 
204
  GtkWindow *flash_window = flash_priv->window;
 
205
 
 
206
  /* If the screen is non-composited, just hide and finish up */
 
207
  if (!gdk_screen_is_composited (gtk_window_get_screen (flash_window)))
 
208
  {
 
209
    gtk_widget_hide (GTK_WIDGET (flash_window));
 
210
    return FALSE;
 
211
  }
 
212
 
 
213
  flash_priv->fade_timeout_tag = g_timeout_add (1000.0 / FLASH_ANIMATION_RATE, cheese_flash_opacity_fade, data);
 
214
  return FALSE;
 
215
}
 
216
 
 
217
void
 
218
cheese_flash_fire (CheeseFlash *flash)
 
219
{
 
220
  CheeseFlashPrivate *flash_priv = CHEESE_FLASH_GET_PRIVATE (flash);
 
221
  GtkWidget          *parent;
 
222
  GdkScreen          *screen;
 
223
  GdkRectangle        rect;
 
224
  int                 monitor;
 
225
 
 
226
  g_return_if_fail (flash_priv->parent != NULL);
 
227
 
 
228
  GtkWindow *flash_window = flash_priv->window;
 
229
 
 
230
  if (flash_priv->flash_timeout_tag > 0)
 
231
    g_source_remove (flash_priv->flash_timeout_tag);
 
232
  if (flash_priv->fade_timeout_tag > 0)
 
233
    g_source_remove (flash_priv->fade_timeout_tag);
 
234
 
 
235
  parent  = gtk_widget_get_toplevel (flash_priv->parent);
 
236
  screen  = gtk_widget_get_screen (parent);
 
237
  monitor = gdk_screen_get_monitor_at_window (screen,
 
238
                                              gtk_widget_get_window (parent));
 
239
  gdk_screen_get_monitor_geometry (screen, monitor, &rect);
 
240
  gtk_window_set_transient_for (GTK_WINDOW (flash_window), GTK_WINDOW (parent));
 
241
  gtk_window_resize (flash_window, rect.width, rect.height);
 
242
  gtk_window_move (flash_window, rect.x, rect.y);
 
243
 
 
244
  gtk_window_set_opacity (flash_window, 1);
 
245
  gtk_widget_show_all (GTK_WIDGET (flash_window));
 
246
  flash_priv->flash_timeout_tag = g_timeout_add (FLASH_DURATION, cheese_flash_start_fade, (gpointer) flash);
 
247
}
 
248
 
 
249
CheeseFlash *
 
250
cheese_flash_new (GtkWidget *parent)
 
251
{
 
252
  return g_object_new (CHEESE_TYPE_FLASH,
 
253
                       "parent", parent,
 
254
                       NULL);
 
255
}