From 988ca977ab412a9b5f82aff0d4e0707f662e4906 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Tue, 21 Jun 1994 16:15:21 +0000 Subject: [PATCH] Release 940620 Mon Jun 20 14:26:41 1994 Bob Amstadt (bob@pooh) * [objects/bitmap.c] Allow negative bitmap sizes. Sun Jun 19 12:00:04 1994 David Metcalfe * [controls/edit.c] Improved selection display. Added processing for WM_SETFONT, EM_REPLACESEL, EM_LINELENGTH, EM_UNDO, EM_EMPTYUNDOBUFFER, EM_GETHANDLE, EM_SETHANDLE messages. Text buffer now stored on application's local heap. * [windows/graphics.c] Corrected bug in Rectangle(). XFillRectangle has the same width as Rectangle, but XDrawRectangle is one pixel wider for the same co-ordinates. * [memory/heap.c] [include/heap.h] Added HEAP_LocalSize function. * [windows/event.c] [windows/keyboard.c] Improvements to KeyStateTable and addition of AsyncKeyStateTable. Added supporting code to GetKeyState and GetAsyncKeyState and merged mouse button states into GetKeyboardState. * [loader/resource.c] [include/accel.h] Added recognition of SHIFT, CONTROL and ALT keys to TranslateAccelerator. * [objects/metafile.c] [objects/font.c] [objects/bitblt.c] A bit more metafile support. Sun Jun 19 17:29:00 MET DST 1994 Erik Bos (erik@hacktic.nl) * [loader/resource.c] SizeofResource() and AllocResource() added, AccessResource() updated. * [if1632/kernel.spec] FreeLibrary() used for FreeModule(). * [windows/graphics.c] Rectangle(): swap left & right corners when right < left, swap top & bottom when botton < top. Jun 19, 94 martin2@trgcorp.solucorp.qc.ca (Martin Ayotte) * [controls/combo.c] Fix bug in window style of the associated listbox. * [controls/menu.c] Skip separators in keyboard navigation by using new internal functions SelectPrevItem() & SelectNextItem(), * [misc/profile.c] Bug fix in GetPrivateProfileInt(), was limited to 4 digit, IntBuf must be alloc to (5+1)=6. char instead of 5. * [misc/main.c] Put code in functions SetEnvironment() & GetEnvironment(). * [misc/shell.c] Start putting some code in ExtractIcon() function. * [misc/mmsystem.c] Some code for MMTimer functions & timers list. * [miscemu/int31.c] Few stubs for DPMI interrupt calls. Nothing work yet. Mon Jun 20 07:37:43 EDT 1994 John Richardson (jrichard@cs.uml.edu) * include/win.h (tagWND): Added icon fields icon, hIcon and rectClientSave to the tagWND struct. * windows/Imakefile Added icon.c to the list of files to compile * windows/dce.c (GetDCEx): Added some checks for iconic mode and pass icon window as drawable, not the real window. * windows/defwnd.c (DefWindowProc) Added PAINTICON default windows procedure. * windows/event.c (EVENT_Expose) Added check for iconic window expose. If iconic window is exposed send a WM_PAINTICON message * windows/icon.c New file. ICON_Iconify, ICON_findIconFromPoint, ICON_Deiconify. * windows/mdi.c (DefMDIChildProc) Test for IsIconic during a SC_RESTORE, this doesn't work yet. * windows/message.c (hardware_event) Looks for icon as well as window now. * windows/nonclient.c (NC_HandleSysCommand, NC_DoNCPaintIcon) Added iconify/deiconify in NC_HandleSysCommand, new function NC_DoNCPaintIcon which paints an icon. * windows/painting.c (BeginPaint) Made a BeginPaint select the STOCK_BLACK_PEN, STOCK_WHITE_BRUSH, and STOCK_SYSTEM_FONT objects since this is (hopefully) default windows behavior. * windows/win.h (CreateWindowEx) Set the default background color of a window to be white. Create icon window, turn off MINIMIZE if it is on, since I don't know what to do with it as of yet... register the icon with the hwnd of its window so we can identify where icon messages are coming from. Mon Jun 20 10:15:59 1994 Miguel de Icaza (miguel@sphinx) * windows/event.c: Added a hack to define XPointer when using X11R4. * toolkit/hello.c: Test application for WineLib. To compile you'll need: gcc -Iinclude -DWINELIB -g hello.c -c, and to link you'll need: gcc hello.o libwine.a -lX11 -L/usr/openwin/lib -lm * toolkit/heap.c: Extended the size of the block size per chunk. * misc/stress.c (GetFreeFileHandles): Fixed typo. * misc/main.c (main): Changes to allow compilation under SunOS. * loader/library.c: Changed some ifdefs to compile WineLib. --- ChangeLog | 135 +++++++++- controls/combo.c | 6 +- controls/edit.c | 626 +++++++++++++++++++++++++++++++++++++------ controls/menu.c | 72 ++++- if1632/call.S | 2 +- if1632/kernel.spec | 6 +- if1632/mmsystem.spec | 7 + include/accel.h | 1 + include/heap.h | 1 + include/metafile.h | 6 + include/win.h | 3 + loader/library.c | 7 +- loader/main.c | 5 +- loader/resource.c | 161 ++++++++++- memory/heap.c | 19 +- misc/main.c | 95 ++++++- misc/mmsystem.c | 171 ++++++++++++ misc/profile.c | 6 +- misc/property.c | 26 +- misc/shell.c | 20 +- misc/stress.c | 2 +- miscemu/int31.c | 82 +++++- objects/bitblt.c | 24 +- objects/bitmap.c | 7 + objects/font.c | 3 + objects/metafile.c | 61 +++++ toolkit/heap.c | 12 +- toolkit/hello.c | 72 +++++ windows/Imakefile | 1 + windows/dce.c | 23 +- windows/defwnd.c | 9 +- windows/event.c | 21 +- windows/graphics.c | 34 ++- windows/icon.c | 175 ++++++++++++ windows/keyboard.c | 30 ++- windows/mdi.c | 4 + windows/message.c | 6 + windows/nonclient.c | 45 +++- windows/painting.c | 8 + windows/win.c | 50 +++- 40 files changed, 1871 insertions(+), 173 deletions(-) create mode 100644 toolkit/hello.c create mode 100644 windows/icon.c diff --git a/ChangeLog b/ChangeLog index 001d4add021..0e61684e88b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,136 @@ +---------------------------------------------------------------------- +Mon Jun 20 14:26:41 1994 Bob Amstadt (bob@pooh) + + * [objects/bitmap.c] + Allow negative bitmap sizes. + +Sun Jun 19 12:00:04 1994 David Metcalfe + + * [controls/edit.c] + Improved selection display. Added processing for WM_SETFONT, + EM_REPLACESEL, EM_LINELENGTH, EM_UNDO, EM_EMPTYUNDOBUFFER, + EM_GETHANDLE, EM_SETHANDLE messages. Text buffer now stored on + application's local heap. + + * [windows/graphics.c] + Corrected bug in Rectangle(). XFillRectangle has the same + width as Rectangle, but XDrawRectangle is one pixel wider + for the same co-ordinates. + + * [memory/heap.c] [include/heap.h] + Added HEAP_LocalSize function. + + * [windows/event.c] [windows/keyboard.c] + Improvements to KeyStateTable and addition of AsyncKeyStateTable. + Added supporting code to GetKeyState and GetAsyncKeyState and + merged mouse button states into GetKeyboardState. + + * [loader/resource.c] [include/accel.h] + Added recognition of SHIFT, CONTROL and ALT keys to + TranslateAccelerator. + + * [objects/metafile.c] [objects/font.c] [objects/bitblt.c] + A bit more metafile support. + +Sun Jun 19 17:29:00 MET DST 1994 Erik Bos (erik@hacktic.nl) + + * [loader/resource.c] + SizeofResource() and AllocResource() added, AccessResource() updated. + + * [if1632/kernel.spec] + FreeLibrary() used for FreeModule(). + + * [windows/graphics.c] + Rectangle(): swap left & right corners when right < left, + swap top & bottom when botton < top. + +Jun 19, 94 martin2@trgcorp.solucorp.qc.ca (Martin Ayotte) + + * [controls/combo.c] + Fix bug in window style of the associated listbox. + + * [controls/menu.c] + Skip separators in keyboard navigation by using new internal + functions SelectPrevItem() & SelectNextItem(), + + * [misc/profile.c] + Bug fix in GetPrivateProfileInt(), was limited to 4 digit, + IntBuf must be alloc to (5+1)=6. char instead of 5. + + * [misc/main.c] + Put code in functions SetEnvironment() & GetEnvironment(). + + * [misc/shell.c] + Start putting some code in ExtractIcon() function. + + * [misc/mmsystem.c] + Some code for MMTimer functions & timers list. + + * [miscemu/int31.c] + Few stubs for DPMI interrupt calls. Nothing work yet. + +Mon Jun 20 07:37:43 EDT 1994 John Richardson (jrichard@cs.uml.edu) + + * include/win.h (tagWND): + Added icon fields icon, hIcon and rectClientSave to + the tagWND struct. + + * windows/Imakefile + Added icon.c to the list of files to compile + + * windows/dce.c (GetDCEx): + Added some checks for iconic mode and pass icon window as drawable, + not the real window. + + * windows/defwnd.c (DefWindowProc) + Added PAINTICON default windows procedure. + + * windows/event.c (EVENT_Expose) + Added check for iconic window expose. If iconic window is exposed + send a WM_PAINTICON message + + * windows/icon.c + New file. ICON_Iconify, ICON_findIconFromPoint, ICON_Deiconify. + + * windows/mdi.c (DefMDIChildProc) + Test for IsIconic during a SC_RESTORE, this doesn't work yet. + + * windows/message.c (hardware_event) + Looks for icon as well as window now. + + * windows/nonclient.c (NC_HandleSysCommand, NC_DoNCPaintIcon) + Added iconify/deiconify in NC_HandleSysCommand, new function + NC_DoNCPaintIcon which paints an icon. + + * windows/painting.c (BeginPaint) + Made a BeginPaint select the STOCK_BLACK_PEN, STOCK_WHITE_BRUSH, + and STOCK_SYSTEM_FONT objects since this is (hopefully) default + windows behavior. + + * windows/win.h (CreateWindowEx) + Set the default background color of a window to be white. + Create icon window, turn off MINIMIZE if it is on, since + I don't know what to do with it as of yet... register + the icon with the hwnd of its window so we can identify where + icon messages are coming from. + +Mon Jun 20 10:15:59 1994 Miguel de Icaza (miguel@sphinx) + + * windows/event.c: Added a hack to define XPointer when using + X11R4. + + * toolkit/hello.c: Test application for WineLib. To compile you'll + need: gcc -Iinclude -DWINELIB -g hello.c -c, and to link you'll + need: gcc hello.o libwine.a -lX11 -L/usr/openwin/lib -lm + + * toolkit/heap.c: Extended the size of the block size per chunk. + + * misc/stress.c (GetFreeFileHandles): Fixed typo. + + * misc/main.c (main): Changes to allow compilation under SunOS. + + * loader/library.c: Changed some ifdefs to compile WineLib. + ---------------------------------------------------------------------- Tue Jun 14 08:09:14 1994 Bob Amstadt (bob@pooh) @@ -16,7 +149,7 @@ Fri Jun 10 07:56:49 1994 Bob Amstadt (bob@pooh) * windows/event.c (SetCapture): Set winHasCursor if mouse capture succeeds. -Jun 6, 94 martin2@trgcorp.solucorp.qc.ca (Martin Ayotte) +Jun 13, 94 martin2@trgcorp.solucorp.qc.ca (Martin Ayotte) * [controls/listbox.c] Fix bug in listbox : InsertString should call AddString if -1. diff --git a/controls/combo.c b/controls/combo.c index ef6c3b70d81..d0591760762 100644 --- a/controls/combo.c +++ b/controls/combo.c @@ -78,9 +78,9 @@ LONG ComboBoxWndProc( HWND hwnd, WORD message, WORD wParam, LONG lParam ) 0, 0, width - bm.bmHeight, bm.bmHeight, hwnd, 1, wndPtr->hInstance, 0L); lphc->hWndLBox = CreateWindow("LISTBOX", "", - WS_CHILD | WS_CLIPCHILDREN | WS_BORDER | WS_VSCROLL | LBS_NOTIFY, - wndPtr->rectClient.left, wndPtr->rectClient.top + bm.bmHeight, - width, height, wndPtr->hwndParent, 1, + WS_POPUP | WS_BORDER | WS_VSCROLL | LBS_NOTIFY, + rect.left, rect.top + bm.bmHeight, + width, height, wndPtr->hwndParent, 0, wndPtr->hInstance, (LPSTR)MAKELONG(0, hwnd)); ShowWindow(lphc->hWndLBox, SW_HIDE); #ifdef DEBUG_COMBO diff --git a/controls/edit.c b/controls/edit.c index abafcfe967e..3aff8f86934 100644 --- a/controls/edit.c +++ b/controls/edit.c @@ -3,7 +3,7 @@ * * Copyright David W. Metcalfe, 1994 * - * Release 1, April 1994 + * Release 2, June 1994 */ static char Copyright[] = "Copyright David W. Metcalfe, 1994"; @@ -11,11 +11,13 @@ static char Copyright[] = "Copyright David W. Metcalfe, 1994"; #include #include #include +#include #include "win.h" #include "class.h" #include "user.h" +#include "scroll.h" -#define DEBUG_EDIT /* */ +/* #define DEBUG_EDIT /* */ #define NOTIFY_PARENT(hWndCntrl, wNotifyCode) \ SendMessage(GetParent(hWndCntrl), WM_COMMAND, \ @@ -44,6 +46,7 @@ typedef struct int textwidth; /* width of longest line in pixels */ RECT fmtrc; /* rectangle in which to format text */ int txtht; /* height of text line in pixels */ + MDESC **localheap; /* pointer to application's local heap */ HANDLE hText; /* handle to text buffer */ HANDLE hCharWidths; /* widths of chars in font */ HANDLE hTextPtrs; /* list of line offsets */ @@ -59,6 +62,11 @@ typedef struct int SelBegCol; /* beginning column of selection */ int SelEndLine; /* ending line of selection */ int SelEndCol; /* ending column of selection */ + HFONT hFont; /* handle of current font (if not default) */ + HANDLE hDeletedText; /* handle to deleted txet buffer for undo */ + int DeletedLength; /* length of deleted text */ + int DeletedCurrLine; /* starting line from which text was deleted */ + int DeletedCurrCol; /* starting col from which text was deleted */ } EDITSTATE; @@ -69,8 +77,8 @@ typedef struct #define EditBufLen(wndPtr) (wndPtr->dwStyle & ES_MULTILINE \ ? EDITLEN : ENTRYLEN) #define CurrChar (EDIT_TextLine(hwnd, es->CurrLine) + es->CurrCol) -#define SelMarked(es) (es->SelBegLine != -1 && es->SelBegCol != -1 && \ - es->SelEndLine != -1 && es->SelEndCol != -1) +#define SelMarked(es) (es->SelBegLine != 0 || es->SelBegCol != 0 || \ + es->SelEndLine != 0 || es->SelEndCol != 0) /* macros to access window styles */ #define IsAutoVScroll() (wndPtr->dwStyle & ES_AUTOVSCROLL) @@ -88,6 +96,7 @@ static BOOL Print = FALSE; LONG EditWndProc(HWND hWnd, WORD uMsg, WORD wParam, LONG lParam); +long EDIT_NCCreateMsg(HWND hwnd, LONG lParam); long EDIT_CreateMsg(HWND hwnd, LONG lParam); void EDIT_ClearTextPointers(HWND hwnd); void EDIT_BuildTextPointers(HWND hwnd); @@ -135,11 +144,24 @@ void EDIT_ClearSel(HWND hwnd); int EDIT_TextLineNumber(HWND hwnd, char *lp); void EDIT_SetAnchor(HWND hwnd, int row, int col); void EDIT_ExtendSel(HWND hwnd, int x, int y); +void EDIT_WriteSel(HWND hwnd, int y, int start, int end); void EDIT_StopMarking(HWND hwnd); LONG EDIT_GetLineMsg(HWND hwnd, WORD wParam, LONG lParam); LONG EDIT_GetSelMsg(HWND hwnd); +void EDIT_ReplaceSel(HWND hwnd, LONG lParam); +void EDIT_InsertText(HWND hwnd, char *str, int len); LONG EDIT_LineFromCharMsg(HWND hwnd, WORD wParam); LONG EDIT_LineIndexMsg(HWND hwnd, WORD wParam); +LONG EDIT_LineLengthMsg(HWND hwnd, WORD wParam); +void EDIT_SetFont(HWND hwnd, WORD wParam, LONG lParam); +void EDIT_SaveDeletedText(HWND hwnd, char *deltext, int len, int line, + int col); +void EDIT_ClearDeletedText(HWND hwnd); +LONG EDIT_UndoMsg(HWND hwnd); +unsigned int EDIT_TextAlloc(EDITSTATE *es, int bytes); +void *EDIT_TextAddr(EDITSTATE *es, unsigned int handle); +unsigned int EDIT_TextReAlloc(EDITSTATE *es, unsigned int handle, int bytes); +void EDIT_SetHandleMsg(HWND hwnd, WORD wParam); void swap(int *a, int *b); @@ -154,13 +176,19 @@ LONG EditWndProc(HWND hwnd, WORD uMsg, WORD wParam, LONG lParam) switch (uMsg) { case EM_CANUNDO: - /* cannot process undo message */ - lResult = 0L; + lResult = es->hDeletedText; break; + case EM_EMPTYUNDOBUFFER: + EDIT_ClearDeletedText(hwnd); + break; + case EM_FMTLINES: - printf("edit: cannot process EM_FMTLINES message\n"); - lResult = 0L; + printf("edit: EM_FMTLINES message received\n"); + if (!wParam) + lResult = 1L; + else + lResult = 0L; break; case EM_GETFIRSTVISIBLELINE: @@ -168,7 +196,7 @@ LONG EditWndProc(HWND hwnd, WORD uMsg, WORD wParam, LONG lParam) break; case EM_GETHANDLE: - printf("edit: cannot process EM_GETHANDLE message\n"); + lResult = es->hText; break; case EM_GETLINE: @@ -206,7 +234,10 @@ LONG EditWndProc(HWND hwnd, WORD uMsg, WORD wParam, LONG lParam) break; case EM_LIMITTEXT: - es->MaxTextLen = wParam; + if (wParam) + es->MaxTextLen = wParam; + else + es->MaxTextLen = 65000; break; case EM_LINEFROMCHAR: @@ -221,7 +252,7 @@ LONG EditWndProc(HWND hwnd, WORD uMsg, WORD wParam, LONG lParam) break; case EM_LINELENGTH: - printf("edit: cannot process EM_LINELENGTH message\n"); + lResult = EDIT_LineLengthMsg(hwnd, wParam); break; case EM_LINESCROLL: @@ -229,11 +260,14 @@ LONG EditWndProc(HWND hwnd, WORD uMsg, WORD wParam, LONG lParam) break; case EM_REPLACESEL: - printf("edit: cannot process EM_REPLACESEL message\n"); + HideCaret(hwnd); + EDIT_ReplaceSel(hwnd, lParam); + SetCaretPos(es->WndCol, es->WndRow * es->txtht); + ShowCaret(hwnd); break; case EM_SETHANDLE: - printf("edit: cannot process EM_SETHANDLE message\n"); + EDIT_SetHandleMsg(hwnd, wParam); break; case EM_SETMODIFY: @@ -268,6 +302,13 @@ LONG EditWndProc(HWND hwnd, WORD uMsg, WORD wParam, LONG lParam) printf("edit: cannot process EM_SETWORDBREAKPROC message\n"); break; + case EM_UNDO: + HideCaret(hwnd); + lResult = EDIT_UndoMsg(hwnd); + SetCaretPos(es->WndCol, es->WndRow * es->txtht); + ShowCaret(hwnd); + break; + case WM_CHAR: EDIT_CharMsg(hwnd, wParam); break; @@ -287,7 +328,7 @@ LONG EditWndProc(HWND hwnd, WORD uMsg, WORD wParam, LONG lParam) break; case WM_GETTEXT: - textPtr = (LPSTR)EDIT_HEAP_ADDR(es->hText); + textPtr = EDIT_TextAddr(es, es->hText); if ((int)wParam > (len = strlen(textPtr))) { strcpy((char *)lParam, textPtr); @@ -298,7 +339,7 @@ LONG EditWndProc(HWND hwnd, WORD uMsg, WORD wParam, LONG lParam) break; case WM_GETTEXTLENGTH: - textPtr = (LPSTR)EDIT_HEAP_ADDR(es->hText); + textPtr = EDIT_TextAddr(es, es->hText); lResult = (DWORD)strlen(textPtr); break; @@ -340,6 +381,10 @@ LONG EditWndProc(HWND hwnd, WORD uMsg, WORD wParam, LONG lParam) lResult = 0; break; + case WM_NCCREATE: + lResult = EDIT_NCCreateMsg(hwnd, lParam); + break; + case WM_PAINT: EDIT_PaintMsg(hwnd); break; @@ -353,6 +398,10 @@ LONG EditWndProc(HWND hwnd, WORD uMsg, WORD wParam, LONG lParam) break; case WM_SETFONT: + HideCaret(hwnd); + EDIT_SetFont(hwnd, wParam, lParam); + SetCaretPos(es->WndCol, es->WndRow * es->txtht); + ShowCaret(hwnd); break; case WM_SETTEXT: @@ -379,19 +428,17 @@ LONG EditWndProc(HWND hwnd, WORD uMsg, WORD wParam, LONG lParam) /********************************************************************* - * WM_CREATE message function + * WM_NCCREATE message function */ -long EDIT_CreateMsg(HWND hwnd, LONG lParam) +long EDIT_NCCreateMsg(HWND hwnd, LONG lParam) { - HDC hdc; + CREATESTRUCT *createStruct = (CREATESTRUCT *)lParam; WND *wndPtr = WIN_FindWndPtr(hwnd); EDITSTATE *es; - CLASS *classPtr; - short *charWidths; - TEXTMETRIC tm; - char *text; unsigned int *textPtrs; + char *text; + int len; /* allocate space for state variable structure */ (HANDLE)(*(wndPtr->wExtra)) = @@ -401,6 +448,61 @@ long EDIT_CreateMsg(HWND hwnd, LONG lParam) textPtrs = (unsigned int *)EDIT_HEAP_ADDR(es->hTextPtrs); es->hCharWidths = EDIT_HEAP_ALLOC(256 * sizeof(short)); + /* --- text buffer */ + es->localheap = &HEAP_LocalFindHeap(createStruct->hInstance)->free_list; + es->MaxTextLen = MAXTEXTLEN + 1; + if (!(es->hText)) + { + es->textlen = EditBufLen(wndPtr) + 1; + es->hText = EDIT_TextAlloc(es, EditBufLen(wndPtr) + 2); + text = EDIT_TextAddr(es, es->hText); + memset(text, 0, es->textlen + 2); + EDIT_ClearTextPointers(hwnd); + } + else + { + if (strlen(createStruct->lpszName) < EditBufLen(wndPtr)) + { + es->hText = EDIT_TextAlloc(es, EditBufLen(wndPtr) + 2); + es->textlen = EditBufLen(wndPtr) + 1; + *(text + es->textlen) = '\0'; + } + else + { + es->hText = EDIT_TextAlloc(es, strlen(createStruct->lpszName) + 2); + es->textlen = strlen(createStruct->lpszName) + 1; + } + text = EDIT_TextAddr(es, es->hText); + *(text + es->textlen + 1) = '\0'; + EDIT_BuildTextPointers(hwnd); + } + + if ((createStruct->style & WS_VSCROLL) || + (createStruct->style & WS_HSCROLL)) NC_CreateScrollBars(hwnd); + + /* remove the WS_CAPTION style if it has been set - this is really a */ + /* pseudo option made from a combination of WS_BORDER and WS_DLGFRAME */ + if (wndPtr->dwStyle & WS_BORDER && wndPtr->dwStyle & WS_DLGFRAME) + wndPtr->dwStyle ^= WS_DLGFRAME; + + return 1; +} + + +/********************************************************************* + * WM_CREATE message function + */ + +long EDIT_CreateMsg(HWND hwnd, LONG lParam) +{ + HDC hdc; + WND *wndPtr = WIN_FindWndPtr(hwnd); + EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra))); + CLASS *classPtr; + short *charWidths; + TEXTMETRIC tm; + char *text; + /* initialize state variable structure */ /* --- char width array */ hdc = GetDC(hwnd); @@ -408,24 +510,6 @@ long EDIT_CreateMsg(HWND hwnd, LONG lParam) memset(charWidths, 0, 256 * sizeof(short)); GetCharWidth(hdc, 0, 255, charWidths); - /* --- text buffer */ - es->MaxTextLen = MAXTEXTLEN + 1; - if (!(wndPtr->hText)) - { - es->textlen = EditBufLen(wndPtr); - es->hText = EDIT_HEAP_ALLOC(EditBufLen(wndPtr) + 2); - text = (LPSTR)EDIT_HEAP_ADDR(es->hText); - memset(text, 0, es->textlen + 2); - EDIT_ClearTextPointers(hwnd); - } - else - { - es->hText = wndPtr->hText; - wndPtr->hText = 0; - es->textlen = GetWindowTextLength(hwnd) + 1; - EDIT_BuildTextPointers(hwnd); - } - /* --- other structure variables */ GetTextMetrics(hdc, &tm); es->txtht = tm.tmHeight + tm.tmExternalLeading; @@ -435,8 +519,11 @@ long EDIT_CreateMsg(HWND hwnd, LONG lParam) es->WndCol = es->WndRow = 0; es->TextChanged = FALSE; es->textwidth = 0; - es->SelBegLine = es->SelBegCol = -1; - es->SelEndLine = es->SelEndCol = -1; + es->SelBegLine = es->SelBegCol = 0; + es->SelEndLine = es->SelEndCol = 0; + es->hFont = 0; + es->hDeletedText = 0; + es->DeletedLength = 0; /* allocate space for a line full of blanks to speed up */ /* line filling */ @@ -494,7 +581,7 @@ void EDIT_BuildTextPointers(HWND hwnd) short *charWidths; es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra))); - text = (char *)EDIT_HEAP_ADDR(es->hText); + text = EDIT_TextAddr(es, es->hText); textPtrs = (unsigned int *)EDIT_HEAP_ADDR(es->hTextPtrs); charWidths = (short *)EDIT_HEAP_ADDR(es->hCharWidths); @@ -627,7 +714,7 @@ char *EDIT_TextLine(HWND hwnd, int sel) { WND *wndPtr = WIN_FindWndPtr(hwnd); EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra))); - char *text = (char *)EDIT_HEAP_ADDR(es->hText); + char *text = EDIT_TextAddr(es, es->hText); unsigned int *textPtrs = (unsigned int *)EDIT_HEAP_ADDR(es->hTextPtrs); return (text + *(textPtrs + sel)); @@ -847,6 +934,7 @@ void EDIT_WriteText(HWND hwnd, char *lp, int off, int len, int row, int diff, num_spaces; HRGN hrgnClip; COLORREF oldTextColor, oldBkgdColor; + HFONT oldfont; WND *wndPtr = WIN_FindWndPtr(hwnd); EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra))); short *charWidths = (short *)EDIT_HEAP_ADDR(es->hCharWidths); @@ -861,6 +949,9 @@ void EDIT_WriteText(HWND hwnd, char *lp, int off, int len, int row, hrgnClip = CreateRectRgnIndirect(rc); SelectClipRgn(hdc, hrgnClip); + if (es->hFont) + oldfont = (HFONT)SelectObject(hdc, (HANDLE)es->hFont); + SendMessage(GetParent(hwnd), WM_CTLCOLOR, (WORD)hdc, MAKELPARAM(hwnd, CTLCOLOR_EDIT)); @@ -891,6 +982,9 @@ void EDIT_WriteText(HWND hwnd, char *lp, int off, int len, int row, } } + if (es->hFont) + SelectObject(hdc, (HANDLE)oldfont); + EDIT_HEAP_FREE(hStr); ReleaseDC(hwnd, hdc); } @@ -988,7 +1082,7 @@ void EDIT_KeyTyped(HWND hwnd, short ch) { WND *wndPtr = WIN_FindWndPtr(hwnd); EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra))); - char *text = (char *)EDIT_HEAP_ADDR(es->hText); + char *text = EDIT_TextAddr(es, es->hText); char *currchar = CurrChar; RECT rc; BOOL FullPaint = FALSE; @@ -1032,10 +1126,10 @@ void EDIT_KeyTyped(HWND hwnd, short ch) /* but not above maximum size */ if (es->textlen > es->MaxTextLen) es->textlen = es->MaxTextLen; - es->hText = EDIT_HEAP_REALLOC(es->hText, es->textlen + 2); + es->hText = EDIT_TextReAlloc(es, es->hText, es->textlen + 2); if (!es->hText) NOTIFY_PARENT(hwnd, EN_ERRSPACE); - text = (char *)EDIT_HEAP_ADDR(es->hText); + text = EDIT_TextAddr(es, es->hText); text[es->textlen - 1] = '\0'; currchar = CurrChar; } @@ -1122,7 +1216,7 @@ void EDIT_Forward(HWND hwnd) { WND *wndPtr = WIN_FindWndPtr(hwnd); EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra))); - char *text = (char *)EDIT_HEAP_ADDR(es->hText); + char *text = EDIT_TextAddr(es, es->hText); char *cc = CurrChar + 1; if (*cc == '\0') @@ -1210,7 +1304,7 @@ void EDIT_Backward(HWND hwnd) { WND *wndPtr = WIN_FindWndPtr(hwnd); EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra))); - char *text = (char *)EDIT_HEAP_ADDR(es->hText); + char *text = EDIT_TextAddr(es, es->hText); if (es->CurrCol) { @@ -1238,7 +1332,7 @@ void EDIT_End(HWND hwnd) RECT rc; WND *wndPtr = WIN_FindWndPtr(hwnd); EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra))); - char *text = (char *)EDIT_HEAP_ADDR(es->hText); + char *text = EDIT_TextAddr(es, es->hText); while (*CurrChar && *CurrChar != '\n') { @@ -1988,8 +2082,8 @@ LONG EDIT_SetTextMsg(HWND hwnd, LONG lParam) len = strlen((char *)lParam); EDIT_ClearText(hwnd); es->textlen = len; - es->hText = EDIT_HEAP_REALLOC(es->hText, len + 3); - text = EDIT_HEAP_ADDR(es->hText); + es->hText = EDIT_TextReAlloc(es, es->hText, len + 3); + text = EDIT_TextAddr(es, es->hText); strcpy(text, (char *)lParam); /* text[len] = '\n'; */ /* Removed by Bob Amstadt */ text[len + 1] = '\0'; @@ -2018,8 +2112,8 @@ void EDIT_ClearText(HWND hwnd) unsigned int blen = EditBufLen(wndPtr) + 2; char *text; - es->hText = EDIT_HEAP_REALLOC(es->hText, blen); - text = EDIT_HEAP_ADDR(es->hText); + es->hText = EDIT_TextReAlloc(es, es->hText, blen); + text = EDIT_TextAddr(es, es->hText); memset(text, 0, blen); es->textlen = 0; es->wlines = 0; @@ -2050,17 +2144,19 @@ void EDIT_SetSelMsg(HWND hwnd, LONG lParam) EDIT_GetLineCol(hwnd, so, &(es->SelBegLine), &(es->SelBegCol)); EDIT_GetLineCol(hwnd, eo, &(es->SelEndLine), &(es->SelEndCol)); - es->CurrLine = es->SelEndLine; - es->CurrCol = es->SelEndCol; - es->WndRow = es->SelEndLine - es->wtop; - if (es->WndRow < 0) + if (SelMarked(es)) { - es->wtop = es->SelEndLine; - es->WndRow = 0; + es->CurrLine = es->SelEndLine; + es->CurrCol = es->SelEndCol; + es->WndRow = es->SelEndLine - es->wtop; + if (es->WndRow < 0) + { + es->wtop = es->SelEndLine; + es->WndRow = 0; + } + es->WndCol = EDIT_LineLength(es, EDIT_TextLine(hwnd, es->SelEndLine), + es->SelEndCol) - es->wleft; } - es->WndCol = EDIT_LineLength(es, EDIT_TextLine(hwnd, es->SelEndLine), - es->SelEndCol) - es->wleft; - InvalidateRect(hwnd, NULL, TRUE); UpdateWindow(hwnd); } @@ -2078,9 +2174,17 @@ void EDIT_GetLineCol(HWND hwnd, int off, int *line, int *col) char *cp, *cp1; WND *wndPtr = WIN_FindWndPtr(hwnd); EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra))); - char *text = (char *)EDIT_HEAP_ADDR(es->hText); + char *text = EDIT_TextAddr(es, es->hText); unsigned int *textPtrs = (unsigned int *)EDIT_HEAP_ADDR(es->hTextPtrs); + /* check for (0,0) */ + if (!off) + { + *line = 0; + *col = 0; + return; + } + if (off > strlen(text)) off = strlen(text); cp1 = text; for (lineno = 0; lineno < es->wlines; lineno++) @@ -2115,13 +2219,14 @@ void EDIT_DeleteSel(HWND hwnd) int len; WND *wndPtr = WIN_FindWndPtr(hwnd); EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra))); - char *text = (char *)EDIT_HEAP_ADDR(es->hText); + char *text = EDIT_TextAddr(es, es->hText); if (SelMarked(es)) { bbl = EDIT_TextLine(hwnd, es->SelBegLine) + es->SelBegCol; bel = EDIT_TextLine(hwnd, es->SelEndLine) + es->SelEndCol; len = (int)(bel - bbl); + EDIT_SaveDeletedText(hwnd, bbl, len, es->SelBegLine, es->SelBegCol); es->TextChanged = TRUE; strcpy(bbl, bel); @@ -2154,8 +2259,8 @@ void EDIT_ClearSel(HWND hwnd) WND *wndPtr = WIN_FindWndPtr(hwnd); EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra))); - es->SelBegLine = es->SelBegCol = -1; - es->SelEndLine = es->SelEndCol = -1; + es->SelBegLine = es->SelBegCol = 0; + es->SelEndLine = es->SelEndCol = 0; InvalidateRect(hwnd, NULL, TRUE); UpdateWindow(hwnd); @@ -2175,7 +2280,7 @@ int EDIT_TextLineNumber(HWND hwnd, char *lp) char *cp; WND *wndPtr = WIN_FindWndPtr(hwnd); EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra))); - char *text = (char *)EDIT_HEAP_ADDR(es->hText); + char *text = EDIT_TextAddr(es, es->hText); unsigned int *textPtrs = (unsigned int *)EDIT_HEAP_ADDR(es->hTextPtrs); for (lineno = 0; lineno < es->wlines; lineno++) @@ -2198,14 +2303,20 @@ int EDIT_TextLineNumber(HWND hwnd, char *lp) void EDIT_SetAnchor(HWND hwnd, int row, int col) { + BOOL sel = FALSE; WND *wndPtr = WIN_FindWndPtr(hwnd); EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra))); + if (SelMarked(es)) + sel = TRUE; EDIT_ClearSel(hwnd); es->SelBegLine = es->SelEndLine = row; es->SelBegCol = es->SelEndCol = col; - InvalidateRect(hwnd, NULL, FALSE); - UpdateWindow(hwnd); + if (sel) + { + InvalidateRect(hwnd, NULL, FALSE); + UpdateWindow(hwnd); + } } @@ -2217,8 +2328,7 @@ void EDIT_SetAnchor(HWND hwnd, int row, int col) void EDIT_ExtendSel(HWND hwnd, int x, int y) { - int bbl, bel; - int ptop, pbot; + int bbl, bel, bbc, bec; char *cp, *cp1; int len; BOOL end = FALSE; @@ -2229,8 +2339,8 @@ void EDIT_ExtendSel(HWND hwnd, int x, int y) printf("EDIT_ExtendSel: x=%d, y=%d\n", x, y); #endif - ptop = min(es->SelBegLine, es->SelEndLine); - pbot = max(es->SelBegLine, es->SelEndLine); + bbl = es->SelEndLine; + bbc = es->SelEndCol; cp = EDIT_TextLine(hwnd, es->wtop + y / es->txtht); cp1 = strchr(cp, '\n'); len = cp1 ? (int)(cp1 - cp) : 0; @@ -2251,25 +2361,93 @@ void EDIT_ExtendSel(HWND hwnd, int x, int y) if (es->WndCol > EDIT_LineLength(es, cp, len) - es->wleft || end) es->WndCol = EDIT_LineLength(es, cp, len) - es->wleft; es->CurrCol = EDIT_PixelToChar(hwnd, es->CurrLine, &(es->WndCol)); - es->SelEndCol = es->CurrCol; + es->SelEndCol = es->CurrCol - 1; - bbl = min(es->SelBegLine, es->SelEndLine); - bel = max(es->SelBegLine, es->SelEndLine); - while (ptop < bbl) + bel = es->SelEndLine; + bec = es->SelEndCol; + + /* return if no new characters to mark */ + if (bbl == bel && bbc == bec) + return; + + /* put lowest marker first */ + if (bbl > bel) { - EDIT_WriteTextLine(hwnd, NULL, ptop); - ptop++; + swap(&bbl, &bel); + swap(&bbc, &bec); } + if (bbl == bel && bbc > bec) + swap(&bbc, &bec); + for (y = bbl; y <= bel; y++) - EDIT_WriteTextLine(hwnd, NULL, y); - while (pbot > bel) { - EDIT_WriteTextLine(hwnd, NULL, pbot); - --pbot; + if (y == bbl && y == bel) + EDIT_WriteSel(hwnd, y, bbc, bec); + else if (y == bbl) + EDIT_WriteSel(hwnd, y, bbc, -1); + else if (y == bel) + EDIT_WriteSel(hwnd, y, 0, bec); + else + EDIT_WriteSel(hwnd, y, 0, -1); } } +/********************************************************************* + * EDIT_WriteSel + * + * Display selection by reversing pixels in selected text. + * If end == -1, selection applies to end of line. + */ + +void EDIT_WriteSel(HWND hwnd, int y, int start, int end) +{ + RECT rc; + int scol, ecol; + char *cp, *cp1; + HDC hdc; + HBRUSH hbrush, holdbrush; + int olddm; + WND *wndPtr = WIN_FindWndPtr(hwnd); + EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra))); + +#ifdef DEBUG_EDIT + printf("EDIT_WriteSel: y=%d start=%d end=%d\n", y, start, end); +#endif + GetClientRect(hwnd, &rc); + + /* make sure y is within the window */ + if (y < es->wtop || y > (es->wtop + ClientHeight(wndPtr, es))) + return; + + /* get pointer to text */ + cp = EDIT_TextLine(hwnd, y); + + /* get length of line if end == -1 */ + if (end == -1) + { + cp1 = strchr(cp, '\n'); + end = cp1 ? (int)(cp1 - cp) : 0; + } + + scol = EDIT_LineLength(es, cp, start); + if (scol > rc.right) return; + if (scol < rc.left) scol = rc.left; + ecol = EDIT_LineLength(es, cp, end); + if (ecol < rc.left) return; + if (ecol > rc.right) ecol = rc.right; + + hdc = GetDC(hwnd); + hbrush = GetStockObject(BLACK_BRUSH); + holdbrush = (HBRUSH)SelectObject(hdc, (HANDLE)hbrush); + olddm = SetROP2(hdc, R2_XORPEN); + Rectangle(hdc, scol, y * es->txtht, ecol, (y + 1) * es->txtht); + SetROP2(hdc, olddm); + SelectObject(hdc, (HANDLE)holdbrush); + ReleaseDC(hwnd, hdc); +} + + /********************************************************************* * EDIT_StopMarking * @@ -2331,6 +2509,53 @@ LONG EDIT_GetSelMsg(HWND hwnd) } +/********************************************************************* + * EM_REPLACESEL message function + */ + +void EDIT_ReplaceSel(HWND hwnd, LONG lParam) +{ + EDIT_DeleteSel(hwnd); + EDIT_InsertText(hwnd, (char *)lParam, strlen((char *)lParam)); + InvalidateRect(hwnd, NULL, TRUE); + UpdateWindow(hwnd); +} + + +/********************************************************************* + * EDIT_InsertText + * + * Insert text at current line and column. + */ + +void EDIT_InsertText(HWND hwnd, char *str, int len) +{ + int plen; + WND *wndPtr = WIN_FindWndPtr(hwnd); + EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra))); + char *text = EDIT_TextAddr(es, es->hText); + + plen = strlen(text) + len; + if (plen + 1 > es->textlen) + { + es->hText = EDIT_TextReAlloc(es, es->hText, es->textlen + len); + es->textlen = plen + 1; + } + memmove(CurrChar + len, CurrChar, strlen(CurrChar) + 1); + memcpy(CurrChar, str, len); + + EDIT_BuildTextPointers(hwnd); + es->PaintBkgd = TRUE; + es->TextChanged = TRUE; + + EDIT_GetLineCol(hwnd, (int)((CurrChar + len) - text), &(es->CurrLine), + &(es->CurrCol)); + es->WndRow = es->CurrLine - es->wtop; + es->WndCol = EDIT_LineLength(es, EDIT_TextLine(hwnd, es->CurrLine), + es->CurrCol) - es->wleft; +} + + /********************************************************************* * EM_LINEFROMCHAR message function */ @@ -2367,6 +2592,239 @@ LONG EDIT_LineIndexMsg(HWND hwnd, WORD wParam) } +/********************************************************************* + * EM_LINELENGTH message function + */ + +LONG EDIT_LineLengthMsg(HWND hwnd, WORD wParam) +{ + int row, col, len; + int sbl, sbc, sel, sec; + WND *wndPtr = WIN_FindWndPtr(hwnd); + EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra))); + unsigned int *textPtrs = (unsigned int *)EDIT_HEAP_ADDR(es->hTextPtrs); + + if (wParam == (WORD)-1) + { + if (SelMarked(es)) + { + sbl = es->SelBegLine; + sbc = es->SelBegCol; + sel = es->SelEndLine; + sec = es->SelEndCol; + + if (sbl > sel) + { + swap(&sbl, &sel); + swap(&sbc, &sec); + } + if (sbl == sel && sbc > sec) + swap(&sbc, &sec); + + if (sbc == sel) + { + len = *(textPtrs + sbl + 1) - *(textPtrs + sbl) - 1; + return len - sec - sbc; + } + + len = *(textPtrs + sel + 1) - *(textPtrs + sel) - sec - 1; + return len + sbc; + } + else /* no selection marked */ + { + len = *(textPtrs + es->CurrLine + 1) - + *(textPtrs + es->CurrLine) - 1; + return len; + } + } + else /* line number specified */ + { + EDIT_GetLineCol(hwnd, wParam, &row, &col); + len = *(textPtrs + row + 1) - *(textPtrs + row); + return len; + } +} + + +/********************************************************************* + * WM_SETFONT message function + */ + +void EDIT_SetFont(HWND hwnd, WORD wParam, LONG lParam) +{ + HDC hdc; + TEXTMETRIC tm; + HFONT oldfont; + WND *wndPtr = WIN_FindWndPtr(hwnd); + EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra))); + short *charWidths = (short *)EDIT_HEAP_ADDR(es->hCharWidths); + + es->hFont = wParam; + hdc = GetDC(hwnd); + oldfont = (HFONT)SelectObject(hdc, (HANDLE)es->hFont); + GetCharWidth(hdc, 0, 255, charWidths); + GetTextMetrics(hdc, &tm); + es->txtht = tm.tmHeight + tm.tmExternalLeading; + SelectObject(hdc, (HANDLE)oldfont); + ReleaseDC(hwnd, hdc); + + es->WndRow = (es->CurrLine - es->wtop) / es->txtht; + es->WndCol = EDIT_LineLength(es, EDIT_TextLine(hwnd, es->CurrLine), + es->CurrCol) - es->wleft; + + InvalidateRect(hwnd, NULL, TRUE); + es->PaintBkgd = TRUE; + if (lParam) UpdateWindow(hwnd); +} + + +/********************************************************************* + * EDIT_SaveDeletedText + * + * Save deleted text in deleted text buffer. + */ + +void EDIT_SaveDeletedText(HWND hwnd, char *deltext, int len, + int line, int col) +{ + char *text; + WND *wndPtr = WIN_FindWndPtr(hwnd); + EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra))); + + es->hDeletedText = EDIT_HEAP_REALLOC(es->hDeletedText, len); + if (!es->hDeletedText) return; + text = (char *)EDIT_HEAP_ADDR(es->hDeletedText); + memcpy(text, deltext, len); + es->DeletedLength = len; + es->DeletedCurrLine = line; + es->DeletedCurrCol = col; +} + + +/********************************************************************* + * EDIT_ClearDeletedText + * + * Clear deleted text buffer. + */ + +void EDIT_ClearDeletedText(HWND hwnd) +{ + WND *wndPtr = WIN_FindWndPtr(hwnd); + EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra))); + + EDIT_HEAP_FREE(es->hDeletedText); + es->hDeletedText = 0; + es->DeletedLength = 0; +} + + +/********************************************************************* + * EM_UNDO message function + */ + +LONG EDIT_UndoMsg(HWND hwnd) +{ + char *text; + WND *wndPtr = WIN_FindWndPtr(hwnd); + EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra))); + + if (es->hDeletedText) + { + text = (char *)EDIT_HEAP_ADDR(es->hDeletedText); + es->CurrLine = es->DeletedCurrLine; + es->CurrCol = es->DeletedCurrCol; + EDIT_InsertText(hwnd, text, es->DeletedLength); + EDIT_ClearDeletedText(hwnd); + + es->SelBegLine = es->CurrLine; + es->SelBegCol = es->CurrCol; + EDIT_GetLineCol(hwnd, (int)((CurrChar + es->DeletedLength) - text), + &(es->CurrLine), &(es->CurrCol)); + es->WndRow = es->CurrLine - es->wtop; + es->WndCol = EDIT_LineLength(es, EDIT_TextLine(hwnd, es->CurrLine), + es->CurrCol) - es->wleft; + es->SelEndLine = es->CurrLine; + es->SelEndCol = es->CurrCol; + + InvalidateRect(hwnd, NULL, TRUE); + UpdateWindow(hwnd); + return 1; + } + else + return 0; +} + + +/********************************************************************* + * EDIT_TextAlloc + * + * Allocate the text buffer. + */ + +unsigned int EDIT_TextAlloc(EDITSTATE *es, int bytes) +{ + return ((unsigned int)HEAP_Alloc(es->localheap, GMEM_MOVEABLE, + bytes) & 0xffff); +} + + +/********************************************************************* + * EDIT_TextAddr + * + * Return the address of the text buffer. + */ + +void *EDIT_TextAddr(EDITSTATE *es, unsigned int handle) +{ + return ((void *)((handle) ? ((handle) | ((unsigned int)(*(es->localheap)) + & 0xffff0000)) : 0)); +} + + +/********************************************************************* + * EDIT_TextReAlloc + * + * Reallocate the text buffer. + */ + +unsigned int EDIT_TextReAlloc(EDITSTATE *es, unsigned int handle, int bytes) +{ + return ((unsigned int)HEAP_ReAlloc(es->localheap, + EDIT_TextAddr(es, handle), + bytes, GMEM_MOVEABLE) & 0xffff); +} + + +/********************************************************************* + * EM_SETHANDLE message function + */ + +void EDIT_SetHandleMsg(HWND hwnd, WORD wParam) +{ + MDESC *m; + WND *wndPtr = WIN_FindWndPtr(hwnd); + EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra))); + + if (IsMultiLine()) + { + es->hText = wParam; + es->MaxTextLen = HEAP_LocalSize(es->localheap, es->hText); + es->wlines = 0; + es->wtop = es->wleft = 0; + es->CurrLine = es->CurrCol = 0; + es->WndRow = es->WndCol = 0; + es->TextChanged = FALSE; + es->textwidth = 0; + es->SelBegLine = es->SelBegCol = 0; + es->SelEndLine = es->SelEndCol = 0; + + es->PaintBkgd = TRUE; + InvalidateRect(hwnd, NULL, TRUE); + UpdateWindow(hwnd); + } +} + + /********************************************************************* * Utility functions */ diff --git a/controls/menu.c b/controls/menu.c index 58a98654030..7b05747dd8b 100644 --- a/controls/menu.c +++ b/controls/menu.c @@ -37,6 +37,8 @@ void MenuButtonUp(HWND hWnd, LPPOPUPMENU lppop, int x, int y); void MenuMouseMove(HWND hWnd, LPPOPUPMENU lppop, WORD wParam, int x, int y); void StdDrawPopupMenu(HWND hwnd); void ResetHiliteFlags(LPPOPUPMENU lppop); +void SelectPrevItem(LPPOPUPMENU lppop); +void SelectNextItem(LPPOPUPMENU lppop); BOOL ExecFocusedMenuItem(HWND hWnd, LPPOPUPMENU lppop); void MenuItemSelect(HWND hWnd, LPPOPUPMENU lppop, WORD wIndex); LPMENUITEM MenuFindItem(LPPOPUPMENU lppop, int x, int y, WORD *lpRet); @@ -60,6 +62,8 @@ BOOL FAR PASCAL AboutWine_Proc(HWND hDlg, WORD msg, WORD wParam, LONG lParam); /*********************************************************************** * PopupMenuWndProc + SetWindow + SetWindow */ LONG PopupMenuWndProc( HWND hwnd, WORD message, WORD wParam, LONG lParam ) { @@ -90,6 +94,7 @@ LONG PopupMenuWndProc( HWND hwnd, WORD message, WORD wParam, LONG lParam ) #ifdef DEBUG_MENU printf("PopupMenu End of WM_CREATE !\n"); #endif + ResetHiliteFlags(lppop); return 0; case WM_DESTROY: lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr); @@ -132,6 +137,7 @@ LONG PopupMenuWndProc( HWND hwnd, WORD message, WORD wParam, LONG lParam ) lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr); if (lppop == NULL) break; if (wParam == 0 && lParam == 0L) { + ResetHiliteFlags(lppop); HideAllSubPopupMenu(lppop); #ifdef DEBUG_MENU printf("PopupMenuWndProc hWnd=%04X WM_SHOWWINDOW -> HIDE!\n", hwnd); @@ -144,7 +150,7 @@ LONG PopupMenuWndProc( HWND hwnd, WORD message, WORD wParam, LONG lParam ) lppop->FocusedItem = (WORD)-1; if (!lppop->BarFlag) { PopupMenuCalcSize(hwnd); - ResetHiliteFlags(lppop); +/* ResetHiliteFlags(lppop); */ #ifdef DEBUG_MENU printf("PopupMenuWndProc hWnd=%04X WM_SHOWWINDOW Width=%d Height=%d !\n", hwnd, lppop->Width, lppop->Height); @@ -195,17 +201,11 @@ LONG PopupMenuWndProc( HWND hwnd, WORD message, WORD wParam, LONG lParam ) break; case VK_UP: if (lppop->BarFlag) break; - if (lppop->FocusedItem < 1) break; - MenuItemSelect(hwnd, lppop, lppop->FocusedItem - 1); + SelectPrevItem(lppop); break; case VK_DOWN: if (lppop->BarFlag) goto ProceedSPACE; - if (lppop->FocusedItem == (WORD)-1) { - MenuItemSelect(hwnd, lppop, lppop->FocusedItem + 1); - break; - } - if (lppop->FocusedItem >= lppop->nItems - 1) break; - MenuItemSelect(hwnd, lppop, lppop->FocusedItem + 1); + SelectNextItem(lppop); break; case VK_LEFT: if (lppop->SysFlag != 0) { @@ -564,6 +564,53 @@ void MenuMouseMove(HWND hWnd, LPPOPUPMENU lppop, WORD wParam, int x, int y) } +void SelectPrevItem(LPPOPUPMENU lppop) +{ + int nIndex; + LPMENUITEM lpitem; + if (lppop == NULL) return; + nIndex = lppop->FocusedItem; + if (nIndex < 1) { + if (nIndex == -1) + nIndex = 0; + else + nIndex = lppop->nItems - 1; + lpitem = GetMenuItemPtr(lppop, nIndex); + } + else { + nIndex--; + lpitem = GetMenuItemPtr(lppop, nIndex); + } + while (lpitem != NULL && lpitem->item_flags & MF_HILITE) { + nIndex--; + lpitem = GetMenuItemPtr(lppop, nIndex); + } + MenuItemSelect(lppop->hWnd, lppop, nIndex); +} + + +void SelectNextItem(LPPOPUPMENU lppop) +{ + int nIndex; + LPMENUITEM lpitem; + if (lppop == NULL) return; + nIndex = lppop->FocusedItem; + if ((nIndex == -1) || (nIndex >= lppop->nItems - 1)) { + nIndex = 0; + lpitem = GetMenuItemPtr(lppop, nIndex); + } + else { + nIndex++; + lpitem = GetMenuItemPtr(lppop, nIndex); + } + while (lpitem != NULL && (lpitem->item_flags & MF_SEPARATOR)) { + nIndex++; + lpitem = GetMenuItemPtr(lppop, nIndex); + } + MenuItemSelect(lppop->hWnd, lppop, nIndex); +} + + void ResetHiliteFlags(LPPOPUPMENU lppop) { LPMENUITEM lpitem; @@ -2162,7 +2209,8 @@ BOOL SetMenu(HWND hWnd, HMENU hMenu) if (GetCapture() == hWnd) ReleaseCapture(); if (wndPtr->window != 0) { flags = SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED; - if (!IsWindowVisible(hWnd)) flags |= SWP_NOREDRAW; +/* if (!IsWindowVisible(hWnd)) flags |= SWP_NOREDRAW; */ + flags |= SWP_NOREDRAW; if (hMenu == 0) { wndPtr->wIDmenu = hMenu; printf("SetMenu(%04X, %04X) // Menu removed, need NC recalc!\n", hWnd, hMenu); @@ -2241,7 +2289,7 @@ void DrawMenuBar(HWND hWnd) int oldHeight; oldHeight = lppop->Height; hDC = GetWindowDC(hWnd); - StdDrawMenuBar(hDC, &lppop->rect, lppop, FALSE); + StdDrawMenuBar(hDC, &lppop->rect, lppop, TRUE); ReleaseDC(hWnd, hDC); if (oldHeight != lppop->Height) { printf("DrawMenuBar // menubar changed oldHeight=%d != lppop->Height=%d\n", @@ -2251,6 +2299,8 @@ void DrawMenuBar(HWND hWnd) wndPtr->rectClient.top += lppop->Height; SendMessage(hWnd, WM_NCPAINT, 1, 0L); } + else + StdDrawMenuBar(hDC, &lppop->rect, lppop, FALSE); } else SendMessage(hWnd, WM_NCPAINT, 1, 0L); diff --git a/if1632/call.S b/if1632/call.S index 7210e686152..7c42967103e 100644 --- a/if1632/call.S +++ b/if1632/call.S @@ -105,7 +105,7 @@ _CallToInit16: movw $UDATASEL,%ax movw %ax,%fs movw %ax,%gs -/* movw %ds,%ax */ + movw %ds,%ax /* * Call entry point diff --git a/if1632/kernel.spec b/if1632/kernel.spec index 668b05a5524..4cba3a68bb6 100644 --- a/if1632/kernel.spec +++ b/if1632/kernel.spec @@ -44,7 +44,7 @@ length 415 #41 ENABLEDOS #42 DISABLEDOS 45 pascal LoadModule(ptr ptr) LoadModule(1 2) -#46 FREEMODULE +46 pascal FreeModule(word) FreeLibrary(1) 47 pascal GetModuleHandle(ptr) GetModuleHandle(1) 48 pascal GetModuleUsage(word) GetModuleUsage(1) 49 pascal GetModuleFileName(word ptr s_word) GetModuleFileName(1 2 3) @@ -63,8 +63,8 @@ length 415 62 pascal LockResource(word) LockResource(1) 63 pascal FreeResource(word) FreeResource(1) 64 pascal AccessResource(word word) AccessResource(1 2) -#65 SIZEOFRESOURCE -#66 ALLOCRESOURCE +65 pascal SizeofResource(word word) SizeofResource(1 2) +66 pascal AllocResource(word word long) AllocResource(1 2 3) #67 SETRESOURCEHANDLER 68 pascal InitAtomTable(word) InitAtomTable(1) 69 pascal FindAtom(ptr) FindAtom(1) diff --git a/if1632/mmsystem.spec b/if1632/mmsystem.spec index df33e6db6ff..d599d196c4e 100644 --- a/if1632/mmsystem.spec +++ b/if1632/mmsystem.spec @@ -82,6 +82,13 @@ length 1226 511 pascal WAVEINRESET(word) waveInReset(1) 512 pascal WAVEINGETPOSITION(word ptr word) waveInGetPosition(1 2 3) 513 pascal WAVEINGETID(word ptr) waveInGetID(1 2) +601 pascal timeGetSystemTime(ptr word) timeGetSystemTime(1 2) +602 pascal timeSetEvent(word word ptr long word) timeSetEvent(1 2 3 4 5) +603 pascal timeKillEvent(word) timeKillEvent(1) +604 pascal timeGetDevCaps(ptr word) timeGetDevCaps(1 2) +605 pascal timeBeginPeriod(word) timeBeginPeriod(1) +606 pascal timeEndPeriod(word) timeEndPeriod(1) +607 pascal timeGetTime() timeGetTime() 701 pascal MCISENDCOMMAND(word word long long) mciSendCommand(1 2 3 4) 702 pascal MCISENDSTRING(ptr ptr word word) mciSendString(1 2 3 4) 703 pascal MCIGETDEVICEID(ptr) mciSendCommand(1) diff --git a/include/accel.h b/include/accel.h index 6ea4084d75c..59fdbd870ba 100644 --- a/include/accel.h +++ b/include/accel.h @@ -19,4 +19,5 @@ typedef struct { #define VIRTKEY_ACCEL 0x01 #define SHIFT_ACCEL 0x04 #define CONTROL_ACCEL 0x08 +#define ALT_ACCEL 0x10 #define SYSTEM_ACCEL 0x80 diff --git a/include/heap.h b/include/heap.h index 7c389f1c032..7ff97a09c1b 100644 --- a/include/heap.h +++ b/include/heap.h @@ -36,6 +36,7 @@ extern int HEAP_Free(MDESC **free_list, void *block); extern void *HEAP_ReAlloc(MDESC **free_list, void *old_block, int new_size, unsigned int flags); extern LHEAP *HEAP_LocalFindHeap(unsigned short owner); +extern unsigned int HEAP_LocalSize(MDESC **free_list, unsigned int handle); #define HEAP_OWNER (Segments[Stack16Frame[11] >> 3].owner) #define LOCALHEAP() (&HEAP_LocalFindHeap(HEAP_OWNER)->free_list) diff --git a/include/metafile.h b/include/metafile.h index a3cd796d7a5..2c56e3427f2 100644 --- a/include/metafile.h +++ b/include/metafile.h @@ -41,8 +41,14 @@ BOOL MF_MetaParam8(DC *dc, short func, short param1, short param2, BOOL MF_CreateBrushIndirect(DC *dc, HBRUSH hBrush, LOGBRUSH *logbrush); BOOL MF_CreatePatternBrush(DC *dc, HBRUSH hBrush, LOGBRUSH *logbrush); BOOL MF_CreatePenIndirect(DC *dc, HPEN hPen, LOGPEN *logpen); +BOOL MF_CreateFontIndirect(DC *dc, HFONT hFont, LOGFONT *logfont); BOOL MF_TextOut(DC *dc, short x, short y, LPSTR str, short count); BOOL MF_MetaPoly(DC *dc, short func, LPPOINT pt, short count); +BOOL MF_BitBlt(DC *dcDest, short xDest, short yDest, short width, + short height, HDC hdcSrc, short xSrc, short ySrc, DWORD rop); +BOOL MF_StretchBlt(DC *dcDest, short xDest, short yDest, short widthDest, + short heightDest, HDC hdcSrc, short xSrc, short ySrc, + short widthSrc, short heightSrc, DWORD rop); #endif /* METAFILE_H */ diff --git a/include/win.h b/include/win.h index 192863269cb..1c3fcc800a3 100644 --- a/include/win.h +++ b/include/win.h @@ -49,6 +49,9 @@ typedef struct tagWND HANDLE hText; /* Handle of window text */ WORD flags; /* Misc. flags (see below) */ Window window; /* X window */ + Window icon; /* icon's X window */ + HICON hIcon; /* icon's MS-windows handle */ + RECT rectClientSave; /* where client rect is saved when icon*/ HMENU hSysMenu; /* window's copy of System Menu */ HANDLE hProp; /* Handle of Properties List */ HTASK hTask; /* Task Handle of the owner */ diff --git a/loader/library.c b/loader/library.c index 21898e927f3..8253cb53438 100644 --- a/loader/library.c +++ b/loader/library.c @@ -6,8 +6,6 @@ static char Copyright[] = "Copyright Martin Ayotte, 1994"; /* #define DEBUG_MODULE */ - -#ifndef WINELIB #include #include #include @@ -15,9 +13,9 @@ static char Copyright[] = "Copyright Martin Ayotte, 1994"; #include #include #include +#include "wine.h" #include "prototypes.h" #include "windows.h" -#include "wine.h" #include "dlls.h" #include "task.h" #include "toolhelp.h" @@ -316,8 +314,6 @@ FARPROC GetProcAddress(HANDLE hModule, char *proc_name) return (FARPROC) ret; } -#endif /* ifndef WINELIB */ - /* internal dlls */ static void FillModStructBuiltIn(MODULEENTRY *lpModule, struct dll_name_table_entry_s *dll) @@ -412,3 +408,4 @@ HMODULE ModuleFindName(MODULEENTRY *lpModule, LPCSTR lpstrName) { return (ModuleFindHandle(lpModule, GetModuleHandle((char*)lpstrName))); } + diff --git a/loader/main.c b/loader/main.c index 90ec7e516d9..8161854eb72 100644 --- a/loader/main.c +++ b/loader/main.c @@ -92,6 +92,7 @@ GetFileInfo(unsigned short instance) return w; } +#ifndef WINELIB /********************************************************************** * * Load MZ Header @@ -104,6 +105,7 @@ void load_mz_header(int fd, struct mz_header_s *mz_header) myerror("Unable to read MZ header from file"); } } +#endif int IsDLLLoaded(char *name) { @@ -233,7 +235,6 @@ HINSTANCE LoadImage(char *module, int filetype, int change_dir) return 14; } - #ifndef WINELIB /********************************************************************** * main @@ -395,4 +396,4 @@ void InitializeLoadedDLLs(struct w_files *wpnt) for( ; wpnt != final_wpnt; wpnt = wpnt->next) InitDLL(wpnt); } -#endif +#endif /* #ifndef WINELIB */ diff --git a/loader/resource.c b/loader/resource.c index 902242f221b..7814e66b27e 100644 --- a/loader/resource.c +++ b/loader/resource.c @@ -344,7 +344,7 @@ FindResourceByNumber(struct resource_nameinfo_s *result_p, } #ifdef DEBUG_RESOURCE printf("FindResource: search type=%X id=%X // type=%X id=%X\n", - type_id, resource_id, typeinfo.type_id, type_id2); + type_id, resource_id, typeinfo.type_id, nameinfo.id); #endif if (nameinfo.id == resource_id) { memcpy(result_p, &nameinfo, sizeof(nameinfo)); @@ -478,6 +478,60 @@ FindResourceByName(struct resource_nameinfo_s *result_p, } +/********************************************************************** + * GetRsrcCount [internal] + */ +int GetRsrcCount(HINSTANCE hInst, int type_id) +{ + struct resource_typeinfo_s typeinfo; + struct resource_nameinfo_s nameinfo; + unsigned short size_shift; +/* off_t old_pos, new_pos; + unsigned char nbytes; + char name[256]; */ + int i; + off_t rtoff; + if (hInst == 0) return 0; +#ifdef DEBUG_RESOURCE + printf("GetRsrcCount hInst=%04X typename=%08X\n", hInst, type_name); +#endif + if (OpenResourceFile(hInst) < 0) return 0; + + /* + * Move to beginning of resource table. + */ + rtoff = (ResourceFileInfo->mz_header->ne_offset + + ResourceFileInfo->ne_header->resource_tab_offset); + lseek(ResourceFd, rtoff, SEEK_SET); + /* + * Read block size. + */ + if (read(ResourceFd, &size_shift, sizeof(size_shift)) != sizeof(size_shift)) { + printf("GetRsrcCount // bad block size !\n"); + return -1; + } + size_shift = CONV_SHORT (size_shift); + for (;;) { + if (!load_typeinfo (ResourceFd, &typeinfo)) { + printf("GetRsrcCount // bad typeinfo size !\n"); + return 0; + } +#ifdef DEBUG_RESOURCE + printf("GetRsrcCount // typeinfo.type_id=%X count=%d type_id=%X\n", + typeinfo.type_id, typeinfo.count, type_id); +#endif + if (typeinfo.type_id == 0) break; + if (type_match(type_id, typeinfo.type_id, ResourceFd, rtoff)) { + return typeinfo.count; + } + else { + lseek(ResourceFd, (typeinfo.count * sizeof(nameinfo)), SEEK_CUR); + } + } + return 0; +} + + /********************************************************************** * LoadIcon [USER.174] */ @@ -685,12 +739,26 @@ int TranslateAccelerator(HWND hWnd, HANDLE hAccel, LPMSG msg) #endif lpAccelTbl = (LPACCELHEADER)GlobalLock(hAccel); for (i = 0; i < lpAccelTbl->wCount; i++) { -/* if (lpAccelTbl->tbl[i].type & SHIFT_ACCEL) { */ -/* if (lpAccelTbl->tbl[i].type & CONTROL_ACCEL) { */ if (lpAccelTbl->tbl[i].type & VIRTKEY_ACCEL) { if (msg->wParam == lpAccelTbl->tbl[i].wEvent && msg->message == WM_KEYDOWN) { + if ((lpAccelTbl->tbl[i].type & SHIFT_ACCEL) && + !(GetKeyState(VK_SHIFT) & 0xf)) { + GlobalUnlock(hAccel); + return 0; + } + if ((lpAccelTbl->tbl[i].type & CONTROL_ACCEL) && + !(GetKeyState(VK_CONTROL) & 0xf)) { + GlobalUnlock(hAccel); + return 0; + } + if ((lpAccelTbl->tbl[i].type & ALT_ACCEL) && + !(GetKeyState(VK_MENU) & 0xf)) { + GlobalUnlock(hAccel); + return 0; + } SendMessage(hWnd, WM_COMMAND, lpAccelTbl->tbl[i].wIDval, 0x00010000L); + GlobalUnlock(hAccel); return 1; } if (msg->message == WM_KEYUP) return 1; @@ -699,6 +767,7 @@ int TranslateAccelerator(HWND hWnd, HANDLE hAccel, LPMSG msg) if (msg->wParam == lpAccelTbl->tbl[i].wEvent && msg->message == WM_CHAR) { SendMessage(hWnd, WM_COMMAND, lpAccelTbl->tbl[i].wIDval, 0x00010000L); + GlobalUnlock(hAccel); return 1; } } @@ -773,6 +842,8 @@ HANDLE FindResource(HANDLE instance, LPSTR resource_name, LPSTR type_name) if (r->size_shift == -1) { + printf("FindResource hInst=%04X typename=%08X resname=%08X not found!\n", + instance, type_name, resource_name); GlobalFree(rh); return 0; } @@ -780,6 +851,36 @@ HANDLE FindResource(HANDLE instance, LPSTR resource_name, LPSTR type_name) return rh; } +/********************************************************************** + * AllocResource [KERNEL.66] + */ +HANDLE AllocResource(HANDLE instance, HANDLE hResInfo, DWORD dwSize) +{ + RESOURCE *r; + int image_size; + + if (instance == 0) + return 0; + + if (OpenResourceFile(instance) < 0) + return 0; + + r = (RESOURCE *)GlobalLock(hResInfo); + if (r == NULL) + return 0; + + image_size = r->nameinfo.length << r->size_shift; + + if (dwSize == 0) + r->rsc_mem = GlobalAlloc(GMEM_MOVEABLE, image_size); + else + r->rsc_mem = GlobalAlloc(GMEM_MOVEABLE, dwSize); + + GlobalUnlock(hResInfo); + + return r->rsc_mem; +} + /********************************************************************** * LoadResource [KERNEL.61] */ @@ -851,24 +952,62 @@ HANDLE FreeResource(HANDLE hResData) return hResData; } - + /********************************************************************** * AccessResource [KERNEL.64] */ int AccessResource(HANDLE instance, HANDLE hResInfo) { - int resfile; -#ifdef DEBUG_RESOURCE + int resfile, image_size; + RESOURCE *r; + +/* #ifdef DEBUG_RESOURCE */ printf("AccessResource(%04X, %04X);\n", instance, hResInfo); -#endif -/* - resfile = OpenResourceFile(instance); +/* #endif */ + + if (instance == 0) + return -1; + + if ((resfile = OpenResourceFile(instance)) < 0) + return -1; + + if ((r = (RESOURCE *)GlobalLock(hResInfo)) == NULL) + return -1; + + lseek(resfile, ((int) r->nameinfo.offset << r->size_shift), SEEK_SET); + GlobalUnlock(hResInfo); + return resfile; -*/ - return - 1; } + +/********************************************************************** + * SizeofResource [KERNEL.65] + */ +WORD SizeofResource(HANDLE instance, HANDLE hResInfo) +{ + int image_size; + RESOURCE *r; +/* #ifdef DEBUG_RESOURCE */ + printf("SizeofResource(%04X, %04X);\n", instance, hResInfo); +/* #endif */ + if (instance == 0) + return 0; + + if ((r = (RESOURCE *)GlobalLock(hResInfo)) == NULL) + return 0; + + image_size = r->nameinfo.length << r->size_shift; + + GlobalUnlock(hResInfo); + +/* #ifdef DEBUG_RESOURCE */ + printf("SizeofResource return %d\n", image_size); +/* #endif */ + + return image_size; +} /********************************************************************** * RSC_LoadResource diff --git a/memory/heap.c b/memory/heap.c index 734520a8f16..be39fe0c0a3 100644 --- a/memory/heap.c +++ b/memory/heap.c @@ -195,13 +195,14 @@ HEAP_ReAlloc(MDESC **free_list, void *old_block, m_free->next->prev = m_free->prev; m->length += sizeof(MDESC) + m_free->length; + #ifdef DEBUG_HEAP printf("HEAP_ReAlloc before GLOBAL_FLAGS_ZEROINIT !\n"); #endif if (flags & GLOBAL_FLAGS_ZEROINIT) memset(m_free, '\0', sizeof(MDESC) + m_free->length); } - + /* * Check for shrink block. */ @@ -399,6 +400,22 @@ HEAP_LocalInit(unsigned short owner, void *start, int length) LocalHeaps = lh; } +/********************************************************************** + * HEAP_LocalSize + */ +unsigned int +HEAP_LocalSize(MDESC **free_list, unsigned int handle) +{ + MDESC *m; + + m = (MDESC *) (((int) *free_list & 0xffff0000) | + (handle & 0xffff)) - 1; + if (m->next != m || m->prev != m) + return 0; + + return m->length; +} + /********************************************************************** * WIN16_LocalAlloc */ diff --git a/misc/main.c b/misc/main.c index ae0d5c9f686..f238568d376 100644 --- a/misc/main.c +++ b/misc/main.c @@ -22,7 +22,16 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1994"; #define WINE_CLASS "Wine" /* Class name for resources */ -LPSTR lpEnvList; +typedef struct tagENVENTRY { + LPSTR Name; + LPSTR Value; + WORD wSize; + struct tagENVENTRY *Prev; + struct tagENVENTRY *Next; + } ENVENTRY; +typedef ENVENTRY *LPENVENTRY; + +LPENVENTRY lpEnvList = NULL; Display * XT_display; /* To be removed */ @@ -400,9 +409,10 @@ int main( int argc, char *argv[] ) MAIN_SaveSetup(); DOS_InitFS(); Comm_Init(); +#ifndef WINELIB INT21_Init(); - -#ifndef sunos +#endif +#ifndef sparc atexit(called_at_exit); #else on_exit (called_at_exit, 0); @@ -442,9 +452,66 @@ LONG GetWinFlags(void) */ int SetEnvironment(LPSTR lpPortName, LPSTR lpEnviron, WORD nCount) { - printf("EMPTY STUB ! // SetEnvironnement('%s', '%s', %d) !\n", - lpPortName, lpEnviron, nCount); - return 0; + LPENVENTRY lpNewEnv; + LPENVENTRY lpEnv = lpEnvList; + printf("SetEnvironnement('%s', '%s', %d) !\n", + lpPortName, lpEnviron, nCount); + if (lpPortName == NULL) return -1; + while (lpEnv != NULL) { + if (lpEnv->Name != NULL && strcmp(lpEnv->Name, lpPortName) == 0) { + if (nCount == 0 || lpEnviron == NULL) { + if (lpEnv->Prev != NULL) lpEnv->Prev->Next = lpEnv->Next; + if (lpEnv->Next != NULL) lpEnv->Next->Prev = lpEnv->Prev; + free(lpEnv->Value); + free(lpEnv->Name); + free(lpEnv); + printf("SetEnvironnement() // entry deleted !\n"); + return -1; + } + free(lpEnv->Value); + lpEnv->Value = malloc(nCount); + if (lpNewEnv->Value == NULL) { + printf("SetEnvironment() // Error allocating entry value !\n"); + return 0; + } + memcpy(lpEnv->Value, lpEnviron, nCount); + lpEnv->wSize = nCount; + printf("SetEnvironnement() // entry modified !\n"); + return nCount; + } + if (lpEnv->Next == NULL) break; + lpEnv = lpEnv->Next; + } + if (nCount == 0 || lpEnviron == NULL) return -1; + printf("SetEnvironnement() // new entry !\n"); + lpNewEnv = malloc(sizeof(ENVENTRY)); + if (lpNewEnv == NULL) { + printf("SetEnvironment() // Error allocating new entry !\n"); + return 0; + } + if (lpEnvList == NULL) { + lpEnvList = lpNewEnv; + lpNewEnv->Prev = NULL; + } + else { + lpEnv->Next = lpNewEnv; + lpNewEnv->Prev = lpEnv; + } + lpNewEnv->Next = NULL; + lpNewEnv->Name = malloc(strlen(lpPortName) + 1); + if (lpNewEnv->Name == NULL) { + printf("SetEnvironment() // Error allocating entry name !\n"); + return 0; + } + strcpy(lpNewEnv->Name, lpPortName); + lpNewEnv->Value = malloc(nCount); + if (lpNewEnv->Value == NULL) { + printf("SetEnvironment() // Error allocating entry value !\n"); + return 0; + } + memcpy(lpNewEnv->Value, lpEnviron, nCount); + lpNewEnv->wSize = nCount; + return nCount; } /*********************************************************************** @@ -452,8 +519,20 @@ int SetEnvironment(LPSTR lpPortName, LPSTR lpEnviron, WORD nCount) */ int GetEnvironment(LPSTR lpPortName, LPSTR lpEnviron, WORD nMaxSiz) { - printf("EMPTY STUB ! // GetEnvironnement('%s', '%s', %d) !\n", - lpPortName, lpEnviron, nMaxSiz); + WORD nCount; + LPENVENTRY lpEnv = lpEnvList; + printf("GetEnvironnement('%s', '%s', %d) !\n", + lpPortName, lpEnviron, nMaxSiz); + while (lpEnv != NULL) { + if (lpEnv->Name != NULL && strcmp(lpEnv->Name, lpPortName) == 0) { + nCount = min(nMaxSiz, lpEnv->wSize); + memcpy(lpEnviron, lpEnv->Value, nCount); + printf("GetEnvironnement() // found '%s' !\n", lpEnviron); + return nCount; + } + lpEnv = lpEnv->Next; + } + printf("GetEnvironnement() // not found !\n"); return 0; } diff --git a/misc/mmsystem.c b/misc/mmsystem.c index 6e22c5cda77..90fc2de9b9e 100644 --- a/misc/mmsystem.c +++ b/misc/mmsystem.c @@ -12,7 +12,24 @@ static char Copyright[] = "Copyright Martin Ayotte, 1993"; #include "mmsystem.h" static WORD mciActiveDev = 0; +static BOOL mmTimeStarted = FALSE; +static MMTIME mmSysTimeMS; +static MMTIME mmSysTimeSMPTE; +typedef struct tagTIMERENTRY { + WORD wDelay; + WORD wResol; + FARPROC lpFunc; + DWORD dwUser; + WORD wFlags; + WORD wTimerID; + WORD wCurTime; + struct tagTIMERENTRY *Next; + struct tagTIMERENTRY *Prev; + } TIMERENTRY; +typedef TIMERENTRY *LPTIMERENTRY; + +static LPTIMERENTRY lpTimerList = NULL; UINT WINAPI midiGetErrorText(UINT uError, LPSTR lpText, UINT uSize); UINT WINAPI waveGetErrorText(UINT uError, LPSTR lpText, UINT uSize); @@ -1451,6 +1468,160 @@ DWORD WINAPI waveInMessage(HWAVEIN hWaveIn, UINT uMessage, } +/************************************************************************** +* MMSysTimeCallback [internal] +*/ +WORD FAR PASCAL MMSysTimeCallback(HWND hWnd, WORD wMsg, int nID, DWORD dwTime) +{ + LPTIMERENTRY lpTimer = lpTimerList; + mmSysTimeMS.u.ms += 33; + mmSysTimeSMPTE.u.smpte.frame++; + while (lpTimer != NULL) { + lpTimer->wCurTime--; + if (lpTimer->wCurTime == 0) { + lpTimer->wCurTime = lpTimer->wDelay; + if (lpTimer->lpFunc != NULL) { +#ifdef WINELIB + (*lpTimer->lpFunc)(lpTimer->wTimerID, (WORD)0, + lpTimer->dwUser, (DWORD)0, (DWORD)0); +#else + CallBack16(lpTimer->lpFunc, 5, + 0, (int)lpTimer->wTimerID, 0, (int)0, + 2, lpTimer->dwUser, 2, 0, 2, 0); +#endif + } + if (lpTimer->wFlags & TIME_ONESHOT) + timeKillEvent(lpTimer->wTimerID); + } + lpTimer = lpTimer->Next; + } +} + +/************************************************************************** +* StartMMTime [internal] +*/ +void StartMMTime() +{ + if (!mmTimeStarted) { + mmTimeStarted = TRUE; + mmSysTimeMS.wType = TIME_MS; + mmSysTimeMS.u.ms = 0; + mmSysTimeSMPTE.wType = TIME_SMPTE; + mmSysTimeSMPTE.u.smpte.hour = 0; + mmSysTimeSMPTE.u.smpte.min = 0; + mmSysTimeSMPTE.u.smpte.sec = 0; + mmSysTimeSMPTE.u.smpte.frame = 0; + mmSysTimeSMPTE.u.smpte.fps = 0; + mmSysTimeSMPTE.u.smpte.dummy = 0; + SetTimer(0, 1, 33, (FARPROC)MMSysTimeCallback); + } +} + +/************************************************************************** +* timeGetSystemTime [MMSYSTEM.601] +*/ +WORD timeGetSystemTime(LPMMTIME lpTime, WORD wSize) +{ + printf("timeGetSystemTime(%08X, %u);\n", lpTime, wSize); + if (!mmTimeStarted) StartMMTime(); + return 0; +} + +/************************************************************************** +* timeSetEvent [MMSYSTEM.602] +*/ +WORD timeSetEvent(WORD wDelay, WORD wResol, + LPTIMECALLBACK lpFunc, + DWORD dwUser, WORD wFlags) +{ + WORD wNewID = 0; + LPTIMERENTRY lpNewTimer; + LPTIMERENTRY lpTimer = lpTimerList; + printf("timeSetEvent(%u, %u, %08X, %08X, %04X);\n", + wDelay, wResol, lpFunc, dwUser, wFlags); + if (!mmTimeStarted) StartMMTime(); + lpNewTimer = malloc(sizeof(TIMERENTRY)); + if (lpNewTimer == NULL) return 0; + while (lpTimer != NULL) { + wNewID = max(wNewID, lpTimer->wTimerID); + if (lpTimer->Next == NULL) break; + lpTimer = lpTimer->Next; + } + if (lpTimerList == NULL) { + lpTimerList = lpNewTimer; + lpNewTimer->Prev == NULL; + } + else { + lpTimer->Next == lpNewTimer; + lpNewTimer->Prev == lpTimer; + } + lpNewTimer->Next == NULL; + lpNewTimer->wTimerID = wNewID + 1; + lpNewTimer->wCurTime = wDelay; + lpNewTimer->wDelay = wDelay; + lpNewTimer->wResol = wResol; + lpNewTimer->lpFunc = lpFunc; + lpNewTimer->dwUser = dwUser; + lpNewTimer->wFlags = wFlags; + return lpNewTimer->wTimerID; +} + +/************************************************************************** +* timeKillEvent [MMSYSTEM.603] +*/ +WORD timeKillEvent(WORD wID) +{ + LPTIMERENTRY lpTimer = lpTimerList; + while (lpTimer != NULL) { + if (wID == lpTimer->wTimerID) { + if (lpTimer->Prev != NULL) lpTimer->Prev->Next = lpTimer->Next; + if (lpTimer->Next != NULL) lpTimer->Next->Prev = lpTimer->Prev; + free(lpTimer); + return TRUE; + } + lpTimer = lpTimer->Next; + } + return 0; +} + +/************************************************************************** +* timeGetDevCaps [MMSYSTEM.604] +*/ +WORD timeGetDevCaps(LPTIMECAPS lpCaps, WORD wSize) +{ + printf("timeGetDevCaps(%08X, %u) !\n", lpCaps, wSize); + return 0; +} + +/************************************************************************** +* timeBeginPeriod [MMSYSTEM.605] +*/ +WORD timeBeginPeriod(WORD wPeriod) +{ + printf("timeBeginPeriod(%u) !\n", wPeriod); + if (!mmTimeStarted) StartMMTime(); + return 0; +} + +/************************************************************************** +* timeEndPeriod [MMSYSTEM.606] +*/ +WORD timeEndPeriod(WORD wPeriod) +{ + printf("timeEndPeriod(%u) !\n", wPeriod); + return 0; +} + +/************************************************************************** +* timeGetTime [MMSYSTEM.607] +*/ +DWORD timeGetTime() +{ + printf("timeGetTime(); !\n"); + if (!mmTimeStarted) StartMMTime(); + return 0; +} + /************************************************************************** * mmioOpen [MMSYSTEM.1210] diff --git a/misc/profile.c b/misc/profile.c index 29e65080c5c..7bd94881d6c 100644 --- a/misc/profile.c +++ b/misc/profile.c @@ -332,13 +332,13 @@ int GetProfileString (LPSTR AppName, LPSTR KeyName, LPSTR Default, WORD GetPrivateProfileInt (LPSTR AppName, LPSTR KeyName, short Default, LPSTR File) { - static char IntBuf [5]; - static char buf [5]; + static char IntBuf [6]; + static char buf [6]; sprintf (buf, "%d", Default); /* Check the exact semantic with the SDK */ - GetPrivateProfileString (AppName, KeyName, buf, IntBuf, 5, File); + GetPrivateProfileString (AppName, KeyName, buf, IntBuf, 6, File); if (!strcasecmp (IntBuf, "true")) return 1; if (!strcasecmp (IntBuf, "yes")) diff --git a/misc/property.c b/misc/property.c index 92f57a40f9a..b58d1731dd8 100644 --- a/misc/property.c +++ b/misc/property.c @@ -3,7 +3,9 @@ */ static char Copyright[] = "Copyright Martin Ayotte, 1994"; +/* #define DEBUG_PROP +*/ #include #include @@ -13,12 +15,12 @@ static char Copyright[] = "Copyright Martin Ayotte, 1994"; #include "heap.h" #include "win.h" -typedef struct { +typedef struct tagPROPENTRY { LPSTR PropName; WORD Atom; HANDLE hData; - void *lpPrevProp; - void *lpNextProp; + struct tagPROPENTRY *lpPrevProp; + struct tagPROPENTRY *lpNextProp; } PROPENTRY; typedef PROPENTRY *LPPROPENTRY; @@ -44,7 +46,9 @@ HANDLE RemoveProp(HWND hWnd, LPSTR lpStr) } lpProp = (LPPROPENTRY) GlobalLock(wndPtr->hProp); if (lpProp == NULL) { +#ifdef DEBUG_PROP printf("Property List Empty !\n"); +#endif return 0; } while (TRUE) { @@ -53,14 +57,14 @@ HANDLE RemoveProp(HWND hWnd, LPSTR lpStr) (((DWORD)lpStr & 0xFFFF0000) != 0L && lpProp->PropName != NULL && strcmp(lpProp->PropName, lpStr) == 0)) { +#ifdef DEBUG_PROP printf("RemoveProp // Property found ! hData=%04X\n", lpProp->hData); +#endif hOldData = lpProp->hData; if (lpProp->lpPrevProp != NULL) - ((LPPROPENTRY)lpProp->lpPrevProp)->lpNextProp = - lpProp->lpNextProp; + lpProp->lpPrevProp->lpNextProp = lpProp->lpNextProp; if (lpProp->lpNextProp != NULL) - ((LPPROPENTRY)lpProp->lpNextProp)->lpPrevProp = - lpProp->lpPrevProp; + lpProp->lpNextProp->lpPrevProp = lpProp->lpPrevProp; if (lpProp->PropName != NULL) free(lpProp->PropName); GlobalFree(lpProp); GlobalUnlock(wndPtr->hProp); @@ -70,7 +74,9 @@ HANDLE RemoveProp(HWND hWnd, LPSTR lpStr) lpProp = lpProp->lpNextProp; } GlobalUnlock(wndPtr->hProp); +#ifdef DEBUG_PROP printf("RemoveProp // Property not found !\n"); +#endif return 0; } @@ -95,7 +101,9 @@ HANDLE GetProp(HWND hWnd, LPSTR lpStr) } lpProp = (LPPROPENTRY) GlobalLock(wndPtr->hProp); if (lpProp == NULL) { +#ifdef DEBUG_PROP printf("Property List Empty !\n"); +#endif return 0; } while (TRUE) { @@ -104,14 +112,18 @@ HANDLE GetProp(HWND hWnd, LPSTR lpStr) (((DWORD)lpStr & 0xFFFF0000) != 0L && lpProp->PropName != NULL && strcmp(lpProp->PropName, lpStr) == 0)) { +#ifdef DEBUG_PROP printf("GetProp // Property found ! hData=%04X\n", lpProp->hData); +#endif GlobalUnlock(wndPtr->hProp); return lpProp->hData; } if (lpProp->lpNextProp == NULL) break; lpProp = lpProp->lpNextProp; } +#ifdef DEBUG_PROP printf("GetProp // Property not found !\n"); +#endif GlobalUnlock(wndPtr->hProp); return 0; } diff --git a/misc/shell.c b/misc/shell.c index d55368d1ee3..0b6e55270d1 100644 --- a/misc/shell.c +++ b/misc/shell.c @@ -5,6 +5,7 @@ #include #include #include +#include "prototypes.h" #include "windows.h" #include "shell.h" @@ -396,8 +397,23 @@ INT AboutDlgProc(HWND hWnd, WORD msg, WORD wParam, LONG lParam) */ HICON ExtractIcon(HINSTANCE hInst, LPCSTR lpszExeFileName, UINT nIconIndex) { - fprintf(stderr, "ExtractIcon : Empty Stub !!!\n"); - + int count; + HICON hIcon = 0; + HINSTANCE hInst2 = hInst; + fprintf(stderr, "ExtractIcon(%04X, '%s', %d\n", + hInst, lpszExeFileName, nIconIndex); + if (lpszExeFileName != NULL) { + hInst2 = LoadLibrary(lpszExeFileName); + } + if (hInst2 != 0 && nIconIndex == (UINT)-1) { + count = GetRsrcCount(hInst2, NE_RSCTYPE_GROUP_ICON); + printf("ExtractIcon // '%s' has %d icons !\n", lpszExeFileName, count); + return (HICON)count; + } + if (hInst2 != hInst && hInst2 != 0) { + FreeLibrary(hInst2); + } + return hIcon; } diff --git a/misc/stress.c b/misc/stress.c index 2b748b78c2a..e503ef9d7b1 100644 --- a/misc/stress.c +++ b/misc/stress.c @@ -88,7 +88,7 @@ int GetFreeFileHandles(void) #endif #ifndef OPEN_MAX - return _POSIX_OPEN_MAX + return _POSIX_OPEN_MAX; #else return OPEN_MAX; #endif diff --git a/miscemu/int31.c b/miscemu/int31.c index eaee32683a5..3d4500ce09e 100644 --- a/miscemu/int31.c +++ b/miscemu/int31.c @@ -3,12 +3,92 @@ #include "msdos.h" #include "wine.h" +typedef struct { + WORD accessed : 1; + WORD read_write : 1; + WORD conf_exp : 1; + WORD code : 1; + WORD xsystem : 1; + WORD dpl : 2; + WORD present : 1; + WORD dummy : 8; + } ACCESS; +typedef ACCESS *LPACCESS; + +typedef struct { + WORD Limit; + WORD addr_lo; + BYTE addr_hi; + ACCESS access; + WORD reserved; + } DESCRIPTOR; +typedef DESCRIPTOR *LPDESCRIPTOR; + +HANDLE DPMI_GetNewSelector(WORD selcount); +BOOL DPMI_FreeSelector(HANDLE pmSel); +BOOL DPMI_SetDescriptor(HANDLE pmSel, LPDESCRIPTOR lpDesc); + +/*************************************************************************/ + int do_int31(struct sigcontext_struct *context) { - switch((context->sc_eax >> 8) & 0xff) + LPDESCRIPTOR lpDesc; + printf("do_int31 // context->sc_eax=%04X\n", context->sc_eax); + switch(context->sc_eax) { + case 0x0000: + context->sc_eax = DPMI_GetNewSelector(context->sc_ecx); + break; + case 0x0001: + context->sc_eax = DPMI_FreeSelector(context->sc_ebx); + break; + case 0x000C: + lpDesc = MAKELONG(context->sc_edi, context->sc_es); + context->sc_eax = DPMI_SetDescriptor(context->sc_ebx, lpDesc); + break; default: IntBarf(0x31, context); }; return 1; } + + +/*************************************************************************/ + + +HANDLE DPMI_GetNewSelector(WORD selcount) +{ + LPSTR ptr; + HANDLE pmSel; + printf("DPMI_GetNewSelector(%d); !\n", selcount); + pmSel = GlobalAlloc(GMEM_FIXED, 4096); + ptr = GlobalLock(pmSel); + printf("DPMI_GetNewSelector() return %04X !\n", pmSel); + return pmSel; +} + + +BOOL DPMI_FreeSelector(HANDLE pmSel) +{ + printf("DPMI_FreeSelector(%04X); !\n", pmSel); + GlobalFree(pmSel); + return 0; +} + +BOOL DPMI_SetDescriptor(HANDLE pmSel, LPDESCRIPTOR lpDesc) +{ + printf("DPMI_SetDescriptor(%04X, %08X); !\n", pmSel, lpDesc); + printf("DPMI lpDesc->Limit=%u \n", lpDesc->Limit); + printf("DPMI lpDesc->addr_lo=%04X \n", lpDesc->addr_lo); + printf("DPMI lpDesc->addr_hi=%02X \n", lpDesc->addr_hi); + printf("DPMI lpDesc->access.accessed=%u \n", lpDesc->access.accessed); + printf("DPMI lpDesc->access.read_write=%u \n", lpDesc->access.read_write); + printf("DPMI lpDesc->access.conf_exp=%u \n", lpDesc->access.conf_exp); + printf("DPMI lpDesc->access.code=%u \n", lpDesc->access.code); + printf("DPMI lpDesc->access.xsystem=%u \n", lpDesc->access.xsystem); + printf("DPMI lpDesc->access.dpl=%u \n", lpDesc->access.dpl); + printf("DPMI lpDesc->access.present=%u \n", lpDesc->access.present); + printf("DPMI lpDesc->reserved=%04X \n", lpDesc->reserved); + return FALSE; +} + diff --git a/objects/bitblt.c b/objects/bitblt.c index c90b9e21585..bb83f993cc3 100644 --- a/objects/bitblt.c +++ b/objects/bitblt.c @@ -66,6 +66,7 @@ BOOL BitBlt( HDC hdcDest, short xDest, short yDest, short width, short height, { int xs1, xs2, ys1, ys2; int xd1, xd2, yd1, yd2; + DWORD saverop = rop; DC *dcDest, *dcSrc; #ifdef DEBUG_GDI @@ -83,10 +84,17 @@ BOOL BitBlt( HDC hdcDest, short xDest, short yDest, short width, short height, return FALSE; } - dcDest = (DC *) GDI_GetObjPtr( hdcDest, DC_MAGIC ); - if (!dcDest) return FALSE; dcSrc = (DC *) GDI_GetObjPtr( hdcSrc, DC_MAGIC ); if (!dcSrc) return FALSE; + dcDest = (DC *) GDI_GetObjPtr( hdcDest, DC_MAGIC ); + if (!dcDest) + { + dcDest = (DC *)GDI_GetObjPtr(hdcDest, METAFILE_DC_MAGIC); + if (!dcDest) return FALSE; + MF_BitBlt(dcDest, xDest, yDest, width, height, + hdcSrc, xSrc, ySrc, saverop); + return TRUE; + } xs1 = dcSrc->w.DCOrgX + XLPTODP( dcSrc, xSrc ); xs2 = dcSrc->w.DCOrgX + XLPTODP( dcSrc, xSrc + width ); @@ -319,6 +327,7 @@ BOOL StretchBlt( HDC hdcDest, short xDest, short yDest, short widthDest, short h int xd1, xd2, yd1, yd2; DC *dcDest, *dcSrc; XImage *sxi, *dxi; + DWORD saverop = rop; WORD stretchmode; BOOL flg; @@ -351,10 +360,17 @@ BOOL StretchBlt( HDC hdcDest, short xDest, short yDest, short widthDest, short h return FALSE; } - dcDest = (DC *) GDI_GetObjPtr( hdcDest, DC_MAGIC ); - if (!dcDest) return FALSE; dcSrc = (DC *) GDI_GetObjPtr( hdcSrc, DC_MAGIC ); if (!dcSrc) return FALSE; + dcDest = (DC *) GDI_GetObjPtr( hdcDest, DC_MAGIC ); + if (!dcDest) + { + dcDest = (DC *)GDI_GetObjPtr(hdcDest, METAFILE_DC_MAGIC); + if (!dcDest) return FALSE; + MF_StretchBlt(dcDest, xDest, yDest, widthDest, heightDest, + hdcSrc, xSrc, ySrc, widthSrc, heightSrc, saverop); + return TRUE; + } xs1 = dcSrc->w.DCOrgX + XLPTODP( dcSrc, xSrc ); xs2 = dcSrc->w.DCOrgX + XLPTODP( dcSrc, xSrc + widthSrc ); diff --git a/objects/bitmap.c b/objects/bitmap.c index 6e8c1b0206e..b068a2a6beb 100644 --- a/objects/bitmap.c +++ b/objects/bitmap.c @@ -115,6 +115,13 @@ HBITMAP CreateBitmapIndirect( BITMAP * bmp ) if (bmp->bmPlanes != 1) return 0; if ((bmp->bmBitsPixel != 1) && (bmp->bmBitsPixel != screenDepth)) return 0; + if (bmp->bmHeight < 0) + bmp->bmHeight = -bmp->bmHeight; + + if (bmp->bmWidth < 0) + bmp->bmWidth = -bmp->bmWidth; + + /* Create the BITMAPOBJ */ hbitmap = GDI_AllocObject( sizeof(BITMAPOBJ), BITMAP_MAGIC ); if (!hbitmap) return 0; diff --git a/objects/font.c b/objects/font.c index fba3ab2ee15..63a5543be4c 100644 --- a/objects/font.c +++ b/objects/font.c @@ -195,6 +195,9 @@ HFONT FONT_SelectObject( DC * dc, HFONT hfont, FONTOBJ * font ) font = (FONTOBJ *) GDI_HEAP_ADDR( hnewfont ); } + if (dc->header.wMagic == METAFILE_DC_MAGIC) + return MF_CreateFontIndirect(dc, hfont, &(font->logfont)); + if ((hfont >= FIRST_STOCK_FONT) && (hfont <= LAST_STOCK_FONT)) stockPtr = &stockFonts[hfont - FIRST_STOCK_FONT]; else diff --git a/objects/metafile.c b/objects/metafile.c index 5ff49ed3617..544e6e48272 100644 --- a/objects/metafile.c +++ b/objects/metafile.c @@ -431,6 +431,11 @@ void PlayMetaFileRecord(HDC hdc, HANDLETABLE *ht, METARECORD *mr, CreatePenIndirect((LOGPEN *)(&(mr->rdParam)))); break; + case META_CREATEFONTINDIRECT: + MF_AddHandle(ht, nHandles, + CreateFontIndirect((LOGFONT *)(&(mr->rdParam)))); + break; + case META_CREATEBRUSHINDIRECT: MF_AddHandle(ht, nHandles, CreateBrushIndirect((LOGBRUSH *)(&(mr->rdParam)))); @@ -798,6 +803,41 @@ BOOL MF_CreatePenIndirect(DC *dc, HPEN hPen, LOGPEN *logpen) } +/****************************************************************** + * MF_CreateFontIndirect + */ +BOOL MF_CreateFontIndirect(DC *dc, HFONT hFont, LOGFONT *logfont) +{ + int index; + BOOL rc; + char buffer[sizeof(METARECORD) - 2 + sizeof(LOGFONT)]; + METARECORD *mr = (METARECORD *)&buffer; + METAFILE *mf; + METAHEADER *mh; + + mr->rdSize = (sizeof(METARECORD) + sizeof(LOGFONT) - 2) / 2; + mr->rdFunction = META_CREATEFONTINDIRECT; + memcpy(&(mr->rdParam), logfont, sizeof(LOGFONT)); + if (!MF_WriteRecord(dc->w.hMetaFile, mr, mr->rdSize * 2)) + return FALSE; + + mr->rdSize = sizeof(METARECORD) / 2; + mr->rdFunction = META_SELECTOBJECT; + if ((index = MF_AddHandleInternal(hFont)) == -1) + return FALSE; + + mf = (METAFILE *)GlobalLock(dc->w.hMetaFile); + mh = (METAHEADER *)GlobalLock(mf->hMetaHdr); + *(mr->rdParam) = index; + if (index >= mh->mtNoObjects) + mh->mtNoObjects++; + rc = MF_WriteRecord(dc->w.hMetaFile, mr, mr->rdSize * 2); + GlobalUnlock(mf->hMetaHdr); + GlobalUnlock(dc->w.hMetaFile); + return rc; +} + + /****************************************************************** * MF_TextOut */ @@ -850,3 +890,24 @@ BOOL MF_MetaPoly(DC *dc, short func, LPPOINT pt, short count) GlobalFree(hmr); return rc; } + + +/****************************************************************** + * MF_BitBlt + */ +BOOL MF_BitBlt(DC *dcDest, short xDest, short yDest, short width, + short height, HDC hdcSrc, short xSrc, short ySrc, DWORD rop) +{ + printf("MF_BitBlt: not implemented yet\n"); +} + + +/****************************************************************** + * MF_StretchBlt + */ +BOOL MF_StretchBlt(DC *dcDest, short xDest, short yDest, short widthDest, + short heightDest, HDC hdcSrc, short xSrc, short ySrc, + short widthSrc, short heightSrc, DWORD rop) +{ + printf("MF_StretchBlt: not implemented yet\n"); +} diff --git a/toolkit/heap.c b/toolkit/heap.c index 93071569c21..002257f7481 100644 --- a/toolkit/heap.c +++ b/toolkit/heap.c @@ -12,7 +12,7 @@ #include "windows.h" /* Controls the blocks per handle table */ -#define MAXBLOCKS 512 +#define MAXBLOCKS 1024 static char Copyright [] = "Copyright (C) 1994 Miguel de Icaza"; @@ -186,6 +186,16 @@ HANDLE GlobalReAlloc(HANDLE hMem, DWORD new_size, WORD flags) return LocalReAlloc (hMem, new_size, flags); } +char *GlobalLinearLock (HANDLE hMem) +{ + return GlobalLock (hMem); +} + +HANDLE GlobalLinearUnlock (HANDLE hMem) +{ + return GlobalUnlock (hMem); +} + #ifdef UNIMPLEMENTED void *GlobalQuickAlloc(int size) { diff --git a/toolkit/hello.c b/toolkit/hello.c new file mode 100644 index 00000000000..d9d9978930a --- /dev/null +++ b/toolkit/hello.c @@ -0,0 +1,72 @@ +/* #include "autoconf.h" */ +#include + +void Write (HDC dc, int x, int y, char *s) +{ + TextOut (dc, x, y, s, strlen (s)); +} + +LONG WndProc (HANDLE wnd, UINT msg, WORD w, LONG l) +{ + static short xChar, yChar; + HDC dc; + PAINTSTRUCT ps; + TEXTMETRIC tm; + + switch (msg){ + case WM_CREATE: + dc = GetDC (wnd); + GetTextMetrics (dc, &tm); + xChar = tm.tmAveCharWidth; + yChar = tm.tmHeight; + ReleaseDC (wnd, dc); + break; + + case WM_PAINT: + dc = BeginPaint (wnd, &ps); + Write (dc, xChar, yChar, "Hola"); + EndPaint (wnd, &ps); + break; + + case WM_DESTROY: + PostQuitMessage (0); + break; + + default: + return DefWindowProc (wnd, msg, w, l); + } + return 0l; +} + +int PASCAL WinMain (HANDLE inst, HANDLE prev, LPSTR cmdline, int show) +{ + HWND wnd; + MSG msg; + WNDCLASS class; + + if (!prev){ + class.style = CS_HREDRAW | CS_VREDRAW; + class.lpfnWndProc = WndProc; + class.cbClsExtra = 0; + class.cbWndExtra = 0; + class.hInstance = inst; + class.hIcon = LoadIcon (0, IDI_APPLICATION); + class.hCursor = LoadCursor (0, IDC_ARROW); + class.hbrBackground = GetStockObject (WHITE_BRUSH); + class.lpszMenuName = NULL; + class.lpszClassName = "class"; + } + if (!RegisterClass (&class)) + return FALSE; + + wnd = CreateWindow ("class", "Test app", WS_OVERLAPPEDWINDOW, + CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, 0, + 0, inst, 0); + ShowWindow (wnd, show); + UpdateWindow (wnd); + + while (GetMessage (&msg, 0, 0, 0)){ + TranslateMessage (&msg); + DispatchMessage (&msg); + } +} diff --git a/windows/Imakefile b/windows/Imakefile index c5720cb5955..53412bc94ce 100644 --- a/windows/Imakefile +++ b/windows/Imakefile @@ -14,6 +14,7 @@ SRCS = \ focus.c \ graphics.c \ hook.c \ + icon.c \ keyboard.c \ mapping.c \ mdi.c \ diff --git a/windows/dce.c b/windows/dce.c index 3dfe56ef66c..58216b4b799 100644 --- a/windows/dce.c +++ b/windows/dce.c @@ -11,6 +11,7 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; #include "win.h" #include "gdi.h" #include "user.h" +#include "icon.h" #define NB_DCE 5 /* Number of DCEs created at startup */ @@ -130,6 +131,7 @@ HDC GetDCEx( HWND hwnd, HRGN hrgnClip, DWORD flags ) DCE * dce; DC * dc; WND * wndPtr; + ICONALLOC *lpico; if (hwnd) { @@ -181,6 +183,25 @@ HDC GetDCEx( HWND hwnd, HRGN hrgnClip, DWORD flags ) dc->w.DCSizeX = wndPtr->rectWindow.right - wndPtr->rectWindow.left; dc->w.DCSizeY = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top; } + else if (IsIconic(hwnd)) /* if we have an icon */ + { + /* more things are hardcoded here than should be, + * I assume the icon windows is 100 pixels 1/2 of which is 50 + * this just sets up the dc so it knows about the size of + * the icon area + */ + dc->u.x.drawable = wndPtr->icon; + if (wndPtr->hIcon != (HICON)NULL) { + lpico = (ICONALLOC *)GlobalLock(wndPtr->hIcon); + dc->w.DCSizeX = /* (int)lpico->descriptor.Width */ 100; + dc->w.DCSizeY = (int)lpico->descriptor.Height + 20; + } else { + dc->w.DCOrgX = /* 64 */ 100; /* assume max size */ + dc->w.DCOrgY = 64 + 20; + } + dc->w.DCOrgX = 0; + dc->w.DCOrgY = 0; + } else { dc->w.DCOrgX = wndPtr->rectClient.left - wndPtr->rectWindow.left; @@ -202,7 +223,7 @@ HDC GetDCEx( HWND hwnd, HRGN hrgnClip, DWORD flags ) if ((flags & DCX_INTERSECTRGN) || (flags & DCX_EXCLUDERGN)) { HRGN hrgn = CreateRectRgn( 0, 0, 0, 0 ); - if (hrgn) + if (hrgn && !IsIconic(hwnd)) { if (CombineRgn( hrgn, InquireVisRgn(hdc), hrgnClip, (flags & DCX_INTERSECTRGN) ? RGN_AND : RGN_DIFF )) diff --git a/windows/defwnd.c b/windows/defwnd.c index 2434840e5ce..e91e3a8368f 100644 --- a/windows/defwnd.c +++ b/windows/defwnd.c @@ -38,11 +38,9 @@ void DEFWND_SetText( HWND hwnd, LPSTR text ) WND *wndPtr = WIN_FindWndPtr( hwnd ); if (wndPtr->hText) USER_HEAP_FREE( wndPtr->hText ); - wndPtr->hText = USER_HEAP_ALLOC( LMEM_MOVEABLE, strlen(text) + 2 ); + wndPtr->hText = USER_HEAP_ALLOC( LMEM_MOVEABLE, strlen(text) + 1 ); textPtr = (LPSTR) USER_HEAP_ADDR( wndPtr->hText ); strcpy( textPtr, text ); - /* for use by edit control */ - *(textPtr + strlen(text) + 1) = '\0'; } @@ -79,6 +77,11 @@ LONG DefWindowProc( HWND hwnd, WORD msg, WORD wParam, LONG lParam ) case WM_NCPAINT: return NC_HandleNCPaint( hwnd, (HRGN)wParam ); + case WM_PAINTICON: + printf("going to call NC_HandleNCPaintIcon\n"); + return NC_HandleNCPaintIcon( hwnd ); + + case WM_NCHITTEST: return NC_HandleNCHitTest( hwnd, MAKEPOINT(lParam) ); diff --git a/windows/event.c b/windows/event.c index b873befc71b..04358df5928 100644 --- a/windows/event.c +++ b/windows/event.c @@ -23,6 +23,11 @@ typedef char *XPointer; #endif #endif +#ifdef sparc +/* Dirty hack to compile with Sun's OpenWindows */ +typedef char *XPointer; +#endif + #define NB_BUTTONS 3 /* Windows can handle 3 buttons */ extern int desktopX, desktopY; /* misc/main.c */ @@ -36,6 +41,7 @@ static XContext winContext = 0; BOOL MouseButtonsStates[NB_BUTTONS] = { FALSE, FALSE, FALSE }; BOOL AsyncMouseButtonsStates[NB_BUTTONS] = { FALSE, FALSE, FALSE }; BYTE KeyStateTable[256]; +BYTE AsyncKeyStateTable[256]; static WORD ALTKeyState; static HWND captureWnd = 0; Window winHasCursor = 0; @@ -245,6 +251,13 @@ static void EVENT_Expose( HWND hwnd, XExposeEvent *event ) WND * wndPtr = WIN_FindWndPtr( hwnd ); if (!wndPtr) return; + if (IsIconic(hwnd) && wndPtr->hIcon) + { + SendMessage(hwnd, WM_PAINTICON, 0, 0); + return; + } + + /* Make position relative to client area instead of window */ rect.left = event->x - (wndPtr->rectClient.left - wndPtr->rectWindow.left); rect.top = event->y - (wndPtr->rectClient.top - wndPtr->rectWindow.top); @@ -321,7 +334,9 @@ static void EVENT_key( HWND hwnd, XKeyEvent *event ) if (event->type == KeyPress) { if (vkey == VK_MENU) ALTKeyState = TRUE; - KeyStateTable[vkey] = 1; + if (!(KeyStateTable[vkey] & 0x0f)) + KeyStateTable[vkey] ^= 0x80; + KeyStateTable[vkey] |= 0x01; keylp.lp1.count = 1; keylp.lp1.code = LOBYTE(event->keycode); keylp.lp1.extended = (extended ? 1 : 0); @@ -330,6 +345,7 @@ static void EVENT_key( HWND hwnd, XKeyEvent *event ) keylp.lp1.transition = 0; #ifdef DEBUG_KEY printf(" wParam=%X, lParam=%lX\n", vkey, keylp.lp2 ); + printf(" KeyState=%X\n", KeyStateTable[vkey]); #endif hardware_event( ALTKeyState ? WM_SYSKEYDOWN : WM_KEYDOWN, vkey, keylp.lp2, @@ -353,7 +369,7 @@ static void EVENT_key( HWND hwnd, XKeyEvent *event ) else { if (vkey == VK_MENU) ALTKeyState = FALSE; - KeyStateTable[vkey] = 1; + KeyStateTable[vkey] &= 0xf0; keylp.lp1.count = 1; keylp.lp1.code = LOBYTE(event->keycode); keylp.lp1.extended = (extended ? 1 : 0); @@ -362,6 +378,7 @@ static void EVENT_key( HWND hwnd, XKeyEvent *event ) keylp.lp1.transition = 1; #ifdef DEBUG_KEY printf(" wParam=%X, lParam=%lX\n", vkey, keylp.lp2 ); + printf(" KeyState=%X\n", KeyStateTable[vkey]); #endif hardware_event( ((ALTKeyState || vkey == VK_MENU) ? WM_SYSKEYUP : WM_KEYUP), diff --git a/windows/graphics.c b/windows/graphics.c index dda491a1df2..0d2392f503c 100644 --- a/windows/graphics.c +++ b/windows/graphics.c @@ -20,6 +20,15 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; extern int COLOR_ToPhysical( DC *dc, COLORREF color ); +static inline swap_int(int *a, int *b) +{ + int c; + + c = *a; + *a = *b; + *b = c; +} + /*********************************************************************** * LineTo (GDI.19) */ @@ -220,6 +229,12 @@ BOOL Ellipse( HDC hdc, int left, int top, int right, int bottom ) right = XLPTODP( dc, right ); bottom = YLPTODP( dc, bottom ); if ((left == right) || (top == bottom)) return FALSE; + + if (right < left) + swap_int(&right, &left); + + if (bottom < top) + swap_int(&bottom, &top); if (DC_SetupGCForBrush( dc )) XFillArc( display, dc->u.x.drawable, dc->u.x.gc, @@ -246,16 +261,31 @@ BOOL Rectangle( HDC hdc, int left, int top, int right, int bottom ) MF_MetaParam4(dc, META_RECTANGLE, left, top, right, bottom); return TRUE; } - left = XLPTODP( dc, left ); top = YLPTODP( dc, top ); right = XLPTODP( dc, right ); bottom = YLPTODP( dc, bottom ); + + if (right < left) + swap_int(&right, &left); + + if (bottom < top) + swap_int(&bottom, &top); + + if ((left == right) || (top == bottom)) { + if (DC_SetupGCForPen( dc )) + XDrawLine(display, dc->u.x.drawable, dc->u.x.gc, + dc->w.DCOrgX + left, + dc->w.DCOrgY + top, + dc->w.DCOrgX + right, + dc->w.DCOrgY + bottom); + return TRUE; + } if (DC_SetupGCForBrush( dc )) XFillRectangle( display, dc->u.x.drawable, dc->u.x.gc, dc->w.DCOrgX + left, dc->w.DCOrgY + top, - right-left-1, bottom-top-1 ); + right-left, bottom-top ); if (DC_SetupGCForPen( dc )) XDrawRectangle( display, dc->u.x.drawable, dc->u.x.gc, dc->w.DCOrgX + left, dc->w.DCOrgY + top, diff --git a/windows/icon.c b/windows/icon.c new file mode 100644 index 00000000000..dc9648e4145 --- /dev/null +++ b/windows/icon.c @@ -0,0 +1,175 @@ + +/* + * Iconification functions + * + * Copyright 1994 John Richardson + */ + +static char Copyright[] = "Copyright John Richardson, 1994"; + +#include "win.h" +#include "class.h" +#include "message.h" +#include "sysmetrics.h" +#include "user.h" +#include "scroll.h" +#include "menu.h" +#include "icon.h" + +RECT myrect; + + +ICON_Iconify(HWND hwnd) +{ + WND *wndPtr = WIN_FindWndPtr( hwnd ); + GC testgc; + WND *parwPtr; + +#ifdef DEBUG_ICON +#endif + printf("ICON_Iconify %d\n", hwnd); + + parwPtr = WIN_FindWndPtr(wndPtr->hwndParent); + if (parwPtr == NULL) { + printf("argh, the parent is NULL, what to do?\n"); + exit(1); + } + wndPtr->dwStyle |= WS_MINIMIZE; + XUnmapWindow(display, wndPtr->window); + if (wndPtr->icon == NULL) { + printf("argh, couldn't find icon\n"); + exit(1); + } + printf("parent edge values are %d, %d\n", parwPtr->rectWindow.left, + parwPtr->rectWindow.bottom); + wndPtr->ptIconPos.x = parwPtr->rectWindow.left + 10; + wndPtr->ptIconPos.y = parwPtr->rectWindow.bottom - 80; + +#ifdef NOT + wndPtr->rectWindow.right = 100; + wndPtr->rectWindow.bottom = 32; + wndPtr->rectNormal.right = 1000; + wndPtr->rectNormal.bottom = 32; + wndPtr->rectClient.top= wndPtr->ptIconPos.y; + wndPtr->rectClient.left= wndPtr->ptIconPos.x; + + wndPtr->rectClient.right = 100; + wndPtr->rectClient.bottom = 64; +#endif + wndPtr->rectClientSave = wndPtr->rectNormal; + myrect = wndPtr->rectClient; + + MoveWindow(hwnd, wndPtr->ptIconPos.x, wndPtr->ptIconPos.y, + 100, 64+20, FALSE); + + XMoveWindow(display, wndPtr->icon, + wndPtr->ptIconPos.x, wndPtr->ptIconPos.y); + + XMapWindow(display, wndPtr->icon); + + SendMessage(hwnd, WM_PAINTICON, 0, 0); + printf("done with iconify\n"); +} + + +BOOL ICON_isAtPoint(HWND hwnd, POINT pt) +{ + WND *wndPtr = WIN_FindWndPtr( hwnd ); + int iconWidth, iconHeight; + +/**************** + if (wndPtr->hwndParent != GetDesktopWindow()) { + pt.x -= wndPtr->rectClient.left; + pt.y -= wndPtr->rectClient.top; + } +*****************/ + + + if (wndPtr->hIcon != (HICON)NULL) { + ICONALLOC *lpico; + lpico = (ICONALLOC *)GlobalLock(wndPtr->hIcon); + iconWidth = (int)lpico->descriptor.Width; + iconHeight = (int)lpico->descriptor.Height; + } else { + iconWidth = 64; + iconHeight = 64; + } +#define DEBUG_ICON 1 +#ifdef DEBUG_ICON + printf("icon x,y is %d,%d\n", + wndPtr->ptIconPos.x, wndPtr->ptIconPos.y); + + printf("icon end x,y is %d,%d\n", + wndPtr->ptIconPos.x + 100, + wndPtr->ptIconPos.y + iconHeight + 20); + + printf("mouse pt x,y is %d,%d\n", pt.x, pt.y); + + printf("%d\n", IsIconic(hwnd)); + printf("%d\n", (pt.x >= wndPtr->ptIconPos.x)); + printf("%d\n", (pt.x < wndPtr->ptIconPos.x + 100)); + printf("%d\n", (pt.y >= wndPtr->ptIconPos.y)); + printf("%d\n", (pt.y < wndPtr->ptIconPos.y + iconHeight + 20)); + printf("%d\n", !(wndPtr->dwStyle & WS_DISABLED)); + printf("%d\n", (wndPtr->dwStyle & WS_VISIBLE)); + printf("%d\n", !(wndPtr->dwExStyle & WS_EX_TRANSPARENT)); +#endif + + if ( IsIconic(hwnd) && + (pt.x >= wndPtr->ptIconPos.x) && + (pt.x < wndPtr->ptIconPos.x + 100) && + (pt.y >= wndPtr->ptIconPos.y) && + (pt.y < wndPtr->ptIconPos.y + iconHeight + 20) && + !(wndPtr->dwStyle & WS_DISABLED) && + (wndPtr->dwStyle & WS_VISIBLE) && + !(wndPtr->dwExStyle & WS_EX_TRANSPARENT)) + { + printf("got a winner!\n"); + return 1; + } + + return 0; + +} + +HWND ICON_findIconFromPoint(POINT pt) +{ + HWND hwnd = GetTopWindow( GetDesktopWindow() ); + WND *wndPtr; + HWND hwndRet = 0; + + while (hwnd) { + + if ( !(wndPtr=WIN_FindWndPtr(hwnd))) return 0; + if (ICON_isAtPoint(hwnd, pt)) { + printf("returning\n"); + return hwndRet = hwnd; + } else { + printf("checking child\n"); + hwnd = wndPtr->hwndChild; + } + } + return hwndRet; +} + + +ICON_Deiconify(HWND hwnd) +{ + WND *wndPtr = WIN_FindWndPtr( hwnd ); + + printf("deiconifying\n"); + XUnmapWindow(display, wndPtr->icon); + wndPtr->dwStyle &= ~WS_MINIMIZE; +/* wndPtr->rectNormal = myrect; +*/ + MoveWindow(hwnd, + wndPtr->rectClientSave.left, + wndPtr->rectClientSave.top, + wndPtr->rectClientSave.right - wndPtr->rectClientSave.left, + wndPtr->rectClientSave.bottom - wndPtr->rectClientSave.top, + FALSE); + + XMapWindow(display, wndPtr->window); +} + + diff --git a/windows/keyboard.c b/windows/keyboard.c index bdde31ebf67..e8181cb107a 100644 --- a/windows/keyboard.c +++ b/windows/keyboard.c @@ -12,6 +12,7 @@ static char Copyright[] = "Copyright Bob Amstadt, 1993"; extern BOOL MouseButtonsStates[3]; extern BOOL AsyncMouseButtonsStates[3]; extern BYTE KeyStateTable[256]; +extern BYTE AsyncKeyStateTable[256]; /********************************************************************** * GetKeyState [USER.106] @@ -26,7 +27,7 @@ int GetKeyState(int keycode) case VK_RBUTTON: return MouseButtonsStates[2]; default: - return 0; + return KeyStateTable[keycode]; } } @@ -35,25 +36,26 @@ int GetKeyState(int keycode) */ void GetKeyboardState(BYTE FAR *lpKeyState) { - if (lpKeyState != NULL) { - memcpy(lpKeyState, KeyStateTable, 256); - } + if (lpKeyState != NULL) { + KeyStateTable[VK_LBUTTON] = MouseButtonsStates[0]; + KeyStateTable[VK_MBUTTON] = MouseButtonsStates[1]; + KeyStateTable[VK_RBUTTON] = MouseButtonsStates[2]; + memcpy(lpKeyState, KeyStateTable, 256); + } } /********************************************************************** - * * GetAsyncKeyState (USER.249) * * Determine if a key is or was pressed. retval has high-order * byte set to 1 if currently pressed, low-order byte 1 if key has * been pressed. * - * This uses the variable AsyncMouseButtonsStates (set in event.c) - * which have the mouse button number set to true if the mouse had been - * depressed since the last call to GetAsyncKeyState. - * - * There should also be some keyboard stuff here... it isn't here - * yet. + * This uses the variable AsyncMouseButtonsStates and + * AsyncKeyStateTable (set in event.c) which have the mouse button + * number or key number (whichever is applicable) set to true if the + * mouse or key had been depressed since the last call to + * GetAsyncKeyState. */ int GetAsyncKeyState(int nKey) { @@ -71,14 +73,16 @@ int GetAsyncKeyState(int nKey) break; case VK_RBUTTON: retval = AsyncMouseButtonsStates[2] | - MouseButtonsStates[2] << 8; + (MouseButtonsStates[2] << 8); break; default: - retval = 0; + retval = AsyncKeyStateTable[nKey] | + (KeyStateTable[nKey] << 8); break; } bzero(AsyncMouseButtonsStates, 3); /* all states to false */ + bzero(AsyncKeyStateTable, 256); return retval; } diff --git a/windows/mdi.c b/windows/mdi.c index 08f45bba119..0835c8a8ef5 100644 --- a/windows/mdi.c +++ b/windows/mdi.c @@ -296,6 +296,8 @@ LONG MDIRestoreChild(HWND parent, MDICLIENTINFO *ci) WND *w = WIN_FindWndPtr(child); LPRECT lprect = &ci->rectRestore; + printf("restoring mdi child\n"); + child = ci->hwndActiveChild; w->dwStyle &= ~WS_MAXIMIZE; @@ -749,6 +751,8 @@ DefMDIChildProc(HWND hwnd, WORD message, WORD wParam, LONG lParam) return SendMessage(GetParent(hwnd), WM_MDIMAXIMIZE, hwnd, 0); case SC_RESTORE: + if (IsIconic(hwnd)) + ICON_Deiconify(hwnd); return SendMessage(GetParent(hwnd), WM_MDIRESTORE, hwnd, 0); } break; diff --git a/windows/message.c b/windows/message.c index a356f519c01..dfafcdef88d 100644 --- a/windows/message.c +++ b/windows/message.c @@ -387,6 +387,12 @@ void hardware_event( WORD message, WORD wParam, LONG lParam, /* Determine the hwnd for this message */ /* Maybe this should be done in GetMessage() */ + if (msg.hwnd = ICON_findIconFromPoint(msg.pt)) { + SendMessage( msg.hwnd, WM_SYSCOMMAND, SC_RESTORE, *(LONG*)&msg.pt ); + return; + } + + if ((message >= WM_MOUSEFIRST) && (message <= WM_MOUSELAST)) { /* Mouse event */ diff --git a/windows/nonclient.c b/windows/nonclient.c index e31a8752d3d..f7998265c9d 100644 --- a/windows/nonclient.c +++ b/windows/nonclient.c @@ -647,6 +647,47 @@ void NC_DoNCPaint( HWND hwnd, HRGN hrgn, BOOL active, BOOL suppress_menupaint ) } +NC_DoNCPaintIcon(HWND hwnd) +{ + WND *wndPtr = WIN_FindWndPtr(hwnd); + PAINTSTRUCT ps; + HDC hdc; + int ret; + DC *dc; + GC testgc; + int s; + char buffer[256]; + + printf("painting icon\n"); + if (wndPtr == NULL) { + printf("argh, can't find an icon to draw\n"); + return; + } + hdc = BeginPaint(hwnd, &ps); + + ret = DrawIcon(hdc, 100/2 - 16, 0, wndPtr->hIcon); + printf("ret is %d\n", ret); + + if (s=GetWindowText(hwnd, buffer, 256)) + { + /*SetBkColor(hdc, TRANSPARENT); */ + TextOut(hdc, 0, 32, buffer, s); + } + EndPaint(hwnd, &ps); + + printf("done painting icon\n"); + +} + + +LONG NC_HandleNCPaintIcon( HWND hwnd ) +{ + NC_DoNCPaintIcon(hwnd); + return 0; +} + + + /*********************************************************************** * NC_HandleNCPaint * @@ -1183,7 +1224,8 @@ LONG NC_HandleSysCommand( HWND hwnd, WORD wParam, POINT pt ) break; case SC_MINIMIZE: - ShowWindow( hwnd, SW_MINIMIZE ); + ICON_Iconify( hwnd ); + /*ShowWindow( hwnd, SW_MINIMIZE );*/ break; case SC_MAXIMIZE: @@ -1191,6 +1233,7 @@ LONG NC_HandleSysCommand( HWND hwnd, WORD wParam, POINT pt ) break; case SC_RESTORE: + ICON_Deiconify(hwnd); ShowWindow( hwnd, SW_RESTORE ); break; diff --git a/windows/painting.c b/windows/painting.c index 36c72e722b5..65a17ca6ae2 100644 --- a/windows/painting.c +++ b/windows/painting.c @@ -10,6 +10,7 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; #include "win.h" #include "message.h" +#include "gdi.h" /* Last CTLCOLOR id */ #define CTLCOLOR_MAX CTLCOLOR_STATIC @@ -43,6 +44,13 @@ HDC BeginPaint( HWND hwnd, LPPAINTSTRUCT lps ) if (!(wndPtr->flags & WIN_ERASE_UPDATERGN)) lps->fErase = TRUE; else lps->fErase = !SendMessage( hwnd, WM_ERASEBKGND, lps->hdc, 0 ); + + /* + * a BeginPaint should return with these objects set by default + */ + SelectObject(lps->hdc, STOCK_BLACK_PEN); + SelectObject(lps->hdc, STOCK_WHITE_BRUSH); + SelectObject(lps->hdc, STOCK_SYSTEM_FONT); return lps->hdc; } diff --git a/windows/win.c b/windows/win.c index 041c2274c01..cc11dd19f9b 100644 --- a/windows/win.c +++ b/windows/win.c @@ -17,6 +17,7 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; #include "dce.h" #include "sysmetrics.h" #include "scroll.h" +#include "icon.h" extern Colormap COLOR_WinColormap; @@ -244,7 +245,8 @@ HWND CreateWindowEx( DWORD exStyle, LPSTR className, LPSTR windowName, CREATESTRUCT *createStruct; HANDLE hcreateStruct; int wmcreate; - XSetWindowAttributes win_attr; + XSetWindowAttributes win_attr, icon_attr; + int iconWidth, iconHeight; #ifdef DEBUG_WIN printf( "CreateWindowEx: %04X '%s' '%s' %04X %d,%d %dx%d %04X %04X %04X %08X\n", @@ -368,6 +370,12 @@ HWND CreateWindowEx( DWORD exStyle, LPSTR className, LPSTR windowName, win_attr.save_under = FALSE; else win_attr.save_under = TRUE; + + + /* set the background of all windows to be white, just like + * MS-Windows does (hopefully!) + */ + win_attr.background_pixel = WhitePixelOfScreen(screen); wndPtr->window = XCreateWindow( display, parentPtr->window, x + parentPtr->rectClient.left - parentPtr->rectWindow.left, @@ -375,9 +383,46 @@ HWND CreateWindowEx( DWORD exStyle, LPSTR className, LPSTR windowName, width, height, 0, CopyFromParent, InputOutput, CopyFromParent, CWEventMask | CWOverrideRedirect | CWColormap | - CWSaveUnder | CWBackingStore, &win_attr ); + CWSaveUnder | CWBackingStore | CWBackPixel, &win_attr ); XStoreName( display, wndPtr->window, windowName ); + + /* create icon window */ + + icon_attr.override_redirect = rootWindow==DefaultRootWindow(display); + icon_attr.background_pixel = WhitePixelOfScreen(screen); + icon_attr.event_mask = ExposureMask | KeyPressMask | + ButtonPressMask | ButtonReleaseMask; + + wndPtr->hIcon = classPtr->wc.hIcon; + if (wndPtr->hIcon != (HICON)NULL) { + ICONALLOC *lpico; + lpico = (ICONALLOC *)GlobalLock(wndPtr->hIcon); + printf("icon is %d x %d\n", + (int)lpico->descriptor.Width, + (int)lpico->descriptor.Height); + iconWidth = (int)lpico->descriptor.Width; + iconHeight = (int)lpico->descriptor.Height; + } else { + printf("icon was NULL\n"); + iconWidth = 64; + iconHeight = 64; + } + + wndPtr->icon = XCreateWindow(display, parentPtr->window, + 10, 10, 100, iconHeight+20, + 0, CopyFromParent, + InputOutput, CopyFromParent, + CWBorderPixel | CWEventMask | CWOverrideRedirect, + &icon_attr); + + if (style & WS_MINIMIZE) + { + style &= ~WS_MINIMIZE; + } + + + #ifdef DEBUG_MENU printf("CreateWindowEx // menu=%04X instance=%04X classmenu=%08X !\n", menu, instance, classPtr->wc.lpszMenuName); @@ -455,6 +500,7 @@ HWND CreateWindowEx( DWORD exStyle, LPSTR className, LPSTR windowName, else CURSOR_SetWinCursor( hwnd, LoadCursor( 0, IDC_ARROW )); EVENT_RegisterWindow( wndPtr->window, hwnd ); + EVENT_RegisterWindow( wndPtr->icon, hwnd ); WIN_SendParentNotify( hwnd, WM_CREATE, MAKELONG( hwnd, wndPtr->wIDmenu ) );