mirror of
https://github.com/reactos/reactos.git
synced 2025-08-06 05:53:05 +00: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
5 changed files with 164 additions and 13 deletions
|
@ -78,10 +78,9 @@ LpkExtTextOut(
|
||||||
if ((GetLayout(hdc) & LAYOUT_RTL) || (GetTextAlign(hdc) & TA_RTLREADING))
|
if ((GetLayout(hdc) & LAYOUT_RTL) || (GetTextAlign(hdc) & TA_RTLREADING))
|
||||||
fuOptions |= ETO_RTLREADING;
|
fuOptions |= ETO_RTLREADING;
|
||||||
|
|
||||||
/* If text direction is RTL change flag to account neutral characters
|
/* If text direction is RTL change flag to account neutral characters */
|
||||||
BUG: disables reordering of propsheet titles */
|
if (fuOptions & ETO_RTLREADING)
|
||||||
/* if (fuOptions & ETO_RTLREADING)
|
dwSICFlags |= SIC_NEUTRAL;
|
||||||
dwSICFlags = SIC_NEUTRAL; */
|
|
||||||
|
|
||||||
/* Check if the string requires complex script processing and not a "glyph indices" array */
|
/* 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))
|
if (ScriptIsComplex(lpString, uCount, dwSICFlags) == S_OK && !(fuOptions & ETO_GLYPH_INDEX))
|
||||||
|
|
|
@ -17,7 +17,8 @@
|
||||||
#define USER32_CALLBACK_DDEPOST (13)
|
#define USER32_CALLBACK_DDEPOST (13)
|
||||||
#define USER32_CALLBACK_DDEGET (14)
|
#define USER32_CALLBACK_DDEGET (14)
|
||||||
#define USER32_CALLBACK_SETOBM (15)
|
#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
|
typedef struct _WINDOWPROC_CALLBACK_ARGUMENTS
|
||||||
{
|
{
|
||||||
|
@ -139,6 +140,18 @@ typedef struct _SETOBM_CALLBACK_ARGUMENTS
|
||||||
struct tagOEMBITMAPINFO oembmi[93];
|
struct tagOEMBITMAPINFO oembmi[93];
|
||||||
} SETOBM_CALLBACK_ARGUMENTS, *PSETOBM_CALLBACK_ARGUMENTS;
|
} 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
|
NTSTATUS WINAPI
|
||||||
User32CallCopyImageFromKernel(PVOID Arguments, ULONG ArgumentLength);
|
User32CallCopyImageFromKernel(PVOID Arguments, ULONG ArgumentLength);
|
||||||
NTSTATUS WINAPI
|
NTSTATUS WINAPI
|
||||||
|
@ -171,4 +184,6 @@ NTSTATUS WINAPI
|
||||||
User32CallDDEGetFromKernel(PVOID Arguments, ULONG ArgumentLength);
|
User32CallDDEGetFromKernel(PVOID Arguments, ULONG ArgumentLength);
|
||||||
NTSTATUS WINAPI
|
NTSTATUS WINAPI
|
||||||
User32CallOBMFromKernel(PVOID Arguments, ULONG ArgumentLength);
|
User32CallOBMFromKernel(PVOID Arguments, ULONG ArgumentLength);
|
||||||
|
NTSTATUS WINAPI
|
||||||
|
User32CallLPKFromKernel(PVOID Arguments, ULONG ArgumentLength);
|
||||||
#endif /* __INCLUDE_USER32_CALLBACK_H */
|
#endif /* __INCLUDE_USER32_CALLBACK_H */
|
||||||
|
|
|
@ -9,6 +9,9 @@
|
||||||
#include <win32k.h>
|
#include <win32k.h>
|
||||||
DBG_DEFAULT_CHANNEL(UserPainting);
|
DBG_DEFAULT_CHANNEL(UserPainting);
|
||||||
|
|
||||||
|
BOOL UserExtTextOutW(HDC hdc, INT x, INT y, UINT flags, PRECTL lprc,
|
||||||
|
LPCWSTR lpString, UINT count);
|
||||||
|
|
||||||
/* PRIVATE FUNCTIONS **********************************************************/
|
/* PRIVATE FUNCTIONS **********************************************************/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2145,15 +2148,13 @@ UserDrawCaptionText(
|
||||||
|
|
||||||
if (Ret)
|
if (Ret)
|
||||||
{ // Faster while in setup.
|
{ // Faster while in setup.
|
||||||
GreExtTextOutW( hDc,
|
UserExtTextOutW( hDc,
|
||||||
lpRc->left,
|
lpRc->left,
|
||||||
lpRc->top + (lpRc->bottom - lpRc->top - Size.cy) / 2, // DT_SINGLELINE && DT_VCENTER
|
lpRc->top + (lpRc->bottom - lpRc->top - Size.cy) / 2, // DT_SINGLELINE && DT_VCENTER
|
||||||
ETO_CLIPPED,
|
ETO_CLIPPED,
|
||||||
(RECTL *)lpRc,
|
(RECTL *)lpRc,
|
||||||
Text->Buffer,
|
Text->Buffer,
|
||||||
Length,
|
Length);
|
||||||
NULL,
|
|
||||||
0 );
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -939,6 +939,120 @@ static void TEXT_DrawUnderscore (HDC hdc, int x, int y, const WCHAR *str, int of
|
||||||
#endif
|
#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.@)
|
* DrawTextExW (USER32.@)
|
||||||
*
|
*
|
||||||
|
@ -1201,10 +1315,10 @@ INT WINAPI DrawTextExWorker( HDC hdc,
|
||||||
else
|
else
|
||||||
len_seg = len;
|
len_seg = len;
|
||||||
#ifdef _WIN32K_
|
#ifdef _WIN32K_
|
||||||
if (!GreExtTextOutW( hdc, xseg, y,
|
if (!UserExtTextOutW( hdc, xseg, y,
|
||||||
((flags & DT_NOCLIP) ? 0 : ETO_CLIPPED) |
|
((flags & DT_NOCLIP) ? 0 : ETO_CLIPPED) |
|
||||||
((flags & DT_RTLREADING) ? ETO_RTLREADING : 0),
|
((flags & DT_RTLREADING) ? ETO_RTLREADING : 0),
|
||||||
rect, str, len_seg, NULL, 0 ))
|
rect, str, len_seg))
|
||||||
#else
|
#else
|
||||||
if (!ExtTextOutW( hdc, xseg, y,
|
if (!ExtTextOutW( hdc, xseg, y,
|
||||||
((flags & DT_NOCLIP) ? 0 : ETO_CLIPPED) |
|
((flags & DT_NOCLIP) ? 0 : ETO_CLIPPED) |
|
||||||
|
|
|
@ -205,6 +205,7 @@ PVOID apfnDispatch[USER32_CALLBACK_MAXIMUM + 1] =
|
||||||
User32CallDDEPostFromKernel,
|
User32CallDDEPostFromKernel,
|
||||||
User32CallDDEGetFromKernel,
|
User32CallDDEGetFromKernel,
|
||||||
User32CallOBMFromKernel,
|
User32CallOBMFromKernel,
|
||||||
|
User32CallLPKFromKernel,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -641,3 +642,24 @@ User32CallOBMFromKernel(PVOID Arguments, ULONG ArgumentLength)
|
||||||
|
|
||||||
return ZwCallbackReturn(Arguments, ArgumentLength, STATUS_SUCCESS);
|
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…
Add table
Add a link
Reference in a new issue