diff --git a/ANNOUNCE b/ANNOUNCE index 2c43984c411..cf7b48e7d0a 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 @@ Because of lags created by using mirror, this message may reach you before 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 09c335fa86a..43a3c8f85cf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,120 @@ +---------------------------------------------------------------------- +Sun Jul 28 17:57:19 1996 Alexandre Julliard + + * [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 + + * [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 + + * [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 + + * [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 + + * [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 @@ -270,7 +387,7 @@ Fri Jul 5 11:56:22 1996 Andreas Kirschbaum +Wed Jul 3 09:26:41 1996 Andrew Lewycky * [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 989c0b23dc1..4990654d595 100644 --- a/controls/combo.c +++ b/controls/combo.c @@ -425,10 +425,7 @@ static LRESULT CBAddString(HWND hwnd, WPARAM wParam, LPARAM lParam) 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 5dae7f95837..c646fb6f6b5 100644 --- a/controls/edit.c +++ b/controls/edit.c @@ -2253,7 +2253,7 @@ static LRESULT EDIT_WM_Create(WND *wndPtr, WPARAM wParam, LPARAM lParam) *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 b3a5b8dda04..1cbb28c91c1 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 @@ -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 @@ int ListBoxFindMouse(LPHEADLIST lphl, int X, int Y) 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 @@ LPLISTSTRUCT ListBoxCreateItem(LPHEADLIST lphl, int id) 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 ListBoxInsertString(LPHEADLIST lphl, UINT uIndex, LPCSTR newstr) } -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 @@ int ListBoxDeleteString(LPHEADLIST lphl, UINT uIndex) 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 @@ int ListBoxDeleteString(LPHEADLIST lphl, UINT uIndex) lpls2 = lpls; lpls = (LPLISTSTRUCT)lpls->lpNext; } + if( lphl->OwnerDrawn ) + lbDeleteItemNotify( lphl, lpls); lpls2->lpNext = lpls->lpNext; } @@ -463,28 +580,43 @@ int ListBoxDeleteString(LPHEADLIST lphl, UINT uIndex) 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 @@ int ListBoxFindString(LPHEADLIST lphl, UINT nFirst, SEGPTR MatchStr) 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 @@ int ListBoxFindString(LPHEADLIST lphl, UINT nFirst, SEGPTR MatchStr) 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 @@ int ListBoxResetContent(LPHEADLIST lphl) 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 @@ int ListBoxGetSel(LPHEADLIST lphl, WORD wIndex) 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 @@ LONG ListBoxDirectory(LPHEADLIST lphl, UINT attrib, LPCSTR filespec) 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 @@ LONG ListBoxDirectory(LPHEADLIST lphl, UINT attrib, LPCSTR filespec) { 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 @@ LONG ListBoxDirectory(LPHEADLIST lphl, UINT attrib, LPCSTR filespec) { 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 @@ LONG ListBoxDirectory(LPHEADLIST lphl, UINT attrib, LPCSTR filespec) 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 @@ static LONG LBAddString(HWND hwnd, WORD wParam, LONG lParam) 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 LBDeleteString(HWND hwnd, WORD wParam, LONG lParam) 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 @@ static LONG LBSelectString(HWND hwnd, WORD wParam, LONG lParam) 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 @@ LRESULT ListBoxWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) 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 c88082927d0..e38a4cd7026 100644 --- a/controls/menu.c +++ b/controls/menu.c @@ -1533,6 +1533,8 @@ static BOOL MENU_TrackMenu( HMENU hmenu, UINT wFlags, int x, int y, 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 00000000000..1cee4342a42 --- /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 " (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 , +additions welcome. diff --git a/files/drive.c b/files/drive.c index fb15297561a..f85c1499c64 100644 --- a/files/drive.c +++ b/files/drive.c @@ -557,7 +557,7 @@ UINT32 GetDriveType32A( LPCSTR root ) { 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 7d30397d6b4..2ea02e3be8a 100644 --- a/files/file.c +++ b/files/file.c @@ -802,6 +802,121 @@ error: /* We get here if there was an error opening the file */ 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 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 f14590753ce..dca8d1bdf08 100644 --- a/if1632/gdi32.spec +++ b/if1632/gdi32.spec @@ -312,7 +312,7 @@ base 1 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 a607a331b76..ece39884018 100644 --- a/if1632/kernel.spec +++ b/if1632/kernel.spec @@ -104,8 +104,8 @@ type win16 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 @@ type win16 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 7378cce8016..71833e49603 100644 --- a/if1632/kernel32.spec +++ b/if1632/kernel32.spec @@ -16,14 +16,14 @@ base 1 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 @@ base 1 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 @@ base 1 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 @@ base 1 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 @@ base 1 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 @@ base 1 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 84019481f2b..614c4196882 100644 --- a/if1632/relay.c +++ b/if1632/relay.c @@ -4,7 +4,7 @@ */ #include - +#include "windows.h" #include "global.h" #include "module.h" #include "registers.h" @@ -268,6 +268,19 @@ INT16 Catch( LPCATCHBUF lpbuf ) /* 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 Catch( LPCATCHBUF lpbuf ) 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 @@ INT16 Throw( LPCATCHBUF lpbuf, INT16 retval ) 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 52ff7e722f8..5e10675291c 100644 --- a/if1632/user.spec +++ b/if1632/user.spec @@ -23,10 +23,10 @@ heap 65520 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 @@ heap 65520 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 ef4b733d6d2..d6da5555721 100644 --- a/if1632/user32.spec +++ b/if1632/user32.spec @@ -55,7 +55,7 @@ base 1 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 @@ base 1 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 @@ base 1 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 @@ base 1 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 @@ base 1 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 @@ base 1 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 @@ base 1 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 @@ base 1 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 @@ base 1 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 @@ base 1 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 @@ base 1 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 @@ base 1 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 6d2d7aa18f6..d420f76f885 100644 --- a/include/callback.h +++ b/include/callback.h @@ -60,8 +60,8 @@ extern WORD CallTo16_regs_( FARPROC16 func, WORD ds, WORD es, WORD bp, WORD ax, 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 @@ extern LONG CallTo32_4( FARPROC32, DWORD, DWORD, DWORD, DWORD ); 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 @@ extern LONG CallTo32_4( FARPROC32, DWORD, DWORD, DWORD, DWORD ); (*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 dda909c2e42..418f72371b2 100644 --- a/include/class.h +++ b/include/class.h @@ -37,6 +37,5 @@ extern void CLASS_DumpClass( CLASS *class ); 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 03a658bff70..7cc07e9f213 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 Colormap COLOR_GetColormap(); 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 1555b1809d7..14c34b8352a 100644 --- a/include/cursoricon.h +++ b/include/cursoricon.h @@ -10,6 +10,8 @@ #include #include "windows.h" +#pragma pack(1) + typedef struct { BYTE bWidth; @@ -38,8 +40,6 @@ typedef union CURSORDIRENTRY cursor; } CURSORICONDIRENTRY; -#pragma pack(1) - typedef struct { WORD idReserved; diff --git a/include/dde_mem.h b/include/dde_mem.h index 3bc8dfaf5e7..b2c30795320 100644 --- a/include/dde_mem.h +++ b/include/dde_mem.h @@ -26,7 +26,7 @@ typedef struct { 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 011d389ee17..29397d756a4 100644 --- a/include/dde_proc.h +++ b/include/dde_proc.h @@ -52,8 +52,8 @@ void dde_wnd_setup(); /* setup Data structure of DDE windows */ /* 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 ee55f9b883c..e262c09a65f 100644 --- a/include/heap.h +++ b/include/heap.h @@ -16,6 +16,7 @@ extern HANDLE32 SegptrHeap; 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 78ab156951f..f77592a480e 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 @@ extern ldt_copy_entry ldt_copy[LDT_SIZE]; #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 @@ extern unsigned char ldt_flags_copy[LDT_SIZE]; #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 cdd82cb99c0..8b9130f2cf4 100644 --- a/include/listbox.h +++ b/include/listbox.h @@ -47,7 +47,7 @@ extern void ListBoxSendNotification(LPHEADLIST lphl, WORD code); 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 90b91841ce4..c876e60ad7b 100644 --- a/include/miscemu.h +++ b/include/miscemu.h @@ -16,6 +16,11 @@ extern BOOL32 DOSMEM_Init(void); 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 ce4519baab7..1bdef2f715b 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 2881c707006..f7c92a56e2e 100644 --- a/include/task.h +++ b/include/task.h @@ -81,7 +81,9 @@ typedef struct 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 37938c1b6bb..3c95981fd5d 100644 --- a/include/win.h +++ b/include/win.h @@ -47,17 +47,17 @@ typedef struct tagWND 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 @@ typedef struct tagWND #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 396942a8515..767363a78ae 100644 --- a/include/windows.h +++ b/include/windows.h @@ -1486,6 +1486,9 @@ typedef struct #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 @@ typedef struct #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 @@ typedef struct tagDCB 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 @@ typedef struct _SYSTEM_POWER_STATUS 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 @@ typedef struct _SYSTEM_POWER_STATUS 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 @@ HQUEUE16 GetTaskQueue(HTASK16); 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 @@ DWORD HeapSize(HANDLE32,DWORD,LPVOID); 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 @@ BOOL32 AppendMenu32W(HMENU32,UINT32,UINT32,LPCWSTR); 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 @@ BOOL32 CharToOemBuff32W(LPCWSTR,LPSTR,DWORD); 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 @@ BOOL32 EndPaint32(HWND32,const PAINTSTRUCT32*); 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 @@ BOOL32 EnumWindows32(WNDENUMPROC32,LPARAM); 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 @@ INT32 GetClipBox32(HDC32,LPRECT32); 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 @@ INT32 GetObject32W(HANDLE32,INT32,LPVOID); 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 RegCreateKey16(HKEY,LPCSTR,LPHKEY); 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 RegEnumKey16(HKEY,DWORD,LPSTR,DWORD); 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 RegOpenKey16(HKEY,LPCSTR,LPHKEY); 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 RegSetValueEx16(HKEY,LPSTR,DWORD,DWORD,LPBYTE,DWORD); 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 SetClassLong16(HWND16,INT16,LONG); 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 @@ BOOL32 SetEnvironmentVariable32W(LPCWSTR,LPCWSTR); 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 @@ BOOL32 TextOut32W(HDC32,INT32,INT32,LPCWSTR,INT32); 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 (*FONTENUMPROC)(const void*,const void*,DWORD,LPARAM); 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 @@ UINT ArrangeIconicWindows(HWND); 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 @@ BOOL ChangeClipboardChain(HWND,HWND); 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 EnumFontFamilies(HDC,LPCSTR,FONTENUMPROC,LPARAM); 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 @@ BOOL FillRgn(HDC,HRGN,HBRUSH); 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 GetClipboardOwner(void); 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 @@ UINT GetPrivateProfileInt(LPCSTR,LPCSTR,INT,LPCSTR); 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 @@ BOOL OemToAnsi(LPCSTR,LPSTR); 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 ProfSetup(int,int); 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 @@ void ReleaseCapture(void); 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 @@ WORD SelectorAccessRights(WORD,WORD,WORD); 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 @@ WORD SetPaletteEntries(HPALETTE16,WORD,WORD,LPPALETTEENTRY); 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 ToAscii(WORD,WORD,LPSTR,LPVOID,WORD); 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 @@ void WaitMessage(void); 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 5a61ec9af78..389a9fe196d 100644 --- a/include/wintypes.h +++ b/include/wintypes.h @@ -160,23 +160,33 @@ DECLARE_HANDLE(HWAVEOUT); 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(HWAVEIN); 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 @@ DECL_WINELIB_TYPE(WNDPROC); #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 6d249084824..1aef654069f 100644 --- a/ipc/dde_atom.c +++ b/ipc/dde_atom.c @@ -66,7 +66,7 @@ static int FindHash(LPCSTR str) /* ignore str case */ 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 @@ static int FindHash(LPCSTR str) /* ignore str case */ 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 b65b5faf0ec..36ca350dd9a 100644 --- a/ipc/dde_proc.c +++ b/ipc/dde_proc.c @@ -45,7 +45,7 @@ sigjmp_buf env_wait_x; #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 @@ int dde_proc_shift_fifo() 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 @@ static BOOL DDE_DoOneMessage (int proc_idx, int size, struct msgbuf *msgbuf) } 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 @@ static HWND HWND_Local2Remote(HWND orig) 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 @@ static BOOL DDE_DoMessage( MSG *msg, int type ) } } -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 @@ int DDE_GetRemoteMessage() { 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 @@ void stop_wait(int a) } } -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 5def7e6a794..6bd296f35d7 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 0f3d9a0f3fe..071b69e5a57 100644 --- a/library/miscstubs.c +++ b/library/miscstubs.c @@ -7,8 +7,8 @@ #include #include #include -#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 01b6511c804..235faea4a7a 100644 --- a/loader/main.c +++ b/loader/main.c @@ -41,6 +41,13 @@ static char Copyright[] = "Copyright Robert J. Amstadt, 1993"; #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 31a998bac9f..bf4fd5e80cc 100644 --- a/loader/module.c +++ b/loader/module.c @@ -273,13 +273,8 @@ static WORD MODULE_Ne2MemFlags(WORD flags) 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 @@ static BOOL MODULE_CreateSegments( HMODULE16 hModule ) /*********************************************************************** * MODULE_GetInstance */ -#ifndef WINELIB32 HINSTANCE16 MODULE_GetInstance( HMODULE16 hModule ) { SEGTABLEENTRY *pSegment; @@ -331,7 +325,6 @@ HINSTANCE16 MODULE_GetInstance( HMODULE16 hModule ) return pSegment->selector; } -#endif /*********************************************************************** @@ -1299,13 +1292,13 @@ int GetModuleFileName( HANDLE hModule, LPSTR lpFileName, short nSize ) */ 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 @@ HANDLE LoadLibrary( LPCSTR libname ) 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 @@ HANDLE WinExec( LPSTR lpCmdLine, WORD nCmdShow ) } /* 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 917877224db..fd3a3029496 100644 --- a/loader/pe_resource.c +++ b/loader/pe_resource.c @@ -82,6 +82,11 @@ PIMAGE_RESOURCE_DIRECTORY GetResDirEntryW(PIMAGE_RESOURCE_DIRECTORY resdirptr, 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 ef862d2ba2e..bf327904fdc 100644 --- a/loader/task.c +++ b/loader/task.c @@ -1059,6 +1059,68 @@ HQUEUE16 GetTaskQueue( HTASK16 hTask ) } +/*********************************************************************** + * 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) */ @@ -1287,3 +1349,15 @@ DWORD GetAppCompatFlags( HTASK32 hTask ) 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 c3d66a75f15..f88d129a7c2 100644 --- a/memory/global.c +++ b/memory/global.c @@ -46,8 +46,6 @@ typedef struct 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)) @@ -550,41 +548,6 @@ BOOL16 GlobalUnWire( HGLOBAL16 handle ) } -/*********************************************************************** - * 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) */ diff --git a/memory/heap.c b/memory/heap.c index acdd8dfe290..5c3573ccad9 100644 --- a/memory/heap.c +++ b/memory/heap.c @@ -1212,6 +1212,18 @@ LPSTR HEAP_strdupA( HANDLE32 heap, DWORD flags, LPCSTR str ) { 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 35116372e63..9b1ef9e7117 100644 --- a/memory/ldt.c +++ b/memory/ldt.c @@ -13,8 +13,6 @@ #include "stddebug.h" #include "debug.h" -#ifndef WINELIB - #ifdef linux #include #include @@ -22,6 +20,7 @@ _syscall3(int, modify_ldt, int, func, void *, ptr, unsigned long, bytecount) #endif /* linux */ + #if defined(__svr4__) || defined(_SCO_DS) #include #include @@ -34,8 +33,6 @@ extern int i386_get_ldt(int, union descriptor *, int); 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 @@ int LDT_SetEntry( int entry, const ldt_entry *content ) /* 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 @@ int LDT_SetEntry( int entry, const ldt_entry *content ) #endif /* linux */ #if defined(__NetBSD__) || defined(__FreeBSD__) + if (!__winelib) { long d[2]; @@ -182,35 +180,32 @@ int LDT_SetEntry( int entry, const ldt_entry *content ) } #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 a38a0d1970a..ecf7df432fa 100644 --- a/memory/selector.c +++ b/memory/selector.c @@ -262,7 +262,20 @@ void LongPtrAdd( DWORD ptr, DWORD add ) */ 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 @@ DWORD GetSelectorBase( WORD sel ) */ 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 a68542a1551..b628a2bd790 100644 --- a/misc/comm.c +++ b/misc/comm.c @@ -1,5 +1,7 @@ /* * DEC 93 Erik Bos + * + * Copyright 1996 Marcus Meissner */ #include @@ -11,7 +13,6 @@ #include #include #if defined(__NetBSD__) || defined(__FreeBSD__) -#include #include #endif #include @@ -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 @@ int WinError(void) } } -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 @@ BOOL BuildCommDCB(LPCSTR device, LPDCB lpdcb) *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 @@ BOOL BuildCommDCB(LPCSTR device, LPDCB lpdcb) 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 @@ int OpenComm(LPCSTR device, UINT cbInQueue, UINT cbOutQueue) 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 CloseComm(int fd) } } -int SetCommBreak(int fd) +/***************************************************************************** + * SetCommBreak (USER.210) + */ +INT16 SetCommBreak16(INT16 fd) { struct DosDeviceStruct *ptr; @@ -309,7 +471,31 @@ int SetCommBreak(int fd) 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 @@ int ClearCommBreak(int fd) 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 @@ LONG EscapeCommFunction(int fd, int nFunction) 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 @@ LONG EscapeCommFunction(int fd, int nFunction) } } -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 FlushComm(int fd, int fnQueue) } } -int GetCommError(int fd, COMSTAT *lpStat) +/***************************************************************************** + * GetCommError (USER.203) + */ +INT16 GetCommError(INT16 fd,LPCOMSTAT lpStat) { int temperror; @@ -437,15 +722,36 @@ int GetCommError(int fd, COMSTAT *lpStat) 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 @@ UINT GetCommEventMask(int fd, int fnEvtClear) 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 SetCommState(DCB *lpdcb) } } -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 @@ int GetCommState(int fd, DCB *lpdcb) commerror = WinError(); return -1; } - lpdcb->Id = fd; - #ifdef CBAUD switch (port.c_cflag & CBAUD) { #else @@ -769,7 +1313,127 @@ int GetCommState(int fd, DCB *lpdcb) 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 TransmitCommChar(int fd, char chTransmit) } } -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 @@ int UngetCommChar(int fd, char chUnget) 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 ReadComm(int fd, LPSTR lpvBuf, int cbRead) } } -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 @@ int WriteComm(int fd, LPSTR lpvBuf, int cbWrite) 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 dda9e254111..176bb5af612 100644 --- a/misc/commdlg.c +++ b/misc/commdlg.c @@ -416,13 +416,8 @@ static LRESULT FILEDLG_WMCommand(HWND hWnd, WPARAM wParam, LPARAM lParam) 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 2c811e300d1..fc0de1851ee 100644 --- a/misc/lstr.c +++ b/misc/lstr.c @@ -631,3 +631,148 @@ BOOL32 OemToChar32W(LPCSTR s,LPWSTR d) 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 @@ -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 @@ typedef struct static BIOSDATA *pBiosData = NULL; +char *DOSMEM_dosmem; +struct dosmem_entry { + struct dosmem_entry *next; + BYTE isfree; +}; /*********************************************************************** @@ -87,54 +94,82 @@ static BIOSDATA *pBiosData = NULL; 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 @@ void DOSMEM_FillBiosSegment(void) 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 738c413ae96..2e41f4b1dab 100644 --- a/miscemu/dpmi.c +++ b/miscemu/dpmi.c @@ -98,10 +98,7 @@ void INT_Int31Handler( SIGCONTEXT *context ) 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 @@ void INT_Int31Handler( SIGCONTEXT *context ) 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 @@ void INT_Int31Handler( SIGCONTEXT *context ) } 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 79176dcaed1..759421957f6 100644 --- a/miscemu/int21.c +++ b/miscemu/int21.c @@ -1308,6 +1308,9 @@ void DOS3Call( SIGCONTEXT *context ) 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 cd2d86bd406..b525372141f 100644 --- a/multimedia/time.c +++ b/multimedia/time.c @@ -174,6 +174,8 @@ WORD timeKillEvent(WORD wID) 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 4eba5dbe315..1cb29bb9a8c 100644 --- a/objects/bitblt.c +++ b/objects/bitblt.c @@ -891,7 +891,8 @@ static void BITBLT_GetDstArea(DC *dc, Pixmap pixmap, GC gc, RECT16 *visRectDst) 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 @@ static void BITBLT_PutDstArea(DC *dc, Pixmap pixmap, GC gc, RECT16 *visRectDst) 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 @@ BOOL BITBLT_InternalStretchBlt( DC *dcDst, short xDst, short yDst, !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 56805817b26..f609f25c41d 100644 --- a/objects/bitmap.c +++ b/objects/bitmap.c @@ -227,6 +227,35 @@ LONG SetBitmapBits( HBITMAP32 hbitmap, LONG count, LPCVOID buffer ) 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 6331df08d5d..00553ab1b24 100644 --- a/objects/brush.c +++ b/objects/brush.c @@ -236,7 +236,7 @@ HBRUSH CreateSolidBrush( COLORREF color ) /*********************************************************************** * 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 @@ DWORD SetBrushOrg( HDC hdc, short x, short y ) 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 e92adea617e..b7c45a2b8c3 100644 --- a/objects/color.c +++ b/objects/color.c @@ -62,7 +62,8 @@ static int COLOR_Graymax = 0; * 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_gapStart = 256; 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 @@ UINT16 COLOR_GetSystemPaletteFlags(void) 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 @@ static BOOL COLOR_BuildSharedMap(CSPACE* cs) * 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 @@ static BOOL COLOR_BuildSharedMap(CSPACE* cs) /* 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 @@ static HPALETTE16 COLOR_InitPalette(void) int i; HPALETTE16 hpalette; LOGPALETTE * palPtr; + PALETTEOBJ* palObj; + + memset(COLOR_freeList, 0, 256*sizeof(unsigned char)); /* calculate max palette size */ @@ -397,11 +486,13 @@ static HPALETTE16 COLOR_InitPalette(void) 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 @@ static HPALETTE16 COLOR_InitPalette(void) 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 @@ BOOL COLOR_IsSolid( COLORREF color ) /*********************************************************************** - * COLOR_PaletteLookup - * + * COLOR_PaletteLookupPixel */ int COLOR_PaletteLookupPixel( PALETTEENTRY* palPalEntry, int size, int* mapping, COLORREF col, BOOL skipReserved ) @@ -543,7 +638,7 @@ int COLOR_PaletteLookupPixel( PALETTEENTRY* palPalEntry, int size, 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 @@ int COLOR_PaletteLookupPixel( PALETTEENTRY* palPalEntry, int size, 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 @@ int COLOR_PaletteLookupExactIndex( PALETTEENTRY* palPalEntry, int size, 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 @@ int COLOR_PaletteLookupExactIndex( PALETTEENTRY* palPalEntry, int size, 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 @@ int COLOR_ToPhysical( DC *dc, COLORREF color ) 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; - } - 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; + return 0; } + + 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 @@ int COLOR_ToPhysical( DC *dc, COLORREF color ) return index; } - /*********************************************************************** * COLOR_SetMapping * @@ -754,11 +912,10 @@ int COLOR_SetMapping( PALETTEOBJ* palPtr, BOOL mapOnly ) 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 @@ int COLOR_SetMapping( PALETTEOBJ* palPtr, BOOL mapOnly ) 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 @@ int COLOR_SetMapping( PALETTEOBJ* palPtr, BOOL mapOnly ) 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 @@ int COLOR_SetMapping( PALETTEOBJ* palPtr, BOOL mapOnly ) 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 @@ int COLOR_SetMapping( PALETTEOBJ* palPtr, BOOL mapOnly ) 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 c750d6143b6..5a35ff8c949 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 @@ HICON16 LoadIcon16(HINSTANCE16 hInstance,SEGPTR name) return CURSORICON_Load( hInstance, name, SYSMETRICS_CXICON, SYSMETRICS_CYICON, - MIN( 16, 1 << screenDepth ), FALSE ); + MIN( 16, COLOR_GetSystemPaletteSize() ), FALSE ); } @@ -935,7 +936,8 @@ void GetClipCursor32( RECT32 *rect ) */ 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 @@ WORD GetIconID( HANDLE hResource, DWORD resType ) } 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 5e3eff9ca05..58529ac8b76 100644 --- a/objects/dc.c +++ b/objects/dc.c @@ -112,7 +112,7 @@ void DC_FillDevCaps( DeviceCaps * caps ) 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 @@ void DC_FillDevCaps( DeviceCaps * caps ) 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 8190af42485..ef9f072aed7 100644 --- a/objects/dib.c +++ b/objects/dib.c @@ -542,13 +542,14 @@ static void DIB_SetImageBits_24( WORD lines, BYTE *bits, WORD width, 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 c287be84b77..854322a544d 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 */ @@ -24,56 +27,6 @@ static HPALETTE16 hPrimaryPalette = 0; /* used for WM_PALETTECHANGED */ static HPALETTE16 hLastRealizedPalette = 0; /* UnrealizeObject() needs it */ -/*********************************************************************** - * 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 */ @@ -158,6 +111,9 @@ WORD SetPaletteEntries( HPALETTE16 hpalette, WORD start, WORD count, count * sizeof(PALETTEENTRY) ); PALETTE_ValidateFlags(palPtr->logpalette.palPalEntry, palPtr->logpalette.palNumEntries); + free(palPtr->mapping); + palPtr->mapping = NULL; + return count; } @@ -213,7 +169,8 @@ WORD GetSystemPaletteEntries( HDC hdc, WORD start, WORD count, { 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 @@ WORD GetSystemPaletteEntries( HDC hdc, WORD start, WORD count, 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 GetSystemPaletteEntries( HDC hdc, WORD start, WORD count, */ 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 @@ WORD GetNearestPaletteIndex( HPALETTE16 hpalette, COLORREF color ) */ 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 )) ) + { + 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 ); + } - if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return 0; - PALETTE_GetNearestIndexAndColor( dc->w.hPalette, &nearest ); dprintf_palette(stddeb,"GetNearestColor(%06lx): returning %06lx\n", color, nearest ); return nearest; @@ -307,7 +276,13 @@ HPALETTE16 GDISelectPalette( HDC hdc, HPALETTE16 hpal, WORD wBkg) 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 @@ HPALETTE16 GDISelectPalette( HDC hdc, HPALETTE16 hpal, WORD wBkg) */ 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 @@ UINT GDIRealizePalette( HDC hdc ) */ 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 @@ WORD RealizeDefaultPalette( HDC hdc ) 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 @@ HPALETTE16 SelectPalette( HDC hDC, HPALETTE16 hPal, BOOL bForceBackground ) /* 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 @@ UINT16 RealizePalette( HDC32 hDC ) /* 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 @@ int UpdateColors( HDC hDC ) /* Docs say that we have to remap current drawable pixel by pixel * but it would take forever given the speed of XGet/PutPixel. */ - if (hWnd) 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 80b6cc98c5a..e95680118e6 100644 --- a/windows/class.c +++ b/windows/class.c @@ -239,20 +239,6 @@ CLASS *CLASS_FindClassByAtom( ATOM atom, HINSTANCE16 hinstance ) } -/*********************************************************************** - * 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 * diff --git a/windows/dialog.c b/windows/dialog.c index bdd46a30c06..9faec22accc 100644 --- a/windows/dialog.c +++ b/windows/dialog.c @@ -577,6 +577,7 @@ static HWND DIALOG_CreateIndirect( HINSTANCE hInst, LPCSTR dlgTemplate, /* 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 @@ static HWND DIALOG_CreateIndirect( HINSTANCE hInst, LPCSTR dlgTemplate, /* 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 e6a053b5ddb..f00cfe94b49 100644 --- a/windows/event.c +++ b/windows/event.c @@ -149,6 +149,9 @@ static void EVENT_SelectionNotify( XSelectionEvent *event); 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 @@ void EVENT_ProcessEvent( XEvent *event ) case ClientMessage: EVENT_ClientMessage( pWnd, (XClientMessageEvent *) event ); break; - +/* case EnterNotify: + * EVENT_EnterNotify( pWnd, (XCrossingEvent *) event ); + * break; + */ case NoExpose: break; @@ -822,6 +828,20 @@ static void EVENT_ClientMessage( WND *pWnd, XClientMessageEvent *event ) 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 aa616c5bb97..e9cb15879be 100644 --- a/windows/hook.c +++ b/windows/hook.c @@ -276,11 +276,7 @@ void HOOK_FreeQueueHooks( HQUEUE16 hQueue ) */ 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 5f536919adc..2ff08e26341 100644 --- a/windows/mdi.c +++ b/windows/mdi.c @@ -373,8 +373,14 @@ HWND MDICreateChild(WND *w, MDICLIENTINFO *ci, HWND parent, LPARAM lParam ) 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 @@ void MDI_ChildGetMinMaxInfo(WND* clientWnd, HWND hwnd, MINMAXINFO16* lpMinMax ) 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 62c4c932d25..ff5e6468b03 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 @@ static BOOL MSG_PeekMessage( LPMSG16 msg, HWND hwnd, WORD first, WORD last, 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 @@ LRESULT SendMessage16( HWND16 hwnd, UINT16 msg, WPARAM16 wParam, LPARAM lParam) } 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 dc5303c4ba4..e60a61c6f8d 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 #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 d25450d122a..d00330b3b19 100644 --- a/windows/scroll.c +++ b/windows/scroll.c @@ -33,9 +33,8 @@ static int RgnType; * 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 @@ HRGN SCROLL_TraceChildren( HWND hScroll, short dx, short dy, WORD dcx) 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 @@ HRGN SCROLL_TraceChildren( HWND hScroll, short dx, short dy, WORD dcx) /* ---------------------------------------------------------------------- * 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 @@ BOOL SCROLL_ScrollChildren( HWND hScroll, short dx, short dy) } /* 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 @@ BOOL SCROLL_ScrollChildren( HWND hScroll, short dx, short dy) */ 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 @@ void ScrollWindow(HWND hwnd, short dx, short dy, LPRECT16 rect, LPRECT16 clipRec 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 @@ void ScrollWindow(HWND hwnd, short dx, short dy, LPRECT16 rect, LPRECT16 clipRec 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 25ccc7f6759..29b902f93bb 100644 --- a/windows/win.c +++ b/windows/win.c @@ -52,11 +52,11 @@ extern HQUEUE QUEUE_GetDoomedQueue(); * * 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 @@ WND * WIN_FindWndPtr( HWND hwnd ) * * 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 @@ void WIN_DumpWindow( HWND hwnd ) "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 @@ void WIN_DumpWindow( HWND hwnd ) 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 @@ void WIN_DumpWindow( HWND hwnd ) * * 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 @@ void WIN_WalkWindows( HWND hwnd, int indent ) * * 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 @@ Window WIN_GetXWindow( HWND hwnd ) * * 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 @@ BOOL WIN_UnlinkWindow( HWND hwnd ) * 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 @@ BOOL WIN_LinkWindow( HWND hwnd, HWND hwndInsertAfter ) * * 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 @@ HWND WIN_FindWinToRepaint( HWND hwnd, HQUEUE hQueue ) * 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 @@ static void WIN_DestroyWindow( HWND hwnd ) 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 @@ void WIN_DestroyQueueWindows( WND* wnd, HQUEUE hQueue ) * * Create the desktop window. */ -BOOL WIN_CreateDesktopWindow(void) +BOOL32 WIN_CreateDesktopWindow(void) { CLASS *class; HDC hdc; @@ -406,11 +407,11 @@ BOOL WIN_CreateDesktopWindow(void) 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 @@ static HWND WIN_CreateWindowEx( CREATESTRUCT32A *cs, ATOM classAtom, 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 @@ static HWND WIN_CreateWindowEx( CREATESTRUCT32A *cs, ATOM classAtom, /* 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 @@ static HWND WIN_CreateWindowEx( CREATESTRUCT32A *cs, ATOM classAtom, 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 @@ static HWND WIN_CreateWindowEx( CREATESTRUCT32A *cs, ATOM classAtom, 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 @@ BOOL DestroyWindow( HWND hwnd ) 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 @@ BOOL DestroyWindow( HWND hwnd ) else break; } - CLIPBOARD_DisOwn( hwnd ); - /* Send destroy messages and destroy children */ SendMessage16( hwnd, WM_DESTROY, 0, 0 ); @@ -1197,10 +1205,10 @@ WORD GetWindowWord( HWND32 hwnd, INT32 offset ) /********************************************************************** * 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 @@ HWND GetParent(HWND hwnd) * * 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 db6e82b9a7c..23ab087b572 100644 --- a/windows/winpos.c +++ b/windows/winpos.c @@ -672,10 +672,21 @@ BOOL ShowWindow( HWND hwnd, int cmd ) 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) {