diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/Makefile.in | 2 | ||||
| -rw-r--r-- | src/data.c | 12 | ||||
| -rw-r--r-- | src/editfns.c | 3 | ||||
| -rw-r--r-- | src/emacs.c | 8 | ||||
| -rw-r--r-- | src/eval.c | 2 | ||||
| -rw-r--r-- | src/keyboard.c | 5 | ||||
| -rw-r--r-- | src/lcms.c | 107 | ||||
| -rw-r--r-- | src/nsterm.m | 173 | ||||
| -rw-r--r-- | src/term.c | 12 | ||||
| -rw-r--r-- | src/termhooks.h | 4 | ||||
| -rw-r--r-- | src/xdisp.c | 4 |
11 files changed, 269 insertions, 63 deletions
diff --git a/src/Makefile.in b/src/Makefile.in index 0e55ad4bb29..9a8c9c85f04 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -280,7 +280,7 @@ GNU_OBJC_CFLAGS=$(patsubst -specs=%-hardened-cc1,,@GNU_OBJC_CFLAGS@) ## w32xfns.o w32select.o image.o w32uniscribe.o if HAVE_W32, else ## empty. W32_OBJ=@W32_OBJ@ -## -lkernel32 -luser32 -lgdi32 -lole32 -lcomdlg32 lusp10 -lcomctl32 +## -lkernel32 -luser32 -lusp10 -lgdi32 -lole32 -lcomdlg32 -lcomctl32 ## --lwinspool if HAVE_W32, else empty. W32_LIBS=@W32_LIBS@ diff --git a/src/data.c b/src/data.c index 95bf06e5102..e070be6c208 100644 --- a/src/data.c +++ b/src/data.c @@ -3010,16 +3010,16 @@ static Lisp_Object minmax_driver (ptrdiff_t nargs, Lisp_Object *args, enum Arith_Comparison comparison) { - eassume (0 < nargs); - Lisp_Object accum = args[0]; /* pacify GCC */ - for (ptrdiff_t argnum = 0; argnum < nargs; argnum++) + Lisp_Object accum = args[0]; + CHECK_NUMBER_OR_FLOAT_COERCE_MARKER (accum); + for (ptrdiff_t argnum = 1; argnum < nargs; argnum++) { Lisp_Object val = args[argnum]; CHECK_NUMBER_OR_FLOAT_COERCE_MARKER (val); - if (argnum == 0 || !NILP (arithcompare (val, accum, comparison))) + if (!NILP (arithcompare (val, accum, comparison))) accum = val; - else if (FLOATP (accum) && isnan (XFLOAT_DATA (accum))) - return accum; + else if (FLOATP (val) && isnan (XFLOAT_DATA (val))) + return val; } return accum; } diff --git a/src/editfns.c b/src/editfns.c index b03eb947dec..2f8b075817a 100644 --- a/src/editfns.c +++ b/src/editfns.c @@ -187,7 +187,8 @@ tzlookup (Lisp_Object zone, bool settz) if (sec != 0) prec += 2, numzone = 100 * numzone + sec; } - sprintf (tzbuf, tzbuf_format, prec, numzone, + sprintf (tzbuf, tzbuf_format, prec, + XINT (zone) < 0 ? -numzone : numzone, &"-"[XINT (zone) < 0], hour, min, sec); zone_string = tzbuf; } diff --git a/src/emacs.c b/src/emacs.c index 1ad8af70a74..0fe7d9113b4 100644 --- a/src/emacs.c +++ b/src/emacs.c @@ -252,7 +252,7 @@ Initialization options:\n\ "\ Action options:\n\ \n\ -FILE visit FILE using find-file\n\ +FILE visit FILE\n\ +LINE go to line LINE in next FILE\n\ +LINE:COLUMN go to line LINE, column COLUMN, in next FILE\n\ --directory, -L DIR prepend DIR to load-path (with :DIR, append DIR)\n\ @@ -260,13 +260,13 @@ FILE visit FILE using find-file\n\ --execute EXPR evaluate Emacs Lisp expression EXPR\n\ ", "\ ---file FILE visit FILE using find-file\n\ ---find-file FILE visit FILE using find-file\n\ +--file FILE visit FILE\n\ +--find-file FILE visit FILE\n\ --funcall, -f FUNC call Emacs Lisp function FUNC with no arguments\n\ --insert FILE insert contents of FILE into current buffer\n\ --kill exit without asking for confirmation\n\ --load, -l FILE load Emacs Lisp FILE using the load function\n\ ---visit FILE visit FILE using find-file\n\ +--visit FILE visit FILE\n\ \n\ ", "\ diff --git a/src/eval.c b/src/eval.c index 62e219631db..39d78364d5f 100644 --- a/src/eval.c +++ b/src/eval.c @@ -1428,7 +1428,7 @@ push_handler (Lisp_Object tag_ch_val, enum handlertype handlertype) struct handler * push_handler_nosignal (Lisp_Object tag_ch_val, enum handlertype handlertype) { - struct handler *c = handlerlist->nextfree; + struct handler *CACHEABLE c = handlerlist->nextfree; if (!c) { c = malloc (sizeof *c); diff --git a/src/keyboard.c b/src/keyboard.c index 4db50be855c..e8701b88708 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -5925,7 +5925,10 @@ make_lispy_event (struct input_event *event) ASIZE (wheel_syms)); } - if (event->modifiers & (double_modifier | triple_modifier)) + if (NUMBERP (event->arg)) + return list4 (head, position, make_number (double_click_count), + event->arg); + else if (event->modifiers & (double_modifier | triple_modifier)) return list3 (head, position, make_number (double_click_count)); else return list2 (head, position); diff --git a/src/lcms.c b/src/lcms.c index f543a030399..a5e527911ef 100644 --- a/src/lcms.c +++ b/src/lcms.c @@ -139,6 +139,26 @@ chroma, and hue, respectively. The parameters each default to 1. */) return make_float (cmsCIE2000DeltaE (&Lab1, &Lab2, Kl, Kc, Kh)); } +static double +deg2rad (double degrees) +{ + return M_PI * degrees / 180.0; +} + +static cmsCIEXYZ illuminant_d65 = { .X = 95.0455, .Y = 100.0, .Z = 108.8753 }; + +static void +default_viewing_conditions (const cmsCIEXYZ *wp, cmsViewingConditions *vc) +{ + vc->whitePoint.X = wp->X; + vc->whitePoint.Y = wp->Y; + vc->whitePoint.Z = wp->Z; + vc->Yb = 20; + vc->La = 100; + vc->surround = AVG_SURROUND; + vc->D_value = 1.0; +} + /* FIXME: code duplication */ static bool @@ -160,11 +180,62 @@ parse_xyz_list (Lisp_Object xyz_list, cmsCIEXYZ *color) return true; } -DEFUN ("lcms-cam02-ucs", Flcms_cam02_ucs, Slcms_cam02_ucs, 2, 3, 0, +static bool +parse_viewing_conditions (Lisp_Object view, const cmsCIEXYZ *wp, + cmsViewingConditions *vc) +{ +#define PARSE_VIEW_CONDITION_FLOAT(field) \ + if (CONSP (view) && NUMBERP (XCAR (view))) \ + { \ + vc->field = XFLOATINT (XCAR (view)); \ + view = XCDR (view); \ + } \ + else \ + return false; +#define PARSE_VIEW_CONDITION_INT(field) \ + if (CONSP (view) && NATNUMP (XCAR (view))) \ + { \ + CHECK_RANGED_INTEGER (XCAR (view), 1, 4); \ + vc->field = XINT (XCAR (view)); \ + view = XCDR (view); \ + } \ + else \ + return false; + + PARSE_VIEW_CONDITION_FLOAT (Yb); + PARSE_VIEW_CONDITION_FLOAT (La); + PARSE_VIEW_CONDITION_INT (surround); + PARSE_VIEW_CONDITION_FLOAT (D_value); + + if (! NILP (view)) + return false; + + vc->whitePoint.X = wp->X; + vc->whitePoint.Y = wp->Y; + vc->whitePoint.Z = wp->Z; + return true; +} + +/* References: + Li, Luo et al. "The CRI-CAM02UCS colour rendering index." COLOR research + and application, 37 No.3, 2012. + Luo et al. "Uniform colour spaces based on CIECAM02 colour appearance + model." COLOR research and application, 31 No.4, 2006. */ + +DEFUN ("lcms-cam02-ucs", Flcms_cam02_ucs, Slcms_cam02_ucs, 2, 4, 0, doc: /* Compute CAM02-UCS metric distance between COLOR1 and COLOR2. -Each color is a list of XYZ coordinates, with Y scaled about unity. -Optional argument is the XYZ white point, which defaults to illuminant D65. */) - (Lisp_Object color1, Lisp_Object color2, Lisp_Object whitepoint) +Each color is a list of XYZ tristimulus values, with Y scaled about unity. +Optional argument WHITEPOINT is the XYZ white point, which defaults to +illuminant D65. +Optional argument VIEW is a list containing the viewing conditions, and +is of the form (YB LA SURROUND DVALUE) where SURROUND corresponds to + 1 AVG_SURROUND + 2 DIM_SURROUND + 3 DARK_SURROUND + 4 CUTSHEET_SURROUND +The default viewing conditions are (20 100 1 1). */) + (Lisp_Object color1, Lisp_Object color2, Lisp_Object whitepoint, + Lisp_Object view) { cmsViewingConditions vc; cmsJCh jch1, jch2; @@ -188,17 +259,13 @@ Optional argument is the XYZ white point, which defaults to illuminant D65. */) if (!(CONSP (color2) && parse_xyz_list (color2, &xyz2))) signal_error ("Invalid color", color2); if (NILP (whitepoint)) - parse_xyz_list (Vlcms_d65_xyz, &xyzw); + xyzw = illuminant_d65; else if (!(CONSP (whitepoint) && parse_xyz_list (whitepoint, &xyzw))) signal_error ("Invalid white point", whitepoint); - - vc.whitePoint.X = xyzw.X; - vc.whitePoint.Y = xyzw.Y; - vc.whitePoint.Z = xyzw.Z; - vc.Yb = 20; - vc.La = 100; - vc.surround = AVG_SURROUND; - vc.D_value = 1.0; + if (NILP (view)) + default_viewing_conditions (&xyzw, &vc); + else if (!(CONSP (view) && parse_viewing_conditions (view, &xyzw, &vc))) + signal_error ("Invalid view conditions", view); h1 = cmsCIECAM02Init (0, &vc); h2 = cmsCIECAM02Init (0, &vc); @@ -227,10 +294,10 @@ Optional argument is the XYZ white point, which defaults to illuminant D65. */) Mp2 = 43.86 * log (1.0 + 0.0228 * (jch2.C * sqrt (sqrt (FL)))); Jp1 = 1.7 * jch1.J / (1.0 + (0.007 * jch1.J)); Jp2 = 1.7 * jch2.J / (1.0 + (0.007 * jch2.J)); - ap1 = Mp1 * cos (jch1.h); - ap2 = Mp2 * cos (jch2.h); - bp1 = Mp1 * sin (jch1.h); - bp2 = Mp2 * sin (jch2.h); + ap1 = Mp1 * cos (deg2rad (jch1.h)); + ap2 = Mp2 * cos (deg2rad (jch2.h)); + bp1 = Mp1 * sin (deg2rad (jch1.h)); + bp2 = Mp2 * sin (deg2rad (jch2.h)); return make_float (sqrt ((Jp2 - Jp1) * (Jp2 - Jp1) + (ap2 - ap1) * (ap2 - ap1) + @@ -291,12 +358,6 @@ DEFUN ("lcms2-available-p", Flcms2_available_p, Slcms2_available_p, 0, 0, 0, void syms_of_lcms2 (void) { - DEFVAR_LISP ("lcms-d65-xyz", Vlcms_d65_xyz, - doc: /* D65 illuminant as a CIE XYZ triple. */); - Vlcms_d65_xyz = list3 (make_float (0.950455), - make_float (1.0), - make_float (1.088753)); - defsubr (&Slcms_cie_de2000); defsubr (&Slcms_cam02_ucs); defsubr (&Slcms2_available_p); diff --git a/src/nsterm.m b/src/nsterm.m index 27515335332..f0b6a70dae3 100644 --- a/src/nsterm.m +++ b/src/nsterm.m @@ -1820,8 +1820,8 @@ x_set_window_size (struct frame *f, if (pixelwise) { - pixelwidth = width; - pixelheight = height; + pixelwidth = FRAME_TEXT_TO_PIXEL_WIDTH (f, width); + pixelheight = FRAME_TEXT_TO_PIXEL_HEIGHT (f, height); } else { @@ -6498,24 +6498,139 @@ not_in_argv (NSString *arg) if ([theEvent type] == NSEventTypeScrollWheel) { - CGFloat delta = [theEvent deltaY]; - /* Mac notebooks send wheel events w/delta =0 when trackpad scrolling */ - if (delta == 0) +#if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 +#if MAC_OS_X_VERSION_MIN_REQUIRED < 1070 + if ([theEvent respondsToSelector:@selector(hasPreciseScrollingDeltas)]) { - delta = [theEvent deltaX]; - if (delta == 0) +#endif + /* If the input device is a touchpad or similar, use precise + * scrolling deltas. These are measured in pixels, so we + * have to add them up until they exceed one line height, + * then we can send a scroll wheel event. + * + * If the device only has coarse scrolling deltas, like a + * real mousewheel, the deltas represent a ratio of whole + * lines, so round up the number of lines. This means we + * always send one scroll event per click, but can still + * scroll more than one line if the OS tells us to. + */ + bool horizontal; + int lines = 0; + int scrollUp = NO; + + /* FIXME: At the top or bottom of the buffer we should + * ignore momentum-phase events. */ + if (! ns_use_mwheel_momentum + && [theEvent momentumPhase] != NSEventPhaseNone) + return; + + if ([theEvent hasPreciseScrollingDeltas]) { - NSTRACE_MSG ("deltaIsZero"); - return; + static int totalDeltaX, totalDeltaY; + int lineHeight; + + if (NUMBERP (ns_mwheel_line_height)) + lineHeight = XINT (ns_mwheel_line_height); + else + { + /* FIXME: Use actual line height instead of the default. */ + lineHeight = default_line_pixel_height + (XWINDOW (FRAME_SELECTED_WINDOW (emacsframe))); + } + + if ([theEvent phase] == NSEventPhaseBegan) + { + totalDeltaX = 0; + totalDeltaY = 0; + } + + totalDeltaX += [theEvent scrollingDeltaX]; + totalDeltaY += [theEvent scrollingDeltaY]; + + /* Calculate the number of lines, if any, to scroll, and + * reset the total delta for the direction we're NOT + * scrolling so that small movements don't add up. */ + if (abs (totalDeltaX) > abs (totalDeltaY) + && abs (totalDeltaX) > lineHeight) + { + horizontal = YES; + scrollUp = totalDeltaX > 0; + + lines = abs (totalDeltaX / lineHeight); + totalDeltaX = totalDeltaX % lineHeight; + totalDeltaY = 0; + } + else if (abs (totalDeltaY) >= abs (totalDeltaX) + && abs (totalDeltaY) > lineHeight) + { + horizontal = NO; + scrollUp = totalDeltaY > 0; + + lines = abs (totalDeltaY / lineHeight); + totalDeltaY = totalDeltaY % lineHeight; + totalDeltaX = 0; + } + + if (lines > 1 && ! ns_use_mwheel_acceleration) + lines = 1; } - emacs_event->kind = HORIZ_WHEEL_EVENT; + else + { + CGFloat delta; + + if ([theEvent scrollingDeltaY] == 0) + { + horizontal = YES; + delta = [theEvent scrollingDeltaX]; + } + else + { + horizontal = NO; + delta = [theEvent scrollingDeltaY]; + } + + lines = (ns_use_mwheel_acceleration) + ? ceil (fabs (delta)) : 1; + + scrollUp = delta > 0; + } + + if (lines == 0) + return; + + emacs_event->kind = horizontal ? HORIZ_WHEEL_EVENT : WHEEL_EVENT; + emacs_event->arg = (make_number (lines)); + + emacs_event->code = 0; + emacs_event->modifiers = EV_MODIFIERS (theEvent) | + (scrollUp ? up_modifier : down_modifier); +#if MAC_OS_X_VERSION_MIN_REQUIRED < 1070 } else - emacs_event->kind = WHEEL_EVENT; +#endif +#endif /* defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 */ +#if defined (NS_IMPL_GNUSTEP) || MAC_OS_X_VERSION_MIN_REQUIRED < 1070 + { + CGFloat delta = [theEvent deltaY]; + /* Mac notebooks send wheel events w/delta =0 when trackpad scrolling */ + if (delta == 0) + { + delta = [theEvent deltaX]; + if (delta == 0) + { + NSTRACE_MSG ("deltaIsZero"); + return; + } + emacs_event->kind = HORIZ_WHEEL_EVENT; + } + else + emacs_event->kind = WHEEL_EVENT; - emacs_event->code = 0; - emacs_event->modifiers = EV_MODIFIERS (theEvent) | - ((delta > 0) ? up_modifier : down_modifier); + emacs_event->code = 0; + emacs_event->modifiers = EV_MODIFIERS (theEvent) | + ((delta > 0) ? up_modifier : down_modifier); + } +#endif } else { @@ -6524,9 +6639,11 @@ not_in_argv (NSString *arg) emacs_event->modifiers = EV_MODIFIERS (theEvent) | EV_UDMODIFIERS (theEvent); } + XSETINT (emacs_event->x, lrint (p.x)); XSETINT (emacs_event->y, lrint (p.y)); EV_TRAILER (theEvent); + return; } @@ -6707,9 +6824,10 @@ not_in_argv (NSString *arg) if (wait_for_tool_bar) { - /* The toolbar height is always 0 in fullscreen, so don't wait - for it to become available. */ + /* The toolbar height is always 0 in fullscreen and undecorated + frames, so don't wait for it to become available. */ if (FRAME_TOOLBAR_HEIGHT (emacsframe) == 0 + && FRAME_UNDECORATED (emacsframe) == false && ! [self isFullscreen]) { NSTRACE_MSG ("Waiting for toolbar"); @@ -7090,9 +7208,9 @@ not_in_argv (NSString *arg) win = [[EmacsWindow alloc] initWithContentRect: r - styleMask: (FRAME_UNDECORATED (f) - ? FRAME_UNDECORATED_FLAGS - : FRAME_DECORATED_FLAGS + styleMask: ((FRAME_UNDECORATED (f) + ? FRAME_UNDECORATED_FLAGS + : FRAME_DECORATED_FLAGS) #ifdef NS_IMPL_COCOA | NSWindowStyleMaskResizable | NSWindowStyleMaskMiniaturizable @@ -9166,6 +9284,23 @@ Note that this does not apply to images. This variable is ignored on Mac OS X < 10.7 and GNUstep. */); ns_use_srgb_colorspace = YES; + DEFVAR_BOOL ("ns-use-mwheel-acceleration", + ns_use_mwheel_acceleration, + doc: /*Non-nil means use macOS's standard mouse wheel acceleration. +This variable is ignored on macOS < 10.7 and GNUstep. Default is t. */); + ns_use_mwheel_acceleration = YES; + + DEFVAR_LISP ("ns-mwheel-line-height", ns_mwheel_line_height, + doc: /*The number of pixels touchpad scrolling considers one line. +Nil or a non-number means use the default frame line height. +This variable is ignored on macOS < 10.7 and GNUstep. Default is nil. */); + ns_mwheel_line_height = Qnil; + + DEFVAR_BOOL ("ns-use-mwheel-momentum", ns_use_mwheel_momentum, + doc: /*Non-nil means mouse wheel scrolling uses momentum. +This variable is ignored on macOS < 10.7 and GNUstep. Default is t. */); + ns_use_mwheel_momentum = YES; + /* TODO: move to common code */ DEFVAR_LISP ("x-toolkit-scroll-bars", Vx_toolkit_scroll_bars, doc: /* Which toolkit scroll bars Emacs uses, if any. diff --git a/src/term.c b/src/term.c index a2ae8c2c6f0..065bce45d3c 100644 --- a/src/term.c +++ b/src/term.c @@ -155,12 +155,16 @@ tty_ring_bell (struct frame *f) static void tty_send_additional_strings (struct terminal *terminal, Lisp_Object sym) { - Lisp_Object lisp_terminal; - Lisp_Object extra_codes; + /* Use only accessors like CDR_SAFE and assq_no_quit to avoid any + form of quitting or signaling an error, since this function can + run as part of the "emergency escape" procedure invoked in the + middle of GC, where quitting means crashing (Bug#17406). */ + if (! terminal->name) + return; struct tty_display_info *tty = terminal->display_info.tty; - XSETTERMINAL (lisp_terminal, terminal); - for (extra_codes = Fterminal_parameter (lisp_terminal, sym); + for (Lisp_Object extra_codes + = CDR_SAFE (assq_no_quit (sym, terminal->param_alist)); CONSP (extra_codes); extra_codes = XCDR (extra_codes)) { diff --git a/src/termhooks.h b/src/termhooks.h index 97c128ba4e2..b5171bf1229 100644 --- a/src/termhooks.h +++ b/src/termhooks.h @@ -116,7 +116,9 @@ enum event_kind .frame_or_window gives the frame the wheel event occurred in. .timestamp gives a timestamp (in - milliseconds) for the event. */ + milliseconds) for the event. + .arg may contain the number of + lines to scroll. */ HORIZ_WHEEL_EVENT, /* A wheel event generated by a second horizontal wheel that is present on some mice. See WHEEL_EVENT. */ diff --git a/src/xdisp.c b/src/xdisp.c index dc5dbb05762..141275f15a0 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -22395,8 +22395,8 @@ Value is the new character position of point. */) row += dir; else row -= dir; - if (row < MATRIX_FIRST_TEXT_ROW (w->current_matrix) - || row > MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w)) + if (!(MATRIX_FIRST_TEXT_ROW (w->current_matrix) <= row + && row < MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w))) goto simulate_display; if (dir > 0) |
