mirror of
https://github.com/reactos/reactos.git
synced 2024-11-28 05:53:31 +08:00
[WIN32SS][LPK] Add BiDi support to menus and window captions (#738)
Added callback function that redirects calls to GreExtTextOutW that didn't went through lpk BiDi processing, calls that are from the kernel. Completely solves JIRA issue CORE-6910.
This commit is contained in:
parent
b277cbdf22
commit
e7d2bbe726
@ -78,10 +78,9 @@ LpkExtTextOut(
|
||||
if ((GetLayout(hdc) & LAYOUT_RTL) || (GetTextAlign(hdc) & TA_RTLREADING))
|
||||
fuOptions |= ETO_RTLREADING;
|
||||
|
||||
/* If text direction is RTL change flag to account neutral characters
|
||||
BUG: disables reordering of propsheet titles */
|
||||
/* if (fuOptions & ETO_RTLREADING)
|
||||
dwSICFlags = SIC_NEUTRAL; */
|
||||
/* If text direction is RTL change flag to account neutral characters */
|
||||
if (fuOptions & ETO_RTLREADING)
|
||||
dwSICFlags |= SIC_NEUTRAL;
|
||||
|
||||
/* Check if the string requires complex script processing and not a "glyph indices" array */
|
||||
if (ScriptIsComplex(lpString, uCount, dwSICFlags) == S_OK && !(fuOptions & ETO_GLYPH_INDEX))
|
||||
|
@ -17,7 +17,8 @@
|
||||
#define USER32_CALLBACK_DDEPOST (13)
|
||||
#define USER32_CALLBACK_DDEGET (14)
|
||||
#define USER32_CALLBACK_SETOBM (15)
|
||||
#define USER32_CALLBACK_MAXIMUM (15)
|
||||
#define USER32_CALLBACK_LPK (16)
|
||||
#define USER32_CALLBACK_MAXIMUM (16)
|
||||
|
||||
typedef struct _WINDOWPROC_CALLBACK_ARGUMENTS
|
||||
{
|
||||
@ -139,6 +140,18 @@ typedef struct _SETOBM_CALLBACK_ARGUMENTS
|
||||
struct tagOEMBITMAPINFO oembmi[93];
|
||||
} SETOBM_CALLBACK_ARGUMENTS, *PSETOBM_CALLBACK_ARGUMENTS;
|
||||
|
||||
typedef struct _LPK_CALLBACK_ARGUMENTS
|
||||
{
|
||||
LPWSTR lpString;
|
||||
HDC hdc;
|
||||
INT x;
|
||||
INT y;
|
||||
UINT flags;
|
||||
RECT rect;
|
||||
UINT count;
|
||||
BOOL bRect;
|
||||
} LPK_CALLBACK_ARGUMENTS, *PLPK_CALLBACK_ARGUMENTS;
|
||||
|
||||
NTSTATUS WINAPI
|
||||
User32CallCopyImageFromKernel(PVOID Arguments, ULONG ArgumentLength);
|
||||
NTSTATUS WINAPI
|
||||
@ -171,4 +184,6 @@ NTSTATUS WINAPI
|
||||
User32CallDDEGetFromKernel(PVOID Arguments, ULONG ArgumentLength);
|
||||
NTSTATUS WINAPI
|
||||
User32CallOBMFromKernel(PVOID Arguments, ULONG ArgumentLength);
|
||||
NTSTATUS WINAPI
|
||||
User32CallLPKFromKernel(PVOID Arguments, ULONG ArgumentLength);
|
||||
#endif /* __INCLUDE_USER32_CALLBACK_H */
|
||||
|
@ -9,6 +9,9 @@
|
||||
#include <win32k.h>
|
||||
DBG_DEFAULT_CHANNEL(UserPainting);
|
||||
|
||||
BOOL UserExtTextOutW(HDC hdc, INT x, INT y, UINT flags, PRECTL lprc,
|
||||
LPCWSTR lpString, UINT count);
|
||||
|
||||
/* PRIVATE FUNCTIONS **********************************************************/
|
||||
|
||||
/**
|
||||
@ -2145,15 +2148,13 @@ UserDrawCaptionText(
|
||||
|
||||
if (Ret)
|
||||
{ // Faster while in setup.
|
||||
GreExtTextOutW( hDc,
|
||||
UserExtTextOutW( hDc,
|
||||
lpRc->left,
|
||||
lpRc->top + (lpRc->bottom - lpRc->top - Size.cy) / 2, // DT_SINGLELINE && DT_VCENTER
|
||||
ETO_CLIPPED,
|
||||
(RECTL *)lpRc,
|
||||
Text->Buffer,
|
||||
Length,
|
||||
NULL,
|
||||
0 );
|
||||
Length);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -939,6 +939,120 @@ static void TEXT_DrawUnderscore (HDC hdc, int x, int y, const WCHAR *str, int of
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef _WIN32K_
|
||||
/***********************************************************************
|
||||
* UserExtTextOutW
|
||||
*
|
||||
* Callback to usermode to use ExtTextOut, which will apply complex
|
||||
* script processing if needed and then draw it
|
||||
*
|
||||
* Parameters
|
||||
* hdc [in] The handle of the DC for drawing
|
||||
* x [in] The x location of the string
|
||||
* y [in] The y location of the string
|
||||
* flags [in] ExtTextOut flags
|
||||
* lprc [in] Clipping rectangle (if not NULL)
|
||||
* lpString [in] String to be drawn
|
||||
* count [in] String length
|
||||
*/
|
||||
BOOL UserExtTextOutW(HDC hdc,
|
||||
INT x,
|
||||
INT y,
|
||||
UINT flags,
|
||||
PRECTL lprc,
|
||||
LPCWSTR lpString,
|
||||
UINT count)
|
||||
{
|
||||
PVOID ResultPointer;
|
||||
ULONG ResultLength;
|
||||
ULONG ArgumentLength;
|
||||
ULONG_PTR pStringBuffer;
|
||||
NTSTATUS Status;
|
||||
PLPK_CALLBACK_ARGUMENTS Argument;
|
||||
BOOL bResult;
|
||||
|
||||
ArgumentLength = sizeof(LPK_CALLBACK_ARGUMENTS);
|
||||
|
||||
pStringBuffer = ArgumentLength;
|
||||
ArgumentLength += sizeof(WCHAR) * (count + 2);
|
||||
|
||||
Argument = IntCbAllocateMemory(ArgumentLength);
|
||||
|
||||
if (!Argument)
|
||||
{
|
||||
goto fallback;
|
||||
}
|
||||
|
||||
/* Initialize struct members */
|
||||
Argument->hdc = hdc;
|
||||
Argument->x = x;
|
||||
Argument->y = y;
|
||||
Argument->flags = flags;
|
||||
Argument->count = count;
|
||||
|
||||
if (lprc)
|
||||
{
|
||||
Argument->rect = *lprc;
|
||||
Argument->bRect = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
RtlZeroMemory(&Argument->rect, sizeof(RECT));
|
||||
Argument->bRect = FALSE;
|
||||
}
|
||||
|
||||
/* Align lpString
|
||||
mimicks code from co_IntClientLoadLibrary */
|
||||
Argument->lpString = (LPWSTR)pStringBuffer;
|
||||
pStringBuffer += (ULONG_PTR)Argument;
|
||||
|
||||
Status = RtlStringCchCopyNW((LPWSTR)pStringBuffer, count + 1, lpString, count);
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
IntCbFreeMemory(Argument);
|
||||
goto fallback;
|
||||
}
|
||||
|
||||
UserLeaveCo();
|
||||
|
||||
Status = KeUserModeCallback(USER32_CALLBACK_LPK,
|
||||
Argument,
|
||||
ArgumentLength,
|
||||
&ResultPointer,
|
||||
&ResultLength);
|
||||
|
||||
UserEnterCo();
|
||||
|
||||
IntCbFreeMemory(Argument);
|
||||
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
_SEH2_TRY
|
||||
{
|
||||
ProbeForRead(ResultPointer, sizeof(BOOL), 1);
|
||||
bResult = *(LPBOOL)ResultPointer;
|
||||
}
|
||||
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
ERR("Failed to copy result from user mode!\n");
|
||||
Status = _SEH2_GetExceptionCode();
|
||||
}
|
||||
_SEH2_END;
|
||||
}
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
goto fallback;
|
||||
}
|
||||
|
||||
return bResult;
|
||||
|
||||
fallback:
|
||||
return GreExtTextOutW(hdc, x, y, flags, lprc, lpString, count, NULL, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
/***********************************************************************
|
||||
* DrawTextExW (USER32.@)
|
||||
*
|
||||
@ -1201,10 +1315,10 @@ INT WINAPI DrawTextExWorker( HDC hdc,
|
||||
else
|
||||
len_seg = len;
|
||||
#ifdef _WIN32K_
|
||||
if (!GreExtTextOutW( hdc, xseg, y,
|
||||
((flags & DT_NOCLIP) ? 0 : ETO_CLIPPED) |
|
||||
((flags & DT_RTLREADING) ? ETO_RTLREADING : 0),
|
||||
rect, str, len_seg, NULL, 0 ))
|
||||
if (!UserExtTextOutW( hdc, xseg, y,
|
||||
((flags & DT_NOCLIP) ? 0 : ETO_CLIPPED) |
|
||||
((flags & DT_RTLREADING) ? ETO_RTLREADING : 0),
|
||||
rect, str, len_seg))
|
||||
#else
|
||||
if (!ExtTextOutW( hdc, xseg, y,
|
||||
((flags & DT_NOCLIP) ? 0 : ETO_CLIPPED) |
|
||||
|
@ -205,6 +205,7 @@ PVOID apfnDispatch[USER32_CALLBACK_MAXIMUM + 1] =
|
||||
User32CallDDEPostFromKernel,
|
||||
User32CallDDEGetFromKernel,
|
||||
User32CallOBMFromKernel,
|
||||
User32CallLPKFromKernel,
|
||||
};
|
||||
|
||||
|
||||
@ -641,3 +642,24 @@ User32CallOBMFromKernel(PVOID Arguments, ULONG ArgumentLength)
|
||||
|
||||
return ZwCallbackReturn(Arguments, ArgumentLength, STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
NTSTATUS WINAPI User32CallLPKFromKernel(PVOID Arguments, ULONG ArgumentLength)
|
||||
{
|
||||
BOOL bResult;
|
||||
PLPK_CALLBACK_ARGUMENTS Argument;
|
||||
|
||||
Argument = (PLPK_CALLBACK_ARGUMENTS)Arguments;
|
||||
|
||||
Argument->lpString = (LPWSTR)((ULONG_PTR)Argument->lpString + (ULONG_PTR)Argument);
|
||||
|
||||
bResult = ExtTextOutW(Argument->hdc,
|
||||
Argument->x,
|
||||
Argument->y,
|
||||
Argument->flags,
|
||||
(Argument->bRect) ? &Argument->rect : NULL,
|
||||
Argument->lpString,
|
||||
Argument->count,
|
||||
NULL);
|
||||
|
||||
return ZwCallbackReturn(&bResult, sizeof(BOOL), STATUS_SUCCESS);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user