Mercurial > hg > xemacs-beta
view src/intl-encap-win32.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 | 7eec2a1f3412 |
children | 308d34e9f07d |
line wrap: on
line source
/* Unicode-encapsulation of Win32 library functions. Copyright (C) 2000, 2001, 2002, 2004, 2010 Ben Wing. This file is part of XEmacs. XEmacs is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. XEmacs is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with XEmacs; see the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* Synched up with: Not in FSF. */ /* Authorship: Current primary author: Ben Wing <ben@xemacs.org> Created summer 2000 by Ben Wing. Completed August 2001. Completely written by Ben Wing. */ #define NEED_MSWINDOWS_COMMCTRL #define NEED_MSWINDOWS_SHLOBJ #include <config.h> #include "lisp.h" #include "console-msw.h" int no_mswin_unicode_lib_calls; /************************************************************************/ /* auto-generation */ /************************************************************************/ /* we use a simple script to control the auto-generation. \(The following is copied from lib-src/make-mswin-unicode.pl.) file specifies a file to start reading from. yes indicates a function to be automatically Unicode-encapsulated. (All parameters either need no special processing or are LPTSTR or LPCTSTR.) override indidates a function where the prototype can be overridden due to errors in Cygwin or Visual Studio. soon indicates a function that should be automatically Unicode-encapsulated, but we're not ready to process it yet. no indicates a function we don't support (it will be #defined to cause a compile error, with the text after the function included in the erroneous definition to indicate why we don't support it). review indicates a function that we still need to review to determine whether or how to support it. This has the same effect as `no', with a comment indicating that the function needs review. skip indicates a function we support manually; only a comment about this will be generated. split indicates a function with a split structure (different versions for Unicode and ANSI), but where the only difference is in pointer types, and the actual size does not differ. The structure name should follow the function name, and it will be automatically Unicode-encapsulated with appropriate casts. begin-bracket indicates a #if statement to be inserted here. end-bracket indicates the corresponding #endif statement. blank lines and lines beginning with // are ignored. The generated files go into intl-auto-encap-win32.[ch]. To regenerate, go to the nt/ subdirectory and type nmake -f xemacs.mak unicode-encapsulate This does the following: cd $(SRC) perl ../lib-src/make-mswin-unicode.pl --c-output intl-auto-encap-win32.c --h-output intl-auto-encap-win32.h intl-encap-win32.c */ /* terminology used below: "split-simple" means a structure where the A and W versions are the same size, and the only differences are string pointer arguments. (This does NOT include structures with a pointer to a split-sized structure within them.) This can also refer to a function pointer whose only split arguments are string pointers or split-simple structures. "split-sized" means a structure where the A and W versions are different sizes (typically because of an inline string argument), or where there's a pointer to another split-sized structure. "split-complex" begin-unicode-encapsulation-script // dir c:\Program Files\Microsoft Visual Studio\VC98\Include\ file ACLAPI.h yes GetNamedSecurityInfo review BuildExplicitAccessWithName review BuildSecurityDescriptor review BuildTrusteeWithName review BuildTrusteeWithObjectsAndName review BuildTrusteeWithObjectsAndSid review BuildTrusteeWithSid review GetAuditedPermissionsFromAcl review GetEffectiveRightsFromAcl review GetExplicitEntriesFromAcl review GetTrusteeForm review GetTrusteeName review GetTrusteeType review LookupSecurityDescriptorParts review SetEntriesInAcl review SetNamedSecurityInfo review BuildImpersonateExplicitAccessWithName review BuildImpersonateTrustee review GetMultipleTrustee review GetMultipleTrusteeOperation file WINBASE.H yes GetBinaryType yes GetShortPathName no GetLongPathName Win98/2K+ only skip GetEnvironmentStrings misnamed ANSI version of the function yes FreeEnvironmentStrings yes FormatMessage yes CreateMailslot begin-bracket !defined (CYGWIN_HEADERS) no EncryptFile Win2K+ only no DecryptFile Win2K+ only end-bracket no OpenRaw error "The procedure entry point OpenRawW could not be located in the dynamic link library ADVAPI32.dll." no QueryRecoveryAgents split-sized LPRECOVERY_AGENT_INFORMATION yes lstrcmp yes lstrcmpi yes lstrcpyn yes lstrcpy yes lstrcat yes lstrlen yes CreateMutex yes OpenMutex yes CreateEvent yes OpenEvent yes CreateSemaphore yes OpenSemaphore yes CreateWaitableTimer yes OpenWaitableTimer yes CreateFileMapping yes OpenFileMapping yes GetLogicalDriveStrings yes LoadLibrary yes LoadLibraryEx yes GetModuleFileName yes GetModuleHandle split CreateProcess LPSTARTUPINFO yes FatalAppExit split GetStartupInfo LPSTARTUPINFO yes GetCommandLine yes GetEnvironmentVariable yes SetEnvironmentVariable yes ExpandEnvironmentStrings yes OutputDebugString yes FindResource yes FindResourceEx skip EnumResourceTypes different prototypes in VC6 and VC7 skip EnumResourceNames different prototypes in VC6 and VC7 skip EnumResourceLanguages different prototypes in VC6 and VC7 yes BeginUpdateResource yes UpdateResource yes EndUpdateResource yes GlobalAddAtom yes GlobalFindAtom yes GlobalGetAtomName yes AddAtom yes FindAtom yes GetAtomName yes GetProfileInt yes GetProfileString yes WriteProfileString yes GetProfileSection yes WriteProfileSection yes GetPrivateProfileInt yes GetPrivateProfileString yes WritePrivateProfileString yes GetPrivateProfileSection yes WritePrivateProfileSection yes GetPrivateProfileSectionNames yes GetPrivateProfileStruct yes WritePrivateProfileStruct yes GetDriveType yes GetSystemDirectory yes GetTempPath yes GetTempFileName yes GetWindowsDirectory yes SetCurrentDirectory yes GetCurrentDirectory yes GetDiskFreeSpace yes GetDiskFreeSpaceEx yes CreateDirectory yes CreateDirectoryEx yes RemoveDirectory yes GetFullPathName yes DefineDosDevice yes QueryDosDevice yes CreateFile yes SetFileAttributes yes GetFileAttributes yes GetFileAttributesEx yes GetCompressedFileSize yes DeleteFile no FindFirstFileEx split-sized LPWIN32_FIND_DATA; not used, NT 4.0+ only skip FindFirstFile split-sized LPWIN32_FIND_DATA skip FindNextFile split-sized LPWIN32_FIND_DATA yes SearchPath yes CopyFile yes CopyFileEx NT 4.0+ only yes MoveFile yes MoveFileEx no MoveFileWithProgress NT 5.0+ only no CreateHardLink NT 5.0+ only yes CreateNamedPipe yes GetNamedPipeHandleState yes CallNamedPipe yes WaitNamedPipe yes SetVolumeLabel yes GetVolumeInformation yes ClearEventLog yes BackupEventLog yes OpenEventLog yes RegisterEventSource yes OpenBackupEventLog yes ReadEventLog yes ReportEvent yes AccessCheckAndAuditAlarm no AccessCheckByTypeAndAuditAlarm NT 5.0+ only no AccessCheckByTypeResultListAndAuditAlarm NT 5.0+ only yes ObjectOpenAuditAlarm yes ObjectPrivilegeAuditAlarm yes ObjectCloseAuditAlarm yes ObjectDeleteAuditAlarm yes PrivilegedServiceAuditAlarm yes SetFileSecurity yes GetFileSecurity yes FindFirstChangeNotification no ReadDirectoryChanges Unicode-only yes IsBadStringPtr yes LookupAccountSid yes LookupAccountName yes LookupPrivilegeValue yes LookupPrivilegeName yes LookupPrivilegeDisplayName yes BuildCommDCB yes BuildCommDCBAndTimeouts yes CommConfigDialog yes GetDefaultCommConfig yes SetDefaultCommConfig yes GetComputerName yes SetComputerName yes GetUserName yes LogonUser split CreateProcessAsUser LPSTARTUPINFO no GetCurrentHwProfile split-sized LPHW_PROFILE_INFO; NT 4.0+ only no GetVersionEx split-sized LPOSVERSIONINFO no CreateJobObject NT 5.0+ only no OpenJobObject NT 5.0+ only review CheckNameLegalDOS8Dot3 review CreateActCtx review CreateProcessWithLogon review DeleteVolumeMountPoint review DnsHostnameToComputerName review FileEncryptionStatus review FindActCtxSectionString review FindFirstVolume review FindFirstVolumeMountPoint review FindNextVolume review FindNextVolumeMountPoint review GetFirmwareEnvironmentVariable review GetComputerNameEx review GetDllDirectory review GetModuleHandleEx review GetSystemWindowsDirectory review GetSystemWow64Directory review GetVolumeNameForVolumeMountPoint review GetVolumePathName review GetVolumePathNamesForVolumeName review QueryActCtx review ReplaceFile review SetComputerNameEx review SetDllDirectory review SetFileShortName review SetFirmwareEnvironmentVariable review SetVolumeMountPoint review VerifyVersionInfo file WINUSER.H skip MAKEINTRESOURCE macro yes wvsprintf no wsprintf varargs yes LoadKeyboardLayout yes GetKeyboardLayoutName no CreateDesktop split-sized LPDEVMODE yes OpenDesktop split EnumDesktops DESKTOPENUMPROC // callback fun differs only in string pointer type override HWINSTA CreateWindowStationW(LPWSTR,DWORD,DWORD,LPSECURITY_ATTRIBUTES); error arg 1, VS6 prototype, missing const yes OpenWindowStation split EnumWindowStations WINSTAENUMPROC // callback fun differs only in string pointer type yes GetUserObjectInformation yes SetUserObjectInformation yes RegisterWindowMessage yes GetMessage yes DispatchMessage yes PeekMessage skip SendMessage split messages and structures no SendMessageTimeout VS6 has erroneous seventh parameter DWORD_PTR instead of PDWORD_PTR yes SendNotifyMessage yes SendMessageCallback no BroadcastSystemMessage win95 version not split; NT 4.0+ only no RegisterDeviceNotification NT 5.0+ only yes PostMessage yes PostThreadMessage no PostAppMessage macro skip DefWindowProc return value is conditionalized on _MAC, messes up parser no CallWindowProc two versions, STRICT and non-STRICT skip RegisterClass need to intercept so we can provide our own window procedure and handle split notify messages; split-simple WNDCLASS skip UnregisterClass need to intercept for reasons related to RegisterClass split GetClassInfo LPWNDCLASS skip RegisterClassEx need to intercept so we can provide our own window procedure and handle split notify messages; split-simple WNDCLASSEX; NT 4.0+ only split GetClassInfoEx LPWNDCLASSEX NT 4.0+ only yes CreateWindowEx skip CreateWindow macro yes CreateDialogParam split CreateDialogIndirectParam LPCDLGTEMPLATE error in Cygwin prototype (no split) but fixable with typedef no CreateDialog macro no CreateDialogIndirect macro w/split LPCDLGTEMPLATE yes DialogBoxParam split DialogBoxIndirectParam LPCDLGTEMPLATE error in Cygwin prototype (no split) but fixable with typedef no DialogBox macro no DialogBoxIndirect macro w/split LPCDLGTEMPLATE yes SetDlgItemText yes GetDlgItemText yes SendDlgItemMessage no DefDlgProc return value is conditionalized on _MAC, messes up parser begin-bracket !defined (CYGWIN_HEADERS) yes CallMsgFilter end-bracket yes RegisterClipboardFormat yes GetClipboardFormatName yes CharToOem yes OemToChar yes CharToOemBuff yes OemToCharBuff yes CharUpper yes CharUpperBuff yes CharLower yes CharLowerBuff yes CharNext yes CharPrev no IsCharAlpha split CHAR no IsCharAlphaNumeric split CHAR no IsCharUpper split CHAR no IsCharLower split CHAR yes GetKeyNameText skip VkKeyScan split CHAR no VkKeyScanEx split CHAR; NT 4.0+ only yes MapVirtualKey yes MapVirtualKeyEx NT 4.0+ only yes LoadAccelerators yes CreateAcceleratorTable yes CopyAcceleratorTable yes TranslateAccelerator yes LoadMenu split LoadMenuIndirect MENUTEMPLATE yes ChangeMenu yes GetMenuString yes InsertMenu yes AppendMenu yes ModifyMenu split InsertMenuItem LPCMENUITEMINFO NT 4.0+ only split GetMenuItemInfo LPMENUITEMINFO NT 4.0+ only split SetMenuItemInfo LPCMENUITEMINFO NT 4.0+ only yes DrawText yes DrawTextEx NT 4.0+ only yes GrayString yes DrawState NT 4.0+ only yes TabbedTextOut yes GetTabbedTextExtent yes SetProp yes GetProp yes RemoveProp split EnumPropsEx PROPENUMPROCEX // callback fun differs only in string pointer type split EnumProps PROPENUMPROC // callback fun differs only in string pointer type yes SetWindowText yes GetWindowText yes GetWindowTextLength yes MessageBox yes MessageBoxEx // split MessageBoxIndirect LPMSGBOXPARAMS NT 4.0+ only no MessageBoxIndirect Cygwin has split MSGBOXPARAMS* instead of LPMSGBOXPARAMS yes GetWindowLong yes SetWindowLong yes GetClassLong yes SetClassLong yes FindWindow yes FindWindowEx NT 4.0+ only yes GetClassName no SetWindowsHook obsolete; two versions, STRICT and non-STRICT yes SetWindowsHookEx yes LoadBitmap yes LoadCursor yes LoadCursorFromFile yes LoadIcon yes LoadImage NT 4.0+ only yes LoadString yes IsDialogMessage yes DlgDirList yes DlgDirSelectEx yes DlgDirListComboBox yes DlgDirSelectComboBoxEx yes DefFrameProc no DefMDIChildProc return value is conditionalized on _MAC, messes up parser override HWND CreateMDIWindowW(LPWSTR,LPWSTR,DWORD,int,int,int,int,HWND,HINSTANCE,LPARAM); error arg 1, VS6 prototype, missing const yes WinHelp no ChangeDisplaySettings split-sized LPDEVMODE no ChangeDisplaySettingsEx split-sized LPDEVMODE; NT 5.0/Win98+ only no EnumDisplaySettings split-sized LPDEVMODE no EnumDisplayDevices split-sized PDISPLAY_DEVICE; NT 5.0+ only, no Win98 yes SystemParametersInfo probs w/ICONMETRICS, NONCLIENTMETRICS no GetMonitorInfo NT 5.0/Win98+ only no GetWindowModuleFileName NT 5.0+ only no RealGetWindowClass NT 5.0+ only no GetAltTabInfo NT 5.0+ only review BroadcastSystemMessageEx review EnumDisplaySettingsEx review GetClassLongPtr review GetRawInputDeviceInfo review GetWindowLongPtr review SetClassLongPtr review SetWindowLongPtr file WINGDI.H begin-bracket defined (HAVE_MS_WINDOWS) // split-sized LOGCOLORSPACE // split-sized TEXTMETRIC // split-sized NEWTEXTMETRIC // split-sized NEWTEXTMETRICEX // split-sized LOGFONT // split-sized ENUMLOGFONT // split-sized ENUMLOGFONTEX // split-sized EXTLOGFONT, used in EMREXTCREATEFONTINDIRECTW (Unicode-only) and (???) in DEVINFO (DDK structure) // split-sized DEVMODE // split-sized DISPLAY_DEVICE, used in EnumDisplayDevices // split-sized OUTLINETEXTMETRIC // split-simple POLYTEXT // split-simple GCP_RESULTS // split-sized function pointer OLDFONTENUMPROC, same as FONTENUMPROC // split-sized function pointer FONTENUMPROC yes AddFontResource yes CopyMetaFile skip CreateDC split-sized DEVMODE skip CreateFontIndirect split-sized LOGFONT yes CreateFont skip CreateIC split-sized DEVMODE yes CreateMetaFile yes CreateScalableFontResource skip DeviceCapabilities split-sized DEVMODE skip EnumFontFamiliesEx split-complex FONTENUMPROC; NT 4.0+ only no EnumFontFamilies split-complex FONTENUMPROC no EnumFonts split-complex FONTENUMPROC yes GetCharWidth yes GetCharWidth32 yes GetCharWidthFloat yes GetCharABCWidths yes GetCharABCWidthsFloat yes GetGlyphOutline yes GetMetaFile no GetOutlineTextMetrics split-sized LPOUTLINETEXTMETRIC yes GetTextExtentPoint yes GetTextExtentPoint32 yes GetTextExtentExPoint split GetCharacterPlacement LPGCP_RESULTS NT 4.0+ only no GetGlyphIndices NT 5.0+ only no AddFontResourceEx NT 5.0+ only no RemoveFontResourceEx NT 5.0+ only // split-sized AXISINFO, used in AXESLIST; NT 5.0+ only // split-sized AXESLIST, used in ENUMLOGFONTEXDV; NT 5.0+ only // split-sized ENUMLOGFONTEXDV; NT 5.0+ only no CreateFontIndirectEx split-sized ENUMLOGFONTEXDV; NT 5.0+ only // split-sized ENUMTEXTMETRIC, returned in EnumFontFamExProc, on NT 5.0+; NT 5.0+ only skip ResetDC split-sized DEVMODE yes RemoveFontResource yes CopyEnhMetaFile yes CreateEnhMetaFile yes GetEnhMetaFile yes GetEnhMetaFileDescription skip GetTextMetrics split-sized LPTEXTMETRIC // split-simple DOCINFO split StartDoc DOCINFO skip GetObject split-sized LOGFONT yes TextOut yes ExtTextOut split PolyTextOut POLYTEXT yes GetTextFace yes GetKerningPairs // split-simple function pointer ICMENUMPROC no GetLogColorSpace split-sized LPLOGCOLORSPACE; NT 4.0+ only no CreateColorSpace split-sized LPLOGCOLORSPACE; NT 4.0+ only yes GetICMProfile NT 4.0+ only, former error in Cygwin prototype but no more (Cygwin 1.7, 1-30-10) yes SetICMProfile NT 4.0+ only split EnumICMProfiles ICMENUMPROC NT 4.0+ only skip UpdateICMRegKey NT 4.0+ only, error in Cygwin prototype // non-split EMREXTTEXTOUT (A and W versions identical) // non-split EMRPOLYTEXTOUT (A and W versions identical) // Unicode-only EMREXTCREATEFONTINDIRECTW no wglUseFontBitmaps causes link error no wglUseFontOutlines causes link error end-bracket file WINSPOOL.H begin-bracket defined (HAVE_MS_WINDOWS) yes EnumPrinters #### problems with DEVMODE pointer in PRINTER_INFO_2 skip OpenPrinter split-sized DEVMODE pointer in split PRINTER_DEFAULTS no ResetPrinter split-sized DEVMODE pointer in split PRINTER_DEFAULTS no SetJob split-sized DEVMODE pointer in split JOB_INFO_2 no GetJob split-sized DEVMODE pointer in split JOB_INFO_2 no EnumJobs split-sized DEVMODE pointer in split JOB_INFO_2 no AddPrinter split-sized DEVMODE pointer in split PRINTER_INFO_2 no SetPrinter split-sized DEVMODE pointer in split PRINTER_INFO_2 no GetPrinter split-sized DEVMODE pointer in split PRINTER_INFO_2 // other than DocumentProperties below, we don't use any of the others, // and they all pretty much have complicated interfaces with lots of // split structures, etc. no AddPrinterDriver not used, complicated interface with split structures no AddPrinterDriverEx not used, complicated interface with split structures no EnumPrinterDrivers not used, complicated interface with split structures no GetPrinterDriver not used, complicated interface with split structures no GetPrinterDriverDirectory not used, complicated interface with split structures no DeletePrinterDriver not used, complicated interface with split structures no DeletePrinterDriverEx not used, complicated interface with split structures no AddPerMachineConnection not used, complicated interface with split structures no DeletePerMachineConnection not used, complicated interface with split structures no EnumPerMachineConnections not used, complicated interface with split structures no AddPrintProcessor not used, complicated interface with split structures no EnumPrintProcessors not used, complicated interface with split structures no GetPrintProcessorDirectory not used, complicated interface with split structures no EnumPrintProcessorDatatypes not used, complicated interface with split structures no DeletePrintProcessor not used, complicated interface with split structures no StartDocPrinter not used, complicated interface with split structures no AddJob not used, complicated interface with split structures skip DocumentProperties split-sized DEVMODE, error in Cygwin prototype no AdvancedDocumentProperties not used, complicated interface with split structures no GetPrinterData not used, complicated interface with split structures no GetPrinterDataEx not used, complicated interface with split structures no EnumPrinterData not used, complicated interface with split structures no EnumPrinterDataEx not used, complicated interface with split structures no EnumPrinterKey not used, complicated interface with split structures no SetPrinterData not used, complicated interface with split structures no SetPrinterDataEx not used, complicated interface with split structures no DeletePrinterData not used, complicated interface with split structures no DeletePrinterDataEx not used, complicated interface with split structures no DeletePrinterKey not used, complicated interface with split structures no PrinterMessageBox not used, complicated interface with split structures no AddForm not used, complicated interface with split structures no DeleteForm not used, complicated interface with split structures no GetForm not used, complicated interface with split structures no SetForm not used, complicated interface with split structures no EnumForms not used, complicated interface with split structures no EnumMonitors not used, complicated interface with split structures no AddMonitor not used, complicated interface with split structures no DeleteMonitor not used, complicated interface with split structures no EnumPorts not used, complicated interface with split structures no AddPort not used, complicated interface with split structures no ConfigurePort not used, complicated interface with split structures no DeletePort not used, complicated interface with split structures no XcvData not used, complicated interface with split structures no SetPort not used, complicated interface with split structures no AddPrinterConnection not used, complicated interface with split structures no DeletePrinterConnection not used, complicated interface with split structures no AddPrintProvidor not used, complicated interface with split structures no DeletePrintProvidor not used, complicated interface with split structures no SetPrinterHTMLView not used, complicated interface with split structures no GetPrinterHTMLView not used, complicated interface with split structures review GetDefaultPrinter end-bracket file SHELLAPI.H yes DragQueryFile yes ShellExecute yes FindExecutable no CommandLineToArgv Unicode-only yes ShellAbout override HICON ExtractAssociatedIconW(HINSTANCE, LPWSTR, LPWORD); error arg2, Cygwin prototype, extra const yes ExtractIcon // split-simple DRAGINFO, used ??? (docs say "Not currently supported") begin-bracket !defined (CYGWIN_HEADERS) yes DoEnvironmentSubst NT 4.0+ only end-bracket no FindEnvironmentString causes link error; NT 4.0+ only yes ExtractIconEx NT 4.0+ only, former error in Cygwin prototype but no more (Cygwin 1.7, 1-30-10) // split-simple SHFILEOPSTRUCT, used in SHFileOperation // split-simple SHNAMEMAPPING, used in SHFileOperation split SHFileOperation LPSHFILEOPSTRUCT NT 4.0+ only // split-simple SHELLEXECUTEINFO, used in ShellExecuteEx split ShellExecuteEx LPSHELLEXECUTEINFO NT 4.0+ only no WinExecError causes link error; NT 4.0+ only begin-bracket !defined (CYGWIN_HEADERS) yes SHQueryRecycleBin NT 4.0+ only yes SHEmptyRecycleBin NT 4.0+ only end-bracket // split-sized NOTIFYICONDATA, used in Shell_NotifyIcon no Shell_NotifyIcon split-sized NOTIFYICONDATA, NT 4.0+ only // split-sized SHFILEINFO, used in SHGetFileInfo skip SHGetFileInfo split-sized SHFILEINFO, NT 4.0+ only no SHGetDiskFreeSpace causes link error; NT 4.0+ only begin-bracket !defined (CYGWIN_HEADERS) yes SHGetNewLinkInfo NT 4.0+ only yes SHInvokePrinterCommand NT 4.0+ only end-bracket end-unicode-encapsulation-script file COMMCTRL.H yes ImageList_LoadImage WC_HEADER HDITEM LPHDITEM HDM_INSERTITEM HDM_GETITEM HDM_SETITEM HDN_ITEMCHANGING HDN_ITEMCHANGED HDN_ITEMCLICK HDN_ITEMDBLCLICK HDN_DIVIDERDBLCLICK HDN_BEGINTRACK HDN_ENDTRACK HDN_TRACK HDN_GETDISPINFO NMHEADER LPNMHEADER NMHDDISPINFO LPNMHDDISPINFO TOOLBARCLASSNAME TBSAVEPARAMS LPTBSAVEPARAMS TB_GETBUTTONTEXT TB_SAVERESTORE TB_ADDSTRING TBBUTTONINFO LPTBBUTTONINFO TB_GETBUTTONINFO TB_SETBUTTONINFO TB_INSERTBUTTON TB_ADDBUTTONS TBN_GETINFOTIP NMTBGETINFOTIP LPNMTBGETINFOTIP TBN_GETDISPINFO LPNMTBDISPINFO TBN_GETBUTTONINFO NMTOOLBAR LPNMTOOLBAR REBARCLASSNAME REBARBANDINFO LPREBARBANDINFO LPCREBARBANDINFO RB_INSERTBAND RB_SETBANDINFO RB_GETBANDINFO TOOLTIPS_CLASS TTTOOLINFO PTOOLINFO LPTTTOOLINFO TTM_ADDTOOL TTM_DELTOOL TTM_NEWTOOLRECT TTM_GETTOOLINFO TTM_SETTOOLINFO TTM_HITTEST TTM_GETTEXT TTM_UPDATETIPTEXT TTM_ENUMTOOLS TTM_GETCURRENTTOOL TTHITTESTINFO LPTTHITTESTINFO TTN_GETDISPINFO NMTTDISPINFO LPNMTTDISPINFO CreateStatusWindow DrawStatusText STATUSCLASSNAME SB_GETTEXT SB_SETTEXT SB_GETTEXTLENGTH SB_SETTIPTEXT SB_GETTIPTEXT TRACKBAR_CLASS UPDOWN_CLASS PROGRESS_CLASS HOTKEY_CLASS WC_LISTVIEW LVITEM LPLVITEM LPSTR_TEXTCALLBACK LVM_GETITEM LVM_SETITEM LVM_INSERTITEM LVFINDINFO LVM_FINDITEM LVM_GETSTRINGWIDTH LVM_EDITLABEL LVCOLUMN LPLVCOLUMN LVM_GETCOLUMN LVM_SETCOLUMN LVM_GETITEMTEXT LVM_SETITEMTEXT LVM_GETISEARCHSTRING LVBKIMAGE LPLVBKIMAGE LVM_SETBKIMAGE LVM_GETBKIMAGE LVN_ODFINDITEM LVN_BEGINLABELEDIT LVN_ENDLABELEDIT LVN_GETDISPINFO LVN_SETDISPINFO NMLVDISPINFO LVN_GETINFOTIP NMLVGETINFOTIP LPNMLVGETINFOTIP WC_TREEVIEW TVITEM LPTVITEM TVINSERTSTRUCT LPTVINSERTSTRUCT TVM_INSERTITEM TVM_GETITEM TVM_SETITEM TVM_EDITLABEL TVM_GETISEARCHSTRING NMTREEVIEW LPNMTREEVIEW NMTVDISPINFO LPNMTVDISPINFO TVN_SELCHANGING TVN_SELCHANGED TVN_GETDISPINFO TVN_SETDISPINFO TVN_ITEMEXPANDING TVN_ITEMEXPANDED TVN_BEGINDRAG TVN_BEGINRDRAG TVN_DELETEITEM TVN_BEGINLABELEDIT TVN_ENDLABELEDIT TVN_GETINFOTIP NMTVGETINFOTIP LPNMTVGETINFOTIP WC_COMBOBOXEX COMBOBOXEXITEM PCOMBOBOXEXITEM PCCOMBOBOXEXITEM CBEM_INSERTITEM CBEM_SETITEM CBEM_GETITEM NMCOMBOBOXEX PNMCOMBOBOXEX CBEN_GETDISPINFO CBEN_DRAGBEGIN CBEN_ENDEDIT NMCBEDRAGBEGIN LPNMCBEDRAGBEGIN PNMCBEDRAGBEGIN NMCBEENDEDIT LPNMCBEENDEDIT PNMCBEENDEDIT WC_TABCONTROL TCITEMHEADER LPTCITEMHEADER TCITEM LPTCITEM TCM_GETITEM TCM_SETITEM TCM_INSERTITEM ANIMATE_CLASS ACM_OPEN MONTHCAL_CLASS DATETIMEPICK_CLASS DTM_SETFORMAT DTN_USERSTRING NMDATETIMESTRING LPNMDATETIMESTRING DTN_WMKEYDOWN NMDATETIMEWMKEYDOWN LPNMDATETIMEWMKEYDOWN DTN_FORMAT NMDATETIMEFORMAT LPNMDATETIMEFORMAT DTN_FORMATQUERY NMDATETIMEFORMATQUERY LPNMDATETIMEFORMATQUERY WC_IPADDRESS WC_PAGESCROLLER WC_NATIVEFONTCTL begin-unicode-encapsulation-script file COMMDLG.H begin-bracket defined (HAVE_MS_WINDOWS) split GetOpenFileName LPOPENFILENAME split GetSaveFileName LPOPENFILENAME yes GetFileTitle no CommDlg_OpenSave_GetSpec macro no CommDlg_OpenSave_GetFilePath macro no CommDlg_OpenSave_GetFolderPath macro split ChooseColor LPCHOOSECOLOR split FindText LPFINDREPLACE split ReplaceText LPFINDREPLACE no AfxReplaceText mac only no ChooseFont split-sized LPLOGFONT in LPCHOOSEFONT // LBSELCHSTRING // SHAREVISTRING // FILEOKSTRING // COLOROKSTRING // SETRGBSTRING // HELPMSGSTRING // FINDMSGSTRING skip PrintDlg LPPRINTDLG with split-sized DEVMODE handle skip PageSetupDlg LPPAGESETUPDLG with split-sized DEVMODE handle review PrintDlgEx end-bracket file DDE.H // nothing file DDEML.H yes DdeInitialize yes DdeCreateStringHandle former error in Cygwin prototype, but no more (Cygwin 1.7, 1-30-10) yes DdeQueryString // #### split-sized (or split-simple??? not completely obvious) structure MONHSZSTRUCT, used when DDE event MF_HSZ_INFO is sent as part of the XTYP_MONITOR transaction sent to a DDE callback; not yet handled file IMM.H begin-bracket defined (HAVE_MS_WINDOWS) yes ImmInstallIME yes ImmGetDescription yes ImmGetIMEFileName yes ImmGetCompositionString skip ImmSetCompositionString different prototypes in VC6 and VC7 yes ImmGetCandidateListCount yes ImmGetCandidateList yes ImmGetGuideLine skip ImmGetCompositionFont split-sized LOGFONT skip ImmSetCompositionFont split-sized LOGFONT yes ImmConfigureIME // split-simple REGISTERWORD yes ImmEscape // strings of various sorts yes ImmGetConversionList yes ImmIsUIMessage yes ImmRegisterWord yes ImmUnregisterWord no ImmGetRegisterWordStyle split-sized STYLEBUF split ImmEnumRegisterWord REGISTERWORDENUMPROC no ImmGetImeMenuItems split-sized IMEMENUITEMINFO end-bracket file MMSYSTEM.H yes sndPlaySound yes PlaySound no waveOutGetDevCaps split-sized LPWAVEOUTCAPS yes waveOutGetErrorText no waveInGetDevCaps split-sized LPWAVEINCAPS yes waveInGetErrorText no midiOutGetDevCaps split-sized LPMIDIOUTCAPS yes midiOutGetErrorText no midiInGetDevCaps split-sized LPMIDIOUTCAPS yes midiInGetErrorText no auxGetDevCaps split-sized LPAUXCAPS no mixerGetDevCaps split-sized LPMIXERCAPS no mixerGetLineInfo split-sized LPMIXERLINE no mixerGetLineControls split-sized LPMIXERCONTROL no mixerGetControlDetails split-sized LPMIXERCONTROL in LPMIXERLINECONTROLS in LPMIXERCONTROLDETAILS no joyGetDevCaps split-sized LPJOYCAPS yes mmioStringToFOURCC yes mmioInstallIOProc yes mmioOpen yes mmioRename yes mciSendCommand yes mciSendString yes mciGetDeviceID begin-bracket !defined (MINGW) no mciGetDeviceIDFromElementID missing from Win98se version of ADVAPI32.dll end-bracket yes mciGetErrorString file WINNETWK.H begin-bracket defined (HAVE_MS_WINDOWS) yes WNetAddConnection split WNetAddConnection2 LPNETRESOURCE split WNetAddConnection3 LPNETRESOURCE yes WNetCancelConnection yes WNetCancelConnection2 yes WNetGetConnection split WNetUseConnection LPNETRESOURCE split WNetConnectionDialog1 LPCONNECTDLGSTRUCT contains split-simple LPNETRESOURCE split WNetDisconnectDialog1 LPDISCDLGSTRUCT split WNetOpenEnum LPNETRESOURCE yes WNetEnumResource yes WNetGetUniversalName yes WNetGetUser yes WNetGetProviderName yes WNetGetNetworkInformation // split-simple function pointer PFNGETPROFILEPATH // split-simple function pointer PFNRECONCILEPROFILE // split-simple function pointer PFNPROCESSPOLICIES yes WNetGetLastError split MultinetGetConnectionPerformance LPNETRESOURCE review WNetSetConnection review WNetGetResourceInformation review WNetGetResourceParent end-bracket // file IME.H -- doesn't exist under Cygwin no SendIMEMessageEx obsolete, no docs available file OBJBASE.H // nothing file SHLOBJ.H // #### split code for IContextMenu not yet written // split flag constant GCS_VERB of IContextMenu::GetCommandString // split flag constant GCS_HELPTEXT of IContextMenu::GetCommandString // split flag constant GCS_VALIDATE of IContextMenu::GetCommandString // split string constant CMDSTR_NEWFOLDER of CMINVOKECOMMANDINFO.lpVerb or CMINVOKECOMMANDINFOEX.lpVerbW of IContextMenu::InvokeCommand // split string constant CMDSTR_VIEWLIST of same // split string constant CMDSTR_VIEWDETAILS of same // #### split code for IExtractIcon, IShellLink, IShellExecuteHook, INewShortcutHook, ICopyHook, IFileViewer not yet written // split interface IExtractIcon // split interface IShellLink // split interface IShellExecuteHook // split interface INewShortcutHook // split interface ICopyHook // split interface IFileViewer yes SHGetPathFromIDList skip SHGetSpecialFolderPath error in Cygwin prototype, missing from Cygwin libraries // split-simple structure BROWSEINFO used in SHBrowseForFolder skip SHBrowseForFolder need to intercept callback for SendMessage // split message BFFM_SETSTATUSTEXT handled in qxeSendMessage // split message BFFM_SETSELECTION handled in qxeSendMessage // split message BFFM_VALIDATEFAILED handled in qxeSHBrowseForFolder intercept proc // #### code to handle split clipboard formats not yet written. this will // #### be tricky -- all functions that use such clipboard formats need to // #### be split, and the data itself munged. this may be too much effort, // #### and we may just need to require that the app itself does the // #### splitting. // split clipboard format CFSTR_FILEDESCRIPTOR // split clipboard format CFSTR_FILENAME // split clipboard format CFSTR_FILENAMEMAP // split-sized structure FILEDESCRIPTOR // split-sized structure FILEGROUPDESCRIPTOR // split flag SHCNF_PATH; we intercept SHChangeNotify // split flag SHCNF_PRINTER; we intercept SHChangeNotify // split flag SHARD_PATH; we intercept SHAddToRecentDocs skip SHGetDataFromIDList split-sized WIN32_FIND_DATA or split-simple NETRESOURCE, missing from Cygwin libraries review SHGetFolderPath review SHGetIconOverlayIndex review SHCreateDirectoryEx review SHGetFolderPathAndSubDir file WINNLS.H no LOCALE_ENUMPROC not used, not examined yet no CODEPAGE_ENUMPROC not used, not examined yet no DATEFMT_ENUMPROC not used, not examined yet no DATEFMT_ENUMPROCEX not used, not examined yet no TIMEFMT_ENUMPROC not used, not examined yet no CALINFO_ENUMPROC not used, not examined yet no CALINFO_ENUMPROCEX not used, not examined yet no GetCPInfoEx not used, not examined yet no CompareString not used, not examined yet no LCMapString not used, not examined yet yes GetLocaleInfo yes SetLocaleInfo no GetTimeFormat not used, not examined yet no GetDateFormat not used, not examined yet no GetNumberFormat not used, not examined yet no GetCurrencyFormat not used, not examined yet no EnumCalendarInfo not used, not examined yet no EnumCalendarInfoEx not used, not examined yet no EnumTimeFormats not used, not examined yet no EnumDateFormats not used, not examined yet no EnumDateFormatsEx not used, not examined yet no GetStringTypeEx not used, not examined yet no GetStringType no such fun; A and W versions have different nos. of args no FoldString not used, not examined yet no EnumSystemLocales not used, not examined yet no EnumSystemCodePages not used, not examined yet review GetCalendarInfo review GetGeoInfo review SetCalendarInfo review EnumSystemLanguageGroups review EnumLanguageGroupLocales review EnumUILanguages end-unicode-encapsulation-script file WINVER.H VerFindFile VerInstallFile GetFileVersionInfoSize GetFileVersionInfo VerLanguageName VerQueryValue begin-unicode-encapsulation-script file WINCON.H yes PeekConsoleInput yes ReadConsoleInput yes WriteConsoleInput yes ReadConsoleOutput yes WriteConsoleOutput yes ReadConsoleOutputCharacter yes WriteConsoleOutputCharacter no FillConsoleOutputCharacter split CHAR yes ScrollConsoleScreenBuffer yes GetConsoleTitle yes SetConsoleTitle yes ReadConsole yes WriteConsole file WINREG.H yes RegConnectRegistry former error in Cygwin prototype, but no more (Cygwin 1.7, 1-30-10) yes RegCreateKey yes RegCreateKeyEx yes RegDeleteKey yes RegDeleteValue yes RegEnumKey yes RegEnumKeyEx yes RegEnumValue yes RegLoadKey yes RegOpenKey yes RegOpenKeyEx yes RegQueryInfoKey yes RegQueryValue split RegQueryMultipleValues PVALENT yes RegQueryValueEx yes RegReplaceKey yes RegRestoreKey yes RegSaveKey yes RegSetValue yes RegSetValueEx yes RegUnLoadKey yes InitiateSystemShutdown override BOOL AbortSystemShutdownW(LPWSTR); error arg 1, Cygwin prototype, extra const review RegDeleteKeyEx file EXCPT.H // nothing file STDARG.H // nothing file CDERR.H // nothing file WINPERF.H // nothing file RPC.H // nothing file NB30.H // nothing end-unicode-encapsulation-script file WINSOCK2.H SO_PROTOCOL_INFO SERVICE_TYPE_VALUE_SAPID SERVICE_TYPE_VALUE_TCPPORT SERVICE_TYPE_VALUE_UDPPORT SERVICE_TYPE_VALUE_OBJECTID WSADuplicateSocket LPFN_WSADUPLICATESOCKET WSAEnumProtocols LPFN_WSAENUMPROTOCOLS WSASocket LPFN_WSASOCKET WSAAddressToString LPFN_WSAADDRESSTOSTRING WSAStringToAddress LPFN_WSASTRINGTOADDRESS WSALookupServiceBegin LPFN_WSALOOKUPSERVICEBEGIN WSALookupServiceNext LPFN_WSALOOKUPSERVICENEXT WSAInstallServiceClass LPFN_WSAINSTALLSERVICECLASS WSAGetServiceClassInfo LPFN_WSAGETSERVICECLASSINFO WSAEnumNameSpaceProviders LPFN_WSAENUMNAMESPACEPROVIDERS WSAGetServiceClassNameByClassId LPFN_WSAGETSERVICECLASSNAMEBYCLASSID WSASetService LPFN_WSASETSERVICE file WINCRYPT.H MS_DEF_PROV_ MS_ENHANCED_PROV_ MS_DEF_RSA_SIG_PROV_ MS_DEF_RSA_SCHANNEL_PROV_ MS_ENHANCED_RSA_SCHANNEL_PROV_ MS_DEF_DSS_PROV_ MS_DEF_DSS_DH_PROV_ CryptAcquireContext CryptSignHash CryptVerifySignature CryptSetProvider CryptSetProviderEx CryptGetDefaultProvider CryptEnumProviderTypes CryptEnumProviders CERT_STORE_PROV_FILENAME_ CERT_STORE_PROV_SYSTEM_ sz_CERT_STORE_PROV_FILENAME_ sz_CERT_STORE_PROV_SYSTEM_ CERT_STORE_SAVE_TO_FILENAME_ CERT_FIND_SUBJECT_STR_ CERT_FIND_ISSUER_STR_ CertRDNValueToStr CertNameToStr CertStrToName CertOpenSystemStore CertAddEncodedCertificateToSystemStore */ /* the functions below are examples of hand-written Unicode-splitting code. note that it needs to be written very carefully and with intimate knowledge of the structures involved, and can sometimes be very hairy (EnumFontFamiliesEx is the most extreme example). it can be argued with some justification that this behind-the-scenes magic is confusing and potentially dangerous, and shouldn't be done. but making the calling code deal with the results in extremely hard-to- read code and is very error-prone. */ /************************************************************************/ /* would be encapsulatable but for parsing problems */ /************************************************************************/ /* NOTE: return value is conditionalized on _MAC, messes up parser */ LRESULT qxeDefWindowProc (HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) { if (XEUNICODE_P) return DefWindowProcW (hWnd, Msg, wParam, lParam); else return DefWindowProcA (hWnd, Msg, wParam, lParam); } /* NOTE: two versions, STRICT and non-STRICT */ LRESULT qxeCallWindowProc (WNDPROC lpPrevWndFunc, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) { if (XEUNICODE_P) return CallWindowProcW (lpPrevWndFunc, hWnd, Msg, wParam, lParam); else return CallWindowProcA (lpPrevWndFunc, hWnd, Msg, wParam, lParam); } /* NOTE: return value is conditionalized on _MAC, messes up parser */ LRESULT qxeDefDlgProc (HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lParam) { if (XEUNICODE_P) return DefDlgProcW (hDlg, Msg, wParam, lParam); else return DefDlgProcA (hDlg, Msg, wParam, lParam); } /* NOTE: return value is conditionalized on _MAC, messes up parser */ LRESULT qxeDefMDIChildProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { if (XEUNICODE_P) return DefMDIChildProcW (hWnd, uMsg, wParam, lParam); else return DefMDIChildProcA (hWnd, uMsg, wParam, lParam); } /* This one has two entry points called GetEnvironmentStringsW and GetEnvironmentStrings. (misnamed A version) */ Extbyte * qxeGetEnvironmentStrings (void) { if (XEUNICODE_P) return (Extbyte *) GetEnvironmentStringsW (); else return (Extbyte *) GetEnvironmentStrings (); } /************************************************************************/ /* would be encapsulatable but for Cygwin problems */ /************************************************************************/ #ifdef HAVE_MS_WINDOWS /* NOTE: NT 4.0+ only */ BOOL qxeUpdateICMRegKey (DWORD arg1, Extbyte * arg2, Extbyte * arg3, UINT arg4) { #ifdef CYGWIN_HEADERS /* Cygwin mistakenly declares the second argument as DWORD. */ if (XEUNICODE_P) return UpdateICMRegKeyW (arg1, (DWORD) arg2, (LPWSTR) arg3, arg4); else return UpdateICMRegKeyA (arg1, (DWORD) arg2, (LPSTR) arg3, arg4); #else if (XEUNICODE_P) return UpdateICMRegKeyW (arg1, (LPWSTR) arg2, (LPWSTR) arg3, arg4); else return UpdateICMRegKeyA (arg1, (LPSTR) arg2, (LPSTR) arg3, arg4); #endif /* CYGWIN_HEADERS */ } #endif /* HAVE_MS_WINDOWS */ #ifndef CYGWIN /* present in headers but missing in shell32.a */ BOOL qxeSHGetSpecialFolderPath (HWND hwndOwner, Extbyte * lpszPath, int nFolder, BOOL fCreate) { #ifdef CYGWIN_HEADERS /* Cygwin mistakenly declares the second argument as LPSTR in both versions. */ if (XEUNICODE_P) return SHGetSpecialFolderPathW (hwndOwner, (LPSTR) lpszPath, nFolder, fCreate); else return SHGetSpecialFolderPathA (hwndOwner, (LPSTR) lpszPath, nFolder, fCreate); #else if (XEUNICODE_P) return SHGetSpecialFolderPathW (hwndOwner, (LPWSTR) lpszPath, nFolder, fCreate); else return SHGetSpecialFolderPathA (hwndOwner, (LPSTR) lpszPath, nFolder, fCreate); #endif } #endif /* not CYGWIN */ /********************************************************************************/ /* would be encapsulatable but for header changes in different versions of VC++ */ /********************************************************************************/ #if MSC_VERSION >= 1300 BOOL qxeEnumResourceTypes (HMODULE hModule, ENUMRESTYPEPROCW lpEnumFunc, LONG lParam) { if (XEUNICODE_P) return EnumResourceTypesW (hModule, lpEnumFunc, lParam); else return EnumResourceTypesA (hModule, (ENUMRESTYPEPROCA) lpEnumFunc, lParam); } BOOL qxeEnumResourceNames (HMODULE hModule, const Extbyte * lpType, ENUMRESNAMEPROCW lpEnumFunc, LONG lParam) { if (XEUNICODE_P) return EnumResourceNamesW (hModule, (LPCWSTR) lpType, lpEnumFunc, lParam); else return EnumResourceNamesA (hModule, (LPCSTR) lpType, (ENUMRESNAMEPROCA) lpEnumFunc, lParam); } BOOL qxeEnumResourceLanguages (HMODULE hModule, const Extbyte * lpType, const Extbyte * lpName, ENUMRESLANGPROCW lpEnumFunc, LONG lParam) { if (XEUNICODE_P) return EnumResourceLanguagesW (hModule, (LPCWSTR) lpType, (LPCWSTR) lpName, lpEnumFunc, lParam); else return EnumResourceLanguagesA (hModule, (LPCSTR) lpType, (LPCSTR) lpName, (ENUMRESLANGPROCA) lpEnumFunc, lParam); } #else BOOL qxeEnumResourceTypes (HMODULE hModule, ENUMRESTYPEPROC lpEnumFunc, LONG lParam) { if (XEUNICODE_P) return EnumResourceTypesW (hModule, lpEnumFunc, lParam); else return EnumResourceTypesA (hModule, lpEnumFunc, lParam); } BOOL qxeEnumResourceNames (HMODULE hModule, const Extbyte * lpType, ENUMRESNAMEPROC lpEnumFunc, LONG lParam) { if (XEUNICODE_P) return EnumResourceNamesW (hModule, (LPCWSTR) lpType, lpEnumFunc, lParam); else return EnumResourceNamesA (hModule, (LPCSTR) lpType, lpEnumFunc, lParam); } BOOL qxeEnumResourceLanguages (HMODULE hModule, const Extbyte * lpType, const Extbyte * lpName, ENUMRESLANGPROC lpEnumFunc, LONG lParam) { if (XEUNICODE_P) return EnumResourceLanguagesW (hModule, (LPCWSTR) lpType, (LPCWSTR) lpName, lpEnumFunc, lParam); else return EnumResourceLanguagesA (hModule, (LPCSTR) lpType, (LPCSTR) lpName, lpEnumFunc, lParam); } #endif /* MSC_VERSION >= 1300 */ /************************************************************************/ /* files */ /************************************************************************/ static void copy_win32_find_dataa_to_win32_find_dataw (const WIN32_FIND_DATAA *pa, WIN32_FIND_DATAW *pw) { /* the layout of WIN32_FIND_DATA is non-split fields; TCHAR cFileName[...]; TCHAR cAlternateFileName[...]; */ xzero (*pw); memcpy (pw, pa, offsetof (WIN32_FIND_DATAA, cFileName)); memcpy (pw->cFileName, pa->cFileName, sizeof (pa->cFileName)); memcpy (pw->cAlternateFileName, pa->cAlternateFileName, sizeof (pa->cAlternateFileName)); } HANDLE qxeFindFirstFile (const Extbyte *lpFileName, WIN32_FIND_DATAW *lpFindFileData) { if (XEUNICODE_P) return FindFirstFileW ((LPCWSTR) lpFileName, lpFindFileData); else { WIN32_FIND_DATAA ansidat; HANDLE retval; retval = FindFirstFileA ((LPCSTR) lpFileName, &ansidat); if (retval != INVALID_HANDLE_VALUE) copy_win32_find_dataa_to_win32_find_dataw (&ansidat, lpFindFileData); return retval; } } BOOL qxeFindNextFile (HANDLE hFindFile, WIN32_FIND_DATAW *lpFindFileData) { if (XEUNICODE_P) return FindNextFileW (hFindFile, lpFindFileData); else { WIN32_FIND_DATAA ansidat; BOOL retval; retval = FindNextFileA (hFindFile, &ansidat); if (retval) copy_win32_find_dataa_to_win32_find_dataw (&ansidat, lpFindFileData); return retval; } } /************************************************************************/ /* shell */ /************************************************************************/ static void copy_shfileinfoa_to_shfileinfow (const SHFILEINFOA *pa, SHFILEINFOW *pw, UINT sz) { /* the layout of SHFILEINFO is non-split fields; TCHAR szDisplayName[...]; TCHAR szTypeName[...]; */ assert (sz >= sizeof (SHFILEINFOW)); xzero (*pw); memcpy (pw, pa, offsetof (SHFILEINFOA, szDisplayName)); memcpy (pw->szDisplayName, pa->szDisplayName, sizeof (pa->szDisplayName)); memcpy (pw->szTypeName, pa->szTypeName, sizeof (pa->szTypeName)); } DWORD qxeSHGetFileInfo (const Extbyte *pszPath, DWORD dwFileAttributes, SHFILEINFOW *psfi, UINT cbFileInfo, UINT uFlags) { if (XEUNICODE_P) return SHGetFileInfoW ((LPCWSTR) pszPath, dwFileAttributes, psfi, cbFileInfo, uFlags); else { SHFILEINFOA ansidat; BOOL retval; retval = SHGetFileInfoA ((LPCSTR) pszPath, dwFileAttributes, (SHFILEINFOA FAR *) &ansidat, cbFileInfo ? sizeof (ansidat) : 0, uFlags); if (retval && cbFileInfo) copy_shfileinfoa_to_shfileinfow (&ansidat, psfi, cbFileInfo); return retval; } } struct intercepted_SHBrowseForFolder { BFFCALLBACK lpfn; LPARAM lParam; HWND hwnd; struct intercepted_SHBrowseForFolder *next; }; static struct intercepted_SHBrowseForFolder *SHBrowseForFolder_list; static int CALLBACK intercepted_SHBrowseForFolder_proc (HWND hwnd, UINT msg, LPARAM lParam, LPARAM lpData) { struct intercepted_SHBrowseForFolder *s = (struct intercepted_SHBrowseForFolder *) lpData; if (s->hwnd == 0) s->hwnd = hwnd; if (s->lpfn) { /* see below */ if (XEUNICODE_P && msg == BFFM_VALIDATEFAILEDW) msg = BFFM_VALIDATEFAILEDA; else if (!XEUNICODE_P && msg == BFFM_VALIDATEFAILEDA) msg = BFFM_VALIDATEFAILEDW; return (s->lpfn) (hwnd, msg, lParam, s->lParam); } else return 0; } #ifdef HAVE_MS_WINDOWS static int is_SHBrowseForFolder (HWND hwnd) { struct intercepted_SHBrowseForFolder *s; for (s = SHBrowseForFolder_list; s; s = s->next) if (s->hwnd == hwnd) return 1; return 0; } #endif /* HAVE_MS_WINDOWS */ LPITEMIDLIST qxeSHBrowseForFolder (LPBROWSEINFOW lpbi) { struct intercepted_SHBrowseForFolder s; LPITEMIDLIST retval; /* There are two outgoing Unicode-split messages: BFFM_SETSELECTION BFFM_SETSTATUSTEXT and one incoming: BFFM_VALIDATEFAILED To handle this, we need to intercept the callback. We handle the incoming message in the callback, and record the window; when qxeSendMessage() is called, we handle the outgoing messages. None of the messages have split-sized structures so we don't need to do anything complicated there. */ s.lParam = lpbi->lParam; s.lpfn = lpbi->lpfn; s.next = SHBrowseForFolder_list; s.hwnd = 0; SHBrowseForFolder_list = &s; lpbi->lpfn = intercepted_SHBrowseForFolder_proc; lpbi->lParam = (LPARAM) &s; if (XEUNICODE_P) retval = SHBrowseForFolderW (lpbi); else retval = SHBrowseForFolderA ((LPBROWSEINFOA) lpbi); SHBrowseForFolder_list = SHBrowseForFolder_list->next; return retval; } VOID qxeSHAddToRecentDocs (UINT uFlags, LPCVOID pv) { /* pv can be a string pointer; this is handled by Unicode-splitting the flag SHARD_PATH rather than the function itself. Fix up the flag to be correct. We write it symmetrically so it doesn't matter whether UNICODE is defined. */ if (XEUNICODE_P) { if (uFlags & SHARD_PATHA) { uFlags |= SHARD_PATHW; uFlags &= ~SHARD_PATHA; } } else { if (uFlags & SHARD_PATHW) { uFlags |= SHARD_PATHA; uFlags &= ~SHARD_PATHW; } } SHAddToRecentDocs (uFlags, pv); } VOID qxeSHChangeNotify (LONG wEventId, UINT uFlags, LPCVOID dwItem1, LPCVOID dwItem2) { /* works like SHAddToRecentDocs */ if (XEUNICODE_P) { if (uFlags & SHCNF_PATHA) { uFlags |= SHCNF_PATHW; uFlags &= ~SHCNF_PATHA; } if (uFlags & SHCNF_PRINTERA) { uFlags |= SHCNF_PRINTERW; uFlags &= ~SHCNF_PRINTERA; } } else { if (uFlags & SHCNF_PATHW) { uFlags |= SHCNF_PATHA; uFlags &= ~SHCNF_PATHW; } if (uFlags & SHCNF_PRINTERW) { uFlags |= SHCNF_PRINTERA; uFlags &= ~SHCNF_PRINTERW; } } SHChangeNotify (wEventId, uFlags, dwItem1, dwItem2); } #ifndef CYGWIN /* present in headers but missing in shell32.a */ HRESULT qxeSHGetDataFromIDList (IShellFolder *psf, LPCITEMIDLIST pidl, int nFormat, PVOID pv, int cb) { if (XEUNICODE_P) return SHGetDataFromIDListW (psf, pidl, nFormat, pv, cb); else if (nFormat == SHGDFIL_FINDDATA) { WIN32_FIND_DATAA ansidat; BOOL retval; retval = SHGetDataFromIDListA (psf, pidl, nFormat, &ansidat, cb); if (retval == NOERROR) copy_win32_find_dataa_to_win32_find_dataw (&ansidat, (WIN32_FIND_DATAW *) pv); return retval; } else /* nFormat == SHGDFIL_NETRESOURCE, and pv is split-simple NETRESOURCE structure, but we don't need to worry about that currently since we don't translate strings */ return SHGetDataFromIDListA (psf, pidl, nFormat, pv, cb); } #endif /* not CYGWIN */ #ifdef HAVE_MS_WINDOWS /************************************************************************/ /* devmode */ /************************************************************************/ /* These functions return globally allocated blocks because some callers (e.g. qxePrintDlg) want this. */ static HGLOBAL copy_devmodew_to_devmodea (const DEVMODEW *src, DEVMODEA *dst) { /* the layout of DEVMODE is TCHAR dmDeviceName[...]; non-split fields, including dmSize (size of structure; differs between Unicode and ANSI) and dmDriverExtra; TCHAR dmFormName[...]; non-split fields; extra data, of size DEVMODE->dmDriverExtra */ HGLOBAL hdst = NULL; if (!dst) { hdst = GlobalAlloc (GHND, src->dmSize + src->dmDriverExtra - (sizeof (DEVMODEW) - sizeof (DEVMODEA))); dst = (DEVMODEA *) GlobalLock (hdst); } memcpy (dst->dmDeviceName, src->dmDeviceName, sizeof (dst->dmDeviceName)); memcpy ((char *) dst + sizeof (dst->dmDeviceName), (char *) src + sizeof (src->dmDeviceName), offsetof (DEVMODEA, dmFormName) - sizeof (dst->dmDeviceName)); dst->dmSize -= sizeof (DEVMODEW) - sizeof (DEVMODEA); memcpy (dst->dmFormName, src->dmFormName, sizeof (dst->dmFormName)); memcpy ((char *) dst + offsetof (DEVMODEA, dmFormName) + sizeof (dst->dmFormName), (char *) src + offsetof (DEVMODEW, dmFormName) + sizeof (src->dmFormName), dst->dmSize + dst->dmDriverExtra - (offsetof (DEVMODEA, dmFormName) + sizeof (dst->dmFormName))); if (hdst) GlobalUnlock (hdst); return hdst; } static HGLOBAL copy_devmodea_to_devmodew (const DEVMODEA *src, DEVMODEW *dst) { HGLOBAL hdst = NULL; if (!dst) { hdst = GlobalAlloc (GHND, src->dmSize + src->dmDriverExtra + (sizeof (DEVMODEW) - sizeof (DEVMODEA))); dst = (DEVMODEW *) GlobalLock (hdst); } memcpy (dst->dmDeviceName, src->dmDeviceName, sizeof (src->dmDeviceName)); memcpy ((char *) dst + sizeof (dst->dmDeviceName), (char *) src + sizeof (src->dmDeviceName), offsetof (DEVMODEA, dmFormName) - sizeof (src->dmDeviceName)); dst->dmSize += sizeof (DEVMODEW) - sizeof (DEVMODEA); memcpy (dst->dmFormName, src->dmFormName, sizeof (src->dmFormName)); memcpy ((char *) dst + offsetof (DEVMODEW, dmFormName) + sizeof (dst->dmFormName), (char *) src + offsetof (DEVMODEA, dmFormName) + sizeof (src->dmFormName), src->dmSize + src->dmDriverExtra - (offsetof (DEVMODEA, dmFormName) + sizeof (src->dmFormName))); if (hdst) GlobalUnlock (hdst); return hdst; } HDC qxeCreateDC (const Extbyte *lpszDriver, const Extbyte *lpszDevice, const Extbyte *lpszOutput, CONST DEVMODEW *lpInitData) { if (XEUNICODE_P) return CreateDCW ((LPCWSTR) lpszDriver, (LPCWSTR) lpszDevice, (LPCWSTR) lpszOutput, lpInitData); else { HGLOBAL hInitData = NULL; DEVMODEA *lpInitDataa = NULL; HDC retval; if (lpInitData) { hInitData = copy_devmodew_to_devmodea (lpInitData, NULL); lpInitDataa = (DEVMODEA *) GlobalLock (hInitData); } retval = CreateDCA ((LPCSTR) lpszDriver, (LPCSTR) lpszDevice, (LPCSTR) lpszOutput, lpInitDataa); if (hInitData) { GlobalUnlock (hInitData); GlobalFree (hInitData); } return retval; } } HDC qxeResetDC (HDC hdc, CONST DEVMODEW *lpInitData) { if (XEUNICODE_P) return ResetDCW (hdc, lpInitData); else { HGLOBAL hInitData = NULL; DEVMODEA *lpInitDataa = NULL; HDC retval; if (lpInitData) { hInitData = copy_devmodew_to_devmodea (lpInitData, NULL); lpInitDataa = (DEVMODEA *) GlobalLock (hInitData); } retval = ResetDCA (hdc, lpInitDataa); if (hInitData) { GlobalUnlock (hInitData); GlobalFree (hInitData); } return retval; } } DWORD qxeOpenPrinter (Extbyte *pPrinterName, LPHANDLE phPrinter, LPPRINTER_DEFAULTSW pDefaultconst) { assert (!pDefaultconst); /* we don't split it, so let's make sure we don't try. */ if (XEUNICODE_P) return OpenPrinterW ((LPWSTR) pPrinterName, phPrinter, pDefaultconst); else return OpenPrinterA ((LPSTR) pPrinterName, phPrinter, (LPPRINTER_DEFAULTSA) pDefaultconst); } LONG qxeDocumentProperties (HWND hWnd, HANDLE hPrinter, Extbyte *pDeviceName, DEVMODEW *pDevModeOutput, DEVMODEW *pDevModeInput, DWORD fMode) { if (XEUNICODE_P) #if defined (CYGWIN_HEADERS) && W32API_INSTALLED_VER < W32API_VER(3,1) /* Cygwin used to mistakenly declare the fourth and fifth arguments as PDEVMODEA. */ return DocumentPropertiesW (hWnd, hPrinter, (LPWSTR) pDeviceName, (DEVMODEA *) pDevModeOutput, (DEVMODEA *) pDevModeInput, fMode); #else return DocumentPropertiesW (hWnd, hPrinter, (LPWSTR) pDeviceName, pDevModeOutput, pDevModeInput, fMode); #endif /* CYGWIN_HEADERS */ else { HGLOBAL hDevModeInput = NULL; DEVMODEA *pDevModeInputa = NULL; LONG retval; if (pDevModeInput) { hDevModeInput = copy_devmodew_to_devmodea (pDevModeInput, NULL); pDevModeInputa = (DEVMODEA *) GlobalLock (hDevModeInput); } /* Here we cheat a bit to avoid a problem: If the output structure is given but not the input one, how do we know how big to allocate our shadow output structure? Since the shadow structure is ANSI and the original Unicode, we know the shadow structure is smaller than what's given, so we just write into the given structure and then fix. */ retval = DocumentPropertiesA (hWnd, hPrinter, (LPSTR) pDeviceName, pDevModeOutput ? (DEVMODEA *) pDevModeOutput : 0, pDevModeInput ? pDevModeInputa : 0, fMode); if (hDevModeInput) { GlobalUnlock (hDevModeInput); GlobalFree (hDevModeInput); } if (retval >= 0 && pDevModeOutput) { /* copy the shadow structure out of the way and then put the right contents back. */ DEVMODEA *shadow = (DEVMODEA *) pDevModeOutput; DEVMODEA *newshadow = alloca_array (DEVMODEA, shadow->dmSize + shadow->dmDriverExtra); memcpy (newshadow, shadow, shadow->dmSize + shadow->dmDriverExtra); copy_devmodea_to_devmodew (newshadow, pDevModeOutput); } if (fMode == 0) retval += (sizeof (DEVMODEW) - sizeof (DEVMODEA)); return retval; } } static BOOL ansi_printer_dialog_1 (void *strucked, HGLOBAL *devmode_inout, int do_PrintDlg) { HGLOBAL hdma = NULL; HGLOBAL hdmw = *devmode_inout; DEVMODEW *dmw = NULL; BOOL retval; if (hdmw != NULL) { /* copy to shadow in structure if needed */ dmw = (DEVMODEW *) GlobalLock (hdmw); hdma = copy_devmodew_to_devmodea (dmw, NULL); *devmode_inout = hdma; } if (do_PrintDlg) retval = PrintDlgA ((PRINTDLGA *) strucked); else retval = PageSetupDlgA ((PAGESETUPDLGA *) strucked); if (retval) { /* copy the shadow output structure back to original, or allocate new one. */ if (*devmode_inout) { DEVMODEA *newdma = (DEVMODEA *) GlobalLock (*devmode_inout); if (dmw) { copy_devmodea_to_devmodew (newdma, dmw); GlobalUnlock (hdmw); } else hdmw = copy_devmodea_to_devmodew (newdma, NULL); GlobalUnlock (*devmode_inout); GlobalFree (*devmode_inout); *devmode_inout = hdmw; } else if (hdma) /* #### can this happen? */ GlobalFree (hdma); } return retval; } BOOL qxePrintDlg (PRINTDLGW *lppd) { if (XEUNICODE_P) return PrintDlgW (lppd); else return ansi_printer_dialog_1 (lppd, &lppd->hDevMode, 1); } BOOL qxePageSetupDlg (PAGESETUPDLGW *lppd) { if (XEUNICODE_P) return PageSetupDlgW (lppd); else return ansi_printer_dialog_1 (lppd, &lppd->hDevMode, 0); } /************************************************************************/ /* fonts */ /************************************************************************/ static void copy_logfonta_to_logfontw (const LOGFONTA *src, LOGFONTW *dst) { /* the layout of LOGFONT is non-split fields; TCHAR lfFaceName[...]; */ memcpy (dst, src, sizeof (LOGFONTA)); } static void copy_logfontw_to_logfonta (const LOGFONTW *src, LOGFONTA *dst) { memcpy (dst, src, sizeof (LOGFONTA)); } #if 0 /* unused */ static void copy_enumlogfonta_to_enumlogfontw (const ENUMLOGFONTA *src, ENUMLOGFONTW *dst) { /* the layout of ENUMLOGFONT is LOGFONT elfLogFont; TCHAR elfFullName[...]; TCHAR elfStyle[...]; */ xzero (*dst); copy_logfonta_to_logfontw (&src->elfLogFont, &dst->elfLogFont); memcpy (dst->elfFullName, src->elfFullName, sizeof (src->elfFullName)); memcpy (dst->elfStyle, src->elfStyle, sizeof (src->elfStyle)); } #endif /* 0 */ static void copy_enumlogfontexa_to_enumlogfontexw (const ENUMLOGFONTEXA *src, ENUMLOGFONTEXW *dst) { /* the layout of ENUMLOGFONT is LOGFONT elfLogFont; TCHAR elfFullName[...]; TCHAR elfStyle[...]; TCHAR elfScript[...]; */ xzero (*dst); copy_logfonta_to_logfontw (&src->elfLogFont, &dst->elfLogFont); memcpy (dst->elfFullName, src->elfFullName, sizeof (src->elfFullName)); memcpy (dst->elfStyle, src->elfStyle, sizeof (src->elfStyle)); memcpy (dst->elfScript, src->elfScript, sizeof (src->elfScript)); } static void copy_newtextmetrica_to_newtextmetricw (const NEWTEXTMETRICA *src, NEWTEXTMETRICW *dst) { /* the layout of NEWTEXTMETRIC is non-split fields; WCHAR/BYTE tmFirstChar; WCHAR/BYTE tmLastChar; WCHAR/BYTE tmDefaultChar; WCHAR/BYTE tmBreakChar; BYTE tmItalic; non-split fields; */ xzero (*dst); memcpy ((char *) dst, (char *) src, offsetof (NEWTEXTMETRICA, tmFirstChar)); memcpy ((char *) dst + offsetof (NEWTEXTMETRICW, tmItalic), (char *) src + offsetof (NEWTEXTMETRICA, tmItalic), sizeof (NEWTEXTMETRICA) - offsetof (NEWTEXTMETRICA, tmItalic)); dst->tmFirstChar = (WCHAR) src->tmFirstChar; dst->tmLastChar = (WCHAR) src->tmLastChar; dst->tmDefaultChar = (WCHAR) src->tmDefaultChar; dst->tmBreakChar = (WCHAR) src->tmBreakChar; } static void copy_newtextmetricexa_to_newtextmetricexw (const NEWTEXTMETRICEXA *src, NEWTEXTMETRICEXW *dst) { /* the layout of NEWTEXTMETRICEX is NEWTEXTMETRICA/W ntmTm; FONTSIGNATURE ntmFontSig; */ copy_newtextmetrica_to_newtextmetricw (&src->ntmTm, &dst->ntmTm); dst->ntmFontSig = src->ntmFontSig; } #if 0 /* unused */ static void copy_textmetricw_to_textmetrica (const TEXTMETRICW *src, TEXTMETRICA *dst) { /* the layout of TEXTMETRIC is like NEWTEXTMETRIC; see above. */ xzero (*dst); memcpy ((char *) dst, (char *) src, offsetof (TEXTMETRICA, tmFirstChar)); memcpy ((char *) dst + offsetof (TEXTMETRICA, tmItalic), (char *) src + offsetof (TEXTMETRICW, tmItalic), sizeof (TEXTMETRICA) - offsetof (TEXTMETRICA, tmItalic)); dst->tmFirstChar = (BYTE) src->tmFirstChar; dst->tmLastChar = (BYTE) src->tmLastChar; dst->tmDefaultChar = (BYTE) src->tmDefaultChar; dst->tmBreakChar = (BYTE) src->tmBreakChar; } #endif /* 0 */ static void copy_textmetrica_to_textmetricw (const TEXTMETRICA *src, TEXTMETRICW *dst) { /* the layout of TEXTMETRIC is like NEWTEXTMETRIC; see above. */ xzero (*dst); memcpy ((char *) dst, (char *) src, offsetof (TEXTMETRICA, tmFirstChar)); memcpy ((char *) dst + offsetof (TEXTMETRICW, tmItalic), (char *) src + offsetof (TEXTMETRICA, tmItalic), sizeof (TEXTMETRICA) - offsetof (TEXTMETRICA, tmItalic)); dst->tmFirstChar = (WCHAR) src->tmFirstChar; dst->tmLastChar = (WCHAR) src->tmLastChar; dst->tmDefaultChar = (WCHAR) src->tmDefaultChar; dst->tmBreakChar = (WCHAR) src->tmBreakChar; } typedef int (CALLBACK *qxeEnumFontFamExProcW) (ENUMLOGFONTEXW *lpelfe, NEWTEXTMETRICEXW *lpntme, DWORD FontType, LPARAM lParam); struct qxeEnumFontFamExProcA_wrapper_t { qxeEnumFontFamExProcW orig_proc; LPARAM orig_lparam; }; static int CALLBACK qxeEnumFontFamExProcA_wrapper (ENUMLOGFONTEXA *lpelfe, NEWTEXTMETRICEXA *lpntme, DWORD fontType, struct qxeEnumFontFamExProcA_wrapper_t *closure) { ENUMLOGFONTEXW lpelfew; NEWTEXTMETRICEXW lpntmew; /* #### if we're on Windows 2000 or above, lpelfe is actually an ENUMLOGFONTEXDV structure, and lpntme is an ENUMTEXTMETRIC structure when TRUETYPE_FONTTYPE. both are split-sized and need their own copy functions. need to handle. */ copy_enumlogfontexa_to_enumlogfontexw (lpelfe, &lpelfew); if (fontType & TRUETYPE_FONTTYPE) copy_newtextmetricexa_to_newtextmetricexw (lpntme, &lpntmew); else { /* see docs of EnumFontFamExProc */ xzero (lpntmew); copy_textmetrica_to_textmetricw ((TEXTMETRICA *) lpntme, (TEXTMETRICW *) &lpntmew); } return (closure->orig_proc) (&lpelfew, &lpntmew, fontType, closure->orig_lparam); } int qxeEnumFontFamiliesEx (HDC hdc, LOGFONTW *lpLogfont, FONTENUMPROCW lpEnumFontFamProc, LPARAM lParam, DWORD dwFlags) { if (XEUNICODE_P) return EnumFontFamiliesExW (hdc, lpLogfont, lpEnumFontFamProc, lParam, dwFlags); else { struct qxeEnumFontFamExProcA_wrapper_t closure; LOGFONTA lfa; closure.orig_proc = (qxeEnumFontFamExProcW) lpEnumFontFamProc; closure.orig_lparam = lParam; copy_logfontw_to_logfonta (lpLogfont, &lfa); return EnumFontFamiliesExA (hdc, &lfa, (FONTENUMPROCA) qxeEnumFontFamExProcA_wrapper, (LPARAM) &closure, dwFlags); } } HFONT qxeCreateFontIndirect (CONST LOGFONTW *lplf) { if (XEUNICODE_P) return CreateFontIndirectW (lplf); else { LOGFONTA lfa; copy_logfontw_to_logfonta (lplf, &lfa); return CreateFontIndirectA (&lfa); } } BOOL qxeImmSetCompositionFont (HIMC imc, LOGFONTW *lplf) { if (XEUNICODE_P) return ImmSetCompositionFontW (imc, lplf); else { LOGFONTA lfa; copy_logfontw_to_logfonta (lplf, &lfa); return ImmSetCompositionFontA (imc, &lfa); } } BOOL qxeImmGetCompositionFont (HIMC imc, LOGFONTW *lplf) { if (XEUNICODE_P) return ImmGetCompositionFontW (imc, lplf); else { LOGFONTA lfa; BOOL retval = ImmGetCompositionFontA (imc, &lfa); if (retval) copy_logfonta_to_logfontw (&lfa, lplf); return retval; } } #if MSC_VERSION >= 1300 BOOL qxeImmSetCompositionString (HIMC arg1, DWORD dwIndex, LPVOID lpComp, DWORD arg4, LPVOID lpRead, DWORD arg6) { if (XEUNICODE_P) return ImmSetCompositionStringW (arg1, dwIndex, lpComp, arg4, lpRead, arg6); else return ImmSetCompositionStringA (arg1, dwIndex, lpComp, arg4, lpRead, arg6); } #else BOOL qxeImmSetCompositionString (HIMC arg1, DWORD dwIndex, LPCVOID lpComp, DWORD arg4, LPCVOID lpRead, DWORD arg6) { if (XEUNICODE_P) return ImmSetCompositionStringW (arg1, dwIndex, lpComp, arg4, lpRead, arg6); else return ImmSetCompositionStringA (arg1, dwIndex, lpComp, arg4, lpRead, arg6); } #endif /* MSC_VERSION >= 1300 */ int qxeGetObject (HGDIOBJ hgdiobj, int cbBuffer, LPVOID lpvObject) { if (XEUNICODE_P) return GetObjectW (hgdiobj, cbBuffer, lpvObject); else { if (cbBuffer == sizeof (LOGFONTW)) { LOGFONTA lfa; int retval = GetObjectA (hgdiobj, sizeof (LOGFONTA), &lfa); if (!retval) return retval; copy_logfonta_to_logfontw (&lfa, (LOGFONTW *) lpvObject); return retval; } else return GetObjectA (hgdiobj, cbBuffer, lpvObject); } } BOOL qxeGetTextMetrics (HDC hdc, LPTEXTMETRICW lptm) { if (XEUNICODE_P) return GetTextMetricsW (hdc, lptm); else { TEXTMETRICA tma; BOOL retval = GetTextMetricsA (hdc, &tma); if (retval) copy_textmetrica_to_textmetricw (&tma, lptm); return retval; } } /************************************************************************/ /* windows */ /************************************************************************/ typedef struct Intercepted_wnd_proc { WNDPROC proc; Extbyte *name; int is_ansi; } Intercepted_wnd_proc; typedef struct { Dynarr_declare (Intercepted_wnd_proc); } Intercepted_wnd_proc_dynarr; static Intercepted_wnd_proc_dynarr *intercepted_wnd_procs; static Intercepted_wnd_proc * find_window_class (const Extbyte *name, int is_ansi) { int i; if (!intercepted_wnd_procs) intercepted_wnd_procs = Dynarr_new (Intercepted_wnd_proc); for (i = 0; i < Dynarr_length (intercepted_wnd_procs); i++) { Intercepted_wnd_proc *s = Dynarr_atp (intercepted_wnd_procs, i); if (s->is_ansi == is_ansi && (is_ansi ? !strcmp (s->name, name) : !wcscmp ((wchar_t *) s->name, (wchar_t *) name))) return s; } return 0; } /* #### check problem with cutting and pasting in my current mule -- if i cut, then go to another application, then switch back to this one and paste, it seems to get confused -- loses the size or something? other things: split flags on CreateProcess and DDE stuff should be handled by us. */ static LRESULT WINAPI intercepted_wnd_proc (HWND hwnd, UINT message_, WPARAM wParam, LPARAM lParam) { Intercepted_wnd_proc *s; int is_ansi = XEUNICODE_P ? !IsWindowUnicode (hwnd) : 1; Extbyte *classname; int size = 100; /* Just in case XEUNICODE_P changes during the execution of the program (admittedly, unlikely), check whether the window is Unicode and keep track of this in the list of classes. */ while (1) { classname = alloca_extbytes (size * XETCHAR_SIZE); if ((is_ansi ? GetClassNameA (hwnd, (LPSTR) classname, size) : GetClassNameW (hwnd, (LPWSTR) classname, size)) < size - 1) break; size *= 2; } s = find_window_class (classname, is_ansi); assert (s); if (message_ == WM_NOTIFY) { LPNMHDR nmhdr = (LPNMHDR) lParam; int putback = nmhdr->code; int do_putback = 0; #define FROB(msg) \ case msg##W: \ /* split structures are the same size, so no conversion necessary */ \ nmhdr->code = (UINT) msg##A; \ do_putback = 1; \ break; switch (nmhdr->code) { /* NMHEADER */ FROB (HDN_ITEMCHANGING); FROB (HDN_ITEMCHANGED); FROB (HDN_ITEMCLICK); FROB (HDN_ITEMDBLCLICK); FROB (HDN_DIVIDERDBLCLICK); FROB (HDN_BEGINTRACK); FROB (HDN_ENDTRACK); FROB (HDN_TRACK); /* NMDISPINFO */ FROB (HDN_GETDISPINFO); /* NMTBGETINFOTIP */ FROB (TBN_GETINFOTIP); /* NMTBDISPINFO */ FROB (TBN_GETDISPINFO); /* NMTOOLBAR */ FROB (TBN_GETBUTTONINFO); /* split-sized NMTTDISPINFO */ FROB (TTN_GETDISPINFO); /* handle the ...W case; then handle the ...A case specially, since we need to mess with the structure */ case TTN_GETDISPINFOA: /* same as TTN_NEEDTEXTA */ { NMTTDISPINFOW *nmw = alloca_new (NMTTDISPINFOW); NMTTDISPINFOA *nma = (NMTTDISPINFOA *) lParam; LRESULT retval; /* the layout of NMTTDISPINFO is non-split fields; TCHAR szText[...]; non-split fields; */ xzero (*nmw); /* copy to ...W struct for Unicode code */ memcpy ((char *) nmw, (char *) nma, offsetof (NMTTDISPINFOA, szText)); memcpy ((char *) nmw + offsetof (NMTTDISPINFOW, szText) + sizeof (nmw->szText), (char *) nma + offsetof (NMTTDISPINFOA, szText) + sizeof (nma->szText), sizeof (NMTTDISPINFOA) - (offsetof (NMTTDISPINFOA, szText) + sizeof (nma->szText))); memcpy (nmw->szText, nma->szText, sizeof (nma->szText)); retval = (s->proc) (hwnd, message_, wParam, lParam); /* copy back to ...A struct */ xzero (*nma); memcpy ((char *) nma, (char *) nmw, offsetof (NMTTDISPINFOA, szText)); memcpy ((char *) nma + offsetof (NMTTDISPINFOA, szText) + sizeof (nma->szText), (char *) nmw + offsetof (NMTTDISPINFOW, szText) + sizeof (nmw->szText), sizeof (NMTTDISPINFOA) - (offsetof (NMTTDISPINFOA, szText) + sizeof (nma->szText))); memcpy (nma->szText, nmw->szText, sizeof (nma->szText)); return retval; } /* NMLVFINDITEM */ FROB (LVN_ODFINDITEM); /* NMLVDISPINFO */ FROB (LVN_BEGINLABELEDIT); FROB (LVN_ENDLABELEDIT); FROB (LVN_GETDISPINFO); FROB (LVN_SETDISPINFO); /* NMLVGETINFOTIP */ FROB (LVN_GETINFOTIP); /* NMTREEVIEW */ FROB (TVN_SELCHANGING); FROB (TVN_SELCHANGED); FROB (TVN_ITEMEXPANDING); FROB (TVN_ITEMEXPANDED); FROB (TVN_BEGINDRAG); FROB (TVN_BEGINRDRAG); FROB (TVN_DELETEITEM); /* NMTVDISPINFO */ FROB (TVN_GETDISPINFO); FROB (TVN_SETDISPINFO); FROB (TVN_BEGINLABELEDIT); FROB (TVN_ENDLABELEDIT); /* NMTVGETINFOTIP */ FROB (TVN_GETINFOTIP); /* NMCOMBOBOXEX */ FROB (CBEN_GETDISPINFO); /* split-sized NMCBEDRAGBEGIN */ FROB (CBEN_DRAGBEGIN); /* handle the ...W case; then handle the ...A case specially, since we need to mess with the structure */ { NMCBEDRAGBEGINW *nmw = alloca_new (NMCBEDRAGBEGINW); NMCBEDRAGBEGINA *nma = (NMCBEDRAGBEGINA *) lParam; LRESULT retval; /* the layout of NNMCBEDRAGBEGIN is non-split fields; TCHAR szText[...]; */ xzero (*nmw); /* copy to ...W struct for Unicode code */ memcpy ((char *) nmw, (char *) nma, sizeof (*nma)); retval = (s->proc) (hwnd, message_, wParam, lParam); /* copy back to ...A struct */ xzero (*nma); memcpy ((char *) nma, (char *) nmw, sizeof (*nma)); return retval; } /* split-sized NMCBEENDEDIT */ FROB (CBEN_ENDEDIT); /* handle the ...W case; then handle the ...A case specially, since we need to mess with the structure */ { NMCBEENDEDITW *nmw = alloca_new (NMCBEENDEDITW); NMCBEENDEDITA *nma = (NMCBEENDEDITA *) lParam; LRESULT retval; /* the layout of NMCBEENDEDIT is non-split fields; TCHAR szText[...]; non-split fields; */ xzero (*nmw); /* copy to ...W struct for Unicode code */ memcpy ((char *) nmw, (char *) nma, offsetof (NMCBEENDEDITA, szText)); memcpy ((char *) nmw + offsetof (NMCBEENDEDITW, szText) + sizeof (nmw->szText), (char *) nma + offsetof (NMCBEENDEDITA, szText) + sizeof (nma->szText), sizeof (NMCBEENDEDITA) - (offsetof (NMCBEENDEDITA, szText) + sizeof (nma->szText))); memcpy (nmw->szText, nma->szText, sizeof (nma->szText)); retval = (s->proc) (hwnd, message_, wParam, lParam); /* copy back to ...A struct */ xzero (*nma); memcpy ((char *) nma, (char *) nmw, offsetof (NMCBEENDEDITA, szText)); memcpy ((char *) nma + offsetof (NMCBEENDEDITA, szText) + sizeof (nma->szText), (char *) nmw + offsetof (NMCBEENDEDITW, szText) + sizeof (nmw->szText), sizeof (NMCBEENDEDITA) - (offsetof (NMCBEENDEDITA, szText) + sizeof (nma->szText))); memcpy (nma->szText, nmw->szText, sizeof (nma->szText)); return retval; } /* NMDATETIMESTRING */ FROB (DTN_USERSTRING); /* NMDATETIMEWMKEYDOWN */ FROB (DTN_WMKEYDOWN); /* split-sized NMDATETIMEFORMAT */ FROB (DTN_FORMAT); /* handle the ...W case; then handle the ...A case specially, since we need to mess with the structure */ { NMDATETIMEFORMATW *nmw = alloca_new (NMDATETIMEFORMATW); NMDATETIMEFORMATA *nma = (NMDATETIMEFORMATA *) lParam; LRESULT retval; /* the layout of NMDATETIMEFORMAT is non-split fields; TCHAR szText[...]; */ xzero (*nmw); /* copy to ...W struct for Unicode code */ memcpy ((char *) nmw, (char *) nma, sizeof (*nma)); retval = (s->proc) (hwnd, message_, wParam, lParam); /* copy back to ...A struct */ xzero (*nma); memcpy ((char *) nma, (char *) nmw, sizeof (*nma)); return retval; } /* NMDATETIMEFORMATQUERY */ FROB (DTN_FORMATQUERY); default: break; } #undef FROB if (do_putback) { LRESULT retval = (s->proc) (hwnd, message_, wParam, lParam); ((LPNMHDR) lParam)->code = putback; return retval; } } return (s->proc) (hwnd, message_, wParam, lParam); } ATOM qxeRegisterClass (CONST WNDCLASSW * lpWndClass) { Intercepted_wnd_proc *s = find_window_class ((Extbyte *) lpWndClass->lpszClassName, !XEUNICODE_P); WNDCLASSW classnew; if (s) { s->proc = lpWndClass->lpfnWndProc; s->name = (Extbyte *) lpWndClass->lpszClassName; s->is_ansi = !XEUNICODE_P; } else { Intercepted_wnd_proc news; news.proc = lpWndClass->lpfnWndProc; news.name = (Extbyte *) lpWndClass->lpszClassName; news.is_ansi = !XEUNICODE_P; Dynarr_add (intercepted_wnd_procs, news); } classnew = *lpWndClass; classnew.lpfnWndProc = intercepted_wnd_proc; if (XEUNICODE_P) return RegisterClassW (&classnew); else /* The intermediate cast fools gcc into not outputting strict-aliasing complaints */ return RegisterClassA ((CONST WNDCLASSA *) (void *) &classnew); } BOOL qxeUnregisterClass (const Extbyte * lpClassName, HINSTANCE hInstance) { Intercepted_wnd_proc *s = find_window_class (lpClassName, !XEUNICODE_P); if (s) Dynarr_delete_by_pointer (intercepted_wnd_procs, s); if (XEUNICODE_P) return UnregisterClassW ((LPCWSTR) lpClassName, hInstance); else return UnregisterClassA ((LPCSTR) lpClassName, hInstance); } /* NOTE: NT 4.0+ only */ ATOM qxeRegisterClassEx (CONST WNDCLASSEXW *lpWndClass) { Intercepted_wnd_proc *s = find_window_class ((Extbyte *) lpWndClass->lpszClassName, !XEUNICODE_P); WNDCLASSEXW classnew; if (s) { s->proc = lpWndClass->lpfnWndProc; s->name = (Extbyte *) lpWndClass->lpszClassName; s->is_ansi = !XEUNICODE_P; } else { Intercepted_wnd_proc news; news.proc = lpWndClass->lpfnWndProc; news.name = (Extbyte *) lpWndClass->lpszClassName; news.is_ansi = !XEUNICODE_P; Dynarr_add (intercepted_wnd_procs, news); } classnew = *lpWndClass; classnew.lpfnWndProc = intercepted_wnd_proc; if (XEUNICODE_P) return RegisterClassExW (&classnew); else /* The intermediate cast fools gcc into not outputting strict-aliasing complaints */ return RegisterClassExA ((CONST WNDCLASSEXA *) (void *) &classnew); } /************************************************************************/ /* COMMCTRL.H */ /************************************************************************/ /* there are only four structures in commctrl.h that cannot be cast between Unicode/ANSI versions: NMTTDISPINFO aka TOOLTIPTEXT NMCBEDRAGBEGIN NMCBEENDEDIT NMDATETIMEFORMAT these are all notify structures, and we handle them above in intercepted_wnd_proc(). in addition, this constant is weird, being a struct size of one of these: NMTTDISPINFO_V1_SIZE */ /* split class names: WC_HEADER TOOLBARCLASSNAME REBARCLASSNAME TOOLTIPS_CLASS STATUSCLASSNAME TRACKBAR_CLASS UPDOWN_CLASS PROGRESS_CLASS HOTKEY_CLASS WC_LISTVIEW WC_TREEVIEW WC_COMBOBOXEX WC_TABCONTROL ANIMATE_CLASS MONTHCAL_CLASS DATETIMEPICK_CLASS WC_IPADDRESS WC_PAGESCROLLER WC_NATIVEFONTCTL */ /* SendMessage split messages: HDM_INSERTITEM HDM_GETITEM HDM_SETITEM TB_GETBUTTONTEXT TB_SAVERESTORE TB_ADDSTRING TB_GETBUTTONINFO TB_SETBUTTONINFO TB_INSERTBUTTON TB_ADDBUTTONS RB_INSERTBAND RB_SETBANDINFO RB_GETBANDINFO TTM_ADDTOOL TTM_DELTOOL TTM_NEWTOOLRECT TTM_GETTOOLINFO TTM_SETTOOLINFO TTM_HITTEST TTM_GETTEXT TTM_UPDATETIPTEXT TTM_ENUMTOOLS TTM_GETCURRENTTOOL SB_GETTEXT SB_SETTEXT SB_GETTEXTLENGTH SB_SETTIPTEXT SB_GETTIPTEXT LVM_GETITEM LVM_SETITEM LVM_INSERTITEM LVM_FINDITEM LVM_GETSTRINGWIDTH LVM_EDITLABEL LVM_GETCOLUMN LVM_SETCOLUMN LVM_GETITEMTEXT LVM_SETITEMTEXT LVM_GETISEARCHSTRING LVM_SETBKIMAGE LVM_GETBKIMAGE TVM_INSERTITEM TVM_GETITEM TVM_SETITEM TVM_EDITLABEL TVM_GETISEARCHSTRING CBEM_INSERTITEM CBEM_SETITEM CBEM_GETITEM TCM_GETITEM TCM_SETITEM TCM_INSERTITEM ACM_OPEN DTM_SETFORMAT BFFM_SETSTATUSTEXT BFFM_SETSELECTION */ /* split notify messages: HDN_ITEMCHANGING HDN_ITEMCHANGED HDN_ITEMCLICK HDN_ITEMDBLCLICK HDN_DIVIDERDBLCLICK HDN_BEGINTRACK HDN_ENDTRACK HDN_TRACK HDN_GETDISPINFO TBN_GETINFOTIP TBN_GETDISPINFO TBN_GETBUTTONINFO TTN_GETDISPINFO TTN_NEEDTEXTW LVN_ODFINDITEM LVN_BEGINLABELEDIT LVN_ENDLABELEDIT LVN_GETDISPINFO LVN_SETDISPINFO LVN_GETINFOTIP TVN_SELCHANGING TVN_SELCHANGED TVN_GETDISPINFO TVN_SETDISPINFO TVN_ITEMEXPANDING TVN_ITEMEXPANDED TVN_BEGINDRAG TVN_BEGINRDRAG TVN_DELETEITEM TVN_BEGINLABELEDIT TVN_ENDLABELEDIT TVN_GETINFOTIP CBEN_GETDISPINFO CBEN_DRAGBEGIN CBEN_ENDEDIT DTN_USERSTRING DTN_WMKEYDOWN DTN_FORMAT DTN_FORMATQUERY BFFM_VALIDATEFAILED (send to SHBrowseForFolder procedure) */ /* split structures: TV_INSERTSTRUCT (simple-split, though -- just cast) TC_ITEM (simple-split, though -- just cast) #### */ /* split macros or macros needing splitting: #### */ LRESULT qxeSendMessage (HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) { #define FROB(msg) \ case msg##A: \ /* split structures are the same size, so no conversion necessary */ \ Msg = msg##W; \ break; if (XEUNICODE_P) { WCHAR classname[100]; /* the name for SHBrowseForFolder windows is non-obvious so we have to intercept the callback */ if (is_SHBrowseForFolder (hWnd)) { switch (Msg) { FROB (BFFM_SETSELECTION); FROB (BFFM_SETSTATUSTEXT); default: break; } } else if (!GetClassNameW (hWnd, classname, 100)) ; /* luckily, subclassing leaves the name alone, so we can still determine fairly easily the correct class to switch on */ else if (!wcscmp (classname, WC_HEADERW)) { switch (Msg) { FROB (HDM_INSERTITEM); FROB (HDM_GETITEM); FROB (HDM_SETITEM); default: break; } } else if (!wcscmp (classname, TOOLBARCLASSNAMEW)) { switch (Msg) { FROB (TB_GETBUTTONTEXT); FROB (TB_SAVERESTORE); FROB (TB_ADDSTRING); FROB (TB_GETBUTTONINFO); FROB (TB_SETBUTTONINFO); FROB (TB_INSERTBUTTON); FROB (TB_ADDBUTTONS); default: break; } } else if (!wcscmp (classname, REBARCLASSNAMEW)) { switch (Msg) { FROB (RB_INSERTBAND); FROB (RB_SETBANDINFO); FROB (RB_GETBANDINFO); default: break; } } else if (!wcscmp (classname, TOOLTIPS_CLASSW)) { switch (Msg) { FROB (TTM_ADDTOOL); FROB (TTM_DELTOOL); FROB (TTM_NEWTOOLRECT); FROB (TTM_GETTOOLINFO); FROB (TTM_SETTOOLINFO); FROB (TTM_HITTEST); FROB (TTM_GETTEXT); FROB (TTM_UPDATETIPTEXT); FROB (TTM_ENUMTOOLS); FROB (TTM_GETCURRENTTOOL); default: break; } } else if (!wcscmp (classname, STATUSCLASSNAMEW)) { switch (Msg) { FROB (SB_GETTEXT); FROB (SB_SETTEXT); FROB (SB_GETTEXTLENGTH); FROB (SB_SETTIPTEXT); FROB (SB_GETTIPTEXT); default: break; } } else if (!wcscmp (classname, WC_LISTVIEWW)) { switch (Msg) { FROB (LVM_GETITEM); FROB (LVM_SETITEM); FROB (LVM_INSERTITEM); FROB (LVM_FINDITEM); FROB (LVM_GETSTRINGWIDTH); FROB (LVM_EDITLABEL); FROB (LVM_GETCOLUMN); FROB (LVM_SETCOLUMN); FROB (LVM_GETITEMTEXT); FROB (LVM_SETITEMTEXT); FROB (LVM_GETISEARCHSTRING); FROB (LVM_SETBKIMAGE); FROB (LVM_GETBKIMAGE); default: break; } } else if (!wcscmp (classname, WC_TREEVIEWW)) { switch (Msg) { FROB (TVM_INSERTITEM); /* no need to split TV_INSERTSTRUCT */ FROB (TVM_GETITEM); FROB (TVM_SETITEM); FROB (TVM_EDITLABEL); FROB (TVM_GETISEARCHSTRING); default: break; } } else if (!wcscmp (classname, WC_COMBOBOXEXW)) { switch (Msg) { FROB (CBEM_INSERTITEM); FROB (CBEM_SETITEM); FROB (CBEM_GETITEM); default: break; } } else if (!wcscmp (classname, WC_TABCONTROLW)) { switch (Msg) { FROB (TCM_GETITEM); FROB (TCM_SETITEM); FROB (TCM_INSERTITEM); /* no need to split TC_ITEM */ default: break; } } else if (!wcscmp (classname, ANIMATE_CLASSW)) { switch (Msg) { FROB (ACM_OPEN); default: break; } } else if (!wcscmp (classname, DATETIMEPICK_CLASSW)) { switch (Msg) { FROB (DTM_SETFORMAT); default: break; } } } if (XEUNICODE_P) return SendMessageW (hWnd, Msg, wParam, lParam); else return SendMessageA (hWnd, Msg, wParam, lParam); #undef FROB } #endif /* HAVE_MS_WINDOWS */