Release 960728
Sun Jul 28 17:57:19 1996 Alexandre Julliard <julliard@lrc.epfl.ch>
* [loader/task.c] [include/task.h]
Implemented SwitchStackTo()/SwitchStackBack().
* [include/wintypes.h] [loader/main.c]
Added __winelib variable to distinguish between emulator and
library at run-time. Later on, this should avoid some
recompilations when building Winelib.
* [windows/property.c]
Implemented Win32 functions for window properties.
Fri Jul 26 18:00:00 1996 Alex Korobka <alex@phm30.pharm.sunysb.edu>
* [controls/listbox.c]
Implemented LBS_SORT style, WM_COMPAREITEM, and WM_DELETEITEM
messages.
* [controls/menu.c]
Call TranslateMessage() to enable shortcuts (on WM_CHAR).
* [include/cursoricon.h]
Moved #pragma pack(1) back to where it belongs.
* [objects/palette.c]
RealizeDefaultPalette() maps to system colors only.
Do not broadcast palette notifications when in TrueColor.
* [objects/color.c] [include/palette.h]
Miscellaneous optimizations. Had to fix several
"improvements" made to my patch for previous release.
* [objects/dib.c]
Reverse dib bits order for 24-bit SetDIBits().
* [objects/dc.c]
GetDeviceCaps() does not return RC_PALETTE when in TrueColor.
* [windows/scroll.c]
Scroll update region too.
* [windows/message.c]
Include QS_MOUSE into the event mask for nonclient mouse
message filter. Fixes problems with Word 6 freezing when
mouse hits nonclient area.
* [windows/win.c]
Allow top-level windows to be linked as HWND_TOP in CreateWindow().
* [windows/winpos.c] [windows/mdi.c]
Attempt to fix control menu duplication.
Fri Jul 26 09:49:35 1996 Marcus Meissner <msmeissn@cip.informatik.uni-erlangen.de>
* [files/drive.c]
GetDriveType32A(): return value for CDROM fixed.
* [files/file.c]
SearchPath* added.
* [if1632/gdi32.spec] [objects/brush.c]
SetBrushOrgEx() added.
* [loader/pe_resource.c]
If even loading the default entry fails, we just use the first
entry from the resource directory.
[loader/task.c]
SetSigHandler() stub added, Paradox 4.5 now starts up.
* [misc/comm.c] [include/windows.h] [if1632/kernel32.spec]
COMM functions updated to win32, not complete.
* [misc/lstr.c]
FormatMessageA partially implemented.
* [include/miscemu.h] [memory/selector.c]
[memory/global.c] [miscemu/dosmem.c]
DOS memory handling changed: 1MB preallocated block, real-mode
segment handling possible, SetSelectorBase into lower physical 1MB
possible.
* [miscemu/dpmi.c]
Real-mode segments changed, real-mode int 21,ax=6506 added.
AX=0x0303 added.
* [multimedia/time.c]
Fixed bug in killTimer.
* [objects/bitmap.c]
LoadImageA partially implemented.
Wed Jul 24 18:20:24 1996 Albrecht Kleine <kleine@ak.sax.de>
* [include/dde_mem.h][include/dde_proc.h]
[ipc/dde_atom.c][ipc/dde_proc.c][windows/message.c]
[ipc/generic_hash.h][library/miscstubs.c]
Changes for error free compilation using "--with-ipc":
replaced some names with *16-equivalent (e.g. MSG to MSG16),
modified prototype of function DDE_GlobalFree() .
* [objects/palette.c]
Added check for metafile-DC in GDISelectPalette(),
GDIRealizePalette(),RealizeDefaultPalette() and
IsDCCurrentPalette().
Tue Jul 23 22:46:53 1996 Andrew Lewycky <plewycky@oise.utoronto.ca>
* [controls/edit.c]
EDIT_WM_Create: Don't EDIT_EM_ReplaceSel if created with lParam = "",
fixes Winhelp.
* [windows/dialog.c]
DIALOG_CreateIndirect: Initialise dlgProc before creating children.
diff --git a/ANNOUNCE b/ANNOUNCE
index 2c43984..cf7b48e 100644
--- a/ANNOUNCE
+++ b/ANNOUNCE
@@ -1,13 +1,13 @@
-This is release 960717 of Wine, the MS Windows emulator. This is still a
+This is release 960728 of Wine, the MS Windows emulator. This is still a
developer's only release. There are many bugs and many unimplemented API
features. Most applications still do not work correctly.
Patches should be submitted to "julliard@lrc.epfl.ch". Please don't
forget to include a ChangeLog entry.
-WHAT'S NEW with Wine-960717: (see ChangeLog for details)
- - New palette management.
- - Changes to the configuration process.
+WHAT'S NEW with Wine-960728: (see ChangeLog for details)
+ - Many fixed to the palette management.
+ - DOS real-mode memory emulation.
- Lots of bug fixes.
See the README file in the distribution for installation instructions.
@@ -16,10 +16,10 @@
the release is available at the ftp sites. The sources will be available
from the following locations:
- sunsite.unc.edu:/pub/Linux/ALPHA/wine/development/Wine-960717.tar.gz
- tsx-11.mit.edu:/pub/linux/ALPHA/Wine/development/Wine-960717.tar.gz
- ftp.infomagic.com:/pub/mirrors/linux/wine/development/Wine-960717.tar.gz
- aris.com:/pub/linux/ALPHA/Wine/development/Wine-960717.tar.gz
+ sunsite.unc.edu:/pub/Linux/ALPHA/wine/development/Wine-960728.tar.gz
+ tsx-11.mit.edu:/pub/linux/ALPHA/Wine/development/Wine-960728.tar.gz
+ ftp.infomagic.com:/pub/mirrors/linux/wine/development/Wine-960728.tar.gz
+ aris.com:/pub/linux/ALPHA/Wine/development/Wine-960728.tar.gz
It should also be available from any site that mirrors tsx-11 or sunsite.
diff --git a/ChangeLog b/ChangeLog
index 09c335f..43a3c8f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,121 @@
----------------------------------------------------------------------
+Sun Jul 28 17:57:19 1996 Alexandre Julliard <julliard@lrc.epfl.ch>
+
+ * [loader/task.c] [include/task.h]
+ Implemented SwitchStackTo()/SwitchStackBack().
+
+ * [include/wintypes.h] [loader/main.c]
+ Added __winelib variable to distinguish between emulator and
+ library at run-time. Later on, this should avoid some
+ recompilations when building Winelib.
+
+ * [windows/property.c]
+ Implemented Win32 functions for window properties.
+
+Fri Jul 26 18:00:00 1996 Alex Korobka <alex@phm30.pharm.sunysb.edu>
+
+ * [controls/listbox.c]
+ Implemented LBS_SORT style, WM_COMPAREITEM, and WM_DELETEITEM
+ messages.
+
+ * [controls/menu.c]
+ Call TranslateMessage() to enable shortcuts (on WM_CHAR).
+
+ * [include/cursoricon.h]
+ Moved #pragma pack(1) back to where it belongs.
+
+ * [objects/palette.c]
+ RealizeDefaultPalette() maps to system colors only.
+ Do not broadcast palette notifications when in TrueColor.
+
+ * [objects/color.c] [include/palette.h]
+ Miscellaneous optimizations. Had to fix several
+ "improvements" made to my patch for previous release.
+
+ * [objects/dib.c]
+ Reverse dib bits order for 24-bit SetDIBits().
+
+ * [objects/dc.c]
+ GetDeviceCaps() does not return RC_PALETTE when in TrueColor.
+
+ * [windows/scroll.c]
+ Scroll update region too.
+
+ * [windows/message.c]
+ Include QS_MOUSE into the event mask for nonclient mouse
+ message filter. Fixes problems with Word 6 freezing when
+ mouse hits nonclient area.
+
+ * [windows/win.c]
+ Allow top-level windows to be linked as HWND_TOP in CreateWindow().
+
+ * [windows/winpos.c] [windows/mdi.c]
+ Attempt to fix control menu duplication.
+
+Fri Jul 26 09:49:35 1996 Marcus Meissner <msmeissn@cip.informatik.uni-erlangen.de>
+
+ * [files/drive.c]
+ GetDriveType32A(): return value for CDROM fixed.
+
+ * [files/file.c]
+ SearchPath* added.
+
+ * [if1632/gdi32.spec] [objects/brush.c]
+ SetBrushOrgEx() added.
+
+ * [loader/pe_resource.c]
+ If even loading the default entry fails, we just use the first
+ entry from the resource directory.
+
+ [loader/task.c]
+ SetSigHandler() stub added, Paradox 4.5 now starts up.
+
+ * [misc/comm.c] [include/windows.h] [if1632/kernel32.spec]
+ COMM functions updated to win32, not complete.
+
+ * [misc/lstr.c]
+ FormatMessageA partially implemented.
+
+ * [include/miscemu.h] [memory/selector.c]
+ [memory/global.c] [miscemu/dosmem.c]
+ DOS memory handling changed: 1MB preallocated block, real-mode
+ segment handling possible, SetSelectorBase into lower physical 1MB
+ possible.
+
+ * [miscemu/dpmi.c]
+ Real-mode segments changed, real-mode int 21,ax=6506 added.
+ AX=0x0303 added.
+
+ * [multimedia/time.c]
+ Fixed bug in killTimer.
+
+ * [objects/bitmap.c]
+ LoadImageA partially implemented.
+
+Wed Jul 24 18:20:24 1996 Albrecht Kleine <kleine@ak.sax.de>
+
+ * [include/dde_mem.h][include/dde_proc.h]
+ [ipc/dde_atom.c][ipc/dde_proc.c][windows/message.c]
+ [ipc/generic_hash.h][library/miscstubs.c]
+ Changes for error free compilation using "--with-ipc":
+ replaced some names with *16-equivalent (e.g. MSG to MSG16),
+ modified prototype of function DDE_GlobalFree() .
+
+ * [objects/palette.c]
+ Added check for metafile-DC in GDISelectPalette(),
+ GDIRealizePalette(),RealizeDefaultPalette() and
+ IsDCCurrentPalette().
+
+Tue Jul 23 22:46:53 1996 Andrew Lewycky <plewycky@oise.utoronto.ca>
+
+ * [controls/edit.c]
+ EDIT_WM_Create: Don't EDIT_EM_ReplaceSel if created with lParam = "",
+ fixes Winhelp.
+
+ * [windows/dialog.c]
+ DIALOG_CreateIndirect: Initialise dlgProc before creating children.
+
+----------------------------------------------------------------------
Wed Jul 17 16:10:16 1996 Alexandre Julliard <julliard@lrc.epfl.ch>
* [configure.in]
@@ -270,7 +387,7 @@
* [windows/winproc.c]
Allows creating dialog windows with NULL as dialog function.
-Wed Jul 3 09:26:41 1996 Peter Lewycky <plewycky@oise.utoronto.ca>
+Wed Jul 3 09:26:41 1996 Andrew Lewycky <plewycky@oise.utoronto.ca>
* [windows/event.c]
EVENT_key: Fixes to VK_ code generation for space bar and
diff --git a/controls/combo.c b/controls/combo.c
index 989c0b2..4990654 100644
--- a/controls/combo.c
+++ b/controls/combo.c
@@ -425,10 +425,7 @@
LPHEADLIST lphl = ComboGetListHeader(hwnd);
LPHEADCOMBO lphc = ComboGetStorageHeader(hwnd);
- if (lphl->HasStrings)
- wRet = ListBoxAddString(lphl, (LPSTR)PTR_SEG_TO_LIN(lParam));
- else
- wRet = ListBoxAddString(lphl, (LPSTR)lParam);
+ wRet = ListBoxAddString(lphl, (SEGPTR)lParam);
ComboUpdateWindow(hwnd, lphl, lphc, TRUE);
return wRet;
diff --git a/controls/edit.c b/controls/edit.c
index 5dae7f9..c646fb6 100644
--- a/controls/edit.c
+++ b/controls/edit.c
@@ -2253,7 +2253,7 @@
*text = '\0';
EDIT_BuildLineDefs(wndPtr);
EDIT_WM_SetFont(wndPtr, 0, 0L);
- if (cs->lpszName)
+ if (cs->lpszName && *(char *)PTR_SEG_TO_LIN(cs->lpszName) != '\0')
EDIT_EM_ReplaceSel(wndPtr, FALSE, (LPARAM)cs->lpszName);
EDIT_WM_SetRedraw(wndPtr, TRUE, 0L);
return 0L;
diff --git a/controls/listbox.c b/controls/listbox.c
index b3a5b8d..1cbb28c 100644
--- a/controls/listbox.c
+++ b/controls/listbox.c
@@ -3,15 +3,17 @@
*
* Copyright Martin Ayotte, 1993
* Constantine Sapuntzakis, 1995
- * Alex Korobka, 1995
+ * Alex Korobka, 1995, 1996
*
*/
/*
* FIXME:
- * - check if multi-column listboxes work
- * - implement more messages and styles
- * - implement caret for LBS_EXTENDEDSEL
+ * - proper scrolling for multicolumn style
+ * - anchor and caret for LBS_EXTENDEDSEL
+ * - proper selection with keyboard
+ * - how to handle (LBS_EXTENDEDSEL | LBS_MULTIPLESEL) style
+ * - support for LBS_NOINTEGRALHEIGHT and LBS_OWNERDRAWVARIABLE styles
*/
#include <stdio.h>
@@ -27,6 +29,7 @@
#include "drive.h"
#include "file.h"
#include "heap.h"
+#include "stackframe.h"
#include "stddebug.h"
#include "debug.h"
#include "xmalloc.h"
@@ -43,6 +46,10 @@
#define LBMM_EDGE 4 /* distance inside box which is same as moving mouse
outside box, to trigger scrolling of LB */
+#define MATCH_SUBSTR 2
+#define MATCH_EXACT 1
+#define MATCH_NEAREST 0
+
static void ListBoxInitialize(LPHEADLIST lphl)
{
lphl->lpFirst = NULL;
@@ -267,6 +274,21 @@
return LB_ERR;
}
+BOOL lbDeleteItemNotify(LPHEADLIST lphl, LPLISTSTRUCT lpls)
+{
+ /* called only for owner drawn listboxes */
+
+ DELETEITEMSTRUCT16 delItem;
+
+ delItem.CtlType = lphl->DrawCtlType;
+ delItem.CtlID = lphl->CtlID;
+ delItem.itemID = lpls->mis.itemID;
+ delItem.hwndItem= lphl->hSelf;
+ delItem.itemData= lpls->mis.itemData;
+
+ return (BOOL) SendMessage16(lphl->hParent, WM_DELETEITEM, (WPARAM)lphl->CtlID,
+ (LPARAM)MAKE_SEGPTR(&delItem));
+}
void ListBoxAskMeasure(LPHEADLIST lphl, LPLISTSTRUCT lpls)
{
@@ -306,7 +328,97 @@
return lplsnew;
}
+int ListBoxAskCompare(LPHEADLIST lphl, int startItem, SEGPTR matchData, BOOL exactMatch )
+{
+ /* Do binary search for sorted listboxes. Linked list item storage sort of
+ * defeats the purpose ( forces to traverse item list all the time ) but M$ does it this way...
+ *
+ * MATCH_NEAREST (0) - return position for insertion - for all styles
+ * MATCH_EXACT (1) - search for an item, return index or LB_ERR
+ * MATCH_SUBSTR (2) - same as exact match but with strncmp for string comparision
+ */
+ COMPAREITEMSTRUCT16 itemCmp;
+ LPLISTSTRUCT currentItem = NULL;
+ LPCSTR matchStr = (lphl->HasStrings)?(LPCSTR)PTR_SEG_TO_LIN(matchData):NULL;
+ int head, pos = -1, tail, loop = 1;
+ short b = 0, s_length = 0;
+
+ /* check if empty */
+
+ if( !lphl->ItemsCount )
+ return (exactMatch)? LB_ERR: 0;
+
+ /* set up variables */
+
+ if( exactMatch == MATCH_NEAREST )
+ startItem = 0;
+ else if( ++startItem )
+ {
+ loop = 2;
+ if( startItem >= lphl->ItemsCount ) startItem = lphl->ItemsCount - 1;
+ }
+
+ if( exactMatch == MATCH_SUBSTR && lphl->HasStrings )
+ {
+ s_length = strlen( matchStr );
+ if( !s_length ) return 0; /* head of the list - empty string */
+ }
+
+ head = startItem; tail = lphl->ItemsCount - 1;
+
+ dprintf_listbox(stddeb,"AskCompare: head = %i, tail = %i, data = %08x\n", head, tail, (unsigned)matchData );
+
+ itemCmp.CtlType = lphl->DrawCtlType;
+ itemCmp.CtlID = lphl->CtlID;
+ itemCmp.hwndItem = lphl->hSelf;
+
+ /* search from startItem */
+
+ while ( loop-- )
+ {
+ while( head <= tail )
+ {
+ pos = (tail + head)/2;
+ currentItem = ListBoxGetItem( lphl, pos );
+
+ if( lphl->HasStrings )
+ {
+ b = ( s_length )? strncasecmp( currentItem->itemText, matchStr, s_length)
+ : strcasecmp( currentItem->itemText, matchStr);
+ }
+ else
+ {
+ itemCmp.itemID1 = pos;
+ itemCmp.itemData1 = currentItem->mis.itemData;
+ itemCmp.itemID2 = -1;
+ itemCmp.itemData2 = matchData;
+
+ b = SendMessage16( lphl->hParent, WM_COMPAREITEM, (WPARAM)lphl->CtlID,
+ (LPARAM)MAKE_SEGPTR(&itemCmp) );
+ }
+
+ if( b == 0 )
+ return pos; /* found exact match */
+ else
+ if( b < 0 ) head = ++pos;
+ else
+ if( b > 0 ) tail = pos - 1;
+ }
+
+ /* reset to search from the first item */
+ head = 0; tail = startItem - 1;
+ }
+
+ dprintf_listbox(stddeb,"\t-> pos = %i\n", pos );
+
+ /* if we got here match is not exact */
+
+ if( pos < 0 ) pos = 0;
+ else if( pos > lphl->ItemsCount ) pos = lphl->ItemsCount;
+
+ return (exactMatch)? LB_ERR: pos;
+}
int ListBoxInsertString(LPHEADLIST lphl, UINT uIndex, LPCSTR newstr)
{
@@ -371,16 +483,14 @@
}
-int ListBoxAddString(LPHEADLIST lphl, LPCSTR newstr)
+int ListBoxAddString(LPHEADLIST lphl, SEGPTR itemData)
{
- UINT pos = (UINT) -1;
-
- if (lphl->HasStrings && (lphl->dwStyle & LBS_SORT)) {
- LPLISTSTRUCT lpls = lphl->lpFirst;
- for (pos = 0; lpls != NULL; lpls = lpls->lpNext, pos++)
- if (strcmp(lpls->itemText, newstr) >= 0)
- break;
- }
+ UINT pos = (UINT) -1;
+ LPCSTR newstr = (lphl->HasStrings)?(LPCSTR)PTR_SEG_TO_LIN(itemData):(LPCSTR)itemData;
+
+ if ( lphl->dwStyle & LBS_SORT )
+ pos = ListBoxAskCompare( lphl, -1, itemData, MATCH_NEAREST );
+
return ListBoxInsertString(lphl, pos, newstr);
}
@@ -438,8 +548,13 @@
if (lpls == NULL) return LB_ERR;
if (uIndex == 0)
+ {
+ if( lphl->OwnerDrawn )
+ lbDeleteItemNotify( lphl, lpls);
lphl->lpFirst = lpls->lpNext;
- else {
+ }
+ else
+ {
LPLISTSTRUCT lpls2 = NULL;
for(Count = 0; Count < uIndex; Count++) {
if (lpls->lpNext == NULL) return LB_ERR;
@@ -447,6 +562,8 @@
lpls2 = lpls;
lpls = (LPLISTSTRUCT)lpls->lpNext;
}
+ if( lphl->OwnerDrawn )
+ lbDeleteItemNotify( lphl, lpls);
lpls2->lpNext = lpls->lpNext;
}
@@ -463,28 +580,43 @@
return lphl->ItemsCount;
}
-
-int ListBoxFindString(LPHEADLIST lphl, UINT nFirst, SEGPTR MatchStr)
+int lbFindString(LPHEADLIST lphl, UINT nFirst, SEGPTR MatchStr, BOOL match)
{
+ /* match is either MATCH_SUBSTR or MATCH_EXACT */
+
LPLISTSTRUCT lpls;
UINT Count;
- UINT First = nFirst + 1;
+ UINT First = nFirst + 1;
+ int s_length = 0;
LPSTR lpMatchStr = (LPSTR)MatchStr;
if (First > lphl->ItemsCount) return LB_ERR;
- if (lphl->HasStrings) lpMatchStr = PTR_SEG_TO_LIN(MatchStr);
-
+ if (lphl->dwStyle & LBS_SORT )
+ return ListBoxAskCompare( lphl, nFirst, MatchStr, match );
+
+ if (lphl->HasStrings )
+ {
+ lpMatchStr = PTR_SEG_TO_LIN(MatchStr);
+
+ if( match == MATCH_SUBSTR )
+ {
+ s_length = strlen(lpMatchStr);
+ if( !s_length ) return (lphl->ItemsCount)?0:LB_ERR;
+ }
+ }
+
lpls = ListBoxGetItem(lphl, First);
Count = 0;
- while(lpls != NULL) {
- if (lphl->HasStrings) {
- if (strstr(lpls->itemText, lpMatchStr) == lpls->itemText) return Count;
- } else if (lphl->dwStyle & LBS_SORT) {
- /* XXX Do a compare item */
+ while(lpls != NULL)
+ {
+ if (lphl->HasStrings)
+ {
+ if ( ( s_length )? !strncasecmp(lpls->itemText, lpMatchStr, s_length)
+ : !strcasecmp(lpls->itemText, lpMatchStr) ) return Count;
}
else
- if (lpls->mis.itemData == (DWORD)lpMatchStr) return Count;
+ if ( lpls->mis.itemData == (DWORD)lpMatchStr ) return Count;
lpls = lpls->lpNext;
Count++;
@@ -494,14 +626,16 @@
Count = 0;
lpls = lphl->lpFirst;
- while (Count < First) {
- if (lphl->HasStrings) {
- if (strstr(lpls->itemText, lpMatchStr) == lpls->itemText) return Count;
- } else if (lphl->dwStyle & LBS_SORT) {
- /* XXX Do a compare item */
- } else {
- if (lpls->mis.itemData == (DWORD)lpMatchStr) return Count;
+ while (Count < First)
+ {
+ if (lphl->HasStrings)
+ {
+ if ( ( s_length )? !strncasecmp(lpls->itemText, lpMatchStr, s_length)
+ : !strcasecmp(lpls->itemText, lpMatchStr) ) return Count;
}
+ else
+ if ( lpls->mis.itemData == (DWORD)lpMatchStr ) return Count;
+
lpls = lpls->lpNext;
Count++;
}
@@ -509,6 +643,15 @@
return LB_ERR;
}
+int ListBoxFindString(LPHEADLIST lphl, UINT nFirst, SEGPTR MatchStr)
+{
+ return lbFindString(lphl, nFirst, MatchStr, MATCH_SUBSTR );
+}
+
+int ListBoxFindStringExact(LPHEADLIST lphl, UINT nFirst, SEGPTR MatchStr)
+{
+ return lbFindString(lphl, nFirst, MatchStr, MATCH_EXACT );
+}
int ListBoxResetContent(LPHEADLIST lphl)
{
@@ -523,7 +666,9 @@
for(i = 0; i < lphl->ItemsCount; i++) {
lpls = lphl->lpFirst;
if (lpls == NULL) return LB_ERR;
-
+
+ if (lphl->OwnerDrawn) lbDeleteItemNotify(lphl, lpls);
+
lphl->lpFirst = lpls->lpNext;
if (lpls->hData != 0) LIST_HEAP_FREE(lphl, lpls->hData);
free(lpls);
@@ -603,12 +748,13 @@
LONG ListBoxDirectory(LPHEADLIST lphl, UINT attrib, LPCSTR filespec)
{
- char temp[16], mask[13];
+ char mask[13];
+ char* temp = NULL;
+ const char* ptr;
+ int skip, count;
+ LONG ret;
+ DOS_DIRENT entry;
char *path, *p;
- const char *ptr;
- int skip, count;
- LONG ret;
- DOS_DIRENT entry;
dprintf_listbox(stddeb, "ListBoxDirectory: '%s' %04x\n", filespec, attrib);
if (!filespec) return LB_ERR;
@@ -616,11 +762,13 @@
path = xstrdup(ptr);
p = strrchr( path, '/' );
*p++ = '\0';
- if (!(ptr = DOSFS_ToDosFCBFormat( p )))
+ if (!(ptr = DOSFS_ToDosFCBFormat( p )) ||
+ !(temp = SEGPTR_ALLOC( sizeof(char) * 16 )) )
{
free( path );
return LB_ERR;
}
+
strcpy( mask, ptr );
dprintf_listbox(stddeb, "ListBoxDirectory: path=%s mask=%s\n", path, mask);
@@ -636,7 +784,7 @@
{
sprintf(temp, "[%s]", DOSFS_ToDosDTAFormat( entry.name ) );
AnsiLower( temp );
- if ((ret = ListBoxAddString(lphl, temp)) == LB_ERR) break;
+ if ((ret = ListBoxAddString(lphl, SEGPTR_GET(temp))) == LB_ERR) break;
}
}
else /* not a directory */
@@ -647,9 +795,11 @@
{
strcpy( temp, DOSFS_ToDosDTAFormat( entry.name ) );
AnsiLower( temp );
- if ((ret = ListBoxAddString(lphl, temp)) == LB_ERR) break;
+ if ((ret = ListBoxAddString(lphl, SEGPTR_GET(temp))) == LB_ERR) break;
}
}
+
+ dprintf_listbox(stddeb,"\tn - %i, file '%s'\n", count, temp);
}
if (attrib & DDL_DRIVES)
{
@@ -658,10 +808,13 @@
for (x = 0; x < MAX_DOS_DRIVES; x++, temp[2]++)
{
if (DRIVE_IsValid(x))
- if ((ret = ListBoxAddString(lphl, temp)) == LB_ERR) break;
+ if ((ret = ListBoxAddString(lphl, SEGPTR_GET(temp))) == LB_ERR) break;
}
}
+
free( path );
+ SEGPTR_FREE( temp );
+
return ret;
}
@@ -1432,10 +1585,7 @@
WORD wRet;
LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
- if (lphl->HasStrings)
- wRet = ListBoxAddString(lphl, (LPCSTR)PTR_SEG_TO_LIN(lParam));
- else
- wRet = ListBoxAddString(lphl, (LPCSTR)lParam);
+ wRet = ListBoxAddString(lphl, (SEGPTR)lParam);
ListBoxUpdateWindow(hwnd,lphl,TRUE);
return wRet;
@@ -1490,7 +1640,16 @@
static LONG LBFindString(HWND hwnd, WORD wParam, LONG lParam)
{
LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
- return ListBoxFindString(lphl, wParam, (SEGPTR)lParam);
+ return lbFindString(lphl, wParam, (SEGPTR)lParam, MATCH_SUBSTR);
+}
+
+/***********************************************************************
+ * LBFindStringExact
+ */
+static LONG LBFindStringExact(HWND hwnd, WORD wParam, LONG lParam)
+{
+ LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
+ return lbFindString(lphl, wParam, (SEGPTR)lParam, MATCH_EXACT);
}
/***********************************************************************
@@ -1661,7 +1820,7 @@
LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
INT iRet;
- iRet = ListBoxFindString(lphl, wParam, (SEGPTR)lParam);
+ iRet = lbFindString(lphl, wParam, (SEGPTR)lParam, MATCH_SUBSTR);
if( iRet != LB_ERR)
{
@@ -1920,6 +2079,7 @@
case LB_INSERTSTRING: return LBInsertString(hwnd, wParam, lParam);
case LB_DELETESTRING: return LBDeleteString(hwnd, wParam, lParam);
case LB_FINDSTRING: return LBFindString(hwnd, wParam, lParam);
+ case LB_FINDSTRINGEXACT: return LBFindStringExact(hwnd, wParam, lParam);
case LB_GETCARETINDEX: return LBGetCaretIndex(hwnd, wParam, lParam);
case LB_GETCOUNT: return LBGetCount(hwnd, wParam, lParam);
case LB_GETCURSEL: return LBGetCurSel(hwnd, wParam, lParam);
diff --git a/controls/menu.c b/controls/menu.c
index c880829..e38a4cd 100644
--- a/controls/menu.c
+++ b/controls/menu.c
@@ -1533,6 +1533,8 @@
hwnd, MSGF_MENU, 0, TRUE ))
break;
+ TranslateMessage( msg );
+
fRemove = FALSE;
if ((msg->message >= WM_MOUSEFIRST) && (msg->message <= WM_MOUSELAST))
{
diff --git a/documentation/debugging b/documentation/debugging
new file mode 100644
index 0000000..1cee434
--- /dev/null
+++ b/documentation/debugging
@@ -0,0 +1,206 @@
+This file describes where to start debugging Wine and how to write
+useful bug reports.
+
+Crashes
+=======
+
+ These usually show up like this:
+
+|Unexpected Windows program segfault - opcode = 8b
+|Segmentation fault in Windows program 1b7:c41.
+|Reading symbols from file /root/wine/wine.sym
+|In 16 bit mode.
+|Register dump:
+| CS:01b7 SS:016f DS:0287 ES:0000
+| IP:0c41 SP:878a BP:8796 FLAGS:0246
+| AX:811e BX:0000 CX:0000 DX:0000 SI:0001 DI:ffff
+|Stack dump:
+|0x016f:0x878a: 0001 016f ffed 0000 0000 0287 890b 1e5b
+|0x016f:0x879a: 01b7 0001 000d 1050 08b7 016f 0001 000d
+|0x016f:0x87aa: 000a 0003 0004 0000 0007 0007 0190 0000
+|0x016f:0x87ba:
+|
+|0050: sel=0287 base=40211d30 limit=0b93f (bytes) 16-bit rw-
+|Backtrace:
+|0 0x01b7:0x0c41 (PXSRV.FONGETFACENAME+0x7c)
+|1 0x01b7:0x1e5b (PXSRV.FONPUTCATFONT+0x2cd)
+|2 0x01a7:0x05aa
+|3 0x01b7:0x0768 (PXSRV.FONINITFONTS+0x81)
+|4 0x014f:0x03ed (PDOXWIN.@SQLCURCB$Q6CBTYPEULN8CBSCTYPE+0x1b1)
+|5 0x013f:0x00ac
+|
+|0x01b7:0x0c41 (PXSRV.FONGETFACENAME+0x7c): movw %es:0x38(%bx),%dx
+
+Steps to debug a crash. You may stop at any step, but please report the bug
+and provide as much of the information gathered to the newsgroup or the
+relevant developer as feasonable.
+
+ 1. Get the reason for the crash. This is usually an access to an invalid
+ selector, an access to an out of range address in a valid selector,
+ popping a segmentregister from the stack or the like. When reporting a
+ crash, report this WHOLE crashdump even if it doesn't make sense to you.
+
+ (In this case it is access to an invalid selector, for %es is 0000, as
+ seen in the register dump).
+
+ 2. Determine where the reason came from.
+ Since this is usually a primary/secondary reaction to a failed or
+ misbehaving Wine function, rerun Wine with "-debugmsg +relay" (without ")
+ added to the commandline. This will get rather much output, but usually
+ the reason is located in the last call(s). Those lines usually look like
+ this:
+
+|Call KERNEL.90: LSTRLEN(0227:0692) ret=01e7:2ce7 ds=0227
+ ^^^^^^^^^ ^ ^^^^^^^^^ ^^^^^^^^^ ^^^^
+ | | | | |Datasegment on entry
+ | | | |Return address.
+ | | |
+ | | |Argument(s). This one is a win16 segmented pointer.
+ | |Function called.
+ |The module, the function is called in. In this case it is KERNEL.
+
+|Ret KERNEL.90: LSTRLEN() retval=0x0007 ret=01e7:2ce7 ds=0227
+ ^^^^^^
+ |Returnvalue is 16 bit and has the value 7.
+
+ 3. If you have found a misbehaving function, try to find out why it
+ misbehaves. Find the function in the source code. Try to make sense of
+ the arguments passed. Usually there is a
+ "dprintf_xyz(stddeb,"Fnction(...)"...);" at the beginning of the
+ function. Rerun wine with "-debugmsg +xyz,+relay" added to the
+ commandline.
+
+
+ 4. If those information isn't clear enough or if you want to know more about
+ what's happening in the function itself, try running wine with "-debugmsg
+ +all", which dumps ALL included debug information in wine.
+
+ 5. If that isn't enough add more debug output for yourself into the
+ functions you find relevant.
+
+ 6. You can also set a breakpoint for that function. Start wine with the
+ "-debug" option added to the commandline. After loading the executable
+ wine will enter the internal debugger. Use "break KERNEL.LSTRLEN"
+ (replace by function you want to debug, CASE IS RELEVANT.) to set a
+ breakpoint. Then use "continue" to start normal program-execution. Wine
+ will stop if it reaches the breakpoint. If the program isn't yet at the
+ crashing call of that function, use "continue" again until you are about
+ to enter that function. You may now proceed with single-stepping the
+ function until you reach the point of crash. Use the other debugger
+ commands to print registers and the like.
+
+
+Program hangs, nothing happens
+==============================
+
+ Switch to UNIX shell, get the process-ID using "ps -a|grep wine", and do a
+ "kill -HUP <pid>" (without " and <>). Wine will then enter its internal
+ debugger and you can procede as explained above.
+
+Program reports an error with a Messagebox
+==========================================
+
+ Sometimes programs are reporting failure using a more or less nondescript
+ messageboxes. We can debug this using the same method as Crashes, but there
+ is one problem... For setting up a message box the program also calls Wine
+ producing huge chunks of debug code.
+
+ Since the failure happens usually directly before setting up the Messagebox
+ you can start wine with "-debug" added to the commandline, set a breakpoint
+ at "USER.MESSAGEBOX" (win16 programs) "USER32.MessageBox" (win32 Programs)
+ and proceed with "continue". With "-debugmsg +all" Wine will now stop
+ directly directly before setting up the Messagebox. Proceed as explained
+ above.
+
+
+Sample debugging session:
+=========================
+
+ Let's debug the infamous Word SHARE.EXE messagebox:
+
+|marcus@jet $ wine winword.exe
+| +---------------------------------------------+
+| | ! You must leave Windows and load SHARE.EXE|
+| | before starting Word. |
+| +---------------------------------------------+
+
+
+|marcus@jet $ wine winword.exe -debugmsg +relay -debug
+|CallTo32(func=08007e00,000001c4,00000081,00000000,00000000)
+|CallTo32(func=08007e00,000001c4,00000014,000006d0,00000000)
+|Win16 task 'winword': Breakpoint 1 at 0x0157:0x001a
+|CallTo16(func=0097:0130,ds=0000)
+|Call WPROCS.24: TASK_RESCHEDULE() ret=003f:0759 ds=0000
+|Ret WPROCS.24: TASK_RESCHEDULE() retval=0x0000 ret=003f:0759 ds=08a7
+|CallTo16(func=0157:001a,ds=08a7,0x11d7,0x0000,0x0000,0x3cb4,0x1f40,0x0000,0x0000,0x08a7)
+|Reading symbols from file /root/wine/wine.sym
+|Stopped on breakpoint 1 at 0x0157:0x001a
+|In 16 bit mode.
+|0x0157:0x001a: xorw %bp,%bp
+|Wine-dbg> break USER.MESSAGEBOX <---- Set Breakpoint
+|Breakpoint 2 at 0x0067:0x00000000 (USER.MESSAGEBOX)
+|Wine-dbg>c <---- Continue
+|Call KERNEL.91: INITTASK() ret=0157:0022 ds=08a7
+| AX=0000 BX=3cb4 CX=1f40 DX=0000 SI=0000 DI=08a7 ES=11d7 EFL=00000286
+|CallTo16(func=090f:085c,ds=0dcf,0x0000,0x0000,0x0000,0x0000,0x0800,0x0000,0x0000,0x0dcf)
+|... <----- Much debugoutput
+|Call KERNEL.97: GETTEMPFILENAME(0x00c3,08a7:8350,0x0000,08a7:8234) ret=058f:09b1 ds=08a7
+ ^ ^ ^ ^
+ | | | |LPSTR buffer
+ | | |UINT16 unique
+ | |LPCSTR prefix
+ |BYTE drive
+
+|Ret KERNEL.97: GETTEMPFILENAME() retval=0xce3f ret=058f:09b1 ds=08a7
+ ^
+ |new unique number
+
+|Call KERNEL.74: OPENFILE(08a7:8234,08a7:82c6,0x1012) ret=058f:09d8 ds=08a7
+ ^ ^ ^
+ | | |UINT32 mode
+ | |OFSTRUCT *ofs
+ |LPCSTR name
+
+|Ret KERNEL.74: OPENFILE() retval=0xffff ret=058f:09d8 ds=08a7
+ ^
+ | -1 aka. HFILE_ERROR
+
+|Stopped on breakpoint 2 at 0x0067:0x00000000 (USER.MESSAGEBOX)
+|In 32 bit mode.
+|0x0067:0x00000000 (USER.MESSAGEBOX): pushw %bp
+
+ Now, we see that OPENFILE seem to have returned 0xFFFF (or -1). Checking
+ the implementation of OpenFile in files/file.c, this signals an error.
+ The mode flags (OF_READWRITE|OF_SHARE_EXCLUSIVE|OF_CREATE) seems to
+ indicate, that WinWord wants to open the file for writing, so we check
+ the filename. Since we don't see the filename in this debugoutput, we use
+ the dprintf_file() in OpenFile to print out more information by adding
+ "-debugmsg +relay" to the commandline.
+
+ (In fact, we see that the filename has been returned by the GetTempFileName
+ function above, but we check it anyway.)
+
+|marcus@jet $ wine winword.exe -debugmsg +relay,+file -debug
+|.....much more debugoutput .....
+|
+|Call KERNEL.97: GETTEMPFILENAME(0x00c3,08a7:8350,0x0000,08a7:8234) ret=058f:09b1 ds=08a7
+|FILE_Create: 'C:~docd03d.tmp' 01b6 1
+|FILE_SetDosError: errno = 13
+|GetTempFileName: returning C:\~DOCD03D.TMP
+|Ret KERNEL.97: GETTEMPFILENAME() retval=0xd03d ret=058f:09b1 ds=08a7
+|Call KERNEL.74: OPENFILE(08a7:8234,08a7:82c6,0x1012) ret=058f:09d8 ds=08a7
+|OpenFile: C:\~DOCD03D.TMP 1012
+|FILE_AllocTaskHandle: returning task handle 1, dos_file 0, file 1 of 254
+|FILE_Create: 'C:\~DOCD03D.TMP' 01b6 0
+|FILE_SetDosError: errno = 13
+|OpenFile(C:\~DOCD03D.TMP): return = HFILE_ERROR
+|FILE_FreeTaskHandle: dos=1 file=0
+|Ret KERNEL.74: OPENFILE() retval=0xffff ret=058f:09d8 ds=08a7
+
+ The filename is "C:\~DOCD03D.TMP". Of course, C:\ is writeable for the
+ superuser only, so the open fails for a normal user and OpenFile returns
+ -1, which in turn generates this messagebox.
+
+
+Written by Marcus Meissner <msmeissn@cip.informatik.uni-erlangen.de>,
+additions welcome.
diff --git a/files/drive.c b/files/drive.c
index fb15297..f85c149 100644
--- a/files/drive.c
+++ b/files/drive.c
@@ -557,7 +557,7 @@
{
case TYPE_FLOPPY: return DRIVE_REMOVABLE;
case TYPE_HD: return DRIVE_FIXED;
- case TYPE_CDROM: return DRIVE_REMOVABLE;
+ case TYPE_CDROM: return DRIVE_CDROM;
case TYPE_NETWORK: return DRIVE_REMOTE;
case TYPE_INVALID:
default: return DRIVE_CANNOTDETERMINE;
diff --git a/files/file.c b/files/file.c
index 7d30397..2ea02e3 100644
--- a/files/file.c
+++ b/files/file.c
@@ -802,6 +802,121 @@
return HFILE_ERROR;
}
+/***********************************************************************
+ * SearchPath32A (KERNEL32.447)
+ * Code borrowed from OpenFile above.
+ */
+DWORD SearchPath32A(
+ LPCSTR path,LPCSTR fn,LPCSTR ext,DWORD buflen,LPSTR buf,LPSTR *lastpart
+) {
+ LPCSTR unixName;
+ INT32 len;
+ char testpath[1000]; /* should be enough for now */
+ char *name,*p;
+ int i;
+
+ if (ext==NULL)
+ ext = "";
+ name=(char*)xmalloc(strlen(fn)+strlen(ext)+1);
+ strcpy(name,fn);
+ strcat(name,ext);
+
+ dprintf_file(stddeb,"SearchPath32A(%s,%s,%s,%ld,%p,%p)\n",
+ path,fn,ext,buflen,buf,lastpart
+ );
+ if (path) {
+ strcpy(testpath,path);
+ strcat(testpath,"\\");
+ strcat(testpath,name);
+ if ((unixName=DOSFS_GetUnixFileName((LPCSTR)testpath,TRUE))!=NULL) {
+ goto found;
+ } else
+ return 0;
+ }
+ if ((len=sizeof(testpath)-strlen(name)-1)<0)
+ return 0;
+
+ /* Try the path of the current executable */
+ if (GetCurrentTask()) {
+ GetModuleFileName(GetCurrentTask(),testpath,len);
+ if ((p=strrchr(testpath,'\\'))) {
+ strcpy(p+1,name);
+ if ((unixName=DOSFS_GetUnixFileName((LPCSTR)testpath,TRUE)))
+ goto found;
+ }
+ }
+
+ /* Try the current directory */
+ lstrcpyn32A(testpath,name,sizeof(testpath) );
+ if ((unixName=DOSFS_GetUnixFileName((LPCSTR)testpath,TRUE))!=NULL)
+ goto found;
+
+ /* Try the Windows directory */
+ GetWindowsDirectory(testpath,len);
+ strcat(testpath,"\\");
+ strcat(testpath,name);
+ if ((unixName = DOSFS_GetUnixFileName((LPCSTR)testpath,TRUE))!=NULL)
+ goto found;
+
+ /* Try the Windows system directory */
+ GetSystemDirectory32A(testpath,len);
+ strcat(testpath,"\\");
+ strcat(testpath,name);
+ if ((unixName=DOSFS_GetUnixFileName((LPCSTR)testpath,TRUE))!=NULL)
+ goto found;
+
+ /* Try all directories in path */
+
+ for (i=0;;i++)
+ {
+ if (!DIR_GetDosPath(i,testpath,len))
+ return 0;
+ strcat(testpath,"\\");
+ strcat(testpath,name);
+ if ((unixName=DOSFS_GetUnixFileName((LPCSTR)testpath,TRUE))!=NULL)
+ break;
+ }
+
+found:
+ strncpy(buf,testpath,buflen);
+ if (NULL!=(p=strrchr(testpath,'\\')))
+ p=p+1;
+ else
+ p=testpath;
+ if (p-testpath<buflen)
+ *lastpart=(p-testpath)+buf;
+ else
+ *lastpart=NULL;
+ dprintf_file(stddeb," -> found %s,last part is %s\n",testpath,p);
+ return strlen(testpath);
+}
+
+/***********************************************************************
+ * SearchPath32W (KERNEL32.448)
+ */
+DWORD SearchPath32W(
+ LPCWSTR path,LPCWSTR fn,LPCWSTR ext,DWORD buflen,LPWSTR buf,
+ LPWSTR *lastpart
+) {
+ LPSTR pathA = path?STRING32_DupUniToAnsi(path):NULL;
+ LPSTR fnA = STRING32_DupUniToAnsi(fn);
+ LPSTR extA = ext?STRING32_DupUniToAnsi(fn):NULL;
+ LPSTR lastpartA;
+ LPSTR bufA = (char*)xmalloc(buflen+1);
+ DWORD ret;
+
+ ret=SearchPath32A(pathA,fnA,extA,buflen,bufA,&lastpartA);
+ lstrcpynAtoW(buf,bufA,buflen);
+ if (lastpartA)
+ *lastpart = buf+(lastpartA-bufA);
+ else
+ *lastpart = NULL;
+ free(bufA);
+ free(fnA);
+ if (pathA) free(pathA);
+ if (extA) free(extA);
+ return ret;
+}
/***********************************************************************
* _lclose (KERNEL.81) (KERNEL32.592)
diff --git a/if1632/gdi32.spec b/if1632/gdi32.spec
index f145907..dca8d1b 100644
--- a/if1632/gdi32.spec
+++ b/if1632/gdi32.spec
@@ -312,7 +312,7 @@
0305 stdcall SetBkColor(long long) SetBkColor
0306 stdcall SetBkMode(long long) SetBkMode
0307 stub SetBoundsRect
-0308 stub SetBrushOrgEx
+0308 stdcall SetBrushOrgEx(long long long ptr) SetBrushOrgEx
0309 stub SetColorAdjustment
0310 stub SetColorSpace
0311 stub SetDIBColorTable
diff --git a/if1632/kernel.spec b/if1632/kernel.spec
index a607a33..ece39884 100644
--- a/if1632/kernel.spec
+++ b/if1632/kernel.spec
@@ -104,8 +104,8 @@
105 stub GetExeVersion
106 pascal SetSwapAreaSize(word) SetSwapAreaSize
107 pascal16 SetErrorMode(word) SetErrorMode
-108 stub SwitchStackTo
-109 stub SwitchStackBack
+108 pascal16 SwitchStackTo(word word word) SwitchStackTo
+109 register SwitchStackBack() SwitchStackBack
110 pascal16 PatchCodeHandle(word) PatchCodeHandle
111 pascal GlobalWire(word) GlobalWire
112 pascal16 GlobalUnWire(word) GlobalUnWire
@@ -138,7 +138,7 @@
137 pascal FatalAppExit(word ptr) FatalAppExit
138 pascal GetHeapSpaces(word) GetHeapSpaces
139 stub DoSignal
-140 stub SetSigHandler
+140 pascal16 SetSigHandler(segptr ptr ptr word word) SetSigHandler
141 stub InitTask1
142 stub GetProfileSectionNames
143 stub GetPrivateProfileSectionNames
diff --git a/if1632/kernel32.spec b/if1632/kernel32.spec
index 7378cce..71833e4 100644
--- a/if1632/kernel32.spec
+++ b/if1632/kernel32.spec
@@ -16,14 +16,14 @@
0011 stdcall Beep(long long) Beep
0012 stub BeginUpdateResourceA
0013 stub BeginUpdateResourceW
-0014 stub BuildCommDCBA
-0015 stub BuildCommDCBAndTimeoutsA
-0016 stub BuildCommDCBAndTimeoutsW
-0017 stub BuildCommDCBW
+0014 stdcall BuildCommDCBA(ptr ptr) BuildCommDCB32A
+0015 stdcall BuildCommDCBAndTimeoutsA(ptr ptr ptr) BuildCommDCBAndTimeouts32A
+0016 stdcall BuildCommDCBAndTimeoutsW(ptr ptr ptr) BuildCommDCBAndTimeouts32W
+0017 stdcall BuildCommDCBW(ptr ptr) BuildCommDCB32W
0018 stub CallNamedPipeA
0019 stub CallNamedPipeW
-0020 stub ClearCommBreak
-0021 stub ClearCommError
+0020 stdcall ClearCommBreak(long) ClearCommBreak32
+0021 stdcall ClearCommError(long ptr ptr) ClearCommError
0022 stub CloseConsoleHandle
0023 stdcall CloseHandle(long) CloseHandle
0024 stub CloseProfileUserMapping
@@ -101,8 +101,8 @@
0096 stub EnumTimeFormatsA
0097 stub EnumTimeFormatsW
0098 stub EraseTape
-0099 stub EscapeCommFunction
-0100 stdcall ExitProcess(long) ExitProcess
+0099 stdcall EscapeCommFunction(long long) EscapeCommFunction32
+0100 stdcall ExitProcess(long) ExitProcess
0101 stub ExitThread
0102 stub ExitVDM
0103 stub ExpandEnvironmentStringsA
@@ -140,7 +140,7 @@
0135 stub FlushViewOfFile
0136 stub FoldStringA
0137 stub FoldStringW
-0138 stub FormatMessageA
+0138 stdcall FormatMessageA(long ptr long long ptr long ptr) FormatMessage32A
0139 stub FormatMessageW
0140 stub FreeConsole
0141 stdcall FreeEnvironmentStringsA(ptr) FreeEnvironmentStringsA
@@ -156,14 +156,14 @@
0151 stub GetBinaryType
0152 stub GetBinaryTypeA
0153 stub GetBinaryTypeW
-0154 stdcall GetCPInfo(long ptr) GetCPInfo
+0154 stdcall GetCPInfo(long ptr) GetCPInfo
0155 stub GetCommConfig
-0156 stub GetCommMask
+0156 stdcall GetCommMask(long ptr) GetCommMask
0157 stub GetCommModemStatus
0158 stub GetCommProperties
-0159 stub GetCommState
-0160 stub GetCommTimeouts
-0161 stdcall GetCommandLineA() GetCommandLineA
+0159 stdcall GetCommState(long ptr) GetCommState32
+0160 stdcall GetCommTimeouts(long ptr) GetCommTimeouts
+0161 stdcall GetCommandLineA() GetCommandLineA
0162 stub GetCommandLineW
0163 stub GetCompressedFileSizeA
0164 stub GetCompressedFileSizeW
@@ -449,13 +449,13 @@
0444 stdcall RtlZeroMemory(ptr long) RtlZeroMemory
0445 stub ScrollConsoleScreenBufferA
0446 stub ScrollConsoleScreenBufferW
-0447 stub SearchPathA
-0448 stub SearchPathW
-0449 stub SetCommBreak
+0447 stdcall SearchPathA(ptr ptr ptr long ptr ptr) SearchPath32A
+0448 stdcall SearchPathW(ptr ptr ptr long ptr ptr) SearchPath32W
+0449 stdcall SetCommBreak(long) SetCommBreak32
0450 stub SetCommConfig
-0451 stub SetCommMask
-0452 stub SetCommState
-0453 stub SetCommTimeouts
+0451 stdcall SetCommMask(long ptr) SetCommMask
+0452 stdcall SetCommState(long ptr) SetCommState32
+0453 stdcall SetCommTimeouts(long ptr) SetCommTimeouts
0454 stub SetComputerNameA
0455 stub SetComputerNameW
0456 stub SetConsoleActiveScreenBuffer
@@ -537,7 +537,7 @@
0532 stdcall TlsGetValue(long) TlsGetValue
0533 stdcall TlsSetValue(long ptr) TlsSetValue
0534 stub TransactNamedPipe
-0535 stub TransmitCommChar
+0535 stdcall TransmitCommChar(long long) TransmitCommChar32
0536 stub TrimVirtualBuffer
0537 stdcall UnhandledExceptionFilter(ptr) UnhandledExceptionFilter
0538 stub UnlockFile
diff --git a/if1632/relay.c b/if1632/relay.c
index 8401948..614c419 100644
--- a/if1632/relay.c
+++ b/if1632/relay.c
@@ -4,7 +4,7 @@
*/
#include <stdio.h>
-
+#include "windows.h"
#include "global.h"
#include "module.h"
#include "registers.h"
@@ -268,6 +268,19 @@
/* only 9 words long. Hopefully no one will have the silly */
/* idea to change the current stack before calling Throw()... */
+ /* Windows uses:
+ * lpbuf[0] = ip
+ * lpbuf[1] = cs
+ * lpbuf[2] = sp
+ * lpbuf[3] = bp
+ * lpbuf[4] = si
+ * lpbuf[5] = di
+ * lpbuf[6] = ds
+ * lpbuf[7] = unused
+ * lpbuf[8] = ss
+ */
+ /* FIXME: we need to save %si and %di */
+
lpbuf[0] = IF1632_Saved16_sp;
lpbuf[1] = LOWORD(IF1632_Saved32_esp);
lpbuf[2] = HIWORD(IF1632_Saved32_esp);
@@ -287,6 +300,7 @@
INT16 Throw( LPCATCHBUF lpbuf, INT16 retval )
{
STACK16FRAME *pFrame;
+ WORD es = CURRENT_STACK16->es;
IF1632_Saved16_sp = lpbuf[0] - sizeof(WORD);
IF1632_Saved32_esp = MAKELONG( lpbuf[1], lpbuf[2] );
@@ -297,6 +311,15 @@
pFrame->bp = lpbuf[6];
pFrame->ip = lpbuf[7];
pFrame->cs = lpbuf[8];
- pFrame->es = 0;
+ pFrame->es = es;
+ if (debugging_relay) /* Make sure we have a valid entry point address */
+ {
+ static FARPROC16 entryPoint = NULL;
+
+ if (!entryPoint) /* Get entry point for Throw() */
+ entryPoint = MODULE_GetEntryPoint( GetModuleHandle("KERNEL"), 56 );
+ pFrame->entry_cs = SELECTOROF(entryPoint);
+ pFrame->entry_ip = OFFSETOF(entryPoint);
+ }
return retval;
}
diff --git a/if1632/user.spec b/if1632/user.spec
index 52ff7e7..5e10675 100644
--- a/if1632/user.spec
+++ b/if1632/user.spec
@@ -23,10 +23,10 @@
21 pascal16 GetDoubleClickTime() GetDoubleClickTime
22 pascal16 SetFocus(word) SetFocus
23 pascal16 GetFocus() GetFocus
-24 pascal16 RemoveProp(word segptr) RemoveProp
-25 pascal16 GetProp(word segptr) GetProp
-26 pascal16 SetProp(word segptr word) SetProp
-27 pascal16 EnumProps(word segptr) EnumProps
+24 pascal16 RemoveProp(word ptr) RemoveProp16
+25 pascal16 GetProp(word ptr) GetProp16
+26 pascal16 SetProp(word ptr word) SetProp16
+27 pascal16 EnumProps(word segptr) EnumProps16
28 pascal16 ClientToScreen(word ptr) ClientToScreen16
29 pascal16 ScreenToClient(word ptr) ScreenToClient16
30 pascal16 WindowFromPoint(long) WindowFromPoint16
@@ -201,20 +201,20 @@
198 pascal16 CascadeChildWindows(word word) CascadeChildWindows
199 pascal16 TileChildWindows(word word) TileChildWindows
200 pascal16 OpenComm(ptr word word) OpenComm
-201 pascal16 SetCommState(ptr) SetCommState
-202 pascal16 GetCommState(word ptr) GetCommState
+201 pascal16 SetCommState(ptr) SetCommState16
+202 pascal16 GetCommState(word ptr) GetCommState16
203 pascal16 GetCommError(word ptr) GetCommError
204 pascal16 ReadComm(word ptr word) ReadComm
205 pascal16 WriteComm(word ptr word) WriteComm
-206 pascal16 TransmitCommChar(word byte) TransmitCommChar
+206 pascal16 TransmitCommChar(word byte) TransmitCommChar16
207 pascal16 CloseComm(word) CloseComm
208 pascal SetCommEventMask(word word) SetCommEventMask
209 pascal16 GetCommEventMask(word word) GetCommEventMask
-210 pascal16 SetCommBreak(word) SetCommBreak
-211 pascal16 ClearCommBreak(word) ClearCommBreak
+210 pascal16 SetCommBreak(word) SetCommBreak16
+211 pascal16 ClearCommBreak(word) ClearCommBreak16
212 pascal16 UngetCommChar(word byte) UngetCommChar
-213 pascal16 BuildCommDCB(ptr ptr) BuildCommDCB
-214 pascal EscapeCommFunction(word word) EscapeCommFunction
+213 pascal16 BuildCommDCB(ptr ptr) BuildCommDCB16
+214 pascal EscapeCommFunction(word word) EscapeCommFunction16
215 pascal16 FlushComm(word word) FlushComm
#216 USERSEEUSERDO
217 pascal16 LookupMenuHandle(word s_word) LookupMenuHandle
diff --git a/if1632/user32.spec b/if1632/user32.spec
index ef4b733..d6da555 100644
--- a/if1632/user32.spec
+++ b/if1632/user32.spec
@@ -55,7 +55,7 @@
0050 stub ClientThreadConnect
0051 stdcall ClientToScreen(long ptr) ClientToScreen32
0052 stdcall ClipCursor(ptr) ClipCursor32
-0053 stub CloseClipboard
+0053 stdcall CloseClipboard() CloseClipboard
0054 stub CloseDesktop
0055 stub CloseWindow
0056 stub CloseWindowStation
@@ -189,10 +189,10 @@
0182 stub EnumDisplayDeviceModesW
0183 stub EnumDisplayDevicesA
0184 stub EnumDisplayDevicesW
-0185 stub EnumPropsA
-0186 stub EnumPropsExA
-0187 stub EnumPropsExW
-0188 stub EnumPropsW
+0185 stdcall EnumPropsA(long ptr) EnumProps32A
+0186 stdcall EnumPropsExA(long ptr long) EnumPropsEx32A
+0187 stdcall EnumPropsExW(long ptr long) EnumPropsEx32W
+0188 stdcall EnumPropsW(long ptr) EnumProps32W
0189 stdcall EnumThreadWindows(long ptr long) EnumThreadWindows
0190 stub EnumWindowStationsA
0191 stub EnumWindowStationsW
@@ -243,7 +243,7 @@
0236 stdcall GetDlgItemTextA(long long ptr long) GetDlgItemText32A
0237 stdcall GetDlgItemTextW(long long ptr long) GetDlgItemText32W
0238 stub GetDoubleClickTime
-0239 stub GetFocus
+0239 stdcall GetFocus() GetFocus
0240 stub GetForegroundWindow
0241 stub GetIconInfo
0242 stub GetInputDesktop
@@ -265,7 +265,7 @@
0258 stub GetMenuContextHelpId
0259 stub GetMenuDefaultItem
0260 stub GetMenuIndex
-0261 stub GetMenuItemCount
+0261 stdcall GetMenuItemCount(long) GetMenuItemCount
0262 stub GetMenuItemID
0263 stub GetMenuItemInfoA
0264 stub GetMenuItemInfoW
@@ -284,8 +284,8 @@
0277 stub GetParent
0278 stub GetPriorityClipboardFormat
0279 stub GetProcessWindowStation
-0280 stub GetPropA
-0281 stub GetPropW
+0280 stdcall GetPropA(long ptr) GetProp32A
+0281 stdcall GetPropW(long ptr) GetProp32W
0282 stub GetQueueStatus
0283 stub GetScrollInfo
0284 stub GetScrollPos
@@ -343,7 +343,7 @@
0336 stdcall IsCharUpperA(long) IsCharUpper32A
0337 stdcall IsCharUpperW(long) IsCharUpper32W
0338 stub IsChild
-0339 stub IsClipboardFormatAvailable
+0339 stdcall IsClipboardFormatAvailable(long) IsClipboardFormatAvailable
0340 stub IsDialogMessage
0341 stub IsDialogMessageA
0342 stub IsDialogMessageW
@@ -368,7 +368,7 @@
0361 stdcall LoadCursorW(long ptr) LoadCursor32W
0362 stdcall LoadIconA(long ptr) LoadIcon32A
0363 stdcall LoadIconW(long ptr) LoadIcon32W
-0364 stub LoadImageA
+0364 stdcall LoadImageA(long ptr long long long long) LoadImage32A
0365 stub LoadImageW
0366 stub LoadKeyboardLayoutA
0367 stub LoadKeyboardLayoutW
@@ -410,7 +410,7 @@
0403 stdcall OemToCharBuffW(ptr ptr long) OemToCharBuff32W
0404 stdcall OemToCharW(ptr ptr) OemToChar32W
0405 stdcall OffsetRect(ptr long long) OffsetRect32
-0406 stub OpenClipboard
+0406 stdcall OpenClipboard(long) OpenClipboard
0407 stub OpenDesktopA
0408 stub OpenDesktopW
0409 stub OpenIcon
@@ -445,8 +445,8 @@
0438 stdcall ReleaseCapture() ReleaseCapture
0439 stdcall ReleaseDC(long long) ReleaseDC
0440 stub RemoveMenu
-0441 stub RemovePropA
-0442 stub RemovePropW
+0441 stdcall RemovePropA(long ptr) RemoveProp32A
+0442 stdcall RemovePropW(long ptr) RemoveProp32W
0443 stub ReplyMessage
0444 stub ResetDisplay
0445 stub ReuseDDElParam
@@ -490,7 +490,7 @@
0483 stub SetKeyboardState
0484 stub SetLastErrorEx
0485 stub SetLogonNotifyWindow
-0486 stub SetMenu
+0486 stdcall SetMenu(long long) SetMenu
0487 stub SetMenuContextHelpId
0488 stub SetMenuDefaultItem
0489 stub SetMenuItemBitmaps
@@ -500,8 +500,8 @@
0493 stdcall SetMessageQueue(long) SetMessageQueue
0494 stub SetParent
0495 stub SetProcessWindowStation
-0496 stub SetPropA
-0497 stub SetPropW
+0496 stdcall SetPropA(long ptr long) SetProp32A
+0497 stdcall SetPropW(long ptr long) SetProp32W
0498 stdcall SetRect(ptr long long long long) SetRect32
0499 stdcall SetRectEmpty(ptr) SetRectEmpty32
0500 stub SetScrollInfo
@@ -535,7 +535,7 @@
0528 stdcall ShowCaret(long) ShowCaret
0529 stdcall ShowCursor(long) ShowCursor
0530 stub ShowOwnedPopups
-0531 stub ShowScrollBar
+0531 stdcall ShowScrollBar(long long long) ShowScrollBar
0532 stub ShowStartGlass
0533 stdcall ShowWindow(long long) ShowWindow
0534 stub ShowWindowAsync
diff --git a/include/callback.h b/include/callback.h
index 6d2d7aa..d420f76 100644
--- a/include/callback.h
+++ b/include/callback.h
@@ -60,8 +60,8 @@
CallTo16_word_wllwl(func, CURRENT_DS, hdc, lptable, lprecord, objs, lParam)
#define CallEnumObjectsProc( func, lpobj, lParam ) \
CallTo16_word_ll( func, CURRENT_DS, lpobj, lParam )
-#define CallEnumPropProc( func, hwnd, lpstr, data ) \
- CallTo16_word_wlw( func, CURRENT_DS, hwnd, lpstr, data )
+#define CallEnumPropProc16( func, hwnd, lpstr, handle ) \
+ CallTo16_word_wlw( (FARPROC16)(func), CURRENT_DS, hwnd, lpstr, handle )
#define CallEnumTaskWndProc( func, hwnd, lParam ) \
CallTo16_word_wl( func, CURRENT_DS, hwnd, lParam )
#define CallEnumWindowsProc16( func, hwnd, lParam ) \
@@ -100,6 +100,10 @@
CallTo32_0( func )
#define CallDLLEntryProc32( func, hmodule, a, b ) \
CallTo32_3( func, hmodule, a, b )
+#define CallEnumPropProc32( func, hwnd, lpstr, handle ) \
+ CallTo32_3( (FARPROC32)(func), hwnd, (DWORD)(lpstr), handle )
+#define CallEnumPropProcEx32( func, hwnd, lpstr, handle, data ) \
+ CallTo32_4( (FARPROC32)(func), hwnd, (DWORD)(lpstr), handle, data )
#define CallEnumWindowsProc32( func, hwnd, lParam ) \
CallTo32_2( func, hwnd, lParam )
#define CallWndProc32( func, hwnd, msg, wParam, lParam ) \
@@ -122,8 +126,12 @@
(*func)( hdc, lptable, lprecord, objs, lParam)
#define CallEnumObjectsProc( func, lpobj, lParam ) \
(*func)( lpobj, lParam )
-#define CallEnumPropProc( func, hwnd, lpstr, data ) \
- (*func)( hwnd, lpstr, data )
+#define CallEnumPropProc16( func, hwnd, lpstr, handle ) \
+ (*func)( hwnd, lpstr, handle )
+#define CallEnumPropProc32( func, hwnd, lpstr, handle ) \
+ (*func)( hwnd, lpstr, handle )
+#define CallEnumPropProcEx32( func, hwnd, lpstr, handle, data ) \
+ (*func)( hwnd, lpstr, handle, data )
#define CallEnumTaskWndProc( func, hwnd, lParam ) \
(*func)( hwnd, lParam )
#define CallEnumWindowsProc16( func, hwnd, lParam ) \
diff --git a/include/class.h b/include/class.h
index dda909c..418f723 100644
--- a/include/class.h
+++ b/include/class.h
@@ -37,6 +37,5 @@
extern void CLASS_WalkClasses(void);
extern void CLASS_FreeModuleClasses( HMODULE16 hModule );
extern CLASS *CLASS_FindClassByAtom( ATOM atom, HINSTANCE16 hinstance );
-extern CLASS * CLASS_FindClassByName( SEGPTR name, HINSTANCE hinstance );
#endif /* CLASS_H */
diff --git a/include/color.h b/include/color.h
index 03a658b..7cc07e9 100644
--- a/include/color.h
+++ b/include/color.h
@@ -9,8 +9,9 @@
#define COLOR_PRIVATE 0x1000 /* private colormap, identity mapping */
-#define PC_SYS_USED 0x80 /* system peFlags */
-#define PC_SYS_RESERVED 0x40
+#define PC_SYS_USED 0x80 /* palentry is used (both system and logical) */
+#define PC_SYS_RESERVED 0x40 /* system palentry is not to be mapped to */
+#define PC_SYS_MAPPED 0x10 /* logical palentry is a direct alias for system palentry */
extern HPALETTE16 COLOR_Init(void);
extern COLORREF COLOR_ToLogical(int pixel);
@@ -21,6 +22,9 @@
extern UINT16 COLOR_GetSystemPaletteSize();
extern UINT16 COLOR_GetSystemPaletteFlags();
+extern COLORREF COLOR_LookupNearestColor( PALETTEENTRY*, int, COLORREF );
+extern int COLOR_PaletteLookupPixel( PALETTEENTRY*, int, int* , COLORREF, BOOL );
+
extern int COLOR_mapEGAPixel[16];
extern int* COLOR_PaletteToPixel;
extern int* COLOR_PixelToPalette;
diff --git a/include/cursoricon.h b/include/cursoricon.h
index 1555b18..14c34b8 100644
--- a/include/cursoricon.h
+++ b/include/cursoricon.h
@@ -10,6 +10,8 @@
#include <X11/Xlib.h>
#include "windows.h"
+#pragma pack(1)
+
typedef struct
{
BYTE bWidth;
@@ -38,8 +40,6 @@
CURSORDIRENTRY cursor;
} CURSORICONDIRENTRY;
-#pragma pack(1)
-
typedef struct
{
WORD idReserved;
diff --git a/include/dde_mem.h b/include/dde_mem.h
index 3bc8dfa..b2c3079 100644
--- a/include/dde_mem.h
+++ b/include/dde_mem.h
@@ -26,7 +26,7 @@
WORD DDE_SyncHandle(HGLOBAL handle, WORD sel);
void *DDE_malloc(unsigned int flags,unsigned long size, SHMDATA *shmdata);
HANDLE DDE_GlobalReAlloc(WORD,long,WORD);
-HANDLE DDE_GlobalFree(WORD block);
+HGLOBAL DDE_GlobalFree(HGLOBAL block);
void *DDE_AttachHandle(HGLOBAL handle, SEGPTR *segptr);
WORD DDE_GlobalHandleToSel( HGLOBAL handle );
int DDE_GlobalUnlock(int);
diff --git a/include/dde_proc.h b/include/dde_proc.h
index 011d389..29397d7 100644
--- a/include/dde_proc.h
+++ b/include/dde_proc.h
@@ -52,8 +52,8 @@
/* Send ack. to hnd indicating that posted/sent msg. got to destination*/
void dde_proc_send_ack(HWND wnd, BOOL val);
-BOOL DDE_PostMessage( MSG *msg);
-BOOL DDE_SendMessage( MSG *msg);
+BOOL DDE_PostMessage( MSG16 *msg);
+BOOL DDE_SendMessage( MSG16 *msg);
int DDE_GetRemoteMessage();
void DDE_DestroyWindow(HWND hwnd); /* delete DDE info regarding hwnd */
void DDE_TestDDE(HWND hwnd); /* do we have dde handling in the window ?*/
diff --git a/include/heap.h b/include/heap.h
index ee55f9b..e262c09 100644
--- a/include/heap.h
+++ b/include/heap.h
@@ -16,6 +16,7 @@
extern int HEAP_IsInsideHeap( HANDLE32 heap, DWORD flags, LPCVOID ptr );
extern SEGPTR HEAP_GetSegptr( HANDLE32 heap, DWORD flags, LPCVOID ptr );
extern LPSTR HEAP_strdupA( HANDLE32 heap, DWORD flags, LPCSTR str );
+extern LPWSTR HEAP_strdupW( HANDLE32 heap, DWORD flags, LPCWSTR str );
/* SEGPTR helper macros */
diff --git a/include/ldt.h b/include/ldt.h
index 78ab156..f77592a 100644
--- a/include/ldt.h
+++ b/include/ldt.h
@@ -4,8 +4,10 @@
* Copyright 1995 Alexandre Julliard
*/
-#ifndef _WINE_LDT_H
-#define _WINE_LDT_H
+#ifndef __WINE_LDT_H
+#define __WINE_LDT_H
+
+#include "wintypes.h"
enum seg_type
{
@@ -54,17 +56,14 @@
#define GET_SEL_BASE(sel) (ldt_copy[SELECTOR_TO_ENTRY(sel)].base)
#define GET_SEL_LIMIT(sel) (ldt_copy[SELECTOR_TO_ENTRY(sel)].limit)
-#define PTR_SEG_OFF_TO_LIN(seg,off) \
- ((void*)(GET_SEL_BASE(seg) + (unsigned int)(off)))
+/* Convert a segmented ptr (16:16) to a linear (32) pointer */
-#ifndef WINELIB
- /* Convert a segmented ptr (16:16) to a linear (32) pointer */
-#define PTR_SEG_TO_LIN(ptr) PTR_SEG_OFF_TO_LIN(SELECTOROF(ptr),OFFSETOF(ptr))
-#define PTR_SEG_OFF_TO_SEGPTR(seg,off) ((SEGPTR)MAKELONG(off,seg))
-#else
-#define PTR_SEG_TO_LIN(ptr) ((void*)(ptr))
-#define PTR_SEG_OFF_TO_SEGPTR(seg,off) ((SEGPTR)PTR_SEG_OFF_TO_LIN(seg,off))
-#endif
+#define PTR_SEG_OFF_TO_LIN(seg,off) \
+ ((void*)(GET_SEL_BASE(seg) + (unsigned int)(off)))
+#define PTR_SEG_TO_LIN(ptr) \
+ (__winelib ? (void*)(ptr) : PTR_SEG_OFF_TO_LIN(SELECTOROF(ptr),OFFSETOF(ptr)))
+#define PTR_SEG_OFF_TO_SEGPTR(seg,off) \
+ (__winelib ? (SEGPTR)PTR_SEG_OFF_TO_LIN(seg,off) : (SEGPTR)MAKELONG(off,seg))
extern unsigned char ldt_flags_copy[LDT_SIZE];
@@ -77,4 +76,4 @@
#define GET_SEL_FLAGS(sel) (ldt_flags_copy[SELECTOR_TO_ENTRY(sel)])
-#endif /* _WINE_LDT_H */
+#endif /* __WINE_LDT_H */
diff --git a/include/listbox.h b/include/listbox.h
index cdd82cb..8b9130f 100644
--- a/include/listbox.h
+++ b/include/listbox.h
@@ -47,7 +47,7 @@
extern LPLISTSTRUCT ListBoxGetItem(LPHEADLIST lphl, UINT uIndex);
extern int ListMaxFirstVisible(LPHEADLIST lphl);
extern int ListBoxScrollToFocus(LPHEADLIST lphl);
-extern int ListBoxAddString(LPHEADLIST lphl, LPCSTR newstr);
+extern int ListBoxAddString(LPHEADLIST lphl, SEGPTR itemData);
extern int ListBoxInsertString(LPHEADLIST lphl, UINT uIndex, LPCSTR newstr);
extern int ListBoxGetText(LPHEADLIST lphl, UINT uIndex, LPSTR OutStr);
extern DWORD ListBoxGetItemData(LPHEADLIST lphl, UINT uIndex);
diff --git a/include/miscemu.h b/include/miscemu.h
index 90b9184..c876e60 100644
--- a/include/miscemu.h
+++ b/include/miscemu.h
@@ -16,6 +16,11 @@
extern void DOSMEM_Tick(void);
extern void DOSMEM_FillBiosSegment(void);
extern HANDLE16 DOSMEM_BiosSeg;
+extern void DOSMEM_InitMemoryHandling();
+extern LPVOID DOSMEM_RealMode2Linear(DWORD);
+extern WORD DOSMEM_AllocSelector(WORD);
+extern DWORD DOSMEM_CollateTable;
+extern void DOSMEM_InitCollateTable();
/* miscemu/instr.c */
extern BOOL32 INSTR_EmulateInstruction( SIGCONTEXT *context );
diff --git a/include/palette.h b/include/palette.h
index ce4519b..1bdef2f 100644
--- a/include/palette.h
+++ b/include/palette.h
@@ -15,8 +15,8 @@
typedef struct
{
GDIOBJHDR header;
- LOGPALETTE logpalette WINE_PACKED;
- int *mapping;
+ int *mapping WINE_PACKED;
+ LOGPALETTE logpalette WINE_PACKED; /* _MUST_ be the last field */
} PALETTEOBJ;
#pragma pack(4)
diff --git a/include/task.h b/include/task.h
index 2881c70..f7c92a5 100644
--- a/include/task.h
+++ b/include/task.h
@@ -81,7 +81,9 @@
DWORD int3e WINE_PACKED; /* 46 int 3e (80x87 emu) handler */
DWORD int75 WINE_PACKED; /* 4a int 75 (80x87 error) handler */
DWORD compat_flags WINE_PACKED; /* 4e Compatibility flags */
- BYTE unused4[14]; /* 52 */
+ BYTE unused4[10]; /* 52 */
+ WORD switchStackSS; /* 5c Saved %ss for SwitchStackTo */
+ WORD switchStackSP; /* 5e Saved %sp for SwitchStackTo */
HANDLE16 hPDB; /* 60 Selector of PDB (i.e. PSP) */
SEGPTR dta WINE_PACKED; /* 62 Current DTA */
BYTE curdrive; /* 66 Current drive */
diff --git a/include/win.h b/include/win.h
index 37938c1..3c95981 100644
--- a/include/win.h
+++ b/include/win.h
@@ -47,17 +47,17 @@
LPSTR text; /* Window text */
void *pVScroll; /* Vertical scroll-bar info */
void *pHScroll; /* Horizontal scroll-bar info */
- HGLOBAL hmemTaskQ; /* Task queue global memory handle */
- HRGN hrgnUpdate; /* Update region */
- HWND hwndLastActive;/* Last active popup hwnd */
+ void *pProp; /* Pointer to properties list */
+ HGLOBAL16 hmemTaskQ; /* Task queue global memory handle */
+ HRGN16 hrgnUpdate; /* Update region */
+ HWND16 hwndLastActive;/* Last active popup hwnd */
DWORD dwStyle; /* Window style (from CreateWindow) */
DWORD dwExStyle; /* Extended style (from CreateWindowEx) */
- HANDLE hdce; /* Window DCE (if CS_OWNDC or CS_CLASSDC) */
- UINT wIDmenu; /* ID or hmenu (from CreateWindow) */
+ HANDLE16 hdce; /* Window DCE (if CS_OWNDC or CS_CLASSDC) */
+ UINT16 wIDmenu; /* ID or hmenu (from CreateWindow) */
WORD flags; /* Misc. flags (see below) */
Window window; /* X window (only for top-level windows) */
- HMENU hSysMenu; /* window's copy of System Menu */
- HANDLE hProp; /* Handle of Properties List */
+ HMENU16 hSysMenu; /* window's copy of System Menu */
DWORD userdata; /* User private data */
DWORD wExtra[1]; /* Window extra bytes */
} WND;
@@ -75,23 +75,25 @@
#define WIN_ISDIALOG 0x0200 /* Window is a dialog */
/* Window functions */
-extern WND *WIN_FindWndPtr( HWND hwnd );
+extern WND *WIN_FindWndPtr( HWND32 hwnd );
extern WND *WIN_GetDesktop(void);
-extern void WIN_DumpWindow( HWND hwnd );
-extern void WIN_WalkWindows( HWND hwnd, int indent );
-extern Window WIN_GetXWindow( HWND hwnd );
-extern BOOL WIN_UnlinkWindow( HWND hwnd );
-extern BOOL WIN_LinkWindow( HWND hwnd, HWND hwndInsertAfter );
-extern HWND WIN_FindWinToRepaint( HWND hwnd, HQUEUE hQueue );
-extern void WIN_SendParentNotify( HWND hwnd, WORD event,
+extern void WIN_DumpWindow( HWND32 hwnd );
+extern void WIN_WalkWindows( HWND32 hwnd, int indent );
+extern Window WIN_GetXWindow( HWND32 hwnd );
+extern BOOL32 WIN_UnlinkWindow( HWND32 hwnd );
+extern BOOL32 WIN_LinkWindow( HWND32 hwnd, HWND32 hwndInsertAfter );
+extern HWND32 WIN_FindWinToRepaint( HWND32 hwnd, HQUEUE16 hQueue );
+extern void WIN_SendParentNotify( HWND32 hwnd, WORD event,
WORD idChild, LONG lValue );
-extern BOOL WIN_CreateDesktopWindow(void);
-extern HWND WIN_GetTopParent( HWND hwnd );
-extern HINSTANCE WIN_GetWindowInstance( HWND hwnd );
+extern BOOL32 WIN_CreateDesktopWindow(void);
+extern HWND32 WIN_GetTopParent( HWND32 hwnd );
+extern HINSTANCE16 WIN_GetWindowInstance( HWND32 hwnd );
extern WND **WIN_BuildWinArray( WND *wndPtr );
extern void DEFWND_SetText( WND *wndPtr, LPCSTR text ); /* windows/defwnd.c */
+extern void PROPERTY_RemoveWindowProps( WND *pWnd ); /* windows/property.c */
+
extern Display * display;
extern Screen * screen;
extern Window rootWindow;
diff --git a/include/windows.h b/include/windows.h
index 396942a..767363a 100644
--- a/include/windows.h
+++ b/include/windows.h
@@ -1486,6 +1486,9 @@
#define DRIVE_REMOVABLE 2
#define DRIVE_FIXED 3
#define DRIVE_REMOTE 4
+/* Win32 additions */
+#define DRIVE_CDROM 5
+#define DRIVE_RAMDISK 6
#define HFILE_ERROR -1
@@ -1592,15 +1595,20 @@
#define SETDTR 5
#define CLRDTR 6
#define RESETDEV 7
+/* win16 only */
#define GETMAXLPT 8
#define GETMAXCOM 9
+/* win32 only */
+#define SETBREAK 8
+#define CLRBREAK 9
+
#define GETBASEIRQ 10
#define CN_RECEIVE 0x0001
#define CN_TRANSMIT 0x0002
#define CN_EVENT 0x0004
-typedef struct tagDCB
+typedef struct tagDCB16
{
BYTE Id;
UINT16 BaudRate WINE_PACKED;
@@ -1636,14 +1644,65 @@
CHAR EofChar;
CHAR EvtChar;
UINT16 TxDelay WINE_PACKED;
-} DCB, *LPDCB;
+} DCB16, *LPDCB16;
+
+typedef struct tagDCB32
+{
+ DWORD DCBlength;
+ DWORD BaudRate;
+ DWORD fBinary :1;
+ DWORD fParity :1;
+ DWORD fOutxCtsFlow :1;
+ DWORD fOutxDsrFlow :1;
+ DWORD fDtrControl :2;
+ DWORD fDsrSensitivity :1;
+ DWORD fTXContinueOnXoff :1;
+ DWORD fOutX :1;
+ DWORD fInX :1;
+ DWORD fErrorChar :1;
+ DWORD fNull :1;
+ DWORD fRtsControl :2;
+ DWORD fAbortOnError :1;
+ DWORD fDummy2 :17;
+ WORD wReserved;
+ WORD XonLim;
+ WORD XoffLim;
+ BYTE ByteSize;
+ BYTE Parity;
+ BYTE StopBits;
+ char XonChar;
+ char XoffChar;
+ char ErrorChar;
+ char EofChar;
+ char EvtChar;
+} DCB32, *LPDCB32;
+
+DECL_WINELIB_TYPE(DCB);
+DECL_WINELIB_TYPE(LPDCB);
+
+#define RTS_CONTROL_DISABLE 0
+#define RTS_CONTROL_ENABLE 1
+#define RTS_CONTROL_HANDSHAKE 2
+#define RTS_CONTROL_TOGGLE 3
+
+#define DTR_CONTROL_DISABLE 0
+#define DTR_CONTROL_ENABLE 1
+#define DTR_CONTROL_HANDSHAKE 2
+
+typedef struct tagCOMMTIMEOUTS {
+ DWORD ReadIntervalTimeout;
+ DWORD ReadTotalTimeoutMultiplier;
+ DWORD ReadTotalTimeoutConstant;
+ DWORD WriteTotalTimeoutMultiplier;
+ DWORD WriteTotalTimeoutConstant;
+} COMMTIMEOUTS,*LPCOMMTIMEOUTS;
typedef struct tagCOMSTAT
{
BYTE status;
UINT16 cbInQue WINE_PACKED;
UINT16 cbOutQue WINE_PACKED;
-} COMSTAT;
+} COMSTAT,*LPCOMSTAT;
#define CSTF_CTSHOLD 0x01
#define CSTF_DSRHOLD 0x02
@@ -3179,6 +3238,31 @@
DWORD BatteryFullLifeTime;
} SYSTEM_POWER_STATUS, *LPSYSTEM_POWER_STATUS;
+/* flags to FormatMessage */
+#define FORMAT_MESSAGE_ALLOCATE_BUFFER 0x00000100
+#define FORMAT_MESSAGE_IGNORE_INSERTS 0x00000200
+#define FORMAT_MESSAGE_FROM_STRING 0x00000400
+#define FORMAT_MESSAGE_FROM_HMODULE 0x00000800
+#define FORMAT_MESSAGE_FROM_SYSTEM 0x00001000
+#define FORMAT_MESSAGE_ARGUMENT_ARRAY 0x00002000
+#define FORMAT_MESSAGE_MAX_WIDTH_MASK 0x000000FF
+
+/* types of LoadImage */
+#define IMAGE_BITMAP 0
+#define IMAGE_ICON 1
+#define IMAGE_CURSOR 2
+#define IMAGE_ENHMETA 3
+
+/* loadflags to LoadImage */
+#define LR_DEFAULTCOLOR 0x0000
+#define LR_MONOCHROME 0x0001
+#define LR_COPYRETURNONORG 0x0002
+#define LR_COPYDELETEORC 0x0004
+#define LR_COPYFROMRESOURCE 0x0008
+#define LR_LOADFROMFILE 0x0010
+#define LR_LOADREALSIZE 0x0020
+#define LR_LOADMAP3DCOLORS 0x1000
+
#pragma pack(4)
/* Declarations for functions that exist only in Win16 */
@@ -3186,11 +3270,15 @@
WORD AllocSelector(WORD);
WORD AllocSelectorArray(WORD);
INT16 Catch(LPCATCHBUF);
+INT16 CloseComm(INT16);
HANDLE16 FarGetOwner(HGLOBAL16);
VOID FarSetOwner(HGLOBAL16,HANDLE16);
VOID FillWindow(HWND16,HWND16,HDC16,HBRUSH16);
+INT16 FlushComm(INT16,INT16);
WORD FreeSelector(WORD);
DWORD GetBitmapDimension(HBITMAP16);
+INT16 GetCommError(INT16,LPCOMSTAT);
+UINT16 GetCommEventMask(INT16,UINT16);
HTASK16 GetCurrentTask(void);
HMODULE16 GetExePtr(HANDLE16);
HINSTANCE16 GetTaskDS(void);
@@ -3198,22 +3286,33 @@
BOOL16 LocalInit(HANDLE16,WORD,WORD);
DWORD OffsetViewportOrg(HDC16,INT16,INT16);
DWORD OffsetWindowOrg(HDC16,INT16,INT16);
+INT16 OpenComm(LPCSTR,UINT16,UINT16);
VOID PaintRect(HWND16,HWND16,HDC16,HBRUSH16,const RECT16*);
+INT16 ReadComm(INT16,LPSTR,INT16);
DWORD ScaleViewportExt(HDC16,INT16,INT16,INT16,INT16);
DWORD ScaleWindowExt(HDC16,INT16,INT16,INT16,INT16);
DWORD SetBitmapDimension(HBITMAP16,INT16,INT16);
+DWORD SetBrushOrg(HDC16,INT16,INT16);
+UINT16* SetCommEventMask(INT16,UINT16);
DWORD SetViewportExt(HDC16,INT16,INT16);
DWORD SetViewportOrg(HDC16,INT16,INT16);
DWORD SetWindowExt(HDC16,INT16,INT16);
DWORD SetWindowOrg(HDC16,INT16,INT16);
INT16 Throw(LPCATCHBUF,INT16);
+INT16 UngetCommChar(INT16,CHAR);
+INT16 WriteComm(INT16,LPSTR,INT16);
VOID hmemcpy(LPVOID,LPCVOID,LONG);
/* Declarations for functions that exist only in Win32 */
BOOL32 Beep(DWORD,DWORD);
+BOOL32 ClearCommError(HANDLE32,LPDWORD,LPCOMSTAT);
+INT32 EnumPropsEx32A(HWND32,PROPENUMPROCEX32A,LPARAM);
+INT32 EnumPropsEx32W(HWND32,PROPENUMPROCEX32W,LPARAM);
+#define EnumPropsEx WINELIB_NAME_AW(EnumPropsEx)
BOOL32 EnumThreadWindows(DWORD,WNDENUMPROC32,LPARAM);
BOOL32 FlushFileBuffers(HFILE);
+BOOL32 GetCommTimeouts(HANDLE32,LPCOMMTIMEOUTS);
DWORD GetLogicalDrives(void);
HANDLE32 GetProcessHeap(void);
LPVOID HeapAlloc(HANDLE32,DWORD,DWORD);
@@ -3227,9 +3326,31 @@
BOOL32 HeapUnlock(HANDLE32);
BOOL32 HeapValidate(HANDLE32,DWORD,LPVOID);
BOOL32 IsWindowUnicode(HWND32);
+DWORD RegCreateKeyEx32A(HKEY,LPCSTR,DWORD,LPSTR,DWORD,REGSAM,
+ LPSECURITY_ATTRIBUTES,LPHKEY,LPDWORD);
+DWORD RegCreateKeyEx32W(HKEY,LPCWSTR,DWORD,LPWSTR,DWORD,REGSAM,
+ LPSECURITY_ATTRIBUTES,LPHKEY,LPDWORD);
+#define RegCreateKeyEx WINELIB_NAME_AW(RegCreateKeyEx)
+DWORD RegEnumKeyEx32A(HKEY,DWORD,LPSTR,LPDWORD,LPDWORD,LPSTR,LPDWORD,FILETIME*);
+DWORD RegEnumKeyEx32W(HKEY,DWORD,LPWSTR,LPDWORD,LPDWORD,LPWSTR,LPDWORD,FILETIME*);
+#define RegEnumKeyEx WINELIB_NAME_AW(RegEnumKeyEx)
+DWORD RegOpenKeyEx32W(HKEY,LPCWSTR,DWORD,REGSAM,LPHKEY);
+DWORD RegOpenKeyEx32A(HKEY,LPCSTR,DWORD,REGSAM,LPHKEY);
+#define RegOpenKeyEx WINELIB_NAME_AW(RegOpenKeyEx)
+DWORD RegQueryInfoKey32W(HKEY,LPWSTR,LPDWORD,LPDWORD,LPDWORD,LPDWORD,
+ LPDWORD,LPDWORD,LPDWORD,LPDWORD,LPDWORD,FILETIME*);
+DWORD RegQueryInfoKey32A(HKEY,LPSTR,LPDWORD,LPDWORD,LPDWORD,LPDWORD,
+ LPDWORD,LPDWORD,LPDWORD,LPDWORD,LPDWORD,FILETIME*);
+#define RegQueryInfoKey WINELIB_NAME_AW(RegQueryInfoKey)
VOID RtlFillMemory(LPVOID,UINT32,UINT32);
VOID RtlMoveMemory(LPVOID,LPCVOID,UINT32);
VOID RtlZeroMemory(LPVOID,UINT32);
+DWORD SearchPath32A(LPCSTR,LPCSTR,LPCSTR,DWORD,LPSTR,LPSTR*);
+DWORD SearchPath32W(LPCWSTR,LPCWSTR,LPCWSTR,DWORD,LPWSTR,LPWSTR*);
+#define SearchPath WINELIB_NAME(SearchPath)
+BOOL32 SetCommMask(HANDLE32,DWORD);
+BOOL32 SetCommTimeouts(HANDLE32,LPCOMMTIMEOUTS);
+BOOL32 SetBrushOrgEx(HDC32,INT32,INT32,LPPOINT32);
LPVOID VirtualAlloc(LPVOID,DWORD,DWORD,DWORD);
BOOL32 VirtualFree(LPVOID,DWORD,DWORD);
@@ -3307,6 +3428,13 @@
HDC16 BeginPaint16(HWND16,LPPAINTSTRUCT16);
HDC32 BeginPaint32(HWND32,LPPAINTSTRUCT32);
#define BeginPaint WINELIB_NAME(BeginPaint)
+BOOL16 BuildCommDCB16(LPCSTR,LPDCB16);
+BOOL32 BuildCommDCB32A(LPCSTR,LPDCB32);
+BOOL32 BuildCommDCB32W(LPCWSTR,LPDCB32);
+#define BuildCommDCB WINELIB_NAME_AW(BuildCommDCB)
+BOOL32 BuildCommDCBAndTimeouts32A(LPCSTR,LPDCB32,LPCOMMTIMEOUTS);
+BOOL32 BuildCommDCBAndTimeouts32W(LPCWSTR,LPDCB32,LPCOMMTIMEOUTS);
+#define BuildCommDCBAndTimeouts WINELIB_NAME_AW(BuildCommDCBAndTimeouts)
LRESULT CallWindowProc16(WNDPROC16,HWND16,UINT16,WPARAM16,LPARAM);
LRESULT CallWindowProc32A(WNDPROC32,HWND32,UINT32,WPARAM32,LPARAM);
LRESULT CallWindowProc32W(WNDPROC32,HWND32,UINT32,WPARAM32,LPARAM);
@@ -3348,6 +3476,9 @@
HWND16 ChildWindowFromPoint16(HWND16,POINT16);
HWND32 ChildWindowFromPoint32(HWND32,POINT32);
#define ChildWindowFromPoint WINELIB_NAME(ChildWindowFromPoint)
+INT16 ClearCommBreak16(INT16);
+BOOL32 ClearCommBreak32(HANDLE32);
+#define ClearCommBreak WINELIB_NAME(ClearCommBreak)
BOOL16 ClientToScreen16(HWND16,LPPOINT16);
BOOL32 ClientToScreen32(HWND32,LPPOINT32);
#define ClientToScreen WINELIB_NAME(ClientToScreen)
@@ -3494,6 +3625,10 @@
BOOL16 EnumChildWindows16(HWND16,WNDENUMPROC16,LPARAM);
BOOL32 EnumChildWindows32(HWND32,WNDENUMPROC32,LPARAM);
#define EnumChildWindows WINELIB_NAME(EnumChildWindows)
+INT16 EnumProps16(HWND16,PROPENUMPROC16);
+INT32 EnumProps32A(HWND32,PROPENUMPROC32A);
+INT32 EnumProps32W(HWND32,PROPENUMPROC32W);
+#define EnumProps WINELIB_NAME_AW(EnumProps)
BOOL16 EnumTaskWindows16(HTASK16,WNDENUMPROC16,LPARAM);
#define EnumTaskWindows32(handle,proc,lparam) \
EnumThreadWindows(handle,proc,lparam)
@@ -3504,6 +3639,9 @@
BOOL16 EqualRect16(const RECT16*,const RECT16*);
BOOL32 EqualRect32(const RECT32*,const RECT32*);
#define EqualRect WINELIB_NAME(EqualRect)
+LONG EscapeCommFunction16(UINT16,UINT16);
+BOOL32 EscapeCommFunction32(HANDLE32,UINT32);
+#define EscapeCommFunction WINELIB_NAME(EscapeCommFunction)
BOOL16 ExtTextOut16(HDC16,INT16,INT16,UINT16,const RECT16*,LPCSTR,UINT16,const INT16*);
BOOL32 ExtTextOut32A(HDC32,INT32,INT32,UINT32,const RECT32*,LPCSTR,UINT32,const INT32*);
BOOL32 ExtTextOut32W(HDC32,INT32,INT32,UINT32,const RECT32*,LPCWSTR,UINT32,const INT32*);
@@ -3572,6 +3710,9 @@
void GetClipCursor16(LPRECT16);
void GetClipCursor32(LPRECT32);
#define GetClipCursor WINELIB_NAME(GetClipCursor)
+INT16 GetCommState16(INT16,LPDCB16);
+BOOL32 GetCommState32(HANDLE32,LPDCB32);
+#define GetCommState WINELIB_NAME(GetCommState)
UINT16 GetCurrentDirectory16(UINT16,LPSTR);
UINT32 GetCurrentDirectory32A(UINT32,LPSTR);
UINT32 GetCurrentDirectory32W(UINT32,LPWSTR);
@@ -3619,6 +3760,10 @@
FARPROC16 GetProcAddress16(HMODULE16,SEGPTR);
FARPROC32 GetProcAddress32(HMODULE32,LPCSTR);
#define GetProcAddress WINELIB_NAME(GetProcAddress)
+HANDLE16 GetProp16(HWND16,LPCSTR);
+HANDLE32 GetProp32A(HWND32,LPCSTR);
+HANDLE32 GetProp32W(HWND32,LPCWSTR);
+#define GetProp WINELIB_NAME_AW(GetProp)
INT16 GetRgnBox16(HRGN16,LPRECT16);
INT32 GetRgnBox32(HRGN32,LPRECT32);
#define GetRgnBox WINELIB_NAME(GetRgnBox)
@@ -3902,12 +4047,6 @@
DWORD RegCreateKey32A(HKEY,LPCSTR,LPHKEY);
DWORD RegCreateKey32W(HKEY,LPCWSTR,LPHKEY);
#define RegCreateKey WINELIB_NAME_AW(RegCreateKey)
-DWORD RegCreateKeyEx32A(HKEY,LPCSTR,DWORD,LPSTR,DWORD,REGSAM,
- LPSECURITY_ATTRIBUTES,LPHKEY,LPDWORD);
-DWORD RegCreateKeyEx32W(HKEY,LPCWSTR,DWORD,LPWSTR,DWORD,REGSAM,
- LPSECURITY_ATTRIBUTES,LPHKEY,LPDWORD);
-/* there is no RegCreateKeyEx16 */
-#define RegCreateKeyEx WINELIB_NAME_AW(RegCreateKeyEx)
DWORD RegDeleteKey16(HKEY,LPCSTR);
DWORD RegDeleteKey32A(HKEY,LPCSTR);
DWORD RegDeleteKey32W(HKEY,LPWSTR);
@@ -3920,10 +4059,6 @@
DWORD RegEnumKey32A(HKEY,DWORD,LPSTR,DWORD);
DWORD RegEnumKey32W(HKEY,DWORD,LPWSTR,DWORD);
#define RegEnumKey WINELIB_NAME_AW(RegEnumKey)
-DWORD RegEnumKeyEx32A(HKEY,DWORD,LPSTR,LPDWORD,LPDWORD,LPSTR,LPDWORD,FILETIME*);
-DWORD RegEnumKeyEx32W(HKEY,DWORD,LPWSTR,LPDWORD,LPDWORD,LPWSTR,LPDWORD,FILETIME*);
-/* there is no RegEnumKeyEx16 */
-#define RegEnumKeyEx WINELIB_NAME_AW(RegEnumKeyEx)
DWORD RegEnumValue16(HKEY,DWORD,LPSTR,LPDWORD,LPDWORD,LPDWORD,LPBYTE,LPDWORD);
DWORD RegEnumValue32A(HKEY,DWORD,LPSTR,LPDWORD,LPDWORD,LPDWORD,LPBYTE,LPDWORD);
DWORD RegEnumValue32W(HKEY,DWORD,LPWSTR,LPDWORD,LPDWORD,LPDWORD,LPBYTE,LPDWORD);
@@ -3944,16 +4079,6 @@
DWORD RegOpenKey32A(HKEY,LPCSTR,LPHKEY);
DWORD RegOpenKey32W(HKEY,LPCWSTR,LPHKEY);
#define RegOpenKey WINELIB_NAME_AW(RegOpenKey)
-DWORD RegOpenKeyEx32W(HKEY,LPCWSTR,DWORD,REGSAM,LPHKEY);
-DWORD RegOpenKeyEx32A(HKEY,LPCSTR,DWORD,REGSAM,LPHKEY);
-/* there is no RegOpenKeyEx16 */
-#define RegOpenKeyEx WINELIB_NAME_AW(RegOpenKeyEx)
-DWORD RegQueryInfoKey32W(HKEY,LPWSTR,LPDWORD,LPDWORD,LPDWORD,LPDWORD,
- LPDWORD,LPDWORD,LPDWORD,LPDWORD,LPDWORD,FILETIME*);
-DWORD RegQueryInfoKey32A(HKEY,LPSTR,LPDWORD,LPDWORD,LPDWORD,LPDWORD,
- LPDWORD,LPDWORD,LPDWORD,LPDWORD,LPDWORD,FILETIME*);
-/* there is no RegQueryInfoKey16 */
-#define RegQueryInfoKey WINELIB_NAME_AW(RegQueryInfoKey)
DWORD RegQueryValue16(HKEY,LPSTR,LPSTR,LPDWORD);
DWORD RegQueryValue32A(HKEY,LPSTR,LPSTR,LPDWORD);
DWORD RegQueryValue32W(HKEY,LPWSTR,LPWSTR,LPDWORD);
@@ -3970,6 +4095,10 @@
DWORD RegSetValueEx32A(HKEY,LPSTR,DWORD,DWORD,LPBYTE,DWORD);
DWORD RegSetValueEx32W(HKEY,LPWSTR,DWORD,DWORD,LPBYTE,DWORD);
#define RegSetValueEx WINELIB_NAME_AW(RegSetValueEx)
+HANDLE16 RemoveProp16(HWND16,LPCSTR);
+HANDLE32 RemoveProp32A(HWND32,LPCSTR);
+HANDLE32 RemoveProp32W(HWND32,LPCWSTR);
+#define RemoveProp WINELIB_NAME_AW(RemoveProp)
BOOL16 RemoveDirectory16(LPCSTR);
BOOL32 RemoveDirectory32A(LPCSTR);
BOOL32 RemoveDirectory32W(LPCWSTR);
@@ -3998,6 +4127,12 @@
LONG SetClassLong32A(HWND32,INT32,LONG);
LONG SetClassLong32W(HWND32,INT32,LONG);
#define SetClassLong WINELIB_NAME_AW(SetClassLong)
+INT16 SetCommBreak16(INT16);
+BOOL32 SetCommBreak32(HANDLE32);
+#define SetCommBreak WINELIB_NAME(SetCommBreak)
+INT16 SetCommState16(LPDCB16);
+BOOL32 SetCommState32(HANDLE32,LPDCB32);
+#define SetCommState WINELIB_NAME(SetCommState)
void SetDlgItemInt16(HWND16,INT16,UINT16,BOOL16);
void SetDlgItemInt32(HWND32,INT32,UINT32,BOOL32);
#define SetDlgItemInt WINELIB_NAME(SetDlgItemInt)
@@ -4011,6 +4146,10 @@
void SetInternalWindowPos16(HWND16,UINT16,LPRECT16,LPPOINT16);
void SetInternalWindowPos32(HWND32,UINT32,LPRECT32,LPPOINT32);
#define SetInternalWindowPos WINELIB_NAME(SetInternalWindowPos)
+BOOL16 SetProp16(HWND16,LPCSTR,HANDLE16);
+BOOL32 SetProp32A(HWND32,LPCSTR,HANDLE32);
+BOOL32 SetProp32W(HWND32,LPCWSTR,HANDLE32);
+#define SetProp WINELIB_NAME_AW(SetProp)
void SetRect16(LPRECT16,INT16,INT16,INT16,INT16);
void SetRect32(LPRECT32,INT32,INT32,INT32,INT32);
#define SetRect WINELIB_NAME(SetRect)
@@ -4059,6 +4198,9 @@
BOOL16 TrackPopupMenu16(HMENU16,UINT16,INT16,INT16,INT16,HWND16,const RECT16*);
BOOL32 TrackPopupMenu32(HMENU32,UINT32,INT32,INT32,INT32,HWND32,const RECT32*);
#define TrackPopupMenu WINELIB_NAME(TrackPopupMenu)
+INT16 TransmitCommChar16(INT16,CHAR);
+BOOL32 TransmitCommChar32(HANDLE32,CHAR);
+#define TransmitCommChar WINELIB_NAME(TransmitCommChar)
BOOL16 UnionRect16(LPRECT16,const RECT16*,const RECT16*);
BOOL32 UnionRect32(LPRECT32,const RECT32*,const RECT32*);
#define UnionRect WINELIB_NAME(UnionRect)
@@ -4222,14 +4364,12 @@
typedef int (*GOBJENUMPROC)(LPVOID,LPARAM);
/*typedef int (*MFENUMPROC)(HDC,HANDLETABLE*,METARECORD*,int,LPARAM);*/
typedef int (*MFENUMPROC)(HDC,void*,void*,int,LPARAM);
-typedef BOOL (*PROPENUMPROC)(HWND,LPCSTR,HANDLE);
#else
typedef SEGPTR DRIVERPROC;
typedef SEGPTR EDITWORDBREAKPROC;
typedef SEGPTR FONTENUMPROC;
typedef SEGPTR GOBJENUMPROC;
typedef SEGPTR MFENUMPROC;
-typedef SEGPTR PROPENUMPROC;
#endif
ATOM AddAtom(SEGPTR);
@@ -4251,7 +4391,6 @@
HDWP16 BeginDeferWindowPos(INT);
BOOL BitBlt(HDC,INT,INT,INT,INT,HDC,INT,INT,DWORD);
BOOL BringWindowToTop(HWND);
-BOOL BuildCommDCB(LPCSTR,DCB*);
void CalcChildScroll(HWND,WORD);
BOOL CallMsgFilter(SEGPTR,INT);
LRESULT CallNextHookEx(HHOOK,INT,WPARAM,LPARAM);
@@ -4259,9 +4398,7 @@
WORD ChangeSelector(WORD,WORD);
INT CheckMenuItem(HMENU,UINT,UINT);
BOOL Chord(HDC,INT,INT,INT,INT,INT,INT,INT,INT);
-int ClearCommBreak(int);
BOOL CloseClipboard(void);
-int CloseComm(int);
HMETAFILE CloseMetaFile(HDC);
void CloseSound(void);
BOOL CloseWindow(HWND);
@@ -4322,9 +4459,7 @@
INT EnumFonts(HDC,LPCSTR,FONTENUMPROC,LPARAM);
BOOL EnumMetaFile(HDC,HMETAFILE,MFENUMPROC,LPARAM);
INT EnumObjects(HDC,INT,GOBJENUMPROC,LPARAM);
-INT EnumProps(HWND,PROPENUMPROC);
INT Escape(HDC,INT,INT,LPCSTR,LPVOID);
-LONG EscapeCommFunction(int,int);
int ExcludeClipRect(HDC,short,short,short,short);
int ExcludeVisRect(HDC,short,short,short,short);
BOOL ExitWindows(DWORD,WORD);
@@ -4335,7 +4470,6 @@
ATOM FindAtom(SEGPTR);
HINSTANCE FindExecutable(LPCSTR,LPCSTR,LPSTR);
BOOL FlashWindow(HWND,BOOL);
-int FlushComm(int,int);
BOOL FrameRgn(HDC,HRGN,HBRUSH,int,int);
void FreeLibrary(HANDLE);
UINT GDIRealizePalette(HDC);
@@ -4358,9 +4492,6 @@
HWND GetClipboardViewer(void);
HANDLE GetCodeHandle(FARPROC16);
void GetCodeInfo(FARPROC16,LPVOID);
-int GetCommError(int,COMSTAT*);
-UINT GetCommEventMask(int,int);
-int GetCommState(int,DCB*);
HBRUSH GetControlBrush(HWND,HDC,WORD);
HANDLE GetCurrentPDB(void);
DWORD GetCurrentPosition(HDC);
@@ -4427,7 +4558,6 @@
INT GetPrivateProfileString(LPCSTR,LPCSTR,LPCSTR,LPSTR,INT,LPCSTR);
UINT GetProfileInt(LPCSTR,LPCSTR,INT);
INT GetProfileString(LPCSTR,LPCSTR,LPCSTR,LPSTR,INT);
-HANDLE GetProp(HWND,SEGPTR);
DWORD GetQueueStatus(UINT);
BOOL GetRasterizerCaps(LPRASTERIZER_STATUS,UINT);
WORD GetROP2(HDC);
@@ -4524,7 +4654,6 @@
void OemToAnsiBuff(LPCSTR,LPSTR,INT);
int OffsetClipRgn(HDC,short,short);
BOOL OpenClipboard(HWND);
-int OpenComm(LPCSTR,UINT,UINT);
BOOL OpenIcon(HWND);
int OpenSound(void);
void OutputDebugString(LPCSTR);
@@ -4547,7 +4676,6 @@
void ProfStart(void);
void ProfStop(void);
BOOL PtVisible(HDC,short,short);
-int ReadComm(int,LPSTR,int);
WORD RealizeDefaultPalette(HDC);
BOOL Rectangle(HDC,INT,INT,INT,INT);
WORD RegisterClipboardFormat(LPCSTR);
@@ -4555,7 +4683,6 @@
int ReleaseDC(HWND,HDC);
BOOL RemoveFontResource(LPSTR);
BOOL RemoveMenu(HMENU,UINT,UINT);
-HANDLE RemoveProp(HWND,SEGPTR);
void ReplyMessage(LRESULT);
HDC ResetDC(HDC,LPVOID);
BOOL ResizePalette(HPALETTE16,UINT);
@@ -4576,13 +4703,9 @@
HWND SetActiveWindow(HWND);
DWORD SetBkColor(HDC,COLORREF);
WORD SetBkMode(HDC,WORD);
-DWORD SetBrushOrg(HDC,short,short);
HWND SetCapture(HWND);
HANDLE SetClipboardData(WORD,HANDLE);
HWND SetClipboardViewer(HWND);
-int SetCommBreak(int);
-UINT* SetCommEventMask(int,UINT);
-int SetCommState(DCB*);
void SetConvertHook(BOOL);
BOOL SetConvertParams(int,int);
BOOL32 SetCurrentDirectory(LPCSTR);
@@ -4609,7 +4732,6 @@
HWND SetParent(HWND,HWND);
COLORREF SetPixel(HDC,short,short,COLORREF);
WORD SetPolyFillMode(HDC,WORD);
-BOOL SetProp(HWND,SEGPTR,HANDLE);
WORD SetROP2(HDC,WORD);
WORD SetRelAbs(HDC,WORD);
FARPROC16 SetResourceHandler(HANDLE,LPSTR,FARPROC16);
@@ -4661,8 +4783,6 @@
int TranslateAccelerator(HWND,HANDLE,LPMSG16);
BOOL TranslateMDISysAccel(HWND,LPMSG16);
BOOL TranslateMessage(LPMSG16);
-int TransmitCommChar(int,char);
-int UngetCommChar(int,char);
BOOL UnhookWindowsHook(short,HOOKPROC16);
BOOL UnhookWindowsHookEx(HHOOK);
BOOL UnrealizeObject(HBRUSH);
@@ -4680,7 +4800,6 @@
int WaitSoundState(int);
HANDLE WinExec(LPSTR,WORD);
BOOL WinHelp(HWND,LPSTR,WORD,DWORD);
-int WriteComm(int,LPSTR,int);
void WriteOutProfiles(void);
BOOL WritePrivateProfileString(LPCSTR,LPCSTR,LPCSTR,LPCSTR);
BOOL WriteProfileString(LPCSTR,LPCSTR,LPCSTR);
diff --git a/include/wintypes.h b/include/wintypes.h
index 5a61ec9..389a9fe 100644
--- a/include/wintypes.h
+++ b/include/wintypes.h
@@ -160,23 +160,33 @@
DECLARE_HANDLE(HWND);
#undef DECLARE_HANDLE
-/* Callback function pointers types for Win16. */
+/* Callback function pointers types */
typedef LRESULT (*DLGPROC16)(HWND16,UINT16,WPARAM16,LPARAM);
-typedef LRESULT (*FARPROC16)();
-typedef LRESULT (*HOOKPROC16)(INT16,WPARAM16,LPARAM);
-typedef VOID (*TIMERPROC16)(HWND16,UINT16,UINT16,DWORD);
-typedef LRESULT (*WNDENUMPROC16)(HWND16,LPARAM);
-typedef LRESULT (*WNDPROC16)(HWND16,UINT16,WPARAM16,LPARAM);
-
-/* Callback function pointers types for Win32. */
-
typedef LRESULT (*DLGPROC32)(HWND32,UINT32,WPARAM32,LPARAM);
+DECL_WINELIB_TYPE(DLGPROC);
+typedef LRESULT (*FARPROC16)();
typedef LRESULT (*FARPROC32)();
+DECL_WINELIB_TYPE(FARPROC);
+typedef LRESULT (*HOOKPROC16)(INT16,WPARAM16,LPARAM);
typedef LRESULT (*HOOKPROC32)(INT32,WPARAM32,LPARAM);
-typedef VOID (*TIMERPROC32)(HWND32,UINT32,UINT32,DWORD);
+DECL_WINELIB_TYPE(HOOKPROC);
+typedef BOOL16 (*PROPENUMPROC16)(HWND16,SEGPTR,HANDLE16);
+typedef BOOL32 (*PROPENUMPROC32A)(HWND32,LPCSTR,HANDLE32);
+typedef BOOL32 (*PROPENUMPROC32W)(HWND32,LPCWSTR,HANDLE32);
+DECL_WINELIB_TYPE_AW(PROPENUMPROC);
+typedef BOOL32 (*PROPENUMPROCEX32A)(HWND32,LPCSTR,HANDLE32,LPARAM);
+typedef BOOL32 (*PROPENUMPROCEX32W)(HWND32,LPCWSTR,HANDLE32,LPARAM);
+DECL_WINELIB_TYPE_AW(PROPENUMPROCEX);
+typedef VOID (*TIMERPROC16)(HWND16,UINT16,UINT16,DWORD);
+typedef VOID (*TIMERPROC32)(HWND32,UINT32,UINT32,DWORD);
+DECL_WINELIB_TYPE(TIMERPROC);
+typedef LRESULT (*WNDENUMPROC16)(HWND16,LPARAM);
typedef LRESULT (*WNDENUMPROC32)(HWND32,LPARAM);
+DECL_WINELIB_TYPE(WNDENUMPROC);
+typedef LRESULT (*WNDPROC16)(HWND16,UINT16,WPARAM16,LPARAM);
typedef LRESULT (*WNDPROC32)(HWND32,UINT32,WPARAM32,LPARAM);
+DECL_WINELIB_TYPE(WNDPROC);
/* TCHAR data types definitions for Winelib. */
/* These types are _not_ defined for the emulator, because they */
@@ -236,11 +246,6 @@
DECL_WINELIB_TYPE(HWAVEOUT);
DECL_WINELIB_TYPE(HWND);
-DECL_WINELIB_TYPE(DLGPROC);
-DECL_WINELIB_TYPE(FARPROC);
-DECL_WINELIB_TYPE(WNDENUMPROC);
-DECL_WINELIB_TYPE(WNDPROC);
-
/* Misc. constants. */
#ifdef FALSE
@@ -330,4 +335,10 @@
#endif
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
+/* Winelib run-time flag */
+
+#ifdef __WINE__
+extern int __winelib;
+#endif /* __WINE__ */
+
#endif /* __WINE_WINTYPES_H */
diff --git a/ipc/dde_atom.c b/ipc/dde_atom.c
index 6d24908..1aef654 100644
--- a/ipc/dde_atom.c
+++ b/ipc/dde_atom.c
@@ -66,7 +66,7 @@
deleted=hash1;
break;
default : /* non empty atom entry */
- if (lstrcmpi( OFS2AtomStr(atom_ofs) , str) == 0)
+ if (lstrcmpi16( OFS2AtomStr(atom_ofs) , str) == 0)
return hash1; /* found string in atom table */
}
hash2%= DDE_ATOMS-1 ; /* hash2=0..(DDE_ATOMS-2) */
@@ -92,7 +92,7 @@
deleted= i;
break;
default : /* nonempty atom entry */
- if (lstrcmpi( OFS2AtomStr(atom_ofs) , str) == 0)
+ if (lstrcmpi16( OFS2AtomStr(atom_ofs) , str) == 0)
return i; /* found string in atom table */
}
}
diff --git a/ipc/dde_proc.c b/ipc/dde_proc.c
index b65b5fa..36ca350 100644
--- a/ipc/dde_proc.c
+++ b/ipc/dde_proc.c
@@ -45,7 +45,7 @@
#define DDE_SEND 1
#define DDE_POST 2
#define DDE_ACK 3
-#define DDE_MSG_SIZE sizeof(MSG)
+#define DDE_MSG_SIZE sizeof(MSG16)
#define FREE_WND (WORD)(-2)
#define DELETED_WND (WORD)(-3)
#if defined(DEBUG_MSG) || defined(DEBUG_RUNTIME)
@@ -106,7 +106,7 @@
return val;
}
-static void print_dde_message(char *desc, MSG *msg);
+static void print_dde_message(char *desc, MSG16 *msg);
/* This should be run only when main_block is first allocated. */
void dde_proc_init(dde_proc proc)
@@ -201,7 +201,7 @@
}
if (debugging_dde) {
- MSG *msg=(MSG*) &msgbuf->mtext;
+ MSG16 *msg=(MSG16*) &msgbuf->mtext;
char *title;
if (msgbuf->mtype==DDE_SEND)
title="sending dde:";
@@ -290,11 +290,11 @@
return 0;
}
-static BOOL DDE_DoMessage( MSG *msg, int type )
+static BOOL DDE_DoMessage( MSG16 *msg, int type )
{
int proc_idx;
- MSG *remote_message;
+ MSG16 *remote_message;
struct msg_dat msg_dat;
BOOL success;
@@ -346,12 +346,12 @@
}
}
-BOOL DDE_SendMessage( MSG *msg)
+BOOL DDE_SendMessage( MSG16 *msg)
{
return DDE_DoMessage(msg, DDE_SEND);
}
-BOOL DDE_PostMessage( MSG *msg)
+BOOL DDE_PostMessage( MSG16 *msg)
{
return DDE_DoMessage(msg, DDE_POST);
}
@@ -381,7 +381,7 @@
{
static int nesting=0; /* to avoid infinite recursion */
- MSG *remote_message;
+ MSG16 *remote_message;
int size;
struct msg_dat msg_dat;
BOOL was_sent; /* sent/received */
@@ -551,7 +551,7 @@
}
}
-static void print_dde_message(char *desc, MSG *msg)
+static void print_dde_message(char *desc, MSG16 *msg)
{
/* extern const char *MessageTypeNames[];*/
extern int debug_last_handle_size;
diff --git a/ipc/generic_hash.h b/ipc/generic_hash.h
index 5def7e6..6bd296f 100644
--- a/ipc/generic_hash.h
+++ b/ipc/generic_hash.h
@@ -10,6 +10,7 @@
#include "wintypes.h"
#include "shm_block.h"
+#include "win.h"
/* default hash values */
#define HASH_LOAD 70
#define HASH_MEM_ALLOC (HASH_PTR (*)(int size)) malloc
diff --git a/library/miscstubs.c b/library/miscstubs.c
index 0f3d9a0..071b69e 100644
--- a/library/miscstubs.c
+++ b/library/miscstubs.c
@@ -7,8 +7,8 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include "dde_mem.h"
#include "windows.h"
+#include "dde_mem.h"
#include "global.h"
#include "debug.h"
#include "xmalloc.h"
diff --git a/loader/main.c b/loader/main.c
index 01b6511..235faea 100644
--- a/loader/main.c
+++ b/loader/main.c
@@ -41,6 +41,13 @@
#include "debug.h"
+/* Winelib run-time flag */
+#ifdef WINELIB
+int __winelib = 1;
+#else
+int __winelib = 0;
+#endif
+
HANDLE32 SystemHeap = 0;
HANDLE32 SegptrHeap = 0;
diff --git a/loader/module.c b/loader/module.c
index 31a998b..bf4fd5e 100644
--- a/loader/module.c
+++ b/loader/module.c
@@ -273,13 +273,8 @@
DWORD MODULE_AllocateSegment(WORD wFlags, WORD wSize, WORD wElem)
{
WORD size = wSize << wElem;
- HANDLE hMem = GlobalAlloc16( MODULE_Ne2MemFlags(wFlags), size);
-#ifdef WINELIB
- return (DWORD)GlobalLock16(hMem);
-#else
- WORD selector = HIWORD(WIN16_GlobalLock16(hMem));
- return MAKELONG(hMem, selector);
-#endif
+ HANDLE16 hMem = GlobalAlloc16( MODULE_Ne2MemFlags(wFlags), size);
+ return MAKELONG( hMem, GlobalHandleToSel(hMem) );
}
/***********************************************************************
@@ -318,7 +313,6 @@
/***********************************************************************
* MODULE_GetInstance
*/
-#ifndef WINELIB32
HINSTANCE16 MODULE_GetInstance( HMODULE16 hModule )
{
SEGTABLEENTRY *pSegment;
@@ -331,7 +325,6 @@
return pSegment->selector;
}
-#endif
/***********************************************************************
@@ -1299,13 +1292,13 @@
*/
HANDLE LoadLibrary( LPCSTR libname )
{
-#ifdef WINELIB
- dprintf_module( stddeb, "LoadLibrary: (%08x) %s\n", (int)libname, libname);
- WINELIB_UNIMP("LoadLibrary()");
- return (HANDLE)0;
-#else
HANDLE handle;
+ if (__winelib)
+ {
+ fprintf( stderr, "LoadLibrary not supported in Winelib\n" );
+ return (HANDLE)0;
+ }
dprintf_module( stddeb, "LoadLibrary: (%08x) %s\n", (int)libname, libname);
/* This does not increment the module reference count, and will
@@ -1320,9 +1313,10 @@
strcat( buffer, ".dll" );
handle = LoadModule( buffer, (LPVOID)-1 );
}
+#ifndef WINELIB
if (handle >= (HANDLE)32) NE_InitializeDLLs( GetExePtr(handle) );
- return handle;
#endif
+ return handle;
}
@@ -1440,20 +1434,22 @@
}
/* Failed ! */
-#ifdef WINELIB
- /* build argv */
- argptr = argv;
- *argptr++ = "wine";
- if (iconic) *argptr++ = "-iconic";
- *argptr++ = lpCmdLine;
- *argptr++ = 0;
- /* Execute */
- execvp(argv[0] , (char**)argv);
+ if (__winelib)
+ {
+ /* build argv */
+ argptr = argv;
+ *argptr++ = "wine";
+ if (iconic) *argptr++ = "-iconic";
+ *argptr++ = lpCmdLine;
+ *argptr++ = 0;
- /* Failed ! */
- fprintf(stderr, "WinExec: can't exec 'wine %s'\n", lpCmdLine);
-#endif
+ /* Execute */
+ execvp(argv[0] , (char**)argv);
+
+ /* Failed ! */
+ fprintf(stderr, "WinExec: can't exec 'wine %s'\n", lpCmdLine);
+ }
exit(1);
}
}
diff --git a/loader/pe_resource.c b/loader/pe_resource.c
index 9178772..fd3a302 100644
--- a/loader/pe_resource.c
+++ b/loader/pe_resource.c
@@ -82,6 +82,11 @@
return (PIMAGE_RESOURCE_DIRECTORY) (
root +
(entryTable[entrynum].OffsetToData & 0x7fffffff));
+ /* just use first entry if no default can be found */
+ if (!name && resdirptr->NumberOfIdEntries)
+ return (PIMAGE_RESOURCE_DIRECTORY) (
+ root +
+ (entryTable[0].OffsetToData & 0x7fffffff));
return NULL;
}
}
diff --git a/loader/task.c b/loader/task.c
index ef862d2..bf32790 100644
--- a/loader/task.c
+++ b/loader/task.c
@@ -1060,6 +1060,68 @@
/***********************************************************************
+ * SwitchStackTo (KERNEL.108)
+ */
+void SwitchStackTo( WORD seg, WORD ptr, WORD top )
+{
+ TDB *pTask;
+ STACK16FRAME *oldFrame, *newFrame;
+
+ if (!(pTask = (TDB *)GlobalLock16( hCurrentTask ))) return;
+ dprintf_task( stddeb, "SwitchStackTo: old=%04x:%04x new=%04x:%04x\n",
+ IF1632_Saved16_ss, IF1632_Saved16_sp, seg, ptr );
+ /* Save the old stack */
+ oldFrame = CURRENT_STACK16;
+ pTask->switchStackSS = IF1632_Saved16_ss;
+ pTask->switchStackSP = IF1632_Saved16_sp;
+ /* Switch to the new stack */
+ IF1632_Saved16_ss = seg;
+ IF1632_Saved16_sp = ptr - sizeof(STACK16FRAME);
+ newFrame = CURRENT_STACK16;
+ /* Build the stack frame on the new stack */
+ *newFrame = *oldFrame;
+}
+
+
+/***********************************************************************
+ * SwitchStackBack (KERNEL.109)
+ *
+ * Note: the function is declared as 'register' in the spec file in order
+ * to make sure all registers are preserved, but we don't use them in any
+ * way, so we don't need a SIGCONTEXT* argument.
+ */
+void SwitchStackBack(void)
+{
+ TDB *pTask;
+ STACK16FRAME *oldFrame, *newFrame;
+
+ if (!(pTask = (TDB *)GlobalLock16( hCurrentTask ))) return;
+ if (!pTask->switchStackSS)
+ {
+ fprintf( stderr, "SwitchStackBack: no previous SwitchStackTo\n" );
+ return;
+ }
+ dprintf_task( stddeb, "SwitchStackBack: restoring stack %04x:%04x\n",
+ pTask->switchStackSS, pTask->switchStackSP );
+
+ oldFrame = CURRENT_STACK16;
+ /* Switch back to the old stack */
+ IF1632_Saved16_ss = pTask->switchStackSS;
+ IF1632_Saved16_sp = pTask->switchStackSP;
+ pTask->switchStackSS = 0;
+ /* Build a stack frame for the return */
+ newFrame = CURRENT_STACK16;
+ newFrame->saved_ss = oldFrame->saved_ss;
+ newFrame->saved_sp = oldFrame->saved_sp;
+ newFrame->entry_ip = oldFrame->entry_ip;
+ newFrame->entry_cs = oldFrame->entry_cs;
+ newFrame->bp = oldFrame->bp;
+ newFrame->ip = oldFrame->ip;
+ newFrame->cs = oldFrame->cs;
+}
+
+
+/***********************************************************************
* GetTaskQueueDS (KERNEL.118)
*/
#ifndef WINELIB
@@ -1287,3 +1349,15 @@
if (GlobalSize16(hTask) < sizeof(TDB)) return 0;
return pTask->compat_flags;
}
+
+
+/***********************************************************************
+ * SetSigHandler (KERNEL.140)
+ */
+WORD SetSigHandler( SEGPTR newhandler,SEGPTR* oldhandler,
+ LPUINT16 *oldmode,UINT16 newmode,UINT16 flag )
+{
+ fprintf(stdnimp,"SetSigHandler(%lx,%p,%p,%d,%d), unimplemented.\n",
+ newhandler,oldhandler,oldmode,newmode,flag );
+ return 0;
+}
diff --git a/memory/global.c b/memory/global.c
index c3d66a7..f88d129 100644
--- a/memory/global.c
+++ b/memory/global.c
@@ -46,8 +46,6 @@
static GLOBALARENA *pGlobalArena = NULL;
static int globalArenaSize = 0;
-static DWORD globalDOSfree = 655350;
-
#define GLOBAL_MAX_ALLOC_SIZE 0x00ff0000 /* Largest allocation is 16M - 64K */
#define GET_ARENA_PTR(handle) (pGlobalArena + ((handle) >> __AHSHIFT))
@@ -551,41 +549,6 @@
/***********************************************************************
- * GlobalDOSAlloc (KERNEL.184)
- *
- * Some programs rely on failure to allocate > 640K total with this function
- */
-DWORD GlobalDOSAlloc( DWORD size )
-{
- WORD sel;
-
- if (size > globalDOSfree) return 0;
- sel = GlobalAlloc16( GMEM_FIXED, size );
-
- dprintf_global( stddeb, "GlobalDOSAlloc: %08lx -> returning %04x\n",
- size, sel );
- if (!sel) return 0;
-
- globalDOSfree -= size;
- return MAKELONG( sel, sel /* this one ought to be a real-mode segment */ );
-}
-
-
-/***********************************************************************
- * GlobalDOSFree (KERNEL.185)
- */
-WORD GlobalDOSFree( WORD sel )
-{
- GLOBALARENA *pArena = GET_ARENA_PTR(sel);
-
- if (!pArena) return sel;
- globalDOSfree += pArena->size;
- GlobalFree16( pArena->handle );
- return 0;
-}
-
-
-/***********************************************************************
* SetSwapAreaSize (KERNEL.106)
*/
LONG SetSwapAreaSize( WORD size )
diff --git a/memory/heap.c b/memory/heap.c
index acdd8df..5c3573c 100644
--- a/memory/heap.c
+++ b/memory/heap.c
@@ -1212,6 +1212,18 @@
{
INT32 len = lstrlen32A(str) + 1;
LPSTR p = HeapAlloc( heap, flags, len );
- if (p) strcpy( p, str );
+ lstrcpy32A( p, str );
+ return p;
+}
+
+
+/***********************************************************************
+ * HEAP_strdupW
+ */
+LPWSTR HEAP_strdupW( HANDLE32 heap, DWORD flags, LPCWSTR str )
+{
+ INT32 len = lstrlen32W(str) + 1;
+ LPWSTR p = HeapAlloc( heap, flags, len * sizeof(WCHAR) );
+ lstrcpy32W( p, str );
return p;
}
diff --git a/memory/ldt.c b/memory/ldt.c
index 3511637..9b1ef9e 100644
--- a/memory/ldt.c
+++ b/memory/ldt.c
@@ -13,8 +13,6 @@
#include "stddebug.h"
#include "debug.h"
-#ifndef WINELIB
-
#ifdef linux
#include <linux/unistd.h>
#include <linux/head.h>
@@ -22,6 +20,7 @@
_syscall3(int, modify_ldt, int, func, void *, ptr, unsigned long, bytecount)
#endif /* linux */
+
#if defined(__svr4__) || defined(_SCO_DS)
#include <sys/sysi86.h>
#include <sys/seg.h>
@@ -34,8 +33,6 @@
extern int i386_set_ldt(int, union descriptor *, int);
#endif /* __NetBSD__ || __FreeBSD__ */
-#endif /* ifndef WINELIB */
-
ldt_copy_entry ldt_copy[LDT_SIZE];
unsigned char ldt_flags_copy[LDT_SIZE];
@@ -121,8 +118,8 @@
/* Entry 0 must not be modified; its base and limit are always 0 */
if (!entry) return 0;
-#ifndef WINELIB
#ifdef linux
+ if (!__winelib)
{
struct modify_ldt_ldt_s ldt_info;
@@ -167,6 +164,7 @@
#endif /* linux */
#if defined(__NetBSD__) || defined(__FreeBSD__)
+ if (!__winelib)
{
long d[2];
@@ -182,35 +180,32 @@
}
#endif /* __NetBSD__ || __FreeBSD__ */
#if defined(__svr4__) || defined(_SCO_DS)
-{
- struct ssd ldt_mod;
- int i;
- ldt_mod.sel = ENTRY_TO_SELECTOR(entry) | 4;
- ldt_mod.bo = content->base;
- ldt_mod.ls = content->limit;
- i = (content->limit & 0xf0000) |
- (content->type << 10) |
- (((content->read_only != 0) ^ 1) << 9) |
- ((content->seg_32bit != 0) << 22) |
- ((content->limit_in_pages != 0)<< 23) |
- (1<<15) |
- 0x7000;
-
- ldt_mod.acc1 = (i & 0xff00) >> 8;
- ldt_mod.acc2 = (i & 0xf00000) >> 20;
-
-
- if (content->base == 0)
+ if (!__winelib)
{
- ldt_mod.acc1 = 0;
- ldt_mod.acc2 = 0;
+ struct ssd ldt_mod;
+ int i;
+ ldt_mod.sel = ENTRY_TO_SELECTOR(entry) | 4;
+ ldt_mod.bo = content->base;
+ ldt_mod.ls = content->limit;
+ i = ((content->limit & 0xf0000) |
+ (content->type << 10) |
+ (((content->read_only != 0) ^ 1) << 9) |
+ ((content->seg_32bit != 0) << 22) |
+ ((content->limit_in_pages != 0)<< 23) |
+ (1<<15) |
+ 0x7000);
+
+ ldt_mod.acc1 = (i & 0xff00) >> 8;
+ ldt_mod.acc2 = (i & 0xf00000) >> 20;
+
+ if (content->base == 0)
+ {
+ ldt_mod.acc1 = 0;
+ ldt_mod.acc2 = 0;
+ }
+ if ((ret = sysi86(SI86DSCR, &ldt_mod)) == -1) perror("sysi86");
}
- if ((i = sysi86(SI86DSCR, &ldt_mod)) == -1)
- perror("sysi86");
-
-}
#endif
-#endif /* ifndef WINELIB */
if (ret < 0) return ret;
ldt_copy[entry].base = content->base;
diff --git a/memory/selector.c b/memory/selector.c
index a38a0d1..ecf7df4 100644
--- a/memory/selector.c
+++ b/memory/selector.c
@@ -262,7 +262,20 @@
*/
DWORD GetSelectorBase( WORD sel )
{
- return GET_SEL_BASE(sel);
+ extern char* DOSMEM_dosmem;
+ DWORD base;
+
+ base = GET_SEL_BASE(sel);
+
+#ifndef WINELIB
+ /* if base points into DOSMEM, assume we have to
+ * return pointer into physical lower 1MB
+ */
+ if ((base >= (DWORD)DOSMEM_dosmem) &&
+ (base < ((DWORD)DOSMEM_dosmem+0x100000)))
+ base = base - (DWORD)DOSMEM_dosmem;
+#endif
+ return base;
}
@@ -271,9 +284,23 @@
*/
WORD SetSelectorBase( WORD sel, DWORD base )
{
+ extern char* DOSMEM_dosmem;
ldt_entry entry;
+
LDT_GetEntry( SELECTOR_TO_ENTRY(sel), &entry );
- entry.base = base;
+#ifndef WINELIB
+ if (base < 0x100000)
+ {
+ /* Assume pointers in the lower 1MB range are
+ * in fact physical addresses into DOS memory.
+ * Translate the base to our internal representation
+ *
+ * (NETAPI.DLL of Win95 does use SetSelectorBase this way)
+ */
+ entry.base = (DWORD)(DOSMEM_dosmem+base);
+ }
+ else entry.base = base;
+#endif
LDT_SetEntry( SELECTOR_TO_ENTRY(sel), &entry );
return sel;
}
diff --git a/misc/comm.c b/misc/comm.c
index a68542a..b628a2b 100644
--- a/misc/comm.c
+++ b/misc/comm.c
@@ -1,5 +1,7 @@
/*
* DEC 93 Erik Bos <erik@xs4all.nl>
+ *
+ * Copyright 1996 Marcus Meissner
*/
#include <stdio.h>
@@ -11,7 +13,6 @@
#include <ctype.h>
#include <sys/stat.h>
#if defined(__NetBSD__) || defined(__FreeBSD__)
-#include <errno.h>
#include <sys/ioctl.h>
#endif
#include <unistd.h>
@@ -20,9 +21,9 @@
#include "comm.h"
#include "options.h"
#include "stddebug.h"
-/* #define DEBUG_COMM */
-/* #undef DEBUG_COMM */
#include "debug.h"
+#include "handle32.h"
+#include "string32.h"
int commerror = 0, eventmask = 0;
@@ -126,11 +127,13 @@
}
}
-BOOL BuildCommDCB(LPCSTR device, LPDCB lpdcb)
+/**************************************************************************
+ * BuildCommDCB (USER.213)
+ */
+BOOL16 BuildCommDCB16(LPCSTR device, LPDCB16 lpdcb)
{
/* "COM1:9600,n,8,1" */
/* 012345 */
-
int port;
char *ptr, temp[256];
@@ -177,14 +180,12 @@
*ptr = toupper(*ptr);
dprintf_comm(stddeb,"BuildCommDCB: parity (%c)\n", *ptr);
+ lpdcb->fParity = 1;
switch (*ptr) {
case 'N':
lpdcb->Parity = NOPARITY;
lpdcb->fParity = 0;
break;
-
- lpdcb->fParity = 1;
-
case 'E':
lpdcb->Parity = EVENPARITY;
break;
@@ -221,7 +222,162 @@
return 0;
}
-int OpenComm(LPCSTR device, UINT cbInQueue, UINT cbOutQueue)
+/**************************************************************************
+ * BuildCommDCBA (KERNEL32.14)
+ */
+BOOL32 BuildCommDCB32A(LPCSTR device,LPDCB32 lpdcb) {
+ return BuildCommDCBAndTimeouts32A(device,lpdcb,NULL);
+}
+
+/**************************************************************************
+ * BuildCommDCBAndTimeoutsA (KERNEL32.15)
+ */
+BOOL32 BuildCommDCBAndTimeouts32A(LPCSTR device, LPDCB32 lpdcb,LPCOMMTIMEOUTS lptimeouts) {
+ int port;
+ char *ptr,*temp;
+
+ dprintf_comm(stddeb,"BuildCommDCBAndTimeouts32A(%s,%p,%p)\n",device,lpdcb,lptimeouts);
+ commerror = 0;
+
+ if (!lstrncmpi32A(device,"COM",3)) {
+ port=device[3]-'0';
+ if (port--==0) {
+ fprintf(stderr,"comm:BUG! COM0 can't exists!.\n");
+ return FALSE;
+ }
+ if (!ValidCOMPort(port))
+ return FALSE;
+ if (*(device+4)!=':')
+ return FALSE;
+ temp=(LPSTR)(device+5);
+ } else
+ temp=(LPSTR)device;
+ lpdcb->DCBlength = sizeof(DCB32);
+ if (strchr(temp,',')) { /* old style */
+ DCB16 dcb16;
+ BOOL16 ret;
+ char last=temp[strlen(temp)-1];
+
+ ret=BuildCommDCB16(device,&dcb16);
+ if (!ret)
+ return FALSE;
+ lpdcb->BaudRate = dcb16.BaudRate;
+ lpdcb->ByteSize = dcb16.ByteSize;
+ lpdcb->fBinary = dcb16.fBinary;
+ lpdcb->Parity = dcb16.Parity;
+ lpdcb->fParity = dcb16.fParity;
+ lpdcb->fNull = dcb16.fNull;
+ lpdcb->StopBits = dcb16.StopBits;
+ if (last == 'x') {
+ lpdcb->fInX = TRUE;
+ lpdcb->fOutX = TRUE;
+ lpdcb->fOutxCtsFlow = FALSE;
+ lpdcb->fOutxDsrFlow = FALSE;
+ lpdcb->fDtrControl = DTR_CONTROL_ENABLE;
+ lpdcb->fRtsControl = RTS_CONTROL_ENABLE;
+ } else if (last=='p') {
+ lpdcb->fInX = FALSE;
+ lpdcb->fOutX = FALSE;
+ lpdcb->fOutxCtsFlow = TRUE;
+ lpdcb->fOutxDsrFlow = TRUE;
+ lpdcb->fDtrControl = DTR_CONTROL_HANDSHAKE;
+ lpdcb->fRtsControl = RTS_CONTROL_HANDSHAKE;
+ } else {
+ lpdcb->fInX = FALSE;
+ lpdcb->fOutX = FALSE;
+ lpdcb->fOutxCtsFlow = FALSE;
+ lpdcb->fOutxDsrFlow = FALSE;
+ lpdcb->fDtrControl = DTR_CONTROL_ENABLE;
+ lpdcb->fRtsControl = RTS_CONTROL_ENABLE;
+ }
+ lpdcb->XonChar = dcb16.XonChar;
+ lpdcb->XoffChar = dcb16.XoffChar;
+ lpdcb->ErrorChar= dcb16.PeChar;
+ lpdcb->fErrorChar= dcb16.fPeChar;
+ lpdcb->EofChar = dcb16.EofChar;
+ lpdcb->EvtChar = dcb16.EvtChar;
+ lpdcb->XonLim = dcb16.XonLim;
+ lpdcb->XoffLim = dcb16.XoffLim;
+ return TRUE;
+ }
+ ptr=strtok(temp," ");
+ while (ptr) {
+ DWORD flag,x;
+
+ flag=0;
+ if (!strncmp("baud=",ptr,5)) {
+ if (!sscanf(ptr+5,"%ld",&x))
+ fprintf(stderr,"BuildCommDCB32A:Couldn't parse %s\n",ptr);
+ lpdcb->BaudRate = x;
+ flag=1;
+ }
+ if (!strncmp("stop=",ptr,5)) {
+ if (!sscanf(ptr+5,"%ld",&x))
+ fprintf(stderr,"BuildCommDCB32A:Couldn't parse %s\n",ptr);
+ lpdcb->StopBits = x;
+ flag=1;
+ }
+ if (!strncmp("data=",ptr,5)) {
+ if (!sscanf(ptr+5,"%ld",&x))
+ fprintf(stderr,"BuildCommDCB32A:Couldn't parse %s\n",ptr);
+ lpdcb->ByteSize = x;
+ flag=1;
+ }
+ if (!strncmp("parity=",ptr,7)) {
+ lpdcb->fParity = TRUE;
+ switch (ptr[8]) {
+ case 'N':case 'n':
+ lpdcb->fParity = FALSE;
+ lpdcb->Parity = NOPARITY;
+ break;
+ case 'E':case 'e':
+ lpdcb->Parity = EVENPARITY;
+ break;
+ case 'O':case 'o':
+ lpdcb->Parity = ODDPARITY;
+ break;
+ case 'M':case 'm':
+ lpdcb->Parity = MARKPARITY;
+ break;
+ }
+ flag=1;
+ }
+ if (!flag)
+ fprintf(stderr,"BuildCommDCB32A: Unhandled specifier '%s', please report.\n",ptr);
+ ptr=strtok(NULL," ");
+ }
+ if (lpdcb->BaudRate==110)
+ lpdcb->StopBits = 2;
+ return TRUE;
+}
+
+/**************************************************************************
+ * BuildCommDCBAndTimeoutsW (KERNEL32.16)
+ */
+BOOL32 BuildCommDCBAndTimeouts32W(
+ LPCWSTR devid,LPDCB32 lpdcb,LPCOMMTIMEOUTS lptimeouts
+) {
+ LPSTR devidA;
+ BOOL32 ret;
+
+ dprintf_comm(stddeb,"BuildCommDCBAndTimeouts32W(%p,%p,%p)\n",devid,lpdcb,lptimeouts);
+ devidA = STRING32_DupUniToAnsi(devid);
+ ret=BuildCommDCBAndTimeouts32A(devidA,lpdcb,lptimeouts);
+ free(devidA);
+ return ret;
+}
+
+/**************************************************************************
+ * BuildCommDCBW (KERNEL32.17)
+ */
+BOOL32 BuildCommDCB32W(LPCWSTR devid,LPDCB32 lpdcb) {
+ return BuildCommDCBAndTimeouts32W(devid,lpdcb,NULL);
+}
+
+/*****************************************************************************
+ * OpenComm (USER.200)
+ */
+INT16 OpenComm(LPCSTR device,UINT16 cbInQueue,UINT16 cbOutQueue)
{
int port, fd;
@@ -282,7 +438,10 @@
return 0;
}
-int CloseComm(int fd)
+/*****************************************************************************
+ * CloseComm (USER.207)
+ */
+INT16 CloseComm(INT16 fd)
{
dprintf_comm(stddeb,"CloseComm: fd %d\n", fd);
if (close(fd) == -1) {
@@ -294,7 +453,10 @@
}
}
-int SetCommBreak(int fd)
+/*****************************************************************************
+ * SetCommBreak (USER.210)
+ */
+INT16 SetCommBreak16(INT16 fd)
{
struct DosDeviceStruct *ptr;
@@ -309,7 +471,31 @@
return 0;
}
-int ClearCommBreak(int fd)
+/*****************************************************************************
+ * SetCommBreak (KERNEL32.449)
+ */
+BOOL32 SetCommBreak32(HANDLE32 hfile)
+{
+ FILE_OBJECT *fob = (FILE_OBJECT*)hfile;
+ int fd = fob->fd;
+
+ struct DosDeviceStruct *ptr;
+
+ dprintf_comm(stddeb,"SetCommBreak: fd: %d\n", fd);
+ if ((ptr = GetDeviceStruct(fd)) == NULL) {
+ commerror = IE_BADID;
+ return FALSE;
+ }
+
+ ptr->suspended = 1;
+ commerror = 0;
+ return TRUE;
+}
+
+/*****************************************************************************
+ * ClearCommBreak (USER.211)
+ */
+INT16 ClearCommBreak16(INT16 fd)
{
struct DosDeviceStruct *ptr;
@@ -324,15 +510,37 @@
return 0;
}
-LONG EscapeCommFunction(int fd, int nFunction)
+/*****************************************************************************
+ * ClearCommBreak (KERNEL32.20)
+ */
+BOOL32 ClearCommBreak32(HANDLE32 hfile)
{
- int max;
+ FILE_OBJECT *fob = (FILE_OBJECT*)hfile;
+ int fd = fob->fd;
+ struct DosDeviceStruct *ptr;
+
+ dprintf_comm(stddeb,"ClearCommBreak: fd: %d\n", fd);
+ if ((ptr = GetDeviceStruct(fd)) == NULL) {
+ commerror = IE_BADID;
+ return FALSE;
+ }
+
+ ptr->suspended = 0;
+ commerror = 0;
+ return TRUE;
+}
+
+/*****************************************************************************
+ * EscapeCommFunction (USER.214)
+ */
+LONG EscapeCommFunction16(UINT16 fd,UINT16 nFunction)
+{
+ int max;
struct termios port;
- dprintf_comm(stddeb,
- "EscapeCommFunction fd: %d, function: %d\n", fd, nFunction);
- if (tcgetattr(fd, &port) == -1) {
- commerror = WinError();
+ dprintf_comm(stddeb,"EscapeCommFunction fd: %d, function: %d\n", fd, nFunction);
+ if (tcgetattr(fd,&port) == -1) {
+ commerror=WinError();
return -1;
}
@@ -342,13 +550,13 @@
case GETMAXCOM:
for (max = MAX_PORTS;!COM[max].devicename;max--)
- ;
+ ;
return max;
break;
case GETMAXLPT:
for (max = MAX_PORTS;!LPT[max].devicename;max--)
- ;
+ ;
return 0x80 + max;
break;
@@ -398,25 +606,99 @@
}
}
-int FlushComm(int fd, int fnQueue)
+/*****************************************************************************
+ * EscapeCommFunction (KERNEL32.214)
+ */
+BOOL32 EscapeCommFunction32(HANDLE32 hfile,UINT32 nFunction)
+{
+ FILE_OBJECT *fob = (FILE_OBJECT*)hfile;
+ int fd = fob->fd;
+ struct termios port;
+ struct DosDeviceStruct *ptr;
+
+ dprintf_comm(stddeb,"EscapeCommFunction fd: %d, function: %d\n", fd, nFunction);
+ if (tcgetattr(fd,&port) == -1) {
+ commerror=WinError();
+ return FALSE;
+ }
+ if ((ptr = GetDeviceStruct(fd)) == NULL) {
+ commerror = IE_BADID;
+ return FALSE;
+ }
+
+ switch (nFunction) {
+ case RESETDEV:
+ break;
+
+#ifdef TIOCM_DTR
+ case CLRDTR:
+ port.c_cflag &= TIOCM_DTR;
+ break;
+#endif
+
+#ifdef TIOCM_RTS
+ case CLRRTS:
+ port.c_cflag &= TIOCM_RTS;
+ break;
+#endif
+
+#ifdef CRTSCTS
+ case SETDTR:
+ port.c_cflag |= CRTSCTS;
+ break;
+
+ case SETRTS:
+ port.c_cflag |= CRTSCTS;
+ break;
+#endif
+
+ case SETXOFF:
+ port.c_iflag |= IXOFF;
+ break;
+
+ case SETXON:
+ port.c_iflag |= IXON;
+ break;
+ case SETBREAK:
+ ptr->suspended = 1;
+ break;
+ case CLRBREAK:
+ ptr->suspended = 0;
+ break;
+ default:
+ fprintf(stderr,
+ "EscapeCommFunction32 fd: %d, unknown function: %d\n",
+ fd, nFunction);
+ break;
+ }
+
+ if (tcsetattr(fd, TCSADRAIN, &port) == -1) {
+ commerror = WinError();
+ return FALSE;
+ } else {
+ commerror = 0;
+ return TRUE;
+ }
+}
+
+/*****************************************************************************
+ * FlushComm (USER.215)
+ */
+INT16 FlushComm(INT16 fd,INT16 fnQueue)
{
int queue;
dprintf_comm(stddeb,"FlushComm fd: %d, queue: %d\n", fd, fnQueue);
switch (fnQueue) {
- case 0:
- queue = TCOFLUSH;
+ case 0: queue = TCOFLUSH;
break;
- case 1:
- queue = TCIFLUSH;
+ case 1: queue = TCIFLUSH;
break;
- default:
- fprintf(stderr,
+ default:fprintf(stderr,
"FlushComm fd: %d, UNKNOWN queue: %d\n",
fd, fnQueue);
return -1;
}
-
if (tcflush(fd, fnQueue)) {
commerror = WinError();
return -1;
@@ -426,7 +708,10 @@
}
}
-int GetCommError(int fd, COMSTAT *lpStat)
+/*****************************************************************************
+ * GetCommError (USER.203)
+ */
+INT16 GetCommError(INT16 fd,LPCOMSTAT lpStat)
{
int temperror;
@@ -437,15 +722,36 @@
return(temperror);
}
-UINT * SetCommEventMask(int fd, UINT fuEvtMask)
+/*****************************************************************************
+ * ClearCommError (KERNEL32.21)
+ */
+BOOL32 ClearCommError(HANDLE32 hfile,LPDWORD errors,LPCOMSTAT lpStat)
{
+ int temperror;
+ FILE_OBJECT *fob=(FILE_OBJECT*)hfile;
+ int fd = fob->fd;
+
dprintf_comm(stddeb,
- "SetCommEventMask: fd %d, mask %d\n", fd, fuEvtMask);
- eventmask |= fuEvtMask;
- return (UINT *)&eventmask;
+ "ClearCommError: fd %d (current error %d)\n", fd, commerror);
+ temperror = commerror;
+ commerror = 0;
+ return TRUE;
}
-UINT GetCommEventMask(int fd, int fnEvtClear)
+/*****************************************************************************
+ * SetCommEventMask (USER.208)
+ */
+UINT16 *SetCommEventMask(INT16 fd,UINT16 fuEvtMask)
+{
+ dprintf_comm(stddeb,"SetCommEventMask:fd %d,mask %d\n",fd,fuEvtMask);
+ eventmask |= fuEvtMask;
+ return (UINT *)&eventmask; /* FIXME, should be SEGPTR */
+}
+
+/*****************************************************************************
+ * GetCommEventMask (USER.209)
+ */
+UINT16 GetCommEventMask(INT16 fd,UINT16 fnEvtClear)
{
dprintf_comm(stddeb,
"GetCommEventMask: fd %d, mask %d\n", fd, fnEvtClear);
@@ -453,7 +759,38 @@
return eventmask;
}
-int SetCommState(DCB *lpdcb)
+/*****************************************************************************
+ * GetCommMask (KERNEL32.156)
+ */
+BOOL32 GetCommMask(HANDLE32 hfile,LPDWORD evtmask)
+{
+ FILE_OBJECT *fob=(FILE_OBJECT*)hfile;
+ int fd = fob->fd;
+
+ dprintf_comm(stddeb,
+ "GetCommMask: fd %d, mask %p\n", fd, evtmask);
+ *evtmask = eventmask;
+ return TRUE;
+}
+
+/*****************************************************************************
+ * SetCommMask (KERNEL32.451)
+ */
+BOOL32 SetCommMask(HANDLE32 hfile,DWORD evtmask)
+{
+ FILE_OBJECT *fob=(FILE_OBJECT*)hfile;
+ int fd = fob->fd;
+
+ dprintf_comm(stddeb,
+ "SetCommMask: fd %d, mask %lx\n", fd, evtmask);
+ eventmask = evtmask;
+ return TRUE;
+}
+
+/*****************************************************************************
+ * SetCommState16 (USER.201)
+ */
+INT16 SetCommState16(LPDCB16 lpdcb)
{
struct termios port;
struct DosDeviceStruct *ptr;
@@ -652,7 +989,216 @@
}
}
-int GetCommState(int fd, DCB *lpdcb)
+/*****************************************************************************
+ * SetCommState32 (KERNEL32.452)
+ */
+BOOL32 SetCommState32(HANDLE32 hfile,LPDCB32 lpdcb)
+{
+ FILE_OBJECT *fob = (FILE_OBJECT*)hfile;
+ int fd = fob->fd;
+ struct termios port;
+ struct DosDeviceStruct *ptr;
+
+ dprintf_comm(stddeb,"SetCommState: fd %d, ptr %p\n",fd,lpdcb);
+ if (tcgetattr(fd,&port) == -1) {
+ commerror = WinError();
+ return FALSE;
+ }
+
+ port.c_cc[VMIN] = 0;
+ port.c_cc[VTIME] = 1;
+
+#ifdef IMAXBEL
+ port.c_iflag &= ~(ISTRIP|BRKINT|IGNCR|ICRNL|INLCR|IMAXBEL);
+#else
+ port.c_iflag &= ~(ISTRIP|BRKINT|IGNCR|ICRNL|INLCR);
+#endif
+ port.c_iflag |= (IGNBRK);
+
+ port.c_oflag &= ~(OPOST);
+
+ port.c_cflag &= ~(HUPCL);
+ port.c_cflag |= CLOCAL | CREAD;
+
+ port.c_lflag &= ~(ICANON|ECHO|ISIG);
+ port.c_lflag |= NOFLSH;
+
+ if ((ptr = GetDeviceStruct(fd)) == NULL) {
+ commerror = IE_BADID;
+ return FALSE;
+ }
+ if (ptr->baudrate > 0)
+ lpdcb->BaudRate = ptr->baudrate;
+ dprintf_comm(stddeb,"SetCommState: baudrate %ld\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 FALSE;
+ }
+#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 FALSE;
+ }
+ port.c_ispeed = port.c_ospeed;
+#endif
+ dprintf_comm(stddeb,"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 FALSE;
+ }
+
+ dprintf_comm(stddeb,"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 FALSE;
+ }
+
+
+ dprintf_comm(stddeb,"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 FALSE;
+ }
+#ifdef CRTSCTS
+ if ( lpdcb->fOutxCtsFlow ||
+ lpdcb->fDtrControl == DTR_CONTROL_ENABLE||
+ lpdcb->fRtsControl == RTS_CONTROL_ENABLE
+ )
+ port.c_cflag |= CRTSCTS;
+ if (lpdcb->fDtrControl == DTR_CONTROL_DISABLE)
+ port.c_cflag &= ~CRTSCTS;
+
+#endif
+ if (lpdcb->fInX)
+ port.c_iflag |= IXON;
+ if (lpdcb->fOutX)
+ port.c_iflag |= IXOFF;
+
+ if (tcsetattr(fd,TCSADRAIN,&port)==-1) {
+ commerror = WinError();
+ return FALSE;
+ } else {
+ commerror = 0;
+ return TRUE;
+ }
+}
+
+
+/*****************************************************************************
+ * GetCommState (USER.202)
+ */
+INT16 GetCommState16(INT16 fd, LPDCB16 lpdcb)
{
struct termios port;
@@ -661,9 +1207,7 @@
commerror = WinError();
return -1;
}
-
lpdcb->Id = fd;
-
#ifdef CBAUD
switch (port.c_cflag & CBAUD) {
#else
@@ -769,7 +1313,127 @@
return 0;
}
-int TransmitCommChar(int fd, char chTransmit)
+/*****************************************************************************
+ * GetCommState (KERNEL32.159)
+ */
+BOOL32 GetCommState32(HANDLE32 hfile, LPDCB32 lpdcb)
+{
+ FILE_OBJECT *fob = (FILE_OBJECT*)hfile;
+ int fd = fob->fd;
+ struct termios port;
+
+
+ dprintf_comm(stddeb,"GetCommState32: fd %d, ptr %p\n", fd, lpdcb);
+ if (tcgetattr(fd, &port) == -1) {
+ commerror = WinError();
+ return FALSE;
+ }
+#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->fNull = 0;
+ lpdcb->fBinary = 1;
+
+#ifdef CRTSCTS
+
+ if (port.c_cflag & CRTSCTS) {
+ lpdcb->fDtrControl = DTR_CONTROL_ENABLE;
+ lpdcb->fRtsControl = RTS_CONTROL_ENABLE;
+ lpdcb->fOutxCtsFlow = 1;
+ lpdcb->fOutxDsrFlow = 1;
+ } else
+#endif
+ {
+ lpdcb->fDtrControl = DTR_CONTROL_DISABLE;
+ lpdcb->fRtsControl = RTS_CONTROL_DISABLE;
+ }
+ 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 TRUE;
+}
+
+/*****************************************************************************
+ * TransmitCommChar (USER.206)
+ */
+INT16 TransmitCommChar16(INT16 fd,CHAR chTransmit)
{
struct DosDeviceStruct *ptr;
@@ -794,7 +1458,38 @@
}
}
-int UngetCommChar(int fd, char chUnget)
+/*****************************************************************************
+ * TransmitCommChar (KERNEL32.535)
+ */
+BOOL32 TransmitCommChar32(HANDLE32 hfile,CHAR chTransmit)
+{
+ FILE_OBJECT *fob = (FILE_OBJECT*)hfile;
+ int fd = fob->fd;
+ struct DosDeviceStruct *ptr;
+
+ dprintf_comm(stddeb,"TransmitCommChar32(%d,'%c')\n",fd,chTransmit);
+ if ((ptr = GetDeviceStruct(fd)) == NULL) {
+ commerror = IE_BADID;
+ return FALSE;
+ }
+
+ if (ptr->suspended) {
+ commerror = IE_HARDWARE;
+ return FALSE;
+ }
+ if (write(fd, (void *) &chTransmit, 1) == -1) {
+ commerror = WinError();
+ return FALSE;
+ } else {
+ commerror = 0;
+ return TRUE;
+ }
+}
+
+/*****************************************************************************
+ * UngetCommChar (USER.212)
+ */
+INT16 UngetCommChar(INT16 fd,CHAR chUnget)
{
struct DosDeviceStruct *ptr;
@@ -811,12 +1506,14 @@
ptr->unget = 1;
ptr->unget_byte = chUnget;
-
commerror = 0;
return 0;
}
-int ReadComm(int fd, LPSTR lpvBuf, int cbRead)
+/*****************************************************************************
+ * ReadComm (USER.204)
+ */
+INT16 ReadComm(INT16 fd,LPSTR lpvBuf,INT16 cbRead)
{
int status, length;
struct DosDeviceStruct *ptr;
@@ -858,7 +1555,10 @@
}
}
-int WriteComm(int fd, LPSTR lpvBuf, int cbWrite)
+/*****************************************************************************
+ * WriteComm (USER.205)
+ */
+INT16 WriteComm(INT16 fd, LPSTR lpvBuf, INT16 cbWrite)
{
int x, length;
struct DosDeviceStruct *ptr;
@@ -888,3 +1588,24 @@
return length;
}
}
+
+
+/*****************************************************************************
+ * GetCommTimeouts (KERNEL32.160)
+ */
+BOOL32 GetCommTimeouts(HANDLE32 hfile,LPCOMMTIMEOUTS lptimeouts) {
+ dprintf_comm(stddeb,"GetCommTimeouts(%lx,%p), empty stub.\n",
+ (DWORD)hfile,lptimeouts
+ );
+ return TRUE;
+}
+
+/*****************************************************************************
+ * SetCommTimeouts (KERNEL32.453)
+ */
+BOOL32 SetCommTimeouts(HANDLE32 hfile,LPCOMMTIMEOUTS lptimeouts) {
+ dprintf_comm(stddeb,"SetCommTimeouts(%lx,%p), empty stub.\n",
+ (DWORD)hfile,lptimeouts
+ );
+ return TRUE;
+}
diff --git a/misc/commdlg.c b/misc/commdlg.c
index dda9e25..176bb5a 100644
--- a/misc/commdlg.c
+++ b/misc/commdlg.c
@@ -416,13 +416,8 @@
UINT control,notification;
/* Notifications are packaged differently in Win32 */
-#ifdef WINELIB32
- control = LOWORD(wParam);
- notification = HIWORD(wParam);
-#else
control = wParam;
notification = HIWORD(lParam);
-#endif
lpofn = (LPOPENFILENAME)GetWindowLong32A(hWnd, DWL_USER);
switch (control)
diff --git a/misc/lstr.c b/misc/lstr.c
index 2c811e3..fc0de18 100644
--- a/misc/lstr.c
+++ b/misc/lstr.c
@@ -631,3 +631,148 @@
STRING32_AnsiToUni(d,x);
return TRUE;
}
+
+/***********************************************************************
+ * FormatMessageA (KERNEL32.138)
+ * FIXME: missing wrap, function has no clue about varargs handling
+ */
+DWORD
+FormatMessage32A(
+ DWORD dwFlags,
+ LPCVOID lpSource,
+ DWORD dwMessageId,
+ DWORD dwLanguageId,
+ LPSTR lpBuffer,
+ DWORD nSize,
+ LPDWORD *Arguments /* va_list *Arguments */
+) {
+ LPSTR target,t;
+ DWORD talloced;
+ LPSTR from,f;
+ DWORD width = dwFlags & FORMAT_MESSAGE_MAX_WIDTH_MASK;
+
+ fprintf(stddeb,"FormatMessage32A(0x%lx,%p,%ld,0x%lx,%p,%ld,%p)\n",
+ dwFlags,lpSource,dwMessageId,dwLanguageId,lpBuffer,
+ nSize,Arguments
+ );
+ if (width)
+ fprintf(stdnimp," - line wrapping not supported.\n");
+ from = NULL;
+ if (dwFlags & FORMAT_MESSAGE_FROM_STRING)
+ from = (LPSTR)lpSource;
+ if (dwFlags & FORMAT_MESSAGE_FROM_SYSTEM) {
+ /* gather information from system message tables ... */
+ fprintf(stdnimp," - FORMAT_MESSAGE_FROM_SYSTEM not implemented.\n");
+ }
+ if (dwFlags & FORMAT_MESSAGE_FROM_HMODULE) {
+ /* gather information from module's message tables ... */
+ fprintf(stdnimp," - FORMAT_MESSAGE_FROM_HMODULE not implemented.\n");
+ }
+ target = (char*)xmalloc(100);
+ t = target;
+ talloced= 100;
+ *t = 0;
+
+#define ADD_TO_T(c) \
+ *t++=c;\
+ if (t-target == talloced) {\
+ target = (char*)xrealloc(target,talloced*2);\
+ t = target+talloced;\
+ talloced*=2;\
+ }
+
+ if (from) {
+ f=from;
+ fprintf(stddeb," from is %s\n",from);
+ while (*f) {
+ if (*f=='%') {
+ int insertnr;
+ char *fmtstr,*sprintfbuf,*x;
+ DWORD arg1,arg2,arg3;
+
+ f++;
+ if (!*f) {
+ ADD_TO_T('%');
+ continue;
+ }
+ switch (*f) {
+ case '1':case '2':case '3':case '4':case '5':
+ case '6':case '7':case '8':case '9':
+ insertnr=*f-'0';
+ switch (f[1]) {
+ case '0':case '1':case '2':case '3':
+ case '4':case '5':case '6':case '7':
+ case '8':case '9':
+ f++;
+ insertnr=insertnr*10+*f-'0';
+ break;
+ default:break;
+ }
+ if (f[1]=='!') {
+ f+=2;
+ if (NULL!=(x=strchr(f,'!'))) {
+ *x='\0';
+ fmtstr=strdup(f);
+ f=x+1;
+ }
+ } else {
+ fmtstr=strdup("%s");
+ }
+
+ if (dwFlags & FORMAT_MESSAGE_ARGUMENT_ARRAY) {
+ DWORD *args = (DWORD*)Arguments;
+ arg1 = args[insertnr-1];
+ arg2 = args[insertnr+0];
+ arg3 = args[insertnr+1];
+ } else {
+ /*
+ int i;
+ va_list vl;
+
+ vl=va_start(Arguments,7);
+ for (i=insertnr;i--;)
+ va_arg(vl,DWORD);
+ arg1 = va_arg(vl,DWORD);
+ arg2 = va_arg(vl,DWORD);
+ arg3 = va_arg(vl,DWORD);
+ va_end(vl);
+ */
+ fprintf(stdnimp," - varargs not supported yet.\n");
+ }
+
+ if (fmtstr[strlen(fmtstr)]=='s') {
+ sprintfbuf=(char*)xmalloc(strlen((LPSTR)arg1)+1);
+ } else {
+ sprintfbuf=(char*)xmalloc(100);
+ }
+ sprintf(sprintfbuf,fmtstr,arg1,arg2,arg3);
+ x=sprintfbuf;
+ while (*x) {
+ ADD_TO_T(*x++);
+ }
+ free(sprintfbuf);
+ free(fmtstr);
+ break;
+ default:ADD_TO_T(*f++)
+ break;
+
+ }
+ } else {
+ ADD_TO_T(*f++)
+ }
+ }
+ *t='\0';
+ }
+ talloced = strlen(target)+1;
+ if (nSize && talloced<nSize) {
+ target = (char*)xrealloc(target,nSize);
+ }
+ if (dwFlags & FORMAT_MESSAGE_ALLOCATE_BUFFER) {
+ /* nSize is the MINIMUM size */
+ *((LPVOID*)lpBuffer) = (LPVOID)LocalAlloc32(GMEM_ZEROINIT,talloced);
+ memcpy(*(LPSTR*)lpBuffer,target,talloced);
+ } else
+ strncpy(lpBuffer,target,nSize);
+ free(target);
+ return strlen(lpBuffer);
+}
diff --git a/misc/port.c b/misc/port.c
index 33866f1..3eec824 100644
--- a/misc/port.c
+++ b/misc/port.c
@@ -22,25 +22,26 @@
#endif /* HAVE_USLEEP */
#ifndef HAVE_MEMMOVE
-void *memmove( void *dst, const void *src, unsigned int len )
+void *memmove( void *dest, const void *src, unsigned int len )
{
+ register char *dst = dest;
+
/* Use memcpy if not overlapping */
- if (((char *)dst + len <= (char *)src) ||
- ((char *)src + len <= (char *)dst))
+ if ((dst + len <= (char *)src) || ((char *)src + len <= dst))
{
memcpy( dst, src, len );
}
/* Otherwise do it the hard way (FIXME: could do better than this) */
else if (dst < src)
{
- while (len--) *((char *)dst)++ = *((char *)src)++;
+ while (len--) *dst++ = *((char *)src)++;
}
else
{
- dst = (char *)dst + len - 1;
+ dst += len - 1;
src = (char *)src + len - 1;
- while (len--) *((char *)dst)-- = *((char *)src)--;
+ while (len--) *dst-- = *((char *)src)--;
}
- return dst;
+ return dest;
}
#endif /* HAVE_MEMMOVE */
diff --git a/miscemu/dosmem.c b/miscemu/dosmem.c
index 95f1aa0..8b454e7 100644
--- a/miscemu/dosmem.c
+++ b/miscemu/dosmem.c
@@ -2,6 +2,7 @@
* DOS memory emulation
*
* Copyright 1995 Alexandre Julliard
+ * Copyright 1996 Marcus Meissner
*/
#include <signal.h>
@@ -14,6 +15,7 @@
#include "ldt.h"
#include "miscemu.h"
#include "module.h"
+#include "debug.h"
HANDLE16 DOSMEM_BiosSeg; /* BIOS data segment at 0x40:0 */
@@ -76,6 +78,11 @@
static BIOSDATA *pBiosData = NULL;
+char *DOSMEM_dosmem;
+struct dosmem_entry {
+ struct dosmem_entry *next;
+ BYTE isfree;
+};
/***********************************************************************
@@ -87,54 +94,82 @@
BOOL32 DOSMEM_Init(void)
{
HMODULE16 hModule = GetModuleHandle( "KERNEL" );
- char *dosmem;
- /* Allocate 7 64k segments for 0000, A000, B000, C000, D000, E000, F000. */
-
- dosmem = VirtualAlloc( NULL, 0x70000, MEM_COMMIT, PAGE_EXECUTE_READWRITE );
- if (!dosmem)
+ /* Allocate 1 MB dosmemory */
+ /* Yes, allocating 1 MB of memory, which is usually not even used, is a
+ * waste of memory. But I (MM) don't see any easy method to use
+ * GlobalDOS{Alloc,Free} within an area of memory, with protected mode
+ * selectors pointing into it, and the possibilty, that the userprogram
+ * calls SetSelectorBase(,physical_address_in_DOSMEM); that includes
+ * dynamical enlarging (reallocing) the dosmem area.
+ * Yes, one could walk the ldt_copy on every realloc() on DOSMEM, but
+ * this feels more like a hack to me than this current implementation is.
+ * If you find another, better, method, just change it. -Marcus Meissner
+ */
+ DOSMEM_dosmem = VirtualAlloc(NULL,0x1000000,MEM_COMMIT,PAGE_EXECUTE_READWRITE);
+ if (!DOSMEM_dosmem)
{
- fprintf( stderr, "Could not allocate DOS segments\n" );
+ fprintf( stderr, "Could not allocate DOS memory.\n" );
return FALSE;
}
MODULE_SetEntryPoint( hModule, 183, /* KERNEL.183: __0000H */
- GLOBAL_CreateBlock( GMEM_FIXED, dosmem,
+ GLOBAL_CreateBlock( GMEM_FIXED, DOSMEM_dosmem,
0x10000, hModule, FALSE, FALSE, FALSE, NULL ));
- DOSMEM_BiosSeg = GLOBAL_CreateBlock( GMEM_FIXED, dosmem + 0x400, 0x100,
+ DOSMEM_BiosSeg = GLOBAL_CreateBlock(GMEM_FIXED,DOSMEM_dosmem+0x400,0x100,
hModule, FALSE, FALSE, FALSE, NULL );
MODULE_SetEntryPoint( hModule, 193, /* KERNEL.193: __0040H */
DOSMEM_BiosSeg );
MODULE_SetEntryPoint( hModule, 174, /* KERNEL.174: __A000H */
- GLOBAL_CreateBlock( GMEM_FIXED, dosmem + 0x10000,
+ GLOBAL_CreateBlock( GMEM_FIXED, DOSMEM_dosmem+0xA0000,
0x10000, hModule, FALSE, FALSE, FALSE, NULL ));
MODULE_SetEntryPoint( hModule, 181, /* KERNEL.181: __B000H */
- GLOBAL_CreateBlock( GMEM_FIXED, dosmem + 0x20000,
+ GLOBAL_CreateBlock( GMEM_FIXED, DOSMEM_dosmem+0xB0000,
0x10000, hModule, FALSE, FALSE, FALSE, NULL ));
MODULE_SetEntryPoint( hModule, 182, /* KERNEL.182: __B800H */
- GLOBAL_CreateBlock( GMEM_FIXED, dosmem + 0x28000,
+ GLOBAL_CreateBlock( GMEM_FIXED, DOSMEM_dosmem+0xB8000,
0x10000, hModule, FALSE, FALSE, FALSE, NULL ));
MODULE_SetEntryPoint( hModule, 195, /* KERNEL.195: __C000H */
- GLOBAL_CreateBlock( GMEM_FIXED, dosmem + 0x30000,
+ GLOBAL_CreateBlock( GMEM_FIXED, DOSMEM_dosmem+0xC0000,
0x10000, hModule, FALSE, FALSE, FALSE, NULL ));
MODULE_SetEntryPoint( hModule, 179, /* KERNEL.179: __D000H */
- GLOBAL_CreateBlock( GMEM_FIXED, dosmem + 0x40000,
+ GLOBAL_CreateBlock( GMEM_FIXED, DOSMEM_dosmem+0xD0000,
0x10000, hModule, FALSE, FALSE, FALSE, NULL ));
MODULE_SetEntryPoint( hModule, 190, /* KERNEL.190: __E000H */
- GLOBAL_CreateBlock( GMEM_FIXED, dosmem + 0x50000,
+ GLOBAL_CreateBlock( GMEM_FIXED, DOSMEM_dosmem+0xE0000,
0x10000, hModule, FALSE, FALSE, FALSE, NULL ));
MODULE_SetEntryPoint( hModule, 173, /* KERNEL.173: __ROMBIOS */
- GLOBAL_CreateBlock( GMEM_FIXED, dosmem + 0x60000,
+ GLOBAL_CreateBlock( GMEM_FIXED, DOSMEM_dosmem+0xF0000,
0x10000, hModule, FALSE, FALSE, FALSE, NULL ));
MODULE_SetEntryPoint( hModule, 194, /* KERNEL.194: __F000H */
- GLOBAL_CreateBlock( GMEM_FIXED, dosmem + 0x60000,
+ GLOBAL_CreateBlock( GMEM_FIXED, DOSMEM_dosmem+0xF0000,
0x10000, hModule, FALSE, FALSE, FALSE, NULL ));
DOSMEM_FillBiosSegment();
+ DOSMEM_InitMemoryHandling();
+ DOSMEM_InitCollateTable();
+
return TRUE;
}
+/***********************************************************************
+ * DOSMEM_InitMemoryHandling
+ *
+ * Initialises the DOS Memory structures.
+ */
+void
+DOSMEM_InitMemoryHandling()
+{
+ struct dosmem_entry *dm;
+
+ dm = (struct dosmem_entry*)(DOSMEM_dosmem+0x10000);
+ dm->isfree = 1;
+ dm->next = (struct dosmem_entry*)(DOSMEM_dosmem+0x9FFF0);
+ dm = dm->next;
+ dm->isfree = 0;
+ dm->next = NULL;
+}
/***********************************************************************
* DOSMEM_Tick
@@ -180,3 +215,146 @@
pBiosData->KbdBufferEnd = 0x3e;
}
+/***********************************************************************
+ * DOSMEM_InitCollateTable
+ *
+ * Initialises the collate table (character sorting, language dependend)
+ */
+DWORD DOSMEM_CollateTable;
+
+void
+DOSMEM_InitCollateTable()
+{
+ DWORD x;
+ unsigned char *tbl;
+ int i;
+
+ x=GlobalDOSAlloc(258);
+ DOSMEM_CollateTable=MAKELONG(0,(x>>16));
+ tbl=DOSMEM_RealMode2Linear(DOSMEM_CollateTable);
+ *(WORD*)tbl = 0x100;
+ tbl+=2;
+ for (i=0;i<0x100;i++)
+ *tbl++=i;
+}
+
+/***********************************************************************
+ * GlobalDOSAlloc (KERNEL.184)
+ *
+ * Allocates a piece of DOS Memory, in the first 1 MB physical memory.
+ *
+ * operates on the preallocated DOSMEM_dosmem (1MB). The useable area
+ * starts at 1000:0000 and ends at 9FFF:FFEF
+ * Memory allocation strategy is First Fit. (FIXME: Yes,I know that First Fit
+ * is a rather bad strategy. But since those functions are rather seldom
+ * called, it's easyness fits the purpose well.)
+ *
+ */
+
+DWORD GlobalDOSAlloc(DWORD size)
+{
+ struct dosmem_entry *dm,*ndm;
+ DWORD start,blocksize;
+ WORD sel;
+ HMODULE16 hModule=GetModuleHandle("KERNEL");
+
+
+ start = 0;
+ dm = (struct dosmem_entry*)(DOSMEM_dosmem+0x10000);
+ size = (size+0xf)&~0xf;
+ while (dm && dm->next) {
+ blocksize = ((char*)dm->next-(char*)dm)-16;
+ if ((dm->isfree) && (blocksize>=size)) {
+ dm->isfree = 0;
+ start = ((((char*)dm)-DOSMEM_dosmem)+0x10)& ~0xf;
+ if ((blocksize-size) >= 0x20) {
+ /* if enough memory is left for a new block
+ * split this area into two blocks
+ */
+ ndm=(struct dosmem_entry*)((char*)dm+0x10+size);
+ ndm->isfree = 1;
+ ndm->next = dm->next;
+ dm->next = ndm;
+ }
+ break;
+ }
+ dm=dm->next;
+ }
+ if (!start)
+ return 0;
+ sel=GLOBAL_CreateBlock(
+ GMEM_FIXED,DOSMEM_dosmem+start,size,
+ hModule,FALSE,FALSE,FALSE,NULL
+ );
+ return MAKELONG(sel,start>>4);
+}
+
+/***********************************************************************
+ * GlobalDOSFree (KERNEL.185)
+ *
+ * Frees allocated dosmemory and corresponding selector.
+ */
+
+WORD
+GlobalDOSFree(WORD sel)
+{
+ DWORD base;
+ struct dosmem_entry *dm;
+
+ base = GetSelectorBase(sel);
+ /* base has already been conversed to a physical address */
+ if (base>=0x100000)
+ return sel;
+ dm = (struct dosmem_entry*)(DOSMEM_dosmem+base-0x10);
+ if (dm->isfree) {
+ fprintf(stderr,"Freeing already freed DOSMEM.\n");
+ return 0;
+ }
+ dm->isfree = 1;
+
+ /* collapse adjunct free blocks into one */
+ dm = (struct dosmem_entry*)(DOSMEM_dosmem+0x10000);
+ while (dm && dm->next) {
+ if (dm->isfree && dm->next->isfree)
+ dm->next = dm->next->next;
+ dm = dm->next;
+ }
+ GLOBAL_FreeBlock(sel);
+ return 0;
+}
+
+/***********************************************************************
+ * DOSMEM_RealMode2Linear
+ *
+ * Converts a realmode segment:offset address into a linear pointer
+ */
+LPVOID DOSMEM_RealMode2Linear(DWORD x)
+{
+ LPVOID lin;
+
+ lin=DOSMEM_dosmem+(x&0xffff)+(((x&0xffff0000)>>16)*16);
+ dprintf_selector(stddeb,"DOSMEM_RealMode2Linear(0x%08lx) returns 0x%p.\n",
+ x,lin
+ );
+ return lin;
+}
+
+/***********************************************************************
+ * DOSMEM_RealMode2Linear
+ *
+ * Allocates a protected mode selector for a realmode segment.
+ */
+WORD DOSMEM_AllocSelector(WORD realsel)
+{
+ HMODULE16 hModule=GetModuleHandle("KERNEL");
+ WORD sel;
+
+ sel=GLOBAL_CreateBlock(
+ GMEM_FIXED,DOSMEM_dosmem+realsel*16,0x10000,
+ hModule,FALSE,FALSE,FALSE,NULL
+ );
+ dprintf_selector(stddeb,"DOSMEM_AllocSelector(0x%04x) returns 0x%04x.\n",
+ realsel,sel
+ );
+ return sel;
+}
diff --git a/miscemu/dpmi.c b/miscemu/dpmi.c
index 738c413..2e41f4b 100644
--- a/miscemu/dpmi.c
+++ b/miscemu/dpmi.c
@@ -98,10 +98,7 @@
case 0xe000: entryPoint = 190; break; /* __E000H */
case 0xf000: entryPoint = 194; break; /* __F000H */
default:
- fprintf( stderr, "DPMI: real-mode seg to descriptor %04x not possible\n",
- BX_reg(context) );
- AX_reg(context) = 0x8011;
- SET_CFLAG(context);
+ AX_reg(context) = DOSMEM_AllocSelector(BX_reg(context));
break;
}
if (entryPoint)
@@ -215,6 +212,35 @@
do_mscdex( context );
break;
}
+ /* NETAPI.DLL of Win95 does AX=6506 to fetch a realmode ptr
+ * to the COLLATE table.
+ */
+ if (BL_reg(context) == 0x21) {
+ switch ((p->eax & 0xFF00)>>8) {
+ case 0x65:
+ switch (p->eax & 0xFF) {
+ case 06:{/* get collate table */
+ extern DWORD DOSMEM_CollateTable;
+ char *table;
+ /* ES:DI is a REALMODE pointer to 5 byte dosmem
+ * we fill that with 0x6, realmode pointer to collateTB
+ */
+ table = DOSMEM_RealMode2Linear(MAKELONG(p->edi,p->es));
+ *(BYTE*)table = 0x06;
+ *(DWORD*)(table+1) = DOSMEM_CollateTable;
+
+ CX_reg(context) = 258;/*FIXME: size of table?*/
+ break;
+ }
+ default:
+ SET_CFLAG(context);
+ }
+ default:
+ SET_CFLAG(context);
+ break;
+ }
+ break;
+ }
SET_CFLAG(context);
}
break;
@@ -243,6 +269,18 @@
}
break;
+ case 0x0303: /* Allocate Real Mode Callback Address */
+ {
+ REALMODECALL *p = (REALMODECALL *)PTR_SEG_OFF_TO_LIN( ES_reg(context), DI_reg(context) );
+ fprintf(stdnimp,
+ "AllocRMCB: EAX=%08lx EBX=%08lx ECX=%08lx EDX=%08lx\n"
+ " ESI=%08lx EDI=%08lx ES=%04x DS=%04x CS:IP=%04x:%04x\n",
+ p->eax, p->ebx, p->ecx, p->edx,
+ p->esi, p->edi, p->es, p->ds, p->cs, p->ip );
+ SET_CFLAG(context);
+ }
+ break;
+
case 0x0400: /* Get DPMI version */
AX_reg(context) = 0x005a; /* DPMI version 0.90 */
BX_reg(context) = 0x0005; /* Flags: 32-bit, virtual memory */
diff --git a/miscemu/int21.c b/miscemu/int21.c
index 79176dc..7594219 100644
--- a/miscemu/int21.c
+++ b/miscemu/int21.c
@@ -1308,6 +1308,9 @@
case 0x0d:
ioctlGenericBlkDevReq(context);
break;
+ case 0x0e: /* get logical drive mapping */
+ AL_reg(context) = 0; /* drive has no mapping */
+ break;
case 0x0F: /* Set logical drive mapping */
/* FIXME: Not implemented at the moment, always returns error
diff --git a/multimedia/time.c b/multimedia/time.c
index cd2d86b..b525372 100644
--- a/multimedia/time.c
+++ b/multimedia/time.c
@@ -174,6 +174,8 @@
if (lpTimer->Next != NULL)
lpTimer->Next->Prev = lpTimer->Prev;
free(lpTimer);
+ if (lpTimer==lpTimerList)
+ lpTimerList=NULL;
return TRUE;
}
lpTimer = lpTimer->Next;
diff --git a/objects/bitblt.c b/objects/bitblt.c
index 4eba5db..1cb29bb 100644
--- a/objects/bitblt.c
+++ b/objects/bitblt.c
@@ -891,7 +891,8 @@
short width = visRectDst->right - visRectDst->left;
short height = visRectDst->bottom - visRectDst->top;
- if (!COLOR_PixelToPalette || (dc->w.bitsPerPixel == 1))
+ if (!COLOR_PixelToPalette || (dc->w.bitsPerPixel == 1) ||
+ (COLOR_GetSystemPaletteFlags() & COLOR_VIRTUAL) )
{
XCopyArea( display, dc->u.x.drawable, pixmap, gc,
visRectDst->left, visRectDst->top, width, height, 0, 0 );
@@ -922,7 +923,10 @@
short width = visRectDst->right - visRectDst->left;
short height = visRectDst->bottom - visRectDst->top;
- if (!COLOR_PaletteToPixel)
+ /* !COLOR_PaletteToPixel is _NOT_ enough */
+
+ if (!COLOR_PaletteToPixel || (dc->w.bitsPerPixel == 1) ||
+ (COLOR_GetSystemPaletteFlags() & COLOR_VIRTUAL) )
{
XCopyArea( display, pixmap, dc->u.x.drawable, gc, 0, 0,
width, height, visRectDst->left, visRectDst->top );
@@ -1111,6 +1115,20 @@
!Options.perfectGraphics)
{
XSetFunction( display, dcDst->u.x.gc, GXinvert );
+
+ if( COLOR_GetSystemPaletteFlags() & (COLOR_PRIVATE | COLOR_VIRTUAL) )
+ XSetFunction( display, dcDst->u.x.gc, GXinvert);
+ else
+ {
+ /* Xor is much better when we do not have full colormap. */
+ /* Using white^black ensures that we invert at least black */
+ /* and white. */
+ Pixel xor_pix = (WhitePixelOfScreen(screen) ^
+ BlackPixelOfScreen(screen));
+ XSetFunction( display, dcDst->u.x.gc, GXxor );
+ XSetForeground( display, dcDst->u.x.gc, xor_pix);
+ XSetFillStyle( display, dcDst->u.x.gc, FillSolid );
+ }
XFillRectangle( display, dcDst->u.x.drawable, dcDst->u.x.gc,
visRectDst.left, visRectDst.top, width, height );
return TRUE;
diff --git a/objects/bitmap.c b/objects/bitmap.c
index 5680581..f609f25 100644
--- a/objects/bitmap.c
+++ b/objects/bitmap.c
@@ -227,6 +227,35 @@
return height * bmp->bitmap.bmWidthBytes;
}
+/**********************************************************************
+ * LoadImageA (USER32.364)
+ * FIXME: implementation still lacks nearly all features, see LR_*
+ * defines in windows.h
+ */
+
+HANDLE32 LoadImage32A(
+ HINSTANCE32 hinst,LPCSTR name,UINT32 type,INT32 desiredx,
+ INT32 desiredy,UINT32 loadflags
+) {
+ if (HIWORD(name)) {
+ dprintf_resource(stddeb,"LoadImage32A(0x%04x,%s,%d,%d,%d,0x%08x)\n",
+ hinst,name,type,desiredx,desiredy,loadflags
+ );
+ } else {
+ dprintf_resource(stddeb,"LoadImage32A(0x%04x,%p,%d,%d,%d,0x%08x)\n",
+ hinst,name,type,desiredx,desiredy,loadflags
+ );
+ }
+ switch (type) {
+ case IMAGE_BITMAP:
+ return LoadBitmap32A(hinst,name);
+ case IMAGE_ICON:
+ return LoadIcon32A(hinst,name);
+ case IMAGE_CURSOR:
+ return LoadCursor32A(hinst,name);
+ }
+ return 0;
+}
/**********************************************************************
* LoadBitmap16 (USER.175)
diff --git a/objects/brush.c b/objects/brush.c
index 6331df0..00553ab 100644
--- a/objects/brush.c
+++ b/objects/brush.c
@@ -236,7 +236,7 @@
/***********************************************************************
* SetBrushOrg (GDI.148)
*/
-DWORD SetBrushOrg( HDC hdc, short x, short y )
+DWORD SetBrushOrg( HDC16 hdc, INT16 x, INT16 y )
{
DWORD retval;
DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
@@ -247,14 +247,36 @@
return retval;
}
+
+/***********************************************************************
+ * SetBrushOrgEx (GDI32.308)
+ */
+BOOL32 SetBrushOrgEx( HDC32 hdc, INT32 x, INT32 y, LPPOINT32 oldorg )
+{
+ DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
+
+ if (!dc) return FALSE;
+ if (oldorg)
+ {
+ oldorg->x = dc->w.brushOrgX;
+ oldorg->y = dc->w.brushOrgY;
+ }
+ dc->w.brushOrgX = x;
+ dc->w.brushOrgY = y;
+ return TRUE;
+}
+
+
/***********************************************************************
* GetSysColorBrush (USER.281)
*/
HBRUSH GetSysColorBrush(WORD x)
{
- return GetStockObject(GRAY_BRUSH);
+ fprintf( stderr, "Unimplemented stub: GetSysColorBrush(%d)\n", x );
+ return GetStockObject(LTGRAY_BRUSH);
}
+
/***********************************************************************
* BRUSH_DeleteObject
*/
diff --git a/objects/color.c b/objects/color.c
index e92adea..b7c45a2 100644
--- a/objects/color.c
+++ b/objects/color.c
@@ -62,7 +62,8 @@
* currently inactive window it changes only DC palette mappings.
*/
-#define NB_RESERVED_COLORS 20 /* number of fixed colors in system palette */
+#define NB_RESERVED_COLORS 20 /* number of fixed colors in system palette */
+#define NB_COLORCUBE_START_INDEX 63
Visual* visual = NULL;
@@ -71,7 +72,8 @@
static int COLOR_gapEnd = -1;
/* First free dynamic color cell, 0 = full palette, -1 = fixed palette */
-static int COLOR_firstFree = 0;
+static int COLOR_firstFree = 0;
+static unsigned char COLOR_freeList[256];
/* Maps entry in the system palette to X pixel value */
int* COLOR_PaletteToPixel = NULL;
@@ -134,21 +136,97 @@
return cSpace.flags;
}
-void COLOR_FormatSystemPalette(void)
+COLORREF COLOR_GetSystemPaletteEntry(BYTE i)
{
- int i, j = COLOR_firstFree = NB_RESERVED_COLORS/2;
-
- COLOR_sysPal[j].peFlags = 0;
- for( i = NB_RESERVED_COLORS/2 + 1 ; i < 256 - NB_RESERVED_COLORS/2 ; i++ )
- if( i < COLOR_gapStart || i > COLOR_gapEnd )
- {
- COLOR_sysPal[i].peFlags = 0; /* unused tag */
- COLOR_sysPal[j].peRed = i; /* next */
- j = i;
- }
- COLOR_sysPal[j].peRed = 0; /* terminal */
+ return *(COLORREF*)(COLOR_sysPal + i) & 0x00ffffff;
}
+void COLOR_FormatSystemPalette(void)
+{
+ /* Build free list so we'd have an easy way to find
+ * out if there are any available colorcells.
+ */
+
+ int i, j = COLOR_firstFree = NB_RESERVED_COLORS/2;
+
+ COLOR_sysPal[j].peFlags = 0;
+ for( i = NB_RESERVED_COLORS/2 + 1 ; i < 256 - NB_RESERVED_COLORS/2 ; i++ )
+ if( i < COLOR_gapStart || i > COLOR_gapEnd )
+ {
+ COLOR_sysPal[i].peFlags = 0; /* unused tag */
+ COLOR_freeList[j] = i; /* next */
+ j = i;
+ }
+ COLOR_freeList[j] = 0;
+}
+
+void COLOR_FillDefaultColors(void)
+{
+ /* initialize unused entries to what Windows uses as a color
+ * cube - based on Greg Kreider's code.
+ */
+
+ int i = 0, idx = 0;
+ int red, no_r, inc_r;
+ int green, no_g, inc_g;
+ int blue, no_b, inc_b;
+
+ while (i*i*i < (cSpace.size - NB_RESERVED_COLORS)) i++;
+ no_r = no_g = no_b = --i;
+ if ((no_r * (no_g+1) * no_b) < (cSpace.size - NB_RESERVED_COLORS)) no_g++;
+ if ((no_r * no_g * (no_b+1)) < (cSpace.size - NB_RESERVED_COLORS)) no_b++;
+ inc_r = (255 - NB_COLORCUBE_START_INDEX)/no_r;
+ inc_g = (255 - NB_COLORCUBE_START_INDEX)/no_g;
+ inc_b = (255 - NB_COLORCUBE_START_INDEX)/no_b;
+
+ idx = COLOR_firstFree;
+
+ for (blue = NB_COLORCUBE_START_INDEX; blue < 256 && idx; blue += inc_b )
+ for (green = NB_COLORCUBE_START_INDEX; green < 256 && idx; green += inc_g )
+ for (red = NB_COLORCUBE_START_INDEX; red < 256 && idx; red += inc_r )
+ {
+ /* weird but true */
+
+ if( red == NB_COLORCUBE_START_INDEX && green == red && blue == green ) continue;
+
+ COLOR_sysPal[idx].peRed = red;
+ COLOR_sysPal[idx].peGreen = green;
+ COLOR_sysPal[idx].peBlue = blue;
+
+ /* set X color */
+
+ if( cSpace.flags & COLOR_VIRTUAL )
+ {
+ if (COLOR_Redmax != 255) no_r = (red * COLOR_Redmax) / 255;
+ if (COLOR_Greenmax != 255) no_g = (green * COLOR_Greenmax) / 255;
+ if (COLOR_Bluemax != 255) no_b = (blue * COLOR_Bluemax) / 255;
+
+ COLOR_PaletteToPixel[idx] = (no_r << COLOR_Redshift) | (no_g << COLOR_Greenshift) | (no_b << COLOR_Blueshift);
+ }
+ else if( !(cSpace.flags & COLOR_FIXED) )
+ {
+ XColor color = { color.pixel = (COLOR_PaletteToPixel)? COLOR_PaletteToPixel[idx] : idx ,
+ COLOR_sysPal[idx].peRed << 8,
+ COLOR_sysPal[idx].peGreen << 8,
+ COLOR_sysPal[idx].peGreen << 8,
+ (DoRed | DoGreen | DoBlue) };
+ XStoreColor(display, cSpace.colorMap, &color);
+ }
+
+ idx = COLOR_freeList[idx];
+ }
+
+ /* fill the rest with gray for now - only needed for
+ * sparse palette (in seamless mode)
+ */
+
+ for ( i = COLOR_gapStart; i <= COLOR_gapEnd; i++ )
+ {
+ *(COLORREF*)(COLOR_sysPal + i) = 0x00c0c0c0;
+ if( COLOR_PaletteToPixel )
+ COLOR_PaletteToPixel[i] = COLOR_PaletteToPixel[7];
+ }
+}
/***********************************************************************
* COLOR_BuildPrivateMap/COLOR_BuildSharedMap
@@ -310,6 +388,7 @@
* color translations but we have to allocate full palette
* to maintain compatibility
*/
+ cs->size = 256;
dprintf_palette(stddeb,"\tvirtual colorspace - screendepth %i\n", screenDepth);
}
else cs->size = NB_RESERVED_COLORS; /* system palette only - however we can alloc a bunch
@@ -338,40 +417,47 @@
/* Setup system palette entry <-> pixel mappings and fill in 20 fixed entries */
if( screenDepth <= 8 )
- {
+ {
COLOR_PixelToPalette = (int*)xmalloc(sizeof(int)*256);
- COLOR_PaletteToPixel = (int*)xmalloc(sizeof(int)*256);
+ memset( COLOR_PixelToPalette, 0, 256*sizeof(int) );
+ }
- for( i = j = 0; i < 256; i++ )
- {
- if( i >= COLOR_gapStart && i <= COLOR_gapEnd )
- {
- COLOR_PaletteToPixel[i] = 0;
- COLOR_sysPal[i].peFlags = 0; /* mark as unused */
- continue;
- }
+ /* for hicolor visuals PaletteToPixel mapping is used to skip
+ * RGB->pixel calculation in COLOR_ToPhysical().
+ */
- if( i < NB_RESERVED_COLORS/2 )
- {
- COLOR_PaletteToPixel[i] = sysPixel[i];
- COLOR_sysPal[i] = __sysPalTemplate[i];
- }
- else if( i >= 256 - NB_RESERVED_COLORS/2 )
- {
- COLOR_PaletteToPixel[i] = sysPixel[(i + NB_RESERVED_COLORS) - 256];
- COLOR_sysPal[i] = __sysPalTemplate[(i + NB_RESERVED_COLORS) - 256];
- }
- else if( pixDynMapping )
- COLOR_PaletteToPixel[i] = pixDynMapping[j++];
+ COLOR_PaletteToPixel = (int*)xmalloc(sizeof(int)*256);
+
+ for( i = j = 0; i < 256; i++ )
+ {
+ if( i >= COLOR_gapStart && i <= COLOR_gapEnd )
+ {
+ COLOR_PaletteToPixel[i] = 0;
+ COLOR_sysPal[i].peFlags = 0; /* mark as unused */
+ continue;
+ }
+
+ if( i < NB_RESERVED_COLORS/2 )
+ {
+ COLOR_PaletteToPixel[i] = sysPixel[i];
+ COLOR_sysPal[i] = __sysPalTemplate[i];
+ }
+ else if( i >= 256 - NB_RESERVED_COLORS/2 )
+ {
+ COLOR_PaletteToPixel[i] = sysPixel[(i + NB_RESERVED_COLORS) - 256];
+ COLOR_sysPal[i] = __sysPalTemplate[(i + NB_RESERVED_COLORS) - 256];
+ }
+ else if( pixDynMapping )
+ COLOR_PaletteToPixel[i] = pixDynMapping[j++];
else
- COLOR_PaletteToPixel[i] = i;
+ COLOR_PaletteToPixel[i] = i;
- dprintf_palette(stddeb,"\tindex %i -> pixel %i\n", i, COLOR_PaletteToPixel[i]);
+ dprintf_palette(stddeb,"\tindex %i -> pixel %i\n", i, COLOR_PaletteToPixel[i]);
- memset( COLOR_PixelToPalette, 0, 256*sizeof(int) );
- COLOR_PixelToPalette[COLOR_PaletteToPixel[i]] = i;
- }
+ if( COLOR_PixelToPalette )
+ COLOR_PixelToPalette[COLOR_PaletteToPixel[i]] = i;
}
+
if( pixDynMapping ) free(pixDynMapping);
return TRUE;
}
@@ -387,6 +473,9 @@
int i;
HPALETTE16 hpalette;
LOGPALETTE * palPtr;
+ PALETTEOBJ* palObj;
+
+ memset(COLOR_freeList, 0, 256*sizeof(unsigned char));
/* calculate max palette size */
@@ -397,11 +486,13 @@
else
COLOR_BuildSharedMap( &cSpace );
- /* Build free list ( use peRed as "next" ) */
+ /* Build free list */
if( COLOR_firstFree != -1 )
COLOR_FormatSystemPalette();
+ COLOR_FillDefaultColors();
+
/* create default palette (20 system colors) */
palPtr = xmalloc( sizeof(LOGPALETTE) + (NB_RESERVED_COLORS-1)*sizeof(PALETTEENTRY) );
@@ -417,6 +508,11 @@
palPtr->palPalEntry[i].peFlags = 0;
}
hpalette = CreatePalette( palPtr );
+
+ palObj = (PALETTEOBJ*) GDI_GetObjPtr( hpalette, PALETTE_MAGIC );
+
+ palObj->mapping = xmalloc( sizeof(int) * 20 );
+
free( palPtr );
return hpalette;
}
@@ -534,8 +630,7 @@
/***********************************************************************
- * COLOR_PaletteLookup
- *
+ * COLOR_PaletteLookupPixel
*/
int COLOR_PaletteLookupPixel( PALETTEENTRY* palPalEntry, int size,
int* mapping, COLORREF col, BOOL skipReserved )
@@ -543,7 +638,7 @@
int i, best = 0, diff = 0x7fffffff;
int r,g,b;
- for( i = 0; i < size; i++ )
+ for( i = 0; i < size && diff ; i++ )
{
if( !(palPalEntry[i].peFlags & PC_SYS_USED) ||
(skipReserved && palPalEntry[i].peFlags & PC_SYS_RESERVED) )
@@ -560,10 +655,33 @@
return (mapping) ? mapping[best] : best;
}
+/***********************************************************************
+ * COLOR_LookupSystemPixel
+ */
+int COLOR_LookupSystemPixel(COLORREF col)
+{
+ int i, best = 0, diff = 0x7fffffff;
+ int size = COLOR_GetSystemPaletteSize();
+ int r,g,b;
+
+ for( i = 0; i < size && diff ; i++ )
+ {
+ if( i == NB_RESERVED_COLORS/2 ) i = size - NB_RESERVED_COLORS/2;
+
+ r = COLOR_sysPal[i].peRed - GetRValue(col);
+ g = COLOR_sysPal[i].peGreen - GetGValue(col);
+ b = COLOR_sysPal[i].peBlue - GetBValue(col);
+
+ r = r*r + g*g + b*b;
+
+ if( r < diff ) { best = i; diff = r; }
+ }
+
+ return (COLOR_PaletteToPixel)? COLOR_PaletteToPixel[best] : best;
+}
/***********************************************************************
* COLOR_PaletteLookupExactIndex
- *
*/
int COLOR_PaletteLookupExactIndex( PALETTEENTRY* palPalEntry, int size,
COLORREF col )
@@ -581,6 +699,32 @@
return -1;
}
+/***********************************************************************
+ * COLOR_LookupNearestColor
+ */
+COLORREF COLOR_LookupNearestColor( PALETTEENTRY* palPalEntry, int size, COLORREF color )
+{
+ unsigned char spec_type = color >> 24;
+ int i;
+
+ /* we need logical palette for PALETTERGB and PALETTEINDEX colorrefs */
+
+ if( spec_type == 2 ) /* PALETTERGB */
+ color = *(COLORREF*)
+ (palPalEntry + COLOR_PaletteLookupPixel(palPalEntry,size,NULL,color,FALSE));
+
+ else if( spec_type == 1 ) /* PALETTEINDEX */
+ if( (i = color & 0x0000ffff) >= size )
+ {
+ fprintf(stderr, "\tRGB(%lx) : idx %d is out of bounds, assuming NULL\n", color, i);
+ color = *(COLORREF*)palPalEntry;
+ }
+ else color = *(COLORREF*)(palPalEntry + i);
+
+ color &= 0x00ffffff;
+ return (0x00ffffff & *(COLORREF*)
+ (COLOR_sysPal + COLOR_PaletteLookupPixel(COLOR_sysPal, 256, NULL, color, FALSE)));
+}
/***********************************************************************
* COLOR_ToLogical
@@ -590,13 +734,29 @@
COLORREF COLOR_ToLogical(int pixel)
{
XColor color;
-
- if (screenDepth > 8) return pixel;
- if ((screenDepth <= 8) && (pixel < 256) && !(cSpace.flags & COLOR_VIRTUAL))
- return ( *(COLORREF*)(COLOR_sysPal + ((COLOR_PixelToPalette)?COLOR_PixelToPalette[pixel]:pixel)) ) & 0x00ffffff;
- color.pixel = pixel;
- XQueryColor(display, cSpace.colorMap, &color);
+ /* truecolor visual */
+
+ if (screenDepth >= 24) return pixel;
+
+ /* check for hicolor visuals first */
+
+ if ( cSpace.flags & COLOR_FIXED && !COLOR_Graymax )
+ {
+ color.red = pixel >> COLOR_Redshift;
+ color.green = pixel >> COLOR_Greenshift;
+ color.blue = pixel >> COLOR_Blueshift;
+ }
+ else if ((screenDepth <= 8) && (pixel < 256) &&
+ !(cSpace.flags & (COLOR_VIRTUAL | COLOR_FIXED)) )
+ return ( *(COLORREF*)(COLOR_sysPal +
+ ((COLOR_PixelToPalette)?COLOR_PixelToPalette[pixel]:pixel)) ) & 0x00ffffff;
+ else
+ {
+ color.pixel = pixel;
+ XQueryColor(display, cSpace.colorMap, &color);
+ return RGB(color.red >> 8, color.green >> 8, color.blue >> 8);
+ }
return RGB((color.red * 255)/COLOR_Redmax,
(color.green * 255)/COLOR_Greenmax,
@@ -650,38 +810,37 @@
switch(spec_type)
{
- default:
- case 0: /* RGB */
-
- red = GetRValue(color);
- green = GetGValue(color);
- blue = GetBValue(color);
- break;
-
case 2: /* PALETTERGB - not sure if we really need to search palette */
idx = COLOR_PaletteLookupPixel( palPtr->logpalette.palPalEntry,
palPtr->logpalette.palNumEntries,
NULL, color, FALSE);
+
+ if( palPtr->mapping ) return palPtr->mapping[idx];
+
+ color = *(COLORREF*)(palPtr->logpalette.palPalEntry + idx);
+ break;
+
case 1: /* PALETTEINDEX */
- idx = ((spec_type == 1)?color:idx) & 0xffff;
-
- if (idx >= palPtr->logpalette.palNumEntries)
+ if ( (idx = color & 0xffff) >= palPtr->logpalette.palNumEntries)
{
fprintf(stderr, "\tRGB(%lx) : idx %d is out of bounds, assuming black\n", color, idx);
- /* out of bounds */
- red = green = blue = 0;
+ return 0;
}
- else if( palPtr->mapping ) return palPtr->mapping[idx];
- else
- {
- red = palPtr->logpalette.palPalEntry[idx].peRed;
- green = palPtr->logpalette.palPalEntry[idx].peGreen;
- blue = palPtr->logpalette.palPalEntry[idx].peBlue;
- }
+
+ if( palPtr->mapping ) return palPtr->mapping[idx];
+
+ color = *(COLORREF*)(palPtr->logpalette.palPalEntry + idx);
+
+ /* fall through and out */
+
+ case 0: /* RGB */
+ default:
}
+ red = GetRValue(color); green = GetGValue(color); blue = GetBValue(color);
+
if (COLOR_Graymax)
{
/* grayscale only; return scaled value */
@@ -740,7 +899,6 @@
return index;
}
-
/***********************************************************************
* COLOR_SetMapping
*
@@ -754,11 +912,10 @@
int prevMapping = (palPtr->mapping) ? 1 : 0;
int iRemapped = 0;
- /* free dynamic colors in system palette -
- * certain optimization is to free them only when they are needed */
+ /* reset dynamic system palette entries */
if( !mapOnly && COLOR_firstFree != -1)
- COLOR_FormatSystemPalette();
+ COLOR_FormatSystemPalette();
/* initialize palette mapping table */
@@ -783,6 +940,7 @@
case PC_RESERVED: /* forbid future mappings to this entry */
flag |= PC_SYS_RESERVED;
+
/* fall through */
default: /* try to collapse identical colors */
index = COLOR_PaletteLookupExactIndex(COLOR_sysPal, 256,
@@ -791,26 +949,32 @@
case PC_NOCOLLAPSE:
if( index < 0 )
{
- if( COLOR_firstFree > 0 && !(cSpace.flags & COLOR_FIXED) && !mapOnly )
+ if( COLOR_firstFree > 0 && !(cSpace.flags & COLOR_FIXED) )
{
XColor color;
index = COLOR_firstFree; /* ought to be available */
- COLOR_firstFree = COLOR_sysPal[index].peRed;
+ COLOR_firstFree = COLOR_freeList[index];
+
color.pixel = (COLOR_PaletteToPixel) ? COLOR_PaletteToPixel[index] : index;
- color.red = palPtr->logpalette.palPalEntry[i].peRed * 65535 / 255;
- color.green = palPtr->logpalette.palPalEntry[i].peGreen * 65535 / 255;
- color.blue = palPtr->logpalette.palPalEntry[i].peBlue * 65535 / 255;
+ color.red = palPtr->logpalette.palPalEntry[i].peRed << 8;
+ color.green = palPtr->logpalette.palPalEntry[i].peGreen << 8;
+ color.blue = palPtr->logpalette.palPalEntry[i].peBlue << 8;
color.flags = DoRed | DoGreen | DoBlue;
XStoreColor(display, cSpace.colorMap, &color);
+
COLOR_sysPal[index] = palPtr->logpalette.palPalEntry[i];
COLOR_sysPal[index].peFlags = flag;
if( COLOR_PaletteToPixel ) index = COLOR_PaletteToPixel[index];
+
+ COLOR_freeList[index] = 0;
+ palPtr->logpalette.palPalEntry[i].peFlags = PC_SYS_USED | PC_SYS_MAPPED;
break;
}
else if ( cSpace.flags & COLOR_VIRTUAL )
{
index = COLOR_ToPhysical( NULL, 0x00ffffff &
*(COLORREF*)(palPtr->logpalette.palPalEntry + i));
+ palPtr->logpalette.palPalEntry[i].peFlags = PC_SYS_USED;
break;
}
@@ -819,6 +983,7 @@
index = COLOR_PaletteLookupPixel(COLOR_sysPal, 256, NULL,
*(COLORREF*)(palPtr->logpalette.palPalEntry + i), TRUE);
}
+ palPtr->logpalette.palPalEntry[i].peFlags = PC_SYS_USED;
if( COLOR_PaletteToPixel ) index = COLOR_PaletteToPixel[index];
break;
@@ -827,9 +992,9 @@
if( !prevMapping || palPtr->mapping[i] != index ) iRemapped++;
palPtr->mapping[i] = index;
- /* dprintf_palette(stddeb,"\tentry %i (%lx) -> pixel %i\n", i,
+ dprintf_palette(stddeb,"\tentry %i (%lx) -> pixel %i\n", i,
*(COLORREF*)(palPtr->logpalette.palPalEntry + i), index);
- */
+
}
return iRemapped;
}
diff --git a/objects/cursoricon.c b/objects/cursoricon.c
index c750d61..5a35ff8 100644
--- a/objects/cursoricon.c
+++ b/objects/cursoricon.c
@@ -35,6 +35,7 @@
#include "xmalloc.h"
#include "task.h"
+extern UINT16 COLOR_GetSystemPaletteSize();
Cursor CURSORICON_XCursor = None; /* Current X cursor */
static HCURSOR hActiveCursor = 0; /* Active cursor */
@@ -491,7 +492,7 @@
return CURSORICON_Load( hInstance, name,
SYSMETRICS_CXICON, SYSMETRICS_CYICON,
- MIN( 16, 1 << screenDepth ), FALSE );
+ MIN( 16, COLOR_GetSystemPaletteSize() ), FALSE );
}
@@ -935,7 +936,8 @@
*/
WORD GetIconID( HANDLE hResource, DWORD resType )
{
- CURSORICONDIR *lpDir = LockResource16(hResource);
+ CURSORICONDIR *lpDir = (CURSORICONDIR *)GlobalLock16(hResource);
+/* LockResource16(hResource); */
if (!lpDir || lpDir->idReserved ||
((lpDir->idType != 1) && (lpDir->idType != 2)))
@@ -957,9 +959,9 @@
}
case 3: /* icon */
{
- ICONDIRENTRY *entry = CURSORICON_FindBestIcon( lpDir,
- SYSMETRICS_CXICON, SYSMETRICS_CYICON,
- MIN( 16, 1 << screenDepth ) );
+ ICONDIRENTRY * entry = CURSORICON_FindBestIcon( lpDir,
+ SYSMETRICS_CXICON, SYSMETRICS_CYICON,
+ MIN( 16, COLOR_GetSystemPaletteSize() ) );
return entry ? entry->wResId : 0;
}
}
diff --git a/objects/dc.c b/objects/dc.c
index 5e3eff9..58529ac 100644
--- a/objects/dc.c
+++ b/objects/dc.c
@@ -112,7 +112,7 @@
caps->numPens = 16; /* 16 solid pens */
caps->numMarkers = 0;
caps->numFonts = 0;
- caps->numColors = 1 << caps->bitsPixel;
+ caps->numColors = 100;
caps->pdeviceSize = 0;
caps->curveCaps = CC_CIRCLES | CC_PIE | CC_CHORD | CC_ELLIPSES |
CC_WIDE | CC_STYLED | CC_WIDESTYLED |
@@ -126,14 +126,20 @@
TC_IA_ABLE | TC_UA_ABLE | TC_SO_ABLE | TC_RA_ABLE;
caps->clipCaps = CP_REGION;
caps->rasterCaps = RC_BITBLT | RC_BANDING | RC_SCALING | RC_BITMAP64 |
- RC_DI_BITMAP | RC_PALETTE | RC_DIBTODEV | RC_BIGFONT|
- RC_STRETCHBLT | RC_STRETCHDIB | RC_DEVBITS;
+ RC_DI_BITMAP | RC_DIBTODEV | RC_BIGFONT|
+ RC_STRETCHBLT | RC_STRETCHDIB | RC_DEVBITS;
+
+ if( !(COLOR_GetSystemPaletteFlags() & COLOR_VIRTUAL) )
+ caps->rasterCaps |= RC_PALETTE;
+
caps->aspectX = 36; /* ?? */
caps->aspectY = 36; /* ?? */
caps->aspectXY = 51;
caps->logPixelsX = (int)(caps->horzRes * 25.4 / caps->horzSize);
caps->logPixelsY = (int)(caps->vertRes * 25.4 / caps->vertSize);
- caps->sizePalette = DefaultVisual(display,DefaultScreen(display))->map_entries;
+ caps->sizePalette = (caps->rasterCaps & RC_PALETTE)
+ ? DefaultVisual(display,DefaultScreen(display))->map_entries
+ : 0;
caps->numReserved = 0;
caps->colorRes = 0;
}
diff --git a/objects/dib.c b/objects/dib.c
index 8190af4..ef9f072 100644
--- a/objects/dib.c
+++ b/objects/dib.c
@@ -542,13 +542,14 @@
WORD x;
BYTE pad = (4 - ((width*3) & 3)) & 3;
+ /* "bits" order is reversed for some reason */
+
while (lines--)
{
for (x = 0; x < width; x++, bits += 3)
- {
- XPutPixel( bmpImage, x, lines,
- COLOR_ToPhysical( dc, RGB(bits[0],bits[1],bits[2]) ));
- }
+ XPutPixel( bmpImage, x, lines,
+ COLOR_ToPhysical(dc, RGB(bits[2],bits[1],bits[0])) );
+
bits += pad;
}
}
diff --git a/objects/palette.c b/objects/palette.c
index c287be8..854322a 100644
--- a/objects/palette.c
+++ b/objects/palette.c
@@ -17,6 +17,9 @@
extern HWND DCE_hDC2hWnd( HDC ); /* get associated window by
* walking DCE list */
+extern int COLOR_LookupSystemPixel(COLORREF); /* lookup pixel among static entries
+ * of the system palette */
+extern COLORREF COLOR_GetSystemPaletteEntry(BYTE);
static WORD SystemPaletteUse = SYSPAL_STATIC; /* currently not considered */
@@ -25,56 +28,6 @@
/***********************************************************************
- * PALETTE_GetNearestIndexAndColor
- */
-static WORD PALETTE_GetNearestIndexAndColor( HPALETTE16 hpalette,
- COLORREF *color)
-{
- int i, minDist, dist;
- WORD index = 0;
- BYTE r, g, b;
- PALETTEENTRY * entry;
- PALETTEOBJ * palPtr;
-
- palPtr = (PALETTEOBJ *) GDI_GetObjPtr( hpalette, PALETTE_MAGIC );
- if (!palPtr) return 0;
-
- if ( hpalette == STOCK_DEFAULT_PALETTE )
- {
- if ((*color & 0xffffff) == 0) return 0; /* Entry 0 is black */
- if ((*color & 0xffffff) == 0xffffff) /* Max entry is white */
- return palPtr->logpalette.palNumEntries - 1;
- }
-
- r = GetRValue(*color);
- g = GetGValue(*color);
- b = GetBValue(*color);
-
- entry = palPtr->logpalette.palPalEntry;
- for (i = 0, minDist = 0xffffff; minDist !=0 &&
- i < palPtr->logpalette.palNumEntries ; i++)
- {
- if (entry->peFlags != 0xff)
- {
- dist = (r - entry->peRed) * (r - entry->peRed) +
- (g - entry->peGreen) * (g - entry->peGreen) +
- (b - entry->peBlue) * (b - entry->peBlue);
- if (dist < minDist)
- {
- minDist = dist;
- index = i;
- }
- }
- entry++;
- }
-
- entry = &palPtr->logpalette.palPalEntry[index];
- *color = RGB( entry->peRed, entry->peGreen, entry->peBlue );
- return index;
-}
-
-
-/***********************************************************************
* PALETTE_ValidateFlags
*/
void PALETTE_ValidateFlags(PALETTEENTRY* lpPalE, int size)
@@ -158,6 +111,9 @@
count * sizeof(PALETTEENTRY) );
PALETTE_ValidateFlags(palPtr->logpalette.palPalEntry,
palPtr->logpalette.palNumEntries);
+ free(palPtr->mapping);
+ palPtr->mapping = NULL;
+
return count;
}
@@ -213,7 +169,8 @@
{
WORD i;
DC *dc;
- XColor color;
+
+ dprintf_palette(stddeb,"GetSystemPaletteEntries: hdc = %04x, cound = %i", hdc, count );
if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return 0;
if (start >= dc->w.devCaps->sizePalette) return 0;
@@ -221,14 +178,10 @@
count = dc->w.devCaps->sizePalette - start;
for (i = 0; i < count; i++)
{
- color.pixel = (COLOR_PaletteToPixel)
- ? COLOR_PaletteToPixel[start + i]
- : start + i;
- XQueryColor( display, COLOR_GetColormap(), &color );
- entries[i].peRed = color.red >> 8;
- entries[i].peGreen = color.green >> 8;
- entries[i].peBlue = color.blue >> 8;
- entries[i].peFlags = 0;
+ *(COLORREF*)(entries + i) = COLOR_GetSystemPaletteEntry((BYTE)(start + i));
+
+ dprintf_palette(stddeb,"\tidx(%02x) -> RGB(%08lx)\n", (unsigned char)(start + i),
+ *(COLORREF*)(entries + i) );
}
return count;
}
@@ -239,7 +192,14 @@
*/
WORD GetNearestPaletteIndex( HPALETTE16 hpalette, COLORREF color )
{
- WORD index = PALETTE_GetNearestIndexAndColor( hpalette, &color );
+ PALETTEOBJ* palObj = (PALETTEOBJ*) GDI_GetObjPtr( hpalette, PALETTE_MAGIC );
+ WORD index = 0;
+
+ if( palObj )
+ index = COLOR_PaletteLookupPixel( palObj->logpalette.palPalEntry,
+ palObj->logpalette.palNumEntries, NULL,
+ color, FALSE );
+
dprintf_palette(stddeb,"GetNearestPaletteIndex(%04x,%06lx): returning %d\n",
hpalette, color, index );
return index;
@@ -251,11 +211,20 @@
*/
COLORREF GetNearestColor( HDC hdc, COLORREF color )
{
- COLORREF nearest = color;
- DC *dc;
+ COLORREF nearest = 0xFADECAFE;
+ DC *dc;
+ PALETTEOBJ *palObj;
- if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return 0;
- PALETTE_GetNearestIndexAndColor( dc->w.hPalette, &nearest );
+ if ( (dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC )) )
+ {
+ palObj = (PALETTEOBJ*)
+ GDI_GetObjPtr( (dc->w.hPalette)? dc->w.hPalette
+ : STOCK_DEFAULT_PALETTE, PALETTE_MAGIC );
+
+ nearest = COLOR_LookupNearestColor( palObj->logpalette.palPalEntry,
+ palObj->logpalette.palNumEntries, color );
+ }
+
dprintf_palette(stddeb,"GetNearestColor(%06lx): returning %06lx\n",
color, nearest );
return nearest;
@@ -307,7 +276,13 @@
DC *dc;
dprintf_palette(stddeb, "GDISelectPalette: %04x %04x\n", hdc, hpal );
- if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return 0;
+
+ dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
+ if (!dc)
+ {
+ dc = (DC *)GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC);
+ if (!dc) return 0;
+ }
prev = dc->w.hPalette;
dc->w.hPalette = hpal;
if (!wBkg) hPrimaryPalette = hpal;
@@ -321,14 +296,22 @@
*/
UINT GDIRealizePalette( HDC hdc )
{
- DC* dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ) ;
PALETTEOBJ* palPtr;
int realized = 0;
+ DC* dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
+ if (!dc)
+ {
+ dc = (DC *)GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC);
+ if (!dc) return 0;
+ }
dprintf_palette(stddeb, "GDIRealizePalette: %04x...", hdc );
if( dc && dc->w.hPalette != hLastRealizedPalette )
{
+ if( dc->w.hPalette == STOCK_DEFAULT_PALETTE )
+ return RealizeDefaultPalette( hdc );
+
palPtr = (PALETTEOBJ *) GDI_GetObjPtr( dc->w.hPalette, PALETTE_MAGIC );
realized = COLOR_SetMapping(palPtr, dc->w.hPalette != hPrimaryPalette
@@ -347,18 +330,38 @@
*/
WORD RealizeDefaultPalette( HDC hdc )
{
- DC *dc;
+ DC *dc;
+ PALETTEOBJ* palPtr;
+ int i, index, realized = 0;
dprintf_palette(stddeb,"RealizeDefaultPalette: %04x\n", hdc );
- if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return 0;
+ dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
+ if (!dc)
+ {
+ dc = (DC *)GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC);
+ if (!dc) return 0;
+ }
+
if ( dc->w.flags & DC_MEMORY ) return 0;
hPrimaryPalette = STOCK_DEFAULT_PALETTE;
hLastRealizedPalette = STOCK_DEFAULT_PALETTE;
- return COLOR_SetMapping( (PALETTEOBJ*)GDI_GetObjPtr(STOCK_DEFAULT_PALETTE, PALETTE_MAGIC ), TRUE);
-}
+ palPtr = (PALETTEOBJ*)GDI_GetObjPtr(STOCK_DEFAULT_PALETTE, PALETTE_MAGIC );
+
+ /* lookup is needed to account for SetSystemPaletteUse() stuff */
+
+ for( i = 0; i < 20; i++ )
+ {
+ index = COLOR_LookupSystemPixel(*(COLORREF*)(palPtr->logpalette.palPalEntry + i));
+
+ /* mapping is allocated in COLOR_InitPalette() */
+
+ if( index != palPtr->mapping[i] ) { palPtr->mapping[i]=index; realized++; }
+ }
+ return realized;
+}
/***********************************************************************
* IsDCCurrentPalette (GDI.412)
@@ -366,7 +369,7 @@
BOOL IsDCCurrentPalette(HDC hDC)
{
DC* dc = (DC *)GDI_GetObjPtr( hDC, DC_MAGIC );
- return (dc->w.hPalette == hPrimaryPalette);
+ return (dc)?(dc->w.hPalette == hPrimaryPalette):FALSE;
}
/***********************************************************************
@@ -391,7 +394,7 @@
/* set primary palette if it's related to current active */
- if( hWnd && (hActive == hWnd || IsChild(hActive,hWnd)) &&
+ if((!hWnd || (hActive == hWnd || IsChild(hActive,hWnd))) &&
!bForceBackground )
wBkgPalette = 0;
}
@@ -408,7 +411,8 @@
/* do not send anything if no colors were changed */
- if( IsDCCurrentPalette( hDC ) && realized )
+ if( IsDCCurrentPalette( hDC ) && realized &&
+ !(COLOR_GetSystemPaletteFlags() & COLOR_VIRTUAL) )
{
/* Send palette change notification */
@@ -431,6 +435,8 @@
/* Docs say that we have to remap current drawable pixel by pixel
* but it would take forever given the speed of XGet/PutPixel.
*/
- if (hWnd) InvalidateRect16( hWnd, NULL, FALSE );
+ if (hWnd && !(COLOR_GetSystemPaletteFlags() & COLOR_VIRTUAL) )
+ InvalidateRect16( hWnd, NULL, FALSE );
return 0x666;
}
+
diff --git a/windows/class.c b/windows/class.c
index 80b6cc9..e956801 100644
--- a/windows/class.c
+++ b/windows/class.c
@@ -240,20 +240,6 @@
/***********************************************************************
- * CLASS_FindClassByName
- *
- * Return a pointer to the class.
- */
-CLASS *CLASS_FindClassByName( SEGPTR name, HINSTANCE hinstance )
-{
- ATOM atom;
-
- if (!(atom = GlobalFindAtom16( name ))) return 0;
- return CLASS_FindClassByAtom( atom, hinstance );
-}
-
-
-/***********************************************************************
* CLASS_RegisterClass
*
* The real RegisterClass() functionality.
diff --git a/windows/dialog.c b/windows/dialog.c
index bdd46a3..9faec22 100644
--- a/windows/dialog.c
+++ b/windows/dialog.c
@@ -577,6 +577,7 @@
/* Initialise dialog extra data */
dlgInfo = (DIALOGINFO *)wndPtr->wExtra;
+ WINPROC_SetProc( &dlgInfo->dlgProc, dlgProc, procType );
dlgInfo->hUserFont = hFont;
dlgInfo->hMenu = hMenu;
dlgInfo->xBaseUnit = xUnit;
@@ -595,7 +596,6 @@
/* Send initialisation messages and set focus */
- WINPROC_SetProc( &dlgInfo->dlgProc, dlgProc, procType );
dlgInfo->hwndFocus = DIALOG_GetFirstTabItem( hwnd );
if (dlgInfo->hUserFont)
SendMessage32A( hwnd, WM_SETFONT, (WPARAM)dlgInfo->hUserFont, 0 );
diff --git a/windows/event.c b/windows/event.c
index e6a053b..f00cfe9 100644
--- a/windows/event.c
+++ b/windows/event.c
@@ -149,6 +149,9 @@
static void EVENT_SelectionClear( WND *pWnd, XSelectionClearEvent *event);
static void EVENT_ClientMessage( WND *pWnd, XClientMessageEvent *event );
+/* Usable only with OLVWM - compile option perhaps?
+static void EVENT_EnterNotify( WND *pWnd, XCrossingEvent *event );
+*/
/***********************************************************************
* EVENT_ProcessEvent
@@ -230,7 +233,10 @@
case ClientMessage:
EVENT_ClientMessage( pWnd, (XClientMessageEvent *) event );
break;
-
+/* case EnterNotify:
+ * EVENT_EnterNotify( pWnd, (XCrossingEvent *) event );
+ * break;
+ */
case NoExpose:
break;
@@ -822,6 +828,20 @@
SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND, SC_CLOSE, 0 );
}
+/**********************************************************************
+ * EVENT_EnterNotify
+ *
+ * Install colormap when Wine window is focused in
+ * self-managed mode with private colormap
+ */
+/*
+ void EVENT_EnterNotify( WND *pWnd, XCrossingEvent *event )
+ {
+ if( !Options.managed && rootWindow == DefaultRootWindow(display) &&
+ (COLOR_GetSystemPaletteFlags() & COLOR_PRIVATE) && GetFocus() )
+ XInstallColormap( display, COLOR_GetColormap() );
+ }
+ */
/**********************************************************************
* SetCapture (USER.18)
diff --git a/windows/hook.c b/windows/hook.c
index aa616c5..e9cb158 100644
--- a/windows/hook.c
+++ b/windows/hook.c
@@ -276,11 +276,7 @@
*/
FARPROC16 SetWindowsHook( INT16 id, HOOKPROC16 proc )
{
-#ifdef WINELIB
- HINSTANCE16 hInst = 0;
-#else
- HINSTANCE16 hInst = FarGetOwner( HIWORD(proc) );
-#endif
+ HINSTANCE16 hInst = __winelib ? 0 : FarGetOwner( HIWORD(proc) );
/* WH_MSGFILTER is the only task-specific hook for SetWindowsHook() */
HTASK16 hTask = (id == WH_MSGFILTER) ? GetCurrentTask() : 0;
diff --git a/windows/mdi.c b/windows/mdi.c
index 5f53691..2ff08e2 100644
--- a/windows/mdi.c
+++ b/windows/mdi.c
@@ -373,8 +373,14 @@
else
{
SetWindowPos( hwnd, 0, 0, 0, 0, 0, SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE );
- if( wnd->dwStyle & WS_MAXIMIZE )
- {
+
+ /* Set maximized state here in case hwnd didn't receive WM_SIZE
+ * during CreateWindow - bad!
+ */
+
+ if( wnd->dwStyle & WS_MAXIMIZE && !ci->hwndChildMaximized )
+ {
+ ci->hwndChildMaximized = wnd->hwndSelf;
MDI_AugmentFrameMenu( ci, w->parent, hwnd );
MDI_UpdateFrameText( w->parent, ci->self, MDI_REPAINTFRAME, NULL );
}
@@ -409,6 +415,10 @@
lpMinMax->ptMaxPosition.x = rect.left;
lpMinMax->ptMaxPosition.y = rect.top;
+
+ dprintf_mdi(stddeb,"\tChildMinMaxInfo: max rect (%i,%i - %i, %i)\n",
+ rect.left,rect.top,rect.right,rect.bottom);
+
}
/**********************************************************************
diff --git a/windows/message.c b/windows/message.c
index 62c4c93..ff5e646 100644
--- a/windows/message.c
+++ b/windows/message.c
@@ -24,6 +24,9 @@
/* #define DEBUG_MSG */
#include "debug.h"
+#define WM_NCMOUSEFIRST WM_NCMOUSEMOVE
+#define WM_NCMOUSELAST WM_NCMBUTTONDBLCLK
+
#define HWND_BROADCAST16 ((HWND16)0xffff)
#define HWND_BROADCAST32 ((HWND32)0xffffffff)
@@ -378,11 +381,14 @@
mask = QS_POSTMESSAGE | QS_SENDMESSAGE; /* Always selected */
if (first || last)
{
- 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 |= QS_TIMER;
- if ((first <= WM_SYSTIMER) && (last >= WM_SYSTIMER)) mask |= QS_TIMER;
- if ((first <= WM_PAINT) && (last >= WM_PAINT)) mask |= QS_PAINT;
+ /* MSWord gets stuck if we do not check for nonclient mouse messages */
+
+ if ((first <= WM_KEYLAST) && (last >= WM_KEYFIRST)) mask |= QS_KEY;
+ if ( ((first <= WM_MOUSELAST) && (last >= WM_MOUSEFIRST)) ||
+ ((first <= WM_NCMOUSELAST) && (last >= WM_NCMOUSEFIRST)) ) mask |= QS_MOUSE;
+ if ((first <= WM_TIMER) && (last >= WM_TIMER)) mask |= QS_TIMER;
+ if ((first <= WM_SYSTIMER) && (last >= WM_SYSTIMER)) mask |= QS_TIMER;
+ if ((first <= WM_PAINT) && (last >= WM_PAINT)) mask |= QS_PAINT;
}
else mask |= QS_MOUSE | QS_KEY | QS_TIMER | QS_PAINT;
@@ -642,7 +648,7 @@
} msgstruct = { lParam, wParam, msg, hwnd };
#ifdef CONFIG_IPC
- MSG DDE_msg = { hwnd, msg, wParam, lParam };
+ MSG16 DDE_msg = { hwnd, msg, wParam, lParam };
if (DDE_SendMessage(&DDE_msg)) return TRUE;
#endif /* CONFIG_IPC */
diff --git a/windows/property.c b/windows/property.c
index dc5303c..e60a61c 100644
--- a/windows/property.c
+++ b/windows/property.c
@@ -1,145 +1,367 @@
/*
* Window properties
*
- * Copyright 1995 Alexandre Julliard
+ * Copyright 1995, 1996 Alexandre Julliard
*/
+#define NO_TRANSITION_TYPES /* This file is Win32-clean */
#include <string.h>
#include "win.h"
-#include "user.h"
+#include "heap.h"
#include "callback.h"
+#include "string32.h"
#include "stddebug.h"
-/* #define DEBUG_PROP */
#include "debug.h"
-typedef struct
+typedef struct tagPROPERTY
{
- HANDLE next; /* Next property in window list */
- ATOM atom; /* Atom (or 0 if string) */
- HANDLE hData; /* User's data */
- char string[1]; /* Property string */
+ struct tagPROPERTY *next; /* Next property in window list */
+ HANDLE32 handle; /* User's data */
+ LPSTR string; /* Property string (or atom) */
} PROPERTY;
/***********************************************************************
- * SetProp (USER.26)
+ * PROP_FindProp
*/
-BOOL SetProp( HWND hwnd, SEGPTR str, HANDLE hData )
+static PROPERTY *PROP_FindProp( HWND32 hwnd, LPCSTR str )
{
- HANDLE hProp;
PROPERTY *prop;
- WND *wndPtr;
+ WND *pWnd = WIN_FindWndPtr( hwnd );
- dprintf_prop( stddeb, "SetProp: %04x %08lx %04x\n",
- hwnd, (DWORD)str, hData );
- if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
- hProp = USER_HEAP_ALLOC( sizeof(PROPERTY) +
- (HIWORD(str) ? strlen(PTR_SEG_TO_LIN(str)) : 0 ));
- if (!hProp) return FALSE;
- prop = (PROPERTY *) USER_HEAP_LIN_ADDR( hProp );
- if (HIWORD(str)) /* string */
+ if (!pWnd) return NULL;
+ if (HIWORD(str))
{
- prop->atom = 0;
- strcpy( prop->string, PTR_SEG_TO_LIN(str) );
+ for (prop = pWnd->pProp; prop; prop = prop->next)
+ if (HIWORD(prop->string) && !lstrcmpi32A( prop->string, str ))
+ return prop;
}
else /* atom */
{
- prop->atom = LOWORD(str);
- prop->string[0] = '\0';
+ for (prop = pWnd->pProp; (prop); prop = prop->next)
+ if (!HIWORD(prop->string) && (LOWORD(prop->string) == LOWORD(str)))
+ return prop;
}
- prop->hData = hData;
- prop->next = wndPtr->hProp;
- wndPtr->hProp = hProp;
+ return NULL;
+}
+
+
+/***********************************************************************
+ * GetProp16 (USER.25)
+ */
+HANDLE16 GetProp16( HWND16 hwnd, LPCSTR str )
+{
+ return (HANDLE16)GetProp32A( hwnd, str );
+}
+
+
+/***********************************************************************
+ * GetProp32A (USER32.280)
+ */
+HANDLE32 GetProp32A( HWND32 hwnd, LPCSTR str )
+{
+ PROPERTY *prop = PROP_FindProp( hwnd, str );
+
+ dprintf_prop( stddeb, "GetProp(%08x,'%s'): returning %08x\n",
+ hwnd, str, prop ? prop->handle : 0 );
+ return prop ? prop->handle : 0;
+}
+
+
+/***********************************************************************
+ * GetProp32W (USER32.281)
+ */
+HANDLE32 GetProp32W( HWND32 hwnd, LPCWSTR str )
+{
+ LPSTR strA;
+ HANDLE32 ret;
+
+ if (!HIWORD(str)) return GetProp32A( hwnd, (LPCSTR)(UINT32)LOWORD(str) );
+ strA = STRING32_DupUniToAnsi( str );
+ ret = GetProp32A( hwnd, strA );
+ free( strA );
+ return ret;
+}
+
+
+/***********************************************************************
+ * SetProp16 (USER.26)
+ */
+BOOL16 SetProp16( HWND16 hwnd, LPCSTR str, HANDLE16 handle )
+{
+ return (BOOL16)SetProp32A( hwnd, str, handle );
+}
+
+
+/***********************************************************************
+ * SetProp32A (USER32.496)
+ */
+BOOL32 SetProp32A( HWND32 hwnd, LPCSTR str, HANDLE32 handle )
+{
+ PROPERTY *prop;
+
+ dprintf_prop( stddeb, "SetProp: %04x '%s' %08x\n", hwnd, str, handle );
+ if (!(prop = PROP_FindProp( hwnd, str )))
+ {
+ /* We need to create it */
+ WND *pWnd = WIN_FindWndPtr( hwnd );
+ if (!pWnd) return FALSE;
+ if (!(prop = HeapAlloc( SystemHeap, 0, sizeof(*prop) ))) return FALSE;
+ if (!(prop->string = SEGPTR_STRDUP(str)))
+ {
+ HeapFree( SystemHeap, 0, prop );
+ return FALSE;
+ }
+ prop->next = pWnd->pProp;
+ pWnd->pProp = prop;
+ }
+ prop->handle = handle;
return TRUE;
}
/***********************************************************************
- * GetProp (USER.25)
+ * SetProp32W (USER32.497)
*/
-HANDLE GetProp( HWND hwnd, SEGPTR str )
+BOOL32 SetProp32W( HWND32 hwnd, LPCWSTR str, HANDLE32 handle )
{
- HANDLE hProp;
- WND *wndPtr;
+ BOOL32 ret;
+ LPSTR strA;
- dprintf_prop( stddeb, "GetProp: %04x %08lx\n", hwnd, (DWORD)str );
- if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
- hProp = wndPtr->hProp;
- while (hProp)
- {
- PROPERTY *prop = (PROPERTY *)USER_HEAP_LIN_ADDR(hProp);
- if (HIWORD(str))
- {
- if (!prop->atom && !lstrcmpi32A(prop->string, PTR_SEG_TO_LIN(str)))
- return prop->hData;
- }
- else if (prop->atom && (prop->atom == LOWORD(str))) return prop->hData;
- hProp = prop->next;
- }
- return 0;
+ if (!HIWORD(str))
+ return SetProp32A( hwnd, (LPCSTR)(UINT32)LOWORD(str), handle );
+ strA = STRING32_DupUniToAnsi( str );
+ ret = SetProp32A( hwnd, strA, handle );
+ free( strA );
+ return ret;
}
/***********************************************************************
- * RemoveProp (USER.24)
+ * RemoveProp16 (USER.24)
*/
-HANDLE RemoveProp( HWND hwnd, SEGPTR str )
+HANDLE16 RemoveProp16( HWND16 hwnd, LPCSTR str )
{
- HANDLE *hProp;
- WND *wndPtr;
-
- dprintf_prop( stddeb, "RemoveProp: %04x %08lx\n", hwnd, (DWORD)str );
- if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
- hProp = &wndPtr->hProp;
- while (*hProp)
- {
- PROPERTY *prop = (PROPERTY *)USER_HEAP_LIN_ADDR( *hProp );
- if ((HIWORD(str) && !prop->atom &&
- !lstrcmpi32A( prop->string, PTR_SEG_TO_LIN(str))) ||
- (!HIWORD(str) && prop->atom && (prop->atom == LOWORD(str))))
- {
- HANDLE hNext = prop->next;
- HANDLE hData = prop->hData;
- USER_HEAP_FREE( *hProp );
- *hProp = hNext;
- return hData;
- }
- hProp = &prop->next;
- }
- return 0;
+ return (HANDLE16)RemoveProp32A( hwnd, str );
}
/***********************************************************************
- * EnumProps (USER.27)
+ * RemoveProp32A (USER32.441)
*/
-INT EnumProps( HWND hwnd, PROPENUMPROC func )
+HANDLE32 RemoveProp32A( HWND32 hwnd, LPCSTR str )
{
- int ret = -1;
- HANDLE hProp;
- WND *wndPtr;
+ HANDLE32 handle;
+ PROPERTY **pprop, *prop;
+ WND *pWnd = WIN_FindWndPtr( hwnd );
- dprintf_prop( stddeb, "EnumProps: %04x %08lx\n", hwnd, (LONG)func );
- if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
- hProp = wndPtr->hProp;
- while (hProp)
+ dprintf_prop( stddeb, "RemoveProp: %04x '%s'\n", hwnd, str );
+ if (!pWnd) return NULL;
+ if (HIWORD(str))
{
- PROPERTY *prop = (PROPERTY *)USER_HEAP_LIN_ADDR(hProp);
-
- dprintf_prop( stddeb, " Callback: atom=%04x data=%04x str='%s'\n",
- prop->atom, prop->hData, prop->string );
+ for (pprop=(PROPERTY**)&pWnd->pProp; (*pprop); pprop = &(*pprop)->next)
+ if (HIWORD((*pprop)->string) &&
+ !lstrcmpi32A( (*pprop)->string, str )) break;
+ }
+ else /* atom */
+ {
+ for (pprop=(PROPERTY**)&pWnd->pProp; (*pprop); pprop = &(*pprop)->next)
+ if (!HIWORD((*pprop)->string) &&
+ (LOWORD((*pprop)->string) == LOWORD(str))) break;
+ }
+ if (!*pprop) return 0;
+ prop = *pprop;
+ handle = prop->handle;
+ *pprop = prop->next;
+ SEGPTR_FREE(prop->string);
+ HeapFree( SystemHeap, 0, prop );
+ return handle;
+}
- /* Already get the next in case the callback */
- /* function removes the current property. */
- hProp = prop->next;
- ret = CallEnumPropProc( (FARPROC16)func, hwnd,
- prop->atom ?
- (LONG)MAKELONG( prop->atom, 0 )
- :
- (LONG)(USER_HEAP_SEG_ADDR(hProp) +
- ((int)prop->string - (int)prop)),
- prop->hData );
+
+/***********************************************************************
+ * RemoveProp32W (USER32.442)
+ */
+HANDLE32 RemoveProp32W( HWND32 hwnd, LPCWSTR str )
+{
+ LPSTR strA;
+ HANDLE32 ret;
+
+ if (!HIWORD(str))
+ return RemoveProp32A( hwnd, (LPCSTR)(UINT32)LOWORD(str) );
+ strA = STRING32_DupUniToAnsi( str );
+ ret = RemoveProp32A( hwnd, strA );
+ free( strA );
+ return ret;
+}
+
+
+/***********************************************************************
+ * PROPERTY_RemoveWindowProps
+ *
+ * Remove all properties of a window.
+ */
+void PROPERTY_RemoveWindowProps( WND *pWnd )
+{
+ PROPERTY *prop, *next;
+
+ for (prop = pWnd->pProp; (prop); prop = next)
+ {
+ next = prop->next;
+ SEGPTR_FREE( prop->string );
+ HeapFree( SystemHeap, 0, prop );
+ }
+ pWnd->pProp = NULL;
+}
+
+
+/***********************************************************************
+ * EnumProps16 (USER.27)
+ */
+INT16 EnumProps16( HWND16 hwnd, PROPENUMPROC16 func )
+{
+ PROPERTY *prop, *next;
+ WND *pWnd;
+ INT16 ret = -1;
+
+ dprintf_prop( stddeb, "EnumProps: %04x %08x\n", hwnd, (UINT32)func );
+ if (!(pWnd = WIN_FindWndPtr( hwnd ))) return -1;
+ for (prop = pWnd->pProp; (prop); prop = next)
+ {
+ /* Already get the next in case the callback */
+ /* function removes the current property. */
+ next = prop->next;
+
+ dprintf_prop( stddeb, " Callback: handle=%08x str='%s'\n",
+ prop->handle, prop->string );
+ ret = CallEnumPropProc16( (FARPROC16)func, hwnd,
+ SEGPTR_GET(prop->string), prop->handle );
+ if (!ret) break;
+ }
+ return ret;
+}
+
+
+/***********************************************************************
+ * EnumProps32A (USER32.185)
+ */
+INT32 EnumProps32A( HWND32 hwnd, PROPENUMPROC32A func )
+{
+ PROPERTY *prop, *next;
+ WND *pWnd;
+ INT32 ret = -1;
+
+ dprintf_prop( stddeb, "EnumProps32A: %04x %08x\n", hwnd, (UINT32)func );
+ if (!(pWnd = WIN_FindWndPtr( hwnd ))) return -1;
+ for (prop = pWnd->pProp; (prop); prop = next)
+ {
+ /* Already get the next in case the callback */
+ /* function removes the current property. */
+ next = prop->next;
+
+ dprintf_prop( stddeb, " Callback: handle=%08x str='%s'\n",
+ prop->handle, prop->string );
+ ret = CallEnumPropProc32( func, hwnd, prop->string, prop->handle );
+ if (!ret) break;
+ }
+ return ret;
+}
+
+
+/***********************************************************************
+ * EnumProps32W (USER32.188)
+ */
+INT32 EnumProps32W( HWND32 hwnd, PROPENUMPROC32W func )
+{
+ PROPERTY *prop, *next;
+ WND *pWnd;
+ INT32 ret = -1;
+
+ dprintf_prop( stddeb, "EnumProps32W: %04x %08x\n", hwnd, (UINT32)func );
+ if (!(pWnd = WIN_FindWndPtr( hwnd ))) return -1;
+ for (prop = pWnd->pProp; (prop); prop = next)
+ {
+ /* Already get the next in case the callback */
+ /* function removes the current property. */
+ next = prop->next;
+
+ dprintf_prop( stddeb, " Callback: handle=%08x str='%s'\n",
+ prop->handle, prop->string );
+ if (HIWORD(prop->string))
+ {
+ LPWSTR str = STRING32_DupAnsiToUni( prop->string );
+ ret = CallEnumPropProc32( func, hwnd, str, prop->handle );
+ free( str );
+ }
+ else
+ ret = CallEnumPropProc32( func, hwnd,
+ (LPCWSTR)(UINT32)LOWORD(prop->string),
+ prop->handle );
+ if (!ret) break;
+ }
+ return ret;
+}
+
+
+/***********************************************************************
+ * EnumPropsEx32A (USER32.186)
+ */
+INT32 EnumPropsEx32A( HWND32 hwnd, PROPENUMPROCEX32A func, LPARAM lParam )
+{
+ PROPERTY *prop, *next;
+ WND *pWnd;
+ INT32 ret = -1;
+
+ dprintf_prop( stddeb, "EnumPropsEx32A: %04x %08x %08lx\n",
+ hwnd, (UINT32)func, lParam );
+ if (!(pWnd = WIN_FindWndPtr( hwnd ))) return -1;
+ for (prop = pWnd->pProp; (prop); prop = next)
+ {
+ /* Already get the next in case the callback */
+ /* function removes the current property. */
+ next = prop->next;
+
+ dprintf_prop( stddeb, " Callback: handle=%08x str='%s'\n",
+ prop->handle, prop->string );
+ ret = CallEnumPropProcEx32( func, hwnd, prop->string,
+ prop->handle, lParam );
+ if (!ret) break;
+ }
+ return ret;
+}
+
+
+/***********************************************************************
+ * EnumPropsEx32W (USER32.187)
+ */
+INT32 EnumPropsEx32W( HWND32 hwnd, PROPENUMPROCEX32W func, LPARAM lParam )
+{
+ PROPERTY *prop, *next;
+ WND *pWnd;
+ INT32 ret = -1;
+
+ dprintf_prop( stddeb, "EnumPropsEx32W: %04x %08x %08lx\n",
+ hwnd, (UINT32)func, lParam );
+ if (!(pWnd = WIN_FindWndPtr( hwnd ))) return -1;
+ for (prop = pWnd->pProp; (prop); prop = next)
+ {
+ /* Already get the next in case the callback */
+ /* function removes the current property. */
+ next = prop->next;
+
+ dprintf_prop( stddeb, " Callback: handle=%08x str='%s'\n",
+ prop->handle, prop->string );
+ if (HIWORD(prop->string))
+ {
+ LPWSTR str = STRING32_DupAnsiToUni( prop->string );
+ ret = CallEnumPropProcEx32( func, hwnd, str, prop->handle, lParam);
+ free( str );
+ }
+ else
+ ret = CallEnumPropProcEx32( func, hwnd,
+ (LPCWSTR)(UINT32)LOWORD(prop->string),
+ prop->handle, lParam );
if (!ret) break;
}
return ret;
diff --git a/windows/scroll.c b/windows/scroll.c
index d25450d..d00330b 100644
--- a/windows/scroll.c
+++ b/windows/scroll.c
@@ -33,9 +33,8 @@
* dcx can have DCX_WINDOW, DCX_CLIPCHILDREN, DCX_CLIPSIBLINGS set
*/
-HRGN SCROLL_TraceChildren( HWND hScroll, short dx, short dy, WORD dcx)
+HRGN SCROLL_TraceChildren( WND* wndScroll, short dx, short dy, WORD dcx)
{
- WND *wndScroll = WIN_FindWndPtr( hScroll );
HRGN hRgnWnd;
HRGN hUpdateRgn,hCombineRgn;
@@ -45,13 +44,13 @@
hRgnWnd = CreateRectRgnIndirect16(&wndScroll->rectWindow);
else
{
- RECT32 rect;
+ RECT32 rect = { 0, 0, wndScroll->rectClient.right - wndScroll->rectClient.left,
+ wndScroll->rectClient.bottom - wndScroll->rectClient.top };
- GetClientRect32(hScroll,&rect);
hRgnWnd = CreateRectRgnIndirect32(&rect);
}
- hUpdateRgn = DCE_GetVisRgn( hScroll, dcx );
+ hUpdateRgn = DCE_GetVisRgn( wndScroll->hwndSelf, dcx );
hCombineRgn = CreateRectRgn(0,0,0,0);
if( !hUpdateRgn || !hCombineRgn )
@@ -74,21 +73,21 @@
/* ----------------------------------------------------------------------
* SCROLL_ScrollChildren
*/
-BOOL SCROLL_ScrollChildren( HWND hScroll, short dx, short dy)
+BOOL SCROLL_ScrollChildren( WND* wndScroll, short dx, short dy)
{
- WND *wndPtr = WIN_FindWndPtr(hScroll);
+ WND *wndPtr = NULL;
HRGN hUpdateRgn;
BOOL b = 0;
- if( !wndPtr || ( !dx && !dy )) return 0;
+ if( !wndScroll || ( !dx && !dy )) return 0;
- dprintf_scroll(stddeb,"SCROLL_ScrollChildren: hwnd %04x dx=%i dy=%i\n",hScroll,dx,dy);
+ dprintf_scroll(stddeb,"SCROLL_ScrollChildren: hwnd %04x dx=%i dy=%i\n",wndScroll->hwndSelf,dx,dy);
/* get a region in client rect invalidated by siblings and ansectors */
- hUpdateRgn = SCROLL_TraceChildren(hScroll, dx , dy, DCX_CLIPSIBLINGS);
+ hUpdateRgn = SCROLL_TraceChildren(wndScroll, dx , dy, DCX_CLIPSIBLINGS);
/* update children coordinates */
- for (wndPtr = wndPtr->child; wndPtr; wndPtr = wndPtr->next)
+ for (wndPtr = wndScroll->child; wndPtr; wndPtr = wndPtr->next)
{
/* we can check if window intersects with clipRect parameter
* and do not move it if not - just a thought. - AK
@@ -100,8 +99,8 @@
}
/* invalidate uncovered region and paint frames */
- b = RedrawWindow32( hScroll, NULL, hUpdateRgn, RDW_INVALIDATE | RDW_FRAME | RDW_ERASE |
- RDW_ERASENOW | RDW_ALLCHILDREN );
+ b = RedrawWindow32( wndScroll->hwndSelf, NULL, hUpdateRgn,
+ RDW_INVALIDATE | RDW_FRAME | RDW_ERASE | RDW_ERASENOW | RDW_ALLCHILDREN );
DeleteObject( hUpdateRgn);
return b;
@@ -114,10 +113,11 @@
*/
void ScrollWindow(HWND hwnd, short dx, short dy, LPRECT16 rect, LPRECT16 clipRect)
{
- HDC hdc;
- HRGN hrgnUpdate,hrgnClip;
- RECT16 rc, cliprc;
- HWND hCaretWnd = CARET_GetHwnd();
+ HDC hdc;
+ HRGN hrgnUpdate,hrgnClip;
+ RECT16 rc, cliprc;
+ HWND hCaretWnd = CARET_GetHwnd();
+ WND* wndScroll = WIN_FindWndPtr( hwnd );
dprintf_scroll(stddeb,"ScrollWindow: dx=%d, dy=%d, lpRect =%08lx clipRect=%i,%i,%i,%i\n",
dx, dy, (LONG)rect, (int)((clipRect)?clipRect->left:0),
@@ -158,6 +158,11 @@
else
CopyRect16(&cliprc, clipRect);
+ /* move window update region (if any) */
+
+ if( wndScroll->hrgnUpdate > 1 )
+ OffsetRgn( wndScroll->hrgnUpdate, dx, dy );
+
hrgnUpdate = CreateRectRgn(0, 0, 0, 0);
ScrollDC(hdc, dx, dy, &rc, &cliprc, hrgnUpdate, NULL);
ReleaseDC(hwnd, hdc);
@@ -165,13 +170,14 @@
if( !rect )
{
/* FIXME: this doesn't take into account hrgnUpdate */
- if( !SCROLL_ScrollChildren(hwnd,dx,dy) )
+
+ if( !SCROLL_ScrollChildren( wndScroll, dx,dy) )
InvalidateRgn(hwnd, hrgnUpdate, TRUE);
}
else
{
- HRGN hrgnInv = SCROLL_TraceChildren(hwnd,dx,dy,DCX_CLIPCHILDREN |
- DCX_CLIPSIBLINGS );
+ HRGN hrgnInv = SCROLL_TraceChildren( wndScroll ,dx,dy,DCX_CLIPCHILDREN |
+ DCX_CLIPSIBLINGS );
if( hrgnInv )
{
CombineRgn(hrgnUpdate,hrgnInv,hrgnUpdate,RGN_OR);
diff --git a/windows/win.c b/windows/win.c
index 25ccc7f..29b902f 100644
--- a/windows/win.c
+++ b/windows/win.c
@@ -52,11 +52,11 @@
*
* Return a pointer to the WND structure corresponding to a HWND.
*/
-WND * WIN_FindWndPtr( HWND hwnd )
+WND * WIN_FindWndPtr( HWND32 hwnd )
{
WND * ptr;
- if (!hwnd) return NULL;
+ if (!hwnd || HIWORD(hwnd)) return NULL;
ptr = (WND *) USER_HEAP_LIN_ADDR( hwnd );
if (ptr->dwMagic != WND_MAGIC) return NULL;
if (ptr->hwndSelf != hwnd)
@@ -74,7 +74,7 @@
*
* Dump the content of a window structure to stderr.
*/
-void WIN_DumpWindow( HWND hwnd )
+void WIN_DumpWindow( HWND32 hwnd )
{
WND *ptr;
char className[80];
@@ -95,7 +95,7 @@
"inst=%04x taskQ=%04x updRgn=%04x active=%04x hdce=%04x idmenu=%04x\n"
"style=%08lx exstyle=%08lx wndproc=%08x text='%s'\n"
"client=%d,%d-%d,%d window=%d,%d-%d,%d iconpos=%d,%d maxpos=%d,%d\n"
- "sysmenu=%04x flags=%04x props=%04x vscroll=%p hscroll=%p\n",
+ "sysmenu=%04x flags=%04x props=%p vscroll=%p hscroll=%p\n",
ptr->next, ptr->child, ptr->parent, ptr->owner,
ptr->class, className, ptr->hInstance, ptr->hmemTaskQ,
ptr->hrgnUpdate, ptr->hwndLastActive, ptr->hdce, ptr->wIDmenu,
@@ -105,7 +105,7 @@
ptr->rectClient.bottom, ptr->rectWindow.left, ptr->rectWindow.top,
ptr->rectWindow.right, ptr->rectWindow.bottom, ptr->ptIconPos.x,
ptr->ptIconPos.y, ptr->ptMaxPos.x, ptr->ptMaxPos.y, ptr->hSysMenu,
- ptr->flags, ptr->hProp, ptr->pVScroll, ptr->pHScroll );
+ ptr->flags, ptr->pProp, ptr->pVScroll, ptr->pHScroll );
if (ptr->class->cbWndExtra)
{
@@ -123,7 +123,7 @@
*
* Walk the windows tree and print each window on stderr.
*/
-void WIN_WalkWindows( HWND hwnd, int indent )
+void WIN_WalkWindows( HWND32 hwnd, int indent )
{
WND *ptr;
char className[80];
@@ -160,7 +160,7 @@
*
* Return the X window associated to a window.
*/
-Window WIN_GetXWindow( HWND hwnd )
+Window WIN_GetXWindow( HWND32 hwnd )
{
WND *wndPtr = WIN_FindWndPtr( hwnd );
while (wndPtr && !wndPtr->window) wndPtr = wndPtr->parent;
@@ -173,7 +173,7 @@
*
* Remove a window from the siblings linked list.
*/
-BOOL WIN_UnlinkWindow( HWND hwnd )
+BOOL32 WIN_UnlinkWindow( HWND32 hwnd )
{
WND *wndPtr, **ppWnd;
@@ -192,7 +192,7 @@
* 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 )
+BOOL32 WIN_LinkWindow( HWND32 hwnd, HWND32 hwndInsertAfter )
{
WND *wndPtr, **ppWnd;
@@ -221,7 +221,7 @@
*
* Find a window that needs repaint.
*/
-HWND WIN_FindWinToRepaint( HWND hwnd, HQUEUE hQueue )
+HWND32 WIN_FindWinToRepaint( HWND32 hwnd, HQUEUE16 hQueue )
{
HWND hwndRet;
WND *pWnd = pWndDesktop;
@@ -267,7 +267,7 @@
* Send a WM_PARENTNOTIFY to all ancestors of the given window, unless
* the window has the WS_EX_NOPARENTNOTIFY style.
*/
-void WIN_SendParentNotify( HWND hwnd, WORD event, WORD idChild, LONG lValue )
+void WIN_SendParentNotify( HWND32 hwnd, WORD event, WORD idChild, LONG lValue )
{
LPPOINT16 lppt = (LPPOINT16)&lValue;
WND *wndPtr = WIN_FindWndPtr( hwnd );
@@ -320,6 +320,7 @@
if (!wndPtr) return;
WIN_UnlinkWindow( hwnd ); /* Remove the window from the linked list */
TIMER_RemoveWindowTimers( hwnd );
+ PROPERTY_RemoveWindowProps( wndPtr );
wndPtr->dwMagic = 0; /* Mark it as invalid */
wndPtr->hwndSelf = 0;
if ((wndPtr->hrgnUpdate) || (wndPtr->flags & WIN_INTERNAL_PAINT))
@@ -362,7 +363,7 @@
*
* Create the desktop window.
*/
-BOOL WIN_CreateDesktopWindow(void)
+BOOL32 WIN_CreateDesktopWindow(void)
{
CLASS *class;
HDC hdc;
@@ -406,11 +407,11 @@
pWndDesktop->hdce = 0;
pWndDesktop->pVScroll = NULL;
pWndDesktop->pHScroll = NULL;
+ pWndDesktop->pProp = NULL;
pWndDesktop->wIDmenu = 0;
pWndDesktop->flags = 0;
pWndDesktop->window = rootWindow;
pWndDesktop->hSysMenu = 0;
- pWndDesktop->hProp = 0;
pWndDesktop->userdata = 0;
WINPROC_SetProc( &pWndDesktop->winproc, (WNDPROC16)class->winproc, 0 );
@@ -528,8 +529,8 @@
wndPtr->flags = 0;
wndPtr->pVScroll = NULL;
wndPtr->pHScroll = NULL;
+ wndPtr->pProp = NULL;
wndPtr->hSysMenu = MENU_GetDefSysMenu();
- wndPtr->hProp = 0;
wndPtr->userdata = 0;
if (classPtr->cbWndExtra) memset( wndPtr->wExtra, 0, classPtr->cbWndExtra);
@@ -556,7 +557,7 @@
/* Insert the window in the linked list */
- WIN_LinkWindow( hwnd, HWND_BOTTOM );
+ WIN_LinkWindow( hwnd, (cs->style & WS_CHILD) ? HWND_BOTTOM : HWND_TOP );
/* Send the WM_GETMINMAXINFO message and fix the size if needed */
@@ -565,6 +566,8 @@
NC_GetMinMaxInfo( hwnd, &maxSize, &maxPos, &minTrack, &maxTrack );
if (maxSize.x < cs->cx) cs->cx = maxSize.x;
if (maxSize.y < cs->cy) cs->cy = maxSize.y;
+ if (cs->cx < minTrack.x ) cs->cx = minTrack.x;
+ if (cs->cy < minTrack.y ) cs->cy = minTrack.y;
}
if (cs->cx <= 0) cs->cx = 1;
if (cs->cy <= 0) cs->cy = 1;
@@ -711,20 +714,25 @@
if (wndPtr->dwStyle & WS_MINIMIZE)
{
+ /* MinMaximize(hwnd, SW_SHOWMINNOACTIVE, 1) in "Internals" */
+
wndPtr->dwStyle &= ~WS_MAXIMIZE;
WINPOS_FindIconPos( hwnd );
SetWindowPos( hwnd, 0, wndPtr->ptIconPos.x, wndPtr->ptIconPos.y,
- SYSMETRICS_CXICON, SYSMETRICS_CYICON, SWP_FRAMECHANGED |
- ((cs->style & WS_VISIBLE) ? SWP_SHOWWINDOW : 0 ));
+ SYSMETRICS_CXICON, SYSMETRICS_CYICON,
+ SWP_FRAMECHANGED | ((GetActiveWindow())? SWP_NOACTIVATE : 0) );
}
else if (wndPtr->dwStyle & WS_MAXIMIZE)
{
+ /* MinMaximize(hwnd, SW_SHOWMAXIMIZED, 1) */
+
POINT16 maxSize, maxPos, minTrack, maxTrack;
NC_GetMinMaxInfo( hwnd, &maxSize, &maxPos, &minTrack, &maxTrack );
SetWindowPos( hwnd, 0, maxPos.x, maxPos.y, maxSize.x, maxSize.y,
- SWP_FRAMECHANGED | ((cs->style & WS_VISIBLE) ? SWP_SHOWWINDOW : 0) );
+ ((GetActiveWindow())? SWP_NOACTIVATE : 0) | SWP_FRAMECHANGED );
}
- else if (cs->style & WS_VISIBLE) ShowWindow( hwnd, SW_SHOW );
+
+ if (cs->style & WS_VISIBLE) ShowWindow( hwnd, SW_SHOW );
/* Call WH_SHELL hook */
@@ -898,8 +906,10 @@
SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE );
if ((hwnd == GetCapture()) || IsChild( hwnd, GetCapture() ))
ReleaseCapture();
- if (!QUEUE_GetDoomedQueue())
- WIN_SendParentNotify( hwnd, WM_DESTROY, wndPtr->wIDmenu, (LONG)hwnd );
+ if (!QUEUE_GetDoomedQueue())
+ WIN_SendParentNotify( hwnd, WM_DESTROY, wndPtr->wIDmenu, (LONG)hwnd );
+
+ CLIPBOARD_DisOwn( hwnd );
/* Recursively destroy owned windows */
@@ -915,8 +925,6 @@
else break;
}
- CLIPBOARD_DisOwn( hwnd );
-
/* Send destroy messages and destroy children */
SendMessage16( hwnd, WM_DESTROY, 0, 0 );
@@ -1197,10 +1205,10 @@
/**********************************************************************
* WIN_GetWindowInstance
*/
-HINSTANCE WIN_GetWindowInstance(HWND hwnd)
+HINSTANCE16 WIN_GetWindowInstance( HWND32 hwnd )
{
WND * wndPtr = WIN_FindWndPtr( hwnd );
- if (!wndPtr) return (HINSTANCE)0;
+ if (!wndPtr) return (HINSTANCE16)0;
return wndPtr->hInstance;
}
@@ -1477,7 +1485,7 @@
*
* Get the top-level parent for a child window.
*/
-HWND WIN_GetTopParent( HWND hwnd )
+HWND32 WIN_GetTopParent( HWND32 hwnd )
{
WND *wndPtr = WIN_FindWndPtr( hwnd );
while (wndPtr && (wndPtr->dwStyle & WS_CHILD)) wndPtr = wndPtr->parent;
diff --git a/windows/winpos.c b/windows/winpos.c
index db6e82b..23ab087 100644
--- a/windows/winpos.c
+++ b/windows/winpos.c
@@ -672,10 +672,21 @@
if (!IsWindow( hwnd )) return wasVisible;
}
- /* We can't activate a child window */
- if (wndPtr->dwStyle & WS_CHILD) swpflags |= SWP_NOACTIVATE | SWP_NOZORDER;
- SetWindowPos( hwnd, HWND_TOP, x, y, cx, cy, swpflags );
- if (!IsWindow( hwnd )) return wasVisible;
+ if ((wndPtr->dwStyle & WS_CHILD) &&
+ !IsWindowVisible( wndPtr->parent->hwndSelf ) &&
+ (swpflags & SWP_NOSIZE) && (swpflags & SWP_NOMOVE))
+ {
+ /* Don't call SetWindowPos() on invisible child windows */
+ if (cmd == SW_HIDE) wndPtr->dwStyle &= ~WS_VISIBLE;
+ else wndPtr->dwStyle |= WS_VISIBLE;
+ }
+ else
+ {
+ /* We can't activate a child window */
+ if (wndPtr->dwStyle & WS_CHILD) swpflags |= SWP_NOACTIVATE;
+ SetWindowPos( hwnd, HWND_TOP, x, y, cx, cy, swpflags );
+ if (!IsWindow( hwnd )) return wasVisible;
+ }
if (wndPtr->flags & WIN_NEED_SIZE)
{