diff --git a/ChangeLog b/ChangeLog index ebf46f14a76..151f65bfec9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,295 @@ +Sun Jan 2 12:38:53 1994 David Metcalfe + + * [windows/class.c] + Implemented GetClassName and GetClassInfo. + + * [windows/caret.c] + Various improvements to text caret code. + +Fri Dec 31 15:22:22 1993 John Brezak + + * [misc/comm.c] + Patches to work with NetBSD. + +Thu Dec 30 12:11:55 1993 John Richardson + + * [objects/bitblt.c] Added StretchBlt(). + +Tue Jan 4 05:22:07 1994 julliard@di.epfl.ch (Alexandre Julliard) + + * [misc/user.c] + Added creation of system message queue. + + * [objects/bitmap.c] [objects/dcvalues.c] [windows/dc.c] + Added DC size fields into DC structure. + + * [objects/clipping.c] + Bug fix in CLIPPING_IntersectRect(). + + * [windows/class.c] + Allocate a DCE instead of a DC for CS_CLASSDC classes. + + * [windows/clipping.c] + Fixed GetUpdateRect() and GetUpdateRgn() to clip to the client area. + + * [windows/dce.c] + Implemented GetDCEx() and GetWindowDC(). + + * [windows/defwnd.c] + Implemented WM_WINDOWPOSCHANGED handling. + + * [windows/event.c] + Preliminary support for Xlib event handling instead of Xt callbacks. + Changed MSG_AddMsg() calls to hardware_event() or PostMessage(). + + * [windows/message.c] + Preliminary support for multiple message queues. + Implemented hardware_event() to store messages into the system queue. + Implemented Get/SetTaskQueue(). + Better WM_PAINT and WM_TIMER handling. + Changes to use Xlib instead of Xt for events. + + * [windows/painting.c] + Use GetDCEx() to retrieve the DC, to get a correct visible region. + + * [windows/timer.c] + Moved the timer procedure callback into DispatchMessage(). + Changed implementation to get rid of Xt timeouts. Timer checking + is now done inside GetMessage(). + + * [windows/win.c] + Allocate a DCE instead of a DC for CS_OWNDC windows. + Replaced Xt calls with Xlib calls. + Moved window positioning functions into windows/winpos.c + + * [windows/winpos.c] (New file) + Rewritten most of the window positioning functions. + Implemented SetWindowPos() and MapWindowPoints(). + +Jan 3, 94 martin2@trgcorp.solucorp.qc.ca (Martin Ayotte) + + * [if1632/user.spec] + Bad arguments description for function SetDlgItemText. + + * [objects/text.c] + Function DrawText now handle DT_CALCRECT request. + + * [misc/message.c] + Message boxes now use DrawText with DT_CALCRECT. + + * [windows/graphics.c] + Bug fix in function FrameRect, (it was using PEN instead of BRUSH). + + * [windows/win.c] + Bug fix for flags in function ShowWindow. + More accurate WM_SIZE generated by function ShowWindow. + + * [controls/listbox.c] + More code for LBS_MULTIPLESEL. + More code for LBS_MULTICOLUMN. + + * [include/windows.h] + Bad define for MF_SEPARATOR. + + * [controls/menu.c] + New functions: PopMenuWndProc() with 'glues', + CreatePopupMenu(), AppendMenu(), InsertMenu(), RemoveMenu(), + DeleteMenu(), ModifyMenu(), TrackPopupMenu(). + Code in stubs: CreateMenu(), DestroyMenu(). + +Sat Jan 1 10:22:43 1994 Bob Amstadt (bob@pooh) + + * loader/wine.c: Added support for relocation types 5 and 6. + +---------------------------------------------------------------------- +Mon Dec 27 11:06:03 1993 Erik Bos (erik@trashcan.hacktic.nl) + + * [misc/comm.c] + new functions: BuildCommDCB(), OpenComm(), CloseComm(), + SetCommBreak(), ClearCommBreak(), EscapeCommFunction(), FlushComm(), + GetCommError(), SetCommEventMask(), GetCommEventMask(), + SetCommState(), GetCommState(), TransmitCommChar(), ReadComm(), + WriteComm(). + +Wed Dec 22 13:00:15 1993 David Metcalfe + + * [windows/caret.c] + Implemented text caret functions. + +Tue Dec 21 06:13:58 1993 julliard@di.epfl.ch (Alexandre Julliard) + + * [loader/wine.c] + Bug fix in LoadImage(). + + * [objects/bitblt.c] [objects/clipping.c] [objects/text.c] + [windows/dc.c] [windows/dce.c] [windows/graphics.c] + Modified graphics calls to take into account the DC origin. + + * [windows/defwnd.c] + Added preliminary WM_NCCALCSIZE handling. + + * [windows/event.c] + Send WM_NCCALCSIZE message on resize event. + + * [windows/win.c] + Send WM_NCCALCSIZE message in CreateWindow(). + Realize widgets at creation time (should prevent problems with + unrealized widgets). + +Dec 19, 93 martin2@trgcorp.solucorp.qc.ca (Martin Ayotte) + + * [controls/static.c] + Send mouse & keyboard message received to its parent. + + * [controls/scroll.c] + Send keyboard message received to its parent. + + * [controls/listbox.c] + Add Navigation keys . + ListBox now use VSCROLL & HSCROLL instead of children. + Alpha version of LBS_MULTIPLESEL. + Alpha version of LBS_MULTICOLUMN. + + * [controls/combo.c] + Add Navigation keys on closed ComboBox. + Remove useless 'COMBOBOX_CreateComboBox' function. + +Mon Dec 19 20:39:34 1993 Erik Bos (erik@trashcan.hacktic.nl) + + * [loader/wine. + LoadImage() modified to use FindFile(). + + * [misc/file.c] + SetErrorMode added + + * [misc/dos_fs.c] + bug fixes. + +Dec 13, 93 martin2@trgcorp.solucorp.qc.ca (Martin Ayotte) + + * [memory/global.c] + bug fix in GlobalGetFreeSegment : good ptr in 'g_prev'. + + * [sysres.dll] + preliminary version of a 'glass of wine' bitmap + + * [windows/event.c] + New function 'GetCapture'. + + * [controls/scroll.c] + Remove useless 'SCROLLBAR_CreateScrollBar' function. + + * [controls/listbox.c] + Remove useless 'LISTBOX_CreateListBox' function. + +Mon Dec 13 13:51:00 1993 David Metcalfe + + * [objects/font.c] + Corrected bugs in GetCharWidth(). + + * [windows/event.c] + Modified EVENT_key to send Windows virtual key codes for + WM_KEYDOWN and WM_KEYUP messages, and a WM_CHAR message + for printable characters. + +Wed Dec 08 19:20:00 1993 Karl Guenter Wuensch (hn324wu@unidui.uni-duisburg.de) + + * [windows/graphics.c] + Added Polyline and Polygon + +Mon Dec 13 14:51:54 1993 Erik Bos (erik@trashcan.hacktic.nl) + + * [controls/listbox.c] + ListBoxDirectory() modified to use dos_fs.c's functions to + access files&|drives. + +Sat Dec 04 17:04:23 1993 Erik Bos (erik@trashcan.hacktic.nl) + + * [misc/dos_fs.c] + Added FindFile() to search a file in a dos/unix style path. + + * [misc/file.c] + New Win31 functions: OpenFile, _lcreate, _llseek, GetTempDrive, + GetTempFileName, GetWindowsDirectory, GetSystemDirectory, + GetDriveType. + + * [misc/int21.c] + Modified. + +Wed Dec 1 16:20:45 1993 Miguel de Icaza (miguel@roxanne.nuclecu.unam.mx) + + * [misc/profile.c] + The Profile functions now return the correct values. They now + implement all the features described in the SDK. + +Tue Nov 30 13:55:27 1993 Bob Amstadt (bob at amscons) + + * [loader/selector.c] + Rewrote selector aliasing routines to use System V IPC + routine to alias memory segments. + +Nov 28, 93 martin2@trgcorp.solucorp.qc.ca (Martin Ayotte) + + * [controls/listbox.c] + More consistency in functions using wIndexes + + * [controls/scroll.c] + New function : ShowScrollBar(). + + * [loader/cursor.c] ... New file + Move cursor functions from [loader/resource.c]. + New function : ClipCursor(). + New function : GetClipCursor(). + New function : CreateCursor(). + SetCursor() now working using gloabal variable 'winHasCursor'. + + *[object/palette.c] + New stub only : SelectPalette(). + New stub only : RealizePalette(). + + *[win/event.c] + New function : EVENT_enter_notify(), + update 'winHasCursor' and send WM_SETCURSOR. + + *[win/defwnd.c] + Add processing of WM_SETCURSOR message. + + *[win/win.c] + New members in WND structure : hCursor, hWndVScroll & hWndHScroll. + CreateWindowEx() now create children for WM_HSCROLL & WM_VSCROLL. + New function ClientToScreen(). + New function ScreenToClient(). + +Mon Nov 25 18:25:40 1993 Erik Bos (erik@trashcan.hacktic.nl) + + * [files.h / regfunc.h / misc/dos.c] + Removed. + + * [misc/dos_fs.c] + Added support for loading dosdrive cfg from wine.ini. + + * [misc/int21.c] + Modified. + + +Wed Nov 24 11:37:33 1993 julliard@disuns2.epfl.ch (Alexandre Julliard) + + * [include/atom.h] [memory/atom.c] + Implemented atoms. + + * [windows/class.c] + Modified RegisterClass() to use atoms. + Implemented CS_GLOBALCLASS style. + + * [windows/message.c] + Implemented RegisterWindowMessage(). + + * [loader/resource.c] + Bug fix in LoadResource(). + + * [windows/dialog.c] + Modified CreateDialogParam() to use Find/LoadResource(). + Mon Nov 22 13:58:56 1993 David Metcalfe * [windows/scroll.c] @@ -37,7 +329,6 @@ Nov 21, 93 martin2@trgcorp.solucorp.qc.ca (Martin Ayotte) * [sysres.dll] Resources only 16bits DLL for System Resources, icons, etc... ----------------------------------------------------------------------- Sun Nov 14 14:39:06 1993 julliard@di.epfl.ch (Alexandre Julliard) * [include/dialog.h] [windows/dialog.c] diff --git a/Imakefile b/Imakefile new file mode 100644 index 00000000000..26b35f407aa --- /dev/null +++ b/Imakefile @@ -0,0 +1,66 @@ +#include "Wine.tmpl" + +/* + * This is the first try at using Imakefiles. There are probably many + * problems and things I haven't even considered. I do not have a Linux + * system to test them on, just NetBSD, so you may need to change things + * like the the SYSLIBS definition below... + * + * Peter Galbavy, 5th Dec 1993 peter@wonderland.org + */ + +#define IHaveSubDirs +#define PassCDebugFlags 'CDEBUGFLAGS=$(CDEBUGFLAGS)' 'CC=$(CC)' + +SUBDIRS = \ + tools \ + controls \ + debugger \ + etc \ + if1632 \ + include \ + loader \ + memory \ + misc \ + objects \ + test \ + windows + +WINEDIR = $(LIBDIR)/wine + +OBJS = \ + if1632.o \ + controls.o \ + loader.o \ + memory.o \ + misc.o \ + objects.o \ + windows.o \ + debugger.o \ + readline.o + +#ifdef i386BsdArchitecture +SYSLIBS = -ll -lm -li386 -lgnumalloc +#else +#ifdef LinuxArchitechture +SYSLIBS = -lm +#endif +#endif + +AllTarget(wine) + +NamedTargetSubdirs($(OBJS),$(SUBDIRS),"making",PassCDebugFlags,all) +MakefileSubdirs($(SUBDIRS)) +DependSubdirs($(SUBDIRS)) +IncludesSubdirs($(SUBDIRS)) +CleanSubdirs($(SUBDIRS)) + +NormalProgramTarget(wine,$(OBJS),XawClientDepLibs,XawClientLibs,$(SYSLIBS)) + +depend:: + +install:: + +includes:: + +clean:: diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000000..3854e932ad3 --- /dev/null +++ b/LICENSE @@ -0,0 +1 @@ +All code unless stated otherwise is covered by the GNU Pubic License. diff --git a/Makefile b/Makefile index 11a884a9bbf..1f7221cbd49 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ ###################################################################### # These variables are inherited by the sub-makefiles -DEBUGOPTS= +DEBUGOPTS=-DUSE_XLIB COPTS=-O2 -m486 INCLUDE_DIR=include LDFLAGS= @@ -12,11 +12,17 @@ LIBS=-L. -L/usr/X386/lib -lXext -lXaw -lXt -lXmu -lX11 -lm OBJS=if1632/if1632.o controls/controls.o loader/loader.o \ memory/memory.o misc/misc.o objects/objects.o windows/windows.o debugger/debugger.o SUBDIRS=if1632 controls loader memory misc objects windows debugger +TAGFILES=if1632/{*.c,*.S} controls/{*.c,*.S} loader/{*.c,*.S} \ + memory/{*.c,*.S} misc/{*.c,*.S} objects/{*.c,*.S} \ + windows/{*.c,*.S} debugger/{*.c,*.S} all: $(TARGET) dummy: +tags: + etags $(TAGFILES) + clean: rm -f *~ *.o *# @for i in tools $(SUBDIRS); do (cd $$i && $(MAKE) clean) || exit; done diff --git a/PROPOSED_LICENSE b/PROPOSED_LICENSE new file mode 100644 index 00000000000..a7d2f7a94a3 --- /dev/null +++ b/PROPOSED_LICENSE @@ -0,0 +1,29 @@ +You may without charge, royalty or other payment, copy and +distribute copies of this work and derivative works of this work +in source or binary form provided that: (1) +you appropriately publish on each copy an appropriate copyright +notice; (2) faithfully reproduce all prior copyright notices +included in the original work (you may also add your own +copyright notice); and (3) agree to indemnify and hold all prior +authors, copyright holders and licensors of the work harmless +from and against all damages arising from use of the work. + +You may distribute sources of derivative works of the work +provided that (1) (a) all source files of the original work that +have been modified, (b) all source files of the derivative work +that contain any party of the original work, and (c) all source +files of the derivative work that are necessary to compile, link +and run the derivative work without unresolved external calls and +with the same functionality of the original work ("Necessary +Sources") carry a prominent notice explaining the nature and date +of the modification and/or creation. You are encouraged to make +the Necessary Sources available under this license in order to +further the development and acceptance of the work. + +EXCEPT AS OTHERWISE RESTRICTED BY LAW, THIS WORK IS PROVIDED +WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES OF ANY KIND, INCLUDING +BUT NOT LIMITED TO, ANY IMPLIED WARRANTIES OF FITNESS FOR A +PARTICULAR PURPOSE, MERCHANTABILITY OR TITLE. EXCEPT AS +OTHERWISE PROVIDED BY LAW, NO AUTHOR, COPYRIGHT HOLDER OR +LICENSOR SHALL BE LIABLE TO YOU FOR DAMAGES OF ANY KIND, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. diff --git a/README b/README index ba0b81b1a75..1b090d42f7a 100644 --- a/README +++ b/README @@ -1,6 +1,6 @@ Copyright Robert J. Amstadt, 1993. All code is provided without -warranty. It is my intent to cover this code with the Gnu Public -License. +warranty. All code is covered by the license contained in the file +LICENSE unless explicitly stated in the individual source file. INSTALLATION: @@ -19,18 +19,56 @@ All: To build Wine, first do a "make depend" and then a "make". The executable "wine" will be built. "wine" will load and run Windows' -executables. You must specify the entire path to the executable, -have the executable in the current directory, or specify a load -path with environment variable WINEPATH. +executables. You must have a file "wine.ini" in the current directory, +your homedirectory, or in the path specified by the environment +variable WINEPATH. Multiple directories in WINEPATH should be seperated +by semi-colons and NOT by colons! -For example, to run Windows' solitaire: +You must specify the entire path to the executable, or a filename only +(using the path= statement in wine.ini as the search path) - export WINEPATH=/dos/windows;/dos/windows/system - wine sol +For example: to run Windows' solitaire: + + export WINEPATH=/etc;/usr/windows + + wine sol (using the path= statement in wine.ini + wine sol.exe as the search path) + + wine c:\\windows\\sol.exe (using a dosfilename) + + wine /usr/windows/sol.exe (using a unixfilename) Have a nice game of solitaire, but be careful. Emulation isn't perfect. So, occassionally it will crash. +WHAT'S NEW with version 0.5: (see ChangeLog for details) + - Working towards elimination of Xt-dependent code. + - StretchBlt() + - GetClassName() & GetClassInfo() + - Implemented loader relocation types 5 and 6. + +WHAT'S NEW with version 0.4.14: (see ChangeLog for details) + - Bug fixes and enhancements + - Comm functions + - Text caret functions + +WHAT'S NEW with version 0.4.13: (see ChangeLog for details) + - Bug fixes + - GetCapture() + - More keyboard handling + - Polyline() and Polygon() + +WHAT'S NEW with version 0.4.12: (see ChangeLog for details) + - Bug fixes + - New DOS file functions + - Experimental Imakefiles + +WHAT'S NEW with version 0.4.11: (see ChangeLog for details) + - Bug fixes + - New cursor functions + - New file system handling + - Atoms + WHAT'S NEW with version 0.4.10: (see ChangeLog for details) - Bug fixes - More scroll bar functions diff --git a/WARRANTY b/WARRANTY new file mode 100644 index 00000000000..492af846b2e --- /dev/null +++ b/WARRANTY @@ -0,0 +1,7 @@ +EXCEPT AS OTHERWISE RESTRICTED BY LAW, THIS WORK IS PROVIDED +WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES OF ANY KIND, INCLUDING +BUT NOT LIMITED TO, ANY IMPLIED WARRANTIES OF FITNESS FOR A +PARTICULAR PURPOSE, MERCHANTABILITY OR TITLE. EXCEPT AS +OTHERWISE PROVIDED BY LAW, NO AUTHOR, COPYRIGHT HOLDER OR +LICENSOR SHALL BE LIABLE TO YOU FOR DAMAGES OF ANY KIND, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. diff --git a/Wine.tmpl b/Wine.tmpl new file mode 100644 index 00000000000..3bb9466ace7 --- /dev/null +++ b/Wine.tmpl @@ -0,0 +1,29 @@ +XCOMM $Id$ + +INCLUDES = -I$(TOP)/include + +XCOMM Imake rules go here + +XCOMM First, dll description to files etc +#ifndef MakeDllFromSpec +#define MakeDllFromSpec(name,objfile) @@\ +objfile.o: Concat(dll_,name.o) Concat3(dll_,name,_tab.o) @@\ + @@\ +Concat(dll_,name.S) Concat3(dll_,name,_tab.c): name.spec $(TOP)/tools/build @@\ + $(TOP)/tools/build name.spec @@\ + +#endif + +/* + * WineRelocatableTarget - generate rules to produce a relocatable object + * file instead of a library. + */ +#ifndef WineRelocatableTarget +#define WineRelocatableTarget(objname,objlist,depobj) @@\ +AllTarget(objname.o) @@\ + @@\ +objname.o: depobj @@\ + $(RM) $@ @@\ + $(LD) $(LDCOMBINEFLAGS) objlist depobj -o $@ +#endif /* WineRelocatableTarget */ + diff --git a/bsdmake.patch b/bsdmake.patch index 99fa57a116e..68fa15782a3 100644 --- a/bsdmake.patch +++ b/bsdmake.patch @@ -6,7 +6,7 @@ diff -ruN ../Backup//Makefile ./Makefile # These definitions are for the top level TARGET=wine -LIBS=-L. -L/usr/X386/lib -lXext -lXaw -lXt -lXmu -lX11 -lm -+LIBS=-L. -L/usr/X386/lib -lXext -lXaw -lXt -lXmu -lX11 -lm -li386 -lgnumalloc ++LIBS=-L. -L/usr/X386/lib -lXext -lXaw -lXt -lXmu -lX11 -lm -li386 -lgnumalloc -ll OBJS=if1632/if1632.o controls/controls.o loader/loader.o \ memory/memory.o misc/misc.o objects/objects.o windows/windows.o SUBDIRS=if1632 controls loader memory misc objects windows diff --git a/controls/Imakefile b/controls/Imakefile new file mode 100644 index 00000000000..aee3e147848 --- /dev/null +++ b/controls/Imakefile @@ -0,0 +1,37 @@ +#include "../Wine.tmpl" + +MODULE = controls + +SRCS = \ + menu.c \ + widgets.c \ + button.c \ + scroll.c \ + listbox.c \ + combo.c \ + static.c \ + SmeMenuButto.c \ + WinLabel.c \ + WinCommand.c \ + WinMenuButto.c + +OBJS = \ + menu.o \ + widgets.o \ + button.o \ + scroll.o \ + listbox.o \ + combo.o \ + static.o \ + SmeMenuButto.o \ + WinLabel.o \ + WinCommand.o \ + WinMenuButto.o + +WineRelocatableTarget($(TOP)/$(MODULE),,$(OBJS)) +DependTarget() +CleanTarget() + +includes:: + +install:: diff --git a/controls/combo.c b/controls/combo.c index e4715891a87..c8e32b9794a 100644 --- a/controls/combo.c +++ b/controls/combo.c @@ -17,60 +17,24 @@ static char Copyright[] = "Copyright Martin Ayotte, 1993"; #include "combo.h" #include "heap.h" #include "win.h" -#include "dirent.h" +#include +#include #include LPHEADCOMBO ComboGetStorageHeader(HWND hwnd); int CreateComboStruct(HWND hwnd); -void COMBOBOX_CreateComboBox(LPSTR className, LPSTR comboLabel, HWND hwnd) -{ - WND *wndPtr = WIN_FindWndPtr(hwnd); - WND *parentPtr = WIN_FindWndPtr(wndPtr->hwndParent); - DWORD style; - char widgetName[15]; - -#ifdef DEBUG_COMBO - printf("combo: label = %s, x = %d, y = %d\n", comboLabel, - wndPtr->rectClient.left, wndPtr->rectClient.top); - printf(" width = %d, height = %d\n", - wndPtr->rectClient.right - wndPtr->rectClient.left, - wndPtr->rectClient.bottom - wndPtr->rectClient.top); -#endif - - if (!wndPtr) - return; - - style = wndPtr->dwStyle & 0x0000FFFF; -/* - if ((style & LBS_NOTIFY) == LBS_NOTIFY) -*/ - sprintf(widgetName, "%s%d", className, wndPtr->wIDmenu); - wndPtr->winWidget = XtVaCreateManagedWidget(widgetName, - compositeWidgetClass, - parentPtr->winWidget, - XtNx, wndPtr->rectClient.left, - XtNy, wndPtr->rectClient.top, - XtNwidth, wndPtr->rectClient.right - - wndPtr->rectClient.left, - XtNheight, 16, - NULL ); - GlobalUnlock(hwnd); - GlobalUnlock(wndPtr->hwndParent); -} - - /*********************************************************************** - * WIDGETS_ComboWndProc + * ComboWndProc */ -LONG COMBOBOX_ComboBoxWndProc( HWND hwnd, WORD message, - WORD wParam, LONG lParam ) +LONG ComboBoxWndProc( HWND hwnd, WORD message, WORD wParam, LONG lParam ) { WORD wRet; RECT rect; - int y; + int y, count; int width, height; + int AltState; WND *wndPtr; LPHEADCOMBO lphc; char str[128]; @@ -106,17 +70,20 @@ LONG COMBOBOX_ComboBoxWndProc( HWND hwnd, WORD message, case WM_DESTROY: lphc = ComboGetStorageHeader(hwnd); if (lphc == 0) return 0; +/* DestroyWindow(lphc->hWndDrop); DestroyWindow(lphc->hWndEdit); -/* - DestroyWindow(lphc->hWndLBox); */ + DestroyWindow(lphc->hWndLBox); free(lphc); - *((LPHEADCOMBO *)&wndPtr->wExtra[1]) = 0; +/* + *((LPHEADCOMBO *)&wndPtr->wExtra[1]) = 0; + printf("Combo WM_DESTROY after clearing wExtra !\n"); +*/ #ifdef DEBUG_COMBO printf("Combo WM_DESTROY %lX !\n", lphc); #endif - return 0; + return DefWindowProc( hwnd, message, wParam, lParam ); case WM_COMMAND: wndPtr = WIN_FindWndPtr(hwnd); @@ -169,9 +136,56 @@ LONG COMBOBOX_ComboBoxWndProc( HWND hwnd, WORD message, break; case WM_LBUTTONDOWN: printf("Combo WM_LBUTTONDOWN wParam=%x lParam=%lX !\n", wParam, lParam); + wndPtr = WIN_FindWndPtr(hwnd); + lphc = ComboGetStorageHeader(hwnd); + lphc->dwState = lphc->dwState ^ CB_SHOWDROPDOWN; + if ((lphc->dwState & CB_SHOWDROPDOWN) == CB_SHOWDROPDOWN) + ShowWindow(lphc->hWndLBox, SW_SHOW); break; case WM_KEYDOWN: - printf("Combo WM_KEYDOWN wParam %X!\n", wParam); + wndPtr = WIN_FindWndPtr(hwnd); + lphc = ComboGetStorageHeader(hwnd); + y = SendMessage(lphc->hWndLBox, LB_GETCURSEL, 0, 0L); + count = SendMessage(lphc->hWndLBox, LB_GETCOUNT, 0, 0L); + printf("COMBOBOX // GetKeyState(VK_MENU)=%d\n", GetKeyState(VK_MENU)); + if (GetKeyState(VK_MENU) < 0) { + lphc->dwState = lphc->dwState ^ CB_SHOWDROPDOWN; + if ((lphc->dwState & CB_SHOWDROPDOWN) == CB_SHOWDROPDOWN) { + ShowWindow(lphc->hWndLBox, SW_SHOW); + } + else { + ShowWindow(lphc->hWndLBox, SW_HIDE); + y = SendMessage(lphc->hWndLBox, LB_GETCURSEL, 0, 0L); + if (y != LB_ERR) { + SendMessage(lphc->hWndLBox, LB_GETTEXT, (WORD)y, (LPARAM)str); + SendMessage(lphc->hWndEdit, WM_SETTEXT, (WORD)y, (LPARAM)str); + } + } + } + else + { + switch(wParam) { + case VK_HOME: + y = 0; + break; + case VK_END: + y = count - 1; + break; + case VK_UP: + y--; + break; + case VK_DOWN: + y++; + break; + } + if (y < 0) y = 0; + if (y >= count) y = count - 1; + SendMessage(lphc->hWndLBox, LB_SETCURSEL, y, 0L); + SendMessage(lphc->hWndLBox, LB_GETTEXT, (WORD)y, (LPARAM)str); + SendMessage(lphc->hWndEdit, WM_SETTEXT, (WORD)y, (LPARAM)str); + SendMessage(GetParent(hwnd), WM_COMMAND, wndPtr->wIDmenu, + MAKELONG(hwnd, CBN_SELCHANGE)); + } break; case WM_CTLCOLOR: return(SendMessage(GetParent(hwnd), WM_CTLCOLOR, wParam, lParam)); diff --git a/controls/listbox.c b/controls/listbox.c index a71eb92b3fe..b1dfb731b25 100644 --- a/controls/listbox.c +++ b/controls/listbox.c @@ -11,16 +11,21 @@ static char Copyright[] = "Copyright Martin Ayotte, 1993"; +#include #include #include +#include +#include +#include #include "windows.h" #include "user.h" #include "heap.h" #include "win.h" +#include "wine.h" #include "listbox.h" #include "scroll.h" -#include "dirent.h" -#include +#include "int21.h" +#include "prototypes.h" #define GMEM_ZEROINIT 0x0040 @@ -38,7 +43,8 @@ int ListBoxDeleteString(HWND hwnd, UINT uIndex); int ListBoxFindString(HWND hwnd, UINT nFirst, LPSTR MatchStr); int ListBoxResetContent(HWND hwnd); int ListBoxSetCurSel(HWND hwnd, WORD wIndex); -int ListBoxSetSel(HWND hwnd, WORD wIndex); +int ListBoxSetSel(HWND hwnd, WORD wIndex, WORD state); +int ListBoxGetSel(HWND hwnd, WORD wIndex); int ListBoxDirectory(HWND hwnd, UINT attrib, LPSTR filespec); int ListBoxGetItemRect(HWND hwnd, WORD wIndex, LPRECT rect); int ListBoxSetItemHeight(HWND hwnd, WORD wIndex, long height); @@ -47,59 +53,16 @@ int ListBoxDefaultItem(HWND hwnd, WND *wndPtr, int ListBoxFindNextMatch(HWND hwnd, WORD wChar); - -void LISTBOX_CreateListBox(LPSTR className, LPSTR listboxLabel, HWND hwnd) -{ - WND *wndPtr = WIN_FindWndPtr(hwnd); - WND *parentPtr = WIN_FindWndPtr(wndPtr->hwndParent); - DWORD style; - char widgetName[15]; - -#ifdef DEBUG_LISTBOX - printf("listbox: label = %s, x = %d, y = %d\n", listboxLabel, - wndPtr->rectClient.left, wndPtr->rectClient.top); - printf(" width = %d, height = %d\n", - wndPtr->rectClient.right - wndPtr->rectClient.left, - wndPtr->rectClient.bottom - wndPtr->rectClient.top); -#endif - - if (!wndPtr) - return; - - style = wndPtr->dwStyle & 0x0000FFFF; -/* - if ((style & LBS_NOTIFY) == LBS_NOTIFY) - if ((style & LBS_SORT) == LBS_SORT) -*/ - sprintf(widgetName, "%s%d", className, wndPtr->wIDmenu); - wndPtr->winWidget = XtVaCreateManagedWidget(widgetName, - compositeWidgetClass, - parentPtr->winWidget, - XtNx, wndPtr->rectClient.left, - XtNy, wndPtr->rectClient.top, - XtNwidth, wndPtr->rectClient.right - - wndPtr->rectClient.left, - XtNheight, wndPtr->rectClient.bottom - - wndPtr->rectClient.top, - NULL ); - GlobalUnlock(hwnd); - GlobalUnlock(wndPtr->hwndParent); -} - - - /*********************************************************************** - * WIDGETS_ListBoxWndProc + * ListBoxWndProc */ -LONG LISTBOX_ListBoxWndProc( HWND hwnd, WORD message, - WORD wParam, LONG lParam ) +LONG ListBoxWndProc( HWND hwnd, WORD message, WORD wParam, LONG lParam ) { WND *wndPtr; LPHEADLIST lphl; WORD wRet; RECT rect; int y; - int width, height; CREATESTRUCT *createStruct; static RECT rectsel; switch(message) @@ -115,19 +78,23 @@ LONG LISTBOX_ListBoxWndProc( HWND hwnd, WORD message, lphl->hWndLogicParent = (HWND)HIWORD(createStruct->lpCreateParams); else lphl->hWndLogicParent = GetParent(hwnd); - width = wndPtr->rectClient.right - wndPtr->rectClient.left; - height = wndPtr->rectClient.bottom - wndPtr->rectClient.top; - lphl->hWndScroll = CreateWindow("SCROLLBAR", "", - WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | SBS_VERT, - width - 17, 0, 16, height, hwnd, 1, wndPtr->hInstance, NULL); - ShowWindow(lphl->hWndScroll, SW_HIDE); - SetScrollRange(lphl->hWndScroll, WM_VSCROLL, 1, lphl->ItemsCount, TRUE); + lphl->ColumnsWidth = wndPtr->rectClient.right - wndPtr->rectClient.left; + if (wndPtr->hWndVScroll != (HWND)NULL) { + SetScrollRange(hwnd, SB_VERT, 1, lphl->ItemsCount, TRUE); + ShowScrollBar(hwnd, SB_VERT, FALSE); + } + if (wndPtr->hWndHScroll != (HWND)NULL) { + SetScrollRange(hwnd, SB_HORZ, 1, 1, TRUE); + ShowScrollBar(hwnd, SB_HORZ, FALSE); + } + if (wndPtr->hCursor == (HCURSOR)NULL) + wndPtr->hCursor = LoadCursor((HINSTANCE)NULL, IDC_ARROW); return 0; case WM_DESTROY: - lphl = ListBoxGetStorageHeader(hwnd); + lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); if (lphl == 0) return 0; ListBoxResetContent(hwnd); - DestroyWindow(lphl->hWndScroll); + DestroyCursor(wndPtr->hCursor); free(lphl); *((LPHEADLIST *)&wndPtr->wExtra[1]) = 0; #ifdef DEBUG_LISTBOX @@ -164,23 +131,74 @@ LONG LISTBOX_ListBoxWndProc( HWND hwnd, WORD message, if (lphl->FirstVisible > lphl->ItemsCount) lphl->FirstVisible = lphl->ItemsCount; if (y != lphl->FirstVisible) { - SetScrollPos(lphl->hWndScroll, WM_VSCROLL, lphl->FirstVisible, TRUE); + SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE); InvalidateRect(hwnd, NULL, TRUE); UpdateWindow(hwnd); } return 0; + case WM_HSCROLL: + lphl = ListBoxGetStorageHeader(hwnd); + if (lphl == NULL) return 0; + y = lphl->FirstVisible; + switch(wParam) { + case SB_LINEUP: + if (lphl->FirstVisible > 1) + lphl->FirstVisible -= lphl->ItemsPerColumn; + break; + case SB_LINEDOWN: + if (lphl->FirstVisible < lphl->ItemsCount) + lphl->FirstVisible += lphl->ItemsPerColumn; + break; + case SB_PAGEUP: + if (lphl->FirstVisible > 1 && lphl->ItemsPerColumn != 0) + lphl->FirstVisible -= lphl->ItemsVisible / + lphl->ItemsPerColumn * lphl->ItemsPerColumn; + break; + case SB_PAGEDOWN: + if (lphl->FirstVisible < lphl->ItemsCount && + lphl->ItemsPerColumn != 0) + lphl->FirstVisible += lphl->ItemsVisible / + lphl->ItemsPerColumn * lphl->ItemsPerColumn; + break; + case SB_THUMBTRACK: + lphl->FirstVisible = lphl->ItemsPerColumn * + (LOWORD(lParam) - 1) + 1; + break; + } + if (lphl->FirstVisible < 1) lphl->FirstVisible = 1; + if (lphl->FirstVisible > lphl->ItemsCount) + lphl->FirstVisible = lphl->ItemsCount; + if (lphl->ItemsPerColumn != 0) { + lphl->FirstVisible = lphl->FirstVisible / + lphl->ItemsPerColumn * lphl->ItemsPerColumn + 1; + if (y != lphl->FirstVisible) { + SetScrollPos(hwnd, SB_HORZ, lphl->FirstVisible / + lphl->ItemsPerColumn + 1, TRUE); + InvalidateRect(hwnd, NULL, TRUE); + UpdateWindow(hwnd); + } + } + return 0; + case WM_LBUTTONDOWN: /* SetFocus(hwnd); */ SetCapture(hwnd); - lphl = ListBoxGetStorageHeader(hwnd); + lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); if (lphl == NULL) return 0; - lphl->PrevSelected = lphl->ItemSelected; - wRet = ListBoxFindMouse(hwnd, LOWORD(lParam), HIWORD(lParam)); - ListBoxSetCurSel(hwnd, wRet); - ListBoxGetItemRect(hwnd, wRet, &rectsel); + lphl->PrevFocused = lphl->ItemFocused; + y = ListBoxFindMouse(hwnd, LOWORD(lParam), HIWORD(lParam)); + if ((wndPtr->dwStyle & LBS_MULTIPLESEL) == LBS_MULTIPLESEL) { + lphl->ItemFocused = y; + wRet = ListBoxGetSel(hwnd, y); + ListBoxSetSel(hwnd, y, !wRet); + } + else { + ListBoxSetCurSel(hwnd, y); + } + ListBoxGetItemRect(hwnd, y, &rectsel); InvalidateRect(hwnd, NULL, TRUE); UpdateWindow(hwnd); return 0; @@ -188,7 +206,7 @@ LONG LISTBOX_ListBoxWndProc( HWND hwnd, WORD message, ReleaseCapture(); lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); if (lphl == NULL) return 0; - if (lphl->PrevSelected != lphl->ItemSelected) + if (lphl->PrevFocused != lphl->ItemFocused) SendMessage(lphl->hWndLogicParent, WM_COMMAND, wndPtr->wIDmenu, MAKELONG(hwnd, LBN_SELCHANGE)); return 0; @@ -200,9 +218,102 @@ LONG LISTBOX_ListBoxWndProc( HWND hwnd, WORD message, MAKELONG(hwnd, LBN_DBLCLK)); printf("ListBox Send LBN_DBLCLK !\n"); return 0; + case WM_MOUSEMOVE: + if ((wParam & MK_LBUTTON) != 0) { + y = HIWORD(lParam); + if (y < 4) { + lphl = ListBoxGetStorageHeader(hwnd); + if (lphl->FirstVisible > 1) { + lphl->FirstVisible--; + if (wndPtr->hWndVScroll != (HWND)NULL) + SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE); + InvalidateRect(hwnd, NULL, TRUE); + UpdateWindow(hwnd); + break; + } + } + GetClientRect(hwnd, &rect); + if (y > (rect.bottom - 4)) { + lphl = ListBoxGetStorageHeader(hwnd); + if (lphl->FirstVisible < lphl->ItemsCount) { + lphl->FirstVisible++; + if (wndPtr->hWndVScroll != (HWND)NULL) + SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE); + InvalidateRect(hwnd, NULL, TRUE); + UpdateWindow(hwnd); + break; + } + } + if ((y > 0) && (y < (rect.bottom - 4))) { + if ((y < rectsel.top) || (y > rectsel.bottom)) { + wRet = ListBoxFindMouse(hwnd, LOWORD(lParam), HIWORD(lParam)); + if ((wndPtr->dwStyle & LBS_MULTIPLESEL) == LBS_MULTIPLESEL) { + lphl->ItemFocused = wRet; + } + else { + ListBoxSetCurSel(hwnd, wRet); + } + ListBoxGetItemRect(hwnd, wRet, &rectsel); + InvalidateRect(hwnd, NULL, TRUE); + UpdateWindow(hwnd); + } + + } + } + break; case WM_KEYDOWN: - printf("ListBox WM_KEYDOWN wParam %X!\n", wParam); - ListBoxFindNextMatch(hwnd, wParam); + lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); + if (lphl == NULL) return 0; + switch(wParam) { + case VK_HOME: + lphl->ItemFocused = 0; + break; + case VK_END: + lphl->ItemFocused = lphl->ItemsCount - 1; + break; + case VK_LEFT: + if ((wndPtr->dwStyle & LBS_MULTICOLUMN) == LBS_MULTICOLUMN) { + lphl->ItemFocused -= lphl->ItemsPerColumn; + break; + } + case VK_UP: + lphl->ItemFocused--; + break; + case VK_RIGHT: + if ((wndPtr->dwStyle & LBS_MULTICOLUMN) == LBS_MULTICOLUMN) { + lphl->ItemFocused += lphl->ItemsPerColumn; + break; + } + case VK_DOWN: + lphl->ItemFocused++; + break; + case VK_PRIOR: + lphl->ItemFocused -= lphl->ItemsVisible; + break; + case VK_NEXT: + lphl->ItemFocused += lphl->ItemsVisible; + break; + case VK_SPACE: + wRet = ListBoxGetSel(hwnd, lphl->ItemFocused); + ListBoxSetSel(hwnd, lphl->ItemFocused, !wRet); + break; + default: + ListBoxFindNextMatch(hwnd, wParam); + return 0; + } + if (lphl->ItemFocused < 0) lphl->ItemFocused = 0; + if (lphl->ItemFocused >= lphl->ItemsCount) + lphl->ItemFocused = lphl->ItemsCount - 1; + lphl->FirstVisible = lphl->ItemFocused / lphl->ItemsVisible * + lphl->ItemsVisible + 1; + if (lphl->FirstVisible < 1) lphl->FirstVisible = 1; + if ((wndPtr->dwStyle & LBS_MULTIPLESEL) != LBS_MULTIPLESEL) { + ListBoxSetCurSel(hwnd, lphl->ItemFocused); + } + if (wndPtr->hWndVScroll != (HWND)NULL) + SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE); + InvalidateRect(hwnd, NULL, TRUE); + UpdateWindow(hwnd); break; case WM_PAINT: wndPtr = WIN_FindWndPtr(hwnd); @@ -216,42 +327,6 @@ LONG LISTBOX_ListBoxWndProc( HWND hwnd, WORD message, } StdDrawListBox(hwnd); break; - case WM_MOUSEMOVE: - if ((wParam & MK_LBUTTON) != 0) { - y = HIWORD(lParam); - if (y < 4) { - lphl = ListBoxGetStorageHeader(hwnd); - if (lphl->FirstVisible > 1) { - lphl->FirstVisible--; - SetScrollPos(lphl->hWndScroll, WM_VSCROLL, lphl->FirstVisible, TRUE); - InvalidateRect(hwnd, NULL, TRUE); - UpdateWindow(hwnd); - break; - } - } - GetClientRect(hwnd, &rect); - if (y > (rect.bottom - 4)) { - lphl = ListBoxGetStorageHeader(hwnd); - if (lphl->FirstVisible < lphl->ItemsCount) { - lphl->FirstVisible++; - SetScrollPos(lphl->hWndScroll, WM_VSCROLL, lphl->FirstVisible, TRUE); - InvalidateRect(hwnd, NULL, TRUE); - UpdateWindow(hwnd); - break; - } - } - if ((y > 0) && (y < (rect.bottom - 4))) { - if ((y < rectsel.top) || (y > rectsel.bottom)) { - wRet = ListBoxFindMouse(hwnd, LOWORD(lParam), HIWORD(lParam)); - ListBoxSetCurSel(hwnd, wRet); - ListBoxGetItemRect(hwnd, wRet, &rectsel); - InvalidateRect(hwnd, NULL, TRUE); - UpdateWindow(hwnd); - } - - } - } - break; case LB_RESETCONTENT: printf("ListBox LB_RESETCONTENT !\n"); @@ -260,17 +335,17 @@ LONG LISTBOX_ListBoxWndProc( HWND hwnd, WORD message, case LB_DIR: printf("ListBox LB_DIR !\n"); wRet = ListBoxDirectory(hwnd, wParam, (LPSTR)lParam); - if (IsWindowVisible(hwnd)) { - InvalidateRect(hwnd, NULL, TRUE); - UpdateWindow(hwnd); - } + InvalidateRect(hwnd, NULL, TRUE); + UpdateWindow(hwnd); return wRet; case LB_ADDSTRING: wRet = ListBoxAddString(hwnd, (LPSTR)lParam); return wRet; case LB_GETTEXT: wRet = ListBoxGetText(hwnd, wParam, (LPSTR)lParam); +#ifdef DEBUG_LISTBOX printf("ListBox LB_GETTEXT #%u '%s' !\n", wParam, (LPSTR)lParam); +#endif return wRet; case LB_INSERTSTRING: wRet = ListBoxInsertString(hwnd, wParam, (LPSTR)lParam); @@ -289,9 +364,8 @@ LONG LISTBOX_ListBoxWndProc( HWND hwnd, WORD message, return lphl->ItemsCount; case LB_GETCURSEL: lphl = ListBoxGetStorageHeader(hwnd); - printf("ListBox LB_GETCURSEL %u !\n", lphl->ItemSelected); - if (lphl->ItemSelected == 0) return LB_ERR; - return lphl->ItemSelected; + printf("ListBox LB_GETCURSEL %u !\n", lphl->ItemFocused); + return lphl->ItemFocused; case LB_GETHORIZONTALEXTENT: return wRet; case LB_GETITEMDATA: @@ -301,6 +375,7 @@ LONG LISTBOX_ListBoxWndProc( HWND hwnd, WORD message, case LB_GETITEMRECT: return wRet; case LB_GETSEL: + wRet = ListBoxGetSel(hwnd, wParam); return wRet; case LB_GETSELCOUNT: return wRet; @@ -317,7 +392,9 @@ LONG LISTBOX_ListBoxWndProc( HWND hwnd, WORD message, case LB_SETCARETINDEX: return wRet; case LB_SETCOLUMNWIDTH: - return wRet; + lphl = ListBoxGetStorageHeader(hwnd); + lphl->ColumnsWidth = wParam; + break; case LB_SETHORIZONTALEXTENT: return wRet; case LB_SETITEMDATA: @@ -329,38 +406,29 @@ LONG LISTBOX_ListBoxWndProc( HWND hwnd, WORD message, printf("ListBox LB_SETCURSEL wParam=%x !\n", wParam); #endif wRet = ListBoxSetCurSel(hwnd, wParam); - if (IsWindowVisible(hwnd)) { - InvalidateRect(hwnd, NULL, TRUE); - UpdateWindow(hwnd); - } + InvalidateRect(hwnd, NULL, TRUE); + UpdateWindow(hwnd); return wRet; case LB_SETSEL: printf("ListBox LB_SETSEL wParam=%x lParam=%lX !\n", wParam, lParam); - wRet = ListBoxSetSel(hwnd, wParam); - if (IsWindowVisible(hwnd)) { - InvalidateRect(hwnd, NULL, TRUE); - UpdateWindow(hwnd); - } + wRet = ListBoxSetSel(hwnd, LOWORD(lParam), wParam); + InvalidateRect(hwnd, NULL, TRUE); + UpdateWindow(hwnd); return wRet; case LB_SETTOPINDEX: printf("ListBox LB_SETTOPINDEX wParam=%x !\n", wParam); lphl = ListBoxGetStorageHeader(hwnd); lphl->FirstVisible = wParam; - SetScrollPos(lphl->hWndScroll, WM_VSCROLL, lphl->FirstVisible, TRUE); - if (IsWindowVisible(hwnd)) { - InvalidateRect(hwnd, NULL, TRUE); - UpdateWindow(hwnd); - } + if (wndPtr->hWndVScroll != (HWND)NULL) + SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE); + InvalidateRect(hwnd, NULL, TRUE); + UpdateWindow(hwnd); break; case LB_SETITEMHEIGHT: #ifdef DEBUG_LISTBOX printf("ListBox LB_SETITEMHEIGHT wParam=%x lParam=%lX !\n", wParam, lParam); #endif wRet = ListBoxSetItemHeight(hwnd, wParam, lParam); - if (IsWindowVisible(hwnd)) { - InvalidateRect(hwnd, NULL, TRUE); - UpdateWindow(hwnd); - } return wRet; default: @@ -392,6 +460,7 @@ LPHEADLIST ListBoxGetStorageHeader(HWND hwnd) void StdDrawListBox(HWND hwnd) { + WND *wndPtr; LPHEADLIST lphl; LPLISTSTRUCT lpls; PAINTSTRUCT ps; @@ -399,7 +468,7 @@ void StdDrawListBox(HWND hwnd) HWND hWndParent; HDC hdc; RECT rect; - UINT i, h, h2; + UINT i, h, h2, maxwidth, ipc; char C[128]; h = 0; hdc = BeginPaint( hwnd, &ps ); @@ -407,41 +476,64 @@ void StdDrawListBox(HWND hwnd) EndPaint( hwnd, &ps ); return; } - GetClientRect(hwnd, &rect); - lphl = ListBoxGetStorageHeader(hwnd); + lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); if (lphl == NULL) goto EndOfPaint; hBrush = SendMessage(lphl->hWndLogicParent, WM_CTLCOLOR, (WORD)hdc, MAKELONG(hwnd, CTLCOLOR_LISTBOX)); if (hBrush == (HBRUSH)NULL) hBrush = GetStockObject(WHITE_BRUSH); - if (lphl->ItemsCount > lphl->ItemsVisible) rect.right -= 16; + GetClientRect(hwnd, &rect); + if ((wndPtr->hWndVScroll != (HWND)NULL) && + IsWindowVisible(wndPtr->hWndVScroll)) rect.right -= 16; + if ((wndPtr->hWndHScroll != (HWND)NULL) && + IsWindowVisible(wndPtr->hWndHScroll)) rect.bottom -= 16; FillRect(hdc, &rect, hBrush); + maxwidth = rect.right; + rect.right = lphl->ColumnsWidth; if (lphl->ItemsCount == 0) goto EndOfPaint; lpls = lphl->lpFirst; if (lpls == NULL) goto EndOfPaint; lphl->ItemsVisible = 0; + lphl->ItemsPerColumn = ipc = 0; for(i = 1; i <= lphl->ItemsCount; i++) { if (i >= lphl->FirstVisible) { h2 = lpls->dis.rcItem.bottom - lpls->dis.rcItem.top; lpls->dis.rcItem.top = h; lpls->dis.rcItem.bottom = h + h2; + lpls->dis.rcItem.left = rect.left; lpls->dis.rcItem.right = rect.right; - TextOut(hdc, 5, h + 2, (char *)lpls->dis.itemData, + TextOut(hdc, rect.left + 5, h + 2, (char *)lpls->dis.itemData, strlen((char *)lpls->dis.itemData)); if (lpls->dis.itemState != 0) { InvertRect(hdc, &lpls->dis.rcItem); } + if (lphl->ItemFocused == i - 1) { + DrawFocusRect(hdc, &lpls->dis.rcItem); + } h += h2; lphl->ItemsVisible++; - if (h > rect.bottom) break; + ipc++; + if (h > rect.bottom) { + if ((wndPtr->dwStyle & LBS_MULTICOLUMN) == LBS_MULTICOLUMN) { + lphl->ItemsPerColumn = max(lphl->ItemsPerColumn, ipc); + ipc = 0; + h = 0; + rect.left += lphl->ColumnsWidth; + rect.right += lphl->ColumnsWidth; + if (rect.left > maxwidth) break; + } + else + break; + } } if (lpls->lpNext == NULL) goto EndOfPaint; lpls = (LPLISTSTRUCT)lpls->lpNext; } EndOfPaint: EndPaint( hwnd, &ps ); - if (lphl->ItemsCount > lphl->ItemsVisible) { - InvalidateRect(lphl->hWndScroll, NULL, TRUE); - UpdateWindow(lphl->hWndScroll); + if ((lphl->ItemsCount > lphl->ItemsVisible) & + (wndPtr->hWndVScroll != (HWND)NULL)) { + InvalidateRect(wndPtr->hWndVScroll, NULL, TRUE); + UpdateWindow(wndPtr->hWndVScroll); } } @@ -449,6 +541,7 @@ EndOfPaint: void OwnerDrawListBox(HWND hwnd) { + WND *wndPtr; LPHEADLIST lphl; LPLISTSTRUCT lpls; PAINTSTRUCT ps; @@ -456,38 +549,47 @@ void OwnerDrawListBox(HWND hwnd) HWND hWndParent; HDC hdc; RECT rect; - UINT i, h, h2; + UINT i, h, h2, maxwidth; char C[128]; h = 0; - hdc = BeginPaint( hwnd, &ps ); + hdc = BeginPaint(hwnd, &ps); if (!IsWindowVisible(hwnd)) { EndPaint( hwnd, &ps ); return; } - GetClientRect(hwnd, &rect); - lphl = ListBoxGetStorageHeader(hwnd); + lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); if (lphl == NULL) goto EndOfPaint; hBrush = SendMessage(lphl->hWndLogicParent, WM_CTLCOLOR, (WORD)hdc, MAKELONG(hwnd, CTLCOLOR_LISTBOX)); if (hBrush == (HBRUSH)NULL) hBrush = GetStockObject(WHITE_BRUSH); - if (lphl->ItemsCount > lphl->ItemsVisible) rect.right -= 16; + GetClientRect(hwnd, &rect); + if ((wndPtr->hWndVScroll != (HWND)NULL) && + IsWindowVisible(wndPtr->hWndVScroll)) rect.right -= 16; + if ((wndPtr->hWndHScroll != (HWND)NULL) && + IsWindowVisible(wndPtr->hWndHScroll)) rect.bottom -= 16; FillRect(hdc, &rect, hBrush); + maxwidth = rect.right; + rect.right = lphl->ColumnsWidth; if (lphl->ItemsCount == 0) goto EndOfPaint; lpls = lphl->lpFirst; if (lpls == NULL) goto EndOfPaint; lphl->ItemsVisible = 0; - for(i = 1; i <= lphl->ItemsCount; i++) { + for (i = 1; i <= lphl->ItemsCount; i++) { if (i >= lphl->FirstVisible) { lpls->dis.hDC = hdc; - lpls->dis.itemID = i; + lpls->dis.itemID = i - 1; h2 = lpls->dis.rcItem.bottom - lpls->dis.rcItem.top; lpls->dis.rcItem.top = h; lpls->dis.rcItem.bottom = h + h2; + lpls->dis.rcItem.left = rect.left; lpls->dis.rcItem.right = rect.right; lpls->dis.itemAction = ODA_DRAWENTIRE; if (lpls->dis.itemState != 0) { lpls->dis.itemAction |= ODA_SELECT; } + if (lphl->ItemFocused == i - 1) { + lpls->dis.itemAction |= ODA_FOCUS; + } #ifdef DEBUT_LISTBOX printf("LBOX WM_DRAWITEM #%d left=%d top=%d right=%d bottom=%d !\n", i, lpls->dis.rcItem.left, lpls->dis.rcItem.top, @@ -502,16 +604,17 @@ void OwnerDrawListBox(HWND hwnd) } h += h2; lphl->ItemsVisible++; - if (h > rect.bottom) break; + if (h > rect.bottom) goto EndOfPaint; } if (lpls->lpNext == NULL) goto EndOfPaint; lpls = (LPLISTSTRUCT)lpls->lpNext; } EndOfPaint: EndPaint( hwnd, &ps ); - if (lphl->ItemsCount > lphl->ItemsVisible) { - InvalidateRect(lphl->hWndScroll, NULL, TRUE); - UpdateWindow(lphl->hWndScroll); + if ((lphl->ItemsCount > lphl->ItemsVisible) & + (wndPtr->hWndVScroll != (HWND)NULL)) { + InvalidateRect(wndPtr->hWndVScroll, NULL, TRUE); + UpdateWindow(wndPtr->hWndVScroll); } } @@ -519,27 +622,42 @@ EndOfPaint: int ListBoxFindMouse(HWND hwnd, int X, int Y) { -LPHEADLIST lphl; -LPLISTSTRUCT lpls; -RECT rect; -UINT i, h, h2; -char C[128]; -h = 0; -lphl = ListBoxGetStorageHeader(hwnd); -if (lphl == NULL) return LB_ERR; -if (lphl->ItemsCount == 0) return LB_ERR; -lpls = lphl->lpFirst; -if (lpls == NULL) return LB_ERR; -for(i = 1; i <= lphl->ItemsCount; i++) { - if (i >= lphl->FirstVisible) { - h2 = h; - h += lpls->dis.rcItem.bottom - lpls->dis.rcItem.top; - if ((Y > h2) && (Y < h)) return(i); + WND *wndPtr; + LPHEADLIST lphl; + LPLISTSTRUCT lpls; + RECT rect; + UINT i, h, h2, w, w2; + char C[128]; + lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); + if (lphl == NULL) return LB_ERR; + if (lphl->ItemsCount == 0) return LB_ERR; + lpls = lphl->lpFirst; + if (lpls == NULL) return LB_ERR; + GetClientRect(hwnd, &rect); + if ((wndPtr->hWndVScroll != (HWND)NULL) && + IsWindowVisible(wndPtr->hWndVScroll)) rect.right -= 16; + if ((wndPtr->hWndHScroll != (HWND)NULL) && + IsWindowVisible(wndPtr->hWndHScroll)) rect.bottom -= 16; + h = w2 = 0; + w = lphl->ColumnsWidth; + for(i = 1; i <= lphl->ItemsCount; i++) { + if (i >= lphl->FirstVisible) { + h2 = h; + h += lpls->dis.rcItem.bottom - lpls->dis.rcItem.top; + if ((Y > h2) && (Y < h) && + (X > w2) && (X < w)) return(i - 1); + if (h > rect.bottom) { + if ((wndPtr->dwStyle & LBS_MULTICOLUMN) != LBS_MULTICOLUMN) return LB_ERR; + h = 0; + w2 = w; + w += lphl->ColumnsWidth; + if (w2 > rect.right) return LB_ERR; + } + } + if (lpls->lpNext == NULL) return LB_ERR; + lpls = (LPLISTSTRUCT)lpls->lpNext; } - if (lpls->lpNext == NULL) return LB_ERR; - lpls = (LPLISTSTRUCT)lpls->lpNext; - } -return(LB_ERR); + return(LB_ERR); } @@ -602,14 +720,22 @@ int ListBoxAddString(HWND hwnd, LPSTR newstr) lplsnew->dis.itemID = lphl->ItemsCount; lplsnew->dis.itemData = (DWORD)newstr; lplsnew->hData = hTemp; - SetScrollRange(lphl->hWndScroll, WM_VSCROLL, 1, lphl->ItemsCount, - (lphl->FirstVisible != 1)); + if (wndPtr->hWndVScroll != (HWND)NULL) + SetScrollRange(hwnd, SB_VERT, 1, lphl->ItemsCount, + (lphl->FirstVisible != 1)); + if (wndPtr->hWndHScroll != (HWND)NULL && lphl->ItemsPerColumn != 0) + SetScrollRange(hwnd, SB_HORZ, 1, lphl->ItemsVisible / + lphl->ItemsPerColumn + 1, (lphl->FirstVisible != 1)); if (lphl->FirstVisible >= (lphl->ItemsCount - lphl->ItemsVisible)) { InvalidateRect(hwnd, NULL, TRUE); UpdateWindow(hwnd); } - if ((lphl->ItemsCount - lphl->FirstVisible) == lphl->ItemsVisible) - ShowWindow(lphl->hWndScroll, SW_NORMAL); + if ((lphl->ItemsCount - lphl->FirstVisible) == lphl->ItemsVisible) { + if (wndPtr->hWndVScroll != (HWND)NULL) + ShowScrollBar(hwnd, SB_VERT, TRUE); + if (wndPtr->hWndHScroll != (HWND)NULL) + ShowScrollBar(hwnd, SB_HORZ, TRUE); + } return lphl->ItemsCount; } @@ -624,7 +750,7 @@ int ListBoxInsertString(HWND hwnd, UINT uIndex, LPSTR newstr) UINT Count; lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); if (lphl == NULL) return LB_ERR; - if (uIndex < 1 || uIndex > lphl->ItemsCount) return LB_ERR; + if (uIndex >= lphl->ItemsCount) return LB_ERR; lpls = lphl->lpFirst; if (lpls == NULL) return LB_ERR; if (uIndex > lphl->ItemsCount) return LB_ERR; @@ -653,11 +779,19 @@ int ListBoxInsertString(HWND hwnd, UINT uIndex, LPSTR newstr) lplsnew->dis.itemID = lphl->ItemsCount; lplsnew->dis.itemData = (DWORD)newstr; lplsnew->hData = hTemp; - SetScrollRange(lphl->hWndScroll, WM_VSCROLL, 1, lphl->ItemsCount, - (lphl->FirstVisible != 1)); + if (wndPtr->hWndVScroll != (HWND)NULL) + SetScrollRange(hwnd, SB_VERT, 1, lphl->ItemsCount, + (lphl->FirstVisible != 1)); + if (wndPtr->hWndHScroll != (HWND)NULL && lphl->ItemsPerColumn != 0) + SetScrollRange(hwnd, SB_HORZ, 1, lphl->ItemsVisible / + lphl->ItemsPerColumn + 1, (lphl->FirstVisible != 1)); if (((lphl->ItemsCount - lphl->FirstVisible) == lphl->ItemsVisible) && - (lphl->ItemsVisible != 0)) - ShowWindow(lphl->hWndScroll, SW_NORMAL); + (lphl->ItemsVisible != 0)) { + if (wndPtr->hWndVScroll != (HWND)NULL) + ShowScrollBar(hwnd, SB_VERT, TRUE); + if (wndPtr->hWndHScroll != (HWND)NULL) + ShowScrollBar(hwnd, SB_HORZ, TRUE); + } if ((lphl->FirstVisible <= uIndex) && ((lphl->FirstVisible + lphl->ItemsVisible) >= uIndex)) { InvalidateRect(hwnd, NULL, TRUE); @@ -675,11 +809,11 @@ int ListBoxGetText(HWND hwnd, UINT uIndex, LPSTR OutStr) UINT Count; lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); if (lphl == NULL) return LB_ERR; - if (uIndex < 1 || uIndex > lphl->ItemsCount) return LB_ERR; + if (uIndex >= lphl->ItemsCount) return LB_ERR; lpls = lphl->lpFirst; if (lpls == NULL) return LB_ERR; if (uIndex > lphl->ItemsCount) return LB_ERR; - for(Count = 1; Count < uIndex; Count++) { + for(Count = 0; Count < uIndex; Count++) { if (lpls->lpNext == NULL) return LB_ERR; lpls = (LPLISTSTRUCT)lpls->lpNext; } @@ -698,12 +832,13 @@ int ListBoxGetText(HWND hwnd, UINT uIndex, LPSTR OutStr) int ListBoxDeleteString(HWND hwnd, UINT uIndex) { + WND *wndPtr; LPHEADLIST lphl; LPLISTSTRUCT lpls, lpls2; UINT Count; - lphl = ListBoxGetStorageHeader(hwnd); + lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); if (lphl == NULL) return LB_ERR; - if (uIndex < 1 || uIndex > lphl->ItemsCount) return LB_ERR; + if (uIndex >= lphl->ItemsCount) return LB_ERR; lpls = lphl->lpFirst; if (lpls == NULL) return LB_ERR; if (uIndex > lphl->ItemsCount) return LB_ERR; @@ -716,9 +851,17 @@ int ListBoxDeleteString(HWND hwnd, UINT uIndex) lphl->ItemsCount--; if (lpls->hData != 0) USER_HEAP_FREE(lpls->hData); if (lpls->hMem != 0) USER_HEAP_FREE(lpls->hMem); - SetScrollRange(lphl->hWndScroll, WM_VSCROLL, 1, lphl->ItemsCount, TRUE); - if (lphl->ItemsCount < lphl->ItemsVisible) - ShowWindow(lphl->hWndScroll, SW_HIDE); + if (wndPtr->hWndVScroll != (HWND)NULL) + SetScrollRange(hwnd, SB_VERT, 1, lphl->ItemsCount, TRUE); + if (wndPtr->hWndHScroll != (HWND)NULL && lphl->ItemsPerColumn != 0) + SetScrollRange(hwnd, SB_HORZ, 1, lphl->ItemsVisible / + lphl->ItemsPerColumn + 1, TRUE); + if (lphl->ItemsCount < lphl->ItemsVisible) { + if (wndPtr->hWndVScroll != (HWND)NULL) + ShowScrollBar(hwnd, SB_VERT, FALSE); + if (wndPtr->hWndHScroll != (HWND)NULL) + ShowScrollBar(hwnd, SB_HORZ, FALSE); + } if ((lphl->FirstVisible <= uIndex) && ((lphl->FirstVisible + lphl->ItemsVisible) >= uIndex)) { InvalidateRect(hwnd, NULL, TRUE); @@ -735,13 +878,12 @@ int ListBoxFindString(HWND hwnd, UINT nFirst, LPSTR MatchStr) UINT Count; lphl = ListBoxGetStorageHeader(hwnd); if (lphl == NULL) return LB_ERR; - if (nFirst < 1 || nFirst > lphl->ItemsCount) return LB_ERR; + if (nFirst > lphl->ItemsCount) return LB_ERR; lpls = lphl->lpFirst; if (lpls == NULL) return LB_ERR; - Count = 1; + Count = 0; while(lpls != NULL) { - if (strcmp((char *)lpls->dis.itemData, MatchStr) == 0) - return Count; + if (strcmp((char *)lpls->dis.itemData, MatchStr) == 0) return Count; lpls = (LPLISTSTRUCT)lpls->lpNext; Count++; } @@ -774,14 +916,21 @@ int ListBoxResetContent(HWND hwnd) lphl->lpFirst = NULL; lphl->FirstVisible = 1; lphl->ItemsCount = 0; - lphl->ItemSelected = 0; - lphl->PrevSelected = 0; + lphl->ItemFocused = 0; + lphl->PrevFocused = 0; if ((wndPtr->dwStyle && LBS_NOTIFY) != 0) SendMessage(wndPtr->hwndParent, WM_COMMAND, wndPtr->wIDmenu, MAKELONG(hwnd, LBN_SELCHANGE)); - SetScrollRange(lphl->hWndScroll, WM_VSCROLL, 1, lphl->ItemsCount, TRUE); - ShowWindow(lphl->hWndScroll, SW_HIDE); + if (wndPtr->hWndVScroll != (HWND)NULL) + SetScrollRange(hwnd, SB_VERT, 1, lphl->ItemsCount, TRUE); + if (wndPtr->hWndHScroll != (HWND)NULL && lphl->ItemsPerColumn != 0) + SetScrollRange(hwnd, SB_HORZ, 1, lphl->ItemsVisible / + lphl->ItemsPerColumn + 1, TRUE); + if (wndPtr->hWndVScroll != (HWND)NULL) + ShowScrollBar(hwnd, SB_VERT, FALSE); + if (wndPtr->hWndHScroll != (HWND)NULL) + ShowScrollBar(hwnd, SB_HORZ, FALSE); InvalidateRect(hwnd, NULL, TRUE); UpdateWindow(hwnd); return TRUE; @@ -796,8 +945,8 @@ int ListBoxSetCurSel(HWND hwnd, WORD wIndex) UINT i; lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); if (lphl == NULL) return LB_ERR; - lphl->ItemSelected = LB_ERR; - if (wIndex < 0 || wIndex >= lphl->ItemsCount) return LB_ERR; + lphl->ItemFocused = LB_ERR; + if (wIndex >= lphl->ItemsCount) return LB_ERR; lpls = lphl->lpFirst; if (lpls == NULL) return LB_ERR; for(i = 0; i < lphl->ItemsCount; i++) { @@ -810,7 +959,7 @@ int ListBoxSetCurSel(HWND hwnd, WORD wIndex) lpls2->dis.itemState = 0; if (lpls == NULL) break; } - lphl->ItemSelected = wIndex; + lphl->ItemFocused = wIndex; if ((wndPtr->dwStyle && LBS_NOTIFY) != 0) SendMessage(wndPtr->hwndParent, WM_COMMAND, wndPtr->wIDmenu, MAKELONG(hwnd, LBN_SELCHANGE)); @@ -819,22 +968,44 @@ int ListBoxSetCurSel(HWND hwnd, WORD wIndex) -int ListBoxSetSel(HWND hwnd, WORD wIndex) +int ListBoxSetSel(HWND hwnd, WORD wIndex, WORD state) { LPHEADLIST lphl; LPLISTSTRUCT lpls, lpls2; UINT i; lphl = ListBoxGetStorageHeader(hwnd); if (lphl == NULL) return LB_ERR; - if (wIndex < 0 || wIndex >= lphl->ItemsCount) return LB_ERR; + if (wIndex >= lphl->ItemsCount) return LB_ERR; + lpls = lphl->lpFirst; + if (lpls == NULL) return LB_ERR; + for(i = 0; i < lphl->ItemsCount; i++) { + lpls2 = lpls; + lpls = (LPLISTSTRUCT)lpls->lpNext; + if ((i == wIndex) || (wIndex == (WORD)-1)) { + lpls2->dis.itemState = state; + break; + } + if (lpls == NULL) break; + } + return LB_ERR; +} + + +int ListBoxGetSel(HWND hwnd, WORD wIndex) +{ + LPHEADLIST lphl; + LPLISTSTRUCT lpls, lpls2; + UINT i; + lphl = ListBoxGetStorageHeader(hwnd); + if (lphl == NULL) return LB_ERR; + if (wIndex >= lphl->ItemsCount) return LB_ERR; lpls = lphl->lpFirst; if (lpls == NULL) return LB_ERR; for(i = 0; i < lphl->ItemsCount; i++) { lpls2 = lpls; lpls = (LPLISTSTRUCT)lpls->lpNext; if (i == wIndex) { - lpls2->dis.itemState = 1; - break; + return lpls2->dis.itemState; } if (lpls == NULL) break; } @@ -844,28 +1015,56 @@ int ListBoxSetSel(HWND hwnd, WORD wIndex) int ListBoxDirectory(HWND hwnd, UINT attrib, LPSTR filespec) { -DIR *dirp; -struct dirent *dp; -struct stat st; -char str[128]; -int wRet; -dirp = opendir("."); -while ( (dp = readdir(dirp)) != NULL) - { - stat(dp->d_name, &st); -#ifdef DEBUG_LBDIR - printf("LB_DIR : st_mode=%lX / d_name='%s'\n", st.st_mode, dp->d_name); -#endif - if S_ISDIR(st.st_mode) { - sprintf(str, "[%s]", dp->d_name); + struct dosdirent *dp; + struct stat st; + int x, wRet; + char temp[256]; + + fprintf(stderr,"ListBoxDirectory: %s, %4x\n",filespec,attrib); + + + if ((dp = (struct dosdirent *)DOS_opendir(filespec)) ==NULL) + return 0; + + while (1) + { + dp = (struct dosdirent *)DOS_readdir(dp); + if (!dp->inuse) + break; + + if (dp->attribute & 0x08) + { + if (attrib & DDL_DIRECTORY) { + sprintf(temp, "[%s]", dp->filename); + if ( (wRet = ListBoxAddString(hwnd, temp)) == LB_ERR) + break; + } + } else + if (attrib & DDL_EXCLUSIVE) { + if (attrib & (DDL_READWRITE | DDL_READONLY | DDL_HIDDEN | DDL_SYSTEM) ) + if ( (wRet = ListBoxAddString(hwnd, dp->filename)) == LB_ERR) + break; + } else { + if ( (wRet = ListBoxAddString(hwnd, dp->filename)) == LB_ERR) + break; + } } - else - strcpy(str, dp->d_name); - wRet = ListBoxAddString(hwnd, str); - if (wRet == LB_ERR) break; - } -closedir(dirp); -return wRet; + DOS_closedir(dp); + + if (attrib & DDL_DRIVES) + { + for (x=0;x!=MAX_DOS_DRIVES;x++) + { + if (DOS_ValidDrive(x)) + { + sprintf(temp, "[-%c-]", 'A'+x); + if ( (wRet = ListBoxAddString(hwnd, temp)) == LB_ERR) + break; + } + } + } + + return wRet; } @@ -876,10 +1075,10 @@ int ListBoxGetItemRect(HWND hwnd, WORD wIndex, LPRECT lprect) UINT i; lphl = ListBoxGetStorageHeader(hwnd); if (lphl == NULL) return LB_ERR; - if (wIndex < 1 || wIndex > lphl->ItemsCount) return LB_ERR; + if (wIndex > lphl->ItemsCount) return LB_ERR; lpls = lphl->lpFirst; if (lpls == NULL) return LB_ERR; - for(i = 0; i <= lphl->ItemsCount; i++) { + for(i = 0; i < lphl->ItemsCount; i++) { lpls2 = lpls; lpls = (LPLISTSTRUCT)lpls->lpNext; if (i == wIndex) { @@ -900,14 +1099,16 @@ int ListBoxSetItemHeight(HWND hwnd, WORD wIndex, long height) UINT i; lphl = ListBoxGetStorageHeader(hwnd); if (lphl == NULL) return LB_ERR; - if (wIndex < 1 || wIndex > lphl->ItemsCount) return LB_ERR; + if (wIndex > lphl->ItemsCount) return LB_ERR; lpls = lphl->lpFirst; if (lpls == NULL) return LB_ERR; - for(i = 0; i <= lphl->ItemsCount; i++) { + for(i = 0; i < lphl->ItemsCount; i++) { lpls2 = lpls; lpls = (LPLISTSTRUCT)lpls->lpNext; if (i == wIndex) { lpls2->dis.rcItem.bottom = lpls2->dis.rcItem.top + (short)height; + InvalidateRect(hwnd, NULL, TRUE); + UpdateWindow(hwnd); break; } if (lpls == NULL) break; @@ -954,14 +1155,19 @@ int ListBoxFindNextMatch(HWND hwnd, WORD wChar) return LB_ERR; } } - Count = 1; + Count = 0; while(lpls != NULL) { - if (Count > lphl->ItemSelected) { + if (Count > lphl->ItemFocused) { if (*((char *)lpls->dis.itemData) == (char)wChar) { lphl->FirstVisible = Count - lphl->ItemsVisible / 2; if (lphl->FirstVisible < 1) lphl->FirstVisible = 1; - ListBoxSetCurSel(hwnd, Count); - SetScrollPos(lphl->hWndScroll, WM_VSCROLL, lphl->FirstVisible, TRUE); + if ((wndPtr->dwStyle & LBS_MULTIPLESEL) == LBS_MULTIPLESEL) { + lphl->ItemFocused = Count; + } + else { + ListBoxSetCurSel(hwnd, Count); + } + SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE); InvalidateRect(hwnd, NULL, TRUE); UpdateWindow(hwnd); return Count; @@ -970,15 +1176,20 @@ int ListBoxFindNextMatch(HWND hwnd, WORD wChar) lpls = (LPLISTSTRUCT)lpls->lpNext; Count++; } - Count = 1; + Count = 0; lpls = lphl->lpFirst; while(lpls != NULL) { if (*((char *)lpls->dis.itemData) == (char)wChar) { - if (Count == lphl->ItemSelected) return LB_ERR; + if (Count == lphl->ItemFocused) return LB_ERR; lphl->FirstVisible = Count - lphl->ItemsVisible / 2; if (lphl->FirstVisible < 1) lphl->FirstVisible = 1; - ListBoxSetCurSel(hwnd, Count); - SetScrollPos(lphl->hWndScroll, WM_VSCROLL, lphl->FirstVisible, TRUE); + if ((wndPtr->dwStyle & LBS_MULTIPLESEL) == LBS_MULTIPLESEL) { + lphl->ItemFocused = Count; + } + else { + ListBoxSetCurSel(hwnd, Count); + } + SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE); InvalidateRect(hwnd, NULL, TRUE); UpdateWindow(hwnd); return Count; diff --git a/controls/menu.c b/controls/menu.c index 2d22115fa0d..c1cd758484d 100644 --- a/controls/menu.c +++ b/controls/menu.c @@ -1,6 +1,8 @@ static char RCSId[] = "$Id$"; static char Copyright[] = "Copyright Robert J. Amstadt, 1993"; +#define DEBUG_MENU + #include #include #include @@ -22,7 +24,306 @@ static int lastLevel; static int menuId = 0; static Pixmap checkBitmap = XtUnspecifiedPixmap; static Pixmap nocheckBitmap = XtUnspecifiedPixmap; - + +LPPOPUPMENU PopupMenuGetStorageHeader(HWND hwnd); +LPPOPUPMENU PopupMenuGetWindowAndStorage(HWND hwnd, WND **wndPtr); +void StdDrawPopupMenu(HWND hwnd); +LPMENUITEM PopupMenuFindItem(HWND hwnd, int x, int y, WORD *lpRet); +LPMENUITEM GetMenuItemPtr(LPPOPUPMENU menu, WORD nPos); + +/*********************************************************************** + * PopupMenuWndProc + */ +LONG PopupMenuWndProc( HWND hwnd, WORD message, WORD wParam, LONG lParam ) +{ + CREATESTRUCT *createStruct; + WORD wRet; + short x, y; + WND *wndPtr; + LPPOPUPMENU lppop; + LPMENUITEM lpitem, lpitem2; + HMENU hSubMenu; + RECT rect; + HDC hDC; + switch(message) + { + case WM_CREATE: +#ifdef DEBUG_MENU + printf("PopupMenu WM_CREATE lParam=%08X !\n", lParam); +#endif + createStruct = (CREATESTRUCT *)lParam; + lppop = (LPPOPUPMENU)createStruct->lpCreateParams; + if (lppop == 0) break; + wndPtr = WIN_FindWndPtr(hwnd); + *((LPPOPUPMENU *)&wndPtr->wExtra[1]) = lppop; +#ifdef DEBUG_MENU + printf("PopupMenu WM_CREATE lppop=%08X !\n", lppop); +#endif + return 0; + case WM_DESTROY: + lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr); +#ifdef DEBUG_MENU + printf("PopupMenu WM_DESTROY %lX !\n", lppop); +#endif + return 0; + + case WM_LBUTTONDOWN: + lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr); + SetCapture(hwnd); + lpitem = PopupMenuFindItem(hwnd, LOWORD(lParam), HIWORD(lParam), &wRet); + printf("PopupMenu WM_LBUTTONDOWN wRet=%d lpitem=%08X !\n", wRet, lpitem); + if (lpitem != NULL) { + lppop->FocusedItem = wRet; + if (((lpitem->item_flags & MF_SEPARATOR) != MF_SEPARATOR) && + ((lpitem->item_flags & MF_MENUBREAK) != MF_MENUBREAK)) { + hDC = GetDC(hwnd); + InvertRect(hDC, &lpitem->rect); + ReleaseDC(hwnd, hDC); + } + } + break; + case WM_LBUTTONUP: + lppop = PopupMenuGetStorageHeader(hwnd); + ReleaseCapture(); + lpitem = PopupMenuFindItem(hwnd, LOWORD(lParam), HIWORD(lParam), &wRet); + printf("PopupMenu WM_LBUTTONUP wRet=%d lpitem=%08X !\n", wRet, lpitem); + if (lpitem != NULL) { + if (lppop->FocusedItem != (WORD)-1) { + lpitem2 = GetMenuItemPtr(lppop, lppop->FocusedItem); + if (((lpitem2->item_flags & MF_SEPARATOR) != MF_SEPARATOR) && + ((lpitem2->item_flags & MF_MENUBREAK) != MF_MENUBREAK)) { + hDC = GetDC(hwnd); + InvertRect(hDC, &lpitem2->rect); + ReleaseDC(hwnd, hDC); + } + } + if ((lpitem->item_flags & MF_POPUP) == MF_POPUP) { + hSubMenu = (HMENU)lpitem->item_id; + printf("ShowSubmenu hSubMenu=%04X !\n", hSubMenu); + GetClientRect(hwnd, &rect); + x = rect.right; + GetWindowRect(hwnd, &rect); + x += rect.left; + TrackPopupMenu(hSubMenu, TPM_LEFTBUTTON, + x, rect.top + HIWORD(lParam), + 0, lppop->ownerWnd, (LPRECT)NULL); + break; + } + if (((lpitem->item_flags & MF_SEPARATOR) != MF_SEPARATOR) && + ((lpitem->item_flags & MF_POPUP) != MF_POPUP)) { + SendMessage(lppop->ownerWnd, WM_COMMAND, lpitem->item_id, 0L); + printf("PopupMenu // SendMessage WM_COMMAND wParam=%d !\n", + lpitem->item_id); + ShowWindow(lppop->hWnd, SW_HIDE); + break; + } + } + break; + case WM_MOUSEMOVE: + if ((wParam & MK_LBUTTON) != 0) { + lppop = PopupMenuGetStorageHeader(hwnd); + lpitem = PopupMenuFindItem(hwnd, LOWORD(lParam), HIWORD(lParam), &wRet); + if ((lpitem != NULL) && (lppop->FocusedItem != wRet)) { + lpitem2 = GetMenuItemPtr(lppop, lppop->FocusedItem); + hDC = GetDC(hwnd); + if (((lpitem2->item_flags & MF_POPUP) == MF_POPUP) || + ((lpitem2->item_flags & MF_STRING) == MF_STRING)) { + InvertRect(hDC, &lpitem2->rect); + } + lppop->FocusedItem = wRet; + printf("PopupMenu WM_MOUSEMOVE wRet=%d lpitem=%08X !\n", wRet, lpitem); + InvertRect(hDC, &lpitem->rect); + ReleaseDC(hwnd, hDC); + } + } + break; + + case WM_KEYDOWN: + case WM_KEYUP: + case WM_CHAR: + lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr); + return(SendMessage(wndPtr->hwndParent, message, wParam, lParam)); + + case WM_PAINT: + printf("PopupMenu WM_PAINT !\n"); + StdDrawPopupMenu(hwnd); + break; + default: + return DefWindowProc( hwnd, message, wParam, lParam ); + } +return(0); +} + + + +LPPOPUPMENU PopupMenuGetWindowAndStorage(HWND hwnd, WND **wndPtr) +{ + WND *Ptr; + LPPOPUPMENU lppop; + *(wndPtr) = Ptr = WIN_FindWndPtr(hwnd); + if (Ptr == 0) { + printf("Bad Window handle on PopupMenu !\n"); + return 0; + } + lppop = *((LPPOPUPMENU *)&Ptr->wExtra[1]); + return lppop; +} + + +LPPOPUPMENU PopupMenuGetStorageHeader(HWND hwnd) +{ + WND *Ptr; + LPPOPUPMENU lppop; + Ptr = WIN_FindWndPtr(hwnd); + if (Ptr == 0) { + printf("Bad Window handle on PopupMenu !\n"); + return 0; + } + lppop = *((LPPOPUPMENU *)&Ptr->wExtra[1]); + return lppop; +} + + +void StdDrawPopupMenu(HWND hwnd) +{ + WND *wndPtr; + LPPOPUPMENU lppop; + LPMENUITEM lpitem; + PAINTSTRUCT ps; + HBRUSH hBrush; + HPEN hOldPen; + HWND hWndParent; + HDC hDC, hMemDC; + RECT rect, rect2, rect3; + HBITMAP hBitMap; + BITMAP bm; + UINT i; + hDC = BeginPaint( hwnd, &ps ); + if (!IsWindowVisible(hwnd)) { + EndPaint( hwnd, &ps ); + return; + } + lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr); + if (lppop == NULL) goto EndOfPaint; + hBrush = SendMessage(lppop->ownerWnd, WM_CTLCOLOR, (WORD)hDC, + MAKELONG(hwnd, CTLCOLOR_LISTBOX)); + if (hBrush == (HBRUSH)NULL) hBrush = GetStockObject(WHITE_BRUSH); + GetClientRect(hwnd, &rect); + GetClientRect(hwnd, &rect2); + FillRect(hDC, &rect, hBrush); + if (lppop->nItems == 0) goto EndOfPaint; + lpitem = lppop->firstItem->next; + if (lpitem == NULL) goto EndOfPaint; + for(i = 0; i < lppop->nItems; i++) { + if ((lpitem->item_flags & MF_SEPARATOR) == MF_SEPARATOR) { + rect2.bottom = rect2.top + 3; + CopyRect(&lpitem->rect, &rect2); + hOldPen = SelectObject(hDC, GetStockObject(BLACK_PEN)); + MoveTo(hDC, rect2.left, rect2.top + 1); + LineTo(hDC, rect2.right, rect2.top + 1); + SelectObject(hDC, hOldPen); + rect2.top += 3; + } + if ((lpitem->item_flags & MF_BITMAP) == MF_BITMAP) { + hBitMap = (HBITMAP)LOWORD(lpitem->item_text); + rect2.bottom = rect2.top + bm.bmHeight; + CopyRect(&lpitem->rect, &rect2); + hMemDC = CreateCompatibleDC(hDC); + SelectObject(hMemDC, hBitMap); + GetObject(hBitMap, sizeof(BITMAP), (LPSTR)&bm); + BitBlt(hDC, rect2.left, rect2.top, + bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY); + DeleteDC(hMemDC); + rect2.top += bm.bmHeight; + } + if (((lpitem->item_flags & MF_BITMAP) != MF_BITMAP) && + ((lpitem->item_flags & MF_SEPARATOR) != MF_SEPARATOR) && + ((lpitem->item_flags & MF_MENUBREAK) != MF_MENUBREAK)) { + rect2.bottom = rect2.top + 15; + CopyRect(&lpitem->rect, &rect2); + TextOut(hDC, rect2.left + 5, rect2.top + 2, + (char *)lpitem->item_text, strlen((char *)lpitem->item_text)); + rect2.top += 15; + } + if ((lpitem->item_flags & MF_CHECKED) == MF_CHECKED) { + CopyRect(&rect3, &rect2); + rect3.left = rect3.right - rect3.bottom + rect3.top; + InvertRect(hDC, &rect3); + } + if ((lpitem->item_flags & MF_POPUP) == MF_POPUP) { + CopyRect(&rect3, &rect2); + rect3.left = rect3.right - rect3.bottom + rect3.top; + FillRect(hDC, &rect3, GetStockObject(BLACK_BRUSH)); + } + if (lpitem->next == NULL) goto EndOfPaint; + lpitem = (LPMENUITEM)lpitem->next; + } +EndOfPaint: + EndPaint( hwnd, &ps ); +} + + + +LPMENUITEM PopupMenuFindItem(HWND hwnd, int x, int y, WORD *lpRet) +{ + WND *wndPtr; + LPPOPUPMENU lppop; + LPMENUITEM lpitem; + RECT rect, rect2; + HBITMAP hBitMap; + BITMAP bm; + UINT i; + lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr); + if (lppop == NULL) return NULL; + GetClientRect(hwnd, &rect); + if (lppop->nItems == 0) return NULL; + lpitem = lppop->firstItem->next; + if (lpitem == NULL) return NULL; + for(i = 0; i < lppop->nItems; i++) { + if (y < rect2.top) return NULL; + if ((lpitem->item_flags & MF_SEPARATOR) == MF_SEPARATOR) { + rect2.bottom = rect2.top + 3; + rect2.top += 3; + } + if ((lpitem->item_flags & MF_BITMAP) == MF_BITMAP) { + hBitMap = (HBITMAP)LOWORD(lpitem->item_text); + GetObject(hBitMap, sizeof(BITMAP), (LPSTR)&bm); + rect2.bottom = rect2.top + bm.bmHeight; + rect2.top += bm.bmHeight; + } + if (((lpitem->item_flags & MF_BITMAP) != MF_BITMAP) && + ((lpitem->item_flags & MF_SEPARATOR) != MF_SEPARATOR) && + ((lpitem->item_flags & MF_MENUBREAK) != MF_MENUBREAK)) { + rect2.bottom = rect2.top + 15; + rect2.top += 15; + } + if (y < rect2.bottom) { + if (lpRet != NULL) *lpRet = i; + return lpitem; + } + if (lpitem->next == NULL) return NULL; + lpitem = (LPMENUITEM)lpitem->next; + } + return NULL; +} + + + +LPMENUITEM GetMenuItemPtr(LPPOPUPMENU menu, WORD nPos) +{ + LPMENUITEM lpitem; + int i; + if (menu == NULL) return NULL; + lpitem = menu->firstItem; + for (i = 0; i < menu->nItems; i++) { + if (lpitem->next == NULL) return NULL; + lpitem = (LPMENUITEM)lpitem->next; + if (i == nPos) return(lpitem); + } + return NULL; +} + + /********************************************************************** * MENU_CheckWidget */ @@ -565,3 +866,316 @@ LoadMenu(HINSTANCE instance, char *menu_name) return GlobalHandleFromPointer(menu->firstItem); } + + +/********************************************************************** + * CheckMenuItem [USER.154] + */ +BOOL CheckMenuItem(HMENU hMenu, WORD wItemID, WORD wFlags) +{ +} + + +/********************************************************************** + * EnableMenuItem [USER.155] + */ +BOOL EnableMenuItem(HMENU hMenu, WORD wItemID, WORD wFlags) +{ +} + + +/********************************************************************** + * InsertMenu [USER.410] + */ +BOOL InsertMenu(HMENU hMenu, WORD nPos, WORD wFlags, WORD wItemID, LPSTR lpNewItem) +{ + WND *wndPtr; + LPPOPUPMENU menu; + HANDLE hNewItem; + LPMENUITEM lpitem, lpitem2; + int i; +#ifdef DEBUG_MENU + printf("InsertMenu (%04X, %04X, %04X, %04X, %08X) !\n", + hMenu, nPos, wFlags, wItemID, lpNewItem); +#endif + menu = (LPPOPUPMENU) GlobalLock(hMenu); + if (menu == NULL) return FALSE; + lpitem = menu->firstItem; + for (i = 0; i < menu->nItems; i++) { + if (lpitem->next == NULL) break; + lpitem = (LPMENUITEM)lpitem->next; + printf("InsertMenu // during loop items !\n"); + } + printf("InsertMenu // after loop items !\n"); + hNewItem = GlobalAlloc(GMEM_MOVEABLE, sizeof(MENUITEM)); + if (hNewItem == 0) return FALSE; + lpitem2 = (LPMENUITEM)GlobalLock(hNewItem); + if (lpitem2 == 0) { + GlobalFree(hNewItem); + return FALSE; + } + lpitem2->item_flags = wFlags; + lpitem2->item_id = wItemID; + if ((wFlags & MF_STRING) == MF_STRING) { + lpitem2->item_text = lpNewItem; + } + else + lpitem2->item_text = lpNewItem; + lpitem2->prev = lpitem; + if (lpitem->next != NULL) + lpitem2->next = lpitem->next; + else + lpitem2->next = NULL; + lpitem->next = lpitem2; + lpitem2->child = NULL; + lpitem2->parent = NULL; + lpitem2->w = NULL; + lpitem2->menu_w = NULL; + menu->nItems++; + return TRUE; +} + + +/********************************************************************** + * AppendMenu [USER.411] + */ +BOOL AppendMenu(HMENU hMenu, WORD wFlags, WORD wItemID, LPSTR lpNewItem) +{ + WND *wndPtr; + LPPOPUPMENU menu; + HANDLE hNewItem; + LPMENUITEM lpitem, lpitem2; +#ifdef DEBUG_MENU + printf("AppendMenu (%04X, %04X, %04X, %08X) !\n", + hMenu, wFlags, wItemID, lpNewItem); +#endif + menu = (LPPOPUPMENU) GlobalLock(hMenu); + if (menu == NULL) return FALSE; + lpitem = menu->firstItem; + while (lpitem->next != NULL) { + lpitem = (LPMENUITEM)lpitem->next; + printf("AppendMenu // during loop items !\n"); + } + printf("AppendMenu // after loop items !\n"); + hNewItem = GlobalAlloc(GMEM_MOVEABLE, sizeof(MENUITEM)); + if (hNewItem == 0) return FALSE; + lpitem2 = (LPMENUITEM)GlobalLock(hNewItem); + if (lpitem2 == 0) { + GlobalFree(hNewItem); + return FALSE; + } + lpitem2->item_flags = wFlags; + lpitem2->item_id = wItemID; + if ((wFlags & MF_STRING) == MF_STRING) { + lpitem2->item_text = lpNewItem; + } + else + lpitem2->item_text = lpNewItem; + lpitem->next = lpitem2; + lpitem2->prev = lpitem; + lpitem2->next = NULL; + lpitem2->child = NULL; + lpitem2->parent = NULL; + lpitem2->w = NULL; + lpitem2->menu_w = NULL; + menu->nItems++; + return TRUE; +} + + +/********************************************************************** + * RemoveMenu [USER.412] + */ +BOOL RemoveMenu(HMENU hMenu, WORD nPos, WORD wFlags) +{ + WND *wndPtr; + LPPOPUPMENU menu; + LPMENUITEM lpitem; + int i; +#ifdef DEBUG_MENU + printf("RemoveMenu (%04X, %04X, %04X) !\n", hMenu, nPos, wFlags); +#endif + menu = (LPPOPUPMENU) GlobalLock(hMenu); + if (menu == NULL) return FALSE; + lpitem = menu->firstItem; + for (i = 0; i < menu->nItems; i++) { + if (lpitem->next == NULL) break; + lpitem = (LPMENUITEM)lpitem->next; + if (i == nPos) { + lpitem->prev->next = lpitem->next; + lpitem->next->prev = lpitem->prev; + GlobalFree(HIWORD(lpitem)); + return(TRUE); + } + printf("RemoveMenu // during loop items !\n"); + } + printf("RemoveMenu // after loop items !\n"); + return FALSE; +} + + +/********************************************************************** + * DeleteMenu [USER.413] + */ +BOOL DeleteMenu(HMENU hMenu, WORD nPos, WORD wFlags) +{ +#ifdef DEBUG_MENU + printf("DeleteMenu (%04X, %04X, %04X) !\n", hMenu, nPos, wFlags); +#endif + return TRUE; +} + + +/********************************************************************** + * ModifyMenu [USER.414] + */ +BOOL ModifyMenu(HMENU hMenu, WORD nPos, WORD wFlags, WORD wItemID, LPSTR lpNewItem) +{ +#ifdef DEBUG_MENU + printf("ModifyMenu (%04X, %04X, %04X, %04X, %08X) !\n", + hMenu, nPos, wFlags, wItemID, lpNewItem); +#endif + return TRUE; +} + + +/********************************************************************** + * CreatePopupMenu [USER.415] + */ +HMENU CreatePopupMenu() +{ + HANDLE hItem; + HMENU hMenu; + LPPOPUPMENU menu; +#ifdef DEBUG_MENU + printf("CreatePopupMenu !\n"); +#endif + hMenu = GlobalAlloc(GMEM_MOVEABLE, sizeof(POPUPMENU)); + menu = (LPPOPUPMENU) GlobalLock(hMenu); + if (menu == NULL) { + GlobalFree(hMenu); + return 0; + } + hItem = GlobalAlloc(GMEM_MOVEABLE, sizeof(MENUITEM)); + if (hItem == 0) { + GlobalFree(hMenu); + return 0; + } + menu->nItems = 0; + menu->firstItem = (LPMENUITEM)GlobalLock(hItem); + menu->ownerWnd = 0; + menu->hWnd = 0; + + menu->firstItem->next = NULL; + menu->firstItem->prev = NULL; + menu->firstItem->child = NULL; + menu->firstItem->parent = NULL; + menu->firstItem->item_flags = 0; + menu->firstItem->item_id = 0; + menu->firstItem->item_text = NULL; + menu->firstItem->w = NULL; + menu->firstItem->menu_w = NULL; + return hMenu; +} + + +/********************************************************************** + * TrackPopupMenu [USER.414] + */ +BOOL TrackPopupMenu(HMENU hMenu, WORD wFlags, short x, short y, + short nReserved, HWND hWnd, LPRECT lpRect) +{ + WND *wndPtr; + LPPOPUPMENU menu; +#ifdef DEBUG_MENU + printf("TrackPopupMenu (%04X, %04X, %d, %d, %04X, %04X, %08X) !\n", + hMenu, wFlags, x, y, nReserved, hWnd, lpRect); +#endif + menu = (LPPOPUPMENU) GlobalLock(hMenu); + if (menu == NULL) return FALSE; + wndPtr = WIN_FindWndPtr(hWnd); + menu->ownerWnd = hWnd; + if (menu->hWnd == NULL) { + menu->hWnd = CreateWindow("POPUPMENU", "", WS_CHILD | WS_VISIBLE, + x, y, 100, 150, hWnd, 0, wndPtr->hInstance, (LPSTR)menu); + } + else + ShowWindow(menu->hWnd, SW_SHOW); + return TRUE; +} + + +/********************************************************************** + * CreateMenu [USER.151] + */ +HMENU CreateMenu() +{ + HANDLE hItem; + HMENU hMenu; + LPMENUBAR menu; +#ifdef DEBUG_MENU + printf("CreateMenu !\n"); +#endif + hMenu = GlobalAlloc(GMEM_MOVEABLE, sizeof(MENUBAR)); + menu = (LPMENUBAR) GlobalLock(hMenu); + if (menu == NULL) { + GlobalFree(hMenu); + return 0; + } + hItem = GlobalAlloc(GMEM_MOVEABLE, sizeof(MENUITEM)); + if (hItem == 0) { + GlobalFree(hMenu); + return 0; + } + menu->menuDescription = 0; + menu->nItems = 0; + menu->parentWidget = NULL; + menu->firstItem = (LPMENUITEM) GlobalLock(hItem); + menu->ownerWnd = 0; + menu->menuBarWidget = NULL; + + menu->firstItem->next = NULL; + menu->firstItem->prev = NULL; + menu->firstItem->child = NULL; + menu->firstItem->parent = NULL; + menu->firstItem->item_flags = 0; + menu->firstItem->item_id = 0; + menu->firstItem->item_text = NULL; + menu->firstItem->w = NULL; + menu->firstItem->menu_w = NULL; + return hMenu; +} + + +/********************************************************************** + * DestroyMenu [USER.152] + */ +BOOL DestroyMenu(HMENU hMenu) +{ + LPPOPUPMENU lppop; + LPMENUITEM lpitem, lpitem2; +#ifdef DEBUG_MENU + printf("DestroyMenu (%04X) !\n", hMenu); +#endif + if (hMenu == 0) return FALSE; + lppop = (LPPOPUPMENU) GlobalLock(hMenu); + if (lppop == NULL) return FALSE; + if (lppop->hWnd) DestroyWindow (lppop->hWnd); + lpitem = lppop->firstItem; + while (lpitem->next != NULL) { +#ifdef DEBUG_MENU + printf("DestroyMenu (%04X) // during loop items !\n", hMenu); +#endif + if ((lpitem->item_flags & MF_POPUP) == MF_POPUP) { + DestroyMenu((HMENU)lpitem->item_id); + } + lpitem = (LPMENUITEM)lpitem->next; + } + GlobalFree(hMenu); +#ifdef DEBUG_MENU + printf("DestroyMenu (%04X) // End !\n", hMenu); +#endif + return TRUE; +} + + diff --git a/controls/scroll.c b/controls/scroll.c index fd8e45a24ee..9cfa55010d1 100644 --- a/controls/scroll.c +++ b/controls/scroll.c @@ -17,7 +17,8 @@ static char Copyright[] = "Copyright Martin Ayotte, 1993"; #include "scroll.h" #include "heap.h" #include "win.h" -#include "dirent.h" +#include +#include #include LPHEADSCROLL ScrollBarGetWindowAndStorage(HWND hwnd, WND **wndPtr); @@ -26,50 +27,10 @@ void StdDrawScrollBar(HWND hwnd); int CreateScrollBarStruct(HWND hwnd); -void SCROLLBAR_CreateScrollBar(LPSTR className, LPSTR scrollLabel, HWND hwnd) -{ - WND *wndPtr = WIN_FindWndPtr(hwnd); - WND *parentPtr = WIN_FindWndPtr(wndPtr->hwndParent); - DWORD style; - char widgetName[15]; - -#ifdef DEBUG_SCROLLBAR - printf("scroll: label = %s, x = %d, y = %d\n", scrollLabel, - wndPtr->rectClient.left, wndPtr->rectClient.top); - printf(" width = %d, height = %d\n", - wndPtr->rectClient.right - wndPtr->rectClient.left, - wndPtr->rectClient.bottom - wndPtr->rectClient.top); -#endif - - if (!wndPtr) - return; - - style = wndPtr->dwStyle & 0x0000FFFF; -/* - if ((style & SBS_NOTIFY) == SBS_NOTIFY) -*/ - sprintf(widgetName, "%s%d", className, wndPtr->wIDmenu); - wndPtr->winWidget = XtVaCreateManagedWidget(widgetName, - compositeWidgetClass, - parentPtr->winWidget, - XtNx, wndPtr->rectClient.left, - XtNy, wndPtr->rectClient.top, - XtNwidth, wndPtr->rectClient.right - - wndPtr->rectClient.left, - XtNheight, wndPtr->rectClient.bottom - - wndPtr->rectClient.top, - NULL ); - GlobalUnlock(hwnd); - GlobalUnlock(wndPtr->hwndParent); -} - - - /*********************************************************************** * WIDGETS_ScrollBarWndProc */ -LONG SCROLLBAR_ScrollBarWndProc( HWND hwnd, WORD message, - WORD wParam, LONG lParam ) +LONG ScrollBarWndProc( HWND hwnd, WORD message, WORD wParam, LONG lParam ) { WORD wRet; short x, y; @@ -169,8 +130,11 @@ LONG SCROLLBAR_ScrollBarWndProc( HWND hwnd, WORD message, break; case WM_KEYDOWN: - printf("ScrollBar WM_KEYDOWN wParam %X !\n", wParam); - break; + case WM_KEYUP: + case WM_CHAR: + lphs = ScrollBarGetWindowAndStorage(hwnd, &wndPtr); + return(SendMessage(wndPtr->hwndParent, message, wParam, lParam)); + case WM_PAINT: StdDrawScrollBar(hwnd); break; @@ -330,36 +294,36 @@ int CreateScrollBarStruct(HWND hwnd) wndPtr->hInstance, 0L); } if (lphs->MaxPix < 1) lphs->MaxPix = 1; + if (wndPtr->hCursor == (HCURSOR)NULL) + wndPtr->hCursor = LoadCursor((HINSTANCE)NULL, IDC_ARROW); return TRUE; } - -int GetScrollPos(HWND hwnd, int nBar) +/************************************************************************* + * GetScrollWindowHandle + */ +HWND GetScrollWindowHandle(HWND hWnd, int nBar) { - LPHEADSCROLL lphs; - lphs = ScrollBarGetStorageHeader(hwnd); - if (lphs == NULL) return 0; - return lphs->CurVal; + WND *wndPtr; + if (nBar != SB_CTL) { + wndPtr = WIN_FindWndPtr(hWnd); + if (nBar == SB_VERT) return wndPtr->hWndVScroll; + if (nBar == SB_HORZ) return wndPtr->hWndHScroll; + return (HWND)NULL; + } + return hWnd; } - -void GetScrollRange(HWND hwnd, int nBar, LPINT lpMin, LPINT lpMax) -{ - LPHEADSCROLL lphs; - lphs = ScrollBarGetStorageHeader(hwnd); - if (lphs == NULL) return; - *lpMin = lphs->MinVal; - *lpMax = lphs->MaxVal; -} - - - +/************************************************************************* + * SetScrollPos [USER.62] + */ int SetScrollPos(HWND hwnd, int nBar, int nPos, BOOL bRedraw) { int nRet; LPHEADSCROLL lphs; + hwnd = GetScrollWindowHandle(hwnd, nBar); lphs = ScrollBarGetStorageHeader(hwnd); if (lphs == NULL) return 0; nRet = lphs->CurVal; @@ -383,9 +347,27 @@ int SetScrollPos(HWND hwnd, int nBar, int nPos, BOOL bRedraw) +/************************************************************************* + * GetScrollPos [USER.63] + */ +int GetScrollPos(HWND hwnd, int nBar) +{ + LPHEADSCROLL lphs; + hwnd = GetScrollWindowHandle(hwnd, nBar); + lphs = ScrollBarGetStorageHeader(hwnd); + if (lphs == NULL) return 0; + return lphs->CurVal; +} + + + +/************************************************************************* + * SetScrollRange [USER.64] + */ void SetScrollRange(HWND hwnd, int nBar, int MinPos, int MaxPos, BOOL bRedraw) { LPHEADSCROLL lphs; + hwnd = GetScrollWindowHandle(hwnd, nBar); lphs = ScrollBarGetStorageHeader(hwnd); if (lphs == NULL) return; lphs->MinVal = (short)MinPos; @@ -406,5 +388,50 @@ void SetScrollRange(HWND hwnd, int nBar, int MinPos, int MaxPos, BOOL bRedraw) +/************************************************************************* + * GetScrollRange [USER.65] + */ +void GetScrollRange(HWND hwnd, int nBar, LPINT lpMin, LPINT lpMax) +{ + LPHEADSCROLL lphs; + hwnd = GetScrollWindowHandle(hwnd, nBar); + lphs = ScrollBarGetStorageHeader(hwnd); + if (lphs == NULL) return; + *lpMin = lphs->MinVal; + *lpMax = lphs->MaxVal; +} + + + +/************************************************************************* + * ShowScrollBar [USER.267] + */ +void ShowScrollBar(HWND hWnd, WORD wBar, BOOL bFlag) +{ + WND *wndPtr; +#ifdef DEBUG_SCROLL + printf("ShowScrollBar hWnd=%04X wBar=%d bFlag=%d\n", hWnd, wBar, bFlag); +#endif + if (wBar == SB_CTL) { + if (bFlag) + ShowWindow(hWnd, SW_SHOW); + else + ShowWindow(hWnd, SW_HIDE); + return; + } + wndPtr = WIN_FindWndPtr(hWnd); + if ((wBar == SB_VERT) || (wBar == SB_BOTH)) { + if (bFlag) + ShowWindow(wndPtr->hWndVScroll, SW_SHOW); + else + ShowWindow(wndPtr->hWndVScroll, SW_HIDE); + } + if ((wBar == SB_HORZ) || (wBar == SB_BOTH)) { + if (bFlag) + ShowWindow(wndPtr->hWndHScroll, SW_SHOW); + else + ShowWindow(wndPtr->hWndHScroll, SW_HIDE); + } +} diff --git a/controls/static.c b/controls/static.c index 692813973d8..558110b6659 100644 --- a/controls/static.c +++ b/controls/static.c @@ -109,6 +109,18 @@ LONG StaticWndProc(HWND hWnd, WORD uMsg, WORD wParam, LONG lParam) InvalidateRect(hWnd, NULL, TRUE); break; + case WM_KEYDOWN: + case WM_KEYUP: + case WM_CHAR: + case WM_LBUTTONDOWN: + case WM_LBUTTONUP: + case WM_MBUTTONDOWN: + case WM_MBUTTONUP: + case WM_RBUTTONDOWN: + case WM_RBUTTONUP: + case WM_MOUSEMOVE: + return(SendMessage(wndPtr->hwndParent, uMsg, wParam, lParam)); + default: lResult = DefWindowProc(hWnd, uMsg, wParam, lParam); break; diff --git a/controls/widgets.c b/controls/widgets.c index 673348685a9..c88ac448a07 100644 --- a/controls/widgets.c +++ b/controls/widgets.c @@ -13,23 +13,28 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; LONG ButtonWndProc( HWND hwnd, WORD message, WORD wParam, LONG lParam ); LONG StaticWndProc( HWND hwnd, WORD message, WORD wParam, LONG lParam ); - -LONG SCROLLBAR_ScrollBarWndProc( HWND hwnd, WORD message, - WORD wParam, LONG lParam ); -LONG LISTBOX_ListBoxWndProc( HWND hwnd, WORD message, - WORD wParam, LONG lParam ); -LONG COMBOBOX_ComboBoxWndProc( HWND hwnd, WORD message, - WORD wParam, LONG lParam ); +LONG ScrollBarWndProc( HWND hwnd, WORD message, WORD wParam, LONG lParam ); +LONG ListBoxWndProc ( HWND hwnd, WORD message, WORD wParam, LONG lParam ); +LONG ComboBoxWndProc ( HWND hwnd, WORD message, WORD wParam, LONG lParam ); +LONG PopupMenuWndProc ( HWND hwnd, WORD message, WORD wParam, LONG lParam ); static WNDCLASS WIDGETS_BuiltinClasses[] = { - { 0, (LONG(*)())ButtonWndProc, 0, 2, 0, 0, 0, 0, NULL, "BUTTON" }, - { 0, (LONG(*)())StaticWndProc, 0, 0, 0, 0, 0, 0, NULL, "STATIC" }, - { 0, (LONG(*)())SCROLLBAR_ScrollBarWndProc, 0, 8, 0, 0, 0, 0, NULL, "SCROLLBAR" }, - { 0, (LONG(*)())LISTBOX_ListBoxWndProc, 0, 8, 0, 0, 0, 0, NULL, "LISTBOX" }, - { 0, (LONG(*)())COMBOBOX_ComboBoxWndProc, 0, 8, 0, 0, 0, 0, NULL, "COMBOBOX" }, - { 0, (LONG(*)())DefDlgProc, 0, DLGWINDOWEXTRA, 0, 0, 0, 0, NULL, DIALOG_CLASS_NAME } + { CS_GLOBALCLASS, (LONG(*)())ButtonWndProc, 0, 2, + 0, 0, 0, 0, NULL, "BUTTON" }, + { CS_GLOBALCLASS, (LONG(*)())StaticWndProc, 0, 0, + 0, 0, 0, 0, NULL, "STATIC" }, + { CS_GLOBALCLASS, (LONG(*)())ScrollBarWndProc, 0, 8, + 0, 0, 0, 0, NULL, "SCROLLBAR" }, + { CS_GLOBALCLASS, (LONG(*)())ListBoxWndProc, 0, 8, + 0, 0, 0, 0, NULL, "LISTBOX" }, + { CS_GLOBALCLASS, (LONG(*)())ComboBoxWndProc, 0, 8, + 0, 0, 0, 0, NULL, "COMBOBOX" }, + { CS_GLOBALCLASS, (LONG(*)())PopupMenuWndProc, 0, 8, + 0, 0, 0, 0, NULL, "POPUPMENU" }, + { CS_GLOBALCLASS, (LONG(*)())DefDlgProc, 0, DLGWINDOWEXTRA, + 0, 0, 0, 0, NULL, DIALOG_CLASS_NAME } }; #define NB_BUILTIN_CLASSES \ diff --git a/debugger/Imakefile b/debugger/Imakefile new file mode 100644 index 00000000000..4b4ed0442c9 --- /dev/null +++ b/debugger/Imakefile @@ -0,0 +1,62 @@ +#include "../Wine.tmpl" + +#define IHavSubDirs +#define PassCDebugFlags 'CDEBUGFLAGS=$(CDEBUGFLAGS)' 'CC=$(CC)' + +MODULE = debugger + +DEFINES = -DUSE_READLINE + +SUBDIRS = readline + +/* Quick and dirt hack, since i386 is defined as 1. sigh */ +#define temp i386 +#undef i386 + +SRCS = \ + dbg.tab.c \ + hash.c \ + lex.yy.c \ + info.c \ + i386-pinsn.c + +OBJS = \ + dbg.tab.o \ + hash.o \ + lex.yy.o \ + info.o \ + i386-pinsn.o + +#define i386 temp +#undef temp + +/* + * All the SUBDIR stuff + */ +MakeSubdirs($(SUBDIRS)) +MakefileSubdirs($(SUBDIRS)) +DependSubdirs($(SUBDIRS)) +CleanSubdirs($(SUBDIRS)) +IncludesSubdirs($(SUBDIRS)) + +/* + * The main act + */ +WineRelocatableTarget($(TOP)/$(MODULE),,$(OBJS)) + +depend:: dbg.tab.c dbg.tab.h lex.yy.c + +DependTarget() + +includes:: + +install:: + +clean:: + $(RM) lex.yy.c dbg.tab* y.tab.c + +dbg.tab.c dbg.tab.h: dbg.y + $(YACC) -b dbg -d dbg.y + +lex.yy.c: debug.l + $(LEX) -I debug.l diff --git a/debugger/readline/Imakefile b/debugger/readline/Imakefile new file mode 100644 index 00000000000..817f4afea06 --- /dev/null +++ b/debugger/readline/Imakefile @@ -0,0 +1,25 @@ +#include "../../Wine.tmpl" + +MODULE = readline + +YACC = yacc -b dbg -d + +DEFINES = -DANSI_ARROWS -DHAVE_TCGETATTR -DHIDE -DUSE_DIRENT -DSYS_UNIX + +SRCS = \ + complete.c \ + editline.c \ + sysunix.c + +OBJS = \ + complete.o \ + editline.o \ + sysunix.o + +WineRelocatableTarget($(TOP)/$(MODULE),,$(OBJS)) +DependTarget() +CleanTarget() + +includes:: + +install:: diff --git a/etc/Imakefile b/etc/Imakefile new file mode 100644 index 00000000000..b39880926cc --- /dev/null +++ b/etc/Imakefile @@ -0,0 +1,11 @@ +#include "../Wine.tmpl" + +MODULE = etc + +AllTarget() + +depend:: + +CleanTarget() + +includes:: diff --git a/etc/Makefile b/etc/Makefile new file mode 100644 index 00000000000..87948b04a9d --- /dev/null +++ b/etc/Makefile @@ -0,0 +1,358 @@ +# Makefile generated by imake - do not edit! +# $XConsortium: imake.c,v 1.65 91/07/25 17:50:17 rws Exp $ + +# ------------------------------------------------------------------------- +# Makefile generated from "Imake.tmpl" and +# $XFree86: mit/config/Imake.tmpl,v 1.17 1993/06/03 15:26:36 dawes Exp $ +# $XConsortium: Imake.tmpl,v 1.139 91/09/16 08:52:48 rws Exp $ +# +# Platform-specific parameters may be set in the appropriate .cf +# configuration files. Site-specific parameters should be set in the file +# site.def. Full rebuilds are recommended if any parameters are changed. +# +# If your C preprocessor does not define any unique symbols, you will need +# to set BOOTSTRAPCFLAGS when rebuilding imake (usually when doing +# "make World" the first time). +# + +# ------------------------------------------------------------------------- +# site-specific configuration parameters that need to come before +# the platform-specific parameters - edit site.def to change + +# $XFree86: mit/config/site.def,v 1.65 1993/06/04 16:02:47 dawes Exp $ +# site: $XConsortium: site.def,v 1.2 91/07/30 20:26:44 rws Exp $ + +# obz: changes for making Linux distribution + +# ------------------------------------------------------------------------- +# platform-specific configuration parameters - edit x386.cf to change + +# $XFree86: mit/config/x386.cf,v 1.90 1993/06/04 16:02:50 dawes Exp $ +# platform: $XConsortium: x386.cf,v 1.7 91/08/16 19:30:10 gildea Exp $ + +# ------------------------------------------------------------------------- +# XFree86 version definition +# $XFree86: mit/config/xf86_vers.def,v 1.5 1993/06/01 09:12:47 dawes Exp $ + +# ------------------------------------------------------------------------- +# XFree86 version: 1300 +# ------------------------------------------------------------------------- + +# $XFree86: mit/config/lnuxLib.rules,v 1.2 1993/06/02 13:48:12 dawes Exp $ + +DLL_BINDIR = /usr/dll/bin + +# operating system: Linux + +# ------------------------------------------------------------------------- +# site-specific configuration parameters that go after +# the platform-specific parameters - edit site.def to change + +# $XFree86: mit/config/site.def,v 1.65 1993/06/04 16:02:47 dawes Exp $ +# site: $XConsortium: site.def,v 1.2 91/07/30 20:26:44 rws Exp $ + +# obz: changes for making Linux distribution + + SHELL = /bin/sh + + TOP = ../. + CURRENT_DIR = ./etc + + AR = ar clq + BOOTSTRAPCFLAGS = + CC = gcc + AS = as + + LEX = flex + + YACC = bison -y + + COMPRESS = compress + CPP = /lib/cpp $(STD_CPP_DEFINES) + PREPROCESSCMD = /lib/cpp $(STD_CPP_DEFINES) + INSTALL = install + LD = ld + LINT = lint + LINTLIBFLAG = -C + LINTOPTS = -axz + LN = ln -s + MAKE = make + MV = mv + CP = cp + + RANLIB = ranlib + RANLIBINSTFLAGS = + + RM = rm -f + TROFF = psroff + MSMACROS = -ms + TBL = tbl + EQN = eqn + STD_INCLUDES = + STD_CPP_DEFINES = -traditional -D_POSIX_SOURCE -D_BSD_SOURCE -D_GNU_SOURCE -Dlinux + STD_DEFINES = -D_POSIX_SOURCE -D_BSD_SOURCE -D_GNU_SOURCE -Dlinux + EXTRA_LOAD_FLAGS = + EXTRA_LIBRARIES = + OS_LIBRARIES = + TAGS = ctags + + SHAREDCODEDEF = + SHLIBDEF = + + PROTO_DEFINES = -DFUNCPROTO=11 -DNARROWPROTO + + INSTPGMFLAGS = -s + + INSTBINFLAGS = -m 0755 + INSTUIDFLAGS = -s -m 4755 + INSTLIBFLAGS = -m 0644 + INSTINCFLAGS = -m 0444 + INSTMANFLAGS = -m 0444 + INSTDATFLAGS = -m 0444 + INSTKMEMFLAGS = -s -m 4755 + + PROJECTROOT = /usr/X386 + + TOP_INCLUDES = -I$(INCROOT) + + CDEBUGFLAGS = -O2 + CCOPTIONS = -m486 -DNO_ASM -fwritable-strings + ANSICCOPTIONS = + + ALLINCLUDES = $(INCLUDES) $(EXTRA_INCLUDES) $(TOP_INCLUDES) $(STD_INCLUDES) + ALLDEFINES = $(ALLINCLUDES) $(STD_DEFINES) $(EXTRA_DEFINES) $(PROTO_DEFINES) $(DEFINES) + CFLAGS = $(ANSICCOPTIONS) $(CDEBUGFLAGS) $(CCOPTIONS) $(ALLDEFINES) + LINTFLAGS = $(LINTOPTS) -DLINT $(ALLDEFINES) + + LDLIBS = $(OS_LIBRARIES) $(SYS_LIBRARIES) $(EXTRA_LIBRARIES) + + LDOPTIONS = $(ANSICCOPTIONS) $(CDEBUGFLAGS) $(CCOPTIONS) $(LOCAL_LDFLAGS) -L$(USRLIBDIR) + + LDCOMBINEFLAGS = -r + DEPENDFLAGS = + + MACROFILE = x386.cf + RM_CMD = $(RM) *.CKP *.ln *.BAK *.bak *.o core errs ,* *~ *.a .emacs_* tags TAGS make.log MakeOut + + IMAKE_DEFINES = + + IRULESRC = $(CONFIGDIR) + IMAKE_CMD = $(IMAKE) -DUseInstalled -I$(IRULESRC) $(IMAKE_DEFINES) + + ICONFIGFILES = $(IRULESRC)/Imake.tmpl $(IRULESRC)/Imake.rules $(IRULESRC)/Project.tmpl $(IRULESRC)/site.def $(IRULESRC)/$(MACROFILE) $(EXTRA_ICONFIGFILES) + +# ------------------------------------------------------------------------- +# X Window System Build Parameters +# $XFree86: mit/config/Project.tmpl,v 1.13 1993/03/27 03:32:45 dawes Exp $ +# $XConsortium: Project.tmpl,v 1.138.1.1 92/11/11 09:49:19 rws Exp $ + +_percentC_ = %C + +# ------------------------------------------------------------------------- +# X Window System make variables; this need to be coordinated with rules + + PATHSEP = / + USRLIBDIR = /usr/X386/lib + BINDIR = /usr/X386/bin + INCROOT = /usr/X386/include + BUILDINCROOT = $(TOP) + BUILDINCDIR = $(BUILDINCROOT)/X11 + BUILDINCTOP = .. + INCDIR = $(INCROOT)/X11 + ADMDIR = /usr/adm + LIBDIR = $(USRLIBDIR)/X11 + CONFIGDIR = $(LIBDIR)/config + LINTLIBDIR = $(USRLIBDIR)/lint + + FONTDIR = $(LIBDIR)/fonts + XINITDIR = $(LIBDIR)/xinit + XDMDIR = $(LIBDIR)/xdm + TWMDIR = $(LIBDIR)/twm + MANPATH = /usr/X386/man + MANSOURCEPATH = $(MANPATH)/man + MANSUFFIX = 1x + LIBMANSUFFIX = 3x + MANDIR = $(MANSOURCEPATH)1 + LIBMANDIR = $(MANSOURCEPATH)3 + NLSDIR = $(LIBDIR)/nls + PEXAPIDIR = $(LIBDIR)/PEX + XAPPLOADDIR = $(LIBDIR)/app-defaults + FONTCFLAGS = -t + LINKKITDIR = $(USRLIBDIR)/Server + + INSTAPPFLAGS = $(INSTDATFLAGS) + + IMAKE = imake + DEPEND = makedepend + RGB = rgb + + FONTC = bdftopcf + + MKFONTDIR = mkfontdir + MKDIRHIER = /bin/sh $(BINDIR)/mkdirhier + + CONFIGSRC = $(TOP)/config + DOCUTILSRC = $(TOP)/doc/util + CLIENTSRC = $(TOP)/clients + DEMOSRC = $(TOP)/demos + LIBSRC = $(TOP)/lib + FONTSRC = $(TOP)/fonts + INCLUDESRC = $(TOP)/X11 + SERVERSRC = $(TOP)/server + UTILSRC = $(TOP)/util + SCRIPTSRC = $(UTILSRC)/scripts + EXAMPLESRC = $(TOP)/examples + CONTRIBSRC = $(TOP)/../contrib + DOCSRC = $(TOP)/doc + RGBSRC = $(TOP)/rgb + DEPENDSRC = $(UTILSRC)/makedepend + IMAKESRC = $(CONFIGSRC) + XAUTHSRC = $(LIBSRC)/Xau + XLIBSRC = $(LIBSRC)/X + XMUSRC = $(LIBSRC)/Xmu + TOOLKITSRC = $(LIBSRC)/Xt + AWIDGETSRC = $(LIBSRC)/Xaw + OLDXLIBSRC = $(LIBSRC)/oldX + XDMCPLIBSRC = $(LIBSRC)/Xdmcp + BDFTOSNFSRC = $(FONTSRC)/bdftosnf + BDFTOSNFSRC = $(FONTSRC)/clients/bdftosnf + BDFTOPCFSRC = $(FONTSRC)/clients/bdftopcf + MKFONTDIRSRC = $(FONTSRC)/clients/mkfontdir + FSLIBSRC = $(FONTSRC)/lib/fs + FONTSERVERSRC = $(FONTSRC)/server + EXTENSIONSRC = $(TOP)/extensions + XILIBSRC = $(EXTENSIONSRC)/lib/xinput + PEXLIBSRC = $(EXTENSIONSRC)/lib/PEXlib + PHIGSLIBSRC = $(EXTENSIONSRC)/lib/PEX + +# $XFree86: mit/config/lnuxLib.tmpl,v 1.1 1993/04/16 14:06:06 dawes Exp $ + +SHLIBLDFLAGS = +PICFLAGS = -B/usr/dll/jump/ + + DEPEXTENSIONLIB = + EXTENSIONLIB = -lXext + + DEPXLIB = $(DEPEXTENSIONLIB) + XLIB = $(EXTENSIONLIB) -lX11 + + DEPXMULIB = + XMULIB = -lXmu + + DEPXTOOLLIB = + XTOOLLIB = -lXt + + DEPXAWLIB = + XAWLIB = -lXaw + + DEPXILIB = + XILIB = -lXi + + DEPXTESTLIB = + XTESTLIB = -lXtst + + DEPPEXLIB = + PEXLIB = -lPEX5 + + SOXLIBREV = 3.0.1 + SOXTREV = 3.0.1 + SOXAWREV = 3.0.1 + SOOLDXREV = 3.0.1 + SOXMUREV = 3.0.1 + SOXEXTREV = 3.0.1 + SOXINPUTREV = 3.0.1 + SOPEXREV = 1.0.1 + + DEPXAUTHLIB = $(USRLIBDIR)/libXau.a + XAUTHLIB = -lXau + DEPXDMCPLIB = $(USRLIBDIR)/libXdmcp.a + XDMCPLIB = -lXdmcp + + DEPOLDXLIB = $(USRLIBDIR)/liboldX.a + OLDXLIB = -loldX + + DEPPHIGSLIB = $(USRLIBDIR)/libphigs.a + PHIGSLIB = -lphigs + + DEPXBSDLIB = $(USRLIBDIR)/libXbsd.a + XBSDLIB = -lXbsd + + LINTEXTENSIONLIB = $(LINTLIBDIR)/llib-lXext.ln + LINTXLIB = $(LINTLIBDIR)/llib-lX11.ln + LINTXMU = $(LINTLIBDIR)/llib-lXmu.ln + LINTXTOOL = $(LINTLIBDIR)/llib-lXt.ln + LINTXAW = $(LINTLIBDIR)/llib-lXaw.ln + LINTXI = $(LINTLIBDIR)/llib-lXi.ln + LINTPEX = $(LINTLIBDIR)/llib-lPEX5.ln + LINTPHIGS = $(LINTLIBDIR)/llib-lphigs.ln + + DEPLIBS = $(DEPXAWLIB) $(DEPXMULIB) $(DEPXTOOLLIB) $(DEPXLIB) + + DEPLIBS1 = $(DEPLIBS) + DEPLIBS2 = $(DEPLIBS) + DEPLIBS3 = $(DEPLIBS) + +# ------------------------------------------------------------------------- +# Imake rules for building libraries, programs, scripts, and data files +# $XFree86: mit/config/Imake.rules,v 1.9 1993/03/23 12:56:27 dawes Exp $ +# rules: $XConsortium: Imake.rules,v 1.123 91/09/16 20:12:16 rws Exp $ + +# ------------------------------------------------------------------------- +# start of Imakefile + +# $Id$ + +INCLUDES = -I$(TOP)/include + +# Imake rules go here + +# First, dll description to files etc + +MODULE = etc + +all:: + +depend:: + +clean:: + $(RM_CMD) "#"* + +includes:: + +# ------------------------------------------------------------------------- +# common rules for all Makefiles - do not edit + +emptyrule:: + +clean:: + $(RM_CMD) "#"* + +Makefile:: + -@if [ -f Makefile ]; then set -x; \ + $(RM) Makefile.bak; $(MV) Makefile Makefile.bak; \ + else exit 0; fi + $(IMAKE_CMD) -DTOPDIR=$(TOP) -DCURDIR=$(CURRENT_DIR) + +tags:: + $(TAGS) -w *.[ch] + $(TAGS) -xw *.[ch] > TAGS + +# ------------------------------------------------------------------------- +# empty rules for directories that do not have SUBDIRS - do not edit + +install:: + @echo "install in $(CURRENT_DIR) done" + +install.man:: + @echo "install.man in $(CURRENT_DIR) done" + +install.linkkit:: + @echo "install.linkkit in $(CURRENT_DIR) done" + +Makefiles:: + +includes:: + +# ------------------------------------------------------------------------- +# dependencies generated by makedepend + diff --git a/if1632/Imakefile b/if1632/Imakefile new file mode 100644 index 00000000000..8c11afdfe95 --- /dev/null +++ b/if1632/Imakefile @@ -0,0 +1,37 @@ +#include "../Wine.tmpl" + +MODULE = if1632 + +SRCS = \ + call.S \ + callback.c \ + relay.c + +OBJS = \ + call.o \ + callback.o \ + relay.o + +/* + * If you add a new spec file, copy one of these lines + */ +MakeDllFromSpec(gdi,$(TOP)/$(MODULE)) +MakeDllFromSpec(kernel,$(TOP)/$(MODULE)) +MakeDllFromSpec(keyboard,$(TOP)/$(MODULE)) +MakeDllFromSpec(shell,$(TOP)/$(MODULE)) +MakeDllFromSpec(sound,$(TOP)/$(MODULE)) +MakeDllFromSpec(unixlib,$(TOP)/$(MODULE)) +MakeDllFromSpec(user,$(TOP)/$(MODULE)) +MakeDllFromSpec(win87em,$(TOP)/$(MODULE)) + +/* + * Yes I know *.o is not veru clever, but can you do it cleaner ? + */ +WineRelocatableTarget($(TOP)/$(MODULE),*.o,$(OBJS)) + +clean:: + $(RM) dll* + +depend:: + +includes:: diff --git a/if1632/callback.c b/if1632/callback.c index 1852185f8d5..82c71de459b 100644 --- a/if1632/callback.c +++ b/if1632/callback.c @@ -7,7 +7,7 @@ static char Copyright[] = "Copyright Robert J. Amstadt, 1993"; #include "segmem.h" #include -extern unsigned short SelectorOwners[]; +extern SEGDESC Segments[]; extern unsigned short IF1632_Saved16_ss; extern unsigned long IF1632_Saved16_ebp; extern unsigned long IF1632_Saved16_esp; @@ -56,7 +56,7 @@ FindDataSegmentForCode(unsigned long csip) unsigned int seg_idx; seg_idx = (unsigned short) (csip >> 19); - return SelectorOwners[seg_idx]; + return Segments[seg_idx].owner; } /********************************************************************** diff --git a/if1632/gdi.spec b/if1632/gdi.spec index a1fc5c59847..f2e2baae437 100644 --- a/if1632/gdi.spec +++ b/if1632/gdi.spec @@ -43,6 +43,11 @@ length 490 33 pascal TextOut(word s_word s_word ptr word) TextOut(1 2 3 4 5) 34 pascal BitBlt( word s_word s_word s_word s_word word s_word s_word long) BitBlt(1 2 3 4 5 6 7 8 9) +35 pascal StrechBlt( word s_word s_word s_word s_word word s_word s_word s_word s_word long) + StrechBlt(1 2 3 4 5 6 7 8 9 10 11) + +36 pascal Polygon (word ptr word) Polygon (1 2 3) +37 pascal Polyline (word ptr word) Polyline (1 2 3) 39 pascal RestoreDC(word s_word) RestoreDC(1 2) 40 pascal FillRgn(word word word) FillRgn(1 2 3) 43 pascal PaintRgn(word word) PaintRgn(1 2) diff --git a/if1632/kernel.spec b/if1632/kernel.spec index 142f4512f59..86a15087b2d 100644 --- a/if1632/kernel.spec +++ b/if1632/kernel.spec @@ -28,6 +28,8 @@ length 415 24 pascal UnlockSegment(s_word) KERNEL_UnlockSegment(1) 25 pascal GlobalCompact(long) GlobalCompact(1) 30 pascal WaitEvent(word) KERNEL_WaitEvent(1) +34 pascal SetTaskQueue(word word) SetTaskQueue(1 2) +35 pascal GetTaskQueue(word) GetTaskQueue(1) 49 pascal GetModuleFileName(word ptr s_word) KERNEL_GetModuleFileName(1 2 3) 50 pascal GetProcAddress(word ptr) GetProcAddress(1 2) 51 pascal MakeProcInstance(ptr word) CALLBACK_MakeProcInstance(1 2) @@ -43,6 +45,8 @@ length 415 74 pascal OpenFile(ptr ptr word) KERNEL_OpenFile(1 2 3) 81 pascal _lclose(word) KERNEL__lclose(1) 82 pascal _lread(word ptr word) KERNEL__lread(1 2 3) +83 pascal _lcreate(ptr word) KERNEL__lcreate(1 2) +84 pascal _llseek(word long word) KERNEL__llseek(1 2 3) 85 pascal _lopen(ptr word) KERNEL__lopen(1 2) 86 pascal _lwrite(word ptr word) KERNEL__lwrite(1 2 3) 88 pascal lstrcpy(ptr ptr) lstrcpy(1 2) @@ -51,11 +55,14 @@ length 415 91 register InitTask(word word word word word word word word word word) KERNEL_InitTask() +92 pascal GetTempDrive(byte) GetTempDrive(1) 95 pascal LoadLibrary(ptr) LoadLibrary(1) 96 pascal FreeLibrary(word) FreeLibrary(1) +97 pascal GetTempFileName(byte ptr word ptr) GetTempDrive(1 2 3 4) 102 register DOS3Call(word word word word word word word word word word) KERNEL_DOS3Call() +107 pascal SetErrorMode(word) SetErrorMode(1) 111 pascal GlobalWire(word) GlobalLock(1) 112 pascal GlobalUnWire(word) GlobalUnlock(1) 115 pascal OutputDebugString(ptr) OutputDebugString(1) @@ -68,6 +75,9 @@ length 415 WritePrivateProfileString(1 2 3 4) 131 pascal GetDOSEnvironment() GetDOSEnvironment() 132 return GetWinFlags 0 0x413 +134 pascal GetWindowsDirectory(ptr word) GetWindowsDirectory(1 2) +135 pascal GetSystemDirectory(ptr word) GetSystemDirectory(1 2) +136 pascal GetDriveType(byte) GetWindowsDirectory(1) 154 return GlobalNotify 4 0 163 pascal GlobalLRUOldest(word) ReturnArg(1) 164 pascal GlobalLRUNewest(word) ReturnArg(1) diff --git a/if1632/relay.c b/if1632/relay.c index 859144c7274..d6ad3353fdb 100644 --- a/if1632/relay.c +++ b/if1632/relay.c @@ -173,7 +173,7 @@ DLLRelay(unsigned int func_num, unsigned int seg_off) case DLL_ARGTYPE_FARPTR: ip = (int *) ((char *) arg_ptr + offset); if (*ip & 0xffff0000) - arg_table[i] = SAFEMAKEPTR((unsigned) *ip >> 16, *ip); + arg_table[i] = FIXPTR(*ip); else arg_table[i] = *ip; break; diff --git a/if1632/user.spec b/if1632/user.spec index bf032d68149..86682f18c6e 100644 --- a/if1632/user.spec +++ b/if1632/user.spec @@ -13,12 +13,16 @@ length 540 13 pascal GetTickCount() GetTickCount() 14 return GetTimerResolution 0 1000 15 pascal GetCurrentTime() GetTickCount() +16 pascal ClipCursor(ptr) ClipCursor(1) +17 pascal GetCursorPos(ptr) GetCursorPos(1) 18 pascal SetCapture(word) SetCapture(1) 19 pascal ReleaseCapture() ReleaseCapture() 20 pascal SetDoubleClickTime(word) SetDoubleClickTime(1) 21 pascal GetDoubleClickTime() GetDoubleClickTime() 22 pascal SetFocus(word) SetFocus(1) 23 pascal GetFocus() GetFocus() +28 pascal ClientToScreen(word ptr) ClientToScreen(1 2) +29 pascal ScreenToClient(word ptr) ScreenToClient(1 2) 31 pascal IsIconic(word) IsIconic(1) 32 pascal GetWindowRect(word ptr) GetWindowRect(1 2) 33 pascal GetClientRect(word ptr) GetClientRect(1 2) @@ -41,13 +45,18 @@ length 540 56 pascal MoveWindow(word word word word word word) MoveWindow(1 2 3 4 5 6) 57 pascal RegisterClass(ptr) RegisterClass(1) +58 pascal GetClassName(word ptr word) GetClassName(1 2 3) 61 pascal ScrollWindow(word s_word s_word ptr ptr) ScrollWindow(1 2 3 4 5) 62 pascal SetScrollPos(word word word word) SetScrollPos(1 2 3 4) +63 pascal GetScrollPos(word word) GetScrollPos(1 2) 64 pascal SetScrollRange(word word word word word) SetScrollRange(1 2 3 4 5) +65 pascal GetScrollRange(word word ptr ptr) GetScrollRange(1 2 3 4) 66 pascal GetDC(word) GetDC(1) +67 pascal GetWindowDC(word) GetWindowDC(1) 68 pascal ReleaseDC(word word) ReleaseDC(1 2) -69 pascal SetCursor(word word) SetCursor(1 2) -71 pascal ShowCursor(word word) ShowCursor(1 2) +69 pascal SetCursor(word) SetCursor(1) +70 pascal SetCursorPos(word word) SetCursorPos(1 2) +71 pascal ShowCursor(word) ShowCursor(1) 72 pascal SetRect(ptr s_word s_word s_word s_word) SetRect(1 2 3 4 5) 73 pascal SetRectEmpty(ptr) SetRectEmpty(1) 74 pascal CopyRect(ptr ptr) CopyRect(1 2) @@ -67,7 +76,7 @@ length 540 89 pascal CreateDialog(word ptr word ptr) CreateDialog(1 2 3 4) 90 pascal IsDialogMessage(word ptr) IsDialogMessage(1 2) 91 pascal GetDlgItem(word word) GetDlgItem(1 2) -92 pascal SetDlgItemText(word ptr) SetDlgItemText(1 2) +92 pascal SetDlgItemText(word word ptr) SetDlgItemText(1 2 3) 93 pascal GetDlgItemText(word word ptr word) GetDlgItemText(1 2 3 4) 94 pascal SetDlgItemInt(word word word word) SetDlgItemInt(1 2 3 4) 95 pascal GetDlgItemInt(word word ptr word) GetDlgItemInt(1 2 3 4) @@ -106,9 +115,18 @@ length 540 136 pascal SetWindowLong(word s_word long) SetWindowLong(1 2 3) 150 pascal LoadMenu(word ptr) LoadMenu(1 2) 151 pascal CreateMenu() CreateMenu() -154 pascal CheckMenu(word word word) CheckMenu(1 2 3) +152 pascal DestroyMenu(word) DestroyMenu(1) +154 pascal CheckMenuItem(word word word) CheckMenuItem(1 2 3) +155 pascal EnableMenuItem(word word word) EnableMenuItem(1 2 3) 157 pascal GetMenu(word) GetMenu(1) 158 pascal SetMenu(word word) SetMenu(1 2) +163 pascal CreateCaret(word word word word) CreateCaret(1 2 3 4) +164 pascal DestroyCaret() DestroyCaret() +165 pascal SetCaretPos(word word) SetCaretPos(1 2) +166 pascal HideCaret(word) HideCaret(1) +167 pascal ShowCaret(word) ShowCaret(1) +166 pascal SetCaretBlinkTime(word) SetCaretBlinkTime(1) +169 pascal GetCaretBlinkTime() GetCaretBlinkTime() 171 pascal WinHelp(word word long) WinHelp(1 2 3) 173 pascal LoadCursor(word ptr) LoadCursor(1 2) 174 pascal LoadIcon(word ptr) LoadIcon(1 2) @@ -119,7 +137,24 @@ length 540 180 pascal GetSysColor(word) GetSysColor(1) 181 pascal SetSysColors(word ptr ptr) SetSysColors(1 2 3) 182 pascal KillSystemTimer(word word) KillSystemTimer(1 2) +183 pascal GetCaretPos(ptr) GetCaretPos(1) 190 pascal GetUpdateRect(word ptr word) GetUpdateRect(1 2 3) +200 pascal OpenComm(ptr word word) OpenComm(1 2 3) +201 pascal SetCommState(ptr) SetCommState(1) +202 pascal GetCommState(word ptr) GetCommState(1 2) +203 pascal GetCommError(word ptr) GetCommError(1 2) +204 pascal ReadComm(word ptr word) ReadComm(1 2 3) +205 pascal WriteComm(word ptr word) WriteComm(1 2 3) +206 pascal TransmitCommChar(word byte) TransmitCommChar (1 2) +207 pascal CloseComm(word) CloseComm(1) +208 pascal SetCommEventMask(word word) SetCommEventMask(1 2) +209 pascal GetCommEventMask(word word) GetCommEventMask(1 2) +210 pascal SetCommBreak(word) SetCommBreak(1) +211 pascal ClearCommBreak(word) ClearCommBreak(1) +212 pascal UngetCommChar(word byte) UngetCommChar(1 2) +213 pascal BuildCommDCB(ptr ptr) BuildCommDCB(1 2) +214 pascal EscapeCommFunction(word word) EscapeCommFunction(1 2) +215 pascal FlushComm(word word) FlushComm(1 2) 218 pascal DialogBoxIndirect(word word word ptr) DialogBoxIndirect(1 2 3 4) 219 pascal CreateDialogIndirect(word ptr word ptr) CreateDialogIndirect(1 2 3 4) @@ -131,6 +166,7 @@ length 540 230 pascal GetNextWindow(word word) GetNextWindow(1 2) 232 pascal SetWindowPos(word word word word word word word) SetWindowPos(1 2 3 4 5 6 7) +236 pascal GetCapture() GetCapture() 237 pascal GetUpdateRgn(word word word) GetUpdateRgn(1 2 3) 239 pascal DialogBoxParam(word ptr word ptr long) DialogBoxParam(1 2 3 4 5) 240 pascal DialogBoxIndirectParam(word word word ptr long) @@ -140,9 +176,14 @@ length 540 242 pascal CreateDialogIndirectParam(word ptr word ptr long) CreateDialogIndirectParam(1 2 3 4 5) 244 pascal EqualRect(ptr ptr) EqualRect(1 2) +258 pascal MapWindowPoints(word word ptr word) MapWindowPoints(1 2 3 4) 262 pascal GetWindow(word word) GetWindow(1 2) 266 pascal SetMessageQueue(word) SetMessageQueue(1) +267 pascal ShowScrollBar(word word word) ShowScrollBar(1 2 3) +272 pascal IsZoomed(word) IsZoomed(1) 277 pascal GetDlgCtrlID(word) GetDlgCtrlID(1) +282 pascal SelectPalette(word word word) SelectPalette(1 2 3) +283 pascal RealizePalette(word) RealizePalette(1) 286 pascal GetDesktopWindow() GetDesktopWindow() 288 pascal GetMessageExtraInfo() GetMessageExtraInfo() 319 pascal ScrollWindowEx(word s_word s_word ptr ptr word ptr word) @@ -151,9 +192,20 @@ length 540 325 pascal PaintRect(word word word word ptr) PaintRect(1 2 3 4 5) 334 pascal GetQueueStatus(word) GetQueueStatus(1) 335 pascal GetInputState() GetInputState() +359 pascal GetDCEx(word word long) GetDCEx(1 2 3) 373 pascal SubtractRect(ptr ptr ptr) SubtractRect(1 2 3) 403 pascal UnregisterClass(ptr word) UnregisterClass(1 2) +404 pascal GetClassInfo(word ptr ptr) GetClassInfo(1 2 3) +406 pascal CreateCursor(word word word word word ptr ptr) + CreateCursor(1 2 3 4 5 6 7) +410 pascal InsertMenu(word word word word ptr) InsertMenu(1 2 3 4 5) 411 pascal AppendMenu(word word word ptr) AppendMenu(1 2 3 4) +412 pascal RemoveMenu(word word word) RemoveMenu(1 2 3) +413 pascal DeleteMenu(word word word) DeleteMenu(1 2 3) +414 pascal ModifyMenu(word word word word ptr) ModifyMenu(1 2 3 4 5) +415 pascal CreatePopupMenu() CreatePopupMenu() +416 pascal TrackPopupMenu(word word word word word word ptr) + TrackPopupMenu(1 2 3 4 5 6 7) 420 pascal wsprintf(ptr ptr) wsprintf(1 2) 421 pascal wvsprintf(ptr ptr ptr) wvsprintf(1 2 3) 430 pascal lstrcmp(ptr ptr) lstrcmp(1 2) diff --git a/include/Imakefile b/include/Imakefile new file mode 100644 index 00000000000..4e3798738ac --- /dev/null +++ b/include/Imakefile @@ -0,0 +1,38 @@ +#include "../Wine.tmpl" + +MODULE = include + +HEADERS = \ + atom.h \ + callback.h \ + class.h \ + combo.h \ + cursor.h \ + dce.h \ + dialog.h \ + dlls.h \ + files.h \ + gdi.h \ + heap.h \ + icon.h \ + int21.h \ + listbox.h \ + menu.h \ + message.h \ + neexe.h \ + prototypes.h \ + regfunc.h \ + scroll.h \ + segmem.h \ + user.h \ + win.h \ + windows.h \ + wine.h + +AllTarget() + +depend:: + +CleanTarget() + +includes:: diff --git a/include/Makefile b/include/Makefile new file mode 100644 index 00000000000..97bc6f4a06b --- /dev/null +++ b/include/Makefile @@ -0,0 +1,360 @@ +# Makefile generated by imake - do not edit! +# $XConsortium: imake.c,v 1.65 91/07/25 17:50:17 rws Exp $ + +# ------------------------------------------------------------------------- +# Makefile generated from "Imake.tmpl" and +# $XFree86: mit/config/Imake.tmpl,v 1.17 1993/06/03 15:26:36 dawes Exp $ +# $XConsortium: Imake.tmpl,v 1.139 91/09/16 08:52:48 rws Exp $ +# +# Platform-specific parameters may be set in the appropriate .cf +# configuration files. Site-specific parameters should be set in the file +# site.def. Full rebuilds are recommended if any parameters are changed. +# +# If your C preprocessor does not define any unique symbols, you will need +# to set BOOTSTRAPCFLAGS when rebuilding imake (usually when doing +# "make World" the first time). +# + +# ------------------------------------------------------------------------- +# site-specific configuration parameters that need to come before +# the platform-specific parameters - edit site.def to change + +# $XFree86: mit/config/site.def,v 1.65 1993/06/04 16:02:47 dawes Exp $ +# site: $XConsortium: site.def,v 1.2 91/07/30 20:26:44 rws Exp $ + +# obz: changes for making Linux distribution + +# ------------------------------------------------------------------------- +# platform-specific configuration parameters - edit x386.cf to change + +# $XFree86: mit/config/x386.cf,v 1.90 1993/06/04 16:02:50 dawes Exp $ +# platform: $XConsortium: x386.cf,v 1.7 91/08/16 19:30:10 gildea Exp $ + +# ------------------------------------------------------------------------- +# XFree86 version definition +# $XFree86: mit/config/xf86_vers.def,v 1.5 1993/06/01 09:12:47 dawes Exp $ + +# ------------------------------------------------------------------------- +# XFree86 version: 1300 +# ------------------------------------------------------------------------- + +# $XFree86: mit/config/lnuxLib.rules,v 1.2 1993/06/02 13:48:12 dawes Exp $ + +DLL_BINDIR = /usr/dll/bin + +# operating system: Linux + +# ------------------------------------------------------------------------- +# site-specific configuration parameters that go after +# the platform-specific parameters - edit site.def to change + +# $XFree86: mit/config/site.def,v 1.65 1993/06/04 16:02:47 dawes Exp $ +# site: $XConsortium: site.def,v 1.2 91/07/30 20:26:44 rws Exp $ + +# obz: changes for making Linux distribution + + SHELL = /bin/sh + + TOP = ../. + CURRENT_DIR = ./include + + AR = ar clq + BOOTSTRAPCFLAGS = + CC = gcc + AS = as + + LEX = flex + + YACC = bison -y + + COMPRESS = compress + CPP = /lib/cpp $(STD_CPP_DEFINES) + PREPROCESSCMD = /lib/cpp $(STD_CPP_DEFINES) + INSTALL = install + LD = ld + LINT = lint + LINTLIBFLAG = -C + LINTOPTS = -axz + LN = ln -s + MAKE = make + MV = mv + CP = cp + + RANLIB = ranlib + RANLIBINSTFLAGS = + + RM = rm -f + TROFF = psroff + MSMACROS = -ms + TBL = tbl + EQN = eqn + STD_INCLUDES = + STD_CPP_DEFINES = -traditional -D_POSIX_SOURCE -D_BSD_SOURCE -D_GNU_SOURCE -Dlinux + STD_DEFINES = -D_POSIX_SOURCE -D_BSD_SOURCE -D_GNU_SOURCE -Dlinux + EXTRA_LOAD_FLAGS = + EXTRA_LIBRARIES = + OS_LIBRARIES = + TAGS = ctags + + SHAREDCODEDEF = + SHLIBDEF = + + PROTO_DEFINES = -DFUNCPROTO=11 -DNARROWPROTO + + INSTPGMFLAGS = -s + + INSTBINFLAGS = -m 0755 + INSTUIDFLAGS = -s -m 4755 + INSTLIBFLAGS = -m 0644 + INSTINCFLAGS = -m 0444 + INSTMANFLAGS = -m 0444 + INSTDATFLAGS = -m 0444 + INSTKMEMFLAGS = -s -m 4755 + + PROJECTROOT = /usr/X386 + + TOP_INCLUDES = -I$(INCROOT) + + CDEBUGFLAGS = -O2 + CCOPTIONS = -m486 -DNO_ASM -fwritable-strings + ANSICCOPTIONS = + + ALLINCLUDES = $(INCLUDES) $(EXTRA_INCLUDES) $(TOP_INCLUDES) $(STD_INCLUDES) + ALLDEFINES = $(ALLINCLUDES) $(STD_DEFINES) $(EXTRA_DEFINES) $(PROTO_DEFINES) $(DEFINES) + CFLAGS = $(ANSICCOPTIONS) $(CDEBUGFLAGS) $(CCOPTIONS) $(ALLDEFINES) + LINTFLAGS = $(LINTOPTS) -DLINT $(ALLDEFINES) + + LDLIBS = $(OS_LIBRARIES) $(SYS_LIBRARIES) $(EXTRA_LIBRARIES) + + LDOPTIONS = $(ANSICCOPTIONS) $(CDEBUGFLAGS) $(CCOPTIONS) $(LOCAL_LDFLAGS) -L$(USRLIBDIR) + + LDCOMBINEFLAGS = -r + DEPENDFLAGS = + + MACROFILE = x386.cf + RM_CMD = $(RM) *.CKP *.ln *.BAK *.bak *.o core errs ,* *~ *.a .emacs_* tags TAGS make.log MakeOut + + IMAKE_DEFINES = + + IRULESRC = $(CONFIGDIR) + IMAKE_CMD = $(IMAKE) -DUseInstalled -I$(IRULESRC) $(IMAKE_DEFINES) + + ICONFIGFILES = $(IRULESRC)/Imake.tmpl $(IRULESRC)/Imake.rules $(IRULESRC)/Project.tmpl $(IRULESRC)/site.def $(IRULESRC)/$(MACROFILE) $(EXTRA_ICONFIGFILES) + +# ------------------------------------------------------------------------- +# X Window System Build Parameters +# $XFree86: mit/config/Project.tmpl,v 1.13 1993/03/27 03:32:45 dawes Exp $ +# $XConsortium: Project.tmpl,v 1.138.1.1 92/11/11 09:49:19 rws Exp $ + +_percentC_ = %C + +# ------------------------------------------------------------------------- +# X Window System make variables; this need to be coordinated with rules + + PATHSEP = / + USRLIBDIR = /usr/X386/lib + BINDIR = /usr/X386/bin + INCROOT = /usr/X386/include + BUILDINCROOT = $(TOP) + BUILDINCDIR = $(BUILDINCROOT)/X11 + BUILDINCTOP = .. + INCDIR = $(INCROOT)/X11 + ADMDIR = /usr/adm + LIBDIR = $(USRLIBDIR)/X11 + CONFIGDIR = $(LIBDIR)/config + LINTLIBDIR = $(USRLIBDIR)/lint + + FONTDIR = $(LIBDIR)/fonts + XINITDIR = $(LIBDIR)/xinit + XDMDIR = $(LIBDIR)/xdm + TWMDIR = $(LIBDIR)/twm + MANPATH = /usr/X386/man + MANSOURCEPATH = $(MANPATH)/man + MANSUFFIX = 1x + LIBMANSUFFIX = 3x + MANDIR = $(MANSOURCEPATH)1 + LIBMANDIR = $(MANSOURCEPATH)3 + NLSDIR = $(LIBDIR)/nls + PEXAPIDIR = $(LIBDIR)/PEX + XAPPLOADDIR = $(LIBDIR)/app-defaults + FONTCFLAGS = -t + LINKKITDIR = $(USRLIBDIR)/Server + + INSTAPPFLAGS = $(INSTDATFLAGS) + + IMAKE = imake + DEPEND = makedepend + RGB = rgb + + FONTC = bdftopcf + + MKFONTDIR = mkfontdir + MKDIRHIER = /bin/sh $(BINDIR)/mkdirhier + + CONFIGSRC = $(TOP)/config + DOCUTILSRC = $(TOP)/doc/util + CLIENTSRC = $(TOP)/clients + DEMOSRC = $(TOP)/demos + LIBSRC = $(TOP)/lib + FONTSRC = $(TOP)/fonts + INCLUDESRC = $(TOP)/X11 + SERVERSRC = $(TOP)/server + UTILSRC = $(TOP)/util + SCRIPTSRC = $(UTILSRC)/scripts + EXAMPLESRC = $(TOP)/examples + CONTRIBSRC = $(TOP)/../contrib + DOCSRC = $(TOP)/doc + RGBSRC = $(TOP)/rgb + DEPENDSRC = $(UTILSRC)/makedepend + IMAKESRC = $(CONFIGSRC) + XAUTHSRC = $(LIBSRC)/Xau + XLIBSRC = $(LIBSRC)/X + XMUSRC = $(LIBSRC)/Xmu + TOOLKITSRC = $(LIBSRC)/Xt + AWIDGETSRC = $(LIBSRC)/Xaw + OLDXLIBSRC = $(LIBSRC)/oldX + XDMCPLIBSRC = $(LIBSRC)/Xdmcp + BDFTOSNFSRC = $(FONTSRC)/bdftosnf + BDFTOSNFSRC = $(FONTSRC)/clients/bdftosnf + BDFTOPCFSRC = $(FONTSRC)/clients/bdftopcf + MKFONTDIRSRC = $(FONTSRC)/clients/mkfontdir + FSLIBSRC = $(FONTSRC)/lib/fs + FONTSERVERSRC = $(FONTSRC)/server + EXTENSIONSRC = $(TOP)/extensions + XILIBSRC = $(EXTENSIONSRC)/lib/xinput + PEXLIBSRC = $(EXTENSIONSRC)/lib/PEXlib + PHIGSLIBSRC = $(EXTENSIONSRC)/lib/PEX + +# $XFree86: mit/config/lnuxLib.tmpl,v 1.1 1993/04/16 14:06:06 dawes Exp $ + +SHLIBLDFLAGS = +PICFLAGS = -B/usr/dll/jump/ + + DEPEXTENSIONLIB = + EXTENSIONLIB = -lXext + + DEPXLIB = $(DEPEXTENSIONLIB) + XLIB = $(EXTENSIONLIB) -lX11 + + DEPXMULIB = + XMULIB = -lXmu + + DEPXTOOLLIB = + XTOOLLIB = -lXt + + DEPXAWLIB = + XAWLIB = -lXaw + + DEPXILIB = + XILIB = -lXi + + DEPXTESTLIB = + XTESTLIB = -lXtst + + DEPPEXLIB = + PEXLIB = -lPEX5 + + SOXLIBREV = 3.0.1 + SOXTREV = 3.0.1 + SOXAWREV = 3.0.1 + SOOLDXREV = 3.0.1 + SOXMUREV = 3.0.1 + SOXEXTREV = 3.0.1 + SOXINPUTREV = 3.0.1 + SOPEXREV = 1.0.1 + + DEPXAUTHLIB = $(USRLIBDIR)/libXau.a + XAUTHLIB = -lXau + DEPXDMCPLIB = $(USRLIBDIR)/libXdmcp.a + XDMCPLIB = -lXdmcp + + DEPOLDXLIB = $(USRLIBDIR)/liboldX.a + OLDXLIB = -loldX + + DEPPHIGSLIB = $(USRLIBDIR)/libphigs.a + PHIGSLIB = -lphigs + + DEPXBSDLIB = $(USRLIBDIR)/libXbsd.a + XBSDLIB = -lXbsd + + LINTEXTENSIONLIB = $(LINTLIBDIR)/llib-lXext.ln + LINTXLIB = $(LINTLIBDIR)/llib-lX11.ln + LINTXMU = $(LINTLIBDIR)/llib-lXmu.ln + LINTXTOOL = $(LINTLIBDIR)/llib-lXt.ln + LINTXAW = $(LINTLIBDIR)/llib-lXaw.ln + LINTXI = $(LINTLIBDIR)/llib-lXi.ln + LINTPEX = $(LINTLIBDIR)/llib-lPEX5.ln + LINTPHIGS = $(LINTLIBDIR)/llib-lphigs.ln + + DEPLIBS = $(DEPXAWLIB) $(DEPXMULIB) $(DEPXTOOLLIB) $(DEPXLIB) + + DEPLIBS1 = $(DEPLIBS) + DEPLIBS2 = $(DEPLIBS) + DEPLIBS3 = $(DEPLIBS) + +# ------------------------------------------------------------------------- +# Imake rules for building libraries, programs, scripts, and data files +# $XFree86: mit/config/Imake.rules,v 1.9 1993/03/23 12:56:27 dawes Exp $ +# rules: $XConsortium: Imake.rules,v 1.123 91/09/16 20:12:16 rws Exp $ + +# ------------------------------------------------------------------------- +# start of Imakefile + +# $Id$ + +INCLUDES = -I$(TOP)/include + +# Imake rules go here + +# First, dll description to files etc + +MODULE = include + +HEADERS = atom.h callback.h class.h combo.h cursor.h dce.h dialog.h dlls.h files.h gdi.h heap.h icon.h int21.h listbox.h menu.h message.h neexe.h prototypes.h regfunc.h scroll.h segmem.h user.h win.h windows.h wine.h + +all:: + +depend:: + +clean:: + $(RM_CMD) "#"* + +includes:: + +# ------------------------------------------------------------------------- +# common rules for all Makefiles - do not edit + +emptyrule:: + +clean:: + $(RM_CMD) "#"* + +Makefile:: + -@if [ -f Makefile ]; then set -x; \ + $(RM) Makefile.bak; $(MV) Makefile Makefile.bak; \ + else exit 0; fi + $(IMAKE_CMD) -DTOPDIR=$(TOP) -DCURDIR=$(CURRENT_DIR) + +tags:: + $(TAGS) -w *.[ch] + $(TAGS) -xw *.[ch] > TAGS + +# ------------------------------------------------------------------------- +# empty rules for directories that do not have SUBDIRS - do not edit + +install:: + @echo "install in $(CURRENT_DIR) done" + +install.man:: + @echo "install.man in $(CURRENT_DIR) done" + +install.linkkit:: + @echo "install.linkkit in $(CURRENT_DIR) done" + +Makefiles:: + +includes:: + +# ------------------------------------------------------------------------- +# dependencies generated by makedepend + diff --git a/include/atom.h b/include/atom.h new file mode 100644 index 00000000000..61cf6b1b7c7 --- /dev/null +++ b/include/atom.h @@ -0,0 +1,27 @@ +/* + * Atom table definitions + * + * Copyright 1993 Alexandre Julliard + */ + +#ifndef ATOM_H +#define ATOM_H + +#include "windows.h" + + +typedef struct +{ + HANDLE next; + WORD refCount; + BYTE length; + BYTE str[1]; +} ATOMENTRY; + +typedef struct +{ + WORD size; + HANDLE entries[1]; +} ATOMTABLE; + +#endif /* ATOM_H */ diff --git a/include/class.h b/include/class.h index 9ab50e4e2f5..285e81bf746 100644 --- a/include/class.h +++ b/include/class.h @@ -17,7 +17,7 @@ typedef struct tagCLASS HCLASS hNext; /* Next class */ WORD wMagic; /* Magic number (must be CLASS_MAGIC) */ ATOM atomName; /* Name of the class */ - HDC hdc; /* Class DC (if CS_CLASSDC) */ + HANDLE hdce; /* Class DCE (if CS_CLASSDC) */ WORD cWindows; /* Count of existing windows of this class */ WNDCLASS wc __attribute__ ((packed)); /* Class information */ WORD wExtra[1]; /* Class extra bytes */ diff --git a/include/dce.h b/include/dce.h index eff58a5a890..d95c7812e6a 100644 --- a/include/dce.h +++ b/include/dce.h @@ -9,16 +9,27 @@ #include "windows.h" +typedef enum +{ + DCE_CACHE_DC, /* This is a cached DC (allocated by USER) */ + DCE_CLASS_DC, /* This is a class DC (style CS_CLASSDC) */ + DCE_WINDOW_DC /* This is a window DC (style CS_OWNDC) */ +} DCE_TYPE; + + typedef struct tagDCE { HANDLE hNext; HWND hwndCurrent; HDC hdc; - BYTE flags; + DCE_TYPE type; BOOL inUse; WORD xOrigin; WORD yOrigin; } DCE; +extern HANDLE DCE_AllocDCE( DCE_TYPE type ); +extern void DCE_FreeDCE( HANDLE hdce ); + #endif /* DCE_H */ diff --git a/include/files.h b/include/files.h deleted file mode 100644 index 1b628a23d4f..00000000000 --- a/include/files.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef _FILES_H -#define _FILES_H - -#define OPEN_MAX 256 - -/*************************************************************************** - This structure stores the infomation needed for a single DOS drive - ***************************************************************************/ -struct DosDriveStruct -{ - char RootDirectory [256]; /* Unix base for this drive letter */ - char CurrentDirectory [256]; /* Current directory for this drive */ - char VolumeLabel [11]; - unsigned long serialnumber; -}; - -#endif /*_FILES_H*/ diff --git a/include/gdi.h b/include/gdi.h index bb5b6323b27..aade98d919f 100644 --- a/include/gdi.h +++ b/include/gdi.h @@ -7,7 +7,7 @@ #ifndef GDI_H #define GDI_H -#include +#include #include "windows.h" #include "segmem.h" @@ -158,6 +158,8 @@ typedef struct WORD MapMode; short DCOrgX; /* DC origin */ short DCOrgY; + short DCSizeX; /* DC dimensions */ + short DCSizeY; short CursPosX; /* Current position */ short CursPosY; short WndOrgX; @@ -200,7 +202,6 @@ typedef struct { GC gc; /* X Window GC */ Drawable drawable; - Widget widget; X_PHYSFONT font; X_PHYSPEN pen; X_PHYSBRUSH brush; diff --git a/include/int21.h b/include/int21.h index 92cabc559da..f44c9a433fa 100644 --- a/include/int21.h +++ b/include/int21.h @@ -1,15 +1,40 @@ #ifndef INT21_H #define INT21_H +#include + +struct dosdirent { + int inuse; + DIR *ds; + char unixpath[256]; + char filename[256]; + char attribute; + long filesize; + long filetime; + long filedate; +}; + +struct diskinfo { + unsigned int infolevel; + unsigned long serialnumber; + char label[11]; + char fstype[8]; +}; #define DosVersion 0x0303; #define SectorSize 0x200; #define SectorsPerCluster 0x04; -#define AX context->sc_eax -#define BX context->sc_ebx -#define CX context->sc_ecx -#define DX context->sc_edx +#define EAX context->sc_eax +#define EBX context->sc_ebx +#define ECX context->sc_ecx +#define EDX context->sc_edx + +#define AX (context->sc_eax & 0x0000ffffL) +#define BX (context->sc_ebx & 0x0000ffffL) +#define CX (context->sc_ecx & 0x0000ffffL) +#define DX (context->sc_edx & 0x0000ffffL) + #define ES context->sc_es #define DS context->sc_ds #define DI context->sc_edi @@ -22,13 +47,6 @@ #define SetCflag (context->sc_efl |= 0x00000001L) #define ResetCflag (context->sc_efl &= 0xfffffffeL) -struct diskinfo { - WORD infolevel; - DWORD serialnumber; - char label[11]; - char fstype[8]; -}; - /* extended error codes */ #define NoError 0x00 diff --git a/include/listbox.h b/include/listbox.h index f44cf8ce8ee..5d89f9eba22 100644 --- a/include/listbox.h +++ b/include/listbox.h @@ -14,16 +14,17 @@ typedef LISTSTRUCT FAR* LPLISTSTRUCT; typedef struct tagHEADLIST { short FirstVisible; - short ItemSelect; short ItemsCount; short ItemsVisible; - short ItemSelected; - short PrevSelected; + short ColumnsVisible; + short ItemsPerColumn; + short ItemFocused; + short PrevFocused; short StdItemHeight; + short ColumnsWidth; short DrawCtlType; void *lpFirst; DWORD dwStyle; - HWND hWndScroll; HWND hWndLogicParent; } HEADLIST; typedef HEADLIST FAR* LPHEADLIST; diff --git a/include/menu.h b/include/menu.h index 15d251adf53..edc0bec12b0 100644 --- a/include/menu.h +++ b/include/menu.h @@ -27,7 +27,10 @@ typedef struct tagMENUITEM Widget w; Widget menu_w; char menu_name[10]; -} MENUITEM; + RECT rect; + HBITMAP hCheckBit; + HBITMAP hUnCheckBit; +} MENUITEM, *LPMENUITEM; typedef struct tagMENUBAR { @@ -40,6 +43,16 @@ typedef struct tagMENUBAR MENUITEM *firstItem; } MENUBAR, *LPMENUBAR; +typedef struct tagPOPUPMENU +{ + HWND hWnd; /* PopupMenu window handle */ + HWND ownerWnd; /* Owner window */ + WORD nItems; /* Number of items on menu */ + MENUITEM *firstItem; + WORD FocusedItem; + WORD MouseFlags; +} POPUPMENU, *LPPOPUPMENU; + typedef struct { WORD version; /* Should be zero */ diff --git a/include/message.h b/include/message.h index 0bbfc9a3ef0..d64b4fcbb2f 100644 --- a/include/message.h +++ b/include/message.h @@ -12,8 +12,8 @@ /* Message as stored in the queue (contains the extraInfo field) */ typedef struct tagQMSG { + DWORD extraInfo; /* Only in 3.1 */ MSG msg; - DWORD extraInfo __attribute__ ((packed)); /* Only in 3.1 */ } QMSG; @@ -28,17 +28,28 @@ typedef struct tagMESSAGEQUEUE WORD queueSize; /* Size of the queue */ DWORD GetMessageTimeVal; /* Value returned by GetMessageTime */ DWORD GetMessagePosVal; /* Value returned by GetMessagePos */ - WORD GetMessageExtraInfoVal; /* Value returned by GetMessageExtraInfo */ - DWORD lParam; /* Next four values set by SetMessage */ + DWORD GetMessageExtraInfoVal; /* Value returned by GetMessageExtraInfo */ + DWORD lParam; /* Next four values set by SendMessage */ WORD wParam; WORD msg; WORD hWnd; WORD wPostQMsg; /* PostQuitMessage flag */ WORD wExitCode; /* PostQuitMessage exit code */ WORD InSendMessageHandle; /* Handle of task that sent a message */ + WORD wPaintCount; /* Number of WM_PAINT needed */ + WORD wTimerCount; /* Number of timers for this application */ WORD tempStatus; /* State reset by GetQueueStatus */ WORD status; /* Queue state */ QMSG messages[1]; /* Queue messages */ } MESSAGEQUEUE; + +extern void MSG_IncPaintCount( HANDLE hQueue ); +extern void MSG_DecPaintCount( HANDLE hQueue ); +extern void MSG_IncTimerCount( HANDLE hQueue ); +extern void MSG_DecTimerCount( HANDLE hQueue ); +extern BOOL MSG_CreateSysMsgQueue( int size ); +extern void hardware_event(HWND hwnd, WORD message, WORD wParam, LONG lParam, + WORD xPos, WORD yPos, DWORD time, DWORD extraInfo); + #endif /* MESSAGE_H */ diff --git a/include/neexe.h b/include/neexe.h index e610ba45ad0..58e67ccc275 100644 --- a/include/neexe.h +++ b/include/neexe.h @@ -136,7 +136,9 @@ struct relocation_entry_s /* Used by Windows 3.0 programs, like when getting selector to be given to makeprocinst */ #define NE_RELTYPE_INT1 4 -#define NE_RELTYPE_OFFSET16 5 +#define NE_RELTYPE_ORDINALADD 5 +#define NE_RELTYPE_NAMEADD 6 + /* * DOS PSP */ diff --git a/include/prototypes.h b/include/prototypes.h index c1c7bf9f483..69fc97bd4a9 100644 --- a/include/prototypes.h +++ b/include/prototypes.h @@ -10,6 +10,7 @@ #include "neexe.h" #include "segmem.h" #include "wine.h" +#include "int21.h" extern struct segment_descriptor_s * CreateSelectors(struct w_files *); @@ -33,5 +34,15 @@ extern int CurrentNEFile; extern do_int1A(struct sigcontext_struct * context); extern do_int21(struct sigcontext_struct * context); -#endif /* PROTOTYPES_H */ +extern void GetUnixDirName(char *rootdir, char *name); +extern char *GetDirectUnixFileName(char *dosfilename); +extern char *GetUnixFileName(char *dosfilename); +extern char *FindFile(char *buffer, int buflen, char *rootname, char **extensions, char *path); +extern char *WineIniFileName(void); +extern char *WinIniFileName(void); +extern struct dosdirent *DOS_opendir(char *dosdirname); +extern struct dosdirent *DOS_readdir(struct dosdirent *de); +extern void DOS_closedir(struct dosdirent *de); + +#endif /* PROTOTYPES_H */ diff --git a/include/segmem.h b/include/segmem.h index ea9f8512402..437dfd98c38 100644 --- a/include/segmem.h +++ b/include/segmem.h @@ -6,6 +6,12 @@ #ifndef SEGMEM_H #define SEGMEM_H +#ifdef __linux__ +#define HAVE_IPC +#include +#include +#endif + /* * Array to track selector allocation. */ @@ -15,21 +21,32 @@ extern unsigned short SelectorMap[MAX_SELECTORS]; +#ifdef HAVE_IPC +#define SAFEMAKEPTR(s, o) (((int) (s) << 16) | ((o) & 0xffff)) +#define FIXPTR(p) (p) +#else #define SAFEMAKEPTR(s, o) \ (((int) SelectorMap[SelectorMap[(s) >> 3] & SELECTOR_INDEXMASK] << 19) \ | 0x70000 | ((o) & 0xffff)) +#define FIXPTR(p) SAFEMAKEPTR((unsigned long) (p) >> 16, (p)) +#endif /* * Structure to hold info about each selector we create. */ -struct segment_descriptor_s +typedef struct segment_descriptor_s { void *base_addr; /* Pointer to segment in flat memory */ unsigned int length; /* Length of segment */ unsigned int flags; /* Segment flags (see neexe.h and below)*/ unsigned short selector; /* Selector used to access this segment */ -}; + unsigned short owner; /* Handle of owner program */ + unsigned char type; /* DATA or CODE */ +#ifdef HAVE_IPC + key_t shm_key; /* Shared memory key or IPC_PRIVATE */ +#endif +} SEGDESC; /* * Additional flags diff --git a/include/user.h b/include/user.h index 3db21d2dc82..3b9867db86b 100644 --- a/include/user.h +++ b/include/user.h @@ -15,6 +15,8 @@ extern MDESC *USER_Heap; #define USER_HEAP_ALLOC(f,size) ((int)HEAP_Alloc(&USER_Heap,f,size) & 0xffff) +#define USER_HEAP_REALLOC(handle,size,f) ((int)HEAP_ReAlloc(&USER_Heap, \ + USER_HEAP_ADDR(handle),size,f) & 0xffff) #define USER_HEAP_ADDR(handle) ((void *)(handle|((int)USER_Heap & 0xffff0000))) #define USER_HEAP_FREE(handle) (HEAP_Free(&USER_Heap,USER_HEAP_ADDR(handle))) diff --git a/include/win.h b/include/win.h index 894da98ff12..b90675db260 100644 --- a/include/win.h +++ b/include/win.h @@ -8,8 +8,6 @@ #define WIN_H #include -#include -#include #include "windows.h" #include "menu.h" @@ -26,31 +24,41 @@ typedef struct tagWND HWND hwndOwner; /* Window owner */ HCLASS hClass; /* Window class */ HANDLE hInstance; /* Window hInstance (from CreateWindow) */ - RECT rectClient; /* Window client area screen coords */ - RECT rectWindow; /* Window whole area screen coords */ + RECT rectClient; /* Client area rel. to parent client area */ + RECT rectWindow; /* Whole window rel. to parent client area */ + HANDLE hmemTaskQ; /* Task queue global memory handle */ HRGN hrgnUpdate; /* Update region */ HWND hwndLastActive; /* Last active popup hwnd */ FARPROC lpfnWndProc; /* Window procedure */ DWORD dwStyle; /* Window style (from CreateWindow) */ DWORD dwExStyle; /* Extended style (from CreateWindowEx) */ - HDC hdc; /* Window DC (if CS_OWNDC) */ + HANDLE hdce; /* Window DCE (if CS_OWNDC or CS_CLASSDC) */ HMENU hmenuSystem; /* System menu */ + HCURSOR hCursor; /* Window Current Cursor */ + HWND hWndVScroll; /* Verti. ScrollBar handle of the window */ + HWND hWndHScroll; /* Horiz. ScrollBar handle of the window */ WORD wIDmenu; /* ID or hmenu (from CreateWindow) */ HANDLE hText; /* Handle of window text */ WORD flags; /* Misc. flags */ Widget shellWidget; /* For top-level windows */ Widget winWidget; /* For all windows */ Widget compositeWidget;/* For top-level windows */ + Window window; /* X window */ LPMENUBAR menuBarPtr; /* Menu bar */ WORD wExtra[1]; /* Window extra bytes */ } WND; /* WND flags values */ -#define WIN_ERASE_UPDATERGN 1 /* Update region needs erasing */ - +#define WIN_ERASE_UPDATERGN 0x01 /* Update region needs erasing */ +#define WIN_NEEDS_BEGINPAINT 0x02 /* WM_PAINT sent to window */ +#define WIN_GOT_SIZEMSG 0x04 /* WM_SIZE has been sent to the window */ +#define WIN_OWN_DC 0x08 /* Win class has style CS_OWNDC */ +#define WIN_CLASS_DC 0x10 /* Win class has style CS_CLASSDC */ /* Window functions */ -WND * WIN_FindWndPtr( HWND hwnd ); +WND *WIN_FindWndPtr( HWND hwnd ); +BOOL WIN_UnlinkWindow( HWND hwnd ); +BOOL WIN_LinkWindow( HWND hwnd, HWND hwndInsertAfter ); HWND WIN_FindWinToRepaint( HWND hwnd ); diff --git a/include/windows.h b/include/windows.h index 9d3eaf3ba76..ae37d54da4e 100644 --- a/include/windows.h +++ b/include/windows.h @@ -64,7 +64,8 @@ typedef int *LPCATCHBUF; #define LOWORD(l) ((WORD)(l)) #define HIWORD(l) ((WORD)((DWORD)(l) >> 16)) -#define MAKELONG(low, high) ((LONG)(((WORD)(low)) | (((DWORD)((WORD)(high))) << 16))) +#define MAKELONG(low, high) ((LONG)(((WORD)(low)) | \ + (((DWORD)((WORD)(high))) << 16))) #ifndef max #define max(a,b) (((a) > (b)) ? (a) : (b)) @@ -208,6 +209,36 @@ typedef struct { #define GW_OWNER 4 #define GW_CHILD 5 + /* WM_WINDOWPOSCHANGING/CHANGED struct */ +typedef struct +{ + HWND hwnd; + HWND hwndInsertAfter; + int x; + int y; + int cx; + int cy; + UINT flags; +} WINDOWPOS; + + /* WM_NCCALCSIZE parameter structure */ +typedef struct +{ + RECT rgrc[3]; + WINDOWPOS FAR* lppos; +} NCCALCSIZE_PARAMS; + + /* WM_NCCALCSIZE return flags */ +#define WVR_ALIGNTOP 0x0010 +#define WVR_ALIGNLEFT 0x0020 +#define WVR_ALIGNBOTTOM 0x0040 +#define WVR_ALIGNRIGHT 0x0080 +#define WVR_HREDRAW 0x0100 +#define WVR_VREDRAW 0x0200 +#define WVR_REDRAW (WVR_HREDRAW | WVR_VREDRAW) +#define WVR_VALIDRECTS 0x0400 + + /* Dialogs */ /* cbWndExtra bytes for dialog class */ @@ -275,6 +306,9 @@ typedef struct tagMSG typedef WORD ATOM; +#define MAKEINTATOM(i) ((LPCSTR)MAKELP(0, (i))) + + /* Raster operations */ #define R2_BLACK 1 @@ -558,6 +592,19 @@ typedef struct tagLOGPEN #define RGN_DIFF 4 #define RGN_COPY 5 + /* Device contexts */ + +/* GetDCEx flags */ +#define DCX_WINDOW 0x00000001 +#define DCX_CACHE 0x00000002 +#define DCX_CLIPCHILDREN 0x00000008 +#define DCX_CLIPSIBLINGS 0x00000010 +#define DCX_PARENTCLIP 0x00000020 +#define DCX_EXCLUDERGN 0x00000040 +#define DCX_INTERSECTRGN 0x00000080 +#define DCX_LOCKWINDOWUPDATE 0x00000400 +#define DCX_USESTYLE 0x00010000 + /* Polygon modes */ #define ALTERNATE 1 #define WINDING 2 @@ -797,18 +844,6 @@ typedef struct tagBITMAPCOREHEADER #define DIB_PAL_COLORS 1 #define CBM_INIT 4 - -/* Unimplemented structs */ -typedef struct { - BYTE Id; /* much more .... */ -} DCB; - -typedef struct { - BYTE i; /* much more .... */ -} COMSTAT; - - - typedef struct { BYTE i; /* much more .... */ } KANJISTRUCT; @@ -842,6 +877,160 @@ typedef OFSTRUCT *LPOFSTRUCT; #define OF_SHARE_EXCLUSIVE 0x0010 #define OF_VERIFY 0x0400 +#define DRIVE_REMOVABLE 2 +#define DRIVE_FIXED 3 +#define DRIVE_REMOTE 4 + +#define HFILE_ERROR -1 + +#define DDL_READWRITE 0x0000 +#define DDL_READONLY 0x0001 +#define DDL_HIDDEN 0x0002 +#define DDL_SYSTEM 0x0004 +#define DDL_DIRECTORY 0x0010 +#define DDL_ARCHIVE 0x0020 + +#define DDL_POSTMSGS 0x2000 +#define DDL_DRIVES 0x4000 +#define DDL_EXCLUSIVE 0x8000 + +/* comm */ + +#define CBR_110 0xFF10 +#define CBR_300 0xFF11 +#define CBR_600 0xFF12 +#define CBR_1200 0xFF13 +#define CBR_2400 0xFF14 +#define CBR_4800 0xFF15 +#define CBR_9600 0xFF16 +#define CBR_14400 0xFF17 +#define CBR_19200 0xFF18 +#define CBR_38400 0xFF1B +#define CBR_56000 0xFF1F +#define CBR_128000 0xFF23 +#define CBR_256000 0xFF27 + +#define NOPARITY 0 +#define ODDPARITY 1 +#define EVENPARITY 2 +#define MARKPARITY 3 +#define SPACEPARITY 4 +#define ONESTOPBIT 0 +#define ONE5STOPBITS 1 +#define TWOSTOPBITS 2 +#define IGNORE 0 +#define INFINITE 0xFFFF + +#define CE_RXOVER 0x0001 +#define CE_OVERRUN 0x0002 +#define CE_RXPARITY 0x0004 +#define CE_FRAME 0x0008 +#define CE_BREAK 0x0010 +#define CE_CTSTO 0x0020 +#define CE_DSRTO 0x0040 +#define CE_RLSDTO 0x0080 +#define CE_TXFULL 0x0100 +#define CE_PTO 0x0200 +#define CE_IOE 0x0400 +#define CE_DNS 0x0800 +#define CE_OOP 0x1000 +#define CE_MODE 0x8000 + +#define IE_BADID -1 +#define IE_OPEN -2 +#define IE_NOPEN -3 +#define IE_MEMORY -4 +#define IE_DEFAULT -5 +#define IE_HARDWARE -10 +#define IE_BYTESIZE -11 +#define IE_BAUDRATE -12 + +#define EV_RXCHAR 0x0001 +#define EV_RXFLAG 0x0002 +#define EV_TXEMPTY 0x0004 +#define EV_CTS 0x0008 +#define EV_DSR 0x0010 +#define EV_RLSD 0x0020 +#define EV_BREAK 0x0040 +#define EV_ERR 0x0080 +#define EV_RING 0x0100 +#define EV_PERR 0x0200 +#define EV_CTSS 0x0400 +#define EV_DSRS 0x0800 +#define EV_RLSDS 0x1000 +#define EV_RINGTE 0x2000 +#define EV_RingTe EV_RINGTE + +#define SETXOFF 1 +#define SETXON 2 +#define SETRTS 3 +#define CLRRTS 4 +#define SETDTR 5 +#define CLRDTR 6 +#define RESETDEV 7 +#define GETMAXLPT 8 +#define GETMAXCOM 9 +#define GETBASEIRQ 10 + +#define CN_RECEIVE 0x0001 +#define CN_TRANSMIT 0x0002 +#define CN_EVENT 0x0004 + +typedef struct tagDCB +{ + BYTE Id; + UINT BaudRate; + BYTE ByteSize; + BYTE Parity; + BYTE StopBits; + UINT RlsTimeout; + UINT CtsTimeout; + UINT DsrTimeout; + + UINT fBinary :1; + UINT fRtsDisable :1; + UINT fParity :1; + UINT fOutxCtsFlow :1; + UINT fOutxDsrFlow :1; + UINT fDummy :2; + UINT fDtrDisable :1; + + UINT fOutX :1; + UINT fInX :1; + UINT fPeChar :1; + UINT fNull :1; + UINT fChEvt :1; + UINT fDtrflow :1; + UINT fRtsflow :1; + UINT fDummy2 :1; + + char XonChar; + char XoffChar; + UINT XonLim; + UINT XoffLim; + char PeChar; + char EofChar; + char EvtChar; + UINT TxDelay; +} DCB; +typedef DCB FAR* LPDCB; + +typedef struct tagCOMSTAT +{ + BYTE status; + UINT cbInQue; + UINT cbOutQue; +} COMSTAT; + +#define CSTF_CTSHOLD 0x01 +#define CSTF_DSRHOLD 0x02 +#define CSTF_RLSDHOLD 0x04 +#define CSTF_XOFFHOLD 0x08 +#define CSTF_XOFFSENT 0x10 +#define CSTF_EOF 0x20 +#define CSTF_TXIM 0x40 + +/* */ typedef struct { @@ -903,8 +1092,12 @@ enum { WM_NULL, WM_CREATE, WM_DESTROY, WM_MOVE, WM_UNUSED0, WM_SIZE, WM_ACTIVATE WM_DELETEITEM, WM_VKEYTOITEM, WM_CHARTOITEM, WM_SETFONT, WM_GETFONT }; +#define WM_WINDOWPOSCHANGING 0x0046 +#define WM_WINDOWPOSCHANGED 0x0047 + #define WM_NCCREATE 0x0081 #define WM_NCDESTROY 0x0082 +#define WM_NCCALCSIZE 0x0083 #define WM_GETDLGCODE 0x0087 @@ -1008,6 +1201,12 @@ enum { SW_HIDE, SW_SHOWNORMAL, SW_NORMAL, SW_SHOWMINIMIZED, SW_SHOWMAXIMIZED, #define HWND_TOPMOST ((HWND)-1) #define HWND_NOTOPMOST ((HWND)-2) +/* Flags for TrackPopupMenu */ +#define TPM_LEFTBUTTON 0x0000 +#define TPM_RIGHTBUTTON 0x0002 +#define TPM_LEFTALIGN 0x0000 +#define TPM_CENTERALIGN 0x0004 +#define TPM_RIGHTALIGN 0x0008 #define MF_INSERT 0 #define MF_CHANGE 0x0080 @@ -1016,7 +1215,7 @@ enum { SW_HIDE, SW_SHOWNORMAL, SW_NORMAL, SW_SHOWMINIMIZED, SW_SHOWMAXIMIZED, #define MF_REMOVE 0x1000 #define MF_BYCOMMAND 0 #define MF_BYPOSITION 0x0400 -#define MF_SEPARATOR 0x080 +#define MF_SEPARATOR 0x0800 #define MF_ENABLED 0 #define MF_GRAYED 0x0001 #define MF_DISABLED 0x0002 @@ -1492,6 +1691,80 @@ typedef struct tagCOMPAREITEMSTRUCT typedef COMPAREITEMSTRUCT NEAR* PCOMPAREITEMSTRUCT; typedef COMPAREITEMSTRUCT FAR* LPCOMPAREITEMSTRUCT; +/* Virtual key codes */ +#define VK_LBUTTON 0x01 +#define VK_RBUTTON 0x02 +#define VK_CANCEL 0x03 +#define VK_MBUTTON 0x04 +#define VK_BACK 0x08 +#define VK_TAB 0x09 +#define VK_CLEAR 0x0C +#define VK_RETURN 0x0D +#define VK_SHIFT 0x10 +#define VK_CONTROL 0x11 +#define VK_MENU 0x12 +#define VK_PAUSE 0x13 +#define VK_CAPITAL 0x14 +#define VK_ESCAPE 0x1B +#define VK_SPACE 0x20 +#define VK_PRIOR 0x21 +#define VK_NEXT 0x22 +#define VK_END 0x23 +#define VK_HOME 0x24 +#define VK_LEFT 0x25 +#define VK_UP 0x26 +#define VK_RIGHT 0x27 +#define VK_DOWN 0x28 +#define VK_SELECT 0x29 +#define VK_PRINT 0x2A +#define VK_EXECUTE 0x2B +#define VK_SNAPSHOT 0x2C +#define VK_INSERT 0x2D +#define VK_DELETE 0x2E +#define VK_HELP 0x2F +#define VK_NUMPAD0 0x60 +#define VK_NUMPAD1 0x61 +#define VK_NUMPAD2 0x62 +#define VK_NUMPAD3 0x63 +#define VK_NUMPAD4 0x64 +#define VK_NUMPAD5 0x65 +#define VK_NUMPAD6 0x66 +#define VK_NUMPAD7 0x67 +#define VK_NUMPAD8 0x68 +#define VK_NUMPAD9 0x69 +#define VK_MULTIPLY 0x6A +#define VK_ADD 0x6B +#define VK_SEPARATOR 0x6C +#define VK_SUBTRACT 0x6D +#define VK_DECIMAL 0x6E +#define VK_DIVIDE 0x6F +#define VK_F1 0x70 +#define VK_F2 0x71 +#define VK_F3 0x72 +#define VK_F4 0x73 +#define VK_F5 0x74 +#define VK_F6 0x75 +#define VK_F7 0x76 +#define VK_F8 0x77 +#define VK_F9 0x78 +#define VK_F10 0x79 +#define VK_F11 0x7A +#define VK_F12 0x7B +#define VK_F13 0x7C +#define VK_F14 0x7D +#define VK_F15 0x7E +#define VK_F16 0x7F +#define VK_F17 0x80 +#define VK_F18 0x81 +#define VK_F19 0x82 +#define VK_F20 0x83 +#define VK_F21 0x84 +#define VK_F22 0x85 +#define VK_F23 0x86 +#define VK_F24 0x87 +#define VK_NUMLOCK 0x90 +#define VK_SCROLL 0x91 + #define LMEM_MOVEABLE 0x0002 @@ -1719,6 +1992,7 @@ Fa(WORD,EnumClipboardFormats,WORD,a) Fa(WORD,FreeSelector,WORD,a) Fa(WORD,GetDriveType,int,a) Fa(WORD,GetMenuItemCount,HMENU,a) +Fa(WORD,GetTaskQueue,HANDLE,a) Fa(WORD,GetTextAlign,HDC,a) Fa(WORD,GlobalFlags,HANDLE,a) Fa(WORD,GlobalPageLock,HANDLE,a) @@ -1726,9 +2000,9 @@ Fa(WORD,GlobalPageUnlock,HANDLE,a) Fa(WORD,LocalCompact,WORD,a) Fa(WORD,LocalFlags,HANDLE,a) Fa(WORD,LocalSize,HANDLE,a) -Fa(WORD,RealizePalette,HDC,a) -Fa(WORD,RegisterClipboardFormat,LPSTR,a) -Fa(WORD,RegisterWindowMessage,LPSTR,a) +Fa(int,RealizePalette,HDC,a) +Fa(WORD,RegisterClipboardFormat,LPCSTR,a) +Fa(WORD,RegisterWindowMessage,LPCSTR,a) Fa(WORD,SetHandleCount,WORD,a) Fa(WORD,VkKeyScan,WORD,a) Fa(char NEAR*,LocalLock,HANDLE,a) @@ -1872,6 +2146,7 @@ Fb(WORD,IsDlgButtonChecked,HWND,a,WORD,b) Fb(WORD,LocalShrink,HANDLE,a,WORD,b) Fb(WORD,MapVirtualKey,WORD,a,WORD,b) Fb(WORD,SetSystemPaletteUse,HDC,a,WORD,b) +Fb(WORD,SetTaskQueue,HANDLE,a,HANDLE,b) Fb(WORD,SetTextAlign,HDC,a,WORD,b) Fb(WORD,SizeofResource,HANDLE,a,HANDLE,b) Fb(WORD,WinExec,LPSTR,a,WORD,b) @@ -1881,7 +2156,7 @@ Fb(int,BuildCommDCB,LPSTR,a,DCB*,b) Fb(int,ConvertRequest,HWND,a,LPKANJISTRUCT,b) Fb(void,CopyRect,LPRECT,a,LPRECT,b) Fb(int,EnumProps,HWND,a,FARPROC,b) -Fb(int,EscapeCommFunction,int,a,int,b) +Fb(LONG,EscapeCommFunction,int,a,int,b) Fb(int,ExcludeUpdateRgn,HDC,a,HWND,b) Fb(int,FlushComm,int,a,int,b) Fb(int,GetClipBox,HDC,a,LPRECT,b) @@ -1910,8 +2185,8 @@ Fb(void,MapDialogRect,HWND,a,LPRECT,b) Fb(void,ProfSampRate,int,a,int,b) Fb(void,ProfSetup,int,a,int,b) Fb(void,ScreenToClient,HWND,a,LPPOINT,b) -Fb(void,SetCaretPos,int,a,int,b) -Fb(void,SetCursorPos,int,a,int,b) +Fb(void,SetCaretPos,short,a,short,b) +Fb(void,SetCursorPos,short,a,short,b) Fb(void,SetWindowText,HWND,a,LPSTR,b) Fb(void,ShowOwnedPopups,HWND,a,BOOL,b) Fb(void,Throw,LPCATCHBUF,a,int,b) @@ -1963,6 +2238,7 @@ Fc(HANDLE,GlobalReAlloc,HANDLE,a,DWORD,b,WORD,c) Fc(HANDLE,LocalReAlloc,HANDLE,a,WORD,b,WORD,c) Fc(HBITMAP,CreateCompatibleBitmap,HDC,a,short,b,short,c) Fc(HBITMAP,CreateDiscardableBitmap,HDC,a,short,b,short,c) +Fc(HDC,GetDCEx,HWND,a,HRGN,b,DWORD,c) Fc(HPALETTE,SelectPalette,HDC,a,HPALETTE,b,BOOL,c) Fc(HPEN,CreatePen,short,a,short,b,COLORREF,c) Fc(HRGN,CreatePolygonRgn,LPPOINT,a,short,b,short,c) @@ -1985,7 +2261,7 @@ Fb(WORD,SetRelAbs,HDC,a,WORD,b) Fb(WORD,SetROP2,HDC,a,WORD,b) Fb(WORD,SetStretchBltMode,HDC,a,WORD,b) Fc(int,FrameRect,HDC,a,LPRECT,b,HBRUSH,c) -Fc(int,GetClassName,HWND,a,LPSTR,b,int,c) +Fc(int,GetClassName,HWND,a,LPSTR,b,short,c) Fc(int,GetClipboardFormatName,WORD,a,LPSTR,b,int,c) Fc(int,GetEnvironment,LPSTR,a,LPSTR,b,WORD,c) Fc(int,GetInstanceData,HANDLE,a,NPSTR,b,int,c) @@ -2066,7 +2342,7 @@ Fd(int,DialogBoxIndirect,HANDLE,a,HANDLE,b,HWND,c,FARPROC,d) Fd(int,EnumFonts,HDC,a,LPSTR,b,FARPROC,c,LPSTR,d) Fd(int,EnumObjects,HDC,a,int,b,FARPROC,c,LPSTR,d) Fd(int,GetDlgItemText,HWND,a,WORD,b,LPSTR,c,WORD,d) -Fd(int,GetTempFileName,BYTE,a,LPSTR,b,WORD,c,LPSTR,d) +Fd(int,GetTempFileName,BYTE,a,LPCSTR,b,UINT,c,LPSTR,d) Fd(int,LoadString,HANDLE,a,WORD,b,LPSTR,c,int,d) Fd(int,MessageBox,HWND,a,LPSTR,b,LPSTR,c,WORD,d) Fd(int,SetScrollPos,HWND,a,int,b,int,c,BOOL,d) @@ -2074,9 +2350,10 @@ Fd(int,SetVoiceNote,int,a,int,b,int,c,int,d) Fd(void,AdjustWindowRectEx,LPRECT,a,LONG,b,BOOL,c,DWORD,d) Fd(void,AnimatePalette,HPALETTE,a,WORD,b,WORD,c,LPPALETTEENTRY,d) Fd(void,CheckRadioButton,HWND,a,WORD,b,WORD,c,WORD,d) -Fd(void,CreateCaret,HWND,a,HBITMAP,b,int,c,int,d) +Fd(void,CreateCaret,HWND,a,HBITMAP,b,short,c,short,d) Fd(void,FillWindow,HWND,a,HWND,b,HDC,c,HBRUSH,d) Fd(void,GetScrollRange,HWND,a,int,b,LPINT,c,LPINT,d) +Fd(void,MapWindowPoints,HWND,a,HWND,b,LPPOINT,c,WORD,d) Fd(void,PlayMetaFileRecord,HDC,a,LPHANDLETABLE,b,LPMETARECORD,c,WORD,d) Fd(void,SetDlgItemInt,HWND,a,WORD,b,WORD,c,BOOL,d) Fe(BOOL,Rectangle,HDC,a,int,xLeft,int,yTop,int,xRight,int,yBottom) @@ -2122,17 +2399,17 @@ Ff(HBITMAP,CreateDIBitmap,HDC,a,LPBITMAPINFOHEADER,b,DWORD,c,LPSTR,d,LPBITMAPINF Ff(HRGN,CreateRoundRectRgn,short,a,short,b,short,c,short,d,short,e,short,f) Ff(short,GetPrivateProfileString,LPSTR,a,LPSTR,b,LPSTR,c,LPSTR,d,short,e,LPSTR,f) Ff(void,LineDDA,short,a,short,b,short,c,short,d,FARPROC,e,long,f) -Ff(void,MoveWindow,HWND,a,short,b,short,c,short,d,short,e,BOOL,f) +Ff(BOOL,MoveWindow,HWND,a,short,b,short,c,short,d,short,e,BOOL,f) Ff(BOOL,ScaleViewportExtEx,HDC,a,short,b,short,c,short,d,short,e,LPSIZE,f) Ff(BOOL,ScaleWindowExtEx,HDC,a,short,b,short,c,short,d,short,e,LPSIZE,f) Fg(BOOL,RoundRect,HDC,a,short,b,short,c,short,d,short,e,short,f,short,g) Fg(BOOL,ScrollDC,HDC,a,short,b,short,c,LPRECT,d,LPRECT,e,HRGN,f,LPRECT,g) -Fg(BOOL,TrackPopupMenu,HMENU,a,WORD,b,int,c,int,d,int,e,HWND,f,LPRECT,g) -Fg(HCURSOR,CreateCursor,HANDLE,a,int,b,int,c,int,d,int,e,LPSTR,f,LPSTR,g) +Fg(BOOL,TrackPopupMenu,HMENU,a,WORD,b,short,c,short,d,short,e,HWND,f,LPRECT,g) +Fg(HCURSOR,CreateCursor,HANDLE,a,short,b,short,c,short,d,short,e,LPSTR,f,LPSTR,g) Fg(HICON,CreateIcon,HANDLE,a,int,b,int,c,BYTE,d,BYTE,e,LPSTR,f,LPSTR,g) Fg(int,GetDIBits,HDC,a,HANDLE,a2,WORD,b,WORD,c,LPSTR,d,LPBITMAPINFO,e,WORD,f) Fg(int,SetDIBits,HDC,a,HANDLE,a2,WORD,b,WORD,c,LPSTR,d,LPBITMAPINFO,e,WORD,f) -Fg(void,SetWindowPos,HWND,a,HWND,b,short,c,short,d,short,e,short,f,WORD,g) +Fg(BOOL,SetWindowPos,HWND,a,HWND,b,short,c,short,d,short,e,short,f,WORD,g) Fh(BOOL,ExtTextOut,HDC,a,int,b,int,c,WORD,d,LPRECT,e,LPSTR,f,WORD,g,LPINT,h) Fh(HANDLE,DeferWindowPos,HANDLE,hWinPosInfo,HWND,hWnd,HWND,hWndInsertAfter,int,x,int,y,int,cx,int,cy,WORD,wFlags) Fh(LONG,TabbedTextOut,HDC,a,int,b,int,c,LPSTR,d,int,e,int,f,LPINT,g,int,h) diff --git a/include/wine.h b/include/wine.h index 6a602e9da40..dbc034cd806 100644 --- a/include/wine.h +++ b/include/wine.h @@ -22,9 +22,14 @@ extern struct w_files * wine_files; extern char *GetFilenameFromInstance(unsigned short instance); extern struct w_files *GetFileInfo(unsigned short instance); -extern char *FindFileInPath(char *buffer, int buflen, char *rootname, - char **extensions, char *path); -extern char *GetSystemIniFilename(void); +extern char *WineIniFileName(void); +extern char *WinIniFileName(void); + +#define MAX_DOS_DRIVES 26 + +#define WINE_INI WineIniFileName() +#define WIN_INI WinIniFileName() + #ifdef linux struct sigcontext_struct { unsigned short sc_gs, __gsh; diff --git a/loader/Imakefile b/loader/Imakefile new file mode 100644 index 00000000000..9c5130a48a6 --- /dev/null +++ b/loader/Imakefile @@ -0,0 +1,35 @@ +#include "../Wine.tmpl" + +MODULE = loader + +SRCS = \ + dump.c \ + files.c \ + ldt.c \ + ldtlib.c \ + resource.c \ + selector.c \ + signal.c \ + library.c \ + wine.c \ + cursor.c + +OBJS = \ + dump.o \ + files.o \ + ldt.o \ + ldtlib.o \ + resource.o \ + selector.o \ + signal.o \ + library.o \ + wine.o \ + cursor.o + +WineRelocatableTarget($(TOP)/$(MODULE),,$(OBJS)) +DependTarget() +CleanTarget() + +includes:: + +install:: diff --git a/loader/Makefile b/loader/Makefile index 873a6acd59d..083d8f68a65 100644 --- a/loader/Makefile +++ b/loader/Makefile @@ -1,7 +1,7 @@ CFLAGS=$(COPTS) $(DEBUGOPTS) -I../include -OBJS=dump.o files.o ldt.o ldtlib.o resource.o selector.o signal.o int1a.o \ - int21.o wine.o library.o +OBJS=dump.o ldt.o ldtlib.o resource.o selector.o signal.o library.o \ + wine.o cursor.o default: loader.o diff --git a/loader/cursor.c b/loader/cursor.c new file mode 100644 index 00000000000..039c1c35bf9 --- /dev/null +++ b/loader/cursor.c @@ -0,0 +1,385 @@ +/* + * WINE +*/ +static char Copyright[] = "Copyright Martin Ayotte, 1993"; + +/* +#define DEBUG_CURSOR +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "prototypes.h" +#include "windows.h" +#include "win.h" +#include "gdi.h" +#include "wine.h" +#include "cursor.h" + +static int ShowCursCount = 0; +static HCURSOR hActiveCursor; +static HCURSOR hEmptyCursor = 0; +RECT ClipCursorRect; +extern HINSTANCE hSysRes; +extern Window winHasCursor; + +/********************************************************************** + * LoadCursor [USER.173] + */ +HCURSOR LoadCursor(HANDLE instance, LPSTR cursor_name) +{ + XColor bkcolor; + XColor fgcolor; + HCURSOR hCursor; + HANDLE rsc_mem; + WORD *lp; + CURSORDESCRIP *lpcurdesc; + CURSORALLOC *lpcur; + BITMAP BitMap; + HBITMAP hBitMap; + HDC hMemDC; + HDC hdc; + int i, j, image_size; +#ifdef DEBUG_RESOURCE + printf("LoadCursor: instance = %04x, name = %08x\n", + instance, cursor_name); +#endif + hCursor = GlobalAlloc(GMEM_MOVEABLE, sizeof(CURSORALLOC) + 1024L); + if (hCursor == (HCURSOR)NULL) return 0; +#ifdef DEBUG_CURSOR + printf("LoadCursor Alloc hCursor=%X\n", hCursor); +#endif + lpcur = (CURSORALLOC *)GlobalLock(hCursor); + memset(lpcur, 0, sizeof(CURSORALLOC)); + if (instance == (HANDLE)NULL) { + instance = hSysRes; + switch((LONG)cursor_name) { + case IDC_ARROW: + lpcur->xcursor = XCreateFontCursor(XT_display, XC_top_left_arrow); + GlobalUnlock(hCursor); + return hCursor; + case IDC_CROSS: + lpcur->xcursor = XCreateFontCursor(XT_display, XC_crosshair); + GlobalUnlock(hCursor); + return hCursor; + case IDC_IBEAM: + lpcur->xcursor = XCreateFontCursor(XT_display, XC_xterm); + GlobalUnlock(hCursor); + return hCursor; + case IDC_WAIT: + lpcur->xcursor = XCreateFontCursor(XT_display, XC_watch); + GlobalUnlock(hCursor); + return hCursor; + default: + break; + } + } + if (!(hdc = GetDC(GetDesktopWindow()))) return 0; + rsc_mem = RSC_LoadResource(instance, cursor_name, NE_RSCTYPE_GROUP_CURSOR, + &image_size); + if (rsc_mem == (HANDLE)NULL) { + printf("LoadCursor / Cursor %08X not Found !\n", cursor_name); + ReleaseDC(GetDesktopWindow(), hdc); + return 0; + } + lp = (WORD *)GlobalLock(rsc_mem); + if (lp == NULL) { + GlobalFree(rsc_mem); + ReleaseDC(GetDesktopWindow(), hdc); + return 0; + } + lpcurdesc = (CURSORDESCRIP *)(lp + 3); +#ifdef DEBUG_CURSOR + printf("LoadCursor / image_size=%d\n", image_size); + printf("LoadCursor / curReserved=%X\n", *lp); + printf("LoadCursor / curResourceType=%X\n", *(lp + 1)); + printf("LoadCursor / curResourceCount=%X\n", *(lp + 2)); + printf("LoadCursor / cursor Width=%d\n", (int)lpcurdesc->Width); + printf("LoadCursor / cursor Height=%d\n", (int)lpcurdesc->Height); + printf("LoadCursor / cursor curXHotspot=%d\n", (int)lpcurdesc->curXHotspot); + printf("LoadCursor / cursor curYHotspot=%d\n", (int)lpcurdesc->curYHotspot); + printf("LoadCursor / cursor curDIBSize=%lX\n", (DWORD)lpcurdesc->curDIBSize); + printf("LoadCursor / cursor curDIBOffset=%lX\n", (DWORD)lpcurdesc->curDIBOffset); +#endif + lpcur->descriptor = *lpcurdesc; + GlobalUnlock(rsc_mem); + GlobalFree(rsc_mem); + rsc_mem = RSC_LoadResource(instance, + MAKEINTRESOURCE(lpcurdesc->curDIBOffset), + NE_RSCTYPE_CURSOR, &image_size); + if (rsc_mem == (HANDLE)NULL) { + printf("LoadCursor / Cursor %08X Bitmap not Found !\n", cursor_name); + ReleaseDC(GetDesktopWindow(), hdc); + return 0; + } + lp = (WORD *)GlobalLock(rsc_mem); + if (lp == NULL) { + GlobalFree(rsc_mem); + ReleaseDC(GetDesktopWindow(), hdc); + return 0; + } + lp += 2; + for (j = 0; j < 16; j++) + printf("%04X ", *(lp + j)); +/* + if (*lp == sizeof(BITMAPINFOHEADER)) + lpcur->hBitmap = ConvertInfoBitmap(hdc, (BITMAPINFO *)lp); + else +*/ + lpcur->hBitmap = 0; + lp += sizeof(BITMAP); + for (i = 0; i < 81; i++) { + char temp = *((char *)lp + 162 + i); + *((char *)lp + 162 + i) = *((char *)lp + 324 - i); + *((char *)lp + 324 - i) = temp; + } + lpcur->pixshape = XCreatePixmapFromBitmapData( + XT_display, DefaultRootWindow(XT_display), + ((char *)lp + 211), 32, 32, +/* + lpcurdesc->Width / 2, lpcurdesc->Height / 4, +*/ + WhitePixel(XT_display, DefaultScreen(XT_display)), + BlackPixel(XT_display, DefaultScreen(XT_display)), 1); + lpcur->pixmask = XCreatePixmapFromBitmapData( + XT_display, DefaultRootWindow(XT_display), + ((char *)lp + 211), 32, 32, + WhitePixel(XT_display, DefaultScreen(XT_display)), + BlackPixel(XT_display, DefaultScreen(XT_display)), 1); + memset(&bkcolor, 0, sizeof(XColor)); + memset(&fgcolor, 0, sizeof(XColor)); + bkcolor.pixel = WhitePixel(XT_display, DefaultScreen(XT_display)); + fgcolor.pixel = BlackPixel(XT_display, DefaultScreen(XT_display)); +printf("LoadCursor / before XCreatePixmapCursor !\n"); + lpcur->xcursor = XCreatePixmapCursor(XT_display, + lpcur->pixshape, lpcur->pixmask, + &fgcolor, &bkcolor, lpcur->descriptor.curXHotspot, + lpcur->descriptor.curYHotspot); + GlobalUnlock(rsc_mem); + GlobalFree(rsc_mem); +/* + hCursor = CreateCursor(instance, lpcur->descriptor.curXHotspot, + lpcur->descriptor.curYHotspot, 32, 32, + (LPSTR)lp + 211, , (LPSTR)lp + 211); +*/ + XFreePixmap(XT_display, lpcur->pixshape); + XFreePixmap(XT_display, lpcur->pixmask); + ReleaseDC(GetDesktopWindow(), hdc); + GlobalUnlock(hCursor); + return hCursor; +} + + + +/********************************************************************** + * CreateCursor [USER.406] + */ +HCURSOR CreateCursor(HANDLE instance, short nXhotspot, short nYhotspot, + short nWidth, short nHeight, LPSTR lpANDbitPlane, LPSTR lpXORbitPlane) +{ + XColor bkcolor; + XColor fgcolor; + HCURSOR hCursor; + CURSORALLOC *lpcur; + BITMAP BitMap; + HBITMAP hBitMap; + HDC hMemDC; + HDC hdc; + int i, j; +#ifdef DEBUG_RESOURCE + printf("CreateCursor: inst=%04x nXhotspot=%d nYhotspot=%d nWidth=%d nHeight=%d\n", + nXhotspot, nYhotspot, nWidth, nHeight); + printf("CreateCursor: inst=%04x lpANDbitPlane=%08X lpXORbitPlane=%08X\n", + LPSTR lpANDbitPlane, LPSTR lpXORbitPlane); +#endif + if (!(hdc = GetDC(GetDesktopWindow()))) return 0; + hCursor = GlobalAlloc(GMEM_MOVEABLE, sizeof(CURSORALLOC) + 1024L); + if (hCursor == (HCURSOR)NULL) { + ReleaseDC(GetDesktopWindow(), hdc); + return 0; + } + printf("CreateCursor Alloc hCursor=%X\n", hCursor); + lpcur = (CURSORALLOC *)GlobalLock(hCursor); + memset(lpcur, 0, sizeof(CURSORALLOC)); + lpcur->descriptor.curXHotspot = nXhotspot; + lpcur->descriptor.curYHotspot = nYhotspot; + lpcur->pixshape = XCreatePixmapFromBitmapData( + XT_display, DefaultRootWindow(XT_display), + lpXORbitPlane, nWidth, nHeight, + WhitePixel(XT_display, DefaultScreen(XT_display)), + BlackPixel(XT_display, DefaultScreen(XT_display)), 1); + lpcur->pixmask = XCreatePixmapFromBitmapData( + XT_display, DefaultRootWindow(XT_display), + lpANDbitPlane, nWidth, nHeight, + WhitePixel(XT_display, DefaultScreen(XT_display)), + BlackPixel(XT_display, DefaultScreen(XT_display)), 1); + memset(&bkcolor, 0, sizeof(XColor)); + memset(&fgcolor, 0, sizeof(XColor)); + bkcolor.pixel = WhitePixel(XT_display, DefaultScreen(XT_display)); + fgcolor.pixel = BlackPixel(XT_display, DefaultScreen(XT_display)); + lpcur->xcursor = XCreatePixmapCursor(XT_display, + lpcur->pixshape, lpcur->pixmask, + &fgcolor, &bkcolor, lpcur->descriptor.curXHotspot, + lpcur->descriptor.curYHotspot); + XFreePixmap(XT_display, lpcur->pixshape); + XFreePixmap(XT_display, lpcur->pixmask); + ReleaseDC(GetDesktopWindow(), hdc); + GlobalUnlock(hCursor); + return hCursor; +} + + + +/********************************************************************** + * DestroyCursor [USER.458] + */ +BOOL DestroyCursor(HCURSOR hCursor) +{ + CURSORALLOC *lpcur; + if (hCursor == (HCURSOR)NULL) return FALSE; + lpcur = (CURSORALLOC *)GlobalLock(hCursor); + if (lpcur->hBitmap != (HBITMAP)NULL) DeleteObject(lpcur->hBitmap); + GlobalUnlock(hCursor); + GlobalFree(hCursor); + return TRUE; +} + + +/********************************************************************** + * SetCursor [USER.69] + */ +HCURSOR SetCursor(HCURSOR hCursor) +{ + HDC hDC; + HDC hMemDC; + BITMAP bm; + CURSORALLOC *lpcur; + HCURSOR hOldCursor; + Window root, child; + int rootX, rootY; + int childX, childY; + unsigned int mousebut; +#ifdef DEBUG_CURSOR + printf("SetCursor / hCursor=%04X !\n", hCursor); +#endif + if (hCursor == (HCURSOR)NULL) return FALSE; + lpcur = (CURSORALLOC *)GlobalLock(hCursor); + hOldCursor = hActiveCursor; +#ifdef DEBUG_CURSOR + printf("SetCursor / lpcur->xcursor=%08X !\n", &lpcur->xcursor); + XQueryPointer(XT_display, DefaultRootWindow(XT_display), + &root, &child, &rootX, &rootY, &childX, &childY, &mousebut); + printf("SetCursor / winHasCursor=%08X !\n", winHasCursor); + printf("SetCursor / child=%08X !\n", child); +#endif + if (hActiveCursor != hCursor) ShowCursCount = 0; + if ((ShowCursCount >= 0) & (winHasCursor != 0)) { +/* XUndefineCursor(XT_display, winHasCursor); */ + XDefineCursor(XT_display, winHasCursor, lpcur->xcursor); + } + GlobalUnlock(hCursor); + hActiveCursor = hCursor; + return hOldCursor; +} + + +/********************************************************************** + * SetCursorPos [USER.70] + */ +void SetCursorPos(short x, short y) +{ + Window root, child; + int rootX, rootY; + int childX, childY; + unsigned int mousebut; +#ifdef DEBUG_CURSOR + printf("SetCursorPos // x=%d y=%d\n", x, y); +#endif + XQueryPointer(XT_display, DefaultRootWindow(XT_display), + &root, &child, &rootX, &rootY, &childX, &childY, &mousebut); + XWarpPointer(XT_display, child, root, 0, 0, + DisplayWidth(XT_display, DefaultScreen(XT_display)), + DisplayHeight(XT_display, DefaultScreen(XT_display)), + (int)x, (int)y); +} + + +/********************************************************************** + * GetCursorPos [USER.17] + */ +void GetCursorPos(LPPOINT lpRetPoint) +{ + Window root, child; + int rootX, rootY; + int childX, childY; + unsigned int mousebut; + if (lpRetPoint != NULL) { + XQueryPointer(XT_display, DefaultRootWindow(XT_display), + &root, &child, &rootX, &rootY, &childX, &childY, &mousebut); +#ifdef DEBUG_CURSOR + printf("GetCursorPos // x=%d y=%d\n", rootX, rootY); +#endif + lpRetPoint->x = rootX; + lpRetPoint->y = rootY; + } +} + + +/********************************************************************** + * ShowCursor [USER.71] + */ +int ShowCursor(BOOL bShow) +{ + HCURSOR hCursor; +#ifdef DEBUG_CURSOR + printf("ShowCursor bShow=%d ShowCount=%d !\n", bShow, ShowCursCount); +#endif + if (bShow) + ShowCursCount++; + else + ShowCursCount--; + if (ShowCursCount >= 0) { +/* if (hCursor == (HCURSOR)NULL) */ + hCursor = LoadCursor((HINSTANCE)NULL, IDC_ARROW); + SetCursor(hCursor); + } + else { +/* XUndefineCursor(XT_display, winHasCursor); */ + if (hEmptyCursor == (HCURSOR)NULL) + hEmptyCursor = CreateCursor((HINSTANCE)NULL, 1, 1, 1, 1, + "\xFF\xFF", "\xFF\xFF"); + hCursor = SetCursor(hEmptyCursor); + hActiveCursor = hCursor; + } + return 0; +} + + +/********************************************************************** + * ClipCursor [USER.16] + */ +void ClipCursor(LPRECT lpNewClipRect) +{ + CopyRect(&ClipCursorRect, lpNewClipRect); +} + + +/********************************************************************** + * GetClipCursor [USER.309] + */ +void GetClipCursor(LPRECT lpRetClipRect) +{ + if (lpRetClipRect != NULL) + CopyRect(lpRetClipRect, &ClipCursorRect); +} + + + + diff --git a/loader/files.c b/loader/files.c deleted file mode 100644 index a4371c6e8ac..00000000000 --- a/loader/files.c +++ /dev/null @@ -1,109 +0,0 @@ -static char RCSId[] = "$Id: wine.c,v 1.2 1993/07/04 04:04:21 root Exp root $"; -static char Copyright[] = "Copyright Robert J. Amstadt, 1993"; - -#include -#include -#include - -/********************************************************************** - * FindFileInPath - */ -char * -FindFileInPath(char *buffer, int buflen, char *rootname, - char **extensions, char *path) -{ - char *workingpath; - char *dirname; - DIR *d; - struct dirent *f; - char **e; - int rootnamelen; - int found = 0; - - if (strchr(rootname, '/') != NULL) - { - strncpy(buffer, rootname, buflen); - return buffer; - } - - rootnamelen = strlen(rootname); - workingpath = malloc(strlen(path) + 1); - if (workingpath == NULL) - return NULL; - strcpy(workingpath, path); - - for(dirname = strtok(workingpath, ":;"); - dirname != NULL; - dirname = strtok(NULL, ":;")) - { - d = opendir(dirname); - if (d != NULL) - { - while ((f = readdir(d)) != NULL) - { - if (strncasecmp(rootname, f->d_name, rootnamelen) == 0) - { - if (extensions == NULL || - strcasecmp(rootname, f->d_name) == 0) - { - found = 1; - } - else if (f->d_name[rootnamelen] == '.') - { - for (e = extensions; *e != NULL; e++) - { - if (strcasecmp(*e, f->d_name + rootnamelen + 1) - == 0) - { - found = 1; - break; - } - } - } - - if (found) - { - strncpy(buffer, dirname, buflen); - strncat(buffer, "/", buflen - strlen(buffer)); - strncat(buffer, f->d_name, buflen - strlen(buffer)); - closedir(d); - return buffer; - } - } - } - closedir(d); - } - } - - return NULL; -} - -/********************************************************************** - * GetSystemIniFilename - */ -char * -GetSystemIniFilename() -{ - static char *IniName = NULL; - char inipath[256]; - - if (IniName) - return IniName; - - getcwd(inipath, 256); - strcat(inipath, ":"); - strcat(inipath, getenv("HOME")); - strcat(inipath, ":"); - strcat(inipath, getenv("WINEPATH")); - - IniName = malloc(1024); - if (FindFileInPath(IniName, 1024, "wine.ini", NULL, inipath) == NULL) - { - free(IniName); - IniName = NULL; - return NULL; - } - - IniName = realloc(IniName, strlen(IniName) + 1); - return IniName; -} diff --git a/loader/library.c b/loader/library.c index 6e96351de24..fe7813e26e3 100644 --- a/loader/library.c +++ b/loader/library.c @@ -20,7 +20,7 @@ HANDLE LoadLibrary(LPSTR libname) { HANDLE hRet; printf("LoadLibrary '%s'\n", libname); - hRet = LoadImage(libname, NULL); + hRet = LoadImage(libname); printf("after LoadLibrary hRet=%04X\n", hRet); return hRet; } diff --git a/loader/resource.c b/loader/resource.c index a0c986c49f1..9d973058c68 100644 --- a/loader/resource.c +++ b/loader/resource.c @@ -14,7 +14,6 @@ static char Copyright[] = "Copyright Robert J. Amstadt, 1993"; #include "gdi.h" #include "wine.h" #include "icon.h" -#include "cursor.h" #define MIN(a,b) ((a) < (b) ? (a) : (b)) @@ -31,7 +30,6 @@ static int ResourceFd = -1; static HANDLE ResourceInst = 0; static struct w_files *ResourceFileInfo = NULL; static RESOURCE *Top = NULL; -static HCURSOR hActiveCursor; extern HINSTANCE hSysRes; HANDLE RSC_LoadResource(int instance, char *rsc_name, int type, int *image_size_ret); @@ -313,23 +311,26 @@ HICON LoadIcon(HANDLE instance, LPSTR icon_name) instance, icon_name); #endif - if (instance == (HANDLE)NULL) instance = hSysRes; if (!(hdc = GetDC(GetDesktopWindow()))) return 0; + if (instance == (HANDLE)NULL) instance = hSysRes; rsc_mem = RSC_LoadResource(instance, icon_name, NE_RSCTYPE_GROUP_ICON, &image_size); if (rsc_mem == (HANDLE)NULL) { printf("LoadIcon / Icon %04X not Found !\n", icon_name); + ReleaseDC(GetDesktopWindow(), hdc); return 0; } lp = (WORD *)GlobalLock(rsc_mem); if (lp == NULL) { GlobalFree(rsc_mem); + ReleaseDC(GetDesktopWindow(), hdc); return 0; } lpicodesc = (ICONDESCRIP *)(lp + 3); hIcon = GlobalAlloc(GMEM_MOVEABLE, sizeof(ICONALLOC) + 1024); if (hIcon == (HICON)NULL) { GlobalFree(rsc_mem); + ReleaseDC(GetDesktopWindow(), hdc); return 0; } printf("LoadIcon Alloc hIcon=%X\n", hIcon); @@ -344,11 +345,13 @@ HICON LoadIcon(HANDLE instance, LPSTR icon_name) NE_RSCTYPE_ICON, &image_size); if (rsc_mem == (HANDLE)NULL) { printf("LoadIcon / Icon %04X Bitmaps not Found !\n", icon_name); + ReleaseDC(GetDesktopWindow(), hdc); return 0; } lp = (WORD *)GlobalLock(rsc_mem); if (lp == NULL) { GlobalFree(rsc_mem); + ReleaseDC(GetDesktopWindow(), hdc); return 0; } bmi = (BITMAPINFO *)lp; @@ -378,7 +381,6 @@ HICON LoadIcon(HANDLE instance, LPSTR icon_name) (BITMAPINFO *)bih, DIB_RGB_COLORS ); GlobalUnlock(rsc_mem); GlobalFree(rsc_mem); - hMemDC = CreateCompatibleDC(hdc); hMemDC2 = CreateCompatibleDC(hdc); SelectObject(hMemDC, lpico->hBitmap); @@ -386,8 +388,7 @@ HICON LoadIcon(HANDLE instance, LPSTR icon_name) BitBlt(hMemDC, 0, 0, bih->biWidth, bih->biHeight, hMemDC2, 0, 0, SRCINVERT); DeleteDC(hMemDC); DeleteDC(hMemDC2); - - ReleaseDC(0, hdc); + ReleaseDC(GetDesktopWindow(), hdc); return hIcon; } @@ -406,165 +407,6 @@ BOOL DestroyIcon(HICON hIcon) } -/********************************************************************** - * LoadCursor [USER.173] - */ -HCURSOR LoadCursor(HANDLE instance, LPSTR cursor_name) -{ - XColor bkcolor; - XColor fgcolor; - HCURSOR hCursor; - HANDLE rsc_mem; - WORD *lp; - CURSORDESCRIP *lpcurdesc; - CURSORALLOC *lpcur; - BITMAP BitMap; - HBITMAP hBitMap; - HDC hMemDC; - HDC hdc; - int i, j, image_size; -#ifdef DEBUG_RESOURCE - printf("LoadCursor: instance = %04x, name = %08x\n", - instance, cursor_name); -#endif - if (!(hdc = GetDC(GetDesktopWindow()))) return 0; - if (instance == (HANDLE)NULL) instance = hSysRes; - rsc_mem = RSC_LoadResource(instance, cursor_name, NE_RSCTYPE_GROUP_CURSOR, - &image_size); - if (rsc_mem == (HANDLE)NULL) { - printf("LoadCursor / Cursor %08X not Found !\n", cursor_name); - return 0; - } - lp = (WORD *)GlobalLock(rsc_mem); - if (lp == NULL) { - GlobalFree(rsc_mem); - return 0; - } - lpcurdesc = (CURSORDESCRIP *)(lp + 3); -#ifdef DEBUG_CURSOR - printf("LoadCursor / image_size=%d\n", image_size); - printf("LoadCursor / curReserved=%X\n", *lp); - printf("LoadCursor / curResourceType=%X\n", *(lp + 1)); - printf("LoadCursor / curResourceCount=%X\n", *(lp + 2)); - printf("LoadCursor / cursor Width=%d\n", (int)lpcurdesc->Width); - printf("LoadCursor / cursor Height=%d\n", (int)lpcurdesc->Height); - printf("LoadCursor / cursor curXHotspot=%d\n", (int)lpcurdesc->curXHotspot); - printf("LoadCursor / cursor curYHotspot=%d\n", (int)lpcurdesc->curYHotspot); - printf("LoadCursor / cursor curDIBSize=%lX\n", (DWORD)lpcurdesc->curDIBSize); - printf("LoadCursor / cursor curDIBOffset=%lX\n", (DWORD)lpcurdesc->curDIBOffset); -#endif - hCursor = GlobalAlloc(GMEM_MOVEABLE, sizeof(CURSORALLOC) + 1024L); - if (hCursor == (HCURSOR)NULL) { - GlobalFree(rsc_mem); - return 0; - } - printf("LoadCursor Alloc hCursor=%X\n", hCursor); - lpcur = (CURSORALLOC *)GlobalLock(hCursor); - lpcur->descriptor = *lpcurdesc; - GlobalUnlock(rsc_mem); - GlobalFree(rsc_mem); - rsc_mem = RSC_LoadResource(instance, - MAKEINTRESOURCE(lpcurdesc->curDIBOffset), - NE_RSCTYPE_CURSOR, &image_size); - if (rsc_mem == (HANDLE)NULL) { - printf("LoadCursor / Cursor %08X Bitmap not Found !\n", cursor_name); - return 0; - } - lp = (WORD *)GlobalLock(rsc_mem); - if (lp == NULL) { - GlobalFree(rsc_mem); - return 0; - } - lp += 2; - for (j = 0; j < 16; j++) - printf("%04X ", *(lp + j)); - if (*lp == sizeof(BITMAPINFOHEADER)) - lpcur->hBitmap = ConvertInfoBitmap(hdc, (BITMAPINFO *)lp); - else - lpcur->hBitmap = 0; - lp += sizeof(BITMAP); - for (i = 0; i < 81; i++) { - char temp = *((char *)lp + 162 + i); - *((char *)lp + 162 + i) = *((char *)lp + 324 - i); - *((char *)lp + 324 - i) = temp; - } -printf("LoadCursor / before XCreatePixmapFromBitmapData !\n"); - lpcur->pixshape = XCreatePixmapFromBitmapData( - XT_display, DefaultRootWindow(XT_display), - ((char *)lp + 211), 32, 32, -/* - lpcurdesc->Width / 2, lpcurdesc->Height / 4, -*/ - WhitePixel(XT_display, DefaultScreen(XT_display)), - BlackPixel(XT_display, DefaultScreen(XT_display)), 1); - lpcur->pixmask = lpcur->pixshape; - bkcolor.pixel = WhitePixel(XT_display, DefaultScreen(XT_display)); - fgcolor.pixel = BlackPixel(XT_display, DefaultScreen(XT_display)); -printf("LoadCursor / before XCreatePixmapCursor !\n"); - lpcur->xcursor = XCreatePixmapCursor(XT_display, - lpcur->pixshape, lpcur->pixmask, - &fgcolor, &bkcolor, lpcur->descriptor.curXHotspot, - lpcur->descriptor.curYHotspot); - - ReleaseDC(0, hdc); - GlobalUnlock(rsc_mem); - GlobalFree(rsc_mem); - return hCursor; -} - - - -/********************************************************************** - * DestroyCursor [USER.458] - */ -BOOL DestroyCursor(HCURSOR hCursor) -{ - CURSORALLOC *lpcur; - if (hCursor == (HCURSOR)NULL) return FALSE; - lpcur = (CURSORALLOC *)GlobalLock(hCursor); - if (lpcur->hBitmap != (HBITMAP)NULL) DeleteObject(lpcur->hBitmap); - GlobalUnlock(hCursor); - GlobalFree(hCursor); - return TRUE; -} - - -/********************************************************************** - * SetCursor [USER.69] - */ -HCURSOR SetCursor(HCURSOR hCursor) -{ - HDC hDC; - HDC hMemDC; - BITMAP bm; - CURSORALLOC *lpcur; - HCURSOR hOldCursor; -#ifdef DEBUG_CURSOR - printf("SetCursor / hCursor=%04X !\n", hCursor); -#endif - if (hCursor == (HCURSOR)NULL) return FALSE; - lpcur = (CURSORALLOC *)GlobalLock(hCursor); - hOldCursor = hActiveCursor; - -printf("SetCursor / before XDefineCursor !\n"); - XDefineCursor(XT_display, DefaultRootWindow(XT_display), lpcur->xcursor); - GlobalUnlock(hCursor); - hActiveCursor = hCursor; - return hOldCursor; -} - - -/********************************************************************** - * ShowCursor [USER.71] - */ -int ShowCursor(BOOL bShow) -{ - if (bShow) { - } - return 0; -} - - /********************************************************************** * LoadAccelerators */ @@ -586,6 +428,10 @@ HANDLE FindResource(HANDLE instance, LPSTR resource_name, LPSTR type_name) if (instance == 0) return 0; +#ifdef DEBUG_RESOURCE + printf("FindResource hInst=%04X typename=%08X resname=%08X\n", + instance, type_name, resource_name); +#endif if (OpenResourceFile(instance) < 0) return 0; @@ -644,6 +490,8 @@ HANDLE LoadResource(HANDLE instance, HANDLE hResInfo) h = r->rsc_mem = GlobalAlloc(GMEM_MOVEABLE, image_size); image = GlobalLock(h); + lseek(ResourceFd, ((int) r->nameinfo.offset << r->size_shift), SEEK_SET); + if (image == NULL || read(ResourceFd, image, image_size) != image_size) { GlobalFree(h); diff --git a/loader/selector.c b/loader/selector.c index f091d1da963..5edee7fa4d7 100644 --- a/loader/selector.c +++ b/loader/selector.c @@ -7,7 +7,7 @@ static char Copyright[] = "Copyright Robert J. Amstadt, 1993"; #include #include #include -#ifdef linux +#ifdef __linux__ #include #include #include @@ -38,17 +38,16 @@ static char Copyright[] = "Copyright Robert J. Amstadt, 1993"; #define UTEXTSEL 0x1f #endif -static struct segment_descriptor_s * EnvironmentSelector = NULL; -static struct segment_descriptor_s * PSP_Selector = NULL; -struct segment_descriptor_s * MakeProcThunks = NULL; +static SEGDESC * EnvironmentSelector = NULL; +static SEGDESC * PSP_Selector = NULL; +SEGDESC * MakeProcThunks = NULL; unsigned short PSPSelector; unsigned char ran_out = 0; -unsigned short SelectorOwners[MAX_SELECTORS]; -unsigned short SelectorMap[MAX_SELECTORS]; -unsigned short SelectorLimits[MAX_SELECTORS]; -unsigned char SelectorTypes[MAX_SELECTORS]; int LastUsedSelector = FIRST_SELECTOR - 1; +unsigned short SelectorMap[MAX_SELECTORS]; +SEGDESC Segments[MAX_SELECTORS]; + #ifdef DEV_ZERO static FILE *zfile = NULL; #endif @@ -83,6 +82,74 @@ FindUnusedSelector(void) return i; } +#ifdef HAVE_IPC +/********************************************************************** + * IPCCopySelector + */ +int +IPCCopySelector(int i_old, int i_new, int swap_type) +{ + SEGDESC *s_new, *s_old; + + s_old = &Segments[i_old]; + s_new = &Segments[i_new]; + + SelectorMap[i_new] = i_new; + + s_new->selector = (i_new << 3) | 0x0007; + s_new->base_addr = (void *) ((long) s_new->selector << 16); + s_new->length = s_old->length; + s_new->flags = s_old->flags; + s_new->owner = s_old->owner; + if (swap_type) + { + if (s_old->type == MODIFY_LDT_CONTENTS_DATA) + s_new->type = MODIFY_LDT_CONTENTS_CODE; + else + s_new->type = MODIFY_LDT_CONTENTS_DATA; + } + else + s_new->type = s_old->type; + + if (s_old->shm_key == 0) + { + s_old->shm_key = shmget(IPC_PRIVATE, s_old->length, 0600); + if (s_old->shm_key == 0) + { + memset(s_new, 0, sizeof(*s_new)); + return 0; + } + if (shmat(s_old->shm_key, s_new->base_addr, 0) == NULL) + { + memset(s_new, 0, sizeof(*s_new)); + shmctl(s_old->shm_key, IPC_RMID, NULL); + return 0; + } + memcpy(s_new->base_addr, s_old->base_addr, s_new->length); + munmap(s_old->base_addr, + ((s_old->length + PAGE_SIZE) & ~(PAGE_SIZE - 1))); + shmat(s_old->shm_key, s_old->base_addr, 0); + } + else + { + if (shmat(s_old->shm_key, s_new->base_addr, 0) == NULL) + { + memset(s_new, 0, sizeof(*s_new)); + return 0; + } + } + s_new->shm_key = s_old->shm_key; + + if (set_ldt_entry(i_new, (unsigned long) s_new->base_addr, + s_new->length - 1, 0, s_new->type, 0, 0) < 0) + { + return 0; + } + + return s_new->selector; +} +#endif + /********************************************************************** * AllocSelector * @@ -92,32 +159,38 @@ FindUnusedSelector(void) unsigned int AllocSelector(unsigned int old_selector) { + SEGDESC *s_new, *s_old; int i_new, i_old; - long base; i_new = FindUnusedSelector(); + s_new = &Segments[i_new]; + if (old_selector) { i_old = (old_selector >> 3); - SelectorMap[i_new] = i_old; - base = SAFEMAKEPTR(old_selector, 0); - if (set_ldt_entry(i_new, base, - SelectorLimits[i_old], 0, - SelectorTypes[i_old], 0, 0) < 0) +#ifdef HAVE_IPC + return IPCCopySelector(i_old, i_new, 0); +#else + s_old = &Segments[i_old]; + s_new->selector = (i_new << 3) | 0x0007; + *s_new = *s_old; + SelectorMap[i_new] = SelectorMap[i_old]; + + if (set_ldt_entry(i_new, s_new->base_addr, + s_new->length - 1, 0, + s_new->type, 0, 0) < 0) { return 0; } - - SelectorLimits[i_new] = SelectorLimits[i_old]; - SelectorTypes[i_new] = SelectorTypes[i_old]; - SelectorMap[i_new] = SelectorMap[i_old]; +#endif } else { + memset(s_new, 0, sizeof(*s_new)); SelectorMap[i_new] = i_new; } - return i_new; + return (i_new << 3) | 0x0007; } /********************************************************************** @@ -128,35 +201,64 @@ AllocSelector(unsigned int old_selector) */ unsigned int PrestoChangoSelector(unsigned src_selector, unsigned dst_selector) { - long dst_base, src_base; +#ifdef HAVE_IPC + SEGDESC *src_s; + int src_idx, dst_idx; + + src_idx = src_selector >> 3; + dst_idx = dst_selector >> 3; + + if (src_idx == dst_idx) + { + src_s = &Segments[src_idx]; + + if (src_s->type == MODIFY_LDT_CONTENTS_DATA) + src_s->type = MODIFY_LDT_CONTENTS_CODE; + else + src_s->type = MODIFY_LDT_CONTENTS_DATA; + + if (set_ldt_entry(src_idx, (long) src_s->base_addr, + src_s->length - 1, 0, src_s->type, 0, 0) < 0) + { + return 0; + } + + return src_s->selector; + } + else + { + return IPCCopySelector(src_idx, dst_idx, 1); + } +#else /* HAVE_IPC */ + SEGDESC *src_s, *dst_s; char *p; int src_idx, dst_idx; int alias_count; int i; - + src_idx = (SelectorMap[src_selector >> 3]); dst_idx = dst_selector >> 3; - src_base = (src_idx << 19) | 0x70000; - dst_base = (dst_idx << 19) | 0x70000; + src_s = &Segments[src_idx]; + dst_s = &Segments[dst_idx]; alias_count = 0; for (i = FIRST_SELECTOR; i < MAX_SELECTORS; i++) if (SelectorMap[i] == src_idx) alias_count++; - if (SelectorTypes[src_idx] == MODIFY_LDT_CONTENTS_DATA + if (src_s->type == MODIFY_LDT_CONTENTS_DATA || alias_count > 1 || src_idx == dst_idx) { - if (SelectorTypes[src_idx] == MODIFY_LDT_CONTENTS_DATA) - SelectorTypes[dst_idx] = MODIFY_LDT_CONTENTS_CODE; + *dst_s = *src_s; + + if (src_s->type == MODIFY_LDT_CONTENTS_DATA) + dst_s->type = MODIFY_LDT_CONTENTS_CODE; else - SelectorTypes[dst_idx] = MODIFY_LDT_CONTENTS_DATA; + dst_s->type = MODIFY_LDT_CONTENTS_DATA; SelectorMap[dst_idx] = SelectorMap[src_idx]; - SelectorLimits[dst_idx] = SelectorLimits[src_idx]; - if (set_ldt_entry(dst_idx, src_base, - SelectorLimits[dst_idx], 0, - SelectorTypes[dst_idx], 0, 0) < 0) + if (set_ldt_entry(dst_idx, (long) dst_s->base_addr, + dst_s->length - 1, 0, dst_s->type, 0, 0) < 0) { return 0; } @@ -168,20 +270,22 @@ unsigned int PrestoChangoSelector(unsigned src_selector, unsigned dst_selector) * segment. The SAFEST (but ugliest) way to deal with * this is to map the new segment and copy all the contents. */ - SelectorTypes[dst_idx] = MODIFY_LDT_CONTENTS_DATA; - SelectorMap[dst_idx] = SelectorMap[src_idx]; - SelectorLimits[dst_idx] = SelectorLimits[src_idx]; + SelectorMap[dst_idx] = dst_idx; + *dst_s = *src_s; + dst_s->selector = (dst_idx << 3) | 0x0007; + dst_s->base_addr = (void *) ((unsigned int) dst_s->selector << 16); + dst_s->type = MODIFY_LDT_CONTENTS_DATA; #ifdef DEV_ZERO if (zfile == NULL) zfile = fopen("/dev/zero","r"); - p = (void *) mmap((char *) dst_base, - ((SelectorLimits[dst_idx] + PAGE_SIZE) + p = (void *) mmap((char *) dst_s->base_addr, + ((dst_s->length + PAGE_SIZE) & ~(PAGE_SIZE - 1)), PROT_EXEC | PROT_READ | PROT_WRITE, MAP_FIXED | MAP_PRIVATE, fileno(zfile), 0); #else - p = (void *) mmap((char *) dst_base, - ((SelectorLimits[dst_idx] + PAGE_SIZE) + p = (void *) mmap((char *) dst_s->base_addr, + ((dst_s->length + PAGE_SIZE) & ~(PAGE_SIZE - 1)), PROT_EXEC | PROT_READ | PROT_WRITE, MAP_FIXED | MAP_PRIVATE | MAP_ANON, -1, 0); @@ -189,23 +293,27 @@ unsigned int PrestoChangoSelector(unsigned src_selector, unsigned dst_selector) if (p == NULL) return 0; - memcpy((void *) dst_base, (void *) src_base, - SelectorLimits[dst_idx] + 1); - if (set_ldt_entry(src_idx, dst_base, - SelectorLimits[dst_idx], 0, - SelectorTypes[dst_idx], 0, 0) < 0) + memcpy((void *) dst_s->base_addr, (void *) src_s->base_addr, + dst_s->length); + if (set_ldt_entry(src_idx, dst_s->base_addr, + dst_s->length - 1, 0, dst_s->type, 0, 0) < 0) { return 0; } - if (set_ldt_entry(dst_idx, dst_base, - SelectorLimits[dst_idx], 0, - SelectorTypes[dst_idx], 0, 0) < 0) + if (set_ldt_entry(dst_idx, dst_s->base_addr, + dst_s->length - 1, 0, dst_s->type, 0, 0) < 0) { return 0; } + + munmap(src_s->base_addr, + (src_s->length + PAGE_SIZE) & ~(PAGE_SIZE - 1)); + SelectorMap[src_idx] = dst_idx; + src_s->base_addr = dst_s->base_addr; } - return (dst_idx << 3) | 0x0007; + return dst_s->selector; +#endif /* HAVE_IPC */ } /********************************************************************** @@ -227,12 +335,46 @@ AllocDStoCSAlias(unsigned int ds_selector) */ unsigned int FreeSelector(unsigned int sel) { + SEGDESC *s; int sel_idx; int alias_count; int i; + +#ifdef HAVE_IPC + sel_idx = sel >> 3; + + if (sel_idx < FIRST_SELECTOR || sel_idx >= MAX_SELECTORS) + return 0; + s = &Segments[sel_idx]; + if (s->shm_key == 0) + { + munmap(s->base_addr, ((s->length + PAGE_SIZE) & ~(PAGE_SIZE - 1))); + memcpy(s, 0, sizeof(*s)); + SelectorMap[sel_idx] = 0; + } + else + { + shmdt(s->base_addr); + + alias_count = 0; + for (i = FIRST_SELECTOR; i < MAX_SELECTORS; i++) + if (SelectorMap[i] && Segments[i].shm_key == s->shm_key) + alias_count++; + + if (alias_count == 1) + shmctl(s->shm_key, IPC_RMID, NULL); + + memcpy(s, 0, sizeof(*s)); + SelectorMap[sel_idx] = 0; + } + +#else /* HAVE_IPC */ sel_idx = SelectorMap[sel >> 3]; + if (sel_idx < FIRST_SELECTOR || sel_idx >= MAX_SELECTORS) + return 0; + if (sel_idx != (sel >> 3)) { SelectorMap[sel >> 3] = 0; @@ -246,10 +388,12 @@ unsigned int FreeSelector(unsigned int sel) if (alias_count == 1) { - munmap((char *) (sel << 16), - ((SelectorLimits[sel_idx] + PAGE_SIZE) & ~(PAGE_SIZE - 1))); + s = &Segments[sel_idx]; + munmap(s->base_addr, ((s->length + PAGE_SIZE) & ~(PAGE_SIZE - 1))); + memcpy(s, 0, sizeof(*s)); SelectorMap[sel >> 3] = 0; } +#endif /* HAVE_IPC */ return 0; } @@ -257,10 +401,10 @@ unsigned int FreeSelector(unsigned int sel) /********************************************************************** * CreateNewSegment */ -struct segment_descriptor_s * +SEGDESC * CreateNewSegment(int code_flag, int read_only, int length) { - struct segment_descriptor_s *s; + SEGDESC *s; int contents; int i; @@ -269,7 +413,7 @@ CreateNewSegment(int code_flag, int read_only, int length) /* * Fill in selector info. */ - s = malloc(sizeof(*s)); + s = &Segments[i]; if (code_flag) { contents = MODIFY_LDT_CONTENTS_CODE; @@ -305,13 +449,12 @@ CreateNewSegment(int code_flag, int read_only, int length) (s->length - 1) & 0xffff, 0, contents, read_only, 0) < 0) { - free(s); + memset(s, 0, sizeof(*s)); return NULL; } SelectorMap[i] = (unsigned short) i; - SelectorLimits[i] = s->length - 1; - SelectorTypes[i] = contents; + s->type = contents; return s; } @@ -319,7 +462,7 @@ CreateNewSegment(int code_flag, int read_only, int length) /********************************************************************** * GetNextSegment */ -struct segment_descriptor_s * +SEGDESC * GetNextSegment(unsigned int flags, unsigned int limit) { return CreateNewSegment(0, 0, limit); @@ -494,11 +637,11 @@ GetDOSEnvironment() /********************************************************************** * CreateEnvironment */ -static struct segment_descriptor_s * +static SEGDESC * CreateEnvironment(void) { char *p; - struct segment_descriptor_s * s; + SEGDESC * s; s = CreateNewSegment(0, 0, PAGE_SIZE); if (s == NULL) @@ -521,12 +664,12 @@ CreateEnvironment(void) /********************************************************************** * CreatePSP */ -static struct segment_descriptor_s * +static SEGDESC * CreatePSP(void) { struct dos_psp_s *psp; unsigned short *usp; - struct segment_descriptor_s * s; + SEGDESC * s; char *p1, *p2; int i; @@ -572,13 +715,13 @@ CreatePSP(void) /********************************************************************** * CreateSelectors */ -struct segment_descriptor_s * +SEGDESC * CreateSelectors(struct w_files * wpnt) { int fd = wpnt->fd; struct ne_segment_table_entry_s *seg_table = wpnt->seg_table; struct ne_header_s *ne_header = wpnt->ne_header; - struct segment_descriptor_s *selectors, *s, *stmp; + SEGDESC *selectors, *s, *stmp; unsigned short auto_data_sel; int contents, read_only; int SelectorTableLength; @@ -692,7 +835,7 @@ CreateSelectors(struct w_files * wpnt) s = selectors; for (i = 0; i < ne_header->n_segment_tab; i++, s++) - SelectorOwners[s->selector >> 3] = auto_data_sel; + Segments[s->selector >> 3].owner = auto_data_sel; if(!EnvironmentSelector) { EnvironmentSelector = CreateEnvironment(); diff --git a/loader/signal.c b/loader/signal.c index 7b2727cae54..b2a492e221f 100644 --- a/loader/signal.c +++ b/loader/signal.c @@ -3,7 +3,11 @@ #include #include +#ifdef __NetBSD__ +#include +#else #include +#endif #include #include #ifdef linux @@ -85,11 +89,11 @@ static void win_fault(int signal, int code, struct sigcontext *scp){ if(!do_int21(scp)) goto oops; break; case 0x11: - scp->sc_eax = 0x00000000; /* get equipment list: we haven't */ - break; /* got anything */ + scp->sc_eax = (scp->sc_eax & 0xffff0000L) | DOS_GetEquipment(); + break; case 0x12: - scp->sc_eax = 640L; /* get base mem size */ - break; + scp->sc_eax = (scp->sc_eax & 0xffff0000L) | 640L; + break; /* get base mem size */ case 0x1A: if(!do_int1A(scp)) goto oops; break; diff --git a/loader/wine.c b/loader/wine.c index 7124317f09a..60b606bbf4a 100644 --- a/loader/wine.c +++ b/loader/wine.c @@ -28,11 +28,14 @@ extern void CallTo32(); char * GetModuleName(struct w_files * wpnt, int index, char *buffer); extern unsigned char ran_out; +extern char WindowsPath[256]; unsigned short WIN_StackSize; unsigned short WIN_HeapSize; struct w_files * wine_files = NULL; +int WineForceFail = 0; + char **Argv; int Argc; struct mz_header_s *CurrentMZHeader; @@ -40,11 +43,9 @@ struct ne_header_s *CurrentNEHeader; int CurrentNEFile; HINSTANCE hSysRes; -static char *dllExtensions[] = { "dll", "exe", NULL }; -static char *exeExtensions[] = { "exe", NULL }; +static char *Extensions[] = { "dll", "exe", NULL }; static char *WinePath = NULL; - /********************************************************************** * DebugPrintString */ @@ -101,12 +102,13 @@ GetFileInfo(unsigned short instance) * LoadImage * Load one NE format executable into memory */ -HINSTANCE LoadImage(char * filename, char * modulename) +HINSTANCE LoadImage(char *modulename) { unsigned int read_size; int i; struct w_files * wpnt, *wpnt1; unsigned int status; + char buffer[256]; /* First allocate a spot to store the info we collect, and add it to * our linked list. @@ -122,10 +124,24 @@ HINSTANCE LoadImage(char * filename, char * modulename) }; wpnt->next = NULL; + /* + * search file + */ + + if (FindFile(buffer, sizeof(buffer), modulename, Extensions, WindowsPath) + ==NULL) + { + char temp[256]; + + sprintf(temp,"LoadImage: I can't find %s !\n",modulename); + myerror(temp); + } + fprintf(stderr,"LoadImage: loading %s (%s)\n", modulename, buffer); + /* * Open file for reading. */ - wpnt->fd = open(filename, O_RDONLY); + wpnt->fd = open(buffer, O_RDONLY); if (wpnt->fd < 0) { myerror(NULL); @@ -133,7 +149,7 @@ HINSTANCE LoadImage(char * filename, char * modulename) /* * Establish header pointers. */ - wpnt->filename = strdup(filename); + wpnt->filename = strdup(buffer); wpnt->name = NULL; if(modulename) wpnt->name = strdup(modulename); @@ -181,7 +197,7 @@ HINSTANCE LoadImage(char * filename, char * modulename) wpnt->selector_table = CreateSelectors(wpnt); wpnt->hinstance = wpnt-> - selector_table[wine_files->ne_header->auto_data_seg-1].selector; + selector_table[wpnt->ne_header->auto_data_seg-1].selector; /* Get the lookup table. This is used for looking up the addresses of functions that are exported */ @@ -227,16 +243,10 @@ HINSTANCE LoadImage(char * filename, char * modulename) if(FindDLLTable(buff)) continue; /* This module already loaded */ - if (FindFileInPath(buff2, sizeof(buff2), - buff, dllExtensions, WinePath) != NULL && - (fd = open(buff2, O_RDONLY)) >= 0) - { - close(fd); - LoadImage(buff2, buff); - continue; - } - + LoadImage(buff); +/* fprintf(stderr,"Unable to load:%s\n", buff); +*/ } return(wpnt->hinstance); } @@ -249,6 +259,8 @@ _WinMain(int argc, char **argv) { int segment; char *p; + char *sysresname; + char syspath[256]; char exe_path[256]; #ifdef WINESTAT char * cp; @@ -273,19 +285,20 @@ _WinMain(int argc, char **argv) strcat(WinePath, ";"); strcat(WinePath, p); - if (FindFileInPath(exe_path, 256, argv[1], exeExtensions, WinePath) - == NULL) - { - fprintf(stderr, "Could not find file '%s'\n", argv[1]); - exit(1); - } - - LoadImage(exe_path, NULL); - hSysRes = LoadImage("sysres.dll", NULL); + LoadImage(argv[1]); + hSysRes = LoadImage("sysres.dll"); + if (hSysRes == (HINSTANCE)NULL) + printf("Error Loading System Resources !!!\n"); + else + printf("System Resources Loaded // hSysRes='%04X'\n", hSysRes); if(ran_out) exit(1); #ifdef DEBUG - GetEntryDLLName("USER", "INITAPP", 0, 0); + { + int dummy1, dummy2; + + GetEntryDLLName("USER", "INITAPP", &dummy1, &dummy2); + } for(i=0; i<1024; i++) { int j; j = GetEntryPointFromOrdinal(wine_files, i); @@ -327,6 +340,21 @@ _WinMain(int argc, char **argv) init_wine_signals(); + if (WineForceFail) + { + p = (char *) ((cs_reg << 16) | ip_reg); + + *p++ = 0xcd; + *p++ = 0x20; + } + + if (ss_reg == 0) + { + fprintf(stderr, "SS is 0. Send email to bob@amscons.com.\n"); + fprintf(stderr, " No. Really. I want to know what programs\n"); + fprintf(stderr, " do this.\n"); + } + rv = CallToInit16(cs_reg << 16 | ip_reg, ss_reg << 16 | sp_reg, ds_reg); printf ("rv = %x\n", rv); } @@ -392,12 +420,11 @@ GetModuleName(struct w_files * wpnt, int index, char *buffer) int FixupSegment(struct w_files * wpnt, int segment_num) { - int fd = wpnt->fd; - struct mz_header_s * mz_header = wpnt->mz_header; - struct ne_header_s *ne_header = wpnt->ne_header; - struct ne_segment_table_entry_s *seg_table = wpnt->seg_table; - struct segment_descriptor_s *selector_table = wpnt->selector_table; - + int fd = wpnt->fd; + struct mz_header_s * mz_header = wpnt->mz_header; + struct ne_header_s *ne_header = wpnt->ne_header; + struct ne_segment_table_entry_s *seg_table = wpnt->seg_table; + struct segment_descriptor_s *selector_table = wpnt->selector_table; struct relocation_entry_s *rep, *rep1; struct ne_segment_table_entry_s *seg; struct segment_descriptor_s *sel; @@ -410,10 +437,14 @@ FixupSegment(struct w_files * wpnt, int segment_num) char dll_name[257]; char func_name[257]; int i, n_entries; + int additive; seg = &seg_table[segment_num]; sel = &selector_table[segment_num]; + fprintf(stderr, "Segment fixups for %s, segment %d, selector %x\n", + wpnt->name, segment_num, (int) sel->base_addr >> 16); + if ((seg->seg_data_offset == 0) || !(seg->seg_flags & NE_SEGFLAGS_RELOC_DATA)) return 0; @@ -445,8 +476,13 @@ FixupSegment(struct w_files * wpnt, int segment_num) /* * Get the target address corresponding to this entry. */ + additive = 0; + switch (rep->relocation_type) { + case NE_RELTYPE_ORDINALADD: + additive = 1; + case NE_RELTYPE_ORDINAL: if (GetModuleName(wpnt, rep->target1, dll_name) == NULL) @@ -474,6 +510,9 @@ FixupSegment(struct w_files * wpnt, int segment_num) #endif break; + case NE_RELTYPE_NAMEADD: + additive = 1; + case NE_RELTYPE_NAME: if (GetModuleName(wpnt, rep->target1, dll_name) == NULL) @@ -543,30 +582,50 @@ FixupSegment(struct w_files * wpnt, int segment_num) continue; default: -#ifndef DEBUG_FIXUP fprintf(stderr,"%d: ADDR TYPE %d, TYPE %d, OFFSET %04.4x, ", i + 1, rep->address_type, rep->relocation_type, rep->offset); - fprintf(stderr,"TARGET %04.4x %04.4x\n", rep->target1, rep->target2); -#endif + fprintf(stderr,"TARGET %04.4x %04.4x\n", + rep->target1, rep->target2); free(rep1); - return -1; +#if 0 + sp = (unsigned short *) ((char *) sel->base_addr + rep->offset); + fprintf(stderr, " FIXUP ADDRESS %04.4x:%04.4x\n", + (int) sel->base_addr >> 16, rep->offset); + WineForceFail = 1; + continue; +#endif } /* * Stuff the right size result in. */ sp = (unsigned short *) ((char *) sel->base_addr + rep->offset); + if (additive) + { + if (FindDLLTable(dll_name) == NULL) + additive = 2; + + fprintf(stderr,"%d: ADDR TYPE %d, TYPE %d, OFFSET %04.4x, ", + i + 1, rep->address_type, rep->relocation_type, + rep->offset); + fprintf(stderr,"TARGET %04.4x %04.4x\n", + rep->target1, rep->target2); + fprintf(stderr, " Additive = %d\n", additive); + } + switch (rep->address_type) { case NE_RADDR_OFFSET16: do { next_addr = *sp; *sp = (unsigned short) address; + if (additive == 2) + *sp += next_addr; sp = (unsigned short *) ((char *) sel->base_addr + next_addr); } - while (next_addr != 0xffff); + while (next_addr != 0xffff && !additive); break; @@ -574,10 +633,12 @@ FixupSegment(struct w_files * wpnt, int segment_num) do { next_addr = *sp; *sp = (unsigned short) address; + if (additive == 2) + *sp += next_addr; *(sp+1) = (unsigned short) selector; sp = (unsigned short *) ((char *) sel->base_addr + next_addr); } - while (next_addr != 0xffff); + while (next_addr != 0xffff && !additive); break; @@ -589,17 +650,15 @@ FixupSegment(struct w_files * wpnt, int segment_num) if (rep->relocation_type == NE_RELTYPE_INT1) break; } - while (next_addr != 0xffff); + while (next_addr != 0xffff && !additive); break; default: -#ifndef DEBUG_FIXUP printf("%d: ADDR TYPE %d, TYPE %d, OFFSET %04.4x, ", i + 1, rep->address_type, rep->relocation_type, rep->offset); printf("TARGET %04.4x %04.4x\n", rep->target1, rep->target2); -#endif free(rep1); return -1; } diff --git a/memory/Imakefile b/memory/Imakefile new file mode 100644 index 00000000000..edf4b6d5604 --- /dev/null +++ b/memory/Imakefile @@ -0,0 +1,21 @@ +#include "../Wine.tmpl" + +MODULE = memory + +SRCS = \ + global.c \ + heap.c \ + atom.c + +OBJS = \ + global.o \ + heap.o \ + atom.o + +WineRelocatableTarget($(TOP)/$(MODULE),,$(OBJS)) +DependTarget() +CleanTarget() + +includes:: + +install:: diff --git a/memory/Makefile b/memory/Makefile index b624e09fd6f..f3ff2c766b6 100644 --- a/memory/Makefile +++ b/memory/Makefile @@ -1,6 +1,6 @@ CFLAGS=$(COPTS) $(DEBUGOPTS) -I$(INCLUDE_DIR) -OBJS=global.o heap.o +OBJS=global.o heap.o atom.o default: memory.o diff --git a/memory/atom.c b/memory/atom.c new file mode 100644 index 00000000000..1fd5f489f89 --- /dev/null +++ b/memory/atom.c @@ -0,0 +1,328 @@ +/* + * Atom table functions + * + * Copyright 1993 Alexandre Julliard + */ + +/* + * Current limitations: + * + * - This code should work fine when called from the emulation library, + * but probably not when called from the Windows program. The reason + * is that everything is allocated on the current local heap, instead + * of taking into account the DS register. Correcting this will also + * require some changes in the local heap management to bring it closer + * to Windows. + * + * - The code assumes that LocalAlloc() returns a block aligned on a + * 4-bytes boundary (because of the shifting done in HANDLETOATOM). + * If this is not the case, the allocation code will have to be changed. + * + * - Integer atoms created with MAKEINTATOM are not supported. This is + * because they can't generally be differentiated from string constants + * located below 0x10000 in the emulation library. If you need + * integer atoms, use the "#1234" form. + */ + +#include +#include + +#include "atom.h" + + +#define DEFAULT_ATOMTABLE_SIZE 37 +#define MIN_STR_ATOM 0xc000 + +#define ATOMTOHANDLE(atom) ((HANDLE)(atom) << 2) +#define HANDLETOATOM(handle) ((ATOM)(0xc000 | ((handle) >> 2))) + + +static ATOMTABLE * localTable = NULL; +static ATOMTABLE * globalTable = NULL; + + +/*********************************************************************** + * ATOM_InitTable + */ +static BOOL ATOM_InitTable( ATOMTABLE ** table, WORD entries ) +{ + int i; + HANDLE handle; + + handle = LocalAlloc( LMEM_MOVEABLE, sizeof(ATOMTABLE) + + (entries-1) * sizeof(HANDLE) ); + if (!handle) return FALSE; + *table = (ATOMTABLE *) LocalLock( handle ); + (*table)->size = entries; + for (i = 0; i < entries; i++) (*table)->entries[i] = 0; + return TRUE; + +} + + +/*********************************************************************** + * ATOM_Init + * + * Global table initialisation. + */ +BOOL ATOM_Init() +{ + return ATOM_InitTable( &globalTable, DEFAULT_ATOMTABLE_SIZE ); +} + + +/*********************************************************************** + * ATOM_MakePtr + * + * Make an ATOMENTRY pointer from a handle (obtained from GetAtomHandle()). + * Is is assumed that the atom is in the same segment as the table. + */ +static ATOMENTRY * ATOM_MakePtr( ATOMTABLE * table, HANDLE handle ) +{ + return (ATOMENTRY *) (((int)table & 0xffff0000) | (int)handle); +} + + +/*********************************************************************** + * ATOM_Hash + */ +static WORD ATOM_Hash( WORD entries, LPCSTR str, WORD len ) +{ + WORD i, hash = 0; + + for (i = 0; i < len; i++) hash ^= str[i] + i; + return hash % entries; +} + + +/*********************************************************************** + * ATOM_AddAtom + */ +static ATOM ATOM_AddAtom( ATOMTABLE * table, LPCSTR str ) +{ + WORD hash; + HANDLE entry; + ATOMENTRY * entryPtr; + int len; + + if ((len = strlen( str )) > 255) len = 255; + + /* Check for integer atom */ +/* if (!((int)str & 0xffff0000)) return (ATOM)((int)str & 0xffff); */ + if (str[0] == '#') return atoi( &str[1] ); + + hash = ATOM_Hash( table->size, str, len ); + entry = table->entries[hash]; + while (entry) + { + entryPtr = ATOM_MakePtr( table, entry ); + if ((entryPtr->length == len) && + (!strncasecmp( entryPtr->str, str, len ))) + { + entryPtr->refCount++; + return HANDLETOATOM( entry ); + } + entry = entryPtr->next; + } + + entry = (int)LocalAlloc( LMEM_MOVEABLE, sizeof(ATOMENTRY)+len-1 ) & 0xffff; + if (!entry) return 0; + entryPtr = ATOM_MakePtr( table, entry ); + entryPtr->next = table->entries[hash]; + entryPtr->refCount = 1; + entryPtr->length = len; + memcpy( entryPtr->str, str, len ); + table->entries[hash] = entry; + return HANDLETOATOM( entry ); +} + + +/*********************************************************************** + * ATOM_DeleteAtom + */ +static ATOM ATOM_DeleteAtom( ATOMTABLE * table, ATOM atom ) +{ + ATOMENTRY * entryPtr; + HANDLE entry, *prevEntry; + WORD hash; + + if (atom < MIN_STR_ATOM) return 0; /* Integer atom */ + + entry = ATOMTOHANDLE( atom ); + entryPtr = ATOM_MakePtr( table, entry ); + + /* Find previous atom */ + hash = ATOM_Hash( table->size, entryPtr->str, entryPtr->length ); + prevEntry = &table->entries[hash]; + while (*prevEntry && *prevEntry != entry) + { + ATOMENTRY * prevEntryPtr = ATOM_MakePtr( table, *prevEntry ); + prevEntry = &prevEntryPtr->next; + } + if (!*prevEntry) return atom; + + /* Delete atom */ + if (--entryPtr->refCount == 0) + { + *prevEntry = entryPtr->next; + LocalFree( entry ); + } + return 0; +} + + +/*********************************************************************** + * ATOM_FindAtom + */ +static ATOM ATOM_FindAtom( ATOMTABLE * table, LPCSTR str ) +{ + WORD hash; + HANDLE entry; + int len; + + if ((len = strlen( str )) > 255) len = 255; + + /* Check for integer atom */ +/* if (!((int)str & 0xffff0000)) return (ATOM)((int)str & 0xffff); */ + if (str[0] == '#') return atoi( &str[1] ); + + hash = ATOM_Hash( table->size, str, len ); + entry = table->entries[hash]; + while (entry) + { + ATOMENTRY * entryPtr = ATOM_MakePtr( table, entry ); + if ((entryPtr->length == len) && + (!strncasecmp( entryPtr->str, str, len ))) + return HANDLETOATOM( entry ); + entry = entryPtr->next; + } + return 0; +} + + +/*********************************************************************** + * ATOM_GetAtomName + */ +static WORD ATOM_GetAtomName( ATOMTABLE * table, ATOM atom, + LPSTR buffer, short count ) +{ + ATOMENTRY * entryPtr; + HANDLE entry; + char * strPtr; + int len; + char text[8]; + + if (!count) return 0; + if (atom < MIN_STR_ATOM) + { + sprintf( text, "#%d", atom ); + len = strlen(text); + strPtr = text; + } + else + { + entry = ATOMTOHANDLE( atom ); + entryPtr = ATOM_MakePtr( table, entry ); + len = entryPtr->length; + strPtr = entryPtr->str; + } + if (len >= count) len = count-1; + memcpy( buffer, strPtr, len ); + buffer[len] = '\0'; + return len; +} + + +/*********************************************************************** + * InitAtomTable (KERNEL.68) + */ +BOOL InitAtomTable( WORD entries ) +{ + return ATOM_InitTable( &localTable, entries ); +} + + +/*********************************************************************** + * GetAtomHandle (KERNEL.73) + */ +HANDLE GetAtomHandle( ATOM atom ) +{ + if (atom < MIN_STR_ATOM) return 0; + return ATOMTOHANDLE( atom ); +} + + +/*********************************************************************** + * AddAtom (KERNEL.70) + */ +ATOM AddAtom( LPCSTR str ) +{ + if (!localTable) InitAtomTable( DEFAULT_ATOMTABLE_SIZE ); + return ATOM_AddAtom( localTable, str ); +} + + +/*********************************************************************** + * DeleteAtom (KERNEL.71) + */ +ATOM DeleteAtom( ATOM atom ) +{ + if (!localTable) InitAtomTable( DEFAULT_ATOMTABLE_SIZE ); + return ATOM_DeleteAtom( localTable, atom ); +} + + +/*********************************************************************** + * FindAtom (KERNEL.69) + */ +ATOM FindAtom( LPCSTR str ) +{ + if (!localTable) InitAtomTable( DEFAULT_ATOMTABLE_SIZE ); + return ATOM_FindAtom( localTable, str ); +} + + +/*********************************************************************** + * GetAtomName (KERNEL.72) + */ +WORD GetAtomName( ATOM atom, LPSTR buffer, short count ) +{ + if (!localTable) InitAtomTable( DEFAULT_ATOMTABLE_SIZE ); + return ATOM_GetAtomName( localTable, atom, buffer, count ); +} + + +/*********************************************************************** + * GlobalAddAtom (USER.268) + */ +ATOM GlobalAddAtom( LPCSTR str ) +{ + return ATOM_AddAtom( globalTable, str ); +} + + +/*********************************************************************** + * GlobalDeleteAtom (USER.269) + */ +ATOM GlobalDeleteAtom( ATOM atom ) +{ + return ATOM_DeleteAtom( globalTable, atom ); +} + + +/*********************************************************************** + * GlobalFindAtom (USER.270) + */ +ATOM GlobalFindAtom( LPCSTR str ) +{ + return ATOM_FindAtom( globalTable, str ); +} + + +/*********************************************************************** + * GlobalGetAtomName (USER.271) + */ +WORD GlobalGetAtomName( ATOM atom, LPSTR buffer, short count ) +{ + return ATOM_GetAtomName( globalTable, atom, buffer, count ); +} diff --git a/memory/global.c b/memory/global.c index 169ebc3878a..bf11b370f13 100644 --- a/memory/global.c +++ b/memory/global.c @@ -75,7 +75,7 @@ GlobalGetFreeSegments(unsigned int flags, int n_segments) else if (count) count = 0; } - + /* * If we couldn't find enough segments, then we need to create some. */ @@ -87,18 +87,22 @@ GlobalGetFreeSegments(unsigned int flags, int n_segments) g_prev = NULL; for (g = GlobalList; g != NULL; g = g->next) g_prev = g; - + /* * Allocate segments. */ for (count = 0; count < n_segments; count++) { s = GetNextSegment(flags, 0x10000); - if (s == NULL) + if (s == NULL) { + printf("GlobalGetFreeSegments // bad GetNextSegment !\n"); return NULL; - + } g = (GDESC *) malloc(sizeof(*g)); - + if (g == NULL) { + printf("GlobalGetFreeSegments // bad GDESC malloc !\n"); + return NULL; + } g->prev = g_prev; g->next = NULL; g->handle = s->selector; @@ -110,18 +114,15 @@ GlobalGetFreeSegments(unsigned int flags, int n_segments) else g->lock_count = 0; - free(s); - - if (count == 0) - g_start = g; + if (count == 0) g_start = g; if (g_prev != NULL) { g_prev->next = g; - g->prev = g_prev; } else GlobalList = g; + g_prev = g; } } @@ -131,6 +132,10 @@ GlobalGetFreeSegments(unsigned int flags, int n_segments) g = g_start; for (i = 0; i < n_segments; i++, g = g->next) { + if (g == NULL) { + printf("GlobalGetFreeSegments // bad Segments chain !\n"); + return NULL; + } g->sequence = i + 1; g->length = n_segments; } diff --git a/misc/Imakefile b/misc/Imakefile new file mode 100644 index 00000000000..53eda7629f5 --- /dev/null +++ b/misc/Imakefile @@ -0,0 +1,45 @@ +#include "../Wine.tmpl" + +MODULE = misc + +SRCS = \ + kernel.c \ + user.c \ + rect.c \ + file.c \ + sound.c \ + emulate.c \ + keyboard.c \ + profile.c \ + lstr.c \ + exec.c \ + message.c \ + int1a.c \ + int21.c \ + dos_fs.c \ + xt.c + +OBJS = \ + kernel.o \ + user.o \ + rect.o \ + file.o \ + sound.o \ + emulate.o \ + keyboard.o \ + profile.o \ + lstr.o \ + exec.o \ + message.o \ + int1a.o \ + int21.o \ + dos_fs.o \ + xt.o + +WineRelocatableTarget($(TOP)/$(MODULE),,$(OBJS)) +DependTarget() +CleanTarget() + +includes:: + +install:: diff --git a/misc/Makefile b/misc/Makefile index 12180d04200..8cdcee9ea77 100644 --- a/misc/Makefile +++ b/misc/Makefile @@ -1,7 +1,8 @@ -CFLAGS=$(COPTS) $(DEBUGOPTS) -I$(INCLUDE_DIR) +CFLAGS=$(COPTS) $(DEBUGOPTS) -I../include -OBJS=dos.o kernel.o user.o xt.o rect.o file.o sound.o emulate.o \ - keyboard.o profile.o lstr.o exec.o message.o +OBJS=kernel.o user.o xt.o rect.o file.o sound.o emulate.o \ + keyboard.o profile.o lstr.o exec.o message.o int1a.o int21.o \ + dos_fs.o comm.o default: misc.o diff --git a/misc/comm.c b/misc/comm.c new file mode 100644 index 00000000000..c0db9d590ff --- /dev/null +++ b/misc/comm.c @@ -0,0 +1,872 @@ +/* + * DEC 93 Erik Bos (erik@trashcan.hacktic.nl) + */ + +#include +#include +#include +#include +#include +#include +#ifdef __NetBSD__ +#include +#include +#endif +#include "wine.h" +#include "windows.h" + +#define DEBUG_COMM + +#define MAX_PORTS 16 + +int commerror = 0, eventmask = 0; + +struct DosDeviceStruct { + char *devicename; /* /dev/cua1 */ + int fd; + int suspended; +}; + +struct DosDeviceStruct COM[MAX_PORTS]; +struct DosDeviceStruct LPT[MAX_PORTS]; + +void Comm_DeInit(void); + +void Comm_Init(void) +{ + int x, serial = 0, parallel = 0; + char option[10], temp[256], *ptr; + struct stat st; + + for (x=0; x!=MAX_PORTS; x++) { + strcpy(option,"COMx"); + option[3] = '0' + x; + option[4] = '\0'; + + GetPrivateProfileString("serialports", option, "*", temp, sizeof(temp), WINE_INI); + if (!strcmp(temp, "*") || *temp == '\0') + COM[serial].devicename = NULL; + else { + stat(temp, &st); + if (!S_ISCHR(st.st_mode)) + fprintf(stderr,"comm: can 't use `%s' as COM%d !\n", temp, x); + else + if ((ptr = malloc(strlen(temp)+1)) == NULL) + fprintf(stderr,"comm: can't malloc for device info!\n"); + else { + COM[serial].fd = 0; + COM[serial].devicename = ptr; + strcpy(COM[serial++].devicename, temp); + } + } + + strcpy(option, "LPTx"); + option[3] = '0' + x; + option[4] = '\0'; + + GetPrivateProfileString("parallelports", option, "*", temp, sizeof(temp), WINE_INI); + if (!strcmp(temp, "*") || *temp == '\0') + LPT[parallel].devicename = NULL; + else { + stat(temp, &st); + if (!S_ISCHR(st.st_mode)) + fprintf(stderr,"comm: can 't use `%s' as LPT%d !\n", temp, x); + else + if ((ptr = malloc(strlen(temp)+1)) == NULL) + fprintf(stderr,"comm: can't malloc for device info!\n"); + else { + LPT[serial].fd = 0; + LPT[serial].devicename = ptr; + strcpy(LPT[serial++].devicename, temp); + } + } + + } + atexit(Comm_DeInit); + +#ifdef DEBUG_COMM + for (x=0; x!=MAX_PORTS; x++) { + if (COM[x].devicename) + fprintf(stderr, "comm: COM%d = %s\n", x, COM[x].devicename); + if (LPT[x].devicename) + fprintf(stderr, "comm: LPT%d = %s\n", x, LPT[x].devicename); + } +#endif +} + +void Comm_DeInit(void) +{ + int x; + + for (x=0; x!=MAX_PORTS; x++) { + + if (COM[x].devicename) { + if (COM[x].fd) + close(COM[x].fd); + fprintf(stderr, "comm: COM%d = %s\n",x,COM[x].devicename); + free(COM[x].devicename); + } + if (LPT[x].devicename) { + if (LPT[x].fd) + close(LPT[x].fd); + fprintf(stderr, "comm: LPT%d = %s\n",x,LPT[x].devicename); + free(LPT[x].devicename); + } + } +} + +struct DosDeviceStruct *GetDeviceStruct(int fd) +{ + int x; + + for (x=0; x!=MAX_PORTS; x++) { + if (COM[x].fd == fd) + return &COM[x]; + if (LPT[x].fd == fd) + return &LPT[x]; + } + + return NULL; +} + +int ValidCOMPort(int x) +{ + return(x < MAX_PORTS ? (int) COM[x].devicename : 0); +} + +int ValidLPTPort(int x) +{ + return(x < MAX_PORTS ? (int) LPT[x].devicename : 0); +} + +int WinError(void) +{ + perror("comm"); + switch (errno) { + default: + return CE_IOE; + } +} + +int BuildCommDCB(LPSTR device, DCB FAR *lpdcb) +{ + /* "COM1:9600,n,8,1" */ + /* 012345 */ + + int port; + char *ptr, *ptr2, temp[256],temp2[10]; + +#ifdef DEBUG_COMM +fprintf(stderr,"BuildCommDCB: (%s), ptr %d\n", device, lpdcb); +#endif + commerror = 0; + + if (!strncmp(device,"COM",3)) { + port = device[3] - '0'; + + if (!ValidCOMPort(port)) { + commerror = IE_BADID; + return -1; + } + + if (!COM[port].fd) { + commerror = IE_NOPEN; + return -1; + } + lpdcb->Id = COM[port].fd; + + if (!*(device+4)) + return 0; + + if (*(device+4) != ':') + return -1; + + strcpy(temp,device+5); + ptr = strtok(temp, ","); + + fprintf(stderr,"BuildCommDCB: baudrate (%s)\n", ptr); + lpdcb->BaudRate = atoi(ptr); + + ptr = strtok(NULL, ","); + if (islower(*ptr)) + *ptr = toupper(*ptr); + + fprintf(stderr,"BuildCommDCB: parity (%c)\n", *ptr); + switch (*ptr) { + case 'N': + lpdcb->Parity = NOPARITY; + lpdcb->fParity = 0; + break; + + lpdcb->fParity = 1; + + case 'E': + lpdcb->Parity = EVENPARITY; + break; + case 'M': + lpdcb->Parity = MARKPARITY; + break; + case 'O': + lpdcb->Parity = ODDPARITY; + break; + default: + fprintf(stderr,"comm: unknown parity `%c'!\n", *ptr); + return -1; + } + + ptr = strtok(NULL, ","); + fprintf(stderr, "BuildCommDCB: charsize (%c)\n", *ptr); + lpdcb->ByteSize = *ptr - '0'; + + ptr = strtok(NULL, ","); + fprintf(stderr, "BuildCommDCB: stopbits (%c)\n", *ptr); + switch (*ptr) { + case '1': + lpdcb->StopBits = ONESTOPBIT; + break; + case '2': + lpdcb->StopBits = TWOSTOPBITS; + break; + default: + fprintf(stderr,"comm: unknown # of stopbits `%c'!\n", *ptr); + return -1; + } + } + + return 0; +} + +int OpenComm(LPSTR device, UINT cbInQueue, UINT cbOutQueue) +{ + int port, fd; + +#ifdef DEBUG_COMM +fprintf(stderr,"OpenComm: %s, %d, %d\n", device, cbInQueue, cbOutQueue); +#endif + + commerror = 0; + + if (!strncmp(device,"COM",3)) { + port = device[3] - '0'; + + if (!ValidCOMPort(port)) { + commerror = IE_BADID; + return -1; + } + if (COM[port].fd) { + commerror = IE_OPEN; + return -1; + } + + fd = open(COM[port].devicename, O_RDWR | O_NONBLOCK, 0); + if (fd == -1) { + commerror = WinError(); + return -1; + } else { + COM[port].fd = fd; + return fd; + } + } + else + if (!strncmp(device,"LPT",3)) { + port = device[3] - '0'; + + if (!ValidLPTPort(port)) { + commerror = IE_BADID; + return -1; + } + if (LPT[port].fd) { + commerror = IE_OPEN; + return -1; + } + + fd = open(LPT[port].devicename, O_RDWR | O_NONBLOCK, 0); + if (fd == -1) { + commerror = WinError(); + return -1; + } else { + LPT[port].fd = fd; + return fd; + } + } + return 0; +} + +int CloseComm(int fd) +{ + int status; + +#ifdef DEBUG_COMM +fprintf(stderr,"CloseComm: fd %d\n", fd); +#endif + + if (close(fd) == -1) { + commerror = WinError(); + return -1; + } else { + commerror = 0; + return 0; + } +} + +int SetCommBreak(int fd) +{ + struct DosDeviceStruct *ptr; + +#ifdef DEBUG_COMM +fprintf(stderr,"SetCommBreak: fd: %d\n", fd); +#endif + + if ((ptr = GetDeviceStruct(fd)) == NULL) { + commerror = IE_BADID; + return -1; + } + + ptr->suspended = 1; + commerror = 0; + return 0; +} + +int ClearCommBreak(int fd) +{ + struct DosDeviceStruct *ptr; + +#ifdef DEBUG_COMM +fprintf(stderr,"ClearCommBreak: fd: %d\n", fd); +#endif + + if ((ptr = GetDeviceStruct(fd)) == NULL) { + commerror = IE_BADID; + return -1; + } + + ptr->suspended = 0; + commerror = 0; + return 0; +} + +LONG EscapeCommFunction(int fd, int nFunction) +{ + int max; + struct termios port; + +#ifdef DEBUG_COMM +fprintf(stderr,"EscapeCommFunction fd: %d, function: %d\n", fd, nFunction); +#endif + + if (tcgetattr(fd, &port) == -1) { + commerror = WinError(); + return -1; + } + + switch (nFunction) { + case RESETDEV: + break; + + case GETMAXCOM: + for (max = 0;COM[max].devicename;max++) + ; + return max; + break; + + case GETMAXLPT: + for (max = 0;LPT[max].devicename;max++) + ; + return 0x80 + max; + break; + + case CLRDTR: + port.c_cflag &= TIOCM_DTR; + break; + + case CLRRTS: + port.c_cflag &= TIOCM_RTS; + break; + + case SETDTR: + port.c_cflag |= CRTSCTS; + break; + + case SETRTS: + port.c_cflag |= CRTSCTS; + break; + + case SETXOFF: + port.c_iflag |= IXOFF; + break; + + case SETXON: + port.c_iflag |= IXON; + break; + + default: + fprintf(stderr,"EscapeCommFunction fd: %d, unknown function: %d\n", fd, nFunction); + break; + } + + if (tcsetattr(fd, TCSADRAIN, &port) == -1) { + commerror = WinError(); + return -1; + } else { + commerror = 0; + return 0; + } +} + +int FlushComm(int fd, int fnQueue) +{ + int queue; + +#ifdef DEBUG_COMM +fprintf(stderr,"FlushComm fd: %d, queue: %d\n", fd, fnQueue); +#endif + + switch (fnQueue) { + case 0: + queue = TCOFLUSH; + break; + case 1: + queue = TCIFLUSH; + break; + default: + fprintf(stderr,"FlushComm fd: %d, UNKNOWN queue: %d\n", fd, fnQueue); + return -1; + } + + if (tcflush(fd, fnQueue)) { + commerror = WinError(); + return -1; + } else { + commerror = 0; + return 0; + } +} + +int GetCommError(int fd, COMSTAT FAR *lpStat) +{ +#ifdef DEBUG_COMM +fprintf(stderr,"GetCommError: fd %d (current error %d)\n", fd, commerror); +#endif + + return(commerror); +} + +UINT FAR* SetCommEventMask(int fd, UINT fuEvtMask) +{ +#ifdef DEBUG_COMM +fprintf(stderr,"SetCommEventMask: fd %d, mask %d\n", fd, fuEvtMask); +#endif + + eventmask |= fuEvtMask; + return (UINT *)&eventmask; +} + +UINT GetCommEventMask(int fd, int fnEvtClear) +{ +#ifdef DEBUG_COMM +fprintf(stderr,"GetCommEventMask: fd %d, mask %d\n", fd, fnEvtClear); +#endif + eventmask &= ~fnEvtClear; + return eventmask; +} + +int SetCommState(DCB FAR *lpdcb) +{ + struct termios port; + +#ifdef DEBUG_COMM +fprintf(stderr,"SetCommState: fd %d, ptr %d\n", lpdcb->Id, lpdcb); +#endif + + if (tcgetattr(lpdcb->Id, &port) == -1) { + commerror = WinError(); + return -1; + } + cfmakeraw(&port); + port.c_cc[VMIN] = 0; + port.c_cc[VTIME] = 0; + + fprintf(stderr,"SetCommState: baudrate %d\n",lpdcb->BaudRate); +#ifdef CBAUD + port.c_cflag &= ~CBAUD; + switch (lpdcb->BaudRate) { + case 110: + case CBR_110: + port.c_cflag |= B110; + break; + case 300: + case CBR_300: + port.c_cflag |= B300; + break; + case 600: + case CBR_600: + port.c_cflag |= B600; + break; + case 1200: + case CBR_1200: + port.c_cflag |= B1200; + break; + case 2400: + case CBR_2400: + port.c_cflag |= B2400; + break; + case 4800: + case CBR_4800: + port.c_cflag |= B4800; + break; + case 9600: + case CBR_9600: + port.c_cflag |= B9600; + break; + case 19200: + case CBR_19200: + port.c_cflag |= B19200; + break; + case 38400: + case CBR_38400: + port.c_cflag |= B38400; + break; + default: + commerror = IE_BAUDRATE; + return -1; + } +#else + switch (lpdcb->BaudRate) { + case 110: + case CBR_110: + port.c_ospeed = B110; + break; + case 300: + case CBR_300: + port.c_ospeed = B300; + break; + case 600: + case CBR_600: + port.c_ospeed = B600; + break; + case 1200: + case CBR_1200: + port.c_ospeed = B1200; + break; + case 2400: + case CBR_2400: + port.c_ospeed = B2400; + break; + case 4800: + case CBR_4800: + port.c_ospeed = B4800; + break; + case 9600: + case CBR_9600: + port.c_ospeed = B9600; + break; + case 19200: + case CBR_19200: + port.c_ospeed = B19200; + break; + case 38400: + case CBR_38400: + port.c_ospeed = B38400; + break; + default: + commerror = IE_BAUDRATE; + return -1; + } + port.c_ispeed = port.c_ospeed; +#endif + fprintf(stderr,"SetCommState: bytesize %d\n",lpdcb->ByteSize); + port.c_cflag &= ~CSIZE; + switch (lpdcb->ByteSize) { + case 5: + port.c_cflag |= CS5; + break; + case 6: + port.c_cflag |= CS6; + break; + case 7: + port.c_cflag |= CS7; + break; + case 8: + port.c_cflag |= CS8; + break; + default: + commerror = IE_BYTESIZE; + return -1; + } + + fprintf(stderr,"SetCommState: parity %d\n",lpdcb->Parity); + port.c_cflag &= ~(PARENB | PARODD); + if (lpdcb->fParity) + switch (lpdcb->Parity) { + case NOPARITY: + port.c_iflag &= ~INPCK; + break; + case ODDPARITY: + port.c_cflag |= (PARENB | PARODD); + port.c_iflag |= INPCK; + break; + case EVENPARITY: + port.c_cflag |= PARENB; + port.c_iflag |= INPCK; + break; + default: + commerror = IE_BYTESIZE; + return -1; + } + + + fprintf(stderr,"SetCommState: stopbits %d\n",lpdcb->StopBits); + switch (lpdcb->StopBits) { + case ONESTOPBIT: + port.c_cflag &= ~CSTOPB; + break; + case TWOSTOPBITS: + port.c_cflag |= CSTOPB; + break; + default: + commerror = IE_BYTESIZE; + return -1; + } + + if (lpdcb->fDtrflow || lpdcb->fRtsflow || lpdcb->fOutxCtsFlow) + port.c_cflag |= CRTSCTS; + + if (lpdcb->fDtrDisable) + port.c_cflag &= ~CRTSCTS; + + if (lpdcb->fInX) + port.c_iflag |= IXON; + if (lpdcb->fOutX) + port.c_iflag |= IXOFF; + + if (tcsetattr(lpdcb->Id, TCSADRAIN, &port) == -1) { + commerror = WinError(); + return -1; + } else { + commerror = 0; + return 0; + } +} + +int GetCommState(int fd, DCB FAR *lpdcb) +{ + struct termios port; + +#ifdef DEBUG_COMM +fprintf(stderr,"GetCommState: fd %d, ptr %d\n", fd, lpdcb); +#endif + + if (tcgetattr(fd, &port) == -1) { + commerror = WinError(); + return -1; + } + + lpdcb->Id = fd; + +#ifdef CBAUD + switch (port.c_cflag & CBAUD) { +#else + switch (port.c_ospeed) { +#endif + case B110: + lpdcb->BaudRate = 110; + break; + case B300: + lpdcb->BaudRate = 300; + break; + case B600: + lpdcb->BaudRate = 600; + break; + case B1200: + lpdcb->BaudRate = 1200; + break; + case B2400: + lpdcb->BaudRate = 2400; + break; + case B4800: + lpdcb->BaudRate = 4800; + break; + case B9600: + lpdcb->BaudRate = 9600; + break; + case B19200: + lpdcb->BaudRate = 19200; + break; + case B38400: + lpdcb->BaudRate = 38400; + break; + } + + switch (port.c_cflag & CSIZE) { + case CS5: + lpdcb->ByteSize = 5; + break; + case CS6: + lpdcb->ByteSize = 6; + break; + case CS7: + lpdcb->ByteSize = 7; + break; + case CS8: + lpdcb->ByteSize = 8; + break; + } + + switch (port.c_cflag & ~(PARENB | PARODD)) { + case 0: + lpdcb->fParity = NOPARITY; + break; + case PARENB: + lpdcb->fParity = EVENPARITY; + break; + case (PARENB | PARODD): + lpdcb->fParity = ODDPARITY; + break; + } + + if (port.c_cflag & CSTOPB) + lpdcb->StopBits = TWOSTOPBITS; + else + lpdcb->StopBits = ONESTOPBIT; + + lpdcb->RlsTimeout = 50; + lpdcb->CtsTimeout = 50; + lpdcb->DsrTimeout = 50; + lpdcb->fNull = 0; + lpdcb->fChEvt = 0; + lpdcb->fBinary = 1; + + lpdcb->fDtrDisable = 0; + if (port.c_cflag & CRTSCTS) { + lpdcb->fDtrflow = 1; + lpdcb->fRtsflow = 1; + lpdcb->fOutxCtsFlow = 1; + lpdcb->fOutxDsrFlow = 1; + } else + lpdcb->fDtrDisable = 1; + + if (port.c_iflag & IXON) + lpdcb->fInX = 1; + else + lpdcb->fInX = 0; + + if (port.c_iflag & IXOFF) + lpdcb->fOutX = 1; + else + lpdcb->fOutX = 0; +/* + lpdcb->XonChar = + lpdcb->XoffChar = + */ + lpdcb->XonLim = 10; + lpdcb->XoffLim = 10; + + commerror = 0; + return 0; +} + +int TransmitCommChar(int fd, char chTransmit) +{ + struct DosDeviceStruct *ptr; + +#ifdef DEBUG_COMM +fprintf(stderr,"TransmitCommChar: fd %d, data %d \n", fd, chTransmit); +#endif + + if ((ptr = GetDeviceStruct(fd)) == NULL) { + commerror = IE_BADID; + return -1; + } + + if (ptr->suspended) { + commerror = IE_HARDWARE; + return -1; + } + + if (write(fd, (void *) &chTransmit, 1) == -1) { + commerror = WinError(); + return -1; + } else { + commerror = 0; + return 0; + } +} + +int UngetCommChar(int fd, char chUnget) +{ + struct DosDeviceStruct *ptr; + +#ifdef DEBUG_COMM +fprintf(stderr,"UngetCommChar: fd %d (char %d)\n", fd, chUnget); +#endif + fprintf(stderr,"NOT implemented!\n"); + + if ((ptr = GetDeviceStruct(fd)) == NULL) { + commerror = IE_BADID; + return -1; + } + + if (ptr->suspended) { + commerror = IE_HARDWARE; + return -1; + } + + commerror = 0; + return 0; +} + +int ReadComm(int fd, LPSTR lpvBuf, int cbRead) +{ + struct DosDeviceStruct *ptr; +#ifdef DEBUG_COMM +fprintf(stderr,"ReadComm: fd %d, ptr %d, length %d\n", fd, lpvBuf, cbRead); +#endif + if ((ptr = GetDeviceStruct(fd)) == NULL) { + commerror = IE_BADID; + return -1; + } + + if (ptr->suspended) { + commerror = IE_HARDWARE; + return -1; + } + + if (read(fd, (void *) lpvBuf, cbRead) == -1) { + commerror = WinError(); + return -1; + } else { + commerror = 0; + return 0; + } +} + +int WriteComm(int fd, LPSTR lpvBuf, int cbWrite) +{ + int x; + struct DosDeviceStruct *ptr; + +#ifdef DEBUG_COMM +fprintf(stderr,"WriteComm: fd %d, ptr %d, length %d\n", fd, lpvBuf, cbWrite); +#endif + + if ((ptr = GetDeviceStruct(fd)) == NULL) { + commerror = IE_BADID; + return -1; + } + + if (ptr->suspended) { + commerror = IE_HARDWARE; + return -1; + } + + for (x=0; x != cbWrite ; x++) + fprintf(stderr,"%c", *(lpvBuf + x) ); + + if (write(fd, (void *) lpvBuf, cbWrite) == -1) { + commerror = WinError(); + return -1; + } else { + commerror = 0; + return 0; + } +} diff --git a/misc/dos.c b/misc/dos.c deleted file mode 100644 index f5f80fcced5..00000000000 --- a/misc/dos.c +++ /dev/null @@ -1,76 +0,0 @@ -static char RCSId[] = "$Id$"; -static char Copyright[] = "Copyright Robert J. Amstadt, 1993"; - -#include -#include -#include -#include "prototypes.h" -#include "regfunc.h" - -static void -GetTimeDate(int time_flag) -{ - struct tm *now; - time_t ltime; - - ltime = time(NULL); - now = localtime(<ime); - if (time_flag) - { - _CX = (now->tm_hour << 8) | now->tm_min; - _DX = now->tm_sec << 8; - } - else - { - _CX = now->tm_year + 1900; - _DX = ((now->tm_mon + 1) << 8) | now->tm_mday; - _AX &= 0xff00; - _AX |= now->tm_wday; - } -#ifdef DEBUG_DOS - printf("GetTimeDate: AX = %04x, CX = %04x, DX = %04x\n", _AX, _CX, _DX); -#endif - - ReturnFromRegisterFunc(); - /* Function does not return */ -} - -/********************************************************************** - * KERNEL_DOS3Call - */ -int -KERNEL_DOS3Call() -{ - switch ((_AX >> 8) & 0xff) - { - case 0x30: - _AX = 0x0303; - ReturnFromRegisterFunc(); - /* Function does not return */ - - case 0x25: - case 0x35: - return 0; - - case 0x2a: - GetTimeDate(0); - /* Function does not return */ - - case 0x2c: - GetTimeDate(1); - /* Function does not return */ - - case 0x4c: - exit(_AX & 0xff); - - default: - fprintf(stderr, "DOS: AX %04x, BX %04x, CX %04x, DX %04x\n", - _AX, _BX, _CX, _DX); - fprintf(stderr, " SP %04x, BP %04x, SI %04x, DI %04x\n", - _SP, _BP, _SI, _DI); - fprintf(stderr, " DS %04x, ES %04x\n", - _DS, _ES); - } - - return 0; -} diff --git a/misc/dos_fs.c b/misc/dos_fs.c new file mode 100644 index 00000000000..e0722741415 --- /dev/null +++ b/misc/dos_fs.c @@ -0,0 +1,756 @@ +/* + * DOS-FS + * NOV 1993 Erik Bos (erik@(trashcan.)hacktic.nl) + * + * FindFile by Bob, hacked for dos & unixpaths by Erik. + */ + +#include +#include +#include +#include +#include +#ifdef __linux__ +#include +#endif +#ifdef __NetBSD__ +#include +#include +#endif +#include +#include "windows.h" +#include "wine.h" +#include "int21.h" + +/* + #define DEBUG +*/ +#define MAX_OPEN_DIRS 16 + +extern char WindowsDirectory[256], SystemDirectory[256],TempDirectory[256]; + +char WindowsPath[256]; + +void DOS_DeInitFS(void); +int DOS_SetDefaultDrive(int); +char *GetDirectUnixFileName(char *); +void ToDos(char *); +void ToUnix(char *); + +int CurrentDrive = 2; + +struct DosDriveStruct { /* eg: */ + char *rootdir; /* /usr/windows */ + char cwd[256]; /* / */ + char label[13]; /* DRIVE-A */ + unsigned int serialnumber; /* ABCD5678 */ + int disabled; /* 0 */ +}; + +struct DosDriveStruct DosDrives[MAX_DOS_DRIVES]; + +struct dosdirent DosDirs[MAX_OPEN_DIRS]; + +void DOS_InitFS(void) +{ + int x; + char drive[2], temp[256], *ptr; + + GetPrivateProfileString("wine", "windows", "c:\\windows", + WindowsDirectory, sizeof(WindowsDirectory), WINE_INI); + + GetPrivateProfileString("wine", "system", "c:\\windows\\system", + SystemDirectory, sizeof(SystemDirectory), WINE_INI); + + GetPrivateProfileString("wine", "temp", "c:\\windows", + TempDirectory, sizeof(TempDirectory), WINE_INI); + + GetPrivateProfileString("wine", "path", "c:\\windows;c:\\windows\\system", + WindowsPath, sizeof(WindowsPath), WINE_INI); + + ToDos(WindowsDirectory); + ToDos(SystemDirectory); + ToDos(TempDirectory); + ToDos(WindowsPath); + +#ifdef DEBUG + fprintf(stderr,"wine.ini = %s\n",WINE_INI); + fprintf(stderr,"win.ini = %s\n",WIN_INI); + fprintf(stderr,"windir = %s\n",WindowsDirectory); + fprintf(stderr,"sysdir = %s\n",SystemDirectory); + fprintf(stderr,"tempdir = %s\n",TempDirectory); + fprintf(stderr,"path = %s\n",WindowsPath); +#endif + + for (x=0; x!=MAX_DOS_DRIVES; x++) { + DosDrives[x].serialnumber = (0xEB0500L | x); + + drive[0] = 'A' + x; + drive[1] = '\0'; + GetPrivateProfileString("drives", drive, "*", temp, sizeof(temp), WINE_INI); + if (!strcmp(temp, "*") || *temp == '\0') { + DosDrives[x].rootdir = NULL; + DosDrives[x].cwd[0] = '\0'; + DosDrives[x].label[0] = '\0'; + DosDrives[x].disabled = 1; + continue; + } + + if ((ptr = (char *) malloc(strlen(temp)+1)) == NULL) { + fprintf(stderr,"DOSFS: can't malloc for drive info!"); + continue; + } + if (temp[strlen(temp)-1] == '/') + temp[strlen(temp)] = '\0'; + DosDrives[x].rootdir = ptr; + strcpy(DosDrives[x].rootdir, temp); + strcpy(DosDrives[x].cwd, "/windows/"); + strcpy(DosDrives[x].label, "DRIVE-"); + strcat(DosDrives[x].label, drive); + DosDrives[x].disabled = 0; + } + + atexit(DOS_DeInitFS); + + DOS_SetDefaultDrive(2); + + for (x=0; x!=MAX_DOS_DRIVES; x++) { + if (DosDrives[x].rootdir != NULL) { +#ifdef DEBUG + fprintf(stderr, "DOSFS: %c: => %-40s %s %s %X %d\n", + 'A'+x, + DosDrives[x].rootdir, + DosDrives[x].cwd, + DosDrives[x].label, + DosDrives[x].serialnumber, + DosDrives[x].disabled + ); +#endif + } + } + + for (x=0; x!=MAX_OPEN_DIRS ; x++) + DosDirs[x].inuse = 0; + +} + +void DOS_DeInitFS(void) +{ + int x; + + for (x=0; x!=MAX_DOS_DRIVES ; x++) + if (DosDrives[x].rootdir != NULL) { +#ifdef DEBUG + + fprintf(stderr, "DOSFS: %c: => %s %s %s %X %d\n", + 'A'+x, + DosDrives[x].rootdir, + DosDrives[x].cwd, + DosDrives[x].label, + DosDrives[x].serialnumber, + DosDrives[x].disabled + ); + free(DosDrives[x].rootdir); +#endif + } +} + +WORD DOS_GetEquipment(void) +{ + WORD equipment; + int diskdrives = 0; + +/* borrowed from Ralph Brown's interrupt lists + + bits 15-14: number of parallel devices + bit 13: [Conv] Internal modem + bit 12: reserved + bits 11- 9: number of serial devices + bit 8: reserved + bits 7- 6: number of diskette drives minus one + bits 5- 4: Initial video mode: + 00b = EGA,VGA,PGA + 01b = 40 x 25 color + 10b = 80 x 25 color + 11b = 80 x 25 mono + bit 3: reserved + bit 2: [PS] =1 if pointing device + [non-PS] reserved + bit 1: =1 if math co-processor + bit 0: =1 if diskette available for boot +*/ + + if (DosDrives[0].rootdir != NULL) + diskdrives++; + if (DosDrives[1].rootdir != NULL) + diskdrives++; + if (diskdrives) + diskdrives--; + + equipment = diskdrives << 6; + + return (equipment); +} + +int DOS_ValidDrive(int drive) +{ +/* +#ifdef DEBUG + fprintf(stderr,"ValidDrive %c (%d)\n",'A'+drive,drive); +#endif +*/ + if (drive >= MAX_DOS_DRIVES) + return 0; + if (DosDrives[drive].rootdir == NULL) + return 0; + if (DosDrives[drive].disabled) + return 0; + + return 1; +} + +int DOS_GetDefaultDrive(void) +{ +#ifdef DEBUG + fprintf(stderr,"GetDefaultDrive (%c)\n",'A'+CurrentDrive); +#endif + + return( CurrentDrive); +} + +int DOS_SetDefaultDrive(int drive) +{ +#ifdef DEBUG + fprintf(stderr,"SetDefaultDrive to %c:\n",'A'+drive); +#endif + + if (!DOS_ValidDrive(drive)) + return 1; + + CurrentDrive = drive; +} + +void ToUnix(char *s) +{ + while (*s) { + if (*s == '/') + break; + if (*s == '\\') + *s = '/'; + if (isupper(*s)) + *s = tolower(*s); + s++; + } +} + +void ToDos(char *s) +{ + while (*s) { + if (*s == '/') + *s = '\\'; + if (islower(*s)) + *s = toupper(*s); + s++; + } +} + +int DOS_DisableDrive(int drive) +{ + if (drive >= MAX_DOS_DRIVES) + return 0; + if (DosDrives[drive].rootdir == NULL) + return 0; + + DosDrives[drive].disabled = 1; + return 1; +} + +int DOS_EnableDrive(int drive) +{ + if (drive >= MAX_DOS_DRIVES) + return 0; + if (DosDrives[drive].rootdir == NULL) + return 0; + + DosDrives[drive].disabled = 0; + return 1; +} + +void GetUnixDirName(char *rootdir, char *name) +{ + int filename; + char *nameptr, *cwdptr; + + cwdptr = rootdir + strlen(rootdir); + nameptr = name; +/* +#ifdef DEBUG + fprintf(stderr,"GetUnixDirName: %s <=> %s => ",rootdir, name); +#endif +*/ + while (*nameptr) { + if (*nameptr == '.' & !filename) { + nameptr++; + if (*nameptr == '\0') { + cwdptr--; + break; + } + if (*nameptr == '.') { + cwdptr--; + while (cwdptr != rootdir) { + cwdptr--; + if (*cwdptr == '/') { + *(cwdptr+1) = '\0'; + goto next; + } + + } + goto next; + } + if (*nameptr == '\\' || *nameptr == '/') { + next: nameptr++; + filename = 0; + continue; + } + } + if (*nameptr == '\\' || *nameptr == '/') { + filename = 0; + if (nameptr == name) + cwdptr = rootdir; + *cwdptr++='/'; + nameptr++; + continue; + } + filename = 1; + *cwdptr++ = *nameptr++; + } + *cwdptr = '\0'; + + ToUnix(rootdir); +/* +#ifdef DEBUG + fprintf(stderr,"%s\n", rootdir); +#endif +*/ +} + +char *GetDirectUnixFileName(char *dosfilename) +{ + /* a:\windows\system.ini => /dos/windows/system.ini */ + + int drive; + char x, temp[256]; + + if (dosfilename[1] == ':') + { + drive = (islower(*dosfilename) ? toupper(*dosfilename) : *dosfilename) - 'A'; + + if (!DOS_ValidDrive(drive)) + return NULL; + else + dosfilename+=2; + } else + drive = CurrentDrive; + + strcpy(temp,DosDrives[drive].rootdir); + strcat(temp, DosDrives[drive].cwd); + GetUnixDirName(temp + strlen(DosDrives[drive].rootdir), dosfilename); + + ToUnix(temp); + +#ifdef DEBUG + fprintf(stderr,"GetDirectUnixFileName: %c:%s => %s\n",'A'+ drive, dosfilename, temp); +#endif + + return(temp); +} + +char *GetUnixFileName(char *dosfilename) +{ + char *dirname, *unixname, workingpath[256], temp[256]; + + /* check if program specified a path */ + + if (*dosfilename == '.' || *dosfilename == '\\') + return( GetDirectUnixFileName(dosfilename) ); + + /* nope, lets find it */ + +#ifdef DEBUG + fprintf(stderr,"GetUnixFileName: %s\n",dosfilename); +#endif + + strcpy(workingpath, WindowsPath); + + for(dirname = strtok(workingpath, ";") ; + dirname != NULL; + dirname = strtok(NULL, ";")) + { + strcpy(temp,dirname); + if (temp[strlen(temp)-1] != '\\') + strcat(temp,"\\"); + strcat(temp,dosfilename); + +#ifdef DEBUG + fprintf(stderr,"trying %s\n",temp); +#endif + + if ( (unixname = GetDirectUnixFileName(temp)) != NULL) + return unixname; + } + puts("FAILED!"); + return NULL; +} + +char *DOS_GetCurrentDir(int drive, char *dirname) +{ + /* should return 'windows\system' */ + + char temp[256]; + + if (!DOS_ValidDrive(drive)) + return 0; + + strcpy(temp, DosDrives[drive].cwd); + ToDos(temp); + + if (temp[strlen(temp)-1] == '\\') + temp[strlen(temp)] = '\0'; + +#ifdef DEBUG + fprintf(stderr,"DOS_GetCWD: %c:\%s",'A'+drive, temp+1); +#endif + return (temp+1); +} + +int DOS_ChangeDir(int drive, char *dirname) +{ + if (!DOS_ValidDrive(drive)) + return 0; + + GetUnixDirName(DosDrives[drive].cwd, dirname); + strcat(DosDrives[drive].cwd,"/"); +#ifdef DEBUG + fprintf(stderr,"DOS_SetCWD: %c:\%s",'A'+drive, DosDrives[drive].cwd); +#endif + return 1; +} + +int DOS_MakeDir(int drive, char *dirname) +{ + char temp[256]; + + if (!DOS_ValidDrive(drive)) + return 0; + + strcpy(temp, DosDrives[drive].cwd); + GetUnixDirName(temp, dirname); + strcat(DosDrives[drive].cwd,"/"); + + ToUnix(temp); + mkdir(temp,0); + +#ifdef DEBUG + fprintf(stderr,"DOS_MakeDir: %c:\%s => %s",'A'+drive, dirname, temp); +#endif +} + +/* +void main(void) +{ + strcpy(DosDrives[0].cwd, "1/2/3/"); + + puts(DosDrives[0].cwd); + ChangeDir(0,".."); + puts(DosDrives[0].cwd); + + ChangeDir(0,"..\\.."); + puts(DosDrives[0].cwd); + + ChangeDir(0,"."); + puts(DosDrives[0].cwd); + + ChangeDir(0,"test"); + puts(DosDrives[0].cwd); + + ChangeDir(0,"\\qwerty\\ab"); + puts(DosDrives[0].cwd); + + ChangeDir(0,"erik\\.\\bos\\..\\24"); + puts(DosDrives[0].cwd); + +} +*/ + +int DOS_GetSerialNumber(int drive, unsigned long *serialnumber) +{ + if (!DOS_ValidDrive(drive)) + return 0; + + *serialnumber = DosDrives[drive].serialnumber; + return 1; +} + +int DOS_SetSerialNumber(int drive, unsigned long serialnumber) +{ + if (!DOS_ValidDrive(drive)) + return 0; + + DosDrives[drive].serialnumber = serialnumber; + return 1; +} + +int DOS_GetFreeSpace(int drive, long *size, long *available) +{ + struct statfs info; + + if (!DOS_ValidDrive(drive)) + return 0; + + if (statfs(DosDrives[drive].rootdir, &info) < 0) { + fprintf(stderr,"dosfs: cannot do statfs(%s)\n",DosDrives[drive].rootdir); + return 0; + } + + *size = info.f_bsize * info.f_blocks / 1024; + *available = info.f_bavail * info.f_bsize / 1024; + + return 1; +} + +char *FindFile(char *buffer, int buflen, char *rootname, char **extensions, + char *path) +{ + char *workingpath; + char *dirname; + DIR *d; + struct dirent *f; + char **e; + int rootnamelen; + int found = 0; + + + if (strchr(rootname, '\\') != NULL) + { + strncpy(buffer, GetDirectUnixFileName(rootname), buflen); + ToUnix(buffer); + +#ifdef DEBUG +fprintf(stderr,"FindFile: %s -> %s\n",rootname,buffer); +#endif + + return buffer; + } + + if (strchr(rootname, '/') != NULL) + { + strncpy(buffer, rootname, buflen); + +#ifdef DEBUG +fprintf(stderr,"FindFile: %s -> %s\n",rootname,buffer); +#endif + + return buffer; + } + +#ifdef DEBUG +fprintf(stderr,"FindFile: looking for %s\n",rootname); +#endif + + ToUnix(rootname); + + rootnamelen = strlen(rootname); + workingpath = malloc(strlen(path) + 1); + if (workingpath == NULL) + return NULL; + strcpy(workingpath, path); + + for(dirname = strtok(workingpath, ";"); + dirname != NULL; + dirname = strtok(NULL, ";")) + { + if (strchr(dirname, '\\')!=NULL) + d = opendir( GetDirectUnixFileName(dirname) ); + else + d = opendir( dirname ); + +#ifdef DEBUG + fprintf(stderr,"in %s\n",dirname); +#endif + + if (d != NULL) + { + while ((f = readdir(d)) != NULL) + { + if (strncasecmp(rootname, f->d_name, rootnamelen) == 0) + { + if (extensions == NULL || + strcasecmp(rootname, f->d_name) == 0) + { + found = 1; + } + else if (f->d_name[rootnamelen] == '.') + { + for (e = extensions; *e != NULL; e++) + { + if (strcasecmp(*e, f->d_name + rootnamelen + 1) + == 0) + { + found = 1; + break; + } + } + } + + if (found) + { + if (strchr(dirname, '\\')!=NULL) + strncpy(buffer, GetDirectUnixFileName(dirname), buflen); + else + strncpy(buffer, dirname, buflen); + + if (buffer[strlen(buffer)-1]!='/') + strncat(buffer, "/", buflen - strlen(buffer)); + + strncat(buffer, f->d_name, buflen - strlen(buffer)); + closedir(d); + + ToUnix(buffer); + + return buffer; + } + } + } + closedir(d); + } + } + return NULL; +} + +/********************************************************************** + * WineIniFileName + */ +char *WineIniFileName(void) +{ + static char *IniName = NULL; + char inipath[256]; + + if (IniName) + return IniName; + + getcwd(inipath, 256); + strcat(inipath, ";"); + strcat(inipath, getenv("HOME")); + strcat(inipath, ";"); + strcat(inipath, getenv("WINEPATH")); + + IniName = malloc(1024); + if (FindFile(IniName, 1024, "wine.ini", NULL, inipath) == NULL) + { + free(IniName); + IniName = NULL; + return NULL; + } + + IniName = realloc(IniName, strlen(IniName) + 1); + + ToUnix(IniName); + + return IniName; +} + +char *WinIniFileName() +{ + char name[256]; + + strcpy(name,GetDirectUnixFileName(WindowsDirectory)); + strcat(name,"win.ini"); + + ToUnix(name); + + return name; +} + +struct dosdirent *DOS_opendir(char *dosdirname) +{ + int x,y; + char *unixdirname; + char temp[256]; + + for (x=0; x != MAX_OPEN_DIRS && DosDirs[x].inuse; x++) + ; + + if (x == MAX_OPEN_DIRS) + return NULL; + + if ((unixdirname = GetDirectUnixFileName(dosdirname)) == NULL) + return NULL; + + strcpy(temp,unixdirname); + + + y = strlen(temp); + + while (y--) + { + if (temp[y] == '/') + { + temp[y] = '\0'; + break; + } + } + + fprintf(stderr,"%s -> %s\n",unixdirname,temp); + + DosDirs[x].inuse = 1; + strcpy(DosDirs[x].unixpath, temp); + + if ((DosDirs[x].ds = opendir(temp)) == NULL) + return NULL; + + return &DosDirs[x]; +} + + +struct dosdirent *DOS_readdir(struct dosdirent *de) +{ + char temp[256]; + struct dirent *d; + struct stat st; + + if (!de->inuse) + return NULL; + + if ((d = readdir(de->ds)) == NULL) + { + closedir(de->ds); + de->inuse = 0; + return de; + } + + strcpy(de->filename, d->d_name); + if (d->d_reclen > 12) + de->filename[12] = '\0'; + ToDos (de->filename); + + de->attribute = 0x0; + + strcpy(temp,de->unixpath); + strcat(temp,"/"); + strcat(temp,de->filename); + ToUnix(temp); + stat (temp, &st); + if S_ISDIR(st.st_mode) + de->attribute |= 0x08; + + return de; +} + +void DOS_closedir(struct dosdirent *de) +{ + if (de->inuse) + { + closedir(de->ds); + de->inuse = 0; + } +} diff --git a/misc/file.c b/misc/file.c index 559fac09cd3..adc43683313 100644 --- a/misc/file.c +++ b/misc/file.c @@ -3,98 +3,29 @@ * * File I/O routines for the Linux Wine Project. * - * There are two main parts to this module - first there are the - * actual emulation functions, and secondly a routine for translating - * DOS filenames into UNIX style filenames. - * - * For each DOS drive letter, we need to store the location in the unix - * file system to map that drive to, and the current directory for that - * drive. - * - * Finally we need to store the current drive letter in this module. - * * WARNING : Many options of OpenFile are not yet implemeted. * - * + * NOV 93 Erik Bos (erik@(trashcan.)hacktic.nl + * - removed ParseDosFileName, and DosDrive structures. + * - structures dynamically configured at runtime. + * - _lopen modified to use GetUnixFileName. + * + * DEC 93 Erik Bos (erik@(trashcan.)hacktic.nl) + * - Existing functions modified to use dosfs functions. + * - Added _llseek, _lcreate, GetDriveType, GetTempDrive, + * GetWindowsDirectory, GetSystemDirectory, GetTempFileName. + * ************************************************************************/ +#define DEBUG_FILE + #include -#include #include #include -#include #include +#include "prototypes.h" -#define OPEN_MAX 256 - -/*************************************************************************** - This structure stores the infomation needed for a single DOS drive - ***************************************************************************/ -struct DosDriveStruct -{ - char RootDirectory [256]; /* Unix base for this drive letter */ - char CurrentDirectory [256]; /* Current directory for this drive */ -}; - -/*************************************************************************** - Table for DOS drives - ***************************************************************************/ -struct DosDriveStruct DosDrives[] = -{ - {"/mnt/floppy1" , ""}, - {"/mnt/floppy2" , ""}, - {"/mnt/HardDisk", "/wine"}, - {"" , "/wine/Wine"} -}; - -#define NUM_DRIVES (sizeof (DosDrives) / sizeof (struct DosDriveStruct)) - - -/************************************************************************** - Global variable to store current drive letter (0 = A, 1 = B etc) - **************************************************************************/ -int CurrentDrive = 2; - -/************************************************************************** - ParseDOSFileName - - Return a fully specified DOS filename with the disk letter separated from - the path information. - **************************************************************************/ -void ParseDOSFileName (char *UnixFileName, char *DosFileName, int *Drive) -{ - int character; - - for (character = 0; character < strlen(DosFileName); character++) - { - if (DosFileName[character] == '\\') - DosFileName[character] = '/'; - } - - - if (DosFileName[1] == ':') - { - *Drive = DosFileName[0] - 'A'; - if (*Drive > 26) - *Drive = *Drive - 'a' + 'A'; - DosFileName = DosFileName + 2; - } - else - *Drive = CurrentDrive; - - if (DosFileName[0] == '/') - { - strcpy (UnixFileName, DosDrives[*Drive].RootDirectory); - strcat (UnixFileName, DosFileName); - return; - } - - strcpy (UnixFileName, DosDrives[*Drive].RootDirectory); - strcat (UnixFileName, DosDrives[*Drive].CurrentDirectory); - strcat (UnixFileName, "/"); - strcat (UnixFileName, DosFileName); - return; -} +char WindowsDirectory[256], SystemDirectory[256], TempDirectory[256]; /*************************************************************************** @@ -104,20 +35,26 @@ void ParseDOSFileName (char *UnixFileName, char *DosFileName, int *Drive) ***************************************************************************/ WORD KERNEL__lopen (LPSTR lpPathName, WORD iReadWrite) { - char UnixFileName[256]; - int Drive; int handle; + char *UnixFileName; - ParseDOSFileName (UnixFileName, lpPathName, &Drive); - +#ifdef DEBUG_FILE + fprintf (stderr, "_lopen: open %s\n", lpPathName); +#endif + if ((UnixFileName = GetUnixFileName(lpPathName)) == NULL) + return HFILE_ERROR; handle = open (UnixFileName, iReadWrite); #ifdef DEBUG_FILE - fprintf (stderr, "_lopen: %s (Handle = %d)\n", UnixFileName, handle); + fprintf (stderr, "_lopen: open: %s (handle %d)\n", UnixFileName, handle); #endif - return handle; + + if (handle == -1) + return HFILE_ERROR; + else + return handle; } /*************************************************************************** @@ -126,26 +63,37 @@ WORD KERNEL__lopen (LPSTR lpPathName, WORD iReadWrite) WORD KERNEL__lread (WORD hFile, LPSTR lpBuffer, WORD wBytes) { int result; + +#ifdef DEBUG_FILE + fprintf(stderr, "_lread: handle %d, buffer = %ld, length = %d\n", + hFile, lpBuffer, wBytes); +#endif result = read (hFile, lpBuffer, wBytes); -#ifdef DEBUG_FILE - fprintf(stderr, "_lread: hFile = %d, lpBuffer = %s, wBytes = %d\n", - hFile, lpBuffer, wBytes); -#endif - return result; -} + if (result == -1) + return HFILE_ERROR; + else + return result; +} /**************************************************************************** _lwrite ****************************************************************************/ WORD KERNEL__lwrite (WORD hFile, LPSTR lpBuffer, WORD wBytes) { + int result; + #ifdef DEBUG_FILE - fprintf(stderr, "_lwrite: hFile = %d, lpBuffer = %s, wBytes = %d\n", - hFile, lpBuffer, wBytes); + fprintf(stderr, "_lwrite: handle %d, buffer = %ld, length = %d\n", + hFile, lpBuffer, wBytes); #endif - return write (hFile, lpBuffer, wBytes); + result = write (hFile, lpBuffer, wBytes); + + if (result == -1) + return HFILE_ERROR; + else + return result; } /*************************************************************************** @@ -153,6 +101,10 @@ WORD KERNEL__lwrite (WORD hFile, LPSTR lpBuffer, WORD wBytes) ***************************************************************************/ WORD KERNEL__lclose (WORD hFile) { +#ifdef DEBUG_FILE + fprintf(stderr, "_lclose: handle %d\n", hFile); +#endif + close (hFile); } @@ -166,7 +118,9 @@ WORD KERNEL_OpenFile (LPSTR lpFileName, LPOFSTRUCT ofs, WORD wStyle) { int base,flags; +#ifdef DEBUG_FILE fprintf(stderr,"Openfile(%s,,%d) ",lpFileName,wStyle); +#endif base=wStyle&0xF; flags=wStyle&0xFFF0; @@ -204,7 +158,148 @@ WORD SetHandleCount (WORD wNumber) return((wNumber %s\n",bDriveLetter, + lpszPrefixString,uUnique,lpszTempFileName); +#endif + + return unique; +} + +/*************************************************************************** + SetErrorMode + ***************************************************************************/ +WORD SetErrorMode(WORD x) +{ + fprintf(stderr,"wine: SetErrorMode %4x (ignored)\n",x); +} diff --git a/loader/int1a.c b/misc/int1a.c similarity index 93% rename from loader/int1a.c rename to misc/int1a.c index 2441d77f526..addfdbcbb92 100644 --- a/loader/int1a.c +++ b/misc/int1a.c @@ -51,7 +51,7 @@ int do_int1A(struct sigcontext_struct * context){ break; default: - fprintf(stderr,"Unable to handle int 0x1A AX %x\n", context->sc_eax); + fprintf(stderr,"Unable to handle int 0x1A AX %04x\n", context->sc_eax & 0xffffL); return 1; }; return 1; diff --git a/loader/int21.c b/misc/int21.c similarity index 52% rename from loader/int21.c rename to misc/int21.c index fdf506aa486..4d1ae704d76 100644 --- a/loader/int21.c +++ b/misc/int21.c @@ -5,34 +5,23 @@ #include #include #include -#ifdef linux -#include -#endif -#ifdef __NetBSD__ -#include -#endif #include #include #include +#include "prototypes.h" +#include "regfunc.h" #include "windows.h" #include "wine.h" #include "int21.h" -#include "files.h" -#define MAX_DRIVES 26 - -static char Copyright[] = "int21.c, copyright Erik Bos, 1993"; - -extern struct DosDriveStruct DosDrives[]; -extern int CurrentDrive; -extern void ParseDOSFileName(); - -int ValidDrive(int); +static char Copyright[] = "copyright Erik Bos, 1993"; WORD ExtendedError, CodePage = 437; BYTE ErrorClass, Action, ErrorLocus; +extern char *TempDirectory; + void Error(int e, int class, int el) { ExtendedError = e; @@ -44,115 +33,99 @@ void Error(int e, int class, int el) void GetFreeDiskSpace(struct sigcontext_struct *context) { int drive; - struct statfs info; - long size,avail; + long size,available; - if (!(DX & 0xff)) - drive = CurrentDrive; + if (!(EDX & 0xffL)) + drive = DOS_GetDefaultDrive(); else - drive = (DX & 0xff) - 1; + drive = (EDX & 0xffL) - 1; - if (!ValidDrive(drive)) { + if (!DOS_ValidDrive(drive)) { Error(InvalidDrive, EC_MediaError , EL_Disk); - AX = 0xffff; + EAX |= 0xffffL; return; } - { - if (statfs(DosDrives[drive].RootDirectory, &info) < 0) { - fprintf(stderr,"cannot do statfs(%s)\n",DosDrives[drive].RootDirectory); - Error(GeneralFailure, EC_MediaError , EL_Disk); - AX = 0xffff; - return; - } - - size = info.f_bsize * info.f_blocks / 1024; - avail = info.f_bavail * info.f_bsize / 1024; - - #ifdef DOSDEBUG - fprintf(stderr,"statfs: size: %8d avail: %8d\n",size,avail); - #endif - - AX = SectorsPerCluster; - CX = SectorSize; - - BX = (avail / (CX * AX)); - DX = (size / (CX * AX)); - Error (0,0,0); + if (!DOS_GetFreeSpace(drive, &size, &available)) { + Error(GeneralFailure, EC_MediaError , EL_Disk); + EAX |= 0xffffL; + return; } + + EAX = (EAX & 0xffff0000L) | SectorsPerCluster; + ECX = (ECX & 0xffff0000L) | SectorSize; + + EBX = (EBX & 0xffff0000L) | (available / (CX * AX)); + EDX = (EDX & 0xffff0000L) | (size / (CX * AX)); + Error (0,0,0); } void SetDefaultDrive(struct sigcontext_struct *context) { - if ((DX & 0xff) < MAX_DRIVES) { - CurrentDrive = DX & 0xff; - AX &= 0xff00; - AX |= MAX_DRIVES; /* # of valid drive letters */ - Error (0,0,0); - } else + int drive; + + drive = EDX & 0xffL; + + if (!DOS_ValidDrive(drive)) { Error (InvalidDrive, EC_MediaError, EL_Disk); + return; + } else { + DOS_SetDefaultDrive(drive); + EAX = (EAX &0xffffff00L) | MAX_DOS_DRIVES; + Error (0,0,0); + } } void GetDefaultDrive(struct sigcontext_struct *context) { - AX &= 0xff00; - AX |= CurrentDrive; + EAX = (EAX & 0xffffff00L) | DOS_GetDefaultDrive(); Error (0,0,0); } void GetDriveAllocInfo(struct sigcontext_struct *context) { int drive; - long size; + long size, available; BYTE mediaID; - struct statfs info; - drive = DX & 0xff; + drive = EDX & 0xffL; - if (!ValidDrive(drive)) { - AX = SectorsPerCluster; - CX = SectorSize; - DX = 0; + if (!DOS_ValidDrive(drive)) { + EAX = (EAX & 0xffff0000L) | SectorsPerCluster; + ECX = (ECX & 0xffff0000L) | SectorSize; + EDX = (EDX & 0xffff0000L); Error (InvalidDrive, EC_MediaError, EL_Disk); return; } - { - if (statfs(DosDrives[drive].RootDirectory, &info) < 0) { - fprintf(stderr,"cannot do statfs(%s)\n",DosDrives[drive].RootDirectory); - Error(GeneralFailure, EC_MediaError , EL_Disk); - AX = 0xffff; - return; - } - - size = info.f_bsize * info.f_blocks / 1024; - - #ifdef DOSDEBUG - fprintf(stderr,"statfs: size: %8d\n",size); - #endif - - AX = SectorsPerCluster; - CX = SectorSize; - DX = (size / (CX * AX)); - - mediaID = 0xf0; - - DS = segment(mediaID); - BX = offset(mediaID); - Error (0,0,0); + if (!DOS_GetFreeSpace(drive, &size, &available)) { + Error(GeneralFailure, EC_MediaError , EL_Disk); + EAX |= 0xffffL; + return; } + + EAX = (EAX & 0xffff0000L) | SectorsPerCluster; + ECX = (ECX & 0xffff0000L) | SectorSize; + EDX = (EDX & 0xffff0000L) | (size / (CX * AX)); + + mediaID = 0xf0; + + DS = segment(mediaID); + EBX = offset(mediaID); + Error (0,0,0); } void GetDefDriveAllocInfo(struct sigcontext_struct *context) { - DX = CurrentDrive; + EDX = DOS_GetDefaultDrive(); GetDriveAllocInfo(context); } void GetDrivePB(struct sigcontext_struct *context) { Error (InvalidDrive, EC_MediaError, EL_Disk); - AX = 0xff; /* I'm sorry but I only got networked drives :-) */ + EAX = (EAX & 0xffff0000L) | 0xffL; + /* I'm sorry but I only got networked drives :-) */ } void ReadFile(struct sigcontext_struct *context) @@ -162,26 +135,26 @@ void ReadFile(struct sigcontext_struct *context) /* can't read from stdout / stderr */ - if (((BX & 0xffff) == 1) ||((BX & 0xffff) == 2)) { + if ((BX == 1) || (BX == 2)) { Error (InvalidHandle, EL_Unknown, EC_Unknown); - AX = InvalidHandle; + EAX = (EAX & 0xffff0000L) | InvalidHandle; SetCflag; return; } ptr = (char *) pointer (DS,DX); - if ((BX & 0xffff) == 0) { + if (BX == 0) { *ptr = EOF; Error (0,0,0); - AX = 1; + EAX = (EAX & 0xffff0000L) | 1; ResetCflag; return; } else { size = read(BX, ptr, CX); if (size == 0) { Error (ReadFault, EC_Unknown, EL_Unknown); - AX = ExtendedError; + EAX = (EAX & 0xffffff00L) | ExtendedError; return; } @@ -197,12 +170,12 @@ void ReadFile(struct sigcontext_struct *context) Error (GeneralFailure, EC_SystemFailure, EL_Unknown); break; } - AX = ExtendedError; + EAX = (EAX & 0xffffff00L) | ExtendedError; SetCflag; return; } Error (0,0,0); - AX = size; + EAX = (EAX & 0xffff0000L) | size; ResetCflag; } } @@ -214,27 +187,27 @@ void WriteFile(struct sigcontext_struct *context) ptr = (char *) pointer (DS,DX); - if ((BX & 0xffff) == 0) { + if (BX == 0) { Error (InvalidHandle, EC_Unknown, EL_Unknown); - AX = InvalidHandle; + EAX = InvalidHandle; SetCflag; return; } - if ((BX & 0xffff) < 3) { + if (BX < 3) { for (x = 0;x != CX;x++) { fprintf(stderr, "%c", *ptr++); } fflush(stderr); Error (0,0,0); - AX = CX; + EAX = (EAX & 0xffffff00L) | CX; ResetCflag; } else { size = write(BX, ptr , CX); if (size == 0) { Error (WriteFault, EC_Unknown, EL_Unknown); - AX = ExtendedError; + EAX = (EAX & 0xffffff00L) | ExtendedError; return; } @@ -253,105 +226,82 @@ void WriteFile(struct sigcontext_struct *context) Error (GeneralFailure, EC_SystemFailure, EL_Unknown); break; } - AX = ExtendedError; + EAX = (EAX & 0xffffff00L) | ExtendedError; SetCflag; return; } Error (0,0,0); - AX = size; + EAX = (EAX & 0xffff0000L) | size; ResetCflag; } } void UnlinkFile(struct sigcontext_struct *context) { - char UnixFileName[256]; - int drive, status; - - ParseDOSFileName(UnixFileName, (char *) pointer(DS,DX), &drive); - - { - status = unlink((char *) pointer(DS,DX)); - if (status == -1) { - switch (errno) { - case EACCES: - case EPERM: - case EROFS: - Error (WriteProtected, EC_AccessDenied, EL_Unknown); - break; - case EBUSY: - Error (LockViolation, EC_AccessDenied, EL_Unknown); - break; - case EAGAIN: - Error (ShareViolation, EC_Temporary, EL_Unknown); - break; - case ENOENT: - Error (FileNotFound, EC_NotFound, EL_Unknown); - break; - default: - Error (GeneralFailure, EC_SystemFailure, EL_Unknown); - break; - } - AX = ExtendedError; - SetCflag; - return; - } - Error (0,0,0); - ResetCflag; - } + if (unlink( GetUnixFileName((char *) pointer(DS,DX)) ) == -1) { + switch (errno) { + case EACCES: + case EPERM: + case EROFS: + Error (WriteProtected, EC_AccessDenied, EL_Unknown); + break; + case EBUSY: + Error (LockViolation, EC_AccessDenied, EL_Unknown); + break; + case EAGAIN: + Error (ShareViolation, EC_Temporary, EL_Unknown); + break; + case ENOENT: + Error (FileNotFound, EC_NotFound, EL_Unknown); + break; + default: + Error (GeneralFailure, EC_SystemFailure, EL_Unknown); + break; + } + EAX = (EAX & 0xffffff00L) | ExtendedError; SetCflag; + return; + } + Error (0,0,0); + ResetCflag; } void SeekFile(struct sigcontext_struct *context) { - char UnixFileName[256]; - int drive, handle, status, fileoffset; + int handle, status, fileoffset; - - ParseDOSFileName(UnixFileName, (char *) pointer(DS,DX), &drive); - - { - switch (AX & 0xff) { - case 1: fileoffset = SEEK_CUR; + switch (EAX & 0xffL) { + case 1: fileoffset = SEEK_CUR; + break; + case 2: fileoffset = SEEK_END; + break; + default: + case 0: fileoffset = SEEK_SET; + break; + } + status = lseek(BX, (CX * 0x100) + DX, fileoffset); + if (status == -1) { + switch (errno) { + case EBADF: + Error (InvalidHandle, EC_AppError, EL_Unknown); break; - case 2: fileoffset = SEEK_END; + case EINVAL: + Error (DataInvalid, EC_AppError, EL_Unknown); break; default: - case 0: fileoffset = SEEK_SET; + Error (GeneralFailure, EC_SystemFailure, EL_Unknown); break; } - status = lseek(BX, (CX * 0x100) + DX, fileoffset); - if (status == -1) { - switch (errno) { - case EBADF: - Error (InvalidHandle, EC_AppError, EL_Unknown); - break; - case EINVAL: - Error (DataInvalid, EC_AppError, EL_Unknown); - break; - default: - Error (GeneralFailure, EC_SystemFailure, EL_Unknown); - break; - } - AX = ExtendedError; - SetCflag; - return; - } - Error (0,0,0); - ResetCflag; - } + EAX = (EAX & 0xffffff00L) | ExtendedError; SetCflag; + return; + } + Error (0,0,0); + ResetCflag; } void GetFileAttributes(struct sigcontext_struct *context) { - char UnixFileName[256]; - int drive,handle; - - ParseDOSFileName(UnixFileName, (char *) pointer(DS,DX), &drive); - - { - CX = 0x0; - ResetCflag; - } + EAX &= 0xfffff00L; + ResetCflag; } void SetFileAttributes(struct sigcontext_struct *context) @@ -361,13 +311,14 @@ void SetFileAttributes(struct sigcontext_struct *context) void DosIOCTL(struct sigcontext_struct *context) { - AX = UnknownUnit; + fprintf(stderr,"int21: IOCTL\n"); + EAX = (EAX & 0xfffff00L) | UnknownUnit; SetCflag; } void DupeFileHandle(struct sigcontext_struct *context) { - AX = dup(BX); + EAX = (EAX & 0xffff0000L) | dup(BX); ResetCflag; } @@ -379,10 +330,9 @@ void GetSystemDate(struct sigcontext_struct *context) ltime = time(NULL); now = localtime(<ime); - CX = now->tm_year + 1900; - DX = ((now->tm_mon + 1) << 8) | now->tm_mday; - AX &= 0xff00; - AX |= now->tm_wday; + ECX = (ECX & 0xffff0000L) | now->tm_year + 1900; + EDX = (EDX & 0xffff0000L) | ((now->tm_mon + 1) << 8) | now->tm_mday; + EAX = (EAX & 0xffff0000L) | now->tm_wday; } void GetSystemTime(struct sigcontext_struct *context) @@ -393,115 +343,102 @@ void GetSystemTime(struct sigcontext_struct *context) ltime = time(NULL); now = localtime(<ime); - CX = (now->tm_hour << 8) | now->tm_min; - DX = now->tm_sec << 8; + ECX = (ECX & 0xffffff00L) | (now->tm_hour << 8) | now->tm_min; + EDX = (EDX & 0xffffff00L) | now->tm_sec << 8; } void GetExtendedErrorInfo(struct sigcontext_struct *context) { - AX = ExtendedError; - BX = (0x100 * ErrorClass) | Action; - CX &= 0x00ff; - CX |= (0x100 * ErrorLocus); + EAX = (EAX & 0xffffff00L) | ExtendedError; + EBX = (EBX & 0xffff0000L) | (0x100 * ErrorClass) | Action; + ECX = (ECX & 0xffff00ffL) | (0x100 * ErrorLocus); } void GetInDosFlag(struct sigcontext_struct *context) { const BYTE InDosFlag = 0; - ES = segment(InDosFlag); - BX = offset(InDosFlag); + ES = (ES & 0xffff0000L) | segment(InDosFlag); + EBX = (EBX & 0xffff0000L) | offset(InDosFlag); } void CreateFile(struct sigcontext_struct *context) { - char UnixFileName[256]; - int drive,handle; - - ParseDOSFileName(UnixFileName, (char *) pointer(DS,DX), &drive); + int handle; - { - handle = open(UnixFileName, O_CREAT | O_TRUNC); - - if (handle == -1) { - switch (errno) { - case EACCES: - case EPERM: - case EROFS: - Error (WriteProtected, EC_AccessDenied, EL_Unknown); - break; - case EISDIR: - Error (CanNotMakeDir, EC_AccessDenied, EL_Unknown); - break; - case ENFILE: - case EMFILE: - Error (NoMoreFiles, EC_MediaError, EL_Unknown); - case EEXIST: - Error (FileExists, EC_Exists, EL_Disk); - break; - case ENOSPC: - Error (DiskFull, EC_MediaError, EL_Disk); - break; - default: - Error (GeneralFailure, EC_SystemFailure, EL_Unknown); - break; - } - AX = ExtendedError; - SetCflag; - return; - } - Error (0,0,0); - BX = handle; - AX = NoError; - ResetCflag; - } + if ((handle = open(GetUnixFileName((char *) pointer(DS,DX)), O_CREAT | O_TRUNC)) == -1) { + switch (errno) { + case EACCES: + case EPERM: + case EROFS: + Error (WriteProtected, EC_AccessDenied, EL_Unknown); + break; + case EISDIR: + Error (CanNotMakeDir, EC_AccessDenied, EL_Unknown); + break; + case ENFILE: + case EMFILE: + Error (NoMoreFiles, EC_MediaError, EL_Unknown); + case EEXIST: + Error (FileExists, EC_Exists, EL_Disk); + break; + case ENOSPC: + Error (DiskFull, EC_MediaError, EL_Disk); + break; + default: + Error (GeneralFailure, EC_SystemFailure, EL_Unknown); + break; + } + EAX = (EAX & 0xffffff00L) | ExtendedError; + SetCflag; + return; + } + Error (0,0,0); + EBX = (EBX & 0xffff0000L) | handle; + EAX = (EAX & 0xffffff00L) | NoError; + ResetCflag; } void OpenExistingFile(struct sigcontext_struct *context) { - char UnixFileName[256]; - int drive, handle; - - ParseDOSFileName(UnixFileName, (char *) pointer(DS,DX), &drive); - - { - handle = open(UnixFileName, O_RDWR); + int handle; - if (handle == -1) { - switch (errno) { - case EACCES: - case EPERM: - case EROFS: - Error (WriteProtected, EC_AccessDenied, EL_Unknown); - break; - case EISDIR: - Error (CanNotMakeDir, EC_AccessDenied, EL_Unknown); - break; - case ENFILE: - case EMFILE: - Error (NoMoreFiles, EC_MediaError, EL_Unknown); - case EEXIST: - Error (FileExists, EC_Exists, EL_Disk); - break; - case ENOSPC: - Error (DiskFull, EC_MediaError, EL_Disk); - break; - case ENOENT: - Error (FileNotFound, EC_MediaError, EL_Disk); - break; - default: - Error (GeneralFailure, EC_SystemFailure, EL_Unknown); - break; - } - AX = ExtendedError; - SetCflag; - return; - } - Error (0,0,0); - BX = handle; - AX = NoError; - ResetCflag; - } + fprintf(stderr,"OpenExistingFile (%s)\n",(char *) pointer(DS,DX)); + + if ((handle = open(GetUnixFileName((char*) pointer(DS,DX)), O_RDWR)) == -1) { + switch (errno) { + case EACCES: + case EPERM: + case EROFS: + Error (WriteProtected, EC_AccessDenied, EL_Unknown); + break; + case EISDIR: + Error (CanNotMakeDir, EC_AccessDenied, EL_Unknown); + break; + case ENFILE: + case EMFILE: + Error (NoMoreFiles, EC_MediaError, EL_Unknown); + case EEXIST: + Error (FileExists, EC_Exists, EL_Disk); + break; + case ENOSPC: + Error (DiskFull, EC_MediaError, EL_Disk); + break; + case ENOENT: + Error (FileNotFound, EC_MediaError, EL_Disk); + break; + default: + Error (GeneralFailure, EC_SystemFailure, EL_Unknown); + break; + } + EAX = (EAX & 0xffffff00L) | ExtendedError; + SetCflag; + return; + } + Error (0,0,0); + EBX = (EBX & 0xffff0000L) | handle; + EAX = (EAX & 0xffffff00L) | NoError; + ResetCflag; } void CloseFile(struct sigcontext_struct *context) @@ -515,105 +452,109 @@ void CloseFile(struct sigcontext_struct *context) Error (GeneralFailure, EC_SystemFailure, EL_Unknown); break; } - AX = ExtendedError; + EAX = (EAX & 0xffffff00L) | ExtendedError; SetCflag; return; } Error (0,0,0); - AX = NoError; + EAX = (EAX & 0xffffff00L) | NoError; ResetCflag; } void RenameFile(struct sigcontext_struct *context) { - rename((char *) pointer(DS,DX), (char *) pointer(ES,DI)); + char *newname, *oldname; + + fprintf(stderr,"int21: renaming %s to %s\n",(char *) pointer(DS,DX), pointer(ES,DI) ); + + oldname = GetUnixFileName( (char *) pointer(DS,DX) ); + newname = GetUnixFileName( (char *) pointer(ES,DI) ); + + rename( oldname, newname); ResetCflag; } void GetTrueFileName(struct sigcontext_struct *context) -{ +{ + fprintf(stderr,"int21: GetTrueFileName of %s\n",(char *) pointer(DS,SI)); + strncpy((char *) pointer(ES,DI), (char *) pointer(DS,SI), strlen((char *) pointer(DS,SI)) & 0x7f); ResetCflag; } void MakeDir(struct sigcontext_struct *context) { - int drive; char *dirname; - char unixname[256]; + + fprintf(stderr,"int21: makedir %s\n",(char *) pointer(DS,DX) ); - dirname = (char *) pointer(DS,DX); - - ParseDOSFileName(unixname,dirname,&drive); - - { - if (mkdir(unixname,0) == -1) { - AX = CanNotMakeDir; - SetCflag; - } - ResetCflag; + if ((dirname = GetUnixFileName( (char *) pointer(DS,DX) ))== NULL) { + EAX = (EAX & 0xffffff00L) | CanNotMakeDir; + SetCflag; + return; } + + if (mkdir(dirname,0) == -1) { + EAX = (EAX & 0xffffff00L) | CanNotMakeDir; + SetCflag; + return; + } + ResetCflag; } void ChangeDir(struct sigcontext_struct *context) { - int drive; - char *dirname; - char unixname[256]; - - dirname = (char *) pointer(DS,DX); + fprintf(stderr,"int21: changedir %s\n",(char *) pointer(DS,DX) ); - ParseDOSFileName(unixname,dirname,&drive); - - { - strcpy(unixname,DosDrives[drive].CurrentDirectory); - ResetCflag; - } + DOS_ChangeDir(DOS_GetDefaultDrive(), (char *) pointer (DS,DX)); } void RemoveDir(struct sigcontext_struct *context) { - int drive; char *dirname; - char unixname[256]; - - dirname = (char *) pointer(DS,DX); - ParseDOSFileName(unixname,dirname,&drive); + fprintf(stderr,"int21: removedir %s\n",(char *) pointer(DS,DX) ); - { - if (strcmp(unixname,DosDrives[drive].CurrentDirectory)) { - AX = CanNotRemoveCwd; - SetCflag; - } - - #ifdef DOSDEBUG - fprintf(stderr,"rmdir %s\n",unixname); - #endif - - if (rmdir(unixname) == -1) { - AX = CanNotMakeDir; /* HUH ?*/ - SetCflag; - } - ResetCflag; + if ((dirname = GetUnixFileName( (char *) pointer(DS,DX) ))== NULL) { + EAX = (EAX & 0xffffff00L) | CanNotMakeDir; + SetCflag; + return; } + +/* + if (strcmp(unixname,DosDrives[drive].CurrentDirectory)) { + EAX = (EAX & 0xffffff00L) | CanNotRemoveCwd; + SetCflag; + } +*/ + if (rmdir(dirname) == -1) { + EAX = (EAX & 0xffffff00L) | CanNotMakeDir; + SetCflag; + } + ResetCflag; } void AllocateMemory(struct sigcontext_struct *context) { char *ptr; + fprintf(stderr,"int21: malloc %d bytes\n", BX * 0x10 ); + if ((ptr = (void *) memalign((size_t) (BX * 0x10), 0x10)) == NULL) { - AX = OutOfMemory; - BX = 0x0; /* out of memory */ + EAX = (EAX & 0xffffff00L) | OutOfMemory; + EBX = (EBX & 0xffffff00L); /* out of memory */ SetCflag; } - AX = segment((unsigned long) ptr); + fprintf(stderr,"int21: malloc (ptr = %d)\n", ptr ); + + EAX = (EAX & 0xffff0000L) | segment((unsigned long) ptr); ResetCflag; } void FreeMemory(struct sigcontext_struct *context) { + fprintf(stderr,"int21: freemem (ptr = %d)\n", ES * 0x10 ); + free((void *)(ES * 0x10)); ResetCflag; } @@ -621,24 +562,26 @@ void FreeMemory(struct sigcontext_struct *context) void ResizeMemoryBlock(struct sigcontext_struct *context) { char *ptr; + + fprintf(stderr,"int21: realloc (ptr = %d)\n", ES * 0x10 ); if ((ptr = (void *) realloc((void *)(ES * 0x10), (size_t) BX * 0x10)) == NULL) { - AX = OutOfMemory; - BX = 0x0; /* out of memory */ + EAX = (EAX & 0xffffff00L) | OutOfMemory; + EBX = (EBX & 0xffffff00L); /* out of memory */ SetCflag; } - BX = segment((unsigned long) ptr); + EBX = (EBX & 0xffff0000L) | segment((unsigned long) ptr); ResetCflag; } void ExecProgram(struct sigcontext_struct *context) { - execl("wine",(char *) pointer(DS,DX)); + execl("wine", GetUnixFileName((char *) pointer(DS,DX)) ); } void GetReturnCode(struct sigcontext_struct *context) { - AX = NoError; /* normal exit */ + EAX = (EAX & 0xffffff00L) | NoError; /* normal exit */ } void FindFirst(struct sigcontext_struct *context) @@ -653,97 +596,83 @@ void FindNext(struct sigcontext_struct *context) void GetSysVars(struct sigcontext_struct *context) { + /* return a null pointer, to encourage anyone who tries to + use the pointer */ + ES = 0x0; - BX = 0x0; + EBX = (EBX & 0xffff0000L); } void GetFileDateTime(struct sigcontext_struct *context) { - int drive; - char *dirname; - char unixname[256]; + char *filename; struct stat filestat; struct tm *now; - dirname = (char *) pointer(DS,DX); - ParseDOSFileName(unixname, dirname, &drive); - - { - stat(unixname, &filestat); - - now = localtime (&filestat.st_mtime); - - CX = (now->tm_hour * 0x2000) + (now->tm_min * 0x20) + now->tm_sec/2; - DX = (now->tm_year * 0x200) + (now->tm_mon * 0x20) + now->tm_mday; - - ResetCflag; + if ((filename = GetUnixFileName( (char *) pointer(DS,DX) ))== NULL) { + EAX = (EAX & 0xffffff00L) | FileNotFound; + SetCflag; + return; } + stat(filename, &filestat); + + now = localtime (&filestat.st_mtime); + + ECX = (ECX & 0xffff0000L) | (now->tm_hour * 0x2000) + (now->tm_min * 0x20) + now->tm_sec/2; + EDX = (EDX & 0xffff0000L) | (now->tm_year * 0x200) + (now->tm_mon * 0x20) + now->tm_mday; + + ResetCflag; } void SetFileDateTime(struct sigcontext_struct *context) { - int drive; - char *dirname; - char unixname[256]; + char *filename; struct utimbuf filetime; - dirname = (char *) pointer(DS,DX); + filename = GetUnixFileName((char *) pointer(DS,DX)); - ParseDOSFileName(unixname, dirname, &drive); + filetime.actime = 0L; + filetime.modtime = filetime.actime; - { - filetime.actime = 0L; - filetime.modtime = filetime.actime; - - utime(unixname,&filetime); - ResetCflag; - } + utime(filename, &filetime); + ResetCflag; } void CreateTempFile(struct sigcontext_struct *context) { - char UnixFileName[256],TempString[256]; - int drive,handle; + char *filename, temp[256]; + int drive, handle; - ParseDOSFileName(UnixFileName, (char *) pointer(DS,DX), &drive); - - sprintf(TempString,"%s%s%d",UnixFileName,"eb",(int) getpid()); + sprintf(temp,"%s\\win%d.tmp",TempDirectory,(int) getpid()); - { - handle = open(TempString, O_CREAT | O_TRUNC | O_RDWR); + fprintf(stderr,"CreateTempFile %s\n",temp); - if (handle == -1) { - AX = WriteProtected; - SetCflag; - return; - } - - strcpy((char *) pointer(DS,DX), UnixFileName); - - AX = handle; - ResetCflag; + handle = open(GetUnixFileName(temp), O_CREAT | O_TRUNC | O_RDWR); + + if (handle == -1) { + EAX = (EAX & 0xffffff00L) | WriteProtected; + SetCflag; + return; } + + strcpy((char *) pointer(DS,DX), temp); + + EAX = (EAX & 0xffff0000L) | handle; + ResetCflag; } void CreateNewFile(struct sigcontext_struct *context) { - char UnixFileName[256]; - int drive,handle; + int handle; - ParseDOSFileName(UnixFileName, (char *) pointer(DS,DX), &drive); - - { - handle = open(UnixFileName, O_CREAT | O_TRUNC | O_RDWR); - - if (handle == -1) { - AX = WriteProtected; - SetCflag; - return; - } - - AX = handle; - ResetCflag; + if ((handle = open(GetUnixFileName((char *) pointer(DS,DX)), O_CREAT | O_TRUNC | O_RDWR)) == -1) { + EAX = (EAX & 0xffffff00L) | WriteProtected; + SetCflag; + return; } + + EAX = (EAX & 0xffff0000L) | handle; + ResetCflag; } void FileLock(struct sigcontext_struct *context) @@ -756,30 +685,23 @@ void GetExtendedCountryInfo(struct sigcontext_struct *context) ResetCflag; } -int ValidDrive(int d) -{ - return 1; -} - void GetCurrentDirectory(struct sigcontext_struct *context) { int drive; - char *ptr; - if ((DX & 0xff) == 0) - drive = CurrentDrive; + if ((EDX & 0xffL) == 0) + drive = DOS_GetDefaultDrive(); else - drive = (DX & 0xff)-1; + drive = (EDX & 0xffL)-1; - if (!ValidDrive(drive)) { - AX = InvalidDrive; + if (!DOS_ValidDrive(drive)) { + EAX = (EAX & 0xffffff00L) | InvalidDrive; SetCflag; return; } - - strcpy((char *) pointer(DS,SI), DosDrives[drive].CurrentDirectory); + + DOS_GetCurrentDir(drive, (char *) pointer(DS,SI) ); ResetCflag; - AX = 0x0100; } void GetCurrentPSP(struct sigcontext_struct *context) @@ -790,53 +712,48 @@ void GetCurrentPSP(struct sigcontext_struct *context) void GetDiskSerialNumber(struct sigcontext_struct *context) { int drive; + unsigned long serialnumber; struct diskinfo *ptr; - if ((BX & 0xff)== 0) - drive = CurrentDrive; + if ((EBX & 0xffL) == 0) + drive = DOS_GetDefaultDrive(); else - drive = (BX & 0xff)-1; + drive = (EBX & 0xffL) - 1; - if (!ValidDrive(drive)) { - AX = InvalidDrive; + if (!DOS_ValidDrive(drive)) { + EAX = (EAX & 0xffffff00L) |InvalidDrive; SetCflag; return; } - { - ptr =(struct diskinfo *) pointer(DS,SI); + DOS_GetSerialNumber(drive,&serialnumber); - ptr->infolevel = 0; - ptr->serialnumber = 0xEBEBEB00 | drive; - strcpy(ptr->label,"NO NAME "); - strcpy(ptr->fstype,"FAT16 "); + ptr = (struct diskinfo *) pointer(DS,SI); + + ptr->infolevel = 0; + ptr->serialnumber = serialnumber; + strcpy(ptr->label,"NO NAME "); + strcpy(ptr->fstype,"FAT16 "); - AX = NoError; - ResetCflag; - } + EAX = (EAX & 0xffffff00L) | NoError; + ResetCflag; } void SetDiskSerialNumber(struct sigcontext_struct *context) { - AX &= 0xff00; - AX |= 1; + EAX = (EAX & 0xffffff00L) | 1L; ResetCflag; } -void CommitFile(struct sigcontext_struct *context) -{ - -} - /************************************************************************/ int do_int21(struct sigcontext_struct * context){ int ah; - fprintf(stderr,"int21: doing AX=%4x BX=%4x CX=%4x DX=%4x\n", - AX & 0xffff,BX & 0xffff,CX & 0xffff,DX & 0xffff); + fprintf(stderr,"int21: doing AX=%04x BX=%04x CX=%04x DX=%04x\n", + EAX & 0xffffL,EBX & 0xffffL,ECX & 0xffffL,EDX & 0xffffL); - ah = (AX >> 8) & 0xff; + ah = (EAX >> 8) & 0xffL; if (ah == 0x59) { GetExtendedErrorInfo(context); @@ -901,7 +818,7 @@ int do_int21(struct sigcontext_struct * context){ case 0x54: /* GET VERIFY FLAG */ case 0x61: /* UNUSED */ case 0x6b: /* NULL FUNCTION */ - AX &= 0xff00; + EAX &= 0xff00; break; case 0x67: /* SET HANDLE COUNT */ @@ -945,36 +862,37 @@ int do_int21(struct sigcontext_struct * context){ break; case 0x30: /* GET DOS VERSION */ - AX = DosVersion; /* Hey folks, this is DOS V3.3! */ - BX = 0x0012; /* 0x123456 is Wine's serial # */ - CX = 0x3456; + fprintf(stderr,"int21: GetDosVersion\n"); + EAX = DosVersion; /* Hey folks, this is DOS V3.3! */ + EBX = 0x0012; /* 0x123456 is Wine's serial # */ + ECX = 0x3456; break; case 0x31: /* TERMINATE AND STAY RESIDENT */ break; case 0x33: /* MULTIPLEXED */ - switch (AX & 0xff) { + switch (EAX & 0xff) { case 0x00: /* GET CURRENT EXTENDED BREAK STATE */ - if (!(AX & 0xff)) - DX &= 0xff00; + if (!(EAX & 0xffL)) + EDX &= 0xff00L; break; case 0x01: /* SET EXTENDED BREAK STATE */ break; case 0x02: /* GET AND SET EXTENDED CONTROL-BREAK CHECKING STATE */ - DX &= 0xff00; + EDX &= 0xff00L; break; case 0x05: /* GET BOOT DRIVE */ - DX &= 0xff00; - DX |= 2; /* c: is Wine's bootdrive */ + EDX = (EDX & 0xff00L) | 2; + /* c: is Wine's bootdrive */ break; case 0x06: /* GET TRUE VERSION NUMBER */ - BX = DosVersion; - DX = 0x00; + EBX = DosVersion; + EDX = 0x00; break; default: break; @@ -989,7 +907,7 @@ int do_int21(struct sigcontext_struct * context){ /* Return a NULL segment selector - this will bomb, if anyone ever tries to use it */ ES = 0; - BX = 0; + EBX = 0; break; case 0x36: /* GET FREE DISK SPACE */ @@ -997,8 +915,8 @@ int do_int21(struct sigcontext_struct * context){ break; case 0x38: /* GET COUNTRY-SPECIFIC INFORMATION */ - AX &= 0xff00; - AX |= 0x02; /* no country support available */ + EAX &= 0xff00; + EAX |= 0x02; /* no country support available */ SetCflag; break; @@ -1023,9 +941,6 @@ int do_int21(struct sigcontext_struct * context){ break; case 0x3e: /* "CLOSE" - CLOSE FILE */ - case 0x68: /* "FFLUSH" - COMMIT FILE */ - case 0x6a: /* COMMIT FILE */ - CloseFile(context); break; @@ -1046,7 +961,7 @@ int do_int21(struct sigcontext_struct * context){ break; case 0x43: /* FILE ATTRIBUTES */ - switch (AX & 0xff) { + switch (EAX & 0xff) { case 0x00: GetFileAttributes(context); break; @@ -1067,8 +982,8 @@ int do_int21(struct sigcontext_struct * context){ case 0x47: /* "CWD" - GET CURRENT DIRECTORY */ GetCurrentDirectory(context); - AX = 0x0100; /* many Microsoft products for Windows rely - on this */ + EAX = (EAX & 0xffff0000L) | 0x0100; + /* many Microsoft products for Windows rely on this */ break; case 0x48: /* ALLOCATE MEMORY */ @@ -1088,8 +1003,10 @@ int do_int21(struct sigcontext_struct * context){ break; case 0x4c: /* "EXIT" - TERMINATE WITH RETURN CODE */ - exit(AX & 0xff); - + fprintf(stderr,"int21: DosExit\n"); + exit(EAX & 0xff); + break; + case 0x4d: /* GET RETURN CODE */ GetReturnCode(context); break; @@ -1111,7 +1028,7 @@ int do_int21(struct sigcontext_struct * context){ break; case 0x57: /* FILE DATE AND TIME */ - switch (AX & 0xff) { + switch (EAX & 0xff) { case 0x00: GetFileDateTime(context); break; @@ -1122,12 +1039,12 @@ int do_int21(struct sigcontext_struct * context){ break; case 0x58: /* GET OR SET MEMORY/UMB ALLOCATION STRATEGY */ - switch (AX & 0xff) { + switch (EAX & 0xff) { case 0x00: - AX = 0x01; + EAX = (EAX & 0xffffff00L) | 0x01L; break; case 0x02: - AX &= 0xff00; + EAX &= 0xff00L; break; case 0x01: case 0x03: @@ -1154,11 +1071,38 @@ int do_int21(struct sigcontext_struct * context){ case 0x5d: /* NETWORK */ case 0x5e: - case 0x5f: - AX &= 0xff00; - AX |= NoNetwork; /* network software not installed */ + EAX = (EAX & 0xfffff00L) | NoNetwork; /* network software not installed */ SetCflag; break; + + case 0x5f: /* NETWORK */ + switch (EAX & 0xffL) { + case 0x07: /* ENABLE DRIVE */ + if (!DOS_EnableDrive(EDX & 0xffL)) { + Error(InvalidDrive, EC_MediaError , EL_Disk); + EAX = (EAX & 0xfffff00L) | InvalidDrive; + SetCflag; + break; + } else { + ResetCflag; + break; + } + case 0x08: /* DISABLE DRIVE */ + if (!DOS_DisableDrive(EDX & 0xffL)) { + Error(InvalidDrive, EC_MediaError , EL_Disk); + EAX = (EAX & 0xfffff00L) | InvalidDrive; + SetCflag; + break; + } else { + ResetCflag; + break; + } + default: + EAX = (EAX & 0xfffff00L) | NoNetwork; /* network software not installed */ + SetCflag; + break; + } + break; case 0x60: /* "TRUENAME" - CANONICALIZE FILENAME OR PATH */ GetTrueFileName(context); @@ -1173,21 +1117,25 @@ int do_int21(struct sigcontext_struct * context){ break; case 0x66: /* GLOBAL CODE PAGE TABLE */ - switch (AX & 0xff) { + switch (EAX & 0xffL) { case 0x01: - BX = CodePage; - DX = BX; + EBX = CodePage; + EDX = EBX; ResetCflag; break; case 0x02: - CodePage = BX; + CodePage = EBX; ResetCflag; break; } break; + + case 0x68: /* "FFLUSH" - COMMIT FILE */ + ResetCflag; + break; case 0x69: /* DISK SERIAL NUMBER */ - switch (AX & 0xff) { + switch (EAX & 0xff) { case 0x00: GetDiskSerialNumber(context); break; @@ -1197,6 +1145,10 @@ int do_int21(struct sigcontext_struct * context){ } break; + case 0x6a: /* COMMIT FILE */ + ResetCflag; + break; + default: fprintf(stderr,"Unable to handle int 0x21 %x\n", context->sc_eax); return 1; @@ -1204,3 +1156,72 @@ int do_int21(struct sigcontext_struct * context){ } return 1; } + +/********************************************************************/ + +static void +GetTimeDate(int time_flag) +{ + struct tm *now; + time_t ltime; + + ltime = time(NULL); + now = localtime(<ime); + if (time_flag) + { + _CX = (now->tm_hour << 8) | now->tm_min; + _DX = now->tm_sec << 8; + } + else + { + _CX = now->tm_year + 1900; + _DX = ((now->tm_mon + 1) << 8) | now->tm_mday; + _AX &= 0xff00; + _AX |= now->tm_wday; + } +#ifdef DEBUG_DOS + printf("GetTimeDate: AX = %04x, CX = %04x, DX = %04x\n", _AX, _CX, _DX); +#endif + + ReturnFromRegisterFunc(); + /* Function does not return */ +} + +/********************************************************************** + * KERNEL_DOS3Call + */ +int KERNEL_DOS3Call() +{ + switch ((_AX >> 8) & 0xff) + { + case 0x30: + _AX = 0x0303; + ReturnFromRegisterFunc(); + /* Function does not return */ + + case 0x25: + case 0x35: + return 0; + + case 0x2a: + GetTimeDate(0); + /* Function does not return */ + + case 0x2c: + GetTimeDate(1); + /* Function does not return */ + + case 0x4c: + exit(_AX & 0xff); + + default: + fprintf(stderr, "DOS: AX %04x, BX %04x, CX %04x, DX %04x\n", + _AX, _BX, _CX, _DX); + fprintf(stderr, " SP %04x, BP %04x, SI %04x, DI %04x\n", + _SP, _BP, _SI, _DI); + fprintf(stderr, " DS %04x, ES %04x\n", + _DS, _ES); + } + + return 0; +} diff --git a/misc/message.c b/misc/message.c index 281b0121a14..cde516415a0 100644 --- a/misc/message.c +++ b/misc/message.c @@ -21,6 +21,8 @@ typedef struct tagMSGBOX { HWND hWndNo; HWND hWndCancel; HICON hIcon; + RECT rectIcon; + RECT rectStr; } MSGBOX; typedef MSGBOX FAR* LPMSGBOX; @@ -46,7 +48,7 @@ int MessageBox( HWND hWnd, LPSTR str, LPSTR title, WORD type ) wndClass.cbWndExtra = 0; wndClass.hInstance = wndPtr->hInstance; wndClass.hIcon = (HICON)NULL; - wndClass.hCursor = LoadCursor((HANDLE)NULL, IDC_ARROW); + wndClass.hCursor = LoadCursor((HANDLE)NULL, IDC_ARROW); wndClass.hbrBackground = GetStockObject(WHITE_BRUSH); wndClass.lpszMenuName = NULL; wndClass.lpszClassName = "MESSAGEBOX"; @@ -57,7 +59,7 @@ int MessageBox( HWND hWnd, LPSTR str, LPSTR title, WORD type ) mb.wType = type; mb.ActiveFlg = TRUE; hDlg = CreateWindow("MESSAGEBOX", title, - WS_POPUP | WS_DLGFRAME | WS_VISIBLE, 100, 150, 320, 120, + WS_POPUP | WS_DLGFRAME | WS_VISIBLE, 100, 150, 400, 120, (HWND)NULL, (HMENU)NULL, wndPtr->hInstance, (LPSTR)&mb); if (hDlg == 0) return 0; while(TRUE) { @@ -113,47 +115,63 @@ LONG SystemMessageBoxProc(HWND hWnd, WORD message, WORD wParam, LONG lParam) *((LPMSGBOX *)&wndPtr->wExtra[1]) = lpmbInit; lpmb = MsgBoxGetStorageHeader(hWnd); GetClientRect(hWnd, &rect); + CopyRect(&lpmb->rectStr, &rect); + lpmb->rectStr.bottom -= 32; switch(lpmb->wType & MB_TYPEMASK) { case MB_OK : lpmb->hWndYes = CreateWindow("BUTTON", "&Ok", WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON, - rect.right / 2 - 70, rect.bottom - 25, + rect.right / 2 - 30, rect.bottom - 25, 60, 18, hWnd, 1, wndPtr->hInstance, 0L); break; case MB_OKCANCEL : lpmb->hWndYes = CreateWindow("BUTTON", "&Ok", WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON, - rect.right / 2 - 70, rect.bottom - 25, + rect.right / 2 - 65, rect.bottom - 25, 60, 18, hWnd, 1, wndPtr->hInstance, 0L); lpmb->hWndCancel = CreateWindow("BUTTON", "&Cancel", WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON, - rect.right / 2 + 10, rect.bottom - 25, + rect.right / 2 + 5, rect.bottom - 25, 60, 18, hWnd, 2, wndPtr->hInstance, 0L); break; case MB_ABORTRETRYIGNORE : lpmb->hWndYes = CreateWindow("BUTTON", "&Retry", WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON, - rect.right / 2 - 70, rect.bottom - 25, + rect.right / 2 - 100, rect.bottom - 25, 60, 18, hWnd, 1, wndPtr->hInstance, 0L); lpmb->hWndNo = CreateWindow("BUTTON", "&Ignore", WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON, - rect.right / 2 + 10, rect.bottom - 25, + rect.right / 2 - 30, rect.bottom - 25, 60, 18, hWnd, 2, wndPtr->hInstance, 0L); lpmb->hWndCancel = CreateWindow("BUTTON", "&Abort", WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON, - rect.right / 2 + 80, rect.bottom - 25, + rect.right / 2 + 40, rect.bottom - 25, 60, 18, hWnd, 3, wndPtr->hInstance, 0L); break; case MB_YESNO : lpmb->hWndYes = CreateWindow("BUTTON", "&Yes", WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON, - rect.right / 2 - 70, rect.bottom - 25, + rect.right / 2 - 65, rect.bottom - 25, 60, 18, hWnd, 1, wndPtr->hInstance, 0L); lpmb->hWndNo = CreateWindow("BUTTON", "&No", WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON, - rect.right / 2 + 10, rect.bottom - 25, + rect.right / 2 + 5, rect.bottom - 25, 60, 18, hWnd, 2, wndPtr->hInstance, 0L); break; + case MB_YESNOCANCEL : + lpmb->hWndYes = CreateWindow("BUTTON", "&Yes", + WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON, + rect.right / 2 - 100, rect.bottom - 25, + 60, 18, hWnd, 1, wndPtr->hInstance, 0L); + lpmb->hWndNo = CreateWindow("BUTTON", "&No", + WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON, + rect.right / 2 - 30, rect.bottom - 25, + 60, 18, hWnd, 2, wndPtr->hInstance, 0L); + lpmb->hWndCancel = CreateWindow("BUTTON", "&Cancel", + WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON, + rect.right / 2 + 40, rect.bottom - 25, + 60, 18, hWnd, 3, wndPtr->hInstance, 0L); + break; } switch(lpmb->wType & MB_ICONMASK) { case MB_ICONEXCLAMATION: @@ -173,16 +191,25 @@ LONG SystemMessageBoxProc(HWND hWnd, WORD message, WORD wParam, LONG lParam) lpmb->hIcon = LoadIcon((HINSTANCE)NULL, IDI_HAND); break; } + if (lpmb->hIcon != (HICON)NULL) { + SetRect(&lpmb->rectIcon, 16, + lpmb->rectStr.bottom / 2 - 16, 48, + lpmb->rectStr.bottom / 2 + 16); + lpmb->rectStr.left += 64; + } break; case WM_PAINT: lpmb = MsgBoxGetStorageHeader(hWnd); - GetClientRect(hWnd, &rect); + CopyRect(&rect, &lpmb->rectStr); hDC = BeginPaint(hWnd, &ps); - if (lpmb->hIcon) DrawIcon(hDC, 30, 20, lpmb->hIcon); - TextOut(hDC, rect.right / 2, 15, - lpmb->Title, strlen(lpmb->Title)); - TextOut(hDC, rect.right / 2, 30, - lpmb->Str, strlen(lpmb->Str)); + if (lpmb->hIcon) + DrawIcon(hDC, lpmb->rectIcon.left, + lpmb->rectIcon.top, lpmb->hIcon); + DrawText(hDC, lpmb->Str, -1, &rect, + DT_CALCRECT | DT_CENTER | DT_WORDBREAK); + rect.top = lpmb->rectStr.bottom / 2 - rect.bottom / 2; + rect.bottom = lpmb->rectStr.bottom / 2 + rect.bottom / 2; + DrawText(hDC, lpmb->Str, -1, &rect, DT_CENTER | DT_WORDBREAK); EndPaint(hWnd, &ps); break; case WM_DESTROY: @@ -216,7 +243,7 @@ LONG SystemMessageBoxProc(HWND hWnd, WORD message, WORD wParam, LONG lParam) DeleteDC(hMemDC); } */ - hBitMap = LoadBitmap((HINSTANCE)NULL, "SMILE"); + hBitMap = LoadBitmap((HINSTANCE)NULL, "WINELOGO"); GetObject(hBitMap, sizeof(BITMAP), (LPSTR)&bm); printf("bm.bmWidth=%d bm.bmHeight=%d\n", bm.bmWidth, bm.bmHeight); @@ -234,12 +261,15 @@ LONG SystemMessageBoxProc(HWND hWnd, WORD message, WORD wParam, LONG lParam) break; case 3: hDC = GetDC(hWnd); - hInst2 = LoadImage("ev3lite.exe", NULL); + hInst2 = LoadImage("ev3lite.exe"); + printf("hInst2=%04X\n", hInst2); hIcon = LoadIcon(hInst2, "EV3LITE"); DrawIcon(hDC, 20, 20, hIcon); DestroyIcon(hIcon); - hInst2 = LoadImage("sysres.dll", NULL); - hIcon = LoadIcon(hInst2, "WINEICON"); + hInst2 = LoadImage("moricons.dll"); + printf("hInst2=%04X\n", hInst2); + hIcon = LoadIcon(hInst2, MAKEINTRESOURCE(1)); +/* hIcon = LoadIcon(hInst2, "WINEICON"); */ DrawIcon(hDC, 60, 20, hIcon); DestroyIcon(hIcon); hIcon = LoadIcon((HINSTANCE)NULL, IDI_EXCLAMATION); diff --git a/misc/profile.c b/misc/profile.c index ac50d862833..12d12fe2704 100644 --- a/misc/profile.c +++ b/misc/profile.c @@ -3,6 +3,12 @@ * * Copyright (c) 1993 Miguel de Icaza * + * 1/Dec o Corrected return values for Get*ProfileString + * + * o Now, if AppName == NULL in Get*ProfileString it returns a list + * of the KeyNames (as documented in the MS-SDK). + * + * o if KeyValue == NULL now clears the value in Get*ProfileString */ static char Copyright [] = "Copyright (C) 1993 Miguel de Icaza"; @@ -12,7 +18,8 @@ static char Copyright [] = "Copyright (C) 1993 Miguel de Icaza"; #include "windows.h" #include "wine.h" -#define INIFILE GetSystemIniFilename() +/* #define DEBUG */ + #define STRSIZE 255 #define xmalloc(x) malloc(x) #define overflow (next == &CharBuffer [STRSIZE-1]) @@ -63,9 +70,15 @@ static TSecHeader *load (char *file) char *next; char c; +#ifdef DEBUG + printf("Load %s\n", file); +#endif if ((f = fopen (file, "r"))==NULL) return NULL; +#ifdef DEBUG + printf("Loading %s\n", file); +#endif state = FirstBrace; while ((c = getc (f)) != EOF){ if (c == '\r') /* Ignore Carriage Return */ @@ -79,6 +92,9 @@ static TSecHeader *load (char *file) next = CharBuffer; SecHeader->AppName = strdup (CharBuffer); state = IgnoreToEOL; +#ifdef DEBUG + printf("%s: section %s\n", file, CharBuffer); +#endif } else *next++ = c; break; @@ -122,6 +138,9 @@ static TSecHeader *load (char *file) SecHeader->Keys->KeyName = strdup (CharBuffer); state = KeyValue; next = CharBuffer; +#ifdef DEBUG + printf("%s: key %s\n", file, CharBuffer); +#endif } else *next++ = c; break; @@ -175,22 +194,36 @@ static short GetSetProfile (int set, LPSTR AppName, LPSTR KeyName, section = New->Section; Current = New; } - /* Start search */ for (; section; section = section->link){ if (strcasecmp (section->AppName, AppName)) continue; + + /* If no key value given, then list all the keys */ + if ((!AppName) && (!set)){ + char *p = ReturnedString; + int left = Size - 1; + int slen; + + for (key = section->Keys; key; key = key->link){ + strncpy (p, key->KeyName, left); + slen = strlen (key->KeyName) + 1; + left -= slen+1; + p += slen; + } + return left; + } for (key = section->Keys; key; key = key->link){ if (strcasecmp (key->KeyName, KeyName)) continue; if (set){ free (key->Value); - key->Value = strdup (Default); + key->Value = strdup (Default ? Default : ""); return 1; } ReturnedString [Size-1] = 0; strncpy (ReturnedString, key->Value, Size-1); - return 1; + return 1; } /* If Getting the information, then don't write the information to the INI file, need to run a couple of tests with windog */ @@ -222,14 +255,20 @@ short GetPrivateProfileString (LPSTR AppName, LPSTR KeyName, LPSTR Default, LPSTR ReturnedString, short Size, LPSTR FileName) { - return (GetSetProfile (0, AppName, KeyName, Default, ReturnedString, Size, FileName)); + int v; + + v = GetSetProfile (0,AppName,KeyName,Default,ReturnedString,Size,FileName); + if (AppName) + return strlen (ReturnedString); + else + return Size - v; } int GetProfileString (LPSTR AppName, LPSTR KeyName, LPSTR Default, LPSTR ReturnedString, int Size) { return GetPrivateProfileString (AppName, KeyName, Default, - ReturnedString, Size, INIFILE); + ReturnedString, Size, WIN_INI); } WORD GetPrivateProfileInt (LPSTR AppName, LPSTR KeyName, short Default, @@ -251,7 +290,7 @@ WORD GetPrivateProfileInt (LPSTR AppName, LPSTR KeyName, short Default, WORD GetProfileInt (LPSTR AppName, LPSTR KeyName, int Default) { - return GetPrivateProfileInt (AppName, KeyName, Default, INIFILE); + return GetPrivateProfileInt (AppName, KeyName, Default, WIN_INI); } BOOL WritePrivateProfileString (LPSTR AppName, LPSTR KeyName, LPSTR String, @@ -262,7 +301,7 @@ BOOL WritePrivateProfileString (LPSTR AppName, LPSTR KeyName, LPSTR String, BOOL WriteProfileString (LPSTR AppName, LPSTR KeyName, LPSTR String) { - return (WritePrivateProfileString (AppName, KeyName, String, INIFILE)); + return (WritePrivateProfileString (AppName, KeyName, String, WIN_INI)); } static void dump_keys (FILE *profile, TKeys *p) diff --git a/misc/user.c b/misc/user.c index 58087eeaaa8..501448cd55d 100644 --- a/misc/user.c +++ b/misc/user.c @@ -6,8 +6,7 @@ static char Copyright[] = "Copyright Robert J. Amstadt, 1993"; #include "prototypes.h" #include "windows.h" #include "user.h" - -#define DEFAULT_MSG_QUEUE_SIZE 8 +#include "message.h" #define USER_HEAP_SIZE 0x10000 @@ -15,6 +14,9 @@ static char Copyright[] = "Copyright Robert J. Amstadt, 1993"; MDESC *USER_Heap = NULL; +extern BOOL ATOM_Init(); +extern BOOL GDI_Init(); + /*********************************************************************** * USER_HeapInit */ @@ -24,7 +26,6 @@ static BOOL USER_HeapInit() s = GetNextSegment( 0, 0x10000 ); if (s == NULL) return FALSE; HEAP_Init( &USER_Heap, s->base_addr, USER_HEAP_SIZE ); - free(s); return TRUE; } @@ -37,6 +38,11 @@ static BOOL USER_HeapInit() int USER_InitApp(int hInstance) { + int queueSize; + + /* Global atom table initialisation */ + if (!ATOM_Init()) return 0; + /* GDI initialisation */ if (!GDI_Init()) return 0; @@ -54,9 +60,14 @@ USER_InitApp(int hInstance) /* Initialize dialog manager */ if (!DIALOG_Init()) return 0; - + + /* Create system message queue */ + queueSize = GetProfileInt( "windows", "TypeAhead", 120 ); + if (!MSG_CreateSysMsgQueue( queueSize )) return 0; + /* Create task message queue */ - if (!SetMessageQueue( DEFAULT_MSG_QUEUE_SIZE )) return 0; + queueSize = GetProfileInt( "windows", "DefaultQueueSize", 8 ); + if (!SetMessageQueue( queueSize )) return 0; return 1; } diff --git a/misc/xt.c b/misc/xt.c index 8d386ae87d4..a829a5b8429 100644 --- a/misc/xt.c +++ b/misc/xt.c @@ -41,6 +41,8 @@ void main(int argc, char **argv) XT_display = XtDisplay( topLevelWidget ); XT_screen = XtScreen( topLevelWidget ); + DOS_InitFS(); + Comm_Init(); _WinMain( argc, argv ); } @@ -58,12 +60,6 @@ void MessageBeep( WORD i ) XBell(XT_display, 100); } -WORD RegisterWindowMessage( LPSTR str ) -{ - printf( "RegisterWindowMessage: '%s'\n", str ); - return 0xc000; -} - /*********************************************************************** * GetTickCount (USER.13) */ @@ -94,11 +90,10 @@ void AdjustWindowRect( LPRECT rect, DWORD style, BOOL menu ) { printf( "AdjustWindowRect: (%d,%d)-(%d,%d) %d %d\n", rect->left, rect->top, rect->right, rect->bottom, style, menu ); +#ifdef USE_XLIB + rect->right += 8; + rect->bottom += 34; +#endif } -HMENU CreateMenu() { return 0; } - -BOOL AppendMenu( HMENU hmenu, WORD flags, WORD id, LPSTR text ) { return TRUE;} - -BOOL DestroyMenu( HMENU hmenu ) { return TRUE; } diff --git a/objects/Imakefile b/objects/Imakefile new file mode 100644 index 00000000000..458761d9172 --- /dev/null +++ b/objects/Imakefile @@ -0,0 +1,43 @@ +#include "../Wine.tmpl" + +MODULE = objects + +SRCS = \ + bitmap.c \ + brush.c \ + font.c \ + gdiobj.c \ + palette.c \ + pen.c \ + dib.c \ + region.c \ + text.c \ + dcvalues.c \ + clipping.c \ + bitblt.c \ + linedda.c \ + color.c + +OBJS = \ + bitmap.o \ + brush.o \ + font.o \ + gdiobj.o \ + palette.o \ + pen.o \ + dib.o \ + region.o \ + text.o \ + dcvalues.o \ + clipping.o \ + bitblt.o \ + linedda.o \ + color.o + +WineRelocatableTarget($(TOP)/$(MODULE),,$(OBJS)) +DependTarget() +CleanTarget() + +includes:: + +install:: diff --git a/objects/bitblt.c b/objects/bitblt.c index 53e9ba1a03a..c4ed6bc516c 100644 --- a/objects/bitblt.c +++ b/objects/bitblt.c @@ -38,10 +38,10 @@ BOOL PatBlt( HDC hdc, short left, short top, else rop = (rop & 0x03) | ((rop >> 4) & 0x0c); XSetFunction( XT_display, dc->u.x.gc, DC_XROPfunction[rop] ); - x1 = XLPTODP( dc, left ); - x2 = XLPTODP( dc, left + width ); - y1 = YLPTODP( dc, top ); - y2 = YLPTODP( dc, top + height ); + x1 = dc->w.DCOrgX + XLPTODP( dc, left ); + x2 = dc->w.DCOrgX + XLPTODP( dc, left + width ); + y1 = dc->w.DCOrgY + YLPTODP( dc, top ); + y2 = dc->w.DCOrgY + YLPTODP( dc, top + height ); XFillRectangle( XT_display, dc->u.x.drawable, dc->u.x.gc, MIN(x1,x2), MIN(y1,y2), abs(x2-x1), abs(y2-y1) ); return TRUE; @@ -78,14 +78,14 @@ BOOL BitBlt( HDC hdcDest, short xDest, short yDest, short width, short height, dcSrc = (DC *) GDI_GetObjPtr( hdcSrc, DC_MAGIC ); if (!dcSrc) return FALSE; - xs1 = XLPTODP( dcSrc, xSrc ); - xs2 = XLPTODP( dcSrc, xSrc + width ); - ys1 = YLPTODP( dcSrc, ySrc ); - ys2 = YLPTODP( dcSrc, ySrc + height ); - xd1 = XLPTODP( dcDest, xDest ); - xd2 = XLPTODP( dcDest, xDest + width ); - yd1 = YLPTODP( dcDest, yDest ); - yd2 = YLPTODP( dcDest, yDest + height ); + xs1 = dcSrc->w.DCOrgX + XLPTODP( dcSrc, xSrc ); + xs2 = dcSrc->w.DCOrgX + XLPTODP( dcSrc, xSrc + width ); + ys1 = dcSrc->w.DCOrgY + YLPTODP( dcSrc, ySrc ); + ys2 = dcSrc->w.DCOrgY + YLPTODP( dcSrc, ySrc + height ); + xd1 = dcDest->w.DCOrgX + XLPTODP( dcDest, xDest ); + xd2 = dcDest->w.DCOrgX + XLPTODP( dcDest, xDest + width ); + yd1 = dcDest->w.DCOrgY + YLPTODP( dcDest, yDest ); + yd2 = dcDest->w.DCOrgY + YLPTODP( dcDest, yDest + height ); if ((abs(xs2-xs1) != abs(xd2-xd1)) || (abs(ys2-ys1) != abs(yd2-yd1))) return FALSE; /* Should call StretchBlt here */ @@ -109,3 +109,78 @@ BOOL BitBlt( HDC hdcDest, short xDest, short yDest, short width, short height, } return TRUE; } + + + +/*********************************************************************** + * StrechBlt (GDI.35) + */ +BOOL StrechBlt( HDC hdcDest, short xDest, short yDest, short widthDest, short heightDest, + HDC hdcSrc, short xSrc, short ySrc, short widthSrc, short heightSrc, DWORD rop ) +{ + int xs1, xs2, ys1, ys2; + int xd1, xd2, yd1, yd2; + DC *dcDest, *dcSrc; + +/*#ifdef DEBUG_GDI */ + + printf( "StrechBlt: %d %d,%d %dx%d %d %d,%d %dx%d %08x\n", + hdcDest, xDest, yDest, widthDest, heightDest, hdcSrc, xSrc, + ySrc, widthSrc, heightSrc, rop ); +/*#endif */ + + + + if ((rop & 0xcc0000) == ((rop & 0x330000) << 2)) + return PatBlt( hdcDest, xDest, yDest, widthDest, heightDest, rop ); + + printf("here\n"); + + rop >>= 16; + if ((rop & 0x0f) != (rop >> 4)) + { + printf( "BitBlt: Unimplemented ROP %02x\n", rop ); + return FALSE; + } + + printf("here2\n"); + + dcDest = (DC *) GDI_GetObjPtr( hdcDest, DC_MAGIC ); + if (!dcDest) return FALSE; + dcSrc = (DC *) GDI_GetObjPtr( hdcSrc, DC_MAGIC ); + if (!dcSrc) return FALSE; + + xs1 = XLPTODP( dcSrc, xSrc ); + xs2 = XLPTODP( dcSrc, xSrc + widthSrc ); + ys1 = YLPTODP( dcSrc, ySrc ); + ys2 = YLPTODP( dcSrc, ySrc + heightSrc ); + xd1 = XLPTODP( dcDest, xDest ); + xd2 = XLPTODP( dcDest, xDest + widthDest ); + yd1 = YLPTODP( dcDest, yDest ); + yd2 = YLPTODP( dcDest, yDest + heightDest ); + + DC_SetupGCForText( dcDest ); + XSetFunction( XT_display, dcDest->u.x.gc, DC_XROPfunction[rop & 0x0f] ); + + if (dcSrc->w.bitsPerPixel == dcDest->w.bitsPerPixel) + { + printf("XCopyArea\n"); + XCopyArea( XT_display, dcSrc->u.x.drawable, + dcDest->u.x.drawable, dcDest->u.x.gc, + MIN(xs1,xs2), MIN(ys1,ys2), abs(xd2-xd1), abs(yd2-yd1), + MIN(xd1,xd2), MIN(yd1,yd2) ); + } + else + { + printf("XCopyPlane\n"); + if (dcSrc->w.bitsPerPixel != 1) return FALSE; + XCopyPlane( XT_display, dcSrc->u.x.drawable, + dcDest->u.x.drawable, dcDest->u.x.gc, + MIN(xs1,xs2), MIN(ys1,ys2), abs(xd2-xd1), abs(yd2-yd1), + MIN(xd1,xd2), MIN(yd1,yd2), 1 ); + } + return TRUE; + + +} + diff --git a/objects/bitmap.c b/objects/bitmap.c index 9de4c1c31a5..ffec3e9a760 100644 --- a/objects/bitmap.c +++ b/objects/bitmap.c @@ -46,6 +46,7 @@ BOOL BITMAP_Init() if (tmpPixmap) { bitmapGC[i] = XCreateGC( XT_display, tmpPixmap, 0, NULL ); + XSetGraphicsExposures( XT_display, bitmapGC[i], False ); XFreePixmap( XT_display, tmpPixmap ); } else bitmapGC[i] = 0; @@ -355,6 +356,8 @@ HBITMAP BITMAP_SelectObject( HDC hdc, DC * dc, HBITMAP hbitmap, DefaultRootWindow( XT_display ), bmp->bmWidth, bmp->bmHeight, bmp->bmBitsPixel ); + dc->w.DCSizeX = bmp->bmWidth; + dc->w.DCSizeY = bmp->bmHeight; BITMAP_CopyToPixmap( bmp, dc->u.x.drawable, 0, 0, bmp->bmWidth, bmp->bmHeight ); diff --git a/objects/clipping.c b/objects/clipping.c index ec9de9ccde5..5776eb857d0 100644 --- a/objects/clipping.c +++ b/objects/clipping.c @@ -10,10 +10,33 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; #include "gdi.h" +/*********************************************************************** + * CLIPPING_SetDeviceClipping + * + * Set the clip region of the physical device. + */ +void CLIPPING_SetDeviceClipping( DC * dc ) +{ + if (dc->w.hGCClipRgn) + { + RGNOBJ *obj = (RGNOBJ *) GDI_GetObjPtr(dc->w.hGCClipRgn, REGION_MAGIC); + XSetClipMask( XT_display, dc->u.x.gc, obj->region.pixmap ); + XSetClipOrigin( XT_display, dc->u.x.gc, + dc->w.DCOrgX + obj->region.box.left, + dc->w.DCOrgY + obj->region.box.top ); + } + else + { + XSetClipMask( XT_display, dc->u.x.gc, None ); + XSetClipOrigin( XT_display, dc->u.x.gc, dc->w.DCOrgX, dc->w.DCOrgY ); + } +} + + /*********************************************************************** * CLIPPING_UpdateGCRegion * - * Update the GC clip region when the ClipRgn of VisRgn have changed. + * Update the GC clip region when the ClipRgn or VisRgn have changed. */ static void CLIPPING_UpdateGCRegion( DC * dc ) { @@ -36,19 +59,7 @@ static void CLIPPING_UpdateGCRegion( DC * dc ) else CombineRgn( dc->w.hGCClipRgn, dc->w.hClipRgn, dc->w.hVisRgn, RGN_AND ); } - - if (dc->w.hGCClipRgn) - { - RGNOBJ *obj = (RGNOBJ *) GDI_GetObjPtr( dc->w.hGCClipRgn, REGION_MAGIC ); - XSetClipMask( XT_display, dc->u.x.gc, obj->region.pixmap ); - XSetClipOrigin( XT_display, dc->u.x.gc, - obj->region.box.left, obj->region.box.top ); - } - else - { - XSetClipMask( XT_display, dc->u.x.gc, None ); - XSetClipOrigin( XT_display, dc->u.x.gc, 0, 0 ); - } + CLIPPING_SetDeviceClipping( dc ); } @@ -157,26 +168,40 @@ int OffsetVisRgn( HDC hdc, short x, short y ) int CLIPPING_IntersectRect( DC * dc, HRGN * hrgn, short left, short top, short right, short bottom, int exclude ) { - HRGN tempRgn, newRgn; + HRGN tempRgn = 0, prevRgn = 0, newRgn = 0; RGNOBJ *newObj, *prevObj; int retval; - if (!*hrgn) return NULLREGION; - if (!(newRgn = CreateRectRgn( 0, 0, 0, 0))) return ERROR; - if (!(tempRgn = CreateRectRgn( left, top, right, bottom ))) + if (!*hrgn) { - DeleteObject( newRgn ); - return ERROR; + if (!(*hrgn = CreateRectRgn( 0, 0, dc->w.DCSizeX, dc->w.DCSizeY ))) + goto Error; + prevRgn = *hrgn; } + if (!(newRgn = CreateRectRgn( 0, 0, 0, 0))) goto Error; + if (!(tempRgn = CreateRectRgn( left, top, right, bottom ))) goto Error; + retval = CombineRgn( newRgn, *hrgn, tempRgn, exclude ? RGN_DIFF : RGN_AND); + if (retval == ERROR) goto Error; + newObj = (RGNOBJ *) GDI_GetObjPtr( newRgn, REGION_MAGIC ); prevObj = (RGNOBJ *) GDI_GetObjPtr( *hrgn, REGION_MAGIC ); if (newObj && prevObj) newObj->header.hNext = prevObj->header.hNext; DeleteObject( tempRgn ); - DeleteObject( *hrgn ); + if (*hrgn) DeleteObject( *hrgn ); *hrgn = newRgn; CLIPPING_UpdateGCRegion( dc ); return retval; + + Error: + if (tempRgn) DeleteObject( tempRgn ); + if (newRgn) DeleteObject( newRgn ); + if (prevRgn) + { + DeleteObject( prevRgn ); + *hrgn = 0; + } + return ERROR; } @@ -292,13 +317,9 @@ int GetClipBox( HDC hdc, LPRECT rect ) if (dc->w.hGCClipRgn) return GetRgnBox( dc->w.hGCClipRgn, rect ); else { - Window root; - int width, height, x, y, border, depth; - XGetGeometry( XT_display, dc->u.x.drawable, &root, &x, &y, - &width, &height, &border, &depth ); rect->top = rect->left = 0; - rect->right = width & 0xffff; - rect->bottom = height & 0xffff; + rect->right = dc->w.DCSizeX; + rect->bottom = dc->w.DCSizeY; return SIMPLEREGION; } } diff --git a/objects/dcvalues.c b/objects/dcvalues.c index b496e2e3609..73c98aabedd 100644 --- a/objects/dcvalues.c +++ b/objects/dcvalues.c @@ -45,6 +45,8 @@ const WIN_DC_INFO DCVAL_defaultValues = MM_TEXT, /* MapMode */ 0, /* DCOrgX */ 0, /* DCOrgY */ + 0, /* DCSizeX */ + 0, /* DCSizeY */ 0, /* CursPosX */ 0, /* CursPosY */ 0, /* WndOrgX */ diff --git a/objects/font.c b/objects/font.c index 1299a26ac51..10bc76b7b08 100644 --- a/objects/font.c +++ b/objects/font.c @@ -331,6 +331,36 @@ BOOL GetTextMetrics( HDC hdc, LPTEXTMETRIC metrics ) } +/***********************************************************************/ + +#define CI_NONEXISTCHAR(cs) (((cs)->width == 0) && \ + (((cs)->rbearing|(cs)->lbearing| \ + (cs)->ascent|(cs)->descent) == 0)) + +/* + * CI_GET_CHAR_INFO - return the charinfo struct for the indicated 8bit + * character. If the character is in the column and exists, then return the + * appropriate metrics (note that fonts with common per-character metrics will + * return min_bounds). If none of these hold true, try again with the default + * char. + */ +#define CI_GET_CHAR_INFO(fs,col,def,cs) \ +{ \ + cs = def; \ + if (col >= fs->min_char_or_byte2 && col <= fs->max_char_or_byte2) { \ + if (fs->per_char == NULL) { \ + cs = &fs->min_bounds; \ + } else { \ + cs = &fs->per_char[(col - fs->min_char_or_byte2)]; \ + if (CI_NONEXISTCHAR(cs)) cs = def; \ + } \ + } \ +} + +#define CI_GET_DEFAULT_INFO(fs,cs) \ + CI_GET_CHAR_INFO(fs, fs->default_char, NULL, cs) + + /*********************************************************************** * GetCharWidth (GDI.350) */ @@ -338,8 +368,7 @@ BOOL GetCharWidth(HDC hdc, WORD wFirstChar, WORD wLastChar, LPINT lpBuffer) { int i, j; XFontStruct *xfont; - XCharStruct *charPtr; - int default_width; + XCharStruct *cs, *def; DC *dc = (DC *)GDI_GetObjPtr(hdc, DC_MAGIC); if (!dc) return FALSE; @@ -353,15 +382,12 @@ BOOL GetCharWidth(HDC hdc, WORD wFirstChar, WORD wLastChar, LPINT lpBuffer) return TRUE; } - charPtr = xfont->per_char; - default_width = (charPtr + xfont->default_char)->width; + CI_GET_DEFAULT_INFO(xfont, def); for (i = wFirstChar, j = 0; i <= wLastChar; i++, j++) { - if (i < xfont->min_char_or_byte2 || i > xfont->max_char_or_byte2) - *(lpBuffer + j) = default_width; - else - *(lpBuffer + j) = charPtr->width; + CI_GET_CHAR_INFO(xfont, i, def, cs); + *(lpBuffer + j) = cs->width; } return TRUE; } diff --git a/objects/gdiobj.c b/objects/gdiobj.c index 32bb4b8ae01..cc539a49025 100644 --- a/objects/gdiobj.c +++ b/objects/gdiobj.c @@ -153,7 +153,6 @@ BOOL GDI_Init() s = (struct segment_descriptor_s *)GetNextSegment( 0, 0x10000 ); if (s == NULL) return FALSE; HEAP_Init( &GDI_Heap, s->base_addr, GDI_HEAP_SIZE ); - free(s); /* Create default palette */ @@ -200,8 +199,11 @@ HANDLE GDI_AllocObject( WORD size, WORD magic ) GDIOBJHDR * obj; HANDLE handle = GDI_HEAP_ALLOC( GMEM_MOVEABLE, size ); if (!handle) return 0; - obj = (GDIOBJHDR *) GDI_HEAP_ADDR( handle ); + if (obj == NULL) { + printf("GDI_AllocObject // Error trying to get GDI_HEAD_ADDR !\n"); + return 0; + } obj->hNext = 0; obj->wMagic = magic; obj->dwCount = ++count; diff --git a/objects/palette.c b/objects/palette.c index 3b101b2608f..511cf3f0efb 100644 --- a/objects/palette.c +++ b/objects/palette.c @@ -177,3 +177,21 @@ int PALETTE_GetObject( PALETTEOBJ * palette, int count, LPSTR buffer ) memcpy( buffer, &palette->logpalette.palNumEntries, count ); return count; } + + +/*********************************************************************** + * SelectPalette (USER.282) + */ +HPALETTE SelectPalette(HDC hDC, HPALETTE hPal, BOOL bForceBackground) +{ + return (HPALETTE)NULL; +} + +/*********************************************************************** + * RealizePalette (USER.283) + */ +int RealizePalette(HDC hDC) +{ + return 0; +} + diff --git a/objects/region.c b/objects/region.c index 08274ca08aa..3a7b9ef290a 100644 --- a/objects/region.c +++ b/objects/region.c @@ -31,6 +31,7 @@ BOOL REGION_Init() XFreePixmap( XT_display, tmpPixmap ); if (!regionGC) return FALSE; XSetForeground( XT_display, regionGC, 1 ); + XSetGraphicsExposures( XT_display, regionGC, False ); return TRUE; } else return FALSE; diff --git a/objects/text.c b/objects/text.c index bbb2740085d..07aef5835c4 100644 --- a/objects/text.c +++ b/objects/text.c @@ -229,7 +229,8 @@ int DrawText( HDC hdc, LPSTR str, int count, LPRECT rect, WORD flags ) else if (flags & DT_BOTTOM) y = rect->bottom - size.cy; } - if (!TextOut(hdc, x, y, line, len)) return 0; + if (!(flags & DT_CALCRECT)) + if (!TextOut(hdc, x, y, line, len)) return 0; if (prefix_offset != -1) { MoveTo(hdc, x + prefix_x, y + size.cy); @@ -247,7 +248,7 @@ int DrawText( HDC hdc, LPSTR str, int count, LPRECT rect, WORD flags ) } } while (strPtr); - + if (flags & DT_CALCRECT) rect->bottom = y; return 1; } @@ -314,10 +315,10 @@ BOOL TextOut( HDC hdc, short x, short y, LPSTR str, short count ) { if (dc->w.backgroundMode == TRANSPARENT) XDrawString( XT_display, dc->u.x.drawable, dc->u.x.gc, - x, y, str, count ); + dc->w.DCOrgX + x, dc->w.DCOrgY + y, str, count ); else XDrawImageString( XT_display, dc->u.x.drawable, dc->u.x.gc, - x, y, str, count ); + dc->w.DCOrgX + x, dc->w.DCOrgY + y, str, count ); } else { @@ -340,14 +341,15 @@ BOOL TextOut( HDC hdc, short x, short y, LPSTR str, short count ) if (dc->w.backgroundMode == TRANSPARENT) XDrawString( XT_display, dc->u.x.drawable, dc->u.x.gc, - xchar, y, p, 1 ); + dc->w.DCOrgX + xchar, dc->w.DCOrgY + y, p, 1 ); else { XDrawImageString( XT_display, dc->u.x.drawable, dc->u.x.gc, - xchar, y, p, 1 ); + dc->w.DCOrgX + xchar, dc->w.DCOrgY + y, p, 1 ); XSetForeground( XT_display, dc->u.x.gc, dc->w.backgroundPixel); XFillRectangle( XT_display, dc->u.x.drawable, dc->u.x.gc, - xchar + charStr->width, y - font->ascent, + dc->w.DCOrgX + xchar + charStr->width, + dc->w.DCOrgY + y - font->ascent, extraWidth, font->ascent + font->descent ); XSetForeground( XT_display, dc->u.x.gc, dc->w.textPixel ); } @@ -368,7 +370,8 @@ BOOL TextOut( HDC hdc, short x, short y, LPSTR str, short count ) XSetLineAttributes( XT_display, dc->u.x.gc, lineWidth, LineSolid, CapRound, JoinBevel ); XDrawLine( XT_display, dc->u.x.drawable, dc->u.x.gc, - x, y + linePos, x + info.width, y + linePos ); + dc->w.DCOrgX + x, dc->w.DCOrgY + y + linePos, + dc->w.DCOrgX + x + info.width, dc->w.DCOrgY + y + linePos ); } if (dc->u.x.font.metrics.tmStruckOut) { @@ -380,7 +383,8 @@ BOOL TextOut( HDC hdc, short x, short y, LPSTR str, short count ) XSetLineAttributes( XT_display, dc->u.x.gc, lineAscent + lineDescent, LineSolid, CapRound, JoinBevel ); XDrawLine( XT_display, dc->u.x.drawable, dc->u.x.gc, - x, y - lineAscent, x + info.width, y - lineAscent ); + dc->w.DCOrgX + x, dc->w.DCOrgY + y - lineAscent, + dc->w.DCOrgX + x + info.width, dc->w.DCOrgY + y - lineAscent ); } return TRUE; diff --git a/sysres.dll b/sysres.dll index 44a53abd38e..38c7ca909d2 100755 Binary files a/sysres.dll and b/sysres.dll differ diff --git a/test/Imakefile b/test/Imakefile new file mode 100644 index 00000000000..d45263d3c95 --- /dev/null +++ b/test/Imakefile @@ -0,0 +1,8 @@ +all:: + +depend:: + +clean:: + +includes:: + diff --git a/test/Makefile b/test/Makefile new file mode 100644 index 00000000000..535cc4716d3 --- /dev/null +++ b/test/Makefile @@ -0,0 +1,347 @@ +# Makefile generated by imake - do not edit! +# $XConsortium: imake.c,v 1.65 91/07/25 17:50:17 rws Exp $ + +# ------------------------------------------------------------------------- +# Makefile generated from "Imake.tmpl" and +# $XFree86: mit/config/Imake.tmpl,v 1.17 1993/06/03 15:26:36 dawes Exp $ +# $XConsortium: Imake.tmpl,v 1.139 91/09/16 08:52:48 rws Exp $ +# +# Platform-specific parameters may be set in the appropriate .cf +# configuration files. Site-specific parameters should be set in the file +# site.def. Full rebuilds are recommended if any parameters are changed. +# +# If your C preprocessor does not define any unique symbols, you will need +# to set BOOTSTRAPCFLAGS when rebuilding imake (usually when doing +# "make World" the first time). +# + +# ------------------------------------------------------------------------- +# site-specific configuration parameters that need to come before +# the platform-specific parameters - edit site.def to change + +# $XFree86: mit/config/site.def,v 1.65 1993/06/04 16:02:47 dawes Exp $ +# site: $XConsortium: site.def,v 1.2 91/07/30 20:26:44 rws Exp $ + +# obz: changes for making Linux distribution + +# ------------------------------------------------------------------------- +# platform-specific configuration parameters - edit x386.cf to change + +# $XFree86: mit/config/x386.cf,v 1.90 1993/06/04 16:02:50 dawes Exp $ +# platform: $XConsortium: x386.cf,v 1.7 91/08/16 19:30:10 gildea Exp $ + +# ------------------------------------------------------------------------- +# XFree86 version definition +# $XFree86: mit/config/xf86_vers.def,v 1.5 1993/06/01 09:12:47 dawes Exp $ + +# ------------------------------------------------------------------------- +# XFree86 version: 1300 +# ------------------------------------------------------------------------- + +# $XFree86: mit/config/lnuxLib.rules,v 1.2 1993/06/02 13:48:12 dawes Exp $ + +DLL_BINDIR = /usr/dll/bin + +# operating system: Linux + +# ------------------------------------------------------------------------- +# site-specific configuration parameters that go after +# the platform-specific parameters - edit site.def to change + +# $XFree86: mit/config/site.def,v 1.65 1993/06/04 16:02:47 dawes Exp $ +# site: $XConsortium: site.def,v 1.2 91/07/30 20:26:44 rws Exp $ + +# obz: changes for making Linux distribution + + SHELL = /bin/sh + + TOP = ../. + CURRENT_DIR = ./test + + AR = ar clq + BOOTSTRAPCFLAGS = + CC = gcc + AS = as + + LEX = flex + + YACC = bison -y + + COMPRESS = compress + CPP = /lib/cpp $(STD_CPP_DEFINES) + PREPROCESSCMD = /lib/cpp $(STD_CPP_DEFINES) + INSTALL = install + LD = ld + LINT = lint + LINTLIBFLAG = -C + LINTOPTS = -axz + LN = ln -s + MAKE = make + MV = mv + CP = cp + + RANLIB = ranlib + RANLIBINSTFLAGS = + + RM = rm -f + TROFF = psroff + MSMACROS = -ms + TBL = tbl + EQN = eqn + STD_INCLUDES = + STD_CPP_DEFINES = -traditional -D_POSIX_SOURCE -D_BSD_SOURCE -D_GNU_SOURCE -Dlinux + STD_DEFINES = -D_POSIX_SOURCE -D_BSD_SOURCE -D_GNU_SOURCE -Dlinux + EXTRA_LOAD_FLAGS = + EXTRA_LIBRARIES = + OS_LIBRARIES = + TAGS = ctags + + SHAREDCODEDEF = + SHLIBDEF = + + PROTO_DEFINES = -DFUNCPROTO=11 -DNARROWPROTO + + INSTPGMFLAGS = -s + + INSTBINFLAGS = -m 0755 + INSTUIDFLAGS = -s -m 4755 + INSTLIBFLAGS = -m 0644 + INSTINCFLAGS = -m 0444 + INSTMANFLAGS = -m 0444 + INSTDATFLAGS = -m 0444 + INSTKMEMFLAGS = -s -m 4755 + + PROJECTROOT = /usr/X386 + + TOP_INCLUDES = -I$(INCROOT) + + CDEBUGFLAGS = -O2 + CCOPTIONS = -m486 -DNO_ASM -fwritable-strings + ANSICCOPTIONS = + + ALLINCLUDES = $(INCLUDES) $(EXTRA_INCLUDES) $(TOP_INCLUDES) $(STD_INCLUDES) + ALLDEFINES = $(ALLINCLUDES) $(STD_DEFINES) $(EXTRA_DEFINES) $(PROTO_DEFINES) $(DEFINES) + CFLAGS = $(ANSICCOPTIONS) $(CDEBUGFLAGS) $(CCOPTIONS) $(ALLDEFINES) + LINTFLAGS = $(LINTOPTS) -DLINT $(ALLDEFINES) + + LDLIBS = $(OS_LIBRARIES) $(SYS_LIBRARIES) $(EXTRA_LIBRARIES) + + LDOPTIONS = $(ANSICCOPTIONS) $(CDEBUGFLAGS) $(CCOPTIONS) $(LOCAL_LDFLAGS) -L$(USRLIBDIR) + + LDCOMBINEFLAGS = -r + DEPENDFLAGS = + + MACROFILE = x386.cf + RM_CMD = $(RM) *.CKP *.ln *.BAK *.bak *.o core errs ,* *~ *.a .emacs_* tags TAGS make.log MakeOut + + IMAKE_DEFINES = + + IRULESRC = $(CONFIGDIR) + IMAKE_CMD = $(IMAKE) -DUseInstalled -I$(IRULESRC) $(IMAKE_DEFINES) + + ICONFIGFILES = $(IRULESRC)/Imake.tmpl $(IRULESRC)/Imake.rules $(IRULESRC)/Project.tmpl $(IRULESRC)/site.def $(IRULESRC)/$(MACROFILE) $(EXTRA_ICONFIGFILES) + +# ------------------------------------------------------------------------- +# X Window System Build Parameters +# $XFree86: mit/config/Project.tmpl,v 1.13 1993/03/27 03:32:45 dawes Exp $ +# $XConsortium: Project.tmpl,v 1.138.1.1 92/11/11 09:49:19 rws Exp $ + +_percentC_ = %C + +# ------------------------------------------------------------------------- +# X Window System make variables; this need to be coordinated with rules + + PATHSEP = / + USRLIBDIR = /usr/X386/lib + BINDIR = /usr/X386/bin + INCROOT = /usr/X386/include + BUILDINCROOT = $(TOP) + BUILDINCDIR = $(BUILDINCROOT)/X11 + BUILDINCTOP = .. + INCDIR = $(INCROOT)/X11 + ADMDIR = /usr/adm + LIBDIR = $(USRLIBDIR)/X11 + CONFIGDIR = $(LIBDIR)/config + LINTLIBDIR = $(USRLIBDIR)/lint + + FONTDIR = $(LIBDIR)/fonts + XINITDIR = $(LIBDIR)/xinit + XDMDIR = $(LIBDIR)/xdm + TWMDIR = $(LIBDIR)/twm + MANPATH = /usr/X386/man + MANSOURCEPATH = $(MANPATH)/man + MANSUFFIX = 1x + LIBMANSUFFIX = 3x + MANDIR = $(MANSOURCEPATH)1 + LIBMANDIR = $(MANSOURCEPATH)3 + NLSDIR = $(LIBDIR)/nls + PEXAPIDIR = $(LIBDIR)/PEX + XAPPLOADDIR = $(LIBDIR)/app-defaults + FONTCFLAGS = -t + LINKKITDIR = $(USRLIBDIR)/Server + + INSTAPPFLAGS = $(INSTDATFLAGS) + + IMAKE = imake + DEPEND = makedepend + RGB = rgb + + FONTC = bdftopcf + + MKFONTDIR = mkfontdir + MKDIRHIER = /bin/sh $(BINDIR)/mkdirhier + + CONFIGSRC = $(TOP)/config + DOCUTILSRC = $(TOP)/doc/util + CLIENTSRC = $(TOP)/clients + DEMOSRC = $(TOP)/demos + LIBSRC = $(TOP)/lib + FONTSRC = $(TOP)/fonts + INCLUDESRC = $(TOP)/X11 + SERVERSRC = $(TOP)/server + UTILSRC = $(TOP)/util + SCRIPTSRC = $(UTILSRC)/scripts + EXAMPLESRC = $(TOP)/examples + CONTRIBSRC = $(TOP)/../contrib + DOCSRC = $(TOP)/doc + RGBSRC = $(TOP)/rgb + DEPENDSRC = $(UTILSRC)/makedepend + IMAKESRC = $(CONFIGSRC) + XAUTHSRC = $(LIBSRC)/Xau + XLIBSRC = $(LIBSRC)/X + XMUSRC = $(LIBSRC)/Xmu + TOOLKITSRC = $(LIBSRC)/Xt + AWIDGETSRC = $(LIBSRC)/Xaw + OLDXLIBSRC = $(LIBSRC)/oldX + XDMCPLIBSRC = $(LIBSRC)/Xdmcp + BDFTOSNFSRC = $(FONTSRC)/bdftosnf + BDFTOSNFSRC = $(FONTSRC)/clients/bdftosnf + BDFTOPCFSRC = $(FONTSRC)/clients/bdftopcf + MKFONTDIRSRC = $(FONTSRC)/clients/mkfontdir + FSLIBSRC = $(FONTSRC)/lib/fs + FONTSERVERSRC = $(FONTSRC)/server + EXTENSIONSRC = $(TOP)/extensions + XILIBSRC = $(EXTENSIONSRC)/lib/xinput + PEXLIBSRC = $(EXTENSIONSRC)/lib/PEXlib + PHIGSLIBSRC = $(EXTENSIONSRC)/lib/PEX + +# $XFree86: mit/config/lnuxLib.tmpl,v 1.1 1993/04/16 14:06:06 dawes Exp $ + +SHLIBLDFLAGS = +PICFLAGS = -B/usr/dll/jump/ + + DEPEXTENSIONLIB = + EXTENSIONLIB = -lXext + + DEPXLIB = $(DEPEXTENSIONLIB) + XLIB = $(EXTENSIONLIB) -lX11 + + DEPXMULIB = + XMULIB = -lXmu + + DEPXTOOLLIB = + XTOOLLIB = -lXt + + DEPXAWLIB = + XAWLIB = -lXaw + + DEPXILIB = + XILIB = -lXi + + DEPXTESTLIB = + XTESTLIB = -lXtst + + DEPPEXLIB = + PEXLIB = -lPEX5 + + SOXLIBREV = 3.0.1 + SOXTREV = 3.0.1 + SOXAWREV = 3.0.1 + SOOLDXREV = 3.0.1 + SOXMUREV = 3.0.1 + SOXEXTREV = 3.0.1 + SOXINPUTREV = 3.0.1 + SOPEXREV = 1.0.1 + + DEPXAUTHLIB = $(USRLIBDIR)/libXau.a + XAUTHLIB = -lXau + DEPXDMCPLIB = $(USRLIBDIR)/libXdmcp.a + XDMCPLIB = -lXdmcp + + DEPOLDXLIB = $(USRLIBDIR)/liboldX.a + OLDXLIB = -loldX + + DEPPHIGSLIB = $(USRLIBDIR)/libphigs.a + PHIGSLIB = -lphigs + + DEPXBSDLIB = $(USRLIBDIR)/libXbsd.a + XBSDLIB = -lXbsd + + LINTEXTENSIONLIB = $(LINTLIBDIR)/llib-lXext.ln + LINTXLIB = $(LINTLIBDIR)/llib-lX11.ln + LINTXMU = $(LINTLIBDIR)/llib-lXmu.ln + LINTXTOOL = $(LINTLIBDIR)/llib-lXt.ln + LINTXAW = $(LINTLIBDIR)/llib-lXaw.ln + LINTXI = $(LINTLIBDIR)/llib-lXi.ln + LINTPEX = $(LINTLIBDIR)/llib-lPEX5.ln + LINTPHIGS = $(LINTLIBDIR)/llib-lphigs.ln + + DEPLIBS = $(DEPXAWLIB) $(DEPXMULIB) $(DEPXTOOLLIB) $(DEPXLIB) + + DEPLIBS1 = $(DEPLIBS) + DEPLIBS2 = $(DEPLIBS) + DEPLIBS3 = $(DEPLIBS) + +# ------------------------------------------------------------------------- +# Imake rules for building libraries, programs, scripts, and data files +# $XFree86: mit/config/Imake.rules,v 1.9 1993/03/23 12:56:27 dawes Exp $ +# rules: $XConsortium: Imake.rules,v 1.123 91/09/16 20:12:16 rws Exp $ + +# ------------------------------------------------------------------------- +# start of Imakefile + +all:: + +depend:: + +clean:: + +includes:: + +# ------------------------------------------------------------------------- +# common rules for all Makefiles - do not edit + +emptyrule:: + +clean:: + $(RM_CMD) "#"* + +Makefile:: + -@if [ -f Makefile ]; then set -x; \ + $(RM) Makefile.bak; $(MV) Makefile Makefile.bak; \ + else exit 0; fi + $(IMAKE_CMD) -DTOPDIR=$(TOP) -DCURDIR=$(CURRENT_DIR) + +tags:: + $(TAGS) -w *.[ch] + $(TAGS) -xw *.[ch] > TAGS + +# ------------------------------------------------------------------------- +# empty rules for directories that do not have SUBDIRS - do not edit + +install:: + @echo "install in $(CURRENT_DIR) done" + +install.man:: + @echo "install.man in $(CURRENT_DIR) done" + +install.linkkit:: + @echo "install.linkkit in $(CURRENT_DIR) done" + +Makefiles:: + +includes:: + +# ------------------------------------------------------------------------- +# dependencies generated by makedepend + diff --git a/test/widget.exe b/test/widget.exe index 6afbf24984c..ea5dc2f8bf3 100755 Binary files a/test/widget.exe and b/test/widget.exe differ diff --git a/tools/Imakefile b/tools/Imakefile new file mode 100644 index 00000000000..7b739a187fa --- /dev/null +++ b/tools/Imakefile @@ -0,0 +1,5 @@ +#include "../Wine.tmpl" + +MODULE = tools + +SimpleProgramTarget(build) diff --git a/windows/Imakefile b/windows/Imakefile new file mode 100644 index 00000000000..b16652fcaab --- /dev/null +++ b/windows/Imakefile @@ -0,0 +1,53 @@ +#include "../Wine.tmpl" + +MODULE = windows + +SRCS = \ + class.c \ + dc.c \ + dce.c \ + event.c \ + message.c \ + win.c \ + timer.c \ + graphics.c \ + clipping.c \ + mapping.c \ + painting.c \ + keyboard.c \ + utility.c \ + syscolor.c \ + defwnd.c \ + defdlg.c \ + dialog.c \ + focus.c \ + scroll.c + +OBJS = \ + class.o \ + dc.o \ + dce.o \ + event.o \ + message.o \ + win.o \ + timer.o \ + graphics.o \ + clipping.o \ + mapping.o \ + painting.o \ + keyboard.o \ + utility.o \ + syscolor.o \ + defwnd.o \ + defdlg.o \ + dialog.o \ + focus.o \ + scroll.o + +WineRelocatableTarget($(TOP)/$(MODULE),,$(OBJS)) +DependTarget() +CleanTarget() + +includes:: + +install:: diff --git a/windows/Makefile b/windows/Makefile index 0c5d34add37..30570a109c9 100644 --- a/windows/Makefile +++ b/windows/Makefile @@ -2,7 +2,7 @@ CFLAGS=$(COPTS) $(DEBUGOPTS) -I$(INCLUDE_DIR) OBJS=class.o dc.o dce.o event.o message.o win.o timer.o graphics.o \ clipping.o mapping.o painting.o keyboard.o utility.o syscolor.o \ - defwnd.o defdlg.o dialog.o focus.o scroll.o + defwnd.o defdlg.o dialog.o focus.o scroll.o caret.o winpos.o default: windows.o diff --git a/windows/caret.c b/windows/caret.c new file mode 100644 index 00000000000..eb78dc80ec1 --- /dev/null +++ b/windows/caret.c @@ -0,0 +1,250 @@ +/* + * Caret functions + * + * Copyright 1993 David Metcalfe + */ + +static char Copyright[] = "Copyright David Metcalfe, 1993"; + +#include + +#include "windows.h" + +extern XtAppContext XT_app_context; + +typedef struct +{ + HWND hwnd; + short hidden; + BOOL on; + short x; + short y; + short width; + short height; + COLORREF color; + WORD timeout; + XtIntervalId xtid; +} CARET; + +static CARET Caret; +static BOOL LockCaret; + +static void CARET_Callback(XtPointer data, XtIntervalId *xtid); +static void CARET_HideCaret(CARET *pCaret); + + +/***************************************************************** + * CARET_Callback + */ + +static void CARET_Callback(XtPointer data, XtIntervalId *xtid) +{ + CARET *pCaret = (CARET *)data; + HDC hdc; + HBRUSH hBrush; + HRGN rgn; + +#ifdef DEBUG_CARET + printf("CARET_Callback: LockCaret=%d, hidden=%d, on=%d\n", + LockCaret, pCaret->hidden, pCaret->on); +#endif + if (!LockCaret && (!pCaret->hidden || pCaret->on)) + { + pCaret->on = (pCaret->on ? FALSE : TRUE); + hdc = GetDC(pCaret->hwnd); + hBrush = CreateSolidBrush(pCaret->color); + SelectObject(hdc, (HANDLE)hBrush); + SetROP2(hdc, R2_XORPEN); + rgn = CreateRectRgn(pCaret->x, pCaret->y, + pCaret->x + pCaret->width, + pCaret->y + pCaret->height); + FillRgn(hdc, rgn, hBrush); + DeleteObject((HANDLE)rgn); + DeleteObject((HANDLE)hBrush); + ReleaseDC(pCaret->hwnd, hdc); + } + + pCaret->xtid = XtAppAddTimeOut(XT_app_context, pCaret->timeout, + CARET_Callback, pCaret); +} + + +/***************************************************************** + * CARET_HideCaret + */ + +static void CARET_HideCaret(CARET *pCaret) +{ + HDC hdc; + HBRUSH hBrush; + HRGN rgn; + + pCaret->on = FALSE; + hdc = GetDC(pCaret->hwnd); + hBrush = CreateSolidBrush(pCaret->color); + SelectObject(hdc, (HANDLE)hBrush); + SetROP2(hdc, R2_XORPEN); + rgn = CreateRectRgn(pCaret->x, pCaret->y, + pCaret->x + pCaret->width, + pCaret->y + pCaret->height); + FillRgn(hdc, rgn, hBrush); + DeleteObject((HANDLE)rgn); + DeleteObject((HANDLE)hBrush); + ReleaseDC(pCaret->hwnd, hdc); +} + + +/***************************************************************** + * CreateCaret (USER.163) + */ + +void CreateCaret(HWND hwnd, HBITMAP bitmap, short width, short height) +{ + if (!hwnd) return; + + /* if cursor already exists, destroy it */ +/* if (Caret.hwnd) + DestroyCaret(); +*/ + if (bitmap) + { + printf("CreateCaret: Bitmaps are currently not supported\n"); + return; + } + + if (width) + Caret.width = width; + else + Caret.width = 3; /* should be SM_CXBORDER */ + + if (height) + Caret.height = height; + else + Caret.height = 3; /* should be SM_CYBORDER */ + + Caret.hwnd = hwnd; + Caret.hidden = 1; + Caret.on = FALSE; + Caret.x = 0; + Caret.y = 0; + Caret.color = GetSysColor(COLOR_WINDOWTEXT); + Caret.timeout = 750; + LockCaret = FALSE; + + Caret.xtid = XtAppAddTimeOut(XT_app_context, Caret.timeout, + CARET_Callback, &Caret); +} + + +/***************************************************************** + * DestroyCaret (USER.164) + */ + +void DestroyCaret() +{ +/* if (!Caret.hwnd) return; +*/ + XtRemoveTimeOut(Caret.xtid); + + if (Caret.on) + CARET_HideCaret(&Caret); + + Caret.hwnd = 0; /* cursor marked as not existing */ +} + + +/***************************************************************** + * SetCaretPos (USER.165) + */ + +void SetCaretPos(short x, short y) +{ + HDC hdc; + HBRUSH hBrush; + HRGN rgn; + + if (!Caret.hwnd) return; + +#ifdef DEBUG_CARET + printf("SetCaretPos: x=%d, y=%d\n", x, y); +#endif + + LockCaret = TRUE; + if (Caret.on) + CARET_HideCaret(&Caret); + + Caret.x = x; + Caret.y = y; + LockCaret = FALSE; +} + +/***************************************************************** + * HideCaret (USER.166) + */ + +void HideCaret(HWND hwnd) +{ + if (!Caret.hwnd) return; + if (hwnd && (Caret.hwnd != hwnd)) return; + + LockCaret = TRUE; + if (Caret.on) + CARET_HideCaret(&Caret); + + ++Caret.hidden; + LockCaret = FALSE; +} + + +/***************************************************************** + * ShowCaret (USER.167) + */ + +void ShowCaret(HWND hwnd) +{ + if (!Caret.hwnd) return; + if (hwnd && (Caret.hwnd != hwnd)) return; + +#ifdef DEBUG_CARET + printf("ShowCaret: hidden=%d\n", Caret.hidden); +#endif + if (Caret.hidden) + --Caret.hidden; +} + + +/***************************************************************** + * SetCaretBlinkTime (USER.168) + */ + +void SetCaretBlinkTime(WORD msecs) +{ + if (!Caret.hwnd) return; + + Caret.timeout = msecs; +} + + +/***************************************************************** + * GetCaretBlinkTime (USER.169) + */ + +WORD GetCaretBlinkTime() +{ + if (!Caret.hwnd) return; + + return Caret.timeout; +} + + +/***************************************************************** + * GetCaretPos (USER.183) + */ + +void GetCaretPos(LPPOINT pt) +{ + if (!Caret.hwnd || !pt) return; + + pt->x = Caret.x; + pt->y = Caret.y; +} diff --git a/windows/class.c b/windows/class.c index 23a2c495764..4ca2d9f5a2d 100644 --- a/windows/class.c +++ b/windows/class.c @@ -9,6 +9,7 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; #include "class.h" #include "user.h" #include "win.h" +#include "dce.h" static HCLASS firstClass = 0; @@ -18,19 +19,50 @@ static HCLASS firstClass = 0; * CLASS_FindClassByName * * Return a handle and a pointer to the class. + * 'ptr' can be NULL if the pointer is not needed. */ HCLASS CLASS_FindClassByName( char * name, CLASS **ptr ) { - HCLASS class = firstClass; - while(class) + ATOM atom; + HCLASS class; + CLASS * classPtr; + + /* First search task-specific classes */ + + if ((atom = FindAtom( name )) != 0) { - *ptr = (CLASS *) USER_HEAP_ADDR(class); - if (!strcasecmp( (*ptr)->wc.lpszClassName, name )) return class; - class = (*ptr)->hNext; + for (class = firstClass; (class); class = classPtr->hNext) + { + classPtr = (CLASS *) USER_HEAP_ADDR(class); + if (classPtr->wc.style & CS_GLOBALCLASS) continue; + if (classPtr->atomName == atom) + { + if (ptr) *ptr = classPtr; + return class; + } + } } + + /* Then search global classes */ + + if ((atom = GlobalFindAtom( name )) != 0) + { + for (class = firstClass; (class); class = classPtr->hNext) + { + classPtr = (CLASS *) USER_HEAP_ADDR(class); + if (!(classPtr->wc.style & CS_GLOBALCLASS)) continue; + if (classPtr->atomName == atom) + { + if (ptr) *ptr = classPtr; + return class; + } + } + } + return 0; } + /*********************************************************************** * CLASS_FindClassPtr * @@ -52,37 +84,50 @@ CLASS * CLASS_FindClassPtr( HCLASS hclass ) */ ATOM RegisterClass( LPWNDCLASS class ) { - CLASS * newClass; - HCLASS handle; + CLASS * newClass, * prevClassPtr; + HCLASS handle, prevClass; #ifdef DEBUG_CLASS printf( "RegisterClass: wndproc=%08x hinst=%d name='%s'\n", class->lpfnWndProc, class->hInstance, class->lpszClassName ); #endif + /* Check if a class with this name already exists */ + + prevClass = CLASS_FindClassByName( class->lpszClassName, &prevClassPtr ); + if (prevClass) + { + /* Class can be created only if it is local and */ + /* if the class with the same name is global. */ + + if (class->style & CS_GLOBALCLASS) return 0; + if (!(prevClassPtr->wc.style & CS_GLOBALCLASS)) return 0; + } + + /* Create class */ + handle = USER_HEAP_ALLOC( GMEM_MOVEABLE, sizeof(CLASS)+class->cbClsExtra ); if (!handle) return 0; newClass = (CLASS *) USER_HEAP_ADDR( handle ); newClass->hNext = firstClass; newClass->wMagic = CLASS_MAGIC; - newClass->atomName = handle; /* Should be an atom */ newClass->cWindows = 0; newClass->wc = *class; - if (newClass->wc.style & CS_CLASSDC) - newClass->hdc = CreateDC( "DISPLAY", NULL, NULL, NULL ); - else newClass->hdc = 0; + if (newClass->wc.style & CS_GLOBALCLASS) + newClass->atomName = GlobalAddAtom( class->lpszClassName ); + else newClass->atomName = AddAtom( class->lpszClassName ); - /* Class name should also be set to zero. For now we need the - * name because we don't have atoms. - */ - newClass->wc.lpszClassName = (char *)malloc(strlen(class->lpszClassName)+1); - strcpy( newClass->wc.lpszClassName, class->lpszClassName ); + if (newClass->wc.style & CS_CLASSDC) + newClass->hdce = DCE_AllocDCE( DCE_CLASS_DC ); + else newClass->hdce = 0; + + /* Menu name should also be set to zero. */ + newClass->wc.lpszClassName = NULL; if (class->cbClsExtra) memset( newClass->wExtra, 0, class->cbClsExtra ); - firstClass = handle; - return handle; /* Should be an atom */ + return newClass->atomName; } @@ -118,8 +163,10 @@ BOOL UnregisterClass( LPSTR className, HANDLE instance ) } /* Delete the class */ - if (classPtr->hdc) DeleteDC( classPtr->hdc ); + if (classPtr->hdce) DCE_FreeDCE( classPtr->hdce ); if (classPtr->wc.hbrBackground) DeleteObject( classPtr->wc.hbrBackground ); + if (classPtr->wc.style & CS_GLOBALCLASS) GlobalDeleteAtom( classPtr->atomName ); + else DeleteAtom( classPtr->atomName ); USER_HEAP_FREE( class ); return TRUE; } @@ -182,3 +229,34 @@ LONG SetClassLong( HWND hwnd, short offset, LONG newval ) *ptr = newval; return retval; } + + +/*********************************************************************** + * GetClassName (USER.58) + */ +int GetClassName(HWND hwnd, LPSTR lpClassName, short maxCount) +{ + WND *wndPtr; + CLASS *classPtr; + + if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0; + if (!(classPtr = CLASS_FindClassPtr(wndPtr->hClass))) return 0; + + return (GetAtomName(classPtr->atomName, lpClassName, maxCount)); +} + + +/*********************************************************************** + * GetClassInfo (USER.404) + */ +BOOL GetClassInfo(HANDLE hInstance, LPSTR lpClassName, + LPWNDCLASS lpWndClass) +{ + CLASS *classPtr; + + if (!(CLASS_FindClassByName(lpClassName, &classPtr))) return FALSE; + if (hInstance && (hInstance != classPtr->wc.hInstance)) return FALSE; + + memcpy(lpWndClass, &(classPtr->wc), sizeof(WNDCLASS)); + return TRUE; +} diff --git a/windows/clipping.c b/windows/clipping.c index 2126c287333..3c759a68790 100644 --- a/windows/clipping.c +++ b/windows/clipping.c @@ -10,6 +10,7 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; #include "windows.h" #include "win.h" +#include "message.h" /*********************************************************************** @@ -34,6 +35,7 @@ void InvalidateRgn( HWND hwnd, HRGN hrgn, BOOL erase ) else CombineRgn( newRgn, wndPtr->hrgnUpdate, hrgn, RGN_OR ); } if (wndPtr->hrgnUpdate) DeleteObject( wndPtr->hrgnUpdate ); + else MSG_IncPaintCount( wndPtr->hmemTaskQ ); wndPtr->hrgnUpdate = newRgn; if (erase) wndPtr->flags |= WIN_ERASE_UPDATERGN; } @@ -112,17 +114,14 @@ BOOL GetUpdateRect( HWND hwnd, LPRECT rect, BOOL erase ) if (rect) { - if (wndPtr->hrgnUpdate) GetRgnBox( wndPtr->hrgnUpdate, rect ); - else SetRectEmpty( rect ); - if (erase && wndPtr->hrgnUpdate) + if (wndPtr->hrgnUpdate) { - HDC hdc = GetDC( hwnd ); - if (hdc) - { - SendMessage( hwnd, WM_ERASEBKGND, hdc, 0 ); - ReleaseDC( hwnd, hdc ); - } + HRGN hrgn = CreateRectRgn( 0, 0, 0, 0 ); + if (GetUpdateRgn( hwnd, hrgn, erase ) == ERROR) return FALSE; + GetRgnBox( hrgn, rect ); + DeleteObject( hrgn ); } + else SetRectEmpty( rect ); } return (wndPtr->hrgnUpdate != 0); } @@ -133,17 +132,34 @@ BOOL GetUpdateRect( HWND hwnd, LPRECT rect, BOOL erase ) */ int GetUpdateRgn( HWND hwnd, HRGN hrgn, BOOL erase ) { + HRGN hrgnClip; + int retval; WND * wndPtr = WIN_FindWndPtr( hwnd ); if (!wndPtr) return ERROR; - if (erase && wndPtr->hrgnUpdate) + if (!wndPtr->hrgnUpdate) { - HDC hdc = GetDC( hwnd ); - if (hdc) - { - SendMessage( hwnd, WM_ERASEBKGND, hdc, 0 ); - ReleaseDC( hwnd, hdc ); - } + if (!(hrgnClip = CreateRectRgn( 0, 0, 0, 0 ))) return ERROR; + retval = CombineRgn( hrgn, hrgnClip, 0, RGN_COPY ); } - return CombineRgn( hrgn, wndPtr->hrgnUpdate, 0, RGN_COPY ); + else + { + hrgnClip = CreateRectRgn( 0, 0, + wndPtr->rectClient.right-wndPtr->rectClient.left, + wndPtr->rectClient.bottom-wndPtr->rectClient.top ); + if (!hrgnClip) return ERROR; + retval = CombineRgn( hrgn, wndPtr->hrgnUpdate, hrgnClip, RGN_AND ); + if (erase) + { + HDC hdc = GetDCEx( hwnd, wndPtr->hrgnUpdate, + DCX_INTERSECTRGN | DCX_USESTYLE ); + if (hdc) + { + SendMessage( hwnd, WM_ERASEBKGND, hdc, 0 ); + ReleaseDC( hwnd, hdc ); + } + } + } + DeleteObject( hrgnClip ); + return retval; } diff --git a/windows/dc.c b/windows/dc.c index 1a65b415927..4224b3ad335 100644 --- a/windows/dc.c +++ b/windows/dc.c @@ -7,7 +7,6 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; #include -#include #include "gdi.h" @@ -17,6 +16,8 @@ static DeviceCaps * displayDevCaps = NULL; extern const WIN_DC_INFO DCVAL_defaultValues; +extern void CLIPPING_SetDeviceClipping( DC * dc ); /* in objects/clipping.c */ + /* ROP code to GC function conversion */ const int DC_XROPfunction[16] = @@ -100,18 +101,8 @@ void DC_SetDeviceInfo( HDC hdc, DC * dc ) SelectObject( hdc, dc->w.hBrush ); SelectObject( hdc, dc->w.hFont ); - if (dc->w.hGCClipRgn) - { - RGNOBJ *obj = (RGNOBJ *) GDI_GetObjPtr(dc->w.hGCClipRgn, REGION_MAGIC); - XSetClipMask( XT_display, dc->u.x.gc, obj->region.pixmap ); - XSetClipOrigin( XT_display, dc->u.x.gc, - obj->region.box.left, obj->region.box.top ); - } - else - { - XSetClipMask( XT_display, dc->u.x.gc, None ); - XSetClipOrigin( XT_display, dc->u.x.gc, 0, 0 ); - } + XSetGraphicsExposures( XT_display, dc->u.x.gc, False ); + CLIPPING_SetDeviceClipping( dc ); } @@ -145,8 +136,11 @@ int DC_SetupGCForBrush( DC * dc ) XSetFillStyle( XT_display, dc->u.x.gc, (dc->w.backgroundMode == OPAQUE) ? FillOpaqueStippled : FillStippled ); - XSetTSOrigin( XT_display, dc->u.x.gc, dc->w.brushOrgX, dc->w.brushOrgY ); + XSetTSOrigin( XT_display, dc->u.x.gc, dc->w.DCOrgX + dc->w.brushOrgX, + dc->w.DCOrgY + dc->w.brushOrgY ); XSetFunction( XT_display, dc->u.x.gc, DC_XROPfunction[dc->w.ROPmode-1] ); + XSetFillRule( XT_display, dc->u.x.gc, + (dc->w.polyFillMode == WINDING) ? WindingRule : EvenOddRule ); return 1; } @@ -226,8 +220,7 @@ HDC GetDCState( HDC hdc ) if (dc->w.hVisRgn) { newdc->w.hVisRgn = CreateRectRgn( 0, 0, 0, 0 ); - CombineRgn( newdc->w.hVisRgn, dc->w.hVisRgn, 0, RGN_COPY ); - + CombineRgn( newdc->w.hVisRgn, dc->w.hVisRgn, 0, RGN_COPY ); } newdc->w.hGCClipRgn = 0; return handle; @@ -255,7 +248,7 @@ void SetDCState( HDC hdc, HDC hdcs ) dc->w.flags &= ~DC_SAVED; DC_SetDeviceInfo( hdc, dc ); SelectClipRgn( hdc, dcs->w.hClipRgn ); - SelectVisRgn( hdc, dcs->w.hGCClipRgn ); + SelectVisRgn( hdc, dcs->w.hVisRgn ); } @@ -337,6 +330,8 @@ HDC CreateDC( LPSTR driver, LPSTR device, LPSTR output, LPSTR initData ) dc->w.devCaps = displayDevCaps; dc->w.planes = displayDevCaps->planes; dc->w.bitsPerPixel = displayDevCaps->bitsPixel; + dc->w.DCSizeX = displayDevCaps->horzRes; + dc->w.DCSizeY = displayDevCaps->vertRes; DC_SetDeviceInfo( handle, dc ); @@ -372,6 +367,8 @@ HDC CreateCompatibleDC( HDC hdc ) dc->w.planes = 1; dc->w.bitsPerPixel = 1; dc->w.devCaps = displayDevCaps; + dc->w.DCSizeX = 1; + dc->w.DCSizeY = 1; SelectObject( handle, BITMAP_hbitmapMemDC ); DC_SetDeviceInfo( handle, dc ); diff --git a/windows/dce.c b/windows/dce.c index aaea4b012c1..7b24f1d4d94 100644 --- a/windows/dce.c +++ b/windows/dce.c @@ -22,6 +22,53 @@ static HANDLE firstDCE = 0; static HDC defaultDCstate = 0; +/*********************************************************************** + * DCE_AllocDCE + * + * Allocate a new DCE. + */ +HANDLE DCE_AllocDCE( DCE_TYPE type ) +{ + DCE * dce; + HANDLE handle = USER_HEAP_ALLOC( GMEM_MOVEABLE, sizeof(DCE) ); + if (!handle) return 0; + dce = (DCE *) USER_HEAP_ADDR( handle ); + if (!(dce->hdc = CreateDC( "DISPLAY", NULL, NULL, NULL ))) + { + USER_HEAP_FREE( handle ); + return 0; + } + dce->hwndCurrent = 0; + dce->type = type; + dce->inUse = (type != DCE_CACHE_DC); + dce->xOrigin = 0; + dce->yOrigin = 0; + dce->hNext = firstDCE; + firstDCE = handle; + return handle; +} + + +/*********************************************************************** + * DCE_FreeDCE + */ +void DCE_FreeDCE( HANDLE hdce ) +{ + DCE * dce; + HANDLE *handle = &firstDCE; + + if (!(dce = (DCE *) USER_HEAP_ADDR( hdce ))) return; + while (*handle && (*handle != hdce)) + { + DCE * prev = (DCE *) USER_HEAP_ADDR( *handle ); + handle = &prev->hNext; + } + if (*handle == hdce) *handle = dce->hNext; + DeleteDC( dce->hdc ); + USER_HEAP_FREE( hdce ); +} + + /*********************************************************************** * DCE_Init */ @@ -33,84 +80,133 @@ void DCE_Init() for (i = 0; i < NB_DCE; i++) { - handle = USER_HEAP_ALLOC( GMEM_MOVEABLE, sizeof(DCE) ); - if (!handle) return; - dce = (DCE *) USER_HEAP_ADDR( handle ); - dce->hdc = CreateDC( "DISPLAY", NULL, NULL, NULL ); - if (!dce->hdc) - { - USER_HEAP_FREE( handle ); - return; - } - dce->hwndCurrent = 0; - dce->flags = 0; - dce->inUse = FALSE; - dce->xOrigin = 0; - dce->yOrigin = 0; - dce->hNext = firstDCE; - firstDCE = handle; + if (!(handle = DCE_AllocDCE( DCE_CACHE_DC ))) return; + dce = (DCE *) USER_HEAP_ADDR( handle ); if (!defaultDCstate) defaultDCstate = GetDCState( dce->hdc ); } } +/*********************************************************************** + * GetDCEx (USER.359) + */ +/* Unimplemented flags: DCX_CLIPSIBLINGS, DCX_LOCKWINDOWUPDATE, DCX_PARENTCLIP + */ +HDC GetDCEx( HWND hwnd, HRGN hrgnClip, DWORD flags ) +{ + HANDLE hdce; + HDC hdc = 0; + DCE * dce; + DC * dc; + WND * wndPtr; + + if (hwnd) + { + if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0; + } + else wndPtr = NULL; + + if (flags & DCX_USESTYLE) + { + /* Not sure if this is the real meaning of the DCX_USESTYLE flag... */ + flags &= ~(DCX_CACHE | DCX_CLIPCHILDREN | DCX_CLIPSIBLINGS); + if (wndPtr) + { + if (!(wndPtr->flags & (WIN_CLASS_DC | WIN_OWN_DC))) + flags |= DCX_CACHE; + if (wndPtr->dwStyle & WS_CLIPCHILDREN) flags |= DCX_CLIPCHILDREN; + if (wndPtr->dwStyle & WS_CLIPSIBLINGS) flags |= DCX_CLIPSIBLINGS; + } + else flags |= DCX_CACHE; + } + + if (flags & DCX_CACHE) + { + for (hdce = firstDCE; (hdce); hdce = dce->hNext) + { + if (!(dce = (DCE *) USER_HEAP_ADDR( hdce ))) return 0; + if ((dce->type == DCE_CACHE_DC) && (!dce->inUse)) break; + } + } + else hdce = wndPtr->hdce; + + if (!hdce) return 0; + dce = (DCE *) USER_HEAP_ADDR( hdce ); + dce->hwndCurrent = hwnd; + dce->inUse = TRUE; + hdc = dce->hdc; + + /* Initialize DC */ + + if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return 0; + + if (wndPtr) + { + dc->u.x.drawable = wndPtr->window; + if (flags & DCX_WINDOW) + { + dc->w.DCOrgX = 0; + dc->w.DCOrgY = 0; + dc->w.DCSizeX = wndPtr->rectWindow.right - wndPtr->rectWindow.left; + dc->w.DCSizeY = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top; + } + else + { + dc->w.DCOrgX = wndPtr->rectClient.left - wndPtr->rectWindow.left; + dc->w.DCOrgY = wndPtr->rectClient.top - wndPtr->rectWindow.top; + dc->w.DCSizeX = wndPtr->rectClient.right - wndPtr->rectClient.left; + dc->w.DCSizeY = wndPtr->rectClient.bottom - wndPtr->rectClient.top; + IntersectVisRect( hdc, 0, 0, dc->w.DCSizeX, dc->w.DCSizeY ); + } + } + else dc->u.x.drawable = DefaultRootWindow( XT_display ); + + if (flags & DCX_CLIPCHILDREN) + XSetSubwindowMode( XT_display, dc->u.x.gc, ClipByChildren ); + else XSetSubwindowMode( XT_display, dc->u.x.gc, IncludeInferiors); + + if ((flags & DCX_INTERSECTRGN) || (flags & DCX_EXCLUDERGN)) + { + HRGN hrgn = CreateRectRgn( 0, 0, 0, 0 ); + if (hrgn) + { + if (CombineRgn( hrgn, InquireVisRgn(hdc), hrgnClip, + (flags & DCX_INTERSECTRGN) ? RGN_AND : RGN_DIFF )) + SelectVisRgn( hdc, hrgn ); + DeleteObject( hrgn ); + } + } + +#ifdef DEBUG_DC + printf( "GetDCEx(%d,%d,0x%x): returning %d\n", hwnd, hrgnClip, flags, hdc); +#endif + return hdc; +} + + /*********************************************************************** * GetDC (USER.66) */ HDC GetDC( HWND hwnd ) { - HANDLE hdce; - HDC hdc = 0; - DCE * dce; - DC * dc; - WND * wndPtr = NULL; - CLASS * classPtr; - + return GetDCEx( hwnd, 0, DCX_USESTYLE ); +} + + +/*********************************************************************** + * GetWindowDC (USER.67) + */ +HDC GetWindowDC( HWND hwnd ) +{ + int flags = DCX_CACHE | DCX_WINDOW; if (hwnd) { + WND * wndPtr; if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0; - if (!(classPtr = CLASS_FindClassPtr( wndPtr->hClass ))) return 0; - if (wndPtr->hdc) hdc = wndPtr->hdc; - else if (classPtr->hdc) hdc = classPtr->hdc; + if (wndPtr->dwStyle & WS_CLIPCHILDREN) flags |= DCX_CLIPCHILDREN; + if (wndPtr->dwStyle & WS_CLIPSIBLINGS) flags |= DCX_CLIPSIBLINGS; } - - if (!hdc) - { - for (hdce = firstDCE; (hdce); hdce = dce->hNext) - { - dce = (DCE *) USER_HEAP_ADDR( hdce ); - if (!dce) return 0; - if (!dce->inUse) break; - } - if (!hdce) return 0; - dce->hwndCurrent = hwnd; - dce->inUse = TRUE; - hdc = dce->hdc; - } - - /* Initialize DC */ - - if (!(dc = (DC *) GDI_GetObjPtr( dce->hdc, DC_MAGIC ))) return 0; - - if (wndPtr) - { - dc->u.x.drawable = XtWindow( wndPtr->winWidget ); - dc->u.x.widget = wndPtr->winWidget; - if (wndPtr->dwStyle & WS_CLIPCHILDREN) - XSetSubwindowMode( XT_display, dc->u.x.gc, ClipByChildren ); - else XSetSubwindowMode( XT_display, dc->u.x.gc, IncludeInferiors); - } - else - { - dc->u.x.drawable = DefaultRootWindow( XT_display ); - dc->u.x.widget = 0; - XSetSubwindowMode( XT_display, dc->u.x.gc, IncludeInferiors ); - } - -#ifdef DEBUG_WIN - printf( "GetDC(%d): returning %d\n", hwnd, hdc ); -#endif - return hdc; + return GetDCEx( hwnd, 0, flags ); } @@ -119,33 +215,23 @@ HDC GetDC( HWND hwnd ) */ int ReleaseDC( HWND hwnd, HDC hdc ) { - HANDLE hdce, next; + HANDLE hdce; DCE * dce; - WND * wndPtr = NULL; - CLASS * classPtr; -#ifdef DEBUG_WIN +#ifdef DEBUG_DC printf( "ReleaseDC: %d %d\n", hwnd, hdc ); #endif - if (hwnd) - { - if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0; - if (wndPtr->hdc && (wndPtr->hdc == hdc)) return 1; - if (!(classPtr = CLASS_FindClassPtr( wndPtr->hClass ))) return 0; - if (classPtr->hdc && (classPtr->hdc == hdc)) return 1; - } - for (hdce = firstDCE; (hdce); hdce = dce->hNext) { if (!(dce = (DCE *) USER_HEAP_ADDR( hdce ))) return 0; if (dce->inUse && (dce->hdc == hdc)) break; } - if (hdce) + if (dce->type == DCE_CACHE_DC) { SetDCState( dce->hdc, defaultDCstate ); dce->inUse = FALSE; - } + } return (hdce != 0); } diff --git a/windows/defwnd.c b/windows/defwnd.c index 3d3a280cdf5..e2f9a397885 100644 --- a/windows/defwnd.c +++ b/windows/defwnd.c @@ -6,24 +6,27 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; +#ifndef USE_XLIB #include #include +#endif #include "windows.h" #include "win.h" #include "class.h" #include "user.h" +extern Display * XT_display; /*********************************************************************** * DefWindowProc (USER.107) */ LONG DefWindowProc( HWND hwnd, WORD msg, WORD wParam, LONG lParam ) { - WND * wndPtr; CLASS * classPtr; LPSTR textPtr; int len; + WND * wndPtr = WIN_FindWndPtr( hwnd ); #ifdef DEBUG_MESSAGE printf( "DefWindowProc: %d %d %d %08x\n", hwnd, msg, wParam, lParam ); @@ -34,24 +37,57 @@ LONG DefWindowProc( HWND hwnd, WORD msg, WORD wParam, LONG lParam ) case WM_NCCREATE: { CREATESTRUCT * createStruct = (CREATESTRUCT *)lParam; - wndPtr = WIN_FindWndPtr(hwnd); if (createStruct->lpszName) { /* Allocate space for window text */ wndPtr->hText = USER_HEAP_ALLOC(GMEM_MOVEABLE, - strlen(createStruct->lpszName) + 1); + strlen(createStruct->lpszName) + 2); textPtr = (LPSTR)USER_HEAP_ADDR(wndPtr->hText); strcpy(textPtr, createStruct->lpszName); + *(textPtr + strlen(createStruct->lpszName) + 1) = '\0'; + /* for use by edit control */ } return 1; } + + case WM_NCCALCSIZE: + { +#ifdef USE_XLIB + NCCALCSIZE_PARAMS *params = (NCCALCSIZE_PARAMS *)lParam; + if (wndPtr->dwStyle & WS_CHILD) + { + if (wndPtr->dwStyle & WS_BORDER) + { + params->rgrc[0].left += 1; /* SM_CXBORDER */ + params->rgrc[0].top += 1; /* SM_CYBORDER */ + params->rgrc[0].right -= 1; /* SM_CXBORDER */ + params->rgrc[0].bottom -= 1; /* SM_CYBORDER */ + } + } + else + { + params->rgrc[0].left += 4; /* SM_CXFRAME */ + params->rgrc[0].top += 30; /* SM_CYFRAME+SM_CYCAPTION */ + params->rgrc[0].right -= 4; /* SM_CXFRAME */ + params->rgrc[0].bottom -= 4; /* SM_CYFRAME */ + if (wndPtr->dwStyle & WS_VSCROLL) + { + params->rgrc[0].right -= 16; /* SM_CXVSCROLL */ + } + if (wndPtr->dwStyle & WS_HSCROLL) + { + params->rgrc[0].bottom += 16; /* SM_CYHSCROLL */ + } + } +#endif + return 0; + } case WM_CREATE: return 0; case WM_NCDESTROY: { - wndPtr = WIN_FindWndPtr(hwnd); if (wndPtr->hText) USER_HEAP_FREE(wndPtr->hText); wndPtr->hText = 0; return 0; @@ -69,10 +105,23 @@ LONG DefWindowProc( HWND hwnd, WORD msg, WORD wParam, LONG lParam ) DestroyWindow( hwnd ); return 0; + case WM_WINDOWPOSCHANGED: + { + WINDOWPOS * winPos = (WINDOWPOS *)lParam; + if (!(winPos->flags & SWP_NOMOVE)) + SendMessage( hwnd, WM_MOVE, 0, + MAKELONG( wndPtr->rectClient.left, + wndPtr->rectClient.top )); + if (!(winPos->flags & SWP_NOSIZE)) + SendMessage( hwnd, WM_SIZE, SIZE_RESTORED, + MAKELONG(wndPtr->rectClient.right-wndPtr->rectClient.left, + wndPtr->rectClient.bottom-wndPtr->rectClient.top)); + return 0; + } + case WM_ERASEBKGND: case WM_ICONERASEBKGND: { - if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 1; if (!(classPtr = CLASS_FindClassPtr( wndPtr->hClass ))) return 1; if (!classPtr->wc.hbrBackground) return 1; FillWindow( GetParent(hwnd), hwnd, (HDC)wParam, @@ -106,7 +155,6 @@ LONG DefWindowProc( HWND hwnd, WORD msg, WORD wParam, LONG lParam ) { if (wParam) { - wndPtr = WIN_FindWndPtr(hwnd); if (wndPtr->hText) { textPtr = (LPSTR)USER_HEAP_ADDR(wndPtr->hText); @@ -123,7 +171,6 @@ LONG DefWindowProc( HWND hwnd, WORD msg, WORD wParam, LONG lParam ) case WM_GETTEXTLENGTH: { - wndPtr = WIN_FindWndPtr(hwnd); if (wndPtr->hText) { textPtr = (LPSTR)USER_HEAP_ADDR(wndPtr->hText); @@ -134,7 +181,6 @@ LONG DefWindowProc( HWND hwnd, WORD msg, WORD wParam, LONG lParam ) case WM_SETTEXT: { - wndPtr = WIN_FindWndPtr(hwnd); if (wndPtr->hText) USER_HEAP_FREE(wndPtr->hText); @@ -142,10 +188,18 @@ LONG DefWindowProc( HWND hwnd, WORD msg, WORD wParam, LONG lParam ) strlen((LPSTR)lParam) + 1); textPtr = (LPSTR)USER_HEAP_ADDR(wndPtr->hText); strcpy(textPtr, (LPSTR)lParam); +#ifdef USE_XLIB + XStoreName( XT_display, wndPtr->window, textPtr ); +#else if (wndPtr->shellWidget) XtVaSetValues( wndPtr->shellWidget, XtNtitle, textPtr, NULL ); +#endif return (0L); } + case WM_SETCURSOR: + if (wndPtr->hCursor != (HCURSOR)NULL) + SetCursor(wndPtr->hCursor); + return 0L; } return 0; } diff --git a/windows/dialog.c b/windows/dialog.c index 108c964c5cb..83a03899566 100644 --- a/windows/dialog.c +++ b/windows/dialog.c @@ -8,7 +8,6 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; #include "windows.h" #include "dialog.h" -#include "prototypes.h" #include "win.h" @@ -149,25 +148,19 @@ HWND CreateDialogParam( HINSTANCE hInst, LPCSTR dlgTemplate, HWND hwnd = 0; HANDLE hres, hmem; LPCSTR data; - int size; #ifdef DEBUG_DIALOG printf( "CreateDialogParam: %d,'%s',%d,%p,%d\n", hInst, dlgTemplate, owner, dlgProc, param ); #endif - -#if 0 - if (!(hres = FindResource( hInst, dlgTemplate, RT_DIALOG ))) return 0; + + /* FIXME: MAKEINTRESOURCE should be replaced by RT_DIALOG */ + if (!(hres = FindResource( hInst, dlgTemplate, MAKEINTRESOURCE(0x8005) ))) + return 0; if (!(hmem = LoadResource( hInst, hres ))) return 0; if (!(data = LockResource( hmem ))) hwnd = 0; else hwnd = CreateDialogIndirectParam(hInst, data, owner, dlgProc, param); FreeResource( hmem ); -#else - hmem = RSC_LoadResource( hInst, dlgTemplate, NE_RSCTYPE_DIALOG, &size ); - data = (LPCSTR) GlobalLock( hmem ); - hwnd = CreateDialogIndirectParam( hInst, data, owner, dlgProc, param ); - GlobalFree( hmem ); -#endif return hwnd; } @@ -314,8 +307,8 @@ HWND CreateDialogIndirectParam( HINSTANCE hInst, LPCSTR dlgTemplate, if (dlgInfo->hUserFont) SendMessage( hwnd, WM_SETFONT, dlgInfo->hUserFont, 0); SendMessage( hwnd, WM_INITDIALOG, dlgInfo->hwndFocus, param ); - if (SendMessage( hwnd, WM_INITDIALOG, dlgInfo->hwndFocus, param )) - SetFocus( dlgInfo->hwndFocus ); +/* if (SendMessage( hwnd, WM_INITDIALOG, dlgInfo->hwndFocus, param )) + SetFocus( dlgInfo->hwndFocus ); */ return hwnd; } diff --git a/windows/event.c b/windows/event.c index 31301896e61..5f3aa3d9e97 100644 --- a/windows/event.c +++ b/windows/event.c @@ -18,6 +18,8 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; #define NB_BUTTONS 3 /* Windows can handle 3 buttons */ static WORD dblclick_time = 300; /* Max. time for a double click (milliseconds) */ +extern Display * XT_display; + /* Event handlers */ static void EVENT_expose(); static void EVENT_key(); @@ -25,17 +27,175 @@ static void EVENT_mouse_motion(); static void EVENT_mouse_button(); static void EVENT_structure(); static void EVENT_focus_change(); +static void EVENT_enter_notify(); + + /* X context to associate a hwnd to an X window */ +static XContext winContext = 0; /* State variables */ static HWND captureWnd = 0; - +Window winHasCursor = 0; extern HWND hWndFocus; +/* Keyboard translation tables */ +static int special_key[] = +{ + VK_BACK, VK_TAB, 0, VK_CLEAR, 0, VK_RETURN, 0, 0, /* FF08 */ + 0, 0, 0, VK_PAUSE, VK_SCROLL, 0, 0, 0, /* FF10 */ + 0, 0, 0, VK_ESCAPE /* FF18 */ +}; + +static cursor_key[] = +{ + VK_HOME, VK_LEFT, VK_UP, VK_RIGHT, VK_DOWN, VK_PRIOR, + VK_NEXT, VK_END /* FF50 */ +}; + +static misc_key[] = +{ + VK_SELECT, VK_SNAPSHOT, VK_EXECUTE, VK_INSERT, 0, 0, 0, 0, /* FF60 */ + VK_CANCEL, VK_HELP, VK_CANCEL, VK_MENU /* FF68 */ +}; + +static keypad_key[] = +{ + VK_MENU, VK_NUMLOCK, /* FF7E */ + 0, 0, 0, 0, 0, 0, 0, 0, /* FF80 */ + 0, 0, 0, 0, 0, VK_RETURN, 0, 0, /* FF88 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* FF90 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* FF98 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* FFA0 */ + 0, 0, VK_MULTIPLY, VK_ADD, VK_SEPARATOR, VK_SUBTRACT, + VK_DECIMAL, VK_DIVIDE, /* FFA8 */ + VK_NUMPAD0, VK_NUMPAD1, VK_NUMPAD2, VK_NUMPAD3, VK_NUMPAD4, + VK_NUMPAD5, VK_NUMPAD6, VK_NUMPAD7, /* FFB0 */ + VK_NUMPAD8, VK_NUMPAD9 /* FFB8 */ +}; + +static function_key[] = +{ + VK_F1, VK_F2, /* FFBE */ + VK_F3, VK_F4, VK_F5, VK_F6, VK_F7, VK_F8, VK_F9, VK_F10, /* FFC0 */ + VK_F11, VK_F12, VK_F13, VK_F14, VK_F15, VK_F16 /* FFC8 */ +}; + +static modifier_key[] = +{ + VK_SHIFT, VK_SHIFT, VK_CONTROL, VK_CONTROL, VK_CAPITAL, + 0, 0, /* FFE1 */ + 0, VK_MENU, VK_MENU /* FFE8 */ +}; + +typedef union +{ + struct + { + unsigned long count : 16; + unsigned long code : 8; + unsigned long extended : 1; + unsigned long : 4; + unsigned long context : 1; + unsigned long previous : 1; + unsigned long transition : 1; + } lp1; + unsigned long lp2; +} KEYLP; + +static BOOL KeyDown = FALSE; + + +#ifdef DEBUG_EVENT +static char *event_names[] = +{ + "", "", "KeyPress", "KeyRelease", "ButtonPress", "ButtonRelease", + "MotionNotify", "EnterNotify", "LeaveNotify", "FocusIn", "FocusOut", + "KeymapNotify", "Expose", "GraphicsExpose", "NoExpose", "VisibilityNotify", + "CreateNotify", "DestroyNotify", "UnmapNotify", "MapNotify", "MapRequest", + "ReparentNotify", "ConfigureNotify", "ConfigureRequest", "GravityNotify", + "ResizeRequest", "CirculateNotify", "CirculateRequest", "PropertyNotify", + "SelectionClear", "SelectionRequest", "SelectionNotify", "ColormapNotify", + "ClientMessage", "MappingNotify" +}; +#endif + + +/*********************************************************************** + * EVENT_ProcessEvent + * + * Process an X event. + */ +void EVENT_ProcessEvent( XEvent *event ) +{ + HWND hwnd; + XPointer ptr; + Boolean cont_dispatch = TRUE; + + XFindContext( XT_display, ((XAnyEvent *)event)->window, winContext, &ptr ); + hwnd = (HWND)ptr & 0xffff; + +#ifdef DEBUG_EVENT + printf( "Got event %s for hwnd %d\n", + event_names[event->type], hwnd ); +#endif + + switch(event->type) + { + case Expose: + EVENT_expose( 0, hwnd, event, &cont_dispatch ); + break; + + case KeyPress: + case KeyRelease: + EVENT_key( 0, hwnd, event, &cont_dispatch ); + break; + + case MotionNotify: + EVENT_mouse_motion( 0, hwnd, event, &cont_dispatch ); + break; + + case ButtonPress: + case ButtonRelease: + EVENT_mouse_button( 0, hwnd, event, &cont_dispatch ); + break; + + case CirculateNotify: + case ConfigureNotify: + case MapNotify: + case UnmapNotify: + EVENT_structure( 0, hwnd, event, &cont_dispatch ); + break; + + case FocusIn: + case FocusOut: + EVENT_focus_change( 0, hwnd, event, &cont_dispatch ); + break; + + case EnterNotify: + EVENT_enter_notify( 0, hwnd, event, &cont_dispatch ); + break; + +#ifdef DEBUG_EVENT + default: + printf( "Unprocessed event %s for hwnd %d\n", + event_names[event->type], hwnd ); + break; +#endif + } +} + + /*********************************************************************** * EVENT_AddHandlers * * Add the event handlers to the given window */ +#ifdef USE_XLIB +void EVENT_AddHandlers( Window w, int hwnd ) +{ + if (!winContext) winContext = XUniqueContext(); + XSaveContext( XT_display, w, winContext, (XPointer)hwnd ); +} +#else void EVENT_AddHandlers( Widget w, int hwnd ) { XtAddEventHandler(w, ExposureMask, FALSE, @@ -50,7 +210,10 @@ void EVENT_AddHandlers( Widget w, int hwnd ) EVENT_structure, (XtPointer)hwnd ); XtAddEventHandler(w, FocusChangeMask, FALSE, EVENT_focus_change, (XtPointer)hwnd ); + XtAddEventHandler(w, EnterWindowMask, FALSE, + EVENT_enter_notify, (XtPointer)hwnd ); } +#endif /*********************************************************************** @@ -60,6 +223,7 @@ void EVENT_AddHandlers( Widget w, int hwnd ) */ void EVENT_RemoveHandlers( Widget w, int hwnd ) { +#ifndef USE_XLIB XtRemoveEventHandler(w, ExposureMask, FALSE, EVENT_expose, (XtPointer)hwnd ); XtRemoveEventHandler(w, KeyPressMask | KeyReleaseMask, FALSE, @@ -72,6 +236,9 @@ void EVENT_RemoveHandlers( Widget w, int hwnd ) EVENT_structure, (XtPointer)hwnd ); XtRemoveEventHandler(w, FocusChangeMask, FALSE, EVENT_focus_change, (XtPointer)hwnd ); + XtRemoveEventHandler(w, EnterWindowMask, FALSE, + EVENT_enter_notify, (XtPointer)hwnd ); +#endif } @@ -103,10 +270,14 @@ static void EVENT_expose( Widget w, int hwnd, XExposeEvent *event, Boolean *cont_dispatch ) { RECT rect; - rect.left = event->x; - rect.top = event->y; - rect.right = event->x + event->width; - rect.bottom = event->y + event->height; + WND * wndPtr = WIN_FindWndPtr( hwnd ); + if (!wndPtr) return; + /* Make position relative to client area instead of window */ + rect.left = event->x - (wndPtr->rectClient.left - wndPtr->rectWindow.left); + rect.top = event->y - (wndPtr->rectClient.top - wndPtr->rectWindow.top); + rect.right = rect.left + event->width; + rect.bottom = rect.top + event->height; + winHasCursor = event->window; InvalidateRect( hwnd, &rect, TRUE ); } @@ -121,24 +292,128 @@ static void EVENT_key( Widget w, int hwnd, XKeyEvent *event, Boolean *cont_dispatch ) { MSG msg; - char Str[24]; XComposeStatus cs; - KeySym key; - int count = XLookupString(event, Str, 1, &key, &cs); + KeySym keysym; + WORD xkey, vkey, key_type, key; + KEYLP keylp; + BOOL extended = FALSE; + WND * wndPtr = WIN_FindWndPtr( hwnd ); + int count = XLookupString(event, Str, 1, &keysym, &cs); Str[count] = '\0'; #ifdef DEBUG_KEY - printf("WM_KEY??? : count=%u / %X / '%s'\n",count, Str[0], Str); -#endif - msg.hwnd = hwnd; - msg.message = (event->type == KeyRelease) ? WM_KEYUP : WM_KEYDOWN; - msg.wParam = Str[0]; - msg.lParam = (event->x & 0xffff) | (event->y << 16); - msg.time = event->time; - msg.pt.x = event->x & 0xffff; - msg.pt.y = event->y & 0xffff; + printf("WM_KEY??? : keysym=%lX, count=%u / %X / '%s'\n", + keysym, count, Str[0], Str); +#endif + + xkey = LOWORD(keysym); + key_type = HIBYTE(xkey); + key = LOBYTE(xkey); +#ifdef DEBUG_KEY + printf(" key_type=%X, key=%X\n", key_type, key); +#endif + + /* Position must be relative to client area */ + event->x -= wndPtr->rectClient.left - wndPtr->rectWindow.left; + event->y -= wndPtr->rectClient.top - wndPtr->rectWindow.top; + + if (key_type == 0xFF) /* non-character key */ + { + if (key >= 0x08 && key <= 0x1B) /* special key */ + vkey = special_key[key - 0x08]; + else if (key >= 0x50 && key <= 0x57) /* cursor key */ + vkey = cursor_key[key - 0x50]; + else if (key >= 0x60 && key <= 0x6B) /* miscellaneous key */ + vkey = misc_key[key - 0x60]; + else if (key >= 0x7E && key <= 0xB9) /* keypad key */ + { + vkey = keypad_key[key - 0x7E]; + extended = TRUE; + } + else if (key >= 0xBE && key <= 0xCD) /* function key */ + { + vkey = function_key[key - 0xBE]; + extended = TRUE; + } + else if (key >= 0xE1 && key <= 0xEA) /* modifier key */ + vkey = modifier_key[key - 0xE1]; + else if (key == 0xFF) /* DEL key */ + vkey = VK_DELETE; + } + else if (key_type == 0) /* character key */ + { + if (key >= 0x61 && key <= 0x7A) + vkey = key - 0x20; /* convert lower to uppercase */ + else + vkey = key; + } + + if (event->type == KeyPress) + { + msg.hwnd = hwnd; + msg.message = WM_KEYDOWN; + msg.wParam = vkey; + keylp.lp1.count = 1; + keylp.lp1.code = LOBYTE(event->keycode); + keylp.lp1.extended = (extended ? 1 : 0); + keylp.lp1.context = (event->state & Mod1Mask ? 1 : 0); + keylp.lp1.previous = (KeyDown ? 0 : 1); + keylp.lp1.transition = 0; + msg.lParam = keylp.lp2; +#ifdef DEBUG_KEY + printf(" wParam=%X, lParam=%lX\n", msg.wParam, msg.lParam); +#endif + msg.time = event->time; + msg.pt.x = event->x & 0xffff; + msg.pt.y = event->y & 0xffff; - MSG_AddMsg( &msg ); + hardware_event( hwnd, WM_KEYDOWN, vkey, keylp.lp2, + event->x & 0xffff, event->y & 0xffff, event->time, 0 ); + KeyDown = TRUE; + + /* The key translation ought to take place in TranslateMessage(). + * However, there is no way of passing the required information + * in a Windows message, so TranslateMessage does not currently + * do anything and the translation is done here. + */ + if (count == 1) /* key has an ASCII representation */ + { + msg.hwnd = hwnd; + msg.message = WM_CHAR; + msg.wParam = (WORD)Str[0]; + msg.lParam = keylp.lp2; +#ifdef DEBUG_KEY + printf("WM_CHAR : wParam=%X\n", msg.wParam); +#endif + msg.time = event->time; + msg.pt.x = event->x & 0xffff; + msg.pt.y = event->y & 0xffff; + PostMessage( hwnd, WM_CHAR, (WORD)Str[0], keylp.lp2 ); + } + } + else + { + msg.hwnd = hwnd; + msg.message = WM_KEYUP; + msg.wParam = vkey; + keylp.lp1.count = 1; + keylp.lp1.code = LOBYTE(event->keycode); + keylp.lp1.extended = (extended ? 1 : 0); + keylp.lp1.context = (event->state & Mod1Mask ? 1 : 0); + keylp.lp1.previous = 1; + keylp.lp1.transition = 1; + msg.lParam = keylp.lp2; +#ifdef DEBUG_KEY + printf(" wParam=%X, lParam=%lX\n", msg.wParam, msg.lParam); +#endif + msg.time = event->time; + msg.pt.x = event->x & 0xffff; + msg.pt.y = event->y & 0xffff; + + hardware_event( hwnd, WM_KEYUP, vkey, keylp.lp2, + event->x & 0xffff, event->y & 0xffff, event->time, 0 ); + KeyDown = FALSE; + } } @@ -150,17 +425,17 @@ static void EVENT_key( Widget w, int hwnd, XKeyEvent *event, static void EVENT_mouse_motion( Widget w, int hwnd, XMotionEvent *event, Boolean *cont_dispatch ) { - MSG msg; - - msg.hwnd = hwnd; - msg.message = WM_MOUSEMOVE; - msg.wParam = EVENT_XStateToKeyState( event->state ); - msg.lParam = (event->x & 0xffff) | (event->y << 16); - msg.time = event->time; - msg.pt.x = event->x & 0xffff; - msg.pt.y = event->y & 0xffff; - - MSG_AddMsg( &msg ); + WND * wndPtr = WIN_FindWndPtr( hwnd ); + if (!wndPtr) return; + + /* Position must be relative to client area */ + event->x -= wndPtr->rectClient.left - wndPtr->rectWindow.left; + event->y -= wndPtr->rectClient.top - wndPtr->rectWindow.top; + + hardware_event( hwnd, WM_MOUSEMOVE, EVENT_XStateToKeyState( event->state ), + (event->x & 0xffff) | (event->y << 16), + event->x & 0xffff, event->y & 0xffff, + event->time, 0 ); } @@ -180,9 +455,15 @@ static void EVENT_mouse_button( Widget w, int hwnd, XButtonEvent *event, }; static unsigned long lastClickTime[NB_BUTTONS] = { 0, 0, 0 }; - MSG msg; int buttonNum, prevTime, type; - + + WND * wndPtr = WIN_FindWndPtr( hwnd ); + if (!wndPtr) return; + + /* Position must be relative to client area */ + event->x -= wndPtr->rectClient.left - wndPtr->rectWindow.left; + event->y -= wndPtr->rectClient.top - wndPtr->rectWindow.top; + buttonNum = event->button-1; if (buttonNum >= NB_BUTTONS) return; if (event->type == ButtonRelease) type = 1; @@ -201,15 +482,13 @@ static void EVENT_mouse_button( Widget w, int hwnd, XButtonEvent *event, else type = 0; } - msg.hwnd = hwnd; - msg.message = messages[type][buttonNum]; - msg.wParam = EVENT_XStateToKeyState( event->state ); - msg.lParam = (event->x & 0xffff) | (event->y << 16); - msg.time = event->time; - msg.pt.x = event->x & 0xffff; - msg.pt.y = event->y & 0xffff; + winHasCursor = event->window; - MSG_AddMsg( &msg ); + hardware_event( hwnd, messages[type][buttonNum], + EVENT_XStateToKeyState( event->state ), + (event->x & 0xffff) | (event->y << 16), + event->x & 0xffff, event->y & 0xffff, + event->time, 0 ); } @@ -232,13 +511,31 @@ static void EVENT_structure( Widget w, int hwnd, XEvent *event, { case ConfigureNotify: { + HANDLE handle; + NCCALCSIZE_PARAMS *params; XConfigureEvent * evt = (XConfigureEvent *)event; WND * wndPtr = WIN_FindWndPtr( hwnd ); if (!wndPtr) return; - wndPtr->rectClient.right = wndPtr->rectClient.left + evt->width; - wndPtr->rectClient.bottom = wndPtr->rectClient.top + evt->height; + wndPtr->rectWindow.left = evt->x; + wndPtr->rectWindow.top = evt->y; + wndPtr->rectWindow.right = evt->x + evt->width; + wndPtr->rectWindow.bottom = evt->y + evt->height; + + /* Send WM_NCCALCSIZE message */ + handle = GlobalAlloc( GMEM_MOVEABLE, sizeof(*params) ); + params = (NCCALCSIZE_PARAMS *)GlobalLock( handle ); + params->rgrc[0] = wndPtr->rectWindow; + params->lppos = NULL; /* Should be WINDOWPOS struct */ + SendMessage( hwnd, WM_NCCALCSIZE, FALSE, params ); + wndPtr->rectClient = params->rgrc[0]; + PostMessage( hwnd, WM_MOVE, 0, + MAKELONG( wndPtr->rectClient.left, + wndPtr->rectClient.top )); PostMessage( hwnd, WM_SIZE, SIZE_RESTORED, - (evt->width & 0xffff) | (evt->height << 16) ); + MAKELONG(wndPtr->rectClient.right-wndPtr->rectClient.left, + wndPtr->rectClient.bottom-wndPtr->rectClient.top)); + GlobalUnlock( handle ); + GlobalFree( handle ); } break; @@ -254,21 +551,12 @@ static void EVENT_structure( Widget w, int hwnd, XEvent *event, static void EVENT_focus_change( Widget w, int hwnd, XEvent *event, Boolean *cont_dispatch ) { - MSG msg; - - msg.hwnd = hwnd; - msg.time = GetTickCount(); - msg.pt.x = 0; - msg.pt.y = 0; - switch(event->type) { case FocusIn: { - msg.message = WM_SETFOCUS; - msg.wParam = hwnd; + PostMessage( hwnd, WM_SETFOCUS, hwnd, 0 ); hWndFocus = hwnd; - } break; @@ -276,13 +564,32 @@ static void EVENT_focus_change( Widget w, int hwnd, XEvent *event, { if (hWndFocus) { - msg.message = WM_KILLFOCUS; - msg.wParam = hwnd; + PostMessage( hwnd, WM_KILLFOCUS, hwnd, 0 ); hWndFocus = 0; } } } - MSG_AddMsg( &msg ); +} + + +/********************************************************************** + * EVENT_enter_notify + * + * Handle an X EnterNotify event + */ +static void EVENT_enter_notify( Widget w, int hwnd, XCrossingEvent *event, + Boolean *cont_dispatch ) +{ + if (captureWnd != 0) return; + + winHasCursor = event->window; + + switch(event->type) + { + case EnterNotify: + PostMessage( hwnd, WM_SETCURSOR, hwnd, 0 ); + break; + } } @@ -297,9 +604,15 @@ HWND SetCapture(HWND wnd) if (wnd_p == NULL) return 0; +#ifdef USE_XLIB + rv = XGrabPointer(XT_display, wnd_p->window, False, + ButtonPressMask | ButtonReleaseMask | ButtonMotionMask, + GrabModeAsync, GrabModeSync, None, None, CurrentTime); +#else rv = XtGrabPointer(wnd_p->winWidget, False, ButtonPressMask | ButtonReleaseMask | ButtonMotionMask, GrabModeAsync, GrabModeSync, None, None, CurrentTime); +#endif if (rv == GrabSuccess) { @@ -324,11 +637,23 @@ void ReleaseCapture() if (wnd_p == NULL) return; +#ifdef USE_XLIB + XUngrabPointer( XT_display, CurrentTime ); +#else XtUngrabPointer(wnd_p->winWidget, CurrentTime); +#endif captureWnd = 0; } +/********************************************************************** + * GetCapture (USER.236) + */ +HWND GetCapture() +{ + return captureWnd; +} + /********************************************************************** * SetDoubleClickTime (USER.20) */ diff --git a/windows/focus.c b/windows/focus.c index ce1a91a25ff..639b2dfd85a 100644 --- a/windows/focus.c +++ b/windows/focus.c @@ -32,7 +32,7 @@ HWND SetFocus(HWND hwnd) else { wndPtr = WIN_FindWndPtr(hwnd); - XSetInputFocus(XT_display, XtWindow(wndPtr->winWidget), + XSetInputFocus(XT_display, wndPtr->window, RevertToParent, CurrentTime); } diff --git a/windows/graphics.c b/windows/graphics.c index a2a1e3254d6..9fd5d27a55f 100644 --- a/windows/graphics.c +++ b/windows/graphics.c @@ -23,8 +23,10 @@ BOOL LineTo( HDC hdc, short x, short y ) if (!dc) return FALSE; if (DC_SetupGCForPen( dc )) XDrawLine(XT_display, dc->u.x.drawable, dc->u.x.gc, - XLPTODP( dc, dc->w.CursPosX ), YLPTODP( dc, dc->w.CursPosY ), - XLPTODP( dc, x ), YLPTODP( dc, y ) ); + dc->w.DCOrgX + XLPTODP( dc, dc->w.CursPosX ), + dc->w.DCOrgY + YLPTODP( dc, dc->w.CursPosY ), + dc->w.DCOrgX + XLPTODP( dc, x ), + dc->w.DCOrgY + YLPTODP( dc, y ) ); dc->w.CursPosX = x; dc->w.CursPosY = y; return TRUE; @@ -97,20 +99,21 @@ BOOL GRAPH_DrawArc( HDC hdc, int left, int top, int right, int bottom, if (diff_angle < 0.0) diff_angle += 2*PI; XDrawArc( XT_display, dc->u.x.drawable, dc->u.x.gc, - left, top, right-left-1, bottom-top-1, + dc->w.DCOrgX + left, dc->w.DCOrgY + top, + right-left-1, bottom-top-1, (int)(start_angle * 180 * 64 / PI), (int)(diff_angle * 180 * 64 / PI) ); if (!lines) return TRUE; - points[0].x = xcenter + (int)(cos(start_angle) * (right-left) / 2); - points[0].y = ycenter - (int)(sin(start_angle) * (bottom-top) / 2); - points[1].x = xcenter + (int)(cos(end_angle) * (right-left) / 2); - points[1].y = ycenter - (int)(sin(end_angle) * (bottom-top) / 2); + points[0].x = dc->w.DCOrgX + xcenter + (int)(cos(start_angle) * (right-left) / 2); + points[0].y = dc->w.DCOrgY + ycenter - (int)(sin(start_angle) * (bottom-top) / 2); + points[1].x = dc->w.DCOrgX + xcenter + (int)(cos(end_angle) * (right-left) / 2); + points[1].y = dc->w.DCOrgY + ycenter - (int)(sin(end_angle) * (bottom-top) / 2); if (lines == 2) { points[2] = points[1]; - points[1].x = xcenter; - points[1].y = ycenter; + points[1].x = dc->w.DCOrgX + xcenter; + points[1].y = dc->w.DCOrgY + ycenter; } XDrawLines( XT_display, dc->u.x.drawable, dc->u.x.gc, points, lines+1, CoordModeOrigin ); @@ -167,10 +170,12 @@ BOOL Ellipse( HDC hdc, int left, int top, int right, int bottom ) if (DC_SetupGCForBrush( dc )) XFillArc( XT_display, dc->u.x.drawable, dc->u.x.gc, - left, top, right-left-1, bottom-top-1, 0, 360*64 ); + dc->w.DCOrgX + left, dc->w.DCOrgY + top, + right-left-1, bottom-top-1, 0, 360*64 ); if (DC_SetupGCForPen( dc )) XDrawArc( XT_display, dc->u.x.drawable, dc->u.x.gc, - left, top, right-left-1, bottom-top-1, 0, 360*64 ); + dc->w.DCOrgX + left, dc->w.DCOrgY + top, + right-left-1, bottom-top-1, 0, 360*64 ); return TRUE; } @@ -190,10 +195,12 @@ BOOL Rectangle( HDC hdc, int left, int top, int right, int bottom ) if (DC_SetupGCForBrush( dc )) XFillRectangle( XT_display, dc->u.x.drawable, dc->u.x.gc, - left, top, right-left-1, bottom-top-1 ); + dc->w.DCOrgX + left, dc->w.DCOrgY + top, + right-left-1, bottom-top-1 ); if (DC_SetupGCForPen( dc )) XDrawRectangle( XT_display, dc->u.x.drawable, dc->u.x.gc, - left, top, right-left-1, bottom-top-1 ); + dc->w.DCOrgX + left, dc->w.DCOrgY + top, + right-left-1, bottom-top-1 ); return TRUE; } @@ -244,10 +251,16 @@ int FrameRect( HDC hdc, LPRECT rect, HBRUSH hbrush ) right = XLPTODP( dc, rect->right ); bottom = YLPTODP( dc, rect->bottom ); - if (DC_SetupGCForBrush( dc )) - XDrawRectangle( XT_display, dc->u.x.drawable, dc->u.x.gc, - left, top, right-left-1, bottom-top-1 ); - + if (DC_SetupGCForBrush( dc )) { + PatBlt( hdc, rect->left, rect->top, 1, + rect->bottom - rect->top, PATCOPY ); + PatBlt( hdc, rect->right - 1, rect->top, 1, + rect->bottom - rect->top, PATCOPY ); + PatBlt( hdc, rect->left, rect->top, + rect->right - rect->left, 1, PATCOPY ); + PatBlt( hdc, rect->left, rect->bottom - 1, + rect->right - rect->left, 1, PATCOPY ); + } SelectObject( hdc, prevBrush ); return 1; } @@ -264,8 +277,8 @@ COLORREF SetPixel( HDC hdc, short x, short y, COLORREF color ) DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ); if (!dc) return 0; - x = XLPTODP( dc, x ); - y = YLPTODP( dc, y ); + x = dc->w.DCOrgX + XLPTODP( dc, x ); + y = dc->w.DCOrgY + YLPTODP( dc, y ); pixel = GetNearestPaletteIndex( dc->w.hPalette, color ); GetPaletteEntries( dc->w.hPalette, pixel, 1, &entry ); @@ -288,15 +301,14 @@ COLORREF GetPixel( HDC hdc, short x, short y ) DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ); if (!dc) return 0; - x = XLPTODP( dc, x ); - y = YLPTODP( dc, y ); + x = dc->w.DCOrgX + XLPTODP( dc, x ); + y = dc->w.DCOrgY + YLPTODP( dc, y ); if ((x < 0) || (y < 0)) return 0; - if (dc->u.x.widget) + if (!(dc->w.flags & DC_MEMORY)) { XWindowAttributes win_attr; - if (!XtIsRealized(dc->u.x.widget)) return 0; if (!XGetWindowAttributes( XT_display, dc->u.x.drawable, &win_attr )) return 0; if (win_attr.map_state != IsViewable) return 0; @@ -342,7 +354,7 @@ BOOL PaintRgn( HDC hdc, HRGN hrgn ) GetClipBox( hdc, &box ); if (DC_SetupGCForBrush( dc )) XFillRectangle( XT_display, dc->u.x.drawable, dc->u.x.gc, - box.left, box.top, + dc->w.DCOrgX + box.left, dc->w.DCOrgY + box.top, box.right-box.left, box.bottom-box.top ); /* Restore the visible region */ @@ -385,15 +397,16 @@ void DrawFocusRect( HDC hdc, LPRECT rc ) hPen = CreatePen(PS_DOT, 1, GetSysColor(COLOR_WINDOWTEXT)); hOldPen = (HPEN)SelectObject(hdc, (HANDLE)hPen); -/* oldDrawMode = SetROP2(hdc, R2_XORPEN); */ + oldDrawMode = SetROP2(hdc, R2_XORPEN); oldBkMode = SetBkMode(hdc, TRANSPARENT); if (DC_SetupGCForPen( dc )) XDrawRectangle( XT_display, dc->u.x.drawable, dc->u.x.gc, - left, top, right-left-1, bottom-top-1 ); + dc->w.DCOrgX + left, dc->w.DCOrgY + top, + right-left-1, bottom-top-1 ); SetBkMode(hdc, oldBkMode); -/* SetROP2(hdc, oldDrawMode); */ + SetROP2(hdc, oldDrawMode); SelectObject(hdc, (HANDLE)hOldPen); DeleteObject((HANDLE)hPen); } @@ -441,3 +454,64 @@ while(ThickNess > 0) { SelectObject(hDC, hOldPen); DeleteObject(hDKGRAYPen); } + +/********************************************************************** + * Polyline (GDI.37) + */ +BOOL Polyline (HDC hdc, LPPOINT pt, int count) +{ + register int i; + DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ); + + if (DC_SetupGCForPen( dc )) + { + for (i = 0; i < count-1; i ++) + XDrawLine (XT_display, dc->u.x.drawable, dc->u.x.gc, + dc->w.DCOrgX + XLPTODP(dc, pt [i].x), + dc->w.DCOrgY + YLPTODP(dc, pt [i].y), + dc->w.DCOrgX + XLPTODP(dc, pt [i+1].x), + dc->w.DCOrgY + YLPTODP(dc, pt [i+1].y)); + XDrawLine (XT_display, dc->u.x.drawable, dc->u.x.gc, + dc->w.DCOrgX + XLPTODP(dc, pt [count-1].x), + dc->w.DCOrgY + YLPTODP(dc, pt [count-1].y), + dc->w.DCOrgX + XLPTODP(dc, pt [0].x), + dc->w.DCOrgY + YLPTODP(dc, pt [0].y)); + } + + return (TRUE); +} + + +/********************************************************************** + * Polygon (GDI.36) + */ +BOOL Polygon (HDC hdc, LPPOINT pt, int count) +{ + register int i; + DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ); + XPoint *points = (XPoint *) malloc (sizeof (XPoint) * count+1); + + if (DC_SetupGCForBrush( dc )) + { + + for (i = 0; i < count; i++) + { + points [i].x = dc->w.DCOrgX + XLPTODP(dc, pt [i].x); + points [i].y = dc->w.DCOrgY + YLPTODP(dc, pt [i].y); + } + points [count] = points [0]; + + XFillPolygon( XT_display, dc->u.x.drawable, dc->u.x.gc, + points, count, Complex, CoordModeOrigin); + + if (DC_SetupGCForPen ( dc )) + { + XDrawLines( XT_display, dc->u.x.drawable, dc->u.x.gc, + points, count, CoordModeOrigin ); + } + } + free ((void *) points); + return (TRUE); +} + + diff --git a/windows/message.c b/windows/message.c index 7307461d99d..09b49e7861c 100644 --- a/windows/message.c +++ b/windows/message.c @@ -12,10 +12,8 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; #include - -#ifdef __NetBSD__ -#define HZ 100 -#endif +#include +#include #include "message.h" #include "win.h" @@ -23,30 +21,72 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; #define MAX_QUEUE_SIZE 120 /* Max. size of a message queue */ -extern HWND WIN_FindWinToRepaint( HWND hwnd ); +extern BOOL TIMER_CheckTimer( DWORD *next ); /* timer.c */ extern Display * XT_display; extern Screen * XT_screen; extern XtAppContext XT_app_context; -static MESSAGEQUEUE * msgQueue = NULL; + /* System message queue (for hardware events) */ +static HANDLE hmemSysMsgQueue = 0; +static MESSAGEQUEUE * sysMsgQueue = NULL; + + /* Application message queue (should be a list, one queue per task) */ +static HANDLE hmemAppMsgQueue = 0; +static MESSAGEQUEUE * appMsgQueue = NULL; + +/*********************************************************************** + * MSG_CreateMsgQueue + * + * Create a message queue. + */ +static HANDLE MSG_CreateMsgQueue( int size ) +{ + HANDLE hQueue; + MESSAGEQUEUE * msgQueue; + int queueSize; + + queueSize = sizeof(MESSAGEQUEUE) + size * sizeof(QMSG); + if (!(hQueue = GlobalAlloc( GMEM_FIXED, queueSize ))) return 0; + msgQueue = (MESSAGEQUEUE *) GlobalLock( hQueue ); + msgQueue->next = 0; + msgQueue->hTask = 0; + msgQueue->msgSize = sizeof(QMSG); + msgQueue->msgCount = 0; + msgQueue->nextMessage = 0; + msgQueue->nextFreeMessage = 0; + msgQueue->queueSize = size; + msgQueue->GetMessageTimeVal = 0; + msgQueue->GetMessagePosVal = 0; + msgQueue->GetMessageExtraInfoVal = 0; + msgQueue->lParam = 0; + msgQueue->wParam = 0; + msgQueue->msg = 0; + msgQueue->hWnd = 0; + msgQueue->wPostQMsg = 0; + msgQueue->wExitCode = 0; + msgQueue->InSendMessageHandle = 0; + msgQueue->wPaintCount = 0; + msgQueue->wTimerCount = 0; + msgQueue->tempStatus = 0; + msgQueue->status = 0; + GlobalUnlock( hQueue ); + return hQueue; +} /*********************************************************************** - * MSG_GetMessageType + * MSG_CreateSysMsgQueue * + * Create the system message queue. Must be called only once. */ -int MSG_GetMessageType( int msg ) +BOOL MSG_CreateSysMsgQueue( int size ) { - if ((msg >= WM_KEYFIRST) && (msg <= WM_KEYLAST)) return QS_KEY; - else if ((msg >= WM_MOUSEFIRST) && (msg <= WM_MOUSELAST)) - { - if (msg == WM_MOUSEMOVE) return QS_MOUSEMOVE; - else return QS_MOUSEBUTTON; - } - else if (msg == WM_PAINT) return QS_PAINT; - else if (msg == WM_TIMER) return QS_TIMER; - return QS_POSTMESSAGE; + if (size > MAX_QUEUE_SIZE) size = MAX_QUEUE_SIZE; + else if (size <= 0) size = 1; + if (!(hmemSysMsgQueue = MSG_CreateMsgQueue( size ))) return FALSE; + sysMsgQueue = (MESSAGEQUEUE *) GlobalLock( hmemSysMsgQueue ); + return TRUE; } @@ -55,16 +95,13 @@ int MSG_GetMessageType( int msg ) * * Add a message to the queue. Return FALSE if queue is full. */ -int MSG_AddMsg( MSG * msg, DWORD extraInfo ) +static int MSG_AddMsg( MESSAGEQUEUE * msgQueue, MSG * msg, DWORD extraInfo ) { - int pos, type; + int pos; if (!msgQueue) return FALSE; pos = msgQueue->nextFreeMessage; - /* No need to store WM_PAINT messages */ - if (msg->message == WM_PAINT) return TRUE; - /* Check if queue is full */ if ((pos == msgQueue->nextMessage) && (msgQueue->msgCount > 0)) return FALSE; @@ -72,17 +109,12 @@ int MSG_AddMsg( MSG * msg, DWORD extraInfo ) /* Store message */ msgQueue->messages[pos].msg = *msg; msgQueue->messages[pos].extraInfo = extraInfo; - - /* Store message type */ - type = MSG_GetMessageType( msg->message ); - msgQueue->status |= type; - msgQueue->tempStatus |= type; - if (pos < msgQueue->queueSize-1) pos++; else pos = 0; msgQueue->nextFreeMessage = pos; msgQueue->msgCount++; - + msgQueue->status |= QS_POSTMESSAGE; + msgQueue->tempStatus |= QS_POSTMESSAGE; return TRUE; } @@ -92,7 +124,7 @@ int MSG_AddMsg( MSG * msg, DWORD extraInfo ) * * Find a message matching the given parameters. Return -1 if none available. */ -int MSG_FindMsg( HWND hwnd, int first, int last ) +static int MSG_FindMsg(MESSAGEQUEUE * msgQueue, HWND hwnd, int first, int last) { int i, pos = msgQueue->nextMessage; @@ -120,9 +152,8 @@ int MSG_FindMsg( HWND hwnd, int first, int last ) * * Remove a message from the queue (pos must be a valid position). */ -void MSG_RemoveMsg( int pos ) +static void MSG_RemoveMsg( MESSAGEQUEUE * msgQueue, int pos ) { - int i, type; QMSG * qmsg; if (!msgQueue) return; @@ -147,56 +178,118 @@ void MSG_RemoveMsg( int pos ) else msgQueue->nextFreeMessage = msgQueue->queueSize-1; } msgQueue->msgCount--; - - /* Recalc status */ - type = 0; - pos = msgQueue->nextMessage; - for (i = 0; i < msgQueue->msgCount; i++) - { - type |= MSG_GetMessageType( msgQueue->messages[pos].msg.message ); - if (++pos >= msgQueue->queueSize-1) pos = 0; - } - msgQueue->status = (msgQueue->status & QS_SENDMESSAGE) | type; + if (!msgQueue->msgCount) msgQueue->status &= ~QS_POSTMESSAGE; msgQueue->tempStatus = 0; } +/*********************************************************************** + * MSG_IncPaintCount + */ +void MSG_IncPaintCount( HANDLE hQueue ) +{ + if (hQueue != hmemAppMsgQueue) return; + appMsgQueue->wPaintCount++; + appMsgQueue->status |= QS_PAINT; + appMsgQueue->tempStatus |= QS_PAINT; +} + + +/*********************************************************************** + * MSG_DecPaintCount + */ +void MSG_DecPaintCount( HANDLE hQueue ) +{ + if (hQueue != hmemAppMsgQueue) return; + appMsgQueue->wPaintCount--; + if (!appMsgQueue->wPaintCount) appMsgQueue->status &= ~QS_PAINT; +} + + +/*********************************************************************** + * MSG_IncTimerCount + */ +void MSG_IncTimerCount( HANDLE hQueue ) +{ + if (hQueue != hmemAppMsgQueue) return; + appMsgQueue->wTimerCount++; + appMsgQueue->status |= QS_TIMER; + appMsgQueue->tempStatus |= QS_TIMER; +} + + +/*********************************************************************** + * MSG_DecTimerCount + */ +void MSG_DecTimerCount( HANDLE hQueue ) +{ + if (hQueue != hmemAppMsgQueue) return; + appMsgQueue->wTimerCount--; + if (!appMsgQueue->wTimerCount) appMsgQueue->status &= ~QS_TIMER; +} + + +/*********************************************************************** + * hardware_event + * + * Add an event to the system message queue. + */ +void hardware_event( HWND hwnd, WORD message, WORD wParam, LONG lParam, + WORD xPos, WORD yPos, DWORD time, DWORD extraInfo ) +{ + MSG msg; + + msg.hwnd = hwnd; + msg.message = message; + msg.wParam = wParam; + msg.lParam = lParam; + msg.time = time; + msg.pt.x = xPos; + msg.pt.y = yPos; + if (!MSG_AddMsg( sysMsgQueue, &msg, extraInfo )) + printf( "hardware_event: Queue is full\n" ); +} + + +/*********************************************************************** + * SetTaskQueue (KERNEL.34) + */ +WORD SetTaskQueue( HANDLE hTask, HANDLE hQueue ) +{ + HANDLE prev = hmemAppMsgQueue; + hmemAppMsgQueue = hQueue; + return prev; +} + + +/*********************************************************************** + * GetTaskQueue (KERNEL.35) + */ +WORD GetTaskQueue( HANDLE hTask ) +{ + return hmemAppMsgQueue; +} + + /*********************************************************************** * SetMessageQueue (USER.266) */ BOOL SetMessageQueue( int size ) { - int queueSize; - + HANDLE hQueue; + + if ((size > MAX_QUEUE_SIZE) || (size <= 0)) return TRUE; + /* Free the old message queue */ - if (msgQueue) free(msgQueue); + if ((hQueue = GetTaskQueue(0)) != 0) + { + GlobalUnlock( hQueue ); + GlobalFree( hQueue ); + } - if ((size > MAX_QUEUE_SIZE) || (size <= 0)) return FALSE; - - queueSize = sizeof(MESSAGEQUEUE) + size * sizeof(QMSG); - msgQueue = (MESSAGEQUEUE *) malloc(queueSize); - if (!msgQueue) return FALSE; - - msgQueue->next = 0; - msgQueue->hTask = 0; - msgQueue->msgSize = sizeof(QMSG); - msgQueue->msgCount = 0; - msgQueue->nextMessage = 0; - msgQueue->nextFreeMessage = 0; - msgQueue->queueSize = size; - msgQueue->GetMessageTimeVal = 0; - msgQueue->GetMessagePosVal = 0; - msgQueue->GetMessageExtraInfoVal = 0; - msgQueue->lParam = 0; - msgQueue->wParam = 0; - msgQueue->msg = 0; - msgQueue->hWnd = 0; - msgQueue->wPostQMsg = 0; - msgQueue->wExitCode = 0; - msgQueue->InSendMessageHandle = 0; - msgQueue->tempStatus = 0; - msgQueue->status = 0; - + if (!(hQueue = MSG_CreateMsgQueue( size ))) return FALSE; + SetTaskQueue( 0, hQueue ); + appMsgQueue = (MESSAGEQUEUE *)GlobalLock( hQueue ); return TRUE; } @@ -206,9 +299,9 @@ BOOL SetMessageQueue( int size ) */ void PostQuitMessage( int exitCode ) { - if (!msgQueue) return; - msgQueue->wPostQMsg = TRUE; - msgQueue->wExitCode = exitCode; + if (!appMsgQueue) return; + appMsgQueue->wPostQMsg = TRUE; + appMsgQueue->wExitCode = exitCode; } @@ -217,12 +310,8 @@ void PostQuitMessage( int exitCode ) */ DWORD GetQueueStatus( int flags ) { - unsigned long ret = (msgQueue->status << 16) | msgQueue->tempStatus; - if (flags & QS_PAINT) - { - if (WIN_FindWinToRepaint(0)) ret |= QS_PAINT | (QS_PAINT << 16); - } - msgQueue->tempStatus = 0; + unsigned long ret = (appMsgQueue->status << 16) | appMsgQueue->tempStatus; + appMsgQueue->tempStatus = 0; return ret & ((flags << 16) | flags); } @@ -232,70 +321,169 @@ DWORD GetQueueStatus( int flags ) */ BOOL GetInputState() { - return msgQueue->status & (QS_KEY | QS_MOUSEBUTTON); + return appMsgQueue->status & (QS_KEY | QS_MOUSEBUTTON); } +#ifndef USE_XLIB +static XtIntervalId xt_timer = 0; + +/*********************************************************************** + * MSG_TimerCallback + */ +static void MSG_TimerCallback( XtPointer data, XtIntervalId * xtid ) +{ + DWORD nextExp; + TIMER_CheckTimer( &nextExp ); + if (nextExp != (DWORD)-1) + xt_timer = XtAppAddTimeOut( XT_app_context, nextExp, + MSG_TimerCallback, NULL ); + else xt_timer = 0; +} +#endif /* USE_XLIB */ + + /*********************************************************************** * MSG_PeekMessage */ -BOOL MSG_PeekMessage( LPMSG msg, HWND hwnd, WORD first, WORD last, WORD flags ) +static BOOL MSG_PeekMessage( MESSAGEQUEUE * msgQueue, LPMSG msg, HWND hwnd, + WORD first, WORD last, WORD flags, BOOL peek ) { - int pos; + int pos, mask; + DWORD nextExp; /* Next timer expiration time */ +#ifdef USE_XLIB + XEvent event; +#endif - /* First handle a WM_QUIT message */ - if (msgQueue->wPostQMsg) + if (first || last) { - msg->hwnd = hwnd; - msg->message = WM_QUIT; - msg->wParam = msgQueue->wExitCode; - msg->lParam = 0; - return TRUE; + mask = QS_POSTMESSAGE; /* Always selectioned */ + if ((first <= WM_KEYLAST) && (last >= WM_KEYFIRST)) mask |= QS_KEY; + if ((first <= WM_MOUSELAST) && (last >= WM_MOUSEFIRST)) mask |= QS_MOUSE; + if ((first <= WM_TIMER) && (last >= WM_TIMER)) mask |= WM_TIMER; + if ((first <= WM_SYSTIMER) && (last >= WM_SYSTIMER)) mask |= WM_TIMER; + if ((first <= WM_PAINT) && (last >= WM_PAINT)) mask |= WM_PAINT; } + else mask = QS_MOUSE | QS_KEY | QS_POSTMESSAGE | QS_TIMER | QS_PAINT; - /* Then handle a message put by SendMessage() */ - if (msgQueue->status & QS_SENDMESSAGE) +#ifdef USE_XLIB + while (XPending( XT_display )) { - if (!hwnd || (msgQueue->hWnd == hwnd)) + XNextEvent( XT_display, &event ); + EVENT_ProcessEvent( &event ); + } +#else + while (XtAppPending( XT_app_context )) + XtAppProcessEvent( XT_app_context, XtIMAll ); +#endif + + while(1) + { + /* First handle a WM_QUIT message */ + if (msgQueue->wPostQMsg) { - if ((!first && !last) || - ((msgQueue->msg >= first) && (msgQueue->msg <= last))) + msg->hwnd = hwnd; + msg->message = WM_QUIT; + msg->wParam = msgQueue->wExitCode; + msg->lParam = 0; + break; + } + + /* Then handle a message put by SendMessage() */ + if (msgQueue->status & QS_SENDMESSAGE) + { + if (!hwnd || (msgQueue->hWnd == hwnd)) { - msg->hwnd = msgQueue->hWnd; - msg->message = msgQueue->msg; - msg->wParam = msgQueue->wParam; - msg->lParam = msgQueue->lParam; - if (flags & PM_REMOVE) msgQueue->status &= ~QS_SENDMESSAGE; - return TRUE; + if ((!first && !last) || + ((msgQueue->msg >= first) && (msgQueue->msg <= last))) + { + msg->hwnd = msgQueue->hWnd; + msg->message = msgQueue->msg; + msg->wParam = msgQueue->wParam; + msg->lParam = msgQueue->lParam; + if (flags & PM_REMOVE) msgQueue->status &= ~QS_SENDMESSAGE; + break; + } } } - - } - /* Now find a normal message */ - pos = MSG_FindMsg( hwnd, first, last ); - if (pos != -1) - { - QMSG *qmsg = &msgQueue->messages[pos]; - *msg = qmsg->msg; - msgQueue->GetMessageTimeVal = msg->time; - msgQueue->GetMessagePosVal = *(DWORD *)&msg->pt; - msgQueue->GetMessageExtraInfoVal = qmsg->extraInfo; + /* Now find a normal message */ + pos = MSG_FindMsg( msgQueue, hwnd, first, last ); + if (pos != -1) + { + QMSG *qmsg = &msgQueue->messages[pos]; + *msg = qmsg->msg; + msgQueue->GetMessageTimeVal = msg->time; + msgQueue->GetMessagePosVal = *(DWORD *)&msg->pt; + msgQueue->GetMessageExtraInfoVal = qmsg->extraInfo; - if (flags & PM_REMOVE) MSG_RemoveMsg(pos); - return TRUE; + if (flags & PM_REMOVE) MSG_RemoveMsg( msgQueue, pos ); + break; + } + + /* Now find a hardware event */ + pos = MSG_FindMsg( sysMsgQueue, hwnd, first, last ); + if (pos != -1) + { + QMSG *qmsg = &sysMsgQueue->messages[pos]; + *msg = qmsg->msg; + msgQueue->GetMessageTimeVal = msg->time; + msgQueue->GetMessagePosVal = *(DWORD *)&msg->pt; + msgQueue->GetMessageExtraInfoVal = qmsg->extraInfo; + + if (flags & PM_REMOVE) MSG_RemoveMsg( sysMsgQueue, pos ); + break; + } + + /* Now find a WM_PAINT message */ + if ((msgQueue->status & QS_PAINT) && (mask & QS_PAINT)) + { + msg->hwnd = WIN_FindWinToRepaint( hwnd ); + msg->message = WM_PAINT; + msg->wParam = 0; + msg->lParam = 0; + if (msg->hwnd != 0) break; + } + + /* Finally handle WM_TIMER messages */ + if ((msgQueue->status & QS_TIMER) && (mask & QS_TIMER)) + { + BOOL posted = TIMER_CheckTimer( &nextExp ); +#ifndef USE_XLIB + if (xt_timer) XtRemoveTimeOut( xt_timer ); + if (nextExp != (DWORD)-1) + xt_timer = XtAppAddTimeOut( XT_app_context, nextExp, + MSG_TimerCallback, NULL ); + else xt_timer = 0; +#endif + if (posted) continue; /* Restart the whole thing */ + } + + /* Wait until something happens */ + if (peek) return FALSE; +#ifdef USE_XLIB + if (!XPending( XT_display ) && (nextExp != -1)) + { + fd_set read_set; + struct timeval timeout; + int fd = ConnectionNumber(XT_display); + FD_ZERO( &read_set ); + FD_SET( fd, &read_set ); + timeout.tv_sec = nextExp / 1000; + timeout.tv_usec = (nextExp % 1000) * 1000; + if (select( fd+1, &read_set, NULL, NULL, &timeout ) != 1) + continue; /* On timeout or error, restart from the start */ + } + XNextEvent( XT_display, &event ); + EVENT_ProcessEvent( &event ); +#else + XtAppProcessEvent( XT_app_context, XtIMAll ); +#endif } - /* If nothing else, return a WM_PAINT message */ - if ((!first && !last) || ((first <= WM_PAINT) && (last >= WM_PAINT))) - { - msg->hwnd = WIN_FindWinToRepaint( hwnd ); - msg->message = WM_PAINT; - msg->wParam = 0; - msg->lParam = 0; - return (msg->hwnd != 0); - } - return FALSE; + /* We got a message */ + if (peek) return TRUE; + else return (msg->message != WM_QUIT); } @@ -304,10 +492,7 @@ BOOL MSG_PeekMessage( LPMSG msg, HWND hwnd, WORD first, WORD last, WORD flags ) */ BOOL PeekMessage( LPMSG msg, HWND hwnd, WORD first, WORD last, WORD flags ) { - while (XtAppPending( XT_app_context )) - XtAppProcessEvent( XT_app_context, XtIMAll ); - - return MSG_PeekMessage( msg, hwnd, first, last, flags ); + return MSG_PeekMessage( appMsgQueue, msg, hwnd, first, last, flags, TRUE ); } @@ -316,13 +501,7 @@ BOOL PeekMessage( LPMSG msg, HWND hwnd, WORD first, WORD last, WORD flags ) */ BOOL GetMessage( LPMSG msg, HWND hwnd, WORD first, WORD last ) { - while(1) - { - if (MSG_PeekMessage( msg, hwnd, first, last, PM_REMOVE )) break; - XtAppProcessEvent( XT_app_context, XtIMAll ); - } - - return (msg->message != WM_QUIT); + return MSG_PeekMessage( appMsgQueue, msg, hwnd, first, last, PM_REMOVE, FALSE ); } @@ -341,7 +520,7 @@ BOOL PostMessage( HWND hwnd, WORD message, WORD wParam, LONG lParam ) msg.pt.x = 0; msg.pt.y = 0; - return MSG_AddMsg( &msg, 0 ); + return MSG_AddMsg( appMsgQueue, &msg, 0 ); } @@ -380,16 +559,39 @@ BOOL TranslateMessage( LPMSG msg ) */ LONG DispatchMessage( LPMSG msg ) { - WND * wndPtr = WIN_FindWndPtr( msg->hwnd ); - + WND * wndPtr; + LONG retval; + int painting; + #ifdef DEBUG_MSG printf( "Dispatch message hwnd=%08x msg=%d w=%d l=%d time=%u pt=%d,%d\n", msg->hwnd, msg->message, msg->wParam, msg->lParam, msg->time, msg->pt.x, msg->pt.y ); #endif - if (!wndPtr) return 0; - return CallWindowProc( wndPtr->lpfnWndProc, msg->hwnd, msg->message, - msg->wParam, msg->lParam ); + + /* Process timer messages */ + if ((msg->message == WM_TIMER) || (msg->message == WM_SYSTIMER)) + { + if (msg->lParam) + return CallWindowProc( (FARPROC)msg->lParam, msg->hwnd, + msg->message, msg->wParam, GetTickCount() ); + } + + if (!msg->hwnd) return 0; + if (!(wndPtr = WIN_FindWndPtr( msg->hwnd ))) return 0; + if (!wndPtr->lpfnWndProc) return 0; + painting = (msg->message == WM_PAINT); + if (painting) wndPtr->flags |= WIN_NEEDS_BEGINPAINT; + retval = CallWindowProc( wndPtr->lpfnWndProc, msg->hwnd, msg->message, + msg->wParam, msg->lParam ); + if (painting && (wndPtr->flags & WIN_NEEDS_BEGINPAINT)) + { +#ifdef DEBUG_WIN + printf( "BeginPaint not called on WM_PAINT!\n" ); +#endif + wndPtr->flags &= ~WIN_NEEDS_BEGINPAINT; + } + return retval; } @@ -398,7 +600,7 @@ LONG DispatchMessage( LPMSG msg ) */ DWORD GetMessagePos(void) { - return msgQueue->GetMessagePosVal; + return appMsgQueue->GetMessagePosVal; } @@ -407,14 +609,27 @@ DWORD GetMessagePos(void) */ LONG GetMessageTime(void) { - return msgQueue->GetMessageTimeVal; + return appMsgQueue->GetMessageTimeVal; } + /*********************************************************************** * GetMessageExtraInfo (USER.288) */ LONG GetMessageExtraInfo(void) { - return msgQueue->GetMessageExtraInfoVal; + return appMsgQueue->GetMessageExtraInfoVal; +} + + +/*********************************************************************** + * RegisterWindowMessage (USER.118) + */ +WORD RegisterWindowMessage( LPCSTR str ) +{ +#ifdef DEBUG_MSG + printf( "RegisterWindowMessage: '%s'\n", str ); +#endif + return GlobalAddAtom( str ); } diff --git a/windows/painting.c b/windows/painting.c index 4f21b13b0a5..5a8e60a0e11 100644 --- a/windows/painting.c +++ b/windows/painting.c @@ -10,6 +10,7 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; #include #include "win.h" +#include "message.h" /* Last CTLCOLOR id */ #define CTLCOLOR_MAX CTLCOLOR_STATIC @@ -23,27 +24,21 @@ HDC BeginPaint( HWND hwnd, LPPAINTSTRUCT lps ) WND * wndPtr = WIN_FindWndPtr( hwnd ); if (!wndPtr) return 0; - lps->hdc = GetDC( hwnd ); - if (!lps->hdc) return 0; - - SelectVisRgn( lps->hdc, wndPtr->hrgnUpdate ); + if (!(lps->hdc = GetDCEx( hwnd, wndPtr->hrgnUpdate, + DCX_INTERSECTRGN | DCX_USESTYLE ))) return 0; + GetRgnBox( InquireVisRgn(lps->hdc), &lps->rcPaint ); + if (wndPtr->hrgnUpdate) { - GetRgnBox( wndPtr->hrgnUpdate, &lps->rcPaint ); DeleteObject( wndPtr->hrgnUpdate ); wndPtr->hrgnUpdate = 0; + MSG_DecPaintCount( wndPtr->hmemTaskQ ); } - else - { - lps->rcPaint.left = 0; - lps->rcPaint.top = 0; - lps->rcPaint.right = wndPtr->rectClient.right-wndPtr->rectClient.left; - lps->rcPaint.bottom = wndPtr->rectClient.bottom-wndPtr->rectClient.top; - } - + wndPtr->flags &= ~WIN_NEEDS_BEGINPAINT; + if (!(wndPtr->flags & WIN_ERASE_UPDATERGN)) lps->fErase = TRUE; else lps->fErase = !SendMessage( hwnd, WM_ERASEBKGND, lps->hdc, 0 ); - + return lps->hdc; } @@ -63,12 +58,7 @@ void EndPaint( HWND hwnd, LPPAINTSTRUCT lps ) void FillWindow( HWND hwndParent, HWND hwnd, HDC hdc, HBRUSH hbrush ) { RECT rect; - WND * wndPtr = WIN_FindWndPtr( hwnd ); - if (!wndPtr) return; - rect.left = 0; - rect.top = 0; - rect.right = wndPtr->rectClient.right - wndPtr->rectClient.left; - rect.bottom = wndPtr->rectClient.bottom - wndPtr->rectClient.top; + GetClientRect( hwnd, &rect ); PaintRect( hwndParent, hwnd, hdc, hbrush, &rect ); } diff --git a/windows/timer.c b/windows/timer.c index 2aeb88ee585..da649610fd2 100644 --- a/windows/timer.c +++ b/windows/timer.c @@ -6,21 +6,19 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; -#include - #include "windows.h" - -extern XtAppContext XT_app_context; +#include "message.h" -typedef struct +typedef struct tagTIMER { - HWND hwnd; - WORD msg; /* WM_TIMER or WM_SYSTIMER */ - WORD id; - WORD timeout; - FARPROC proc; - XtIntervalId xtid; + HWND hwnd; + WORD msg; /* WM_TIMER or WM_SYSTIMER */ + WORD id; + WORD timeout; + struct tagTIMER *next; + DWORD expires; + FARPROC proc; } TIMER; #define NB_TIMERS 34 @@ -28,39 +26,100 @@ typedef struct static TIMER TimersArray[NB_TIMERS]; +static TIMER * pNextTimer = NULL; /* Next timer to expire */ + /*********************************************************************** - * TIMER_callback + * TIMER_InsertTimer + * + * Insert the timer at its place in the chain. */ -static void TIMER_callback( XtPointer data, XtIntervalId * xtid ) +static void TIMER_InsertTimer( TIMER * pTimer ) { - TIMER * pTimer = (TIMER *) data; - - pTimer->xtid = 0; /* In case the timer procedure calls KillTimer */ - - if (pTimer->proc) + if (!pNextTimer || (pTimer->expires < pNextTimer->expires)) { - CallWindowProc(pTimer->proc, pTimer->hwnd, pTimer->msg, - pTimer->id, GetTickCount()); + pTimer->next = pNextTimer; + pNextTimer = pTimer; } - else - PostMessage( pTimer->hwnd, pTimer->msg, pTimer->id, 0 ); + else + { + TIMER * ptr = pNextTimer; + while (ptr->next && (pTimer->expires >= ptr->next->expires)) + ptr = ptr->next; + pTimer->next = ptr; + ptr->next = pTimer; + } +} + + +/*********************************************************************** + * TIMER_RemoveTimer + * + * Remove the timer from the chain. + */ +static void TIMER_RemoveTimer( TIMER * pTimer ) +{ + if (pTimer == pNextTimer) pNextTimer = pTimer->next; + else + { + TIMER * ptr = pNextTimer; + while (ptr && (ptr->next != pTimer)) ptr = ptr->next; + if (ptr) ptr->next = pTimer->next; + } + pTimer->next = NULL; +} + + +/*********************************************************************** + * TIMER_NextExpire + * + * Return time until next timer expiration (-1 if none). + */ +static DWORD TIMER_NextExpire( DWORD curTime ) +{ + if (!pNextTimer) return -1; + if (pNextTimer->expires <= curTime) return 0; + return pNextTimer->expires - curTime; +} + + +/*********************************************************************** + * TIMER_CheckTimer + * + * Check whether a timer has expired, and post a message if necessary. + * Return TRUE if msg posted, and return time until next expiration in 'next'. + */ +BOOL TIMER_CheckTimer( DWORD *next ) +{ + TIMER * pTimer = pNextTimer; + DWORD curTime = GetTickCount(); + + if ((*next = TIMER_NextExpire( curTime )) != 0) return FALSE; + + PostMessage( pTimer->hwnd, pTimer->msg, pTimer->id, (LONG)pTimer->proc ); + TIMER_RemoveTimer( pTimer ); /* If timeout == 0, the timer has been removed by KillTimer */ if (pTimer->timeout) - pTimer->xtid = XtAppAddTimeOut( XT_app_context, pTimer->timeout, - TIMER_callback, pTimer ); + { + /* Restart the timer */ + pTimer->expires = curTime + pTimer->timeout; + TIMER_InsertTimer( pTimer ); + } + *next = TIMER_NextExpire( curTime ); + return TRUE; } /*********************************************************************** * TIMER_SetTimer */ -WORD TIMER_SetTimer( HWND hwnd, WORD id, WORD timeout, FARPROC proc, BOOL sys ) +static WORD TIMER_SetTimer( HWND hwnd, WORD id, WORD timeout, + FARPROC proc, BOOL sys ) { int i; TIMER * pTimer; - + if (!timeout) return 0; if (!hwnd && !proc) return 0; @@ -79,9 +138,10 @@ WORD TIMER_SetTimer( HWND hwnd, WORD id, WORD timeout, FARPROC proc, BOOL sys ) pTimer->msg = sys ? WM_SYSTIMER : WM_TIMER; pTimer->id = id; pTimer->timeout = timeout; + pTimer->expires = GetTickCount() + timeout; pTimer->proc = proc; - pTimer->xtid = XtAppAddTimeOut( XT_app_context, timeout, - TIMER_callback, pTimer ); + TIMER_InsertTimer( pTimer ); + MSG_IncTimerCount( GetTaskQueue(0) ); return id; } @@ -89,7 +149,7 @@ WORD TIMER_SetTimer( HWND hwnd, WORD id, WORD timeout, FARPROC proc, BOOL sys ) /*********************************************************************** * TIMER_KillTimer */ -BOOL TIMER_KillTimer( HWND hwnd, WORD id, BOOL sys ) +static BOOL TIMER_KillTimer( HWND hwnd, WORD id, BOOL sys ) { int i; TIMER * pTimer; @@ -106,13 +166,13 @@ BOOL TIMER_KillTimer( HWND hwnd, WORD id, BOOL sys ) /* Delete the timer */ - if (pTimer->xtid) XtRemoveTimeOut( pTimer->xtid ); pTimer->hwnd = 0; pTimer->msg = 0; pTimer->id = 0; pTimer->timeout = 0; pTimer->proc = 0; - pTimer->xtid = 0; + TIMER_RemoveTimer( pTimer ); + MSG_DecTimerCount( GetTaskQueue(0) ); return TRUE; } @@ -123,7 +183,7 @@ BOOL TIMER_KillTimer( HWND hwnd, WORD id, BOOL sys ) WORD SetTimer( HWND hwnd, WORD id, WORD timeout, FARPROC proc ) { #ifdef DEBUG_TIMER - printf( "SetTimer: %d %d %d %08x\n", hwnd, id, timeout, proc ); + printf( "SetTimer: %d %d %d %p\n", hwnd, id, timeout, proc ); #endif return TIMER_SetTimer( hwnd, id, timeout, proc, FALSE ); } @@ -135,7 +195,7 @@ WORD SetTimer( HWND hwnd, WORD id, WORD timeout, FARPROC proc ) WORD SetSystemTimer( HWND hwnd, WORD id, WORD timeout, FARPROC proc ) { #ifdef DEBUG_TIMER - printf( "SetSystemTimer: %d %d %d %08x\n", hwnd, id, timeout, proc ); + printf( "SetSystemTimer: %d %d %d %p\n", hwnd, id, timeout, proc ); #endif return TIMER_SetTimer( hwnd, id, timeout, proc, TRUE ); } diff --git a/windows/win.c b/windows/win.c index d7fe3a2c88e..8411e489860 100644 --- a/windows/win.c +++ b/windows/win.c @@ -10,11 +10,11 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; #include #include #include -#include #include "class.h" #include "win.h" #include "user.h" +#include "dce.h" extern Display * XT_display; extern Screen * XT_screen; @@ -22,10 +22,6 @@ extern Colormap COLOR_WinColormap; static HWND firstWindow = 0; -void SCROLLBAR_CreateScrollBar(LPSTR className, LPSTR Label, HWND hwnd); -void LISTBOX_CreateListBox(LPSTR className, LPSTR Label, HWND hwnd); -void COMBOBOX_CreateComboBox(LPSTR className, LPSTR Label, HWND hwnd); - /*********************************************************************** * WIN_FindWndPtr * @@ -42,6 +38,76 @@ WND * WIN_FindWndPtr( HWND hwnd ) } +/*********************************************************************** + * WIN_UnlinkWindow + * + * Remove a window from the siblings linked list. + */ +BOOL WIN_UnlinkWindow( HWND hwnd ) +{ + HWND * curWndPtr; + WND * wndPtr = WIN_FindWndPtr( hwnd ); + + if (!wndPtr) return FALSE; + if (wndPtr->hwndParent) + { + WND * parentPtr = WIN_FindWndPtr( wndPtr->hwndParent ); + curWndPtr = &parentPtr->hwndChild; + } + else curWndPtr = &firstWindow; + + while (*curWndPtr != hwnd) + { + WND * curPtr = WIN_FindWndPtr( *curWndPtr ); + curWndPtr = &curPtr->hwndNext; + } + *curWndPtr = wndPtr->hwndNext; + return TRUE; +} + + +/*********************************************************************** + * WIN_LinkWindow + * + * Insert a window into the siblings linked list. + * The window is inserted after the specified window, which can also + * be specified as HWND_TOP or HWND_BOTTOM. + */ +BOOL WIN_LinkWindow( HWND hwnd, HWND hwndInsertAfter ) +{ + HWND * hwndPtr = NULL; /* pointer to hwnd to change */ + + WND * wndPtr = WIN_FindWndPtr( hwnd ); + if (!wndPtr) return FALSE; + + if ((hwndInsertAfter == HWND_TOP) || (hwndInsertAfter == HWND_BOTTOM)) + { + /* Make hwndPtr point to the first sibling hwnd */ + if (wndPtr->hwndParent) + { + WND * parentPtr = WIN_FindWndPtr( wndPtr->hwndParent ); + if (parentPtr) hwndPtr = &parentPtr->hwndChild; + } + else hwndPtr = &firstWindow; + if (hwndInsertAfter == HWND_BOTTOM) /* Find last sibling hwnd */ + while (*hwndPtr) + { + WND * nextPtr = WIN_FindWndPtr( *hwndPtr ); + hwndPtr = &nextPtr->hwndNext; + } + } + else /* Normal case */ + { + WND * afterPtr = WIN_FindWndPtr( hwndInsertAfter ); + if (afterPtr) hwndPtr = &afterPtr->hwndNext; + } + if (!hwndPtr) return FALSE; + wndPtr->hwndNext = *hwndPtr; + *hwndPtr = hwnd; + return TRUE; +} + + /*********************************************************************** * WIN_FindWinToRepaint * @@ -55,8 +121,6 @@ HWND WIN_FindWinToRepaint( HWND hwnd ) for ( ; hwnd != 0; hwnd = wndPtr->hwndNext ) { if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0; - if (!wndPtr || !wndPtr->winWidget) continue; - if (!XtIsRealized( wndPtr->winWidget )) continue; if (wndPtr->hrgnUpdate) return hwnd; if (wndPtr->hwndChild) { @@ -114,9 +178,11 @@ HWND CreateWindowEx( DWORD exStyle, LPSTR className, LPSTR windowName, CREATESTRUCT *createStruct; HANDLE hcreateStruct; int wmcreate; + short newwidth, newheight; #ifdef DEBUG_WIN - printf( "CreateWindowEx: %s %s %d,%d %dx%d\n", className, windowName, x, y, width, height ); + printf( "CreateWindowEx: %s %s %d,%d %dx%d %08x\n", + className, windowName, x, y, width, height, style ); #endif if (x == CW_USEDEFAULT) x = 0; @@ -155,11 +221,12 @@ HWND CreateWindowEx( DWORD exStyle, LPSTR className, LPSTR windowName, wndPtr->hwndOwner = parent; /* What else? */ wndPtr->hClass = class; wndPtr->hInstance = instance; - wndPtr->rectClient.left = x; - wndPtr->rectClient.top = y; - wndPtr->rectClient.right = x + width; - wndPtr->rectClient.bottom = y + height; - wndPtr->rectWindow = wndPtr->rectClient; + wndPtr->rectWindow.left = x; + wndPtr->rectWindow.top = y; + wndPtr->rectWindow.right = x + width; + wndPtr->rectWindow.bottom = y + height; + wndPtr->rectClient = wndPtr->rectWindow; + wndPtr->hmemTaskQ = GetTaskQueue(0); wndPtr->hrgnUpdate = 0; wndPtr->hwndLastActive = 0; wndPtr->lpfnWndProc = classPtr->wc.lpfnWndProc; @@ -169,43 +236,70 @@ HWND CreateWindowEx( DWORD exStyle, LPSTR className, LPSTR windowName, wndPtr->wIDmenu = menu; wndPtr->hText = 0; wndPtr->flags = 0; + wndPtr->hCursor = 0; + wndPtr->hWndVScroll = 0; + wndPtr->hWndHScroll = 0; if (classPtr->wc.cbWndExtra) memset( wndPtr->wExtra, 0, classPtr->wc.cbWndExtra ); - if (classPtr->wc.style & CS_OWNDC) - wndPtr->hdc = CreateDC( "DISPLAY", NULL, NULL, NULL); - else wndPtr->hdc = 0; classPtr->cWindows++; + /* Get class or window DC if needed */ + if (classPtr->wc.style & CS_OWNDC) + { + wndPtr->flags |= WIN_OWN_DC; + wndPtr->hdce = DCE_AllocDCE( DCE_WINDOW_DC ); + } + else if (classPtr->wc.style & CS_CLASSDC) + { + wndPtr->flags |= WIN_CLASS_DC; + wndPtr->hdce = classPtr->hdce; + } + else wndPtr->hdce = 0; + /* Insert the window in the linked list */ - if (parent) - { - wndPtr->hwndNext = parentPtr->hwndChild; - parentPtr->hwndChild = hwnd; - } - else /* Top-level window */ - { - wndPtr->hwndNext = firstWindow; - firstWindow = hwnd; - } - - if (!strcasecmp(className, "SCROLLBAR")) - { - SCROLLBAR_CreateScrollBar(className, windowName, hwnd); - goto WinCreated; - } - if (!strcasecmp(className, "LISTBOX")) - { - LISTBOX_CreateListBox(className, windowName, hwnd); - goto WinCreated; - } + WIN_LinkWindow( hwnd, HWND_TOP ); + if (!strcasecmp(className, "COMBOBOX")) { - COMBOBOX_CreateComboBox(className, windowName, hwnd); - goto WinCreated; + height = 16; } - /* Create the widgets */ + +#ifdef USE_XLIB + { + XSetWindowAttributes win_attr; + Window parentWindow; + int x_rel, y_rel; + + win_attr.event_mask = ExposureMask | KeyPressMask | KeyReleaseMask | + PointerMotionMask | ButtonPressMask | + ButtonReleaseMask | StructureNotifyMask | + FocusChangeMask | EnterWindowMask; + win_attr.override_redirect = /*True*/ False; + win_attr.colormap = COLOR_WinColormap; + if (style & WS_CHILD) + { + parentWindow = parentPtr->window; + x_rel = x + parentPtr->rectClient.left-parentPtr->rectWindow.left; + y_rel = y + parentPtr->rectClient.top-parentPtr->rectWindow.top; + } + else + { + parentWindow = DefaultRootWindow( XT_display ); + x_rel = x; + y_rel = y; + } + wndPtr->window = XCreateWindow( XT_display, parentWindow, + x_rel, y_rel, width, height, 0, + CopyFromParent, InputOutput, + CopyFromParent, + CWEventMask | CWOverrideRedirect | + CWColormap, &win_attr ); + XStoreName( XT_display, wndPtr->window, windowName ); + } +#else + /* Create the widgets */ if (style & WS_CHILD) { @@ -223,6 +317,7 @@ HWND CreateWindowEx( DWORD exStyle, LPSTR className, LPSTR windowName, XtNwidth, width, XtNheight, height, XtNborderColor, borderCol, + XtNmappedWhenManaged, FALSE, NULL ); } else @@ -235,6 +330,7 @@ HWND CreateWindowEx( DWORD exStyle, LPSTR className, LPSTR windowName, XtNwidth, width, XtNheight, height, XtNborderWidth, 0, + XtNmappedWhenManaged, FALSE, NULL ); } } @@ -247,6 +343,7 @@ HWND CreateWindowEx( DWORD exStyle, LPSTR className, LPSTR windowName, XtNx, x, XtNy, y, XtNcolormap, COLOR_WinColormap, + XtNmappedWhenManaged, FALSE, NULL ); wndPtr->compositeWidget = XtVaCreateManagedWidget(className, formWidgetClass, @@ -296,8 +393,24 @@ HWND CreateWindowEx( DWORD exStyle, LPSTR className, LPSTR windowName, NULL ); } } + if (wndPtr->shellWidget) XtRealizeWidget( wndPtr->shellWidget ); + if (wndPtr->compositeWidget) XtRealizeWidget( wndPtr->compositeWidget ); + XtRealizeWidget( wndPtr->winWidget ); + wndPtr->window = XtWindow( wndPtr->winWidget ); +#endif /* USE_XLIB */ -WinCreated: + if ((style & WS_VSCROLL) == WS_VSCROLL) { + newheight = height - (((style & WS_HSCROLL) == WS_HSCROLL) ? 16 : 0); + wndPtr->hWndVScroll = CreateWindow("SCROLLBAR", "", + WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE | SBS_VERT, + width - 16, 0, 16, newheight, hwnd, 2, instance, 0L); + } + if ((style & WS_HSCROLL) == WS_HSCROLL) { + newwidth = width - (((style & WS_VSCROLL) == WS_VSCROLL) ? 16 : 0); + wndPtr->hWndHScroll = CreateWindow("SCROLLBAR", "", + WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE | SBS_HORZ, + 0, height - 16, newwidth, 16, hwnd, 3, instance, 0L); + } /* Send the WM_CREATE message */ @@ -318,7 +431,24 @@ WinCreated: wmcreate = SendMessage( hwnd, WM_NCCREATE, 0, (LONG)createStruct ); if (!wmcreate) wmcreate = -1; - else wmcreate = SendMessage( hwnd, WM_CREATE, 0, (LONG)createStruct ); + else + { + /* Send WM_NCCALCSIZE message */ + NCCALCSIZE_PARAMS *params; + HANDLE hparams; + hparams = GlobalAlloc( GMEM_MOVEABLE, sizeof(*params) ); + if (hparams) + { + params = (NCCALCSIZE_PARAMS *) GlobalLock( hparams ); + params->rgrc[0] = wndPtr->rectWindow; + params->lppos = NULL; + SendMessage( hwnd, WM_NCCALCSIZE, FALSE, (LONG)params ); + wndPtr->rectClient = params->rgrc[0]; + GlobalUnlock( hparams ); + GlobalFree( hparams ); + } + wmcreate = SendMessage( hwnd, WM_CREATE, 0, (LONG)createStruct ); + } GlobalUnlock( hcreateStruct ); GlobalFree( hcreateStruct ); @@ -329,18 +459,27 @@ WinCreated: if (parent) parentPtr->hwndChild = wndPtr->hwndNext; else firstWindow = wndPtr->hwndNext; +#ifdef USE_XLIB + XDestroyWindow( XT_display, wndPtr->window ); +#else if (wndPtr->shellWidget) XtDestroyWidget( wndPtr->shellWidget ); else XtDestroyWidget( wndPtr->winWidget ); - if (wndPtr->hdc) DeleteDC( wndPtr->hdc ); +#endif + if (wndPtr->flags & WIN_OWN_DC) DCE_FreeDCE( wndPtr->hdce ); classPtr->cWindows--; USER_HEAP_FREE( hwnd ); return 0; } - - EVENT_AddHandlers( wndPtr->winWidget, hwnd ); - if (style & WS_VISIBLE) ShowWindow( hwnd, SW_SHOW ); +#ifdef USE_XLIB + EVENT_AddHandlers( wndPtr->window, hwnd ); +#else + EVENT_AddHandlers( wndPtr->winWidget, hwnd ); +#endif + WIN_SendParentNotify( hwnd, wndPtr, WM_CREATE ); + + if (style & WS_VISIBLE) ShowWindow( hwnd, SW_SHOW ); return hwnd; } @@ -350,7 +489,6 @@ WinCreated: BOOL DestroyWindow( HWND hwnd ) { WND * wndPtr; - HWND * curWndPtr; CLASS * classPtr; /* Initialisation */ @@ -366,130 +504,30 @@ BOOL DestroyWindow( HWND hwnd ) /* Destroy all children */ + if (wndPtr->hWndVScroll) DestroyWindow(wndPtr->hWndVScroll); + if (wndPtr->hWndHScroll) DestroyWindow(wndPtr->hWndHScroll); while (wndPtr->hwndChild) /* The child removes itself from the list */ DestroyWindow( wndPtr->hwndChild ); /* Remove the window from the linked list */ - if (wndPtr->hwndParent) - { - WND * parentPtr = WIN_FindWndPtr( wndPtr->hwndParent ); - curWndPtr = &parentPtr->hwndChild; - } - else curWndPtr = &firstWindow; - - while (*curWndPtr != hwnd) - { - WND * curPtr = WIN_FindWndPtr( *curWndPtr ); - curWndPtr = &curPtr->hwndNext; - } - *curWndPtr = wndPtr->hwndNext; + WIN_UnlinkWindow( hwnd ); /* Destroy the window */ +#ifdef USE_XLIB + XDestroyWindow( XT_display, wndPtr->window ); +#else if (wndPtr->shellWidget) XtDestroyWidget( wndPtr->shellWidget ); else XtDestroyWidget( wndPtr->winWidget ); - if (wndPtr->hdc) DeleteDC( wndPtr->hdc ); +#endif + if (wndPtr->flags & WIN_OWN_DC) DCE_FreeDCE( wndPtr->hdce ); classPtr->cWindows--; USER_HEAP_FREE( hwnd ); return TRUE; } -/*********************************************************************** - * GetWindowRect (USER.32) - */ -void GetWindowRect( HWND hwnd, LPRECT rect ) -{ - int x, y, width, height; - WND * wndPtr = WIN_FindWndPtr( hwnd ); - - if (wndPtr) - { - XtVaGetValues(wndPtr->winWidget, - XtNx, &x, XtNy, &y, - XtNwidth, &width, - XtNheight, &height, - NULL ); - rect->left = x & 0xffff; - rect->top = y & 0xffff; - rect->right = width & 0xffff; - rect->bottom = height & 0xffff; - } -} - - -/*********************************************************************** - * GetClientRect (USER.33) - */ -void GetClientRect( HWND hwnd, LPRECT rect ) -{ - int width, height; - WND * wndPtr = WIN_FindWndPtr( hwnd ); - - rect->left = rect->top = rect->right = rect->bottom = 0; - if (wndPtr) - { - XtVaGetValues(wndPtr->winWidget, - XtNwidth, &width, - XtNheight, &height, - NULL ); - rect->right = width & 0xffff; - rect->bottom = height & 0xffff; - } -} - - -/*********************************************************************** - * ShowWindow (USER.42) - */ -BOOL ShowWindow( HWND hwnd, int cmd ) -{ - int width, height; - - WND * wndPtr = WIN_FindWndPtr( hwnd ); - if (wndPtr) - { - if (wndPtr->shellWidget) XtRealizeWidget( wndPtr->shellWidget ); - XtVaGetValues(wndPtr->winWidget, - XtNwidth, &width, - XtNheight, &height, - NULL ); - switch(cmd) - { - case SW_HIDE: - XtSetMappedWhenManaged(wndPtr->winWidget, FALSE); - wndPtr->dwStyle &= (WS_VISIBLE ^ 0xFFFFFFFL); - SendMessage( hwnd, WM_SHOWWINDOW, FALSE, 0 ); - break; - case SW_SHOWMINNOACTIVE: - case SW_SHOWMINIMIZED: - case SW_MINIMIZE: - wndPtr->dwStyle |= WS_ICONIC; - goto WINVisible; - case SW_SHOWNA: - case SW_SHOWNOACTIVATE: - case SW_MAXIMIZE: - case SW_SHOWMAXIMIZED: - case SW_SHOW: - case SW_NORMAL: - case SW_SHOWNORMAL: - wndPtr->dwStyle &= (WS_ICONIC ^ 0xFFFFFFFL); -WINVisible: - XtSetMappedWhenManaged(wndPtr->winWidget, TRUE); - wndPtr->dwStyle |= WS_VISIBLE; - SendMessage( hwnd, WM_SIZE, SIZE_RESTORED, - (width & 0xffff) | (height << 16) ); - SendMessage( hwnd, WM_SHOWWINDOW, TRUE, 0 ); - break; - default: - break; - } - } - return TRUE; -} - - /*********************************************************************** * CloseWindow (USER.43) */ @@ -498,7 +536,6 @@ void CloseWindow(HWND hWnd) WND * wndPtr = WIN_FindWndPtr(hWnd); if (wndPtr->dwStyle & WS_CHILD) return; ShowWindow(hWnd, SW_MINIMIZE); - PostMessage(hWnd, WM_CLOSE, 0, 0L); } @@ -508,7 +545,6 @@ void CloseWindow(HWND hWnd) */ BOOL OpenIcon(HWND hWnd) { - WND * wndPtr = WIN_FindWndPtr(hWnd); if (!IsIconic(hWnd)) return FALSE; ShowWindow(hWnd, SW_SHOWNORMAL); return(TRUE); @@ -523,34 +559,8 @@ HWND FindWindow(LPSTR ClassMatch, LPSTR TitleMatch) { return((HWND)NULL); } - -/*********************************************************************** - * MoveWindow (USER.56) - */ -void MoveWindow(HWND hWnd, short x, short y, short w, short h, BOOL bRepaint) -{ - WND * wndPtr = WIN_FindWndPtr( hWnd ); - if (wndPtr) - { - wndPtr->rectClient.left = x; - wndPtr->rectClient.top = y; - wndPtr->rectClient.right = x + w; - wndPtr->rectClient.bottom = y + h; - XtVaSetValues(wndPtr->winWidget, XtNx, x, XtNy, y, - XtNwidth, w, XtNheight, h, NULL ); - SendMessage(hWnd, WM_MOVE, 0, MAKELONG(x, y)); - printf("MoveWindow(%X, %d, %d, %d, %d, %d); !\n", - hWnd, x, y, w, h, bRepaint); - if (bRepaint) { - InvalidateRect(hWnd, NULL, TRUE); - UpdateWindow(hWnd); - } - } -} - - /*********************************************************************** * UpdateWindow (USER.124) */ @@ -578,8 +588,10 @@ HMENU GetMenu( HWND hwnd ) */ BOOL SetMenu(HWND hwnd, HMENU hmenu) { +#ifdef USE_XLIB + return FALSE; +#else WND *wndPtr; - wndPtr = WIN_FindWndPtr(hwnd); if (wndPtr == NULL) return FALSE; @@ -618,44 +630,7 @@ BOOL SetMenu(HWND hwnd, HMENU hmenu) } return TRUE; -} - - -/*********************************************************************** - * SetWindowPos (USER.232) - */ -void SetWindowPos(HWND hWnd, HWND hWndInsertAfter, short x, short y, short w, short h, WORD wFlag) -{ - WND * wndPtr = WIN_FindWndPtr( hWnd ); - if (wndPtr) - { - if ((wFlag & SWP_NOMOVE) != SWP_NOMOVE) { - wndPtr->rectClient.left = x; - wndPtr->rectClient.top = y; - XtVaSetValues(wndPtr->winWidget, XtNx, x, XtNy, y, NULL ); - } - if ((wFlag & SWP_NOSIZE) != SWP_NOSIZE) { - wndPtr->rectClient.right = x + w; - wndPtr->rectClient.bottom = y + h; - XtVaSetValues(wndPtr->winWidget, XtNwidth, w, XtNheight, h, NULL ); - } - if ((wFlag & SWP_NOREDRAW) != SWP_NOREDRAW) { - InvalidateRect(hWnd, NULL, TRUE); - UpdateWindow(hWnd); - } - if ((wFlag & SWP_HIDEWINDOW) == SWP_HIDEWINDOW) - ShowWindow(hWnd, SW_HIDE); - if ((wFlag & SWP_SHOWWINDOW) == SWP_SHOWWINDOW) - ShowWindow(hWnd, SW_SHOW); -/* - if ((wFlag & SWP_NOACTIVATE) != SWP_NOACTIVATE) - SetActiveWindow(hWnd); - if ((wFlag & SWP_NOZORDER) != SWP_NOZORDER) - { } -*/ - printf("SetWindowPos(%X, %X, %d, %d, %d, %d, %X); !\n", - hWnd, hWndInsertAfter, x, y, w, h, wFlag); - } +#endif /* USE_XLIB */ } @@ -748,21 +723,6 @@ LONG SetWindowLong( HWND hwnd, short offset, LONG newval ) } -/*********************************************************************** - * IsIconic (USER.31) - */ -BOOL IsIconic(HWND hWnd) -{ - WND * wndPtr; - if (hWnd == 0) return(FALSE); - wndPtr = WIN_FindWndPtr(hWnd); - if (wndPtr == 0) return(FALSE); - if (wndPtr->dwStyle & WS_ICONIC) return(TRUE); - return(FALSE); -} - - - /******************************************************************* * GetWindowText (USER.36) */ @@ -796,7 +756,7 @@ int GetWindowTextLength(HWND hwnd) BOOL IsWindow( HWND hwnd ) { WND * wndPtr = WIN_FindWndPtr( hwnd ); - return (wndPtr->dwMagic == WND_MAGIC); + return ((wndPtr != NULL) && (wndPtr->dwMagic == WND_MAGIC)); } @@ -806,6 +766,7 @@ BOOL IsWindow( HWND hwnd ) HWND GetParent(HWND hwnd) { WND *wndPtr = WIN_FindWndPtr(hwnd); + if (!wndPtr) return 0; return wndPtr->hwndParent; } @@ -838,14 +799,9 @@ BOOL IsChild( HWND parent, HWND child ) */ BOOL IsWindowVisible(HWND hWnd) { - WND * wndPtr; - if (hWnd == 0) return(FALSE); - wndPtr = WIN_FindWndPtr(hWnd); + WND * wndPtr = WIN_FindWndPtr(hWnd); if (wndPtr == 0) return(FALSE); - if (wndPtr->dwStyle & WS_VISIBLE) { - if (XtIsRealized(wndPtr->winWidget)) return(TRUE); - } - return(FALSE); + else return ((wndPtr->dwStyle & WS_VISIBLE) != 0); } diff --git a/windows/winpos.c b/windows/winpos.c new file mode 100644 index 00000000000..0b474e2e3ea --- /dev/null +++ b/windows/winpos.c @@ -0,0 +1,389 @@ +/* + * Window position related functions. + * + * Copyright 1993 Alexandre Julliard + */ + +static char Copyright[] = "Copyright Alexandre Julliard, 1993"; + +#include "win.h" + +extern Display * XT_display; +extern Screen * XT_screen; + + +/*********************************************************************** + * GetWindowRect (USER.32) + */ +void GetWindowRect( HWND hwnd, LPRECT rect ) +{ + WND * wndPtr = WIN_FindWndPtr( hwnd ); + if (!wndPtr) return; + + *rect = wndPtr->rectWindow; + if (wndPtr->hwndParent) + MapWindowPoints( wndPtr->hwndParent, 0, (POINT *)rect, 2 ); +} + + +/*********************************************************************** + * GetClientRect (USER.33) + */ +void GetClientRect( HWND hwnd, LPRECT rect ) +{ + WND * wndPtr = WIN_FindWndPtr( hwnd ); + + rect->left = rect->top = rect->right = rect->bottom = 0; + if (wndPtr) + { + rect->right = wndPtr->rectClient.right - wndPtr->rectClient.left; + rect->bottom = wndPtr->rectClient.bottom - wndPtr->rectClient.top; + } +} + + +/******************************************************************* + * ClientToScreen (USER.28) + */ +void ClientToScreen( HWND hwnd, LPPOINT lppnt ) +{ + MapWindowPoints( hwnd, 0, lppnt, 1 ); +} + + +/******************************************************************* + * ScreenToClient (USER.29) + */ +void ScreenToClient( HWND hwnd, LPPOINT lppnt ) +{ + MapWindowPoints( 0, hwnd, lppnt, 1 ); +} + + +/******************************************************************* + * MapWindowPoints (USER.258) + */ +void MapWindowPoints( HWND hwndFrom, HWND hwndTo, LPPOINT lppt, WORD count ) +{ + WND * wndPtr; + POINT * curpt; + POINT origin = { 0, 0 }; + WORD i; + + /* Translate source window origin to screen coords */ + while(hwndFrom) + { + wndPtr = WIN_FindWndPtr( hwndFrom ); + origin.x += wndPtr->rectClient.left; + origin.y += wndPtr->rectClient.top; + hwndFrom = wndPtr->hwndParent; + } + + /* Translate origin to destination window coords */ + while(hwndTo) + { + wndPtr = WIN_FindWndPtr( hwndTo ); + origin.x -= wndPtr->rectClient.left; + origin.y -= wndPtr->rectClient.top; + hwndTo = wndPtr->hwndParent; + } + + /* Translate points */ + for (i = 0, curpt = lppt; i < count; i++, curpt++) + { + curpt->x += origin.x; + curpt->y += origin.y; + } +} + + +/*********************************************************************** + * IsIconic (USER.31) + */ +BOOL IsIconic(HWND hWnd) +{ + WND * wndPtr = WIN_FindWndPtr(hWnd); + if (wndPtr == NULL) return FALSE; + return (wndPtr->dwStyle & WS_MINIMIZE) != 0; +} + + +/*********************************************************************** + * IsZoomed (USER.272) + */ +BOOL IsZoomed(HWND hWnd) +{ + WND * wndPtr = WIN_FindWndPtr(hWnd); + if (wndPtr == NULL) return FALSE; + return (wndPtr->dwStyle & WS_MAXIMIZE) != 0; +} + + +/*********************************************************************** + * MoveWindow (USER.56) + */ +BOOL MoveWindow( HWND hwnd, short x, short y, short cx, short cy, BOOL repaint) +{ + int flags = SWP_NOZORDER | SWP_NOACTIVATE; + if (!repaint) flags |= SWP_NOREDRAW; +#ifdef DEBUG_WIN + printf( "MoveWindow: %d %d,%d %dx%d %d\n", hwnd, x, y, cx, cy, repaint ); +#endif + return SetWindowPos( hwnd, 0, x, y, cx, cy, flags ); +} + + +/*********************************************************************** + * ShowWindow (USER.42) + */ +BOOL ShowWindow( HWND hwnd, int cmd ) +{ + WND * wndPtr = WIN_FindWndPtr( hwnd ); + BOOL wasVisible; + int swpflags = 0; + +#ifdef DEBUG_WIN + printf("ShowWindow: hwnd=%d, cmd=%d\n", hwnd, cmd); +#endif + + if (!wndPtr) return FALSE; + wasVisible = (wndPtr->dwStyle & WS_VISIBLE) != 0; + switch(cmd) + { + case SW_HIDE: + if (!wasVisible) return FALSE; /* Nothing to do */ + swpflags |= SWP_HIDEWINDOW | SWP_NOSIZE | SWP_NOMOVE | + SWP_NOACTIVATE | SWP_NOZORDER; + break; + + case SW_SHOWMINNOACTIVE: + case SW_SHOWMINIMIZED: + case SW_MINIMIZE: + wndPtr->dwStyle |= WS_MINIMIZE; + swpflags |= SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE | + SWP_NOACTIVATE | SWP_NOZORDER; + break; + + case SW_SHOWNA: + case SW_SHOWNOACTIVATE: + case SW_MAXIMIZE: + case SW_SHOWMAXIMIZED: + case SW_SHOW: + case SW_NORMAL: + case SW_SHOWNORMAL: + wndPtr->dwStyle &= ~WS_MINIMIZE; + swpflags |= SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE | + SWP_NOACTIVATE | SWP_NOZORDER; + break; + } + SendMessage( hwnd, WM_SHOWWINDOW, (cmd != SW_HIDE), 0 ); + SetWindowPos( hwnd, 0, 0, 0, 0, 0, swpflags ); + + /* Send WM_SIZE and WM_MOVE messages if not already done */ + if (!(wndPtr->flags & WIN_GOT_SIZEMSG)) + { + int wParam = SIZE_RESTORED; + if (wndPtr->dwStyle & WS_MAXIMIZE) wParam = SIZE_MAXIMIZED; + else if (wndPtr->dwStyle & WS_MINIMIZE) wParam = SIZE_MINIMIZED; + wndPtr->flags |= WIN_GOT_SIZEMSG; + SendMessage( hwnd, WM_SIZE, wParam, + MAKELONG(wndPtr->rectClient.right-wndPtr->rectClient.left, + wndPtr->rectClient.bottom-wndPtr->rectClient.top)); + SendMessage( hwnd, WM_MOVE, 0, + MAKELONG(wndPtr->rectClient.left, wndPtr->rectClient.top) ); + } + return wasVisible; +} + + +/*********************************************************************** + * SetWindowPos (USER.232) + */ +/* Unimplemented flags: SWP_NOREDRAW, SWP_NOACTIVATE + */ +/* Note: all this code should be in the DeferWindowPos() routines, + * and SetWindowPos() should simply call them. This will be implemented + * some day... + */ +BOOL SetWindowPos( HWND hwnd, HWND hwndInsertAfter, short x, short y, + short cx, short cy, WORD flags ) +{ + WINDOWPOS *winPos; + HANDLE hmem = 0; + RECT newWindowRect, newClientRect; + WND *wndPtr; + int calcsize_result = 0; +#ifdef USE_XLIB + XWindowChanges winChanges; + int changeMask = 0; +#endif + +#ifdef DEBUG_WIN + printf( "SetWindowPos: %d %d %d,%d %dx%d 0x%x\n", + hwnd, hwndInsertAfter, x, y, cx, cy, flags ); +#endif + + if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE; + if (flags & (SWP_SHOWWINDOW | SWP_HIDEWINDOW)) + flags |= SWP_NOMOVE | SWP_NOSIZE; + + /* Send WM_WINDOWPOSCHANGING message */ + + if (!(hmem = GlobalAlloc( GMEM_MOVEABLE,sizeof(WINDOWPOS) ))) return FALSE; + winPos = (WINDOWPOS *)GlobalLock( hmem ); + winPos->hwnd = hwnd; + winPos->hwndInsertAfter = hwndInsertAfter; + winPos->x = x; + winPos->y = y; + winPos->cx = cx; + winPos->cy = cy; + winPos->flags = flags; + SendMessage( hwnd, WM_WINDOWPOSCHANGING, 0, (LONG)winPos ); + + /* Calculate new position and size */ + + newWindowRect = wndPtr->rectWindow; + newClientRect = wndPtr->rectClient; + + if (!(winPos->flags & SWP_NOSIZE)) + { + newWindowRect.right = newWindowRect.left + winPos->cx; + newWindowRect.bottom = newWindowRect.top + winPos->cy; + } + + if (!(winPos->flags & SWP_NOMOVE)) + { + newWindowRect.left = winPos->x; + newWindowRect.top = winPos->y; + newWindowRect.right += winPos->x - wndPtr->rectWindow.left; + newWindowRect.bottom += winPos->y - wndPtr->rectWindow.top; + } + + /* Reposition window in Z order */ + + if (!(winPos->flags & SWP_NOZORDER)) + { + hwndInsertAfter = winPos->hwndInsertAfter; + + /* TOPMOST not supported yet */ + if ((hwndInsertAfter == HWND_TOPMOST) || + (hwndInsertAfter == HWND_NOTOPMOST)) hwndInsertAfter = HWND_TOP; + + /* Make sure hwndInsertAfter is a sibling of hwnd */ + if ((hwndInsertAfter != HWND_TOP) && (hwndInsertAfter != HWND_BOTTOM)) + if (wndPtr->hwndParent != GetParent(hwndInsertAfter)) goto Abort; + + WIN_UnlinkWindow( hwnd ); + WIN_LinkWindow( hwnd, hwndInsertAfter ); + } + + /* Recalculate client area position */ + + if (winPos->flags & SWP_FRAMECHANGED) + { + /* Send WM_NCCALCSIZE message */ + NCCALCSIZE_PARAMS *params; + HANDLE hparams; + + if (!(hparams = GlobalAlloc( GMEM_MOVEABLE, sizeof(*params) ))) + goto Abort; + params = (NCCALCSIZE_PARAMS *) GlobalLock( hparams ); + params->rgrc[0] = newWindowRect; + params->rgrc[1] = wndPtr->rectWindow; + params->rgrc[2] = wndPtr->rectClient; + params->lppos = winPos; + calcsize_result = SendMessage(hwnd, WM_NCCALCSIZE, TRUE, (LONG)params); + GlobalUnlock( hparams ); + GlobalFree( hparams ); + newClientRect = params->rgrc[0]; + /* Handle result here */ + } + else + { + newClientRect.left = newWindowRect.left + wndPtr->rectClient.left + - wndPtr->rectWindow.left; + newClientRect.top = newWindowRect.top + wndPtr->rectClient.top + - wndPtr->rectWindow.top; + newClientRect.right = newWindowRect.right + wndPtr->rectClient.right + - wndPtr->rectWindow.right; + newClientRect.bottom = newWindowRect.bottom + wndPtr->rectClient.bottom + - wndPtr->rectWindow.bottom; + } + + /* Perform the moving and resizing */ +#ifdef USE_XLIB + if (!(winPos->flags & SWP_NOMOVE)) + { + WND * parentPtr; + winChanges.x = newWindowRect.left; + winChanges.y = newWindowRect.top; + if (wndPtr->hwndParent) + { + parentPtr = WIN_FindWndPtr(wndPtr->hwndParent); + winChanges.x += parentPtr->rectClient.left-parentPtr->rectWindow.left; + winChanges.y += parentPtr->rectClient.top-parentPtr->rectWindow.top; + } + changeMask |= CWX | CWY; + } + if (!(winPos->flags & SWP_NOSIZE)) + { + winChanges.width = newWindowRect.right - newWindowRect.left; + winChanges.height = newWindowRect.bottom - newWindowRect.top; + changeMask |= CWWidth | CWHeight; + } + if (!(winPos->flags & SWP_NOZORDER)) + { + if (hwndInsertAfter == HWND_TOP) winChanges.stack_mode = Above; + else winChanges.stack_mode = Below; + if ((hwndInsertAfter != HWND_TOP) && (hwndInsertAfter != HWND_BOTTOM)) + { + WND * insertPtr = WIN_FindWndPtr( hwndInsertAfter ); + winChanges.sibling = insertPtr->window; + changeMask |= CWSibling; + } + changeMask |= CWStackMode; + } + if (changeMask) XConfigureWindow( XT_display, wndPtr->window, + changeMask, &winChanges ); +#endif + + if (winPos->flags & SWP_SHOWWINDOW) + { + wndPtr->dwStyle |= WS_VISIBLE; +#ifdef USE_XLIB + XMapWindow( XT_display, wndPtr->window ); +#else + if (wndPtr->shellWidget) XtMapWidget( wndPtr->shellWidget ); + else XtMapWidget( wndPtr->winWidget ); +#endif + } + else if (winPos->flags & SWP_HIDEWINDOW) + { + wndPtr->dwStyle &= ~WS_VISIBLE; +#ifdef USE_XLIB + XUnmapWindow( XT_display, wndPtr->window ); +#else + if (wndPtr->shellWidget) XtUnmapWidget( wndPtr->shellWidget ); + else XtUnmapWidget( wndPtr->winWidget ); +#endif + } + + /* Finally send the WM_WINDOWPOSCHANGED message */ + wndPtr->rectWindow = newWindowRect; + wndPtr->rectClient = newClientRect; + SendMessage( hwnd, WM_WINDOWPOSCHANGED, 0, (LONG)winPos ); + GlobalUnlock( hmem ); + GlobalFree( hmem ); + + return TRUE; + + Abort: /* Fatal error encountered */ + if (hmem) + { + GlobalUnlock( hmem ); + GlobalFree( hmem ); + } + return FALSE; +} + + diff --git a/wine.ini b/wine.ini new file mode 100644 index 00000000000..d9958bea4f0 --- /dev/null +++ b/wine.ini @@ -0,0 +1,19 @@ +[drives] +a=/mnt/fd0 +c=/dos +d=/usr/windows +e=/home/bob/Wine/work +f=/home/bob/test + +[wine] +windows=c:\windows +system=c:\windows\system +temp=c:\temp +path=c:\windows;c:\windows\system;e:\;e:\test;f:\ + +[serialports] +com1=/dev/cua0 +com2=/dev/cua1 + +[parallelports] +lpt1=/dev/lp0