Mercurial > hg > xemacs-beta
annotate src/redisplay-msw.c @ 5353:38e24b8be4ea
Improve the lexical scoping in #'block, #'return-from.
lisp/ChangeLog addition:
2011-02-07 Aidan Kehoe <kehoea@parhasard.net>
* bytecomp.el:
* bytecomp.el (byte-compile-initial-macro-environment):
Shadow `block', `return-from' here, we implement them differently
when byte-compiling.
* bytecomp.el (byte-compile-active-blocks): New.
* bytecomp.el (byte-compile-block-1): New.
* bytecomp.el (byte-compile-return-from-1): New.
* bytecomp.el (return-from-1): New.
* bytecomp.el (block-1): New.
These are two aliases that exist to have their own associated
byte-compile functions, which functions implement `block' and
`return-from'.
* cl-extra.el (cl-macroexpand-all):
Fix a bug here when macros in the environment have been compiled.
* cl-macs.el (block):
* cl-macs.el (return):
* cl-macs.el (return-from):
Be more careful about lexical scope in these macros.
* cl.el:
* cl.el ('cl-block-wrapper): Removed.
* cl.el ('cl-block-throw): Removed.
These aren't needed in code generated by this XEmacs. They
shouldn't be needed in code generated by XEmacs 21.4, but if it
turns out the packages do need them, we can put them back.
2011-01-30 Mike Sperber <mike@xemacs.org>
* font-lock.el (font-lock-fontify-pending-extents): Don't fail if
`font-lock-mode' is unset, which can happen in the middle of
`revert-buffer'.
2011-01-23 Aidan Kehoe <kehoea@parhasard.net>
* cl-macs.el (delete):
* cl-macs.el (delq):
* cl-macs.el (remove):
* cl-macs.el (remq):
Don't use the compiler macro if these functions were given the
wrong number of arguments, as happens in lisp-tests.el.
* cl-seq.el (remove, remq): Removed.
I added these to subr.el, and forgot to remove them from here.
2011-01-22 Aidan Kehoe <kehoea@parhasard.net>
* bytecomp.el (byte-compile-setq, byte-compile-set):
Remove kludge allowing keywords' values to be set, all the code
that does that is gone.
* cl-compat.el (elt-satisfies-test-p):
* faces.el (set-face-parent):
* faces.el (face-doc-string):
* gtk-font-menu.el:
* gtk-font-menu.el (gtk-reset-device-font-menus):
* msw-font-menu.el:
* msw-font-menu.el (mswindows-reset-device-font-menus):
* package-get.el (package-get-installedp):
* select.el (select-convert-from-image-data):
* sound.el:
* sound.el (load-sound-file):
* x-font-menu.el (x-reset-device-font-menus-core):
Don't quote keywords, they're self-quoting, and the
win from backward-compatibility is sufficiently small now that the
style problem overrides it.
2011-01-22 Aidan Kehoe <kehoea@parhasard.net>
* cl-macs.el (block, return-from): Require that NAME be a symbol
in these macros, as always documented in the #'block docstring and
as required by Common Lisp.
* descr-text.el (unidata-initialize-unihan-database):
Correct the use of non-symbols in #'block and #'return-from in
this function.
2011-01-15 Aidan Kehoe <kehoea@parhasard.net>
* cl-extra.el (concatenate): Accept more complicated TYPEs in this
function, handing the sequences over to #'coerce if we don't
understand them here.
* cl-macs.el (inline): Don't proclaim #'concatenate as inline, its
compiler macro is more useful than doing that.
2011-01-11 Aidan Kehoe <kehoea@parhasard.net>
* subr.el (delete, delq, remove, remq): Move #'remove, #'remq
here, they don't belong in cl-seq.el; move #'delete, #'delq here
from fns.c, implement them in terms of #'delete*, allowing support
for sequences generally.
* update-elc.el (do-autoload-commands): Use #'delete*, not #'delq
here, now the latter's no longer dumped.
* cl-macs.el (delete, delq): Add compiler macros transforming
#'delete and #'delq to #'delete* calls.
2011-01-10 Aidan Kehoe <kehoea@parhasard.net>
* dialog.el (make-dialog-box): Correct a misplaced parenthesis
here, thank you Mats Lidell in 87zkr9gqrh.fsf@mail.contactor.se !
2011-01-02 Aidan Kehoe <kehoea@parhasard.net>
* dialog.el (make-dialog-box):
* list-mode.el (display-completion-list):
These functions used to use cl-parsing-keywords; change them to
use defun* instead, fixing the build. (Not sure what led to me
not including this change in d1b17a33450b!)
2011-01-02 Aidan Kehoe <kehoea@parhasard.net>
* cl-macs.el (define-star-compiler-macros):
Make sure the form has ITEM and LIST specified before attempting
to change to calls with explicit tests; necessary for some tests
in lisp-tests.el to compile correctly.
(stable-union, stable-intersection): Add compiler macros for these
functions, in the same way we do for most of the other functions
in cl-seq.el.
2011-01-01 Aidan Kehoe <kehoea@parhasard.net>
* cl-macs.el (dolist, dotimes, do-symbols, macrolet)
(symbol-macrolet):
Define these macros with defmacro* instead of parsing the argument
list by hand, for the sake of style and readability; use backquote
where appropriate, instead of calling #'list and and friends, for
the same reason.
2010-12-30 Aidan Kehoe <kehoea@parhasard.net>
* x-misc.el (device-x-display):
Provide this function, documented in the Lispref for years, but
not existing previously. Thank you Julian Bradfield, thank you
Jeff Mincy.
2010-12-30 Aidan Kehoe <kehoea@parhasard.net>
* cl-seq.el:
Move the heavy lifting from this file to C. Dump the
cl-parsing-keywords macro, but don't use defun* for the functions
we define that do take keywords, dynamic scope lossage makes that
not practical.
* subr.el (sort, fillarray): Move these aliases here.
(map-plist): #'nsublis is now built-in, but at this point #'eql
isn't necessarily available as a test; use #'eq.
* obsolete.el (cl-delete-duplicates): Make this available for old
compiler macros and old code.
(memql): Document that this is equivalent to #'member*, and worse.
* cl.el (adjoin, subst): Removed. These are in C.
2010-12-30 Aidan Kehoe <kehoea@parhasard.net>
* simple.el (assoc-ignore-case): Remove a duplicate definition of
this function (it's already in subr.el).
* iso8859-1.el (char-width):
On non-Mule, make this function equivalent to that produced by
(constantly 1), but preserve its docstring.
* subr.el (subst-char-in-string): Define this in terms of
#'substitute, #'nsubstitute.
(string-width): Define this using #'reduce and #'char-width.
(char-width): Give this a simpler definition, it makes far more
sense to check for mule at load time and redefine, as we do in
iso8859-1.el.
(store-substring): Implement this in terms of #'replace, now
#'replace is cheap.
2010-12-30 Aidan Kehoe <kehoea@parhasard.net>
* update-elc.el (lisp-files-needed-for-byte-compilation)
(lisp-files-needing-early-byte-compilation):
cl-macs belongs in the former, not the latter, it is as
fundamental as bytecomp.el.
2010-12-30 Aidan Kehoe <kehoea@parhasard.net>
* cl.el:
Provde the Common Lisp program-error, type-error as error
symbols. This doesn't nearly go far enough for anyone using the
Common Lisp errors.
2010-12-29 Aidan Kehoe <kehoea@parhasard.net>
* cl-macs.el (delete-duplicates):
If the form has an incorrect number of arguments, don't attempt a
compiler macroexpansion.
2010-12-29 Aidan Kehoe <kehoea@parhasard.net>
* cl-macs.el (cl-safe-expr-p):
Forms that start with the symbol lambda are also safe.
2010-12-29 Aidan Kehoe <kehoea@parhasard.net>
* cl-macs.el (= < > <= >=):
For these functions' compiler macros, the optimisation is safe
even if the first and the last arguments have side effects, since
they're only used the once.
2010-12-29 Aidan Kehoe <kehoea@parhasard.net>
* cl-macs.el (inline-side-effect-free-compiler-macros):
Unroll a loop here at macro-expansion time, so these compiler
macros are compiled. Use #'eql instead of #'eq in a couple of
places for better style.
2010-12-29 Aidan Kehoe <kehoea@parhasard.net>
* cl-extra.el (notany, notevery): Avoid some dynamic scope
stupidity with local variable names in these functions, when they
weren't prefixed with cl-; go into some more detail in the doc
strings.
2010-12-29 Aidan Kehoe <kehoea@parhasard.net>
* byte-optimize.el (side-effect-free-fns): #'remove, #'remq are
free of side-effects.
(side-effect-and-error-free-fns):
Drop dot, dot-marker from the list.
2010-11-17 Aidan Kehoe <kehoea@parhasard.net>
* cl-extra.el (coerce):
In the argument list, name the first argument OBJECT, not X; the
former name was always used in the doc string and is clearer.
Handle vector type specifications which include the length of the
target sequence, error if there's a mismatch.
* cl-macs.el (cl-make-type-test): Handle type specifications
starting with the symbol 'eql.
2010-11-14 Aidan Kehoe <kehoea@parhasard.net>
* cl-macs.el (eql): Don't remove the byte-compile property of this
symbol. That was necessary to override a bug in bytecomp.el where
#'eql was confused with #'eq, which bug we no longer have.
If neither expression is constant, don't attempt to handle the
expression in this compiler macro, leave it to byte-compile-eql,
which produces better code anyway.
* bytecomp.el (eq): #'eql is not the function associated with the
byte-eq byte code.
(byte-compile-eql): Add an explicit compile method for this
function, for cases where the cl-macs compiler macro hasn't
reduced it to #'eq or #'equal.
2010-10-25 Aidan Kehoe <kehoea@parhasard.net>
Add compiler macros and compilation sanity-checking for various
functions that take keywords.
* byte-optimize.el (side-effect-free-fns): #'symbol-value is
side-effect free and not error free.
* bytecomp.el (byte-compile-normal-call): Check keyword argument
lists for sanity; store information about the positions where
keyword arguments start using the new byte-compile-keyword-start
property.
* cl-macs.el (cl-const-expr-val): Take a new optional argument,
cl-not-constant, defaulting to nil, in this function; return it if
the expression is not constant.
(cl-non-fixnum-number-p): Make this into a separate function, we
want to pass it to #'every.
(eql): Use it.
(define-star-compiler-macros): Use the same code to generate the
member*, assoc* and rassoc* compiler macros; special-case some
code in #'add-to-list in subr.el.
(remove, remq): Add compiler macros for these two functions, in
preparation for #'remove being in C.
(define-foo-if-compiler-macros): Transform (remove-if-not ...) calls to
(remove ... :if-not) at compile time, which will be a real win
once the latter is in C.
(define-substitute-if-compiler-macros)
(define-subst-if-compiler-macros): Similarly for these functions.
(delete-duplicates): Change this compiler macro to use
#'plists-equal; if we don't have information about the type of
SEQUENCE at compile time, don't bother attempting to inline the
call, the function will be in C soon enough.
(equalp): Remove an old commented-out compiler macro for this, if
we want to see it it's in version control.
(subst-char-in-string): Transform this to a call to nsubstitute or
nsubstitute, if that is appropriate.
* cl.el (ldiff): Don't call setf here, this makes for a load-time
dependency problem in cl-macs.el
2010-06-14 Stephen J. Turnbull <stephen@xemacs.org>
* term/vt100.el:
Refer to XEmacs, not GNU Emacs, in permissions.
* term/bg-mouse.el:
* term/sup-mouse.el:
Put copyright notice in canonical "Copyright DATE AUTHOR" form.
Refer to XEmacs, not GNU Emacs, in permissions.
* site-load.el:
Add permission boilerplate.
* mule/canna-leim.el:
* alist.el:
Refer to XEmacs, not APEL/this program, in permissions.
* mule/canna-leim.el:
Remove my copyright, I've assigned it to the FSF.
2010-06-14 Stephen J. Turnbull <stephen@xemacs.org>
* gtk.el:
* gtk-widget-accessors.el:
* gtk-package.el:
* gtk-marshal.el:
* gtk-compose.el:
* gnome.el:
Add copyright notice based on internal evidence.
2010-06-14 Stephen J. Turnbull <stephen@xemacs.org>
* easymenu.el: Add reference to COPYING to permission notice.
* gutter.el:
* gutter-items.el:
* menubar-items.el:
Fix typo "Xmacs" in permissions notice.
2010-06-14 Stephen J. Turnbull <stephen@xemacs.org>
* auto-save.el:
* font.el:
* fontconfig.el:
* mule/kinsoku.el:
Add "part of XEmacs" text to permission notice.
2010-10-14 Aidan Kehoe <kehoea@parhasard.net>
* byte-optimize.el (side-effect-free-fns):
* cl-macs.el (remf, getf):
* cl-extra.el (tailp, cl-set-getf, cl-do-remf):
* cl.el (ldiff, endp):
Tighten up Common Lisp compatibility for #'ldiff, #'endp, #'tailp;
add circularity checking for the first two.
#'cl-set-getf and #'cl-do-remf were Lisp implementations of
#'plist-put and #'plist-remprop; change the names to aliases,
changes the macros that use them to using #'plist-put and
#'plist-remprop directly.
2010-10-12 Aidan Kehoe <kehoea@parhasard.net>
* abbrev.el (fundamental-mode-abbrev-table, global-abbrev-table):
Create both these abbrev tables using the usual
#'define-abbrev-table calls, rather than attempting to
special-case them.
* cl-extra.el: Force cl-macs to be loaded here, if cl-extra.el is
being loaded interpreted. Previously other, later files would
redundantly call (load "cl-macs") when interpreted, it's more
reasonable to do it here, once.
* cmdloop.el (read-quoted-char-radix): Use defcustom here, we
don't have any dump-order dependencies that would prevent that.
* custom.el (eval-when-compile): Don't load cl-macs when
interpreted or when byte-compiling, rely on cl-extra.el in the
former case and the appropriate entry in bytecomp-load-hook in the
latter. Get rid of custom-declare-variable-list, we have no
dump-time dependencies that would require it.
* faces.el (eval-when-compile): Don't load cl-macs when
interpreted or when byte-compiling.
* packages.el: Remove some inaccurate comments.
* post-gc.el (cleanup-simple-finalizers): Use #'delete-if-not
here, now the order of preloaded-file-list has been changed to
make it available.
* subr.el (custom-declare-variable-list): Remove. No need for it.
Also remove a stub define-abbrev-table from this file, given the
current order of preloaded-file-list there's no need for it.
2010-10-10 Aidan Kehoe <kehoea@parhasard.net>
* bytecomp.el (byte-compile-constp) Forms quoted with FUNCTION are
also constant.
(byte-compile-initial-macro-environment): In #'the, if FORM is
constant and does not match TYPE, warn at byte-compile time.
2010-10-10 Aidan Kehoe <kehoea@parhasard.net>
* backquote.el (bq-vector-contents, bq-list*): Remove; the former
is equivalent to (append VECTOR nil), the latter to (list* ...).
(bq-process-2): Use (append VECTOR nil) instead of using
#'bq-vector-contents to convert to a list.
(bq-process-1): Now we use list* instead of bq-list
* subr.el (list*): Moved from cl.el, since it is now required to
be available the first time a backquoted form is encountered.
* cl.el (list*): Move to subr.el.
2010-09-16 Aidan Kehoe <kehoea@parhasard.net>
* test-harness.el (Check-Message):
Add an omitted comma here, thank you the buildbot.
2010-09-16 Aidan Kehoe <kehoea@parhasard.net>
* hash-table.el (hash-table-key-list, hash-table-value-list)
(hash-table-key-value-alist, hash-table-key-value-plist):
Remove some useless #'nreverse calls in these files; our hash
tables have no order, it's not helpful to pretend they do.
* behavior.el (read-behavior):
Do the same in this file, in some code evidently copied from
hash-table.el.
2010-09-16 Aidan Kehoe <kehoea@parhasard.net>
* info.el (Info-insert-dir):
* format.el (format-deannotate-region):
* files.el (cd, save-buffers-kill-emacs):
Use #'some, #'every and related functions for applying boolean
operations to lists, instead of rolling our own ones that cons and
don't short-circuit.
2010-09-16 Aidan Kehoe <kehoea@parhasard.net>
* bytecomp.el (byte-compile-initial-macro-environment):
* cl-macs.el (the):
Rephrase the docstring, make its implementation when compiling
files a little nicer.
2010-09-16 Aidan Kehoe <kehoea@parhasard.net>
* descr-text.el (unidata-initialize-unicodedata-database)
(unidata-initialize-unihan-database, describe-char-unicode-data)
(describe-char-unicode-data):
Wrap calls to the database functions with (with-fboundp ...),
avoiding byte compile warnings on builds without support for the
database functions.
(describe-char): (reduce #'max ...), not (apply #'max ...), no
need to cons needlessly.
(describe-char): Remove a redundant lambda wrapping
#'extent-properties.
(describe-char-unicode-data): Call #'nsubst when replacing "" with
nil in the result of #'split-string, instead of consing inside
mapcar.
2010-09-16 Aidan Kehoe <kehoea@parhasard.net>
* x-faces.el (x-available-font-sizes):
* specifier.el (let-specifier):
* package-ui.el (pui-add-required-packages):
* msw-faces.el (mswindows-available-font-sizes):
* modeline.el (modeline-minor-mode-menu):
* minibuf.el (minibuf-directory-files):
Replace the O2N (delq nil (mapcar (lambda (W) (and X Y)) Z)) with
the ON (mapcan (lambda (W) (and X (list Y))) Z) in these files.
2010-09-16 Aidan Kehoe <kehoea@parhasard.net>
* cl-macs.el (= < > <= >=):
When these functions are handed more than two arguments, and those
arguments have no side effects, transform to a series of two
argument calls, avoiding funcall in the byte-compiled code.
* mule/mule-cmds.el (finish-set-language-environment):
Take advantage of this change in a function called 256 times at
startup.
2010-09-16 Aidan Kehoe <kehoea@parhasard.net>
* bytecomp.el (byte-compile-function-form, byte-compile-quote)
(byte-compile-quote-form):
Warn at compile time, and error at runtime, if a (quote ...) or a
(function ...) form attempts to quote more than one object.
2010-09-16 Aidan Kehoe <kehoea@parhasard.net>
* byte-optimize.el (byte-optimize-apply): Transform (apply 'nconc
(mapcar ...)) to (mapcan ...); warn about use of the first idiom.
* update-elc.el (do-autoload-commands):
* packages.el (packages-find-package-library-path):
* frame.el (frame-list):
* extents.el (extent-descendants):
* etags.el (buffer-tag-table-files):
* dumped-lisp.el (preloaded-file-list):
* device.el (device-list):
* bytecomp-runtime.el (proclaim-inline, proclaim-notinline)
Use #'mapcan, not (apply #'nconc (mapcar ...) in all these files.
* bytecomp-runtime.el (eval-when-compile, eval-and-compile):
In passing, mention that these macros also evaluate the body when
interpreted.
tests/ChangeLog addition:
2011-02-07 Aidan Kehoe <kehoea@parhasard.net>
* automated/lisp-tests.el:
Test lexical scope for `block', `return-from'; add a
Known-Bug-Expect-Failure for a contorted example that fails when
byte-compiled.
author | Aidan Kehoe <kehoea@parhasard.net> |
---|---|
date | Mon, 07 Feb 2011 12:01:24 +0000 |
parents | 97eb4942aec8 |
children | 308d34e9f07d |
rev | line source |
---|---|
428 | 1 /* mswindows output and frame manipulation routines. |
2 Copyright (C) 1994, 1995 Board of Trustees, University of Illinois. | |
3 Copyright (C) 1994 Lucid, Inc. | |
4 Copyright (C) 1995 Sun Microsystems, Inc. | |
5046 | 5 Copyright (C) 2001, 2002, 2003, 2010 Ben Wing. |
428 | 6 |
7 This file is part of XEmacs. | |
8 | |
9 XEmacs is free software; you can redistribute it and/or modify it | |
10 under the terms of the GNU General Public License as published by the | |
11 Free Software Foundation; either version 2, or (at your option) any | |
12 later version. | |
13 | |
14 XEmacs is distributed in the hope that it will be useful, but WITHOUT | |
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
17 for more details. | |
18 | |
19 You should have received a copy of the GNU General Public License | |
20 along with XEmacs; see the file COPYING. If not, write to | |
21 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, | |
22 Boston, MA 02111-1307, USA. */ | |
23 | |
24 /* Synched up with: Not in FSF. */ | |
25 | |
771 | 26 /* I think this file is essentially Mule-ized, but I'm not sure! |
27 Could stand a good once-over. Unicode support is trash, of course. */ | |
28 | |
428 | 29 /* Authorship: |
30 | |
31 Chuck Thompson | |
32 Lots of work done by Ben Wing for Mule | |
442 | 33 |
34 Partially rewritten for mswindows by Jonathan Harris, November 1997 | |
35 for 21.0. */ | |
428 | 36 |
37 #include <config.h> | |
38 #include "lisp.h" | |
39 | |
40 #include "buffer.h" | |
800 | 41 #include "charset.h" |
428 | 42 #include "debug.h" |
872 | 43 #include "device-impl.h" |
428 | 44 #include "events.h" |
45 #include "faces.h" | |
872 | 46 #include "frame-impl.h" |
428 | 47 #include "gutter.h" |
48 #include "redisplay.h" | |
49 #include "sysdep.h" | |
872 | 50 #include "window-impl.h" |
800 | 51 |
872 | 52 #include "console-msw-impl.h" |
800 | 53 #include "glyphs-msw.h" |
5176
8b2f75cecb89
rename objects* (.c, .h and .el files) to fontcolor*
Ben Wing <ben@xemacs.org>
parents:
5046
diff
changeset
|
54 #include "fontcolor-msw-impl.h" |
428 | 55 |
56 #define MSWINDOWS_EOL_CURSOR_WIDTH 5 | |
57 | |
58 /* | |
59 * Random forward declarations | |
60 */ | |
440 | 61 static void mswindows_update_dc (HDC hdc, Lisp_Object fg, Lisp_Object bg, |
62 Lisp_Object bg_pmap); | |
63 static void mswindows_set_dc_font (HDC hdc, Lisp_Object font, | |
64 int under, int strike); | |
428 | 65 static void mswindows_output_vertical_divider (struct window *w, int clear); |
66 static void mswindows_output_dibitmap (struct frame *f, | |
440 | 67 Lisp_Image_Instance *p, |
771 | 68 struct display_box *db, |
69 struct display_glyph_area *dga); | |
428 | 70 |
71 typedef struct textual_run | |
72 { | |
771 | 73 Lisp_Object charset; /* charset of this run */ |
74 WCHAR *ptr; /* pointer to Unicode chars in this run */ | |
75 int nchars; /* number of internal characters in this run */ | |
76 int nwchars; /* number of Unicode chars in this run */ | |
428 | 77 } textual_run; |
78 | |
771 | 79 /* Separate out the text in STR into a series of textual runs of a |
80 particular charset. Returns the number of runs actually used. | |
81 Returns the textual runs (STATICALLY ALLOCATED!) in RUN_STORAGE_PTR. */ | |
428 | 82 |
83 static int | |
771 | 84 separate_textual_runs (textual_run **run_storage_ptr, |
867 | 85 const Ichar *str, Charcount len) |
428 | 86 { |
771 | 87 static WCHAR *ext_storage; |
88 static int ext_storage_size; /* in WCHARS! */ | |
89 static textual_run *run_storage; | |
90 static int run_storage_size; | |
428 | 91 int runs_so_far = 0; |
771 | 92 int runbegin = 0; |
93 int total_nchars = 0; | |
428 | 94 int i; |
771 | 95 Lisp_Object prev_charset; |
428 | 96 |
771 | 97 if (len == 0) |
98 return 0; | |
99 | |
867 | 100 prev_charset = ichar_charset (str[0]); |
428 | 101 |
771 | 102 for (i = 1; i <= len; i++) |
103 { | |
867 | 104 if (i == len || !EQ (ichar_charset (str[i]), prev_charset)) |
428 | 105 { |
771 | 106 int j; |
867 | 107 Ibyte *int_storage = |
108 alloca_ibytes (MAX_ICHAR_LEN * (i - runbegin)); | |
771 | 109 int int_storage_ptr = 0; |
110 Extbyte *alloca_ext_storage; | |
111 int nchars; | |
428 | 112 |
771 | 113 int_storage_ptr = 0; |
114 for (j = runbegin; j < i; j++) | |
115 int_storage_ptr += | |
867 | 116 set_itext_ichar (int_storage + int_storage_ptr, str[j]); |
771 | 117 TO_EXTERNAL_FORMAT (DATA, (int_storage, int_storage_ptr), |
118 ALLOCA, (alloca_ext_storage, nchars), | |
119 Qmswindows_unicode); | |
120 nchars /= sizeof (WCHAR); /* Tricky ... */ | |
121 DO_REALLOC (ext_storage, ext_storage_size, total_nchars + nchars, | |
122 WCHAR); | |
123 memcpy (ext_storage + total_nchars, alloca_ext_storage, | |
124 nchars * sizeof (WCHAR)); | |
125 DO_REALLOC (run_storage, run_storage_size, runs_so_far + 1, | |
126 textual_run); | |
127 run_storage[runs_so_far].ptr = ext_storage + total_nchars; | |
128 run_storage[runs_so_far].charset = prev_charset; | |
129 run_storage[runs_so_far].nwchars = nchars; | |
130 run_storage[runs_so_far].nchars = i - runbegin; | |
131 total_nchars += nchars; | |
428 | 132 runs_so_far++; |
771 | 133 runbegin = i; |
134 if (i < len) | |
867 | 135 prev_charset = ichar_charset (str[i]); |
428 | 136 } |
137 } | |
138 | |
771 | 139 *run_storage_ptr = run_storage; |
428 | 140 return runs_so_far; |
141 } | |
142 | |
143 | |
144 static int | |
145 mswindows_text_width_single_run (HDC hdc, struct face_cachel *cachel, | |
146 textual_run *run) | |
147 { | |
148 Lisp_Object font_inst = FACE_CACHEL_FONT (cachel, run->charset); | |
149 SIZE size; | |
150 | |
4476
dbf79a1732ba
Don't try to get text width for the null font instance, mswindows
Aidan Kehoe <kehoea@parhasard.net>
parents:
3479
diff
changeset
|
151 /* The X11 code doesn't have to do this explicitly, because there we trust |
dbf79a1732ba
Don't try to get text width for the null font instance, mswindows
Aidan Kehoe <kehoea@parhasard.net>
parents:
3479
diff
changeset
|
152 the font instance to know whether it's actually proportional or not, |
dbf79a1732ba
Don't try to get text width for the null font instance, mswindows
Aidan Kehoe <kehoea@parhasard.net>
parents:
3479
diff
changeset
|
153 and we use the zero width that is stored in the monospace null font |
dbf79a1732ba
Don't try to get text width for the null font instance, mswindows
Aidan Kehoe <kehoea@parhasard.net>
parents:
3479
diff
changeset
|
154 instance. */ |
dbf79a1732ba
Don't try to get text width for the null font instance, mswindows
Aidan Kehoe <kehoea@parhasard.net>
parents:
3479
diff
changeset
|
155 if (EQ (Vthe_null_font_instance, font_inst)) |
dbf79a1732ba
Don't try to get text width for the null font instance, mswindows
Aidan Kehoe <kehoea@parhasard.net>
parents:
3479
diff
changeset
|
156 { |
dbf79a1732ba
Don't try to get text width for the null font instance, mswindows
Aidan Kehoe <kehoea@parhasard.net>
parents:
3479
diff
changeset
|
157 return 0; |
dbf79a1732ba
Don't try to get text width for the null font instance, mswindows
Aidan Kehoe <kehoea@parhasard.net>
parents:
3479
diff
changeset
|
158 } |
dbf79a1732ba
Don't try to get text width for the null font instance, mswindows
Aidan Kehoe <kehoea@parhasard.net>
parents:
3479
diff
changeset
|
159 |
2367 | 160 #if 0 /* #### not the way of ikeyama's ws */ |
428 | 161 if (!fi->proportional_p || !hdc) |
771 | 162 { |
163 if (XCHARSET_DIMENSION (run->charset) == 2) | |
164 /* Don't trust FONT_INSTANCE_WIDTH. Asian fonts have both of | |
165 one and two column characters. */ | |
166 goto the_hard_way; | |
167 else | |
168 return fi->width * run->nchars; | |
169 } | |
428 | 170 else |
171 { | |
771 | 172 the_hard_way: |
173 #endif | |
440 | 174 mswindows_set_dc_font (hdc, font_inst, |
175 cachel->underline, cachel->strikethru); | |
771 | 176 GetTextExtentPoint32W (hdc, run->ptr, run->nwchars, &size); |
177 return size.cx; | |
2367 | 178 #if 0 /* #### not the way of ikeyama's ws */ |
428 | 179 } |
771 | 180 #endif |
428 | 181 } |
182 | |
440 | 183 /* |
184 * Given F, retrieve device context. F can be a display frame, or | |
442 | 185 * a print job. For a print job, page is also started when printer's |
186 * device context is first time requested. | |
440 | 187 */ |
188 static HDC | |
442 | 189 get_frame_dc (struct frame *f, int start_page_p) |
440 | 190 { |
191 if (FRAME_MSWINDOWS_P (f)) | |
192 return FRAME_MSWINDOWS_DC (f); | |
193 else | |
442 | 194 { |
195 if (start_page_p && !FRAME_MSPRINTER_PAGE_STARTED (f)) | |
196 msprinter_start_page (f); | |
197 return DEVICE_MSPRINTER_HDC (XDEVICE (FRAME_DEVICE (f))); | |
198 } | |
440 | 199 } |
200 | |
201 /* | |
202 * Given F, retrieve compatible device context. F can be a display | |
203 * frame, or a print job. | |
204 */ | |
205 static HDC | |
206 get_frame_compdc (struct frame *f) | |
207 { | |
442 | 208 struct device *d = XDEVICE (FRAME_DEVICE (f)); |
209 if (DEVICE_MSWINDOWS_P (d)) | |
210 return DEVICE_MSWINDOWS_HCDC (d); | |
440 | 211 else |
442 | 212 return DEVICE_MSPRINTER_HCDC (d); |
440 | 213 } |
428 | 214 |
215 /***************************************************************************** | |
216 mswindows_update_dc | |
217 | |
218 Given a number of parameters munge the DC so it has those properties. | |
219 ****************************************************************************/ | |
220 static void | |
440 | 221 mswindows_update_dc (HDC hdc, Lisp_Object fg, Lisp_Object bg, |
2286 | 222 Lisp_Object UNUSED (bg_pmap)) |
428 | 223 { |
224 if (!NILP (fg)) | |
225 { | |
226 SetTextColor (hdc, COLOR_INSTANCE_MSWINDOWS_COLOR | |
227 (XCOLOR_INSTANCE (fg))); | |
228 } | |
440 | 229 |
428 | 230 if (!NILP (bg)) |
231 { | |
232 SetBkMode (hdc, OPAQUE); | |
233 SetBkColor (hdc, COLOR_INSTANCE_MSWINDOWS_COLOR (XCOLOR_INSTANCE (bg))); | |
234 } | |
235 else | |
236 { | |
237 SetBkMode (hdc, TRANSPARENT); | |
238 } | |
239 } | |
240 | |
771 | 241 static void |
242 mswindows_set_dc_font (HDC hdc, Lisp_Object font, int under, int strike) | |
428 | 243 { |
771 | 244 SelectObject (hdc, mswindows_get_hfont (XFONT_INSTANCE (font), |
245 under, strike)); | |
428 | 246 } |
247 | |
248 /***************************************************************************** | |
249 mswindows_output_hline | |
250 | |
251 Output a horizontal line in the foreground of its face. | |
252 ****************************************************************************/ | |
253 static void | |
2286 | 254 mswindows_output_hline (struct window *UNUSED (w), |
255 struct display_line *UNUSED (dl), | |
256 struct rune *UNUSED (rb)) | |
771 | 257 { /* #### Implement me */ |
428 | 258 } |
259 | |
260 | |
261 /***************************************************************************** | |
262 mswindows_output_blank | |
263 | |
264 Output a blank by clearing the area it covers in the background color | |
265 of its face. | |
266 ****************************************************************************/ | |
267 static void | |
268 mswindows_output_blank (struct window *w, struct display_line *dl, | |
269 struct rune *rb, int start_pixpos) | |
270 { | |
271 struct frame *f = XFRAME (w->frame); | |
442 | 272 HDC hdc = get_frame_dc (f, 1); |
428 | 273 RECT rect = { rb->xpos, DISPLAY_LINE_YPOS (dl), |
274 rb->xpos+rb->width, | |
275 DISPLAY_LINE_YEND (dl) }; | |
276 struct face_cachel *cachel = WINDOW_FACE_CACHEL (w, rb->findex); | |
277 | |
278 Lisp_Object bg_pmap = WINDOW_FACE_CACHEL_BACKGROUND_PIXMAP (w, rb->findex); | |
279 | |
280 /* Unmap all subwindows in the area we are going to blank. */ | |
281 redisplay_unmap_subwindows_maybe (f, rb->xpos, DISPLAY_LINE_YPOS (dl), | |
282 rb->width, DISPLAY_LINE_HEIGHT (dl)); | |
283 | |
284 if (!IMAGE_INSTANCEP (bg_pmap) | |
285 || !IMAGE_INSTANCE_PIXMAP_TYPE_P (XIMAGE_INSTANCE (bg_pmap))) | |
286 bg_pmap = Qnil; | |
287 | |
288 if (!NILP(bg_pmap)) | |
289 { | |
290 struct display_box db; | |
291 struct display_glyph_area dga; | |
292 redisplay_calculate_display_boxes (dl, rb->xpos, | |
293 /*rb->object.dglyph.xoffset*/ 0, | |
819 | 294 /*rb->object.dglyph.yoffset*/ 0, |
428 | 295 start_pixpos, rb->width, |
296 &db, &dga); | |
297 /* blank the background in the appropriate color */ | |
440 | 298 mswindows_update_dc (hdc, cachel->foreground, |
428 | 299 cachel->background, Qnil); |
300 redisplay_output_pixmap (w, bg_pmap, &db, &dga, rb->findex, | |
301 0, 0, 0, TRUE); | |
302 } | |
303 else | |
304 { | |
440 | 305 mswindows_update_dc (hdc, Qnil, cachel->background, Qnil); |
771 | 306 ExtTextOutW (hdc, 0, 0, ETO_OPAQUE, &rect, NULL, 0, NULL); |
428 | 307 } |
308 } | |
309 | |
310 | |
311 /***************************************************************************** | |
312 mswindows_output_cursor | |
313 | |
314 Draw a normal or end-of-line cursor. The end-of-line cursor is | |
315 narrower than the normal cursor. | |
316 ****************************************************************************/ | |
317 static void | |
318 mswindows_output_cursor (struct window *w, struct display_line *dl, int xpos, | |
867 | 319 int width, face_index findex, Ichar ch, int image_p) |
428 | 320 { |
321 struct frame *f = XFRAME (w->frame); | |
322 struct device *d = XDEVICE (f->device); | |
323 Lisp_Object font = Qnil; | |
324 int focus = EQ (w->frame, DEVICE_FRAME_WITH_FOCUS_REAL (d)); | |
442 | 325 HDC hdc = get_frame_dc (f, 1); |
647 | 326 int local_face_index = 0; |
771 | 327 textual_run *run; |
328 int nruns = 0; | |
428 | 329 RECT rect = { xpos, |
330 DISPLAY_LINE_YPOS (dl), | |
331 xpos + width, | |
332 DISPLAY_LINE_YEND (dl) }; | |
333 Lisp_Object bar = symbol_value_in_buffer (Qbar_cursor, | |
334 WINDOW_BUFFER (w)); | |
335 int bar_p = image_p || !NILP (bar); | |
336 int cursor_p = !NILP (w->text_cursor_visible_p); | |
337 int real_char_p = ch != 0; | |
338 | |
339 /* Unmap all subwindows in the area we are going to blank. */ | |
340 redisplay_unmap_subwindows_maybe (f, xpos, DISPLAY_LINE_YPOS (dl), | |
341 width, DISPLAY_LINE_HEIGHT (dl)); | |
342 | |
343 if (real_char_p) | |
344 { | |
345 /* Use the font from the underlying character */ | |
771 | 346 struct face_cachel *font_cachel = WINDOW_FACE_CACHEL (w, findex); |
347 nruns = separate_textual_runs (&run, &ch, 1); | |
348 font = FACE_CACHEL_FONT (font_cachel, run->charset); | |
349 mswindows_set_dc_font (hdc, font, | |
350 font_cachel->underline, font_cachel->strikethru); | |
428 | 351 } |
352 | |
353 if (!image_p) | |
354 { | |
355 struct face_cachel *color_cachel; | |
356 | |
357 /* Use cursor fg/bg for block cursor, or character fg/bg for the bar | |
358 or when we need to erase the cursor. Output nothing at eol if bar | |
359 cursor */ | |
440 | 360 local_face_index = get_builtin_face_cache_index (w, Vtext_cursor_face); |
428 | 361 color_cachel = WINDOW_FACE_CACHEL (w, ((!cursor_p || bar_p) ? |
440 | 362 findex : local_face_index)); |
363 mswindows_update_dc (hdc, color_cachel->foreground, | |
428 | 364 color_cachel->background, Qnil); |
771 | 365 ExtTextOutW (hdc, xpos, dl->ypos, ETO_OPAQUE|ETO_CLIPPED, &rect, |
366 nruns ? run->ptr : NULL, nruns ? run->nwchars : 0, NULL); | |
428 | 367 } |
368 | |
369 if (!cursor_p) | |
370 return; | |
371 | |
372 if (focus && bar_p) | |
373 { | |
771 | 374 struct face_cachel *cursor_cachel; |
428 | 375 rect.right = rect.left + (EQ (bar, Qt) ? 1 : min (2, width)); |
440 | 376 local_face_index = get_builtin_face_cache_index (w, Vtext_cursor_face); |
771 | 377 cursor_cachel = WINDOW_FACE_CACHEL (w, local_face_index); |
378 mswindows_update_dc (hdc, Qnil, cursor_cachel->background, Qnil); | |
379 ExtTextOutW (hdc, xpos, dl->ypos, ETO_OPAQUE, &rect, NULL, 0, NULL); | |
428 | 380 } |
381 else if (!focus) | |
382 { | |
771 | 383 struct face_cachel *cursor_cachel; |
384 | |
428 | 385 /* Now have real character drawn in its own color. We deflate |
386 the rectangle so character cell will be bounded by the | |
387 previously drawn cursor shape */ | |
388 InflateRect (&rect, -1, -1); | |
771 | 389 local_face_index = get_builtin_face_cache_index (w, Vdefault_face); |
390 cursor_cachel = | |
391 WINDOW_FACE_CACHEL (w, (real_char_p ? findex : local_face_index)); | |
392 mswindows_update_dc (hdc, | |
393 cursor_cachel->foreground, | |
394 cursor_cachel->background, Qnil); | |
395 ExtTextOutW (hdc, xpos, dl->ypos, ETO_OPAQUE | ETO_CLIPPED, | |
396 &rect, nruns ? run->ptr : NULL, nruns ? run->nwchars : 0, | |
397 NULL); | |
398 } | |
428 | 399 |
771 | 400 #ifdef MULE |
401 if (DEVICE_MSWINDOWS_P (d) && | |
402 (FRAME_MSWINDOWS_CURSOR_X (f) != xpos | |
403 || FRAME_MSWINDOWS_CURSOR_Y (f) != DISPLAY_LINE_YPOS (dl) | |
404 || FRAME_MSWINDOWS_CURSOR_FINDEX (f) != findex)) | |
405 { | |
406 HWND hwnd = FRAME_MSWINDOWS_HANDLE(f); | |
407 HIMC himc = ImmGetContext (hwnd); | |
408 | |
409 FRAME_MSWINDOWS_CURSOR_X (f) = xpos; | |
410 FRAME_MSWINDOWS_CURSOR_Y (f) = DISPLAY_LINE_YPOS (dl); | |
411 FRAME_MSWINDOWS_CURSOR_FINDEX (f) = findex; | |
412 | |
413 /* If the composition window is active, reset position of the | |
414 composition window. */ | |
415 if (qxeImmGetCompositionString (himc, GCS_COMPSTR, NULL, 0)) | |
416 mswindows_start_ime_composition (f); | |
417 | |
418 ImmReleaseContext (hwnd, himc); | |
428 | 419 } |
771 | 420 #endif /* MULE */ |
428 | 421 } |
422 | |
423 | |
424 /***************************************************************************** | |
425 mswindows_output_string | |
426 | |
427 Given a string and a starting position, output that string in the | |
428 given face. | |
429 Correctly handles multiple charsets in the string. | |
430 | |
431 The meaning of the parameters is something like this: | |
432 | |
433 W Window that the text is to be displayed in. | |
434 DL Display line that this text is on. The values in the | |
435 structure are used to determine the vertical position and | |
436 clipping range of the text. | |
867 | 437 BUF Dynamic array of Ichars specifying what is actually to be |
428 | 438 drawn. |
439 XPOS X position in pixels where the text should start being drawn. | |
440 XOFFSET Number of pixels to be chopped off the left side of the | |
441 text. The effect is as if the text were shifted to the | |
442 left this many pixels and clipped at XPOS. | |
443 CLIP_START Clip everything left of this X position. | |
444 WIDTH Clip everything right of XPOS + WIDTH. | |
445 FINDEX Index for the face cache element describing how to display | |
446 the text. | |
447 ****************************************************************************/ | |
440 | 448 static void |
428 | 449 mswindows_output_string (struct window *w, struct display_line *dl, |
2286 | 450 Ichar_dynarr *buf, int xpos, int xoffset, |
451 int clip_start, int width, face_index findex, | |
452 int UNUSED (cursor), int UNUSED (cursor_start), | |
453 int UNUSED (cursor_width), int UNUSED (cursor_height)) | |
428 | 454 { |
455 struct frame *f = XFRAME (w->frame); | |
456 /* struct device *d = XDEVICE (f->device);*/ | |
457 Lisp_Object window; | |
442 | 458 HDC hdc = get_frame_dc (f, 1); |
428 | 459 int clip_end; |
460 Lisp_Object bg_pmap; | |
771 | 461 textual_run *runs; |
428 | 462 int nruns; |
463 int i, height; | |
464 RECT rect; | |
465 struct face_cachel *cachel = WINDOW_FACE_CACHEL (w, findex); | |
466 | |
793 | 467 window = wrap_window (w); |
428 | 468 |
469 #if 0 /* #### FIXME? */ | |
470 /* We can't work out the width before we've set the font in the DC */ | |
471 if (width < 0) | |
4967 | 472 width = mswindows_text_width (w, cachel, Dynarr_begin (buf), |
4928
ea701c23ed84
change text_width method to take a window, in preparation for unicode-internal changes
Ben Wing <ben@xemacs.org>
parents:
4476
diff
changeset
|
473 Dynarr_length (buf)); |
428 | 474 #else |
4928
ea701c23ed84
change text_width method to take a window, in preparation for unicode-internal changes
Ben Wing <ben@xemacs.org>
parents:
4476
diff
changeset
|
475 assert (width >= 0); |
428 | 476 #endif |
477 | |
478 /* Regularize the variables passed in. */ | |
479 if (clip_start < xpos) | |
480 clip_start = xpos; | |
481 clip_end = xpos + width; | |
482 if (clip_start >= clip_end) | |
483 /* It's all clipped out. */ | |
484 return; | |
485 | |
486 xpos -= xoffset; | |
487 | |
488 /* sort out the destination rectangle */ | |
489 height = DISPLAY_LINE_HEIGHT (dl); | |
490 rect.left = clip_start; | |
491 rect.top = DISPLAY_LINE_YPOS (dl); | |
492 rect.right = clip_end; | |
493 rect.bottom = rect.top + height; | |
494 | |
495 /* make sure the area we are about to display is subwindow free. */ | |
496 redisplay_unmap_subwindows_maybe (f, clip_start, DISPLAY_LINE_YPOS (dl), | |
497 clip_end - clip_start, DISPLAY_LINE_HEIGHT (dl)); | |
498 | |
499 /* output the background pixmap if there is one */ | |
500 bg_pmap = cachel->background_pixmap; | |
501 if (!IMAGE_INSTANCEP (bg_pmap) | |
502 || !IMAGE_INSTANCE_PIXMAP_TYPE_P (XIMAGE_INSTANCE (bg_pmap))) | |
503 bg_pmap = Qnil; | |
504 | |
505 if (!NILP(bg_pmap)) | |
506 { | |
507 struct display_box db; | |
508 struct display_glyph_area dga; | |
819 | 509 redisplay_calculate_display_boxes (dl, xpos + xoffset, 0, 0, |
428 | 510 clip_start, width, &db, &dga); |
511 /* blank the background in the appropriate color */ | |
440 | 512 mswindows_update_dc (hdc, |
513 cachel->foreground, cachel->background, Qnil); | |
428 | 514 redisplay_output_pixmap (w, bg_pmap, &db, &dga, findex, |
515 0, 0, 0, TRUE); | |
516 /* output pixmap calls this so we have to recall to get correct | |
517 references */ | |
518 cachel = WINDOW_FACE_CACHEL (w, findex); | |
519 } | |
520 | |
4967 | 521 nruns = separate_textual_runs (&runs, Dynarr_begin (buf), |
428 | 522 Dynarr_length (buf)); |
523 | |
524 for (i = 0; i < nruns; i++) | |
525 { | |
526 Lisp_Object font = FACE_CACHEL_FONT (cachel, runs[i].charset); | |
440 | 527 Lisp_Font_Instance *fi = XFONT_INSTANCE (font); |
428 | 528 int this_width; |
529 | |
530 if (EQ (font, Vthe_null_font_instance)) | |
531 continue; | |
532 | |
440 | 533 mswindows_update_dc (hdc, cachel->foreground, |
428 | 534 NILP(bg_pmap) ? cachel->background : Qnil, Qnil); |
440 | 535 mswindows_set_dc_font (hdc, font, cachel->underline, cachel->strikethru); |
428 | 536 |
537 this_width = mswindows_text_width_single_run (hdc, cachel, runs + i); | |
538 | |
539 /* cope with fonts taller than lines */ | |
540 if ((int) fi->height < (int) (height + dl->clip + dl->top_clip)) | |
541 { | |
542 int clear_start = max (xpos, clip_start); | |
543 int clear_end = min (xpos + this_width, clip_end); | |
544 | |
545 { | |
546 redisplay_clear_region (window, findex, clear_start, | |
547 DISPLAY_LINE_YPOS (dl), | |
548 clear_end - clear_start, | |
549 height); | |
550 /* output pixmap calls this so we have to recall to get correct | |
551 references */ | |
552 cachel = WINDOW_FACE_CACHEL (w, findex); | |
553 } | |
554 } | |
555 | |
771 | 556 ExtTextOutW (hdc, xpos, dl->ypos, |
557 NILP(bg_pmap) ? ETO_CLIPPED | ETO_OPAQUE : ETO_CLIPPED, | |
558 &rect, runs[i].ptr, runs[i].nwchars, NULL); | |
428 | 559 |
560 xpos += this_width; | |
561 } | |
562 } | |
563 | |
564 static void | |
440 | 565 mswindows_output_dibitmap (struct frame *f, Lisp_Image_Instance *p, |
771 | 566 struct display_box *db, |
567 struct display_glyph_area *dga) | |
428 | 568 { |
442 | 569 HDC hdc = get_frame_dc (f, 1); |
440 | 570 HDC hcompdc = get_frame_compdc (f); |
428 | 571 HGDIOBJ old=NULL; |
442 | 572 const int real_x = IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_WIDTH (p); |
573 const int real_y = IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_HEIGHT (p); | |
574 const int surface_x = IMAGE_INSTANCE_PIXMAP_WIDTH (p); | |
575 const int surface_y = IMAGE_INSTANCE_PIXMAP_HEIGHT (p); | |
428 | 576 |
442 | 577 /* first blit the mask */ |
428 | 578 if (IMAGE_INSTANCE_MSWINDOWS_MASK (p)) |
579 { | |
442 | 580 RGBQUAD bg; |
581 COLORREF bgcolor; | |
428 | 582 |
440 | 583 old = SelectObject (hcompdc, IMAGE_INSTANCE_MSWINDOWS_MASK (p)); |
428 | 584 |
442 | 585 if (IMAGE_INSTANCE_TYPE (p) == IMAGE_MONO_PIXMAP) |
586 { | |
587 COLORREF fgcolor; | |
588 RGBQUAD fg; | |
589 | |
590 fgcolor = GetTextColor (hdc); | |
591 fg.rgbBlue = GetBValue (fgcolor); | |
592 fg.rgbRed = GetRValue (fgcolor); | |
593 fg.rgbGreen = GetGValue (fgcolor); | |
594 fg.rgbReserved = 0; | |
595 SetDIBColorTable (hcompdc, 0, 1, &fg); | |
596 } | |
428 | 597 |
442 | 598 bgcolor = GetBkColor (hdc); |
599 bg.rgbBlue = GetBValue (bgcolor); | |
600 bg.rgbRed = GetRValue (bgcolor); | |
601 bg.rgbGreen = GetGValue (bgcolor); | |
602 bg.rgbReserved = 0; | |
603 SetDIBColorTable (hcompdc, 1, 1, &bg); | |
604 | |
605 StretchBlt (hdc, | |
606 db->xpos, db->ypos, | |
607 dga->width, dga->height, | |
608 hcompdc, | |
609 MulDiv (dga->xoffset, real_x, surface_x), | |
610 MulDiv (dga->yoffset, real_y, surface_y), | |
611 MulDiv (dga->width, real_x, surface_x), | |
612 MulDiv (dga->height, real_y, surface_y), | |
613 SRCCOPY); | |
428 | 614 |
440 | 615 SelectObject (hcompdc, old); |
428 | 616 } |
617 | |
442 | 618 /* Now blit the bitmap itself, or one of its slices. */ |
440 | 619 old = SelectObject (hcompdc, |
428 | 620 IMAGE_INSTANCE_MSWINDOWS_BITMAP_SLICE |
621 (p, IMAGE_INSTANCE_PIXMAP_SLICE (p))); | |
622 | |
442 | 623 StretchBlt (hdc, |
624 db->xpos, db->ypos, | |
625 dga->width, dga->height, | |
626 hcompdc, | |
627 MulDiv (dga->xoffset, real_x, surface_x), | |
628 MulDiv (dga->yoffset, real_y, surface_y), | |
629 MulDiv (dga->width, real_x, surface_x), | |
630 MulDiv (dga->height, real_y, surface_y), | |
631 IMAGE_INSTANCE_MSWINDOWS_MASK (p) ? SRCINVERT : SRCCOPY); | |
428 | 632 |
440 | 633 SelectObject (hcompdc, old); |
428 | 634 } |
635 | |
5138
6d13ad8ed3b2
implement absolute background-placement for Windows, sort of
Ben Wing <ben@xemacs.org>
parents:
5080
diff
changeset
|
636 /* Return x MOD y, but the result is guaranteed positive */ |
6d13ad8ed3b2
implement absolute background-placement for Windows, sort of
Ben Wing <ben@xemacs.org>
parents:
5080
diff
changeset
|
637 |
6d13ad8ed3b2
implement absolute background-placement for Windows, sort of
Ben Wing <ben@xemacs.org>
parents:
5080
diff
changeset
|
638 static int |
6d13ad8ed3b2
implement absolute background-placement for Windows, sort of
Ben Wing <ben@xemacs.org>
parents:
5080
diff
changeset
|
639 posmod (int x, int y) |
6d13ad8ed3b2
implement absolute background-placement for Windows, sort of
Ben Wing <ben@xemacs.org>
parents:
5080
diff
changeset
|
640 { |
6d13ad8ed3b2
implement absolute background-placement for Windows, sort of
Ben Wing <ben@xemacs.org>
parents:
5080
diff
changeset
|
641 int retval = x % y; |
6d13ad8ed3b2
implement absolute background-placement for Windows, sort of
Ben Wing <ben@xemacs.org>
parents:
5080
diff
changeset
|
642 if (retval < 0) |
6d13ad8ed3b2
implement absolute background-placement for Windows, sort of
Ben Wing <ben@xemacs.org>
parents:
5080
diff
changeset
|
643 retval += y; |
6d13ad8ed3b2
implement absolute background-placement for Windows, sort of
Ben Wing <ben@xemacs.org>
parents:
5080
diff
changeset
|
644 return retval; |
6d13ad8ed3b2
implement absolute background-placement for Windows, sort of
Ben Wing <ben@xemacs.org>
parents:
5080
diff
changeset
|
645 } |
6d13ad8ed3b2
implement absolute background-placement for Windows, sort of
Ben Wing <ben@xemacs.org>
parents:
5080
diff
changeset
|
646 |
428 | 647 /* X gc's have this nice property that setting the bg pixmap will |
648 * output it offset relative to the window. Windows doesn't have this | |
649 * feature so we have to emulate this by outputting multiple pixmaps. | |
650 * This is only used for background pixmaps. Normal pixmaps are | |
651 * outputted once and are scrollable */ | |
652 static void | |
653 mswindows_output_dibitmap_region (struct frame *f, | |
440 | 654 Lisp_Image_Instance *p, |
428 | 655 struct display_box *db, |
5138
6d13ad8ed3b2
implement absolute background-placement for Windows, sort of
Ben Wing <ben@xemacs.org>
parents:
5080
diff
changeset
|
656 struct display_glyph_area *dga, |
6d13ad8ed3b2
implement absolute background-placement for Windows, sort of
Ben Wing <ben@xemacs.org>
parents:
5080
diff
changeset
|
657 int absolute) |
428 | 658 { |
659 struct display_box xdb = { db->xpos, db->ypos, db->width, db->height }; | |
660 struct display_glyph_area xdga | |
661 = { 0, 0, IMAGE_INSTANCE_PIXMAP_WIDTH (p), | |
662 IMAGE_INSTANCE_PIXMAP_HEIGHT (p) }; | |
663 int pxoffset = 0, pyoffset = 0; | |
5138
6d13ad8ed3b2
implement absolute background-placement for Windows, sort of
Ben Wing <ben@xemacs.org>
parents:
5080
diff
changeset
|
664 int absolute_pxoffset = 0, absolute_pyoffset = 0; |
428 | 665 |
666 if (dga) | |
667 { | |
668 xdga.width = dga->width; | |
669 xdga.height = dga->height; | |
670 } | |
671 else if (!redisplay_normalize_glyph_area (&xdb, &xdga)) | |
672 return; | |
673 | |
5138
6d13ad8ed3b2
implement absolute background-placement for Windows, sort of
Ben Wing <ben@xemacs.org>
parents:
5080
diff
changeset
|
674 if (absolute) |
6d13ad8ed3b2
implement absolute background-placement for Windows, sort of
Ben Wing <ben@xemacs.org>
parents:
5080
diff
changeset
|
675 { |
6d13ad8ed3b2
implement absolute background-placement for Windows, sort of
Ben Wing <ben@xemacs.org>
parents:
5080
diff
changeset
|
676 POINT point; |
6d13ad8ed3b2
implement absolute background-placement for Windows, sort of
Ben Wing <ben@xemacs.org>
parents:
5080
diff
changeset
|
677 point.x = 0; |
6d13ad8ed3b2
implement absolute background-placement for Windows, sort of
Ben Wing <ben@xemacs.org>
parents:
5080
diff
changeset
|
678 point.y = 0; |
6d13ad8ed3b2
implement absolute background-placement for Windows, sort of
Ben Wing <ben@xemacs.org>
parents:
5080
diff
changeset
|
679 if (ScreenToClient (FRAME_MSWINDOWS_HANDLE (f), &point)) |
6d13ad8ed3b2
implement absolute background-placement for Windows, sort of
Ben Wing <ben@xemacs.org>
parents:
5080
diff
changeset
|
680 { |
6d13ad8ed3b2
implement absolute background-placement for Windows, sort of
Ben Wing <ben@xemacs.org>
parents:
5080
diff
changeset
|
681 absolute_pxoffset = point.x; |
6d13ad8ed3b2
implement absolute background-placement for Windows, sort of
Ben Wing <ben@xemacs.org>
parents:
5080
diff
changeset
|
682 absolute_pyoffset = point.y; |
6d13ad8ed3b2
implement absolute background-placement for Windows, sort of
Ben Wing <ben@xemacs.org>
parents:
5080
diff
changeset
|
683 } |
6d13ad8ed3b2
implement absolute background-placement for Windows, sort of
Ben Wing <ben@xemacs.org>
parents:
5080
diff
changeset
|
684 } |
6d13ad8ed3b2
implement absolute background-placement for Windows, sort of
Ben Wing <ben@xemacs.org>
parents:
5080
diff
changeset
|
685 |
428 | 686 /* when doing a bg pixmap do a partial pixmap first so that we |
687 blt whole pixmaps thereafter */ | |
688 xdga.height = min (xdga.height, IMAGE_INSTANCE_PIXMAP_HEIGHT (p) - | |
5138
6d13ad8ed3b2
implement absolute background-placement for Windows, sort of
Ben Wing <ben@xemacs.org>
parents:
5080
diff
changeset
|
689 posmod (db->ypos - absolute_pyoffset, |
6d13ad8ed3b2
implement absolute background-placement for Windows, sort of
Ben Wing <ben@xemacs.org>
parents:
5080
diff
changeset
|
690 IMAGE_INSTANCE_PIXMAP_HEIGHT (p))); |
428 | 691 |
692 while (xdga.height > 0) | |
693 { | |
694 xdga.width = min (min (db->width, IMAGE_INSTANCE_PIXMAP_WIDTH (p)), | |
695 IMAGE_INSTANCE_PIXMAP_WIDTH (p) - | |
5138
6d13ad8ed3b2
implement absolute background-placement for Windows, sort of
Ben Wing <ben@xemacs.org>
parents:
5080
diff
changeset
|
696 posmod (db->xpos - absolute_pxoffset, |
6d13ad8ed3b2
implement absolute background-placement for Windows, sort of
Ben Wing <ben@xemacs.org>
parents:
5080
diff
changeset
|
697 IMAGE_INSTANCE_PIXMAP_WIDTH (p))); |
428 | 698 pxoffset = 0; |
699 while (xdga.width > 0) | |
700 { | |
701 xdb.xpos = db->xpos + pxoffset; | |
702 xdb.ypos = db->ypos + pyoffset; | |
703 /* do we need to offset the pixmap vertically? this is necessary | |
704 for background pixmaps. */ | |
5138
6d13ad8ed3b2
implement absolute background-placement for Windows, sort of
Ben Wing <ben@xemacs.org>
parents:
5080
diff
changeset
|
705 xdga.xoffset = posmod (xdb.xpos - absolute_pxoffset, |
6d13ad8ed3b2
implement absolute background-placement for Windows, sort of
Ben Wing <ben@xemacs.org>
parents:
5080
diff
changeset
|
706 IMAGE_INSTANCE_PIXMAP_WIDTH (p)); |
6d13ad8ed3b2
implement absolute background-placement for Windows, sort of
Ben Wing <ben@xemacs.org>
parents:
5080
diff
changeset
|
707 xdga.yoffset = posmod (xdb.ypos - absolute_pyoffset, |
6d13ad8ed3b2
implement absolute background-placement for Windows, sort of
Ben Wing <ben@xemacs.org>
parents:
5080
diff
changeset
|
708 IMAGE_INSTANCE_PIXMAP_HEIGHT (p)); |
6d13ad8ed3b2
implement absolute background-placement for Windows, sort of
Ben Wing <ben@xemacs.org>
parents:
5080
diff
changeset
|
709 /* [[ the width is handled by mswindows_output_pixmap_region ]] |
6d13ad8ed3b2
implement absolute background-placement for Windows, sort of
Ben Wing <ben@xemacs.org>
parents:
5080
diff
changeset
|
710 #### -- What is the correct meaning of this comment? There is |
6d13ad8ed3b2
implement absolute background-placement for Windows, sort of
Ben Wing <ben@xemacs.org>
parents:
5080
diff
changeset
|
711 no mswindows_output_pixmap_region(). --ben*/ |
428 | 712 mswindows_output_dibitmap (f, p, &xdb, &xdga); |
713 pxoffset += xdga.width; | |
714 xdga.width = min ((db->width - pxoffset), | |
715 IMAGE_INSTANCE_PIXMAP_WIDTH (p)); | |
716 } | |
717 pyoffset += xdga.height; | |
718 xdga.height = min ((db->height - pyoffset), | |
719 IMAGE_INSTANCE_PIXMAP_HEIGHT (p)); | |
720 } | |
721 } | |
722 | |
723 /* Output a pixmap at the desired location. | |
724 DB normalized display_box. | |
725 DGA normalized display_glyph_area. */ | |
726 static void | |
727 mswindows_output_pixmap (struct window *w, Lisp_Object image_instance, | |
2286 | 728 struct display_box *db, |
729 struct display_glyph_area *dga, face_index findex, | |
730 int UNUSED (cursor_start), int UNUSED (cursor_width), | |
731 int UNUSED (cursor_height), int bg_pixmap) | |
428 | 732 { |
733 struct frame *f = XFRAME (w->frame); | |
442 | 734 HDC hdc = get_frame_dc (f, 1); |
428 | 735 |
440 | 736 Lisp_Image_Instance *p = XIMAGE_INSTANCE (image_instance); |
428 | 737 |
738 /* Output the pixmap. Have to do this as many times as is required | |
739 to fill the given area */ | |
440 | 740 mswindows_update_dc (hdc, |
428 | 741 WINDOW_FACE_CACHEL_FOREGROUND (w, findex), |
742 WINDOW_FACE_CACHEL_BACKGROUND (w, findex), Qnil); | |
743 | |
744 if (bg_pixmap) | |
5138
6d13ad8ed3b2
implement absolute background-placement for Windows, sort of
Ben Wing <ben@xemacs.org>
parents:
5080
diff
changeset
|
745 mswindows_output_dibitmap_region |
6d13ad8ed3b2
implement absolute background-placement for Windows, sort of
Ben Wing <ben@xemacs.org>
parents:
5080
diff
changeset
|
746 (f, p, db, dga, |
6d13ad8ed3b2
implement absolute background-placement for Windows, sort of
Ben Wing <ben@xemacs.org>
parents:
5080
diff
changeset
|
747 EQ (WINDOW_FACE_CACHEL_BACKGROUND_PLACEMENT (w, findex), Qabsolute)); |
428 | 748 else |
749 mswindows_output_dibitmap (f, p, db, dga); | |
750 } | |
751 | |
752 #ifdef HAVE_SCROLLBARS | |
753 /* | |
754 * This function paints window's deadbox, a rectangle between window | |
755 * borders and two short edges of both scrollbars. | |
756 * | |
757 * Function checks whether deadbox intersects with the rectangle pointed | |
758 * to by PRC, and paints only the intersection | |
759 */ | |
760 static void | |
1318 | 761 mswindows_redisplay_deadbox (struct window *w, int x, int y, int width, |
762 int height) | |
428 | 763 { |
1318 | 764 RECT rc = { x, y, x + width, y + height }; |
428 | 765 int sbh = window_scrollbar_height (w); |
766 int sbw = window_scrollbar_width (w); | |
767 RECT rect_dead, rect_paint; | |
768 if (sbh == 0 || sbw == 0) | |
769 return; | |
770 | |
771 if (!NILP (w->scrollbar_on_left_p)) | |
772 rect_dead.left = WINDOW_LEFT (w); | |
773 else | |
774 rect_dead.left = WINDOW_TEXT_RIGHT (w); | |
775 rect_dead.right = rect_dead.left + sbw; | |
776 | |
777 if (!NILP (w->scrollbar_on_top_p)) | |
778 rect_dead.top = WINDOW_TOP (w); | |
779 else | |
780 rect_dead.top = WINDOW_TEXT_BOTTOM (w); | |
781 rect_dead.bottom = rect_dead.top + sbh; | |
782 | |
1318 | 783 if (IntersectRect (&rect_paint, &rect_dead, &rc)) |
428 | 784 { |
785 struct frame *f = XFRAME (WINDOW_FRAME (w)); | |
442 | 786 FillRect (get_frame_dc (f, 1), &rect_paint, |
428 | 787 (HBRUSH) (COLOR_BTNFACE+1)); |
788 } | |
789 } | |
790 | |
791 #endif /* HAVE_SCROLLBARS */ | |
792 | |
793 /***************************************************************************** | |
794 mswindows_bevel_area | |
795 | |
796 Draw a 3d border around the specified area on window W. | |
797 ****************************************************************************/ | |
798 static void | |
799 mswindows_bevel_area (struct window *w, face_index findex, int x, int y, | |
800 int width, int height, int thickness, | |
801 int edges, enum edge_style style) | |
802 { | |
803 struct frame *f = XFRAME (w->frame); | |
804 UINT edge; | |
805 UINT border = 0; | |
806 | |
807 if (style == EDGE_ETCHED_IN) | |
808 edge = EDGE_ETCHED; | |
809 else if (style == EDGE_ETCHED_OUT) | |
810 edge = EDGE_BUMP; | |
811 else if (style == EDGE_BEVEL_IN) | |
812 { | |
813 if (thickness == 1) | |
814 edge = BDR_SUNKENINNER; | |
815 else | |
816 edge = EDGE_SUNKEN; | |
817 } | |
818 else /* EDGE_BEVEL_OUT */ | |
819 { | |
820 if (thickness == 1) | |
821 edge = BDR_RAISEDINNER; | |
822 else | |
823 edge = EDGE_RAISED; | |
824 } | |
825 | |
826 if (edges & EDGE_TOP) | |
827 border |= BF_TOP; | |
828 if (edges & EDGE_LEFT) | |
829 border |= BF_LEFT; | |
830 if (edges & EDGE_BOTTOM) | |
831 border |= BF_BOTTOM; | |
832 if (edges & EDGE_RIGHT) | |
833 border |= BF_RIGHT; | |
834 | |
835 { | |
836 RECT rect = { x, y, x + width, y + height }; | |
837 Lisp_Object color = WINDOW_FACE_CACHEL_BACKGROUND (w, findex); | |
442 | 838 HDC hdc = get_frame_dc (f, 1); |
428 | 839 |
440 | 840 mswindows_update_dc (hdc, Qnil, color, Qnil); |
841 DrawEdge (hdc, &rect, edge, border); | |
428 | 842 } |
843 } | |
844 | |
845 | |
846 /***************************************************************************** | |
847 Display methods | |
848 *****************************************************************************/ | |
849 | |
850 /***************************************************************************** | |
851 mswindows_divider_height | |
852 | |
853 Return the height of the horizontal divider. | |
854 ****************************************************************************/ | |
855 static int | |
856 mswindows_divider_height (void) | |
857 { | |
858 return 1; /* XXX Copied from redisplay-X.c. What is this? */ | |
859 } | |
860 | |
861 /***************************************************************************** | |
862 mswindows_eol_cursor_width | |
863 | |
864 Return the width of the end-of-line cursor. | |
865 ****************************************************************************/ | |
866 static int | |
867 mswindows_eol_cursor_width (void) | |
868 { | |
869 return MSWINDOWS_EOL_CURSOR_WIDTH; | |
870 } | |
871 | |
872 /***************************************************************************** | |
442 | 873 mswindows_frame_output_begin |
428 | 874 |
875 Perform any necessary initialization prior to an update. | |
876 ****************************************************************************/ | |
877 static void | |
2286 | 878 mswindows_frame_output_begin (struct frame *UNUSED (f)) |
428 | 879 { |
880 } | |
881 | |
882 /***************************************************************************** | |
442 | 883 mswindows_frame_output_end |
428 | 884 |
885 Perform any necessary flushing of queues when an update has completed. | |
886 ****************************************************************************/ | |
887 static void | |
2286 | 888 mswindows_frame_output_end (struct frame * |
889 #ifdef DEFER_WINDOW_POS | |
890 f | |
891 #else | |
892 UNUSED (f) | |
893 #endif | |
894 ) | |
442 | 895 { |
896 #ifdef DEFER_WINDOW_POS | |
897 HDWP hdwp = FRAME_MSWINDOWS_DATA (f)->hdwp; | |
898 | |
899 if (hdwp != 0) | |
900 { | |
901 EndDeferWindowPos (hdwp); | |
902 FRAME_MSWINDOWS_DATA (f)->hdwp = 0; | |
903 } | |
904 #endif | |
905 GdiFlush(); | |
906 } | |
907 | |
908 /* Printer version is more lightweight. */ | |
909 static void | |
2286 | 910 msprinter_frame_output_end (struct frame *UNUSED (f)) |
428 | 911 { |
912 GdiFlush(); | |
913 } | |
914 | |
915 static int | |
916 mswindows_flash (struct device *d) | |
917 { | |
918 struct frame *f = device_selected_frame (d); | |
442 | 919 HDC hdc = get_frame_dc (f, 1); |
428 | 920 RECT rc; |
921 | |
922 GetClientRect (FRAME_MSWINDOWS_HANDLE (f), &rc); | |
440 | 923 InvertRect (hdc, &rc); |
428 | 924 GdiFlush (); |
925 Sleep (25); | |
440 | 926 InvertRect (hdc, &rc); |
428 | 927 |
928 return 1; | |
929 } | |
930 | |
931 static void | |
2286 | 932 mswindows_ring_bell (struct device *UNUSED (d), int UNUSED (volume), |
933 int UNUSED (pitch), int UNUSED (duration)) | |
428 | 934 { |
935 /* Beep does not work at all, anyways! -kkm */ | |
936 MessageBeep (MB_OK); | |
937 } | |
938 | |
939 /***************************************************************************** | |
940 mswindows_output_display_block | |
941 | |
942 Given a display line, a block number for that start line, output all | |
943 runes between start and end in the specified display block. | |
944 Ripped off with minimal thought from the corresponding X routine. | |
945 ****************************************************************************/ | |
946 static void | |
771 | 947 mswindows_output_display_block (struct window *w, struct display_line *dl, |
948 int block, int start, int end, | |
949 int start_pixpos, int cursor_start, | |
950 int cursor_width, int cursor_height) | |
428 | 951 { |
952 struct frame *f = XFRAME (w->frame); | |
3479 | 953 Ichar_dynarr *buf; |
428 | 954 Lisp_Object window; |
955 | |
956 struct display_block *db = Dynarr_atp (dl->display_blocks, block); | |
957 rune_dynarr *rba = db->runes; | |
958 struct rune *rb; | |
959 | |
960 int elt = start; | |
961 face_index findex; | |
962 int xpos, width; | |
963 Lisp_Object charset = Qunbound; /* Qnil is a valid charset when | |
964 MULE is not defined */ | |
793 | 965 window = wrap_window (w); |
428 | 966 rb = Dynarr_atp (rba, start); |
967 | |
968 if (!rb) | |
969 /* Nothing to do so don't do anything. */ | |
970 return; | |
971 | |
972 findex = rb->findex; | |
973 xpos = rb->xpos; | |
974 width = 0; | |
975 if (rb->type == RUNE_CHAR) | |
867 | 976 charset = ichar_charset (rb->object.chr.ch); |
428 | 977 |
978 if (end < 0) | |
979 end = Dynarr_length (rba); | |
3479 | 980 buf = Dynarr_new (Ichar); |
428 | 981 |
982 while (elt < end) | |
983 { | |
984 rb = Dynarr_atp (rba, elt); | |
985 | |
986 if (rb->findex == findex && rb->type == RUNE_CHAR | |
987 && rb->object.chr.ch != '\n' && rb->cursor_type != CURSOR_ON | |
867 | 988 && EQ (charset, ichar_charset (rb->object.chr.ch))) |
428 | 989 { |
990 Dynarr_add (buf, rb->object.chr.ch); | |
991 width += rb->width; | |
992 elt++; | |
993 } | |
994 else | |
995 { | |
996 if (Dynarr_length (buf)) | |
997 { | |
771 | 998 mswindows_output_string (w, dl, buf, xpos, 0, start_pixpos, |
999 width, findex, 0, 0, 0, 0); | |
428 | 1000 xpos = rb->xpos; |
1001 width = 0; | |
1002 } | |
1003 Dynarr_reset (buf); | |
1004 width = 0; | |
1005 | |
1006 if (rb->type == RUNE_CHAR) | |
1007 { | |
1008 findex = rb->findex; | |
1009 xpos = rb->xpos; | |
867 | 1010 charset = ichar_charset (rb->object.chr.ch); |
428 | 1011 |
1012 if (rb->cursor_type == CURSOR_ON) | |
1013 { | |
1014 if (rb->object.chr.ch == '\n') | |
1015 { | |
1016 mswindows_output_cursor (w, dl, xpos, cursor_width, | |
1017 findex, 0, 0); | |
1018 } | |
1019 else | |
1020 { | |
1021 Dynarr_add (buf, rb->object.chr.ch); | |
1022 mswindows_output_cursor (w, dl, xpos, cursor_width, | |
1023 findex, rb->object.chr.ch, 0); | |
1024 Dynarr_reset (buf); | |
1025 } | |
1026 | |
1027 xpos += rb->width; | |
1028 elt++; | |
1029 } | |
1030 else if (rb->object.chr.ch == '\n') | |
1031 { | |
1032 /* Clear in case a cursor was formerly here. */ | |
1033 redisplay_clear_region (window, findex, xpos, | |
1034 DISPLAY_LINE_YPOS (dl), | |
1035 rb->width, DISPLAY_LINE_HEIGHT (dl)); | |
1036 elt++; | |
1037 } | |
1038 } | |
1039 else if (rb->type == RUNE_BLANK || rb->type == RUNE_HLINE) | |
1040 { | |
1041 if (rb->type == RUNE_BLANK) | |
1042 mswindows_output_blank (w, dl, rb, start_pixpos); | |
1043 else | |
1044 { | |
1045 /* #### Our flagging of when we need to redraw the | |
1046 modeline shadows sucks. Since RUNE_HLINE is only used | |
1047 by the modeline at the moment it is a good bet | |
1048 that if it gets redrawn then we should also | |
1049 redraw the shadows. This won't be true forever. | |
1050 We borrow the shadow_thickness_changed flag for | |
1051 now. */ | |
1052 w->shadow_thickness_changed = 1; | |
1053 mswindows_output_hline (w, dl, rb); | |
1054 } | |
1055 | |
1056 if (rb->cursor_type == CURSOR_ON) | |
1057 mswindows_output_cursor (w, dl, xpos, cursor_width, rb->findex, 0, 0); | |
1058 | |
1059 elt++; | |
1060 if (elt < end) | |
1061 { | |
1062 rb = Dynarr_atp (rba, elt); | |
1063 | |
1064 findex = rb->findex; | |
1065 xpos = rb->xpos; | |
1066 } | |
1067 } | |
1068 else if (rb->type == RUNE_DGLYPH) | |
1069 { | |
1070 Lisp_Object instance; | |
440 | 1071 struct display_box dbox; |
428 | 1072 struct display_glyph_area dga; |
442 | 1073 |
428 | 1074 redisplay_calculate_display_boxes (dl, rb->xpos, rb->object.dglyph.xoffset, |
819 | 1075 rb->object.dglyph.yoffset, |
1076 start_pixpos, rb->width, &dbox, &dga); | |
428 | 1077 |
793 | 1078 window = wrap_window (w); |
428 | 1079 instance = glyph_image_instance (rb->object.dglyph.glyph, |
793 | 1080 window, ERROR_ME_DEBUG_WARN, 1); |
428 | 1081 findex = rb->findex; |
1082 | |
1083 if (IMAGE_INSTANCEP (instance)) | |
442 | 1084 { |
1085 switch (XIMAGE_INSTANCE_TYPE (instance)) | |
428 | 1086 { |
442 | 1087 case IMAGE_MONO_PIXMAP: |
1088 case IMAGE_COLOR_PIXMAP: | |
1089 redisplay_output_pixmap (w, instance, &dbox, &dga, findex, | |
1090 cursor_start, cursor_width, | |
1091 cursor_height, 0); | |
428 | 1092 if (rb->cursor_type == CURSOR_ON) |
1093 mswindows_output_cursor (w, dl, xpos, cursor_width, | |
442 | 1094 findex, 0, 1); |
1095 break; | |
1096 | |
1097 case IMAGE_WIDGET: | |
1098 if (EQ (XIMAGE_INSTANCE_WIDGET_TYPE (instance), | |
1099 Qlayout)) | |
1100 { | |
1101 redisplay_output_layout (window, instance, &dbox, &dga, findex, | |
1102 cursor_start, cursor_width, | |
1103 cursor_height); | |
1104 if (rb->cursor_type == CURSOR_ON) | |
1105 mswindows_output_cursor (w, dl, xpos, cursor_width, | |
1106 findex, 0, 1); | |
1107 break; | |
1108 } | |
1109 case IMAGE_SUBWINDOW: | |
1110 redisplay_output_subwindow (w, instance, &dbox, &dga, findex, | |
1111 cursor_start, cursor_width, | |
1112 cursor_height); | |
1113 if (rb->cursor_type == CURSOR_ON) | |
1114 mswindows_output_cursor (w, dl, xpos, cursor_width, | |
1115 findex, 0, 1); | |
1116 break; | |
1117 | |
1118 case IMAGE_NOTHING: | |
1119 /* nothing is as nothing does */ | |
1120 break; | |
428 | 1121 |
442 | 1122 case IMAGE_TEXT: |
1123 case IMAGE_POINTER: | |
1124 default: | |
2500 | 1125 ABORT (); |
442 | 1126 } |
1127 IMAGE_INSTANCE_OPTIMIZE_OUTPUT | |
1128 (XIMAGE_INSTANCE (instance)) = 0; | |
1129 } | |
428 | 1130 xpos += rb->width; |
1131 elt++; | |
1132 } | |
1133 else | |
2500 | 1134 ABORT (); |
428 | 1135 } |
1136 } | |
1137 | |
1138 if (Dynarr_length (buf)) | |
1139 mswindows_output_string (w, dl, buf, xpos, 0, start_pixpos, width, findex, | |
1140 0, 0, 0, 0); | |
1141 | |
1142 if (dl->modeline | |
1143 && !EQ (Qzero, w->modeline_shadow_thickness) | |
1144 && (f->clear | |
1145 || f->windows_structure_changed | |
1146 || w->shadow_thickness_changed)) | |
1147 bevel_modeline (w, dl); | |
1148 | |
1149 Dynarr_free (buf); | |
1150 } | |
1151 | |
1152 | |
1153 /***************************************************************************** | |
1154 mswindows_output_vertical_divider | |
1155 | |
1156 Draw a vertical divider down the right side of the given window. | |
1157 ****************************************************************************/ | |
1158 static void | |
2286 | 1159 mswindows_output_vertical_divider (struct window *w, int UNUSED (clear_unused)) |
428 | 1160 { |
1161 struct frame *f = XFRAME (w->frame); | |
442 | 1162 HDC hdc = get_frame_dc (f, 1); |
428 | 1163 RECT rect; |
1164 int spacing = XINT (w->vertical_divider_spacing); | |
1165 int shadow = XINT (w->vertical_divider_shadow_thickness); | |
1166 int abs_shadow = abs (shadow); | |
1167 int line_width = XINT (w->vertical_divider_line_width); | |
1168 int div_left = WINDOW_RIGHT (w) - window_divider_width (w); | |
442 | 1169 int y1 = WINDOW_TOP (w); |
1170 int y2 = WINDOW_BOTTOM (w); | |
428 | 1171 |
1172 /* Clear left and right spacing areas */ | |
1173 if (spacing) | |
1174 { | |
1175 rect.top = y1; | |
1176 rect.bottom = y2; | |
440 | 1177 mswindows_update_dc (hdc, Qnil, |
428 | 1178 WINDOW_FACE_CACHEL_BACKGROUND (w, DEFAULT_INDEX), Qnil); |
1179 rect.right = WINDOW_RIGHT (w); | |
1180 rect.left = rect.right - spacing; | |
771 | 1181 ExtTextOutW (hdc, 0, 0, ETO_OPAQUE, &rect, NULL, 0, NULL); |
428 | 1182 rect.left = div_left; |
1183 rect.right = div_left + spacing; | |
771 | 1184 ExtTextOutW (hdc, 0, 0, ETO_OPAQUE, &rect, NULL, 0, NULL); |
428 | 1185 } |
1186 | |
1187 /* Clear divider face */ | |
1188 rect.top = y1 + abs_shadow; | |
1189 rect.bottom = y2 - abs_shadow; | |
1190 rect.left = div_left + spacing + abs_shadow; | |
1191 rect.right = rect.left + line_width; | |
1192 if (rect.left < rect.right) | |
1193 { | |
1194 face_index div_face | |
1195 = get_builtin_face_cache_index (w, Vvertical_divider_face); | |
440 | 1196 mswindows_update_dc (hdc, Qnil, |
428 | 1197 WINDOW_FACE_CACHEL_BACKGROUND (w, div_face), Qnil); |
771 | 1198 ExtTextOutW (hdc, 0, 0, ETO_OPAQUE, &rect, NULL, 0, NULL); |
428 | 1199 } |
1200 | |
1201 /* Draw a shadow around the divider */ | |
1202 if (shadow != 0) | |
1203 { | |
1204 /* #### This will be fixed to support arbitrary thickness */ | |
1205 InflateRect (&rect, abs_shadow, abs_shadow); | |
440 | 1206 DrawEdge (hdc, &rect, |
428 | 1207 shadow > 0 ? EDGE_RAISED : EDGE_SUNKEN, BF_RECT); |
1208 } | |
1209 } | |
1210 | |
1211 /**************************************************************************** | |
1212 mswindows_text_width | |
1213 | |
1214 Given a string and a face, return the string's length in pixels when | |
1215 displayed in the font associated with the face. | |
1216 ****************************************************************************/ | |
1217 static int | |
4928
ea701c23ed84
change text_width method to take a window, in preparation for unicode-internal changes
Ben Wing <ben@xemacs.org>
parents:
4476
diff
changeset
|
1218 mswindows_text_width (struct window *w, struct face_cachel *cachel, |
867 | 1219 const Ichar *str, Charcount len) |
428 | 1220 { |
4928
ea701c23ed84
change text_width method to take a window, in preparation for unicode-internal changes
Ben Wing <ben@xemacs.org>
parents:
4476
diff
changeset
|
1221 struct frame *f = WINDOW_XFRAME (w); |
442 | 1222 HDC hdc = get_frame_dc (f, 0); |
428 | 1223 int width_so_far = 0; |
771 | 1224 textual_run *runs; |
428 | 1225 int nruns; |
1226 int i; | |
1227 | |
771 | 1228 nruns = separate_textual_runs (&runs, str, len); |
428 | 1229 |
1230 for (i = 0; i < nruns; i++) | |
771 | 1231 width_so_far += mswindows_text_width_single_run (hdc, cachel, runs + i); |
428 | 1232 |
1233 return width_so_far; | |
1234 } | |
1235 | |
1236 | |
1237 /**************************************************************************** | |
1238 mswindows_clear_region | |
1239 | |
1240 Clear the area in the box defined by the given parameters using the | |
1241 given face. | |
1242 ****************************************************************************/ | |
1243 static void | |
5046 | 1244 mswindows_clear_region (Lisp_Object USED_IF_SCROLLBARS (locale), |
2286 | 1245 struct device *UNUSED (d), struct frame *f, |
1246 face_index UNUSED (findex), int x, int y, | |
1247 int width, int height, Lisp_Object fcolor, | |
5080
5502045ec510
The background-placement face property.
Didier Verna <didier@lrde.epita.fr>
parents:
5046
diff
changeset
|
1248 Lisp_Object bcolor, |
5502045ec510
The background-placement face property.
Didier Verna <didier@lrde.epita.fr>
parents:
5046
diff
changeset
|
1249 Lisp_Object background_pixmap, |
5502045ec510
The background-placement face property.
Didier Verna <didier@lrde.epita.fr>
parents:
5046
diff
changeset
|
1250 Lisp_Object background_placement) |
428 | 1251 { |
1252 RECT rect = { x, y, x+width, y+height }; | |
442 | 1253 HDC hdc = get_frame_dc (f, 1); |
428 | 1254 |
1255 if (!NILP (background_pixmap)) | |
1256 { | |
1257 struct display_box db = { x, y, width, height }; | |
440 | 1258 mswindows_update_dc (hdc, |
1259 fcolor, bcolor, background_pixmap); | |
428 | 1260 mswindows_output_dibitmap_region |
5138
6d13ad8ed3b2
implement absolute background-placement for Windows, sort of
Ben Wing <ben@xemacs.org>
parents:
5080
diff
changeset
|
1261 (f, XIMAGE_INSTANCE (background_pixmap), &db, 0, |
6d13ad8ed3b2
implement absolute background-placement for Windows, sort of
Ben Wing <ben@xemacs.org>
parents:
5080
diff
changeset
|
1262 EQ (background_placement, Qabsolute)); |
428 | 1263 } |
1264 else | |
1265 { | |
440 | 1266 mswindows_update_dc (hdc, Qnil, fcolor, Qnil); |
771 | 1267 ExtTextOutW (hdc, 0, 0, ETO_OPAQUE, &rect, NULL, 0, NULL); |
428 | 1268 } |
1269 | |
1270 #ifdef HAVE_SCROLLBARS | |
1271 if (WINDOWP (locale)) | |
1318 | 1272 mswindows_redisplay_deadbox (XWINDOW (locale), x, y, width, height); |
428 | 1273 #endif |
1274 } | |
1275 | |
1318 | 1276 /* #### Implement me! */ |
428 | 1277 static void |
2286 | 1278 mswindows_clear_frame (struct frame *UNUSED (f)) |
428 | 1279 { |
1318 | 1280 GdiFlush (); |
428 | 1281 } |
1282 | |
1283 | |
1284 /************************************************************************/ | |
1285 /* initialization */ | |
1286 /************************************************************************/ | |
1287 | |
1288 void | |
1289 console_type_create_redisplay_mswindows (void) | |
1290 { | |
440 | 1291 /* redisplay methods - display*/ |
428 | 1292 CONSOLE_HAS_METHOD (mswindows, text_width); |
1293 CONSOLE_HAS_METHOD (mswindows, output_display_block); | |
1294 CONSOLE_HAS_METHOD (mswindows, divider_height); | |
1295 CONSOLE_HAS_METHOD (mswindows, eol_cursor_width); | |
1296 CONSOLE_HAS_METHOD (mswindows, output_vertical_divider); | |
1297 CONSOLE_HAS_METHOD (mswindows, clear_region); | |
1298 CONSOLE_HAS_METHOD (mswindows, clear_frame); | |
442 | 1299 CONSOLE_HAS_METHOD (mswindows, frame_output_begin); |
1300 CONSOLE_HAS_METHOD (mswindows, frame_output_end); | |
428 | 1301 CONSOLE_HAS_METHOD (mswindows, flash); |
1302 CONSOLE_HAS_METHOD (mswindows, ring_bell); | |
1303 CONSOLE_HAS_METHOD (mswindows, bevel_area); | |
1304 CONSOLE_HAS_METHOD (mswindows, output_string); | |
1305 CONSOLE_HAS_METHOD (mswindows, output_pixmap); | |
1318 | 1306 #ifdef HAVE_SCROLLBARS |
1307 CONSOLE_HAS_METHOD (mswindows, redisplay_deadbox); | |
1308 #endif | |
440 | 1309 |
1310 /* redisplay methods - printer */ | |
442 | 1311 CONSOLE_HAS_METHOD (msprinter, frame_output_end); |
440 | 1312 CONSOLE_INHERITS_METHOD (msprinter, mswindows, text_width); |
1313 CONSOLE_INHERITS_METHOD (msprinter, mswindows, output_display_block); | |
1314 CONSOLE_INHERITS_METHOD (msprinter, mswindows, divider_height); | |
1315 CONSOLE_INHERITS_METHOD (msprinter, mswindows, eol_cursor_width); | |
1316 CONSOLE_INHERITS_METHOD (msprinter, mswindows, output_vertical_divider); | |
1317 CONSOLE_INHERITS_METHOD (msprinter, mswindows, clear_region); | |
1318 CONSOLE_INHERITS_METHOD (msprinter, mswindows, clear_frame); | |
442 | 1319 CONSOLE_INHERITS_METHOD (msprinter, mswindows, frame_output_begin); |
440 | 1320 CONSOLE_INHERITS_METHOD (msprinter, mswindows, bevel_area); |
1321 CONSOLE_INHERITS_METHOD (msprinter, mswindows, output_string); | |
1322 CONSOLE_INHERITS_METHOD (msprinter, mswindows, output_pixmap); | |
428 | 1323 } |