First step in using faster approach for A<->W message mapping
Dmitry Timoshkov
dmitry at baikal.ru
Thu Feb 19 21:44:40 CST 2004
Hello,
this is a very first patch aiming to use a faster approach for
message mapping routines. It just converts WM_[NC]CREATE W->A case
for now. Gradually we can convert all remaining paths and messages.
Changelog:
Dmitry Timoshkov <dmitry at codeweavers.com>
First step in using faster approach for A<->W message mapping.
diff -u cvs/hq/wine/dlls/user/winproc.h wine/dlls/user/winproc.h
--- cvs/hq/wine/dlls/user/winproc.h 2004-02-12 15:35:47.000000000 +0800
+++ wine/dlls/user/winproc.h 2004-02-20 11:21:31.000000000 +0800
@@ -67,8 +67,6 @@ extern WINDOWPROCTYPE WINPROC_GetProcTyp
extern INT WINPROC_MapMsg32ATo32W( HWND hwnd, UINT msg, WPARAM *pwparam,
LPARAM *plparam );
-extern INT WINPROC_MapMsg32WTo32A( HWND hwnd, UINT msg, WPARAM *pwparam,
- LPARAM *plparam );
extern INT WINPROC_MapMsg16To32A( HWND hwnd, UINT16 msg16, WPARAM16 wParam16,
UINT *pmsg32, WPARAM *pwparam32,
LPARAM *plparam );
@@ -83,8 +81,6 @@ extern INT WINPROC_MapMsg32WTo16( HWND h
WPARAM16 *pwparam16, LPARAM *plparam );
extern LRESULT WINPROC_UnmapMsg32ATo32W( HWND hwnd, UINT msg, WPARAM wParam,
LPARAM lParam, LRESULT result );
-extern LRESULT WINPROC_UnmapMsg32WTo32A( HWND hwnd, UINT msg, WPARAM wParam,
- LPARAM lParam, LRESULT result );
extern LRESULT WINPROC_UnmapMsg16To32A( HWND hwnd, UINT msg, WPARAM wParam,
LPARAM lParam, LRESULT result );
extern LRESULT WINPROC_UnmapMsg16To32W( HWND hwnd, UINT msg, WPARAM wParam,
diff -u cvs/hq/wine/windows/winproc.c wine/windows/winproc.c
--- cvs/hq/wine/windows/winproc.c 2004-01-29 15:56:08.000000000 +0800
+++ wine/windows/winproc.c 2004-02-20 11:28:15.000000000 +0800
@@ -954,7 +954,7 @@ LRESULT WINPROC_UnmapMsg32ATo32W( HWND h
* Map a message from Unicode to Ansi.
* Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
*/
-INT WINPROC_MapMsg32WTo32A( HWND hwnd, UINT msg, WPARAM *pwparam, LPARAM *plparam )
+static INT WINPROC_MapMsg32WTo32A( HWND hwnd, UINT msg, WPARAM *pwparam, LPARAM *plparam )
{
switch(msg)
{
@@ -980,41 +980,6 @@ INT WINPROC_MapMsg32WTo32A( HWND hwnd, U
*plparam = (LPARAM)HEAP_strdupWtoA( GetProcessHeap(), 0, (LPCWSTR)*plparam );
return (*plparam ? 1 : -1);
- case WM_NCCREATE:
- case WM_CREATE:
- {
- CREATESTRUCTA *cs = (CREATESTRUCTA *)HeapAlloc( GetProcessHeap(), 0,
- sizeof(*cs) );
- if (!cs) return -1;
- *cs = *(CREATESTRUCTA *)*plparam;
- if (HIWORD(cs->lpszName))
- cs->lpszName = HEAP_strdupWtoA( GetProcessHeap(), 0,
- (LPCWSTR)cs->lpszName );
- if (HIWORD(cs->lpszClass))
- cs->lpszClass = HEAP_strdupWtoA( GetProcessHeap(), 0,
- (LPCWSTR)cs->lpszClass);
-
- if (GetWindowLongW(hwnd, GWL_EXSTYLE) & WS_EX_MDICHILD)
- {
- MDICREATESTRUCTA *mdi_cs = (MDICREATESTRUCTA *)HeapAlloc(GetProcessHeap(), 0,
- sizeof(*mdi_cs));
- if (!mdi_cs)
- {
- HeapFree(GetProcessHeap(), 0, cs);
- return -1;
- }
- *mdi_cs = *(MDICREATESTRUCTA *)cs->lpCreateParams;
- if (HIWORD(mdi_cs->szTitle))
- mdi_cs->szTitle = HEAP_strdupWtoA(GetProcessHeap(), 0,
- (LPCWSTR)mdi_cs->szTitle);
- if (HIWORD(mdi_cs->szClass))
- mdi_cs->szClass = HEAP_strdupWtoA(GetProcessHeap(), 0,
- (LPCWSTR)mdi_cs->szClass);
- cs->lpCreateParams = (LPVOID)mdi_cs;
- }
- *plparam = (LPARAM)cs;
- }
- return 1;
case WM_MDICREATE:
{
MDICREATESTRUCTA *cs =
@@ -1126,7 +1091,7 @@ INT WINPROC_MapMsg32WTo32A( HWND hwnd, U
*
* Unmap a message that was mapped from Unicode to Ansi.
*/
-LRESULT WINPROC_UnmapMsg32WTo32A( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam, LRESULT result )
+static LRESULT WINPROC_UnmapMsg32WTo32A( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam, LRESULT result )
{
switch(msg)
{
@@ -1156,27 +1121,6 @@ LRESULT WINPROC_UnmapMsg32WTo32A( HWND h
HeapFree( GetProcessHeap(), 0, (void *)lParam );
break;
- case WM_NCCREATE:
- case WM_CREATE:
- {
- CREATESTRUCTA *cs = (CREATESTRUCTA *)lParam;
- if (HIWORD(cs->lpszName))
- HeapFree( GetProcessHeap(), 0, (LPVOID)cs->lpszName );
- if (HIWORD(cs->lpszClass))
- HeapFree( GetProcessHeap(), 0, (LPVOID)cs->lpszClass );
- if (GetWindowLongW(hwnd, GWL_EXSTYLE) & WS_EX_MDICHILD)
- {
- MDICREATESTRUCTA *mdi_cs = (MDICREATESTRUCTA *)cs->lpCreateParams;
- if (HIWORD(mdi_cs->szTitle))
- HeapFree(GetProcessHeap(), 0, (LPVOID)mdi_cs->szTitle);
- if (HIWORD(mdi_cs->szClass))
- HeapFree(GetProcessHeap(), 0, (LPVOID)mdi_cs->szClass);
- HeapFree(GetProcessHeap(), 0, mdi_cs);
- }
- HeapFree( GetProcessHeap(), 0, cs );
- }
- break;
-
case WM_MDICREATE:
{
MDICREATESTRUCTA *cs = (MDICREATESTRUCTA *)lParam;
@@ -2879,6 +2823,84 @@ static LRESULT WINPROC_CallProc32ATo32W(
/**********************************************************************
+ * WINPROC_CallProc32WTo32A_fast
+ *
+ */
+static BOOL WINPROC_CallProc32WTo32A_fast( WNDPROC func, HWND hwnd,
+ UINT msg, WPARAM wParam,
+ LPARAM lParam, LRESULT *result )
+{
+ switch(msg)
+ {
+ case WM_NCCREATE:
+ case WM_CREATE:
+ /* Win2k SP4 uses buffer[1030] for both caption and class name
+ * for W->A calls.
+ * For larger strings Windows does:
+ * VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE);
+ * We want to use HeapAlloc instead of VirtualAlloc, it's much faster.
+ */
+ { /* csW->lpszName and csW->lpszClass are NOT supposed to be atoms
+ * at this point.
+ */
+ char buffer[1024];
+ char *cls = buffer, *name;
+ CREATESTRUCTW *csW = (CREATESTRUCTW *)lParam;
+ CREATESTRUCTA csA = *(CREATESTRUCTA *)csW;
+ DWORD name_lenA, name_lenW, class_lenA, class_lenW;
+
+ class_lenW = strlenW(csW->lpszClass) * sizeof(WCHAR);
+ RtlUnicodeToMultiByteSize(&class_lenA, csW->lpszClass, class_lenW);
+
+ if (csW->lpszName)
+ {
+ name_lenW = strlenW(csW->lpszName) * sizeof(WCHAR);
+ RtlUnicodeToMultiByteSize(&name_lenA, csW->lpszName, name_lenW);
+ }
+ else
+ name_lenW = name_lenA = 0;
+
+ if (class_lenA + name_lenA + 2 > sizeof(buffer))
+ {
+ cls = HeapAlloc(GetProcessHeap(), 0, class_lenA + name_lenA + 2);
+ if (!cls) return FALSE;
+ }
+
+ RtlUnicodeToMultiByteN(cls, class_lenA, NULL, csW->lpszClass, class_lenW);
+ cls[class_lenA] = 0;
+ csA.lpszClass = cls;
+
+ if (csW->lpszName)
+ {
+ name = cls + class_lenA + 1;
+ RtlUnicodeToMultiByteN(name, name_lenA, NULL, csW->lpszName, name_lenW);
+ name[name_lenA] = 0;
+ csA.lpszName = name;
+ }
+
+ if (GetWindowLongW(hwnd, GWL_EXSTYLE) & WS_EX_MDICHILD)
+ {
+ MDICREATESTRUCTA mdi_cs;
+
+ mdi_cs = *(MDICREATESTRUCTA *)csW->lpCreateParams;
+ mdi_cs.szTitle = csA.lpszName;
+ mdi_cs.szClass = csA.lpszClass;
+ csA.lpCreateParams = &mdi_cs;
+ }
+
+ lParam = (LPARAM)&csA;
+ *result = WINPROC_CallWndProc(func, hwnd, msg, wParam, lParam);
+
+ if (cls != buffer) HeapFree(GetProcessHeap(), 0, cls);
+ }
+ return TRUE;
+
+ default:
+ return FALSE;
+ }
+}
+
+/**********************************************************************
* WINPROC_CallProc32WTo32A
*
* Call a window procedure, translating args from Unicode to Ansi.
@@ -2893,6 +2915,9 @@ static LRESULT WINPROC_CallProc32WTo32A(
TRACE_(msg)("func %p (hwnd=%p,msg=%s,wp=%08x,lp=%08lx)\n",
func, hwnd, SPY_GetMsgName(msg, hwnd), wParam, lParam);
+ if (WINPROC_CallProc32WTo32A_fast( func, hwnd, msg, wParam, lParam, &result ))
+ return result;
+
if ((unmap = WINPROC_MapMsg32WTo32A( hwnd, msg, &wParam, &lParam )) == -1) {
ERR_(msg)("Message translation failed. (msg=%s,wp=%08x,lp=%08lx)\n",
SPY_GetMsgName(msg, hwnd), wParam, lParam );
More information about the wine-patches
mailing list