~ubuntu-branches/ubuntu/jaunty/gimp/jaunty-security

« back to all changes in this revision

Viewing changes to devel-docs/tools/shooter.c

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Holbach
  • Date: 2007-05-02 16:33:03 UTC
  • mfrom: (1.1.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20070502163303-bvzhjzbpw8qglc4y
Tags: 2.3.16-1ubuntu1
* Resynchronized with Debian, remaining Ubuntu changes:
  - debian/rules: i18n magic.
* debian/control.in:
  - Maintainer: Ubuntu Core Developers <ubuntu-devel@lists.ubuntu.com>
* debian/patches/02_help-message.patch,
  debian/patches/03_gimp.desktop.in.in.patch,
  debian/patches/10_dont_show_wizard.patch: updated.
* debian/patches/04_composite-signedness.patch,
  debian/patches/05_add-letter-spacing.patch: dropped, used upstream.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
 
 
2
#include "config.h"
 
3
 
 
4
#include <stdlib.h>
 
5
 
 
6
#ifdef HAVE_UNISTD_H
 
7
#include <unistd.h>
 
8
#endif
 
9
 
 
10
#include <gdk/gdkx.h>
 
11
#include <gtk/gtk.h>
 
12
 
 
13
#include <X11/extensions/shape.h>
 
14
 
 
15
#include "libgimpbase/gimpbase.h"
 
16
#include "libgimpconfig/gimpconfig.h"
 
17
#include "libgimpmodule/gimpmodule.h"
 
18
#include "libgimpwidgets/gimpwidgets.h"
 
19
#include "libgimpwidgets/gimpwidgets-private.h"
 
20
 
 
21
#include "shadow.h"
 
22
#include "units.h"
 
23
#include "widgets.h"
 
24
 
 
25
 
 
26
static Window
 
27
find_toplevel_window (Display *display,
 
28
                      Window   xid)
 
29
{
 
30
  Window  root, parent, *children;
 
31
  guint   nchildren;
 
32
 
 
33
  do
 
34
    {
 
35
      if (XQueryTree (display, xid,
 
36
                      &root, &parent, &children, &nchildren) == 0)
 
37
        {
 
38
          g_warning ("Couldn't find window manager window");
 
39
          return 0;
 
40
        }
 
41
 
 
42
      if (root == parent)
 
43
        return xid;
 
44
 
 
45
      xid = parent;
 
46
    }
 
47
  while (TRUE);
 
48
}
 
49
 
 
50
static GdkPixbuf *
 
51
add_border_to_shot (GdkPixbuf *pixbuf)
 
52
{
 
53
  GdkPixbuf *retval;
 
54
 
 
55
  retval = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8,
 
56
                           gdk_pixbuf_get_width (pixbuf) + 2,
 
57
                           gdk_pixbuf_get_height (pixbuf) + 2);
 
58
 
 
59
  /* Fill with solid black */
 
60
  gdk_pixbuf_fill (retval, 0x000000FF);
 
61
 
 
62
  gdk_pixbuf_copy_area (pixbuf,
 
63
                        0, 0,
 
64
                        gdk_pixbuf_get_width (pixbuf),
 
65
                        gdk_pixbuf_get_height (pixbuf),
 
66
                        retval, 1, 1);
 
67
 
 
68
  return retval;
 
69
}
 
70
 
 
71
static GdkPixbuf *
 
72
remove_shaped_area (GdkPixbuf *pixbuf,
 
73
                    Window     window)
 
74
{
 
75
  Display    *display;
 
76
  GdkPixbuf  *retval;
 
77
  XRectangle *rectangles;
 
78
  gint        rectangle_count, rectangle_order;
 
79
  gint        i;
 
80
 
 
81
  retval = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8,
 
82
                           gdk_pixbuf_get_width (pixbuf),
 
83
                           gdk_pixbuf_get_height (pixbuf));
 
84
 
 
85
  gdk_pixbuf_fill (retval, 0);
 
