summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.in2
-rw-r--r--src/data.c12
-rw-r--r--src/editfns.c3
-rw-r--r--src/emacs.c8
-rw-r--r--src/eval.c2
-rw-r--r--src/keyboard.c5
-rw-r--r--src/lcms.c107
-rw-r--r--src/nsterm.m173
-rw-r--r--src/term.c12
-rw-r--r--src/termhooks.h4
-rw-r--r--src/xdisp.c4
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)