From 88393b4b38988c2aebff7650d74da2dab2ef8f99 Mon Sep 17 00:00:00 2001 From: Jan Zerebecki Date: Sat, 16 May 2009 10:54:48 +0200 Subject: [PATCH] push 52cba0a224aad01bcbdb26d79e43229ba950650e --- .gitignore | 1 - configure | 9 + configure.ac | 1 + dlls/Makefile.in | 4 - dlls/appwiz.cpl/appwiz.c | 4 +- dlls/cfgmgr32/cfgmgr32.spec | 4 +- dlls/comctl32/listview.c | 29 +- dlls/comctl32/tests/listview.c | 145 ++ dlls/comctl32/tests/msg.c | 2 +- dlls/comctl32/tests/msg.h | 4 +- dlls/comdlg32/cdlg_Nl.rc | 32 +- dlls/cryptui/main.c | 2 +- dlls/d3d10core/d3d10core_private.h | 12 +- dlls/d3d10core/device.c | 29 +- dlls/d3d10core/inputlayout.c | 67 +- dlls/d3d10core/shader.c | 98 +- dlls/d3d8/device.c | 2 +- dlls/d3d9/pixelshader.c | 3 +- dlls/d3dx8/tests/mesh.c | 2 +- dlls/d3dxof/tests/d3dxof.c | 4 +- dlls/ddraw/tests/ddrawmodes.c | 6 +- dlls/dplayx/dplayx_global.c | 700 ++++---- dlls/dplayx/dplayx_messages.c | 4 - dlls/dplayx/name_server.c | 8 - dlls/dplayx/name_server.h | 1 - dlls/dsound/tests/ds3d.c | 4 +- dlls/dsound/tests/ds3d8.c | 2 +- dlls/fusion/assembly.c | 6 - dlls/fusion/fusion.c | 25 - dlls/fusion/fusionpriv.h | 1 - dlls/gdi32/freetype.c | 188 +- dlls/gdiplus/font.c | 66 +- dlls/gdiplus/gdiplus.c | 10 + dlls/gdiplus/gdiplus.spec | 4 +- dlls/gdiplus/gdiplus_private.h | 5 + dlls/gdiplus/graphics.c | 7 + dlls/gdiplus/graphicspath.c | 18 + dlls/gdiplus/stringformat.c | 16 + dlls/hlink/tests/hlink.c | 2 +- dlls/imm32/tests/imm32.c | 2 +- dlls/inetcomm/smtptransport.c | 9 +- dlls/inetmib1/main.c | 84 +- dlls/inetmib1/tests/main.c | 18 +- dlls/iphlpapi/ifenum.c | 6 +- dlls/iphlpapi/ifenum.h | 2 - dlls/kernel32/tests/volume.c | 48 +- dlls/lz32/tests/lzexpand_main.c | 4 +- dlls/mlang/mlang.c | 2 +- dlls/msctf/context.c | 8 + dlls/msctf/inputprocessor.c | 131 ++ dlls/msctf/msctf.c | 46 + dlls/msctf/msctf_internal.h | 5 + dlls/msctf/tests/inputprocessor.c | 1870 ++++++++++---------- dlls/msctf/threadmgr.c | 83 +- dlls/mshtml/Sv.rc | 13 +- dlls/mshtml/navigate.c | 17 +- dlls/mshtml/tests/protocol.c | 12 +- dlls/msi/msi.c | 2 +- dlls/msvcrt/tests/data.c | 2 +- dlls/msvcrt/tests/heap.c | 8 +- dlls/msvfw32/Makefile.in | 5 - dlls/msvfw32/msvideo_main.c | 37 +- dlls/msvfw32/msvideo_private.h | 14 - dlls/msvideo.dll16/Makefile.in | 16 + .../msvideo.dll16.spec} | 0 dlls/{msvfw32 => msvideo.dll16}/msvideo16.c | 288 +-- dlls/{msvfw32 => msvideo.dll16}/vfw16.h | 0 dlls/ntdll/ntdll_misc.h | 1 - dlls/ntdll/tests/rtlstr.c | 10 +- dlls/ntdll/virtual.c | 26 - dlls/ole32/tests/usrmarshal.c | 43 +- dlls/oleaut32/tests/varformat.c | 2 + dlls/oleaut32/varformat.c | 8 +- dlls/opengl32/tests/opengl.c | 54 + dlls/pdh/pdh_main.c | 2 + dlls/riched20/editor.h | 1 - dlls/riched20/string.c | 5 - dlls/rpcrt4/rpc_message.c | 4 +- dlls/rpcrt4/rpc_message.h | 1 - dlls/secur32/tests/secur32.c | 8 +- dlls/setupapi/misc.c | 39 + dlls/setupapi/setupapi.spec | 10 +- dlls/setupapi/setupx.spec | 2 +- dlls/setupapi/setupx16.h | 1 - dlls/setupapi/stubs.c | 40 + dlls/setupapi/tests/parser.c | 6 + dlls/setupapi/virtcopy.c | 78 - dlls/shdocvw/tests/webbrowser.c | 1 + dlls/shell32/brsfolder.c | 14 +- dlls/shell32/control.c | 4 +- dlls/shell32/shell32_Nl.rc | 4 +- dlls/shell32/shell32_main.c | 4 +- dlls/shell32/shell32_main.h | 5 - dlls/shell32/shlexec.c | 5 +- dlls/shell32/shlview.c | 19 +- dlls/shell32/tests/shlexec.c | 4 +- dlls/shlwapi/ordinal.c | 20 + dlls/shlwapi/shlwapi.spec | 2 +- dlls/urlmon/binding.c | 326 +--- dlls/urlmon/bindprot.c | 429 ++++- dlls/urlmon/tests/protocol.c | 100 +- dlls/urlmon/tests/url.c | 24 + dlls/urlmon/urlmon_main.c | 85 +- dlls/urlmon/urlmon_main.h | 13 + dlls/user32/tests/msg.c | 88 +- dlls/user32/tests/scroll.c | 30 +- dlls/user32/tests/win.c | 12 +- dlls/wined3d/arb_program_shader.c | 641 +++---- dlls/wined3d/ati_fragment_shader.c | 4 + dlls/wined3d/baseshader.c | 119 +- dlls/wined3d/basetexture.c | 6 +- dlls/wined3d/context.c | 77 +- dlls/wined3d/cubetexture.c | 9 - dlls/wined3d/device.c | 13 +- dlls/wined3d/directx.c | 24 +- dlls/wined3d/drawprim.c | 5 + dlls/wined3d/glsl_shader.c | 36 +- dlls/wined3d/nvidia_texture_shader.c | 5 + dlls/wined3d/pixelshader.c | 9 +- dlls/wined3d/shader_sm1.c | 7 +- dlls/wined3d/shader_sm4.c | 77 +- dlls/wined3d/state.c | 7 +- dlls/wined3d/surface.c | 14 +- dlls/wined3d/texture.c | 8 - dlls/wined3d/utils.c | 7 + dlls/wined3d/vertexshader.c | 9 +- dlls/wined3d/volumetexture.c | 10 - dlls/wined3d/wined3d_gl.h | 1 + dlls/wined3d/wined3d_main.c | 9 +- dlls/wined3d/wined3d_private.h | 12 +- dlls/winex11.drv/opengl.c | 108 +- dlls/wininet/http.c | 430 +++-- dlls/wininet/internet.h | 8 +- dlls/wininet/netconnection.c | 148 +- dlls/wininet/tests/http.c | 123 +- dlls/wininet/tests/internet.c | 7 +- dlls/wininet/tests/urlcache.c | 45 + dlls/wininet/urlcache.c | 31 +- dlls/wininet/wininet.spec | 4 +- fonts/system.sfd | 94 +- fonts/system.ttf | Bin 24776 -> 24820 bytes include/commctrl.h | 274 +-- include/gdiplusenums.h | 6 + include/msctf.idl | 14 + include/setupapi.h | 3 + include/wine/wined3d.idl | 38 +- include/winineti.h | 2 + include/winnt.h | 4 +- programs/notepad/Nl.rc | 7 +- programs/notepad/Sv.rc | 1 + programs/regedit/Sv.rc | 1 + programs/winecfg/audio.c | 7 +- programs/winedbg/gdbproxy.c | 12 +- programs/winhlp32/macro.c | 14 +- tools/sfnt2fnt.c | 2 +- tools/winedump/Makefile.in | 1 + tools/winedump/dump.c | 1 + tools/winedump/font.c | 139 ++ tools/winedump/winedump.h | 4 +- 159 files changed, 5082 insertions(+), 3344 deletions(-) create mode 100644 dlls/msvideo.dll16/Makefile.in rename dlls/{msvfw32/msvideo.spec => msvideo.dll16/msvideo.dll16.spec} (100%) rename dlls/{msvfw32 => msvideo.dll16}/msvideo16.c (82%) rename dlls/{msvfw32 => msvideo.dll16}/vfw16.h (100%) create mode 100644 tools/winedump/font.c diff --git a/.gitignore b/.gitignore index 3ce8388768f..78ff6c52e45 100644 --- a/.gitignore +++ b/.gitignore @@ -53,7 +53,6 @@ dlls/msi/sql.tab.c dlls/msi/sql.tab.h dlls/mstask/mstask_local.h dlls/mstask/mstask_local_i.c -dlls/msvideo.dll16 dlls/msxml3/msxml3_v1.tlb dlls/ole32/dcom.h dlls/ole32/dcom_p.c diff --git a/configure b/configure index 2cc929b3389..462fb1c9db5 100755 --- a/configure +++ b/configure @@ -24905,6 +24905,14 @@ dlls/msvidc32/Makefile: dlls/msvidc32/Makefile.in dlls/Makedll.rules" ac_config_files="$ac_config_files dlls/msvidc32/Makefile" ALL_MAKEFILES="$ALL_MAKEFILES \\ + dlls/msvideo.dll16/Makefile" +test "x$enable_win16" != xno && ALL_DLL_DIRS="$ALL_DLL_DIRS \\ + msvideo.dll16" +ALL_MAKEFILE_DEPENDS="$ALL_MAKEFILE_DEPENDS +dlls/msvideo.dll16/Makefile: dlls/msvideo.dll16/Makefile.in dlls/Makedll.rules" +ac_config_files="$ac_config_files dlls/msvideo.dll16/Makefile" + +ALL_MAKEFILES="$ALL_MAKEFILES \\ dlls/mswsock/Makefile" test "x$enable_mswsock" != xno && ALL_DLL_DIRS="$ALL_DLL_DIRS \\ mswsock" @@ -27882,6 +27890,7 @@ do "dlls/msvfw32/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/msvfw32/Makefile" ;; "dlls/msvfw32/tests/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/msvfw32/tests/Makefile" ;; "dlls/msvidc32/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/msvidc32/Makefile" ;; + "dlls/msvideo.dll16/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/msvideo.dll16/Makefile" ;; "dlls/mswsock/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/mswsock/Makefile" ;; "dlls/msxml3/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/msxml3/Makefile" ;; "dlls/msxml3/tests/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/msxml3/tests/Makefile" ;; diff --git a/configure.ac b/configure.ac index 5457d7f6ddb..6a686a1986e 100644 --- a/configure.ac +++ b/configure.ac @@ -2137,6 +2137,7 @@ WINE_CONFIG_MAKEFILE([dlls/msvcrtd/tests/Makefile],[dlls/Maketest.rules],[dlls], WINE_CONFIG_MAKEFILE([dlls/msvfw32/Makefile],[dlls/Makedll.rules],[dlls],[ALL_DLL_DIRS]) WINE_CONFIG_MAKEFILE([dlls/msvfw32/tests/Makefile],[dlls/Maketest.rules],[dlls],[ALL_TEST_DIRS],[enable_tests]) WINE_CONFIG_MAKEFILE([dlls/msvidc32/Makefile],[dlls/Makedll.rules],[dlls],[ALL_DLL_DIRS]) +WINE_CONFIG_MAKEFILE([dlls/msvideo.dll16/Makefile],[dlls/Makedll.rules],[dlls],[ALL_DLL_DIRS],[enable_win16]) WINE_CONFIG_MAKEFILE([dlls/mswsock/Makefile],[dlls/Makedll.rules],[dlls],[ALL_DLL_DIRS]) WINE_CONFIG_MAKEFILE([dlls/msxml3/Makefile],[dlls/Makedll.rules],[dlls],[ALL_DLL_DIRS]) WINE_CONFIG_MAKEFILE([dlls/msxml3/tests/Makefile],[dlls/Maketest.rules],[dlls],[ALL_TEST_DIRS],[enable_tests]) diff --git a/dlls/Makefile.in b/dlls/Makefile.in index a04057034a3..b600c3ac83b 100644 --- a/dlls/Makefile.in +++ b/dlls/Makefile.in @@ -22,7 +22,6 @@ WIN16_FILES = \ gdi.exe16 \ krnl386.exe16 \ mmsystem.dll16 \ - msvideo.dll16 \ setupx.dll16 \ system.drv16 \ toolhelp.dll16 \ @@ -50,9 +49,6 @@ gdi.exe16 wing.dll16: krnl386.exe16 system.drv16 toolhelp.dll16: echo "kernel32.dll" >$@ -msvideo.dll16: - echo "msvfw32.dll" >$@ - setupx.dll16: echo "setupapi.dll" >$@ diff --git a/dlls/appwiz.cpl/appwiz.c b/dlls/appwiz.cpl/appwiz.c index b5a722f8b59..892c6354a17 100644 --- a/dlls/appwiz.cpl/appwiz.c +++ b/dlls/appwiz.cpl/appwiz.c @@ -365,7 +365,7 @@ static inline void EmptyList(void) */ static void UpdateButtons(HWND hWnd) { - BOOL sel = ListView_GetSelectedCount(GetDlgItem(hWnd, IDL_PROGRAMS)) != 0; + BOOL sel = SendMessageW(GetDlgItem(hWnd, IDL_PROGRAMS), LVM_GETSELECTEDCOUNT, 0, 0) != 0; EnableWindow(GetDlgItem(hWnd, IDC_ADDREMOVE), sel); EnableWindow(GetDlgItem(hWnd, IDC_SUPPORT_INFO), sel); @@ -636,7 +636,7 @@ static HIMAGELIST AddListViewImageList(HWND hWnd) ImageList_AddIcon(hSmall, hDefaultIcon); DestroyIcon(hDefaultIcon); - (void) ListView_SetImageList(hWnd, hSmall, LVSIL_SMALL); + SendMessageW(hWnd, LVM_SETIMAGELIST, LVSIL_SMALL, (LPARAM)hSmall); return hSmall; } diff --git a/dlls/cfgmgr32/cfgmgr32.spec b/dlls/cfgmgr32/cfgmgr32.spec index f080e7d8f50..da53b3736f8 100644 --- a/dlls/cfgmgr32/cfgmgr32.spec +++ b/dlls/cfgmgr32/cfgmgr32.spec @@ -119,8 +119,8 @@ @ stub CM_Is_Dock_Station_Present @ stdcall CM_Locate_DevNodeA(ptr str long) setupapi.CM_Locate_DevNodeA @ stdcall CM_Locate_DevNodeW(ptr wstr long) setupapi.CM_Locate_DevNodeW -@ stub CM_Locate_DevNode_ExA -@ stub CM_Locate_DevNode_ExW +@ stdcall CM_Locate_DevNode_ExA(ptr str long long) setupapi.CM_Locate_DevNode_ExA +@ stdcall CM_Locate_DevNode_ExW(ptr wstr long long) setupapi.CM_Locate_DevNode_ExW @ stub CM_Merge_Range_List @ stub CM_Modify_Res_Des @ stub CM_Modify_Res_Des_Ex diff --git a/dlls/comctl32/listview.c b/dlls/comctl32/listview.c index a8ecd91e287..e94d3899a41 100644 --- a/dlls/comctl32/listview.c +++ b/dlls/comctl32/listview.c @@ -411,12 +411,7 @@ static BOOL LISTVIEW_GetItemRect(const LISTVIEW_INFO *, INT, LPRECT); static INT LISTVIEW_GetLabelWidth(const LISTVIEW_INFO *, INT); static void LISTVIEW_GetOrigin(const LISTVIEW_INFO *, LPPOINT); static BOOL LISTVIEW_GetViewRect(const LISTVIEW_INFO *, LPRECT); -static void LISTVIEW_SetGroupSelection(LISTVIEW_INFO *, INT); -static BOOL LISTVIEW_SetItemT(LISTVIEW_INFO *, LVITEMW *, BOOL); -static void LISTVIEW_UpdateScroll(const LISTVIEW_INFO *); -static void LISTVIEW_SetSelection(LISTVIEW_INFO *, INT); static void LISTVIEW_UpdateSize(LISTVIEW_INFO *); -static HWND LISTVIEW_EditLabelT(LISTVIEW_INFO *, INT, BOOL); static LRESULT LISTVIEW_Command(const LISTVIEW_INFO *, WPARAM, LPARAM); static INT LISTVIEW_GetStringWidthT(const LISTVIEW_INFO *, LPCWSTR, BOOL); static BOOL LISTVIEW_KeySelection(LISTVIEW_INFO *, INT, BOOL); @@ -424,7 +419,6 @@ static UINT LISTVIEW_GetItemState(const LISTVIEW_INFO *, INT, UINT); static BOOL LISTVIEW_SetItemState(LISTVIEW_INFO *, INT, const LVITEMW *); static LRESULT LISTVIEW_VScroll(LISTVIEW_INFO *, INT, INT, HWND); static LRESULT LISTVIEW_HScroll(LISTVIEW_INFO *, INT, INT, HWND); -static INT LISTVIEW_GetTopIndex(const LISTVIEW_INFO *); static BOOL LISTVIEW_EnsureVisible(LISTVIEW_INFO *, INT, BOOL); static HWND CreateEditLabelT(LISTVIEW_INFO *, LPCWSTR, DWORD, INT, INT, INT, INT, BOOL); static HIMAGELIST LISTVIEW_SetImageList(LISTVIEW_INFO *, INT, HIMAGELIST); @@ -3514,7 +3508,8 @@ static BOOL set_main_item(LISTVIEW_INFO *infoPtr, const LVITEMW *lpLVItem, BOOL item.iItem = lpLVItem->iItem; item.iSubItem = lpLVItem->iSubItem; item.mask = LVIF_STATE | LVIF_PARAM; - item.stateMask = ~0; + item.stateMask = (infoPtr->dwStyle & LVS_OWNERDATA) ? LVIS_FOCUSED | LVIS_SELECTED : ~0; + item.state = 0; item.lParam = 0; if (!isNew && !LISTVIEW_GetItemW(infoPtr, &item)) return FALSE; @@ -4664,9 +4659,6 @@ static void LISTVIEW_ScrollColumns(LISTVIEW_INFO *infoPtr, INT nColumn, INT dx) /* do not update screen if not in report mode */ if (!is_redrawing(infoPtr) || (infoPtr->dwStyle & LVS_TYPEMASK) != LVS_REPORT) return; - /* if we have a focus, we must first erase the focus rect */ - if (infoPtr->bFocus) LISTVIEW_ShowFocusRect(infoPtr, FALSE); - /* Need to reset the item width when inserting a new column */ infoPtr->nItemWidth += dx; @@ -4677,9 +4669,6 @@ static void LISTVIEW_ScrollColumns(LISTVIEW_INFO *infoPtr, INT nColumn, INT dx) rcOld = infoPtr->rcList; rcOld.left = ptOrigin.x + rcCol.left + dx; ScrollWindowEx(infoPtr->hwndSelf, dx, 0, &rcOld, &rcOld, 0, 0, SW_ERASE | SW_INVALIDATE); - - /* we can restore focus now */ - if (infoPtr->bFocus) LISTVIEW_ShowFocusRect(infoPtr, TRUE); } /*** @@ -4710,7 +4699,7 @@ static BOOL LISTVIEW_DeleteColumn(LISTVIEW_INFO *infoPtr, INT nColumn) LISTVIEW_GetHeaderRect(infoPtr, nColumn, &rcCol); - if (!Header_DeleteItem(infoPtr->hwndHeader, nColumn)) + if (!SendMessageW(infoPtr->hwndHeader, HDM_DELETEITEM, nColumn, 0)) return FALSE; Free(DPA_GetPtr(infoPtr->hdpaColumns, nColumn)); @@ -5565,7 +5554,8 @@ static BOOL LISTVIEW_GetItemT(const LISTVIEW_INFO *infoPtr, LPLVITEMW lpLVItem, dispInfo.item.state = 0; /* apparently, we should not callback for lParam in LVS_OWNERDATA */ - if ((lpLVItem->mask & ~(LVIF_STATE | LVIF_PARAM)) || infoPtr->uCallbackMask) + if ((lpLVItem->mask & ~(LVIF_STATE | LVIF_PARAM)) || + ((lpLVItem->mask & LVIF_STATE) && (infoPtr->uCallbackMask & lpLVItem->stateMask))) { UINT mask = lpLVItem->mask; @@ -6031,7 +6021,7 @@ static BOOL LISTVIEW_GetSubItemRect(const LISTVIEW_INFO *infoPtr, INT nItem, LPR } if (infoPtr->hwndHeader) - return Header_GetItemRect(infoPtr->hwndHeader, lprc->top, lprc); + return SendMessageW(infoPtr->hwndHeader, HDM_GETITEMRECT, lprc->top, (LPARAM)lprc); else { memset(lprc, 0, sizeof(RECT)); @@ -6995,7 +6985,8 @@ static INT LISTVIEW_InsertColumnT(LISTVIEW_INFO *infoPtr, INT nColumn, if (DPA_InsertPtr(infoPtr->hdpaColumns, nNewColumn, lpColumnInfo) == -1) goto fail; if (lpColumn->mask & LVCF_FMT) lpColumnInfo->fmt = lpColumn->fmt; - if (!Header_GetItemRect(infoPtr->hwndHeader, nNewColumn, &lpColumnInfo->rcHeader)) goto fail; + if (!SendMessageW(infoPtr->hwndHeader, HDM_GETITEMRECT, nNewColumn, (LPARAM)&lpColumnInfo->rcHeader)) + goto fail; /* now we have to actually adjust the data */ if (!(infoPtr->dwStyle & LVS_OWNERDATA) && infoPtr->nItemCount > 0) @@ -7693,6 +7684,10 @@ static BOOL LISTVIEW_SetItemState(LISTVIEW_INFO *infoPtr, INT nItem, const LVITE if (nItem == -1) { + /* select all isn't allowed in LVS_SINGLESEL */ + if ((lvItem.state & lvItem.stateMask & LVIS_SELECTED) && (infoPtr->dwStyle & LVS_SINGLESEL)) + return FALSE; + /* apply to all items */ for (lvItem.iItem = 0; lvItem.iItem < infoPtr->nItemCount; lvItem.iItem++) if (!LISTVIEW_SetItemT(infoPtr, &lvItem, TRUE)) bResult = FALSE; diff --git a/dlls/comctl32/tests/listview.c b/dlls/comctl32/tests/listview.c index e94bdaaabd0..63866555e41 100644 --- a/dlls/comctl32/tests/listview.c +++ b/dlls/comctl32/tests/listview.c @@ -168,6 +168,23 @@ static const struct message forward_erasebkgnd_parent_seq[] = { { 0 } }; +static const struct message ownderdata_select_focus_parent_seq[] = { + { WM_NOTIFY, sent|id, 0, 0, LVN_ITEMCHANGED }, + { WM_NOTIFY, sent|id, 0, 0, LVN_GETDISPINFOA }, + { 0 } +}; + +static const struct message textcallback_set_again_parent_seq[] = { + { WM_NOTIFY, sent|id, 0, 0, LVN_ITEMCHANGING }, + { WM_NOTIFY, sent|id, 0, 0, LVN_ITEMCHANGED }, + { 0 } +}; + +static const struct message single_getdispinfo_parent_seq[] = { + { WM_NOTIFY, sent|id, 0, 0, LVN_GETDISPINFOA }, + { 0 } +}; + struct subclass_info { WNDPROC oldproc; @@ -184,6 +201,7 @@ static LRESULT WINAPI parent_wnd_proc(HWND hwnd, UINT message, WPARAM wParam, LP if (defwndproc_counter) msg.flags |= defwinproc; msg.wParam = wParam; msg.lParam = lParam; + if (message == WM_NOTIFY && lParam) msg.id = ((NMHDR*)lParam)->code; /* log system messages, except for painting */ if (message < WM_USER && @@ -827,6 +845,26 @@ static void test_items(void) r = SendMessage(hwnd, LVM_GETITEMA, 0, (LPARAM) &item); ok(r != 0, "ret %d\n", r); + /* set text to callback value already having it */ + r = SendMessage(hwnd, LVM_DELETEALLITEMS, 0, 0); + expect(TRUE, r); + memset (&item, 0, sizeof (item)); + item.mask = LVIF_TEXT; + item.pszText = LPSTR_TEXTCALLBACK; + item.iItem = 0; + r = SendMessage(hwnd, LVM_INSERTITEMA, 0, (LPARAM) &item); + ok(r == 0, "ret %d\n", r); + memset (&item, 0, sizeof (item)); + + flush_sequences(sequences, NUM_MSG_SEQUENCES); + + item.pszText = LPSTR_TEXTCALLBACK; + r = SendMessage(hwnd, LVM_SETITEMTEXT, 0 , (LPARAM) &item); + expect(TRUE, r); + + ok_sequence(sequences, PARENT_SEQ_INDEX, textcallback_set_again_parent_seq, + "check callback text comparison rule", TRUE); + DestroyWindow(hwnd); } @@ -1496,6 +1534,7 @@ static void test_multiselect(void) BYTE kstate[256]; select_task task; LONG_PTR style; + LVITEMA item; static struct t_select_task task_list[] = { { "using VK_DOWN", 0, VK_DOWN, -1, -1 }, @@ -1605,6 +1644,36 @@ todo_wine todo_wine expect(-1, r); + /* try to select all on LVS_SINGLESEL */ + memset(&item, 0, sizeof(item)); + item.stateMask = LVIS_SELECTED; + r = SendMessage(hwnd, LVM_SETITEMSTATE, -1, (LPARAM)&item); + expect(TRUE, r); + ListView_SetSelectionMark(hwnd, -1); + + item.stateMask = LVIS_SELECTED; + item.state = LVIS_SELECTED; + r = SendMessage(hwnd, LVM_SETITEMSTATE, -1, (LPARAM)&item); + expect(FALSE, r); + + r = ListView_GetSelectedCount(hwnd); + expect(0, r); + r = ListView_GetSelectionMark(hwnd); + expect(-1, r); + + /* try to deselect all on LVS_SINGLESEL */ + item.stateMask = LVIS_SELECTED; + item.state = LVIS_SELECTED; + r = SendMessage(hwnd, LVM_SETITEMSTATE, 0, (LPARAM)&item); + expect(TRUE, r); + + item.stateMask = LVIS_SELECTED; + item.state = 0; + r = SendMessage(hwnd, LVM_SETITEMSTATE, -1, (LPARAM)&item); + expect(TRUE, r); + r = ListView_GetSelectedCount(hwnd); + expect(0, r); + DestroyWindow(hwnd); } @@ -1952,6 +2021,82 @@ static void test_ownerdata(void) res = SendMessageA(hwnd, LVM_SETITEM, 0, (LPARAM)&item); expect(FALSE, res); DestroyWindow(hwnd); + + /* check notifications after focused/selected changed */ + hwnd = create_listview_control(LVS_OWNERDATA); + ok(hwnd != NULL, "failed to create a listview window\n"); + res = SendMessageA(hwnd, LVM_SETITEMCOUNT, 1, 0); + ok(res != 0, "Expected LVM_SETITEMCOUNT to succeed\n"); + + flush_sequences(sequences, NUM_MSG_SEQUENCES); + + memset(&item, 0, sizeof(item)); + item.stateMask = LVIS_SELECTED; + item.state = LVIS_SELECTED; + res = SendMessageA(hwnd, LVM_SETITEMSTATE, 0, (LPARAM)&item); + expect(TRUE, res); + + ok_sequence(sequences, PARENT_SEQ_INDEX, ownderdata_select_focus_parent_seq, + "ownerdata select notification", TRUE); + + flush_sequences(sequences, NUM_MSG_SEQUENCES); + + memset(&item, 0, sizeof(item)); + item.stateMask = LVIS_FOCUSED; + item.state = LVIS_FOCUSED; + res = SendMessageA(hwnd, LVM_SETITEMSTATE, 0, (LPARAM)&item); + expect(TRUE, res); + + ok_sequence(sequences, PARENT_SEQ_INDEX, ownderdata_select_focus_parent_seq, + "ownerdata focus notification", TRUE); + DestroyWindow(hwnd); + + /* check notifications on LVM_GETITEM */ + /* zero callback mask */ + hwnd = create_listview_control(LVS_OWNERDATA); + ok(hwnd != NULL, "failed to create a listview window\n"); + res = SendMessageA(hwnd, LVM_SETITEMCOUNT, 1, 0); + ok(res != 0, "Expected LVM_SETITEMCOUNT to succeed\n"); + + flush_sequences(sequences, NUM_MSG_SEQUENCES); + + memset(&item, 0, sizeof(item)); + item.stateMask = LVIS_SELECTED; + item.mask = LVIF_STATE; + res = SendMessageA(hwnd, LVM_GETITEMA, 0, (LPARAM)&item); + expect(TRUE, res); + + ok_sequence(sequences, PARENT_SEQ_INDEX, empty_seq, + "ownerdata getitem selected state 1", FALSE); + + /* non zero callback mask but not we asking for */ + res = SendMessageA(hwnd, LVM_SETCALLBACKMASK, LVIS_OVERLAYMASK, 0); + expect(TRUE, res); + + flush_sequences(sequences, NUM_MSG_SEQUENCES); + + memset(&item, 0, sizeof(item)); + item.stateMask = LVIS_SELECTED; + item.mask = LVIF_STATE; + res = SendMessageA(hwnd, LVM_GETITEMA, 0, (LPARAM)&item); + expect(TRUE, res); + + ok_sequence(sequences, PARENT_SEQ_INDEX, empty_seq, + "ownerdata getitem selected state 2", FALSE); + + /* LVIS_OVERLAYMASK callback mask, asking for index */ + flush_sequences(sequences, NUM_MSG_SEQUENCES); + + memset(&item, 0, sizeof(item)); + item.stateMask = LVIS_OVERLAYMASK; + item.mask = LVIF_STATE; + res = SendMessageA(hwnd, LVM_GETITEMA, 0, (LPARAM)&item); + expect(TRUE, res); + + ok_sequence(sequences, PARENT_SEQ_INDEX, single_getdispinfo_parent_seq, + "ownerdata getitem selected state 2", FALSE); + + DestroyWindow(hwnd); } static void test_norecompute(void) diff --git a/dlls/comctl32/tests/msg.c b/dlls/comctl32/tests/msg.c index 2129f222e01..314bb557e65 100644 --- a/dlls/comctl32/tests/msg.c +++ b/dlls/comctl32/tests/msg.c @@ -51,7 +51,7 @@ void add_message(struct msg_sequence **seq, int sequence_index, msg_seq->count++; } -void flush_sequence(struct msg_sequence **seg, int sequence_index) +static void flush_sequence(struct msg_sequence **seg, int sequence_index) { struct msg_sequence *msg_seq = seg[sequence_index]; HeapFree(GetProcessHeap(), 0, msg_seq->sequence); diff --git a/dlls/comctl32/tests/msg.h b/dlls/comctl32/tests/msg.h index 2ec3ea17a85..87c6387d1ad 100644 --- a/dlls/comctl32/tests/msg.h +++ b/dlls/comctl32/tests/msg.h @@ -47,7 +47,8 @@ struct message msg_flags_t flags; /* message props */ WPARAM wParam; /* expected value of wParam */ LPARAM lParam; /* expected value of lParam */ - UINT id; /* id of the window */ + UINT id; /* extra message data: id of the window, + notify code etc. */ }; struct msg_sequence @@ -59,7 +60,6 @@ struct msg_sequence void add_message(struct msg_sequence **seq, int sequence_index, const struct message *msg); -void flush_sequence(struct msg_sequence **seg, int sequence_index); void flush_sequences(struct msg_sequence **seq, int n); #define ok_sequence(seq, index, exp, contx, todo) \ diff --git a/dlls/comdlg32/cdlg_Nl.rc b/dlls/comdlg32/cdlg_Nl.rc index baeb880a875..6910405154e 100644 --- a/dlls/comdlg32/cdlg_Nl.rc +++ b/dlls/comdlg32/cdlg_Nl.rc @@ -182,7 +182,7 @@ FONT 8, "MS Shell Dlg" } -FINDDLGORD DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 236, 62 +FINDDLGORD DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 246, 72 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Tekst zoeken" FONT 8, "MS Shell Dlg" @@ -190,18 +190,18 @@ FONT 8, "MS Shell Dlg" LTEXT "&Zoek naar:", -1, 4, 8, 42, 8 EDITTEXT 1152, 47, 7, 128, 12, ES_AUTOHSCROLL | WS_BORDER | WS_GROUP | WS_TABSTOP CHECKBOX "Heel &woord", 1040, 4, 26, 100, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP - CHECKBOX "Gelijke &hoofd-/kleine letters", 1041, 4, 42, 64, 12, BS_AUTOCHECKBOX | WS_TABSTOP - GROUPBOX "Zoekrichting", 1072, 107, 26, 68, 28 - CONTROL "&Omhoog", 1056, "BUTTON", BS_AUTORADIOBUTTON | WS_CHILD | WS_VISIBLE | WS_GROUP | WS_TABSTOP, 111, 38, 20, 12 - CONTROL "Om&laag", 1057, "BUTTON", BS_AUTORADIOBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 138, 38, 30, 12 - - DEFPUSHBUTTON "&Volgende zoeken", IDOK, 182, 5, 50, 14, WS_GROUP | WS_TABSTOP | BS_DEFPUSHBUTTON - PUSHBUTTON "Annuleren", IDCANCEL, 182, 23, 50, 14, WS_GROUP | WS_TABSTOP - PUSHBUTTON "&Help", pshHelp , 182, 45, 50, 14, WS_GROUP | WS_TABSTOP + CHECKBOX "Gelijke &hoofd-/kleine letters", 1041, 4, 52, 100, 12, BS_AUTOCHECKBOX | WS_TABSTOP + GROUPBOX "Zoekrichting", 1072, 117, 26, 58, 38 + CONTROL "&Omhoog", 1056, "BUTTON", BS_AUTORADIOBUTTON | WS_CHILD | WS_VISIBLE | WS_GROUP | WS_TABSTOP, 121, 38, 40, 12 + CONTROL "Om&laag", 1057, "BUTTON", BS_AUTORADIOBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 121, 50, 40, 12 + + DEFPUSHBUTTON "&Volgende zoeken", IDOK, 182, 5, 60, 14, WS_GROUP | WS_TABSTOP | BS_DEFPUSHBUTTON + PUSHBUTTON "Annuleren", IDCANCEL, 182, 23, 60, 14, WS_GROUP | WS_TABSTOP + PUSHBUTTON "&Help", pshHelp , 182, 45, 60, 14, WS_GROUP | WS_TABSTOP } -REPLACEDLGORD DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 230, 94 +REPLACEDLGORD DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 240, 94 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Tekst vervangen" FONT 8, "MS Shell Dlg" @@ -211,13 +211,13 @@ FONT 8, "MS Shell Dlg" LTEXT "Vervang &door:", -1, 4, 26, 48, 8 EDITTEXT 1153, 54, 24, 114, 12, ES_AUTOHSCROLL | WS_BORDER | WS_GROUP | WS_TABSTOP CHECKBOX "Heel &woord", 1040, 5, 46, 104, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP - CHECKBOX "Gelijke &hoofd-/kleine letters", 1041, 5, 62, 59, 12, BS_AUTOCHECKBOX | WS_TABSTOP + CHECKBOX "Gelijke &hoofd-/kleine letters", 1041, 5, 62, 100, 12, BS_AUTOCHECKBOX | WS_TABSTOP - DEFPUSHBUTTON "Volgende zoeken", IDOK, 174, 4, 50, 14, WS_GROUP | WS_TABSTOP | BS_DEFPUSHBUTTON - PUSHBUTTON "Ve&rvangen", psh1 , 174, 21, 50, 14, WS_GROUP | WS_TABSTOP - PUSHBUTTON "&Alles vervangen", psh2 , 174, 38, 50, 14, WS_GROUP | WS_TABSTOP - PUSHBUTTON "Annuleren", IDCANCEL, 174, 55, 50, 14, WS_GROUP | WS_TABSTOP - PUSHBUTTON "&Help", pshHelp , 174, 75, 50, 14, WS_GROUP | WS_TABSTOP + DEFPUSHBUTTON "Volgende zoeken", IDOK, 174, 4, 60, 14, WS_GROUP | WS_TABSTOP | BS_DEFPUSHBUTTON + PUSHBUTTON "Ve&rvangen", psh1 , 174, 21, 60, 14, WS_GROUP | WS_TABSTOP + PUSHBUTTON "&Alles vervangen", psh2 , 174, 38, 60, 14, WS_GROUP | WS_TABSTOP + PUSHBUTTON "Annuleren", IDCANCEL, 174, 55, 60, 14, WS_GROUP | WS_TABSTOP + PUSHBUTTON "&Help", pshHelp , 174, 75, 60, 14, WS_GROUP | WS_TABSTOP } NEWFILEOPENORD DIALOG LOADONCALL MOVEABLE DISCARDABLE 0, 0, 280, 164 diff --git a/dlls/cryptui/main.c b/dlls/cryptui/main.c index f6fb60c5581..f15420b4bca 100644 --- a/dlls/cryptui/main.c +++ b/dlls/cryptui/main.c @@ -5170,7 +5170,7 @@ static LRESULT CALLBACK import_store_dlg_proc(HWND hwnd, UINT msg, WPARAM wp, selectInfo.dwSize = sizeof(selectInfo); selectInfo.parent = hwnd; selectInfo.dwFlags = CRYPTUI_ENABLE_SHOW_PHYSICAL_STORE; - selectInfo.pwszTitle = selectInfo.pwszTitle = NULL; + selectInfo.pwszTitle = NULL; selectInfo.pEnumData = &enumData; selectInfo.pfnSelectedStoreCallback = NULL; if ((store = CryptUIDlgSelectStoreW(&selectInfo))) diff --git a/dlls/d3d10core/d3d10core_private.h b/dlls/d3d10core/d3d10core_private.h index 3f782baf1dc..7600e232cc0 100644 --- a/dlls/d3d10core/d3d10core_private.h +++ b/dlls/d3d10core/d3d10core_private.h @@ -39,8 +39,15 @@ ((DWORD)(ch2) << 16) | ((DWORD)(ch3) << 24 )) #define TAG_DXBC MAKE_TAG('D', 'X', 'B', 'C') #define TAG_ISGN MAKE_TAG('I', 'S', 'G', 'N') +#define TAG_OSGN MAKE_TAG('O', 'S', 'G', 'N') #define TAG_SHDR MAKE_TAG('S', 'H', 'D', 'R') +struct d3d10_shader_info +{ + const DWORD *shader_code; + struct wined3d_shader_signature *output_signature; +}; + /* TRACE helper functions */ const char *debug_d3d10_primitive_topology(D3D10_PRIMITIVE_TOPOLOGY topology); const char *debug_dxgi_format(DXGI_FORMAT format); @@ -152,9 +159,12 @@ struct d3d10_pixel_shader LONG refcount; IWineD3DPixelShader *wined3d_shader; + struct wined3d_shader_signature output_signature; }; -HRESULT shader_extract_from_dxbc(const void *dxbc, SIZE_T dxbc_length, const DWORD **shader_code); +HRESULT shader_extract_from_dxbc(const void *dxbc, SIZE_T dxbc_length, struct d3d10_shader_info *shader_info); +HRESULT shader_parse_signature(const char *data, DWORD data_size, struct wined3d_shader_signature *s); +void shader_free_signature(struct wined3d_shader_signature *s); /* Layered device */ enum dxgi_device_layer_id diff --git a/dlls/d3d10core/device.c b/dlls/d3d10core/device.c index 5c91cbd5f40..bbc527b0b46 100644 --- a/dlls/d3d10core/device.c +++ b/dlls/d3d10core/device.c @@ -124,7 +124,12 @@ static void STDMETHODCALLTYPE d3d10_device_PSSetShaderResources(ID3D10Device *if static void STDMETHODCALLTYPE d3d10_device_PSSetShader(ID3D10Device *iface, ID3D10PixelShader *shader) { - FIXME("iface %p, shader %p stub!\n", iface, shader); + struct d3d10_device *This = (struct d3d10_device *)iface; + struct d3d10_pixel_shader *ps = (struct d3d10_pixel_shader *)shader; + + TRACE("iface %p, shader %p\n", iface, shader); + + IWineD3DDevice_SetPixelShader(This->wined3d_device, ps ? ps->wined3d_shader : NULL); } static void STDMETHODCALLTYPE d3d10_device_PSSetSamplers(ID3D10Device *iface, @@ -1025,19 +1030,12 @@ static HRESULT STDMETHODCALLTYPE d3d10_device_CreatePixelShader(ID3D10Device *if { struct d3d10_device *This = (struct d3d10_device *)iface; struct d3d10_pixel_shader *object; - const DWORD *shader_code; + struct d3d10_shader_info shader_info; HRESULT hr; TRACE("iface %p, byte_code %p, byte_code_length %lu, shader %p\n", iface, byte_code, byte_code_length, shader); - hr = shader_extract_from_dxbc(byte_code, byte_code_length, &shader_code); - if (FAILED(hr)) - { - ERR("Failed to extract shader, hr %#x\n", hr); - return hr; - } - object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)); if (!object) { @@ -1048,11 +1046,22 @@ static HRESULT STDMETHODCALLTYPE d3d10_device_CreatePixelShader(ID3D10Device *if object->vtbl = &d3d10_pixel_shader_vtbl; object->refcount = 1; + shader_info.output_signature = &object->output_signature; + hr = shader_extract_from_dxbc(byte_code, byte_code_length, &shader_info); + if (FAILED(hr)) + { + ERR("Failed to extract shader, hr %#x\n", hr); + HeapFree(GetProcessHeap(), 0, object); + return hr; + } + hr = IWineD3DDevice_CreatePixelShader(This->wined3d_device, - shader_code, &object->wined3d_shader, (IUnknown *)object); + shader_info.shader_code, &object->output_signature, + &object->wined3d_shader, (IUnknown *)object); if (FAILED(hr)) { ERR("CreatePixelShader failed, hr %#x\n", hr); + shader_free_signature(&object->output_signature); HeapFree(GetProcessHeap(), 0, object); return hr; } diff --git a/dlls/d3d10core/inputlayout.c b/dlls/d3d10core/inputlayout.c index d78ecad7a91..f6f50bc26a9 100644 --- a/dlls/d3d10core/inputlayout.c +++ b/dlls/d3d10core/inputlayout.c @@ -24,74 +24,15 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d10core); -struct input_signature_element -{ - const char *semantic_name; - UINT semantic_idx; - DWORD unknown; /* system value semantic? */ - DWORD component_type; - UINT register_idx; - DWORD mask; -}; - -struct input_signature -{ - struct input_signature_element *elements; - UINT element_count; -}; - -static HRESULT parse_isgn(const char *data, struct input_signature *is) -{ - struct input_signature_element *e; - const char *ptr = data; - unsigned int i; - DWORD count; - - read_dword(&ptr, &count); - TRACE("%u elements\n", count); - - skip_dword_unknown(&ptr, 1); - - e = HeapAlloc(GetProcessHeap(), 0, count * sizeof(*e)); - if (!e) - { - ERR("Failed to allocate input signature memory.\n"); - return E_OUTOFMEMORY; - } - - for (i = 0; i < count; ++i) - { - UINT name_offset; - - read_dword(&ptr, &name_offset); - e[i].semantic_name = data + name_offset; - read_dword(&ptr, &e[i].semantic_idx); - read_dword(&ptr, &e[i].unknown); - read_dword(&ptr, &e[i].component_type); - read_dword(&ptr, &e[i].register_idx); - read_dword(&ptr, &e[i].mask); - - TRACE("semantic: %s, semantic idx: %u, unknown %#x, type %u, register idx: %u, use_mask %#x, input_mask %#x\n", - e[i].semantic_name, e[i].semantic_idx, e[i].unknown, e[i].component_type, - e[i].register_idx, (e[i].mask >> 8) & 0xff, e[i].mask & 0xff); - } - - is->elements = e; - is->element_count = count; - - return S_OK; -} - static HRESULT isgn_handler(const char *data, DWORD data_size, DWORD tag, void *ctx) { - struct input_signature *is = ctx; - const char *ptr = data; + struct wined3d_shader_signature *is = ctx; char tag_str[5]; switch(tag) { case TAG_ISGN: - return parse_isgn(ptr, is); + return shader_parse_signature(data, data_size, is); default: memcpy(tag_str, &tag, 4); @@ -105,7 +46,7 @@ HRESULT d3d10_input_layout_to_wined3d_declaration(const D3D10_INPUT_ELEMENT_DESC UINT element_count, const void *shader_byte_code, SIZE_T shader_byte_code_length, WINED3DVERTEXELEMENT **wined3d_elements, UINT *wined3d_element_count) { - struct input_signature is; + struct wined3d_shader_signature is; HRESULT hr; UINT i; @@ -157,7 +98,7 @@ HRESULT d3d10_input_layout_to_wined3d_declaration(const D3D10_INPUT_ELEMENT_DESC } } - HeapFree(GetProcessHeap(), 0, is.elements); + shader_free_signature(&is); return S_OK; } diff --git a/dlls/d3d10core/shader.c b/dlls/d3d10core/shader.c index 8b3d01e442c..41b5a1a55d6 100644 --- a/dlls/d3d10core/shader.c +++ b/dlls/d3d10core/shader.c @@ -26,35 +26,115 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d10core); static HRESULT shdr_handler(const char *data, DWORD data_size, DWORD tag, void *ctx) { - const DWORD **shader_data = ctx; + struct d3d10_shader_info *shader_info = ctx; char tag_str[5]; + HRESULT hr; switch(tag) { + case TAG_OSGN: + hr = shader_parse_signature(data, data_size, shader_info->output_signature); + if (FAILED(hr)) return hr; + break; + case TAG_SHDR: - *shader_data = (const DWORD *)data; - return S_OK; + shader_info->shader_code = (const DWORD *)data; + break; default: memcpy(tag_str, &tag, 4); tag_str[4] = '\0'; FIXME("Unhandled chunk %s\n", tag_str); - return S_OK; + break; } + + return S_OK; } -HRESULT shader_extract_from_dxbc(const void *dxbc, SIZE_T dxbc_length, const DWORD **shader_code) +HRESULT shader_extract_from_dxbc(const void *dxbc, SIZE_T dxbc_length, struct d3d10_shader_info *shader_info) { HRESULT hr; - hr = parse_dxbc(dxbc, dxbc_length, shdr_handler, shader_code); - if (!*shader_code) hr = E_FAIL; + shader_info->shader_code = NULL; + memset(shader_info->output_signature, 0, sizeof(*shader_info->output_signature)); - if (FAILED(hr)) ERR("Failed to parse shader, hr %#x\n", hr); + hr = parse_dxbc(dxbc, dxbc_length, shdr_handler, shader_info); + if (!shader_info->shader_code) hr = E_FAIL; + + if (FAILED(hr)) + { + ERR("Failed to parse shader, hr %#x\n", hr); + shader_free_signature(shader_info->output_signature); + } return hr; } +HRESULT shader_parse_signature(const char *data, DWORD data_size, struct wined3d_shader_signature *s) +{ + struct wined3d_shader_signature_element *e; + unsigned int string_data_offset; + unsigned int string_data_size; + const char *ptr = data; + char *string_data; + unsigned int i; + DWORD count; + + read_dword(&ptr, &count); + TRACE("%u elements\n", count); + + skip_dword_unknown(&ptr, 1); + + e = HeapAlloc(GetProcessHeap(), 0, count * sizeof(*e)); + if (!e) + { + ERR("Failed to allocate input signature memory.\n"); + return E_OUTOFMEMORY; + } + + /* 2 DWORDs for the header, 6 for each element. */ + string_data_offset = 2 * sizeof(DWORD) + count * 6 * sizeof(DWORD); + string_data_size = data_size - string_data_offset; + string_data = HeapAlloc(GetProcessHeap(), 0, string_data_size); + if (!string_data) + { + ERR("Failed to allocate string data memory.\n"); + HeapFree(GetProcessHeap(), 0, e); + return E_OUTOFMEMORY; + } + memcpy(string_data, data + string_data_offset, string_data_size); + + for (i = 0; i < count; ++i) + { + UINT name_offset; + + read_dword(&ptr, &name_offset); + e[i].semantic_name = string_data + (name_offset - string_data_offset); + read_dword(&ptr, &e[i].semantic_idx); + read_dword(&ptr, &e[i].sysval_semantic); + read_dword(&ptr, &e[i].component_type); + read_dword(&ptr, &e[i].register_idx); + read_dword(&ptr, &e[i].mask); + + TRACE("semantic: %s, semantic idx: %u, sysval_semantic %#x, " + "type %u, register idx: %u, use_mask %#x, input_mask %#x\n", + e[i].semantic_name, e[i].semantic_idx, e[i].sysval_semantic, e[i].component_type, + e[i].register_idx, (e[i].mask >> 8) & 0xff, e[i].mask & 0xff); + } + + s->elements = e; + s->element_count = count; + s->string_data = string_data; + + return S_OK; +} + +void shader_free_signature(struct wined3d_shader_signature *s) +{ + HeapFree(GetProcessHeap(), 0, s->string_data); + HeapFree(GetProcessHeap(), 0, s->elements); +} + /* IUnknown methods */ static HRESULT STDMETHODCALLTYPE d3d10_vertex_shader_QueryInterface(ID3D10VertexShader *iface, @@ -282,6 +362,8 @@ static ULONG STDMETHODCALLTYPE d3d10_pixel_shader_Release(ID3D10PixelShader *ifa if (!refcount) { + IWineD3DPixelShader_Release(This->wined3d_shader); + shader_free_signature(&This->output_signature); HeapFree(GetProcessHeap(), 0, This); } diff --git a/dlls/d3d8/device.c b/dlls/d3d8/device.c index f5ab8b3a73a..206697d99d4 100644 --- a/dlls/d3d8/device.c +++ b/dlls/d3d8/device.c @@ -2166,7 +2166,7 @@ static HRESULT WINAPI IDirect3DDevice8Impl_CreatePixelShader(LPDIRECT3DDEVICE8 i EnterCriticalSection(&d3d8_cs); hr = IWineD3DDevice_CreatePixelShader(This->WineD3DDevice, pFunction, - &object->wineD3DPixelShader, (IUnknown *)object); + NULL, &object->wineD3DPixelShader, (IUnknown *)object); if (FAILED(hr)) { LeaveCriticalSection(&d3d8_cs); diff --git a/dlls/d3d9/pixelshader.c b/dlls/d3d9/pixelshader.c index 9c528d9dba4..3939f5977a8 100644 --- a/dlls/d3d9/pixelshader.c +++ b/dlls/d3d9/pixelshader.c @@ -128,7 +128,8 @@ HRESULT WINAPI IDirect3DDevice9Impl_CreatePixelShader(LPDIRECT3DDEVICE9EX iface, object->ref = 1; object->lpVtbl = &Direct3DPixelShader9_Vtbl; EnterCriticalSection(&d3d9_cs); - hrc = IWineD3DDevice_CreatePixelShader(This->WineD3DDevice, pFunction, &object->wineD3DPixelShader , (IUnknown *)object); + hrc = IWineD3DDevice_CreatePixelShader(This->WineD3DDevice, pFunction, NULL, + &object->wineD3DPixelShader, (IUnknown *)object); LeaveCriticalSection(&d3d9_cs); if (hrc != D3D_OK) { diff --git a/dlls/d3dx8/tests/mesh.c b/dlls/d3dx8/tests/mesh.c index c16ee15db70..04e8bf2e325 100644 --- a/dlls/d3dx8/tests/mesh.c +++ b/dlls/d3dx8/tests/mesh.c @@ -32,7 +32,7 @@ static BOOL compare(FLOAT u, FLOAT v) return (fabs(u-v) < admitted_error); } -BOOL compare_vec3(D3DXVECTOR3 u, D3DXVECTOR3 v) +static BOOL compare_vec3(D3DXVECTOR3 u, D3DXVECTOR3 v) { return ( compare(u.x, v.x) && compare(u.y, v.y) && compare(u.z, v.z) ); } diff --git a/dlls/d3dxof/tests/d3dxof.c b/dlls/d3dxof/tests/d3dxof.c index 71dda869e92..aec29b048b9 100644 --- a/dlls/d3dxof/tests/d3dxof.c +++ b/dlls/d3dxof/tests/d3dxof.c @@ -151,10 +151,10 @@ static void process_data(LPDIRECTXFILEDATA lpDirectXFileData, int* plevel) char str_clsid_type[40]; DWORD len= 100; LPDIRECTXFILEOBJECT pChildObj; - int i,k; + int i; int j = 0; LPBYTE pData; - DWORD size; + DWORD k, size; hr = IDirectXFileData_GetId(lpDirectXFileData, &clsid); ok(hr == DXFILE_OK, "IDirectXFileData_GetId: %x\n", hr); diff --git a/dlls/ddraw/tests/ddrawmodes.c b/dlls/ddraw/tests/ddrawmodes.c index e0bf526ac49..03ac6732bb1 100644 --- a/dlls/ddraw/tests/ddrawmodes.c +++ b/dlls/ddraw/tests/ddrawmodes.c @@ -92,16 +92,16 @@ static void releasedirectdraw(void) static void adddisplaymode(LPDDSURFACEDESC lpddsd) { if (!modes) - modes = malloc((modes_size = 2) * sizeof(DDSURFACEDESC)); + modes = HeapAlloc(GetProcessHeap(), 0, (modes_size = 2) * sizeof(DDSURFACEDESC)); if (modes_cnt == modes_size) - modes = realloc(modes, (modes_size *= 2) * sizeof(DDSURFACEDESC)); + modes = HeapReAlloc(GetProcessHeap(), 0, modes, (modes_size *= 2) * sizeof(DDSURFACEDESC)); assert(modes); modes[modes_cnt++] = *lpddsd; } static void flushdisplaymodes(void) { - free(modes); + HeapFree(GetProcessHeap(), 0, modes); modes = 0; modes_cnt = modes_size = 0; } diff --git a/dlls/dplayx/dplayx_global.c b/dlls/dplayx/dplayx_global.c index 938ade98082..9035902f826 100644 --- a/dlls/dplayx/dplayx_global.c +++ b/dlls/dplayx/dplayx_global.c @@ -174,19 +174,181 @@ static DPLAYX_LOBBYDATA* lobbyData = NULL; static DPSESSIONDESC2* sessionData = NULL; /* static DPSESSIONDESC2* sessionData[ numSupportedSessions ]; */ -/* Function prototypes */ -static DWORD DPLAYX_SizeOfLobbyDataA( const DPLCONNECTION *lpDplData ); -static DWORD DPLAYX_SizeOfLobbyDataW( const DPLCONNECTION *lpDplData ); -static void DPLAYX_CopyConnStructA( LPDPLCONNECTION dest, const DPLCONNECTION *src ); -static void DPLAYX_CopyConnStructW( LPDPLCONNECTION dest, const DPLCONNECTION *src ); -static BOOL DPLAYX_IsAppIdLobbied( DWORD dwAppId, LPDPLAYX_LOBBYDATA* dplData ); -static void DPLAYX_InitializeLobbyDataEntry( LPDPLAYX_LOBBYDATA lpData ); -static BOOL DPLAYX_CopyIntoSessionDesc2A( LPDPSESSIONDESC2 lpSessionDest, - LPCDPSESSIONDESC2 lpSessionSrc ); -static BOOL DPLAYX_GetThisLobbyHandles( LPHANDLE lphStart, LPHANDLE lphDeath, - LPHANDLE lphConnRead, BOOL bClearSetHandles ); +static void DPLAYX_InitializeLobbyDataEntry( LPDPLAYX_LOBBYDATA lpData ) +{ + ZeroMemory( lpData, sizeof( *lpData ) ); +} + +/* NOTE: This must be called with the semaphore acquired. + * TRUE/FALSE with a pointer to it's data returned. Pointer data is + * is only valid if TRUE is returned. + */ +static BOOL DPLAYX_IsAppIdLobbied( DWORD dwAppID, LPDPLAYX_LOBBYDATA* lplpDplData ) +{ + UINT i; + + *lplpDplData = NULL; + + if( dwAppID == 0 ) + { + dwAppID = GetCurrentProcessId(); + TRACE( "Translated dwAppID == 0 into 0x%08x\n", dwAppID ); + } + + for( i=0; i < numSupportedLobbies; i++ ) + { + if( lobbyData[ i ].dwAppID == dwAppID ) + { + /* This process is lobbied */ + TRACE( "Found 0x%08x @ %u\n", dwAppID, i ); + *lplpDplData = &lobbyData[ i ]; + return TRUE; + } + } + + return FALSE; +} + +/* Reserve a spot for the new application. TRUE means success and FALSE failure. */ +BOOL DPLAYX_CreateLobbyApplication( DWORD dwAppID ) +{ + UINT i; + + /* 0 is the marker for unused application data slots */ + if( dwAppID == 0 ) + { + return FALSE; + } + + DPLAYX_AcquireSemaphore(); + + /* Find an empty space in the list and insert the data */ + for( i=0; i < numSupportedLobbies; i++ ) + { + if( lobbyData[ i ].dwAppID == 0 ) + { + /* This process is now lobbied */ + TRACE( "Setting lobbyData[%u] for (0x%08x,0x%08x)\n", + i, dwAppID, GetCurrentProcessId() ); + + lobbyData[ i ].dwAppID = dwAppID; + lobbyData[ i ].dwAppLaunchedFromID = GetCurrentProcessId(); + + /* FIXME: Where is the best place for this? In interface or here? */ + lobbyData[ i ].hInformOnAppStart = 0; + lobbyData[ i ].hInformOnAppDeath = 0; + lobbyData[ i ].hInformOnSettingRead = 0; + + DPLAYX_ReleaseSemaphore(); + return TRUE; + } + } + + ERR( "No empty lobbies\n" ); + + DPLAYX_ReleaseSemaphore(); + return FALSE; +} + +BOOL DPLAYX_SetLobbyHandles( DWORD dwAppID, + HANDLE hStart, HANDLE hDeath, HANDLE hConnRead ) +{ + LPDPLAYX_LOBBYDATA lpLData; + + /* Need to explicitly give lobby application. Can't set for yourself */ + if( dwAppID == 0 ) + { + return FALSE; + } + + DPLAYX_AcquireSemaphore(); + + if( !DPLAYX_IsAppIdLobbied( dwAppID, &lpLData ) ) + { + DPLAYX_ReleaseSemaphore(); + return FALSE; + } + + lpLData->hInformOnAppStart = hStart; + lpLData->hInformOnAppDeath = hDeath; + lpLData->hInformOnSettingRead = hConnRead; + + DPLAYX_ReleaseSemaphore(); + + return TRUE; +} + +static BOOL DPLAYX_GetThisLobbyHandles( LPHANDLE lphStart, + LPHANDLE lphDeath, + LPHANDLE lphConnRead, + BOOL bClearSetHandles ) +{ + LPDPLAYX_LOBBYDATA lpLData; + + DPLAYX_AcquireSemaphore(); + + if( !DPLAYX_IsAppIdLobbied( 0, &lpLData ) ) + { + DPLAYX_ReleaseSemaphore(); + return FALSE; + } + if( lphStart != NULL ) + { + if( lpLData->hInformOnAppStart == 0 ) + { + DPLAYX_ReleaseSemaphore(); + return FALSE; + } + + *lphStart = lpLData->hInformOnAppStart; + + if( bClearSetHandles ) + { + CloseHandle( lpLData->hInformOnAppStart ); + lpLData->hInformOnAppStart = 0; + } + } + + if( lphDeath != NULL ) + { + if( lpLData->hInformOnAppDeath == 0 ) + { + DPLAYX_ReleaseSemaphore(); + return FALSE; + } + + *lphDeath = lpLData->hInformOnAppDeath; + + if( bClearSetHandles ) + { + CloseHandle( lpLData->hInformOnAppDeath ); + lpLData->hInformOnAppDeath = 0; + } + } + + if( lphConnRead != NULL ) + { + if( lpLData->hInformOnSettingRead == 0 ) + { + DPLAYX_ReleaseSemaphore(); + return FALSE; + } + + *lphConnRead = lpLData->hInformOnSettingRead; + + if( bClearSetHandles ) + { + CloseHandle( lpLData->hInformOnSettingRead ); + lpLData->hInformOnSettingRead = 0; + } + } + + DPLAYX_ReleaseSemaphore(); + + return TRUE; +} /*************************************************************************** * Called to initialize the global data. This will only be used on the @@ -272,7 +434,7 @@ BOOL DPLAYX_ConstructData(void) else { /* Presently the shared data structures use pointers. If the - * files are no mapped into the same area, the pointers will no + * files are not mapped into the same area, the pointers will no * longer make any sense :( * FIXME: In the future make the shared data structures have some * sort of fixup to make them independent between data spaces. @@ -374,182 +536,241 @@ BOOL DPLAYX_DestructData(void) } -void DPLAYX_InitializeLobbyDataEntry( LPDPLAYX_LOBBYDATA lpData ) +/* Assumption: Enough contiguous space was allocated at dest */ +static void DPLAYX_CopyConnStructA( LPDPLCONNECTION dest, const DPLCONNECTION *src ) { - ZeroMemory( lpData, sizeof( *lpData ) ); -} + BYTE* lpStartOfFreeSpace; -/* NOTE: This must be called with the semaphore acquired. - * TRUE/FALSE with a pointer to it's data returned. Pointer data is - * is only valid if TRUE is returned. - */ -BOOL DPLAYX_IsAppIdLobbied( DWORD dwAppID, LPDPLAYX_LOBBYDATA* lplpDplData ) -{ - UINT i; + *dest = *src; - *lplpDplData = NULL; + lpStartOfFreeSpace = ((BYTE*)dest) + sizeof( DPLCONNECTION ); - if( dwAppID == 0 ) + /* Copy the LPDPSESSIONDESC2 structure if it exists */ + if( src->lpSessionDesc ) { - dwAppID = GetCurrentProcessId(); - TRACE( "Translated dwAppID == 0 into 0x%08x\n", dwAppID ); + dest->lpSessionDesc = (LPDPSESSIONDESC2)lpStartOfFreeSpace; + lpStartOfFreeSpace += sizeof( DPSESSIONDESC2 ); + *dest->lpSessionDesc = *src->lpSessionDesc; + + /* Session names may or may not exist */ + if( src->lpSessionDesc->u1.lpszSessionNameA ) + { + strcpy( (LPSTR)lpStartOfFreeSpace, src->lpSessionDesc->u1.lpszSessionNameA ); + dest->lpSessionDesc->u1.lpszSessionNameA = (LPSTR)lpStartOfFreeSpace; + lpStartOfFreeSpace += + strlen( dest->lpSessionDesc->u1.lpszSessionNameA ) + 1; + } + + if( src->lpSessionDesc->u2.lpszPasswordA ) + { + strcpy( (LPSTR)lpStartOfFreeSpace, src->lpSessionDesc->u2.lpszPasswordA ); + dest->lpSessionDesc->u2.lpszPasswordA = (LPSTR)lpStartOfFreeSpace; + lpStartOfFreeSpace += + strlen( dest->lpSessionDesc->u2.lpszPasswordA ) + 1; + } } - for( i=0; i < numSupportedLobbies; i++ ) + /* DPNAME structure is optional */ + if( src->lpPlayerName ) { - if( lobbyData[ i ].dwAppID == dwAppID ) + dest->lpPlayerName = (LPDPNAME)lpStartOfFreeSpace; + lpStartOfFreeSpace += sizeof( DPNAME ); + *dest->lpPlayerName = *src->lpPlayerName; + + if( src->lpPlayerName->u1.lpszShortNameA ) { - /* This process is lobbied */ - TRACE( "Found 0x%08x @ %u\n", dwAppID, i ); - *lplpDplData = &lobbyData[ i ]; - return TRUE; + strcpy( (LPSTR)lpStartOfFreeSpace, src->lpPlayerName->u1.lpszShortNameA ); + dest->lpPlayerName->u1.lpszShortNameA = (LPSTR)lpStartOfFreeSpace; + lpStartOfFreeSpace += + strlen( dest->lpPlayerName->u1.lpszShortNameA ) + 1; } + + if( src->lpPlayerName->u2.lpszLongNameA ) + { + strcpy( (LPSTR)lpStartOfFreeSpace, src->lpPlayerName->u2.lpszLongNameA ); + dest->lpPlayerName->u2.lpszLongNameA = (LPSTR)lpStartOfFreeSpace; + lpStartOfFreeSpace += + strlen( (LPSTR)dest->lpPlayerName->u2.lpszLongName ) + 1 ; + } + } - return FALSE; + /* Copy address if it exists */ + if( src->lpAddress ) + { + dest->lpAddress = lpStartOfFreeSpace; + CopyMemory( lpStartOfFreeSpace, src->lpAddress, src->dwAddressSize ); + /* No need to advance lpStartOfFreeSpace as there is no more "dynamic" data */ + } } -/* Reserve a spot for the new application. TRUE means success and FALSE failure. */ -BOOL DPLAYX_CreateLobbyApplication( DWORD dwAppID ) +/* Assumption: Enough contiguous space was allocated at dest */ +static void DPLAYX_CopyConnStructW( LPDPLCONNECTION dest, const DPLCONNECTION *src ) { - UINT i; + BYTE* lpStartOfFreeSpace; - /* 0 is the marker for unused application data slots */ - if( dwAppID == 0 ) - { - return FALSE; - } + *dest = *src; - DPLAYX_AcquireSemaphore(); + lpStartOfFreeSpace = ( (BYTE*)dest) + sizeof( DPLCONNECTION ); - /* Find an empty space in the list and insert the data */ - for( i=0; i < numSupportedLobbies; i++ ) + /* Copy the LPDPSESSIONDESC2 structure if it exists */ + if( src->lpSessionDesc ) { - if( lobbyData[ i ].dwAppID == 0 ) - { - /* This process is now lobbied */ - TRACE( "Setting lobbyData[%u] for (0x%08x,0x%08x)\n", - i, dwAppID, GetCurrentProcessId() ); - - lobbyData[ i ].dwAppID = dwAppID; - lobbyData[ i ].dwAppLaunchedFromID = GetCurrentProcessId(); + dest->lpSessionDesc = (LPDPSESSIONDESC2)lpStartOfFreeSpace; + lpStartOfFreeSpace += sizeof( DPSESSIONDESC2 ); + *dest->lpSessionDesc = *src->lpSessionDesc; - /* FIXME: Where is the best place for this? In interface or here? */ - lobbyData[ i ].hInformOnAppStart = 0; - lobbyData[ i ].hInformOnAppDeath = 0; - lobbyData[ i ].hInformOnSettingRead = 0; + /* Session names may or may not exist */ + if( src->lpSessionDesc->u1.lpszSessionName ) + { + strcpyW( (LPWSTR)lpStartOfFreeSpace, src->lpSessionDesc->u1.lpszSessionName ); + dest->lpSessionDesc->u1.lpszSessionName = (LPWSTR)lpStartOfFreeSpace; + lpStartOfFreeSpace += sizeof(WCHAR) * + ( strlenW( dest->lpSessionDesc->u1.lpszSessionName ) + 1 ); + } - DPLAYX_ReleaseSemaphore(); - return TRUE; + if( src->lpSessionDesc->u2.lpszPassword ) + { + strcpyW( (LPWSTR)lpStartOfFreeSpace, src->lpSessionDesc->u2.lpszPassword ); + dest->lpSessionDesc->u2.lpszPassword = (LPWSTR)lpStartOfFreeSpace; + lpStartOfFreeSpace += sizeof(WCHAR) * + ( strlenW( dest->lpSessionDesc->u2.lpszPassword ) + 1 ); } } - ERR( "No empty lobbies\n" ); + /* DPNAME structure is optional */ + if( src->lpPlayerName ) + { + dest->lpPlayerName = (LPDPNAME)lpStartOfFreeSpace; + lpStartOfFreeSpace += sizeof( DPNAME ); + *dest->lpPlayerName = *src->lpPlayerName; - DPLAYX_ReleaseSemaphore(); - return FALSE; -} + if( src->lpPlayerName->u1.lpszShortName ) + { + strcpyW( (LPWSTR)lpStartOfFreeSpace, src->lpPlayerName->u1.lpszShortName ); + dest->lpPlayerName->u1.lpszShortName = (LPWSTR)lpStartOfFreeSpace; + lpStartOfFreeSpace += sizeof(WCHAR) * + ( strlenW( dest->lpPlayerName->u1.lpszShortName ) + 1 ); + } -BOOL DPLAYX_SetLobbyHandles( DWORD dwAppID, - HANDLE hStart, HANDLE hDeath, HANDLE hConnRead ) -{ - LPDPLAYX_LOBBYDATA lpLData; + if( src->lpPlayerName->u2.lpszLongName ) + { + strcpyW( (LPWSTR)lpStartOfFreeSpace, src->lpPlayerName->u2.lpszLongName ); + dest->lpPlayerName->u2.lpszLongName = (LPWSTR)lpStartOfFreeSpace; + lpStartOfFreeSpace += sizeof(WCHAR) * + ( strlenW( dest->lpPlayerName->u2.lpszLongName ) + 1 ); + } - /* Need to explicitly give lobby application. Can't set for yourself */ - if( dwAppID == 0 ) - { - return FALSE; } - DPLAYX_AcquireSemaphore(); - - if( !DPLAYX_IsAppIdLobbied( dwAppID, &lpLData ) ) + /* Copy address if it exists */ + if( src->lpAddress ) { - DPLAYX_ReleaseSemaphore(); - return FALSE; + dest->lpAddress = lpStartOfFreeSpace; + CopyMemory( lpStartOfFreeSpace, src->lpAddress, src->dwAddressSize ); + /* No need to advance lpStartOfFreeSpace as there is no more "dynamic" data */ } - lpLData->hInformOnAppStart = hStart; - lpLData->hInformOnAppDeath = hDeath; - lpLData->hInformOnSettingRead = hConnRead; - - DPLAYX_ReleaseSemaphore(); - - return TRUE; } -static BOOL DPLAYX_GetThisLobbyHandles( LPHANDLE lphStart, - LPHANDLE lphDeath, - LPHANDLE lphConnRead, - BOOL bClearSetHandles ) +static DWORD DPLAYX_SizeOfLobbyDataA( const DPLCONNECTION *lpConn ) { - LPDPLAYX_LOBBYDATA lpLData; - - DPLAYX_AcquireSemaphore(); + DWORD dwTotalSize = sizeof( DPLCONNECTION ); - if( !DPLAYX_IsAppIdLobbied( 0, &lpLData ) ) + /* Just a safety check */ + if( lpConn == NULL ) { - DPLAYX_ReleaseSemaphore(); - return FALSE; + ERR( "lpConn is NULL\n" ); + return 0; } - if( lphStart != NULL ) + if( lpConn->lpSessionDesc != NULL ) { - if( lpLData->hInformOnAppStart == 0 ) + dwTotalSize += sizeof( DPSESSIONDESC2 ); + + if( lpConn->lpSessionDesc->u1.lpszSessionNameA ) { - DPLAYX_ReleaseSemaphore(); - return FALSE; + dwTotalSize += strlen( lpConn->lpSessionDesc->u1.lpszSessionNameA ) + 1; } - *lphStart = lpLData->hInformOnAppStart; - - if( bClearSetHandles ) + if( lpConn->lpSessionDesc->u2.lpszPasswordA ) { - CloseHandle( lpLData->hInformOnAppStart ); - lpLData->hInformOnAppStart = 0; + dwTotalSize += strlen( lpConn->lpSessionDesc->u2.lpszPasswordA ) + 1; } } - if( lphDeath != NULL ) + if( lpConn->lpPlayerName != NULL ) { - if( lpLData->hInformOnAppDeath == 0 ) + dwTotalSize += sizeof( DPNAME ); + + if( lpConn->lpPlayerName->u1.lpszShortNameA ) { - DPLAYX_ReleaseSemaphore(); - return FALSE; + dwTotalSize += strlen( lpConn->lpPlayerName->u1.lpszShortNameA ) + 1; } - *lphDeath = lpLData->hInformOnAppDeath; + if( lpConn->lpPlayerName->u2.lpszLongNameA ) + { + dwTotalSize += strlen( lpConn->lpPlayerName->u2.lpszLongNameA ) + 1; + } - if( bClearSetHandles ) + } + + dwTotalSize += lpConn->dwAddressSize; + + return dwTotalSize; +} + +static DWORD DPLAYX_SizeOfLobbyDataW( const DPLCONNECTION *lpConn ) +{ + DWORD dwTotalSize = sizeof( DPLCONNECTION ); + + /* Just a safety check */ + if( lpConn == NULL ) + { + ERR( "lpConn is NULL\n" ); + return 0; + } + + if( lpConn->lpSessionDesc != NULL ) + { + dwTotalSize += sizeof( DPSESSIONDESC2 ); + + if( lpConn->lpSessionDesc->u1.lpszSessionName ) { - CloseHandle( lpLData->hInformOnAppDeath ); - lpLData->hInformOnAppDeath = 0; + dwTotalSize += sizeof( WCHAR ) * + ( strlenW( lpConn->lpSessionDesc->u1.lpszSessionName ) + 1 ); + } + + if( lpConn->lpSessionDesc->u2.lpszPassword ) + { + dwTotalSize += sizeof( WCHAR ) * + ( strlenW( lpConn->lpSessionDesc->u2.lpszPassword ) + 1 ); } } - if( lphConnRead != NULL ) + if( lpConn->lpPlayerName != NULL ) { - if( lpLData->hInformOnSettingRead == 0 ) + dwTotalSize += sizeof( DPNAME ); + + if( lpConn->lpPlayerName->u1.lpszShortName ) { - DPLAYX_ReleaseSemaphore(); - return FALSE; + dwTotalSize += sizeof( WCHAR ) * + ( strlenW( lpConn->lpPlayerName->u1.lpszShortName ) + 1 ); } - *lphConnRead = lpLData->hInformOnSettingRead; - - if( bClearSetHandles ) + if( lpConn->lpPlayerName->u2.lpszLongName ) { - CloseHandle( lpLData->hInformOnSettingRead ); - lpLData->hInformOnSettingRead = 0; + dwTotalSize += sizeof( WCHAR ) * + ( strlenW( lpConn->lpPlayerName->u2.lpszLongName ) + 1 ); } + } - DPLAYX_ReleaseSemaphore(); + dwTotalSize += lpConn->dwAddressSize; - return TRUE; + return dwTotalSize; } - HRESULT DPLAYX_GetConnectionSettingsA ( DWORD dwAppID, LPVOID lpData, @@ -606,74 +827,6 @@ HRESULT DPLAYX_GetConnectionSettingsA return DP_OK; } -/* Assumption: Enough contiguous space was allocated at dest */ -void DPLAYX_CopyConnStructA( LPDPLCONNECTION dest, const DPLCONNECTION *src ) -{ - BYTE* lpStartOfFreeSpace; - - *dest = *src; - - lpStartOfFreeSpace = ((BYTE*)dest) + sizeof( DPLCONNECTION ); - - /* Copy the LPDPSESSIONDESC2 structure if it exists */ - if( src->lpSessionDesc ) - { - dest->lpSessionDesc = (LPDPSESSIONDESC2)lpStartOfFreeSpace; - lpStartOfFreeSpace += sizeof( DPSESSIONDESC2 ); - *dest->lpSessionDesc = *src->lpSessionDesc; - - /* Session names may or may not exist */ - if( src->lpSessionDesc->u1.lpszSessionNameA ) - { - strcpy( (LPSTR)lpStartOfFreeSpace, src->lpSessionDesc->u1.lpszSessionNameA ); - dest->lpSessionDesc->u1.lpszSessionNameA = (LPSTR)lpStartOfFreeSpace; - lpStartOfFreeSpace += - strlen( dest->lpSessionDesc->u1.lpszSessionNameA ) + 1; - } - - if( src->lpSessionDesc->u2.lpszPasswordA ) - { - strcpy( (LPSTR)lpStartOfFreeSpace, src->lpSessionDesc->u2.lpszPasswordA ); - dest->lpSessionDesc->u2.lpszPasswordA = (LPSTR)lpStartOfFreeSpace; - lpStartOfFreeSpace += - strlen( dest->lpSessionDesc->u2.lpszPasswordA ) + 1; - } - } - - /* DPNAME structure is optional */ - if( src->lpPlayerName ) - { - dest->lpPlayerName = (LPDPNAME)lpStartOfFreeSpace; - lpStartOfFreeSpace += sizeof( DPNAME ); - *dest->lpPlayerName = *src->lpPlayerName; - - if( src->lpPlayerName->u1.lpszShortNameA ) - { - strcpy( (LPSTR)lpStartOfFreeSpace, src->lpPlayerName->u1.lpszShortNameA ); - dest->lpPlayerName->u1.lpszShortNameA = (LPSTR)lpStartOfFreeSpace; - lpStartOfFreeSpace += - strlen( dest->lpPlayerName->u1.lpszShortNameA ) + 1; - } - - if( src->lpPlayerName->u2.lpszLongNameA ) - { - strcpy( (LPSTR)lpStartOfFreeSpace, src->lpPlayerName->u2.lpszLongNameA ); - dest->lpPlayerName->u2.lpszLongNameA = (LPSTR)lpStartOfFreeSpace; - lpStartOfFreeSpace += - strlen( (LPSTR)dest->lpPlayerName->u2.lpszLongName ) + 1 ; - } - - } - - /* Copy address if it exists */ - if( src->lpAddress ) - { - dest->lpAddress = lpStartOfFreeSpace; - CopyMemory( lpStartOfFreeSpace, src->lpAddress, src->dwAddressSize ); - /* No need to advance lpStartOfFreeSpace as there is no more "dynamic" data */ - } -} - HRESULT DPLAYX_GetConnectionSettingsW ( DWORD dwAppID, LPVOID lpData, @@ -728,75 +881,6 @@ HRESULT DPLAYX_GetConnectionSettingsW return DP_OK; } -/* Assumption: Enough contiguous space was allocated at dest */ -void DPLAYX_CopyConnStructW( LPDPLCONNECTION dest, const DPLCONNECTION *src ) -{ - BYTE* lpStartOfFreeSpace; - - *dest = *src; - - lpStartOfFreeSpace = ( (BYTE*)dest) + sizeof( DPLCONNECTION ); - - /* Copy the LPDPSESSIONDESC2 structure if it exists */ - if( src->lpSessionDesc ) - { - dest->lpSessionDesc = (LPDPSESSIONDESC2)lpStartOfFreeSpace; - lpStartOfFreeSpace += sizeof( DPSESSIONDESC2 ); - *dest->lpSessionDesc = *src->lpSessionDesc; - - /* Session names may or may not exist */ - if( src->lpSessionDesc->u1.lpszSessionName ) - { - strcpyW( (LPWSTR)lpStartOfFreeSpace, src->lpSessionDesc->u1.lpszSessionName ); - dest->lpSessionDesc->u1.lpszSessionName = (LPWSTR)lpStartOfFreeSpace; - lpStartOfFreeSpace += sizeof(WCHAR) * - ( strlenW( dest->lpSessionDesc->u1.lpszSessionName ) + 1 ); - } - - if( src->lpSessionDesc->u2.lpszPassword ) - { - strcpyW( (LPWSTR)lpStartOfFreeSpace, src->lpSessionDesc->u2.lpszPassword ); - dest->lpSessionDesc->u2.lpszPassword = (LPWSTR)lpStartOfFreeSpace; - lpStartOfFreeSpace += sizeof(WCHAR) * - ( strlenW( dest->lpSessionDesc->u2.lpszPassword ) + 1 ); - } - } - - /* DPNAME structure is optional */ - if( src->lpPlayerName ) - { - dest->lpPlayerName = (LPDPNAME)lpStartOfFreeSpace; - lpStartOfFreeSpace += sizeof( DPNAME ); - *dest->lpPlayerName = *src->lpPlayerName; - - if( src->lpPlayerName->u1.lpszShortName ) - { - strcpyW( (LPWSTR)lpStartOfFreeSpace, src->lpPlayerName->u1.lpszShortName ); - dest->lpPlayerName->u1.lpszShortName = (LPWSTR)lpStartOfFreeSpace; - lpStartOfFreeSpace += sizeof(WCHAR) * - ( strlenW( dest->lpPlayerName->u1.lpszShortName ) + 1 ); - } - - if( src->lpPlayerName->u2.lpszLongName ) - { - strcpyW( (LPWSTR)lpStartOfFreeSpace, src->lpPlayerName->u2.lpszLongName ); - dest->lpPlayerName->u2.lpszLongName = (LPWSTR)lpStartOfFreeSpace; - lpStartOfFreeSpace += sizeof(WCHAR) * - ( strlenW( dest->lpPlayerName->u2.lpszLongName ) + 1 ); - } - - } - - /* Copy address if it exists */ - if( src->lpAddress ) - { - dest->lpAddress = lpStartOfFreeSpace; - CopyMemory( lpStartOfFreeSpace, src->lpAddress, src->dwAddressSize ); - /* No need to advance lpStartOfFreeSpace as there is no more "dynamic" data */ - } - -} - /* Store the structure into the shared data structure. Ensure that allocs for * variable length strings come from the shared data structure. * FIXME: We need to free information as well. @@ -911,108 +995,10 @@ HRESULT DPLAYX_SetConnectionSettingsW return DP_OK; } -DWORD DPLAYX_SizeOfLobbyDataA( const DPLCONNECTION *lpConn ) -{ - DWORD dwTotalSize = sizeof( DPLCONNECTION ); - - /* Just a safety check */ - if( lpConn == NULL ) - { - ERR( "lpConn is NULL\n" ); - return 0; - } - - if( lpConn->lpSessionDesc != NULL ) - { - dwTotalSize += sizeof( DPSESSIONDESC2 ); - - if( lpConn->lpSessionDesc->u1.lpszSessionNameA ) - { - dwTotalSize += strlen( lpConn->lpSessionDesc->u1.lpszSessionNameA ) + 1; - } - - if( lpConn->lpSessionDesc->u2.lpszPasswordA ) - { - dwTotalSize += strlen( lpConn->lpSessionDesc->u2.lpszPasswordA ) + 1; - } - } - - if( lpConn->lpPlayerName != NULL ) - { - dwTotalSize += sizeof( DPNAME ); - - if( lpConn->lpPlayerName->u1.lpszShortNameA ) - { - dwTotalSize += strlen( lpConn->lpPlayerName->u1.lpszShortNameA ) + 1; - } - - if( lpConn->lpPlayerName->u2.lpszLongNameA ) - { - dwTotalSize += strlen( lpConn->lpPlayerName->u2.lpszLongNameA ) + 1; - } - - } - - dwTotalSize += lpConn->dwAddressSize; - - return dwTotalSize; -} - -DWORD DPLAYX_SizeOfLobbyDataW( const DPLCONNECTION *lpConn ) -{ - DWORD dwTotalSize = sizeof( DPLCONNECTION ); - - /* Just a safety check */ - if( lpConn == NULL ) - { - ERR( "lpConn is NULL\n" ); - return 0; - } - - if( lpConn->lpSessionDesc != NULL ) - { - dwTotalSize += sizeof( DPSESSIONDESC2 ); - - if( lpConn->lpSessionDesc->u1.lpszSessionName ) - { - dwTotalSize += sizeof( WCHAR ) * - ( strlenW( lpConn->lpSessionDesc->u1.lpszSessionName ) + 1 ); - } - - if( lpConn->lpSessionDesc->u2.lpszPassword ) - { - dwTotalSize += sizeof( WCHAR ) * - ( strlenW( lpConn->lpSessionDesc->u2.lpszPassword ) + 1 ); - } - } - - if( lpConn->lpPlayerName != NULL ) - { - dwTotalSize += sizeof( DPNAME ); - - if( lpConn->lpPlayerName->u1.lpszShortName ) - { - dwTotalSize += sizeof( WCHAR ) * - ( strlenW( lpConn->lpPlayerName->u1.lpszShortName ) + 1 ); - } - - if( lpConn->lpPlayerName->u2.lpszLongName ) - { - dwTotalSize += sizeof( WCHAR ) * - ( strlenW( lpConn->lpPlayerName->u2.lpszLongName ) + 1 ); - } - - } - - dwTotalSize += lpConn->dwAddressSize; - - return dwTotalSize; -} - /* Copy an ANSI session desc structure to the given buffer */ -BOOL DPLAYX_CopyIntoSessionDesc2A( LPDPSESSIONDESC2 lpSessionDest, +static BOOL DPLAYX_CopyIntoSessionDesc2A( LPDPSESSIONDESC2 lpSessionDest, LPCDPSESSIONDESC2 lpSessionSrc ) { CopyMemory( lpSessionDest, lpSessionSrc, sizeof( *lpSessionSrc ) ); diff --git a/dlls/dplayx/dplayx_messages.c b/dlls/dplayx/dplayx_messages.c index 181e6b08198..2e34950ded7 100644 --- a/dlls/dplayx/dplayx_messages.c +++ b/dlls/dplayx/dplayx_messages.c @@ -329,11 +329,7 @@ HRESULT DP_MSG_ForwardPlayerCreation( IDirectPlay2AImpl* This, DPID dpidServer ) lpMsgBody->unknown4[5] = 0x0; lpMsgBody->unknown4[6] = 0x0; -#if 0 - lpMsgBody->unknown4[7] = NS_GetOtherMagic( This->dp2->lpNameServerData ) -#else lpMsgBody->unknown4[7] = NS_GetNsMagic( This->dp2->lpNameServerData ); -#endif TRACE( "Setting second magic to 0x%08x\n", lpMsgBody->unknown4[7] ); lpMsgBody->unknown4[8] = 0x0; diff --git a/dlls/dplayx/name_server.c b/dlls/dplayx/name_server.c index e6a6b621d9d..58402cc12de 100644 --- a/dlls/dplayx/name_server.c +++ b/dlls/dplayx/name_server.c @@ -183,14 +183,6 @@ DWORD NS_GetNsMagic( LPVOID lpNSInfo ) return lpHdrInfo[1]; } -/* Get the magic number associated with the non NS end */ -DWORD NS_GetOtherMagic( LPVOID lpNSInfo ) -{ - lpNSCache lpCache = (lpNSCache)lpNSInfo; - - return ((LPDWORD)lpCache->lpLocalAddrHdr)[1]; -} - void NS_SetLocalAddr( LPVOID lpNSInfo, LPCVOID lpHdr, DWORD dwHdrSize ) { lpNSCache lpCache = (lpNSCache)lpNSInfo; diff --git a/dlls/dplayx/name_server.h b/dlls/dplayx/name_server.h index 9c09ec60a7d..c9df0c0de29 100644 --- a/dlls/dplayx/name_server.h +++ b/dlls/dplayx/name_server.h @@ -35,7 +35,6 @@ void NS_AddRemoteComputerAsNameServer( LPCVOID lpNSAddrHdr, LPVOID lpNSInfo ); LPVOID NS_GetNSAddr( LPVOID lpNSInfo ); DWORD NS_GetNsMagic( LPVOID lpNSInfo ); -DWORD NS_GetOtherMagic( LPVOID lpNSInfo ); void NS_SetLocalAddr( LPVOID lpNSInfo, LPCVOID lpHdr, DWORD dwHdrSize ); void NS_ReplyToEnumSessionsRequest( LPCVOID lpcMsg, diff --git a/dlls/dsound/tests/ds3d.c b/dlls/dsound/tests/ds3d.c index 8f5b88a8448..71ff2ab3908 100644 --- a/dlls/dsound/tests/ds3d.c +++ b/dlls/dsound/tests/ds3d.c @@ -48,7 +48,7 @@ char* wave_generate_la(WAVEFORMATEX* wfx, double duration, DWORD* size) nb_samples=(int)(duration*wfx->nSamplesPerSec); *size=nb_samples*wfx->nBlockAlign; - b=buf=malloc(*size); + b=buf=HeapAlloc(GetProcessHeap(), 0, *size); for (i=0;inSamplesPerSec); if (wfx->wBitsPerSample==8) { @@ -674,7 +674,7 @@ void test_buffer(LPDIRECTSOUND dso, LPDIRECTSOUNDBUFFER *dsbo, "The sound played for %d ms instead of %g ms\n", now-start_time,1000*duration); - free(state.wave); + HeapFree(GetProcessHeap(), 0, state.wave); if (is_primary) { /* Set the CooperativeLevel back to normal */ /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */ diff --git a/dlls/dsound/tests/ds3d8.c b/dlls/dsound/tests/ds3d8.c index 1f5f28a3dd7..9dfdd31bbdc 100644 --- a/dlls/dsound/tests/ds3d8.c +++ b/dlls/dsound/tests/ds3d8.c @@ -518,7 +518,7 @@ void test_buffer8(LPDIRECTSOUND8 dso, LPDIRECTSOUNDBUFFER * dsbo, "The sound played for %d ms instead of %g ms\n", now-start_time,1000*duration); - free(state.wave); + HeapFree(GetProcessHeap(), 0, state.wave); if (is_primary) { /* Set the CooperativeLevel back to normal */ /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */ diff --git a/dlls/fusion/assembly.c b/dlls/fusion/assembly.c index faef8efdd15..bc187ac91cd 100644 --- a/dlls/fusion/assembly.c +++ b/dlls/fusion/assembly.c @@ -811,12 +811,6 @@ HRESULT assembly_get_version(ASSEMBLY *assembly, LPWSTR *version) return S_OK; } -HRESULT assembly_get_architecture(ASSEMBLY *assembly, DWORD fixme) -{ - /* FIXME */ - return S_OK; -} - static BYTE *assembly_get_blob(ASSEMBLY *assembly, WORD index, ULONG *size) { return GetData(&assembly->blobs[index], size); diff --git a/dlls/fusion/fusion.c b/dlls/fusion/fusion.c index 1435743d8c9..7c94100039d 100644 --- a/dlls/fusion/fusion.c +++ b/dlls/fusion/fusion.c @@ -42,19 +42,6 @@ HRESULT WINAPI ClearDownloadCache(void) } /****************************************************************** - * CompareAssemblyIdentity (FUSION.@) - */ -HRESULT WINAPI CompareAssemblyIdentity(LPCWSTR pwzAssemblyIdentity1, BOOL fUnified1, - LPCWSTR pwzAssemblyIdentity2, BOOL fUnified2, - BOOL *pfEquivalent, AssemblyComparisonResult *pResult) -{ - FIXME("(%s, %d, %s, %d, %p, %p) stub!\n", debugstr_w(pwzAssemblyIdentity1), - fUnified1, debugstr_w(pwzAssemblyIdentity2), fUnified2, pfEquivalent, pResult); - - return E_NOTIMPL; -} - -/****************************************************************** * CreateInstallReferenceEnum (FUSION.@) */ HRESULT WINAPI CreateInstallReferenceEnum(IInstallReferenceEnum **ppRefEnum, @@ -65,18 +52,6 @@ HRESULT WINAPI CreateInstallReferenceEnum(IInstallReferenceEnum **ppRefEnum, return E_NOTIMPL; } -/****************************************************************** - * GetAssemblyIdentityFromFile (FUSION.@) - */ -HRESULT WINAPI GetAssemblyIdentityFromFile(LPCWSTR pwzFilePath, REFIID riid, - IUnknown **ppIdentity) -{ - FIXME("(%s, %s, %p) stub!\n", debugstr_w(pwzFilePath), debugstr_guid(riid), - ppIdentity); - - return E_NOTIMPL; -} - static HRESULT (WINAPI *pGetCORVersion)(LPWSTR pbuffer, DWORD cchBuffer, DWORD *dwLength); diff --git a/dlls/fusion/fusionpriv.h b/dlls/fusion/fusionpriv.h index 363d530313d..4b9bd576d5b 100644 --- a/dlls/fusion/fusionpriv.h +++ b/dlls/fusion/fusionpriv.h @@ -433,7 +433,6 @@ HRESULT assembly_release(ASSEMBLY *assembly); HRESULT assembly_get_name(ASSEMBLY *assembly, LPWSTR *name); HRESULT assembly_get_path(ASSEMBLY *assembly, LPWSTR *path); HRESULT assembly_get_version(ASSEMBLY *assembly, LPWSTR *version); -HRESULT assembly_get_architecture(ASSEMBLY *assembly, DWORD fixme); HRESULT assembly_get_pubkey_token(ASSEMBLY *assembly, LPWSTR *token); static inline LPWSTR strdupW(LPCWSTR src) diff --git a/dlls/gdi32/freetype.c b/dlls/gdi32/freetype.c index 7b0afa8760d..60c5f215e93 100644 --- a/dlls/gdi32/freetype.c +++ b/dlls/gdi32/freetype.c @@ -400,6 +400,16 @@ static const WCHAR * const SystemFontValues[4] = { static const WCHAR external_fonts_reg_key[] = {'S','o','f','t','w','a','r','e','\\','W','i','n','e','\\', 'F','o','n','t','s','\\','E','x','t','e','r','n','a','l',' ','F','o','n','t','s','\0'}; +/* Interesting and well-known (frequently-assumed!) font names */ +static const WCHAR Lucida_Sans_Unicode[] = {'L','u','c','i','d','a',' ','S','a','n','s',' ','U','n','i','c','o','d','e',0}; +static const WCHAR Microsoft_Sans_Serif[] = {'M','i','c','r','o','s','o','f','t',' ','S','a','n','s',' ','S','e','r','i','f',0 }; +static const WCHAR Tahoma[] = {'T','a','h','o','m','a',0}; +static const WCHAR MS_UI_Gothic[] = {'M','S',' ','U','I',' ','G','o','t','h','i','c',0}; +static const WCHAR SimSun[] = {'S','i','m','S','u','n',0}; +static const WCHAR Gulim[] = {'G','u','l','i','m',0}; +static const WCHAR PMingLiU[] = {'P','M','i','n','g','L','i','U',0}; +static const WCHAR Batang[] = {'B','a','t','a','n','g',0}; + static const WCHAR ArabicW[] = {'A','r','a','b','i','c','\0'}; static const WCHAR BalticW[] = {'B','a','l','t','i','c','\0'}; static const WCHAR CHINESE_BIG5W[] = {'C','H','I','N','E','S','E','_','B','I','G','5','\0'}; @@ -482,6 +492,11 @@ static BOOL use_default_fallback = FALSE; static BOOL get_glyph_index_linked(GdiFont *font, UINT c, GdiFont **linked_font, FT_UInt *glyph); +static const WCHAR system_link[] = {'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\', + 'W','i','n','d','o','w','s',' ','N','T','\\', + 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\','F','o','n','t','L','i','n','k','\\', + 'S','y','s','t','e','m','L','i','n','k',0}; + /**************************************** * Notes on .fon files * @@ -1622,10 +1637,6 @@ static void LoadReplaceList(void) */ static BOOL init_system_links(void) { - static const WCHAR system_link[] = {'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\', - 'W','i','n','d','o','w','s',' ','N','T','\\', - 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\','F','o','n','t','L','i','n','k','\\', - 'S','y','s','t','e','m','L','i','n','k',0}; HKEY hkey; BOOL ret = FALSE; DWORD type, max_val, max_data, val_len, data_len, index; @@ -1633,7 +1644,6 @@ static BOOL init_system_links(void) WCHAR *entry, *next; SYSTEM_LINKS *font_link, *system_font_link; CHILD_FONT *child_font; - static const WCHAR Tahoma[] = {'T','a','h','o','m','a',0}; static const WCHAR tahoma_ttf[] = {'t','a','h','o','m','a','.','t','t','f',0}; static const WCHAR System[] = {'S','y','s','t','e','m',0}; FONTSIGNATURE fs; @@ -2313,6 +2323,46 @@ static const struct nls_update_font_list } }; +static const WCHAR *font_links_list[] = +{ + Lucida_Sans_Unicode, + Microsoft_Sans_Serif, + Tahoma +}; + +static const struct font_links_defaults_list +{ + /* Keyed off substitution for "MS Shell Dlg" */ + const WCHAR *shelldlg; + /* Maximum of four substitutes, plus terminating NULL pointer */ + const WCHAR *substitutes[5]; +} font_links_defaults_list[] = +{ + /* Non East-Asian */ + { Tahoma, /* FIXME unverified ordering */ + { MS_UI_Gothic, SimSun, Gulim, PMingLiU, NULL } + }, + /* Below lists are courtesy of + * http://blogs.msdn.com/michkap/archive/2005/06/18/430507.aspx + */ + /* Japanese */ + { MS_UI_Gothic, + { MS_UI_Gothic, PMingLiU, SimSun, Gulim, NULL } + }, + /* Chinese Simplified */ + { SimSun, + { SimSun, PMingLiU, MS_UI_Gothic, Batang, NULL } + }, + /* Korean */ + { Gulim, + { Gulim, PMingLiU, MS_UI_Gothic, SimSun, NULL } + }, + /* Chinese Traditional */ + { PMingLiU, + { PMingLiU, SimSun, MS_UI_Gothic, Batang, NULL } + } +}; + static inline BOOL is_dbcs_ansi_cp(UINT ansi_cp) { return ( ansi_cp == 932 /* CP932 for Japanese */ @@ -2459,6 +2509,133 @@ static void update_font_info(void) } if (!done) FIXME("there is no font defaults for codepages %u,%u\n", ansi_cp, oem_cp); + + /* Clear out system links */ + RegDeleteKeyW(HKEY_LOCAL_MACHINE, system_link); +} + +static void populate_system_links(HKEY hkey, const WCHAR *name, const WCHAR *const *values) +{ + const WCHAR *value; + int i; + FontSubst *psub; + Family *family; + Face *face; + const char *file; + WCHAR *fileW; + int fileLen; + WCHAR buff[MAX_PATH]; + WCHAR *data; + int entryLen; + + static const WCHAR comma[] = {',',0}; + + RegDeleteValueW(hkey, name); + if (values) + { + data = buff; + data[0] = '\0'; + for (i = 0; values[i] != NULL; i++) + { + value = values[i]; + if (!strcmpiW(name,value)) + continue; + psub = get_font_subst(&font_subst_list, value, -1); + if(psub) + value = psub->to.name; + family = find_family_from_name(value); + if (!family) + continue; + file = NULL; + /* Use first extant filename for this Family */ + LIST_FOR_EACH_ENTRY(face, &family->faces, Face, entry) + { + if (!face->file) + continue; + file = strrchr(face->file, '/'); + if (!file) + file = face->file; + else + file++; + break; + } + if (!file) + continue; + fileLen = MultiByteToWideChar(CP_UNIXCP, 0, file, -1, NULL, 0); + fileW = HeapAlloc(GetProcessHeap(), 0, fileLen * sizeof(WCHAR)); + MultiByteToWideChar(CP_UNIXCP, 0, file, -1, fileW, fileLen); + entryLen = strlenW(fileW) + 1 + strlenW(value) + 1; + if (sizeof(buff)-(data-buff) < entryLen + 1) + { + WARN("creating SystemLink for %s, ran out of buffer space\n", debugstr_w(name)); + HeapFree(GetProcessHeap(), 0, fileW); + break; + } + strcpyW(data, fileW); + strcatW(data, comma); + strcatW(data, value); + data += entryLen; + TRACE("added SystemLink for %s to %s in %s\n", debugstr_w(name), debugstr_w(value),debugstr_w(fileW)); + HeapFree(GetProcessHeap(), 0, fileW); + } + if (data != buff) + { + *data='\0'; + data++; + RegSetValueExW(hkey, name, 0, REG_MULTI_SZ, (BYTE*)buff, (data-buff) * sizeof(WCHAR)); + } else + TRACE("no SystemLink fonts found for %s\n", debugstr_w(name)); + } else + TRACE("removed SystemLink for %s\n", debugstr_w(name)); +} + +static void update_system_links(void) +{ + HKEY hkey = 0; + UINT i, j; + BOOL done = FALSE; + DWORD disposition; + FontSubst *psub; + + static const WCHAR MS_Shell_Dlg[] = {'M','S',' ','S','h','e','l','l',' ','D','l','g',0}; + + if (!RegCreateKeyExW(HKEY_LOCAL_MACHINE, system_link, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hkey, &disposition)) + { + if (disposition == REG_OPENED_EXISTING_KEY) + { + TRACE("SystemLink key already exists, doing nothing\n"); + RegCloseKey(hkey); + return; + } + + psub = get_font_subst(&font_subst_list, MS_Shell_Dlg, -1); + if (!psub) { + WARN("could not find FontSubstitute for MS Shell Dlg\n"); + RegCloseKey(hkey); + return; + } + + for (i = 0; i < sizeof(font_links_defaults_list)/sizeof(font_links_defaults_list[0]); i++) + { + if (!strcmpiW(font_links_defaults_list[i].shelldlg, psub->to.name)) + { + for (j = 0; j < sizeof(font_links_list)/sizeof(font_links_list[0]); j++) + populate_system_links(hkey, font_links_list[j], font_links_defaults_list[i].substitutes); + + if (!strcmpiW(psub->to.name, font_links_defaults_list[i].substitutes[0])) + populate_system_links(hkey, psub->to.name, font_links_defaults_list[i].substitutes); + done = TRUE; + } + else if (strcmpiW(psub->to.name, font_links_defaults_list[i].substitutes[0])) + { + populate_system_links(hkey, font_links_defaults_list[i].substitutes[0], NULL); + } + } + RegCloseKey(hkey); + if (!done) + WARN("there is no SystemLink default list for MS Shell Dlg %s\n", debugstr_w(psub->to.name)); + } else + WARN("failed to create SystemLink key\n"); } @@ -2701,6 +2878,7 @@ BOOL WineEngInit(void) LoadReplaceList(); update_reg_entries(); + update_system_links(); init_system_links(); ReleaseMutex(font_mutex); diff --git a/dlls/gdiplus/font.c b/dlls/gdiplus/font.c index 0b582a73c47..89498bce0d0 100644 --- a/dlls/gdiplus/font.c +++ b/dlls/gdiplus/font.c @@ -844,6 +844,7 @@ GpStatus WINGDIPAPI GdipNewPrivateFontCollection(GpFontCollection** fontCollecti (*fontCollection)->FontFamilies = NULL; (*fontCollection)->count = 0; + (*fontCollection)->allocated = 0; return Ok; } @@ -930,14 +931,77 @@ GpStatus WINGDIPAPI GdipGetFontCollectionFamilyList( return Ok; } +void free_installed_fonts(void) +{ + while (installedFontCollection.count) + GdipDeleteFontFamily(installedFontCollection.FontFamilies[--installedFontCollection.count]); + HeapFree(GetProcessHeap(), 0, installedFontCollection.FontFamilies); + installedFontCollection.FontFamilies = NULL; + installedFontCollection.allocated = 0; +} + +static INT CALLBACK add_font_proc(const LOGFONTW *lfw, const TEXTMETRICW *ntm, + DWORD type, LPARAM lParam) +{ + GpFontCollection* fonts = (GpFontCollection*)lParam; + int i; + + /* skip duplicates */ + for (i=0; icount; i++) + if (strcmpiW(lfw->lfFaceName, fonts->FontFamilies[i]->FamilyName) == 0) + return 1; + + if (fonts->allocated == fonts->count) + { + INT new_alloc_count = fonts->allocated+50; + GpFontFamily** new_family_list = HeapAlloc(GetProcessHeap(), 0, new_alloc_count*sizeof(void*)); + + if (!new_family_list) + return 0; + + memcpy(new_family_list, fonts->FontFamilies, fonts->count*sizeof(void*)); + HeapFree(GetProcessHeap(), 0, fonts->FontFamilies); + fonts->FontFamilies = new_family_list; + fonts->allocated = new_alloc_count; + } + + if (GdipCreateFontFamilyFromName(lfw->lfFaceName, NULL, &fonts->FontFamilies[fonts->count]) == Ok) + fonts->count++; + else + return 0; + + return 1; +} + GpStatus WINGDIPAPI GdipNewInstalledFontCollection( GpFontCollection** fontCollection) { - FIXME("stub: %p\n",fontCollection); + TRACE("(%p)\n",fontCollection); if (!fontCollection) return InvalidParameter; + if (installedFontCollection.count == 0) + { + HDC hdc; + LOGFONTW lfw; + + hdc = GetDC(0); + + lfw.lfCharSet = DEFAULT_CHARSET; + lfw.lfFaceName[0] = 0; + lfw.lfPitchAndFamily = 0; + + if (!EnumFontFamiliesExW(hdc, &lfw, add_font_proc, (LPARAM)&installedFontCollection, 0)) + { + free_installed_fonts(); + ReleaseDC(0, hdc); + return OutOfMemory; + } + + ReleaseDC(0, hdc); + } + *fontCollection = &installedFontCollection; return Ok; diff --git a/dlls/gdiplus/gdiplus.c b/dlls/gdiplus/gdiplus.c index 35caad8d830..950e0027de8 100644 --- a/dlls/gdiplus/gdiplus.c +++ b/dlls/gdiplus/gdiplus.c @@ -64,6 +64,10 @@ BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, LPVOID reserved) case DLL_PROCESS_ATTACH: DisableThreadLibraryCalls( hinst ); break; + + case DLL_PROCESS_DETACH: + free_installed_fonts(); + break; } return TRUE; } @@ -380,3 +384,9 @@ inline void delete_element(region_element* element) break; } } + +const char *debugstr_rectf(CONST RectF* rc) +{ + if (!rc) return "(null)"; + return wine_dbg_sprintf("(%0.2f,%0.2f,%0.2f,%0.2f)", rc->X, rc->Y, rc->Width, rc->Height); +} diff --git a/dlls/gdiplus/gdiplus.spec b/dlls/gdiplus/gdiplus.spec index 76c7328de9e..34c897a6dd0 100644 --- a/dlls/gdiplus/gdiplus.spec +++ b/dlls/gdiplus/gdiplus.spec @@ -621,8 +621,8 @@ @ stdcall GdipTranslateWorldTransform(ptr long long long) @ stdcall GdipVectorTransformMatrixPoints(ptr ptr long) @ stdcall GdipVectorTransformMatrixPointsI(ptr ptr long) -@ stub GdipWarpPath -@ stub GdipWidenPath +@ stdcall GdipWarpPath(ptr ptr ptr long long long long long long long) +@ stdcall GdipWidenPath(ptr ptr ptr long) @ stub GdipWindingModeOutline @ stdcall GdiplusNotificationHook(ptr) @ stdcall GdiplusNotificationUnhook(ptr) diff --git a/dlls/gdiplus/gdiplus_private.h b/dlls/gdiplus/gdiplus_private.h index f3bf79767b2..af20c755a12 100644 --- a/dlls/gdiplus/gdiplus_private.h +++ b/dlls/gdiplus/gdiplus_private.h @@ -52,6 +52,8 @@ extern void calc_curve_bezier(CONST GpPointF *pts, REAL tension, REAL *x1, extern void calc_curve_bezier_endp(REAL xend, REAL yend, REAL xadj, REAL yadj, REAL tension, REAL *x, REAL *y); +extern void free_installed_fonts(void); + extern BOOL lengthen_path(GpPath *path, INT len); extern GpStatus trace_path(GpGraphics *graphics, GpPath *path); @@ -69,6 +71,8 @@ static inline REAL deg2rad(REAL degrees) return M_PI * degrees / 180.0; } +extern const char *debugstr_rectf(CONST RectF* rc); + struct GpPen{ UINT style; GpUnit unit; @@ -243,6 +247,7 @@ struct GpStringFormat{ struct GpFontCollection{ GpFontFamily **FontFamilies; INT count; + INT allocated; }; struct GpFontFamily{ diff --git a/dlls/gdiplus/graphics.c b/dlls/gdiplus/graphics.c index 07b21141d23..5e5883f88eb 100644 --- a/dlls/gdiplus/graphics.c +++ b/dlls/gdiplus/graphics.c @@ -2016,6 +2016,9 @@ GpStatus WINGDIPAPI GdipDrawString(GpGraphics *graphics, GDIPCONST WCHAR *string SIZE size; RECT drawcoord; + TRACE("(%p, %s, %i, %p, %s, %p, %p)\n", graphics, debugstr_wn(string, length), + length, font, debugstr_rectf(rect), format, brush); + if(!graphics || !string || !font || !brush || !rect) return InvalidParameter; @@ -2932,6 +2935,10 @@ GpStatus WINGDIPAPI GdipMeasureString(GpGraphics *graphics, nheight; SIZE size; + TRACE("(%p, %s, %i, %p, %s, %p, %p, %p, %p)\n", graphics, + debugstr_wn(string, length), length, font, debugstr_rectf(rect), format, + bounds, codepointsfitted, linesfilled); + if(!graphics || !string || !font || !rect) return InvalidParameter; diff --git a/dlls/gdiplus/graphicspath.c b/dlls/gdiplus/graphicspath.c index ca33082731e..8ffe531a37a 100644 --- a/dlls/gdiplus/graphicspath.c +++ b/dlls/gdiplus/graphicspath.c @@ -1465,6 +1465,24 @@ GpStatus WINGDIPAPI GdipTransformPath(GpPath *path, GpMatrix *matrix) path->pathdata.Count); } +GpStatus WINGDIPAPI GdipWarpPath(GpPath *path, GpMatrix* matrix, + GDIPCONST GpPointF *points, INT count, REAL x, REAL y, REAL width, + REAL height, WarpMode warpmode, REAL flatness) +{ + FIXME("(%p,%p,%p,%i,%0.2f,%0.2f,%0.2f,%0.2f,%i,%0.2f)\n", path, matrix, + points, count, x, y, width, height, warpmode, flatness); + + return NotImplemented; +} + +GpStatus WINGDIPAPI GdipWidenPath(GpPath *path, GpPen *pen, GpMatrix *matrix, + REAL flatness) +{ + FIXME("(%p,%p,%p,%0.2f)\n", path, pen, matrix, flatness); + + return NotImplemented; +} + GpStatus WINGDIPAPI GdipAddPathRectangle(GpPath *path, REAL x, REAL y, REAL width, REAL height) { diff --git a/dlls/gdiplus/stringformat.c b/dlls/gdiplus/stringformat.c index 21053b78e46..bfe7d34e05e 100644 --- a/dlls/gdiplus/stringformat.c +++ b/dlls/gdiplus/stringformat.c @@ -35,6 +35,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(gdiplus); GpStatus WINGDIPAPI GdipCreateStringFormat(INT attr, LANGID lang, GpStringFormat **format) { + TRACE("(%i, %x, %p)\n", attr, lang, format); + if(!format) return InvalidParameter; @@ -189,6 +191,8 @@ GpStatus WINGDIPAPI GdipGetStringFormatTrimming(GpStringFormat *format, GpStatus WINGDIPAPI GdipSetStringFormatAlign(GpStringFormat *format, StringAlignment align) { + TRACE("(%p, %i)\n", format, align); + if(!format) return InvalidParameter; @@ -201,6 +205,8 @@ GpStatus WINGDIPAPI GdipSetStringFormatAlign(GpStringFormat *format, GpStatus WINGDIPAPI GdipSetStringFormatDigitSubstitution(GpStringFormat *format, LANGID language, StringDigitSubstitute substitute) { + TRACE("(%p, %x, %i)\n", format, language, substitute); + if(!format) return InvalidParameter; @@ -213,6 +219,8 @@ GpStatus WINGDIPAPI GdipSetStringFormatDigitSubstitution(GpStringFormat *format, GpStatus WINGDIPAPI GdipSetStringFormatHotkeyPrefix(GpStringFormat *format, INT hkpx) { + TRACE("(%p, %i)\n", format, hkpx); + if(!format || hkpx < 0 || hkpx > 2) return InvalidParameter; @@ -224,6 +232,8 @@ GpStatus WINGDIPAPI GdipSetStringFormatHotkeyPrefix(GpStringFormat *format, GpStatus WINGDIPAPI GdipSetStringFormatLineAlign(GpStringFormat *format, StringAlignment align) { + TRACE("(%p, %i)\n", format, align); + if(!format) return InvalidParameter; @@ -246,6 +256,8 @@ GpStatus WINGDIPAPI GdipSetStringFormatMeasurableCharacterRanges(GpStringFormat* GpStatus WINGDIPAPI GdipSetStringFormatTabStops(GpStringFormat *format, REAL firsttab, INT count, GDIPCONST REAL *tabs) { + TRACE("(%p, %0.2f, %i, %p)\n", format, firsttab, count, tabs); + if(!format || !tabs) return InvalidParameter; @@ -276,6 +288,8 @@ GpStatus WINGDIPAPI GdipSetStringFormatTabStops(GpStringFormat *format, REAL fir GpStatus WINGDIPAPI GdipSetStringFormatTrimming(GpStringFormat *format, StringTrimming trimming) { + TRACE("(%p, %i)\n", format, trimming); + if(!format) return InvalidParameter; @@ -286,6 +300,8 @@ GpStatus WINGDIPAPI GdipSetStringFormatTrimming(GpStringFormat *format, GpStatus WINGDIPAPI GdipSetStringFormatFlags(GpStringFormat *format, INT flags) { + TRACE("(%p, %x)\n", format, flags); + if(!format) return InvalidParameter; diff --git a/dlls/hlink/tests/hlink.c b/dlls/hlink/tests/hlink.c index 5e07359fdf5..69819426007 100644 --- a/dlls/hlink/tests/hlink.c +++ b/dlls/hlink/tests/hlink.c @@ -80,7 +80,7 @@ static const char *debugstr_guid(REFIID riid) static void test_HlinkIsShortcut(void) { - int i; + UINT i; HRESULT hres; static const WCHAR file0[] = {'f','i','l','e',0}; diff --git a/dlls/imm32/tests/imm32.c b/dlls/imm32/tests/imm32.c index 7e7f752d466..1951242a7a1 100644 --- a/dlls/imm32/tests/imm32.c +++ b/dlls/imm32/tests/imm32.c @@ -90,7 +90,7 @@ static void msg_spy_flush_msgs(void) { } static CWPSTRUCT* msg_spy_find_msg(UINT message) { - int i; + UINT i; msg_spy_pump_msg_queue(); diff --git a/dlls/inetcomm/smtptransport.c b/dlls/inetcomm/smtptransport.c index 91070b65512..d17419f295b 100644 --- a/dlls/inetcomm/smtptransport.c +++ b/dlls/inetcomm/smtptransport.c @@ -732,7 +732,7 @@ static HRESULT WINAPI SMTPTransport_CommandMAIL(ISMTPTransport2 *iface, LPSTR ps SMTPTransport *This = (SMTPTransport *)iface; const char szCommandFormat[] = "MAIL FROM: <%s>\n"; char *szCommand; - int len = sizeof(szCommandFormat) - 2 /* "%s" */ + strlen(pszEmailFrom); + int len; HRESULT hr; TRACE("(%s)\n", debugstr_a(pszEmailFrom)); @@ -740,6 +740,7 @@ static HRESULT WINAPI SMTPTransport_CommandMAIL(ISMTPTransport2 *iface, LPSTR ps if (!pszEmailFrom) return E_INVALIDARG; + len = sizeof(szCommandFormat) - 2 /* "%s" */ + strlen(pszEmailFrom); szCommand = HeapAlloc(GetProcessHeap(), 0, len); if (!szCommand) return E_OUTOFMEMORY; @@ -758,7 +759,7 @@ static HRESULT WINAPI SMTPTransport_CommandRCPT(ISMTPTransport2 *iface, LPSTR ps SMTPTransport *This = (SMTPTransport *)iface; const char szCommandFormat[] = "RCPT TO: <%s>\n"; char *szCommand; - int len = sizeof(szCommandFormat) - 2 /* "%s" */ + strlen(pszEmailTo); + int len; HRESULT hr; TRACE("(%s)\n", debugstr_a(pszEmailTo)); @@ -766,6 +767,7 @@ static HRESULT WINAPI SMTPTransport_CommandRCPT(ISMTPTransport2 *iface, LPSTR ps if (!pszEmailTo) return E_INVALIDARG; + len = sizeof(szCommandFormat) - 2 /* "%s" */ + strlen(pszEmailTo); szCommand = HeapAlloc(GetProcessHeap(), 0, len); if (!szCommand) return E_OUTOFMEMORY; @@ -833,7 +835,7 @@ static HRESULT WINAPI SMTPTransport_CommandAUTH(ISMTPTransport2 *iface, SMTPTransport *This = (SMTPTransport *)iface; const char szCommandFormat[] = "AUTH %s\n"; char *szCommand; - int len = sizeof(szCommandFormat) - 2 /* "%s" */ + strlen(pszAuthType); + int len; HRESULT hr; TRACE("(%s)\n", debugstr_a(pszAuthType)); @@ -841,6 +843,7 @@ static HRESULT WINAPI SMTPTransport_CommandAUTH(ISMTPTransport2 *iface, if (!pszAuthType) return E_INVALIDARG; + len = sizeof(szCommandFormat) - 2 /* "%s" */ + strlen(pszAuthType); szCommand = HeapAlloc(GetProcessHeap(), 0, len); if (!szCommand) return E_OUTOFMEMORY; diff --git a/dlls/inetmib1/main.c b/dlls/inetmib1/main.c index 1093117b5ad..7ce01117455 100644 --- a/dlls/inetmib1/main.c +++ b/dlls/inetmib1/main.c @@ -143,7 +143,10 @@ static BOOL mib2IfNumberQuery(BYTE bPduType, SnmpVarBind *pVarBind, copyInt(&pVarBind->value, &numIfs); if (bPduType == SNMP_PDU_GETNEXT) + { + SnmpUtilOidFree(&pVarBind->name); SnmpUtilOidCpy(&pVarBind->name, &numberOid); + } *pErrorStatus = SNMP_ERRORSTATUS_NOERROR; } else @@ -320,7 +323,27 @@ static DWORD oidToIpAddr(AsnObjectIdentifier *oid) typedef void (*oidToKeyFunc)(AsnObjectIdentifier *oid, void *dst); typedef int (*compareFunc)(const void *key, const void *value); -static UINT findValueInTable(AsnObjectIdentifier *oid, +/* Finds the first value in the table that matches key. Returns its 1-based + * index if found, or 0 if not found. + */ +static UINT findValueInTable(const void *key, + struct GenericTable *table, size_t tableEntrySize, compareFunc compare) +{ + UINT index = 0; + void *value; + + value = bsearch(key, table->entries, table->numEntries, tableEntrySize, + compare); + if (value) + index = ((BYTE *)value - (BYTE *)table->entries) / tableEntrySize + 1; + return index; +} + +/* Finds the first value in the table that matches oid, using makeKey to + * convert the oid to a key for comparison. Returns the value's 1-based + * index if found, or 0 if not found. + */ +static UINT findOidInTable(AsnObjectIdentifier *oid, struct GenericTable *table, size_t tableEntrySize, oidToKeyFunc makeKey, compareFunc compare) { @@ -329,14 +352,50 @@ static UINT findValueInTable(AsnObjectIdentifier *oid, if (key) { - void *value; + makeKey(oid, key); + index = findValueInTable(key, table, tableEntrySize, compare); + HeapFree(GetProcessHeap(), 0, key); + } + return index; +} + +/* Finds the first successor to the value in the table that does matches oid, + * using makeKey to convert the oid to a key for comparison. A successor is + * a value that does not match oid, so if multiple entries match an oid, only + * the first will ever be returned using this method. + * Returns the successor's 1-based index if found, or 0 if not found. + */ +static UINT findNextOidInTable(AsnObjectIdentifier *oid, + struct GenericTable *table, size_t tableEntrySize, oidToKeyFunc makeKey, + compareFunc compare) +{ + UINT index = 0; + void *key = HeapAlloc(GetProcessHeap(), 0, tableEntrySize); + if (key) + { makeKey(oid, key); - value = bsearch(key, table->entries, table->numEntries, tableEntrySize, - compare); - if (value) - index = ((BYTE *)value - (BYTE *)table->entries) / tableEntrySize - + 1; + index = findValueInTable(key, table, tableEntrySize, compare); + if (index == 0) + { + /* Not found in table. If it's less than the first entry, return + * the first index. Otherwise just return 0 and let the caller + * handle finding the successor. + */ + if (compare(key, table->entries) < 0) + index = 1; + } + else + { + /* Skip any entries that match the same key. This enumeration will + * be incomplete, but it's what Windows appears to do if there are + * multiple entries with the same index in a table, and it avoids + * an infinite loop. + */ + for (++index; index <= table->numEntries && compare(key, + &table->entries[tableEntrySize * index]) == 0; ++index) + ; + } HeapFree(GetProcessHeap(), 0, key); } return index; @@ -400,9 +459,9 @@ static AsnInteger32 getItemAndInstanceFromTable(AsnObjectIdentifier *oid, AsnObjectIdentifier ipOid = { instanceLen, oid->ids + base->idLength + 1 }; - *instance = findValueInTable(&ipOid, table, tableEntrySize, - makeKey, compare) + 1; - if (*instance > table->numEntries) + *instance = findNextOidInTable(&ipOid, table, tableEntrySize, + makeKey, compare); + if (!*instance || *instance > table->numEntries) ret = SNMP_ERRORSTATUS_NOSUCHNAME; } } @@ -421,7 +480,7 @@ static AsnInteger32 getItemAndInstanceFromTable(AsnObjectIdentifier *oid, AsnObjectIdentifier ipOid = { instanceLen, oid->ids + base->idLength + 1 }; - *instance = findValueInTable(&ipOid, table, tableEntrySize, + *instance = findOidInTable(&ipOid, table, tableEntrySize, makeKey, compare); if (!*instance) ret = SNMP_ERRORSTATUS_NOSUCHNAME; @@ -440,6 +499,7 @@ static INT setOidWithItem(AsnObjectIdentifier *dst, AsnObjectIdentifier *base, AsnObjectIdentifier oid; INT ret; + SnmpUtilOidFree(dst); ret = SnmpUtilOidCpy(dst, base); if (ret) { @@ -1311,7 +1371,7 @@ BOOL WINAPI SnmpExtensionQuery(BYTE bPduType, SnmpVarBindList *pVarBindList, * so we have to continue until an implementation handles the * query or we exhaust the table of supported OIDs. */ - for (; error == SNMP_ERRORSTATUS_NOSUCHNAME && + for (matchingIndex++; error == SNMP_ERRORSTATUS_NOSUCHNAME && matchingIndex < DEFINE_SIZEOF(supportedIDs); matchingIndex++) { diff --git a/dlls/inetmib1/tests/main.c b/dlls/inetmib1/tests/main.c index 6c83d58e7fd..c52cc43ff52 100644 --- a/dlls/inetmib1/tests/main.c +++ b/dlls/inetmib1/tests/main.c @@ -88,7 +88,7 @@ static void testQuery(void) error = 0xdeadbeef; index = 0xdeadbeef; ret = pQuery(SNMP_PDU_GET, &list, &error, &index); - ok(ret, "SnmpExtensionQuery failed: %d\n", GetLastError()); + ok(ret, "SnmpExtensionQuery failed: %d, %d\n", error, index); ok(error == SNMP_ERRORSTATUS_NOERROR, "expected SNMP_ERRORSTATUS_NOERROR, got %d\n", error); ok(index == 0, "expected index 0, got %d\n", index); @@ -105,7 +105,7 @@ static void testQuery(void) error = 0xdeadbeef; index = 0xdeadbeef; ret = pQuery(SNMP_PDU_GET, &list, &error, &index); - ok(ret, "SnmpExtensionQuery failed: %d\n", GetLastError()); + ok(ret, "SnmpExtensionQuery failed: %d, %d\n", error, index); ok(error == SNMP_ERRORSTATUS_NOERROR || error == ERROR_FILE_NOT_FOUND /* Win9x */, "expected SNMP_ERRORSTATUS_NOERROR or ERROR_FILE_NOT_FOUND, got %d\n", @@ -125,7 +125,7 @@ static void testQuery(void) error = 0xdeadbeef; index = 0xdeadbeef; ret = pQuery(SNMP_PDU_GET, &list, &error, &index); - ok(ret, "SnmpExtensionQuery failed: %d\n", GetLastError()); + ok(ret, "SnmpExtensionQuery failed: %d, %d\n", error, index); ok(error == SNMP_ERRORSTATUS_NOSUCHNAME, "expected SNMP_ERRORSTATUS_NOSUCHNAME, got %d\n", error); /* The index is 1-based rather than 0-based */ @@ -147,7 +147,7 @@ static void testQuery(void) error = 0xdeadbeef; index = 0xdeadbeef; ret = pQuery(SNMP_PDU_GET, &list, &error, &index); - ok(ret, "SnmpExtensionQuery failed: %d\n", GetLastError()); + ok(ret, "SnmpExtensionQuery failed: %d, %d\n", error, index); ok(error == SNMP_ERRORSTATUS_NOSUCHNAME, "expected SNMP_ERRORSTATUS_NOSUCHNAME, got %d\n", error); ok(index == 1, "expected index 1, got %d\n", index); @@ -169,7 +169,7 @@ static void testQuery(void) error = 0xdeadbeef; index = 0xdeadbeef; ret = pQuery(SNMP_PDU_GETNEXT, &list, &error, &index); - ok(ret, "SnmpExtensionQuery failed: %d\n", GetLastError()); + ok(ret, "SnmpExtensionQuery failed: %d, %d\n", error, index); ok(error == SNMP_ERRORSTATUS_NOERROR, "expected SNMP_ERRORSTATUS_NOERROR, got %d\n", error); ok(index == 0, "expected index 0, got %d\n", index); @@ -252,7 +252,7 @@ static void testQuery(void) moreData = TRUE; noChange = FALSE; ret = pQuery(SNMP_PDU_GETNEXT, &list, &error, &index); - ok(ret, "SnmpExtensionQuery failed: %d\n", GetLastError()); + ok(ret, "SnmpExtensionQuery failed: %d, %d\n", error, index); ok(error == SNMP_ERRORSTATUS_NOERROR, "expected SNMP_ERRORSTATUS_NOERROR, got %d\n", error); ok(index == 0, "expected index 0, got %d\n", index); @@ -274,7 +274,7 @@ static void testQuery(void) moreData = TRUE; do { ret = pQuery(SNMP_PDU_GETNEXT, &list, &error, &index); - ok(ret, "SnmpExtensionQuery failed: %d\n", GetLastError()); + ok(ret, "SnmpExtensionQuery failed: %d, %d\n", error, index); ok(error == SNMP_ERRORSTATUS_NOERROR, "expected SNMP_ERRORSTATUS_NOERROR, got %d\n", error); ok(index == 0, "expected index 0, got %d\n", index); @@ -340,7 +340,7 @@ static void testQuery(void) noChange = FALSE; do { ret = pQuery(SNMP_PDU_GETNEXT, &list, &error, &index); - ok(ret, "SnmpExtensionQuery failed: %d\n", GetLastError()); + ok(ret, "SnmpExtensionQuery failed: %d, %d\n", error, index); ok(error == SNMP_ERRORSTATUS_NOERROR, "expected SNMP_ERRORSTATUS_NOERROR, got %d\n", error); ok(index == 0, "expected index 0, got %d\n", index); @@ -406,7 +406,7 @@ static void testQuery(void) noChange = FALSE; do { ret = pQuery(SNMP_PDU_GETNEXT, &list, &error, &index); - ok(ret, "SnmpExtensionQuery failed: %d\n", GetLastError()); + ok(ret, "SnmpExtensionQuery failed: %d, %d\n", error, index); /* FIXME: error and index aren't checked here because the UDP table is * the last OID currently supported by Wine, so the last GetNext fails. * todo_wine is also not effective because it will succeed for all but diff --git a/dlls/iphlpapi/ifenum.c b/dlls/iphlpapi/ifenum.c index 19c3c3c952c..d3482290a76 100644 --- a/dlls/iphlpapi/ifenum.c +++ b/dlls/iphlpapi/ifenum.c @@ -299,7 +299,7 @@ static DWORD getInterfaceMaskByName(const char *name) } #if defined (SIOCGIFHWADDR) -DWORD getInterfacePhysicalByName(const char *name, PDWORD len, PBYTE addr, +static DWORD getInterfacePhysicalByName(const char *name, PDWORD len, PBYTE addr, PDWORD type) { DWORD ret; @@ -387,7 +387,7 @@ DWORD getInterfacePhysicalByName(const char *name, PDWORD len, PBYTE addr, return ret; } #elif defined (SIOCGARP) -DWORD getInterfacePhysicalByName(const char *name, PDWORD len, PBYTE addr, +static DWORD getInterfacePhysicalByName(const char *name, PDWORD len, PBYTE addr, PDWORD type) { DWORD ret; @@ -446,7 +446,7 @@ DWORD getInterfacePhysicalByName(const char *name, PDWORD len, PBYTE addr, return ret; } #elif defined (HAVE_SYS_SYSCTL_H) && defined (HAVE_NET_IF_DL_H) -DWORD getInterfacePhysicalByName(const char *name, PDWORD len, PBYTE addr, +static DWORD getInterfacePhysicalByName(const char *name, PDWORD len, PBYTE addr, PDWORD type) { DWORD ret; diff --git a/dlls/iphlpapi/ifenum.h b/dlls/iphlpapi/ifenum.h index 6835dcad3c2..c348191912c 100644 --- a/dlls/iphlpapi/ifenum.h +++ b/dlls/iphlpapi/ifenum.h @@ -86,8 +86,6 @@ DWORD getInterfaceIndexByName(const char *name, PDWORD index); * if internal errors occur. * Returns NO_ERROR on success. */ -DWORD getInterfacePhysicalByName(const char *name, PDWORD len, PBYTE addr, - PDWORD type); DWORD getInterfacePhysicalByIndex(DWORD index, PDWORD len, PBYTE addr, PDWORD type); diff --git a/dlls/kernel32/tests/volume.c b/dlls/kernel32/tests/volume.c index 19fc6f08f7d..498c2d8d743 100644 --- a/dlls/kernel32/tests/volume.c +++ b/dlls/kernel32/tests/volume.c @@ -114,7 +114,8 @@ static void test_GetVolumeNameForVolumeMountPointA(void) { BOOL ret; char volume[MAX_PATH], path[] = "c:\\"; - DWORD len = sizeof(volume); + DWORD len = sizeof(volume), reti; + char temp_path[MAX_PATH]; /* not present before w2k */ if (!pGetVolumeNameForVolumeMountPointA) { @@ -122,6 +123,10 @@ static void test_GetVolumeNameForVolumeMountPointA(void) return; } + reti = GetTempPathA(MAX_PATH, temp_path); + ok(reti != 0, "GetTempPathA error %d\n", GetLastError()); + ok(reti < MAX_PATH, "temp path should fit into MAX_PATH\n"); + ret = pGetVolumeNameForVolumeMountPointA(path, volume, 0); ok(ret == FALSE, "GetVolumeNameForVolumeMountPointA succeeded\n"); @@ -135,6 +140,47 @@ static void test_GetVolumeNameForVolumeMountPointA(void) ret = pGetVolumeNameForVolumeMountPointA(path, volume, len); ok(ret == TRUE, "GetVolumeNameForVolumeMountPointA failed\n"); + ok(!strncmp( volume, "\\\\?\\Volume{", 11), + "GetVolumeNameForVolumeMountPointA failed to return valid string <%s>\n", + volume); + + /* test with too small buffer */ + ret = pGetVolumeNameForVolumeMountPointA(path, volume, 10); +todo_wine + ok(ret == FALSE && GetLastError() == ERROR_FILENAME_EXCED_RANGE, + "GetVolumeNameForVolumeMountPointA failed, wrong error returned, was %d, should be ERROR_FILENAME_EXCED_RANGE\n", + GetLastError()); + + /* Try on a arbitrary directory */ + ret = pGetVolumeNameForVolumeMountPointA(temp_path, volume, len); +todo_wine + ok(ret == FALSE && GetLastError() == ERROR_NOT_A_REPARSE_POINT, + "GetVolumeNameForVolumeMountPointA failed on %s, last=%d\n", + temp_path, GetLastError()); + + /* Try on a non-existent dos drive */ + path[2] = 0; + for (;path[0] <= 'z'; path[0]++) { + ret = QueryDosDeviceA( path, volume, len); + if(!ret) break; + } + if (path[0] <= 'z') + { + path[2] = '\\'; + ret = pGetVolumeNameForVolumeMountPointA(path, volume, len); +todo_wine + ok(ret == FALSE && GetLastError() == ERROR_FILE_NOT_FOUND, + "GetVolumeNameForVolumeMountPointA failed on %s, last=%d\n", + path, GetLastError()); + + /* Try without trailing \ and on a non-existent dos drive */ + path[2] = 0; + ret = pGetVolumeNameForVolumeMountPointA(path, volume, len); +todo_wine + ok(ret == FALSE && GetLastError() == ERROR_INVALID_NAME, + "GetVolumeNameForVolumeMountPointA failed on %s, last=%d\n", + path, GetLastError()); + } } static void test_GetVolumeNameForVolumeMountPointW(void) diff --git a/dlls/lz32/tests/lzexpand_main.c b/dlls/lz32/tests/lzexpand_main.c index 91fd6873e3f..3e46fb0a47c 100644 --- a/dlls/lz32/tests/lzexpand_main.c +++ b/dlls/lz32/tests/lzexpand_main.c @@ -881,10 +881,10 @@ static void test_LZOpenFileW(void) START_TEST(lzexpand_main) { - buf = malloc(uncompressed_data_size * 2); + buf = HeapAlloc(GetProcessHeap(), 0, uncompressed_data_size * 2); test_LZOpenFileA(); test_LZOpenFileW(); test_LZRead(); test_LZCopy(); - free(buf); + HeapFree(GetProcessHeap(), 0, buf); } diff --git a/dlls/mlang/mlang.c b/dlls/mlang/mlang.c index d627cfd96b3..5deb87b3881 100644 --- a/dlls/mlang/mlang.c +++ b/dlls/mlang/mlang.c @@ -1939,7 +1939,7 @@ static HRESULT WINAPI fnIMLangFontLink_GetStrCodePages( } if (pdwCodePages) *pdwCodePages = cps; - if (pcchCodePages) *pcchCodePages = i; + if (pcchCodePages) *pcchCodePages = min( i + 1, cchSrc ); return S_OK; } diff --git a/dlls/msctf/context.c b/dlls/msctf/context.c index 38d8ad6218c..dff4fd88f9f 100644 --- a/dlls/msctf/context.c +++ b/dlls/msctf/context.c @@ -58,6 +58,13 @@ typedef struct tagContextSink { typedef struct tagContext { const ITfContextVtbl *ContextVtbl; const ITfSourceVtbl *SourceVtbl; + /* const ITfContextCompositionVtbl *ContextCompositionVtbl; */ + /* const ITfContextOwnerCompositionServicesVtbl *ContextOwnerCompositionServicesVtbl; */ + /* const ITfContextOwnerServicesVtbl *ContextOwnerServicesVtbl; */ + /* const ITfInsertAtSelectionVtbl *InsertAtSelectionVtbl; */ + /* const ITfMouseTrackerVtbl *MouseTrackerVtbl; */ + /* const ITfQueryEmbeddedVtbl *QueryEmbeddedVtbl; */ + /* const ITfSourceSingleVtbl *SourceSingleVtbl; */ LONG refCount; TfClientId tidOwner; @@ -79,6 +86,7 @@ typedef struct tagContext { typedef struct tagTextStoreACPSink { const ITextStoreACPSinkVtbl *TextStoreACPSinkVtbl; + /* const ITextStoreACPServicesVtbl *TextStoreACPServicesVtbl; */ LONG refCount; Context *pContext; diff --git a/dlls/msctf/inputprocessor.c b/dlls/msctf/inputprocessor.c index 38e93688596..90daa2fb474 100644 --- a/dlls/msctf/inputprocessor.c +++ b/dlls/msctf/inputprocessor.c @@ -32,8 +32,10 @@ #include "shlwapi.h" #include "winerror.h" #include "objbase.h" +#include "olectl.h" #include "wine/unicode.h" +#include "wine/list.h" #include "msctf.h" #include "msctf_internal.h" @@ -45,11 +47,26 @@ static const WCHAR szwEnabled[] = {'E','n','a','b','l','e','d',0}; static const WCHAR szwTipfmt[] = {'%','s','\\','%','s',0}; static const WCHAR szwFullLangfmt[] = {'%','s','\\','%','s','\\','%','s','\\','0','x','%','0','8','x','\\','%','s',0}; +typedef struct tagInputProcessorProfilesSink { + struct list entry; + union { + /* InputProcessorProfile Sinks */ + IUnknown *pIUnknown; + ITfLanguageProfileNotifySink *pITfLanguageProfileNotifySink; + } interfaces; +} InputProcessorProfilesSink; + typedef struct tagInputProcessorProfiles { const ITfInputProcessorProfilesVtbl *InputProcessorProfilesVtbl; + const ITfSourceVtbl *SourceVtbl; + /* const ITfInputProcessorProfileMgrVtbl *InputProcessorProfileMgrVtbl; */ + /* const ITfInputProcessorProfilesExVtbl *InputProcessorProfilesExVtbl; */ + /* const ITfInputProcessorProfileSubstituteLayoutVtbl *InputProcessorProfileSubstituteLayoutVtbl; */ LONG refCount; LANGID currentLanguage; + + struct list LanguageProfileNotifySink; } InputProcessorProfiles; typedef struct tagProfilesEnumGuid { @@ -78,9 +95,30 @@ typedef struct tagEnumTfLanguageProfiles { static HRESULT ProfilesEnumGuid_Constructor(IEnumGUID **ppOut); static HRESULT EnumTfLanguageProfiles_Constructor(LANGID langid, IEnumTfLanguageProfiles **ppOut); +static inline InputProcessorProfiles *impl_from_ITfSourceVtbl(ITfSource *iface) +{ + return (InputProcessorProfiles *)((char *)iface - FIELD_OFFSET(InputProcessorProfiles,SourceVtbl)); +} + +static void free_sink(InputProcessorProfilesSink *sink) +{ + IUnknown_Release(sink->interfaces.pIUnknown); + HeapFree(GetProcessHeap(),0,sink); +} + static void InputProcessorProfiles_Destructor(InputProcessorProfiles *This) { + struct list *cursor, *cursor2; TRACE("destroying %p\n", This); + + /* free sinks */ + LIST_FOR_EACH_SAFE(cursor, cursor2, &This->LanguageProfileNotifySink) + { + InputProcessorProfilesSink* sink = LIST_ENTRY(cursor,InputProcessorProfilesSink,entry); + list_remove(cursor); + free_sink(sink); + } + HeapFree(GetProcessHeap(),0,This); } @@ -122,6 +160,10 @@ static HRESULT WINAPI InputProcessorProfiles_QueryInterface(ITfInputProcessorPro { *ppvOut = This; } + else if (IsEqualIID(iid, &IID_ITfSource)) + { + *ppvOut = &This->SourceVtbl; + } if (*ppvOut) { @@ -536,6 +578,92 @@ static const ITfInputProcessorProfilesVtbl InputProcessorProfiles_InputProcessor InputProcessorProfiles_SubstituteKeyboardLayout }; +/***************************************************** + * ITfSource functions + *****************************************************/ +static HRESULT WINAPI IPPSource_QueryInterface(ITfSource *iface, REFIID iid, LPVOID *ppvOut) +{ + InputProcessorProfiles *This = impl_from_ITfSourceVtbl(iface); + return InputProcessorProfiles_QueryInterface((ITfInputProcessorProfiles *)This, iid, *ppvOut); +} + +static ULONG WINAPI IPPSource_AddRef(ITfSource *iface) +{ + InputProcessorProfiles *This = impl_from_ITfSourceVtbl(iface); + return InputProcessorProfiles_AddRef((ITfInputProcessorProfiles*)This); +} + +static ULONG WINAPI IPPSource_Release(ITfSource *iface) +{ + InputProcessorProfiles *This = impl_from_ITfSourceVtbl(iface); + return InputProcessorProfiles_Release((ITfInputProcessorProfiles *)This); +} + +static WINAPI HRESULT IPPSource_AdviseSink(ITfSource *iface, + REFIID riid, IUnknown *punk, DWORD *pdwCookie) +{ + InputProcessorProfilesSink *ipps; + InputProcessorProfiles *This = impl_from_ITfSourceVtbl(iface); + + TRACE("(%p) %s %p %p\n",This,debugstr_guid(riid),punk,pdwCookie); + + if (!riid || !punk || !pdwCookie) + return E_INVALIDARG; + + if (IsEqualIID(riid, &IID_ITfLanguageProfileNotifySink)) + { + ipps = HeapAlloc(GetProcessHeap(),0,sizeof(InputProcessorProfilesSink)); + if (!ipps) + return E_OUTOFMEMORY; + if (!SUCCEEDED(IUnknown_QueryInterface(punk, riid, (LPVOID*)&ipps->interfaces.pITfLanguageProfileNotifySink))) + { + HeapFree(GetProcessHeap(),0,ipps); + return CONNECT_E_CANNOTCONNECT; + } + list_add_head(&This->LanguageProfileNotifySink,&ipps->entry); + *pdwCookie = generate_Cookie(COOKIE_MAGIC_IPPSINK, ipps); + } + else + { + FIXME("(%p) Unhandled Sink: %s\n",This,debugstr_guid(riid)); + return E_NOTIMPL; + } + + TRACE("cookie %x\n",*pdwCookie); + + return S_OK; +} + +static WINAPI HRESULT IPPSource_UnadviseSink(ITfSource *iface, DWORD pdwCookie) +{ + InputProcessorProfilesSink *sink; + InputProcessorProfiles *This = impl_from_ITfSourceVtbl(iface); + + TRACE("(%p) %x\n",This,pdwCookie); + + if (get_Cookie_magic(pdwCookie)!=COOKIE_MAGIC_IPPSINK) + return E_INVALIDARG; + + sink = (InputProcessorProfilesSink*)remove_Cookie(pdwCookie); + if (!sink) + return CONNECT_E_NOCONNECTION; + + list_remove(&sink->entry); + free_sink(sink); + + return S_OK; +} + +static const ITfSourceVtbl InputProcessorProfiles_SourceVtbl = +{ + IPPSource_QueryInterface, + IPPSource_AddRef, + IPPSource_Release, + + IPPSource_AdviseSink, + IPPSource_UnadviseSink, +}; + HRESULT InputProcessorProfiles_Constructor(IUnknown *pUnkOuter, IUnknown **ppOut) { InputProcessorProfiles *This; @@ -547,9 +675,12 @@ HRESULT InputProcessorProfiles_Constructor(IUnknown *pUnkOuter, IUnknown **ppOut return E_OUTOFMEMORY; This->InputProcessorProfilesVtbl= &InputProcessorProfiles_InputProcessorProfilesVtbl; + This->SourceVtbl = &InputProcessorProfiles_SourceVtbl; This->refCount = 1; This->currentLanguage = GetUserDefaultLCID(); + list_init(&This->LanguageProfileNotifySink); + TRACE("returning %p\n", This); *ppOut = (IUnknown *)This; return S_OK; diff --git a/dlls/msctf/msctf.c b/dlls/msctf/msctf.c index c8dd486c63b..55a80752ce2 100644 --- a/dlls/msctf/msctf.c +++ b/dlls/msctf/msctf.c @@ -55,6 +55,7 @@ typedef struct { TF_LANGUAGEPROFILE LanguageProfile; ITfTextInputProcessor *pITfTextInputProcessor; ITfThreadMgr *pITfThreadMgr; + ITfKeyEventSink *pITfKeyEventSink; TfClientId tid; } ActivatedTextService; @@ -378,6 +379,7 @@ HRESULT add_active_textservice(TF_LANGUAGEPROFILE *lp) actsvr->pITfTextInputProcessor = NULL; actsvr->LanguageProfile = *lp; actsvr->LanguageProfile.fActive = TRUE; + actsvr->pITfKeyEventSink = NULL; /* get TIP category */ if (SUCCEEDED(CategoryMgr_Constructor(NULL,(IUnknown**)&catmgr))) @@ -456,6 +458,50 @@ HRESULT deactivate_textservices(void) return S_OK; } +CLSID get_textservice_clsid(TfClientId tid) +{ + AtsEntry *ats; + + LIST_FOR_EACH_ENTRY(ats, &AtsList, AtsEntry, entry) + if (ats->ats->tid == tid) + return ats->ats->LanguageProfile.clsid; + return GUID_NULL; +} + +HRESULT get_textservice_sink(TfClientId tid, REFCLSID iid, IUnknown **sink) +{ + AtsEntry *ats; + + if (!IsEqualCLSID(iid,&IID_ITfKeyEventSink)) + return E_NOINTERFACE; + + LIST_FOR_EACH_ENTRY(ats, &AtsList, AtsEntry, entry) + if (ats->ats->tid == tid) + { + *sink = (IUnknown*)ats->ats->pITfKeyEventSink; + return S_OK; + } + + return E_FAIL; +} + +HRESULT set_textservice_sink(TfClientId tid, REFCLSID iid, IUnknown* sink) +{ + AtsEntry *ats; + + if (!IsEqualCLSID(iid,&IID_ITfKeyEventSink)) + return E_NOINTERFACE; + + LIST_FOR_EACH_ENTRY(ats, &AtsList, AtsEntry, entry) + if (ats->ats->tid == tid) + { + ats->ats->pITfKeyEventSink = (ITfKeyEventSink*)sink; + return S_OK; + } + + return E_FAIL; +} + /************************************************************************* * MSCTF DllMain */ diff --git a/dlls/msctf/msctf_internal.h b/dlls/msctf/msctf_internal.h index 433b79ea6af..15950ed616c 100644 --- a/dlls/msctf/msctf_internal.h +++ b/dlls/msctf/msctf_internal.h @@ -24,6 +24,7 @@ #define COOKIE_MAGIC_TMSINK 0x0010 #define COOKIE_MAGIC_CONTEXTSINK 0x0020 #define COOKIE_MAGIC_GUIDATOM 0x0030 +#define COOKIE_MAGIC_IPPSINK 0x0040 extern DWORD tlsIndex; extern TfClientId processId; @@ -47,5 +48,9 @@ extern BOOL get_active_textservice(REFCLSID rclsid, TF_LANGUAGEPROFILE *lp); extern HRESULT activate_textservices(ITfThreadMgr *tm); extern HRESULT deactivate_textservices(void); +extern CLSID get_textservice_clsid(TfClientId tid); +extern HRESULT get_textservice_sink(TfClientId tid, REFCLSID iid, IUnknown** sink); +extern HRESULT set_textservice_sink(TfClientId tid, REFCLSID iid, IUnknown* sink); + extern const WCHAR szwSystemTIPKey[]; #endif /* __WINE_MSCTF_I_H */ diff --git a/dlls/msctf/tests/inputprocessor.c b/dlls/msctf/tests/inputprocessor.c index 7ba9140573a..a3070fc41f2 100644 --- a/dlls/msctf/tests/inputprocessor.c +++ b/dlls/msctf/tests/inputprocessor.c @@ -55,235 +55,27 @@ static INT test_OnPushContext = SINK_UNEXPECTED; static INT test_OnPopContext = SINK_UNEXPECTED; static INT test_KEV_OnSetFocus = SINK_UNEXPECTED; -HRESULT RegisterTextService(REFCLSID rclsid); -HRESULT UnregisterTextService(); -HRESULT ThreadMgrEventSink_Constructor(IUnknown **ppOut); -HRESULT TextStoreACP_Constructor(IUnknown **ppOut); - -DEFINE_GUID(CLSID_FakeService, 0xEDE1A7AD,0x66DE,0x47E0,0xB6,0x20,0x3E,0x92,0xF8,0x24,0x6B,0xF3); -DEFINE_GUID(CLSID_TF_InputProcessorProfiles, 0x33c53a50,0xf456,0x4884,0xb0,0x49,0x85,0xfd,0x64,0x3e,0xcf,0xed); -DEFINE_GUID(CLSID_TF_CategoryMgr, 0xA4B544A1,0x438D,0x4B41,0x93,0x25,0x86,0x95,0x23,0xE2,0xD6,0xC7); -DEFINE_GUID(GUID_TFCAT_TIP_KEYBOARD, 0x34745c63,0xb2f0,0x4784,0x8b,0x67,0x5e,0x12,0xc8,0x70,0x1a,0x31); -DEFINE_GUID(GUID_TFCAT_TIP_SPEECH, 0xB5A73CD1,0x8355,0x426B,0xA1,0x61,0x25,0x98,0x08,0xF2,0x6B,0x14); -DEFINE_GUID(GUID_TFCAT_TIP_HANDWRITING, 0x246ecb87,0xc2f2,0x4abe,0x90,0x5b,0xc8,0xb3,0x8a,0xdd,0x2c,0x43); -DEFINE_GUID (GUID_TFCAT_DISPLAYATTRIBUTEPROVIDER, 0x046B8C80,0x1647,0x40F7,0x9B,0x21,0xB9,0x3B,0x81,0xAA,0xBC,0x1B); -DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0); -DEFINE_GUID(CLSID_TF_ThreadMgr, 0x529a9e6b,0x6587,0x4f23,0xab,0x9e,0x9c,0x7d,0x68,0x3e,0x3c,0x50); -DEFINE_GUID(CLSID_PreservedKey, 0xA0ED8E55,0xCD3B,0x4274,0xB2,0x95,0xF6,0xC9,0xBA,0x2B,0x84,0x72); - - -static HRESULT initialize(void) -{ - HRESULT hr; - CoInitialize(NULL); - hr = CoCreateInstance (&CLSID_TF_InputProcessorProfiles, NULL, - CLSCTX_INPROC_SERVER, &IID_ITfInputProcessorProfiles, (void**)&g_ipp); - if (SUCCEEDED(hr)) - hr = CoCreateInstance (&CLSID_TF_CategoryMgr, NULL, - CLSCTX_INPROC_SERVER, &IID_ITfCategoryMgr, (void**)&g_cm); - if (SUCCEEDED(hr)) - hr = CoCreateInstance (&CLSID_TF_ThreadMgr, NULL, - CLSCTX_INPROC_SERVER, &IID_ITfThreadMgr, (void**)&g_tm); - return hr; -} - -static void cleanup(void) -{ - if (g_ipp) - ITfInputProcessorProfiles_Release(g_ipp); - if (g_cm) - ITfCategoryMgr_Release(g_cm); - if (g_tm) - ITfThreadMgr_Release(g_tm); - CoUninitialize(); -} - -static void test_Register(void) -{ - HRESULT hr; - - static const WCHAR szDesc[] = {'F','a','k','e',' ','W','i','n','e',' ','S','e','r','v','i','c','e',0}; - static const WCHAR szFile[] = {'F','a','k','e',' ','W','i','n','e',' ','S','e','r','v','i','c','e',' ','F','i','l','e',0}; - - hr = ITfInputProcessorProfiles_GetCurrentLanguage(g_ipp,&gLangid); - ok(SUCCEEDED(hr),"Unable to get current language id\n"); - trace("Current Language %x\n",gLangid); - - hr = RegisterTextService(&CLSID_FakeService); - ok(SUCCEEDED(hr),"Unable to register COM for TextService\n"); - hr = ITfInputProcessorProfiles_Register(g_ipp, &CLSID_FakeService); - ok(SUCCEEDED(hr),"Unable to register text service(%x)\n",hr); - hr = ITfInputProcessorProfiles_AddLanguageProfile(g_ipp, &CLSID_FakeService, gLangid, &CLSID_FakeService, szDesc, sizeof(szDesc)/sizeof(WCHAR), szFile, sizeof(szFile)/sizeof(WCHAR), 1); - ok(SUCCEEDED(hr),"Unable to add Language Profile (%x)\n",hr); -} - -static void test_Unregister(void) -{ - HRESULT hr; - hr = ITfInputProcessorProfiles_Unregister(g_ipp, &CLSID_FakeService); - ok(SUCCEEDED(hr),"Unable to unregister text service(%x)\n",hr); - UnregisterTextService(); -} - -static void test_EnumInputProcessorInfo(void) -{ - IEnumGUID *ppEnum; - BOOL found = FALSE; - - if (SUCCEEDED(ITfInputProcessorProfiles_EnumInputProcessorInfo(g_ipp, &ppEnum))) - { - ULONG fetched; - GUID g; - while (IEnumGUID_Next(ppEnum, 1, &g, &fetched) == S_OK) - { - if(IsEqualGUID(&g,&CLSID_FakeService)) - found = TRUE; - } - } - ok(found,"Did not find registered text service\n"); -} - -static void test_EnumLanguageProfiles(void) -{ - BOOL found = FALSE; - IEnumTfLanguageProfiles *ppEnum; - if (SUCCEEDED(ITfInputProcessorProfiles_EnumLanguageProfiles(g_ipp,gLangid,&ppEnum))) - { - TF_LANGUAGEPROFILE profile; - while (IEnumTfLanguageProfiles_Next(ppEnum,1,&profile,NULL)==S_OK) - { - if (IsEqualGUID(&profile.clsid,&CLSID_FakeService)) - { - found = TRUE; - ok(profile.langid == gLangid, "LangId Incorrect\n"); - ok(IsEqualGUID(&profile.catid,&GUID_TFCAT_TIP_KEYBOARD), "CatId Incorrect\n"); - ok(IsEqualGUID(&profile.guidProfile,&CLSID_FakeService), "guidProfile Incorrect\n"); - } - } - } - ok(found,"Registered text service not found\n"); -} - -static void test_RegisterCategory(void) -{ - HRESULT hr; - hr = ITfCategoryMgr_RegisterCategory(g_cm, &CLSID_FakeService, &GUID_TFCAT_TIP_KEYBOARD, &CLSID_FakeService); - ok(SUCCEEDED(hr),"ITfCategoryMgr_RegisterCategory failed\n"); - hr = ITfCategoryMgr_RegisterCategory(g_cm, &CLSID_FakeService, &GUID_TFCAT_DISPLAYATTRIBUTEPROVIDER, &CLSID_FakeService); - ok(SUCCEEDED(hr),"ITfCategoryMgr_RegisterCategory failed\n"); -} - -static void test_UnregisterCategory(void) -{ - HRESULT hr; - hr = ITfCategoryMgr_UnregisterCategory(g_cm, &CLSID_FakeService, &GUID_TFCAT_TIP_KEYBOARD, &CLSID_FakeService); - ok(SUCCEEDED(hr),"ITfCategoryMgr_UnregisterCategory failed\n"); - hr = ITfCategoryMgr_UnregisterCategory(g_cm, &CLSID_FakeService, &GUID_TFCAT_DISPLAYATTRIBUTEPROVIDER, &CLSID_FakeService); - ok(SUCCEEDED(hr),"ITfCategoryMgr_UnregisterCategory failed\n"); -} - -static void test_FindClosestCategory(void) -{ - GUID output; - HRESULT hr; - const GUID *list[3] = {&GUID_TFCAT_TIP_SPEECH, &GUID_TFCAT_TIP_KEYBOARD, &GUID_TFCAT_TIP_HANDWRITING}; - - hr = ITfCategoryMgr_FindClosestCategory(g_cm, &CLSID_FakeService, &output, NULL, 0); - ok(SUCCEEDED(hr),"ITfCategoryMgr_FindClosestCategory failed (%x)\n",hr); - ok(IsEqualGUID(&output,&GUID_TFCAT_DISPLAYATTRIBUTEPROVIDER),"Wrong GUID\n"); - - hr = ITfCategoryMgr_FindClosestCategory(g_cm, &CLSID_FakeService, &output, list, 1); - ok(SUCCEEDED(hr),"ITfCategoryMgr_FindClosestCategory failed (%x)\n",hr); - ok(IsEqualGUID(&output,&GUID_NULL),"Wrong GUID\n"); - - hr = ITfCategoryMgr_FindClosestCategory(g_cm, &CLSID_FakeService, &output, list, 3); - ok(SUCCEEDED(hr),"ITfCategoryMgr_FindClosestCategory failed (%x)\n",hr); - ok(IsEqualGUID(&output,&GUID_TFCAT_TIP_KEYBOARD),"Wrong GUID\n"); -} - -static void test_Enable(void) -{ - HRESULT hr; - BOOL enabled = FALSE; - - hr = ITfInputProcessorProfiles_EnableLanguageProfile(g_ipp,&CLSID_FakeService, gLangid, &CLSID_FakeService, TRUE); - ok(SUCCEEDED(hr),"Failed to enable text service\n"); - hr = ITfInputProcessorProfiles_IsEnabledLanguageProfile(g_ipp,&CLSID_FakeService, gLangid, &CLSID_FakeService, &enabled); - ok(SUCCEEDED(hr),"Failed to get enabled state\n"); - ok(enabled == TRUE,"enabled state incorrect\n"); -} - -static void test_Disable(void) -{ - HRESULT hr; - - trace("Disabling\n"); - hr = ITfInputProcessorProfiles_EnableLanguageProfile(g_ipp,&CLSID_FakeService, gLangid, &CLSID_FakeService, FALSE); - ok(SUCCEEDED(hr),"Failed to disable text service\n"); -} - -static void test_ThreadMgrAdviseSinks(void) -{ - ITfSource *source = NULL; - HRESULT hr; - IUnknown *sink; - - hr = ITfThreadMgr_QueryInterface(g_tm, &IID_ITfSource, (LPVOID*)&source); - ok(SUCCEEDED(hr),"Failed to get IID_ITfSource for ThreadMgr\n"); - if (!source) - return; - - ThreadMgrEventSink_Constructor(&sink); - - tmSinkRefCount = 1; - tmSinkCookie = 0; - hr = ITfSource_AdviseSink(source,&IID_ITfThreadMgrEventSink, sink, &tmSinkCookie); - ok(SUCCEEDED(hr),"Failed to Advise Sink\n"); - ok(tmSinkCookie!=0,"Failed to get sink cookie\n"); - - /* Advising the sink adds a ref, Relesing here lets the object be deleted - when unadvised */ - tmSinkRefCount = 2; - IUnknown_Release(sink); - ITfSource_Release(source); -} - -static void test_ThreadMgrUnadviseSinks(void) -{ - ITfSource *source = NULL; - HRESULT hr; - - hr = ITfThreadMgr_QueryInterface(g_tm, &IID_ITfSource, (LPVOID*)&source); - ok(SUCCEEDED(hr),"Failed to get IID_ITfSource for ThreadMgr\n"); - if (!source) - return; - - tmSinkRefCount = 1; - hr = ITfSource_UnadviseSink(source, tmSinkCookie); - ok(SUCCEEDED(hr),"Failed to unadvise Sink\n"); - ITfSource_Release(source); -} /********************************************************************** - * ITfKeyEventSink + * ITextStoreACP **********************************************************************/ -typedef struct tagKeyEventSink +typedef struct tagTextStoreACP { - const ITfKeyEventSinkVtbl *KeyEventSinkVtbl; + const ITextStoreACPVtbl *TextStoreACPVtbl; LONG refCount; -} KeyEventSink; +} TextStoreACP; -static void KeyEventSink_Destructor(KeyEventSink *This) +static void TextStoreACP_Destructor(TextStoreACP *This) { HeapFree(GetProcessHeap(),0,This); } -static HRESULT WINAPI KeyEventSink_QueryInterface(ITfKeyEventSink *iface, REFIID iid, LPVOID *ppvOut) +static HRESULT WINAPI TextStoreACP_QueryInterface(ITextStoreACP *iface, REFIID iid, LPVOID *ppvOut) { - KeyEventSink *This = (KeyEventSink *)iface; + TextStoreACP *This = (TextStoreACP *)iface; *ppvOut = NULL; - if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_ITfKeyEventSink)) + if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_ITextStoreACP)) { *ppvOut = This; } @@ -297,449 +89,479 @@ static HRESULT WINAPI KeyEventSink_QueryInterface(ITfKeyEventSink *iface, REFIID return E_NOINTERFACE; } -static ULONG WINAPI KeyEventSink_AddRef(ITfKeyEventSink *iface) +static ULONG WINAPI TextStoreACP_AddRef(ITextStoreACP *iface) { - KeyEventSink *This = (KeyEventSink *)iface; + TextStoreACP *This = (TextStoreACP *)iface; return InterlockedIncrement(&This->refCount); } -static ULONG WINAPI KeyEventSink_Release(ITfKeyEventSink *iface) +static ULONG WINAPI TextStoreACP_Release(ITextStoreACP *iface) { - KeyEventSink *This = (KeyEventSink *)iface; + TextStoreACP *This = (TextStoreACP *)iface; ULONG ret; ret = InterlockedDecrement(&This->refCount); if (ret == 0) - KeyEventSink_Destructor(This); + TextStoreACP_Destructor(This); return ret; } -static HRESULT WINAPI KeyEventSink_OnSetFocus(ITfKeyEventSink *iface, - BOOL fForeground) -{ - ok(test_KEV_OnSetFocus == SINK_EXPECTED,"Unexpected KeyEventSink_OnSetFocus\n"); - test_KEV_OnSetFocus = SINK_FIRED; - return S_OK; -} - -static HRESULT WINAPI KeyEventSink_OnTestKeyDown(ITfKeyEventSink *iface, - ITfContext *pic, WPARAM wParam, LPARAM lParam, BOOL *pfEaten) +static HRESULT WINAPI TextStoreACP_AdviseSink(ITextStoreACP *iface, + REFIID riid, IUnknown *punk, DWORD dwMask) { trace("\n"); return S_OK; } -static HRESULT WINAPI KeyEventSink_OnTestKeyUp(ITfKeyEventSink *iface, - ITfContext *pic, WPARAM wParam, LPARAM lParam, BOOL *pfEaten) +static HRESULT WINAPI TextStoreACP_UnadviseSink(ITextStoreACP *iface, + IUnknown *punk) { trace("\n"); return S_OK; } - -static HRESULT WINAPI KeyEventSink_OnKeyDown(ITfKeyEventSink *iface, - ITfContext *pic, WPARAM wParam, LPARAM lParam, BOOL *pfEaten) +static HRESULT WINAPI TextStoreACP_RequestLock(ITextStoreACP *iface, + DWORD dwLockFlags, HRESULT *phrSession) { trace("\n"); return S_OK; } - -static HRESULT WINAPI KeyEventSink_OnKeyUp(ITfKeyEventSink *iface, - ITfContext *pic, WPARAM wParam, LPARAM lParam, BOOL *pfEaten) +static HRESULT WINAPI TextStoreACP_GetStatus(ITextStoreACP *iface, + TS_STATUS *pdcs) { trace("\n"); return S_OK; } - -static HRESULT WINAPI KeyEventSink_OnPreservedKey(ITfKeyEventSink *iface, - ITfContext *pic, REFGUID rguid, BOOL *pfEaten) +static HRESULT WINAPI TextStoreACP_QueryInsert(ITextStoreACP *iface, + LONG acpTestStart, LONG acpTestEnd, ULONG cch, LONG *pacpResultStart, + LONG *pacpResultEnd) +{ + trace("\n"); + return S_OK; +} +static HRESULT WINAPI TextStoreACP_GetSelection(ITextStoreACP *iface, + ULONG ulIndex, ULONG ulCount, TS_SELECTION_ACP *pSelection, ULONG *pcFetched) +{ + trace("\n"); + return S_OK; +} +static HRESULT WINAPI TextStoreACP_SetSelection(ITextStoreACP *iface, + ULONG ulCount, const TS_SELECTION_ACP *pSelection) +{ + trace("\n"); + return S_OK; +} +static HRESULT WINAPI TextStoreACP_GetText(ITextStoreACP *iface, + LONG acpStart, LONG acpEnd, WCHAR *pchPlain, ULONG cchPlainReq, + ULONG *pcchPlainRet, TS_RUNINFO *prgRunInfo, ULONG cRunInfoReq, + ULONG *pcRunInfoRet, LONG *pacpNext) +{ + trace("\n"); + return S_OK; +} +static HRESULT WINAPI TextStoreACP_SetText(ITextStoreACP *iface, + DWORD dwFlags, LONG acpStart, LONG acpEnd, const WCHAR *pchText, + ULONG cch, TS_TEXTCHANGE *pChange) +{ + trace("\n"); + return S_OK; +} +static HRESULT WINAPI TextStoreACP_GetFormattedText(ITextStoreACP *iface, + LONG acpStart, LONG acpEnd, IDataObject **ppDataObject) +{ + trace("\n"); + return S_OK; +} +static HRESULT WINAPI TextStoreACP_GetEmbedded(ITextStoreACP *iface, + LONG acpPos, REFGUID rguidService, REFIID riid, IUnknown **ppunk) +{ + trace("\n"); + return S_OK; +} +static HRESULT WINAPI TextStoreACP_QueryInsertEmbedded(ITextStoreACP *iface, + const GUID *pguidService, const FORMATETC *pFormatEtc, BOOL *pfInsertable) +{ + trace("\n"); + return S_OK; +} +static HRESULT WINAPI TextStoreACP_InsertEmbedded(ITextStoreACP *iface, + DWORD dwFlags, LONG acpStart, LONG acpEnd, IDataObject *pDataObject, + TS_TEXTCHANGE *pChange) +{ + trace("\n"); + return S_OK; +} +static HRESULT WINAPI TextStoreACP_InsertTextAtSelection(ITextStoreACP *iface, + DWORD dwFlags, const WCHAR *pchText, ULONG cch, LONG *pacpStart, + LONG *pacpEnd, TS_TEXTCHANGE *pChange) +{ + trace("\n"); + return S_OK; +} +static HRESULT WINAPI TextStoreACP_InsertEmbeddedAtSelection(ITextStoreACP *iface, + DWORD dwFlags, IDataObject *pDataObject, LONG *pacpStart, LONG *pacpEnd, + TS_TEXTCHANGE *pChange) +{ + trace("\n"); + return S_OK; +} +static HRESULT WINAPI TextStoreACP_RequestSupportedAttrs(ITextStoreACP *iface, + DWORD dwFlags, ULONG cFilterAttrs, const TS_ATTRID *paFilterAttrs) +{ + trace("\n"); + return S_OK; +} +static HRESULT WINAPI TextStoreACP_RequestAttrsAtPosition(ITextStoreACP *iface, + LONG acpPos, ULONG cFilterAttrs, const TS_ATTRID *paFilterAttrs, + DWORD dwFlags) +{ + trace("\n"); + return S_OK; +} +static HRESULT WINAPI TextStoreACP_RequestAttrsTransitioningAtPosition(ITextStoreACP *iface, + LONG acpPos, ULONG cFilterAttrs, const TS_ATTRID *paFilterAttrs, + DWORD dwFlags) +{ + trace("\n"); + return S_OK; +} +static HRESULT WINAPI TextStoreACP_FindNextAttrTransition(ITextStoreACP *iface, + LONG acpStart, LONG acpHalt, ULONG cFilterAttrs, const TS_ATTRID *paFilterAttrs, + DWORD dwFlags, LONG *pacpNext, BOOL *pfFound, LONG *plFoundOffset) +{ + trace("\n"); + return S_OK; +} +static HRESULT WINAPI TextStoreACP_RetrieveRequestedAttrs(ITextStoreACP *iface, + ULONG ulCount, TS_ATTRVAL *paAttrVals, ULONG *pcFetched) +{ + trace("\n"); + return S_OK; +} +static HRESULT WINAPI TextStoreACP_GetEndACP(ITextStoreACP *iface, + LONG *pacp) +{ + trace("\n"); + return S_OK; +} +static HRESULT WINAPI TextStoreACP_GetActiveView(ITextStoreACP *iface, + TsViewCookie *pvcView) +{ + trace("\n"); + return S_OK; +} +static HRESULT WINAPI TextStoreACP_GetACPFromPoint(ITextStoreACP *iface, + TsViewCookie vcView, const POINT *ptScreen, DWORD dwFlags, + LONG *pacp) +{ + trace("\n"); + return S_OK; +} +static HRESULT WINAPI TextStoreACP_GetTextExt(ITextStoreACP *iface, + TsViewCookie vcView, LONG acpStart, LONG acpEnd, RECT *prc, + BOOL *pfClipped) +{ + trace("\n"); + return S_OK; +} +static HRESULT WINAPI TextStoreACP_GetScreenExt(ITextStoreACP *iface, + TsViewCookie vcView, RECT *prc) +{ + trace("\n"); + return S_OK; +} +static HRESULT WINAPI TextStoreACP_GetWnd(ITextStoreACP *iface, + TsViewCookie vcView, HWND *phwnd) { trace("\n"); return S_OK; } -static const ITfKeyEventSinkVtbl KeyEventSink_KeyEventSinkVtbl = +static const ITextStoreACPVtbl TextStoreACP_TextStoreACPVtbl = { - KeyEventSink_QueryInterface, - KeyEventSink_AddRef, - KeyEventSink_Release, + TextStoreACP_QueryInterface, + TextStoreACP_AddRef, + TextStoreACP_Release, - KeyEventSink_OnSetFocus, - KeyEventSink_OnTestKeyDown, - KeyEventSink_OnTestKeyUp, - KeyEventSink_OnKeyDown, - KeyEventSink_OnKeyUp, - KeyEventSink_OnPreservedKey + TextStoreACP_AdviseSink, + TextStoreACP_UnadviseSink, + TextStoreACP_RequestLock, + TextStoreACP_GetStatus, + TextStoreACP_QueryInsert, + TextStoreACP_GetSelection, + TextStoreACP_SetSelection, + TextStoreACP_GetText, + TextStoreACP_SetText, + TextStoreACP_GetFormattedText, + TextStoreACP_GetEmbedded, + TextStoreACP_QueryInsertEmbedded, + TextStoreACP_InsertEmbedded, + TextStoreACP_InsertTextAtSelection, + TextStoreACP_InsertEmbeddedAtSelection, + TextStoreACP_RequestSupportedAttrs, + TextStoreACP_RequestAttrsAtPosition, + TextStoreACP_RequestAttrsTransitioningAtPosition, + TextStoreACP_FindNextAttrTransition, + TextStoreACP_RetrieveRequestedAttrs, + TextStoreACP_GetEndACP, + TextStoreACP_GetActiveView, + TextStoreACP_GetACPFromPoint, + TextStoreACP_GetTextExt, + TextStoreACP_GetScreenExt, + TextStoreACP_GetWnd }; -HRESULT KeyEventSink_Constructor(ITfKeyEventSink **ppOut) +static HRESULT TextStoreACP_Constructor(IUnknown **ppOut) { - KeyEventSink *This; + TextStoreACP *This; - This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(KeyEventSink)); + This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(TextStoreACP)); if (This == NULL) return E_OUTOFMEMORY; - This->KeyEventSinkVtbl = &KeyEventSink_KeyEventSinkVtbl; + This->TextStoreACPVtbl = &TextStoreACP_TextStoreACPVtbl; This->refCount = 1; - *ppOut = (ITfKeyEventSink*)This; + *ppOut = (IUnknown *)This; return S_OK; } - -static void test_KeystrokeMgr(void) -{ - ITfKeystrokeMgr *keymgr= NULL; - HRESULT hr; - TF_PRESERVEDKEY tfpk; - BOOL preserved; - ITfKeyEventSink *sink; - - KeyEventSink_Constructor(&sink); - - hr = ITfThreadMgr_QueryInterface(g_tm, &IID_ITfKeystrokeMgr, (LPVOID*)&keymgr); - ok(SUCCEEDED(hr),"Failed to get IID_ITfKeystrokeMgr for ThreadMgr\n"); - - tfpk.uVKey = 'A'; - tfpk.uModifiers = TF_MOD_SHIFT; - - test_KEV_OnSetFocus = SINK_EXPECTED; - hr = ITfKeystrokeMgr_AdviseKeyEventSink(keymgr,tid,sink,TRUE); - todo_wine ok(SUCCEEDED(hr),"ITfKeystrokeMgr_AdviseKeyEventSink failed\n"); - todo_wine ok(test_KEV_OnSetFocus == SINK_FIRED, "KeyEventSink_OnSetFocus not fired as expected\n"); - - hr =ITfKeystrokeMgr_PreserveKey(keymgr, 0, &CLSID_PreservedKey, &tfpk, NULL, 0); - ok(hr==E_INVALIDARG,"ITfKeystrokeMgr_PreserveKey inproperly succeeded\n"); - - hr =ITfKeystrokeMgr_PreserveKey(keymgr, tid, &CLSID_PreservedKey, &tfpk, NULL, 0); - ok(SUCCEEDED(hr),"ITfKeystrokeMgr_PreserveKey failed\n"); - - hr =ITfKeystrokeMgr_PreserveKey(keymgr, tid, &CLSID_PreservedKey, &tfpk, NULL, 0); - ok(hr == TF_E_ALREADY_EXISTS,"ITfKeystrokeMgr_PreserveKey inproperly succeeded\n"); - - preserved = FALSE; - hr = ITfKeystrokeMgr_IsPreservedKey(keymgr, &CLSID_PreservedKey, &tfpk, &preserved); - ok(hr == S_OK, "ITfKeystrokeMgr_IsPreservedKey failed\n"); - if (hr == S_OK) ok(preserved == TRUE,"misreporting preserved key\n"); - - hr = ITfKeystrokeMgr_UnpreserveKey(keymgr, &CLSID_PreservedKey,&tfpk); - ok(SUCCEEDED(hr),"ITfKeystrokeMgr_UnpreserveKey failed\n"); - - hr = ITfKeystrokeMgr_IsPreservedKey(keymgr, &CLSID_PreservedKey, &tfpk, &preserved); - ok(hr == S_FALSE, "ITfKeystrokeMgr_IsPreservedKey failed\n"); - if (hr == S_FALSE) ok(preserved == FALSE,"misreporting preserved key\n"); - - hr = ITfKeystrokeMgr_UnpreserveKey(keymgr, &CLSID_PreservedKey,&tfpk); - ok(hr==CONNECT_E_NOCONNECTION,"ITfKeystrokeMgr_UnpreserveKey inproperly succeeded\n"); - - hr = ITfKeystrokeMgr_UnadviseKeyEventSink(keymgr,tid); - todo_wine ok(SUCCEEDED(hr),"ITfKeystrokeMgr_UnadviseKeyEventSink failed\n"); - - ITfKeystrokeMgr_Release(keymgr); - ITfKeyEventSink_Release(sink); -} - -static void test_Activate(void) +/********************************************************************** + * ITfThreadMgrEventSink + **********************************************************************/ +typedef struct tagThreadMgrEventSink { - HRESULT hr; - - hr = ITfInputProcessorProfiles_ActivateLanguageProfile(g_ipp,&CLSID_FakeService,gLangid,&CLSID_FakeService); - ok(SUCCEEDED(hr),"Failed to Activate text service\n"); -} + const ITfThreadMgrEventSinkVtbl *ThreadMgrEventSinkVtbl; + LONG refCount; +} ThreadMgrEventSink; -static inline int check_context_refcount(ITfContext *iface) +static void ThreadMgrEventSink_Destructor(ThreadMgrEventSink *This) { - IUnknown_AddRef(iface); - return IUnknown_Release(iface); + HeapFree(GetProcessHeap(),0,This); } -static void test_startSession(void) +static HRESULT WINAPI ThreadMgrEventSink_QueryInterface(ITfThreadMgrEventSink *iface, REFIID iid, LPVOID *ppvOut) { - HRESULT hr; - DWORD cnt; - DWORD editCookie; - ITfDocumentMgr *dmtest; - ITfContext *cxt,*cxt2,*cxt3,*cxtTest; - ITextStoreACP *ts; - TfClientId cid2 = 0; - - hr = ITfThreadMgr_Deactivate(g_tm); - ok(hr == E_UNEXPECTED,"Deactivate should have failed with E_UNEXPECTED\n"); - - test_ShouldActivate = TRUE; - hr = ITfThreadMgr_Activate(g_tm,&cid); - ok(SUCCEEDED(hr),"Failed to Activate\n"); - ok(cid != tid,"TextService id mistakenly matches Client id\n"); - - test_ShouldActivate = FALSE; - hr = ITfThreadMgr_Activate(g_tm,&cid2); - ok(SUCCEEDED(hr),"Failed to Activate\n"); - ok (cid == cid2, "Second activate client ID does not match\n"); - - hr = ITfThreadMgr_Deactivate(g_tm); - ok(SUCCEEDED(hr),"Failed to Deactivate\n"); - - hr = ITfThreadMgr_CreateDocumentMgr(g_tm,&g_dm); - ok(SUCCEEDED(hr),"CreateDocumentMgr failed\n"); - - hr = ITfThreadMgr_GetFocus(g_tm,&dmtest); - ok(SUCCEEDED(hr),"GetFocus Failed\n"); - ok(dmtest == NULL,"Initial focus not null\n"); - - test_CurrentFocus = g_dm; - test_PrevFocus = NULL; - test_OnSetFocus = SINK_EXPECTED; - hr = ITfThreadMgr_SetFocus(g_tm,g_dm); - ok(SUCCEEDED(hr),"SetFocus Failed\n"); - ok(test_OnSetFocus == SINK_FIRED, "OnSetFocus sink not called\n"); - test_OnSetFocus = SINK_UNEXPECTED; + ThreadMgrEventSink *This = (ThreadMgrEventSink *)iface; + *ppvOut = NULL; - hr = ITfThreadMgr_GetFocus(g_tm,&dmtest); - ok(SUCCEEDED(hr),"GetFocus Failed\n"); - ok(g_dm == dmtest,"Expected DocumentMgr not focused\n"); + if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_ITfThreadMgrEventSink)) + { + *ppvOut = This; + } - cnt = ITfDocumentMgr_Release(g_dm); - ok(cnt == 2,"DocumentMgr refcount not expected (2 vs %i)\n",cnt); + if (*ppvOut) + { + IUnknown_AddRef(iface); + return S_OK; + } - hr = ITfThreadMgr_GetFocus(g_tm,&dmtest); - ok(SUCCEEDED(hr),"GetFocus Failed\n"); - ok(g_dm == dmtest,"Expected DocumentMgr not focused\n"); + return E_NOINTERFACE; +} - TextStoreACP_Constructor((IUnknown**)&ts); +static ULONG WINAPI ThreadMgrEventSink_AddRef(ITfThreadMgrEventSink *iface) +{ + ThreadMgrEventSink *This = (ThreadMgrEventSink *)iface; + ok (tmSinkRefCount == This->refCount,"ThreadMgrEventSink refcount off %i vs %i\n",This->refCount,tmSinkRefCount); + return InterlockedIncrement(&This->refCount); +} - hr = ITfDocumentMgr_CreateContext(g_dm, cid, 0, (IUnknown*)ts, &cxt, &editCookie); - ok(SUCCEEDED(hr),"CreateContext Failed\n"); +static ULONG WINAPI ThreadMgrEventSink_Release(ITfThreadMgrEventSink *iface) +{ + ThreadMgrEventSink *This = (ThreadMgrEventSink *)iface; + ULONG ret; - hr = ITfDocumentMgr_CreateContext(g_dm, cid, 0, NULL, &cxt2, &editCookie); - ok(SUCCEEDED(hr),"CreateContext Failed\n"); + ok (tmSinkRefCount == This->refCount,"ThreadMgrEventSink refcount off %i vs %i\n",This->refCount,tmSinkRefCount); + ret = InterlockedDecrement(&This->refCount); + if (ret == 0) + ThreadMgrEventSink_Destructor(This); + return ret; +} - hr = ITfDocumentMgr_CreateContext(g_dm, cid, 0, NULL, &cxt3, &editCookie); - ok(SUCCEEDED(hr),"CreateContext Failed\n"); +static HRESULT WINAPI ThreadMgrEventSink_OnInitDocumentMgr(ITfThreadMgrEventSink *iface, +ITfDocumentMgr *pdim) +{ + ok(test_OnInitDocumentMgr == SINK_EXPECTED, "Unexpected OnInitDocumentMgr sink\n"); + test_OnInitDocumentMgr = SINK_FIRED; + return S_OK; +} - cnt = check_context_refcount(cxt); - test_OnPushContext = SINK_EXPECTED; - test_OnInitDocumentMgr = SINK_EXPECTED; - hr = ITfDocumentMgr_Push(g_dm, cxt); - ok(SUCCEEDED(hr),"Push Failed\n"); - ok(check_context_refcount(cxt) > cnt, "Ref count did not increase\n"); - ok(test_OnPushContext == SINK_FIRED, "OnPushContext sink not fired\n"); - ok(test_OnInitDocumentMgr == SINK_FIRED, "OnInitDocumentMgr sink not fired\n"); +static HRESULT WINAPI ThreadMgrEventSink_OnUninitDocumentMgr(ITfThreadMgrEventSink *iface, +ITfDocumentMgr *pdim) +{ + trace("\n"); + return S_OK; +} - hr = ITfDocumentMgr_GetTop(g_dm, &cxtTest); - ok(SUCCEEDED(hr),"GetTop Failed\n"); - ok(cxtTest == cxt, "Wrong context on top\n"); - ok(check_context_refcount(cxt) > cnt, "Ref count did not increase\n"); - cnt = ITfContext_Release(cxtTest); +static HRESULT WINAPI ThreadMgrEventSink_OnSetFocus(ITfThreadMgrEventSink *iface, +ITfDocumentMgr *pdimFocus, ITfDocumentMgr *pdimPrevFocus) +{ + ok(test_OnSetFocus == SINK_EXPECTED, "Unexpected OnSetFocus sink\n"); + ok(pdimFocus == test_CurrentFocus,"Sink reports wrong focus\n"); + ok(pdimPrevFocus == test_PrevFocus,"Sink reports wrong previous focus\n"); + test_OnSetFocus = SINK_FIRED; + return S_OK; +} - hr = ITfDocumentMgr_GetBase(g_dm, &cxtTest); - ok(SUCCEEDED(hr),"GetBase Failed\n"); - ok(cxtTest == cxt, "Wrong context on Base\n"); - ok(check_context_refcount(cxt) > cnt, "Ref count did not increase\n"); - ITfContext_Release(cxtTest); +static HRESULT WINAPI ThreadMgrEventSink_OnPushContext(ITfThreadMgrEventSink *iface, +ITfContext *pic) +{ + ok(test_OnPushContext == SINK_EXPECTED, "Unexpected OnPushContext sink\n"); + test_OnPushContext = SINK_FIRED; + return S_OK; +} - check_context_refcount(cxt2); - test_OnPushContext = SINK_EXPECTED; - hr = ITfDocumentMgr_Push(g_dm, cxt2); - ok(SUCCEEDED(hr),"Push Failed\n"); - ok(test_OnPushContext == SINK_FIRED, "OnPushContext sink not fired\n"); +static HRESULT WINAPI ThreadMgrEventSink_OnPopContext(ITfThreadMgrEventSink *iface, +ITfContext *pic) +{ + ok(test_OnPopContext == SINK_EXPECTED, "Unexpected OnPopContext sink\n"); + test_OnPopContext = SINK_FIRED; + return S_OK; +} - cnt = check_context_refcount(cxt2); - hr = ITfDocumentMgr_GetTop(g_dm, &cxtTest); - ok(SUCCEEDED(hr),"GetTop Failed\n"); - ok(cxtTest == cxt2, "Wrong context on top\n"); - ok(check_context_refcount(cxt2) > cnt, "Ref count did not increase\n"); - ITfContext_Release(cxtTest); +static const ITfThreadMgrEventSinkVtbl ThreadMgrEventSink_ThreadMgrEventSinkVtbl = +{ + ThreadMgrEventSink_QueryInterface, + ThreadMgrEventSink_AddRef, + ThreadMgrEventSink_Release, - cnt = check_context_refcount(cxt); - hr = ITfDocumentMgr_GetBase(g_dm, &cxtTest); - ok(SUCCEEDED(hr),"GetBase Failed\n"); - ok(cxtTest == cxt, "Wrong context on Base\n"); - ok(check_context_refcount(cxt) > cnt, "Ref count did not increase\n"); - ITfContext_Release(cxtTest); + ThreadMgrEventSink_OnInitDocumentMgr, + ThreadMgrEventSink_OnUninitDocumentMgr, + ThreadMgrEventSink_OnSetFocus, + ThreadMgrEventSink_OnPushContext, + ThreadMgrEventSink_OnPopContext +}; - cnt = check_context_refcount(cxt3); - hr = ITfDocumentMgr_Push(g_dm, cxt3); - ok(!SUCCEEDED(hr),"Push Succeeded\n"); - ok(check_context_refcount(cxt3) == cnt, "Ref changed\n"); +static HRESULT ThreadMgrEventSink_Constructor(IUnknown **ppOut) +{ + ThreadMgrEventSink *This; - cnt = check_context_refcount(cxt2); - hr = ITfDocumentMgr_GetTop(g_dm, &cxtTest); - ok(SUCCEEDED(hr),"GetTop Failed\n"); - ok(cxtTest == cxt2, "Wrong context on top\n"); - ok(check_context_refcount(cxt2) > cnt, "Ref count did not increase\n"); - ITfContext_Release(cxtTest); + This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(ThreadMgrEventSink)); + if (This == NULL) + return E_OUTOFMEMORY; - cnt = check_context_refcount(cxt); - hr = ITfDocumentMgr_GetBase(g_dm, &cxtTest); - ok(SUCCEEDED(hr),"GetBase Failed\n"); - ok(cxtTest == cxt, "Wrong context on Base\n"); - ok(check_context_refcount(cxt) > cnt, "Ref count did not increase\n"); - ITfContext_Release(cxtTest); + This->ThreadMgrEventSinkVtbl = &ThreadMgrEventSink_ThreadMgrEventSinkVtbl; + This->refCount = 1; - cnt = check_context_refcount(cxt2); - test_OnPopContext = SINK_EXPECTED; - hr = ITfDocumentMgr_Pop(g_dm, 0); - ok(SUCCEEDED(hr),"Pop Failed\n"); - ok(check_context_refcount(cxt2) < cnt, "Ref count did not decrease\n"); - ok(test_OnPopContext == SINK_FIRED, "OnPopContext sink not fired\n"); + *ppOut = (IUnknown *)This; + return S_OK; +} - hr = ITfDocumentMgr_GetTop(g_dm, &cxtTest); - ok(SUCCEEDED(hr),"GetTop Failed\n"); - ok(cxtTest == cxt, "Wrong context on top\n"); - ITfContext_Release(cxtTest); - hr = ITfDocumentMgr_GetBase(g_dm, &cxtTest); - ok(SUCCEEDED(hr),"GetBase Failed\n"); - ok(cxtTest == cxt, "Wrong context on base\n"); - ITfContext_Release(cxtTest); +/******************************************************************************************** + * Stub text service for testing + ********************************************************************************************/ - hr = ITfDocumentMgr_Pop(g_dm, 0); - ok(!SUCCEEDED(hr),"Pop Succeeded\n"); +static LONG TS_refCount; +static IClassFactory *cf; +static DWORD regid; - hr = ITfDocumentMgr_GetTop(g_dm, &cxtTest); - ok(SUCCEEDED(hr),"GetTop Failed\n"); - ok(cxtTest == cxt, "Wrong context on top\n"); - ITfContext_Release(cxtTest); +typedef HRESULT (*LPFNCONSTRUCTOR)(IUnknown *pUnkOuter, IUnknown **ppvOut); - hr = ITfDocumentMgr_GetBase(g_dm, &cxtTest); - ok(SUCCEEDED(hr),"GetBase Failed\n"); - ok(cxtTest == cxt, "Wrong context on base\n"); - ITfContext_Release(cxtTest); +typedef struct tagClassFactory +{ + const IClassFactoryVtbl *vtbl; + LONG ref; + LPFNCONSTRUCTOR ctor; +} ClassFactory; - ITfContext_Release(cxt); - ITfContext_Release(cxt2); - ITfContext_Release(cxt3); -} +typedef struct tagTextService +{ + const ITfTextInputProcessorVtbl *TextInputProcessorVtbl; + LONG refCount; +} TextService; -static void test_endSession(void) +static void ClassFactory_Destructor(ClassFactory *This) { - HRESULT hr; - test_ShouldDeactivate = TRUE; - test_CurrentFocus = NULL; - test_PrevFocus = g_dm; - test_OnSetFocus = SINK_EXPECTED; - hr = ITfThreadMgr_Deactivate(g_tm); - ok(SUCCEEDED(hr),"Failed to Deactivate\n"); - ok(test_OnSetFocus == SINK_FIRED, "OnSetFocus sink not called\n"); - test_OnSetFocus = SINK_UNEXPECTED; + HeapFree(GetProcessHeap(),0,This); + TS_refCount--; } -static void test_TfGuidAtom(void) +static HRESULT WINAPI ClassFactory_QueryInterface(IClassFactory *iface, REFIID riid, LPVOID *ppvOut) { - GUID gtest,g1; - HRESULT hr; - TfGuidAtom atom1,atom2; - BOOL equal; + *ppvOut = NULL; + if (IsEqualIID(riid, &IID_IClassFactory) || IsEqualIID(riid, &IID_IUnknown)) + { + IClassFactory_AddRef(iface); + *ppvOut = iface; + return S_OK; + } - CoCreateGuid(>est); + return E_NOINTERFACE; +} - /* msdn reports this should return E_INVALIDARG. However my test show it crashing (winxp)*/ - /* - hr = ITfCategoryMgr_RegisterGUID(g_cm,>est,NULL); - ok(hr==E_INVALIDARG,"ITfCategoryMgr_RegisterGUID should have failed\n"); - */ - hr = ITfCategoryMgr_RegisterGUID(g_cm,>est,&atom1); - ok(SUCCEEDED(hr),"ITfCategoryMgr_RegisterGUID failed\n"); - hr = ITfCategoryMgr_RegisterGUID(g_cm,>est,&atom2); - ok(SUCCEEDED(hr),"ITfCategoryMgr_RegisterGUID failed\n"); - ok(atom1 == atom2,"atoms do not match\n"); - hr = ITfCategoryMgr_GetGUID(g_cm,atom2,NULL); - ok(hr==E_INVALIDARG,"ITfCategoryMgr_GetGUID should have failed\n"); - hr = ITfCategoryMgr_GetGUID(g_cm,atom2,&g1); - ok(SUCCEEDED(hr),"ITfCategoryMgr_GetGUID failed\n"); - ok(IsEqualGUID(&g1,>est),"guids do not match\n"); - hr = ITfCategoryMgr_IsEqualTfGuidAtom(g_cm,atom1,>est,NULL); - ok(hr==E_INVALIDARG,"ITfCategoryMgr_IsEqualTfGuidAtom should have failed\n"); - hr = ITfCategoryMgr_IsEqualTfGuidAtom(g_cm,atom1,>est,&equal); - ok(SUCCEEDED(hr),"ITfCategoryMgr_IsEqualTfGuidAtom failed\n"); - ok(equal == TRUE,"Equal value invalid\n"); +static ULONG WINAPI ClassFactory_AddRef(IClassFactory *iface) +{ + ClassFactory *This = (ClassFactory *)iface; + return InterlockedIncrement(&This->ref); +} - /* show that cid and tid TfClientIds are also TfGuidAtoms */ - hr = ITfCategoryMgr_IsEqualTfGuidAtom(g_cm,tid,&CLSID_FakeService,&equal); - ok(SUCCEEDED(hr),"ITfCategoryMgr_IsEqualTfGuidAtom failed\n"); - ok(equal == TRUE,"Equal value invalid\n"); - hr = ITfCategoryMgr_GetGUID(g_cm,cid,&g1); - ok(SUCCEEDED(hr),"ITfCategoryMgr_GetGUID failed\n"); - ok(!IsEqualGUID(&g1,&GUID_NULL),"guid should not be NULL\n"); +static ULONG WINAPI ClassFactory_Release(IClassFactory *iface) +{ + ClassFactory *This = (ClassFactory *)iface; + ULONG ret = InterlockedDecrement(&This->ref); + + if (ret == 0) + ClassFactory_Destructor(This); + return ret; } -static void test_ClientId(void) +static HRESULT WINAPI ClassFactory_CreateInstance(IClassFactory *iface, IUnknown *punkOuter, REFIID iid, LPVOID *ppvOut) { - ITfClientId *pcid; - TfClientId id1,id2; - HRESULT hr; - GUID g2; - - hr = ITfThreadMgr_QueryInterface(g_tm, &IID_ITfClientId, (LPVOID*)&pcid); - ok(SUCCEEDED(hr),"Unable to aquire ITfClientId interface\n"); - - CoCreateGuid(&g2); + ClassFactory *This = (ClassFactory *)iface; + HRESULT ret; + IUnknown *obj; - hr = ITfClientId_GetClientId(pcid,&GUID_NULL,&id1); - ok(SUCCEEDED(hr),"GetClientId failed\n"); - hr = ITfClientId_GetClientId(pcid,&GUID_NULL,&id2); - ok(SUCCEEDED(hr),"GetClientId failed\n"); - ok(id1==id2,"Id's for GUID_NULL do not match\n"); - hr = ITfClientId_GetClientId(pcid,&CLSID_FakeService,&id2); - ok(SUCCEEDED(hr),"GetClientId failed\n"); - ok(id2!=id1,"Id matches GUID_NULL\n"); - ok(id2==tid,"Id for CLSID_FakeService not matching tid\n"); - ok(id2!=cid,"Id for CLSID_FakeService matching cid\n"); - hr = ITfClientId_GetClientId(pcid,&g2,&id2); - ok(SUCCEEDED(hr),"GetClientId failed\n"); - ok(id2!=id1,"Id matches GUID_NULL\n"); - ok(id2!=tid,"Id for random guid matching tid\n"); - ok(id2!=cid,"Id for random guid matching cid\n"); - ITfClientId_Release(pcid); + ret = This->ctor(punkOuter, &obj); + if (FAILED(ret)) + return ret; + ret = IUnknown_QueryInterface(obj, iid, ppvOut); + IUnknown_Release(obj); + return ret; } -START_TEST(inputprocessor) +static HRESULT WINAPI ClassFactory_LockServer(IClassFactory *iface, BOOL fLock) { - if (SUCCEEDED(initialize())) - { - test_Register(); - test_RegisterCategory(); - test_EnumInputProcessorInfo(); - test_Enable(); - test_ThreadMgrAdviseSinks(); - test_Activate(); - test_startSession(); - test_TfGuidAtom(); - test_ClientId(); - test_KeystrokeMgr(); - test_endSession(); - test_EnumLanguageProfiles(); - test_FindClosestCategory(); - test_Disable(); - test_ThreadMgrUnadviseSinks(); - test_UnregisterCategory(); - test_Unregister(); - } + if(fLock) + InterlockedIncrement(&TS_refCount); else - skip("Unable to create InputProcessor\n"); - cleanup(); + InterlockedDecrement(&TS_refCount); + + return S_OK; } -/********************************************************************** - * ITextStoreACP - **********************************************************************/ -typedef struct tagTextStoreACP +static const IClassFactoryVtbl ClassFactoryVtbl = { + /* IUnknown */ + ClassFactory_QueryInterface, + ClassFactory_AddRef, + ClassFactory_Release, + + /* IClassFactory*/ + ClassFactory_CreateInstance, + ClassFactory_LockServer +}; + +static HRESULT ClassFactory_Constructor(LPFNCONSTRUCTOR ctor, LPVOID *ppvOut) { - const ITextStoreACPVtbl *TextStoreACPVtbl; - LONG refCount; -} TextStoreACP; + ClassFactory *This = HeapAlloc(GetProcessHeap(),0,sizeof(ClassFactory)); + This->vtbl = &ClassFactoryVtbl; + This->ref = 1; + This->ctor = ctor; + *ppvOut = (LPVOID)This; + TS_refCount++; + return S_OK; +} -static void TextStoreACP_Destructor(TextStoreACP *This) +static void TextService_Destructor(TextService *This) { HeapFree(GetProcessHeap(),0,This); } -static HRESULT WINAPI TextStoreACP_QueryInterface(ITextStoreACP *iface, REFIID iid, LPVOID *ppvOut) +static HRESULT WINAPI TextService_QueryInterface(ITfTextInputProcessor *iface, REFIID iid, LPVOID *ppvOut) { - TextStoreACP *This = (TextStoreACP *)iface; + TextService *This = (TextService *)iface; *ppvOut = NULL; - if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_ITextStoreACP)) + if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_ITfTextInputProcessor)) { *ppvOut = This; } @@ -753,262 +575,305 @@ static HRESULT WINAPI TextStoreACP_QueryInterface(ITextStoreACP *iface, REFIID i return E_NOINTERFACE; } -static ULONG WINAPI TextStoreACP_AddRef(ITextStoreACP *iface) +static ULONG WINAPI TextService_AddRef(ITfTextInputProcessor *iface) { - TextStoreACP *This = (TextStoreACP *)iface; + TextService *This = (TextService *)iface; return InterlockedIncrement(&This->refCount); } -static ULONG WINAPI TextStoreACP_Release(ITextStoreACP *iface) +static ULONG WINAPI TextService_Release(ITfTextInputProcessor *iface) { - TextStoreACP *This = (TextStoreACP *)iface; + TextService *This = (TextService *)iface; ULONG ret; ret = InterlockedDecrement(&This->refCount); if (ret == 0) - TextStoreACP_Destructor(This); + TextService_Destructor(This); return ret; } -static HRESULT WINAPI TextStoreACP_AdviseSink(ITextStoreACP *iface, - REFIID riid, IUnknown *punk, DWORD dwMask) +static HRESULT WINAPI TextService_Activate(ITfTextInputProcessor *iface, + ITfThreadMgr *ptim, TfClientId id) { - trace("\n"); + trace("TextService_Activate\n"); + ok(test_ShouldActivate,"Activation came unexpectedly\n"); + tid = id; return S_OK; } -static HRESULT WINAPI TextStoreACP_UnadviseSink(ITextStoreACP *iface, - IUnknown *punk) -{ - trace("\n"); - return S_OK; -} -static HRESULT WINAPI TextStoreACP_RequestLock(ITextStoreACP *iface, - DWORD dwLockFlags, HRESULT *phrSession) -{ - trace("\n"); - return S_OK; -} -static HRESULT WINAPI TextStoreACP_GetStatus(ITextStoreACP *iface, - TS_STATUS *pdcs) -{ - trace("\n"); - return S_OK; -} -static HRESULT WINAPI TextStoreACP_QueryInsert(ITextStoreACP *iface, - LONG acpTestStart, LONG acpTestEnd, ULONG cch, LONG *pacpResultStart, - LONG *pacpResultEnd) -{ - trace("\n"); - return S_OK; -} -static HRESULT WINAPI TextStoreACP_GetSelection(ITextStoreACP *iface, - ULONG ulIndex, ULONG ulCount, TS_SELECTION_ACP *pSelection, ULONG *pcFetched) -{ - trace("\n"); - return S_OK; -} -static HRESULT WINAPI TextStoreACP_SetSelection(ITextStoreACP *iface, - ULONG ulCount, const TS_SELECTION_ACP *pSelection) -{ - trace("\n"); - return S_OK; -} -static HRESULT WINAPI TextStoreACP_GetText(ITextStoreACP *iface, - LONG acpStart, LONG acpEnd, WCHAR *pchPlain, ULONG cchPlainReq, - ULONG *pcchPlainRet, TS_RUNINFO *prgRunInfo, ULONG cRunInfoReq, - ULONG *pcRunInfoRet, LONG *pacpNext) -{ - trace("\n"); - return S_OK; -} -static HRESULT WINAPI TextStoreACP_SetText(ITextStoreACP *iface, - DWORD dwFlags, LONG acpStart, LONG acpEnd, const WCHAR *pchText, - ULONG cch, TS_TEXTCHANGE *pChange) -{ - trace("\n"); - return S_OK; -} -static HRESULT WINAPI TextStoreACP_GetFormattedText(ITextStoreACP *iface, - LONG acpStart, LONG acpEnd, IDataObject **ppDataObject) -{ - trace("\n"); - return S_OK; -} -static HRESULT WINAPI TextStoreACP_GetEmbedded(ITextStoreACP *iface, - LONG acpPos, REFGUID rguidService, REFIID riid, IUnknown **ppunk) +static HRESULT WINAPI TextService_Deactivate(ITfTextInputProcessor *iface) { - trace("\n"); + trace("TextService_Deactivate\n"); + ok(test_ShouldDeactivate,"Deactivation came unexpectedly\n"); return S_OK; } -static HRESULT WINAPI TextStoreACP_QueryInsertEmbedded(ITextStoreACP *iface, - const GUID *pguidService, const FORMATETC *pFormatEtc, BOOL *pfInsertable) + +static const ITfTextInputProcessorVtbl TextService_TextInputProcessorVtbl= { - trace("\n"); - return S_OK; -} -static HRESULT WINAPI TextStoreACP_InsertEmbedded(ITextStoreACP *iface, - DWORD dwFlags, LONG acpStart, LONG acpEnd, IDataObject *pDataObject, - TS_TEXTCHANGE *pChange) + TextService_QueryInterface, + TextService_AddRef, + TextService_Release, + + TextService_Activate, + TextService_Deactivate +}; + +static HRESULT TextService_Constructor(IUnknown *pUnkOuter, IUnknown **ppOut) { - trace("\n"); + TextService *This; + if (pUnkOuter) + return CLASS_E_NOAGGREGATION; + + This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(TextService)); + if (This == NULL) + return E_OUTOFMEMORY; + + This->TextInputProcessorVtbl= &TextService_TextInputProcessorVtbl; + This->refCount = 1; + + *ppOut = (IUnknown *)This; return S_OK; } -static HRESULT WINAPI TextStoreACP_InsertTextAtSelection(ITextStoreACP *iface, - DWORD dwFlags, const WCHAR *pchText, ULONG cch, LONG *pacpStart, - LONG *pacpEnd, TS_TEXTCHANGE *pChange) + +static HRESULT RegisterTextService(REFCLSID rclsid) { - trace("\n"); - return S_OK; + ClassFactory_Constructor( TextService_Constructor ,(LPVOID*)&cf); + return CoRegisterClassObject(rclsid, (IUnknown*) cf, CLSCTX_INPROC_SERVER, REGCLS_MULTIPLEUSE, ®id); } -static HRESULT WINAPI TextStoreACP_InsertEmbeddedAtSelection(ITextStoreACP *iface, - DWORD dwFlags, IDataObject *pDataObject, LONG *pacpStart, LONG *pacpEnd, - TS_TEXTCHANGE *pChange) + +static HRESULT UnregisterTextService() { - trace("\n"); - return S_OK; + return CoRevokeClassObject(regid); } -static HRESULT WINAPI TextStoreACP_RequestSupportedAttrs(ITextStoreACP *iface, - DWORD dwFlags, ULONG cFilterAttrs, const TS_ATTRID *paFilterAttrs) + +/* + * The tests + */ + +DEFINE_GUID(CLSID_FakeService, 0xEDE1A7AD,0x66DE,0x47E0,0xB6,0x20,0x3E,0x92,0xF8,0x24,0x6B,0xF3); +DEFINE_GUID(CLSID_TF_InputProcessorProfiles, 0x33c53a50,0xf456,0x4884,0xb0,0x49,0x85,0xfd,0x64,0x3e,0xcf,0xed); +DEFINE_GUID(CLSID_TF_CategoryMgr, 0xA4B544A1,0x438D,0x4B41,0x93,0x25,0x86,0x95,0x23,0xE2,0xD6,0xC7); +DEFINE_GUID(GUID_TFCAT_TIP_KEYBOARD, 0x34745c63,0xb2f0,0x4784,0x8b,0x67,0x5e,0x12,0xc8,0x70,0x1a,0x31); +DEFINE_GUID(GUID_TFCAT_TIP_SPEECH, 0xB5A73CD1,0x8355,0x426B,0xA1,0x61,0x25,0x98,0x08,0xF2,0x6B,0x14); +DEFINE_GUID(GUID_TFCAT_TIP_HANDWRITING, 0x246ecb87,0xc2f2,0x4abe,0x90,0x5b,0xc8,0xb3,0x8a,0xdd,0x2c,0x43); +DEFINE_GUID (GUID_TFCAT_DISPLAYATTRIBUTEPROVIDER, 0x046B8C80,0x1647,0x40F7,0x9B,0x21,0xB9,0x3B,0x81,0xAA,0xBC,0x1B); +DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0); +DEFINE_GUID(CLSID_TF_ThreadMgr, 0x529a9e6b,0x6587,0x4f23,0xab,0x9e,0x9c,0x7d,0x68,0x3e,0x3c,0x50); +DEFINE_GUID(CLSID_PreservedKey, 0xA0ED8E55,0xCD3B,0x4274,0xB2,0x95,0xF6,0xC9,0xBA,0x2B,0x84,0x72); + + +static HRESULT initialize(void) { - trace("\n"); - return S_OK; + HRESULT hr; + CoInitialize(NULL); + hr = CoCreateInstance (&CLSID_TF_InputProcessorProfiles, NULL, + CLSCTX_INPROC_SERVER, &IID_ITfInputProcessorProfiles, (void**)&g_ipp); + if (SUCCEEDED(hr)) + hr = CoCreateInstance (&CLSID_TF_CategoryMgr, NULL, + CLSCTX_INPROC_SERVER, &IID_ITfCategoryMgr, (void**)&g_cm); + if (SUCCEEDED(hr)) + hr = CoCreateInstance (&CLSID_TF_ThreadMgr, NULL, + CLSCTX_INPROC_SERVER, &IID_ITfThreadMgr, (void**)&g_tm); + return hr; } -static HRESULT WINAPI TextStoreACP_RequestAttrsAtPosition(ITextStoreACP *iface, - LONG acpPos, ULONG cFilterAttrs, const TS_ATTRID *paFilterAttrs, - DWORD dwFlags) + +static void cleanup(void) { - trace("\n"); - return S_OK; + if (g_ipp) + ITfInputProcessorProfiles_Release(g_ipp); + if (g_cm) + ITfCategoryMgr_Release(g_cm); + if (g_tm) + ITfThreadMgr_Release(g_tm); + CoUninitialize(); } -static HRESULT WINAPI TextStoreACP_RequestAttrsTransitioningAtPosition(ITextStoreACP *iface, - LONG acpPos, ULONG cFilterAttrs, const TS_ATTRID *paFilterAttrs, - DWORD dwFlags) + +static void test_Register(void) { - trace("\n"); - return S_OK; + HRESULT hr; + + static const WCHAR szDesc[] = {'F','a','k','e',' ','W','i','n','e',' ','S','e','r','v','i','c','e',0}; + static const WCHAR szFile[] = {'F','a','k','e',' ','W','i','n','e',' ','S','e','r','v','i','c','e',' ','F','i','l','e',0}; + + hr = ITfInputProcessorProfiles_GetCurrentLanguage(g_ipp,&gLangid); + ok(SUCCEEDED(hr),"Unable to get current language id\n"); + trace("Current Language %x\n",gLangid); + + hr = RegisterTextService(&CLSID_FakeService); + ok(SUCCEEDED(hr),"Unable to register COM for TextService\n"); + hr = ITfInputProcessorProfiles_Register(g_ipp, &CLSID_FakeService); + ok(SUCCEEDED(hr),"Unable to register text service(%x)\n",hr); + hr = ITfInputProcessorProfiles_AddLanguageProfile(g_ipp, &CLSID_FakeService, gLangid, &CLSID_FakeService, szDesc, sizeof(szDesc)/sizeof(WCHAR), szFile, sizeof(szFile)/sizeof(WCHAR), 1); + ok(SUCCEEDED(hr),"Unable to add Language Profile (%x)\n",hr); } -static HRESULT WINAPI TextStoreACP_FindNextAttrTransition(ITextStoreACP *iface, - LONG acpStart, LONG acpHalt, ULONG cFilterAttrs, const TS_ATTRID *paFilterAttrs, - DWORD dwFlags, LONG *pacpNext, BOOL *pfFound, LONG *plFoundOffset) + +static void test_Unregister(void) { - trace("\n"); - return S_OK; + HRESULT hr; + hr = ITfInputProcessorProfiles_Unregister(g_ipp, &CLSID_FakeService); + ok(SUCCEEDED(hr),"Unable to unregister text service(%x)\n",hr); + UnregisterTextService(); } -static HRESULT WINAPI TextStoreACP_RetrieveRequestedAttrs(ITextStoreACP *iface, - ULONG ulCount, TS_ATTRVAL *paAttrVals, ULONG *pcFetched) + +static void test_EnumInputProcessorInfo(void) { - trace("\n"); - return S_OK; + IEnumGUID *ppEnum; + BOOL found = FALSE; + + if (SUCCEEDED(ITfInputProcessorProfiles_EnumInputProcessorInfo(g_ipp, &ppEnum))) + { + ULONG fetched; + GUID g; + while (IEnumGUID_Next(ppEnum, 1, &g, &fetched) == S_OK) + { + if(IsEqualGUID(&g,&CLSID_FakeService)) + found = TRUE; + } + } + ok(found,"Did not find registered text service\n"); } -static HRESULT WINAPI TextStoreACP_GetEndACP(ITextStoreACP *iface, - LONG *pacp) + +static void test_EnumLanguageProfiles(void) { - trace("\n"); - return S_OK; + BOOL found = FALSE; + IEnumTfLanguageProfiles *ppEnum; + if (SUCCEEDED(ITfInputProcessorProfiles_EnumLanguageProfiles(g_ipp,gLangid,&ppEnum))) + { + TF_LANGUAGEPROFILE profile; + while (IEnumTfLanguageProfiles_Next(ppEnum,1,&profile,NULL)==S_OK) + { + if (IsEqualGUID(&profile.clsid,&CLSID_FakeService)) + { + found = TRUE; + ok(profile.langid == gLangid, "LangId Incorrect\n"); + ok(IsEqualGUID(&profile.catid,&GUID_TFCAT_TIP_KEYBOARD), "CatId Incorrect\n"); + ok(IsEqualGUID(&profile.guidProfile,&CLSID_FakeService), "guidProfile Incorrect\n"); + } + } + } + ok(found,"Registered text service not found\n"); } -static HRESULT WINAPI TextStoreACP_GetActiveView(ITextStoreACP *iface, - TsViewCookie *pvcView) + +static void test_RegisterCategory(void) { - trace("\n"); - return S_OK; + HRESULT hr; + hr = ITfCategoryMgr_RegisterCategory(g_cm, &CLSID_FakeService, &GUID_TFCAT_TIP_KEYBOARD, &CLSID_FakeService); + ok(SUCCEEDED(hr),"ITfCategoryMgr_RegisterCategory failed\n"); + hr = ITfCategoryMgr_RegisterCategory(g_cm, &CLSID_FakeService, &GUID_TFCAT_DISPLAYATTRIBUTEPROVIDER, &CLSID_FakeService); + ok(SUCCEEDED(hr),"ITfCategoryMgr_RegisterCategory failed\n"); } -static HRESULT WINAPI TextStoreACP_GetACPFromPoint(ITextStoreACP *iface, - TsViewCookie vcView, const POINT *ptScreen, DWORD dwFlags, - LONG *pacp) + +static void test_UnregisterCategory(void) { - trace("\n"); - return S_OK; + HRESULT hr; + hr = ITfCategoryMgr_UnregisterCategory(g_cm, &CLSID_FakeService, &GUID_TFCAT_TIP_KEYBOARD, &CLSID_FakeService); + ok(SUCCEEDED(hr),"ITfCategoryMgr_UnregisterCategory failed\n"); + hr = ITfCategoryMgr_UnregisterCategory(g_cm, &CLSID_FakeService, &GUID_TFCAT_DISPLAYATTRIBUTEPROVIDER, &CLSID_FakeService); + ok(SUCCEEDED(hr),"ITfCategoryMgr_UnregisterCategory failed\n"); } -static HRESULT WINAPI TextStoreACP_GetTextExt(ITextStoreACP *iface, - TsViewCookie vcView, LONG acpStart, LONG acpEnd, RECT *prc, - BOOL *pfClipped) + +static void test_FindClosestCategory(void) { - trace("\n"); - return S_OK; + GUID output; + HRESULT hr; + const GUID *list[3] = {&GUID_TFCAT_TIP_SPEECH, &GUID_TFCAT_TIP_KEYBOARD, &GUID_TFCAT_TIP_HANDWRITING}; + + hr = ITfCategoryMgr_FindClosestCategory(g_cm, &CLSID_FakeService, &output, NULL, 0); + ok(SUCCEEDED(hr),"ITfCategoryMgr_FindClosestCategory failed (%x)\n",hr); + ok(IsEqualGUID(&output,&GUID_TFCAT_DISPLAYATTRIBUTEPROVIDER),"Wrong GUID\n"); + + hr = ITfCategoryMgr_FindClosestCategory(g_cm, &CLSID_FakeService, &output, list, 1); + ok(SUCCEEDED(hr),"ITfCategoryMgr_FindClosestCategory failed (%x)\n",hr); + ok(IsEqualGUID(&output,&GUID_NULL),"Wrong GUID\n"); + + hr = ITfCategoryMgr_FindClosestCategory(g_cm, &CLSID_FakeService, &output, list, 3); + ok(SUCCEEDED(hr),"ITfCategoryMgr_FindClosestCategory failed (%x)\n",hr); + ok(IsEqualGUID(&output,&GUID_TFCAT_TIP_KEYBOARD),"Wrong GUID\n"); } -static HRESULT WINAPI TextStoreACP_GetScreenExt(ITextStoreACP *iface, - TsViewCookie vcView, RECT *prc) + +static void test_Enable(void) { - trace("\n"); - return S_OK; + HRESULT hr; + BOOL enabled = FALSE; + + hr = ITfInputProcessorProfiles_EnableLanguageProfile(g_ipp,&CLSID_FakeService, gLangid, &CLSID_FakeService, TRUE); + ok(SUCCEEDED(hr),"Failed to enable text service\n"); + hr = ITfInputProcessorProfiles_IsEnabledLanguageProfile(g_ipp,&CLSID_FakeService, gLangid, &CLSID_FakeService, &enabled); + ok(SUCCEEDED(hr),"Failed to get enabled state\n"); + ok(enabled == TRUE,"enabled state incorrect\n"); } -static HRESULT WINAPI TextStoreACP_GetWnd(ITextStoreACP *iface, - TsViewCookie vcView, HWND *phwnd) + +static void test_Disable(void) { - trace("\n"); - return S_OK; + HRESULT hr; + + trace("Disabling\n"); + hr = ITfInputProcessorProfiles_EnableLanguageProfile(g_ipp,&CLSID_FakeService, gLangid, &CLSID_FakeService, FALSE); + ok(SUCCEEDED(hr),"Failed to disable text service\n"); } -static const ITextStoreACPVtbl TextStoreACP_TextStoreACPVtbl = +static void test_ThreadMgrAdviseSinks(void) { - TextStoreACP_QueryInterface, - TextStoreACP_AddRef, - TextStoreACP_Release, + ITfSource *source = NULL; + HRESULT hr; + IUnknown *sink; - TextStoreACP_AdviseSink, - TextStoreACP_UnadviseSink, - TextStoreACP_RequestLock, - TextStoreACP_GetStatus, - TextStoreACP_QueryInsert, - TextStoreACP_GetSelection, - TextStoreACP_SetSelection, - TextStoreACP_GetText, - TextStoreACP_SetText, - TextStoreACP_GetFormattedText, - TextStoreACP_GetEmbedded, - TextStoreACP_QueryInsertEmbedded, - TextStoreACP_InsertEmbedded, - TextStoreACP_InsertTextAtSelection, - TextStoreACP_InsertEmbeddedAtSelection, - TextStoreACP_RequestSupportedAttrs, - TextStoreACP_RequestAttrsAtPosition, - TextStoreACP_RequestAttrsTransitioningAtPosition, - TextStoreACP_FindNextAttrTransition, - TextStoreACP_RetrieveRequestedAttrs, - TextStoreACP_GetEndACP, - TextStoreACP_GetActiveView, - TextStoreACP_GetACPFromPoint, - TextStoreACP_GetTextExt, - TextStoreACP_GetScreenExt, - TextStoreACP_GetWnd -}; + hr = ITfThreadMgr_QueryInterface(g_tm, &IID_ITfSource, (LPVOID*)&source); + ok(SUCCEEDED(hr),"Failed to get IID_ITfSource for ThreadMgr\n"); + if (!source) + return; -HRESULT TextStoreACP_Constructor(IUnknown **ppOut) -{ - TextStoreACP *This; + ThreadMgrEventSink_Constructor(&sink); - This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(TextStoreACP)); - if (This == NULL) - return E_OUTOFMEMORY; + tmSinkRefCount = 1; + tmSinkCookie = 0; + hr = ITfSource_AdviseSink(source,&IID_ITfThreadMgrEventSink, sink, &tmSinkCookie); + ok(SUCCEEDED(hr),"Failed to Advise Sink\n"); + ok(tmSinkCookie!=0,"Failed to get sink cookie\n"); - This->TextStoreACPVtbl = &TextStoreACP_TextStoreACPVtbl; - This->refCount = 1; + /* Advising the sink adds a ref, Relesing here lets the object be deleted + when unadvised */ + tmSinkRefCount = 2; + IUnknown_Release(sink); + ITfSource_Release(source); +} - *ppOut = (IUnknown *)This; - return S_OK; +static void test_ThreadMgrUnadviseSinks(void) +{ + ITfSource *source = NULL; + HRESULT hr; + + hr = ITfThreadMgr_QueryInterface(g_tm, &IID_ITfSource, (LPVOID*)&source); + ok(SUCCEEDED(hr),"Failed to get IID_ITfSource for ThreadMgr\n"); + if (!source) + return; + + tmSinkRefCount = 1; + hr = ITfSource_UnadviseSink(source, tmSinkCookie); + ok(SUCCEEDED(hr),"Failed to unadvise Sink\n"); + ITfSource_Release(source); } /********************************************************************** - * ITfThreadMgrEventSink + * ITfKeyEventSink **********************************************************************/ -typedef struct tagThreadMgrEventSink +typedef struct tagKeyEventSink { - const ITfThreadMgrEventSinkVtbl *ThreadMgrEventSinkVtbl; + const ITfKeyEventSinkVtbl *KeyEventSinkVtbl; LONG refCount; -} ThreadMgrEventSink; +} KeyEventSink; -static void ThreadMgrEventSink_Destructor(ThreadMgrEventSink *This) +static void KeyEventSink_Destructor(KeyEventSink *This) { HeapFree(GetProcessHeap(),0,This); } -static HRESULT WINAPI ThreadMgrEventSink_QueryInterface(ITfThreadMgrEventSink *iface, REFIID iid, LPVOID *ppvOut) +static HRESULT WINAPI KeyEventSink_QueryInterface(ITfKeyEventSink *iface, REFIID iid, LPVOID *ppvOut) { - ThreadMgrEventSink *This = (ThreadMgrEventSink *)iface; + KeyEventSink *This = (KeyEventSink *)iface; *ppvOut = NULL; - if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_ITfThreadMgrEventSink)) + if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_ITfKeyEventSink)) { *ppvOut = This; } @@ -1022,290 +887,429 @@ static HRESULT WINAPI ThreadMgrEventSink_QueryInterface(ITfThreadMgrEventSink *i return E_NOINTERFACE; } -static ULONG WINAPI ThreadMgrEventSink_AddRef(ITfThreadMgrEventSink *iface) +static ULONG WINAPI KeyEventSink_AddRef(ITfKeyEventSink *iface) { - ThreadMgrEventSink *This = (ThreadMgrEventSink *)iface; - ok (tmSinkRefCount == This->refCount,"ThreadMgrEventSink refcount off %i vs %i\n",This->refCount,tmSinkRefCount); + KeyEventSink *This = (KeyEventSink *)iface; return InterlockedIncrement(&This->refCount); } -static ULONG WINAPI ThreadMgrEventSink_Release(ITfThreadMgrEventSink *iface) +static ULONG WINAPI KeyEventSink_Release(ITfKeyEventSink *iface) { - ThreadMgrEventSink *This = (ThreadMgrEventSink *)iface; + KeyEventSink *This = (KeyEventSink *)iface; ULONG ret; - ok (tmSinkRefCount == This->refCount,"ThreadMgrEventSink refcount off %i vs %i\n",This->refCount,tmSinkRefCount); ret = InterlockedDecrement(&This->refCount); if (ret == 0) - ThreadMgrEventSink_Destructor(This); + KeyEventSink_Destructor(This); return ret; } -static HRESULT WINAPI ThreadMgrEventSink_OnInitDocumentMgr(ITfThreadMgrEventSink *iface, -ITfDocumentMgr *pdim) +static HRESULT WINAPI KeyEventSink_OnSetFocus(ITfKeyEventSink *iface, + BOOL fForeground) { - ok(test_OnInitDocumentMgr == SINK_EXPECTED, "Unexpected OnInitDocumentMgr sink\n"); - test_OnInitDocumentMgr = SINK_FIRED; + ok(test_KEV_OnSetFocus == SINK_EXPECTED,"Unexpected KeyEventSink_OnSetFocus\n"); + test_KEV_OnSetFocus = SINK_FIRED; return S_OK; } -static HRESULT WINAPI ThreadMgrEventSink_OnUninitDocumentMgr(ITfThreadMgrEventSink *iface, -ITfDocumentMgr *pdim) +static HRESULT WINAPI KeyEventSink_OnTestKeyDown(ITfKeyEventSink *iface, + ITfContext *pic, WPARAM wParam, LPARAM lParam, BOOL *pfEaten) { trace("\n"); return S_OK; } -static HRESULT WINAPI ThreadMgrEventSink_OnSetFocus(ITfThreadMgrEventSink *iface, -ITfDocumentMgr *pdimFocus, ITfDocumentMgr *pdimPrevFocus) +static HRESULT WINAPI KeyEventSink_OnTestKeyUp(ITfKeyEventSink *iface, + ITfContext *pic, WPARAM wParam, LPARAM lParam, BOOL *pfEaten) { - ok(test_OnSetFocus == SINK_EXPECTED, "Unexpected OnSetFocus sink\n"); - ok(pdimFocus == test_CurrentFocus,"Sink reports wrong focus\n"); - ok(pdimPrevFocus == test_PrevFocus,"Sink reports wrong previous focus\n"); - test_OnSetFocus = SINK_FIRED; + trace("\n"); return S_OK; } -static HRESULT WINAPI ThreadMgrEventSink_OnPushContext(ITfThreadMgrEventSink *iface, -ITfContext *pic) +static HRESULT WINAPI KeyEventSink_OnKeyDown(ITfKeyEventSink *iface, + ITfContext *pic, WPARAM wParam, LPARAM lParam, BOOL *pfEaten) { - ok(test_OnPushContext == SINK_EXPECTED, "Unexpected OnPushContext sink\n"); - test_OnPushContext = SINK_FIRED; + trace("\n"); return S_OK; } -static HRESULT WINAPI ThreadMgrEventSink_OnPopContext(ITfThreadMgrEventSink *iface, -ITfContext *pic) +static HRESULT WINAPI KeyEventSink_OnKeyUp(ITfKeyEventSink *iface, + ITfContext *pic, WPARAM wParam, LPARAM lParam, BOOL *pfEaten) { - ok(test_OnPopContext == SINK_EXPECTED, "Unexpected OnPopContext sink\n"); - test_OnPopContext = SINK_FIRED; + trace("\n"); return S_OK; } -static const ITfThreadMgrEventSinkVtbl ThreadMgrEventSink_ThreadMgrEventSinkVtbl = +static HRESULT WINAPI KeyEventSink_OnPreservedKey(ITfKeyEventSink *iface, + ITfContext *pic, REFGUID rguid, BOOL *pfEaten) { - ThreadMgrEventSink_QueryInterface, - ThreadMgrEventSink_AddRef, - ThreadMgrEventSink_Release, + trace("\n"); + return S_OK; +} - ThreadMgrEventSink_OnInitDocumentMgr, - ThreadMgrEventSink_OnUninitDocumentMgr, - ThreadMgrEventSink_OnSetFocus, - ThreadMgrEventSink_OnPushContext, - ThreadMgrEventSink_OnPopContext +static const ITfKeyEventSinkVtbl KeyEventSink_KeyEventSinkVtbl = +{ + KeyEventSink_QueryInterface, + KeyEventSink_AddRef, + KeyEventSink_Release, + + KeyEventSink_OnSetFocus, + KeyEventSink_OnTestKeyDown, + KeyEventSink_OnTestKeyUp, + KeyEventSink_OnKeyDown, + KeyEventSink_OnKeyUp, + KeyEventSink_OnPreservedKey }; -HRESULT ThreadMgrEventSink_Constructor(IUnknown **ppOut) +static HRESULT KeyEventSink_Constructor(ITfKeyEventSink **ppOut) { - ThreadMgrEventSink *This; + KeyEventSink *This; - This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(ThreadMgrEventSink)); + This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(KeyEventSink)); if (This == NULL) return E_OUTOFMEMORY; - This->ThreadMgrEventSinkVtbl = &ThreadMgrEventSink_ThreadMgrEventSinkVtbl; + This->KeyEventSinkVtbl = &KeyEventSink_KeyEventSinkVtbl; This->refCount = 1; - *ppOut = (IUnknown *)This; + *ppOut = (ITfKeyEventSink*)This; return S_OK; } -/******************************************************************************************** - * Stub text service for testing - ********************************************************************************************/ +static void test_KeystrokeMgr(void) +{ + ITfKeystrokeMgr *keymgr= NULL; + HRESULT hr; + TF_PRESERVEDKEY tfpk; + BOOL preserved; + ITfKeyEventSink *sink = NULL; -static LONG TS_refCount; -static IClassFactory *cf; -static DWORD regid; + KeyEventSink_Constructor(&sink); -typedef HRESULT (*LPFNCONSTRUCTOR)(IUnknown *pUnkOuter, IUnknown **ppvOut); + hr = ITfThreadMgr_QueryInterface(g_tm, &IID_ITfKeystrokeMgr, (LPVOID*)&keymgr); + ok(SUCCEEDED(hr),"Failed to get IID_ITfKeystrokeMgr for ThreadMgr\n"); -typedef struct tagClassFactory -{ - const IClassFactoryVtbl *vtbl; - LONG ref; - LPFNCONSTRUCTOR ctor; -} ClassFactory; + tfpk.uVKey = 'A'; + tfpk.uModifiers = TF_MOD_SHIFT; -typedef struct tagTextService -{ - const ITfTextInputProcessorVtbl *TextInputProcessorVtbl; - LONG refCount; -} TextService; + test_KEV_OnSetFocus = SINK_EXPECTED; + hr = ITfKeystrokeMgr_AdviseKeyEventSink(keymgr,tid,sink,TRUE); + ok(SUCCEEDED(hr),"ITfKeystrokeMgr_AdviseKeyEventSink failed\n"); + ok(test_KEV_OnSetFocus == SINK_FIRED, "KeyEventSink_OnSetFocus not fired as expected\n"); + hr = ITfKeystrokeMgr_AdviseKeyEventSink(keymgr,tid,sink,TRUE); + ok(hr == CONNECT_E_ADVISELIMIT,"Wrong return, expected CONNECT_E_ADVISELIMIT\n"); + hr = ITfKeystrokeMgr_AdviseKeyEventSink(keymgr,cid,sink,TRUE); + ok(hr == E_INVALIDARG,"Wrong return, expected E_INVALIDARG\n"); -static void ClassFactory_Destructor(ClassFactory *This) -{ - HeapFree(GetProcessHeap(),0,This); - TS_refCount--; + hr =ITfKeystrokeMgr_PreserveKey(keymgr, 0, &CLSID_PreservedKey, &tfpk, NULL, 0); + ok(hr==E_INVALIDARG,"ITfKeystrokeMgr_PreserveKey inproperly succeeded\n"); + + hr =ITfKeystrokeMgr_PreserveKey(keymgr, tid, &CLSID_PreservedKey, &tfpk, NULL, 0); + ok(SUCCEEDED(hr),"ITfKeystrokeMgr_PreserveKey failed\n"); + + hr =ITfKeystrokeMgr_PreserveKey(keymgr, tid, &CLSID_PreservedKey, &tfpk, NULL, 0); + ok(hr == TF_E_ALREADY_EXISTS,"ITfKeystrokeMgr_PreserveKey inproperly succeeded\n"); + + preserved = FALSE; + hr = ITfKeystrokeMgr_IsPreservedKey(keymgr, &CLSID_PreservedKey, &tfpk, &preserved); + ok(hr == S_OK, "ITfKeystrokeMgr_IsPreservedKey failed\n"); + if (hr == S_OK) ok(preserved == TRUE,"misreporting preserved key\n"); + + hr = ITfKeystrokeMgr_UnpreserveKey(keymgr, &CLSID_PreservedKey,&tfpk); + ok(SUCCEEDED(hr),"ITfKeystrokeMgr_UnpreserveKey failed\n"); + + hr = ITfKeystrokeMgr_IsPreservedKey(keymgr, &CLSID_PreservedKey, &tfpk, &preserved); + ok(hr == S_FALSE, "ITfKeystrokeMgr_IsPreservedKey failed\n"); + if (hr == S_FALSE) ok(preserved == FALSE,"misreporting preserved key\n"); + + hr = ITfKeystrokeMgr_UnpreserveKey(keymgr, &CLSID_PreservedKey,&tfpk); + ok(hr==CONNECT_E_NOCONNECTION,"ITfKeystrokeMgr_UnpreserveKey inproperly succeeded\n"); + + hr = ITfKeystrokeMgr_UnadviseKeyEventSink(keymgr,tid); + ok(SUCCEEDED(hr),"ITfKeystrokeMgr_UnadviseKeyEventSink failed\n"); + + ITfKeystrokeMgr_Release(keymgr); + ITfKeyEventSink_Release(sink); } -static HRESULT WINAPI ClassFactory_QueryInterface(IClassFactory *iface, REFIID riid, LPVOID *ppvOut) +static void test_Activate(void) { - *ppvOut = NULL; - if (IsEqualIID(riid, &IID_IClassFactory) || IsEqualIID(riid, &IID_IUnknown)) - { - IClassFactory_AddRef(iface); - *ppvOut = iface; - return S_OK; - } + HRESULT hr; - return E_NOINTERFACE; + hr = ITfInputProcessorProfiles_ActivateLanguageProfile(g_ipp,&CLSID_FakeService,gLangid,&CLSID_FakeService); + ok(SUCCEEDED(hr),"Failed to Activate text service\n"); } -static ULONG WINAPI ClassFactory_AddRef(IClassFactory *iface) +static inline int check_context_refcount(ITfContext *iface) { - ClassFactory *This = (ClassFactory *)iface; - return InterlockedIncrement(&This->ref); + IUnknown_AddRef(iface); + return IUnknown_Release(iface); } -static ULONG WINAPI ClassFactory_Release(IClassFactory *iface) +static void test_startSession(void) { - ClassFactory *This = (ClassFactory *)iface; - ULONG ret = InterlockedDecrement(&This->ref); + HRESULT hr; + DWORD cnt; + DWORD editCookie; + ITfDocumentMgr *dmtest; + ITfContext *cxt,*cxt2,*cxt3,*cxtTest; + ITextStoreACP *ts; + TfClientId cid2 = 0; - if (ret == 0) - ClassFactory_Destructor(This); - return ret; -} + hr = ITfThreadMgr_Deactivate(g_tm); + ok(hr == E_UNEXPECTED,"Deactivate should have failed with E_UNEXPECTED\n"); + + test_ShouldActivate = TRUE; + hr = ITfThreadMgr_Activate(g_tm,&cid); + ok(SUCCEEDED(hr),"Failed to Activate\n"); + ok(cid != tid,"TextService id mistakenly matches Client id\n"); + + test_ShouldActivate = FALSE; + hr = ITfThreadMgr_Activate(g_tm,&cid2); + ok(SUCCEEDED(hr),"Failed to Activate\n"); + ok (cid == cid2, "Second activate client ID does not match\n"); + + hr = ITfThreadMgr_Deactivate(g_tm); + ok(SUCCEEDED(hr),"Failed to Deactivate\n"); + + hr = ITfThreadMgr_CreateDocumentMgr(g_tm,&g_dm); + ok(SUCCEEDED(hr),"CreateDocumentMgr failed\n"); + + hr = ITfThreadMgr_GetFocus(g_tm,&dmtest); + ok(SUCCEEDED(hr),"GetFocus Failed\n"); + ok(dmtest == NULL,"Initial focus not null\n"); + + test_CurrentFocus = g_dm; + test_PrevFocus = NULL; + test_OnSetFocus = SINK_EXPECTED; + hr = ITfThreadMgr_SetFocus(g_tm,g_dm); + ok(SUCCEEDED(hr),"SetFocus Failed\n"); + ok(test_OnSetFocus == SINK_FIRED, "OnSetFocus sink not called\n"); + test_OnSetFocus = SINK_UNEXPECTED; + + hr = ITfThreadMgr_GetFocus(g_tm,&dmtest); + ok(SUCCEEDED(hr),"GetFocus Failed\n"); + ok(g_dm == dmtest,"Expected DocumentMgr not focused\n"); + + cnt = ITfDocumentMgr_Release(g_dm); + ok(cnt == 2,"DocumentMgr refcount not expected (2 vs %i)\n",cnt); + + hr = ITfThreadMgr_GetFocus(g_tm,&dmtest); + ok(SUCCEEDED(hr),"GetFocus Failed\n"); + ok(g_dm == dmtest,"Expected DocumentMgr not focused\n"); + + TextStoreACP_Constructor((IUnknown**)&ts); + + hr = ITfDocumentMgr_CreateContext(g_dm, cid, 0, (IUnknown*)ts, &cxt, &editCookie); + ok(SUCCEEDED(hr),"CreateContext Failed\n"); + + hr = ITfDocumentMgr_CreateContext(g_dm, cid, 0, NULL, &cxt2, &editCookie); + ok(SUCCEEDED(hr),"CreateContext Failed\n"); + + hr = ITfDocumentMgr_CreateContext(g_dm, cid, 0, NULL, &cxt3, &editCookie); + ok(SUCCEEDED(hr),"CreateContext Failed\n"); + + cnt = check_context_refcount(cxt); + test_OnPushContext = SINK_EXPECTED; + test_OnInitDocumentMgr = SINK_EXPECTED; + hr = ITfDocumentMgr_Push(g_dm, cxt); + ok(SUCCEEDED(hr),"Push Failed\n"); + ok(check_context_refcount(cxt) > cnt, "Ref count did not increase\n"); + ok(test_OnPushContext == SINK_FIRED, "OnPushContext sink not fired\n"); + ok(test_OnInitDocumentMgr == SINK_FIRED, "OnInitDocumentMgr sink not fired\n"); + + hr = ITfDocumentMgr_GetTop(g_dm, &cxtTest); + ok(SUCCEEDED(hr),"GetTop Failed\n"); + ok(cxtTest == cxt, "Wrong context on top\n"); + ok(check_context_refcount(cxt) > cnt, "Ref count did not increase\n"); + cnt = ITfContext_Release(cxtTest); + + hr = ITfDocumentMgr_GetBase(g_dm, &cxtTest); + ok(SUCCEEDED(hr),"GetBase Failed\n"); + ok(cxtTest == cxt, "Wrong context on Base\n"); + ok(check_context_refcount(cxt) > cnt, "Ref count did not increase\n"); + ITfContext_Release(cxtTest); + + check_context_refcount(cxt2); + test_OnPushContext = SINK_EXPECTED; + hr = ITfDocumentMgr_Push(g_dm, cxt2); + ok(SUCCEEDED(hr),"Push Failed\n"); + ok(test_OnPushContext == SINK_FIRED, "OnPushContext sink not fired\n"); -static HRESULT WINAPI ClassFactory_CreateInstance(IClassFactory *iface, IUnknown *punkOuter, REFIID iid, LPVOID *ppvOut) -{ - ClassFactory *This = (ClassFactory *)iface; - HRESULT ret; - IUnknown *obj; + cnt = check_context_refcount(cxt2); + hr = ITfDocumentMgr_GetTop(g_dm, &cxtTest); + ok(SUCCEEDED(hr),"GetTop Failed\n"); + ok(cxtTest == cxt2, "Wrong context on top\n"); + ok(check_context_refcount(cxt2) > cnt, "Ref count did not increase\n"); + ITfContext_Release(cxtTest); - ret = This->ctor(punkOuter, &obj); - if (FAILED(ret)) - return ret; - ret = IUnknown_QueryInterface(obj, iid, ppvOut); - IUnknown_Release(obj); - return ret; -} + cnt = check_context_refcount(cxt); + hr = ITfDocumentMgr_GetBase(g_dm, &cxtTest); + ok(SUCCEEDED(hr),"GetBase Failed\n"); + ok(cxtTest == cxt, "Wrong context on Base\n"); + ok(check_context_refcount(cxt) > cnt, "Ref count did not increase\n"); + ITfContext_Release(cxtTest); -static HRESULT WINAPI ClassFactory_LockServer(IClassFactory *iface, BOOL fLock) -{ - if(fLock) - InterlockedIncrement(&TS_refCount); - else - InterlockedDecrement(&TS_refCount); + cnt = check_context_refcount(cxt3); + hr = ITfDocumentMgr_Push(g_dm, cxt3); + ok(!SUCCEEDED(hr),"Push Succeeded\n"); + ok(check_context_refcount(cxt3) == cnt, "Ref changed\n"); - return S_OK; -} + cnt = check_context_refcount(cxt2); + hr = ITfDocumentMgr_GetTop(g_dm, &cxtTest); + ok(SUCCEEDED(hr),"GetTop Failed\n"); + ok(cxtTest == cxt2, "Wrong context on top\n"); + ok(check_context_refcount(cxt2) > cnt, "Ref count did not increase\n"); + ITfContext_Release(cxtTest); -static const IClassFactoryVtbl ClassFactoryVtbl = { - /* IUnknown */ - ClassFactory_QueryInterface, - ClassFactory_AddRef, - ClassFactory_Release, + cnt = check_context_refcount(cxt); + hr = ITfDocumentMgr_GetBase(g_dm, &cxtTest); + ok(SUCCEEDED(hr),"GetBase Failed\n"); + ok(cxtTest == cxt, "Wrong context on Base\n"); + ok(check_context_refcount(cxt) > cnt, "Ref count did not increase\n"); + ITfContext_Release(cxtTest); - /* IClassFactory*/ - ClassFactory_CreateInstance, - ClassFactory_LockServer -}; + cnt = check_context_refcount(cxt2); + test_OnPopContext = SINK_EXPECTED; + hr = ITfDocumentMgr_Pop(g_dm, 0); + ok(SUCCEEDED(hr),"Pop Failed\n"); + ok(check_context_refcount(cxt2) < cnt, "Ref count did not decrease\n"); + ok(test_OnPopContext == SINK_FIRED, "OnPopContext sink not fired\n"); -static HRESULT ClassFactory_Constructor(LPFNCONSTRUCTOR ctor, LPVOID *ppvOut) -{ - ClassFactory *This = HeapAlloc(GetProcessHeap(),0,sizeof(ClassFactory)); - This->vtbl = &ClassFactoryVtbl; - This->ref = 1; - This->ctor = ctor; - *ppvOut = (LPVOID)This; - TS_refCount++; - return S_OK; -} + hr = ITfDocumentMgr_GetTop(g_dm, &cxtTest); + ok(SUCCEEDED(hr),"GetTop Failed\n"); + ok(cxtTest == cxt, "Wrong context on top\n"); + ITfContext_Release(cxtTest); -static void TextService_Destructor(TextService *This) -{ - HeapFree(GetProcessHeap(),0,This); -} + hr = ITfDocumentMgr_GetBase(g_dm, &cxtTest); + ok(SUCCEEDED(hr),"GetBase Failed\n"); + ok(cxtTest == cxt, "Wrong context on base\n"); + ITfContext_Release(cxtTest); -static HRESULT WINAPI TextService_QueryInterface(ITfTextInputProcessor *iface, REFIID iid, LPVOID *ppvOut) -{ - TextService *This = (TextService *)iface; - *ppvOut = NULL; + hr = ITfDocumentMgr_Pop(g_dm, 0); + ok(!SUCCEEDED(hr),"Pop Succeeded\n"); - if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_ITfTextInputProcessor)) - { - *ppvOut = This; - } + hr = ITfDocumentMgr_GetTop(g_dm, &cxtTest); + ok(SUCCEEDED(hr),"GetTop Failed\n"); + ok(cxtTest == cxt, "Wrong context on top\n"); + ITfContext_Release(cxtTest); - if (*ppvOut) - { - IUnknown_AddRef(iface); - return S_OK; - } + hr = ITfDocumentMgr_GetBase(g_dm, &cxtTest); + ok(SUCCEEDED(hr),"GetBase Failed\n"); + ok(cxtTest == cxt, "Wrong context on base\n"); + ITfContext_Release(cxtTest); - return E_NOINTERFACE; + ITfContext_Release(cxt); + ITfContext_Release(cxt2); + ITfContext_Release(cxt3); } -static ULONG WINAPI TextService_AddRef(ITfTextInputProcessor *iface) +static void test_endSession(void) { - TextService *This = (TextService *)iface; - return InterlockedIncrement(&This->refCount); + HRESULT hr; + test_ShouldDeactivate = TRUE; + test_CurrentFocus = NULL; + test_PrevFocus = g_dm; + test_OnSetFocus = SINK_EXPECTED; + hr = ITfThreadMgr_Deactivate(g_tm); + ok(SUCCEEDED(hr),"Failed to Deactivate\n"); + ok(test_OnSetFocus == SINK_FIRED, "OnSetFocus sink not called\n"); + test_OnSetFocus = SINK_UNEXPECTED; } -static ULONG WINAPI TextService_Release(ITfTextInputProcessor *iface) +static void test_TfGuidAtom(void) { - TextService *This = (TextService *)iface; - ULONG ret; + GUID gtest,g1; + HRESULT hr; + TfGuidAtom atom1,atom2; + BOOL equal; - ret = InterlockedDecrement(&This->refCount); - if (ret == 0) - TextService_Destructor(This); - return ret; -} + CoCreateGuid(>est); -static HRESULT WINAPI TextService_Activate(ITfTextInputProcessor *iface, - ITfThreadMgr *ptim, TfClientId id) -{ - trace("TextService_Activate\n"); - ok(test_ShouldActivate,"Activation came unexpectedly\n"); - tid = id; - return S_OK; -} + /* msdn reports this should return E_INVALIDARG. However my test show it crashing (winxp)*/ + /* + hr = ITfCategoryMgr_RegisterGUID(g_cm,>est,NULL); + ok(hr==E_INVALIDARG,"ITfCategoryMgr_RegisterGUID should have failed\n"); + */ + hr = ITfCategoryMgr_RegisterGUID(g_cm,>est,&atom1); + ok(SUCCEEDED(hr),"ITfCategoryMgr_RegisterGUID failed\n"); + hr = ITfCategoryMgr_RegisterGUID(g_cm,>est,&atom2); + ok(SUCCEEDED(hr),"ITfCategoryMgr_RegisterGUID failed\n"); + ok(atom1 == atom2,"atoms do not match\n"); + hr = ITfCategoryMgr_GetGUID(g_cm,atom2,NULL); + ok(hr==E_INVALIDARG,"ITfCategoryMgr_GetGUID should have failed\n"); + hr = ITfCategoryMgr_GetGUID(g_cm,atom2,&g1); + ok(SUCCEEDED(hr),"ITfCategoryMgr_GetGUID failed\n"); + ok(IsEqualGUID(&g1,>est),"guids do not match\n"); + hr = ITfCategoryMgr_IsEqualTfGuidAtom(g_cm,atom1,>est,NULL); + ok(hr==E_INVALIDARG,"ITfCategoryMgr_IsEqualTfGuidAtom should have failed\n"); + hr = ITfCategoryMgr_IsEqualTfGuidAtom(g_cm,atom1,>est,&equal); + ok(SUCCEEDED(hr),"ITfCategoryMgr_IsEqualTfGuidAtom failed\n"); + ok(equal == TRUE,"Equal value invalid\n"); -static HRESULT WINAPI TextService_Deactivate(ITfTextInputProcessor *iface) -{ - trace("TextService_Deactivate\n"); - ok(test_ShouldDeactivate,"Deactivation came unexpectedly\n"); - return S_OK; + /* show that cid and tid TfClientIds are also TfGuidAtoms */ + hr = ITfCategoryMgr_IsEqualTfGuidAtom(g_cm,tid,&CLSID_FakeService,&equal); + ok(SUCCEEDED(hr),"ITfCategoryMgr_IsEqualTfGuidAtom failed\n"); + ok(equal == TRUE,"Equal value invalid\n"); + hr = ITfCategoryMgr_GetGUID(g_cm,cid,&g1); + ok(SUCCEEDED(hr),"ITfCategoryMgr_GetGUID failed\n"); + ok(!IsEqualGUID(&g1,&GUID_NULL),"guid should not be NULL\n"); } -static const ITfTextInputProcessorVtbl TextService_TextInputProcessorVtbl= -{ - TextService_QueryInterface, - TextService_AddRef, - TextService_Release, - - TextService_Activate, - TextService_Deactivate -}; - -HRESULT TextService_Constructor(IUnknown *pUnkOuter, IUnknown **ppOut) +static void test_ClientId(void) { - TextService *This; - if (pUnkOuter) - return CLASS_E_NOAGGREGATION; - - This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(TextService)); - if (This == NULL) - return E_OUTOFMEMORY; + ITfClientId *pcid; + TfClientId id1,id2; + HRESULT hr; + GUID g2; - This->TextInputProcessorVtbl= &TextService_TextInputProcessorVtbl; - This->refCount = 1; + hr = ITfThreadMgr_QueryInterface(g_tm, &IID_ITfClientId, (LPVOID*)&pcid); + ok(SUCCEEDED(hr),"Unable to aquire ITfClientId interface\n"); - *ppOut = (IUnknown *)This; - return S_OK; -} + CoCreateGuid(&g2); -HRESULT RegisterTextService(REFCLSID rclsid) -{ - ClassFactory_Constructor( TextService_Constructor ,(LPVOID*)&cf); - return CoRegisterClassObject(rclsid, (IUnknown*) cf, CLSCTX_INPROC_SERVER, REGCLS_MULTIPLEUSE, ®id); + hr = ITfClientId_GetClientId(pcid,&GUID_NULL,&id1); + ok(SUCCEEDED(hr),"GetClientId failed\n"); + hr = ITfClientId_GetClientId(pcid,&GUID_NULL,&id2); + ok(SUCCEEDED(hr),"GetClientId failed\n"); + ok(id1==id2,"Id's for GUID_NULL do not match\n"); + hr = ITfClientId_GetClientId(pcid,&CLSID_FakeService,&id2); + ok(SUCCEEDED(hr),"GetClientId failed\n"); + ok(id2!=id1,"Id matches GUID_NULL\n"); + ok(id2==tid,"Id for CLSID_FakeService not matching tid\n"); + ok(id2!=cid,"Id for CLSID_FakeService matching cid\n"); + hr = ITfClientId_GetClientId(pcid,&g2,&id2); + ok(SUCCEEDED(hr),"GetClientId failed\n"); + ok(id2!=id1,"Id matches GUID_NULL\n"); + ok(id2!=tid,"Id for random guid matching tid\n"); + ok(id2!=cid,"Id for random guid matching cid\n"); + ITfClientId_Release(pcid); } -HRESULT UnregisterTextService() +START_TEST(inputprocessor) { - return CoRevokeClassObject(regid); + if (SUCCEEDED(initialize())) + { + test_Register(); + test_RegisterCategory(); + test_EnumInputProcessorInfo(); + test_Enable(); + test_ThreadMgrAdviseSinks(); + test_Activate(); + test_startSession(); + test_TfGuidAtom(); + test_ClientId(); + test_KeystrokeMgr(); + test_endSession(); + test_EnumLanguageProfiles(); + test_FindClosestCategory(); + test_Disable(); + test_ThreadMgrUnadviseSinks(); + test_UnregisterCategory(); + test_Unregister(); + } + else + skip("Unable to create InputProcessor\n"); + cleanup(); } diff --git a/dlls/msctf/threadmgr.c b/dlls/msctf/threadmgr.c index 2afee3913bc..c91e5361072 100644 --- a/dlls/msctf/threadmgr.c +++ b/dlls/msctf/threadmgr.c @@ -71,6 +71,11 @@ typedef struct tagACLMulti { const ITfKeystrokeMgrVtbl *KeystrokeMgrVtbl; const ITfMessagePumpVtbl *MessagePumpVtbl; const ITfClientIdVtbl *ClientIdVtbl; + /* const ITfThreadMgrExVtbl *ThreadMgrExVtbl; */ + /* const ITfConfigureSystemKeystrokeFeedVtbl *ConfigureSystemKeystrokeFeedVtbl; */ + /* const ITfLangBarItemMgrVtbl *LangBarItemMgrVtbl; */ + /* const ITfUIElementMgrVtbl *UIElementMgrVtbl; */ + /* const ITfSourceSingleVtbl *SourceSingleVtbl; */ LONG refCount; const ITfThreadMgrEventSinkVtbl *ThreadMgrEventSinkVtbl; /* internal */ @@ -78,6 +83,9 @@ typedef struct tagACLMulti { ITfDocumentMgr *focus; LONG activationCount; + ITfKeyEventSink *forgroundKeyEventSink; + CLSID forgroundTextService; + struct list CurrentPreservedKeys; /* kept as separate lists to reduce unnecessary iterations */ @@ -509,24 +517,87 @@ static HRESULT WINAPI KeystrokeMgr_AdviseKeyEventSink(ITfKeystrokeMgr *iface, TfClientId tid, ITfKeyEventSink *pSink, BOOL fForeground) { ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface); - FIXME("STUB:(%p)\n",This); - return E_NOTIMPL; + CLSID textservice; + ITfKeyEventSink *check = NULL; + + TRACE("(%p) %x %p %i\n",This,tid,pSink,fForeground); + + if (!tid || !pSink) + return E_INVALIDARG; + + textservice = get_textservice_clsid(tid); + if (IsEqualCLSID(&GUID_NULL,&textservice)) + return E_INVALIDARG; + + get_textservice_sink(tid, &IID_ITfKeyEventSink, (IUnknown**)&check); + if (check != NULL) + return CONNECT_E_ADVISELIMIT; + + if (FAILED(IUnknown_QueryInterface(pSink,&IID_ITfKeyEventSink,(LPVOID*) &check))) + return E_INVALIDARG; + + set_textservice_sink(tid, &IID_ITfKeyEventSink, (IUnknown*)check); + + if (fForeground) + { + if (This->forgroundKeyEventSink) + { + ITfKeyEventSink_OnSetFocus(This->forgroundKeyEventSink, FALSE); + ITfKeyEventSink_Release(This->forgroundKeyEventSink); + } + ITfKeyEventSink_AddRef(check); + ITfKeyEventSink_OnSetFocus(check, TRUE); + This->forgroundKeyEventSink = check; + This->forgroundTextService = textservice; + } + return S_OK; } static HRESULT WINAPI KeystrokeMgr_UnadviseKeyEventSink(ITfKeystrokeMgr *iface, TfClientId tid) { ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface); - FIXME("STUB:(%p)\n",This); - return E_NOTIMPL; + CLSID textservice; + ITfKeyEventSink *check = NULL; + TRACE("(%p) %x\n",This,tid); + + if (!tid) + return E_INVALIDARG; + + textservice = get_textservice_clsid(tid); + if (IsEqualCLSID(&GUID_NULL,&textservice)) + return E_INVALIDARG; + + get_textservice_sink(tid, &IID_ITfKeyEventSink, (IUnknown**)&check); + + if (!check) + return CONNECT_E_NOCONNECTION; + + set_textservice_sink(tid, &IID_ITfKeyEventSink, NULL); + ITfKeyEventSink_Release(check); + + if (This->forgroundKeyEventSink == check) + { + ITfKeyEventSink_Release(This->forgroundKeyEventSink); + This->forgroundKeyEventSink = NULL; + This->forgroundTextService = GUID_NULL; + } + return S_OK; } static HRESULT WINAPI KeystrokeMgr_GetForeground(ITfKeystrokeMgr *iface, CLSID *pclsid) { ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface); - FIXME("STUB:(%p)\n",This); - return E_NOTIMPL; + TRACE("(%p) %p\n",This,pclsid); + if (!pclsid) + return E_INVALIDARG; + + if (IsEqualCLSID(&This->forgroundTextService,&GUID_NULL)) + return S_FALSE; + + *pclsid = This->forgroundTextService; + return S_OK; } static HRESULT WINAPI KeystrokeMgr_TestKeyDown(ITfKeystrokeMgr *iface, diff --git a/dlls/mshtml/Sv.rc b/dlls/mshtml/Sv.rc index 2d9c29233dd..b6a1fd04573 100644 --- a/dlls/mshtml/Sv.rc +++ b/dlls/mshtml/Sv.rc @@ -51,6 +51,17 @@ FONT 8, "MS Shell Dlg" COMBOBOX IDC_TYPE, 35, 20, 45, 100, WS_TABSTOP | WS_GROUP | WS_VSCROLL | CBS_DROPDOWNLIST | CBS_HASSTRINGS LTEXT "&URL:", -1, 10, 42, 20, 10 EDITTEXT IDC_URL, 35, 40, 150, 14, ES_AUTOHSCROLL | WS_BORDER | WS_GROUP | WS_TABSTOP - PUSHBUTTON "Ok", IDOK, 200, 10, 45, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP + PUSHBUTTON "OK", IDOK, 200, 10, 45, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP PUSHBUTTON "Avbryt", IDCANCEL, 200, 28, 45, 14, WS_GROUP | WS_TABSTOP } + +ID_PROMPT_DIALOG DIALOG 0, 0, 200, 90 +STYLE WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "" +FONT 8, "MS Shell Dlg" +{ + LTEXT "", ID_PROMPT_PROMPT, 10, 10, 180, 30 + EDITTEXT ID_PROMPT_EDIT, 10, 45, 180, 14, ES_AUTOHSCROLL | WS_BORDER | WS_GROUP | WS_TABSTOP + PUSHBUTTON "OK", IDOK, 40, 65, 45, 15, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP + PUSHBUTTON "Avbryt", IDCANCEL, 115, 65, 45, 15, WS_GROUP | WS_TABSTOP +} diff --git a/dlls/mshtml/navigate.c b/dlls/mshtml/navigate.c index 6e41699b280..f882e6c0290 100644 --- a/dlls/mshtml/navigate.c +++ b/dlls/mshtml/navigate.c @@ -152,18 +152,21 @@ static nsresult NSAPI nsInputStream_Read(nsIInputStream *iface, char *aBuf, PRUi PRUint32 *_retval) { nsProtocolStream *This = NSINSTREAM_THIS(iface); + DWORD read = aCount; TRACE("(%p)->(%p %d %p)\n", This, aBuf, aCount, _retval); - /* Gecko always calls Read with big enough buffer */ - if(aCount < This->buf_size) - FIXME("aCount < This->buf_size\n"); + if(read > This->buf_size) + read = This->buf_size; - *_retval = This->buf_size; - if(This->buf_size) - memcpy(aBuf, This->buf, This->buf_size); - This->buf_size = 0; + if(read) { + memcpy(aBuf, This->buf, read); + if(read < This->buf_size) + memmove(This->buf, This->buf+read, This->buf_size-read); + This->buf_size -= read; + } + *_retval = read; return NS_OK; } diff --git a/dlls/mshtml/tests/protocol.c b/dlls/mshtml/tests/protocol.c index 36355bf36b0..adee2cbb93f 100644 --- a/dlls/mshtml/tests/protocol.c +++ b/dlls/mshtml/tests/protocol.c @@ -350,14 +350,18 @@ static void test_res_protocol(void) sizeof(buf)/sizeof(buf[0]), &size, 0); ok(hres == S_OK || hres == E_FAIL, "ParseUrl failed: %08x\n", hres); ok(buf[0] == '?', "buf changed\n"); - ok(size == sizeof(blank_url)/sizeof(WCHAR), "size=%d\n", size); + ok(size == sizeof(blank_url)/sizeof(WCHAR) || + size == sizeof(buf)/sizeof(buf[0]), /* IE8 */ + "size=%d\n", size); size = 0xdeadbeef; hres = IInternetProtocolInfo_ParseUrl(protocol_info, wrong_url1, PARSE_DOMAIN, 0, buf, sizeof(buf)/sizeof(buf[0]), &size, 0); ok(hres == S_OK || hres == E_FAIL, "ParseUrl failed: %08x\n", hres); ok(buf[0] == '?', "buf changed\n"); - ok(size == sizeof(wrong_url1)/sizeof(WCHAR), "size=%d\n", size); + ok(size == sizeof(wrong_url1)/sizeof(WCHAR) || + size == sizeof(buf)/sizeof(buf[0]), /* IE8 */ + "size=%d\n", size); if (0) { @@ -653,7 +657,9 @@ static void test_about_protocol(void) sizeof(buf)/sizeof(buf[0]), &size, 0); ok(hres == S_OK || hres == E_FAIL, "ParseUrl failed: %08x\n", hres); ok(buf[0] == '?', "buf changed\n"); - ok(size == sizeof(about_blank_url)/sizeof(WCHAR), "size=%d\n", size); + ok(size == sizeof(about_blank_url)/sizeof(WCHAR) || + size == sizeof(buf)/sizeof(buf[0]), /* IE8 */ + "size=%d\n", size); if (0) { diff --git a/dlls/msi/msi.c b/dlls/msi/msi.c index ed8b4ab24de..be1ad93bf9f 100644 --- a/dlls/msi/msi.c +++ b/dlls/msi/msi.c @@ -304,7 +304,7 @@ done: static UINT MSI_ApplyPatchW(LPCWSTR szPatchPackage, LPCWSTR szProductCode, LPCWSTR szCommandLine) { MSIHANDLE patch = 0, info = 0; - UINT r, type; + UINT r = ERROR_SUCCESS, type; DWORD size = 0; LPCWSTR cmd_ptr = szCommandLine; LPCWSTR product_code = szProductCode; diff --git a/dlls/msvcrt/tests/data.c b/dlls/msvcrt/tests/data.c index 40ff46b21d1..db29cd49a9b 100644 --- a/dlls/msvcrt/tests/data.c +++ b/dlls/msvcrt/tests/data.c @@ -74,7 +74,7 @@ static void test_initvar( HMODULE hmsvcrt ) int* (*pp_winmajor)() = (int*(*)())GetProcAddress(hmsvcrt, "__p__winmajor"); int* (*pp_winminor)() = (int*(*)())GetProcAddress(hmsvcrt, "__p__winminor"); int* (*pp_osver)() = (int*(*)())GetProcAddress(hmsvcrt, "__p__osver"); - int winver, winmajor, winminor, osver; + unsigned int winver, winmajor, winminor, osver; if( !( pp_winmajor && pp_winminor && pp_winver)) { win_skip("_winver variables are not available\n"); diff --git a/dlls/msvcrt/tests/heap.c b/dlls/msvcrt/tests/heap.c index 6e6b54446a6..7d3db2348f9 100644 --- a/dlls/msvcrt/tests/heap.c +++ b/dlls/msvcrt/tests/heap.c @@ -103,7 +103,7 @@ static void test_aligned_realloc(unsigned int size1, unsigned int size2, unsigne mem1 = malloc(size1); if (mem1) { - int i; + unsigned int i; for (i = 0; i < size1; i++) ((char *)mem)[i] = i + 1; memcpy(mem1, mem, size1); @@ -138,7 +138,7 @@ static void test_aligned_realloc(unsigned int size1, unsigned int size2, unsigne ok(memcmp(mem2, mem1, min(size1, size2))==0, "_aligned_realloc(%p, %d, %d) has different data\n", mem, size2, alignment); if (memcmp(mem2, mem1, min(size1, size2)) && winetest_debug > 1) { - int i; + unsigned int i; for (i = 0; i < min(size1, size2); i++) { if (((char *)mem2)[i] != ((char *)mem1)[i]) @@ -175,7 +175,7 @@ static void test_aligned_offset_realloc(unsigned int size1, unsigned int size2, mem1 = malloc(size1); if (mem1) { - int i; + unsigned int i; for (i = 0; i < size1; i++) ((char *)mem)[i] = i + 1; memcpy(mem1, mem, size1); @@ -211,7 +211,7 @@ static void test_aligned_offset_realloc(unsigned int size1, unsigned int size2, ok(memcmp(mem2, mem1, min(size1, size2))==0, "_aligned_offset_realloc(%p, %d, %d, %d) has different data\n", mem, size2, alignment, offset); if (memcmp(mem2, mem1, min(size1, size2)) && winetest_debug > 1) { - int i; + unsigned int i; for (i = 0; i < min(size1, size2); i++) { if (((char *)mem2)[i] != ((char *)mem1)[i]) diff --git a/dlls/msvfw32/Makefile.in b/dlls/msvfw32/Makefile.in index d152cc27c8b..8347fe88131 100644 --- a/dlls/msvfw32/Makefile.in +++ b/dlls/msvfw32/Makefile.in @@ -11,11 +11,6 @@ C_SRCS = \ msvideo_main.c \ drawdib.c -C_SRCS16 = \ - msvideo16.c - -SPEC_SRCS16 = msvideo.spec - RC_SRCS = rsrc.rc @MAKE_DLL_RULES@ diff --git a/dlls/msvfw32/msvideo_main.c b/dlls/msvfw32/msvideo_main.c index 962d6efe95f..7c98a1613c9 100644 --- a/dlls/msvfw32/msvideo_main.c +++ b/dlls/msvfw32/msvideo_main.c @@ -53,8 +53,6 @@ static inline const char *wine_dbgstr_fcc( DWORD fcc ) LOBYTE(HIWORD(fcc)), HIBYTE(HIWORD(fcc))); } -LRESULT (CALLBACK *pFnCallTo16)(HDRVR, HIC, UINT, LPARAM, LPARAM) = NULL; - static WINE_HIC* MSVIDEO_FirstHic /* = NULL */; typedef struct _reg_driver reg_driver; @@ -327,7 +325,7 @@ HIC VFWAPI ICOpen(DWORD fccType, DWORD fccHandler, UINT wMode) if (driver && driver->proc) /* The driver has been registered at runtime with its driverproc */ - return MSVIDEO_OpenFunction(fccType, fccHandler, wMode, driver->proc, 0); + return ICOpenFunction(fccType, fccHandler, wMode, driver->proc); /* Well, lParam2 is in fact a LPVIDEO_OPEN_PARMS, but it has the * same layout as ICOPEN @@ -360,9 +358,10 @@ HIC VFWAPI ICOpen(DWORD fccType, DWORD fccHandler, UINT wMode) } bIs16 = GetDriverFlags(hdrv) & 0x10000000; /* undocumented flag: WINE_GDF_16BIT */ - if (bIs16 && !pFnCallTo16) + if (bIs16) { FIXME("Got a 16 bit driver, but no 16 bit support in msvfw\n"); + CloseDriver(hdrv, 0, 0); return 0; } whic = HeapAlloc(GetProcessHeap(), 0, sizeof(WINE_HIC)); @@ -372,13 +371,11 @@ HIC VFWAPI ICOpen(DWORD fccType, DWORD fccHandler, UINT wMode) return FALSE; } whic->hdrv = hdrv; - /* FIXME: is the signature the real one ? */ - whic->driverproc = bIs16 ? (DRIVERPROC)pFnCallTo16 : NULL; - whic->driverproc16 = 0; + whic->driverproc = NULL; whic->type = fccType; whic->handler = fccHandler; - while (MSVIDEO_GetHicPtr(HIC_32(IC_HandleRef)) != NULL) IC_HandleRef++; - whic->hic = HIC_32(IC_HandleRef++); + while (MSVIDEO_GetHicPtr((HIC)(ULONG_PTR)IC_HandleRef) != NULL) IC_HandleRef++; + whic->hic = (HIC)(ULONG_PTR)IC_HandleRef++; whic->next = MSVIDEO_FirstHic; MSVIDEO_FirstHic = whic; @@ -387,16 +384,15 @@ HIC VFWAPI ICOpen(DWORD fccType, DWORD fccHandler, UINT wMode) } /*********************************************************************** - * MSVIDEO_OpenFunction + * ICOpenFunction [MSVFW32.@] */ -HIC MSVIDEO_OpenFunction(DWORD fccType, DWORD fccHandler, UINT wMode, - DRIVERPROC lpfnHandler, DWORD lpfnHandler16) +HIC VFWAPI ICOpenFunction(DWORD fccType, DWORD fccHandler, UINT wMode, FARPROC lpfnHandler) { ICOPEN icopen; WINE_HIC* whic; - TRACE("(%s,%s,%d,%p,%08x)\n", - wine_dbgstr_fcc(fccType), wine_dbgstr_fcc(fccHandler), wMode, lpfnHandler, lpfnHandler16); + TRACE("(%s,%s,%d,%p)\n", + wine_dbgstr_fcc(fccType), wine_dbgstr_fcc(fccHandler), wMode, lpfnHandler); icopen.dwSize = sizeof(ICOPEN); icopen.fccType = fccType; @@ -412,9 +408,8 @@ HIC MSVIDEO_OpenFunction(DWORD fccType, DWORD fccHandler, UINT wMode, if (!whic) return 0; whic->driverproc = lpfnHandler; - whic->driverproc16 = lpfnHandler16; - while (MSVIDEO_GetHicPtr(HIC_32(IC_HandleRef)) != NULL) IC_HandleRef++; - whic->hic = HIC_32(IC_HandleRef++); + while (MSVIDEO_GetHicPtr((HIC)(ULONG_PTR)IC_HandleRef) != NULL) IC_HandleRef++; + whic->hic = (HIC)(ULONG_PTR)IC_HandleRef++; whic->next = MSVIDEO_FirstHic; MSVIDEO_FirstHic = whic; @@ -448,14 +443,6 @@ HIC MSVIDEO_OpenFunction(DWORD fccType, DWORD fccHandler, UINT wMode, } /*********************************************************************** - * ICOpenFunction [MSVFW32.@] - */ -HIC VFWAPI ICOpenFunction(DWORD fccType, DWORD fccHandler, UINT wMode, FARPROC lpfnHandler) -{ - return MSVIDEO_OpenFunction(fccType, fccHandler, wMode, (DRIVERPROC)lpfnHandler, 0); -} - -/*********************************************************************** * ICGetInfo [MSVFW32.@] */ LRESULT VFWAPI ICGetInfo(HIC hic, ICINFO *picinfo, DWORD cb) diff --git a/dlls/msvfw32/msvideo_private.h b/dlls/msvfw32/msvideo_private.h index 6bd8e936463..d1e5f8d0d65 100644 --- a/dlls/msvfw32/msvideo_private.h +++ b/dlls/msvfw32/msvideo_private.h @@ -36,26 +36,12 @@ typedef struct tagWINE_HIC { WORD x2; /* 20: */ DWORD x3; /* 22: */ /* 26: */ - DWORD driverproc16; /* Wine specific flags */ HIC hic; DWORD driverId; struct tagWINE_HIC* next; } WINE_HIC; -HIC MSVIDEO_OpenFunction(DWORD, DWORD, UINT, DRIVERPROC, DWORD); LRESULT MSVIDEO_SendMessage(WINE_HIC*, UINT, DWORD_PTR, DWORD_PTR); -WINE_HIC* MSVIDEO_GetHicPtr(HIC); - -extern LRESULT (CALLBACK *pFnCallTo16)(HDRVR, HIC, UINT, LPARAM, LPARAM); - -/* handle16 --> handle conversions */ -#define HDRAWDIB_32(h16) ((HDRAWDIB)(ULONG_PTR)(h16)) -#define HIC_32(h16) ((HIC)(ULONG_PTR)(h16)) - -/* handle --> handle16 conversions */ -#define HDRVR_16(h32) (LOWORD(h32)) -#define HDRAWDIB_16(h32) (LOWORD(h32)) -#define HIC_16(h32) (LOWORD(h32)) #define IDC_CONFIGURE 882 #define IDC_ABOUT 883 diff --git a/dlls/msvideo.dll16/Makefile.in b/dlls/msvideo.dll16/Makefile.in new file mode 100644 index 00000000000..64a093bf56d --- /dev/null +++ b/dlls/msvideo.dll16/Makefile.in @@ -0,0 +1,16 @@ +TOPSRCDIR = @top_srcdir@ +TOPOBJDIR = ../.. +SRCDIR = @srcdir@ +VPATH = @srcdir@ +MODULE = msvideo.dll16 +IMPORTS = msvfw32 version advapi32 kernel32 + +EXTRADLLFLAGS = -Wb,--subsystem,win16,--main-module,msvfw32.dll + +SPEC_SRCS = msvideo.dll16.spec + +C_SRCS = msvideo16.c + +@MAKE_DLL_RULES@ + +@DEPENDENCIES@ # everything below this line is overwritten by make depend diff --git a/dlls/msvfw32/msvideo.spec b/dlls/msvideo.dll16/msvideo.dll16.spec similarity index 100% rename from dlls/msvfw32/msvideo.spec rename to dlls/msvideo.dll16/msvideo.dll16.spec diff --git a/dlls/msvfw32/msvideo16.c b/dlls/msvideo.dll16/msvideo16.c similarity index 82% rename from dlls/msvfw32/msvideo16.c rename to dlls/msvideo.dll16/msvideo16.c index c873da57f45..ef2163fa1e1 100644 --- a/dlls/msvfw32/msvideo16.c +++ b/dlls/msvideo.dll16/msvideo16.c @@ -30,7 +30,6 @@ #include "winreg.h" #include "winuser.h" #include "vfw16.h" -#include "msvideo_private.h" #include "wine/debug.h" WINE_DEFAULT_DEBUG_CHANNEL(msvideo); @@ -38,6 +37,15 @@ WINE_DEFAULT_DEBUG_CHANNEL(msvideo); /* Drivers32 settings */ #define HKLM_DRIVERS32 "Software\\Microsoft\\Windows NT\\CurrentVersion\\Drivers32" +/* handle16 --> handle conversions */ +#define HDRAWDIB_32(h16) ((HDRAWDIB)(ULONG_PTR)(h16)) +#define HIC_32(h16) ((HIC)(ULONG_PTR)(h16)) + +/* handle --> handle16 conversions */ +#define HDRVR_16(h32) (LOWORD(h32)) +#define HDRAWDIB_16(h32) (LOWORD(h32)) +#define HIC_16(h32) (LOWORD(h32)) + /*********************************************************************** * DrawDibOpen [MSVIDEO.102] */ @@ -135,14 +143,6 @@ HIC16 VFWAPI ICOpen16(DWORD fccType, DWORD fccHandler, UINT16 wMode) } /*********************************************************************** - * ICClose [MSVIDEO.204] - */ -LRESULT WINAPI ICClose16(HIC16 hic) -{ - return ICClose(HIC_32(hic)); -} - -/*********************************************************************** * _ICMessage [MSVIDEO.207] */ LRESULT VFWAPIV ICMessage16( HIC16 hic, UINT16 msg, UINT16 cb, VA_LIST16 valist ) @@ -156,7 +156,7 @@ LRESULT VFWAPIV ICMessage16( HIC16 hic, UINT16 msg, UINT16 cb, VA_LIST16 valist TRACE("0x%08x, %u, %u, ...)\n", (DWORD) hic, msg, cb); - for (i = 0; i < cb / sizeof(WORD); i++) + for (i = 0; i < cb / sizeof(WORD); i++) { lpData[i] = VA_ARG16(valist, WORD); } @@ -186,7 +186,7 @@ LRESULT VFWAPI ICGetInfo16(HIC16 hic, ICINFO16 * picinfo, DWORD cb) */ HIC16 VFWAPI ICLocate16(DWORD fccType, DWORD fccHandler, LPBITMAPINFOHEADER lpbiIn, LPBITMAPINFOHEADER lpbiOut, - WORD wFlags) + WORD wFlags) { return HIC_16(ICLocate(fccType, fccHandler, lpbiIn, lpbiOut, wFlags)); } @@ -205,7 +205,7 @@ DWORD VFWAPIV ICCompress16(HIC16 hic, DWORD dwFlags, DWORD ret; ICCOMPRESS iccmp; SEGPTR seg_iccmp; - + TRACE("(0x%08x,%d,%p,%p,%p,%p,...)\n", (DWORD) hic, dwFlags, lpbiOutput, lpData, lpbiInput, lpBits); @@ -350,7 +350,7 @@ HIC16 VFWAPI ICGetDisplayFormat16(HIC16 hic, LPBITMAPINFOHEADER lpbiIn, * * */ -static LPVOID MSVIDEO_MapICDEX16To32(LPDWORD lParam) +static LPVOID MSVIDEO_MapICDEX16To32(LPDWORD lParam) { LPVOID ret; @@ -387,7 +387,7 @@ static LPVOID MSVIDEO_MapMsg16To32(UINT msg, LPDWORD lParam1, LPDWORD lParam2) TRACE("Mapping %d\n", msg); - switch (msg) + switch (msg) { case DRV_LOAD: case DRV_ENABLE: @@ -418,10 +418,10 @@ static LPVOID MSVIDEO_MapMsg16To32(UINT msg, LPDWORD lParam1, LPDWORD lParam2) { ICINFO *ici = HeapAlloc(GetProcessHeap(), 0, sizeof(ICINFO)); ICINFO16 *ici16; - + ici16 = MapSL(*lParam1); ret = ici16; - + ici->dwSize = sizeof(ICINFO); COPY(ici, fccType); COPY(ici, fccHandler); @@ -503,7 +503,7 @@ static LPVOID MSVIDEO_MapMsg16To32(UINT msg, LPDWORD lParam1, LPDWORD lParam2) addr[1] = MSVIDEO_MapICDEX16To32(lParam2); else addr[1] = 0; - + ret = addr; } break;*/ @@ -597,7 +597,7 @@ static void MSVIDEO_UnmapMsg16To32(UINT msg, LPVOID data16, LPDWORD lParam1, LPD #define UNCOPY(x, y) (x##16->y = x->y); - switch (msg) + switch (msg) { case ICM_GETINFO: { @@ -609,10 +609,10 @@ static void MSVIDEO_UnmapMsg16To32(UINT msg, LPVOID data16, LPDWORD lParam1, LPD UNCOPY(ici, dwFlags); UNCOPY(ici, dwVersion); UNCOPY(ici, dwVersionICM); - WideCharToMultiByte( CP_ACP, 0, ici->szName, -1, ici16->szName, + WideCharToMultiByte( CP_ACP, 0, ici->szName, -1, ici16->szName, sizeof(ici16->szName), NULL, NULL ); ici16->szName[sizeof(ici16->szName)-1] = 0; - WideCharToMultiByte( CP_ACP, 0, ici->szDescription, -1, ici16->szDescription, + WideCharToMultiByte( CP_ACP, 0, ici->szDescription, -1, ici16->szDescription, sizeof(ici16->szDescription), NULL, NULL ); ici16->szDescription[sizeof(ici16->szDescription)-1] = 0; /* This just gives garbage for some reason - BB @@ -654,7 +654,7 @@ BOOL16 VFWAPI ICInfo16(DWORD fccType, DWORD fccHandler, ICINFO16 *lpicinfo) LPVOID lpv; DWORD lParam = (DWORD)lpicinfo; DWORD size = ((ICINFO*)(MapSL((SEGPTR)lpicinfo)))->dwSize; - + /* Use the mapping functions to map the ICINFO structure */ lpv = MSVIDEO_MapMsg16To32(ICM_GETINFO, &lParam, &size); @@ -670,40 +670,99 @@ BOOL16 VFWAPI ICInfo16(DWORD fccType, DWORD fccHandler, ICINFO16 *lpicinfo) * * */ -static LRESULT CALLBACK IC_Callback3216(HIC hic, HDRVR hdrv, UINT msg, DWORD lp1, DWORD lp2) +static LRESULT CALLBACK IC_Callback3216(DWORD pfn16, HIC hic, HDRVR hdrv, UINT msg, DWORD lp1, DWORD lp2) { - WINE_HIC* whic; WORD args[8]; + DWORD ret = 0; + + switch (msg) + { + case DRV_OPEN: + lp2 = (DWORD)MapLS((void*)lp2); + break; + } + args[7] = HIWORD(hic); + args[6] = LOWORD(hic); + args[5] = HDRVR_16(hdrv); + args[4] = msg; + args[3] = HIWORD(lp1); + args[2] = LOWORD(lp1); + args[1] = HIWORD(lp2); + args[0] = LOWORD(lp2); + WOWCallback16Ex( pfn16, WCB16_PASCAL, sizeof(args), args, &ret ); + + switch (msg) + { + case DRV_OPEN: + UnMapLS(lp2); + break; + } + return ret; +} + +#define MAX_THUNKS 32 + +static struct msvideo_thunk +{ + BYTE popl_eax; /* popl %eax (return address) */ + BYTE pushl_func; /* pushl $pfn16 (16bit callback function) */ + DWORD pfn16; + BYTE pushl_eax; /* pushl %eax */ + BYTE jmp; /* ljmp WDML_InvokeCallback16 */ + DWORD callback; + HIC16 hIC16; /* driver's handle */ +} *MSVIDEO_Thunks; + +static CRITICAL_SECTION msvideo_cs; +static CRITICAL_SECTION_DEBUG critsect_debug = +{ + 0, 0, &msvideo_cs, + { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList }, + 0, 0, { (DWORD_PTR)(__FILE__ ": msvideo_cs") } +}; +static CRITICAL_SECTION msvideo_cs = { &critsect_debug, -1, 0, 0, 0, 0 }; + +static struct msvideo_thunk* MSVIDEO_AddThunk(DWORD pfn16) +{ + struct msvideo_thunk* thunk; - whic = MSVIDEO_GetHicPtr(hic); - if (whic) + if (!MSVIDEO_Thunks) { - DWORD ret = 0; - switch (msg) + MSVIDEO_Thunks = VirtualAlloc(NULL, MAX_THUNKS * sizeof(*MSVIDEO_Thunks), MEM_COMMIT, + PAGE_EXECUTE_READWRITE); + if (!MSVIDEO_Thunks) return NULL; + for (thunk = MSVIDEO_Thunks; thunk < &MSVIDEO_Thunks[MAX_THUNKS]; thunk++) { - case DRV_OPEN: - lp2 = (DWORD)MapLS((void*)lp2); - break; + thunk->popl_eax = 0x58; /* popl %eax */ + thunk->pushl_func = 0x68; /* pushl $pfn16 */ + thunk->pfn16 = 0; + thunk->pushl_eax = 0x50; /* pushl %eax */ + thunk->jmp = 0xe9; /* jmp IC_Callback3216 */ + thunk->callback = (char *)IC_Callback3216 - (char *)(&thunk->callback + 1); + thunk->hIC16 = 0; } - args[7] = HIWORD(hic); - args[6] = LOWORD(hic); - args[5] = HDRVR_16(whic->hdrv); - args[4] = msg; - args[3] = HIWORD(lp1); - args[2] = LOWORD(lp1); - args[1] = HIWORD(lp2); - args[0] = LOWORD(lp2); - WOWCallback16Ex( whic->driverproc16, WCB16_PASCAL, sizeof(args), args, &ret ); - - switch (msg) + } + for (thunk = MSVIDEO_Thunks; thunk < &MSVIDEO_Thunks[MAX_THUNKS]; thunk++) + { + if (thunk->pfn16 == 0) { - case DRV_OPEN: - UnMapLS(lp2); - break; + thunk->pfn16 = pfn16; + return thunk; } - return ret; } - else return ICERR_BADHANDLE; + FIXME("Out of msvideo-thunks. Bump MAX_THUNKS\n"); + return NULL; +} + +static struct msvideo_thunk* MSVIDEO_HasThunk(HIC16 hic) +{ + struct msvideo_thunk* thunk; + + for (thunk = MSVIDEO_Thunks; thunk < &MSVIDEO_Thunks[MAX_THUNKS]; thunk++) + { + if (thunk->hIC16 == hic) return thunk; + } + return NULL; } /*********************************************************************** @@ -712,52 +771,75 @@ static LRESULT CALLBACK IC_Callback3216(HIC hic, HDRVR hdrv, UINT msg, DWORD l HIC16 VFWAPI ICOpenFunction16(DWORD fccType, DWORD fccHandler, UINT16 wMode, FARPROC16 lpfnHandler) { HIC hic32; + struct msvideo_thunk* thunk; - hic32 = MSVIDEO_OpenFunction(fccType, fccHandler, wMode, - (DRIVERPROC)IC_Callback3216, (DWORD)lpfnHandler); + EnterCriticalSection(&msvideo_cs); + if (!(thunk = MSVIDEO_AddThunk((DWORD)lpfnHandler))) return 0; + if ((hic32 = ICOpenFunction(fccType, fccHandler, wMode, IC_Callback3216))) + thunk->hIC16 = HIC_16(hic32); + else + thunk->pfn16 = 0; + LeaveCriticalSection(&msvideo_cs); return HIC_16(hic32); } /*********************************************************************** * ICSendMessage [MSVIDEO.205] */ -LRESULT VFWAPI ICSendMessage16(HIC16 hic, UINT16 msg, DWORD lParam1, DWORD lParam2) +LRESULT VFWAPI ICSendMessage16(HIC16 hic, UINT16 msg, DWORD lParam1, DWORD lParam2) { LRESULT ret = ICERR_BADHANDLE; - WINE_HIC* whic; + struct msvideo_thunk* thunk; - whic = MSVIDEO_GetHicPtr(HIC_32(hic)); - if (whic) + if ((thunk = MSVIDEO_HasThunk(hic))) { - /* we've got a 16 bit driver proc... call it directly */ - if (whic->driverproc16) - { - WORD args[8]; - DWORD result; - - /* FIXME: original code was passing hdrv first and hic second */ - /* but this doesn't match what IC_Callback3216 does */ - args[7] = HIWORD(hic); - args[6] = LOWORD(hic); - args[5] = HDRVR_16(whic->hdrv); - args[4] = msg; - args[3] = HIWORD(lParam1); - args[2] = LOWORD(lParam1); - args[1] = HIWORD(lParam2); - args[0] = LOWORD(lParam2); - WOWCallback16Ex( whic->driverproc16, WCB16_PASCAL, sizeof(args), args, &result ); - ret = result; - } - else + WORD args[8]; + DWORD result; + + /* FIXME: original code was passing hdrv first and hic second */ + /* but this doesn't match what IC_Callback3216 does */ + args[7] = HIWORD(hic); + args[6] = LOWORD(hic); + args[5] = 0; /* the 32bit also sets it to NULL */ + args[4] = msg; + args[3] = HIWORD(lParam1); + args[2] = LOWORD(lParam1); + args[1] = HIWORD(lParam2); + args[0] = LOWORD(lParam2); + WOWCallback16Ex( thunk->pfn16, WCB16_PASCAL, sizeof(args), args, &result ); + ret = result; + } + else + { + /* map the message for a 32 bit infrastructure, and pass it along */ + void* data16 = MSVIDEO_MapMsg16To32(msg, &lParam1, &lParam2); + + ret = ICSendMessage(HIC_32(hic), msg, lParam1, lParam2); + if (data16) + MSVIDEO_UnmapMsg16To32(msg, data16, &lParam1, &lParam2); + } + return ret; +} + +/*********************************************************************** + * ICClose [MSVIDEO.204] + */ +LRESULT WINAPI ICClose16(HIC16 hic) +{ + BOOL ret = ICClose(HIC_32(hic)); + + EnterCriticalSection(&msvideo_cs); + if (ret) + { + struct msvideo_thunk* thunk; + if ((thunk = MSVIDEO_HasThunk(hic))) { - /* map the message for a 32 bit infrastructure, and pass it along */ - void* data16 = MSVIDEO_MapMsg16To32(msg, &lParam1, &lParam2); - - ret = MSVIDEO_SendMessage(whic, msg, lParam1, lParam2); - if (data16) - MSVIDEO_UnmapMsg16To32(msg, data16, &lParam1, &lParam2); + thunk->pfn16 = 0; + thunk->hIC16 = 0; } + else ret = FALSE; } + LeaveCriticalSection(&msvideo_cs); return ret; } @@ -782,10 +864,10 @@ DWORD WINAPI VideoCapDriverDescAndVer16(WORD nr, LPSTR buf1, WORD buf1len, TRACE("(%d,%p,%d,%p,%d)\n", nr, buf1, buf1len, buf2, buf2len); lRet = RegOpenKeyExA(HKEY_LOCAL_MACHINE, HKLM_DRIVERS32, 0, KEY_QUERY_VALUE, &hKey); - if (lRet == ERROR_SUCCESS) + if (lRet == ERROR_SUCCESS) { RegQueryInfoKeyA( hKey, 0, 0, 0, &cnt, 0, 0, 0, 0, 0, 0, 0); - for (i = 0; i < cnt; i++) + for (i = 0; i < cnt; i++) { bufLen = sizeof(buf) / sizeof(buf[0]); lRet = RegEnumKeyExA(hKey, i, buf, &bufLen, 0, 0, 0, &lastWrite); @@ -797,8 +879,8 @@ DWORD WINAPI VideoCapDriverDescAndVer16(WORD nr, LPSTR buf1, WORD buf1len, if (lRet == ERROR_SUCCESS) found = TRUE; break; } - RegCloseKey( hKey ); - } + RegCloseKey( hKey ); + } /* search system.ini if not found in the registry */ if (!found && GetPrivateProfileStringA("drivers32", NULL, NULL, buf, sizeof(buf), "system.ini")) @@ -819,13 +901,13 @@ DWORD WINAPI VideoCapDriverDescAndVer16(WORD nr, LPSTR buf1, WORD buf1len, return 20; } infosize = GetFileVersionInfoSizeA(fn, &verhandle); - if (!infosize) + if (!infosize) { TRACE("%s has no fileversioninfo.\n", fn); return 18; } infobuf = HeapAlloc(GetProcessHeap(), 0, infosize); - if (GetFileVersionInfoA(fn, verhandle, infosize, infobuf)) + if (GetFileVersionInfoA(fn, verhandle, infosize, infobuf)) { /* Yes, two space behind : */ /* FIXME: test for buflen */ @@ -837,7 +919,7 @@ DWORD WINAPI VideoCapDriverDescAndVer16(WORD nr, LPSTR buf1, WORD buf1len, ); TRACE("version of %s is %s\n", fn, buf2); } - else + else { TRACE("GetFileVersionInfoA failed for %s.\n", fn); lstrcpynA(buf2, fn, buf2len); /* msvideo.dll appears to copy fn*/ @@ -847,14 +929,14 @@ DWORD WINAPI VideoCapDriverDescAndVer16(WORD nr, LPSTR buf1, WORD buf1len, version_info_spec, &subblock, &subblocklen - )) + )) { UINT copylen = min(subblocklen,buf1len-1); memcpy(buf1, subblock, copylen); buf1[copylen] = '\0'; TRACE("VQA returned %s\n", (LPCSTR)subblock); } - else + else { TRACE("VQA did not return on query \\StringFileInfo\\040904E4\\FileDescription?\n"); lstrcpynA(buf1, fn, buf1len); /* msvideo.dll appears to copy fn*/ @@ -863,32 +945,6 @@ DWORD WINAPI VideoCapDriverDescAndVer16(WORD nr, LPSTR buf1, WORD buf1len, return 0; } -/****************************************************************** - * IC_CallTo16 - * - * - */ -static LRESULT CALLBACK IC_CallTo16(HDRVR hdrv, HIC hic, UINT msg, LPARAM lp1, LPARAM lp2) -{ -#if 0 - WINE_HIC* whic = IC_GetPtr(hic); - LRESULT ret = 0; - - - if (whic->driverproc) - { - ret = whic->driverproc(hic, whic->hdrv, msg, lParam1, lParam2); - } - else - { - ret = SendDriverMessage(whic->hdrv, msg, lParam1, lParam2); - } -#else - FIXME("No 32=>16 conversion yet\n"); -#endif - return 0; -} - /************************************************************************** * DllEntryPoint (MSVIDEO.3) * @@ -898,15 +954,11 @@ static LRESULT CALLBACK IC_CallTo16(HDRVR hdrv, HIC hic, UINT msg, LPARAM lp1, BOOL WINAPI VIDEO_LibMain(DWORD fdwReason, HINSTANCE hinstDLL, WORD ds, WORD wHeapSize, DWORD dwReserved1, WORD wReserved2) { - switch (fdwReason) + switch (fdwReason) { case DLL_PROCESS_ATTACH: - /* hook in our 16 bit management functions */ - pFnCallTo16 = IC_CallTo16; break; case DLL_PROCESS_DETACH: - /* remove our 16 bit management functions */ - pFnCallTo16 = NULL; break; case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: diff --git a/dlls/msvfw32/vfw16.h b/dlls/msvideo.dll16/vfw16.h similarity index 100% rename from dlls/msvfw32/vfw16.h rename to dlls/msvideo.dll16/vfw16.h diff --git a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h index 15df5d0706e..3e54250da01 100644 --- a/dlls/ntdll/ntdll_misc.h +++ b/dlls/ntdll/ntdll_misc.h @@ -141,7 +141,6 @@ extern unsigned int DIR_get_drives_info( struct drive_info info[MAX_DOS_DRIVES] /* virtual memory */ extern void virtual_get_system_info( SYSTEM_BASIC_INFORMATION *info ); extern NTSTATUS virtual_create_system_view( void *base, SIZE_T size, DWORD vprot ); -extern SIZE_T virtual_free_system_view( PVOID *addr_ptr ); extern NTSTATUS virtual_alloc_thread_stack( TEB *teb, SIZE_T reserve_size, SIZE_T commit_size ); extern void virtual_clear_thread_stack(void); extern BOOL virtual_handle_stack_fault( void *addr ); diff --git a/dlls/ntdll/tests/rtlstr.c b/dlls/ntdll/tests/rtlstr.c index e1d4be7ea83..53f0c805697 100644 --- a/dlls/ntdll/tests/rtlstr.c +++ b/dlls/ntdll/tests/rtlstr.c @@ -89,7 +89,7 @@ static WCHAR* AtoW( const char* p ) { WCHAR* buffer; DWORD len = MultiByteToWideChar( CP_ACP, 0, p, -1, NULL, 0 ); - buffer = malloc( len * sizeof(WCHAR) ); + buffer = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR) ); MultiByteToWideChar( CP_ACP, 0, p, -1, buffer, len ); return buffer; } @@ -191,7 +191,7 @@ static void test_RtlInitUnicodeStringEx(void) UNICODE_STRING uni; NTSTATUS result; - teststring2 = malloc((TESTSTRING2_LEN + 1) * sizeof(WCHAR)); + teststring2 = HeapAlloc(GetProcessHeap(), 0, (TESTSTRING2_LEN + 1) * sizeof(WCHAR)); memset(teststring2, 'X', TESTSTRING2_LEN * sizeof(WCHAR)); teststring2[TESTSTRING2_LEN] = '\0'; @@ -293,7 +293,7 @@ static void test_RtlInitUnicodeStringEx(void) "pRtlInitUnicodeString(&uni, 0) sets Buffer to %p, expected %p\n", uni.Buffer, NULL); - free(teststring2); + HeapFree(GetProcessHeap(), 0, teststring2); } @@ -1364,7 +1364,7 @@ static void test_RtlUnicodeStringToInteger(void) ok(value == 0xdeadbeef || value == 0 /* vista */, "(test %d): RtlUnicodeStringToInteger(\"%s\", %d, [out]) assigns value %d, expected 0 or deadbeef\n", test_num, str2int[test_num].str, str2int[test_num].base, value); - free(wstr); + HeapFree(GetProcessHeap(), 0, wstr); } wstr = AtoW(str2int[1].str); @@ -1404,7 +1404,7 @@ static void test_RtlUnicodeStringToInteger(void) "didn't return expected value (test c): expected: %d, got: %d\n", 1, value); /* w2k: uni.Length = 0 returns value 11234567 instead of 0 */ - free(wstr); + HeapFree(GetProcessHeap(), 0, wstr); } diff --git a/dlls/ntdll/virtual.c b/dlls/ntdll/virtual.c index 9d46764ddfd..e0a758b22a5 100644 --- a/dlls/ntdll/virtual.c +++ b/dlls/ntdll/virtual.c @@ -1368,32 +1368,6 @@ NTSTATUS virtual_create_system_view( void *base, SIZE_T size, DWORD vprot ) /*********************************************************************** - * virtual_free_system_view - */ -SIZE_T virtual_free_system_view( PVOID *addr_ptr ) -{ - FILE_VIEW *view; - sigset_t sigset; - SIZE_T size = 0; - char *base = ROUND_ADDR( *addr_ptr, page_mask ); - - server_enter_uninterrupted_section( &csVirtual, &sigset ); - if ((view = VIRTUAL_FindView( base, 0 ))) - { - TRACE( "freeing %p-%p\n", view->base, (char *)view->base + view->size ); - /* return the values that the caller should use to unmap the area */ - *addr_ptr = view->base; - /* make sure we don't munmap anything from a reserved area */ - if (!wine_mmap_is_in_reserved_area( view->base, view->size )) size = view->size; - view->protect |= VPROT_SYSTEM; - delete_view( view ); - } - server_leave_uninterrupted_section( &csVirtual, &sigset ); - return size; -} - - -/*********************************************************************** * virtual_alloc_thread_stack */ NTSTATUS virtual_alloc_thread_stack( TEB *teb, SIZE_T reserve_size, SIZE_T commit_size ) diff --git a/dlls/ole32/tests/usrmarshal.c b/dlls/ole32/tests/usrmarshal.c index 3411cc283b1..b6e37fa089c 100644 --- a/dlls/ole32/tests/usrmarshal.c +++ b/dlls/ole32/tests/usrmarshal.c @@ -512,7 +512,6 @@ static void test_marshal_WdtpInterfacePointer(void) IUnknown *unk; IUnknown *unk2; unsigned char *wireip; - const IID *iid; /* shows that the WdtpInterfacePointer functions don't marshal anything for * NULL pointers, so code using these functions must handle that case @@ -530,34 +529,40 @@ static void test_marshal_WdtpInterfacePointer(void) init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_INPROC); size = WdtpInterfacePointer_UserSize(&umcb.Flags, umcb.Flags, 0, unk, &IID_IUnknown); todo_wine - ok(size > 28, "size should be > 28 bytes, not %d\n", size); + ok(size >= 0x4c, "size should be >= 0x4c bytes, not %d\n", size); trace("WdtpInterfacePointer_UserSize returned %d\n", size); buffer = HeapAlloc(GetProcessHeap(), 0, size); init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_INPROC); buffer_end = WdtpInterfacePointer_UserMarshal(&umcb.Flags, umcb.Flags, buffer, unk, &IID_IUnknown); wireip = buffer; - if (size >= 28) + if (size >= 0x4c) { + HGLOBAL h = GlobalAlloc(GMEM_MOVEABLE, 0); + IStream *stm; + void *ptr; + LARGE_INTEGER pos; + DWORD h_size; + + ok(buffer_end == buffer + 0x4c, "buffer_end %p buffer %p\n", buffer_end, buffer); ok(*(DWORD *)wireip == 0x44, "wireip + 0x0 should be 0x44 instead of 0x%08x\n", *(DWORD *)wireip); wireip += sizeof(DWORD); ok(*(DWORD *)wireip == 0x44, "wireip + 0x4 should be 0x44 instead of 0x%08x\n", *(DWORD *)wireip); wireip += sizeof(DWORD); - ok(*(DWORD *)wireip == 0x574f454d /* 'MEOW' */, "wireip + 0x8 should be 0x574f454d instead of 0x%08x\n", *(DWORD *)wireip); - wireip += sizeof(DWORD); - ok(*(DWORD *)wireip == 0x1, "wireip + 0xc should be 0x1 instead of 0x%08x\n", *(DWORD *)wireip); - wireip += sizeof(DWORD); - iid = (const IID *)wireip; - ok(IsEqualIID(iid, &IID_IUnknown), - "wireip + 0x10 should be IID_IUnknown instead of {%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}\n", - iid->Data1, iid->Data2, iid->Data3, - iid->Data4[0], iid->Data4[1], iid->Data4[2], iid->Data4[3], - iid->Data4[4], iid->Data4[5], iid->Data4[6], iid->Data4[7]); - wireip += sizeof(IID); - ok(*(DWORD *)wireip == 0, "wireip + 0x1c should be 0 instead of 0x%08x\n", *(DWORD *)wireip); - wireip += sizeof(DWORD); - ok(*(DWORD *)wireip == 5, "wireip + 0x20 should be 5 instead of %d\n", *(DWORD *)wireip); - wireip += sizeof(DWORD); - /* the rest is dynamic so can't really be tested */ + + /* The remaining 0x44 bytes are the result of CoMarshalInterface */ + + CreateStreamOnHGlobal(h, TRUE, &stm); + CoMarshalInterface(stm, &IID_IUnknown, unk, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL); + h_size = GlobalSize(h); + ok(h_size == 0x44, "size %x\n", h_size); + + ptr = GlobalLock(h); + ok(!memcmp(ptr, wireip, 0x44), "buffer mismatch\n"); + GlobalUnlock(h); + pos.QuadPart = 0; + IStream_Seek(stm, pos, STREAM_SEEK_SET, NULL); + CoReleaseMarshalData(stm); + IStream_Release(stm); } unk2 = NULL; diff --git a/dlls/oleaut32/tests/varformat.c b/dlls/oleaut32/tests/varformat.c index b19efbdbd02..3c0e72eb061 100644 --- a/dlls/oleaut32/tests/varformat.c +++ b/dlls/oleaut32/tests/varformat.c @@ -379,6 +379,8 @@ static void test_VarFormat(void) VARFMT(VT_R8,V_R8,-1.57,"0.00",S_OK,"-1.57"); VARFMT(VT_R8,V_R8,-1.57,"#.##",S_OK,"-1.57"); VARFMT(VT_R8,V_R8,-0.1,".#",S_OK,"-.1"); + VARFMT(VT_R8,V_R8,0.099,"#.#",S_OK,".1"); + VARFMT(VT_R8,V_R8,0.0999,"#.##",S_OK,".1"); /* 'out' is not cleared */ diff --git a/dlls/oleaut32/varformat.c b/dlls/oleaut32/varformat.c index 06bab0ffb36..f6c142dc284 100644 --- a/dlls/oleaut32/varformat.c +++ b/dlls/oleaut32/varformat.c @@ -1305,11 +1305,17 @@ static HRESULT VARIANT_FormatNumber(LPVARIANT pVarIn, LPOLESTR lpszFormat, else { rgbDig[have_int + need_frac] = 0; - have_int++; + if (exponent < 0) + exponent++; + else + have_int++; } } else (*prgbDig)++; + /* We converted trailing digits to zeroes => have_frac has changed */ + while (have_frac > 0 && rgbDig[have_int + have_frac - 1] == 0) + have_frac--; } } TRACE("have_int=%d,need_int=%d,have_frac=%d,need_frac=%d,pad=%d,exp=%d\n", diff --git a/dlls/opengl32/tests/opengl.c b/dlls/opengl32/tests/opengl.c index 49659eb8b4d..48a75f871b6 100644 --- a/dlls/opengl32/tests/opengl.c +++ b/dlls/opengl32/tests/opengl.c @@ -285,6 +285,59 @@ static void test_setpixelformat(HDC winhdc) } } +static void test_sharelists(HDC winhdc) +{ + HGLRC hglrc1, hglrc2, hglrc3; + int res; + + hglrc1 = wglCreateContext(winhdc); + res = wglShareLists(0, 0); + ok(res == FALSE, "Sharing display lists for no contexts passed!\n"); + + /* Test 1: Create a context and just share lists without doing anything special */ + hglrc2 = wglCreateContext(winhdc); + if(hglrc2) + { + res = wglShareLists(hglrc1, hglrc2); + ok(res, "Sharing of display lists failed\n"); + wglDeleteContext(hglrc2); + } + + /* Test 2: Share display lists with a 'destination' context which has been made current */ + hglrc2 = wglCreateContext(winhdc); + if(hglrc2) + { + res = wglMakeCurrent(winhdc, hglrc2); + ok(res, "Make current failed\n"); + res = wglShareLists(hglrc1, hglrc2); + todo_wine ok(res, "Sharing display lists with a destination context which has been made current passed\n"); + wglMakeCurrent(0, 0); + wglDeleteContext(hglrc2); + } + + /* Test 3: Share display lists with a context which already shares display lists with another context. + * According to MSDN the second paramater can't share any display lists but some buggy drivers might allow it */ + hglrc3 = wglCreateContext(winhdc); + if(hglrc3) + { + res = wglShareLists(hglrc3, hglrc1); + ok(res == FALSE, "Sharing of display lists failed for a context which already shared lists before\n"); + wglDeleteContext(hglrc3); + } + + /* Test 4: Share display lists with a 'source' context which has been made current */ + hglrc2 = wglCreateContext(winhdc); + if(hglrc2) + { + res = wglMakeCurrent(winhdc, hglrc1); + ok(res, "Make current failed\n"); + res = wglShareLists(hglrc1, hglrc2); + ok(res, "Sharing display lists with a source context which has been made current passed\n"); + wglMakeCurrent(0, 0); + wglDeleteContext(hglrc2); + } +} + static void test_makecurrent(HDC winhdc) { BOOL ret; @@ -601,6 +654,7 @@ START_TEST(opengl) test_makecurrent(hdc); test_setpixelformat(hdc); + test_sharelists(hdc); test_colorbits(hdc); test_gdi_dbuf(hdc); diff --git a/dlls/pdh/pdh_main.c b/dlls/pdh/pdh_main.c index 8e91cafce83..9ca174b957e 100644 --- a/dlls/pdh/pdh_main.c +++ b/dlls/pdh/pdh_main.c @@ -1098,6 +1098,8 @@ PDH_STATUS WINAPI PdhMakeCounterPathA( PDH_COUNTER_PATH_ELEMENTS_A *e, LPSTR buf } heap_free( bufferW ); } + else + ret = PDH_MEMORY_ALLOCATION_FAILURE; } done: diff --git a/dlls/riched20/editor.h b/dlls/riched20/editor.h index 77b33d248c7..8568420dedd 100644 --- a/dlls/riched20/editor.h +++ b/dlls/riched20/editor.h @@ -86,7 +86,6 @@ void ME_DumpDocument(ME_TextBuffer *buffer); const char *ME_GetDITypeName(ME_DIType type); /* string.c */ -ME_String *ME_MakeString(LPCWSTR szText); ME_String *ME_MakeStringN(LPCWSTR szText, int nMaxChars); ME_String *ME_MakeStringR(WCHAR cRepeat, int nMaxChars); ME_String *ME_StrDup(const ME_String *s); diff --git a/dlls/riched20/string.c b/dlls/riched20/string.c index 128e3c2ea7c..db45d928d64 100644 --- a/dlls/riched20/string.c +++ b/dlls/riched20/string.c @@ -49,11 +49,6 @@ ME_String *ME_MakeStringN(LPCWSTR szText, int nMaxChars) return s; } -ME_String *ME_MakeString(LPCWSTR szText) -{ - return ME_MakeStringN(szText, lstrlenW(szText)); -} - /* Make a string by repeating a char nMaxChars times */ ME_String *ME_MakeStringR(WCHAR cRepeat, int nMaxChars) { diff --git a/dlls/rpcrt4/rpc_message.c b/dlls/rpcrt4/rpc_message.c index d3374cbbb82..46830c8583c 100644 --- a/dlls/rpcrt4/rpc_message.c +++ b/dlls/rpcrt4/rpc_message.c @@ -527,7 +527,7 @@ BOOL RPCRT4_IsValidHttpPacket(RpcPktHdr *hdr, unsigned char *data, } /* assumes the HTTP packet has been validated */ -unsigned char *RPCRT4_NextHttpHeaderField(unsigned char *data) +static unsigned char *RPCRT4_NextHttpHeaderField(unsigned char *data) { ULONG type; @@ -1032,7 +1032,7 @@ RPC_STATUS RPCRT4_ValidateCommonHeader(const RpcPktCommonHdr *hdr) * * Receive a fragment from a connection. */ -RPC_STATUS RPCRT4_default_receive_fragment(RpcConnection *Connection, RpcPktHdr **Header, void **Payload) +static RPC_STATUS RPCRT4_default_receive_fragment(RpcConnection *Connection, RpcPktHdr **Header, void **Payload) { RPC_STATUS status; DWORD hdr_length; diff --git a/dlls/rpcrt4/rpc_message.h b/dlls/rpcrt4/rpc_message.h index 228a7c8a6bf..8ce5a558adc 100644 --- a/dlls/rpcrt4/rpc_message.h +++ b/dlls/rpcrt4/rpc_message.h @@ -41,7 +41,6 @@ DWORD RPCRT4_GetHeaderSize(const RpcPktHdr *Header); RPC_STATUS RPCRT4_ValidateCommonHeader(const RpcPktCommonHdr *hdr); BOOL RPCRT4_IsValidHttpPacket(RpcPktHdr *hdr, unsigned char *data, unsigned short data_len); -unsigned char *RPCRT4_NextHttpHeaderField(unsigned char *data); RPC_STATUS RPCRT4_ParseHttpPrepareHeader1(RpcPktHdr *header, unsigned char *data, ULONG *field1); RPC_STATUS RPCRT4_ParseHttpPrepareHeader2(RpcPktHdr *header, unsigned char *data, ULONG *field1, ULONG *bytes_until_next_packet, ULONG *field3); RPC_STATUS RPCRT4_ParseHttpFlowControlHeader(RpcPktHdr *header, unsigned char *data, BOOL server, ULONG *bytes_transmitted, ULONG *flow_control_increment, UUID *pipe_uuid); diff --git a/dlls/secur32/tests/secur32.c b/dlls/secur32/tests/secur32.c index 21bb83a5cba..0ad6f0f5523 100644 --- a/dlls/secur32/tests/secur32.c +++ b/dlls/secur32/tests/secur32.c @@ -48,7 +48,7 @@ static void testGetComputerObjectNameA(void) char name[256]; ULONG size; BOOLEAN rc; - int i; + UINT i; for (i = 0; i < (sizeof(formats) / sizeof(formats[0])); i++) { size = sizeof(name); @@ -73,7 +73,7 @@ static void testGetComputerObjectNameW(void) WCHAR nameW[256]; ULONG size; BOOLEAN rc; - int i; + UINT i; for (i = 0; i < (sizeof(formats) / sizeof(formats[0])); i++) { size = sizeof(nameW)/sizeof(nameW[0]); @@ -101,7 +101,7 @@ static void testGetUserNameExA(void) char name[256]; ULONG size; BOOLEAN rc; - int i; + UINT i; for (i = 0; i < (sizeof(formats) / sizeof(formats[0])); i++) { size = sizeof(name); @@ -148,7 +148,7 @@ static void testGetUserNameExW(void) WCHAR nameW[256]; ULONG size; BOOLEAN rc; - int i; + UINT i; for (i = 0; i < (sizeof(formats) / sizeof(formats[0])); i++) { size = sizeof(nameW); diff --git a/dlls/setupapi/misc.c b/dlls/setupapi/misc.c index 63320e62166..36d52ba7bd8 100644 --- a/dlls/setupapi/misc.c +++ b/dlls/setupapi/misc.c @@ -1114,6 +1114,45 @@ BOOL WINAPI SetupCopyOEMInfW( PCWSTR source, PCWSTR location, } /*********************************************************************** + * SetupUninstallOEMInfA (SETUPAPI.@) + */ +BOOL WINAPI SetupUninstallOEMInfA( PCSTR inf_file, DWORD flags, PVOID reserved ) +{ + BOOL ret; + WCHAR *inf_fileW = NULL; + + TRACE("%s, 0x%08x, %p\n", debugstr_a(inf_file), flags, reserved); + + if (inf_file && !(inf_fileW = strdupAtoW( inf_file ))) return FALSE; + ret = SetupUninstallOEMInfW( inf_fileW, flags, reserved ); + HeapFree( GetProcessHeap(), 0, inf_fileW ); + return ret; +} + +/*********************************************************************** + * SetupUninstallOEMInfW (SETUPAPI.@) + */ +BOOL WINAPI SetupUninstallOEMInfW( PCWSTR inf_file, DWORD flags, PVOID reserved ) +{ + static const WCHAR infW[] = {'\\','i','n','f','\\',0}; + WCHAR target[MAX_PATH]; + + TRACE("%s, 0x%08x, %p\n", debugstr_w(inf_file), flags, reserved); + + if (!GetWindowsDirectoryW( target, sizeof(target)/sizeof(WCHAR) )) return FALSE; + + strcatW( target, infW ); + strcatW( target, inf_file ); + + if (flags & SUOI_FORCEDELETE) + return DeleteFileW(target); + + FIXME("not deleting %s\n", debugstr_w(target)); + + return TRUE; +} + +/*********************************************************************** * InstallCatalog (SETUPAPI.@) */ DWORD WINAPI InstallCatalog( LPCSTR catalog, LPCSTR basename, LPSTR fullname ) diff --git a/dlls/setupapi/setupapi.spec b/dlls/setupapi/setupapi.spec index c37a2b9c94e..e3fe250b5ba 100644 --- a/dlls/setupapi/setupapi.spec +++ b/dlls/setupapi/setupapi.spec @@ -95,8 +95,8 @@ @ stub CM_Get_Device_Interface_List_ExW @ stub CM_Get_Device_Interface_List_SizeA @ stub CM_Get_Device_Interface_List_SizeW -@ stub CM_Get_Device_Interface_List_Size_ExA -@ stub CM_Get_Device_Interface_List_Size_ExW +@ stdcall CM_Get_Device_Interface_List_Size_ExA(ptr ptr str long ptr) +@ stdcall CM_Get_Device_Interface_List_Size_ExW(ptr ptr wstr long ptr) @ stub CM_Get_First_Log_Conf @ stub CM_Get_First_Log_Conf_Ex @ stub CM_Get_Global_State @@ -130,8 +130,8 @@ @ stub CM_Is_Dock_Station_Present @ stdcall CM_Locate_DevNodeA(ptr str long) @ stdcall CM_Locate_DevNodeW(ptr wstr long) -@ stub CM_Locate_DevNode_ExA -@ stub CM_Locate_DevNode_ExW +@ stdcall CM_Locate_DevNode_ExA(ptr str long long) +@ stdcall CM_Locate_DevNode_ExW(ptr wstr long long) @ stub CM_Merge_Range_List @ stub CM_Modify_Res_Des @ stub CM_Modify_Res_Des_Ex @@ -526,6 +526,8 @@ @ stdcall SetupSetSourceListW(long ptr long) @ stdcall SetupTermDefaultQueueCallback(ptr) @ stdcall SetupTerminateFileLog(long) +@ stdcall SetupUninstallOEMInfA(str long ptr) +@ stdcall SetupUninstallOEMInfW(wstr long ptr) @ stub ShouldDeviceBeExcluded @ stdcall StampFileSecurity(wstr ptr) @ stdcall StringTableAddString(ptr wstr long) diff --git a/dlls/setupapi/setupx.spec b/dlls/setupapi/setupx.spec index 590355fb633..e5bdf23686f 100644 --- a/dlls/setupapi/setupx.spec +++ b/dlls/setupapi/setupx.spec @@ -122,7 +122,7 @@ 200 pascal VcpOpen(segptr ptr) VcpOpen16 201 pascal VcpClose(word str) VcpClose16 202 pascal -ret16 vcpDefCallbackProc(ptr word word long long) vcpDefCallbackProc16 -203 stub vcpEnumFiles #(ptr long) +203 pascal VcpEnumFiles(ptr long) 204 pascal -ret16 VcpQueueRename(str str str str word word long) VcpQueueRename16 205 pascal -ret16 vsmGetStringName(word ptr word) vsmGetStringName16 206 pascal -ret16 vsmStringDelete(word) vsmStringDelete16 diff --git a/dlls/setupapi/setupx16.h b/dlls/setupapi/setupx16.h index e9e800ac52f..f348340d016 100644 --- a/dlls/setupapi/setupx16.h +++ b/dlls/setupapi/setupx16.h @@ -382,7 +382,6 @@ RETERR16 WINAPI VcpQueueCopy16( LPEXPANDVTBL lpExpandVtbl, WORD fl, LPARAM lParam ); -RETERR16 VcpFlush16(WORD fl, LPCSTR lpszBackupDest); RETERR16 WINAPI VcpClose16(WORD fl, LPCSTR lpszBackupDest); /* VcpExplain flags */ diff --git a/dlls/setupapi/stubs.c b/dlls/setupapi/stubs.c index 39974478197..eed89722b90 100644 --- a/dlls/setupapi/stubs.c +++ b/dlls/setupapi/stubs.c @@ -265,3 +265,43 @@ CONFIGRET WINAPI CM_Locate_DevNodeW(PDEVINST pdnDevInst, DEVINSTID_W pDeviceID, return CR_FAILURE; } + +/*********************************************************************** + * CM_Locate_DevNode_ExA (SETUPAPI.@) + */ +CONFIGRET WINAPI CM_Locate_DevNode_ExA(PDEVINST pdnDevInst, DEVINSTID_A pDeviceID, ULONG ulFlags, HMACHINE hMachine) +{ + FIXME("%p %s 0x%08x %p: stub\n", pdnDevInst, debugstr_a(pDeviceID), ulFlags, hMachine); + + return CR_FAILURE; +} + +/*********************************************************************** + * CM_Locate_DevNode_ExW (SETUPAPI.@) + */ +CONFIGRET WINAPI CM_Locate_DevNode_ExW(PDEVINST pdnDevInst, DEVINSTID_W pDeviceID, ULONG ulFlags, HMACHINE hMachine) +{ + FIXME("%p %s 0x%08x %p: stub\n", pdnDevInst, debugstr_w(pDeviceID), ulFlags, hMachine); + + return CR_FAILURE; +} + +/*********************************************************************** + * CM_Get_Device_Interface_List_Size_ExA (SETUPAPI.@) + */ +CONFIGRET WINAPI CM_Get_Device_Interface_List_Size_ExA(PULONG len, LPGUID class, DEVINSTID_A id, + ULONG flags, HMACHINE machine) +{ + FIXME("%p %p %s 0x%08x %p: stub\n", len, class, debugstr_a(id), flags, machine); + return CR_FAILURE; +} + +/*********************************************************************** + * CM_Get_Device_Interface_List_Size_ExW (SETUPAPI.@) + */ +CONFIGRET WINAPI CM_Get_Device_Interface_List_Size_ExW(PULONG len, LPGUID class, DEVINSTID_W id, + ULONG flags, HMACHINE machine) +{ + FIXME("%p %p %s 0x%08x %p: stub\n", len, class, debugstr_w(id), flags, machine); + return CR_FAILURE; +} diff --git a/dlls/setupapi/tests/parser.c b/dlls/setupapi/tests/parser.c index 91a84252804..a67a5cd4f5d 100644 --- a/dlls/setupapi/tests/parser.c +++ b/dlls/setupapi/tests/parser.c @@ -589,6 +589,12 @@ static void test_SetupGetIntField(void) retb = SetupGetIntField( &context, keys[i].index, &intfield ); if ( keys[i].err == ERROR_SUCCESS ) { + if ( !retb && !lstrcmpA( keys[i].key, "123=" ) ) + { + win_skip( "results differ on Win9x\n" ); + SetupCloseInfFile( hinf ); + continue; + } ok( retb, "%u: Expected success\n", i ); ok( GetLastError() == ERROR_SUCCESS || GetLastError() == 0xdeadbeef /* win9x, NT4 */, diff --git a/dlls/setupapi/virtcopy.c b/dlls/setupapi/virtcopy.c index c2fded22ccc..2506a6a29bd 100644 --- a/dlls/setupapi/virtcopy.c +++ b/dlls/setupapi/virtcopy.c @@ -161,18 +161,6 @@ INT16 WINAPI vsmStringDelete16(VHSTR vhstr) return VCPN_FAIL; } -/* - * vsmStringFind() - not exported from a standard SETUPX.DLL, it seems - */ -VHSTR WINAPI vsmStringFind16(LPCSTR lpszName) -{ - WORD n; - for (n = 0; n < vhstr_alloc; n++) - if ((vhstrlist[n]) && (vhstrlist[n]->refcount) && (!strcmp(vhstrlist[n]->pStr, lpszName))) - return n; - return 0xffff; -} - /*********************************************************************** * vsmGetStringName (SETUPX.205) * @@ -194,16 +182,6 @@ INT16 WINAPI vsmGetStringName16(VHSTR vhstr, LPSTR lpszBuffer, int cbBuffer) } /*********************************************************************** - * vsmStringCompare (not exported from a standard SETUPX.DLL, it seems) - */ -INT16 WINAPI vsmStringCompare16(VHSTR vhstrA, VHSTR vhstrB) -{ - if ((!VALID_VHSTR(vhstrA)) || (!VALID_VHSTR(vhstrB))) - return VCPN_FAIL; /* correct ? */ - return strcmp(vhstrlist[vhstrA]->pStr, vhstrlist[vhstrB]->pStr); -} - -/*********************************************************************** * vsmGetStringRawName (SETUPX.208) */ LPCSTR WINAPI vsmGetStringRawName16(VHSTR vhstr) @@ -266,26 +244,6 @@ static RETERR16 VCP_VirtnodeCreate(const VCPFILESPEC *vfsSrc, const VCPFILESPEC return OK; } -#if 0 -static BOOL VCP_VirtnodeDelete(LPVIRTNODE lpvnDel) -{ - DWORD n; - RETERR16 cbres; - - for (n = 0; n < vn_last; n++) - { - if (pvnlist[n] == lpvnDel) - { - cbres = VCP_Callback(lpvnDel, VCPM_NODEDESTROY, 0, 0, VCP_MsgRef); - HeapFree(GetProcessHeap(), 0, lpvnDel); - pvnlist[n] = NULL; - return TRUE; - } - } - return FALSE; -} -#endif - /*********************************************************************** * VcpOpen (SETUPX.200) * @@ -505,16 +463,6 @@ static RETERR16 VCP_CopyFiles(void) } /*********************************************************************** - * VcpFlush - internal (not exported), but documented - * - * VNFL_NOW is used for VcpFlush. - */ -RETERR16 VcpFlush16(WORD fl, LPCSTR lpszBackupDest) -{ - return OK; -} - -/*********************************************************************** * VcpClose (SETUPX.201) * * Does callbacks (-> vifproc) with VCPM_VSTATCLOSESTART, @@ -554,32 +502,6 @@ RETERR16 WINAPI VcpClose16(WORD fl, LPCSTR lpszBackupDest) return OK; } -#if 0 -static RETERR16 VCP_RenameFiles(void) -{ - char fn_src[MAX_PATH], fn_dst[MAX_PATH]; - RETERR16 res = OK, cbres; - DWORD n; - LPVIRTNODE lpvn; - - cbres = VCP_Callback(&vcp_status, VCPM_VSTATRENAMESTART, 0, 0, VCP_MsgRef); - for (n = 0; n < vn_num; n++) - { - lpvn = pvnlist[n]; - if ((!lpvn) || ((lpvn->fl & VNFL_NODE_TYPE) != VNFL_RENAME)) continue; - strcpy(fn_src, VcpExplain16(lpvn, VCPEX_SRC_FULL)); - strcpy(fn_dst, VcpExplain16(lpvn, VCPEX_DST_FULL)); - cbres = VCP_Callback(&lpvn->vfsDst, VCPM_FILEOPENOUT, 0, (LPARAM)lpvn, VCP_MsgRef); - if (!(MoveFileExA(fn_src, fn_dst, MOVEFILE_REPLACE_EXISTING))) - res = ERR_VCP_IOFAIL; - else - VCP_VirtnodeDelete(lpvn); - } - cbres = VCP_Callback(&vcp_status, VCPM_VSTATRENAMEEND, 0, 0, VCP_MsgRef); - return res; -} -#endif - /*********************************************************************** * vcpDefCallbackProc (SETUPX.202) */ diff --git a/dlls/shdocvw/tests/webbrowser.c b/dlls/shdocvw/tests/webbrowser.c index fe7df890de8..131b29ca8bc 100644 --- a/dlls/shdocvw/tests/webbrowser.c +++ b/dlls/shdocvw/tests/webbrowser.c @@ -275,6 +275,7 @@ static HRESULT WINAPI OleCommandTarget_Exec(IOleCommandTarget *iface, const GUID case 66: /* TODO */ case 67: /* TODO */ case 69: /* TODO */ + case 101: /* TODO (IE8) */ return E_FAIL; default: ok(0, "unexpected nCmdID %d\n", nCmdID); diff --git a/dlls/shell32/brsfolder.c b/dlls/shell32/brsfolder.c index cc8a91daef8..925d439f941 100644 --- a/dlls/shell32/brsfolder.c +++ b/dlls/shell32/brsfolder.c @@ -723,9 +723,11 @@ static BOOL BrsFolder_OnSetExpanded(browse_info *info, LPVOID selection, /* Initialize item to point to the first child of the root folder. */ memset(&item, 0, sizeof(item)); item.mask = TVIF_PARAM; - item.hItem = TreeView_GetRoot(info->hwndTreeView); - if (item.hItem) - item.hItem = TreeView_GetChild(info->hwndTreeView, item.hItem); + item.hItem = (HTREEITEM)SendMessageW(info->hwndTreeView, TVM_GETNEXTITEM, TVGN_ROOT, 0); + + if (item.hItem) + item.hItem = (HTREEITEM)SendMessageW(info->hwndTreeView, TVM_GETNEXTITEM, TVGN_CHILD, + (LPARAM)item.hItem); /* Walk the tree along the nodes corresponding to the remaining ITEMIDLIST */ while (item.hItem && !_ILIsEmpty(pidlCurrent)) { @@ -740,10 +742,12 @@ static BOOL BrsFolder_OnSetExpanded(browse_info *info, LPVOID selection, /* Only expand current node and move on to it's first child, * if we didn't already reach the last SHITEMID */ SendMessageW(info->hwndTreeView, TVM_EXPAND, TVE_EXPAND, (LPARAM)item.hItem); - item.hItem = TreeView_GetChild(info->hwndTreeView, item.hItem); + item.hItem = (HTREEITEM)SendMessageW(info->hwndTreeView, TVM_GETNEXTITEM, TVGN_CHILD, + (LPARAM)item.hItem); } } else { - item.hItem = TreeView_GetNextSibling(info->hwndTreeView, item.hItem); + item.hItem = (HTREEITEM)SendMessageW(info->hwndTreeView, TVM_GETNEXTITEM, TVGN_NEXT, + (LPARAM)item.hItem); } } diff --git a/dlls/shell32/control.c b/dlls/shell32/control.c index 5d2e2deb6d9..88d6ead0d03 100644 --- a/dlls/shell32/control.c +++ b/dlls/shell32/control.c @@ -214,8 +214,8 @@ static BOOL Control_CreateListView (CPanel *panel) panel->hImageListLarge = ImageList_Create(GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON), ILC_MASK, 1, 1); - (void) ListView_SetImageList(panel->hWndListView, panel->hImageListSmall, LVSIL_SMALL); - (void) ListView_SetImageList(panel->hWndListView, panel->hImageListLarge, LVSIL_NORMAL); + SendMessageW(panel->hWndListView, LVM_SETIMAGELIST, LVSIL_SMALL, (LPARAM)panel->hImageListSmall); + SendMessageW(panel->hWndListView, LVM_SETIMAGELIST, LVSIL_NORMAL, (LPARAM)panel->hImageListLarge); /* Create columns for list view */ lvc.mask = LVCF_FMT | LVCF_TEXT | LVCF_SUBITEM | LVCF_WIDTH; diff --git a/dlls/shell32/shell32_Nl.rc b/dlls/shell32/shell32_Nl.rc index 7bea2e889b3..71a0545e46d 100644 --- a/dlls/shell32/shell32_Nl.rc +++ b/dlls/shell32/shell32_Nl.rc @@ -160,12 +160,12 @@ FONT 8, "MS Shell Dlg" LTEXT "", IDD_MESSAGE, 40, 10, 238, 52, 0 } -SHELL_ABOUT_MSGBOX DIALOG LOADONCALL MOVEABLE DISCARDABLE 15, 40, 210, 152 +SHELL_ABOUT_MSGBOX DIALOG LOADONCALL MOVEABLE DISCARDABLE 15, 40, 220, 152 STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU CAPTION "Info %s" FONT 10, "MS Shell Dlg" { - DEFPUSHBUTTON "OK", IDOK, 153, 133, 50, 12, WS_TABSTOP + DEFPUSHBUTTON "OK", IDOK, 153, 133, 60, 12, WS_TABSTOP PUSHBUTTON "Wine &licentie...", IDC_ABOUT_LICENSE, 153, 113, 60, 12, WS_TABSTOP LISTBOX IDC_ABOUT_LISTBOX, 8, 65, 137, 82, LBS_NOTIFY | WS_VSCROLL | WS_BORDER ICON "", stc1, 10, 10, 30, 30 diff --git a/dlls/shell32/shell32_main.c b/dlls/shell32/shell32_main.c index 5706d5004ce..6a4848f9dc7 100644 --- a/dlls/shell32/shell32_main.c +++ b/dlls/shell32/shell32_main.c @@ -911,8 +911,8 @@ HRESULT WINAPI SHLoadInProc (REFCLSID rclsid) /************************************************************************* * AboutDlgProc (internal) */ -INT_PTR CALLBACK AboutDlgProc( HWND hWnd, UINT msg, WPARAM wParam, - LPARAM lParam ) +static INT_PTR CALLBACK AboutDlgProc( HWND hWnd, UINT msg, WPARAM wParam, + LPARAM lParam ) { HWND hWndCtl; diff --git a/dlls/shell32/shell32_main.h b/dlls/shell32/shell32_main.h index eea2e18299a..86652a16d11 100644 --- a/dlls/shell32/shell32_main.h +++ b/dlls/shell32/shell32_main.h @@ -68,7 +68,6 @@ BOOL HCR_GetClassNameA(REFIID riid, LPSTR szDest, DWORD len); BOOL HCR_GetFolderAttributes(LPCITEMIDLIST pidlFolder, LPDWORD dwAttributes); -INT_PTR CALLBACK AboutDlgProc(HWND,UINT,WPARAM,LPARAM); DWORD WINAPI ParseFieldA(LPCSTR src, DWORD nField, LPSTR dst, DWORD len); DWORD WINAPI ParseFieldW(LPCWSTR src, DWORD nField, LPWSTR dst, DWORD len); @@ -190,10 +189,6 @@ static inline WCHAR * __SHCloneStrAtoW(WCHAR ** target, const char * source) return *target; } -typedef UINT_PTR (*SHELL_ExecuteW32)(const WCHAR *lpCmd, WCHAR *env, BOOL shWait, - const SHELLEXECUTEINFOW *sei, LPSHELLEXECUTEINFOW sei_out); - -BOOL SHELL_execute(LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc); extern WCHAR swShell32Name[MAX_PATH]; diff --git a/dlls/shell32/shlexec.c b/dlls/shell32/shlexec.c index 201791faaee..1a12e51d42e 100644 --- a/dlls/shell32/shlexec.c +++ b/dlls/shell32/shlexec.c @@ -59,6 +59,9 @@ static const WCHAR wszEmpty[] = {0}; #define SEE_MASK_CLASSALL (SEE_MASK_CLASSNAME | SEE_MASK_CLASSKEY) +typedef UINT_PTR (*SHELL_ExecuteW32)(const WCHAR *lpCmd, WCHAR *env, BOOL shWait, + const SHELLEXECUTEINFOW *sei, LPSHELLEXECUTEINFOW sei_out); + /*********************************************************************** * SHELL_ArgifyW [Internal] @@ -1465,7 +1468,7 @@ static void do_error_dialog( UINT_PTR retval, HWND hwnd ) /************************************************************************* * SHELL_execute [Internal] */ -BOOL SHELL_execute( LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc ) +static BOOL SHELL_execute( LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc ) { static const WCHAR wSpace[] = {' ',0}; static const WCHAR wWww[] = {'w','w','w',0}; diff --git a/dlls/shell32/shlview.c b/dlls/shell32/shlview.c index c5783dcda89..318b15b7c19 100644 --- a/dlls/shell32/shlview.c +++ b/dlls/shell32/shlview.c @@ -560,7 +560,7 @@ static BOOLEAN LV_AddItem(IShellViewImpl * This, LPCITEMIDLIST pidl) TRACE("(%p)(pidl=%p)\n", This, pidl); lvItem.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM; /*set the mask*/ - lvItem.iItem = ListView_GetItemCount(This->hWndList); /*add the item to the end of the list*/ + lvItem.iItem = SendMessageW(This->hWndList, LVM_GETITEMCOUNT, 0, 0); /*add the item to the end of the list*/ lvItem.iSubItem = 0; lvItem.lParam = (LPARAM) ILClone(ILFindLastID(pidl)); /*set the item's data*/ lvItem.pszText = LPSTR_TEXTCALLBACKW; /*get text on a callback basis*/ @@ -578,7 +578,7 @@ static BOOLEAN LV_DeleteItem(IShellViewImpl * This, LPCITEMIDLIST pidl) TRACE("(%p)(pidl=%p)\n", This, pidl); nIndex = LV_FindItemByPidl(This, ILFindLastID(pidl)); - return (-1==ListView_DeleteItem(This->hWndList, nIndex))? FALSE: TRUE; + return (-1==SendMessageW(This->hWndList, LVM_DELETEITEM, nIndex, 0))? FALSE: TRUE; } /********************************************************** @@ -836,7 +836,7 @@ static UINT ShellView_GetSelections(IShellViewImpl * This) SHFree(This->apidl); - This->cidl = ListView_GetSelectedCount(This->hWndList); + This->cidl = SendMessageW(This->hWndList, LVM_GETSELECTEDCOUNT, 0, 0); This->apidl = SHAlloc(This->cidl * sizeof(LPITEMIDLIST)); TRACE("selected=%i\n", This->cidl); @@ -1494,14 +1494,13 @@ static LRESULT ShellView_OnNotify(IShellViewImpl * This, UINT CtlID, LPNMHDR lpn if(plvKeyDown->wVKey == VK_F2) { /* see how many files are selected */ - int i = ListView_GetSelectedCount(This->hWndList); + int i = SendMessageW(This->hWndList, LVM_GETSELECTEDCOUNT, 0, 0); /* get selected item */ if(i == 1) { /* get selected item */ - i = ListView_GetNextItem(This->hWndList, -1, - LVNI_SELECTED); + i = SendMessageW(This->hWndList, LVM_GETNEXTITEM, -1, MAKELPARAM (LVNI_SELECTED, 0)); SendMessageW(This->hWndList, LVM_ENSUREVISIBLE, i, 0); SendMessageW(This->hWndList, LVM_EDITLABELW, i, 0); @@ -1524,7 +1523,7 @@ static LRESULT ShellView_OnNotify(IShellViewImpl * This, UINT CtlID, LPNMHDR lpn if (psfhlp == NULL) break; - if(!(i = ListView_GetSelectedCount(This->hWndList))) + if(!(i = SendMessageW(This->hWndList, LVM_GETSELECTEDCOUNT, 0, 0))) break; /* allocate memory for the pidl array */ @@ -1534,11 +1533,11 @@ static LRESULT ShellView_OnNotify(IShellViewImpl * This, UINT CtlID, LPNMHDR lpn /* retrieve all selected items */ i = 0; item_index = -1; - while(ListView_GetSelectedCount(This->hWndList) > i) + while(SendMessageW(This->hWndList, LVM_GETSELECTEDCOUNT, 0, 0) > i) { /* get selected item */ - item_index = ListView_GetNextItem(This->hWndList, - item_index, LVNI_SELECTED); + item_index = SendMessageW(This->hWndList, LVM_GETNEXTITEM, item_index, + MAKELPARAM (LVNI_SELECTED, 0)); item.iItem = item_index; item.mask = LVIF_PARAM; SendMessageA(This->hWndList, LVM_GETITEMA, 0, (LPARAM) &item); diff --git a/dlls/shell32/tests/shlexec.c b/dlls/shell32/tests/shlexec.c index 863cea16120..3460e1fca40 100644 --- a/dlls/shell32/tests/shlexec.c +++ b/dlls/shell32/tests/shlexec.c @@ -333,11 +333,11 @@ static void create_test_verb_dde(const char* extension, const char* verb, } else { - cmd=malloc(strlen(argv0)+10+strlen(child_file)+2+strlen(cmdtail)+1); + cmd=HeapAlloc(GetProcessHeap(), 0, strlen(argv0)+10+strlen(child_file)+2+strlen(cmdtail)+1); sprintf(cmd,"%s shlexec \"%s\" %s", argv0, child_file, cmdtail); rc=RegSetValueEx(hkey_cmd, NULL, 0, REG_SZ, (LPBYTE)cmd, strlen(cmd)+1); assert(rc==ERROR_SUCCESS); - free(cmd); + HeapFree(GetProcessHeap(), 0, cmd); } if (ddeexec) diff --git a/dlls/shlwapi/ordinal.c b/dlls/shlwapi/ordinal.c index 882058e60db..c18d1ea1db8 100644 --- a/dlls/shlwapi/ordinal.c +++ b/dlls/shlwapi/ordinal.c @@ -2914,6 +2914,26 @@ static HRESULT SHLWAPI_InvokeByIID( } /************************************************************************* + * IConnectionPoint_InvokeWithCancel [SHLWAPI.283] + */ +HRESULT WINAPI IConnectionPoint_InvokeWithCancel( IConnectionPoint* iCP, + DISPID dispId, DISPPARAMS* dispParams, + DWORD unknown1, DWORD unknown2 ) +{ + IID iid; + HRESULT result; + + FIXME("(%p)->(0x%x %p %x %x) partial stub\n", iCP, dispId, dispParams, unknown1, unknown2); + + result = IConnectionPoint_GetConnectionInterface(iCP, &iid); + if (SUCCEEDED(result)) + result = SHLWAPI_InvokeByIID(iCP, &iid, dispId, dispParams); + + return result; +} + + +/************************************************************************* * @ [SHLWAPI.284] * * IConnectionPoint_SimpleInvoke diff --git a/dlls/shlwapi/shlwapi.spec b/dlls/shlwapi/shlwapi.spec index 0b1cd4c569d..d9cc3a5f842 100644 --- a/dlls/shlwapi/shlwapi.spec +++ b/dlls/shlwapi/shlwapi.spec @@ -280,7 +280,7 @@ 280 stdcall -noname SHRegGetIntW(ptr wstr long) 281 stdcall -noname SHPackDispParamsV(ptr ptr long ptr) 282 varargs -noname SHPackDispParams(ptr ptr long) -283 stub -noname IConnectionPoint_InvokeWithCancel +283 stdcall -noname IConnectionPoint_InvokeWithCancel(ptr long long long long) 284 stdcall -noname IConnectionPoint_SimpleInvoke(ptr long ptr) 285 stdcall -noname IConnectionPoint_OnChanged(ptr long) 286 varargs -noname IUnknown_CPContainerInvokeParam(ptr ptr long ptr long) diff --git a/dlls/urlmon/binding.c b/dlls/urlmon/binding.c index 28d0802174b..3ff4683e053 100644 --- a/dlls/urlmon/binding.c +++ b/dlls/urlmon/binding.c @@ -100,18 +100,14 @@ struct Binding { LPWSTR url; IID iid; BOOL report_mime; - DWORD continue_call; DWORD state; HRESULT hres; download_state_t download_state; IUnknown *obj; IMoniker *mon; IBindCtx *bctx; - - DWORD apartment_thread; HWND notif_hwnd; - task_header_t *task_queue_head, *task_queue_tail; CRITICAL_SECTION section; }; @@ -124,43 +120,6 @@ struct Binding { #define STREAM(x) ((IStream*) &(x)->lpStreamVtbl) #define HTTPNEG2(x) ((IHttpNegotiate2*) &(x)->lpHttpNegotiate2Vtbl) -#define WM_MK_CONTINUE (WM_USER+101) - -static void push_task(Binding *binding, task_header_t *task, task_proc_t proc) -{ - task->proc = proc; - task->next = NULL; - - EnterCriticalSection(&binding->section); - - if(binding->task_queue_tail) { - binding->task_queue_tail->next = task; - binding->task_queue_tail = task; - }else { - binding->task_queue_tail = binding->task_queue_head = task; - } - - LeaveCriticalSection(&binding->section); -} - -static task_header_t *pop_task(Binding *binding) -{ - task_header_t *ret; - - EnterCriticalSection(&binding->section); - - ret = binding->task_queue_head; - if(ret) { - binding->task_queue_head = ret->next; - if(!binding->task_queue_head) - binding->task_queue_tail = NULL; - } - - LeaveCriticalSection(&binding->section); - - return ret; -} - static void fill_stgmed_buffer(stgmed_buf_t *buf) { DWORD read = 0; @@ -175,59 +134,6 @@ static void fill_stgmed_buffer(stgmed_buf_t *buf) buf->init = TRUE; } -static LRESULT WINAPI notif_wnd_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - if(msg == WM_MK_CONTINUE) { - Binding *binding = (Binding*)lParam; - task_header_t *task; - - while((task = pop_task(binding))) { - binding->continue_call++; - task->proc(binding, task); - binding->continue_call--; - } - - IBinding_Release(BINDING(binding)); - return 0; - } - - return DefWindowProcW(hwnd, msg, wParam, lParam); -} - -static HWND get_notif_hwnd(void) -{ - static ATOM wnd_class = 0; - HWND hwnd; - - static const WCHAR wszURLMonikerNotificationWindow[] = - {'U','R','L',' ','M','o','n','i','k','e','r',' ', - 'N','o','t','i','f','i','c','a','t','i','o','n',' ','W','i','n','d','o','w',0}; - - if(!wnd_class) { - static WNDCLASSEXW wndclass = { - sizeof(wndclass), 0, - notif_wnd_proc, 0, 0, - NULL, NULL, NULL, NULL, NULL, - wszURLMonikerNotificationWindow, - NULL - }; - - wndclass.hInstance = URLMON_hInstance; - - wnd_class = RegisterClassExW(&wndclass); - if (!wnd_class && GetLastError() == ERROR_CLASS_ALREADY_EXISTS) - wnd_class = 1; - } - - hwnd = CreateWindowExW(0, wszURLMonikerNotificationWindow, - wszURLMonikerNotificationWindow, 0, 0, 0, 0, 0, HWND_MESSAGE, - NULL, URLMON_hInstance, NULL); - - TRACE("hwnd = %p\n", hwnd); - - return hwnd; -} - static void dump_BINDINFO(BINDINFO *bi) { static const char * const BINDINFOF_str[] = { @@ -272,73 +178,17 @@ static void dump_BINDINFO(BINDINFO *bi) ); } -static void set_binding_mime(Binding *binding, LPCWSTR mime) -{ - EnterCriticalSection(&binding->section); - - if(binding->report_mime) { - heap_free(binding->mime); - binding->mime = heap_strdupW(mime); - } - - LeaveCriticalSection(&binding->section); -} - -static void handle_mime_available(Binding *binding, BOOL verify) +static void mime_available(Binding *This, LPCWSTR mime) { - BOOL report_mime; - - EnterCriticalSection(&binding->section); - report_mime = binding->report_mime; - binding->report_mime = FALSE; - LeaveCriticalSection(&binding->section); + heap_free(This->mime); + This->mime = heap_strdupW(mime); - if(!report_mime) + if(!This->mime || !This->report_mime) return; - if(verify) { - LPWSTR mime = NULL; - - fill_stgmed_buffer(binding->stgmed_buf); - FindMimeFromData(NULL, binding->url, binding->stgmed_buf->buf, - min(binding->stgmed_buf->size, 255), binding->mime, 0, &mime, 0); - - heap_free(binding->mime); - binding->mime = heap_strdupW(mime); - CoTaskMemFree(mime); - } - - IBindStatusCallback_OnProgress(binding->callback, 0, 0, BINDSTATUS_MIMETYPEAVAILABLE, binding->mime); - - binding->clipboard_format = RegisterClipboardFormatW(binding->mime); -} - -typedef struct { - task_header_t header; - BOOL verify; -} mime_available_task_t; - -static void mime_available_proc(Binding *binding, task_header_t *t) -{ - mime_available_task_t *task = (mime_available_task_t*)t; + IBindStatusCallback_OnProgress(This->callback, 0, 0, BINDSTATUS_MIMETYPEAVAILABLE, This->mime); - handle_mime_available(binding, task->verify); - - heap_free(task); -} - -static void mime_available(Binding *This, LPCWSTR mime, BOOL verify) -{ - if(mime) - set_binding_mime(This, mime); - - if(GetCurrentThreadId() == This->apartment_thread) { - handle_mime_available(This, verify); - }else { - mime_available_task_t *task = heap_alloc(sizeof(task_header_t)); - task->verify = verify; - push_task(This, &task->header, mime_available_proc); - } + This->clipboard_format = RegisterClipboardFormatW(This->mime); } static void stop_binding(Binding *binding, HRESULT hres, LPCWSTR str) @@ -957,8 +807,8 @@ static ULONG WINAPI Binding_Release(IBinding *iface) TRACE("(%p) ref=%d\n", This, ref); if(!ref) { - if (This->notif_hwnd) - DestroyWindow( This->notif_hwnd ); + if(This->notif_hwnd) + release_notif_hwnd(This->notif_hwnd); if(This->mon) IMoniker_Release(This->mon); if(This->callback) @@ -1087,92 +937,21 @@ static ULONG WINAPI InternetProtocolSink_Release(IInternetProtocolSink *iface) return IBinding_Release(BINDING(This)); } -typedef struct { - task_header_t header; - PROTOCOLDATA data; -} switch_task_t; - -static void switch_proc(Binding *binding, task_header_t *t) -{ - switch_task_t *task = (switch_task_t*)t; - - IInternetProtocol_Continue(binding->protocol, &task->data); - - heap_free(task); -} - static HRESULT WINAPI InternetProtocolSink_Switch(IInternetProtocolSink *iface, PROTOCOLDATA *pProtocolData) { Binding *This = PROTSINK_THIS(iface); - switch_task_t *task; - - TRACE("(%p)->(%p)\n", This, pProtocolData); - - task = heap_alloc(sizeof(switch_task_t)); - task->data = *pProtocolData; - - push_task(This, &task->header, switch_proc); - IBinding_AddRef(BINDING(This)); - PostMessageW(This->notif_hwnd, WM_MK_CONTINUE, 0, (LPARAM)This); + WARN("(%p)->(%p)\n", This, pProtocolData); - return S_OK; -} - -typedef struct { - task_header_t header; - - Binding *binding; - ULONG progress; - ULONG progress_max; - ULONG status_code; - LPWSTR status_text; -} on_progress_task_t; - -static void on_progress_proc(Binding *binding, task_header_t *t) -{ - on_progress_task_t *task = (on_progress_task_t*)t; - - IBindStatusCallback_OnProgress(binding->callback, task->progress, - task->progress_max, task->status_code, task->status_text); - - heap_free(task->status_text); - heap_free(task); + return E_FAIL; } static void on_progress(Binding *This, ULONG progress, ULONG progress_max, ULONG status_code, LPCWSTR status_text) { - on_progress_task_t *task; - - if(GetCurrentThreadId() == This->apartment_thread && !This->continue_call) { - IBindStatusCallback_OnProgress(This->callback, progress, progress_max, - status_code, status_text); - return; - } - - task = heap_alloc(sizeof(on_progress_task_t)); - - task->progress = progress; - task->progress_max = progress_max; - task->status_code = status_code; - - if(status_text) { - DWORD size = (strlenW(status_text)+1)*sizeof(WCHAR); - - task->status_text = heap_alloc(size); - memcpy(task->status_text, status_text, size); - }else { - task->status_text = NULL; - } - - push_task(This, &task->header, on_progress_proc); - - if(GetCurrentThreadId() != This->apartment_thread) { - IBinding_AddRef(BINDING(This)); - PostMessageW(This->notif_hwnd, WM_MK_CONTINUE, 0, (LPARAM)This); - } + IBindStatusCallback_OnProgress(This->callback, progress, progress_max, + status_code, status_text); } static HRESULT WINAPI InternetProtocolSink_ReportProgress(IInternetProtocolSink *iface, @@ -1192,22 +971,20 @@ static HRESULT WINAPI InternetProtocolSink_ReportProgress(IInternetProtocolSink case BINDSTATUS_BEGINDOWNLOADDATA: fill_stgmed_buffer(This->stgmed_buf); break; - case BINDSTATUS_MIMETYPEAVAILABLE: - set_binding_mime(This, szStatusText); - break; case BINDSTATUS_SENDINGREQUEST: on_progress(This, 0, 0, BINDSTATUS_SENDINGREQUEST, szStatusText); break; case BINDSTATUS_PROTOCOLCLASSID: break; + case BINDSTATUS_MIMETYPEAVAILABLE: case BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE: - mime_available(This, szStatusText, FALSE); + mime_available(This, szStatusText); break; case BINDSTATUS_CACHEFILENAMEAVAILABLE: heap_free(This->stgmed_buf->cache_file); This->stgmed_buf->cache_file = heap_strdupW(szStatusText); break; - case BINDSTATUS_DIRECTBIND: + case BINDSTATUS_DIRECTBIND: /* FIXME: Handle BINDSTATUS_DIRECTBIND in BindProtocol */ This->report_mime = FALSE; break; case BINDSTATUS_ACCEPTRANGES: @@ -1230,12 +1007,6 @@ static void report_data(Binding *This, DWORD bscf, ULONG progress, ULONG progres if(This->download_state == END_DOWNLOAD || (This->state & BINDING_STOPPED)) return; - if(GetCurrentThreadId() != This->apartment_thread) - FIXME("called from worker thread\n"); - - if(This->report_mime) - mime_available(This, NULL, TRUE); - if(This->download_state == BEFORE_DOWNLOAD) { fill_stgmed_buffer(This->stgmed_buf); @@ -1288,22 +1059,6 @@ static void report_data(Binding *This, DWORD bscf, ULONG progress, ULONG progres } } -typedef struct { - task_header_t header; - DWORD bscf; - ULONG progress; - ULONG progress_max; -} report_data_task_t; - -static void report_data_proc(Binding *binding, task_header_t *t) -{ - report_data_task_t *task = (report_data_task_t*)t; - - report_data(binding, task->bscf, task->progress, task->progress_max); - - heap_free(task); -} - static HRESULT WINAPI InternetProtocolSink_ReportData(IInternetProtocolSink *iface, DWORD grfBSCF, ULONG ulProgress, ULONG ulProgressMax) { @@ -1311,42 +1066,10 @@ static HRESULT WINAPI InternetProtocolSink_ReportData(IInternetProtocolSink *ifa TRACE("(%p)->(%d %u %u)\n", This, grfBSCF, ulProgress, ulProgressMax); - if(GetCurrentThreadId() != This->apartment_thread) - FIXME("called from worked hread\n"); - - if(This->continue_call) { - report_data_task_t *task = heap_alloc(sizeof(report_data_task_t)); - task->bscf = grfBSCF; - task->progress = ulProgress; - task->progress_max = ulProgressMax; - - push_task(This, &task->header, report_data_proc); - }else { - report_data(This, grfBSCF, ulProgress, ulProgressMax); - } - + report_data(This, grfBSCF, ulProgress, ulProgressMax); return S_OK; } -typedef struct { - task_header_t header; - - HRESULT hres; - LPWSTR str; -} report_result_task_t; - -static void report_result_proc(Binding *binding, task_header_t *t) -{ - report_result_task_t *task = (report_result_task_t*)t; - - IInternetProtocol_Terminate(binding->protocol, 0); - - stop_binding(binding, task->hres, task->str); - - heap_free(task->str); - heap_free(task); -} - static HRESULT WINAPI InternetProtocolSink_ReportResult(IInternetProtocolSink *iface, HRESULT hrResult, DWORD dwError, LPCWSTR szResult) { @@ -1354,18 +1077,8 @@ static HRESULT WINAPI InternetProtocolSink_ReportResult(IInternetProtocolSink *i TRACE("(%p)->(%08x %d %s)\n", This, hrResult, dwError, debugstr_w(szResult)); - if(GetCurrentThreadId() == This->apartment_thread && !This->continue_call) { - IInternetProtocol_Terminate(This->protocol, 0); - stop_binding(This, hrResult, szResult); - }else { - report_result_task_t *task = heap_alloc(sizeof(report_result_task_t)); - - task->hres = hrResult; - task->str = heap_strdupW(szResult); - - push_task(This, &task->header, report_result_proc); - } - + IInternetProtocol_Terminate(This->protocol, 0); + stop_binding(This, hrResult, szResult); return S_OK; } @@ -1639,7 +1352,6 @@ static HRESULT Binding_Create(IMoniker *mon, Binding *binding_ctx, LPCWSTR url, ret->to_object = to_obj; ret->iid = *riid; - ret->apartment_thread = GetCurrentThreadId(); ret->notif_hwnd = get_notif_hwnd(); ret->report_mime = !binding_ctx; ret->download_state = BEFORE_DOWNLOAD; @@ -1749,7 +1461,7 @@ static HRESULT start_binding(IMoniker *mon, Binding *binding_ctx, LPCWSTR url, I report_data(binding, 0, 0, 0); }else { hres = IInternetProtocol_Start(binding->protocol, url, PROTSINK(binding), - BINDINF(binding), 0, 0); + BINDINF(binding), PI_APARTMENTTHREADED|PI_MIMEVERIFICATION, 0); TRACE("start ret %08x\n", hres); diff --git a/dlls/urlmon/bindprot.c b/dlls/urlmon/bindprot.c index 1f245943b3b..7231ae6a476 100644 --- a/dlls/urlmon/bindprot.c +++ b/dlls/urlmon/bindprot.c @@ -21,7 +21,18 @@ WINE_DEFAULT_DEBUG_CHANNEL(urlmon); -typedef struct { +typedef struct BindProtocol BindProtocol; + +struct _task_header_t; + +typedef void (*task_proc_t)(BindProtocol*,struct _task_header_t*); + +typedef struct _task_header_t { + task_proc_t proc; + struct _task_header_t *next; +} task_header_t; + +struct BindProtocol { const IInternetProtocolVtbl *lpInternetProtocolVtbl; const IInternetBindInfoVtbl *lpInternetBindInfoVtbl; const IInternetPriorityVtbl *lpInternetPriorityVtbl; @@ -39,8 +50,22 @@ typedef struct { LONG priority; BOOL reported_result; + BOOL reported_mime; BOOL from_urlmon; -} BindProtocol; + DWORD pi; + + DWORD apartment_thread; + HWND notif_hwnd; + DWORD continue_call; + + CRITICAL_SECTION section; + task_header_t *task_queue_head, *task_queue_tail; + + BYTE *buf; + DWORD buf_size; + LPWSTR mime; + LPWSTR url; +}; #define PROTOCOL(x) ((IInternetProtocol*) &(x)->lpInternetProtocolVtbl) #define BINDINFO(x) ((IInternetBindInfo*) &(x)->lpInternetBindInfoVtbl) @@ -48,6 +73,148 @@ typedef struct { #define SERVPROV(x) ((IServiceProvider*) &(x)->lpServiceProviderVtbl) #define PROTSINK(x) ((IInternetProtocolSink*) &(x)->lpInternetProtocolSinkVtbl) +#define BUFFER_SIZE 2048 +#define MIME_TEST_SIZE 255 + +#define WM_MK_CONTINUE (WM_USER+101) +#define WM_MK_RELEASE (WM_USER+102) + +static LRESULT WINAPI notif_wnd_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch(msg) { + case WM_MK_CONTINUE: { + BindProtocol *This = (BindProtocol*)lParam; + task_header_t *task; + + while(1) { + EnterCriticalSection(&This->section); + + task = This->task_queue_head; + if(task) { + This->task_queue_head = task->next; + if(!This->task_queue_head) + This->task_queue_tail = NULL; + } + + LeaveCriticalSection(&This->section); + + if(!task) + break; + + This->continue_call++; + task->proc(This, task); + This->continue_call--; + } + + IInternetProtocol_Release(PROTOCOL(This)); + return 0; + } + case WM_MK_RELEASE: { + tls_data_t *data = get_tls_data(); + + if(!--data->notif_hwnd_cnt) { + DestroyWindow(hwnd); + data->notif_hwnd = NULL; + } + } + } + + return DefWindowProcW(hwnd, msg, wParam, lParam); +} + +HWND get_notif_hwnd(void) +{ + static ATOM wnd_class = 0; + tls_data_t *tls_data; + + static const WCHAR wszURLMonikerNotificationWindow[] = + {'U','R','L',' ','M','o','n','i','k','e','r',' ', + 'N','o','t','i','f','i','c','a','t','i','o','n',' ','W','i','n','d','o','w',0}; + + tls_data = get_tls_data(); + if(!tls_data) + return NULL; + + if(tls_data->notif_hwnd_cnt) { + tls_data->notif_hwnd_cnt++; + return tls_data->notif_hwnd; + } + + if(!wnd_class) { + static WNDCLASSEXW wndclass = { + sizeof(wndclass), 0, + notif_wnd_proc, 0, 0, + NULL, NULL, NULL, NULL, NULL, + wszURLMonikerNotificationWindow, + NULL + }; + + wndclass.hInstance = URLMON_hInstance; + + wnd_class = RegisterClassExW(&wndclass); + if (!wnd_class && GetLastError() == ERROR_CLASS_ALREADY_EXISTS) + wnd_class = 1; + } + + tls_data->notif_hwnd = CreateWindowExW(0, wszURLMonikerNotificationWindow, + wszURLMonikerNotificationWindow, 0, 0, 0, 0, 0, HWND_MESSAGE, + NULL, URLMON_hInstance, NULL); + if(tls_data->notif_hwnd) + tls_data->notif_hwnd_cnt++; + + TRACE("hwnd = %p\n", tls_data->notif_hwnd); + + return tls_data->notif_hwnd; +} + +void release_notif_hwnd(HWND hwnd) +{ + tls_data_t *data = get_tls_data(); + + if(!data) + return; + + if(data->notif_hwnd != hwnd) { + PostMessageW(data->notif_hwnd, WM_MK_RELEASE, 0, 0); + return; + } + + if(!--data->notif_hwnd_cnt) { + DestroyWindow(data->notif_hwnd); + data->notif_hwnd = NULL; + } +} + +static void push_task(BindProtocol *This, task_header_t *task, task_proc_t proc) +{ + BOOL do_post = FALSE; + + task->proc = proc; + task->next = NULL; + + EnterCriticalSection(&This->section); + + if(This->task_queue_tail) { + This->task_queue_tail->next = task; + This->task_queue_tail = task; + }else { + This->task_queue_tail = This->task_queue_head = task; + do_post = TRUE; + } + + LeaveCriticalSection(&This->section); + + if(do_post) { + IInternetProtocol_AddRef(PROTOCOL(This)); + PostMessageW(This->notif_hwnd, WM_MK_CONTINUE, 0, (LPARAM)This); + } +} + +static BOOL inline do_direct_notif(BindProtocol *This) +{ + return !(This->pi & PI_APARTMENTTHREADED) || (This->apartment_thread == GetCurrentThreadId() && !This->continue_call); +} + #define PROTOCOL_THIS(iface) DEFINE_THIS(BindProtocol, InternetProtocol, iface) static HRESULT WINAPI BindProtocol_QueryInterface(IInternetProtocol *iface, REFIID riid, void **ppv) @@ -113,6 +280,13 @@ static ULONG WINAPI BindProtocol_Release(IInternetProtocol *iface) IInternetBindInfo_Release(This->bind_info); set_binding_sink(PROTOCOL(This), NULL); + + if(This->notif_hwnd) + release_notif_hwnd(This->notif_hwnd); + DeleteCriticalSection(&This->section); + + heap_free(This->mime); + heap_free(This->url); heap_free(This); URLMON_UnlockModule(); @@ -140,6 +314,9 @@ static HRESULT WINAPI BindProtocol_Start(IInternetProtocol *iface, LPCWSTR szUrl if(!szUrl || !pOIProtSink || !pOIBindInfo) return E_INVALIDARG; + This->pi = grfPI; + This->url = heap_strdupW(szUrl); + hres = IInternetProtocolSink_QueryInterface(pOIProtSink, &IID_IServiceProvider, (void**)&service_provider); if(SUCCEEDED(hres)) { @@ -256,11 +433,30 @@ static HRESULT WINAPI BindProtocol_Read(IInternetProtocol *iface, void *pv, { BindProtocol *This = PROTOCOL_THIS(iface); ULONG read = 0; - HRESULT hres; + HRESULT hres = S_OK; TRACE("(%p)->(%p %u %p)\n", This, pv, cb, pcbRead); - hres = IInternetProtocol_Read(This->protocol, pv, cb, &read); + if(This->buf) { + read = min(cb, This->buf_size); + memcpy(pv, This->buf, read); + + if(read == This->buf_size) { + heap_free(This->buf); + This->buf = NULL; + }else { + memmove(This->buf, This->buf+cb, This->buf_size-cb); + } + + This->buf_size -= read; + } + + if(read < cb) { + ULONG cread = 0; + + hres = IInternetProtocol_Read(This->protocol, (BYTE*)pv+read, cb, &cread); + read += cread; + } *pcbRead = read; return hres; @@ -468,6 +664,20 @@ static ULONG WINAPI BPInternetProtocolSink_Release(IInternetProtocolSink *iface) return IInternetProtocol_Release(PROTOCOL(This)); } +typedef struct { + task_header_t header; + PROTOCOLDATA data; +} switch_task_t; + +static void switch_proc(BindProtocol *bind, task_header_t *t) +{ + switch_task_t *task = (switch_task_t*)t; + + IInternetProtocol_Continue(bind->protocol, &task->data); + + heap_free(task); +} + static HRESULT WINAPI BPInternetProtocolSink_Switch(IInternetProtocolSink *iface, PROTOCOLDATA *pProtocolData) { @@ -478,6 +688,19 @@ static HRESULT WINAPI BPInternetProtocolSink_Switch(IInternetProtocolSink *iface TRACE("flags %x state %x data %p cb %u\n", pProtocolData->grfFlags, pProtocolData->dwState, pProtocolData->pData, pProtocolData->cbData); + if(!do_direct_notif(This)) { + switch_task_t *task; + + task = heap_alloc(sizeof(switch_task_t)); + if(!task) + return E_OUTOFMEMORY; + + task->data = *pProtocolData; + + push_task(This, &task->header, switch_proc); + return S_OK; + } + if(!This->protocol_sink) { IInternetProtocol_Continue(This->protocol, pProtocolData); return S_OK; @@ -486,14 +709,9 @@ static HRESULT WINAPI BPInternetProtocolSink_Switch(IInternetProtocolSink *iface return IInternetProtocolSink_Switch(This->protocol_sink, pProtocolData); } -static HRESULT WINAPI BPInternetProtocolSink_ReportProgress(IInternetProtocolSink *iface, - ULONG ulStatusCode, LPCWSTR szStatusText) +static void report_progress(BindProtocol *This, ULONG status_code, LPCWSTR status_text) { - BindProtocol *This = PROTSINK_THIS(iface); - - TRACE("(%p)->(%u %s)\n", This, ulStatusCode, debugstr_w(szStatusText)); - - switch(ulStatusCode) { + switch(status_code) { case BINDSTATUS_FINDINGRESOURCE: case BINDSTATUS_CONNECTING: case BINDSTATUS_BEGINDOWNLOADDATA: @@ -501,23 +719,136 @@ static HRESULT WINAPI BPInternetProtocolSink_ReportProgress(IInternetProtocolSin case BINDSTATUS_CACHEFILENAMEAVAILABLE: case BINDSTATUS_DIRECTBIND: case BINDSTATUS_ACCEPTRANGES: + if(This->protocol_sink) + IInternetProtocolSink_ReportProgress(This->protocol_sink, status_code, status_text); + break; + case BINDSTATUS_MIMETYPEAVAILABLE: - if(!This->protocol_sink) - return S_OK; - return IInternetProtocolSink_ReportProgress(This->protocol_sink, - ulStatusCode, szStatusText); + if(!This->reported_mime) { + heap_free(This->mime); + This->mime = heap_strdupW(status_text); + } + + if(This->protocol_sink && !(This->pi & PI_MIMEVERIFICATION)) + IInternetProtocolSink_ReportProgress(This->protocol_sink, status_code, status_text); + break; case BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE: - if(!This->protocol_sink) - return S_OK; - return IInternetProtocolSink_ReportProgress(This->protocol_sink, - This->from_urlmon ? BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE : BINDSTATUS_MIMETYPEAVAILABLE, - szStatusText); + if(!This->reported_mime) { + heap_free(This->mime); + This->mime = heap_strdupW(status_text); + } + + if(This->protocol_sink) { + This->reported_mime = TRUE; + IInternetProtocolSink_ReportProgress(This->protocol_sink, BINDSTATUS_MIMETYPEAVAILABLE, status_text); + } + break; + default: - FIXME("unsupported ulStatusCode %u\n", ulStatusCode); + FIXME("unsupported ulStatusCode %u\n", status_code); } +} - return E_NOTIMPL; +typedef struct { + task_header_t header; + + ULONG status_code; + LPWSTR status_text; +} on_progress_task_t; + +static void on_progress_proc(BindProtocol *This, task_header_t *t) +{ + on_progress_task_t *task = (on_progress_task_t*)t; + + report_progress(This, task->status_code, task->status_text); + + heap_free(task->status_text); + heap_free(task); +} + +static HRESULT WINAPI BPInternetProtocolSink_ReportProgress(IInternetProtocolSink *iface, + ULONG ulStatusCode, LPCWSTR szStatusText) +{ + BindProtocol *This = PROTSINK_THIS(iface); + + TRACE("(%p)->(%u %s)\n", This, ulStatusCode, debugstr_w(szStatusText)); + + if(do_direct_notif(This)) { + report_progress(This, ulStatusCode, szStatusText); + }else { + on_progress_task_t *task; + + task = heap_alloc(sizeof(on_progress_task_t)); + + task->status_code = ulStatusCode; + task->status_text = heap_strdupW(szStatusText); + + push_task(This, &task->header, on_progress_proc); + } + + return S_OK; +} + +static HRESULT report_data(BindProtocol *This, DWORD bscf, ULONG progress, ULONG progress_max) +{ + if(!This->protocol_sink) + return S_OK; + + if((This->pi & PI_MIMEVERIFICATION) && !This->reported_mime) { + DWORD read = 0; + LPWSTR mime; + HRESULT hres; + + if(!This->buf) { + This->buf = heap_alloc(BUFFER_SIZE); + if(!This->buf) + return E_OUTOFMEMORY; + } + + do { + read = 0; + hres = IInternetProtocol_Read(This->protocol, This->buf+This->buf_size, BUFFER_SIZE-This->buf_size, &read); + if(hres != S_OK) + break; + This->buf_size += read; + }while(This->buf_size < MIME_TEST_SIZE); + if(FAILED(hres) && hres != E_PENDING) + return hres; + + This->buf_size += read; + if(This->buf_size < MIME_TEST_SIZE && hres != S_FALSE) + return S_OK; + + + hres = FindMimeFromData(NULL, This->url, This->buf, min(This->buf_size, MIME_TEST_SIZE), This->mime, 0, &mime, 0); + if(FAILED(hres)) + return hres; + + heap_free(This->mime); + This->mime = heap_strdupW(mime); + CoTaskMemFree(mime); + + This->reported_mime = TRUE; + IInternetProtocolSink_ReportProgress(This->protocol_sink, BINDSTATUS_MIMETYPEAVAILABLE, This->mime); + } + + return IInternetProtocolSink_ReportData(This->protocol_sink, bscf, progress, progress_max); +} + +typedef struct { + task_header_t header; + DWORD bscf; + ULONG progress; + ULONG progress_max; +} report_data_task_t; + +static void report_data_proc(BindProtocol *This, task_header_t *t) +{ + report_data_task_t *task = (report_data_task_t*)t; + + report_data(This, task->bscf, task->progress, task->progress_max); + heap_free(task); } static HRESULT WINAPI BPInternetProtocolSink_ReportData(IInternetProtocolSink *iface, @@ -530,7 +861,41 @@ static HRESULT WINAPI BPInternetProtocolSink_ReportData(IInternetProtocolSink *i if(!This->protocol_sink) return S_OK; - return IInternetProtocolSink_ReportData(This->protocol_sink, grfBSCF, ulProgress, ulProgressMax); + if(!do_direct_notif(This)) { + report_data_task_t *task; + + task = heap_alloc(sizeof(report_data_task_t)); + if(!task) + return E_OUTOFMEMORY; + + task->bscf = grfBSCF; + task->progress = ulProgress; + task->progress_max = ulProgressMax; + + push_task(This, &task->header, report_data_proc); + return S_OK; + } + + return report_data(This, grfBSCF, ulProgress, ulProgressMax); +} + +typedef struct { + task_header_t header; + + HRESULT hres; + DWORD err; + LPWSTR str; +} report_result_task_t; + +static void report_result_proc(BindProtocol *This, task_header_t *t) +{ + report_result_task_t *task = (report_result_task_t*)t; + + if(This->protocol_sink) + IInternetProtocolSink_ReportResult(This->protocol_sink, task->hres, task->err, task->str); + + heap_free(task->str); + heap_free(task); } static HRESULT WINAPI BPInternetProtocolSink_ReportResult(IInternetProtocolSink *iface, @@ -545,6 +910,21 @@ static HRESULT WINAPI BPInternetProtocolSink_ReportResult(IInternetProtocolSink This->reported_result = TRUE; + if(!do_direct_notif(This)) { + report_result_task_t *task; + + task = heap_alloc(sizeof(report_result_task_t)); + if(!task) + return E_OUTOFMEMORY; + + task->hres = hrResult; + task->err = dwError; + task->str = heap_strdupW(szResult); + + push_task(This, &task->header, report_result_proc); + return S_OK; + } + return IInternetProtocolSink_ReportResult(This->protocol_sink, hrResult, dwError, szResult); } @@ -615,6 +995,9 @@ HRESULT create_binding_protocol(LPCWSTR url, BOOL from_urlmon, IInternetProtocol ret->ref = 1; ret->from_urlmon = from_urlmon; + ret->apartment_thread = GetCurrentThreadId(); + ret->notif_hwnd = get_notif_hwnd(); + InitializeCriticalSection(&ret->section); URLMON_LockModule(); diff --git a/dlls/urlmon/tests/protocol.c b/dlls/urlmon/tests/protocol.c index a9732117319..725c3cc6d91 100644 --- a/dlls/urlmon/tests/protocol.c +++ b/dlls/urlmon/tests/protocol.c @@ -115,7 +115,7 @@ static IInternetProtocol *async_protocol = NULL; static BOOL first_data_notif = FALSE, http_is_first = FALSE, http_post_test = FALSE; static int state = 0, prot_state; -static DWORD bindf = 0, ex_priority = 0; +static DWORD bindf, ex_priority , pi; static IInternetProtocol *binding_protocol; static IInternetBindInfo *prot_bind_info; static IInternetProtocolSink *binding_sink; @@ -125,6 +125,7 @@ static BOOL binding_test; static PROTOCOLDATA protocoldata, *pdata; static DWORD prot_read; static BOOL security_problem = FALSE; +static BOOL async_read_pending; static enum { FILE_TEST, @@ -1088,7 +1089,7 @@ static HRESULT WINAPI Protocol_Start(IInternetProtocol *iface, LPCWSTR szUrl, static HRESULT WINAPI Protocol_Continue(IInternetProtocol *iface, PROTOCOLDATA *pProtocolData) { - DWORD bscf = 0; + DWORD bscf = 0, pr; HRESULT hres; CHECK_EXPECT(Continue); @@ -1121,10 +1122,12 @@ static HRESULT WINAPI Protocol_Continue(IInternetProtocol *iface, IHttpNegotiate_Release(http_negotiate); ok(hres == S_OK, "OnResponse failed: %08x\n", hres); - SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE); + if(!(pi & PI_MIMEVERIFICATION)) + SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE); hres = IInternetProtocolSink_ReportProgress(binding_sink, BINDSTATUS_MIMETYPEAVAILABLE, text_htmlW); - CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE); + if(!(pi & PI_MIMEVERIFICATION)) + CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE); ok(hres == S_OK, "ReportProgress(BINDSTATUS_MIMETYPEAVAILABLE) failed: %08x\n", hres); @@ -1137,11 +1140,32 @@ static HRESULT WINAPI Protocol_Continue(IInternetProtocol *iface, break; } - SET_EXPECT(ReportData); + pr = prot_read; + if(pi & PI_MIMEVERIFICATION) { + if(pr < 200) + SET_EXPECT(Read); + if(pr == 200) { + SET_EXPECT(Read); + SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE); + } + } + if(!(pi & PI_MIMEVERIFICATION) || pr >= 200) + SET_EXPECT(ReportData); + hres = IInternetProtocolSink_ReportData(binding_sink, bscf, 100, 400); - CHECK_CALLED(ReportData); ok(hres == S_OK, "ReportData failed: %08x\n", hres); + if(pi & PI_MIMEVERIFICATION) { + if(pr < 200) + CHECK_CALLED(Read); + if(pr == 200) { + CLEAR_CALLED(Read); + CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE); + } + } + if(!(pi & PI_MIMEVERIFICATION) || pr >= 200) + CHECK_CALLED(ReportData); + if(prot_state == 3) prot_state = 4; @@ -1177,14 +1201,26 @@ static HRESULT WINAPI Protocol_Resume(IInternetProtocol *iface) static HRESULT WINAPI Protocol_Read(IInternetProtocol *iface, void *pv, ULONG cb, ULONG *pcbRead) { - static BOOL b = TRUE; + if(pi & PI_MIMEVERIFICATION) { + CHECK_EXPECT2(Read); - CHECK_EXPECT(Read); + if(prot_read < 300) { + ok(pv != expect_pv, "pv == expect_pv\n"); + if(prot_read < 300) + ok(cb == 2048-prot_read, "cb=%d\n", cb); + else + ok(cb == 700, "cb=%d\n", cb); + }else { + ok(expect_pv <= pv && (BYTE*)pv < (BYTE*)expect_pv + cb, "pv != expect_pv\n"); + } + }else { + CHECK_EXPECT(Read); - ok(pv == expect_pv, "pv != expect_pv\n"); - ok(cb == 1000, "cb=%d\n", cb); + ok(pv == expect_pv, "pv != expect_pv\n"); + ok(cb == 1000, "cb=%d\n", cb); + ok(!*pcbRead, "*pcbRead = %d\n", *pcbRead); + } ok(pcbRead != NULL, "pcbRead == NULL\n"); - ok(!*pcbRead, "*pcbRead = %d\n", *pcbRead); if(prot_state == 3) { HRESULT hres; @@ -1196,8 +1232,10 @@ static HRESULT WINAPI Protocol_Read(IInternetProtocol *iface, void *pv, return S_FALSE; } - if((b = !b)) + if((async_read_pending = !async_read_pending)) { + *pcbRead = 0; return tested_protocol == HTTP_TEST || tested_protocol == HTTPS_TEST ? E_PENDING : S_FALSE; + } memset(pv, 'x', 100); prot_read += *pcbRead = 100; @@ -1287,6 +1325,16 @@ static const IClassFactoryVtbl ClassFactoryVtbl = { static IClassFactory ClassFactory = { &ClassFactoryVtbl }; +static void init_test(int prot, BOOL is_binding) +{ + tested_protocol = prot; + binding_test = is_binding; + first_data_notif = TRUE; + prot_read = 0; + prot_state = 0; + async_read_pending = TRUE; +} + static void test_priority(IInternetProtocol *protocol) { IInternetPriority *priority; @@ -1540,7 +1588,7 @@ static void test_file_protocol(void) { static const char html_doc[] = ""; trace("Testing file protocol...\n"); - tested_protocol = FILE_TEST; + init_test(FILE_TEST, FALSE); SetLastError(0xdeadbeef); file = CreateFileW(wszIndexHtml, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, @@ -1849,7 +1897,7 @@ static void test_https_protocol(void) '.','c','o','m','/','t','e','s','t','.','h','t','m','l',0}; trace("Testing https protocol (from urlmon)...\n"); - tested_protocol = HTTPS_TEST; + init_test(HTTPS_TEST, FALSE); bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON | BINDF_NOWRITECACHE; test_http_protocol_url(codeweavers_url, TRUE, TRUE); } @@ -1986,7 +2034,7 @@ static void test_mk_protocol(void) static const WCHAR wrong_url2[] = {'m','k',':','/','t','e','s','t','.','h','t','m','l',0}; trace("Testing mk protocol...\n"); - tested_protocol = MK_TEST; + init_test(MK_TEST, FALSE); hres = CoGetClassObject(&CLSID_MkProtocol, CLSCTX_INPROC_SERVER, NULL, &IID_IUnknown, (void**)&unk); @@ -2059,8 +2107,7 @@ static void test_CreateBinding(void) static const WCHAR wsz_test[] = {'t','e','s','t',0}; trace("Testing CreateBinding...\n"); - tested_protocol = BIND_TEST; - binding_test = TRUE; + init_test(BIND_TEST, TRUE); hres = CoInternetGetSession(0, &session, 0); ok(hres == S_OK, "CoInternetGetSession failed: %08x\n", hres); @@ -2168,19 +2215,16 @@ static void test_CreateBinding(void) IInternetSession_Release(session); } -static void test_binding(int prot) +static void test_binding(int prot, DWORD grf_pi) { IInternetProtocol *protocol; IInternetSession *session; ULONG ref; HRESULT hres; - trace("Testing %s binding...\n", debugstr_w(protocol_names[prot])); - - tested_protocol = prot; - binding_test = TRUE; - first_data_notif = TRUE; - prot_read = 0; + trace("Testing %s binding (grfPI %x)...\n", debugstr_w(protocol_names[prot]), grf_pi); + init_test(prot, TRUE); + pi = grf_pi; hres = CoInternetGetSession(0, &session, 0); ok(hres == S_OK, "CoInternetGetSession failed: %08x\n", hres); @@ -2208,7 +2252,7 @@ static void test_binding(int prot) SET_EXPECT(Start); expect_hrResult = S_OK; - hres = IInternetProtocol_Start(protocol, binding_urls[prot], &protocol_sink, &bind_info, 0, 0); + hres = IInternetProtocol_Start(protocol, binding_urls[prot], &protocol_sink, &bind_info, pi, 0); ok(hres == S_OK, "Start failed: %08x\n", hres); CHECK_CALLED(QueryService_InternetProtocol); @@ -2264,8 +2308,10 @@ START_TEST(protocol) test_gopher_protocol(); test_mk_protocol(); test_CreateBinding(); - test_binding(FILE_TEST); - test_binding(HTTP_TEST); + test_binding(FILE_TEST, 0); + test_binding(HTTP_TEST, 0); + test_binding(FILE_TEST, PI_MIMEVERIFICATION); + test_binding(HTTP_TEST, PI_MIMEVERIFICATION); CloseHandle(event_complete); CloseHandle(event_complete2); diff --git a/dlls/urlmon/tests/url.c b/dlls/urlmon/tests/url.c index 6d3832edf60..7b9c89fdebf 100644 --- a/dlls/urlmon/tests/url.c +++ b/dlls/urlmon/tests/url.c @@ -324,6 +324,28 @@ static ULONG WINAPI Protocol_Release(IInternetProtocol *iface) return 1; } +static void test_switch_fail(void) +{ + IInternetProtocolSink *binding_sink; + PROTOCOLDATA protocoldata; + HRESULT hres; + + static BOOL tested_switch_fail; + + if(tested_switch_fail) + return; + + tested_switch_fail = TRUE; + + hres = IBinding_QueryInterface(current_binding, &IID_IInternetProtocolSink, (void**)&binding_sink); + ok(hres == S_OK, "Could not get IInternetProtocolSink iface: %08x\n", hres); + if(SUCCEEDED(hres)) { + hres = IInternetProtocolSink_Switch(binding_sink, &protocoldata); + ok(hres == E_FAIL, "Switch failed: %08x, expected E_FAIL\n", hres); + IInternetProtocolSink_Release(binding_sink); + } +} + static DWORD WINAPI thread_proc(PVOID arg) { PROTOCOLDATA protocoldata; @@ -368,6 +390,8 @@ static DWORD WINAPI thread_proc(PVOID arg) else CHECK_CALLED(OnProgress_SENDINGREQUEST); + test_switch_fail(); + SET_EXPECT(Continue); prot_state = 1; hres = IInternetProtocolSink_Switch(protocol_sink, &protocoldata); diff --git a/dlls/urlmon/urlmon_main.c b/dlls/urlmon/urlmon_main.c index 8561937643a..3203753f923 100644 --- a/dlls/urlmon/urlmon_main.c +++ b/dlls/urlmon/urlmon_main.c @@ -36,9 +36,88 @@ LONG URLMON_refCount = 0; HINSTANCE URLMON_hInstance = 0; static HMODULE hCabinet = NULL; +static DWORD urlmon_tls; static void init_session(BOOL); +static struct list tls_list = LIST_INIT(tls_list); + +static CRITICAL_SECTION tls_cs; +static CRITICAL_SECTION_DEBUG tls_cs_dbg = +{ + 0, 0, &tls_cs, + { &tls_cs_dbg.ProcessLocksList, &tls_cs_dbg.ProcessLocksList }, + 0, 0, { (DWORD_PTR)(__FILE__ ": tls") } +}; + +static CRITICAL_SECTION tls_cs = { &tls_cs_dbg, -1, 0, 0, 0, 0 }; + +tls_data_t *get_tls_data(void) +{ + tls_data_t *data; + + if(!urlmon_tls) { + DWORD tls = TlsAlloc(); + tls = InterlockedCompareExchange((LONG*)&urlmon_tls, tls, 0); + if(tls != urlmon_tls) + TlsFree(tls); + } + + data = TlsGetValue(urlmon_tls); + if(!data) { + data = heap_alloc_zero(sizeof(tls_data_t)); + if(!data) + return NULL; + + EnterCriticalSection(&tls_cs); + list_add_tail(&tls_list, &data->entry); + LeaveCriticalSection(&tls_cs); + + TlsSetValue(urlmon_tls, data); + } + + return data; +} + +static void free_tls_list(void) +{ + tls_data_t *data; + + if(!urlmon_tls) + return; + + while(!list_empty(&tls_list)) { + data = LIST_ENTRY(list_head(&tls_list), tls_data_t, entry); + list_remove(&data->entry); + heap_free(data); + } + + TlsFree(urlmon_tls); +} + +static void detach_thread(void) +{ + tls_data_t *data; + + if(!urlmon_tls) + return; + + data = TlsGetValue(urlmon_tls); + if(!data) + return; + + EnterCriticalSection(&tls_cs); + list_remove(&data->entry); + LeaveCriticalSection(&tls_cs); + + if(data->notif_hwnd) { + WARN("notif_hwnd not destroyed\n"); + DestroyWindow(data->notif_hwnd); + } + + heap_free(data); +} + /*********************************************************************** * DllMain (URLMON.init) */ @@ -48,7 +127,6 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID fImpLoad) switch(fdwReason) { case DLL_PROCESS_ATTACH: - DisableThreadLibraryCalls(hinstDLL); URLMON_hInstance = hinstDLL; init_session(TRUE); break; @@ -58,8 +136,13 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID fImpLoad) FreeLibrary(hCabinet); hCabinet = NULL; init_session(FALSE); + free_tls_list(); URLMON_hInstance = 0; break; + + case DLL_THREAD_DETACH: + detach_thread(); + break; } return TRUE; } diff --git a/dlls/urlmon/urlmon_main.h b/dlls/urlmon/urlmon_main.h index 1ee2eec313e..c3f944854ad 100644 --- a/dlls/urlmon/urlmon_main.h +++ b/dlls/urlmon/urlmon_main.h @@ -34,6 +34,7 @@ #include "wininet.h" #include "wine/unicode.h" +#include "wine/list.h" extern HINSTANCE URLMON_hInstance; extern HRESULT SecManagerImpl_Construct(IUnknown *pUnkOuter, LPVOID *ppobj); @@ -106,6 +107,18 @@ HRESULT protocol_lock_request(Protocol*); HRESULT protocol_unlock_request(Protocol*); void protocol_close_connection(Protocol*); +typedef struct { + HWND notif_hwnd; + DWORD notif_hwnd_cnt; + + struct list entry; +} tls_data_t; + +tls_data_t *get_tls_data(void); + +HWND get_notif_hwnd(void); +void release_notif_hwnd(HWND); + static inline void *heap_alloc(size_t len) { return HeapAlloc(GetProcessHeap(), 0, len); diff --git a/dlls/user32/tests/msg.c b/dlls/user32/tests/msg.c index 2445f82b5c7..1db5146d85b 100644 --- a/dlls/user32/tests/msg.c +++ b/dlls/user32/tests/msg.c @@ -1557,6 +1557,8 @@ static const struct message WmEnableWindowSeq_1[] = { { WM_CANCELMODE, sent|wparam|lparam, 0, 0 }, { EVENT_OBJECT_STATECHANGE, winevent_hook|wparam|lparam, 0, 0 }, + { HCBT_SETFOCUS, hook|optional }, + { WM_KILLFOCUS, sent|optional }, { WM_ENABLE, sent|wparam|lparam, FALSE, 0 }, { 0 } }; @@ -1759,6 +1761,16 @@ static const char *get_winpos_flags(UINT flags) #undef DUMP } +static BOOL ignore_message( UINT message ) +{ + /* these are always ignored */ + return (message >= 0xc000 || + message == WM_GETICON || + message == WM_GETOBJECT || + message == WM_TIMECHANGE || + message == WM_DEVICECHANGE); +} + #define add_message(msg) add_message_(__LINE__,msg); static void add_message_(int line, const struct recvd_message *msg) @@ -1863,6 +1875,8 @@ static void add_message_(int line, const struct recvd_message *msg) sprintf( seq->output, "%s: %p %04x wp %08lx lp %08lx", msg->descr, msg->hwnd, msg->message, msg->wParam, msg->lParam ); } + if (msg->flags & (sent|posted|parent|defwinproc|beginpaint)) + sprintf( seq->output + strlen(seq->output), " (flags %x)", msg->flags ); } } @@ -3202,9 +3216,7 @@ static LRESULT WINAPI mdi_client_hook_proc(HWND hwnd, UINT message, WPARAM wPara message != WM_NCHITTEST && message != WM_GETTEXT && message != WM_MDIGETACTIVE && - message != WM_GETICON && - message != WM_GETOBJECT && - message != WM_DEVICECHANGE) + !ignore_message( message )) { msg.hwnd = hwnd; msg.message = message; @@ -3231,9 +3243,7 @@ static LRESULT WINAPI mdi_child_wnd_proc(HWND hwnd, UINT message, WPARAM wParam, message != WM_ERASEBKGND && message != WM_NCHITTEST && message != WM_GETTEXT && - message != WM_GETICON && - message != WM_GETOBJECT && - message != WM_DEVICECHANGE) + !ignore_message( message )) { switch (message) { @@ -3281,9 +3291,7 @@ static LRESULT WINAPI mdi_frame_wnd_proc(HWND hwnd, UINT message, WPARAM wParam, message != WM_ERASEBKGND && message != WM_NCHITTEST && message != WM_GETTEXT && - message != WM_GETICON && - message != WM_GETOBJECT && - message != WM_DEVICECHANGE) + !ignore_message( message )) { msg.hwnd = hwnd; msg.message = message; @@ -3898,16 +3906,15 @@ static INT_PTR CALLBACK TestModalDlgProcA(HWND hwnd, UINT message, WPARAM wParam { struct recvd_message msg; + if (ignore_message( message )) return 0; + switch (message) { /* ignore */ - case WM_GETICON: - case WM_GETOBJECT: case WM_MOUSEMOVE: case WM_NCMOUSEMOVE: case WM_NCMOUSELEAVE: case WM_SETCURSOR: - case WM_DEVICECHANGE: return 0; case WM_NCHITTEST: return HTCLIENT; @@ -5157,11 +5164,10 @@ static LRESULT CALLBACK button_hook_proc(HWND hwnd, UINT message, WPARAM wParam, LRESULT ret; struct recvd_message msg; + if (ignore_message( message )) return 0; + switch (message) { - case WM_GETICON: - case WM_GETOBJECT: - return 0; /* ignore them */ case WM_SYNCPAINT: break; case BM_SETSTATE: @@ -5318,7 +5324,7 @@ static LRESULT CALLBACK static_hook_proc(HWND hwnd, UINT message, WPARAM wParam, LRESULT ret; struct recvd_message msg; - if (message == WM_GETICON || message == WM_GETOBJECT) return 0; /* ignore them */ + if (ignore_message( message )) return 0; msg.hwnd = hwnd; msg.message = message; @@ -5420,9 +5426,7 @@ static LRESULT CALLBACK combobox_hook_proc(HWND hwnd, UINT message, WPARAM wPara message != WM_ERASEBKGND && message != WM_NCHITTEST && message != WM_GETTEXT && - message != WM_GETICON && - message != WM_GETOBJECT && - message != WM_DEVICECHANGE) + !ignore_message( message )) { msg.hwnd = hwnd; msg.message = message; @@ -6657,10 +6661,8 @@ static void pump_msg_loop(HWND hwnd, HACCEL hAccel) /* ignore some unwanted messages */ if (msg.message == WM_MOUSEMOVE || - msg.message == WM_GETICON || - msg.message == WM_GETOBJECT || msg.message == WM_TIMER || - msg.message == WM_DEVICECHANGE) + ignore_message( msg.message )) continue; log_msg.hwnd = msg.hwnd; @@ -6902,8 +6904,7 @@ static LRESULT MsgCheckProc (BOOL unicode, HWND hwnd, UINT message, LRESULT ret; struct recvd_message msg; - /* ignore registered messages */ - if (message >= 0xc000) return 0; + if (ignore_message( message )) return 0; switch (message) { @@ -6966,9 +6967,6 @@ static LRESULT MsgCheckProc (BOOL unicode, HWND hwnd, UINT message, case WM_MOUSEACTIVATE: case WM_NCMOUSEMOVE: case WM_SETCURSOR: - case WM_GETICON: - case WM_GETOBJECT: - case WM_DEVICECHANGE: case WM_IME_SELECT: return 0; } @@ -7038,11 +7036,10 @@ static LRESULT WINAPI PopupMsgCheckProcA(HWND hwnd, UINT message, WPARAM wParam, LRESULT ret; struct recvd_message msg; + if (ignore_message( message )) return 0; + switch (message) { - case WM_GETICON: - case WM_GETOBJECT: - return 0; /* ignore them */ case WM_QUERYENDSESSION: case WM_ENDSESSION: lParam &= ~0x01; /* Vista adds a 0x01 flag */ @@ -7078,10 +7075,7 @@ static LRESULT WINAPI ParentMsgCheckProcA(HWND hwnd, UINT message, WPARAM wParam LRESULT ret; struct recvd_message msg; - if (message == WM_GETICON || message == WM_GETOBJECT) return 0; /* ignore them */ - - /* ignore registered messages */ - if (message >= 0xc000) return 0; + if (ignore_message( message )) return 0; if (log_all_parent_messages || message == WM_PARENTNOTIFY || message == WM_CANCELMODE || @@ -7145,7 +7139,7 @@ static LRESULT WINAPI TestDlgProcA(HWND hwnd, UINT message, WPARAM wParam, LPARA LRESULT ret; struct recvd_message msg; - if (message == WM_GETICON || message == WM_GETOBJECT) return 0; /* ignore them */ + if (ignore_message( message )) return 0; if (test_def_id) { @@ -8254,6 +8248,7 @@ static const struct message ScrollWindowPaint1[] = { { WM_GETTEXT, sent|beginpaint|optional }, { WM_GETTEXT, sent|beginpaint|optional }, { WM_GETTEXT, sent|beginpaint|optional }, + { WM_GETTEXT, sent|beginpaint|defwinproc|optional }, { WM_ERASEBKGND, sent|beginpaint|optional }, { 0 } }; @@ -8773,7 +8768,7 @@ static LRESULT CALLBACK edit_hook_proc(HWND hwnd, UINT message, WPARAM wParam, L LRESULT ret; struct recvd_message msg; - if (message == WM_GETICON || message == WM_GETOBJECT) return 0; /* ignore them */ + if (ignore_message( message )) return 0; msg.hwnd = hwnd; msg.message = message; @@ -10271,12 +10266,7 @@ static INT_PTR WINAPI test_dlg_proc(HWND hwnd, UINT message, WPARAM wParam, LPAR { struct recvd_message msg; - switch (message) - { - case WM_GETICON: - case WM_GETOBJECT: - return 0; /* ignore them */ - } + if (ignore_message( message )) return 0; msg.hwnd = hwnd; msg.message = message; @@ -11020,14 +11010,18 @@ static const struct message wm_lb_click_0[] = static const struct message wm_lb_deletestring[] = { { LB_DELETESTRING, sent|wparam|lparam, 0, 0 }, - { WM_DELETEITEM, sent|wparam|parent, ID_LISTBOX, 0 }, + { WM_DELETEITEM, sent|wparam|parent|optional, ID_LISTBOX, 0 }, + { WM_DRAWITEM, sent|wparam|parent|optional, ID_LISTBOX }, + { WM_DRAWITEM, sent|wparam|parent|optional, ID_LISTBOX }, { 0 } }; static const struct message wm_lb_deletestring_reset[] = { { LB_DELETESTRING, sent|wparam|lparam, 0, 0 }, - { LB_RESETCONTENT, sent|wparam|lparam|defwinproc, 0, 0 }, - { WM_DELETEITEM, sent|wparam|parent, ID_LISTBOX, 0 }, + { LB_RESETCONTENT, sent|wparam|lparam|defwinproc|optional, 0, 0 }, + { WM_DELETEITEM, sent|wparam|parent|optional, ID_LISTBOX, 0 }, + { WM_DRAWITEM, sent|wparam|parent|optional, ID_LISTBOX }, + { WM_DRAWITEM, sent|wparam|parent|optional, ID_LISTBOX }, { 0 } }; @@ -11048,9 +11042,7 @@ static LRESULT WINAPI listbox_hook_proc(HWND hwnd, UINT message, WPARAM wp, LPAR message != WM_ERASEBKGND && message != WM_NCHITTEST && message != WM_GETTEXT && - message != WM_GETOBJECT && - message != WM_GETICON && - message != WM_DEVICECHANGE) + !ignore_message( message )) { msg.hwnd = hwnd; msg.message = message; diff --git a/dlls/user32/tests/scroll.c b/dlls/user32/tests/scroll.c index 55fb6f64ac4..03725b92f48 100644 --- a/dlls/user32/tests/scroll.c +++ b/dlls/user32/tests/scroll.c @@ -222,25 +222,27 @@ static void scrollbar_test_default( DWORD style) ret = GetScrollRange( hwnd, SB_VERT, &min, &max); ok( ret || - broken( !ret) /* Win 98/ME */ , "GetScrollRange failed.\n"); + broken( !ret) /* Win 9x/ME */ , "GetScrollRange failed.\n"); /* range is 0,0 if there are no H or V scroll bars. 0,100 otherwise */ if( !( style & ( WS_VSCROLL | WS_HSCROLL))) ok( min == 0 && max == 0, "Scroll bar range is %d,%d. Expected 0,0. Style %08x\n", min, max, style); else todo_wine - ok( min == 0 && max == 100, + ok(( min == 0 && max == 100) || + broken( min == 0 && max == 0), /* Win 9x/ME */ "Scroll bar range is %d,%d. Expected 0,100. Style %08x\n", min, max, style); ret = GetScrollRange( hwnd, SB_HORZ, &min, &max); ok( ret || - broken( !ret) /* Win 98/ME */ , "GetScrollRange failed.\n"); + broken( !ret) /* Win 9x/ME */ , "GetScrollRange failed.\n"); /* range is 0,0 if there are no H or V scroll bars. 0,100 otherwise */ if( !( style & ( WS_VSCROLL | WS_HSCROLL))) ok( min == 0 && max == 0, "Scroll bar range is %d,%d. Expected 0,0. Style %08x\n", min, max, style); else todo_wine - ok( min == 0 && max == 100, + ok(( min == 0 && max == 100) || + broken( min == 0 && max == 0), /* Win 9x/ME */ "Scroll bar range is %d,%d. Expected 0,100. Style %08x\n", min, max, style); /* test GetScrollInfo, vist for vertical SB */ ret = GetScrollInfo( hwnd, SB_VERT, &si); @@ -249,7 +251,9 @@ todo_wine ok( !ret, "GetScrollInfo succeeded unexpectedly. Style is %08x\n", style); else todo_wine - ok( ret, "GetScrollInfo failed unexpectedly. Style is %08x\n", style); + ok( ret || + broken( !ret), /* Win 9x/ME */ + "GetScrollInfo failed unexpectedly. Style is %08x\n", style); /* Same for Horizontal SB */ ret = GetScrollInfo( hwnd, SB_HORZ, &si); /* should fail if no H orV scroll bar styles are present. Succeed otherwise */ @@ -257,7 +261,9 @@ todo_wine ok( !ret, "GetScrollInfo succeeded unexpectedly. Style is %08x\n", style); else todo_wine - ok( ret, "GetScrollInfo failed unexpectedly. Style is %08x\n", style); + ok( ret || + broken( !ret), /* Win 9x/ME */ + "GetScrollInfo failed unexpectedly. Style is %08x\n", style); /* now set the Vertical Scroll range to something that could be the default value it * already has */; ret = SetScrollRange( hwnd, SB_VERT, 0, 100, FALSE); @@ -276,7 +282,7 @@ todo_wine /* should succeed in ALL cases */ ok( ret, "GetScrollInfo failed unexpectedly. Style is %08x\n", style); /* report the windows style */ - winstyle = GetWindowLongW( hwnd, GWL_STYLE ); + winstyle = GetWindowLongA( hwnd, GWL_STYLE ); /* WS_VSCROLL added to the window style */ if( !(style & WS_VSCROLL)) { @@ -286,7 +292,8 @@ todo_wine "unexpected style change %8lx expected %8lx\n", (winstyle & (WS_HSCROLL|WS_VSCROLL)), style | WS_VSCROLL); else - ok( (winstyle & (WS_HSCROLL|WS_VSCROLL)) == style, + ok( (winstyle & (WS_HSCROLL|WS_VSCROLL)) == style || + broken((winstyle & (WS_HSCROLL|WS_VSCROLL)) == (WS_HSCROLL|WS_VSCROLL)), /* Win 9x/ME */ "unexpected style change %8lx expected %8x\n", (winstyle & (WS_HSCROLL|WS_VSCROLL)), style); } @@ -314,7 +321,7 @@ todo_wine /* should succeed in ALL cases */ ok( ret, "GetScrollInfo failed unexpectedly. Style is %08x\n", style); /* report the windows style */ - winstyle = GetWindowLongW( hwnd, GWL_STYLE ); + winstyle = GetWindowLongA( hwnd, GWL_STYLE ); /* WS_HSCROLL added to the window style */ if( !(style & WS_HSCROLL)) { @@ -324,7 +331,8 @@ todo_wine "unexpected style change %8lx expected %8lx\n", (winstyle & (WS_HSCROLL|WS_VSCROLL)), style | WS_HSCROLL); else - ok( (winstyle & (WS_HSCROLL|WS_VSCROLL)) == style, + ok( (winstyle & (WS_HSCROLL|WS_VSCROLL)) == style || + broken((winstyle & (WS_HSCROLL|WS_VSCROLL)) == (WS_HSCROLL|WS_VSCROLL)), /* Win 9x/ME */ "unexpected style change %8lx expected %8x\n", (winstyle & (WS_HSCROLL|WS_VSCROLL)), style); } @@ -372,7 +380,7 @@ todo_wine /* should fail */ ok( !ret, "GetScrollInfo succeeded unexpectedly. Style is %08x\n", style); /* add scroll styles */ - winstyle = GetWindowLongW( hwnd, GWL_STYLE ); + winstyle = GetWindowLongA( hwnd, GWL_STYLE ); SetWindowLongW( hwnd, GWL_STYLE, winstyle | WS_VSCROLL | WS_HSCROLL); ret = GetScrollInfo( hwnd, SB_VERT, &si); /* should still fail */ diff --git a/dlls/user32/tests/win.c b/dlls/user32/tests/win.c index 1f0420e1460..13e5d67e4c1 100644 --- a/dlls/user32/tests/win.c +++ b/dlls/user32/tests/win.c @@ -118,6 +118,16 @@ static void check_parents( HWND hwnd, HWND ga_parent, HWND gwl_parent, HWND get_ } } +static BOOL ignore_message( UINT message ) +{ + /* these are always ignored */ + return (message >= 0xc000 || + message == WM_GETICON || + message == WM_GETOBJECT || + message == WM_TIMECHANGE || + message == WM_DEVICECHANGE); +} + static BOOL CALLBACK EnumChildProc( HWND hwndChild, LPARAM lParam) { (*(LPINT)lParam)++; @@ -2713,7 +2723,7 @@ static BOOL wait_for_message( MSG *msg ) if (ret) { if (msg->message == WM_PAINT) DispatchMessage(msg); - else if (msg->message < 0xc000) break; /* skip registered messages */ + else if (!ignore_message(msg->message)) break; } else if (MsgWaitForMultipleObjects( 0, NULL, FALSE, 100, QS_ALLINPUT ) == WAIT_TIMEOUT) break; } diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c index 2f8a989fead..c9e1ed89bf9 100644 --- a/dlls/wined3d/arb_program_shader.c +++ b/dlls/wined3d/arb_program_shader.c @@ -41,6 +41,8 @@ WINE_DECLARE_DEBUG_CHANNEL(d3d); #define GLINFO_LOCATION (*gl_info) +/* GL locking for state handlers is done by the caller. */ + /* We have to subtract any other PARAMs that we might use in our shader programs. * ATI seems to count 2 implicit PARAMs when we use fog and NVIDIA counts 1, * and we reference one row of the PROJECTION matrix which counts as 1 PARAM. */ @@ -78,6 +80,7 @@ struct shader_arb_priv { * @target_type should be either GL_VERTEX_PROGRAM_ARB (for vertex shaders) * or GL_FRAGMENT_PROGRAM_ARB (for pixel shaders) */ +/* GL locking is done by the caller */ static unsigned int shader_arb_load_constantsF(IWineD3DBaseShaderImpl* This, const WineD3D_GL_Info *gl_info, GLuint target_type, unsigned int max_constants, const float *constants, char *dirty_consts) { @@ -189,6 +192,7 @@ static void shader_arb_load_np2fixup_constants( * We only support float constants in ARB at the moment, so don't * worry about the Integers or Booleans */ +/* GL locking is done by the caller (state handler) */ static void shader_arb_load_constants( IWineD3DDevice* device, char usePixelShader, @@ -316,15 +320,11 @@ static void shader_generate_arb_declarations(IWineD3DBaseShader *iface, const sh shader_addline(buffer, "ADDRESS A%d;\n", i); } - for(i = 0; i < This->baseShader.limits.texcoord; i++) { - if (reg_maps->texcoord[i]) - shader_addline(buffer,"TEMP T%u;\n", i); - } - - /* Texture coordinate registers must be pre-loaded */ - for (i = 0; i < This->baseShader.limits.texcoord; i++) { - if (reg_maps->texcoord[i]) - shader_addline(buffer, "MOV T%u, fragment.texcoord[%u];\n", i, i); + if(pshader && reg_maps->shader_version.major == 1 && reg_maps->shader_version.minor <= 3) { + for(i = 0; i < This->baseShader.limits.texcoord; i++) { + if (reg_maps->texcoord[i] && pshader) + shader_addline(buffer,"TEMP T%u;\n", i); + } } for(i = 0; i < (sizeof(reg_maps->bumpmat) / sizeof(reg_maps->bumpmat[0])); i++) { @@ -476,8 +476,8 @@ static void shader_arb_get_swizzle(const struct wined3d_shader_src_param *param, *ptr = '\0'; } -static void shader_arb_get_register_name(IWineD3DBaseShader *iface, WINED3DSHADER_PARAM_REGISTER_TYPE register_type, - UINT register_idx, BOOL rel_addr, char *register_name, BOOL *is_color) +static void shader_arb_get_register_name(IWineD3DBaseShader *iface, + const struct wined3d_shader_register *reg, char *register_name, BOOL *is_color) { /* oPos, oFog and oPts in D3D */ static const char * const rastout_reg_names[] = {"TMP_OUT", "result.fogcoord", "result.pointsize"}; @@ -486,63 +486,82 @@ static void shader_arb_get_register_name(IWineD3DBaseShader *iface, WINED3DSHADE *is_color = FALSE; - switch (register_type) + switch (reg->type) { case WINED3DSPR_TEMP: - sprintf(register_name, "R%u", register_idx); + sprintf(register_name, "R%u", reg->idx); break; case WINED3DSPR_INPUT: if (pshader) { - if (register_idx == 0) strcpy(register_name, "fragment.color.primary"); + if (reg->idx == 0) strcpy(register_name, "fragment.color.primary"); else strcpy(register_name, "fragment.color.secondary"); } else { - if (((IWineD3DVertexShaderImpl *)This)->cur_args->swizzle_map & (1 << register_idx)) *is_color = TRUE; - sprintf(register_name, "vertex.attrib[%u]", register_idx); + if (((IWineD3DVertexShaderImpl *)This)->cur_args->swizzle_map & (1 << reg->idx)) *is_color = TRUE; + sprintf(register_name, "vertex.attrib[%u]", reg->idx); } break; case WINED3DSPR_CONST: - if (!pshader && rel_addr) + if (!pshader && reg->rel_addr) { UINT rel_offset = ((IWineD3DVertexShaderImpl *)This)->rel_offset; - if (register_idx >= rel_offset) - sprintf(register_name, "C[A0.x + %u]", register_idx - rel_offset); + if (reg->idx >= rel_offset) + sprintf(register_name, "C[A0.x + %u]", reg->idx - rel_offset); else - sprintf(register_name, "C[A0.x - %u]", -register_idx + rel_offset); + sprintf(register_name, "C[A0.x - %u]", -reg->idx + rel_offset); } else { if (This->baseShader.reg_maps.usesrelconstF) - sprintf(register_name, "C[%u]", register_idx); + sprintf(register_name, "C[%u]", reg->idx); else - sprintf(register_name, "C%u", register_idx); + sprintf(register_name, "C%u", reg->idx); } break; case WINED3DSPR_TEXTURE: /* case WINED3DSPR_ADDR: */ - if (pshader) sprintf(register_name, "T%u", register_idx); - else sprintf(register_name, "A%u", register_idx); + if (pshader) { + if(This->baseShader.reg_maps.shader_version.major == 1 && + This->baseShader.reg_maps.shader_version.minor <= 3) { + /* In ps <= 1.3, Tx is a temporary register as destination to all instructions, + * and as source to most instructions. For some instructions it is the texcoord + * input. Those instructions know about the special use + */ + sprintf(register_name, "T%u", reg->idx); + } else { + /* in ps 1.4 and 2.x Tx is always a (read-only) varying */ + sprintf(register_name, "fragment.texcoord[%u]", reg->idx); + } + } + else sprintf(register_name, "A%u", reg->idx); break; case WINED3DSPR_COLOROUT: - if (register_idx == 0) + if (reg->idx == 0) { - strcpy(register_name, "TMP_COLOR"); + if(((IWineD3DPixelShaderImpl *)This)->cur_args->srgb_correction) + { + strcpy(register_name, "TMP_COLOR"); + } + else + { + strcpy(register_name, "result.color"); + } } else { /* TODO: See GL_ARB_draw_buffers */ - FIXME("Unsupported write to render target %u\n", register_idx); + FIXME("Unsupported write to render target %u\n", reg->idx); sprintf(register_name, "unsupported_register"); } break; case WINED3DSPR_RASTOUT: - sprintf(register_name, "%s", rastout_reg_names[register_idx]); + sprintf(register_name, "%s", rastout_reg_names[reg->idx]); break; case WINED3DSPR_DEPTHOUT: @@ -550,53 +569,32 @@ static void shader_arb_get_register_name(IWineD3DBaseShader *iface, WINED3DSHADE break; case WINED3DSPR_ATTROUT: - if (pshader) sprintf(register_name, "oD[%u]", register_idx); - else if (register_idx == 0) strcpy(register_name, "result.color.primary"); + if (pshader) sprintf(register_name, "oD[%u]", reg->idx); + else if (reg->idx == 0) strcpy(register_name, "result.color.primary"); else strcpy(register_name, "result.color.secondary"); break; case WINED3DSPR_TEXCRDOUT: - if (pshader) sprintf(register_name, "oT[%u]", register_idx); - else sprintf(register_name, "result.texcoord[%u]", register_idx); + if (pshader) sprintf(register_name, "oT[%u]", reg->idx); + else sprintf(register_name, "result.texcoord[%u]", reg->idx); break; default: - FIXME("Unhandled register type %#x[%u]\n", register_type, register_idx); - sprintf(register_name, "unrecognized_register[%u]", register_idx); + FIXME("Unhandled register type %#x[%u]\n", reg->type, reg->idx); + sprintf(register_name, "unrecognized_register[%u]", reg->idx); break; } } -static void shader_arb_add_src_param(const struct wined3d_shader_instruction *ins, - const struct wined3d_shader_src_param *wined3d_src, char *str) -{ - char register_name[255]; - char swizzle[6]; - BOOL is_color; - - if (wined3d_src->modifiers == WINED3DSPSM_NEG) strcat(str, " -"); - else strcat(str, " "); - - shader_arb_get_register_name(ins->ctx->shader, wined3d_src->reg.type, - wined3d_src->reg.idx, !!wined3d_src->reg.rel_addr, register_name, &is_color); - strcat(str, register_name); - - shader_arb_get_swizzle(wined3d_src, is_color, swizzle); - strcat(str, swizzle); -} - -static void shader_arb_add_dst_param(const struct wined3d_shader_instruction *ins, +static void shader_arb_get_dst_param(const struct wined3d_shader_instruction *ins, const struct wined3d_shader_dst_param *wined3d_dst, char *str) { char register_name[255]; char write_mask[6]; BOOL is_color; - strcat(str, " "); - - shader_arb_get_register_name(ins->ctx->shader, wined3d_dst->reg.type, - wined3d_dst->reg.idx, !!wined3d_dst->reg.rel_addr, register_name, &is_color); - strcat(str, register_name); + shader_arb_get_register_name(ins->ctx->shader, &wined3d_dst->reg, register_name, &is_color); + strcpy(str, register_name); shader_arb_get_write_mask(ins, wined3d_dst, write_mask); strcat(str, write_mask); @@ -732,7 +730,7 @@ static void shader_hw_sample(const struct wined3d_shader_instruction *ins, DWORD } } -static void pshader_gen_input_modifier_line(IWineD3DBaseShader *iface, SHADER_BUFFER *buffer, +static void shader_arb_get_src_param(const struct wined3d_shader_instruction *ins, const struct wined3d_shader_src_param *src, unsigned int tmpreg, char *outregstr) { /* Generate a line that does the input modifier computation and return the input register to use */ @@ -740,13 +738,13 @@ static void pshader_gen_input_modifier_line(IWineD3DBaseShader *iface, SHADER_BU char regstr[256]; char swzstr[20]; int insert_line; + SHADER_BUFFER *buffer = ins->ctx->buffer; /* Assume a new line will be added */ insert_line = 1; /* Get register name */ - shader_arb_get_register_name(iface, src->reg.type, - src->reg.idx, !!src->reg.rel_addr, regstr, &is_color); + shader_arb_get_register_name(ins->ctx->shader, &src->reg, regstr, &is_color); shader_arb_get_swizzle(src, is_color, swzstr); switch (src->modifiers) @@ -798,6 +796,31 @@ static void pshader_gen_input_modifier_line(IWineD3DBaseShader *iface, SHADER_BU sprintf(outregstr, "T%c%s", 'A' + tmpreg, swzstr); } +static const char *shader_arb_get_modifier(const struct wined3d_shader_instruction *ins) +{ + DWORD mod; + const char *ret = ""; + if (!ins->dst_count) return ""; + + mod = ins->dst[0].modifiers; + if(mod & WINED3DSPDM_SATURATE) { + ret = "_SAT"; + mod &= ~WINED3DSPDM_SATURATE; + } + if(mod & WINED3DSPDM_PARTIALPRECISION) { + FIXME("Unhandled modifier WINED3DSPDM_PARTIALPRECISION\n"); + mod &= ~WINED3DSPDM_PARTIALPRECISION; + } + if(mod & WINED3DSPDM_MSAMPCENTROID) { + FIXME("Unhandled modifier WINED3DSPDM_MSAMPCENTROID\n"); + mod &= ~WINED3DSPDM_MSAMPCENTROID; + } + if(mod) { + FIXME("Unknown modifiers 0x%08x\n", mod); + } + return ret; +} + static void pshader_hw_bem(const struct wined3d_shader_instruction *ins) { IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->ctx->shader; @@ -805,10 +828,8 @@ static void pshader_hw_bem(const struct wined3d_shader_instruction *ins) SHADER_BUFFER *buffer = ins->ctx->buffer; char dst_name[50]; char src_name[2][50]; - char dst_wmask[20]; DWORD sampler_code = dst->reg.idx; BOOL has_bumpmat = FALSE; - BOOL is_color; int i; for(i = 0; i < This->numbumpenvmatconsts; i++) { @@ -820,13 +841,8 @@ static void pshader_hw_bem(const struct wined3d_shader_instruction *ins) } } - shader_arb_get_register_name(ins->ctx->shader, dst->reg.type, - dst->reg.idx, !!dst->reg.rel_addr, dst_name, &is_color); - shader_arb_get_write_mask(ins, dst, dst_wmask); - strcat(dst_name, dst_wmask); - - pshader_gen_input_modifier_line(ins->ctx->shader, buffer, &ins->src[0], 0, src_name[0]); - pshader_gen_input_modifier_line(ins->ctx->shader, buffer, &ins->src[1], 1, src_name[1]); + shader_arb_get_src_param(ins, &ins->src[0], 0, src_name[0]); + shader_arb_get_src_param(ins, &ins->src[1], 1, src_name[1]); if(has_bumpmat) { /* Sampling the perturbation map in Tsrc was done already, including the signedness correction if needed */ @@ -845,34 +861,24 @@ static void pshader_hw_cnd(const struct wined3d_shader_instruction *ins) { const struct wined3d_shader_dst_param *dst = &ins->dst[0]; SHADER_BUFFER *buffer = ins->ctx->buffer; - char dst_wmask[20]; char dst_name[50]; char src_name[3][50]; - BOOL sat = dst->modifiers & WINED3DSPDM_SATURATE; - BOOL is_color; DWORD shader_version = WINED3D_SHADER_VERSION(ins->ctx->reg_maps->shader_version.major, ins->ctx->reg_maps->shader_version.minor); - /* FIXME: support output modifiers */ - - /* Handle output register */ - shader_arb_get_register_name(ins->ctx->shader, dst->reg.type, - dst->reg.idx, !!dst->reg.rel_addr, dst_name, &is_color); - shader_arb_get_write_mask(ins, dst, dst_wmask); - - /* Generate input register names (with modifiers) */ - pshader_gen_input_modifier_line(ins->ctx->shader, buffer, &ins->src[0], 0, src_name[0]); - pshader_gen_input_modifier_line(ins->ctx->shader, buffer, &ins->src[1], 1, src_name[1]); - pshader_gen_input_modifier_line(ins->ctx->shader, buffer, &ins->src[2], 2, src_name[2]); + shader_arb_get_dst_param(ins, dst, dst_name); + shader_arb_get_src_param(ins, &ins->src[1], 1, src_name[1]); /* The coissue flag changes the semantic of the cnd instruction in <= 1.3 shaders */ if (shader_version <= WINED3D_SHADER_VERSION(1, 3) && ins->coissue) { - shader_addline(buffer, "MOV%s %s%s, %s;\n", sat ? "_SAT" : "", dst_name, dst_wmask, src_name[1]); + shader_addline(buffer, "MOV%s %s, %s;\n", shader_arb_get_modifier(ins), dst_name, src_name[1]); } else { + shader_arb_get_src_param(ins, &ins->src[0], 0, src_name[0]); + shader_arb_get_src_param(ins, &ins->src[2], 2, src_name[2]); shader_addline(buffer, "ADD TMP, -%s, coefdiv.x;\n", src_name[0]); - shader_addline(buffer, "CMP%s %s%s, TMP, %s, %s;\n", - sat ? "_SAT" : "", dst_name, dst_wmask, src_name[1], src_name[2]); + shader_addline(buffer, "CMP%s %s, TMP, %s, %s;\n", + shader_arb_get_modifier(ins), dst_name, src_name[1], src_name[2]); } } @@ -880,25 +886,17 @@ static void pshader_hw_cmp(const struct wined3d_shader_instruction *ins) { const struct wined3d_shader_dst_param *dst = &ins->dst[0]; SHADER_BUFFER *buffer = ins->ctx->buffer; - char dst_wmask[20]; char dst_name[50]; char src_name[3][50]; - BOOL sat = dst->modifiers & WINED3DSPDM_SATURATE; - BOOL is_color; - /* FIXME: support output modifiers */ - - /* Handle output register */ - shader_arb_get_register_name(ins->ctx->shader, dst->reg.type, - dst->reg.idx, !!dst->reg.rel_addr, dst_name, &is_color); - shader_arb_get_write_mask(ins, dst, dst_wmask); + shader_arb_get_dst_param(ins, dst, dst_name); /* Generate input register names (with modifiers) */ - pshader_gen_input_modifier_line(ins->ctx->shader, buffer, &ins->src[0], 0, src_name[0]); - pshader_gen_input_modifier_line(ins->ctx->shader, buffer, &ins->src[1], 1, src_name[1]); - pshader_gen_input_modifier_line(ins->ctx->shader, buffer, &ins->src[2], 2, src_name[2]); + shader_arb_get_src_param(ins, &ins->src[0], 0, src_name[0]); + shader_arb_get_src_param(ins, &ins->src[1], 1, src_name[1]); + shader_arb_get_src_param(ins, &ins->src[2], 2, src_name[2]); - shader_addline(buffer, "CMP%s %s%s, %s, %s, %s;\n", sat ? "_SAT" : "", dst_name, dst_wmask, + shader_addline(buffer, "CMP%s %s, %s, %s, %s;\n", shader_arb_get_modifier(ins), dst_name, src_name[0], src_name[2], src_name[1]); } @@ -908,25 +906,19 @@ static void pshader_hw_dp2add(const struct wined3d_shader_instruction *ins) { const struct wined3d_shader_dst_param *dst = &ins->dst[0]; SHADER_BUFFER *buffer = ins->ctx->buffer; - char dst_wmask[20]; char dst_name[50]; char src_name[3][50]; - BOOL sat = dst->modifiers & WINED3DSPDM_SATURATE; - BOOL is_color; - shader_arb_get_register_name(ins->ctx->shader, dst->reg.type, - dst->reg.idx, !!dst->reg.rel_addr, dst_name, &is_color); - shader_arb_get_write_mask(ins, dst, dst_wmask); - - pshader_gen_input_modifier_line(ins->ctx->shader, buffer, &ins->src[0], 0, src_name[0]); - pshader_gen_input_modifier_line(ins->ctx->shader, buffer, &ins->src[1], 1, src_name[1]); - pshader_gen_input_modifier_line(ins->ctx->shader, buffer, &ins->src[2], 2, src_name[2]); + shader_arb_get_dst_param(ins, dst, dst_name); + shader_arb_get_src_param(ins, &ins->src[0], 0, src_name[0]); + shader_arb_get_src_param(ins, &ins->src[1], 1, src_name[1]); + shader_arb_get_src_param(ins, &ins->src[2], 2, src_name[2]); /* Emulate a DP2 with a DP3 and 0.0 */ shader_addline(buffer, "MOV TMP, %s;\n", src_name[0]); shader_addline(buffer, "MOV TMP.z, 0.0;\n"); shader_addline(buffer, "DP3 TMP2, TMP, %s;\n", src_name[1]); - shader_addline(buffer, "ADD%s %s%s, TMP2, %s;\n", sat ? "_SAT" : "", dst_name, dst_wmask, src_name[2]); + shader_addline(buffer, "ADD%s %s, TMP2, %s;\n", shader_arb_get_modifier(ins), dst_name, src_name[2]); } /* Map the opcode 1-to-1 to the GL code */ @@ -934,8 +926,9 @@ static void shader_hw_map2gl(const struct wined3d_shader_instruction *ins) { SHADER_BUFFER *buffer = ins->ctx->buffer; const char *instruction; - char arguments[256]; + char arguments[256], dst_str[50]; unsigned int i; + const struct wined3d_shader_dst_param *dst = &ins->dst[0]; switch (ins->handler_idx) { @@ -957,7 +950,6 @@ static void shader_hw_map2gl(const struct wined3d_shader_instruction *ins) case WINED3DSIH_MIN: instruction = "MIN"; break; case WINED3DSIH_MOV: instruction = "MOV"; break; case WINED3DSIH_MUL: instruction = "MUL"; break; - case WINED3DSIH_NOP: instruction = "NOP"; break; case WINED3DSIH_POW: instruction = "POW"; break; case WINED3DSIH_SGE: instruction = "SGE"; break; case WINED3DSIH_SLT: instruction = "SLT"; break; @@ -967,81 +959,23 @@ static void shader_hw_map2gl(const struct wined3d_shader_instruction *ins) break; } - if (shader_is_pshader_version(ins->ctx->reg_maps->shader_version.type)) + /* Note that shader_arb_add_dst_param() adds spaces. */ + arguments[0] = '\0'; + shader_arb_get_dst_param(ins, dst, dst_str); + for (i = 0; i < ins->src_count; ++i) { - /* Output token related */ - const struct wined3d_shader_dst_param *dst; - char output_rname[256]; - char output_wmask[20]; - char operands[4][100]; - BOOL saturate = FALSE; - BOOL centroid = FALSE; - BOOL partialprecision = FALSE; - const char *modifier; - BOOL is_color; - DWORD shift; - - if (!(ins->dst_count + ins->src_count)) - { - ERR("Opcode \"%#x\" has no parameters\n", ins->handler_idx); - return; - } - dst = &ins->dst[0]; - - /* Process modifiers */ - if (dst->modifiers) - { - DWORD mask = dst->modifiers; - - saturate = mask & WINED3DSPDM_SATURATE; - centroid = mask & WINED3DSPDM_MSAMPCENTROID; - partialprecision = mask & WINED3DSPDM_PARTIALPRECISION; - mask &= ~(WINED3DSPDM_MSAMPCENTROID | WINED3DSPDM_PARTIALPRECISION | WINED3DSPDM_SATURATE); - if (mask) - FIXME("Unrecognized modifier(%#x)\n", mask); - - if (centroid) - FIXME("Unhandled modifier(%#x)\n", mask); - } - shift = dst->shift; - modifier = (saturate && !shift) ? "_SAT" : ""; - - /* Generate input register names (with modifiers) */ - for (i = 0; i < ins->src_count; ++i) - { - pshader_gen_input_modifier_line(ins->ctx->shader, buffer, &ins->src[i], i, operands[i + 1]); - } - - /* Handle output register */ - shader_arb_get_register_name(ins->ctx->shader, dst->reg.type, - dst->reg.idx, !!dst->reg.rel_addr, output_rname, &is_color); - strcpy(operands[0], output_rname); - shader_arb_get_write_mask(ins, dst, output_wmask); - strcat(operands[0], output_wmask); - - arguments[0] = '\0'; - strcat(arguments, operands[0]); - for (i = 0; i < ins->src_count; ++i) - { - strcat(arguments, ", "); - strcat(arguments, operands[i + 1]); - } - shader_addline(buffer, "%s%s %s;\n", instruction, modifier, arguments); - } else { - /* Note that shader_arb_add_*_param() adds spaces. */ - - arguments[0] = '\0'; - if (ins->dst_count) - { - shader_arb_add_dst_param(ins, &ins->dst[0], arguments); - for (i = 0; i < ins->src_count; ++i) - { - strcat(arguments, ","); - shader_arb_add_src_param(ins, &ins->src[i], arguments); - } - } - shader_addline(buffer, "%s%s;\n", instruction, arguments); + char operand[100]; + strcat(arguments, ", "); + shader_arb_get_src_param(ins, &ins->src[i], i, operand); + strcat(arguments, operand); } + shader_addline(buffer, "%s%s %s%s;\n", instruction, shader_arb_get_modifier(ins), dst_str, arguments); +} + +static void shader_hw_nop(const struct wined3d_shader_instruction *ins) +{ + SHADER_BUFFER *buffer = ins->ctx->buffer; + shader_addline(buffer, "NOP;\n"); } static void shader_hw_mov(const struct wined3d_shader_instruction *ins) @@ -1062,7 +996,7 @@ static void shader_hw_mov(const struct wined3d_shader_instruction *ins) src0_param[0] = '\0'; if (((IWineD3DVertexShaderImpl *)shader)->rel_offset) { - shader_arb_add_src_param(ins, &ins->src[0], src0_param); + shader_arb_get_src_param(ins, &ins->src[0], 0, src0_param); shader_addline(buffer, "ADD TMP.x, %s, helper_const.z;\n", src0_param); shader_addline(buffer, "ARL A0.x, TMP.x;\n"); } @@ -1073,7 +1007,7 @@ static void shader_hw_mov(const struct wined3d_shader_instruction *ins) * 4 components. For example, .xyzw -> .x (or better: .xxxx), .zwxy -> .z, etc) */ struct wined3d_shader_src_param tmp_src = ins->src[0]; tmp_src.swizzle = (tmp_src.swizzle & 0x3) * 0x55; - shader_arb_add_src_param(ins, &tmp_src, src0_param); + shader_arb_get_src_param(ins, &tmp_src, 0, src0_param); shader_addline(buffer, "ARL A0.x, %s;\n", src0_param); } } @@ -1088,24 +1022,30 @@ static void pshader_hw_texkill(const struct wined3d_shader_instruction *ins) const struct wined3d_shader_dst_param *dst = &ins->dst[0]; SHADER_BUFFER *buffer = ins->ctx->buffer; char reg_dest[40]; - BOOL is_color; /* No swizzles are allowed in d3d's texkill. PS 1.x ignores the 4th component as documented, * but >= 2.0 honors it(undocumented, but tested by the d3d9 testsuit) */ - shader_arb_get_register_name(ins->ctx->shader, dst->reg.type, - dst->reg.idx, !!dst->reg.rel_addr, reg_dest, &is_color); + shader_arb_get_dst_param(ins, dst, reg_dest); if (ins->ctx->reg_maps->shader_version.major >= 2) { /* The arb backend doesn't claim ps 2.0 support, but try to eat what the app feeds to us */ + shader_arb_get_dst_param(ins, dst, reg_dest); shader_addline(buffer, "KIL %s;\n", reg_dest); } else { /* ARB fp doesn't like swizzles on the parameter of the KIL instruction. To mask the 4th component, * copy the register into our general purpose TMP variable, overwrite .w and pass TMP to KIL + * + * ps_1_3 shaders use the texcoord incarnation of the Tx register. ps_1_4 shaders can use the same, + * or pass in any temporary register(in shader phase 2) */ - shader_addline(buffer, "MOV TMP, %s;\n", reg_dest); - shader_addline(buffer, "MOV TMP.w, one.w;\n"); + if(ins->ctx->reg_maps->shader_version.minor <= 3) { + sprintf(reg_dest, "fragment.texcoord[%u]", dst->reg.idx); + } else { + shader_arb_get_dst_param(ins, dst, reg_dest); + } + shader_addline(buffer, "SWZ TMP, %s, x, y, z, 1;\n", reg_dest); shader_addline(buffer, "KIL TMP;\n"); } } @@ -1115,62 +1055,70 @@ static void pshader_hw_tex(const struct wined3d_shader_instruction *ins) IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->ctx->shader; IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device; const struct wined3d_shader_dst_param *dst = &ins->dst[0]; - BOOL is_color; - SHADER_BUFFER *buffer = ins->ctx->buffer; DWORD shader_version = WINED3D_SHADER_VERSION(ins->ctx->reg_maps->shader_version.major, ins->ctx->reg_maps->shader_version.minor); BOOL projected = FALSE, bias = FALSE; + struct wined3d_shader_src_param src; char reg_dest[40]; char reg_coord[40]; DWORD reg_sampler_code; /* All versions have a destination register */ - shader_arb_get_register_name(ins->ctx->shader, dst->reg.type, - dst->reg.idx, !!dst->reg.rel_addr, reg_dest, &is_color); + shader_arb_get_dst_param(ins, dst, reg_dest); + + /* 1.0-1.4: Use destination register number as texture code. + 2.0+: Use provided sampler number as texure code. */ + if (shader_version < WINED3D_SHADER_VERSION(2,0)) + reg_sampler_code = dst->reg.idx; + else + reg_sampler_code = ins->src[1].reg.idx; - /* 1.0-1.3: Use destination register as coordinate source. + /* 1.0-1.3: Use the texcoord varying. 1.4+: Use provided coordinate source register. */ - if (shader_version < WINED3D_SHADER_VERSION(1,4)) - strcpy(reg_coord, reg_dest); - else - pshader_gen_input_modifier_line(ins->ctx->shader, buffer, &ins->src[0], 0, reg_coord); - - /* 1.0-1.4: Use destination register number as texture code. - 2.0+: Use provided sampler number as texure code. */ - if (shader_version < WINED3D_SHADER_VERSION(2,0)) - reg_sampler_code = dst->reg.idx; - else - reg_sampler_code = ins->src[1].reg.idx; - - /* projection flag: - * 1.1, 1.2, 1.3: Use WINED3DTSS_TEXTURETRANSFORMFLAGS - * 1.4: Use WINED3DSPSM_DZ or WINED3DSPSM_DW on src[0] - * 2.0+: Use WINED3DSI_TEXLD_PROJECT on the opcode - */ - if (shader_version < WINED3D_SHADER_VERSION(1,4)) - { - DWORD flags = 0; - if(reg_sampler_code < MAX_TEXTURES) { - flags = deviceImpl->stateBlock->textureState[reg_sampler_code][WINED3DTSS_TEXTURETRANSFORMFLAGS]; - } - if (flags & WINED3DTTFF_PROJECTED) { - projected = TRUE; - } - } - else if (shader_version < WINED3D_SHADER_VERSION(2,0)) - { - DWORD src_mod = ins->src[0].modifiers; - if (src_mod == WINED3DSPSM_DZ) { - projected = TRUE; - } else if(src_mod == WINED3DSPSM_DW) { - projected = TRUE; - } - } else { - if (ins->flags & WINED3DSI_TEXLD_PROJECT) projected = TRUE; - if (ins->flags & WINED3DSI_TEXLD_BIAS) bias = TRUE; - } - shader_hw_sample(ins, reg_sampler_code, reg_dest, reg_coord, projected, bias); + if (shader_version < WINED3D_SHADER_VERSION(1,4)) + sprintf(reg_coord, "fragment.texcoord[%u]", reg_sampler_code); + else { + /* TEX is the only instruction that can handle DW and DZ natively */ + src = ins->src[0]; + if(src.modifiers == WINED3DSPSM_DW) src.modifiers = WINED3DSPSM_NONE; + if(src.modifiers == WINED3DSPSM_DZ) src.modifiers = WINED3DSPSM_NONE; + shader_arb_get_src_param(ins, &src, 0, reg_coord); + } + + /* projection flag: + * 1.1, 1.2, 1.3: Use WINED3DTSS_TEXTURETRANSFORMFLAGS + * 1.4: Use WINED3DSPSM_DZ or WINED3DSPSM_DW on src[0] + * 2.0+: Use WINED3DSI_TEXLD_PROJECT on the opcode + */ + if (shader_version < WINED3D_SHADER_VERSION(1,4)) + { + DWORD flags = 0; + if(reg_sampler_code < MAX_TEXTURES) { + flags = deviceImpl->stateBlock->textureState[reg_sampler_code][WINED3DTSS_TEXTURETRANSFORMFLAGS]; + } + if (flags & WINED3DTTFF_PROJECTED) { + projected = TRUE; + } + } + else if (shader_version < WINED3D_SHADER_VERSION(2,0)) + { + DWORD src_mod = ins->src[0].modifiers; + if (src_mod == WINED3DSPSM_DZ) { + /* TXP cannot handle DZ natively, so move the z coordinate to .w. reg_coord is a read-only + * varying register, so we need a temp reg + */ + shader_addline(ins->ctx->buffer, "SWZ TA, %s, x, y, z, z;\n", reg_coord); + strcpy(reg_coord, "TA"); + projected = TRUE; + } else if(src_mod == WINED3DSPSM_DW) { + projected = TRUE; + } + } else { + if (ins->flags & WINED3DSI_TEXLD_PROJECT) projected = TRUE; + if (ins->flags & WINED3DSI_TEXLD_BIAS) bias = TRUE; + } + shader_hw_sample(ins, reg_sampler_code, reg_dest, reg_coord, projected, bias); } static void pshader_hw_texcoord(const struct wined3d_shader_instruction *ins) @@ -1189,7 +1137,7 @@ static void pshader_hw_texcoord(const struct wined3d_shader_instruction *ins) } else { char reg_src[40]; - pshader_gen_input_modifier_line(ins->ctx->shader, buffer, &ins->src[0], 0, reg_src); + shader_arb_get_src_param(ins, &ins->src[0], 0, reg_src); shader_addline(buffer, "MOV R%u%s, %s;\n", dst->reg.idx, tmp, reg_src); } } @@ -1202,11 +1150,12 @@ static void pshader_hw_texreg2ar(const struct wined3d_shader_instruction *ins) DWORD flags; DWORD reg1 = ins->dst[0].reg.idx; - char dst_str[8]; + char dst_str[50]; char src_str[50]; - sprintf(dst_str, "T%u", reg1); - pshader_gen_input_modifier_line(ins->ctx->shader, buffer, &ins->src[0], 0, src_str); + /* Note that texreg2ar treats Tx as a temporary register, not as a varying */ + shader_arb_get_dst_param(ins, &ins->dst[0], dst_str); + shader_arb_get_src_param(ins, &ins->src[0], 0, src_str); shader_addline(buffer, "MOV TMP.x, %s.w;\n", src_str); shader_addline(buffer, "MOV TMP.y, %s.x;\n", src_str); flags = reg1 < MAX_TEXTURES ? deviceImpl->stateBlock->textureState[reg1][WINED3DTSS_TEXTURETRANSFORMFLAGS] : 0; @@ -1218,11 +1167,12 @@ static void pshader_hw_texreg2gb(const struct wined3d_shader_instruction *ins) SHADER_BUFFER *buffer = ins->ctx->buffer; DWORD reg1 = ins->dst[0].reg.idx; - char dst_str[8]; + char dst_str[50]; char src_str[50]; - sprintf(dst_str, "T%u", reg1); - pshader_gen_input_modifier_line(ins->ctx->shader, buffer, &ins->src[0], 0, src_str); + /* Note that texreg2gb treats Tx as a temporary register, not as a varying */ + shader_arb_get_dst_param(ins, &ins->dst[0], dst_str); + shader_arb_get_src_param(ins, &ins->src[0], 0, src_str); shader_addline(buffer, "MOV TMP.x, %s.y;\n", src_str); shader_addline(buffer, "MOV TMP.y, %s.z;\n", src_str); shader_hw_sample(ins, reg1, dst_str, "TMP", FALSE, FALSE); @@ -1230,13 +1180,13 @@ static void pshader_hw_texreg2gb(const struct wined3d_shader_instruction *ins) static void pshader_hw_texreg2rgb(const struct wined3d_shader_instruction *ins) { - SHADER_BUFFER *buffer = ins->ctx->buffer; DWORD reg1 = ins->dst[0].reg.idx; - char dst_str[8]; + char dst_str[50]; char src_str[50]; - sprintf(dst_str, "T%u", reg1); - pshader_gen_input_modifier_line(ins->ctx->shader, buffer, &ins->src[0], 0, src_str); + /* Note that texreg2rg treats Tx as a temporary register, not as a varying */ + shader_arb_get_dst_param(ins, &ins->dst[0], dst_str); + shader_arb_get_src_param(ins, &ins->src[0], 0, src_str); shader_hw_sample(ins, reg1, dst_str, src_str, FALSE, FALSE); } @@ -1246,19 +1196,19 @@ static void pshader_hw_texbem(const struct wined3d_shader_instruction *ins) const struct wined3d_shader_dst_param *dst = &ins->dst[0]; BOOL has_bumpmat = FALSE; BOOL has_luminance = FALSE; - BOOL is_color; int i; SHADER_BUFFER *buffer = ins->ctx->buffer; - char reg_coord[40]; + char reg_coord[40], dst_reg[50]; DWORD reg_dest_code; - /* All versions have a destination register */ + /* All versions have a destination register. The Tx where the texture coordinates come + * from is the varying incarnation of the texture register + */ reg_dest_code = dst->reg.idx; - /* Can directly use the name because texbem is only valid for <= 1.3 shaders */ - shader_arb_get_register_name(ins->ctx->shader, dst->reg.type, - dst->reg.idx, !!dst->reg.rel_addr, reg_coord, &is_color); + shader_arb_get_dst_param(ins, &ins->dst[0], dst_reg); + sprintf(reg_coord, "fragment.texcoord[%u]", reg_dest_code); for(i = 0; i < This->numbumpenvmatconsts; i++) { if (This->bumpenvmatconst[i].const_num != WINED3D_CONST_NUM_UNUSED @@ -1280,8 +1230,9 @@ static void pshader_hw_texbem(const struct wined3d_shader_instruction *ins) if(has_bumpmat) { DWORD src = ins->src[0].reg.idx; - /* Sampling the perturbation map in Tsrc was done already, including the signedness correction if needed */ - + /* Sampling the perturbation map in Tsrc was done already, including the signedness correction if needed + * The Tx in which the perturbation map is stored is the tempreg incarnation of the texture register + */ shader_addline(buffer, "SWZ TMP2, bumpenvmat%d, x, z, 0, 0;\n", reg_dest_code); shader_addline(buffer, "DP3 TMP.x, TMP2, T%u;\n", src); shader_addline(buffer, "SWZ TMP2, bumpenvmat%d, y, w, 0, 0;\n", reg_dest_code); @@ -1299,13 +1250,13 @@ static void pshader_hw_texbem(const struct wined3d_shader_instruction *ins) shader_addline(buffer, "ADD TMP.xy, TMP, %s;\n", reg_coord); } - shader_hw_sample(ins, reg_dest_code, reg_coord, "TMP", FALSE, FALSE); + shader_hw_sample(ins, reg_dest_code, dst_reg, "TMP", FALSE, FALSE); if (ins->handler_idx == WINED3DSIH_TEXBEML && has_luminance) { shader_addline(buffer, "MAD TMP, T%u.z, luminance%d.x, luminance%d.y;\n", src, reg_dest_code, reg_dest_code); - shader_addline(buffer, "MUL %s, %s, TMP;\n", reg_coord, reg_coord); + shader_addline(buffer, "MUL %s, %s, TMP;\n", dst_reg, dst_reg); } } else { @@ -1316,7 +1267,7 @@ static void pshader_hw_texbem(const struct wined3d_shader_instruction *ins) tf = 0; } /* Without a bump matrix loaded, just sample with the unmodified coordinates */ - shader_hw_sample(ins, reg_dest_code, reg_coord, reg_coord, tf & WINED3DTTFF_PROJECTED, FALSE); + shader_hw_sample(ins, reg_dest_code, dst_reg, reg_coord, tf & WINED3DTTFF_PROJECTED, FALSE); } } @@ -1326,8 +1277,8 @@ static void pshader_hw_texm3x2pad(const struct wined3d_shader_instruction *ins) SHADER_BUFFER *buffer = ins->ctx->buffer; char src0_name[50]; - pshader_gen_input_modifier_line(ins->ctx->shader, buffer, &ins->src[0], 0, src0_name); - shader_addline(buffer, "DP3 TMP.x, T%u, %s;\n", reg, src0_name); + shader_arb_get_src_param(ins, &ins->src[0], 0, src0_name); + shader_addline(buffer, "DP3 TMP.x, fragment.texcoord[%u], %s;\n", reg, src0_name); } static void pshader_hw_texm3x2tex(const struct wined3d_shader_instruction *ins) @@ -1337,12 +1288,12 @@ static void pshader_hw_texm3x2tex(const struct wined3d_shader_instruction *ins) DWORD flags; DWORD reg = ins->dst[0].reg.idx; SHADER_BUFFER *buffer = ins->ctx->buffer; - char dst_str[8]; + char dst_str[50]; char src0_name[50]; - sprintf(dst_str, "T%u", reg); - pshader_gen_input_modifier_line(ins->ctx->shader, buffer, &ins->src[0], 0, src0_name); - shader_addline(buffer, "DP3 TMP.y, T%u, %s;\n", reg, src0_name); + shader_arb_get_dst_param(ins, &ins->dst[0], dst_str); + shader_arb_get_src_param(ins, &ins->src[0], 0, src0_name); + shader_addline(buffer, "DP3 TMP.y, fragment.texcoord[%u], %s;\n", reg, src0_name); flags = reg < MAX_TEXTURES ? deviceImpl->stateBlock->textureState[reg][WINED3DTSS_TEXTURETRANSFORMFLAGS] : 0; shader_hw_sample(ins, reg, dst_str, "TMP", flags & WINED3DTTFF_PROJECTED, FALSE); } @@ -1355,8 +1306,8 @@ static void pshader_hw_texm3x3pad(const struct wined3d_shader_instruction *ins) SHADER_PARSE_STATE* current_state = &This->baseShader.parse_state; char src0_name[50]; - pshader_gen_input_modifier_line(ins->ctx->shader, buffer, &ins->src[0], 0, src0_name); - shader_addline(buffer, "DP3 TMP.%c, T%u, %s;\n", 'x' + current_state->current_row, reg, src0_name); + shader_arb_get_src_param(ins, &ins->src[0], 0, src0_name); + shader_addline(buffer, "DP3 TMP.%c, fragment.texcoord[%u], %s;\n", 'x' + current_state->current_row, reg, src0_name); current_state->texcoord_w[current_state->current_row++] = reg; } @@ -1368,14 +1319,14 @@ static void pshader_hw_texm3x3tex(const struct wined3d_shader_instruction *ins) DWORD reg = ins->dst[0].reg.idx; SHADER_BUFFER *buffer = ins->ctx->buffer; SHADER_PARSE_STATE* current_state = &This->baseShader.parse_state; - char dst_str[8]; + char dst_str[50]; char src0_name[50]; - pshader_gen_input_modifier_line(ins->ctx->shader, buffer, &ins->src[0], 0, src0_name); - shader_addline(buffer, "DP3 TMP.z, T%u, %s;\n", reg, src0_name); + shader_arb_get_src_param(ins, &ins->src[0], 0, src0_name); + shader_addline(buffer, "DP3 TMP.z, fragment.texcoord[%u], %s;\n", reg, src0_name); /* Sample the texture using the calculated coordinates */ - sprintf(dst_str, "T%u", reg); + shader_arb_get_dst_param(ins, &ins->dst[0], dst_str); flags = reg < MAX_TEXTURES ? deviceImpl->stateBlock->textureState[reg][WINED3DTSS_TEXTURETRANSFORMFLAGS] : 0; shader_hw_sample(ins, reg, dst_str, "TMP", flags & WINED3DTTFF_PROJECTED, FALSE); current_state->current_row = 0; @@ -1389,11 +1340,11 @@ static void pshader_hw_texm3x3vspec(const struct wined3d_shader_instruction *ins DWORD reg = ins->dst[0].reg.idx; SHADER_BUFFER *buffer = ins->ctx->buffer; SHADER_PARSE_STATE* current_state = &This->baseShader.parse_state; - char dst_str[8]; + char dst_str[50]; char src0_name[50]; - pshader_gen_input_modifier_line(ins->ctx->shader, buffer, &ins->src[0], 0, src0_name); - shader_addline(buffer, "DP3 TMP.z, T%u, %s;\n", reg, src0_name); + shader_arb_get_src_param(ins, &ins->src[0], 0, src0_name); + shader_addline(buffer, "DP3 TMP.z, fragment.texcoord[%u], %s;\n", reg, src0_name); /* Construct the eye-ray vector from w coordinates */ shader_addline(buffer, "MOV TMP2.x, fragment.texcoord[%u].w;\n", current_state->texcoord_w[0]); @@ -1411,7 +1362,7 @@ static void pshader_hw_texm3x3vspec(const struct wined3d_shader_instruction *ins shader_addline(buffer, "MAD TMP, coefmul.x, TMP, -TMP2;\n"); /* Sample the texture using the calculated coordinates */ - sprintf(dst_str, "T%u", reg); + shader_arb_get_dst_param(ins, &ins->dst[0], dst_str); flags = reg < MAX_TEXTURES ? deviceImpl->stateBlock->textureState[reg][WINED3DTSS_TEXTURETRANSFORMFLAGS] : 0; shader_hw_sample(ins, reg, dst_str, "TMP", flags & WINED3DTTFF_PROJECTED, FALSE); current_state->current_row = 0; @@ -1425,13 +1376,13 @@ static void pshader_hw_texm3x3spec(const struct wined3d_shader_instruction *ins) DWORD reg = ins->dst[0].reg.idx; SHADER_PARSE_STATE* current_state = &This->baseShader.parse_state; SHADER_BUFFER *buffer = ins->ctx->buffer; - char dst_str[8]; + char dst_str[50]; char src0_name[50]; char src1_name[50]; - pshader_gen_input_modifier_line(ins->ctx->shader, buffer, &ins->src[0], 0, src0_name); - pshader_gen_input_modifier_line(ins->ctx->shader, buffer, &ins->src[1], 1, src1_name); - shader_addline(buffer, "DP3 TMP.z, T%u, %s;\n", reg, src0_name); + shader_arb_get_src_param(ins, &ins->src[0], 0, src0_name); + shader_arb_get_src_param(ins, &ins->src[0], 1, src1_name); + shader_addline(buffer, "DP3 TMP.z, fragment.texcoord[%u], %s;\n", reg, src0_name); /* Calculate reflection vector. * @@ -1449,7 +1400,7 @@ static void pshader_hw_texm3x3spec(const struct wined3d_shader_instruction *ins) shader_addline(buffer, "MAD TMP, coefmul.x, TMP, -%s;\n", src1_name); /* Sample the texture using the calculated coordinates */ - sprintf(dst_str, "T%u", reg); + shader_arb_get_dst_param(ins, &ins->dst[0], dst_str); flags = reg < MAX_TEXTURES ? deviceImpl->stateBlock->textureState[reg][WINED3DTSS_TEXTURETRANSFORMFLAGS] : 0; shader_hw_sample(ins, reg, dst_str, "TMP", flags & WINED3DTTFF_PROJECTED, FALSE); current_state->current_row = 0; @@ -1460,15 +1411,13 @@ static void pshader_hw_texdepth(const struct wined3d_shader_instruction *ins) const struct wined3d_shader_dst_param *dst = &ins->dst[0]; SHADER_BUFFER *buffer = ins->ctx->buffer; char dst_name[50]; - BOOL is_color; /* texdepth has an implicit destination, the fragment depth value. It's only parameter, * which is essentially an input, is the destination register because it is the first * parameter. According to the msdn, this must be register r5, but let's keep it more flexible - * here + * here(writemasks/swizzles are not valid on texdepth) */ - shader_arb_get_register_name(ins->ctx->shader, dst->reg.type, - dst->reg.idx, !!dst->reg.rel_addr, dst_name, &is_color); + shader_arb_get_dst_param(ins, dst, dst_name); /* According to the msdn, the source register(must be r5) is unusable after * the texdepth instruction, so we're free to modify it @@ -1493,13 +1442,13 @@ static void pshader_hw_texdp3tex(const struct wined3d_shader_instruction *ins) SHADER_BUFFER *buffer = ins->ctx->buffer; DWORD sampler_idx = ins->dst[0].reg.idx; char src0[50]; - char dst_str[8]; + char dst_str[50]; - pshader_gen_input_modifier_line(ins->ctx->shader, buffer, &ins->src[0], 0, src0); + shader_arb_get_src_param(ins, &ins->src[0], 0, src0); shader_addline(buffer, "MOV TMP, 0.0;\n"); - shader_addline(buffer, "DP3 TMP.x, T%u, %s;\n", sampler_idx, src0); + shader_addline(buffer, "DP3 TMP.x, fragment.texcoord[%u], %s;\n", sampler_idx, src0); - sprintf(dst_str, "T%u", sampler_idx); + shader_arb_get_dst_param(ins, &ins->dst[0], dst_str); shader_hw_sample(ins, sampler_idx, dst_str, "TMP", FALSE /* Only one coord, can't be projected */, FALSE); } @@ -1510,19 +1459,12 @@ static void pshader_hw_texdp3(const struct wined3d_shader_instruction *ins) const struct wined3d_shader_dst_param *dst = &ins->dst[0]; char src0[50]; char dst_str[50]; - char dst_mask[6]; SHADER_BUFFER *buffer = ins->ctx->buffer; - BOOL is_color; /* Handle output register */ - shader_arb_get_register_name(ins->ctx->shader, dst->reg.type, - dst->reg.idx, !!dst->reg.rel_addr, dst_str, &is_color); - shader_arb_get_write_mask(ins, dst, dst_mask); - - pshader_gen_input_modifier_line(ins->ctx->shader, buffer, &ins->src[0], 0, src0); - shader_addline(buffer, "DP3 %s%s, T%u, %s;\n", dst_str, dst_mask, dst->reg.idx, src0); - - /* TODO: Handle output modifiers */ + shader_arb_get_dst_param(ins, dst, dst_str); + shader_arb_get_src_param(ins, &ins->src[0], 0, src0); + shader_addline(buffer, "DP3 %s, fragment.texcoord[%u], %s;\n", dst_str, dst->reg.idx, src0); } /** Process the WINED3DSIO_TEXM3X3 instruction in ARB @@ -1532,19 +1474,12 @@ static void pshader_hw_texm3x3(const struct wined3d_shader_instruction *ins) const struct wined3d_shader_dst_param *dst = &ins->dst[0]; SHADER_BUFFER *buffer = ins->ctx->buffer; char dst_str[50]; - char dst_mask[6]; char src0[50]; - BOOL is_color; - - shader_arb_get_register_name(ins->ctx->shader, dst->reg.type, - dst->reg.idx, !!dst->reg.rel_addr, dst_str, &is_color); - shader_arb_get_write_mask(ins, dst, dst_mask); - pshader_gen_input_modifier_line(ins->ctx->shader, buffer, &ins->src[0], 0, src0); - shader_addline(buffer, "DP3 TMP.z, T%u, %s;\n", dst->reg.idx, src0); - shader_addline(buffer, "MOV %s%s, TMP;\n", dst_str, dst_mask); - - /* TODO: Handle output modifiers */ + shader_arb_get_dst_param(ins, dst, dst_str); + shader_arb_get_src_param(ins, &ins->src[0], 0, src0); + shader_addline(buffer, "DP3 TMP.z, fragment.texcoord[%u], %s;\n", dst->reg.idx, src0); + shader_addline(buffer, "MOV %s, TMP;\n", dst_str); } /** Process the WINED3DSIO_TEXM3X2DEPTH instruction in ARB: @@ -1558,8 +1493,8 @@ static void pshader_hw_texm3x2depth(const struct wined3d_shader_instruction *ins DWORD dst_reg = ins->dst[0].reg.idx; char src0[50]; - pshader_gen_input_modifier_line(ins->ctx->shader, buffer, &ins->src[0], 0, src0); - shader_addline(buffer, "DP3 TMP.y, T%u, %s;\n", dst_reg, src0); + shader_arb_get_src_param(ins, &ins->src[0], 0, src0); + shader_addline(buffer, "DP3 TMP.y, fragment.texcoord[%u], %s;\n", dst_reg, src0); /* How to deal with the special case dst_name.g == 0? if r != 0, then * the r * (1 / 0) will give infinity, which is clamped to 1.0, the correct @@ -1627,12 +1562,13 @@ static void shader_hw_mnxn(const struct wined3d_shader_instruction *ins) } } -static void vshader_hw_rsq_rcp(const struct wined3d_shader_instruction *ins) +static void shader_hw_rsq_rcp(const struct wined3d_shader_instruction *ins) { SHADER_BUFFER *buffer = ins->ctx->buffer; const char *instruction; - char tmpLine[256]; + char dst[50]; + char src[50]; switch(ins->handler_idx) { @@ -1643,40 +1579,31 @@ static void vshader_hw_rsq_rcp(const struct wined3d_shader_instruction *ins) break; } - strcpy(tmpLine, instruction); - shader_arb_add_dst_param(ins, &ins->dst[0], tmpLine); /* Destination */ - strcat(tmpLine, ","); - shader_arb_add_src_param(ins, &ins->src[0], tmpLine); + shader_arb_get_dst_param(ins, &ins->dst[0], dst); /* Destination */ + shader_arb_get_src_param(ins, &ins->src[0], 0, src); if (ins->src[0].swizzle == WINED3DSP_NOSWIZZLE) { /* Dx sdk says .x is used if no swizzle is given, but our test shows that * .w is used */ - strcat(tmpLine, ".w"); + strcat(src, ".w"); } - shader_addline(buffer, "%s;\n", tmpLine); + shader_addline(buffer, "%s%s %s, %s;\n", instruction, shader_arb_get_modifier(ins), dst, src); } static void shader_hw_nrm(const struct wined3d_shader_instruction *ins) { - const struct wined3d_shader_dst_param *dst = &ins->dst[0]; SHADER_BUFFER *buffer = ins->ctx->buffer; char dst_name[50]; char src_name[50]; - char dst_wmask[20]; - BOOL sat = dst->modifiers & WINED3DSPDM_SATURATE; - BOOL is_color; - - shader_arb_get_register_name(ins->ctx->shader, dst->reg.type, - dst->reg.idx, !!dst->reg.rel_addr, dst_name, &is_color); - shader_arb_get_write_mask(ins, dst, dst_wmask); - pshader_gen_input_modifier_line(ins->ctx->shader, buffer, &ins->src[0], 0, src_name); + shader_arb_get_dst_param(ins, &ins->dst[0], dst_name); + shader_arb_get_src_param(ins, &ins->src[0], 0, src_name); shader_addline(buffer, "DP3 TMP, %s, %s;\n", src_name, src_name); shader_addline(buffer, "RSQ TMP, TMP.x;\n"); /* dst.w = src[0].w * 1 / (src.x^2 + src.y^2 + src.z^2)^(1/2) according to msdn*/ - shader_addline(buffer, "MUL%s %s%s, %s, TMP;\n", sat ? "_SAT" : "", dst_name, dst_wmask, + shader_addline(buffer, "MUL%s %s, %s, TMP;\n", shader_arb_get_modifier(ins), dst_name, src_name); } @@ -1686,23 +1613,17 @@ static void shader_hw_sincos(const struct wined3d_shader_instruction *ins) * must contain fixed constants. So we need a separate function to filter those constants and * can't use map2gl */ - const struct wined3d_shader_dst_param *dst = &ins->dst[0]; SHADER_BUFFER *buffer = ins->ctx->buffer; char dst_name[50]; char src_name[50]; - char dst_wmask[20]; - BOOL sat = dst->modifiers & WINED3DSPDM_SATURATE; - BOOL is_color; - - shader_arb_get_register_name(ins->ctx->shader, dst->reg.type, - dst->reg.idx, !!dst->reg.rel_addr, dst_name, &is_color); - shader_arb_get_write_mask(ins, dst, dst_wmask); - pshader_gen_input_modifier_line(ins->ctx->shader, buffer, &ins->src[0], 0, src_name); - shader_addline(buffer, "SCS%s %s%s, %s;\n", sat ? "_SAT" : "", dst_name, dst_wmask, + shader_arb_get_dst_param(ins, &ins->dst[0], dst_name); + shader_arb_get_src_param(ins, &ins->src[0], 0, src_name); + shader_addline(buffer, "SCS%s %s, %s;\n", shader_arb_get_modifier(ins), dst_name, src_name); } +/* GL locking is done by the caller */ static GLuint create_arb_blt_vertex_program(const WineD3D_GL_Info *gl_info) { GLuint program_id = 0; @@ -1728,6 +1649,7 @@ static GLuint create_arb_blt_vertex_program(const WineD3D_GL_Info *gl_info) return program_id; } +/* GL locking is done by the caller */ static GLuint create_arb_blt_fragment_program(const WineD3D_GL_Info *gl_info, enum tex_types tex_type) { GLuint program_id = 0; @@ -1777,6 +1699,7 @@ static GLuint create_arb_blt_fragment_program(const WineD3D_GL_Info *gl_info, en return program_id; } +/* GL locking is done by the caller */ static void shader_arb_select(IWineD3DDevice *iface, BOOL usePS, BOOL useVS) { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; struct shader_arb_priv *priv = This->shader_priv; @@ -1831,6 +1754,7 @@ static void shader_arb_select(IWineD3DDevice *iface, BOOL usePS, BOOL useVS) { } } +/* GL locking is done by the caller */ static void shader_arb_select_depth_blt(IWineD3DDevice *iface, enum tex_types tex_type) { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; struct shader_arb_priv *priv = This->shader_priv; @@ -1846,6 +1770,7 @@ static void shader_arb_select_depth_blt(IWineD3DDevice *iface, enum tex_types te glEnable(GL_FRAGMENT_PROGRAM_ARB); } +/* GL locking is done by the caller */ static void shader_arb_deselect_depth_blt(IWineD3DDevice *iface) { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; struct shader_arb_priv *priv = This->shader_priv; @@ -1926,6 +1851,7 @@ static void shader_arb_free(IWineD3DDevice *iface) { struct shader_arb_priv *priv = This->shader_priv; int i; + ENTER_GL(); if(priv->depth_blt_vprogram_id) { GL_EXTCALL(glDeleteProgramsARB(1, &priv->depth_blt_vprogram_id)); } @@ -1934,6 +1860,7 @@ static void shader_arb_free(IWineD3DDevice *iface) { GL_EXTCALL(glDeleteProgramsARB(1, &priv->depth_blt_fprogram_id[i])); } } + LEAVE_GL(); HeapFree(GetProcessHeap(), 0, This->shader_priv); } @@ -1964,6 +1891,7 @@ static void arbfp_add_sRGB_correction(SHADER_BUFFER *buffer, const char *fragcol /* [0.0;1.0] clamping. Not needed, this is done implicitly */ } +/* GL locking is done by the caller */ static GLuint shader_arb_generate_pshader(IWineD3DPixelShader *iface, SHADER_BUFFER *buffer, const struct ps_compile_args *args) { @@ -2009,8 +1937,12 @@ static GLuint shader_arb_generate_pshader(IWineD3DPixelShader *iface, { fragcolor = "R0"; } else { - shader_addline(buffer, "TEMP TMP_COLOR;\n"); - fragcolor = "TMP_COLOR"; + if(args->srgb_correction) { + shader_addline(buffer, "TEMP TMP_COLOR;\n"); + fragcolor = "TMP_COLOR"; + } else { + fragcolor = "result.color"; + } } /* Base Declarations */ @@ -2021,8 +1953,10 @@ static GLuint shader_arb_generate_pshader(IWineD3DPixelShader *iface, if(args->srgb_correction) { arbfp_add_sRGB_correction(buffer, fragcolor, "TMP", "TMP2", "TA", "TB"); + shader_addline(buffer, "MOV result.color, %s;\n", fragcolor); + } else if(reg_maps->shader_version.major < 2) { + shader_addline(buffer, "MOV result.color, %s;\n", fragcolor); } - shader_addline(buffer, "MOV result.color, %s;\n", fragcolor); shader_addline(buffer, "END\n"); /* TODO: change to resource.glObjectHandle or something like that */ @@ -2057,6 +1991,7 @@ static GLuint shader_arb_generate_pshader(IWineD3DPixelShader *iface, return retval; } +/* GL locking is done by the caller */ static GLuint shader_arb_generate_vshader(IWineD3DVertexShader *iface, SHADER_BUFFER *buffer, const struct vs_compile_args *args) { @@ -2217,7 +2152,6 @@ static BOOL shader_arb_color_fixup_supported(struct color_fixup_desc fixup) } static void shader_arb_add_instruction_modifiers(const struct wined3d_shader_instruction *ins) { - BOOL saturate; DWORD shift; char write_mask[20], regstr[50]; SHADER_BUFFER *buffer = ins->ctx->buffer; @@ -2229,14 +2163,15 @@ static void shader_arb_add_instruction_modifiers(const struct wined3d_shader_ins dst = &ins->dst[0]; shift = dst->shift; if(shift == 0) return; /* Saturate alone is handled by the instructions */ - saturate = dst->modifiers & WINED3DSPDM_SATURATE; shader_arb_get_write_mask(ins, dst, write_mask); - shader_arb_get_register_name(ins->ctx->shader, dst->reg.type, - dst->reg.idx, !!dst->reg.rel_addr, regstr, &is_color); + shader_arb_get_register_name(ins->ctx->shader, &dst->reg, regstr, &is_color); - /* Generate a line that does the output modifier computation */ - shader_addline(buffer, "MUL%s %s%s, %s, %s;\n", saturate ? "_SAT" : "", + /* Generate a line that does the output modifier computation + * FIXME: _SAT vs shift? _SAT alone is already handled in the instructions, if this + * maps problems in e.g. _d4_sat modify shader_arb_get_modifier + */ + shader_addline(buffer, "MUL%s %s%s, %s, %s;\n", shader_arb_get_modifier(ins), regstr, write_mask, regstr, shift_tab[shift]); } @@ -2289,14 +2224,14 @@ static const SHADER_HANDLER shader_arb_instruction_handler_table[WINED3DSIH_TABL /* WINED3DSIH_MOV */ shader_hw_mov, /* WINED3DSIH_MOVA */ shader_hw_mov, /* WINED3DSIH_MUL */ shader_hw_map2gl, - /* WINED3DSIH_NOP */ shader_hw_map2gl, + /* WINED3DSIH_NOP */ shader_hw_nop, /* WINED3DSIH_NRM */ shader_hw_nrm, /* WINED3DSIH_PHASE */ NULL, /* WINED3DSIH_POW */ shader_hw_map2gl, - /* WINED3DSIH_RCP */ vshader_hw_rsq_rcp, + /* WINED3DSIH_RCP */ shader_hw_rsq_rcp, /* WINED3DSIH_REP */ NULL, /* WINED3DSIH_RET */ NULL, - /* WINED3DSIH_RSQ */ vshader_hw_rsq_rcp, + /* WINED3DSIH_RSQ */ shader_hw_rsq_rcp, /* WINED3DSIH_SETP */ NULL, /* WINED3DSIH_SGE */ shader_hw_map2gl, /* WINED3DSIH_SGN */ NULL, @@ -2362,6 +2297,7 @@ struct arbfp_ffp_desc }; static void arbfp_enable(IWineD3DDevice *iface, BOOL enable) { + ENTER_GL(); if(enable) { glEnable(GL_FRAGMENT_PROGRAM_ARB); checkGLcall("glEnable(GL_FRAGMENT_PROGRAM_ARB)"); @@ -2369,6 +2305,7 @@ static void arbfp_enable(IWineD3DDevice *iface, BOOL enable) { glDisable(GL_FRAGMENT_PROGRAM_ARB); checkGLcall("glDisable(GL_FRAGMENT_PROGRAM_ARB)"); } + LEAVE_GL(); } static HRESULT arbfp_alloc(IWineD3DDevice *iface) { diff --git a/dlls/wined3d/ati_fragment_shader.c b/dlls/wined3d/ati_fragment_shader.c index a8c137f9b45..1fd34599ed8 100644 --- a/dlls/wined3d/ati_fragment_shader.c +++ b/dlls/wined3d/ati_fragment_shader.c @@ -28,6 +28,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d_shader); WINE_DECLARE_DEBUG_CHANNEL(d3d); +/* GL locking for state handlers is done by the caller. */ + /* Some private defines, Constant associations, etc. * Env bump matrix and per stage constant should be independent, * a stage that bump maps can't read the per state constant @@ -1043,6 +1045,7 @@ static const struct StateEntryTemplate atifs_fragmentstate_template[] = { }; static void atifs_enable(IWineD3DDevice *iface, BOOL enable) { + ENTER_GL(); if(enable) { glEnable(GL_FRAGMENT_SHADER_ATI); checkGLcall("glEnable(GL_FRAGMENT_SHADER_ATI)"); @@ -1050,6 +1053,7 @@ static void atifs_enable(IWineD3DDevice *iface, BOOL enable) { glDisable(GL_FRAGMENT_SHADER_ATI); checkGLcall("glDisable(GL_FRAGMENT_SHADER_ATI)"); } + LEAVE_GL(); } static void atifs_get_caps(WINED3DDEVTYPE devtype, const WineD3D_GL_Info *gl_info, struct fragment_caps *caps) diff --git a/dlls/wined3d/baseshader.c b/dlls/wined3d/baseshader.c index 8b8aef4d15a..1746917e6bb 100644 --- a/dlls/wined3d/baseshader.c +++ b/dlls/wined3d/baseshader.c @@ -246,24 +246,24 @@ static inline void set_bitmap_bit(DWORD *bitmap, DWORD bit) } static void shader_record_register_usage(IWineD3DBaseShaderImpl *This, struct shader_reg_maps *reg_maps, - DWORD register_type, UINT register_idx, BOOL has_rel_addr, BOOL pshader) + const struct wined3d_shader_register *reg, BOOL pshader) { - switch (register_type) + switch (reg->type) { case WINED3DSPR_TEXTURE: /* WINED3DSPR_ADDR */ - if (pshader) reg_maps->texcoord[register_idx] = 1; - else reg_maps->address[register_idx] = 1; + if (pshader) reg_maps->texcoord[reg->idx] = 1; + else reg_maps->address[reg->idx] = 1; break; case WINED3DSPR_TEMP: - reg_maps->temporary[register_idx] = 1; + reg_maps->temporary[reg->idx] = 1; break; case WINED3DSPR_INPUT: - if (!pshader) reg_maps->attributes[register_idx] = 1; + if (!pshader) reg_maps->attributes[reg->idx] = 1; else { - if (has_rel_addr) + if (reg->rel_addr) { /* If relative addressing is used, we must assume that all registers * are used. Even if it is a construct like v3[aL], we can't assume @@ -276,68 +276,68 @@ static void shader_record_register_usage(IWineD3DBaseShaderImpl *This, struct sh } else { - ((IWineD3DPixelShaderImpl *)This)->input_reg_used[register_idx] = TRUE; + ((IWineD3DPixelShaderImpl *)This)->input_reg_used[reg->idx] = TRUE; } } break; case WINED3DSPR_RASTOUT: - if (register_idx == 1) reg_maps->fog = 1; + if (reg->idx == 1) reg_maps->fog = 1; break; case WINED3DSPR_MISCTYPE: - if (pshader && register_idx == 0) reg_maps->vpos = 1; + if (pshader && reg->idx == 0) reg_maps->vpos = 1; break; case WINED3DSPR_CONST: - if (has_rel_addr) + if (reg->rel_addr) { if (!pshader) { - if (register_idx <= ((IWineD3DVertexShaderImpl *)This)->min_rel_offset) - ((IWineD3DVertexShaderImpl *)This)->min_rel_offset = register_idx; - else if (register_idx >= ((IWineD3DVertexShaderImpl *)This)->max_rel_offset) - ((IWineD3DVertexShaderImpl *)This)->max_rel_offset = register_idx; + if (reg->idx <= ((IWineD3DVertexShaderImpl *)This)->min_rel_offset) + ((IWineD3DVertexShaderImpl *)This)->min_rel_offset = reg->idx; + else if (reg->idx >= ((IWineD3DVertexShaderImpl *)This)->max_rel_offset) + ((IWineD3DVertexShaderImpl *)This)->max_rel_offset = reg->idx; } reg_maps->usesrelconstF = TRUE; } else { - set_bitmap_bit(reg_maps->constf, register_idx); + set_bitmap_bit(reg_maps->constf, reg->idx); } break; case WINED3DSPR_CONSTINT: - reg_maps->integer_constants |= (1 << register_idx); + reg_maps->integer_constants |= (1 << reg->idx); break; case WINED3DSPR_CONSTBOOL: - reg_maps->boolean_constants |= (1 << register_idx); + reg_maps->boolean_constants |= (1 << reg->idx); break; default: - TRACE("Not recording register of type %#x and idx %u\n", register_type, register_idx); + TRACE("Not recording register of type %#x and idx %u\n", reg->type, reg->idx); break; } } -static unsigned char get_instr_regcount(enum WINED3D_SHADER_INSTRUCTION_HANDLER instr, int param) +static unsigned int get_instr_extra_regcount(enum WINED3D_SHADER_INSTRUCTION_HANDLER instr, unsigned int param) { switch(instr) { case WINED3DSIH_M4x4: case WINED3DSIH_M3x4: - return param == 1 ? 4 : 1; + return param == 1 ? 3 : 0; case WINED3DSIH_M4x3: case WINED3DSIH_M3x3: - return param == 1 ? 3 : 1; + return param == 1 ? 2 : 0; case WINED3DSIH_M3x2: - return param == 1 ? 2 : 1; + return param == 1 ? 1 : 0; default: - return 1; + return 0; } } @@ -558,8 +558,7 @@ HRESULT shader_get_registers_used(IWineD3DBaseShader *iface, const struct wined3 } else { - shader_record_register_usage(This, reg_maps, dst_param.reg.type, - dst_param.reg.idx, !!dst_param.reg.rel_addr, pshader); + shader_record_register_usage(This, reg_maps, &dst_param.reg, pshader); } /* Declare 1.X samplers implicitly, based on the destination reg. number */ @@ -617,25 +616,17 @@ HRESULT shader_get_registers_used(IWineD3DBaseShader *iface, const struct wined3 for (i = 0; i < limit; ++i) { struct wined3d_shader_src_param src_param, src_rel_addr; + unsigned int count; fe->shader_read_src_param(fe_data, &pToken, &src_param, &src_rel_addr); - switch(get_instr_regcount(ins.handler_idx, i)) + count = get_instr_extra_regcount(ins.handler_idx, i); + + shader_record_register_usage(This, reg_maps, &src_param.reg, pshader); + while (count) { - case 4: - shader_record_register_usage(This, reg_maps, src_param.reg.type, - src_param.reg.idx + 3, !!src_param.reg.rel_addr, pshader); - /* drop through */ - case 3: - shader_record_register_usage(This, reg_maps, src_param.reg.type, - src_param.reg.idx + 2, !!src_param.reg.rel_addr, pshader); - /* drop through */ - case 2: - shader_record_register_usage(This, reg_maps, src_param.reg.type, - src_param.reg.idx + 1, !!src_param.reg.rel_addr, pshader); - /* drop through */ - case 1: - shader_record_register_usage(This, reg_maps, src_param.reg.type, - src_param.reg.idx, !!src_param.reg.rel_addr, pshader); + ++src_param.reg.idx; + shader_record_register_usage(This, reg_maps, &src_param.reg, pshader); + --count; } } } @@ -721,15 +712,14 @@ static void shader_dump_decl_usage(const struct wined3d_shader_semantic *semanti } } -static void shader_dump_register(WINED3DSHADER_PARAM_REGISTER_TYPE register_type, UINT register_idx, - enum wined3d_immconst_type immconst_type, const DWORD *immconst_data, - const struct wined3d_shader_src_param *rel_addr, const struct wined3d_shader_version *shader_version) +static void shader_dump_register(const struct wined3d_shader_register *reg, + const struct wined3d_shader_version *shader_version) { static const char * const rastout_reg_names[] = {"oPos", "oFog", "oPts"}; static const char * const misctype_reg_names[] = {"vPos", "vFace"}; - UINT offset = register_idx; + UINT offset = reg->idx; - switch (register_type) + switch (reg->type) { case WINED3DSPR_TEMP: TRACE("r"); @@ -744,7 +734,7 @@ static void shader_dump_register(WINED3DSHADER_PARAM_REGISTER_TYPE register_type case WINED3DSPR_CONST3: case WINED3DSPR_CONST4: TRACE("c"); - offset = shader_get_float_offset(register_type, register_idx); + offset = shader_get_float_offset(reg->type, reg->idx); break; case WINED3DSPR_TEXTURE: /* vs: case WINED3DSPR_ADDR */ @@ -752,7 +742,7 @@ static void shader_dump_register(WINED3DSHADER_PARAM_REGISTER_TYPE register_type break; case WINED3DSPR_RASTOUT: - TRACE("%s", rastout_reg_names[register_idx]); + TRACE("%s", rastout_reg_names[reg->idx]); break; case WINED3DSPR_COLOROUT: @@ -795,8 +785,8 @@ static void shader_dump_register(WINED3DSHADER_PARAM_REGISTER_TYPE register_type break; case WINED3DSPR_MISCTYPE: - if (register_idx > 1) FIXME("Unhandled misctype register %d\n", register_idx); - else TRACE("%s", misctype_reg_names[register_idx]); + if (reg->idx > 1) FIXME("Unhandled misctype register %d\n", reg->idx); + else TRACE("%s", misctype_reg_names[reg->idx]); break; case WINED3DSPR_PREDICATE: @@ -808,41 +798,41 @@ static void shader_dump_register(WINED3DSHADER_PARAM_REGISTER_TYPE register_type break; default: - TRACE("unhandled_rtype(%#x)", register_type); + TRACE("unhandled_rtype(%#x)", reg->type); break; } - if (register_type == WINED3DSPR_IMMCONST) + if (reg->type == WINED3DSPR_IMMCONST) { TRACE("("); - switch (immconst_type) + switch (reg->immconst_type) { case WINED3D_IMMCONST_FLOAT: - TRACE("%.8e", *(float *)immconst_data); + TRACE("%.8e", *(float *)reg->immconst_data); break; case WINED3D_IMMCONST_FLOAT4: TRACE("%.8e, %.8e, %.8e, %.8e", - *(float *)&immconst_data[0], *(float *)&immconst_data[1], - *(float *)&immconst_data[2], *(float *)&immconst_data[3]); + *(float *)®->immconst_data[0], *(float *)®->immconst_data[1], + *(float *)®->immconst_data[2], *(float *)®->immconst_data[3]); break; default: - TRACE("", immconst_type); + TRACE("", reg->immconst_type); break; } TRACE(")"); } - else if (register_type != WINED3DSPR_RASTOUT && register_type != WINED3DSPR_MISCTYPE) + else if (reg->type != WINED3DSPR_RASTOUT && reg->type != WINED3DSPR_MISCTYPE) { - if (rel_addr) + if (reg->rel_addr) { TRACE("["); - shader_dump_src_param(rel_addr, shader_version); + shader_dump_src_param(reg->rel_addr, shader_version); TRACE(" + "); } TRACE("%u", offset); - if (rel_addr) TRACE("]"); + if (reg->rel_addr) TRACE("]"); } } @@ -851,7 +841,7 @@ void shader_dump_dst_param(const struct wined3d_shader_dst_param *param, { DWORD write_mask = param->write_mask; - shader_dump_register(param->reg.type, param->reg.idx, 0, NULL, param->reg.rel_addr, shader_version); + shader_dump_register(¶m->reg, shader_version); if (write_mask != WINED3DSP_WRITEMASK_ALL) { @@ -885,8 +875,7 @@ void shader_dump_src_param(const struct wined3d_shader_src_param *param, if (src_modifier == WINED3DSPSM_ABS || src_modifier == WINED3DSPSM_ABSNEG) TRACE("abs("); - shader_dump_register(param->reg.type, param->reg.idx, param->reg.immconst_type, - param->reg.immconst_data, param->reg.rel_addr, shader_version); + shader_dump_register(¶m->reg, shader_version); if (src_modifier) { diff --git a/dlls/wined3d/basetexture.c b/dlls/wined3d/basetexture.c index caf2148ba55..9d64b63422f 100644 --- a/dlls/wined3d/basetexture.c +++ b/dlls/wined3d/basetexture.c @@ -288,6 +288,7 @@ HRESULT basetexture_bind(IWineD3DBaseTexture *iface, BOOL srgb, BOOL *set_surfac return hr; } +/* GL locking is done by the caller */ static inline void apply_wrap(const GLint textureDimensions, const DWORD state, const GLint type, BOOL cond_np2) { GLint wrapParm; @@ -313,6 +314,7 @@ static inline void apply_wrap(const GLint textureDimensions, const DWORD state, } } +/* GL locking is done by the caller (state handler) */ void basetexture_apply_state_changes(IWineD3DBaseTexture *iface, const DWORD textureStates[WINED3D_HIGHEST_TEXTURE_STATE + 1], const DWORD samplerStates[WINED3D_HIGHEST_SAMPLER_STATE + 1]) @@ -322,13 +324,15 @@ void basetexture_apply_state_changes(IWineD3DBaseTexture *iface, GLint textureDimensions = IWineD3DBaseTexture_GetTextureDimensions(iface); BOOL cond_np2 = IWineD3DBaseTexture_IsCondNP2(iface); + TRACE("iface %p, textureStates %p, samplerStates %p\n", iface, textureStates, samplerStates); + if(This->baseTexture.is_srgb) { states = This->baseTexture.srgbstates; } else { states = This->baseTexture.states; } - /* ApplyStateChanges relies on the correct texture being bound and loaded. */ + /* This function relies on the correct texture being bound and loaded. */ if(samplerStates[WINED3DSAMP_ADDRESSU] != states[WINED3DTEXSTA_ADDRESSU]) { state = samplerStates[WINED3DSAMP_ADDRESSU]; diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c index 2c6703f3603..02215c8af83 100644 --- a/dlls/wined3d/context.c +++ b/dlls/wined3d/context.c @@ -38,6 +38,7 @@ static IWineD3DDeviceImpl *last_device; /* FBO helper functions */ +/* GL locking is done by the caller */ void context_bind_fbo(IWineD3DDevice *iface, GLenum target, GLuint *fbo) { const IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; @@ -53,12 +54,11 @@ void context_bind_fbo(IWineD3DDevice *iface, GLenum target, GLuint *fbo) checkGLcall("glBindFramebuffer()"); } -static void context_destroy_fbo(IWineD3DDeviceImpl *This, const GLuint *fbo) +/* GL locking is done by the caller */ +static void context_clean_fbo_attachments(IWineD3DDeviceImpl *This) { unsigned int i; - GL_EXTCALL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, *fbo)); - checkGLcall("glBindFramebuffer()"); for (i = 0; i < GL_LIMITS(buffers); ++i) { GL_EXTCALL(glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT + i, GL_TEXTURE_2D, 0, 0)); @@ -66,12 +66,23 @@ static void context_destroy_fbo(IWineD3DDeviceImpl *This, const GLuint *fbo) } GL_EXTCALL(glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, 0, 0)); checkGLcall("glFramebufferTexture2D()"); +} + +/* GL locking is done by the caller */ +static void context_destroy_fbo(IWineD3DDeviceImpl *This, const GLuint *fbo) +{ + GL_EXTCALL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, *fbo)); + checkGLcall("glBindFramebuffer()"); + + context_clean_fbo_attachments(This); + GL_EXTCALL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0)); checkGLcall("glBindFramebuffer()"); GL_EXTCALL(glDeleteFramebuffersEXT(1, fbo)); checkGLcall("glDeleteFramebuffers()"); } +/* GL locking is done by the caller */ static void context_apply_attachment_filter_states(IWineD3DDevice *iface, IWineD3DSurface *surface, BOOL force_preload) { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; @@ -136,6 +147,7 @@ static void context_apply_attachment_filter_states(IWineD3DDevice *iface, IWineD } /* TODO: Handle stencil attachments */ +/* GL locking is done by the caller */ void context_attach_depth_stencil_fbo(IWineD3DDeviceImpl *This, GLenum fbo_target, IWineD3DSurface *depth_stencil, BOOL use_render_buffer) { IWineD3DSurfaceImpl *depth_stencil_impl = (IWineD3DSurfaceImpl *)depth_stencil; @@ -161,6 +173,7 @@ void context_attach_depth_stencil_fbo(IWineD3DDeviceImpl *This, GLenum fbo_targe } } +/* GL locking is done by the caller */ void context_attach_surface_fbo(IWineD3DDeviceImpl *This, GLenum fbo_target, DWORD idx, IWineD3DSurface *surface) { const IWineD3DSurfaceImpl *surface_impl = (IWineD3DSurfaceImpl *)surface; @@ -180,6 +193,7 @@ void context_attach_surface_fbo(IWineD3DDeviceImpl *This, GLenum fbo_target, DWO } } +/* GL locking is done by the caller */ static void context_check_fbo_status(IWineD3DDevice *iface) { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; @@ -230,6 +244,21 @@ static struct fbo_entry *context_create_fbo_entry(IWineD3DDevice *iface) return entry; } +/* GL locking is done by the caller */ +static void context_reuse_fbo_entry(IWineD3DDevice *iface, struct fbo_entry *entry) +{ + IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; + + GL_EXTCALL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, entry->id)); + checkGLcall("glBindFramebuffer()"); + context_clean_fbo_attachments(This); + + memcpy(entry->render_targets, This->render_targets, GL_LIMITS(buffers) * sizeof(*entry->render_targets)); + entry->depth_stencil = This->stencilBufferTarget; + entry->attached = FALSE; +} + +/* GL locking is done by the caller */ static void context_destroy_fbo_entry(IWineD3DDeviceImpl *This, struct fbo_entry *entry) { if (entry->id) @@ -243,6 +272,7 @@ static void context_destroy_fbo_entry(IWineD3DDeviceImpl *This, struct fbo_entry } +/* GL locking is done by the caller */ static struct fbo_entry *context_find_fbo_entry(IWineD3DDevice *iface, WineD3DContext *context) { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; @@ -253,15 +283,30 @@ static struct fbo_entry *context_find_fbo_entry(IWineD3DDevice *iface, WineD3DCo if (!memcmp(entry->render_targets, This->render_targets, GL_LIMITS(buffers) * sizeof(*entry->render_targets)) && entry->depth_stencil == This->stencilBufferTarget) { + list_remove(&entry->entry); + list_add_head(&context->fbo_list, &entry->entry); return entry; } } - entry = context_create_fbo_entry(iface); - list_add_head(&context->fbo_list, &entry->entry); + if (context->fbo_entry_count < WINED3D_MAX_FBO_ENTRIES) + { + entry = context_create_fbo_entry(iface); + list_add_head(&context->fbo_list, &entry->entry); + ++context->fbo_entry_count; + } + else + { + entry = LIST_ENTRY(list_tail(&context->fbo_list), struct fbo_entry, entry); + context_reuse_fbo_entry(iface, entry); + list_remove(&entry->entry); + list_add_head(&context->fbo_list, &entry->entry); + } + return entry; } +/* GL locking is done by the caller */ static void context_apply_fbo_entry(IWineD3DDevice *iface, struct fbo_entry *entry) { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; @@ -307,6 +352,7 @@ static void context_apply_fbo_entry(IWineD3DDevice *iface, struct fbo_entry *ent } } +/* GL locking is done by the caller */ static void context_apply_fbo_state(IWineD3DDevice *iface) { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; @@ -337,6 +383,8 @@ void context_resource_released(IWineD3DDevice *iface, IWineD3DResource *resource { struct fbo_entry *entry, *entry2; + ENTER_GL(); + LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &This->contexts[i]->fbo_list, struct fbo_entry, entry) { BOOL destroyed = FALSE; @@ -354,6 +402,8 @@ void context_resource_released(IWineD3DDevice *iface, IWineD3DResource *resource if (!destroyed && entry->depth_stencil == (IWineD3DSurface *)resource) context_destroy_fbo_entry(This, entry); } + + LEAVE_GL(); } break; @@ -1035,6 +1085,7 @@ void DestroyContext(IWineD3DDeviceImpl *This, WineD3DContext *context) { RemoveContextFromArray(This, context); } +/* GL locking is done by the caller */ static inline void set_blit_dimension(UINT width, UINT height) { glMatrixMode(GL_PROJECTION); checkGLcall("glMatrixMode(GL_PROJECTION)"); @@ -1071,7 +1122,9 @@ static inline void SetupForBlit(IWineD3DDeviceImpl *This, WineD3DContext *contex TRACE("Setting up context %p for blitting\n", context); if(context->last_was_blit) { if(context->blit_w != width || context->blit_h != height) { + ENTER_GL(); set_blit_dimension(width, height); + LEAVE_GL(); context->blit_w = width; context->blit_h = height; /* No need to dirtify here, the states are still dirtified because they weren't * applied since the last SetupForBlit call. Otherwise last_was_blit would not @@ -1086,7 +1139,10 @@ static inline void SetupForBlit(IWineD3DDeviceImpl *This, WineD3DContext *contex /* TODO: Use a display list */ /* Disable shaders */ + ENTER_GL(); This->shader_backend->shader_select((IWineD3DDevice *)This, FALSE, FALSE); + LEAVE_GL(); + Context_MarkStateDirty(context, STATE_VSHADER, StateTable); Context_MarkStateDirty(context, STATE_PIXELSHADER, StateTable); @@ -1227,9 +1283,11 @@ static inline void SetupForBlit(IWineD3DDeviceImpl *This, WineD3DContext *contex glDisable(GL_CLIP_PLANE4); checkGLcall("glDisable(clip plane 4)"); glDisable(GL_CLIP_PLANE5); checkGLcall("glDisable(clip plane 5)"); Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_CLIPPING), StateTable); - LEAVE_GL(); set_blit_dimension(width, height); + + LEAVE_GL(); + context->blit_w = width; context->blit_h = height; Context_MarkStateDirty(context, STATE_VIEWPORT, StateTable); Context_MarkStateDirty(context, STATE_TRANSFORM(WINED3DTS_PROJECTION), StateTable); @@ -1562,7 +1620,9 @@ void ActivateContext(IWineD3DDeviceImpl *This, IWineD3DSurface *target, ContextU case CTXUSAGE_CLEAR: case CTXUSAGE_DRAWPRIM: if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) { + ENTER_GL(); context_apply_fbo_state((IWineD3DDevice *)This); + LEAVE_GL(); } if (context->draw_buffer_dirty) { apply_draw_buffer(This, target, FALSE); @@ -1574,10 +1634,9 @@ void ActivateContext(IWineD3DDeviceImpl *This, IWineD3DSurface *target, ContextU if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) { if (This->render_offscreen) { FIXME("Activating for CTXUSAGE_BLIT for an offscreen target with ORM_FBO. This should be avoided.\n"); + ENTER_GL(); context_bind_fbo((IWineD3DDevice *)This, GL_FRAMEBUFFER_EXT, &context->dst_fbo); context_attach_surface_fbo(This, GL_FRAMEBUFFER_EXT, 0, target); - - ENTER_GL(); GL_EXTCALL(glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, 0)); checkGLcall("glFramebufferRenderbufferEXT"); LEAVE_GL(); @@ -1636,6 +1695,7 @@ void ActivateContext(IWineD3DDeviceImpl *This, IWineD3DSurface *target, ContextU IWineD3DDeviceImpl_FindTexUnitMap(This); + ENTER_GL(); for(i=0; i < context->numDirtyEntries; i++) { dirtyState = context->dirtyArray[i]; idx = dirtyState >> 5; @@ -1643,6 +1703,7 @@ void ActivateContext(IWineD3DDeviceImpl *This, IWineD3DSurface *target, ContextU context->isStateDirty[idx] &= ~(1 << shift); StateTable[dirtyState].apply(dirtyState, This->stateBlock, context); } + LEAVE_GL(); context->numDirtyEntries = 0; /* This makes the whole list clean */ context->last_was_blit = FALSE; break; diff --git a/dlls/wined3d/cubetexture.c b/dlls/wined3d/cubetexture.c index ce5f6b618bc..f29db225c85 100644 --- a/dlls/wined3d/cubetexture.c +++ b/dlls/wined3d/cubetexture.c @@ -257,14 +257,6 @@ static BOOL WINAPI IWineD3DCubeTextureImpl_IsCondNP2(IWineD3DCubeTexture *iface) return FALSE; } -static void WINAPI IWineD3DCubeTextureImpl_ApplyStateChanges(IWineD3DCubeTexture *iface, - const DWORD textureStates[WINED3D_HIGHEST_TEXTURE_STATE + 1], - const DWORD samplerStates[WINED3D_HIGHEST_SAMPLER_STATE + 1]) { - TRACE("(%p) : relay to BaseTexture\n", iface); - basetexture_apply_state_changes((IWineD3DBaseTexture *)iface, textureStates, samplerStates); -} - - /* ******************************************* IWineD3DCubeTexture IWineD3DCubeTexture parts follow ******************************************* */ @@ -399,7 +391,6 @@ const IWineD3DCubeTextureVtbl IWineD3DCubeTexture_Vtbl = IWineD3DCubeTextureImpl_BindTexture, IWineD3DCubeTextureImpl_GetTextureDimensions, IWineD3DCubeTextureImpl_IsCondNP2, - IWineD3DCubeTextureImpl_ApplyStateChanges, /* IWineD3DCubeTexture */ IWineD3DCubeTextureImpl_Destroy, IWineD3DCubeTextureImpl_GetLevelDesc, diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index af50c77ffea..83af654876f 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -2354,7 +2354,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateVertexShader(IWineD3DDevice *ifac IWineD3DVertexShader_FakeSemantics(*ppVertexShader, vertex_declaration); } - hr = IWineD3DVertexShader_SetFunction(*ppVertexShader, pFunction); + hr = IWineD3DVertexShader_SetFunction(*ppVertexShader, pFunction, NULL); if (FAILED(hr)) { WARN("(%p) : Failed to set function, returning %#x\n", iface, hr); @@ -2366,7 +2366,10 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateVertexShader(IWineD3DDevice *ifac return hr; } -static HRESULT WINAPI IWineD3DDeviceImpl_CreatePixelShader(IWineD3DDevice *iface, CONST DWORD *pFunction, IWineD3DPixelShader **ppPixelShader, IUnknown *parent) { +static HRESULT WINAPI IWineD3DDeviceImpl_CreatePixelShader(IWineD3DDevice *iface, + const DWORD *pFunction, const struct wined3d_shader_signature *output_signature, + IWineD3DPixelShader **ppPixelShader, IUnknown *parent) +{ IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; IWineD3DPixelShaderImpl *object; /* NOTE: impl allowed, this is a create */ HRESULT hr = WINED3D_OK; @@ -2389,7 +2392,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreatePixelShader(IWineD3DDevice *iface TRACE("(%p) : Created pixel shader %p\n", This, *ppPixelShader); - hr = IWineD3DPixelShader_SetFunction(*ppPixelShader, pFunction); + hr = IWineD3DPixelShader_SetFunction(*ppPixelShader, pFunction, output_signature); if (FAILED(hr)) { WARN("(%p) : Failed to set function, returning %#x\n", iface, hr); @@ -2831,11 +2834,15 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Uninit3D(IWineD3DDevice *iface, D3DCB_D * private data, it might contain opengl pointers */ if(This->depth_blt_texture) { + ENTER_GL(); glDeleteTextures(1, &This->depth_blt_texture); + LEAVE_GL(); This->depth_blt_texture = 0; } if (This->depth_blt_rb) { + ENTER_GL(); GL_EXTCALL(glDeleteRenderbuffersEXT(1, &This->depth_blt_rb)); + LEAVE_GL(); This->depth_blt_rb = 0; This->depth_blt_rb_w = 0; This->depth_blt_rb_h = 0; diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c index d1f851abd1a..825d8f5a174 100644 --- a/dlls/wined3d/directx.c +++ b/dlls/wined3d/directx.c @@ -268,7 +268,7 @@ static BOOL WineD3D_CreateFakeGLContext(void) { wined3d_fake_gl_context_foreign = FALSE; /* We need a fake window as a hdc retrieved using GetDC(0) can't be used for much GL purposes */ - wined3d_fake_gl_context_hwnd = CreateWindowA("WineD3D_OpenGL", "WineD3D fake window", WS_OVERLAPPEDWINDOW, 10, 10, 10, 10, NULL, NULL, NULL, NULL); + wined3d_fake_gl_context_hwnd = CreateWindowA(WINED3D_OPENGL_WINDOW_CLASS_NAME, "WineD3D fake window", WS_OVERLAPPEDWINDOW, 10, 10, 10, 10, NULL, NULL, NULL, NULL); if(!wined3d_fake_gl_context_hwnd) { ERR("HWND creation failed!\n"); goto fail; @@ -453,6 +453,7 @@ static void select_shader_max_constants( * IWineD3D parts follows **********************************************************/ +/* GL locking is done by the caller */ static inline BOOL test_arb_vs_offset_limit(const WineD3D_GL_Info *gl_info) { GLuint prog; @@ -1271,10 +1272,20 @@ static BOOL IWineD3DImpl_FillGLCaps(WineD3D_GL_Info *gl_info) { break; case VENDOR_ATI: if(WINE_D3D9_CAPABLE(gl_info)) { + /* Radeon R7xx HD4800 - highend */ + if (strstr(gl_info->gl_renderer, "HD 4800") || + strstr(gl_info->gl_renderer, "HD 4830") || + strstr(gl_info->gl_renderer, "HD 4850") || + strstr(gl_info->gl_renderer, "HD 4870") || + strstr(gl_info->gl_renderer, "HD 4890")) + { + gl_info->gl_card = CARD_ATI_RADEON_HD4800; + vidmem = 512; /* HD4800 cards use 512-1024MB, up to 2048MB for X2 version */ + } /* Radeon R6xx HD2900/HD3800 - highend */ - if (strstr(gl_info->gl_renderer, "HD 2900") || - strstr(gl_info->gl_renderer, "HD 3870") || - strstr(gl_info->gl_renderer, "HD 3850")) + else if (strstr(gl_info->gl_renderer, "HD 2900") || + strstr(gl_info->gl_renderer, "HD 3870") || + strstr(gl_info->gl_renderer, "HD 3850")) { gl_info->gl_card = CARD_ATI_RADEON_HD2900; vidmem = 512; /* HD2900/HD3800 uses 256-1024MB */ @@ -3907,6 +3918,8 @@ static void test_pbo_functionality(WineD3D_GL_Info *gl_info) { return; } + ENTER_GL(); + while(glGetError()); glGenTextures(1, &texture); glBindTexture(GL_TEXTURE_2D, texture); @@ -3934,6 +3947,8 @@ static void test_pbo_functionality(WineD3D_GL_Info *gl_info) { GL_EXTCALL(glDeleteBuffersARB(1, &pbo)); checkGLcall("PBO test cleanup\n"); + LEAVE_GL(); + if(memcmp(check, pattern, sizeof(check)) != 0) { WARN_(d3d_caps)("PBO test failed, read back data doesn't match original\n"); WARN_(d3d_caps)("Disabling PBOs. This may result in slower performance\n"); @@ -4003,6 +4018,7 @@ static const struct driver_version_information driver_version_table[] = { {VENDOR_ATI, CARD_ATI_RADEON_HD2300, "ATI Mobility Radeon HD 2300", 6, 14, 10, 6764 }, {VENDOR_ATI, CARD_ATI_RADEON_HD2600, "ATI Mobility Radeon HD 2600", 6, 14, 10, 6764 }, {VENDOR_ATI, CARD_ATI_RADEON_HD2900, "ATI Radeon HD 2900 XT", 6, 14, 10, 6764 }, + {VENDOR_ATI, CARD_ATI_RADEON_HD4800, "ATI Radeon HD 4800 Series", 6, 14, 10, 6764 }, /* TODO: Add information about legacy ATI hardware, Intel and other cards */ }; diff --git a/dlls/wined3d/drawprim.c b/dlls/wined3d/drawprim.c index 68821b44db0..e655b1ca625 100644 --- a/dlls/wined3d/drawprim.c +++ b/dlls/wined3d/drawprim.c @@ -32,6 +32,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d_draw); #include #include +/* GL locking is done by the caller */ static void drawStridedFast(IWineD3DDevice *iface, GLenum primitive_type, UINT min_vertex_idx, UINT max_vertex_idx, UINT count, UINT idx_size, const void *idx_data, UINT start_idx) @@ -68,6 +69,7 @@ static void drawStridedFast(IWineD3DDevice *iface, GLenum primitive_type, * Slower GL version which extracts info about each vertex in turn */ +/* GL locking is done by the caller */ static void drawStridedSlow(IWineD3DDevice *iface, const struct wined3d_stream_info *si, UINT NumVertexes, GLenum glPrimType, const void *idxData, UINT idxSize, UINT minIndex, UINT startIdx) { @@ -295,6 +297,7 @@ static void drawStridedSlow(IWineD3DDevice *iface, const struct wined3d_stream_i checkGLcall("glEnd and previous calls"); } +/* GL locking is done by the caller */ static inline void send_attribute(IWineD3DDeviceImpl *This, WINED3DFORMAT format, const UINT index, const void *ptr) { switch(format) @@ -397,6 +400,7 @@ static inline void send_attribute(IWineD3DDeviceImpl *This, WINED3DFORMAT format } } +/* GL locking is done by the caller */ static void drawStridedSlowVs(IWineD3DDevice *iface, const struct wined3d_stream_info *si, UINT numberOfVertices, GLenum glPrimitiveType, const void *idxData, UINT idxSize, UINT minIndex, UINT startIdx) { @@ -457,6 +461,7 @@ static void drawStridedSlowVs(IWineD3DDevice *iface, const struct wined3d_stream glEnd(); } +/* GL locking is done by the caller */ static inline void drawStridedInstanced(IWineD3DDevice *iface, const struct wined3d_stream_info *si, UINT numberOfVertices, GLenum glPrimitiveType, const void *idxData, UINT idxSize, UINT minIndex, UINT startIdx) diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index ca503050646..a9061992083 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -124,6 +124,7 @@ typedef struct { /** Prints the GLSL info log which will contain error messages if they exist */ +/* GL locking is done by the caller */ static void print_glsl_info_log(const WineD3D_GL_Info *gl_info, GLhandleARB obj) { int infologLength = 0; @@ -181,6 +182,7 @@ static void print_glsl_info_log(const WineD3D_GL_Info *gl_info, GLhandleARB obj) /** * Loads (pixel shader) samplers */ +/* GL locking is done by the caller */ static void shader_glsl_load_psamplers(const WineD3D_GL_Info *gl_info, DWORD *tex_unit_map, GLhandleARB programId) { GLint name_loc; @@ -204,6 +206,7 @@ static void shader_glsl_load_psamplers(const WineD3D_GL_Info *gl_info, DWORD *te } } +/* GL locking is done by the caller */ static void shader_glsl_load_vsamplers(const WineD3D_GL_Info *gl_info, DWORD *tex_unit_map, GLhandleARB programId) { GLint name_loc; @@ -227,6 +230,7 @@ static void shader_glsl_load_vsamplers(const WineD3D_GL_Info *gl_info, DWORD *te } } +/* GL locking is done by the caller */ static inline void walk_constant_heap(const WineD3D_GL_Info *gl_info, const float *constants, const GLint *constant_locations, const struct constant_heap *heap, unsigned char *stack, DWORD version) { @@ -288,6 +292,7 @@ static inline void walk_constant_heap(const WineD3D_GL_Info *gl_info, const floa checkGLcall("walk_constant_heap()"); } +/* GL locking is done by the caller */ static inline void apply_clamped_constant(const WineD3D_GL_Info *gl_info, GLint location, const GLfloat *data) { GLfloat clamped_constant[4]; @@ -302,6 +307,7 @@ static inline void apply_clamped_constant(const WineD3D_GL_Info *gl_info, GLint GL_EXTCALL(glUniform4fvARB(location, 1, clamped_constant)); } +/* GL locking is done by the caller */ static inline void walk_constant_heap_clamped(const WineD3D_GL_Info *gl_info, const float *constants, const GLint *constant_locations, const struct constant_heap *heap, unsigned char *stack, DWORD version) { @@ -362,6 +368,7 @@ static inline void walk_constant_heap_clamped(const WineD3D_GL_Info *gl_info, co } /* Loads floating point constants (aka uniforms) into the currently set GLSL program. */ +/* GL locking is done by the caller */ static void shader_glsl_load_constantsF(IWineD3DBaseShaderImpl *This, const WineD3D_GL_Info *gl_info, const float *constants, const GLint *constant_locations, const struct constant_heap *heap, unsigned char *stack, UINT version) @@ -392,6 +399,7 @@ static void shader_glsl_load_constantsF(IWineD3DBaseShaderImpl *This, const Wine } /* Loads integer constants (aka uniforms) into the currently set GLSL program. */ +/* GL locking is done by the caller */ static void shader_glsl_load_constantsI(IWineD3DBaseShaderImpl *This, const WineD3D_GL_Info *gl_info, const GLint locations[MAX_CONST_I], const int *constants, WORD constants_set) { @@ -428,6 +436,7 @@ static void shader_glsl_load_constantsI(IWineD3DBaseShaderImpl *This, const Wine } /* Loads boolean constants (aka uniforms) into the currently set GLSL program. */ +/* GL locking is done by the caller */ static void shader_glsl_load_constantsB(IWineD3DBaseShaderImpl *This, const WineD3D_GL_Info *gl_info, GLhandleARB programId, const BOOL *constants, WORD constants_set) { @@ -487,6 +496,7 @@ static void reset_program_constant_version(void *value, void *context) /** * Loads the texture dimensions for NP2 fixup into the currently set GLSL program. */ +/* GL locking is done by the caller (state handler) */ static void shader_glsl_load_np2fixup_constants( IWineD3DDevice* device, char usePixelShader, @@ -529,6 +539,7 @@ static void shader_glsl_load_np2fixup_constants( /** * Loads the app-supplied constants into the currently set GLSL program. */ +/* GL locking is done by the caller (state handler) */ static void shader_glsl_load_constants( IWineD3DDevice* device, char usePixelShader, @@ -1175,7 +1186,7 @@ static void shader_glsl_get_register_name(const struct wined3d_shader_register * case WINED3DSPR_COLOROUT: if (reg->idx >= GL_LIMITS(buffers)) - WARN("Write to render target %u, only %d supported\n", reg->idx, 4); + WARN("Write to render target %u, only %d supported\n", reg->idx, GL_LIMITS(buffers)); if (GL_SUPPORT(ARB_DRAW_BUFFERS)) sprintf(register_name, "gl_FragData[%u]", reg->idx); /* On older cards with GLSL support like the GeforceFX there's only one buffer. */ @@ -3197,6 +3208,7 @@ static struct glsl_shader_prog_link *get_glsl_program_entry(struct shader_glsl_p return hash_table_get(priv->glsl_program_lookup, &key); } +/* GL locking is done by the caller */ static void delete_glsl_program_entry(struct shader_glsl_priv *priv, const WineD3D_GL_Info *gl_info, struct glsl_shader_prog_link *entry) { @@ -3363,6 +3375,7 @@ static void handle_ps3_input(SHADER_BUFFER *buffer, const WineD3D_GL_Info *gl_in HeapFree(GetProcessHeap(), 0, set); } +/* GL locking is done by the caller */ static GLhandleARB generate_param_reorder_function(IWineD3DVertexShader *vertexshader, IWineD3DPixelShader *pixelshader, const WineD3D_GL_Info *gl_info) { @@ -3508,6 +3521,7 @@ static GLhandleARB generate_param_reorder_function(IWineD3DVertexShader *vertexs return ret; } +/* GL locking is done by the caller */ static void hardcode_local_constants(IWineD3DBaseShaderImpl *shader, const WineD3D_GL_Info *gl_info, GLhandleARB programId, char prefix) { @@ -3533,6 +3547,8 @@ static void hardcode_local_constants(IWineD3DBaseShaderImpl *shader, const WineD * the program in the hash table. If it creates a program, it will link the * given objects, too. */ + +/* GL locking is done by the caller */ static void set_glsl_shader_program(IWineD3DDevice *iface, BOOL use_ps, BOOL use_vs) { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; struct shader_glsl_priv *priv = This->shader_priv; @@ -3738,6 +3754,7 @@ static void set_glsl_shader_program(IWineD3DDevice *iface, BOOL use_ps, BOOL use } } +/* GL locking is done by the caller */ static GLhandleARB create_glsl_blt_shader(const WineD3D_GL_Info *gl_info, enum tex_types tex_type) { GLhandleARB program_id; @@ -3812,6 +3829,7 @@ static GLhandleARB create_glsl_blt_shader(const WineD3D_GL_Info *gl_info, enum t return program_id; } +/* GL locking is done by the caller */ static void shader_glsl_select(IWineD3DDevice *iface, BOOL usePS, BOOL useVS) { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; struct shader_glsl_priv *priv = This->shader_priv; @@ -3841,6 +3859,7 @@ static void shader_glsl_select(IWineD3DDevice *iface, BOOL usePS, BOOL useVS) { checkGLcall("glUseProgramObjectARB"); } +/* GL locking is done by the caller */ static void shader_glsl_select_depth_blt(IWineD3DDevice *iface, enum tex_types tex_type) { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; const WineD3D_GL_Info *gl_info = &This->adapter->gl_info; @@ -3858,6 +3877,7 @@ static void shader_glsl_select_depth_blt(IWineD3DDevice *iface, enum tex_types t } } +/* GL locking is done by the caller */ static void shader_glsl_deselect_depth_blt(IWineD3DDevice *iface) { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; const WineD3D_GL_Info *gl_info = &This->adapter->gl_info; @@ -3889,12 +3909,20 @@ static void shader_glsl_destroy(IWineD3DBaseShader *iface) { ps = (IWineD3DPixelShaderImpl *) This; if(ps->num_gl_shaders == 0) return; if (priv->glsl_program && (IWineD3DBaseShader *)priv->glsl_program->pshader == iface) + { + ENTER_GL(); shader_glsl_select(This->baseShader.device, FALSE, FALSE); + LEAVE_GL(); + } } else { vs = (IWineD3DVertexShaderImpl *) This; if(vs->num_gl_shaders == 0) return; if (priv->glsl_program && (IWineD3DBaseShader *)priv->glsl_program->vshader == iface) + { + ENTER_GL(); shader_glsl_select(This->baseShader.device, FALSE, FALSE); + LEAVE_GL(); + } } linked_programs = &This->baseShader.linked_programs; @@ -3903,6 +3931,7 @@ static void shader_glsl_destroy(IWineD3DBaseShader *iface) { if (linked_programs->next) { struct glsl_shader_prog_link *entry, *entry2; + ENTER_GL(); if(pshader) { LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, linked_programs, struct glsl_shader_prog_link, pshader_entry) { delete_glsl_program_entry(priv, gl_info, entry); @@ -3912,6 +3941,7 @@ static void shader_glsl_destroy(IWineD3DBaseShader *iface) { delete_glsl_program_entry(priv, gl_info, entry); } } + LEAVE_GL(); } if(pshader) { @@ -4038,6 +4068,7 @@ static void shader_glsl_free(IWineD3DDevice *iface) { struct shader_glsl_priv *priv = This->shader_priv; int i; + ENTER_GL(); for (i = 0; i < tex_type_count; ++i) { if (priv->depth_blt_program[i]) @@ -4045,6 +4076,7 @@ static void shader_glsl_free(IWineD3DDevice *iface) { GL_EXTCALL(glDeleteObjectARB(priv->depth_blt_program[i])); } } + LEAVE_GL(); hash_table_destroy(priv->glsl_program_lookup, NULL, NULL); constant_heap_free(&priv->pconst_heap); @@ -4059,6 +4091,7 @@ static BOOL shader_glsl_dirty_const(IWineD3DDevice *iface) { return FALSE; } +/* GL locking is done by the caller */ static GLuint shader_glsl_generate_pshader(IWineD3DPixelShader *iface, SHADER_BUFFER *buffer, const struct ps_compile_args *args) { @@ -4165,6 +4198,7 @@ static GLuint shader_glsl_generate_pshader(IWineD3DPixelShader *iface, return shader_obj; } +/* GL locking is done by the caller */ static GLuint shader_glsl_generate_vshader(IWineD3DVertexShader *iface, SHADER_BUFFER *buffer, const struct vs_compile_args *args) { diff --git a/dlls/wined3d/nvidia_texture_shader.c b/dlls/wined3d/nvidia_texture_shader.c index f7e331de3d4..f9a81bc84db 100644 --- a/dlls/wined3d/nvidia_texture_shader.c +++ b/dlls/wined3d/nvidia_texture_shader.c @@ -29,6 +29,9 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d); #define GLINFO_LOCATION stateblock->wineD3DDevice->adapter->gl_info + +/* GL locking for state handlers is done by the caller. */ + static void nvts_activate_dimensions(DWORD stage, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) { BOOL bumpmap = FALSE; @@ -595,6 +598,7 @@ static void nvrc_texfactor(DWORD state, IWineD3DStateBlockImpl *stateblock, Wine static void nvrc_enable(IWineD3DDevice *iface, BOOL enable) { } static void nvts_enable(IWineD3DDevice *iface, BOOL enable) { + ENTER_GL(); if(enable) { glEnable(GL_TEXTURE_SHADER_NV); checkGLcall("glEnable(GL_TEXTURE_SHADER_NV)"); @@ -602,6 +606,7 @@ static void nvts_enable(IWineD3DDevice *iface, BOOL enable) { glDisable(GL_TEXTURE_SHADER_NV); checkGLcall("glDisable(GL_TEXTURE_SHADER_NV)"); } + LEAVE_GL(); } static void nvrc_fragment_get_caps(WINED3DDEVTYPE devtype, const WineD3D_GL_Info *gl_info, struct fragment_caps *pCaps) diff --git a/dlls/wined3d/pixelshader.c b/dlls/wined3d/pixelshader.c index 9b001db65f3..6045085a367 100644 --- a/dlls/wined3d/pixelshader.c +++ b/dlls/wined3d/pixelshader.c @@ -204,8 +204,9 @@ static void pshader_set_limits(IWineD3DPixelShaderImpl *This) } } -static HRESULT WINAPI IWineD3DPixelShaderImpl_SetFunction(IWineD3DPixelShader *iface, CONST DWORD *pFunction) { - +static HRESULT WINAPI IWineD3DPixelShaderImpl_SetFunction(IWineD3DPixelShader *iface, + const DWORD *pFunction, const struct wined3d_shader_signature *output_signature) +{ IWineD3DPixelShaderImpl *This =(IWineD3DPixelShaderImpl *)iface; unsigned int i, highest_reg_used = 0, num_regs_used = 0; shader_reg_maps *reg_maps = &This->baseShader.reg_maps; @@ -221,7 +222,7 @@ static HRESULT WINAPI IWineD3DPixelShaderImpl_SetFunction(IWineD3DPixelShader *i return WINED3DERR_INVALIDCALL; } This->baseShader.frontend = fe; - This->baseShader.frontend_data = fe->shader_init(pFunction); + This->baseShader.frontend_data = fe->shader_init(pFunction, output_signature); if (!This->baseShader.frontend_data) { FIXME("Failed to initialize frontend.\n"); @@ -337,6 +338,7 @@ static void pixelshader_update_samplers(struct shader_reg_maps *reg_maps, IWineD } } +/* GL locking is done by the caller */ static GLuint pixelshader_compile(IWineD3DPixelShaderImpl *This, const struct ps_compile_args *args) { CONST DWORD *function = This->baseShader.function; @@ -439,6 +441,7 @@ void find_ps_compile_args(IWineD3DPixelShaderImpl *shader, IWineD3DStateBlockImp } } +/* GL locking is done by the caller */ GLuint find_gl_pshader(IWineD3DPixelShaderImpl *shader, const struct ps_compile_args *args) { UINT i; diff --git a/dlls/wined3d/shader_sm1.c b/dlls/wined3d/shader_sm1.c index 211566a5d1a..a626d52a763 100644 --- a/dlls/wined3d/shader_sm1.c +++ b/dlls/wined3d/shader_sm1.c @@ -410,7 +410,7 @@ static int shader_skip_unrecognized(const struct wined3d_sm1_data *priv, const D return tokens_read; } -static void *shader_sm1_init(const DWORD *byte_code) +static void *shader_sm1_init(const DWORD *byte_code, const struct wined3d_shader_signature *output_signature) { struct wined3d_sm1_data *priv = HeapAlloc(GetProcessHeap(), 0, sizeof(*priv)); if (!priv) @@ -419,6 +419,11 @@ static void *shader_sm1_init(const DWORD *byte_code) return NULL; } + if (output_signature) + { + FIXME("SM 1-3 shader shouldn't have output signatures.\n"); + } + switch (*byte_code >> 16) { case WINED3D_SM1_VS: diff --git a/dlls/wined3d/shader_sm4.c b/dlls/wined3d/shader_sm4.c index 4e9f8d5c2da..5cc445db69a 100644 --- a/dlls/wined3d/shader_sm4.c +++ b/dlls/wined3d/shader_sm4.c @@ -71,6 +71,7 @@ struct wined3d_sm4_data { struct wined3d_shader_version shader_version; const DWORD *end; + const struct wined3d_shader_signature *output_signature; }; struct wined3d_sm4_opcode_info @@ -81,6 +82,13 @@ struct wined3d_sm4_opcode_info UINT src_count; }; +struct sysval_map +{ + enum wined3d_sysval_semantic sysval; + WINED3DSHADER_PARAM_REGISTER_TYPE register_type; + UINT register_idx; +}; + static const struct wined3d_sm4_opcode_info opcode_table[] = { {WINED3D_SM4_OP_ADD, WINED3DSIH_ADD, 1, 2}, @@ -100,6 +108,19 @@ static const WINED3DSHADER_PARAM_REGISTER_TYPE register_type_table[] = /* WINED3D_SM4_RT_IMMCONST */ WINED3DSPR_IMMCONST, }; +static const struct sysval_map sysval_map[] = +{ + {WINED3D_SV_DEPTH, WINED3DSPR_DEPTHOUT, 0}, + {WINED3D_SV_TARGET0, WINED3DSPR_COLOROUT, 0}, + {WINED3D_SV_TARGET1, WINED3DSPR_COLOROUT, 1}, + {WINED3D_SV_TARGET2, WINED3DSPR_COLOROUT, 2}, + {WINED3D_SV_TARGET3, WINED3DSPR_COLOROUT, 3}, + {WINED3D_SV_TARGET4, WINED3DSPR_COLOROUT, 4}, + {WINED3D_SV_TARGET5, WINED3DSPR_COLOROUT, 5}, + {WINED3D_SV_TARGET6, WINED3DSPR_COLOROUT, 6}, + {WINED3D_SV_TARGET7, WINED3DSPR_COLOROUT, 7}, +}; + static const struct wined3d_sm4_opcode_info *get_opcode_info(enum wined3d_sm4_opcode opcode) { unsigned int i; @@ -112,7 +133,53 @@ static const struct wined3d_sm4_opcode_info *get_opcode_info(enum wined3d_sm4_op return NULL; } -static void *shader_sm4_init(const DWORD *byte_code) +static void map_sysval(enum wined3d_sysval_semantic sysval, struct wined3d_shader_register *reg) +{ + unsigned int i; + + for (i = 0; i < sizeof(sysval_map) / sizeof(*sysval_map); ++i) + { + if (sysval == sysval_map[i].sysval) + { + reg->type = sysval_map[i].register_type; + reg->idx = sysval_map[i].register_idx; + } + } +} + +static void map_register(struct wined3d_sm4_data *priv, struct wined3d_shader_register *reg) +{ + switch (priv->shader_version.type) + { + case WINED3D_SHADER_TYPE_PIXEL: + if (reg->type == WINED3DSPR_OUTPUT) + { + unsigned int i; + const struct wined3d_shader_signature *s = priv->output_signature; + + if (!s) + { + ERR("Shader has no output signature, unable to map register.\n"); + break; + } + + for (i = 0; i < s->element_count; ++i) + { + if (s->elements[i].register_idx == reg->idx) + { + map_sysval(s->elements[i].sysval_semantic, reg); + break; + } + } + } + break; + + default: + break; + } +} + +static void *shader_sm4_init(const DWORD *byte_code, const struct wined3d_shader_signature *output_signature) { struct wined3d_sm4_data *priv = HeapAlloc(GetProcessHeap(), 0, sizeof(*priv)); if (!priv) @@ -121,6 +188,8 @@ static void *shader_sm4_init(const DWORD *byte_code) return NULL; } + priv->output_signature = output_signature; + return priv; } @@ -193,6 +262,7 @@ static void shader_sm4_read_opcode(void *data, const DWORD **ptr, struct wined3d static void shader_sm4_read_src_param(void *data, const DWORD **ptr, struct wined3d_shader_src_param *src_param, struct wined3d_shader_src_param *src_rel_addr) { + struct wined3d_sm4_data *priv = data; DWORD token = *(*ptr)++; enum wined3d_sm4_register_type register_type; @@ -240,11 +310,14 @@ static void shader_sm4_read_src_param(void *data, const DWORD **ptr, struct wine src_param->modifiers = 0; src_param->reg.rel_addr = NULL; + + map_register(priv, &src_param->reg); } static void shader_sm4_read_dst_param(void *data, const DWORD **ptr, struct wined3d_shader_dst_param *dst_param, struct wined3d_shader_src_param *dst_rel_addr) { + struct wined3d_sm4_data *priv = data; DWORD token = *(*ptr)++; UINT register_idx = *(*ptr)++; enum wined3d_sm4_register_type register_type; @@ -265,6 +338,8 @@ static void shader_sm4_read_dst_param(void *data, const DWORD **ptr, struct wine dst_param->modifiers = 0; dst_param->shift = 0; dst_param->reg.rel_addr = NULL; + + map_register(priv, &dst_param->reg); } static void shader_sm4_read_semantic(const DWORD **ptr, struct wined3d_shader_semantic *semantic) diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c index ad1593c7196..061f4738222 100644 --- a/dlls/wined3d/state.c +++ b/dlls/wined3d/state.c @@ -36,6 +36,8 @@ WINE_DECLARE_DEBUG_CHANNEL(d3d_shader); #define GLINFO_LOCATION stateblock->wineD3DDevice->adapter->gl_info +/* GL locking for state handlers is done by the caller. */ + static void state_blendop(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context); static void state_nogl(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) { @@ -3308,7 +3310,7 @@ static void sampler_texmatrix(DWORD state, IWineD3DStateBlockImpl *stateblock, W if(!texture) return; /* The fixed function np2 texture emulation uses the texture matrix to fix up the coordinates - * IWineD3DBaseTexture::ApplyStateChanges multiplies the set matrix with a fixup matrix. Before the + * basetexture_apply_state_changes() multiplies the set matrix with a fixup matrix. Before the * scaling is reapplied or removed, the texture matrix has to be reapplied * * The mapped stage is already active because the sampler() function below, which is part of the @@ -3356,7 +3358,8 @@ static void sampler(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DCont IWineD3DBaseTextureImpl *tex_impl = (IWineD3DBaseTextureImpl *) stateblock->textures[sampler]; tex_impl->baseTexture.internal_preload(stateblock->textures[sampler], srgb ? SRGB_SRGB : SRGB_RGB); IWineD3DBaseTexture_BindTexture(stateblock->textures[sampler], srgb); - IWineD3DBaseTexture_ApplyStateChanges(stateblock->textures[sampler], stateblock->textureState[sampler], stateblock->samplerState[sampler]); + basetexture_apply_state_changes(stateblock->textures[sampler], + stateblock->textureState[sampler], stateblock->samplerState[sampler]); if (GL_SUPPORT(EXT_TEXTURE_LOD_BIAS)) { tmpvalue.d = stateblock->samplerState[sampler][WINED3DSAMP_MIPMAPLODBIAS]; diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c index 9e9d55c5b33..8fc0d285533 100644 --- a/dlls/wined3d/surface.c +++ b/dlls/wined3d/surface.c @@ -38,7 +38,7 @@ static void d3dfmt_p8_init_palette(IWineD3DSurfaceImpl *This, BYTE table[256][4] static void d3dfmt_p8_upload_palette(IWineD3DSurface *iface, CONVERT_TYPES convert); static void surface_remove_pbo(IWineD3DSurfaceImpl *This); -void surface_force_reload(IWineD3DSurface *iface) +static void surface_force_reload(IWineD3DSurface *iface) { IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface; @@ -426,6 +426,7 @@ static void surface_allocate_surface(IWineD3DSurfaceImpl *This, GLenum internal, /* In D3D the depth stencil dimensions have to be greater than or equal to the * render target dimensions. With FBOs, the dimensions have to be an exact match. */ /* TODO: We should synchronize the renderbuffer's content with the texture's content. */ +/* GL locking is done by the caller */ void surface_set_compatible_renderbuffer(IWineD3DSurface *iface, unsigned int width, unsigned int height) { IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface; renderbuffer_entry_t *entry; @@ -2263,7 +2264,9 @@ static void d3dfmt_p8_upload_palette(IWineD3DSurface *iface, CONVERT_TYPES conve if(GL_SUPPORT(EXT_PALETTED_TEXTURE)) { TRACE("Using GL_EXT_PALETTED_TEXTURE for 8-bit paletted texture support\n"); + ENTER_GL(); GL_EXTCALL(glColorTableEXT(This->glDescription.target,GL_RGBA,256,GL_RGBA,GL_UNSIGNED_BYTE, table)); + LEAVE_GL(); } else { @@ -2271,6 +2274,8 @@ static void d3dfmt_p8_upload_palette(IWineD3DSurface *iface, CONVERT_TYPES conve * The 8bit pixel data will be used as an index in this palette texture to retrieve the final color. */ TRACE("Using fragment shaders for emulating 8-bit paletted texture support\n"); + ENTER_GL(); + /* Create the fragment program if we don't have it */ if(!device->paletteConversionShader) { @@ -2310,6 +2315,8 @@ static void d3dfmt_p8_upload_palette(IWineD3DSurface *iface, CONVERT_TYPES conve /* Rebind the texture because it isn't bound anymore */ glBindTexture(This->glDescription.target, This->glDescription.textureName); + + LEAVE_GL(); } } @@ -4073,6 +4080,7 @@ static void surface_get_depth_blt_info(GLenum target, GLsizei w, GLsizei h, stru } } +/* GL locking is done by the caller */ static void surface_depth_blt(IWineD3DSurfaceImpl *This, GLuint texture, GLsizei w, GLsizei h, GLenum target) { IWineD3DDeviceImpl *device = This->resource.wineD3DDevice; @@ -4847,13 +4855,16 @@ static void ffp_blit_free(IWineD3DDevice *iface) { } static HRESULT ffp_blit_set(IWineD3DDevice *iface, const struct GlPixelFormatDesc *format_desc, GLenum textype, UINT width, UINT height) { + ENTER_GL(); glEnable(textype); checkGLcall("glEnable(textype)"); + LEAVE_GL(); return WINED3D_OK; } static void ffp_blit_unset(IWineD3DDevice *iface) { IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *) iface; + ENTER_GL(); glDisable(GL_TEXTURE_2D); checkGLcall("glDisable(GL_TEXTURE_2D)"); if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) { @@ -4864,6 +4875,7 @@ static void ffp_blit_unset(IWineD3DDevice *iface) { glDisable(GL_TEXTURE_RECTANGLE_ARB); checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)"); } + LEAVE_GL(); } static BOOL ffp_blit_color_fixup_supported(struct color_fixup_desc fixup) diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c index dda43537cfc..5981a33d62b 100644 --- a/dlls/wined3d/texture.c +++ b/dlls/wined3d/texture.c @@ -271,13 +271,6 @@ static BOOL WINAPI IWineD3DTextureImpl_IsCondNP2(IWineD3DTexture *iface) { return This->cond_np2; } -static void WINAPI IWineD3DTextureImpl_ApplyStateChanges(IWineD3DTexture *iface, - const DWORD textureStates[WINED3D_HIGHEST_TEXTURE_STATE + 1], - const DWORD samplerStates[WINED3D_HIGHEST_SAMPLER_STATE + 1]) { - TRACE("(%p) : relay to BaseTexture\n", iface); - basetexture_apply_state_changes((IWineD3DBaseTexture *)iface, textureStates, samplerStates); -} - /* ******************************************* IWineD3DTexture IWineD3DTexture parts follow ******************************************* */ @@ -401,7 +394,6 @@ const IWineD3DTextureVtbl IWineD3DTexture_Vtbl = IWineD3DTextureImpl_BindTexture, IWineD3DTextureImpl_GetTextureDimensions, IWineD3DTextureImpl_IsCondNP2, - IWineD3DTextureImpl_ApplyStateChanges, /* IWineD3DTexture */ IWineD3DTextureImpl_Destroy, IWineD3DTextureImpl_GetLevelDesc, diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c index d6973725748..09f76fd84fd 100644 --- a/dlls/wined3d/utils.c +++ b/dlls/wined3d/utils.c @@ -449,6 +449,8 @@ static BOOL check_fbo_compat(const WineD3D_GL_Info *gl_info, GLint internal_form GLuint tex, fb; GLenum status; + ENTER_GL(); + while(glGetError()); glGenTextures(1, &tex); glBindTexture(GL_TEXTURE_2D, tex); @@ -464,6 +466,8 @@ static BOOL check_fbo_compat(const WineD3D_GL_Info *gl_info, GLint internal_form checkGLcall("Framebuffer format check"); + LEAVE_GL(); + return status == GL_FRAMEBUFFER_COMPLETE_EXT; } @@ -1512,6 +1516,7 @@ BOOL is_invalid_op(IWineD3DDeviceImpl *This, int stage, WINED3DTEXTUREOP op, DWO } /* Setup this textures matrix according to the texture flags*/ +/* GL locking is done by the caller (state handler) */ void set_texture_matrix(const float *smat, DWORD flags, BOOL calculatedCoords, BOOL transformed, WINED3DFORMAT vtx_fmt, BOOL ffp_proj_control) { @@ -2380,6 +2385,7 @@ void add_ffp_frag_shader(struct hash_table_t *shaders, struct ffp_frag_desc *des * Requires the caller to activate the correct unit before */ #define GLINFO_LOCATION stateblock->wineD3DDevice->adapter->gl_info +/* GL locking is done by the caller (state handler) */ void texture_activate_dimensions(DWORD stage, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) { if(stateblock->textures[stage]) { switch (IWineD3DBaseTexture_GetTextureDimensions(stateblock->textures[stage])) { @@ -2453,6 +2459,7 @@ void texture_activate_dimensions(DWORD stage, IWineD3DStateBlockImpl *stateblock } } +/* GL locking is done by the caller (state handler) */ void sampler_texdim(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) { DWORD sampler = state - STATE_SAMPLER(0); DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[sampler]; diff --git a/dlls/wined3d/vertexshader.c b/dlls/wined3d/vertexshader.c index 1491b0c725b..f7766a1fa8b 100644 --- a/dlls/wined3d/vertexshader.c +++ b/dlls/wined3d/vertexshader.c @@ -243,8 +243,9 @@ static HRESULT WINAPI IWineD3DVertexShaderImpl_GetFunction(IWineD3DVertexShader* * shader is first used. The reason for this is that we need the vertex * declaration the shader will be used with in order to determine if * the data in a register is of type D3DCOLOR, and needs swizzling. */ -static HRESULT WINAPI IWineD3DVertexShaderImpl_SetFunction(IWineD3DVertexShader *iface, CONST DWORD *pFunction) { - +static HRESULT WINAPI IWineD3DVertexShaderImpl_SetFunction(IWineD3DVertexShader *iface, + const DWORD *pFunction, const struct wined3d_shader_signature *output_signature) +{ IWineD3DVertexShaderImpl *This =(IWineD3DVertexShaderImpl *)iface; IWineD3DDeviceImpl *deviceImpl = (IWineD3DDeviceImpl *) This->baseShader.device; const struct wined3d_shader_frontend *fe; @@ -260,7 +261,7 @@ static HRESULT WINAPI IWineD3DVertexShaderImpl_SetFunction(IWineD3DVertexShader return WINED3DERR_INVALIDCALL; } This->baseShader.frontend = fe; - This->baseShader.frontend_data = fe->shader_init(pFunction); + This->baseShader.frontend_data = fe->shader_init(pFunction, output_signature); if (!This->baseShader.frontend_data) { FIXME("Failed to initialize frontend.\n"); @@ -350,6 +351,7 @@ static HRESULT WINAPI IWIneD3DVertexShaderImpl_SetLocalConstantsF(IWineD3DVertex return WINED3D_OK; } +/* GL locking is done by the caller */ static GLuint vertexshader_compile(IWineD3DVertexShaderImpl *This, const struct vs_compile_args *args) { IWineD3DDeviceImpl *deviceImpl = (IWineD3DDeviceImpl *) This->baseShader.device; SHADER_BUFFER buffer; @@ -394,6 +396,7 @@ static inline BOOL vs_args_equal(const struct vs_compile_args *stored, const str return stored->fog_src == new->fog_src; } +/* GL locking is done by the caller */ GLuint find_gl_vshader(IWineD3DVertexShaderImpl *shader, const struct vs_compile_args *args) { UINT i; diff --git a/dlls/wined3d/volumetexture.c b/dlls/wined3d/volumetexture.c index 41a1160b1a0..680df930de9 100644 --- a/dlls/wined3d/volumetexture.c +++ b/dlls/wined3d/volumetexture.c @@ -211,15 +211,6 @@ static BOOL WINAPI IWineD3DVolumeTextureImpl_IsCondNP2(IWineD3DVolumeTexture *if return FALSE; } -static void WINAPI IWineD3DVolumeTextureImpl_ApplyStateChanges(IWineD3DVolumeTexture *iface, - const DWORD textureStates[WINED3D_HIGHEST_TEXTURE_STATE + 1], - const DWORD samplerStates[WINED3D_HIGHEST_SAMPLER_STATE + 1]) { - IWineD3DVolumeTextureImpl *This = (IWineD3DVolumeTextureImpl *)iface; - TRACE("(%p) : nothing to do, passing to base texture\n", This); - basetexture_apply_state_changes((IWineD3DBaseTexture *)iface, textureStates, samplerStates); -} - - /* ******************************************* IWineD3DVolumeTexture IWineD3DVolumeTexture parts follow ******************************************* */ @@ -330,7 +321,6 @@ const IWineD3DVolumeTextureVtbl IWineD3DVolumeTexture_Vtbl = IWineD3DVolumeTextureImpl_BindTexture, IWineD3DVolumeTextureImpl_GetTextureDimensions, IWineD3DVolumeTextureImpl_IsCondNP2, - IWineD3DVolumeTextureImpl_ApplyStateChanges, /* volume texture */ IWineD3DVolumeTextureImpl_Destroy, IWineD3DVolumeTextureImpl_GetLevelDesc, diff --git a/dlls/wined3d/wined3d_gl.h b/dlls/wined3d/wined3d_gl.h index 1a9c9251899..615d9149deb 100644 --- a/dlls/wined3d/wined3d_gl.h +++ b/dlls/wined3d/wined3d_gl.h @@ -3302,6 +3302,7 @@ typedef enum _GL_Cards { CARD_ATI_RADEON_HD2600 = 0x9581, CARD_ATI_RADEON_HD2900 = 0x9400, CARD_ATI_RADEON_HD3200 = 0x9620, + CARD_ATI_RADEON_HD4800 = 0x944c, CARD_NVIDIA_RIVA_128 = 0x0018, CARD_NVIDIA_RIVA_TNT = 0x0020, diff --git a/dlls/wined3d/wined3d_main.c b/dlls/wined3d/wined3d_main.c index 687fe893c05..2775dc96563 100644 --- a/dlls/wined3d/wined3d_main.c +++ b/dlls/wined3d/wined3d_main.c @@ -117,9 +117,9 @@ static BOOL wined3d_init(HINSTANCE hInstDLL) wc.hCursor = LoadCursorA(NULL, (LPCSTR)IDC_ARROW); wc.hbrBackground = NULL; wc.lpszMenuName = NULL; - wc.lpszClassName = "WineD3D_OpenGL"; + wc.lpszClassName = WINED3D_OPENGL_WINDOW_CLASS_NAME; - if (!RegisterClassA(&wc) && GetLastError() != ERROR_CLASS_ALREADY_EXISTS) + if (!RegisterClassA(&wc)) { ERR("Failed to register window class 'WineD3D_OpenGL'!\n"); return FALSE; @@ -320,9 +320,10 @@ static BOOL wined3d_init(HINSTANCE hInstDLL) return TRUE; } -static BOOL wined3d_destroy(void) +static BOOL wined3d_destroy(HINSTANCE hInstDLL) { HeapFree(GetProcessHeap(), 0, wined3d_settings.logo); + UnregisterClassA(WINED3D_OPENGL_WINDOW_CLASS_NAME, hInstDLL); return TRUE; } @@ -338,7 +339,7 @@ BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv) return wined3d_init(hInstDLL); case DLL_PROCESS_DETACH: - return wined3d_destroy(); + return wined3d_destroy(hInstDLL); default: return TRUE; diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 641ca8c0b05..75abdbe1017 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -697,7 +697,7 @@ struct wined3d_shader_semantic struct wined3d_shader_frontend { - void *(*shader_init)(const DWORD *ptr); + void *(*shader_init)(const DWORD *ptr, const struct wined3d_shader_signature *output_signature); void (*shader_free)(void *data); void (*shader_read_header)(void *data, const DWORD **ptr, struct wined3d_shader_version *shader_version); void (*shader_read_opcode)(void *data, const DWORD **ptr, struct wined3d_shader_instruction *ins, UINT *param_size); @@ -1167,6 +1167,8 @@ enum fogsource { FOGSOURCE_COORD, }; +#define WINED3D_MAX_FBO_ENTRIES 64 + /* The new context manager that should deal with onscreen and offscreen rendering */ struct WineD3DContext { /* State dirtification @@ -1214,6 +1216,7 @@ struct WineD3DContext { GLint aux_buffers; /* FBOs */ + UINT fbo_entry_count; struct list fbo_list; struct fbo_entry *current_fbo; GLuint src_fbo; @@ -1652,8 +1655,6 @@ HRESULT resource_set_private_data(IWineD3DResource *iface, REFGUID guid, /***************************************************************************** * IWineD3DBaseTexture D3D- > openGL state map lookups */ -#define WINED3DFUNC_NOTSUPPORTED -2 -#define WINED3DFUNC_UNIMPLEMENTED -1 typedef enum winetexturestates { WINED3DTEXSTA_ADDRESSU = 0, @@ -2461,7 +2462,6 @@ void state_fogstartend(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DC void state_fog_fragpart(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context); void surface_add_dirty_rect(IWineD3DSurface *iface, const RECT *dirty_rect); -void surface_force_reload(IWineD3DSurface *iface); GLenum surface_get_gl_buffer(IWineD3DSurface *iface, IWineD3DSwapChain *swapchain); void surface_load_ds_location(IWineD3DSurface *iface, DWORD location); void surface_modify_ds_location(IWineD3DSurface *iface, DWORD location); @@ -2815,4 +2815,8 @@ static inline BOOL use_ps(IWineD3DStateBlockImpl *stateblock) void stretch_rect_fbo(IWineD3DDevice *iface, IWineD3DSurface *src_surface, WINED3DRECT *src_rect, IWineD3DSurface *dst_surface, WINED3DRECT *dst_rect, const WINED3DTEXTUREFILTERTYPE filter, BOOL flip); + +/* The WNDCLASS-Name for the fake window which we use to retrieve the GL capabilities */ +#define WINED3D_OPENGL_WINDOW_CLASS_NAME "WineD3D_OpenGL" + #endif diff --git a/dlls/winex11.drv/opengl.c b/dlls/winex11.drv/opengl.c index 7ac8cadbb68..ed46d693bfd 100644 --- a/dlls/winex11.drv/opengl.c +++ b/dlls/winex11.drv/opengl.c @@ -100,6 +100,7 @@ typedef struct wine_glpixelformat { int fmt_id; int render_type; BOOL offscreenOnly; + DWORD dwFlags; /* We store some PFD_* flags in here for emulated bitmap formats */ } WineGLPixelFormat; typedef struct wine_glcontext { @@ -854,12 +855,24 @@ static int get_render_type_from_fbconfig(Display *display, GLXFBConfig fbconfig) return render_type; } +/* Check whether a fbconfig is suitable for Windows-style bitmap rendering */ +static BOOL check_fbconfig_bitmap_capability(Display *display, GLXFBConfig fbconfig) +{ + int dbuf, value; + pglXGetFBConfigAttrib(display, fbconfig, GLX_DOUBLEBUFFER, &dbuf); + pglXGetFBConfigAttrib(gdi_display, fbconfig, GLX_DRAWABLE_TYPE, &value); + + /* Windows only supports bitmap rendering on single buffered formats, further the fbconfig needs to have + * the GLX_PIXMAP_BIT set. */ + return !dbuf && (value & GLX_PIXMAP_BIT); +} + static WineGLPixelFormat *get_formats(Display *display, int *size_ret, int *onscreen_size_ret) { static WineGLPixelFormat *list; static int size, onscreen_size; - int fmt_id, nCfgs, i, run; + int fmt_id, nCfgs, i, run, bmp_formats; GLXFBConfig* cfgs; XVisualInfo *visinfo; @@ -874,7 +887,21 @@ static WineGLPixelFormat *get_formats(Display *display, int *size_ret, int *onsc return NULL; } - list = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, nCfgs*sizeof(WineGLPixelFormat)); + /* Bitmap rendering on Windows implies the use of the Microsoft GDI software renderer. + * Further most GLX drivers only offer pixmap rendering using indirect rendering (except for modern drivers which support 'AIGLX' / composite). + * Indirect rendering can indicate software rendering (on Nvidia it is hw accelerated) + * Since bitmap rendering implies the use of software rendering we can safely use indirect rendering for bitmaps. + * + * Below we count the number of formats which are suitable for bitmap rendering. Windows restricts bitmap rendering to single buffered formats. + */ + for(i=0, bmp_formats=0; ifmt->dwFlags & PFD_DRAW_TO_BITMAP) ? FALSE : TRUE; + if(context->vis) - ctx = pglXCreateContext(gdi_display, context->vis, shareList, direct); + ctx = pglXCreateContext(gdi_display, context->vis, shareList, indirect); else /* Create a GLX Context for a pbuffer */ - ctx = pglXCreateNewContext(gdi_display, context->fmt->fbconfig, context->fmt->render_type, shareList, direct); + ctx = pglXCreateNewContext(gdi_display, context->fmt->fbconfig, context->fmt->render_type, shareList, TRUE); return ctx; } @@ -1110,6 +1158,14 @@ int CDECL X11DRV_ChoosePixelFormat(X11DRV_PDEVICE *physDev, continue; } + /* Only use bitmap capable for formats for bitmap rendering. + * See get_formats for more info. */ + if( (ppfd->dwFlags & PFD_DRAW_TO_BITMAP) != (fmt->dwFlags & PFD_DRAW_TO_BITMAP)) + { + TRACE("PFD_DRAW_TO_BITMAP mismatch for iPixelFormat=%d\n", i+1); + continue; + } + pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_DOUBLEBUFFER, &value); if (value) dwFlags |= PFD_DOUBLEBUFFER; pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_STEREO, &value); @@ -1347,19 +1403,22 @@ int CDECL X11DRV_DescribePixelFormat(X11DRV_PDEVICE *physDev, wine_tsx11_lock(); - pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_X_RENDERABLE, &value); - if(value) - ppfd->dwFlags |= PFD_SUPPORT_GDI; - pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_DRAWABLE_TYPE, &value); if(value & GLX_WINDOW_BIT) ppfd->dwFlags |= PFD_DRAW_TO_WINDOW; - if(value & GLX_PIXMAP_BIT) - ppfd->dwFlags |= PFD_DRAW_TO_BITMAP; - pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_CONFIG_CAVEAT, &value); - if(value == GLX_SLOW_CONFIG) - ppfd->dwFlags |= PFD_GENERIC_ACCELERATED; + /* On Windows bitmap rendering is only offered using the GDI Software renderer. We reserve some formats (see get_formats for more info) + * for bitmap rendering since we require indirect rendering for this. Further pixel format logs of a GeforceFX, Geforce8800GT, Radeon HD3400 and a + * Radeon 9000 indicated that all bitmap formats have PFD_SUPPORT_GDI. Except for 2 formats on the Radeon 9000 none of the hw accelerated formats + * offered the GDI bit either. */ + ppfd->dwFlags |= fmt->dwFlags & (PFD_DRAW_TO_BITMAP | PFD_SUPPORT_GDI); + + /* PFD_GENERIC_FORMAT - gdi software rendering + * PFD_GENERIC_ACCELERATED - some parts are accelerated by a display driver (ICD or MCD) + * none set - full hardware accelerated by a ICD + * + * We only set PFD_GENERIC_ACCELERATED on bitmap formats (see get_formats) as that's what ATI and Nvidia Windows drivers do */ + ppfd->dwFlags |= fmt->dwFlags & PFD_GENERIC_ACCELERATED; pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_DOUBLEBUFFER, &value); if (value) { @@ -1600,15 +1659,13 @@ BOOL CDECL X11DRV_wglCopyContext(HGLRC hglrcSrc, HGLRC hglrcDst, UINT mask) { } if (!src->ctx) { - DWORD type = GetObjectType(src->hdc); wine_tsx11_lock(); - src->ctx = create_glxcontext(gdi_display, src, NULL, type == OBJ_MEMDC ? False : True); + src->ctx = create_glxcontext(gdi_display, src, NULL); TRACE(" created a delayed OpenGL context (%p)\n", src->ctx); } else if (!dst->ctx) { - DWORD type = GetObjectType(dst->hdc); wine_tsx11_lock(); - dst->ctx = create_glxcontext(gdi_display, dst, NULL, type == OBJ_MEMDC ? False : True); + dst->ctx = create_glxcontext(gdi_display, dst, NULL); TRACE(" created a delayed OpenGL context (%p)\n", dst->ctx); } } @@ -1787,7 +1844,7 @@ BOOL CDECL X11DRV_wglMakeCurrent(X11DRV_PDEVICE *physDev, HGLRC hglrc) { * We are certain that the drawable and context are compatible as we only allow compatible formats. */ TRACE(" Creating GLX Context\n"); - ctx->ctx = create_glxcontext(gdi_display, ctx, NULL, type == OBJ_MEMDC ? False : True); + ctx->ctx = create_glxcontext(gdi_display, ctx, NULL); TRACE(" created a delayed OpenGL context (%p)\n", ctx->ctx); } TRACE(" make current for dis %p, drawable %p, ctx %p\n", gdi_display, (void*) drawable, ctx->ctx); @@ -1821,7 +1878,6 @@ BOOL CDECL X11DRV_wglMakeCurrent(X11DRV_PDEVICE *physDev, HGLRC hglrc) { BOOL CDECL X11DRV_wglMakeContextCurrentARB(X11DRV_PDEVICE* pDrawDev, X11DRV_PDEVICE* pReadDev, HGLRC hglrc) { BOOL ret; - int indirect = (GetObjectType(pDrawDev->hdc) == OBJ_MEMDC); TRACE("(%p,%p,%p)\n", pDrawDev, pReadDev, hglrc); @@ -1840,7 +1896,7 @@ BOOL CDECL X11DRV_wglMakeContextCurrentARB(X11DRV_PDEVICE* pDrawDev, X11DRV_PDEV Drawable d_read = get_glxdrawable(pReadDev); if (ctx->ctx == NULL) { - ctx->ctx = create_glxcontext(gdi_display, ctx, NULL, !indirect); + ctx->ctx = create_glxcontext(gdi_display, ctx, NULL); TRACE(" created a delayed OpenGL context (%p)\n", ctx->ctx); } ctx->hdc = pDrawDev->hdc; @@ -1875,20 +1931,22 @@ BOOL CDECL X11DRV_wglShareLists(HGLRC hglrc1, HGLRC hglrc2) { ERR("Could not share display lists, context already created !\n"); return FALSE; } else { + if(org && dest && (GetObjectType(org->hdc) == OBJ_MEMDC) ^ (GetObjectType(dest->hdc) == OBJ_MEMDC)) { + WARN("Attempting to share a context between a direct and indirect rendering context, expect issues!\n"); + } + if (org->ctx == NULL) { - int indirect = (GetObjectType(org->hdc) == OBJ_MEMDC); wine_tsx11_lock(); describeContext(org); - org->ctx = create_glxcontext(gdi_display, org, NULL, !indirect); + org->ctx = create_glxcontext(gdi_display, org, NULL); wine_tsx11_unlock(); TRACE(" created a delayed OpenGL context (%p) for Wine context %p\n", org->ctx, org); } if (NULL != dest) { - int indirect = (GetObjectType(dest->hdc) == OBJ_MEMDC); wine_tsx11_lock(); describeContext(dest); - dest->ctx = create_glxcontext(gdi_display, dest, org->ctx, !indirect); + dest->ctx = create_glxcontext(gdi_display, dest, org->ctx); wine_tsx11_unlock(); TRACE(" created a delayed OpenGL context (%p) for Wine context %p sharing lists with OpenGL ctx %p\n", dest->ctx, dest, org->ctx); return TRUE; diff --git a/dlls/wininet/http.c b/dlls/wininet/http.c index 9c75862f312..212ff9f7913 100644 --- a/dlls/wininet/http.c +++ b/dlls/wininet/http.c @@ -138,6 +138,29 @@ static LPHTTPHEADERW HTTP_GetHeader(LPWININETHTTPREQW req, LPCWSTR head) return &req->pCustHeaders[HeaderIndex]; } +/* set the request content length based on the headers */ +static DWORD set_content_length( LPWININETHTTPREQW lpwhr ) +{ + static const WCHAR szChunked[] = {'c','h','u','n','k','e','d',0}; + WCHAR encoding[20]; + DWORD size; + + size = sizeof(lpwhr->dwContentLength); + if (!HTTP_HttpQueryInfoW(lpwhr, HTTP_QUERY_FLAG_NUMBER|HTTP_QUERY_CONTENT_LENGTH, + &lpwhr->dwContentLength, &size, NULL)) + lpwhr->dwContentLength = ~0u; + + size = sizeof(encoding); + if (HTTP_HttpQueryInfoW(lpwhr, HTTP_QUERY_TRANSFER_ENCODING, encoding, &size, NULL) && + !strcmpiW(encoding, szChunked)) + { + lpwhr->dwContentLength = ~0u; + lpwhr->read_chunked = TRUE; + } + + return lpwhr->dwContentLength; +} + /*********************************************************************** * HTTP_Tokenize (internal) * @@ -753,13 +776,7 @@ static BOOL HTTP_HttpEndRequestW(LPWININETHTTPREQW lpwhr, DWORD dwFlags, DWORD_P /* process cookies here. Is this right? */ HTTP_ProcessCookies(lpwhr); - dwBufferSize = sizeof(lpwhr->dwContentLength); - if (!HTTP_HttpQueryInfoW(lpwhr, HTTP_QUERY_FLAG_NUMBER|HTTP_QUERY_CONTENT_LENGTH, - &lpwhr->dwContentLength, &dwBufferSize, NULL)) - lpwhr->dwContentLength = -1; - - if (lpwhr->dwContentLength == 0) - HTTP_FinishedReading(lpwhr); + if (!set_content_length( lpwhr )) HTTP_FinishedReading(lpwhr); if (!(lpwhr->hdr.dwFlags & INTERNET_FLAG_NO_AUTO_REDIRECT)) { @@ -1598,161 +1615,225 @@ static DWORD HTTPREQ_SetOption(WININETHANDLEHEADER *hdr, DWORD option, void *buf return ERROR_INTERNET_INVALID_OPTION; } -static void HTTP_ReceiveRequestData(WININETHTTPREQW *req, BOOL first_notif) +/* read some more data into the read buffer */ +static BOOL read_more_data( WININETHTTPREQW *req, int maxlen ) { - INTERNET_ASYNC_RESULT iar; - BYTE buffer[4096]; - int available; - BOOL res; + int len; - TRACE("%p\n", req); - - res = NETCON_recv(&req->netConnection, buffer, - min(sizeof(buffer), req->dwContentLength - req->dwContentRead), - MSG_PEEK, &available); - - if(res) { - iar.dwResult = (DWORD_PTR)req->hdr.hInternet; - iar.dwError = first_notif ? 0 : available; - }else { - iar.dwResult = 0; - iar.dwError = INTERNET_GetLastError(); + if (req->read_size && req->read_pos) + { + /* move existing data to the start of the buffer */ + memmove( req->read_buf, req->read_buf + req->read_pos, req->read_size ); + req->read_pos = 0; } - INTERNET_SendCallback(&req->hdr, req->hdr.dwContext, INTERNET_STATUS_REQUEST_COMPLETE, &iar, - sizeof(INTERNET_ASYNC_RESULT)); + if (maxlen == -1) maxlen = sizeof(req->read_buf); + if (!NETCON_recv( &req->netConnection, req->read_buf + req->read_size, + maxlen - req->read_size, 0, &len )) return FALSE; + req->read_size += len; + return TRUE; } -static DWORD HTTP_Read(WININETHTTPREQW *req, void *buffer, DWORD size, DWORD *read, BOOL sync) +/* remove some amount of data from the read buffer */ +static void remove_data( WININETHTTPREQW *req, int count ) { - int bytes_read; + if (!(req->read_size -= count)) req->read_pos = 0; + else req->read_pos += count; +} - if(!NETCON_recv(&req->netConnection, buffer, min(size, req->dwContentLength - req->dwContentRead), - sync ? MSG_WAITALL : 0, &bytes_read)) { - if(req->dwContentLength != -1 && req->dwContentRead != req->dwContentLength) - ERR("not all data received %d/%d\n", req->dwContentRead, req->dwContentLength); +static BOOL read_line( WININETHTTPREQW *req, LPSTR buffer, DWORD *len ) +{ + int count, bytes_read, pos = 0; - /* always return success, even if the network layer returns an error */ - *read = 0; - HTTP_FinishedReading(req); - return ERROR_SUCCESS; - } + for (;;) + { + char *eol = memchr( req->read_buf + req->read_pos, '\n', req->read_size ); - req->dwContentRead += bytes_read; - *read = bytes_read; + if (eol) + { + count = eol - (req->read_buf + req->read_pos); + bytes_read = count + 1; + } + else count = bytes_read = req->read_size; - if(req->lpszCacheFile) { - BOOL res; - DWORD dwBytesWritten; + count = min( count, *len - pos ); + memcpy( buffer + pos, req->read_buf + req->read_pos, count ); + pos += count; + remove_data( req, bytes_read ); + if (eol) break; - res = WriteFile(req->hCacheFile, buffer, bytes_read, &dwBytesWritten, NULL); - if(!res) - WARN("WriteFile failed: %u\n", GetLastError()); + if (!read_more_data( req, -1 )) return FALSE; + if (!req->read_size) + { + *len = 0; + TRACE( "returning empty string\n" ); + return FALSE; + } } - if(!bytes_read && (req->dwContentRead == req->dwContentLength)) - HTTP_FinishedReading(req); - - return ERROR_SUCCESS; + if (pos < *len) + { + if (pos && buffer[pos - 1] == '\r') pos--; + *len = pos + 1; + } + buffer[*len - 1] = 0; + TRACE( "returning %s\n", debugstr_a(buffer)); + return TRUE; } -static DWORD get_chunk_size(const char *buffer) +/* discard data contents until we reach end of line */ +static BOOL discard_eol( WININETHTTPREQW *req ) { - const char *p; - DWORD size = 0; - - for (p = buffer; *p; p++) + do { - if (*p >= '0' && *p <= '9') size = size * 16 + *p - '0'; - else if (*p >= 'a' && *p <= 'f') size = size * 16 + *p - 'a' + 10; - else if (*p >= 'A' && *p <= 'F') size = size * 16 + *p - 'A' + 10; - else if (*p == ';') break; - } - return size; + char *eol = memchr( req->read_buf + req->read_pos, '\n', req->read_size ); + if (eol) + { + remove_data( req, (eol + 1) - (req->read_buf + req->read_pos) ); + break; + } + req->read_pos = req->read_size = 0; /* discard everything */ + if (!read_more_data( req, -1 )) return FALSE; + } while (req->read_size); + return TRUE; } -static DWORD HTTP_ReadChunked(WININETHTTPREQW *req, void *buffer, DWORD size, DWORD *read, BOOL sync) +/* read the size of the next chunk */ +static BOOL start_next_chunk( WININETHTTPREQW *req ) { - char reply[MAX_REPLY_LEN], *p = buffer; - DWORD buflen, to_read, to_write = size; - int bytes_read; + DWORD chunk_size = 0; - *read = 0; + if (!req->dwContentLength) return TRUE; + if (req->dwContentLength == req->dwContentRead) + { + /* read terminator for the previous chunk */ + if (!discard_eol( req )) return FALSE; + req->dwContentLength = ~0u; + req->dwContentRead = 0; + } for (;;) { - if (*read == size) break; - - if (req->dwContentLength == ~0u) /* new chunk */ + while (req->read_size) { - buflen = sizeof(reply); - if (!NETCON_getNextLine(&req->netConnection, reply, &buflen)) break; - - if (!(req->dwContentLength = get_chunk_size(reply))) + char ch = req->read_buf[req->read_pos]; + if (ch >= '0' && ch <= '9') chunk_size = chunk_size * 16 + ch - '0'; + else if (ch >= 'a' && ch <= 'f') chunk_size = chunk_size * 16 + ch - 'a' + 10; + else if (ch >= 'A' && ch <= 'F') chunk_size = chunk_size * 16 + ch - 'A' + 10; + else if (ch == ';' || ch == '\r' || ch == '\n') { - /* zero sized chunk marks end of transfer; read any trailing headers and return */ - HTTP_GetResponseHeaders(req, FALSE); - break; + TRACE( "reading %u byte chunk\n", chunk_size ); + req->dwContentLength = chunk_size; + req->dwContentRead = 0; + if (!discard_eol( req )) return FALSE; + return TRUE; } + remove_data( req, 1 ); } - to_read = min(to_write, req->dwContentLength - req->dwContentRead); - - if (!NETCON_recv(&req->netConnection, p, to_read, sync ? MSG_WAITALL : 0, &bytes_read)) + if (!read_more_data( req, -1 )) return FALSE; + if (!req->read_size) { - if (bytes_read != to_read) - ERR("Not all data received %d/%d\n", bytes_read, to_read); - - /* always return success, even if the network layer returns an error */ - *read = 0; - break; + req->dwContentLength = req->dwContentRead = 0; + return TRUE; } - if (!bytes_read) break; + } +} - req->dwContentRead += bytes_read; - to_write -= bytes_read; - *read += bytes_read; +/* return the size of data available to be read immediately */ +static DWORD get_avail_data( WININETHTTPREQW *req ) +{ + if (req->read_chunked && (req->dwContentLength == ~0u || req->dwContentLength == req->dwContentRead)) + return 0; + return min( req->read_size, req->dwContentLength - req->dwContentRead ); +} - if (req->lpszCacheFile) - { - DWORD dwBytesWritten; +/* check if we have reached the end of the data to read */ +static BOOL end_of_read_data( WININETHTTPREQW *req ) +{ + if (req->read_chunked) return (req->dwContentLength == 0); + if (req->dwContentLength == ~0u) return FALSE; + return (req->dwContentLength == req->dwContentRead); +} - if (!WriteFile(req->hCacheFile, p, bytes_read, &dwBytesWritten, NULL)) - WARN("WriteFile failed: %u\n", GetLastError()); - } - p += bytes_read; +static BOOL refill_buffer( WININETHTTPREQW *req ) +{ + int len = sizeof(req->read_buf); - if (req->dwContentRead == req->dwContentLength) /* chunk complete */ - { - req->dwContentRead = 0; - req->dwContentLength = ~0u; + if (req->read_chunked && (req->dwContentLength == ~0u || req->dwContentLength == req->dwContentRead)) + { + if (!start_next_chunk( req )) return FALSE; + } - buflen = sizeof(reply); - if (!NETCON_getNextLine(&req->netConnection, reply, &buflen)) - { - ERR("Malformed chunk\n"); - *read = 0; - break; - } - } + if (req->dwContentLength != ~0u) len = min( len, req->dwContentLength - req->dwContentRead ); + if (len <= req->read_size) return TRUE; + + if (!read_more_data( req, len )) return FALSE; + if (!req->read_size) req->dwContentLength = req->dwContentRead = 0; + return TRUE; +} + +static void HTTP_ReceiveRequestData(WININETHTTPREQW *req, BOOL first_notif) +{ + INTERNET_ASYNC_RESULT iar; + + TRACE("%p\n", req); + + if (refill_buffer( req )) { + iar.dwResult = (DWORD_PTR)req->hdr.hInternet; + iar.dwError = first_notif ? 0 : get_avail_data(req); + }else { + iar.dwResult = 0; + iar.dwError = INTERNET_GetLastError(); } - if (!*read) HTTP_FinishedReading(req); - return ERROR_SUCCESS; + + INTERNET_SendCallback(&req->hdr, req->hdr.dwContext, INTERNET_STATUS_REQUEST_COMPLETE, &iar, + sizeof(INTERNET_ASYNC_RESULT)); } static DWORD HTTPREQ_Read(WININETHTTPREQW *req, void *buffer, DWORD size, DWORD *read, BOOL sync) { - WCHAR encoding[20]; - DWORD buflen = sizeof(encoding); - static const WCHAR szChunked[] = {'c','h','u','n','k','e','d',0}; + int len, bytes_read = 0; - if (HTTP_HttpQueryInfoW(req, HTTP_QUERY_TRANSFER_ENCODING, encoding, &buflen, NULL) && - !strcmpiW(encoding, szChunked)) + if (req->read_chunked && (req->dwContentLength == ~0u || req->dwContentLength == req->dwContentRead)) { - return HTTP_ReadChunked(req, buffer, size, read, sync); + if (!start_next_chunk( req )) goto done; } - else - return HTTP_Read(req, buffer, size, read, sync); + if (req->dwContentLength != ~0u) size = min( size, req->dwContentLength - req->dwContentRead ); + + if (req->read_size) + { + bytes_read = min( req->read_size, size ); + memcpy( buffer, req->read_buf + req->read_pos, bytes_read ); + remove_data( req, bytes_read ); + } + + if (size > bytes_read && (!bytes_read || sync)) + { + if (NETCON_recv( &req->netConnection, (char *)buffer + bytes_read, size - bytes_read, + sync ? MSG_WAITALL : 0, &len)) + bytes_read += len; + /* always return success, even if the network layer returns an error */ + } +done: + req->dwContentRead += bytes_read; + *read = bytes_read; + + TRACE( "retrieved %u bytes (%u/%u)\n", bytes_read, req->dwContentRead, req->dwContentLength ); + if(req->lpszCacheFile) { + BOOL res; + DWORD dwBytesWritten; + + res = WriteFile(req->hCacheFile, buffer, bytes_read, &dwBytesWritten, NULL); + if(!res) + WARN("WriteFile failed: %u\n", GetLastError()); + } + + if(!bytes_read && (req->dwContentRead == req->dwContentLength)) + HTTP_FinishedReading(req); + + return ERROR_SUCCESS; } + static DWORD HTTPREQ_ReadFile(WININETHANDLEHEADER *hdr, void *buffer, DWORD size, DWORD *read) { WININETHTTPREQW *req = (WININETHTTPREQW*)hdr; @@ -1794,22 +1875,17 @@ static DWORD HTTPREQ_ReadFileExA(WININETHANDLEHEADER *hdr, INTERNET_BUFFERSA *bu INTERNET_SendCallback(&req->hdr, req->hdr.dwContext, INTERNET_STATUS_RECEIVING_RESPONSE, NULL, 0); - if (hdr->dwFlags & INTERNET_FLAG_ASYNC) { - DWORD available = 0; - - NETCON_query_data_available(&req->netConnection, &available); - if (!available) - { - WORKREQUEST workRequest; + if ((hdr->dwFlags & INTERNET_FLAG_ASYNC) && !get_avail_data(req)) + { + WORKREQUEST workRequest; - workRequest.asyncproc = HTTPREQ_AsyncReadFileExAProc; - workRequest.hdr = WININET_AddRef(&req->hdr); - workRequest.u.InternetReadFileExA.lpBuffersOut = buffers; + workRequest.asyncproc = HTTPREQ_AsyncReadFileExAProc; + workRequest.hdr = WININET_AddRef(&req->hdr); + workRequest.u.InternetReadFileExA.lpBuffersOut = buffers; - INTERNET_AsyncCall(&workRequest); + INTERNET_AsyncCall(&workRequest); - return ERROR_IO_PENDING; - } + return ERROR_IO_PENDING; } res = HTTPREQ_Read(req, buffers->lpvBuffer, buffers->dwBufferLength, &buffers->dwBufferLength, @@ -1859,22 +1935,17 @@ static DWORD HTTPREQ_ReadFileExW(WININETHANDLEHEADER *hdr, INTERNET_BUFFERSW *bu INTERNET_SendCallback(&req->hdr, req->hdr.dwContext, INTERNET_STATUS_RECEIVING_RESPONSE, NULL, 0); - if (hdr->dwFlags & INTERNET_FLAG_ASYNC) { - DWORD available = 0; - - NETCON_query_data_available(&req->netConnection, &available); - if (!available) - { - WORKREQUEST workRequest; + if ((hdr->dwFlags & INTERNET_FLAG_ASYNC) && !get_avail_data(req)) + { + WORKREQUEST workRequest; - workRequest.asyncproc = HTTPREQ_AsyncReadFileExWProc; - workRequest.hdr = WININET_AddRef(&req->hdr); - workRequest.u.InternetReadFileExW.lpBuffersOut = buffers; + workRequest.asyncproc = HTTPREQ_AsyncReadFileExWProc; + workRequest.hdr = WININET_AddRef(&req->hdr); + workRequest.u.InternetReadFileExW.lpBuffersOut = buffers; - INTERNET_AsyncCall(&workRequest); + INTERNET_AsyncCall(&workRequest); - return ERROR_IO_PENDING; - } + return ERROR_IO_PENDING; } res = HTTPREQ_Read(req, buffers->lpvBuffer, buffers->dwBufferLength, &buffers->dwBufferLength, @@ -1914,34 +1985,39 @@ static void HTTPREQ_AsyncQueryDataAvailableProc(WORKREQUEST *workRequest) static DWORD HTTPREQ_QueryDataAvailable(WININETHANDLEHEADER *hdr, DWORD *available, DWORD flags, DWORD_PTR ctx) { WININETHTTPREQW *req = (WININETHTTPREQW*)hdr; - BYTE buffer[4048]; - BOOL async; TRACE("(%p %p %x %lx)\n", req, available, flags, ctx); - if(!NETCON_query_data_available(&req->netConnection, available) || *available) - return ERROR_SUCCESS; + if (!(*available = get_avail_data( req ))) + { + if (end_of_read_data( req )) return ERROR_SUCCESS; - /* Even if we are in async mode, we need to determine whether - * there is actually more data available. We do this by trying - * to peek only a single byte in async mode. */ - async = (req->lpHttpSession->lpAppInfo->hdr.dwFlags & INTERNET_FLAG_ASYNC) != 0; + if (req->lpHttpSession->lpAppInfo->hdr.dwFlags & INTERNET_FLAG_ASYNC) + { + WORKREQUEST workRequest; - if (NETCON_recv(&req->netConnection, buffer, - min(async ? 1 : sizeof(buffer), req->dwContentLength - req->dwContentRead), - MSG_PEEK, (int *)available) && async && *available) - { - WORKREQUEST workRequest; + workRequest.asyncproc = HTTPREQ_AsyncQueryDataAvailableProc; + workRequest.hdr = WININET_AddRef( &req->hdr ); - *available = 0; - workRequest.asyncproc = HTTPREQ_AsyncQueryDataAvailableProc; - workRequest.hdr = WININET_AddRef( &req->hdr ); + INTERNET_AsyncCall(&workRequest); - INTERNET_AsyncCall(&workRequest); + return ERROR_IO_PENDING; + } + else + { + refill_buffer( req ); + *available = get_avail_data( req ); + } + } - return ERROR_IO_PENDING; + if (*available == sizeof(req->read_buf)) /* check if we have even more pending in the socket */ + { + DWORD extra; + if (NETCON_query_data_available(&req->netConnection, &extra)) + *available = min( *available + extra, req->dwContentLength - req->dwContentRead ); } + TRACE( "returning %u\n", *available ); return ERROR_SUCCESS; } @@ -1998,6 +2074,7 @@ HINTERNET WINAPI HTTP_HttpOpenRequestW(LPWININETHTTPSESSIONW lpwhs, lpwhr->hdr.refs = 1; lpwhr->hdr.lpfnStatusCB = lpwhs->hdr.lpfnStatusCB; lpwhr->hdr.dwInternalFlags = lpwhs->hdr.dwInternalFlags & INET_CALLBACKW; + lpwhr->dwContentLength = ~0u; WININET_AddRef( &lpwhs->hdr ); lpwhr->lpHttpSession = lpwhs; @@ -2112,7 +2189,10 @@ static void HTTP_DrainContent(WININETHTTPREQW *req) if (!NETCON_connected(&req->netConnection)) return; if (req->dwContentLength == -1) + { NETCON_close(&req->netConnection); + return; + } do { @@ -3124,6 +3204,8 @@ static BOOL HTTP_HandleRedirect(LPWININETHTTPREQW lpwhr, LPCWSTR lpszUrl) NETCON_close(&lpwhr->netConnection); if (!HTTP_ResolveName(lpwhr)) return FALSE; if (!NETCON_init(&lpwhr->netConnection, lpwhr->hdr.dwFlags & INTERNET_FLAG_SECURE)) return FALSE; + lpwhr->read_pos = lpwhr->read_size = 0; + lpwhr->read_chunked = FALSE; } } else @@ -3402,8 +3484,6 @@ BOOL WINAPI HTTP_HttpSendRequestW(LPWININETHTTPREQW lpwhr, LPCWSTR lpszHeaders, { DWORD dwBufferSize; DWORD dwStatusCode; - WCHAR encoding[20]; - static const WCHAR szChunked[] = {'c','h','u','n','k','e','d',0}; INTERNET_SendCallback(&lpwhr->hdr, lpwhr->hdr.dwContext, INTERNET_STATUS_RECEIVING_RESPONSE, NULL, 0); @@ -3421,22 +3501,7 @@ BOOL WINAPI HTTP_HttpSendRequestW(LPWININETHTTPREQW lpwhr, LPCWSTR lpszHeaders, HTTP_ProcessCookies(lpwhr); - dwBufferSize = sizeof(lpwhr->dwContentLength); - if (!HTTP_HttpQueryInfoW(lpwhr,HTTP_QUERY_FLAG_NUMBER|HTTP_QUERY_CONTENT_LENGTH, - &lpwhr->dwContentLength,&dwBufferSize,NULL)) - lpwhr->dwContentLength = -1; - - if (lpwhr->dwContentLength == 0) - HTTP_FinishedReading(lpwhr); - - /* Correct the case where both a Content-Length and Transfer-encoding = chunked are set */ - - dwBufferSize = sizeof(encoding); - if (HTTP_HttpQueryInfoW(lpwhr, HTTP_QUERY_TRANSFER_ENCODING, encoding, &dwBufferSize, NULL) && - !strcmpiW(encoding, szChunked)) - { - lpwhr->dwContentLength = -1; - } + if (!set_content_length( lpwhr )) HTTP_FinishedReading(lpwhr); dwBufferSize = sizeof(dwStatusCode); if (!HTTP_HttpQueryInfoW(lpwhr,HTTP_QUERY_FLAG_NUMBER|HTTP_QUERY_STATUS_CODE, @@ -3826,6 +3891,9 @@ static BOOL HTTP_OpenConnection(LPWININETHTTPREQW lpwhr) bSuccess = TRUE; lend: + lpwhr->read_pos = lpwhr->read_size = 0; + lpwhr->read_chunked = FALSE; + TRACE("%d <--\n", bSuccess); return bSuccess; } @@ -3890,7 +3958,7 @@ static INT HTTP_GetResponseHeaders(LPWININETHTTPREQW lpwhr, BOOL clear) * We should first receive 'HTTP/1.x nnn OK' where nnn is the status code. */ buflen = MAX_REPLY_LEN; - if (!NETCON_getNextLine(&lpwhr->netConnection, bufferA, &buflen)) + if (!read_line(lpwhr, bufferA, &buflen)) goto lend; rc += buflen; MultiByteToWideChar( CP_ACP, 0, bufferA, buflen, buffer, MAX_REPLY_LEN ); @@ -3942,7 +4010,7 @@ static INT HTTP_GetResponseHeaders(LPWININETHTTPREQW lpwhr, BOOL clear) do { buflen = MAX_REPLY_LEN; - if (NETCON_getNextLine(&lpwhr->netConnection, bufferA, &buflen)) + if (read_line(lpwhr, bufferA, &buflen)) { LPWSTR * pFieldAndValue; diff --git a/dlls/wininet/internet.h b/dlls/wininet/internet.h index f69c424690a..48271d650ec 100644 --- a/dlls/wininet/internet.h +++ b/dlls/wininet/internet.h @@ -53,9 +53,6 @@ typedef struct BOOL useSSL; int socketFD; void *ssl_s; - char *peek_msg; - char *peek_msg_mem; - size_t peek_len; } WININET_NETCONNECTION; static inline LPWSTR WININET_strdupW( LPCWSTR str ) @@ -206,6 +203,10 @@ typedef struct LPWSTR lpszCacheFile; struct HttpAuthInfo *pAuthInfo; struct HttpAuthInfo *pProxyAuthInfo; + BOOL read_chunked; /* are we reading in chunked mode? */ + DWORD read_pos; /* current read position in read_buf */ + DWORD read_size; /* valid data size in read_buf */ + char read_buf[4096]; /* buffer for already read but not returned data */ } WININETHTTPREQW, *LPWININETHTTPREQW; @@ -410,7 +411,6 @@ BOOL NETCON_send(WININET_NETCONNECTION *connection, const void *msg, size_t len, BOOL NETCON_recv(WININET_NETCONNECTION *connection, void *buf, size_t len, int flags, int *recvd /* out */); BOOL NETCON_query_data_available(WININET_NETCONNECTION *connection, DWORD *available); -BOOL NETCON_getNextLine(WININET_NETCONNECTION *connection, LPSTR lpszBuffer, LPDWORD dwBuffer); LPCVOID NETCON_GetCert(WININET_NETCONNECTION *connection); DWORD NETCON_set_timeout(WININET_NETCONNECTION *connection, BOOL send, int value); diff --git a/dlls/wininet/netconnection.c b/dlls/wininet/netconnection.c index 3c55528e7cc..b5ca18aa4ea 100644 --- a/dlls/wininet/netconnection.c +++ b/dlls/wininet/netconnection.c @@ -209,8 +209,6 @@ BOOL NETCON_init(WININET_NETCONNECTION *connection, BOOL useSSL) pBIO_new_fp(stderr, BIO_NOCLOSE); /* FIXME: should use winedebug stuff */ meth = pSSLv23_method(); - connection->peek_msg = NULL; - connection->peek_msg_mem = NULL; #else FIXME("can't use SSL, not compiled in.\n"); INTERNET_SetLastError(ERROR_INTERNET_SECURITY_CHANNEL_ERROR); @@ -329,11 +327,6 @@ BOOL NETCON_close(WININET_NETCONNECTION *connection) #ifdef SONAME_LIBSSL if (connection->useSSL) { - HeapFree(GetProcessHeap(),0,connection->peek_msg_mem); - connection->peek_msg = NULL; - connection->peek_msg_mem = NULL; - connection->peek_len = 0; - pSSL_shutdown(connection->ssl_s); pSSL_free(connection->ssl_s); connection->ssl_s = NULL; @@ -541,54 +534,7 @@ BOOL NETCON_recv(WININET_NETCONNECTION *connection, void *buf, size_t len, int f else { #ifdef SONAME_LIBSSL - size_t peek_read = 0, read; - - if (flags & ~(MSG_PEEK|MSG_WAITALL)) - FIXME("SSL_read does not support the following flag: %08x\n", flags); - - /* this ugly hack is all for MSG_PEEK. eww gross */ - if(connection->peek_msg) { - if(connection->peek_len >= len) { - memcpy(buf, connection->peek_msg, len); - if(!(flags & MSG_PEEK)) { - if(connection->peek_len == len) { - HeapFree(GetProcessHeap(), 0, connection->peek_msg); - connection->peek_msg = NULL; - connection->peek_len = 0; - }else { - memmove(connection->peek_msg, connection->peek_msg+len, connection->peek_len-len); - connection->peek_len -= len; - connection->peek_msg = HeapReAlloc(GetProcessHeap(), 0, connection->peek_msg, connection->peek_len); - } - } - - *recvd = len; - return TRUE; - } - - memcpy(buf, connection->peek_msg, connection->peek_len); - peek_read = connection->peek_len; - - if(!(flags & MSG_PEEK)) { - HeapFree(GetProcessHeap(), 0, connection->peek_msg); - connection->peek_msg = NULL; - connection->peek_len = 0; - } - } - - read = pSSL_read(connection->ssl_s, (BYTE*)buf+peek_read, len-peek_read); - - if(flags & MSG_PEEK) { - if(connection->peek_msg) - connection->peek_msg = HeapReAlloc(GetProcessHeap(), 0, connection->peek_msg, - connection->peek_len+read); - else - connection->peek_msg = HeapAlloc(GetProcessHeap(), 0, read); - memcpy(connection->peek_msg+connection->peek_len, (BYTE*)buf+peek_read, read); - connection->peek_len += read; - } - - *recvd = read + peek_read; + *recvd = pSSL_read(connection->ssl_s, buf, len); return *recvd > 0 || !len; #else return FALSE; @@ -607,13 +553,9 @@ BOOL NETCON_query_data_available(WININET_NETCONNECTION *connection, DWORD *avail if (!NETCON_connected(connection)) return FALSE; -#ifdef SONAME_LIBSSL - if (connection->peek_msg) *available = connection->peek_len + pSSL_pending(connection->ssl_s); -#endif - -#ifdef FIONREAD if (!connection->useSSL) { +#ifdef FIONREAD int unread; int retval = ioctlsocket(connection->socketFD, FIONREAD, &unread); if (!retval) @@ -621,99 +563,17 @@ BOOL NETCON_query_data_available(WININET_NETCONNECTION *connection, DWORD *avail TRACE("%d bytes of queued, but unread data\n", unread); *available += unread; } - } #endif - return TRUE; -} - -/****************************************************************************** - * NETCON_getNextLine - */ -BOOL NETCON_getNextLine(WININET_NETCONNECTION *connection, LPSTR lpszBuffer, LPDWORD dwBuffer) -{ - - TRACE("\n"); - - if (!NETCON_connected(connection)) return FALSE; - - if (!connection->useSSL) - { - struct pollfd pfd; - DWORD nRecv = 0; - int ret; - - pfd.fd = connection->socketFD; - pfd.events = POLLIN; - - while (nRecv < *dwBuffer) - { - if (poll(&pfd,1, RESPONSE_TIMEOUT * 1000) > 0) - { - if ((ret = recv(connection->socketFD, &lpszBuffer[nRecv], 1, 0)) <= 0) - { - if (ret == -1) INTERNET_SetLastError(sock_get_error(errno)); - break; - } - - if (lpszBuffer[nRecv] == '\n') - { - lpszBuffer[nRecv++] = '\0'; - *dwBuffer = nRecv; - TRACE(":%u %s\n", nRecv, debugstr_a(lpszBuffer)); - return TRUE; - } - if (lpszBuffer[nRecv] != '\r') - nRecv++; - } - else - { - INTERNET_SetLastError(ERROR_INTERNET_TIMEOUT); - break; - } - } } else { #ifdef SONAME_LIBSSL - long prev_timeout; - DWORD nRecv = 0; - BOOL success = TRUE; - - prev_timeout = pSSL_CTX_get_timeout(ctx); - pSSL_CTX_set_timeout(ctx, RESPONSE_TIMEOUT); - - while (nRecv < *dwBuffer) - { - int recv = 1; - if (!NETCON_recv(connection, &lpszBuffer[nRecv], 1, 0, &recv)) - { - INTERNET_SetLastError(ERROR_CONNECTION_ABORTED); - success = FALSE; - } - - if (lpszBuffer[nRecv] == '\n') - { - success = TRUE; - break; - } - if (lpszBuffer[nRecv] != '\r') - nRecv++; - } - - pSSL_CTX_set_timeout(ctx, prev_timeout); - if (success) - { - lpszBuffer[nRecv++] = '\0'; - *dwBuffer = nRecv; - TRACE("_SSL:%u %s\n", nRecv, lpszBuffer); - return TRUE; - } + *available = pSSL_pending(connection->ssl_s); #endif } - return FALSE; + return TRUE; } - LPCVOID NETCON_GetCert(WININET_NETCONNECTION *connection) { #ifdef SONAME_LIBSSL diff --git a/dlls/wininet/tests/http.c b/dlls/wininet/tests/http.c index e3c33bd8748..7e3c08cc55e 100644 --- a/dlls/wininet/tests/http.c +++ b/dlls/wininet/tests/http.c @@ -493,6 +493,114 @@ abort: first_connection_to_test_url = FALSE; } +static void InternetReadFile_chunked_test(void) +{ + BOOL res; + CHAR buffer[4000]; + DWORD length; + const char *types[2] = { "*", NULL }; + HINTERNET hi, hic = 0, hor = 0; + + trace("Starting InternetReadFile chunked test\n"); + + trace("InternetOpenA <--\n"); + hi = InternetOpenA("", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0); + ok((hi != 0x0),"InternetOpen failed with error %u\n", GetLastError()); + trace("InternetOpenA -->\n"); + + if (hi == 0x0) goto abort; + + trace("InternetConnectA <--\n"); + hic=InternetConnectA(hi, "test.winehq.org", INTERNET_INVALID_PORT_NUMBER, + NULL, NULL, INTERNET_SERVICE_HTTP, 0x0, 0xdeadbeef); + ok((hic != 0x0),"InternetConnect failed with error %u\n", GetLastError()); + trace("InternetConnectA -->\n"); + + if (hic == 0x0) goto abort; + + trace("HttpOpenRequestA <--\n"); + hor = HttpOpenRequestA(hic, "GET", "/testchunked", NULL, NULL, types, + INTERNET_FLAG_KEEP_CONNECTION | INTERNET_FLAG_RESYNCHRONIZE, + 0xdeadbead); + if (hor == 0x0 && GetLastError() == ERROR_INTERNET_NAME_NOT_RESOLVED) { + /* + * If the internet name can't be resolved we are probably behind + * a firewall or in some other way not directly connected to the + * Internet. Not enough reason to fail the test. Just ignore and + * abort. + */ + } else { + ok((hor != 0x0),"HttpOpenRequest failed with error %u\n", GetLastError()); + } + trace("HttpOpenRequestA -->\n"); + + if (hor == 0x0) goto abort; + + trace("HttpSendRequestA -->\n"); + SetLastError(0xdeadbeef); + res = HttpSendRequestA(hor, "", -1, NULL, 0); + ok(res || (GetLastError() == ERROR_INTERNET_NAME_NOT_RESOLVED), + "Synchronous HttpSendRequest returning 0, error %u\n", GetLastError()); + trace("HttpSendRequestA <--\n"); + + length = 100; + res = HttpQueryInfoA(hor,HTTP_QUERY_CONTENT_TYPE,buffer,&length,0x0); + buffer[length]=0; + trace("Option CONTENT_TYPE -> %i %s\n",res,buffer); + + SetLastError( 0xdeadbeef ); + length = 100; + res = HttpQueryInfoA(hor,HTTP_QUERY_TRANSFER_ENCODING,buffer,&length,0x0); + buffer[length]=0; + trace("Option TRANSFER_ENCODING -> %i %s\n",res,buffer); + ok( res, "Failed to get TRANSFER_ENCODING option, error %u\n", GetLastError() ); + ok( !strcmp( buffer, "chunked" ), "Wrong transfer encoding '%s'\n", buffer ); + + SetLastError( 0xdeadbeef ); + length = 16; + res = HttpQueryInfoA(hor,HTTP_QUERY_CONTENT_LENGTH,&buffer,&length,0x0); + ok( !res, "Found CONTENT_LENGTH option '%s'\n", buffer ); + ok( GetLastError() == ERROR_HTTP_HEADER_NOT_FOUND, "Wrong error %u\n", GetLastError() ); + + length = 100; + trace("Entering Query loop\n"); + + while (TRUE) + { + res = InternetQueryDataAvailable(hor,&length,0x0,0x0); + ok(!(!res && length != 0),"InternetQueryDataAvailable failed with non-zero length\n"); + ok(res, "InternetQueryDataAvailable failed, error %d\n", GetLastError()); + trace("got %u available\n",length); + if (length) + { + DWORD got; + char *buffer = HeapAlloc(GetProcessHeap(),0,length+1); + + res = InternetReadFile(hor,buffer,length,&got); + + buffer[got]=0; + trace("ReadFile -> %i %i\n",res,got); + ok( length == got, "only got %u of %u available\n", got, length ); + ok( buffer[got-1] == '\n', "received partial line '%s'\n", buffer ); + + HeapFree(GetProcessHeap(),0,buffer); + if (!got) break; + } + if (length == 0) + break; + } +abort: + trace("aborting\n"); + if (hor != 0x0) { + res = InternetCloseHandle(hor); + ok (res, "InternetCloseHandle of handle opened by HttpOpenRequestA failed\n"); + } + if (hi != 0x0) { + res = InternetCloseHandle(hi); + ok (res, "InternetCloseHandle of handle opened by InternetOpenA failed\n"); + } +} + static void InternetReadFileExA_test(int flags) { DWORD rc; @@ -2321,6 +2429,7 @@ struct notification unsigned int status; /* status received */ int async; /* delivered from another thread? */ int todo; + int optional; }; struct info @@ -2356,6 +2465,13 @@ static void CALLBACK check_notification( HINTERNET handle, DWORD_PTR context, DW return; } + while (info->test[i].status != status && info->test[i].optional && + i < info->count - 1 && + info->test[i].function == info->test[i + 1].function) + { + i++; + } + status_ok = (info->test[i].status == status); function_ok = (info->test[i].function == info->function); @@ -2375,7 +2491,7 @@ static void CALLBACK check_notification( HINTERNET handle, DWORD_PTR context, DW todo_wine ok( function_ok, "%u: expected function %u got %u\n", info->line, info->test[i].function, info->function ); } if (i == info->count - 1 || info->test[i].function != info->test[i + 1].function) SetEvent( info->wait ); - info->index++; + info->index = i+1; LeaveCriticalSection( ¬ification_cs ); } @@ -2390,6 +2506,7 @@ static const struct notification async_send_request_ex_test[] = { { internet_connect, INTERNET_STATUS_HANDLE_CREATED, 0 }, { http_open_request, INTERNET_STATUS_HANDLE_CREATED, 0 }, + { http_send_request_ex, INTERNET_STATUS_DETECTING_PROXY, 1, 0, 1 }, { http_send_request_ex, INTERNET_STATUS_RESOLVING_NAME, 1 }, { http_send_request_ex, INTERNET_STATUS_NAME_RESOLVED, 1 }, { http_send_request_ex, INTERNET_STATUS_CONNECTING_TO_SERVER, 1 }, @@ -2493,6 +2610,7 @@ static void test_async_HttpSendRequestEx(void) InternetCloseHandle( ses ); WaitForSingleObject( info.wait, 10000 ); + Sleep(100); CloseHandle( info.wait ); } @@ -2557,9 +2675,10 @@ START_TEST(http) InternetOpenRequest_test(); test_http_cache(); InternetOpenUrlA_test(); - HttpSendRequestEx_test(); HttpHeaders_test(); test_http_connection(); test_user_agent_header(); test_bogus_accept_types_array(); + InternetReadFile_chunked_test(); + HttpSendRequestEx_test(); } diff --git a/dlls/wininet/tests/internet.c b/dlls/wininet/tests/internet.c index 176f3d8f648..5f36c3d9354 100644 --- a/dlls/wininet/tests/internet.c +++ b/dlls/wininet/tests/internet.c @@ -742,8 +742,9 @@ static void test_IsDomainLegalCookieDomainW(void) error = GetLastError(); ok(!ret, "IsDomainLegalCookieDomainW succeeded\n"); ok(error == ERROR_SXS_KEY_NOT_FOUND || + error == ERROR_SUCCESS || /* IE8 on W2K3 */ error == 0xdeadbeef, /* up to IE7 */ - "got %u expected ERROR_SXS_KEY_NOT_FOUND or 0xdeadbeef\n", error); + "unexpected error: %u\n", error); ret = pIsDomainLegalCookieDomainW(gmail_com, gmail_com); ok(ret, "IsDomainLegalCookieDomainW failed\n"); @@ -754,9 +755,9 @@ static void test_IsDomainLegalCookieDomainW(void) ok(!ret, "IsDomainLegalCookieDomainW succeeded\n"); ok(error == ERROR_SXS_KEY_NOT_FOUND || /* IE8 on XP */ error == ERROR_FILE_NOT_FOUND || /* IE8 on Vista */ + error == ERROR_SUCCESS || /* IE8 on W2K3 */ error == 0xdeadbeef, /* up to IE7 */ - "got %u expected ERROR_SXS_KEY_NOT_FOUND, ERROR_FILE_NOT_FOUND or " - "0xdeadbeef\n", error); + "unexpected error: %u\n", error); ret = pIsDomainLegalCookieDomainW(uk, co_uk); ok(!ret, "IsDomainLegalCookieDomainW succeeded\n"); diff --git a/dlls/wininet/tests/urlcache.c b/dlls/wininet/tests/urlcache.c index d13597626de..b7df03e3120 100644 --- a/dlls/wininet/tests/urlcache.c +++ b/dlls/wininet/tests/urlcache.c @@ -25,6 +25,7 @@ #include "windef.h" #include "winbase.h" #include "wininet.h" +#include "winineti.h" #include "wine/test.h" @@ -219,6 +220,49 @@ static void test_FindCloseUrlCache(void) ok(ERROR_INVALID_HANDLE == err, "expected %d, got %d\n", ERROR_INVALID_HANDLE, err); } +static void test_GetDiskInfoA(void) +{ + BOOL ret; + DWORD error, cluster_size; + DWORDLONG free, total; + char path[MAX_PATH], *p; + + GetSystemDirectoryA(path, MAX_PATH); + if ((p = strchr(path, '\\'))) *++p = 0; + + ret = GetDiskInfoA(path, &cluster_size, &free, &total); + ok(ret, "GetDiskInfoA failed %u\n", GetLastError()); + + ret = GetDiskInfoA(path, &cluster_size, &free, NULL); + ok(ret, "GetDiskInfoA failed %u\n", GetLastError()); + + ret = GetDiskInfoA(path, &cluster_size, NULL, NULL); + ok(ret, "GetDiskInfoA failed %u\n", GetLastError()); + + ret = GetDiskInfoA(path, NULL, NULL, NULL); + ok(ret, "GetDiskInfoA failed %u\n", GetLastError()); + + ret = GetDiskInfoA(path, NULL, NULL, NULL); + ok(ret, "GetDiskInfoA failed %u\n", GetLastError()); + + SetLastError(0xdeadbeef); + strcpy(p, "\\non\\existing\\path"); + ret = GetDiskInfoA(path, NULL, NULL, NULL); + error = GetLastError(); + ok(!ret || + broken(ret), /* < IE7 */ + "GetDiskInfoA succeeded\n"); + ok(error == ERROR_PATH_NOT_FOUND || + broken(error == 0xdeadbeef), /* < IE7 */ + "got %u expected ERROR_PATH_NOT_FOUND\n", error); + + SetLastError(0xdeadbeef); + ret = GetDiskInfoA(NULL, NULL, NULL, NULL); + error = GetLastError(); + ok(!ret, "GetDiskInfoA succeeded\n"); + ok(error == ERROR_INVALID_PARAMETER, "got %u expected ERROR_INVALID_PARAMETER\n", error); +} + START_TEST(urlcache) { HMODULE hdll; @@ -227,4 +271,5 @@ START_TEST(urlcache) pUnlockUrlCacheEntryFileA = (void*)GetProcAddress(hdll, "UnlockUrlCacheEntryFileA"); test_urlcacheA(); test_FindCloseUrlCache(); + test_GetDiskInfoA(); } diff --git a/dlls/wininet/urlcache.c b/dlls/wininet/urlcache.c index 5e1541da5b1..f385c7e81cb 100644 --- a/dlls/wininet/urlcache.c +++ b/dlls/wininet/urlcache.c @@ -3624,10 +3624,26 @@ BOOL WINAPI IsUrlCacheEntryExpiredW( LPCWSTR url, DWORD dwFlags, FILETIME* pftLa /*********************************************************************** * GetDiskInfoA (WININET.@) */ -DWORD WINAPI GetDiskInfoA(void *p0, void *p1, void *p2, void *p3) +BOOL WINAPI GetDiskInfoA(PCSTR path, PDWORD cluster_size, PDWORDLONG free, PDWORDLONG total) { - FIXME("(%p, %p, %p, %p)\n", p0, p1, p2, p3); - return 0; + BOOL ret; + ULARGE_INTEGER bytes_free, bytes_total; + + TRACE("(%s, %p, %p, %p)\n", debugstr_a(path), cluster_size, free, total); + + if (!path) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + if ((ret = GetDiskFreeSpaceExA(path, NULL, &bytes_total, &bytes_free))) + { + if (cluster_size) *cluster_size = 1; + if (free) *free = bytes_free.QuadPart; + if (total) *total = bytes_total.QuadPart; + } + return ret; } /*********************************************************************** @@ -3638,3 +3654,12 @@ DWORD WINAPI RegisterUrlCacheNotification(LPVOID a, DWORD b, DWORD c, DWORD d, D FIXME("(%p %x %x %x %x %x)\n", a, b, c, d, e, f); return 0; } + +/*********************************************************************** + * IncrementUrlCacheHeaderData (WININET.@) + */ +BOOL WINAPI IncrementUrlCacheHeaderData(DWORD index, LPDWORD data) +{ + FIXME("(%u, %p)\n", index, data); + return FALSE; +} diff --git a/dlls/wininet/wininet.spec b/dlls/wininet/wininet.spec index 61beaf4a325..d5995eb3cc3 100644 --- a/dlls/wininet/wininet.spec +++ b/dlls/wininet/wininet.spec @@ -1,5 +1,5 @@ 101 stub -noname DoConnectoidsExist -102 stdcall -noname GetDiskInfoA(ptr ptr ptr ptr) +102 stdcall -noname GetDiskInfoA(str ptr ptr ptr) 103 stub -noname PerformOperationOverUrlCacheA 104 stub -noname HttpCheckDavComplianceA 105 stub -noname HttpCheckDavComplianceW @@ -109,7 +109,7 @@ @ stdcall HttpSendRequestExA(long ptr ptr long long) @ stdcall HttpSendRequestExW(long ptr ptr long long) @ stdcall HttpSendRequestW(ptr wstr long ptr long) -@ stub IncrementUrlCacheHeaderData +@ stdcall IncrementUrlCacheHeaderData(long ptr) @ stub InternetAlgIdToStringA @ stub InternetAlgIdToStringW @ stdcall InternetAttemptConnect(long) diff --git a/fonts/system.sfd b/fonts/system.sfd index 44cdba2f386..c84ad8e6d0e 100644 --- a/fonts/system.sfd +++ b/fonts/system.sfd @@ -46,10 +46,10 @@ LangName: 1033 "" "" "" "" "" "" "" "" "Created with FontForge 1.0 (http://fontf Encoding: UnicodeBmp UnicodeInterp: none NameList: Adobe Glyph List -DisplaySize: 16 +DisplaySize: 18 AntiAlias: 0 FitToEm: 1 -WinInfo: 42 42 15 +WinInfo: 38 38 14 OnlyBitmaps: 1 BeginChars: 65536 484 @@ -4696,58 +4696,58 @@ BDFChar: 63 95 8 0 7 -2 -2 rr<$! BDFChar: 64 96 4 1 3 11 13 J3Y4W -BDFChar: 65 97 8 1 6 0 6 -Gg$SDbfkG7 +BDFChar: 65 97 8 1 7 0 6 +G_CHtKS4XO BDFChar: 66 98 8 1 6 0 9 -^qdb\bfn;TbkM/< +J:N0[`.Wes`4,dI BDFChar: 67 99 8 1 6 0 6 -Gg*t=^s%$' +G_CTtJ:r.I BDFChar: 68 100 8 1 6 0 9 -$k*Plbfn;Tb^9Bj +"9\jLN.ck;N-#%" BDFChar: 69 101 9 1 6 0 6 -Gg+D,^s%$' -BDFChar: 70 102 5 0 3 0 9 -0OS;X?smAM?sis7 +G_CbJJ:r.I +BDFChar: 70 102 5 0 2 0 9 ++@&3M5X7S"5X5;L BDFChar: 71 103 8 1 6 -3 6 -I*BgYbfkGCb]j*f -BDFChar: 72 104 8 1 6 0 9 -^qdb\bfn;Tbfg%e +FGtm+KT(!UKQmIs +BDFChar: 72 104 8 1 5 0 9 +J:N0SaG>Y.Lkl$2 BDFChar: 73 105 3 1 2 0 9 -^q]rc^qdb$^q]pM -BDFChar: 74 106 4 0 2 -3 9 -?sitB?smAM?smAM^]4?7 +J,fS"J:N0#J:IV" +BDFChar: 74 106 4 0 1 -3 9 +5QCdL5X7S"5X7S"J,fQL BDFChar: 75 107 7 1 6 0 9 -^qdb0f^RhgfZX/beVH( BDFChar: 91 123 5 1 3 -2 12 +@&1W5X7Sb5X7S"5X6Fl BDFChar: 92 124 3 1 1 -2 13 @@ -4948,7 +4948,7 @@ BDFChar: 211 222 6 0 4 12 15 OH<"( BDFChar: 212 223 5 0 3 12 15 @$$IX -BDFChar: 213 224 8 1 6 0 10 +BDFChar: 213 224 9 1 6 0 10 E%i+/Gg$SDbfkG7 BDFChar: 214 225 8 1 6 0 10 3&"_?Gg$SDbfkG7 @@ -5002,23 +5002,21 @@ BDFChar: 353 158 8 1 6 -1 13 r;?Kjr;?Kjr;?Kjr;?Hm BDFChar: 354 159 8 1 6 -1 13 r;?Kjr;?Kjr;?Kjr;?Hm -BDFChar: 475 302 5 1 3 -2 12 +BDFChar: 469 1108 5 1 3 -2 12 i'9Om5X7S"5X7S"i':ZM -BDFChar: 476 303 3 1 2 -2 9 +BDFChar: 470 1028 3 1 2 -2 9 ^q]rc^qdb$^qbK9 -BDFChar: 477 362 11 2 8 0 14 +BDFChar: 471 1118 11 2 8 0 14 HiSbMJqAT+JqAT+Jj_Qu -BDFChar: 478 363 8 1 6 0 9 +BDFChar: 472 1038 8 1 6 0 9 r;6Q=bfn;Tb^9Bj -BDFChar: 479 370 11 2 8 -2 12 +BDFChar: 473 1168 11 2 8 -2 12 JqAT+JqAT+JqASB3!]om -BDFChar: 480 371 8 1 6 -2 6 +BDFChar: 474 1169 8 1 6 -2 6 bfn;TbfkG?$ig8- -BDFChar: 481 278 7 1 5 0 14 +BDFChar: 475 302 7 1 5 0 14 +9;1eJ:N1>J:N0#J:RCp -BDFChar: 482 279 9 1 6 0 9 +BDFChar: 476 303 9 1 6 0 9 0JEKObfojtb]j*f -BDFChar: 483 27 18 0 0 0 0 -z EndBitmapFont EndSplineFont diff --git a/fonts/system.ttf b/fonts/system.ttf index 7d4494591ba018e750ba810307633d08b918e5f1..7e79ed0758bc3c35683ba4bcaaf2216cc7e4d295 100644 GIT binary patch delta 1561 zcwSx9drXyO9KiA4bIy6+=e-;P0r5B(ay4w_pxkh+c>y7?B2I#Tv~&kAfEz2f%#3UY zx#!R&wB~XZuKdR?T4&je+Q2Eb8sQ(d(fznCT5Cqr%~}|J&*Am5c=^1~`~1%H{NCqw z&ZlGQ%9yGVB_i{<1thJiVogKV;fy+wJ99*e+o~!atUTMXeu+r9UnDqFRk5z}s=K{e zWMj98uc5lS;URj{IWl#i=G(v%!S7V8L~Xl2s+G2$v9FZWzuMuL%CS1FrQ@Nd@whhm zpgok=xnM3HNZYVK)U@wxB5t>bqKUX)9An9j!5SygcIWb@-tyHwamS!_cYfP=*}y7C zDaZfXXo^pq!0N`vWG3BdwP@XCq!;uA zMBDuLpWbxGk#JhSHf534J%z!tl2y*lMpk}@4v_E9qMGU0$y#M7J2q11_=e8cFU&Gj zs?J+!RpfT(Tb1$B(cH_4;9_e|b*d15-%uTqR(iw0|# z9!%A~RCl*87%Gj7b(z6X$$lY};wGMxA*XPUU+6Viek$msij%gz>D{ho|3QhU4)a3x zv&~ogmJbbwSC~eSy-bh&6prcW3zGcvPqDddum7U>xWxaLoRcp(E0#>jSClytm-CdR z@(Y&)*2o1e2{h0xai&^ThRUGatuj?6<$&6%wo(qOR@F**Tpd+MDNn1n)jO2u)G>8T z*w>3{N=*@%iCK?ks3>jxAK(-w@il(LG-hb#2g466L>}%!IV$il9>W$qj;FB)`|vW3 zAcl|d3BEvLZgG&`U>;E;orgj!LlxGe1-tM(NMyVTk{F-i8~hFiXEHdG!I|@sjeOjV z6<7;$nGv+19lbb!SMWOCm#CQIJg^|2o1&K6?bTt~mfHVWr3`ifsTlg5vNdEw4 zqyH7L=3x;^QHe*u>R3;KFShj(SaE9vOvd^?%Iy!#ir93vd9hsvme*c~ZD8a!FSc0; zo6h!oI0=^2=E&G=m(2j|YizFzw#r!yR@5PnQ;!YcSU6AOIrQO0L=SUIoC{{-d=6H^ z`5Bk+w}`93^15u1%dA{xJ45!3k9O0$>2^e zxB$go!$V$-?T~CQcH&0NCkFL1JX?t$DSJlJy*3kG8@?Qp@5L^8vH5fTia9r8yQXq= y%eCtri-TSx%WIT*J-Kxwd2x={#`WsA-}17>UcbZ-x3&|%dN=zu#OgQh^8E**dIaPE delta 1406 zcwSx8ZD?Cn7{Kx8Xa=-{2=IL4uv^3gIaun)XKUKozdZ>Qgsoc5d(J)Q zJm)zlzm2P7 ze@8~7XR}D8d)>P3JLyg5-h+EOzczn)CbufTTy493sjalr-+Zc=DtNZ?oQYsfvE^*B zq$~BgN0Lhdx4-4mL~6h@#j|pw$z{sOjV0?{qgZ2B5s})B}PfUkdu^iGA&=RpQd~(-%-ZoM=mjMmD5~euBBULzc(u;q0}`a&XL)O zn{gXDaTgxILwKSxF`mVXcnyc}AtrGGmBsvkGdM3|1tMANS{_!Q6&tYyk75X;cpU_2 zF^EN0EHYr76R}ybJr7IJfE&;Rg0s6oa5iJv1ZO{qr?Cew;|&m;U68EUpYyK$?K`0lWuxQnMocGgyt|f-E^VVl_74K5Pe>abCbayn~})G0tq3 z+utIt2RgeM@RYFCN5W z*o6`7#Vg1j> 12) -1) #define TreeView_SetLineColor(hwnd, clr) \ - (COLORREF)SNDMSGA((hwnd), TVM_SETLINECOLOR, 0, (LPARAM)(clr)) + (COLORREF)SNDMSG((hwnd), TVM_SETLINECOLOR, 0, (LPARAM)(clr)) #define TreeView_GetLineColor(hwnd) \ - (COLORREF)SNDMSGA((hwnd), TVM_GETLINECOLOR, 0, 0) + (COLORREF)SNDMSG((hwnd), TVM_GETLINECOLOR, 0, 0) #define TreeView_MapAccIDToHTREEITEM(hwnd, id) \ (HTREEITEM)SNDMSG((hwnd), TVM_MAPACCIDTOHTREEITEM, id, 0) @@ -3253,12 +3253,20 @@ static const WCHAR WC_LISTVIEWW[] = { 'S','y','s', #define LVN_GETINFOTIPA (LVN_FIRST-57) #define LVN_GETINFOTIPW (LVN_FIRST-58) #define LVN_GETINFOTIP WINELIB_NAME_AW(LVN_GETINFOTIP) +#define LVN_INCREMENTALSEARCHA (LVN_FIRST-62) +#define LVN_INCREMENTALSEARCHW (LVN_FIRST-63) +#define LVN_INCREMENTALSEARCH WINELIB_NAME_AW(LVN_INCREMENTALSEARCH) #define LVN_BEGINSCROLL (LVN_FIRST-80) #define LVN_ENDSCROLL (LVN_FIRST-81) #define LVN_LINKCLICK (LVN_FIRST-84) #define LVN_ASYNCDRAWN (LVN_FIRST-86) #define LVN_GETEMPTYMARKUP (LVN_FIRST-87) +/* LVN_INCREMENTALSEARCH return codes */ +#define LVNSCH_DEFAULT -1 +#define LVNSCH_ERROR -2 +#define LVNSCH_IGNORE -3 + #define LVA_DEFAULT 0x0000 #define LVA_ALIGNLEFT 0x0001 #define LVA_ALIGNTOP 0x0002 @@ -3667,13 +3675,13 @@ typedef struct NMLVSCROLL } NMLVSCROLL, *LPNMLVSCROLL; #define ListView_SetItemCount(hwnd,count) \ - (BOOL)SNDMSGA((hwnd),LVM_SETITEMCOUNT,(WPARAM)(INT)(count),0) + (BOOL)SNDMSG((hwnd),LVM_SETITEMCOUNT,(WPARAM)(INT)(count),0) #define ListView_SetTextBkColor(hwnd,clrBk) \ - (BOOL)SNDMSGA((hwnd),LVM_SETTEXTBKCOLOR,0,(LPARAM)(COLORREF)(clrBk)) + (BOOL)SNDMSG((hwnd),LVM_SETTEXTBKCOLOR,0,(LPARAM)(COLORREF)(clrBk)) #define ListView_SetTextColor(hwnd,clrBk) \ - (BOOL)SNDMSGA((hwnd),LVM_SETTEXTCOLOR,0,(LPARAM)(COLORREF)(clrBk)) + (BOOL)SNDMSG((hwnd),LVM_SETTEXTCOLOR,0,(LPARAM)(COLORREF)(clrBk)) #define ListView_DeleteColumn(hwnd,col)\ - (LRESULT)SNDMSGA((hwnd),LVM_DELETECOLUMN,0,(LPARAM)(INT)(col)) + (LRESULT)SNDMSG((hwnd),LVM_DELETECOLUMN,0,(LPARAM)(INT)(col)) #define ListView_GetColumnA(hwnd,x,col)\ (LRESULT)SNDMSGA((hwnd),LVM_GETCOLUMNA,(WPARAM)(INT)(x),(LPARAM)(LPLVCOLUMNA)(col)) #define ListView_GetColumnW(hwnd,x,col)\ @@ -3685,13 +3693,13 @@ typedef struct NMLVSCROLL (LRESULT)SNDMSGW((hwnd),LVM_SETCOLUMNW,(WPARAM)(INT)(x),(LPARAM)(LPLVCOLUMNW)(col)) #define ListView_SetColumn WINELIB_NAME_AW(ListView_SetColumn) #define ListView_GetColumnWidth(hwnd,x)\ - (INT)SNDMSGW((hwnd),LVM_GETCOLUMNWIDTH,(WPARAM)(INT)(x),0L) + (INT)SNDMSG((hwnd),LVM_GETCOLUMNWIDTH,(WPARAM)(INT)(x),0L) #define ListView_SetColumnWidth(hwnd,x,width)\ - (BOOL)SNDMSGW((hwnd),LVM_SETCOLUMNWIDTH,(WPARAM)(INT)(x),(LPARAM)(MAKELPARAM(width,0))) + (BOOL)SNDMSG((hwnd),LVM_SETCOLUMNWIDTH,(WPARAM)(INT)(x),(LPARAM)(MAKELPARAM(width,0))) #define ListView_GetNextItem(hwnd,nItem,flags) \ - (INT)SNDMSGA((hwnd),LVM_GETNEXTITEM,(WPARAM)(INT)(nItem),(LPARAM)(MAKELPARAM(flags,0))) + (INT)SNDMSG((hwnd),LVM_GETNEXTITEM,(WPARAM)(INT)(nItem),(LPARAM)(MAKELPARAM(flags,0))) #define ListView_FindItemA(hwnd,nItem,plvfi) \ (INT)SNDMSGA((hwnd),LVM_FINDITEMA,(WPARAM)(INT)(nItem),(LPARAM)(LVFINDINFOA*)(plvfi)) #define ListView_FindItemW(hwnd,nItem,plvfi) \ @@ -3699,11 +3707,11 @@ typedef struct NMLVSCROLL #define ListView_FindItem WINELIB_NAME_AW(ListView_FindItem) #define ListView_Arrange(hwnd,code) \ - (INT)SNDMSGA((hwnd),LVM_ARRANGE,(WPARAM)(INT)(code),0L) + (INT)SNDMSG((hwnd),LVM_ARRANGE,(WPARAM)(INT)(code),0L) #define ListView_GetItemPosition(hwnd,i,ppt) \ - (INT)SNDMSGA((hwnd),LVM_GETITEMPOSITION,(WPARAM)(INT)(i),(LPARAM)(LPPOINT)(ppt)) + (INT)SNDMSG((hwnd),LVM_GETITEMPOSITION,(WPARAM)(INT)(i),(LPARAM)(LPPOINT)(ppt)) #define ListView_GetItemRect(hwnd,i,prc,code) \ - (BOOL)SNDMSGA((hwnd), LVM_GETITEMRECT, (WPARAM)(int)(i), \ + (BOOL)SNDMSG((hwnd), LVM_GETITEMRECT, (WPARAM)(int)(i), \ ((prc) ? (((RECT*)(prc))->left = (code),(LPARAM)(RECT \ *)(prc)) : (LPARAM)(RECT*)NULL)) #define ListView_SetItemA(hwnd,pitem) \ @@ -3712,51 +3720,51 @@ typedef struct NMLVSCROLL (INT)SNDMSGW((hwnd),LVM_SETITEMW,0,(LPARAM)(const LVITEMW *)(pitem)) #define ListView_SetItem WINELIB_NAME_AW(ListView_SetItem) #define ListView_SetItemState(hwnd,i,data,dataMask) \ -{ LVITEMA _LVi; _LVi.state = data; _LVi.stateMask = dataMask;\ - SNDMSGA(hwnd, LVM_SETITEMSTATE, (WPARAM)(UINT)i, (LPARAM) (LPLVITEMA)&_LVi);} +{ LVITEM _LVi; _LVi.state = data; _LVi.stateMask = dataMask;\ + SNDMSG(hwnd, LVM_SETITEMSTATE, (WPARAM)(UINT)i, (LPARAM) (LPLVITEM)&_LVi);} #define ListView_GetItemState(hwnd,i,mask) \ - (UINT)SNDMSGA((hwnd),LVM_GETITEMSTATE,(WPARAM)(UINT)(i),(LPARAM)(UINT)(mask)) + (UINT)SNDMSG((hwnd),LVM_GETITEMSTATE,(WPARAM)(UINT)(i),(LPARAM)(UINT)(mask)) #define ListView_GetCountPerPage(hwnd) \ - (BOOL)SNDMSGW((hwnd),LVM_GETCOUNTPERPAGE,0,0L) + (BOOL)SNDMSG((hwnd),LVM_GETCOUNTPERPAGE,0,0L) #define ListView_GetImageList(hwnd,iImageList) \ - (HIMAGELIST)SNDMSGA((hwnd),LVM_GETIMAGELIST,(WPARAM)(INT)(iImageList),0L) + (HIMAGELIST)SNDMSG((hwnd),LVM_GETIMAGELIST,(WPARAM)(INT)(iImageList),0L) #define ListView_GetStringWidthA(hwnd,pstr) \ (INT)SNDMSGA((hwnd),LVM_GETSTRINGWIDTHA,0,(LPARAM)(LPCSTR)(pstr)) #define ListView_GetStringWidthW(hwnd,pstr) \ (INT)SNDMSGW((hwnd),LVM_GETSTRINGWIDTHW,0,(LPARAM)(LPCWSTR)(pstr)) #define ListView_GetStringWidth WINELIB_NAME_AW(ListView_GetStringWidth) #define ListView_GetTopIndex(hwnd) \ - (BOOL)SNDMSGA((hwnd),LVM_GETTOPINDEX,0,0L) + (BOOL)SNDMSG((hwnd),LVM_GETTOPINDEX,0,0L) #define ListView_Scroll(hwnd,dx,dy) \ - (BOOL)SNDMSGA((hwnd),LVM_SCROLL,(WPARAM)(INT)(dx),(LPARAM)(INT)(dy)) + (BOOL)SNDMSG((hwnd),LVM_SCROLL,(WPARAM)(INT)(dx),(LPARAM)(INT)(dy)) #define ListView_EnsureVisible(hwnd,i,fPartialOk) \ - (BOOL)SNDMSGA((hwnd),LVM_ENSUREVISIBLE,(WPARAM)(INT)i,(LPARAM)(BOOL)fPartialOk) + (BOOL)SNDMSG((hwnd),LVM_ENSUREVISIBLE,(WPARAM)(INT)i,(LPARAM)(BOOL)fPartialOk) #define ListView_SetBkColor(hwnd,clrBk) \ - (BOOL)SNDMSGA((hwnd),LVM_SETBKCOLOR,0,(LPARAM)(COLORREF)(clrBk)) + (BOOL)SNDMSG((hwnd),LVM_SETBKCOLOR,0,(LPARAM)(COLORREF)(clrBk)) #define ListView_SetImageList(hwnd,himl,iImageList) \ - (HIMAGELIST)SNDMSGA((hwnd),LVM_SETIMAGELIST,(WPARAM)(iImageList),(LPARAM)(HIMAGELIST)(himl)) + (HIMAGELIST)SNDMSG((hwnd),LVM_SETIMAGELIST,(WPARAM)(iImageList),(LPARAM)(HIMAGELIST)(himl)) #define ListView_GetItemCount(hwnd) \ - (INT)SNDMSGA((hwnd),LVM_GETITEMCOUNT,0,0L) + (INT)SNDMSG((hwnd),LVM_GETITEMCOUNT,0,0L) #define ListView_RedrawItems(hwnd,first,last) \ - (BOOL)SNDMSGA((hwnd),LVM_REDRAWITEMS,(WPARAM)(INT)(first),(LPARAM)(INT)(last)) + (BOOL)SNDMSG((hwnd),LVM_REDRAWITEMS,(WPARAM)(INT)(first),(LPARAM)(INT)(last)) #define ListView_GetEditControl(hwnd) \ - (HWND)SNDMSGA((hwnd), LVM_GETEDITCONTROL, 0, 0) + (HWND)SNDMSG((hwnd), LVM_GETEDITCONTROL, 0, 0) #define ListView_GetTextColor(hwnd) \ - (COLORREF)SNDMSGA((hwnd), LVM_GETTEXTCOLOR, 0, 0) + (COLORREF)SNDMSG((hwnd), LVM_GETTEXTCOLOR, 0, 0) #define ListView_GetTextBkColor(hwnd) \ - (COLORREF)SNDMSGA((hwnd), LVM_GETTEXTBKCOLOR, 0, 0) + (COLORREF)SNDMSG((hwnd), LVM_GETTEXTBKCOLOR, 0, 0) #define ListView_GetBkColor(hwnd) \ - (COLORREF)SNDMSGA((hwnd), LVM_GETBKCOLOR, 0, 0) + (COLORREF)SNDMSG((hwnd), LVM_GETBKCOLOR, 0, 0) #define ListView_GetItemA(hwnd,pitem) \ (BOOL)SNDMSGA((hwnd),LVM_GETITEMA,0,(LPARAM)(LVITEMA *)(pitem)) #define ListView_GetItemW(hwnd,pitem) \ (BOOL)SNDMSGW((hwnd),LVM_GETITEMW,0,(LPARAM)(LVITEMW *)(pitem)) #define ListView_GetItem WINELIB_NAME_AW(ListView_GetItem) #define ListView_GetOrigin(hwnd,ppt) \ - (BOOL)SNDMSGW((hwnd),LVM_GETORIGIN,0,(LPARAM)(POINT *)(ppt)) + (BOOL)SNDMSG((hwnd),LVM_GETORIGIN,0,(LPARAM)(POINT *)(ppt)) #define ListView_HitTest(hwnd,pinfo) \ - (INT)SNDMSGA((hwnd),LVM_HITTEST,0,(LPARAM)(LPLVHITTESTINFO)(pinfo)) + (INT)SNDMSG((hwnd),LVM_HITTEST,0,(LPARAM)(LPLVHITTESTINFO)(pinfo)) #define ListView_InsertItemA(hwnd,pitem) \ (INT)SNDMSGA((hwnd),LVM_INSERTITEMA,0,(LPARAM)(const LVITEMA *)(pitem)) @@ -3765,7 +3773,7 @@ typedef struct NMLVSCROLL #define ListView_InsertItem WINELIB_NAME_AW(ListView_InsertItem) #define ListView_DeleteAllItems(hwnd) \ - (BOOL)SNDMSGA((hwnd),LVM_DELETEALLITEMS,0,0L) + (BOOL)SNDMSG((hwnd),LVM_DELETEALLITEMS,0,0L) #define ListView_InsertColumnA(hwnd,iCol,pcol) \ (INT)SNDMSGA((hwnd),LVM_INSERTCOLUMNA,(WPARAM)(INT)(iCol),(LPARAM)(const LVCOLUMNA *)(pcol)) @@ -3774,19 +3782,19 @@ typedef struct NMLVSCROLL #define ListView_InsertColumn WINELIB_NAME_AW(ListView_InsertColumn) #define ListView_SortItems(hwndLV,_pfnCompare,_lPrm) \ - (BOOL)SNDMSGA((hwndLV),LVM_SORTITEMS,(WPARAM)(LPARAM)_lPrm,(LPARAM)(PFNLVCOMPARE)_pfnCompare) + (BOOL)SNDMSG((hwndLV),LVM_SORTITEMS,(WPARAM)(LPARAM)_lPrm,(LPARAM)(PFNLVCOMPARE)_pfnCompare) #define ListView_SortItemsEx(hwndLV, _pfnCompare, _lPrm) \ - (BOOL)SNDMSGA((hwndLV), LVM_SORTITEMSEX, (WPARAM)(LPARAM)(_lPrm), (LPARAM)(PFNLVCOMPARE)(_pfnCompare)) + (BOOL)SNDMSG((hwndLV), LVM_SORTITEMSEX, (WPARAM)(LPARAM)(_lPrm), (LPARAM)(PFNLVCOMPARE)(_pfnCompare)) #define ListView_SetItemPosition(hwndLV, i, x, y) \ - (BOOL)SNDMSGA((hwndLV),LVM_SETITEMPOSITION,(WPARAM)(INT)(i),MAKELPARAM((x),(y))) + (BOOL)SNDMSG((hwndLV),LVM_SETITEMPOSITION,(WPARAM)(INT)(i),MAKELPARAM((x),(y))) #define ListView_GetSelectedCount(hwndLV) \ - (UINT)SNDMSGA((hwndLV),LVM_GETSELECTEDCOUNT,0,0L) + (UINT)SNDMSG((hwndLV),LVM_GETSELECTEDCOUNT,0,0L) #define ListView_EditLabelA(hwndLV, i) \ - (HWND)SNDMSGA((hwndLV),LVM_EDITLABELA,(WPARAM)(int)(i), 0L) + (HWND)SNDMSG((hwndLV),LVM_EDITLABELA,(WPARAM)(int)(i), 0L) #define ListView_EditLabelW(hwndLV, i) \ - (HWND)SNDMSGW((hwndLV),LVM_EDITLABELW,(WPARAM)(int)(i), 0L) + (HWND)SNDMSG((hwndLV),LVM_EDITLABELW,(WPARAM)(int)(i), 0L) #define ListView_EditLabel WINELIB_NAME_AW(ListView_EditLabel) #define ListView_GetItemTextA(hwndLV, i, _iSubItem, _pszText, _cchTextMax) \ @@ -3807,7 +3815,7 @@ typedef struct NMLVSCROLL } #define ListView_GetItemText WINELIB_NAME_AW(ListView_GetItemText) #define ListView_SetItemPosition32(hwnd,n,x1,y1) \ -{ POINT ptNewPos; ptNewPos.x = (x1); ptNewPos.y = (y1); SNDMSGA((hwnd), LVM_SETITEMPOSITION32, (WPARAM)(int)(n), (LPARAM)&ptNewPos); } +{ POINT ptNewPos; ptNewPos.x = (x1); ptNewPos.y = (y1); SNDMSG((hwnd), LVM_SETITEMPOSITION32, (WPARAM)(int)(n), (LPARAM)&ptNewPos); } #define ListView_SetItemTextA(hwndLV, i, _iSubItem, _pszText) \ { LVITEMA _LVi; _LVi.iSubItem = _iSubItem; _LVi.pszText = _pszText;\ SNDMSGA(hwndLV, LVM_SETITEMTEXTA, (WPARAM)i, (LPARAM) (LVITEMA*)&_LVi);} @@ -3817,40 +3825,40 @@ typedef struct NMLVSCROLL #define ListView_SetItemText WINELIB_NAME_AW(ListView_SetItemText) #define ListView_DeleteItem(hwndLV, i) \ - (BOOL)SNDMSGA(hwndLV, LVM_DELETEITEM, (WPARAM)(int)(i), 0L) + (BOOL)SNDMSG(hwndLV, LVM_DELETEITEM, (WPARAM)(int)(i), 0L) #define ListView_Update(hwndLV, i) \ - (BOOL)SNDMSGA((hwndLV), LVM_UPDATE, (WPARAM)(i), 0L) + (BOOL)SNDMSG((hwndLV), LVM_UPDATE, (WPARAM)(i), 0L) #define ListView_GetColumnOrderArray(hwndLV, iCount, pi) \ - (BOOL)SNDMSGA((hwndLV), LVM_GETCOLUMNORDERARRAY, (WPARAM)iCount, (LPARAM)(LPINT)pi) + (BOOL)SNDMSG((hwndLV), LVM_GETCOLUMNORDERARRAY, (WPARAM)iCount, (LPARAM)(LPINT)pi) #define ListView_GetExtendedListViewStyle(hwndLV) \ - (DWORD)SNDMSGA((hwndLV), LVM_GETEXTENDEDLISTVIEWSTYLE, 0, 0L) + (DWORD)SNDMSG((hwndLV), LVM_GETEXTENDEDLISTVIEWSTYLE, 0, 0L) #define ListView_GetHotCursor(hwndLV) \ - (HCURSOR)SNDMSGA((hwndLV), LVM_GETHOTCURSOR, 0, 0L) + (HCURSOR)SNDMSG((hwndLV), LVM_GETHOTCURSOR, 0, 0L) #define ListView_GetHotItem(hwndLV) \ - (int)SNDMSGA((hwndLV), LVM_GETHOTITEM, 0, 0L) + (int)SNDMSG((hwndLV), LVM_GETHOTITEM, 0, 0L) #define ListView_GetItemSpacing(hwndLV, fSmall) \ - (DWORD)SNDMSGA((hwndLV), LVM_GETITEMSPACING, (WPARAM)fSmall, 0L) + (DWORD)SNDMSG((hwndLV), LVM_GETITEMSPACING, (WPARAM)fSmall, 0L) #define ListView_GetSubItemRect(hwndLV, iItem, iSubItem, code, prc) \ - (BOOL)SNDMSGA((hwndLV), LVM_GETSUBITEMRECT, (WPARAM)(int)(iItem), \ + (BOOL)SNDMSG((hwndLV), LVM_GETSUBITEMRECT, (WPARAM)(int)(iItem), \ ((prc) ? ((((LPRECT)(prc))->top = iSubItem), (((LPRECT)(prc))->left = code), (LPARAM)(prc)) : 0)) #define ListView_GetToolTips(hwndLV) \ - (HWND)SNDMSGA((hwndLV), LVM_GETTOOLTIPS, 0, 0L) + (HWND)SNDMSG((hwndLV), LVM_GETTOOLTIPS, 0, 0L) #define ListView_SetColumnOrderArray(hwndLV, iCount, pi) \ - (BOOL)SNDMSGA((hwndLV), LVM_SETCOLUMNORDERARRAY, (WPARAM)iCount, (LPARAM)(LPINT)pi) + (BOOL)SNDMSG((hwndLV), LVM_SETCOLUMNORDERARRAY, (WPARAM)iCount, (LPARAM)(LPINT)pi) #define ListView_SetExtendedListViewStyle(hwndLV, dw) \ - (DWORD)SNDMSGA((hwndLV), LVM_SETEXTENDEDLISTVIEWSTYLE, 0, (LPARAM)dw) + (DWORD)SNDMSG((hwndLV), LVM_SETEXTENDEDLISTVIEWSTYLE, 0, (LPARAM)dw) #define ListView_SetExtendedListViewStyleEx(hwndLV, dwMask, dw) \ - (DWORD)SNDMSGA((hwndLV), LVM_SETEXTENDEDLISTVIEWSTYLE, (WPARAM)dwMask, (LPARAM)dw) + (DWORD)SNDMSG((hwndLV), LVM_SETEXTENDEDLISTVIEWSTYLE, (WPARAM)dwMask, (LPARAM)dw) #define ListView_SetHotCursor(hwndLV, hcur) \ - (HCURSOR)SNDMSGA((hwndLV), LVM_SETHOTCURSOR, 0, (LPARAM)hcur) + (HCURSOR)SNDMSG((hwndLV), LVM_SETHOTCURSOR, 0, (LPARAM)hcur) #define ListView_SetHotItem(hwndLV, i) \ - (int)SNDMSGA((hwndLV), LVM_SETHOTITEM, (WPARAM)i, 0L) + (int)SNDMSG((hwndLV), LVM_SETHOTITEM, (WPARAM)i, 0L) #define ListView_SetIconSpacing(hwndLV, cx, cy) \ - (DWORD)SNDMSGA((hwndLV), LVM_SETICONSPACING, 0, MAKELONG(cx,cy)) + (DWORD)SNDMSG((hwndLV), LVM_SETICONSPACING, 0, MAKELONG(cx,cy)) #define ListView_SetToolTips(hwndLV, hwndNewHwnd) \ - (HWND)SNDMSGA((hwndLV), LVM_SETTOOLTIPS, (WPARAM)hwndNewHwnd, 0L) + (HWND)SNDMSG((hwndLV), LVM_SETTOOLTIPS, (WPARAM)hwndNewHwnd, 0L) #define ListView_SubItemHitTest(hwndLV, plvhti) \ - (int)SNDMSGA((hwndLV), LVM_SUBITEMHITTEST, 0, (LPARAM)(LPLVHITTESTINFO)(plvhti)) + (int)SNDMSG((hwndLV), LVM_SUBITEMHITTEST, 0, (LPARAM)(LPLVHITTESTINFO)(plvhti)) #define ListView_GetSelectionMark(hwndLV) \ (int)SNDMSG((hwndLV), LVM_GETSELECTIONMARK, 0, 0) #define ListView_SetSelectionMark(hwndLV, iItem) \ @@ -4027,11 +4035,11 @@ static const WCHAR WC_TABCONTROLW[] = { 'S','y','s', /* TabCtrl Macros */ #define TabCtrl_GetImageList(hwnd) \ - (HIMAGELIST)SNDMSGA((hwnd), TCM_GETIMAGELIST, 0, 0L) + (HIMAGELIST)SNDMSG((hwnd), TCM_GETIMAGELIST, 0, 0L) #define TabCtrl_SetImageList(hwnd, himl) \ - (HIMAGELIST)SNDMSGA((hwnd), TCM_SETIMAGELIST, 0, (LPARAM)(UINT)(HIMAGELIST)(himl)) + (HIMAGELIST)SNDMSG((hwnd), TCM_SETIMAGELIST, 0, (LPARAM)(UINT)(HIMAGELIST)(himl)) #define TabCtrl_GetItemCount(hwnd) \ - (int)SNDMSGA((hwnd), TCM_GETITEMCOUNT, 0, 0L) + (int)SNDMSG((hwnd), TCM_GETITEMCOUNT, 0, 0L) #define TabCtrl_GetItemA(hwnd, iItem, pitem) \ (BOOL)SNDMSGA((hwnd), TCM_GETITEMA, (WPARAM)(int)iItem, (LPARAM)(TCITEMA *)(pitem)) #define TabCtrl_GetItemW(hwnd, iItem, pitem) \ @@ -4048,49 +4056,49 @@ static const WCHAR WC_TABCONTROLW[] = { 'S','y','s', (int)SNDMSGW((hwnd), TCM_INSERTITEMW, (WPARAM)(int)iItem, (LPARAM)(const TCITEMW *)(pitem)) #define TabCtrl_InsertItem WINELIB_NAME_AW(TabCtrl_InsertItem) #define TabCtrl_DeleteItem(hwnd, i) \ - (BOOL)SNDMSGA((hwnd), TCM_DELETEITEM, (WPARAM)(int)(i), 0L) + (BOOL)SNDMSG((hwnd), TCM_DELETEITEM, (WPARAM)(int)(i), 0L) #define TabCtrl_DeleteAllItems(hwnd) \ - (BOOL)SNDMSGA((hwnd), TCM_DELETEALLITEMS, 0, 0L) + (BOOL)SNDMSG((hwnd), TCM_DELETEALLITEMS, 0, 0L) #define TabCtrl_GetItemRect(hwnd, i, prc) \ - (BOOL)SNDMSGA((hwnd), TCM_GETITEMRECT, (WPARAM)(int)(i), (LPARAM)(RECT *)(prc)) + (BOOL)SNDMSG((hwnd), TCM_GETITEMRECT, (WPARAM)(int)(i), (LPARAM)(RECT *)(prc)) #define TabCtrl_GetCurSel(hwnd) \ - (int)SNDMSGA((hwnd), TCM_GETCURSEL, 0, 0) + (int)SNDMSG((hwnd), TCM_GETCURSEL, 0, 0) #define TabCtrl_SetCurSel(hwnd, i) \ - (int)SNDMSGA((hwnd), TCM_SETCURSEL, (WPARAM)i, 0) + (int)SNDMSG((hwnd), TCM_SETCURSEL, (WPARAM)i, 0) #define TabCtrl_HitTest(hwndTC, pinfo) \ - (int)SNDMSGA((hwndTC), TCM_HITTEST, 0, (LPARAM)(TC_HITTESTINFO *)(pinfo)) + (int)SNDMSG((hwndTC), TCM_HITTEST, 0, (LPARAM)(TC_HITTESTINFO *)(pinfo)) #define TabCtrl_SetItemExtra(hwndTC, cb) \ - (BOOL)SNDMSGA((hwndTC), TCM_SETITEMEXTRA, (WPARAM)(cb), 0L) + (BOOL)SNDMSG((hwndTC), TCM_SETITEMEXTRA, (WPARAM)(cb), 0L) #define TabCtrl_AdjustRect(hwnd, bLarger, prc) \ - (int)SNDMSGA(hwnd, TCM_ADJUSTRECT, (WPARAM)(BOOL)bLarger, (LPARAM)(RECT *)prc) + (int)SNDMSG(hwnd, TCM_ADJUSTRECT, (WPARAM)(BOOL)bLarger, (LPARAM)(RECT *)prc) #define TabCtrl_SetItemSize(hwnd, x, y) \ - (DWORD)SNDMSGA((hwnd), TCM_SETITEMSIZE, 0, MAKELPARAM(x,y)) + (DWORD)SNDMSG((hwnd), TCM_SETITEMSIZE, 0, MAKELPARAM(x,y)) #define TabCtrl_RemoveImage(hwnd, i) \ - (void)SNDMSGA((hwnd), TCM_REMOVEIMAGE, i, 0L) + (void)SNDMSG((hwnd), TCM_REMOVEIMAGE, i, 0L) #define TabCtrl_SetPadding(hwnd, cx, cy) \ - (void)SNDMSGA((hwnd), TCM_SETPADDING, 0, MAKELPARAM(cx, cy)) + (void)SNDMSG((hwnd), TCM_SETPADDING, 0, MAKELPARAM(cx, cy)) #define TabCtrl_GetRowCount(hwnd) \ - (int)SNDMSGA((hwnd), TCM_GETROWCOUNT, 0, 0L) + (int)SNDMSG((hwnd), TCM_GETROWCOUNT, 0, 0L) #define TabCtrl_GetToolTips(hwnd) \ - (HWND)SNDMSGA((hwnd), TCM_GETTOOLTIPS, 0, 0L) + (HWND)SNDMSG((hwnd), TCM_GETTOOLTIPS, 0, 0L) #define TabCtrl_SetToolTips(hwnd, hwndTT) \ - (void)SNDMSGA((hwnd), TCM_SETTOOLTIPS, (WPARAM)hwndTT, 0L) + (void)SNDMSG((hwnd), TCM_SETTOOLTIPS, (WPARAM)hwndTT, 0L) #define TabCtrl_GetCurFocus(hwnd) \ - (int)SNDMSGA((hwnd), TCM_GETCURFOCUS, 0, 0) + (int)SNDMSG((hwnd), TCM_GETCURFOCUS, 0, 0) #define TabCtrl_SetCurFocus(hwnd, i) \ - SNDMSGA((hwnd),TCM_SETCURFOCUS, i, 0) + SNDMSG((hwnd),TCM_SETCURFOCUS, i, 0) #define TabCtrl_SetMinTabWidth(hwnd, x) \ - (int)SNDMSGA((hwnd), TCM_SETMINTABWIDTH, 0, x) + (int)SNDMSG((hwnd), TCM_SETMINTABWIDTH, 0, x) #define TabCtrl_DeselectAll(hwnd, fExcludeFocus)\ - (void)SNDMSGA((hwnd), TCM_DESELECTALL, fExcludeFocus, 0) + (void)SNDMSG((hwnd), TCM_DESELECTALL, fExcludeFocus, 0) #define TabCtrl_GetUnicodeFormat(hwnd) \ - (BOOL)SNDMSGA((hwnd), TCM_GETUNICODEFORMAT, 0, 0) + (BOOL)SNDMSG((hwnd), TCM_GETUNICODEFORMAT, 0, 0) #define TabCtrl_SetUnicodeFormat(hwnd, fUnicode) \ - (BOOL)SNDMSGA((hwnd), TCM_SETUNICODEFORMAT, (WPARAM)fUnicode, 0) + (BOOL)SNDMSG((hwnd), TCM_SETUNICODEFORMAT, (WPARAM)fUnicode, 0) #define TabCtrl_GetExtendedStyle(hwnd) \ - (BOOL)SNDMSGA((hwnd), TCM_GETEXTENDEDSTYLE, 0, 0) + (BOOL)SNDMSG((hwnd), TCM_GETEXTENDEDSTYLE, 0, 0) #define TabCtrl_SetExtendedStyle(hwnd, dwExStyle) \ - (BOOL)SNDMSGA((hwnd), TCM_GETEXTENDEDSTYLE, 0, (LPARAM)dwExStyle) + (BOOL)SNDMSG((hwnd), TCM_GETEXTENDEDSTYLE, 0, (LPARAM)dwExStyle) #define TabCtrl_HighlightItem(hwnd, i, fHighlight) \ (BOOL)SNDMSG((hwnd), TCM_HIGHLIGHTITEM, (WPARAM)i, (LPARAM)MAKELONG(fHighlight, 0)) @@ -4419,13 +4427,13 @@ static const WCHAR ANIMATE_CLASSW[] = { 'S','y','s', (BOOL)SNDMSGW(hwnd,ACM_OPENW,(WPARAM)hInst,(LPARAM)(LPWSTR)(szName)) #define Animate_OpenEx WINELIB_NAME_AW(Animate_OpenEx) #define Animate_Play(hwnd,from,to,rep) \ - (BOOL)SNDMSGA(hwnd,ACM_PLAY,(WPARAM)(UINT)(rep),(LPARAM)MAKELONG(from,to)) + (BOOL)SNDMSG(hwnd,ACM_PLAY,(WPARAM)(UINT)(rep),(LPARAM)MAKELONG(from,to)) #define Animate_Stop(hwnd) \ - (BOOL)SNDMSGA(hwnd,ACM_STOP,0,0) + (BOOL)SNDMSG(hwnd,ACM_STOP,0,0) #define Animate_Close(hwnd) \ - (BOOL)SNDMSGA(hwnd,ACM_OPENA,0,0) + (BOOL)SNDMSG(hwnd,ACM_OPENA,0,0) #define Animate_Seek(hwnd,frame) \ - (BOOL)SNDMSGA(hwnd,ACM_PLAY,1,(LPARAM)MAKELONG(frame,frame)) + (BOOL)SNDMSG(hwnd,ACM_PLAY,1,(LPARAM)MAKELONG(frame,frame)) /************************************************************************** diff --git a/include/gdiplusenums.h b/include/gdiplusenums.h index c989000f12d..9997bf1dfd9 100644 --- a/include/gdiplusenums.h +++ b/include/gdiplusenums.h @@ -181,6 +181,11 @@ enum ImageType ImageTypeMetafile }; +enum WarpMode { + WarpModePerspective, + WarpModeBilinear +}; + enum WrapMode { WrapModeTile, @@ -436,6 +441,7 @@ typedef enum DashStyle DashStyle; typedef enum MatrixOrder MatrixOrder; typedef enum ImageType ImageType; typedef enum ImageFlags ImageFlags; +typedef enum WarpMode WarpMode; typedef enum WrapMode WrapMode; typedef enum MetafileType MetafileType; typedef enum LinearGradientMode LinearGradientMode; diff --git a/include/msctf.idl b/include/msctf.idl index 7e643f464f0..40853eea282 100644 --- a/include/msctf.idl +++ b/include/msctf.idl @@ -699,3 +699,17 @@ interface ITfClientId : IUnknown [in] REFCLSID rclsid, [out] TfClientId *ptid); }; + +[ + object, + uuid(43c9fe15-f494-4c17-9de2-b8a4ac350aa8), + pointer_default(unique) +] +interface ITfLanguageProfileNotifySink : IUnknown +{ + HRESULT OnLanguageChange( + [in] LANGID langid, + [out] BOOL *pfAccept); + + HRESULT OnLanguageChanged(); +} diff --git a/include/setupapi.h b/include/setupapi.h index 009af29595a..c4e16641165 100644 --- a/include/setupapi.h +++ b/include/setupapi.h @@ -1391,6 +1391,9 @@ typedef enum { /* SetupConfigureWmiFromInfSection Flags values */ #define SCWMI_CLOBBER_SECURITY 0x00000001 +/* SetupUninstallOEMInf Flags values */ +#define SUOI_FORCEDELETE 0x00000001 + LONG WINAPI AddTagToGroupOrderList(PCWSTR lpGroupName, DWORD dwUnknown2, DWORD dwUnknown3); DWORD WINAPI CaptureAndConvertAnsiArg(PCSTR lpSrc, PWSTR *lpDst); DWORD WINAPI CaptureStringArg(PCWSTR lpSrc, PWSTR *lpDst); diff --git a/include/wine/wined3d.idl b/include/wine/wined3d.idl index db23df921cb..7a476e858e1 100644 --- a/include/wine/wined3d.idl +++ b/include/wine/wined3d.idl @@ -848,6 +848,19 @@ typedef enum _WINED3DSURFTYPE SURFACE_GDI, /* User surface. No 3D, DirectDraw rendering with GDI */ } WINED3DSURFTYPE; +enum wined3d_sysval_semantic +{ + WINED3D_SV_DEPTH = 0xffffffff, + WINED3D_SV_TARGET0 = 0, + WINED3D_SV_TARGET1 = 1, + WINED3D_SV_TARGET2 = 2, + WINED3D_SV_TARGET3 = 3, + WINED3D_SV_TARGET4 = 4, + WINED3D_SV_TARGET5 = 5, + WINED3D_SV_TARGET6 = 6, + WINED3D_SV_TARGET7 = 7, +}; + const UINT WINED3DCOLORWRITEENABLE_RED = (1<<0); const UINT WINED3DCOLORWRITEENABLE_GREEN = (1<<1); const UINT WINED3DCOLORWRITEENABLE_BLUE = (1<<2); @@ -2117,6 +2130,23 @@ struct wined3d_buffer_desc UINT misc_flags; }; +struct wined3d_shader_signature_element +{ + const char *semantic_name; + UINT semantic_idx; + enum wined3d_sysval_semantic sysval_semantic; + DWORD component_type; + UINT register_idx; + DWORD mask; +}; + +struct wined3d_shader_signature +{ + UINT element_count; + struct wined3d_shader_signature_element *elements; + char *string_data; +}; + interface IWineD3DResource; interface IWineD3DSurface; interface IWineD3DVolume; @@ -2586,10 +2616,6 @@ interface IWineD3DBaseTexture : IWineD3DResource ); BOOL IsCondNP2( ); - void ApplyStateChanges( - const DWORD texture_states[WINED3D_HIGHEST_TEXTURE_STATE + 1], - const DWORD sampler_states[WINED3D_HIGHEST_SAMPLER_STATE + 1] - ); } [ @@ -2823,7 +2849,8 @@ interface IWineD3DBuffer : IWineD3DResource interface IWineD3DBaseShader : IWineD3DBase { HRESULT SetFunction( - [in] const DWORD *function + [in] const DWORD *function, + [in] const struct wined3d_shader_signature *output_signature ); } @@ -2991,6 +3018,7 @@ interface IWineD3DDevice : IWineD3DBase ); HRESULT CreatePixelShader( [in] const DWORD *function, + [in] const struct wined3d_shader_signature *output_signature, [out] IWineD3DPixelShader **shader, [in] IUnknown *parent ); diff --git a/include/winineti.h b/include/winineti.h index 98cba3b5da0..27efa50a42b 100644 --- a/include/winineti.h +++ b/include/winineti.h @@ -90,9 +90,11 @@ extern "C" { #endif DWORD WINAPI DeleteIE3Cache(HWND,HINSTANCE,LPSTR,int); +BOOL WINAPI GetDiskInfoA(PCSTR,PDWORD,PDWORDLONG,PDWORDLONG); BOOL WINAPI GetUrlCacheConfigInfoA(LPINTERNET_CACHE_CONFIG_INFOA,LPDWORD,DWORD); BOOL WINAPI GetUrlCacheConfigInfoW(LPINTERNET_CACHE_CONFIG_INFOW,LPDWORD,DWORD); #define GetUrlCacheConfigInfo WINELIB_NAME_AW(GetUrlCacheConfigInfo) +BOOL WINAPI IncrementUrlCacheHeaderData(DWORD,LPDWORD); BOOL WINAPI InternetQueryFortezzaStatus(DWORD*,DWORD_PTR); BOOL WINAPI IsUrlCacheEntryExpiredA(LPCSTR,DWORD,FILETIME*); BOOL WINAPI IsUrlCacheEntryExpiredW(LPCWSTR,DWORD,FILETIME*); diff --git a/include/winnt.h b/include/winnt.h index abcc50205a1..93c796124fc 100644 --- a/include/winnt.h +++ b/include/winnt.h @@ -291,10 +291,8 @@ extern "C" { #if defined(_MSC_VER) # define C_ASSERT(e) typedef char __C_ASSERT__[(e)?1:-1] -#elif defined(__GNUC__) -# define C_ASSERT(e) extern char __C_ASSERT__[(e)?1:-1] __attribute__((unused)) #else -# define C_ASSERT(e) +# define C_ASSERT(e) extern void __C_ASSERT__(int [(e)?1:-1]) #endif /* Eliminate Microsoft C/C++ compiler warning 4715 */ diff --git a/programs/notepad/Nl.rc b/programs/notepad/Nl.rc index e2d921363aa..e4d12217c64 100644 --- a/programs/notepad/Nl.rc +++ b/programs/notepad/Nl.rc @@ -49,15 +49,16 @@ POPUP "Be&werken" { MENUITEM "&Lettertype instellen...", CMD_FONT } POPUP "&Zoeken" { - MENUITEM "&Zoeken...\tCtrl+Z", CMD_SEARCH - MENUITEM "&Volgende zoeken\tF3", CMD_SEARCH_NEXT + MENUITEM "&Zoeken...\tCtrl+Z", CMD_SEARCH + MENUITEM "V&olgende zoeken\tF3", CMD_SEARCH_NEXT + MENUITEM "&Vervangen...\tCtrl+H", CMD_REPLACE } POPUP "&Help" { MENUITEM "&Help-onderwerpen", CMD_HELP_CONTENTS MENUITEM "&Zoeken...", CMD_HELP_SEARCH MENUITEM "&Hulp bij Help", CMD_HELP_ON_HELP MENUITEM SEPARATOR - MENUITEM "&About Notepad", CMD_HELP_ABOUT_NOTEPAD + MENUITEM "&Over Notepad", CMD_HELP_ABOUT_NOTEPAD } } diff --git a/programs/notepad/Sv.rc b/programs/notepad/Sv.rc index fdd6660af08..7e4aa294c1f 100644 --- a/programs/notepad/Sv.rc +++ b/programs/notepad/Sv.rc @@ -54,6 +54,7 @@ POPUP "&Redigera" { POPUP "&Sök" { MENUITEM "Sök...", CMD_SEARCH MENUITEM "&Sök nästa\tF3", CMD_SEARCH_NEXT + MENUITEM "&Ersätt...\tCtrl+H", CMD_REPLACE } POPUP "&Hjälp" { MENUITEM "&Innehåll", CMD_HELP_CONTENTS diff --git a/programs/regedit/Sv.rc b/programs/regedit/Sv.rc index b47b0502909..dd384d9ada6 100644 --- a/programs/regedit/Sv.rc +++ b/programs/regedit/Sv.rc @@ -281,6 +281,7 @@ BEGIN ID_EDIT_COPYKEYNAME "Kopierar namnet på den valda nyckeln till utklipp" ID_EDIT_FIND "Söker en textsträng i nyckel, värde eller data" ID_EDIT_FINDNEXT "Söker nästa träff till texten specificerad i föregående sökning" + ID_EDIT_EXPORT "Exporterar vald gren av registret till en textfil" END STRINGTABLE DISCARDABLE diff --git a/programs/winecfg/audio.c b/programs/winecfg/audio.c index 9c2cde3bd55..b9a310cfdf8 100644 --- a/programs/winecfg/audio.c +++ b/programs/winecfg/audio.c @@ -544,7 +544,10 @@ static void findAudioDrivers(void) static void checkRegistrySetting(HWND hDlg) { const AUDIO_DRIVER *pAudioDrv; - char * token, * tokens = strdup(curAudioDriver); + char * token, * tokens; + + tokens = HeapAlloc(GetProcessHeap(), 0, strlen(curAudioDriver)+1); + strcpy(tokens, curAudioDriver); start_over: token = strtok(tokens, ","); @@ -582,7 +585,7 @@ start_over: } token = strtok(NULL, ","); } - free(tokens); + HeapFree(GetProcessHeap(), 0, tokens); } static void selectDriver(HWND hDlg, const char * driver) diff --git a/programs/winedbg/gdbproxy.c b/programs/winedbg/gdbproxy.c index 9026b372693..680caeabc82 100644 --- a/programs/winedbg/gdbproxy.c +++ b/programs/winedbg/gdbproxy.c @@ -823,12 +823,20 @@ static void get_thread_info(struct gdb_context* gdbctx, unsigned tid, enum packet_return {packet_error = 0x00, packet_ok = 0x01, packet_done = 0x02, packet_last_f = 0x80}; +static char* packet_realloc(char* buf, int size) +{ + if (!buf) + return HeapAlloc(GetProcessHeap(), 0, size); + return HeapReAlloc(GetProcessHeap(), 0, buf, size); + +} + static void packet_reply_grow(struct gdb_context* gdbctx, size_t size) { if (gdbctx->out_buf_alloc < gdbctx->out_len + size) { gdbctx->out_buf_alloc = ((gdbctx->out_len + size) / 32 + 1) * 32; - gdbctx->out_buf = realloc(gdbctx->out_buf, gdbctx->out_buf_alloc); + gdbctx->out_buf = packet_realloc(gdbctx->out_buf, gdbctx->out_buf_alloc); } } @@ -2105,7 +2113,7 @@ static int fetch_data(struct gdb_context* gdbctx) { #define STEP 128 if (gdbctx->in_len + STEP > gdbctx->in_buf_alloc) - gdbctx->in_buf = realloc(gdbctx->in_buf, gdbctx->in_buf_alloc += STEP); + gdbctx->in_buf = packet_realloc(gdbctx->in_buf, gdbctx->in_buf_alloc += STEP); #undef STEP if (gdbctx->trace & GDBPXY_TRC_LOWLEVEL) fprintf(stderr, "%d %d %*.*s\n", diff --git a/programs/winhlp32/macro.c b/programs/winhlp32/macro.c index 0eeaa9b2b27..9e6e5f8865e 100644 --- a/programs/winhlp32/macro.c +++ b/programs/winhlp32/macro.c @@ -47,6 +47,14 @@ static unsigned MACRO_NumLoaded /* = 0 */; /******* helper functions *******/ +static char* StrDup(const char* str) +{ + char* dst; + dst=HeapAlloc(GetProcessHeap(),0,strlen(str)+1); + strcpy(dst, str); + return dst; +} + static WINHELP_BUTTON** MACRO_LookupButton(WINHELP_WINDOW* win, LPCSTR name) { WINHELP_BUTTON** b; @@ -711,7 +719,7 @@ static void CALLBACK MACRO_RegisterRoutine(LPCSTR dll_name, LPCSTR proc, LPCSTR else if ((dll = HeapAlloc(GetProcessHeap(), 0, sizeof(*dll)))) { dll->hLib = hLib; - dll->name = strdup(dll_name); /* FIXME */ + dll->name = StrDup(dll_name); /* FIXME: never freed */ dll->next = Globals.dlls; Globals.dlls = dll; dll->handler = (WINHELP_LDLLHandler)GetProcAddress(dll->hLib, "LDLLHandler"); @@ -731,10 +739,10 @@ static void CALLBACK MACRO_RegisterRoutine(LPCSTR dll_name, LPCSTR proc, LPCSTR size = ++MACRO_NumLoaded * sizeof(struct MacroDesc); if (!MACRO_Loaded) MACRO_Loaded = HeapAlloc(GetProcessHeap(), 0, size); else MACRO_Loaded = HeapReAlloc(GetProcessHeap(), 0, MACRO_Loaded, size); - MACRO_Loaded[MACRO_NumLoaded - 1].name = strdup(proc); /* FIXME */ + MACRO_Loaded[MACRO_NumLoaded - 1].name = StrDup(proc); /* FIXME: never freed */ MACRO_Loaded[MACRO_NumLoaded - 1].alias = NULL; MACRO_Loaded[MACRO_NumLoaded - 1].isBool = 0; - MACRO_Loaded[MACRO_NumLoaded - 1].arguments = strdup(args); /* FIXME */ + MACRO_Loaded[MACRO_NumLoaded - 1].arguments = StrDup(args); /* FIXME: never freed */ MACRO_Loaded[MACRO_NumLoaded - 1].fn = fn; WINE_TRACE("Added %s(%s) at %p\n", proc, args, fn); } diff --git a/tools/sfnt2fnt.c b/tools/sfnt2fnt.c index 6880ee895ce..de19d8fb263 100644 --- a/tools/sfnt2fnt.c +++ b/tools/sfnt2fnt.c @@ -414,7 +414,7 @@ static struct fontinfo *fill_fontinfo( const char *face_name, int ppem, int enc, info->dfCharTable[i].offset = start + (width_bytes * ppem); info->hdr.fi.dfType = 0; - info->hdr.fi.dfPoints = ((ppem - il) * 72 + dpi/2) / dpi; + info->hdr.fi.dfPoints = ((ppem - il - el) * 72 + dpi/2) / dpi; info->hdr.fi.dfVertRes = dpi; info->hdr.fi.dfHorizRes = dpi; info->hdr.fi.dfAscent = ascent; diff --git a/tools/winedump/Makefile.in b/tools/winedump/Makefile.in index 6f7f1d28c6b..34445ad60eb 100644 --- a/tools/winedump/Makefile.in +++ b/tools/winedump/Makefile.in @@ -13,6 +13,7 @@ C_SRCS = \ dos.c \ dump.c \ emf.c \ + font.c \ le.c \ lib.c \ lnk.c \ diff --git a/tools/winedump/dump.c b/tools/winedump/dump.c index 9c8f2ff53cb..e882c3cd550 100644 --- a/tools/winedump/dump.c +++ b/tools/winedump/dump.c @@ -242,6 +242,7 @@ dumpers[] = {SIG_MDMP, get_kind_mdmp, mdmp_dump}, {SIG_LNK, get_kind_lnk, lnk_dump}, {SIG_EMF, get_kind_emf, emf_dump}, + {SIG_FNT, get_kind_fnt, fnt_dump}, {SIG_UNKNOWN, NULL, NULL} /* sentinel */ }; diff --git a/tools/winedump/font.c b/tools/winedump/font.c new file mode 100644 index 00000000000..76710b80397 --- /dev/null +++ b/tools/winedump/font.c @@ -0,0 +1,139 @@ +/* + * Dump a font file + * + * Copyright 2009 Dmitry Timoshkov + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "config.h" +#include "wine/port.h" + +#include +#include +#include +#ifdef HAVE_UNISTD_H +# include +#endif +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_SYS_MMAN_H +#include +#endif +#include + +#define NONAMELESSUNION +#define NONAMELESSSTRUCT +#include "windef.h" +#include "winbase.h" +#include "winnt.h" + +#include "winedump.h" + +#include +typedef struct +{ + INT16 dfType; + INT16 dfPoints; + INT16 dfVertRes; + INT16 dfHorizRes; + INT16 dfAscent; + INT16 dfInternalLeading; + INT16 dfExternalLeading; + BYTE dfItalic; + BYTE dfUnderline; + BYTE dfStrikeOut; + INT16 dfWeight; + BYTE dfCharSet; + INT16 dfPixWidth; + INT16 dfPixHeight; + BYTE dfPitchAndFamily; + INT16 dfAvgWidth; + INT16 dfMaxWidth; + BYTE dfFirstChar; + BYTE dfLastChar; + BYTE dfDefaultChar; + BYTE dfBreakChar; + INT16 dfWidthBytes; + LONG dfDevice; + LONG dfFace; + LONG dfBitsPointer; + LONG dfBitsOffset; + BYTE dfReserved; + /* Fields, introduced for Windows 3.x fonts */ + LONG dfFlags; + INT16 dfAspace; + INT16 dfBspace; + INT16 dfCspace; + LONG dfColorPointer; + LONG dfReserved1[4]; +} FONTINFO16; + +typedef struct +{ + SHORT dfVersion; /* Version */ + LONG dfSize; /* Total File Size */ + char dfCopyright[60]; /* Copyright notice */ + FONTINFO16 fi; /* FONTINFO structure */ +} WINFNT; +#include + +/* FIXME: recognize and dump also NE/PE wrapped fonts */ + +enum FileSig get_kind_fnt(void) +{ + const WINFNT *fnt = PRD(0, sizeof(WINFNT)); + if (fnt && (fnt->dfVersion == 0x200 || fnt->dfVersion == 0x300) && + PRD(0, fnt->dfSize) != NULL) + return SIG_FNT; + return SIG_UNKNOWN; +} + +void fnt_dump(void) +{ + const WINFNT *fnt = PRD(0, sizeof(WINFNT)); + + printf("dfVersion %#x, dfSize %d bytes, dfCopyright %.60s\n", + fnt->dfVersion, fnt->dfSize, fnt->dfCopyright); + printf("dfType %d\n" + "dfPoints %d\n" + "dfVertRes %d\n" + "dfHorizRes %d\n" + "dfAscent %d\n" + "dfInternalLeading %d\n" + "dfExternalLeading %d\n" + "dfItalic %d\n" + "dfUnderline %d\n" + "dfStrikeOut %d\n" + "dfWeight %d\n" + "dfCharSet %d\n" + "dfPixWidth %d\n" + "dfPixHeight %d\n" + "dfPitchAndFamily %#x\n" + "dfAvgWidth %d\n" + "dfMaxWidth %d\n" + "dfFirstChar %#x\n" + "dfLastChar %#x\n" + "dfDefaultChar %#x\n" + "dfBreakChar %#x\n" + "dfWidthBytes %d\n", + fnt->fi.dfType, fnt->fi.dfPoints, fnt->fi.dfVertRes, fnt->fi.dfHorizRes, + fnt->fi.dfAscent, fnt->fi.dfInternalLeading, fnt->fi.dfExternalLeading, + fnt->fi.dfItalic, fnt->fi.dfUnderline, fnt->fi.dfStrikeOut, fnt->fi.dfWeight, + fnt->fi.dfCharSet, fnt->fi.dfPixWidth, fnt->fi.dfPixHeight, fnt->fi.dfPitchAndFamily, + fnt->fi.dfAvgWidth, fnt->fi.dfMaxWidth, fnt->fi.dfFirstChar, fnt->fi.dfLastChar, + fnt->fi.dfDefaultChar, fnt->fi.dfBreakChar, fnt->fi.dfWidthBytes); +} diff --git a/tools/winedump/winedump.h b/tools/winedump/winedump.h index f71103e09f1..4b8984210b9 100644 --- a/tools/winedump/winedump.h +++ b/tools/winedump/winedump.h @@ -217,7 +217,7 @@ char *str_toupper (char *str); const char *get_machine_str(int mach); /* file dumping functions */ -enum FileSig {SIG_UNKNOWN, SIG_DOS, SIG_PE, SIG_DBG, SIG_PDB, SIG_NE, SIG_LE, SIG_MDMP, SIG_COFFLIB, SIG_LNK, SIG_EMF}; +enum FileSig {SIG_UNKNOWN, SIG_DOS, SIG_PE, SIG_DBG, SIG_PDB, SIG_NE, SIG_LE, SIG_MDMP, SIG_COFFLIB, SIG_LNK, SIG_EMF, SIG_FNT}; const void* PRD(unsigned long prd, unsigned long len); unsigned long Offset(const void* ptr); @@ -252,6 +252,8 @@ enum FileSig get_kind_emf(void); void emf_dump( void ); enum FileSig get_kind_pdb(void); void pdb_dump(void); +enum FileSig get_kind_fnt(void); +void fnt_dump( void ); int codeview_dump_symbols(const void* root, unsigned long size); int codeview_dump_types_from_offsets(const void* table, const DWORD* offsets, unsigned num_types); int codeview_dump_types_from_block(const void* table, unsigned long len); -- 2.11.4.GIT