aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPo Lu2021-12-12 11:15:00 +0800
committerPo Lu2021-12-12 11:15:00 +0800
commit0e69753ac142ef0f45ec14c8281ec4f76aea723b (patch)
tree2f53ce6aa6f45bbb2876f54bdeb51d7c0b7433e4
parentb9c1e1d73bbaf9228867dad2885ca6de53a3175f (diff)
parentff9360f4da351d25f1f9fb1ed9a78ce9db321ac4 (diff)
downloademacs-0e69753ac142ef0f45ec14c8281ec4f76aea723b.tar.gz
emacs-0e69753ac142ef0f45ec14c8281ec4f76aea723b.zip
Merge remote-tracking branch 'origin/master' into feature/pgtk
-rw-r--r--configure.ac2
-rw-r--r--doc/lispref/text.texi83
-rw-r--r--etc/NEWS14
-rw-r--r--lisp/emacs-lisp/byte-opt.el8
-rw-r--r--lisp/gnus/gnus-sum.el24
-rw-r--r--lisp/pixel-scroll.el66
-rw-r--r--lisp/sqlite-mode.el2
-rw-r--r--lisp/subr.el2
-rw-r--r--src/haikuterm.c321
-rw-r--r--src/w32.c28
-rw-r--r--src/w32.h1
-rw-r--r--src/w32proc.c21
-rw-r--r--test/lisp/emacs-lisp/bytecomp-tests.el6
13 files changed, 313 insertions, 265 deletions
diff --git a/configure.ac b/configure.ac
index 892c3e0b7b8..9a74c52c68a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2704,7 +2704,7 @@ if test "${with_sqlite3}" != "no"; then
2704 AC_SUBST(SQLITE3_LIBS) 2704 AC_SUBST(SQLITE3_LIBS)
2705 LIBS="$SQLITE3_LIBS $LIBS" 2705 LIBS="$SQLITE3_LIBS $LIBS"
2706 AC_DEFINE(HAVE_SQLITE3, 1, [Define to 1 if you have the libsqlite3 library (-lsqlite).]) 2706 AC_DEFINE(HAVE_SQLITE3, 1, [Define to 1 if you have the libsqlite3 library (-lsqlite).])
2707 # Windows loads libwebp dynamically 2707 # Windows loads libsqlite dynamically
2708 if test "${opsys}" = "mingw32"; then 2708 if test "${opsys}" = "mingw32"; then
2709 SQLITE3_LIBS= 2709 SQLITE3_LIBS=
2710 fi 2710 fi
diff --git a/doc/lispref/text.texi b/doc/lispref/text.texi
index e964d7b53c8..b8d92f7fdca 100644
--- a/doc/lispref/text.texi
+++ b/doc/lispref/text.texi
@@ -5138,8 +5138,11 @@ IV used.
5138 5138
5139@node Database 5139@node Database
5140@section Database 5140@section Database
5141@cindex database access, SQLite
5141 5142
5142 Emacs can be compiled with built-in SQLite support. 5143 Emacs can be compiled with built-in support for accessing SQLite
5144databases. This section describes the facilities available for
5145accessing SQLite databases from Lisp programs.
5143 5146
5144@defun sqlite-available-p 5147@defun sqlite-available-p
5145The function returns non-@code{nil} if built-in SQLite support is 5148The function returns non-@code{nil} if built-in SQLite support is
@@ -5148,20 +5151,21 @@ available in this Emacs session.
5148 5151
5149When SQLite support is available, the following functions can be used. 5152When SQLite support is available, the following functions can be used.
5150 5153
5154@cindex database object
5151@defun sqlite-open &optional file 5155@defun sqlite-open &optional file
5152This function opens @var{file} as a database file. If it doesn't 5156This function opens @var{file} as an SQLite database file. If
5153exist, a new database will be created and stored there. If this 5157@var{file} doesn't exist, a new database will be created and stored in
5154argument is missing or @code{nil}, a new in-memory database is created 5158that file. If @var{file} is omitted or @code{nil}, a new in-memory
5155instead. 5159database is created instead.
5156 5160
5157The return value is a @dfn{database object} that can be used as the 5161The return value is a @dfn{database object} that can be used as the
5158argument to most of the subsequent functions in this section of the 5162argument to most of the subsequent functions described below.
5159manual.
5160@end defun 5163@end defun
5161 5164
5162@defun sqlitep 5165@defun sqlitep object
5163The database object returned by the @code{sqlite-open} function 5166This predicate returns non-@code{nil} if @var{object} is an SQLite
5164satisfies this predicate. 5167database object. The database object returned by the
5168@code{sqlite-open} function satisfies this predicate.
5165@end defun 5169@end defun
5166 5170
5167@defun sqlite-close db 5171@defun sqlite-close db
@@ -5185,13 +5189,13 @@ For instance:
5185(sqlite-execute db "insert into foo values (?, ?)" '("bar" 2)) 5189(sqlite-execute db "insert into foo values (?, ?)" '("bar" 2))
5186@end lisp 5190@end lisp
5187 5191
5188This has exactly the same effect as the first form, but is more 5192This has exactly the same effect as the previous example, but is more
5189efficient and safer (because it doesn't involve any string parsing or 5193efficient and safer (because it doesn't involve any string parsing or
5190interpolation). 5194interpolation).
5191 5195
5192The number of affected rows is returned. For instance, an 5196@code{sqlite-execute} returns the number of affected rows. For
5193@samp{insert} statement will return @samp{1}, but an @samp{update} 5197instance, an @samp{insert} statement will return @samp{1}, whereas an
5194statement may return zero or a higher number. 5198@samp{update} statement may return zero or a higher number.
5195@end defun 5199@end defun
5196 5200
5197@defun sqlite-select db query &optional values result-type 5201@defun sqlite-select db query &optional values result-type
@@ -5202,33 +5206,36 @@ Select some data from @var{db} and return them. For instance:
5202 @result{} (("bar" 2)) 5206 @result{} (("bar" 2))
5203@end lisp 5207@end lisp
5204 5208
5205As with the @code{sqlite-execute} command, you can pass in a list or a 5209As with the @code{sqlite-execute}, you can optionally pass in a list
5206vector of values that will be bound before executing the select: 5210or a vector of values that will be bound before executing the select:
5207 5211
5208@lisp 5212@lisp
5209(sqlite-select db "select * from foo where key = ?" [2]) 5213(sqlite-select db "select * from foo where key = ?" [2])
5210 @result{} (("bar" 2)) 5214 @result{} (("bar" 2))
5211@end lisp 5215@end lisp
5212 5216
5213This is usually more efficient and safer than the first method. 5217This is usually more efficient and safer than the method used by the
5218previous example.
5214 5219
5215This function, by default, returns a list of matching rows, where each 5220By default, this function returns a list of matching rows, where each
5216row is a list of column values. If @var{return-type} is @code{full}, 5221row is a list of column values. If @var{return-type} is @code{full},
5217the names of the columns (as a list of strings) will be returned as 5222the names of the columns (as a list of strings) will be returned as
5218the first element in the return value. 5223the first element in the return value.
5219 5224
5225@cindex statement object
5220If @var{return-type} is @code{set}, this function will return a 5226If @var{return-type} is @code{set}, this function will return a
5221@dfn{statement object} instead. This object can be interrogated by 5227@dfn{statement object} instead. This object can be examined by using
5222the @code{sqlite-next}, @code{sqlite-columns} and @code{sqlite-more-p} 5228the @code{sqlite-next}, @code{sqlite-columns} and @code{sqlite-more-p}
5223functions. If the result set is small, it's often more convenient to 5229functions. If the result set is small, it's often more convenient to
5224just return the data directly, but if the result set is large (or if 5230just return the data directly, but if the result set is large (or if
5225you won't be using all the data from the set), using the @code{set} 5231you won't be using all the data from the set), using the @code{set}
5226method will allocate a lot less data, and therefore be more efficient. 5232method will allocate a lot less memory, and is therefore more
5233memory-efficient.
5227@end defun 5234@end defun
5228 5235
5229@defun sqlite-next statement 5236@defun sqlite-next statement
5230This function returns the next row in the result set returned by 5237This function returns the next row in the result set @var{statement},
5231@code{sqlite-select}. 5238typically an object returned by @code{sqlite-select}.
5232 5239
5233@lisp 5240@lisp
5234(sqlite-next stmt) 5241(sqlite-next stmt)
@@ -5237,8 +5244,8 @@ This function returns the next row in the result set returned by
5237@end defun 5244@end defun
5238 5245
5239@defun sqlite-columns statement 5246@defun sqlite-columns statement
5240This function returns the column names of the result set returned by 5247This function returns the column names of the result set
5241@code{sqlite-select}. 5248@var{statement}, typically an object returned by @code{sqlite-select}.
5242 5249
5243@lisp 5250@lisp
5244(sqlite-columns stmt) 5251(sqlite-columns stmt)
@@ -5247,38 +5254,42 @@ This function returns the column names of the result set returned by
5247@end defun 5254@end defun
5248 5255
5249@defun sqlite-more-p statement 5256@defun sqlite-more-p statement
5250This predicate says whether there is more data to be fetched in the 5257This predicate says whether there is more data to be fetched from the
5251result set returned by @code{sqlite-select}. 5258result set @var{statement}, typically an object returned by
5259@code{sqlite-select}.
5252@end defun 5260@end defun
5253 5261
5254@defun sqlite-finalize statement 5262@defun sqlite-finalize statement
5255If @var{statement} is not going to be used any more, calling this 5263If @var{statement} is not going to be used any more, calling this
5256function will free the resources bound by @var{statement}. This is 5264function will free the resources used by @var{statement}. This is
5257usually not necessary---when the statement object is 5265usually not necessary---when the @var{statement} object is
5258garbage-collected, this will happen automatically. 5266garbage-collected, Emacs will automatically free its resources.
5259@end defun 5267@end defun
5260 5268
5261@defun sqlite-transaction db 5269@defun sqlite-transaction db
5262Start a transaction in @var{db}. When in a transaction, other readers 5270Start a transaction in @var{db}. When in a transaction, other readers
5263of the database won't access the results until the transaction has 5271of the database won't access the results until the transaction has
5264been committed. 5272been committed by @code{sqlite-commit}.
5265@end defun 5273@end defun
5266 5274
5267@defun sqlite-commit db 5275@defun sqlite-commit db
5268End a transaction and write the data out to file. 5276End a transaction in @var{db} and write the data out to its file.
5269@end defun 5277@end defun
5270 5278
5271@defun sqlite-rollback db 5279@defun sqlite-rollback db
5272End a transaction and discard any changes that have been made. 5280End a transaction in @var{db} and discard any changes that have been
5281made by the transaction.
5273@end defun 5282@end defun
5274 5283
5275@defmac with-sqlite-transaction db &body body 5284@defmac with-sqlite-transaction db body@dots{}
5276Like @code{progn}, but executes @var{body} with a transaction held, 5285Like @code{progn} (@pxref{Sequencing}), but executes @var{body} with a
5277and do a commit at the end. 5286transaction held, and commits the transaction at the end.
5278@end defmac 5287@end defmac
5279 5288
5280@defun sqlite-load-extension db module 5289@defun sqlite-load-extension db module
5281Load an extension into @var{db}. Extensions are usually @file{.so} files. 5290Load the named extension @var{module} into the database @var{db}.
5291Extensions are usually shared-library files; on GNU and Unix systems,
5292they have the @file{.so} file-name extension.
5282@end defun 5293@end defun
5283 5294
5284@node Parsing HTML/XML 5295@node Parsing HTML/XML
diff --git a/etc/NEWS b/etc/NEWS
index b0dfa301d31..807751ae126 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -24,6 +24,11 @@ applies, and please also update docstrings as needed.
24 24
25* Installation Changes in Emacs 29.1 25* Installation Changes in Emacs 29.1
26 26
27+++
28** Emacs can be built with built-in support for accessing SQLite databases.
29This uses the popular sqlite3 library, and can be disabled by using
30the '--without-sqlite3' option to the 'configure' script.
31
27** Emacs has been ported to the Haiku operating system. 32** Emacs has been ported to the Haiku operating system.
28The configuration process should automatically detect and build for 33The configuration process should automatically detect and build for
29Haiku. There is also an optional window-system port to Haiku, which 34Haiku. There is also an optional window-system port to Haiku, which
@@ -91,13 +96,10 @@ the 'variable-pitch' face, or add this to your "~/.emacs":
91 96
92* Changes in Emacs 29.1 97* Changes in Emacs 29.1
93 98
94+++
95** Emacs now comes with optional built-in support for sqlite3.
96This allows you to examine and manipulate sqlite3 databases.
97
98** New command 'sqlite-mode-open-file' for examining an sqlite3 file. 99** New command 'sqlite-mode-open-file' for examining an sqlite3 file.
99This uses the new 'sqlite-mode' which allows listing the tables 100This uses the new 'sqlite-mode' which allows listing the tables in a
100in a file, the columns, and the contents of the tables. 101DB file, and examining and modifying the columns and the contents of
102those tables.
101 103
102--- 104---
103** 'write-file' will now copy some file mode bits. 105** 'write-file' will now copy some file mode bits.
diff --git a/lisp/emacs-lisp/byte-opt.el b/lisp/emacs-lisp/byte-opt.el
index f6db803b78e..2bdf1f55111 100644
--- a/lisp/emacs-lisp/byte-opt.el
+++ b/lisp/emacs-lisp/byte-opt.el
@@ -342,8 +342,12 @@ for speeding up processing.")
342 (numberp expr) 342 (numberp expr)
343 (stringp expr) 343 (stringp expr)
344 (and (consp expr) 344 (and (consp expr)
345 (memq (car expr) '(quote function)) 345 (or (and (memq (car expr) '(quote function))
346 (symbolp (cadr expr))) 346 (symbolp (cadr expr)))
347 ;; (internal-get-closed-var N) can be considered constant for
348 ;; const-prop purposes.
349 (and (eq (car expr) 'internal-get-closed-var)
350 (integerp (cadr expr)))))
347 (keywordp expr))) 351 (keywordp expr)))
348 352
349(defmacro byte-optimize--pcase (exp &rest cases) 353(defmacro byte-optimize--pcase (exp &rest cases)
diff --git a/lisp/gnus/gnus-sum.el b/lisp/gnus/gnus-sum.el
index ba616586002..1bd0e8847e2 100644
--- a/lisp/gnus/gnus-sum.el
+++ b/lisp/gnus/gnus-sum.el
@@ -5001,23 +5001,13 @@ If LINE, insert the rebuilt thread starting on line LINE."
5001 gnus-article-sort-functions))) 5001 gnus-article-sort-functions)))
5002 (gnus-message 7 "Sorting articles...done")))) 5002 (gnus-message 7 "Sorting articles...done"))))
5003 5003
5004;; Written by Hallvard B Furuseth <h.b.furuseth@usit.uio.no>. 5004(defsubst gnus-thread-header (thread)
5005(defmacro gnus-thread-header (thread) 5005 "Return header of first article in THREAD."
5006 "Return header of first article in THREAD. 5006 (if (consp thread)
5007Note that THREAD must never, ever be anything else than a variable - 5007 (car (if (stringp (car thread))
5008using some other form will lead to serious barfage." 5008 (cadr thread)
5009 (or (symbolp thread) (signal 'wrong-type-argument '(symbolp thread))) 5009 thread))
5010 ;; (8% speedup to gnus-summary-prepare, just for fun :-) 5010 thread))
5011 (cond
5012 ((and (boundp 'lexical-binding) lexical-binding)
5013 ;; FIXME: This version could be a "defsubst" rather than a macro.
5014 `(#[257 "\211:\203\16\0\211@;\203\15\0A@@\207"
5015 [] 2]
5016 ,thread))
5017 (t
5018 ;; Not sure how XEmacs handles these things, so let's keep the old code.
5019 (list 'byte-code "\10\211:\203\17\0\211@;\203\16\0A@@\207"
5020 (vector thread) 2))))
5021 5011
5022(defsubst gnus-article-sort-by-number (h1 h2) 5012(defsubst gnus-article-sort-by-number (h1 h2)
5023 "Sort articles by article number." 5013 "Sort articles by article number."
diff --git a/lisp/pixel-scroll.el b/lisp/pixel-scroll.el
index 336b555e77c..0e22ef2a6a7 100644
--- a/lisp/pixel-scroll.el
+++ b/lisp/pixel-scroll.el
@@ -542,35 +542,43 @@ animation."
542 (< (- (float-time) time) 1.0) 542 (< (- (float-time) time) 1.0)
543 (eq (< delta 0) (< rem 0))) 543 (eq (< delta 0) (< rem 0)))
544 (setq delta (+ delta rem))) 544 (setq delta (+ delta rem)))
545 (while-no-input 545 (if (or (null rem)
546 (unwind-protect 546 (eq (< delta 0) (< rem 0)))
547 (while (< percentage 1) 547 (while-no-input
548 (redisplay t) 548 (unwind-protect
549 (sleep-for between-scroll) 549 (while (< percentage 1)
550 (setq time-elapsed (+ time-elapsed 550 (redisplay t)
551 (- (float-time) last-time)) 551 (sleep-for between-scroll)
552 percentage (/ time-elapsed total-time)) 552 (setq time-elapsed (+ time-elapsed
553 (let ((throw-on-input nil)) 553 (- (float-time) last-time))
554 (if (< delta 0) 554 percentage (/ time-elapsed total-time))
555 (pixel-scroll-precision-scroll-down 555 (let ((throw-on-input nil))
556 (ceiling (abs (* (* delta factor) 556 (if (< delta 0)
557 (/ between-scroll total-time))))) 557 (pixel-scroll-precision-scroll-down
558 (pixel-scroll-precision-scroll-up 558 (ceiling (abs (* (* delta factor)
559 (ceiling (* (* delta factor) 559 (/ between-scroll total-time)))))
560 (/ between-scroll total-time)))))) 560 (pixel-scroll-precision-scroll-up
561 (setq last-time (float-time))) 561 (ceiling (* (* delta factor)
562 (if (< percentage 1) 562 (/ between-scroll total-time))))))
563 (progn 563 (setq last-time (float-time)))
564 (set-window-parameter nil 'interpolated-scroll-remainder 564 (if (< percentage 1)
565 (* delta (- 1 percentage))) 565 (progn
566 (set-window-parameter nil 'interpolated-scroll-remainder-time 566 (set-window-parameter nil 'interpolated-scroll-remainder
567 (float-time))) 567 (* delta (- 1 percentage)))
568 (set-window-parameter nil 568 (set-window-parameter nil 'interpolated-scroll-remainder-time
569 'interpolated-scroll-remainder 569 (float-time)))
570 nil) 570 (set-window-parameter nil
571 (set-window-parameter nil 571 'interpolated-scroll-remainder
572 'interpolated-scroll-remainder-time 572 nil)
573 nil)))))) 573 (set-window-parameter nil
574 'interpolated-scroll-remainder-time
575 nil))))
576 (set-window-parameter nil
577 'interpolated-scroll-remainder
578 nil)
579 (set-window-parameter nil
580 'interpolated-scroll-remainder-time
581 nil))))
574 582
575(defun pixel-scroll-precision-scroll-up (delta) 583(defun pixel-scroll-precision-scroll-up (delta)
576 "Scroll the current window up by DELTA pixels." 584 "Scroll the current window up by DELTA pixels."
diff --git a/lisp/sqlite-mode.el b/lisp/sqlite-mode.el
index 61398c180f7..9306bd85dcd 100644
--- a/lisp/sqlite-mode.el
+++ b/lisp/sqlite-mode.el
@@ -130,7 +130,7 @@
130 (split-string (replace-regexp-in-string "^.*(\\|)$" "" sql) ",")))) 130 (split-string (replace-regexp-in-string "^.*(\\|)$" "" sql) ","))))
131 131
132(defun sqlite-mode-list-data () 132(defun sqlite-mode-list-data ()
133 "List the data from the table under poing." 133 "List the data from the table under point."
134 (interactive nil sqlite-mode) 134 (interactive nil sqlite-mode)
135 (let ((row (and (eq (get-text-property (point) 'sqlite--type) 'table) 135 (let ((row (and (eq (get-text-property (point) 'sqlite--type) 'table)
136 (get-text-property (point) 'sqlite--row)))) 136 (get-text-property (point) 'sqlite--row))))
diff --git a/lisp/subr.el b/lisp/subr.el
index d224f761e1f..9c07606100b 100644
--- a/lisp/subr.el
+++ b/lisp/subr.el
@@ -4057,7 +4057,7 @@ BUFFER is the buffer (or buffer name) to associate with the process.
4057 Process output goes at end of that buffer, unless you specify 4057 Process output goes at end of that buffer, unless you specify
4058 an output stream or filter function to handle the output. 4058 an output stream or filter function to handle the output.
4059 BUFFER may be also nil, meaning that this process is not associated 4059 BUFFER may be also nil, meaning that this process is not associated
4060 with any buffer 4060 with any buffer.
4061COMMAND is the shell command to run." 4061COMMAND is the shell command to run."
4062 ;; We used to use `exec' to replace the shell with the command, 4062 ;; We used to use `exec' to replace the shell with the command,
4063 ;; but that failed to handle (...) and semicolon, etc. 4063 ;; but that failed to handle (...) and semicolon, etc.
diff --git a/src/haikuterm.c b/src/haikuterm.c
index f3c37b0258e..f95a013867f 100644
--- a/src/haikuterm.c
+++ b/src/haikuterm.c
@@ -536,162 +536,6 @@ haiku_draw_relief_rect (struct glyph_string *s,
536} 536}
537 537
538static void 538static void
539haiku_draw_string_box (struct glyph_string *s, int clip_p)
540{
541 int hwidth, vwidth, left_x, right_x, top_y, bottom_y, last_x;
542 bool raised_p, left_p, right_p;
543 struct glyph *last_glyph;
544 struct haiku_rect clip_rect;
545
546 struct face *face = s->face;
547
548 last_x = ((s->row->full_width_p && !s->w->pseudo_window_p)
549 ? WINDOW_RIGHT_EDGE_X (s->w)
550 : window_box_right (s->w, s->area));
551
552 /* The glyph that may have a right box line. For static
553 compositions and images, the right-box flag is on the first glyph
554 of the glyph string; for other types it's on the last glyph. */
555 if (s->cmp || s->img)
556 last_glyph = s->first_glyph;
557 else if (s->first_glyph->type == COMPOSITE_GLYPH
558 && s->first_glyph->u.cmp.automatic)
559 {
560 /* For automatic compositions, we need to look up the last glyph
561 in the composition. */
562 struct glyph *end = s->row->glyphs[s->area] + s->row->used[s->area];
563 struct glyph *g = s->first_glyph;
564 for (last_glyph = g++;
565 g < end && g->u.cmp.automatic && g->u.cmp.id == s->cmp_id
566 && g->slice.cmp.to < s->cmp_to;
567 last_glyph = g++)
568 ;
569 }
570 else
571 last_glyph = s->first_glyph + s->nchars - 1;
572
573 vwidth = eabs (face->box_vertical_line_width);
574 hwidth = eabs (face->box_horizontal_line_width);
575 raised_p = face->box == FACE_RAISED_BOX;
576 left_x = s->x;
577 right_x = (s->row->full_width_p && s->extends_to_end_of_line_p
578 ? last_x - 1
579 : min (last_x, s->x + s->background_width) - 1);
580
581 top_y = s->y;
582 bottom_y = top_y + s->height - 1;
583
584 left_p = (s->first_glyph->left_box_line_p
585 || (s->hl == DRAW_MOUSE_FACE
586 && (s->prev == NULL
587 || s->prev->hl != s->hl)));
588 right_p = (last_glyph->right_box_line_p
589 || (s->hl == DRAW_MOUSE_FACE
590 && (s->next == NULL
591 || s->next->hl != s->hl)));
592
593 get_glyph_string_clip_rect (s, &clip_rect);
594
595 if (face->box == FACE_SIMPLE_BOX)
596 haiku_draw_box_rect (s, left_x, top_y, right_x, bottom_y, hwidth,
597 vwidth, left_p, right_p, &clip_rect);
598 else
599 haiku_draw_relief_rect (s, left_x, top_y, right_x, bottom_y, hwidth,
600 vwidth, raised_p, true, true, left_p, right_p,
601 &clip_rect, 1);
602
603 if (clip_p)
604 {
605 void *view = FRAME_HAIKU_VIEW (s->f);
606 BView_ClipToInverseRect (view, left_x, top_y, right_x - left_x + 1, hwidth);
607 if (left_p)
608 BView_ClipToInverseRect (view, left_x, top_y, vwidth, bottom_y - top_y + 1);
609 BView_ClipToInverseRect (view, left_x, bottom_y - hwidth + 1,
610 right_x - left_x + 1, hwidth);
611 if (right_p)
612 BView_ClipToInverseRect (view, right_x - vwidth + 1,
613 top_y, vwidth, bottom_y - top_y + 1);
614 }
615}
616
617static void
618haiku_draw_plain_background (struct glyph_string *s, struct face *face,
619 int box_line_hwidth, int box_line_vwidth)
620{
621 void *view = FRAME_HAIKU_VIEW (s->f);
622 BView_StartClip (view);
623 if (s->hl == DRAW_CURSOR)
624 BView_SetHighColor (view, FRAME_CURSOR_COLOR (s->f).pixel);
625 else
626 BView_SetHighColor (view, face->background_defaulted_p ?
627 FRAME_BACKGROUND_PIXEL (s->f) :
628 face->background);
629
630 BView_FillRectangle (view, s->x,
631 s->y + box_line_hwidth,
632 s->background_width,
633 s->height - 2 * box_line_hwidth);
634 BView_EndClip (view);
635}
636
637static void
638haiku_draw_stipple_background (struct glyph_string *s, struct face *face,
639 int box_line_hwidth, int box_line_vwidth)
640{
641}
642
643static void
644haiku_maybe_draw_background (struct glyph_string *s, int force_p)
645{
646 if ((s->first_glyph->type != IMAGE_GLYPH) && !s->background_filled_p)
647 {
648 struct face *face = s->face;
649 int box_line_width = max (face->box_horizontal_line_width, 0);
650 int box_vline_width = max (face->box_vertical_line_width, 0);
651
652 if (FONT_HEIGHT (s->font) < s->height - 2 * box_vline_width
653 || FONT_TOO_HIGH (s->font)
654 || s->font_not_found_p || s->extends_to_end_of_line_p || force_p)
655 {
656 if (!face->stipple)
657 haiku_draw_plain_background (s, face, box_line_width,
658 box_vline_width);
659 else
660 haiku_draw_stipple_background (s, face, box_line_width,
661 box_vline_width);
662 s->background_filled_p = 1;
663 }
664 }
665}
666
667static void
668haiku_mouse_face_colors (struct glyph_string *s, uint32_t *fg,
669 uint32_t *bg)
670{
671 int face_id;
672 struct face *face;
673
674 /* What face has to be used last for the mouse face? */
675 face_id = MOUSE_HL_INFO (s->f)->mouse_face_face_id;
676 face = FACE_FROM_ID_OR_NULL (s->f, face_id);
677 if (face == NULL)
678 face = FACE_FROM_ID (s->f, MOUSE_FACE_ID);
679
680 if (s->first_glyph->type == CHAR_GLYPH)
681 face_id = FACE_FOR_CHAR (s->f, face, s->first_glyph->u.ch, -1, Qnil);
682 else
683 face_id = FACE_FOR_CHAR (s->f, face, 0, -1, Qnil);
684
685 face = FACE_FROM_ID (s->f, face_id);
686 prepare_face_for_display (s->f, s->face);
687
688 if (fg)
689 *fg = face->foreground;
690 if (bg)
691 *bg = face->background;
692}
693
694static void
695haiku_draw_underwave (struct glyph_string *s, int width, int x) 539haiku_draw_underwave (struct glyph_string *s, int width, int x)
696{ 540{
697 int wave_height = 3, wave_length = 2; 541 int wave_height = 3, wave_length = 2;
@@ -876,6 +720,164 @@ haiku_draw_text_decoration (struct glyph_string *s, struct face *face,
876} 720}
877 721
878static void 722static void
723haiku_draw_string_box (struct glyph_string *s, int clip_p)
724{
725 int hwidth, vwidth, left_x, right_x, top_y, bottom_y, last_x;
726 bool raised_p, left_p, right_p;
727 struct glyph *last_glyph;
728 struct haiku_rect clip_rect;
729
730 struct face *face = s->face;
731
732 last_x = ((s->row->full_width_p && !s->w->pseudo_window_p)
733 ? WINDOW_RIGHT_EDGE_X (s->w)
734 : window_box_right (s->w, s->area));
735
736 /* The glyph that may have a right box line. For static
737 compositions and images, the right-box flag is on the first glyph
738 of the glyph string; for other types it's on the last glyph. */
739 if (s->cmp || s->img)
740 last_glyph = s->first_glyph;
741 else if (s->first_glyph->type == COMPOSITE_GLYPH
742 && s->first_glyph->u.cmp.automatic)
743 {
744 /* For automatic compositions, we need to look up the last glyph
745 in the composition. */
746 struct glyph *end = s->row->glyphs[s->area] + s->row->used[s->area];
747 struct glyph *g = s->first_glyph;
748 for (last_glyph = g++;
749 g < end && g->u.cmp.automatic && g->u.cmp.id == s->cmp_id
750 && g->slice.cmp.to < s->cmp_to;
751 last_glyph = g++)
752 ;
753 }
754 else
755 last_glyph = s->first_glyph + s->nchars - 1;
756
757 vwidth = eabs (face->box_vertical_line_width);
758 hwidth = eabs (face->box_horizontal_line_width);
759 raised_p = face->box == FACE_RAISED_BOX;
760 left_x = s->x;
761 right_x = (s->row->full_width_p && s->extends_to_end_of_line_p
762 ? last_x - 1
763 : min (last_x, s->x + s->background_width) - 1);
764
765 top_y = s->y;
766 bottom_y = top_y + s->height - 1;
767
768 left_p = (s->first_glyph->left_box_line_p
769 || (s->hl == DRAW_MOUSE_FACE
770 && (s->prev == NULL
771 || s->prev->hl != s->hl)));
772 right_p = (last_glyph->right_box_line_p
773 || (s->hl == DRAW_MOUSE_FACE
774 && (s->next == NULL
775 || s->next->hl != s->hl)));
776
777 get_glyph_string_clip_rect (s, &clip_rect);
778
779 if (face->box == FACE_SIMPLE_BOX)
780 haiku_draw_box_rect (s, left_x, top_y, right_x, bottom_y, hwidth,
781 vwidth, left_p, right_p, &clip_rect);
782 else
783 haiku_draw_relief_rect (s, left_x, top_y, right_x, bottom_y, hwidth,
784 vwidth, raised_p, true, true, left_p, right_p,
785 &clip_rect, 1);
786
787 if (clip_p)
788 {
789 void *view = FRAME_HAIKU_VIEW (s->f);
790
791 haiku_draw_text_decoration (s, face, face->foreground, s->width, s->x);
792 BView_ClipToInverseRect (view, left_x, top_y, right_x - left_x + 1, hwidth);
793 if (left_p)
794 BView_ClipToInverseRect (view, left_x, top_y, vwidth, bottom_y - top_y + 1);
795 BView_ClipToInverseRect (view, left_x, bottom_y - hwidth + 1,
796 right_x - left_x + 1, hwidth);
797 if (right_p)
798 BView_ClipToInverseRect (view, right_x - vwidth + 1,
799 top_y, vwidth, bottom_y - top_y + 1);
800 }
801}
802
803static void
804haiku_draw_plain_background (struct glyph_string *s, struct face *face,
805 int box_line_hwidth, int box_line_vwidth)
806{
807 void *view = FRAME_HAIKU_VIEW (s->f);
808 BView_StartClip (view);
809 if (s->hl == DRAW_CURSOR)
810 BView_SetHighColor (view, FRAME_CURSOR_COLOR (s->f).pixel);
811 else
812 BView_SetHighColor (view, face->background_defaulted_p ?
813 FRAME_BACKGROUND_PIXEL (s->f) :
814 face->background);
815
816 BView_FillRectangle (view, s->x,
817 s->y + box_line_hwidth,
818 s->background_width,
819 s->height - 2 * box_line_hwidth);
820 BView_EndClip (view);
821}
822
823static void
824haiku_draw_stipple_background (struct glyph_string *s, struct face *face,
825 int box_line_hwidth, int box_line_vwidth)
826{
827}
828
829static void
830haiku_maybe_draw_background (struct glyph_string *s, int force_p)
831{
832 if ((s->first_glyph->type != IMAGE_GLYPH) && !s->background_filled_p)
833 {
834 struct face *face = s->face;
835 int box_line_width = max (face->box_horizontal_line_width, 0);
836 int box_vline_width = max (face->box_vertical_line_width, 0);
837
838 if (FONT_HEIGHT (s->font) < s->height - 2 * box_vline_width
839 || FONT_TOO_HIGH (s->font)
840 || s->font_not_found_p || s->extends_to_end_of_line_p || force_p)
841 {
842 if (!face->stipple)
843 haiku_draw_plain_background (s, face, box_line_width,
844 box_vline_width);
845 else
846 haiku_draw_stipple_background (s, face, box_line_width,
847 box_vline_width);
848 s->background_filled_p = 1;
849 }
850 }
851}
852
853static void
854haiku_mouse_face_colors (struct glyph_string *s, uint32_t *fg,
855 uint32_t *bg)
856{
857 int face_id;
858 struct face *face;
859
860 /* What face has to be used last for the mouse face? */
861 face_id = MOUSE_HL_INFO (s->f)->mouse_face_face_id;
862 face = FACE_FROM_ID_OR_NULL (s->f, face_id);
863 if (face == NULL)
864 face = FACE_FROM_ID (s->f, MOUSE_FACE_ID);
865
866 if (s->first_glyph->type == CHAR_GLYPH)
867 face_id = FACE_FOR_CHAR (s->f, face, s->first_glyph->u.ch, -1, Qnil);
868 else
869 face_id = FACE_FOR_CHAR (s->f, face, 0, -1, Qnil);
870
871 face = FACE_FROM_ID (s->f, face_id);
872 prepare_face_for_display (s->f, s->face);
873
874 if (fg)
875 *fg = face->foreground;
876 if (bg)
877 *bg = face->background;
878}
879
880static void
879haiku_draw_glyph_string_foreground (struct glyph_string *s) 881haiku_draw_glyph_string_foreground (struct glyph_string *s)
880{ 882{
881 struct face *face = s->face; 883 struct face *face = s->face;
@@ -1557,14 +1559,11 @@ haiku_draw_glyph_string (struct glyph_string *s)
1557 1559
1558 if (!box_filled_p && face->box != FACE_NO_BOX) 1560 if (!box_filled_p && face->box != FACE_NO_BOX)
1559 haiku_draw_string_box (s, 1); 1561 haiku_draw_string_box (s, 1);
1562 else
1563 haiku_draw_text_decoration (s, face, face->foreground, s->width, s->x);
1560 1564
1561 if (!s->for_overlaps) 1565 if (!s->for_overlaps)
1562 { 1566 {
1563 uint32_t dcol;
1564 dcol = face->foreground;
1565
1566 haiku_draw_text_decoration (s, face, dcol, s->width, s->x);
1567
1568 if (s->prev) 1567 if (s->prev)
1569 { 1568 {
1570 struct glyph_string *prev; 1569 struct glyph_string *prev;
diff --git a/src/w32.c b/src/w32.c
index 2b2f8aadf6b..1de148f0343 100644
--- a/src/w32.c
+++ b/src/w32.c
@@ -8548,7 +8548,7 @@ fcntl (int s, int cmd, int options)
8548int 8548int
8549sys_close (int fd) 8549sys_close (int fd)
8550{ 8550{
8551 int rc; 8551 int rc = -1;
8552 8552
8553 if (fd < 0) 8553 if (fd < 0)
8554 { 8554 {
@@ -8603,14 +8603,31 @@ sys_close (int fd)
8603 } 8603 }
8604 } 8604 }
8605 8605
8606 if (fd >= 0 && fd < MAXDESC)
8607 fd_info[fd].flags = 0;
8608
8609 /* Note that sockets do not need special treatment here (at least on 8606 /* Note that sockets do not need special treatment here (at least on
8610 NT and Windows 95 using the standard tcp/ip stacks) - it appears that 8607 NT and Windows 95 using the standard tcp/ip stacks) - it appears that
8611 closesocket is equivalent to CloseHandle, which is to be expected 8608 closesocket is equivalent to CloseHandle, which is to be expected
8612 because socket handles are fully fledged kernel handles. */ 8609 because socket handles are fully fledged kernel handles. */
8613 rc = _close (fd); 8610 if (fd < MAXDESC)
8611 {
8612 if ((fd_info[fd].flags & FILE_DONT_CLOSE) == 0)
8613 {
8614 fd_info[fd].flags = 0;
8615 rc = _close (fd);
8616 }
8617 else
8618 {
8619 /* We don't close here descriptors open by pipe processes
8620 for reading from the pipe, because the reader thread
8621 might be stuck in _sys_read_ahead, and then we will hang
8622 here. If the reader thread exits normally, it will close
8623 the descriptor; otherwise we will leave a zombie thread
8624 hanging around. */
8625 rc = 0;
8626 /* Leave the flag set for the reader thread to close the
8627 descriptor. */
8628 fd_info[fd].flags = FILE_DONT_CLOSE;
8629 }
8630 }
8614 8631
8615 return rc; 8632 return rc;
8616} 8633}
@@ -10898,6 +10915,7 @@ register_aux_fd (int infd)
10898 } 10915 }
10899 fd_info[ infd ].cp = cp; 10916 fd_info[ infd ].cp = cp;
10900 fd_info[ infd ].hnd = (HANDLE) _get_osfhandle (infd); 10917 fd_info[ infd ].hnd = (HANDLE) _get_osfhandle (infd);
10918 fd_info[ infd ].flags |= FILE_DONT_CLOSE;
10901} 10919}
10902 10920
10903#ifdef HAVE_GNUTLS 10921#ifdef HAVE_GNUTLS
diff --git a/src/w32.h b/src/w32.h
index b31d66646c9..bb3ec40324a 100644
--- a/src/w32.h
+++ b/src/w32.h
@@ -135,6 +135,7 @@ extern filedesc fd_info [ MAXDESC ];
135#define FILE_SOCKET 0x0200 135#define FILE_SOCKET 0x0200
136#define FILE_NDELAY 0x0400 136#define FILE_NDELAY 0x0400
137#define FILE_SERIAL 0x0800 137#define FILE_SERIAL 0x0800
138#define FILE_DONT_CLOSE 0x1000
138 139
139extern child_process * new_child (void); 140extern child_process * new_child (void);
140extern void delete_child (child_process *cp); 141extern void delete_child (child_process *cp);
diff --git a/src/w32proc.c b/src/w32proc.c
index 360f45e9e11..bfe720eb623 100644
--- a/src/w32proc.c
+++ b/src/w32proc.c
@@ -1206,6 +1206,7 @@ static DWORD WINAPI
1206reader_thread (void *arg) 1206reader_thread (void *arg)
1207{ 1207{
1208 child_process *cp; 1208 child_process *cp;
1209 int fd;
1209 1210
1210 /* Our identity */ 1211 /* Our identity */
1211 cp = (child_process *)arg; 1212 cp = (child_process *)arg;
@@ -1220,12 +1221,13 @@ reader_thread (void *arg)
1220 { 1221 {
1221 int rc; 1222 int rc;
1222 1223
1223 if (cp->fd >= 0 && (fd_info[cp->fd].flags & FILE_CONNECT) != 0) 1224 fd = cp->fd;
1224 rc = _sys_wait_connect (cp->fd); 1225 if (fd >= 0 && (fd_info[fd].flags & FILE_CONNECT) != 0)
1225 else if (cp->fd >= 0 && (fd_info[cp->fd].flags & FILE_LISTEN) != 0) 1226 rc = _sys_wait_connect (fd);
1226 rc = _sys_wait_accept (cp->fd); 1227 else if (fd >= 0 && (fd_info[fd].flags & FILE_LISTEN) != 0)
1228 rc = _sys_wait_accept (fd);
1227 else 1229 else
1228 rc = _sys_read_ahead (cp->fd); 1230 rc = _sys_read_ahead (fd);
1229 1231
1230 /* Don't bother waiting for the event if we already have been 1232 /* Don't bother waiting for the event if we already have been
1231 told to exit by delete_child. */ 1233 told to exit by delete_child. */
@@ -1238,7 +1240,7 @@ reader_thread (void *arg)
1238 { 1240 {
1239 DebPrint (("reader_thread.SetEvent(0x%x) failed with %lu for fd %ld (PID %d)\n", 1241 DebPrint (("reader_thread.SetEvent(0x%x) failed with %lu for fd %ld (PID %d)\n",
1240 (DWORD_PTR)cp->char_avail, GetLastError (), 1242 (DWORD_PTR)cp->char_avail, GetLastError (),
1241 cp->fd, cp->pid)); 1243 fd, cp->pid));
1242 return 1; 1244 return 1;
1243 } 1245 }
1244 1246
@@ -1266,6 +1268,13 @@ reader_thread (void *arg)
1266 if (cp->status == STATUS_READ_ERROR) 1268 if (cp->status == STATUS_READ_ERROR)
1267 break; 1269 break;
1268 } 1270 }
1271 /* If this thread was reading from a pipe process, close the
1272 descriptor used for reading, as sys_close doesn't in that case. */
1273 if (fd_info[fd].flags == FILE_DONT_CLOSE)
1274 {
1275 fd_info[fd].flags = 0;
1276 _close (fd);
1277 }
1269 return 0; 1278 return 0;
1270} 1279}
1271 1280
diff --git a/test/lisp/emacs-lisp/bytecomp-tests.el b/test/lisp/emacs-lisp/bytecomp-tests.el
index 7e51f820b70..a442eb473be 100644
--- a/test/lisp/emacs-lisp/bytecomp-tests.el
+++ b/test/lisp/emacs-lisp/bytecomp-tests.el
@@ -686,6 +686,12 @@ inner loops respectively."
686 (let* ((x 'a)) 686 (let* ((x 'a))
687 (list x (funcall g) (funcall h))))))) 687 (list x (funcall g) (funcall h)))))))
688 (funcall (funcall f 'b))) 688 (funcall (funcall f 'b)))
689
690 ;; Test constant-propagation of access to captured variables.
691 (let* ((x 2)
692 (f (lambda ()
693 (let ((y x)) (list y 3 y)))))
694 (funcall f))
689 ) 695 )
690 "List of expressions for cross-testing interpreted and compiled code.") 696 "List of expressions for cross-testing interpreted and compiled code.")
691 697