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 ) );