86
 
 
87
  display = gdk_x11_display_get_xdisplay (gdk_display_get_default ());
 
88
 
 
89
  rectangles = XShapeGetRectangles (display, window, ShapeBounding,
 
90
                                    &rectangle_count, &rectangle_order);
 
91
 
 
92
  for (i = 0; i < rectangle_count; i++)
 
93
    {
 
94
      int y, x;
 
95
 
 
96
      for (y = rectangles[i].y;
 
97
           y < rectangles[i].y + rectangles[i].height;
 
98
           y++)
 
99
        {
 
100
          const guchar *src_pixels;
 
101
          guchar       *dest_pixels;
 
102
 
 
103
          src_pixels = gdk_pixbuf_get_pixels (pixbuf) +
 
104
            y * gdk_pixbuf_get_rowstride (pixbuf) +
 
105
            rectangles[i].x * (gdk_pixbuf_get_has_alpha (pixbuf) ? 4 : 3);
 
106
 
 
107
          dest_pixels = gdk_pixbuf_get_pixels (retval) +
 
108
            y * gdk_pixbuf_get_rowstride (retval) +
 
109
            rectangles[i].x * 4;
 
110
 
 
111
          for (x = rectangles[i].x;
 
112
               x < rectangles[i].x + rectangles[i].width;
 
113
               x++)
 
114
            {
 
115
              *dest_pixels++ = *src_pixels ++;
 
116
              *dest_pixels++ = *src_pixels ++;
 
117
              *dest_pixels++ = *src_pixels ++;
 
118
              *dest_pixels++ = 255;
 
119
 
 
120
              if (gdk_pixbuf_get_has_alpha (pixbuf))
 
121
                src_pixels++;
 
122
            }
 
123
        }
 
124
    }
 
125
 
 
126
  return retval;
 
127
}
 
128
 
 
129
static GdkPixbuf *
 
130
take_window_shot (Window   child,
 
131
                  gboolean include_decoration)
 
132
{
 
133
  GdkDisplay *display;
 
134
  GdkScreen  *screen;
 
135
  GdkWindow  *window;
 
136
  Window      xid;
 
137
  gint        x_orig, y_orig;
 
138
  gint        x = 0, y = 0;
 
139
  gint        width, height;
 
140
  GdkPixbuf  *tmp, *tmp2;
 
141
  GdkPixbuf  *retval;
 
142
 
 
143
  display = gdk_display_get_default ();
 
144
  screen = gdk_screen_get_default ();
 
145
 
 
146
  if (include_decoration)
 
147
    xid = find_toplevel_window (gdk_x11_display_get_xdisplay (display), child);
 
148
  else
 
149
    xid = child;
 
150
 
 
151
  window = gdk_window_foreign_new_for_display (display, xid);
 
152
 
 
153
  gdk_drawable_get_size (window, &width, &height);
 
154
  gdk_window_get_origin (window, &x_orig, &y_orig);
 
155
 
 
156
  if (x_orig < 0)
 
157
    {
 
158
      x = - x_orig;
 
159
      width = width + x_orig;
 
160
      x_orig = 0;
 
161
    }
 
162
 
 
163
  if (y_orig < 0)
 
164
    {
 
165
      y = - y_orig;
 
166
      height = height + y_orig;
 
167
      y_orig = 0;
 
168
    }
 
169
 
 
170
  if (x_orig + width > gdk_screen_get_width (screen))
 
171
    width = gdk_screen_get_width (screen) - x_orig;
 
172
 
 
173
  if (y_orig + height > gdk_screen_get_height (screen))
 
174
    height = gdk_screen_get_height (screen) - y_orig;
 
175
 
 
176
  tmp = gdk_pixbuf_get_from_drawable (NULL, window, NULL,
 
177
                                      x, y, 0, 0, width, height);
 
178
 
 
179
  if (include_decoration)
 
180
    tmp2 = remove_shaped_area (tmp, xid);
 
181
  else
 
182
    tmp2 = add_border_to_shot (tmp);
 
183
 
 
184
  retval = create_shadowed_pixbuf (tmp2);
 
185
 
 
186
  g_object_unref (tmp);
 
187
  g_object_unref (tmp2);
 
188
 
 
189
  return retval;
 
190
}
 
