[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Adding mask to the window icon
From: |
Terje Rosten |
Subject: |
Adding mask to the window icon |
Date: |
Fri, 23 May 2003 12:44:51 +0200 |
User-agent: |
Gnus/5.1003 (Gnus v5.10.3) Emacs/21.2 (gnu/linux) |
I have added support for the WM_HINTS IconMaskHint property.
In order the achieve this I have added a new member to the
x_bitmap_record struct in xterm.h and created a two new functions for
bitmaps: x_bitmap_mask() and x_create_bitmap_mask().
Gtk+ has a simple gtk_window_set_icon_from_file() and in the patch
this function is used instead of the internal Emacs icon machinery if
Emacs is compiled with Gtk+ support. The advantage of this is that the
icon then will not be restricted to bitmaps. The new relevant function
is xg_set_icon in xfns.c.
Please review the patch and apply if it's appropriate.
- Terje
Index: src/xfns.c
===================================================================
RCS file: /cvsroot/emacs/emacs/src/xfns.c,v
retrieving revision 1.579
diff -c -r1.579 xfns.c
*** src/xfns.c 21 May 2003 22:12:15 -0000 1.579
--- src/xfns.c 23 May 2003 09:58:04 -0000
***************
*** 550,555 ****
--- 550,563 ----
return FRAME_X_DISPLAY_INFO (f)->bitmaps[id - 1].pixmap;
}
+ int
+ x_bitmap_mask (f, id)
+ FRAME_PTR f;
+ int id;
+ {
+ return FRAME_X_DISPLAY_INFO (f)->bitmaps[id - 1].mask;
+ }
+
/* Allocate a new bitmap record. Returns index of new record. */
***************
*** 693,698 ****
--- 701,707 ----
{
BLOCK_INPUT;
XFreePixmap (FRAME_X_DISPLAY (f), dpyinfo->bitmaps[id - 1].pixmap);
+ XFreePixmap (FRAME_X_DISPLAY (f), dpyinfo->bitmaps[id - 1].mask);
if (dpyinfo->bitmaps[id - 1].file)
{
xfree (dpyinfo->bitmaps[id - 1].file);
***************
*** 714,719 ****
--- 723,729 ----
if (dpyinfo->bitmaps[i].refcount > 0)
{
XFreePixmap (dpyinfo->display, dpyinfo->bitmaps[i].pixmap);
+ XFreePixmap (dpyinfo->display, dpyinfo->bitmaps[i].mask);
if (dpyinfo->bitmaps[i].file)
xfree (dpyinfo->bitmaps[i].file);
}
***************
*** 721,726 ****
--- 731,835 ----
}
+
+
+ /* Useful functions defined in the section
+ `Image type independent image structures' below. */
+
+ static unsigned long four_corners_best P_ ((XImage *ximg, unsigned long
width,
+ unsigned long height));
+
+ static int x_create_x_image_and_pixmap P_ ((struct frame *f, int width, int
height,
+ int depth, XImage **ximg,
+ Pixmap *pixmap));
+
+ static void x_destroy_x_image P_ ((XImage *ximg));
+
+
+ /* Create a mask of a bitmap. Note is this not a perfect mask.
+ It's nicer with some borders in this context */
+
+ int
+ x_create_bitmap_mask(f, id)
+ struct frame *f;
+ int id;
+ {
+ Pixmap pixmap, mask;
+ XImage *ximg, *mask_img;
+ unsigned long width, height;
+ int result;
+ unsigned long bg;
+ unsigned long x, y, xp, xm, yp, ym;
+ GC gc;
+
+ int depth = DefaultDepthOfScreen (FRAME_X_SCREEN (f));
+ struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
+
+ if (!(id > 0))
+ return -1;
+
+ pixmap = x_bitmap_pixmap(f, id);
+ width = x_bitmap_width(f, id);
+ height = x_bitmap_height(f, id);
+
+ BLOCK_INPUT;
+ ximg = XGetImage (FRAME_X_DISPLAY (f), pixmap, 0, 0, width, height,
+ ~0, ZPixmap);
+
+ if (!ximg)
+ {
+ UNBLOCK_INPUT;
+ return -1;
+ }
+
+ result = x_create_x_image_and_pixmap (f, width, height, 1, &mask_img,
&mask);
+
+ UNBLOCK_INPUT;
+ if (!result)
+ {
+ XDestroyImage(ximg);
+ return -1;
+ }
+
+ bg = four_corners_best (ximg, width, height);
+
+ for (y = 0; y < ximg->height; ++y)
+ {
+ for (x = 0; x < ximg->width; ++x)
+ {
+ xp = x != ximg->width - 1 ? x + 1 : 0;
+ xm = x != 0 ? x - 1 : ximg->width - 1;
+ yp = y != ximg->height - 1 ? y + 1 : 0;
+ ym = y != 0 ? y - 1 : ximg->height - 1;
+ if (XGetPixel (ximg, x, y) == bg
+ && XGetPixel (ximg, x, yp) == bg
+ && XGetPixel (ximg, x, ym) == bg
+ && XGetPixel (ximg, xp, y) == bg
+ && XGetPixel (ximg, xp, yp) == bg
+ && XGetPixel (ximg, xp, ym) == bg
+ && XGetPixel (ximg, xm, y) == bg
+ && XGetPixel (ximg, xm, yp) == bg
+ && XGetPixel (ximg, xm, ym) == bg)
+ XPutPixel (mask_img, x, y, 0);
+ else
+ XPutPixel (mask_img, x, y, 1);
+ }
+ }
+
+ xassert (interrupt_input_blocked);
+ gc = XCreateGC (FRAME_X_DISPLAY (f), mask, 0, NULL);
+ XPutImage (FRAME_X_DISPLAY (f), mask, gc, mask_img, 0, 0, 0, 0,
+ width, height);
+ XFreeGC (FRAME_X_DISPLAY (f), gc);
+
+ dpyinfo->bitmaps[id - 1].mask = mask;
+
+ XDestroyImage (ximg);
+ x_destroy_x_image(mask_img);
+
+ return 0;
+ }
+
static Lisp_Object unwind_create_frame P_ ((Lisp_Object));
static Lisp_Object unwind_create_tip_frame P_ ((Lisp_Object));
static void x_disable_image P_ ((struct frame *, struct image *));
***************
*** 974,979 ****
--- 1083,1123 ----
{
f->output_data.x->wait_for_wm = !NILP (new_value);
}
+
+ #ifdef USE_GTK
+
+ /* Wrapper for gtk_window_icon_from_file() */
+
+ int
+ xg_set_icon(f, file)
+ struct frame *f;
+ Lisp_Object file;
+ {
+ struct gcpro gcpro1, gcpro2, gcpro3;
+ int fd;
+ int result = 1;
+ Lisp_Object found, search_path;
+ char *filename;
+
+ search_path = Fcons (Vdata_directory, Vx_bitmap_file_path);
+
+ GCPRO3 (found, search_path, file);
+ fd = openp (search_path, file, Qnil, &found, Qnil);
+ if (fd > 0)
+ {
+ filename = (char *) SDATA (found);
+ BLOCK_INPUT;
+ result =
+ gtk_window_set_icon_from_file (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET
(f)),
+ filename,
+ NULL);
+ UNBLOCK_INPUT;
+ }
+ emacs_close (fd);
+ UNGCPRO;
+ return result;
+ }
+ #endif /* USE_GTK */
/* Functions called only from `x_set_frame_param'
Index: src/xterm.c
===================================================================
RCS file: /cvsroot/emacs/emacs/src/xterm.c,v
retrieving revision 1.793
diff -c -r1.793 xterm.c
*** src/xterm.c 21 May 2003 22:11:50 -0000 1.793
--- src/xterm.c 23 May 2003 09:58:05 -0000
***************
*** 7479,7502 ****
if (FRAME_X_WINDOW (f) == 0)
return 1;
! /* Free up our existing icon bitmap if any. */
if (f->output_data.x->icon_bitmap > 0)
x_destroy_bitmap (f, f->output_data.x->icon_bitmap);
f->output_data.x->icon_bitmap = 0;
if (STRINGP (file))
! bitmap_id = x_create_bitmap_from_file (f, file);
else
{
! /* Create the GNU bitmap if necessary. */
if (FRAME_X_DISPLAY_INFO (f)->icon_bitmap_id < 0)
! FRAME_X_DISPLAY_INFO (f)->icon_bitmap_id
! = x_create_bitmap_from_data (f, gnu_bits,
! gnu_width, gnu_height);
! /* The first time we create the GNU bitmap,
this increments the ref-count one extra time.
! As a result, the GNU bitmap is never freed.
That way, we don't have to worry about allocating it again. */
x_reference_bitmap (f, FRAME_X_DISPLAY_INFO (f)->icon_bitmap_id);
--- 7479,7514 ----
if (FRAME_X_WINDOW (f) == 0)
return 1;
! /* Free up our existing icon bitmap and mask if any. */
if (f->output_data.x->icon_bitmap > 0)
x_destroy_bitmap (f, f->output_data.x->icon_bitmap);
f->output_data.x->icon_bitmap = 0;
if (STRINGP (file))
! {
! #ifdef USE_GTK
! /* Use gtk_window_set_icon_from_file() if available,
! It's not restricted to bitmaps */
! if (!xg_set_icon(f, file))
! return 0;
! #endif /* USE_GTK */
! bitmap_id = x_create_bitmap_from_file (f, file);
! x_create_bitmap_mask(f, bitmap_id);
! }
else
{
! /* Create the GNU bitmap and mask if necessary. */
if (FRAME_X_DISPLAY_INFO (f)->icon_bitmap_id < 0)
! {
! FRAME_X_DISPLAY_INFO (f)->icon_bitmap_id
! = x_create_bitmap_from_data (f, gnu_bits,
! gnu_width, gnu_height);
! x_create_bitmap_mask(f, FRAME_X_DISPLAY_INFO (f)->icon_bitmap_id);
! }
! /* The first time we create the GNU bitmap and mask,
this increments the ref-count one extra time.
! As a result, the GNU bitmap and mask are never freed.
That way, we don't have to worry about allocating it again. */
x_reference_bitmap (f, FRAME_X_DISPLAY_INFO (f)->icon_bitmap_id);
***************
*** 9315,9321 ****
struct frame *f;
int pixmap_id;
{
! Pixmap icon_pixmap;
#ifndef USE_X_TOOLKIT
Window window = FRAME_OUTER_WINDOW (f);
--- 9327,9333 ----
struct frame *f;
int pixmap_id;
{
! Pixmap icon_pixmap, icon_mask;
#ifndef USE_X_TOOLKIT
Window window = FRAME_OUTER_WINDOW (f);
***************
*** 9325,9330 ****
--- 9337,9344 ----
{
icon_pixmap = x_bitmap_pixmap (f, pixmap_id);
f->output_data.x->wm_hints.icon_pixmap = icon_pixmap;
+ icon_mask = x_bitmap_mask (f, pixmap_id);
+ f->output_data.x->wm_hints.icon_mask = icon_mask;
}
else
{
***************
*** 9337,9342 ****
--- 9351,9357 ----
best to explicitly give up. */
#if 0
f->output_data.x->wm_hints.icon_pixmap = None;
+ f->output_data.x->wm_hints.icon_mask = None;
#else
return;
#endif
***************
*** 9348,9358 ****
Arg al[1];
XtSetArg (al[0], XtNiconPixmap, icon_pixmap);
XtSetValues (f->output_data.x->widget, al, 1);
}
#else /* not USE_X_TOOLKIT */
! f->output_data.x->wm_hints.flags |= IconPixmapHint;
XSetWMHints (FRAME_X_DISPLAY (f), window, &f->output_data.x->wm_hints);
#endif /* not USE_X_TOOLKIT */
--- 9363,9375 ----
Arg al[1];
XtSetArg (al[0], XtNiconPixmap, icon_pixmap);
XtSetValues (f->output_data.x->widget, al, 1);
+ XtSetArg (al[0], XtNiconMask, icon_mask);
+ XtSetValues (f->output_data.x->widget, al, 1);
}
#else /* not USE_X_TOOLKIT */
! f->output_data.x->wm_hints.flags |= (IconPixmapHint | IconMaskHint);
XSetWMHints (FRAME_X_DISPLAY (f), window, &f->output_data.x->wm_hints);
#endif /* not USE_X_TOOLKIT */
Index: src/xterm.h
===================================================================
RCS file: /cvsroot/emacs/emacs/src/xterm.h,v
retrieving revision 1.147
diff -c -r1.147 xterm.h
*** src/xterm.h 21 May 2003 22:11:31 -0000 1.147
--- src/xterm.h 23 May 2003 09:58:05 -0000
***************
*** 126,131 ****
--- 126,132 ----
struct x_bitmap_record
{
Pixmap pixmap;
+ Pixmap mask;
char *file;
int refcount;
/* Record some info about this pixmap. */
***************
*** 1096,1101 ****
--- 1097,1106 ----
unsigned int, unsigned int));
extern int x_create_bitmap_from_file P_ ((struct frame *, Lisp_Object));
extern void x_destroy_bitmap P_ ((struct frame *, int));
+ extern int x_create_bitmap_mask P_ ((struct frame * , int));
+
+ extern int xg_set_icon P_ ((struct frame *, Lisp_Object));
+
extern void x_real_positions P_ ((struct frame *, int *, int *));
extern int defined_color P_ ((struct frame *, char *, XColor *, int));
extern void x_set_border_pixel P_ ((struct frame *, int));
- Adding mask to the window icon,
Terje Rosten <=