~ubuntu-branches/ubuntu/saucy/thunar/saucy

« back to all changes in this revision

Viewing changes to thunar/thunar-gdk-extensions.c

  • Committer: Package Import Robot
  • Author(s): Lionel Le Folgoc
  • Date: 2012-12-03 13:13:58 UTC
  • mfrom: (1.3.4)
  • Revision ID: package-import@ubuntu.com-20121203131358-zk6tkel37d732wh6
Tags: 1.6.0-0ubuntu1
* Upload to raring.
* Remaining Ubuntu change:
  - debian/control: recommend udisks2 for mounting devices. lp: #1014632
* Drop obsolete Ubuntu changes:
  - debian/patches/02_guard-for-no-supported-vfs-schemas.patch,
    debian/patches/xubuntu_fix-duplicate-volumes.patch: included upstream.
* Bugs fixed:
  - "Thunar: sendto_printer broken" lp: #1061846
  - "segfault when a specific html file is selected" lp: #751739
  - "can't book mark remote shares" lp: #778268
  - "Thunar crashed with SIGSEGV in thunarx_menu_provider_get_file_actions()
    thinking a directory was a file" lp: #852410
  - "Left or right-clicking on 3MB or bigger svg file is unresponsive"
    lp: #893330
  - "Thunar crashed with SIGSEGV in fast_validate()" lp: #913041
  - "Thunar crashed with SIGSEGV in thunar_file_get_display_name()"
    lp: #931101
  - "Thunar crashed with SIGSEGV in sort_by_mime_type()" lp: #931842
  - "Thunar crashed with SIGSEGV in thunar_util_parse_parent()" lp: #969222
  - "thunar crashed with SIGSEGV in thunar_standard_view_cancel_thumbnailing()"
    lp: #1059397
  - "Does not unmount USB drive when you try first time" lp: #1059997
  - "regression: thunar no longer shows all unmounted, but mountable, volumes
    in sidepane" lp: #1068947
  - "Thunar shows folder sizes wrong" lp: #59235
  - "Right-click "Open With" list not refreshing" lp: #107392
  - "no thunar contextmenu with GTK setting "gtk-menu-popup-delay = 0""
    lp: #127372
  - "rename folder, still active but answers not on 'Enter'" lp: #479975
  - "Thunar hangs on first launch of each session" lp: #775117
  - "emblems disappear on rename" lp: #877755
  - "Remote Deleted file in Thunar remains visible until resfresh" lp: #999824
  - "Incorrect alphabetical sort order in thunar with non-latin (eg. cyrillic)
    file names" lp: #684317
  - "Thunar does not display current folder name" lp: #875193
  - "Thunar crashed with SIGSEGV in g_file_equal()" lp: #900306
  - "Hard to see, if volume is mounted or not" lp: #838917

Show diffs side-by-side

added added

removed removed

Lines of Context:
39
39
 
40
40
 
41
41
 
 
42
static const cairo_user_data_key_t cairo_key;
 
43
 
 
44
 
 
45
 
 
46
static cairo_surface_t *
 
47
thunar_gdk_cairo_create_surface (const GdkPixbuf *pixbuf)
 
