*** lib-src/make-docfile.c.~1.56.~ Mon Jan 5 09:55:10 2004 --- lib-src/make-docfile.c Mon Jan 12 17:14:03 2004 *************** *** 43,53 **** #undef chdir #include #ifdef MSDOS #include #endif /* MSDOS */ #ifdef WINDOWSNT - #include #include #include #endif /* WINDOWSNT */ --- 43,53 ---- #undef chdir #include + #include #ifdef MSDOS #include #endif /* MSDOS */ #ifdef WINDOWSNT #include #include #endif /* WINDOWSNT */ *** mac/makefile.MPW.~1.9.~ Tue Sep 2 00:45:41 2003 --- mac/makefile.MPW Mon Jan 12 19:31:40 2004 *************** *** 142,147 **** --- 142,148 ---- "{SharedLibraries}AppleScriptLib" ¶ "{SharedLibraries}TextEncodingConverter" ¶ "{SharedLibraries}AppearanceLib" ¶ + "{SharedLibraries}QuickTimeLib" ¶ "{PPCLibraries}StdCRuntime.o" ¶ "{PPCLibraries}PPCCRuntime.o" ¶ "{PPCLibraries}PPCToolLibs.o" ¶ *************** *** 1017,1023 **** {Lisp}international:codepage.elc ¶ {Lisp}abbrev.elc ¶ {Lisp}buff-menu.elc ¶ ! {Lisp}byte-run.elc ¶ {Lisp}cus-start.el ¶ {Lisp}custom.elc ¶ {Lisp}emacs-lisp:lisp-mode.elc ¶ --- 1018,1024 ---- {Lisp}international:codepage.elc ¶ {Lisp}abbrev.elc ¶ {Lisp}buff-menu.elc ¶ ! {Lisp}emacs-lisp:byte-run.elc ¶ {Lisp}cus-start.el ¶ {Lisp}custom.elc ¶ {Lisp}emacs-lisp:lisp-mode.elc ¶ *************** *** 1025,1031 **** {Lisp}facemenu.elc ¶ {Lisp}faces.elc ¶ {Lisp}files.elc ¶ ! {Lisp}float-sup.elc ¶ {Lisp}format.elc ¶ {Lisp}frame.elc ¶ {Lisp}help.elc ¶ --- 1026,1032 ---- {Lisp}facemenu.elc ¶ {Lisp}faces.elc ¶ {Lisp}files.elc ¶ ! {Lisp}emacs-lisp:float-sup.elc ¶ {Lisp}format.elc ¶ {Lisp}frame.elc ¶ {Lisp}help.elc ¶ *************** *** 1034,1040 **** {Lisp}loadup.el ¶ {Lisp}loaddefs.el ¶ {Lisp}bindings.elc ¶ ! {Lisp}map-ynp.elc ¶ {Lisp}international:mule.elc ¶ {Lisp}international:mule-conf.el ¶ {Lisp}international:mule-cmds.elc ¶ --- 1035,1041 ---- {Lisp}loadup.el ¶ {Lisp}loaddefs.el ¶ {Lisp}bindings.elc ¶ ! {Lisp}emacs-lisp:map-ynp.elc ¶ {Lisp}international:mule.elc ¶ {Lisp}international:mule-conf.el ¶ {Lisp}international:mule-cmds.elc ¶ *** mac/inc/config.h.~1.4.~ Tue Sep 2 00:45:41 2003 --- mac/inc/config.h Mon Jan 12 22:11:36 2004 *************** *** 261,267 **** /* #undef CRAY_STACKSEG_END */ ! /* #undef UNEXEC_SRC unexelf.c /* #undef HAVE_LIBXBSD */ /* #undef HAVE_XRMSETDATABASE */ --- 261,267 ---- /* #undef CRAY_STACKSEG_END */ ! /* #undef UNEXEC_SRC */ /* #undef HAVE_LIBXBSD */ /* #undef HAVE_XRMSETDATABASE */ *** mac/inc/epaths.h.~1.4.~ Tue Sep 2 00:45:42 2003 --- mac/inc/epaths.h Mon Jan 12 21:34:21 2004 *************** *** 57,62 **** --- 57,65 ---- macro, and is then used to set the Info-default-directory-list. */ #define PATH_INFO "~emacs/info" + /* Where Emacs should store game score files. */ + #define PATH_GAME "~emacs/games" + /* Where Emacs should look for the application default file. */ /* #define PATH_X_DEFAULTS "/usr/lib/X11/%L/%T/%N%C%S:/usr/lib/X11/%l/%T/%N%C%S:/usr/lib/X11/%T/%N%C%S:/usr/lib/X11/%L/%T/%N%S:/usr/lib/X11/%l/%T/%N%S:/usr/lib/X11/%T/%N%S" */ *** mac/inc/s-mac.h.~1.3.~ Tue Sep 2 00:45:44 2003 --- mac/inc/s-mac.h Mon Jan 12 17:47:21 2004 *************** *** 255,260 **** --- 255,264 ---- #include #endif + #ifndef X_OK + #define X_OK 01 + #endif + #undef unlink #define unlink sys_unlink #undef read *** src/alloca.c.~1.28.~ Tue Sep 2 09:09:44 2003 --- src/alloca.c Mon Jan 12 17:37:52 2004 *************** *** 99,106 **** # undef free # define free xfree ! void *xmalloc _P ((size_t)); ! void xfree _P ((void *)) /* Define STACK_DIRECTION if you know the direction of stack growth for your system; otherwise it will be automatically --- 99,106 ---- # undef free # define free xfree ! void *xmalloc __P ((size_t)); ! void xfree __P ((void *)); /* Define STACK_DIRECTION if you know the direction of stack growth for your system; otherwise it will be automatically *** src/dispextern.h.~1.161.~ Wed Jan 7 10:01:29 2004 --- src/dispextern.h Mon Jan 12 18:36:45 2004 *************** *** 58,98 **** typedef struct w32_display_info Display_Info; #endif ! #ifdef HAVE_CARBON #include "macgui.h" typedef struct mac_display_info Display_Info; - - /* Include Carbon.h to define Cursor and Rect. */ - #undef mktime - #undef DEBUG - #undef Z - #undef free - #undef malloc - #undef realloc - /* Macros max and min defined in lisp.h conflict with those in - precompiled header Carbon.h. */ - #undef max - #undef min - #undef init_process - #include - #undef Z - #define Z (current_buffer->text->z) - #undef free - #define free unexec_free - #undef malloc - #define malloc unexec_malloc - #undef realloc - #define realloc unexec_realloc - #undef min - #define min(a, b) ((a) < (b) ? (a) : (b)) - #undef max - #define max(a, b) ((a) > (b) ? (a) : (b)) - #undef init_process - #define init_process emacs_init_process - #endif - #ifndef NativeRectangle #define NativeRectangle int #endif --- 58,68 ---- typedef struct w32_display_info Display_Info; #endif ! #ifdef MAC_OS #include "macgui.h" typedef struct mac_display_info Display_Info; #endif #ifndef NativeRectangle #define NativeRectangle int #endif *************** *** 1098,1104 **** unsigned for_overlaps_p : 1; /* The GC to use for drawing this glyph string. */ ! #if defined(HAVE_X_WINDOWS) || defined(HAVE_CARBON) GC gc; #endif #if defined(HAVE_NTGUI) --- 1068,1074 ---- unsigned for_overlaps_p : 1; /* The GC to use for drawing this glyph string. */ ! #if defined(HAVE_X_WINDOWS) || defined(MAC_OS) GC gc; #endif #if defined(HAVE_NTGUI) *** src/emacs.c.~1.330.~ Mon Nov 17 12:04:03 2003 --- src/emacs.c Mon Jan 12 18:47:41 2004 *************** *** 1526,1537 **** syms_of_fontset (); #endif /* HAVE_NTGUI */ ! #ifdef HAVE_CARBON syms_of_macterm (); syms_of_macfns (); syms_of_macmenu (); syms_of_fontset (); ! #endif /* HAVE_CARBON */ #ifdef SYMS_SYSTEM SYMS_SYSTEM; --- 1526,1537 ---- syms_of_fontset (); #endif /* HAVE_NTGUI */ ! #ifdef MAC_OS syms_of_macterm (); syms_of_macfns (); syms_of_macmenu (); syms_of_fontset (); ! #endif /* MAC_OS */ #ifdef SYMS_SYSTEM SYMS_SYSTEM; *************** *** 1576,1582 **** init_vmsproc (); /* And this too. */ #endif /* VMS */ init_sys_modes (); /* Init system terminal modes (RAW or CBREAK, etc.). */ ! #if defined (HAVE_X_WINDOWS) || defined (WINDOWSNT) init_xfns (); #endif /* HAVE_X_WINDOWS */ init_fns (); --- 1576,1582 ---- init_vmsproc (); /* And this too. */ #endif /* VMS */ init_sys_modes (); /* Init system terminal modes (RAW or CBREAK, etc.). */ ! #if defined (HAVE_X_WINDOWS) || defined (WINDOWSNT) || defined (MAC_OS) init_xfns (); #endif /* HAVE_X_WINDOWS */ init_fns (); *** src/fns.c.~1.354.~ Mon Jan 5 09:55:13 2004 --- src/fns.c Mon Jan 12 22:09:02 2004 *************** *** 26,33 **** #endif #include ! #ifndef MAC_OSX ! /* On Mac OS X, defining this conflicts with precompiled headers. */ /* Note on some machines this defines `vector' as a typedef, so make sure we don't use that name in this file. */ --- 26,33 ---- #endif #include ! #ifndef MAC_OS ! /* On Mac OS, defining this conflicts with precompiled headers. */ /* Note on some machines this defines `vector' as a typedef, so make sure we don't use that name in this file. */ *** src/frame.c.~1.306.~ Mon Nov 17 12:04:05 2003 --- src/frame.c Mon Jan 12 19:00:29 2004 *************** *** 2774,2780 **** XSETINT (icon_top, 0); } ! #ifndef HAVE_CARBON /* MAC_TODO: fullscreen */ if (FRAME_VISIBLE_P (f) && fullscreen_is_being_set) { --- 2774,2780 ---- XSETINT (icon_top, 0); } ! #ifndef MAC_OS /* MAC_TODO: fullscreen */ if (FRAME_VISIBLE_P (f) && fullscreen_is_being_set) { *************** *** 2952,2958 **** store_in_alist (alistptr, Qdisplay, XCAR (FRAME_X_DISPLAY_INFO (f)->name_list_element)); ! #ifndef HAVE_CARBON /* A Mac Window is identified by a struct, not an integer. */ if (FRAME_X_OUTPUT (f)->parent_desc == FRAME_X_DISPLAY_INFO (f)->root_window) tem = Qnil; --- 2952,2958 ---- store_in_alist (alistptr, Qdisplay, XCAR (FRAME_X_DISPLAY_INFO (f)->name_list_element)); ! #ifndef MAC_OS /* A Mac Window is identified by a struct, not an integer. */ if (FRAME_X_OUTPUT (f)->parent_desc == FRAME_X_DISPLAY_INFO (f)->root_window) tem = Qnil; *************** *** 2971,2977 **** struct frame *f; Lisp_Object new_value, old_value; { ! #ifndef HAVE_CARBON if (NILP (new_value)) f->want_fullscreen = FULLSCREEN_NONE; else if (EQ (new_value, Qfullboth)) --- 2971,2977 ---- struct frame *f; Lisp_Object new_value, old_value; { ! #ifndef MAC_OS if (NILP (new_value)) f->want_fullscreen = FULLSCREEN_NONE; else if (EQ (new_value, Qfullboth)) *************** *** 3100,3106 **** if (XINT (arg) == f->border_width) return; ! #ifndef HAVE_CARBON if (FRAME_X_WINDOW (f) != 0) error ("Cannot change the border width of a window"); #endif /* MAC_TODO */ --- 3100,3106 ---- if (XINT (arg) == f->border_width) return; ! #ifndef MAC_OS if (FRAME_X_WINDOW (f) != 0) error ("Cannot change the border width of a window"); #endif /* MAC_TODO */ *************** *** 4011,4017 **** DEFVAR_LISP ("default-frame-scroll-bars", &Vdefault_frame_scroll_bars, doc: /* Default position of scroll bars on this window-system. */); #ifdef HAVE_WINDOW_SYSTEM ! #if defined(HAVE_NTGUI) || defined(HAVE_CARBON) /* MS-Windows has scroll bars on the right by default. */ Vdefault_frame_scroll_bars = Qright; #else --- 4011,4017 ---- DEFVAR_LISP ("default-frame-scroll-bars", &Vdefault_frame_scroll_bars, doc: /* Default position of scroll bars on this window-system. */); #ifdef HAVE_WINDOW_SYSTEM ! #if defined(HAVE_NTGUI) || defined(MAC_OS) /* MS-Windows has scroll bars on the right by default. */ Vdefault_frame_scroll_bars = Qright; #else *** src/macfns.c.~1.26.~ Sun Dec 28 16:03:48 2003 --- src/macfns.c Tue Jan 13 17:38:05 2004 *************** *** 54,97 **** /*#include #include */ #include #include #include #ifndef MAC_OSX #include #endif #ifdef MAC_OSX ! #undef mktime ! #undef DEBUG ! #undef Z ! #undef free ! #undef malloc ! #undef realloc ! /* Macros max and min defined in lisp.h conflict with those in ! precompiled header Carbon.h. */ ! #undef max ! #undef min ! #undef init_process ! #include ! #undef Z ! #define Z (current_buffer->text->z) ! #undef free ! #define free unexec_free ! #undef malloc ! #define malloc unexec_malloc ! #undef realloc ! #define realloc unexec_realloc ! #undef min ! #define min(a, b) ((a) < (b) ? (a) : (b)) ! #undef max ! #define max(a, b) ((a) > (b) ? (a) : (b)) ! #undef init_process ! #define init_process emacs_init_process ! #else /* not MAC_OSX */ #include #include #include #endif /* not MAC_OSX */ /*extern void free_frame_menubar (); --- 54,77 ---- /*#include #include */ #include + #include + #include #include #include #ifndef MAC_OSX #include + #include #endif #ifdef MAC_OSX ! #include ! #else #include #include #include + #include + #include #endif /* not MAC_OSX */ /*extern void free_frame_menubar (); *************** *** 209,214 **** --- 189,200 ---- extern void x_find_ccl_program (struct font_info *); extern struct font_info *x_query_font (struct frame *, char *); extern void mac_initialize (); + extern Pixmap XCreatePixmap (Display *, WindowPtr, unsigned int, unsigned int, unsigned int); + extern Pixmap XCreatePixmapFromBitmapData (Display *, WindowPtr, char *, unsigned int, unsigned int, unsigned long, unsigned long, unsigned int); + extern void XFreePixmap (Display *, Pixmap); + extern void XSetForeground (Display *, GC, unsigned long); + extern void mac_draw_line_to_pixmap (Display *, Pixmap, GC, int, int, int, int); + /* compare two strings ignoring case */ *************** *** 552,564 **** xfree (dpyinfo->bitmaps[i].bitmap_data); dpyinfo->bitmaps_last = 0; } ! /* Connect the frame-parameter names for W32 frames ! to the ways of passing the parameter values to the window system. ! The name of a parameter, as a Lisp symbol, ! has an `x-frame-parameter' property which is an integer in Lisp ! but can be interpreted as an `enum x_frame_parm' in C. */ void x_set_foreground_color P_ ((struct frame *, Lisp_Object, Lisp_Object)); void x_set_background_color P_ ((struct frame *, Lisp_Object, Lisp_Object)); --- 538,626 ---- xfree (dpyinfo->bitmaps[i].bitmap_data); dpyinfo->bitmaps_last = 0; } + + + + /* Mac equivalent of XImage. */ + typedef Pixmap XImagePtr; + #define ZPixmap 0 /* arbitrary */ + + static XImagePtr + XGetImage (display, pixmap, x, y, width, height, plane_mask, format) + Display *display; /* not used */ + Pixmap pixmap; + int x, y; /* not used */ + unsigned int width, height; /* not used */ + unsigned long plane_mask; /* not used */ + int format; /* not used */ + { + #if GLYPH_DEBUG + xassert (x == 0 && y == 0); + { + Rect ri, rp; + SetRect (&ri, 0, 0, width, height); + xassert (EqualRect (&ri, GetPixBounds (GetGWorldPixMap (pixmap), &rp))); + } + xassert (! (pixelsLocked & GetPixelsState (GetGWorldPixMap (pixmap)))); + #endif + + LockPixels (GetGWorldPixMap (pixmap)); + + return pixmap; + } + + static void + XPutPixel (ximage, x, y, pixel) + XImagePtr ximage; + int x, y; + unsigned long pixel; + { + RGBColor color; + + SetGWorld (ximage, NULL); + + color.red = RED16_FROM_ULONG (pixel); + color.green = GREEN16_FROM_ULONG (pixel); + color.blue = BLUE16_FROM_ULONG (pixel); + SetCPixel (x, y, &color); + } + + static unsigned long + XGetPixel (ximage, x, y) + XImagePtr ximage; + int x, y; + { + RGBColor color; + + SetGWorld (ximage, NULL); + + GetCPixel (x, y, &color); + return RGB_TO_ULONG (color.red >> 8, color.green >> 8, color.blue >> 8); + } + + static void + XDestroyImage (ximg) + XImagePtr ximg; + { + UnlockPixels (GetGWorldPixMap (ximg)); + } + + ! /* Useful functions defined in the section ! `Image type independent image structures' below. */ ! ! static unsigned long four_corners_best P_ ((XImagePtr 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, XImagePtr *ximg, ! Pixmap *pixmap)); ! static void x_destroy_x_image P_ ((XImagePtr ximg)); ! ! ! static void x_disable_image P_ ((struct frame *, struct image *)); void x_set_foreground_color P_ ((struct frame *, Lisp_Object, Lisp_Object)); void x_set_background_color P_ ((struct frame *, Lisp_Object, Lisp_Object)); *************** *** 581,586 **** --- 643,655 ---- Lisp_Object, char *, char *, int)); + static void x_edge_detection P_ ((struct frame *, struct image *, Lisp_Object, + Lisp_Object)); + static void init_color_table P_ ((void)); + static void free_color_table P_ ((void)); + static unsigned long *colors_in_color_table P_ ((int *n)); + static unsigned long lookup_rgb_color P_ ((struct frame *f, int r, int g, int b)); + static unsigned long lookup_pixel_color P_ ((struct frame *f, unsigned long p)); /* Store the screen positions of frame F into XPTR and YPTR. These are the positions of the containing window manager window, *************** *** 1616,1624 **** } color_def->pixel = mac_color_ref; ! color_def->red = RED_FROM_ULONG (mac_color_ref); ! color_def->green = GREEN_FROM_ULONG (mac_color_ref); ! color_def->blue = BLUE_FROM_ULONG (mac_color_ref); return 1; } --- 1685,1693 ---- } color_def->pixel = mac_color_ref; ! color_def->red = RED16_FROM_ULONG (mac_color_ref); ! color_def->green = GREEN16_FROM_ULONG (mac_color_ref); ! color_def->blue = BLUE16_FROM_ULONG (mac_color_ref); return 1; } *************** *** 1649,1656 **** return WHITE_PIX_DEFAULT (f); #if 0 ! if ((FRAME_MAC_DISPLAY_INFO (f)->n_planes ! * FRAME_MAC_DISPLAY_INFO (f)->n_cbits) == 1) return def; #endif --- 1718,1724 ---- return WHITE_PIX_DEFAULT (f); #if 0 ! if (FRAME_MAC_DISPLAY_INFO (f)->n_planes) == 1) return def; #endif *************** *** 1674,1681 **** struct frame *f; Lisp_Object arg, oldval; { ! FRAME_FOREGROUND_PIXEL (f) ! = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f)); if (FRAME_MAC_WINDOW (f) != 0) { --- 1742,1752 ---- struct frame *f; Lisp_Object arg, oldval; { ! unsigned long fg, old_fg; ! ! fg = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f)); ! old_fg = FRAME_FOREGROUND_PIXEL (f); ! FRAME_FOREGROUND_PIXEL (f) = fg; if (FRAME_MAC_WINDOW (f) != 0) { *************** *** 1856,1891 **** struct frame *f; Lisp_Object arg, oldval; { ! unsigned long fore_pixel; if (!NILP (Vx_cursor_fore_pixel)) fore_pixel = x_decode_color (f, Vx_cursor_fore_pixel, WHITE_PIX_DEFAULT (f)); else fore_pixel = FRAME_BACKGROUND_PIXEL (f); ! f->output_data.mac->cursor_pixel = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f)); /* Make sure that the cursor color differs from the background color. */ ! if (f->output_data.mac->cursor_pixel == FRAME_BACKGROUND_PIXEL (f)) { ! f->output_data.mac->cursor_pixel = f->output_data.mac->mouse_pixel; ! if (f->output_data.mac->cursor_pixel == fore_pixel) fore_pixel = FRAME_BACKGROUND_PIXEL (f); } - FRAME_FOREGROUND_PIXEL (f) = fore_pixel; ! #if 0 /* MAC_TODO: cannot figure out what to do (wrong number of params) */ if (FRAME_MAC_WINDOW (f) != 0) { if (FRAME_VISIBLE_P (f)) { ! BLOCK_INPUT; ! display_and_set_cursor (f, 0); ! display_and_set_cursor (f, 1); ! UNBLOCK_INPUT; } } - #endif update_face_from_frame_parameter (f, Qcursor_color, arg); } --- 1927,1968 ---- struct frame *f; Lisp_Object arg, oldval; { ! unsigned long fore_pixel, pixel; if (!NILP (Vx_cursor_fore_pixel)) fore_pixel = x_decode_color (f, Vx_cursor_fore_pixel, WHITE_PIX_DEFAULT (f)); else fore_pixel = FRAME_BACKGROUND_PIXEL (f); ! ! pixel = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f)); /* Make sure that the cursor color differs from the background color. */ ! if (pixel == FRAME_BACKGROUND_PIXEL (f)) { ! pixel = f->output_data.mac->mouse_pixel; ! if (pixel == fore_pixel) fore_pixel = FRAME_BACKGROUND_PIXEL (f); } ! f->output_data.mac->cursor_foreground_pixel = fore_pixel; ! f->output_data.mac->cursor_pixel = pixel; ! if (FRAME_MAC_WINDOW (f) != 0) { + BLOCK_INPUT; + /* Update frame's cursor_gc. */ + f->output_data.mac->cursor_gc->foreground = fore_pixel; + f->output_data.mac->cursor_gc->background = pixel; + + UNBLOCK_INPUT; + if (FRAME_VISIBLE_P (f)) { ! x_update_cursor (f, 0); ! x_update_cursor (f, 1); } } update_face_from_frame_parameter (f, Qcursor_color, arg); } *************** *** 1893,1903 **** --- 1970,1982 ---- /* Set the border-color of frame F to pixel value PIX. Note that this does not fully take effect if done before F has a window. */ + void x_set_border_pixel (f, pix) struct frame *f; int pix; { + f->output_data.mac->border_pixel = pix; if (FRAME_MAC_WINDOW (f) != 0 && f->border_width > 0) *************** *** 1926,1931 **** --- 2005,2011 ---- update_face_from_frame_parameter (f, Qborder_color, arg); } + void x_set_cursor_type (f, arg, oldval) FRAME_PTR f; *************** *** 1933,1941 **** { set_frame_cursor_types (f, arg); ! /* Make sure the cursor gets redrawn. This is overkill, but how ! often do people change cursor types? */ ! update_mode_lines++; } #if 0 /* MAC_TODO: really no icon for Mac */ --- 2013,2020 ---- { set_frame_cursor_types (f, arg); ! /* Make sure the cursor gets redrawn. */ ! cursor_type_changed = 1; } #if 0 /* MAC_TODO: really no icon for Mac */ *************** *** 2597,2603 **** BLOCK_INPUT; ! /* Create the GC's of this frame. Note that many default values are used. */ /* Normal video */ --- 2676,2682 ---- BLOCK_INPUT; ! /* Create the GCs of this frame. Note that many default values are used. */ /* Normal video */ *************** *** 2629,2634 **** --- 2708,2726 ---- f->output_data.mac->white_relief.gc = 0; f->output_data.mac->black_relief.gc = 0; + #if 0 + /* Create the gray border tile used when the pointer is not in + the frame. Since this depends on the frame's pixel values, + this must be done on a per-frame basis. */ + f->output_data.x->border_tile + = (XCreatePixmapFromBitmapData + (FRAME_X_DISPLAY (f), FRAME_X_DISPLAY_INFO (f)->root_window, + gray_bits, gray_width, gray_height, + f->output_data.x->foreground_pixel, + f->output_data.x->background_pixel, + DefaultDepth (FRAME_X_DISPLAY (f), FRAME_X_SCREEN_NUMBER (f)))); + #endif + UNBLOCK_INPUT; } *************** *** 2800,2806 **** if (! STRINGP (font)) font = x_new_font (f, "-ETL-fixed-medium-r-*--*-160-*-*-*-*-iso8859-1"); /* If those didn't work, look for something which will at least work. */ ! if (!STRINGP (font)) font = x_new_font (f, "-*-monaco-*-12-*-mac-roman"); if (! STRINGP (font)) font = x_new_font (f, "-*-courier-*-10-*-mac-roman"); --- 2892,2898 ---- if (! STRINGP (font)) font = x_new_font (f, "-ETL-fixed-medium-r-*--*-160-*-*-*-*-iso8859-1"); /* If those didn't work, look for something which will at least work. */ ! if (! STRINGP (font)) font = x_new_font (f, "-*-monaco-*-12-*-mac-roman"); if (! STRINGP (font)) font = x_new_font (f, "-*-courier-*-10-*-mac-roman"); *************** *** 3011,3022 **** { Lisp_Object rgb[3]; ! rgb[0] = make_number ((RED_FROM_ULONG (foo.pixel) << 8) ! | RED_FROM_ULONG (foo.pixel)); ! rgb[1] = make_number ((GREEN_FROM_ULONG (foo.pixel) << 8) ! | GREEN_FROM_ULONG (foo.pixel)); ! rgb[2] = make_number ((BLUE_FROM_ULONG (foo.pixel) << 8) ! | BLUE_FROM_ULONG (foo.pixel)); return Flist (3, rgb); } else --- 3103,3111 ---- { Lisp_Object rgb[3]; ! rgb[0] = make_number (foo.red); ! rgb[1] = make_number (foo.green); ! rgb[2] = make_number (foo.blue); return Flist (3, rgb); } else *************** *** 3030,3036 **** { struct mac_display_info *dpyinfo = check_x_display_info (display); ! if ((dpyinfo->n_planes * dpyinfo->n_cbits) <= 2) return Qnil; return Qt; --- 3119,3125 ---- { struct mac_display_info *dpyinfo = check_x_display_info (display); ! if (!dpyinfo->color_p) return Qnil; return Qt; *************** *** 3048,3054 **** { struct mac_display_info *dpyinfo = check_x_display_info (display); ! if ((dpyinfo->n_planes * dpyinfo->n_cbits) <= 1) return Qnil; return Qt; --- 3137,3143 ---- { struct mac_display_info *dpyinfo = check_x_display_info (display); ! if (dpyinfo->n_planes <= 1) return Qnil; return Qt; *************** *** 3093,3099 **** { struct mac_display_info *dpyinfo = check_x_display_info (display); ! return make_number (dpyinfo->n_planes * dpyinfo->n_cbits); } DEFUN ("x-display-color-cells", Fx_display_color_cells, Sx_display_color_cells, --- 3182,3188 ---- { struct mac_display_info *dpyinfo = check_x_display_info (display); ! return make_number (dpyinfo->n_planes); } DEFUN ("x-display-color-cells", Fx_display_color_cells, Sx_display_color_cells, *************** *** 3108,3114 **** struct mac_display_info *dpyinfo = check_x_display_info (display); /* MAC_TODO: check whether this is right */ ! return make_number ((unsigned long) (pow (2, dpyinfo->n_cbits))); } DEFUN ("x-server-max-request-size", Fx_server_max_request_size, --- 3197,3203 ---- struct mac_display_info *dpyinfo = check_x_display_info (display); /* MAC_TODO: check whether this is right */ ! return make_number (dpyinfo->n_planes >= 8 ? 256 : 1 << dpyinfo->n_planes - 1); } DEFUN ("x-server-max-request-size", Fx_server_max_request_size, *************** *** 3446,3451 **** --- 3535,3541 ---- return Qnil; } + /*********************************************************************** Image types *************** *** 3470,3480 **** extern Lisp_Object QCdata, QCtype; Lisp_Object QCascent, QCmargin, QCrelief; Lisp_Object QCconversion, QCcolor_symbols, QCheuristic_mask; ! Lisp_Object QCindex; /* Other symbols. */ ! Lisp_Object Qlaplace; /* Time in seconds after which images should be removed from the cache if not displayed. */ --- 3560,3570 ---- extern Lisp_Object QCdata, QCtype; Lisp_Object QCascent, QCmargin, QCrelief; Lisp_Object QCconversion, QCcolor_symbols, QCheuristic_mask; ! Lisp_Object QCindex, QCmatrix, QCcolor_adjustment, QCmask; /* Other symbols. */ ! Lisp_Object Qlaplace, Qemboss, Qedge_detection, Qheuristic; /* Time in seconds after which images should be removed from the cache if not displayed. */ *************** *** 3487,3492 **** --- 3577,3583 ---- static struct image_type *lookup_image_type P_ ((Lisp_Object symbol)); static void image_error P_ ((char *format, Lisp_Object, Lisp_Object)); static void x_laplace P_ ((struct frame *, struct image *)); + static void x_emboss P_ ((struct frame *, struct image *)); static int x_build_heuristic_mask P_ ((struct frame *, struct image *, Lisp_Object)); *************** *** 3540,3550 **** if (IMAGEP (object)) { ! Lisp_Object symbol = Fplist_get (XCDR (object), QCtype); ! struct image_type *type = lookup_image_type (symbol); ! if (type) ! valid_p = type->valid_p (object); } return valid_p; --- 3631,3652 ---- if (IMAGEP (object)) { ! Lisp_Object tem; ! ! for (tem = XCDR (object); CONSP (tem); tem = XCDR (tem)) ! if (EQ (XCAR (tem), QCtype)) ! { ! tem = XCDR (tem); ! if (CONSP (tem) && SYMBOLP (XCAR (tem))) ! { ! struct image_type *type; ! type = lookup_image_type (XCAR (tem)); ! if (type) ! valid_p = type->valid_p (object); ! } ! break; ! } } return valid_p; *************** *** 3554,3561 **** /* Log error message with format string FORMAT and argument ARG. Signaling an error, e.g. when an image cannot be loaded, is not a good idea because this would interrupt redisplay, and the error ! message display would lead to another redisplay. This function ! therefore simply displays a message. */ static void image_error (format, arg1, arg2) --- 3656,3663 ---- /* Log error message with format string FORMAT and argument ARG. Signaling an error, e.g. when an image cannot be loaded, is not a good idea because this would interrupt redisplay, and the error ! message display would lead to another redisplay. This function ! therefore simply displays a message. */ static void image_error (format, arg1, arg2) *************** *** 3575,3580 **** --- 3677,3683 ---- { IMAGE_DONT_CHECK_VALUE_TYPE, IMAGE_STRING_VALUE, + IMAGE_STRING_OR_NIL_VALUE, IMAGE_SYMBOL_VALUE, IMAGE_POSITIVE_INTEGER_VALUE, IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, *************** *** 3654,3660 **** break; if (i == nkeywords) ! continue; /* Record that we recognized the keyword. If a keywords was found more than once, it's an error. */ --- 3757,3763 ---- break; if (i == nkeywords) ! continue; /* Record that we recognized the keyword. If a keywords was found more than once, it's an error. */ *************** *** 3672,3677 **** --- 3775,3785 ---- return 0; break; + case IMAGE_STRING_OR_NIL_VALUE: + if (!STRINGP (value) && !NILP (value)) + return 0; + break; + case IMAGE_SYMBOL_VALUE: if (!SYMBOLP (value)) return 0; *************** *** 3691,3697 **** break; return 0; ! case IMAGE_ASCENT_VALUE: if (SYMBOLP (value) && EQ (value, Qcenter)) break; else if (INTEGERP (value) --- 3799,3805 ---- break; return 0; ! case IMAGE_ASCENT_VALUE: if (SYMBOLP (value) && EQ (value, Qcenter)) break; else if (INTEGERP (value) *************** *** 3780,3785 **** --- 3888,3950 ---- } + DEFUN ("image-size", Fimage_size, Simage_size, 1, 3, 0, + doc: /* Return the size of image SPEC as pair (WIDTH . HEIGHT). + PIXELS non-nil means return the size in pixels, otherwise return the + size in canonical character units. + FRAME is the frame on which the image will be displayed. FRAME nil + or omitted means use the selected frame. */) + (spec, pixels, frame) + Lisp_Object spec, pixels, frame; + { + Lisp_Object size; + + size = Qnil; + if (valid_image_p (spec)) + { + struct frame *f = check_x_frame (frame); + int id = lookup_image (f, spec); + struct image *img = IMAGE_FROM_ID (f, id); + int width = img->width + 2 * img->hmargin; + int height = img->height + 2 * img->vmargin; + + if (NILP (pixels)) + size = Fcons (make_float ((double) width / FRAME_COLUMN_WIDTH (f)), + make_float ((double) height / FRAME_LINE_HEIGHT (f))); + else + size = Fcons (make_number (width), make_number (height)); + } + else + error ("Invalid image specification"); + + return size; + } + + + DEFUN ("image-mask-p", Fimage_mask_p, Simage_mask_p, 1, 2, 0, + doc: /* Return t if image SPEC has a mask bitmap. + FRAME is the frame on which the image will be displayed. FRAME nil + or omitted means use the selected frame. */) + (spec, frame) + Lisp_Object spec, frame; + { + Lisp_Object mask; + + mask = Qnil; + if (valid_image_p (spec)) + { + struct frame *f = check_x_frame (frame); + int id = lookup_image (f, spec); + struct image *img = IMAGE_FROM_ID (f, id); + if (img->mask) + mask = Qt; + } + else + error ("Invalid image specification"); + + return mask; + } + /*********************************************************************** *************** *** 3876,3883 **** if (img->ascent == CENTERED_IMAGE_ASCENT) { if (face->font) ! ascent = height / 2 - (FONT_DESCENT(face->font) ! - FONT_BASE(face->font)) / 2; else ascent = height / 2; } --- 4041,4052 ---- if (img->ascent == CENTERED_IMAGE_ASCENT) { if (face->font) ! /* This expression is arranged so that if the image can't be ! exactly centered, it will be moved slightly up. This is ! because a typical font is `top-heavy' (due to the presence ! uppercase letters), so the image placement should err towards ! being top-heavy too. It also just generally looks better. */ ! ascent = (height + face->font->ascent - face->font->descent + 1) / 2; else ascent = height / 2; } *************** *** 3887,3944 **** return ascent; } /*********************************************************************** Helper functions for X image types ***********************************************************************/ static void x_clear_image P_ ((struct frame *f, struct image *img)); static unsigned long x_alloc_image_color P_ ((struct frame *f, struct image *img, Lisp_Object color_name, unsigned long dflt)); ! /* Free X resources of image IMG which is used on frame F. */ static void ! x_clear_image (f, img) struct frame *f; struct image *img; { ! #if 0 /* MAC_TODO: W32 image support */ ! ! if (img->pixmap) { ! BLOCK_INPUT; ! XFreePixmap (NULL, img->pixmap); ! img->pixmap = 0; ! UNBLOCK_INPUT; } ! if (img->ncolors) { ! int class = FRAME_W32_DISPLAY_INFO (f)->visual->class; ! ! /* If display has an immutable color map, freeing colors is not ! necessary and some servers don't allow it. So don't do it. */ ! if (class != StaticColor ! && class != StaticGray ! && class != TrueColor) ! { ! Colormap cmap; ! BLOCK_INPUT; ! cmap = DefaultColormapOfScreen (FRAME_W32_DISPLAY_INFO (f)->screen); ! XFreeColors (FRAME_W32_DISPLAY (f), cmap, img->colors, ! img->ncolors, 0); ! UNBLOCK_INPUT; ! } xfree (img->colors); img->colors = NULL; img->ncolors = 0; } ! #endif /* MAC_TODO */ } --- 4056,4220 ---- return ascent; } + + /* Image background colors. */ + + static unsigned long + four_corners_best (ximg, width, height) + XImagePtr ximg; + unsigned long width, height; + { + unsigned long corners[4], best; + int i, best_count; + + /* Get the colors at the corners of ximg. */ + corners[0] = XGetPixel (ximg, 0, 0); + corners[1] = XGetPixel (ximg, width - 1, 0); + corners[2] = XGetPixel (ximg, width - 1, height - 1); + corners[3] = XGetPixel (ximg, 0, height - 1); + + /* Choose the most frequently found color as background. */ + for (i = best_count = 0; i < 4; ++i) + { + int j, n; + + for (j = n = 0; j < 4; ++j) + if (corners[i] == corners[j]) + ++n; + + if (n > best_count) + best = corners[i], best_count = n; + } + + return best; + } + + /* Return the `background' field of IMG. If IMG doesn't have one yet, + it is guessed heuristically. If non-zero, XIMG is an existing XImage + object to use for the heuristic. */ + + unsigned long + image_background (img, f, ximg) + struct image *img; + struct frame *f; + XImagePtr ximg; + { + if (! img->background_valid) + /* IMG doesn't have a background yet, try to guess a reasonable value. */ + { + int free_ximg = !ximg; + + if (! ximg) + ximg = XGetImage (FRAME_X_DISPLAY (f), img->pixmap, + 0, 0, img->width, img->height, ~0, ZPixmap); + + img->background = four_corners_best (ximg, img->width, img->height); + + if (free_ximg) + XDestroyImage (ximg); + + img->background_valid = 1; + } + + return img->background; + } + + /* Return the `background_transparent' field of IMG. If IMG doesn't + have one yet, it is guessed heuristically. If non-zero, MASK is an + existing XImage object to use for the heuristic. */ + + int + image_background_transparent (img, f, mask) + struct image *img; + struct frame *f; + XImagePtr mask; + { + if (! img->background_transparent_valid) + /* IMG doesn't have a background yet, try to guess a reasonable value. */ + { + if (img->mask) + { + int free_mask = !mask; + + if (! mask) + mask = XGetImage (FRAME_X_DISPLAY (f), img->mask, + 0, 0, img->width, img->height, ~0, ZPixmap); + + img->background_transparent + = four_corners_best (mask, img->width, img->height) == PIX_MASK_RETAIN (f); + + if (free_mask) + XDestroyImage (mask); + } + else + img->background_transparent = 0; + + img->background_transparent_valid = 1; + } + + return img->background_transparent; + } /*********************************************************************** Helper functions for X image types ***********************************************************************/ + static void x_clear_image_1 P_ ((struct frame *, struct image *, int, + int, int)); static void x_clear_image P_ ((struct frame *f, struct image *img)); static unsigned long x_alloc_image_color P_ ((struct frame *f, struct image *img, Lisp_Object color_name, unsigned long dflt)); ! ! /* Clear X resources of image IMG on frame F. PIXMAP_P non-zero means ! free the pixmap if any. MASK_P non-zero means clear the mask ! pixmap if any. COLORS_P non-zero means free colors allocated for ! the image, if any. */ static void ! x_clear_image_1 (f, img, pixmap_p, mask_p, colors_p) struct frame *f; struct image *img; + int pixmap_p, mask_p, colors_p; { ! if (pixmap_p && img->pixmap) { ! XFreePixmap (FRAME_X_DISPLAY (f), img->pixmap); ! img->pixmap = NULL; ! img->background_valid = 0; } ! if (mask_p && img->mask) { ! XFreePixmap (FRAME_X_DISPLAY (f), img->mask); ! img->mask = NULL; ! img->background_transparent_valid = 0; ! } + if (colors_p && img->ncolors) + { + #if 0 /* TODO: color table support. */ + x_free_colors (f, img->colors, img->ncolors); + #endif xfree (img->colors); img->colors = NULL; img->ncolors = 0; } ! } ! ! /* Free X resources of image IMG which is used on frame F. */ ! ! static void ! x_clear_image (f, img) ! struct frame *f; ! struct image *img; ! { ! BLOCK_INPUT; ! x_clear_image_1 (f, img, 1, 1, 1); ! UNBLOCK_INPUT; } *************** *** 3954,3966 **** Lisp_Object color_name; unsigned long dflt; { - #if 0 /* MAC_TODO: allocing colors. */ XColor color; unsigned long result; xassert (STRINGP (color_name)); ! if (w32_defined_color (f, SDATA (color_name), &color, 1)) { /* This isn't called frequently so we get away with simply reallocating the color vector to the needed size, here. */ --- 4230,4241 ---- Lisp_Object color_name; unsigned long dflt; { XColor color; unsigned long result; xassert (STRINGP (color_name)); ! if (mac_defined_color (f, SDATA (color_name), &color, 1)) { /* This isn't called frequently so we get away with simply reallocating the color vector to the needed size, here. */ *************** *** 3973,3981 **** } else result = dflt; return result; - #endif /* MAC_TODO */ - return 0; } --- 4248,4255 ---- } else result = dflt; + return result; } *************** *** 3985,3990 **** --- 4259,4265 ---- ***********************************************************************/ static void cache_image P_ ((struct frame *f, struct image *img)); + static void postprocess_image P_ ((struct frame *, struct image *)); /* Return a new, initialized image cache that is allocated from the *************** *** 4049,4068 **** { EMACS_TIME t; unsigned long old; ! int i, any_freed_p = 0; EMACS_GET_TIME (t); old = EMACS_SECS (t) - XFASTINT (Vimage_cache_eviction_delay); ! for (i = 0; i < c->used; ++i) { struct image *img = c->images[i]; if (img != NULL ! && (force_p ! || (img->timestamp > old))) { free_image (f, img); ! any_freed_p = 1; } } --- 4324,4346 ---- { EMACS_TIME t; unsigned long old; ! int i, nfreed; EMACS_GET_TIME (t); old = EMACS_SECS (t) - XFASTINT (Vimage_cache_eviction_delay); ! /* Block input so that we won't be interrupted by a SIGIO ! while being in an inconsistent state. */ ! BLOCK_INPUT; ! ! for (i = nfreed = 0; i < c->used; ++i) { struct image *img = c->images[i]; if (img != NULL ! && (force_p || img->timestamp < old)) { free_image (f, img); ! ++nfreed; } } *************** *** 4070,4080 **** Emacs was iconified for a longer period of time. In that case, current matrices may still contain references to images freed above. So, clear these matrices. */ ! if (any_freed_p) { ! clear_current_matrices (f); ++windows_or_buffers_changed; } } } --- 4348,4369 ---- Emacs was iconified for a longer period of time. In that case, current matrices may still contain references to images freed above. So, clear these matrices. */ ! if (nfreed) { ! Lisp_Object tail, frame; ! ! FOR_EACH_FRAME (tail, frame) ! { ! struct frame *f = XFRAME (frame); ! if (FRAME_MAC_P (f) ! && FRAME_X_IMAGE_CACHE (f) == c) ! clear_current_matrices (f); ! } ! ++windows_or_buffers_changed; } + + UNBLOCK_INPUT; } } *************** *** 4084,4090 **** doc: /* Clear the image cache of FRAME. FRAME nil or omitted means use the selected frame. FRAME t means clear the image caches of all frames. */) ! (frame) Lisp_Object frame; { if (EQ (frame, Qt)) --- 4373,4379 ---- doc: /* Clear the image cache of FRAME. FRAME nil or omitted means use the selected frame. FRAME t means clear the image caches of all frames. */) ! (frame) Lisp_Object frame; { if (EQ (frame, Qt)) *************** *** 4102,4107 **** --- 4391,4471 ---- } + /* Compute masks and transform image IMG on frame F, as specified + by the image's specification, */ + + static void + postprocess_image (f, img) + struct frame *f; + struct image *img; + { + /* Manipulation of the image's mask. */ + if (img->pixmap) + { + Lisp_Object conversion, spec; + Lisp_Object mask; + + spec = img->spec; + + /* `:heuristic-mask t' + `:mask heuristic' + means build a mask heuristically. + `:heuristic-mask (R G B)' + `:mask (heuristic (R G B))' + means build a mask from color (R G B) in the + image. + `:mask nil' + means remove a mask, if any. */ + + mask = image_spec_value (spec, QCheuristic_mask, NULL); + if (!NILP (mask)) + x_build_heuristic_mask (f, img, mask); + else + { + int found_p; + + mask = image_spec_value (spec, QCmask, &found_p); + + if (EQ (mask, Qheuristic)) + x_build_heuristic_mask (f, img, Qt); + else if (CONSP (mask) + && EQ (XCAR (mask), Qheuristic)) + { + if (CONSP (XCDR (mask))) + x_build_heuristic_mask (f, img, XCAR (XCDR (mask))); + else + x_build_heuristic_mask (f, img, XCDR (mask)); + } + else if (NILP (mask) && found_p && img->mask) + { + XFreePixmap (FRAME_X_DISPLAY (f), img->mask); + img->mask = NULL; + } + } + + + /* Should we apply an image transformation algorithm? */ + conversion = image_spec_value (spec, QCconversion, NULL); + if (EQ (conversion, Qdisabled)) + x_disable_image (f, img); + else if (EQ (conversion, Qlaplace)) + x_laplace (f, img); + else if (EQ (conversion, Qemboss)) + x_emboss (f, img); + else if (CONSP (conversion) + && EQ (XCAR (conversion), Qedge_detection)) + { + Lisp_Object tem; + tem = XCDR (conversion); + if (CONSP (tem)) + x_edge_detection (f, img, + Fplist_get (tem, QCmatrix), + Fplist_get (tem, QCcolor_adjustment)); + } + } + } + + /* Return the id of image with Lisp specification SPEC on frame F. SPEC must be a valid Lisp image specification (see valid_image_p). */ *************** *** 4135,4145 **** /* If not found, create a new image and cache it. */ if (img == NULL) { BLOCK_INPUT; img = make_image (spec, hash); cache_image (f, img); img->load_failed_p = img->type->load (f, img) == 0; - xassert (!interrupt_input_blocked); /* If we can't load the image, and we don't have a width and height, use some arbitrary width and height so that we can --- 4499,4510 ---- /* If not found, create a new image and cache it. */ if (img == NULL) { + extern Lisp_Object Qpostscript; + BLOCK_INPUT; img = make_image (spec, hash); cache_image (f, img); img->load_failed_p = img->type->load (f, img) == 0; /* If we can't load the image, and we don't have a width and height, use some arbitrary width and height so that we can *************** *** 4158,4171 **** else { /* Handle image type independent image attributes ! `:ascent PERCENT', `:margin MARGIN', `:relief RELIEF'. */ ! Lisp_Object ascent, margin, relief; ascent = image_spec_value (spec, QCascent, NULL); if (INTEGERP (ascent)) img->ascent = XFASTINT (ascent); else if (EQ (ascent, Qcenter)) ! img->ascent = CENTERED_IMAGE_ASCENT; margin = image_spec_value (spec, QCmargin, NULL); if (INTEGERP (margin) && XINT (margin) >= 0) --- 4523,4537 ---- else { /* Handle image type independent image attributes ! `:ascent ASCENT', `:margin MARGIN', `:relief RELIEF', ! `:background COLOR'. */ ! Lisp_Object ascent, margin, relief, bg; ascent = image_spec_value (spec, QCascent, NULL); if (INTEGERP (ascent)) img->ascent = XFASTINT (ascent); else if (EQ (ascent, Qcenter)) ! img->ascent = CENTERED_IMAGE_ASCENT; margin = image_spec_value (spec, QCmargin, NULL); if (INTEGERP (margin) && XINT (margin) >= 0) *************** *** 4186,4192 **** --- 4552,4578 ---- img->hmargin += abs (img->relief); img->vmargin += abs (img->relief); } + + if (! img->background_valid) + { + bg = image_spec_value (img->spec, QCbackground, NULL); + if (!NILP (bg)) + { + img->background + = x_alloc_image_color (f, img, bg, + FRAME_BACKGROUND_PIXEL (f)); + img->background_valid = 1; + } + } + + /* Do image transformations and compute masks, unless we + don't have the image yet. */ + if (!EQ (*img->type->type, Qpostscript)) + postprocess_image (f, img); } + + UNBLOCK_INPUT; + xassert (!interrupt_input_blocked); } /* We're using IMG, so set its timestamp to `now'. */ *************** *** 4266,4313 **** Mac support code ***********************************************************************/ - #if 0 /* MAC_TODO: Mac specific image code. */ - static int x_create_x_image_and_pixmap P_ ((struct frame *, int, int, int, ! XImage **, Pixmap *)); ! static void x_destroy_x_image P_ ((XImage *)); ! static void x_put_x_image P_ ((struct frame *, XImage *, Pixmap, int, int)); - /* Create an XImage and a pixmap of size WIDTH x HEIGHT for use on - frame F. Set *XIMG and *PIXMAP to the XImage and Pixmap created. - Set (*XIMG)->data to a raster of WIDTH x HEIGHT pixels allocated - via xmalloc. Print error messages via image_error if an error - occurs. Value is non-zero if successful. */ - - static int x_create_x_image_and_pixmap (f, width, height, depth, ximg, pixmap) struct frame *f; int width, height, depth; ! XImage **ximg; Pixmap *pixmap; { ! #if 0 /* MAC_TODO: Image support for Mac */ ! Display *display = FRAME_W32_DISPLAY (f); ! Screen *screen = FRAME_X_SCREEN (f); ! Window window = FRAME_W32_WINDOW (f); xassert (interrupt_input_blocked); - if (depth <= 0) - depth = DefaultDepthOfScreen (screen); - *ximg = XCreateImage (display, DefaultVisualOfScreen (screen), - depth, ZPixmap, 0, NULL, width, height, - depth > 16 ? 32 : depth > 8 ? 16 : 8, 0); - if (*ximg == NULL) - { - image_error ("Unable to allocate X image", Qnil, Qnil); - return 0; - } - - /* Allocate image raster. */ - (*ximg)->data = (char *) xmalloc ((*ximg)->bytes_per_line * height); - /* Allocate a pixmap of the same size. */ *pixmap = XCreatePixmap (display, window, width, height, depth); if (*pixmap == 0) --- 4652,4674 ---- Mac support code ***********************************************************************/ static int x_create_x_image_and_pixmap P_ ((struct frame *, int, int, int, ! XImagePtr *, Pixmap *)); ! static void x_destroy_x_image P_ ((XImagePtr)); ! static void x_put_x_image P_ ((struct frame *, XImagePtr, Pixmap, int, int)); x_create_x_image_and_pixmap (f, width, height, depth, ximg, pixmap) struct frame *f; int width, height, depth; ! XImagePtr *ximg; Pixmap *pixmap; { ! Display *display = FRAME_MAC_DISPLAY (f); ! Window window = FRAME_MAC_WINDOW (f); xassert (interrupt_input_blocked); /* Allocate a pixmap of the same size. */ *pixmap = XCreatePixmap (display, window, width, height, depth); if (*pixmap == 0) *************** *** 4317,4368 **** image_error ("Unable to create X pixmap", Qnil, Qnil); return 0; } ! #endif /* MAC_TODO */ return 1; } - - /* Destroy XImage XIMG. Free XIMG->data. */ - static void x_destroy_x_image (ximg) ! XImage *ximg; { xassert (interrupt_input_blocked); if (ximg) ! { ! xfree (ximg->data); ! ximg->data = NULL; ! XDestroyImage (ximg); ! } } - - /* Put XImage XIMG into pixmap PIXMAP on frame F. WIDTH and HEIGHT - are width and height of both the image and pixmap. */ - static void x_put_x_image (f, ximg, pixmap, width, height) struct frame *f; ! XImage *ximg; Pixmap pixmap; { ! GC gc; ! ! xassert (interrupt_input_blocked); ! gc = XCreateGC (NULL, pixmap, 0, NULL); ! XPutImage (NULL, pixmap, gc, ximg, 0, 0, 0, 0, width, height); ! XFreeGC (NULL, gc); } - #endif /* MAC_TODO */ /*********************************************************************** ! Searching files ***********************************************************************/ static Lisp_Object x_find_image_file P_ ((Lisp_Object)); /* Find image file FILE. Look in data-directory, then x-bitmap-file-path. Value is the full name of the file found, or --- 4678,4716 ---- image_error ("Unable to create X pixmap", Qnil, Qnil); return 0; } ! ! LockPixels (GetGWorldPixMap (*pixmap)); ! *ximg = *pixmap; return 1; } static void x_destroy_x_image (ximg) ! XImagePtr ximg; { xassert (interrupt_input_blocked); if (ximg) ! XDestroyImage (ximg); } static void x_put_x_image (f, ximg, pixmap, width, height) struct frame *f; ! XImagePtr ximg; Pixmap pixmap; { ! xassert (ximg == pixmap); } /*********************************************************************** ! File Handling ***********************************************************************/ static Lisp_Object x_find_image_file P_ ((Lisp_Object)); + static char *slurp_file P_ ((char *, int *)); + /* Find image file FILE. Look in data-directory, then x-bitmap-file-path. Value is the full name of the file found, or *************** *** 4383,4389 **** /* Try to find FILE in data-directory, then x-bitmap-file-path. */ fd = openp (search_path, file, Qnil, &file_found, Qnil); ! if (fd < 0) file_found = Qnil; else close (fd); --- 4731,4737 ---- /* Try to find FILE in data-directory, then x-bitmap-file-path. */ fd = openp (search_path, file, Qnil, &file_found, Qnil); ! if (fd == -1) file_found = Qnil; else close (fd); *************** *** 4392,4418 **** return file_found; } - - /*********************************************************************** - XBM images - ***********************************************************************/ - - static int xbm_load P_ ((struct frame *f, struct image *img)); - static int xbm_load_image_from_file P_ ((struct frame *f, struct image *img, - Lisp_Object file)); - static int xbm_image_p P_ ((Lisp_Object object)); - static int xbm_read_bitmap_file_data P_ ((char *, int *, int *, - unsigned char **)); - ! /* Indices of image specification fields in xbm_format, below. */ ! enum xbm_keyword_index { ! XBM_TYPE, ! XBM_FILE, ! XBM_WIDTH, ! XBM_HEIGHT, XBM_DATA, XBM_FOREGROUND, XBM_BACKGROUND, --- 4740,5147 ---- return file_found; } ! /* Read FILE into memory. Value is a pointer to a buffer allocated ! with xmalloc holding FILE's contents. Value is null if an error ! occurred. *SIZE is set to the size of the file. */ ! static char * ! slurp_file (file, size) ! char *file; ! int *size; { ! FILE *fp = NULL; ! char *buf = NULL; ! struct stat st; ! ! if (stat (file, &st) == 0 ! && (fp = fopen (file, "r")) != NULL ! && (buf = (char *) xmalloc (st.st_size), ! fread (buf, 1, st.st_size, fp) == st.st_size)) ! { ! *size = st.st_size; ! fclose (fp); ! } ! else ! { ! if (fp) ! fclose (fp); ! if (buf) ! { ! xfree (buf); ! buf = NULL; ! } ! } ! ! return buf; ! } ! ! ! ! /*********************************************************************** ! Image Load Functions ! ***********************************************************************/ ! ! static int image_load_quicktime P_ ((struct frame *, struct image *img, ! OSType)); ! #ifdef MAC_OSX ! static int image_load_quartz2d P_ ((struct frame *, struct image *img, int)); ! #endif ! ! ! static OSErr ! find_image_fsspec (specified_file, file, fss) ! Lisp_Object specified_file, *file; ! FSSpec *fss; ! { ! #if TARGET_API_MAC_CARBON ! FSRef fsr; ! #else ! Str255 mac_pathname; ! #endif ! OSErr err; ! ! *file = x_find_image_file (specified_file); ! if (!STRINGP (*file)) ! return fnfErr; /* file or directory not found; ! incomplete pathname */ ! /* Try to open the image file. */ ! #if TARGET_API_MAC_CARBON ! err = FSPathMakeRef (SDATA (*file), &fsr, NULL); ! if (err == noErr) ! err = FSGetCatalogInfo (&fsr, kFSCatInfoNone, NULL, NULL, fss, NULL); ! #else ! if (posix_to_mac_pathname (SDATA (*file), mac_pathname, MAXPATHLEN+1) == 0) ! return fnfErr; ! c2pstr (mac_pathname); ! err = FSMakeFSSpec (0, 0, mac_pathname, fss); ! #endif ! return err; ! } ! ! ! static int ! image_load_qt_1 (f, img, type, fss, dh) ! struct frame *f; ! struct image *img; ! OSType type; ! FSSpec *fss; ! Handle dh; ! { ! OSErr err; ! GraphicsImportComponent gi; ! Rect rect; ! int width, height; ! short draw_all_pixels; ! Lisp_Object specified_bg; ! XColor color; ! XImagePtr ximg; ! RGBColor bg_color; ! ! err = OpenADefaultComponent (GraphicsImporterComponentType, ! type, &gi); ! if (err != noErr) ! { ! image_error ("Cannot get importer component for `%s'", img->spec, Qnil); ! return 0; ! } ! if (dh == NULL) ! { ! /* read from file system spec */ ! err = GraphicsImportSetDataFile (gi, fss); ! if (err != noErr) ! { ! image_error ("Cannot set fsspec to graphics importer for '%s'", ! img->spec, Qnil); ! goto error; ! } ! } ! else ! { ! /* read from data handle */ ! err = GraphicsImportSetDataHandle (gi, dh); ! if (err != noErr) ! { ! image_error ("Cannot set data handle to graphics importer for `%s'", ! img->spec, Qnil); ! goto error; ! } ! } ! err = GraphicsImportGetNaturalBounds (gi, &rect); ! if (err != noErr) ! { ! image_error ("Error reading `%s'", img->spec, Qnil); ! goto error; ! } ! width = img->width = rect.right - rect.left; ! height = img->height = rect.bottom - rect.top; ! err = GraphicsImportDoesDrawAllPixels (gi, &draw_all_pixels); ! #if 0 ! /* Don't check the error code here. It may have an undocumented ! value -32766. */ ! if (err != noErr) ! { ! image_error ("Error reading `%s'", img->spec, Qnil); ! goto error; ! } ! #endif ! if (draw_all_pixels != graphicsImporterDrawsAllPixels) ! { ! specified_bg = image_spec_value (img->spec, QCbackground, NULL); ! if (!STRINGP (specified_bg) || ! !mac_defined_color (f, SDATA (specified_bg), &color, 0)) ! { ! color.pixel = FRAME_BACKGROUND_PIXEL (f); ! color.red = RED16_FROM_ULONG (color.pixel); ! color.green = GREEN16_FROM_ULONG (color.pixel); ! color.blue = BLUE16_FROM_ULONG (color.pixel); ! } ! } ! ! if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap)) ! goto error; ! if (draw_all_pixels != graphicsImporterDrawsAllPixels) ! { ! SetGWorld (ximg, NULL); ! bg_color.red = color.red; ! bg_color.green = color.green; ! bg_color.blue = color.blue; ! RGBBackColor (&bg_color); ! #if TARGET_API_MAC_CARBON ! GetPortBounds (ximg, &rect); ! EraseRect (&rect); ! #else ! EraseRect (&(ximg->portRect)); ! #endif ! } ! GraphicsImportSetGWorld (gi, ximg, NULL); ! GraphicsImportDraw (gi); ! CloseComponent (gi); ! ! /* Maybe fill in the background field while we have ximg handy. */ ! if (NILP (image_spec_value (img->spec, QCbackground, NULL))) ! IMAGE_BACKGROUND (img, f, ximg); ! ! /* Put the image into the pixmap. */ ! x_put_x_image (f, ximg, img->pixmap, width, height); ! x_destroy_x_image (ximg); ! return 1; ! ! error: ! CloseComponent (gi); ! return 0; ! } ! ! ! /* Load an image using the QuickTime Graphics Importer. ! Note: The alpha channel does not work for PNG images. */ ! static int ! image_load_quicktime (f, img, type) ! struct frame *f; ! struct image *img; ! OSType type; ! { ! Lisp_Object specified_file; ! Lisp_Object specified_data; ! OSErr err; ! ! specified_file = image_spec_value (img->spec, QCfile, NULL); ! specified_data = image_spec_value (img->spec, QCdata, NULL); ! ! if (NILP (specified_data)) ! { ! /* Read from a file */ ! Lisp_Object file; ! FSSpec fss; ! ! err = find_image_fsspec (specified_file, &file, &fss); ! if (err != noErr) ! { ! if (err == fnfErr) ! image_error ("Cannot find image file `%s'", specified_file, Qnil); ! else ! image_error ("Cannot open `%s'", file, Qnil); ! return 0; ! } ! return image_load_qt_1 (f, img, type, &fss, NULL); ! } ! else ! { ! /* Memory source! */ ! int success_p; ! Handle dh; ! ! err = PtrToHand (SDATA (specified_data), &dh, SBYTES (specified_data)); ! if (err != noErr) ! { ! image_error ("Cannot allocate data handle for `%s'", ! img->spec, Qnil); ! return 0; ! } ! success_p = image_load_qt_1 (f, img, type, NULL, dh); ! DisposeHandle (dh); ! return success_p; ! } ! } ! ! ! #ifdef MAC_OSX ! /* Load a PNG/JPEG image using Quartz 2D decoding routines. ! CGImageCreateWithPNGDataProvider is provided after Mac OS X 10.2. ! So don't use this function directly but determine at runtime ! whether it exists. */ ! typedef CGImageRef (*CGImageCreateWithPNGDataProviderProcType) ! (CGDataProviderRef, const float [], bool, CGColorRenderingIntent); ! static CGImageCreateWithPNGDataProviderProcType MyCGImageCreateWithPNGDataProvider; ! ! ! static void ! init_image_func_pointer () ! { ! if (NSIsSymbolNameDefined ("_CGImageCreateWithPNGDataProvider")) ! { ! MyCGImageCreateWithPNGDataProvider ! = (CGImageCreateWithPNGDataProviderProcType) ! NSAddressOfSymbol (NSLookupAndBindSymbol ! ("_CGImageCreateWithPNGDataProvider")); ! } ! else ! MyCGImageCreateWithPNGDataProvider = NULL; ! } ! ! ! static int ! image_load_quartz2d (f, img, png_p) ! struct frame *f; ! struct image *img; ! int png_p; ! { ! Lisp_Object file, specified_file; ! Lisp_Object specified_data, specified_bg; ! struct gcpro gcpro1; ! CGDataProviderRef source; ! CGImageRef image; ! int width, height; ! XColor color; ! XImagePtr ximg = NULL; ! CGContextRef context; ! CGRect rectangle; ! ! /* Open the file. */ ! specified_file = image_spec_value (img->spec, QCfile, NULL); ! specified_data = image_spec_value (img->spec, QCdata, NULL); ! ! file = Qnil; ! GCPRO1 (file); ! ! if (NILP (specified_data)) ! { ! CFStringRef path; ! CFURLRef url; ! ! file = x_find_image_file (specified_file); ! if (!STRINGP (file)) ! { ! image_error ("Cannot find image file `%s'", specified_file, Qnil); ! UNGCPRO; ! return 0; ! } ! path = CFStringCreateWithCString (NULL, SDATA (file), ! kCFStringEncodingUTF8); ! url = CFURLCreateWithFileSystemPath (NULL, path, ! kCFURLPOSIXPathStyle, 0); ! CFRelease (path); ! source = CGDataProviderCreateWithURL (url); ! CFRelease (url); ! } ! else ! source = CGDataProviderCreateWithData (NULL, SDATA (specified_data), ! SBYTES (specified_data), NULL); ! ! if (png_p) ! image = (*MyCGImageCreateWithPNGDataProvider) (source, NULL, FALSE, ! kCGRenderingIntentDefault); ! else ! image = CGImageCreateWithJPEGDataProvider (source, NULL, FALSE, ! kCGRenderingIntentDefault); ! ! CGDataProviderRelease (source); ! if (image == NULL) ! { ! UNGCPRO; ! image_error ("Error reading image `%s'", img->spec, Qnil); ! return 0; ! } ! ! if (png_p) ! { ! specified_bg = image_spec_value (img->spec, QCbackground, NULL); ! if (!STRINGP (specified_bg) || ! !mac_defined_color (f, SDATA (specified_bg), &color, 0)) ! { ! color.pixel = FRAME_BACKGROUND_PIXEL (f); ! color.red = RED16_FROM_ULONG (color.pixel); ! color.green = GREEN16_FROM_ULONG (color.pixel); ! color.blue = BLUE16_FROM_ULONG (color.pixel); ! } ! } ! width = img->width = CGImageGetWidth (image); ! height = img->height = CGImageGetHeight (image); ! if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap)) ! { ! CGImageRelease (image); ! UNGCPRO; ! return 0; ! } ! rectangle = CGRectMake (0, 0, width, height); ! QDBeginCGContext (ximg, &context); ! if (png_p) ! { ! CGContextSetRGBFillColor (context, color.red / 65535.0, ! color.green / 65535.0, ! color.blue / 65535.0, 1.0); ! CGContextFillRect (context, rectangle); ! } ! CGContextDrawImage (context, rectangle, image); ! QDEndCGContext (ximg, &context); ! CGImageRelease (image); ! ! /* Maybe fill in the background field while we have ximg handy. */ ! if (NILP (image_spec_value (img->spec, QCbackground, NULL))) ! IMAGE_BACKGROUND (img, f, ximg); ! ! /* Put the image into the pixmap. */ ! x_put_x_image (f, ximg, img->pixmap, width, height); ! x_destroy_x_image (ximg); ! UNGCPRO; ! return 1; ! } ! #endif ! ! ! ! /*********************************************************************** ! XBM images ! ***********************************************************************/ ! ! static int xbm_scan P_ ((char **, char *, char *, int *)); ! static int xbm_load P_ ((struct frame *f, struct image *img)); ! static int xbm_load_image P_ ((struct frame *f, struct image *img, ! char *, char *)); ! static int xbm_image_p P_ ((Lisp_Object object)); ! static int xbm_read_bitmap_data P_ ((char *, char *, int *, int *, ! unsigned char **)); ! static int xbm_file_p P_ ((Lisp_Object)); ! ! ! /* Indices of image specification fields in xbm_format, below. */ ! ! enum xbm_keyword_index ! { ! XBM_TYPE, ! XBM_FILE, ! XBM_WIDTH, ! XBM_HEIGHT, XBM_DATA, XBM_FOREGROUND, XBM_BACKGROUND, *************** *** 4421,4426 **** --- 5150,5156 ---- XBM_RELIEF, XBM_ALGORITHM, XBM_HEURISTIC_MASK, + XBM_MASK, XBM_LAST }; *************** *** 4434,4446 **** {":width", IMAGE_POSITIVE_INTEGER_VALUE, 0}, {":height", IMAGE_POSITIVE_INTEGER_VALUE, 0}, {":data", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, ! {":foreground", IMAGE_STRING_VALUE, 0}, ! {":background", IMAGE_STRING_VALUE, 0}, ! {":ascent", IMAGE_NON_NEGATIVE_INTEGER_VALUE, 0}, {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0}, {":relief", IMAGE_INTEGER_VALUE, 0}, {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, ! {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0} }; /* Structure describing the image type XBM. */ --- 5164,5177 ---- {":width", IMAGE_POSITIVE_INTEGER_VALUE, 0}, {":height", IMAGE_POSITIVE_INTEGER_VALUE, 0}, {":data", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, ! {":foreground", IMAGE_STRING_OR_NIL_VALUE, 0}, ! {":background", IMAGE_STRING_OR_NIL_VALUE, 0}, ! {":ascent", IMAGE_ASCENT_VALUE, 0}, {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0}, {":relief", IMAGE_INTEGER_VALUE, 0}, {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, ! {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, ! {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0} }; /* Structure describing the image type XBM. */ *************** *** 4483,4492 **** 3. a vector of strings or bool-vectors, one for each line of the bitmap. Both the file and data forms may contain the additional entries `:background COLOR' and `:foreground COLOR'. If not present, foreground and background of the frame on which the image is ! displayed, is used. */ static int xbm_image_p (object) --- 5214,5227 ---- 3. a vector of strings or bool-vectors, one for each line of the bitmap. + 4. A string containing an in-memory XBM file. WIDTH and HEIGHT + may not be specified in this case because they are defined in the + XBM file. + Both the file and data forms may contain the additional entries `:background COLOR' and `:foreground COLOR'. If not present, foreground and background of the frame on which the image is ! displayed is used. */ static int xbm_image_p (object) *************** *** 4505,4510 **** --- 5240,5251 ---- if (kw[XBM_WIDTH].count || kw[XBM_HEIGHT].count || kw[XBM_DATA].count) return 0; } + else if (kw[XBM_DATA].count && xbm_file_p (kw[XBM_DATA].value)) + { + /* In-memory XBM file. */ + if (kw[XBM_WIDTH].count || kw[XBM_HEIGHT].count || kw[XBM_FILE].count) + return 0; + } else { Lisp_Object data; *************** *** 4566,4576 **** return 0; } - /* Baseline must be a value between 0 and 100 (a percentage). */ - if (kw[XBM_ASCENT].count - && XFASTINT (kw[XBM_ASCENT].value) > 100) - return 0; - return 1; } --- 5307,5312 ---- *************** *** 4582,4611 **** scanning a number, store its value in *IVAL. */ static int ! xbm_scan (fp, sval, ival) ! FILE *fp; char *sval; int *ival; { int c; /* Skip white space. */ ! while ((c = fgetc (fp)) != EOF && isspace (c)) ; ! if (c == EOF) c = 0; else if (isdigit (c)) { int value = 0, digit; ! if (c == '0') { ! c = fgetc (fp); if (c == 'x' || c == 'X') { ! while ((c = fgetc (fp)) != EOF) { if (isdigit (c)) digit = c - '0'; else if (c >= 'a' && c <= 'f') --- 5318,5350 ---- scanning a number, store its value in *IVAL. */ static int ! xbm_scan (s, end, sval, ival) ! char **s, *end; char *sval; int *ival; { int c; + loop: + /* Skip white space. */ ! while (*s < end && (c = *(*s)++, isspace (c))) ; ! if (*s >= end) c = 0; else if (isdigit (c)) { int value = 0, digit; ! if (c == '0' && *s < end) { ! c = *(*s)++; if (c == 'x' || c == 'X') { ! while (*s < end) { + c = *(*s)++; if (isdigit (c)) digit = c - '0'; else if (c >= 'a' && c <= 'f') *************** *** 4620,4672 **** else if (isdigit (c)) { value = c - '0'; ! while ((c = fgetc (fp)) != EOF ! && isdigit (c)) value = 8 * value + c - '0'; } } else { value = c - '0'; ! while ((c = fgetc (fp)) != EOF ! && isdigit (c)) value = 10 * value + c - '0'; } ! if (c != EOF) ! ungetc (c, fp); *ival = value; c = XBM_TK_NUMBER; } else if (isalpha (c) || c == '_') { *sval++ = c; ! while ((c = fgetc (fp)) != EOF ! && (isalnum (c) || c == '_')) *sval++ = c; *sval = 0; ! if (c != EOF) ! ungetc (c, fp); c = XBM_TK_IDENT; } return c; } /* Replacement for XReadBitmapFileData which isn't available under old ! X versions. FILE is the name of the bitmap file to read. Set ! *WIDTH and *HEIGHT to the width and height of the image. Return in ! *DATA the bitmap data allocated with xmalloc. Value is non-zero if ! successful. */ static int ! xbm_read_bitmap_file_data (file, width, height, data) ! char *file; int *width, *height; unsigned char **data; { ! FILE *fp; char buffer[BUFSIZ]; int padding_p = 0; int v10 = 0; --- 5359,5424 ---- else if (isdigit (c)) { value = c - '0'; ! while (*s < end ! && (c = *(*s)++, isdigit (c))) value = 8 * value + c - '0'; } } else { value = c - '0'; ! while (*s < end ! && (c = *(*s)++, isdigit (c))) value = 10 * value + c - '0'; } ! if (*s < end) ! *s = *s - 1; *ival = value; c = XBM_TK_NUMBER; } else if (isalpha (c) || c == '_') { *sval++ = c; ! while (*s < end ! && (c = *(*s)++, (isalnum (c) || c == '_'))) *sval++ = c; *sval = 0; ! if (*s < end) ! *s = *s - 1; c = XBM_TK_IDENT; } + else if (c == '/' && **s == '*') + { + /* C-style comment. */ + ++*s; + while (**s && (**s != '*' || *(*s + 1) != '/')) + ++*s; + if (**s) + { + *s += 2; + goto loop; + } + } return c; } /* Replacement for XReadBitmapFileData which isn't available under old ! X versions. CONTENTS is a pointer to a buffer to parse; END is the ! buffer's end. Set *WIDTH and *HEIGHT to the width and height of ! the image. Return in *DATA the bitmap data allocated with xmalloc. ! Value is non-zero if successful. DATA null means just test if ! CONTENTS looks like an in-memory XBM file. */ static int ! xbm_read_bitmap_data (contents, end, width, height, data) ! char *contents, *end; int *width, *height; unsigned char **data; { ! char *s = contents; char buffer[BUFSIZ]; int padding_p = 0; int v10 = 0; *************** *** 4676,4682 **** int LA1; #define match() \ ! LA1 = xbm_scan (fp, buffer, &value) #define expect(TOKEN) \ if (LA1 != (TOKEN)) \ --- 5428,5434 ---- int LA1; #define match() \ ! LA1 = xbm_scan (&s, end, buffer, &value) #define expect(TOKEN) \ if (LA1 != (TOKEN)) \ *************** *** 4690,4702 **** else \ goto failure - fp = fopen (file, "r"); - if (fp == NULL) - return 0; - *width = *height = -1; ! *data = NULL; ! LA1 = xbm_scan (fp, buffer, &value); /* Parse defines for width, height and hot-spots. */ while (LA1 == '#') --- 5442,5451 ---- else \ goto failure *width = *height = -1; ! if (data) ! *data = NULL; ! LA1 = xbm_scan (&s, end, buffer, &value); /* Parse defines for width, height and hot-spots. */ while (LA1 == '#') *************** *** 4719,4724 **** --- 5468,5475 ---- if (*width < 0 || *height < 0) goto failure; + else if (data == NULL) + goto success; /* Parse bits. Must start with `static'. */ expect_ident ("static"); *************** *** 4756,4762 **** if (v10) { - for (i = 0; i < nbytes; i += 2) { int val = value; --- 5507,5512 ---- *************** *** 4788,4800 **** } } ! fclose (fp); return 1; failure: ! fclose (fp); ! if (*data) { xfree (*data); *data = NULL; --- 5538,5549 ---- } } ! success: return 1; failure: ! if (data && *data) { xfree (*data); *data = NULL; *************** *** 4807,4844 **** } ! /* Load XBM image IMG which will be displayed on frame F from file ! SPECIFIED_FILE. Value is non-zero if successful. */ static int ! xbm_load_image_from_file (f, img, specified_file) struct frame *f; struct image *img; ! Lisp_Object specified_file; { int rc; unsigned char *data; int success_p = 0; - Lisp_Object file; - struct gcpro gcpro1; ! xassert (STRINGP (specified_file)); ! file = Qnil; ! GCPRO1 (file); ! ! file = x_find_image_file (specified_file); ! if (!STRINGP (file)) ! { ! image_error ("Cannot find image file `%s'", specified_file, Qnil); ! UNGCPRO; ! return 0; ! } ! ! rc = xbm_read_bitmap_file_data (SDATA (file), &img->width, ! &img->height, &data); if (rc) { ! int depth = one_mac_display_info.n_cbits; unsigned long foreground = FRAME_FOREGROUND_PIXEL (f); unsigned long background = FRAME_BACKGROUND_PIXEL (f); Lisp_Object value; --- 5556,5579 ---- } ! /* Load XBM image IMG which will be displayed on frame F from buffer ! CONTENTS. END is the end of the buffer. Value is non-zero if ! successful. */ static int ! xbm_load_image (f, img, contents, end) struct frame *f; struct image *img; ! char *contents, *end; { int rc; unsigned char *data; int success_p = 0; ! rc = xbm_read_bitmap_data (contents, end, &img->width, &img->height, &data); if (rc) { ! int depth = one_mac_display_info.n_planes; unsigned long foreground = FRAME_FOREGROUND_PIXEL (f); unsigned long background = FRAME_BACKGROUND_PIXEL (f); Lisp_Object value; *************** *** 4849,4864 **** value = image_spec_value (img->spec, QCforeground, NULL); if (!NILP (value)) foreground = x_alloc_image_color (f, img, value, foreground); - value = image_spec_value (img->spec, QCbackground, NULL); if (!NILP (value)) ! background = x_alloc_image_color (f, img, value, background); - #if 0 /* MAC_TODO : Port image display to Mac */ - BLOCK_INPUT; img->pixmap ! = XCreatePixmapFromBitmapData (FRAME_W32_DISPLAY (f), ! FRAME_W32_WINDOW (f), data, img->width, img->height, foreground, background, --- 5584,5600 ---- value = image_spec_value (img->spec, QCforeground, NULL); if (!NILP (value)) foreground = x_alloc_image_color (f, img, value, foreground); value = image_spec_value (img->spec, QCbackground, NULL); if (!NILP (value)) ! { ! background = x_alloc_image_color (f, img, value, background); ! img->background = background; ! img->background_valid = 1; ! } img->pixmap ! = XCreatePixmapFromBitmapData (FRAME_MAC_DISPLAY (f), ! FRAME_MAC_WINDOW (f), data, img->width, img->height, foreground, background, *************** *** 4868,4889 **** if (img->pixmap == 0) { x_clear_image (f, img); ! image_error ("Unable to create X pixmap for `%s'", file, Qnil); } else success_p = 1; - - UNBLOCK_INPUT; - #endif /* MAC_TODO */ } else image_error ("Error loading XBM image `%s'", img->spec, Qnil); - UNGCPRO; return success_p; } /* Fill image IMG which is used on frame F with pixmap data. Value is non-zero if successful. */ --- 5604,5636 ---- if (img->pixmap == 0) { x_clear_image (f, img); ! image_error ("Unable to create X pixmap for `%s'", img->spec, Qnil); } else success_p = 1; } else image_error ("Error loading XBM image `%s'", img->spec, Qnil); return success_p; } + /* Value is non-zero if DATA looks like an in-memory XBM file. */ + + static int + xbm_file_p (data) + Lisp_Object data; + { + int w, h; + return (STRINGP (data) + && xbm_read_bitmap_data (SDATA (data), + (SDATA (data) + + SBYTES (data)), + &w, &h, NULL)); + } + + /* Fill image IMG which is used on frame F with pixmap data. Value is non-zero if successful. */ *************** *** 4900,4906 **** /* If IMG->spec specifies a file name, create a non-file spec from it. */ file_name = image_spec_value (img->spec, QCfile, NULL); if (STRINGP (file_name)) ! success_p = xbm_load_image_from_file (f, img, file_name); else { struct image_keyword fmt[XBM_LAST]; --- 5647,5678 ---- /* If IMG->spec specifies a file name, create a non-file spec from it. */ file_name = image_spec_value (img->spec, QCfile, NULL); if (STRINGP (file_name)) ! { ! Lisp_Object file; ! char *contents; ! int size; ! struct gcpro gcpro1; ! ! file = x_find_image_file (file_name); ! GCPRO1 (file); ! if (!STRINGP (file)) ! { ! image_error ("Cannot find image file `%s'", file_name, Qnil); ! UNGCPRO; ! return 0; ! } ! ! contents = slurp_file (SDATA (file), &size); ! if (contents == NULL) ! { ! image_error ("Error loading XBM image `%s'", img->spec, Qnil); ! UNGCPRO; ! return 0; ! } ! ! success_p = xbm_load_image (f, img, contents, contents + size); ! UNGCPRO; ! } else { struct image_keyword fmt[XBM_LAST]; *************** *** 4910,4984 **** unsigned long background = FRAME_BACKGROUND_PIXEL (f); char *bits; int parsed_p; ! /* Parse the list specification. */ bcopy (xbm_format, fmt, sizeof fmt); parsed_p = parse_image_spec (img->spec, fmt, XBM_LAST, Qxbm); xassert (parsed_p); /* Get specified width, and height. */ ! img->width = XFASTINT (fmt[XBM_WIDTH].value); ! img->height = XFASTINT (fmt[XBM_HEIGHT].value); ! xassert (img->width > 0 && img->height > 0); ! ! BLOCK_INPUT; ! ! if (fmt[XBM_ASCENT].count) ! img->ascent = XFASTINT (fmt[XBM_ASCENT].value); /* Get foreground and background colors, maybe allocate colors. */ ! if (fmt[XBM_FOREGROUND].count) foreground = x_alloc_image_color (f, img, fmt[XBM_FOREGROUND].value, foreground); ! if (fmt[XBM_BACKGROUND].count) background = x_alloc_image_color (f, img, fmt[XBM_BACKGROUND].value, background); ! /* Set bits to the bitmap image data. */ ! data = fmt[XBM_DATA].value; ! if (VECTORP (data)) { ! int i; ! char *p; ! int nbytes = (img->width + BITS_PER_CHAR - 1) / BITS_PER_CHAR; ! ! p = bits = (char *) alloca (nbytes * img->height); ! for (i = 0; i < img->height; ++i, p += nbytes) { ! Lisp_Object line = XVECTOR (data)->contents[i]; ! if (STRINGP (line)) ! bcopy (SDATA (line), p, nbytes); ! else ! bcopy (XBOOL_VECTOR (line)->data, p, nbytes); ! } ! } ! else if (STRINGP (data)) ! bits = SDATA (data); ! else ! bits = XBOOL_VECTOR (data)->data; ! #if 0 /* MAC_TODO : port Mac display code */ ! /* Create the pixmap. */ ! depth = DefaultDepthOfScreen (FRAME_X_SCREEN (f)); ! img->pixmap ! = XCreatePixmapFromBitmapData (FRAME_W32_DISPLAY (f), ! FRAME_W32_WINDOW (f), ! bits, ! img->width, img->height, ! foreground, background, ! depth); ! #endif /* MAC_TODO */ ! if (img->pixmap) ! success_p = 1; ! else ! { ! image_error ("Unable to create pixmap for XBM image `%s'", ! img->spec, Qnil); ! x_clear_image (f, img); } - - UNBLOCK_INPUT; } return success_p; --- 5682,5761 ---- unsigned long background = FRAME_BACKGROUND_PIXEL (f); char *bits; int parsed_p; + int in_memory_file_p = 0; ! /* See if data looks like an in-memory XBM file. */ ! data = image_spec_value (img->spec, QCdata, NULL); ! in_memory_file_p = xbm_file_p (data); ! ! /* Parse the image specification. */ bcopy (xbm_format, fmt, sizeof fmt); parsed_p = parse_image_spec (img->spec, fmt, XBM_LAST, Qxbm); xassert (parsed_p); /* Get specified width, and height. */ ! if (!in_memory_file_p) ! { ! img->width = XFASTINT (fmt[XBM_WIDTH].value); ! img->height = XFASTINT (fmt[XBM_HEIGHT].value); ! xassert (img->width > 0 && img->height > 0); ! } /* Get foreground and background colors, maybe allocate colors. */ ! if (fmt[XBM_FOREGROUND].count ! && STRINGP (fmt[XBM_FOREGROUND].value)) foreground = x_alloc_image_color (f, img, fmt[XBM_FOREGROUND].value, foreground); ! if (fmt[XBM_BACKGROUND].count ! && STRINGP (fmt[XBM_BACKGROUND].value)) background = x_alloc_image_color (f, img, fmt[XBM_BACKGROUND].value, background); ! if (in_memory_file_p) ! success_p = xbm_load_image (f, img, SDATA (data), ! (SDATA (data) ! + SBYTES (data))); ! else { ! if (VECTORP (data)) { ! int i; ! char *p; ! int nbytes = (img->width + BITS_PER_CHAR - 1) / BITS_PER_CHAR; ! p = bits = (char *) alloca (nbytes * img->height); ! for (i = 0; i < img->height; ++i, p += nbytes) ! { ! Lisp_Object line = XVECTOR (data)->contents[i]; ! if (STRINGP (line)) ! bcopy (SDATA (line), p, nbytes); ! else ! bcopy (XBOOL_VECTOR (line)->data, p, nbytes); ! } ! } ! else if (STRINGP (data)) ! bits = SDATA (data); ! else ! bits = XBOOL_VECTOR (data)->data; ! /* Create the pixmap. */ ! depth = one_mac_display_info.n_planes; ! img->pixmap ! = XCreatePixmapFromBitmapData (FRAME_MAC_DISPLAY (f), ! FRAME_MAC_WINDOW (f), ! bits, ! img->width, img->height, ! foreground, background, ! depth); ! if (img->pixmap) ! success_p = 1; ! else ! { ! image_error ("Unable to create pixmap for XBM image `%s'", ! img->spec, Qnil); ! x_clear_image (f, img); ! } } } return success_p; *************** *** 5014,5020 **** --- 5791,5799 ---- XPM_RELIEF, XPM_ALGORITHM, XPM_HEURISTIC_MASK, + XPM_MASK, XPM_COLOR_SYMBOLS, + XPM_BACKGROUND, XPM_LAST }; *************** *** 5026,5037 **** {":type", IMAGE_SYMBOL_VALUE, 1}, {":file", IMAGE_STRING_VALUE, 0}, {":data", IMAGE_STRING_VALUE, 0}, ! {":ascent", IMAGE_NON_NEGATIVE_INTEGER_VALUE, 0}, {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0}, {":relief", IMAGE_INTEGER_VALUE, 0}, {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, ! {":color-symbols", IMAGE_DONT_CHECK_VALUE_TYPE, 0} }; /* Structure describing the image type XBM. */ --- 5805,5818 ---- {":type", IMAGE_SYMBOL_VALUE, 1}, {":file", IMAGE_STRING_VALUE, 0}, {":data", IMAGE_STRING_VALUE, 0}, ! {":ascent", IMAGE_ASCENT_VALUE, 0}, {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0}, {":relief", IMAGE_INTEGER_VALUE, 0}, {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, ! {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, ! {":color-symbols", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, ! {":background", IMAGE_STRING_OR_NIL_VALUE, 0} }; /* Structure describing the image type XBM. */ *************** *** 5082,5090 **** /* Either no `:color-symbols' or it's a list of conses whose car and cdr are strings. */ && (fmt[XPM_COLOR_SYMBOLS].count == 0 ! || xpm_valid_color_symbols_p (fmt[XPM_COLOR_SYMBOLS].value)) ! && (fmt[XPM_ASCENT].count == 0 ! || XFASTINT (fmt[XPM_ASCENT].value) < 100)); } --- 5863,5869 ---- /* Either no `:color-symbols' or it's a list of conses whose car and cdr are strings. */ && (fmt[XPM_COLOR_SYMBOLS].count == 0 ! || xpm_valid_color_symbols_p (fmt[XPM_COLOR_SYMBOLS].value))); } *************** *** 5096,5102 **** struct frame *f; struct image *img; { ! int rc, i; XpmAttributes attrs; Lisp_Object specified_file, color_symbols; --- 5875,5881 ---- struct frame *f; struct image *img; { ! int rc; XpmAttributes attrs; Lisp_Object specified_file, color_symbols; *************** *** 5111,5120 **** #ifdef XpmAllocCloseColors attrs.alloc_close_colors = 1; attrs.valuemask |= XpmAllocCloseColors; ! #else attrs.closeness = 600; attrs.valuemask |= XpmCloseness; ! #endif /* If image specification contains symbolic color definitions, add these to `attrs'. */ --- 5890,5899 ---- #ifdef XpmAllocCloseColors attrs.alloc_close_colors = 1; attrs.valuemask |= XpmAllocCloseColors; ! #else /* not XpmAllocCloseColors */ attrs.closeness = 600; attrs.valuemask |= XpmCloseness; ! #endif /* not XpmAllocCloseColors */ /* If image specification contains symbolic color definitions, add these to `attrs'. */ *************** *** 5154,5160 **** /* Create a pixmap for the image, either from a file, or from a string buffer containing data in the same format as an XPM file. */ ! BLOCK_INPUT; specified_file = image_spec_value (img->spec, QCfile, NULL); if (STRINGP (specified_file)) { --- 5933,5939 ---- /* Create a pixmap for the image, either from a file, or from a string buffer containing data in the same format as an XPM file. */ ! specified_file = image_spec_value (img->spec, QCfile, NULL); if (STRINGP (specified_file)) { *************** *** 5162,5188 **** if (!STRINGP (file)) { image_error ("Cannot find image file `%s'", specified_file, Qnil); - UNBLOCK_INPUT; return 0; } ! rc = XpmReadFileToPixmap (NULL, FRAME_W32_WINDOW (f), SDATA (file), &img->pixmap, &img->mask, &attrs); } else { Lisp_Object buffer = image_spec_value (img->spec, QCdata, NULL); ! rc = XpmCreatePixmapFromBuffer (NULL, FRAME_W32_WINDOW (f), SDATA (buffer), &img->pixmap, &img->mask, &attrs); } - UNBLOCK_INPUT; if (rc == XpmSuccess) { ! /* Remember allocated colors. */ img->ncolors = attrs.nalloc_pixels; img->colors = (unsigned long *) xmalloc (img->ncolors * sizeof *img->colors); --- 5941,5966 ---- if (!STRINGP (file)) { image_error ("Cannot find image file `%s'", specified_file, Qnil); return 0; } ! rc = XpmReadFileToPixmap (FRAME_MAC_DISPLAY (f), FRAME_MAC_WINDOW (f), SDATA (file), &img->pixmap, &img->mask, &attrs); } else { Lisp_Object buffer = image_spec_value (img->spec, QCdata, NULL); ! rc = XpmCreatePixmapFromBuffer (FRAME_MAC_DISPLAY (f), FRAME_MAC_WINDOW (f), SDATA (buffer), &img->pixmap, &img->mask, &attrs); } if (rc == XpmSuccess) { ! int i; ! img->ncolors = attrs.nalloc_pixels; img->colors = (unsigned long *) xmalloc (img->ncolors * sizeof *img->colors); *************** *** 5194,5202 **** xassert (img->width > 0 && img->height > 0); /* The call to XpmFreeAttributes below frees attrs.alloc_pixels. */ - BLOCK_INPUT; XpmFreeAttributes (&attrs); - UNBLOCK_INPUT; } else { --- 5972,5978 ---- *************** *** 5262,5276 **** int ct_colors_allocated; - /* Function prototypes. */ - - static void init_color_table P_ ((void)); - static void free_color_table P_ ((void)); - static unsigned long *colors_in_color_table P_ ((int *n)); - static unsigned long lookup_rgb_color P_ ((struct frame *f, int r, int g, int b)); - static unsigned long lookup_pixel_color P_ ((struct frame *f, unsigned long p)); - - /* Initialize the color table. */ static void --- 6038,6043 ---- *************** *** 5399,5579 **** colors_in_color_table (n) int *n; { ! int i, j; ! struct ct_color *p; ! unsigned long *colors; ! if (ct_colors_allocated == 0) { ! *n = 0; ! colors = NULL; } - else - { - colors = (unsigned long *) xmalloc (ct_colors_allocated - * sizeof *colors); - *n = ct_colors_allocated; ! for (i = j = 0; i < CT_SIZE; ++i) ! for (p = ct_table[i]; p; p = p->next) ! colors[j++] = p->pixel; } ! return colors; ! } ! #endif /* MAC_TODO */ ! ! /*********************************************************************** ! Algorithms ! ***********************************************************************/ ! #if 0 /* MAC_TODO : Mac versions of low level algorithms */ ! static void x_laplace_write_row P_ ((struct frame *, long *, ! int, XImage *, int)); ! static void x_laplace_read_row P_ ((struct frame *, Colormap, ! XColor *, int, XImage *, int)); ! /* Fill COLORS with RGB colors from row Y of image XIMG. F is the ! frame we operate on, CMAP is the color-map in effect, and WIDTH is ! the width of one row in the image. */ static void ! x_laplace_read_row (f, cmap, colors, width, ximg, y) struct frame *f; ! Colormap cmap; ! XColor *colors; ! int width; ! XImage *ximg; ! int y; { ! int x; ! ! for (x = 0; x < width; ++x) ! colors[x].pixel = XGetPixel (ximg, x, y); ! ! XQueryColors (NULL, cmap, colors, width); } ! /* Write row Y of image XIMG. PIXELS is an array of WIDTH longs ! containing the pixel colors to write. F is the frame we are ! working on. */ static void ! x_laplace_write_row (f, pixels, width, ximg, y) struct frame *f; ! long *pixels; ! int width; ! XImage *ximg; ! int y; { ! int x; ! ! for (x = 0; x < width; ++x) ! XPutPixel (ximg, x, y, pixels[x]); } - #endif /* MAC_TODO */ ! /* Transform image IMG which is used on frame F with a Laplace ! edge-detection algorithm. The result is an image that can be used ! to draw disabled buttons, for example. */ static void ! x_laplace (f, img) struct frame *f; struct image *img; { ! #if 0 /* MAC_TODO : Mac version */ ! Colormap cmap = DefaultColormapOfScreen (FRAME_X_SCREEN (f)); ! XImage *ximg, *oimg; ! XColor *in[3]; ! long *out; ! Pixmap pixmap; ! int x, y, i; ! long pixel; ! int in_y, out_y, rc; ! int mv2 = 45000; ! BLOCK_INPUT; ! /* Get the X image IMG->pixmap. */ ! ximg = XGetImage (NULL, img->pixmap, ! 0, 0, img->width, img->height, ~0, ZPixmap); ! /* Allocate 3 input rows, and one output row of colors. */ ! for (i = 0; i < 3; ++i) ! in[i] = (XColor *) alloca (img->width * sizeof (XColor)); ! out = (long *) alloca (img->width * sizeof (long)); ! ! /* Create an X image for output. */ ! rc = x_create_x_image_and_pixmap (f, img->width, img->height, 0, ! &oimg, &pixmap); ! ! /* Fill first two rows. */ ! x_laplace_read_row (f, cmap, in[0], img->width, ximg, 0); ! x_laplace_read_row (f, cmap, in[1], img->width, ximg, 1); ! in_y = 2; - /* Write first row, all zeros. */ - init_color_table (); - pixel = lookup_rgb_color (f, 0, 0, 0); - for (x = 0; x < img->width; ++x) - out[x] = pixel; - x_laplace_write_row (f, out, img->width, oimg, 0); - out_y = 1; ! for (y = 2; y < img->height; ++y) ! { ! int rowa = y % 3; ! int rowb = (y + 2) % 3; ! x_laplace_read_row (f, cmap, in[rowa], img->width, ximg, in_y++); ! for (x = 0; x < img->width - 2; ++x) { ! int r = in[rowa][x].red + mv2 - in[rowb][x + 2].red; ! int g = in[rowa][x].green + mv2 - in[rowb][x + 2].green; ! int b = in[rowa][x].blue + mv2 - in[rowb][x + 2].blue; ! ! out[x + 1] = lookup_rgb_color (f, r & 0xffff, g & 0xffff, ! b & 0xffff); } ! x_laplace_write_row (f, out, img->width, oimg, out_y++); } ! /* Write last line, all zeros. */ ! for (x = 0; x < img->width; ++x) ! out[x] = pixel; ! x_laplace_write_row (f, out, img->width, oimg, out_y); ! ! /* Free the input image, and free resources of IMG. */ ! XDestroyImage (ximg); ! x_clear_image (f, img); ! ! /* Put the output image into pixmap, and destroy it. */ ! x_put_x_image (f, oimg, pixmap, img->width, img->height); ! x_destroy_x_image (oimg); ! /* Remember new pixmap and colors in IMG. */ ! img->pixmap = pixmap; ! img->colors = colors_in_color_table (&img->ncolors); ! free_color_table (); ! UNBLOCK_INPUT; ! #endif /* MAC_TODO */ } ! /* Build a mask for image IMG which is used on frame F. FILE is the ! name of an image file, for error messages. HOW determines how to ! determine the background color of IMG. If it is a list '(R G B)', with R, G, and B being integers >= 0, take that as the color of the ! background. Otherwise, determine the background color of IMG ! heuristically. Value is non-zero if successful. */ static int x_build_heuristic_mask (f, img, how) --- 6166,6539 ---- colors_in_color_table (n) int *n; { ! int i, j; ! struct ct_color *p; ! unsigned long *colors; ! ! if (ct_colors_allocated == 0) ! { ! *n = 0; ! colors = NULL; ! } ! else ! { ! colors = (unsigned long *) xmalloc (ct_colors_allocated ! * sizeof *colors); ! *n = ct_colors_allocated; ! ! for (i = j = 0; i < CT_SIZE; ++i) ! for (p = ct_table[i]; p; p = p->next) ! colors[j++] = p->pixel; ! } ! ! return colors; ! } ! ! #else ! static unsigned long ! lookup_rgb_color (f, r, g, b) ! struct frame *f; ! int r, g, b; ! { ! unsigned long pixel = RGB_TO_ULONG (r >> 8, g >> 8, b >> 8); ! ! gamma_correct (f, &pixel); ! return pixel; ! } ! #endif /* MAC_TODO */ ! ! ! /*********************************************************************** ! Algorithms ! ***********************************************************************/ ! ! static XColor *x_to_xcolors P_ ((struct frame *, struct image *, int)); ! static void x_from_xcolors P_ ((struct frame *, struct image *, XColor *)); ! static void x_detect_edges P_ ((struct frame *, struct image *, int[9], int)); ! ! /* Non-zero means draw a cross on images having `:conversion ! disabled'. */ ! ! int cross_disabled_images; ! ! /* Edge detection matrices for different edge-detection ! strategies. */ ! ! static int emboss_matrix[9] = { ! /* x - 1 x x + 1 */ ! 2, -1, 0, /* y - 1 */ ! -1, 0, 1, /* y */ ! 0, 1, -2 /* y + 1 */ ! }; ! ! static int laplace_matrix[9] = { ! /* x - 1 x x + 1 */ ! 1, 0, 0, /* y - 1 */ ! 0, 0, 0, /* y */ ! 0, 0, -1 /* y + 1 */ ! }; ! ! /* Value is the intensity of the color whose red/green/blue values ! are R, G, and B. */ ! ! #define COLOR_INTENSITY(R, G, B) ((2 * (R) + 3 * (G) + (B)) / 6) ! ! ! /* On frame F, return an array of XColor structures describing image ! IMG->pixmap. Each XColor structure has its pixel color set. RGB_P ! non-zero means also fill the red/green/blue members of the XColor ! structures. Value is a pointer to the array of XColors structures, ! allocated with xmalloc; it must be freed by the caller. */ ! ! static XColor * ! x_to_xcolors (f, img, rgb_p) ! struct frame *f; ! struct image *img; ! int rgb_p; ! { ! int x, y; ! XColor *colors, *p; ! XImagePtr ximg; ! ! colors = (XColor *) xmalloc (img->width * img->height * sizeof *colors); ! ! /* Get the X image IMG->pixmap. */ ! ximg = XGetImage (FRAME_X_DISPLAY (f), img->pixmap, ! 0, 0, img->width, img->height, ~0, ZPixmap); ! ! /* Fill the `pixel' members of the XColor array. I wished there ! were an easy and portable way to circumvent XGetPixel. */ ! p = colors; ! for (y = 0; y < img->height; ++y) ! { ! XColor *row = p; ! ! for (x = 0; x < img->width; ++x, ++p) ! { ! p->pixel = XGetPixel (ximg, x, y); ! ! if (rgb_p) ! { ! p->red = RED16_FROM_ULONG (p->pixel); ! p->green = GREEN16_FROM_ULONG (p->pixel); ! p->blue = BLUE16_FROM_ULONG (p->pixel); ! } ! } ! } ! ! XDestroyImage (ximg); ! return colors; ! } ! ! ! /* Create IMG->pixmap from an array COLORS of XColor structures, whose ! RGB members are set. F is the frame on which this all happens. ! COLORS will be freed; an existing IMG->pixmap will be freed, too. */ ! ! static void ! x_from_xcolors (f, img, colors) ! struct frame *f; ! struct image *img; ! XColor *colors; ! { ! int x, y; ! XImagePtr oimg; ! Pixmap pixmap; ! XColor *p; ! ! #if 0 /* TODO: color tables. */ ! init_color_table (); ! #endif ! ! x_create_x_image_and_pixmap (f, img->width, img->height, 0, ! &oimg, &pixmap); ! p = colors; ! for (y = 0; y < img->height; ++y) ! for (x = 0; x < img->width; ++x, ++p) ! { ! unsigned long pixel; ! pixel = lookup_rgb_color (f, p->red, p->green, p->blue); ! XPutPixel (oimg, x, y, pixel); ! } ! ! xfree (colors); ! x_clear_image_1 (f, img, 1, 0, 1); ! ! x_put_x_image (f, oimg, pixmap, img->width, img->height); ! x_destroy_x_image (oimg); ! img->pixmap = pixmap; ! #if 0 /* TODO: color tables. */ ! img->colors = colors_in_color_table (&img->ncolors); ! free_color_table (); ! #endif ! } ! ! ! /* On frame F, perform edge-detection on image IMG. ! ! MATRIX is a nine-element array specifying the transformation ! matrix. See emboss_matrix for an example. ! ! COLOR_ADJUST is a color adjustment added to each pixel of the ! outgoing image. */ ! ! static void ! x_detect_edges (f, img, matrix, color_adjust) ! struct frame *f; ! struct image *img; ! int matrix[9], color_adjust; ! { ! XColor *colors = x_to_xcolors (f, img, 1); ! XColor *new, *p; ! int x, y, i, sum; ! for (i = sum = 0; i < 9; ++i) ! sum += abs (matrix[i]); ! ! #define COLOR(A, X, Y) ((A) + (Y) * img->width + (X)) ! ! new = (XColor *) xmalloc (img->width * img->height * sizeof *new); ! ! for (y = 0; y < img->height; ++y) { ! p = COLOR (new, 0, y); ! p->red = p->green = p->blue = 0xffff/2; ! p = COLOR (new, img->width - 1, y); ! p->red = p->green = p->blue = 0xffff/2; } ! for (x = 1; x < img->width - 1; ++x) ! { ! p = COLOR (new, x, 0); ! p->red = p->green = p->blue = 0xffff/2; ! p = COLOR (new, x, img->height - 1); ! p->red = p->green = p->blue = 0xffff/2; } ! for (y = 1; y < img->height - 1; ++y) ! { ! p = COLOR (new, 1, y); ! for (x = 1; x < img->width - 1; ++x, ++p) ! { ! int r, g, b, y1, x1; ! r = g = b = i = 0; ! for (y1 = y - 1; y1 < y + 2; ++y1) ! for (x1 = x - 1; x1 < x + 2; ++x1, ++i) ! if (matrix[i]) ! { ! XColor *t = COLOR (colors, x1, y1); ! r += matrix[i] * t->red; ! g += matrix[i] * t->green; ! b += matrix[i] * t->blue; ! } ! ! r = (r / sum + color_adjust) & 0xffff; ! g = (g / sum + color_adjust) & 0xffff; ! b = (b / sum + color_adjust) & 0xffff; ! p->red = p->green = p->blue = COLOR_INTENSITY (r, g, b); ! } ! } ! ! xfree (colors); ! x_from_xcolors (f, img, new); ! #undef COLOR ! } ! /* Perform the pre-defined `emboss' edge-detection on image IMG ! on frame F. */ static void ! x_emboss (f, img) struct frame *f; ! struct image *img; { ! x_detect_edges (f, img, emboss_matrix, 0xffff / 2); } ! /* Perform the pre-defined `laplace' edge-detection on image IMG ! on frame F. */ static void ! x_laplace (f, img) struct frame *f; ! struct image *img; { ! x_detect_edges (f, img, laplace_matrix, 45000); } ! ! /* Perform edge-detection on image IMG on frame F, with specified ! transformation matrix MATRIX and color-adjustment COLOR_ADJUST. ! ! MATRIX must be either ! ! - a list of at least 9 numbers in row-major form ! - a vector of at least 9 numbers ! ! COLOR_ADJUST nil means use a default; otherwise it must be a ! number. */ static void ! x_edge_detection (f, img, matrix, color_adjust) struct frame *f; struct image *img; + Lisp_Object matrix, color_adjust; { ! int i = 0; ! int trans[9]; ! if (CONSP (matrix)) ! { ! for (i = 0; ! i < 9 && CONSP (matrix) && NUMBERP (XCAR (matrix)); ! ++i, matrix = XCDR (matrix)) ! trans[i] = XFLOATINT (XCAR (matrix)); ! } ! else if (VECTORP (matrix) && ASIZE (matrix) >= 9) ! { ! for (i = 0; i < 9 && NUMBERP (AREF (matrix, i)); ++i) ! trans[i] = XFLOATINT (AREF (matrix, i)); ! } ! if (NILP (color_adjust)) ! color_adjust = make_number (0xffff / 2); ! if (i == 9 && NUMBERP (color_adjust)) ! x_detect_edges (f, img, trans, (int) XFLOATINT (color_adjust)); ! } ! /* Transform image IMG on frame F so that it looks disabled. */ ! ! static void ! x_disable_image (f, img) ! struct frame *f; ! struct image *img; ! { ! struct x_display_info *dpyinfo = FRAME_MAC_DISPLAY_INFO (f); ! if (dpyinfo->n_planes >= 2) ! { ! /* Color (or grayscale). Convert to gray, and equalize. Just ! drawing such images with a stipple can look very odd, so ! we're using this method instead. */ ! XColor *colors = x_to_xcolors (f, img, 1); ! XColor *p, *end; ! const int h = 15000; ! const int l = 30000; ! for (p = colors, end = colors + img->width * img->height; ! p < end; ! ++p) { ! int i = COLOR_INTENSITY (p->red, p->green, p->blue); ! int i2 = (0xffff - h - l) * i / 0xffff + l; ! p->red = p->green = p->blue = i2; } ! x_from_xcolors (f, img, colors); } ! /* Draw a cross over the disabled image, if we must or if we ! should. */ ! if (dpyinfo->n_planes < 2 || cross_disabled_images) ! { ! Display *dpy = FRAME_MAC_DISPLAY (f); ! GC gc; ! gc = XCreateGC (dpy, NULL /*img->pixmap*/, 0, NULL); ! XSetForeground (dpy, gc, BLACK_PIX_DEFAULT (f)); ! mac_draw_line_to_pixmap (dpy, img->pixmap, gc, 0, 0, ! img->width - 1, img->height - 1); ! mac_draw_line_to_pixmap (dpy, img->pixmap, gc, 0, img->height - 1, ! img->width - 1, 0); ! XFreeGC (dpy, gc); ! if (img->mask) ! { ! gc = XCreateGC (dpy, NULL /*img->mask*/, 0, NULL); ! XSetForeground (dpy, gc, PIX_MASK_DRAW (f)); ! mac_draw_line_to_pixmap (dpy, img->mask, gc, 0, 0, ! img->width - 1, img->height - 1); ! mac_draw_line_to_pixmap (dpy, img->mask, gc, 0, img->height - 1, ! img->width - 1, 0); ! XFreeGC (dpy, gc); ! } ! } } ! /* Build a mask for image IMG which is used on frame F. FILE is the ! name of an image file, for error messages. HOW determines how to ! determine the background color of IMG. If it is a list '(R G B)', with R, G, and B being integers >= 0, take that as the color of the ! background. Otherwise, determine the background color of IMG ! heuristically. Value is non-zero if successful. */ static int x_build_heuristic_mask (f, img, how) *************** *** 5581,5619 **** struct image *img; Lisp_Object how; { ! #if 0 /* MAC_TODO : Mac version */ ! Display *dpy = FRAME_W32_DISPLAY (f); ! XImage *ximg, *mask_img; ! int x, y, rc, look_at_corners_p; ! unsigned long bg; ! ! BLOCK_INPUT; /* Create an image and pixmap serving as mask. */ rc = x_create_x_image_and_pixmap (f, img->width, img->height, 1, &mask_img, &img->mask); if (!rc) ! { ! UNBLOCK_INPUT; ! return 0; ! } /* Get the X image of IMG->pixmap. */ ximg = XGetImage (dpy, img->pixmap, 0, 0, img->width, img->height, ~0, ZPixmap); /* Determine the background color of ximg. If HOW is `(R G B)' ! take that as color. Otherwise, try to determine the color ! heuristically. */ ! look_at_corners_p = 1; if (CONSP (how)) { ! int rgb[3], i = 0; ! while (i < 3 ! && CONSP (how) ! && NATNUMP (XCAR (how))) { rgb[i] = XFASTINT (XCAR (how)) & 0xffff; how = XCDR (how); --- 6541,6577 ---- struct image *img; Lisp_Object how; { ! Display *dpy = FRAME_X_DISPLAY (f); ! XImagePtr ximg, mask_img; ! int x, y, rc, use_img_background; ! unsigned long bg = 0; ! ! if (img->mask) ! { ! XFreePixmap (FRAME_X_DISPLAY (f), img->mask); ! img->mask = 0; ! img->background_transparent_valid = 0; ! } /* Create an image and pixmap serving as mask. */ rc = x_create_x_image_and_pixmap (f, img->width, img->height, 1, &mask_img, &img->mask); if (!rc) ! return 0; /* Get the X image of IMG->pixmap. */ ximg = XGetImage (dpy, img->pixmap, 0, 0, img->width, img->height, ~0, ZPixmap); /* Determine the background color of ximg. If HOW is `(R G B)' ! take that as color. Otherwise, use the image's background color. */ ! use_img_background = 1; if (CONSP (how)) { ! int rgb[3], i; ! for (i = 0; i < 3 && CONSP (how) && NATNUMP (XCAR (how)); ++i) { rgb[i] = XFASTINT (XCAR (how)) & 0xffff; how = XCDR (how); *************** *** 5622,5680 **** if (i == 3 && NILP (how)) { char color_name[30]; - XColor exact, color; - Colormap cmap; - sprintf (color_name, "#%04x%04x%04x", rgb[0], rgb[1], rgb[2]); ! ! cmap = DefaultColormapOfScreen (FRAME_X_SCREEN (f)); ! if (XLookupColor (dpy, cmap, color_name, &exact, &color)) ! { ! bg = color.pixel; ! look_at_corners_p = 0; ! } } } ! if (look_at_corners_p) ! { ! unsigned long corners[4]; ! int i, best_count; ! ! /* Get the colors at the corners of ximg. */ ! corners[0] = XGetPixel (ximg, 0, 0); ! corners[1] = XGetPixel (ximg, img->width - 1, 0); ! corners[2] = XGetPixel (ximg, img->width - 1, img->height - 1); ! corners[3] = XGetPixel (ximg, 0, img->height - 1); ! ! /* Choose the most frequently found color as background. */ ! for (i = best_count = 0; i < 4; ++i) ! { ! int j, n; ! ! for (j = n = 0; j < 4; ++j) ! if (corners[i] == corners[j]) ! ++n; ! ! if (n > best_count) ! bg = corners[i], best_count = n; ! } ! } /* Set all bits in mask_img to 1 whose color in ximg is different from the background color bg. */ for (y = 0; y < img->height; ++y) for (x = 0; x < img->width; ++x) ! XPutPixel (mask_img, x, y, XGetPixel (ximg, x, y) != bg); /* Put mask_img into img->mask. */ x_put_x_image (f, mask_img, img->mask, img->width, img->height); x_destroy_x_image (mask_img); XDestroyImage (ximg); - UNBLOCK_INPUT; - #endif /* MAC_TODO */ - return 1; } --- 6580,6608 ---- if (i == 3 && NILP (how)) { char color_name[30]; sprintf (color_name, "#%04x%04x%04x", rgb[0], rgb[1], rgb[2]); ! bg = x_alloc_image_color (f, img, build_string (color_name), 0); ! use_img_background = 0; } } ! if (use_img_background) ! bg = four_corners_best (ximg, img->width, img->height); /* Set all bits in mask_img to 1 whose color in ximg is different from the background color bg. */ for (y = 0; y < img->height; ++y) for (x = 0; x < img->width; ++x) ! XPutPixel (mask_img, x, y, XGetPixel (ximg, x, y) != bg ? PIX_MASK_DRAW (f) : PIX_MASK_RETAIN (f)); ! ! /* Fill in the background_transparent field while we have the mask handy. */ ! image_background_transparent (img, f, mask_img); /* Put mask_img into img->mask. */ x_put_x_image (f, mask_img, img->mask, img->width, img->height); x_destroy_x_image (mask_img); XDestroyImage (ximg); return 1; } *************** *** 5683,5689 **** /*********************************************************************** PBM (mono, gray, color) ***********************************************************************/ - #ifdef HAVE_PBM static int pbm_image_p P_ ((Lisp_Object object)); static int pbm_load P_ ((struct frame *f, struct image *img)); --- 6611,6616 ---- *************** *** 5705,5710 **** --- 6632,6640 ---- PBM_RELIEF, PBM_ALGORITHM, PBM_HEURISTIC_MASK, + PBM_MASK, + PBM_FOREGROUND, + PBM_BACKGROUND, PBM_LAST }; *************** *** 5716,5726 **** {":type", IMAGE_SYMBOL_VALUE, 1}, {":file", IMAGE_STRING_VALUE, 0}, {":data", IMAGE_STRING_VALUE, 0}, ! {":ascent", IMAGE_NON_NEGATIVE_INTEGER_VALUE, 0}, {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0}, {":relief", IMAGE_INTEGER_VALUE, 0}, {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, ! {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0} }; /* Structure describing the image type `pbm'. */ --- 6646,6659 ---- {":type", IMAGE_SYMBOL_VALUE, 1}, {":file", IMAGE_STRING_VALUE, 0}, {":data", IMAGE_STRING_VALUE, 0}, ! {":ascent", IMAGE_ASCENT_VALUE, 0}, {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0}, {":relief", IMAGE_INTEGER_VALUE, 0}, {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, ! {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, ! {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, ! {":foreground", IMAGE_STRING_OR_NIL_VALUE, 0}, ! {":background", IMAGE_STRING_OR_NIL_VALUE, 0} }; /* Structure describing the image type `pbm'. */ *************** *** 5745,5753 **** bcopy (pbm_format, fmt, sizeof fmt); ! if (!parse_image_spec (object, fmt, PBM_LAST, Qpbm) ! || (fmt[PBM_ASCENT].count ! && XFASTINT (fmt[PBM_ASCENT].value) > 100)) return 0; /* Must specify either :data or :file. */ --- 6678,6684 ---- bcopy (pbm_format, fmt, sizeof fmt); ! if (!parse_image_spec (object, fmt, PBM_LAST, Qpbm)) return 0; /* Must specify either :data or :file. */ *************** *** 5763,5769 **** pbm_scan_number (s, end) unsigned char **s, *end; { ! int c, val = -1; while (*s < end) { --- 6694,6700 ---- pbm_scan_number (s, end) unsigned char **s, *end; { ! int c = 0, val = -1; while (*s < end) { *************** *** 5793,5834 **** } - /* Read FILE into memory. Value is a pointer to a buffer allocated - with xmalloc holding FILE's contents. Value is null if an error - occurred. *SIZE is set to the size of the file. */ - - static char * - pbm_read_file (file, size) - Lisp_Object file; - int *size; - { - FILE *fp = NULL; - char *buf = NULL; - struct stat st; - - if (stat (SDATA (file), &st) == 0 - && (fp = fopen (SDATA (file), "r")) != NULL - && (buf = (char *) xmalloc (st.st_size), - fread (buf, 1, st.st_size, fp) == st.st_size)) - { - *size = st.st_size; - fclose (fp); - } - else - { - if (fp) - fclose (fp); - if (buf) - { - xfree (buf); - buf = NULL; - } - } - - return buf; - } - - /* Load PBM image IMG for use on frame F. */ static int --- 6724,6729 ---- *************** *** 5838,5844 **** { int raw_p, x, y; int width, height, max_color_idx = 0; ! XImage *ximg; Lisp_Object file, specified_file; enum {PBM_MONO, PBM_GRAY, PBM_COLOR} type; struct gcpro gcpro1; --- 6733,6739 ---- { int raw_p, x, y; int width, height, max_color_idx = 0; ! XImagePtr ximg; Lisp_Object file, specified_file; enum {PBM_MONO, PBM_GRAY, PBM_COLOR} type; struct gcpro gcpro1; *************** *** 5854,5866 **** { file = x_find_image_file (specified_file); if (!STRINGP (file)) ! { ! image_error ("Cannot find image file `%s'", specified_file, Qnil); ! UNGCPRO; ! return 0; ! } ! contents = pbm_read_file (file, &size); if (contents == NULL) { image_error ("Error reading `%s'", file, Qnil); --- 6749,6761 ---- { file = x_find_image_file (specified_file); if (!STRINGP (file)) ! { ! image_error ("Cannot find image file `%s'", specified_file, Qnil); ! UNGCPRO; ! return 0; ! } ! contents = slurp_file (SDATA (file), &size); if (contents == NULL) { image_error ("Error reading `%s'", file, Qnil); *************** *** 5937,5956 **** || (type != PBM_MONO && max_color_idx < 0)) goto error; - BLOCK_INPUT; if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap)) ! { ! UNBLOCK_INPUT; ! goto error; ! } /* Initialize the color hash table. */ init_color_table (); if (type == PBM_MONO) { int c = 0, g; for (y = 0; y < height; ++y) for (x = 0; x < width; ++x) --- 6832,6868 ---- || (type != PBM_MONO && max_color_idx < 0)) goto error; if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap)) ! goto error; + #if 0 /* TODO: color tables. */ /* Initialize the color hash table. */ init_color_table (); + #endif if (type == PBM_MONO) { int c = 0, g; + struct image_keyword fmt[PBM_LAST]; + unsigned long fg = FRAME_FOREGROUND_PIXEL (f); + unsigned long bg = FRAME_BACKGROUND_PIXEL (f); + + /* Parse the image specification. */ + bcopy (pbm_format, fmt, sizeof fmt); + parse_image_spec (img->spec, fmt, PBM_LAST, Qpbm); + + /* Get foreground and background colors, maybe allocate colors. */ + if (fmt[PBM_FOREGROUND].count + && STRINGP (fmt[PBM_FOREGROUND].value)) + fg = x_alloc_image_color (f, img, fmt[PBM_FOREGROUND].value, fg); + if (fmt[PBM_BACKGROUND].count + && STRINGP (fmt[PBM_BACKGROUND].value)) + { + bg = x_alloc_image_color (f, img, fmt[PBM_BACKGROUND].value, bg); + img->background = bg; + img->background_valid = 1; + } for (y = 0; y < height; ++y) for (x = 0; x < width; ++x) *************** *** 5965,5973 **** else g = pbm_scan_number (&p, end); ! XPutPixel (ximg, x, y, (g ! ? FRAME_FOREGROUND_PIXEL (f) ! : FRAME_BACKGROUND_PIXEL (f))); } } else --- 6877,6883 ---- else g = pbm_scan_number (&p, end); ! XPutPixel (ximg, x, y, g ? fg : bg); } } else *************** *** 5994,6006 **** if (r < 0 || g < 0 || b < 0) { ! xfree (ximg->data); ! ximg->data = NULL; ! XDestroyImage (ximg); ! UNBLOCK_INPUT; image_error ("Invalid pixel value in image `%s'", img->spec, Qnil); ! goto error; } /* RGB values are now in the range 0..max_color_idx. --- 6904,6913 ---- if (r < 0 || g < 0 || b < 0) { ! x_destroy_x_image (ximg); image_error ("Invalid pixel value in image `%s'", img->spec, Qnil); ! goto error; } /* RGB values are now in the range 0..max_color_idx. *************** *** 6012,6026 **** } } /* Store in IMG->colors the colors allocated for the image, and free the color table. */ img->colors = colors_in_color_table (&img->ncolors); free_color_table (); /* Put the image into a pixmap. */ x_put_x_image (f, ximg, img->pixmap, width, height); x_destroy_x_image (ximg); - UNBLOCK_INPUT; img->width = width; img->height = height; --- 6919,6938 ---- } } + #if 0 /* TODO: color tables. */ /* Store in IMG->colors the colors allocated for the image, and free the color table. */ img->colors = colors_in_color_table (&img->ncolors); free_color_table (); + #endif + + /* Maybe fill in the background field while we have ximg handy. */ + if (NILP (image_spec_value (img->spec, QCbackground, NULL))) + IMAGE_BACKGROUND (img, f, ximg); /* Put the image into a pixmap. */ x_put_x_image (f, ximg, img->pixmap, width, height); x_destroy_x_image (ximg); img->width = width; img->height = height; *************** *** 6029,6044 **** xfree (contents); return 1; } ! #endif /* HAVE_PBM */ /*********************************************************************** PNG ***********************************************************************/ - #if HAVE_PNG - - #include /* Function prototypes. */ --- 6941,6953 ---- xfree (contents); return 1; } ! /*********************************************************************** PNG ***********************************************************************/ /* Function prototypes. */ *************** *** 6061,6066 **** --- 6970,6977 ---- PNG_RELIEF, PNG_ALGORITHM, PNG_HEURISTIC_MASK, + PNG_MASK, + PNG_BACKGROUND, PNG_LAST }; *************** *** 6072,6082 **** {":type", IMAGE_SYMBOL_VALUE, 1}, {":data", IMAGE_STRING_VALUE, 0}, {":file", IMAGE_STRING_VALUE, 0}, ! {":ascent", IMAGE_NON_NEGATIVE_INTEGER_VALUE, 0}, {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0}, {":relief", IMAGE_INTEGER_VALUE, 0}, {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, ! {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0} }; /* Structure describing the image type `png'. */ --- 6983,6995 ---- {":type", IMAGE_SYMBOL_VALUE, 1}, {":data", IMAGE_STRING_VALUE, 0}, {":file", IMAGE_STRING_VALUE, 0}, ! {":ascent", IMAGE_ASCENT_VALUE, 0}, {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0}, {":relief", IMAGE_INTEGER_VALUE, 0}, {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, ! {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, ! {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, ! {":background", IMAGE_STRING_OR_NIL_VALUE, 0} }; /* Structure describing the image type `png'. */ *************** *** 6100,6108 **** struct image_keyword fmt[PNG_LAST]; bcopy (png_format, fmt, sizeof fmt); ! if (!parse_image_spec (object, fmt, PNG_LAST, Qpng) ! || (fmt[PNG_ASCENT].count ! && XFASTINT (fmt[PNG_ASCENT].value) > 100)) return 0; /* Must specify either the :data or :file keyword. */ --- 7013,7019 ---- struct image_keyword fmt[PNG_LAST]; bcopy (png_format, fmt, sizeof fmt); ! if (!parse_image_spec (object, fmt, PNG_LAST, Qpng)) return 0; /* Must specify either the :data or :file keyword. */ *************** *** 6110,6115 **** --- 7021,7047 ---- } + #ifndef HAVE_PNG + static int + png_load (f, img) + struct frame *f; + struct image *img; + { + #ifdef MAC_OSX + if (MyCGImageCreateWithPNGDataProvider) + return image_load_quartz2d (f, img, 1); + else + #endif + return image_load_quicktime (f, img, kQTFileTypePNG); + } + #else + + #if defined HAVE_LIBPNG_PNG_H + # include + #else + # include + #endif + /* Error and warning handlers installed when the PNG library is initialized. */ *************** *** 6174,6195 **** Lisp_Object file, specified_file; Lisp_Object specified_data; int x, y, i; ! XImage *ximg, *mask_img = NULL; struct gcpro gcpro1; png_struct *png_ptr = NULL; png_info *info_ptr = NULL, *end_info = NULL; ! FILE *fp = NULL; png_byte sig[8]; ! png_byte *pixels = NULL; ! png_byte **rows = NULL; png_uint_32 width, height; int bit_depth, color_type, interlace_type; png_byte channels; png_uint_32 row_bytes; int transparent_p; ! char *gamma_str; ! double screen_gamma, image_gamma; ! int intent; struct png_memory_storage tbr; /* Data to be read */ /* Find out what file to load. */ --- 7106,7125 ---- Lisp_Object file, specified_file; Lisp_Object specified_data; int x, y, i; ! XImagePtr ximg, mask_img = NULL; struct gcpro gcpro1; png_struct *png_ptr = NULL; png_info *info_ptr = NULL, *end_info = NULL; ! FILE *volatile fp = NULL; png_byte sig[8]; ! png_byte * volatile pixels = NULL; ! png_byte ** volatile rows = NULL; png_uint_32 width, height; int bit_depth, color_type, interlace_type; png_byte channels; png_uint_32 row_bytes; int transparent_p; ! double screen_gamma; struct png_memory_storage tbr; /* Data to be read */ /* Find out what file to load. */ *************** *** 6202,6232 **** { file = x_find_image_file (specified_file); if (!STRINGP (file)) ! { ! image_error ("Cannot find image file `%s'", specified_file, Qnil); ! UNGCPRO; ! return 0; ! } /* Open the image file. */ fp = fopen (SDATA (file), "rb"); if (!fp) ! { ! image_error ("Cannot open image file `%s'", file, Qnil); ! UNGCPRO; ! fclose (fp); ! return 0; ! } /* Check PNG signature. */ if (fread (sig, 1, sizeof sig, fp) != sizeof sig ! || !png_check_sig (sig, sizeof sig)) ! { ! image_error ("Not a PNG file:` %s'", file, Qnil); ! UNGCPRO; ! fclose (fp); ! return 0; ! } } else { --- 7132,7162 ---- { file = x_find_image_file (specified_file); if (!STRINGP (file)) ! { ! image_error ("Cannot find image file `%s'", specified_file, Qnil); ! UNGCPRO; ! return 0; ! } /* Open the image file. */ fp = fopen (SDATA (file), "rb"); if (!fp) ! { ! image_error ("Cannot open image file `%s'", file, Qnil); ! UNGCPRO; ! fclose (fp); ! return 0; ! } /* Check PNG signature. */ if (fread (sig, 1, sizeof sig, fp) != sizeof sig ! || !png_check_sig (sig, sizeof sig)) ! { ! image_error ("Not a PNG file: `%s'", file, Qnil); ! UNGCPRO; ! fclose (fp); ! return 0; ! } } else { *************** *** 6325,6380 **** || color_type == PNG_COLOR_TYPE_GRAY_ALPHA) png_set_gray_to_rgb (png_ptr); ! /* The value 2.2 is a guess for PC monitors from PNG example.c. */ ! gamma_str = getenv ("SCREEN_GAMMA"); ! screen_gamma = gamma_str ? atof (gamma_str) : 2.2; ! ! /* Tell the PNG lib to handle gamma correction for us. */ #if defined(PNG_READ_sRGB_SUPPORTED) || defined(PNG_WRITE_sRGB_SUPPORTED) ! if (png_get_sRGB (png_ptr, info_ptr, &intent)) ! /* There is a special chunk in the image specifying the gamma. */ ! png_set_sRGB (png_ptr, info_ptr, intent); ! else #endif ! if (png_get_gAMA (png_ptr, info_ptr, &image_gamma)) ! /* Image contains gamma information. */ ! png_set_gamma (png_ptr, screen_gamma, image_gamma); ! else ! /* Use a default of 0.5 for the image gamma. */ ! png_set_gamma (png_ptr, screen_gamma, 0.5); /* Handle alpha channel by combining the image with a background color. Do this only if a real alpha channel is supplied. For simple transparency, we prefer a clipping mask. */ if (!transparent_p) { ! png_color_16 *image_background; ! if (png_get_bKGD (png_ptr, info_ptr, &image_background)) /* Image contains a background color with which to combine the image. */ ! png_set_background (png_ptr, image_background, PNG_BACKGROUND_GAMMA_FILE, 1, 1.0); else { /* Image does not contain a background color with which to combine the image data via an alpha channel. Use the frame's background instead. */ ! XColor color; ! Colormap cmap; png_color_16 frame_background; ! BLOCK_INPUT; ! cmap = DefaultColormapOfScreen (FRAME_X_SCREEN (f)); ! color.pixel = FRAME_BACKGROUND_PIXEL (f); ! XQueryColor (FRAME_W32_DISPLAY (f), cmap, &color); ! UNBLOCK_INPUT; ! bzero (&frame_background, sizeof frame_background); ! frame_background.red = color.red; ! frame_background.green = color.green; ! frame_background.blue = color.blue; png_set_background (png_ptr, &frame_background, PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0); --- 7255,7330 ---- || color_type == PNG_COLOR_TYPE_GRAY_ALPHA) png_set_gray_to_rgb (png_ptr); ! screen_gamma = (f->gamma ? 1 / f->gamma / 0.45455 : 2.2); + #if 0 /* Avoid double gamma correction for PNG images. */ + { /* Tell the PNG lib to handle gamma correction for us. */ + int intent; + double image_gamma; #if defined(PNG_READ_sRGB_SUPPORTED) || defined(PNG_WRITE_sRGB_SUPPORTED) ! if (png_get_sRGB (png_ptr, info_ptr, &intent)) ! /* The libpng documentation says this is right in this case. */ ! png_set_gamma (png_ptr, screen_gamma, 0.45455); ! else #endif ! if (png_get_gAMA (png_ptr, info_ptr, &image_gamma)) ! /* Image contains gamma information. */ ! png_set_gamma (png_ptr, screen_gamma, image_gamma); ! else ! /* Use the standard default for the image gamma. */ ! png_set_gamma (png_ptr, screen_gamma, 0.45455); ! } ! #endif /* if 0 */ /* Handle alpha channel by combining the image with a background color. Do this only if a real alpha channel is supplied. For simple transparency, we prefer a clipping mask. */ if (!transparent_p) { ! png_color_16 *image_bg; ! Lisp_Object specified_bg ! = image_spec_value (img->spec, QCbackground, NULL); ! ! if (STRINGP (specified_bg)) ! /* The user specified `:background', use that. */ ! { ! XColor color; ! if (mac_defined_color (f, SDATA (specified_bg), &color, 0)) ! { ! png_color_16 user_bg; ! ! bzero (&user_bg, sizeof user_bg); ! user_bg.red = color.red >> 8; ! user_bg.green = color.green >> 8; ! user_bg.blue = color.blue >> 8; ! png_set_background (png_ptr, &user_bg, ! PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0); ! } ! } ! else if (png_get_bKGD (png_ptr, info_ptr, &image_bg)) /* Image contains a background color with which to combine the image. */ ! png_set_background (png_ptr, image_bg, PNG_BACKGROUND_GAMMA_FILE, 1, 1.0); else { /* Image does not contain a background color with which to combine the image data via an alpha channel. Use the frame's background instead. */ ! unsigned long color; png_color_16 frame_background; + color = FRAME_BACKGROUND_PIXEL (f); + #if 0 /* TODO : Colormap support. */ + Colormap cmap; ! cmap = FRAME_X_COLORMAP (f); ! x_query_color (f, &color); ! #endif bzero (&frame_background, sizeof frame_background); ! frame_background.red = RED_FROM_ULONG (color); ! frame_background.green = GREEN_FROM_ULONG (color); ! frame_background.blue = BLUE_FROM_ULONG (color); png_set_background (png_ptr, &frame_background, PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0); *************** *** 6410,6424 **** fp = NULL; } - BLOCK_INPUT; - /* Create the X image and pixmap. */ if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap)) ! { ! UNBLOCK_INPUT; ! goto error; ! } /* Create an image and pixmap serving as mask if the PNG image contains an alpha channel. */ --- 7360,7369 ---- fp = NULL; } /* Create the X image and pixmap. */ if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap)) ! goto error; /* Create an image and pixmap serving as mask if the PNG image contains an alpha channel. */ *************** *** 6428,6441 **** &mask_img, &img->mask)) { x_destroy_x_image (ximg); ! XFreePixmap (FRAME_W32_DISPLAY (f), img->pixmap); ! img->pixmap = 0; ! UNBLOCK_INPUT; goto error; } /* Fill the X image and mask from PNG data. */ init_color_table (); for (y = 0; y < height; ++y) { --- 7373,7387 ---- &mask_img, &img->mask)) { x_destroy_x_image (ximg); ! XFreePixmap (FRAME_MAC_DISPLAY (f), img->pixmap); ! img->pixmap = NULL; goto error; } /* Fill the X image and mask from PNG data. */ + #if 0 /* TODO: Color tables. */ init_color_table (); + #endif for (y = 0; y < height; ++y) { *************** *** 6469,6483 **** if (channels == 4) { if (mask_img) ! XPutPixel (mask_img, x, y, *p > 0); ++p; } } } /* Remember colors allocated for this image. */ img->colors = colors_in_color_table (&img->ncolors); free_color_table (); /* Clean up. */ png_destroy_read_struct (&png_ptr, &info_ptr, &end_info); --- 7415,7443 ---- if (channels == 4) { if (mask_img) ! XPutPixel (mask_img, x, y, *p > 0 ? PIX_MASK_DRAW (f) : PIX_MASK_RETAIN (f)); ++p; } } } + if (NILP (image_spec_value (img->spec, QCbackground, NULL))) + /* Set IMG's background color from the PNG image, unless the user + overrode it. */ + { + png_color_16 *bg; + if (png_get_bKGD (png_ptr, info_ptr, &bg)) + { + img->background = lookup_rgb_color (f, bg->red, bg->green, bg->blue); + img->background_valid = 1; + } + } + + #if 0 /* TODO: Color tables. */ /* Remember colors allocated for this image. */ img->colors = colors_in_color_table (&img->ncolors); free_color_table (); + #endif /* Clean up. */ png_destroy_read_struct (&png_ptr, &info_ptr, &end_info); *************** *** 6487,6492 **** --- 7447,7455 ---- img->width = width; img->height = height; + /* Maybe fill in the background field while we have ximg handy. */ + IMAGE_BACKGROUND (img, f, ximg); + /* Put the image into the pixmap, then free the X image and its buffer. */ x_put_x_image (f, ximg, img->pixmap, width, height); x_destroy_x_image (ximg); *************** *** 6494,6532 **** /* Same for the mask. */ if (mask_img) { x_put_x_image (f, mask_img, img->mask, img->width, img->height); x_destroy_x_image (mask_img); } - UNBLOCK_INPUT; UNGCPRO; return 1; ! } ! ! #endif /* HAVE_PNG != 0 */ ! ! ! ! /*********************************************************************** ! JPEG ! ***********************************************************************/ ! ! #if HAVE_JPEG ! ! /* Work around a warning about HAVE_STDLIB_H being redefined in ! jconfig.h. */ ! #ifdef HAVE_STDLIB_H ! #define HAVE_STDLIB_H_1 ! #undef HAVE_STDLIB_H ! #endif /* HAVE_STLIB_H */ ! #include ! #include ! #include ! #ifdef HAVE_STLIB_H_1 ! #define HAVE_STDLIB_H 1 ! #endif static int jpeg_image_p P_ ((Lisp_Object object)); static int jpeg_load P_ ((struct frame *f, struct image *img)); --- 7457,7481 ---- /* Same for the mask. */ if (mask_img) { + /* Fill in the background_transparent field while we have the mask + handy. */ + image_background_transparent (img, f, mask_img); + x_put_x_image (f, mask_img, img->mask, img->width, img->height); x_destroy_x_image (mask_img); } UNGCPRO; return 1; ! } ! #endif /* HAVE_PNG */ ! ! ! /*********************************************************************** ! JPEG ! ***********************************************************************/ static int jpeg_image_p P_ ((Lisp_Object object)); static int jpeg_load P_ ((struct frame *f, struct image *img)); *************** *** 6547,6552 **** --- 7496,7503 ---- JPEG_RELIEF, JPEG_ALGORITHM, JPEG_HEURISTIC_MASK, + JPEG_MASK, + JPEG_BACKGROUND, JPEG_LAST }; *************** *** 6558,6568 **** {":type", IMAGE_SYMBOL_VALUE, 1}, {":data", IMAGE_STRING_VALUE, 0}, {":file", IMAGE_STRING_VALUE, 0}, ! {":ascent", IMAGE_NON_NEGATIVE_INTEGER_VALUE, 0}, {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0}, {":relief", IMAGE_INTEGER_VALUE, 0}, ! {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, ! {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0} }; /* Structure describing the image type `jpeg'. */ --- 7509,7521 ---- {":type", IMAGE_SYMBOL_VALUE, 1}, {":data", IMAGE_STRING_VALUE, 0}, {":file", IMAGE_STRING_VALUE, 0}, ! {":ascent", IMAGE_ASCENT_VALUE, 0}, {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0}, {":relief", IMAGE_INTEGER_VALUE, 0}, ! {":conversions", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, ! {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, ! {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, ! {":background", IMAGE_STRING_OR_NIL_VALUE, 0} }; /* Structure describing the image type `jpeg'. */ *************** *** 6587,6595 **** bcopy (jpeg_format, fmt, sizeof fmt); ! if (!parse_image_spec (object, fmt, JPEG_LAST, Qjpeg) ! || (fmt[JPEG_ASCENT].count ! && XFASTINT (fmt[JPEG_ASCENT].value) > 100)) return 0; /* Must specify either the :data or :file keyword. */ --- 7540,7546 ---- bcopy (jpeg_format, fmt, sizeof fmt); ! if (!parse_image_spec (object, fmt, JPEG_LAST, Qjpeg)) return 0; /* Must specify either the :data or :file keyword. */ *************** *** 6597,6608 **** --- 7548,7589 ---- } + #ifndef HAVE_JPEG + static int + jpeg_load (f, img) + struct frame *f; + struct image *img; + { + #ifdef MAC_OSX + return image_load_quartz2d (f, img, 0); + #else + return image_load_quicktime (f, img, kQTFileTypeJPEG); + #endif + } + #else + + /* Work around a warning about HAVE_STDLIB_H being redefined in + jconfig.h. */ + #ifdef HAVE_STDLIB_H + #define HAVE_STDLIB_H_1 + #undef HAVE_STDLIB_H + #endif /* HAVE_STLIB_H */ + + #include + #include + #include + + #ifdef HAVE_STLIB_H_1 + #define HAVE_STDLIB_H 1 + #endif + struct my_jpeg_error_mgr { struct jpeg_error_mgr pub; jmp_buf setjmp_buffer; }; + static void my_error_exit (cinfo) j_common_ptr cinfo; *************** *** 6611,6616 **** --- 7592,7598 ---- longjmp (mgr->setjmp_buffer, 1); } + /* Init source method for JPEG data source manager. Called by jpeg_read_header() before any data is actually read. See libjpeg.doc from the JPEG lib distribution. */ *************** *** 6719,6728 **** struct my_jpeg_error_mgr mgr; Lisp_Object file, specified_file; Lisp_Object specified_data; ! FILE *fp = NULL; JSAMPARRAY buffer; int row_stride, x, y; ! XImage *ximg = NULL; int rc; unsigned long *colors; int width, height; --- 7701,7710 ---- struct my_jpeg_error_mgr mgr; Lisp_Object file, specified_file; Lisp_Object specified_data; ! FILE * volatile fp = NULL; JSAMPARRAY buffer; int row_stride, x, y; ! XImagePtr ximg = NULL; int rc; unsigned long *colors; int width, height; *************** *** 6738,6762 **** { file = x_find_image_file (specified_file); if (!STRINGP (file)) ! { ! image_error ("Cannot find image file `%s'", specified_file, Qnil); ! UNGCPRO; ! return 0; ! } fp = fopen (SDATA (file), "r"); if (fp == NULL) ! { ! image_error ("Cannot open `%s'", file, Qnil); ! UNGCPRO; ! return 0; ! } } /* Customize libjpeg's error handling to call my_error_exit when an ! error is detected. This function will perform a longjmp. */ ! mgr.pub.error_exit = my_error_exit; cinfo.err = jpeg_std_error (&mgr.pub); if ((rc = setjmp (mgr.setjmp_buffer)) != 0) { --- 7720,7744 ---- { file = x_find_image_file (specified_file); if (!STRINGP (file)) ! { ! image_error ("Cannot find image file `%s'", specified_file, Qnil); ! UNGCPRO; ! return 0; ! } fp = fopen (SDATA (file), "r"); if (fp == NULL) ! { ! image_error ("Cannot open `%s'", file, Qnil); ! UNGCPRO; ! return 0; ! } } /* Customize libjpeg's error handling to call my_error_exit when an ! error is detected. This function will perform a longjmp. */ cinfo.err = jpeg_std_error (&mgr.pub); + mgr.pub.error_exit = my_error_exit; if ((rc = setjmp (mgr.setjmp_buffer)) != 0) { *************** *** 6771,6798 **** /* Close the input file and destroy the JPEG object. */ if (fp) ! fclose (fp); jpeg_destroy_decompress (&cinfo); - BLOCK_INPUT; - /* If we already have an XImage, free that. */ x_destroy_x_image (ximg); /* Free pixmap and colors. */ x_clear_image (f, img); - UNBLOCK_INPUT; UNGCPRO; return 0; } /* Create the JPEG decompression object. Let it read from fp. ! Read the JPEG image header. */ jpeg_create_decompress (&cinfo); if (NILP (specified_data)) ! jpeg_stdio_src (&cinfo, fp); else jpeg_memory_src (&cinfo, SDATA (specified_data), SBYTES (specified_data)); --- 7753,7777 ---- /* Close the input file and destroy the JPEG object. */ if (fp) ! fclose ((FILE *) fp); jpeg_destroy_decompress (&cinfo); /* If we already have an XImage, free that. */ x_destroy_x_image (ximg); /* Free pixmap and colors. */ x_clear_image (f, img); UNGCPRO; return 0; } /* Create the JPEG decompression object. Let it read from fp. ! Read the JPEG image header. */ jpeg_create_decompress (&cinfo); if (NILP (specified_data)) ! jpeg_stdio_src (&cinfo, (FILE *) fp); else jpeg_memory_src (&cinfo, SDATA (specified_data), SBYTES (specified_data)); *************** *** 6800,6820 **** jpeg_read_header (&cinfo, TRUE); /* Customize decompression so that color quantization will be used. ! Start decompression. */ cinfo.quantize_colors = TRUE; jpeg_start_decompress (&cinfo); width = img->width = cinfo.output_width; height = img->height = cinfo.output_height; - BLOCK_INPUT; - /* Create X image and pixmap. */ ! if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, ! &img->pixmap)) ! { ! UNBLOCK_INPUT; ! longjmp (mgr.setjmp_buffer, 2); ! } /* Allocate colors. When color quantization is used, cinfo.actual_number_of_colors has been set with the number of --- 7779,7793 ---- jpeg_read_header (&cinfo, TRUE); /* Customize decompression so that color quantization will be used. ! Start decompression. */ cinfo.quantize_colors = TRUE; jpeg_start_decompress (&cinfo); width = img->width = cinfo.output_width; height = img->height = cinfo.output_height; /* Create X image and pixmap. */ ! if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap)) ! longjmp (mgr.setjmp_buffer, 2); /* Allocate colors. When color quantization is used, cinfo.actual_number_of_colors has been set with the number of *************** *** 6831,6841 **** --- 7804,7816 ---- else ir = 0, ig = 0, ib = 0; + #if 0 /* TODO: Color tables. */ /* Use the color table mechanism because it handles colors that cannot be allocated nicely. Such colors will be replaced with a default color, and we don't have to care about which colors can be freed safely, and which can't. */ init_color_table (); + #endif colors = (unsigned long *) alloca (cinfo.actual_number_of_colors * sizeof *colors); *************** *** 6849,6857 **** --- 7824,7834 ---- colors[i] = lookup_rgb_color (f, r, g, b); } + #if 0 /* TODO: Color tables. */ /* Remember those colors actually allocated. */ img->colors = colors_in_color_table (&img->ncolors); free_color_table (); + #endif } /* Read pixels. */ *************** *** 6869,6880 **** jpeg_finish_decompress (&cinfo); jpeg_destroy_decompress (&cinfo); if (fp) ! fclose (fp); /* Put the image into the pixmap. */ x_put_x_image (f, ximg, img->pixmap, width, height); x_destroy_x_image (ximg); - UNBLOCK_INPUT; UNGCPRO; return 1; } --- 7846,7860 ---- jpeg_finish_decompress (&cinfo); jpeg_destroy_decompress (&cinfo); if (fp) ! fclose ((FILE *) fp); ! ! /* Maybe fill in the background field while we have ximg handy. */ ! if (NILP (image_spec_value (img->spec, QCbackground, NULL))) ! IMAGE_BACKGROUND (img, f, ximg); /* Put the image into the pixmap. */ x_put_x_image (f, ximg, img->pixmap, width, height); x_destroy_x_image (ximg); UNGCPRO; return 1; } *************** *** 6887,6896 **** TIFF ***********************************************************************/ - #if HAVE_TIFF - - #include - static int tiff_image_p P_ ((Lisp_Object object)); static int tiff_load P_ ((struct frame *f, struct image *img)); --- 7867,7872 ---- *************** *** 6910,6915 **** --- 7886,7893 ---- TIFF_RELIEF, TIFF_ALGORITHM, TIFF_HEURISTIC_MASK, + TIFF_MASK, + TIFF_BACKGROUND, TIFF_LAST }; *************** *** 6921,6931 **** {":type", IMAGE_SYMBOL_VALUE, 1}, {":data", IMAGE_STRING_VALUE, 0}, {":file", IMAGE_STRING_VALUE, 0}, ! {":ascent", IMAGE_NON_NEGATIVE_INTEGER_VALUE, 0}, {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0}, {":relief", IMAGE_INTEGER_VALUE, 0}, ! {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, ! {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0} }; /* Structure describing the image type `tiff'. */ --- 7899,7911 ---- {":type", IMAGE_SYMBOL_VALUE, 1}, {":data", IMAGE_STRING_VALUE, 0}, {":file", IMAGE_STRING_VALUE, 0}, ! {":ascent", IMAGE_ASCENT_VALUE, 0}, {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0}, {":relief", IMAGE_INTEGER_VALUE, 0}, ! {":conversions", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, ! {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, ! {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, ! {":background", IMAGE_STRING_OR_NIL_VALUE, 0} }; /* Structure describing the image type `tiff'. */ *************** *** 6949,6963 **** struct image_keyword fmt[TIFF_LAST]; bcopy (tiff_format, fmt, sizeof fmt); ! if (!parse_image_spec (object, fmt, TIFF_LAST, Qtiff) ! || (fmt[TIFF_ASCENT].count ! && XFASTINT (fmt[TIFF_ASCENT].value) > 100)) return 0; /* Must specify either the :data or :file keyword. */ return fmt[TIFF_FILE].count + fmt[TIFF_DATA].count == 1; } /* Reading from a memory buffer for TIFF images Based on the PNG memory source, but we have to provide a lot of extra functions. --- 7929,7954 ---- struct image_keyword fmt[TIFF_LAST]; bcopy (tiff_format, fmt, sizeof fmt); ! if (!parse_image_spec (object, fmt, TIFF_LAST, Qtiff)) return 0; /* Must specify either the :data or :file keyword. */ return fmt[TIFF_FILE].count + fmt[TIFF_DATA].count == 1; } + #ifndef HAVE_TIFF + + static int + tiff_load (f, img) + struct frame *f; + struct image *img; + { + return image_load_quicktime (f, img, kQTFileTypeTIFF); + } + + #else + + #include /* Reading from a memory buffer for TIFF images Based on the PNG memory source, but we have to provide a lot of extra functions. *************** *** 6976,6981 **** --- 7967,7973 ---- } tiff_memory_source; + static size_t tiff_read_from_memory (data, buf, size) thandle_t data; *************** *** 6991,6996 **** --- 7983,7989 ---- return size; } + static size_t tiff_write_from_memory (data, buf, size) thandle_t data; *************** *** 7000,7005 **** --- 7993,7999 ---- return (size_t) -1; } + static toff_t tiff_seek_in_memory (data, off, whence) thandle_t data; *************** *** 7023,7029 **** idx = src->index + off; break; ! default: /* Invalid `whence'. */ return -1; } --- 8017,8023 ---- idx = src->index + off; break; ! default: /* Invalid `whence'. */ return -1; } *************** *** 7034,7039 **** --- 8028,8034 ---- return src->index; } + static int tiff_close_memory (data) thandle_t data; *************** *** 7042,7047 **** --- 8037,8043 ---- return 0; } + static int tiff_mmap_memory (data, pbase, psize) thandle_t data; *************** *** 7052,7057 **** --- 8048,8054 ---- return 0; } + static void tiff_unmap_memory (data, base, size) thandle_t data; *************** *** 7061,7066 **** --- 8058,8064 ---- /* We don't need to do this. */ } + static toff_t tiff_size_of_memory (data) thandle_t data; *************** *** 7068,7073 **** --- 8066,8100 ---- return ((tiff_memory_source *) data)->len; } + + static void + tiff_error_handler (title, format, ap) + const char *title, *format; + va_list ap; + { + char buf[512]; + int len; + + len = sprintf (buf, "TIFF error: %s ", title); + vsprintf (buf + len, format, ap); + add_to_log (buf, Qnil, Qnil); + } + + + static void + tiff_warning_handler (title, format, ap) + const char *title, *format; + va_list ap; + { + char buf[512]; + int len; + + len = sprintf (buf, "TIFF warning: %s ", title); + vsprintf (buf + len, format, ap); + add_to_log (buf, Qnil, Qnil); + } + + /* Load TIFF image IMG for use on frame F. Value is non-zero if successful. */ *************** *** 7082,7088 **** int width, height, x, y; uint32 *buf; int rc; ! XImage *ximg; struct gcpro gcpro1; tiff_memory_source memsrc; --- 8109,8115 ---- int width, height, x, y; uint32 *buf; int rc; ! XImagePtr ximg; struct gcpro gcpro1; tiff_memory_source memsrc; *************** *** 7091,7115 **** file = Qnil; GCPRO1 (file); if (NILP (specified_data)) { /* Read from a file */ file = x_find_image_file (specified_file); if (!STRINGP (file)) ! { ! image_error ("Cannot find image file `%s'", file, Qnil); ! UNGCPRO; ! return 0; ! } /* Try to open the image file. */ tiff = TIFFOpen (SDATA (file), "r"); if (tiff == NULL) ! { ! image_error ("Cannot open `%s'", file, Qnil); ! UNGCPRO; ! return 0; ! } } else { --- 8118,8145 ---- file = Qnil; GCPRO1 (file); + TIFFSetErrorHandler (tiff_error_handler); + TIFFSetWarningHandler (tiff_warning_handler); + if (NILP (specified_data)) { /* Read from a file */ file = x_find_image_file (specified_file); if (!STRINGP (file)) ! { ! image_error ("Cannot find image file `%s'", specified_file, Qnil); ! UNGCPRO; ! return 0; ! } /* Try to open the image file. */ tiff = TIFFOpen (SDATA (file), "r"); if (tiff == NULL) ! { ! image_error ("Cannot open `%s'", file, Qnil); ! UNGCPRO; ! return 0; ! } } else { *************** *** 7151,7169 **** return 0; } - BLOCK_INPUT; - /* Create the X image and pixmap. */ if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap)) { - UNBLOCK_INPUT; xfree (buf); UNGCPRO; return 0; } /* Initialize the color table. */ init_color_table (); /* Process the pixel raster. Origin is in the lower-left corner. */ for (y = 0; y < height; ++y) --- 8181,8198 ---- return 0; } /* Create the X image and pixmap. */ if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap)) { xfree (buf); UNGCPRO; return 0; } + #if 0 /* TODO: Color tables. */ /* Initialize the color table. */ init_color_table (); + #endif /* Process the pixel raster. Origin is in the lower-left corner. */ for (y = 0; y < height; ++y) *************** *** 7180,7203 **** } } /* Remember the colors allocated for the image. Free the color table. */ img->colors = colors_in_color_table (&img->ncolors); free_color_table (); /* Put the image into the pixmap, then free the X image and its buffer. */ x_put_x_image (f, ximg, img->pixmap, width, height); x_destroy_x_image (ximg); xfree (buf); - UNBLOCK_INPUT; - - img->width = width; - img->height = height; UNGCPRO; return 1; } ! #endif /* HAVE_TIFF != 0 */ --- 8209,8237 ---- } } + #if 0 /* TODO: Color tables. */ /* Remember the colors allocated for the image. Free the color table. */ img->colors = colors_in_color_table (&img->ncolors); free_color_table (); + #endif + + img->width = width; + img->height = height; + + /* Maybe fill in the background field while we have ximg handy. */ + if (NILP (image_spec_value (img->spec, QCbackground, NULL))) + IMAGE_BACKGROUND (img, f, ximg); /* Put the image into the pixmap, then free the X image and its buffer. */ x_put_x_image (f, ximg, img->pixmap, width, height); x_destroy_x_image (ximg); xfree (buf); UNGCPRO; return 1; } ! #endif /* HAVE_TIFF */ *************** *** 7205,7214 **** GIF ***********************************************************************/ - #if HAVE_GIF - - #include - static int gif_image_p P_ ((Lisp_Object object)); static int gif_load P_ ((struct frame *f, struct image *img)); --- 8239,8244 ---- *************** *** 7228,7234 **** --- 8258,8266 ---- GIF_RELIEF, GIF_ALGORITHM, GIF_HEURISTIC_MASK, + GIF_MASK, GIF_IMAGE, + GIF_BACKGROUND, GIF_LAST }; *************** *** 7240,7251 **** {":type", IMAGE_SYMBOL_VALUE, 1}, {":data", IMAGE_STRING_VALUE, 0}, {":file", IMAGE_STRING_VALUE, 0}, ! {":ascent", IMAGE_NON_NEGATIVE_INTEGER_VALUE, 0}, {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0}, {":relief", IMAGE_INTEGER_VALUE, 0}, {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, ! {":image", IMAGE_NON_NEGATIVE_INTEGER_VALUE, 0} }; /* Structure describing the image type `gif'. */ --- 8272,8285 ---- {":type", IMAGE_SYMBOL_VALUE, 1}, {":data", IMAGE_STRING_VALUE, 0}, {":file", IMAGE_STRING_VALUE, 0}, ! {":ascent", IMAGE_ASCENT_VALUE, 0}, {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0}, {":relief", IMAGE_INTEGER_VALUE, 0}, {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, ! {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, ! {":image", IMAGE_NON_NEGATIVE_INTEGER_VALUE, 0}, ! {":background", IMAGE_STRING_OR_NIL_VALUE, 0} }; /* Structure describing the image type `gif'. */ *************** *** 7259,7264 **** --- 8293,8299 ---- NULL }; + /* Return non-zero if OBJECT is a valid GIF image specification. */ static int *************** *** 7268,7282 **** struct image_keyword fmt[GIF_LAST]; bcopy (gif_format, fmt, sizeof fmt); ! if (!parse_image_spec (object, fmt, GIF_LAST, Qgif) ! || (fmt[GIF_ASCENT].count ! && XFASTINT (fmt[GIF_ASCENT].value) > 100)) return 0; /* Must specify either the :data or :file keyword. */ return fmt[GIF_FILE].count + fmt[GIF_DATA].count == 1; } /* Reading a GIF image from memory Based on the PNG memory stuff to a certain extent. */ --- 8303,8502 ---- struct image_keyword fmt[GIF_LAST]; bcopy (gif_format, fmt, sizeof fmt); ! if (!parse_image_spec (object, fmt, GIF_LAST, Qgif)) return 0; /* Must specify either the :data or :file keyword. */ return fmt[GIF_FILE].count + fmt[GIF_DATA].count == 1; } + #ifndef HAVE_GIF + + static int + gif_load (f, img) + struct frame *f; + struct image *img; + { + Lisp_Object specified_file, file; + Lisp_Object specified_data; + OSErr err; + Boolean graphic_p, movie_p, prefer_graphic_p; + Handle dh = NULL; + Movie movie = NULL; + Lisp_Object image; + Track track = NULL; + Media media = NULL; + long nsamples; + Rect rect; + Lisp_Object specified_bg; + XColor color; + RGBColor bg_color; + int width, height; + XImagePtr ximg; + TimeValue time; + struct gcpro gcpro1; + int ino; + + specified_file = image_spec_value (img->spec, QCfile, NULL); + specified_data = image_spec_value (img->spec, QCdata, NULL); + + if (NILP (specified_data)) + { + /* Read from a file */ + FSSpec fss; + short refnum; + + err = find_image_fsspec (specified_file, &file, &fss); + if (err != noErr) + { + if (err == fnfErr) + image_error ("Cannot find image file `%s'", specified_file, Qnil); + else + goto open_error; + } + + err = CanQuickTimeOpenFile (&fss, kQTFileTypeGIF, 0, + &graphic_p, &movie_p, &prefer_graphic_p, 0); + if (err != noErr) + goto open_error; + + if (!graphic_p && !movie_p) + goto open_error; + if (prefer_graphic_p) + return image_load_qt_1 (f, img, kQTFileTypeGIF, &fss, NULL); + err = OpenMovieFile (&fss, &refnum, fsRdPerm); + if (err != noErr) + goto open_error; + err = NewMovieFromFile (&movie, refnum, NULL, NULL, 0, NULL); + CloseMovieFile (refnum); + if (err != noErr) + { + image_error ("Error reading `%s'", file, Qnil); + return 0; + } + } + else + { + /* Memory source! */ + Handle dref = NULL; + long file_type_atom[3]; + + err = PtrToHand (SDATA (specified_data), &dh, SBYTES (specified_data)); + if (err != noErr) + { + image_error ("Cannot allocate data handle for `%s'", + img->spec, Qnil); + goto error; + } + + file_type_atom[0] = EndianU32_NtoB (sizeof (long) * 3); + file_type_atom[1] = EndianU32_NtoB (kDataRefExtensionMacOSFileType); + file_type_atom[2] = EndianU32_NtoB (kQTFileTypeGIF); + err = PtrToHand (&dh, &dref, sizeof (Handle)); + if (err == noErr) + /* no file name */ + err = PtrAndHand ("\p", dref, 1); + if (err == noErr) + err = PtrAndHand (file_type_atom, dref, sizeof (long) * 3); + if (err != noErr) + { + image_error ("Cannot allocate handle data ref for `%s'", img->spec, Qnil); + goto error; + } + err = CanQuickTimeOpenDataRef (dref, HandleDataHandlerSubType, &graphic_p, + &movie_p, &prefer_graphic_p, 0); + if (err != noErr) + goto open_error; + + if (!graphic_p && !movie_p) + goto open_error; + if (prefer_graphic_p) + { + int success_p; + + DisposeHandle (dref); + success_p = image_load_qt_1 (f, img, kQTFileTypeGIF, NULL, dh); + DisposeHandle (dh); + return success_p; + } + err = NewMovieFromDataRef (&movie, 0, NULL, dref, + HandleDataHandlerSubType); + DisposeHandle (dref); + if (err != noErr) + goto open_error; + } + + image = image_spec_value (img->spec, QCindex, NULL); + ino = INTEGERP (image) ? XFASTINT (image) : 0; + track = GetMovieIndTrack (movie, 1); + media = GetTrackMedia (track); + nsamples = GetMediaSampleCount (media); + if (ino >= nsamples) + { + image_error ("Invalid image number `%s' in image `%s'", + image, img->spec); + goto error; + } + + specified_bg = image_spec_value (img->spec, QCbackground, NULL); + if (!STRINGP (specified_bg) || + !mac_defined_color (f, SDATA (specified_bg), &color, 0)) + { + color.pixel = FRAME_BACKGROUND_PIXEL (f); + color.red = RED16_FROM_ULONG (color.pixel); + color.green = GREEN16_FROM_ULONG (color.pixel); + color.blue = BLUE16_FROM_ULONG (color.pixel); + } + GetMovieBox (movie, &rect); + width = img->width = rect.right - rect.left; + height = img->height = rect.bottom - rect.top; + if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap)) + goto error; + + SetGWorld (ximg, NULL); + bg_color.red = color.red; + bg_color.green = color.green; + bg_color.blue = color.blue; + RGBBackColor (&bg_color); + SetMovieActive (movie, TRUE); + SetMovieGWorld (movie, ximg, NULL); + SampleNumToMediaTime (media, ino + 1, &time, NULL); + SetMovieTimeValue (movie, time); + MoviesTask (movie, 0L); + DisposeTrackMedia (media); + DisposeMovieTrack (track); + DisposeMovie (movie); + if (dh) + DisposeHandle (dh); + /* Maybe fill in the background field while we have ximg handy. */ + if (NILP (image_spec_value (img->spec, QCbackground, NULL))) + IMAGE_BACKGROUND (img, f, ximg); + + /* Put the image into the pixmap. */ + x_put_x_image (f, ximg, img->pixmap, width, height); + x_destroy_x_image (ximg); + return 1; + + open_error: + image_error ("Cannot open `%s'", file, Qnil); + error: + if (media) + DisposeTrackMedia (media); + if (track) + DisposeMovieTrack (track); + if (movie) + DisposeMovie (movie); + if (dh) + DisposeHandle (dh); + return 0; + } + + #else + + #define DrawText gif_DrawText /* avoid conflict with QuickdrawText.h */ + #include + #undef DrawText + /* Reading a GIF image from memory Based on the PNG memory stuff to a certain extent. */ *************** *** 7288,7293 **** --- 8508,8514 ---- } gif_memory_source; + /* Make the current memory source available to gif_read_from_memory. It's done this way because not all versions of libungif support a UserData field in the GifFileType structure. */ *************** *** 7321,7327 **** Lisp_Object file, specified_file; Lisp_Object specified_data; int rc, width, height, x, y, i; ! XImage *ximg; ColorMapObject *gif_color_map; unsigned long pixel_colors[256]; GifFileType *gif; --- 8542,8548 ---- Lisp_Object file, specified_file; Lisp_Object specified_data; int rc, width, height, x, y, i; ! XImagePtr ximg; ColorMapObject *gif_color_map; unsigned long pixel_colors[256]; GifFileType *gif; *************** *** 7340,7359 **** { file = x_find_image_file (specified_file); if (!STRINGP (file)) ! { ! image_error ("Cannot find image file `%s'", specified_file, Qnil); ! UNGCPRO; ! return 0; ! } /* Open the GIF file. */ gif = DGifOpenFileName (SDATA (file)); if (gif == NULL) ! { ! image_error ("Cannot open `%s'", file, Qnil); ! UNGCPRO; ! return 0; ! } } else { --- 8561,8580 ---- { file = x_find_image_file (specified_file); if (!STRINGP (file)) ! { ! image_error ("Cannot find image file `%s'", specified_file, Qnil); ! UNGCPRO; ! return 0; ! } /* Open the GIF file. */ gif = DGifOpenFileName (SDATA (file)); if (gif == NULL) ! { ! image_error ("Cannot open `%s'", file, Qnil); ! UNGCPRO; ! return 0; ! } } else { *************** *** 7363,7369 **** memsrc.len = SBYTES (specified_data); memsrc.index = 0; ! gif = DGifOpen(&memsrc, gif_read_from_memory); if (!gif) { image_error ("Cannot open memory source `%s'", img->spec, Qnil); --- 8584,8590 ---- memsrc.len = SBYTES (specified_data); memsrc.index = 0; ! gif = DGifOpen (&memsrc, gif_read_from_memory); if (!gif) { image_error ("Cannot open memory source `%s'", img->spec, Qnil); *************** *** 7387,7407 **** if (ino >= gif->ImageCount) { image_error ("Invalid image number `%s' in image `%s'", ! image, img->spec); DGifCloseFile (gif); UNGCPRO; return 0; } ! width = img->width = gif->SWidth; ! height = img->height = gif->SHeight; ! ! BLOCK_INPUT; /* Create the X image and pixmap. */ if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap)) { - UNBLOCK_INPUT; DGifCloseFile (gif); UNGCPRO; return 0; --- 8608,8625 ---- if (ino >= gif->ImageCount) { image_error ("Invalid image number `%s' in image `%s'", ! image, img->spec); DGifCloseFile (gif); UNGCPRO; return 0; } ! width = img->width = max (gif->SWidth, gif->Image.Left + gif->Image.Width); ! height = img->height = max (gif->SHeight, gif->Image.Top + gif->Image.Height); /* Create the X image and pixmap. */ if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap)) { DGifCloseFile (gif); UNGCPRO; return 0; *************** *** 7411,7417 **** --- 8629,8637 ---- gif_color_map = gif->SavedImages[ino].ImageDesc.ColorMap; if (!gif_color_map) gif_color_map = gif->SColorMap; + #if 0 /* TODO: Color tables */ init_color_table (); + #endif bzero (pixel_colors, sizeof pixel_colors); for (i = 0; i < gif_color_map->ColorCount; ++i) *************** *** 7422,7429 **** --- 8642,8651 ---- pixel_colors[i] = lookup_rgb_color (f, r, g, b); } + #if 0 /* TODO: Color tables */ img->colors = colors_in_color_table (&img->ncolors); free_color_table (); + #endif /* Clear the part of the screen image that are not covered by the image from the GIF file. Full animated GIF support *************** *** 7460,7466 **** { static int interlace_start[] = {0, 4, 2, 1}; static int interlace_increment[] = {8, 8, 4, 2}; ! int pass, inc; int row = interlace_start[0]; pass = 0; --- 8682,8688 ---- { static int interlace_start[] = {0, 4, 2, 1}; static int interlace_increment[] = {8, 8, 4, 2}; ! int pass; int row = interlace_start[0]; pass = 0; *************** *** 7489,7511 **** for (y = 0; y < image_height; ++y) for (x = 0; x < image_width; ++x) { ! int i = raster[y* image_width + x]; XPutPixel (ximg, x + image_left, y + image_top, pixel_colors[i]); } } DGifCloseFile (gif); /* Put the image into the pixmap, then free the X image and its buffer. */ x_put_x_image (f, ximg, img->pixmap, width, height); x_destroy_x_image (ximg); - UNBLOCK_INPUT; UNGCPRO; return 1; } ! ! #endif /* HAVE_GIF != 0 */ --- 8711,8735 ---- for (y = 0; y < image_height; ++y) for (x = 0; x < image_width; ++x) { ! int i = raster[y * image_width + x]; XPutPixel (ximg, x + image_left, y + image_top, pixel_colors[i]); } } DGifCloseFile (gif); + /* Maybe fill in the background field while we have ximg handy. */ + if (NILP (image_spec_value (img->spec, QCbackground, NULL))) + IMAGE_BACKGROUND (img, f, ximg); + /* Put the image into the pixmap, then free the X image and its buffer. */ x_put_x_image (f, ximg, img->pixmap, width, height); x_destroy_x_image (ximg); UNGCPRO; return 1; } ! #endif /* HAVE_GIF */ *************** *** 7513,7523 **** Ghostscript ***********************************************************************/ - #ifdef HAVE_GHOSTSCRIPT - static int gs_image_p P_ ((Lisp_Object object)); - static int gs_load P_ ((struct frame *f, struct image *img)); - static void gs_clear_image P_ ((struct frame *f, struct image *img)); - /* The symbol `postscript' identifying images of this type. */ Lisp_Object Qpostscript; --- 8737,8742 ---- *************** *** 7526,7531 **** --- 8745,8755 ---- Lisp_Object QCloader, QCbounding_box, QCpt_width, QCpt_height; + #ifdef HAVE_GHOSTSCRIPT + static int gs_image_p P_ ((Lisp_Object object)); + static int gs_load P_ ((struct frame *f, struct image *img)); + static void gs_clear_image P_ ((struct frame *f, struct image *img)); + /* Indices of image specification fields in gs_format, below. */ enum gs_keyword_index *************** *** 7541,7546 **** --- 8765,8772 ---- GS_RELIEF, GS_ALGORITHM, GS_HEURISTIC_MASK, + GS_MASK, + GS_BACKGROUND, GS_LAST }; *************** *** 7555,7565 **** {":file", IMAGE_STRING_VALUE, 1}, {":loader", IMAGE_FUNCTION_VALUE, 0}, {":bounding-box", IMAGE_DONT_CHECK_VALUE_TYPE, 1}, ! {":ascent", IMAGE_NON_NEGATIVE_INTEGER_VALUE, 0}, {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0}, {":relief", IMAGE_INTEGER_VALUE, 0}, {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, ! {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0} }; /* Structure describing the image type `ghostscript'. */ --- 8781,8793 ---- {":file", IMAGE_STRING_VALUE, 1}, {":loader", IMAGE_FUNCTION_VALUE, 0}, {":bounding-box", IMAGE_DONT_CHECK_VALUE_TYPE, 1}, ! {":ascent", IMAGE_ASCENT_VALUE, 0}, {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0}, {":relief", IMAGE_INTEGER_VALUE, 0}, {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, ! {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, ! {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, ! {":background", IMAGE_STRING_OR_NIL_VALUE, 0} }; /* Structure describing the image type `ghostscript'. */ *************** *** 7600,7608 **** bcopy (gs_format, fmt, sizeof fmt); ! if (!parse_image_spec (object, fmt, GS_LAST, Qpostscript) ! || (fmt[GS_ASCENT].count ! && XFASTINT (fmt[GS_ASCENT].value) > 100)) return 0; /* Bounding box must be a list or vector containing 4 integers. */ --- 8828,8834 ---- bcopy (gs_format, fmt, sizeof fmt); ! if (!parse_image_spec (object, fmt, GS_LAST, Qpostscript)) return 0; /* Bounding box must be a list or vector containing 4 integers. */ *************** *** 7651,7668 **** info. */ pt_width = image_spec_value (img->spec, QCpt_width, NULL); in_width = XFASTINT (pt_width) / 72.0; ! img->width = in_width * FRAME_W32_DISPLAY_INFO (f)->resx; pt_height = image_spec_value (img->spec, QCpt_height, NULL); in_height = XFASTINT (pt_height) / 72.0; ! img->height = in_height * FRAME_W32_DISPLAY_INFO (f)->resy; /* Create the pixmap. */ ! BLOCK_INPUT; ! xassert (img->pixmap == 0); ! img->pixmap = XCreatePixmap (FRAME_W32_DISPLAY (f), FRAME_W32_WINDOW (f), img->width, img->height, ! DefaultDepthOfScreen (FRAME_X_SCREEN (f))); ! UNBLOCK_INPUT; if (!img->pixmap) { --- 8877,8892 ---- info. */ pt_width = image_spec_value (img->spec, QCpt_width, NULL); in_width = XFASTINT (pt_width) / 72.0; ! img->width = in_width * FRAME_MAC_DISPLAY_INFO (f)->resx; pt_height = image_spec_value (img->spec, QCpt_height, NULL); in_height = XFASTINT (pt_height) / 72.0; ! img->height = in_height * FRAME_MAC_DISPLAY_INFO (f)->resy; /* Create the pixmap. */ ! xassert (img->pixmap == NULL); ! img->pixmap = XCreatePixmap (FRAME_MAC_DISPLAY (f), FRAME_MAC_WINDOW (f), img->width, img->height, ! one_mac_display_info.n_planes); if (!img->pixmap) { *************** *** 7677,7683 **** GCPRO2 (window_and_pixmap_id, pixel_colors); sprintf (buffer, "%lu %lu", ! (unsigned long) FRAME_W32_WINDOW (f), (unsigned long) img->pixmap); window_and_pixmap_id = build_string (buffer); --- 8901,8907 ---- GCPRO2 (window_and_pixmap_id, pixel_colors); sprintf (buffer, "%lu %lu", ! (unsigned long) FRAME_MAC_WINDOW (f), (unsigned long) img->pixmap); window_and_pixmap_id = build_string (buffer); *************** *** 7719,7744 **** if (c->images[i]->pixmap == pixmap) break; /* Kill the GS process. We should have found PIXMAP in the image cache and its image should contain a process object. */ - xassert (i < c->used); img = c->images[i]; xassert (PROCESSP (img->data.lisp_val)); Fkill_process (img->data.lisp_val, Qnil); img->data.lisp_val = Qnil; /* On displays with a mutable colormap, figure out the colors allocated for the image by looking at the pixels of an XImage for img->pixmap. */ ! class = FRAME_W32_DISPLAY_INFO (f)->visual->class; if (class != StaticColor && class != StaticGray && class != TrueColor) { ! XImage *ximg; BLOCK_INPUT; /* Try to get an XImage for img->pixmep. */ ! ximg = XGetImage (FRAME_W32_DISPLAY (f), img->pixmap, 0, 0, img->width, img->height, ~0, ZPixmap); if (ximg) { --- 8943,8973 ---- if (c->images[i]->pixmap == pixmap) break; + /* Should someone in between have cleared the image cache, for + instance, give up. */ + if (i == c->used) + return; + /* Kill the GS process. We should have found PIXMAP in the image cache and its image should contain a process object. */ img = c->images[i]; xassert (PROCESSP (img->data.lisp_val)); Fkill_process (img->data.lisp_val, Qnil); img->data.lisp_val = Qnil; + #if 0 /* On displays with a mutable colormap, figure out the colors allocated for the image by looking at the pixels of an XImage for img->pixmap. */ ! class = FRAME_MAC_DISPLAY_INFO (f)->visual->class; if (class != StaticColor && class != StaticGray && class != TrueColor) { ! XImagePtr ximg; BLOCK_INPUT; /* Try to get an XImage for img->pixmep. */ ! ximg = XGetImage (FRAME_MAC_DISPLAY (f), img->pixmap, 0, 0, img->width, img->height, ~0, ZPixmap); if (ximg) { *************** *** 7769,7779 **** allocated colors on behalf of us. So, to get the reference counts right, free them once. */ if (img->ncolors) ! { ! Colormap cmap = DefaultColormapOfScreen (FRAME_X_SCREEN (f)); ! XFreeColors (FRAME_W32_DISPLAY (f), cmap, ! img->colors, img->ncolors, 0); ! } #endif } else --- 8998,9004 ---- allocated colors on behalf of us. So, to get the reference counts right, free them once. */ if (img->ncolors) ! x_free_colors (f, img->colors, img->ncolors); #endif } else *************** *** 7782,7787 **** --- 9007,9019 ---- UNBLOCK_INPUT; } + #endif + + /* Now that we have the pixmap, compute mask and transform the + image if requested. */ + BLOCK_INPUT; + postprocess_image (f, img); + UNBLOCK_INPUT; } #endif /* HAVE_GHOSTSCRIPT */ *************** *** 8793,8798 **** --- 10025,10042 ---- Qlaplace = intern ("laplace"); staticpro (&Qlaplace); + Qemboss = intern ("emboss"); + staticpro (&Qemboss); + Qedge_detection = intern ("edge-detection"); + staticpro (&Qedge_detection); + Qheuristic = intern ("heuristic"); + staticpro (&Qheuristic); + QCmatrix = intern (":matrix"); + staticpro (&QCmatrix); + QCcolor_adjustment = intern (":color-adjustment"); + staticpro (&QCcolor_adjustment); + QCmask = intern (":mask"); + staticpro (&QCmask); Qface_set_after_frame_default = intern ("face-set-after-frame-default"); staticpro (&Qface_set_after_frame_default); *************** *** 8802,8807 **** --- 10046,10057 ---- Fput (Qundefined_color, Qerror_message, build_string ("Undefined color")); + DEFVAR_BOOL ("cross-disabled-images", &cross_disabled_images, + doc: /* Non-nil means always draw a cross over disabled images. + Disabled images are those having an `:conversion disabled' property. + A cross is always drawn on black & white displays. */); + cross_disabled_images = 0; + DEFVAR_LISP ("x-bitmap-file-path", &Vx_bitmap_file_path, doc: /* List of directories to search for window system bitmap files. */); Vx_bitmap_file_path = decode_env_path ((char *) 0, "PATH"); *************** *** 8867,8875 **** --- 10117,10127 ---- meaning don't clear the cache. */); Vimage_cache_eviction_delay = make_number (30 * 60); + /* X window properties. */ defsubr (&Sx_change_window_property); defsubr (&Sx_delete_window_property); defsubr (&Sx_window_property); + defsubr (&Sxw_display_color_p); defsubr (&Sx_display_grayscale_p); defsubr (&Sxw_color_defined_p); *************** *** 8906,8920 **** load_font_func = x_load_font; find_ccl_program_func = x_find_ccl_program; query_font_func = x_query_font; - set_frame_fontset_func = x_set_font; check_window_system_func = check_mac; ! #if 0 /* MAC_TODO: Image support for Mac Images. */ Qxbm = intern ("xbm"); staticpro (&Qxbm); - QCtype = intern (":type"); - staticpro (&QCtype); QCconversion = intern (":conversion"); staticpro (&QCconversion); QCheuristic_mask = intern (":heuristic-mask"); --- 10158,10169 ---- load_font_func = x_load_font; find_ccl_program_func = x_find_ccl_program; query_font_func = x_query_font; set_frame_fontset_func = x_set_font; check_window_system_func = check_mac; ! /* Images. */ Qxbm = intern ("xbm"); staticpro (&Qxbm); QCconversion = intern (":conversion"); staticpro (&QCconversion); QCheuristic_mask = intern (":heuristic-mask"); *************** *** 8947,8979 **** staticpro (&Qxpm); #endif - #if HAVE_JPEG Qjpeg = intern ("jpeg"); staticpro (&Qjpeg); - #endif - #if HAVE_TIFF Qtiff = intern ("tiff"); staticpro (&Qtiff); - #endif - #if HAVE_GIF Qgif = intern ("gif"); staticpro (&Qgif); - #endif - #if HAVE_PNG Qpng = intern ("png"); staticpro (&Qpng); - #endif defsubr (&Sclear_image_cache); #if GLYPH_DEBUG defsubr (&Simagep); defsubr (&Slookup_image); #endif - #endif /* MAC_TODO */ hourglass_atimer = NULL; hourglass_shown_p = 0; --- 10196,10221 ---- staticpro (&Qxpm); #endif Qjpeg = intern ("jpeg"); staticpro (&Qjpeg); Qtiff = intern ("tiff"); staticpro (&Qtiff); Qgif = intern ("gif"); staticpro (&Qgif); Qpng = intern ("png"); staticpro (&Qpng); defsubr (&Sclear_image_cache); + defsubr (&Simage_size); + defsubr (&Simage_mask_p); #if GLYPH_DEBUG defsubr (&Simagep); defsubr (&Slookup_image); #endif hourglass_atimer = NULL; hourglass_shown_p = 0; *************** *** 8996,9025 **** Vimage_types = Qnil; define_image_type (&xbm_type); ! #if 0 /* NTEMACS_TODO : Image support for W32 */ define_image_type (&gs_type); define_image_type (&pbm_type); #if HAVE_XPM define_image_type (&xpm_type); #endif - #if HAVE_JPEG define_image_type (&jpeg_type); - #endif - - #if HAVE_TIFF define_image_type (&tiff_type); - #endif - - #if HAVE_GIF define_image_type (&gif_type); - #endif - - #if HAVE_PNG define_image_type (&png_type); #endif - #endif /* NTEMACS_TODO */ } /* arch-tag: d7591289-f374-4377-b245-12f5dbbb8edc --- 10238,10263 ---- Vimage_types = Qnil; define_image_type (&xbm_type); ! #if HAVE_GHOSTSCRIPT define_image_type (&gs_type); + #endif define_image_type (&pbm_type); #if HAVE_XPM define_image_type (&xpm_type); #endif define_image_type (&jpeg_type); define_image_type (&tiff_type); define_image_type (&gif_type); define_image_type (&png_type); + + /* Animated gifs use QuickTime Movie Toolbox. So initialize it + here. */ + EnterMovies (); + #ifdef MAC_OSX + init_image_func_pointer (); #endif } /* arch-tag: d7591289-f374-4377-b245-12f5dbbb8edc *** src/macgui.h.~1.8.~ Tue Sep 2 09:09:47 2003 --- src/macgui.h Mon Jan 12 19:05:53 2004 *************** *** 23,31 **** #ifndef EMACS_MACGUI_H #define EMACS_MACGUI_H - typedef int Pixmap; - typedef int Bitmap; - typedef int Display; /* fix later */ typedef char * XrmDatabase; /* fix later */ --- 23,28 ---- *************** *** 33,43 **** typedef unsigned long Time; #if MAC_OSX typedef struct OpaqueWindowPtr* Window; #else ! #include typedef WindowPtr Window; #endif #define FACE_DEFAULT (~0) --- 30,71 ---- typedef unsigned long Time; #if MAC_OSX + #undef mktime + #undef DEBUG + #undef Z + #undef free + #undef malloc + #undef realloc + /* Macros max and min defined in lisp.h conflict with those in + precompiled header Carbon.h. */ + #undef max + #undef min + #undef init_process + #include + #undef Z + #define Z (current_buffer->text->z) + #undef free + #define free unexec_free + #undef malloc + #define malloc unexec_malloc + #undef realloc + #define realloc unexec_realloc + #undef min + #define min(a, b) ((a) < (b) ? (a) : (b)) + #undef max + #define max(a, b) ((a) > (b) ? (a) : (b)) + #undef init_process + #define init_process emacs_init_process + #undef INFINITY typedef struct OpaqueWindowPtr* Window; #else ! #include /* for WindowPtr */ ! #include /* for GWorldPtr */ ! #include /* for ControlHandle in xdisp.c */ typedef WindowPtr Window; #endif + + typedef GWorldPtr Pixmap; #define FACE_DEFAULT (~0) *** src/macmenu.c.~1.12.~ Tue Sep 2 09:09:47 2003 --- src/macmenu.c Wed Dec 31 14:22:22 2003 *************** *** 35,68 **** #include "charset.h" #include "coding.h" ! #ifdef MAC_OSX ! #undef mktime ! #undef DEBUG ! #undef Z ! #undef free ! #undef malloc ! #undef realloc ! /* Macros max and min defined in lisp.h conflict with those in ! precompiled header Carbon.h. */ ! #undef max ! #undef min ! #undef init_process ! #include ! #undef Z ! #define Z (current_buffer->text->z) ! #undef free ! #define free unexec_free ! #undef malloc ! #define malloc unexec_malloc ! #undef realloc ! #define realloc unexec_realloc ! #undef min ! #define min(a, b) ((a) < (b) ? (a) : (b)) ! #undef max ! #define max(a, b) ((a) > (b) ? (a) : (b)) ! #undef init_process ! #define init_process emacs_init_process ! #else /* not MAC_OSX */ #include #include #include --- 35,41 ---- #include "charset.h" #include "coding.h" ! #ifndef MAC_OSX #include #include #include *** src/macterm.c.~1.53.~ Sat Jan 3 22:23:18 2004 --- src/macterm.c Tue Jan 13 17:37:15 2004 *************** *** 35,63 **** #endif #ifdef MAC_OSX - #undef mktime - #undef DEBUG - #undef free - #undef malloc - #undef realloc - /* Macros max and min defined in lisp.h conflict with those in - precompiled header Carbon.h. */ - #undef max - #undef min - #undef init_process - #include - #undef free - #define free unexec_free - #undef malloc - #define malloc unexec_malloc - #undef realloc - #define realloc unexec_realloc - #undef min - #define min(a, b) ((a) < (b) ? (a) : (b)) - #undef max - #define max(a, b) ((a) > (b) ? (a) : (b)) - #undef init_process - #define init_process emacs_init_process /* USE_CARBON_EVENTS determines if the Carbon Event Manager is used to obtain events from the event queue. If set to 0, WaitNextEvent is used instead. */ --- 35,40 ---- *************** *** 303,309 **** static void XTframe_rehighlight P_ ((struct frame *)); static void x_frame_rehighlight P_ ((struct x_display_info *)); static void x_draw_hollow_cursor P_ ((struct window *, struct glyph_row *)); ! static void x_draw_bar_cursor P_ ((struct window *, struct glyph_row *, int)); static void x_clip_to_row P_ ((struct window *, struct glyph_row *, GC)); static void x_flush P_ ((struct frame *f)); static void x_update_begin P_ ((struct frame *)); --- 280,288 ---- static void XTframe_rehighlight P_ ((struct frame *)); static void x_frame_rehighlight P_ ((struct x_display_info *)); static void x_draw_hollow_cursor P_ ((struct window *, struct glyph_row *)); ! static void x_draw_bar_cursor P_ ((struct window *, struct glyph_row *, int, ! enum text_cursor_kinds)); ! static void x_clip_to_row P_ ((struct window *, struct glyph_row *, GC)); static void x_flush P_ ((struct frame *f)); static void x_update_begin P_ ((struct frame *)); *************** *** 327,341 **** /* X display function emulation */ ! static void XFreePixmap (display, pixmap) ! Display *display; Pixmap pixmap; { ! PixMap *p = (PixMap *) pixmap; ! ! xfree (p->baseAddr); ! xfree (p); } --- 306,317 ---- /* X display function emulation */ ! void XFreePixmap (display, pixmap) ! Display *display; /* not used */ Pixmap pixmap; { ! DisposeGWorld (pixmap); } *************** *** 347,355 **** { RGBColor fg_color; ! fg_color.red = RED_FROM_ULONG (color) * 256; ! fg_color.green = GREEN_FROM_ULONG (color) * 256; ! fg_color.blue = BLUE_FROM_ULONG (color) * 256; RGBForeColor (&fg_color); } --- 323,331 ---- { RGBColor fg_color; ! fg_color.red = RED16_FROM_ULONG (color); ! fg_color.green = GREEN16_FROM_ULONG (color); ! fg_color.blue = BLUE16_FROM_ULONG (color); RGBForeColor (&fg_color); } *************** *** 363,371 **** { RGBColor bg_color; ! bg_color.red = RED_FROM_ULONG (color) * 256; ! bg_color.green = GREEN_FROM_ULONG (color) * 256; ! bg_color.blue = BLUE_FROM_ULONG (color) * 256; RGBBackColor (&bg_color); } --- 339,347 ---- { RGBColor bg_color; ! bg_color.red = RED16_FROM_ULONG (color); ! bg_color.green = GREEN16_FROM_ULONG (color); ! bg_color.blue = BLUE16_FROM_ULONG (color); RGBBackColor (&bg_color); } *************** *** 401,406 **** --- 377,399 ---- LineTo (x2, y2); } + void + mac_draw_line_to_pixmap (display, p, gc, x1, y1, x2, y2) + Display *display; + Pixmap p; + GC gc; + int x1, y1, x2, y2; + { + SetGWorld (p, NULL); + + mac_set_colors (gc); + + LockPixels (GetGWorldPixMap (p)); + MoveTo (x1, y1); + LineTo (x2, y2); + UnlockPixels (GetGWorldPixMap (p)); + } + /* Mac version of XClearArea. */ void *************** *** 486,499 **** SetRect (&r, x, y, x + bitmap->bounds.right, y + bitmap->bounds.bottom); #if TARGET_API_MAC_CARBON ! { ! PixMapHandle pmh; ! ! LockPortBits (GetWindowPort (w)); ! pmh = GetPortPixMap (GetWindowPort (w)); ! CopyBits (bitmap, (BitMap *) *pmh, &(bitmap->bounds), &r, srcCopy, 0); ! UnlockPortBits (GetWindowPort (w)); ! } #else /* not TARGET_API_MAC_CARBON */ CopyBits (bitmap, &(w->portBits), &(bitmap->bounds), &r, srcCopy, 0); #endif /* not TARGET_API_MAC_CARBON */ --- 479,488 ---- SetRect (&r, x, y, x + bitmap->bounds.right, y + bitmap->bounds.bottom); #if TARGET_API_MAC_CARBON ! LockPortBits (GetWindowPort (w)); ! CopyBits (bitmap, GetPortBitMapForCopyBits (GetWindowPort (w)), ! &(bitmap->bounds), &r, srcCopy, 0); ! UnlockPortBits (GetWindowPort (w)); #else /* not TARGET_API_MAC_CARBON */ CopyBits (bitmap, &(w->portBits), &(bitmap->bounds), &r, srcCopy, 0); #endif /* not TARGET_API_MAC_CARBON */ *************** *** 538,543 **** --- 527,549 ---- } + /* XBM bits seem to be backward within bytes compared with how + Mac does things. */ + static unsigned char + reflect_byte (orig) + unsigned char orig; + { + int i; + unsigned char reflected = 0x00; + for (i = 0; i < 8; i++) + { + if (orig & (0x01 << i)) + reflected |= 0x80 >> i; + } + return reflected; + } + + /* Mac replacement for XCreateBitmapFromBitmapData. */ static void *************** *** 546,568 **** char *bits; int w, h; { ! int bytes_per_row, i, j; ! bitmap->rowBytes = (w + 15) / 16 * 2; /* must be on word boundary */ bitmap->baseAddr = xmalloc (bitmap->rowBytes * h); - if (!bitmap->baseAddr) - abort (); - bzero (bitmap->baseAddr, bitmap->rowBytes * h); for (i = 0; i < h; i++) ! for (j = 0; j < w; j++) ! if (BitTst (bits, i * w + j)) ! BitSet (bitmap->baseAddr, i * bitmap->rowBytes * 8 + j); SetRect (&(bitmap->bounds), 0, 0, w, h); } static void mac_free_bitmap (bitmap) BitMap *bitmap; --- 552,634 ---- char *bits; int w, h; { ! int i, j, w1; ! char *p; ! w1 = (w + 7) / 8; /* nb of 8bits elt in X bitmap */ ! bitmap->rowBytes = ((w + 15) / 16) * 2; /* nb of 16bits elt in Mac bitmap */ bitmap->baseAddr = xmalloc (bitmap->rowBytes * h); bzero (bitmap->baseAddr, bitmap->rowBytes * h); for (i = 0; i < h; i++) ! { ! p = bitmap->baseAddr + i * bitmap->rowBytes; ! for (j = 0; j < w1; j++) ! *p++ = reflect_byte (*bits++); ! } SetRect (&(bitmap->bounds), 0, 0, w, h); } + Pixmap + XCreatePixmap (display, w, width, height, depth) + Display *display; /* not used */ + WindowPtr w; + unsigned int width, height; + unsigned int depth; /* not used */ + { + Pixmap pixmap; + Rect r; + QDErr err; + + #if TARGET_API_MAC_CARBON + SetPort (GetWindowPort (w)); + #else + SetPort (w); + #endif + + SetRect (&r, 0, 0, width, height); + err = NewGWorld (&pixmap, depth, &r, NULL, NULL, 0); + if (err != noErr) + return NULL; + return pixmap; + } + + + Pixmap + XCreatePixmapFromBitmapData (display, w, data, width, height, fg, bg, depth) + Display *display; /* not used */ + WindowPtr w; + char *data; + unsigned int width, height; + unsigned long fg, bg; + unsigned int depth; /* not used */ + { + Pixmap pixmap; + BitMap bitmap; + + pixmap = XCreatePixmap (display, w, width, height, depth); + if (pixmap == NULL) + return NULL; + + SetGWorld (pixmap, NULL); + mac_create_bitmap_from_bitmap_data (&bitmap, data, width, height); + mac_set_forecolor (fg); + mac_set_backcolor (bg); + LockPixels (GetGWorldPixMap (pixmap)); + #if TARGET_API_MAC_CARBON + CopyBits (&bitmap, GetPortBitMapForCopyBits (pixmap), + &bitmap.bounds, &bitmap.bounds, srcCopy, 0); + #else /* not TARGET_API_MAC_CARBON */ + CopyBits (&bitmap, &(((GrafPtr)pixmap)->portBits), + &bitmap.bounds, &bitmap.bounds, srcCopy, 0); + #endif /* not TARGET_API_MAC_CARBON */ + UnlockPixels (GetGWorldPixMap (pixmap)); + + return pixmap; + } + + static void mac_free_bitmap (bitmap) BitMap *bitmap; *************** *** 595,600 **** --- 661,686 ---- } + static void + mac_fill_rectangle_to_pixmap (display, p, gc, x, y, width, height) + Display *display; + Pixmap p; + GC gc; + int x, y; + unsigned int width, height; + { + Rect r; + + SetGWorld (p, NULL); + mac_set_colors (gc); + SetRect (&r, x, y, x + width, y + height); + + LockPixels (GetGWorldPixMap (p)); + PaintRect (&r); /* using foreground color of gc */ + UnlockPixels (GetGWorldPixMap (p)); + } + + /* Mac replacement for XDrawRectangle: dest is a window. */ static void *************** *** 630,649 **** int x, y; unsigned int width, height; { - #if 0 /* MAC_TODO: draw a rectangle in a PixMap */ Rect r; ! #if TARGET_API_MAC_CARBON ! SetPort (GetWindowPort (w)); ! #else ! SetPort (w); ! #endif ! mac_set_colors (gc); ! SetRect (&r, x, y, x + width, y + height); FrameRect (&r); /* using foreground color of gc */ ! #endif /* 0 */ } --- 716,730 ---- int x, y; unsigned int width, height; { Rect r; ! SetGWorld (p, NULL); mac_set_colors (gc); ! SetRect (&r, x, y, x + width + 1, y + height + 1); + LockPixels (GetGWorldPixMap (p)); FrameRect (&r); /* using foreground color of gc */ ! UnlockPixels (GetGWorldPixMap (p)); } *************** *** 758,780 **** SetPort (dest); #endif - mac_set_colors (gc); - SetRect (&src_r, src_x, src_y, src_x + width, src_y + height); SetRect (&dest_r, dest_x, dest_y, dest_x + width, dest_y + height); #if TARGET_API_MAC_CARBON ! { ! PixMapHandle pmh; ! LockPortBits (GetWindowPort (dest)); ! pmh = GetPortPixMap (GetWindowPort (dest)); ! CopyBits ((BitMap *) &src, (BitMap *) *pmh, &src_r, &dest_r, srcCopy, 0); ! UnlockPortBits (GetWindowPort (dest)); ! } #else /* not TARGET_API_MAC_CARBON */ ! CopyBits ((BitMap *) &src, &(dest->portBits), &src_r, &dest_r, srcCopy, 0); #endif /* not TARGET_API_MAC_CARBON */ } --- 839,904 ---- SetPort (dest); #endif SetRect (&src_r, src_x, src_y, src_x + width, src_y + height); SetRect (&dest_r, dest_x, dest_y, dest_x + width, dest_y + height); + ForeColor (blackColor); + BackColor (whiteColor); + + LockPixels (GetGWorldPixMap (src)); #if TARGET_API_MAC_CARBON ! LockPortBits (GetWindowPort (dest)); ! CopyBits (GetPortBitMapForCopyBits (src), ! GetPortBitMapForCopyBits (GetWindowPort (dest)), ! &src_r, &dest_r, srcCopy, 0); ! UnlockPortBits (GetWindowPort (dest)); ! #else /* not TARGET_API_MAC_CARBON */ ! CopyBits (&(((GrafPtr)src)->portBits), &(dest->portBits), ! &src_r, &dest_r, srcCopy, 0); ! #endif /* not TARGET_API_MAC_CARBON */ ! UnlockPixels (GetGWorldPixMap (src)); ! } ! ! static void ! mac_copy_area_with_mask (display, src, mask, dest, gc, src_x, src_y, ! width, height, dest_x, dest_y) ! Display *display; ! Pixmap src, mask; ! WindowPtr dest; ! GC gc; ! int src_x, src_y; ! unsigned int width, height; ! int dest_x, dest_y; ! { ! Rect src_r, dest_r; ! ! #if TARGET_API_MAC_CARBON ! SetPort (GetWindowPort (dest)); ! #else ! SetPort (dest); ! #endif ! ! SetRect (&src_r, src_x, src_y, src_x + width, src_y + height); ! SetRect (&dest_r, dest_x, dest_y, dest_x + width, dest_y + height); ! ! ForeColor (blackColor); ! BackColor (whiteColor); ! ! LockPixels (GetGWorldPixMap (src)); ! LockPixels (GetGWorldPixMap (mask)); ! #if TARGET_API_MAC_CARBON ! LockPortBits (GetWindowPort (dest)); ! CopyMask (GetPortBitMapForCopyBits (src), GetPortBitMapForCopyBits (mask), ! GetPortBitMapForCopyBits (GetWindowPort (dest)), ! &src_r, &src_r, &dest_r); ! UnlockPortBits (GetWindowPort (dest)); #else /* not TARGET_API_MAC_CARBON */ ! CopyMask (&(((GrafPtr)src)->portBits), &(((GrafPtr)mask)->portBits), ! &(dest->portBits), &src_r, &src_r, &dest_r); #endif /* not TARGET_API_MAC_CARBON */ + UnlockPixels (GetGWorldPixMap (mask)); + UnlockPixels (GetGWorldPixMap (src)); } *************** *** 809,815 **** { #if TARGET_API_MAC_CARBON Rect gw_r, src_r, dest_r; - PixMapHandle pmh; SetRect (&src_r, src_x, src_y, src_x + width, src_y + height); SetRect (&dest_r, dest_x, dest_y, dest_x + width, dest_y + height); --- 933,938 ---- *************** *** 820,827 **** BackColor (whiteColor); LockPortBits (GetWindowPort (w)); ! pmh = GetPortPixMap (GetWindowPort (w)); ! CopyBits ((BitMap *) *pmh, (BitMap *) *pmh, &src_r, &dest_r, srcCopy, 0); UnlockPortBits (GetWindowPort (w)); mac_set_colors (gc); --- 943,952 ---- BackColor (whiteColor); LockPortBits (GetWindowPort (w)); ! { ! const BitMap *bitmap = GetPortBitMapForCopyBits (GetWindowPort (w)); ! CopyBits (bitmap, bitmap, &src_r, &dest_r, srcCopy, 0); ! } UnlockPortBits (GetWindowPort (w)); mac_set_colors (gc); *************** *** 864,888 **** mac_copy_area_to_pixmap (display, src, dest, gc, src_x, src_y, width, height, dest_x, dest_y) Display *display; ! Pixmap src; ! Pixmap dest; GC gc; int src_x, src_y; unsigned int width, height; int dest_x, dest_y; { Rect src_r, dest_r; - int src_right = ((PixMap *) src)->bounds.right; - int src_bottom = ((PixMap *) src)->bounds.bottom; - int w = src_right - src_x; - int h = src_bottom - src_y; ! mac_set_colors (gc); ! SetRect (&src_r, src_x, src_y, src_right, src_bottom); ! SetRect (&dest_r, dest_x, dest_y, dest_x + w, dest_y + h); ! CopyBits ((BitMap *) &src, (BitMap *) &dest, &src_r, &dest_r, srcCopy, 0); } --- 989,1055 ---- mac_copy_area_to_pixmap (display, src, dest, gc, src_x, src_y, width, height, dest_x, dest_y) Display *display; ! Pixmap src, dest; GC gc; int src_x, src_y; unsigned int width, height; int dest_x, dest_y; { Rect src_r, dest_r; ! SetGWorld (dest, NULL); ! ForeColor (blackColor); ! BackColor (whiteColor); ! SetRect (&src_r, src_x, src_y, src_x + width, src_y + height); ! SetRect (&dest_r, dest_x, dest_y, dest_x + width, dest_y + height); ! ! LockPixels (GetGWorldPixMap (src)); ! LockPixels (GetGWorldPixMap (dest)); ! #if TARGET_API_MAC_CARBON ! CopyBits (GetPortBitMapForCopyBits (src), GetPortBitMapForCopyBits (dest), ! &src_r, &dest_r, srcCopy, 0); ! #else /* not TARGET_API_MAC_CARBON */ ! CopyBits (&(((GrafPtr)src)->portBits), &(((GrafPtr)dest)->portBits), ! &src_r, &dest_r, srcCopy, 0); ! #endif /* not TARGET_API_MAC_CARBON */ ! UnlockPixels (GetGWorldPixMap (dest)); ! UnlockPixels (GetGWorldPixMap (src)); ! } ! ! ! static void ! mac_copy_area_with_mask_to_pixmap (display, src, mask, dest, gc, src_x, src_y, ! width, height, dest_x, dest_y) ! Display *display; ! Pixmap src, mask, dest; ! GC gc; ! int src_x, src_y; ! unsigned int width, height; ! int dest_x, dest_y; ! { ! Rect src_r, dest_r; ! ! SetGWorld (dest, NULL); ! ForeColor (blackColor); ! BackColor (whiteColor); ! ! SetRect (&src_r, src_x, src_y, src_x + width, src_y + height); ! SetRect (&dest_r, dest_x, dest_y, dest_x + width, dest_y + height); ! LockPixels (GetGWorldPixMap (src)); ! LockPixels (GetGWorldPixMap (mask)); ! LockPixels (GetGWorldPixMap (dest)); ! #if TARGET_API_MAC_CARBON ! CopyMask (GetPortBitMapForCopyBits (src), GetPortBitMapForCopyBits (mask), ! GetPortBitMapForCopyBits (dest), &src_r, &src_r, &dest_r); ! #else /* not TARGET_API_MAC_CARBON */ ! CopyMask (&(((GrafPtr)src)->portBits), &(((GrafPtr)mask)->portBits), ! &(((GrafPtr)dest)->portBits), &src_r, &src_r, &dest_r); ! #endif /* not TARGET_API_MAC_CARBON */ ! UnlockPixels (GetGWorldPixMap (dest)); ! UnlockPixels (GetGWorldPixMap (mask)); ! UnlockPixels (GetGWorldPixMap (src)); } *************** *** 939,945 **** /* Mac replacement for XSetForeground. */ ! static void XSetForeground (display, gc, color) Display *display; GC gc; --- 1106,1112 ---- /* Mac replacement for XSetForeground. */ ! void XSetForeground (display, gc, color) Display *display; GC gc; *************** *** 2117,2122 **** --- 2284,2304 ---- #endif /* MAC_TODO */ + + /* Brightness beyond which a color won't have its highlight brightness + boosted. + + Nominally, highlight colors for `3d' faces are calculated by + brightening an object's color by a constant scale factor, but this + doesn't yield good results for dark colors, so for colors who's + brightness is less than this value (on a scale of 0-255) have to + use an additional additive factor. + + The value here is set so that the default menu-bar/mode-line color + (grey75) will not have its highlights changed at all. */ + #define HIGHLIGHT_COLOR_DARK_BOOST_LIMIT 187 + + /* Allocate a color which is lighter or darker than *COLOR by FACTOR or DELTA. Try a color with RGB values multiplied by FACTOR first. If this produces the same color as COLOR, try a color where all RGB *************** *** 2132,2143 **** --- 2314,2355 ---- int delta; { unsigned long new; + long bright; + + /* On Mac, RGB values are 0-255, not 0-65535, so scale delta. */ + delta /= 256; /* Change RGB values by specified FACTOR. Avoid overflow! */ xassert (factor >= 0); new = RGB_TO_ULONG (min (0xff, (int) (factor * RED_FROM_ULONG (*color))), min (0xff, (int) (factor * GREEN_FROM_ULONG (*color))), min (0xff, (int) (factor * BLUE_FROM_ULONG (*color)))); + + /* Calculate brightness of COLOR. */ + bright = (2 * RED_FROM_ULONG (*color) + 3 * GREEN_FROM_ULONG (*color) + + BLUE_FROM_ULONG (*color)) / 6; + + /* We only boost colors that are darker than + HIGHLIGHT_COLOR_DARK_BOOST_LIMIT. */ + if (bright < HIGHLIGHT_COLOR_DARK_BOOST_LIMIT) + /* Make an additive adjustment to NEW, because it's dark enough so + that scaling by FACTOR alone isn't enough. */ + { + /* How far below the limit this color is (0 - 1, 1 being darker). */ + double dimness = 1 - (double)bright / HIGHLIGHT_COLOR_DARK_BOOST_LIMIT; + /* The additive adjustment. */ + int min_delta = delta * dimness * factor / 2; + + if (factor < 1) + new = RGB_TO_ULONG (max (0, min (0xff, (int) (RED_FROM_ULONG (*color)) - min_delta)), + max (0, min (0xff, (int) (GREEN_FROM_ULONG (*color)) - min_delta)), + max (0, min (0xff, (int) (BLUE_FROM_ULONG (*color)) - min_delta))); + else + new = RGB_TO_ULONG (max (0, min (0xff, (int) (min_delta + RED_FROM_ULONG (*color)))), + max (0, min (0xff, (int) (min_delta + GREEN_FROM_ULONG (*color)))), + max (0, min (0xff, (int) (min_delta + BLUE_FROM_ULONG (*color))))); + } + if (new == *color) new = RGB_TO_ULONG (max (0, min (0xff, (int) (delta + RED_FROM_ULONG (*color)))), max (0, min (0xff, (int) (delta + GREEN_FROM_ULONG (*color)))), *************** *** 2182,2188 **** /* Allocate new color. */ xgcv.foreground = default_pixel; pixel = background; ! if (mac_alloc_lighter_color (f, &pixel, factor, delta)) { relief->allocated_p = 1; xgcv.foreground = relief->pixel = pixel; --- 2394,2401 ---- /* Allocate new color. */ xgcv.foreground = default_pixel; pixel = background; ! if (dpyinfo->n_planes != 1 ! && mac_alloc_lighter_color (f, &pixel, factor, delta)) { relief->allocated_p = 1; xgcv.foreground = relief->pixel = pixel; *************** *** 2212,2217 **** --- 2425,2434 ---- if (s->face->use_box_color_for_shadows_p) color = s->face->box_color; + else if (s->first_glyph->type == IMAGE_GLYPH + && s->img->pixmap + && !IMAGE_BACKGROUND_TRANSPARENT (s->img, s->f, 0)) + color = IMAGE_BACKGROUND (s->img, s->f, 0); else { XGCValues xgcv; *************** *** 2245,2253 **** x_draw_relief_rect (f, left_x, top_y, right_x, bottom_y, width, raised_p, left_p, right_p, clip_rect) struct frame *f; ! int left_x, top_y, right_x, bottom_y, left_p, right_p, raised_p; Rect *clip_rect; { int i; GC gc; --- 2462,2472 ---- x_draw_relief_rect (f, left_x, top_y, right_x, bottom_y, width, raised_p, left_p, right_p, clip_rect) struct frame *f; ! int left_x, top_y, right_x, bottom_y, width, left_p, right_p, raised_p; Rect *clip_rect; { + Display *dpy = FRAME_MAC_DISPLAY (f); + Window window = FRAME_MAC_WINDOW (f); int i; GC gc; *************** *** 2255,2295 **** gc = f->output_data.mac->white_relief.gc; else gc = f->output_data.mac->black_relief.gc; ! mac_set_clip_rectangle (FRAME_MAC_DISPLAY (f), FRAME_MAC_WINDOW (f), clip_rect); /* Top. */ for (i = 0; i < width; ++i) ! XDrawLine (FRAME_MAC_DISPLAY (f), FRAME_MAC_WINDOW (f), gc, left_x + i * left_p, top_y + i, ! right_x + 1 - i * right_p, top_y + i); /* Left. */ if (left_p) for (i = 0; i < width; ++i) ! XDrawLine (FRAME_MAC_DISPLAY (f), FRAME_MAC_WINDOW (f), gc, left_x + i, top_y + i, left_x + i, bottom_y - i); ! mac_reset_clipping (FRAME_MAC_DISPLAY (f), FRAME_MAC_WINDOW (f)); if (raised_p) gc = f->output_data.mac->black_relief.gc; else gc = f->output_data.mac->white_relief.gc; ! mac_set_clip_rectangle (FRAME_MAC_DISPLAY (f), FRAME_MAC_WINDOW (f), clip_rect); /* Bottom. */ for (i = 0; i < width; ++i) ! XDrawLine (FRAME_MAC_DISPLAY (f), FRAME_MAC_WINDOW (f), gc, left_x + i * left_p, bottom_y - i, ! right_x + 1 - i * right_p, bottom_y - i); /* Right. */ if (right_p) for (i = 0; i < width; ++i) ! XDrawLine (FRAME_MAC_DISPLAY (f), FRAME_MAC_WINDOW (f), gc, ! right_x - i, top_y + i + 1, right_x - i, bottom_y - i); ! mac_reset_clipping (FRAME_MAC_DISPLAY (f), FRAME_MAC_WINDOW (f)); } --- 2474,2514 ---- gc = f->output_data.mac->white_relief.gc; else gc = f->output_data.mac->black_relief.gc; ! mac_set_clip_rectangle (dpy, window, clip_rect); /* Top. */ for (i = 0; i < width; ++i) ! XDrawLine (dpy, window, gc, left_x + i * left_p, top_y + i, ! right_x - i * right_p, top_y + i); /* Left. */ if (left_p) for (i = 0; i < width; ++i) ! XDrawLine (dpy, window, gc, left_x + i, top_y + i, left_x + i, bottom_y - i); ! mac_reset_clipping (dpy, window); if (raised_p) gc = f->output_data.mac->black_relief.gc; else gc = f->output_data.mac->white_relief.gc; ! mac_set_clip_rectangle (dpy, window, clip_rect); /* Bottom. */ for (i = 0; i < width; ++i) ! XDrawLine (dpy, window, gc, left_x + i * left_p, bottom_y - i, ! right_x - i * right_p, bottom_y - i); /* Right. */ if (right_p) for (i = 0; i < width; ++i) ! XDrawLine (dpy, window, gc, ! right_x - i, top_y + i + 1, right_x - i, bottom_y - i - 1); ! mac_reset_clipping (dpy, window); } *************** *** 2304,2310 **** x_draw_box_rect (s, left_x, top_y, right_x, bottom_y, width, left_p, right_p, clip_rect) struct glyph_string *s; ! int left_x, top_y, right_x, bottom_y, left_p, right_p; Rect *clip_rect; { XGCValues xgcv; --- 2523,2529 ---- x_draw_box_rect (s, left_x, top_y, right_x, bottom_y, width, left_p, right_p, clip_rect) struct glyph_string *s; ! int left_x, top_y, right_x, bottom_y, width, left_p, right_p; Rect *clip_rect; { XGCValues xgcv; *************** *** 2314,2334 **** /* Top. */ XFillRectangle (s->display, s->window, &xgcv, ! left_x, top_y, right_x - left_x, width); /* Left. */ if (left_p) XFillRectangle (s->display, s->window, &xgcv, ! left_x, top_y, width, bottom_y - top_y); /* Bottom. */ XFillRectangle (s->display, s->window, &xgcv, ! left_x, bottom_y - width, right_x - left_x, width); /* Right. */ if (right_p) XFillRectangle (s->display, s->window, &xgcv, ! right_x - width, top_y, width, bottom_y - top_y); mac_reset_clipping (s->display, s->window); } --- 2533,2553 ---- /* Top. */ XFillRectangle (s->display, s->window, &xgcv, ! left_x, top_y, right_x - left_x + 1, width); /* Left. */ if (left_p) XFillRectangle (s->display, s->window, &xgcv, ! left_x, top_y, width, bottom_y - top_y + 1); /* Bottom. */ XFillRectangle (s->display, s->window, &xgcv, ! left_x, bottom_y - width + 1, right_x - left_x + 1, width); /* Right. */ if (right_p) XFillRectangle (s->display, s->window, &xgcv, ! right_x - width + 1, top_y, width, bottom_y - top_y + 1); mac_reset_clipping (s->display, s->window); } *************** *** 2363,2371 **** width = abs (s->face->box_line_width); raised_p = s->face->box == FACE_RAISED_BOX; left_x = s->x; ! right_x = ((s->row->full_width_p && s->extends_to_end_of_line_p ! ? last_x - 1 ! : min (last_x, s->x + s->background_width) - 1)); top_y = s->y; bottom_y = top_y + s->height - 1; --- 2582,2590 ---- width = abs (s->face->box_line_width); raised_p = s->face->box == FACE_RAISED_BOX; left_x = s->x; ! right_x = (s->row->full_width_p && s->extends_to_end_of_line_p ! ? last_x - 1 ! : min (last_x, s->x + s->background_width) - 1); top_y = s->y; bottom_y = top_y + s->height - 1; *************** *** 2416,2454 **** if (s->img->pixmap) { - #if 0 /* MAC_TODO: image mask */ if (s->img->mask) { ! /* We can't set both a clip mask and use XSetClipRectangles ! because the latter also sets a clip mask. We also can't ! trust on the shape extension to be available ! (XShapeCombineRegion). So, compute the rectangle to draw ! manually. */ ! unsigned long mask = (GCClipMask | GCClipXOrigin | GCClipYOrigin ! | GCFunction); ! XGCValues xgcv; XRectangle clip_rect, image_rect, r; ! xgcv.clip_mask = s->img->mask; ! xgcv.clip_x_origin = x; ! xgcv.clip_y_origin = y; ! xgcv.function = GXcopy; ! XChangeGC (s->display, s->gc, mask, &xgcv); ! ! get_glyph_string_clip_rect (s, &clip_rect); image_rect.x = x; image_rect.y = y; image_rect.width = s->img->width; image_rect.height = s->img->height; if (x_intersect_rectangles (&clip_rect, &image_rect, &r)) ! XCopyArea (s->display, s->img->pixmap, s->window, s->gc, ! r.x - x, r.y - y, r.width, r.height, r.x, r.y); } else - #endif /* MAC_TODO */ { ! mac_copy_area (s->display, s->img->pixmap, s->window, s->gc, ! 0, 0, s->img->width, s->img->height, x, y); /* When the image has a mask, we can expect that at least part of a mouse highlight or a block cursor will --- 2635,2670 ---- if (s->img->pixmap) { if (s->img->mask) { ! Rect nr; XRectangle clip_rect, image_rect, r; ! get_glyph_string_clip_rect (s, &nr); ! CONVERT_TO_XRECT (clip_rect, nr); image_rect.x = x; image_rect.y = y; image_rect.width = s->img->width; image_rect.height = s->img->height; if (x_intersect_rectangles (&clip_rect, &image_rect, &r)) ! mac_copy_area_with_mask (s->display, s->img->pixmap, s->img->mask, ! s->window, s->gc, r.x - x, r.y - y, ! r.width, r.height, r.x, r.y); } else { ! Rect nr; ! XRectangle clip_rect, image_rect, r; ! ! get_glyph_string_clip_rect (s, &nr); ! CONVERT_TO_XRECT (clip_rect, nr); ! image_rect.x = x; ! image_rect.y = y; ! image_rect.width = s->img->width; ! image_rect.height = s->img->height; ! if (x_intersect_rectangles (&clip_rect, &image_rect, &r)) ! mac_copy_area (s->display, s->img->pixmap, s->window, s->gc, ! r.x - x, r.y - y, r.width, r.height, r.x, r.y); /* When the image has a mask, we can expect that at least part of a mouse highlight or a block cursor will *************** *** 2472,2478 **** } - /* Draw a relief around the image glyph string S. */ static void --- 2688,2693 ---- *************** *** 2545,2574 **** if (s->img->pixmap) { - #if 0 /* MAC_TODO: image mask */ if (s->img->mask) ! { ! /* We can't set both a clip mask and use XSetClipRectangles ! because the latter also sets a clip mask. We also can't ! trust on the shape extension to be available ! (XShapeCombineRegion). So, compute the rectangle to draw ! manually. */ ! unsigned long mask = (GCClipMask | GCClipXOrigin | GCClipYOrigin ! | GCFunction); ! XGCValues xgcv; ! ! xgcv.clip_mask = s->img->mask; ! xgcv.clip_x_origin = x; ! xgcv.clip_y_origin = y; ! xgcv.function = GXcopy; ! XChangeGC (s->display, s->gc, mask, &xgcv); ! ! XCopyArea (s->display, s->img->pixmap, pixmap, s->gc, ! 0, 0, s->img->width, s->img->height, x, y); ! XSetClipMask (s->display, s->gc, None); ! } else - #endif /* MAC_TODO */ { mac_copy_area_to_pixmap (s->display, s->img->pixmap, pixmap, s->gc, 0, 0, s->img->width, s->img->height, x, y); --- 2760,2771 ---- if (s->img->pixmap) { if (s->img->mask) ! mac_copy_area_with_mask_to_pixmap (s->display, s->img->pixmap, ! s->img->mask, pixmap, s->gc, ! 0, 0, s->img->width, s->img->height, ! x, y); else { mac_copy_area_to_pixmap (s->display, s->img->pixmap, pixmap, s->gc, 0, 0, s->img->width, s->img->height, x, y); *************** *** 2583,2597 **** { int r = s->img->relief; if (r < 0) r = -r; ! mac_draw_rectangle_to_pixmap (s->display, pixmap, s->gc, x - r, y - r, ! s->img->width + r*2 - 1, s->img->height + r*2 - 1); } } } else /* Draw a rectangle if image could not be loaded. */ mac_draw_rectangle_to_pixmap (s->display, pixmap, s->gc, x, y, ! s->img->width - 1, s->img->height - 1); } --- 2780,2795 ---- { int r = s->img->relief; if (r < 0) r = -r; ! mac_draw_rectangle (s->display, s->window, s->gc, x - r, y - r, ! s->img->width + r*2 - 1, ! s->img->height + r*2 - 1); } } } else /* Draw a rectangle if image could not be loaded. */ mac_draw_rectangle_to_pixmap (s->display, pixmap, s->gc, x, y, ! s->img->width - 1, s->img->height - 1); } *************** *** 2624,2630 **** | s->face->box | | +------------------------- ! | | s->img->vmargin | | | | +------------------- | | | the image --- 2822,2828 ---- | s->face->box | | +------------------------- ! | | s->img->margin | | | | +------------------- | | | the image *************** *** 2643,2648 **** --- 2841,2847 ---- height = s->height - 2 * box_line_vwidth; + /* Fill background with face under the image. Do it only if row is taller than image or if image has a clip mask to reduce flickering. */ *************** *** 2650,2658 **** if (height > s->img->height || s->img->hmargin || s->img->vmargin - #if 0 /* TODO: image mask */ || s->img->mask - #endif || s->img->pixmap == 0 || s->width != s->background_width) { --- 2849,2855 ---- *************** *** 2662,2686 **** x = s->x; y = s->y + box_line_vwidth; ! #if 0 /* TODO: image mask */ if (s->img->mask) { /* Create a pixmap as large as the glyph string. Fill it with the background color. Copy the image to it, using its mask. Copy the temporary pixmap to the display. */ ! Screen *screen = FRAME_X_SCREEN (s->f); ! int depth = DefaultDepthOfScreen (screen); /* Create a pixmap as large as the glyph string. */ pixmap = XCreatePixmap (s->display, s->window, s->background_width, s->height, depth); - /* Don't clip in the following because we're working on the - pixmap. */ - XSetClipMask (s->display, s->gc, None); - /* Fill the pixmap with the background color/stipple. */ if (s->stippled_p) { /* Fill background with a stipple pattern. */ --- 2859,2879 ---- x = s->x; y = s->y + box_line_vwidth; ! if (s->img->mask) { /* Create a pixmap as large as the glyph string. Fill it with the background color. Copy the image to it, using its mask. Copy the temporary pixmap to the display. */ ! int depth = one_mac_display_info.n_planes; /* Create a pixmap as large as the glyph string. */ pixmap = XCreatePixmap (s->display, s->window, s->background_width, s->height, depth); /* Fill the pixmap with the background color/stipple. */ + #if 0 /* TODO: stipple */ if (s->stippled_p) { /* Fill background with a stipple pattern. */ *************** *** 2690,2707 **** XSetFillStyle (s->display, s->gc, FillSolid); } else { XGCValues xgcv; XGetGCValues (s->display, s->gc, GCForeground | GCBackground, &xgcv); XSetForeground (s->display, s->gc, xgcv.background); ! XFillRectangle (s->display, pixmap, s->gc, ! 0, 0, s->background_width, s->height); XSetForeground (s->display, s->gc, xgcv.foreground); } } else - #endif x_draw_glyph_string_bg_rect (s, x, y, s->background_width, height); s->background_filled_p = 1; --- 2883,2901 ---- XSetFillStyle (s->display, s->gc, FillSolid); } else + #endif { XGCValues xgcv; XGetGCValues (s->display, s->gc, GCForeground | GCBackground, &xgcv); XSetForeground (s->display, s->gc, xgcv.background); ! mac_fill_rectangle_to_pixmap (s->display, pixmap, s->gc, ! 0, 0, s->background_width, ! s->height); XSetForeground (s->display, s->gc, xgcv.foreground); } } else x_draw_glyph_string_bg_rect (s, x, y, s->background_width, height); s->background_filled_p = 1; *************** *** 2713,2719 **** x_draw_image_foreground_1 (s, pixmap); x_set_glyph_string_clipping (s); mac_copy_area (s->display, pixmap, s->window, s->gc, ! 0, 0, s->background_width, s->height, s->x, s->y); mac_reset_clipping (s->display, s->window); XFreePixmap (s->display, pixmap); } --- 2907,2913 ---- x_draw_image_foreground_1 (s, pixmap); x_set_glyph_string_clipping (s); mac_copy_area (s->display, pixmap, s->window, s->gc, ! 0, 0, s->background_width, s->height, s->x, s->y); mac_reset_clipping (s->display, s->window); XFreePixmap (s->display, pixmap); } *************** *** 2750,2759 **** /* Clear rest using the GC of the original non-cursor face. */ if (width < s->background_width) { - GC gc = s->face->gc; int x = s->x + width, y = s->y; int w = s->background_width - width, h = s->height; Rect r; if (s->row->mouse_face_p && cursor_in_mouse_face_p (s->w)) --- 2944,2953 ---- /* Clear rest using the GC of the original non-cursor face. */ if (width < s->background_width) { int x = s->x + width, y = s->y; int w = s->background_width - width, h = s->height; Rect r; + GC gc; if (s->row->mouse_face_p && cursor_in_mouse_face_p (s->w)) *************** *** 2813,2819 **** x_set_glyph_string_gc (s->next); x_set_glyph_string_clipping (s->next); x_draw_glyph_string_background (s->next, 1); - } /* Set up S->gc, set clipping and draw S. */ --- 3007,3012 ---- *************** *** 2850,2856 **** if (s->for_overlaps_p) s->background_filled_p = 1; else ! x_draw_glyph_string_background (s, 0); x_draw_glyph_string_foreground (s); break; --- 3043,3049 ---- if (s->for_overlaps_p) s->background_filled_p = 1; else ! x_draw_glyph_string_background (s, 0); x_draw_glyph_string_foreground (s); break; *************** *** 2927,2935 **** } } ! /* Draw relief. */ if (!relief_drawn_p && s->face->box != FACE_NO_BOX) ! x_draw_glyph_string_box (s); } /* Reset clipping. */ --- 3120,3128 ---- } } ! /* Draw relief if not yet drawn. */ if (!relief_drawn_p && s->face->box != FACE_NO_BOX) ! x_draw_glyph_string_box (s); } /* Reset clipping. */ *************** *** 2949,2955 **** x + shift_by, y); } - /* Delete N glyphs at the nominal cursor position. Not implemented for X frames. */ --- 3142,3147 ---- *************** *** 3004,3009 **** --- 3196,3202 ---- #if defined (HAVE_TIMEVAL) && defined (HAVE_SELECT) + /* Subtract the `struct timeval' values X and Y, storing the result in *RESULT. Return 1 if the difference is negative, otherwise 0. */ *************** *** 3107,3113 **** This, and those operations, are used only within an update that is bounded by calls to x_update_begin and x_update_end. */ ! void XTset_terminal_window (n) register int n; { --- 3300,3306 ---- This, and those operations, are used only within an update that is bounded by calls to x_update_begin and x_update_end. */ ! static void XTset_terminal_window (n) register int n; { *************** *** 3143,3149 **** /* Get frame-relative bounding box of the text display area of W, without mode lines. Include in this box the left and right ! fringes of W. */ window_box (w, -1, &x, &y, &width, &height); from_y = WINDOW_TO_FRAME_PIXEL_Y (w, run->current_y); --- 3336,3342 ---- /* Get frame-relative bounding box of the text display area of W, without mode lines. Include in this box the left and right ! fringe of W. */ window_box (w, -1, &x, &y, &width, &height); from_y = WINDOW_TO_FRAME_PIXEL_Y (w, run->current_y); *************** *** 3265,3272 **** XTframe_rehighlight (frame) struct frame *frame; { - - x_frame_rehighlight (FRAME_X_DISPLAY_INFO (frame)); } --- 3458,3463 ---- *************** *** 4407,4419 **** struct glyph *cursor_glyph; GC gc; - /* Compute frame-relative coordinates from window-relative - coordinates. */ - x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x); - y = (WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y) - + row->ascent - w->phys_cursor_ascent); - h = row->height - 1; - /* Get the glyph the cursor is on. If we can't tell because the current matrix is invalid or such, give up. */ cursor_glyph = get_phys_cursor_glyph (w); --- 4598,4603 ---- *************** *** 4428,4433 **** --- 4612,4631 ---- if (cursor_glyph->type == STRETCH_GLYPH && !x_stretch_cursor_p) wd = min (FRAME_COLUMN_WIDTH (f), wd); + w->phys_cursor_width = wd; + + /* Compute frame-relative coordinates from window-relative + coordinates. */ + x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x); + y = WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y); + + /* Compute the proper height and ascent of the rectangle, based + on the actual glyph. Using the full height of the row looks + bad when there are tall images on that row. */ + h = max (FRAME_LINE_HEIGHT (f), cursor_glyph->ascent + cursor_glyph->descent); + if (h < row->height) + y += row->ascent /* - w->phys_cursor_ascent */ + cursor_glyph->descent - h; + h--; /* The foreground of cursor_gc is typically the same as the normal background color, which can cause the cursor box to be invisible. */ *************** *** 4454,4488 **** --gerd. */ static void ! x_draw_bar_cursor (w, row, width) struct window *w; struct glyph_row *row; int width; { ! /* If cursor hpos is out of bounds, don't draw garbage. This can ! happen in mini-buffer windows when switching between echo area ! glyphs and mini-buffer. */ ! if (w->phys_cursor.hpos < row->used[TEXT_AREA]) ! { ! struct frame *f = XFRAME (w->frame); ! struct glyph *cursor_glyph; ! GC gc; ! int x; ! unsigned long mask; ! XGCValues xgcv; ! Display *dpy; ! Window window; ! cursor_glyph = get_phys_cursor_glyph (w); ! if (cursor_glyph == NULL) ! return; ! xgcv.background = f->output_data.mac->cursor_pixel; ! xgcv.foreground = f->output_data.mac->cursor_pixel; ! mask = GCForeground | GCBackground; ! dpy = FRAME_MAC_DISPLAY (f); ! window = FRAME_MAC_WINDOW (f); ! gc = FRAME_X_DISPLAY_INFO (f)->scratch_cursor_gc; if (gc) XChangeGC (dpy, gc, mask, &xgcv); --- 4652,4700 ---- --gerd. */ static void ! x_draw_bar_cursor (w, row, width, kind) struct window *w; struct glyph_row *row; int width; + enum text_cursor_kinds kind; { ! struct frame *f = XFRAME (w->frame); ! struct glyph *cursor_glyph; ! /* If cursor is out of bounds, don't draw garbage. This can happen ! in mini-buffer windows when switching between echo area glyphs ! and mini-buffer. */ ! cursor_glyph = get_phys_cursor_glyph (w); ! if (cursor_glyph == NULL) ! return; ! /* If on an image, draw like a normal cursor. That's usually better ! visible than drawing a bar, esp. if the image is large so that ! the bar might not be in the window. */ ! if (cursor_glyph->type == IMAGE_GLYPH) ! { ! struct glyph_row *row; ! row = MATRIX_ROW (w->current_matrix, w->phys_cursor.vpos); ! draw_phys_cursor_glyph (w, row, DRAW_CURSOR); ! } ! else ! { ! Display *dpy = FRAME_MAC_DISPLAY (f); ! Window window = FRAME_MAC_WINDOW (f); ! GC gc = FRAME_MAC_DISPLAY_INFO (f)->scratch_cursor_gc; ! unsigned long mask = GCForeground | GCBackground; ! struct face *face = FACE_FROM_ID (f, cursor_glyph->face_id); ! XGCValues xgcv; ! ! /* If the glyph's background equals the color we normally draw ! the bar cursor in, the bar cursor in its normal color is ! invisible. Use the glyph's foreground color instead in this ! case, on the assumption that the glyph's colors are chosen so ! that the glyph is legible. */ ! if (face->background == f->output_data.mac->cursor_pixel) ! xgcv.background = xgcv.foreground = face->foreground; ! else ! xgcv.background = xgcv.foreground = f->output_data.mac->cursor_pixel; if (gc) XChangeGC (dpy, gc, mask, &xgcv); *************** *** 4494,4507 **** if (width < 0) width = FRAME_CURSOR_WIDTH (f); ! x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x); x_clip_to_row (w, row, gc); ! XFillRectangle (dpy, window, gc, ! x, ! WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y), ! min (cursor_glyph->pixel_width, width), ! row->height); mac_reset_clipping (dpy, FRAME_MAC_WINDOW (f)); } } --- 4706,4729 ---- if (width < 0) width = FRAME_CURSOR_WIDTH (f); + width = min (cursor_glyph->pixel_width, width); ! w->phys_cursor_width = width; x_clip_to_row (w, row, gc); ! ! if (kind == BAR_CURSOR) ! XFillRectangle (dpy, window, gc, ! WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x), ! WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y), ! width, row->height); ! else ! XFillRectangle (dpy, window, gc, ! WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x), ! WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y + ! row->height - width), ! cursor_glyph->pixel_width, ! width); ! mac_reset_clipping (dpy, FRAME_MAC_WINDOW (f)); } } *************** *** 4556,4565 **** draw_phys_cursor_glyph (w, glyph_row, DRAW_CURSOR); break; - case HBAR_CURSOR: - /* TODO. For now, just draw bar cursor. */ case BAR_CURSOR: ! x_draw_bar_cursor (w, glyph_row, cursor_width); break; case NO_CURSOR: --- 4778,4789 ---- draw_phys_cursor_glyph (w, glyph_row, DRAW_CURSOR); break; case BAR_CURSOR: ! x_draw_bar_cursor (w, glyph_row, cursor_width, BAR_CURSOR); ! break; ! ! case HBAR_CURSOR: ! x_draw_bar_cursor (w, glyph_row, cursor_width, HBAR_CURSOR); break; case NO_CURSOR: *************** *** 5087,5092 **** --- 5311,5318 ---- FRAME_SAMPLE_VISIBILITY (f); } } + #else + UNBLOCK_INPUT; #endif /* MAC_TODO */ } *************** *** 5448,5453 **** --- 5674,5680 ---- int font_name_table_size = 0; int font_name_count = 0; + #if 0 /* compare two strings ignoring case */ static int stricmp (const char *s, const char *t) *************** *** 5527,5532 **** --- 5754,5799 ---- && wildstrieq (m_charset, x_charset)) || mac_font_pattern_match (mf, xf); } + #endif + + static Lisp_Object Qbig5, Qcn_gb, Qsjis, Qeuc_kr; + + static void + decode_mac_font_name (char *name, int size, short scriptcode) + { + Lisp_Object coding_system; + struct coding_system coding; + char *buf; + + switch (scriptcode) + { + case smTradChinese: + coding_system = Qbig5; + break; + case smSimpChinese: + coding_system = Qcn_gb; + break; + case smJapanese: + coding_system = Qsjis; + break; + case smKorean: + coding_system = Qeuc_kr; + break; + default: + return; + } + + setup_coding_system (coding_system, &coding); + coding.src_multibyte = 0; + coding.dst_multibyte = 1; + coding.mode |= CODING_MODE_LAST_BLOCK; + coding.composing = COMPOSITION_DISABLED; + buf = (char *) alloca (size); + + decode_coding (&coding, name, buf, strlen (name), size - 1); + bcopy (buf, name, coding.produced); + name[coding.produced] = '\0'; + } static char * *************** *** 5592,5597 **** --- 5859,5866 ---- x_font_name_to_mac_font_name (char *xf, char *mf) { char foundry[32], family[32], weight[20], slant[2], cs[32]; + Lisp_Object coding_system = Qnil; + struct coding_system coding; strcpy (mf, ""); *************** *** 5601,5613 **** foundry, family, weight, slant, cs) != 5) return; ! if (strcmp (cs, "big5-0") == 0 || strcmp (cs, "gb2312.1980-0") == 0 ! || strcmp (cs, "jisx0208.1983-sjis") == 0 ! || strcmp (cs, "jisx0201.1976-0") == 0 ! || strcmp (cs, "ksc5601.1989-0") == 0 || strcmp (cs, "mac-roman") == 0) ! strcpy(mf, family); ! else ! sprintf(mf, "%s-%s-%s", foundry, family, cs); } --- 5870,5898 ---- foundry, family, weight, slant, cs) != 5) return; ! if (strcmp (cs, "big5-0") == 0) ! coding_system = Qbig5; ! else if (strcmp (cs, "gb2312.1980-0") == 0) ! coding_system = Qcn_gb; ! else if (strcmp (cs, "jisx0208.1983-sjis") == 0 ! || strcmp (cs, "jisx0201.1976-0") == 0) ! coding_system = Qsjis; ! else if (strcmp (cs, "ksc5601.1989-0") == 0) ! coding_system = Qeuc_kr; ! else if (strcmp (cs, "mac-roman") == 0) ! strcpy (mf, family); ! else ! sprintf (mf, "%s-%s-%s", foundry, family, cs); ! ! if (!NILP (coding_system)) ! { ! setup_coding_system (coding_system, &coding); ! coding.src_multibyte = 1; ! coding.dst_multibyte = 1; ! coding.mode |= CODING_MODE_LAST_BLOCK; ! encode_coding (&coding, family, mf, strlen (family), sizeof (Str32) - 1); ! mf[coding.produced] = '\0'; ! } } *************** *** 5671,5706 **** if (FMGetFontFamilyName (ff, name) != noErr) break; p2cstr (name); sc = FontToScript (ff); /* Point the instance iterator at the current font family. */ ! if (FMResetFontFamilyInstanceIterator(ff, &ffii) != noErr) break; while (FMGetNextFontFamilyInstance (&ffii, &font, &style, &size) == noErr) ! if (size == 0) ! { ! add_font_name_table_entry (mac_to_x_fontname (name, size, ! style, sc)); ! add_font_name_table_entry (mac_to_x_fontname (name, size, ! italic, sc)); ! add_font_name_table_entry (mac_to_x_fontname (name, size, ! bold, sc)); ! add_font_name_table_entry (mac_to_x_fontname (name, size, ! italic | bold, ! sc)); ! } ! else ! { add_font_name_table_entry (mac_to_x_fontname (name, size, style, sc)); ! if (smJapanese == sc) ! add_font_name_table_entry (mac_to_x_fontname (name, size, ! style, ! -smJapanese)); ! } } /* Dispose of the iterators. */ --- 5956,6000 ---- if (FMGetFontFamilyName (ff, name) != noErr) break; p2cstr (name); + if (*name == '.') + continue; sc = FontToScript (ff); + decode_mac_font_name (name, sizeof (name), sc); /* Point the instance iterator at the current font family. */ ! if (FMResetFontFamilyInstanceIterator (ff, &ffii) != noErr) break; while (FMGetNextFontFamilyInstance (&ffii, &font, &style, &size) == noErr) ! { ! /* Both jisx0208.1983-sjis and jisx0201.1976-0 parts are ! contained in Apple Japanese (SJIS) font. */ ! again: ! if (size == 0) ! { ! add_font_name_table_entry (mac_to_x_fontname (name, size, ! style, sc)); ! add_font_name_table_entry (mac_to_x_fontname (name, size, ! italic, sc)); ! add_font_name_table_entry (mac_to_x_fontname (name, size, ! bold, sc)); ! add_font_name_table_entry (mac_to_x_fontname (name, size, ! italic | bold, ! sc)); ! } ! else add_font_name_table_entry (mac_to_x_fontname (name, size, style, sc)); ! if (sc == smJapanese) ! { ! sc = -smJapanese; ! goto again; ! } ! else if (sc == -smJapanese) ! sc = smJapanese; ! } } /* Dispose of the iterators. */ *************** *** 5742,5747 **** --- 6036,6042 ---- TextFont (fontnum); scriptcode = FontToScript (fontnum); + decode_mac_font_name (name, sizeof (name), scriptcode); do { HLock (font_handle); *************** *** 5776,5784 **** assc_entry->fontSize, assc_entry->fontStyle, scriptcode); ! /* Both jisx0208.1983-sjis and ! jisx0201.1976-sjis parts are contained in ! Apple Japanese (SJIS) font. */ if (smJapanese == scriptcode) { font_name_table[font_name_count++] --- 6071,6079 ---- assc_entry->fontSize, assc_entry->fontStyle, scriptcode); ! /* Both jisx0208.1983-sjis and jisx0201.1976-0 ! parts are contained in Apple Japanese (SJIS) ! font. */ if (smJapanese == scriptcode) { font_name_table[font_name_count++] *************** *** 5805,5810 **** --- 6100,6151 ---- } + static Lisp_Object + mac_do_list_fonts (pattern, maxnames) + char *pattern; + int maxnames; + { + int i, n_fonts = 0; + Lisp_Object font_list = Qnil, pattern_regex, fontname; + char *regex = (char *) alloca (strlen (pattern) * 2 + 3); + char *ptr; + + ptr = regex; + *ptr++ = '^'; + + /* Turn pattern into a regexp and do a regexp match. */ + for (; *pattern; pattern++) + { + if (*pattern == '?') + *ptr++ = '.'; + else if (*pattern == '*') + { + *ptr++ = '.'; + *ptr++ = '*'; + } + else + *ptr++ = tolower (*pattern); + } + *ptr = '$'; + *(ptr + 1) = '\0'; + + pattern_regex = build_string (regex); + + for (i = 0; i < font_name_count; i++) + { + fontname = build_string (font_name_table[i]); + if (fast_string_match (pattern_regex, fontname) >= 0) + { + font_list = Fcons (fontname, font_list); + + n_fonts++; + if (maxnames> 0 && n_fonts >= maxnames) + break; + } + } + return font_list; + } + /* Return a list of at most MAXNAMES font specs matching the one in PATTERN. Cache matching fonts for patterns in dpyinfo->name_list_element to avoid looking them up again by *************** *** 5817,5823 **** int size, int maxnames) { - char *ptnstr; Lisp_Object newlist = Qnil, tem, key; int n_fonts = 0; int i; --- 6158,6163 ---- *************** *** 5840,5866 **** } } ! ptnstr = SDATA (pattern); ! ! GCPRO2 (pattern, newlist); ! ! /* Scan and matching bitmap fonts. */ ! for (i = 0; i < font_name_count; i++) ! { ! if (mac_font_pattern_match (font_name_table[i], ptnstr)) ! { ! newlist = Fcons (build_string (font_name_table[i]), newlist); ! ! n_fonts++; ! if (maxnames > 0 && n_fonts >= maxnames) ! break; ! } ! } /* MAC_TODO: add code for matching outline fonts here */ - UNGCPRO; - if (dpyinfo) { XSETCDR (dpyinfo->name_list_element, --- 6180,6189 ---- } } ! newlist = mac_do_list_fonts (SDATA (pattern), maxnames); /* MAC_TODO: add code for matching outline fonts here */ if (dpyinfo) { XSETCDR (dpyinfo->name_list_element, *************** *** 6020,6033 **** name = fontname; else { ! for (i = 0; i < font_name_count; i++) ! if (mac_font_pattern_match (font_name_table[i], fontname)) ! break; ! if (i >= font_name_count) ! return NULL; ! ! name = font_name_table[i]; } GetPort (&port); /* save the current font number used */ --- 6343,6354 ---- name = fontname; else { ! Lisp_Object matched_fonts; ! matched_fonts = mac_do_list_fonts (fontname, 1); ! if (NILP (matched_fonts)) ! return NULL; ! name = SDATA (XCAR (matched_fonts)); } GetPort (&port); /* save the current font number used */ *************** *** 6149,6155 **** for (c = 0x20; c <= 0xff; c++) { font->per_char[c - 0x20] = font->max_bounds; ! font->per_char[c - 0x20].width = CharWidth (c); } } } --- 6470,6477 ---- for (c = 0x20; c <= 0xff; c++) { font->per_char[c - 0x20] = font->max_bounds; ! font->per_char[c - 0x20].width = ! font->per_char[c - 0x20].rbearing = CharWidth (c); } } } *************** *** 6475,6483 **** --- 6797,6807 ---- static pascal OSErr do_ae_open_documents (AppleEvent *, AppleEvent *, long); static pascal OSErr do_ae_quit_application (AppleEvent *, AppleEvent *, long); + #if TARGET_API_MAC_CARBON /* Drag and Drop */ static OSErr init_mac_drag_n_drop (); static pascal OSErr mac_do_receive_drag (WindowPtr, void*, DragReference); + #endif #if USE_CARBON_EVENTS /* Preliminary Support for the OSX Services Menu */ *************** *** 7022,7027 **** --- 7346,7352 ---- SetPort (save_port); } + #if TARGET_API_MAC_CARBON /* Initialize Drag And Drop to allow files to be dropped onto emacs frames */ static OSErr init_mac_drag_n_drop () *************** *** 7029,7034 **** --- 7354,7360 ---- OSErr result = InstallReceiveHandler (mac_do_receive_drag, 0L, NULL); return result; } + #endif /* Intialize AppleEvent dispatcher table for the required events. */ void *************** *** 7295,7300 **** --- 7621,7627 ---- } + #if TARGET_API_MAC_CARBON static pascal OSErr mac_do_receive_drag (WindowPtr window, void *handlerRefCon, DragReference theDrag) *************** *** 7371,7376 **** --- 7698,7704 ---- } } } + #endif /* Print Document Apple Event */ *************** *** 7768,7781 **** } else { ! bufp->kind = MOUSE_CLICK_EVENT; XSETFRAME (bufp->frame_or_window, mwp->mFP); if (er.what == mouseDown) ! mouse_tracking_in_progress = mouse_tracking_mouse_movement; else ! mouse_tracking_in_progress = mouse_tracking_none; ! } #if USE_CARBON_EVENTS bufp->modifiers = mac_event_to_emacs_modifiers (eventRef); --- 8096,8127 ---- } else { ! Lisp_Object window; ! ! bufp->kind = MOUSE_CLICK_EVENT; XSETFRAME (bufp->frame_or_window, mwp->mFP); if (er.what == mouseDown) ! mouse_tracking_in_progress = mouse_tracking_mouse_movement; else ! mouse_tracking_in_progress = mouse_tracking_none; ! window = window_from_coordinates (mwp->mFP, bufp->x, bufp->y, 0, 0, 0, 1); ! ! if (EQ (window, mwp->mFP->tool_bar_window)) ! { ! if (er.what == mouseDown) ! handle_tool_bar_click (mwp->mFP, bufp->x, bufp->y, 1, 0); ! else ! handle_tool_bar_click (mwp->mFP, bufp->x, bufp->y, 0, ! #if USE_CARBON_EVENTS ! mac_event_to_emacs_modifiers (eventRef) ! #else ! er.modifiers ! #endif ! ); ! break; ! } ! } #if USE_CARBON_EVENTS bufp->modifiers = mac_event_to_emacs_modifiers (eventRef); *************** *** 7875,7886 **** --- 8221,8234 ---- } #endif + #if TARGET_API_MAC_CARBON if (!IsValidWindowPtr (FrontNonFloatingWindow ())) { SysBeep (1); UNBLOCK_INPUT; return 0; } + #endif ObscureCursor (); *************** *** 7973,7980 **** #endif { ! mac_output *mwp ! = (mac_output *) GetWRefCon (FrontNonFloatingWindow ()); XSETFRAME (bufp->frame_or_window, mwp->mFP); } --- 8321,8332 ---- #endif { ! mac_output *mwp = ! #if TARGET_API_MAC_CARBON ! (mac_output *) GetWRefCon (FrontNonFloatingWindow ()); ! #else ! (mac_output *) GetWRefCon (FrontWindow ()); ! #endif XSETFRAME (bufp->frame_or_window, mwp->mFP); } *************** *** 7996,8001 **** --- 8348,8354 ---- WindowPtr wp; Lisp_Object frame; + #if TARGET_API_MAC_CARBON wp = FrontNonFloatingWindow (); if (!wp) *************** *** 8004,8011 **** CollapseWindow (FRAME_MAC_WINDOW (f), false); wp = FrontNonFloatingWindow (); } ! if (wp && is_emacs_window(wp)) f = ((mac_output *) GetWRefCon (wp))->mFP; bufp->kind = DRAG_N_DROP_EVENT; --- 8357,8367 ---- CollapseWindow (FRAME_MAC_WINDOW (f), false); wp = FrontNonFloatingWindow (); } + #else + wp = FrontWindow (); + #endif ! if (wp && is_emacs_window (wp)) f = ((mac_output *) GetWRefCon (wp))->mFP; bufp->kind = DRAG_N_DROP_EVENT; *************** *** 8287,8298 **** dpyinfo->reference_count = 0; dpyinfo->resx = 75.0; dpyinfo->resy = 75.0; ! dpyinfo->n_planes = 1; ! dpyinfo->n_cbits = 16; dpyinfo->height = (**main_device_handle).gdRect.bottom; dpyinfo->width = (**main_device_handle).gdRect.right; dpyinfo->grabbed = 0; dpyinfo->root_window = NULL; dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1; dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1; --- 8643,8658 ---- dpyinfo->reference_count = 0; dpyinfo->resx = 75.0; dpyinfo->resy = 75.0; ! dpyinfo->color_p = TestDeviceAttribute (main_device_handle, gdDevType); ! for (dpyinfo->n_planes = 32; dpyinfo->n_planes > 0; dpyinfo->n_planes >>= 1) ! if (HasDepth (main_device_handle, dpyinfo->n_planes, ! gdDevType, dpyinfo->color_p)) ! break; dpyinfo->height = (**main_device_handle).gdRect.bottom; dpyinfo->width = (**main_device_handle).gdRect.right; dpyinfo->grabbed = 0; dpyinfo->root_window = NULL; + dpyinfo->image_cache = make_image_cache (); dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1; dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1; *************** *** 8625,8630 **** --- 8985,9002 ---- Qmac_ready_for_drag_n_drop = intern ("mac-ready-for-drag-n-drop"); staticpro (&Qmac_ready_for_drag_n_drop); + + Qbig5 = intern ("big5"); + staticpro (&Qbig5); + + Qcn_gb = intern ("cn-gb"); + staticpro (&Qcn_gb); + + Qsjis = intern ("sjis"); + staticpro (&Qsjis); + + Qeuc_kr = intern ("euc-kr"); + staticpro (&Qeuc_kr); DEFVAR_BOOL ("x-autoselect-window", &x_autoselect_window_p, doc: /* *Non-nil means autoselect window with mouse pointer. */); *** src/macterm.h.~1.10.~ Tue Sep 2 09:10:04 2003 --- src/macterm.h Thu Jan 8 10:10:08 2004 *************** *** 23,67 **** #include "macgui.h" #include "frame.h" - /* Include Carbon.h to define Cursor and Rect. */ - #ifdef HAVE_CARBON - #undef mktime - #undef DEBUG - #undef Z - #undef free - #undef malloc - #undef realloc - /* Macros max and min defined in lisp.h conflict with those in - precompiled header Carbon.h. */ - #undef max - #undef min - #undef init_process - #include - #undef Z - #define Z (current_buffer->text->z) - #undef free - #define free unexec_free - #undef malloc - #define malloc unexec_malloc - #undef realloc - #define realloc unexec_realloc - #undef min - #define min(a, b) ((a) < (b) ? (a) : (b)) - #undef max - #define max(a, b) ((a) > (b) ? (a) : (b)) - #undef init_process - #define init_process emacs_init_process - #endif /* MAC_OSX */ - #define RGB_TO_ULONG(r, g, b) (((r) << 16) | ((g) << 8) | (b)) #define RED_FROM_ULONG(color) ((color) >> 16) #define GREEN_FROM_ULONG(color) (((color) >> 8) & 0xff) #define BLUE_FROM_ULONG(color) ((color) & 0xff) #define BLACK_PIX_DEFAULT(f) RGB_TO_ULONG(0,0,0) #define WHITE_PIX_DEFAULT(f) RGB_TO_ULONG(255,255,255) #define FONT_WIDTH(f) ((f)->max_bounds.width) #define FONT_HEIGHT(f) ((f)->ascent + (f)->descent) #define FONT_BASE(f) ((f)->ascent) --- 23,48 ---- #include "macgui.h" #include "frame.h" #define RGB_TO_ULONG(r, g, b) (((r) << 16) | ((g) << 8) | (b)) #define RED_FROM_ULONG(color) ((color) >> 16) #define GREEN_FROM_ULONG(color) (((color) >> 8) & 0xff) #define BLUE_FROM_ULONG(color) ((color) & 0xff) + /* Do not change `* 0x101' in the following lines to `<< 8'. If + changed, image masks in 1-bit depth will not work. */ + #define RED16_FROM_ULONG(color) (RED_FROM_ULONG(color) * 0x101) + #define GREEN16_FROM_ULONG(color) (GREEN_FROM_ULONG(color) * 0x101) + #define BLUE16_FROM_ULONG(color) (BLUE_FROM_ULONG(color) * 0x101) + #define BLACK_PIX_DEFAULT(f) RGB_TO_ULONG(0,0,0) #define WHITE_PIX_DEFAULT(f) RGB_TO_ULONG(255,255,255) + /* A black pixel in a mask bitmap/pixmap means ``draw a source + pixel''. A white pixel means ``retain the current pixel''. */ + #define PIX_MASK_DRAW(f) BLACK_PIX_DEFAULT(f) + #define PIX_MASK_RETAIN(f) WHITE_PIX_DEFAULT(f) + #define FONT_WIDTH(f) ((f)->max_bounds.width) #define FONT_HEIGHT(f) ((f)->ascent + (f)->descent) #define FONT_BASE(f) ((f)->ascent) *************** *** 101,108 **** --- 82,94 ---- /* Number of planes on this screen. */ int n_planes; + /* Whether the screen supports color */ + int color_p; + + #if 0 /* Number of bits per pixel on this screen. */ int n_cbits; + #endif /* Dimensions of this screen. */ int height, width; *** src/xdisp.c.~1.857.~ Wed Jan 7 10:20:46 2004 --- src/xdisp.c Mon Jan 12 18:46:46 2004 *************** *** 20147,20153 **** cursor = FRAME_X_OUTPUT (f)->nontext_cursor; } ! #ifndef HAVE_CARBON if (cursor != No_Cursor) #else if (bcmp (&cursor, &No_Cursor, sizeof (Cursor))) --- 20147,20153 ---- cursor = FRAME_X_OUTPUT (f)->nontext_cursor; } ! #ifndef MAC_OS if (cursor != No_Cursor) #else if (bcmp (&cursor, &No_Cursor, sizeof (Cursor))) *************** *** 21135,21141 **** } } ! #ifdef HAVE_CARBON /* Display scroll bar for this window. */ if (!NILP (w->vertical_scroll_bar)) { --- 21135,21141 ---- } } ! #ifdef MAC_OS /* Display scroll bar for this window. */ if (!NILP (w->vertical_scroll_bar)) { *************** *** 21207,21213 **** return; } ! #ifdef HAVE_CARBON /* MAC_TODO: this is a kludge, but if scroll bars are not activated or deactivated here, for unknown reasons, activated scroll bars are shown in deactivated frames in some instances. */ --- 21207,21213 ---- return; } ! #ifdef MAC_OS /* MAC_TODO: this is a kludge, but if scroll bars are not activated or deactivated here, for unknown reasons, activated scroll bars are shown in deactivated frames in some instances. */ *** src/s/darwin.h.~1.13.~ Mon Oct 13 16:04:54 2003 --- src/s/darwin.h Sun Jan 4 21:03:19 2004 *************** *** 250,256 **** page) to leave room at the end of the header for adding load commands. Needed for dumping. 0x690 is the total size of 30 segment load commands (at 56 each). */ ! #define LD_SWITCH_SYSTEM_TEMACS -prebind -framework Carbon -lstdc++ -Xlinker -headerpad -Xlinker 690 #define C_SWITCH_SYSTEM_TEMACS -Dtemacs --- 250,256 ---- page) to leave room at the end of the header for adding load commands. Needed for dumping. 0x690 is the total size of 30 segment load commands (at 56 each). */ ! #define LD_SWITCH_SYSTEM_TEMACS -prebind -framework Carbon -framework QuickTime -lstdc++ -Xlinker -headerpad -Xlinker 690 #define C_SWITCH_SYSTEM_TEMACS -Dtemacs