191
 
 
192
static gboolean
 
193
shooter_get_foreground (GimpRGB *color)
 
194
{
 
195
  color->r = color->g = color->b = 0.0;
 
196
  color->a = 1.0;
 
197
  return TRUE;
 
198
}
 
199
 
 
200
static gboolean
 
201
shooter_get_background (GimpRGB *color)
 
202
{
 
203
  color->r = color->g = color->b = 1.0;
 
204
  color->a = 1.0;
 
205
  return TRUE;
 
206
}
 
207
 
 
208
static void
 
209
shooter_standard_help (const gchar *help_id,
 
210
                       gpointer     help_data)
 
211
{
 
212
}
 
213
 
 
214
static void
 
215
shooter_ensure_modules (void)
 
216
{
 
217
  static GimpModuleDB *module_db = NULL;
 
218
 
 
219
  if (! module_db)
 
220
    {
 
221
      gchar *config = gimp_config_build_plug_in_path ("modules");
 
222
      gchar *path   = gimp_config_path_expand (config, TRUE, NULL);
 
223
 
 
224
      module_db = gimp_module_db_new (FALSE);
 
225
      gimp_module_db_load (module_db, path);
 
226
 
 
227
      g_free (path);
 
228
      g_free (config);
 
229
    }
 
230
}
 
231
 
 
232
int
 
233
main (int argc, char **argv)
 
234
{
 
235
  GdkPixbuf *screenshot = NULL;
 
236
  GList     *toplevels;
 
237
  GList     *node;
 
238
 
 
239
  g_set_application_name ("GIMP documention shooter");
 
240
 
 
241
  /* If there's no DISPLAY, we silently error out.
 
242
   * We don't want to break headless builds.
 
243
   */
 
244
  if (! gtk_init_check (&argc, &argv))
 
245
    return EXIT_SUCCESS;
 
246
 
 
247
  gtk_rc_add_default_file (gimp_gtkrc ());
 
248
 
 
249
  units_init ();
 
250
 
 
251
  gimp_widgets_init (shooter_standard_help,
 
252
                     shooter_get_foreground,
 
253
                     shooter_get_background,
 
254
                     shooter_ensure_modules);
 
255
 
 
256
  toplevels = get_all_widgets ();
 
257
 
 
258
  for (node = toplevels; node; node = g_list_next (node))
 
259
    {
 
260
      GdkWindow  *window;
 
261
      WidgetInfo *info;
 
262
      XID         xid;
 
263
      gchar      *filename;
 
264
 
 
265
      info = node->data;
 
266
 
 
267
      gtk_widget_show (info->window);
 
268
 
 
269
      window = info->window->window;
 
270
 
 
271
      gtk_widget_show_now (info->window);
 
272
      gtk_widget_queue_draw (info->window);
 
273
 
 
274
      while (gtk_events_pending ())
 
275
        {
 
276
          gtk_main_iteration ();
 
277
        }
 
278
      sleep (1);
 
279
 
 
280
      while (gtk_events_pending ())
 
281
        {
 
282
          gtk_main_iteration ();
 
283
        }
 
284
 
 
285
      xid = gdk_x11_drawable_get_xid (GDK_DRAWABLE (window));
 
286
      screenshot = take_window_shot (xid, info->include_decorations);
 
287
 
 
288
      filename = g_strdup_printf ("%s.png", info->name);
 
289
      gdk_pixbuf_save (screenshot, filename, "png", NULL, NULL);
 
290
      g_free(filename);
 
291
 
 
292
      gtk_widget_hide (info->window);
 
293
    }
 
294
 
 
295
  return EXIT_SUCCESS;
 
296
}