48
{
 
49
  gint             width;
 
50
  gint             height;
 
51
  guchar          *gdk_pixels;
 
52
  gint             gdk_rowstride;
 
53
  gint             n_channels;
 
54
  gint             cairo_stride;
 
55
  guchar          *cairo_pixels;
 
56
  cairo_format_t   format;
 
57
  cairo_surface_t *surface;
 
58
  gint             j;
 
59
  guchar          *p, *q;
 
60
  guchar          *end;
 
61
 
 
62
  _thunar_return_val_if_fail (GDK_IS_PIXBUF (pixbuf), NULL);
 
63
 
 
64
  /* get pixbuf information */
 
65
  width = gdk_pixbuf_get_width (pixbuf);
 
66
  height = gdk_pixbuf_get_height (pixbuf);
 
67
  gdk_pixels = gdk_pixbuf_get_pixels (pixbuf);
 
68
  gdk_rowstride = gdk_pixbuf_get_rowstride (pixbuf);
 
69
  n_channels = gdk_pixbuf_get_n_channels (pixbuf);
 
70
 
 
71
  if (n_channels == 3)
 
72
    format = CAIRO_FORMAT_RGB24;
 
73
  else
 
74
    format = CAIRO_FORMAT_ARGB32;
 
75
 
 
76
  /* prepare pixel data and surface */
 
77
  cairo_stride = cairo_format_stride_for_width (format, width);
 
78
  cairo_pixels = g_malloc (height * cairo_stride);
 
79
  surface = cairo_image_surface_create_for_data (cairo_pixels, format,
 
80
                                                 width, height, cairo_stride);
 
81
  cairo_surface_set_user_data (surface, &cairo_key, cairo_pixels, g_free);
 
82
 
 
83
  /* convert format */
 
84
  if (G_UNLIKELY (n_channels == 3))
 
85
    {
 
86
      for (j = height; j; j--)
 
87
        {
 
88
          p = gdk_pixels;
 
89
          q = cairo_pixels;
 
90
          end = p + 3 * width;
 
91
 
 
92
          while (p < end)
 
93
            {
 
94
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
 
95
              q[0] = p[2];
 
96
              q[1] = p[1];
 
97
              q[2] = p[0];
 
98
#else
 
99
              q[1] = p[0];
 
100
              q[2] = p[1];
 
101
              q[3] = p[2];
 
102
#endif
 
103
              p += 3;
 
104
              q += 4;
 
105
            }
 
106
 
 
107
          gdk_pixels += gdk_rowstride;
 
108
          cairo_pixels += cairo_stride;
 
109
        }
 
110
    }
 
111
  else
 
112
    {
 
113
#define MULT(d,c,a) G_STMT_START { guint t = c * a + 0x7f; d = ((t >> 8) + t) >> 8; } G_STMT_END
 
114
      for (j = height; j; j--)
 
115
        {
 
116
          p = gdk_pixels;
 
117
          q = cairo_pixels;
 
118
          end = p + 4 * width;
 
119
 
 
120
          while (p < end)
 
121
            {
 
122
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
 
123
              MULT(q[0], p[2], p[3]);
 
124
              MULT(q[1], p[1], p[3]);
 
125
              MULT(q[2], p[0], p[3]);
 
126
              q[3] = p[3];
 
127
#else
 
128
              q[0] = p[3];
 
129
              MULT(q[1], p[0], p[3]);
 
130
              MULT(q[2], p[1], p[3]);
 
131
              MULT(q[3], p[2], p[3]);
 
132
#endif
 
133
 
 
134
              p += 4;
 
135
              q += 4;
 
136
            }
 
137
 
 
138
          gdk_pixels += gdk_rowstride;
 
139
          cairo_pixels += cairo_stride;
 
140
        }
 
141
#undef MULT
 
142
    }
 
143
 
 
144
  return surface;
 
145
}
 
146
 
 
147
 
 
148
 
42
149
/**
43
150
 * thunar_gdk_screen_open:
44
151
 * @display_name : a fully qualified display name.
128
235
 
129
236
  return screen;
130
237
}
 
238
 
 
239
 
 
240
 
 
241
/**
 
242
 * thunar_gdk_cairo_set_source_pixbuf:
 
243
 * cr       : a Cairo context
 
244
 * pixbuf   : a GdkPixbuf
 
245
 * pixbuf_x : X coordinate of location to place upper left corner of pixbuf
 
246
 * pixbuf_y : Y coordinate of location to place upper left corner of pixbuf
 
247
 *
 
248
 * Works like gdk_cairo_set_source_pixbuf but we try to cache the surface
 
249
 * on the pixbuf, which is efficient within Thunar because we also share
 
250
 * the pixbufs using the icon cache.
 
251
 **/
 
252
void
 
253
thunar_gdk_cairo_set_source_pixbuf (cairo_t   *cr,
 
254
                                    GdkPixbuf *pixbuf,
 
255
                                    gdouble    pixbuf_x,
 
256
                                    gdouble    pixbuf_y)
 
257
{
 
258
  cairo_surface_t *surface;
 
259
  static GQuark    surface_quark = 0;
 
260
 
 
261
  if (G_UNLIKELY (surface_quark == 0))
 
262
    surface_quark = g_quark_from_static_string ("thunar-gdk-surface");
 
263
 
 
264
  /* peek if there is already a surface */
 
265
  surface = g_object_get_qdata (G_OBJECT (pixbuf), surface_quark);
 
266
  if (surface == NULL)
 
267
    {
 
268
      /* create a new surface */
 
269
      surface = thunar_gdk_cairo_create_surface (pixbuf);
 
270
 
 
271
      /* store the pixbuf on the pixbuf */
 
272
      g_object_set_qdata_full (G_OBJECT (pixbuf), surface_quark,
 
273
                               surface, (GDestroyNotify) cairo_surface_destroy);
 
274
    }
 
275
 
 
276
  /* apply */
 
277
  cairo_set_source_surface (cr, surface, pixbuf_x, pixbuf_y);
 
278
}