diff options
Diffstat (limited to 'src/gtkutil.c')
| -rw-r--r-- | src/gtkutil.c | 132 |
1 files changed, 81 insertions, 51 deletions
diff --git a/src/gtkutil.c b/src/gtkutil.c index 1cb1004f576..3b590e0faed 100644 --- a/src/gtkutil.c +++ b/src/gtkutil.c | |||
| @@ -1,6 +1,5 @@ | |||
| 1 | /* Functions for creating and updating GTK widgets. | 1 | /* Functions for creating and updating GTK widgets. |
| 2 | Copyright (C) 2003 | 2 | Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc. |
| 3 | Free Software Foundation, Inc. | ||
| 4 | 3 | ||
| 5 | This file is part of GNU Emacs. | 4 | This file is part of GNU Emacs. |
| 6 | 5 | ||
| @@ -240,6 +239,64 @@ xg_create_default_cursor (dpy) | |||
| 240 | return gdk_cursor_new_for_display (gdpy, GDK_LEFT_PTR); | 239 | return gdk_cursor_new_for_display (gdpy, GDK_LEFT_PTR); |
| 241 | } | 240 | } |
| 242 | 241 | ||
| 242 | /* Apply GMASK to GPIX and return a GdkPixbuf with an alpha channel. */ | ||
| 243 | |||
| 244 | static GdkPixbuf * | ||
| 245 | xg_get_pixbuf_from_pix_and_mask (gpix, gmask, cmap) | ||
| 246 | GdkPixmap *gpix; | ||
| 247 | GdkPixmap *gmask; | ||
| 248 | GdkColormap *cmap; | ||
| 249 | { | ||
| 250 | int x, y, width, height, rowstride, mask_rowstride; | ||
| 251 | GdkPixbuf *icon_buf, *tmp_buf; | ||
| 252 | guchar *pixels; | ||
| 253 | guchar *mask_pixels; | ||
| 254 | |||
| 255 | gdk_drawable_get_size (gpix, &width, &height); | ||
| 256 | tmp_buf = gdk_pixbuf_get_from_drawable (NULL, gpix, cmap, | ||
| 257 | 0, 0, 0, 0, width, height); | ||
| 258 | icon_buf = gdk_pixbuf_add_alpha (tmp_buf, FALSE, 0, 0, 0); | ||
| 259 | g_object_unref (G_OBJECT (tmp_buf)); | ||
| 260 | |||
| 261 | if (gmask) | ||
| 262 | { | ||
| 263 | GdkPixbuf *mask_buf = gdk_pixbuf_get_from_drawable (NULL, | ||
| 264 | gmask, | ||
| 265 | NULL, | ||
| 266 | 0, 0, 0, 0, | ||
| 267 | width, height); | ||
| 268 | guchar *pixels = gdk_pixbuf_get_pixels (icon_buf); | ||
| 269 | guchar *mask_pixels = gdk_pixbuf_get_pixels (mask_buf); | ||
| 270 | int rowstride = gdk_pixbuf_get_rowstride (icon_buf); | ||
| 271 | int mask_rowstride = gdk_pixbuf_get_rowstride (mask_buf); | ||
| 272 | int y; | ||
| 273 | |||
| 274 | for (y = 0; y < height; ++y) | ||
| 275 | { | ||
| 276 | guchar *iconptr, *maskptr; | ||
| 277 | int x; | ||
| 278 | |||
| 279 | iconptr = pixels + y * rowstride; | ||
| 280 | maskptr = mask_pixels + y * mask_rowstride; | ||
| 281 | |||
| 282 | for (x = 0; x < width; ++x) | ||
| 283 | { | ||
| 284 | /* In a bitmap, RGB is either 255/255/255 or 0/0/0. Checking | ||
| 285 | just R is sufficient. */ | ||
| 286 | if (maskptr[0] == 0) | ||
| 287 | iconptr[3] = 0; /* 0, 1, 2 is R, G, B. 3 is alpha. */ | ||
| 288 | |||
| 289 | iconptr += rowstride/width; | ||
| 290 | maskptr += mask_rowstride/width; | ||
| 291 | } | ||
| 292 | } | ||
| 293 | |||
| 294 | g_object_unref (G_OBJECT (mask_buf)); | ||
| 295 | } | ||
| 296 | |||
| 297 | return icon_buf; | ||
| 298 | } | ||
| 299 | |||
| 243 | /* For the image defined in IMG, make and return a GtkImage. For displays with | 300 | /* For the image defined in IMG, make and return a GtkImage. For displays with |
| 244 | 8 planes or less we must make a GdkPixbuf and apply the mask manually. | 301 | 8 planes or less we must make a GdkPixbuf and apply the mask manually. |
| 245 | Otherwise the highlightning and dimming the tool bar code in GTK does | 302 | Otherwise the highlightning and dimming the tool bar code in GTK does |
| @@ -312,60 +369,15 @@ xg_get_image_for_pixmap (f, img, widget, old_widget) | |||
| 312 | } | 369 | } |
| 313 | else | 370 | else |
| 314 | { | 371 | { |
| 372 | |||
| 315 | /* This is a workaround to make icons look good on pseudo color | 373 | /* This is a workaround to make icons look good on pseudo color |
| 316 | displays. Apparently GTK expects the images to have an alpha | 374 | displays. Apparently GTK expects the images to have an alpha |
| 317 | channel. If they don't, insensitive and activated icons will | 375 | channel. If they don't, insensitive and activated icons will |
| 318 | look bad. This workaround does not work on monochrome displays, | 376 | look bad. This workaround does not work on monochrome displays, |
| 319 | and is not needed on true color/static color displays (i.e. | 377 | and is not needed on true color/static color displays (i.e. |
| 320 | 16 bits and higher). */ | 378 | 16 bits and higher). */ |
| 321 | int x, y, width, height, rowstride, mask_rowstride; | 379 | GdkColormap *cmap = gtk_widget_get_colormap (widget); |
| 322 | GdkPixbuf *icon_buf, *tmp_buf; | 380 | GdkPixbuf *icon_buf = xg_get_pixbuf_from_pix_and_mask (gpix, gmask, cmap); |
| 323 | guchar *pixels; | ||
| 324 | guchar *mask_pixels; | ||
| 325 | |||
| 326 | gdk_drawable_get_size (gpix, &width, &height); | ||
| 327 | tmp_buf = gdk_pixbuf_get_from_drawable (NULL, | ||
| 328 | gpix, | ||
| 329 | gtk_widget_get_colormap (widget), | ||
| 330 | 0, 0, 0, 0, width, height); | ||
| 331 | icon_buf = gdk_pixbuf_add_alpha (tmp_buf, FALSE, 0, 0, 0); | ||
| 332 | g_object_unref (G_OBJECT (tmp_buf)); | ||
| 333 | |||
| 334 | if (gmask) | ||
| 335 | { | ||
| 336 | GdkPixbuf *mask_buf = gdk_pixbuf_get_from_drawable (NULL, | ||
| 337 | gmask, | ||
| 338 | NULL, | ||
| 339 | 0, 0, 0, 0, | ||
| 340 | width, height); | ||
| 341 | guchar *pixels = gdk_pixbuf_get_pixels (icon_buf); | ||
| 342 | guchar *mask_pixels = gdk_pixbuf_get_pixels (mask_buf); | ||
| 343 | int rowstride = gdk_pixbuf_get_rowstride (icon_buf); | ||
| 344 | int mask_rowstride = gdk_pixbuf_get_rowstride (mask_buf); | ||
| 345 | int y; | ||
| 346 | |||
| 347 | for (y = 0; y < height; ++y) | ||
| 348 | { | ||
| 349 | guchar *iconptr, *maskptr; | ||
| 350 | int x; | ||
| 351 | |||
| 352 | iconptr = pixels + y * rowstride; | ||
| 353 | maskptr = mask_pixels + y * mask_rowstride; | ||
| 354 | |||
| 355 | for (x = 0; x < width; ++x) | ||
| 356 | { | ||
| 357 | /* In a bitmap, RGB is either 255/255/255 or 0/0/0. Checking | ||
| 358 | just R is sufficient. */ | ||
| 359 | if (maskptr[0] == 0) | ||
| 360 | iconptr[3] = 0; /* 0, 1, 2 is R, G, B. 3 is alpha. */ | ||
| 361 | |||
| 362 | iconptr += rowstride/width; | ||
| 363 | maskptr += mask_rowstride/width; | ||
| 364 | } | ||
| 365 | } | ||
| 366 | |||
| 367 | g_object_unref (G_OBJECT (mask_buf)); | ||
| 368 | } | ||
| 369 | 381 | ||
| 370 | if (! old_widget) | 382 | if (! old_widget) |
| 371 | old_widget = GTK_IMAGE (gtk_image_new_from_pixbuf (icon_buf)); | 383 | old_widget = GTK_IMAGE (gtk_image_new_from_pixbuf (icon_buf)); |
| @@ -940,6 +952,24 @@ xg_set_background_color (f, bg) | |||
| 940 | } | 952 | } |
| 941 | 953 | ||
| 942 | 954 | ||
| 955 | /* Set the frame icon to ICON_PIXMAP/MASK. This must be done with GTK | ||
| 956 | functions so GTK does not overwrite the icon. */ | ||
| 957 | |||
| 958 | void | ||
| 959 | xg_set_frame_icon (f, icon_pixmap, icon_mask) | ||
| 960 | FRAME_PTR f; | ||
| 961 | Pixmap icon_pixmap; | ||
| 962 | Pixmap icon_mask; | ||
| 963 | { | ||
| 964 | GdkDisplay *gdpy = gdk_x11_lookup_xdisplay (FRAME_X_DISPLAY (f)); | ||
| 965 | GdkPixmap *gpix = gdk_pixmap_foreign_new_for_display (gdpy, icon_pixmap); | ||
| 966 | GdkPixmap *gmask = gdk_pixmap_foreign_new_for_display (gdpy, icon_mask); | ||
| 967 | GdkPixbuf *gp = xg_get_pixbuf_from_pix_and_mask (gpix, gmask, NULL); | ||
| 968 | |||
| 969 | gtk_window_set_icon (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), gp); | ||
| 970 | } | ||
| 971 | |||
| 972 | |||
| 943 | 973 | ||
| 944 | /*********************************************************************** | 974 | /*********************************************************************** |
| 945 | Dialog functions | 975 | Dialog functions |
| @@ -2607,7 +2637,7 @@ xg_modify_menubar_widgets (menubar, f, val, deep_p, | |||
| 2607 | xg_update_menubar (menubar, f, &list, list, 0, val->contents, | 2637 | xg_update_menubar (menubar, f, &list, list, 0, val->contents, |
| 2608 | select_cb, highlight_cb, cl_data); | 2638 | select_cb, highlight_cb, cl_data); |
| 2609 | 2639 | ||
| 2610 | if (deep_p); | 2640 | if (deep_p) |
| 2611 | { | 2641 | { |
| 2612 | widget_value *cur; | 2642 | widget_value *cur; |
| 2613 | 2643 | ||