comparison src/intl-encap-win32.c @ 771:943eaba38521

[xemacs-hg @ 2002-03-13 08:51:24 by ben] The big ben-mule-21-5 check-in! Various files were added and deleted. See CHANGES-ben-mule. There are still some test suite failures. No crashes, though. Many of the failures have to do with problems in the test suite itself rather than in the actual code. I'll be addressing these in the next day or so -- none of the test suite failures are at all critical. Meanwhile I'll be trying to address the biggest issues -- i.e. build or run failures, which will almost certainly happen on various platforms. All comments should be sent to ben@xemacs.org -- use a Cc: if necessary when sending to mailing lists. There will be pre- and post- tags, something like pre-ben-mule-21-5-merge-in, and post-ben-mule-21-5-merge-in.
author ben
date Wed, 13 Mar 2002 08:54:06 +0000
parents
children 2923009caf47
comparison
equal deleted inserted replaced
770:336a418893b5 771:943eaba38521
1 /* Unicode-encapsulation of Win32 library functions.
2 Copyright (C) 2000, 2001, 2002 Ben Wing.
3
4 This file is part of XEmacs.
5
6 XEmacs is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
9 later version.
10
11 XEmacs is distributed in the hope that it will be useful, but WITHOUT
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with XEmacs; see the file COPYING. If not, write to
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
20
21 /* Synched up with: Not in FSF. */
22
23 /* Authorship:
24
25 Current primary author: Ben Wing <ben@xemacs.org>
26
27 Created summer 2000 by Ben Wing. Completed August 2001. Completely
28 written by Ben Wing.
29 */
30
31 #define NEED_MSWINDOWS_COMMCTRL
32 #define NEED_MSWINDOWS_SHLOBJ
33
34 #include <config.h>
35 #include "lisp.h"
36
37 #include "console-msw.h"
38
39 int no_mswin_unicode_lib_calls;
40
41 /* The golden rules of writing Unicode-safe code:
42
43 -- There are no preprocessor games going on.
44
45 -- Do not set the UNICODE constant.
46
47 -- You need to change your code to call the Windows API prefixed with "qxe"
48 functions (when they exist) and use the ...W structs instead of the
49 generic ones. String arguments in the qxe functions are of type Extbyte
50 *.
51
52 -- You code is responsible for conversion of text arguments. We try to
53 handle everything else -- the argument differences, the copying back and
54 forth of structures, etc. Use Qmswindows_tstr and macros such as
55 C_STRING_TO_TSTR. You are also responsible for interpreting and
56 specifying string sizes, which have not been changed. Usually these are
57 in characters, meaning you need to divide by XETCHAR_SIZE. (But, some
58 functions want sizes in bytes, even with Unicode strings. Look in the
59 documentation.) Use XETEXT when specifying string constants, so that
60 they show up in Unicode as necessary.
61
62 -- If you need to process external strings (in general you should not do
63 this; do all your manipulations in internal format and convert at the
64 point of entry into or exit from the function), use the xet...()
65 functions.
66
67 more specifically:
68
69 Unicode support is important for supporting many languages under
70 Windows, such as Cyrillic, without resorting to translation tables for
71 particular Windows-specific code pages. Internally, all characters in
72 Windows can be represented in two encodings: code pages and Unicode.
73 With Unicode support, we can seamlessly support all Windows
74 characters. Currently, the test in the drive to support Unicode is if
75 IME input works properly, since it is being converted from Unicode.
76
77 Unicode support also requires that the various Windows API's be
78 "Unicode-encapsulated", so that they automatically call the ANSI or
79 Unicode version of the API call appropriately and handle the size
80 differences in structures. What this means is:
81
82 -- first, note that Windows already provides a sort of encapsulation
83 of all API's that deal with text. All such API's are underlyingly
84 provided in two versions, with an A or W suffix (ANSI or "wide"
85 i.e. Unicode), and the compile-time constant UNICODE controls which is
86 selected by the unsuffixed API. Same thing happens with structures, and
87 also with types, where the generic types have names beginning with T --
88 TCHAR, LPTSTR, etc.. Unfortunately, this is compile-time only, not
89 run-time, so not sufficient. (Creating the necessary run-time encoding
90 is not conceptually difficult, but very time-consuming to write. It
91 adds no significant overhead, and the only reason it's not standard in
92 Windows is conscious marketing attempts by Microsoft to cripple Windows
93 95. FUCK MICROSOFT! They even describe in a KnowledgeBase article
94 exactly how to create such an API [although we don't exactly follow
95 their procedure], and point out its usefulness; the procedure is also
96 described more generally in Nadine Kano's book on Win32
97 internationalization -- written SIX YEARS AGO! Obviously Microsoft has
98 such an API available internally.)
99
100 -- what we do is provide an encapsulation of each standard Windows API call
101 that is split into A and W versions. current theory is to avoid all
102 preprocessor games; so we name the function with a prefix -- "qxe"
103 currently -- and require callers to use the prefixed name. Callers need
104 to explicitly use the W version of all structures, and convert text
105 themselves using Qmswindows_tstr. the qxe encapsulated version will
106 automatically call the appropriate A or W version depending on whether
107 we're running on 9x or NT (you can force use of the A calls on NT,
108 e.g. for testing purposes, using the command- line switch -nuni aka
109 -no-unicode-lib-calls), and copy data between W and A versions of the
110 structures as necessary.
111
112 -- We require the caller to handle the actual translation of text to
113 avoid possible overflow when dealing with fixed-size Windows
114 structures. There are no such problems when copying data between
115 the A and W versions because ANSI text is never larger than its
116 equivalent Unicode representation.
117
118 NOTE NOTE NOTE: As of August 2001, Microsoft (finally! See my nasty
119 comment above) released their own Unicode-encapsulation library, called
120 Microsoft Layer for Unicode on Windows 95/98/Me Systems. It tries to be
121 more transparent than we are, in that
122
123 -- its routines do ANSI/Unicode string translation, while we don't, for
124 efficiency (we already have to do internal/external conversion so it's
125 no extra burden to do the proper conversion directly rather than always
126 converting to Unicode and then doing a second conversion to ANSI as
127 necessary)
128
129 -- rather than requiring separately-named routines (qxeFooBar), they
130 physically override the existing routines at the link level. it also
131 appears that they do this BADLY, in that if you link with the MLU, you
132 get an application that runs ONLY on Win9x!!! (hint -- use
133 GetProcAddress()). there's still no way to create a single binary!
134 fucking losers.
135
136 -- they assume you compile with UNICODE defined, so there's no need for the
137 application to explicitly use ...W structures, as we require.
138
139 -- they also intercept windows procedures to deal with notify messages as
140 necessary, which we don't do yet.
141
142 -- they (of course) don't use Extbyte.
143
144 at some point (especially when they fix the single-binary problem!), we
145 should consider switching. for the meantime, we'll stick with what i've
146 already written. perhaps we should think about adopting some of the
147 greater transparency they have; but i opted against transparency on
148 purpose, to make the code easier to follow for someone who's not familiar
149 with it. until our library is really complete and bug-free, we should
150 think twice before doing this.
151 */
152
153
154 /************************************************************************/
155 /* auto-generation */
156 /************************************************************************/
157
158 /* we use a simple script to control the auto-generation.
159
160 \(The following is copied from lib-src/make-mswin-unicode.pl.)
161
162 dir sets the directory for include files.
163 file specifies a file to start reading from.
164 yes indicates a function to be automatically Unicode-encapsulated.
165 (All parameters either need no special processing or are LPTSTR or
166 LPCTSTR.)
167 soon indicates a function that should be automatically Unicode-encapsulated,
168 but we're not ready to process it yet.
169 no indicates a function we don't support (it will be #defined to cause
170 a compile error, with the text after the function included in the
171 erroneous definition to indicate why we don't support it).
172 skip indicates a function we support manually; only a comment about this
173 will be generated.
174 split indicates a function with a split structure (different versions
175 for Unicode and ANSI), but where the only difference is in pointer
176 types, and the actual size does not differ. The structure name
177 should follow the function name, and it will be automatically
178 Unicode-encapsulated with appropriate casts.
179 begin-bracket indicates a #if statement to be inserted here.
180 end-bracket indicates the corresponding #endif statement.
181 blank lines and lines beginning with // are ignored.
182
183 The generated files go into intl-auto-encap-win32.[ch].
184
185 To regenerate, go to the nt/ subdirectory and type
186
187 nmake -f xemacs.mak unicode-encapsulate
188
189 This does the following:
190
191 cd $(SRC)
192 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
193
194 NOTE: If your copy of VC++ is not in the directory indicated below, you'll
195 have to change that directive (or create a symlink, provided you're using
196 Cygwin perl). #### There should be an option to the perl script to specify
197 this.
198 */
199
200 /*
201
202 terminology used below:
203
204 "split-simple" means a structure where the A and W versions are the same
205 size, and the only differences are string pointer arguments. (This does NOT
206 include structures with a pointer to a split-sized structure within them.)
207 This can also refer to a function pointer whose only split arguments are
208 string pointers or split-simple structures.
209
210 "split-sized" means a structure where the A and W versions are different
211 sizes (typically because of an inline string argument), or where there's a
212 pointer to another split-sized structure.
213
214 "split-complex"
215
216 begin-unicode-encapsulation-script
217
218 dir c:\Program Files\Microsoft Visual Studio\VC98\Include\
219
220 file WINBASE.H
221
222 yes GetBinaryType
223 yes GetShortPathName
224 yes GetLongPathName
225 yes GetEnvironmentStrings
226 yes FreeEnvironmentStrings
227 yes FormatMessage
228 yes CreateMailslot
229 begin-bracket !defined (CYGWIN_HEADERS)
230 yes EncryptFile
231 yes DecryptFile
232 end-bracket
233 no OpenRaw error "The procedure entry point OpenRawW could not be located in the dynamic link library ADVAPI32.dll."
234 no QueryRecoveryAgents split-sized LPRECOVERY_AGENT_INFORMATION
235 yes lstrcmp
236 yes lstrcmpi
237 yes lstrcpyn
238 yes lstrcpy
239 yes lstrcat
240 yes lstrlen
241 yes CreateMutex
242 yes OpenMutex
243 yes CreateEvent
244 yes OpenEvent
245 yes CreateSemaphore
246 yes OpenSemaphore
247 yes CreateWaitableTimer
248 yes OpenWaitableTimer
249 yes CreateFileMapping
250 yes OpenFileMapping
251 yes GetLogicalDriveStrings
252 yes LoadLibrary
253 yes LoadLibraryEx
254 yes GetModuleFileName
255 yes GetModuleHandle
256 split CreateProcess LPSTARTUPINFO
257 yes FatalAppExit
258 split GetStartupInfo LPSTARTUPINFO
259 yes GetCommandLine
260 yes GetEnvironmentVariable
261 yes SetEnvironmentVariable
262 yes ExpandEnvironmentStrings
263 yes OutputDebugString
264 yes FindResource
265 yes FindResourceEx
266 yes EnumResourceTypes
267 yes EnumResourceNames
268 yes EnumResourceLanguages
269 yes BeginUpdateResource
270 yes UpdateResource
271 yes EndUpdateResource
272 yes GlobalAddAtom
273 yes GlobalFindAtom
274 yes GlobalGetAtomName
275 yes AddAtom
276 yes FindAtom
277 yes GetAtomName
278 yes GetProfileInt
279 yes GetProfileString
280 yes WriteProfileString
281 yes GetProfileSection
282 yes WriteProfileSection
283 yes GetPrivateProfileInt
284 yes GetPrivateProfileString
285 yes WritePrivateProfileString
286 yes GetPrivateProfileSection
287 yes WritePrivateProfileSection
288 yes GetPrivateProfileSectionNames
289 yes GetPrivateProfileStruct
290 yes WritePrivateProfileStruct
291 yes GetDriveType
292 yes GetSystemDirectory
293 yes GetTempPath
294 yes GetTempFileName
295 yes GetWindowsDirectory
296 yes SetCurrentDirectory
297 yes GetCurrentDirectory
298 yes GetDiskFreeSpace
299 yes GetDiskFreeSpaceEx
300 yes CreateDirectory
301 yes CreateDirectoryEx
302 yes RemoveDirectory
303 yes GetFullPathName
304 yes DefineDosDevice
305 yes QueryDosDevice
306 yes CreateFile
307 yes SetFileAttributes
308 yes GetFileAttributes
309 yes GetFileAttributesEx
310 yes GetCompressedFileSize
311 yes DeleteFile
312 no FindFirstFileEx split-sized LPWIN32_FIND_DATA; not used, NT 4.0+ only
313 skip FindFirstFile split-sized LPWIN32_FIND_DATA
314 skip FindNextFile split-sized LPWIN32_FIND_DATA
315 yes SearchPath
316 yes CopyFile
317 yes CopyFileEx NT 4.0+ only
318 yes MoveFile
319 yes MoveFileEx
320 no MoveFileWithProgress NT 5.0+ only
321 no CreateHardLink NT 5.0+ only
322 yes CreateNamedPipe
323 yes GetNamedPipeHandleState
324 yes CallNamedPipe
325 yes WaitNamedPipe
326 yes SetVolumeLabel
327 yes GetVolumeInformation
328 yes ClearEventLog
329 yes BackupEventLog
330 yes OpenEventLog
331 yes RegisterEventSource
332 yes OpenBackupEventLog
333 yes ReadEventLog
334 yes ReportEvent
335 yes AccessCheckAndAuditAlarm
336 no AccessCheckByTypeAndAuditAlarm NT 5.0+ only
337 no AccessCheckByTypeResultListAndAuditAlarm NT 5.0+ only
338 yes ObjectOpenAuditAlarm
339 yes ObjectPrivilegeAuditAlarm
340 yes ObjectCloseAuditAlarm
341 yes ObjectDeleteAuditAlarm
342 yes PrivilegedServiceAuditAlarm
343 yes SetFileSecurity
344 yes GetFileSecurity
345 yes FindFirstChangeNotification
346 no ReadDirectoryChanges Unicode-only
347 yes IsBadStringPtr
348 yes LookupAccountSid
349 yes LookupAccountName
350 yes LookupPrivilegeValue
351 yes LookupPrivilegeName
352 yes LookupPrivilegeDisplayName
353 yes BuildCommDCB
354 yes BuildCommDCBAndTimeouts
355 yes CommConfigDialog
356 yes GetDefaultCommConfig
357 yes SetDefaultCommConfig
358 yes GetComputerName
359 yes SetComputerName
360 yes GetUserName
361 yes LogonUser
362 split CreateProcessAsUser LPSTARTUPINFO
363 no GetCurrentHwProfile split-sized LPHW_PROFILE_INFO; NT 4.0+ only
364 no GetVersionEx split-sized LPOSVERSIONINFO
365 no CreateJobObject NT 5.0+ only
366 no OpenJobObject NT 5.0+ only
367
368 file WINUSER.H
369
370 skip MAKEINTRESOURCE macro
371 yes wvsprintf
372 no wsprintf varargs
373 yes LoadKeyboardLayout
374 yes GetKeyboardLayoutName
375 no CreateDesktop split-sized LPDEVMODE
376 yes OpenDesktop
377 split EnumDesktops DESKTOPENUMPROC // callback fun differs only in string pointer type
378 yes CreateWindowStation
379 yes OpenWindowStation
380 split EnumWindowStations WINSTAENUMPROC // callback fun differs only in string pointer type
381 yes GetUserObjectInformation
382 yes SetUserObjectInformation
383 yes RegisterWindowMessage
384 yes GetMessage
385 yes DispatchMessage
386 yes PeekMessage
387 skip SendMessage split messages and structures
388 yes SendMessageTimeout
389 yes SendNotifyMessage
390 yes SendMessageCallback
391 no BroadcastSystemMessage win95 version not split; NT 4.0+ only
392 no RegisterDeviceNotification NT 5.0+ only
393 yes PostMessage
394 yes PostThreadMessage
395 no PostAppMessage macro
396 skip DefWindowProc return value is conditionalized on _MAC, messes up parser
397 no CallWindowProc two versions, STRICT and non-STRICT
398 skip RegisterClass need to intercept so we can provide our own window procedure and handle split notify messages; split-simple WNDCLASS
399 skip UnregisterClass need to intercept for reasons related to RegisterClass
400 split GetClassInfo LPWNDCLASS
401 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
402 split GetClassInfoEx LPWNDCLASSEX NT 4.0+ only
403 yes CreateWindowEx
404 skip CreateWindow macro
405 yes CreateDialogParam
406 split CreateDialogIndirectParam LPCDLGTEMPLATE error in Cygwin prototype (no split) but fixable with typedef
407 no CreateDialog macro
408 no CreateDialogIndirect macro w/split LPCDLGTEMPLATE
409 yes DialogBoxParam
410 split DialogBoxIndirectParam LPCDLGTEMPLATE error in Cygwin prototype (no split) but fixable with typedef
411 no DialogBox macro
412 no DialogBoxIndirect macro w/split LPCDLGTEMPLATE
413 yes SetDlgItemText
414 yes GetDlgItemText
415 yes SendDlgItemMessage
416 no DefDlgProc return value is conditionalized on _MAC, messes up parser
417 begin-bracket !defined (CYGWIN_HEADERS)
418 yes CallMsgFilter
419 end-bracket
420 yes RegisterClipboardFormat
421 yes GetClipboardFormatName
422 yes CharToOem
423 yes OemToChar
424 yes CharToOemBuff
425 yes OemToCharBuff
426 yes CharUpper
427 yes CharUpperBuff
428 yes CharLower
429 yes CharLowerBuff
430 yes CharNext
431 yes CharPrev
432 no IsCharAlpha split CHAR
433 no IsCharAlphaNumeric split CHAR
434 no IsCharUpper split CHAR
435 no IsCharLower split CHAR
436 yes GetKeyNameText
437 skip VkKeyScan split CHAR
438 no VkKeyScanEx split CHAR; NT 4.0+ only
439 yes MapVirtualKey
440 yes MapVirtualKeyEx NT 4.0+ only
441 yes LoadAccelerators
442 yes CreateAcceleratorTable
443 yes CopyAcceleratorTable
444 yes TranslateAccelerator
445 yes LoadMenu
446 split LoadMenuIndirect MENUTEMPLATE
447 yes ChangeMenu
448 yes GetMenuString
449 yes InsertMenu
450 yes AppendMenu
451 yes ModifyMenu
452 split InsertMenuItem LPCMENUITEMINFO NT 4.0+ only
453 split GetMenuItemInfo LPMENUITEMINFO NT 4.0+ only
454 split SetMenuItemInfo LPCMENUITEMINFO NT 4.0+ only
455 yes DrawText
456 yes DrawTextEx NT 4.0+ only
457 yes GrayString
458 yes DrawState NT 4.0+ only
459 yes TabbedTextOut
460 yes GetTabbedTextExtent
461 yes SetProp
462 yes GetProp
463 yes RemoveProp
464 split EnumPropsEx PROPENUMPROCEX // callback fun differs only in string pointer type
465 split EnumProps PROPENUMPROC // callback fun differs only in string pointer type
466 yes SetWindowText
467 yes GetWindowText
468 yes GetWindowTextLength
469 yes MessageBox
470 yes MessageBoxEx
471 split MessageBoxIndirect LPMSGBOXPARAMS NT 4.0+ only
472 yes GetWindowLong
473 yes SetWindowLong
474 yes GetClassLong
475 yes SetClassLong
476 yes FindWindow
477 yes FindWindowEx NT 4.0+ only
478 yes GetClassName
479 no SetWindowsHook obsolete; two versions, STRICT and non-STRICT
480 yes SetWindowsHookEx
481 yes LoadBitmap
482 yes LoadCursor
483 yes LoadCursorFromFile
484 yes LoadIcon
485 yes LoadImage NT 4.0+ only
486 yes LoadString
487 yes IsDialogMessage
488 yes DlgDirList
489 yes DlgDirSelectEx
490 yes DlgDirListComboBox
491 yes DlgDirSelectComboBoxEx
492 yes DefFrameProc
493 no DefMDIChildProc return value is conditionalized on _MAC, messes up parser
494
495 yes CreateMDIWindow
496 yes WinHelp
497 no ChangeDisplaySettings split-sized LPDEVMODE
498 no ChangeDisplaySettingsEx split-sized LPDEVMODE; NT 5.0/Win98+ only
499 no EnumDisplaySettings split-sized LPDEVMODE
500 no EnumDisplayDevices split-sized PDISPLAY_DEVICE; NT 5.0+ only, no Win98
501 yes SystemParametersInfo probs w/ICONMETRICS, NONCLIENTMETRICS
502 no GetMonitorInfo NT 5.0/Win98+ only
503 no GetWindowModuleFileName NT 5.0+ only
504 no RealGetWindowClass NT 5.0+ only
505 no GetAltTabInfo NT 5.0+ only
506
507 file WINGDI.H
508
509 // split-sized LOGCOLORSPACE
510 // split-sized TEXTMETRIC
511 // split-sized NEWTEXTMETRIC
512 // split-sized NEWTEXTMETRICEX
513 // split-sized LOGFONT
514 // split-sized ENUMLOGFONT
515 // split-sized ENUMLOGFONTEX
516 // split-sized EXTLOGFONT, used in EMREXTCREATEFONTINDIRECTW (Unicode-only) and (???) in DEVINFO (DDK structure)
517 // split-sized DEVMODE
518 // split-sized DISPLAY_DEVICE, used in EnumDisplayDevices
519 // split-sized OUTLINETEXTMETRIC
520 // split-simple POLYTEXT
521 // split-simple GCP_RESULTS
522 // split-sized function pointer OLDFONTENUMPROC, same as FONTENUMPROC
523 // split-sized function pointer FONTENUMPROC
524 yes AddFontResource
525 yes CopyMetaFile
526 skip CreateDC split-sized DEVMODE
527 skip CreateFontIndirect split-sized LOGFONT
528 yes CreateFont
529 skip CreateIC split-sized DEVMODE
530 yes CreateMetaFile
531 yes CreateScalableFontResource
532 skip DeviceCapabilities split-sized DEVMODE
533 skip EnumFontFamiliesEx split-complex FONTENUMPROC; NT 4.0+ only
534 no EnumFontFamilies split-complex FONTENUMPROC
535 no EnumFonts split-complex FONTENUMPROC
536 yes GetCharWidth
537 yes GetCharWidth32
538 yes GetCharWidthFloat
539 yes GetCharABCWidths
540 yes GetCharABCWidthsFloat
541 yes GetGlyphOutline
542 yes GetMetaFile
543 no GetOutlineTextMetrics split-sized LPOUTLINETEXTMETRIC
544 yes GetTextExtentPoint
545 yes GetTextExtentPoint32
546 yes GetTextExtentExPoint
547 split GetCharacterPlacement LPGCP_RESULTS NT 4.0+ only
548 no GetGlyphIndices NT 5.0+ only
549 no AddFontResourceEx NT 5.0+ only
550 no RemoveFontResourceEx NT 5.0+ only
551 // split-sized AXISINFO, used in AXESLIST; NT 5.0+ only
552 // split-sized AXESLIST, used in ENUMLOGFONTEXDV; NT 5.0+ only
553 // split-sized ENUMLOGFONTEXDV; NT 5.0+ only
554 no CreateFontIndirectEx split-sized ENUMLOGFONTEXDV; NT 5.0+ only
555 // split-sized ENUMTEXTMETRIC, returned in EnumFontFamExProc, on NT 5.0+; NT 5.0+ only
556 skip ResetDC split-sized DEVMODE
557 yes RemoveFontResource
558 yes CopyEnhMetaFile
559 yes CreateEnhMetaFile
560 yes GetEnhMetaFile
561 yes GetEnhMetaFileDescription
562 skip GetTextMetrics split-sized LPTEXTMETRIC
563 // split-simple DOCINFO
564 split StartDoc DOCINFO
565 skip GetObject split-sized LOGFONT
566 yes TextOut
567 yes ExtTextOut
568 split PolyTextOut POLYTEXT
569 yes GetTextFace
570 yes GetKerningPairs
571 // split-simple function pointer ICMENUMPROC
572 no GetLogColorSpace split-sized LPLOGCOLORSPACE; NT 4.0+ only
573 no CreateColorSpace split-sized LPLOGCOLORSPACE; NT 4.0+ only
574 skip GetICMProfile NT 4.0+ only, error in Cygwin prototype
575 yes SetICMProfile NT 4.0+ only
576 split EnumICMProfiles ICMENUMPROC NT 4.0+ only
577 skip UpdateICMRegKey NT 4.0+ only, error in Cygwin prototype
578 // non-split EMREXTTEXTOUT (A and W versions identical)
579 // non-split EMRPOLYTEXTOUT (A and W versions identical)
580 // Unicode-only EMREXTCREATEFONTINDIRECTW
581 no wglUseFontBitmaps causes link error
582 no wglUseFontOutlines causes link error
583
584 file WINSPOOL.H
585
586 begin-bracket defined (HAVE_MS_WINDOWS)
587 yes EnumPrinters #### problems with DEVMODE pointer in PRINTER_INFO_2
588 skip OpenPrinter split-sized DEVMODE pointer in split PRINTER_DEFAULTS
589 no ResetPrinter split-sized DEVMODE pointer in split PRINTER_DEFAULTS
590 no SetJob split-sized DEVMODE pointer in split JOB_INFO_2
591 no GetJob split-sized DEVMODE pointer in split JOB_INFO_2
592 no EnumJobs split-sized DEVMODE pointer in split JOB_INFO_2
593 no AddPrinter split-sized DEVMODE pointer in split PRINTER_INFO_2
594 no SetPrinter split-sized DEVMODE pointer in split PRINTER_INFO_2
595 no GetPrinter split-sized DEVMODE pointer in split PRINTER_INFO_2
596 // other than DocumentProperties below, we don't use any of the others,
597 // and they all pretty much have complicated interfaces with lots of
598 // split structures, etc.
599 no AddPrinterDriver not used, complicated interface with split structures
600 no AddPrinterDriverEx not used, complicated interface with split structures
601 no EnumPrinterDrivers not used, complicated interface with split structures
602 no GetPrinterDriver not used, complicated interface with split structures
603 no GetPrinterDriverDirectory not used, complicated interface with split structures
604 no DeletePrinterDriver not used, complicated interface with split structures
605 no DeletePrinterDriverEx not used, complicated interface with split structures
606 no AddPerMachineConnection not used, complicated interface with split structures
607 no DeletePerMachineConnection not used, complicated interface with split structures
608 no EnumPerMachineConnections not used, complicated interface with split structures
609 no AddPrintProcessor not used, complicated interface with split structures
610 no EnumPrintProcessors not used, complicated interface with split structures
611 no GetPrintProcessorDirectory not used, complicated interface with split structures
612 no EnumPrintProcessorDatatypes not used, complicated interface with split structures
613 no DeletePrintProcessor not used, complicated interface with split structures
614 no StartDocPrinter not used, complicated interface with split structures
615 no AddJob not used, complicated interface with split structures
616 skip DocumentProperties split-sized DEVMODE, error in Cygwin prototype
617 no AdvancedDocumentProperties not used, complicated interface with split structures
618 no GetPrinterData not used, complicated interface with split structures
619 no GetPrinterDataEx not used, complicated interface with split structures
620 no EnumPrinterData not used, complicated interface with split structures
621 no EnumPrinterDataEx not used, complicated interface with split structures
622 no EnumPrinterKey not used, complicated interface with split structures
623 no SetPrinterData not used, complicated interface with split structures
624 no SetPrinterDataEx not used, complicated interface with split structures
625 no DeletePrinterData not used, complicated interface with split structures
626 no DeletePrinterDataEx not used, complicated interface with split structures
627 no DeletePrinterKey not used, complicated interface with split structures
628 no PrinterMessageBox not used, complicated interface with split structures
629 no AddForm not used, complicated interface with split structures
630 no DeleteForm not used, complicated interface with split structures
631 no GetForm not used, complicated interface with split structures
632 no SetForm not used, complicated interface with split structures
633 no EnumForms not used, complicated interface with split structures
634 no EnumMonitors not used, complicated interface with split structures
635 no AddMonitor not used, complicated interface with split structures
636 no DeleteMonitor not used, complicated interface with split structures
637 no EnumPorts not used, complicated interface with split structures
638 no AddPort not used, complicated interface with split structures
639 no ConfigurePort not used, complicated interface with split structures
640 no DeletePort not used, complicated interface with split structures
641 no XcvData not used, complicated interface with split structures
642 no SetPort not used, complicated interface with split structures
643 no AddPrinterConnection not used, complicated interface with split structures
644 no DeletePrinterConnection not used, complicated interface with split structures
645 no AddPrintProvidor not used, complicated interface with split structures
646 no DeletePrintProvidor not used, complicated interface with split structures
647 no SetPrinterHTMLView not used, complicated interface with split structures
648 no GetPrinterHTMLView not used, complicated interface with split structures
649 end-bracket
650
651 file SHELLAPI.H
652
653 yes DragQueryFile
654 yes ShellExecute
655 yes FindExecutable
656 no CommandLineToArgv Unicode-only
657 yes ShellAbout
658 yes ExtractAssociatedIcon
659 yes ExtractIcon
660 // split-simple DRAGINFO, used ??? (docs say "Not currently supported")
661 begin-bracket !defined (CYGWIN_HEADERS)
662 yes DoEnvironmentSubst NT 4.0+ only
663 end-bracket
664 no FindEnvironmentString causes link error; NT 4.0+ only
665 skip ExtractIconEx NT 4.0+ only, error in Cygwin prototype
666 // split-simple SHFILEOPSTRUCT, used in SHFileOperation
667 // split-simple SHNAMEMAPPING, used in SHFileOperation
668 split SHFileOperation LPSHFILEOPSTRUCT NT 4.0+ only
669 // split-simple SHELLEXECUTEINFO, used in ShellExecuteEx
670 split ShellExecuteEx LPSHELLEXECUTEINFO NT 4.0+ only
671 no WinExecError causes link error; NT 4.0+ only
672 begin-bracket !defined (CYGWIN_HEADERS)
673 yes SHQueryRecycleBin NT 4.0+ only
674 yes SHEmptyRecycleBin NT 4.0+ only
675 end-bracket
676 // split-sized NOTIFYICONDATA, used in Shell_NotifyIcon
677 no Shell_NotifyIcon split-sized NOTIFYICONDATA, NT 4.0+ only
678 // split-sized SHFILEINFO, used in SHGetFileInfo
679 skip SHGetFileInfo split-sized SHFILEINFO, NT 4.0+ only
680 no SHGetDiskFreeSpace causes link error; NT 4.0+ only
681 begin-bracket !defined (CYGWIN_HEADERS)
682 yes SHGetNewLinkInfo NT 4.0+ only
683 yes SHInvokePrinterCommand NT 4.0+ only
684 end-bracket
685
686 end-unicode-encapsulation-script
687
688 file COMMCTRL.H
689
690 yes ImageList_LoadImage
691 WC_HEADER
692 HDITEM
693 LPHDITEM
694 HDM_INSERTITEM
695 HDM_GETITEM
696 HDM_SETITEM
697 HDN_ITEMCHANGING
698 HDN_ITEMCHANGED
699 HDN_ITEMCLICK
700 HDN_ITEMDBLCLICK
701 HDN_DIVIDERDBLCLICK
702 HDN_BEGINTRACK
703 HDN_ENDTRACK
704 HDN_TRACK
705 HDN_GETDISPINFO
706 NMHEADER
707 LPNMHEADER
708 NMHDDISPINFO
709 LPNMHDDISPINFO
710 TOOLBARCLASSNAME
711 TBSAVEPARAMS
712 LPTBSAVEPARAMS
713 TB_GETBUTTONTEXT
714 TB_SAVERESTORE
715 TB_ADDSTRING
716 TBBUTTONINFO
717 LPTBBUTTONINFO
718 TB_GETBUTTONINFO
719 TB_SETBUTTONINFO
720 TB_INSERTBUTTON
721 TB_ADDBUTTONS
722 TBN_GETINFOTIP
723 NMTBGETINFOTIP
724 LPNMTBGETINFOTIP
725 TBN_GETDISPINFO
726 LPNMTBDISPINFO
727 TBN_GETBUTTONINFO
728 NMTOOLBAR
729 LPNMTOOLBAR
730 REBARCLASSNAME
731 REBARBANDINFO
732 LPREBARBANDINFO
733 LPCREBARBANDINFO
734 RB_INSERTBAND
735 RB_SETBANDINFO
736 RB_GETBANDINFO
737 TOOLTIPS_CLASS
738 TTTOOLINFO
739 PTOOLINFO
740 LPTTTOOLINFO
741 TTM_ADDTOOL
742 TTM_DELTOOL
743 TTM_NEWTOOLRECT
744 TTM_GETTOOLINFO
745 TTM_SETTOOLINFO
746 TTM_HITTEST
747 TTM_GETTEXT
748 TTM_UPDATETIPTEXT
749 TTM_ENUMTOOLS
750 TTM_GETCURRENTTOOL
751 TTHITTESTINFO
752 LPTTHITTESTINFO
753 TTN_GETDISPINFO
754 NMTTDISPINFO
755 LPNMTTDISPINFO
756 CreateStatusWindow
757 DrawStatusText
758 STATUSCLASSNAME
759 SB_GETTEXT
760 SB_SETTEXT
761 SB_GETTEXTLENGTH
762 SB_SETTIPTEXT
763 SB_GETTIPTEXT
764 TRACKBAR_CLASS
765 UPDOWN_CLASS
766 PROGRESS_CLASS
767 HOTKEY_CLASS
768 WC_LISTVIEW
769 LVITEM
770 LPLVITEM
771 LPSTR_TEXTCALLBACK
772 LVM_GETITEM
773 LVM_SETITEM
774 LVM_INSERTITEM
775 LVFINDINFO
776 LVM_FINDITEM
777 LVM_GETSTRINGWIDTH
778 LVM_EDITLABEL
779 LVCOLUMN
780 LPLVCOLUMN
781 LVM_GETCOLUMN
782 LVM_SETCOLUMN
783 LVM_GETITEMTEXT
784 LVM_SETITEMTEXT
785 LVM_GETISEARCHSTRING
786 LVBKIMAGE
787 LPLVBKIMAGE
788 LVM_SETBKIMAGE
789 LVM_GETBKIMAGE
790 LVN_ODFINDITEM
791 LVN_BEGINLABELEDIT
792 LVN_ENDLABELEDIT
793 LVN_GETDISPINFO
794 LVN_SETDISPINFO
795 NMLVDISPINFO
796 LVN_GETINFOTIP
797 NMLVGETINFOTIP
798 LPNMLVGETINFOTIP
799 WC_TREEVIEW
800 TVITEM
801 LPTVITEM
802 TVINSERTSTRUCT
803 LPTVINSERTSTRUCT
804 TVM_INSERTITEM
805 TVM_GETITEM
806 TVM_SETITEM
807 TVM_EDITLABEL
808 TVM_GETISEARCHSTRING
809 NMTREEVIEW
810 LPNMTREEVIEW
811 NMTVDISPINFO
812 LPNMTVDISPINFO
813 TVN_SELCHANGING
814 TVN_SELCHANGED
815 TVN_GETDISPINFO
816 TVN_SETDISPINFO
817 TVN_ITEMEXPANDING
818 TVN_ITEMEXPANDED
819 TVN_BEGINDRAG
820 TVN_BEGINRDRAG
821 TVN_DELETEITEM
822 TVN_BEGINLABELEDIT
823 TVN_ENDLABELEDIT
824 TVN_GETINFOTIP
825 NMTVGETINFOTIP
826 LPNMTVGETINFOTIP
827 WC_COMBOBOXEX
828 COMBOBOXEXITEM
829 PCOMBOBOXEXITEM
830 PCCOMBOBOXEXITEM
831 CBEM_INSERTITEM
832 CBEM_SETITEM
833 CBEM_GETITEM
834 NMCOMBOBOXEX
835 PNMCOMBOBOXEX
836 CBEN_GETDISPINFO
837 CBEN_DRAGBEGIN
838 CBEN_ENDEDIT
839 NMCBEDRAGBEGIN
840 LPNMCBEDRAGBEGIN
841 PNMCBEDRAGBEGIN
842 NMCBEENDEDIT
843 LPNMCBEENDEDIT
844 PNMCBEENDEDIT
845 WC_TABCONTROL
846 TCITEMHEADER
847 LPTCITEMHEADER
848 TCITEM
849 LPTCITEM
850 TCM_GETITEM
851 TCM_SETITEM
852 TCM_INSERTITEM
853 ANIMATE_CLASS
854 ACM_OPEN
855 MONTHCAL_CLASS
856 DATETIMEPICK_CLASS
857 DTM_SETFORMAT
858 DTN_USERSTRING
859 NMDATETIMESTRING
860 LPNMDATETIMESTRING
861 DTN_WMKEYDOWN
862 NMDATETIMEWMKEYDOWN
863 LPNMDATETIMEWMKEYDOWN
864 DTN_FORMAT
865 NMDATETIMEFORMAT
866 LPNMDATETIMEFORMAT
867 DTN_FORMATQUERY
868 NMDATETIMEFORMATQUERY
869 LPNMDATETIMEFORMATQUERY
870 WC_IPADDRESS
871 WC_PAGESCROLLER
872 WC_NATIVEFONTCTL
873
874 begin-unicode-encapsulation-script
875
876 file COMMDLG.H
877
878 split GetOpenFileName LPOPENFILENAME
879 split GetSaveFileName LPOPENFILENAME
880 yes GetFileTitle
881 no CommDlg_OpenSave_GetSpec macro
882 no CommDlg_OpenSave_GetFilePath macro
883 no CommDlg_OpenSave_GetFolderPath macro
884 split ChooseColor LPCHOOSECOLOR
885 split FindText LPFINDREPLACE
886 split ReplaceText LPFINDREPLACE
887 no AfxReplaceText mac only
888 no ChooseFont split-sized LPLOGFONT in LPCHOOSEFONT
889 // LBSELCHSTRING
890 // SHAREVISTRING
891 // FILEOKSTRING
892 // COLOROKSTRING
893 // SETRGBSTRING
894 // HELPMSGSTRING
895 // FINDMSGSTRING
896 skip PrintDlg LPPRINTDLG with split-sized DEVMODE handle
897 skip PageSetupDlg LPPAGESETUPDLG with split-sized DEVMODE handle
898
899 file DDE.H
900
901 // nothing
902
903 file DDEML.H
904
905 yes DdeInitialize
906 yes DdeCreateStringHandle
907 yes DdeQueryString
908 // #### 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
909
910 file IMM.H
911
912 begin-bracket defined (HAVE_MS_WINDOWS)
913 yes ImmInstallIME
914 yes ImmGetDescription
915 yes ImmGetIMEFileName
916 yes ImmGetCompositionString
917 yes ImmSetCompositionString
918 yes ImmGetCandidateListCount
919 yes ImmGetCandidateList
920 yes ImmGetGuideLine
921 skip ImmGetCompositionFont split-sized LOGFONT
922 skip ImmSetCompositionFont split-sized LOGFONT
923 yes ImmConfigureIME // split-simple REGISTERWORD
924 yes ImmEscape // strings of various sorts
925 yes ImmGetConversionList
926 yes ImmIsUIMessage
927 yes ImmRegisterWord
928 yes ImmUnregisterWord
929 no ImmGetRegisterWordStyle split-sized STYLEBUF
930 split ImmEnumRegisterWord REGISTERWORDENUMPROC
931 no ImmGetImeMenuItems split-sized IMEMENUITEMINFO
932 end-bracket
933
934 file MMSYSTEM.H
935
936 yes sndPlaySound
937 yes PlaySound
938 no waveOutGetDevCaps split-sized LPWAVEOUTCAPS
939 yes waveOutGetErrorText
940 no waveInGetDevCaps split-sized LPWAVEINCAPS
941 yes waveInGetErrorText
942 no midiOutGetDevCaps split-sized LPMIDIOUTCAPS
943 yes midiOutGetErrorText
944 no midiInGetDevCaps split-sized LPMIDIOUTCAPS
945 yes midiInGetErrorText
946 no auxGetDevCaps split-sized LPAUXCAPS
947 no mixerGetDevCaps split-sized LPMIXERCAPS
948 no mixerGetLineInfo split-sized LPMIXERLINE
949 no mixerGetLineControls split-sized LPMIXERCONTROL
950 no mixerGetControlDetails split-sized LPMIXERCONTROL in LPMIXERLINECONTROLS in LPMIXERCONTROLDETAILS
951 no joyGetDevCaps split-sized LPJOYCAPS
952 yes mmioStringToFOURCC
953 yes mmioInstallIOProc
954 yes mmioOpen
955 yes mmioRename
956 yes mciSendCommand
957 yes mciSendString
958 yes mciGetDeviceID
959 begin-bracket !defined (MINGW)
960 yes mciGetDeviceIDFromElementID
961 end-bracket
962 yes mciGetErrorString
963
964 file WINNETWK.H
965
966 begin-bracket defined (HAVE_MS_WINDOWS)
967 yes WNetAddConnection
968 split WNetAddConnection2 LPNETRESOURCE
969 split WNetAddConnection3 LPNETRESOURCE
970 yes WNetCancelConnection
971 yes WNetCancelConnection2
972 yes WNetGetConnection
973 split WNetUseConnection LPNETRESOURCE
974 split WNetConnectionDialog1 LPCONNECTDLGSTRUCT contains split-simple LPNETRESOURCE
975 split WNetDisconnectDialog1 LPDISCDLGSTRUCT
976 split WNetOpenEnum LPNETRESOURCE
977 yes WNetEnumResource
978 yes WNetGetUniversalName
979 yes WNetGetUser
980 yes WNetGetProviderName
981 yes WNetGetNetworkInformation
982 // split-simple function pointer PFNGETPROFILEPATH
983 // split-simple function pointer PFNRECONCILEPROFILE
984 // split-simple function pointer PFNPROCESSPOLICIES
985 yes WNetGetLastError
986 split MultinetGetConnectionPerformance LPNETRESOURCE
987 end-bracket
988
989 file IME.H
990
991 no SendIMEMessageEx obsolete, no docs available
992
993 file OBJBASE.H
994
995 // nothing
996
997 file SHLOBJ.H
998
999 // #### split code for IContextMenu not yet written
1000 // split flag constant GCS_VERB of IContextMenu::GetCommandString
1001 // split flag constant GCS_HELPTEXT of IContextMenu::GetCommandString
1002 // split flag constant GCS_VALIDATE of IContextMenu::GetCommandString
1003 // split string constant CMDSTR_NEWFOLDER of CMINVOKECOMMANDINFO.lpVerb or CMINVOKECOMMANDINFOEX.lpVerbW of IContextMenu::InvokeCommand
1004 // split string constant CMDSTR_VIEWLIST of same
1005 // split string constant CMDSTR_VIEWDETAILS of same
1006 // #### split code for IExtractIcon, IShellLink, IShellExecuteHook, INewShortcutHook, ICopyHook, IFileViewer not yet written
1007 // split interface IExtractIcon
1008 // split interface IShellLink
1009 // split interface IShellExecuteHook
1010 // split interface INewShortcutHook
1011 // split interface ICopyHook
1012 // split interface IFileViewer
1013 yes SHGetPathFromIDList
1014 skip SHGetSpecialFolderPath error in Cygwin prototype, missing from Cygwin libraries
1015 // split-simple structure BROWSEINFO used in SHBrowseForFolder
1016 skip SHBrowseForFolder need to intercept callback for SendMessage
1017 // split message BFFM_SETSTATUSTEXT handled in qxeSendMessage
1018 // split message BFFM_SETSELECTION handled in qxeSendMessage
1019 // split message BFFM_VALIDATEFAILED handled in qxeSHBrowseForFolder intercept proc
1020 // #### code to handle split clipboard formats not yet written. this will
1021 // #### be tricky -- all functions that use such clipboard formats need to
1022 // #### be split, and the data itself munged. this may be too much effort,
1023 // #### and we may just need to require that the app itself does the
1024 // #### splitting.
1025 // split clipboard format CFSTR_FILEDESCRIPTOR
1026 // split clipboard format CFSTR_FILENAME
1027 // split clipboard format CFSTR_FILENAMEMAP
1028 // split-sized structure FILEDESCRIPTOR
1029 // split-sized structure FILEGROUPDESCRIPTOR
1030 // split flag SHCNF_PATH; we intercept SHChangeNotify
1031 // split flag SHCNF_PRINTER; we intercept SHChangeNotify
1032 // split flag SHARD_PATH; we intercept SHAddToRecentDocs
1033 skip SHGetDataFromIDList split-sized WIN32_FIND_DATA or split-simple NETRESOURCE, missing from Cygwin libraries
1034
1035 end-unicode-encapsulation-script
1036
1037 file WINNLS.H
1038
1039 LOCALE_ENUMPROC
1040 CODEPAGE_ENUMPROC
1041 DATEFMT_ENUMPROC
1042 DATEFMT_ENUMPROCEX
1043 TIMEFMT_ENUMPROC
1044 CALINFO_ENUMPROC
1045 CALINFO_ENUMPROCEX
1046 GetCPInfoEx
1047 CompareString
1048 LCMapString
1049 GetLocaleInfo
1050 SetLocaleInfo
1051 GetTimeFormat
1052 GetDateFormat
1053 GetNumberFormat
1054 GetCurrencyFormat
1055 EnumCalendarInfo
1056 EnumCalendarInfoEx
1057 EnumTimeFormats
1058 EnumDateFormats
1059 EnumDateFormatsEx
1060 GetStringTypeEx
1061 FoldString
1062 EnumSystemLocales
1063 EnumSystemCodePages
1064
1065 file WINVER.H
1066
1067 VerFindFile
1068 VerInstallFile
1069 GetFileVersionInfoSize
1070 GetFileVersionInfo
1071 VerLanguageName
1072 VerQueryValue
1073
1074 begin-unicode-encapsulation-script
1075
1076 file WINCON.H
1077
1078 yes PeekConsoleInput
1079 yes ReadConsoleInput
1080 yes WriteConsoleInput
1081 yes ReadConsoleOutput
1082 yes WriteConsoleOutput
1083 yes ReadConsoleOutputCharacter
1084 yes WriteConsoleOutputCharacter
1085 no FillConsoleOutputCharacter split CHAR
1086 yes ScrollConsoleScreenBuffer
1087 yes GetConsoleTitle
1088 yes SetConsoleTitle
1089 yes ReadConsole
1090 yes WriteConsole
1091
1092 file WINREG.H
1093
1094 skip RegConnectRegistry error in Cygwin prototype
1095 yes RegCreateKey
1096 yes RegCreateKeyEx
1097 yes RegDeleteKey
1098 yes RegDeleteValue
1099 yes RegEnumKey
1100 yes RegEnumKeyEx
1101 yes RegEnumValue
1102 yes RegLoadKey
1103 yes RegOpenKey
1104 yes RegOpenKeyEx
1105 yes RegQueryInfoKey
1106 yes RegQueryValue
1107 split RegQueryMultipleValues PVALENT
1108 yes RegQueryValueEx
1109 yes RegReplaceKey
1110 yes RegRestoreKey
1111 yes RegSaveKey
1112 yes RegSetValue
1113 yes RegSetValueEx
1114 yes RegUnLoadKey
1115 yes InitiateSystemShutdown
1116 yes AbortSystemShutdown
1117
1118 end-unicode-encapsulation-script
1119
1120 file EXCPT.H
1121
1122 // nothing
1123
1124 file STDARG.H
1125
1126 // nothing
1127
1128 file CDERR.H
1129
1130 // nothing
1131
1132 file WINPERF.H
1133
1134 // nothing
1135
1136 file RPC.H
1137
1138 // nothing
1139
1140 file NB30.H
1141
1142 // nothing
1143
1144 file WINSOCK2.H
1145
1146 SO_PROTOCOL_INFO
1147 SERVICE_TYPE_VALUE_SAPID
1148 SERVICE_TYPE_VALUE_TCPPORT
1149 SERVICE_TYPE_VALUE_UDPPORT
1150 SERVICE_TYPE_VALUE_OBJECTID
1151 WSADuplicateSocket
1152 LPFN_WSADUPLICATESOCKET
1153 WSAEnumProtocols
1154 LPFN_WSAENUMPROTOCOLS
1155 WSASocket
1156 LPFN_WSASOCKET
1157 WSAAddressToString
1158 LPFN_WSAADDRESSTOSTRING
1159 WSAStringToAddress
1160 LPFN_WSASTRINGTOADDRESS
1161 WSALookupServiceBegin
1162 LPFN_WSALOOKUPSERVICEBEGIN
1163 WSALookupServiceNext
1164 LPFN_WSALOOKUPSERVICENEXT
1165 WSAInstallServiceClass
1166 LPFN_WSAINSTALLSERVICECLASS
1167 WSAGetServiceClassInfo
1168 LPFN_WSAGETSERVICECLASSINFO
1169 WSAEnumNameSpaceProviders
1170 LPFN_WSAENUMNAMESPACEPROVIDERS
1171 WSAGetServiceClassNameByClassId
1172 LPFN_WSAGETSERVICECLASSNAMEBYCLASSID
1173 WSASetService
1174 LPFN_WSASETSERVICE
1175
1176 file WINCRYPT.H
1177
1178 MS_DEF_PROV_
1179 MS_ENHANCED_PROV_
1180 MS_DEF_RSA_SIG_PROV_
1181 MS_DEF_RSA_SCHANNEL_PROV_
1182 MS_ENHANCED_RSA_SCHANNEL_PROV_
1183 MS_DEF_DSS_PROV_
1184 MS_DEF_DSS_DH_PROV_
1185 CryptAcquireContext
1186 CryptSignHash
1187 CryptVerifySignature
1188 CryptSetProvider
1189 CryptSetProviderEx
1190 CryptGetDefaultProvider
1191 CryptEnumProviderTypes
1192 CryptEnumProviders
1193 CERT_STORE_PROV_FILENAME_
1194 CERT_STORE_PROV_SYSTEM_
1195 sz_CERT_STORE_PROV_FILENAME_
1196 sz_CERT_STORE_PROV_SYSTEM_
1197 CERT_STORE_SAVE_TO_FILENAME_
1198 CERT_FIND_SUBJECT_STR_
1199 CERT_FIND_ISSUER_STR_
1200 CertRDNValueToStr
1201 CertNameToStr
1202 CertStrToName
1203 CertOpenSystemStore
1204 CertAddEncodedCertificateToSystemStore
1205
1206 */
1207
1208 /* the functions below are examples of hand-written Unicode-splitting
1209 code. note that it needs to be written very carefully and with
1210 intimate knowledge of the structures involved, and can sometimes be
1211 very hairy (EnumFontFamiliesEx is the most extreme example). it can
1212 be argued with some justification that this behind-the-scenes magic
1213 is confusing and potentially dangerous, and shouldn't be done. but
1214 making the calling code deal with the results in extremely hard-to-
1215 read code and is very error-prone. */
1216
1217
1218 /************************************************************************/
1219 /* would be encapsulatable but for parsing problems */
1220 /************************************************************************/
1221
1222 /* NOTE: return value is conditionalized on _MAC, messes up parser */
1223 LRESULT
1224 qxeDefWindowProc (HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
1225 {
1226 if (XEUNICODE_P)
1227 return DefWindowProcW (hWnd, Msg, wParam, lParam);
1228 else
1229 return DefWindowProcA (hWnd, Msg, wParam, lParam);
1230 }
1231
1232
1233 /* NOTE: two versions, STRICT and non-STRICT */
1234 LRESULT
1235 qxeCallWindowProc (WNDPROC lpPrevWndFunc, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
1236 {
1237 if (XEUNICODE_P)
1238 return CallWindowProcW (lpPrevWndFunc, hWnd, Msg, wParam, lParam);
1239 else
1240 return CallWindowProcA (lpPrevWndFunc, hWnd, Msg, wParam, lParam);
1241 }
1242
1243 /* NOTE: return value is conditionalized on _MAC, messes up parser */
1244 LRESULT
1245 qxeDefDlgProc (HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lParam)
1246 {
1247 if (XEUNICODE_P)
1248 return DefDlgProcW (hDlg, Msg, wParam, lParam);
1249 else
1250 return DefDlgProcA (hDlg, Msg, wParam, lParam);
1251 }
1252
1253 /* NOTE: return value is conditionalized on _MAC, messes up parser */
1254 LRESULT
1255 qxeDefMDIChildProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
1256 {
1257 if (XEUNICODE_P)
1258 return DefMDIChildProcW (hWnd, uMsg, wParam, lParam);
1259 else
1260 return DefMDIChildProcA (hWnd, uMsg, wParam, lParam);
1261 }
1262
1263
1264 /************************************************************************/
1265 /* would be encapsulatable but for Cygwin problems */
1266 /************************************************************************/
1267
1268 LONG
1269 qxeRegConnectRegistry (const Extbyte * lpMachineName, HKEY hKey, PHKEY phkResult)
1270 {
1271 /* Cygwin mistakenly omits const in first argument. */
1272 if (XEUNICODE_P)
1273 return RegConnectRegistryW ((LPWSTR) lpMachineName, hKey, phkResult);
1274 else
1275 return RegConnectRegistryA ((LPSTR) lpMachineName, hKey, phkResult);
1276 }
1277
1278 /* NOTE: NT 4.0+ only */
1279 UINT
1280 qxeExtractIconEx (const Extbyte * lpszFile, int nIconIndex, HICON FAR * phiconLarge, HICON FAR * phiconSmall, UINT nIcons)
1281 {
1282 /* Cygwin mistakenly declares the return type as HICON. */
1283 if (XEUNICODE_P)
1284 return (UINT) ExtractIconExW ((LPCWSTR) lpszFile, nIconIndex, phiconLarge, phiconSmall, nIcons);
1285 else
1286 return (UINT) ExtractIconExA ((LPCSTR) lpszFile, nIconIndex, phiconLarge, phiconSmall, nIcons);
1287 }
1288
1289 /* NOTE: NT 4.0+ only */
1290 BOOL
1291 qxeGetICMProfile (HDC arg1, LPDWORD arg2, Extbyte * arg3)
1292 {
1293 #ifdef CYGWIN_HEADERS
1294 /* Cygwin mistakenly declares the second argument as DWORD. */
1295 if (XEUNICODE_P)
1296 return GetICMProfileW (arg1, (DWORD) arg2, (LPWSTR) arg3);
1297 else
1298 return GetICMProfileA (arg1, (DWORD) arg2, (LPSTR) arg3);
1299 #else
1300 if (XEUNICODE_P)
1301 return GetICMProfileW (arg1, arg2, (LPWSTR) arg3);
1302 else
1303 return GetICMProfileA (arg1, arg2, (LPSTR) arg3);
1304 #endif /* CYGWIN_HEADERS */
1305 }
1306
1307 /* NOTE: NT 4.0+ only */
1308 BOOL
1309 qxeUpdateICMRegKey (DWORD arg1, Extbyte * arg2, Extbyte * arg3, UINT arg4)
1310 {
1311 #ifdef CYGWIN_HEADERS
1312 /* Cygwin mistakenly declares the second argument as DWORD. */
1313 if (XEUNICODE_P)
1314 return UpdateICMRegKeyW (arg1, (DWORD) arg2, (LPWSTR) arg3, arg4);
1315 else
1316 return UpdateICMRegKeyA (arg1, (DWORD) arg2, (LPSTR) arg3, arg4);
1317 #else
1318 if (XEUNICODE_P)
1319 return UpdateICMRegKeyW (arg1, (LPWSTR) arg2, (LPWSTR) arg3, arg4);
1320 else
1321 return UpdateICMRegKeyA (arg1, (LPSTR) arg2, (LPSTR) arg3, arg4);
1322 #endif /* CYGWIN_HEADERS */
1323 }
1324
1325 #ifndef CYGWIN /* present in headers but missing in shell32.a */
1326
1327 BOOL
1328 qxeSHGetSpecialFolderPath (HWND hwndOwner, Extbyte * lpszPath, int nFolder, BOOL fCreate)
1329 {
1330 #ifdef CYGWIN_HEADERS
1331 /* Cygwin mistakenly declares the second argument as LPSTR in both
1332 versions. */
1333 if (XEUNICODE_P)
1334 return SHGetSpecialFolderPathW (hwndOwner, (LPSTR) lpszPath, nFolder, fCreate);
1335 else
1336 return SHGetSpecialFolderPathA (hwndOwner, (LPSTR) lpszPath, nFolder, fCreate);
1337 #else
1338 if (XEUNICODE_P)
1339 return SHGetSpecialFolderPathW (hwndOwner, (LPWSTR) lpszPath, nFolder, fCreate);
1340 else
1341 return SHGetSpecialFolderPathA (hwndOwner, (LPSTR) lpszPath, nFolder, fCreate);
1342 #endif
1343 }
1344
1345 #endif /* not CYGWIN */
1346
1347
1348 /************************************************************************/
1349 /* files */
1350 /************************************************************************/
1351
1352 static void
1353 copy_win32_find_dataa_to_win32_find_dataw (const WIN32_FIND_DATAA *pa,
1354 WIN32_FIND_DATAW *pw)
1355 {
1356 /* the layout of WIN32_FIND_DATA is
1357
1358 non-split fields;
1359 TCHAR cFileName[...];
1360 TCHAR cAlternateFileName[...];
1361 */
1362
1363 xzero (*pw);
1364 memcpy (pw, pa, offsetof (WIN32_FIND_DATAA, cFileName));
1365 memcpy (pw->cFileName, pa->cFileName, sizeof (pa->cFileName));
1366 memcpy (pw->cAlternateFileName, pa->cAlternateFileName,
1367 sizeof (pa->cAlternateFileName));
1368 }
1369
1370 HANDLE
1371 qxeFindFirstFile (const Extbyte *lpFileName,
1372 WIN32_FIND_DATAW *lpFindFileData)
1373 {
1374 if (XEUNICODE_P)
1375 return FindFirstFileW ((LPCWSTR) lpFileName, lpFindFileData);
1376 else
1377 {
1378 WIN32_FIND_DATAA ansidat;
1379 HANDLE retval;
1380
1381 retval = FindFirstFileA ((LPCSTR) lpFileName, &ansidat);
1382 if (retval != INVALID_HANDLE_VALUE)
1383 copy_win32_find_dataa_to_win32_find_dataw (&ansidat, lpFindFileData);
1384 return retval;
1385 }
1386 }
1387
1388 BOOL
1389 qxeFindNextFile (HANDLE hFindFile, WIN32_FIND_DATAW *lpFindFileData)
1390 {
1391 if (XEUNICODE_P)
1392 return FindNextFileW (hFindFile, lpFindFileData);
1393 else
1394 {
1395 WIN32_FIND_DATAA ansidat;
1396 BOOL retval;
1397
1398 retval = FindNextFileA (hFindFile, &ansidat);
1399 if (retval)
1400 copy_win32_find_dataa_to_win32_find_dataw (&ansidat, lpFindFileData);
1401 return retval;
1402 }
1403 }
1404
1405
1406 /************************************************************************/
1407 /* shell */
1408 /************************************************************************/
1409
1410 static void
1411 copy_shfileinfoa_to_shfileinfow (const SHFILEINFOA *pa,
1412 SHFILEINFOW *pw)
1413 {
1414 /* the layout of SHFILEINFO is
1415
1416 non-split fields;
1417 TCHAR szDisplayName[...];
1418 TCHAR szTypeName[...];
1419 */
1420
1421 xzero (*pw);
1422 memcpy (pw, pa, offsetof (SHFILEINFOA, szDisplayName));
1423 memcpy (pw->szDisplayName, pa->szDisplayName, sizeof (pa->szDisplayName));
1424 memcpy (pw->szTypeName, pa->szTypeName, sizeof (pa->szTypeName));
1425 }
1426
1427 DWORD
1428 qxeSHGetFileInfo (const Extbyte *pszPath, DWORD dwFileAttributes,
1429 SHFILEINFOW *psfi, UINT cbFileInfo, UINT uFlags)
1430 {
1431 if (XEUNICODE_P)
1432 return SHGetFileInfoW ((LPCWSTR) pszPath, dwFileAttributes,
1433 psfi, cbFileInfo, uFlags);
1434 else
1435 {
1436 SHFILEINFOA ansidat;
1437 BOOL retval;
1438
1439 retval = SHGetFileInfoA ((LPCSTR) pszPath, dwFileAttributes,
1440 (SHFILEINFOA FAR *) &ansidat, sizeof (ansidat),
1441 uFlags);
1442 if (retval)
1443 copy_shfileinfoa_to_shfileinfow (&ansidat, psfi);
1444 return retval;
1445 }
1446 }
1447
1448 struct intercepted_SHBrowseForFolder
1449 {
1450 BFFCALLBACK lpfn;
1451 LPARAM lParam;
1452 HWND hwnd;
1453 struct intercepted_SHBrowseForFolder *next;
1454 };
1455
1456 static struct intercepted_SHBrowseForFolder *SHBrowseForFolder_list;
1457
1458 static int
1459 CALLBACK intercepted_SHBrowseForFolder_proc (HWND hwnd, UINT msg,
1460 LPARAM lParam, LPARAM lpData)
1461 {
1462 struct intercepted_SHBrowseForFolder *s =
1463 (struct intercepted_SHBrowseForFolder *) lpData;
1464
1465 if (s->hwnd == 0)
1466 s->hwnd = hwnd;
1467 if (s->lpfn)
1468 {
1469 /* see below */
1470 if (XEUNICODE_P && msg == BFFM_VALIDATEFAILEDW)
1471 msg = BFFM_VALIDATEFAILEDA;
1472 else if (!XEUNICODE_P && msg == BFFM_VALIDATEFAILEDA)
1473 msg = BFFM_VALIDATEFAILEDW;
1474 return (s->lpfn) (hwnd, msg, lParam, s->lParam);
1475 }
1476 else
1477 return 0;
1478 }
1479
1480 static int
1481 is_SHBrowseForFolder (HWND hwnd)
1482 {
1483 struct intercepted_SHBrowseForFolder *s;
1484
1485 for (s = SHBrowseForFolder_list; s; s = s->next)
1486 if (s->hwnd == hwnd)
1487 return 1;
1488 return 0;
1489 }
1490
1491 LPITEMIDLIST
1492 qxeSHBrowseForFolder (LPBROWSEINFOW lpbi)
1493 {
1494 struct intercepted_SHBrowseForFolder s;
1495 LPITEMIDLIST retval;
1496
1497 /* There are two outgoing Unicode-split messages:
1498
1499 BFFM_SETSELECTION
1500 BFFM_SETSTATUSTEXT
1501
1502 and one incoming:
1503
1504 BFFM_VALIDATEFAILED
1505
1506 To handle this, we need to intercept the callback. We handle the
1507 incoming message in the callback, and record the window; when
1508 qxeSendMessage() is called, we handle the outgoing messages. None of
1509 the messages have split-sized structures so we don't need to do
1510 anything complicated there. */
1511
1512 s.lParam = lpbi->lParam;
1513 s.lpfn = lpbi->lpfn;
1514 s.next = SHBrowseForFolder_list;
1515 s.hwnd = 0;
1516 SHBrowseForFolder_list = &s;
1517
1518 lpbi->lpfn = intercepted_SHBrowseForFolder_proc;
1519 lpbi->lParam = (LPARAM) &s;
1520
1521 if (XEUNICODE_P)
1522 retval = SHBrowseForFolderW (lpbi);
1523 else
1524 retval = SHBrowseForFolderA ((LPBROWSEINFOA) lpbi);
1525 SHBrowseForFolder_list = SHBrowseForFolder_list->next;
1526 return retval;
1527 }
1528
1529 VOID
1530 qxeSHAddToRecentDocs (UINT uFlags, LPCVOID pv)
1531 {
1532 /* pv can be a string pointer; this is handled by Unicode-splitting the
1533 flag SHARD_PATH rather than the function itself. Fix up the flag to
1534 be correct. We write it symmetrically so it doesn't matter whether
1535 UNICODE is defined. */
1536 if (XEUNICODE_P)
1537 {
1538 if (uFlags & SHARD_PATHA)
1539 {
1540 uFlags |= SHARD_PATHW;
1541 uFlags &= ~SHARD_PATHA;
1542 }
1543 }
1544 else
1545 {
1546 if (uFlags & SHARD_PATHW)
1547 {
1548 uFlags |= SHARD_PATHA;
1549 uFlags &= ~SHARD_PATHW;
1550 }
1551 }
1552 SHAddToRecentDocs (uFlags, pv);
1553 }
1554
1555 VOID
1556 qxeSHChangeNotify (LONG wEventId, UINT uFlags, LPCVOID dwItem1,
1557 LPCVOID dwItem2)
1558 {
1559 /* works like SHAddToRecentDocs */
1560 if (XEUNICODE_P)
1561 {
1562 if (uFlags & SHCNF_PATHA)
1563 {
1564 uFlags |= SHCNF_PATHW;
1565 uFlags &= ~SHCNF_PATHA;
1566 }
1567 if (uFlags & SHCNF_PRINTERA)
1568 {
1569 uFlags |= SHCNF_PRINTERW;
1570 uFlags &= ~SHCNF_PRINTERA;
1571 }
1572 }
1573 else
1574 {
1575 if (uFlags & SHCNF_PATHW)
1576 {
1577 uFlags |= SHCNF_PATHA;
1578 uFlags &= ~SHCNF_PATHW;
1579 }
1580 if (uFlags & SHCNF_PRINTERW)
1581 {
1582 uFlags |= SHCNF_PRINTERA;
1583 uFlags &= ~SHCNF_PRINTERW;
1584 }
1585 }
1586 SHChangeNotify (wEventId, uFlags, dwItem1, dwItem2);
1587 }
1588
1589 #ifndef CYGWIN /* present in headers but missing in shell32.a */
1590
1591 HRESULT
1592 qxeSHGetDataFromIDList (IShellFolder *psf, LPCITEMIDLIST pidl, int nFormat,
1593 PVOID pv, int cb)
1594 {
1595 if (XEUNICODE_P)
1596 return SHGetDataFromIDListW (psf, pidl, nFormat, pv, cb);
1597 else if (nFormat == SHGDFIL_FINDDATA)
1598 {
1599 WIN32_FIND_DATAA ansidat;
1600 BOOL retval;
1601
1602 retval = SHGetDataFromIDListA (psf, pidl, nFormat, &ansidat, cb);
1603 if (retval == NOERROR)
1604 copy_win32_find_dataa_to_win32_find_dataw (&ansidat, pv);
1605 return retval;
1606 }
1607 else
1608 /* nFormat == SHGDFIL_NETRESOURCE, and pv is split-simple NETRESOURCE
1609 structure, but we don't need to worry about that currently since we
1610 don't translate strings */
1611 return SHGetDataFromIDListA (psf, pidl, nFormat, pv, cb);
1612 }
1613
1614 #endif /* not CYGWIN */
1615
1616
1617
1618 #ifdef HAVE_MS_WINDOWS
1619
1620 /************************************************************************/
1621 /* devmode */
1622 /************************************************************************/
1623
1624 /* These functions return globally allocated blocks because some
1625 callers (e.g. qxePrintDlg) want this. */
1626
1627 static HGLOBAL
1628 copy_devmodew_to_devmodea (const DEVMODEW *src, DEVMODEA *dst)
1629 {
1630 /* the layout of DEVMODE is
1631
1632 TCHAR dmDeviceName[...];
1633 non-split fields, including dmSize (size of structure; differs between
1634 Unicode and ANSI) and dmDriverExtra;
1635 TCHAR dmFormName[...];
1636 non-split fields;
1637 extra data, of size DEVMODE->dmDriverExtra
1638 */
1639 HGLOBAL hdst = NULL;
1640
1641 if (!dst)
1642 {
1643 hdst = GlobalAlloc (GHND, src->dmSize + src->dmDriverExtra -
1644 (sizeof (DEVMODEW) - sizeof (DEVMODEA)));
1645 dst = (DEVMODEA *) GlobalLock (hdst);
1646 }
1647
1648 memcpy (dst->dmDeviceName, src->dmDeviceName, sizeof (dst->dmDeviceName));
1649 memcpy ((char *) dst + sizeof (dst->dmDeviceName),
1650 (char *) src + sizeof (src->dmDeviceName),
1651 offsetof (DEVMODEA, dmFormName) - sizeof (dst->dmDeviceName));
1652 dst->dmSize -= sizeof (DEVMODEW) - sizeof (DEVMODEA);
1653 memcpy (dst->dmFormName, src->dmFormName, sizeof (dst->dmFormName));
1654 memcpy ((char *) dst + offsetof (DEVMODEA, dmFormName) +
1655 sizeof (dst->dmFormName),
1656 (char *) src + offsetof (DEVMODEW, dmFormName) +
1657 sizeof (src->dmFormName),
1658 dst->dmSize + dst->dmDriverExtra -
1659 (offsetof (DEVMODEA, dmFormName) + sizeof (dst->dmFormName)));
1660
1661 if (hdst)
1662 GlobalUnlock (hdst);
1663 return hdst;
1664 }
1665
1666 static HGLOBAL
1667 copy_devmodea_to_devmodew (const DEVMODEA *src, DEVMODEW *dst)
1668 {
1669 HGLOBAL hdst = NULL;
1670
1671 if (!dst)
1672 {
1673 hdst = GlobalAlloc (GHND, src->dmSize + src->dmDriverExtra +
1674 (sizeof (DEVMODEW) - sizeof (DEVMODEA)));
1675 dst = (DEVMODEW *) GlobalLock (hdst);
1676 }
1677
1678 memcpy (dst->dmDeviceName, src->dmDeviceName, sizeof (src->dmDeviceName));
1679 memcpy ((char *) dst + sizeof (dst->dmDeviceName),
1680 (char *) src + sizeof (src->dmDeviceName),
1681 offsetof (DEVMODEA, dmFormName) - sizeof (src->dmDeviceName));
1682 dst->dmSize += sizeof (DEVMODEW) - sizeof (DEVMODEA);
1683 memcpy (dst->dmFormName, src->dmFormName, sizeof (src->dmFormName));
1684 memcpy ((char *) dst + offsetof (DEVMODEW, dmFormName) +
1685 sizeof (dst->dmFormName),
1686 (char *) src + offsetof (DEVMODEA, dmFormName) +
1687 sizeof (src->dmFormName),
1688 src->dmSize + src->dmDriverExtra -
1689 (offsetof (DEVMODEA, dmFormName) + sizeof (src->dmFormName)));
1690
1691 if (hdst)
1692 GlobalUnlock (hdst);
1693 return hdst;
1694 }
1695
1696 HDC
1697 qxeCreateDC (const Extbyte *lpszDriver, const Extbyte *lpszDevice,
1698 const Extbyte *lpszOutput, CONST DEVMODEW *lpInitData)
1699 {
1700 if (XEUNICODE_P)
1701 return CreateDCW ((LPCWSTR) lpszDriver, (LPCWSTR) lpszDevice,
1702 (LPCWSTR) lpszOutput, lpInitData);
1703 else
1704 {
1705 HGLOBAL hInitData = NULL;
1706 DEVMODEA *lpInitDataa = NULL;
1707 HDC retval;
1708
1709 if (lpInitData)
1710 {
1711 hInitData = copy_devmodew_to_devmodea (lpInitData, NULL);
1712 lpInitDataa = (DEVMODEA *) GlobalLock (hInitData);
1713 }
1714 retval = CreateDCA ((LPCSTR) lpszDriver, (LPCSTR) lpszDevice,
1715 (LPCSTR) lpszOutput, lpInitDataa);
1716
1717 if (hInitData)
1718 {
1719 GlobalUnlock (hInitData);
1720 GlobalFree (hInitData);
1721 }
1722
1723 return retval;
1724 }
1725 }
1726
1727 HDC
1728 qxeResetDC (HDC hdc, CONST DEVMODEW *lpInitData)
1729 {
1730 if (XEUNICODE_P)
1731 return ResetDCW (hdc, lpInitData);
1732 else
1733 {
1734 HGLOBAL hInitData = NULL;
1735 DEVMODEA *lpInitDataa = NULL;
1736 HDC retval;
1737
1738 if (lpInitData)
1739 {
1740 hInitData = copy_devmodew_to_devmodea (lpInitData, NULL);
1741 lpInitDataa = (DEVMODEA *) GlobalLock (hInitData);
1742 }
1743 retval = ResetDCA (hdc, lpInitDataa);
1744
1745 if (hInitData)
1746 {
1747 GlobalUnlock (hInitData);
1748 GlobalFree (hInitData);
1749 }
1750
1751 return retval;
1752 }
1753 }
1754
1755 DWORD
1756 qxeOpenPrinter (Extbyte *pPrinterName, LPHANDLE phPrinter,
1757 LPPRINTER_DEFAULTSW pDefaultconst)
1758 {
1759 assert (!pDefaultconst); /* we don't split it, so let's make sure we
1760 don't try. */
1761 if (XEUNICODE_P)
1762 return OpenPrinterW ((LPWSTR) pPrinterName, phPrinter,
1763 pDefaultconst);
1764 else
1765 return OpenPrinterA ((LPSTR) pPrinterName, phPrinter,
1766 (LPPRINTER_DEFAULTSA) pDefaultconst);
1767 }
1768
1769 LONG
1770 qxeDocumentProperties (HWND hWnd, HANDLE hPrinter, Extbyte *pDeviceName,
1771 DEVMODEW *pDevModeOutput, DEVMODEW *pDevModeInput,
1772 DWORD fMode)
1773 {
1774 if (XEUNICODE_P)
1775 #ifdef CYGWIN_HEADERS
1776 /* Cygwin mistakenly declares the fourth and fifth arguments as
1777 PDEVMODEA. */
1778 return DocumentPropertiesW (hWnd, hPrinter, (LPWSTR) pDeviceName,
1779 (DEVMODEA *) pDevModeOutput,
1780 (DEVMODEA *) pDevModeInput, fMode);
1781 #else
1782 return DocumentPropertiesW (hWnd, hPrinter, (LPWSTR) pDeviceName,
1783 pDevModeOutput, pDevModeInput, fMode);
1784 #endif /* CYGWIN_HEADERS */
1785 else
1786 {
1787 HGLOBAL hDevModeInput = NULL;
1788 DEVMODEA *pDevModeInputa = NULL;
1789 LONG retval;
1790
1791 if (pDevModeInput)
1792 {
1793 hDevModeInput = copy_devmodew_to_devmodea (pDevModeInput, NULL);
1794 pDevModeInputa = (DEVMODEA *) GlobalLock (hDevModeInput);
1795 }
1796
1797 /* Here we cheat a bit to avoid a problem: If the output
1798 structure is given but not the input one, how do we know how
1799 big to allocate our shadow output structure? Since the
1800 shadow structure is ANSI and the original Unicode, we know
1801 the shadow structure is smaller than what's given, so we just
1802 write into the given structure and then fix. */
1803 retval = DocumentPropertiesA (hWnd, hPrinter, (LPSTR) pDeviceName,
1804 pDevModeOutput ?
1805 (DEVMODEA *) pDevModeOutput : 0,
1806 pDevModeInput ? pDevModeInputa : 0,
1807 fMode);
1808
1809 if (hDevModeInput)
1810 {
1811 GlobalUnlock (hDevModeInput);
1812 GlobalFree (hDevModeInput);
1813 }
1814
1815 if (retval >= 0 && pDevModeOutput)
1816 {
1817 /* copy the shadow structure out of the way and then put the
1818 right contents back. */
1819 DEVMODEA *shadow = (DEVMODEA *) pDevModeOutput;
1820 DEVMODEA *newshadow = alloca_array (DEVMODEA, shadow->dmSize +
1821 shadow->dmDriverExtra);
1822
1823 memcpy (newshadow, shadow, shadow->dmSize + shadow->dmDriverExtra);
1824 copy_devmodea_to_devmodew (newshadow, pDevModeOutput);
1825 }
1826
1827 if (fMode == 0)
1828 retval += (sizeof (DEVMODEW) - sizeof (DEVMODEA));
1829 return retval;
1830 }
1831 }
1832
1833 static BOOL
1834 ansi_printer_dialog_1 (void *strucked, HGLOBAL *devmode_inout, int do_PrintDlg)
1835 {
1836 HGLOBAL hdma = NULL;
1837 HGLOBAL hdmw = *devmode_inout;
1838 DEVMODEW *dmw = NULL;
1839 BOOL retval;
1840
1841 if (hdmw != NULL)
1842 {
1843 /* copy to shadow in structure if needed */
1844 dmw = (DEVMODEW *) GlobalLock (hdmw);
1845 hdma = copy_devmodew_to_devmodea (dmw, NULL);
1846 *devmode_inout = hdma;
1847 }
1848
1849 if (do_PrintDlg)
1850 retval = PrintDlgA ((PRINTDLGA *) strucked);
1851 else
1852 retval = PageSetupDlgA ((PAGESETUPDLGA *) strucked);
1853
1854 if (retval)
1855 {
1856 /* copy the shadow output structure back to original, or
1857 allocate new one. */
1858 if (*devmode_inout)
1859 {
1860 DEVMODEA *newdma = (DEVMODEA *) GlobalLock (*devmode_inout);
1861 if (dmw)
1862 {
1863 copy_devmodea_to_devmodew (newdma, dmw);
1864 GlobalUnlock (hdmw);
1865 }
1866 else
1867 hdmw = copy_devmodea_to_devmodew (newdma, NULL);
1868 GlobalUnlock (*devmode_inout);
1869 GlobalFree (*devmode_inout);
1870 *devmode_inout = hdmw;
1871 }
1872 else if (hdma)
1873 /* #### can this happen? */
1874 GlobalFree (hdma);
1875 }
1876
1877 return retval;
1878 }
1879
1880 BOOL
1881 qxePrintDlg (PRINTDLGW *lppd)
1882 {
1883 if (XEUNICODE_P)
1884 return PrintDlgW (lppd);
1885 else
1886 return ansi_printer_dialog_1 (lppd, &lppd->hDevMode, 1);
1887 }
1888
1889 BOOL
1890 qxePageSetupDlg (PAGESETUPDLGW *lppd)
1891 {
1892 if (XEUNICODE_P)
1893 return PageSetupDlgW (lppd);
1894 else
1895 return ansi_printer_dialog_1 (lppd, &lppd->hDevMode, 0);
1896 }
1897
1898
1899 /************************************************************************/
1900 /* fonts */
1901 /************************************************************************/
1902
1903 static void
1904 copy_logfonta_to_logfontw (const LOGFONTA *src, LOGFONTW *dst)
1905 {
1906 /* the layout of LOGFONT is
1907
1908 non-split fields;
1909 TCHAR lfFaceName[...];
1910 */
1911 memcpy (dst, src, sizeof (LOGFONTA));
1912 }
1913
1914 static void
1915 copy_logfontw_to_logfonta (const LOGFONTW *src, LOGFONTA *dst)
1916 {
1917 memcpy (dst, src, sizeof (LOGFONTA));
1918 }
1919
1920 static void
1921 copy_enumlogfonta_to_enumlogfontw (const ENUMLOGFONTA *src, ENUMLOGFONTW *dst)
1922 {
1923 /* the layout of ENUMLOGFONT is
1924
1925 LOGFONT elfLogFont;
1926 TCHAR elfFullName[...];
1927 TCHAR elfStyle[...];
1928 */
1929 xzero (*dst);
1930 copy_logfonta_to_logfontw (&src->elfLogFont, &dst->elfLogFont);
1931 memcpy (dst->elfFullName, src->elfFullName, sizeof (src->elfFullName));
1932 memcpy (dst->elfStyle, src->elfStyle, sizeof (src->elfStyle));
1933 }
1934
1935 static void
1936 copy_enumlogfontexa_to_enumlogfontexw (const ENUMLOGFONTEXA *src,
1937 ENUMLOGFONTEXW *dst)
1938 {
1939 /* the layout of ENUMLOGFONT is
1940
1941 LOGFONT elfLogFont;
1942 TCHAR elfFullName[...];
1943 TCHAR elfStyle[...];
1944 TCHAR elfScript[...];
1945 */
1946 xzero (*dst);
1947 copy_logfonta_to_logfontw (&src->elfLogFont, &dst->elfLogFont);
1948 memcpy (dst->elfFullName, src->elfFullName, sizeof (src->elfFullName));
1949 memcpy (dst->elfStyle, src->elfStyle, sizeof (src->elfStyle));
1950 memcpy (dst->elfScript, src->elfScript, sizeof (src->elfScript));
1951 }
1952
1953 static void
1954 copy_newtextmetrica_to_newtextmetricw (const NEWTEXTMETRICA *src,
1955 NEWTEXTMETRICW *dst)
1956 {
1957 /* the layout of NEWTEXTMETRIC is
1958
1959 non-split fields;
1960 WCHAR/BYTE tmFirstChar;
1961 WCHAR/BYTE tmLastChar;
1962 WCHAR/BYTE tmDefaultChar;
1963 WCHAR/BYTE tmBreakChar;
1964 BYTE tmItalic;
1965 non-split fields;
1966 */
1967 xzero (*dst);
1968 memcpy ((char *) dst, (char *) src,
1969 offsetof (NEWTEXTMETRICA, tmFirstChar));
1970 memcpy ((char *) dst + offsetof (NEWTEXTMETRICW, tmItalic),
1971 (char *) src + offsetof (NEWTEXTMETRICA, tmItalic),
1972 sizeof (NEWTEXTMETRICA) - offsetof (NEWTEXTMETRICA, tmItalic));
1973 dst->tmFirstChar = (WCHAR) src->tmFirstChar;
1974 dst->tmLastChar = (WCHAR) src->tmLastChar;
1975 dst->tmDefaultChar = (WCHAR) src->tmDefaultChar;
1976 dst->tmBreakChar = (WCHAR) src->tmBreakChar;
1977 }
1978
1979 static void
1980 copy_newtextmetricexa_to_newtextmetricexw (const NEWTEXTMETRICEXA *src,
1981 NEWTEXTMETRICEXW *dst)
1982 {
1983 /* the layout of NEWTEXTMETRICEX is
1984
1985 NEWTEXTMETRICA/W ntmTm;
1986 FONTSIGNATURE ntmFontSig;
1987 */
1988 copy_newtextmetrica_to_newtextmetricw (&src->ntmTm, &dst->ntmTm);
1989 dst->ntmFontSig = src->ntmFontSig;
1990 }
1991
1992 static void
1993 copy_textmetricw_to_textmetrica (const TEXTMETRICW *src,
1994 TEXTMETRICA *dst)
1995 {
1996 /* the layout of TEXTMETRIC is like NEWTEXTMETRIC; see above. */
1997 xzero (*dst);
1998 memcpy ((char *) dst, (char *) src,
1999 offsetof (TEXTMETRICA, tmFirstChar));
2000 memcpy ((char *) dst + offsetof (TEXTMETRICA, tmItalic),
2001 (char *) src + offsetof (TEXTMETRICW, tmItalic),
2002 sizeof (TEXTMETRICA) - offsetof (TEXTMETRICA, tmItalic));
2003 dst->tmFirstChar = (BYTE) src->tmFirstChar;
2004 dst->tmLastChar = (BYTE) src->tmLastChar;
2005 dst->tmDefaultChar = (BYTE) src->tmDefaultChar;
2006 dst->tmBreakChar = (BYTE) src->tmBreakChar;
2007 }
2008
2009 static void
2010 copy_textmetrica_to_textmetricw (const TEXTMETRICA *src,
2011 TEXTMETRICW *dst)
2012 {
2013 /* the layout of TEXTMETRIC is like NEWTEXTMETRIC; see above. */
2014 xzero (*dst);
2015 memcpy ((char *) dst, (char *) src,
2016 offsetof (TEXTMETRICA, tmFirstChar));
2017 memcpy ((char *) dst + offsetof (TEXTMETRICW, tmItalic),
2018 (char *) src + offsetof (TEXTMETRICA, tmItalic),
2019 sizeof (TEXTMETRICA) - offsetof (TEXTMETRICA, tmItalic));
2020 dst->tmFirstChar = (WCHAR) src->tmFirstChar;
2021 dst->tmLastChar = (WCHAR) src->tmLastChar;
2022 dst->tmDefaultChar = (WCHAR) src->tmDefaultChar;
2023 dst->tmBreakChar = (WCHAR) src->tmBreakChar;
2024 }
2025
2026 typedef int (CALLBACK *qxeEnumFontFamExProcW) (ENUMLOGFONTEXW *lpelfe,
2027 NEWTEXTMETRICEXW *lpntme,
2028 DWORD FontType,
2029 LPARAM lParam);
2030
2031 struct qxeEnumFontFamExProcA_wrapper_t
2032 {
2033 qxeEnumFontFamExProcW orig_proc;
2034 LPARAM orig_lparam;
2035 };
2036
2037 static int CALLBACK
2038 qxeEnumFontFamExProcA_wrapper (ENUMLOGFONTEXA *lpelfe,
2039 NEWTEXTMETRICEXA *lpntme,
2040 DWORD fontType,
2041 struct qxeEnumFontFamExProcA_wrapper_t
2042 *closure)
2043 {
2044 ENUMLOGFONTEXW lpelfew;
2045 NEWTEXTMETRICEXW lpntmew;
2046
2047 /* #### if we're on Windows 2000 or above, lpelfe is actually an
2048 ENUMLOGFONTEXDV structure, and lpntme is an ENUMTEXTMETRIC structure
2049 when TRUETYPE_FONTTYPE. both are split-sized and need their own copy
2050 functions. need to handle. */
2051 copy_enumlogfontexa_to_enumlogfontexw (lpelfe, &lpelfew);
2052 if (fontType & TRUETYPE_FONTTYPE)
2053 copy_newtextmetricexa_to_newtextmetricexw (lpntme, &lpntmew);
2054 else
2055 {
2056 /* see docs of EnumFontFamExProc */
2057 xzero (lpntmew);
2058 copy_textmetrica_to_textmetricw ((TEXTMETRICA *) lpntme,
2059 (TEXTMETRICW *) &lpntmew);
2060 }
2061 return (closure->orig_proc) (&lpelfew, &lpntmew, fontType,
2062 closure->orig_lparam);
2063 }
2064
2065 int
2066 qxeEnumFontFamiliesEx (HDC hdc, LOGFONTW *lpLogfont,
2067 FONTENUMPROCW lpEnumFontFamProc, LPARAM lParam,
2068 DWORD dwFlags)
2069 {
2070 if (XEUNICODE_P)
2071 return EnumFontFamiliesExW (hdc, lpLogfont, lpEnumFontFamProc, lParam,
2072 dwFlags);
2073 else
2074 {
2075 struct qxeEnumFontFamExProcA_wrapper_t closure;
2076 LOGFONTA lfa;
2077
2078 closure.orig_proc = (qxeEnumFontFamExProcW) lpEnumFontFamProc;
2079 closure.orig_lparam = lParam;
2080 copy_logfontw_to_logfonta (lpLogfont, &lfa);
2081 return EnumFontFamiliesExA (hdc, &lfa,
2082 (FONTENUMPROCA)
2083 qxeEnumFontFamExProcA_wrapper,
2084 (LPARAM) &closure, dwFlags);
2085 }
2086 }
2087
2088 HFONT
2089 qxeCreateFontIndirect (CONST LOGFONTW *lplf)
2090 {
2091 if (XEUNICODE_P)
2092 return CreateFontIndirectW (lplf);
2093 else
2094 {
2095 LOGFONTA lfa;
2096
2097 copy_logfontw_to_logfonta (lplf, &lfa);
2098 return CreateFontIndirectA (&lfa);
2099 }
2100 }
2101
2102 BOOL
2103 qxeImmSetCompositionFont (HIMC imc, LOGFONTW *lplf)
2104 {
2105 if (XEUNICODE_P)
2106 return ImmSetCompositionFontW (imc, lplf);
2107 else
2108 {
2109 LOGFONTA lfa;
2110
2111 copy_logfontw_to_logfonta (lplf, &lfa);
2112 return ImmSetCompositionFontA (imc, &lfa);
2113 }
2114 }
2115
2116 BOOL
2117 qxeImmGetCompositionFont (HIMC imc, LOGFONTW *lplf)
2118 {
2119 if (XEUNICODE_P)
2120 return ImmGetCompositionFontW (imc, lplf);
2121 else
2122 {
2123 LOGFONTA lfa;
2124 BOOL retval = ImmGetCompositionFontA (imc, &lfa);
2125
2126 if (retval)
2127 copy_logfonta_to_logfontw (&lfa, lplf);
2128 return retval;
2129 }
2130 }
2131
2132 int
2133 qxeGetObject (HGDIOBJ hgdiobj, int cbBuffer, LPVOID lpvObject)
2134 {
2135 if (XEUNICODE_P)
2136 return GetObjectW (hgdiobj, cbBuffer, lpvObject);
2137 else
2138 {
2139 if (cbBuffer == sizeof (LOGFONTW))
2140 {
2141 LOGFONTA lfa;
2142 int retval = GetObjectA (hgdiobj, sizeof (LOGFONTA), &lfa);
2143
2144 if (!retval)
2145 return retval;
2146 copy_logfonta_to_logfontw (&lfa, (LOGFONTW *) lpvObject);
2147 return retval;
2148 }
2149 else
2150 return GetObjectA (hgdiobj, cbBuffer, lpvObject);
2151 }
2152 }
2153
2154 BOOL
2155 qxeGetTextMetrics (HDC hdc, LPTEXTMETRICW lptm)
2156 {
2157 if (XEUNICODE_P)
2158 return GetTextMetricsW (hdc, lptm);
2159 else
2160 {
2161 TEXTMETRICA tma;
2162 BOOL retval = GetTextMetricsA (hdc, &tma);
2163
2164 if (retval)
2165 copy_textmetrica_to_textmetricw (&tma, lptm);
2166 return retval;
2167 }
2168 }
2169
2170
2171 /************************************************************************/
2172 /* windows */
2173 /************************************************************************/
2174
2175 typedef struct Intercepted_wnd_proc
2176 {
2177 WNDPROC proc;
2178 Extbyte *name;
2179 int is_ansi;
2180 } Intercepted_wnd_proc;
2181
2182 typedef struct
2183 {
2184 Dynarr_declare (Intercepted_wnd_proc);
2185 } Intercepted_wnd_proc_dynarr;
2186
2187 static Intercepted_wnd_proc_dynarr *intercepted_wnd_procs;
2188
2189 static Intercepted_wnd_proc *
2190 find_window_class (const Extbyte *name, int is_ansi)
2191 {
2192 int i;
2193
2194 if (!intercepted_wnd_procs)
2195 intercepted_wnd_procs = Dynarr_new (Intercepted_wnd_proc);
2196
2197 for (i = 0; i < Dynarr_length (intercepted_wnd_procs); i++)
2198 {
2199 Intercepted_wnd_proc *s = Dynarr_atp (intercepted_wnd_procs, i);
2200
2201 if (s->is_ansi == is_ansi && (is_ansi ? !strcmp (s->name, name) :
2202 !wcscmp ((wchar_t *) s->name,
2203 (wchar_t *) name)))
2204 return s;
2205 }
2206
2207 return 0;
2208 }
2209
2210 /* ####
2211
2212 check problem with cutting and pasting in my current mule -- if i cut,
2213 then go to another application, then switch back to this one and
2214 paste, it seems to get confused -- loses the size or something?
2215
2216 other things: split flags on CreateProcess and DDE stuff should be
2217 handled by us.
2218 */
2219
2220 static LRESULT WINAPI
2221 intercepted_wnd_proc (HWND hwnd, UINT message_, WPARAM wParam, LPARAM lParam)
2222 {
2223 Intercepted_wnd_proc *s;
2224 int is_ansi = XEUNICODE_P ? !IsWindowUnicode (hwnd) : 1;
2225 Extbyte *classname;
2226 int size = 100;
2227
2228 /* Just in case XEUNICODE_P changes during the execution of the program
2229 (admittedly, unlikely), check whether the window is Unicode and keep
2230 track of this in the list of classes. */
2231 while (1)
2232 {
2233 classname = alloca_extbytes (size * XETCHAR_SIZE);
2234 if ((is_ansi ? GetClassNameA (hwnd, (LPSTR) classname, size) :
2235 GetClassNameW (hwnd, (LPWSTR) classname, size)) < size - 1)
2236 break;
2237 size *= 2;
2238 }
2239
2240 s = find_window_class (classname, is_ansi);
2241
2242 assert (s);
2243
2244 if (message_ == WM_NOTIFY)
2245 {
2246 LPNMHDR nmhdr = (LPNMHDR) lParam;
2247 int putback = nmhdr->code;
2248 int do_putback = 0;
2249
2250 #define FROB(msg) \
2251 case msg##W: \
2252 /* split structures are the same size, so no conversion necessary */ \
2253 nmhdr->code = (UINT) msg##A; \
2254 do_putback = 1; \
2255 break;
2256 switch (nmhdr->code)
2257 {
2258 /* NMHEADER */
2259 FROB (HDN_ITEMCHANGING);
2260 FROB (HDN_ITEMCHANGED);
2261 FROB (HDN_ITEMCLICK);
2262 FROB (HDN_ITEMDBLCLICK);
2263 FROB (HDN_DIVIDERDBLCLICK);
2264 FROB (HDN_BEGINTRACK);
2265 FROB (HDN_ENDTRACK);
2266 FROB (HDN_TRACK);
2267 /* NMDISPINFO */
2268 FROB (HDN_GETDISPINFO);
2269 /* NMTBGETINFOTIP */
2270 FROB (TBN_GETINFOTIP);
2271 /* NMTBDISPINFO */
2272 FROB (TBN_GETDISPINFO);
2273 /* NMTOOLBAR */
2274 FROB (TBN_GETBUTTONINFO);
2275
2276 /* split-sized NMTTDISPINFO */
2277 FROB (TTN_GETDISPINFO); /* handle the ...W case; then handle the
2278 ...A case specially, since we need to
2279 mess with the structure */
2280 case TTN_GETDISPINFOA: /* same as TTN_NEEDTEXTA */
2281 {
2282 NMTTDISPINFOW *nmw = alloca_new (NMTTDISPINFOW);
2283 NMTTDISPINFOA *nma = (NMTTDISPINFOA *) lParam;
2284 LRESULT retval;
2285 /* the layout of NMTTDISPINFO is
2286
2287 non-split fields;
2288 TCHAR szText[...];
2289 non-split fields;
2290 */
2291
2292 xzero (*nmw);
2293 /* copy to ...W struct for Unicode code */
2294 memcpy ((char *) nmw, (char *) nma,
2295 offsetof (NMTTDISPINFOA, szText));
2296 memcpy ((char *) nmw + offsetof (NMTTDISPINFOW, szText) +
2297 sizeof (nmw->szText),
2298 (char *) nma + offsetof (NMTTDISPINFOA, szText) +
2299 sizeof (nma->szText),
2300 sizeof (NMTTDISPINFOA) -
2301 (offsetof (NMTTDISPINFOA, szText) + sizeof (nma->szText)));
2302 memcpy (nmw->szText, nma->szText, sizeof (nma->szText));
2303 retval = (s->proc) (hwnd, message_, wParam, lParam);
2304 /* copy back to ...A struct */
2305 xzero (*nma);
2306 memcpy ((char *) nma, (char *) nmw,
2307 offsetof (NMTTDISPINFOA, szText));
2308 memcpy ((char *) nma + offsetof (NMTTDISPINFOA, szText) +
2309 sizeof (nma->szText),
2310 (char *) nmw + offsetof (NMTTDISPINFOW, szText) +
2311 sizeof (nmw->szText),
2312 sizeof (NMTTDISPINFOA) -
2313 (offsetof (NMTTDISPINFOA, szText) + sizeof (nma->szText)));
2314 memcpy (nma->szText, nmw->szText, sizeof (nma->szText));
2315 return retval;
2316 }
2317
2318 /* NMLVFINDITEM */
2319 FROB (LVN_ODFINDITEM);
2320 /* NMLVDISPINFO */
2321 FROB (LVN_BEGINLABELEDIT);
2322 FROB (LVN_ENDLABELEDIT);
2323 FROB (LVN_GETDISPINFO);
2324 FROB (LVN_SETDISPINFO);
2325 /* NMLVGETINFOTIP */
2326 FROB (LVN_GETINFOTIP);
2327 /* NMTREEVIEW */
2328 FROB (TVN_SELCHANGING);
2329 FROB (TVN_SELCHANGED);
2330 FROB (TVN_ITEMEXPANDING);
2331 FROB (TVN_ITEMEXPANDED);
2332 FROB (TVN_BEGINDRAG);
2333 FROB (TVN_BEGINRDRAG);
2334 FROB (TVN_DELETEITEM);
2335 /* NMTVDISPINFO */
2336 FROB (TVN_GETDISPINFO);
2337 FROB (TVN_SETDISPINFO);
2338 FROB (TVN_BEGINLABELEDIT);
2339 FROB (TVN_ENDLABELEDIT);
2340 /* NMTVGETINFOTIP */
2341 FROB (TVN_GETINFOTIP);
2342 /* NMCOMBOBOXEX */
2343 FROB (CBEN_GETDISPINFO);
2344
2345 /* split-sized NMCBEDRAGBEGIN */
2346 FROB (CBEN_DRAGBEGIN); /* handle the ...W case; then handle the
2347 ...A case specially, since we need to
2348 mess with the structure */
2349 {
2350 NMCBEDRAGBEGINW *nmw = alloca_new (NMCBEDRAGBEGINW);
2351 NMCBEDRAGBEGINA *nma = (NMCBEDRAGBEGINA *) lParam;
2352 LRESULT retval;
2353 /* the layout of NNMCBEDRAGBEGIN is
2354
2355 non-split fields;
2356 TCHAR szText[...];
2357 */
2358
2359 xzero (*nmw);
2360 /* copy to ...W struct for Unicode code */
2361 memcpy ((char *) nmw, (char *) nma,
2362 sizeof (*nma));
2363 retval = (s->proc) (hwnd, message_, wParam, lParam);
2364 /* copy back to ...A struct */
2365 xzero (*nma);
2366 memcpy ((char *) nma, (char *) nmw,
2367 sizeof (*nma));
2368 return retval;
2369 }
2370
2371 /* split-sized NMCBEENDEDIT */
2372 FROB (CBEN_ENDEDIT); /* handle the ...W case; then handle the
2373 ...A case specially, since we need to
2374 mess with the structure */
2375 {
2376 NMCBEENDEDITW *nmw = alloca_new (NMCBEENDEDITW);
2377 NMCBEENDEDITA *nma = (NMCBEENDEDITA *) lParam;
2378 LRESULT retval;
2379 /* the layout of NMCBEENDEDIT is
2380
2381 non-split fields;
2382 TCHAR szText[...];
2383 non-split fields;
2384 */
2385
2386 xzero (*nmw);
2387 /* copy to ...W struct for Unicode code */
2388 memcpy ((char *) nmw, (char *) nma,
2389 offsetof (NMCBEENDEDITA, szText));
2390 memcpy ((char *) nmw + offsetof (NMCBEENDEDITW, szText) +
2391 sizeof (nmw->szText),
2392 (char *) nma + offsetof (NMCBEENDEDITA, szText) +
2393 sizeof (nma->szText),
2394 sizeof (NMCBEENDEDITA) -
2395 (offsetof (NMCBEENDEDITA, szText) + sizeof (nma->szText)));
2396 memcpy (nmw->szText, nma->szText, sizeof (nma->szText));
2397 retval = (s->proc) (hwnd, message_, wParam, lParam);
2398 /* copy back to ...A struct */
2399 xzero (*nma);
2400 memcpy ((char *) nma, (char *) nmw,
2401 offsetof (NMCBEENDEDITA, szText));
2402 memcpy ((char *) nma + offsetof (NMCBEENDEDITA, szText) +
2403 sizeof (nma->szText),
2404 (char *) nmw + offsetof (NMCBEENDEDITW, szText) +
2405 sizeof (nmw->szText),
2406 sizeof (NMCBEENDEDITA) -
2407 (offsetof (NMCBEENDEDITA, szText) + sizeof (nma->szText)));
2408 memcpy (nma->szText, nmw->szText, sizeof (nma->szText));
2409 return retval;
2410 }
2411
2412 /* NMDATETIMESTRING */
2413 FROB (DTN_USERSTRING);
2414 /* NMDATETIMEWMKEYDOWN */
2415 FROB (DTN_WMKEYDOWN);
2416
2417 /* split-sized NMDATETIMEFORMAT */
2418 FROB (DTN_FORMAT); /* handle the ...W case; then handle the
2419 ...A case specially, since we need to
2420 mess with the structure */
2421 {
2422 NMDATETIMEFORMATW *nmw = alloca_new (NMDATETIMEFORMATW);
2423 NMDATETIMEFORMATA *nma = (NMDATETIMEFORMATA *) lParam;
2424 LRESULT retval;
2425 /* the layout of NMDATETIMEFORMAT is
2426
2427 non-split fields;
2428 TCHAR szText[...];
2429 */
2430
2431 xzero (*nmw);
2432 /* copy to ...W struct for Unicode code */
2433 memcpy ((char *) nmw, (char *) nma,
2434 sizeof (*nma));
2435 retval = (s->proc) (hwnd, message_, wParam, lParam);
2436 /* copy back to ...A struct */
2437 xzero (*nma);
2438 memcpy ((char *) nma, (char *) nmw,
2439 sizeof (*nma));
2440 return retval;
2441 }
2442
2443 /* NMDATETIMEFORMATQUERY */
2444 FROB (DTN_FORMATQUERY);
2445 default: break;
2446 }
2447 #undef FROB
2448 if (do_putback)
2449 {
2450 LRESULT retval = (s->proc) (hwnd, message_, wParam, lParam);
2451 ((LPNMHDR) lParam)->code = putback;
2452 return retval;
2453 }
2454 }
2455
2456 return (s->proc) (hwnd, message_, wParam, lParam);
2457 }
2458
2459 ATOM
2460 qxeRegisterClass (CONST WNDCLASSW * lpWndClass)
2461 {
2462 Intercepted_wnd_proc *s =
2463 find_window_class ((Extbyte *) lpWndClass->lpszClassName, !XEUNICODE_P);
2464 WNDCLASSW classnew;
2465
2466 if (s)
2467 {
2468 s->proc = lpWndClass->lpfnWndProc;
2469 s->name = (Extbyte *) lpWndClass->lpszClassName;
2470 s->is_ansi = !XEUNICODE_P;
2471 }
2472 else
2473 {
2474 Intercepted_wnd_proc news;
2475 news.proc = lpWndClass->lpfnWndProc;
2476 news.name = (Extbyte *) lpWndClass->lpszClassName;
2477 news.is_ansi = !XEUNICODE_P;
2478 Dynarr_add (intercepted_wnd_procs, news);
2479 }
2480 classnew = *lpWndClass;
2481 classnew.lpfnWndProc = intercepted_wnd_proc;
2482 if (XEUNICODE_P)
2483 return RegisterClassW (&classnew);
2484 else
2485 return RegisterClassA ((CONST WNDCLASSA *) &classnew);
2486 }
2487
2488 BOOL
2489 qxeUnregisterClass (const Extbyte * lpClassName, HINSTANCE hInstance)
2490 {
2491 Intercepted_wnd_proc *s =
2492 find_window_class (lpClassName, !XEUNICODE_P);
2493
2494 if (s)
2495 Dynarr_delete_by_pointer (intercepted_wnd_procs, s);
2496 if (XEUNICODE_P)
2497 return UnregisterClassW ((LPCWSTR) lpClassName, hInstance);
2498 else
2499 return UnregisterClassA ((LPCSTR) lpClassName, hInstance);
2500 }
2501
2502 /* NOTE: NT 4.0+ only */
2503 ATOM
2504 qxeRegisterClassEx (CONST WNDCLASSEXW *lpWndClass)
2505 {
2506 Intercepted_wnd_proc *s =
2507 find_window_class ((Extbyte *) lpWndClass->lpszClassName, !XEUNICODE_P);
2508 WNDCLASSEXW classnew;
2509
2510 if (s)
2511 {
2512 s->proc = lpWndClass->lpfnWndProc;
2513 s->name = (Extbyte *) lpWndClass->lpszClassName;
2514 s->is_ansi = !XEUNICODE_P;
2515 }
2516 else
2517 {
2518 Intercepted_wnd_proc news;
2519 news.proc = lpWndClass->lpfnWndProc;
2520 news.name = (Extbyte *) lpWndClass->lpszClassName;
2521 news.is_ansi = !XEUNICODE_P;
2522 Dynarr_add (intercepted_wnd_procs, news);
2523 }
2524 classnew = *lpWndClass;
2525 classnew.lpfnWndProc = intercepted_wnd_proc;
2526 if (XEUNICODE_P)
2527 return RegisterClassExW (&classnew);
2528 else
2529 return RegisterClassExA ((CONST WNDCLASSEXA *) &classnew);
2530 }
2531
2532
2533 /************************************************************************/
2534 /* COMMCTRL.H */
2535 /************************************************************************/
2536
2537 /* there are only four structures in commctrl.h that cannot be cast
2538 between Unicode/ANSI versions:
2539
2540 NMTTDISPINFO aka TOOLTIPTEXT
2541 NMCBEDRAGBEGIN
2542 NMCBEENDEDIT
2543 NMDATETIMEFORMAT
2544
2545 these are all notify structures, and we handle them above in
2546 intercepted_wnd_proc().
2547
2548 in addition, this constant is weird, being a struct size of one of these:
2549
2550 NMTTDISPINFO_V1_SIZE
2551 */
2552
2553 /*
2554 split class names:
2555
2556 WC_HEADER
2557 TOOLBARCLASSNAME
2558 REBARCLASSNAME
2559 TOOLTIPS_CLASS
2560 STATUSCLASSNAME
2561 TRACKBAR_CLASS
2562 UPDOWN_CLASS
2563 PROGRESS_CLASS
2564 HOTKEY_CLASS
2565 WC_LISTVIEW
2566 WC_TREEVIEW
2567 WC_COMBOBOXEX
2568 WC_TABCONTROL
2569 ANIMATE_CLASS
2570 MONTHCAL_CLASS
2571 DATETIMEPICK_CLASS
2572 WC_IPADDRESS
2573 WC_PAGESCROLLER
2574 WC_NATIVEFONTCTL
2575 */
2576
2577 /*
2578 SendMessage split messages:
2579
2580 HDM_INSERTITEM
2581 HDM_GETITEM
2582 HDM_SETITEM
2583 TB_GETBUTTONTEXT
2584 TB_SAVERESTORE
2585 TB_ADDSTRING
2586 TB_GETBUTTONINFO
2587 TB_SETBUTTONINFO
2588 TB_INSERTBUTTON
2589 TB_ADDBUTTONS
2590 RB_INSERTBAND
2591 RB_SETBANDINFO
2592 RB_GETBANDINFO
2593 TTM_ADDTOOL
2594 TTM_DELTOOL
2595 TTM_NEWTOOLRECT
2596 TTM_GETTOOLINFO
2597 TTM_SETTOOLINFO
2598 TTM_HITTEST
2599 TTM_GETTEXT
2600 TTM_UPDATETIPTEXT
2601 TTM_ENUMTOOLS
2602 TTM_GETCURRENTTOOL
2603 SB_GETTEXT
2604 SB_SETTEXT
2605 SB_GETTEXTLENGTH
2606 SB_SETTIPTEXT
2607 SB_GETTIPTEXT
2608 LVM_GETITEM
2609 LVM_SETITEM
2610 LVM_INSERTITEM
2611 LVM_FINDITEM
2612 LVM_GETSTRINGWIDTH
2613 LVM_EDITLABEL
2614 LVM_GETCOLUMN
2615 LVM_SETCOLUMN
2616 LVM_GETITEMTEXT
2617 LVM_SETITEMTEXT
2618 LVM_GETISEARCHSTRING
2619 LVM_SETBKIMAGE
2620 LVM_GETBKIMAGE
2621 TVM_INSERTITEM
2622 TVM_GETITEM
2623 TVM_SETITEM
2624 TVM_EDITLABEL
2625 TVM_GETISEARCHSTRING
2626 CBEM_INSERTITEM
2627 CBEM_SETITEM
2628 CBEM_GETITEM
2629 TCM_GETITEM
2630 TCM_SETITEM
2631 TCM_INSERTITEM
2632 ACM_OPEN
2633 DTM_SETFORMAT
2634 BFFM_SETSTATUSTEXT
2635 BFFM_SETSELECTION
2636 */
2637
2638 /*
2639 split notify messages:
2640
2641 HDN_ITEMCHANGING
2642 HDN_ITEMCHANGED
2643 HDN_ITEMCLICK
2644 HDN_ITEMDBLCLICK
2645 HDN_DIVIDERDBLCLICK
2646 HDN_BEGINTRACK
2647 HDN_ENDTRACK
2648 HDN_TRACK
2649 HDN_GETDISPINFO
2650 TBN_GETINFOTIP
2651 TBN_GETDISPINFO
2652 TBN_GETBUTTONINFO
2653 TTN_GETDISPINFO
2654 TTN_NEEDTEXTW
2655 LVN_ODFINDITEM
2656 LVN_BEGINLABELEDIT
2657 LVN_ENDLABELEDIT
2658 LVN_GETDISPINFO
2659 LVN_SETDISPINFO
2660 LVN_GETINFOTIP
2661 TVN_SELCHANGING
2662 TVN_SELCHANGED
2663 TVN_GETDISPINFO
2664 TVN_SETDISPINFO
2665 TVN_ITEMEXPANDING
2666 TVN_ITEMEXPANDED
2667 TVN_BEGINDRAG
2668 TVN_BEGINRDRAG
2669 TVN_DELETEITEM
2670 TVN_BEGINLABELEDIT
2671 TVN_ENDLABELEDIT
2672 TVN_GETINFOTIP
2673 CBEN_GETDISPINFO
2674 CBEN_DRAGBEGIN
2675 CBEN_ENDEDIT
2676 DTN_USERSTRING
2677 DTN_WMKEYDOWN
2678 DTN_FORMAT
2679 DTN_FORMATQUERY
2680 BFFM_VALIDATEFAILED (send to SHBrowseForFolder procedure)
2681 */
2682
2683 /*
2684 split structures:
2685
2686 TV_INSERTSTRUCT (simple-split, though -- just cast)
2687 TC_ITEM (simple-split, though -- just cast)
2688
2689 ####
2690 */
2691
2692 /*
2693 split macros or macros needing splitting:
2694
2695 ####
2696 */
2697
2698 LRESULT
2699 qxeSendMessage (HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
2700 {
2701 #define FROB(msg) \
2702 case msg##A: \
2703 /* split structures are the same size, so no conversion necessary */ \
2704 Msg = msg##W; \
2705 break;
2706
2707 if (XEUNICODE_P)
2708 {
2709 WCHAR classname[100];
2710 /* the name for SHBrowseForFolder windows is non-obvious so we have
2711 to intercept the callback */
2712 if (is_SHBrowseForFolder (hWnd))
2713 {
2714 switch (Msg)
2715 {
2716 FROB (BFFM_SETSELECTION);
2717 FROB (BFFM_SETSTATUSTEXT);
2718 default: break;
2719 }
2720 }
2721 else if (!GetClassNameW (hWnd, classname, 100))
2722 ;
2723 /* luckily, subclassing leaves the name alone, so we can still
2724 determine fairly easily the correct class to switch on */
2725 else if (!wcscmp (classname, WC_HEADERW))
2726 {
2727 switch (Msg)
2728 {
2729 FROB (HDM_INSERTITEM);
2730 FROB (HDM_GETITEM);
2731 FROB (HDM_SETITEM);
2732 default: break;
2733 }
2734 }
2735 else if (!wcscmp (classname, TOOLBARCLASSNAMEW))
2736 {
2737 switch (Msg)
2738 {
2739 FROB (TB_GETBUTTONTEXT);
2740 FROB (TB_SAVERESTORE);
2741 FROB (TB_ADDSTRING);
2742 FROB (TB_GETBUTTONINFO);
2743 FROB (TB_SETBUTTONINFO);
2744 FROB (TB_INSERTBUTTON);
2745 FROB (TB_ADDBUTTONS);
2746 default: break;
2747 }
2748 }
2749 else if (!wcscmp (classname, REBARCLASSNAMEW))
2750 {
2751 switch (Msg)
2752 {
2753 FROB (RB_INSERTBAND);
2754 FROB (RB_SETBANDINFO);
2755 FROB (RB_GETBANDINFO);
2756 default: break;
2757 }
2758 }
2759 else if (!wcscmp (classname, TOOLTIPS_CLASSW))
2760 {
2761 switch (Msg)
2762 {
2763 FROB (TTM_ADDTOOL);
2764 FROB (TTM_DELTOOL);
2765 FROB (TTM_NEWTOOLRECT);
2766 FROB (TTM_GETTOOLINFO);
2767 FROB (TTM_SETTOOLINFO);
2768 FROB (TTM_HITTEST);
2769 FROB (TTM_GETTEXT);
2770 FROB (TTM_UPDATETIPTEXT);
2771 FROB (TTM_ENUMTOOLS);
2772 FROB (TTM_GETCURRENTTOOL);
2773 default: break;
2774 }
2775 }
2776 else if (!wcscmp (classname, STATUSCLASSNAMEW))
2777 {
2778 switch (Msg)
2779 {
2780 FROB (SB_GETTEXT);
2781 FROB (SB_SETTEXT);
2782 FROB (SB_GETTEXTLENGTH);
2783 FROB (SB_SETTIPTEXT);
2784 FROB (SB_GETTIPTEXT);
2785 default: break;
2786 }
2787 }
2788 else if (!wcscmp (classname, WC_LISTVIEWW))
2789 {
2790 switch (Msg)
2791 {
2792 FROB (LVM_GETITEM);
2793 FROB (LVM_SETITEM);
2794 FROB (LVM_INSERTITEM);
2795 FROB (LVM_FINDITEM);
2796 FROB (LVM_GETSTRINGWIDTH);
2797 FROB (LVM_EDITLABEL);
2798 FROB (LVM_GETCOLUMN);
2799 FROB (LVM_SETCOLUMN);
2800 FROB (LVM_GETITEMTEXT);
2801 FROB (LVM_SETITEMTEXT);
2802 FROB (LVM_GETISEARCHSTRING);
2803 FROB (LVM_SETBKIMAGE);
2804 FROB (LVM_GETBKIMAGE);
2805 default: break;
2806 }
2807 }
2808 else if (!wcscmp (classname, WC_TREEVIEWW))
2809 {
2810 switch (Msg)
2811 {
2812 FROB (TVM_INSERTITEM); /* no need to split TV_INSERTSTRUCT */
2813 FROB (TVM_GETITEM);
2814 FROB (TVM_SETITEM);
2815 FROB (TVM_EDITLABEL);
2816 FROB (TVM_GETISEARCHSTRING);
2817 default: break;
2818 }
2819 }
2820 else if (!wcscmp (classname, WC_COMBOBOXEXW))
2821 {
2822 switch (Msg)
2823 {
2824 FROB (CBEM_INSERTITEM);
2825 FROB (CBEM_SETITEM);
2826 FROB (CBEM_GETITEM);
2827 default: break;
2828 }
2829 }
2830 else if (!wcscmp (classname, WC_TABCONTROLW))
2831 {
2832 switch (Msg)
2833 {
2834 FROB (TCM_GETITEM);
2835 FROB (TCM_SETITEM);
2836 FROB (TCM_INSERTITEM); /* no need to split TC_ITEM */
2837 default: break;
2838 }
2839 }
2840 else if (!wcscmp (classname, ANIMATE_CLASSW))
2841 {
2842 switch (Msg)
2843 {
2844 FROB (ACM_OPEN);
2845 default: break;
2846 }
2847 }
2848 else if (!wcscmp (classname, DATETIMEPICK_CLASSW))
2849 {
2850 switch (Msg)
2851 {
2852 FROB (DTM_SETFORMAT);
2853 default: break;
2854 }
2855 }
2856 }
2857
2858 if (XEUNICODE_P)
2859 return SendMessageW (hWnd, Msg, wParam, lParam);
2860 else
2861 return SendMessageA (hWnd, Msg, wParam, lParam);
2862
2863 #undef FROB
2864 }
2865
2866 #endif /* HAVE_MS_WINDOWS */
2867
2868