Compare commits

...

526 Commits

Author SHA1 Message Date
Aleksey Bragin
8d09a004ab [ARWINSS]
- Reduce patch to trunk by 1Kb by removing unnecessary debug prints and other misc stuff.

svn path=/branches/arwinss/; revision=70346
2015-12-14 12:14:01 +00:00
Aleksey Bragin
d5b00851ef [ARWINSS]
- Implement logon process registration in win32k and its shutdown notification.
- Add a hack into server/queue.c which allows to send message to a thread without the desktop. Once the dektop issue is properly solved, this hack should go away.
- Arwinss boots to the desktop now.
- Remove redundant csr_shared.h, and use trunk's ntuser.h instead.

svn path=/branches/arwinss/; revision=70345
2015-12-14 12:10:40 +00:00
Aleksey Bragin
0b6cd57f4c [WIN32K]
- Add (yet another) shutdown.c file, and import trunk's shutdown code there. Key parts are turned off now.
- Enable respective parts in the NtUserSetInformationThread.
- Include undocuser.h

svn path=/branches/arwinss/; revision=70343
2015-12-13 23:16:41 +00:00
Aleksey Bragin
ed047f5dfd [ARWINSS]
- Update patch for trunk. Size--;
- Thanks to Konstantin Shkil for spotting and fixing that dhcpsvc.dll overlap!

svn path=/branches/arwinss/; revision=70342
2015-12-13 22:31:27 +00:00
Aleksey Bragin
27516771f7 [WIN32K]
- Add NtUserSetInformationThread stub, thanks to Konstantin Shkil.
The general direction is that it's fine to add syscalls to Arwinss' win32k which are called by other components like usersrv/consrv, as the list is quite small really, and NtUserInitialize is already there.

svn path=/branches/arwinss/; revision=70341
2015-12-13 22:29:04 +00:00
Aleksey Bragin
3ec85127f2 Update trunk's patch wrt recent commit. It starts to get smaller in size, finally.
svn path=/branches/arwinss/; revision=69875
2015-11-10 23:21:30 +00:00
Aleksey Bragin
cc1122b0e1 - Hack away two biggest Arwinss bugs:
* Bug #1 in msgina: GUIDisplayStatusMessage hang.
 * Bug #2 in user32: Failed to create desktop window, by forcing desktop window creation.
Annoying debug messages are present.
- Move input thread from win32csr.dll to user32's inputros.c. The trick is to export NtUserCallOneParam from user32, which is called by usersrv to start the threads. (c) Pigglesworth.
- Arwinss now boots again.
- Shutdown is not implemented yet.

svn path=/branches/arwinss/; revision=69874
2015-11-10 23:12:42 +00:00
Aleksey Bragin
c3a1464b62 [ARWINSS]
- Change base addresses so that user32, gdi32 and kernel32 don't get relocated.

svn path=/branches/arwinss/; revision=69809
2015-11-03 22:31:23 +00:00
Aleksey Bragin
c86b2c24e8 [ARWINSS]
- win32k: Properly check for the right USER version in NtUserInitialize. Now Arwinss doesn't stop loading so early in the boot process.

svn path=/branches/arwinss/; revision=69804
2015-11-03 21:51:31 +00:00
Aleksey Bragin
6dfde613b2 [ARWINSS]
- gdi32: Use FreeType inclusion macros.

svn path=/branches/arwinss/; revision=69802
2015-11-03 21:29:58 +00:00
Aleksey Bragin
cefeebd8f0 [ARWINSS]
- Move the patch file to the right place. Patch size increased to 19Kb.

svn path=/branches/arwinss/; revision=69530
2015-10-14 20:29:45 +00:00
Aleksey Bragin
495478dc66 [ARWINSS]
- Add latest version of patch to trunk. It contains all the ugly hacks and whatever is needed to make Arwinss "work" in trunk.

svn path=/branches/arwinss/; revision=69529
2015-10-14 19:46:24 +00:00
Aleksey Bragin
6e382d3f0c [ARWINSS]
- Fix win32k build.

svn path=/branches/arwinss/; revision=69527
2015-10-14 19:14:56 +00:00
Aleksey Bragin
93b9443cfe [ARWINSS]
- Fix winent.drv compiling.

svn path=/branches/arwinss/; revision=69526
2015-10-14 12:04:19 +00:00
Aleksey Bragin
aa7af460b4 [ARWINSS]
- Use Wine's winternl.h instead of PSDK's one (same to what was done to gdi32)
- Introduce a csr_shared.h which defines structs used for CSR communication.
- Slightly fix user32/csr.c ExitWindowsEx code.

svn path=/branches/arwinss/; revision=69525
2015-10-14 11:56:49 +00:00
Aleksey Bragin
b94a7e2443 [ARWINSS]
- Use proper winternl.h header from Wine.
- metafile.c: No need to save font from the DC as it's not necessary to restore it (see recent Wine src code).
- freetype.c: Comment out unused variable.

svn path=/branches/arwinss/; revision=69524
2015-10-14 11:27:08 +00:00
Aleksey Bragin
c3c01b2542 [ARWINSS]
- Update freetype CMakeLists.txt file according to r69124.

svn path=/branches/arwinss/; revision=69520
2015-10-13 12:05:13 +00:00
Aleksey Bragin
a5e65cd387 [ARWINSS]
- Bring missing GDI Object Manager defines into gdiobj.c.
- Add missing ime.h include into win32k.h

svn path=/branches/arwinss/; revision=66740
2015-03-16 17:09:59 +00:00
Aleksey Bragin
ef02ab3930 [ARWINSS]
- Fix SetLogonNotify and SetWindowStationUser stubs.

svn path=/branches/arwinss/; revision=66739
2015-03-16 17:08:44 +00:00
Aleksey Bragin
ece9a119f4 [ARWINSS]
- Fix win32k compilation. Now Arwinss compiles in trunk again! \o/

svn path=/branches/arwinss/; revision=64717
2014-10-13 11:46:01 +00:00
Aleksey Bragin
dacf595d8c [ARWINSS]
- Stubplement some gdi32 OpenGL functions, imported by opengl.dll.
- Get rid of NONAMELESSUNION in exticon.c. I'm tired of changing those u2.s2 every time they change.

svn path=/branches/arwinss/; revision=64715
2014-10-13 11:10:06 +00:00
Aleksey Bragin
3b60a34aa3 [ARWINSS]
- Add missing EndTask() implementation.

svn path=/branches/arwinss/; revision=64709
2014-10-13 10:27:27 +00:00
Aleksey Bragin
bbeeb44324 [ARWINSS]
- Properly declare with FORCEINLINE (see r63152 by Pierre).

svn path=/branches/arwinss/; revision=64708
2014-10-13 10:24:08 +00:00
Aleksey Bragin
d4e63bd9ea [ARWINSS]
- Comment out broken precompiled header directives.

svn path=/branches/arwinss/; revision=64707
2014-10-13 10:19:18 +00:00
Aleksey Bragin
ffe31a6267 [WIN32K]
- Indeed Win32kProcessCallout may be called for a process with an already created Win32 Process Info. Handle it like in trunk. Found and fixed by Kamil Hornicek.

svn path=/branches/arwinss/; revision=62970
2014-04-25 21:36:32 +00:00
Aleksey Bragin
87ad959a45 [USER32]
- Make a proper stub for RegisterUserApiHook(), as it's actually being called.

svn path=/branches/arwinss/; revision=62969
2014-04-25 21:28:22 +00:00
Aleksey Bragin
0fbc1e1272 [ARWINSS]
- Properly set and reset Win32 process/thread info. Fixes a crash when first thread in the system terminates (and that's CSRSS thread by design).

svn path=/branches/arwinss/; revision=62865
2014-04-22 10:45:58 +00:00
Aleksey Bragin
ad26cd5ff9 [ARWINSS]
- Factor out Win32 thread info create/destroy into UserCreateThreadInfo and UserDestroyThreadInfo like in trunk.
- Improve NtUserInitialize.

svn path=/branches/arwinss/; revision=62851
2014-04-21 09:47:01 +00:00
Aleksey Bragin
3e3a3dd179 [ARWINSS]
- Update the patch to trunk. CSR stuff is still missing, however other necessary changes are in. 7kb -> 10kb size increase (temporary, I hope).

svn path=/branches/arwinss/; revision=62845
2014-04-20 22:11:39 +00:00
Aleksey Bragin
441eb0fe1d [ARWINSS]
- Bring in Eng functions from trunk's gdi32
- Add GetFontResourceInfoW() because base/applications/fontviewer started to depend on it
- Stub InitializeLpkHooks() in user32
- Arwinss now builds in trunk. I hope the cat is happier now and gets off my window.

svn path=/branches/arwinss/; revision=62759
2014-04-16 17:02:22 +00:00
Aleksey Bragin
6b3de3f767 [ARWINSS]
* Update the FreeType header inclusions, as per 62417.

svn path=/branches/arwinss/; revision=62507
2014-03-15 21:18:27 +00:00
Aleksey Bragin
2dd4e99574 [ARWINSS]
- Update the patch to trunk. Bright side: it got significantly smaller (22kb vs 7kb). Dark side: it misses the CSR stuff either.

svn path=/branches/arwinss/; revision=62337
2014-02-26 20:24:22 +00:00
Aleksey Bragin
fec546e935 Make Arwinss compile in newest trunk. It wouldn't work yet as CSRSS stuff should be fixed, however at least a buildable Arwinss is a good starting point.
Thanks goes to Hermes Belusca, Amine Khaldi and also to Oleg Izgagin (BMSTU student) for their help with this update.

svn path=/branches/arwinss/; revision=62336
2014-02-26 20:22:07 +00:00
Aleksey Bragin
e93c1440fb [WINENT]
- Don't skip rendering clipboard data.

ARWINSS-84 #comment This issue is resolved by r57783.

svn path=/branches/arwinss/; revision=57783
2012-11-29 13:08:29 +00:00
Aleksey Bragin
656a7a60fb - Rewrite connect_process_winstation from the hacky "process inheritance" (which is a unixism) to stably assigning WinSta0/Default desktop to all processes. Further improvement would be to support reading window station and desktop name from process parameters block (there is already a stub for that, which will issue a corresponding debug print if the non-default desktop is specified). This seems to fix the long-standing bug with accessing a 0x0000005C pointer.
http://jira.reactos.org/browse/ARWINSS-75

svn path=/branches/arwinss/; revision=57760
2012-11-24 19:00:04 +00:00
Aleksey Bragin
cbd3993dd7 - Update diff to trunk.
- Now it all builds with consistent version (and that, in fact, fixed at least a couple of bugs).

svn path=/branches/arwinss/; revision=57565
2012-10-15 14:30:55 +00:00
Aleksey Bragin
6fd0e5a258 - Get rid of version redefines. It turned out the 6.0+ stuff could be easily isolated.
svn path=/branches/arwinss/; revision=57564
2012-10-15 14:14:28 +00:00
Aleksey Bragin
ad63d91cbb - Patch to apply to trunk if you want to build arwinss (includes win32csr changes). Eventually these changes will be cleaned up and merged to trunk.
svn path=/branches/arwinss/; revision=57426
2012-09-29 12:42:28 +00:00
Aleksey Bragin
69e0c88568 - Final header files reshuffling. Now it compiles as it should.
svn path=/branches/arwinss/; revision=57396
2012-09-26 20:42:12 +00:00
Aleksey Bragin
06e19ef0b5 Move remaining of arwinss-specific parts to preserve files change history. Remove everything else.
svn path=/branches/arwinss/; revision=57380
2012-09-24 21:40:19 +00:00
Aleksey Bragin
70413222a4 - Start converting arwinss from feature branch into a trunk-pluggable module:
* Move all arwinss-specific components to the arwinss top-level directory.

svn path=/branches/arwinss/; revision=57379
2012-09-24 18:52:37 +00:00
Aleksey Bragin
543c73a7ac - Start converting arwinss from feature branch into a trunk-pluggable module:
* Delete unnecessary files.

svn path=/branches/arwinss/; revision=57377
2012-09-24 12:49:01 +00:00
Aleksey Bragin
d4cd1a3d2e - Compiling fixes.
- CMake switch.

svn path=/branches/arwinss/; revision=57372
2012-09-23 20:35:42 +00:00
Aleksey Bragin
519378c08e - Minor compiling fixes.
- CMake switch.

svn path=/branches/arwinss/; revision=57371
2012-09-23 20:32:14 +00:00
Aleksey Bragin
f8f96f0316 - CMake switch.
svn path=/branches/arwinss/; revision=57370
2012-09-23 20:31:19 +00:00
Aleksey Bragin
11bcfa3fd6 - Minor compiling fixes.
- CMake switch.

svn path=/branches/arwinss/; revision=57369
2012-09-23 20:30:27 +00:00
Aleksey Bragin
36401d9ad3 Fix a dcattr memory leak. Similar leak was already fixed in trunk in bug 6119. Huge (really!) thanks goes to igorko for finding all related fixes in trunk, for regress-testing the issue and finding the one and only, absolutely correct, guilty revision. After that, fixing it was just a few minutes work.
svn path=/branches/arwinss/; revision=55266
2012-01-27 22:01:24 +00:00
Aleksey Bragin
f46e1c931a - Misc trunk headers compatibility fixes.
svn path=/branches/arwinss/; revision=55077
2012-01-22 21:31:01 +00:00
Aleksey Bragin
03923a0f2b - Misc changes, mostly involving the change in NDK path happened many many revisions ago. I commit this change since the compilability of arwinss branch itself is already broken (it's supposed to compile in trunk now).
svn path=/branches/arwinss/; revision=54741
2011-12-23 18:15:17 +00:00
Aleksey Bragin
9f1fa83d22 - Misc trunk 547xx-compatibility fixes.
svn path=/branches/arwinss/; revision=54740
2011-12-23 17:01:24 +00:00
Aleksey Bragin
f1b83e5328 - Misc trunk 547xx-compatibility fixes.
svn path=/branches/arwinss/; revision=54739
2011-12-23 17:00:51 +00:00
Aleksey Bragin
9241378d46 [GDI32]
- Get rid of dangerous LoadLibraryA("freetype.dll") invocation happening inside DLL_PROCESS_ATTACH and link statically instead. This commit breaks the arwinss branch buildability on itself (not that much of a loss considering how old stuff is in the branch) and is a first commit towards ability to build arwinss in trunk.

svn path=/branches/arwinss/; revision=53279
2011-08-17 11:11:54 +00:00
Aleksey Bragin
e072ca7e2d - The very first victim of DPH monitoring: Fix user-provided glyph buffer overread.
- P.S. Arwinss just happen to be my experimental set up right now, so DPH is first tested there and once it works it's gonna be applied to trunk.

svn path=/branches/arwinss/; revision=50889
2011-02-24 11:12:18 +00:00
Aleksey Bragin
108edc065b - Add new-style syscall definitions in win32k_arwinss.
svn path=/branches/arwinss/; revision=50642
2011-02-10 10:41:01 +00:00
Aleksey Bragin
a739bcdf03 - Sync up to Wine-1.3.13.
svn path=/branches/arwinss/; revision=50632
2011-02-09 13:28:02 +00:00
Aleksey Bragin
e6795f25f7 - Add experimental cleartype drawing code. This place will be revisited later, maybe after yarotows->arwinss merge.
svn path=/branches/arwinss/; revision=50618
2011-02-08 13:16:46 +00:00
Aleksey Bragin
e67fa2cb71 - Implement support for smoothed (gray) glyph rendering.
- Modify GreTextOut to use sharp rendering for non-antialised glyphs and smooth for AA ones respectively.
- Removed unnecessary unused code from font.c.
- This fixes bug 5327 if FontSmoothing is enabled in the registry.

svn path=/branches/arwinss/; revision=50613
2011-02-07 21:11:21 +00:00
Aleksey Bragin
852a67f3fa - Merge 50604 by Timo.
svn path=/branches/arwinss/; revision=50608
2011-02-05 10:30:07 +00:00
Aleksey Bragin
f2db332334 - Add an update routine which resizes the SWM root window to the primary surface size.
See issue #5876 for more details.

svn path=/branches/arwinss/; revision=50591
2011-02-02 13:38:49 +00:00
Aleksey Bragin
814993fb02 - Add a dummy undocuser.h to fix compiling.
svn path=/branches/arwinss/; revision=50567
2011-01-29 19:07:09 +00:00
Aleksey Bragin
3f757bc7fb - Fix compiling in recent trunk.
svn path=/branches/arwinss/; revision=50564
2011-01-29 18:18:35 +00:00
Aleksey Bragin
c02e5f87b5 - Sync up to Wine-1.3.12.
svn path=/branches/arwinss/; revision=50517
2011-01-27 18:13:10 +00:00
Aleksey Bragin
5842c5fa8a - Fix "Not enough hook windows array size" debug print.
svn path=/branches/arwinss/; revision=50510
2011-01-27 10:52:59 +00:00
Aleksey Bragin
409d3bc0df - PatBlt should use current brush, not pen, for filling. Fixes some parts of the famous "black background" problem.
See issue #5331 for more details.

svn path=/branches/arwinss/; revision=50503
2011-01-26 22:12:27 +00:00
Aleksey Bragin
710693cebe [winent.drv]
- Add process_detach() routine which performs some required cleanup.
- Sync font-related code to the most recent Wine version.
- Add back commented out asserts() in winent.drv font code.

svn path=/branches/arwinss/; revision=50476
2011-01-23 20:19:35 +00:00
Aleksey Bragin
5053d3783c - Change DrawFocusRect to use PatBlt instead of alternate pen, as it's done in trunk. It looks like earlier Windows also used PatBlt for this purpose, and even Wine itself hints that it should be done this way. Fixes bug #5280.
svn path=/branches/arwinss/; revision=50453
2011-01-21 17:19:57 +00:00
Aleksey Bragin
4acf3ef043 - Allow size change for a minimized window. This fixes the famous "unable to restore a minimized window" bug. Now you can freely minimize/maximize windows using taskbar as you would usually do in trunk/windows.
svn path=/branches/arwinss/; revision=50451
2011-01-20 21:36:07 +00:00
Aleksey Bragin
0ea3835321 - Maarten Kroese: Properly hide minimized top level windows. Fixes bug 5207.
svn path=/branches/arwinss/; revision=50446
2011-01-19 21:42:46 +00:00
Aleksey Bragin
f6eacb589f - Maarten Kroese: Fix SM_CX/YMAXIMIZED calculation too.
svn path=/branches/arwinss/; revision=50445
2011-01-19 20:00:10 +00:00
Aleksey Bragin
8fdd54acad - Fix undeclared functions warnings.
svn path=/branches/arwinss/; revision=50440
2011-01-19 17:19:17 +00:00
Aleksey Bragin
5ecaa24f31 - Globally save monitor working area per monitor, fix incorrectly storing it in the kernelmode. Patch by Drazic.
- Required two lines modification of Wine's user32, not a big problem for later syncing.
See issue #5523 for more details.

svn path=/branches/arwinss/; revision=50439
2011-01-19 17:17:58 +00:00
Aleksey Bragin
c0b9840ea6 - Forgot to commit w32ksvc.db change.
svn path=/branches/arwinss/; revision=50425
2011-01-18 18:30:57 +00:00
Aleksey Bragin
822a250ef0 - Substitute rcVcPort by a ptlDCOrig, like in trunk.
- Pass window origin in a call to RosGdiSetWindow(), which fixes drawing broken in a previous commit.

svn path=/branches/arwinss/; revision=50424
2011-01-18 17:03:28 +00:00
Aleksey Bragin
3641ab168f - Remove unneeded events code, definitions, types.
- Rename RosGdiGetDC() to RosGdiSetWindow(), to be consistent with the current model which was discussed so hot in #reactos-dev. If/when it changes, it should be changed back.
- Remove RosGdiReleaseDC() because it's unused.
- Remove RosGdiSetDcRects() because it was added as kind of a temporary hack. Instead, get position from a real window set for that DC.
- Change GR_WINDOW_ID to more suitable SWM_WINDOW_ID.
- Bring back getting hwnd via SWM for input events code because using ChildWindowFromPoint introduces usability problems in some apps (e.g. unable to push buttons) and dependence on hacked winlogon. To be investigated in future. Also as a bonus, it turns out to be faster. 

svn path=/branches/arwinss/; revision=50422
2011-01-18 12:47:07 +00:00
Aleksey Bragin
1ec8646be8 - It's more useful to show a dprint before asserting.
svn path=/branches/arwinss/; revision=50421
2011-01-18 12:13:59 +00:00
Aleksey Bragin
c2c174234e - Properly initialize an empty CLIPOBJ.
- Uncomment children window clipping of desktop's window, allows fullscreen drawing operations.
- Update surface clipping region when a new bitmap is selected.
- Don't leak allocated clipping regions at DC cleanup time, spotted by smiley_.

svn path=/branches/arwinss/; revision=50420
2011-01-18 12:11:43 +00:00
Aleksey Bragin
1154d4edc8 [WINENT.DRV]
- Remove unnecessary events code, it has no use for us.

svn path=/branches/arwinss/; revision=50419
2011-01-18 12:01:58 +00:00
Aleksey Bragin
25e9779830 [WINENT.DRV]
- Fix a number of small mistakes in the new usermode handle mapping code (performing dirty read, masking out hUser function parameter by a local variable and thus sometimes adding an incorrect mapping, mapping NULL handles, etc).
- Thanks to Wine's usage of DllMain and our dll loader, wine*.drv still gets called even after DLL_PROCESS_DETACH. To partially fix the issue, store stock objects mapping in a static global array. Fixes "SURFACE_ShareLock failed" issues.

svn path=/branches/arwinss/; revision=50409
2011-01-17 14:28:38 +00:00
Aleksey Bragin
ff795f70c8 - It's a really bad idea to use freed data, so fix that.
svn path=/branches/arwinss/; revision=50395
2011-01-15 22:00:23 +00:00
Aleksey Bragin
7c86bdd4fd - Solve one of the most visible and historical drawing problem of arwinss: improper clipping. E.g. child windows borders being "visible" in an explorer window is an example, FAP drawing issues an another. All redrawing bugs should be retested to see what's fixed.
- Add a "clipchildren" property to the DC. This property affects only those DCs which have a root window (screen) selected. A better name for this variable would be welcome.
- Important! The change in behaviour introduced by ClipChildren is currently commented out until some issues it brings are solved.

svn path=/branches/arwinss/; revision=50394
2011-01-15 21:33:09 +00:00
Giannis Adamopoulos
1bb8b59140 swm isn't always the best solution. Instead of reinverting the well we can also use win32 api
svn path=/branches/arwinss/; revision=50393
2011-01-15 20:13:44 +00:00
Aleksey Bragin
1918135c82 - Don't use an unitialized rect offset.
svn path=/branches/arwinss/; revision=50388
2011-01-15 12:10:51 +00:00
Aleksey Bragin
1de44813dd - Repaint all children only in case of non-desktop window paint operation. Should remove unnecessary redrawing and thus increase performance.
svn path=/branches/arwinss/; revision=50383
2011-01-14 14:34:26 +00:00
Giannis Adamopoulos
0b4772d4bd fix build... err, implement shared memory for dcs between win32k and winent
svn path=/branches/arwinss/; revision=50366
2011-01-12 12:50:22 +00:00
Aleksey Bragin
3e794d75f4 - Change SWM API to use window id's instead of hwnds.
- Deprecate RosGdiReleaseDC, the DC always have a window selected (either root one if it's released, or the one passed via GetDC).
- Use "good" version of code in RosDrv_GetDC, getting rid of old GetAncestor hack.
- Change include order of ntrosgdi.h and rosuser.h. The latter one must always be included before ntrosgdi one.
- Kernelmode DC-related changes:
* Save DC type, because clipping will be different for memory and window DCs.
* Always select a window for OBJ_DC. In the default mode a root window is selected.
* Simplify clipping calculations, make them transparent and understandable, remove dummy window hack.
- SWM changes:
* Add an always existing root_window, which is used now instead of a number of dynamically created desktop windows.
* Add SWM window events structures and definitions. Unused now, and future usage is still subject for further experiments.
- One problem is introduced, which leads to inability to get a full screen DC (it will be clipped by children). To be fixed by next commits introducing clipping properties.

svn path=/branches/arwinss/; revision=50364
2011-01-12 10:34:41 +00:00
Giannis Adamopoulos
788635a274 [winent]
- Remove a hack for stock objects from RosGdiSelectBitmap. To handle stock objects properly, map their handles instead
[win32k]
- Add NtGdiGetStockObject and remove some difference to trunk. 
From now on if a function is the same with trunk it will use the NtGdi prefix

svn path=/branches/arwinss/; revision=50325
2011-01-08 13:26:33 +00:00
Aleksey Bragin
faa67eed95 - Forgot to commit this file, related to SWM interface changes.
svn path=/branches/arwinss/; revision=50318
2011-01-08 11:24:57 +00:00
Giannis Adamopoulos
4bf37a247f [winent]
- Move implementation of handle mapping to user mode. 

[win32k]
- Remove handle mappings from win32k. Now win32k manages only its own handles

svn path=/branches/arwinss/; revision=50317
2011-01-08 08:57:15 +00:00
Aleksey Bragin
3794634a18 - Use updated SWM interface in winent.drv, and cleanup code.
svn path=/branches/arwinss/; revision=50316
2011-01-07 21:53:30 +00:00
Aleksey Bragin
f30333aad5 - Change SWM interface to better suit new requirements. Move to window ids instead of always referencing by hwnd (will be needed to distinct between whole and client windows).
svn path=/branches/arwinss/; revision=50315
2011-01-07 21:51:51 +00:00
Aleksey Bragin
db5d0c04f4 - Move windowing code to window.c.
- Add proper code structure for creating client windows too, and fix other places so they would be ready for a newer window manager interface.
- Slightly cleanup file headers, and state that some code is based on Wine.
- Add some experimental event code, which is #if0ed for now.

svn path=/branches/arwinss/; revision=50313
2011-01-07 20:50:13 +00:00
Aleksey Bragin
e695e15d20 - Get rid of rcDcRect, kernelmode DC shouldn't care because all coordinate transformation is done in usermode. rcViewPort remains, and will be changed soon.
svn path=/branches/arwinss/; revision=50299
2011-01-06 13:17:03 +00:00
Aleksey Bragin
1e364bd992 - winent.drv: Keep dc_rect in usermode counterpart of DC structure.
- winent.drv: Rename hUserDC to hdc for better readibility.
- ntrosgdi.h: Update the PHYSDEV struct and remove unused ROS_DCINFO.

svn path=/branches/arwinss/; revision=50298
2011-01-06 13:13:47 +00:00
Aleksey Bragin
f889c2f6cd - Modify RosGdiCreateDC accordingly.
svn path=/branches/arwinss/; revision=50295
2011-01-05 23:19:10 +00:00
Aleksey Bragin
7b3a3f62fc - Move font related routines to font.c.
- Remove ROS_DCINFO structure and all related stuff. It's totally unnecessary, since coordinate transformation is done in usermode.

svn path=/branches/arwinss/; revision=50294
2011-01-05 23:18:00 +00:00
Aleksey Bragin
4355a63d8e - More code cleanup: put GDI code into appropriate places.
svn path=/branches/arwinss/; revision=50293
2011-01-05 22:39:38 +00:00
Aleksey Bragin
9a079d7dc6 - Code cleanup: add source files for common function groups.
- Change license information to better reflect the contents.
- Move tons of different header includes in individual files to one include set inside winent.h.

svn path=/branches/arwinss/; revision=50292
2011-01-05 20:15:19 +00:00
Aleksey Bragin
61dab2f4ae - Sync up to Wine-1.3.10.
svn path=/branches/arwinss/; revision=50162
2010-12-27 15:36:26 +00:00
Aleksey Bragin
ce69a835d8 - If RosGdiGetDC is called with a NULL (or non-existing) hwnd, restrict any drawing operations on that DC.
svn path=/branches/arwinss/; revision=50128
2010-12-24 17:36:07 +00:00
Aleksey Bragin
fa3bf0a1bd - Support scenario when GetDC() is performed on an invisible window. Previously, this problem led to getting DC of a whole screen, but the proper solution is to restrict any drawing to such DC. This fixes drawing issues in GTK based apps.
- Add get_device_rect (from Wine source code) and use it to map coordinates in Rectangle implementation.
- Silence IsSelectionOwner() debug print.

svn path=/branches/arwinss/; revision=50127
2010-12-24 17:34:14 +00:00
Aleksey Bragin
cad8139750 - Return time difference to the next timeout as a 64 bit integer instead of 32 bit which sometimes could "overlap" in case of big timeouts.
See issue #5758 for more details.

svn path=/branches/arwinss/; revision=50006
2010-12-10 21:17:49 +00:00
Aleksey Bragin
fe243d1161 - Adjust SWM to actually behave like a window manager which user32/server expects. [2/2]
Changes briefly:
 * A window is created as a hidden window by default .
 * When a window is being made visible zorder doesn't change (it's not moved to foreground automatically anymore).

svn path=/branches/arwinss/; revision=49964
2010-12-06 14:16:20 +00:00
Aleksey Bragin
d0b21be1e6 - Move to a more formalized window manager interaction in winent. Based on code from winex11.drv. [1/2]
- As a result, windows should appear and hide correctly, as expected by the core user32/server code.

svn path=/branches/arwinss/; revision=49963
2010-12-06 14:13:08 +00:00
Aleksey Bragin
2f755db2f4 - Fix POINT/POINTL mismatch.
svn path=/branches/arwinss/; revision=49820
2010-11-27 14:53:22 +00:00
Aleksey Bragin
67ef11ade9 - Sync up to Wine-1.3.8.
svn path=/branches/arwinss/; revision=49802
2010-11-26 23:13:42 +00:00
Aleksey Bragin
649986c6d2 - Sync up to Wine-1.3.7.
svn path=/branches/arwinss/; revision=49760
2010-11-23 22:12:41 +00:00
Aleksey Bragin
d0751e3dde - Fix RosBuildShellHookWndList() declaration and its usage in user32. Fixes weird crashes "here and there" (c) ROS forum.
svn path=/branches/arwinss/; revision=49430
2010-11-02 14:01:04 +00:00
Aleksey Bragin
4eb0016661 - Fix RosUserBuildShellhookWndList() implementation in win32k.
svn path=/branches/arwinss/; revision=49429
2010-11-02 13:57:43 +00:00
Aleksey Bragin
5c5cffccf4 - Properly implement win32k timers in arwinss. Fixes a whole bunch of weird crashes, race conditions, unnecessary code complications, and things like that (e.g. #5222).
- A couple of timer managing functions are based on code (c) Alexandre Julliard, Wine project (server/fd.c).
See issue #5222 for more details.

svn path=/branches/arwinss/; revision=49416
2010-11-01 21:31:07 +00:00
Aleksey Bragin
daf5add98c - Stop abusing non paged pool in arwinss.
- Fix different time units usage in message queue code.
- My timeout implementation still s..ks b..ls.
See issue #5222 for more details.

svn path=/branches/arwinss/; revision=49404
2010-11-01 14:36:45 +00:00
Aleksey Bragin
61618c34c0 - Properly queue and free timer and result callback work items. Fixes probably the most significant problem in arwinss's message queue, affecting many apps. However, another half of this problem still remains in bug #5222.
svn path=/branches/arwinss/; revision=49350
2010-10-30 12:39:34 +00:00
Aleksey Bragin
cf11c6a03a - Implement RegisterShellHookWindow/DeregisterShellHookWindow in user32. Running applications now appear in Explorer's taskbar (except for console windows and inactive windows, bug #5206).
- Thanks to Maarten Kroese, this work is partially based on his patch.

svn path=/branches/arwinss/; revision=49329
2010-10-28 13:50:53 +00:00
Aleksey Bragin
3e98a2e166 - Add support for shell window hooks in win32k, based on trunk's code. It's not beautiful however it's well isolated and easy for future merges.
- The proper code for keeping a list of registered windows for shell hook notifications in desktop structure is commented out for debugging purposes, and the list is global atm.
- Thanks to Maarten Kroese, this work is partially based on his patch.

svn path=/branches/arwinss/; revision=49328
2010-10-28 13:39:49 +00:00
Aleksey Bragin
00258c7c1c - Undef NB_HOOKS to fix compilation with latest trunk.
- Check if Process is not NULL in get_process_idle_event request, fixes a crash.

svn path=/branches/arwinss/; revision=49304
2010-10-27 12:56:36 +00:00
Aleksey Bragin
e34c6f3732 - Properly release all resources during thread and process termination.
svn path=/branches/arwinss/; revision=49254
2010-10-24 09:24:02 +00:00
Aleksey Bragin
0fad69ebac - Change the way private window data is stored, from using window properties to a per-process usermode linked list. Fixes crashes in a number of apps (e.g. uTorrent), and also improves performance (no syscall is necessary).
See issue #5623 for more details.

svn path=/branches/arwinss/; revision=49213
2010-10-19 22:24:52 +00:00
Aleksey Bragin
4ec1ab59fb - Forward BitBlt with NULL source DC to PatBlt. Fixes this kind of crashes in different apps (ab)using this feature of WinAPI.
See issue #5628 for more details.

svn path=/branches/arwinss/; revision=49197
2010-10-18 15:30:18 +00:00
Aleksey Bragin
ad6981998d - Zero-initialize eparent, fixes uninitialized memory access (seen in traces like in bug #5631).
svn path=/branches/arwinss/; revision=49192
2010-10-18 10:10:52 +00:00
Aleksey Bragin
2bb122c69a - Sync up to Wine-1.3.5.
- Merge necessary header changes from trunk.
- Rework the icon copying hack introduced in r47602. Now it applies only to those icons which copying indeed failed, all others are copied with the fast and alpha-compatible routine.

svn path=/branches/arwinss/; revision=49190
2010-10-17 22:08:02 +00:00
Aleksey Bragin
2871cb0260 - Merge 48462 by tkreuzer: "Copy the alpha channel as well when doing RGB<->BGR color translations."
svn path=/branches/arwinss/; revision=48803
2010-09-18 13:14:21 +00:00
Aleksey Bragin
0489e8e360 - Fix winex11.drv build.
svn path=/branches/arwinss/; revision=48794
2010-09-17 19:26:28 +00:00
Aleksey Bragin
1ca9563209 - Revert 42950: "Don't paint desktop itself but rely on csrss's Desktop Thread to do this for now". This hack is not needed anymore after 48791.
svn path=/branches/arwinss/; revision=48793
2010-09-17 19:21:26 +00:00
Aleksey Bragin
117e33dabd - Apply patch from wine-patches (http://www.winehq.org/pipermail/wine-patches/2010-September/093369.html):
Implement support for getting class data GCLP_HBRBACKGROUND on other process window. [3/3]

svn path=/branches/arwinss/; revision=48791
2010-09-17 18:40:31 +00:00
Aleksey Bragin
4eaa7baae1 - Apply patch from wine-patches (http://www.winehq.org/pipermail/wine-patches/2010-September/093369.html):
Implement support for getting class data GCLP_HBRBACKGROUND on other process window. [2/3]

svn path=/branches/arwinss/; revision=48790
2010-09-17 18:39:23 +00:00
Aleksey Bragin
015053544e - Apply patch from wine-patches (http://www.winehq.org/pipermail/wine-patches/2010-September/093369.html):
Implement support for getting class data GCLP_HBRBACKGROUND on other process window. [1/3]

svn path=/branches/arwinss/; revision=48789
2010-09-17 18:37:43 +00:00
Aleksey Bragin
f8ab1fac4d - Always capture unsafe bits buffer in SetDIBits to a safe one allocated from heap (by analogy from trunk's gdi32).
- Cleanup winent.rbuild, add PSEH library.
See issue #5509 for more details.

svn path=/branches/arwinss/; revision=48784
2010-09-16 20:04:53 +00:00
Aleksey Bragin
1b1aa06add - Add unsafe bits buffer probing in GreSetDIBits.
svn path=/branches/arwinss/; revision=48783
2010-09-16 20:00:06 +00:00
Aleksey Bragin
998c5fa6c8 - Take absolute value of ScanLines in GreSetDIBits because it can be negative. Fixes last major issue with arwinss-in-trunk.
svn path=/branches/arwinss/; revision=48776
2010-09-15 12:56:35 +00:00
Aleksey Bragin
f9288039ba - Improve parameters check in usermode part of SetDIBits too.
- Fix signedness of scanlines passed to SetDIBitsToDevice.

svn path=/branches/arwinss/; revision=48775
2010-09-15 12:54:45 +00:00
Aleksey Bragin
d7dcc43c58 - Fix GetTextExtentExPointI and GetTextExtentPointI prototypes to match Platform SDK.
svn path=/branches/arwinss/; revision=48769
2010-09-13 20:45:45 +00:00
Aleksey Bragin
e88da4a5eb - Sync up to Wine-1.3.1.
- Merge 48678 from trunk.

svn path=/branches/arwinss/; revision=48679
2010-09-01 13:46:19 +00:00
Jan Roeloffzen
7d2a149ce9 [user32]
- Revert 48571
- Thou shall not fix wine where it ain't broken. Credits Gabriel Ilardi.
- See bug 5303

svn path=/branches/arwinss/; revision=48577
2010-08-21 13:10:15 +00:00
Jan Roeloffzen
caa6976653 [user32]
- Don't update visible regions of hidden windows.
Fixes bug 5303

svn path=/branches/arwinss/; revision=48571
2010-08-19 23:36:22 +00:00
Aleksey Bragin
46072908c0 - Sync up to Wine-1.3.
- Remove unnecessary win32k api and a corresponding winent api.

svn path=/branches/arwinss/; revision=48421
2010-08-02 20:37:45 +00:00
Aleksey Bragin
7650e547f9 - Fix user32 build by merging header updates (44999-48394).
svn path=/branches/arwinss/; revision=48395
2010-08-01 13:20:30 +00:00
Aleksey Bragin
5964cd7dca - winent.drv: Fix include paths.
- winent.drv: Remove unnecessary included winuser16.h.

svn path=/branches/arwinss/; revision=48394
2010-08-01 12:52:23 +00:00
Aleksey Bragin
ba9925ecee - user32: Fix function definitions to match MS PSDK. To be submitted upstream.
svn path=/branches/arwinss/; revision=48393
2010-08-01 12:50:40 +00:00
Aleksey Bragin
6e66a32b8d - Fix include paths.
svn path=/branches/arwinss/; revision=48392
2010-08-01 12:44:24 +00:00
Aleksey Bragin
046bed5b0f - Move arwinss-specific headers into reactos/wine include directory.
svn path=/branches/arwinss/; revision=48391
2010-08-01 12:42:07 +00:00
Aleksey Bragin
8fcd91f052 - Merge 44999:48380 of psdk/wingdi.h
svn path=/branches/arwinss/; revision=48382
2010-07-31 12:20:50 +00:00
Aleksey Bragin
925243dae4 - Fix incorrect function definitions. To be submitted upstream.
svn path=/branches/arwinss/; revision=48380
2010-07-31 12:08:50 +00:00
Aleksey Bragin
7977f3ce7e - Sync up to Wine-1.2.
svn path=/branches/arwinss/; revision=48166
2010-07-21 19:53:00 +00:00
Giannis Adamopoulos
b15d90f4a1 [win32k]
- Remove test code

svn path=/branches/arwinss/; revision=48033
2010-07-14 07:51:54 +00:00
Aleksey Bragin
a2e457c88a [WINENT]
- Start porting clipboard implementation from Wine. Notepad is already able to copy/paste text. Code cleanup will follow in a few days.

svn path=/branches/arwinss/; revision=48032
2010-07-13 22:39:30 +00:00
Giannis Adamopoulos
7f0e1d5878 [kernel32]
-Revert r42201

[user32]
-Fix atom usage. Create a local copy of atom.c that calls the wineserver to manage user atoms.
Wine code assumes that kernel32 will use the same global atom table with win32k (and this is how windows really work)
However reactos doesn't do it and as a result some functions use atoms created by kernel32 and some created by win32k.
To solve this issue, user32 parts that use kernel32 atoms will use kernel32 atom functions and the parts that use win32k atoms will use the local user atom functions

svn path=/branches/arwinss/; revision=48003
2010-07-12 10:10:10 +00:00
Giannis Adamopoulos
86410bd8a8 [win32k]
- Implement RosGdiExtFloodFill

svn path=/branches/arwinss/; revision=48001
2010-07-11 19:38:37 +00:00
Aleksey Bragin
080fb691d4 - Cleanup clipboard information at thread destroy.
svn path=/branches/arwinss/; revision=47995
2010-07-11 08:17:12 +00:00
Aleksey Bragin
d618afff9f - Bring in server-side clipboard implementation.
svn path=/branches/arwinss/; revision=47994
2010-07-11 08:13:09 +00:00
Aleksey Bragin
558ba5d6a5 - Merge 47992 ("Create window station with all access rights").
svn path=/branches/arwinss/; revision=47993
2010-07-11 08:11:51 +00:00
Aleksey Bragin
7015064002 - Fix build.
svn path=/branches/arwinss/; revision=47984
2010-07-09 22:31:56 +00:00
Giannis Adamopoulos
6979b1ff32 [win32k]
- Sync implementaion of dib, brushes, pens, palettes, xform, xlate and mouse pointer functions with trunk

svn path=/branches/arwinss/; revision=47980
2010-07-09 16:13:10 +00:00
Gabriel Ilardi
e24265e4fe Add also csrsrv.dll to reactos.dff
svn path=/branches/arwinss/; revision=47976
2010-07-09 07:30:15 +00:00
Aleksey Bragin
90cb37a0da - Merge everything csrss/console-related 44999:47973.
- Remove PrivateCsrssInitialized ReactOS-only export.

svn path=/branches/arwinss/; revision=47975
2010-07-08 22:11:51 +00:00
Kamil Hornicek
d092e54d66 Fix the bug of the month in arwinss too.
svn path=/branches/arwinss/; revision=47973
2010-07-08 19:57:08 +00:00
Aleksey Bragin
341ab0c23e - SwmCopyBits: Implement moving bits of a non-foreground window (which usually is the case, because at least a taskbar is an always-on-top window). Fixes e.g. visual glitches when moving a window over the taskbar.
svn path=/branches/arwinss/; revision=47966
2010-07-07 22:10:22 +00:00
Aleksey Bragin
b964cdb4ac - Remove deprecated SwmGetTopWindow(), use SwmGetForegroundWindow() instead.
svn path=/branches/arwinss/; revision=47949
2010-07-05 12:57:16 +00:00
Aleksey Bragin
8d54c171e1 - Implement basic support for topmost window handling. Currently limited only to windows created with this flag, no change on-the-fly. Also, moving windows with contents hasn't been fixed yet either to support always on top windows.
svn path=/branches/arwinss/; revision=47947
2010-07-05 11:43:26 +00:00
Aleksey Bragin
86b593cfe6 - Pass window styles to SWM when adding a window.
- Fix a debug print showing wrong previous hwnd value in SwmWindowPosChanged.

svn path=/branches/arwinss/; revision=47932
2010-07-03 20:56:49 +00:00
Aleksey Bragin
fa35ae9494 - Properly pass antialiasing information to the kernelmode text output routine.
- Delete unused code.

svn path=/branches/arwinss/; revision=47928
2010-07-03 12:29:09 +00:00
Aleksey Bragin
5fa635f83b - Remove off-by-one fix from 47923, problems were caused by other local changes. Text rendering is back to normal.
svn path=/branches/arwinss/; revision=47925
2010-07-02 21:34:00 +00:00
Aleksey Bragin
43cbb2398b - Fix an off by one error in glyph drawing which resulted in a slightly distorted text output.
- Add support for grey glyphs (still with sharp output).

svn path=/branches/arwinss/; revision=47923
2010-07-02 09:41:09 +00:00
Aleksey Bragin
9ec96b17d4 - Giannis Adamopoulos: Never allow bringing shell window to foreground in SWM.
svn path=/branches/arwinss/; revision=47910
2010-06-29 21:56:07 +00:00
Aleksey Bragin
26d39bd2c4 - Merge 47605.
svn path=/branches/arwinss/; revision=47904
2010-06-29 10:08:23 +00:00
Aleksey Bragin
395af0c2e9 - Sync up to Wine-1.2-rc5.
svn path=/branches/arwinss/; revision=47903
2010-06-29 09:14:16 +00:00
Aleksey Bragin
8111c146f9 - Sync up to Wine-1.2-rc3.
svn path=/branches/arwinss/; revision=47806
2010-06-19 08:58:57 +00:00
Aleksey Bragin
37f7c50406 - Merge in changes from Wine-1.1.44 related to supporting the ETO_PDY flag. Unregresses the text rendering in FF 3.5. Thanks to Jan Roeloffzen for help finding this problem and suggesting the right solution.
svn path=/branches/arwinss/; revision=47757
2010-06-11 20:18:59 +00:00
Aleksey Bragin
e3efc8ec13 - Remove my implementation of SWM cursor icons which turned out to be similar to creating an elephant from a fly. Instead use a much simpler, updated and fail-proof implementation by Giannis Adamopoulos. Arwinss is back on track.
svn path=/branches/arwinss/; revision=47640
2010-06-06 21:40:11 +00:00
Aleksey Bragin
302f254851 - Copy bitmap even if it can't be selected into the dc (e.g. when it's already selected into another DC) using already existing helper. Fixes mouse cursor icon problem.
svn path=/branches/arwinss/; revision=47602
2010-06-05 19:59:12 +00:00
Aleksey Bragin
3315dfa2f9 - Sync up to Wine-1.2-rc2.
svn path=/branches/arwinss/; revision=47590
2010-06-05 15:03:58 +00:00
Aleksey Bragin
f70e2eb18f - Further work on the new cursor icons support. Core functionality is there, however there are still a few bugs and some debugging code marked with C++-style comments and words like HACK and FIXME.
svn path=/branches/arwinss/; revision=47396
2010-05-29 08:33:12 +00:00
Aleksey Bragin
8d7949687a - Initialize (hide) mouse pointer right after creating the primary surface. Fixes a possible crash when the cursor was moved and only then cursor icon was set.
svn path=/branches/arwinss/; revision=47395
2010-05-29 08:24:25 +00:00
Aleksey Bragin
e574bead74 - Implement some base support for window-based cursor icons support. Still work in progress. RosDrv_CreateCursorIcon is unused and will be removed soon, instead creation happens lazily and is implemented in create_cursor(). All possible unimplemented places are marked with TODO or FIXME.
svn path=/branches/arwinss/; revision=47332
2010-05-23 18:36:11 +00:00
Aleksey Bragin
3fe49df00a - Sync up to Wine-1.2-rc1.
- Further refactoring of cursor icons code according to recent Wine's improvements.

svn path=/branches/arwinss/; revision=47323
2010-05-23 11:16:16 +00:00
Aleksey Bragin
0643d5788b - Initial cursor icons support, work in progress. When it's finished, improvements and optimisations are welcome.
svn path=/branches/arwinss/; revision=47320
2010-05-23 10:22:09 +00:00
Aleksey Bragin
ac1550c260 - Sync up to Wine-1.1.44. Mouse pointer support in native driver mode is broken by this commit!
- winent.drv: Move mouse pointer support code from userdrv.c to mouse.c.

svn path=/branches/arwinss/; revision=47289
2010-05-21 18:57:53 +00:00
Kamil Hornicek
500c668d83 [WIN32K]
- Bring support from RLE compressed bitmaps from trunk.
- Merge the 4bpp and 8bpp decompress functions to one generic function to avoid code duplication and to reduce code complexity.
- Fixes missing icons in Wordpad toolbars, missing reactos logo bitmap in shell about dialog and more.

svn path=/branches/arwinss/; revision=47054
2010-04-28 12:39:22 +00:00
Aleksey Bragin
043d105bde - SWM: Create clipping region in a shorter way for SwmDc (previously due to passing NULL in rcBounds parameter to RosGdiSetDeviceClipping it was not really fully initialized). Should fix issues with copying contents of a moving window.
svn path=/branches/arwinss/; revision=47034
2010-04-26 13:21:19 +00:00
Aleksey Bragin
2299e46981 - RosGdiCreateDC: Remove transformation objects from DC. All needed transformations are performed in usermode (additional bonus is that we remove part of floating point operations done in kernelmode).
See issue #5237 for more details.

svn path=/branches/arwinss/; revision=47015
2010-04-25 15:44:02 +00:00
Aleksey Bragin
6557525282 - WINENT.DRV: Remove bit copying, it's a job of SWM.
- SWM: Create a screen DC, and copy window's contents when changing position (significantly faster than doing it from winent.drv, not to say that doing so without interaction with a window manager is not possible).
- SWM: Invalidate areas after changing moving a window or changing its size.
- GDIOBJ: Add a missing space for code beautification.
See issue #5237 for more details.

svn path=/branches/arwinss/; revision=47014
2010-04-25 13:28:14 +00:00
Aleksey Bragin
358d17c258 - RosGdiCreateDC: Make sure DC is not tied to any window.
svn path=/branches/arwinss/; revision=47013
2010-04-25 13:19:24 +00:00
Aleksey Bragin
dec90ff046 - Initialize SWM after DC implementation init. Doesn't change anything now, but it's more logical because SWM is higher level of abstraction than DCs, palette and other low-level things.
svn path=/branches/arwinss/; revision=47012
2010-04-25 13:17:00 +00:00
Aleksey Bragin
7981b024a1 - Properly convert region coordinates in SwmInvalidateRegion. This gives a substantial visibility improvement: now windows properly repaint themselves when changing focus.
svn path=/branches/arwinss/; revision=47002
2010-04-23 16:38:28 +00:00
Gregor Schneider
b3de52bac3 [WIN32K] pLogPen cannot be NULL (static buffer), check pExtLogPen instead
svn path=/branches/arwinss/; revision=47001
2010-04-23 15:58:13 +00:00
Aleksey Bragin
2583797798 - Target mouse events to a corresponding window. Fixes issues like inability to click radiobuttons, move resolution slider in desk.cpl, etc.
See issue #5214 for more details.

svn path=/branches/arwinss/; revision=46999
2010-04-23 10:02:09 +00:00
Aleksey Bragin
eb50c378c0 - Merge 46959, fixes arwinss-in-trunk booting.
svn path=/branches/arwinss/; revision=46993
2010-04-22 17:37:20 +00:00
Aleksey Bragin
725e539926 - Sync up to Wine-1.1.43.
svn path=/branches/arwinss/; revision=46919
2010-04-18 12:53:37 +00:00
Aleksey Bragin
2d4e0e1d26 - Get rid of the last hardcoded screen size.
- Remove unnecessary function declaration.
See issue #5304 for more details.

svn path=/branches/arwinss/; revision=46914
2010-04-18 08:15:55 +00:00
Aleksey Bragin
fbe0b85f6b - Enable clipped text output. Solves issues like caption text being printed outside of window's caption when window is being made too small.
svn path=/branches/arwinss/; revision=46872
2010-04-14 20:37:43 +00:00
Aleksey Bragin
ff5282f46a - Add a clipping region cache to the usermode DC structure and use it in SetDeviceClipping calls instead of creating an empty region all the time. Speed increase and also it's needed for further text output improvements.
svn path=/branches/arwinss/; revision=46871
2010-04-14 20:23:38 +00:00
Aleksey Bragin
6f0f121b0a - Grab a USER lock when entering timer worker routines, fixes race conditions (were exhibited by user32_winetest msg).
svn path=/branches/arwinss/; revision=46861
2010-04-13 20:11:19 +00:00
Aleksey Bragin
0f1b3ee11f - A user server inside the win32k should have its own error state and must not change thread's last error! Implement this by using a global_error variable, having in mind that handling a server request is an atomic operation.
- Number of winetest failures is dramatically reduced.

svn path=/branches/arwinss/; revision=46827
2010-04-10 20:29:37 +00:00
Aleksey Bragin
21fcb62dd9 - Copy whole window bits when moving a window, SWM's job. Fixes "repainting" issues when moving a window.
svn path=/branches/arwinss/; revision=46778
2010-04-08 09:09:26 +00:00
Aleksey Bragin
65dbeb0962 - Temporarily comment out freeing the message queue at thread termination. Fixes "hangs" after exiting any application.
svn path=/branches/arwinss/; revision=46773
2010-04-07 21:23:51 +00:00
Aleksey Bragin
7ce7a0250b - Code cleanup: remove unnecessary PTHREADINFO/PPROCESSINFO casts, reduce diff to the original code, make the code smaller by querying the current thread info only once per function.
svn path=/branches/arwinss/; revision=46772
2010-04-07 21:17:42 +00:00
Aleksey Bragin
830b2e2929 - Store a handle to the idle event, not just a pointer to the event object in a per process structure.
- Dereference and properly close idle event object when terminating a process.

svn path=/branches/arwinss/; revision=46759
2010-04-07 09:57:49 +00:00
Aleksey Bragin
e941d6dcec - Finally implement timeout removal from the old desktop when setting a new one for the process.
svn path=/branches/arwinss/; revision=46756
2010-04-06 22:08:17 +00:00
Aleksey Bragin
abdd40883b - Add thread termination cleanup (destroying windows, freeing a message queue, dereferencing its desktop).
svn path=/branches/arwinss/; revision=46755
2010-04-06 21:30:29 +00:00
Aleksey Bragin
61e8214482 - Create and use idle_event as expected by Wine. It creates idle_event for every gui process (TODO: investigate if CUI process in ReactOS should have it).
- Rewrite get_process_idle_event handler in a NT way.

svn path=/branches/arwinss/; revision=46753
2010-04-06 18:47:52 +00:00
Aleksey Bragin
90c547a445 - Import process.s from wineserver, clean it up to contain only ported get_process_idle_event handler. Not included into the build now.
svn path=/branches/arwinss/; revision=46752
2010-04-06 17:37:08 +00:00
Aleksey Bragin
402b64c6e2 - Sync up to Wine-1.1.42.
svn path=/branches/arwinss/; revision=46715
2010-04-04 13:19:10 +00:00
Aleksey Bragin
e0d9979bc3 - Sync up to Wine-1.1.41.
svn path=/branches/arwinss/; revision=46322
2010-03-21 20:53:56 +00:00
Aleksey Bragin
ba0a26a8dd Maarten Kroese
- Apply same Marlett-font charset fix to the system menu drawing.
- Also slightly adjust symbol's position. (Should be sent upstream).

svn path=/branches/arwinss/; revision=45981
2010-03-07 09:44:18 +00:00
Aleksey Bragin
f003056663 - Sync up to Wine-1.1.40.
- winent.drv: Since GetObject doesn't report negative height for topdown bitmaps anymore, rely on information from bmi. In future, it should be fixed to just provide a boolean topdown flag to the kernelmode GDI driver counterpart.

svn path=/branches/arwinss/; revision=45949
2010-03-06 15:00:23 +00:00
Aleksey Bragin
4f58c0190c - GetBitmapBits and SetBitmapBits should get/set bitmaps bits in a particular format described in MSDN, not in the format they are stored in internally. Reimplement them based on winex11.drv implementation. Could use some optimisation, but they are deprecated non time-critical functions. Thanks to Maarten Kroese for finding this problem. Fixes issue #28 in Arwinss wiki.
svn path=/branches/arwinss/; revision=45810
2010-03-03 22:33:50 +00:00
Aleksey Bragin
6a4a249743 - GreSetDIBits: Don't leak a surface lock in case parameters check fails.
- GreSetDIBits: Add a (now commented out) optimisation for directly copying bits if source and target bitmaps parameters closely match. Based on a similar winex11.drv optimisation in this function.

svn path=/branches/arwinss/; revision=45808
2010-03-03 21:50:51 +00:00
Aleksey Bragin
33b282aa29 - Merge 45687:45688 by Maarten Kroese. Fixes issues with context menus in ReactOS Explorer.
svn path=/branches/arwinss/; revision=45689
2010-02-26 19:16:22 +00:00
Aleksey Bragin
18ce4c0141 Maarten Kroese
UITOOLS95_DrawFrameCaption improvements:
- Change FIXED_PITCH to DEFAULT_PITCH (because Marlett is not a fixed pitch font).
- Change from SYMBOL_CHARSET to DEFAULT_CHARSET, it's correct according to MSDN, because SYMBOL_CHARSET implies that it can fall back to another font, but that is never what we want.
- FW_NORMAL to FW_DONTCARE.
- This patch should be sent to Wine, however their Marlett font hides these problems.

svn path=/branches/arwinss/; revision=45678
2010-02-23 20:58:12 +00:00
Aleksey Bragin
7bac01ee38 - Sync up to Wine-1.1.39.
svn path=/branches/arwinss/; revision=45651
2010-02-21 14:16:14 +00:00
Aleksey Bragin
6886738f15 - Merge 45011: "avoid warning messages on Explorer startup when missing configuration files".
svn path=/branches/arwinss/; revision=45630
2010-02-20 10:44:36 +00:00
Dmitry Gorbachev
4152dcfc39 [SYSSETUP] Wait until all autostart services are up. Bug #4194.
svn path=/branches/arwinss/; revision=45629
2010-02-20 00:32:31 +00:00
Dmitry Gorbachev
5e351c9152 [SERVICES] When autostart services are up, signal an event.
svn path=/branches/arwinss/; revision=45628
2010-02-20 00:32:23 +00:00
Dmitry Gorbachev
2d6f3bd1a2 [SYSSETUP] Wait until PlugPlay service is up. Bug #4142.
svn path=/branches/arwinss/; revision=45606
2010-02-18 02:28:51 +00:00
Dmitry Gorbachev
0f3bd258d0 [UMPNPMGR] Update the service control manager's status information.
svn path=/branches/arwinss/; revision=45605
2010-02-18 02:28:48 +00:00
Dmitry Gorbachev
6b06433745 [SERVICES] Set default status to SERVICE_START_PENDING when starting a service.
svn path=/branches/arwinss/; revision=45604
2010-02-18 02:28:45 +00:00
Dmitry Gorbachev
05a1d3bd7d [WINLOGON] Fix a comment.
svn path=/branches/arwinss/; revision=45603
2010-02-18 02:27:57 +00:00
Aleksey Bragin
647f4b734a - Implement SetDIBColorTable.
svn path=/branches/arwinss/; revision=45601
2010-02-16 19:56:35 +00:00
Aleksey Bragin
701d3b128d - Implement kernelmode part of SetDIBitsToDevice (heavily based on win32k from r41760).
svn path=/branches/arwinss/; revision=45600
2010-02-16 18:45:49 +00:00
Aleksey Bragin
fae75f5b72 - Implement usermode part of SetDIBitsToDevice.
svn path=/branches/arwinss/; revision=45599
2010-02-16 18:43:21 +00:00
Aleksey Bragin
52d1633fe9 - Calculate correct bounding rectangle and pass it to GrePolygon. Fixes non-filled polygon bug (because GrepFillPolygon relies on a correct bounding rect), issue #31 in the Arwinss wiki.
- Pass bounding rect to GrepFillPolygon by pointer instead of by value.
- Update line brush in GrePolyline.

svn path=/branches/arwinss/; revision=45594
2010-02-14 20:45:31 +00:00
Aleksey Bragin
fb460af868 - Calculate a real bounding rect instead of hacking it to be always display surface sized.
svn path=/branches/arwinss/; revision=45593
2010-02-14 11:57:56 +00:00
Aleksey Bragin
cf577056b8 - Implement ellipse and arcs (pie/chord/arc) in the graphics driver. Heavily based on trunk's win32k.
svn path=/branches/arwinss/; revision=45581
2010-02-11 21:58:21 +00:00
Aleksey Bragin
ceb742e761 - Implement usermode parts of Pie and Ellipse GDI driver APIs.
svn path=/branches/arwinss/; revision=45571
2010-02-11 12:57:39 +00:00
Aleksey Bragin
f3b4f63a4a - Merge RosBE-1.5 compatibility patch.
svn path=/branches/arwinss/; revision=45570
2010-02-11 10:56:43 +00:00
Aleksey Bragin
23b59be45f - We are always using client side fonts, so remove the unimplemented warning from RosDrv_EnumDeviceFonts.
svn path=/branches/arwinss/; revision=45537
2010-02-09 20:04:48 +00:00
Aleksey Bragin
47ea80e2bb - Add back DIB section's "bottom down" property, which fixes existing issues (and adds new one in Explorer's start menu). Issue #28 in the Arwinss wiki.
- Remove unnecessary abs'es of always positive values.
- Add ScanLines/ScanStart bounds checking.
- Actually return a real amount of copied scanlines instead of always faking success.

svn path=/branches/arwinss/; revision=45502
2010-02-08 21:42:12 +00:00
Aleksey Bragin
f5fa38600a - Merge 45418, 45419 (expand sync from Wine). Part 2/2.
svn path=/branches/arwinss/; revision=45458
2010-02-06 13:37:41 +00:00
Aleksey Bragin
0ceb649bc6 - Merge 45418, 45419 (expand sync from Wine). Part 1/2.
svn path=/branches/arwinss/; revision=45457
2010-02-06 13:36:35 +00:00
Aleksey Bragin
43acf1e9ec - Sync up to Wine-1.1.38.
svn path=/branches/arwinss/; revision=45456
2010-02-06 10:18:44 +00:00
Aleksey Bragin
702de3b64f - Disable hacked-up SwitchDesktop implementation for now. During shutdown, winlogon tries to switch to the winlogon (the same and only) desktop which results in a RedrawWindow sending a message to a CSR desktop window which is probably already in the process of being destroyed. Fixes a hang during shutdown (issue #27 in the wiki).
svn path=/branches/arwinss/; revision=45342
2010-01-30 13:10:29 +00:00
Aleksey Bragin
d0025d43e9 - Merge 45319, fixes issue #26 on arwinss wiki page (cmd text output problems). Thanks to Jan Roeloffzen for finding the issue, testing the behaviour on Windows and a hint for the fix.
svn path=/branches/arwinss/; revision=45322
2010-01-29 21:46:24 +00:00
Aleksey Bragin
ff5f1eb947 - Sync up to Wine-1.1.37.
svn path=/branches/arwinss/; revision=45207
2010-01-22 22:40:03 +00:00
Aleksey Bragin
5eaf63dae6 - Best way to fix CRT problem: Add more underscores! (and hacks)
- winex11.drv builds again.
- Mark usleep as unimplemented.

svn path=/branches/arwinss/; revision=45199
2010-01-22 10:49:40 +00:00
Aleksey Bragin
9a02a210e1 - Fully sync up desktopbg.c with 44999 and merge arwinss-specific changes.
svn path=/branches/arwinss/; revision=45179
2010-01-21 12:44:04 +00:00
Aleksey Bragin
6ef7e6c320 - Merge 44422:44999
svn path=/branches/arwinss/; revision=45178
2010-01-21 11:28:31 +00:00
Aleksey Bragin
938cd6439d - Merge 44184:44421
svn path=/branches/arwinss/; revision=45177
2010-01-21 11:12:57 +00:00
Aleksey Bragin
48c5da482e - Merge 44130:44183
svn path=/branches/arwinss/; revision=45176
2010-01-21 10:49:07 +00:00
Aleksey Bragin
8d362bc61b - Merge 44085:44129.
svn path=/branches/arwinss/; revision=45175
2010-01-21 10:44:42 +00:00
Aleksey Bragin
55e38ad33b - Merge 44013:44084
svn path=/branches/arwinss/; revision=45174
2010-01-21 10:36:58 +00:00
Aleksey Bragin
6957e6fd55 - Merge 43924:44012
svn path=/branches/arwinss/; revision=45173
2010-01-21 10:21:05 +00:00
Aleksey Bragin
c7c420025f - Merge 43668:43924
svn path=/branches/arwinss/; revision=45164
2010-01-20 22:09:42 +00:00
Aleksey Bragin
3b700392d6 - Reduce differences to stock Wine code.
svn path=/branches/arwinss/; revision=45111
2010-01-16 19:15:51 +00:00
Aleksey Bragin
4d7ebfce22 - Update to Wine-1.1.31.
svn path=/branches/arwinss/; revision=45105
2010-01-16 16:05:35 +00:00
Aleksey Bragin
257b68ce72 - Remove all ROS-specific modifications from comctl32-1.1.30 except the TOOLTIPS_NotifyFormat one for now.
svn path=/branches/arwinss/; revision=45104
2010-01-16 15:43:36 +00:00
Aleksey Bragin
9259743762 - Revert back to working comctl32 (Wine-1.1.30 as it looks like from logs).
- Apply TOOLTIPS_NotifyFormat fix.

svn path=/branches/arwinss/; revision=45103
2010-01-16 15:27:59 +00:00
Aleksey Bragin
f8c96b9da5 - Sync comctl32 to Wine-1.1.36.
svn path=/branches/arwinss/; revision=45101
2010-01-16 14:14:02 +00:00
Aleksey Bragin
545511f365 Merge:
- 45097: "Add commoncontrols.idl from Wine-1.1.36 (needed for newer comctl32)".
- 45098: "Merge Wine-1.1.36 changes to commctrl.h."
- 45099: "Add missing IIDs to UUID."

svn path=/branches/arwinss/; revision=45100
2010-01-16 13:55:35 +00:00
Aleksey Bragin
77e35db81e - Merge Wine-1.1.36 release changes. Besides all usual improvements, all 16 bit stuff has been finally separated and moved to other modules.
svn path=/branches/arwinss/; revision=45049
2010-01-11 20:49:34 +00:00
Aleksey Bragin
649878c7fd - Enable window contents copying in certain cases (like movement of a child window), which works beautifully now after fix from r44814.
svn path=/branches/arwinss/; revision=44815
2009-12-30 17:07:31 +00:00
Aleksey Bragin
6ed3b23f25 - Fix a copypaste typo which led to incorrect calculation of a source point in BitBlt.
svn path=/branches/arwinss/; revision=44814
2009-12-30 16:58:01 +00:00
Aleksey Bragin
e60ee098a0 - Pass swp flags to SWM and cleanup usermode part of WindowPosChanged.
- SWM: Silence debug prints.
- SWM: Warn when the zorder change is requested but not performed (and window's zorder doesn't match the requested one).
- SWM: Don't use SwmBringToFront in SwmShowWindow and make it respect the SWP_NOZORDER flag.

svn path=/branches/arwinss/; revision=44812
2009-12-30 13:26:24 +00:00
Aleksey Bragin
3ad913d67f - Cleanup swm.c from commented out code, 26KB -> 22KB.
- Make unhiding debug print show the window rect.

svn path=/branches/arwinss/; revision=44804
2009-12-29 19:40:54 +00:00
Aleksey Bragin
4eb46a040e - Always sync whole window position with SWM (winex11.drv does this way too). The only thing hacked for now is avoiding pos sync when SWP_NOREDRAW flag is passed (otherwise explorer's start menu is drawn cropped). Fixes FF3.5 start up in maximized mode.
svn path=/branches/arwinss/; revision=44800
2009-12-29 14:57:54 +00:00
Aleksey Bragin
30c696de67 - Remove SetDCOrg driver API.
svn path=/branches/arwinss/; revision=44744
2009-12-23 18:49:59 +00:00
Aleksey Bragin
38e881f5e0 - Update to the newest server protocol version.
svn path=/branches/arwinss/; revision=44719
2009-12-22 20:33:39 +00:00
Aleksey Bragin
ff5701364a - Merge Wine-1.1.34 and 1.1.35 changes.
svn path=/branches/arwinss/; revision=44718
2009-12-22 20:16:41 +00:00
Kamil Hornicek
ae4c72d396 - use EngMovePointer when appropriate, fixes mouse in VBox
svn path=/branches/arwinss/; revision=44362
2009-12-02 14:31:16 +00:00
Kamil Hornicek
516ccf2461 - bring support for EnumDisplaySettings and ChangeDisplaySettings from trunk
svn path=/branches/arwinss/; revision=44361
2009-12-02 13:17:44 +00:00
Kamil Hornicek
cb363eb8c2 - add EngCreateDeviceSurface, one step closer to working VBox video driver
svn path=/branches/arwinss/; revision=44360
2009-12-02 12:55:44 +00:00
Kamil Hornicek
4849149a5d - consider dest. palette in GreRealizeBrush
svn path=/branches/arwinss/; revision=44264
2009-11-21 22:05:52 +00:00
Kamil Hornicek
f9c88728d5 - palette support for dib sections
svn path=/branches/arwinss/; revision=44263
2009-11-21 21:54:17 +00:00
Aleksey Bragin
01df7ab1b4 - Merge 44261: "Don't export unnecessary stub. Fixes Firefox 3.5.5 startup."
svn path=/branches/arwinss/; revision=44262
2009-11-21 20:42:54 +00:00
Aleksey Bragin
4f8a811d14 - winent.drv: Inform SWM in all cases when a window really changes its size or position.
- SWM: Recalculate clipping of all windows every time a window state is changed. This is more time consuming rather than the incremental approach used earlier, however it's 100% fail proof.
- The above changes provide a substantial improvement to the window clipping and drawing in arwinss, except for a few unhandled cases.

svn path=/branches/arwinss/; revision=44255
2009-11-21 15:02:55 +00:00
Kamil Hornicek
0cbe67757a - actually plug alpha blend in
svn path=/branches/arwinss/; revision=44253
2009-11-21 14:11:32 +00:00
Kamil Hornicek
5c9f252114 - bring alpha blend from trunk
svn path=/branches/arwinss/; revision=44252
2009-11-21 14:09:27 +00:00
Kamil Hornicek
de226d2a0e - add dummy hooks for mouse and keyboard so WH_MOUSE_LL and WH_KEYBOARD_LL hooks are flagged as active
- needed until these two are implemented via SendMessage

svn path=/branches/arwinss/; revision=44251
2009-11-21 14:05:22 +00:00
Aleksey Bragin
2ba51183e0 - GetDC(): Always clip the root window, instead of trying to attach a non-existing in SWM child window. Fixes visual glitches when browsing through menus.
svn path=/branches/arwinss/; revision=44246
2009-11-20 21:36:47 +00:00
Kamil Hornicek
4642c13e91 - release the old bitmap when selecting a new one
svn path=/branches/arwinss/; revision=44200
2009-11-16 13:22:56 +00:00
Kamil Hornicek
ef7c14b849 - load font substitutes from both SysFontSubstitutes and FontSubstitutes registry keys
- add a temporary workaround for font files mapping (compare file name instead of file index)
- font selection now works

svn path=/branches/arwinss/; revision=44175
2009-11-15 17:01:45 +00:00
Aleksey Bragin
a9fe2bd490 - Update to Wine-1.1.33.
- Merge 44153 from trunk.

svn path=/branches/arwinss/; revision=44154
2009-11-14 11:29:19 +00:00
Aleksey Bragin
17a878bcee - Remove wineism.
svn path=/branches/arwinss/; revision=44152
2009-11-14 11:14:44 +00:00
Aleksey Bragin
8f450c398d [SWM]
- Implement SwmGetTopWindow() which returns the currently top most window.
- If there is no movement in SwmPosChanged, don't do anything (a prerequisite for further work).
- Demote debug prints to DPRINT level.

svn path=/branches/arwinss/; revision=44150
2009-11-14 11:00:53 +00:00
Aleksey Bragin
8f1b31d4fd - Create windata for the desktop window in RosDrv_CreateWindow.
- Fix RosDrv_SetFocus (it should bring to forward only parent window whenever any of its child is clicked, previously such events would be ignored).
- Add some checks to RosDrv_ShowWindow, but without changing logic.
- Fix a key problem of not differentiating between SWM managed and child windows. Fix this by adding the "whole_window" pointer to the windata structure, which will be a pointer to SWM's window structure. Right now it's just set to non-zero value if a window is an SWM window.
- Zero win data structure in NTDRV_create_win_data.

svn path=/branches/arwinss/; revision=44149
2009-11-14 09:29:44 +00:00
Kamil Hornicek
ecd8906f3f - initialize the pointer exclude rectangle
svn path=/branches/arwinss/; revision=44131
2009-11-13 13:52:17 +00:00
Kamil Hornicek
866f87d5f2 - pass a pointer to the exclude rect to GreMovePointer
- store the cursor coordinates in pdevobj
- retrieve the cursor position form global CursorInfo in MouseSafetyOnDrawEnd
- MouseSafetyOnDrawStart/End should work now


svn path=/branches/arwinss/; revision=44126
2009-11-13 10:07:18 +00:00
Aleksey Bragin
39debde877 [SWM]
- Move out the code for setting foreground window into a separate helper function SwmBringToFront. Call it from SwmSetForeground and SwmShowWindow.

svn path=/branches/arwinss/; revision=44118
2009-11-12 19:11:28 +00:00
Aleksey Bragin
d0c4ecab73 [SWM]
- Start implementing window hide/show support.

svn path=/branches/arwinss/; revision=44114
2009-11-11 22:01:19 +00:00
Aleksey Bragin
66de833b67 - Implement GetDC/ReleaseDC for window manager with clipping support. This addresses the invalid drawing order "bug", which is in fact a feature. Client window manager is responsible for compositing all windows in a given rectangle being redrawn. Arwinss implements a very simple client window manager (SWM) which just clips out all contents behind the window on top of a z order.
- Notify SWM about a new (or an existing) desktop window.
- Fix comment typos.

svn path=/branches/arwinss/; revision=44112
2009-11-11 19:55:22 +00:00
Aleksey Bragin
66715b3b57 [SWM]
- Fix invalidating a region: properly convert coordinates, invoke update_window_zorder.
- Implement SwmAddDesktop for adding a desktop window.
- Fix SwmSetForeground which was incorrectly calculating a visible region (should be subtracting instead of intersecting).
- Remove "struct region" hack from debug deumping routines.

svn path=/branches/arwinss/; revision=44111
2009-11-11 19:40:48 +00:00
Aleksey Bragin
0bbd67b29c - Move swm.h include higher in the list.
svn path=/branches/arwinss/; revision=44110
2009-11-11 19:30:28 +00:00
Aleksey Bragin
21e5854731 - Implement region -> CLIPOBJ conversion.
svn path=/branches/arwinss/; revision=44109
2009-11-11 19:26:21 +00:00
Aleksey Bragin
63532a9404 - Move region structure definition to user.h.
- Implement creating a region from RECTL array.

svn path=/branches/arwinss/; revision=44108
2009-11-11 19:23:49 +00:00
Kamil Hornicek
6de143bd7d - sync IntShowMousePointer with trunk, don't invert the cursor mask in EngSetPointerShape
- RosDrv_GetIconInfo: don't pass empty bmbits + remove the fixme, GetObject isn't really supposed to do that
- fixes cursors once again

svn path=/branches/arwinss/; revision=44087
2009-11-11 01:40:04 +00:00
Gregor Schneider
fdcda2d761 [win32k] Pass the size of the appropriate pen style (copypasta)
svn path=/branches/arwinss/; revision=44051
2009-11-09 18:04:59 +00:00
Aleksey Bragin
6dd6f9d421 - Add brush updating before any LineTo call.
- Properly mark dotted pens as needing a realization.

svn path=/branches/arwinss/; revision=44048
2009-11-09 14:39:18 +00:00
Aleksey Bragin
a65a6752f7 - Check if pBitsLock is NULL in SURFACE_Cleanup before freeing it. This may happen only in a low-memory condition failure branch in create surface code. Spotted by Kamil Hornicek.
svn path=/branches/arwinss/; revision=44029
2009-11-08 20:14:15 +00:00
Aleksey Bragin
3860edf183 - Implement pattern brush realization. Based on code by Kamil Hornicek.
svn path=/branches/arwinss/; revision=44028
2009-11-08 16:49:45 +00:00
Aleksey Bragin
63d284586e - Merge 44019.
svn path=/branches/arwinss/; revision=44020
2009-11-07 20:19:08 +00:00
Aleksey Bragin
b7e48d02eb - Fully sync comctl32 with Wine-1.1.32 removing all ReactOS-specific hacks.
- TOOLTIPS_NotifyFormat implementation remains.

svn path=/branches/arwinss/; revision=44017
2009-11-07 20:02:44 +00:00
Aleksey Bragin
b0a50a2620 - Merge r44013 and r44015 from trunk (commctrl.h updates).
svn path=/branches/arwinss/; revision=44016
2009-11-07 19:56:54 +00:00
Kamil Hornicek
104c777085 - fill the whole pattern
svn path=/branches/arwinss/; revision=44011
2009-11-07 18:56:04 +00:00
Aleksey Bragin
1fb94e627a - Satisfy only one thread waiting on message queue at a time as expected by the original implementation.
svn path=/branches/arwinss/; revision=43999
2009-11-07 15:06:32 +00:00
Kamil Hornicek
6286a84a24 - opengl support for arwinss
svn path=/branches/arwinss/; revision=43987
2009-11-06 14:52:27 +00:00
Aleksey Bragin
3a7861a492 - Fix incorrect clipping calculation when empty region is passed to RosDeviceSetClipping. Instead of setting clipping to full underlying surface access, it should set it to the dc rectangle intersected with the underlying surface rect. Fixes visual glitch when painting non-client area of a window.
- Fix a typo which lead to using stack allocated RECTs array only for one rectangle instead of 8 possible. This fix reduces pool memory allocations for complex regions.

svn path=/branches/arwinss/; revision=43974
2009-11-05 13:38:01 +00:00
Aleksey Bragin
c6bf99a42e - Revert the mouse hwnd change for now, it was not intended for committing. This unregresses arwinss usability.
svn path=/branches/arwinss/; revision=43939
2009-11-03 21:37:01 +00:00
Aleksey Bragin
6a91a97806 - Make desktop window clip siblings too.
svn path=/branches/arwinss/; revision=43938
2009-11-03 21:28:21 +00:00
Aleksey Bragin
bb1594a166 - Merge 43934, 43935.
svn path=/branches/arwinss/; revision=43937
2009-11-03 21:19:36 +00:00
Aleksey Bragin
3523f37879 - Open and set window station for CSR's process when a first request for create desktop comes (at this time we are sure winlogon created the window station). Examples of fixed bugs: console windows open now, no weird crashes at shutdown.
svn path=/branches/arwinss/; revision=43927
2009-11-02 21:31:09 +00:00
Aleksey Bragin
546baaf297 - Start working on proper window managing: Implement a very simple window manager, responsible for redrawing top-level windows (Swm* APIs in win32k).
- Remove all previous hacks related to window redrawing in events of move or focus change. They couldn't work properly.
- Wine's win32 engine really expects mouse events to be tagged by a corresponding window's handle. Make it so using SWM.
- All these changes make arwinss usability actually regress (mostly due to removing unnecessary hacks and problems in other components).

svn path=/branches/arwinss/; revision=43887
2009-10-31 20:55:25 +00:00
Aleksey Bragin
d426b63bb9 - Assign "Default" desktop to processes who don't have a parent.
svn path=/branches/arwinss/; revision=43720
2009-10-24 18:37:56 +00:00
Aleksey Bragin
e57f7721ff - Update arwinss to Wine-1.1.32.
- 16 bit code is well isolated by Wine team now, so amount of differences is substantially smaller. Also more compatibility due to rewritten user32/resource.c.

svn path=/branches/arwinss/; revision=43713
2009-10-24 13:20:16 +00:00
Aleksey Bragin
970608f49d - Make all object dumping use DbgPrint instead of DPRINT macro, since it does table formatted output.
- Properly print strings.

svn path=/branches/arwinss/; revision=43699
2009-10-23 13:26:18 +00:00
Aleksey Bragin
9af0fccf23 - Enable debug dump routines.
svn path=/branches/arwinss/; revision=43697
2009-10-23 12:49:38 +00:00
Aleksey Bragin
c0c3119548 - Move all CSR-interacting functions to a standalone file (csr.c) and implement them (ROS-specific, for Win2003 compatiblity they have to be at least commented out). Mainly those are needed for proper shutdown/reboot in ReactOS.
svn path=/branches/arwinss/; revision=43696
2009-10-23 10:30:21 +00:00
Aleksey Bragin
7052b7cec8 - Merge 43126:43670.
svn path=/branches/arwinss/; revision=43672
2009-10-21 16:53:32 +00:00
Aleksey Bragin
81ae3601cd - It was really too early to remove PatBlt and BitBlt. Get them back for now, since they are still supported.
svn path=/branches/arwinss/; revision=43540
2009-10-17 19:47:26 +00:00
Aleksey Bragin
298fd25286 - Properly remove mouse pointer.
svn path=/branches/arwinss/; revision=43535
2009-10-17 18:53:14 +00:00
Aleksey Bragin
fb7fb7c669 - Remove PatBlt driver routine and instead call it from StretchBlt handler. Unregresses arwinss after syncing. Mouse cursor is still totally broken though.
svn path=/branches/arwinss/; revision=43409
2009-10-12 18:10:24 +00:00
Aleksey Bragin
2b88347ed8 - Remove BitBlt and PatBlt, they are going to be superseded by StretchBlt.
svn path=/branches/arwinss/; revision=43405
2009-10-12 15:10:01 +00:00
Aleksey Bragin
7966b58cda [arwinss]
- Sync up to Wine-1.1.31.

svn path=/branches/arwinss/; revision=43404
2009-10-12 15:03:17 +00:00
Aleksey Bragin
1f10d7d079 [arwinss]
- Sync up to Wine-1.1.31.

svn path=/branches/arwinss/; revision=43403
2009-10-12 14:56:37 +00:00
Aleksey Bragin
9181fc23f7 [arwinss]
- Sync up to Wine-1.1.31.

svn path=/branches/arwinss/; revision=43402
2009-10-12 14:23:25 +00:00
Aleksey Bragin
c6186b50e8 [arwinss]
- Merge Wine-1.1.31 server headers.

svn path=/branches/arwinss/; revision=43401
2009-10-12 14:22:23 +00:00
Aleksey Bragin
2e7ddff929 - Update user32, gdi32 and winex11.drv to Wine 1.1.30.
svn path=/branches/arwinss/; revision=43151
2009-09-25 18:54:49 +00:00
Aleksey Bragin
05362eccf8 - Update to Wine 1.1.29.
svn path=/branches/arwinss/; revision=43148
2009-09-25 18:24:36 +00:00
Aleksey Bragin
9fc7f502e4 - Uncomment ws2help from reactos.dff too as it now builds.
svn path=/branches/arwinss/; revision=43135
2009-09-24 18:53:28 +00:00
Stefan Ginsberg
c1bb1c53d6 Remove leftover ws2help.h that somehow didn't get deleted by the latest sync -- ws2help now builds again as the correct header gets included. Re-enable ws2help and ws2_32 again -- both build fine.
svn path=/branches/arwinss/; revision=43134
2009-09-24 18:51:53 +00:00
Aleksey Bragin
915d92482e - Merge trunk changes (up to 43125).
- ws2help and ws2_32_new are again commented out from the build process due to weird errors.

svn path=/branches/arwinss/; revision=43128
2009-09-24 14:00:29 +00:00
Aleksey Bragin
e0b70edadf - Remove the window station hack, it's not really needed anymore. Window station is not properly created by winlogon.
svn path=/branches/arwinss/; revision=42955
2009-08-27 09:18:34 +00:00
Aleksey Bragin
921057da68 [win32k]
- Add a missing thread reference. Fixes a crash exposed by AbiWord.

svn path=/branches/arwinss/; revision=42954
2009-08-27 09:11:43 +00:00
Aleksey Bragin
7bf3aa7c97 [win32csr]
- Temporarily comment out PaintDesktop here too to prevent flickering.

svn path=/branches/arwinss/; revision=42953
2009-08-27 09:00:31 +00:00
Aleksey Bragin
bcb9a4e8fd [user32]
- In a process initialization phase, replase CreateWindowStationW and CreateDesktopW calls with OpenWindowStationW and OpenDesktopW so that they don't force creation of a winstation or a new desktop if one doesn't exist. After this commit, a default desktop is properly created by winlogon after csrss is attached, and thus can repaint its background without problems. A hack for a missing window station remains.

svn path=/branches/arwinss/; revision=42952
2009-08-27 08:56:03 +00:00
Aleksey Bragin
1010bc975d [winlogon]
- Don't even try to create new desktops if they aren't going to be used. This should assist in arwinss development (marked with a comment).

svn path=/branches/arwinss/; revision=42951
2009-08-27 08:53:22 +00:00
Aleksey Bragin
e6dabc52f3 [explorer]
- Don't paint desktop itself but rely on csrss's Desktop Thread to do this for now.

svn path=/branches/arwinss/; revision=42950
2009-08-27 08:49:44 +00:00
Aleksey Bragin
9da2f920c2 - Remove unused shared user heap code.
svn path=/branches/arwinss/; revision=42947
2009-08-26 19:50:18 +00:00
Aleksey Bragin
8716cbbafc - Own the bitmap before freeing it, fixes a crash when trying to free a global bitmap.
- Don't free NULL pointers.

svn path=/branches/arwinss/; revision=42935
2009-08-26 10:56:11 +00:00
Aleksey Bragin
54fe08731c - Fix a typo in the assert which made a lot of false positives, e.g. when running taskmgr.
svn path=/branches/arwinss/; revision=42919
2009-08-24 18:09:56 +00:00
Aleksey Bragin
b406f0a2fe - Update zorder when switching focus from one window to another, and when a windows becomes visible. Not quite there yet - window's contents is not being repainted if needed, but switching between windows is much better now.
- Remove unneeded magic from NTDRV.

svn path=/branches/arwinss/; revision=42914
2009-08-24 16:47:13 +00:00
Aleksey Bragin
5df60db6e3 - Pass a direct bitmap bits pointer. It's yet unknown why bitmap object's bmBits pointer contains NULL (a corresponding FIXME comment is added).
- Issue 20 from Arwinss wiki is fixed.

svn path=/branches/arwinss/; revision=42877
2009-08-23 09:58:17 +00:00
Aleksey Bragin
02ee5dc45a - Create an XLATE for a mouse pointer.
- Silence a dprint in RosGdiGetDIBits.
- A step to fix an old issue nr. 20 from Arwinss wiki: "Fix mouse cursor being black problem"

svn path=/branches/arwinss/; revision=42876
2009-08-23 09:55:10 +00:00
Aleksey Bragin
d64003119e - Purge user->kernel mapping for a terminated process.
- Define GDI_DEBUG to track doublefrees and similar problems for now.

svn path=/branches/arwinss/; revision=42863
2009-08-22 17:49:51 +00:00
Aleksey Bragin
87aacb0b98 - No need for an annoying dprint message about deleting a DIB section. This section is nothing more than a bitmap in the system, so all specific cleanup is happening inside the kernelmode part of a driver.
svn path=/branches/arwinss/; revision=42840
2009-08-22 09:51:30 +00:00
Aleksey Bragin
f15632273e - Free brush's pattern bitmap only if it wasn't a user provided one. Fixes a lot of double-free errors.
svn path=/branches/arwinss/; revision=42839
2009-08-22 09:40:36 +00:00
Aleksey Bragin
5b0c103598 - Implement windows moving (with contents).
svn path=/branches/arwinss/; revision=42833
2009-08-21 19:13:00 +00:00
Aleksey Bragin
932ff2b0b8 - Get wine/class.c back to using Wine-styled linked list functions/macros for consistency: either all user server code uses NT linked lists or Wine linked lists. This fixes a problem with window's classes list consistency.
- Add Win32 process cleanup on its termination: delete the handles table and delete all classes. This fixes a problem of never terminating process, and occasionally fixes "New hardware found" wizard. Leaks--;

svn path=/branches/arwinss/; revision=42717
2009-08-15 21:53:24 +00:00
Aleksey Bragin
f0f727dbfc - Implement GetSystemPaletteEntries.
svn path=/branches/arwinss/; revision=42712
2009-08-15 18:25:13 +00:00
Aleksey Bragin
37c7915c2a - Implement system palette based on palette.c from r41760 (pre-Timo rewrite, to be compatible with other existing stuff).
svn path=/branches/arwinss/; revision=42711
2009-08-15 18:10:34 +00:00
Aleksey Bragin
f6d9c2e93f - Totally get rid of 16 bit global heap functions.
svn path=/branches/arwinss/; revision=42710
2009-08-15 16:58:58 +00:00
Stefan Ginsberg
4b97ad75f3 - gdi32: Don't use typeof -- MSVC does not implement it. Also fix an unitialized variable warning spotted by MSVC.
- user32: Properly stub out 16-bit code -- fixes several warnings (more remain)
- winent/winex11: Fix some const warnings in MSVC, and use redefine for WINVER and _WIN32_WINNT

svn path=/branches/arwinss/; revision=42707
2009-08-15 16:23:21 +00:00
Aleksey Bragin
c14ac7e4f3 - Update mouse pointer code from trunk. Color cursors aren't supported due to absence of EXLATEOBJs.
svn path=/branches/arwinss/; revision=42697
2009-08-15 12:59:07 +00:00
Aleksey Bragin
58d66d22a3 - Merge up to 42678. Tree fully builds.
svn path=/branches/arwinss/; revision=42682
2009-08-15 09:33:17 +00:00
Aleksey Bragin
88cb33f22c - Delete lib/sdk/crt/time.
svn path=/branches/arwinss/; revision=42679
2009-08-15 09:05:18 +00:00
Stefan Ginsberg
8b19eb5df9 - Define _WINE for gdi32, user32, winent and winex11 to be compatible with recent header changes
- Properly define RtlNtStatusToDosError in winternl.h so it doesn't conflict with server.h (the inconsistency is not detected by gcc)

svn path=/branches/arwinss/; revision=42677
2009-08-15 08:00:02 +00:00
Aleksey Bragin
d9acd339e5 - Merge 42376-42400.
svn path=/branches/arwinss/; revision=42670
2009-08-14 20:21:33 +00:00
Aleksey Bragin
1fcb5aee91 - Merge 42350-42376.
svn path=/branches/arwinss/; revision=42668
2009-08-14 19:36:55 +00:00
Aleksey Bragin
ab6d6c451c - Merge 42300-42350.
svn path=/branches/arwinss/; revision=42667
2009-08-14 19:19:54 +00:00
Aleksey Bragin
40a0a6dc5e - Merge 42250-42300.
svn path=/branches/arwinss/; revision=42666
2009-08-14 19:07:41 +00:00
Aleksey Bragin
0a366dba08 - Merge 42200-42250. Without dll/win32/ws2help (causes merge problems).
svn path=/branches/arwinss/; revision=42665
2009-08-14 18:56:27 +00:00
Aleksey Bragin
002fc9cec7 - Add a brush origin point to DC structure and update it before doing any operation potentially involving a brush origin (some unimplemented operations lack this). Partially fixes hatch brushes drawing.
svn path=/branches/arwinss/; revision=42658
2009-08-13 20:51:14 +00:00
Aleksey Bragin
4a5aa42a36 - Create XlateObject for brushes having a bitmap. Partially fixes drawing with these kind of brushes.
- Set iSolidColor back to reserved value, otherwise pattern won't be drawn.

svn path=/branches/arwinss/; revision=42657
2009-08-13 19:12:37 +00:00
Aleksey Bragin
410586ea8c - Implement hatched brushes support.
- Convert brush's pattern bitmap handle to a kernel GDI handle.

svn path=/branches/arwinss/; revision=42656
2009-08-13 17:29:50 +00:00
Aleksey Bragin
0aff19aec9 - If SetDeviceClipping is called without any rectangles, set clip region to cover whole surface, and remove annoying debug message related to that.
svn path=/branches/arwinss/; revision=42655
2009-08-13 13:13:54 +00:00
Aleksey Bragin
bc066f1d9b - Lock cursor's mask bitmap exclusively instead of shared.
svn path=/branches/arwinss/; revision=42654
2009-08-13 12:58:19 +00:00
Aleksey Bragin
e8bcbc5c9b - Intersect cursor clipping rectangle with virtual screen rectangle to get a real clipping. Now mouse cursor movements are fully clipped as expected.
- Update windows Z order when window position changed. Experimental.

svn path=/branches/arwinss/; revision=42653
2009-08-13 12:49:49 +00:00
Aleksey Bragin
004c3328f5 - Add GreCopyBits function for copying bitmap bits, and use it inside graphics engine. The function is a simple wrapper around EngCopyBits but with mouse cursor safety functions (if it actually gives a visible benefit, if any).
svn path=/branches/arwinss/; revision=42652
2009-08-13 10:35:29 +00:00
Stefan Ginsberg
0835e7a2a2 - Sync some headers to trunk, fix misc. msvc errors in the code -- win32k now compiles
svn path=/branches/arwinss/; revision=42640
2009-08-12 20:45:35 +00:00
Aleksey Bragin
920f847718 - Fix an epic typo in GreCreateBitmap which inverted bottomdown bitmaps and kept topdown as they were. As a result a hack in EngCreateBitmap goes away.
- Add a internal surface flags field to SURFACE structure, and add the one and only flag for now - SRF_BITSALLOCD, which means that the bitmap's bits are allocated by GRE.
- Free up GRE allocated bitmap's bits in the cleanup routine. Leaks--;

svn path=/branches/arwinss/; revision=42639
2009-08-12 20:27:16 +00:00
Aleksey Bragin
504a0bfff5 - Add cleanup routine for SURFACE object. Now SURFACE frees all memory except bits if they were allocated (TODO).
- Implement surface's bits locking/unlock (same concept as in trunk).

svn path=/branches/arwinss/; revision=42636
2009-08-12 18:02:42 +00:00
Aleksey Bragin
4137a25a0b - Don't try to lock DC twice in BitBlt if it's a same DC.
- Implement GetPixel operation (lacks color conversion!).
- Implement SetPixel using the idea from trunk's win32k: create a solid brush and PatBlt it to the needed place. Return value needs to be checked though, what gdi32 expects from it.

svn path=/branches/arwinss/; revision=42614
2009-08-11 13:26:06 +00:00
Aleksey Bragin
cd2dad78bd - Implement usermode part of Get/SetPixel.
- Add RosDrv_UpdateZOrder declaration to winent.h

svn path=/branches/arwinss/; revision=42613
2009-08-11 13:20:32 +00:00
Aleksey Bragin
0ad3849d1d - Merge 42000-42200.
svn path=/branches/arwinss/; revision=42595
2009-08-10 14:57:46 +00:00
Aleksey Bragin
7e836d6273 - Add missing constifying to MonitorFromRect API
- Don't compile d3d8thk.dll since it relies on a nonstubbed GDI API now.
- Remove d3d8thk.dll and ftfd.dll from bootcd, and add freetype.dll and winent.drv.
- Update some merge history.
- Arwinss branch now can be compiled with a usual "makex bootcd".

svn path=/branches/arwinss/; revision=42582
2009-08-10 09:10:53 +00:00
Aleksey Bragin
c0a6f50a32 - Sync wine/config.h with trunk's changes to fix msxml3 compiling.
svn path=/branches/arwinss/; revision=42581
2009-08-10 08:47:22 +00:00
Aleksey Bragin
3aa466c9b5 - Get back exception.h include to winbase16.h, but guard it with #ifndef _NTNDK_ so that exception record structure won't get redefined. Wine incompatibly places this structure to psdk/winnt.h.
- Add two missing definitions to commctrl.h.
- Remove unneeded wine/winbase.h and wine/windef.h.
- Sync up winbase16.h with trunk.

svn path=/branches/arwinss/; revision=42573
2009-08-09 20:23:50 +00:00
Aleksey Bragin
6c2879d128 - Add back STACK16/32FRAME which is needed by dbghelp.dll.
- Add #include <exception.h> to get rid of "#include <exception.h> // ROS Hack" in windef16.h.

svn path=/branches/arwinss/; revision=42561
2009-08-09 13:31:58 +00:00
Aleksey Bragin
824decf1ba - Properly update commctrl.h taking in account ReactOS-specific changes.
svn path=/branches/arwinss/; revision=42560
2009-08-09 13:25:48 +00:00
Aleksey Bragin
299aa42894 - Get rid of legacy win32k.def and import win32k.pspec from trunk.
- Add a missing EngQueryFileTimeStamp stub.

svn path=/branches/arwinss/; revision=42558
2009-08-09 12:41:25 +00:00
Aleksey Bragin
ecd9b0009b - Add missing XFORMOBJ exports.
svn path=/branches/arwinss/; revision=42549
2009-08-09 09:46:22 +00:00
Aleksey Bragin
82944ee829 - Fix UpdatePerUserSystemParameters definition.
svn path=/branches/arwinss/; revision=42548
2009-08-09 08:38:46 +00:00
Aleksey Bragin
4db95820d6 - Fix incorrect RegisterLogonProcess prototype/stub.
svn path=/branches/arwinss/; revision=42547
2009-08-09 08:27:50 +00:00
Aleksey Bragin
095e5ac1d2 - Implement GetDIBits, this was the last piece of code needed to support icons drawing in ROS explorer's Start Menu.
- Pass a pointer to the dibsection to RosGdiGetDIBits, currently unused though.
- Fix RosGdiCreateDIBSection bug: DIB section bits shouldn't be inverted once again if biHeight<0, this is already taken care of in other places. This fixes correct mask, but topdown icon drawing in the ROS explorer's Start Menu.

svn path=/branches/arwinss/; revision=42532
2009-08-08 19:13:20 +00:00
Aleksey Bragin
eb36cd995a - Create graphics engine bitmaps for backing DIB sections. Fixes displaying of desktop icons. Work in progress, freeing of DIB sections is not implemented yet.
svn path=/branches/arwinss/; revision=42512
2009-08-08 13:31:14 +00:00
Aleksey Bragin
23d03fcac1 - Uncomment a missing MouseSafetyOnDrawEnd.
svn path=/branches/arwinss/; revision=42508
2009-08-08 12:29:25 +00:00
Aleksey Bragin
f94447e141 - Remove unneeded and wrong LPtoDP translation in kernelmode graphics engine.
svn path=/branches/arwinss/; revision=42437
2009-08-06 20:29:46 +00:00
Aleksey Bragin
8875f1d1e2 - Translate coordinates (logical to device) for blitting operations in usermode.
- Implement ScrollDC (almost fully based on winex11's implementation). Work in progress.

svn path=/branches/arwinss/; revision=42436
2009-08-06 20:28:46 +00:00
Aleksey Bragin
c9f4d1209b - Implement GetDCOrgEx.
svn path=/branches/arwinss/; revision=42434
2009-08-06 17:47:08 +00:00
Aleksey Bragin
536be888a8 - Fix a typo (missing braces), spotted in bug 4764.
- Wrap returns from SEH into _SEH2_YIELD. Probably exceptions need to just be fully converted to ReactOS PSEH2 syntax.

svn path=/branches/arwinss/; revision=42431
2009-08-06 16:37:12 +00:00
Aleksey Bragin
5472075a3a - Implement RosGdiGetDcRects.
- Wrap usermode pointers access in RosGdiSetDcRects/GetDcRects to SEH.

svn path=/branches/arwinss/; revision=42424
2009-08-06 11:48:07 +00:00
Aleksey Bragin
c43e037af1 Stefan Ginsberg:
- Change some parts to use PsGetThreadWin32Thread, PsGetThreadId and PsGetProcessId instead of touching ETHREAD/EPROCESS members.
- The code looping the EPROCESS’ thread list remains (also, this code should probably use a thread list in the desktop structure instead of one in PROCESSINFO).

See ReactOS Assembla ticket #1 for more details.

svn path=/branches/arwinss/; revision=42421
2009-08-06 11:23:37 +00:00
Aleksey Bragin
317e2296b1 Merge 42419:
- Add PsGetThreadId declaration.

svn path=/branches/arwinss/; revision=42420
2009-08-06 11:19:05 +00:00
Aleksey Bragin
852e755813 - A leftover from a previous commit to winent.h (fixes incorrect structure names).
- More work towards movable windows support: create private window data in SetWindowStyle too, make move_window_bits and WindowPosChanged more or less what they should be. New windows appear perfectly now, however moving still doesn't work.

svn path=/branches/arwinss/; revision=42416
2009-08-06 09:42:34 +00:00
Aleksey Bragin
61b084b678 - Add a private window data storage support associated with each window via window properties. Could be improved in the future if using SetProp/GetProp proves to be very slow (it is in wine, but not in arwinss).
svn path=/branches/arwinss/; revision=42415
2009-08-06 08:51:18 +00:00
Aleksey Bragin
a904f7cb42 Giannis Adamopoulos
- Implement initial keyboard input support.
- Bring EngLoadImage from trunk.

svn path=/branches/arwinss/; revision=42409
2009-08-05 18:10:41 +00:00
Aleksey Bragin
1782ba46f5 - Make new desktop's window foreground in SwitchDesktop.
svn path=/branches/arwinss/; revision=42406
2009-08-05 12:57:11 +00:00
Aleksey Bragin
bdcc272230 - Remove unused code from GreCreateBitmap.
- If GreCreateBitmap is called with 0 bytewidth, calculate it automatically.
- Fix GreCreatePen pattern brush creation, and free up pattern bitmap in GreFreeBrush.

svn path=/branches/arwinss/; revision=42405
2009-08-05 12:35:19 +00:00
Aleksey Bragin
dd44fa9987 - Add preliminary support for pattern pens.
- Create null brushes when a DC is created.

svn path=/branches/arwinss/; revision=42392
2009-08-04 20:39:20 +00:00
Aleksey Bragin
5c27cd2eae - Uncomment missing surface unlocks.
svn path=/branches/arwinss/; revision=42381
2009-08-04 14:07:15 +00:00
Aleksey Bragin
63703b3e2d - Use a precreated stock bitmap.
svn path=/branches/arwinss/; revision=42380
2009-08-04 12:20:45 +00:00
Aleksey Bragin
b583f10270 - Connect a new Win32 process to the window station, as it's supposed to be done. However, desktop inheritance still needs to be checked. There is some testing code in connect_process_winstation left #if0ed out.
svn path=/branches/arwinss/; revision=42379
2009-08-04 12:13:26 +00:00
Aleksey Bragin
ea3c904ba1 - Merge 42376 (along with committing a merge history leftover from a previous merge).
svn path=/branches/arwinss/; revision=42377
2009-08-03 21:06:49 +00:00
Aleksey Bragin
4c47435815 - Stick missing winternl.h include to fix compiling until a better solution is found.
svn path=/branches/arwinss/; revision=42370
2009-08-03 18:42:23 +00:00
Kamil Hornicek
abaf4d9e9e - clip text
svn path=/branches/arwinss/; revision=42361
2009-08-03 13:31:19 +00:00
Aleksey Bragin
e0262096ad - Create stock bitmap in win32k and use it whenever a stock bitmap is selected into the DC.
- Bring in GDIOBJ_ConvertToStockObj from trunk.
- Fixes arwinss issue nr. 7.

svn path=/branches/arwinss/; revision=42348
2009-08-02 20:53:12 +00:00
Aleksey Bragin
c6f0a6de8a - Remove _NTDRIVER_ define, in arwinss freetype is built as a usual usermode dll.
svn path=/branches/arwinss/; revision=42347
2009-08-02 20:51:16 +00:00
Aleksey Bragin
1e9d38626b - Remove unnecessary hack from RosDrv_GetTextMetrics. Text output now is nearly perfect. See arwinss issue nr. 6.
svn path=/branches/arwinss/; revision=42343
2009-08-02 18:18:58 +00:00
Aleksey Bragin
5212c79ee4 - Initialize size field of font_mapping structure, this fixes freetype font loading errors (see arwinss issue nr. 6).
- Add mapping lookup, in case that process already mapped it, so mapping will just be reused.
- Add unmapping support, so if process closes, no mapping leaks occur.

svn path=/branches/arwinss/; revision=42341
2009-08-02 17:32:22 +00:00
Aleksey Bragin
401a0ad91b - Move GDIPOINTER inside DEVOBJ, where it belongs.
- Bring in and use mouse safety functions from trunk.

svn path=/branches/arwinss/; revision=42340
2009-08-02 17:06:38 +00:00
Kamil Hornicek
a41b2094b9 - add support for ETO_OPAQUE
svn path=/branches/arwinss/; revision=42336
2009-08-02 13:37:22 +00:00
Aleksey Bragin
b4541589c9 - Handle case when RosGdiSetDeviceClipping is being called without rects at all (with a respective DPRINT1).
- Use combined clipping object everywhere to ensure drawing happens only in allowed rectangle, see arwinss nr. 15. As a side effect, it fixes FireFox and other apps which would corrupt memory if trying to blit to area outside of DC.
- Enable commented out XLATE object creation in GreStretchBltMask. Start menu icons now get masked properly too, but still are black.

svn path=/branches/arwinss/; revision=42333
2009-08-02 10:32:57 +00:00
Aleksey Bragin
1e288094a0 - Capture user's buffer using SEH in RosGdiSetDeviceClipping.
- Offset combined clipping region by DC and viewport origins, which was the problem preventing its usage.
- Remove unneeded stuff from RosGdiSetDcRects. Setting DC rects to fullscreen dimensions is done in usermode.

svn path=/branches/arwinss/; revision=42332
2009-08-02 09:56:44 +00:00
Aleksey Bragin
7111873809 - Set drawable rect back to full screen size when releasing a DC.
svn path=/branches/arwinss/; revision=42331
2009-08-02 08:45:28 +00:00
Aleksey Bragin
93fe826934 - Remove GreatLord's "uberoptimized" DIB_32BPP_ColorFill since it doesn't really conform to any calling convention and doesn't correctly set up ebp and esp as it should. As an example of such actions it's impossible to have a backtrace if an exception occurs in this function.
svn path=/branches/arwinss/; revision=42326
2009-08-01 19:00:07 +00:00
Aleksey Bragin
1803cc9dd6 Giannis Adamopoulos
- Remove hardcoded dependency to 800x600 (and 640x480 in monitor functions) display size (see arwinss issue nr. 18), explorer now correctly shows its desktop on a full screen.

svn path=/branches/arwinss/; revision=42325
2009-08-01 18:24:39 +00:00
Aleksey Bragin
f85952f4d4 - Switch arwinss win32k to the GDI object manager from trunk. gdiobj.c is cleaned up from functions which aren't used in arwinss, and the user<->kernel handle mapping still remains. The only supported object types now are DC, SURFACE and PALETTE. (see arwinss issue nr. 14).
- Kernelmode GDI handles leak now very significantly. To be investigated.

svn path=/branches/arwinss/; revision=42320
2009-07-31 22:08:01 +00:00
Aleksey Bragin
15a8ae38d4 - Merge: gschneider * r42318 reactos/subsystems/win32/win32k/eng/mouse.c: Fix a typo in EngMovePointer.
svn path=/branches/arwinss/; revision=42319
2009-07-31 20:13:27 +00:00
Aleksey Bragin
41bb246071 - Use a default MIX value instead of 0.
svn path=/branches/arwinss/; revision=42308
2009-07-30 19:06:21 +00:00
Aleksey Bragin
4fce4bc781 - Use Xlate object in GreBitBlt. Icons are still black, but have correct shape now.
svn path=/branches/arwinss/; revision=42307
2009-07-30 18:52:03 +00:00
Aleksey Bragin
4149b715d1 - Implement CURSORICON_Copy.
svn path=/branches/arwinss/; revision=42304
2009-07-30 17:38:48 +00:00
Aleksey Bragin
ff981e6202 - Actually do set bitmap bits if RosGdiCreateBitmap was provided with bits.
- Add helper GreSetBitmapBits function implementation.

svn path=/branches/arwinss/; revision=42301
2009-07-30 13:09:59 +00:00
Aleksey Bragin
2fd1d89be7 - Uncomment access check for setting class info, but still leave the STATUS_ACCESS_DENIED case commented out with a mandatory debug print for debugging if it ever happens.
svn path=/branches/arwinss/; revision=42300
2009-07-30 13:08:50 +00:00
Aleksey Bragin
500f803c49 - Bring in a modified GetIconInfo implementation to get rid of a graphics driver api change.
svn path=/branches/arwinss/; revision=42299
2009-07-30 09:52:21 +00:00
Aleksey Bragin
43f9708807 - Usermode GDI handles are per-process, not global! Fix this assumption when mapping usermode handles to global kernelmode handles. Fixes a lot of weird crashes happening due to wrong surface objects usage.
svn path=/branches/arwinss/; revision=42297
2009-07-30 08:59:02 +00:00
Aleksey Bragin
899ac7e157 - Unstub get_atom_information request.
svn path=/branches/arwinss/; revision=42292
2009-07-29 20:39:39 +00:00
Aleksey Bragin
0c3e675ece - Silence RealizeDefaultPalette call.
- Remove some testing code from userdrv, and silence tracing debug prints there too.

svn path=/branches/arwinss/; revision=42290
2009-07-29 15:44:37 +00:00
Aleksey Bragin
098f51e7bc - Silence most of debug warnings. Only errors should have DPRINT1 now.
svn path=/branches/arwinss/; revision=42289
2009-07-29 15:42:53 +00:00
Aleksey Bragin
cf5837f5cb - GDIO_GetObjPtr: Don't go through handles array without obtaining a lock.
svn path=/branches/arwinss/; revision=42288
2009-07-29 15:29:50 +00:00
Aleksey Bragin
19bdfd92d8 - Implement EngDeletePalette.
svn path=/branches/arwinss/; revision=42287
2009-07-29 13:42:26 +00:00
Aleksey Bragin
6458526939 - RosGdiSelectBitmap: In case it gets an unknown bitmap, create a stock bitmap and select it. But warning is still printed for further investigation.
- RosGdiSelectBrush: Nullify selected brush pointer after freeing last selected brush. It helps tracking selection failures.
- RosGdiSelectBrush: Create a NULL brush if requested.
- RosGdiSelectPen: Don't free previously selected brush if selecting new pen fails.

svn path=/branches/arwinss/; revision=42286
2009-07-29 13:40:32 +00:00
Aleksey Bragin
d0ab23c511 - Uncomment mouse safety code in BitBlt (it doesn't do anything since it's stubbed anyway).
- Add GreCreateNullBrush for creating NULL brushes.
- Allocate/free surface objects using Eng routines using TAG_SURFOBJ.

svn path=/branches/arwinss/; revision=42285
2009-07-29 13:32:00 +00:00
Aleksey Bragin
7ce8ed5349 - Add surface object allocation tag.
svn path=/branches/arwinss/; revision=42284
2009-07-29 13:29:26 +00:00
Aleksey Bragin
b47c56cd08 - SwitchDesktop: Fix SetWindowPos call to not alter desktop's height and width but just make it visible.
svn path=/branches/arwinss/; revision=42274
2009-07-28 14:36:17 +00:00
Aleksey Bragin
7bbfc5d36e Giannis Adamopoulos
- Add minimal mouse input support to the gdi/user driver:
 * Implement SendInput and SetCursor
 * Bring in some helper functions from winex11.drv driver

svn path=/branches/arwinss/; revision=42273
2009-07-28 14:33:16 +00:00
Aleksey Bragin
17fa55509e Giannis Adamopoulos
- Implement mouse input thread support in win32csr (based on win32k/ntuser/input.c from trunk).

svn path=/branches/arwinss/; revision=42272
2009-07-28 14:23:34 +00:00
Aleksey Bragin
fa429e0ed4 - Add XBUTTONx defines.
svn path=/branches/arwinss/; revision=42271
2009-07-28 14:18:48 +00:00
Aleksey Bragin
6b2f967661 Giannis Adamopoulos
- Bring in mouse pointer functions to engpoint.c from trunk.
- Implement kernelmode part of mouse cursor support.

svn path=/branches/arwinss/; revision=42270
2009-07-28 14:12:29 +00:00
Aleksey Bragin
e38a6b684d - Add declarations of cursor related RosUser APIs.
svn path=/branches/arwinss/; revision=42269
2009-07-28 14:10:13 +00:00
Aleksey Bragin
4831d192e2 Giannis Adamopoulos
- Implement table growing in add_atom_entry, grow_handle_table and add_handle_to_array.
- Uncomment all_windows_from_point and get_window_children_from_point.

svn path=/branches/arwinss/; revision=42267
2009-07-28 13:50:45 +00:00
Aleksey Bragin
8f3df48789 - Make desktop window occupy whole primary surface (as usual, dimensions are hacked to 800x600 with a corresponding // FIXME:) if it's size is set to 0x0 at creation time. This fixes a number of window drawing problems, particularly arwinss issue nr. 5.
svn path=/branches/arwinss/; revision=42266
2009-07-28 13:11:22 +00:00
Aleksey Bragin
6e20e52fb7 - Remove the CSR show desktop notification. This is a leftover from 42231.
svn path=/branches/arwinss/; revision=42258
2009-07-27 20:22:10 +00:00
Aleksey Bragin
a55b756560 - Never release the user lock when processing a user server request! The user lock was being released to perform a csr notification (it still happens this way in trunk) allowing another request to start processing. Fix this by moving csr notification outside the user lock.
- Don't rely on a reqinfo->data_count but use a simple boolean var for tracking the memory which must be freed.

svn path=/branches/arwinss/; revision=42231
2009-07-26 13:13:00 +00:00
Aleksey Bragin
5410752ffe - Actually just add RtlNtStatusToDosError declaration to wineserver_call_err to kill dependency on complex header sets.
svn path=/branches/arwinss/; revision=42207
2009-07-25 13:17:38 +00:00
Aleksey Bragin
262c3859a8 - Merge 42202: Create a solid black brush for background color of a ConsoleWindowClass.
svn path=/branches/arwinss/; revision=42203
2009-07-25 10:27:27 +00:00
Aleksey Bragin
c2d2884484 - Hack atom support in kernel32 to call user server for global atom information. Ugly, crappy, will be deprecated once the move to proper atoms support happens. But for now it provides consistency with win32k/user32.
svn path=/branches/arwinss/; revision=42201
2009-07-25 09:56:27 +00:00
Aleksey Bragin
774150e744 - Remove unnecessary inclusion from wine/server.h.
svn path=/branches/arwinss/; revision=42200
2009-07-25 09:53:06 +00:00
Aleksey Bragin
e3e0e4d4f3 - Move winternl.h inclusion from wine/server.h to the actual C files. Next step could be killing winternl.h usage.
- Slightly experiment with SwitchDesktop, doesn't fix anything yet.

svn path=/branches/arwinss/; revision=42199
2009-07-25 09:52:04 +00:00
Aleksey Bragin
a489c31aa9 - Implement shrink_handle_table though this code (along with the object.c) will be deprecated in future.
svn path=/branches/arwinss/; revision=42184
2009-07-24 21:33:28 +00:00
Aleksey Bragin
44d7197980 - PsLookupProcess/Thread already references the object, so don't reference it yet again! Thaaaaank you Stefan Ginsberg. Fixes a rather big reference leak.
See arwinss issue Nr 2.

svn path=/branches/arwinss/; revision=42183
2009-07-24 21:19:50 +00:00
Aleksey Bragin
0f31b35b3c - Implement desktop_close_handle. It is the second place in winstation.c which directly relies on ETHREAD's internal members for enumerating threads of a process. Should be reimplemented in a more compatible way, but so far it works in ReactOS and Windows 2003.
- Sticked // FIXME where appropriate.

svn path=/branches/arwinss/; revision=42181
2009-07-24 21:00:17 +00:00
Aleksey Bragin
8c330813fc - Commit an evil hack which sets desktop's window to 800x600 in win32csr and redraws it to make it visible. This brings us the so missed desktop background and is going to aid in debugging further problems.
svn path=/branches/arwinss/; revision=42160
2009-07-23 19:27:06 +00:00
Aleksey Bragin
3c49d76565 - Don't link win32csr to win32k syscalls library.
svn path=/branches/arwinss/; revision=42159
2009-07-23 19:24:45 +00:00
Aleksey Bragin
344accda4e - Convert color from COLORREF to device's color space. Fixes RGB/BGR issue with text output, brushes and pens.
- Don't use a stack allocated BRUSHOBJ for text output, because other routines may rely on it being a real BRUSHGDI object. Create a pen for text output instead (once per TextOut call, an optimisation could be to move that to DC structure and create once).

svn path=/branches/arwinss/; revision=42158
2009-07-23 19:20:00 +00:00
Aleksey Bragin
0f8f3229c1 - User server: only copy variable length data to the caller if a buffer was provided. Otherwise notify via a debug print that no buffer was provided. Fixes a crash at repainting.
svn path=/branches/arwinss/; revision=42154
2009-07-23 13:16:59 +00:00
Aleksey Bragin
e79ab6500a - Kill another 16 bit support crappiness.
svn path=/branches/arwinss/; revision=42142
2009-07-22 12:45:42 +00:00
Aleksey Bragin
e04a3c4bf2 - Silent debug prints in eng/engsurf.c.
- Fix a typo in the comments of gdi/misc.c.
- Offset source point in BitBlt by vport origin too.
- Offset coordinates once in GreTextOut, so that SharpGlyphMono works with already offsetted device coordinates.
- Offset coordinates by vport origin in GrePolyline and GreRectangle.

svn path=/branches/arwinss/; revision=42141
2009-07-22 12:17:20 +00:00
Kamil Hornicek
56ff138104 - draw text with the foreground color
svn path=/branches/arwinss/; revision=42139
2009-07-22 11:24:35 +00:00
Aleksey Bragin
b7a887cdbf - Add user buffer probing and copying to RosGdiPolygon.
- Offset all points before calling the GrePolygon function.

svn path=/branches/arwinss/; revision=42137
2009-07-22 10:24:08 +00:00
Aleksey Bragin
8193989f54 - Remove wake_up, this became an unneeded wineism now.
- Silence timeout_user debug prints.

svn path=/branches/arwinss/; revision=42136
2009-07-22 09:52:08 +00:00
Aleksey Bragin
c32b3e0ad7 - Create an event for every message queue and return its handle for the user driver to wait on. This fixes "active" looping in all GetMessage loops, which actually made the system feel soo slow.
- Turn two DPC callbacks (timer and timeout) to allocate and schedule work items instead of processing everything inside the DPC, because the processing may result in a KePulseEvent call.
- Change message queue and msg_result to be allocated from a nonpaged pool, because they are accessed inside DPCs.
- TODO: Add locking to prevent message queue lists corruption from concurrent access.

svn path=/branches/arwinss/; revision=42135
2009-07-22 08:53:28 +00:00
Aleksey Bragin
776fc7136f - It's fine to use kernel32's WaitForMultipleObjectsEx, it's going to be the same NtCreateEvent handle anyway. Thanks Alex for reminding. Win32k fix to follow.
svn path=/branches/arwinss/; revision=42134
2009-07-22 08:44:41 +00:00
Aleksey Bragin
d0190056f5 - Fix user driver's MsgWaitForMultipleObjectsEx implementation to call native NtWaitForMultipleObjects instead of kernel32's WaitForMultipleObjects. Next commit will fix the corresponding win32k counter part to provide it a correct handle. Winex11.drv should be fixed in a similar way.
- Disable move_window_bits invocation for now, so it doesn't distort the picture.

svn path=/branches/arwinss/; revision=42133
2009-07-22 08:31:39 +00:00
Aleksey Bragin
1e0bac3402 - Add polygon filling support to GrePolygon (previously only polygon outline was drawn).
svn path=/branches/arwinss/; revision=42106
2009-07-20 21:30:34 +00:00
Aleksey Bragin
20ea58988e - Fix build.
svn path=/branches/arwinss/; revision=42105
2009-07-20 21:28:10 +00:00
Aleksey Bragin
c0a8e52500 - Copy polygon filling algorithms from trunk's win32k.
svn path=/branches/arwinss/; revision=42099
2009-07-20 14:18:56 +00:00
Aleksey Bragin
aa1aaa5334 - Properly implement add_timeout_user / remove_timeout_user (thus eliminating non paged pool leakage of a test implementation).
- Debug prints are still turned on because remove_timeout_user seems to not being called.

svn path=/branches/arwinss/; revision=42098
2009-07-20 14:01:25 +00:00
Aleksey Bragin
91bd49d663 - Swap szWnd/szVport/ptWndOrg/ptVportOrg to two rectangles: Vport one, and DC one. The DC one is relative to the Vport one.
- Set both DC and Vport rectangles from the winent driver. Setting them back to fullscreen is not supported now, but since only their origins (top,left) are used now - it's ok.
- Offset all graphic operations by the Vport offset too. Now graphics is displayed at correct places inside windows, including text output too.
- Silence font.c debug prints.
- Add inlined functions for RECTL management (set, offset, check for emptyness) from the trunk's win32k.

svn path=/branches/arwinss/; revision=42097
2009-07-20 13:33:16 +00:00
Aleksey Bragin
12c10146bc - Add CsrNotifyShowDesktop CSR notification, not used now and its future is unclear.
svn path=/branches/arwinss/; revision=42096
2009-07-20 12:04:51 +00:00
Kamil Hornicek
9cd89b9fa8 - plug in code previously #ifed out
- fix some warnings
- some quick 'n dirty fixes, WIP
- fonts should load now

svn path=/branches/arwinss/; revision=42095
2009-07-20 01:24:47 +00:00
Kamil Hornicek
261b5f7af5 - add regglue.c for now, it contains APIs needed by freetype
svn path=/branches/arwinss/; revision=42094
2009-07-20 01:08:50 +00:00
Kamil Hornicek
ac4aceee3f - go through all fonts in the requested directory and load them
svn path=/branches/arwinss/; revision=42093
2009-07-20 01:03:19 +00:00
Aleksey Bragin
13561925f6 - Set window proc for the desktop background window. Now, the CsrShowDesktop call is missing.
svn path=/branches/arwinss/; revision=42091
2009-07-19 20:34:00 +00:00
Aleksey Bragin
06c8b49926 - Fix win32csr build (get rid of NtUserInitialize invocation).
- Don't create the desktop window class (looks like a hack).

svn path=/branches/arwinss/; revision=42090
2009-07-19 18:53:22 +00:00
Aleksey Bragin
c19eb08f78 - Fix build by disabling registry related code for now (advapi32 is not available for linking).
svn path=/branches/arwinss/; revision=42085
2009-07-19 12:32:42 +00:00
Aleksey Bragin
18ca34d21c - Enable usermode font engine in gdi32.
svn path=/branches/arwinss/; revision=42084
2009-07-19 12:31:17 +00:00
Aleksey Bragin
5600234842 - Remove ftfd from build (it depends on a kernel-mode-built freetype library).
svn path=/branches/arwinss/; revision=42083
2009-07-19 12:29:35 +00:00
Aleksey Bragin
0368db8274 - Build freetype as a usual win32 dll.
svn path=/branches/arwinss/; revision=42082
2009-07-19 12:27:58 +00:00
Aleksey Bragin
a3cfb65ccf - Import a native GDI driver implementation. It uses custom win32k syscalls (RosGdi* and RosUser*) to achieve fast graphics output.
Work in progress!
Fully developed by me with some small code pieces taken from winex11.drv.

svn path=/branches/arwinss/; revision=42081
2009-07-19 12:13:47 +00:00
Aleksey Bragin
2c81f1a12e - Export functions needed by DDI drivers.
svn path=/branches/arwinss/; revision=42080
2009-07-19 12:09:41 +00:00
Aleksey Bragin
00431b0b7e - Move user32 and gdi32 baseaddresses to prevent relocation.
- Add an entry for native GDI driver.

svn path=/branches/arwinss/; revision=42079
2009-07-19 11:35:51 +00:00
Aleksey Bragin
21e271e0ea - Initialize graphics parts of win32k since we have them now.
svn path=/branches/arwinss/; revision=42078
2009-07-19 08:14:49 +00:00
Aleksey Bragin
7bbf7660ae - Add missing font rendering quality types.
- Add specific GGO and TT flags wrapped into #ifdef __WINESRC__. For internal usage only.

svn path=/branches/arwinss/; revision=42077
2009-07-19 08:11:01 +00:00
Aleksey Bragin
620594e51f - Uncomment RosUserConnectCsrss call since it's now implemented in win32k.
svn path=/branches/arwinss/; revision=42075
2009-07-18 22:29:19 +00:00
Aleksey Bragin
3d41402b1b - Greatly improve win32k by implementing a graphics counterpart of the GDI. It interacts with the to-be-committed GDI driver DLL via a set of RosGdi* and RosUser* syscall APIs. Some of the code is imported from ReactOS, Eng stubs are imported from nwin32 and made by Stefan Ginsberg (all copyrights information is in respective files), everything else is developed by me.
svn path=/branches/arwinss/; revision=42074
2009-07-18 22:25:30 +00:00
Aleksey Bragin
7f0c50e395 - Win32k's main include file is win32k.h, not w32k.h in this branch.
svn path=/branches/arwinss/; revision=42072
2009-07-18 22:14:08 +00:00
Aleksey Bragin
9670892119 - Prepare for importing a new winent driver and further work on win32k: add two header files:
* ntrosgdi.h (should be renamed to rosgdi.h) - RosGdi* system calls.
 * rosuser.h - RosUser* system calls.

svn path=/branches/arwinss/; revision=42070
2009-07-18 19:52:36 +00:00
Aleksey Bragin
d123a8672c - Add a precompiled libX11.a lib. It's made from an Xming official source code tarball crosscompiled in a latest Ubuntu release. In order to use, copy this file to obj-i386/lib/3rdparty/libX11.
svn path=/branches/arwinss/; revision=42067
2009-07-18 19:43:40 +00:00
Aleksey Bragin
177fd67597 - Remove unneeded files.
- #ifdef 0 incompatible code.
- winex11 fully builds.

svn path=/branches/arwinss/; revision=42066
2009-07-18 19:37:33 +00:00
Aleksey Bragin
91a00aed24 - Add wine/port.h to event.c to have POLL* defines.
- Add XBUTTON* defines to x11drv.h.
- Add HAVE_POLL section to wine/port.h.

svn path=/branches/arwinss/; revision=42063
2009-07-18 19:18:18 +00:00
Aleksey Bragin
05c394297f - Add two WineX11-specific mouse event flags.
- Add an OEM specific VK code.

svn path=/branches/arwinss/; revision=42062
2009-07-18 19:15:34 +00:00
Aleksey Bragin
e4fc7762c0 - Add winex11.drv to the build.
- Import poll.c from wine/port.h.
- Add supporting code in rosglue.c.

svn path=/branches/arwinss/; revision=42061
2009-07-18 19:07:50 +00:00
Aleksey Bragin
83fc370184 - Add libX11 placeholder.
svn path=/branches/arwinss/; revision=42060
2009-07-18 18:59:02 +00:00
Aleksey Bragin
caa6424393 - Bring atan2 implementation from crt. Please excuse me for this hack, but gdi32 can't link to msvcrt, and ntdll doesn't export atan2. Static linkage to crt doesn't work either.
- Remove advapi32 from the list of included DLLs, gdi32 must NOT link to advapi32, otherwise a circular dependency happens.
- Remove ASSERT macro definition.
- gdi32 builds without any errors or warnings.

svn path=/branches/arwinss/; revision=42059
2009-07-18 18:53:05 +00:00
Aleksey Bragin
0cac18f69e - Import winex11.drv from Wine.
svn path=/branches/arwinss/; revision=42057
2009-07-18 18:38:55 +00:00
Aleksey Bragin
37eddd4ab1 - Bring back an accidentally removed function stub.
svn path=/branches/arwinss/; revision=42056
2009-07-18 18:35:56 +00:00
Aleksey Bragin
9a05189a01 - Temporary comment out most of multilanguage resources.
- Get rid of even more 16 bit crap in edit.c.
- user32.dll now builds.

svn path=/branches/arwinss/; revision=42055
2009-07-18 17:58:06 +00:00
Aleksey Bragin
a867f103e7 - Update headers.
- Remove ROS HACK from windef16.h.
- Add an empty placeholder header file rosuser.h.

svn path=/branches/arwinss/; revision=42053
2009-07-18 17:54:20 +00:00
Aleksey Bragin
5ac9bef03c - Include csr.c into the build.
- Temporarily add EngGetTickCount implementation to winesup.c.
- win32k now fully builds.

svn path=/branches/arwinss/; revision=42050
2009-07-18 13:37:05 +00:00
Aleksey Bragin
caa3056ce4 - Fix two memory freeing leftovers.
svn path=/branches/arwinss/; revision=42049
2009-07-18 13:35:10 +00:00
Aleksey Bragin
e234c3b21c - Fix some of build problems related to newer headers.
svn path=/branches/arwinss/; revision=42048
2009-07-18 13:33:33 +00:00
Aleksey Bragin
6ed3e6f46c - Implement CSR interaction function - ReactOS specific!
svn path=/branches/arwinss/; revision=42047
2009-07-18 13:31:51 +00:00
Aleksey Bragin
4e2d2ce912 - Port server headers too (use our process/thread structures instead of theirs, etc).
- Start improving the win32k private header.

svn path=/branches/arwinss/; revision=42046
2009-07-18 12:48:05 +00:00
Aleksey Bragin
0cb3055dd0 - Improve header for ported code.
svn path=/branches/arwinss/; revision=42045
2009-07-18 12:46:44 +00:00
Aleksey Bragin
710788d832 - Use custom PROCESSINFO and THREADINFO structures for keeping Win32 specific information.
svn path=/branches/arwinss/; revision=42044
2009-07-18 12:44:11 +00:00
Aleksey Bragin
6f1915aba0 - Fix win32k process and thread callouts.
- Do proper initialization.

svn path=/branches/arwinss/; revision=42043
2009-07-18 12:41:27 +00:00
Aleksey Bragin
f37a3a2124 - Implement set_error, get_error.
- Implement add_timeout_user, remove_timeout_user (Testmode implementation! Currently leaks memory!).
- Implement a ExReallocPool routine. The name is stupid, but it reallocates the given paged pool to another (smaller or bigger) size preserving the data.
- Other misc routines needed for ported server code.

svn path=/branches/arwinss/; revision=42042
2009-07-18 12:38:04 +00:00
Aleksey Bragin
9e2e9361c1 - Implement proper "wine server" invocations support, including variable data requests (both to and from the server).
- Add global synch, so that our server deals only with one caller at a time.

svn path=/branches/arwinss/; revision=42041
2009-07-18 12:35:59 +00:00
Aleksey Bragin
9bfddc8760 - Similarly port other needed components to kernelmode.
svn path=/branches/arwinss/; revision=42040
2009-07-18 12:33:44 +00:00
Aleksey Bragin
45f64fe28f - Fix include headers.
- Change memory allocations to pool allocations.
- Reference/dereference process and thread objects using NT's object manager.
- Disable current process check in set_class_info request, a "Fixme!" debug print for reminding. 

svn path=/branches/arwinss/; revision=42039
2009-07-18 11:53:20 +00:00
Aleksey Bragin
099d91f129 - Fix include headers.
- Change memory allocations to pool allocations.

svn path=/branches/arwinss/; revision=42038
2009-07-18 11:50:12 +00:00
Aleksey Bragin
a58861c5a0 - One leftover header, copying from wineserver.
svn path=/branches/arwinss/; revision=42037
2009-07-18 11:48:23 +00:00
Aleksey Bragin
627cb97e3c - Rename "gre" to "main" since it better describes the contents.
svn path=/branches/arwinss/; revision=42036
2009-07-18 11:47:01 +00:00
Aleksey Bragin
d41abfee15 - Add X11 headers.
svn path=/branches/arwinss/; revision=42035
2009-07-18 11:40:18 +00:00
Aleksey Bragin
9d9379a6c3 - Import the following from a wineserver:
* Wine's object manager
 * Window classes support
 * Atoms support
 * Handles support
 * Windows stations
 * Object directory
 * Windows support
 * Region implementation
 * Queue and user functions

svn path=/branches/arwinss/; revision=42034
2009-07-18 09:46:29 +00:00
Aleksey Bragin
3eec12f4d8 - Bring in two more headers from wineserver.
svn path=/branches/arwinss/; revision=42033
2009-07-18 09:41:02 +00:00
Aleksey Bragin
adb5baa1f1 - Fix Wine-server interface to allow data transfer, first version.
svn path=/branches/arwinss/; revision=42032
2009-07-18 09:39:24 +00:00
Aleksey Bragin
7aed2e2bf5 - Add win32 thread infrastructure.
- Cleanup win32 process/thread info structures.

svn path=/branches/arwinss/; revision=42031
2009-07-18 09:35:40 +00:00
Aleksey Bragin
698c7094a9 - Add basic Win32k infrastructure: W32PROCESS and W32THREAD, global user heap.
svn path=/branches/arwinss/; revision=42030
2009-07-18 09:34:22 +00:00
Aleksey Bragin
dbe4d860d9 - Stub all Wine server calls as UNIMPLEMENTED.
svn path=/branches/arwinss/; revision=42029
2009-07-18 09:30:26 +00:00
Aleksey Bragin
cf1ec1bc3b - Remove unneeded stuff.
svn path=/branches/arwinss/; revision=42028
2009-07-18 09:26:43 +00:00
Aleksey Bragin
ac3ed8e80b - Copy request.h header from Wine server to win32k private headers.
- Fix server protocol include header.

svn path=/branches/arwinss/; revision=42027
2009-07-18 09:25:25 +00:00
Aleksey Bragin
66abd7dd16 - Add a temporary hack to SwitchDesktop.
- Temporary disable saving system parameters to the registry. It seems to do it wrong.
- Add a native assert implementation, this was the last bit which fixed MSVCRT-linkage completely.
- Disable TRY/FINALLY block in menu.c since it has perverted syntax.
- Don't use errno.
- Use _snprintf instead of snprintf.
- Get rid of imm32.dll dependency by #if0-defining a block of code (a debug mark is put there instead).
- Implement PrivateCsrssInitialized.
- Fix a warning.
- 16bit -> 32bit in cursoricon.c, resource.c (accelerators).
- Return success in RegisterServiceProcess.
- Disable debug print in USER_CheckNotLock.
- Get rid of another 16 bit history and move on to using Heap[Alloc/Realloc/Free] instead of the old Local* functions (user_private.h).
- Make ClientThreadSetup and UpdatePerUserSystemParameters stubs returning success.
- Remove more unneeded 16 bit crap from winproc.c.
- Fix user32 exports so it loads on Windows 2003.

svn path=/branches/arwinss/; revision=42026
2009-07-18 08:50:27 +00:00
Aleksey Bragin
54024432ce - Add assert/ASSERT implementation to prevent linking with a wrong msvcrt version of it.
- Fix one msvcrt function linkage (snprintf -> _snprintf).
- Stub out all other registry operations for now and thus get rid of advapi32 dependancy (and unbreak the system).
- Start converting registry operations from advapi32 to native functions.
- Initial port of freetype.c to ReactOS. Many places are UNIMPLEMENTED yet.
- Implement GdiAddFontResourceW as a success-returning stub.
- Fix gdi32 exports so it loads on Windows 2003.
- 16->32 conversion in user32/cursoricon.
- Remove all calls to advapi's registry operations from gdi32 init and use defaults.

svn path=/branches/arwinss/; revision=42025
2009-07-18 08:29:27 +00:00
Aleksey Bragin
691e27e7a5 - Fix user32 compiling/linking.
- Add missing function declarations to winuser.h

svn path=/branches/arwinss/; revision=42024
2009-07-17 21:29:46 +00:00
Aleksey Bragin
8052f46bdf - Make win32k compile.
- Add "wine_server_call" system entry.
- Adapt Wine's server.h to use it.

svn path=/branches/arwinss/; revision=42023
2009-07-17 21:19:09 +00:00
Aleksey Bragin
a687c08abf - Header fixes to add to the previous commit.
svn path=/branches/arwinss/; revision=42022
2009-07-17 20:47:28 +00:00
Aleksey Bragin
24c8503bf0 - More fixes, stubbing out, commenting out..
- More 16bit crap removal.

svn path=/branches/arwinss/; revision=42021
2009-07-17 20:45:32 +00:00
Aleksey Bragin
c863e2b6c3 - Start removing 16bit crap, and stub needed stuff for now.
svn path=/branches/arwinss/; revision=42020
2009-07-17 20:39:01 +00:00
Aleksey Bragin
357c85153b - Add more missing defines to PSDK headers.
- User32 almost compiles, but a lot of serious warnings are there.

svn path=/branches/arwinss/; revision=42019
2009-07-17 20:34:31 +00:00
Aleksey Bragin
62cc3a97b4 - Make user32 compile, part 1.
svn path=/branches/arwinss/; revision=42018
2009-07-17 19:42:17 +00:00
Aleksey Bragin
c40a92b9b1 - Fix headers, work in progress, contains undocumented stuff from Wine going into PSDK. Should be separated later.
- Import server.h and server_protocol.h from Wine-1.1.25.

svn path=/branches/arwinss/; revision=42017
2009-07-17 19:25:10 +00:00
Aleksey Bragin
3708634af8 - Add more EMR_ types (a leftover from a pre-previous commit).
svn path=/branches/arwinss/; revision=42014
2009-07-17 19:13:57 +00:00
Aleksey Bragin
599c8fcf33 - Get gdi32.dll to compile. It doesn't link due to absence of atan2.
- EnhMetaFile stuff is stubbed.
- SysLevel stuff substituted by critical sections.
- 16 bit stuff ifdefed away.
- #include <ddrawgdi.h> in driver.c temporary commented out.

svn path=/branches/arwinss/; revision=42013
2009-07-17 19:13:14 +00:00
Aleksey Bragin
241a312053 - Update wingdi.h with new stuff from Wine.
svn path=/branches/arwinss/; revision=42010
2009-07-17 18:23:48 +00:00
Aleksey Bragin
f0ea593d65 - Add .rbuild and .rc files for gdi32 and user32.
svn path=/branches/arwinss/; revision=42009
2009-07-17 18:08:01 +00:00
Aleksey Bragin
57f5a59497 - Remove tests and 16 bit stuff.
svn path=/branches/arwinss/; revision=42008
2009-07-17 18:05:01 +00:00
Aleksey Bragin
3c37dcd40b - Copy Wine's gdi32 and user32.
svn path=/branches/arwinss/; revision=42007
2009-07-17 18:02:01 +00:00
Aleksey Bragin
854cba9577 - Import some win32k parts from nwin32 branch.
svn path=/branches/arwinss/; revision=42002
2009-07-17 13:08:57 +00:00
Aleksey Bragin
df2aaf6233 - Totally clean win32k, gdi32 and user32 in preparation for a rewrite.
svn path=/branches/arwinss/; revision=42001
2009-07-17 13:02:54 +00:00
20744 changed files with 241984 additions and 7649156 deletions

7
arwinss/CMakeLists.txt Normal file
View File

@@ -0,0 +1,7 @@
# Give ARWIN subsystem its own project.
PROJECT(ARWINSS)
add_subdirectory(client)
add_subdirectory(server)
add_subdirectory(freetype)

View File

@@ -0,0 +1,41 @@
So to sum up all the ideas + how arwinss would fit:
win32ss\user\user32
win32ss\user\ntuser
win32ss\user\win32csr
win32ss\gdi\gdi32
win32ss\gdi\ntgdi
win32ss\gdi\eng
win32ss\gdi\dib
win32ss\include
win32ss\misc
win32ss\reactx\ntddraw
win32ss\reactx\ddraw
win32ss\reactx\d3d*
win32ss\reactx\dxapi
win32ss\reactx\dxg
win32ss\reactx\dxgthk
win32k = ntuser + ntgdi + eng + dib + ntddraw
arwinss\user\user32 (wine's user32)
arwinss\user\userdrv ('driver dll' that connects wine's user32 to win32k)
arwinss\user\ntuser (mostly shared parts like keyboard layouts, monitors, DisplaySettings)
arwinss\user\win32csr (same with trunk + minor changes)
arwinss\user\wineserver (parts of wine's server)
arwinss\gdi\gdi32 (wine's gdi32)
arwinss\gdi\gdidrv ('driver dll' that connects wine's gdi32 to win32k)
arwinss\gdi\ntgdi (glue code that connects trunk's gre with wine's gdi32)
arwinss\gdi\gre (part of trunk's gre)
arwinss\gdi\eng (trunk's eng)
arwinss\gdi\dib (trunk's dib)
arwinss\include
arwinss\misc (trunk's misc)
arwinss\reactx\ddraw
arwinss\reactx\d3d*
arwinss\reactx\wined3d
win32k = ntuser + ntgdi + eng + dib + wineserver
winent = userdrv + gdidrv
note that winent is a normal usermode dll that does all the system calls

View File

@@ -0,0 +1,4 @@
add_subdirectory(gdi32)
add_subdirectory(user32)
add_subdirectory(winent.drv)

View File

@@ -0,0 +1,60 @@
add_definitions(-DLANGPACK)
add_definitions(-D__WINESRC__)
add_definitions(-D_WINE)
include_directories(
include
${REACTOS_SOURCE_DIR}/include/reactos/wine
${REACTOS_SOURCE_DIR}/arwinss/include
${REACTOS_SOURCE_DIR}/lib/3rdparty/freetype/include
${REACTOS_SOURCE_DIR}/win32ss/include)
spec2def(gdi32.dll gdi32.spec ADD_IMPORTLIB)
list(APPEND SOURCE
atan2.c
bidi.c
bitblt.c
bitmap.c
brush.c
clipping.c
dc.c
dib.c
driver.c
eng.c
enhmetafile.c
enhmeta2.c
font.c
freetype.c
gdiobj.c
icm.c
mapping.c
metafile.c
opengl.c
painting.c
palette.c
path.c
pen.c
printdrv.c
region.c
regglue.c
historic.c
gdi32.rc
${CMAKE_CURRENT_BINARY_DIR}/gdi32_stubs.c
${CMAKE_CURRENT_BINARY_DIR}/gdi32.def)
add_library(gdi32 SHARED ${SOURCE})
set_module_type(gdi32 win32dll UNICODE)
target_link_libraries(gdi32
win32ksys
dxguid
wine
${PSEH_LIB})
add_importlibs(gdi32 user32 freetype usp10 msvcrt kernel32 ntdll)
#add_pch(gdi32 include/precomp.h)
add_cd_file(TARGET gdi32 DESTINATION reactos/system32 FOR all)

View File

@@ -15,13 +15,7 @@ double atan2 (double __y, double __x)
"fld %%st(0)"
: "=t" (__val) : "0" (__x), "u" (__y));
#else
__asm
{
fld __y
fld __x
fpatan
fstp __val
}
__val = linkme_atan2(__x, __y);
#endif /*__GNUC__*/
return __val;
}

669
arwinss/client/gdi32/bidi.c Normal file
View File

@@ -0,0 +1,669 @@
/*
* GDI BiDirectional handling
*
* Copyright 2003 Shachar Shemesh
* Copyright 2007 Maarten Lankhorst
* Copyright 2010 CodeWeavers, Aric Stewart
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*
* Code derived from the modified reference implementation
* that was found in revision 17 of http://unicode.org/reports/tr9/
* "Unicode Standard Annex #9: THE BIDIRECTIONAL ALGORITHM"
*
* -- Copyright (C) 1999-2005, ASMUS, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of the Unicode data files and any associated documentation (the
* "Data Files") or Unicode software and any associated documentation (the
* "Software") to deal in the Data Files or Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, and/or sell copies of the Data Files or Software,
* and to permit persons to whom the Data Files or Software are furnished
* to do so, provided that (a) the above copyright notice(s) and this
* permission notice appear with all copies of the Data Files or Software,
* (b) both the above copyright notice(s) and this permission notice appear
* in associated documentation, and (c) there is clear notice in each
* modified Data File or in the Software as well as in the documentation
* associated with the Data File(s) or Software that the data or software
* has been modified.
*/
#include "config.h"
#include <stdarg.h>
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winnls.h"
#include "usp10.h"
#include "wine/unicode.h"
#include "wine/debug.h"
#include "gdi_private.h"
WINE_DEFAULT_DEBUG_CHANNEL(bidi);
/* HELPER FUNCTIONS AND DECLARATIONS */
#define odd(x) ((x) & 1)
/*------------------------------------------------------------------------
Bidirectional Character Types
as defined by the Unicode Bidirectional Algorithm Table 3-7.
Note:
The list of bidirectional character types here is not grouped the
same way as the table 3-7, since the numberic values for the types
are chosen to keep the state and action tables compact.
------------------------------------------------------------------------*/
enum directions
{
/* input types */
/* ON MUST be zero, code relies on ON = N = 0 */
ON = 0, /* Other Neutral */
L, /* Left Letter */
R, /* Right Letter */
AN, /* Arabic Number */
EN, /* European Number */
AL, /* Arabic Letter (Right-to-left) */
NSM, /* Non-spacing Mark */
CS, /* Common Separator */
ES, /* European Separator */
ET, /* European Terminator (post/prefix e.g. $ and %) */
/* resolved types */
BN, /* Boundary neutral (type of RLE etc after explicit levels) */
/* input types, */
S, /* Segment Separator (TAB) // used only in L1 */
WS, /* White space // used only in L1 */
B, /* Paragraph Separator (aka as PS) */
/* types for explicit controls */
RLO, /* these are used only in X1-X9 */
RLE,
LRO,
LRE,
PDF,
/* resolved types, also resolved directions */
N = ON, /* alias, where ON, WS and S are treated the same */
};
/* HELPER FUNCTIONS */
/* the character type contains the C1_* flags in the low 12 bits */
/* and the C2_* type in the high 4 bits */
/*static __inline unsigned short get_char_typeW( WCHAR ch )
{
WORD CharType;
GetStringTypeW(CT_CTYPE1, &ch, 1, &CharType);
return CharType;
}*/
/* Convert the libwine information to the direction enum */
static void classify(LPCWSTR lpString, WORD *chartype, DWORD uCount)
{
static const enum directions dir_map[16] =
{
L, /* unassigned defaults to L */
L,
R,
EN,
ES,
ET,
AN,
CS,
B,
S,
WS,
ON,
AL,
NSM,
BN,
PDF /* also LRE, LRO, RLE, RLO */
};
unsigned i;
for (i = 0; i < uCount; ++i)
{
chartype[i] = dir_map[get_char_typeW(lpString[i]) >> 12];
if (chartype[i] == PDF)
{
switch (lpString[i])
{
case 0x202A: chartype[i] = LRE; break;
case 0x202B: chartype[i] = RLE; break;
case 0x202C: chartype[i] = PDF; break;
case 0x202D: chartype[i] = LRO; break;
case 0x202E: chartype[i] = RLO; break;
}
}
}
}
/* Set a run of cval values at locations all prior to, but not including */
/* iStart, to the new value nval. */
static void SetDeferredRun(BYTE *pval, int cval, int iStart, int nval)
{
int i = iStart - 1;
for (; i >= iStart - cval; i--)
{
pval[i] = nval;
}
}
/* THE PARAGRAPH LEVEL */
/*------------------------------------------------------------------------
Function: resolveParagraphs
Resolves the input strings into blocks over which the algorithm
is then applied.
Implements Rule P1 of the Unicode Bidi Algorithm
Input: Text string
Character count
Output: revised character count
Note: This is a very simplistic function. In effect it restricts
the action of the algorithm to the first paragraph in the input
where a paragraph ends at the end of the first block separator
or at the end of the input text.
------------------------------------------------------------------------*/
static int resolveParagraphs(WORD *types, int cch)
{
/* skip characters not of type B */
int ich = 0;
for(; ich < cch && types[ich] != B; ich++);
/* stop after first B, make it a BN for use in the next steps */
if (ich < cch && types[ich] == B)
types[ich++] = BN;
return ich;
}
/* REORDER */
/*------------------------------------------------------------------------
Function: resolveLines
Breaks a paragraph into lines
Input: Array of line break flags
Character count
In/Out: Array of characters
Returns the count of characters on the first line
Note: This function only breaks lines at hard line breaks. Other
line breaks can be passed in. If pbrk[n] is TRUE, then a break
occurs after the character in pszInput[n]. Breaks before the first
character are not allowed.
------------------------------------------------------------------------*/
static int resolveLines(LPCWSTR pszInput, const BOOL * pbrk, int cch)
{
/* skip characters not of type LS */
int ich = 0;
for(; ich < cch; ich++)
{
if (pszInput[ich] == (WCHAR)'\n' || (pbrk && pbrk[ich]))
{
ich++;
break;
}
}
return ich;
}
/*------------------------------------------------------------------------
Function: resolveWhiteSpace
Resolves levels for WS and S
Implements rule L1 of the Unicode bidi Algorithm.
Input: Base embedding level
Character count
Array of direction classes (for one line of text)
In/Out: Array of embedding levels (for one line of text)
Note: this should be applied a line at a time. The default driver
code supplied in this file assumes a single line of text; for
a real implementation, cch and the initial pointer values
would have to be adjusted.
------------------------------------------------------------------------*/
static void resolveWhitespace(int baselevel, const WORD *pcls, BYTE *plevel, int cch)
{
int cchrun = 0;
BYTE oldlevel = baselevel;
int ich = 0;
for (; ich < cch; ich++)
{
switch(pcls[ich])
{
default:
cchrun = 0; /* any other character breaks the run */
break;
case WS:
cchrun++;
break;
case RLE:
case LRE:
case LRO:
case RLO:
case PDF:
case BN:
plevel[ich] = oldlevel;
cchrun++;
break;
case S:
case B:
/* reset levels for WS before eot */
SetDeferredRun(plevel, cchrun, ich, baselevel);
cchrun = 0;
plevel[ich] = baselevel;
break;
}
oldlevel = plevel[ich];
}
/* reset level before eot */
SetDeferredRun(plevel, cchrun, ich, baselevel);
}
/*------------------------------------------------------------------------
Function: BidiLines
Implements the Line-by-Line phases of the Unicode Bidi Algorithm
Input: Count of characters
Array of character directions
Inp/Out: Input text
Array of levels
------------------------------------------------------------------------*/
static void BidiLines(int baselevel, LPWSTR pszOutLine, LPCWSTR pszLine, const WORD * pclsLine,
BYTE * plevelLine, int cchPara, const BOOL * pbrk)
{
int cchLine = 0;
int done = 0;
int *run;
run = HeapAlloc(GetProcessHeap(), 0, cchPara * sizeof(int));
if (!run)
{
WARN("Out of memory\n");
return;
}
do
{
/* break lines at LS */
cchLine = resolveLines(pszLine, pbrk, cchPara);
/* resolve whitespace */
resolveWhitespace(baselevel, pclsLine, plevelLine, cchLine);
if (pszOutLine)
{
int i;
/* reorder each line in place */
ScriptLayout(cchLine, plevelLine, NULL, run);
for (i = 0; i < cchLine; i++)
pszOutLine[done+run[i]] = pszLine[i];
}
pszLine += cchLine;
plevelLine += cchLine;
pbrk += pbrk ? cchLine : 0;
pclsLine += cchLine;
cchPara -= cchLine;
done += cchLine;
} while (cchPara);
HeapFree(GetProcessHeap(), 0, run);
}
/*************************************************************
* BIDI_Reorder
*
* Returns TRUE if reordering was required and done.
*/
BOOL BIDI_Reorder(
HDC hDC, /*[in] Display DC */
LPCWSTR lpString, /* [in] The string for which information is to be returned */
INT uCount, /* [in] Number of WCHARs in string. */
DWORD dwFlags, /* [in] GetCharacterPlacement compatible flags specifying how to process the string */
DWORD dwWineGCP_Flags, /* [in] Wine internal flags - Force paragraph direction */
LPWSTR lpOutString, /* [out] Reordered string */
INT uCountOut, /* [in] Size of output buffer */
UINT *lpOrder, /* [out] Logical -> Visual order map */
WORD **lpGlyphs, /* [out] reordered, mirrored, shaped glyphs to display */
INT *cGlyphs /* [out] number of glyphs generated */
)
{
WORD *chartype;
BYTE *levels;
unsigned i, done, glyph_i;
int maxItems;
int nItems;
SCRIPT_CONTROL Control;
SCRIPT_STATE State;
SCRIPT_ITEM *pItems;
HRESULT res;
SCRIPT_CACHE psc = NULL;
WORD *run_glyphs = NULL;
WORD *pwLogClust = NULL;
SCRIPT_VISATTR *psva = NULL;
DWORD cMaxGlyphs = 0;
BOOL doGlyphs = TRUE;
TRACE("%s, %d, 0x%08x lpOutString=%p, lpOrder=%p\n",
debugstr_wn(lpString, uCount), uCount, dwFlags,
lpOutString, lpOrder);
memset(&Control, 0, sizeof(Control));
memset(&State, 0, sizeof(State));
if (lpGlyphs)
*lpGlyphs = NULL;
if (!(dwFlags & GCP_REORDER))
{
FIXME("Asked to reorder without reorder flag set\n");
return FALSE;
}
if (lpOutString && uCountOut < uCount)
{
FIXME("lpOutString too small\n");
return FALSE;
}
chartype = HeapAlloc(GetProcessHeap(), 0, uCount * sizeof(WORD));
if (!chartype)
{
WARN("Out of memory\n");
return FALSE;
}
if (lpOutString)
memcpy(lpOutString, lpString, uCount * sizeof(WCHAR));
/* Verify reordering will be required */
if ((WINE_GCPW_FORCE_RTL == (dwWineGCP_Flags&WINE_GCPW_DIR_MASK)) ||
((dwWineGCP_Flags&WINE_GCPW_DIR_MASK) == WINE_GCPW_LOOSE_RTL))
State.uBidiLevel = 1;
else
{
done = 1;
classify(lpString, chartype, uCount);
for (i = 0; i < uCount; i++)
switch (chartype[i])
{
case R:
case AL:
case RLE:
case RLO:
done = 0;
break;
}
if (done)
{
HeapFree(GetProcessHeap(), 0, chartype);
if (lpOrder)
{
for (i = 0; i < uCount; i++)
lpOrder[i] = i;
}
return TRUE;
}
}
levels = HeapAlloc(GetProcessHeap(), 0, uCount * sizeof(BYTE));
if (!levels)
{
WARN("Out of memory\n");
HeapFree(GetProcessHeap(), 0, chartype);
return FALSE;
}
maxItems = 5;
pItems = HeapAlloc(GetProcessHeap(),0, maxItems * sizeof(SCRIPT_ITEM));
if (!pItems)
{
WARN("Out of memory\n");
HeapFree(GetProcessHeap(), 0, chartype);
HeapFree(GetProcessHeap(), 0, levels);
return FALSE;
}
if (lpGlyphs)
{
cMaxGlyphs = 1.5 * uCount + 16;
run_glyphs = HeapAlloc(GetProcessHeap(),0,sizeof(WORD) * cMaxGlyphs);
if (!run_glyphs)
{
WARN("Out of memory\n");
HeapFree(GetProcessHeap(), 0, chartype);
HeapFree(GetProcessHeap(), 0, levels);
HeapFree(GetProcessHeap(), 0, pItems);
return FALSE;
}
pwLogClust = HeapAlloc(GetProcessHeap(),0,sizeof(WORD) * uCount);
if (!pwLogClust)
{
WARN("Out of memory\n");
HeapFree(GetProcessHeap(), 0, chartype);
HeapFree(GetProcessHeap(), 0, levels);
HeapFree(GetProcessHeap(), 0, pItems);
HeapFree(GetProcessHeap(), 0, run_glyphs);
return FALSE;
}
psva = HeapAlloc(GetProcessHeap(),0,sizeof(SCRIPT_VISATTR) * uCount);
if (!psva)
{
WARN("Out of memory\n");
HeapFree(GetProcessHeap(), 0, chartype);
HeapFree(GetProcessHeap(), 0, levels);
HeapFree(GetProcessHeap(), 0, pItems);
HeapFree(GetProcessHeap(), 0, run_glyphs);
HeapFree(GetProcessHeap(), 0, pwLogClust);
return FALSE;
}
}
done = 0;
glyph_i = 0;
while (done < uCount)
{
unsigned j;
classify(lpString + done, chartype, uCount - done);
/* limit text to first block */
i = resolveParagraphs(chartype, uCount - done);
for (j = 0; j < i; ++j)
switch(chartype[j])
{
case B:
case S:
case WS:
case ON: chartype[j] = N;
default: continue;
}
if ((dwWineGCP_Flags&WINE_GCPW_DIR_MASK) == WINE_GCPW_LOOSE_RTL)
State.uBidiLevel = 1;
else if ((dwWineGCP_Flags&WINE_GCPW_DIR_MASK) == WINE_GCPW_LOOSE_LTR)
State.uBidiLevel = 0;
if (dwWineGCP_Flags & WINE_GCPW_LOOSE_MASK)
{
for (j = 0; j < i; ++j)
if (chartype[j] == L)
{
State.uBidiLevel = 0;
break;
}
else if (chartype[j] == R || chartype[j] == AL)
{
State.uBidiLevel = 1;
break;
}
}
res = ScriptItemize(lpString + done, i, maxItems, &Control, &State, pItems, &nItems);
while (res == E_OUTOFMEMORY)
{
maxItems = maxItems * 2;
pItems = HeapReAlloc(GetProcessHeap(), 0, pItems, sizeof(SCRIPT_ITEM) * maxItems);
if (!pItems)
{
WARN("Out of memory\n");
HeapFree(GetProcessHeap(), 0, chartype);
HeapFree(GetProcessHeap(), 0, levels);
return FALSE;
}
res = ScriptItemize(lpString + done, i, maxItems, &Control, &State, pItems, &nItems);
}
if (lpOutString || lpOrder)
for (j = 0; j < nItems; j++)
{
int k;
for (k = pItems[j].iCharPos; k < pItems[j+1].iCharPos; k++)
levels[k] = pItems[j].a.s.uBidiLevel;
}
if (lpOutString)
{
/* assign directional types again, but for WS, S this time */
classify(lpString + done, chartype, i);
BidiLines(State.uBidiLevel, lpOutString + done, lpString + done,
chartype, levels, i, 0);
}
if (lpOrder)
{
int k, lastgood;
for (j = lastgood = 0; j < i; ++j)
if (levels[j] != levels[lastgood])
{
--j;
if (odd(levels[lastgood]))
for (k = j; k >= lastgood; --k)
lpOrder[done + k] = done + j - k;
else
for (k = lastgood; k <= j; ++k)
lpOrder[done + k] = done + k;
lastgood = ++j;
}
if (odd(levels[lastgood]))
for (k = j - 1; k >= lastgood; --k)
lpOrder[done + k] = done + j - 1 - k;
else
for (k = lastgood; k < j; ++k)
lpOrder[done + k] = done + k;
}
if (lpGlyphs && doGlyphs)
{
int j;
BYTE runOrder[maxItems];
int visOrder[maxItems];
SCRIPT_ITEM *curItem;
for (j = 0; j < nItems; j++)
runOrder[j] = pItems[j].a.s.uBidiLevel;
ScriptLayout(nItems, runOrder, visOrder, NULL);
for (j = 0; j < nItems; j++)
{
int k;
int cChars,cOutGlyphs;
curItem = &pItems[visOrder[j]];
cChars = pItems[visOrder[j]+1].iCharPos - curItem->iCharPos;
res = ScriptShape(hDC, &psc, lpString + done + curItem->iCharPos, cChars, cMaxGlyphs, &curItem->a, run_glyphs, pwLogClust, psva, &cOutGlyphs);
while (res == E_OUTOFMEMORY)
{
cMaxGlyphs *= 2;
run_glyphs = HeapReAlloc(GetProcessHeap(), 0, run_glyphs, sizeof(WORD) * cMaxGlyphs);
if (!run_glyphs)
{
WARN("Out of memory\n");
HeapFree(GetProcessHeap(), 0, chartype);
HeapFree(GetProcessHeap(), 0, levels);
HeapFree(GetProcessHeap(), 0, pItems);
HeapFree(GetProcessHeap(), 0, psva);
HeapFree(GetProcessHeap(), 0, pwLogClust);
HeapFree(GetProcessHeap(), 0, *lpGlyphs);
ScriptFreeCache(&psc);
*lpGlyphs = NULL;
return FALSE;
}
res = ScriptShape(hDC, &psc, lpString + done + curItem->iCharPos, cChars, cMaxGlyphs, &curItem->a, run_glyphs, pwLogClust, psva, &cOutGlyphs);
}
if (res)
{
if (res == USP_E_SCRIPT_NOT_IN_FONT)
TRACE("Unable to shape with currently selected font\n");
else
FIXME("Unable to shape string (%x)\n",res);
j = nItems;
doGlyphs = FALSE;
HeapFree(GetProcessHeap(), 0, *lpGlyphs);
*lpGlyphs = NULL;
}
else
{
if (*lpGlyphs)
*lpGlyphs = HeapReAlloc(GetProcessHeap(), 0, *lpGlyphs, sizeof(WORD) * (glyph_i + cOutGlyphs));
else
*lpGlyphs = HeapAlloc(GetProcessHeap(), 0, sizeof(WORD) * (glyph_i + cOutGlyphs));
for (k = 0; k < cOutGlyphs; k++)
(*lpGlyphs)[glyph_i+k] = run_glyphs[k];
glyph_i += cOutGlyphs;
}
}
}
done += i;
}
if (cGlyphs)
*cGlyphs = glyph_i;
HeapFree(GetProcessHeap(), 0, chartype);
HeapFree(GetProcessHeap(), 0, levels);
HeapFree(GetProcessHeap(), 0, pItems);
HeapFree(GetProcessHeap(), 0, run_glyphs);
HeapFree(GetProcessHeap(), 0, pwLogClust);
HeapFree(GetProcessHeap(), 0, psva);
ScriptFreeCache(&psc);
return TRUE;
}

View File

@@ -0,0 +1,629 @@
/*
* GDI bit-blit operations
*
* Copyright 1993, 1994 Alexandre Julliard
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "config.h"
#include <stdarg.h>
#include <math.h>
#ifdef HAVE_FLOAT_H
#include <float.h>
#endif
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "gdi_private.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(bitblt);
/***********************************************************************
* PatBlt (GDI32.@)
*/
BOOL WINAPI PatBlt( HDC hdc, INT left, INT top,
INT width, INT height, DWORD rop)
{
DC * dc = get_dc_ptr( hdc );
BOOL bRet = FALSE;
if (!dc) return FALSE;
TRACE("%p %d,%d %dx%d %06x\n", hdc, left, top, width, height, rop );
if (dc->funcs->pPatBlt)
{
update_dc( dc );
bRet = dc->funcs->pPatBlt( dc->physDev, left, top, width, height, rop );
}
else if (dc->funcs->pStretchBlt)
{
update_dc( dc );
bRet = dc->funcs->pStretchBlt( dc->physDev, left, top, width, height, NULL, 0, 0, 0, 0, rop );
}
release_dc_ptr( dc );
return bRet;
}
/***********************************************************************
* BitBlt (GDI32.@)
*/
BOOL WINAPI BitBlt( HDC hdcDst, INT xDst, INT yDst, INT width,
INT height, HDC hdcSrc, INT xSrc, INT ySrc, DWORD rop )
{
BOOL ret = FALSE;
DC *dcDst, *dcSrc;
TRACE("hdcSrc=%p %d,%d -> hdcDest=%p %d,%d %dx%d rop=%06x\n",
hdcSrc, xSrc, ySrc, hdcDst, xDst, yDst, width, height, rop);
if (!(dcDst = get_dc_ptr( hdcDst ))) return FALSE;
if (dcDst->funcs->pBitBlt || dcDst->funcs->pStretchBlt)
{
update_dc( dcDst );
dcSrc = get_dc_ptr( hdcSrc );
if (dcSrc) update_dc( dcSrc );
if (dcDst->funcs->pBitBlt)
ret = dcDst->funcs->pBitBlt( dcDst->physDev, xDst, yDst, width, height,
dcSrc ? dcSrc->physDev : NULL, xSrc, ySrc, rop );
else
ret = dcDst->funcs->pStretchBlt( dcDst->physDev, xDst, yDst, width, height,
dcSrc ? dcSrc->physDev : NULL, xSrc, ySrc,
width, height, rop );
release_dc_ptr( dcDst );
if (dcSrc) release_dc_ptr( dcSrc );
}
else if (dcDst->funcs->pStretchDIBits)
{
BITMAP bm;
BITMAPINFOHEADER info_hdr;
HBITMAP hbm;
LPVOID bits;
INT lines;
release_dc_ptr( dcDst );
if(GetObjectType( hdcSrc ) != OBJ_MEMDC)
{
FIXME("hdcSrc isn't a memory dc. Don't yet cope with this\n");
return FALSE;
}
GetObjectW(GetCurrentObject(hdcSrc, OBJ_BITMAP), sizeof(bm), &bm);
info_hdr.biSize = sizeof(info_hdr);
info_hdr.biWidth = bm.bmWidth;
info_hdr.biHeight = bm.bmHeight;
info_hdr.biPlanes = 1;
info_hdr.biBitCount = 32;
info_hdr.biCompression = BI_RGB;
info_hdr.biSizeImage = 0;
info_hdr.biXPelsPerMeter = 0;
info_hdr.biYPelsPerMeter = 0;
info_hdr.biClrUsed = 0;
info_hdr.biClrImportant = 0;
if(!(bits = HeapAlloc(GetProcessHeap(), 0, bm.bmHeight * bm.bmWidth * 4)))
return FALSE;
/* Select out the src bitmap before calling GetDIBits */
hbm = SelectObject(hdcSrc, GetStockObject(DEFAULT_BITMAP));
GetDIBits(hdcSrc, hbm, 0, bm.bmHeight, bits, (BITMAPINFO*)&info_hdr, DIB_RGB_COLORS);
SelectObject(hdcSrc, hbm);
lines = StretchDIBits(hdcDst, xDst, yDst, width, height, xSrc, bm.bmHeight - height - ySrc,
width, height, bits, (BITMAPINFO*)&info_hdr, DIB_RGB_COLORS, rop);
HeapFree(GetProcessHeap(), 0, bits);
return (lines == height);
}
else release_dc_ptr( dcDst );
return ret;
}
/***********************************************************************
* StretchBlt (GDI32.@)
*/
BOOL WINAPI StretchBlt( HDC hdcDst, INT xDst, INT yDst,
INT widthDst, INT heightDst,
HDC hdcSrc, INT xSrc, INT ySrc,
INT widthSrc, INT heightSrc,
DWORD rop )
{
BOOL ret = FALSE;
DC *dcDst, *dcSrc;
TRACE("%p %d,%d %dx%d -> %p %d,%d %dx%d rop=%06x\n",
hdcSrc, xSrc, ySrc, widthSrc, heightSrc,
hdcDst, xDst, yDst, widthDst, heightDst, rop );
if (!(dcDst = get_dc_ptr( hdcDst ))) return FALSE;
if (dcDst->funcs->pStretchBlt)
{
if ((dcSrc = get_dc_ptr( hdcSrc )))
{
update_dc( dcDst );
update_dc( dcSrc );
ret = dcDst->funcs->pStretchBlt( dcDst->physDev, xDst, yDst, widthDst, heightDst,
dcSrc->physDev, xSrc, ySrc, widthSrc, heightSrc,
rop );
release_dc_ptr( dcDst );
release_dc_ptr( dcSrc );
}
}
else if (dcDst->funcs->pStretchDIBits)
{
BITMAP bm;
BITMAPINFOHEADER info_hdr;
HBITMAP hbm;
LPVOID bits;
INT lines;
POINT pts[2];
pts[0].x = xSrc;
pts[0].y = ySrc;
pts[1].x = xSrc + widthSrc;
pts[1].y = ySrc + heightSrc;
LPtoDP(hdcSrc, pts, 2);
xSrc = pts[0].x;
ySrc = pts[0].y;
widthSrc = pts[1].x - pts[0].x;
heightSrc = pts[1].y - pts[0].y;
release_dc_ptr( dcDst );
if(GetObjectType( hdcSrc ) != OBJ_MEMDC) return FALSE;
GetObjectW(GetCurrentObject(hdcSrc, OBJ_BITMAP), sizeof(bm), &bm);
info_hdr.biSize = sizeof(info_hdr);
info_hdr.biWidth = bm.bmWidth;
info_hdr.biHeight = bm.bmHeight;
info_hdr.biPlanes = 1;
info_hdr.biBitCount = 32;
info_hdr.biCompression = BI_RGB;
info_hdr.biSizeImage = 0;
info_hdr.biXPelsPerMeter = 0;
info_hdr.biYPelsPerMeter = 0;
info_hdr.biClrUsed = 0;
info_hdr.biClrImportant = 0;
if(!(bits = HeapAlloc(GetProcessHeap(), 0, bm.bmHeight * bm.bmWidth * 4)))
return FALSE;
/* Select out the src bitmap before calling GetDIBits */
hbm = SelectObject(hdcSrc, GetStockObject(DEFAULT_BITMAP));
GetDIBits(hdcSrc, hbm, 0, bm.bmHeight, bits, (BITMAPINFO*)&info_hdr, DIB_RGB_COLORS);
SelectObject(hdcSrc, hbm);
lines = StretchDIBits(hdcDst, xDst, yDst, widthDst, heightDst, xSrc, bm.bmHeight - heightSrc - ySrc,
widthSrc, heightSrc, bits, (BITMAPINFO*)&info_hdr, DIB_RGB_COLORS, rop);
HeapFree(GetProcessHeap(), 0, bits);
return (lines == heightSrc);
}
else release_dc_ptr( dcDst );
return ret;
}
#define FRGND_ROP3(ROP4) ((ROP4) & 0x00FFFFFF)
#define BKGND_ROP3(ROP4) (ROP3Table[((ROP4)>>24) & 0xFF])
/***********************************************************************
* MaskBlt [GDI32.@]
*/
BOOL WINAPI MaskBlt(HDC hdcDest, INT nXDest, INT nYDest,
INT nWidth, INT nHeight, HDC hdcSrc,
INT nXSrc, INT nYSrc, HBITMAP hbmMask,
INT xMask, INT yMask, DWORD dwRop)
{
HBITMAP hBitmap1, hOldBitmap1, hBitmap2, hOldBitmap2;
HDC hDC1, hDC2;
HBRUSH hbrMask, hbrDst, hbrTmp;
static const DWORD ROP3Table[256] =
{
0x00000042, 0x00010289,
0x00020C89, 0x000300AA,
0x00040C88, 0x000500A9,
0x00060865, 0x000702C5,
0x00080F08, 0x00090245,
0x000A0329, 0x000B0B2A,
0x000C0324, 0x000D0B25,
0x000E08A5, 0x000F0001,
0x00100C85, 0x001100A6,
0x00120868, 0x001302C8,
0x00140869, 0x001502C9,
0x00165CCA, 0x00171D54,
0x00180D59, 0x00191CC8,
0x001A06C5, 0x001B0768,
0x001C06CA, 0x001D0766,
0x001E01A5, 0x001F0385,
0x00200F09, 0x00210248,
0x00220326, 0x00230B24,
0x00240D55, 0x00251CC5,
0x002606C8, 0x00271868,
0x00280369, 0x002916CA,
0x002A0CC9, 0x002B1D58,
0x002C0784, 0x002D060A,
0x002E064A, 0x002F0E2A,
0x0030032A, 0x00310B28,
0x00320688, 0x00330008,
0x003406C4, 0x00351864,
0x003601A8, 0x00370388,
0x0038078A, 0x00390604,
0x003A0644, 0x003B0E24,
0x003C004A, 0x003D18A4,
0x003E1B24, 0x003F00EA,
0x00400F0A, 0x00410249,
0x00420D5D, 0x00431CC4,
0x00440328, 0x00450B29,
0x004606C6, 0x0047076A,
0x00480368, 0x004916C5,
0x004A0789, 0x004B0605,
0x004C0CC8, 0x004D1954,
0x004E0645, 0x004F0E25,
0x00500325, 0x00510B26,
0x005206C9, 0x00530764,
0x005408A9, 0x00550009,
0x005601A9, 0x00570389,
0x00580785, 0x00590609,
0x005A0049, 0x005B18A9,
0x005C0649, 0x005D0E29,
0x005E1B29, 0x005F00E9,
0x00600365, 0x006116C6,
0x00620786, 0x00630608,
0x00640788, 0x00650606,
0x00660046, 0x006718A8,
0x006858A6, 0x00690145,
0x006A01E9, 0x006B178A,
0x006C01E8, 0x006D1785,
0x006E1E28, 0x006F0C65,
0x00700CC5, 0x00711D5C,
0x00720648, 0x00730E28,
0x00740646, 0x00750E26,
0x00761B28, 0x007700E6,
0x007801E5, 0x00791786,
0x007A1E29, 0x007B0C68,
0x007C1E24, 0x007D0C69,
0x007E0955, 0x007F03C9,
0x008003E9, 0x00810975,
0x00820C49, 0x00831E04,
0x00840C48, 0x00851E05,
0x008617A6, 0x008701C5,
0x008800C6, 0x00891B08,
0x008A0E06, 0x008B0666,
0x008C0E08, 0x008D0668,
0x008E1D7C, 0x008F0CE5,
0x00900C45, 0x00911E08,
0x009217A9, 0x009301C4,
0x009417AA, 0x009501C9,
0x00960169, 0x0097588A,
0x00981888, 0x00990066,
0x009A0709, 0x009B07A8,
0x009C0704, 0x009D07A6,
0x009E16E6, 0x009F0345,
0x00A000C9, 0x00A11B05,
0x00A20E09, 0x00A30669,
0x00A41885, 0x00A50065,
0x00A60706, 0x00A707A5,
0x00A803A9, 0x00A90189,
0x00AA0029, 0x00AB0889,
0x00AC0744, 0x00AD06E9,
0x00AE0B06, 0x00AF0229,
0x00B00E05, 0x00B10665,
0x00B21974, 0x00B30CE8,
0x00B4070A, 0x00B507A9,
0x00B616E9, 0x00B70348,
0x00B8074A, 0x00B906E6,
0x00BA0B09, 0x00BB0226,
0x00BC1CE4, 0x00BD0D7D,
0x00BE0269, 0x00BF08C9,
0x00C000CA, 0x00C11B04,
0x00C21884, 0x00C3006A,
0x00C40E04, 0x00C50664,
0x00C60708, 0x00C707AA,
0x00C803A8, 0x00C90184,
0x00CA0749, 0x00CB06E4,
0x00CC0020, 0x00CD0888,
0x00CE0B08, 0x00CF0224,
0x00D00E0A, 0x00D1066A,
0x00D20705, 0x00D307A4,
0x00D41D78, 0x00D50CE9,
0x00D616EA, 0x00D70349,
0x00D80745, 0x00D906E8,
0x00DA1CE9, 0x00DB0D75,
0x00DC0B04, 0x00DD0228,
0x00DE0268, 0x00DF08C8,
0x00E003A5, 0x00E10185,
0x00E20746, 0x00E306EA,
0x00E40748, 0x00E506E5,
0x00E61CE8, 0x00E70D79,
0x00E81D74, 0x00E95CE6,
0x00EA02E9, 0x00EB0849,
0x00EC02E8, 0x00ED0848,
0x00EE0086, 0x00EF0A08,
0x00F00021, 0x00F10885,
0x00F20B05, 0x00F3022A,
0x00F40B0A, 0x00F50225,
0x00F60265, 0x00F708C5,
0x00F802E5, 0x00F90845,
0x00FA0089, 0x00FB0A09,
0x00FC008A, 0x00FD0A0A,
0x00FE02A9, 0x00FF0062,
};
if (!hbmMask)
return BitBlt(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc, FRGND_ROP3(dwRop));
hbrMask = CreatePatternBrush(hbmMask);
hbrDst = SelectObject(hdcDest, GetStockObject(NULL_BRUSH));
/* make bitmap */
hDC1 = CreateCompatibleDC(hdcDest);
hBitmap1 = CreateCompatibleBitmap(hdcDest, nWidth, nHeight);
hOldBitmap1 = SelectObject(hDC1, hBitmap1);
/* draw using bkgnd rop */
BitBlt(hDC1, 0, 0, nWidth, nHeight, hdcDest, nXDest, nYDest, SRCCOPY);
hbrTmp = SelectObject(hDC1, hbrDst);
BitBlt(hDC1, 0, 0, nWidth, nHeight, hdcSrc, nXSrc, nYSrc, BKGND_ROP3(dwRop));
SelectObject(hDC1, hbrTmp);
/* make bitmap */
hDC2 = CreateCompatibleDC(hdcDest);
hBitmap2 = CreateCompatibleBitmap(hdcDest, nWidth, nHeight);
hOldBitmap2 = SelectObject(hDC2, hBitmap2);
/* draw using foregnd rop */
BitBlt(hDC2, 0, 0, nWidth, nHeight, hdcDest, nXDest, nYDest, SRCCOPY);
hbrTmp = SelectObject(hDC2, hbrDst);
BitBlt(hDC2, 0, 0, nWidth, nHeight, hdcSrc, nXSrc, nYSrc, FRGND_ROP3(dwRop));
/* combine both using the mask as a pattern brush */
SelectObject(hDC2, hbrMask);
BitBlt(hDC2, 0, 0, nWidth, nHeight, hDC1, 0, 0, 0xac0744 ); /* (D & P) | (S & ~P) */
SelectObject(hDC2, hbrTmp);
/* blit to dst */
BitBlt(hdcDest, nXDest, nYDest, nWidth, nHeight, hDC2, 0, 0, SRCCOPY);
/* restore all objects */
SelectObject(hdcDest, hbrDst);
SelectObject(hDC1, hOldBitmap1);
SelectObject(hDC2, hOldBitmap2);
/* delete all temp objects */
DeleteObject(hBitmap1);
DeleteObject(hBitmap2);
DeleteObject(hbrMask);
DeleteDC(hDC1);
DeleteDC(hDC2);
return TRUE;
}
/******************************************************************************
* GdiTransparentBlt [GDI32.@]
*/
BOOL WINAPI GdiTransparentBlt( HDC hdcDest, int xDest, int yDest, int widthDest, int heightDest,
HDC hdcSrc, int xSrc, int ySrc, int widthSrc, int heightSrc,
UINT crTransparent )
{
BOOL ret = FALSE;
HDC hdcWork;
HBITMAP bmpWork;
HGDIOBJ oldWork;
HDC hdcMask = NULL;
HBITMAP bmpMask = NULL;
HBITMAP oldMask = NULL;
COLORREF oldBackground;
COLORREF oldForeground;
int oldStretchMode;
if(widthDest < 0 || heightDest < 0 || widthSrc < 0 || heightSrc < 0) {
TRACE("Cannot mirror\n");
return FALSE;
}
oldBackground = SetBkColor(hdcDest, RGB(255,255,255));
oldForeground = SetTextColor(hdcDest, RGB(0,0,0));
/* Stretch bitmap */
oldStretchMode = GetStretchBltMode(hdcSrc);
if(oldStretchMode == BLACKONWHITE || oldStretchMode == WHITEONBLACK)
SetStretchBltMode(hdcSrc, COLORONCOLOR);
hdcWork = CreateCompatibleDC(hdcDest);
bmpWork = CreateCompatibleBitmap(hdcDest, widthDest, heightDest);
oldWork = SelectObject(hdcWork, bmpWork);
if(!StretchBlt(hdcWork, 0, 0, widthDest, heightDest, hdcSrc, xSrc, ySrc, widthSrc, heightSrc, SRCCOPY)) {
TRACE("Failed to stretch\n");
goto error;
}
SetBkColor(hdcWork, crTransparent);
/* Create mask */
hdcMask = CreateCompatibleDC(hdcDest);
bmpMask = CreateCompatibleBitmap(hdcMask, widthDest, heightDest);
oldMask = SelectObject(hdcMask, bmpMask);
if(!BitBlt(hdcMask, 0, 0, widthDest, heightDest, hdcWork, 0, 0, SRCCOPY)) {
TRACE("Failed to create mask\n");
goto error;
}
/* Replace transparent color with black */
SetBkColor(hdcWork, RGB(0,0,0));
SetTextColor(hdcWork, RGB(255,255,255));
if(!BitBlt(hdcWork, 0, 0, widthDest, heightDest, hdcMask, 0, 0, SRCAND)) {
TRACE("Failed to mask out background\n");
goto error;
}
/* Replace non-transparent area on destination with black */
if(!BitBlt(hdcDest, xDest, yDest, widthDest, heightDest, hdcMask, 0, 0, SRCAND)) {
TRACE("Failed to clear destination area\n");
goto error;
}
/* Draw the image */
if(!BitBlt(hdcDest, xDest, yDest, widthDest, heightDest, hdcWork, 0, 0, SRCPAINT)) {
TRACE("Failed to paint image\n");
goto error;
}
ret = TRUE;
error:
SetStretchBltMode(hdcSrc, oldStretchMode);
SetBkColor(hdcDest, oldBackground);
SetTextColor(hdcDest, oldForeground);
if(hdcWork) {
SelectObject(hdcWork, oldWork);
DeleteDC(hdcWork);
}
if(bmpWork) DeleteObject(bmpWork);
if(hdcMask) {
SelectObject(hdcMask, oldMask);
DeleteDC(hdcMask);
}
if(bmpMask) DeleteObject(bmpMask);
return ret;
}
/******************************************************************************
* GdiAlphaBlend [GDI32.@]
*/
BOOL WINAPI GdiAlphaBlend(HDC hdcDst, int xDst, int yDst, int widthDst, int heightDst,
HDC hdcSrc, int xSrc, int ySrc, int widthSrc, int heightSrc,
BLENDFUNCTION blendFunction)
{
BOOL ret = FALSE;
DC *dcDst, *dcSrc;
dcSrc = get_dc_ptr( hdcSrc );
if (!dcSrc) return FALSE;
if ((dcDst = get_dc_ptr( hdcDst )))
{
update_dc( dcSrc );
update_dc( dcDst );
TRACE("%p %d,%d %dx%d -> %p %d,%d %dx%d op=%02x flags=%02x srcconstalpha=%02x alphafmt=%02x\n",
hdcSrc, xSrc, ySrc, widthSrc, heightSrc,
hdcDst, xDst, yDst, widthDst, heightDst,
blendFunction.BlendOp, blendFunction.BlendFlags,
blendFunction.SourceConstantAlpha, blendFunction.AlphaFormat);
if (dcDst->funcs->pAlphaBlend)
ret = dcDst->funcs->pAlphaBlend( dcDst->physDev, xDst, yDst, widthDst, heightDst,
dcSrc->physDev, xSrc, ySrc, widthSrc, heightSrc,
blendFunction );
release_dc_ptr( dcDst );
}
release_dc_ptr( dcSrc );
return ret;
}
/*********************************************************************
* PlgBlt [GDI32.@]
*
*/
BOOL WINAPI PlgBlt( HDC hdcDest, const POINT *lpPoint,
HDC hdcSrc, INT nXSrc, INT nYSrc, INT nWidth,
INT nHeight, HBITMAP hbmMask, INT xMask, INT yMask)
{
int oldgMode;
/* parallelogram coords */
POINT plg[3];
/* rect coords */
POINT rect[3];
XFORM xf;
XFORM SrcXf;
XFORM oldDestXf;
double det;
/* save actual mode, set GM_ADVANCED */
oldgMode = SetGraphicsMode(hdcDest,GM_ADVANCED);
if (oldgMode == 0)
return FALSE;
memcpy(plg,lpPoint,sizeof(POINT)*3);
rect[0].x = nXSrc;
rect[0].y = nYSrc;
rect[1].x = nXSrc + nWidth;
rect[1].y = nYSrc;
rect[2].x = nXSrc;
rect[2].y = nYSrc + nHeight;
/* calc XFORM matrix to transform hdcDest -> hdcSrc (parallelogram to rectangle) */
/* determinant */
det = rect[1].x*(rect[2].y - rect[0].y) - rect[2].x*(rect[1].y - rect[0].y) - rect[0].x*(rect[2].y - rect[1].y);
if (fabs(det) < 1e-5)
{
SetGraphicsMode(hdcDest,oldgMode);
return FALSE;
}
TRACE("hdcSrc=%p %d,%d,%dx%d -> hdcDest=%p %d,%d,%d,%d,%d,%d\n",
hdcSrc, nXSrc, nYSrc, nWidth, nHeight, hdcDest, plg[0].x, plg[0].y, plg[1].x, plg[1].y, plg[2].x, plg[2].y);
/* X components */
xf.eM11 = (plg[1].x*(rect[2].y - rect[0].y) - plg[2].x*(rect[1].y - rect[0].y) - plg[0].x*(rect[2].y - rect[1].y)) / det;
xf.eM21 = (rect[1].x*(plg[2].x - plg[0].x) - rect[2].x*(plg[1].x - plg[0].x) - rect[0].x*(plg[2].x - plg[1].x)) / det;
xf.eDx = (rect[0].x*(rect[1].y*plg[2].x - rect[2].y*plg[1].x) -
rect[1].x*(rect[0].y*plg[2].x - rect[2].y*plg[0].x) +
rect[2].x*(rect[0].y*plg[1].x - rect[1].y*plg[0].x)
) / det;
/* Y components */
xf.eM12 = (plg[1].y*(rect[2].y - rect[0].y) - plg[2].y*(rect[1].y - rect[0].y) - plg[0].y*(rect[2].y - rect[1].y)) / det;
xf.eM22 = (plg[1].x*(rect[2].y - rect[0].y) - plg[2].x*(rect[1].y - rect[0].y) - plg[0].x*(rect[2].y - rect[1].y)) / det;
xf.eDy = (rect[0].x*(rect[1].y*plg[2].y - rect[2].y*plg[1].y) -
rect[1].x*(rect[0].y*plg[2].y - rect[2].y*plg[0].y) +
rect[2].x*(rect[0].y*plg[1].y - rect[1].y*plg[0].y)
) / det;
GetWorldTransform(hdcSrc,&SrcXf);
CombineTransform(&xf,&xf,&SrcXf);
/* save actual dest transform */
GetWorldTransform(hdcDest,&oldDestXf);
SetWorldTransform(hdcDest,&xf);
/* now destination and source DCs use same coords */
MaskBlt(hdcDest,nXSrc,nYSrc,nWidth,nHeight,
hdcSrc, nXSrc,nYSrc,
hbmMask,xMask,yMask,
SRCCOPY);
/* restore dest DC */
SetWorldTransform(hdcDest,&oldDestXf);
SetGraphicsMode(hdcDest,oldgMode);
return TRUE;
}

View File

@@ -0,0 +1,797 @@
/*
* GDI bitmap objects
*
* Copyright 1993 Alexandre Julliard
* 1998 Huw D M Davies
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "gdi_private.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(bitmap);
static HGDIOBJ BITMAP_SelectObject( HGDIOBJ handle, HDC hdc );
static INT BITMAP_GetObject( HGDIOBJ handle, INT count, LPVOID buffer );
static BOOL BITMAP_DeleteObject( HGDIOBJ handle );
static const struct gdi_obj_funcs bitmap_funcs =
{
BITMAP_SelectObject, /* pSelectObject */
BITMAP_GetObject, /* pGetObjectA */
BITMAP_GetObject, /* pGetObjectW */
NULL, /* pUnrealizeObject */
BITMAP_DeleteObject /* pDeleteObject */
};
/***********************************************************************
* BITMAP_GetWidthBytes
*
* Return number of bytes taken by a scanline of 16-bit aligned Windows DDB
* data.
*/
INT BITMAP_GetWidthBytes( INT bmWidth, INT bpp )
{
switch(bpp)
{
case 1:
return 2 * ((bmWidth+15) >> 4);
case 24:
bmWidth *= 3; /* fall through */
case 8:
return bmWidth + (bmWidth & 1);
case 32:
return bmWidth * 4;
case 16:
case 15:
return bmWidth * 2;
case 4:
return 2 * ((bmWidth+3) >> 2);
default:
WARN("Unknown depth %d, please report.\n", bpp );
}
return -1;
}
/******************************************************************************
* CreateBitmap [GDI32.@]
*
* Creates a bitmap with the specified info.
*
* PARAMS
* width [I] bitmap width
* height [I] bitmap height
* planes [I] Number of color planes
* bpp [I] Number of bits to identify a color
* bits [I] Pointer to array containing color data
*
* RETURNS
* Success: Handle to bitmap
* Failure: 0
*/
HBITMAP WINAPI CreateBitmap( INT width, INT height, UINT planes,
UINT bpp, LPCVOID bits )
{
BITMAP bm;
bm.bmType = 0;
bm.bmWidth = width;
bm.bmHeight = height;
bm.bmWidthBytes = BITMAP_GetWidthBytes( width, bpp );
bm.bmPlanes = planes;
bm.bmBitsPixel = bpp;
bm.bmBits = (LPVOID)bits;
return CreateBitmapIndirect( &bm );
}
/******************************************************************************
* CreateCompatibleBitmap [GDI32.@]
*
* Creates a bitmap compatible with the DC.
*
* PARAMS
* hdc [I] Handle to device context
* width [I] Width of bitmap
* height [I] Height of bitmap
*
* RETURNS
* Success: Handle to bitmap
* Failure: 0
*/
HBITMAP WINAPI CreateCompatibleBitmap( HDC hdc, INT width, INT height)
{
HBITMAP hbmpRet = 0;
TRACE("(%p,%d,%d) =\n", hdc, width, height);
if (GetObjectType( hdc ) != OBJ_MEMDC)
{
hbmpRet = CreateBitmap(width, height,
GetDeviceCaps(hdc, PLANES),
GetDeviceCaps(hdc, BITSPIXEL),
NULL);
}
else /* Memory DC */
{
DIBSECTION dib;
HBITMAP bitmap = GetCurrentObject( hdc, OBJ_BITMAP );
INT size = GetObjectW( bitmap, sizeof(dib), &dib );
if (!size) return 0;
if (size == sizeof(BITMAP))
{
/* A device-dependent bitmap is selected in the DC */
hbmpRet = CreateBitmap(width, height,
dib.dsBm.bmPlanes,
dib.dsBm.bmBitsPixel,
NULL);
}
else
{
/* A DIB section is selected in the DC */
BITMAPINFO *bi;
void *bits;
/* Allocate memory for a BITMAPINFOHEADER structure and a
color table. The maximum number of colors in a color table
is 256 which corresponds to a bitmap with depth 8.
Bitmaps with higher depths don't have color tables. */
bi = HeapAlloc(GetProcessHeap(), 0, sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
if (bi)
{
bi->bmiHeader.biSize = sizeof(bi->bmiHeader);
bi->bmiHeader.biWidth = width;
bi->bmiHeader.biHeight = height;
bi->bmiHeader.biPlanes = dib.dsBmih.biPlanes;
bi->bmiHeader.biBitCount = dib.dsBmih.biBitCount;
bi->bmiHeader.biCompression = dib.dsBmih.biCompression;
bi->bmiHeader.biSizeImage = 0;
bi->bmiHeader.biXPelsPerMeter = dib.dsBmih.biXPelsPerMeter;
bi->bmiHeader.biYPelsPerMeter = dib.dsBmih.biYPelsPerMeter;
bi->bmiHeader.biClrUsed = dib.dsBmih.biClrUsed;
bi->bmiHeader.biClrImportant = dib.dsBmih.biClrImportant;
if (bi->bmiHeader.biCompression == BI_BITFIELDS)
{
/* Copy the color masks */
CopyMemory(bi->bmiColors, dib.dsBitfields, 3 * sizeof(DWORD));
}
else if (bi->bmiHeader.biBitCount <= 8)
{
/* Copy the color table */
GetDIBColorTable(hdc, 0, 256, bi->bmiColors);
}
hbmpRet = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
HeapFree(GetProcessHeap(), 0, bi);
}
}
}
TRACE("\t\t%p\n", hbmpRet);
return hbmpRet;
}
/******************************************************************************
* CreateBitmapIndirect [GDI32.@]
*
* Creates a bitmap with the specified info.
*
* PARAMS
* bmp [I] Pointer to the bitmap info describing the bitmap
*
* RETURNS
* Success: Handle to bitmap
* Failure: NULL. Use GetLastError() to determine the cause.
*
* NOTES
* If a width or height of 0 are given, a 1x1 monochrome bitmap is returned.
*/
HBITMAP WINAPI CreateBitmapIndirect( const BITMAP *bmp )
{
BITMAP bm;
BITMAPOBJ *bmpobj;
HBITMAP hbitmap;
if (!bmp || bmp->bmType)
{
SetLastError( ERROR_INVALID_PARAMETER );
return NULL;
}
if (bmp->bmWidth > 0x7ffffff || bmp->bmHeight > 0x7ffffff)
{
SetLastError( ERROR_INVALID_PARAMETER );
return 0;
}
bm = *bmp;
if (!bm.bmWidth || !bm.bmHeight)
{
return GetStockObject( DEFAULT_BITMAP );
}
else
{
if (bm.bmHeight < 0)
bm.bmHeight = -bm.bmHeight;
if (bm.bmWidth < 0)
bm.bmWidth = -bm.bmWidth;
}
if (bm.bmPlanes != 1)
{
FIXME("planes = %d\n", bm.bmPlanes);
SetLastError( ERROR_INVALID_PARAMETER );
return NULL;
}
/* Windows only uses 1, 4, 8, 16, 24 and 32 bpp */
if(bm.bmBitsPixel == 1) bm.bmBitsPixel = 1;
else if(bm.bmBitsPixel <= 4) bm.bmBitsPixel = 4;
else if(bm.bmBitsPixel <= 8) bm.bmBitsPixel = 8;
else if(bm.bmBitsPixel <= 16) bm.bmBitsPixel = 16;
else if(bm.bmBitsPixel <= 24) bm.bmBitsPixel = 24;
else if(bm.bmBitsPixel <= 32) bm.bmBitsPixel = 32;
else {
WARN("Invalid bmBitsPixel %d, returning ERROR_INVALID_PARAMETER\n", bm.bmBitsPixel);
SetLastError(ERROR_INVALID_PARAMETER);
return NULL;
}
/* Windows ignores the provided bm.bmWidthBytes */
bm.bmWidthBytes = BITMAP_GetWidthBytes( bm.bmWidth, bm.bmBitsPixel );
/* XP doesn't allow to create bitmaps larger than 128 Mb */
if (bm.bmHeight > 128 * 1024 * 1024 / bm.bmWidthBytes)
{
SetLastError( ERROR_NOT_ENOUGH_MEMORY );
return 0;
}
/* Create the BITMAPOBJ */
if (!(bmpobj = HeapAlloc( GetProcessHeap(), 0, sizeof(*bmpobj) )))
{
SetLastError( ERROR_NOT_ENOUGH_MEMORY );
return 0;
}
bmpobj->size.cx = 0;
bmpobj->size.cy = 0;
bmpobj->bitmap = bm;
bmpobj->bitmap.bmBits = NULL;
bmpobj->funcs = NULL;
bmpobj->dib = NULL;
bmpobj->color_table = NULL;
bmpobj->nb_colors = 0;
if (!(hbitmap = alloc_gdi_handle( &bmpobj->header, OBJ_BITMAP, &bitmap_funcs )))
{
HeapFree( GetProcessHeap(), 0, bmpobj );
return 0;
}
if (bm.bmBits)
SetBitmapBits( hbitmap, bm.bmHeight * bm.bmWidthBytes, bm.bmBits );
TRACE("%dx%d, %d colors returning %p\n", bm.bmWidth, bm.bmHeight,
1 << (bm.bmPlanes * bm.bmBitsPixel), hbitmap);
return hbitmap;
}
/***********************************************************************
* GetBitmapBits [GDI32.@]
*
* Copies bitmap bits of bitmap to buffer.
*
* RETURNS
* Success: Number of bytes copied
* Failure: 0
*/
LONG WINAPI GetBitmapBits(
HBITMAP hbitmap, /* [in] Handle to bitmap */
LONG count, /* [in] Number of bytes to copy */
LPVOID bits) /* [out] Pointer to buffer to receive bits */
{
BITMAPOBJ *bmp = GDI_GetObjPtr( hbitmap, OBJ_BITMAP );
LONG height, ret;
if (!bmp) return 0;
if (bmp->dib) /* simply copy the bits from the DIB */
{
DIBSECTION *dib = bmp->dib;
const char *src = dib->dsBm.bmBits;
INT width_bytes = BITMAP_GetWidthBytes(dib->dsBm.bmWidth, dib->dsBm.bmBitsPixel);
LONG max = width_bytes * bmp->bitmap.bmHeight;
if (!bits)
{
ret = max;
goto done;
}
if (count > max) count = max;
ret = count;
/* GetBitmapBits returns not 32-bit aligned data */
if (bmp->dib->dsBmih.biHeight >= 0) /* not top-down, need to flip contents vertically */
{
src += dib->dsBm.bmWidthBytes * dib->dsBm.bmHeight;
while (count > 0)
{
src -= dib->dsBm.bmWidthBytes;
memcpy( bits, src, min( count, width_bytes ) );
bits = (char *)bits + width_bytes;
count -= width_bytes;
}
}
else
{
while (count > 0)
{
memcpy( bits, src, min( count, width_bytes ) );
src += dib->dsBm.bmWidthBytes;
bits = (char *)bits + width_bytes;
count -= width_bytes;
}
}
goto done;
}
/* If the bits vector is null, the function should return the read size */
if(bits == NULL)
{
ret = bmp->bitmap.bmWidthBytes * bmp->bitmap.bmHeight;
goto done;
}
if (count < 0) {
WARN("(%d): Negative number of bytes passed???\n", count );
count = -count;
}
/* Only get entire lines */
height = count / bmp->bitmap.bmWidthBytes;
if (height > bmp->bitmap.bmHeight) height = bmp->bitmap.bmHeight;
count = height * bmp->bitmap.bmWidthBytes;
if (count == 0)
{
WARN("Less than one entire line requested\n");
ret = 0;
goto done;
}
TRACE("(%p, %d, %p) %dx%d %d colors fetched height: %d\n",
hbitmap, count, bits, bmp->bitmap.bmWidth, bmp->bitmap.bmHeight,
1 << bmp->bitmap.bmBitsPixel, height );
if(bmp->funcs && bmp->funcs->pGetBitmapBits)
{
TRACE("Calling device specific BitmapBits\n");
ret = bmp->funcs->pGetBitmapBits(hbitmap, bits, count);
} else {
if(!bmp->bitmap.bmBits) {
TRACE("Bitmap is empty\n");
memset(bits, 0, count);
ret = count;
} else {
memcpy(bits, bmp->bitmap.bmBits, count);
ret = count;
}
}
done:
GDI_ReleaseObj( hbitmap );
return ret;
}
/******************************************************************************
* SetBitmapBits [GDI32.@]
*
* Sets bits of color data for a bitmap.
*
* RETURNS
* Success: Number of bytes used in setting the bitmap bits
* Failure: 0
*/
LONG WINAPI SetBitmapBits(
HBITMAP hbitmap, /* [in] Handle to bitmap */
DWORD count, /* [in] Number of bytes in bitmap array */
LPCVOID bits) /* [in] Address of array with bitmap bits */
{
BITMAPOBJ *bmp;
LONG height, ret;
if (!bits) return 0;
bmp = GDI_GetObjPtr( hbitmap, OBJ_BITMAP );
if (!bmp) return 0;
if (count < 0) {
WARN("(%d): Negative number of bytes passed???\n", count );
count = -count;
}
if (bmp->dib) /* simply copy the bits into the DIB */
{
DIBSECTION *dib = bmp->dib;
char *dest = dib->dsBm.bmBits;
LONG max = dib->dsBm.bmWidthBytes * dib->dsBm.bmHeight;
if (count > max) count = max;
ret = count;
if (bmp->dib->dsBmih.biHeight >= 0) /* not top-down, need to flip contents vertically */
{
dest += dib->dsBm.bmWidthBytes * dib->dsBm.bmHeight;
while (count > 0)
{
dest -= dib->dsBm.bmWidthBytes;
memcpy( dest, bits, min( count, dib->dsBm.bmWidthBytes ) );
bits = (const char *)bits + dib->dsBm.bmWidthBytes;
count -= dib->dsBm.bmWidthBytes;
}
}
else memcpy( dest, bits, count );
GDI_ReleaseObj( hbitmap );
return ret;
}
/* Only get entire lines */
height = count / bmp->bitmap.bmWidthBytes;
if (height > bmp->bitmap.bmHeight) height = bmp->bitmap.bmHeight;
count = height * bmp->bitmap.bmWidthBytes;
TRACE("(%p, %d, %p) %dx%d %d colors fetched height: %d\n",
hbitmap, count, bits, bmp->bitmap.bmWidth, bmp->bitmap.bmHeight,
1 << bmp->bitmap.bmBitsPixel, height );
if(bmp->funcs && bmp->funcs->pSetBitmapBits) {
TRACE("Calling device specific BitmapBits\n");
ret = bmp->funcs->pSetBitmapBits(hbitmap, bits, count);
} else {
if(!bmp->bitmap.bmBits) /* Alloc enough for entire bitmap */
bmp->bitmap.bmBits = HeapAlloc( GetProcessHeap(), 0, count );
if(!bmp->bitmap.bmBits) {
WARN("Unable to allocate bit buffer\n");
ret = 0;
} else {
memcpy(bmp->bitmap.bmBits, bits, count);
ret = count;
}
}
GDI_ReleaseObj( hbitmap );
return ret;
}
/**********************************************************************
* BITMAP_CopyBitmap
*
*/
HBITMAP BITMAP_CopyBitmap(HBITMAP hbitmap)
{
HBITMAP res;
DIBSECTION dib;
DWORD size;
if (!(size = GetObjectW( hbitmap, sizeof(dib), &dib ))) return 0;
if (size == sizeof(DIBSECTION))
{
void *bits;
BITMAPINFO *bi;
HDC dc = CreateCompatibleDC( NULL );
if (!dc) return 0;
if (!(bi = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ))))
{
DeleteDC( dc );
return 0;
}
bi->bmiHeader = dib.dsBmih;
/* Get the color table or the color masks */
GetDIBits( dc, hbitmap, 0, 0, NULL, bi, DIB_RGB_COLORS );
res = CreateDIBSection( dc, bi, DIB_RGB_COLORS, &bits, NULL, 0 );
if (res) SetDIBits( dc, res, 0, dib.dsBm.bmHeight, dib.dsBm.bmBits, bi, DIB_RGB_COLORS );
HeapFree( GetProcessHeap(), 0, bi );
DeleteDC( dc );
return res;
}
res = CreateBitmapIndirect( &dib.dsBm );
if(res) {
char *buf = HeapAlloc( GetProcessHeap(), 0, dib.dsBm.bmWidthBytes * dib.dsBm.bmHeight );
GetBitmapBits (hbitmap, dib.dsBm.bmWidthBytes * dib.dsBm.bmHeight, buf);
SetBitmapBits (res, dib.dsBm.bmWidthBytes * dib.dsBm.bmHeight, buf);
HeapFree( GetProcessHeap(), 0, buf );
}
return res;
}
/***********************************************************************
* BITMAP_SetOwnerDC
*
* Set the type of DC that owns the bitmap. This is used when the
* bitmap is selected into a device to initialize the bitmap function
* table.
*/
BOOL BITMAP_SetOwnerDC( HBITMAP hbitmap, DC *dc )
{
BITMAPOBJ *bitmap;
BOOL ret;
/* never set the owner of the stock bitmap since it can be selected in multiple DCs */
if (hbitmap == GetStockObject(DEFAULT_BITMAP)) return TRUE;
if (!(bitmap = GDI_GetObjPtr( hbitmap, OBJ_BITMAP ))) return FALSE;
ret = TRUE;
if (!bitmap->funcs) /* not owned by a DC yet */
{
if (dc->funcs->pCreateBitmap) ret = dc->funcs->pCreateBitmap( dc->physDev, hbitmap,
bitmap->bitmap.bmBits );
if (ret) bitmap->funcs = dc->funcs;
}
else if (bitmap->funcs != dc->funcs)
{
FIXME( "Trying to select bitmap %p in different DC type\n", hbitmap );
ret = FALSE;
}
GDI_ReleaseObj( hbitmap );
return ret;
}
/***********************************************************************
* BITMAP_SelectObject
*/
static HGDIOBJ BITMAP_SelectObject( HGDIOBJ handle, HDC hdc )
{
HGDIOBJ ret;
BITMAPOBJ *bitmap;
DC *dc;
if (!(dc = get_dc_ptr( hdc ))) return 0;
if (GetObjectType( hdc ) != OBJ_MEMDC)
{
ret = 0;
goto done;
}
ret = dc->hBitmap;
if (handle == dc->hBitmap) goto done; /* nothing to do */
if (!(bitmap = GDI_GetObjPtr( handle, OBJ_BITMAP )))
{
ret = 0;
goto done;
}
if (bitmap->header.selcount && (handle != GetStockObject(DEFAULT_BITMAP)))
{
WARN( "Bitmap already selected in another DC\n" );
GDI_ReleaseObj( handle );
ret = 0;
goto done;
}
if (!bitmap->funcs && !BITMAP_SetOwnerDC( handle, dc ))
{
GDI_ReleaseObj( handle );
ret = 0;
goto done;
}
if (dc->funcs->pSelectBitmap && !dc->funcs->pSelectBitmap( dc->physDev, handle ))
{
GDI_ReleaseObj( handle );
ret = 0;
}
else
{
dc->hBitmap = handle;
GDI_inc_ref_count( handle );
dc->dirty = 0;
dc->vis_rect.left = 0;
dc->vis_rect.top = 0;
dc->vis_rect.right = bitmap->bitmap.bmWidth;
dc->vis_rect.bottom = bitmap->bitmap.bmHeight;
SetRectRgn( dc->hVisRgn, 0, 0, bitmap->bitmap.bmWidth, bitmap->bitmap.bmHeight);
GDI_ReleaseObj( handle );
DC_InitDC( dc );
GDI_dec_ref_count( ret );
}
done:
release_dc_ptr( dc );
return ret;
}
/***********************************************************************
* BITMAP_DeleteObject
*/
static BOOL BITMAP_DeleteObject( HGDIOBJ handle )
{
const DC_FUNCTIONS *funcs;
BITMAPOBJ *bmp = GDI_GetObjPtr( handle, OBJ_BITMAP );
if (!bmp) return FALSE;
funcs = bmp->funcs;
GDI_ReleaseObj( handle );
if (funcs && funcs->pDeleteBitmap) funcs->pDeleteBitmap( handle );
if (!(bmp = free_gdi_handle( handle ))) return FALSE;
HeapFree( GetProcessHeap(), 0, bmp->bitmap.bmBits );
if (bmp->dib)
{
DIBSECTION *dib = bmp->dib;
if (dib->dsBm.bmBits)
{
if (dib->dshSection)
{
SYSTEM_INFO SystemInfo;
GetSystemInfo( &SystemInfo );
UnmapViewOfFile( (char *)dib->dsBm.bmBits -
(dib->dsOffset % SystemInfo.dwAllocationGranularity) );
}
else if (!dib->dsOffset)
VirtualFree(dib->dsBm.bmBits, 0L, MEM_RELEASE );
}
HeapFree(GetProcessHeap(), 0, dib);
HeapFree(GetProcessHeap(), 0, bmp->color_table);
}
return HeapFree( GetProcessHeap(), 0, bmp );
}
/***********************************************************************
* BITMAP_GetObject
*/
static INT BITMAP_GetObject( HGDIOBJ handle, INT count, LPVOID buffer )
{
INT ret;
BITMAPOBJ *bmp = GDI_GetObjPtr( handle, OBJ_BITMAP );
if (!bmp) return 0;
if (!buffer) ret = sizeof(BITMAP);
else if (count < sizeof(BITMAP)) ret = 0;
else if (bmp->dib)
{
if (count >= sizeof(DIBSECTION))
{
DIBSECTION *dib = buffer;
*dib = *bmp->dib;
dib->dsBmih.biHeight = abs( dib->dsBmih.biHeight );
ret = sizeof(DIBSECTION);
}
else /* if (count >= sizeof(BITMAP)) */
{
DIBSECTION *dib = bmp->dib;
memcpy( buffer, &dib->dsBm, sizeof(BITMAP) );
ret = sizeof(BITMAP);
}
}
else
{
memcpy( buffer, &bmp->bitmap, sizeof(BITMAP) );
((BITMAP *) buffer)->bmBits = NULL;
ret = sizeof(BITMAP);
}
GDI_ReleaseObj( handle );
return ret;
}
/******************************************************************************
* CreateDiscardableBitmap [GDI32.@]
*
* Creates a discardable bitmap.
*
* RETURNS
* Success: Handle to bitmap
* Failure: NULL
*/
HBITMAP WINAPI CreateDiscardableBitmap(
HDC hdc, /* [in] Handle to device context */
INT width, /* [in] Bitmap width */
INT height) /* [in] Bitmap height */
{
return CreateCompatibleBitmap( hdc, width, height );
}
/******************************************************************************
* GetBitmapDimensionEx [GDI32.@]
*
* Retrieves dimensions of a bitmap.
*
* RETURNS
* Success: TRUE
* Failure: FALSE
*/
BOOL WINAPI GetBitmapDimensionEx(
HBITMAP hbitmap, /* [in] Handle to bitmap */
LPSIZE size) /* [out] Address of struct receiving dimensions */
{
BITMAPOBJ * bmp = GDI_GetObjPtr( hbitmap, OBJ_BITMAP );
if (!bmp) return FALSE;
*size = bmp->size;
GDI_ReleaseObj( hbitmap );
return TRUE;
}
/******************************************************************************
* SetBitmapDimensionEx [GDI32.@]
*
* Assigns dimensions to a bitmap.
* MSDN says that this function will fail if hbitmap is a handle created by
* CreateDIBSection, but that's not true on Windows 2000.
*
* RETURNS
* Success: TRUE
* Failure: FALSE
*/
BOOL WINAPI SetBitmapDimensionEx(
HBITMAP hbitmap, /* [in] Handle to bitmap */
INT x, /* [in] Bitmap width */
INT y, /* [in] Bitmap height */
LPSIZE prevSize) /* [out] Address of structure for orig dims */
{
BITMAPOBJ * bmp = GDI_GetObjPtr( hbitmap, OBJ_BITMAP );
if (!bmp) return FALSE;
if (prevSize) *prevSize = bmp->size;
bmp->size.cx = x;
bmp->size.cy = y;
GDI_ReleaseObj( hbitmap );
return TRUE;
}

View File

@@ -0,0 +1,447 @@
/*
* GDI brush objects
*
* Copyright 1993, 1994 Alexandre Julliard
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "config.h"
#include <stdarg.h>
#include <string.h>
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "gdi_private.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(gdi);
/* GDI logical brush object */
typedef struct
{
GDIOBJHDR header;
LOGBRUSH logbrush;
} BRUSHOBJ;
#define NB_HATCH_STYLES 6
static HGDIOBJ BRUSH_SelectObject( HGDIOBJ handle, HDC hdc );
static INT BRUSH_GetObject( HGDIOBJ handle, INT count, LPVOID buffer );
static BOOL BRUSH_DeleteObject( HGDIOBJ handle );
static const struct gdi_obj_funcs brush_funcs =
{
BRUSH_SelectObject, /* pSelectObject */
BRUSH_GetObject, /* pGetObjectA */
BRUSH_GetObject, /* pGetObjectW */
NULL, /* pUnrealizeObject */
BRUSH_DeleteObject /* pDeleteObject */
};
static HGLOBAL dib_copy(const BITMAPINFO *info, UINT coloruse)
{
BITMAPINFO *newInfo;
HGLOBAL hmem;
INT size;
if (info->bmiHeader.biCompression != BI_RGB && info->bmiHeader.biCompression != BI_BITFIELDS)
size = info->bmiHeader.biSizeImage;
else
size = DIB_GetDIBImageBytes(info->bmiHeader.biWidth,
info->bmiHeader.biHeight,
info->bmiHeader.biBitCount);
size += bitmap_info_size( info, coloruse );
if (!(hmem = GlobalAlloc( GMEM_MOVEABLE, size )))
{
return 0;
}
newInfo = GlobalLock( hmem );
memcpy( newInfo, info, size );
GlobalUnlock( hmem );
return hmem;
}
/***********************************************************************
* CreateBrushIndirect (GDI32.@)
*
* Create a logical brush with a given style, color or pattern.
*
* PARAMS
* brush [I] Pointer to a LOGBRUSH structure describing the desired brush.
*
* RETURNS
* A handle to the created brush, or a NULL handle if the brush cannot be
* created.
*
* NOTES
* - The brush returned should be freed by the caller using DeleteObject()
* when it is no longer required.
* - Windows 95 and earlier cannot create brushes from bitmaps or DIBs larger
* than 8x8 pixels. If a larger bitmap is given, only a portion of the bitmap
* is used.
*/
HBRUSH WINAPI CreateBrushIndirect( const LOGBRUSH * brush )
{
BRUSHOBJ * ptr;
HBRUSH hbrush;
if (!(ptr = HeapAlloc( GetProcessHeap(), 0, sizeof(*ptr) ))) return 0;
ptr->logbrush.lbStyle = brush->lbStyle;
ptr->logbrush.lbColor = brush->lbColor;
ptr->logbrush.lbHatch = brush->lbHatch;
switch (ptr->logbrush.lbStyle)
{
case BS_PATTERN8X8:
ptr->logbrush.lbStyle = BS_PATTERN;
/* fall through */
case BS_PATTERN:
ptr->logbrush.lbHatch = (ULONG_PTR)BITMAP_CopyBitmap( (HBITMAP) ptr->logbrush.lbHatch );
if (!ptr->logbrush.lbHatch) goto error;
break;
case BS_DIBPATTERNPT:
ptr->logbrush.lbStyle = BS_DIBPATTERN;
ptr->logbrush.lbHatch = (ULONG_PTR)dib_copy( (BITMAPINFO *) ptr->logbrush.lbHatch,
ptr->logbrush.lbColor);
if (!ptr->logbrush.lbHatch) goto error;
break;
case BS_DIBPATTERN8X8:
case BS_DIBPATTERN:
{
BITMAPINFO* bmi;
HGLOBAL h = (HGLOBAL)ptr->logbrush.lbHatch;
ptr->logbrush.lbStyle = BS_DIBPATTERN;
if (!(bmi = GlobalLock( h ))) goto error;
ptr->logbrush.lbHatch = (ULONG_PTR)dib_copy( bmi, ptr->logbrush.lbColor);
GlobalUnlock( h );
if (!ptr->logbrush.lbHatch) goto error;
break;
}
default:
if(ptr->logbrush.lbStyle > BS_MONOPATTERN) goto error;
break;
}
if ((hbrush = alloc_gdi_handle( &ptr->header, OBJ_BRUSH, &brush_funcs )))
{
TRACE("%p\n", hbrush);
return hbrush;
}
error:
if (ptr->logbrush.lbHatch)
{
if (ptr->logbrush.lbStyle == BS_PATTERN)
DeleteObject( (HGDIOBJ)ptr->logbrush.lbHatch );
else if (ptr->logbrush.lbStyle == BS_DIBPATTERN)
GlobalFree( (HGLOBAL)ptr->logbrush.lbHatch );
}
HeapFree( GetProcessHeap(), 0, ptr );
return 0;
}
/***********************************************************************
* CreateHatchBrush (GDI32.@)
*
* Create a logical brush with a hatched pattern.
*
* PARAMS
* style [I] Direction of lines for the hatch pattern (HS_* values from "wingdi.h")
* color [I] Colour of the hatched pattern
*
* RETURNS
* A handle to the created brush, or a NULL handle if the brush cannot
* be created.
*
* NOTES
* - This function uses CreateBrushIndirect() to create the brush.
* - The brush returned should be freed by the caller using DeleteObject()
* when it is no longer required.
*/
HBRUSH WINAPI CreateHatchBrush( INT style, COLORREF color )
{
LOGBRUSH logbrush;
TRACE("%d %06x\n", style, color );
logbrush.lbStyle = BS_HATCHED;
logbrush.lbColor = color;
logbrush.lbHatch = style;
return CreateBrushIndirect( &logbrush );
}
/***********************************************************************
* CreatePatternBrush (GDI32.@)
*
* Create a logical brush with a pattern from a bitmap.
*
* PARAMS
* hbitmap [I] Bitmap containing pattern for the brush
*
* RETURNS
* A handle to the created brush, or a NULL handle if the brush cannot
* be created.
*
* NOTES
* - This function uses CreateBrushIndirect() to create the brush.
* - The brush returned should be freed by the caller using DeleteObject()
* when it is no longer required.
*/
HBRUSH WINAPI CreatePatternBrush( HBITMAP hbitmap )
{
LOGBRUSH logbrush = { BS_PATTERN, 0, 0 };
TRACE("%p\n", hbitmap );
logbrush.lbHatch = (ULONG_PTR)hbitmap;
return CreateBrushIndirect( &logbrush );
}
/***********************************************************************
* CreateDIBPatternBrush (GDI32.@)
*
* Create a logical brush with a pattern from a DIB.
*
* PARAMS
* hbitmap [I] Global object containing BITMAPINFO structure for the pattern
* coloruse [I] Specifies color format, if provided
*
* RETURNS
* A handle to the created brush, or a NULL handle if the brush cannot
* be created.
*
* NOTES
* - This function uses CreateBrushIndirect() to create the brush.
* - The brush returned should be freed by the caller using DeleteObject()
* when it is no longer required.
* - This function is for compatibility only. CreateDIBPatternBrushPt() should
* be used instead.
*/
HBRUSH WINAPI CreateDIBPatternBrush( HGLOBAL hbitmap, UINT coloruse )
{
LOGBRUSH logbrush;
TRACE("%p\n", hbitmap );
logbrush.lbStyle = BS_DIBPATTERN;
logbrush.lbColor = coloruse;
logbrush.lbHatch = (ULONG_PTR)hbitmap;
return CreateBrushIndirect( &logbrush );
}
/***********************************************************************
* CreateDIBPatternBrushPt (GDI32.@)
*
* Create a logical brush with a pattern from a DIB.
*
* PARAMS
* data [I] Pointer to a BITMAPINFO structure and image data for the pattern
* coloruse [I] Specifies color format, if provided
*
* RETURNS
* A handle to the created brush, or a NULL handle if the brush cannot
* be created.
*
* NOTES
* - This function uses CreateBrushIndirect() to create the brush.
* - The brush returned should be freed by the caller using DeleteObject()
* when it is no longer required.
*/
HBRUSH WINAPI CreateDIBPatternBrushPt( const void* data, UINT coloruse )
{
const BITMAPINFO *info=data;
LOGBRUSH logbrush;
if (!data)
return NULL;
TRACE("%p %dx%d %dbpp\n", info, info->bmiHeader.biWidth,
info->bmiHeader.biHeight, info->bmiHeader.biBitCount);
logbrush.lbStyle = BS_DIBPATTERNPT;
logbrush.lbColor = coloruse;
logbrush.lbHatch = (ULONG_PTR)data;
return CreateBrushIndirect( &logbrush );
}
/***********************************************************************
* CreateSolidBrush (GDI32.@)
*
* Create a logical brush consisting of a single colour.
*
* PARAMS
* color [I] Colour to make the solid brush
*
* RETURNS
* A handle to the newly created brush, or a NULL handle if the brush cannot
* be created.
*
* NOTES
* - This function uses CreateBrushIndirect() to create the brush.
* - The brush returned should be freed by the caller using DeleteObject()
* when it is no longer required.
*/
HBRUSH WINAPI CreateSolidBrush( COLORREF color )
{
LOGBRUSH logbrush;
TRACE("%06x\n", color );
logbrush.lbStyle = BS_SOLID;
logbrush.lbColor = color;
logbrush.lbHatch = 0;
return CreateBrushIndirect( &logbrush );
}
/***********************************************************************
* SetBrushOrgEx (GDI32.@)
*
* Set the brush origin for a device context.
*
* PARAMS
* hdc [I] Device context to set the brush origin for
* x [I] New x origin
* y [I] Ney y origin
* oldorg [O] If non NULL, destination for previously set brush origin.
*
* RETURNS
* Success: TRUE. The origin is set to (x,y), and oldorg is updated if given.
*/
BOOL WINAPI SetBrushOrgEx( HDC hdc, INT x, INT y, LPPOINT oldorg )
{
DC *dc = get_dc_ptr( hdc );
if (!dc) return FALSE;
if (oldorg)
{
oldorg->x = dc->brushOrgX;
oldorg->y = dc->brushOrgY;
}
dc->brushOrgX = x;
dc->brushOrgY = y;
release_dc_ptr( dc );
return TRUE;
}
/***********************************************************************
* FixBrushOrgEx (GDI32.@)
*
* See SetBrushOrgEx.
*
* NOTES
* This function is no longer documented by MSDN, but in Win95 GDI32 it
* is the same as SetBrushOrgEx().
*/
BOOL WINAPI FixBrushOrgEx( HDC hdc, INT x, INT y, LPPOINT oldorg )
{
return SetBrushOrgEx(hdc,x,y,oldorg);
}
/***********************************************************************
* BRUSH_SelectObject
*/
static HGDIOBJ BRUSH_SelectObject( HGDIOBJ handle, HDC hdc )
{
BRUSHOBJ *brush;
HGDIOBJ ret = 0;
DC *dc = get_dc_ptr( hdc );
if (!dc)
{
SetLastError( ERROR_INVALID_HANDLE );
return 0;
}
if ((brush = GDI_GetObjPtr( handle, OBJ_BRUSH )))
{
if (brush->logbrush.lbStyle == BS_PATTERN)
BITMAP_SetOwnerDC( (HBITMAP)brush->logbrush.lbHatch, dc );
GDI_inc_ref_count( handle );
GDI_ReleaseObj( handle );
if (dc->funcs->pSelectBrush && !dc->funcs->pSelectBrush( dc->physDev, handle ))
{
GDI_dec_ref_count( handle );
}
else
{
ret = dc->hBrush;
dc->hBrush = handle;
GDI_dec_ref_count( ret );
}
}
release_dc_ptr( dc );
return ret;
}
/***********************************************************************
* BRUSH_DeleteObject
*/
static BOOL BRUSH_DeleteObject( HGDIOBJ handle )
{
BRUSHOBJ *brush = free_gdi_handle( handle );
if (!brush) return FALSE;
switch(brush->logbrush.lbStyle)
{
case BS_PATTERN:
DeleteObject( (HGDIOBJ)brush->logbrush.lbHatch );
break;
case BS_DIBPATTERN:
GlobalFree( (HGLOBAL)brush->logbrush.lbHatch );
break;
}
return HeapFree( GetProcessHeap(), 0, brush );
}
/***********************************************************************
* BRUSH_GetObject
*/
static INT BRUSH_GetObject( HGDIOBJ handle, INT count, LPVOID buffer )
{
BRUSHOBJ *brush = GDI_GetObjPtr( handle, OBJ_BRUSH );
if (!brush) return 0;
if (buffer)
{
if (count > sizeof(brush->logbrush)) count = sizeof(brush->logbrush);
memcpy( buffer, &brush->logbrush, count );
}
else count = sizeof(brush->logbrush);
GDI_ReleaseObj( handle );
return count;
}

View File

@@ -0,0 +1,549 @@
/*
* DC clipping functions
*
* Copyright 1993 Alexandre Julliard
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <stdarg.h>
#include <stdlib.h>
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "gdi_private.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(clipping);
/***********************************************************************
* get_clip_region
*
* Return the total clip region (if any).
*/
static inline HRGN get_clip_region( DC * dc )
{
if (dc->hMetaClipRgn) return dc->hMetaClipRgn;
if (dc->hMetaRgn) return dc->hMetaRgn;
return dc->hClipRgn;
}
/***********************************************************************
* get_clip_rect
*
* Compute a clip rectangle from its logical coordinates.
*/
static inline RECT get_clip_rect( DC * dc, int left, int top, int right, int bottom )
{
RECT rect;
rect.left = left;
rect.top = top;
rect.right = right;
rect.bottom = bottom;
LPtoDP( dc->hSelf, (POINT *)&rect, 2 );
if (dc->layout & LAYOUT_RTL)
{
int tmp = rect.left;
rect.left = rect.right + 1;
rect.right = tmp + 1;
}
return rect;
}
/***********************************************************************
* CLIPPING_UpdateGCRegion
*
* Update the GC clip region when the ClipRgn or VisRgn have changed.
*/
void CLIPPING_UpdateGCRegion( DC * dc )
{
HRGN clip_rgn;
/* update the intersection of meta and clip regions */
if (dc->hMetaRgn && dc->hClipRgn)
{
if (!dc->hMetaClipRgn) dc->hMetaClipRgn = CreateRectRgn( 0, 0, 0, 0 );
CombineRgn( dc->hMetaClipRgn, dc->hClipRgn, dc->hMetaRgn, RGN_AND );
clip_rgn = dc->hMetaClipRgn;
}
else /* only one is set, no need for an intersection */
{
if (dc->hMetaClipRgn) DeleteObject( dc->hMetaClipRgn );
dc->hMetaClipRgn = 0;
clip_rgn = dc->hMetaRgn ? dc->hMetaRgn : dc->hClipRgn;
}
if (dc->funcs->pSetDeviceClipping)
dc->funcs->pSetDeviceClipping( dc->physDev, dc->hVisRgn, clip_rgn );
}
/***********************************************************************
* create_default_clip_region
*
* Create a default clipping region when none already exists.
*/
static inline void create_default_clip_region( DC * dc )
{
UINT width, height;
if (dc->header.type == OBJ_MEMDC)
{
BITMAP bitmap;
GetObjectW( dc->hBitmap, sizeof(bitmap), &bitmap );
width = bitmap.bmWidth;
height = bitmap.bmHeight;
}
else
{
width = GetDeviceCaps( dc->hSelf, DESKTOPHORZRES );
height = GetDeviceCaps( dc->hSelf, DESKTOPVERTRES );
}
dc->hClipRgn = CreateRectRgn( 0, 0, width, height );
}
/***********************************************************************
* SelectClipRgn (GDI32.@)
*/
INT WINAPI SelectClipRgn( HDC hdc, HRGN hrgn )
{
return ExtSelectClipRgn( hdc, hrgn, RGN_COPY );
}
/******************************************************************************
* ExtSelectClipRgn [GDI32.@]
*/
INT WINAPI ExtSelectClipRgn( HDC hdc, HRGN hrgn, INT fnMode )
{
INT retval;
RECT rect;
DC * dc = get_dc_ptr( hdc );
if (!dc) return ERROR;
TRACE("%p %p %d\n", hdc, hrgn, fnMode );
update_dc( dc );
if (dc->funcs->pExtSelectClipRgn)
{
retval = dc->funcs->pExtSelectClipRgn( dc->physDev, hrgn, fnMode );
release_dc_ptr( dc );
return retval;
}
if (!hrgn)
{
if (fnMode == RGN_COPY)
{
if (dc->hClipRgn) DeleteObject( dc->hClipRgn );
dc->hClipRgn = 0;
}
else
{
FIXME("Unimplemented: hrgn NULL in mode: %d\n", fnMode);
release_dc_ptr( dc );
return ERROR;
}
}
else
{
HRGN mirrored = 0;
if (dc->layout & LAYOUT_RTL)
{
if (!(mirrored = CreateRectRgn( 0, 0, 0, 0 )))
{
release_dc_ptr( dc );
return ERROR;
}
mirror_region( mirrored, hrgn, dc->vis_rect.right - dc->vis_rect.left );
hrgn = mirrored;
}
if (!dc->hClipRgn)
create_default_clip_region( dc );
if(fnMode == RGN_COPY)
CombineRgn( dc->hClipRgn, hrgn, 0, fnMode );
else
CombineRgn( dc->hClipRgn, dc->hClipRgn, hrgn, fnMode);
if (mirrored) DeleteObject( mirrored );
}
CLIPPING_UpdateGCRegion( dc );
release_dc_ptr( dc );
return GetClipBox(hdc, &rect);
}
/***********************************************************************
* __wine_set_visible_region (GDI32.@)
*/
void CDECL __wine_set_visible_region( HDC hdc, HRGN hrgn, const RECT *vis_rect )
{
DC * dc;
if (!(dc = get_dc_ptr( hdc ))) return;
TRACE( "%p %p %s\n", hdc, hrgn, wine_dbgstr_rect(vis_rect) );
/* map region to DC coordinates */
OffsetRgn( hrgn, -vis_rect->left, -vis_rect->top );
DeleteObject( dc->hVisRgn );
dc->dirty = 0;
dc->vis_rect = *vis_rect;
dc->hVisRgn = hrgn;
DC_UpdateXforms( dc );
CLIPPING_UpdateGCRegion( dc );
release_dc_ptr( dc );
}
/***********************************************************************
* OffsetClipRgn (GDI32.@)
*/
INT WINAPI OffsetClipRgn( HDC hdc, INT x, INT y )
{
INT ret = SIMPLEREGION;
DC *dc = get_dc_ptr( hdc );
if (!dc) return ERROR;
TRACE("%p %d,%d\n", hdc, x, y );
update_dc( dc );
if(dc->funcs->pOffsetClipRgn)
{
ret = dc->funcs->pOffsetClipRgn( dc->physDev, x, y );
/* FIXME: ret is just a success flag, we should return a proper value */
}
else if (dc->hClipRgn) {
x = MulDiv( x, dc->vportExtX, dc->wndExtX );
y = MulDiv( y, dc->vportExtY, dc->wndExtY );
if (dc->layout & LAYOUT_RTL) x = -x;
ret = OffsetRgn( dc->hClipRgn, x, y );
CLIPPING_UpdateGCRegion( dc );
}
release_dc_ptr( dc );
return ret;
}
/***********************************************************************
* ExcludeClipRect (GDI32.@)
*/
INT WINAPI ExcludeClipRect( HDC hdc, INT left, INT top,
INT right, INT bottom )
{
HRGN newRgn;
INT ret;
DC *dc = get_dc_ptr( hdc );
if (!dc) return ERROR;
TRACE("%p %dx%d,%dx%d\n", hdc, left, top, right, bottom );
update_dc( dc );
if(dc->funcs->pExcludeClipRect)
{
ret = dc->funcs->pExcludeClipRect( dc->physDev, left, top, right, bottom );
/* FIXME: ret is just a success flag, we should return a proper value */
}
else
{
RECT rect = get_clip_rect( dc, left, top, right, bottom );
if (!(newRgn = CreateRectRgnIndirect( &rect ))) ret = ERROR;
else
{
if (!dc->hClipRgn)
create_default_clip_region( dc );
ret = CombineRgn( dc->hClipRgn, dc->hClipRgn, newRgn, RGN_DIFF );
DeleteObject( newRgn );
}
if (ret != ERROR) CLIPPING_UpdateGCRegion( dc );
}
release_dc_ptr( dc );
return ret;
}
/***********************************************************************
* IntersectClipRect (GDI32.@)
*/
INT WINAPI IntersectClipRect( HDC hdc, INT left, INT top, INT right, INT bottom )
{
INT ret;
DC *dc = get_dc_ptr( hdc );
if (!dc) return ERROR;
TRACE("%p %d,%d - %d,%d\n", hdc, left, top, right, bottom );
update_dc( dc );
if(dc->funcs->pIntersectClipRect)
{
ret = dc->funcs->pIntersectClipRect( dc->physDev, left, top, right, bottom );
/* FIXME: ret is just a success flag, we should return a proper value */
}
else
{
RECT rect = get_clip_rect( dc, left, top, right, bottom );
if (!dc->hClipRgn)
{
dc->hClipRgn = CreateRectRgnIndirect( &rect );
ret = SIMPLEREGION;
}
else
{
HRGN newRgn;
if (!(newRgn = CreateRectRgnIndirect( &rect ))) ret = ERROR;
else
{
ret = CombineRgn( dc->hClipRgn, dc->hClipRgn, newRgn, RGN_AND );
DeleteObject( newRgn );
}
}
if (ret != ERROR) CLIPPING_UpdateGCRegion( dc );
}
release_dc_ptr( dc );
return ret;
}
/***********************************************************************
* PtVisible (GDI32.@)
*/
BOOL WINAPI PtVisible( HDC hdc, INT x, INT y )
{
POINT pt;
BOOL ret;
HRGN clip;
DC *dc = get_dc_ptr( hdc );
TRACE("%p %d,%d\n", hdc, x, y );
if (!dc) return FALSE;
pt.x = x;
pt.y = y;
LPtoDP( hdc, &pt, 1 );
update_dc( dc );
ret = PtInRegion( dc->hVisRgn, pt.x, pt.y );
if (ret && (clip = get_clip_region(dc))) ret = PtInRegion( clip, pt.x, pt.y );
release_dc_ptr( dc );
return ret;
}
/***********************************************************************
* RectVisible (GDI32.@)
*/
BOOL WINAPI RectVisible( HDC hdc, const RECT* rect )
{
RECT tmpRect;
BOOL ret;
HRGN clip;
DC *dc = get_dc_ptr( hdc );
if (!dc) return FALSE;
TRACE("%p %d,%dx%d,%d\n", hdc, rect->left, rect->top, rect->right, rect->bottom );
tmpRect = *rect;
LPtoDP( hdc, (POINT *)&tmpRect, 2 );
update_dc( dc );
if ((clip = get_clip_region(dc)))
{
HRGN hrgn = CreateRectRgn( 0, 0, 0, 0 );
CombineRgn( hrgn, dc->hVisRgn, clip, RGN_AND );
ret = RectInRegion( hrgn, &tmpRect );
DeleteObject( hrgn );
}
else ret = RectInRegion( dc->hVisRgn, &tmpRect );
release_dc_ptr( dc );
return ret;
}
/***********************************************************************
* GetClipBox (GDI32.@)
*/
INT WINAPI GetClipBox( HDC hdc, LPRECT rect )
{
INT ret;
HRGN clip;
DC *dc = get_dc_ptr( hdc );
if (!dc) return ERROR;
update_dc( dc );
if ((clip = get_clip_region(dc)))
{
HRGN hrgn = CreateRectRgn( 0, 0, 0, 0 );
CombineRgn( hrgn, dc->hVisRgn, clip, RGN_AND );
ret = GetRgnBox( hrgn, rect );
DeleteObject( hrgn );
}
else ret = GetRgnBox( dc->hVisRgn, rect );
if (dc->layout & LAYOUT_RTL)
{
int tmp = rect->left;
rect->left = rect->right - 1;
rect->right = tmp - 1;
}
DPtoLP( hdc, (LPPOINT)rect, 2 );
release_dc_ptr( dc );
TRACE("%p => %d %s\n", hdc, ret, wine_dbgstr_rect( rect ));
return ret;
}
/***********************************************************************
* GetClipRgn (GDI32.@)
*/
INT WINAPI GetClipRgn( HDC hdc, HRGN hRgn )
{
INT ret = -1;
DC * dc;
if ((dc = get_dc_ptr( hdc )))
{
if( dc->hClipRgn )
{
if( CombineRgn(hRgn, dc->hClipRgn, 0, RGN_COPY) != ERROR )
{
ret = 1;
if (dc->layout & LAYOUT_RTL)
mirror_region( hRgn, hRgn, dc->vis_rect.right - dc->vis_rect.left );
}
}
else ret = 0;
release_dc_ptr( dc );
}
return ret;
}
/***********************************************************************
* GetMetaRgn (GDI32.@)
*/
INT WINAPI GetMetaRgn( HDC hdc, HRGN hRgn )
{
INT ret = 0;
DC * dc = get_dc_ptr( hdc );
if (dc)
{
if (dc->hMetaRgn && CombineRgn( hRgn, dc->hMetaRgn, 0, RGN_COPY ) != ERROR)
{
ret = 1;
if (dc->layout & LAYOUT_RTL)
mirror_region( hRgn, hRgn, dc->vis_rect.right - dc->vis_rect.left );
}
release_dc_ptr( dc );
}
return ret;
}
/***********************************************************************
* GetRandomRgn [GDI32.@]
*
* NOTES
* This function is documented in MSDN online for the case of
* iCode == SYSRGN (4).
*
* For iCode == 1 it should return the clip region
* 2 " " " the meta region
* 3 " " " the intersection of the clip with
* the meta region (== 'Rao' region).
*
* See http://www.codeproject.com/gdi/cliprgnguide.asp
*/
INT WINAPI GetRandomRgn(HDC hDC, HRGN hRgn, INT iCode)
{
HRGN rgn;
DC *dc = get_dc_ptr( hDC );
if (!dc) return -1;
switch (iCode)
{
case 1:
rgn = dc->hClipRgn;
break;
case 2:
rgn = dc->hMetaRgn;
break;
case 3:
rgn = dc->hMetaClipRgn;
if(!rgn) rgn = dc->hClipRgn;
if(!rgn) rgn = dc->hMetaRgn;
break;
case SYSRGN: /* == 4 */
update_dc( dc );
rgn = dc->hVisRgn;
break;
default:
WARN("Unknown code %d\n", iCode);
release_dc_ptr( dc );
return -1;
}
if (rgn) CombineRgn( hRgn, rgn, 0, RGN_COPY );
release_dc_ptr( dc );
/* On Windows NT/2000, the SYSRGN returned is in screen coordinates */
if (iCode == SYSRGN && !(GetVersion() & 0x80000000))
OffsetRgn( hRgn, dc->vis_rect.left, dc->vis_rect.top );
return (rgn != 0);
}
/***********************************************************************
* SetMetaRgn (GDI32.@)
*/
INT WINAPI SetMetaRgn( HDC hdc )
{
INT ret;
RECT dummy;
DC *dc = get_dc_ptr( hdc );
if (!dc) return ERROR;
if (dc->hMetaClipRgn)
{
/* the intersection becomes the new meta region */
DeleteObject( dc->hMetaRgn );
DeleteObject( dc->hClipRgn );
dc->hMetaRgn = dc->hMetaClipRgn;
dc->hClipRgn = 0;
dc->hMetaClipRgn = 0;
}
else if (dc->hClipRgn)
{
dc->hMetaRgn = dc->hClipRgn;
dc->hClipRgn = 0;
}
/* else nothing to do */
/* Note: no need to call CLIPPING_UpdateGCRegion, the overall clip region hasn't changed */
ret = GetRgnBox( dc->hMetaRgn, &dummy );
release_dc_ptr( dc );
return ret;
}

2194
arwinss/client/gdi32/dc.c Normal file

File diff suppressed because it is too large Load Diff

1409
arwinss/client/gdi32/dib.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,706 @@
/*
* Graphics driver management functions
*
* Copyright 1994 Bob Amstadt
* Copyright 1996, 2001 Alexandre Julliard
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "config.h"
#include "wine/port.h"
#include <stdarg.h>
#include <string.h>
#include <stdio.h>
#include "windef.h"
#include "winbase.h"
#include "winreg.h"
//#include "ddrawgdi.h"
#include "wine/winbase16.h"
#include "gdi_private.h"
#include "wine/unicode.h"
#include "wine/list.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(driver);
struct graphics_driver
{
struct list entry;
HMODULE module; /* module handle */
DC_FUNCTIONS funcs;
};
static struct list drivers = LIST_INIT( drivers );
static struct graphics_driver *display_driver;
static CRITICAL_SECTION driver_section;
static CRITICAL_SECTION_DEBUG critsect_debug =
{
0, 0, &driver_section,
{ &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
0, 0, { (DWORD_PTR)(__FILE__ ": driver_section") }
};
static CRITICAL_SECTION driver_section = { &critsect_debug, -1, 0, 0, 0, 0 };
/**********************************************************************
* create_driver
*
* Allocate and fill the driver structure for a given module.
*/
static struct graphics_driver *create_driver( HMODULE module )
{
struct graphics_driver *driver;
if (!(driver = HeapAlloc( GetProcessHeap(), 0, sizeof(*driver)))) return NULL;
driver->module = module;
/* fill the function table */
if (module)
{
#define GET_FUNC(name) driver->funcs.p##name = (void*)GetProcAddress( module, #name )
GET_FUNC(AbortDoc);
GET_FUNC(AbortPath);
GET_FUNC(AlphaBlend);
GET_FUNC(AngleArc);
GET_FUNC(Arc);
GET_FUNC(ArcTo);
GET_FUNC(BeginPath);
GET_FUNC(BitBlt);
GET_FUNC(ChoosePixelFormat);
GET_FUNC(Chord);
GET_FUNC(CloseFigure);
GET_FUNC(CreateBitmap);
GET_FUNC(CreateDC);
GET_FUNC(CreateDIBSection);
GET_FUNC(DeleteBitmap);
GET_FUNC(DeleteDC);
GET_FUNC(DescribePixelFormat);
GET_FUNC(DeviceCapabilities);
GET_FUNC(Ellipse);
GET_FUNC(EndDoc);
GET_FUNC(EndPage);
GET_FUNC(EndPath);
GET_FUNC(EnumDeviceFonts);
GET_FUNC(EnumICMProfiles);
GET_FUNC(ExcludeClipRect);
GET_FUNC(ExtDeviceMode);
GET_FUNC(ExtEscape);
GET_FUNC(ExtFloodFill);
GET_FUNC(ExtSelectClipRgn);
GET_FUNC(ExtTextOut);
GET_FUNC(FillPath);
GET_FUNC(FillRgn);
GET_FUNC(FlattenPath);
GET_FUNC(FrameRgn);
GET_FUNC(GdiComment);
GET_FUNC(GetBitmapBits);
GET_FUNC(GetCharWidth);
GET_FUNC(GetDIBColorTable);
GET_FUNC(GetDIBits);
GET_FUNC(GetDeviceCaps);
GET_FUNC(GetDeviceGammaRamp);
GET_FUNC(GetICMProfile);
GET_FUNC(GetNearestColor);
GET_FUNC(GetPixel);
GET_FUNC(GetPixelFormat);
GET_FUNC(GetSystemPaletteEntries);
GET_FUNC(GetTextExtentExPoint);
GET_FUNC(GetTextMetrics);
GET_FUNC(IntersectClipRect);
GET_FUNC(InvertRgn);
GET_FUNC(LineTo);
GET_FUNC(MoveTo);
GET_FUNC(ModifyWorldTransform);
GET_FUNC(OffsetClipRgn);
GET_FUNC(OffsetViewportOrg);
GET_FUNC(OffsetWindowOrg);
GET_FUNC(PaintRgn);
GET_FUNC(PatBlt);
GET_FUNC(Pie);
GET_FUNC(PolyBezier);
GET_FUNC(PolyBezierTo);
GET_FUNC(PolyDraw);
GET_FUNC(PolyPolygon);
GET_FUNC(PolyPolyline);
GET_FUNC(Polygon);
GET_FUNC(Polyline);
GET_FUNC(PolylineTo);
GET_FUNC(RealizeDefaultPalette);
GET_FUNC(RealizePalette);
GET_FUNC(Rectangle);
GET_FUNC(ResetDC);
GET_FUNC(RestoreDC);
GET_FUNC(RoundRect);
GET_FUNC(SaveDC);
GET_FUNC(ScaleViewportExt);
GET_FUNC(ScaleWindowExt);
GET_FUNC(SelectBitmap);
GET_FUNC(SelectBrush);
GET_FUNC(SelectClipPath);
GET_FUNC(SelectFont);
GET_FUNC(SelectPalette);
GET_FUNC(SelectPen);
GET_FUNC(SetArcDirection);
GET_FUNC(SetBitmapBits);
GET_FUNC(SetBkColor);
GET_FUNC(SetBkMode);
GET_FUNC(SetDCBrushColor);
GET_FUNC(SetDCPenColor);
GET_FUNC(SetDIBColorTable);
GET_FUNC(SetDIBits);
GET_FUNC(SetDIBitsToDevice);
GET_FUNC(SetDeviceClipping);
GET_FUNC(SetDeviceGammaRamp);
GET_FUNC(SetMapMode);
GET_FUNC(SetMapperFlags);
GET_FUNC(SetPixel);
GET_FUNC(SetPixelFormat);
GET_FUNC(SetPolyFillMode);
GET_FUNC(SetROP2);
GET_FUNC(SetRelAbs);
GET_FUNC(SetStretchBltMode);
GET_FUNC(SetTextAlign);
GET_FUNC(SetTextCharacterExtra);
GET_FUNC(SetTextColor);
GET_FUNC(SetTextJustification);
GET_FUNC(SetViewportExt);
GET_FUNC(SetViewportOrg);
GET_FUNC(SetWindowExt);
GET_FUNC(SetWindowOrg);
GET_FUNC(SetWorldTransform);
GET_FUNC(StartDoc);
GET_FUNC(StartPage);
GET_FUNC(StretchBlt);
GET_FUNC(StretchDIBits);
GET_FUNC(StrokeAndFillPath);
GET_FUNC(StrokePath);
GET_FUNC(SwapBuffers);
GET_FUNC(UnrealizePalette);
GET_FUNC(WidenPath);
/* OpenGL32 */
GET_FUNC(wglCreateContext);
GET_FUNC(wglCreateContextAttribsARB);
GET_FUNC(wglDeleteContext);
GET_FUNC(wglGetProcAddress);
GET_FUNC(wglGetPbufferDCARB);
GET_FUNC(wglMakeContextCurrentARB);
GET_FUNC(wglMakeCurrent);
GET_FUNC(wglSetPixelFormatWINE);
GET_FUNC(wglShareLists);
GET_FUNC(wglUseFontBitmapsA);
GET_FUNC(wglUseFontBitmapsW);
#undef GET_FUNC
}
else memset( &driver->funcs, 0, sizeof(driver->funcs) );
return driver;
}
/**********************************************************************
* DRIVER_get_display_driver
*
* Special case for loading the display driver: get the name from the config file
*/
const DC_FUNCTIONS *DRIVER_get_display_driver(void)
{
struct graphics_driver *driver;
char buffer[MAX_PATH], libname[32], *name, *next;
HMODULE module = 0;
#if 0
HKEY hkey;
#endif
if (display_driver) return &display_driver->funcs; /* already loaded */
#ifndef __REACTOS__
strcpy( buffer, "x11" ); /* default value */
#else
strcpy( buffer, "nt" ); /* default value */
#endif
/* @@ Wine registry key: HKCU\Software\Wine\Drivers */
#if 0
if (!RegOpenKeyA( HKEY_CURRENT_USER, "Software\\Wine\\Drivers", &hkey ))
{
DWORD type, count = sizeof(buffer);
RegQueryValueExA( hkey, "Graphics", 0, &type, (LPBYTE) buffer, &count );
RegCloseKey( hkey );
}
#endif
name = buffer;
while (name)
{
next = strchr( name, ',' );
if (next) *next++ = 0;
_snprintf( libname, sizeof(libname), "wine%s.drv", name );
if ((module = LoadLibraryA( libname )) != 0) break;
name = next;
}
if (!(driver = create_driver( module )))
{
MESSAGE( "Could not create graphics driver '%s'\n", buffer );
FreeLibrary( module );
ExitProcess(1);
}
if (InterlockedCompareExchangePointer( (void **)&display_driver, driver, NULL ))
{
/* somebody beat us to it */
FreeLibrary( driver->module );
HeapFree( GetProcessHeap(), 0, driver );
}
return &display_driver->funcs;
}
/**********************************************************************
* DRIVER_load_driver
*/
const DC_FUNCTIONS *DRIVER_load_driver( LPCWSTR name )
{
HMODULE module;
struct graphics_driver *driver, *new_driver;
static const WCHAR displayW[] = { 'd','i','s','p','l','a','y',0 };
static const WCHAR display1W[] = {'\\','\\','.','\\','D','I','S','P','L','A','Y','1',0};
/* display driver is a special case */
if (!strcmpiW( name, displayW ) || !strcmpiW( name, display1W )) return DRIVER_get_display_driver();
if ((module = GetModuleHandleW( name )))
{
if (display_driver && display_driver->module == module) return &display_driver->funcs;
EnterCriticalSection( &driver_section );
LIST_FOR_EACH_ENTRY( driver, &drivers, struct graphics_driver, entry )
{
if (driver->module == module) goto done;
}
LeaveCriticalSection( &driver_section );
}
if (!(module = LoadLibraryW( name ))) return NULL;
if (!(new_driver = create_driver( module )))
{
FreeLibrary( module );
return NULL;
}
/* check if someone else added it in the meantime */
EnterCriticalSection( &driver_section );
LIST_FOR_EACH_ENTRY( driver, &drivers, struct graphics_driver, entry )
{
if (driver->module != module) continue;
FreeLibrary( module );
HeapFree( GetProcessHeap(), 0, new_driver );
goto done;
}
driver = new_driver;
list_add_head( &drivers, &driver->entry );
TRACE( "loaded driver %p for %s\n", driver, debugstr_w(name) );
done:
LeaveCriticalSection( &driver_section );
return &driver->funcs;
}
/*****************************************************************************
* DRIVER_GetDriverName
*
*/
BOOL DRIVER_GetDriverName( LPCWSTR device, LPWSTR driver, DWORD size )
{
static const WCHAR displayW[] = { 'd','i','s','p','l','a','y',0 };
static const WCHAR devicesW[] = { 'd','e','v','i','c','e','s',0 };
static const WCHAR display1W[] = {'\\','\\','.','\\','D','I','S','P','L','A','Y','1',0};
static const WCHAR empty_strW[] = { 0 };
WCHAR *p;
/* display is a special case */
if (!strcmpiW( device, displayW ) ||
!strcmpiW( device, display1W ))
{
lstrcpynW( driver, displayW, size );
return TRUE;
}
size = GetProfileStringW(devicesW, device, empty_strW, driver, size);
if(!size) {
WARN("Unable to find %s in [devices] section of win.ini\n", debugstr_w(device));
return FALSE;
}
p = strchrW(driver, ',');
if(!p)
{
WARN("%s entry in [devices] section of win.ini is malformed.\n", debugstr_w(device));
return FALSE;
}
*p = 0;
TRACE("Found %s for %s\n", debugstr_w(driver), debugstr_w(device));
return TRUE;
}
/***********************************************************************
* GdiConvertToDevmodeW (GDI32.@)
*/
DEVMODEW * WINAPI GdiConvertToDevmodeW(const DEVMODEA *dmA)
{
DEVMODEW *dmW;
WORD dmW_size, dmA_size;
dmA_size = dmA->dmSize;
/* this is the minimal dmSize that XP accepts */
if (dmA_size < FIELD_OFFSET(DEVMODEA, dmFields))
return NULL;
if (dmA_size > sizeof(DEVMODEA))
dmA_size = sizeof(DEVMODEA);
dmW_size = dmA_size + CCHDEVICENAME;
if (dmA_size >= FIELD_OFFSET(DEVMODEA, dmFormName) + CCHFORMNAME)
dmW_size += CCHFORMNAME;
dmW = HeapAlloc(GetProcessHeap(), 0, dmW_size + dmA->dmDriverExtra);
if (!dmW) return NULL;
MultiByteToWideChar(CP_ACP, 0, (const char*) dmA->dmDeviceName, -1,
dmW->dmDeviceName, CCHDEVICENAME);
/* copy slightly more, to avoid long computations */
memcpy(&dmW->dmSpecVersion, &dmA->dmSpecVersion, dmA_size - CCHDEVICENAME);
if (dmA_size >= FIELD_OFFSET(DEVMODEA, dmFormName) + CCHFORMNAME)
{
if (dmA->dmFields & DM_FORMNAME)
MultiByteToWideChar(CP_ACP, 0, (const char*) dmA->dmFormName, -1,
dmW->dmFormName, CCHFORMNAME);
else
dmW->dmFormName[0] = 0;
if (dmA_size > FIELD_OFFSET(DEVMODEA, dmLogPixels))
memcpy(&dmW->dmLogPixels, &dmA->dmLogPixels, dmA_size - FIELD_OFFSET(DEVMODEA, dmLogPixels));
}
if (dmA->dmDriverExtra)
memcpy((char *)dmW + dmW_size, (const char *)dmA + dmA_size, dmA->dmDriverExtra);
dmW->dmSize = dmW_size;
return dmW;
}
/*****************************************************************************
* @ [GDI32.100]
*
* This should thunk to 16-bit and simply call the proc with the given args.
*/
INT WINAPI GDI_CallDevInstall16( FARPROC16 lpfnDevInstallProc, HWND hWnd,
LPSTR lpModelName, LPSTR OldPort, LPSTR NewPort )
{
FIXME("(%p, %p, %s, %s, %s)\n", lpfnDevInstallProc, hWnd, lpModelName, OldPort, NewPort );
return -1;
}
/*****************************************************************************
* @ [GDI32.101]
*
* This should load the correct driver for lpszDevice and calls this driver's
* ExtDeviceModePropSheet proc.
*
* Note: The driver calls a callback routine for each property sheet page; these
* pages are supposed to be filled into the structure pointed to by lpPropSheet.
* The layout of this structure is:
*
* struct
* {
* DWORD nPages;
* DWORD unknown;
* HPROPSHEETPAGE pages[10];
* };
*/
INT WINAPI GDI_CallExtDeviceModePropSheet16( HWND hWnd, LPCSTR lpszDevice,
LPCSTR lpszPort, LPVOID lpPropSheet )
{
FIXME("(%p, %s, %s, %p)\n", hWnd, lpszDevice, lpszPort, lpPropSheet );
return -1;
}
/*****************************************************************************
* @ [GDI32.102]
*
* This should load the correct driver for lpszDevice and call this driver's
* ExtDeviceMode proc.
*
* FIXME: convert ExtDeviceMode to unicode in the driver interface
*/
INT WINAPI GDI_CallExtDeviceMode16( HWND hwnd,
LPDEVMODEA lpdmOutput, LPSTR lpszDevice,
LPSTR lpszPort, LPDEVMODEA lpdmInput,
LPSTR lpszProfile, DWORD fwMode )
{
WCHAR deviceW[300];
WCHAR bufW[300];
char buf[300];
HDC hdc;
DC *dc;
INT ret = -1;
TRACE("(%p, %p, %s, %s, %p, %s, %d)\n",
hwnd, lpdmOutput, lpszDevice, lpszPort, lpdmInput, lpszProfile, fwMode );
if (!lpszDevice) return -1;
if (!MultiByteToWideChar(CP_ACP, 0, lpszDevice, -1, deviceW, 300)) return -1;
if(!DRIVER_GetDriverName( deviceW, bufW, 300 )) return -1;
if (!WideCharToMultiByte(CP_ACP, 0, bufW, -1, buf, 300, NULL, NULL)) return -1;
if (!(hdc = CreateICA( buf, lpszDevice, lpszPort, NULL ))) return -1;
if ((dc = get_dc_ptr( hdc )))
{
if (dc->funcs->pExtDeviceMode)
ret = dc->funcs->pExtDeviceMode( buf, hwnd, lpdmOutput, lpszDevice, lpszPort,
lpdmInput, lpszProfile, fwMode );
release_dc_ptr( dc );
}
DeleteDC( hdc );
return ret;
}
/****************************************************************************
* @ [GDI32.103]
*
* This should load the correct driver for lpszDevice and calls this driver's
* AdvancedSetupDialog proc.
*/
INT WINAPI GDI_CallAdvancedSetupDialog16( HWND hwnd, LPSTR lpszDevice,
LPDEVMODEA devin, LPDEVMODEA devout )
{
TRACE("(%p, %s, %p, %p)\n", hwnd, lpszDevice, devin, devout );
return -1;
}
/*****************************************************************************
* @ [GDI32.104]
*
* This should load the correct driver for lpszDevice and calls this driver's
* DeviceCapabilities proc.
*
* FIXME: convert DeviceCapabilities to unicode in the driver interface
*/
DWORD WINAPI GDI_CallDeviceCapabilities16( LPCSTR lpszDevice, LPCSTR lpszPort,
WORD fwCapability, LPSTR lpszOutput,
LPDEVMODEA lpdm )
{
WCHAR deviceW[300];
WCHAR bufW[300];
char buf[300];
HDC hdc;
DC *dc;
INT ret = -1;
TRACE("(%s, %s, %d, %p, %p)\n", lpszDevice, lpszPort, fwCapability, lpszOutput, lpdm );
if (!lpszDevice) return -1;
if (!MultiByteToWideChar(CP_ACP, 0, lpszDevice, -1, deviceW, 300)) return -1;
if(!DRIVER_GetDriverName( deviceW, bufW, 300 )) return -1;
if (!WideCharToMultiByte(CP_ACP, 0, bufW, -1, buf, 300, NULL, NULL)) return -1;
if (!(hdc = CreateICA( buf, lpszDevice, lpszPort, NULL ))) return -1;
if ((dc = get_dc_ptr( hdc )))
{
if (dc->funcs->pDeviceCapabilities)
ret = dc->funcs->pDeviceCapabilities( buf, lpszDevice, lpszPort,
fwCapability, lpszOutput, lpdm );
release_dc_ptr( dc );
}
DeleteDC( hdc );
return ret;
}
/************************************************************************
* Escape [GDI32.@]
*/
INT WINAPI Escape( HDC hdc, INT escape, INT in_count, LPCSTR in_data, LPVOID out_data )
{
INT ret;
POINT *pt;
switch (escape)
{
case ABORTDOC:
return AbortDoc( hdc );
case ENDDOC:
return EndDoc( hdc );
case GETPHYSPAGESIZE:
pt = out_data;
pt->x = GetDeviceCaps( hdc, PHYSICALWIDTH );
pt->y = GetDeviceCaps( hdc, PHYSICALHEIGHT );
return 1;
case GETPRINTINGOFFSET:
pt = out_data;
pt->x = GetDeviceCaps( hdc, PHYSICALOFFSETX );
pt->y = GetDeviceCaps( hdc, PHYSICALOFFSETY );
return 1;
case GETSCALINGFACTOR:
pt = out_data;
pt->x = GetDeviceCaps( hdc, SCALINGFACTORX );
pt->y = GetDeviceCaps( hdc, SCALINGFACTORY );
return 1;
case NEWFRAME:
return EndPage( hdc );
case SETABORTPROC:
return SetAbortProc( hdc, (ABORTPROC)in_data );
case STARTDOC:
{
DOCINFOA doc;
char *name = NULL;
/* in_data may not be 0 terminated so we must copy it */
if (in_data)
{
name = HeapAlloc( GetProcessHeap(), 0, in_count+1 );
memcpy( name, in_data, in_count );
name[in_count] = 0;
}
/* out_data is actually a pointer to the DocInfo structure and used as
* a second input parameter */
if (out_data) doc = *(DOCINFOA *)out_data;
else
{
doc.cbSize = sizeof(doc);
doc.lpszOutput = NULL;
doc.lpszDatatype = NULL;
doc.fwType = 0;
}
doc.lpszDocName = name;
ret = StartDocA( hdc, &doc );
HeapFree( GetProcessHeap(), 0, name );
if (ret > 0) ret = StartPage( hdc );
return ret;
}
case QUERYESCSUPPORT:
{
const INT *ptr = (const INT *)in_data;
if (in_count < sizeof(INT)) return 0;
switch(*ptr)
{
case ABORTDOC:
case ENDDOC:
case GETPHYSPAGESIZE:
case GETPRINTINGOFFSET:
case GETSCALINGFACTOR:
case NEWFRAME:
case QUERYESCSUPPORT:
case SETABORTPROC:
case STARTDOC:
return TRUE;
}
break;
}
}
/* if not handled internally, pass it to the driver */
return ExtEscape( hdc, escape, in_count, in_data, 0, out_data );
}
/******************************************************************************
* ExtEscape [GDI32.@]
*
* Access capabilities of a particular device that are not available through GDI.
*
* PARAMS
* hdc [I] Handle to device context
* nEscape [I] Escape function
* cbInput [I] Number of bytes in input structure
* lpszInData [I] Pointer to input structure
* cbOutput [I] Number of bytes in output structure
* lpszOutData [O] Pointer to output structure
*
* RETURNS
* Success: >0
* Not implemented: 0
* Failure: <0
*/
INT WINAPI ExtEscape( HDC hdc, INT nEscape, INT cbInput, LPCSTR lpszInData,
INT cbOutput, LPSTR lpszOutData )
{
INT ret = 0;
DC * dc = get_dc_ptr( hdc );
if (dc)
{
if (dc->funcs->pExtEscape)
ret = dc->funcs->pExtEscape( dc->physDev, nEscape, cbInput, lpszInData, cbOutput, lpszOutData );
release_dc_ptr( dc );
}
return ret;
}
/*******************************************************************
* DrawEscape [GDI32.@]
*
*
*/
INT WINAPI DrawEscape(HDC hdc, INT nEscape, INT cbInput, LPCSTR lpszInData)
{
FIXME("DrawEscape, stub\n");
return 0;
}
/*******************************************************************
* NamedEscape [GDI32.@]
*/
INT WINAPI NamedEscape( HDC hdc, LPCWSTR pDriver, INT nEscape, INT cbInput, LPCSTR lpszInData,
INT cbOutput, LPSTR lpszOutData )
{
FIXME("(%p, %s, %d, %d, %p, %d, %p)\n",
hdc, wine_dbgstr_w(pDriver), nEscape, cbInput, lpszInData, cbOutput,
lpszOutData);
return 0;
}
/*******************************************************************
* DdQueryDisplaySettingsUniqueness [GDI32.@]
* GdiEntry13 [GDI32.@]
*/
ULONG WINAPI DdQueryDisplaySettingsUniqueness(VOID)
{
static int warn_once;
if (!warn_once++)
FIXME("stub\n");
return 0;
}

194
arwinss/client/gdi32/eng.c Normal file
View File

@@ -0,0 +1,194 @@
/*
* reactos/lib/gdi32/misc/eng.c
*
* GDI32.DLL eng part
*
*
*/
#include "config.h"
/* Definitions */
#define WIN32_NO_STATUS
#define _INC_WINDOWS
#define COM_NO_WINDOWS_H
#define NTOS_MODE_USER
#include <stdarg.h>
/* SDK/DDK/NDK Headers. */
#include <windef.h>
#include <winbase.h>
#include <winnls.h>
#include <objbase.h>
#include <ndk/rtlfuncs.h>
#include <wingdi.h>
#define _ENGINE_EXPORT_
#include <winddi.h>
#include <winuser.h>
#include "gdi_private.h"
/*
* @implemented
*/
VOID
WINAPI
EngAcquireSemaphore ( IN HSEMAPHORE hsem )
{
RtlEnterCriticalSection((PRTL_CRITICAL_SECTION)hsem);
}
/*
* @implemented
*/
HSEMAPHORE
WINAPI
EngCreateSemaphore ( VOID )
{
PRTL_CRITICAL_SECTION CritSect = RtlAllocateHeap(GetProcessHeap(), 0, sizeof(RTL_CRITICAL_SECTION));
if (!CritSect)
{
return NULL;
}
RtlInitializeCriticalSection( CritSect );
return (HSEMAPHORE)CritSect;
}
/*
* @implemented
*/
VOID
WINAPI
EngDeleteSemaphore ( IN HSEMAPHORE hsem )
{
if (hsem)
{
RtlDeleteCriticalSection( (PRTL_CRITICAL_SECTION) hsem );
RtlFreeHeap( GetProcessHeap(), 0, hsem );
}
}
/*
* @implemented
*/
PVOID WINAPI
EngFindResource(HANDLE h,
int iName,
int iType,
PULONG pulSize)
{
HRSRC HRSrc;
DWORD Size = 0;
HGLOBAL Hg;
LPVOID Lock = NULL;
HRSrc = FindResourceW((HMODULE)h, MAKEINTRESOURCEW(iName), MAKEINTRESOURCEW(iType));
if (HRSrc != NULL)
{
Size = SizeofResource((HMODULE)h, HRSrc);
if (Size != 0)
{
Hg = LoadResource((HMODULE)h, HRSrc);
if (Hg != NULL)
{
Lock = LockResource( Hg );
}
}
}
*pulSize = Size;
return (PVOID) Lock;
}
/*
* @implemented
*/
VOID WINAPI
EngFreeModule(HANDLE h)
{
FreeLibrary(h);
}
/*
* @implemented
*/
VOID WINAPI
EngGetCurrentCodePage( OUT PUSHORT OemCodePage,
OUT PUSHORT AnsiCodePage)
{
*OemCodePage = GetOEMCP();
*AnsiCodePage = GetACP();
}
/*
* @implemented
*/
HANDLE WINAPI
EngLoadModule(LPWSTR pwsz)
{
return LoadLibraryExW ( pwsz, NULL, LOAD_LIBRARY_AS_DATAFILE);
}
/*
* @implemented
*/
INT WINAPI
EngMultiByteToWideChar(UINT CodePage,
LPWSTR WideCharString,
INT BytesInWideCharString,
LPSTR MultiByteString,
INT BytesInMultiByteString)
{
return MultiByteToWideChar(CodePage,0,MultiByteString,BytesInMultiByteString,WideCharString,BytesInWideCharString / sizeof(WCHAR));
}
/*
* @implemented
*/
VOID WINAPI
EngQueryLocalTime(PENG_TIME_FIELDS etf)
{
SYSTEMTIME SystemTime;
GetLocalTime( &SystemTime );
etf->usYear = SystemTime.wYear;
etf->usMonth = SystemTime.wMonth;
etf->usWeekday = SystemTime.wDayOfWeek;
etf->usDay = SystemTime.wDay;
etf->usHour = SystemTime.wHour;
etf->usMinute = SystemTime.wMinute;
etf->usSecond = SystemTime.wSecond;
etf->usMilliseconds = SystemTime.wMilliseconds;
}
/*
* @implemented
*/
VOID
WINAPI
EngReleaseSemaphore ( IN HSEMAPHORE hsem )
{
RtlLeaveCriticalSection( (PRTL_CRITICAL_SECTION) hsem);
}
/*
* @implemented
*/
INT
WINAPI
EngWideCharToMultiByte( UINT CodePage,
LPWSTR WideCharString,
INT BytesInWideCharString,
LPSTR MultiByteString,
INT BytesInMultiByteString)
{
return WideCharToMultiByte(CodePage, 0, WideCharString, (BytesInWideCharString/sizeof(WCHAR)),
MultiByteString, BytesInMultiByteString, NULL, NULL);
}

View File

@@ -0,0 +1,100 @@
#include "config.h"
#include "wine/port.h"
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winnls.h"
#include "winerror.h"
#include "gdi_private.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(enhmetafile);
/**********************************************************************
* CreateEnhMetaFileW (GDI32.@)
*/
HDC WINAPI CreateEnhMetaFileW(
HDC hdc, /* [in] optional reference DC */
LPCWSTR filename, /* [in] optional filename for disk metafiles */
const RECT* rect, /* [in] optional bounding rectangle */
LPCWSTR description /* [in] optional description */
)
{
UNIMPLEMENTED;
return 0;
}
/**********************************************************************
* CreateEnhMetaFileA (GDI32.@)
*/
HDC WINAPI CreateEnhMetaFileA(
HDC hdc, /* [in] optional reference DC */
LPCSTR filename, /* [in] optional filename for disk metafiles */
const RECT *rect, /* [in] optional bounding rectangle */
LPCSTR description /* [in] optional description */
)
{
UNIMPLEMENTED;
return 0;
}
/**********************************************************************
* CreateMetaFileA (GDI32.@)
*
* See CreateMetaFileW.
*/
HDC WINAPI CreateMetaFileA(LPCSTR filename)
{
UNIMPLEMENTED;
return 0;
}
/**********************************************************************
* CreateMetaFileW (GDI32.@)
*
* Create a new DC and associate it with a metafile. Pass a filename
* to create a disk-based metafile, NULL to create a memory metafile.
*
* PARAMS
* filename [I] Filename of disk metafile
*
* RETURNS
* A handle to the metafile DC if successful, NULL on failure.
*/
HDC WINAPI CreateMetaFileW( LPCWSTR filename )
{
UNIMPLEMENTED;
return 0;
}
/******************************************************************
* CloseEnhMetaFile (GDI32.@)
*/
HENHMETAFILE WINAPI CloseEnhMetaFile(HDC hdc) /* [in] metafile DC */
{
UNIMPLEMENTED;
return NULL;
}
/******************************************************************
* CloseMetaFile (GDI32.@)
*
* Stop recording graphics operations in metafile associated with
* hdc and retrieve metafile.
*
* PARAMS
* hdc [I] Metafile DC to close
*
* RETURNS
* Handle of newly created metafile on success, NULL on failure.
*/
HMETAFILE WINAPI CloseMetaFile(HDC hdc)
{
UNIMPLEMENTED;
return NULL;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,331 @@
/*
* Enhanced MetaFile driver BitBlt functions
*
* Copyright 2002 Huw D M Davies for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <stdarg.h>
#include <string.h>
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "enhmetafiledrv.h"
#include "wine/debug.h"
BOOL CDECL EMFDRV_PatBlt( PHYSDEV dev, INT left, INT top,
INT width, INT height, DWORD rop )
{
EMRBITBLT emr;
BOOL ret;
emr.emr.iType = EMR_BITBLT;
emr.emr.nSize = sizeof(emr);
emr.rclBounds.left = left;
emr.rclBounds.top = top;
emr.rclBounds.right = left + width - 1;
emr.rclBounds.bottom = top + height - 1;
emr.xDest = left;
emr.yDest = top;
emr.cxDest = width;
emr.cyDest = height;
emr.dwRop = rop;
emr.xSrc = 0;
emr.ySrc = 0;
emr.xformSrc.eM11 = 1.0;
emr.xformSrc.eM12 = 0.0;
emr.xformSrc.eM21 = 0.0;
emr.xformSrc.eM22 = 1.0;
emr.xformSrc.eDx = 0.0;
emr.xformSrc.eDy = 0.0;
emr.crBkColorSrc = 0;
emr.iUsageSrc = 0;
emr.offBmiSrc = 0;
emr.cbBmiSrc = 0;
emr.offBitsSrc = 0;
emr.cbBitsSrc = 0;
ret = EMFDRV_WriteRecord( dev, &emr.emr );
if(ret)
EMFDRV_UpdateBBox( dev, &emr.rclBounds );
return ret;
}
/* Utilitarian function used by EMFDRV_BitBlt and EMFDRV_StretchBlt */
static BOOL EMFDRV_BitBlockTransfer(
PHYSDEV devDst, INT xDst, INT yDst, INT widthDst, INT heightDst,
PHYSDEV devSrc, INT xSrc, INT ySrc, INT widthSrc, INT heightSrc, DWORD rop,
DWORD emrType)
{
BOOL ret;
PEMRBITBLT pEMR;
UINT emrSize;
UINT bmiSize;
UINT bitsSize;
UINT size;
BITMAP BM;
WORD nBPP = 0;
LPBITMAPINFOHEADER lpBmiH;
BOOL useSrc;
EMFDRV_PDEVICE* physDevSrc = (EMFDRV_PDEVICE*)devSrc;
HBITMAP hBitmap = NULL;
useSrc = (((rop >> 2) & 0x330000) != (rop & 0x330000));
if (!physDevSrc && useSrc) return FALSE;
if (emrType == EMR_BITBLT)
emrSize = sizeof(EMRBITBLT);
else if (emrType == EMR_STRETCHBLT)
emrSize = sizeof(EMRSTRETCHBLT);
else
return FALSE;
if(useSrc)
{
hBitmap = GetCurrentObject(physDevSrc->hdc, OBJ_BITMAP);
if(sizeof(BITMAP) != GetObjectW(hBitmap, sizeof(BITMAP), &BM))
return FALSE;
nBPP = BM.bmPlanes * BM.bmBitsPixel;
if(nBPP > 8) nBPP = 24; /* FIXME Can't get 16bpp to work for some reason */
bitsSize = DIB_GetDIBWidthBytes(BM.bmWidth, nBPP) * BM.bmHeight;
bmiSize = sizeof(BITMAPINFOHEADER) +
(nBPP <= 8 ? 1 << nBPP : 0) * sizeof(RGBQUAD);
}
else
{
bitsSize = bmiSize = 0;
}
size = emrSize + bmiSize + bitsSize;
pEMR = HeapAlloc(GetProcessHeap(), 0, size);
if (!pEMR) return FALSE;
/* Initialize EMR */
pEMR->emr.iType = emrType;
pEMR->emr.nSize = size;
pEMR->rclBounds.left = xDst;
pEMR->rclBounds.top = yDst;
pEMR->rclBounds.right = xDst + widthDst - 1;
pEMR->rclBounds.bottom = yDst + heightDst - 1;
pEMR->xDest = xDst;
pEMR->yDest = yDst;
pEMR->cxDest = widthDst;
pEMR->cyDest = heightDst;
pEMR->dwRop = rop;
pEMR->xSrc = xSrc;
pEMR->ySrc = ySrc;
if (useSrc)
{
GetWorldTransform(physDevSrc->hdc, &pEMR->xformSrc);
pEMR->crBkColorSrc = GetBkColor(physDevSrc->hdc);
pEMR->iUsageSrc = DIB_RGB_COLORS;
pEMR->offBmiSrc = emrSize;
pEMR->offBitsSrc = emrSize + bmiSize;
}
else
{
pEMR->xformSrc.eM11 = 1.0; /** FIXME: */
pEMR->xformSrc.eM12 = 0.0; /** Setting default */
pEMR->xformSrc.eM21 = 0.0; /** value. */
pEMR->xformSrc.eM22 = 1.0; /** Where should we */
pEMR->xformSrc.eDx = 0.0; /** get that info */
pEMR->xformSrc.eDy = 0.0; /** ???? */
pEMR->crBkColorSrc = 0;
pEMR->iUsageSrc = 0;
pEMR->offBmiSrc = 0;
pEMR->offBitsSrc = 0;
}
pEMR->cbBmiSrc = bmiSize;
pEMR->cbBitsSrc = bitsSize;
if (emrType == EMR_STRETCHBLT)
{
PEMRSTRETCHBLT pEMRStretch = (PEMRSTRETCHBLT)pEMR;
pEMRStretch->cxSrc = widthSrc;
pEMRStretch->cySrc = heightSrc;
}
if (useSrc)
{
/* Initialize BITMAPINFO structure */
lpBmiH = (LPBITMAPINFOHEADER)((BYTE*)pEMR + pEMR->offBmiSrc);
lpBmiH->biSize = sizeof(BITMAPINFOHEADER);
lpBmiH->biWidth = BM.bmWidth;
lpBmiH->biHeight = BM.bmHeight;
lpBmiH->biPlanes = BM.bmPlanes;
lpBmiH->biBitCount = nBPP;
/* Assume the bitmap isn't compressed and set the BI_RGB flag. */
lpBmiH->biCompression = BI_RGB;
lpBmiH->biSizeImage = bitsSize;
lpBmiH->biYPelsPerMeter = 0;
lpBmiH->biXPelsPerMeter = 0;
lpBmiH->biClrUsed = nBPP <= 8 ? 1 << nBPP : 0;
/* Set biClrImportant to 0, indicating that all of the
device colors are important. */
lpBmiH->biClrImportant = 0;
/* Initialize bitmap bits */
if (GetDIBits(physDevSrc->hdc, hBitmap, 0, (UINT)lpBmiH->biHeight,
(BYTE*)pEMR + pEMR->offBitsSrc,
(LPBITMAPINFO)lpBmiH, DIB_RGB_COLORS))
{
ret = EMFDRV_WriteRecord(devDst, (EMR*)pEMR);
if (ret) EMFDRV_UpdateBBox(devDst, &(pEMR->rclBounds));
}
else
ret = FALSE;
}
else
{
ret = EMFDRV_WriteRecord(devDst, (EMR*)pEMR);
if (ret) EMFDRV_UpdateBBox(devDst, &(pEMR->rclBounds));
}
HeapFree( GetProcessHeap(), 0, pEMR);
return ret;
}
BOOL CDECL EMFDRV_BitBlt(
PHYSDEV devDst, INT xDst, INT yDst, INT width, INT height,
PHYSDEV devSrc, INT xSrc, INT ySrc, DWORD rop)
{
return EMFDRV_BitBlockTransfer( devDst, xDst, yDst, width, height,
devSrc, xSrc, ySrc, width, height,
rop, EMR_BITBLT );
}
BOOL CDECL EMFDRV_StretchBlt(
PHYSDEV devDst, INT xDst, INT yDst, INT widthDst, INT heightDst,
PHYSDEV devSrc, INT xSrc, INT ySrc, INT widthSrc, INT heightSrc, DWORD rop )
{
return EMFDRV_BitBlockTransfer( devDst, xDst, yDst, widthDst, heightDst,
devSrc, xSrc, ySrc, widthSrc, heightSrc,
rop, EMR_STRETCHBLT );
}
INT CDECL EMFDRV_StretchDIBits( PHYSDEV dev, INT xDst, INT yDst, INT widthDst,
INT heightDst, INT xSrc, INT ySrc,
INT widthSrc, INT heightSrc,
const void *bits, const BITMAPINFO *info,
UINT wUsage, DWORD dwRop )
{
EMRSTRETCHDIBITS *emr;
BOOL ret;
UINT bmi_size=0, bits_size, emr_size;
bits_size = DIB_GetDIBImageBytes(info->bmiHeader.biWidth,
info->bmiHeader.biHeight,
info->bmiHeader.biBitCount);
/* calculate the size of the colour table */
bmi_size = bitmap_info_size(info, wUsage);
emr_size = sizeof (EMRSTRETCHDIBITS) + bmi_size + bits_size;
emr = HeapAlloc(GetProcessHeap(), 0, emr_size );
if (!emr) return 0;
/* write a bitmap info header (with colours) to the record */
memcpy( &emr[1], info, bmi_size);
/* write bitmap bits to the record */
memcpy ( ( (BYTE *) (&emr[1]) ) + bmi_size, bits, bits_size);
/* fill in the EMR header at the front of our piece of memory */
emr->emr.iType = EMR_STRETCHDIBITS;
emr->emr.nSize = emr_size;
emr->xDest = xDst;
emr->yDest = yDst;
emr->cxDest = widthDst;
emr->cyDest = heightDst;
emr->dwRop = dwRop;
emr->xSrc = xSrc; /* FIXME: only save the piece of the bitmap needed */
emr->ySrc = ySrc;
emr->iUsageSrc = wUsage;
emr->offBmiSrc = sizeof (EMRSTRETCHDIBITS);
emr->cbBmiSrc = bmi_size;
emr->offBitsSrc = emr->offBmiSrc + bmi_size;
emr->cbBitsSrc = bits_size;
emr->cxSrc = widthSrc;
emr->cySrc = heightSrc;
emr->rclBounds.left = xDst;
emr->rclBounds.top = yDst;
emr->rclBounds.right = xDst + widthDst;
emr->rclBounds.bottom = yDst + heightDst;
/* save the record we just created */
ret = EMFDRV_WriteRecord( dev, &emr->emr );
if(ret)
EMFDRV_UpdateBBox( dev, &emr->rclBounds );
HeapFree(GetProcessHeap(), 0, emr);
return ret ? heightSrc : GDI_ERROR;
}
INT CDECL EMFDRV_SetDIBitsToDevice(
PHYSDEV dev, INT xDst, INT yDst, DWORD width, DWORD height,
INT xSrc, INT ySrc, UINT startscan, UINT lines,
LPCVOID bits, const BITMAPINFO *info, UINT wUsage )
{
EMRSETDIBITSTODEVICE* pEMR;
DWORD size, bmiSize, bitsSize;
bmiSize = bitmap_info_size(info, wUsage);
bitsSize = DIB_GetDIBImageBytes( info->bmiHeader.biWidth,
info->bmiHeader.biHeight,
info->bmiHeader.biBitCount );
size = sizeof(EMRSETDIBITSTODEVICE) + bmiSize + bitsSize;
pEMR = HeapAlloc(GetProcessHeap(), 0, size);
if (!pEMR) return 0;
pEMR->emr.iType = EMR_SETDIBITSTODEVICE;
pEMR->emr.nSize = size;
pEMR->rclBounds.left = xDst;
pEMR->rclBounds.top = yDst;
pEMR->rclBounds.right = xDst + width - 1;
pEMR->rclBounds.bottom = yDst + height - 1;
pEMR->xDest = xDst;
pEMR->yDest = yDst;
pEMR->xSrc = xSrc;
pEMR->ySrc = ySrc;
pEMR->cxSrc = width;
pEMR->cySrc = height;
pEMR->offBmiSrc = sizeof(EMRSETDIBITSTODEVICE);
pEMR->cbBmiSrc = bmiSize;
pEMR->offBitsSrc = sizeof(EMRSETDIBITSTODEVICE) + bmiSize;
pEMR->cbBitsSrc = bitsSize;
pEMR->iUsageSrc = wUsage;
pEMR->iStartScan = startscan;
pEMR->cScans = lines;
memcpy((BYTE*)pEMR + pEMR->offBmiSrc, info, bmiSize);
memcpy((BYTE*)pEMR + pEMR->offBitsSrc, bits, bitsSize);
if (EMFDRV_WriteRecord(dev, (EMR*)pEMR))
EMFDRV_UpdateBBox(dev, &(pEMR->rclBounds));
HeapFree( GetProcessHeap(), 0, pEMR);
return lines;
}

View File

@@ -0,0 +1,339 @@
/*
* Enhanced MetaFile driver dc value functions
*
* Copyright 1999 Huw D M Davies
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "enhmfdrv/enhmetafiledrv.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(enhmetafile);
INT CDECL EMFDRV_SaveDC( PHYSDEV dev )
{
EMFDRV_PDEVICE* physDev = (EMFDRV_PDEVICE*)dev;
INT ret = save_dc_state( physDev->hdc );
EMRSAVEDC emr;
if (ret)
{
emr.emr.iType = EMR_SAVEDC;
emr.emr.nSize = sizeof(emr);
EMFDRV_WriteRecord( dev, &emr.emr );
}
return ret;
}
BOOL CDECL EMFDRV_RestoreDC( PHYSDEV dev, INT level )
{
EMFDRV_PDEVICE* physDev = (EMFDRV_PDEVICE*)dev;
DC *dc = get_dc_ptr( physDev->hdc );
EMRRESTOREDC emr;
BOOL ret;
emr.emr.iType = EMR_RESTOREDC;
emr.emr.nSize = sizeof(emr);
if (level < 0)
emr.iRelative = level;
else
emr.iRelative = level - dc->saveLevel - 1;
release_dc_ptr( dc );
physDev->restoring++;
ret = restore_dc_state( physDev->hdc, level );
physDev->restoring--;
if (ret) EMFDRV_WriteRecord( dev, &emr.emr );
return ret;
}
UINT CDECL EMFDRV_SetTextAlign( PHYSDEV dev, UINT align )
{
EMRSETTEXTALIGN emr;
emr.emr.iType = EMR_SETTEXTALIGN;
emr.emr.nSize = sizeof(emr);
emr.iMode = align;
return EMFDRV_WriteRecord( dev, &emr.emr );
}
BOOL CDECL EMFDRV_SetTextJustification(PHYSDEV dev, INT nBreakExtra, INT nBreakCount)
{
EMRSETTEXTJUSTIFICATION emr;
emr.emr.iType = EMR_SETTEXTJUSTIFICATION;
emr.emr.nSize = sizeof(emr);
emr.nBreakExtra = nBreakExtra;
emr.nBreakCount = nBreakCount;
return EMFDRV_WriteRecord(dev, &emr.emr);
}
INT CDECL EMFDRV_SetBkMode( PHYSDEV dev, INT mode )
{
EMRSETBKMODE emr;
emr.emr.iType = EMR_SETBKMODE;
emr.emr.nSize = sizeof(emr);
emr.iMode = mode;
return EMFDRV_WriteRecord( dev, &emr.emr );
}
INT CDECL EMFDRV_SetROP2( PHYSDEV dev, INT rop )
{
EMRSETROP2 emr;
emr.emr.iType = EMR_SETROP2;
emr.emr.nSize = sizeof(emr);
emr.iMode = rop;
return EMFDRV_WriteRecord( dev, &emr.emr );
}
INT CDECL EMFDRV_SetPolyFillMode( PHYSDEV dev, INT mode )
{
EMRSETPOLYFILLMODE emr;
emr.emr.iType = EMR_SETPOLYFILLMODE;
emr.emr.nSize = sizeof(emr);
emr.iMode = mode;
return EMFDRV_WriteRecord( dev, &emr.emr );
}
INT CDECL EMFDRV_SetStretchBltMode( PHYSDEV dev, INT mode )
{
EMRSETSTRETCHBLTMODE emr;
emr.emr.iType = EMR_SETSTRETCHBLTMODE;
emr.emr.nSize = sizeof(emr);
emr.iMode = mode;
return EMFDRV_WriteRecord( dev, &emr.emr );
}
INT CDECL EMFDRV_ExcludeClipRect( PHYSDEV dev, INT left, INT top, INT right, INT bottom )
{
EMREXCLUDECLIPRECT emr;
emr.emr.iType = EMR_EXCLUDECLIPRECT;
emr.emr.nSize = sizeof(emr);
emr.rclClip.left = left;
emr.rclClip.top = top;
emr.rclClip.right = right;
emr.rclClip.bottom = bottom;
return EMFDRV_WriteRecord( dev, &emr.emr );
}
INT CDECL EMFDRV_IntersectClipRect( PHYSDEV dev, INT left, INT top, INT right, INT bottom)
{
EMRINTERSECTCLIPRECT emr;
emr.emr.iType = EMR_INTERSECTCLIPRECT;
emr.emr.nSize = sizeof(emr);
emr.rclClip.left = left;
emr.rclClip.top = top;
emr.rclClip.right = right;
emr.rclClip.bottom = bottom;
return EMFDRV_WriteRecord( dev, &emr.emr );
}
INT CDECL EMFDRV_OffsetClipRgn( PHYSDEV dev, INT x, INT y )
{
EMROFFSETCLIPRGN emr;
emr.emr.iType = EMR_OFFSETCLIPRGN;
emr.emr.nSize = sizeof(emr);
emr.ptlOffset.x = x;
emr.ptlOffset.y = y;
return EMFDRV_WriteRecord( dev, &emr.emr );
}
INT CDECL EMFDRV_ExtSelectClipRgn( PHYSDEV dev, HRGN hrgn, INT mode )
{
EMREXTSELECTCLIPRGN *emr;
DWORD size, rgnsize;
BOOL ret;
if (!hrgn)
{
if (mode != RGN_COPY) return ERROR;
rgnsize = 0;
}
else rgnsize = GetRegionData( hrgn, 0, NULL );
size = rgnsize + offsetof(EMREXTSELECTCLIPRGN,RgnData);
emr = HeapAlloc( GetProcessHeap(), 0, size );
if (rgnsize) GetRegionData( hrgn, rgnsize, (RGNDATA *)&emr->RgnData );
emr->emr.iType = EMR_EXTSELECTCLIPRGN;
emr->emr.nSize = size;
emr->cbRgnData = rgnsize;
emr->iMode = mode;
ret = EMFDRV_WriteRecord( dev, &emr->emr );
HeapFree( GetProcessHeap(), 0, emr );
return ret ? SIMPLEREGION : ERROR;
}
DWORD CDECL EMFDRV_SetMapperFlags( PHYSDEV dev, DWORD flags )
{
EMRSETMAPPERFLAGS emr;
emr.emr.iType = EMR_SETMAPPERFLAGS;
emr.emr.nSize = sizeof(emr);
emr.dwFlags = flags;
return EMFDRV_WriteRecord( dev, &emr.emr );
}
BOOL CDECL EMFDRV_AbortPath( PHYSDEV dev )
{
EMRABORTPATH emr;
emr.emr.iType = EMR_ABORTPATH;
emr.emr.nSize = sizeof(emr);
return EMFDRV_WriteRecord( dev, &emr.emr );
}
BOOL CDECL EMFDRV_BeginPath( PHYSDEV dev )
{
EMRBEGINPATH emr;
emr.emr.iType = EMR_BEGINPATH;
emr.emr.nSize = sizeof(emr);
return EMFDRV_WriteRecord( dev, &emr.emr );
}
BOOL CDECL EMFDRV_CloseFigure( PHYSDEV dev )
{
EMRCLOSEFIGURE emr;
emr.emr.iType = EMR_CLOSEFIGURE;
emr.emr.nSize = sizeof(emr);
return EMFDRV_WriteRecord( dev, &emr.emr );
}
BOOL CDECL EMFDRV_EndPath( PHYSDEV dev )
{
EMRENDPATH emr;
emr.emr.iType = EMR_ENDPATH;
emr.emr.nSize = sizeof(emr);
return EMFDRV_WriteRecord( dev, &emr.emr );
}
BOOL CDECL EMFDRV_FillPath( PHYSDEV dev )
{
EMRFILLPATH emr;
emr.emr.iType = EMR_FILLPATH;
emr.emr.nSize = sizeof(emr);
FIXME("Bounds\n");
emr.rclBounds.left = 0;
emr.rclBounds.top = 0;
emr.rclBounds.right = 0;
emr.rclBounds.bottom = 0;
return EMFDRV_WriteRecord( dev, &emr.emr );
}
BOOL CDECL EMFDRV_FlattenPath( PHYSDEV dev )
{
EMRFLATTENPATH emr;
emr.emr.iType = EMR_FLATTENPATH;
emr.emr.nSize = sizeof(emr);
return EMFDRV_WriteRecord( dev, &emr.emr );
}
BOOL CDECL EMFDRV_SelectClipPath( PHYSDEV dev, INT iMode )
{
EMRSELECTCLIPPATH emr;
emr.emr.iType = EMR_SELECTCLIPPATH;
emr.emr.nSize = sizeof(emr);
emr.iMode = iMode;
return EMFDRV_WriteRecord( dev, &emr.emr );
}
BOOL CDECL EMFDRV_StrokeAndFillPath( PHYSDEV dev )
{
EMRSTROKEANDFILLPATH emr;
emr.emr.iType = EMR_STROKEANDFILLPATH;
emr.emr.nSize = sizeof(emr);
FIXME("Bounds\n");
emr.rclBounds.left = 0;
emr.rclBounds.top = 0;
emr.rclBounds.right = 0;
emr.rclBounds.bottom = 0;
return EMFDRV_WriteRecord( dev, &emr.emr );
}
BOOL CDECL EMFDRV_StrokePath( PHYSDEV dev )
{
EMRSTROKEPATH emr;
emr.emr.iType = EMR_STROKEPATH;
emr.emr.nSize = sizeof(emr);
FIXME("Bounds\n");
emr.rclBounds.left = 0;
emr.rclBounds.top = 0;
emr.rclBounds.right = 0;
emr.rclBounds.bottom = 0;
return EMFDRV_WriteRecord( dev, &emr.emr );
}
BOOL CDECL EMFDRV_WidenPath( PHYSDEV dev )
{
EMRWIDENPATH emr;
emr.emr.iType = EMR_WIDENPATH;
emr.emr.nSize = sizeof(emr);
return EMFDRV_WriteRecord( dev, &emr.emr );
}
INT CDECL EMFDRV_GetDeviceCaps(PHYSDEV dev, INT cap)
{
EMFDRV_PDEVICE *physDev = (EMFDRV_PDEVICE*) dev;
switch(cap) {
case HORZRES:
return physDev->horzres;
case VERTRES:
return physDev->vertres;
case LOGPIXELSX:
return physDev->logpixelsx;
case LOGPIXELSY:
return physDev->logpixelsy;
case HORZSIZE:
return physDev->horzsize;
case VERTSIZE:
return physDev->vertsize;
case BITSPIXEL:
return physDev->bitspixel;
case TEXTCAPS:
return physDev->textcaps;
case RASTERCAPS:
return physDev->rastercaps;
case TECHNOLOGY:
return physDev->technology;
case PLANES:
return physDev->planes;
case NUMCOLORS:
return physDev->numcolors;
default:
FIXME("Unimplemented cap %d\n", cap);
return 0;
}
}

View File

@@ -0,0 +1,164 @@
/*
* Enhanced MetaFile driver definitions
*
* Copyright 1999 Huw D M Davies
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef __WINE_ENHMETAFILEDRV_H
#define __WINE_ENHMETAFILEDRV_H
#include <stdarg.h>
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "gdi_private.h"
/* Enhanced Metafile driver physical DC */
typedef struct
{
HDC hdc;
ENHMETAHEADER *emh; /* Pointer to enhanced metafile header */
UINT handles_size, cur_handles;
HGDIOBJ *handles;
HANDLE hFile; /* Handle for disk based MetaFile */
INT horzres, vertres;
INT horzsize, vertsize;
INT logpixelsx, logpixelsy;
INT bitspixel;
INT textcaps;
INT rastercaps;
INT technology;
INT planes;
INT numcolors;
INT restoring; /* RestoreDC counter */
} EMFDRV_PDEVICE;
extern BOOL EMFDRV_WriteRecord( PHYSDEV dev, EMR *emr ) DECLSPEC_HIDDEN;
extern void EMFDRV_UpdateBBox( PHYSDEV dev, RECTL *rect ) DECLSPEC_HIDDEN;
extern DWORD EMFDRV_CreateBrushIndirect( PHYSDEV dev, HBRUSH hBrush ) DECLSPEC_HIDDEN;
#define HANDLE_LIST_INC 20
/* Metafile driver functions */
extern BOOL CDECL EMFDRV_AbortPath( PHYSDEV dev ) DECLSPEC_HIDDEN;
extern BOOL CDECL EMFDRV_Arc( PHYSDEV dev, INT left, INT top, INT right,
INT bottom, INT xstart, INT ystart, INT xend,
INT yend ) DECLSPEC_HIDDEN;
extern BOOL CDECL EMFDRV_BeginPath( PHYSDEV dev ) DECLSPEC_HIDDEN;
extern BOOL CDECL EMFDRV_BitBlt( PHYSDEV devDst, INT xDst, INT yDst,
INT width, INT height, PHYSDEV devSrc,
INT xSrc, INT ySrc, DWORD rop ) DECLSPEC_HIDDEN;
extern BOOL CDECL EMFDRV_Chord( PHYSDEV dev, INT left, INT top, INT right,
INT bottom, INT xstart, INT ystart, INT xend,
INT yend ) DECLSPEC_HIDDEN;
extern BOOL CDECL EMFDRV_CloseFigure( PHYSDEV dev ) DECLSPEC_HIDDEN;
extern BOOL CDECL EMFDRV_DeleteObject( PHYSDEV dev, HGDIOBJ obj ) DECLSPEC_HIDDEN;
extern BOOL CDECL EMFDRV_Ellipse( PHYSDEV dev, INT left, INT top,
INT right, INT bottom ) DECLSPEC_HIDDEN;
extern BOOL CDECL EMFDRV_EndPath( PHYSDEV dev ) DECLSPEC_HIDDEN;
extern INT CDECL EMFDRV_ExcludeClipRect( PHYSDEV dev, INT left, INT top, INT right, INT bottom ) DECLSPEC_HIDDEN;
extern BOOL CDECL EMFDRV_ExtFloodFill( PHYSDEV dev, INT x, INT y, COLORREF color, UINT fillType ) DECLSPEC_HIDDEN;
extern INT CDECL EMFDRV_ExtSelectClipRgn( PHYSDEV dev, HRGN hrgn, INT mode ) DECLSPEC_HIDDEN;
extern BOOL CDECL EMFDRV_ExtTextOut( PHYSDEV dev, INT x, INT y,
UINT flags, const RECT *lprect, LPCWSTR str,
UINT count, const INT *lpDx ) DECLSPEC_HIDDEN;
extern BOOL CDECL EMFDRV_FillPath( PHYSDEV dev ) DECLSPEC_HIDDEN;
extern BOOL CDECL EMFDRV_FillRgn( PHYSDEV dev, HRGN hrgn, HBRUSH hbrush ) DECLSPEC_HIDDEN;
extern BOOL CDECL EMFDRV_FlattenPath( PHYSDEV dev ) DECLSPEC_HIDDEN;
extern BOOL CDECL EMFDRV_FrameRgn( PHYSDEV dev, HRGN hrgn, HBRUSH hbrush, INT width,
INT height ) DECLSPEC_HIDDEN;
extern BOOL CDECL EMFDRV_GdiComment( PHYSDEV dev, UINT bytes, CONST BYTE *buffer ) DECLSPEC_HIDDEN;
extern INT CDECL EMFDRV_GetDeviceCaps( PHYSDEV dev, INT cap ) DECLSPEC_HIDDEN;
extern INT CDECL EMFDRV_IntersectClipRect( PHYSDEV dev, INT left, INT top, INT right,
INT bottom ) DECLSPEC_HIDDEN;
extern BOOL CDECL EMFDRV_InvertRgn( PHYSDEV dev, HRGN hrgn ) DECLSPEC_HIDDEN;
extern BOOL CDECL EMFDRV_LineTo( PHYSDEV dev, INT x, INT y ) DECLSPEC_HIDDEN;
extern BOOL CDECL EMFDRV_ModifyWorldTransform( PHYSDEV dev, const XFORM *xform, INT mode ) DECLSPEC_HIDDEN;
extern BOOL CDECL EMFDRV_MoveTo( PHYSDEV dev, INT x, INT y ) DECLSPEC_HIDDEN;
extern INT CDECL EMFDRV_OffsetClipRgn( PHYSDEV dev, INT x, INT y ) DECLSPEC_HIDDEN;
extern INT CDECL EMFDRV_OffsetViewportOrg( PHYSDEV dev, INT x, INT y ) DECLSPEC_HIDDEN;
extern INT CDECL EMFDRV_OffsetWindowOrg( PHYSDEV dev, INT x, INT y ) DECLSPEC_HIDDEN;
extern BOOL CDECL EMFDRV_PaintRgn( PHYSDEV dev, HRGN hrgn ) DECLSPEC_HIDDEN;
extern BOOL CDECL EMFDRV_PatBlt( PHYSDEV dev, INT left, INT top,
INT width, INT height, DWORD rop ) DECLSPEC_HIDDEN;
extern BOOL CDECL EMFDRV_Pie( PHYSDEV dev, INT left, INT top, INT right,
INT bottom, INT xstart, INT ystart, INT xend,
INT yend ) DECLSPEC_HIDDEN;
extern BOOL CDECL EMFDRV_PolyPolygon( PHYSDEV dev, const POINT* pt,
const INT* counts, UINT polys) DECLSPEC_HIDDEN;
extern BOOL CDECL EMFDRV_PolyPolyline( PHYSDEV dev, const POINT* pt,
const DWORD* counts, DWORD polys) DECLSPEC_HIDDEN;
extern BOOL CDECL EMFDRV_Polygon( PHYSDEV dev, const POINT* pt, INT count ) DECLSPEC_HIDDEN;
extern BOOL CDECL EMFDRV_Polyline( PHYSDEV dev, const POINT* pt,INT count) DECLSPEC_HIDDEN;
extern BOOL CDECL EMFDRV_Rectangle( PHYSDEV dev, INT left, INT top,
INT right, INT bottom) DECLSPEC_HIDDEN;
extern BOOL CDECL EMFDRV_RestoreDC( PHYSDEV dev, INT level ) DECLSPEC_HIDDEN;
extern BOOL CDECL EMFDRV_RoundRect( PHYSDEV dev, INT left, INT top,
INT right, INT bottom, INT ell_width,
INT ell_height ) DECLSPEC_HIDDEN;
extern INT CDECL EMFDRV_SaveDC( PHYSDEV dev ) DECLSPEC_HIDDEN;
extern INT CDECL EMFDRV_ScaleViewportExt( PHYSDEV dev, INT xNum,
INT xDenom, INT yNum, INT yDenom ) DECLSPEC_HIDDEN;
extern INT CDECL EMFDRV_ScaleWindowExt( PHYSDEV dev, INT xNum, INT xDenom,
INT yNum, INT yDenom ) DECLSPEC_HIDDEN;
extern HBITMAP CDECL EMFDRV_SelectBitmap( PHYSDEV dev, HBITMAP handle ) DECLSPEC_HIDDEN;
extern HBRUSH CDECL EMFDRV_SelectBrush( PHYSDEV dev, HBRUSH handle ) DECLSPEC_HIDDEN;
extern BOOL CDECL EMFDRV_SelectClipPath( PHYSDEV dev, INT iMode ) DECLSPEC_HIDDEN;
extern HFONT CDECL EMFDRV_SelectFont( PHYSDEV dev, HFONT handle, HANDLE gdiFont ) DECLSPEC_HIDDEN;
extern HPEN CDECL EMFDRV_SelectPen( PHYSDEV dev, HPEN handle ) DECLSPEC_HIDDEN;
extern HPALETTE CDECL EMFDRV_SelectPalette( PHYSDEV dev, HPALETTE hPal, BOOL force ) DECLSPEC_HIDDEN;
extern INT CDECL EMFDRV_SetArcDirection( PHYSDEV dev, INT arcDirection ) DECLSPEC_HIDDEN;
extern COLORREF CDECL EMFDRV_SetBkColor( PHYSDEV dev, COLORREF color ) DECLSPEC_HIDDEN;
extern INT CDECL EMFDRV_SetBkMode( PHYSDEV dev, INT mode ) DECLSPEC_HIDDEN;
extern INT CDECL EMFDRV_SetDIBitsToDevice( PHYSDEV dev, INT xDest, INT yDest,
DWORD cx, DWORD cy, INT xSrc,
INT ySrc, UINT startscan, UINT lines,
LPCVOID bits, const BITMAPINFO *info,
UINT coloruse ) DECLSPEC_HIDDEN;
extern INT CDECL EMFDRV_SetMapMode( PHYSDEV dev, INT mode ) DECLSPEC_HIDDEN;
extern DWORD CDECL EMFDRV_SetMapperFlags( PHYSDEV dev, DWORD flags ) DECLSPEC_HIDDEN;
extern COLORREF CDECL EMFDRV_SetPixel( PHYSDEV dev, INT x, INT y, COLORREF color ) DECLSPEC_HIDDEN;
extern INT CDECL EMFDRV_SetPolyFillMode( PHYSDEV dev, INT mode ) DECLSPEC_HIDDEN;
extern INT CDECL EMFDRV_SetROP2( PHYSDEV dev, INT rop ) DECLSPEC_HIDDEN;
extern INT CDECL EMFDRV_SetStretchBltMode( PHYSDEV dev, INT mode ) DECLSPEC_HIDDEN;
extern UINT CDECL EMFDRV_SetTextAlign( PHYSDEV dev, UINT align ) DECLSPEC_HIDDEN;
extern COLORREF CDECL EMFDRV_SetTextColor( PHYSDEV dev, COLORREF color ) DECLSPEC_HIDDEN;
extern BOOL CDECL EMFDRV_SetTextJustification( PHYSDEV dev, INT nBreakExtra,
INT nBreakCount ) DECLSPEC_HIDDEN;
extern INT CDECL EMFDRV_SetViewportExt( PHYSDEV dev, INT x, INT y ) DECLSPEC_HIDDEN;
extern INT CDECL EMFDRV_SetViewportOrg( PHYSDEV dev, INT x, INT y ) DECLSPEC_HIDDEN;
extern INT CDECL EMFDRV_SetWindowExt( PHYSDEV dev, INT x, INT y ) DECLSPEC_HIDDEN;
extern INT CDECL EMFDRV_SetWindowOrg( PHYSDEV dev, INT x, INT y ) DECLSPEC_HIDDEN;
extern BOOL CDECL EMFDRV_SetWorldTransform( PHYSDEV dev, const XFORM *xform ) DECLSPEC_HIDDEN;
extern BOOL CDECL EMFDRV_StretchBlt( PHYSDEV devDst, INT xDst, INT yDst,
INT widthDst, INT heightDst,
PHYSDEV devSrc, INT xSrc, INT ySrc,
INT widthSrc, INT heightSrc, DWORD rop ) DECLSPEC_HIDDEN;
extern INT CDECL EMFDRV_StretchDIBits( PHYSDEV dev, INT xDst, INT yDst, INT widthDst,
INT heightDst, INT xSrc, INT ySrc,
INT widthSrc, INT heightSrc,
const void *bits, const BITMAPINFO *info,
UINT wUsage, DWORD dwRop ) DECLSPEC_HIDDEN;
extern BOOL CDECL EMFDRV_StrokeAndFillPath( PHYSDEV dev ) DECLSPEC_HIDDEN;
extern BOOL CDECL EMFDRV_StrokePath( PHYSDEV dev ) DECLSPEC_HIDDEN;
extern BOOL CDECL EMFDRV_WidenPath( PHYSDEV dev ) DECLSPEC_HIDDEN;
#endif /* __WINE_METAFILEDRV_H */

View File

@@ -0,0 +1,852 @@
/*
* Enhanced MetaFile driver graphics functions
*
* Copyright 1999 Huw D M Davies
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "config.h"
#include "wine/port.h"
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "enhmfdrv/enhmetafiledrv.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(enhmetafile);
/**********************************************************************
* EMFDRV_MoveTo
*/
BOOL CDECL
EMFDRV_MoveTo(PHYSDEV dev, INT x, INT y)
{
EMRMOVETOEX emr;
emr.emr.iType = EMR_MOVETOEX;
emr.emr.nSize = sizeof(emr);
emr.ptl.x = x;
emr.ptl.y = y;
return EMFDRV_WriteRecord( dev, &emr.emr );
}
/***********************************************************************
* EMFDRV_LineTo
*/
BOOL CDECL
EMFDRV_LineTo( PHYSDEV dev, INT x, INT y )
{
POINT pt;
EMRLINETO emr;
RECTL bounds;
EMFDRV_PDEVICE *physDev = (EMFDRV_PDEVICE *)dev;
emr.emr.iType = EMR_LINETO;
emr.emr.nSize = sizeof(emr);
emr.ptl.x = x;
emr.ptl.y = y;
if(!EMFDRV_WriteRecord( dev, &emr.emr ))
return FALSE;
GetCurrentPositionEx(physDev->hdc, &pt);
bounds.left = min(x, pt.x);
bounds.top = min(y, pt.y);
bounds.right = max(x, pt.x);
bounds.bottom = max(y, pt.y);
EMFDRV_UpdateBBox( dev, &bounds );
return TRUE;
}
/***********************************************************************
* EMFDRV_ArcChordPie
*/
static BOOL
EMFDRV_ArcChordPie( PHYSDEV dev, INT left, INT top, INT right, INT bottom,
INT xstart, INT ystart, INT xend, INT yend, DWORD iType )
{
INT temp, xCentre, yCentre, i;
double angleStart, angleEnd;
double xinterStart, yinterStart, xinterEnd, yinterEnd;
EMRARC emr;
RECTL bounds;
EMFDRV_PDEVICE *physDev = (EMFDRV_PDEVICE *)dev;
if(left == right || top == bottom) return FALSE;
if(left > right) {temp = left; left = right; right = temp;}
if(top > bottom) {temp = top; top = bottom; bottom = temp;}
if(GetGraphicsMode(physDev->hdc) == GM_COMPATIBLE) {
right--;
bottom--;
}
emr.emr.iType = iType;
emr.emr.nSize = sizeof(emr);
emr.rclBox.left = left;
emr.rclBox.top = top;
emr.rclBox.right = right;
emr.rclBox.bottom = bottom;
emr.ptlStart.x = xstart;
emr.ptlStart.y = ystart;
emr.ptlEnd.x = xend;
emr.ptlEnd.y = yend;
/* Now calculate the BBox */
xCentre = (left + right + 1) / 2;
yCentre = (top + bottom + 1) / 2;
xstart -= xCentre;
ystart -= yCentre;
xend -= xCentre;
yend -= yCentre;
/* invert y co-ords to get angle anti-clockwise from x-axis */
angleStart = atan2( -(double)ystart, (double)xstart);
angleEnd = atan2( -(double)yend, (double)xend);
/* These are the intercepts of the start/end lines with the arc */
xinterStart = (right - left + 1)/2 * cos(angleStart) + xCentre;
yinterStart = -(bottom - top + 1)/2 * sin(angleStart) + yCentre;
xinterEnd = (right - left + 1)/2 * cos(angleEnd) + xCentre;
yinterEnd = -(bottom - top + 1)/2 * sin(angleEnd) + yCentre;
if(angleStart < 0) angleStart += 2 * M_PI;
if(angleEnd < 0) angleEnd += 2 * M_PI;
if(angleEnd < angleStart) angleEnd += 2 * M_PI;
bounds.left = min(xinterStart, xinterEnd);
bounds.top = min(yinterStart, yinterEnd);
bounds.right = max(xinterStart, xinterEnd);
bounds.bottom = max(yinterStart, yinterEnd);
for(i = 0; i <= 8; i++) {
if(i * M_PI / 2 < angleStart) /* loop until we're past start */
continue;
if(i * M_PI / 2 > angleEnd) /* if we're past end we're finished */
break;
/* the arc touches the rectangle at the start of quadrant i, so adjust
BBox to reflect this. */
switch(i % 4) {
case 0:
bounds.right = right;
break;
case 1:
bounds.top = top;
break;
case 2:
bounds.left = left;
break;
case 3:
bounds.bottom = bottom;
break;
}
}
/* If we're drawing a pie then make sure we include the centre */
if(iType == EMR_PIE) {
if(bounds.left > xCentre) bounds.left = xCentre;
else if(bounds.right < xCentre) bounds.right = xCentre;
if(bounds.top > yCentre) bounds.top = yCentre;
else if(bounds.bottom < yCentre) bounds.right = yCentre;
}
if(!EMFDRV_WriteRecord( dev, &emr.emr ))
return FALSE;
EMFDRV_UpdateBBox( dev, &bounds );
return TRUE;
}
/***********************************************************************
* EMFDRV_Arc
*/
BOOL CDECL
EMFDRV_Arc( PHYSDEV dev, INT left, INT top, INT right, INT bottom,
INT xstart, INT ystart, INT xend, INT yend )
{
return EMFDRV_ArcChordPie( dev, left, top, right, bottom, xstart, ystart,
xend, yend, EMR_ARC );
}
/***********************************************************************
* EMFDRV_Pie
*/
BOOL CDECL
EMFDRV_Pie( PHYSDEV dev, INT left, INT top, INT right, INT bottom,
INT xstart, INT ystart, INT xend, INT yend )
{
return EMFDRV_ArcChordPie( dev, left, top, right, bottom, xstart, ystart,
xend, yend, EMR_PIE );
}
/***********************************************************************
* EMFDRV_Chord
*/
BOOL CDECL
EMFDRV_Chord( PHYSDEV dev, INT left, INT top, INT right, INT bottom,
INT xstart, INT ystart, INT xend, INT yend )
{
return EMFDRV_ArcChordPie( dev, left, top, right, bottom, xstart, ystart,
xend, yend, EMR_CHORD );
}
/***********************************************************************
* EMFDRV_Ellipse
*/
BOOL CDECL
EMFDRV_Ellipse( PHYSDEV dev, INT left, INT top, INT right, INT bottom )
{
EMRELLIPSE emr;
INT temp;
EMFDRV_PDEVICE *physDev = (EMFDRV_PDEVICE *)dev;
TRACE("%d,%d - %d,%d\n", left, top, right, bottom);
if(left == right || top == bottom) return FALSE;
if(left > right) {temp = left; left = right; right = temp;}
if(top > bottom) {temp = top; top = bottom; bottom = temp;}
if(GetGraphicsMode(physDev->hdc) == GM_COMPATIBLE) {
right--;
bottom--;
}
emr.emr.iType = EMR_ELLIPSE;
emr.emr.nSize = sizeof(emr);
emr.rclBox.left = left;
emr.rclBox.top = top;
emr.rclBox.right = right;
emr.rclBox.bottom = bottom;
EMFDRV_UpdateBBox( dev, &emr.rclBox );
return EMFDRV_WriteRecord( dev, &emr.emr );
}
/***********************************************************************
* EMFDRV_Rectangle
*/
BOOL CDECL
EMFDRV_Rectangle(PHYSDEV dev, INT left, INT top, INT right, INT bottom)
{
EMRRECTANGLE emr;
INT temp;
EMFDRV_PDEVICE *physDev = (EMFDRV_PDEVICE *)dev;
TRACE("%d,%d - %d,%d\n", left, top, right, bottom);
if(left == right || top == bottom) return FALSE;
if(left > right) {temp = left; left = right; right = temp;}
if(top > bottom) {temp = top; top = bottom; bottom = temp;}
if(GetGraphicsMode(physDev->hdc) == GM_COMPATIBLE) {
right--;
bottom--;
}
emr.emr.iType = EMR_RECTANGLE;
emr.emr.nSize = sizeof(emr);
emr.rclBox.left = left;
emr.rclBox.top = top;
emr.rclBox.right = right;
emr.rclBox.bottom = bottom;
EMFDRV_UpdateBBox( dev, &emr.rclBox );
return EMFDRV_WriteRecord( dev, &emr.emr );
}
/***********************************************************************
* EMFDRV_RoundRect
*/
BOOL CDECL
EMFDRV_RoundRect( PHYSDEV dev, INT left, INT top, INT right,
INT bottom, INT ell_width, INT ell_height )
{
EMRROUNDRECT emr;
INT temp;
EMFDRV_PDEVICE *physDev = (EMFDRV_PDEVICE *)dev;
if(left == right || top == bottom) return FALSE;
if(left > right) {temp = left; left = right; right = temp;}
if(top > bottom) {temp = top; top = bottom; bottom = temp;}
if(GetGraphicsMode(physDev->hdc) == GM_COMPATIBLE) {
right--;
bottom--;
}
emr.emr.iType = EMR_ROUNDRECT;
emr.emr.nSize = sizeof(emr);
emr.rclBox.left = left;
emr.rclBox.top = top;
emr.rclBox.right = right;
emr.rclBox.bottom = bottom;
emr.szlCorner.cx = ell_width;
emr.szlCorner.cy = ell_height;
EMFDRV_UpdateBBox( dev, &emr.rclBox );
return EMFDRV_WriteRecord( dev, &emr.emr );
}
/***********************************************************************
* EMFDRV_SetPixel
*/
COLORREF CDECL
EMFDRV_SetPixel( PHYSDEV dev, INT x, INT y, COLORREF color )
{
EMRSETPIXELV emr;
emr.emr.iType = EMR_SETPIXELV;
emr.emr.nSize = sizeof(emr);
emr.ptlPixel.x = x;
emr.ptlPixel.y = y;
emr.crColor = color;
if (EMFDRV_WriteRecord( dev, &emr.emr )) {
RECTL bounds;
bounds.left = bounds.right = x;
bounds.top = bounds.bottom = y;
EMFDRV_UpdateBBox( dev, &bounds );
return color;
}
return -1;
}
/**********************************************************************
* EMFDRV_Polylinegon
*
* Helper for EMFDRV_Poly{line|gon}
*/
static BOOL
EMFDRV_Polylinegon( PHYSDEV dev, const POINT* pt, INT count, DWORD iType )
{
EMRPOLYLINE *emr;
DWORD size;
INT i;
BOOL ret;
size = sizeof(EMRPOLYLINE) + sizeof(POINTL) * (count - 1);
emr = HeapAlloc( GetProcessHeap(), 0, size );
emr->emr.iType = iType;
emr->emr.nSize = size;
emr->rclBounds.left = emr->rclBounds.right = pt[0].x;
emr->rclBounds.top = emr->rclBounds.bottom = pt[0].y;
for(i = 1; i < count; i++) {
if(pt[i].x < emr->rclBounds.left)
emr->rclBounds.left = pt[i].x;
else if(pt[i].x > emr->rclBounds.right)
emr->rclBounds.right = pt[i].x;
if(pt[i].y < emr->rclBounds.top)
emr->rclBounds.top = pt[i].y;
else if(pt[i].y > emr->rclBounds.bottom)
emr->rclBounds.bottom = pt[i].y;
}
emr->cptl = count;
memcpy(emr->aptl, pt, count * sizeof(POINTL));
ret = EMFDRV_WriteRecord( dev, &emr->emr );
if(ret)
EMFDRV_UpdateBBox( dev, &emr->rclBounds );
HeapFree( GetProcessHeap(), 0, emr );
return ret;
}
/**********************************************************************
* EMFDRV_Polylinegon16
*
* Helper for EMFDRV_Poly{line|gon}
*
* This is not a legacy function!
* We are using SHORT integers to save space.
*/
static BOOL
EMFDRV_Polylinegon16( PHYSDEV dev, const POINT* pt, INT count, DWORD iType )
{
EMRPOLYLINE16 *emr;
DWORD size;
INT i;
BOOL ret;
/* check whether all points fit in the SHORT int POINT structure */
for(i = 0; i < count; i++) {
if( ((pt[i].x+0x8000) & ~0xffff ) ||
((pt[i].y+0x8000) & ~0xffff ) )
return FALSE;
}
size = sizeof(EMRPOLYLINE16) + sizeof(POINTS) * (count - 1);
emr = HeapAlloc( GetProcessHeap(), 0, size );
emr->emr.iType = iType;
emr->emr.nSize = size;
emr->rclBounds.left = emr->rclBounds.right = pt[0].x;
emr->rclBounds.top = emr->rclBounds.bottom = pt[0].y;
for(i = 1; i < count; i++) {
if(pt[i].x < emr->rclBounds.left)
emr->rclBounds.left = pt[i].x;
else if(pt[i].x > emr->rclBounds.right)
emr->rclBounds.right = pt[i].x;
if(pt[i].y < emr->rclBounds.top)
emr->rclBounds.top = pt[i].y;
else if(pt[i].y > emr->rclBounds.bottom)
emr->rclBounds.bottom = pt[i].y;
}
emr->cpts = count;
for(i = 0; i < count; i++ ) {
emr->apts[i].x = pt[i].x;
emr->apts[i].y = pt[i].y;
}
ret = EMFDRV_WriteRecord( dev, &emr->emr );
if(ret)
EMFDRV_UpdateBBox( dev, &emr->rclBounds );
HeapFree( GetProcessHeap(), 0, emr );
return ret;
}
/**********************************************************************
* EMFDRV_Polyline
*/
BOOL CDECL
EMFDRV_Polyline( PHYSDEV dev, const POINT* pt, INT count )
{
if( EMFDRV_Polylinegon16( dev, pt, count, EMR_POLYLINE16 ) )
return TRUE;
return EMFDRV_Polylinegon( dev, pt, count, EMR_POLYLINE );
}
/**********************************************************************
* EMFDRV_Polygon
*/
BOOL CDECL
EMFDRV_Polygon( PHYSDEV dev, const POINT* pt, INT count )
{
if(count < 2) return FALSE;
if( EMFDRV_Polylinegon16( dev, pt, count, EMR_POLYGON16 ) )
return TRUE;
return EMFDRV_Polylinegon( dev, pt, count, EMR_POLYGON );
}
/**********************************************************************
* EMFDRV_PolyPolylinegon
*
* Helper for EMFDRV_PolyPoly{line|gon}
*/
static BOOL
EMFDRV_PolyPolylinegon( PHYSDEV dev, const POINT* pt, const INT* counts, UINT polys,
DWORD iType)
{
EMRPOLYPOLYLINE *emr;
DWORD cptl = 0, poly, size;
INT point;
RECTL bounds;
const POINT *pts;
BOOL ret;
bounds.left = bounds.right = pt[0].x;
bounds.top = bounds.bottom = pt[0].y;
pts = pt;
for(poly = 0; poly < polys; poly++) {
cptl += counts[poly];
for(point = 0; point < counts[poly]; point++) {
if(bounds.left > pts->x) bounds.left = pts->x;
else if(bounds.right < pts->x) bounds.right = pts->x;
if(bounds.top > pts->y) bounds.top = pts->y;
else if(bounds.bottom < pts->y) bounds.bottom = pts->y;
pts++;
}
}
size = sizeof(EMRPOLYPOLYLINE) + (polys - 1) * sizeof(DWORD) +
(cptl - 1) * sizeof(POINTL);
emr = HeapAlloc( GetProcessHeap(), 0, size );
emr->emr.iType = iType;
emr->emr.nSize = size;
emr->rclBounds = bounds;
emr->nPolys = polys;
emr->cptl = cptl;
memcpy(emr->aPolyCounts, counts, polys * sizeof(DWORD));
memcpy(emr->aPolyCounts + polys, pt, cptl * sizeof(POINTL));
ret = EMFDRV_WriteRecord( dev, &emr->emr );
if(ret)
EMFDRV_UpdateBBox( dev, &emr->rclBounds );
HeapFree( GetProcessHeap(), 0, emr );
return ret;
}
/**********************************************************************
* EMFDRV_PolyPolyline
*/
BOOL CDECL
EMFDRV_PolyPolyline(PHYSDEV dev, const POINT* pt, const DWORD* counts, DWORD polys)
{
return EMFDRV_PolyPolylinegon( dev, pt, (const INT *)counts, polys,
EMR_POLYPOLYLINE );
}
/**********************************************************************
* EMFDRV_PolyPolygon
*/
BOOL CDECL
EMFDRV_PolyPolygon( PHYSDEV dev, const POINT* pt, const INT* counts, UINT polys )
{
return EMFDRV_PolyPolylinegon( dev, pt, counts, polys, EMR_POLYPOLYGON );
}
/**********************************************************************
* EMFDRV_ExtFloodFill
*/
BOOL CDECL
EMFDRV_ExtFloodFill( PHYSDEV dev, INT x, INT y, COLORREF color, UINT fillType )
{
EMREXTFLOODFILL emr;
emr.emr.iType = EMR_EXTFLOODFILL;
emr.emr.nSize = sizeof(emr);
emr.ptlStart.x = x;
emr.ptlStart.y = y;
emr.crColor = color;
emr.iMode = fillType;
return EMFDRV_WriteRecord( dev, &emr.emr );
}
/*********************************************************************
* EMFDRV_FillRgn
*/
BOOL CDECL EMFDRV_FillRgn( PHYSDEV dev, HRGN hrgn, HBRUSH hbrush )
{
EMRFILLRGN *emr;
DWORD size, rgnsize, index;
BOOL ret;
index = EMFDRV_CreateBrushIndirect( dev, hbrush );
if(!index) return FALSE;
rgnsize = GetRegionData( hrgn, 0, NULL );
size = rgnsize + offsetof(EMRFILLRGN,RgnData);
emr = HeapAlloc( GetProcessHeap(), 0, size );
GetRegionData( hrgn, rgnsize, (RGNDATA *)&emr->RgnData );
emr->emr.iType = EMR_FILLRGN;
emr->emr.nSize = size;
emr->rclBounds.left = ((RGNDATA *)&emr->RgnData)->rdh.rcBound.left;
emr->rclBounds.top = ((RGNDATA *)&emr->RgnData)->rdh.rcBound.top;
emr->rclBounds.right = ((RGNDATA *)&emr->RgnData)->rdh.rcBound.right - 1;
emr->rclBounds.bottom = ((RGNDATA *)&emr->RgnData)->rdh.rcBound.bottom - 1;
emr->cbRgnData = rgnsize;
emr->ihBrush = index;
ret = EMFDRV_WriteRecord( dev, &emr->emr );
if(ret)
EMFDRV_UpdateBBox( dev, &emr->rclBounds );
HeapFree( GetProcessHeap(), 0, emr );
return ret;
}
/*********************************************************************
* EMFDRV_FrameRgn
*/
BOOL CDECL EMFDRV_FrameRgn( PHYSDEV dev, HRGN hrgn, HBRUSH hbrush, INT width, INT height )
{
EMRFRAMERGN *emr;
DWORD size, rgnsize, index;
BOOL ret;
index = EMFDRV_CreateBrushIndirect( dev, hbrush );
if(!index) return FALSE;
rgnsize = GetRegionData( hrgn, 0, NULL );
size = rgnsize + offsetof(EMRFRAMERGN,RgnData);
emr = HeapAlloc( GetProcessHeap(), 0, size );
GetRegionData( hrgn, rgnsize, (RGNDATA *)&emr->RgnData );
emr->emr.iType = EMR_FRAMERGN;
emr->emr.nSize = size;
emr->rclBounds.left = ((RGNDATA *)&emr->RgnData)->rdh.rcBound.left;
emr->rclBounds.top = ((RGNDATA *)&emr->RgnData)->rdh.rcBound.top;
emr->rclBounds.right = ((RGNDATA *)&emr->RgnData)->rdh.rcBound.right - 1;
emr->rclBounds.bottom = ((RGNDATA *)&emr->RgnData)->rdh.rcBound.bottom - 1;
emr->cbRgnData = rgnsize;
emr->ihBrush = index;
emr->szlStroke.cx = width;
emr->szlStroke.cy = height;
ret = EMFDRV_WriteRecord( dev, &emr->emr );
if(ret)
EMFDRV_UpdateBBox( dev, &emr->rclBounds );
HeapFree( GetProcessHeap(), 0, emr );
return ret;
}
/*********************************************************************
* EMFDRV_PaintInvertRgn
*
* Helper for EMFDRV_{Paint|Invert}Rgn
*/
static BOOL EMFDRV_PaintInvertRgn( PHYSDEV dev, HRGN hrgn, DWORD iType )
{
EMRINVERTRGN *emr;
DWORD size, rgnsize;
BOOL ret;
rgnsize = GetRegionData( hrgn, 0, NULL );
size = rgnsize + offsetof(EMRINVERTRGN,RgnData);
emr = HeapAlloc( GetProcessHeap(), 0, size );
GetRegionData( hrgn, rgnsize, (RGNDATA *)&emr->RgnData );
emr->emr.iType = iType;
emr->emr.nSize = size;
emr->rclBounds.left = ((RGNDATA *)&emr->RgnData)->rdh.rcBound.left;
emr->rclBounds.top = ((RGNDATA *)&emr->RgnData)->rdh.rcBound.top;
emr->rclBounds.right = ((RGNDATA *)&emr->RgnData)->rdh.rcBound.right - 1;
emr->rclBounds.bottom = ((RGNDATA *)&emr->RgnData)->rdh.rcBound.bottom - 1;
emr->cbRgnData = rgnsize;
ret = EMFDRV_WriteRecord( dev, &emr->emr );
if(ret)
EMFDRV_UpdateBBox( dev, &emr->rclBounds );
HeapFree( GetProcessHeap(), 0, emr );
return ret;
}
/**********************************************************************
* EMFDRV_PaintRgn
*/
BOOL CDECL
EMFDRV_PaintRgn( PHYSDEV dev, HRGN hrgn )
{
return EMFDRV_PaintInvertRgn( dev, hrgn, EMR_PAINTRGN );
}
/**********************************************************************
* EMFDRV_InvertRgn
*/
BOOL CDECL
EMFDRV_InvertRgn( PHYSDEV dev, HRGN hrgn )
{
return EMFDRV_PaintInvertRgn( dev, hrgn, EMR_INVERTRGN );
}
/**********************************************************************
* EMFDRV_SetBkColor
*/
COLORREF CDECL
EMFDRV_SetBkColor( PHYSDEV dev, COLORREF color )
{
EMRSETBKCOLOR emr;
EMFDRV_PDEVICE *physDev = (EMFDRV_PDEVICE *)dev;
if (physDev->restoring) return color; /* don't output records during RestoreDC */
emr.emr.iType = EMR_SETBKCOLOR;
emr.emr.nSize = sizeof(emr);
emr.crColor = color;
return EMFDRV_WriteRecord( dev, &emr.emr ) ? color : CLR_INVALID;
}
/**********************************************************************
* EMFDRV_SetTextColor
*/
COLORREF CDECL
EMFDRV_SetTextColor( PHYSDEV dev, COLORREF color )
{
EMRSETTEXTCOLOR emr;
EMFDRV_PDEVICE *physDev = (EMFDRV_PDEVICE *)dev;
if (physDev->restoring) return color; /* don't output records during RestoreDC */
emr.emr.iType = EMR_SETTEXTCOLOR;
emr.emr.nSize = sizeof(emr);
emr.crColor = color;
return EMFDRV_WriteRecord( dev, &emr.emr ) ? color : CLR_INVALID;
}
/**********************************************************************
* EMFDRV_ExtTextOut
*/
BOOL CDECL EMFDRV_ExtTextOut( PHYSDEV dev, INT x, INT y, UINT flags,
const RECT *lprect, LPCWSTR str, UINT count,
const INT *lpDx )
{
EMREXTTEXTOUTW *pemr;
DWORD nSize;
BOOL ret;
EMFDRV_PDEVICE *physDev = (EMFDRV_PDEVICE*) dev;
int textHeight = 0;
int textWidth = 0;
const UINT textAlign = GetTextAlign(physDev->hdc);
nSize = sizeof(*pemr) + ((count+1) & ~1) * sizeof(WCHAR) + count * sizeof(INT);
TRACE("%s %s count %d nSize = %d\n", debugstr_wn(str, count),
wine_dbgstr_rect(lprect), count, nSize);
pemr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, nSize);
pemr->emr.iType = EMR_EXTTEXTOUTW;
pemr->emr.nSize = nSize;
pemr->iGraphicsMode = GetGraphicsMode(physDev->hdc);
pemr->exScale = pemr->eyScale = 1.0; /* FIXME */
pemr->emrtext.ptlReference.x = x;
pemr->emrtext.ptlReference.y = y;
pemr->emrtext.nChars = count;
pemr->emrtext.offString = sizeof(*pemr);
memcpy((char*)pemr + pemr->emrtext.offString, str, count * sizeof(WCHAR));
pemr->emrtext.fOptions = flags;
if(!lprect) {
pemr->emrtext.rcl.left = pemr->emrtext.rcl.top = 0;
pemr->emrtext.rcl.right = pemr->emrtext.rcl.bottom = -1;
} else {
pemr->emrtext.rcl.left = lprect->left;
pemr->emrtext.rcl.top = lprect->top;
pemr->emrtext.rcl.right = lprect->right;
pemr->emrtext.rcl.bottom = lprect->bottom;
}
pemr->emrtext.offDx = pemr->emrtext.offString + ((count+1) & ~1) * sizeof(WCHAR);
if(lpDx) {
UINT i;
SIZE strSize;
memcpy((char*)pemr + pemr->emrtext.offDx, lpDx, count * sizeof(INT));
for (i = 0; i < count; i++) {
textWidth += lpDx[i];
}
if (GetTextExtentPoint32W(physDev->hdc, str, count, &strSize))
textHeight = strSize.cy;
}
else {
UINT i;
INT *dx = (INT *)((char*)pemr + pemr->emrtext.offDx);
SIZE charSize;
for (i = 0; i < count; i++) {
if (GetTextExtentPoint32W(physDev->hdc, str + i, 1, &charSize)) {
dx[i] = charSize.cx;
textWidth += charSize.cx;
textHeight = max(textHeight, charSize.cy);
}
}
}
if (!lprect)
{
pemr->rclBounds.left = pemr->rclBounds.top = 0;
pemr->rclBounds.right = pemr->rclBounds.bottom = -1;
goto no_bounds;
}
switch (textAlign & (TA_LEFT | TA_RIGHT | TA_CENTER)) {
case TA_CENTER: {
pemr->rclBounds.left = x - (textWidth / 2) - 1;
pemr->rclBounds.right = x + (textWidth / 2) + 1;
break;
}
case TA_RIGHT: {
pemr->rclBounds.left = x - textWidth - 1;
pemr->rclBounds.right = x;
break;
}
default: { /* TA_LEFT */
pemr->rclBounds.left = x;
pemr->rclBounds.right = x + textWidth + 1;
}
}
switch (textAlign & (TA_TOP | TA_BOTTOM | TA_BASELINE)) {
case TA_BASELINE: {
TEXTMETRICW tm;
if (!GetTextMetricsW(physDev->hdc, &tm))
tm.tmDescent = 0;
/* Play safe here... it's better to have a bounding box */
/* that is too big than too small. */
pemr->rclBounds.top = y - textHeight - 1;
pemr->rclBounds.bottom = y + tm.tmDescent + 1;
break;
}
case TA_BOTTOM: {
pemr->rclBounds.top = y - textHeight - 1;
pemr->rclBounds.bottom = y;
break;
}
default: { /* TA_TOP */
pemr->rclBounds.top = y;
pemr->rclBounds.bottom = y + textHeight + 1;
}
}
EMFDRV_UpdateBBox( dev, &pemr->rclBounds );
no_bounds:
ret = EMFDRV_WriteRecord( dev, &pemr->emr );
HeapFree( GetProcessHeap(), 0, pemr );
return ret;
}
/**********************************************************************
* EMFDRV_SetArcDirection
*/
INT CDECL EMFDRV_SetArcDirection(PHYSDEV dev, INT arcDirection)
{
EMRSETARCDIRECTION emr;
emr.emr.iType = EMR_SETARCDIRECTION;
emr.emr.nSize = sizeof(emr);
emr.iArcDirection = arcDirection;
EMFDRV_WriteRecord(dev, &emr.emr);
/* We don't know the old arc direction and we don't care... */
return 0;
}

View File

@@ -0,0 +1,507 @@
/*
* Enhanced MetaFile driver initialisation functions
*
* Copyright 1999 Huw D M Davies
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <assert.h>
#include <stdarg.h>
#include <string.h>
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winnls.h"
#include "gdi_private.h"
#include "enhmfdrv/enhmetafiledrv.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(enhmetafile);
static const DC_FUNCTIONS EMFDRV_Funcs =
{
NULL, /* pAbortDoc */
EMFDRV_AbortPath, /* pAbortPath */
NULL, /* pAlphaBlend */
NULL, /* pAngleArc */
EMFDRV_Arc, /* pArc */
NULL, /* pArcTo */
EMFDRV_BeginPath, /* pBeginPath */
EMFDRV_BitBlt, /* pBitBlt */
NULL, /* pChoosePixelFormat */
EMFDRV_Chord, /* pChord */
EMFDRV_CloseFigure, /* pCloseFigure */
NULL, /* pCreateBitmap */
NULL, /* pCreateDC */
NULL, /* pCreateDIBSection */
NULL, /* pDeleteBitmap */
NULL, /* pDeleteDC */
EMFDRV_DeleteObject, /* pDeleteObject */
NULL, /* pDescribePixelFormat */
NULL, /* pDeviceCapabilities */
EMFDRV_Ellipse, /* pEllipse */
NULL, /* pEndDoc */
NULL, /* pEndPage */
EMFDRV_EndPath, /* pEndPath */
NULL, /* pEnumDeviceFonts */
NULL, /* pEnumICMProfiles */
EMFDRV_ExcludeClipRect, /* pExcludeClipRect */
NULL, /* pExtDeviceMode */
NULL, /* pExtEscape */
EMFDRV_ExtFloodFill, /* pExtFloodFill */
EMFDRV_ExtSelectClipRgn, /* pExtSelectClipRgn */
EMFDRV_ExtTextOut, /* pExtTextOut */
EMFDRV_FillPath, /* pFillPath */
EMFDRV_FillRgn, /* pFillRgn */
EMFDRV_FlattenPath, /* pFlattenPath */
EMFDRV_FrameRgn, /* pFrameRgn */
EMFDRV_GdiComment, /* pGdiComment */
NULL, /* pGetBitmapBits */
NULL, /* pGetCharWidth */
NULL, /* pGetDIBColorTable */
NULL, /* pGetDIBits */
EMFDRV_GetDeviceCaps, /* pGetDeviceCaps */
NULL, /* pGetDeviceGammaRamp */
NULL, /* pGetICMProfile */
NULL, /* pGetNearestColor */
NULL, /* pGetPixel */
NULL, /* pGetPixelFormat */
NULL, /* pGetSystemPaletteEntries */
NULL, /* pGetTextExtentExPoint */
NULL, /* pGetTextMetrics */
EMFDRV_IntersectClipRect, /* pIntersectClipRect */
EMFDRV_InvertRgn, /* pInvertRgn */
EMFDRV_LineTo, /* pLineTo */
EMFDRV_ModifyWorldTransform, /* pModifyWorldTransform */
EMFDRV_MoveTo, /* pMoveTo */
EMFDRV_OffsetClipRgn, /* pOffsetClipRgn */
EMFDRV_OffsetViewportOrg, /* pOffsetViewportOrg */
EMFDRV_OffsetWindowOrg, /* pOffsetWindowOrg */
EMFDRV_PaintRgn, /* pPaintRgn */
EMFDRV_PatBlt, /* pPatBlt */
EMFDRV_Pie, /* pPie */
NULL, /* pPolyBezier */
NULL, /* pPolyBezierTo */
NULL, /* pPolyDraw */
EMFDRV_PolyPolygon, /* pPolyPolygon */
EMFDRV_PolyPolyline, /* pPolyPolyline */
EMFDRV_Polygon, /* pPolygon */
EMFDRV_Polyline, /* pPolyline */
NULL, /* pPolylineTo */
NULL, /* pRealizeDefaultPalette */
NULL, /* pRealizePalette */
EMFDRV_Rectangle, /* pRectangle */
NULL, /* pResetDC */
EMFDRV_RestoreDC, /* pRestoreDC */
EMFDRV_RoundRect, /* pRoundRect */
EMFDRV_SaveDC, /* pSaveDC */
EMFDRV_ScaleViewportExt, /* pScaleViewportExt */
EMFDRV_ScaleWindowExt, /* pScaleWindowExt */
EMFDRV_SelectBitmap, /* pSelectBitmap */
EMFDRV_SelectBrush, /* pSelectBrush */
EMFDRV_SelectClipPath, /* pSelectClipPath */
EMFDRV_SelectFont, /* pSelectFont */
EMFDRV_SelectPalette, /* pSelectPalette */
EMFDRV_SelectPen, /* pSelectPen */
EMFDRV_SetArcDirection, /* pSetArcDirection */
NULL, /* pSetBitmapBits */
EMFDRV_SetBkColor, /* pSetBkColor */
EMFDRV_SetBkMode, /* pSetBkMode */
NULL, /* pSetDCBrushColor */
NULL, /* pSetDCPenColor */
NULL, /* pSetDIBColorTable */
NULL, /* pSetDIBits */
EMFDRV_SetDIBitsToDevice, /* pSetDIBitsToDevice */
NULL, /* pSetDeviceClipping */
NULL, /* pSetDeviceGammaRamp */
EMFDRV_SetMapMode, /* pSetMapMode */
EMFDRV_SetMapperFlags, /* pSetMapperFlags */
EMFDRV_SetPixel, /* pSetPixel */
NULL, /* pSetPixelFormat */
EMFDRV_SetPolyFillMode, /* pSetPolyFillMode */
EMFDRV_SetROP2, /* pSetROP2 */
NULL, /* pSetRelAbs */
EMFDRV_SetStretchBltMode, /* pSetStretchBltMode */
EMFDRV_SetTextAlign, /* pSetTextAlign */
NULL, /* pSetTextCharacterExtra */
EMFDRV_SetTextColor, /* pSetTextColor */
EMFDRV_SetTextJustification, /* pSetTextJustification */
EMFDRV_SetViewportExt, /* pSetViewportExt */
EMFDRV_SetViewportOrg, /* pSetViewportOrg */
EMFDRV_SetWindowExt, /* pSetWindowExt */
EMFDRV_SetWindowOrg, /* pSetWindowOrg */
EMFDRV_SetWorldTransform, /* pSetWorldTransform */
NULL, /* pStartDoc */
NULL, /* pStartPage */
EMFDRV_StretchBlt, /* pStretchBlt */
EMFDRV_StretchDIBits, /* pStretchDIBits */
EMFDRV_StrokeAndFillPath, /* pStrokeAndFillPath */
EMFDRV_StrokePath, /* pStrokePath */
NULL, /* pSwapBuffers */
NULL, /* pUnrealizePalette */
EMFDRV_WidenPath /* pWidenPath */
};
/**********************************************************************
* EMFDRV_DeleteDC
*/
static BOOL EMFDRV_DeleteDC( DC *dc )
{
EMFDRV_PDEVICE *physDev = (EMFDRV_PDEVICE *)dc->physDev;
UINT index;
if (physDev->emh) HeapFree( GetProcessHeap(), 0, physDev->emh );
for(index = 0; index < physDev->handles_size; index++)
if(physDev->handles[index])
GDI_hdc_not_using_object(physDev->handles[index], physDev->hdc);
HeapFree( GetProcessHeap(), 0, physDev->handles );
HeapFree( GetProcessHeap(), 0, physDev );
dc->physDev = NULL;
free_dc_ptr( dc );
return TRUE;
}
/******************************************************************
* EMFDRV_WriteRecord
*
* Warning: this function can change the pointer to the metafile header.
*/
BOOL EMFDRV_WriteRecord( PHYSDEV dev, EMR *emr )
{
DWORD len;
ENHMETAHEADER *emh;
EMFDRV_PDEVICE *physDev = (EMFDRV_PDEVICE *)dev;
TRACE("record %d, size %d %s\n",
emr->iType, emr->nSize, physDev->hFile ? "(to disk)" : "");
assert( !(emr->nSize & 3) );
physDev->emh->nBytes += emr->nSize;
physDev->emh->nRecords++;
if(physDev->hFile) {
if (!WriteFile(physDev->hFile, emr, emr->nSize, NULL, NULL))
return FALSE;
} else {
DWORD nEmfSize = HeapSize(GetProcessHeap(), 0, physDev->emh);
len = physDev->emh->nBytes;
if (len > nEmfSize) {
nEmfSize += (nEmfSize / 2) + emr->nSize;
emh = HeapReAlloc(GetProcessHeap(), 0, physDev->emh, nEmfSize);
if (!emh) return FALSE;
physDev->emh = emh;
}
memcpy((CHAR *)physDev->emh + physDev->emh->nBytes - emr->nSize, emr,
emr->nSize);
}
return TRUE;
}
/******************************************************************
* EMFDRV_UpdateBBox
*/
void EMFDRV_UpdateBBox( PHYSDEV dev, RECTL *rect )
{
EMFDRV_PDEVICE *physDev = (EMFDRV_PDEVICE *)dev;
RECTL *bounds = &physDev->emh->rclBounds;
RECTL vportRect = *rect;
LPtoDP(physDev->hdc, (LPPOINT)&vportRect, 2);
/* The coordinate systems may be mirrored
(LPtoDP handles points, not rectangles) */
if (vportRect.left > vportRect.right)
{
LONG temp = vportRect.right;
vportRect.right = vportRect.left;
vportRect.left = temp;
}
if (vportRect.top > vportRect.bottom)
{
LONG temp = vportRect.bottom;
vportRect.bottom = vportRect.top;
vportRect.top = temp;
}
if (bounds->left > bounds->right)
{
/* first bounding rectangle */
*bounds = vportRect;
}
else
{
bounds->left = min(bounds->left, vportRect.left);
bounds->top = min(bounds->top, vportRect.top);
bounds->right = max(bounds->right, vportRect.right);
bounds->bottom = max(bounds->bottom, vportRect.bottom);
}
}
/**********************************************************************
* CreateEnhMetaFileA (GDI32.@)
*/
HDC WINAPI CreateEnhMetaFileA(
HDC hdc, /* [in] optional reference DC */
LPCSTR filename, /* [in] optional filename for disk metafiles */
const RECT *rect, /* [in] optional bounding rectangle */
LPCSTR description /* [in] optional description */
)
{
LPWSTR filenameW = NULL;
LPWSTR descriptionW = NULL;
HDC hReturnDC;
DWORD len1, len2, total;
if(filename)
{
total = MultiByteToWideChar( CP_ACP, 0, filename, -1, NULL, 0 );
filenameW = HeapAlloc( GetProcessHeap(), 0, total * sizeof(WCHAR) );
MultiByteToWideChar( CP_ACP, 0, filename, -1, filenameW, total );
}
if(description) {
len1 = strlen(description);
len2 = strlen(description + len1 + 1);
total = MultiByteToWideChar( CP_ACP, 0, description, len1 + len2 + 3, NULL, 0 );
descriptionW = HeapAlloc( GetProcessHeap(), 0, total * sizeof(WCHAR) );
MultiByteToWideChar( CP_ACP, 0, description, len1 + len2 + 3, descriptionW, total );
}
hReturnDC = CreateEnhMetaFileW(hdc, filenameW, rect, descriptionW);
HeapFree( GetProcessHeap(), 0, filenameW );
HeapFree( GetProcessHeap(), 0, descriptionW );
return hReturnDC;
}
/**********************************************************************
* CreateEnhMetaFileW (GDI32.@)
*/
HDC WINAPI CreateEnhMetaFileW(
HDC hdc, /* [in] optional reference DC */
LPCWSTR filename, /* [in] optional filename for disk metafiles */
const RECT* rect, /* [in] optional bounding rectangle */
LPCWSTR description /* [in] optional description */
)
{
static const WCHAR displayW[] = {'D','I','S','P','L','A','Y',0};
HDC ret;
DC *dc;
HDC hRefDC = hdc ? hdc : CreateDCW(displayW,NULL,NULL,NULL);
/* If no ref, use current display */
EMFDRV_PDEVICE *physDev;
HANDLE hFile;
DWORD size = 0, length = 0;
TRACE("%s\n", debugstr_w(filename) );
if (!(dc = alloc_dc_ptr( &EMFDRV_Funcs, OBJ_ENHMETADC ))) return 0;
physDev = HeapAlloc(GetProcessHeap(),0,sizeof(*physDev));
if (!physDev) {
free_dc_ptr( dc );
return 0;
}
dc->physDev = (PHYSDEV)physDev;
physDev->hdc = dc->hSelf;
if(description) { /* App name\0Title\0\0 */
length = lstrlenW(description);
length += lstrlenW(description + length + 1);
length += 3;
length *= 2;
}
size = sizeof(ENHMETAHEADER) + (length + 3) / 4 * 4;
if (!(physDev->emh = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, size))) {
HeapFree( GetProcessHeap(), 0, physDev );
free_dc_ptr( dc );
return 0;
}
physDev->handles = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, HANDLE_LIST_INC * sizeof(physDev->handles[0]));
physDev->handles_size = HANDLE_LIST_INC;
physDev->cur_handles = 1;
physDev->hFile = 0;
physDev->horzres = GetDeviceCaps(hRefDC, HORZRES);
physDev->vertres = GetDeviceCaps(hRefDC, VERTRES);
physDev->logpixelsx = GetDeviceCaps(hRefDC, LOGPIXELSX);
physDev->logpixelsy = GetDeviceCaps(hRefDC, LOGPIXELSY);
physDev->horzsize = GetDeviceCaps(hRefDC, HORZSIZE);
physDev->vertsize = GetDeviceCaps(hRefDC, VERTSIZE);
physDev->bitspixel = GetDeviceCaps(hRefDC, BITSPIXEL);
physDev->textcaps = GetDeviceCaps(hRefDC, TEXTCAPS);
physDev->rastercaps = GetDeviceCaps(hRefDC, RASTERCAPS);
physDev->technology = GetDeviceCaps(hRefDC, TECHNOLOGY);
physDev->planes = GetDeviceCaps(hRefDC, PLANES);
physDev->numcolors = GetDeviceCaps(hRefDC, NUMCOLORS);
physDev->restoring = 0;
SetVirtualResolution(dc->hSelf, 0, 0, 0, 0);
physDev->emh->iType = EMR_HEADER;
physDev->emh->nSize = size;
physDev->emh->rclBounds.left = physDev->emh->rclBounds.top = 0;
physDev->emh->rclBounds.right = physDev->emh->rclBounds.bottom = -1;
if(rect) {
physDev->emh->rclFrame.left = rect->left;
physDev->emh->rclFrame.top = rect->top;
physDev->emh->rclFrame.right = rect->right;
physDev->emh->rclFrame.bottom = rect->bottom;
} else { /* Set this to {0,0 - -1,-1} and update it at the end */
physDev->emh->rclFrame.left = physDev->emh->rclFrame.top = 0;
physDev->emh->rclFrame.right = physDev->emh->rclFrame.bottom = -1;
}
physDev->emh->dSignature = ENHMETA_SIGNATURE;
physDev->emh->nVersion = 0x10000;
physDev->emh->nBytes = physDev->emh->nSize;
physDev->emh->nRecords = 1;
physDev->emh->nHandles = 1;
physDev->emh->sReserved = 0; /* According to docs, this is reserved and must be 0 */
physDev->emh->nDescription = length / 2;
physDev->emh->offDescription = length ? sizeof(ENHMETAHEADER) : 0;
physDev->emh->nPalEntries = 0; /* I guess this should start at 0 */
/* Size in pixels */
physDev->emh->szlDevice.cx = physDev->horzres;
physDev->emh->szlDevice.cy = physDev->vertres;
/* Size in millimeters */
physDev->emh->szlMillimeters.cx = physDev->horzsize;
physDev->emh->szlMillimeters.cy = physDev->vertsize;
/* Size in micrometers */
physDev->emh->szlMicrometers.cx = physDev->horzsize * 1000;
physDev->emh->szlMicrometers.cy = physDev->vertsize * 1000;
memcpy((char *)physDev->emh + sizeof(ENHMETAHEADER), description, length);
if (filename) /* disk based metafile */
{
if ((hFile = CreateFileW(filename, GENERIC_WRITE | GENERIC_READ, 0,
NULL, CREATE_ALWAYS, 0, 0)) == INVALID_HANDLE_VALUE) {
EMFDRV_DeleteDC( dc );
return 0;
}
if (!WriteFile( hFile, physDev->emh, size, NULL, NULL )) {
EMFDRV_DeleteDC( dc );
return 0;
}
physDev->hFile = hFile;
}
TRACE("returning %p\n", dc->hSelf);
ret = dc->hSelf;
release_dc_ptr( dc );
if( !hdc )
DeleteDC( hRefDC );
return ret;
}
/******************************************************************
* CloseEnhMetaFile (GDI32.@)
*/
HENHMETAFILE WINAPI CloseEnhMetaFile(HDC hdc) /* [in] metafile DC */
{
HENHMETAFILE hmf;
EMFDRV_PDEVICE *physDev;
DC *dc;
EMREOF emr;
HANDLE hMapping = 0;
TRACE("(%p)\n", hdc );
if (!(dc = get_dc_ptr( hdc ))) return NULL;
if (dc->header.type != OBJ_ENHMETADC)
{
release_dc_ptr( dc );
return NULL;
}
if (dc->refcount != 1)
{
FIXME( "not deleting busy DC %p refcount %u\n", dc->hSelf, dc->refcount );
release_dc_ptr( dc );
return NULL;
}
physDev = (EMFDRV_PDEVICE *)dc->physDev;
if(dc->saveLevel)
RestoreDC(hdc, 1);
emr.emr.iType = EMR_EOF;
emr.emr.nSize = sizeof(emr);
emr.nPalEntries = 0;
emr.offPalEntries = FIELD_OFFSET(EMREOF, nSizeLast);
emr.nSizeLast = emr.emr.nSize;
EMFDRV_WriteRecord( dc->physDev, &emr.emr );
/* Update rclFrame if not initialized in CreateEnhMetaFile */
if(physDev->emh->rclFrame.left > physDev->emh->rclFrame.right) {
physDev->emh->rclFrame.left = physDev->emh->rclBounds.left *
physDev->emh->szlMillimeters.cx * 100 / physDev->emh->szlDevice.cx;
physDev->emh->rclFrame.top = physDev->emh->rclBounds.top *
physDev->emh->szlMillimeters.cy * 100 / physDev->emh->szlDevice.cy;
physDev->emh->rclFrame.right = physDev->emh->rclBounds.right *
physDev->emh->szlMillimeters.cx * 100 / physDev->emh->szlDevice.cx;
physDev->emh->rclFrame.bottom = physDev->emh->rclBounds.bottom *
physDev->emh->szlMillimeters.cy * 100 / physDev->emh->szlDevice.cy;
}
if (physDev->hFile) /* disk based metafile */
{
if (SetFilePointer(physDev->hFile, 0, NULL, FILE_BEGIN) != 0)
{
CloseHandle( physDev->hFile );
EMFDRV_DeleteDC( dc );
return 0;
}
if (!WriteFile(physDev->hFile, physDev->emh, sizeof(*physDev->emh),
NULL, NULL))
{
CloseHandle( physDev->hFile );
EMFDRV_DeleteDC( dc );
return 0;
}
HeapFree( GetProcessHeap(), 0, physDev->emh );
hMapping = CreateFileMappingA(physDev->hFile, NULL, PAGE_READONLY, 0,
0, NULL);
TRACE("hMapping = %p\n", hMapping );
physDev->emh = MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0);
TRACE("view = %p\n", physDev->emh );
CloseHandle( hMapping );
CloseHandle( physDev->hFile );
}
hmf = EMF_Create_HENHMETAFILE( physDev->emh, (physDev->hFile != 0) );
physDev->emh = NULL; /* So it won't be deleted */
EMFDRV_DeleteDC( dc );
return hmf;
}

View File

@@ -0,0 +1,164 @@
/*
* Enhanced MetaFile driver mapping functions
*
* Copyright 1999 Huw D M Davies
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "enhmfdrv/enhmetafiledrv.h"
INT CDECL EMFDRV_SetMapMode( PHYSDEV dev, INT mode )
{
EMRSETMAPMODE emr;
emr.emr.iType = EMR_SETMAPMODE;
emr.emr.nSize = sizeof(emr);
emr.iMode = mode;
return EMFDRV_WriteRecord( dev, &emr.emr );
}
INT CDECL EMFDRV_SetViewportExt( PHYSDEV dev, INT cx, INT cy )
{
EMRSETVIEWPORTEXTEX emr;
emr.emr.iType = EMR_SETVIEWPORTEXTEX;
emr.emr.nSize = sizeof(emr);
emr.szlExtent.cx = cx;
emr.szlExtent.cy = cy;
return EMFDRV_WriteRecord( dev, &emr.emr );
}
INT CDECL EMFDRV_SetWindowExt( PHYSDEV dev, INT cx, INT cy )
{
EMRSETWINDOWEXTEX emr;
emr.emr.iType = EMR_SETWINDOWEXTEX;
emr.emr.nSize = sizeof(emr);
emr.szlExtent.cx = cx;
emr.szlExtent.cy = cy;
return EMFDRV_WriteRecord( dev, &emr.emr );
}
INT CDECL EMFDRV_SetViewportOrg( PHYSDEV dev, INT x, INT y )
{
EMRSETVIEWPORTORGEX emr;
emr.emr.iType = EMR_SETVIEWPORTORGEX;
emr.emr.nSize = sizeof(emr);
emr.ptlOrigin.x = x;
emr.ptlOrigin.y = y;
return EMFDRV_WriteRecord( dev, &emr.emr );
}
INT CDECL EMFDRV_SetWindowOrg( PHYSDEV dev, INT x, INT y )
{
EMRSETWINDOWORGEX emr;
emr.emr.iType = EMR_SETWINDOWORGEX;
emr.emr.nSize = sizeof(emr);
emr.ptlOrigin.x = x;
emr.ptlOrigin.y = y;
return EMFDRV_WriteRecord( dev, &emr.emr );
}
INT CDECL EMFDRV_ScaleViewportExt( PHYSDEV dev, INT xNum, INT xDenom, INT yNum,
INT yDenom )
{
EMRSCALEVIEWPORTEXTEX emr;
emr.emr.iType = EMR_SCALEVIEWPORTEXTEX;
emr.emr.nSize = sizeof(emr);
emr.xNum = xNum;
emr.xDenom = xDenom;
emr.yNum = yNum;
emr.yDenom = yDenom;
return EMFDRV_WriteRecord( dev, &emr.emr );
}
INT CDECL EMFDRV_ScaleWindowExt( PHYSDEV dev, INT xNum, INT xDenom, INT yNum,
INT yDenom )
{
EMRSCALEWINDOWEXTEX emr;
emr.emr.iType = EMR_SCALEWINDOWEXTEX;
emr.emr.nSize = sizeof(emr);
emr.xNum = xNum;
emr.xDenom = xDenom;
emr.yNum = yNum;
emr.yDenom = yDenom;
return EMFDRV_WriteRecord( dev, &emr.emr );
}
BOOL CDECL EMFDRV_SetWorldTransform( PHYSDEV dev, const XFORM *xform)
{
EMRSETWORLDTRANSFORM emr;
emr.emr.iType = EMR_SETWORLDTRANSFORM;
emr.emr.nSize = sizeof(emr);
emr.xform = *xform;
return EMFDRV_WriteRecord( dev, &emr.emr );
}
BOOL CDECL EMFDRV_ModifyWorldTransform( PHYSDEV dev, const XFORM *xform, INT mode)
{
EMRMODIFYWORLDTRANSFORM emr;
emr.emr.iType = EMR_MODIFYWORLDTRANSFORM;
emr.emr.nSize = sizeof(emr);
emr.xform = *xform;
emr.iMode = mode;
return EMFDRV_WriteRecord( dev, &emr.emr );
}
INT CDECL EMFDRV_OffsetViewportOrg( PHYSDEV dev, INT x, INT y )
{
POINT pt;
EMRSETVIEWPORTORGEX emr;
EMFDRV_PDEVICE* physDev = (EMFDRV_PDEVICE*)dev;
GetViewportOrgEx(physDev->hdc, &pt);
emr.emr.iType = EMR_SETVIEWPORTORGEX;
emr.emr.nSize = sizeof(emr);
emr.ptlOrigin.x = pt.x + x;
emr.ptlOrigin.y = pt.y + y;
return EMFDRV_WriteRecord( dev, &emr.emr );
}
INT CDECL EMFDRV_OffsetWindowOrg( PHYSDEV dev, INT x, INT y )
{
POINT pt;
EMRSETWINDOWORGEX emr;
EMFDRV_PDEVICE* physDev = (EMFDRV_PDEVICE*)dev;
GetWindowOrgEx(physDev->hdc, &pt);
emr.emr.iType = EMR_SETWINDOWORGEX;
emr.emr.nSize = sizeof(emr);
emr.ptlOrigin.x = pt.x + x;
emr.ptlOrigin.y = pt.y + y;
return EMFDRV_WriteRecord( dev, &emr.emr );
}

View File

@@ -0,0 +1,556 @@
/*
* Enhanced MetaFile objects
*
* Copyright 1999 Huw D M Davies
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "enhmfdrv/enhmetafiledrv.h"
#include "gdi_private.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(enhmetafile);
/******************************************************************
* EMFDRV_AddHandle
*/
static UINT EMFDRV_AddHandle( PHYSDEV dev, HGDIOBJ obj )
{
EMFDRV_PDEVICE *physDev = (EMFDRV_PDEVICE *)dev;
UINT index;
for(index = 0; index < physDev->handles_size; index++)
if(physDev->handles[index] == 0) break;
if(index == physDev->handles_size) {
physDev->handles_size += HANDLE_LIST_INC;
physDev->handles = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
physDev->handles,
physDev->handles_size * sizeof(physDev->handles[0]));
}
physDev->handles[index] = obj;
physDev->cur_handles++;
if(physDev->cur_handles > physDev->emh->nHandles)
physDev->emh->nHandles++;
return index + 1; /* index 0 is reserved for the hmf, so we increment everything by 1 */
}
/******************************************************************
* EMFDRV_FindObject
*/
static UINT EMFDRV_FindObject( PHYSDEV dev, HGDIOBJ obj )
{
EMFDRV_PDEVICE *physDev = (EMFDRV_PDEVICE*) dev;
UINT index;
for(index = 0; index < physDev->handles_size; index++)
if(physDev->handles[index] == obj) break;
if(index == physDev->handles_size) return 0;
return index + 1;
}
/******************************************************************
* EMFDRV_DeleteObject
*/
BOOL CDECL EMFDRV_DeleteObject( PHYSDEV dev, HGDIOBJ obj )
{
EMRDELETEOBJECT emr;
EMFDRV_PDEVICE *physDev = (EMFDRV_PDEVICE*) dev;
UINT index;
BOOL ret = TRUE;
if(!(index = EMFDRV_FindObject(dev, obj))) return 0;
emr.emr.iType = EMR_DELETEOBJECT;
emr.emr.nSize = sizeof(emr);
emr.ihObject = index;
if(!EMFDRV_WriteRecord( dev, &emr.emr ))
ret = FALSE;
physDev->handles[index - 1] = 0;
physDev->cur_handles--;
return ret;
}
/***********************************************************************
* EMFDRV_SelectBitmap
*/
HBITMAP CDECL EMFDRV_SelectBitmap( PHYSDEV dev, HBITMAP hbitmap )
{
return 0;
}
/* Internal helper for EMFDRV_CreateBrushIndirect():
* Change the padding of a bitmap from 16 (BMP) to 32 (DIB) bits.
*/
static inline void EMFDRV_PadTo32(LPBYTE lpRows, int height, int width)
{
int bytes16 = 2 * ((width + 15) / 16);
int bytes32 = 4 * ((width + 31) / 32);
LPBYTE lpSrc, lpDst;
int i;
if (!height)
return;
height = abs(height) - 1;
lpSrc = lpRows + height * bytes16;
lpDst = lpRows + height * bytes32;
/* Note that we work backwards so we can re-pad in place */
while (height >= 0)
{
for (i = bytes32; i > bytes16; i--)
lpDst[i - 1] = 0; /* Zero the padding bytes */
for (; i > 0; i--)
lpDst[i - 1] = lpSrc[i - 1]; /* Move image bytes into alignment */
lpSrc -= bytes16;
lpDst -= bytes32;
height--;
}
}
/***********************************************************************
* EMFDRV_CreateBrushIndirect
*/
DWORD EMFDRV_CreateBrushIndirect( PHYSDEV dev, HBRUSH hBrush )
{
DWORD index = 0;
LOGBRUSH logbrush;
if (!GetObjectA( hBrush, sizeof(logbrush), &logbrush )) return 0;
switch (logbrush.lbStyle) {
case BS_SOLID:
case BS_HATCHED:
case BS_NULL:
{
EMRCREATEBRUSHINDIRECT emr;
emr.emr.iType = EMR_CREATEBRUSHINDIRECT;
emr.emr.nSize = sizeof(emr);
emr.ihBrush = index = EMFDRV_AddHandle( dev, hBrush );
emr.lb.lbStyle = logbrush.lbStyle;
emr.lb.lbColor = logbrush.lbColor;
emr.lb.lbHatch = logbrush.lbHatch;
if(!EMFDRV_WriteRecord( dev, &emr.emr ))
index = 0;
}
break;
case BS_DIBPATTERN:
{
EMRCREATEDIBPATTERNBRUSHPT *emr;
DWORD bmSize, biSize, size;
BITMAPINFO *info = GlobalLock( (HGLOBAL)logbrush.lbHatch );
if (info->bmiHeader.biCompression)
bmSize = info->bmiHeader.biSizeImage;
else
bmSize = DIB_GetDIBImageBytes(info->bmiHeader.biWidth,
info->bmiHeader.biHeight,
info->bmiHeader.biBitCount);
biSize = bitmap_info_size(info, LOWORD(logbrush.lbColor));
size = sizeof(EMRCREATEDIBPATTERNBRUSHPT) + biSize + bmSize;
emr = HeapAlloc( GetProcessHeap(), 0, size );
if(!emr) break;
emr->emr.iType = EMR_CREATEDIBPATTERNBRUSHPT;
emr->emr.nSize = size;
emr->ihBrush = index = EMFDRV_AddHandle( dev, hBrush );
emr->iUsage = LOWORD(logbrush.lbColor);
emr->offBmi = sizeof(EMRCREATEDIBPATTERNBRUSHPT);
emr->cbBmi = biSize;
emr->offBits = sizeof(EMRCREATEDIBPATTERNBRUSHPT) + biSize;
emr->cbBits = bmSize;
memcpy((char *)emr + sizeof(EMRCREATEDIBPATTERNBRUSHPT), info,
biSize + bmSize );
if(!EMFDRV_WriteRecord( dev, &emr->emr ))
index = 0;
HeapFree( GetProcessHeap(), 0, emr );
GlobalUnlock( (HGLOBAL)logbrush.lbHatch );
}
break;
case BS_PATTERN:
{
EMRCREATEDIBPATTERNBRUSHPT *emr;
BITMAPINFOHEADER *info;
BITMAP bm;
DWORD bmSize, biSize, size;
GetObjectA((HANDLE)logbrush.lbHatch, sizeof(bm), &bm);
if (bm.bmBitsPixel != 1 || bm.bmPlanes != 1)
{
FIXME("Trying to create a color pattern brush\n");
break;
}
/* BMP will be aligned to 32 bits, not 16 */
bmSize = DIB_GetDIBImageBytes(bm.bmWidth, bm.bmHeight, bm.bmBitsPixel);
biSize = sizeof(BITMAPINFOHEADER);
/* FIXME: There is an extra DWORD written by native before the BMI.
* Not sure what its meant to contain.
*/
size = sizeof(EMRCREATEDIBPATTERNBRUSHPT) + biSize + bmSize + sizeof(DWORD);
emr = HeapAlloc( GetProcessHeap(), 0, size );
if(!emr)
break;
info = (BITMAPINFOHEADER *)((LPBYTE)emr +
sizeof(EMRCREATEDIBPATTERNBRUSHPT) + sizeof(DWORD));
info->biSize = sizeof(BITMAPINFOHEADER);
info->biWidth = bm.bmWidth;
info->biHeight = bm.bmHeight;
info->biPlanes = bm.bmPlanes;
info->biBitCount = bm.bmBitsPixel;
info->biSizeImage = bmSize;
GetBitmapBits((HANDLE)logbrush.lbHatch,
bm.bmHeight * BITMAP_GetWidthBytes(bm.bmWidth, bm.bmBitsPixel),
(LPBYTE)info + sizeof(BITMAPINFOHEADER));
/* Change the padding to be DIB compatible if needed */
if (bm.bmWidth & 31)
EMFDRV_PadTo32((LPBYTE)info + sizeof(BITMAPINFOHEADER), bm.bmWidth, bm.bmHeight);
emr->emr.iType = EMR_CREATEMONOBRUSH;
emr->emr.nSize = size;
emr->ihBrush = index = EMFDRV_AddHandle( dev, hBrush );
/* Presumably to reduce the size of the written EMF, MS supports an
* undocumented iUsage value of 2, indicating a mono bitmap without the
* 8 byte 2 entry black/white palette. Stupidly, they could have saved
* over 20 bytes more by also ignoring the BITMAPINFO fields that are
* irrelevant/constant for monochrome bitmaps.
* FIXME: It may be that the DIB functions themselves accept this value.
*/
emr->iUsage = DIB_PAL_MONO;
emr->offBmi = (LPBYTE)info - (LPBYTE)emr;
emr->cbBmi = biSize;
emr->offBits = emr->offBmi + biSize;
emr->cbBits = bmSize;
if(!EMFDRV_WriteRecord( dev, &emr->emr ))
index = 0;
HeapFree( GetProcessHeap(), 0, emr );
}
break;
default:
FIXME("Unknown style %x\n", logbrush.lbStyle);
break;
}
return index;
}
/***********************************************************************
* EMFDRV_SelectBrush
*/
HBRUSH CDECL EMFDRV_SelectBrush(PHYSDEV dev, HBRUSH hBrush )
{
EMFDRV_PDEVICE *physDev = (EMFDRV_PDEVICE*)dev;
EMRSELECTOBJECT emr;
DWORD index;
int i;
if (physDev->restoring) return hBrush; /* don't output SelectObject records during RestoreDC */
/* If the object is a stock brush object, do not need to create it.
* See definitions in wingdi.h for range of stock brushes.
* We do however have to handle setting the higher order bit to
* designate that this is a stock object.
*/
for (i = WHITE_BRUSH; i <= NULL_BRUSH; i++)
{
if (hBrush == GetStockObject(i))
{
index = i | 0x80000000;
goto found;
}
}
if((index = EMFDRV_FindObject(dev, hBrush)) != 0)
goto found;
if (!(index = EMFDRV_CreateBrushIndirect(dev, hBrush ))) return 0;
GDI_hdc_using_object(hBrush, physDev->hdc);
found:
emr.emr.iType = EMR_SELECTOBJECT;
emr.emr.nSize = sizeof(emr);
emr.ihObject = index;
return EMFDRV_WriteRecord( dev, &emr.emr ) ? hBrush : 0;
}
/******************************************************************
* EMFDRV_CreateFontIndirect
*/
static BOOL EMFDRV_CreateFontIndirect(PHYSDEV dev, HFONT hFont )
{
DWORD index = 0;
EMREXTCREATEFONTINDIRECTW emr;
int i;
if (!GetObjectW( hFont, sizeof(emr.elfw.elfLogFont), &emr.elfw.elfLogFont )) return 0;
emr.emr.iType = EMR_EXTCREATEFONTINDIRECTW;
emr.emr.nSize = (sizeof(emr) + 3) / 4 * 4;
emr.ihFont = index = EMFDRV_AddHandle( dev, hFont );
emr.elfw.elfFullName[0] = '\0';
emr.elfw.elfStyle[0] = '\0';
emr.elfw.elfVersion = 0;
emr.elfw.elfStyleSize = 0;
emr.elfw.elfMatch = 0;
emr.elfw.elfReserved = 0;
for(i = 0; i < ELF_VENDOR_SIZE; i++)
emr.elfw.elfVendorId[i] = 0;
emr.elfw.elfCulture = PAN_CULTURE_LATIN;
emr.elfw.elfPanose.bFamilyType = PAN_NO_FIT;
emr.elfw.elfPanose.bSerifStyle = PAN_NO_FIT;
emr.elfw.elfPanose.bWeight = PAN_NO_FIT;
emr.elfw.elfPanose.bProportion = PAN_NO_FIT;
emr.elfw.elfPanose.bContrast = PAN_NO_FIT;
emr.elfw.elfPanose.bStrokeVariation = PAN_NO_FIT;
emr.elfw.elfPanose.bArmStyle = PAN_NO_FIT;
emr.elfw.elfPanose.bLetterform = PAN_NO_FIT;
emr.elfw.elfPanose.bMidline = PAN_NO_FIT;
emr.elfw.elfPanose.bXHeight = PAN_NO_FIT;
if(!EMFDRV_WriteRecord( dev, &emr.emr ))
index = 0;
return index;
}
/***********************************************************************
* EMFDRV_SelectFont
*/
HFONT CDECL EMFDRV_SelectFont( PHYSDEV dev, HFONT hFont, HANDLE gdiFont )
{
EMFDRV_PDEVICE *physDev = (EMFDRV_PDEVICE*)dev;
EMRSELECTOBJECT emr;
DWORD index;
int i;
if (physDev->restoring) return 0; /* don't output SelectObject records during RestoreDC */
/* If the object is a stock font object, do not need to create it.
* See definitions in wingdi.h for range of stock fonts.
* We do however have to handle setting the higher order bit to
* designate that this is a stock object.
*/
for (i = OEM_FIXED_FONT; i <= DEFAULT_GUI_FONT; i++)
{
if (i != DEFAULT_PALETTE && hFont == GetStockObject(i))
{
index = i | 0x80000000;
goto found;
}
}
if((index = EMFDRV_FindObject(dev, hFont)) != 0)
goto found;
if (!(index = EMFDRV_CreateFontIndirect(dev, hFont ))) return HGDI_ERROR;
GDI_hdc_using_object(hFont, physDev->hdc);
found:
emr.emr.iType = EMR_SELECTOBJECT;
emr.emr.nSize = sizeof(emr);
emr.ihObject = index;
if(!EMFDRV_WriteRecord( dev, &emr.emr ))
return HGDI_ERROR;
return 0;
}
/******************************************************************
* EMFDRV_CreatePenIndirect
*/
static DWORD EMFDRV_CreatePenIndirect(PHYSDEV dev, HPEN hPen)
{
EMRCREATEPEN emr;
DWORD index = 0;
if (!GetObjectW( hPen, sizeof(emr.lopn), &emr.lopn ))
{
/* must be an extended pen */
EXTLOGPEN *elp;
INT size = GetObjectW( hPen, 0, NULL );
if (!size) return 0;
elp = HeapAlloc( GetProcessHeap(), 0, size );
GetObjectW( hPen, size, elp );
/* FIXME: add support for user style pens */
emr.lopn.lopnStyle = elp->elpPenStyle;
emr.lopn.lopnWidth.x = elp->elpWidth;
emr.lopn.lopnWidth.y = 0;
emr.lopn.lopnColor = elp->elpColor;
HeapFree( GetProcessHeap(), 0, elp );
}
emr.emr.iType = EMR_CREATEPEN;
emr.emr.nSize = sizeof(emr);
emr.ihPen = index = EMFDRV_AddHandle( dev, hPen );
if(!EMFDRV_WriteRecord( dev, &emr.emr ))
index = 0;
return index;
}
/******************************************************************
* EMFDRV_SelectPen
*/
HPEN CDECL EMFDRV_SelectPen(PHYSDEV dev, HPEN hPen )
{
EMFDRV_PDEVICE *physDev = (EMFDRV_PDEVICE*)dev;
EMRSELECTOBJECT emr;
DWORD index;
int i;
if (physDev->restoring) return hPen; /* don't output SelectObject records during RestoreDC */
/* If the object is a stock pen object, do not need to create it.
* See definitions in wingdi.h for range of stock pens.
* We do however have to handle setting the higher order bit to
* designate that this is a stock object.
*/
for (i = WHITE_PEN; i <= NULL_PEN; i++)
{
if (hPen == GetStockObject(i))
{
index = i | 0x80000000;
goto found;
}
}
if((index = EMFDRV_FindObject(dev, hPen)) != 0)
goto found;
if (!(index = EMFDRV_CreatePenIndirect(dev, hPen))) return 0;
GDI_hdc_using_object(hPen, physDev->hdc);
found:
emr.emr.iType = EMR_SELECTOBJECT;
emr.emr.nSize = sizeof(emr);
emr.ihObject = index;
return EMFDRV_WriteRecord( dev, &emr.emr ) ? hPen : 0;
}
/******************************************************************
* EMFDRV_CreatePalette
*/
static DWORD EMFDRV_CreatePalette(PHYSDEV dev, HPALETTE hPal)
{
WORD i;
struct {
EMRCREATEPALETTE hdr;
PALETTEENTRY entry[255];
} pal;
memset( &pal, 0, sizeof(pal) );
if (!GetObjectW( hPal, sizeof(pal.hdr.lgpl) + sizeof(pal.entry), &pal.hdr.lgpl ))
return 0;
for (i = 0; i < pal.hdr.lgpl.palNumEntries; i++)
pal.hdr.lgpl.palPalEntry[i].peFlags = 0;
pal.hdr.emr.iType = EMR_CREATEPALETTE;
pal.hdr.emr.nSize = sizeof(pal.hdr) + pal.hdr.lgpl.palNumEntries * sizeof(PALETTEENTRY);
pal.hdr.ihPal = EMFDRV_AddHandle( dev, hPal );
if (!EMFDRV_WriteRecord( dev, &pal.hdr.emr ))
pal.hdr.ihPal = 0;
return pal.hdr.ihPal;
}
/******************************************************************
* EMFDRV_SelectPalette
*/
HPALETTE CDECL EMFDRV_SelectPalette( PHYSDEV dev, HPALETTE hPal, BOOL force )
{
EMFDRV_PDEVICE *physDev = (EMFDRV_PDEVICE*)dev;
EMRSELECTPALETTE emr;
DWORD index;
if (physDev->restoring) return hPal; /* don't output SelectObject records during RestoreDC */
if (hPal == GetStockObject( DEFAULT_PALETTE ))
{
index = DEFAULT_PALETTE | 0x80000000;
goto found;
}
if ((index = EMFDRV_FindObject( dev, hPal )) != 0)
goto found;
if (!(index = EMFDRV_CreatePalette( dev, hPal ))) return 0;
GDI_hdc_using_object( hPal, physDev->hdc );
found:
emr.emr.iType = EMR_SELECTPALETTE;
emr.emr.nSize = sizeof(emr);
emr.ihPal = index;
return EMFDRV_WriteRecord( dev, &emr.emr ) ? hPal : 0;
}
/******************************************************************
* EMFDRV_GdiComment
*/
BOOL CDECL EMFDRV_GdiComment(PHYSDEV dev, UINT bytes, CONST BYTE *buffer)
{
EMRGDICOMMENT *emr;
UINT total, rounded_size;
BOOL ret;
rounded_size = (bytes+3) & ~3;
total = offsetof(EMRGDICOMMENT,Data) + rounded_size;
emr = HeapAlloc(GetProcessHeap(), 0, total);
emr->emr.iType = EMR_GDICOMMENT;
emr->emr.nSize = total;
emr->cbData = bytes;
memset(&emr->Data[bytes], 0, rounded_size - bytes);
memcpy(&emr->Data[0], buffer, bytes);
ret = EMFDRV_WriteRecord( dev, &emr->emr );
HeapFree(GetProcessHeap(), 0, emr);
return ret;
}

3495
arwinss/client/gdi32/font.c Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,5 @@
#define REACTOS_VERSION_DLL
#define REACTOS_STR_FILE_DESCRIPTION "GDI Client DLL\0"
#define REACTOS_STR_INTERNAL_NAME "gdi32\0"
#define REACTOS_STR_ORIGINAL_FILENAME "gdi32.dll\0"
#include <reactos/version.rc>

View File

@@ -0,0 +1,657 @@
@ stdcall AbortDoc(long)
@ stdcall AbortPath(long)
@ stdcall AddFontMemResourceEx(ptr long ptr ptr)
@ stdcall AddFontResourceA(str)
@ stdcall AddFontResourceExA(str long ptr)
@ stdcall AddFontResourceExW(wstr long ptr)
@ stub AddFontResourceTracking
@ stdcall AddFontResourceW(wstr)
@ stdcall AngleArc(long long long long long long)
@ stdcall AnimatePalette(long long long ptr)
@ stub AnyLinkedFonts
@ stdcall Arc(long long long long long long long long long)
@ stdcall ArcTo(long long long long long long long long long)
@ stub BRUSHOBJ_hGetColorTransform
@ stub BRUSHOBJ_pvAllocRbrush
@ stub BRUSHOBJ_pvGetRbrush
@ stub BRUSHOBJ_ulGetBrushColor
@ stdcall BeginPath(long)
@ stdcall BitBlt(long long long long long long long long long)
@ stub ByeByeGDI
@ stub CLIPOBJ_bEnum
@ stub CLIPOBJ_cEnumStart
@ stub CLIPOBJ_ppoGetPath
@ stdcall CancelDC(long)
@ stub CheckColorsInGamut
@ stdcall ChoosePixelFormat(long ptr)
@ stdcall Chord(long long long long long long long long long)
@ stub ClearBitmapAttributes
@ stub ClearBrushAttributes
@ stdcall CloseEnhMetaFile(long)
@ stdcall CloseFigure(long)
@ stdcall CloseMetaFile(long)
@ stub ColorCorrectPalette
@ stub ColorMatchToTarget
@ stdcall CombineRgn(long long long long)
@ stdcall CombineTransform(ptr ptr ptr)
@ stdcall CopyEnhMetaFileA(long str)
@ stdcall CopyEnhMetaFileW(long wstr)
@ stdcall CopyMetaFileA(long str)
@ stdcall CopyMetaFileW(long wstr)
@ stdcall CreateBitmap(long long long long ptr)
@ stdcall CreateBitmapIndirect(ptr)
@ stdcall CreateBrushIndirect(ptr)
@ stdcall CreateColorSpaceA(ptr)
@ stdcall CreateColorSpaceW(ptr)
@ stdcall CreateCompatibleBitmap(long long long)
@ stdcall CreateCompatibleDC(long)
@ stdcall CreateDCA(str str str ptr)
@ stdcall CreateDCW(wstr wstr wstr ptr)
@ stdcall CreateDIBPatternBrush(long long)
@ stdcall CreateDIBPatternBrushPt(long long)
@ stdcall CreateDIBSection(long ptr long ptr long long)
@ stdcall CreateDIBitmap(long ptr long ptr ptr long)
@ stdcall CreateDiscardableBitmap(long long long)
@ stdcall CreateEllipticRgn(long long long long)
@ stdcall CreateEllipticRgnIndirect(ptr)
@ stdcall CreateEnhMetaFileA(long str ptr str)
@ stdcall CreateEnhMetaFileW(long wstr ptr wstr)
@ stdcall CreateFontA(long long long long long long long long long long long long long str)
@ stdcall CreateFontIndirectA(ptr)
@ stdcall CreateFontIndirectExA(ptr)
@ stdcall CreateFontIndirectExW(ptr)
@ stdcall CreateFontIndirectW(ptr)
@ stdcall CreateFontW(long long long long long long long long long long long long long wstr)
@ stdcall CreateHalftonePalette(long)
@ stdcall CreateHatchBrush(long long)
@ stdcall CreateICA(str str str ptr)
@ stdcall CreateICW(wstr wstr wstr ptr)
@ stdcall CreateMetaFileA(str)
@ stdcall CreateMetaFileW(wstr)
@ stdcall CreatePalette(ptr)
@ stdcall CreatePatternBrush(long)
@ stdcall CreatePen(long long long)
@ stdcall CreatePenIndirect(ptr)
@ stdcall CreatePolyPolygonRgn(ptr ptr long long)
@ stdcall CreatePolygonRgn(ptr long long)
@ stdcall CreateRectRgn(long long long long)
@ stdcall CreateRectRgnIndirect(ptr)
@ stdcall CreateRoundRectRgn(long long long long long long)
@ stdcall CreateScalableFontResourceA(long str str str)
@ stdcall CreateScalableFontResourceW(long wstr wstr wstr)
@ stdcall CreateSolidBrush(long)
@ stdcall DPtoLP(long ptr long)
@ stub DdEntry0
@ stub DdEntry10
@ stub DdEntry11
@ stub DdEntry12
@ stub DdEntry13
@ stub DdEntry14
@ stub DdEntry15
@ stub DdEntry16
@ stub DdEntry17
@ stub DdEntry18
@ stub DdEntry19
@ stub DdEntry1
@ stub DdEntry20
@ stub DdEntry21
@ stub DdEntry22
@ stub DdEntry23
@ stub DdEntry24
@ stub DdEntry25
@ stub DdEntry26
@ stub DdEntry27
@ stub DdEntry28
@ stub DdEntry29
@ stub DdEntry2
@ stub DdEntry30
@ stub DdEntry31
@ stub DdEntry32
@ stub DdEntry33
@ stub DdEntry34
@ stub DdEntry35
@ stub DdEntry36
@ stub DdEntry37
@ stub DdEntry38
@ stub DdEntry39
@ stub DdEntry3
@ stub DdEntry40
@ stub DdEntry41
@ stub DdEntry42
@ stub DdEntry43
@ stub DdEntry44
@ stub DdEntry45
@ stub DdEntry46
@ stub DdEntry47
@ stub DdEntry48
@ stub DdEntry49
@ stub DdEntry4
@ stub DdEntry50
@ stub DdEntry51
@ stub DdEntry52
@ stub DdEntry53
@ stub DdEntry54
@ stub DdEntry55
@ stub DdEntry56
@ stub DdEntry5
@ stub DdEntry6
@ stub DdEntry7
@ stub DdEntry8
@ stub DdEntry9
@ stdcall DeleteColorSpace(long)
@ stdcall DeleteDC(long)
@ stdcall DeleteEnhMetaFile(long)
@ stdcall DeleteMetaFile(long)
@ stdcall DeleteObject(long)
@ stdcall DescribePixelFormat(long long long ptr)
@ stub DeviceCapabilitiesEx
@ stub DeviceCapabilitiesExA
@ stub DeviceCapabilitiesExW
@ stdcall DrawEscape(long long long ptr)
@ stdcall Ellipse(long long long long long)
@ stdcall EnableEUDC(long)
@ stdcall EndDoc(long)
@ stub EndFormPage
@ stdcall EndPage(long)
@ stdcall EndPath(long)
@ stdcall EngAcquireSemaphore(ptr)
@ stub EngAlphaBlend
@ stub EngAssociateSurface
@ stub EngBitBlt
@ stub EngCheckAbort
@ stub EngComputeGlyphSet
@ stub EngCopyBits
@ stub EngCreateBitmap
@ stub EngCreateClip
@ stub EngCreateDeviceBitmap
@ stub EngCreateDeviceSurface
@ stub EngCreatePalette
@ stdcall EngCreateSemaphore()
@ stub EngDeleteClip
@ stub EngDeletePalette
@ stub EngDeletePath
@ stdcall EngDeleteSemaphore(ptr)
@ stub EngDeleteSurface
@ stub EngEraseSurface
@ stub EngFillPath
@ stdcall EngFindResource(ptr long long ptr)
@ stdcall EngFreeModule(ptr)
@ stdcall EngGetCurrentCodePage(ptr ptr)
@ stub EngGetDriverName
@ stub EngGetPrinterDataFileName
@ stub EngGradientFill
@ stub EngLineTo
@ stdcall EngLoadModule(ptr)
@ stub EngLockSurface
@ stub EngMarkBandingSurface
@ stub EngMultiByteToUnicodeN
@ stdcall EngMultiByteToWideChar(long wstr long str long)
@ stub EngPaint
@ stub EngPlgBlt
@ stub EngQueryEMFInfo
@ stdcall EngQueryLocalTime(ptr)
@ stdcall EngReleaseSemaphore(ptr)
@ stub EngStretchBlt
@ stub EngStretchBltROP
@ stub EngStrokeAndFillPath
@ stub EngStrokePath
@ stub EngTextOut
@ stub EngTransparentBlt
@ stub EngUnicodeToMultiByteN
@ stub EngUnlockSurface
@ stub EngWideCharToMultiByte
@ stdcall EnumEnhMetaFile(long long ptr ptr ptr)
@ stdcall EnumFontFamiliesA(long str ptr long)
@ stdcall EnumFontFamiliesExA(long ptr ptr long long)
@ stdcall EnumFontFamiliesExW(long ptr ptr long long)
@ stdcall EnumFontFamiliesW(long wstr ptr long)
@ stdcall EnumFontsA(long str ptr long)
@ stdcall EnumFontsW(long wstr ptr long)
@ stdcall EnumICMProfilesA(long ptr long)
@ stdcall EnumICMProfilesW(long ptr long)
@ stdcall EnumMetaFile(long long ptr ptr)
@ stdcall EnumObjects(long long ptr long)
@ stdcall EqualRgn(long long)
@ stdcall Escape(long long long ptr ptr)
@ stub EudcLoadLinkW
@ stub EudcUnloadLinkW
@ stdcall ExcludeClipRect(long long long long long)
@ stdcall ExtCreatePen(long long ptr long ptr)
@ stdcall ExtCreateRegion(ptr long ptr)
@ stdcall ExtEscape(long long long ptr long ptr)
@ stdcall ExtFloodFill(long long long long long)
@ stdcall ExtSelectClipRgn(long long long)
@ stdcall ExtTextOutA(long long long long ptr str long ptr)
@ stdcall ExtTextOutW(long long long long ptr wstr long ptr)
@ stub FONTOBJ_cGetAllGlyphHandles
@ stub FONTOBJ_cGetGlyphs
@ stub FONTOBJ_pQueryGlyphAttrs
@ stub FONTOBJ_pfdg
@ stub FONTOBJ_pifi
@ stub FONTOBJ_pvTrueTypeFontFile
@ stub FONTOBJ_pxoGetXform
@ stub FONTOBJ_vGetInfo
@ stdcall FillPath(long)
@ stdcall FillRgn(long long long)
@ stdcall FixBrushOrgEx(long long long ptr)
@ stdcall FlattenPath(long)
@ stdcall FloodFill(long long long long)
@ stdcall FontIsLinked(long)
@ stdcall FrameRgn(long long long long long)
@ stub FreeImageColorMatcher
@ stdcall GdiAddFontResourceW(ptr ptr ptr)
@ stub GdiAddGlsBounds
@ stub GdiAddGlsRecord
@ stdcall GdiAlphaBlend(long long long long long long long long long long long)
@ stub GdiArtificialDecrementDriver
@ stub GdiAssociateObject
@ stub GdiCleanCacheDC
@ stdcall GdiComment(long long ptr)
@ stub GdiConsoleTextOut
@ stub GdiConvertAndCheckDC
@ stdcall GdiConvertBitmap(ptr)
@ stub GdiConvertBitmapV5
@ stdcall GdiConvertBrush(ptr)
@ stdcall GdiConvertDC(ptr)
@ stub GdiConvertEnhMetaFile
@ stdcall GdiConvertFont(ptr)
@ stub GdiConvertMetaFilePict
@ stdcall GdiConvertPalette(ptr)
@ stdcall GdiConvertRegion(ptr)
@ stdcall GdiConvertToDevmodeW(ptr)
@ stub GdiCreateLocalBitmap
@ stub GdiCreateLocalBrush
@ stub GdiCreateLocalEnhMetaFile
@ stub GdiCreateLocalFont
@ stub GdiCreateLocalMetaFilePict
@ stub GdiCreateLocalPalette
@ stub GdiCreateLocalRegion
@ stub GdiDciBeginAccess
@ stub GdiDciCreateOffscreenSurface
@ stub GdiDciCreateOverlaySurface
@ stub GdiDciCreatePrimarySurface
@ stub GdiDciDestroySurface
@ stub GdiDciDrawSurface
@ stub GdiDciEndAccess
@ stub GdiDciEnumSurface
@ stub GdiDciInitialize
@ stub GdiDciSetClipList
@ stub GdiDciSetDestination
@ stdcall GdiDeleteLocalDC(ptr)
@ stub GdiDeleteLocalObject
@ stub GdiDeleteSpoolFileHandle
@ stdcall GdiDescribePixelFormat(ptr long long ptr)
@ stub GdiDllInitialize
@ stub GdiDrawStream
@ stub GdiEndDocEMF
@ stub GdiEndPageEMF
@ stub GdiEntry10
@ stub GdiEntry11
@ stub GdiEntry12
@ stub GdiEntry13
@ stub GdiEntry14
@ stub GdiEntry15
@ stub GdiEntry16
@ stub GdiEntry1
@ stub GdiEntry2
@ stub GdiEntry3
@ stub GdiEntry4
@ stub GdiEntry5
@ stub GdiEntry6
@ stub GdiEntry7
@ stub GdiEntry8
@ stub GdiEntry9
@ stub GdiFixUpHandle
@ stdcall GdiFlush()
@ stub GdiFullscreenControl
@ stdcall GdiGetBatchLimit()
@ stdcall GdiGetCharDimensions(long ptr ptr)
@ stdcall GdiGetCodePage(long)
@ stub GdiGetDC
@ stub GdiGetDevmodeForPage
@ stub GdiGetLocalBitmap
@ stdcall GdiGetLocalBrush(ptr)
@ stdcall GdiGetLocalDC(ptr)
@ stub GdiGetLocalFont
@ stub GdiGetPageCount
@ stub GdiGetPageHandle
@ stub GdiGetSpoolFileHandle
@ stdcall GdiGetSpoolMessage(ptr long ptr long)
@ stdcall GdiGradientFill(long ptr long ptr long long)
@ stdcall GdiInitSpool()
@ stdcall GdiInitializeLanguagePack(long)
@ stdcall GdiIsMetaFileDC(long)
@ stdcall GdiIsMetaPrintDC(long)
@ stdcall GdiIsPlayMetafileDC(long)
@ stub GdiPlayDCScript
@ stub GdiPlayEMF
@ stub GdiPlayJournal
@ stub GdiPlayPageEMF
@ stub GdiPlayPrivatePageEMF
@ stub GdiPlayScript
@ stub GdiPrinterThunk
@ stub GdiProcessSetup
@ stub GdiQueryFonts
@ stub GdiQueryTable
@ stdcall GdiRealizationInfo(long ptr)
@ stub GdiReleaseDC
@ stdcall GdiReleaseLocalDC(ptr)
@ stub GdiResetDCEMF
@ stdcall GdiSetAttrs(ptr)
@ stdcall GdiSetBatchLimit(long)
@ stub GdiSetLastError
@ stdcall GdiSetPixelFormat(ptr long)
@ stub GdiSetServerAttr
@ stub GdiStartDocEMF
@ stub GdiStartPageEMF
@ stdcall GdiSwapBuffers(ptr)
@ stdcall GdiTransparentBlt(long long long long long long long long long long long)
@ stub GdiValidateHandle
@ stub GdiWinWatchClose
@ stub GdiWinWatchDidStatusChange
@ stub GdiWinWatchGetClipList
@ stub GdiWinWatchOpen
@ stdcall GetArcDirection(long)
@ stdcall GetAspectRatioFilterEx(long ptr)
@ stub GetBitmapAttributes
@ stdcall GetBitmapBits(long long ptr)
@ stdcall GetBitmapDimensionEx(long ptr)
@ stdcall GetBkColor(long)
@ stdcall GetBkMode(long)
@ stdcall GetBoundsRect(long ptr long)
@ stub GetBrushAttributes
@ stdcall GetBrushOrgEx(long ptr)
@ stdcall GetCharABCWidthsA(long long long ptr)
@ stdcall GetCharABCWidthsFloatA(long long long ptr)
@ stdcall GetCharABCWidthsFloatW(long long long ptr)
@ stdcall GetCharABCWidthsI(long long long ptr ptr)
@ stdcall GetCharABCWidthsW(long long long ptr)
@ stdcall GetCharWidth32A(long long long long)
@ stdcall GetCharWidth32W(long long long long)
@ stdcall GetCharWidthA(long long long long) GetCharWidth32A
@ stdcall GetCharWidthFloatA(long long long ptr)
@ stdcall GetCharWidthFloatW(long long long ptr)
@ stdcall GetCharWidthI(ptr long long ptr ptr)
@ stub GetCharWidthInfo
@ stdcall GetCharWidthW(long long long long) GetCharWidth32W
@ stub GetCharWidthWOW
@ stdcall GetCharacterPlacementA(long str long long ptr long)
@ stdcall GetCharacterPlacementW(long wstr long long ptr long)
@ stdcall GetClipBox(long ptr)
@ stdcall GetClipRgn(long long)
@ stdcall GetColorAdjustment(long ptr)
@ stdcall GetColorSpace(long)
@ stdcall GetCurrentObject(long long)
@ stdcall GetCurrentPositionEx(long ptr)
@ stdcall GetDCBrushColor(long)
@ stdcall GetDCOrgEx(long ptr)
@ stdcall GetDCPenColor(long)
@ stdcall GetDIBColorTable(long long long ptr)
@ stdcall GetDIBits(long long long long ptr ptr long)
@ stdcall GetDeviceCaps(long long)
@ stdcall GetDeviceGammaRamp(long ptr)
@ stub GetETM
@ stub GetEUDCTimeStamp
@ stub GetEUDCTimeStampExW
@ stdcall GetEnhMetaFileA(str)
@ stdcall GetEnhMetaFileBits(long long ptr)
@ stdcall GetEnhMetaFileDescriptionA(long long ptr)
@ stdcall GetEnhMetaFileDescriptionW(long long ptr)
@ stdcall GetEnhMetaFileHeader(long long ptr)
@ stdcall GetEnhMetaFilePaletteEntries (long long ptr)
@ stub GetEnhMetaFilePixelFormat
@ stdcall GetEnhMetaFileW(wstr)
@ stub GetFontAssocStatus
@ stdcall GetFontData(long long long ptr long)
@ stdcall GetFontLanguageInfo(long)
@ stub GetFontResourceInfo
@ stdcall GetFontResourceInfoW(str ptr ptr long)
@ stdcall GetFontUnicodeRanges(ptr ptr)
@ stdcall GetGlyphIndicesA(long ptr long ptr long)
@ stdcall GetGlyphIndicesW(long ptr long ptr long)
@ stdcall GetGlyphOutline(long long long ptr long ptr ptr) GetGlyphOutlineA
@ stdcall GetGlyphOutlineA(long long long ptr long ptr ptr)
@ stdcall GetGlyphOutlineW(long long long ptr long ptr ptr)
@ stub GetGlyphOutlineWow
@ stdcall GetGraphicsMode(long)
@ stub GetHFONT
@ stdcall GetICMProfileA(long ptr ptr)
@ stdcall GetICMProfileW(long ptr ptr)
@ stdcall GetKerningPairs(long long ptr) GetKerningPairsA
@ stdcall GetKerningPairsA(long long ptr)
@ stdcall GetKerningPairsW(long long ptr)
@ stdcall GetLayout(long)
@ stdcall GetLogColorSpaceA(long ptr long)
@ stdcall GetLogColorSpaceW(long ptr long)
@ stdcall GetMapMode(long)
@ stdcall GetMetaFileA(str)
@ stdcall GetMetaFileBitsEx(long long ptr)
@ stdcall GetMetaFileW(wstr)
@ stdcall GetMetaRgn(long long)
@ stdcall GetMiterLimit(long ptr)
@ stdcall GetNearestColor(long long)
@ stdcall GetNearestPaletteIndex(long long)
@ stdcall GetObjectA(long long ptr)
@ stdcall GetObjectType(long)
@ stdcall GetObjectW(long long ptr)
@ stdcall GetOutlineTextMetricsA(long long ptr)
@ stdcall GetOutlineTextMetricsW(long long ptr)
@ stdcall GetPaletteEntries(long long long ptr)
@ stdcall GetPath(long ptr ptr long)
@ stdcall GetPixel(long long long)
@ stdcall GetPixelFormat(long)
@ stdcall GetPolyFillMode(long)
@ stdcall GetROP2(long)
@ stdcall GetRandomRgn(long long long)
@ stdcall GetRasterizerCaps(ptr long)
@ stdcall GetRegionData(long long ptr)
@ stdcall GetRelAbs(long long)
@ stdcall GetRgnBox(long ptr)
@ stdcall GetStockObject(long)
@ stdcall GetStretchBltMode(long)
@ stub GetStringBitmapA
@ stub GetStringBitmapW
@ stdcall GetSystemPaletteEntries(long long long ptr)
@ stdcall GetSystemPaletteUse(long)
@ stdcall GetTextAlign(long)
@ stdcall GetTextCharacterExtra(long)
@ stdcall GetTextCharset(long)
@ stdcall GetTextCharsetInfo(long ptr long)
@ stdcall GetTextColor(long)
@ stdcall GetTextExtentExPointA(long str long long ptr ptr ptr)
@ stdcall GetTextExtentExPointI(long ptr long long ptr ptr ptr)
@ stdcall GetTextExtentExPointW(long wstr long long ptr ptr ptr)
@ stub GetTextExtentExPointWPri
@ stdcall GetTextExtentPoint32A(long str long ptr)
@ stdcall GetTextExtentPoint32W(long wstr long ptr)
@ stdcall GetTextExtentPointA(long str long ptr)
@ stdcall GetTextExtentPointI(long ptr long ptr)
@ stdcall GetTextExtentPointW(long wstr long ptr)
@ stdcall GetTextFaceA(long long ptr)
@ stub GetTextFaceAliasW
@ stdcall GetTextFaceW(long long ptr)
@ stdcall GetTextMetricsA(long ptr)
@ stdcall GetTextMetricsW(long ptr)
@ stdcall GetTransform(long long ptr)
@ stdcall GetViewportExtEx(long ptr)
@ stdcall GetViewportOrgEx(long ptr)
@ stdcall GetWinMetaFileBits(long long ptr long long)
@ stdcall GetWindowExtEx(long ptr)
@ stdcall GetWindowOrgEx(long ptr)
@ stdcall GetWorldTransform(long ptr)
@ stdcall IntersectClipRect(long long long long long)
@ stdcall InvertRgn(long long)
@ stub IsValidEnhMetaRecord
@ stub IsValidEnhMetaRecordOffExt
@ stdcall LPtoDP(long ptr long)
@ stdcall LineDDA(long long long long ptr long)
@ stdcall LineTo(long long long)
@ stub LoadImageColorMatcherA
@ stub LoadImageColorMatcherW
@ stdcall MaskBlt(long long long long long long long long long long long long)
@ stdcall MirrorRgn(long long)
@ stdcall ModifyWorldTransform(long ptr long)
@ stdcall MoveToEx(long long long ptr)
@ stdcall NamedEscape(long wstr long long ptr long ptr)
@ stdcall OffsetClipRgn(long long long)
@ stdcall OffsetRgn(long long long)
@ stdcall OffsetViewportOrgEx(long long long ptr)
@ stdcall OffsetWindowOrgEx(long long long ptr)
@ stdcall PaintRgn(long long)
@ stdcall PatBlt(long long long long long long)
@ stdcall PathToRegion(long)
@ stdcall Pie(long long long long long long long long long)
@ stdcall PlayEnhMetaFile(long long ptr)
@ stdcall PlayEnhMetaFileRecord(long ptr ptr long)
@ stdcall PlayMetaFile(long long)
@ stdcall PlayMetaFileRecord(long ptr ptr long)
@ stdcall PlgBlt(long ptr long long long long long long long long)
@ stdcall PolyBezier(long ptr long)
@ stdcall PolyBezierTo(long ptr long)
@ stdcall PolyDraw(long ptr ptr long)
@ stub PolyPatBlt
@ stdcall PolyPolygon(long ptr ptr long)
@ stdcall PolyPolyline(long ptr ptr long)
@ stdcall PolyTextOutA(long ptr long)
@ stdcall PolyTextOutW(long ptr long)
@ stdcall Polygon(long ptr long)
@ stdcall Polyline(long ptr long)
@ stdcall PolylineTo(long ptr long)
@ stdcall PtInRegion(long long long)
@ stdcall PtVisible(long long long)
@ stub QueryFontAssocStatus
@ stdcall RealizePalette(long)
@ stdcall RectInRegion(long ptr)
@ stdcall RectVisible(long ptr)
@ stdcall Rectangle(long long long long long)
@ stdcall RemoveFontMemResourceEx(ptr)
@ stdcall RemoveFontResourceA(str)
@ stdcall RemoveFontResourceExA(str long ptr)
@ stdcall RemoveFontResourceExW(wstr long ptr)
@ stub RemoveFontResourceTracking
@ stdcall RemoveFontResourceW(wstr)
@ stdcall ResetDCA(long ptr)
@ stdcall ResetDCW(long ptr)
@ stdcall ResizePalette(long long)
@ stdcall RestoreDC(long long)
@ stdcall RoundRect(long long long long long long long)
@ stdcall SaveDC(long)
@ stdcall ScaleViewportExtEx(long long long long long ptr)
@ stdcall ScaleWindowExtEx(long long long long long ptr)
@ stub SelectBrushLocal
@ stdcall SelectClipPath(long long)
@ stdcall SelectClipRgn(long long)
@ stub SelectFontLocal
@ stdcall SelectObject(long long)
@ stdcall SelectPalette(long long long)
@ stdcall SetAbortProc(long ptr)
@ stdcall SetArcDirection(long long)
@ stub SetBitmapAttributes
@ stdcall SetBitmapBits(long long ptr)
@ stdcall SetBitmapDimensionEx(long long long ptr)
@ stdcall SetBkColor(long long)
@ stdcall SetBkMode(long long)
@ stdcall SetBoundsRect(long ptr long)
@ stub SetBrushAttributes
@ stdcall SetBrushOrgEx(long long long ptr)
@ stdcall SetColorAdjustment(long ptr)
@ stdcall SetColorSpace(long long)
@ stdcall SetDCBrushColor(long long)
@ stdcall SetDCPenColor(long long)
@ stdcall SetDIBColorTable(long long long ptr)
@ stdcall SetDIBits(long long long long ptr ptr long)
@ stdcall SetDIBitsToDevice(long long long long long long long long long ptr ptr long)
@ stdcall SetDeviceGammaRamp(long ptr)
@ stdcall SetEnhMetaFileBits(long ptr)
@ stub SetFontEnumeration
@ stdcall SetGraphicsMode(long long)
@ stdcall SetICMMode(long long)
@ stdcall SetICMProfileA(long str)
@ stdcall SetICMProfileW(long wstr)
@ stdcall SetLayout(long long)
@ stub SetLayoutWidth
@ stdcall SetMagicColors(ptr long long)
@ stdcall SetMapMode(long long)
@ stdcall SetMapperFlags(long long)
@ stdcall SetMetaFileBitsEx(long ptr)
@ stdcall SetMetaRgn(long)
@ stdcall SetMiterLimit(long long ptr)
@ stdcall SetObjectOwner(long long)
@ stdcall SetPaletteEntries(long long long ptr)
@ stdcall SetPixel(long long long long)
@ stdcall SetPixelFormat(long long ptr)
@ stdcall SetPixelV(long long long long)
@ stdcall SetPolyFillMode(long long)
@ stdcall SetROP2(long long)
@ stdcall SetRectRgn(long long long long long)
@ stdcall SetRelAbs(long long)
@ stdcall SetStretchBltMode(long long)
@ stdcall SetSystemPaletteUse(long long)
@ stdcall SetTextAlign(long long)
@ stdcall SetTextCharacterExtra(long long)
@ stdcall SetTextColor(long long)
@ stdcall SetTextJustification(long long long)
@ stdcall SetViewportExtEx(long long long ptr)
@ stdcall SetViewportOrgEx(long long long ptr)
@ stdcall SetVirtualResolution(long long long long long)
@ stdcall SetWinMetaFileBits(long ptr long ptr)
@ stdcall SetWindowExtEx(long long long ptr)
@ stdcall SetWindowOrgEx(long long long ptr)
@ stdcall SetWorldTransform(long ptr)
@ stdcall StartDocA(long ptr)
@ stdcall StartDocW(long ptr)
@ stub StartFormPage
@ stdcall StartPage(long)
@ stdcall StretchBlt(long long long long long long long long long long long)
@ stdcall StretchDIBits(long long long long long long long long long ptr ptr long long)
@ stdcall StrokeAndFillPath(long)
@ stdcall StrokePath(long)
@ stdcall SwapBuffers(long)
@ stdcall TextOutA(long long long str long)
@ stdcall TextOutW(long long long wstr long)
@ stdcall TranslateCharsetInfo(ptr ptr long)
@ stub UnloadNetworkFonts
@ stdcall UnrealizeObject(long)
@ stdcall UpdateColors(long)
@ stdcall UpdateICMRegKey(long str str long) UpdateICMRegKeyA
@ stdcall UpdateICMRegKeyA(long str str long)
@ stdcall UpdateICMRegKeyW(long wstr wstr long)
@ stdcall WidenPath(long)
@ stub bInitSystemAndFontsDirectoriesW
@ stub bMakePathNameW
@ stub cGetTTFFromFOT
@ stub gdiPlaySpoolStream
@ extern pfnRealizePalette
@ extern pfnSelectPalette
@ stub pstackConnect
################################################################
# Wine extensions: OpenGL support
#
@ stdcall wglCopyContext(long long long)
@ stdcall wglCreateContext(long)
@ stdcall wglDeleteContext(long)
@ stdcall wglGetCurrentContext()
@ stdcall wglGetCurrentDC()
@ stdcall -private wglGetProcAddress(str)
@ stdcall wglMakeCurrent(long long)
@ stdcall wglShareLists(long long)
@ stdcall wglUseFontBitmapsA(long long long long)
@ stdcall wglUseFontBitmapsW(long long long long)
################################################################
# Wine extensions: Win16 functions that are needed by other dlls
#
@ stdcall GetDCHook(long ptr)
@ stdcall SetDCHook(long ptr long)
@ stdcall SetHookFlags(long long)
################################################################
# Wine internal extensions
#
# All functions must be prefixed with '__wine_' (for internal functions)
# or 'wine_' (for user-visible functions) to avoid namespace conflicts.
# GDI objects
@ cdecl __wine_make_gdi_object_system(long long)
@ cdecl __wine_set_visible_region(long long ptr)

View File

@@ -0,0 +1,518 @@
/*
* GDI definitions
*
* Copyright 1993 Alexandre Julliard
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef __WINE_GDI_PRIVATE_H
#define __WINE_GDI_PRIVATE_H
#include <math.h>
#include <stdarg.h>
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
/* Metafile defines */
#define META_EOF 0x0000
/* values of mtType in METAHEADER. Note however that the disk image of a disk
based metafile has mtType == 1 */
#define METAFILE_MEMORY 1
#define METAFILE_DISK 2
#define MFHEADERSIZE (sizeof(METAHEADER))
#define MFVERSION 0x300
typedef struct {
EMR emr;
INT nBreakExtra;
INT nBreakCount;
} EMRSETTEXTJUSTIFICATION, *PEMRSETTEXTJUSTIFICATION;
/* extra stock object: default 1x1 bitmap for memory DCs */
#define DEFAULT_BITMAP (STOCK_LAST+1)
struct gdi_obj_funcs
{
HGDIOBJ (*pSelectObject)( HGDIOBJ handle, HDC hdc );
INT (*pGetObjectA)( HGDIOBJ handle, INT count, LPVOID buffer );
INT (*pGetObjectW)( HGDIOBJ handle, INT count, LPVOID buffer );
BOOL (*pUnrealizeObject)( HGDIOBJ handle );
BOOL (*pDeleteObject)( HGDIOBJ handle );
};
struct hdc_list
{
HDC hdc;
struct hdc_list *next;
};
typedef struct tagGDIOBJHDR
{
WORD type; /* object type (one of the OBJ_* constants) */
WORD system : 1; /* system object flag */
WORD deleted : 1; /* whether DeleteObject has been called on this object */
DWORD selcount; /* number of times the object is selected in a DC */
const struct gdi_obj_funcs *funcs;
struct hdc_list *hdcs;
} GDIOBJHDR;
/* Device functions for the Wine driver interface */
typedef struct { int opaque; } *PHYSDEV; /* PHYSDEV is an opaque pointer */
typedef struct tagDC_FUNCS
{
INT (CDECL *pAbortDoc)(PHYSDEV);
BOOL (CDECL *pAbortPath)(PHYSDEV);
BOOL (CDECL *pAlphaBlend)(PHYSDEV,INT,INT,INT,INT,PHYSDEV,INT,INT,INT,INT,BLENDFUNCTION);
BOOL (CDECL *pAngleArc)(PHYSDEV,INT,INT,DWORD,FLOAT,FLOAT);
BOOL (CDECL *pArc)(PHYSDEV,INT,INT,INT,INT,INT,INT,INT,INT);
BOOL (CDECL *pArcTo)(PHYSDEV,INT,INT,INT,INT,INT,INT,INT,INT);
BOOL (CDECL *pBeginPath)(PHYSDEV);
BOOL (CDECL *pBitBlt)(PHYSDEV,INT,INT,INT,INT,PHYSDEV,INT,INT,DWORD);
INT (CDECL *pChoosePixelFormat)(PHYSDEV,const PIXELFORMATDESCRIPTOR *);
BOOL (CDECL *pChord)(PHYSDEV,INT,INT,INT,INT,INT,INT,INT,INT);
BOOL (CDECL *pCloseFigure)(PHYSDEV);
BOOL (CDECL *pCreateBitmap)(PHYSDEV,HBITMAP,LPVOID);
BOOL (CDECL *pCreateDC)(HDC,PHYSDEV *,LPCWSTR,LPCWSTR,LPCWSTR,const DEVMODEW*);
HBITMAP (CDECL *pCreateDIBSection)(PHYSDEV,HBITMAP,const BITMAPINFO *,UINT);
BOOL (CDECL *pDeleteBitmap)(HBITMAP);
BOOL (CDECL *pDeleteDC)(PHYSDEV);
BOOL (CDECL *pDeleteObject)(PHYSDEV,HGDIOBJ);
INT (CDECL *pDescribePixelFormat)(PHYSDEV,INT,UINT,PIXELFORMATDESCRIPTOR *);
DWORD (CDECL *pDeviceCapabilities)(LPSTR,LPCSTR,LPCSTR,WORD,LPSTR,LPDEVMODEA);
BOOL (CDECL *pEllipse)(PHYSDEV,INT,INT,INT,INT);
INT (CDECL *pEndDoc)(PHYSDEV);
INT (CDECL *pEndPage)(PHYSDEV);
BOOL (CDECL *pEndPath)(PHYSDEV);
INT (CDECL *pEnumICMProfiles)(PHYSDEV,ICMENUMPROCW,LPARAM);
BOOL (CDECL *pEnumDeviceFonts)(PHYSDEV,LPLOGFONTW,FONTENUMPROCW,LPARAM);
INT (CDECL *pExcludeClipRect)(PHYSDEV,INT,INT,INT,INT);
INT (CDECL *pExtDeviceMode)(LPSTR,HWND,LPDEVMODEA,LPSTR,LPSTR,LPDEVMODEA,LPSTR,DWORD);
INT (CDECL *pExtEscape)(PHYSDEV,INT,INT,LPCVOID,INT,LPVOID);
BOOL (CDECL *pExtFloodFill)(PHYSDEV,INT,INT,COLORREF,UINT);
INT (CDECL *pExtSelectClipRgn)(PHYSDEV,HRGN,INT);
BOOL (CDECL *pExtTextOut)(PHYSDEV,INT,INT,UINT,const RECT*,LPCWSTR,UINT,const INT*);
BOOL (CDECL *pFillPath)(PHYSDEV);
BOOL (CDECL *pFillRgn)(PHYSDEV,HRGN,HBRUSH);
BOOL (CDECL *pFlattenPath)(PHYSDEV);
BOOL (CDECL *pFrameRgn)(PHYSDEV,HRGN,HBRUSH,INT,INT);
BOOL (CDECL *pGdiComment)(PHYSDEV,UINT,CONST BYTE*);
LONG (CDECL *pGetBitmapBits)(HBITMAP,void*,LONG);
BOOL (CDECL *pGetCharWidth)(PHYSDEV,UINT,UINT,LPINT);
UINT (CDECL *pGetDIBColorTable)(PHYSDEV,UINT,UINT,RGBQUAD*);
INT (CDECL *pGetDIBits)(PHYSDEV,HBITMAP,UINT,UINT,LPVOID,BITMAPINFO*,UINT);
INT (CDECL *pGetDeviceCaps)(PHYSDEV,INT);
BOOL (CDECL *pGetDeviceGammaRamp)(PHYSDEV,LPVOID);
BOOL (CDECL *pGetICMProfile)(PHYSDEV,LPDWORD,LPWSTR);
COLORREF (CDECL *pGetNearestColor)(PHYSDEV,COLORREF);
COLORREF (CDECL *pGetPixel)(PHYSDEV,INT,INT);
INT (CDECL *pGetPixelFormat)(PHYSDEV);
UINT (CDECL *pGetSystemPaletteEntries)(PHYSDEV,UINT,UINT,LPPALETTEENTRY);
BOOL (CDECL *pGetTextExtentExPoint)(PHYSDEV,LPCWSTR,INT,INT,LPINT,LPINT,LPSIZE);
BOOL (CDECL *CDECL pGetTextMetrics)(PHYSDEV,TEXTMETRICW*);
INT (CDECL *pIntersectClipRect)(PHYSDEV,INT,INT,INT,INT);
BOOL (CDECL *pInvertRgn)(PHYSDEV,HRGN);
BOOL (CDECL *pLineTo)(PHYSDEV,INT,INT);
BOOL (CDECL *pModifyWorldTransform)(PHYSDEV,const XFORM*,INT);
BOOL (CDECL *pMoveTo)(PHYSDEV,INT,INT);
INT (CDECL *pOffsetClipRgn)(PHYSDEV,INT,INT);
INT (CDECL *pOffsetViewportOrg)(PHYSDEV,INT,INT);
INT (CDECL *pOffsetWindowOrg)(PHYSDEV,INT,INT);
BOOL (CDECL *pPaintRgn)(PHYSDEV,HRGN);
BOOL (CDECL *pPatBlt)(PHYSDEV,INT,INT,INT,INT,DWORD);
BOOL (CDECL *pPie)(PHYSDEV,INT,INT,INT,INT,INT,INT,INT,INT);
BOOL (CDECL *pPolyBezier)(PHYSDEV,const POINT*,DWORD);
BOOL (CDECL *pPolyBezierTo)(PHYSDEV,const POINT*,DWORD);
BOOL (CDECL *pPolyDraw)(PHYSDEV,const POINT*,const BYTE *,DWORD);
BOOL (CDECL *pPolyPolygon)(PHYSDEV,const POINT*,const INT*,UINT);
BOOL (CDECL *pPolyPolyline)(PHYSDEV,const POINT*,const DWORD*,DWORD);
BOOL (CDECL *pPolygon)(PHYSDEV,const POINT*,INT);
BOOL (CDECL *pPolyline)(PHYSDEV,const POINT*,INT);
BOOL (CDECL *pPolylineTo)(PHYSDEV,const POINT*,INT);
UINT (CDECL *pRealizeDefaultPalette)(PHYSDEV);
UINT (CDECL *pRealizePalette)(PHYSDEV,HPALETTE,BOOL);
BOOL (CDECL *pRectangle)(PHYSDEV,INT,INT,INT,INT);
HDC (CDECL *pResetDC)(PHYSDEV,const DEVMODEW*);
BOOL (CDECL *pRestoreDC)(PHYSDEV,INT);
BOOL (CDECL *pRoundRect)(PHYSDEV,INT,INT,INT,INT,INT,INT);
INT (CDECL *pSaveDC)(PHYSDEV);
INT (CDECL *pScaleViewportExt)(PHYSDEV,INT,INT,INT,INT);
INT (CDECL *pScaleWindowExt)(PHYSDEV,INT,INT,INT,INT);
HBITMAP (CDECL *pSelectBitmap)(PHYSDEV,HBITMAP);
HBRUSH (CDECL *pSelectBrush)(PHYSDEV,HBRUSH);
BOOL (CDECL *pSelectClipPath)(PHYSDEV,INT);
HFONT (CDECL *pSelectFont)(PHYSDEV,HFONT,HANDLE);
HPALETTE (CDECL *pSelectPalette)(PHYSDEV,HPALETTE,BOOL);
HPEN (CDECL *pSelectPen)(PHYSDEV,HPEN);
INT (CDECL *pSetArcDirection)(PHYSDEV,INT);
LONG (CDECL *pSetBitmapBits)(HBITMAP,const void*,LONG);
COLORREF (CDECL *pSetBkColor)(PHYSDEV,COLORREF);
INT (CDECL *pSetBkMode)(PHYSDEV,INT);
COLORREF (CDECL *pSetDCBrushColor)(PHYSDEV, COLORREF);
COLORREF (CDECL *pSetDCPenColor)(PHYSDEV, COLORREF);
UINT (CDECL *pSetDIBColorTable)(PHYSDEV,UINT,UINT,const RGBQUAD*);
INT (CDECL *pSetDIBits)(PHYSDEV,HBITMAP,UINT,UINT,LPCVOID,const BITMAPINFO*,UINT);
INT (CDECL *pSetDIBitsToDevice)(PHYSDEV,INT,INT,DWORD,DWORD,INT,INT,UINT,UINT,LPCVOID,
const BITMAPINFO*,UINT);
VOID (CDECL *pSetDeviceClipping)(PHYSDEV,HRGN,HRGN);
BOOL (CDECL *pSetDeviceGammaRamp)(PHYSDEV,LPVOID);
INT (CDECL *pSetMapMode)(PHYSDEV,INT);
DWORD (CDECL *pSetMapperFlags)(PHYSDEV,DWORD);
COLORREF (CDECL *pSetPixel)(PHYSDEV,INT,INT,COLORREF);
BOOL (CDECL *pSetPixelFormat)(PHYSDEV,INT,const PIXELFORMATDESCRIPTOR *);
INT (CDECL *pSetPolyFillMode)(PHYSDEV,INT);
INT (CDECL *pSetROP2)(PHYSDEV,INT);
INT (CDECL *pSetRelAbs)(PHYSDEV,INT);
INT (CDECL *pSetStretchBltMode)(PHYSDEV,INT);
UINT (CDECL *pSetTextAlign)(PHYSDEV,UINT);
INT (CDECL *pSetTextCharacterExtra)(PHYSDEV,INT);
DWORD (CDECL *pSetTextColor)(PHYSDEV,DWORD);
INT (CDECL *pSetTextJustification)(PHYSDEV,INT,INT);
INT (CDECL *pSetViewportExt)(PHYSDEV,INT,INT);
INT (CDECL *pSetViewportOrg)(PHYSDEV,INT,INT);
INT (CDECL *pSetWindowExt)(PHYSDEV,INT,INT);
INT (CDECL *pSetWindowOrg)(PHYSDEV,INT,INT);
BOOL (CDECL *pSetWorldTransform)(PHYSDEV,const XFORM*);
INT (CDECL *pStartDoc)(PHYSDEV,const DOCINFOW*);
INT (CDECL *pStartPage)(PHYSDEV);
BOOL (CDECL *pStretchBlt)(PHYSDEV,INT,INT,INT,INT,PHYSDEV,INT,INT,INT,INT,DWORD);
INT (CDECL *pStretchDIBits)(PHYSDEV,INT,INT,INT,INT,INT,INT,INT,INT,const void *,
const BITMAPINFO*,UINT,DWORD);
BOOL (CDECL *pStrokeAndFillPath)(PHYSDEV);
BOOL (CDECL *pStrokePath)(PHYSDEV);
BOOL (CDECL *pSwapBuffers)(PHYSDEV);
BOOL (CDECL *pUnrealizePalette)(HPALETTE);
BOOL (CDECL *pWidenPath)(PHYSDEV);
/* OpenGL32 */
BOOL (CDECL *pwglCopyContext)(HGLRC, HGLRC, UINT);
HGLRC (CDECL *pwglCreateContext)(PHYSDEV);
HGLRC (CDECL *pwglCreateContextAttribsARB)(PHYSDEV, HGLRC, const int*);
BOOL (CDECL *pwglDeleteContext)(HGLRC);
PROC (CDECL *pwglGetProcAddress)(LPCSTR);
HDC (CDECL *pwglGetPbufferDCARB)(PHYSDEV, void*);
BOOL (CDECL *pwglMakeCurrent)(PHYSDEV, HGLRC);
BOOL (CDECL *pwglMakeContextCurrentARB)(PHYSDEV, PHYSDEV, HGLRC);
BOOL (CDECL *pwglSetPixelFormatWINE)(PHYSDEV,INT,const PIXELFORMATDESCRIPTOR *);
BOOL (CDECL *pwglShareLists)(HGLRC hglrc1, HGLRC hglrc2);
BOOL (CDECL *pwglUseFontBitmapsA)(PHYSDEV, DWORD, DWORD, DWORD);
BOOL (CDECL *pwglUseFontBitmapsW)(PHYSDEV, DWORD, DWORD, DWORD);
} DC_FUNCTIONS;
/* It should not be necessary to access the contents of the GdiPath
* structure directly; if you find that the exported functions don't
* allow you to do what you want, then please place a new exported
* function that does this job in path.c.
*/
typedef enum tagGdiPathState
{
PATH_Null,
PATH_Open,
PATH_Closed
} GdiPathState;
typedef struct tagGdiPath
{
GdiPathState state;
POINT *pPoints;
BYTE *pFlags;
int numEntriesUsed, numEntriesAllocated;
BOOL newStroke;
} GdiPath;
typedef struct tagGdiFont GdiFont;
typedef struct tagDC
{
GDIOBJHDR header;
HDC hSelf; /* Handle to this DC */
const struct tagDC_FUNCS *funcs; /* DC function table */
PHYSDEV physDev; /* Physical device (driver-specific) */
DWORD thread; /* thread owning the DC */
LONG refcount; /* thread refcount */
LONG dirty; /* dirty flag */
INT saveLevel;
HDC saved_dc;
DWORD_PTR dwHookData;
DCHOOKPROC hookProc; /* DC hook */
INT wndOrgX; /* Window origin */
INT wndOrgY;
INT wndExtX; /* Window extent */
INT wndExtY;
INT vportOrgX; /* Viewport origin */
INT vportOrgY;
INT vportExtX; /* Viewport extent */
INT vportExtY;
SIZE virtual_res; /* Initially HORZRES,VERTRES. Changed by SetVirtualResolution */
SIZE virtual_size; /* Initially HORZSIZE,VERTSIZE. Changed by SetVirtualResolution */
RECT vis_rect; /* visible rectangle in screen coords */
FLOAT miterLimit;
int flags;
DWORD layout;
HRGN hClipRgn; /* Clip region (may be 0) */
HRGN hMetaRgn; /* Meta region (may be 0) */
HRGN hMetaClipRgn; /* Intersection of meta and clip regions (may be 0) */
HRGN hVisRgn; /* Visible region (must never be 0) */
HPEN hPen;
HBRUSH hBrush;
HFONT hFont;
HBITMAP hBitmap;
HANDLE hDevice;
HPALETTE hPalette;
GdiFont *gdiFont;
GdiPath path;
UINT font_code_page;
WORD ROPmode;
WORD polyFillMode;
WORD stretchBltMode;
WORD relAbsMode;
WORD backgroundMode;
COLORREF backgroundColor;
COLORREF textColor;
COLORREF dcBrushColor;
COLORREF dcPenColor;
short brushOrgX;
short brushOrgY;
WORD textAlign; /* Text alignment from SetTextAlign() */
INT charExtra; /* Spacing from SetTextCharacterExtra() */
INT breakExtra; /* breakTotalExtra / breakCount */
INT breakRem; /* breakTotalExtra % breakCount */
INT MapMode;
INT GraphicsMode; /* Graphics mode */
ABORTPROC pAbortProc; /* AbortProc for Printing */
INT CursPosX; /* Current position */
INT CursPosY;
INT ArcDirection;
XFORM xformWorld2Wnd; /* World-to-window transformation */
XFORM xformWorld2Vport; /* World-to-viewport transformation */
XFORM xformVport2World; /* Inverse of the above transformation */
BOOL vport2WorldValid; /* Is xformVport2World valid? */
RECT BoundsRect; /* Current bounding rect */
} DC;
/* DC flags */
#define DC_SAVED 0x0002 /* It is a saved DC */
#define DC_BOUNDS_ENABLE 0x0008 /* Bounding rectangle tracking is enabled */
#define DC_BOUNDS_SET 0x0010 /* Bounding rectangle has been set */
/* Certain functions will do no further processing if the driver returns this.
Used by mfdrv for example. */
#define GDI_NO_MORE_WORK 2
/* Rounds a floating point number to integer. The world-to-viewport
* transformation process is done in floating point internally. This function
* is then used to round these coordinates to integer values.
*/
static inline INT GDI_ROUND(double val)
{
return (int)floor(val + 0.5);
}
/* bitmap object */
typedef struct tagBITMAPOBJ
{
GDIOBJHDR header;
BITMAP bitmap;
SIZE size; /* For SetBitmapDimension() */
const DC_FUNCTIONS *funcs; /* DC function table */
/* For device-independent bitmaps: */
DIBSECTION *dib;
RGBQUAD *color_table; /* DIB color table if <= 8bpp */
UINT nb_colors; /* number of colors in table */
} BITMAPOBJ;
/* bidi.c */
/* Wine_GCPW Flags */
/* Directionality -
* LOOSE means taking the directionality of the first strong character, if there is found one.
* FORCE means the paragraph direction is forced. (RLE/LRE)
*/
#define WINE_GCPW_FORCE_LTR 0
#define WINE_GCPW_FORCE_RTL 1
#define WINE_GCPW_LOOSE_LTR 2
#define WINE_GCPW_LOOSE_RTL 3
#define WINE_GCPW_DIR_MASK 3
#define WINE_GCPW_LOOSE_MASK 2
extern BOOL BIDI_Reorder( HDC hDC, LPCWSTR lpString, INT uCount, DWORD dwFlags, DWORD dwWineGCP_Flags,
LPWSTR lpOutString, INT uCountOut, UINT *lpOrder, WORD **lpGlyphs, INT* cGlyphs ) DECLSPEC_HIDDEN;
/* bitmap.c */
extern HBITMAP BITMAP_CopyBitmap( HBITMAP hbitmap ) DECLSPEC_HIDDEN;
extern BOOL BITMAP_SetOwnerDC( HBITMAP hbitmap, DC *dc ) DECLSPEC_HIDDEN;
extern INT BITMAP_GetWidthBytes( INT bmWidth, INT bpp ) DECLSPEC_HIDDEN;
/* clipping.c */
extern void CLIPPING_UpdateGCRegion( DC * dc ) DECLSPEC_HIDDEN;
/* dc.c */
extern DC *alloc_dc_ptr( const DC_FUNCTIONS *funcs, WORD magic ) DECLSPEC_HIDDEN;
extern BOOL free_dc_ptr( DC *dc ) DECLSPEC_HIDDEN;
extern DC *get_dc_ptr( HDC hdc ) DECLSPEC_HIDDEN;
extern void release_dc_ptr( DC *dc ) DECLSPEC_HIDDEN;
extern void update_dc( DC *dc ) DECLSPEC_HIDDEN;
extern void DC_InitDC( DC * dc ) DECLSPEC_HIDDEN;
extern void DC_UpdateXforms( DC * dc ) DECLSPEC_HIDDEN;
extern INT save_dc_state( HDC hdc ) DECLSPEC_HIDDEN;
extern BOOL restore_dc_state( HDC hdc, INT level ) DECLSPEC_HIDDEN;
/* dib.c */
extern int DIB_GetDIBWidthBytes( int width, int depth ) DECLSPEC_HIDDEN;
extern int DIB_GetDIBImageBytes( int width, int height, int depth ) DECLSPEC_HIDDEN;
extern int bitmap_info_size( const BITMAPINFO * info, WORD coloruse ) DECLSPEC_HIDDEN;
extern int DIB_GetBitmapInfo( const BITMAPINFOHEADER *header, LONG *width,
LONG *height, WORD *planes, WORD *bpp, DWORD *compr, DWORD *size ) DECLSPEC_HIDDEN;
/* driver.c */
extern const DC_FUNCTIONS *DRIVER_get_display_driver(void) DECLSPEC_HIDDEN;
extern const DC_FUNCTIONS *DRIVER_load_driver( LPCWSTR name ) DECLSPEC_HIDDEN;
extern BOOL DRIVER_GetDriverName( LPCWSTR device, LPWSTR driver, DWORD size ) DECLSPEC_HIDDEN;
/* enhmetafile.c */
extern HENHMETAFILE EMF_Create_HENHMETAFILE(ENHMETAHEADER *emh, BOOL on_disk ) DECLSPEC_HIDDEN;
/* freetype.c */
/* Undocumented structure filled in by GdiRealizationInfo */
typedef struct
{
DWORD flags; /* 1 for bitmap fonts, 3 for scalable fonts */
DWORD cache_num; /* keeps incrementing - num of fonts that have been created allowing for caching?? */
DWORD unknown2; /* fixed for a given font - looks like it could be the order of the face in the font list or the order
in which the face was first rendered. */
} realization_info_t;
extern INT WineEngAddFontResourceEx(LPCWSTR, DWORD, PVOID) DECLSPEC_HIDDEN;
extern HANDLE WineEngAddFontMemResourceEx(PVOID, DWORD, PVOID, LPDWORD) DECLSPEC_HIDDEN;
extern GdiFont* WineEngCreateFontInstance(DC*, HFONT) DECLSPEC_HIDDEN;
extern BOOL WineEngDestroyFontInstance(HFONT handle) DECLSPEC_HIDDEN;
extern DWORD WineEngEnumFonts(LPLOGFONTW, FONTENUMPROCW, LPARAM) DECLSPEC_HIDDEN;
extern BOOL WineEngGetCharABCWidths(GdiFont *font, UINT firstChar,
UINT lastChar, LPABC buffer) DECLSPEC_HIDDEN;
extern BOOL WineEngGetCharABCWidthsFloat(GdiFont *font, UINT firstChar,
UINT lastChar, LPABCFLOAT buffer) DECLSPEC_HIDDEN;
extern BOOL WineEngGetCharABCWidthsI(GdiFont *font, UINT firstChar,
UINT count, LPWORD pgi, LPABC buffer) DECLSPEC_HIDDEN;
extern BOOL WineEngGetCharWidth(GdiFont*, UINT, UINT, LPINT) DECLSPEC_HIDDEN;
extern DWORD WineEngGetFontData(GdiFont*, DWORD, DWORD, LPVOID, DWORD) DECLSPEC_HIDDEN;
extern DWORD WineEngGetFontUnicodeRanges(GdiFont *, LPGLYPHSET) DECLSPEC_HIDDEN;
extern DWORD WineEngGetGlyphIndices(GdiFont *font, LPCWSTR lpstr, INT count,
LPWORD pgi, DWORD flags) DECLSPEC_HIDDEN;
extern DWORD WineEngGetGlyphOutline(GdiFont*, UINT glyph, UINT format,
LPGLYPHMETRICS, DWORD buflen, LPVOID buf,
const MAT2*) DECLSPEC_HIDDEN;
extern DWORD WineEngGetKerningPairs(GdiFont*, DWORD, KERNINGPAIR *) DECLSPEC_HIDDEN;
extern BOOL WineEngGetLinkedHFont(DC *dc, WCHAR c, HFONT *new_hfont, UINT *glyph) DECLSPEC_HIDDEN;
extern UINT WineEngGetOutlineTextMetrics(GdiFont*, UINT, LPOUTLINETEXTMETRICW) DECLSPEC_HIDDEN;
extern UINT WineEngGetTextCharsetInfo(GdiFont *font, LPFONTSIGNATURE fs, DWORD flags) DECLSPEC_HIDDEN;
extern BOOL WineEngGetTextExtentExPoint(GdiFont*, LPCWSTR, INT, INT, LPINT, LPINT, LPSIZE) DECLSPEC_HIDDEN;
extern BOOL WineEngGetTextExtentExPointI(GdiFont*, const WORD *, INT, INT, LPINT, LPINT, LPSIZE) DECLSPEC_HIDDEN;
extern INT WineEngGetTextFace(GdiFont*, INT, LPWSTR) DECLSPEC_HIDDEN;
extern BOOL WineEngGetTextMetrics(GdiFont*, LPTEXTMETRICW) DECLSPEC_HIDDEN;
extern BOOL WineEngFontIsLinked(GdiFont*) DECLSPEC_HIDDEN;
extern BOOL WineEngInit(void) DECLSPEC_HIDDEN;
extern BOOL WineEngRealizationInfo(GdiFont*, realization_info_t*) DECLSPEC_HIDDEN;
extern BOOL WineEngRemoveFontResourceEx(LPCWSTR, DWORD, PVOID) DECLSPEC_HIDDEN;
/* gdiobj.c */
extern HGDIOBJ alloc_gdi_handle( GDIOBJHDR *obj, WORD type, const struct gdi_obj_funcs *funcs ) DECLSPEC_HIDDEN;
extern void *free_gdi_handle( HGDIOBJ handle ) DECLSPEC_HIDDEN;
extern void *GDI_GetObjPtr( HGDIOBJ, WORD ) DECLSPEC_HIDDEN;
extern void GDI_ReleaseObj( HGDIOBJ ) DECLSPEC_HIDDEN;
extern void GDI_CheckNotLock(void) DECLSPEC_HIDDEN;
extern HGDIOBJ GDI_inc_ref_count( HGDIOBJ handle ) DECLSPEC_HIDDEN;
extern BOOL GDI_dec_ref_count( HGDIOBJ handle ) DECLSPEC_HIDDEN;
extern BOOL GDI_hdc_using_object(HGDIOBJ obj, HDC hdc) DECLSPEC_HIDDEN;
extern BOOL GDI_hdc_not_using_object(HGDIOBJ obj, HDC hdc) DECLSPEC_HIDDEN;
/* metafile.c */
extern HMETAFILE MF_Create_HMETAFILE(METAHEADER *mh) DECLSPEC_HIDDEN;
extern METAHEADER *MF_CreateMetaHeaderDisk(METAHEADER *mr, LPCVOID filename, BOOL unicode ) DECLSPEC_HIDDEN;
/* path.c */
#define PATH_IsPathOpen(path) ((path).state==PATH_Open)
/* Returns TRUE if the specified path is in the open state, i.e. in the
* state where points will be added to the path, or FALSE otherwise. This
* function is implemented as a macro for performance reasons.
*/
extern void PATH_InitGdiPath(GdiPath *pPath) DECLSPEC_HIDDEN;
extern void PATH_DestroyGdiPath(GdiPath *pPath) DECLSPEC_HIDDEN;
extern BOOL PATH_AssignGdiPath(GdiPath *pPathDest, const GdiPath *pPathSrc) DECLSPEC_HIDDEN;
extern BOOL PATH_MoveTo(DC *dc) DECLSPEC_HIDDEN;
extern BOOL PATH_LineTo(DC *dc, INT x, INT y) DECLSPEC_HIDDEN;
extern BOOL PATH_Rectangle(DC *dc, INT x1, INT y1, INT x2, INT y2) DECLSPEC_HIDDEN;
extern BOOL PATH_ExtTextOut(DC *dc, INT x, INT y, UINT flags, const RECT *lprc,
LPCWSTR str, UINT count, const INT *dx) DECLSPEC_HIDDEN;
extern BOOL PATH_Ellipse(DC *dc, INT x1, INT y1, INT x2, INT y2) DECLSPEC_HIDDEN;
extern BOOL PATH_Arc(DC *dc, INT x1, INT y1, INT x2, INT y2,
INT xStart, INT yStart, INT xEnd, INT yEnd, INT lines) DECLSPEC_HIDDEN;
extern BOOL PATH_PolyBezierTo(DC *dc, const POINT *pt, DWORD cbCount) DECLSPEC_HIDDEN;
extern BOOL PATH_PolyBezier(DC *dc, const POINT *pt, DWORD cbCount) DECLSPEC_HIDDEN;
extern BOOL PATH_PolyDraw(DC *dc, const POINT *pts, const BYTE *types, DWORD cbCount) DECLSPEC_HIDDEN;
extern BOOL PATH_PolylineTo(DC *dc, const POINT *pt, DWORD cbCount) DECLSPEC_HIDDEN;
extern BOOL PATH_Polyline(DC *dc, const POINT *pt, DWORD cbCount) DECLSPEC_HIDDEN;
extern BOOL PATH_Polygon(DC *dc, const POINT *pt, DWORD cbCount) DECLSPEC_HIDDEN;
extern BOOL PATH_PolyPolyline(DC *dc, const POINT *pt, const DWORD *counts, DWORD polylines) DECLSPEC_HIDDEN;
extern BOOL PATH_PolyPolygon(DC *dc, const POINT *pt, const INT *counts, UINT polygons) DECLSPEC_HIDDEN;
extern BOOL PATH_RoundRect(DC *dc, INT x1, INT y1, INT x2, INT y2, INT ell_width, INT ell_height) DECLSPEC_HIDDEN;
/* painting.c */
extern POINT *GDI_Bezier( const POINT *Points, INT count, INT *nPtsOut ) DECLSPEC_HIDDEN;
/* palette.c */
extern HPALETTE WINAPI GDISelectPalette( HDC hdc, HPALETTE hpal, WORD wBkg);
extern UINT WINAPI GDIRealizePalette( HDC hdc );
extern HPALETTE PALETTE_Init(void) DECLSPEC_HIDDEN;
/* region.c */
extern INT mirror_region( HRGN dst, HRGN src, INT width ) DECLSPEC_HIDDEN;
extern BOOL REGION_FrameRgn( HRGN dest, HRGN src, INT x, INT y ) DECLSPEC_HIDDEN;
/* Undocumented value for DIB's iUsage: Indicates a mono DIB w/o pal entries */
#define DIB_PAL_MONO 2
BOOL WINAPI FontIsLinked(HDC);
BOOL WINAPI SetVirtualResolution(HDC hdc, DWORD horz_res, DWORD vert_res, DWORD horz_size, DWORD vert_size);
NTSYSAPI
VOID
NTAPI
RtlAssert(
PVOID FailedAssertion,
PVOID FileName,
ULONG LineNumber,
PCHAR Message
);
#ifdef assert
#undef assert
#endif
#define assert(x) if (!(x)) {RtlAssert("#x",__FILE__,__LINE__, ""); }
#endif /* __WINE_GDI_PRIVATE_H */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,291 @@
/*
* reactos/lib/gdi32/misc/historic.c
*
* GDI32.DLL Stubs
*
* Apis that do basically nothing, but are here for backwards compatibility with older Windows
*
*/
#include "config.h"
#include <stdarg.h>
#include <string.h>
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winnls.h"
#include "winreg.h"
#include "gdi_private.h"
/*
* @implemented
*/
/*BOOL
WINAPI
EngQueryEMFInfo(HDEV hdev,
EMFINFO *pEMFInfo)
{
return FALSE;
}*/
/*
* @implemented
*/
BOOL
WINAPI
GdiPlayDCScript(DWORD a0,
DWORD a1,
DWORD a2,
DWORD a3,
DWORD a4,
DWORD a5)
{
/* FIXME fix the prototype right */
return FALSE;
}
/*
* @implemented
*/
BOOL
WINAPI
GdiPlayJournal(DWORD a0,
DWORD a1,
DWORD a2,
DWORD a3,
DWORD a4)
{
/* FIXME fix the prototype right */
return FALSE;
}
/*
* @implemented
*/
BOOL
WINAPI
GdiPlayScript(DWORD a0,
DWORD a1,
DWORD a2,
DWORD a3,
DWORD a4,
DWORD a5,
DWORD a6)
{
/* FIXME fix the prototype right */
return FALSE;
}
/*
* @implemented
*/
HBITMAP
WINAPI
GdiConvertBitmap(HBITMAP hbm)
{
/* Note Windows 2000/XP/VISTA always returns hbm */
return hbm;
}
/*
* @implemented
*/
HBRUSH
WINAPI
GdiConvertBrush(HBRUSH hbr)
{
/* Note Windows 2000/XP/VISTA always returns hbr */
return hbr;
}
/*
* @implemented
*/
HDC
WINAPI
GdiConvertDC(HDC hdc)
{
/* Note Windows 2000/XP/VISTA always returns hdc */
return hdc;
}
/*
* @implemented
*/
HFONT
WINAPI
GdiConvertFont(HFONT hfont)
{
/* Note Windows 2000/XP/VISTA always returns hfont */
return hfont;
}
/*
* @implemented
*/
HPALETTE
WINAPI
GdiConvertPalette(HPALETTE hpal)
{
/* Note Windows 2000/XP/VISTA always returns hpal */
return hpal;
}
/*
* @implemented
*/
HRGN
WINAPI
GdiConvertRegion(HRGN hregion)
{
/* Note Windows 2000/XP/VISTA always returns hregion */
return hregion;
}
/*
* @implemented
*/
BOOL
WINAPI
GdiSetAttrs(HDC hdc)
{
/* Note Windows 2000/XP/VISTA always returns TRUE */
return TRUE;
}
/*
* @implemented
*/
BOOL
WINAPI
GdiDeleteLocalDC(HDC hdc)
{
/* Note Windows 2000/XP/VISTA always returns TRUE */
return TRUE;
}
/*
* @implemented
*/
VOID
WINAPI
GdiSetServerAttr(HDC hdc,DWORD attr)
{
/* it does do nothing */
}
/*
* @implemented
*/
int
WINAPI
DeviceCapabilitiesExA(LPCSTR pDevice,
LPCSTR pPort,
WORD fwCapability,
LPSTR pOutput,
CONST DEVMODEA *pDevMode)
{
/* Note Windows 2000/XP/VISTA always returns -1 */
return -1;
}
/*
* @implemented
*/
int
WINAPI
DeviceCapabilitiesExW(LPCWSTR pDevice,
LPCWSTR pPort,
WORD fwCapability,
LPWSTR pOutput,
CONST DEVMODEW *pDevMode)
{
/* Note Windows 2000/XP/VISTA always returns -1 */
return -1;
}
/*
* @implemented
*
* GDIEntry 16
*/
#if 0
DWORD
WINAPI
DdSwapTextureHandles(LPDDRAWI_DIRECTDRAW_LCL pDDraw,
LPDDRAWI_DDRAWSURFACE_LCL pDDSLcl1,
LPDDRAWI_DDRAWSURFACE_LCL pDDSLcl2)
{
/* Note Windows 2000/XP/VISTA always returns success */
return TRUE;
}
#endif
/*
* @implemented
*/
BOOL
WINAPI
GdiReleaseLocalDC(HDC hdc)
{
/* Note Windows 2000/XP/VISTA always returns TRUE */
return TRUE;
}
/*
* @implemented
*/
HBRUSH
WINAPI
SelectBrushLocal(HBRUSH Currenthbm,
HBRUSH Newhbm)
{
return Newhbm;
}
/*
* @implemented
*/
HFONT
WINAPI
SelectFontLocal(HFONT Currenthfnt,
HFONT newhfnt)
{
return newhfnt;
}
/*
* @implemented
*/
HBRUSH
WINAPI
GdiGetLocalBrush(HBRUSH hbr)
{
return hbr;
}
/*
* @implemented
*/
HDC
WINAPI
GdiGetLocalDC(HDC hdc)
{
return hdc;
}
/*
* @implemented
*/
HFONT
WINAPI
GdiGetLocalFont(HFONT hfont)
{
return hfont;
}

257
arwinss/client/gdi32/icm.c Normal file
View File

@@ -0,0 +1,257 @@
/*
* Image Color Management
*
* Copyright 2004 Marcus Meissner
* Copyright 2008 Hans Leidekker
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "config.h"
#include <stdarg.h>
#include <string.h>
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winnls.h"
#include "winreg.h"
#include "gdi_private.h"
#include "wine/debug.h"
#include "wine/unicode.h"
WINE_DEFAULT_DEBUG_CHANNEL(icm);
struct enum_profiles
{
BOOL unicode;
union
{
ICMENUMPROCA funcA;
ICMENUMPROCW funcW;
} callback;
LPARAM data;
};
INT CALLBACK enum_profiles_callback( LPWSTR filename, LPARAM lparam )
{
int len, ret = -1;
struct enum_profiles *ep = (struct enum_profiles *)lparam;
char *filenameA;
if (ep->unicode)
return ep->callback.funcW( filename, ep->data );
len = WideCharToMultiByte( CP_ACP, 0, filename, -1, NULL, 0, NULL, NULL );
filenameA = HeapAlloc( GetProcessHeap(), 0, len );
if (filenameA)
{
WideCharToMultiByte( CP_ACP, 0, filename, -1, filenameA, len, NULL, NULL );
ret = ep->callback.funcA( filenameA, ep->data );
HeapFree( GetProcessHeap(), 0, filenameA );
}
return ret;
}
/***********************************************************************
* EnumICMProfilesA (GDI32.@)
*/
INT WINAPI EnumICMProfilesA(HDC hdc, ICMENUMPROCA func, LPARAM lparam)
{
DC *dc;
INT ret = -1;
TRACE("%p, %p, 0x%08lx\n", hdc, func, lparam);
if (!func) return -1;
if ((dc = get_dc_ptr(hdc)))
{
if (dc->funcs->pEnumICMProfiles)
{
struct enum_profiles ep;
ep.unicode = FALSE;
ep.callback.funcA = func;
ep.data = lparam;
ret = dc->funcs->pEnumICMProfiles(dc->physDev, enum_profiles_callback, (LPARAM)&ep);
}
release_dc_ptr(dc);
}
return ret;
}
/***********************************************************************
* EnumICMProfilesW (GDI32.@)
*/
INT WINAPI EnumICMProfilesW(HDC hdc, ICMENUMPROCW func, LPARAM lparam)
{
DC *dc;
INT ret = -1;
TRACE("%p, %p, 0x%08lx\n", hdc, func, lparam);
if (!func) return -1;
if ((dc = get_dc_ptr(hdc)))
{
if (dc->funcs->pEnumICMProfiles)
{
struct enum_profiles ep;
ep.unicode = TRUE;
ep.callback.funcW = func;
ep.data = lparam;
ret = dc->funcs->pEnumICMProfiles(dc->physDev, enum_profiles_callback, (LPARAM)&ep);
}
release_dc_ptr(dc);
}
return ret;
}
/**********************************************************************
* GetICMProfileA (GDI32.@)
*
* Returns the filename of the specified device context's color
* management profile, even if color management is not enabled
* for that DC.
*
* RETURNS
* TRUE if filename is copied successfully.
* FALSE if the buffer length pointed to by size is too small.
*
* FIXME
* How does Windows assign these? Some registry key?
*/
BOOL WINAPI GetICMProfileA(HDC hdc, LPDWORD size, LPSTR filename)
{
WCHAR filenameW[MAX_PATH];
DWORD buflen = MAX_PATH;
BOOL ret = FALSE;
TRACE("%p, %p, %p\n", hdc, size, filename);
if (!hdc || !size || !filename) return FALSE;
if (GetICMProfileW(hdc, &buflen, filenameW))
{
int len = WideCharToMultiByte(CP_ACP, 0, filenameW, -1, NULL, 0, NULL, NULL);
if (*size >= len)
{
WideCharToMultiByte(CP_ACP, 0, filenameW, -1, filename, *size, NULL, NULL);
ret = TRUE;
}
else SetLastError(ERROR_INSUFFICIENT_BUFFER);
*size = len;
}
return ret;
}
/**********************************************************************
* GetICMProfileW (GDI32.@)
*/
BOOL WINAPI GetICMProfileW(HDC hdc, LPDWORD size, LPWSTR filename)
{
BOOL ret = FALSE;
DC *dc = get_dc_ptr(hdc);
TRACE("%p, %p, %p\n", hdc, size, filename);
if (dc)
{
if (dc->funcs->pGetICMProfile)
ret = dc->funcs->pGetICMProfile(dc->physDev, size, filename);
release_dc_ptr(dc);
}
return ret;
}
/**********************************************************************
* GetLogColorSpaceA (GDI32.@)
*/
BOOL WINAPI GetLogColorSpaceA(HCOLORSPACE colorspace, LPLOGCOLORSPACEA buffer, DWORD size)
{
FIXME("%p %p 0x%08x stub\n", colorspace, buffer, size);
return FALSE;
}
/**********************************************************************
* GetLogColorSpaceW (GDI32.@)
*/
BOOL WINAPI GetLogColorSpaceW(HCOLORSPACE colorspace, LPLOGCOLORSPACEW buffer, DWORD size)
{
FIXME("%p %p 0x%08x stub\n", colorspace, buffer, size);
return FALSE;
}
/**********************************************************************
* SetICMProfileA (GDI32.@)
*/
BOOL WINAPI SetICMProfileA(HDC hdc, LPSTR filename)
{
FIXME("%p %s stub\n", hdc, debugstr_a(filename));
if (!filename)
{
SetLastError( ERROR_INVALID_PARAMETER );
return FALSE;
}
if (!hdc)
{
SetLastError( ERROR_INVALID_HANDLE );
return FALSE;
}
return TRUE;
}
/**********************************************************************
* SetICMProfileW (GDI32.@)
*/
BOOL WINAPI SetICMProfileW(HDC hdc, LPWSTR filename)
{
FIXME("%p %s stub\n", hdc, debugstr_w(filename));
if (!filename)
{
SetLastError( ERROR_INVALID_PARAMETER );
return FALSE;
}
if (!hdc)
{
SetLastError( ERROR_INVALID_HANDLE );
return FALSE;
}
return TRUE;
}
/**********************************************************************
* UpdateICMRegKeyA (GDI32.@)
*/
BOOL WINAPI UpdateICMRegKeyA(DWORD reserved, LPSTR cmid, LPSTR filename, UINT command)
{
FIXME("0x%08x, %s, %s, 0x%08x stub\n", reserved, debugstr_a(cmid), debugstr_a(filename), command);
return TRUE;
}
/**********************************************************************
* UpdateICMRegKeyW (GDI32.@)
*/
BOOL WINAPI UpdateICMRegKeyW(DWORD reserved, LPWSTR cmid, LPWSTR filename, UINT command)
{
FIXME("0x%08x, %s, %s, 0x%08x stub\n", reserved, debugstr_w(cmid), debugstr_w(filename), command);
return TRUE;
}

View File

@@ -0,0 +1,537 @@
/*
* GDI mapping mode functions
*
* Copyright 1993 Alexandre Julliard
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <stdarg.h>
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "gdi_private.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(dc);
/***********************************************************************
* MAPPING_FixIsotropic
*
* Fix viewport extensions for isotropic mode.
*/
static void MAPPING_FixIsotropic( DC * dc )
{
double xdim = fabs((double)dc->vportExtX * dc->virtual_size.cx /
(dc->virtual_res.cx * dc->wndExtX));
double ydim = fabs((double)dc->vportExtY * dc->virtual_size.cy /
(dc->virtual_res.cy * dc->wndExtY));
if (xdim > ydim)
{
INT mincx = (dc->vportExtX >= 0) ? 1 : -1;
dc->vportExtX = floor(dc->vportExtX * ydim / xdim + 0.5);
if (!dc->vportExtX) dc->vportExtX = mincx;
}
else
{
INT mincy = (dc->vportExtY >= 0) ? 1 : -1;
dc->vportExtY = floor(dc->vportExtY * xdim / ydim + 0.5);
if (!dc->vportExtY) dc->vportExtY = mincy;
}
}
/***********************************************************************
* DPtoLP (GDI32.@)
*/
BOOL WINAPI DPtoLP( HDC hdc, LPPOINT points, INT count )
{
DC * dc = get_dc_ptr( hdc );
if (!dc) return FALSE;
if (dc->vport2WorldValid)
{
while (count--)
{
double x = points->x;
double y = points->y;
points->x = floor( x * dc->xformVport2World.eM11 +
y * dc->xformVport2World.eM21 +
dc->xformVport2World.eDx + 0.5 );
points->y = floor( x * dc->xformVport2World.eM12 +
y * dc->xformVport2World.eM22 +
dc->xformVport2World.eDy + 0.5 );
points++;
}
}
release_dc_ptr( dc );
return (count < 0);
}
/***********************************************************************
* LPtoDP (GDI32.@)
*/
BOOL WINAPI LPtoDP( HDC hdc, LPPOINT points, INT count )
{
DC * dc = get_dc_ptr( hdc );
if (!dc) return FALSE;
while (count--)
{
double x = points->x;
double y = points->y;
points->x = floor( x * dc->xformWorld2Vport.eM11 +
y * dc->xformWorld2Vport.eM21 +
dc->xformWorld2Vport.eDx + 0.5 );
points->y = floor( x * dc->xformWorld2Vport.eM12 +
y * dc->xformWorld2Vport.eM22 +
dc->xformWorld2Vport.eDy + 0.5 );
points++;
}
release_dc_ptr( dc );
return TRUE;
}
/***********************************************************************
* SetMapMode (GDI32.@)
*/
INT WINAPI SetMapMode( HDC hdc, INT mode )
{
INT ret;
INT horzSize, vertSize, horzRes, vertRes;
DC * dc = get_dc_ptr( hdc );
if (!dc) return 0;
if (dc->funcs->pSetMapMode)
{
if((ret = dc->funcs->pSetMapMode( dc->physDev, mode )) != TRUE)
{
if(ret == GDI_NO_MORE_WORK)
ret = TRUE;
goto done;
}
}
TRACE("%p %d\n", hdc, mode );
ret = dc->MapMode;
if (mode == dc->MapMode && (mode == MM_ISOTROPIC || mode == MM_ANISOTROPIC))
goto done;
horzSize = dc->virtual_size.cx;
vertSize = dc->virtual_size.cy;
horzRes = dc->virtual_res.cx;
vertRes = dc->virtual_res.cy;
switch(mode)
{
case MM_TEXT:
dc->wndExtX = 1;
dc->wndExtY = 1;
dc->vportExtX = 1;
dc->vportExtY = 1;
break;
case MM_LOMETRIC:
case MM_ISOTROPIC:
dc->wndExtX = horzSize * 10;
dc->wndExtY = vertSize * 10;
dc->vportExtX = horzRes;
dc->vportExtY = -vertRes;
break;
case MM_HIMETRIC:
dc->wndExtX = horzSize * 100;
dc->wndExtY = vertSize * 100;
dc->vportExtX = horzRes;
dc->vportExtY = -vertRes;
break;
case MM_LOENGLISH:
dc->wndExtX = MulDiv(1000, horzSize, 254);
dc->wndExtY = MulDiv(1000, vertSize, 254);
dc->vportExtX = horzRes;
dc->vportExtY = -vertRes;
break;
case MM_HIENGLISH:
dc->wndExtX = MulDiv(10000, horzSize, 254);
dc->wndExtY = MulDiv(10000, vertSize, 254);
dc->vportExtX = horzRes;
dc->vportExtY = -vertRes;
break;
case MM_TWIPS:
dc->wndExtX = MulDiv(14400, horzSize, 254);
dc->wndExtY = MulDiv(14400, vertSize, 254);
dc->vportExtX = horzRes;
dc->vportExtY = -vertRes;
break;
case MM_ANISOTROPIC:
break;
default:
goto done;
}
/* RTL layout is always MM_ANISOTROPIC */
if (!(dc->layout & LAYOUT_RTL)) dc->MapMode = mode;
DC_UpdateXforms( dc );
done:
release_dc_ptr( dc );
return ret;
}
/***********************************************************************
* SetViewportExtEx (GDI32.@)
*/
BOOL WINAPI SetViewportExtEx( HDC hdc, INT x, INT y, LPSIZE size )
{
INT ret = TRUE;
DC * dc = get_dc_ptr( hdc );
if (!dc) return FALSE;
if (dc->funcs->pSetViewportExt)
{
if((ret = dc->funcs->pSetViewportExt( dc->physDev, x, y )) != TRUE)
{
if(ret == GDI_NO_MORE_WORK)
ret = TRUE;
goto done;
}
}
if (size)
{
size->cx = dc->vportExtX;
size->cy = dc->vportExtY;
}
if ((dc->MapMode != MM_ISOTROPIC) && (dc->MapMode != MM_ANISOTROPIC))
goto done;
if (!x || !y)
{
ret = FALSE;
goto done;
}
dc->vportExtX = x;
dc->vportExtY = y;
if (dc->MapMode == MM_ISOTROPIC) MAPPING_FixIsotropic( dc );
DC_UpdateXforms( dc );
done:
release_dc_ptr( dc );
return ret;
}
/***********************************************************************
* SetViewportOrgEx (GDI32.@)
*/
BOOL WINAPI SetViewportOrgEx( HDC hdc, INT x, INT y, LPPOINT pt )
{
INT ret = TRUE;
DC * dc = get_dc_ptr( hdc );
if (!dc) return FALSE;
if (dc->funcs->pSetViewportOrg)
{
if((ret = dc->funcs->pSetViewportOrg( dc->physDev, x, y )) != TRUE)
{
if(ret == GDI_NO_MORE_WORK)
ret = TRUE;
goto done;
}
}
if (pt)
{
pt->x = dc->vportOrgX;
pt->y = dc->vportOrgY;
}
dc->vportOrgX = x;
dc->vportOrgY = y;
DC_UpdateXforms( dc );
done:
release_dc_ptr( dc );
return ret;
}
/***********************************************************************
* SetWindowExtEx (GDI32.@)
*/
BOOL WINAPI SetWindowExtEx( HDC hdc, INT x, INT y, LPSIZE size )
{
INT ret = TRUE;
DC * dc = get_dc_ptr( hdc );
if (!dc) return FALSE;
if (dc->funcs->pSetWindowExt)
{
if((ret = dc->funcs->pSetWindowExt( dc->physDev, x, y )) != TRUE)
{
if(ret == GDI_NO_MORE_WORK)
ret = TRUE;
goto done;
}
}
if (size)
{
size->cx = dc->wndExtX;
size->cy = dc->wndExtY;
}
if ((dc->MapMode != MM_ISOTROPIC) && (dc->MapMode != MM_ANISOTROPIC))
goto done;
if (!x || !y)
{
ret = FALSE;
goto done;
}
dc->wndExtX = x;
dc->wndExtY = y;
/* The API docs say that you should call SetWindowExtEx before
SetViewportExtEx. This advice does not imply that Windows
doesn't ensure the isotropic mapping after SetWindowExtEx! */
if (dc->MapMode == MM_ISOTROPIC) MAPPING_FixIsotropic( dc );
DC_UpdateXforms( dc );
done:
release_dc_ptr( dc );
return ret;
}
/***********************************************************************
* SetWindowOrgEx (GDI32.@)
*/
BOOL WINAPI SetWindowOrgEx( HDC hdc, INT x, INT y, LPPOINT pt )
{
INT ret = TRUE;
DC * dc = get_dc_ptr( hdc );
if (!dc) return FALSE;
if (dc->funcs->pSetWindowOrg)
{
if((ret = dc->funcs->pSetWindowOrg( dc->physDev, x, y )) != TRUE)
{
if(ret == GDI_NO_MORE_WORK)
ret = TRUE;
goto done;
}
}
if (pt)
{
pt->x = dc->wndOrgX;
pt->y = dc->wndOrgY;
}
dc->wndOrgX = x;
dc->wndOrgY = y;
DC_UpdateXforms( dc );
done:
release_dc_ptr( dc );
return ret;
}
/***********************************************************************
* OffsetViewportOrgEx (GDI32.@)
*/
BOOL WINAPI OffsetViewportOrgEx( HDC hdc, INT x, INT y, LPPOINT pt)
{
INT ret = TRUE;
DC * dc = get_dc_ptr( hdc );
if (!dc) return FALSE;
if (dc->funcs->pOffsetViewportOrg)
{
if((ret = dc->funcs->pOffsetViewportOrg( dc->physDev, x, y )) != TRUE)
{
if(ret == GDI_NO_MORE_WORK)
ret = TRUE;
goto done;
}
}
if (pt)
{
pt->x = dc->vportOrgX;
pt->y = dc->vportOrgY;
}
dc->vportOrgX += x;
dc->vportOrgY += y;
DC_UpdateXforms( dc );
done:
release_dc_ptr( dc );
return ret;
}
/***********************************************************************
* OffsetWindowOrgEx (GDI32.@)
*/
BOOL WINAPI OffsetWindowOrgEx( HDC hdc, INT x, INT y, LPPOINT pt )
{
INT ret = TRUE;
DC * dc = get_dc_ptr( hdc );
if (!dc) return FALSE;
if (dc->funcs->pOffsetWindowOrg)
{
if((ret = dc->funcs->pOffsetWindowOrg( dc->physDev, x, y )) != TRUE)
{
if(ret == GDI_NO_MORE_WORK)
ret = TRUE;
goto done;
}
}
if (pt)
{
pt->x = dc->wndOrgX;
pt->y = dc->wndOrgY;
}
dc->wndOrgX += x;
dc->wndOrgY += y;
DC_UpdateXforms( dc );
done:
release_dc_ptr( dc );
return ret;
}
/***********************************************************************
* ScaleViewportExtEx (GDI32.@)
*/
BOOL WINAPI ScaleViewportExtEx( HDC hdc, INT xNum, INT xDenom,
INT yNum, INT yDenom, LPSIZE size )
{
INT ret = TRUE;
DC * dc = get_dc_ptr( hdc );
if (!dc) return FALSE;
if (dc->funcs->pScaleViewportExt)
{
if((ret = dc->funcs->pScaleViewportExt( dc->physDev, xNum, xDenom, yNum, yDenom )) != TRUE)
{
if(ret == GDI_NO_MORE_WORK)
ret = TRUE;
goto done;
}
}
if (size)
{
size->cx = dc->vportExtX;
size->cy = dc->vportExtY;
}
if ((dc->MapMode != MM_ISOTROPIC) && (dc->MapMode != MM_ANISOTROPIC))
goto done;
if (!xNum || !xDenom || !yNum || !yDenom)
{
ret = FALSE;
goto done;
}
dc->vportExtX = (dc->vportExtX * xNum) / xDenom;
dc->vportExtY = (dc->vportExtY * yNum) / yDenom;
if (dc->vportExtX == 0) dc->vportExtX = 1;
if (dc->vportExtY == 0) dc->vportExtY = 1;
if (dc->MapMode == MM_ISOTROPIC) MAPPING_FixIsotropic( dc );
DC_UpdateXforms( dc );
done:
release_dc_ptr( dc );
return ret;
}
/***********************************************************************
* ScaleWindowExtEx (GDI32.@)
*/
BOOL WINAPI ScaleWindowExtEx( HDC hdc, INT xNum, INT xDenom,
INT yNum, INT yDenom, LPSIZE size )
{
INT ret = TRUE;
DC * dc = get_dc_ptr( hdc );
if (!dc) return FALSE;
if (dc->funcs->pScaleWindowExt)
{
if((ret = dc->funcs->pScaleWindowExt( dc->physDev, xNum, xDenom, yNum, yDenom )) != TRUE)
{
if(ret == GDI_NO_MORE_WORK)
ret = TRUE;
goto done;
}
}
if (size)
{
size->cx = dc->wndExtX;
size->cy = dc->wndExtY;
}
if ((dc->MapMode != MM_ISOTROPIC) && (dc->MapMode != MM_ANISOTROPIC))
goto done;
if (!xNum || !xDenom || !xNum || !yDenom)
{
ret = FALSE;
goto done;
}
dc->wndExtX = (dc->wndExtX * xNum) / xDenom;
dc->wndExtY = (dc->wndExtY * yNum) / yDenom;
if (dc->wndExtX == 0) dc->wndExtX = 1;
if (dc->wndExtY == 0) dc->wndExtY = 1;
if (dc->MapMode == MM_ISOTROPIC) MAPPING_FixIsotropic( dc );
DC_UpdateXforms( dc );
done:
release_dc_ptr( dc );
return ret;
}
/***********************************************************************
* SetVirtualResolution (GDI32.@)
*
* Undocumented on msdn.
*
* Changes the values of screen size in pixels and millimeters used by
* the mapping mode functions.
*
* PARAMS
* hdc [I] Device context
* horz_res [I] Width in pixels (equivalent to HORZRES device cap).
* vert_res [I] Height in pixels (equivalent to VERTRES device cap).
* horz_size [I] Width in mm (equivalent to HORZSIZE device cap).
* vert_size [I] Height in mm (equivalent to VERTSIZE device cap).
*
* RETURNS
* TRUE if successful.
* FALSE if any (but not all) of the last four params are zero.
*
* NOTES
* This doesn't change the values returned by GetDeviceCaps, just the
* scaling of the mapping modes.
*
* Calling with the last four params equal to zero sets the values
* back to their defaults obtained by calls to GetDeviceCaps.
*/
BOOL WINAPI SetVirtualResolution(HDC hdc, DWORD horz_res, DWORD vert_res,
DWORD horz_size, DWORD vert_size)
{
DC * dc;
TRACE("(%p %d %d %d %d)\n", hdc, horz_res, vert_res, horz_size, vert_size);
if(horz_res == 0 && vert_res == 0 && horz_size == 0 && vert_size == 0)
{
horz_res = GetDeviceCaps(hdc, HORZRES);
vert_res = GetDeviceCaps(hdc, VERTRES);
horz_size = GetDeviceCaps(hdc, HORZSIZE);
vert_size = GetDeviceCaps(hdc, VERTSIZE);
}
else if(horz_res == 0 || vert_res == 0 || horz_size == 0 || vert_size == 0)
return FALSE;
dc = get_dc_ptr( hdc );
if (!dc) return FALSE;
dc->virtual_res.cx = horz_res;
dc->virtual_res.cy = vert_res;
dc->virtual_size.cx = horz_size;
dc->virtual_size.cy = vert_size;
release_dc_ptr( dc );
return TRUE;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,207 @@
/*
* GDI bit-blit operations
*
* Copyright 1993, 1994 Alexandre Julliard
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <string.h>
#include "mfdrv/metafiledrv.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(metafile);
/***********************************************************************
* MFDRV_PatBlt
*/
BOOL CDECL MFDRV_PatBlt( PHYSDEV dev, INT left, INT top, INT width, INT height, DWORD rop )
{
MFDRV_MetaParam6( dev, META_PATBLT, left, top, width, height, HIWORD(rop), LOWORD(rop) );
return TRUE;
}
/***********************************************************************
* MFDRV_StretchBlt
* this function contains TWO ways for processing StretchBlt in metafiles,
* decide between rdFunction values META_STRETCHBLT or META_DIBSTRETCHBLT
* via #define STRETCH_VIA_DIB
*/
#define STRETCH_VIA_DIB
BOOL CDECL MFDRV_StretchBlt( PHYSDEV devDst, INT xDst, INT yDst, INT widthDst,
INT heightDst, PHYSDEV devSrc, INT xSrc, INT ySrc,
INT widthSrc, INT heightSrc, DWORD rop )
{
BOOL ret;
DWORD len;
METARECORD *mr;
BITMAP BM;
METAFILEDRV_PDEVICE *physDevSrc = (METAFILEDRV_PDEVICE *)devSrc;
#ifdef STRETCH_VIA_DIB
LPBITMAPINFOHEADER lpBMI;
WORD nBPP;
#endif
HBITMAP hBitmap = GetCurrentObject(physDevSrc->hdc, OBJ_BITMAP);
if (GetObjectW(hBitmap, sizeof(BITMAP), &BM) != sizeof(BITMAP))
{
WARN("bad bitmap object %p passed for hdc %p\n", hBitmap, physDevSrc->hdc);
return FALSE;
}
#ifdef STRETCH_VIA_DIB
nBPP = BM.bmPlanes * BM.bmBitsPixel;
if(nBPP > 8) nBPP = 24; /* FIXME Can't get 16bpp to work for some reason */
len = sizeof(METARECORD) + 10 * sizeof(INT16)
+ sizeof(BITMAPINFOHEADER) + (nBPP <= 8 ? 1 << nBPP: 0) * sizeof(RGBQUAD)
+ DIB_GetDIBWidthBytes(BM.bmWidth, nBPP) * BM.bmHeight;
if (!(mr = HeapAlloc( GetProcessHeap(), 0, len)))
return FALSE;
mr->rdFunction = META_DIBSTRETCHBLT;
lpBMI=(LPBITMAPINFOHEADER)(mr->rdParm+10);
lpBMI->biSize = sizeof(BITMAPINFOHEADER);
lpBMI->biWidth = BM.bmWidth;
lpBMI->biHeight = BM.bmHeight;
lpBMI->biPlanes = 1;
lpBMI->biBitCount = nBPP;
lpBMI->biSizeImage = DIB_GetDIBWidthBytes(BM.bmWidth, nBPP) * lpBMI->biHeight;
lpBMI->biClrUsed = nBPP <= 8 ? 1 << nBPP : 0;
lpBMI->biCompression = BI_RGB;
lpBMI->biXPelsPerMeter = MulDiv(GetDeviceCaps(physDevSrc->hdc,LOGPIXELSX),3937,100);
lpBMI->biYPelsPerMeter = MulDiv(GetDeviceCaps(physDevSrc->hdc,LOGPIXELSY),3937,100);
lpBMI->biClrImportant = 0; /* 1 meter = 39.37 inch */
TRACE("MF_StretchBltViaDIB->len = %d rop=%x PixYPM=%d Caps=%d\n",
len,rop,lpBMI->biYPelsPerMeter,GetDeviceCaps(physDevSrc->hdc, LOGPIXELSY));
if (GetDIBits(physDevSrc->hdc, hBitmap, 0, (UINT)lpBMI->biHeight,
(LPSTR)lpBMI + bitmap_info_size( (BITMAPINFO *)lpBMI,
DIB_RGB_COLORS ),
(LPBITMAPINFO)lpBMI, DIB_RGB_COLORS))
#else
len = sizeof(METARECORD) + 15 * sizeof(INT16) + BM.bmWidthBytes * BM.bmHeight;
if (!(mr = HeapAlloc( GetProcessHeap(), 0, len )))
return FALSE;
mr->rdFunction = META_STRETCHBLT;
*(mr->rdParm +10) = BM.bmWidth;
*(mr->rdParm +11) = BM.bmHeight;
*(mr->rdParm +12) = BM.bmWidthBytes;
*(mr->rdParm +13) = BM.bmPlanes;
*(mr->rdParm +14) = BM.bmBitsPixel;
TRACE("len = %ld rop=%lx\n", len, rop);
if (GetBitmapBits( hBitmap, BM.bmWidthBytes * BM.bmHeight, mr->rdParm + 15))
#endif
{
mr->rdSize = len / sizeof(INT16);
*(mr->rdParm) = LOWORD(rop);
*(mr->rdParm + 1) = HIWORD(rop);
*(mr->rdParm + 2) = heightSrc;
*(mr->rdParm + 3) = widthSrc;
*(mr->rdParm + 4) = ySrc;
*(mr->rdParm + 5) = xSrc;
*(mr->rdParm + 6) = heightDst;
*(mr->rdParm + 7) = widthDst;
*(mr->rdParm + 8) = yDst;
*(mr->rdParm + 9) = xDst;
ret = MFDRV_WriteRecord( devDst, mr, mr->rdSize * 2);
}
else
ret = FALSE;
HeapFree( GetProcessHeap(), 0, mr);
return ret;
}
/***********************************************************************
* MFDRV_StretchDIBits
*/
INT CDECL MFDRV_StretchDIBits( PHYSDEV dev, INT xDst, INT yDst, INT widthDst,
INT heightDst, INT xSrc, INT ySrc, INT widthSrc,
INT heightSrc, const void *bits,
const BITMAPINFO *info, UINT wUsage, DWORD dwRop )
{
DWORD len, infosize, imagesize;
METARECORD *mr;
infosize = bitmap_info_size(info, wUsage);
imagesize = DIB_GetDIBImageBytes( info->bmiHeader.biWidth,
info->bmiHeader.biHeight,
info->bmiHeader.biBitCount );
len = sizeof(METARECORD) + 10 * sizeof(WORD) + infosize + imagesize;
mr = HeapAlloc( GetProcessHeap(), 0, len );
if(!mr) return 0;
mr->rdSize = len / 2;
mr->rdFunction = META_STRETCHDIB;
mr->rdParm[0] = LOWORD(dwRop);
mr->rdParm[1] = HIWORD(dwRop);
mr->rdParm[2] = wUsage;
mr->rdParm[3] = (INT16)heightSrc;
mr->rdParm[4] = (INT16)widthSrc;
mr->rdParm[5] = (INT16)ySrc;
mr->rdParm[6] = (INT16)xSrc;
mr->rdParm[7] = (INT16)heightDst;
mr->rdParm[8] = (INT16)widthDst;
mr->rdParm[9] = (INT16)yDst;
mr->rdParm[10] = (INT16)xDst;
memcpy(mr->rdParm + 11, info, infosize);
memcpy(mr->rdParm + 11 + infosize / 2, bits, imagesize);
MFDRV_WriteRecord( dev, mr, mr->rdSize * 2 );
HeapFree( GetProcessHeap(), 0, mr );
return heightSrc;
}
/***********************************************************************
* MFDRV_SetDIBitsToDeivce
*/
INT CDECL MFDRV_SetDIBitsToDevice( PHYSDEV dev, INT xDst, INT yDst, DWORD cx,
DWORD cy, INT xSrc, INT ySrc, UINT startscan,
UINT lines, LPCVOID bits, const BITMAPINFO *info,
UINT coloruse )
{
DWORD len, infosize, imagesize;
METARECORD *mr;
infosize = bitmap_info_size(info, coloruse);
imagesize = DIB_GetDIBImageBytes( info->bmiHeader.biWidth,
info->bmiHeader.biHeight,
info->bmiHeader.biBitCount );
len = sizeof(METARECORD) + 8 * sizeof(WORD) + infosize + imagesize;
mr = HeapAlloc( GetProcessHeap(), 0, len );
if(!mr) return 0;
mr->rdSize = len / 2;
mr->rdFunction = META_SETDIBTODEV;
mr->rdParm[0] = coloruse;
mr->rdParm[1] = lines;
mr->rdParm[2] = startscan;
mr->rdParm[3] = (INT16)ySrc;
mr->rdParm[4] = (INT16)xSrc;
mr->rdParm[5] = (INT16)cy;
mr->rdParm[6] = (INT16)cx;
mr->rdParm[7] = (INT16)yDst;
mr->rdParm[8] = (INT16)xDst;
memcpy(mr->rdParm + 9, info, infosize);
memcpy(mr->rdParm + 9 + infosize / 2, bits, imagesize);
MFDRV_WriteRecord( dev, mr, mr->rdSize * 2 );
HeapFree( GetProcessHeap(), 0, mr );
return lines;
}

View File

@@ -0,0 +1,146 @@
/*
* MetaFile driver DC value functions
*
* Copyright 1999 Huw D M Davies
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "mfdrv/metafiledrv.h"
INT CDECL MFDRV_SaveDC( PHYSDEV dev )
{
return MFDRV_MetaParam0( dev, META_SAVEDC );
}
BOOL CDECL MFDRV_RestoreDC( PHYSDEV dev, INT level )
{
return MFDRV_MetaParam1( dev, META_RESTOREDC, level );
}
UINT CDECL MFDRV_SetTextAlign( PHYSDEV dev, UINT align )
{
return MFDRV_MetaParam2( dev, META_SETTEXTALIGN, HIWORD(align), LOWORD(align));
}
INT CDECL MFDRV_SetBkMode( PHYSDEV dev, INT mode )
{
return MFDRV_MetaParam1( dev, META_SETBKMODE, (WORD)mode);
}
INT CDECL MFDRV_SetROP2( PHYSDEV dev, INT rop )
{
return MFDRV_MetaParam1( dev, META_SETROP2, (WORD)rop);
}
INT CDECL MFDRV_SetRelAbs( PHYSDEV dev, INT mode )
{
return MFDRV_MetaParam1( dev, META_SETRELABS, (WORD)mode);
}
INT CDECL MFDRV_SetPolyFillMode( PHYSDEV dev, INT mode )
{
return MFDRV_MetaParam1( dev, META_SETPOLYFILLMODE, (WORD)mode);
}
INT CDECL MFDRV_SetStretchBltMode( PHYSDEV dev, INT mode )
{
return MFDRV_MetaParam1( dev, META_SETSTRETCHBLTMODE, (WORD)mode);
}
INT CDECL MFDRV_IntersectClipRect( PHYSDEV dev, INT left, INT top, INT right, INT bottom )
{
return MFDRV_MetaParam4( dev, META_INTERSECTCLIPRECT, left, top, right,
bottom );
}
INT CDECL MFDRV_ExcludeClipRect( PHYSDEV dev, INT left, INT top, INT right, INT bottom )
{
return MFDRV_MetaParam4( dev, META_EXCLUDECLIPRECT, left, top, right,
bottom );
}
INT CDECL MFDRV_OffsetClipRgn( PHYSDEV dev, INT x, INT y )
{
return MFDRV_MetaParam2( dev, META_OFFSETCLIPRGN, x, y );
}
INT CDECL MFDRV_SetTextJustification( PHYSDEV dev, INT extra, INT breaks )
{
return MFDRV_MetaParam2( dev, META_SETTEXTJUSTIFICATION, extra, breaks );
}
INT CDECL MFDRV_SetTextCharacterExtra( PHYSDEV dev, INT extra )
{
if(!MFDRV_MetaParam1( dev, META_SETTEXTCHAREXTRA, extra ))
return 0x80000000;
return TRUE;
}
DWORD CDECL MFDRV_SetMapperFlags( PHYSDEV dev, DWORD flags )
{
return MFDRV_MetaParam2( dev, META_SETMAPPERFLAGS, HIWORD(flags),
LOWORD(flags) );
}
BOOL CDECL MFDRV_AbortPath( PHYSDEV dev )
{
return FALSE;
}
BOOL CDECL MFDRV_BeginPath( PHYSDEV dev )
{
return FALSE;
}
BOOL CDECL MFDRV_CloseFigure( PHYSDEV dev )
{
return FALSE;
}
BOOL CDECL MFDRV_EndPath( PHYSDEV dev )
{
return FALSE;
}
BOOL CDECL MFDRV_FillPath( PHYSDEV dev )
{
return FALSE;
}
BOOL CDECL MFDRV_FlattenPath( PHYSDEV dev )
{
return FALSE;
}
BOOL CDECL MFDRV_SelectClipPath( PHYSDEV dev, INT iMode )
{
return FALSE;
}
BOOL CDECL MFDRV_StrokeAndFillPath( PHYSDEV dev )
{
return FALSE;
}
BOOL CDECL MFDRV_StrokePath( PHYSDEV dev )
{
return FALSE;
}
BOOL CDECL MFDRV_WidenPath( PHYSDEV dev )
{
return FALSE;
}

View File

@@ -0,0 +1,474 @@
/*
* Metafile driver graphics functions
*
* Copyright 1993, 1994 Alexandre Julliard
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "mfdrv/metafiledrv.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(metafile);
/**********************************************************************
* MFDRV_MoveTo
*/
BOOL CDECL
MFDRV_MoveTo(PHYSDEV dev, INT x, INT y)
{
return MFDRV_MetaParam2(dev,META_MOVETO,x,y);
}
/***********************************************************************
* MFDRV_LineTo
*/
BOOL CDECL
MFDRV_LineTo( PHYSDEV dev, INT x, INT y )
{
return MFDRV_MetaParam2(dev, META_LINETO, x, y);
}
/***********************************************************************
* MFDRV_Arc
*/
BOOL CDECL
MFDRV_Arc( PHYSDEV dev, INT left, INT top, INT right, INT bottom,
INT xstart, INT ystart, INT xend, INT yend )
{
return MFDRV_MetaParam8(dev, META_ARC, left, top, right, bottom,
xstart, ystart, xend, yend);
}
/***********************************************************************
* MFDRV_Pie
*/
BOOL CDECL
MFDRV_Pie( PHYSDEV dev, INT left, INT top, INT right, INT bottom,
INT xstart, INT ystart, INT xend, INT yend )
{
return MFDRV_MetaParam8(dev, META_PIE, left, top, right, bottom,
xstart, ystart, xend, yend);
}
/***********************************************************************
* MFDRV_Chord
*/
BOOL CDECL
MFDRV_Chord( PHYSDEV dev, INT left, INT top, INT right, INT bottom,
INT xstart, INT ystart, INT xend, INT yend )
{
return MFDRV_MetaParam8(dev, META_CHORD, left, top, right, bottom,
xstart, ystart, xend, yend);
}
/***********************************************************************
* MFDRV_Ellipse
*/
BOOL CDECL
MFDRV_Ellipse( PHYSDEV dev, INT left, INT top, INT right, INT bottom )
{
return MFDRV_MetaParam4(dev, META_ELLIPSE, left, top, right, bottom);
}
/***********************************************************************
* MFDRV_Rectangle
*/
BOOL CDECL
MFDRV_Rectangle(PHYSDEV dev, INT left, INT top, INT right, INT bottom)
{
return MFDRV_MetaParam4(dev, META_RECTANGLE, left, top, right, bottom);
}
/***********************************************************************
* MFDRV_RoundRect
*/
BOOL CDECL
MFDRV_RoundRect( PHYSDEV dev, INT left, INT top, INT right,
INT bottom, INT ell_width, INT ell_height )
{
return MFDRV_MetaParam6(dev, META_ROUNDRECT, left, top, right, bottom,
ell_width, ell_height);
}
/***********************************************************************
* MFDRV_SetPixel
*/
COLORREF CDECL
MFDRV_SetPixel( PHYSDEV dev, INT x, INT y, COLORREF color )
{
return MFDRV_MetaParam4(dev, META_SETPIXEL, x, y,HIWORD(color),
LOWORD(color));
}
/******************************************************************
* MFDRV_MetaPoly - implements Polygon and Polyline
*/
static BOOL MFDRV_MetaPoly(PHYSDEV dev, short func, POINTS *pt, short count)
{
BOOL ret;
DWORD len;
METARECORD *mr;
len = sizeof(METARECORD) + (count * 4);
if (!(mr = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, len )))
return FALSE;
mr->rdSize = len / 2;
mr->rdFunction = func;
*(mr->rdParm) = count;
memcpy(mr->rdParm + 1, pt, count * 4);
ret = MFDRV_WriteRecord( dev, mr, mr->rdSize * 2);
HeapFree( GetProcessHeap(), 0, mr);
return ret;
}
/**********************************************************************
* MFDRV_Polyline
*/
BOOL CDECL
MFDRV_Polyline( PHYSDEV dev, const POINT* pt, INT count )
{
int i;
POINTS *pts;
BOOL ret;
pts = HeapAlloc( GetProcessHeap(), 0, sizeof(POINTS)*count );
if(!pts) return FALSE;
for (i=count;i--;)
{
pts[i].x = pt[i].x;
pts[i].y = pt[i].y;
}
ret = MFDRV_MetaPoly(dev, META_POLYLINE, pts, count);
HeapFree( GetProcessHeap(), 0, pts );
return ret;
}
/**********************************************************************
* MFDRV_Polygon
*/
BOOL CDECL
MFDRV_Polygon( PHYSDEV dev, const POINT* pt, INT count )
{
int i;
POINTS *pts;
BOOL ret;
pts = HeapAlloc( GetProcessHeap(), 0, sizeof(POINTS)*count );
if(!pts) return FALSE;
for (i=count;i--;)
{
pts[i].x = pt[i].x;
pts[i].y = pt[i].y;
}
ret = MFDRV_MetaPoly(dev, META_POLYGON, pts, count);
HeapFree( GetProcessHeap(), 0, pts );
return ret;
}
/**********************************************************************
* MFDRV_PolyPolygon
*/
BOOL CDECL
MFDRV_PolyPolygon( PHYSDEV dev, const POINT* pt, const INT* counts, UINT polygons)
{
BOOL ret;
DWORD len;
METARECORD *mr;
unsigned int i,j;
POINTS *pts;
INT16 totalpoint16 = 0;
INT16 * pointcounts;
for (i=0;i<polygons;i++) {
totalpoint16 += counts[i];
}
/* allocate space for all points */
pts=HeapAlloc( GetProcessHeap(), 0, sizeof(POINTS) * totalpoint16 );
pointcounts = HeapAlloc( GetProcessHeap(), 0, sizeof(INT16) * totalpoint16 );
/* copy point counts */
for (i=0;i<polygons;i++) {
pointcounts[i] = counts[i];
}
/* convert all points */
for (j = totalpoint16; j--;){
pts[j].x = pt[j].x;
pts[j].y = pt[j].y;
}
len = sizeof(METARECORD) + sizeof(WORD) + polygons*sizeof(INT16) + totalpoint16*sizeof(*pts);
if (!(mr = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, len ))) {
HeapFree( GetProcessHeap(), 0, pts );
HeapFree( GetProcessHeap(), 0, pointcounts );
return FALSE;
}
mr->rdSize = len /2;
mr->rdFunction = META_POLYPOLYGON;
*(mr->rdParm) = polygons;
memcpy(mr->rdParm + 1, pointcounts, polygons*sizeof(INT16));
memcpy(mr->rdParm + 1+polygons, pts , totalpoint16*sizeof(*pts));
ret = MFDRV_WriteRecord( dev, mr, mr->rdSize * 2);
HeapFree( GetProcessHeap(), 0, pts );
HeapFree( GetProcessHeap(), 0, pointcounts );
HeapFree( GetProcessHeap(), 0, mr);
return ret;
}
/**********************************************************************
* MFDRV_ExtFloodFill
*/
BOOL CDECL
MFDRV_ExtFloodFill( PHYSDEV dev, INT x, INT y, COLORREF color, UINT fillType )
{
return MFDRV_MetaParam4(dev,META_FLOODFILL,x,y,HIWORD(color),
LOWORD(color));
}
/******************************************************************
* MFDRV_CreateRegion
*
* For explanation of the format of the record see MF_Play_MetaCreateRegion in
* objects/metafile.c
*/
static INT16 MFDRV_CreateRegion(PHYSDEV dev, HRGN hrgn)
{
DWORD len;
METARECORD *mr;
RGNDATA *rgndata;
RECT *pCurRect, *pEndRect;
WORD Bands = 0, MaxBands = 0;
WORD *Param, *StartBand;
BOOL ret;
if (!(len = GetRegionData( hrgn, 0, NULL ))) return -1;
if( !(rgndata = HeapAlloc( GetProcessHeap(), 0, len )) ) {
WARN("Can't alloc rgndata buffer\n");
return -1;
}
GetRegionData( hrgn, len, rgndata );
/* Overestimate of length:
* Assume every rect is a separate band -> 6 WORDs per rect
*/
len = sizeof(METARECORD) + 20 + (rgndata->rdh.nCount * 12);
if( !(mr = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, len )) ) {
WARN("Can't alloc METARECORD buffer\n");
HeapFree( GetProcessHeap(), 0, rgndata );
return -1;
}
Param = mr->rdParm + 11;
StartBand = NULL;
pEndRect = (RECT *)rgndata->Buffer + rgndata->rdh.nCount;
for(pCurRect = (RECT *)rgndata->Buffer; pCurRect < pEndRect; pCurRect++)
{
if( StartBand && pCurRect->top == *(StartBand + 1) )
{
*Param++ = pCurRect->left;
*Param++ = pCurRect->right;
}
else
{
if(StartBand)
{
*StartBand = Param - StartBand - 3;
*Param++ = *StartBand;
if(*StartBand > MaxBands)
MaxBands = *StartBand;
Bands++;
}
StartBand = Param++;
*Param++ = pCurRect->top;
*Param++ = pCurRect->bottom;
*Param++ = pCurRect->left;
*Param++ = pCurRect->right;
}
}
len = Param - (WORD *)mr;
mr->rdParm[0] = 0;
mr->rdParm[1] = 6;
mr->rdParm[2] = 0x1234;
mr->rdParm[3] = 0;
mr->rdParm[4] = len * 2;
mr->rdParm[5] = Bands;
mr->rdParm[6] = MaxBands;
mr->rdParm[7] = rgndata->rdh.rcBound.left;
mr->rdParm[8] = rgndata->rdh.rcBound.top;
mr->rdParm[9] = rgndata->rdh.rcBound.right;
mr->rdParm[10] = rgndata->rdh.rcBound.bottom;
mr->rdFunction = META_CREATEREGION;
mr->rdSize = len / 2;
ret = MFDRV_WriteRecord( dev, mr, mr->rdSize * 2 );
HeapFree( GetProcessHeap(), 0, mr );
HeapFree( GetProcessHeap(), 0, rgndata );
if(!ret)
{
WARN("MFDRV_WriteRecord failed\n");
return -1;
}
return MFDRV_AddHandle( dev, hrgn );
}
/**********************************************************************
* MFDRV_PaintRgn
*/
BOOL CDECL
MFDRV_PaintRgn( PHYSDEV dev, HRGN hrgn )
{
INT16 index;
index = MFDRV_CreateRegion( dev, hrgn );
if(index == -1)
return FALSE;
return MFDRV_MetaParam1( dev, META_PAINTREGION, index );
}
/**********************************************************************
* MFDRV_InvertRgn
*/
BOOL CDECL
MFDRV_InvertRgn( PHYSDEV dev, HRGN hrgn )
{
INT16 index;
index = MFDRV_CreateRegion( dev, hrgn );
if(index == -1)
return FALSE;
return MFDRV_MetaParam1( dev, META_INVERTREGION, index );
}
/**********************************************************************
* MFDRV_FillRgn
*/
BOOL CDECL
MFDRV_FillRgn( PHYSDEV dev, HRGN hrgn, HBRUSH hbrush )
{
INT16 iRgn, iBrush;
iRgn = MFDRV_CreateRegion( dev, hrgn );
if(iRgn == -1)
return FALSE;
iBrush = MFDRV_CreateBrushIndirect( dev, hbrush );
if(!iBrush)
return FALSE;
return MFDRV_MetaParam2( dev, META_FILLREGION, iRgn, iBrush );
}
/**********************************************************************
* MFDRV_FrameRgn
*/
BOOL CDECL
MFDRV_FrameRgn( PHYSDEV dev, HRGN hrgn, HBRUSH hbrush, INT x, INT y )
{
INT16 iRgn, iBrush;
iRgn = MFDRV_CreateRegion( dev, hrgn );
if(iRgn == -1)
return FALSE;
iBrush = MFDRV_CreateBrushIndirect( dev, hbrush );
if(!iBrush)
return FALSE;
return MFDRV_MetaParam4( dev, META_FRAMEREGION, iRgn, iBrush, x, y );
}
/**********************************************************************
* MFDRV_ExtSelectClipRgn
*/
INT CDECL MFDRV_ExtSelectClipRgn( PHYSDEV dev, HRGN hrgn, INT mode )
{
INT16 iRgn;
INT ret;
if (mode != RGN_COPY) return ERROR;
if (!hrgn) return NULLREGION;
iRgn = MFDRV_CreateRegion( dev, hrgn );
if(iRgn == -1) return ERROR;
ret = MFDRV_MetaParam1( dev, META_SELECTCLIPREGION, iRgn ) ? NULLREGION : ERROR;
MFDRV_MetaParam1( dev, META_DELETEOBJECT, iRgn );
MFDRV_RemoveHandle( dev, iRgn );
return ret;
}
/**********************************************************************
* MFDRV_SetBkColor
*/
COLORREF CDECL
MFDRV_SetBkColor( PHYSDEV dev, COLORREF color )
{
return MFDRV_MetaParam2(dev, META_SETBKCOLOR, HIWORD(color),
LOWORD(color)) ? color : CLR_INVALID;
}
/**********************************************************************
* MFDRV_SetTextColor
*/
COLORREF CDECL
MFDRV_SetTextColor( PHYSDEV dev, COLORREF color )
{
return MFDRV_MetaParam2(dev, META_SETTEXTCOLOR, HIWORD(color),
LOWORD(color)) ? color : CLR_INVALID;
}
/**********************************************************************
* MFDRV_PolyBezier
* Since MetaFiles don't record Beziers and they don't even record
* approximations to them using lines, we need this stub function.
*/
BOOL CDECL
MFDRV_PolyBezier( PHYSDEV dev, const POINT *pts, DWORD count )
{
return FALSE;
}
/**********************************************************************
* MFDRV_PolyBezierTo
* Since MetaFiles don't record Beziers and they don't even record
* approximations to them using lines, we need this stub function.
*/
BOOL CDECL
MFDRV_PolyBezierTo( PHYSDEV dev, const POINT *pts, DWORD count )
{
return FALSE;
}

View File

@@ -0,0 +1,582 @@
/*
* Metafile driver initialisation functions
*
* Copyright 1996 Alexandre Julliard
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <stdarg.h>
#include <string.h>
#include "windef.h"
#include "winbase.h"
#include "winnls.h"
#include "gdi_private.h"
#include "mfdrv/metafiledrv.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(metafile);
static const DC_FUNCTIONS MFDRV_Funcs =
{
NULL, /* pAbortDoc */
MFDRV_AbortPath, /* pAbortPath */
NULL, /* pAlphaBlend */
NULL, /* pAngleArc */
MFDRV_Arc, /* pArc */
NULL, /* pArcTo */
MFDRV_BeginPath, /* pBeginPath */
NULL, /* pBitBlt */
NULL, /* pChoosePixelFormat */
MFDRV_Chord, /* pChord */
MFDRV_CloseFigure, /* pCloseFigure */
NULL, /* pCreateBitmap */
NULL, /* pCreateDC */
NULL, /* pCreateDIBSection */
NULL, /* pDeleteBitmap */
NULL, /* pDeleteDC */
MFDRV_DeleteObject, /* pDeleteObject */
NULL, /* pDescribePixelFormat */
NULL, /* pDeviceCapabilities */
MFDRV_Ellipse, /* pEllipse */
NULL, /* pEndDoc */
NULL, /* pEndPage */
MFDRV_EndPath, /* pEndPath */
NULL, /* pEnumDeviceFonts */
NULL, /* pEnumICMProfiles */
MFDRV_ExcludeClipRect, /* pExcludeClipRect */
NULL, /* pExtDeviceMode */
MFDRV_ExtEscape, /* pExtEscape */
MFDRV_ExtFloodFill, /* pExtFloodFill */
MFDRV_ExtSelectClipRgn, /* pExtSelectClipRgn */
MFDRV_ExtTextOut, /* pExtTextOut */
MFDRV_FillPath, /* pFillPath */
MFDRV_FillRgn, /* pFillRgn */
MFDRV_FlattenPath, /* pFlattenPath */
MFDRV_FrameRgn, /* pFrameRgn */
NULL, /* pGdiComment */
NULL, /* pGetBitmapBits */
NULL, /* pGetCharWidth */
NULL, /* pGetDIBColorTable */
NULL, /* pGetDIBits */
MFDRV_GetDeviceCaps, /* pGetDeviceCaps */
NULL, /* pGetDeviceGammaRamp */
NULL, /* pGetICMProfile */
NULL, /* pGetNearestColor */
NULL, /* pGetPixel */
NULL, /* pGetPixelFormat */
NULL, /* pGetSystemPaletteEntries */
NULL, /* pGetTextExtentExPoint */
NULL, /* pGetTextMetrics */
MFDRV_IntersectClipRect, /* pIntersectClipRect */
MFDRV_InvertRgn, /* pInvertRgn */
MFDRV_LineTo, /* pLineTo */
NULL, /* pModifyWorldTransform */
MFDRV_MoveTo, /* pMoveTo */
MFDRV_OffsetClipRgn, /* pOffsetClipRgn */
MFDRV_OffsetViewportOrg, /* pOffsetViewportOrg */
MFDRV_OffsetWindowOrg, /* pOffsetWindowOrg */
MFDRV_PaintRgn, /* pPaintRgn */
MFDRV_PatBlt, /* pPatBlt */
MFDRV_Pie, /* pPie */
MFDRV_PolyBezier, /* pPolyBezier */
MFDRV_PolyBezierTo, /* pPolyBezierTo */
NULL, /* pPolyDraw */
MFDRV_PolyPolygon, /* pPolyPolygon */
NULL, /* pPolyPolyline */
MFDRV_Polygon, /* pPolygon */
MFDRV_Polyline, /* pPolyline */
NULL, /* pPolylineTo */
NULL, /* pRealizeDefaultPalette */
MFDRV_RealizePalette, /* pRealizePalette */
MFDRV_Rectangle, /* pRectangle */
NULL, /* pResetDC */
MFDRV_RestoreDC, /* pRestoreDC */
MFDRV_RoundRect, /* pRoundRect */
MFDRV_SaveDC, /* pSaveDC */
MFDRV_ScaleViewportExt, /* pScaleViewportExt */
MFDRV_ScaleWindowExt, /* pScaleWindowExt */
MFDRV_SelectBitmap, /* pSelectBitmap */
MFDRV_SelectBrush, /* pSelectBrush */
MFDRV_SelectClipPath, /* pSelectClipPath */
MFDRV_SelectFont, /* pSelectFont */
MFDRV_SelectPalette, /* pSelectPalette */
MFDRV_SelectPen, /* pSelectPen */
NULL, /* pSetArcDirection */
NULL, /* pSetBitmapBits */
MFDRV_SetBkColor, /* pSetBkColor */
MFDRV_SetBkMode, /* pSetBkMode */
NULL, /* pSetDCBrushColor*/
NULL, /* pSetDCPenColor*/
NULL, /* pSetDIBColorTable */
NULL, /* pSetDIBits */
MFDRV_SetDIBitsToDevice, /* pSetDIBitsToDevice */
NULL, /* pSetDeviceClipping */
NULL, /* pSetDeviceGammaRamp */
MFDRV_SetMapMode, /* pSetMapMode */
MFDRV_SetMapperFlags, /* pSetMapperFlags */
MFDRV_SetPixel, /* pSetPixel */
NULL, /* pSetPixelFormat */
MFDRV_SetPolyFillMode, /* pSetPolyFillMode */
MFDRV_SetROP2, /* pSetROP2 */
MFDRV_SetRelAbs, /* pSetRelAbs */
MFDRV_SetStretchBltMode, /* pSetStretchBltMode */
MFDRV_SetTextAlign, /* pSetTextAlign */
MFDRV_SetTextCharacterExtra, /* pSetTextCharacterExtra */
MFDRV_SetTextColor, /* pSetTextColor */
MFDRV_SetTextJustification, /* pSetTextJustification */
MFDRV_SetViewportExt, /* pSetViewportExt */
MFDRV_SetViewportOrg, /* pSetViewportOrg */
MFDRV_SetWindowExt, /* pSetWindowExt */
MFDRV_SetWindowOrg, /* pSetWindowOrg */
NULL, /* pSetWorldTransform */
NULL, /* pStartDoc */
NULL, /* pStartPage */
MFDRV_StretchBlt, /* pStretchBlt */
MFDRV_StretchDIBits, /* pStretchDIBits */
MFDRV_StrokeAndFillPath, /* pStrokeAndFillPath */
MFDRV_StrokePath, /* pStrokePath */
NULL, /* pSwapBuffers */
NULL, /* pUnrealizePalette */
MFDRV_WidenPath /* pWidenPath */
};
/**********************************************************************
* MFDRV_AllocMetaFile
*/
static DC *MFDRV_AllocMetaFile(void)
{
DC *dc;
METAFILEDRV_PDEVICE *physDev;
if (!(dc = alloc_dc_ptr( &MFDRV_Funcs, OBJ_METADC ))) return NULL;
physDev = HeapAlloc(GetProcessHeap(),0,sizeof(*physDev));
if (!physDev)
{
free_dc_ptr( dc );
return NULL;
}
dc->physDev = (PHYSDEV)physDev;
physDev->hdc = dc->hSelf;
if (!(physDev->mh = HeapAlloc( GetProcessHeap(), 0, sizeof(*physDev->mh) )))
{
HeapFree( GetProcessHeap(), 0, physDev );
free_dc_ptr( dc );
return NULL;
}
physDev->handles = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, HANDLE_LIST_INC * sizeof(physDev->handles[0]));
physDev->handles_size = HANDLE_LIST_INC;
physDev->cur_handles = 0;
physDev->hFile = 0;
physDev->mh->mtHeaderSize = sizeof(METAHEADER) / sizeof(WORD);
physDev->mh->mtVersion = 0x0300;
physDev->mh->mtSize = physDev->mh->mtHeaderSize;
physDev->mh->mtNoObjects = 0;
physDev->mh->mtMaxRecord = 0;
physDev->mh->mtNoParameters = 0;
SetVirtualResolution(dc->hSelf, 0, 0, 0, 0);
return dc;
}
/**********************************************************************
* MFDRV_DeleteDC
*/
static BOOL MFDRV_DeleteDC( DC *dc )
{
METAFILEDRV_PDEVICE *physDev = (METAFILEDRV_PDEVICE *)dc->physDev;
DWORD index;
HeapFree( GetProcessHeap(), 0, physDev->mh );
for(index = 0; index < physDev->handles_size; index++)
if(physDev->handles[index])
GDI_hdc_not_using_object(physDev->handles[index], physDev->hdc);
HeapFree( GetProcessHeap(), 0, physDev->handles );
HeapFree( GetProcessHeap(), 0, physDev );
dc->physDev = NULL;
free_dc_ptr( dc );
return TRUE;
}
/**********************************************************************
* CreateMetaFileW (GDI32.@)
*
* Create a new DC and associate it with a metafile. Pass a filename
* to create a disk-based metafile, NULL to create a memory metafile.
*
* PARAMS
* filename [I] Filename of disk metafile
*
* RETURNS
* A handle to the metafile DC if successful, NULL on failure.
*/
HDC WINAPI CreateMetaFileW( LPCWSTR filename )
{
HDC ret;
DC *dc;
METAFILEDRV_PDEVICE *physDev;
HANDLE hFile;
TRACE("%s\n", debugstr_w(filename) );
if (!(dc = MFDRV_AllocMetaFile())) return 0;
physDev = (METAFILEDRV_PDEVICE *)dc->physDev;
if (filename) /* disk based metafile */
{
physDev->mh->mtType = METAFILE_DISK;
if ((hFile = CreateFileW(filename, GENERIC_WRITE, 0, NULL,
CREATE_ALWAYS, 0, 0)) == INVALID_HANDLE_VALUE) {
MFDRV_DeleteDC( dc );
return 0;
}
if (!WriteFile( hFile, physDev->mh, sizeof(*physDev->mh), NULL,
NULL )) {
MFDRV_DeleteDC( dc );
return 0;
}
physDev->hFile = hFile;
/* Grow METAHEADER to include filename */
physDev->mh = MF_CreateMetaHeaderDisk(physDev->mh, filename, TRUE);
}
else /* memory based metafile */
physDev->mh->mtType = METAFILE_MEMORY;
TRACE("returning %p\n", dc->hSelf);
ret = dc->hSelf;
release_dc_ptr( dc );
return ret;
}
/**********************************************************************
* CreateMetaFileA (GDI32.@)
*
* See CreateMetaFileW.
*/
HDC WINAPI CreateMetaFileA(LPCSTR filename)
{
LPWSTR filenameW;
DWORD len;
HDC hReturnDC;
if (!filename) return CreateMetaFileW(NULL);
len = MultiByteToWideChar( CP_ACP, 0, filename, -1, NULL, 0 );
filenameW = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
MultiByteToWideChar( CP_ACP, 0, filename, -1, filenameW, len );
hReturnDC = CreateMetaFileW(filenameW);
HeapFree( GetProcessHeap(), 0, filenameW );
return hReturnDC;
}
/**********************************************************************
* MFDRV_CloseMetaFile
*/
static DC *MFDRV_CloseMetaFile( HDC hdc )
{
DC *dc;
METAFILEDRV_PDEVICE *physDev;
TRACE("(%p)\n", hdc );
if (!(dc = get_dc_ptr( hdc ))) return NULL;
if (dc->header.type != OBJ_METADC)
{
release_dc_ptr( dc );
return NULL;
}
if (dc->refcount != 1)
{
FIXME( "not deleting busy DC %p refcount %u\n", dc->hSelf, dc->refcount );
release_dc_ptr( dc );
return NULL;
}
physDev = (METAFILEDRV_PDEVICE *)dc->physDev;
/* Construct the end of metafile record - this is documented
* in SDK Knowledgebase Q99334.
*/
if (!MFDRV_MetaParam0(dc->physDev, META_EOF))
{
MFDRV_DeleteDC( dc );
return 0;
}
if (physDev->mh->mtType == METAFILE_DISK) /* disk based metafile */
{
if (SetFilePointer(physDev->hFile, 0, NULL, FILE_BEGIN) != 0) {
MFDRV_DeleteDC( dc );
return 0;
}
physDev->mh->mtType = METAFILE_MEMORY; /* This is what windows does */
if (!WriteFile(physDev->hFile, physDev->mh, sizeof(*physDev->mh),
NULL, NULL)) {
MFDRV_DeleteDC( dc );
return 0;
}
CloseHandle(physDev->hFile);
physDev->mh->mtType = METAFILE_DISK;
}
return dc;
}
/******************************************************************
* CloseMetaFile (GDI32.@)
*
* Stop recording graphics operations in metafile associated with
* hdc and retrieve metafile.
*
* PARAMS
* hdc [I] Metafile DC to close
*
* RETURNS
* Handle of newly created metafile on success, NULL on failure.
*/
HMETAFILE WINAPI CloseMetaFile(HDC hdc)
{
HMETAFILE hmf;
METAFILEDRV_PDEVICE *physDev;
DC *dc = MFDRV_CloseMetaFile(hdc);
if (!dc) return 0;
physDev = (METAFILEDRV_PDEVICE *)dc->physDev;
/* Now allocate a global handle for the metafile */
hmf = MF_Create_HMETAFILE( physDev->mh );
physDev->mh = NULL; /* So it won't be deleted */
MFDRV_DeleteDC( dc );
return hmf;
}
/******************************************************************
* MFDRV_WriteRecord
*
* Warning: this function can change the pointer to the metafile header.
*/
BOOL MFDRV_WriteRecord( PHYSDEV dev, METARECORD *mr, DWORD rlen)
{
DWORD len, size;
METAHEADER *mh;
METAFILEDRV_PDEVICE *physDev = (METAFILEDRV_PDEVICE *)dev;
switch(physDev->mh->mtType)
{
case METAFILE_MEMORY:
len = physDev->mh->mtSize * 2 + rlen;
/* reallocate memory if needed */
size = HeapSize( GetProcessHeap(), 0, physDev->mh );
if (len > size)
{
/*expand size*/
size += size / 2 + rlen;
mh = HeapReAlloc( GetProcessHeap(), 0, physDev->mh, size);
if (!mh) return FALSE;
physDev->mh = mh;
TRACE("Reallocated metafile: new size is %d\n",size);
}
memcpy((WORD *)physDev->mh + physDev->mh->mtSize, mr, rlen);
break;
case METAFILE_DISK:
TRACE("Writing record to disk\n");
if (!WriteFile(physDev->hFile, mr, rlen, NULL, NULL))
return FALSE;
break;
default:
ERR("Unknown metafile type %d\n", physDev->mh->mtType );
return FALSE;
}
physDev->mh->mtSize += rlen / 2;
physDev->mh->mtMaxRecord = max(physDev->mh->mtMaxRecord, rlen / 2);
return TRUE;
}
/******************************************************************
* MFDRV_MetaParam0
*/
BOOL MFDRV_MetaParam0(PHYSDEV dev, short func)
{
char buffer[8];
METARECORD *mr = (METARECORD *)&buffer;
mr->rdSize = 3;
mr->rdFunction = func;
return MFDRV_WriteRecord( dev, mr, mr->rdSize * 2);
}
/******************************************************************
* MFDRV_MetaParam1
*/
BOOL MFDRV_MetaParam1(PHYSDEV dev, short func, short param1)
{
char buffer[8];
METARECORD *mr = (METARECORD *)&buffer;
mr->rdSize = 4;
mr->rdFunction = func;
*(mr->rdParm) = param1;
return MFDRV_WriteRecord( dev, mr, mr->rdSize * 2);
}
/******************************************************************
* MFDRV_MetaParam2
*/
BOOL MFDRV_MetaParam2(PHYSDEV dev, short func, short param1, short param2)
{
char buffer[10];
METARECORD *mr = (METARECORD *)&buffer;
mr->rdSize = 5;
mr->rdFunction = func;
*(mr->rdParm) = param2;
*(mr->rdParm + 1) = param1;
return MFDRV_WriteRecord( dev, mr, mr->rdSize * 2);
}
/******************************************************************
* MFDRV_MetaParam4
*/
BOOL MFDRV_MetaParam4(PHYSDEV dev, short func, short param1, short param2,
short param3, short param4)
{
char buffer[14];
METARECORD *mr = (METARECORD *)&buffer;
mr->rdSize = 7;
mr->rdFunction = func;
*(mr->rdParm) = param4;
*(mr->rdParm + 1) = param3;
*(mr->rdParm + 2) = param2;
*(mr->rdParm + 3) = param1;
return MFDRV_WriteRecord( dev, mr, mr->rdSize * 2);
}
/******************************************************************
* MFDRV_MetaParam6
*/
BOOL MFDRV_MetaParam6(PHYSDEV dev, short func, short param1, short param2,
short param3, short param4, short param5, short param6)
{
char buffer[18];
METARECORD *mr = (METARECORD *)&buffer;
mr->rdSize = 9;
mr->rdFunction = func;
*(mr->rdParm) = param6;
*(mr->rdParm + 1) = param5;
*(mr->rdParm + 2) = param4;
*(mr->rdParm + 3) = param3;
*(mr->rdParm + 4) = param2;
*(mr->rdParm + 5) = param1;
return MFDRV_WriteRecord( dev, mr, mr->rdSize * 2);
}
/******************************************************************
* MFDRV_MetaParam8
*/
BOOL MFDRV_MetaParam8(PHYSDEV dev, short func, short param1, short param2,
short param3, short param4, short param5,
short param6, short param7, short param8)
{
char buffer[22];
METARECORD *mr = (METARECORD *)&buffer;
mr->rdSize = 11;
mr->rdFunction = func;
*(mr->rdParm) = param8;
*(mr->rdParm + 1) = param7;
*(mr->rdParm + 2) = param6;
*(mr->rdParm + 3) = param5;
*(mr->rdParm + 4) = param4;
*(mr->rdParm + 5) = param3;
*(mr->rdParm + 6) = param2;
*(mr->rdParm + 7) = param1;
return MFDRV_WriteRecord( dev, mr, mr->rdSize * 2);
}
/**********************************************************************
* MFDRV_ExtEscape
*/
INT CDECL MFDRV_ExtEscape( PHYSDEV dev, INT nEscape, INT cbInput, LPCVOID in_data,
INT cbOutput, LPVOID out_data )
{
METARECORD *mr;
DWORD len;
INT ret;
if (cbOutput) return 0; /* escapes that require output cannot work in metafiles */
len = sizeof(*mr) + sizeof(WORD) + ((cbInput + 1) & ~1);
mr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len);
mr->rdSize = len / 2;
mr->rdFunction = META_ESCAPE;
mr->rdParm[0] = nEscape;
mr->rdParm[1] = cbInput;
memcpy(&(mr->rdParm[2]), in_data, cbInput);
ret = MFDRV_WriteRecord( dev, mr, len);
HeapFree(GetProcessHeap(), 0, mr);
return ret;
}
/******************************************************************
* MFDRV_GetDeviceCaps
*
*A very simple implementation that returns DT_METAFILE
*/
INT CDECL MFDRV_GetDeviceCaps(PHYSDEV dev, INT cap)
{
switch(cap)
{
case TECHNOLOGY:
return DT_METAFILE;
case TEXTCAPS:
return 0;
default:
TRACE(" unsupported capability %d, will return 0\n", cap );
}
return 0;
}

View File

@@ -0,0 +1,125 @@
/*
* Metafile GDI mapping mode functions
*
* Copyright 1996 Alexandre Julliard
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <stdarg.h>
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "gdi_private.h"
#include "mfdrv/metafiledrv.h"
/***********************************************************************
* MFDRV_SetMapMode
*/
INT CDECL MFDRV_SetMapMode( PHYSDEV dev, INT mode )
{
if(!MFDRV_MetaParam1( dev, META_SETMAPMODE, mode ))
return FALSE;
return GDI_NO_MORE_WORK;
}
/***********************************************************************
* MFDRV_SetViewportExt
*/
INT CDECL MFDRV_SetViewportExt( PHYSDEV dev, INT x, INT y )
{
if(!MFDRV_MetaParam2( dev, META_SETVIEWPORTEXT, x, y ))
return FALSE;
return GDI_NO_MORE_WORK;
}
/***********************************************************************
* MFDRV_SetViewportOrg
*/
INT CDECL MFDRV_SetViewportOrg( PHYSDEV dev, INT x, INT y )
{
if(!MFDRV_MetaParam2( dev, META_SETVIEWPORTORG, x, y ))
return FALSE;
return GDI_NO_MORE_WORK;
}
/***********************************************************************
* MFDRV_SetWindowExt
*/
INT CDECL MFDRV_SetWindowExt( PHYSDEV dev, INT x, INT y )
{
if(!MFDRV_MetaParam2( dev, META_SETWINDOWEXT, x, y ))
return FALSE;
return GDI_NO_MORE_WORK;
}
/***********************************************************************
* MFDRV_SetWindowOrg
*/
INT CDECL MFDRV_SetWindowOrg( PHYSDEV dev, INT x, INT y )
{
if(!MFDRV_MetaParam2( dev, META_SETWINDOWORG, x, y ))
return FALSE;
return GDI_NO_MORE_WORK;
}
/***********************************************************************
* MFDRV_OffsetViewportOrg
*/
INT CDECL MFDRV_OffsetViewportOrg( PHYSDEV dev, INT x, INT y )
{
if(!MFDRV_MetaParam2( dev, META_OFFSETVIEWPORTORG, x, y ))
return FALSE;
return GDI_NO_MORE_WORK;
}
/***********************************************************************
* MFDRV_OffsetWindowOrg
*/
INT CDECL MFDRV_OffsetWindowOrg( PHYSDEV dev, INT x, INT y )
{
if(!MFDRV_MetaParam2( dev, META_OFFSETWINDOWORG, x, y ))
return FALSE;
return GDI_NO_MORE_WORK;
}
/***********************************************************************
* MFDRV_ScaleViewportExt
*/
INT CDECL MFDRV_ScaleViewportExt( PHYSDEV dev, INT xNum, INT xDenom, INT yNum, INT yDenom )
{
if(!MFDRV_MetaParam4( dev, META_SCALEVIEWPORTEXT, xNum, xDenom, yNum, yDenom ))
return FALSE;
return GDI_NO_MORE_WORK;
}
/***********************************************************************
* MFDRV_ScaleWindowExt
*/
INT CDECL MFDRV_ScaleWindowExt( PHYSDEV dev, INT xNum, INT xDenom, INT yNum, INT yDenom )
{
if(!MFDRV_MetaParam4( dev, META_SCALEWINDOWEXT, xNum, xDenom, yNum, yDenom ))
return FALSE;
return GDI_NO_MORE_WORK;
}

View File

@@ -0,0 +1,160 @@
/*
* Metafile driver definitions
*
* Copyright 1996 Alexandre Julliard
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef __WINE_METAFILEDRV_H
#define __WINE_METAFILEDRV_H
#include <stdarg.h>
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "gdi_private.h"
/* Metafile driver physical DC */
typedef struct
{
HDC hdc;
METAHEADER *mh; /* Pointer to metafile header */
UINT handles_size, cur_handles;
HGDIOBJ *handles;
HANDLE hFile; /* Handle for disk based MetaFile */
} METAFILEDRV_PDEVICE;
#define HANDLE_LIST_INC 20
extern BOOL MFDRV_MetaParam0(PHYSDEV dev, short func) DECLSPEC_HIDDEN;
extern BOOL MFDRV_MetaParam1(PHYSDEV dev, short func, short param1) DECLSPEC_HIDDEN;
extern BOOL MFDRV_MetaParam2(PHYSDEV dev, short func, short param1, short param2) DECLSPEC_HIDDEN;
extern BOOL MFDRV_MetaParam4(PHYSDEV dev, short func, short param1, short param2,
short param3, short param4) DECLSPEC_HIDDEN;
extern BOOL MFDRV_MetaParam6(PHYSDEV dev, short func, short param1, short param2,
short param3, short param4, short param5,
short param6) DECLSPEC_HIDDEN;
extern BOOL MFDRV_MetaParam8(PHYSDEV dev, short func, short param1, short param2,
short param3, short param4, short param5,
short param6, short param7, short param8) DECLSPEC_HIDDEN;
extern BOOL MFDRV_WriteRecord(PHYSDEV dev, METARECORD *mr, DWORD rlen) DECLSPEC_HIDDEN;
extern UINT MFDRV_AddHandle( PHYSDEV dev, HGDIOBJ obj ) DECLSPEC_HIDDEN;
extern BOOL MFDRV_RemoveHandle( PHYSDEV dev, UINT index ) DECLSPEC_HIDDEN;
extern INT16 MFDRV_CreateBrushIndirect( PHYSDEV dev, HBRUSH hBrush ) DECLSPEC_HIDDEN;
/* Metafile driver functions */
extern BOOL CDECL MFDRV_AbortPath( PHYSDEV dev ) DECLSPEC_HIDDEN;
extern BOOL CDECL MFDRV_Arc( PHYSDEV dev, INT left, INT top, INT right, INT bottom,
INT xstart, INT ystart, INT xend, INT yend ) DECLSPEC_HIDDEN;
extern BOOL CDECL MFDRV_BeginPath( PHYSDEV dev ) DECLSPEC_HIDDEN;
extern BOOL CDECL MFDRV_Chord( PHYSDEV dev, INT left, INT top, INT right,
INT bottom, INT xstart, INT ystart, INT xend,
INT yend ) DECLSPEC_HIDDEN;
extern BOOL CDECL MFDRV_CloseFigure( PHYSDEV dev ) DECLSPEC_HIDDEN;
extern BOOL CDECL MFDRV_DeleteObject( PHYSDEV dev, HGDIOBJ obj ) DECLSPEC_HIDDEN;
extern BOOL CDECL MFDRV_Ellipse( PHYSDEV dev, INT left, INT top,
INT right, INT bottom ) DECLSPEC_HIDDEN;
extern BOOL CDECL MFDRV_EndPath( PHYSDEV dev ) DECLSPEC_HIDDEN;
extern INT CDECL MFDRV_ExcludeClipRect( PHYSDEV dev, INT left, INT top, INT right,
INT bottom ) DECLSPEC_HIDDEN;
extern INT CDECL MFDRV_ExtEscape( PHYSDEV dev, INT nEscape, INT cbInput, LPCVOID in_data,
INT cbOutput, LPVOID out_data ) DECLSPEC_HIDDEN;
extern BOOL CDECL MFDRV_ExtFloodFill( PHYSDEV dev, INT x, INT y, COLORREF color, UINT fillType ) DECLSPEC_HIDDEN;
extern INT CDECL MFDRV_ExtSelectClipRgn( PHYSDEV dev, HRGN hrgn, INT mode ) DECLSPEC_HIDDEN;
extern BOOL CDECL MFDRV_ExtTextOut( PHYSDEV dev, INT x, INT y,
UINT flags, const RECT *lprect, LPCWSTR str,
UINT count, const INT *lpDx ) DECLSPEC_HIDDEN;
extern BOOL CDECL MFDRV_FillPath( PHYSDEV dev ) DECLSPEC_HIDDEN;
extern BOOL CDECL MFDRV_FillRgn( PHYSDEV dev, HRGN hrgn, HBRUSH hbrush ) DECLSPEC_HIDDEN;
extern BOOL CDECL MFDRV_FlattenPath( PHYSDEV dev ) DECLSPEC_HIDDEN;
extern BOOL CDECL MFDRV_FrameRgn( PHYSDEV dev, HRGN hrgn, HBRUSH hbrush, INT x, INT y ) DECLSPEC_HIDDEN;
extern INT CDECL MFDRV_GetDeviceCaps( PHYSDEV dev , INT cap ) DECLSPEC_HIDDEN;
extern INT CDECL MFDRV_IntersectClipRect( PHYSDEV dev, INT left, INT top, INT right, INT bottom ) DECLSPEC_HIDDEN;
extern BOOL CDECL MFDRV_InvertRgn( PHYSDEV dev, HRGN hrgn ) DECLSPEC_HIDDEN;
extern BOOL CDECL MFDRV_LineTo( PHYSDEV dev, INT x, INT y ) DECLSPEC_HIDDEN;
extern BOOL CDECL MFDRV_MoveTo( PHYSDEV dev, INT x, INT y ) DECLSPEC_HIDDEN;
extern INT CDECL MFDRV_OffsetClipRgn( PHYSDEV dev, INT x, INT y ) DECLSPEC_HIDDEN;
extern INT CDECL MFDRV_OffsetViewportOrg( PHYSDEV dev, INT x, INT y ) DECLSPEC_HIDDEN;
extern INT CDECL MFDRV_OffsetWindowOrg( PHYSDEV dev, INT x, INT y ) DECLSPEC_HIDDEN;
extern BOOL CDECL MFDRV_PaintRgn( PHYSDEV dev, HRGN hrgn ) DECLSPEC_HIDDEN;
extern BOOL CDECL MFDRV_PatBlt( PHYSDEV dev, INT left, INT top, INT width, INT height,
DWORD rop ) DECLSPEC_HIDDEN;
extern BOOL CDECL MFDRV_Pie( PHYSDEV dev, INT left, INT top, INT right,
INT bottom, INT xstart, INT ystart, INT xend,
INT yend ) DECLSPEC_HIDDEN;
extern BOOL CDECL MFDRV_PolyBezier( PHYSDEV dev, const POINT* pt, DWORD count ) DECLSPEC_HIDDEN;
extern BOOL CDECL MFDRV_PolyBezierTo( PHYSDEV dev, const POINT* pt, DWORD count ) DECLSPEC_HIDDEN;
extern BOOL CDECL MFDRV_PolyPolygon( PHYSDEV dev, const POINT* pt, const INT* counts,
UINT polygons) DECLSPEC_HIDDEN;
extern BOOL CDECL MFDRV_Polygon( PHYSDEV dev, const POINT* pt, INT count ) DECLSPEC_HIDDEN;
extern BOOL CDECL MFDRV_Polyline( PHYSDEV dev, const POINT* pt,INT count) DECLSPEC_HIDDEN;
extern BOOL CDECL MFDRV_Rectangle( PHYSDEV dev, INT left, INT top,
INT right, INT bottom) DECLSPEC_HIDDEN;
extern BOOL CDECL MFDRV_RestoreDC( PHYSDEV dev, INT level ) DECLSPEC_HIDDEN;
extern BOOL CDECL MFDRV_RoundRect( PHYSDEV dev, INT left, INT top,
INT right, INT bottom, INT ell_width,
INT ell_height ) DECLSPEC_HIDDEN;
extern INT CDECL MFDRV_SaveDC( PHYSDEV dev ) DECLSPEC_HIDDEN;
extern INT CDECL MFDRV_ScaleViewportExt( PHYSDEV dev, INT xNum, INT xDenom, INT yNum,
INT yDenom ) DECLSPEC_HIDDEN;
extern INT CDECL MFDRV_ScaleWindowExt( PHYSDEV dev, INT xNum, INT xDenom, INT yNum,
INT yDenom ) DECLSPEC_HIDDEN;
extern HBITMAP CDECL MFDRV_SelectBitmap( PHYSDEV dev, HBITMAP handle ) DECLSPEC_HIDDEN;
extern HBRUSH CDECL MFDRV_SelectBrush( PHYSDEV dev, HBRUSH handle ) DECLSPEC_HIDDEN;
extern BOOL CDECL MFDRV_SelectClipPath( PHYSDEV dev, INT iMode ) DECLSPEC_HIDDEN;
extern HFONT CDECL MFDRV_SelectFont( PHYSDEV dev, HFONT handle, HANDLE gdiFont ) DECLSPEC_HIDDEN;
extern HPEN CDECL MFDRV_SelectPen( PHYSDEV dev, HPEN handle ) DECLSPEC_HIDDEN;
extern HPALETTE CDECL MFDRV_SelectPalette( PHYSDEV dev, HPALETTE hPalette, BOOL bForceBackground) DECLSPEC_HIDDEN;
extern UINT CDECL MFDRV_RealizePalette(PHYSDEV dev, HPALETTE hPalette, BOOL primary) DECLSPEC_HIDDEN;
extern COLORREF CDECL MFDRV_SetBkColor( PHYSDEV dev, COLORREF color ) DECLSPEC_HIDDEN;
extern INT CDECL MFDRV_SetBkMode( PHYSDEV dev, INT mode ) DECLSPEC_HIDDEN;
extern INT CDECL MFDRV_SetMapMode( PHYSDEV dev, INT mode ) DECLSPEC_HIDDEN;
extern DWORD CDECL MFDRV_SetMapperFlags( PHYSDEV dev, DWORD flags ) DECLSPEC_HIDDEN;
extern COLORREF CDECL MFDRV_SetPixel( PHYSDEV dev, INT x, INT y, COLORREF color ) DECLSPEC_HIDDEN;
extern INT CDECL MFDRV_SetPolyFillMode( PHYSDEV dev, INT mode ) DECLSPEC_HIDDEN;
extern INT CDECL MFDRV_SetROP2( PHYSDEV dev, INT rop ) DECLSPEC_HIDDEN;
extern INT CDECL MFDRV_SetRelAbs( PHYSDEV dev, INT mode ) DECLSPEC_HIDDEN;
extern INT CDECL MFDRV_SetStretchBltMode( PHYSDEV dev, INT mode ) DECLSPEC_HIDDEN;
extern UINT CDECL MFDRV_SetTextAlign( PHYSDEV dev, UINT align ) DECLSPEC_HIDDEN;
extern INT CDECL MFDRV_SetTextCharacterExtra( PHYSDEV dev, INT extra ) DECLSPEC_HIDDEN;
extern COLORREF CDECL MFDRV_SetTextColor( PHYSDEV dev, COLORREF color ) DECLSPEC_HIDDEN;
extern INT CDECL MFDRV_SetTextJustification( PHYSDEV dev, INT extra, INT breaks ) DECLSPEC_HIDDEN;
extern INT CDECL MFDRV_SetViewportExt( PHYSDEV dev, INT x, INT y ) DECLSPEC_HIDDEN;
extern INT CDECL MFDRV_SetViewportOrg( PHYSDEV dev, INT x, INT y ) DECLSPEC_HIDDEN;
extern INT CDECL MFDRV_SetWindowExt( PHYSDEV dev, INT x, INT y ) DECLSPEC_HIDDEN;
extern INT CDECL MFDRV_SetWindowOrg( PHYSDEV dev, INT x, INT y ) DECLSPEC_HIDDEN;
extern BOOL CDECL MFDRV_StretchBlt( PHYSDEV devDst, INT xDst, INT yDst, INT widthDst,
INT heightDst, PHYSDEV devSrc, INT xSrc, INT ySrc,
INT widthSrc, INT heightSrc, DWORD rop ) DECLSPEC_HIDDEN;
extern BOOL CDECL MFDRV_PaintRgn( PHYSDEV dev, HRGN hrgn ) DECLSPEC_HIDDEN;
extern INT CDECL MFDRV_SetDIBitsToDevice( PHYSDEV dev, INT xDest, INT yDest, DWORD cx,
DWORD cy, INT xSrc, INT ySrc,
UINT startscan, UINT lines, LPCVOID bits,
const BITMAPINFO *info, UINT coloruse ) DECLSPEC_HIDDEN;
extern INT CDECL MFDRV_StretchDIBits( PHYSDEV dev, INT xDst, INT yDst, INT widthDst,
INT heightDst, INT xSrc, INT ySrc,
INT widthSrc, INT heightSrc, const void *bits,
const BITMAPINFO *info, UINT wUsage,
DWORD dwRop ) DECLSPEC_HIDDEN;
extern BOOL CDECL MFDRV_StrokeAndFillPath( PHYSDEV dev ) DECLSPEC_HIDDEN;
extern BOOL CDECL MFDRV_StrokePath( PHYSDEV dev ) DECLSPEC_HIDDEN;
extern BOOL CDECL MFDRV_WidenPath( PHYSDEV dev ) DECLSPEC_HIDDEN;
#endif /* __WINE_METAFILEDRV_H */

View File

@@ -0,0 +1,573 @@
/*
* GDI objects
*
* Copyright 1993 Alexandre Julliard
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "wine/wingdi16.h"
#include "mfdrv/metafiledrv.h"
#include "gdi_private.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(metafile);
/******************************************************************
* MFDRV_AddHandle
*/
UINT MFDRV_AddHandle( PHYSDEV dev, HGDIOBJ obj )
{
METAFILEDRV_PDEVICE *physDev = (METAFILEDRV_PDEVICE *)dev;
UINT16 index;
for(index = 0; index < physDev->handles_size; index++)
if(physDev->handles[index] == 0) break;
if(index == physDev->handles_size) {
physDev->handles_size += HANDLE_LIST_INC;
physDev->handles = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
physDev->handles,
physDev->handles_size * sizeof(physDev->handles[0]));
}
physDev->handles[index] = obj;
physDev->cur_handles++;
if(physDev->cur_handles > physDev->mh->mtNoObjects)
physDev->mh->mtNoObjects++;
return index ; /* index 0 is not reserved for metafiles */
}
/******************************************************************
* MFDRV_RemoveHandle
*/
BOOL MFDRV_RemoveHandle( PHYSDEV dev, UINT index )
{
METAFILEDRV_PDEVICE *physDev = (METAFILEDRV_PDEVICE *)dev;
BOOL ret = FALSE;
if (index < physDev->handles_size && physDev->handles[index])
{
physDev->handles[index] = 0;
physDev->cur_handles--;
ret = TRUE;
}
return ret;
}
/******************************************************************
* MFDRV_FindObject
*/
static INT16 MFDRV_FindObject( PHYSDEV dev, HGDIOBJ obj )
{
METAFILEDRV_PDEVICE *physDev = (METAFILEDRV_PDEVICE *)dev;
INT16 index;
for(index = 0; index < physDev->handles_size; index++)
if(physDev->handles[index] == obj) break;
if(index == physDev->handles_size) return -1;
return index ;
}
/******************************************************************
* MFDRV_DeleteObject
*/
BOOL CDECL MFDRV_DeleteObject( PHYSDEV dev, HGDIOBJ obj )
{
METARECORD mr;
METAFILEDRV_PDEVICE *physDev = (METAFILEDRV_PDEVICE *)dev;
INT16 index;
BOOL ret = TRUE;
index = MFDRV_FindObject(dev, obj);
if( index < 0 )
return 0;
mr.rdSize = sizeof mr / 2;
mr.rdFunction = META_DELETEOBJECT;
mr.rdParm[0] = index;
if(!MFDRV_WriteRecord( dev, &mr, mr.rdSize*2 ))
ret = FALSE;
physDev->handles[index] = 0;
physDev->cur_handles--;
return ret;
}
/***********************************************************************
* MFDRV_SelectObject
*/
static BOOL MFDRV_SelectObject( PHYSDEV dev, INT16 index)
{
METARECORD mr;
mr.rdSize = sizeof mr / 2;
mr.rdFunction = META_SELECTOBJECT;
mr.rdParm[0] = index;
return MFDRV_WriteRecord( dev, &mr, mr.rdSize*2 );
}
/***********************************************************************
* MFDRV_SelectBitmap
*/
HBITMAP CDECL MFDRV_SelectBitmap( PHYSDEV dev, HBITMAP hbitmap )
{
return 0;
}
/***********************************************************************
* Internal helper for MFDRV_CreateBrushIndirect():
* Change the padding of a bitmap from 16 (BMP) to 32 (DIB) bits.
*/
static inline void MFDRV_PadTo32(LPBYTE lpRows, int height, int width)
{
int bytes16 = 2 * ((width + 15) / 16);
int bytes32 = 4 * ((width + 31) / 32);
LPBYTE lpSrc, lpDst;
int i;
if (!height)
return;
height = abs(height) - 1;
lpSrc = lpRows + height * bytes16;
lpDst = lpRows + height * bytes32;
/* Note that we work backwards so we can re-pad in place */
while (height >= 0)
{
for (i = bytes32; i > bytes16; i--)
lpDst[i - 1] = 0; /* Zero the padding bytes */
for (; i > 0; i--)
lpDst[i - 1] = lpSrc[i - 1]; /* Move image bytes into alignment */
lpSrc -= bytes16;
lpDst -= bytes32;
height--;
}
}
/***********************************************************************
* Internal helper for MFDRV_CreateBrushIndirect():
* Reverse order of bitmap rows in going from BMP to DIB.
*/
static inline void MFDRV_Reverse(LPBYTE lpRows, int height, int width)
{
int bytes = 4 * ((width + 31) / 32);
LPBYTE lpSrc, lpDst;
BYTE temp;
int i;
if (!height)
return;
lpSrc = lpRows;
lpDst = lpRows + (height-1) * bytes;
height = height/2;
while (height > 0)
{
for (i = 0; i < bytes; i++)
{
temp = lpDst[i];
lpDst[i] = lpSrc[i];
lpSrc[i] = temp;
}
lpSrc += bytes;
lpDst -= bytes;
height--;
}
}
/******************************************************************
* MFDRV_CreateBrushIndirect
*/
INT16 MFDRV_CreateBrushIndirect(PHYSDEV dev, HBRUSH hBrush )
{
DWORD size;
METARECORD *mr;
LOGBRUSH logbrush;
METAFILEDRV_PDEVICE *physDev = (METAFILEDRV_PDEVICE *)dev;
BOOL r;
if (!GetObjectA( hBrush, sizeof(logbrush), &logbrush )) return -1;
switch(logbrush.lbStyle)
{
case BS_SOLID:
case BS_NULL:
case BS_HATCHED:
{
LOGBRUSH16 lb16;
lb16.lbStyle = logbrush.lbStyle;
lb16.lbColor = logbrush.lbColor;
lb16.lbHatch = logbrush.lbHatch;
size = sizeof(METARECORD) + sizeof(LOGBRUSH16) - 2;
mr = HeapAlloc( GetProcessHeap(), 0, size );
mr->rdSize = size / 2;
mr->rdFunction = META_CREATEBRUSHINDIRECT;
memcpy( mr->rdParm, &lb16, sizeof(LOGBRUSH16));
break;
}
case BS_PATTERN:
{
BITMAP bm;
BITMAPINFO *info;
DWORD bmSize;
COLORREF cref;
GetObjectA((HANDLE)logbrush.lbHatch, sizeof(bm), &bm);
if(bm.bmBitsPixel != 1 || bm.bmPlanes != 1) {
FIXME("Trying to store a colour pattern brush\n");
goto done;
}
bmSize = DIB_GetDIBImageBytes(bm.bmWidth, bm.bmHeight, DIB_PAL_COLORS);
size = sizeof(METARECORD) + sizeof(WORD) + sizeof(BITMAPINFO) +
sizeof(RGBQUAD) + bmSize;
mr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
if(!mr) goto done;
mr->rdFunction = META_DIBCREATEPATTERNBRUSH;
mr->rdSize = size / 2;
mr->rdParm[0] = BS_PATTERN;
mr->rdParm[1] = DIB_RGB_COLORS;
info = (BITMAPINFO *)(mr->rdParm + 2);
info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
info->bmiHeader.biWidth = bm.bmWidth;
info->bmiHeader.biHeight = bm.bmHeight;
info->bmiHeader.biPlanes = 1;
info->bmiHeader.biBitCount = 1;
info->bmiHeader.biSizeImage = bmSize;
GetBitmapBits((HANDLE)logbrush.lbHatch,
bm.bmHeight * BITMAP_GetWidthBytes (bm.bmWidth, bm.bmBitsPixel),
(LPBYTE)info + sizeof(BITMAPINFO) + sizeof(RGBQUAD));
/* Change the padding to be DIB compatible if needed */
if(bm.bmWidth & 31)
MFDRV_PadTo32((LPBYTE)info + sizeof(BITMAPINFO) + sizeof(RGBQUAD),
bm.bmWidth, bm.bmHeight);
/* BMP and DIB have opposite row order conventions */
MFDRV_Reverse((LPBYTE)info + sizeof(BITMAPINFO) + sizeof(RGBQUAD),
bm.bmWidth, bm.bmHeight);
cref = GetTextColor(physDev->hdc);
info->bmiColors[0].rgbRed = GetRValue(cref);
info->bmiColors[0].rgbGreen = GetGValue(cref);
info->bmiColors[0].rgbBlue = GetBValue(cref);
info->bmiColors[0].rgbReserved = 0;
cref = GetBkColor(physDev->hdc);
info->bmiColors[1].rgbRed = GetRValue(cref);
info->bmiColors[1].rgbGreen = GetGValue(cref);
info->bmiColors[1].rgbBlue = GetBValue(cref);
info->bmiColors[1].rgbReserved = 0;
break;
}
case BS_DIBPATTERN:
{
BITMAPINFO *info;
DWORD bmSize, biSize;
info = GlobalLock( (HGLOBAL)logbrush.lbHatch );
if (info->bmiHeader.biCompression)
bmSize = info->bmiHeader.biSizeImage;
else
bmSize = DIB_GetDIBImageBytes(info->bmiHeader.biWidth,
info->bmiHeader.biHeight,
info->bmiHeader.biBitCount);
biSize = bitmap_info_size(info, LOWORD(logbrush.lbColor));
size = sizeof(METARECORD) + biSize + bmSize + 2;
mr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
if (!mr)
{
GlobalUnlock( (HGLOBAL)logbrush.lbHatch );
goto done;
}
mr->rdFunction = META_DIBCREATEPATTERNBRUSH;
mr->rdSize = size / 2;
*(mr->rdParm) = logbrush.lbStyle;
*(mr->rdParm + 1) = LOWORD(logbrush.lbColor);
memcpy(mr->rdParm + 2, info, biSize + bmSize);
GlobalUnlock( (HGLOBAL)logbrush.lbHatch );
break;
}
default:
FIXME("Unkonwn brush style %x\n", logbrush.lbStyle);
return 0;
}
r = MFDRV_WriteRecord( dev, mr, mr->rdSize * 2);
HeapFree(GetProcessHeap(), 0, mr);
if( !r )
return -1;
done:
return MFDRV_AddHandle( dev, hBrush );
}
/***********************************************************************
* MFDRV_SelectBrush
*/
HBRUSH CDECL MFDRV_SelectBrush( PHYSDEV dev, HBRUSH hbrush )
{
METAFILEDRV_PDEVICE *physDev = (METAFILEDRV_PDEVICE *)dev;
INT16 index;
index = MFDRV_FindObject(dev, hbrush);
if( index < 0 )
{
index = MFDRV_CreateBrushIndirect( dev, hbrush );
if( index < 0 )
return 0;
GDI_hdc_using_object(hbrush, physDev->hdc);
}
return MFDRV_SelectObject( dev, index ) ? hbrush : HGDI_ERROR;
}
/******************************************************************
* MFDRV_CreateFontIndirect
*/
static UINT16 MFDRV_CreateFontIndirect(PHYSDEV dev, HFONT hFont, LOGFONTW *logfont)
{
char buffer[sizeof(METARECORD) - 2 + sizeof(LOGFONT16)];
METARECORD *mr = (METARECORD *)&buffer;
LOGFONT16 *font16;
INT written;
mr->rdSize = (sizeof(METARECORD) + sizeof(LOGFONT16) - 2) / 2;
mr->rdFunction = META_CREATEFONTINDIRECT;
font16 = (LOGFONT16 *)&mr->rdParm;
font16->lfHeight = logfont->lfHeight;
font16->lfWidth = logfont->lfWidth;
font16->lfEscapement = logfont->lfEscapement;
font16->lfOrientation = logfont->lfOrientation;
font16->lfWeight = logfont->lfWeight;
font16->lfItalic = logfont->lfItalic;
font16->lfUnderline = logfont->lfUnderline;
font16->lfStrikeOut = logfont->lfStrikeOut;
font16->lfCharSet = logfont->lfCharSet;
font16->lfOutPrecision = logfont->lfOutPrecision;
font16->lfClipPrecision = logfont->lfClipPrecision;
font16->lfQuality = logfont->lfQuality;
font16->lfPitchAndFamily = logfont->lfPitchAndFamily;
written = WideCharToMultiByte( CP_ACP, 0, logfont->lfFaceName, -1, font16->lfFaceName, LF_FACESIZE - 1, NULL, NULL );
/* Zero pad the facename buffer, so that we don't write uninitialized data to disk */
memset(font16->lfFaceName + written, 0, LF_FACESIZE - written);
if (!(MFDRV_WriteRecord( dev, mr, mr->rdSize * 2)))
return 0;
return MFDRV_AddHandle( dev, hFont );
}
/***********************************************************************
* MFDRV_SelectFont
*/
HFONT CDECL MFDRV_SelectFont( PHYSDEV dev, HFONT hfont, HANDLE gdiFont )
{
METAFILEDRV_PDEVICE *physDev = (METAFILEDRV_PDEVICE *)dev;
LOGFONTW font;
INT16 index;
index = MFDRV_FindObject(dev, hfont);
if( index < 0 )
{
if (!GetObjectW( hfont, sizeof(font), &font ))
return HGDI_ERROR;
index = MFDRV_CreateFontIndirect(dev, hfont, &font);
if( index < 0 )
return HGDI_ERROR;
GDI_hdc_using_object(hfont, physDev->hdc);
}
return MFDRV_SelectObject( dev, index ) ? hfont : HGDI_ERROR;
}
/******************************************************************
* MFDRV_CreatePenIndirect
*/
static UINT16 MFDRV_CreatePenIndirect(PHYSDEV dev, HPEN hPen, LOGPEN16 *logpen)
{
char buffer[sizeof(METARECORD) - 2 + sizeof(*logpen)];
METARECORD *mr = (METARECORD *)&buffer;
mr->rdSize = (sizeof(METARECORD) + sizeof(*logpen) - 2) / 2;
mr->rdFunction = META_CREATEPENINDIRECT;
memcpy(&(mr->rdParm), logpen, sizeof(*logpen));
if (!(MFDRV_WriteRecord( dev, mr, mr->rdSize * 2)))
return 0;
return MFDRV_AddHandle( dev, hPen );
}
/***********************************************************************
* MFDRV_SelectPen
*/
HPEN CDECL MFDRV_SelectPen( PHYSDEV dev, HPEN hpen )
{
METAFILEDRV_PDEVICE *physDev = (METAFILEDRV_PDEVICE *)dev;
LOGPEN16 logpen;
INT16 index;
index = MFDRV_FindObject(dev, hpen);
if( index < 0 )
{
/* must be an extended pen */
INT size = GetObjectW( hpen, 0, NULL );
if (!size) return 0;
if (size == sizeof(LOGPEN))
{
LOGPEN pen;
GetObjectW( hpen, sizeof(pen), &pen );
logpen.lopnStyle = pen.lopnStyle;
logpen.lopnWidth.x = pen.lopnWidth.x;
logpen.lopnWidth.y = pen.lopnWidth.y;
logpen.lopnColor = pen.lopnColor;
}
else /* must be an extended pen */
{
EXTLOGPEN *elp = HeapAlloc( GetProcessHeap(), 0, size );
GetObjectW( hpen, size, elp );
/* FIXME: add support for user style pens */
logpen.lopnStyle = elp->elpPenStyle;
logpen.lopnWidth.x = elp->elpWidth;
logpen.lopnWidth.y = 0;
logpen.lopnColor = elp->elpColor;
HeapFree( GetProcessHeap(), 0, elp );
}
index = MFDRV_CreatePenIndirect( dev, hpen, &logpen );
if( index < 0 )
return 0;
GDI_hdc_using_object(hpen, physDev->hdc);
}
return MFDRV_SelectObject( dev, index ) ? hpen : HGDI_ERROR;
}
/******************************************************************
* MFDRV_CreatePalette
*/
static BOOL MFDRV_CreatePalette(PHYSDEV dev, HPALETTE hPalette, LOGPALETTE* logPalette, int sizeofPalette)
{
int index;
BOOL ret;
METARECORD *mr;
mr = HeapAlloc( GetProcessHeap(), 0, sizeof(METARECORD) + sizeofPalette - sizeof(WORD) );
mr->rdSize = (sizeof(METARECORD) + sizeofPalette - sizeof(WORD)) / sizeof(WORD);
mr->rdFunction = META_CREATEPALETTE;
memcpy(&(mr->rdParm), logPalette, sizeofPalette);
if (!(MFDRV_WriteRecord( dev, mr, mr->rdSize * sizeof(WORD))))
{
HeapFree(GetProcessHeap(), 0, mr);
return FALSE;
}
mr->rdSize = sizeof(METARECORD) / sizeof(WORD);
mr->rdFunction = META_SELECTPALETTE;
if ((index = MFDRV_AddHandle( dev, hPalette )) == -1) ret = FALSE;
else
{
*(mr->rdParm) = index;
ret = MFDRV_WriteRecord( dev, mr, mr->rdSize * sizeof(WORD));
}
HeapFree(GetProcessHeap(), 0, mr);
return ret;
}
/***********************************************************************
* MFDRV_SelectPalette
*/
HPALETTE CDECL MFDRV_SelectPalette( PHYSDEV dev, HPALETTE hPalette, BOOL bForceBackground )
{
#define PALVERSION 0x0300
PLOGPALETTE logPalette;
WORD wNumEntries = 0;
BOOL creationSucceed;
int sizeofPalette;
GetObjectA(hPalette, sizeof(WORD), &wNumEntries);
if (wNumEntries == 0) return 0;
sizeofPalette = sizeof(LOGPALETTE) + ((wNumEntries-1) * sizeof(PALETTEENTRY));
logPalette = HeapAlloc( GetProcessHeap(), 0, sizeofPalette );
if (logPalette == NULL) return 0;
logPalette->palVersion = PALVERSION;
logPalette->palNumEntries = wNumEntries;
GetPaletteEntries(hPalette, 0, wNumEntries, logPalette->palPalEntry);
creationSucceed = MFDRV_CreatePalette( dev, hPalette, logPalette, sizeofPalette );
HeapFree( GetProcessHeap(), 0, logPalette );
if (creationSucceed)
return hPalette;
return 0;
}
/***********************************************************************
* MFDRV_RealizePalette
*/
UINT CDECL MFDRV_RealizePalette(PHYSDEV dev, HPALETTE hPalette, BOOL dummy)
{
char buffer[sizeof(METARECORD) - sizeof(WORD)];
METARECORD *mr = (METARECORD *)&buffer;
mr->rdSize = (sizeof(METARECORD) - sizeof(WORD)) / sizeof(WORD);
mr->rdFunction = META_REALIZEPALETTE;
if (!(MFDRV_WriteRecord( dev, mr, mr->rdSize * sizeof(WORD)))) return 0;
/* The return value is suppose to be the number of entries
in the logical palette mapped to the system palette or 0
if the function failed. Since it's not trivial here to
get that kind of information and since it's of little
use in the case of metafiles, we'll always return 1. */
return 1;
}

View File

@@ -0,0 +1,156 @@
/*
* metafile driver text functions
*
* Copyright 1993, 1994 Alexandre Julliard
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <stdarg.h>
#include <string.h>
#include "windef.h"
#include "winbase.h"
#include "wine/wingdi16.h"
#include "mfdrv/metafiledrv.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(metafile);
/******************************************************************
* MFDRV_MetaExtTextOut
*/
static BOOL MFDRV_MetaExtTextOut( PHYSDEV dev, short x, short y, UINT16 flags,
const RECT16 *rect, LPCSTR str, short count,
const INT16 *lpDx)
{
BOOL ret;
DWORD len;
METARECORD *mr;
BOOL isrect = flags & (ETO_CLIPPED | ETO_OPAQUE);
len = sizeof(METARECORD) + (((count + 1) >> 1) * 2) + 2 * sizeof(short)
+ sizeof(UINT16);
if (isrect)
len += sizeof(RECT16);
if (lpDx)
len+=count*sizeof(INT16);
if (!(mr = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, len)))
return FALSE;
mr->rdSize = len / 2;
mr->rdFunction = META_EXTTEXTOUT;
*(mr->rdParm) = y;
*(mr->rdParm + 1) = x;
*(mr->rdParm + 2) = count;
*(mr->rdParm + 3) = flags;
if (isrect) memcpy(mr->rdParm + 4, rect, sizeof(RECT16));
memcpy(mr->rdParm + (isrect ? 8 : 4), str, count);
if (lpDx)
memcpy(mr->rdParm + (isrect ? 8 : 4) + ((count + 1) >> 1),lpDx,
count*sizeof(INT16));
ret = MFDRV_WriteRecord( dev, mr, mr->rdSize * 2);
HeapFree( GetProcessHeap(), 0, mr);
return ret;
}
/***********************************************************************
* MFDRV_ExtTextOut
*/
BOOL CDECL
MFDRV_ExtTextOut( PHYSDEV dev, INT x, INT y, UINT flags,
const RECT *lprect, LPCWSTR str, UINT count,
const INT *lpDx )
{
RECT16 rect16;
LPINT16 lpdx16 = NULL;
BOOL ret;
unsigned int i, j;
LPSTR ascii;
DWORD len;
CHARSETINFO csi;
METAFILEDRV_PDEVICE *physDev = (METAFILEDRV_PDEVICE *)dev;
int charset = GetTextCharset(physDev->hdc);
UINT cp = CP_ACP;
if(TranslateCharsetInfo(ULongToPtr(charset), &csi, TCI_SRCCHARSET))
cp = csi.ciACP;
else {
switch(charset) {
case OEM_CHARSET:
cp = GetOEMCP();
break;
case DEFAULT_CHARSET:
cp = GetACP();
break;
case VISCII_CHARSET:
case TCVN_CHARSET:
case KOI8_CHARSET:
case ISO3_CHARSET:
case ISO4_CHARSET:
case ISO10_CHARSET:
case CELTIC_CHARSET:
/* FIXME: These have no place here, but because x11drv
enumerates fonts with these (made up) charsets some apps
might use them and then the FIXME below would become
annoying. Now we could pick the intended codepage for
each of these, but since it's broken anyway we'll just
use CP_ACP and hope it'll go away...
*/
cp = CP_ACP;
break;
default:
FIXME("Can't find codepage for charset %d\n", charset);
break;
}
}
TRACE("cp == %d\n", cp);
len = WideCharToMultiByte(cp, 0, str, count, NULL, 0, NULL, NULL);
ascii = HeapAlloc(GetProcessHeap(), 0, len);
WideCharToMultiByte(cp, 0, str, count, ascii, len, NULL, NULL);
TRACE("mapped %s -> %s\n", debugstr_wn(str, count), debugstr_an(ascii, len));
if (lprect)
{
rect16.left = lprect->left;
rect16.top = lprect->top;
rect16.right = lprect->right;
rect16.bottom = lprect->bottom;
}
if(lpDx) {
lpdx16 = HeapAlloc( GetProcessHeap(), 0, sizeof(INT16)*len );
for(i = j = 0; i < len; )
if(IsDBCSLeadByteEx(cp, ascii[i])) {
lpdx16[i++] = lpDx[j++];
lpdx16[i++] = 0;
} else
lpdx16[i++] = lpDx[j++];
}
ret = MFDRV_MetaExtTextOut(dev,x,y,flags,lprect?&rect16:NULL,ascii,len,lpdx16);
HeapFree( GetProcessHeap(), 0, ascii );
HeapFree( GetProcessHeap(), 0, lpdx16 );
return ret;
}

View File

@@ -0,0 +1,428 @@
/*
* OpenGL function forwarding to the display driver
*
* Copyright (c) 1999 Lionel Ulmer
* Copyright (c) 2005 Raphael Junqueira
* Copyright (c) 2006 Roderick Colenbrander
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "config.h"
#include "wine/port.h"
#include <stdarg.h>
#include <string.h>
#include <stdlib.h>
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winerror.h"
#include "wine/winternl.h"
#include "winnt.h"
#include "gdi_private.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(wgl);
static HDC default_hdc = 0;
typedef struct opengl_context
{
HDC hdc;
} *OPENGL_Context;
/* We route all wgl functions from opengl32.dll through gdi32.dll to
* the display driver. Various wgl calls have a hDC as one of their parameters.
* Using get_dc_ptr we get access to the functions exported by the driver.
* Some functions don't receive a hDC. This function creates a global hdc and
* if there's already a global hdc, it returns it.
*/
static DC* OPENGL_GetDefaultDC(void)
{
if(!default_hdc)
default_hdc = CreateDCA("DISPLAY", NULL, NULL, NULL);
return get_dc_ptr(default_hdc);
}
/***********************************************************************
* wglCopyContext (OPENGL32.@)
*/
BOOL WINAPI wglCopyContext(HGLRC hglrcSrc, HGLRC hglrcDst, UINT mask)
{
DC *dc;
BOOL ret = FALSE;
OPENGL_Context ctx = (OPENGL_Context)hglrcSrc;
TRACE("hglrcSrc: (%p), hglrcDst: (%p), mask: %#x\n", hglrcSrc, hglrcDst, mask);
/* If no context is set, this call doesn't have a purpose */
if(!hglrcSrc || !hglrcDst)
return FALSE;
/* Retrieve the HDC associated with the context to access the display driver */
dc = get_dc_ptr(ctx->hdc);
if (!dc) return FALSE;
if (!dc->funcs->pwglCopyContext) FIXME(" :stub\n");
else ret = dc->funcs->pwglCopyContext(hglrcSrc, hglrcDst, mask);
release_dc_ptr( dc );
return ret;
}
/***********************************************************************
* wglCreateContext (OPENGL32.@)
*/
HGLRC WINAPI wglCreateContext(HDC hdc)
{
HGLRC ret = 0;
DC * dc = get_dc_ptr( hdc );
TRACE("(%p)\n",hdc);
if (!dc) return 0;
update_dc( dc );
if (!dc->funcs->pwglCreateContext) FIXME(" :stub\n");
else ret = dc->funcs->pwglCreateContext(dc->physDev);
release_dc_ptr( dc );
return ret;
}
/***********************************************************************
* wglCreateContextAttribsARB
*/
static HGLRC WINAPI wglCreateContextAttribsARB(HDC hdc, HGLRC hShareContext, const int *attributeList)
{
HGLRC ret = 0;
DC * dc = get_dc_ptr( hdc );
TRACE("(%p)\n",hdc);
if (!dc) return 0;
update_dc( dc );
if (!dc->funcs->pwglCreateContextAttribsARB) FIXME(" :stub\n");
else ret = dc->funcs->pwglCreateContextAttribsARB(dc->physDev, hShareContext, attributeList);
release_dc_ptr( dc );
return ret;
}
/***********************************************************************
* wglDeleteContext (OPENGL32.@)
*/
BOOL WINAPI wglDeleteContext(HGLRC hglrc)
{
DC *dc;
BOOL ret = FALSE;
OPENGL_Context ctx = (OPENGL_Context)hglrc;
TRACE("hglrc: (%p)\n", hglrc);
if(ctx == NULL)
{
SetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
/* Retrieve the HDC associated with the context to access the display driver */
dc = get_dc_ptr(ctx->hdc);
if (!dc)
{
SetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
if (!dc->funcs->pwglDeleteContext) FIXME(" :stub\n");
else ret = dc->funcs->pwglDeleteContext(hglrc);
release_dc_ptr( dc );
return ret;
}
/***********************************************************************
* wglGetCurrentContext (OPENGL32.@)
*/
HGLRC WINAPI wglGetCurrentContext(void)
{
HGLRC ret = NtCurrentTeb()->glContext;
TRACE(" returning %p\n", ret);
return ret;
}
/***********************************************************************
* wglGetCurrentDC (OPENGL32.@)
*/
HDC WINAPI wglGetCurrentDC(void)
{
OPENGL_Context ctx = (OPENGL_Context)wglGetCurrentContext();
TRACE(" found context: %p\n", ctx);
if(ctx == NULL)
return NULL;
/* Retrieve the current DC from the active context */
TRACE(" returning hdc: %p\n", ctx->hdc);
return ctx->hdc;
}
/***********************************************************************
* wglGetPbufferDCARB
*/
static HDC WINAPI wglGetPbufferDCARB(void *pbuffer)
{
HDC ret = 0;
/* Create a device context to associate with the pbuffer */
HDC hdc = CreateDCA("DISPLAY", NULL, NULL, NULL);
DC *dc = get_dc_ptr(hdc);
TRACE("(%p)\n", pbuffer);
if (!dc) return 0;
/* The display driver has to do the rest of the work because
* we need access to lowlevel datatypes which we can't access here
*/
if (!dc->funcs->pwglGetPbufferDCARB) FIXME(" :stub\n");
else ret = dc->funcs->pwglGetPbufferDCARB(dc->physDev, pbuffer);
TRACE("(%p), hdc=%p\n", pbuffer, ret);
release_dc_ptr( dc );
return ret;
}
/***********************************************************************
* wglMakeCurrent (OPENGL32.@)
*/
BOOL WINAPI wglMakeCurrent(HDC hdc, HGLRC hglrc)
{
BOOL ret = FALSE;
DC * dc = NULL;
/* When the context hglrc is NULL, the HDC is ignored and can be NULL.
* In that case use the global hDC to get access to the driver. */
if(hglrc == NULL)
{
if( hdc == NULL && !wglGetCurrentContext() )
{
WARN( "Current context is NULL\n");
SetLastError( ERROR_INVALID_HANDLE );
return FALSE;
}
dc = OPENGL_GetDefaultDC();
}
else
dc = get_dc_ptr( hdc );
TRACE("hdc: (%p), hglrc: (%p)\n", hdc, hglrc);
if (!dc) return FALSE;
update_dc( dc );
if (!dc->funcs->pwglMakeCurrent) FIXME(" :stub\n");
else ret = dc->funcs->pwglMakeCurrent(dc->physDev,hglrc);
release_dc_ptr( dc );
return ret;
}
/***********************************************************************
* wglMakeContextCurrentARB
*/
static BOOL WINAPI wglMakeContextCurrentARB(HDC hDrawDC, HDC hReadDC, HGLRC hglrc)
{
BOOL ret = FALSE;
DC *DrawDC;
DC *ReadDC;
TRACE("hDrawDC: (%p), hReadDC: (%p) hglrc: (%p)\n", hDrawDC, hReadDC, hglrc);
/* Both hDrawDC and hReadDC need to be valid */
DrawDC = get_dc_ptr( hDrawDC );
if (!DrawDC) return FALSE;
ReadDC = get_dc_ptr( hReadDC );
if (!ReadDC) {
release_dc_ptr( DrawDC );
return FALSE;
}
update_dc( DrawDC );
update_dc( ReadDC );
if (!DrawDC->funcs->pwglMakeContextCurrentARB) FIXME(" :stub\n");
else ret = DrawDC->funcs->pwglMakeContextCurrentARB(DrawDC->physDev, ReadDC->physDev, hglrc);
release_dc_ptr( DrawDC );
release_dc_ptr( ReadDC );
return ret;
}
/**************************************************************************************
* WINE-specific wglSetPixelFormat which can set the iPixelFormat multiple times
*
*/
static BOOL WINAPI wglSetPixelFormatWINE(HDC hdc, int iPixelFormat, const PIXELFORMATDESCRIPTOR *ppfd)
{
INT bRet = FALSE;
DC * dc = get_dc_ptr( hdc );
TRACE("(%p,%d,%p)\n", hdc, iPixelFormat, ppfd);
if (!dc) return 0;
update_dc( dc );
if (!dc->funcs->pwglSetPixelFormatWINE) FIXME(" :stub\n");
else bRet = dc->funcs->pwglSetPixelFormatWINE(dc->physDev, iPixelFormat, ppfd);
release_dc_ptr( dc );
return bRet;
}
/***********************************************************************
* wglShareLists (OPENGL32.@)
*/
BOOL WINAPI wglShareLists(HGLRC hglrc1, HGLRC hglrc2)
{
DC *dc;
BOOL ret = FALSE;
OPENGL_Context ctx = (OPENGL_Context)hglrc1;
TRACE("hglrc1: (%p); hglrc: (%p)\n", hglrc1, hglrc2);
if(ctx == NULL || hglrc2 == NULL)
return FALSE;
/* Retrieve the HDC associated with the context to access the display driver */
dc = get_dc_ptr(ctx->hdc);
if (!dc) return FALSE;
if (!dc->funcs->pwglShareLists) FIXME(" :stub\n");
else ret = dc->funcs->pwglShareLists(hglrc1, hglrc2);
release_dc_ptr( dc );
return ret;
}
/***********************************************************************
* wglUseFontBitmapsA (OPENGL32.@)
*/
BOOL WINAPI wglUseFontBitmapsA(HDC hdc, DWORD first, DWORD count, DWORD listBase)
{
BOOL ret = FALSE;
DC * dc = get_dc_ptr( hdc );
TRACE("(%p, %d, %d, %d)\n", hdc, first, count, listBase);
if (!dc) return FALSE;
if (!dc->funcs->pwglUseFontBitmapsA) FIXME(" :stub\n");
else ret = dc->funcs->pwglUseFontBitmapsA(dc->physDev, first, count, listBase);
release_dc_ptr( dc );
return ret;
}
/***********************************************************************
* wglUseFontBitmapsW (OPENGL32.@)
*/
BOOL WINAPI wglUseFontBitmapsW(HDC hdc, DWORD first, DWORD count, DWORD listBase)
{
BOOL ret = FALSE;
DC * dc = get_dc_ptr( hdc );
TRACE("(%p, %d, %d, %d)\n", hdc, first, count, listBase);
if (!dc) return FALSE;
if (!dc->funcs->pwglUseFontBitmapsW) FIXME(" :stub\n");
else ret = dc->funcs->pwglUseFontBitmapsW(dc->physDev, first, count, listBase);
release_dc_ptr( dc );
return ret;
}
/***********************************************************************
* Internal wglGetProcAddress for retrieving WGL extensions
*/
PROC WINAPI wglGetProcAddress(LPCSTR func)
{
PROC ret = NULL;
DC *dc;
if(!func)
return NULL;
TRACE("func: '%s'\n", func);
/* Retrieve the global hDC to get access to the driver. */
dc = OPENGL_GetDefaultDC();
if (!dc) return NULL;
if (!dc->funcs->pwglGetProcAddress) FIXME(" :stub\n");
else ret = dc->funcs->pwglGetProcAddress(func);
release_dc_ptr( dc );
/* At the moment we implement one WGL extension which requires a HDC. When we
* are looking up this call and when the Extension is available (that is the case
* when a non-NULL value is returned by wglGetProcAddress), we return the address
* of a wrapper function which will handle the HDC->PhysDev conversion.
*/
if(ret && strcmp(func, "wglCreateContextAttribsARB") == 0)
return (PROC)wglCreateContextAttribsARB;
else if(ret && strcmp(func, "wglMakeContextCurrentARB") == 0)
return (PROC)wglMakeContextCurrentARB;
else if(ret && strcmp(func, "wglGetPbufferDCARB") == 0)
return (PROC)wglGetPbufferDCARB;
else if(ret && strcmp(func, "wglSetPixelFormatWINE") == 0)
return (PROC)wglSetPixelFormatWINE;
return ret;
}
INT
WINAPI
GdiDescribePixelFormat(
HDC hdc,
INT ipfd,
UINT cjpfd,
PPIXELFORMATDESCRIPTOR ppfd)
{
UNIMPLEMENTED;
return 0;
}
BOOL
WINAPI
GdiSetPixelFormat(
HDC hdc,
INT ipfd)
{
UNIMPLEMENTED;
return FALSE;
}
BOOL
WINAPI
GdiSwapBuffers(
HDC hdc)
{
UNIMPLEMENTED;
return FALSE;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,837 @@
/*
* GDI palette objects
*
* Copyright 1993,1994 Alexandre Julliard
* Copyright 1996 Alex Korobka
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*
* NOTES:
* PALETTEOBJ is documented in the Dr. Dobbs Journal May 1993.
* Information in the "Undocumented Windows" is incorrect.
*/
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include "windef.h"
#include "winbase.h"
#include "winerror.h"
#include "wingdi.h"
#include "winuser.h"
#include "gdi_private.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(palette);
typedef struct tagPALETTEOBJ
{
GDIOBJHDR header;
const DC_FUNCTIONS *funcs; /* DC function table */
WORD version; /* palette version */
WORD count; /* count of palette entries */
PALETTEENTRY *entries;
} PALETTEOBJ;
static INT PALETTE_GetObject( HGDIOBJ handle, INT count, LPVOID buffer );
static BOOL PALETTE_UnrealizeObject( HGDIOBJ handle );
static BOOL PALETTE_DeleteObject( HGDIOBJ handle );
static const struct gdi_obj_funcs palette_funcs =
{
NULL, /* pSelectObject */
PALETTE_GetObject, /* pGetObjectA */
PALETTE_GetObject, /* pGetObjectW */
PALETTE_UnrealizeObject, /* pUnrealizeObject */
PALETTE_DeleteObject /* pDeleteObject */
};
/* Pointers to USER implementation of SelectPalette/RealizePalette */
/* they will be patched by USER on startup */
HPALETTE (WINAPI *pfnSelectPalette)(HDC hdc, HPALETTE hpal, WORD bkgnd ) = GDISelectPalette;
UINT (WINAPI *pfnRealizePalette)(HDC hdc) = GDIRealizePalette;
static UINT SystemPaletteUse = SYSPAL_STATIC; /* currently not considered */
static HPALETTE hPrimaryPalette = 0; /* used for WM_PALETTECHANGED */
static HPALETTE hLastRealizedPalette = 0; /* UnrealizeObject() needs it */
#define NB_RESERVED_COLORS 20 /* number of fixed colors in system palette */
static const PALETTEENTRY sys_pal_template[NB_RESERVED_COLORS] =
{
/* first 10 entries in the system palette */
/* red green blue flags */
{ 0x00, 0x00, 0x00, 0 },
{ 0x80, 0x00, 0x00, 0 },
{ 0x00, 0x80, 0x00, 0 },
{ 0x80, 0x80, 0x00, 0 },
{ 0x00, 0x00, 0x80, 0 },
{ 0x80, 0x00, 0x80, 0 },
{ 0x00, 0x80, 0x80, 0 },
{ 0xc0, 0xc0, 0xc0, 0 },
{ 0xc0, 0xdc, 0xc0, 0 },
{ 0xa6, 0xca, 0xf0, 0 },
/* ... c_min/2 dynamic colorcells */
/* ... gap (for sparse palettes) */
/* ... c_min/2 dynamic colorcells */
{ 0xff, 0xfb, 0xf0, 0 },
{ 0xa0, 0xa0, 0xa4, 0 },
{ 0x80, 0x80, 0x80, 0 },
{ 0xff, 0x00, 0x00, 0 },
{ 0x00, 0xff, 0x00, 0 },
{ 0xff, 0xff, 0x00, 0 },
{ 0x00, 0x00, 0xff, 0 },
{ 0xff, 0x00, 0xff, 0 },
{ 0x00, 0xff, 0xff, 0 },
{ 0xff, 0xff, 0xff, 0 } /* last 10 */
};
/***********************************************************************
* PALETTE_Init
*
* Create the system palette.
*/
HPALETTE PALETTE_Init(void)
{
HPALETTE hpalette;
LOGPALETTE * palPtr;
/* create default palette (20 system colors) */
palPtr = HeapAlloc( GetProcessHeap(), 0,
sizeof(LOGPALETTE) + (NB_RESERVED_COLORS-1)*sizeof(PALETTEENTRY));
if (!palPtr) return FALSE;
palPtr->palVersion = 0x300;
palPtr->palNumEntries = NB_RESERVED_COLORS;
memcpy( palPtr->palPalEntry, sys_pal_template, sizeof(sys_pal_template) );
hpalette = CreatePalette( palPtr );
HeapFree( GetProcessHeap(), 0, palPtr );
return hpalette;
}
/***********************************************************************
* CreatePalette [GDI32.@]
*
* Creates a logical color palette.
*
* RETURNS
* Success: Handle to logical palette
* Failure: NULL
*/
HPALETTE WINAPI CreatePalette(
const LOGPALETTE* palette) /* [in] Pointer to logical color palette */
{
PALETTEOBJ * palettePtr;
HPALETTE hpalette;
int size;
if (!palette) return 0;
TRACE("entries=%i\n", palette->palNumEntries);
size = sizeof(LOGPALETTE) + (palette->palNumEntries - 1) * sizeof(PALETTEENTRY);
if (!(palettePtr = HeapAlloc( GetProcessHeap(), 0, sizeof(*palettePtr) ))) return 0;
palettePtr->funcs = NULL;
palettePtr->version = palette->palVersion;
palettePtr->count = palette->palNumEntries;
size = palettePtr->count * sizeof(*palettePtr->entries);
if (!(palettePtr->entries = HeapAlloc( GetProcessHeap(), 0, size )))
{
HeapFree( GetProcessHeap(), 0, palettePtr );
return 0;
}
memcpy( palettePtr->entries, palette->palPalEntry, size );
if (!(hpalette = alloc_gdi_handle( &palettePtr->header, OBJ_PAL, &palette_funcs )))
{
HeapFree( GetProcessHeap(), 0, palettePtr->entries );
HeapFree( GetProcessHeap(), 0, palettePtr );
}
TRACE(" returning %p\n", hpalette);
return hpalette;
}
/***********************************************************************
* CreateHalftonePalette [GDI32.@]
*
* Creates a halftone palette.
*
* RETURNS
* Success: Handle to logical halftone palette
* Failure: 0
*
* FIXME: This simply creates the halftone palette derived from running
* tests on a windows NT machine. This is assuming a color depth
* of greater that 256 color. On a 256 color device the halftone
* palette will be different and this function will be incorrect
*/
HPALETTE WINAPI CreateHalftonePalette(
HDC hdc) /* [in] Handle to device context */
{
int i;
struct {
WORD Version;
WORD NumberOfEntries;
PALETTEENTRY aEntries[256];
} Palette;
Palette.Version = 0x300;
Palette.NumberOfEntries = 256;
GetSystemPaletteEntries(hdc, 0, 256, Palette.aEntries);
Palette.NumberOfEntries = 20;
for (i = 0; i < Palette.NumberOfEntries; i++)
{
Palette.aEntries[i].peRed=0xff;
Palette.aEntries[i].peGreen=0xff;
Palette.aEntries[i].peBlue=0xff;
Palette.aEntries[i].peFlags=0x00;
}
Palette.aEntries[0].peRed=0x00;
Palette.aEntries[0].peBlue=0x00;
Palette.aEntries[0].peGreen=0x00;
/* the first 6 */
for (i=1; i <= 6; i++)
{
Palette.aEntries[i].peRed=(i%2)?0x80:0;
Palette.aEntries[i].peGreen=(i==2)?0x80:(i==3)?0x80:(i==6)?0x80:0;
Palette.aEntries[i].peBlue=(i>3)?0x80:0;
}
for (i=7; i <= 12; i++)
{
switch(i)
{
case 7:
Palette.aEntries[i].peRed=0xc0;
Palette.aEntries[i].peBlue=0xc0;
Palette.aEntries[i].peGreen=0xc0;
break;
case 8:
Palette.aEntries[i].peRed=0xc0;
Palette.aEntries[i].peGreen=0xdc;
Palette.aEntries[i].peBlue=0xc0;
break;
case 9:
Palette.aEntries[i].peRed=0xa6;
Palette.aEntries[i].peGreen=0xca;
Palette.aEntries[i].peBlue=0xf0;
break;
case 10:
Palette.aEntries[i].peRed=0xff;
Palette.aEntries[i].peGreen=0xfb;
Palette.aEntries[i].peBlue=0xf0;
break;
case 11:
Palette.aEntries[i].peRed=0xa0;
Palette.aEntries[i].peGreen=0xa0;
Palette.aEntries[i].peBlue=0xa4;
break;
case 12:
Palette.aEntries[i].peRed=0x80;
Palette.aEntries[i].peGreen=0x80;
Palette.aEntries[i].peBlue=0x80;
}
}
for (i=13; i <= 18; i++)
{
Palette.aEntries[i].peRed=(i%2)?0xff:0;
Palette.aEntries[i].peGreen=(i==14)?0xff:(i==15)?0xff:(i==18)?0xff:0;
Palette.aEntries[i].peBlue=(i>15)?0xff:0x00;
}
return CreatePalette((LOGPALETTE *)&Palette);
}
/***********************************************************************
* GetPaletteEntries [GDI32.@]
*
* Retrieves palette entries.
*
* RETURNS
* Success: Number of entries from logical palette
* Failure: 0
*/
UINT WINAPI GetPaletteEntries(
HPALETTE hpalette, /* [in] Handle of logical palette */
UINT start, /* [in] First entry to receive */
UINT count, /* [in] Number of entries to receive */
LPPALETTEENTRY entries) /* [out] Address of array receiving entries */
{
PALETTEOBJ * palPtr;
UINT numEntries;
TRACE("hpal = %p, count=%i\n", hpalette, count );
palPtr = GDI_GetObjPtr( hpalette, OBJ_PAL );
if (!palPtr) return 0;
/* NOTE: not documented but test show this to be the case */
if (count == 0)
{
count = palPtr->count;
}
else
{
numEntries = palPtr->count;
if (start+count > numEntries) count = numEntries - start;
if (entries)
{
if (start >= numEntries) count = 0;
else memcpy( entries, &palPtr->entries[start], count * sizeof(PALETTEENTRY) );
}
}
GDI_ReleaseObj( hpalette );
return count;
}
/***********************************************************************
* SetPaletteEntries [GDI32.@]
*
* Sets color values for range in palette.
*
* RETURNS
* Success: Number of entries that were set
* Failure: 0
*/
UINT WINAPI SetPaletteEntries(
HPALETTE hpalette, /* [in] Handle of logical palette */
UINT start, /* [in] Index of first entry to set */
UINT count, /* [in] Number of entries to set */
const PALETTEENTRY *entries) /* [in] Address of array of structures */
{
PALETTEOBJ * palPtr;
UINT numEntries;
TRACE("hpal=%p,start=%i,count=%i\n",hpalette,start,count );
if (hpalette == GetStockObject(DEFAULT_PALETTE)) return 0;
palPtr = GDI_GetObjPtr( hpalette, OBJ_PAL );
if (!palPtr) return 0;
numEntries = palPtr->count;
if (start >= numEntries)
{
GDI_ReleaseObj( hpalette );
return 0;
}
if (start+count > numEntries) count = numEntries - start;
memcpy( &palPtr->entries[start], entries, count * sizeof(PALETTEENTRY) );
GDI_ReleaseObj( hpalette );
UnrealizeObject( hpalette );
return count;
}
/***********************************************************************
* ResizePalette [GDI32.@]
*
* Resizes logical palette.
*
* RETURNS
* Success: TRUE
* Failure: FALSE
*/
BOOL WINAPI ResizePalette(
HPALETTE hPal, /* [in] Handle of logical palette */
UINT cEntries) /* [in] Number of entries in logical palette */
{
PALETTEOBJ * palPtr = GDI_GetObjPtr( hPal, OBJ_PAL );
PALETTEENTRY *entries;
if( !palPtr ) return FALSE;
TRACE("hpal = %p, prev = %i, new = %i\n", hPal, palPtr->count, cEntries );
if (!(entries = HeapReAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
palPtr->entries, cEntries * sizeof(*palPtr->entries) )))
{
GDI_ReleaseObj( hPal );
return FALSE;
}
palPtr->entries = entries;
palPtr->count = cEntries;
GDI_ReleaseObj( hPal );
PALETTE_UnrealizeObject( hPal );
return TRUE;
}
/***********************************************************************
* AnimatePalette [GDI32.@]
*
* Replaces entries in logical palette.
*
* RETURNS
* Success: TRUE
* Failure: FALSE
*
* FIXME
* Should use existing mapping when animating a primary palette
*/
BOOL WINAPI AnimatePalette(
HPALETTE hPal, /* [in] Handle to logical palette */
UINT StartIndex, /* [in] First entry in palette */
UINT NumEntries, /* [in] Count of entries in palette */
const PALETTEENTRY* PaletteColors) /* [in] Pointer to first replacement */
{
TRACE("%p (%i - %i)\n", hPal, StartIndex,StartIndex+NumEntries);
if( hPal != GetStockObject(DEFAULT_PALETTE) )
{
PALETTEOBJ * palPtr;
UINT pal_entries;
const PALETTEENTRY *pptr = PaletteColors;
const DC_FUNCTIONS *funcs;
palPtr = GDI_GetObjPtr( hPal, OBJ_PAL );
if (!palPtr) return 0;
pal_entries = palPtr->count;
if (StartIndex >= pal_entries)
{
GDI_ReleaseObj( hPal );
return 0;
}
if (StartIndex+NumEntries > pal_entries) NumEntries = pal_entries - StartIndex;
for (NumEntries += StartIndex; StartIndex < NumEntries; StartIndex++, pptr++) {
/* According to MSDN, only animate PC_RESERVED colours */
if (palPtr->entries[StartIndex].peFlags & PC_RESERVED) {
TRACE("Animating colour (%d,%d,%d) to (%d,%d,%d)\n",
palPtr->entries[StartIndex].peRed,
palPtr->entries[StartIndex].peGreen,
palPtr->entries[StartIndex].peBlue,
pptr->peRed, pptr->peGreen, pptr->peBlue);
palPtr->entries[StartIndex] = *pptr;
} else {
TRACE("Not animating entry %d -- not PC_RESERVED\n", StartIndex);
}
}
funcs = palPtr->funcs;
GDI_ReleaseObj( hPal );
if (funcs && funcs->pRealizePalette) funcs->pRealizePalette( NULL, hPal, hPal == hPrimaryPalette );
}
return TRUE;
}
/***********************************************************************
* SetSystemPaletteUse [GDI32.@]
*
* Specify whether the system palette contains 2 or 20 static colors.
*
* RETURNS
* Success: Previous system palette
* Failure: SYSPAL_ERROR
*/
UINT WINAPI SetSystemPaletteUse(
HDC hdc, /* [in] Handle of device context */
UINT use) /* [in] Palette-usage flag */
{
UINT old = SystemPaletteUse;
/* Device doesn't support colour palettes */
if (!(GetDeviceCaps(hdc, RASTERCAPS) & RC_PALETTE)) {
return SYSPAL_ERROR;
}
switch (use) {
case SYSPAL_NOSTATIC:
case SYSPAL_NOSTATIC256: /* WINVER >= 0x0500 */
case SYSPAL_STATIC:
SystemPaletteUse = use;
return old;
default:
return SYSPAL_ERROR;
}
}
/***********************************************************************
* GetSystemPaletteUse [GDI32.@]
*
* Gets state of system palette.
*
* RETURNS
* Current state of system palette
*/
UINT WINAPI GetSystemPaletteUse(
HDC hdc) /* [in] Handle of device context */
{
return SystemPaletteUse;
}
/***********************************************************************
* GetSystemPaletteEntries [GDI32.@]
*
* Gets range of palette entries.
*
* RETURNS
* Success: Number of entries retrieved from palette
* Failure: 0
*/
UINT WINAPI GetSystemPaletteEntries(
HDC hdc, /* [in] Handle of device context */
UINT start, /* [in] Index of first entry to be retrieved */
UINT count, /* [in] Number of entries to be retrieved */
LPPALETTEENTRY entries) /* [out] Array receiving system-palette entries */
{
UINT ret = 0;
DC *dc;
TRACE("hdc=%p,start=%i,count=%i\n", hdc,start,count);
if ((dc = get_dc_ptr( hdc )))
{
if (dc->funcs->pGetSystemPaletteEntries)
ret = dc->funcs->pGetSystemPaletteEntries( dc->physDev, start, count, entries );
release_dc_ptr( dc );
}
return ret;
}
/***********************************************************************
* GetNearestPaletteIndex [GDI32.@]
*
* Gets palette index for color.
*
* NOTES
* Should index be initialized to CLR_INVALID instead of 0?
*
* RETURNS
* Success: Index of entry in logical palette
* Failure: CLR_INVALID
*/
UINT WINAPI GetNearestPaletteIndex(
HPALETTE hpalette, /* [in] Handle of logical color palette */
COLORREF color) /* [in] Color to be matched */
{
PALETTEOBJ* palObj = GDI_GetObjPtr( hpalette, OBJ_PAL );
UINT index = 0;
if( palObj )
{
int i, diff = 0x7fffffff;
int r,g,b;
PALETTEENTRY* entry = palObj->entries;
for( i = 0; i < palObj->count && diff ; i++, entry++)
{
r = entry->peRed - GetRValue(color);
g = entry->peGreen - GetGValue(color);
b = entry->peBlue - GetBValue(color);
r = r*r + g*g + b*b;
if( r < diff ) { index = i; diff = r; }
}
GDI_ReleaseObj( hpalette );
}
TRACE("(%p,%06x): returning %d\n", hpalette, color, index );
return index;
}
/***********************************************************************
* GetNearestColor [GDI32.@]
*
* Gets a system color to match.
*
* RETURNS
* Success: Color from system palette that corresponds to given color
* Failure: CLR_INVALID
*/
COLORREF WINAPI GetNearestColor(
HDC hdc, /* [in] Handle of device context */
COLORREF color) /* [in] Color to be matched */
{
unsigned char spec_type;
COLORREF nearest;
DC *dc;
if (!(dc = get_dc_ptr( hdc ))) return CLR_INVALID;
if (dc->funcs->pGetNearestColor)
{
nearest = dc->funcs->pGetNearestColor( dc->physDev, color );
release_dc_ptr( dc );
return nearest;
}
if (!(GetDeviceCaps(hdc, RASTERCAPS) & RC_PALETTE))
{
release_dc_ptr( dc );
return color;
}
spec_type = color >> 24;
if (spec_type == 1 || spec_type == 2)
{
/* we need logical palette for PALETTERGB and PALETTEINDEX colorrefs */
UINT index;
PALETTEENTRY entry;
HPALETTE hpal = dc->hPalette ? dc->hPalette : GetStockObject( DEFAULT_PALETTE );
if (spec_type == 2) /* PALETTERGB */
index = GetNearestPaletteIndex( hpal, color );
else /* PALETTEINDEX */
index = LOWORD(color);
if (!GetPaletteEntries( hpal, index, 1, &entry ))
{
WARN("RGB(%x) : idx %d is out of bounds, assuming NULL\n", color, index );
if (!GetPaletteEntries( hpal, 0, 1, &entry ))
{
release_dc_ptr( dc );
return CLR_INVALID;
}
}
color = RGB( entry.peRed, entry.peGreen, entry.peBlue );
}
nearest = color & 0x00ffffff;
release_dc_ptr( dc );
TRACE("(%06x): returning %06x\n", color, nearest );
return nearest;
}
/***********************************************************************
* PALETTE_GetObject
*/
static INT PALETTE_GetObject( HGDIOBJ handle, INT count, LPVOID buffer )
{
PALETTEOBJ *palette = GDI_GetObjPtr( handle, OBJ_PAL );
if (!palette) return 0;
if (buffer)
{
if (count > sizeof(WORD)) count = sizeof(WORD);
memcpy( buffer, &palette->count, count );
}
else count = sizeof(WORD);
GDI_ReleaseObj( handle );
return count;
}
/***********************************************************************
* PALETTE_UnrealizeObject
*/
static BOOL PALETTE_UnrealizeObject( HGDIOBJ handle )
{
PALETTEOBJ *palette = GDI_GetObjPtr( handle, OBJ_PAL );
if (palette)
{
const DC_FUNCTIONS *funcs = palette->funcs;
palette->funcs = NULL;
GDI_ReleaseObj( handle );
if (funcs && funcs->pUnrealizePalette) funcs->pUnrealizePalette( handle );
}
if (InterlockedCompareExchangePointer( (void **)&hLastRealizedPalette, 0, handle ) == handle)
TRACE("unrealizing palette %p\n", handle);
return TRUE;
}
/***********************************************************************
* PALETTE_DeleteObject
*/
static BOOL PALETTE_DeleteObject( HGDIOBJ handle )
{
PALETTEOBJ *obj;
PALETTE_UnrealizeObject( handle );
if (!(obj = free_gdi_handle( handle ))) return FALSE;
HeapFree( GetProcessHeap(), 0, obj->entries );
return HeapFree( GetProcessHeap(), 0, obj );
}
/***********************************************************************
* GDISelectPalette (Not a Windows API)
*/
HPALETTE WINAPI GDISelectPalette( HDC hdc, HPALETTE hpal, WORD wBkg)
{
HPALETTE ret;
DC *dc;
TRACE("%p %p\n", hdc, hpal );
if (GetObjectType(hpal) != OBJ_PAL)
{
WARN("invalid selected palette %p\n",hpal);
return 0;
}
if (!(dc = get_dc_ptr( hdc ))) return 0;
ret = dc->hPalette;
if (dc->funcs->pSelectPalette) hpal = dc->funcs->pSelectPalette( dc->physDev, hpal, FALSE );
if (hpal)
{
dc->hPalette = hpal;
if (!wBkg) hPrimaryPalette = hpal;
}
else ret = 0;
release_dc_ptr( dc );
return ret;
}
/***********************************************************************
* GDIRealizePalette (Not a Windows API)
*/
UINT WINAPI GDIRealizePalette( HDC hdc )
{
UINT realized = 0;
DC* dc = get_dc_ptr( hdc );
if (!dc) return 0;
TRACE("%p...\n", hdc );
if( dc->hPalette == GetStockObject( DEFAULT_PALETTE ))
{
if (dc->funcs->pRealizeDefaultPalette)
realized = dc->funcs->pRealizeDefaultPalette( dc->physDev );
}
else if (InterlockedExchangePointer( (void **)&hLastRealizedPalette, dc->hPalette ) != dc->hPalette)
{
if (dc->funcs->pRealizePalette)
{
PALETTEOBJ *palPtr = GDI_GetObjPtr( dc->hPalette, OBJ_PAL );
if (palPtr)
{
realized = dc->funcs->pRealizePalette( dc->physDev, dc->hPalette,
(dc->hPalette == hPrimaryPalette) );
palPtr->funcs = dc->funcs;
GDI_ReleaseObj( dc->hPalette );
}
}
}
else TRACE(" skipping (hLastRealizedPalette = %p)\n", hLastRealizedPalette);
release_dc_ptr( dc );
TRACE(" realized %i colors.\n", realized );
return realized;
}
/***********************************************************************
* SelectPalette [GDI32.@]
*
* Selects logical palette into DC.
*
* RETURNS
* Success: Previous logical palette
* Failure: NULL
*/
HPALETTE WINAPI SelectPalette(
HDC hDC, /* [in] Handle of device context */
HPALETTE hPal, /* [in] Handle of logical color palette */
BOOL bForceBackground) /* [in] Foreground/background mode */
{
return pfnSelectPalette( hDC, hPal, bForceBackground );
}
/***********************************************************************
* RealizePalette [GDI32.@]
*
* Maps palette entries to system palette.
*
* RETURNS
* Success: Number of entries in logical palette
* Failure: GDI_ERROR
*/
UINT WINAPI RealizePalette(
HDC hDC) /* [in] Handle of device context */
{
return pfnRealizePalette( hDC );
}
typedef HWND (WINAPI *WindowFromDC_funcptr)( HDC );
typedef BOOL (WINAPI *RedrawWindow_funcptr)( HWND, const RECT *, HRGN, UINT );
/**********************************************************************
* UpdateColors [GDI32.@]
*
* Remaps current colors to logical palette.
*
* RETURNS
* Success: TRUE
* Failure: FALSE
*/
BOOL WINAPI UpdateColors(
HDC hDC) /* [in] Handle of device context */
{
HMODULE mod;
int size = GetDeviceCaps( hDC, SIZEPALETTE );
if (!size) return 0;
mod = GetModuleHandleA("user32.dll");
if (mod)
{
WindowFromDC_funcptr pWindowFromDC = (WindowFromDC_funcptr)GetProcAddress(mod,"WindowFromDC");
if (pWindowFromDC)
{
HWND hWnd = pWindowFromDC( hDC );
/* Docs say that we have to remap current drawable pixel by pixel
* but it would take forever given the speed of XGet/PutPixel.
*/
if (hWnd && size)
{
RedrawWindow_funcptr pRedrawWindow = (void *)GetProcAddress( mod, "RedrawWindow" );
if (pRedrawWindow) pRedrawWindow( hWnd, NULL, 0, RDW_INVALIDATE );
}
}
}
return 0x666;
}
/*********************************************************************
* SetMagicColors (GDI32.@)
*/
BOOL WINAPI SetMagicColors(HDC hdc, ULONG u1, ULONG u2)
{
FIXME("(%p 0x%08x 0x%08x): stub\n", hdc, u1, u2);
return TRUE;
}

2222
arwinss/client/gdi32/path.c Normal file

File diff suppressed because it is too large Load Diff

312
arwinss/client/gdi32/pen.c Normal file
View File

@@ -0,0 +1,312 @@
/*
* GDI pen objects
*
* Copyright 1993 Alexandre Julliard
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "config.h"
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "gdi_private.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(gdi);
/* GDI logical pen object */
typedef struct
{
GDIOBJHDR header;
EXTLOGPEN logpen;
} PENOBJ;
static HGDIOBJ PEN_SelectObject( HGDIOBJ handle, HDC hdc );
static INT PEN_GetObject( HGDIOBJ handle, INT count, LPVOID buffer );
static BOOL PEN_DeleteObject( HGDIOBJ handle );
static const struct gdi_obj_funcs pen_funcs =
{
PEN_SelectObject, /* pSelectObject */
PEN_GetObject, /* pGetObjectA */
PEN_GetObject, /* pGetObjectW */
NULL, /* pUnrealizeObject */
PEN_DeleteObject /* pDeleteObject */
};
/***********************************************************************
* CreatePen (GDI32.@)
*/
HPEN WINAPI CreatePen( INT style, INT width, COLORREF color )
{
LOGPEN logpen;
TRACE("%d %d %06x\n", style, width, color );
logpen.lopnStyle = style;
logpen.lopnWidth.x = width;
logpen.lopnWidth.y = 0;
logpen.lopnColor = color;
return CreatePenIndirect( &logpen );
}
/***********************************************************************
* CreatePenIndirect (GDI32.@)
*/
HPEN WINAPI CreatePenIndirect( const LOGPEN * pen )
{
PENOBJ * penPtr;
HPEN hpen;
if (pen->lopnStyle == PS_NULL)
{
hpen = GetStockObject(NULL_PEN);
if (hpen) return hpen;
}
if (!(penPtr = HeapAlloc( GetProcessHeap(), 0, sizeof(*penPtr) ))) return 0;
if (pen->lopnStyle == PS_USERSTYLE || pen->lopnStyle == PS_ALTERNATE)
penPtr->logpen.elpPenStyle = PS_SOLID;
else
penPtr->logpen.elpPenStyle = pen->lopnStyle;
if (pen->lopnStyle == PS_NULL)
{
penPtr->logpen.elpWidth = 1;
penPtr->logpen.elpColor = RGB(0, 0, 0);
}
else
{
penPtr->logpen.elpWidth = abs(pen->lopnWidth.x);
penPtr->logpen.elpColor = pen->lopnColor;
}
penPtr->logpen.elpBrushStyle = BS_SOLID;
penPtr->logpen.elpHatch = 0;
penPtr->logpen.elpNumEntries = 0;
penPtr->logpen.elpStyleEntry[0] = 0;
if (!(hpen = alloc_gdi_handle( &penPtr->header, OBJ_PEN, &pen_funcs )))
HeapFree( GetProcessHeap(), 0, penPtr );
return hpen;
}
/***********************************************************************
* ExtCreatePen (GDI32.@)
*
* FIXME: PS_USERSTYLE not handled
*/
HPEN WINAPI ExtCreatePen( DWORD style, DWORD width,
const LOGBRUSH * brush, DWORD style_count,
const DWORD *style_bits )
{
PENOBJ * penPtr;
HPEN hpen;
if ((style & PS_STYLE_MASK) == PS_USERSTYLE)
{
if(((INT)style_count) <= 0)
return 0;
if ((style_count > 16) || !style_bits)
{
SetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
if ((style & PS_TYPE_MASK) == PS_COSMETIC)
{
/* FIXME: PS_USERSTYLE workaround */
FIXME("PS_COSMETIC | PS_USERSTYLE not handled\n");
style = (style & ~PS_STYLE_MASK) | PS_SOLID;
}
else
{
UINT i;
BOOL has_neg = FALSE, all_zero = TRUE;
for(i = 0; (i < style_count) && !has_neg; i++)
{
has_neg = has_neg || (((INT)(style_bits[i])) < 0);
all_zero = all_zero && (style_bits[i] == 0);
}
if(all_zero || has_neg)
{
SetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
}
}
else
{
if (style_count || style_bits)
{
SetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
}
if ((style & PS_STYLE_MASK) == PS_NULL)
return CreatePen( PS_NULL, 0, brush->lbColor );
if ((style & PS_TYPE_MASK) == PS_GEOMETRIC)
{
/* PS_ALTERNATE is applicable only for cosmetic pens */
if ((style & PS_STYLE_MASK) == PS_ALTERNATE)
{
SetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
if (brush->lbHatch && ((brush->lbStyle == BS_SOLID) || (brush->lbStyle == BS_HOLLOW)))
{
static int fixme_hatches_shown;
if (!fixme_hatches_shown++) FIXME("Hatches not implemented\n");
}
}
else
{
/* PS_INSIDEFRAME is applicable only for geometric pens */
if ((style & PS_STYLE_MASK) == PS_INSIDEFRAME || width != 1)
{
SetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
}
if (!(penPtr = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(PENOBJ,logpen.elpStyleEntry[style_count]))))
return 0;
penPtr->logpen.elpPenStyle = style;
penPtr->logpen.elpWidth = abs(width);
penPtr->logpen.elpBrushStyle = brush->lbStyle;
penPtr->logpen.elpColor = brush->lbColor;
penPtr->logpen.elpHatch = brush->lbHatch;
penPtr->logpen.elpNumEntries = style_count;
memcpy(penPtr->logpen.elpStyleEntry, style_bits, style_count * sizeof(DWORD));
if (!(hpen = alloc_gdi_handle( &penPtr->header, OBJ_EXTPEN, &pen_funcs )))
HeapFree( GetProcessHeap(), 0, penPtr );
return hpen;
}
/***********************************************************************
* PEN_SelectObject
*/
static HGDIOBJ PEN_SelectObject( HGDIOBJ handle, HDC hdc )
{
HGDIOBJ ret = 0;
DC *dc = get_dc_ptr( hdc );
if (!dc)
{
SetLastError( ERROR_INVALID_HANDLE );
return 0;
}
if (!GDI_inc_ref_count( handle ))
{
release_dc_ptr( dc );
return 0;
}
if (dc->funcs->pSelectPen && !dc->funcs->pSelectPen( dc->physDev, handle ))
{
GDI_dec_ref_count( handle );
}
else
{
ret = dc->hPen;
dc->hPen = handle;
GDI_dec_ref_count( ret );
}
release_dc_ptr( dc );
return ret;
}
/***********************************************************************
* PEN_DeleteObject
*/
static BOOL PEN_DeleteObject( HGDIOBJ handle )
{
PENOBJ *pen = free_gdi_handle( handle );
if (!pen) return FALSE;
return HeapFree( GetProcessHeap(), 0, pen );
}
/***********************************************************************
* PEN_GetObject
*/
static INT PEN_GetObject( HGDIOBJ handle, INT count, LPVOID buffer )
{
PENOBJ *pen = GDI_GetObjPtr( handle, 0 );
INT ret = 0;
if (!pen) return 0;
switch (pen->header.type)
{
case OBJ_PEN:
{
LOGPEN *lp;
if (!buffer) ret = sizeof(LOGPEN);
else if (count < sizeof(LOGPEN)) ret = 0;
else if ((pen->logpen.elpPenStyle & PS_STYLE_MASK) == PS_NULL && count == sizeof(EXTLOGPEN))
{
EXTLOGPEN *elp = buffer;
*elp = pen->logpen;
elp->elpWidth = 0;
ret = sizeof(EXTLOGPEN);
}
else
{
lp = buffer;
lp->lopnStyle = pen->logpen.elpPenStyle;
lp->lopnColor = pen->logpen.elpColor;
lp->lopnWidth.x = pen->logpen.elpWidth;
lp->lopnWidth.y = 0;
ret = sizeof(LOGPEN);
}
break;
}
case OBJ_EXTPEN:
ret = sizeof(EXTLOGPEN) + pen->logpen.elpNumEntries * sizeof(DWORD) - sizeof(pen->logpen.elpStyleEntry);
if (buffer)
{
if (count < ret) ret = 0;
else memcpy(buffer, &pen->logpen, ret);
}
break;
}
GDI_ReleaseObj( handle );
return ret;
}

View File

@@ -0,0 +1,215 @@
/*
* Implementation of some printer driver bits
*
* Copyright 1996 John Harvey
* Copyright 1998 Huw Davies
* Copyright 1998 Andreas Mohr
* Copyright 1999 Klaas van Gend
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <stdarg.h>
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winnls.h"
#include "winspool.h"
#include "winerror.h"
#include "wine/debug.h"
#include "gdi_private.h"
WINE_DEFAULT_DEBUG_CHANNEL(print);
/******************************************************************
* GdiGetSpoolMessage [GDI32.@]
*
*/
DWORD WINAPI GdiGetSpoolMessage(LPVOID ptr1, DWORD data2, LPVOID ptr3, DWORD data4)
{
TRACE("(%p 0x%x %p 0x%x) stub\n", ptr1, data2, ptr3, data4);
/* avoid 100% cpu usage with spoolsv.exe from w2k
(spoolsv.exe from xp does Sleep 1000/1500/2000 in a loop) */
Sleep(500);
return 0;
}
/******************************************************************
* GdiInitSpool [GDI32.@]
*
*/
DWORD WINAPI GdiInitSpool(void)
{
FIXME("stub\n");
return TRUE;
}
/******************************************************************
* StartDocW [GDI32.@]
*
* StartDoc calls the STARTDOC Escape with the input data pointing to DocName
* and the output data (which is used as a second input parameter).pointing at
* the whole docinfo structure. This seems to be an undocumented feature of
* the STARTDOC Escape.
*
* Note: we now do it the other way, with the STARTDOC Escape calling StartDoc.
*/
INT WINAPI StartDocW(HDC hdc, const DOCINFOW* doc)
{
INT ret = 0;
DC *dc = get_dc_ptr( hdc );
TRACE("DocName = %s Output = %s Datatype = %s\n",
debugstr_w(doc->lpszDocName), debugstr_w(doc->lpszOutput),
debugstr_w(doc->lpszDatatype));
if(!dc) return SP_ERROR;
if (dc->pAbortProc && !dc->pAbortProc( hdc, 0 ))
{
release_dc_ptr( dc );
return ret;
}
if (dc->funcs->pStartDoc) ret = dc->funcs->pStartDoc( dc->physDev, doc );
release_dc_ptr( dc );
return ret;
}
/*************************************************************************
* StartDocA [GDI32.@]
*
*/
INT WINAPI StartDocA(HDC hdc, const DOCINFOA* doc)
{
LPWSTR szDocName = NULL, szOutput = NULL, szDatatype = NULL;
DOCINFOW docW;
INT ret, len;
docW.cbSize = doc->cbSize;
if (doc->lpszDocName)
{
len = MultiByteToWideChar(CP_ACP,0,doc->lpszDocName,-1,NULL,0);
szDocName = HeapAlloc(GetProcessHeap(),0,len*sizeof(WCHAR));
MultiByteToWideChar(CP_ACP,0,doc->lpszDocName,-1,szDocName,len);
}
if (doc->lpszOutput)
{
len = MultiByteToWideChar(CP_ACP,0,doc->lpszOutput,-1,NULL,0);
szOutput = HeapAlloc(GetProcessHeap(),0,len*sizeof(WCHAR));
MultiByteToWideChar(CP_ACP,0,doc->lpszOutput,-1,szOutput,len);
}
if (doc->lpszDatatype)
{
len = MultiByteToWideChar(CP_ACP,0,doc->lpszDatatype,-1,NULL,0);
szDatatype = HeapAlloc(GetProcessHeap(),0,len*sizeof(WCHAR));
MultiByteToWideChar(CP_ACP,0,doc->lpszDatatype,-1,szDatatype,len);
}
docW.lpszDocName = szDocName;
docW.lpszOutput = szOutput;
docW.lpszDatatype = szDatatype;
docW.fwType = doc->fwType;
ret = StartDocW(hdc, &docW);
HeapFree( GetProcessHeap(), 0, szDocName );
HeapFree( GetProcessHeap(), 0, szOutput );
HeapFree( GetProcessHeap(), 0, szDatatype );
return ret;
}
/******************************************************************
* EndDoc [GDI32.@]
*
*/
INT WINAPI EndDoc(HDC hdc)
{
INT ret = 0;
DC *dc = get_dc_ptr( hdc );
if(!dc) return SP_ERROR;
if (dc->funcs->pEndDoc) ret = dc->funcs->pEndDoc( dc->physDev );
release_dc_ptr( dc );
return ret;
}
/******************************************************************
* StartPage [GDI32.@]
*
*/
INT WINAPI StartPage(HDC hdc)
{
INT ret = 1;
DC *dc = get_dc_ptr( hdc );
if(!dc) return SP_ERROR;
if(dc->funcs->pStartPage)
ret = dc->funcs->pStartPage( dc->physDev );
else
FIXME("stub\n");
release_dc_ptr( dc );
return ret;
}
/******************************************************************
* EndPage [GDI32.@]
*
*/
INT WINAPI EndPage(HDC hdc)
{
INT ret = 0;
DC *dc = get_dc_ptr( hdc );
if(!dc) return SP_ERROR;
if (dc->funcs->pEndPage) ret = dc->funcs->pEndPage( dc->physDev );
release_dc_ptr( dc );
return ret;
}
/******************************************************************************
* AbortDoc [GDI32.@]
*/
INT WINAPI AbortDoc(HDC hdc)
{
INT ret = 0;
DC *dc = get_dc_ptr( hdc );
if(!dc) return SP_ERROR;
if (dc->funcs->pAbortDoc) ret = dc->funcs->pAbortDoc( dc->physDev );
release_dc_ptr( dc );
return ret;
}
/**********************************************************************
* SetAbortProc (GDI32.@)
*
*/
INT WINAPI SetAbortProc(HDC hdc, ABORTPROC abrtprc)
{
DC *dc = get_dc_ptr( hdc );
if (!dc) return FALSE;
dc->pAbortProc = abrtprc;
release_dc_ptr( dc );
return TRUE;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,79 @@
add_definitions(-D__WINESRC__
-D_WINE)
spec2def(user32.dll user32.spec ADD_IMPORTLIB)
include_directories(
${REACTOS_SOURCE_DIR}/include/reactos/subsys
${REACTOS_SOURCE_DIR}/arwinss/include
${REACTOS_SOURCE_DIR}/win32ss/include
${REACTOS_SOURCE_DIR}/include/reactos/wine
)
list(APPEND SOURCE
atom.c
button.c
caret.c
class.c
clipboard.c
combo.c
csr.c
cursoricon.c
dde_client.c
dde_misc.c
dde_server.c
defdlg.c
defwnd.c
desktop.c
dialog.c
driver.c
edit.c
exticon.c
focus.c
hook.c
icontitle.c
input.c
inputros.c
legacy.c
listbox.c
lstr.c
mdi.c
menu.c
message.c
misc.c
msgbox.c
nonclient.c
painting.c
property.c
resource.c
scroll.c
spy.c
static.c
sysparams.c
text.c
uitools.c
user_main.c
win.c
winhelp.c
winpos.c
winproc.c
winstation.c
wsprintf.c
resources/user32.rc
${CMAKE_CURRENT_BINARY_DIR}/user32_stubs.c
${CMAKE_CURRENT_BINARY_DIR}/user32.def)
add_library(user32 SHARED ${SOURCE})
set_module_type(user32 win32dll UNICODE)
target_link_libraries(user32
user32_wsprintf
wine
win32ksys
${PSEH_LIB})
add_delay_importlibs(user32 imm32 usp10)
add_importlibs(user32 gdi32 advapi32 version msvcrt kernel32 ntdll)
#add_pch(user32 include/user32.h SOURCE)
add_cd_file(TARGET user32 DESTINATION reactos/system32 FOR all)

View File

@@ -0,0 +1,649 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
* FILE: lib/kernel32/misc/atom.c
* PURPOSE: Atom functions
* PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
*/
/* INCLUDES ******************************************************************/
#define WIN32_NO_STATUS
#include <windows.h>
#include <ndk/ntndk.h>
#include "wine/debug.h"
#include "wine/server.h"
WINE_DEFAULT_DEBUG_CHANNEL(useratom);
#define SetLastErrorByStatus(__S__) \
((void)SetLastError(RtlNtStatusToDosError(__S__)))
/* DEAR GOD, FORGIVE ME ******************************************************/
#define MAX_ATOM_LEN 255
/******************************************************************
* is_integral_atom
* Returns STATUS_SUCCESS if integral atom and 'pAtom' is filled
* STATUS_INVALID_PARAMETER if 'atomstr' is too long
* STATUS_MORE_ENTRIES otherwise
*/
static NTSTATUS is_integral_atom( LPCWSTR atomstr, size_t len, RTL_ATOM* pAtom )
{
RTL_ATOM atom;
if (HIWORD( atomstr ))
{
const WCHAR* ptr = atomstr;
if (!len) return STATUS_OBJECT_NAME_INVALID;
if (*ptr++ == '#')
{
atom = 0;
while (ptr < atomstr + len && *ptr >= '0' && *ptr <= '9')
{
atom = atom * 10 + *ptr++ - '0';
}
if (ptr > atomstr + 1 && ptr == atomstr + len) goto done;
}
if (len > MAX_ATOM_LEN) return STATUS_INVALID_PARAMETER;
return STATUS_MORE_ENTRIES;
}
else atom = LOWORD( atomstr );
done:
if (!atom || atom >= MAXINTATOM) return STATUS_INVALID_PARAMETER;
*pAtom = atom;
return STATUS_SUCCESS;
}
/******************************************************************
* integral_atom_name (internal)
*
* Helper for fetching integral atoms names.
*/
static ULONG integral_atom_name(WCHAR* buffer, ULONG len, RTL_ATOM atom)
{
static const WCHAR fmt[] = {'#','%','u',0};
WCHAR tmp[16];
int ret;
ret = swprintf( tmp, fmt, atom );
if (!len) return ret * sizeof(WCHAR);
if (len <= ret) ret = len - 1;
memcpy( buffer, tmp, ret * sizeof(WCHAR) );
buffer[ret] = 0;
return ret * sizeof(WCHAR);
}
/*************************************************
* Global handle table management
*************************************************/
/******************************************************************
* NtAddAtom (NTDLL.@)
*/
NTSTATUS WINAPI WineNtAddAtom( const WCHAR* name, ULONG length, RTL_ATOM* atom )
{
NTSTATUS status;
status = is_integral_atom( name, length / sizeof(WCHAR), atom );
if (status == STATUS_MORE_ENTRIES)
{
SERVER_START_REQ( add_atom )
{
wine_server_add_data( req, name, length );
req->table = 0;
status = wine_server_call( req );
*atom = reply->atom;
}
SERVER_END_REQ;
}
//TRACE( "%s -> %x\n",
// debugstr_wn(name, length/sizeof(WCHAR)), status == STATUS_SUCCESS ? *atom : 0 );
return status;
}
/******************************************************************
* NtDeleteAtom (NTDLL.@)
*/
NTSTATUS WINAPI WineNtDeleteAtom(RTL_ATOM atom)
{
NTSTATUS status;
SERVER_START_REQ( delete_atom )
{
req->atom = atom;
req->table = 0;
status = wine_server_call( req );
}
SERVER_END_REQ;
return status;
}
/******************************************************************
* NtFindAtom (NTDLL.@)
*/
NTSTATUS WINAPI WineNtFindAtom( const WCHAR* name, ULONG length, RTL_ATOM* atom )
{
NTSTATUS status;
status = is_integral_atom( name, length / sizeof(WCHAR), atom );
if (status == STATUS_MORE_ENTRIES)
{
SERVER_START_REQ( find_atom )
{
wine_server_add_data( req, name, length );
req->table = 0;
status = wine_server_call( req );
*atom = reply->atom;
}
SERVER_END_REQ;
}
//TRACE( "%s -> %x\n",
// debugstr_wn(name, length/sizeof(WCHAR)), status == STATUS_SUCCESS ? *atom : 0 );
return status;
}
/******************************************************************
* NtQueryInformationAtom (NTDLL.@)
*/
NTSTATUS WINAPI WineNtQueryInformationAtom( RTL_ATOM atom, ATOM_INFORMATION_CLASS class,
PVOID ptr, ULONG size, PULONG psize )
{
NTSTATUS status;
switch (class)
{
case AtomBasicInformation:
{
ULONG name_len;
ATOM_BASIC_INFORMATION* abi = ptr;
if (size < sizeof(ATOM_BASIC_INFORMATION))
return STATUS_INVALID_PARAMETER;
name_len = size - sizeof(ATOM_BASIC_INFORMATION);
if (atom < MAXINTATOM)
{
if (atom)
{
abi->NameLength = integral_atom_name( abi->Name, name_len, atom );
status = (name_len) ? STATUS_SUCCESS : STATUS_BUFFER_TOO_SMALL;
//abi->ReferenceCount = 1;
//abi->Pinned = 1;
}
else status = STATUS_INVALID_PARAMETER;
}
else
{
SERVER_START_REQ( get_atom_information )
{
req->atom = atom;
req->table = 0;
if (name_len) wine_server_set_reply( req, abi->Name, name_len );
status = wine_server_call( req );
if (status == STATUS_SUCCESS)
{
name_len = wine_server_reply_size( reply );
if (name_len)
{
abi->NameLength = name_len;
abi->Name[name_len / sizeof(WCHAR)] = '\0';
}
else
{
name_len = reply->total;
abi->NameLength = name_len;
status = STATUS_BUFFER_TOO_SMALL;
}
//abi->ReferenceCount = reply->count;
//abi->Pinned = reply->pinned;
}
else name_len = 0;
}
SERVER_END_REQ;
}
//TRACE( "%x -> %s (%u)\n",
// atom, debugstr_wn(abi->Name, abi->NameLength / sizeof(WCHAR)),
// status );
if (psize)
*psize = sizeof(ATOM_BASIC_INFORMATION) + name_len;
}
break;
default:
ERR( "Unsupported class %u\n", class );
status = STATUS_INVALID_INFO_CLASS;
break;
}
return status;
}
/* FUNCTIONS *****************************************************************/
ATOM
WINAPI
InternalAddAtom(BOOLEAN Unicode,
LPCSTR AtomName)
{
NTSTATUS Status;
ANSI_STRING AnsiString;
UNICODE_STRING UnicodeString;
PUNICODE_STRING AtomNameString;
ATOM Atom = INVALID_ATOM;
if (Unicode)
WARN("InternalAddAtom name %S\n", AtomName);
else
WARN("InternalAddAtom name %s\n", AtomName);
/* Check if it's an integer atom */
if ((ULONG_PTR)AtomName <= 0xFFFF)
{
/* Convert the name to an atom */
Atom = (ATOM)PtrToShort((PVOID)AtomName);
if (Atom >= MAXINTATOM)
{
/* Fail, atom number too large */
SetLastErrorByStatus(STATUS_INVALID_PARAMETER);
return INVALID_ATOM;
}
/* Return it */
return Atom;
}
else
{
/* Check if this is a unicode atom */
if (Unicode)
{
/* Use a unicode string */
AtomNameString = &UnicodeString;
RtlInitUnicodeString(AtomNameString, (LPWSTR)AtomName);
Status = STATUS_SUCCESS;
}
else
{
/* Use an ansi string */
RtlInitAnsiString(&AnsiString, AtomName );
/* Check if we can abuse the TEB */
if (AnsiString.MaximumLength > 260)
{
/* We can't, allocate a new string */
AtomNameString = &UnicodeString;
Status = RtlAnsiStringToUnicodeString(AtomNameString,
&AnsiString,
TRUE);
}
else
{
/* We can! Get the TEB String */
AtomNameString = &NtCurrentTeb()->StaticUnicodeString;
/* Convert it into the TEB */
Status = RtlAnsiStringToUnicodeString(AtomNameString,
&AnsiString,
FALSE);
}
}
/* Check for failure */
if (!NT_SUCCESS(Status))
{
SetLastErrorByStatus(Status);
return Atom;
}
}
/* Do a global add */
Status = WineNtAddAtom(AtomNameString->Buffer,
AtomNameString->Length,
&Atom);
/* Check for failure */
if (!NT_SUCCESS(Status)) SetLastErrorByStatus(Status);
/* Check if we were non-static ANSI */
if (!(Unicode) && (AtomNameString == &UnicodeString))
{
/* Free the allocated buffer */
RtlFreeUnicodeString(AtomNameString);
}
/* Return the atom */
return Atom;
}
ATOM
WINAPI
InternalFindAtom(BOOLEAN Unicode,LPCSTR AtomName)
{
NTSTATUS Status;
ANSI_STRING AnsiString;
UNICODE_STRING UnicodeString;
PUNICODE_STRING AtomNameString;
ATOM Atom = INVALID_ATOM;
if (Unicode)
WARN("InternalFindAtom name %S\n", AtomName);
else
WARN("InternalFindAtom name %s\n", AtomName);
/* Check if it's an integer atom */
if ((ULONG_PTR)AtomName <= 0xFFFF)
{
/* Convert the name to an atom */
Atom = (ATOM)PtrToShort((PVOID)AtomName);
if (Atom >= MAXINTATOM)
{
/* Fail, atom number too large */
SetLastErrorByStatus(STATUS_INVALID_PARAMETER);
ERR("Invalid atom\n");
}
/* Return it */
return Atom;
}
else
{
/* Check if this is a unicode atom */
if (Unicode)
{
/* Use a unicode string */
AtomNameString = &UnicodeString;
RtlInitUnicodeString(AtomNameString, (LPWSTR)AtomName);
Status = STATUS_SUCCESS;
}
else
{
/* Use an ansi string */
RtlInitAnsiString(&AnsiString, AtomName);
/* Check if we can abuse the TEB */
if (AnsiString.MaximumLength > 260)
{
/* We can't, allocate a new string */
AtomNameString = &UnicodeString;
Status = RtlAnsiStringToUnicodeString(AtomNameString,
&AnsiString,
TRUE);
}
else
{
/* We can! Get the TEB String */
AtomNameString = &NtCurrentTeb()->StaticUnicodeString;
/* Convert it into the TEB */
Status = RtlAnsiStringToUnicodeString(AtomNameString,
&AnsiString,
FALSE);
}
}
/* Check for failure */
if (!NT_SUCCESS(Status))
{
ERR("Failed\n");
SetLastErrorByStatus(Status);
return Atom;
}
}
/* Do a global search */
if (!AtomNameString->Length)
{
/* This is illegal in win32 */
ERR("No name given\n");
Status = STATUS_OBJECT_NAME_NOT_FOUND;
}
else
{
/* Call the global function */
Status = WineNtFindAtom(AtomNameString->Buffer,
AtomNameString->Length,
&Atom);
}
/* Check for failure */
if (!NT_SUCCESS(Status)) SetLastErrorByStatus(Status);
/* Check if we were non-static ANSI */
if (!(Unicode) && (AtomNameString == &UnicodeString))
{
/* Free the allocated buffer */
RtlFreeUnicodeString(AtomNameString);
}
/* Return the atom */
return Atom;
}
ATOM
WINAPI
InternalDeleteAtom(ATOM Atom)
{
NTSTATUS Status;
WARN("InternalDeleteAtom atom %x\n", Atom);
/* Validate it */
if (Atom >= MAXINTATOM)
{
/* Delete it globall */
Status = WineNtDeleteAtom(Atom);
/* Check for success */
if (!NT_SUCCESS(Status))
{
/* Fail */
SetLastErrorByStatus(Status);
return INVALID_ATOM;
}
}
/* Return failure */
return 0;
}
UINT
WINAPI
InternalGetAtomName(BOOLEAN Unicode,
ATOM Atom,
LPSTR AtomName,
DWORD Size)
{
NTSTATUS Status;
DWORD RetVal = 0;
ANSI_STRING AnsiString;
UNICODE_STRING UnicodeString;
PVOID TempBuffer = NULL;
PWSTR AtomNameString;
ULONG AtomInfoLength;
ULONG AtomNameLength;
PATOM_BASIC_INFORMATION AtomInfo;
WARN("InternalGetAtomName atom %x size %x\n", Atom, Size);
/* Normalize the size as not to overflow */
if (!Unicode && Size > 0x7000) Size = 0x7000;
/* Make sure it's valid too */
if (!Size)
{
SetLastErrorByStatus(STATUS_BUFFER_OVERFLOW);
return 0;
}
if (!Atom)
{
SetLastErrorByStatus(STATUS_INVALID_PARAMETER);
return 0;
}
/* We're going to do a global query, so allocate a buffer */
AtomInfoLength = sizeof(ATOM_BASIC_INFORMATION) +
(Size * sizeof(WCHAR));
AtomInfo = TempBuffer = RtlAllocateHeap(RtlGetProcessHeap(),
0,
AtomInfoLength);
if (!AtomInfo)
{
SetLastErrorByStatus(STATUS_NO_MEMORY);
return 0;
}
/* Query the name */
Status = WineNtQueryInformationAtom(Atom,
AtomBasicInformation,
AtomInfo,
AtomInfoLength,
&AtomInfoLength);
if (NT_SUCCESS(Status))
{
/* Success. Update the length and get the name */
AtomNameLength = (ULONG)AtomInfo->NameLength;
AtomNameString = AtomInfo->Name;
}
/* Check for global success */
if (NT_SUCCESS(Status))
{
/* Check if it was unicode */
if (Unicode)
{
/* We return the length in chars */
RetVal = AtomNameLength / sizeof(WCHAR);
/* Copy the memory if this was a global query */
if (AtomNameString != (PWSTR)AtomName)
{
RtlMoveMemory(AtomName, AtomNameString, AtomNameLength);
}
/* And null-terminate it if the buffer was too large */
if (RetVal < Size)
{
((PWCHAR)AtomName)[RetVal] = UNICODE_NULL;
}
}
else
{
/* First create a unicode string with our data */
UnicodeString.Buffer = AtomNameString;
UnicodeString.Length = (USHORT)AtomNameLength;
UnicodeString.MaximumLength = (USHORT)(UnicodeString.Length +
sizeof(WCHAR));
/* Now prepare an ansi string for conversion */
AnsiString.Buffer = AtomName;
AnsiString.Length = 0;
AnsiString.MaximumLength = (USHORT)Size;
/* Convert it */
Status = RtlUnicodeStringToAnsiString(&AnsiString,
&UnicodeString,
FALSE);
/* Return the length */
if (NT_SUCCESS(Status)) RetVal = AnsiString.Length;
}
}
/* Free the temporary buffer if we have one */
if (TempBuffer) RtlFreeHeap(RtlGetProcessHeap(), 0, TempBuffer);
/* Check for failure */
if (!NT_SUCCESS(Status))
{
/* Fail */
WARN("Failed: %lx\n", Status);
SetLastErrorByStatus(Status);
}
if (Unicode)
WARN("InternalGetAtomName name %S\n", AtomName);
else
WARN("InternalGetAtomName name %s\n", AtomName);
/* Return length */
return RetVal;
}
/* FUNCTIONS *****************************************************************/
/*
* @implemented
*/
ATOM
UserAddAtomA(LPCSTR lpString)
{
return InternalAddAtom(FALSE, lpString);
}
/*
* @implemented
*/
ATOM
UserAddAtomW(LPCWSTR lpString)
{
return InternalAddAtom(TRUE, (LPSTR)lpString);
}
/*
* @implemented
*/
ATOM
UserDeleteAtom(ATOM nAtom)
{
return InternalDeleteAtom(nAtom);
}
/*
* @implemented
*/
ATOM
UserFindAtomA(LPCSTR lpString)
{
return InternalFindAtom(FALSE, lpString);
}
/*
* @implemented
*/
ATOM
UserFindAtomW(LPCWSTR lpString)
{
return InternalFindAtom(TRUE, (LPSTR)lpString);
}
/*
* @implemented
*/
UINT
UserGetAtomNameA(ATOM nAtom,
LPSTR lpBuffer,
int nSize)
{
return InternalGetAtomName(FALSE, nAtom, lpBuffer, (DWORD)nSize);
}
/*
* @implemented
*/
UINT
UserGetAtomNameW(ATOM nAtom,
LPWSTR lpBuffer,
int nSize)
{
return InternalGetAtomName(TRUE,
nAtom,
(LPSTR)lpBuffer,
(DWORD)nSize);
}
/* EOF */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,410 @@
/*
* Caret functions
*
* Copyright 1993 David Metcalfe
* Copyright 1996 Frans van Dorsselaer
* Copyright 2001 Eric Pouech
* Copyright 2002 Alexandre Julliard
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "config.h"
#include "wine/port.h"
#include <stdarg.h>
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"
#include "wine/winternl.h"
#include "wine/server.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(caret);
typedef struct
{
HBITMAP hBmp;
UINT timeout;
} CARET;
static CARET Caret = { 0, 500 };
#define TIMERID 0xffff /* system timer id for the caret */
/*****************************************************************
* CARET_DisplayCaret
*/
static void CARET_DisplayCaret( HWND hwnd, const RECT *r )
{
HDC hdc;
HDC hCompDC;
/* do not use DCX_CACHE here, for x,y,width,height are in logical units */
if (!(hdc = GetDCEx( hwnd, 0, DCX_USESTYLE /*| DCX_CACHE*/ ))) return;
hCompDC = CreateCompatibleDC(hdc);
if (hCompDC)
{
HBITMAP hPrevBmp;
hPrevBmp = SelectObject(hCompDC, Caret.hBmp);
BitBlt(hdc, r->left, r->top, r->right-r->left, r->bottom-r->top, hCompDC, 0, 0, SRCINVERT);
SelectObject(hCompDC, hPrevBmp);
DeleteDC(hCompDC);
}
ReleaseDC( hwnd, hdc );
}
/*****************************************************************
* CARET_Callback
*/
static void CALLBACK CARET_Callback( HWND hwnd, UINT msg, UINT_PTR id, DWORD ctime)
{
BOOL ret;
RECT r;
int hidden = 0;
SERVER_START_REQ( set_caret_info )
{
req->flags = SET_CARET_STATE;
req->handle = wine_server_user_handle( hwnd );
req->x = 0;
req->y = 0;
req->hide = 0;
req->state = -1; /* toggle current state */
if ((ret = !wine_server_call( req )))
{
hwnd = wine_server_ptr_handle( reply->full_handle );
r.left = reply->old_rect.left;
r.top = reply->old_rect.top;
r.right = reply->old_rect.right;
r.bottom = reply->old_rect.bottom;
hidden = reply->old_hide;
}
}
SERVER_END_REQ;
if (ret && !hidden) CARET_DisplayCaret( hwnd, &r );
}
/*****************************************************************
* CreateCaret (USER32.@)
*/
BOOL WINAPI CreateCaret( HWND hwnd, HBITMAP bitmap, INT width, INT height )
{
BOOL ret;
RECT r;
int old_state = 0;
int hidden = 0;
HBITMAP hBmp = 0;
HWND prev = 0;
TRACE("hwnd=%p\n", hwnd);
if (!hwnd) return FALSE;
if (bitmap && (bitmap != (HBITMAP)1))
{
BITMAP bmp;
if (!GetObjectA( bitmap, sizeof(bmp), &bmp )) return FALSE;
width = bmp.bmWidth;
height = bmp.bmHeight;
bmp.bmBits = NULL;
hBmp = CreateBitmapIndirect(&bmp);
if (hBmp)
{
/* copy the bitmap */
LPBYTE buf = HeapAlloc(GetProcessHeap(), 0, bmp.bmWidthBytes * bmp.bmHeight);
GetBitmapBits(bitmap, bmp.bmWidthBytes * bmp.bmHeight, buf);
SetBitmapBits(hBmp, bmp.bmWidthBytes * bmp.bmHeight, buf);
HeapFree(GetProcessHeap(), 0, buf);
}
}
else
{
HDC hdc;
if (!width) width = GetSystemMetrics(SM_CXBORDER);
if (!height) height = GetSystemMetrics(SM_CYBORDER);
/* create the uniform bitmap on the fly */
hdc = GetDC(hwnd);
if (hdc)
{
HDC hMemDC = CreateCompatibleDC(hdc);
if (hMemDC)
{
if ((hBmp = CreateCompatibleBitmap(hMemDC, width, height )))
{
HBITMAP hPrevBmp = SelectObject(hMemDC, hBmp);
SetRect( &r, 0, 0, width, height );
FillRect(hMemDC, &r, bitmap ? GetStockObject(GRAY_BRUSH) : GetStockObject(WHITE_BRUSH));
SelectObject(hMemDC, hPrevBmp);
}
DeleteDC(hMemDC);
}
ReleaseDC(hwnd, hdc);
}
}
if (!hBmp) return FALSE;
SERVER_START_REQ( set_caret_window )
{
req->handle = wine_server_user_handle( hwnd );
req->width = width;
req->height = height;
if ((ret = !wine_server_call_err( req )))
{
prev = wine_server_ptr_handle( reply->previous );
r.left = reply->old_rect.left;
r.top = reply->old_rect.top;
r.right = reply->old_rect.right;
r.bottom = reply->old_rect.bottom;
old_state = reply->old_state;
hidden = reply->old_hide;
}
}
SERVER_END_REQ;
if (!ret) return FALSE;
if (prev && !hidden) /* hide the previous one */
{
/* FIXME: won't work if prev belongs to a different process */
KillSystemTimer( prev, TIMERID );
if (old_state) CARET_DisplayCaret( prev, &r );
}
if (Caret.hBmp) DeleteObject( Caret.hBmp );
Caret.hBmp = hBmp;
Caret.timeout = GetProfileIntA( "windows", "CursorBlinkRate", 500 );
return TRUE;
}
/*****************************************************************
* DestroyCaret (USER32.@)
*/
BOOL WINAPI DestroyCaret(void)
{
BOOL ret;
HWND prev = 0;
RECT r;
int old_state = 0;
int hidden = 0;
SERVER_START_REQ( set_caret_window )
{
req->handle = 0;
req->width = 0;
req->height = 0;
if ((ret = !wine_server_call_err( req )))
{
prev = wine_server_ptr_handle( reply->previous );
r.left = reply->old_rect.left;
r.top = reply->old_rect.top;
r.right = reply->old_rect.right;
r.bottom = reply->old_rect.bottom;
old_state = reply->old_state;
hidden = reply->old_hide;
}
}
SERVER_END_REQ;
if (ret && prev && !hidden)
{
/* FIXME: won't work if prev belongs to a different process */
KillSystemTimer( prev, TIMERID );
if (old_state) CARET_DisplayCaret( prev, &r );
}
if (Caret.hBmp) DeleteObject( Caret.hBmp );
Caret.hBmp = 0;
return ret;
}
/*****************************************************************
* SetCaretPos (USER32.@)
*/
BOOL WINAPI SetCaretPos( INT x, INT y )
{
BOOL ret;
HWND hwnd = 0;
RECT r;
int old_state = 0;
int hidden = 0;
SERVER_START_REQ( set_caret_info )
{
req->flags = SET_CARET_POS|SET_CARET_STATE;
req->handle = 0;
req->x = x;
req->y = y;
req->hide = 0;
req->state = 1;
if ((ret = !wine_server_call_err( req )))
{
hwnd = wine_server_ptr_handle( reply->full_handle );
r.left = reply->old_rect.left;
r.top = reply->old_rect.top;
r.right = reply->old_rect.right;
r.bottom = reply->old_rect.bottom;
old_state = reply->old_state;
hidden = reply->old_hide;
}
}
SERVER_END_REQ;
if (ret && !hidden && (x != r.left || y != r.top))
{
if (old_state) CARET_DisplayCaret( hwnd, &r );
r.right += x - r.left;
r.bottom += y - r.top;
r.left = x;
r.top = y;
CARET_DisplayCaret( hwnd, &r );
SetSystemTimer( hwnd, TIMERID, Caret.timeout, CARET_Callback );
}
return ret;
}
/*****************************************************************
* HideCaret (USER32.@)
*/
BOOL WINAPI HideCaret( HWND hwnd )
{
BOOL ret;
RECT r;
int old_state = 0;
int hidden = 0;
SERVER_START_REQ( set_caret_info )
{
req->flags = SET_CARET_HIDE|SET_CARET_STATE;
req->handle = wine_server_user_handle( hwnd );
req->x = 0;
req->y = 0;
req->hide = 1;
req->state = 0;
if ((ret = !wine_server_call_err( req )))
{
hwnd = wine_server_ptr_handle( reply->full_handle );
r.left = reply->old_rect.left;
r.top = reply->old_rect.top;
r.right = reply->old_rect.right;
r.bottom = reply->old_rect.bottom;
old_state = reply->old_state;
hidden = reply->old_hide;
}
}
SERVER_END_REQ;
if (ret && !hidden)
{
if (old_state) CARET_DisplayCaret( hwnd, &r );
KillSystemTimer( hwnd, TIMERID );
}
return ret;
}
/*****************************************************************
* ShowCaret (USER32.@)
*/
BOOL WINAPI ShowCaret( HWND hwnd )
{
BOOL ret;
RECT r;
int hidden = 0;
SERVER_START_REQ( set_caret_info )
{
req->flags = SET_CARET_HIDE|SET_CARET_STATE;
req->handle = wine_server_user_handle( hwnd );
req->x = 0;
req->y = 0;
req->hide = -1;
req->state = 1;
if ((ret = !wine_server_call_err( req )))
{
hwnd = wine_server_ptr_handle( reply->full_handle );
r.left = reply->old_rect.left;
r.top = reply->old_rect.top;
r.right = reply->old_rect.right;
r.bottom = reply->old_rect.bottom;
hidden = reply->old_hide;
}
}
SERVER_END_REQ;
if (ret && (hidden == 1)) /* hidden was 1 so it's now 0 */
{
CARET_DisplayCaret( hwnd, &r );
SetSystemTimer( hwnd, TIMERID, Caret.timeout, CARET_Callback );
}
return ret;
}
/*****************************************************************
* GetCaretPos (USER32.@)
*/
BOOL WINAPI GetCaretPos( LPPOINT pt )
{
BOOL ret;
SERVER_START_REQ( set_caret_info )
{
req->flags = 0; /* don't set anything */
req->handle = 0;
req->x = 0;
req->y = 0;
req->hide = 0;
req->state = 0;
if ((ret = !wine_server_call_err( req )))
{
pt->x = reply->old_rect.left;
pt->y = reply->old_rect.top;
}
}
SERVER_END_REQ;
return ret;
}
/*****************************************************************
* SetCaretBlinkTime (USER32.@)
*/
BOOL WINAPI SetCaretBlinkTime( UINT msecs )
{
TRACE("msecs=%d\n", msecs);
Caret.timeout = msecs;
/* if (Caret.hwnd) CARET_SetTimer(); FIXME */
return TRUE;
}
/*****************************************************************
* GetCaretBlinkTime (USER32.@)
*/
UINT WINAPI GetCaretBlinkTime(void)
{
return Caret.timeout;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,599 @@
/*
* WIN32 clipboard implementation
*
* Copyright 1994 Martin Ayotte
* 1996 Alex Korobka
* 1999 Noel Borthwick
* 2003 Ulrich Czekalla for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*
* NOTES:
* This file contains the implementation for the WIN32 Clipboard API
* and Wine's internal clipboard cache.
* The actual contents of the clipboard are held in the clipboard cache.
* The internal implementation talks to a "clipboard driver" to fill or
* expose the cache to the native device. (Currently only the X11 and
* TTY clipboard driver are available)
*/
#include "config.h"
#include "wine/port.h"
#include <stdarg.h>
#include <stdlib.h>
#include <sys/types.h>
#include <fcntl.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#include <string.h>
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"
#include "winerror.h"
#include "user_private.h"
#include "win.h"
#include "wine/debug.h"
#include "wine/unicode.h"
#include "wine/server.h"
WINE_DEFAULT_DEBUG_CHANNEL(clipboard);
#define CF_REGFORMATBASE 0xC000
typedef struct
{
HWND hWndOpen;
HWND hWndOwner;
HWND hWndViewer;
UINT seqno;
UINT flags;
} CLIPBOARDINFO, *LPCLIPBOARDINFO;
/*
* Indicates if data has changed since open.
*/
static BOOL bCBHasChanged = FALSE;
/**************************************************************************
* CLIPBOARD_SetClipboardOwner
*
* Set the global wineserver clipboard owner. The current process will
* be the owner and <hWnd> will get the render notifications.
*/
static BOOL CLIPBOARD_SetClipboardOwner(HWND hWnd)
{
BOOL bRet;
TRACE(" hWnd(%p)\n", hWnd);
SERVER_START_REQ( set_clipboard_info )
{
req->flags = SET_CB_OWNER;
req->owner = wine_server_user_handle( hWnd );
bRet = !wine_server_call_err( req );
}
SERVER_END_REQ;
return bRet;
}
/**************************************************************************
* CLIPBOARD_GetClipboardInfo
*/
static BOOL CLIPBOARD_GetClipboardInfo(LPCLIPBOARDINFO cbInfo)
{
BOOL bRet;
SERVER_START_REQ( set_clipboard_info )
{
req->flags = 0;
if (((bRet = !wine_server_call_err( req ))))
{
cbInfo->hWndOpen = wine_server_ptr_handle( reply->old_clipboard );
cbInfo->hWndOwner = wine_server_ptr_handle( reply->old_owner );
cbInfo->hWndViewer = wine_server_ptr_handle( reply->old_viewer );
cbInfo->seqno = reply->seqno;
cbInfo->flags = reply->flags;
}
}
SERVER_END_REQ;
return bRet;
}
/**************************************************************************
* CLIPBOARD_ReleaseOwner
*/
BOOL CLIPBOARD_ReleaseOwner(void)
{
BOOL bRet = FALSE;
SERVER_START_REQ( set_clipboard_info )
{
req->flags = SET_CB_RELOWNER | SET_CB_SEQNO;
if (wine_server_call_err( req ))
{
ERR("Failed to set clipboard.\n");
}
else
{
bRet = TRUE;
}
}
SERVER_END_REQ;
return bRet;
}
/**************************************************************************
* CLIPBOARD_OpenClipboard
*/
static BOOL CLIPBOARD_OpenClipboard(HWND hWnd)
{
BOOL bRet;
SERVER_START_REQ( set_clipboard_info )
{
req->flags = SET_CB_OPEN;
req->clipboard = wine_server_user_handle( hWnd );
bRet = !wine_server_call( req );
}
SERVER_END_REQ;
return bRet;
}
/**************************************************************************
* CLIPBOARD_CloseClipboard
*/
static BOOL CLIPBOARD_CloseClipboard(void)
{
BOOL bRet;
TRACE(" Changed=%d\n", bCBHasChanged);
SERVER_START_REQ( set_clipboard_info )
{
req->flags = SET_CB_CLOSE;
if (bCBHasChanged) req->flags |= SET_CB_SEQNO;
bRet = !wine_server_call_err( req );
}
SERVER_END_REQ;
return bRet;
}
/**************************************************************************
* CLIPBOARD_SetClipboardViewer
*/
static HWND CLIPBOARD_SetClipboardViewer( HWND hWnd )
{
HWND hwndPrev = 0;
SERVER_START_REQ( set_clipboard_info )
{
req->flags = SET_CB_VIEWER;
req->viewer = wine_server_user_handle( hWnd );
if (!wine_server_call_err( req ))
hwndPrev = wine_server_ptr_handle( reply->old_viewer );
}
SERVER_END_REQ;
return hwndPrev;
}
/**************************************************************************
* WIN32 Clipboard implementation
**************************************************************************/
/**************************************************************************
* RegisterClipboardFormatW (USER32.@)
*/
UINT WINAPI RegisterClipboardFormatW(LPCWSTR FormatName)
{
return USER_Driver->pRegisterClipboardFormat(FormatName);
}
/**************************************************************************
* RegisterClipboardFormatA (USER32.@)
*/
UINT WINAPI RegisterClipboardFormatA(LPCSTR formatName)
{
int len;
LPWSTR wFormat;
UINT ret;
len = MultiByteToWideChar(CP_ACP, 0, formatName, -1, NULL, 0);
wFormat = HeapAlloc(GetProcessHeap(), 0, len*sizeof(WCHAR));
MultiByteToWideChar(CP_ACP, 0, formatName, -1, wFormat, len);
ret = RegisterClipboardFormatW(wFormat);
HeapFree(GetProcessHeap(), 0, wFormat);
return ret;
}
/**************************************************************************
* GetClipboardFormatNameW (USER32.@)
*/
INT WINAPI GetClipboardFormatNameW(UINT wFormat, LPWSTR retStr, INT maxlen)
{
return USER_Driver->pGetClipboardFormatName(wFormat, retStr, maxlen);
}
/**************************************************************************
* GetClipboardFormatNameA (USER32.@)
*/
INT WINAPI GetClipboardFormatNameA(UINT wFormat, LPSTR retStr, INT maxlen)
{
INT ret;
LPWSTR p = HeapAlloc( GetProcessHeap(), 0, maxlen*sizeof(WCHAR) );
if(p == NULL) return 0; /* FIXME: is this the correct failure value? */
ret = GetClipboardFormatNameW( wFormat, p, maxlen );
if (ret && maxlen > 0 && !WideCharToMultiByte( CP_ACP, 0, p, -1, retStr, maxlen, 0, 0))
retStr[maxlen-1] = 0;
HeapFree( GetProcessHeap(), 0, p );
return ret;
}
/**************************************************************************
* OpenClipboard (USER32.@)
*
* Note: Netscape uses NULL hWnd to open the clipboard.
*/
BOOL WINAPI OpenClipboard( HWND hWnd )
{
BOOL bRet;
TRACE("(%p)...\n", hWnd);
bRet = CLIPBOARD_OpenClipboard(hWnd);
TRACE(" returning %i\n", bRet);
return bRet;
}
/**************************************************************************
* CloseClipboard (USER32.@)
*/
BOOL WINAPI CloseClipboard(void)
{
BOOL bRet = FALSE;
TRACE("() Changed=%d\n", bCBHasChanged);
if (CLIPBOARD_CloseClipboard())
{
if (bCBHasChanged)
{
HWND hWndViewer = GetClipboardViewer();
USER_Driver->pEndClipboardUpdate();
bCBHasChanged = FALSE;
if (hWndViewer)
SendMessageW(hWndViewer, WM_DRAWCLIPBOARD, (WPARAM) GetClipboardOwner(), 0);
}
bRet = TRUE;
}
return bRet;
}
/**************************************************************************
* EmptyClipboard (USER32.@)
* Empties and acquires ownership of the clipboard
*/
BOOL WINAPI EmptyClipboard(void)
{
CLIPBOARDINFO cbinfo;
TRACE("()\n");
if (!CLIPBOARD_GetClipboardInfo(&cbinfo) ||
~cbinfo.flags & CB_OPEN)
{
WARN("Clipboard not opened by calling task!\n");
SetLastError(ERROR_CLIPBOARD_NOT_OPEN);
return FALSE;
}
/* Destroy private objects */
if (cbinfo.hWndOwner)
SendMessageW(cbinfo.hWndOwner, WM_DESTROYCLIPBOARD, 0, 0);
/* Tell the driver to acquire the selection. The current owner
* will be signaled to delete it's own cache. */
/* Assign ownership of the clipboard to the current client. We do
* this before acquiring the selection so that when we do acquire the
* selection and the selection loser gets notified, it can check if
* it has lost the Wine clipboard ownership. If it did then it knows
* that a WM_DESTORYCLIPBOARD has already been sent. Otherwise it
* lost the selection to a X app and it should send the
* WM_DESTROYCLIPBOARD itself. */
CLIPBOARD_SetClipboardOwner(cbinfo.hWndOpen);
/* Acquire the selection. This will notify the previous owner
* to clear it's cache. */
USER_Driver->pAcquireClipboard(cbinfo.hWndOpen);
/* Empty the local cache */
USER_Driver->pEmptyClipboard(FALSE);
bCBHasChanged = TRUE;
return TRUE;
}
/**************************************************************************
* GetClipboardOwner (USER32.@)
* FIXME: Can't return the owner if the clipboard is owned by an external X-app
*/
HWND WINAPI GetClipboardOwner(void)
{
HWND hWndOwner = 0;
SERVER_START_REQ( set_clipboard_info )
{
req->flags = 0;
if (!wine_server_call_err( req )) hWndOwner = wine_server_ptr_handle( reply->old_owner );
}
SERVER_END_REQ;
TRACE(" hWndOwner(%p)\n", hWndOwner);
return hWndOwner;
}
/**************************************************************************
* GetOpenClipboardWindow (USER32.@)
*/
HWND WINAPI GetOpenClipboardWindow(void)
{
HWND hWndOpen = 0;
SERVER_START_REQ( set_clipboard_info )
{
req->flags = 0;
if (!wine_server_call_err( req )) hWndOpen = wine_server_ptr_handle( reply->old_clipboard );
}
SERVER_END_REQ;
TRACE(" hWndClipWindow(%p)\n", hWndOpen);
return hWndOpen;
}
/**************************************************************************
* SetClipboardViewer (USER32.@)
*/
HWND WINAPI SetClipboardViewer( HWND hWnd )
{
HWND hwndPrev = CLIPBOARD_SetClipboardViewer(hWnd);
if (hWnd)
SendMessageW(hWnd, WM_DRAWCLIPBOARD, (WPARAM) GetClipboardOwner(), 0);
TRACE("(%p): returning %p\n", hWnd, hwndPrev);
return hwndPrev;
}
/**************************************************************************
* GetClipboardViewer (USER32.@)
*/
HWND WINAPI GetClipboardViewer(void)
{
HWND hWndViewer = 0;
SERVER_START_REQ( set_clipboard_info )
{
req->flags = 0;
if (!wine_server_call_err( req )) hWndViewer = wine_server_ptr_handle( reply->old_viewer );
}
SERVER_END_REQ;
TRACE(" hWndViewer=%p\n", hWndViewer);
return hWndViewer;
}
/**************************************************************************
* ChangeClipboardChain (USER32.@)
*/
BOOL WINAPI ChangeClipboardChain(HWND hWnd, HWND hWndNext)
{
BOOL bRet = TRUE;
HWND hWndViewer = GetClipboardViewer();
if (hWndViewer)
{
if (WIN_GetFullHandle(hWnd) == hWndViewer)
CLIPBOARD_SetClipboardViewer(WIN_GetFullHandle(hWndNext));
else
bRet = !SendMessageW(hWndViewer, WM_CHANGECBCHAIN, (WPARAM)hWnd, (LPARAM)hWndNext);
}
else
ERR("hWndViewer is lost\n");
return bRet;
}
/**************************************************************************
* SetClipboardData (USER32.@)
*/
HANDLE WINAPI SetClipboardData(UINT wFormat, HANDLE hData)
{
CLIPBOARDINFO cbinfo;
HANDLE hResult = 0;
TRACE("(%04X, %p) !\n", wFormat, hData);
/* If it's not owned, data can only be set if the format isn't
available and its rendering is not delayed */
if (!CLIPBOARD_GetClipboardInfo(&cbinfo) ||
(!(cbinfo.flags & CB_OWNER) && !hData))
{
WARN("Clipboard not owned by calling task. Operation failed.\n");
return 0;
}
if (USER_Driver->pSetClipboardData(wFormat, hData, cbinfo.flags & CB_OWNER))
{
hResult = hData;
bCBHasChanged = TRUE;
}
return hResult;
}
/**************************************************************************
* CountClipboardFormats (USER32.@)
*/
INT WINAPI CountClipboardFormats(void)
{
INT count = USER_Driver->pCountClipboardFormats();
TRACE("returning %d\n", count);
return count;
}
/**************************************************************************
* EnumClipboardFormats (USER32.@)
*/
UINT WINAPI EnumClipboardFormats(UINT wFormat)
{
CLIPBOARDINFO cbinfo;
TRACE("(%04X)\n", wFormat);
if (!CLIPBOARD_GetClipboardInfo(&cbinfo) ||
(~cbinfo.flags & CB_OPEN))
{
WARN("Clipboard not opened by calling task.\n");
SetLastError(ERROR_CLIPBOARD_NOT_OPEN);
return 0;
}
return USER_Driver->pEnumClipboardFormats(wFormat);
}
/**************************************************************************
* IsClipboardFormatAvailable (USER32.@)
*/
BOOL WINAPI IsClipboardFormatAvailable(UINT wFormat)
{
BOOL bret = USER_Driver->pIsClipboardFormatAvailable(wFormat);
TRACE("%04x, returning %d\n", wFormat, bret);
return bret;
}
/**************************************************************************
* GetClipboardData (USER32.@)
*/
HANDLE WINAPI GetClipboardData(UINT wFormat)
{
HANDLE hData = 0;
CLIPBOARDINFO cbinfo;
TRACE("%04x\n", wFormat);
if (!CLIPBOARD_GetClipboardInfo(&cbinfo) ||
(~cbinfo.flags & CB_OPEN))
{
WARN("Clipboard not opened by calling task.\n");
SetLastError(ERROR_CLIPBOARD_NOT_OPEN);
return 0;
}
hData = USER_Driver->pGetClipboardData( wFormat );
TRACE("returning %p\n", hData);
return hData;
}
/**************************************************************************
* GetPriorityClipboardFormat (USER32.@)
*/
INT WINAPI GetPriorityClipboardFormat(UINT *list, INT nCount)
{
int i;
TRACE("()\n");
if(CountClipboardFormats() == 0)
return 0;
for (i = 0; i < nCount; i++)
if (IsClipboardFormatAvailable(list[i]))
return list[i];
return -1;
}
/**************************************************************************
* GetClipboardSequenceNumber (USER32.@)
* Supported on Win2k/Win98
* MSDN: Windows clipboard code keeps a serial number for the clipboard
* for each window station. The number is incremented whenever the
* contents change or are emptied.
* If you do not have WINSTA_ACCESSCLIPBOARD then the function returns 0
*/
DWORD WINAPI GetClipboardSequenceNumber(VOID)
{
DWORD seqno = 0;
SERVER_START_REQ( set_clipboard_info )
{
req->flags = 0;
if (!wine_server_call_err( req )) seqno = reply->seqno;
}
SERVER_END_REQ;
TRACE("returning %x\n", seqno);
return seqno;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,248 @@
/*
* User controls definitions
*
* Copyright 2000 Alexandre Julliard
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef __WINE_CONTROLS_H
#define __WINE_CONTROLS_H
#include "winuser.h"
/* Built-in class names (see _Undocumented_Windows_ p.418) */
#define POPUPMENU_CLASS_ATOM MAKEINTATOM(32768) /* PopupMenu */
#define DESKTOP_CLASS_ATOM MAKEINTATOM(32769) /* Desktop */
#define DIALOG_CLASS_ATOM MAKEINTATOM(32770) /* Dialog */
#define WINSWITCH_CLASS_ATOM MAKEINTATOM(32771) /* WinSwitch */
#define ICONTITLE_CLASS_ATOM MAKEINTATOM(32772) /* IconTitle */
enum builtin_winprocs
{
/* dual A/W procs */
WINPROC_BUTTON = 0,
WINPROC_COMBO,
WINPROC_DEFWND,
WINPROC_DIALOG,
WINPROC_EDIT,
WINPROC_LISTBOX,
WINPROC_MDICLIENT,
WINPROC_SCROLLBAR,
WINPROC_STATIC,
/* unicode-only procs */
WINPROC_DESKTOP,
WINPROC_ICONTITLE,
WINPROC_MENU,
WINPROC_MESSAGE,
NB_BUILTIN_WINPROCS,
NB_BUILTIN_AW_WINPROCS = WINPROC_DESKTOP
};
#define WINPROC_HANDLE (~0u >> 16)
#define BUILTIN_WINPROC(index) ((WNDPROC)(ULONG_PTR)((index) | (WINPROC_HANDLE << 16)))
/* Built-in class descriptor */
struct builtin_class_descr
{
LPCWSTR name; /* class name */
UINT style; /* class style */
enum builtin_winprocs proc;
INT extra; /* window extra bytes */
ULONG_PTR cursor; /* cursor id */
HBRUSH brush; /* brush or system color */
};
extern const struct builtin_class_descr BUTTON_builtin_class DECLSPEC_HIDDEN;
extern const struct builtin_class_descr COMBO_builtin_class DECLSPEC_HIDDEN;
extern const struct builtin_class_descr COMBOLBOX_builtin_class DECLSPEC_HIDDEN;
extern const struct builtin_class_descr DIALOG_builtin_class DECLSPEC_HIDDEN;
extern const struct builtin_class_descr DESKTOP_builtin_class DECLSPEC_HIDDEN;
extern const struct builtin_class_descr EDIT_builtin_class DECLSPEC_HIDDEN;
extern const struct builtin_class_descr ICONTITLE_builtin_class DECLSPEC_HIDDEN;
extern const struct builtin_class_descr LISTBOX_builtin_class DECLSPEC_HIDDEN;
extern const struct builtin_class_descr MDICLIENT_builtin_class DECLSPEC_HIDDEN;
extern const struct builtin_class_descr MENU_builtin_class DECLSPEC_HIDDEN;
extern const struct builtin_class_descr MESSAGE_builtin_class DECLSPEC_HIDDEN;
extern const struct builtin_class_descr SCROLL_builtin_class DECLSPEC_HIDDEN;
extern const struct builtin_class_descr STATIC_builtin_class DECLSPEC_HIDDEN;
extern LRESULT WINAPI DesktopWndProc(HWND,UINT,WPARAM,LPARAM) DECLSPEC_HIDDEN;
extern LRESULT WINAPI IconTitleWndProc(HWND,UINT,WPARAM,LPARAM) DECLSPEC_HIDDEN;
extern LRESULT WINAPI PopupMenuWndProc(HWND,UINT,WPARAM,LPARAM) DECLSPEC_HIDDEN;
extern LRESULT WINAPI MessageWndProc(HWND,UINT,WPARAM,LPARAM) DECLSPEC_HIDDEN;
/* Wow handlers */
/* the structures must match the corresponding ones in user.exe */
struct wow_handlers16
{
LRESULT (*button_proc)(HWND,UINT,WPARAM,LPARAM,BOOL);
LRESULT (*combo_proc)(HWND,UINT,WPARAM,LPARAM,BOOL);
LRESULT (*edit_proc)(HWND,UINT,WPARAM,LPARAM,BOOL);
LRESULT (*listbox_proc)(HWND,UINT,WPARAM,LPARAM,BOOL);
LRESULT (*mdiclient_proc)(HWND,UINT,WPARAM,LPARAM,BOOL);
LRESULT (*scrollbar_proc)(HWND,UINT,WPARAM,LPARAM,BOOL);
LRESULT (*static_proc)(HWND,UINT,WPARAM,LPARAM,BOOL);
DWORD (*wait_message)(DWORD,const HANDLE*,DWORD,DWORD,DWORD);
HWND (*create_window)(CREATESTRUCTW*,LPCWSTR,HINSTANCE,BOOL);
LRESULT (*call_window_proc)(HWND,UINT,WPARAM,LPARAM,LRESULT*,void*);
LRESULT (*call_dialog_proc)(HWND,UINT,WPARAM,LPARAM,LRESULT*,void*);
void (*free_icon_param)(ULONG_PTR);
};
struct wow_handlers32
{
LRESULT (*button_proc)(HWND,UINT,WPARAM,LPARAM,BOOL);
LRESULT (*combo_proc)(HWND,UINT,WPARAM,LPARAM,BOOL);
LRESULT (*edit_proc)(HWND,UINT,WPARAM,LPARAM,BOOL);
LRESULT (*listbox_proc)(HWND,UINT,WPARAM,LPARAM,BOOL);
LRESULT (*mdiclient_proc)(HWND,UINT,WPARAM,LPARAM,BOOL);
LRESULT (*scrollbar_proc)(HWND,UINT,WPARAM,LPARAM,BOOL);
LRESULT (*static_proc)(HWND,UINT,WPARAM,LPARAM,BOOL);
DWORD (*wait_message)(DWORD,const HANDLE*,DWORD,DWORD,DWORD);
HWND (*create_window)(CREATESTRUCTW*,LPCWSTR,HINSTANCE,BOOL);
HWND (*get_win_handle)(HWND);
WNDPROC (*alloc_winproc)(WNDPROC,BOOL);
struct tagDIALOGINFO *(*get_dialog_info)(HWND,BOOL);
INT (*dialog_box_loop)(HWND,HWND);
ULONG_PTR (*get_icon_param)(HICON);
ULONG_PTR (*set_icon_param)(HICON,ULONG_PTR);
};
extern struct wow_handlers16 wow_handlers DECLSPEC_HIDDEN;
extern LRESULT ButtonWndProc_common(HWND,UINT,WPARAM,LPARAM,BOOL) DECLSPEC_HIDDEN;
extern LRESULT ComboWndProc_common(HWND,UINT,WPARAM,LPARAM,BOOL) DECLSPEC_HIDDEN;
extern LRESULT EditWndProc_common(HWND,UINT,WPARAM,LPARAM,BOOL) DECLSPEC_HIDDEN;
extern LRESULT ListBoxWndProc_common(HWND,UINT,WPARAM,LPARAM,BOOL) DECLSPEC_HIDDEN;
extern LRESULT MDIClientWndProc_common(HWND,UINT,WPARAM,LPARAM,BOOL) DECLSPEC_HIDDEN;
extern LRESULT ScrollBarWndProc_common(HWND,UINT,WPARAM,LPARAM,BOOL) DECLSPEC_HIDDEN;
extern LRESULT StaticWndProc_common(HWND,UINT,WPARAM,LPARAM,BOOL) DECLSPEC_HIDDEN;
extern ULONG_PTR get_icon_param( HICON handle ) DECLSPEC_HIDDEN;
extern ULONG_PTR set_icon_param( HICON handle, ULONG_PTR param ) DECLSPEC_HIDDEN;
/* Class functions */
struct tagCLASS; /* opaque structure */
struct tagWND;
extern ATOM get_int_atom_value( LPCWSTR name ) DECLSPEC_HIDDEN;
extern void CLASS_RegisterBuiltinClasses(void) DECLSPEC_HIDDEN;
extern WNDPROC get_class_winproc( struct tagCLASS *class ) DECLSPEC_HIDDEN;
extern struct dce *get_class_dce( struct tagCLASS *class ) DECLSPEC_HIDDEN;
extern struct dce *set_class_dce( struct tagCLASS *class, struct dce *dce ) DECLSPEC_HIDDEN;
/* defwnd proc */
extern HBRUSH DEFWND_ControlColor( HDC hDC, UINT ctlType ) DECLSPEC_HIDDEN;
/* desktop */
extern BOOL DESKTOP_SetPattern( LPCWSTR pattern ) DECLSPEC_HIDDEN;
/* icon title */
extern HWND ICONTITLE_Create( HWND hwnd ) DECLSPEC_HIDDEN;
/* menu controls */
extern HWND MENU_IsMenuActive(void) DECLSPEC_HIDDEN;
extern UINT MENU_GetMenuBarHeight( HWND hwnd, UINT menubarWidth,
INT orgX, INT orgY ) DECLSPEC_HIDDEN;
extern BOOL MENU_SetMenu(HWND, HMENU) DECLSPEC_HIDDEN;
extern void MENU_TrackMouseMenuBar( HWND hwnd, INT ht, POINT pt ) DECLSPEC_HIDDEN;
extern void MENU_TrackKbdMenuBar( HWND hwnd, UINT wParam, WCHAR wChar ) DECLSPEC_HIDDEN;
extern UINT MENU_DrawMenuBar( HDC hDC, LPRECT lprect,
HWND hwnd, BOOL suppress_draw ) DECLSPEC_HIDDEN;
extern void MENU_EndMenu(HWND) DECLSPEC_HIDDEN;
/* nonclient area */
extern LRESULT NC_HandleNCPaint( HWND hwnd , HRGN clip) DECLSPEC_HIDDEN;
extern LRESULT NC_HandleNCActivate( HWND hwnd, WPARAM wParam, LPARAM lParam ) DECLSPEC_HIDDEN;
extern LRESULT NC_HandleNCCalcSize( HWND hwnd, WPARAM wParam, RECT *winRect ) DECLSPEC_HIDDEN;
extern LRESULT NC_HandleNCHitTest( HWND hwnd, POINT pt ) DECLSPEC_HIDDEN;
extern LRESULT NC_HandleNCLButtonDown( HWND hwnd, WPARAM wParam, LPARAM lParam ) DECLSPEC_HIDDEN;
extern LRESULT NC_HandleNCLButtonDblClk( HWND hwnd, WPARAM wParam, LPARAM lParam) DECLSPEC_HIDDEN;
extern LRESULT NC_HandleSysCommand( HWND hwnd, WPARAM wParam, LPARAM lParam ) DECLSPEC_HIDDEN;
extern LRESULT NC_HandleSetCursor( HWND hwnd, WPARAM wParam, LPARAM lParam ) DECLSPEC_HIDDEN;
extern BOOL NC_DrawSysButton( HWND hwnd, HDC hdc, BOOL down ) DECLSPEC_HIDDEN;
extern void NC_GetSysPopupPos( HWND hwnd, RECT* rect ) DECLSPEC_HIDDEN;
/* scrollbar */
extern void SCROLL_DrawScrollBar( HWND hwnd, HDC hdc, INT nBar, BOOL arrows, BOOL interior ) DECLSPEC_HIDDEN;
extern void SCROLL_TrackScrollBar( HWND hwnd, INT scrollbar, POINT pt ) DECLSPEC_HIDDEN;
extern INT SCROLL_SetNCSbState( HWND hwnd, int vMin, int vMax, int vPos,
int hMin, int hMax, int hPos ) DECLSPEC_HIDDEN;
/* combo box */
#define ID_CB_LISTBOX 1000
#define ID_CB_EDIT 1001
/* internal flags */
#define CBF_DROPPED 0x0001
#define CBF_BUTTONDOWN 0x0002
#define CBF_NOROLLUP 0x0004
#define CBF_MEASUREITEM 0x0008
#define CBF_FOCUSED 0x0010
#define CBF_CAPTURE 0x0020
#define CBF_EDIT 0x0040
#define CBF_NORESIZE 0x0080
#define CBF_NOTIFY 0x0100
#define CBF_NOREDRAW 0x0200
#define CBF_SELCHANGE 0x0400
#define CBF_NOEDITNOTIFY 0x1000
#define CBF_NOLBSELECT 0x2000 /* do not change current selection */
#define CBF_BEENFOCUSED 0x4000 /* has it ever had focus */
#define CBF_EUI 0x8000
/* combo state struct */
typedef struct
{
HWND self;
HWND owner;
UINT dwStyle;
HWND hWndEdit;
HWND hWndLBox;
UINT wState;
HFONT hFont;
RECT textRect;
RECT buttonRect;
RECT droppedRect;
INT droppedIndex;
INT fixedOwnerDrawHeight;
INT droppedWidth; /* last two are not used unless set */
INT editHeight; /* explicitly */
} HEADCOMBO,*LPHEADCOMBO;
extern BOOL COMBO_FlipListbox( LPHEADCOMBO, BOOL, BOOL ) DECLSPEC_HIDDEN;
/* Dialog info structure (note: shared with user.exe) */
typedef struct tagDIALOGINFO
{
HWND hwndFocus; /* Current control with focus */
HFONT hUserFont; /* Dialog font */
HMENU hMenu; /* Dialog menu */
UINT xBaseUnit; /* Dialog units (depends on the font) */
UINT yBaseUnit;
INT idResult; /* EndDialog() result / default pushbutton ID */
UINT flags; /* EndDialog() called for this dialog */
} DIALOGINFO;
#define DF_END 0x0001
#define DF_OWNERENABLED 0x0002
extern DIALOGINFO *DIALOG_get_info( HWND hwnd, BOOL create ) DECLSPEC_HIDDEN;
extern INT DIALOG_DoDialogBox( HWND hwnd, HWND owner ) DECLSPEC_HIDDEN;
HRGN set_control_clipping( HDC hdc, const RECT *rect ) DECLSPEC_HIDDEN;
#endif /* __WINE_CONTROLS_H */

144
arwinss/client/user32/csr.c Normal file
View File

@@ -0,0 +1,144 @@
/*
* COPYRIGHT: GNU LGPL v2.1 or any later version as
published by the Free Software Foundation
* PROJECT: ReactOS
* FILE: dll/win32/user32/csr.c
* PURPOSE: ReactOS-specific interaction with CSR
* PROGRAMMER: Aleksey Bragin <aleksey@reactos.org>
*/
/* INCLUDES ******************************************************************/
/* C Headers */
#include <assert.h>
#include <stdio.h>
#include <math.h>
/* SDK/NDK Headers */
#define _USER32_
#define OEMRESOURCE
#define NTOS_MODE_USER
#define WIN32_NO_STATUS
#include <windows.h>
#include <winuser.h>
#include <windowsx.h>
#include <winnls32.h>
#include <ndk/ntndk.h>
//#include <ddk/ntstatus.h>
/* CSRSS Headers */
#include <subsys/csr/csr.h>
#include <ntuser.h>
#include <subsys/win/winmsg.h>
#include "wine/rosuser.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(usercsr);
/* GLOBALS ********************************************************************/
BOOLEAN gfLogonProcess = FALSE;
/* FUNCTIONS ******************************************************************/
/***********************************************************************
* ExitWindowsEx (USER32.@)
*/
BOOL WINAPI ExitWindowsEx( UINT uFlags, DWORD dwReserved )
{
NTSTATUS Status;
USER_API_MESSAGE ApiMessage;
PUSER_EXIT_REACTOS ExitReactOSRequest = &ApiMessage.Data.ExitReactOSRequest;
ExitReactOSRequest->Flags = uFlags;
//ExitReactOSRequest->Reserved = dwReserved;
Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
NULL,
CSR_CREATE_API_NUMBER(USERSRV_SERVERDLL_INDEX, UserpExitWindowsEx),
sizeof(USER_EXIT_REACTOS));
if (!NT_SUCCESS(Status))
{
SetLastError(RtlNtStatusToDosError(Status));
ExitReactOSRequest->Success = FALSE;
return FALSE;
}
return TRUE;
}
/***********************************************************************
* RegisterServicesProcess (USER32.@)
*/
BOOL WINAPI
RegisterServicesProcess(DWORD ServicesProcessId)
{
NTSTATUS Status;
USER_API_MESSAGE ApiMessage;
ApiMessage.Data.RegisterServicesProcessRequest.ProcessId = ServicesProcessId;
Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
NULL,
CSR_CREATE_API_NUMBER(USERSRV_SERVERDLL_INDEX, UserpRegisterServicesProcess),
sizeof(USER_REGISTER_SERVICES_PROCESS));
if (!NT_SUCCESS(Status))
{
SetLastError(RtlNtStatusToDosError(Status));
return FALSE;
}
return TRUE;
}
EXTINLINE BOOL NtUserxRegisterLogonProcess(DWORD dwProcessId, BOOL bRegister)
{
return (BOOL)NtUserCallTwoParam((DWORD_PTR)dwProcessId, (DWORD_PTR)bRegister, TWOPARAM_ROUTINE_REGISTERLOGONPROCESS);
}
/***********************************************************************
* RegisterLogonProcess (USER32.@)
*/
BOOL
WINAPI
RegisterLogonProcess(DWORD dwProcessId,
BOOL bRegister)
{
gfLogonProcess = NtUserxRegisterLogonProcess(dwProcessId, bRegister);
if (gfLogonProcess)
{
USER_API_MESSAGE ApiMessage;
PUSER_REGISTER_LOGON_PROCESS RegisterLogonProcessRequest = &ApiMessage.Data.RegisterLogonProcessRequest;
RegisterLogonProcessRequest->ProcessId = dwProcessId;
RegisterLogonProcessRequest->Register = bRegister;
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
NULL,
CSR_CREATE_API_NUMBER(USERSRV_SERVERDLL_INDEX, UserpRegisterLogonProcess),
sizeof(*RegisterLogonProcessRequest));
if (!NT_SUCCESS(ApiMessage.Status))
{
ERR("Failed to register logon process with CSRSS\n");
SetLastError(RtlNtStatusToDosError(ApiMessage.Status));
}
}
return gfLogonProcess;
}
/***********************************************************************
* SetLogonNotifyWindow (USER32.@)
*/
BOOL
WINAPI
SetLogonNotifyWindow (HWND Wnd)
{
return NtUserSetLogonNotifyWindow(Wnd);
}
/* EOF */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -19,7 +19,7 @@
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef __WINE_DDEML_PRIVATE_H
@@ -143,7 +143,7 @@ typedef struct tagWDML_CONV
/* DDE_LINK struct defines hot, warm, and cold links */
typedef struct tagWDML_LINK {
struct tagWDML_LINK* next; /* to link all the active links */
HCONV hConv; /* to get back to the converstaion */
HCONV hConv; /* to get back to the conversation */
UINT transactionType;/* 0 for no link */
HSZ hszItem; /* item targetted for (hot/warm) link */
UINT uFmt; /* format for data */
@@ -169,8 +169,6 @@ typedef struct tagWDML_INSTANCE
WDML_LINK* links[2]; /* active links for this instance (client and server) */
} WDML_INSTANCE;
extern CRITICAL_SECTION WDML_CritSect; /* protection for instance list */
/* header for the DDE Data objects */
typedef struct tagDDE_DATAHANDLE_HEAD
{
@@ -189,66 +187,66 @@ typedef enum {
extern HDDEDATA WDML_InvokeCallback(WDML_INSTANCE* pInst, UINT uType, UINT uFmt, HCONV hConv,
HSZ hsz1, HSZ hsz2, HDDEDATA hdata,
ULONG_PTR dwData1, ULONG_PTR dwData2);
extern WDML_SERVER* WDML_AddServer(WDML_INSTANCE* pInstance, HSZ hszService, HSZ hszTopic);
extern void WDML_RemoveServer(WDML_INSTANCE* pInstance, HSZ hszService, HSZ hszTopic);
extern WDML_SERVER* WDML_FindServer(WDML_INSTANCE* pInstance, HSZ hszService, HSZ hszTopic);
ULONG_PTR dwData1, ULONG_PTR dwData2) DECLSPEC_HIDDEN;
extern WDML_SERVER* WDML_AddServer(WDML_INSTANCE* pInstance, HSZ hszService, HSZ hszTopic) DECLSPEC_HIDDEN;
extern void WDML_RemoveServer(WDML_INSTANCE* pInstance, HSZ hszService, HSZ hszTopic) DECLSPEC_HIDDEN;
extern WDML_SERVER* WDML_FindServer(WDML_INSTANCE* pInstance, HSZ hszService, HSZ hszTopic) DECLSPEC_HIDDEN;
/* transaction handler on the server side */
extern WDML_QUEUE_STATE WDML_ServerHandle(WDML_CONV* pConv, WDML_XACT* pXAct);
extern WDML_QUEUE_STATE WDML_ServerHandle(WDML_CONV* pConv, WDML_XACT* pXAct) DECLSPEC_HIDDEN;
/* transaction handler on the client side */
HDDEDATA WDML_ClientHandle(WDML_CONV *pConv, WDML_XACT *pXAct, DWORD dwTimeout, LPDWORD pdwResult) DECLSPEC_HIDDEN;
/* called both in DdeClientTransaction and server side. */
extern UINT WDML_Initialize(LPDWORD pidInst, PFNCALLBACK pfnCallback,
DWORD afCmd, DWORD ulRes, BOOL bUnicode);
DWORD afCmd, DWORD ulRes, BOOL bUnicode) DECLSPEC_HIDDEN;
extern WDML_CONV* WDML_AddConv(WDML_INSTANCE* pInstance, WDML_SIDE side,
HSZ hszService, HSZ hszTopic, HWND hwndClient, HWND hwndServer);
extern void WDML_RemoveConv(WDML_CONV* pConv, WDML_SIDE side);
extern WDML_CONV* WDML_GetConv(HCONV hConv, BOOL checkConnected);
extern WDML_CONV* WDML_GetConvFromWnd(HWND hWnd);
HSZ hszService, HSZ hszTopic, HWND hwndClient, HWND hwndServer) DECLSPEC_HIDDEN;
extern void WDML_RemoveConv(WDML_CONV* pConv, WDML_SIDE side) DECLSPEC_HIDDEN;
extern WDML_CONV* WDML_GetConv(HCONV hConv, BOOL checkConnected) DECLSPEC_HIDDEN;
extern WDML_CONV* WDML_GetConvFromWnd(HWND hWnd) DECLSPEC_HIDDEN;
extern WDML_CONV* WDML_FindConv(WDML_INSTANCE* pInstance, WDML_SIDE side,
HSZ hszService, HSZ hszTopic);
HSZ hszService, HSZ hszTopic) DECLSPEC_HIDDEN;
extern BOOL WDML_PostAck(WDML_CONV* pConv, WDML_SIDE side, WORD appRetCode,
BOOL fBusy, BOOL fAck, UINT_PTR pmt, LPARAM lParam, UINT oldMsg);
BOOL fBusy, BOOL fAck, UINT_PTR pmt, LPARAM lParam, UINT oldMsg) DECLSPEC_HIDDEN;
extern void WDML_AddLink(WDML_INSTANCE* pInstance, HCONV hConv, WDML_SIDE side,
UINT wType, HSZ hszItem, UINT wFmt);
UINT wType, HSZ hszItem, UINT wFmt) DECLSPEC_HIDDEN;
extern WDML_LINK* WDML_FindLink(WDML_INSTANCE* pInstance, HCONV hConv, WDML_SIDE side,
HSZ hszItem, BOOL use_fmt, UINT uFmt);
HSZ hszItem, BOOL use_fmt, UINT uFmt) DECLSPEC_HIDDEN;
extern void WDML_RemoveLink(WDML_INSTANCE* pInstance, HCONV hConv, WDML_SIDE side,
HSZ hszItem, UINT wFmt);
extern void WDML_RemoveAllLinks(WDML_INSTANCE* pInstance, WDML_CONV* pConv, WDML_SIDE side);
HSZ hszItem, UINT wFmt) DECLSPEC_HIDDEN;
extern void WDML_RemoveAllLinks(WDML_INSTANCE* pInstance, WDML_CONV* pConv, WDML_SIDE side) DECLSPEC_HIDDEN;
/* string internals */
extern void WDML_FreeAllHSZ(WDML_INSTANCE* pInstance);
extern BOOL WDML_DecHSZ(WDML_INSTANCE* pInstance, HSZ hsz);
extern BOOL WDML_IncHSZ(WDML_INSTANCE* pInstance, HSZ hsz);
extern ATOM WDML_MakeAtomFromHsz(HSZ hsz);
extern HSZ WDML_MakeHszFromAtom(const WDML_INSTANCE* pInstance, ATOM atom);
extern void WDML_FreeAllHSZ(WDML_INSTANCE* pInstance) DECLSPEC_HIDDEN;
extern BOOL WDML_DecHSZ(WDML_INSTANCE* pInstance, HSZ hsz) DECLSPEC_HIDDEN;
extern BOOL WDML_IncHSZ(WDML_INSTANCE* pInstance, HSZ hsz) DECLSPEC_HIDDEN;
extern ATOM WDML_MakeAtomFromHsz(HSZ hsz) DECLSPEC_HIDDEN;
extern HSZ WDML_MakeHszFromAtom(const WDML_INSTANCE* pInstance, ATOM atom) DECLSPEC_HIDDEN;
/* client calls these */
extern WDML_XACT* WDML_AllocTransaction(WDML_INSTANCE* pInstance, UINT ddeMsg, UINT wFmt, HSZ hszItem);
extern void WDML_QueueTransaction(WDML_CONV* pConv, WDML_XACT* pXAct);
extern BOOL WDML_UnQueueTransaction(WDML_CONV* pConv, WDML_XACT* pXAct);
extern void WDML_FreeTransaction(WDML_INSTANCE* pInstance, WDML_XACT* pXAct, BOOL doFreePmt);
extern WDML_XACT* WDML_FindTransaction(WDML_CONV* pConv, DWORD tid);
extern HGLOBAL WDML_DataHandle2Global(HDDEDATA hDdeData, BOOL fResponse, BOOL fRelease,
BOOL fDeferUpd, BOOL fAckReq);
extern HDDEDATA WDML_Global2DataHandle(WDML_CONV* pConv, HGLOBAL hMem, WINE_DDEHEAD* p);
extern BOOL WDML_IsAppOwned(HDDEDATA hDdeData);
extern WDML_INSTANCE* WDML_GetInstance(DWORD InstId);
extern WDML_INSTANCE* WDML_GetInstanceFromWnd(HWND hWnd);
extern WDML_XACT* WDML_AllocTransaction(WDML_INSTANCE* pInstance, UINT ddeMsg, UINT wFmt, HSZ hszItem) DECLSPEC_HIDDEN;
extern void WDML_QueueTransaction(WDML_CONV* pConv, WDML_XACT* pXAct) DECLSPEC_HIDDEN;
extern BOOL WDML_UnQueueTransaction(WDML_CONV* pConv, WDML_XACT* pXAct) DECLSPEC_HIDDEN;
extern void WDML_FreeTransaction(WDML_INSTANCE* pInstance, WDML_XACT* pXAct, BOOL doFreePmt) DECLSPEC_HIDDEN;
extern WDML_XACT* WDML_FindTransaction(WDML_CONV* pConv, DWORD tid) DECLSPEC_HIDDEN;
extern HGLOBAL WDML_DataHandle2Global(HDDEDATA hDdeData, BOOL fResponse, BOOL fRelease,
BOOL fDeferUpd, BOOL dAckReq) DECLSPEC_HIDDEN;
extern HDDEDATA WDML_Global2DataHandle(WDML_CONV* pConv, HGLOBAL hMem, WINE_DDEHEAD* da) DECLSPEC_HIDDEN;
extern BOOL WDML_IsAppOwned(HDDEDATA hDdeData) DECLSPEC_HIDDEN;
extern WDML_INSTANCE* WDML_GetInstance(DWORD InstId) DECLSPEC_HIDDEN;
extern WDML_INSTANCE* WDML_GetInstanceFromWnd(HWND hWnd) DECLSPEC_HIDDEN;
/* broadcasting to DDE windows */
extern void WDML_BroadcastDDEWindows(LPCWSTR clsName, UINT uMsg,
WPARAM wParam, LPARAM lParam);
extern void WDML_NotifyThreadExit(DWORD tid);
WPARAM wParam, LPARAM lParam) DECLSPEC_HIDDEN;
extern void WDML_NotifyThreadExit(DWORD tid) DECLSPEC_HIDDEN;
static __inline void WDML_ExtractAck(WORD status, DDEACK* da)
static inline void WDML_ExtractAck(WORD status, DDEACK* da)
{
*da = *((DDEACK*)&status);
}
extern const WCHAR WDML_szEventClass[]; /* class of window for events (aka instance) */
extern const char WDML_szServerConvClassA[]; /* ANSI class of window for server side conv */
extern const WCHAR WDML_szServerConvClassW[]; /* unicode class of window for server side conv */
extern const char WDML_szClientConvClassA[]; /* ANSI class of window for client side conv */
extern const WCHAR WDML_szClientConvClassW[]; /* unicode class of window for client side conv */
extern const WCHAR WDML_szEventClass[] DECLSPEC_HIDDEN; /* class of window for events (aka instance) */
extern const char WDML_szServerConvClassA[] DECLSPEC_HIDDEN; /* ANSI class of window for server side conv */
extern const WCHAR WDML_szServerConvClassW[] DECLSPEC_HIDDEN; /* unicode class of window for server side conv */
extern const char WDML_szClientConvClassA[] DECLSPEC_HIDDEN; /* ANSI class of window for client side conv */
extern const WCHAR WDML_szClientConvClassW[] DECLSPEC_HIDDEN; /* unicode class of window for client side conv */
#define WM_WDML_REGISTER (WM_USER + 0x200)
#define WM_WDML_UNREGISTER (WM_USER + 0x201)

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,465 @@
/*
* Default dialog procedure
*
* Copyright 1993, 1996 Alexandre Julliard
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <stdarg.h>
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"
#include "controls.h"
#include "win.h"
#include "user_private.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(dialog);
/***********************************************************************
* DEFDLG_GetDlgProc
*/
static DLGPROC DEFDLG_GetDlgProc( HWND hwnd )
{
DLGPROC ret;
WND *wndPtr = WIN_GetPtr( hwnd );
if (!wndPtr) return 0;
if (wndPtr == WND_OTHER_PROCESS)
{
ERR( "cannot get dlg proc %p from other process\n", hwnd );
return 0;
}
ret = *(DLGPROC *)((char *)wndPtr->wExtra + DWLP_DLGPROC);
WIN_ReleasePtr( wndPtr );
return ret;
}
/***********************************************************************
* DEFDLG_SetFocus
*
* Set the focus to a control of the dialog, selecting the text if
* the control is an edit dialog.
*/
static void DEFDLG_SetFocus( HWND hwndDlg, HWND hwndCtrl )
{
if (SendMessageW( hwndCtrl, WM_GETDLGCODE, 0, 0 ) & DLGC_HASSETSEL)
SendMessageW( hwndCtrl, EM_SETSEL, 0, -1 );
SetFocus( hwndCtrl );
}
/***********************************************************************
* DEFDLG_SaveFocus
*/
static void DEFDLG_SaveFocus( HWND hwnd )
{
DIALOGINFO *infoPtr;
HWND hwndFocus = GetFocus();
if (!hwndFocus || !IsChild( hwnd, hwndFocus )) return;
if (!(infoPtr = DIALOG_get_info( hwnd, FALSE ))) return;
infoPtr->hwndFocus = hwndFocus;
/* Remove default button */
}
/***********************************************************************
* DEFDLG_RestoreFocus
*/
static void DEFDLG_RestoreFocus( HWND hwnd )
{
DIALOGINFO *infoPtr;
if (IsIconic( hwnd )) return;
if (!(infoPtr = DIALOG_get_info( hwnd, FALSE ))) return;
/* Don't set the focus back to controls if EndDialog is already called.*/
if (infoPtr->flags & DF_END) return;
if (!IsWindow(infoPtr->hwndFocus) || infoPtr->hwndFocus == hwnd) {
/* If no saved focus control exists, set focus to the first visible,
non-disabled, WS_TABSTOP control in the dialog */
infoPtr->hwndFocus = GetNextDlgTabItem( hwnd, 0, FALSE );
if (!IsWindow( infoPtr->hwndFocus )) return;
}
DEFDLG_SetFocus( hwnd, infoPtr->hwndFocus );
/* This used to set infoPtr->hwndFocus to NULL for no apparent reason,
sometimes losing focus when receiving WM_SETFOCUS messages. */
}
/***********************************************************************
* DEFDLG_FindDefButton
*
* Find the current default push-button.
*/
static HWND DEFDLG_FindDefButton( HWND hwndDlg )
{
HWND hwndChild, hwndTmp;
hwndChild = GetWindow( hwndDlg, GW_CHILD );
while (hwndChild)
{
if (SendMessageW( hwndChild, WM_GETDLGCODE, 0, 0 ) & DLGC_DEFPUSHBUTTON)
break;
/* Recurse into WS_EX_CONTROLPARENT controls */
if (GetWindowLongW( hwndChild, GWL_EXSTYLE ) & WS_EX_CONTROLPARENT)
{
LONG dsStyle = GetWindowLongW( hwndChild, GWL_STYLE );
if ((dsStyle & WS_VISIBLE) && !(dsStyle & WS_DISABLED) &&
(hwndTmp = DEFDLG_FindDefButton(hwndChild)) != NULL)
return hwndTmp;
}
hwndChild = GetWindow( hwndChild, GW_HWNDNEXT );
}
return hwndChild;
}
/***********************************************************************
* DEFDLG_SetDefId
*
* Set the default button id.
*/
static BOOL DEFDLG_SetDefId( HWND hwndDlg, DIALOGINFO *dlgInfo, WPARAM wParam)
{
DWORD dlgcode=0; /* initialize just to avoid a warning */
HWND hwndOld, hwndNew = GetDlgItem(hwndDlg, wParam);
INT old_id = dlgInfo->idResult;
dlgInfo->idResult = wParam;
if (hwndNew &&
!((dlgcode=SendMessageW(hwndNew, WM_GETDLGCODE, 0, 0 ))
& (DLGC_UNDEFPUSHBUTTON | DLGC_BUTTON)))
return FALSE; /* Destination is not a push button */
/* Make sure the old default control is a valid push button ID */
hwndOld = GetDlgItem( hwndDlg, old_id );
if (!hwndOld || !(SendMessageW( hwndOld, WM_GETDLGCODE, 0, 0) & DLGC_DEFPUSHBUTTON))
hwndOld = DEFDLG_FindDefButton( hwndDlg );
if (hwndOld && hwndOld != hwndNew)
SendMessageW( hwndOld, BM_SETSTYLE, BS_PUSHBUTTON, TRUE );
if (hwndNew)
{
if(dlgcode & DLGC_UNDEFPUSHBUTTON)
SendMessageW( hwndNew, BM_SETSTYLE, BS_DEFPUSHBUTTON, TRUE );
}
return TRUE;
}
/***********************************************************************
* DEFDLG_SetDefButton
*
* Set the new default button to be hwndNew.
*/
static BOOL DEFDLG_SetDefButton( HWND hwndDlg, DIALOGINFO *dlgInfo, HWND hwndNew )
{
DWORD dlgcode=0; /* initialize just to avoid a warning */
HWND hwndOld = GetDlgItem( hwndDlg, dlgInfo->idResult );
if (hwndNew &&
!((dlgcode=SendMessageW(hwndNew, WM_GETDLGCODE, 0, 0 ))
& (DLGC_UNDEFPUSHBUTTON | DLGC_DEFPUSHBUTTON)))
{
/**
* Need to draw only default push button rectangle.
* Since the next control is not a push button, need to draw the push
* button rectangle for the default control.
*/
hwndNew = hwndOld;
dlgcode = SendMessageW(hwndNew, WM_GETDLGCODE, 0, 0 );
}
/* Make sure the old default control is a valid push button ID */
if (!hwndOld || !(SendMessageW( hwndOld, WM_GETDLGCODE, 0, 0) & DLGC_DEFPUSHBUTTON))
hwndOld = DEFDLG_FindDefButton( hwndDlg );
if (hwndOld && hwndOld != hwndNew)
SendMessageW( hwndOld, BM_SETSTYLE, BS_PUSHBUTTON, TRUE );
if (hwndNew)
{
if(dlgcode & DLGC_UNDEFPUSHBUTTON)
SendMessageW( hwndNew, BM_SETSTYLE, BS_DEFPUSHBUTTON, TRUE );
}
return TRUE;
}
/***********************************************************************
* DEFDLG_Proc
*
* Implementation of DefDlgProc(). Only handle messages that need special
* handling for dialogs.
*/
static LRESULT DEFDLG_Proc( HWND hwnd, UINT msg, WPARAM wParam,
LPARAM lParam, DIALOGINFO *dlgInfo )
{
switch(msg)
{
case WM_ERASEBKGND:
{
HBRUSH brush = (HBRUSH)SendMessageW( hwnd, WM_CTLCOLORDLG, wParam, (LPARAM)hwnd );
if (!brush) brush = (HBRUSH)DefWindowProcW( hwnd, WM_CTLCOLORDLG, wParam, (LPARAM)hwnd );
if (brush)
{
RECT rect;
HDC hdc = (HDC)wParam;
GetClientRect( hwnd, &rect );
DPtoLP( hdc, (LPPOINT)&rect, 2 );
FillRect( hdc, &rect, brush );
}
return 1;
}
case WM_NCDESTROY:
if (dlgInfo)
{
WND *wndPtr;
if (dlgInfo->hUserFont) DeleteObject( dlgInfo->hUserFont );
if (dlgInfo->hMenu) DestroyMenu( dlgInfo->hMenu );
HeapFree( GetProcessHeap(), 0, dlgInfo );
wndPtr = WIN_GetPtr( hwnd );
wndPtr->dlgInfo = NULL;
WIN_ReleasePtr( wndPtr );
}
/* Window clean-up */
return DefWindowProcA( hwnd, msg, wParam, lParam );
case WM_SHOWWINDOW:
if (!wParam) DEFDLG_SaveFocus( hwnd );
return DefWindowProcA( hwnd, msg, wParam, lParam );
case WM_ACTIVATE:
if (wParam) DEFDLG_RestoreFocus( hwnd );
else DEFDLG_SaveFocus( hwnd );
return 0;
case WM_SETFOCUS:
DEFDLG_RestoreFocus( hwnd );
return 0;
case DM_SETDEFID:
if (dlgInfo && !(dlgInfo->flags & DF_END))
DEFDLG_SetDefId( hwnd, dlgInfo, wParam );
return 1;
case DM_GETDEFID:
if (dlgInfo && !(dlgInfo->flags & DF_END))
{
HWND hwndDefId;
if (dlgInfo->idResult)
return MAKELONG( dlgInfo->idResult, DC_HASDEFID );
if ((hwndDefId = DEFDLG_FindDefButton( hwnd )))
return MAKELONG( GetDlgCtrlID( hwndDefId ), DC_HASDEFID);
}
return 0;
case WM_NEXTDLGCTL:
if (dlgInfo)
{
HWND hwndDest = (HWND)wParam;
if (!lParam)
hwndDest = GetNextDlgTabItem(hwnd, GetFocus(), wParam);
if (hwndDest) DEFDLG_SetFocus( hwnd, hwndDest );
DEFDLG_SetDefButton( hwnd, dlgInfo, hwndDest );
}
return 0;
case WM_ENTERMENULOOP:
case WM_LBUTTONDOWN:
case WM_NCLBUTTONDOWN:
{
HWND hwndFocus = GetFocus();
if (hwndFocus)
{
/* always make combo box hide its listbox control */
if (!SendMessageW( hwndFocus, CB_SHOWDROPDOWN, FALSE, 0 ))
SendMessageW( GetParent(hwndFocus), CB_SHOWDROPDOWN, FALSE, 0 );
}
}
return DefWindowProcA( hwnd, msg, wParam, lParam );
case WM_GETFONT:
return dlgInfo ? (LRESULT)dlgInfo->hUserFont : 0;
case WM_CLOSE:
PostMessageA( hwnd, WM_COMMAND, MAKEWPARAM(IDCANCEL, BN_CLICKED),
(LPARAM)GetDlgItem( hwnd, IDCANCEL ) );
return 0;
}
return 0;
}
/***********************************************************************
* DIALOG_get_info
*
* Get the DIALOGINFO structure of a window, allocating it if needed
* and 'create' is TRUE.
*/
DIALOGINFO *DIALOG_get_info( HWND hwnd, BOOL create )
{
WND* wndPtr;
DIALOGINFO* dlgInfo;
wndPtr = WIN_GetPtr( hwnd );
if (!wndPtr || wndPtr == WND_OTHER_PROCESS || wndPtr == WND_DESKTOP)
{
SetLastError( ERROR_INVALID_WINDOW_HANDLE );
return NULL;
}
dlgInfo = wndPtr->dlgInfo;
if (!dlgInfo && create)
{
if (!(dlgInfo = HeapAlloc( GetProcessHeap(), 0, sizeof(*dlgInfo) )))
goto out;
dlgInfo->hwndFocus = 0;
dlgInfo->hUserFont = 0;
dlgInfo->hMenu = 0;
dlgInfo->xBaseUnit = 0;
dlgInfo->yBaseUnit = 0;
dlgInfo->idResult = IDOK;
dlgInfo->flags = 0;
wndPtr->dlgInfo = dlgInfo;
}
out:
WIN_ReleasePtr( wndPtr );
return dlgInfo;
}
/***********************************************************************
* DefDlgProcA (USER32.@)
*/
LRESULT WINAPI DefDlgProcA( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
DIALOGINFO *dlgInfo;
DLGPROC dlgproc;
LRESULT result = 0;
/* Perform DIALOGINFO initialization if not done */
if(!(dlgInfo = DIALOG_get_info( hwnd, TRUE ))) return 0;
SetWindowLongPtrW( hwnd, DWLP_MSGRESULT, 0 );
if ((dlgproc = DEFDLG_GetDlgProc( hwnd ))) /* Call dialog procedure */
result = WINPROC_CallDlgProcA( dlgproc, hwnd, msg, wParam, lParam );
if (!result && IsWindow(hwnd))
{
/* callback didn't process this message */
switch(msg)
{
case WM_ERASEBKGND:
case WM_SHOWWINDOW:
case WM_ACTIVATE:
case WM_SETFOCUS:
case DM_SETDEFID:
case DM_GETDEFID:
case WM_NEXTDLGCTL:
case WM_GETFONT:
case WM_CLOSE:
case WM_NCDESTROY:
case WM_ENTERMENULOOP:
case WM_LBUTTONDOWN:
case WM_NCLBUTTONDOWN:
return DEFDLG_Proc( hwnd, msg, wParam, lParam, dlgInfo );
case WM_INITDIALOG:
case WM_VKEYTOITEM:
case WM_COMPAREITEM:
case WM_CHARTOITEM:
break;
default:
return DefWindowProcA( hwnd, msg, wParam, lParam );
}
}
if ((msg >= WM_CTLCOLORMSGBOX && msg <= WM_CTLCOLORSTATIC) ||
msg == WM_CTLCOLOR || msg == WM_COMPAREITEM ||
msg == WM_VKEYTOITEM || msg == WM_CHARTOITEM ||
msg == WM_QUERYDRAGICON || msg == WM_INITDIALOG)
return result;
return GetWindowLongPtrW( hwnd, DWLP_MSGRESULT );
}
/***********************************************************************
* DefDlgProcW (USER32.@)
*/
LRESULT WINAPI DefDlgProcW( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
DIALOGINFO *dlgInfo;
DLGPROC dlgproc;
LRESULT result = 0;
/* Perform DIALOGINFO initialization if not done */
if(!(dlgInfo = DIALOG_get_info( hwnd, TRUE ))) return 0;
SetWindowLongPtrW( hwnd, DWLP_MSGRESULT, 0 );
if ((dlgproc = DEFDLG_GetDlgProc( hwnd ))) /* Call dialog procedure */
result = WINPROC_CallDlgProcW( dlgproc, hwnd, msg, wParam, lParam );
if (!result && IsWindow(hwnd))
{
/* callback didn't process this message */
switch(msg)
{
case WM_ERASEBKGND:
case WM_SHOWWINDOW:
case WM_ACTIVATE:
case WM_SETFOCUS:
case DM_SETDEFID:
case DM_GETDEFID:
case WM_NEXTDLGCTL:
case WM_GETFONT:
case WM_CLOSE:
case WM_NCDESTROY:
case WM_ENTERMENULOOP:
case WM_LBUTTONDOWN:
case WM_NCLBUTTONDOWN:
return DEFDLG_Proc( hwnd, msg, wParam, lParam, dlgInfo );
case WM_INITDIALOG:
case WM_VKEYTOITEM:
case WM_COMPAREITEM:
case WM_CHARTOITEM:
break;
default:
return DefWindowProcW( hwnd, msg, wParam, lParam );
}
}
if ((msg >= WM_CTLCOLORMSGBOX && msg <= WM_CTLCOLORSTATIC) ||
msg == WM_CTLCOLOR || msg == WM_COMPAREITEM ||
msg == WM_VKEYTOITEM || msg == WM_CHARTOITEM ||
msg == WM_QUERYDRAGICON || msg == WM_INITDIALOG)
return result;
return GetWindowLongPtrW( hwnd, DWLP_MSGRESULT );
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,243 @@
/*
* Desktop window class.
*
* Copyright 1994 Alexandre Julliard
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "config.h"
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winnls.h"
#include "controls.h"
#include "user_private.h"
static HBRUSH hbrushPattern;
static HBITMAP hbitmapWallPaper;
static SIZE bitmapSize;
static BOOL fTileWallPaper;
/*********************************************************************
* desktop class descriptor
*/
const struct builtin_class_descr DESKTOP_builtin_class =
{
(LPCWSTR)DESKTOP_CLASS_ATOM, /* name */
CS_DBLCLKS, /* style */
WINPROC_DESKTOP, /* proc */
0, /* extra */
IDC_ARROW, /* cursor */
(HBRUSH)(COLOR_BACKGROUND+1) /* brush */
};
/***********************************************************************
* DESKTOP_LoadBitmap
*
* Load a bitmap from a file. Used by SetDeskWallPaper().
*/
static HBITMAP DESKTOP_LoadBitmap( HDC hdc, const char *filename )
{
BITMAPFILEHEADER *fileHeader;
BITMAPINFO *bitmapInfo;
HBITMAP hbitmap;
HFILE file;
LPSTR buffer;
LONG size;
/* Read all the file into memory */
if ((file = _lopen( filename, OF_READ )) == HFILE_ERROR)
{
UINT len = GetWindowsDirectoryA( NULL, 0 );
if (!(buffer = HeapAlloc( GetProcessHeap(), 0,
len + strlen(filename) + 2 )))
return 0;
GetWindowsDirectoryA( buffer, len + 1 );
strcat( buffer, "\\" );
strcat( buffer, filename );
file = _lopen( buffer, OF_READ );
HeapFree( GetProcessHeap(), 0, buffer );
}
if (file == HFILE_ERROR) return 0;
size = _llseek( file, 0, 2 );
if (!(buffer = HeapAlloc( GetProcessHeap(), 0, size )))
{
_lclose( file );
return 0;
}
_llseek( file, 0, 0 );
size = _lread( file, buffer, size );
_lclose( file );
fileHeader = (BITMAPFILEHEADER *)buffer;
bitmapInfo = (BITMAPINFO *)(buffer + sizeof(BITMAPFILEHEADER));
/* Check header content */
if ((fileHeader->bfType != 0x4d42) || (size < fileHeader->bfSize))
{
HeapFree( GetProcessHeap(), 0, buffer );
return 0;
}
hbitmap = CreateDIBitmap( hdc, &bitmapInfo->bmiHeader, CBM_INIT,
buffer + fileHeader->bfOffBits,
bitmapInfo, DIB_RGB_COLORS );
HeapFree( GetProcessHeap(), 0, buffer );
return hbitmap;
}
/***********************************************************************
* DesktopWndProc
*/
LRESULT WINAPI DesktopWndProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam )
{
if (message == WM_NCCREATE) return TRUE;
return 0; /* all other messages are ignored */
}
/***********************************************************************
* PaintDesktop (USER32.@)
*
*/
BOOL WINAPI PaintDesktop(HDC hdc)
{
HWND hwnd = GetDesktopWindow();
/* check for an owning thread; otherwise don't paint anything (non-desktop mode) */
if (GetWindowThreadProcessId( hwnd, NULL ))
{
RECT rect;
GetClientRect( hwnd, &rect );
/* Paint desktop pattern (only if wall paper does not cover everything) */
if (!hbitmapWallPaper ||
(!fTileWallPaper && ((bitmapSize.cx < rect.right) || (bitmapSize.cy < rect.bottom))))
{
HBRUSH brush = hbrushPattern;
if (!brush) brush = (HBRUSH)GetClassLongPtrW( hwnd, GCLP_HBRBACKGROUND );
/* Set colors in case pattern is a monochrome bitmap */
SetBkColor( hdc, RGB(0,0,0) );
SetTextColor( hdc, GetSysColor(COLOR_BACKGROUND) );
FillRect( hdc, &rect, brush );
}
/* Paint wall paper */
if (hbitmapWallPaper)
{
INT x, y;
HDC hMemDC = CreateCompatibleDC( hdc );
SelectObject( hMemDC, hbitmapWallPaper );
if (fTileWallPaper)
{
for (y = 0; y < rect.bottom; y += bitmapSize.cy)
for (x = 0; x < rect.right; x += bitmapSize.cx)
BitBlt( hdc, x, y, bitmapSize.cx, bitmapSize.cy, hMemDC, 0, 0, SRCCOPY );
}
else
{
x = (rect.left + rect.right - bitmapSize.cx) / 2;
y = (rect.top + rect.bottom - bitmapSize.cy) / 2;
if (x < 0) x = 0;
if (y < 0) y = 0;
BitBlt( hdc, x, y, bitmapSize.cx, bitmapSize.cy, hMemDC, 0, 0, SRCCOPY );
}
DeleteDC( hMemDC );
}
}
return TRUE;
}
/***********************************************************************
* SetDeskWallPaper (USER32.@)
*
* FIXME: is there a unicode version?
*/
BOOL WINAPI SetDeskWallPaper( LPCSTR filename )
{
HBITMAP hbitmap;
HDC hdc;
char buffer[256];
if (filename == (LPSTR)-1)
{
GetProfileStringA( "desktop", "WallPaper", "(None)", buffer, 256 );
filename = buffer;
}
hdc = GetDC( 0 );
hbitmap = DESKTOP_LoadBitmap( hdc, filename );
ReleaseDC( 0, hdc );
if (hbitmapWallPaper) DeleteObject( hbitmapWallPaper );
hbitmapWallPaper = hbitmap;
fTileWallPaper = GetProfileIntA( "desktop", "TileWallPaper", 0 );
if (hbitmap)
{
BITMAP bmp;
GetObjectA( hbitmap, sizeof(bmp), &bmp );
bitmapSize.cx = (bmp.bmWidth != 0) ? bmp.bmWidth : 1;
bitmapSize.cy = (bmp.bmHeight != 0) ? bmp.bmHeight : 1;
}
return TRUE;
}
/***********************************************************************
* DESKTOP_SetPattern
*
* Set the desktop pattern.
*/
BOOL DESKTOP_SetPattern( LPCWSTR pattern )
{
int pat[8];
if (hbrushPattern) DeleteObject( hbrushPattern );
hbrushPattern = 0;
memset( pat, 0, sizeof(pat) );
if (pattern)
{
char buffer[64];
WideCharToMultiByte( CP_ACP, 0, pattern, -1, buffer, sizeof(buffer), NULL, NULL );
if (sscanf( buffer, " %d %d %d %d %d %d %d %d",
&pat[0], &pat[1], &pat[2], &pat[3],
&pat[4], &pat[5], &pat[6], &pat[7] ))
{
WORD pattern[8];
HBITMAP hbitmap;
int i;
for (i = 0; i < 8; i++) pattern[i] = pat[i] & 0xffff;
hbitmap = CreateBitmap( 8, 8, 1, 1, pattern );
hbrushPattern = CreatePatternBrush( hbitmap );
DeleteObject( hbitmap );
}
}
return TRUE;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,862 @@
/*
* USER driver support
*
* Copyright 2000, 2005 Alexandre Julliard
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <stdarg.h>
#include <stdio.h>
#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "wine/debug.h"
#include "user_private.h"
static USER_DRIVER null_driver, lazy_load_driver;
const USER_DRIVER *USER_Driver = &lazy_load_driver;
static DWORD driver_load_error;
/* load the graphics driver */
static const USER_DRIVER *load_driver(void)
{
char buffer[MAX_PATH], libname[32], *name, *next;
#if 0
HKEY hkey;
#endif
void *ptr;
HMODULE graphics_driver;
USER_DRIVER *driver, *prev;
#ifndef __REACTOS__
strcpy( buffer, "x11" ); /* default value */
#else
strcpy( buffer, "nt" );
#endif
#if 0
/* @@ Wine registry key: HKCU\Software\Wine\Drivers */
if (!RegOpenKeyA( HKEY_CURRENT_USER, "Software\\Wine\\Drivers", &hkey ))
{
DWORD type, count = sizeof(buffer);
RegQueryValueExA( hkey, "Graphics", 0, &type, (LPBYTE) buffer, &count );
RegCloseKey( hkey );
}
#endif
name = buffer;
while (name)
{
next = strchr( name, ',' );
if (next) *next++ = 0;
_snprintf( libname, sizeof(libname), "wine%s.drv", name );
if ((graphics_driver = LoadLibraryA( libname )) != 0) break;
name = next;
}
if (!graphics_driver)
driver_load_error = GetLastError();
driver = HeapAlloc( GetProcessHeap(), 0, sizeof(*driver) );
*driver = null_driver;
if (graphics_driver)
{
#define GET_USER_FUNC(name) \
do { if ((ptr = GetProcAddress( graphics_driver, #name ))) driver->p##name = ptr; } while(0)
GET_USER_FUNC(ActivateKeyboardLayout);
GET_USER_FUNC(Beep);
GET_USER_FUNC(GetAsyncKeyState);
GET_USER_FUNC(GetKeyNameText);
GET_USER_FUNC(GetKeyboardLayout);
GET_USER_FUNC(GetKeyboardLayoutName);
GET_USER_FUNC(LoadKeyboardLayout);
GET_USER_FUNC(MapVirtualKeyEx);
GET_USER_FUNC(SendInput);
GET_USER_FUNC(ToUnicodeEx);
GET_USER_FUNC(UnloadKeyboardLayout);
GET_USER_FUNC(VkKeyScanEx);
GET_USER_FUNC(CreateCursorIcon);
GET_USER_FUNC(DestroyCursorIcon);
GET_USER_FUNC(SetCursor);
GET_USER_FUNC(GetCursorPos);
GET_USER_FUNC(SetCursorPos);
GET_USER_FUNC(ClipCursor);
GET_USER_FUNC(GetScreenSaveActive);
GET_USER_FUNC(SetScreenSaveActive);
GET_USER_FUNC(AcquireClipboard);
GET_USER_FUNC(EmptyClipboard);
GET_USER_FUNC(SetClipboardData);
GET_USER_FUNC(GetClipboardData);
GET_USER_FUNC(CountClipboardFormats);
GET_USER_FUNC(EnumClipboardFormats);
GET_USER_FUNC(IsClipboardFormatAvailable);
GET_USER_FUNC(RegisterClipboardFormat);
GET_USER_FUNC(GetClipboardFormatName);
GET_USER_FUNC(EndClipboardUpdate);
GET_USER_FUNC(ChangeDisplaySettingsEx);
GET_USER_FUNC(EnumDisplayMonitors);
GET_USER_FUNC(EnumDisplaySettingsEx);
GET_USER_FUNC(GetMonitorInfo);
GET_USER_FUNC(CreateDesktopWindow);
GET_USER_FUNC(CreateWindow);
GET_USER_FUNC(DestroyWindow);
GET_USER_FUNC(GetDC);
GET_USER_FUNC(MsgWaitForMultipleObjectsEx);
GET_USER_FUNC(ReleaseDC);
GET_USER_FUNC(ScrollDC);
GET_USER_FUNC(SetCapture);
GET_USER_FUNC(SetFocus);
GET_USER_FUNC(SetLayeredWindowAttributes);
GET_USER_FUNC(SetParent);
GET_USER_FUNC(SetWindowRgn);
GET_USER_FUNC(SetWindowIcon);
GET_USER_FUNC(SetWindowStyle);
GET_USER_FUNC(SetWindowText);
GET_USER_FUNC(ShowWindow);
GET_USER_FUNC(SysCommand);
GET_USER_FUNC(WindowMessage);
GET_USER_FUNC(WindowPosChanging);
GET_USER_FUNC(WindowPosChanged);
#undef GET_USER_FUNC
}
prev = InterlockedCompareExchangePointer( (void **)&USER_Driver, driver, &lazy_load_driver );
if (prev != &lazy_load_driver)
{
/* another thread beat us to it */
HeapFree( GetProcessHeap(), 0, driver );
FreeLibrary( graphics_driver );
driver = prev;
}
return driver;
}
/* unload the graphics driver on process exit */
void USER_unload_driver(void)
{
USER_DRIVER *prev;
/* make sure we don't try to call the driver after it has been detached */
prev = InterlockedExchangePointer( (void **)&USER_Driver, &null_driver );
if (prev != &lazy_load_driver && prev != &null_driver)
HeapFree( GetProcessHeap(), 0, prev );
}
/**********************************************************************
* Null user driver
*
* These are fallbacks for entry points that are not implemented in the real driver.
*/
static HKL CDECL nulldrv_ActivateKeyboardLayout( HKL layout, UINT flags )
{
return 0;
}
static void CDECL nulldrv_Beep(void)
{
}
static SHORT CDECL nulldrv_GetAsyncKeyState( INT key )
{
return 0;
}
static INT CDECL nulldrv_GetKeyNameText( LONG lparam, LPWSTR buffer, INT size )
{
return 0;
}
static HKL CDECL nulldrv_GetKeyboardLayout( DWORD layout )
{
return 0;
}
static BOOL CDECL nulldrv_GetKeyboardLayoutName( LPWSTR name )
{
return FALSE;
}
static HKL CDECL nulldrv_LoadKeyboardLayout( LPCWSTR name, UINT flags )
{
return 0;
}
static UINT CDECL nulldrv_MapVirtualKeyEx( UINT code, UINT type, HKL layout )
{
return 0;
}
static UINT CDECL nulldrv_SendInput( UINT count, LPINPUT inputs, int size )
{
return 0;
}
static INT CDECL nulldrv_ToUnicodeEx( UINT virt, UINT scan, const BYTE *state, LPWSTR str,
int size, UINT flags, HKL layout )
{
return 0;
}
static BOOL CDECL nulldrv_UnloadKeyboardLayout( HKL layout )
{
return 0;
}
static SHORT CDECL nulldrv_VkKeyScanEx( WCHAR ch, HKL layout )
{
return -1;
}
static void CDECL nulldrv_CreateCursorIcon( HCURSOR cursor )
{
}
static void CDECL nulldrv_DestroyCursorIcon( HCURSOR cursor )
{
}
static void CDECL nulldrv_SetCursor( HCURSOR cursor )
{
}
static BOOL CDECL nulldrv_GetCursorPos( LPPOINT pt )
{
return FALSE;
}
static BOOL CDECL nulldrv_SetCursorPos( INT x, INT y )
{
return FALSE;
}
static BOOL CDECL nulldrv_ClipCursor( LPCRECT clip )
{
return FALSE;
}
static BOOL CDECL nulldrv_GetScreenSaveActive(void)
{
return FALSE;
}
static void CDECL nulldrv_SetScreenSaveActive( BOOL on )
{
}
static INT CDECL nulldrv_AcquireClipboard( HWND hwnd )
{
return 0;
}
static BOOL CDECL nulldrv_CountClipboardFormats(void)
{
return 0;
}
static void CDECL nulldrv_EmptyClipboard( BOOL keepunowned )
{
}
static void CDECL nulldrv_EndClipboardUpdate(void)
{
}
static UINT CDECL nulldrv_EnumClipboardFormats( UINT format )
{
return 0;
}
static HANDLE CDECL nulldrv_GetClipboardData( UINT format )
{
return 0;
}
static INT CDECL nulldrv_GetClipboardFormatName( UINT format, LPWSTR buffer, UINT len )
{
return FALSE;
}
static BOOL CDECL nulldrv_IsClipboardFormatAvailable( UINT format )
{
return FALSE;
}
static UINT CDECL nulldrv_RegisterClipboardFormat( LPCWSTR name )
{
return 0;
}
static BOOL CDECL nulldrv_SetClipboardData( UINT format, HANDLE handle, BOOL owner )
{
return FALSE;
}
static LONG CDECL nulldrv_ChangeDisplaySettingsEx( LPCWSTR name, LPDEVMODEW mode, HWND hwnd,
DWORD flags, LPVOID lparam )
{
return DISP_CHANGE_FAILED;
}
static BOOL CDECL nulldrv_EnumDisplayMonitors( HDC hdc, LPRECT rect, MONITORENUMPROC proc, LPARAM lp )
{
return FALSE;
}
static BOOL CDECL nulldrv_EnumDisplaySettingsEx( LPCWSTR name, DWORD num, LPDEVMODEW mode, DWORD flags )
{
return FALSE;
}
static BOOL CDECL nulldrv_GetMonitorInfo( HMONITOR handle, LPMONITORINFO info )
{
return FALSE;
}
static BOOL CDECL nulldrv_CreateDesktopWindow( HWND hwnd )
{
return TRUE;
}
static BOOL CDECL nulldrv_CreateWindow( HWND hwnd )
{
static int warned;
/* HWND_MESSAGE windows don't need a graphics driver */
if (GetAncestor( hwnd, GA_PARENT ) == get_user_thread_info()->msg_window) return TRUE;
if (warned++) return FALSE;
MESSAGE( "Application tried to create a window, but no driver could be loaded.\n");
switch (driver_load_error)
{
case ERROR_MOD_NOT_FOUND:
MESSAGE( "The X11 driver is missing. Check your build!\n" );
break;
case ERROR_DLL_INIT_FAILED:
MESSAGE( "Make sure that your X server is running and that $DISPLAY is set correctly.\n" );
break;
default:
MESSAGE( "Unknown error (%d).\n", driver_load_error );
}
return FALSE;
}
static void CDECL nulldrv_DestroyWindow( HWND hwnd )
{
}
static void CDECL nulldrv_GetDC( HDC hdc, HWND hwnd, HWND top_win, const RECT *win_rect,
const RECT *top_rect, DWORD flags )
{
}
static DWORD CDECL nulldrv_MsgWaitForMultipleObjectsEx( DWORD count, const HANDLE *handles, DWORD timeout,
DWORD mask, DWORD flags )
{
return WaitForMultipleObjectsEx( count, handles, flags & MWMO_WAITALL,
timeout, flags & MWMO_ALERTABLE );
}
static void CDECL nulldrv_ReleaseDC( HWND hwnd, HDC hdc )
{
}
static BOOL CDECL nulldrv_ScrollDC( HDC hdc, INT dx, INT dy, const RECT *scroll, const RECT *clip,
HRGN hrgn, LPRECT update )
{
return FALSE;
}
static void CDECL nulldrv_SetCapture( HWND hwnd, UINT flags )
{
}
static void CDECL nulldrv_SetFocus( HWND hwnd )
{
}
static void CDECL nulldrv_SetLayeredWindowAttributes( HWND hwnd, COLORREF key, BYTE alpha, DWORD flags )
{
}
static void CDECL nulldrv_SetParent( HWND hwnd, HWND parent, HWND old_parent )
{
}
static int CDECL nulldrv_SetWindowRgn( HWND hwnd, HRGN hrgn, BOOL redraw )
{
return 1;
}
static void CDECL nulldrv_SetWindowIcon( HWND hwnd, UINT type, HICON icon )
{
}
static void CDECL nulldrv_SetWindowStyle( HWND hwnd, INT offset, STYLESTRUCT *style )
{
}
static void CDECL nulldrv_SetWindowText( HWND hwnd, LPCWSTR text )
{
}
static UINT CDECL nulldrv_ShowWindow( HWND hwnd, INT cmd, RECT *rect, UINT swp )
{
return swp;
}
static LRESULT CDECL nulldrv_SysCommand( HWND hwnd, WPARAM wparam, LPARAM lparam )
{
return -1;
}
static LRESULT CDECL nulldrv_WindowMessage( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam )
{
return 0;
}
static void CDECL nulldrv_WindowPosChanging( HWND hwnd, HWND insert_after, UINT swp_flags,
const RECT *window_rect, const RECT *client_rect,
RECT *visible_rect )
{
}
static void CDECL nulldrv_WindowPosChanged( HWND hwnd, HWND insert_after, UINT swp_flags,
const RECT *window_rect, const RECT *client_rect,
const RECT *visible_rect, const RECT *valid_rects )
{
}
static USER_DRIVER null_driver =
{
/* keyboard functions */
nulldrv_ActivateKeyboardLayout,
nulldrv_Beep,
nulldrv_GetAsyncKeyState,
nulldrv_GetKeyNameText,
nulldrv_GetKeyboardLayout,
nulldrv_GetKeyboardLayoutName,
nulldrv_LoadKeyboardLayout,
nulldrv_MapVirtualKeyEx,
nulldrv_SendInput,
nulldrv_ToUnicodeEx,
nulldrv_UnloadKeyboardLayout,
nulldrv_VkKeyScanEx,
/* cursor/icon functions */
nulldrv_CreateCursorIcon,
nulldrv_DestroyCursorIcon,
nulldrv_SetCursor,
nulldrv_GetCursorPos,
nulldrv_SetCursorPos,
nulldrv_ClipCursor,
/* screen saver functions */
nulldrv_GetScreenSaveActive,
nulldrv_SetScreenSaveActive,
/* clipboard functions */
nulldrv_AcquireClipboard,
nulldrv_CountClipboardFormats,
nulldrv_EmptyClipboard,
nulldrv_EndClipboardUpdate,
nulldrv_EnumClipboardFormats,
nulldrv_GetClipboardData,
nulldrv_GetClipboardFormatName,
nulldrv_IsClipboardFormatAvailable,
nulldrv_RegisterClipboardFormat,
nulldrv_SetClipboardData,
/* display modes */
nulldrv_ChangeDisplaySettingsEx,
nulldrv_EnumDisplayMonitors,
nulldrv_EnumDisplaySettingsEx,
nulldrv_GetMonitorInfo,
/* windowing functions */
nulldrv_CreateDesktopWindow,
nulldrv_CreateWindow,
nulldrv_DestroyWindow,
nulldrv_GetDC,
nulldrv_MsgWaitForMultipleObjectsEx,
nulldrv_ReleaseDC,
nulldrv_ScrollDC,
nulldrv_SetCapture,
nulldrv_SetFocus,
nulldrv_SetLayeredWindowAttributes,
nulldrv_SetParent,
nulldrv_SetWindowRgn,
nulldrv_SetWindowIcon,
nulldrv_SetWindowStyle,
nulldrv_SetWindowText,
nulldrv_ShowWindow,
nulldrv_SysCommand,
nulldrv_WindowMessage,
nulldrv_WindowPosChanging,
nulldrv_WindowPosChanged
};
/**********************************************************************
* Lazy loading user driver
*
* Initial driver used before another driver is loaded.
* Each entry point simply loads the real driver and chains to it.
*/
static HKL CDECL loaderdrv_ActivateKeyboardLayout( HKL layout, UINT flags )
{
return load_driver()->pActivateKeyboardLayout( layout, flags );
}
static void CDECL loaderdrv_Beep(void)
{
load_driver()->pBeep();
}
static SHORT CDECL loaderdrv_GetAsyncKeyState( INT key )
{
return load_driver()->pGetAsyncKeyState( key );
}
static INT CDECL loaderdrv_GetKeyNameText( LONG lparam, LPWSTR buffer, INT size )
{
return load_driver()->pGetKeyNameText( lparam, buffer, size );
}
static HKL CDECL loaderdrv_GetKeyboardLayout( DWORD layout )
{
return load_driver()->pGetKeyboardLayout( layout );
}
static BOOL CDECL loaderdrv_GetKeyboardLayoutName( LPWSTR name )
{
return load_driver()->pGetKeyboardLayoutName( name );
}
static HKL CDECL loaderdrv_LoadKeyboardLayout( LPCWSTR name, UINT flags )
{
return load_driver()->pLoadKeyboardLayout( name, flags );
}
static UINT CDECL loaderdrv_MapVirtualKeyEx( UINT code, UINT type, HKL layout )
{
return load_driver()->pMapVirtualKeyEx( code, type, layout );
}
static UINT CDECL loaderdrv_SendInput( UINT count, LPINPUT inputs, int size )
{
return load_driver()->pSendInput( count, inputs, size );
}
static INT CDECL loaderdrv_ToUnicodeEx( UINT virt, UINT scan, const BYTE *state, LPWSTR str,
int size, UINT flags, HKL layout )
{
return load_driver()->pToUnicodeEx( virt, scan, state, str, size, flags, layout );
}
static BOOL CDECL loaderdrv_UnloadKeyboardLayout( HKL layout )
{
return load_driver()->pUnloadKeyboardLayout( layout );
}
static SHORT CDECL loaderdrv_VkKeyScanEx( WCHAR ch, HKL layout )
{
return load_driver()->pVkKeyScanEx( ch, layout );
}
static void CDECL loaderdrv_CreateCursorIcon( HCURSOR cursor )
{
load_driver()->pCreateCursorIcon( cursor );
}
static void CDECL loaderdrv_DestroyCursorIcon( HCURSOR cursor )
{
load_driver()->pDestroyCursorIcon( cursor );
}
static void CDECL loaderdrv_SetCursor( HCURSOR cursor )
{
load_driver()->pSetCursor( cursor );
}
static BOOL CDECL loaderdrv_GetCursorPos( LPPOINT pt )
{
return load_driver()->pGetCursorPos( pt );
}
static BOOL CDECL loaderdrv_SetCursorPos( INT x, INT y )
{
return load_driver()->pSetCursorPos( x, y );
}
static BOOL CDECL loaderdrv_ClipCursor( LPCRECT clip )
{
return load_driver()->pClipCursor( clip );
}
static BOOL CDECL loaderdrv_GetScreenSaveActive(void)
{
return load_driver()->pGetScreenSaveActive();
}
static void CDECL loaderdrv_SetScreenSaveActive( BOOL on )
{
load_driver()->pSetScreenSaveActive( on );
}
static INT CDECL loaderdrv_AcquireClipboard( HWND hwnd )
{
return load_driver()->pAcquireClipboard( hwnd );
}
static BOOL CDECL loaderdrv_CountClipboardFormats(void)
{
return load_driver()->pCountClipboardFormats();
}
static void CDECL loaderdrv_EmptyClipboard( BOOL keepunowned )
{
load_driver()->pEmptyClipboard( keepunowned );
}
static void CDECL loaderdrv_EndClipboardUpdate(void)
{
load_driver()->pEndClipboardUpdate();
}
static UINT CDECL loaderdrv_EnumClipboardFormats( UINT format )
{
return load_driver()->pEnumClipboardFormats( format );
}
static HANDLE CDECL loaderdrv_GetClipboardData( UINT format )
{
return load_driver()->pGetClipboardData( format );
}
static INT CDECL loaderdrv_GetClipboardFormatName( UINT format, LPWSTR buffer, UINT len )
{
return load_driver()->pGetClipboardFormatName( format, buffer, len );
}
static BOOL CDECL loaderdrv_IsClipboardFormatAvailable( UINT format )
{
return load_driver()->pIsClipboardFormatAvailable( format );
}
static UINT CDECL loaderdrv_RegisterClipboardFormat( LPCWSTR name )
{
return load_driver()->pRegisterClipboardFormat( name );
}
static BOOL CDECL loaderdrv_SetClipboardData( UINT format, HANDLE handle, BOOL owner )
{
return load_driver()->pSetClipboardData( format, handle, owner );
}
static LONG CDECL loaderdrv_ChangeDisplaySettingsEx( LPCWSTR name, LPDEVMODEW mode, HWND hwnd,
DWORD flags, LPVOID lparam )
{
return load_driver()->pChangeDisplaySettingsEx( name, mode, hwnd, flags, lparam );
}
static BOOL CDECL loaderdrv_EnumDisplayMonitors( HDC hdc, LPRECT rect, MONITORENUMPROC proc, LPARAM lp )
{
return load_driver()->pEnumDisplayMonitors( hdc, rect, proc, lp );
}
static BOOL CDECL loaderdrv_EnumDisplaySettingsEx( LPCWSTR name, DWORD num, LPDEVMODEW mode, DWORD flags )
{
return load_driver()->pEnumDisplaySettingsEx( name, num, mode, flags );
}
static BOOL CDECL loaderdrv_GetMonitorInfo( HMONITOR handle, LPMONITORINFO info )
{
return load_driver()->pGetMonitorInfo( handle, info );
}
static BOOL CDECL loaderdrv_CreateDesktopWindow( HWND hwnd )
{
return load_driver()->pCreateDesktopWindow( hwnd );
}
static BOOL CDECL loaderdrv_CreateWindow( HWND hwnd )
{
return load_driver()->pCreateWindow( hwnd );
}
static void CDECL loaderdrv_DestroyWindow( HWND hwnd )
{
load_driver()->pDestroyWindow( hwnd );
}
static void CDECL loaderdrv_GetDC( HDC hdc, HWND hwnd, HWND top_win, const RECT *win_rect,
const RECT *top_rect, DWORD flags )
{
load_driver()->pGetDC( hdc, hwnd, top_win, win_rect, top_rect, flags );
}
static DWORD CDECL loaderdrv_MsgWaitForMultipleObjectsEx( DWORD count, const HANDLE *handles, DWORD timeout,
DWORD mask, DWORD flags )
{
return load_driver()->pMsgWaitForMultipleObjectsEx( count, handles, timeout, mask, flags );
}
static void CDECL loaderdrv_ReleaseDC( HWND hwnd, HDC hdc )
{
load_driver()->pReleaseDC( hwnd, hdc );
}
static BOOL CDECL loaderdrv_ScrollDC( HDC hdc, INT dx, INT dy, const RECT *scroll, const RECT *clip,
HRGN hrgn, LPRECT update )
{
return load_driver()->pScrollDC( hdc, dx, dy, scroll, clip, hrgn, update );
}
static void CDECL loaderdrv_SetCapture( HWND hwnd, UINT flags )
{
load_driver()->pSetCapture( hwnd, flags );
}
static void CDECL loaderdrv_SetFocus( HWND hwnd )
{
load_driver()->pSetFocus( hwnd );
}
static void CDECL loaderdrv_SetLayeredWindowAttributes( HWND hwnd, COLORREF key, BYTE alpha, DWORD flags )
{
load_driver()->pSetLayeredWindowAttributes( hwnd, key, alpha, flags );
}
static void CDECL loaderdrv_SetParent( HWND hwnd, HWND parent, HWND old_parent )
{
load_driver()->pSetParent( hwnd, parent, old_parent );
}
static int CDECL loaderdrv_SetWindowRgn( HWND hwnd, HRGN hrgn, BOOL redraw )
{
return load_driver()->pSetWindowRgn( hwnd, hrgn, redraw );
}
static void CDECL loaderdrv_SetWindowIcon( HWND hwnd, UINT type, HICON icon )
{
load_driver()->pSetWindowIcon( hwnd, type, icon );
}
static void CDECL loaderdrv_SetWindowStyle( HWND hwnd, INT offset, STYLESTRUCT *style )
{
load_driver()->pSetWindowStyle( hwnd, offset, style );
}
static void CDECL loaderdrv_SetWindowText( HWND hwnd, LPCWSTR text )
{
load_driver()->pSetWindowText( hwnd, text );
}
static UINT CDECL loaderdrv_ShowWindow( HWND hwnd, INT cmd, RECT *rect, UINT swp )
{
return load_driver()->pShowWindow( hwnd, cmd, rect, swp );
}
static LRESULT CDECL loaderdrv_SysCommand( HWND hwnd, WPARAM wparam, LPARAM lparam )
{
return load_driver()->pSysCommand( hwnd, wparam, lparam );
}
static LRESULT CDECL loaderdrv_WindowMessage( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam )
{
return load_driver()->pWindowMessage( hwnd, msg, wparam, lparam );
}
static void CDECL loaderdrv_WindowPosChanging( HWND hwnd, HWND insert_after, UINT swp_flags,
const RECT *window_rect, const RECT *client_rect,
RECT *visible_rect )
{
load_driver()->pWindowPosChanging( hwnd, insert_after, swp_flags,
window_rect, client_rect, visible_rect );
}
static void CDECL loaderdrv_WindowPosChanged( HWND hwnd, HWND insert_after, UINT swp_flags,
const RECT *window_rect, const RECT *client_rect,
const RECT *visible_rect, const RECT *valid_rects )
{
load_driver()->pWindowPosChanged( hwnd, insert_after, swp_flags, window_rect,
client_rect, visible_rect, valid_rects );
}
static USER_DRIVER lazy_load_driver =
{
/* keyboard functions */
loaderdrv_ActivateKeyboardLayout,
loaderdrv_Beep,
loaderdrv_GetAsyncKeyState,
loaderdrv_GetKeyNameText,
loaderdrv_GetKeyboardLayout,
loaderdrv_GetKeyboardLayoutName,
loaderdrv_LoadKeyboardLayout,
loaderdrv_MapVirtualKeyEx,
loaderdrv_SendInput,
loaderdrv_ToUnicodeEx,
loaderdrv_UnloadKeyboardLayout,
loaderdrv_VkKeyScanEx,
/* cursor/icon functions */
loaderdrv_CreateCursorIcon,
loaderdrv_DestroyCursorIcon,
loaderdrv_SetCursor,
loaderdrv_GetCursorPos,
loaderdrv_SetCursorPos,
loaderdrv_ClipCursor,
/* screen saver functions */
loaderdrv_GetScreenSaveActive,
loaderdrv_SetScreenSaveActive,
/* clipboard functions */
loaderdrv_AcquireClipboard,
loaderdrv_CountClipboardFormats,
loaderdrv_EmptyClipboard,
loaderdrv_EndClipboardUpdate,
loaderdrv_EnumClipboardFormats,
loaderdrv_GetClipboardData,
loaderdrv_GetClipboardFormatName,
loaderdrv_IsClipboardFormatAvailable,
loaderdrv_RegisterClipboardFormat,
loaderdrv_SetClipboardData,
/* display modes */
loaderdrv_ChangeDisplaySettingsEx,
loaderdrv_EnumDisplayMonitors,
loaderdrv_EnumDisplaySettingsEx,
loaderdrv_GetMonitorInfo,
/* windowing functions */
loaderdrv_CreateDesktopWindow,
loaderdrv_CreateWindow,
loaderdrv_DestroyWindow,
loaderdrv_GetDC,
loaderdrv_MsgWaitForMultipleObjectsEx,
loaderdrv_ReleaseDC,
loaderdrv_ScrollDC,
loaderdrv_SetCapture,
loaderdrv_SetFocus,
loaderdrv_SetLayeredWindowAttributes,
loaderdrv_SetParent,
loaderdrv_SetWindowRgn,
loaderdrv_SetWindowIcon,
loaderdrv_SetWindowStyle,
loaderdrv_SetWindowText,
loaderdrv_ShowWindow,
loaderdrv_SysCommand,
loaderdrv_WindowMessage,
loaderdrv_WindowPosChanging,
loaderdrv_WindowPosChanged
};

4980
arwinss/client/user32/edit.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -22,14 +22,71 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <user32.h>
#include "config.h"
#include <wine/debug.h>
#include <stdarg.h>
#include <string.h>
#include <stdlib.h> /* abs() */
#include <sys/types.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
/* Start of Hack section */
//#define NONAMELESSUNION
#define NONAMELESSSTRUCT
#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "winnls.h"
#include "user_private.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(icon);
#include "pshpack1.h"
typedef struct
{
BYTE bWidth; /* Width, in pixels, of the image */
BYTE bHeight; /* Height, in pixels, of the image */
BYTE bColorCount; /* Number of colors in image (0 if >=8bpp) */
BYTE bReserved; /* Reserved ( must be 0) */
WORD wPlanes; /* Color Planes */
WORD wBitCount; /* Bits per pixel */
DWORD dwBytesInRes; /* How many bytes in this resource? */
DWORD dwImageOffset; /* Where in the file is this image? */
} icoICONDIRENTRY, *LPicoICONDIRENTRY;
typedef struct
{
WORD idReserved; /* Reserved (must be 0) */
WORD idType; /* Resource Type (RES_ICON or RES_CURSOR) */
WORD idCount; /* How many images */
icoICONDIRENTRY idEntries[1]; /* An entry for each image (idCount of 'em) */
} icoICONDIR, *LPicoICONDIR;
typedef struct
{
WORD offset;
WORD length;
WORD flags;
WORD id;
WORD handle;
WORD usage;
} NE_NAMEINFO;
typedef struct
{
WORD type_id;
WORD count;
DWORD resloader;
} NE_TYPEINFO;
#define NE_RSCTYPE_ICON 0x8003
#define NE_RSCTYPE_GROUP_ICON 0x800e
#include "poppack.h"
#if 0
static void dumpIcoDirEnty ( LPicoICONDIRENTRY entry )
{
@@ -112,7 +169,7 @@ static DWORD USER32_GetResourceTable(LPBYTE peimage,DWORD pesize,LPBYTE *retptr)
}
if (*((DWORD*)(peimage + mz_header->e_lfanew)) == IMAGE_NT_SIGNATURE )
return IMAGE_NT_SIGNATURE;
#if 0
if (*((WORD*)(peimage + mz_header->e_lfanew)) == IMAGE_OS2_SIGNATURE )
{
IMAGE_OS2_HEADER * ne_header;
@@ -129,10 +186,8 @@ static DWORD USER32_GetResourceTable(LPBYTE peimage,DWORD pesize,LPBYTE *retptr)
return IMAGE_OS2_SIGNATURE;
}
#endif
return 0; /* failed */
}
#if 0
/*************************************************************************
* USER32_LoadResource
*/
@@ -188,7 +243,7 @@ static BYTE * ICO_GetIconDirectory( LPBYTE peimage, LPicoICONDIR* lplpiID, ULONG
/* copy the entries */
for( i=0; i < lpcid->idCount; i++ )
{
memcpy(&lpID->idEntries[i], &lpcid->idEntries[i], sizeof(CURSORICONDIRENTRY) - 2);
memcpy(&lpID->idEntries[i], &lpcid->idEntries[i], sizeof(CURSORICONDIRENTRY) - 2);
lpID->idEntries[i].wResId = i;
}
@@ -197,7 +252,7 @@ static BYTE * ICO_GetIconDirectory( LPBYTE peimage, LPicoICONDIR* lplpiID, ULONG
}
return 0;
}
#endif
/*************************************************************************
* ICO_ExtractIconExW [internal]
*
@@ -224,7 +279,7 @@ static UINT ICO_ExtractIconExW(
LPBYTE pData;
DWORD sig;
HANDLE hFile;
UINT16 iconDirCount = 0; //,iconCount = 0;
UINT16 iconDirCount = 0,iconCount = 0;
LPBYTE peimage;
HANDLE fmapping;
DWORD fsizeh,fsizel;
@@ -249,13 +304,13 @@ static UINT ICO_ExtractIconExW(
CloseHandle(hFile);
if (!fmapping)
{
WARN("CreateFileMapping error %ld\n", GetLastError() );
WARN("CreateFileMapping error %d\n", GetLastError() );
return 0xFFFFFFFF;
}
if (!(peimage = MapViewOfFile(fmapping, FILE_MAP_READ, 0, 0, 0)))
{
WARN("MapViewOfFile error %ld\n", GetLastError() );
WARN("MapViewOfFile error %d\n", GetLastError() );
CloseHandle(fmapping);
return 0xFFFFFFFF;
}
@@ -275,7 +330,6 @@ static UINT ICO_ExtractIconExW(
sig = USER32_GetResourceTable(peimage, fsizel, &pData);
/* ico file or NE exe/dll*/
#if 0
if (sig==IMAGE_OS2_SIGNATURE || sig==1) /* .ICO file */
{
BYTE *pCIDir = 0;
@@ -283,8 +337,9 @@ static UINT ICO_ExtractIconExW(
NE_NAMEINFO *pIconStorage = NULL;
NE_NAMEINFO *pIconDir = NULL;
LPicoICONDIR lpiID = NULL;
ULONG uSize = 0;
TRACE("-- OS2/icon Signature (0x%08lx)\n", sig);
TRACE("-- OS2/icon Signature (0x%08x)\n", sig);
if (pData == (BYTE*)-1)
{
@@ -292,7 +347,7 @@ static UINT ICO_ExtractIconExW(
if (pCIDir)
{
iconDirCount = 1; iconCount = lpiID->idCount;
TRACE("-- icon found %p 0x%08lx 0x%08x 0x%08x\n", pCIDir, uSize, iconDirCount, iconCount);
TRACE("-- icon found %p 0x%08x 0x%08x 0x%08x\n", pCIDir, uSize, iconDirCount, iconCount);
}
}
else while (pTInfo->type_id && !(pIconStorage && pIconDir))
@@ -317,7 +372,7 @@ static UINT ICO_ExtractIconExW(
if (nIcons == 0)
{
ret = iconDirCount;
if (lpiID && pCIDir) /* *.ico file, deallocate heap pointer*/
if (lpiID) /* *.ico file, deallocate heap pointer*/
HeapFree(GetProcessHeap(), 0, pCIDir);
}
else if (nIconIndex < iconDirCount)
@@ -331,9 +386,10 @@ static UINT ICO_ExtractIconExW(
/* .ICO files have only one icon directory */
if (lpiID == NULL) /* not *.ico */
pCIDir = USER32_LoadResource(peimage, pIconDir + i + nIconIndex, *(WORD*)pData, &uSize);
pIconId[i] = LookupIconIdFromDirectoryEx(pCIDir, TRUE, (i & 1) ? cx2 : cx1, (i & 1) ? cy2 : cy1, flags);
pIconId[i] = LookupIconIdFromDirectoryEx(pCIDir, TRUE, cx1, cy1, flags);
if (cx2 && cy2) pIconId[++i] = LookupIconIdFromDirectoryEx(pCIDir, TRUE, cx2, cy2, flags);
}
if (lpiID && pCIDir) /* *.ico file, deallocate heap pointer*/
if (lpiID) /* *.ico file, deallocate heap pointer*/
HeapFree(GetProcessHeap(), 0, pCIDir);
for (icon = 0; icon < nIcons; icon++)
@@ -347,8 +403,13 @@ static UINT ICO_ExtractIconExW(
pCIDir = USER32_LoadResource(peimage, pIconStorage + i, *(WORD*)pData, &uSize);
if (pCIDir)
RetPtr[icon] = (HICON)CreateIconFromResourceEx(pCIDir, uSize, TRUE, 0x00030000,
(icon & 1) ? cx2 : cx1, (icon & 1) ? cy2 : cy1, flags);
{
RetPtr[icon] = CreateIconFromResourceEx(pCIDir, uSize, TRUE, 0x00030000,
cx1, cy1, flags);
if (cx2 && cy2)
RetPtr[++icon] = CreateIconFromResourceEx(pCIDir, uSize, TRUE, 0x00030000,
cx2, cy2, flags);
}
else
RetPtr[icon] = 0;
}
@@ -360,8 +421,6 @@ static UINT ICO_ExtractIconExW(
/* exe/dll */
else if( sig == IMAGE_NT_SIGNATURE )
#endif
if( sig == IMAGE_NT_SIGNATURE )
{
LPBYTE idata,igdata;
PIMAGE_DOS_HEADER dheader;
@@ -384,7 +443,7 @@ static UINT ICO_ExtractIconExW(
if (pe_sections[i].Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA)
continue;
if (fsizel < pe_sections[i].PointerToRawData+pe_sections[i].SizeOfRawData) {
FIXME("File %s too short (section is at %ld bytes, real size is %ld)\n",
FIXME("File %s too short (section is at %d bytes, real size is %d)\n",
debugstr_w(lpszExeFileName),
pe_sections[i].PointerToRawData+pe_sections[i].SizeOfRawData,
fsizel
@@ -465,7 +524,7 @@ static UINT ICO_ExtractIconExW(
const IMAGE_RESOURCE_DIRECTORY *resdir;
/* go down this resource entry, name */
resdir = (const IMAGE_RESOURCE_DIRECTORY*)((const char *)rootresdir+(xresent->OffsetToDirectory));
resdir = (const IMAGE_RESOURCE_DIRECTORY *)((const char *)rootresdir + xresent->OffsetToDirectory);
/* default language (0) */
resdir = find_entry_default(resdir,rootresdir);
@@ -482,7 +541,7 @@ static UINT ICO_ExtractIconExW(
continue;
if (igdataent->OffsetToData-pe_sections[j].VirtualAddress+pe_sections[j].PointerToRawData+igdataent->Size > fsizel) {
FIXME("overflow in PE lookup (%s has len %ld, have offset %ld), short file?\n", debugstr_w(lpszExeFileName), fsizel,
FIXME("overflow in PE lookup (%s has len %d, have offset %d), short file?\n", debugstr_w(lpszExeFileName), fsizel,
igdataent->OffsetToData - pe_sections[j].VirtualAddress + pe_sections[j].PointerToRawData + igdataent->Size);
goto end; /* failure */
}
@@ -495,7 +554,7 @@ static UINT ICO_ExtractIconExW(
goto end; /* failure */
}
pIconId[i] = LookupIconIdFromDirectoryEx(igdata, TRUE, cx1, cy1, flags);
if (cx2 && cy2) pIconId[++i] = LookupIconIdFromDirectoryEx(igdata, TRUE, cx2, cy2, flags);
if (cx2 && cy2) pIconId[++i] = LookupIconIdFromDirectoryEx(igdata, TRUE, cx2, cy2, flags);
}
if (!(iconresdir=find_entry_by_id(rootresdir,LOWORD(RT_ICON),rootresdir)))
@@ -508,19 +567,13 @@ static UINT ICO_ExtractIconExW(
{
const IMAGE_RESOURCE_DIRECTORY *xresdir;
xresdir = find_entry_by_id(iconresdir, LOWORD(pIconId[i]), rootresdir);
if (!xresdir)
{
WARN("icon entry %d not found\n", LOWORD(pIconId[i]));
if( !xresdir )
{
WARN("icon entry %d not found\n", LOWORD(pIconId[i]));
RetPtr[i]=0;
continue;
}
}
xresdir = find_entry_default(xresdir, rootresdir);
if (!xresdir)
{
WARN("icon entry %d not found\n", LOWORD(pIconId[i]));
RetPtr[i]=0;
continue;
}
idataent = (const IMAGE_RESOURCE_DATA_ENTRY*)xresdir;
idata = NULL;
@@ -604,8 +657,6 @@ UINT WINAPI PrivateExtractIconsA (
UINT ret;
INT len = MultiByteToWideChar(CP_ACP, 0, lpstrFile, -1, NULL, 0);
LPWSTR lpwstrFile = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
if (lpwstrFile == NULL)
return 0;
MultiByteToWideChar(CP_ACP, 0, lpstrFile, -1, lpwstrFile, len);
ret = PrivateExtractIconsW(lpwstrFile, nIndex, sizeX, sizeY, phicon, piconid, nIcons, flags);
@@ -644,7 +695,7 @@ UINT WINAPI PrivateExtractIconExW (
cxsmicon = GetSystemMetrics(SM_CXSMICON);
cysmicon = GetSystemMetrics(SM_CYSMICON);
ret = ICO_ExtractIconExW(lpwstrFile, hIcon, nIndex, 2, cxicon | (cxsmicon<<16),
ret = ICO_ExtractIconExW(lpwstrFile, hIcon, nIndex, 2, cxicon | (cxsmicon<<16),
cyicon | (cysmicon<<16), NULL, LR_DEFAULTCOLOR);
*phIconLarge = hIcon[0];
*phIconSmall = hIcon[1];
@@ -683,8 +734,6 @@ UINT WINAPI PrivateExtractIconExA (
UINT ret;
INT len = MultiByteToWideChar(CP_ACP, 0, lpstrFile, -1, NULL, 0);
LPWSTR lpwstrFile = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
if (lpwstrFile == NULL)
return 0;
TRACE("%s %d %p %p %d\n", lpstrFile, nIndex, phIconLarge, phIconSmall, nIcons);

View File

@@ -0,0 +1,502 @@
/*
* Focus and activation functions
*
* Copyright 1993 David Metcalfe
* Copyright 1995 Alex Korobka
* Copyright 1994, 2002 Alexandre Julliard
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "config.h"
#include "wine/port.h"
#include <stdarg.h>
#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "win.h"
#include "user_private.h"
#include "wine/server.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(win);
/*****************************************************************
* set_focus_window
*
* Change the focus window, sending the WM_SETFOCUS and WM_KILLFOCUS messages
*/
static HWND set_focus_window( HWND hwnd )
{
HWND previous = 0;
BOOL ret;
SERVER_START_REQ( set_focus_window )
{
req->handle = wine_server_user_handle( hwnd );
if ((ret = !wine_server_call_err( req )))
previous = wine_server_ptr_handle( reply->previous );
}
SERVER_END_REQ;
if (!ret) return 0;
if (previous == hwnd) return previous;
if (previous)
{
SendMessageW( previous, WM_KILLFOCUS, (WPARAM)hwnd, 0 );
if (hwnd != GetFocus()) return previous; /* changed by the message */
}
if (IsWindow(hwnd))
{
USER_Driver->pSetFocus(hwnd);
SendMessageW( hwnd, WM_SETFOCUS, (WPARAM)previous, 0 );
}
return previous;
}
/*******************************************************************
* set_active_window
*/
static BOOL set_active_window( HWND hwnd, HWND *prev, BOOL mouse, BOOL focus )
{
HWND previous = GetActiveWindow();
BOOL ret;
DWORD old_thread, new_thread;
CBTACTIVATESTRUCT cbt;
if (previous == hwnd)
{
if (prev) *prev = hwnd;
return TRUE;
}
/* call CBT hook chain */
cbt.fMouse = mouse;
cbt.hWndActive = previous;
if (HOOK_CallHooks( WH_CBT, HCBT_ACTIVATE, (WPARAM)hwnd, (LPARAM)&cbt, TRUE )) return FALSE;
if (IsWindow(previous))
{
SendMessageW( previous, WM_NCACTIVATE, FALSE, (LPARAM)hwnd );
SendMessageW( previous, WM_ACTIVATE,
MAKEWPARAM( WA_INACTIVE, IsIconic(previous) ), (LPARAM)hwnd );
}
SERVER_START_REQ( set_active_window )
{
req->handle = wine_server_user_handle( hwnd );
if ((ret = !wine_server_call_err( req )))
previous = wine_server_ptr_handle( reply->previous );
}
SERVER_END_REQ;
if (!ret) return FALSE;
if (prev) *prev = previous;
if (previous == hwnd) return TRUE;
if (hwnd)
{
/* send palette messages */
if (SendMessageW( hwnd, WM_QUERYNEWPALETTE, 0, 0 ))
SendMessageTimeoutW( HWND_BROADCAST, WM_PALETTEISCHANGING, (WPARAM)hwnd, 0,
SMTO_ABORTIFHUNG, 2000, NULL );
if (!IsWindow(hwnd)) return FALSE;
}
old_thread = previous ? GetWindowThreadProcessId( previous, NULL ) : 0;
new_thread = hwnd ? GetWindowThreadProcessId( hwnd, NULL ) : 0;
if (old_thread != new_thread)
{
HWND *list, *phwnd;
if ((list = WIN_ListChildren( GetDesktopWindow() )))
{
if (old_thread)
{
for (phwnd = list; *phwnd; phwnd++)
{
if (GetWindowThreadProcessId( *phwnd, NULL ) == old_thread)
SendMessageW( *phwnd, WM_ACTIVATEAPP, 0, new_thread );
}
}
if (new_thread)
{
for (phwnd = list; *phwnd; phwnd++)
{
if (GetWindowThreadProcessId( *phwnd, NULL ) == new_thread)
SendMessageW( *phwnd, WM_ACTIVATEAPP, 1, old_thread );
}
}
HeapFree( GetProcessHeap(), 0, list );
}
}
if (IsWindow(hwnd))
{
SendMessageW( hwnd, WM_NCACTIVATE, (hwnd == GetForegroundWindow()), (LPARAM)previous );
SendMessageW( hwnd, WM_ACTIVATE,
MAKEWPARAM( mouse ? WA_CLICKACTIVE : WA_ACTIVE, IsIconic(hwnd) ),
(LPARAM)previous );
/* Call WH_SHELL hook */
HOOK_CallHooks( WH_SHELL, HSHELL_WINDOWACTIVATED, (WPARAM)hwnd, 0, TRUE );
}
/* now change focus if necessary */
if (focus)
{
GUITHREADINFO info;
info.cbSize = sizeof(info);
GetGUIThreadInfo( GetCurrentThreadId(), &info );
/* Do not change focus if the window is no more active */
if (hwnd == info.hwndActive)
{
if (!info.hwndFocus || !hwnd || GetAncestor( info.hwndFocus, GA_ROOT ) != hwnd)
set_focus_window( hwnd );
}
}
return TRUE;
}
/*******************************************************************
* set_foreground_window
*/
static BOOL set_foreground_window( HWND hwnd, BOOL mouse )
{
BOOL ret, send_msg_old = FALSE, send_msg_new = FALSE;
HWND previous = 0;
SERVER_START_REQ( set_foreground_window )
{
req->handle = wine_server_user_handle( hwnd );
if ((ret = !wine_server_call_err( req )))
{
previous = wine_server_ptr_handle( reply->previous );
send_msg_old = reply->send_msg_old;
send_msg_new = reply->send_msg_new;
}
}
SERVER_END_REQ;
if (ret && previous != hwnd)
{
if (send_msg_old) /* old window belongs to other thread */
SendNotifyMessageW( previous, WM_WINE_SETACTIVEWINDOW, 0, 0 );
else if (send_msg_new) /* old window belongs to us but new one to other thread */
ret = set_active_window( 0, NULL, mouse, TRUE );
if (send_msg_new) /* new window belongs to other thread */
SendNotifyMessageW( hwnd, WM_WINE_SETACTIVEWINDOW, (WPARAM)hwnd, 0 );
else /* new window belongs to us */
ret = set_active_window( hwnd, NULL, mouse, TRUE );
}
return ret;
}
/*******************************************************************
* FOCUS_MouseActivate
*
* Activate a window as a result of a mouse click
*/
BOOL FOCUS_MouseActivate( HWND hwnd )
{
return set_foreground_window( hwnd, TRUE );
}
/*******************************************************************
* SetActiveWindow (USER32.@)
*/
HWND WINAPI SetActiveWindow( HWND hwnd )
{
HWND prev;
TRACE( "%p\n", hwnd );
if (hwnd)
{
LONG style = GetWindowLongW( hwnd, GWL_STYLE );
if ((style & (WS_POPUP|WS_CHILD)) == WS_CHILD)
return GetActiveWindow(); /* Windows doesn't seem to return an error here */
hwnd = WIN_GetFullHandle( hwnd );
}
if (!set_active_window( hwnd, &prev, FALSE, TRUE )) return 0;
return prev;
}
/*****************************************************************
* SetFocus (USER32.@)
*/
HWND WINAPI SetFocus( HWND hwnd )
{
HWND hwndTop = hwnd;
HWND previous = GetFocus();
TRACE( "%p prev %p\n", hwnd, previous );
if (hwnd)
{
/* Check if we can set the focus to this window */
hwnd = WIN_GetFullHandle( hwnd );
if (hwnd == previous) return previous; /* nothing to do */
for (;;)
{
HWND parent;
LONG style = GetWindowLongW( hwndTop, GWL_STYLE );
if (style & (WS_MINIMIZE | WS_DISABLED)) return 0;
parent = GetAncestor( hwndTop, GA_PARENT );
if (!parent || parent == GetDesktopWindow()) break;
if (parent == get_hwnd_message_parent()) return 0;
hwndTop = parent;
}
/* call hooks */
if (HOOK_CallHooks( WH_CBT, HCBT_SETFOCUS, (WPARAM)hwnd, (LPARAM)previous, TRUE )) return 0;
/* activate hwndTop if needed. */
if (hwndTop != GetActiveWindow())
{
if (!set_active_window( hwndTop, NULL, FALSE, FALSE )) return 0;
if (!IsWindow( hwnd )) return 0; /* Abort if window destroyed */
/* Do not change focus if the window is no longer active */
if (hwndTop != GetActiveWindow()) return 0;
}
}
else /* NULL hwnd passed in */
{
if (!previous) return 0; /* nothing to do */
if (HOOK_CallHooks( WH_CBT, HCBT_SETFOCUS, 0, (LPARAM)previous, TRUE )) return 0;
}
/* change focus and send messages */
return set_focus_window( hwnd );
}
/*******************************************************************
* SetForegroundWindow (USER32.@)
*/
BOOL WINAPI SetForegroundWindow( HWND hwnd )
{
TRACE( "%p\n", hwnd );
hwnd = WIN_GetFullHandle( hwnd );
return set_foreground_window( hwnd, FALSE );
}
/*******************************************************************
* GetActiveWindow (USER32.@)
*/
HWND WINAPI GetActiveWindow(void)
{
HWND ret = 0;
SERVER_START_REQ( get_thread_input )
{
req->tid = GetCurrentThreadId();
if (!wine_server_call_err( req )) ret = wine_server_ptr_handle( reply->active );
}
SERVER_END_REQ;
return ret;
}
/*****************************************************************
* GetFocus (USER32.@)
*/
HWND WINAPI GetFocus(void)
{
HWND ret = 0;
SERVER_START_REQ( get_thread_input )
{
req->tid = GetCurrentThreadId();
if (!wine_server_call_err( req )) ret = wine_server_ptr_handle( reply->focus );
}
SERVER_END_REQ;
return ret;
}
/*******************************************************************
* GetForegroundWindow (USER32.@)
*/
HWND WINAPI GetForegroundWindow(void)
{
HWND ret = 0;
SERVER_START_REQ( get_thread_input )
{
req->tid = 0;
if (!wine_server_call_err( req )) ret = wine_server_ptr_handle( reply->foreground );
}
SERVER_END_REQ;
return ret;
}
/***********************************************************************
* SetShellWindowEx (USER32.@)
* hwndShell = Progman[Program Manager]
* |-> SHELLDLL_DefView
* hwndListView = | |-> SysListView32
* | | |-> tooltips_class32
* | |
* | |-> SysHeader32
* |
* |-> ProxyTarget
*/
BOOL WINAPI SetShellWindowEx(HWND hwndShell, HWND hwndListView)
{
BOOL ret;
if (GetShellWindow())
return FALSE;
if (GetWindowLongW(hwndShell, GWL_EXSTYLE) & WS_EX_TOPMOST)
return FALSE;
if (hwndListView != hwndShell)
if (GetWindowLongW(hwndListView, GWL_EXSTYLE) & WS_EX_TOPMOST)
return FALSE;
if (hwndListView && hwndListView!=hwndShell)
SetWindowPos(hwndListView, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE);
SetWindowPos(hwndShell, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE);
SERVER_START_REQ(set_global_windows)
{
req->flags = SET_GLOBAL_SHELL_WINDOWS;
req->shell_window = wine_server_user_handle( hwndShell );
req->shell_listview = wine_server_user_handle( hwndListView );
ret = !wine_server_call_err(req);
}
SERVER_END_REQ;
return ret;
}
/*******************************************************************
* SetShellWindow (USER32.@)
*/
BOOL WINAPI SetShellWindow(HWND hwndShell)
{
return SetShellWindowEx(hwndShell, hwndShell);
}
/*******************************************************************
* GetShellWindow (USER32.@)
*/
HWND WINAPI GetShellWindow(void)
{
HWND hwndShell = 0;
SERVER_START_REQ(set_global_windows)
{
req->flags = 0;
if (!wine_server_call_err(req))
hwndShell = wine_server_ptr_handle( reply->old_shell_window );
}
SERVER_END_REQ;
return hwndShell;
}
/***********************************************************************
* SetProgmanWindow (USER32.@)
*/
HWND WINAPI SetProgmanWindow ( HWND hwnd )
{
SERVER_START_REQ(set_global_windows)
{
req->flags = SET_GLOBAL_PROGMAN_WINDOW;
req->progman_window = wine_server_user_handle( hwnd );
if (wine_server_call_err( req )) hwnd = 0;
}
SERVER_END_REQ;
return hwnd;
}
/***********************************************************************
* GetProgmanWindow (USER32.@)
*/
HWND WINAPI GetProgmanWindow(void)
{
HWND ret = 0;
SERVER_START_REQ(set_global_windows)
{
req->flags = 0;
if (!wine_server_call_err(req))
ret = wine_server_ptr_handle( reply->old_progman_window );
}
SERVER_END_REQ;
return ret;
}
/***********************************************************************
* SetTaskmanWindow (USER32.@)
* NOTES
* hwnd = MSTaskSwWClass
* |-> SysTabControl32
*/
HWND WINAPI SetTaskmanWindow ( HWND hwnd )
{
SERVER_START_REQ(set_global_windows)
{
req->flags = SET_GLOBAL_TASKMAN_WINDOW;
req->taskman_window = wine_server_user_handle( hwnd );
if (wine_server_call_err( req )) hwnd = 0;
}
SERVER_END_REQ;
return hwnd;
}
/***********************************************************************
* GetTaskmanWindow (USER32.@)
*/
HWND WINAPI GetTaskmanWindow(void)
{
HWND ret = 0;
SERVER_START_REQ(set_global_windows)
{
req->flags = 0;
if (!wine_server_call_err(req))
ret = wine_server_ptr_handle( reply->old_taskman_window );
}
SERVER_END_REQ;
return ret;
}

View File

@@ -0,0 +1,936 @@
/*
* Windows hook functions
*
* Copyright 2002 Alexandre Julliard
* Copyright 2005 Dmitry Timoshkov
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*
* NOTES:
* Status of the various hooks:
* WH_MSGFILTER OK
* WH_JOURNALRECORD Partially implemented
* WH_JOURNALPLAYBACK Partially implemented
* WH_KEYBOARD OK
* WH_GETMESSAGE OK (FIXME: A/W mapping?)
* WH_CALLWNDPROC OK (FIXME: A/W mapping?)
* WH_CBT
* HCBT_MOVESIZE OK
* HCBT_MINMAX OK
* HCBT_QS OK
* HCBT_CREATEWND OK
* HCBT_DESTROYWND OK
* HCBT_ACTIVATE OK
* HCBT_CLICKSKIPPED OK
* HCBT_KEYSKIPPED OK
* HCBT_SYSCOMMAND OK
* HCBT_SETFOCUS OK
* WH_SYSMSGFILTER OK
* WH_MOUSE OK
* WH_HARDWARE Not supported in Win32
* WH_DEBUG Not implemented
* WH_SHELL
* HSHELL_WINDOWCREATED OK
* HSHELL_WINDOWDESTROYED OK
* HSHELL_ACTIVATESHELLWINDOW Not implemented
* HSHELL_WINDOWACTIVATED Not implemented
* HSHELL_GETMINRECT Not implemented
* HSHELL_REDRAW Not implemented
* HSHELL_TASKMAN Not implemented
* HSHELL_LANGUAGE Not implemented
* HSHELL_SYSMENU Not implemented
* HSHELL_ENDTASK Not implemented
* HSHELL_ACCESSIBILITYSTATE Not implemented
* HSHELL_APPCOMMAND Not implemented
* HSHELL_WINDOWREPLACED Not implemented
* HSHELL_WINDOWREPLACING Not implemented
* WH_FOREGROUNDIDLE Not implemented
* WH_CALLWNDPROCRET OK (FIXME: A/W mapping?)
* WH_KEYBOARD_LL Implemented but should use SendMessage instead
* WH_MOUSE_LL Implemented but should use SendMessage instead
*/
#include "config.h"
#include "wine/port.h"
#include <stdarg.h>
#include <assert.h>
#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "winerror.h"
#include "win.h"
#include "user_private.h"
#include "wine/rosuser.h"
#include "wine/server.h"
#include "wine/unicode.h"
#include "wine/debug.h"
#include "wine/winternl.h"
WINE_DEFAULT_DEBUG_CHANNEL(hook);
WINE_DECLARE_DEBUG_CHANNEL(relay);
struct hook_info
{
INT id;
void *proc;
void *handle;
DWORD pid, tid;
BOOL prev_unicode, next_unicode;
WCHAR module[MAX_PATH];
};
#define WH_WINEVENT (WH_MAXHOOK+1)
static const char * const hook_names[WH_WINEVENT - WH_MINHOOK + 1] =
{
"WH_MSGFILTER",
"WH_JOURNALRECORD",
"WH_JOURNALPLAYBACK",
"WH_KEYBOARD",
"WH_GETMESSAGE",
"WH_CALLWNDPROC",
"WH_CBT",
"WH_SYSMSGFILTER",
"WH_MOUSE",
"WH_HARDWARE",
"WH_DEBUG",
"WH_SHELL",
"WH_FOREGROUNDIDLE",
"WH_CALLWNDPROCRET",
"WH_KEYBOARD_LL",
"WH_MOUSE_LL",
"WH_WINEVENT"
};
/***********************************************************************
* get_ll_hook_timeout
*
*/
static UINT get_ll_hook_timeout(void)
{
/* FIXME: should retrieve LowLevelHooksTimeout in HKEY_CURRENT_USER\Control Panel\Desktop */
return 2000;
}
/***********************************************************************
* set_windows_hook
*
* Implementation of SetWindowsHookExA and SetWindowsHookExW.
*/
static HHOOK set_windows_hook( INT id, HOOKPROC proc, HINSTANCE inst, DWORD tid, BOOL unicode )
{
HHOOK handle = 0;
WCHAR module[MAX_PATH];
DWORD len;
if (!proc)
{
SetLastError( ERROR_INVALID_FILTER_PROC );
return 0;
}
if (tid) /* thread-local hook */
{
if (id == WH_JOURNALRECORD ||
id == WH_JOURNALPLAYBACK ||
id == WH_KEYBOARD_LL ||
id == WH_MOUSE_LL ||
id == WH_SYSMSGFILTER)
{
/* these can only be global */
SetLastError( ERROR_INVALID_PARAMETER );
return 0;
}
}
else /* system-global hook */
{
if (id == WH_KEYBOARD_LL || id == WH_MOUSE_LL) inst = 0;
else if (!inst)
{
SetLastError( ERROR_HOOK_NEEDS_HMOD );
return 0;
}
}
if (inst && (!(len = GetModuleFileNameW( inst, module, MAX_PATH )) || len >= MAX_PATH))
{
SetLastError( ERROR_INVALID_PARAMETER );
return 0;
}
SERVER_START_REQ( set_hook )
{
req->id = id;
req->pid = 0;
req->tid = tid;
req->event_min = EVENT_MIN;
req->event_max = EVENT_MAX;
req->flags = WINEVENT_INCONTEXT;
req->unicode = unicode;
if (inst) /* make proc relative to the module base */
{
req->proc = wine_server_client_ptr( (void *)((char *)proc - (char *)inst) );
wine_server_add_data( req, module, strlenW(module) * sizeof(WCHAR) );
}
else req->proc = wine_server_client_ptr( proc );
if (!wine_server_call_err( req ))
{
handle = wine_server_ptr_handle( reply->handle );
get_user_thread_info()->active_hooks = reply->active_hooks;
}
}
SERVER_END_REQ;
TRACE( "%s %p %x -> %p\n", hook_names[id-WH_MINHOOK], proc, tid, handle );
return handle;
}
/***********************************************************************
* call_hook_AtoW
*/
static LRESULT call_hook_AtoW( HOOKPROC proc, INT id, INT code, WPARAM wparam, LPARAM lparam )
{
LRESULT ret;
UNICODE_STRING usBuffer;
if (id != WH_CBT || code != HCBT_CREATEWND) ret = proc( code, wparam, lparam );
else
{
CBT_CREATEWNDA *cbtcwA = (CBT_CREATEWNDA *)lparam;
CBT_CREATEWNDW cbtcwW;
CREATESTRUCTW csW;
LPWSTR nameW = NULL;
LPWSTR classW = NULL;
cbtcwW.lpcs = &csW;
cbtcwW.hwndInsertAfter = cbtcwA->hwndInsertAfter;
csW = *(CREATESTRUCTW *)cbtcwA->lpcs;
if (!IS_INTRESOURCE(cbtcwA->lpcs->lpszName))
{
RtlCreateUnicodeStringFromAsciiz(&usBuffer,cbtcwA->lpcs->lpszName);
csW.lpszName = nameW = usBuffer.Buffer;
}
if (!IS_INTRESOURCE(cbtcwA->lpcs->lpszClass))
{
RtlCreateUnicodeStringFromAsciiz(&usBuffer,cbtcwA->lpcs->lpszClass);
csW.lpszClass = classW = usBuffer.Buffer;
}
ret = proc( code, wparam, (LPARAM)&cbtcwW );
cbtcwA->hwndInsertAfter = cbtcwW.hwndInsertAfter;
HeapFree( GetProcessHeap(), 0, nameW );
HeapFree( GetProcessHeap(), 0, classW );
}
return ret;
}
/***********************************************************************
* call_hook_WtoA
*/
static LRESULT call_hook_WtoA( HOOKPROC proc, INT id, INT code, WPARAM wparam, LPARAM lparam )
{
LRESULT ret;
if (id != WH_CBT || code != HCBT_CREATEWND) ret = proc( code, wparam, lparam );
else
{
CBT_CREATEWNDW *cbtcwW = (CBT_CREATEWNDW *)lparam;
CBT_CREATEWNDA cbtcwA;
CREATESTRUCTA csA;
int len;
LPSTR nameA = NULL;
LPSTR classA = NULL;
cbtcwA.lpcs = &csA;
cbtcwA.hwndInsertAfter = cbtcwW->hwndInsertAfter;
csA = *(CREATESTRUCTA *)cbtcwW->lpcs;
if (!IS_INTRESOURCE(cbtcwW->lpcs->lpszName)) {
len = WideCharToMultiByte( CP_ACP, 0, cbtcwW->lpcs->lpszName, -1, NULL, 0, NULL, NULL );
nameA = HeapAlloc( GetProcessHeap(), 0, len*sizeof(CHAR) );
WideCharToMultiByte( CP_ACP, 0, cbtcwW->lpcs->lpszName, -1, nameA, len, NULL, NULL );
csA.lpszName = nameA;
}
if (!IS_INTRESOURCE(cbtcwW->lpcs->lpszClass)) {
len = WideCharToMultiByte( CP_ACP, 0, cbtcwW->lpcs->lpszClass, -1, NULL, 0, NULL, NULL );
classA = HeapAlloc( GetProcessHeap(), 0, len*sizeof(CHAR) );
WideCharToMultiByte( CP_ACP, 0, cbtcwW->lpcs->lpszClass, -1, classA, len, NULL, NULL );
csA.lpszClass = classA;
}
ret = proc( code, wparam, (LPARAM)&cbtcwA );
cbtcwW->hwndInsertAfter = cbtcwA.hwndInsertAfter;
HeapFree( GetProcessHeap(), 0, nameA );
HeapFree( GetProcessHeap(), 0, classA );
}
return ret;
}
/***********************************************************************
* call_hook_proc
*/
static LRESULT call_hook_proc( HOOKPROC proc, INT id, INT code, WPARAM wparam, LPARAM lparam,
BOOL prev_unicode, BOOL next_unicode )
{
LRESULT ret;
if (TRACE_ON(relay))
DPRINTF( "%04x:Call hook proc %p (id=%s,code=%x,wp=%08lx,lp=%08lx)\n",
GetCurrentThreadId(), proc, hook_names[id-WH_MINHOOK], code, wparam, lparam );
if (!prev_unicode == !next_unicode) ret = proc( code, wparam, lparam );
else if (prev_unicode) ret = call_hook_WtoA( proc, id, code, wparam, lparam );
else ret = call_hook_AtoW( proc, id, code, wparam, lparam );
if (TRACE_ON(relay))
DPRINTF( "%04x:Ret hook proc %p (id=%s,code=%x,wp=%08lx,lp=%08lx) retval=%08lx\n",
GetCurrentThreadId(), proc, hook_names[id-WH_MINHOOK], code, wparam, lparam, ret );
return ret;
}
/***********************************************************************
* get_hook_proc
*
* Retrieve the hook procedure real value for a module-relative proc
*/
void *get_hook_proc( void *proc, const WCHAR *module )
{
HMODULE mod;
if (!(mod = GetModuleHandleW(module)))
{
TRACE( "loading %s\n", debugstr_w(module) );
/* FIXME: the library will never be freed */
if (!(mod = LoadLibraryExW(module, NULL, LOAD_WITH_ALTERED_SEARCH_PATH))) return NULL;
}
return (char *)mod + (ULONG_PTR)proc;
}
/***********************************************************************
* call_hook
*
* Call hook either in current thread or send message to the destination
* thread.
*/
static LRESULT call_hook( struct hook_info *info, INT code, WPARAM wparam, LPARAM lparam )
{
DWORD_PTR ret = 0;
if (info->tid)
{
struct hook_extra_info h_extra;
h_extra.handle = info->handle;
h_extra.lparam = lparam;
TRACE( "calling hook in thread %04x %s code %x wp %lx lp %lx\n",
info->tid, hook_names[info->id-WH_MINHOOK], code, wparam, lparam );
switch(info->id)
{
case WH_KEYBOARD_LL:
MSG_SendInternalMessageTimeout( info->pid, info->tid, WM_WINE_KEYBOARD_LL_HOOK,
wparam, (LPARAM)&h_extra, SMTO_ABORTIFHUNG,
get_ll_hook_timeout(), &ret );
break;
case WH_MOUSE_LL:
MSG_SendInternalMessageTimeout( info->pid, info->tid, WM_WINE_MOUSE_LL_HOOK,
wparam, (LPARAM)&h_extra, SMTO_ABORTIFHUNG,
get_ll_hook_timeout(), &ret );
break;
default:
ERR("Unknown hook id %d\n", info->id);
assert(0);
break;
}
}
else if (info->proc)
{
TRACE( "calling hook %p %s code %x wp %lx lp %lx module %s\n",
info->proc, hook_names[info->id-WH_MINHOOK], code, wparam,
lparam, debugstr_w(info->module) );
if (!info->module[0] ||
(info->proc = get_hook_proc( info->proc, info->module )) != NULL)
{
struct user_thread_info *thread_info = get_user_thread_info();
HHOOK prev = thread_info->hook;
BOOL prev_unicode = thread_info->hook_unicode;
thread_info->hook = info->handle;
thread_info->hook_unicode = info->next_unicode;
ret = call_hook_proc( info->proc, info->id, code, wparam, lparam,
info->prev_unicode, info->next_unicode );
thread_info->hook = prev;
thread_info->hook_unicode = prev_unicode;
}
}
return ret;
}
/***********************************************************************
* HOOK_IsHooked
*/
static BOOL HOOK_IsHooked( INT id )
{
struct user_thread_info *thread_info = get_user_thread_info();
if (!thread_info->active_hooks) return TRUE;
return (thread_info->active_hooks & (1 << (id - WH_MINHOOK))) != 0;
}
/***********************************************************************
* HOOK_CallHooks
*/
LRESULT HOOK_CallHooks( INT id, INT code, WPARAM wparam, LPARAM lparam, BOOL unicode )
{
struct user_thread_info *thread_info = get_user_thread_info();
struct hook_info info;
DWORD_PTR ret = 0;
USER_CheckNotLock();
if (id == WH_SHELL)
{
HWND hook_windows[4]; // FIXME: Not a good way, but dynamic allocation all the time is stupid too
UINT cbListSize = sizeof(hook_windows);
if (!RosUserBuildShellHookHwndList(hook_windows, &cbListSize))
{
if (cbListSize > sizeof(hook_windows)) ERR("Not enough hook windows array size!\n");
/* otherwise the list is just empty */
}
else
{
INT wm_shellhook = RegisterWindowMessageW(L"SHELLHOOK");
INT wnd_num;
for (wnd_num = 0; wnd_num < cbListSize / sizeof(HWND); wnd_num++)
PostMessage(hook_windows[wnd_num], wm_shellhook, code, wparam);
}
}
if (!HOOK_IsHooked( id ))
{
TRACE( "skipping hook %s mask %x\n", hook_names[id-WH_MINHOOK], thread_info->active_hooks );
return 0;
}
ZeroMemory( &info, sizeof(info) - sizeof(info.module) );
info.prev_unicode = unicode;
info.id = id;
SERVER_START_REQ( start_hook_chain )
{
req->id = info.id;
req->event = EVENT_MIN;
wine_server_set_reply( req, info.module, sizeof(info.module)-sizeof(WCHAR) );
if (!wine_server_call( req ))
{
info.module[wine_server_reply_size(req) / sizeof(WCHAR)] = 0;
info.handle = wine_server_ptr_handle( reply->handle );
info.pid = reply->pid;
info.tid = reply->tid;
info.proc = wine_server_get_ptr( reply->proc );
info.next_unicode = reply->unicode;
thread_info->active_hooks = reply->active_hooks;
}
}
SERVER_END_REQ;
if (!info.tid && !info.proc) return 0;
ret = call_hook( &info, code, wparam, lparam );
SERVER_START_REQ( finish_hook_chain )
{
req->id = id;
wine_server_call( req );
}
SERVER_END_REQ;
return ret;
}
/***********************************************************************
* SetWindowsHookA (USER32.@)
*/
HHOOK WINAPI SetWindowsHookA( INT id, HOOKPROC proc )
{
return SetWindowsHookExA( id, proc, 0, GetCurrentThreadId() );
}
/***********************************************************************
* SetWindowsHookW (USER32.@)
*/
HHOOK WINAPI SetWindowsHookW( INT id, HOOKPROC proc )
{
return SetWindowsHookExW( id, proc, 0, GetCurrentThreadId() );
}
/***********************************************************************
* SetWindowsHookExA (USER32.@)
*/
HHOOK WINAPI SetWindowsHookExA( INT id, HOOKPROC proc, HINSTANCE inst, DWORD tid )
{
return set_windows_hook( id, proc, inst, tid, FALSE );
}
/***********************************************************************
* SetWindowsHookExW (USER32.@)
*/
HHOOK WINAPI SetWindowsHookExW( INT id, HOOKPROC proc, HINSTANCE inst, DWORD tid )
{
return set_windows_hook( id, proc, inst, tid, TRUE );
}
/***********************************************************************
* UnhookWindowsHook (USER32.@)
*/
BOOL WINAPI UnhookWindowsHook( INT id, HOOKPROC proc )
{
BOOL ret;
TRACE( "%s %p\n", hook_names[id-WH_MINHOOK], proc );
SERVER_START_REQ( remove_hook )
{
req->handle = 0;
req->id = id;
req->proc = wine_server_client_ptr( proc );
ret = !wine_server_call_err( req );
if (ret) get_user_thread_info()->active_hooks = reply->active_hooks;
}
SERVER_END_REQ;
if (!ret && GetLastError() == ERROR_INVALID_HANDLE) SetLastError( ERROR_INVALID_HOOK_HANDLE );
return ret;
}
/***********************************************************************
* UnhookWindowsHookEx (USER32.@)
*/
BOOL WINAPI UnhookWindowsHookEx( HHOOK hhook )
{
BOOL ret;
SERVER_START_REQ( remove_hook )
{
req->handle = wine_server_user_handle( hhook );
req->id = 0;
ret = !wine_server_call_err( req );
if (ret) get_user_thread_info()->active_hooks = reply->active_hooks;
}
SERVER_END_REQ;
if (!ret && GetLastError() == ERROR_INVALID_HANDLE) SetLastError( ERROR_INVALID_HOOK_HANDLE );
return ret;
}
/***********************************************************************
* CallNextHookEx (USER32.@)
*/
LRESULT WINAPI CallNextHookEx( HHOOK hhook, INT code, WPARAM wparam, LPARAM lparam )
{
struct user_thread_info *thread_info = get_user_thread_info();
struct hook_info info;
ZeroMemory( &info, sizeof(info) - sizeof(info.module) );
SERVER_START_REQ( get_hook_info )
{
req->handle = wine_server_user_handle( thread_info->hook );
req->get_next = 1;
req->event = EVENT_MIN;
wine_server_set_reply( req, info.module, sizeof(info.module)-sizeof(WCHAR) );
if (!wine_server_call_err( req ))
{
info.module[wine_server_reply_size(req) / sizeof(WCHAR)] = 0;
info.handle = wine_server_ptr_handle( reply->handle );
info.id = reply->id;
info.pid = reply->pid;
info.tid = reply->tid;
info.proc = wine_server_get_ptr( reply->proc );
info.next_unicode = reply->unicode;
}
}
SERVER_END_REQ;
info.prev_unicode = thread_info->hook_unicode;
return call_hook( &info, code, wparam, lparam );
}
LRESULT call_current_hook( HHOOK hhook, INT code, WPARAM wparam, LPARAM lparam )
{
struct hook_info info;
ZeroMemory( &info, sizeof(info) - sizeof(info.module) );
SERVER_START_REQ( get_hook_info )
{
req->handle = wine_server_user_handle( hhook );
req->get_next = 0;
req->event = EVENT_MIN;
wine_server_set_reply( req, info.module, sizeof(info.module)-sizeof(WCHAR) );
if (!wine_server_call_err( req ))
{
info.module[wine_server_reply_size(req) / sizeof(WCHAR)] = 0;
info.handle = wine_server_ptr_handle( reply->handle );
info.id = reply->id;
info.pid = reply->pid;
info.tid = reply->tid;
info.proc = wine_server_get_ptr( reply->proc );
info.next_unicode = reply->unicode;
}
}
SERVER_END_REQ;
info.prev_unicode = TRUE; /* assume Unicode for this function */
return call_hook( &info, code, wparam, lparam );
}
/***********************************************************************
* CallMsgFilterA (USER32.@)
*/
BOOL WINAPI CallMsgFilterA( LPMSG msg, INT code )
{
if (HOOK_CallHooks( WH_SYSMSGFILTER, code, 0, (LPARAM)msg, FALSE )) return TRUE;
return HOOK_CallHooks( WH_MSGFILTER, code, 0, (LPARAM)msg, FALSE );
}
/***********************************************************************
* CallMsgFilterW (USER32.@)
*/
BOOL WINAPI CallMsgFilterW( LPMSG msg, INT code )
{
if (HOOK_CallHooks( WH_SYSMSGFILTER, code, 0, (LPARAM)msg, TRUE )) return TRUE;
return HOOK_CallHooks( WH_MSGFILTER, code, 0, (LPARAM)msg, TRUE );
}
/***********************************************************************
* SetWinEventHook [USER32.@]
*
* Set up an event hook for a set of events.
*
* PARAMS
* event_min [I] Lowest event handled by pfnProc
* event_max [I] Highest event handled by pfnProc
* inst [I] DLL containing pfnProc
* proc [I] Callback event hook function
* pid [I] Process to get events from, or 0 for all processes
* tid [I] Thread to get events from, or 0 for all threads
* flags [I] Flags indicating the status of pfnProc
*
* RETURNS
* Success: A handle representing the hook.
* Failure: A NULL handle.
*/
HWINEVENTHOOK WINAPI SetWinEventHook(DWORD event_min, DWORD event_max,
HMODULE inst, WINEVENTPROC proc,
DWORD pid, DWORD tid, DWORD flags)
{
HWINEVENTHOOK handle = 0;
WCHAR module[MAX_PATH];
DWORD len;
TRACE("%d,%d,%p,%p,%08x,%04x,%08x\n", event_min, event_max, inst,
proc, pid, tid, flags);
if (inst)
{
if (!(len = GetModuleFileNameW(inst, module, MAX_PATH)) || len >= MAX_PATH)
inst = 0;
}
if ((flags & WINEVENT_INCONTEXT) && !inst)
{
SetLastError(ERROR_HOOK_NEEDS_HMOD);
return 0;
}
if (event_min > event_max)
{
SetLastError(ERROR_INVALID_HOOK_FILTER);
return 0;
}
/* FIXME: what if the tid or pid belongs to another process? */
if (tid) /* thread-local hook */
inst = 0;
SERVER_START_REQ( set_hook )
{
req->id = WH_WINEVENT;
req->pid = pid;
req->tid = tid;
req->event_min = event_min;
req->event_max = event_max;
req->flags = flags;
req->unicode = 1;
if (inst) /* make proc relative to the module base */
{
req->proc = wine_server_client_ptr( (void *)((char *)proc - (char *)inst) );
wine_server_add_data( req, module, strlenW(module) * sizeof(WCHAR) );
}
else req->proc = wine_server_client_ptr( proc );
if (!wine_server_call_err( req ))
{
handle = wine_server_ptr_handle( reply->handle );
get_user_thread_info()->active_hooks = reply->active_hooks;
}
}
SERVER_END_REQ;
TRACE("-> %p\n", handle);
return handle;
}
/***********************************************************************
* UnhookWinEvent [USER32.@]
*
* Remove an event hook for a set of events.
*
* PARAMS
* hEventHook [I] Event hook to remove
*
* RETURNS
* Success: TRUE. The event hook has been removed.
* Failure: FALSE, if hEventHook is invalid.
*/
BOOL WINAPI UnhookWinEvent(HWINEVENTHOOK hEventHook)
{
BOOL ret;
SERVER_START_REQ( remove_hook )
{
req->handle = wine_server_user_handle( hEventHook );
req->id = WH_WINEVENT;
ret = !wine_server_call_err( req );
if (ret) get_user_thread_info()->active_hooks = reply->active_hooks;
}
SERVER_END_REQ;
return ret;
}
static inline BOOL find_first_hook(DWORD id, DWORD event, HWND hwnd, LONG object_id,
LONG child_id, struct hook_info *info)
{
struct user_thread_info *thread_info = get_user_thread_info();
BOOL ret;
if (!HOOK_IsHooked( id ))
{
TRACE( "skipping hook %s mask %x\n", hook_names[id-WH_MINHOOK], thread_info->active_hooks );
return FALSE;
}
SERVER_START_REQ( start_hook_chain )
{
req->id = id;
req->event = event;
req->window = wine_server_user_handle( hwnd );
req->object_id = object_id;
req->child_id = child_id;
wine_server_set_reply( req, info->module, sizeof(info->module)-sizeof(WCHAR) );
ret = !wine_server_call( req );
if (ret)
{
info->module[wine_server_reply_size(req) / sizeof(WCHAR)] = 0;
info->handle = wine_server_ptr_handle( reply->handle );
info->proc = wine_server_get_ptr( reply->proc );
info->tid = reply->tid;
thread_info->active_hooks = reply->active_hooks;
}
}
SERVER_END_REQ;
return ret && (info->tid || info->proc);
}
static inline BOOL find_next_hook(DWORD event, HWND hwnd, LONG object_id,
LONG child_id, struct hook_info *info)
{
BOOL ret;
SERVER_START_REQ( get_hook_info )
{
req->handle = wine_server_user_handle( info->handle );
req->get_next = 1;
req->event = event;
req->window = wine_server_user_handle( hwnd );
req->object_id = object_id;
req->child_id = child_id;
wine_server_set_reply( req, info->module, sizeof(info->module)-sizeof(WCHAR) );
ret = !wine_server_call( req );
if (ret)
{
info->module[wine_server_reply_size(req) / sizeof(WCHAR)] = 0;
info->handle = wine_server_ptr_handle( reply->handle );
info->proc = wine_server_get_ptr( reply->proc );
info->tid = reply->tid;
}
}
SERVER_END_REQ;
return ret;
}
static inline void find_hook_close(DWORD id)
{
SERVER_START_REQ( finish_hook_chain )
{
req->id = id;
wine_server_call( req );
}
SERVER_END_REQ;
}
/***********************************************************************
* NotifyWinEvent [USER32.@]
*
* Inform the OS that an event has occurred.
*
* PARAMS
* event [I] Id of the event
* hwnd [I] Window holding the object that created the event
* object_id [I] Type of object that created the event
* child_id [I] Child object of nId, or CHILDID_SELF.
*
* RETURNS
* Nothing.
*/
void WINAPI NotifyWinEvent(DWORD event, HWND hwnd, LONG object_id, LONG child_id)
{
struct hook_info info;
TRACE("%04x,%p,%d,%d\n", event, hwnd, object_id, child_id);
if (!hwnd)
{
SetLastError(ERROR_INVALID_WINDOW_HANDLE);
return;
}
USER_CheckNotLock();
#if 0
if (event & 0x80000000)
{
/* FIXME: on 64-bit platforms we need to invent some other way for
* passing parameters, nId and nChildId can't hold full [W|L]PARAM.
* struct call_hook *hook = (LRESULT *)hWnd;
* wparam = hook->wparam;
* lparam = hook->lparam;
*/
LRESULT *ret = (LRESULT *)hwnd;
INT id, code, unicode;
id = (dwEvent & 0x7fff0000) >> 16;
code = event & 0x7fff;
unicode = event & 0x8000;
*ret = HOOK_CallHooks(id, code, object_id, child_id, unicode);
return;
}
#endif
if (!find_first_hook(WH_WINEVENT, event, hwnd, object_id, child_id, &info)) return;
do
{
WINEVENTPROC proc = info.proc;
if (proc)
{
TRACE( "calling WH_WINEVENT hook %p event %x hwnd %p %x %x module %s\n",
proc, event, hwnd, object_id, child_id, debugstr_w(info.module) );
if (!info.module[0] || (proc = get_hook_proc( proc, info.module )) != NULL)
{
if (TRACE_ON(relay))
DPRINTF( "%04x:Call winevent hook proc %p (hhook=%p,event=%x,hwnd=%p,object_id=%x,child_id=%x,tid=%04x,time=%x)\n",
GetCurrentThreadId(), proc, info.handle, event, hwnd, object_id,
child_id, GetCurrentThreadId(), GetCurrentTime());
proc( info.handle, event, hwnd, object_id, child_id,
GetCurrentThreadId(), GetCurrentTime());
if (TRACE_ON(relay))
DPRINTF( "%04x:Ret winevent hook proc %p (hhook=%p,event=%x,hwnd=%p,object_id=%x,child_id=%x,tid=%04x,time=%x)\n",
GetCurrentThreadId(), proc, info.handle, event, hwnd, object_id,
child_id, GetCurrentThreadId(), GetCurrentTime());
}
}
else
break;
}
while (find_next_hook(event, hwnd, object_id, child_id, &info));
find_hook_close(WH_WINEVENT);
}
/***********************************************************************
* IsWinEventHookInstalled [USER32.@]
*
* Determine if an event hook is installed for an event.
*
* PARAMS
* dwEvent [I] Id of the event
*
* RETURNS
* TRUE, If there are any hooks installed for the event.
* FALSE, Otherwise.
*
* BUGS
* Not implemented.
*/
BOOL WINAPI IsWinEventHookInstalled(DWORD dwEvent)
{
/* FIXME: Needed by Office 2007 installer */
WARN("(%d)-stub!\n", dwEvent);
return TRUE;
}
/***********************************************************************
* RegisterShellHookWindow [USER32.@]
*/
BOOL WINAPI RegisterShellHookWindow ( HWND hWnd )
{
return RosUserRegisterShellHookWindow( hWnd );
}
/***********************************************************************
* DeregisterShellHookWindow [USER32.@]
*/
HRESULT WINAPI DeregisterShellHookWindow ( HWND hWnd )
{
return RosUserDeRegisterShellHookWindow( hWnd );
}

View File

@@ -18,10 +18,22 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <user32.h>
#include "config.h"
#include <wine/debug.h>
WINE_DEFAULT_DEBUG_CHANNEL(user32);
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"
#include "wine/unicode.h"
#include "controls.h"
#include "win.h"
static BOOL bMultiLineTitle;
static HFONT hIconTitleFont;
@@ -31,18 +43,16 @@ static HFONT hIconTitleFont;
*/
const struct builtin_class_descr ICONTITLE_builtin_class =
{
WC_ICONTITLE, /* name */
0, /* style */
NULL, /* procA (winproc is Unicode only) */
IconTitleWndProc, /* procW */
0, /* extra */
IDC_ARROW, /* cursor */
0 /* brush */
(LPCWSTR)ICONTITLE_CLASS_ATOM, /* name */
0, /* style */
WINPROC_ICONTITLE, /* proc */
0, /* extra */
IDC_ARROW, /* cursor */
0 /* brush */
};
#ifndef __REACTOS__
/***********************************************************************
* ICONTITLE_Create
*/
@@ -53,7 +63,7 @@ HWND ICONTITLE_Create( HWND owner )
LONG style = WS_CLIPSIBLINGS;
if (!IsWindowEnabled(owner)) style |= WS_DISABLED;
if( GetWindowLongPtrA( owner, GWL_STYLE ) & WS_CHILD )
if( GetWindowLongA( owner, GWL_STYLE ) & WS_CHILD )
hWnd = CreateWindowExA( 0, (LPCSTR)ICONTITLE_CLASS_ATOM, NULL,
style | WS_CHILD, 0, 0, 1, 1,
GetParent(owner), 0, instance, NULL );
@@ -62,11 +72,10 @@ HWND ICONTITLE_Create( HWND owner )
style, 0, 0, 1, 1,
owner, 0, instance, NULL );
WIN_SetOwner( hWnd, owner ); /* MDI depends on this */
SetWindowLongPtrW( hWnd, GWL_STYLE,
GetWindowLongPtrW( hWnd, GWL_STYLE ) & ~(WS_CAPTION | WS_BORDER) );
SetWindowLongW( hWnd, GWL_STYLE,
GetWindowLongW( hWnd, GWL_STYLE ) & ~(WS_CAPTION | WS_BORDER) );
return hWnd;
}
#endif
/***********************************************************************
* ICONTITLE_SetTitlePos
@@ -136,7 +145,7 @@ static BOOL ICONTITLE_Paint( HWND hwnd, HWND owner, HDC hDC, BOOL bActive )
}
else
{
if( GetWindowLongPtrA( hwnd, GWL_STYLE ) & WS_CHILD )
if( GetWindowLongA( hwnd, GWL_STYLE ) & WS_CHILD )
{
hBrush = (HBRUSH) GetClassLongPtrW(hwnd, GCLP_HBRBACKGROUND);
if( hBrush )
@@ -216,7 +225,7 @@ LRESULT WINAPI IconTitleWndProc( HWND hWnd, UINT msg,
if (wParam) ICONTITLE_SetTitlePos( hWnd, owner );
return 0;
case WM_ERASEBKGND:
if( GetWindowLongPtrW( owner, GWL_STYLE ) & WS_CHILD )
if( GetWindowLongW( owner, GWL_STYLE ) & WS_CHILD )
lParam = SendMessageW( owner, WM_ISACTIVEICON, 0, 0 );
else
lParam = (owner == GetActiveWindow());

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,413 @@
/*
* PROJECT: ReactOS CSRSS
* LICENSE: GPL - See COPYING in the top level directory
* COPYRIGHT: Casper S. Hornstrup (chorns@users.sourceforge.net)
*
* this file is heavily based on subsystems\win32\win32k\ntuser\input.c from trunk
*/
#define NDEBUG
#define WIN32_NO_STATUS
#define NOCRYPT
#include <windows.h>
#define NTOS_MODE_USER
#include <ndk/ntndk.h>
#include <debug.h>
#include <ntddmou.h>
#include <ntddkbd.h>
#include <ntuser.h>
static HHOOK gKeyboardHook, gMouseHook;
#define ClearMouseInput(mi) \
mi.dx = 0; \
mi.dy = 0; \
mi.mouseData = 0; \
mi.dwFlags = 0;
#define SendMouseEvent(mi) \
if(mi.dx != 0 || mi.dy != 0) \
mi.dwFlags |= MOUSEEVENTF_MOVE; \
if(mi.dwFlags) \
mouse_event(mi.dwFlags,mi.dx,mi.dy, mi.mouseData, 0); \
ClearMouseInput(mi);
#define INPUT_DEVICES 2
static LRESULT CALLBACK DummyHookProc( INT code, WPARAM wparam, LPARAM lparam ){
return CallNextHookEx( 0, code, wparam, lparam );
}
VOID FASTCALL
ProcessMouseInputData(PMOUSE_INPUT_DATA Data, ULONG InputCount)
{
PMOUSE_INPUT_DATA mid;
MOUSEINPUT mi;
ULONG i;
ClearMouseInput(mi);
mi.time = 0;
mi.dwExtraInfo = 0;
for(i = 0; i < InputCount; i++)
{
mid = (Data + i);
mi.dx += mid->LastX;
mi.dy += mid->LastY;
/* Check if the mouse move is absolute */
if (mid->Flags == MOUSE_MOVE_ABSOLUTE)
{
/* Set flag and convert to screen location */
mi.dwFlags |= MOUSEEVENTF_ABSOLUTE;
mi.dx = mi.dx / (65535 / (GetSystemMetrics(SM_CXVIRTUALSCREEN) - 1));
mi.dy = mi.dy / (65535 / (GetSystemMetrics(SM_CYVIRTUALSCREEN) - 1));
}
if(mid->ButtonFlags)
{
if(mid->ButtonFlags & MOUSE_LEFT_BUTTON_DOWN)
{
mi.dwFlags |= MOUSEEVENTF_LEFTDOWN;
SendMouseEvent(mi);
}
if(mid->ButtonFlags & MOUSE_LEFT_BUTTON_UP)
{
mi.dwFlags |= MOUSEEVENTF_LEFTUP;
SendMouseEvent(mi);
}
if(mid->ButtonFlags & MOUSE_MIDDLE_BUTTON_DOWN)
{
mi.dwFlags |= MOUSEEVENTF_MIDDLEDOWN;
SendMouseEvent(mi);
}
if(mid->ButtonFlags & MOUSE_MIDDLE_BUTTON_UP)
{
mi.dwFlags |= MOUSEEVENTF_MIDDLEUP;
SendMouseEvent(mi);
}
if(mid->ButtonFlags & MOUSE_RIGHT_BUTTON_DOWN)
{
mi.dwFlags |= MOUSEEVENTF_RIGHTDOWN;
SendMouseEvent(mi);
}
if(mid->ButtonFlags & MOUSE_RIGHT_BUTTON_UP)
{
mi.dwFlags |= MOUSEEVENTF_RIGHTUP;
SendMouseEvent(mi);
}
if(mid->ButtonFlags & MOUSE_BUTTON_4_DOWN)
{
mi.mouseData |= XBUTTON1;
mi.dwFlags |= MOUSEEVENTF_XDOWN;
SendMouseEvent(mi);
}
if(mid->ButtonFlags & MOUSE_BUTTON_4_UP)
{
mi.mouseData |= XBUTTON1;
mi.dwFlags |= MOUSEEVENTF_XUP;
SendMouseEvent(mi);
}
if(mid->ButtonFlags & MOUSE_BUTTON_5_DOWN)
{
mi.mouseData |= XBUTTON2;
mi.dwFlags |= MOUSEEVENTF_XDOWN;
SendMouseEvent(mi);
}
if(mid->ButtonFlags & MOUSE_BUTTON_5_UP)
{
mi.mouseData |= XBUTTON2;
mi.dwFlags |= MOUSEEVENTF_XUP;
SendMouseEvent(mi);
}
if(mid->ButtonFlags & MOUSE_WHEEL)
{
mi.mouseData = mid->ButtonData;
mi.dwFlags |= MOUSEEVENTF_WHEEL;
SendMouseEvent(mi);
}
}
}
SendMouseEvent(mi);
}
/* Sends the keyboard commands to turn on/off the lights.
*/
static NTSTATUS APIENTRY
IntKeyboardUpdateLeds(HANDLE KeyboardDeviceHandle,
PKEYBOARD_INPUT_DATA KeyInput,
PKEYBOARD_INDICATOR_TRANSLATION IndicatorTrans)
{
NTSTATUS Status;
UINT Count;
static KEYBOARD_INDICATOR_PARAMETERS Indicators;
IO_STATUS_BLOCK Block;
if (!IndicatorTrans)
return STATUS_NOT_SUPPORTED;
if (KeyInput->Flags & (KEY_E0 | KEY_E1 | KEY_BREAK))
return STATUS_SUCCESS;
for (Count = 0; Count < IndicatorTrans->NumberOfIndicatorKeys; Count++)
{
if (KeyInput->MakeCode == IndicatorTrans->IndicatorList[Count].MakeCode)
{
Indicators.LedFlags ^=
IndicatorTrans->IndicatorList[Count].IndicatorFlags;
/* Update the lights on the hardware */
Status = NtDeviceIoControlFile(KeyboardDeviceHandle,
NULL,
NULL,
NULL,
&Block,
IOCTL_KEYBOARD_SET_INDICATORS,
&Indicators, sizeof(Indicators),
NULL, 0);
return Status;
}
}
return STATUS_SUCCESS;
}
/* Asks the keyboard driver to send a small table that shows which
* lights should connect with which scancodes
*/
static NTSTATUS APIENTRY
IntKeyboardGetIndicatorTrans(HANDLE KeyboardDeviceHandle,
PKEYBOARD_INDICATOR_TRANSLATION *IndicatorTrans)
{
NTSTATUS Status;
DWORD Size = 0;
IO_STATUS_BLOCK Block;
PKEYBOARD_INDICATOR_TRANSLATION Ret;
Size = sizeof(KEYBOARD_INDICATOR_TRANSLATION);
Ret = HeapAlloc(GetProcessHeap(), 0, Size);
while (Ret)
{
Status = NtDeviceIoControlFile(KeyboardDeviceHandle,
NULL,
NULL,
NULL,
&Block,
IOCTL_KEYBOARD_QUERY_INDICATOR_TRANSLATION,
NULL,
0,
Ret, Size);
if (Status != STATUS_BUFFER_TOO_SMALL)
break;
HeapFree(GetProcessHeap(), 0, Ret);
Size += sizeof(KEYBOARD_INDICATOR_TRANSLATION);
Ret = HeapAlloc(GetProcessHeap(), 0, Size);
}
if (!Ret)
return STATUS_INSUFFICIENT_RESOURCES;
if (Status != STATUS_SUCCESS)
{
HeapFree(GetProcessHeap(), 0, Ret);
return Status;
}
*IndicatorTrans = Ret;
return Status;
}
DWORD WINAPI InputThread()
{
UNICODE_STRING KeyboardDeviceName = RTL_CONSTANT_STRING(L"\\Device\\KeyboardClass0");
UNICODE_STRING MouseDeviceName = RTL_CONSTANT_STRING(L"\\Device\\PointerClass0");
OBJECT_ATTRIBUTES KeyboardObjectAttributes;
OBJECT_ATTRIBUTES MouseObjectAttributes;
IO_STATUS_BLOCK KeyboardIosb;
IO_STATUS_BLOCK MouseIosb;
HANDLE KeyboardDeviceHandle;
HANDLE MouseDeviceHandle;
NTSTATUS KeyboardStatus = STATUS_UNSUCCESSFUL;
NTSTATUS MouseStatus = STATUS_UNSUCCESSFUL;
PKEYBOARD_INDICATOR_TRANSLATION IndicatorTrans = NULL;
HANDLE hInputs[INPUT_DEVICES];
NTSTATUS Status;
LARGE_INTEGER ByteOffset;
ByteOffset.QuadPart = (LONGLONG)0;
InitializeObjectAttributes(&KeyboardObjectAttributes,
&KeyboardDeviceName,
0,
NULL,
NULL);
do
{
Sleep(1000);
KeyboardStatus = NtOpenFile(&KeyboardDeviceHandle,
FILE_ALL_ACCESS,
&KeyboardObjectAttributes,
&KeyboardIosb,
0,
0);
} while (!NT_SUCCESS(KeyboardStatus));
InitializeObjectAttributes(&MouseObjectAttributes,
&MouseDeviceName,
0,
NULL,
NULL);
do
{
Sleep(1000);
MouseStatus = NtOpenFile(&MouseDeviceHandle,
FILE_ALL_ACCESS,
&MouseObjectAttributes,
&MouseIosb,
0,
0);
} while (!NT_SUCCESS(MouseStatus));
IntKeyboardGetIndicatorTrans(KeyboardDeviceHandle, &IndicatorTrans);
while(1)
{
KEYBOARD_INPUT_DATA KeyInput;
MOUSE_INPUT_DATA MouseInput;
DWORD flags;
INT iWaitObjects = 0;
if(MouseStatus != STATUS_PENDING)
{
MouseStatus = NtReadFile(MouseDeviceHandle,
NULL,
NULL,
NULL,
&MouseIosb,
&MouseInput,
sizeof(MOUSE_INPUT_DATA),
&ByteOffset,
NULL);
}
if(MouseStatus == STATUS_PENDING)
hInputs[iWaitObjects++] = MouseDeviceHandle;
if(KeyboardStatus != STATUS_PENDING)
{
KeyboardStatus = NtReadFile(KeyboardDeviceHandle,
NULL,
NULL,
NULL,
&KeyboardIosb,
&KeyInput,
sizeof(KEYBOARD_INPUT_DATA),
&ByteOffset,
NULL);
}
if(KeyboardStatus == STATUS_PENDING)
hInputs[iWaitObjects++] = KeyboardDeviceHandle;
if(MouseStatus == STATUS_PENDING && KeyboardStatus == STATUS_PENDING)
{
/* Both devices pending, wait for them */
Status = NtWaitForMultipleObjects(iWaitObjects, hInputs, WaitAny, FALSE, 0);
if ((Status >= STATUS_WAIT_0) && (Status < (STATUS_WAIT_0 + iWaitObjects)))
{
if(hInputs[Status - STATUS_WAIT_0] == KeyboardDeviceHandle)
{
KeyboardStatus = KeyboardIosb.Status;
}
else if(hInputs[Status - STATUS_WAIT_0] == MouseDeviceHandle)
{
MouseStatus = MouseIosb.Status;
}
}
}
if(NT_SUCCESS(MouseStatus) && MouseStatus != STATUS_PENDING)
{
if(!gMouseHook)
gMouseHook = SetWindowsHookEx(WH_MOUSE_LL, DummyHookProc, NULL, 0);
ProcessMouseInputData(&MouseInput, MouseIosb.Information / sizeof(MOUSE_INPUT_DATA));
}
else if (MouseStatus != STATUS_PENDING)
{
DPRINT1("Failed to read from mouse 0x%08x\n", MouseStatus);
}
if(NT_SUCCESS(KeyboardStatus) && KeyboardStatus != STATUS_PENDING)
{
IntKeyboardUpdateLeds(KeyboardDeviceHandle, &KeyInput, IndicatorTrans);
flags = 0;
if (KeyInput.Flags & KEY_E0)
flags |= KEYEVENTF_EXTENDEDKEY;
if (KeyInput.Flags & KEY_BREAK)
flags |= KEYEVENTF_KEYUP;
if(!gKeyboardHook)
gKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, DummyHookProc, NULL, 0);
keybd_event(MapVirtualKey(KeyInput.MakeCode & 0xff, MAPVK_VSC_TO_VK), KeyInput.MakeCode & 0xff, flags , 0);
}
else if (KeyboardStatus != STATUS_PENDING)
{
DPRINT1("Failed to read from keyboard 0x%08x\n", KeyboardStatus);
}
}
return KeyboardStatus;
}
DWORD_PTR WINAPI NtUserCallOneParam(DWORD_PTR Param, DWORD Routine)
{
BOOLEAN Suspend = FALSE;
if(Routine == ONEPARAM_ROUTINE_CREATESYSTEMTHREADS)
{
if(Param == 0)
{
Suspend = InputThread();
}
else
{
/* FIXME */
Suspend = TRUE;
}
}
else
{
DPRINT1("Unknown routine %u\n", Routine);
}
while(Suspend)
{
Sleep(INFINITE);
}
return 0;
}

View File

@@ -0,0 +1,42 @@
#include <stdarg.h>
#include <string.h>
#include <stdlib.h>
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winerror.h"
#include "wine/winbase16.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(userlegacy);
VOID
WINAPI
ReleaseThunkLock(DWORD *mutex_count)
{
}
VOID
WINAPI
RestoreThunkLock(DWORD mutex_count)
{
}
VOID
WINAPI
InitializeLpkHooks(FARPROC *hookfuncs)
{
UNIMPLEMENTED;
}
/*
* Private calls for CSRSS
*/
VOID
WINAPI
PrivateCsrssManualGuiCheck(LONG Check)
{
UNIMPLEMENTED;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,459 @@
/*
* USER string functions
*
* Copyright 1993 Yngvi Sigurjonsson (yngvi@hafro.is)
* Copyright 1996 Alexandre Julliard
* Copyright 1996 Marcus Meissner
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "config.h"
#include "wine/port.h"
#include <ctype.h>
#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "winerror.h"
#include "wine/exception.h"
#include "wine/unicode.h"
/***********************************************************************
* CharNextA (USER32.@)
*/
LPSTR WINAPI CharNextA( LPCSTR ptr )
{
if (!*ptr) return (LPSTR)ptr;
if (IsDBCSLeadByte( ptr[0] ) && ptr[1]) return (LPSTR)(ptr + 2);
return (LPSTR)(ptr + 1);
}
/***********************************************************************
* CharNextExA (USER32.@)
*/
LPSTR WINAPI CharNextExA( WORD codepage, LPCSTR ptr, DWORD flags )
{
if (!*ptr) return (LPSTR)ptr;
if (IsDBCSLeadByteEx( codepage, ptr[0] ) && ptr[1]) return (LPSTR)(ptr + 2);
return (LPSTR)(ptr + 1);
}
/***********************************************************************
* CharNextExW (USER32.@)
*/
LPWSTR WINAPI CharNextExW( WORD codepage, LPCWSTR ptr, DWORD flags )
{
/* doesn't make sense, there are no codepages for Unicode */
return NULL;
}
/***********************************************************************
* CharNextW (USER32.@)
*/
LPWSTR WINAPI CharNextW(LPCWSTR x)
{
if (*x) x++;
return (LPWSTR)x;
}
/***********************************************************************
* CharPrevA (USER32.@)
*/
LPSTR WINAPI CharPrevA( LPCSTR start, LPCSTR ptr )
{
while (*start && (start < ptr))
{
LPCSTR next = CharNextA( start );
if (next >= ptr) break;
start = next;
}
return (LPSTR)start;
}
/***********************************************************************
* CharPrevExA (USER32.@)
*/
LPSTR WINAPI CharPrevExA( WORD codepage, LPCSTR start, LPCSTR ptr, DWORD flags )
{
while (*start && (start < ptr))
{
LPCSTR next = CharNextExA( codepage, start, flags );
if (next >= ptr) break;
start = next;
}
return (LPSTR)start;
}
/***********************************************************************
* CharPrevExW (USER32.@)
*/
LPWSTR WINAPI CharPrevExW( WORD codepage, LPCWSTR start, LPCWSTR ptr, DWORD flags )
{
/* doesn't make sense, there are no codepages for Unicode */
return NULL;
}
/***********************************************************************
* CharPrevW (USER32.@)
*/
LPWSTR WINAPI CharPrevW(LPCWSTR start,LPCWSTR x)
{
if (x>start) return (LPWSTR)(x-1);
else return (LPWSTR)x;
}
/***********************************************************************
* CharToOemA (USER32.@)
*/
BOOL WINAPI CharToOemA( LPCSTR s, LPSTR d )
{
if ( !s || !d ) return TRUE;
return CharToOemBuffA( s, d, strlen( s ) + 1 );
}
/***********************************************************************
* CharToOemBuffA (USER32.@)
*/
BOOL WINAPI CharToOemBuffA( LPCSTR s, LPSTR d, DWORD len )
{
WCHAR *bufW;
bufW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
if( bufW )
{
MultiByteToWideChar( CP_ACP, 0, s, len, bufW, len );
WideCharToMultiByte( CP_OEMCP, 0, bufW, len, d, len, NULL, NULL );
HeapFree( GetProcessHeap(), 0, bufW );
}
return TRUE;
}
/***********************************************************************
* CharToOemBuffW (USER32.@)
*/
BOOL WINAPI CharToOemBuffW( LPCWSTR s, LPSTR d, DWORD len )
{
if ( !s || !d ) return TRUE;
WideCharToMultiByte( CP_OEMCP, 0, s, len, d, len, NULL, NULL );
return TRUE;
}
/***********************************************************************
* CharToOemW (USER32.@)
*/
BOOL WINAPI CharToOemW( LPCWSTR s, LPSTR d )
{
return CharToOemBuffW( s, d, strlenW( s ) + 1 );
}
/***********************************************************************
* OemToCharA (USER32.@)
*/
BOOL WINAPI OemToCharA( LPCSTR s, LPSTR d )
{
return OemToCharBuffA( s, d, strlen( s ) + 1 );
}
/***********************************************************************
* OemToCharBuffA (USER32.@)
*/
BOOL WINAPI OemToCharBuffA( LPCSTR s, LPSTR d, DWORD len )
{
WCHAR *bufW;
bufW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
if( bufW )
{
MultiByteToWideChar( CP_OEMCP, 0, s, len, bufW, len );
WideCharToMultiByte( CP_ACP, 0, bufW, len, d, len, NULL, NULL );
HeapFree( GetProcessHeap(), 0, bufW );
}
return TRUE;
}
/***********************************************************************
* OemToCharBuffW (USER32.@)
*/
BOOL WINAPI OemToCharBuffW( LPCSTR s, LPWSTR d, DWORD len )
{
MultiByteToWideChar( CP_OEMCP, 0, s, len, d, len );
return TRUE;
}
/***********************************************************************
* OemToCharW (USER32.@)
*/
BOOL WINAPI OemToCharW( LPCSTR s, LPWSTR d )
{
return OemToCharBuffW( s, d, strlen( s ) + 1 );
}
/***********************************************************************
* CharLowerA (USER32.@)
*/
LPSTR WINAPI CharLowerA(LPSTR str)
{
if (IS_INTRESOURCE(str))
{
char ch = LOWORD(str);
CharLowerBuffA( &ch, 1 );
return (LPSTR)(UINT_PTR)(BYTE)ch;
}
__TRY
{
CharLowerBuffA( str, strlen(str) );
}
__EXCEPT_PAGE_FAULT
{
SetLastError( ERROR_INVALID_PARAMETER );
_SEH2_YIELD(return NULL;)
}
__ENDTRY
return str;
}
/***********************************************************************
* CharUpperA (USER32.@)
*/
LPSTR WINAPI CharUpperA(LPSTR str)
{
if (IS_INTRESOURCE(str))
{
char ch = LOWORD(str);
CharUpperBuffA( &ch, 1 );
return (LPSTR)(UINT_PTR)(BYTE)ch;
}
__TRY
{
CharUpperBuffA( str, strlen(str) );
}
__EXCEPT_PAGE_FAULT
{
SetLastError( ERROR_INVALID_PARAMETER );
_SEH2_YIELD(return NULL;)
}
__ENDTRY
return str;
}
/***********************************************************************
* CharLowerW (USER32.@)
*/
LPWSTR WINAPI CharLowerW(LPWSTR x)
{
if (!IS_INTRESOURCE(x)) return strlwrW(x);
else return (LPWSTR)((UINT_PTR)tolowerW(LOWORD(x)));
}
/***********************************************************************
* CharUpperW (USER32.@)
*/
LPWSTR WINAPI CharUpperW(LPWSTR x)
{
if (!IS_INTRESOURCE(x)) return struprW(x);
else return (LPWSTR)((UINT_PTR)toupperW(LOWORD(x)));
}
/***********************************************************************
* CharLowerBuffA (USER32.@)
*/
DWORD WINAPI CharLowerBuffA( LPSTR str, DWORD len )
{
DWORD lenW;
WCHAR buffer[32];
WCHAR *strW = buffer;
if (!str) return 0; /* YES */
lenW = MultiByteToWideChar(CP_ACP, 0, str, len, NULL, 0);
if (lenW > sizeof(buffer)/sizeof(WCHAR))
{
strW = HeapAlloc(GetProcessHeap(), 0, lenW * sizeof(WCHAR));
if (!strW) return 0;
}
MultiByteToWideChar(CP_ACP, 0, str, len, strW, lenW);
CharLowerBuffW(strW, lenW);
len = WideCharToMultiByte(CP_ACP, 0, strW, lenW, str, len, NULL, NULL);
if (strW != buffer) HeapFree(GetProcessHeap(), 0, strW);
return len;
}
/***********************************************************************
* CharLowerBuffW (USER32.@)
*/
DWORD WINAPI CharLowerBuffW( LPWSTR str, DWORD len )
{
DWORD ret = len;
if (!str) return 0; /* YES */
for (; len; len--, str++) *str = tolowerW(*str);
return ret;
}
/***********************************************************************
* CharUpperBuffA (USER32.@)
*/
DWORD WINAPI CharUpperBuffA( LPSTR str, DWORD len )
{
DWORD lenW;
WCHAR buffer[32];
WCHAR *strW = buffer;
if (!str) return 0; /* YES */
lenW = MultiByteToWideChar(CP_ACP, 0, str, len, NULL, 0);
if (lenW > sizeof(buffer)/sizeof(WCHAR))
{
strW = HeapAlloc(GetProcessHeap(), 0, lenW * sizeof(WCHAR));
if (!strW) return 0;
}
MultiByteToWideChar(CP_ACP, 0, str, len, strW, lenW);
CharUpperBuffW(strW, lenW);
len = WideCharToMultiByte(CP_ACP, 0, strW, lenW, str, len, NULL, NULL);
if (strW != buffer) HeapFree(GetProcessHeap(), 0, strW);
return len;
}
/***********************************************************************
* CharUpperBuffW (USER32.@)
*/
DWORD WINAPI CharUpperBuffW( LPWSTR str, DWORD len )
{
DWORD ret = len;
if (!str) return 0; /* YES */
for (; len; len--, str++) *str = toupperW(*str);
return ret;
}
/***********************************************************************
* IsCharLower (USER.436)
* IsCharLowerA (USER32.@)
*/
BOOL WINAPI IsCharLowerA(CHAR x)
{
WCHAR wch;
MultiByteToWideChar(CP_ACP, 0, &x, 1, &wch, 1);
return IsCharLowerW(wch);
}
/***********************************************************************
* IsCharLowerW (USER32.@)
*/
BOOL WINAPI IsCharLowerW(WCHAR x)
{
//return (get_char_typeW(x) & C1_LOWER) != 0;
return iswlower(x);
}
/***********************************************************************
* IsCharUpper (USER.435)
* IsCharUpperA (USER32.@)
*/
BOOL WINAPI IsCharUpperA(CHAR x)
{
WCHAR wch;
MultiByteToWideChar(CP_ACP, 0, &x, 1, &wch, 1);
return IsCharUpperW(wch);
}
/***********************************************************************
* IsCharUpperW (USER32.@)
*/
BOOL WINAPI IsCharUpperW(WCHAR x)
{
//return (get_char_typeW(x) & C1_UPPER) != 0;
return iswupper(x);
}
/***********************************************************************
* IsCharAlphaNumeric (USER.434)
* IsCharAlphaNumericA (USER32.@)
*/
BOOL WINAPI IsCharAlphaNumericA(CHAR x)
{
WCHAR wch;
MultiByteToWideChar(CP_ACP, 0, &x, 1, &wch, 1);
return IsCharAlphaNumericW(wch);
}
/***********************************************************************
* IsCharAlphaNumericW (USER32.@)
*/
BOOL WINAPI IsCharAlphaNumericW(WCHAR x)
{
//return (get_char_typeW(x) & (C1_ALPHA|C1_DIGIT)) != 0;
return iswalnum(x);
}
/***********************************************************************
* IsCharAlpha (USER.433)
* IsCharAlphaA (USER32.@)
*/
BOOL WINAPI IsCharAlphaA(CHAR x)
{
WCHAR wch;
MultiByteToWideChar(CP_ACP, 0, &x, 1, &wch, 1);
return IsCharAlphaW(wch);
}
/***********************************************************************
* IsCharAlphaW (USER32.@)
*/
BOOL WINAPI IsCharAlphaW(WCHAR x)
{
//return (get_char_typeW(x) & C1_ALPHA) != 0;
return iswalpha(x);
}

1991
arwinss/client/user32/mdi.c Normal file

File diff suppressed because it is too large Load Diff

5356
arwinss/client/user32/menu.c Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,615 @@
/*
* Misc USER functions
*
* Copyright 1995 Thomas Sandford
* Copyright 1997 Marcus Meissner
* Copyright 1998 Turchanov Sergey
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <stdarg.h>
#include "windef.h"
#include "wine/windef16.h"
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"
#include "winnls.h"
#include "wine/winternl.h"
#include "user_private.h"
#include "wine/unicode.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(win);
/* USER signal proc flags and codes */
/* See UserSignalProc for comments */
#define USIG_FLAGS_WIN32 0x0001
#define USIG_FLAGS_GUI 0x0002
#define USIG_FLAGS_FEEDBACK 0x0004
#define USIG_FLAGS_FAULT 0x0008
#define USIG_DLL_UNLOAD_WIN16 0x0001
#define USIG_DLL_UNLOAD_WIN32 0x0002
#define USIG_FAULT_DIALOG_PUSH 0x0003
#define USIG_FAULT_DIALOG_POP 0x0004
#define USIG_DLL_UNLOAD_ORPHANS 0x0005
#define USIG_THREAD_INIT 0x0010
#define USIG_THREAD_EXIT 0x0020
#define USIG_PROCESS_CREATE 0x0100
#define USIG_PROCESS_INIT 0x0200
#define USIG_PROCESS_EXIT 0x0300
#define USIG_PROCESS_DESTROY 0x0400
#define USIG_PROCESS_RUNNING 0x0500
#define USIG_PROCESS_LOADED 0x0600
/***********************************************************************
* SignalProc32 (USER.391)
* UserSignalProc (USER32.@)
*
* The exact meaning of the USER signals is undocumented, but this
* should cover the basic idea:
*
* USIG_DLL_UNLOAD_WIN16
* This is sent when a 16-bit module is unloaded.
*
* USIG_DLL_UNLOAD_WIN32
* This is sent when a 32-bit module is unloaded.
*
* USIG_DLL_UNLOAD_ORPHANS
* This is sent after the last Win3.1 module is unloaded,
* to allow removal of orphaned menus.
*
* USIG_FAULT_DIALOG_PUSH
* USIG_FAULT_DIALOG_POP
* These are called to allow USER to prepare for displaying a
* fault dialog, even though the fault might have happened while
* inside a USER critical section.
*
* USIG_THREAD_INIT
* This is called from the context of a new thread, as soon as it
* has started to run.
*
* USIG_THREAD_EXIT
* This is called, still in its context, just before a thread is
* about to terminate.
*
* USIG_PROCESS_CREATE
* This is called, in the parent process context, after a new process
* has been created.
*
* USIG_PROCESS_INIT
* This is called in the new process context, just after the main thread
* has started execution (after the main thread's USIG_THREAD_INIT has
* been sent).
*
* USIG_PROCESS_LOADED
* This is called after the executable file has been loaded into the
* new process context.
*
* USIG_PROCESS_RUNNING
* This is called immediately before the main entry point is called.
*
* USIG_PROCESS_EXIT
* This is called in the context of a process that is about to
* terminate (but before the last thread's USIG_THREAD_EXIT has
* been sent).
*
* USIG_PROCESS_DESTROY
* This is called after a process has terminated.
*
*
* The meaning of the dwFlags bits is as follows:
*
* USIG_FLAGS_WIN32
* Current process is 32-bit.
*
* USIG_FLAGS_GUI
* Current process is a (Win32) GUI process.
*
* USIG_FLAGS_FEEDBACK
* Current process needs 'feedback' (determined from the STARTUPINFO
* flags STARTF_FORCEONFEEDBACK / STARTF_FORCEOFFFEEDBACK).
*
* USIG_FLAGS_FAULT
* The signal is being sent due to a fault.
*/
WORD WINAPI UserSignalProc( UINT uCode, DWORD dwThreadOrProcessID,
DWORD dwFlags, HMODULE16 hModule )
{
FIXME("(%04x, %08x, %04x, %04x)\n",
uCode, dwThreadOrProcessID, dwFlags, hModule );
/* FIXME: Should chain to GdiSignalProc now. */
return 0;
}
/**********************************************************************
* SetLastErrorEx [USER32.@]
*
* Sets the last-error code.
*
* RETURNS
* None.
*/
void WINAPI SetLastErrorEx(
DWORD error, /* [in] Per-thread error code */
DWORD type) /* [in] Error type */
{
TRACE("(0x%08x, 0x%08x)\n", error,type);
switch(type) {
case 0:
break;
case SLE_ERROR:
case SLE_MINORERROR:
case SLE_WARNING:
/* Fall through for now */
default:
FIXME("(error=%08x, type=%08x): Unhandled type\n", error,type);
break;
}
SetLastError( error );
}
/******************************************************************************
* GetAltTabInfoA [USER32.@]
*/
BOOL WINAPI GetAltTabInfoA(HWND hwnd, int iItem, PALTTABINFO pati, LPSTR pszItemText, UINT cchItemText)
{
FIXME("(%p, 0x%08x, %p, %p, 0x%08x)\n", hwnd, iItem, pati, pszItemText, cchItemText);
return FALSE;
}
/******************************************************************************
* GetAltTabInfoW [USER32.@]
*/
BOOL WINAPI GetAltTabInfoW(HWND hwnd, int iItem, PALTTABINFO pati, LPWSTR pszItemText, UINT cchItemText)
{
FIXME("(%p, 0x%08x, %p, %p, 0x%08x)\n", hwnd, iItem, pati, pszItemText, cchItemText);
return FALSE;
}
/******************************************************************************
* SetDebugErrorLevel [USER32.@]
* Sets the minimum error level for generating debugging events
*
* PARAMS
* dwLevel [I] Debugging error level
*
* RETURNS
* Nothing.
*/
VOID WINAPI SetDebugErrorLevel( DWORD dwLevel )
{
FIXME("(%d): stub\n", dwLevel);
}
/***********************************************************************
* SetWindowStationUser (USER32.@)
*/
DWORD WINAPI SetWindowStationUser(DWORD x1,DWORD x2,DWORD x3,DWORD x4)
{
FIXME("(0x%08x,0x%08x,0x%08x,0x%08x),stub!\n",x1,x2,x3,x4);
return 1;
}
static const WCHAR primary_device_name[] = {'\\','\\','.','\\','D','I','S','P','L','A','Y','1',0};
static const WCHAR primary_device_string[] = {'X','1','1',' ','W','i','n','d','o','w','i','n','g',' ',
'S','y','s','t','e','m',0};
static const WCHAR primary_device_deviceid[] = {'P','C','I','\\','V','E','N','_','0','0','0','0','&',
'D','E','V','_','0','0','0','0',0};
/***********************************************************************
* EnumDisplayDevicesA (USER32.@)
*/
BOOL WINAPI EnumDisplayDevicesA( LPCSTR lpDevice, DWORD i, LPDISPLAY_DEVICEA lpDispDev,
DWORD dwFlags )
{
UNICODE_STRING deviceW;
DISPLAY_DEVICEW ddW;
BOOL ret;
if(lpDevice)
RtlCreateUnicodeStringFromAsciiz(&deviceW, lpDevice);
else
deviceW.Buffer = NULL;
ddW.cb = sizeof(ddW);
ret = EnumDisplayDevicesW(deviceW.Buffer, i, &ddW, dwFlags);
RtlFreeUnicodeString(&deviceW);
if(!ret) return ret;
WideCharToMultiByte(CP_ACP, 0, ddW.DeviceName, -1, lpDispDev->DeviceName, sizeof(lpDispDev->DeviceName), NULL, NULL);
WideCharToMultiByte(CP_ACP, 0, ddW.DeviceString, -1, lpDispDev->DeviceString, sizeof(lpDispDev->DeviceString), NULL, NULL);
lpDispDev->StateFlags = ddW.StateFlags;
if(lpDispDev->cb >= offsetof(DISPLAY_DEVICEA, DeviceID) + sizeof(lpDispDev->DeviceID))
WideCharToMultiByte(CP_ACP, 0, ddW.DeviceID, -1, lpDispDev->DeviceID, sizeof(lpDispDev->DeviceID), NULL, NULL);
if(lpDispDev->cb >= offsetof(DISPLAY_DEVICEA, DeviceKey) + sizeof(lpDispDev->DeviceKey))
WideCharToMultiByte(CP_ACP, 0, ddW.DeviceKey, -1, lpDispDev->DeviceKey, sizeof(lpDispDev->DeviceKey), NULL, NULL);
return TRUE;
}
/***********************************************************************
* EnumDisplayDevicesW (USER32.@)
*/
BOOL WINAPI EnumDisplayDevicesW( LPCWSTR lpDevice, DWORD i, LPDISPLAY_DEVICEW lpDisplayDevice,
DWORD dwFlags )
{
FIXME("(%s,%d,%p,0x%08x), stub!\n",debugstr_w(lpDevice),i,lpDisplayDevice,dwFlags);
if (i)
return FALSE;
memcpy(lpDisplayDevice->DeviceName, primary_device_name, sizeof(primary_device_name));
memcpy(lpDisplayDevice->DeviceString, primary_device_string, sizeof(primary_device_string));
lpDisplayDevice->StateFlags =
DISPLAY_DEVICE_ATTACHED_TO_DESKTOP |
DISPLAY_DEVICE_PRIMARY_DEVICE |
DISPLAY_DEVICE_VGA_COMPATIBLE;
if(lpDisplayDevice->cb >= offsetof(DISPLAY_DEVICEW, DeviceID) + sizeof(lpDisplayDevice->DeviceID))
memcpy(lpDisplayDevice->DeviceID, primary_device_deviceid, sizeof(primary_device_deviceid));
if(lpDisplayDevice->cb >= offsetof(DISPLAY_DEVICEW, DeviceKey) + sizeof(lpDisplayDevice->DeviceKey))
lpDisplayDevice->DeviceKey[0] = 0;
return TRUE;
}
struct monitor_enum_info
{
RECT rect;
UINT max_area;
UINT min_distance;
HMONITOR primary;
HMONITOR nearest;
HMONITOR ret;
};
/* helper callback for MonitorFromRect */
static BOOL CALLBACK monitor_enum( HMONITOR monitor, HDC hdc, LPRECT rect, LPARAM lp )
{
struct monitor_enum_info *info = (struct monitor_enum_info *)lp;
RECT intersect;
if (IntersectRect( &intersect, rect, &info->rect ))
{
/* check for larger intersecting area */
UINT area = (intersect.right - intersect.left) * (intersect.bottom - intersect.top);
if (area > info->max_area)
{
info->max_area = area;
info->ret = monitor;
}
}
else if (!info->max_area) /* if not intersecting, check for min distance */
{
UINT distance;
INT x, y;
if (rect->left >= info->rect.right) x = info->rect.right - rect->left;
else x = rect->right - info->rect.left;
if (rect->top >= info->rect.bottom) y = info->rect.bottom - rect->top;
else y = rect->bottom - info->rect.top;
distance = x * x + y * y;
if (distance < info->min_distance)
{
info->min_distance = distance;
info->nearest = monitor;
}
}
if (!info->primary)
{
MONITORINFO mon_info;
mon_info.cbSize = sizeof(mon_info);
GetMonitorInfoW( monitor, &mon_info );
if (mon_info.dwFlags & MONITORINFOF_PRIMARY) info->primary = monitor;
}
return TRUE;
}
/***********************************************************************
* MonitorFromRect (USER32.@)
*/
HMONITOR WINAPI MonitorFromRect( LPCRECT rect, DWORD flags )
{
struct monitor_enum_info info;
/* make sure the desktop window exists */
GetDesktopWindow();
info.rect = *rect;
info.max_area = 0;
info.min_distance = ~0u;
info.primary = 0;
info.nearest = 0;
info.ret = 0;
if (!EnumDisplayMonitors( 0, NULL, monitor_enum, (LPARAM)&info )) return 0;
if (!info.ret)
{
if (flags & MONITOR_DEFAULTTOPRIMARY) info.ret = info.primary;
else if (flags & MONITOR_DEFAULTTONEAREST) info.ret = info.nearest;
}
TRACE( "%s flags %x returning %p\n", wine_dbgstr_rect(rect), flags, info.ret );
return info.ret;
}
/***********************************************************************
* MonitorFromPoint (USER32.@)
*/
HMONITOR WINAPI MonitorFromPoint( POINT pt, DWORD flags )
{
RECT rect;
SetRect( &rect, pt.x, pt.y, pt.x + 1, pt.y + 1 );
return MonitorFromRect( &rect, flags );
}
/***********************************************************************
* MonitorFromWindow (USER32.@)
*/
HMONITOR WINAPI MonitorFromWindow(HWND hWnd, DWORD dwFlags)
{
RECT rect;
WINDOWPLACEMENT wp;
TRACE("(%p, 0x%08x)\n", hWnd, dwFlags);
if (IsIconic(hWnd) && GetWindowPlacement(hWnd, &wp))
return MonitorFromRect( &wp.rcNormalPosition, dwFlags );
if (GetWindowRect( hWnd, &rect ))
return MonitorFromRect( &rect, dwFlags );
if (!(dwFlags & (MONITOR_DEFAULTTOPRIMARY|MONITOR_DEFAULTTONEAREST))) return 0;
/* retrieve the primary */
SetRect( &rect, 0, 0, 1, 1 );
return MonitorFromRect( &rect, dwFlags );
}
/***********************************************************************
* GetMonitorInfoA (USER32.@)
*/
BOOL WINAPI GetMonitorInfoA(HMONITOR hMonitor, LPMONITORINFO lpMonitorInfo)
{
MONITORINFOEXW miW;
MONITORINFOEXA *miA = (MONITORINFOEXA*)lpMonitorInfo;
BOOL ret;
miW.cbSize = sizeof(miW);
ret = GetMonitorInfoW(hMonitor, (MONITORINFO*)&miW);
if(!ret) return ret;
miA->rcMonitor = miW.rcMonitor;
miA->rcWork = miW.rcWork;
miA->dwFlags = miW.dwFlags;
if(miA->cbSize >= offsetof(MONITORINFOEXA, szDevice) + sizeof(miA->szDevice))
WideCharToMultiByte(CP_ACP, 0, miW.szDevice, -1, miA->szDevice, sizeof(miA->szDevice), NULL, NULL);
return ret;
}
/***********************************************************************
* GetMonitorInfoW (USER32.@)
*/
BOOL WINAPI GetMonitorInfoW(HMONITOR hMonitor, LPMONITORINFO lpMonitorInfo)
{
BOOL ret = USER_Driver->pGetMonitorInfo( hMonitor, lpMonitorInfo );
if (ret)
TRACE("flags %04x, monitor %s, work %s\n", lpMonitorInfo->dwFlags,
wine_dbgstr_rect(&lpMonitorInfo->rcMonitor),
wine_dbgstr_rect(&lpMonitorInfo->rcWork));
return ret;
}
/***********************************************************************
* EnumDisplayMonitors (USER32.@)
*/
BOOL WINAPI EnumDisplayMonitors( HDC hdc, LPCRECT rect, MONITORENUMPROC proc, LPARAM lp )
{
return USER_Driver->pEnumDisplayMonitors( hdc, (LPRECT)rect, proc, lp );
}
/***********************************************************************
* RegisterSystemThread (USER32.@)
*/
void WINAPI RegisterSystemThread(DWORD flags, DWORD reserved)
{
FIXME("(%08x, %08x)\n", flags, reserved);
}
/***********************************************************************
* RegisterTasklist [USER32.@]
*/
DWORD WINAPI RegisterTasklist (DWORD x)
{
FIXME("0x%08x\n",x);
return TRUE;
}
/***********************************************************************
* RegisterDeviceNotificationA (USER32.@)
*
* See RegisterDeviceNotificationW.
*/
HDEVNOTIFY WINAPI RegisterDeviceNotificationA(HANDLE hnd, LPVOID notifyfilter, DWORD flags)
{
FIXME("(hwnd=%p, filter=%p,flags=0x%08x) returns a fake device notification handle!\n",
hnd,notifyfilter,flags );
return (HDEVNOTIFY) 0xcafecafe;
}
/***********************************************************************
* RegisterDeviceNotificationW (USER32.@)
*
* Registers a window with the system so that it will receive
* notifications about a device.
*
* PARAMS
* hRecepient [I] Window or service status handle that
* will receive notifications.
* pNotificationFilter [I] DEV_BROADCAST_HDR followed by some
* type-specific data.
* dwFlags [I] See notes
*
* RETURNS
*
* A handle to the device notification.
*
* NOTES
*
* The dwFlags parameter can be one of two values:
*| DEVICE_NOTIFY_WINDOW_HANDLE - hRecepient is a window handle
*| DEVICE_NOTIFY_SERVICE_HANDLE - hRecepient is a service status handle
*/
HDEVNOTIFY WINAPI RegisterDeviceNotificationW(HANDLE hRecepient, LPVOID pNotificationFilter, DWORD dwFlags)
{
FIXME("(hwnd=%p, filter=%p,flags=0x%08x) returns a fake device notification handle!\n",
hRecepient,pNotificationFilter,dwFlags );
return (HDEVNOTIFY) 0xcafeaffe;
}
/***********************************************************************
* UnregisterDeviceNotification (USER32.@)
*
*/
BOOL WINAPI UnregisterDeviceNotification(HDEVNOTIFY hnd)
{
FIXME("(handle=%p), STUB!\n", hnd);
return TRUE;
}
/***********************************************************************
* GetAppCompatFlags (USER32.@)
*/
DWORD WINAPI GetAppCompatFlags( HTASK hTask )
{
FIXME("(%p) stub\n", hTask);
return 0;
}
/***********************************************************************
* GetAppCompatFlags2 (USER32.@)
*/
DWORD WINAPI GetAppCompatFlags2( HTASK hTask )
{
FIXME("(%p) stub\n", hTask);
return 0;
}
/***********************************************************************
* AlignRects (USER32.@)
*/
BOOL WINAPI AlignRects(LPRECT rect, DWORD b, DWORD c, DWORD d)
{
FIXME("(%p, %d, %d, %d): stub\n", rect, b, c, d);
if (rect)
FIXME("rect: [[%d, %d], [%d, %d]]\n", rect->left, rect->top, rect->right, rect->bottom);
/* Calls OffsetRect */
return FALSE;
}
/***********************************************************************
* LoadLocalFonts (USER32.@)
*/
VOID WINAPI LoadLocalFonts(VOID)
{
/* are loaded. */
return;
}
/***********************************************************************
* User32InitializeImmEntryTable
*/
BOOL WINAPI User32InitializeImmEntryTable(LPVOID ptr)
{
FIXME("(%p): stub\n", ptr);
return TRUE;
}
/**********************************************************************
* WINNLSGetIMEHotkey [USER32.@]
*
*/
UINT WINAPI WINNLSGetIMEHotkey(HWND hUnknown1)
{
FIXME("hUnknown1 %p: stub!\n", hUnknown1);
return 0; /* unknown */
}
/**********************************************************************
* WINNLSEnableIME [USER32.@]
*
*/
BOOL WINAPI WINNLSEnableIME(HWND hUnknown1, BOOL bUnknown2)
{
FIXME("hUnknown1 %p bUnknown2 %d: stub!\n", hUnknown1, bUnknown2);
return TRUE; /* success (?) */
}
/**********************************************************************
* WINNLSGetEnableStatus [USER32.@]
*
*/
BOOL WINAPI WINNLSGetEnableStatus(HWND hUnknown1)
{
FIXME("hUnknown1 %p: stub!\n", hUnknown1);
return TRUE; /* success (?) */
}
/**********************************************************************
* SendIMEMessageExA [USER32.@]
*
*/
LRESULT WINAPI SendIMEMessageExA(HWND p1, LPARAM p2)
{
FIXME("(%p,%lx): stub\n", p1, p2);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
}
/**********************************************************************
* SendIMEMessageExW [USER32.@]
*
*/
LRESULT WINAPI SendIMEMessageExW(HWND p1, LPARAM p2)
{
FIXME("(%p,%lx): stub\n", p1, p2);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
}
/**********************************************************************
* DisableProcessWindowsGhosting [USER32.@]
*
*/
VOID WINAPI DisableProcessWindowsGhosting(VOID)
{
FIXME(": stub\n");
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return;
}

View File

@@ -0,0 +1,541 @@
/*
* Message boxes
*
* Copyright 1995 Bernd Schmidt
* Copyright 2004 Ivan Leo Puoti, Juan Lang
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <stdarg.h>
#include <string.h>
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "wine/winternl.h"
#include "dlgs.h"
#include "user_private.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(dialog);
WINE_DECLARE_DEBUG_CHANNEL(msgbox);
#define MSGBOX_IDICON 1088
#define MSGBOX_IDTEXT 100
#define IDS_ERROR 2
struct ThreadWindows
{
UINT numHandles;
UINT numAllocs;
HWND *handles;
};
static BOOL CALLBACK MSGBOX_EnumProc(HWND hwnd, LPARAM lParam)
{
struct ThreadWindows *threadWindows = (struct ThreadWindows *)lParam;
if (!EnableWindow(hwnd, FALSE))
{
if(threadWindows->numHandles >= threadWindows->numAllocs)
{
threadWindows->handles = HeapReAlloc(GetProcessHeap(), 0, threadWindows->handles,
(threadWindows->numAllocs*2)*sizeof(HWND));
threadWindows->numAllocs *= 2;
}
threadWindows->handles[threadWindows->numHandles++]=hwnd;
}
return TRUE;
}
static HFONT MSGBOX_OnInit(HWND hwnd, LPMSGBOXPARAMSW lpmb)
{
HFONT hFont = 0, hPrevFont = 0;
RECT rect;
HWND hItem;
HDC hdc;
int i, buttons;
int bspace, bw, bh, theight, tleft, wwidth, wheight, wleft, wtop, bpos;
int borheight, borwidth, iheight, ileft, iwidth, twidth, tiheight;
NONCLIENTMETRICSW nclm;
HMONITOR monitor = 0;
MONITORINFO mon_info;
LPCWSTR lpszText;
WCHAR *buffer = NULL;
const WCHAR *ptr;
/* Index the order the buttons need to appear to an ID* constant */
static const int buttonOrder[10] = { 6, 7, 1, 3, 4, 2, 5, 10, 11, 9 };
nclm.cbSize = sizeof(nclm);
SystemParametersInfoW (SPI_GETNONCLIENTMETRICS, 0, &nclm, 0);
hFont = CreateFontIndirectW (&nclm.lfMessageFont);
/* set button font */
for (i=1; i < 12; i++)
/* No button 8 (Close) */
if (i != 8) {
SendDlgItemMessageW (hwnd, i, WM_SETFONT, (WPARAM)hFont, 0);
}
/* set text font */
SendDlgItemMessageW (hwnd, MSGBOX_IDTEXT, WM_SETFONT, (WPARAM)hFont, 0);
if (!IS_INTRESOURCE(lpmb->lpszCaption)) {
SetWindowTextW(hwnd, lpmb->lpszCaption);
} else {
UINT len = LoadStringW( lpmb->hInstance, LOWORD(lpmb->lpszCaption), (LPWSTR)&ptr, 0 );
if (!len) len = LoadStringW( user32_module, IDS_ERROR, (LPWSTR)&ptr, 0 );
buffer = HeapAlloc( GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR) );
if (buffer)
{
memcpy( buffer, ptr, len * sizeof(WCHAR) );
buffer[len] = 0;
SetWindowTextW( hwnd, buffer );
HeapFree( GetProcessHeap(), 0, buffer );
buffer = NULL;
}
}
if (IS_INTRESOURCE(lpmb->lpszText)) {
UINT len = LoadStringW( lpmb->hInstance, LOWORD(lpmb->lpszText), (LPWSTR)&ptr, 0 );
lpszText = buffer = HeapAlloc( GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR) );
if (buffer)
{
memcpy( buffer, ptr, len * sizeof(WCHAR) );
buffer[len] = 0;
}
} else {
lpszText = lpmb->lpszText;
}
TRACE_(msgbox)("%s\n", debugstr_w(lpszText));
SetWindowTextW(GetDlgItem(hwnd, MSGBOX_IDTEXT), lpszText);
/* Remove not selected buttons */
switch(lpmb->dwStyle & MB_TYPEMASK) {
case MB_OK:
DestroyWindow(GetDlgItem(hwnd, IDCANCEL));
/* fall through */
case MB_OKCANCEL:
DestroyWindow(GetDlgItem(hwnd, IDABORT));
DestroyWindow(GetDlgItem(hwnd, IDRETRY));
DestroyWindow(GetDlgItem(hwnd, IDIGNORE));
DestroyWindow(GetDlgItem(hwnd, IDYES));
DestroyWindow(GetDlgItem(hwnd, IDNO));
DestroyWindow(GetDlgItem(hwnd, IDTRYAGAIN));
DestroyWindow(GetDlgItem(hwnd, IDCONTINUE));
break;
case MB_ABORTRETRYIGNORE:
DestroyWindow(GetDlgItem(hwnd, IDOK));
DestroyWindow(GetDlgItem(hwnd, IDCANCEL));
DestroyWindow(GetDlgItem(hwnd, IDYES));
DestroyWindow(GetDlgItem(hwnd, IDNO));
DestroyWindow(GetDlgItem(hwnd, IDCONTINUE));
DestroyWindow(GetDlgItem(hwnd, IDTRYAGAIN));
break;
case MB_YESNO:
DestroyWindow(GetDlgItem(hwnd, IDCANCEL));
/* fall through */
case MB_YESNOCANCEL:
DestroyWindow(GetDlgItem(hwnd, IDOK));
DestroyWindow(GetDlgItem(hwnd, IDABORT));
DestroyWindow(GetDlgItem(hwnd, IDRETRY));
DestroyWindow(GetDlgItem(hwnd, IDIGNORE));
DestroyWindow(GetDlgItem(hwnd, IDCONTINUE));
DestroyWindow(GetDlgItem(hwnd, IDTRYAGAIN));
break;
case MB_RETRYCANCEL:
DestroyWindow(GetDlgItem(hwnd, IDOK));
DestroyWindow(GetDlgItem(hwnd, IDABORT));
DestroyWindow(GetDlgItem(hwnd, IDIGNORE));
DestroyWindow(GetDlgItem(hwnd, IDYES));
DestroyWindow(GetDlgItem(hwnd, IDNO));
DestroyWindow(GetDlgItem(hwnd, IDCONTINUE));
DestroyWindow(GetDlgItem(hwnd, IDTRYAGAIN));
break;
case MB_CANCELTRYCONTINUE:
DestroyWindow(GetDlgItem(hwnd, IDOK));
DestroyWindow(GetDlgItem(hwnd, IDABORT));
DestroyWindow(GetDlgItem(hwnd, IDIGNORE));
DestroyWindow(GetDlgItem(hwnd, IDYES));
DestroyWindow(GetDlgItem(hwnd, IDNO));
DestroyWindow(GetDlgItem(hwnd, IDRETRY));
}
/* Set the icon */
switch(lpmb->dwStyle & MB_ICONMASK) {
case MB_ICONEXCLAMATION:
SendDlgItemMessageW(hwnd, stc1, STM_SETICON,
(WPARAM)LoadIconW(0, (LPWSTR)IDI_EXCLAMATION), 0);
break;
case MB_ICONQUESTION:
SendDlgItemMessageW(hwnd, stc1, STM_SETICON,
(WPARAM)LoadIconW(0, (LPWSTR)IDI_QUESTION), 0);
break;
case MB_ICONASTERISK:
SendDlgItemMessageW(hwnd, stc1, STM_SETICON,
(WPARAM)LoadIconW(0, (LPWSTR)IDI_ASTERISK), 0);
break;
case MB_ICONHAND:
SendDlgItemMessageW(hwnd, stc1, STM_SETICON,
(WPARAM)LoadIconW(0, (LPWSTR)IDI_HAND), 0);
break;
case MB_USERICON:
SendDlgItemMessageW(hwnd, stc1, STM_SETICON,
(WPARAM)LoadIconW(lpmb->hInstance, lpmb->lpszIcon), 0);
break;
default:
/* By default, Windows 95/98/NT do not associate an icon to message boxes.
* So wine should do the same.
*/
break;
}
/* Remove Help button unless MB_HELP supplied */
if (!(lpmb->dwStyle & MB_HELP)) {
DestroyWindow(GetDlgItem(hwnd, IDHELP));
}
/* Position everything */
GetWindowRect(hwnd, &rect);
borheight = rect.bottom - rect.top;
borwidth = rect.right - rect.left;
GetClientRect(hwnd, &rect);
borheight -= rect.bottom - rect.top;
borwidth -= rect.right - rect.left;
/* Get the icon height */
GetWindowRect(GetDlgItem(hwnd, MSGBOX_IDICON), &rect);
MapWindowPoints(0, hwnd, (LPPOINT)&rect, 2);
if (!(lpmb->dwStyle & MB_ICONMASK))
{
rect.bottom = rect.top;
rect.right = rect.left;
}
iheight = rect.bottom - rect.top;
ileft = rect.left;
iwidth = rect.right - ileft;
hdc = GetDC(hwnd);
if (hFont)
hPrevFont = SelectObject(hdc, hFont);
/* Get the number of visible buttons and their size */
bh = bw = 1; /* Minimum button sizes */
for (buttons = 0, i = 1; i < 12; i++)
{
if (i == 8) continue; /* No CLOSE button */
hItem = GetDlgItem(hwnd, i);
if (GetWindowLongW(hItem, GWL_STYLE) & WS_VISIBLE)
{
WCHAR buttonText[1024];
int w, h;
buttons++;
if (GetWindowTextW(hItem, buttonText, 1024))
{
DrawTextW( hdc, buttonText, -1, &rect, DT_LEFT | DT_EXPANDTABS | DT_CALCRECT);
h = rect.bottom - rect.top;
w = rect.right - rect.left;
if (h > bh) bh = h;
if (w > bw) bw = w ;
}
}
}
bw = max(bw, bh * 2);
/* Button white space */
bh = bh * 2;
bw = bw * 2;
bspace = bw/3; /* Space between buttons */
/* Get the text size */
GetClientRect(GetDlgItem(hwnd, MSGBOX_IDTEXT), &rect);
rect.top = rect.left = rect.bottom = 0;
DrawTextW( hdc, lpszText, -1, &rect,
DT_LEFT | DT_EXPANDTABS | DT_WORDBREAK | DT_CALCRECT);
/* Min text width corresponds to space for the buttons */
tleft = ileft;
if (iwidth) tleft += ileft + iwidth;
twidth = max((bw + bspace) * buttons + bspace - tleft, rect.right);
theight = rect.bottom;
if (hFont)
SelectObject(hdc, hPrevFont);
ReleaseDC(hwnd, hdc);
tiheight = 16 + max(iheight, theight);
wwidth = tleft + twidth + ileft + borwidth;
wheight = 8 + tiheight + bh + borheight;
/* Message boxes are always desktop centered, so query desktop size and center window */
monitor = MonitorFromWindow(lpmb->hwndOwner ? lpmb->hwndOwner : GetActiveWindow(), MONITOR_DEFAULTTOPRIMARY);
mon_info.cbSize = sizeof(mon_info);
GetMonitorInfoW(monitor, &mon_info);
wleft = (mon_info.rcWork.left + mon_info.rcWork.right - wwidth) / 2;
wtop = (mon_info.rcWork.top + mon_info.rcWork.bottom - wheight) / 2;
/* Resize and center the window */
SetWindowPos(hwnd, 0, wleft, wtop, wwidth, wheight,
SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOREDRAW);
/* Position the icon */
SetWindowPos(GetDlgItem(hwnd, MSGBOX_IDICON), 0, ileft, (tiheight - iheight) / 2, 0, 0,
SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOREDRAW);
/* Position the text */
SetWindowPos(GetDlgItem(hwnd, MSGBOX_IDTEXT), 0, tleft, (tiheight - theight) / 2, twidth, theight,
SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOREDRAW);
/* Position the buttons */
bpos = (wwidth - (bw + bspace) * buttons + bspace) / 2;
for (buttons = i = 0; i < (sizeof(buttonOrder) / sizeof(buttonOrder[0])); i++) {
/* Convert the button order to ID* value to order for the buttons */
hItem = GetDlgItem(hwnd, buttonOrder[i]);
if (GetWindowLongW(hItem, GWL_STYLE) & WS_VISIBLE) {
if (buttons++ == ((lpmb->dwStyle & MB_DEFMASK) >> 8)) {
SetFocus(hItem);
SendMessageW( hItem, BM_SETSTYLE, BS_DEFPUSHBUTTON, TRUE );
}
SetWindowPos(hItem, 0, bpos, tiheight, bw, bh,
SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOREDRAW);
bpos += bw + bspace;
}
}
/*handle modal message boxes*/
if (((lpmb->dwStyle & MB_TASKMODAL) && (lpmb->hwndOwner==NULL)) || (lpmb->dwStyle & MB_SYSTEMMODAL))
SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
HeapFree( GetProcessHeap(), 0, buffer );
return hFont;
}
/**************************************************************************
* MSGBOX_DlgProc
*
* Dialog procedure for message boxes.
*/
static INT_PTR CALLBACK MSGBOX_DlgProc( HWND hwnd, UINT message,
WPARAM wParam, LPARAM lParam )
{
HFONT hFont;
switch(message) {
case WM_INITDIALOG:
{
LPMSGBOXPARAMSW mbp = (LPMSGBOXPARAMSW)lParam;
SetWindowContextHelpId(hwnd, mbp->dwContextHelpId);
hFont = MSGBOX_OnInit(hwnd, mbp);
SetPropA(hwnd, "WINE_MSGBOX_HFONT", hFont);
SetPropA(hwnd, "WINE_MSGBOX_HELPCALLBACK", mbp->lpfnMsgBoxCallback);
break;
}
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDOK:
case IDCANCEL:
case IDABORT:
case IDRETRY:
case IDIGNORE:
case IDYES:
case IDNO:
case IDTRYAGAIN:
case IDCONTINUE:
hFont = GetPropA(hwnd, "WINE_MSGBOX_HFONT");
EndDialog(hwnd, wParam);
if (hFont)
DeleteObject(hFont);
break;
case IDHELP:
FIXME("Help button not supported yet\n");
break;
}
break;
case WM_HELP:
{
MSGBOXCALLBACK callback = (MSGBOXCALLBACK)GetPropA(hwnd, "WINE_MSGBOX_HELPCALLBACK");
HELPINFO hi;
memcpy(&hi, (void *)lParam, sizeof(hi));
hi.dwContextId = GetWindowContextHelpId(hwnd);
if (callback)
callback(&hi);
else
SendMessageW(GetWindow(hwnd, GW_OWNER), WM_HELP, 0, (LPARAM)&hi);
break;
}
default:
/* Ok. Ignore all the other messages */
TRACE("Message number 0x%04x is being ignored.\n", message);
break;
}
return 0;
}
/**************************************************************************
* MessageBoxA (USER32.@)
*/
INT WINAPI MessageBoxA(HWND hWnd, LPCSTR text, LPCSTR title, UINT type)
{
return MessageBoxExA(hWnd, text, title, type, LANG_NEUTRAL);
}
/**************************************************************************
* MessageBoxW (USER32.@)
*/
INT WINAPI MessageBoxW( HWND hwnd, LPCWSTR text, LPCWSTR title, UINT type )
{
return MessageBoxExW(hwnd, text, title, type, LANG_NEUTRAL);
}
/**************************************************************************
* MessageBoxExA (USER32.@)
*/
INT WINAPI MessageBoxExA( HWND hWnd, LPCSTR text, LPCSTR title,
UINT type, WORD langid )
{
MSGBOXPARAMSA msgbox;
msgbox.cbSize = sizeof(msgbox);
msgbox.hwndOwner = hWnd;
msgbox.hInstance = 0;
msgbox.lpszText = text;
msgbox.lpszCaption = title;
msgbox.dwStyle = type;
msgbox.lpszIcon = NULL;
msgbox.dwContextHelpId = 0;
msgbox.lpfnMsgBoxCallback = NULL;
msgbox.dwLanguageId = langid;
return MessageBoxIndirectA(&msgbox);
}
/**************************************************************************
* MessageBoxExW (USER32.@)
*/
INT WINAPI MessageBoxExW( HWND hWnd, LPCWSTR text, LPCWSTR title,
UINT type, WORD langid )
{
MSGBOXPARAMSW msgbox;
msgbox.cbSize = sizeof(msgbox);
msgbox.hwndOwner = hWnd;
msgbox.hInstance = 0;
msgbox.lpszText = text;
msgbox.lpszCaption = title;
msgbox.dwStyle = type;
msgbox.lpszIcon = NULL;
msgbox.dwContextHelpId = 0;
msgbox.lpfnMsgBoxCallback = NULL;
msgbox.dwLanguageId = langid;
return MessageBoxIndirectW(&msgbox);
}
/**************************************************************************
* MessageBoxIndirectA (USER32.@)
*/
INT WINAPI MessageBoxIndirectA( CONST MSGBOXPARAMSA *msgbox )
{
MSGBOXPARAMSW msgboxW;
UNICODE_STRING textW, captionW, iconW;
int ret;
if (IS_INTRESOURCE(msgbox->lpszText))
textW.Buffer = (LPWSTR)msgbox->lpszText;
else
RtlCreateUnicodeStringFromAsciiz(&textW, msgbox->lpszText);
if (IS_INTRESOURCE(msgbox->lpszCaption))
captionW.Buffer = (LPWSTR)msgbox->lpszCaption;
else
RtlCreateUnicodeStringFromAsciiz(&captionW, msgbox->lpszCaption);
if (msgbox->dwStyle & MB_USERICON)
{
if (IS_INTRESOURCE(msgbox->lpszIcon))
iconW.Buffer = (LPWSTR)msgbox->lpszIcon;
else
RtlCreateUnicodeStringFromAsciiz(&iconW, msgbox->lpszIcon);
}
else
iconW.Buffer = NULL;
msgboxW.cbSize = sizeof(msgboxW);
msgboxW.hwndOwner = msgbox->hwndOwner;
msgboxW.hInstance = msgbox->hInstance;
msgboxW.lpszText = textW.Buffer;
msgboxW.lpszCaption = captionW.Buffer;
msgboxW.dwStyle = msgbox->dwStyle;
msgboxW.lpszIcon = iconW.Buffer;
msgboxW.dwContextHelpId = msgbox->dwContextHelpId;
msgboxW.lpfnMsgBoxCallback = msgbox->lpfnMsgBoxCallback;
msgboxW.dwLanguageId = msgbox->dwLanguageId;
ret = MessageBoxIndirectW(&msgboxW);
if (!IS_INTRESOURCE(textW.Buffer)) RtlFreeUnicodeString(&textW);
if (!IS_INTRESOURCE(captionW.Buffer)) RtlFreeUnicodeString(&captionW);
if (!IS_INTRESOURCE(iconW.Buffer)) RtlFreeUnicodeString(&iconW);
return ret;
}
/**************************************************************************
* MessageBoxIndirectW (USER32.@)
*/
INT WINAPI MessageBoxIndirectW( CONST MSGBOXPARAMSW *msgbox )
{
LPVOID tmplate;
HRSRC hRes;
int ret;
UINT i;
struct ThreadWindows threadWindows;
static const WCHAR msg_box_res_nameW[] = { 'M','S','G','B','O','X',0 };
if (!(hRes = FindResourceExW(user32_module, (LPWSTR)RT_DIALOG,
msg_box_res_nameW, msgbox->dwLanguageId)))
{
if (!msgbox->dwLanguageId ||
!(hRes = FindResourceExW(user32_module, (LPWSTR)RT_DIALOG, msg_box_res_nameW, LANG_NEUTRAL)))
return 0;
}
if (!(tmplate = LoadResource(user32_module, hRes)))
return 0;
if ((msgbox->dwStyle & MB_TASKMODAL) && (msgbox->hwndOwner==NULL))
{
threadWindows.numHandles = 0;
threadWindows.numAllocs = 10;
threadWindows.handles = HeapAlloc(GetProcessHeap(), 0, 10*sizeof(HWND));
EnumThreadWindows(GetCurrentThreadId(), MSGBOX_EnumProc, (LPARAM)&threadWindows);
}
ret=DialogBoxIndirectParamW(msgbox->hInstance, tmplate,
msgbox->hwndOwner, MSGBOX_DlgProc, (LPARAM)msgbox);
if ((msgbox->dwStyle & MB_TASKMODAL) && (msgbox->hwndOwner==NULL))
{
for (i = 0; i < threadWindows.numHandles; i++)
EnableWindow(threadWindows.handles[i], TRUE);
HeapFree(GetProcessHeap(), 0, threadWindows.handles);
}
return ret;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,255 @@
/*
* Window properties
*
* Copyright 1995, 1996, 2001 Alexandre Julliard
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "config.h"
#include "wine/port.h"
#include <stdarg.h>
#include <string.h>
#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "wine/unicode.h"
#include "wine/winternl.h"
#include "user_private.h"
#include "wine/server.h"
/* size of buffer needed to store an atom string */
#define ATOM_BUFFER_SIZE 256
/***********************************************************************
* get_properties
*
* Retrieve the list of properties of a given window.
* Returned buffer must be freed by caller.
*/
static property_data_t *get_properties( HWND hwnd, int *count )
{
property_data_t *data;
int total = 32;
while (total)
{
int res = 0;
if (!(data = HeapAlloc( GetProcessHeap(), 0, total * sizeof(*data) ))) break;
*count = 0;
SERVER_START_REQ( get_window_properties )
{
req->window = wine_server_user_handle( hwnd );
wine_server_set_reply( req, data, total * sizeof(*data) );
if (!wine_server_call( req )) res = reply->total;
}
SERVER_END_REQ;
if (res && res <= total)
{
*count = res;
return data;
}
HeapFree( GetProcessHeap(), 0, data );
total = res; /* restart with larger buffer */
}
return NULL;
}
/***********************************************************************
* EnumPropsA_relay
*
* relay to call the EnumProps callback function from EnumPropsEx
*/
static BOOL CALLBACK EnumPropsA_relay( HWND hwnd, LPSTR str, HANDLE handle, ULONG_PTR lparam )
{
PROPENUMPROCA func = (PROPENUMPROCA)lparam;
return func( hwnd, str, handle );
}
/***********************************************************************
* EnumPropsW_relay
*
* relay to call the EnumProps callback function from EnumPropsEx
*/
static BOOL CALLBACK EnumPropsW_relay( HWND hwnd, LPWSTR str, HANDLE handle, ULONG_PTR lparam )
{
PROPENUMPROCW func = (PROPENUMPROCW)lparam;
return func( hwnd, str, handle );
}
/***********************************************************************
* EnumPropsA (USER32.@)
*/
INT WINAPI EnumPropsA( HWND hwnd, PROPENUMPROCA func )
{
return EnumPropsExA( hwnd, EnumPropsA_relay, (LPARAM)func );
}
/***********************************************************************
* EnumPropsW (USER32.@)
*/
INT WINAPI EnumPropsW( HWND hwnd, PROPENUMPROCW func )
{
return EnumPropsExW( hwnd, EnumPropsW_relay, (LPARAM)func );
}
/***********************************************************************
* GetPropA (USER32.@)
*/
HANDLE WINAPI GetPropA( HWND hwnd, LPCSTR str )
{
WCHAR buffer[ATOM_BUFFER_SIZE];
if (IS_INTRESOURCE(str)) return GetPropW( hwnd, (LPCWSTR)str );
if (!MultiByteToWideChar( CP_ACP, 0, str, -1, buffer, ATOM_BUFFER_SIZE )) return 0;
return GetPropW( hwnd, buffer );
}
/***********************************************************************
* GetPropW (USER32.@)
*/
HANDLE WINAPI GetPropW( HWND hwnd, LPCWSTR str )
{
ULONG_PTR ret = 0;
SERVER_START_REQ( get_window_property )
{
req->window = wine_server_user_handle( hwnd );
if (IS_INTRESOURCE(str)) req->atom = LOWORD(str);
else wine_server_add_data( req, str, strlenW(str) * sizeof(WCHAR) );
if (!wine_server_call_err( req )) ret = reply->data;
}
SERVER_END_REQ;
return (HANDLE)ret;
}
/***********************************************************************
* SetPropA (USER32.@)
*/
BOOL WINAPI SetPropA( HWND hwnd, LPCSTR str, HANDLE handle )
{
WCHAR buffer[ATOM_BUFFER_SIZE];
if (IS_INTRESOURCE(str)) return SetPropW( hwnd, (LPCWSTR)str, handle );
if (!MultiByteToWideChar( CP_ACP, 0, str, -1, buffer, ATOM_BUFFER_SIZE )) return FALSE;
return SetPropW( hwnd, buffer, handle );
}
/***********************************************************************
* SetPropW (USER32.@)
*/
BOOL WINAPI SetPropW( HWND hwnd, LPCWSTR str, HANDLE handle )
{
BOOL ret;
SERVER_START_REQ( set_window_property )
{
req->window = wine_server_user_handle( hwnd );
req->data = (ULONG_PTR)handle;
if (IS_INTRESOURCE(str)) req->atom = LOWORD(str);
else wine_server_add_data( req, str, strlenW(str) * sizeof(WCHAR) );
ret = !wine_server_call_err( req );
}
SERVER_END_REQ;
return ret;
}
/***********************************************************************
* RemovePropA (USER32.@)
*/
HANDLE WINAPI RemovePropA( HWND hwnd, LPCSTR str )
{
WCHAR buffer[ATOM_BUFFER_SIZE];
if (IS_INTRESOURCE(str)) return RemovePropW( hwnd, (LPCWSTR)str );
if (!MultiByteToWideChar( CP_ACP, 0, str, -1, buffer, ATOM_BUFFER_SIZE )) return 0;
return RemovePropW( hwnd, buffer );
}
/***********************************************************************
* RemovePropW (USER32.@)
*/
HANDLE WINAPI RemovePropW( HWND hwnd, LPCWSTR str )
{
ULONG_PTR ret = 0;
SERVER_START_REQ( remove_window_property )
{
req->window = wine_server_user_handle( hwnd );
if (IS_INTRESOURCE(str)) req->atom = LOWORD(str);
else wine_server_add_data( req, str, strlenW(str) * sizeof(WCHAR) );
if (!wine_server_call_err( req )) ret = reply->data;
}
SERVER_END_REQ;
return (HANDLE)ret;
}
/***********************************************************************
* EnumPropsExA (USER32.@)
*/
INT WINAPI EnumPropsExA(HWND hwnd, PROPENUMPROCEXA func, LPARAM lParam)
{
int ret = -1, i, count;
property_data_t *list = get_properties( hwnd, &count );
if (list)
{
for (i = 0; i < count; i++)
{
char string[ATOM_BUFFER_SIZE];
if (!UserGetAtomNameA( list[i].atom, string, ATOM_BUFFER_SIZE )) continue;
if (!(ret = func( hwnd, string, (HANDLE)(ULONG_PTR)list[i].data, lParam ))) break;
}
HeapFree( GetProcessHeap(), 0, list );
}
return ret;
}
/***********************************************************************
* EnumPropsExW (USER32.@)
*/
INT WINAPI EnumPropsExW(HWND hwnd, PROPENUMPROCEXW func, LPARAM lParam)
{
int ret = -1, i, count;
property_data_t *list = get_properties( hwnd, &count );
if (list)
{
for (i = 0; i < count; i++)
{
WCHAR string[ATOM_BUFFER_SIZE];
if (!UserGetAtomNameW( list[i].atom, string, ATOM_BUFFER_SIZE )) continue;
if (!(ret = func( hwnd, string, (HANDLE)(ULONG_PTR)list[i].data, lParam ))) break;
}
HeapFree( GetProcessHeap(), 0, list );
}
return ret;
}

View File

@@ -0,0 +1,334 @@
/*
* USER resource functions
*
* Copyright 1993 Robert J. Amstadt
* Copyright 1995, 2009 Alexandre Julliard
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <stdarg.h>
#include "windef.h"
#include "winbase.h"
#include "winerror.h"
#include "wine/winternl.h"
#include "winnls.h"
#include "wine/debug.h"
#include "user_private.h"
WINE_DEFAULT_DEBUG_CHANNEL(resource);
WINE_DECLARE_DEBUG_CHANNEL(accel);
/* this is the 8 byte accel struct used in Win32 resources (internal only) */
typedef struct
{
WORD fVirt;
WORD key;
WORD cmd;
WORD pad;
} PE_ACCEL;
/* the accelerator user object */
struct accelerator
{
struct user_object obj;
unsigned int count;
PE_ACCEL table[1];
};
/**********************************************************************
* LoadAcceleratorsW (USER32.@)
*/
HACCEL WINAPI LoadAcceleratorsW(HINSTANCE instance, LPCWSTR name)
{
struct accelerator *accel;
const PE_ACCEL *table;
HRSRC rsrc;
HACCEL handle;
DWORD count;
if (!(rsrc = FindResourceW( instance, name, (LPWSTR)RT_ACCELERATOR ))) return 0;
table = LoadResource( instance, rsrc );
count = SizeofResource( instance, rsrc ) / sizeof(*table);
if (!count) return 0;
accel = HeapAlloc( GetProcessHeap(), 0, FIELD_OFFSET( struct accelerator, table[count] ));
if (!accel) return 0;
accel->count = count;
memcpy( accel->table, table, count * sizeof(*table) );
if (!(handle = alloc_user_handle( &accel->obj, USER_ACCEL )))
HeapFree( GetProcessHeap(), 0, accel );
TRACE_(accel)("%p %s returning %p\n", instance, debugstr_w(name), handle );
return handle;
}
/***********************************************************************
* LoadAcceleratorsA (USER32.@)
*/
HACCEL WINAPI LoadAcceleratorsA(HINSTANCE instance,LPCSTR lpTableName)
{
INT len;
LPWSTR uni;
HACCEL result = 0;
if (IS_INTRESOURCE(lpTableName)) return LoadAcceleratorsW( instance, (LPCWSTR)lpTableName );
len = MultiByteToWideChar( CP_ACP, 0, lpTableName, -1, NULL, 0 );
if ((uni = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) )))
{
MultiByteToWideChar( CP_ACP, 0, lpTableName, -1, uni, len );
result = LoadAcceleratorsW(instance,uni);
HeapFree( GetProcessHeap(), 0, uni);
}
return result;
}
/**********************************************************************
* CopyAcceleratorTableA (USER32.@)
*/
INT WINAPI CopyAcceleratorTableA(HACCEL src, LPACCEL dst, INT count)
{
char ch;
int i, ret = CopyAcceleratorTableW( src, dst, count );
if (ret && dst)
{
for (i = 0; i < ret; i++)
{
if (dst[i].fVirt & FVIRTKEY) continue;
WideCharToMultiByte( CP_ACP, 0, &dst[i].key, 1, &ch, 1, NULL, NULL );
dst[i].key = ch;
}
}
return ret;
}
/**********************************************************************
* CopyAcceleratorTableW (USER32.@)
*/
INT WINAPI CopyAcceleratorTableW(HACCEL src, LPACCEL dst, INT count)
{
struct accelerator *accel;
int i;
if (!(accel = get_user_handle_ptr( src, USER_ACCEL ))) return 0;
if (accel == OBJ_OTHER_PROCESS)
{
FIXME( "other process handle %p?\n", src );
return 0;
}
if (dst)
{
if (count > accel->count) count = accel->count;
for (i = 0; i < count; i++)
{
dst[i].fVirt = accel->table[i].fVirt & 0x7f;
dst[i].key = accel->table[i].key;
dst[i].cmd = accel->table[i].cmd;
}
}
else count = accel->count;
release_user_handle_ptr( accel );
return count;
}
/*********************************************************************
* CreateAcceleratorTableA (USER32.@)
*/
HACCEL WINAPI CreateAcceleratorTableA(LPACCEL lpaccel, INT count)
{
struct accelerator *accel;
HACCEL handle;
int i;
if (count < 1)
{
SetLastError( ERROR_INVALID_PARAMETER );
return 0;
}
accel = HeapAlloc( GetProcessHeap(), 0, FIELD_OFFSET( struct accelerator, table[count] ));
if (!accel) return 0;
accel->count = count;
for (i = 0; i < count; i++)
{
accel->table[i].fVirt = lpaccel[i].fVirt;
accel->table[i].cmd = lpaccel[i].cmd;
if (!(lpaccel[i].fVirt & FVIRTKEY))
{
char ch = lpaccel[i].key;
MultiByteToWideChar( CP_ACP, 0, &ch, 1, &accel->table[i].key, 1 );
}
else accel->table[i].key = lpaccel[i].key;
}
if (!(handle = alloc_user_handle( &accel->obj, USER_ACCEL )))
HeapFree( GetProcessHeap(), 0, accel );
TRACE_(accel)("returning %p\n", handle );
return handle;
}
/*********************************************************************
* CreateAcceleratorTableW (USER32.@)
*/
HACCEL WINAPI CreateAcceleratorTableW(LPACCEL lpaccel, INT count)
{
struct accelerator *accel;
HACCEL handle;
int i;
if (count < 1)
{
SetLastError( ERROR_INVALID_PARAMETER );
return 0;
}
accel = HeapAlloc( GetProcessHeap(), 0, FIELD_OFFSET( struct accelerator, table[count] ));
if (!accel) return 0;
accel->count = count;
for (i = 0; i < count; i++)
{
accel->table[i].fVirt = lpaccel[i].fVirt;
accel->table[i].key = lpaccel[i].key;
accel->table[i].cmd = lpaccel[i].cmd;
}
if (!(handle = alloc_user_handle( &accel->obj, USER_ACCEL )))
HeapFree( GetProcessHeap(), 0, accel );
TRACE_(accel)("returning %p\n", handle );
return handle;
}
/******************************************************************************
* DestroyAcceleratorTable [USER32.@]
* Destroys an accelerator table
*
* PARAMS
* handle [I] Handle to accelerator table
*
* RETURNS
* Success: TRUE
* Failure: FALSE
*/
BOOL WINAPI DestroyAcceleratorTable( HACCEL handle )
{
struct accelerator *accel;
if (!(accel = free_user_handle( handle, USER_ACCEL ))) return FALSE;
if (accel == OBJ_OTHER_PROCESS)
{
FIXME( "other process handle %p?\n", accel );
return FALSE;
}
return HeapFree( GetProcessHeap(), 0, accel );
}
/**********************************************************************
* LoadStringW (USER32.@)
*/
INT WINAPI LoadStringW( HINSTANCE instance, UINT resource_id,
LPWSTR buffer, INT buflen )
{
HGLOBAL hmem;
HRSRC hrsrc;
WCHAR *p;
int string_num;
int i;
TRACE("instance = %p, id = %04x, buffer = %p, length = %d\n",
instance, resource_id, buffer, buflen);
if(buffer == NULL)
return 0;
/* Use loword (incremented by 1) as resourceid */
hrsrc = FindResourceW( instance, MAKEINTRESOURCEW((LOWORD(resource_id) >> 4) + 1),
(LPWSTR)RT_STRING );
if (!hrsrc) return 0;
hmem = LoadResource( instance, hrsrc );
if (!hmem) return 0;
p = LockResource(hmem);
string_num = resource_id & 0x000f;
for (i = 0; i < string_num; i++)
p += *p + 1;
TRACE("strlen = %d\n", (int)*p );
/*if buflen == 0, then return a read-only pointer to the resource itself in buffer
it is assumed that buffer is actually a (LPWSTR *) */
if(buflen == 0)
{
*((LPWSTR *)buffer) = p + 1;
return *p;
}
i = min(buflen - 1, *p);
if (i > 0) {
memcpy(buffer, p + 1, i * sizeof (WCHAR));
buffer[i] = 0;
} else {
if (buflen > 1) {
buffer[0] = 0;
return 0;
}
}
TRACE("%s loaded !\n", debugstr_w(buffer));
return i;
}
/**********************************************************************
* LoadStringA (USER32.@)
*/
INT WINAPI LoadStringA( HINSTANCE instance, UINT resource_id, LPSTR buffer, INT buflen )
{
HGLOBAL hmem;
HRSRC hrsrc;
DWORD retval = 0;
TRACE("instance = %p, id = %04x, buffer = %p, length = %d\n",
instance, resource_id, buffer, buflen);
if (!buflen) return -1;
/* Use loword (incremented by 1) as resourceid */
if ((hrsrc = FindResourceW( instance, MAKEINTRESOURCEW((LOWORD(resource_id) >> 4) + 1),
(LPWSTR)RT_STRING )) &&
(hmem = LoadResource( instance, hrsrc )))
{
const WCHAR *p = LockResource(hmem);
unsigned int id = resource_id & 0x000f;
while (id--) p += *p + 1;
RtlUnicodeToMultiByteN( buffer, buflen - 1, &retval, p + 1, *p * sizeof(WCHAR) );
}
buffer[retval] = 0;
TRACE("returning %s\n", debugstr_a(buffer));
return retval;
}
/**********************************************************************
* GetGuiResources (USER32.@)
*/
DWORD WINAPI GetGuiResources( HANDLE hProcess, DWORD uiFlags )
{
static BOOL warn = TRUE;
if (warn) {
FIXME("(%p,%x): stub\n",hProcess,uiFlags);
warn = FALSE;
}
SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
return 0;
}

View File

@@ -0,0 +1,28 @@
/*
* Copyright 1999 Bertho Stultiens
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#define OEMRESOURCE
#include <windef.h>
#include <winbase.h>
#include <winuser.h>
#include <winnls.h>
#include <dlgs.h>
#define MDI_IDC_LISTBOX 100
#define IDS_MDI_MOREWINDOWS 13
#define IDS_ERROR 2

View File

Before

Width:  |  Height:  |  Size: 118 B

After

Width:  |  Height:  |  Size: 118 B

View File

Before

Width:  |  Height:  |  Size: 122 B

After

Width:  |  Height:  |  Size: 122 B

View File

Before

Width:  |  Height:  |  Size: 118 B

After

Width:  |  Height:  |  Size: 118 B

View File

Before

Width:  |  Height:  |  Size: 374 B

After

Width:  |  Height:  |  Size: 374 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 478 B

View File

Before

Width:  |  Height:  |  Size: 98 B

After

Width:  |  Height:  |  Size: 98 B

View File

Before

Width:  |  Height:  |  Size: 322 B

After

Width:  |  Height:  |  Size: 322 B

View File

Before

Width:  |  Height:  |  Size: 322 B

After

Width:  |  Height:  |  Size: 322 B

View File

Before

Width:  |  Height:  |  Size: 322 B

After

Width:  |  Height:  |  Size: 322 B

View File

Before

Width:  |  Height:  |  Size: 322 B

After

Width:  |  Height:  |  Size: 322 B

View File

Before

Width:  |  Height:  |  Size: 322 B

After

Width:  |  Height:  |  Size: 322 B

View File

Before

Width:  |  Height:  |  Size: 322 B

After

Width:  |  Height:  |  Size: 322 B

Some files were not shown because too many files have changed in this diff Show More