X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/ea3ac1d302c2b7c3754a58127a32b9bb53588f80..49d395cd57e646162e7f646a8561a416abacac82:/src/macterm.c diff --git a/src/macterm.c b/src/macterm.c index 8439a79d65..472fe3d28c 100644 --- a/src/macterm.c +++ b/src/macterm.c @@ -269,14 +269,84 @@ extern void menubar_selection_callback (FRAME_PTR, int); #define GC_FORE_COLOR(gc) (&(gc)->fore_color) #define GC_BACK_COLOR(gc) (&(gc)->back_color) #define GC_FONT(gc) ((gc)->xgcv.font) -#define GC_CLIP_REGION(gc) ((gc)->clip_region) #define FRAME_NORMAL_GC(f) ((f)->output_data.mac->normal_gc) +#define CG_SET_FILL_COLOR(context, color) \ + CGContextSetRGBFillColor (context, \ + RED_FROM_ULONG (color) / 255.0f, \ + GREEN_FROM_ULONG (color) / 255.0f, \ + BLUE_FROM_ULONG (color) / 255.0f, 1.0f) +#define CG_SET_STROKE_COLOR(context, color) \ + CGContextSetRGBStrokeColor (context, \ + RED_FROM_ULONG (color) / 255.0f, \ + GREEN_FROM_ULONG (color) / 255.0f, \ + BLUE_FROM_ULONG (color) / 255.0f, 1.0f) +#if USE_CG_DRAWING +#define FRAME_CG_CONTEXT(f) ((f)->output_data.mac->cg_context) + +/* Fringe bitmaps. */ + +static int max_fringe_bmp = 0; +static CGImageRef *fringe_bmp = 0; + +static CGContextRef +mac_begin_cg_clip (f, gc) + struct frame *f; + GC gc; +{ + CGContextRef context = FRAME_CG_CONTEXT (f); + + if (!context) + { + QDBeginCGContext (GetWindowPort (FRAME_MAC_WINDOW (f)), &context); + FRAME_CG_CONTEXT (f) = context; + } + + CGContextSaveGState (context); + CGContextTranslateCTM (context, 0, FRAME_PIXEL_HEIGHT (f)); + CGContextScaleCTM (context, 1, -1); + if (gc && gc->n_clip_rects) + CGContextClipToRects (context, gc->clip_rects, gc->n_clip_rects); + + return context; +} + +static void +mac_end_cg_clip (f) + struct frame *f; +{ + CGContextRestoreGState (FRAME_CG_CONTEXT (f)); +} + +void +mac_prepare_for_quickdraw (f) + struct frame *f; +{ + if (f == NULL) + { + Lisp_Object rest, frame; + FOR_EACH_FRAME (rest, frame) + if (FRAME_MAC_P (XFRAME (frame))) + mac_prepare_for_quickdraw (XFRAME (frame)); + } + else + { + CGContextRef context = FRAME_CG_CONTEXT (f); + + if (context) + { + CGContextSynchronize (context); + QDEndCGContext (GetWindowPort (FRAME_MAC_WINDOW (f)), + &FRAME_CG_CONTEXT (f)); + } + } +} +#endif static RgnHandle saved_port_clip_region = NULL; static void -mac_begin_clip (region) - RgnHandle region; +mac_begin_clip (gc) + GC gc; { static RgnHandle new_region = NULL; @@ -285,19 +355,19 @@ mac_begin_clip (region) if (new_region == NULL) new_region = NewRgn (); - if (region) + if (gc->n_clip_rects) { GetClip (saved_port_clip_region); - SectRgn (saved_port_clip_region, region, new_region); + SectRgn (saved_port_clip_region, gc->clip_region, new_region); SetClip (new_region); } } static void -mac_end_clip (region) - RgnHandle region; +mac_end_clip (gc) + GC gc; { - if (region) + if (gc->n_clip_rects) SetClip (saved_port_clip_region); } @@ -321,14 +391,27 @@ mac_draw_line (f, gc, x1, y1, x2, y2) GC gc; int x1, y1, x2, y2; { +#if USE_CG_DRAWING + CGContextRef context; + + context = mac_begin_cg_clip (f, gc); + CG_SET_STROKE_COLOR (context, gc->xgcv.foreground); + CGContextBeginPath (context); + CGContextMoveToPoint (context, x1 + 0.5f, y1 + 0.5f); + CGContextAddLineToPoint (context, x2 + 0.5f, y2 + 0.5f); + CGContextClosePath (context); + CGContextStrokePath (context); + mac_end_cg_clip (f); +#else SetPortWindowPort (FRAME_MAC_WINDOW (f)); RGBForeColor (GC_FORE_COLOR (gc)); - mac_begin_clip (GC_CLIP_REGION (gc)); + mac_begin_clip (gc); MoveTo (x1, y1); LineTo (x2, y2); - mac_end_clip (GC_CLIP_REGION (gc)); + mac_end_clip (gc); +#endif } void @@ -362,6 +445,14 @@ mac_erase_rectangle (f, gc, x, y, width, height) int x, y; unsigned int width, height; { +#if USE_CG_DRAWING + CGContextRef context; + + context = mac_begin_cg_clip (f, gc); + CG_SET_FILL_COLOR (context, gc->xgcv.background); + CGContextFillRect (context, CGRectMake (x, y, width, height)); + mac_end_cg_clip (f); +#else Rect r; SetPortWindowPort (FRAME_MAC_WINDOW (f)); @@ -369,11 +460,12 @@ mac_erase_rectangle (f, gc, x, y, width, height) RGBBackColor (GC_BACK_COLOR (gc)); SetRect (&r, x, y, x + width, y + height); - mac_begin_clip (GC_CLIP_REGION (gc)); + mac_begin_clip (gc); EraseRect (&r); - mac_end_clip (GC_CLIP_REGION (gc)); + mac_end_clip (gc); RGBBackColor (GC_BACK_COLOR (FRAME_NORMAL_GC (f))); +#endif } @@ -394,6 +486,16 @@ static void mac_clear_window (f) struct frame *f; { +#if USE_CG_DRAWING + CGContextRef context; + GC gc = FRAME_NORMAL_GC (f); + + context = mac_begin_cg_clip (f, NULL); + CG_SET_FILL_COLOR (context, gc->xgcv.background); + CGContextFillRect (context, CGRectMake (0, 0, FRAME_PIXEL_WIDTH (f), + FRAME_PIXEL_HEIGHT (f))); + mac_end_cg_clip (f); +#else SetPortWindowPort (FRAME_MAC_WINDOW (f)); RGBBackColor (GC_BACK_COLOR (FRAME_NORMAL_GC (f))); @@ -408,11 +510,50 @@ mac_clear_window (f) #else /* not TARGET_API_MAC_CARBON */ EraseRect (&(FRAME_MAC_WINDOW (f)->portRect)); #endif /* not TARGET_API_MAC_CARBON */ +#endif } /* Mac replacement for XCopyArea. */ +#if USE_CG_DRAWING +static void +mac_draw_cg_image (image, f, gc, src_x, src_y, width, height, + dest_x, dest_y, overlay_p) + CGImageRef image; + struct frame *f; + GC gc; + int src_x, src_y; + unsigned int width, height; + int dest_x, dest_y, overlay_p; +{ + CGContextRef context; + float port_height = FRAME_PIXEL_HEIGHT (f); + CGRect dest_rect = CGRectMake (dest_x, dest_y, width, height); + + context = mac_begin_cg_clip (f, gc); + if (!overlay_p) + { + CG_SET_FILL_COLOR (context, gc->xgcv.background); + CGContextFillRect (context, dest_rect); + } + CGContextClipToRect (context, dest_rect); + CGContextScaleCTM (context, 1, -1); + CGContextTranslateCTM (context, 0, -port_height); + if (CGImageIsMask (image)) + CG_SET_FILL_COLOR (context, gc->xgcv.foreground); + CGContextDrawImage (context, + CGRectMake (dest_x - src_x, + port_height - (dest_y - src_y + + CGImageGetHeight (image)), + CGImageGetWidth (image), + CGImageGetHeight (image)), + image); + mac_end_cg_clip (f); +} + +#else /* !USE_CG_DRAWING */ + static void mac_draw_bitmap (f, gc, x, y, width, height, bits, overlay_p) struct frame *f; @@ -434,7 +575,7 @@ mac_draw_bitmap (f, gc, x, y, width, height, bits, overlay_p) RGBBackColor (GC_BACK_COLOR (gc)); SetRect (&r, x, y, x + width, y + height); - mac_begin_clip (GC_CLIP_REGION (gc)); + mac_begin_clip (gc); #if TARGET_API_MAC_CARBON { CGrafPtr port; @@ -449,10 +590,11 @@ mac_draw_bitmap (f, gc, x, y, width, height, bits, overlay_p) CopyBits (&bitmap, &(FRAME_MAC_WINDOW (f)->portBits), &(bitmap.bounds), &r, overlay_p ? srcOr : srcCopy, 0); #endif /* not TARGET_API_MAC_CARBON */ - mac_end_clip (GC_CLIP_REGION (gc)); + mac_end_clip (gc); RGBBackColor (GC_BACK_COLOR (FRAME_NORMAL_GC (f))); } +#endif /* !USE_CG_DRAWING */ /* Mac replacement for XCreateBitmapFromBitmapData. */ @@ -513,7 +655,15 @@ XCreatePixmap (display, w, width, height, depth) SetPortWindowPort (w); SetRect (&r, 0, 0, width, height); - err = NewGWorld (&pixmap, depth, &r, NULL, NULL, 0); +#if !defined (WORDS_BIG_ENDIAN) && USE_CG_DRAWING + if (depth == 1) +#endif + err = NewGWorld (&pixmap, depth, &r, NULL, NULL, 0); +#if !defined (WORDS_BIG_ENDIAN) && USE_CG_DRAWING + else + /* CreateCGImageFromPixMaps requires ARGB format. */ + err = QTNewGWorld (&pixmap, k32ARGBPixelFormat, &r, NULL, NULL, 0); +#endif if (err != noErr) return NULL; return pixmap; @@ -574,6 +724,14 @@ mac_fill_rectangle (f, gc, x, y, width, height) int x, y; unsigned int width, height; { +#if USE_CG_DRAWING + CGContextRef context; + + context = mac_begin_cg_clip (f, gc); + CG_SET_FILL_COLOR (context, gc->xgcv.foreground); + CGContextFillRect (context, CGRectMake (x, y, width, height)); + mac_end_cg_clip (f); +#else Rect r; SetPortWindowPort (FRAME_MAC_WINDOW (f)); @@ -581,9 +739,10 @@ mac_fill_rectangle (f, gc, x, y, width, height) RGBForeColor (GC_FORE_COLOR (gc)); SetRect (&r, x, y, x + width, y + height); - mac_begin_clip (GC_CLIP_REGION (gc)); + mac_begin_clip (gc); PaintRect (&r); /* using foreground color of gc */ - mac_end_clip (GC_CLIP_REGION (gc)); + mac_end_clip (gc); +#endif } @@ -596,6 +755,15 @@ mac_draw_rectangle (f, gc, x, y, width, height) int x, y; unsigned int width, height; { +#if USE_CG_DRAWING + CGContextRef context; + + context = mac_begin_cg_clip (f, gc); + CG_SET_STROKE_COLOR (context, gc->xgcv.foreground); + CGContextStrokeRect (context, + CGRectMake (x + 0.5f, y + 0.5f, width, height)); + mac_end_cg_clip (f); +#else Rect r; SetPortWindowPort (FRAME_MAC_WINDOW (f)); @@ -603,9 +771,10 @@ mac_draw_rectangle (f, gc, x, y, width, height) RGBForeColor (GC_FORE_COLOR (gc)); SetRect (&r, x, y, x + width + 1, y + height + 1); - mac_begin_clip (GC_CLIP_REGION (gc)); + mac_begin_clip (gc); FrameRect (&r); /* using foreground color of gc */ - mac_end_clip (GC_CLIP_REGION (gc)); + mac_end_clip (gc); +#endif } @@ -675,6 +844,9 @@ mac_invert_rectangle (f, x, y, width, height) { Rect r; +#if USE_CG_DRAWING + mac_prepare_for_quickdraw (f); +#endif SetPortWindowPort (FRAME_MAC_WINDOW (f)); SetRect (&r, x, y, x + width, y + height); @@ -684,27 +856,15 @@ mac_invert_rectangle (f, x, y, width, height) static void -mac_draw_string_common (f, gc, x, y, buf, nchars, mode, bytes_per_char) +mac_draw_string_common (f, gc, x, y, buf, nchars, bg_width, bytes_per_char) struct frame *f; GC gc; int x, y; char *buf; - int nchars, mode, bytes_per_char; + int nchars, bg_width, bytes_per_char; { -#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020 - UInt32 textFlags, savedFlags; - if (mac_use_core_graphics) { - textFlags = kQDUseCGTextRendering; - savedFlags = SwapQDTextFlags(textFlags); - } -#endif - SetPortWindowPort (FRAME_MAC_WINDOW (f)); - RGBForeColor (GC_FORE_COLOR (gc)); - if (mode != srcOr) - RGBBackColor (GC_BACK_COLOR (gc)); - #if USE_ATSUI if (GC_FONT (gc)->mac_style) { @@ -726,91 +886,151 @@ mac_draw_string_common (f, gc, x, y, buf, nchars, mode, bytes_per_char) nchars, GC_FONT (gc)->mac_style, &text_layout); - if (err == noErr) - { + if (err != noErr) + return; #ifdef MAC_OSX - if (!mac_use_core_graphics) - { + if (!mac_use_core_graphics) + { #endif - mac_begin_clip (GC_CLIP_REGION (gc)); - MoveTo (x, y); - ATSUDrawText (text_layout, - kATSUFromTextBeginning, kATSUToTextEnd, - kATSUUseGrafPortPenLoc, kATSUUseGrafPortPenLoc); - mac_end_clip (GC_CLIP_REGION (gc)); -#ifdef MAC_OSX +#if USE_CG_DRAWING + mac_prepare_for_quickdraw (f); +#endif + mac_begin_clip (gc); + RGBForeColor (GC_FORE_COLOR (gc)); + if (bg_width) + { + Rect r; + + SetRect (&r, x, y - FONT_BASE (GC_FONT (gc)), + x + bg_width, y + FONT_DESCENT (GC_FONT (gc))); + RGBBackColor (GC_BACK_COLOR (gc)); + EraseRect (&r); + RGBBackColor (GC_BACK_COLOR (FRAME_NORMAL_GC (f))); } - else + MoveTo (x, y); + ATSUDrawText (text_layout, + kATSUFromTextBeginning, kATSUToTextEnd, + kATSUUseGrafPortPenLoc, kATSUUseGrafPortPenLoc); + mac_end_clip (gc); +#ifdef MAC_OSX + } + else + { + CGrafPtr port; + CGContextRef context; + float port_height = FRAME_PIXEL_HEIGHT (f); + ATSUAttributeTag tags[] = {kATSUCGContextTag}; + ByteCount sizes[] = {sizeof (CGContextRef)}; + ATSUAttributeValuePtr values[] = {&context}; + +#if USE_CG_DRAWING + context = mac_begin_cg_clip (f, gc); +#else + GetPort (&port); + QDBeginCGContext (port, &context); + if (gc->n_clip_rects || bg_width) { - CGrafPtr port; - CGContextRef context; - float port_height = FRAME_PIXEL_HEIGHT (f); - ATSUAttributeTag tags[] = {kATSUCGContextTag}; - ByteCount sizes[] = {sizeof (CGContextRef)}; - ATSUAttributeValuePtr values[] = {&context}; - - GetPort (&port); - QDBeginCGContext (port, &context); + CGContextTranslateCTM (context, 0, port_height); + CGContextScaleCTM (context, 1, -1); if (gc->n_clip_rects) + CGContextClipToRects (context, gc->clip_rects, + gc->n_clip_rects); +#endif + if (bg_width) { - CGContextTranslateCTM (context, 0, port_height); - CGContextScaleCTM (context, 1, -1); - CGContextClipToRects (context, gc->clip_rects, - gc->n_clip_rects); - CGContextScaleCTM (context, 1, -1); - CGContextTranslateCTM (context, 0, -port_height); + CG_SET_FILL_COLOR (context, gc->xgcv.background); + CGContextFillRect + (context, + CGRectMake (x, y - FONT_BASE (GC_FONT (gc)), + bg_width, FONT_HEIGHT (GC_FONT (gc)))); } - CGContextSetRGBFillColor - (context, - RED_FROM_ULONG (gc->xgcv.foreground) / 255.0, - GREEN_FROM_ULONG (gc->xgcv.foreground) / 255.0, - BLUE_FROM_ULONG (gc->xgcv.foreground) / 255.0, - 1.0); - err = ATSUSetLayoutControls (text_layout, - sizeof (tags) / sizeof (tags[0]), - tags, sizes, values); - if (err == noErr) - ATSUDrawText (text_layout, - kATSUFromTextBeginning, kATSUToTextEnd, - Long2Fix (x), Long2Fix (port_height - y)); - CGContextSynchronize (context); - QDEndCGContext (port, &context); -#if 0 - /* This doesn't work on Mac OS X 10.1. */ - ATSUClearLayoutControls (text_layout, + CGContextScaleCTM (context, 1, -1); + CGContextTranslateCTM (context, 0, -port_height); +#if !USE_CG_DRAWING + } +#endif + CG_SET_FILL_COLOR (context, gc->xgcv.foreground); + err = ATSUSetLayoutControls (text_layout, sizeof (tags) / sizeof (tags[0]), - tags); + tags, sizes, values); + if (err == noErr) + ATSUDrawText (text_layout, + kATSUFromTextBeginning, kATSUToTextEnd, + Long2Fix (x), Long2Fix (port_height - y)); +#if USE_CG_DRAWING + mac_end_cg_clip (f); + context = NULL; #else - ATSUSetLayoutControls (text_layout, - sizeof (tags) / sizeof (tags[0]), - tags, sizes, values); + CGContextSynchronize (context); + QDEndCGContext (port, &context); #endif - } +#if 0 + /* This doesn't work on Mac OS X 10.1. */ + ATSUClearLayoutControls (text_layout, + sizeof (tags) / sizeof (tags[0]), tags); +#else + ATSUSetLayoutControls (text_layout, + sizeof (tags) / sizeof (tags[0]), + tags, sizes, values); #endif } +#endif /* MAC_OSX */ } else +#endif /* USE_ATSUI */ { +#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020 + UInt32 savedFlags; + + if (mac_use_core_graphics) + savedFlags = SwapQDTextFlags (kQDUseCGTextRendering); #endif - TextFont (GC_FONT (gc)->mac_fontnum); - TextSize (GC_FONT (gc)->mac_fontsize); - TextFace (GC_FONT (gc)->mac_fontface); - TextMode (mode); +#if USE_CG_DRAWING + mac_prepare_for_quickdraw (f); +#endif + mac_begin_clip (gc); + RGBForeColor (GC_FORE_COLOR (gc)); +#ifdef MAC_OS8 + if (bg_width) + { + RGBBackColor (GC_BACK_COLOR (gc)); + TextMode (srcCopy); + } + else + TextMode (srcOr); +#else + /* We prefer not to use srcCopy text transfer mode on Mac OS X + because: + - Screen is double-buffered. (In srcCopy mode, a text is + drawn into an offscreen graphics world first. So + performance gain cannot be expected.) + - It lowers rendering quality. + - Some fonts leave garbage on cursor movement. */ + if (bg_width) + { + Rect r; - mac_begin_clip (GC_CLIP_REGION (gc)); - MoveTo (x, y); - DrawText (buf, 0, nchars * bytes_per_char); - mac_end_clip (GC_CLIP_REGION (gc)); -#if USE_ATSUI - } + RGBBackColor (GC_BACK_COLOR (gc)); + SetRect (&r, x, y - FONT_BASE (GC_FONT (gc)), + x + bg_width, y + FONT_DESCENT (GC_FONT (gc))); + EraseRect (&r); + } + TextMode (srcOr); #endif + TextFont (GC_FONT (gc)->mac_fontnum); + TextSize (GC_FONT (gc)->mac_fontsize); + TextFace (GC_FONT (gc)->mac_fontface); + MoveTo (x, y); + DrawText (buf, 0, nchars * bytes_per_char); + if (bg_width) + RGBBackColor (GC_BACK_COLOR (FRAME_NORMAL_GC (f))); + mac_end_clip (gc); - if (mode != srcOr) - RGBBackColor (GC_BACK_COLOR (FRAME_NORMAL_GC (f))); #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020 - if (mac_use_core_graphics) - SwapQDTextFlags(savedFlags); + if (mac_use_core_graphics) + SwapQDTextFlags(savedFlags); #endif + } } @@ -824,7 +1044,7 @@ mac_draw_string (f, gc, x, y, buf, nchars) char *buf; int nchars; { - mac_draw_string_common (f, gc, x, y, buf, nchars, srcOr, 1); + mac_draw_string_common (f, gc, x, y, buf, nchars, 0, 1); } @@ -838,35 +1058,35 @@ mac_draw_string_16 (f, gc, x, y, buf, nchars) XChar2b *buf; int nchars; { - mac_draw_string_common (f, gc, x, y, (char *) buf, nchars, srcOr, 2); + mac_draw_string_common (f, gc, x, y, (char *) buf, nchars, 0, 2); } /* Mac replacement for XDrawImageString. */ static void -mac_draw_image_string (f, gc, x, y, buf, nchars) +mac_draw_image_string (f, gc, x, y, buf, nchars, bg_width) struct frame *f; GC gc; int x, y; char *buf; - int nchars; + int nchars, bg_width; { - mac_draw_string_common (f, gc, x, y, buf, nchars, srcCopy, 1); + mac_draw_string_common (f, gc, x, y, buf, nchars, bg_width, 1); } /* Mac replacement for XDrawString16. */ static void -mac_draw_image_string_16 (f, gc, x, y, buf, nchars) +mac_draw_image_string_16 (f, gc, x, y, buf, nchars, bg_width) struct frame *f; GC gc; int x, y; XChar2b *buf; - int nchars; + int nchars, bg_width; { - mac_draw_string_common (f, gc, x, y, (char *) buf, nchars, srcCopy, 2); + mac_draw_string_common (f, gc, x, y, (char *) buf, nchars, bg_width, 2); } @@ -1040,12 +1260,12 @@ init_cg_text_anti_aliasing_threshold () } static int -mac_draw_string_cg (f, gc, x, y, buf, nchars) +mac_draw_image_string_cg (f, gc, x, y, buf, nchars, bg_width) struct frame *f; GC gc; int x, y; XChar2b *buf; - int nchars; + int nchars, bg_width; { CGrafPtr port; float port_height, gx, gy; @@ -1062,7 +1282,9 @@ mac_draw_string_cg (f, gc, x, y, buf, nchars) gx = x; gy = port_height - y; glyphs = (CGGlyph *)buf; - advances = xmalloc (sizeof (CGSize) * nchars); + advances = alloca (sizeof (CGSize) * nchars); + if (advances == NULL) + return 0; for (i = 0; i < nchars; i++) { XCharStruct *pcm = mac_per_char_metric (GC_FONT (gc), buf, 0); @@ -1073,20 +1295,31 @@ mac_draw_string_cg (f, gc, x, y, buf, nchars) buf++; } +#if USE_CG_DRAWING + context = mac_begin_cg_clip (f, gc); +#else QDBeginCGContext (port, &context); - if (gc->n_clip_rects) + if (gc->n_clip_rects || bg_width) { CGContextTranslateCTM (context, 0, port_height); CGContextScaleCTM (context, 1, -1); - CGContextClipToRects (context, gc->clip_rects, gc->n_clip_rects); + if (gc->n_clip_rects) + CGContextClipToRects (context, gc->clip_rects, gc->n_clip_rects); +#endif + if (bg_width) + { + CG_SET_FILL_COLOR (context, gc->xgcv.background); + CGContextFillRect + (context, + CGRectMake (gx, y - FONT_BASE (GC_FONT (gc)), + bg_width, FONT_HEIGHT (GC_FONT (gc)))); + } CGContextScaleCTM (context, 1, -1); CGContextTranslateCTM (context, 0, -port_height); +#if !USE_CG_DRAWING } - CGContextSetRGBFillColor (context, - RED_FROM_ULONG (gc->xgcv.foreground) / 255.0, - GREEN_FROM_ULONG (gc->xgcv.foreground) / 255.0, - BLUE_FROM_ULONG (gc->xgcv.foreground) / 255.0, - 1.0); +#endif + CG_SET_FILL_COLOR (context, gc->xgcv.foreground); CGContextSetFont (context, GC_FONT (gc)->cg_font); CGContextSetFontSize (context, GC_FONT (gc)->mac_fontsize); if (GC_FONT (gc)->mac_fontsize <= cg_text_anti_aliasing_threshold) @@ -1101,16 +1334,19 @@ mac_draw_string_cg (f, gc, x, y, buf, nchars) gx += advances[i].width; } #endif +#if USE_CG_DRAWING + mac_end_cg_clip (f); +#else CGContextSynchronize (context); QDEndCGContext (port, &context); - - xfree (advances); +#endif return 1; } #endif +#if !USE_CG_DRAWING /* Mac replacement for XCopyArea: dest must be window. */ static void @@ -1132,7 +1368,7 @@ mac_copy_area (src, f, gc, src_x, src_y, width, height, dest_x, dest_y) ForeColor (blackColor); BackColor (whiteColor); - mac_begin_clip (GC_CLIP_REGION (gc)); + mac_begin_clip (gc); LockPixels (GetGWorldPixMap (src)); #if TARGET_API_MAC_CARBON { @@ -1150,7 +1386,7 @@ mac_copy_area (src, f, gc, src_x, src_y, width, height, dest_x, dest_y) &src_r, &dest_r, srcCopy, 0); #endif /* not TARGET_API_MAC_CARBON */ UnlockPixels (GetGWorldPixMap (src)); - mac_end_clip (GC_CLIP_REGION (gc)); + mac_end_clip (gc); RGBBackColor (GC_BACK_COLOR (FRAME_NORMAL_GC (f))); } @@ -1176,7 +1412,7 @@ mac_copy_area_with_mask (src, mask, f, gc, src_x, src_y, ForeColor (blackColor); BackColor (whiteColor); - mac_begin_clip (GC_CLIP_REGION (gc)); + mac_begin_clip (gc); LockPixels (GetGWorldPixMap (src)); LockPixels (GetGWorldPixMap (mask)); #if TARGET_API_MAC_CARBON @@ -1196,10 +1432,11 @@ mac_copy_area_with_mask (src, mask, f, gc, src_x, src_y, #endif /* not TARGET_API_MAC_CARBON */ UnlockPixels (GetGWorldPixMap (mask)); UnlockPixels (GetGWorldPixMap (src)); - mac_end_clip (GC_CLIP_REGION (gc)); + mac_end_clip (gc); RGBBackColor (GC_BACK_COLOR (FRAME_NORMAL_GC (f))); } +#endif /* !USE_CG_DRAWING */ /* Mac replacement for XCopyArea: used only for scrolling. */ @@ -1217,6 +1454,9 @@ mac_scroll_area (f, gc, src_x, src_y, width, height, dest_x, dest_y) RgnHandle dummy = NewRgn (); /* For avoiding update events. */ SetRect (&src_r, src_x, src_y, src_x + width, src_y + height); +#if USE_CG_DRAWING + mac_prepare_for_quickdraw (f); +#endif ScrollWindowRect (FRAME_MAC_WINDOW (f), &src_r, dest_x - src_x, dest_y - src_y, kScrollWindowNoOptions, dummy); @@ -1234,9 +1474,9 @@ mac_scroll_area (f, gc, src_x, src_y, width, height, dest_x, dest_y) color mapping in CopyBits. Otherwise, it will be slow. */ ForeColor (blackColor); BackColor (whiteColor); - mac_begin_clip (GC_CLIP_REGION (gc)); + mac_begin_clip (gc); CopyBits (&(w->portBits), &(w->portBits), &src_r, &dest_r, srcCopy, 0); - mac_end_clip (GC_CLIP_REGION (gc)); + mac_end_clip (gc); RGBBackColor (GC_BACK_COLOR (FRAME_NORMAL_GC (f))); #endif /* not TARGET_API_MAC_CARBON */ @@ -1372,17 +1612,10 @@ mac_set_clip_rectangles (display, gc, rectangles, n) { int i; - if (n < 0 || n > MAX_CLIP_RECTS) - abort (); - if (n == 0) - { - if (gc->clip_region) - { - DisposeRgn (gc->clip_region); - gc->clip_region = NULL; - } - } - else + xassert (n >= 0 && n <= MAX_CLIP_RECTS); + + gc->n_clip_rects = n; + if (n > 0) { if (gc->clip_region == NULL) gc->clip_region = NewRgn (); @@ -1400,8 +1633,6 @@ mac_set_clip_rectangles (display, gc, rectangles, n) } } #if defined (MAC_OSX) && USE_ATSUI - gc->n_clip_rects = n; - for (i = 0; i < n; i++) { Rect *rect = rectangles + i; @@ -1421,7 +1652,7 @@ mac_reset_clip_rectangles (display, gc) Display *display; GC gc; { - mac_set_clip_rectangles (display, gc, NULL, 0); + gc->n_clip_rects = 0; } @@ -1484,6 +1715,9 @@ x_flush (f) { #if TARGET_API_MAC_CARBON BLOCK_INPUT; +#if USE_CG_DRAWING + mac_prepare_for_quickdraw (f); +#endif if (f) QDFlushPortBuffer (GetWindowPort (FRAME_MAC_WINDOW (f)), NULL); else @@ -1814,9 +2048,12 @@ x_draw_fringe_bitmap (w, row, p) #endif } - if (p->which) + if (p->which +#if USE_CG_DRAWING + && p->which < max_fringe_bmp +#endif + ) { - unsigned short *bits = p->bits + p->dh; XGCValues gcv; XGetGCValues (display, face->gc, GCForeground, &gcv); @@ -1825,14 +2062,64 @@ x_draw_fringe_bitmap (w, row, p) ? (p->overlay_p ? face->background : f->output_data.mac->cursor_pixel) : face->foreground)); +#if USE_CG_DRAWING + mac_draw_cg_image (fringe_bmp[p->which], f, face->gc, 0, p->dh, + p->wd, p->h, p->x, p->y, p->overlay_p); +#else mac_draw_bitmap (f, face->gc, p->x, p->y, - p->wd, p->h, bits, p->overlay_p); + p->wd, p->h, p->bits + p->dh, p->overlay_p); +#endif XSetForeground (display, face->gc, gcv.foreground); } mac_reset_clip_rectangles (display, face->gc); } +#if USE_CG_DRAWING +static void +mac_define_fringe_bitmap (which, bits, h, wd) + int which; + unsigned short *bits; + int h, wd; +{ + unsigned short *mask_bits; + int i; + CGDataProviderRef provider; + + if (which >= max_fringe_bmp) + { + i = max_fringe_bmp; + max_fringe_bmp = which + 20; + fringe_bmp = (CGImageRef *) xrealloc (fringe_bmp, max_fringe_bmp * sizeof (CGImageRef)); + while (i < max_fringe_bmp) + fringe_bmp[i++] = 0; + } + + for (i = 0; i < h; i++) + bits[i] = ~bits[i]; + provider = CGDataProviderCreateWithData (NULL, bits, + sizeof (unsigned short) * h, NULL); + if (provider) + { + fringe_bmp[which] = CGImageMaskCreate (wd, h, 1, 1, + sizeof (unsigned short), + provider, NULL, 0); + CGDataProviderRelease (provider); + } +} + +static void +mac_destroy_fringe_bitmap (which) + int which; +{ + if (which >= max_fringe_bmp) + return; + + if (fringe_bmp[which]) + CGImageRelease (fringe_bmp[which]); + fringe_bmp[which] = 0; +} +#endif /* This is called when starting Emacs and when restarting after @@ -2324,14 +2611,6 @@ x_clear_glyph_string_rect (s, x, y, w, h) } -/* We prefer not to use XDrawImageString (srcCopy text transfer mode) - on Mac OS X because: - - Screen is double-buffered. (In srcCopy mode, a text is drawn - into an offscreen graphics world first. So performance gain - cannot be expected.) - - It lowers rendering quality. - - Some fonts leave garbage on cursor movement. */ - /* Draw the background of glyph_string S. If S->background_filled_p is non-zero don't draw it. FORCE_P non-zero means draw the background even if it wouldn't be drawn normally. This is used @@ -2363,12 +2642,10 @@ x_draw_glyph_string_background (s, force_p) } else #endif -#if defined (MAC_OS8) && !USE_ATSUI if (FONT_HEIGHT (s->font) < s->height - 2 * box_line_width || s->font_not_found_p || s->extends_to_end_of_line_p || force_p) -#endif { x_clear_glyph_string_rect (s, s->x, s->y + box_line_width, s->background_width, @@ -2385,7 +2662,7 @@ static void x_draw_glyph_string_foreground (s) struct glyph_string *s; { - int i, x; + int i, x, bg_width; /* If first glyph of S has a left box line, start drawing the text of S to the right of that box line. */ @@ -2424,7 +2701,6 @@ x_draw_glyph_string_foreground (s) for (i = 0; i < s->nchars; ++i) char1b[i] = s->char2b[i].byte2; -#if defined (MAC_OS8) && !USE_ATSUI /* Draw text with XDrawString if background has already been filled. Otherwise, use XDrawImageString. (Note that XDrawImageString is usually faster than XDrawString.) Always @@ -2432,38 +2708,27 @@ x_draw_glyph_string_foreground (s) no chance that characters under a box cursor are invisible. */ if (s->for_overlaps || (s->background_filled_p && s->hl != DRAW_CURSOR)) -#endif - { - /* Draw characters with 16-bit or 8-bit functions. */ - if (s->two_byte_p + bg_width = 0; /* Corresponds to XDrawString. */ + else + bg_width = s->background_width; /* Corresponds to XDrawImageString. */ + + if (s->two_byte_p #if USE_ATSUI - || GC_FONT (s->gc)->mac_style + || GC_FONT (s->gc)->mac_style #endif - ) + ) #if USE_CG_TEXT_DRAWING - if (!s->two_byte_p - && mac_draw_string_cg (s->f, s->gc, x, s->ybase - boff, - s->char2b, s->nchars)) - ; - else + if (!s->two_byte_p + && mac_draw_image_string_cg (s->f, s->gc, x, s->ybase - boff, + s->char2b, s->nchars, bg_width)) + ; + else #endif - mac_draw_string_16 (s->f, s->gc, x, s->ybase - boff, - s->char2b, s->nchars); - else - mac_draw_string (s->f, s->gc, x, s->ybase - boff, - char1b, s->nchars); - } -#if defined (MAC_OS8) && !USE_ATSUI + mac_draw_image_string_16 (s->f, s->gc, x, s->ybase - boff, + s->char2b, s->nchars, bg_width); else - { - if (s->two_byte_p) - mac_draw_image_string_16 (s->f, s->gc, x, s->ybase - boff, - s->char2b, s->nchars); - else - mac_draw_image_string (s->f, s->gc, x, s->ybase - boff, - char1b, s->nchars); - } -#endif + mac_draw_image_string (s->f, s->gc, x, s->ybase - boff, + char1b, s->nchars, bg_width); } } @@ -3026,15 +3291,26 @@ x_draw_image_foreground (s) { x_set_glyph_string_clipping (s); +#if USE_CG_DRAWING + mac_draw_cg_image (s->img->data.ptr_val, + s->f, s->gc, s->slice.x, s->slice.y, + s->slice.width, s->slice.height, x, y, 1); +#endif if (s->img->mask) +#if !USE_CG_DRAWING mac_copy_area_with_mask (s->img->pixmap, s->img->mask, s->f, s->gc, s->slice.x, s->slice.y, s->slice.width, s->slice.height, x, y); +#else + ; +#endif else { +#if !USE_CG_DRAWING mac_copy_area (s->img->pixmap, s->f, s->gc, s->slice.x, s->slice.y, s->slice.width, s->slice.height, x, y); +#endif /* When the image has a mask, we can expect that at least part of a mouse highlight or a block cursor will @@ -4244,8 +4520,8 @@ static OSStatus set_scroll_bar_timer P_ ((EventTimerInterval)); static int control_part_code_to_scroll_bar_part P_ ((ControlPartCode)); static void construct_scroll_bar_click P_ ((struct scroll_bar *, int, struct input_event *)); -static OSErr get_control_part_bounds P_ ((ControlHandle, ControlPartCode, - Rect *)); +static OSStatus get_control_part_bounds P_ ((ControlHandle, ControlPartCode, + Rect *)); static void x_scroll_bar_handle_press P_ ((struct scroll_bar *, ControlPartCode, struct input_event *)); @@ -4366,7 +4642,7 @@ construct_scroll_bar_click (bar, part, bufp) bufp->modifiers = 0; } -static OSErr +static OSStatus get_control_part_bounds (ch, part_code, rect) ControlHandle ch; ControlPartCode part_code; @@ -4508,10 +4784,12 @@ x_set_toolkit_scroll_bar_thumb (bar, portion, position, whole) int portion, position, whole; { ControlHandle ch = SCROLL_BAR_CONTROL_HANDLE (bar); - int value, viewsize, maximum; - if (whole == 0 || XINT (bar->track_height) == 0) + if (XINT (bar->track_height) == 0) + return; + + if (whole == 0) value = 0, viewsize = 1, maximum = 0; else { @@ -4522,10 +4800,19 @@ x_set_toolkit_scroll_bar_thumb (bar, portion, position, whole) BLOCK_INPUT; - SetControl32BitMinimum (ch, 0); - SetControl32BitMaximum (ch, maximum); - SetControl32BitValue (ch, value); - SetControlViewSize (ch, viewsize); + if (GetControlViewSize (ch) != viewsize + || GetControl32BitValue (ch) != value + || GetControl32BitMaximum (ch) != maximum) + { + /* Temporarily hide the scroll bar to avoid multiple redraws. */ + SetControlVisibility (ch, false, false); + + SetControl32BitMaximum (ch, maximum); + SetControl32BitValue (ch, value); + SetControlViewSize (ch, viewsize); + + SetControlVisibility (ch, true, true); + } UNBLOCK_INPUT; } @@ -4561,8 +4848,16 @@ x_scroll_bar_create (w, top, left, width, height, disp_top, disp_height) r.right = left + width; r.bottom = disp_top + disp_height; +#if USE_CG_DRAWING + mac_prepare_for_quickdraw (f); +#endif #if TARGET_API_MAC_CARBON - ch = NewControl (FRAME_MAC_WINDOW (f), &r, "\p", width < disp_height, + ch = NewControl (FRAME_MAC_WINDOW (f), &r, "\p", +#if USE_TOOLKIT_SCROLL_BARS + false, +#else + width < disp_height, +#endif 0, 0, 0, kControlScrollBarProc, (long) bar); #else ch = NewControl (FRAME_MAC_WINDOW (f), &r, "\p", width < disp_height, @@ -4682,6 +4977,9 @@ x_scroll_bar_remove (bar) BLOCK_INPUT; +#if USE_CG_DRAWING + mac_prepare_for_quickdraw (f); +#endif /* Destroy the Mac scroll bar control */ DisposeControl (SCROLL_BAR_CONTROL_HANDLE (bar)); @@ -4732,6 +5030,7 @@ XTset_vertical_scroll_bar (w, portion, whole, position) /* Adjustments according to Inside Macintosh to make it look nice */ disp_top = top; disp_height = height; +#ifdef MAC_OS8 if (disp_top == 0) { disp_top = -1; @@ -4745,6 +5044,7 @@ XTset_vertical_scroll_bar (w, portion, whole, position) if (sb_left + sb_width == FRAME_PIXEL_WIDTH (f)) sb_left++; +#endif /* Does the scroll bar exist yet? */ if (NILP (w->vertical_scroll_bar)) @@ -4776,12 +5076,17 @@ XTset_vertical_scroll_bar (w, portion, whole, position) for them on the frame, we have to clear "under" them. */ mac_clear_area (f, left, top, width, height); +#if USE_CG_DRAWING + mac_prepare_for_quickdraw (f); +#endif HideControl (ch); MoveControl (ch, sb_left + VERTICAL_SCROLL_BAR_WIDTH_TRIM, disp_top); SizeControl (ch, sb_width - VERTICAL_SCROLL_BAR_WIDTH_TRIM * 2, disp_height); +#ifndef USE_TOOLKIT_SCROLL_BARS if (sb_width < disp_height) ShowControl (ch); +#endif /* Remember new settings. */ XSETINT (bar->left, sb_left); @@ -4799,30 +5104,41 @@ XTset_vertical_scroll_bar (w, portion, whole, position) #ifdef USE_TOOLKIT_SCROLL_BARS if (NILP (bar->track_top)) - { - ControlHandle ch = SCROLL_BAR_CONTROL_HANDLE (bar); - Rect r0, r1; + if (sb_width >= disp_height) + { + XSETINT (bar->track_top, 0); + XSETINT (bar->track_height, 0); + } + else + { + ControlHandle ch = SCROLL_BAR_CONTROL_HANDLE (bar); + Rect r0, r1; - BLOCK_INPUT; + BLOCK_INPUT; - SetControl32BitMinimum (ch, 0); - SetControl32BitMaximum (ch, 1); - SetControlViewSize (ch, 1); + SetControl32BitMinimum (ch, 0); + SetControl32BitMaximum (ch, 1); + SetControlViewSize (ch, 1); - /* Move the scroll bar thumb to the top. */ - SetControl32BitValue (ch, 0); - get_control_part_bounds (ch, kControlIndicatorPart, &r0); + /* Move the scroll bar thumb to the top. */ + SetControl32BitValue (ch, 0); + get_control_part_bounds (ch, kControlIndicatorPart, &r0); - /* Move the scroll bar thumb to the bottom. */ - SetControl32BitValue (ch, 1); - get_control_part_bounds (ch, kControlIndicatorPart, &r1); + /* Move the scroll bar thumb to the bottom. */ + SetControl32BitValue (ch, 1); + get_control_part_bounds (ch, kControlIndicatorPart, &r1); - UnionRect (&r0, &r1, &r0); - XSETINT (bar->track_top, r0.top); - XSETINT (bar->track_height, r0.bottom - r0.top); + UnionRect (&r0, &r1, &r0); + XSETINT (bar->track_top, r0.top); + XSETINT (bar->track_height, r0.bottom - r0.top); - UNBLOCK_INPUT; - } + /* Don't show the scroll bar if its height is not enough to + display the scroll bar thumb. */ + if (r0.bottom - r0.top > 0) + ShowControl (ch); + + UNBLOCK_INPUT; + } x_set_toolkit_scroll_bar_thumb (bar, portion, position, whole); #else /* not USE_TOOLKIT_SCROLL_BARS */ @@ -5207,7 +5523,7 @@ x_draw_hollow_cursor (w, row) /* Set clipping, draw the rectangle, and reset clipping again. */ x_clip_to_row (w, row, TEXT_AREA, gc); - mac_draw_rectangle (f, gc, x, y, wd, h); + mac_draw_rectangle (f, gc, x, y, wd, h - 1); mac_reset_clip_rectangles (dpy, gc); } @@ -5751,8 +6067,13 @@ x_set_window_size (f, change_gravity, cols, rows) SizeWindow (FRAME_MAC_WINDOW (f), pixelwidth, pixelheight, 0); #if TARGET_API_MAC_CARBON if (f->output_data.mac->hourglass_control) - MoveControl (f->output_data.mac->hourglass_control, - pixelwidth - HOURGLASS_WIDTH, 0); + { +#if USE_CG_DRAWING + mac_prepare_for_quickdraw (f); +#endif + MoveControl (f->output_data.mac->hourglass_control, + pixelwidth - HOURGLASS_WIDTH, 0); + } #endif /* Now, strictly speaking, we can't be sure that this is accurate, @@ -7856,9 +8177,13 @@ XLoadQueryFont (Display *dpy, char *fontname) #if !defined (MAC_OS8) || USE_ATSUI /* AppKit and WebKit do some adjustment to the heights of Courier, Helvetica, and Times. This only works on the environments where - the XDrawImageString counterpart is never used. */ - if (strcmp (family, "courier") == 0 || strcmp (family, "helvetica") == 0 - || strcmp (family, "times") == 0) + srcCopy text transfer mode is never used. */ + if ( +#ifdef MAC_OS8 /* implies USE_ATSUI */ + font->mac_style && +#endif + (strcmp (family, "courier") == 0 || strcmp (family, "helvetica") == 0 + || strcmp (family, "times") == 0)) font->ascent += (font->ascent + font->descent) * .15 + 0.5; #endif @@ -8372,6 +8697,7 @@ mac_get_mouse_btn (EventRef ref) XTread_socket loop). */ static Boolean mac_convert_event_ref (EventRef eventRef, EventRecord *eventRec) { + OSStatus err; Boolean result = ConvertEventRefToEventRecord (eventRef, eventRec); if (result) @@ -8405,13 +8731,19 @@ static Boolean mac_convert_event_ref (EventRef eventRef, EventRecord *eventRec) unsigned char char_codes; UInt32 key_code; - eventRec->what = keyDown; - GetEventParameter (eventRef, kEventParamKeyMacCharCodes, typeChar, - NULL, sizeof (char), NULL, &char_codes); - GetEventParameter (eventRef, kEventParamKeyCode, typeUInt32, - NULL, sizeof (UInt32), NULL, &key_code); - eventRec->message = char_codes | ((key_code & 0xff) << 8); - result = 1; + err = GetEventParameter (eventRef, kEventParamKeyMacCharCodes, + typeChar, NULL, sizeof (char), + NULL, &char_codes); + if (err == noErr) + err = GetEventParameter (eventRef, kEventParamKeyCode, + typeUInt32, NULL, sizeof (UInt32), + NULL, &key_code); + if (err == noErr) + { + eventRec->what = keyDown; + eventRec->message = char_codes | ((key_code & 0xff) << 8); + result = 1; + } } break; @@ -8427,7 +8759,7 @@ static Boolean mac_convert_event_ref (EventRef eventRef, EventRecord *eventRec) if (result) { /* Need where and when. */ - UInt32 mods; + UInt32 mods = 0; GetEventParameter (eventRef, kEventParamMouseLocation, typeQDPoint, NULL, sizeof (Point), NULL, &eventRec->where); @@ -8837,8 +9169,7 @@ mac_handle_command_event (next_handler, event, data) EventRef event; void *data; { - OSStatus result; - OSErr err; + OSStatus result, err; HICommand command; Lisp_Object class_key, id_key, binding; @@ -8846,10 +9177,10 @@ mac_handle_command_event (next_handler, event, data) if (result != eventNotHandledErr) return result; - GetEventParameter (event, kEventParamDirectObject, typeHICommand, NULL, - sizeof (HICommand), NULL, &command); + err = GetEventParameter (event, kEventParamDirectObject, typeHICommand, + NULL, sizeof (HICommand), NULL, &command); - if (command.commandID == 0) + if (err != noErr || command.commandID == 0) return eventNotHandledErr; /* A HICommand event is mapped to an Apple event whose event class @@ -8903,12 +9234,14 @@ mac_handle_window_event (next_handler, event, data) void *data; { WindowPtr wp; - OSStatus result; + OSStatus result, err; UInt32 attributes; XSizeHints *size_hints; - GetEventParameter (event, kEventParamDirectObject, typeWindowRef, - NULL, sizeof (WindowPtr), NULL, &wp); + err = GetEventParameter (event, kEventParamDirectObject, typeWindowRef, + NULL, sizeof (WindowPtr), NULL, &wp); + if (err != noErr) + return eventNotHandledErr; switch (GetEventKind (event)) { @@ -8925,8 +9258,11 @@ mac_handle_window_event (next_handler, event, data) if (result != eventNotHandledErr) return result; - GetEventParameter (event, kEventParamAttributes, typeUInt32, - NULL, sizeof (UInt32), NULL, &attributes); + err = GetEventParameter (event, kEventParamAttributes, typeUInt32, + NULL, sizeof (UInt32), NULL, &attributes); + if (err != noErr) + break; + size_hints = FRAME_SIZE_HINTS (mac_window_to_frame (wp)); if ((attributes & kWindowBoundsChangeUserResize) && ((size_hints->flags & (PResizeInc | PBaseSize | PMinSize)) @@ -8935,9 +9271,12 @@ mac_handle_window_event (next_handler, event, data) Rect bounds; int width, height; - GetEventParameter (event, kEventParamCurrentBounds, - typeQDRectangle, - NULL, sizeof (Rect), NULL, &bounds); + err = GetEventParameter (event, kEventParamCurrentBounds, + typeQDRectangle, NULL, sizeof (Rect), + NULL, &bounds); + if (err != noErr) + break; + width = bounds.right - bounds.left; height = bounds.bottom - bounds.top; @@ -8986,7 +9325,7 @@ mac_handle_mouse_event (next_handler, event, data) EventRef event; void *data; { - OSStatus result; + OSStatus result, err; switch (GetEventKind (event)) { @@ -9002,22 +9341,31 @@ mac_handle_mouse_event (next_handler, event, data) if (result != eventNotHandledErr || read_socket_inev == NULL) return result; - GetEventParameter (event, kEventParamWindowRef, typeWindowRef, - NULL, sizeof (WindowRef), NULL, &wp); + err = GetEventParameter (event, kEventParamWindowRef, typeWindowRef, + NULL, sizeof (WindowRef), NULL, &wp); + if (err != noErr) + break; + f = mac_window_to_frame (wp); if (f != mac_focus_frame (&one_mac_display_info)) break; - GetEventParameter (event, kEventParamMouseWheelAxis, - typeMouseWheelAxis, NULL, - sizeof (EventMouseWheelAxis), NULL, &axis); - if (axis != kEventMouseWheelAxisY) + err = GetEventParameter (event, kEventParamMouseWheelAxis, + typeMouseWheelAxis, NULL, + sizeof (EventMouseWheelAxis), NULL, &axis); + if (err != noErr || axis != kEventMouseWheelAxisY) break; - GetEventParameter (event, kEventParamMouseWheelDelta, typeSInt32, - NULL, sizeof (SInt32), NULL, &delta); - GetEventParameter (event, kEventParamMouseLocation, typeQDPoint, - NULL, sizeof (Point), NULL, &point); + err = GetEventParameter (event, kEventParamMouseWheelDelta, + typeSInt32, NULL, sizeof (SInt32), + NULL, &delta); + if (err != noErr) + break; + err = GetEventParameter (event, kEventParamMouseLocation, + typeQDPoint, NULL, sizeof (Point), + NULL, &point); + if (err != noErr) + break; read_socket_inev->kind = WHEEL_EVENT; read_socket_inev->code = 0; read_socket_inev->modifiers = @@ -9479,13 +9827,13 @@ convert_fn_keycode (EventRef eventRef, int keyCode, int *newCode) Fn modifier. That's why we need the table. */ - + OSStatus err; UInt32 mods = 0; if (!NILP(Vmac_function_modifier)) { - GetEventParameter (eventRef, kEventParamKeyModifiers, typeUInt32, NULL, - sizeof (UInt32), NULL, &mods); - if (mods & kEventKeyModifierFnMask) + err = GetEventParameter (eventRef, kEventParamKeyModifiers, typeUInt32, + NULL, sizeof (UInt32), NULL, &mods); + if (err != noErr && mods & kEventKeyModifierFnMask) { *newCode = fn_keycode_to_xkeysym_table [keyCode & 0x7f]; return (*newCode != 0); @@ -9612,7 +9960,11 @@ XTread_socket (sd, expected, hold_quit) #if USE_CARBON_EVENTS toolbox_dispatcher = GetEventDispatcherTarget (); - while (!ReceiveNextEvent (0, NULL, kEventDurationNoWait, + while ( +#if USE_CG_DRAWING + mac_prepare_for_quickdraw (NULL), +#endif + !ReceiveNextEvent (0, NULL, kEventDurationNoWait, kEventRemoveFromQueue, &eventRef)) #else /* !USE_CARBON_EVENTS */ while (mac_wait_next_event (&er, 0, true)) @@ -10124,7 +10476,10 @@ XTread_socket (sd, expected, hold_quit) ObscureCursor (); - if (!dpyinfo->mouse_face_hidden && INTEGERP (Vmouse_highlight)) + f = mac_focus_frame (dpyinfo); + + if (!dpyinfo->mouse_face_hidden && INTEGERP (Vmouse_highlight) + && !EQ (f->tool_bar_window, dpyinfo->mouse_face_window)) { clear_mouse_face (dpyinfo); dpyinfo->mouse_face_hidden = 1; @@ -10168,7 +10523,7 @@ XTread_socket (sd, expected, hold_quit) inev.modifiers |= (extra_keyboard_modifiers & (meta_modifier | alt_modifier | hyper_modifier | super_modifier)); - XSETFRAME (inev.frame_or_window, mac_focus_frame (dpyinfo)); + XSETFRAME (inev.frame_or_window, f); break; case kHighLevelEvent: @@ -10670,8 +11025,13 @@ static struct redisplay_interface x_redisplay_interface = x_get_glyph_overhangs, x_fix_overlapping_area, x_draw_fringe_bitmap, +#if USE_CG_DRAWING + mac_define_fringe_bitmap, + mac_destroy_fringe_bitmap, +#else 0, /* define_fringe_bitmap */ 0, /* destroy_fringe_bitmap */ +#endif mac_per_char_metric, mac_encode_char, mac_compute_glyph_string_overhangs, @@ -10747,6 +11107,11 @@ mac_initialize () MakeMeTheFrontProcess (); #endif #endif + +#if USE_CG_DRAWING + mac_init_fringe (); +#endif + UNBLOCK_INPUT; }