Wine-Devel
Threads by month
- ----- 2026 -----
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2002 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2001 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- 9 participants
- 84536 discussions
[PATCH 1/6] user32: Implement WCA_CLOAK in SetWindowCompositionAttribute.
by Gabriel Ivăncescu Nov. 6, 2020
by Gabriel Ivăncescu Nov. 6, 2020
Nov. 6, 2020
This implements the user32 and server-side of keeping track of cloaking,
without actually doing the cloaking, which is done by the driver. The
driver function SetWindowCompositionAttribute must return whether it
supports cloaking, and whether it's a manual cloaking done by the app,
or the shell cloaking a window.
Manually cloaked windows can be activated and set to foreground. They also
remain on the taskbar and can be activated from the taskbar too (and function
like uncloaked windows), but are otherwise visibly hidden. WindowFromPoint
doesn't work to retrieve them, though.
Signed-off-by: Gabriel Ivăncescu <gabrielopcode(a)gmail.com>
---
This patchset will attempt to implement both manual cloaking done by
applications, and shell cloaking using the WM (for virtual desktops/workspaces
for example).
It uses the undocumented user32 API SetWindowCompositionAttribute to do
so. Of course, the documented DwmSetWindowAttribute will just be a wrapper
around this one.
dlls/user32/driver.c | 9 +++
dlls/user32/message.c | 2 +
dlls/user32/user_private.h | 41 +++++++++++++
dlls/user32/win.c | 121 ++++++++++++++++++++++++++++++++++---
server/protocol.def | 13 ++++
server/window.c | 80 +++++++++++++++++++++---
6 files changed, 250 insertions(+), 16 deletions(-)
diff --git a/dlls/user32/driver.c b/dlls/user32/driver.c
index 7ac7714..6dad5dc 100644
--- a/dlls/user32/driver.c
+++ b/dlls/user32/driver.c
@@ -140,6 +140,7 @@ static const USER_DRIVER *load_driver(void)
GET_USER_FUNC(SetFocus);
GET_USER_FUNC(SetLayeredWindowAttributes);
GET_USER_FUNC(SetParent);
+ GET_USER_FUNC(SetWindowCompositionAttribute);
GET_USER_FUNC(SetWindowRgn);
GET_USER_FUNC(SetWindowIcon);
GET_USER_FUNC(SetWindowStyle);
@@ -421,6 +422,12 @@ static void CDECL nulldrv_SetParent( HWND hwnd, HWND parent, HWND old_parent )
{
}
+static DWORD CDECL nulldrv_SetWindowCompositionAttribute( HWND hwnd, DWORD attribute, void *data )
+{
+ SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
+ return ~0;
+}
+
static void CDECL nulldrv_SetWindowRgn( HWND hwnd, HRGN hrgn, BOOL redraw )
{
}
@@ -522,6 +529,7 @@ static USER_DRIVER null_driver =
nulldrv_SetFocus,
nulldrv_SetLayeredWindowAttributes,
nulldrv_SetParent,
+ nulldrv_SetWindowCompositionAttribute,
nulldrv_SetWindowRgn,
nulldrv_SetWindowIcon,
nulldrv_SetWindowStyle,
@@ -737,6 +745,7 @@ static USER_DRIVER lazy_load_driver =
nulldrv_SetFocus,
loaderdrv_SetLayeredWindowAttributes,
nulldrv_SetParent,
+ nulldrv_SetWindowCompositionAttribute,
loaderdrv_SetWindowRgn,
nulldrv_SetWindowIcon,
nulldrv_SetWindowStyle,
diff --git a/dlls/user32/message.c b/dlls/user32/message.c
index 4434f4b..67f89bb 100644
--- a/dlls/user32/message.c
+++ b/dlls/user32/message.c
@@ -1887,6 +1887,8 @@ static LRESULT handle_internal_message( HWND hwnd, UINT msg, WPARAM wparam, LPAR
case WM_WINE_UPDATEWINDOWSTATE:
update_window_state( hwnd );
return 0;
+ case WM_WINE_SETWINDOWCLOAKED:
+ return USER_Driver->pSetWindowCompositionAttribute( hwnd, WCA_CLOAK, &wparam );
default:
if (msg >= WM_WINE_FIRST_DRIVER_MSG && msg <= WM_WINE_LAST_DRIVER_MSG)
return USER_Driver->pWindowMessage( hwnd, msg, wparam, lparam );
diff --git a/dlls/user32/user_private.h b/dlls/user32/user_private.h
index 7761a1c..3baf39c 100644
--- a/dlls/user32/user_private.h
+++ b/dlls/user32/user_private.h
@@ -56,6 +56,7 @@ enum wine_internal_message
WM_WINE_MOUSE_LL_HOOK,
WM_WINE_CLIPCURSOR,
WM_WINE_UPDATEWINDOWSTATE,
+ WM_WINE_SETWINDOWCLOAKED,
WM_WINE_FIRST_DRIVER_MSG = 0x80001000, /* range of messages reserved for the USER driver */
WM_WINE_LAST_DRIVER_MSG = 0x80001fff
};
@@ -101,6 +102,7 @@ typedef struct tagUSER_DRIVER {
void (CDECL *pSetFocus)(HWND);
void (CDECL *pSetLayeredWindowAttributes)(HWND,COLORREF,BYTE,DWORD);
void (CDECL *pSetParent)(HWND,HWND,HWND);
+ DWORD (CDECL *pSetWindowCompositionAttribute)(HWND,DWORD,void*);
void (CDECL *pSetWindowRgn)(HWND,HRGN,BOOL);
void (CDECL *pSetWindowIcon)(HWND,UINT,HICON);
void (CDECL *pSetWindowStyle)(HWND,INT,STYLESTRUCT*);
@@ -366,6 +368,45 @@ typedef struct
#include "poppack.h"
+/* Undocumented structure for (Get|Set)WindowCompositionAttribute */
+struct WINCOMPATTRDATA
+{
+ DWORD attribute;
+ void *pData;
+ ULONG dataSize;
+};
+enum
+{
+ WCA_UNDEFINED = 0,
+ WCA_NCRENDERING_ENABLED = 1,
+ WCA_NCRENDERING_POLICY = 2,
+ WCA_TRANSITIONS_FORCEDISABLED = 3,
+ WCA_ALLOW_NCPAINT = 4,
+ WCA_CAPTION_BUTTON_BOUNDS = 5,
+ WCA_NONCLIENT_RTL_LAYOUT = 6,
+ WCA_FORCE_ICONIC_REPRESENTATION = 7,
+ WCA_EXTENDED_FRAME_BOUNDS = 8,
+ WCA_HAS_ICONIC_BITMAP = 9,
+ WCA_THEME_ATTRIBUTES = 10,
+ WCA_NCRENDERING_EXILED = 11,
+ WCA_NCADORNMENTINFO = 12,
+ WCA_EXCLUDED_FROM_LIVEPREVIEW = 13,
+ WCA_VIDEO_OVERLAY_ACTIVE = 14,
+ WCA_FORCE_ACTIVEWINDOW_APPEARANCE = 15,
+ WCA_DISALLOW_PEEK = 16,
+ WCA_CLOAK = 17,
+ WCA_CLOAKED = 18,
+ WCA_ACCENT_POLICY = 19,
+ WCA_FREEZE_REPRESENTATION = 20,
+ WCA_EVER_UNCLOAKED = 21,
+ WCA_VISUAL_OWNER = 22,
+ WCA_HOLOGRAPHIC = 23,
+ WCA_EXCLUDED_FROM_DDA = 24,
+ WCA_PASSIVEUPDATEMODE = 25,
+ WCA_USEDARKMODECOLORS = 26,
+ WCA_LAST
+};
+
extern int bitmap_info_size( const BITMAPINFO * info, WORD coloruse ) DECLSPEC_HIDDEN;
extern BOOL get_icon_size( HICON handle, SIZE *size ) DECLSPEC_HIDDEN;
diff --git a/dlls/user32/win.c b/dlls/user32/win.c
index 680defc..9840a76 100644
--- a/dlls/user32/win.c
+++ b/dlls/user32/win.c
@@ -27,6 +27,7 @@
#include "winbase.h"
#include "winnls.h"
#include "winver.h"
+#include "dwmapi.h"
#include "wine/server.h"
#include "wine/asm.h"
#include "win.h"
@@ -54,6 +55,8 @@ static CRITICAL_SECTION_DEBUG critsect_debug =
};
static CRITICAL_SECTION surfaces_section = { &critsect_debug, -1, 0, 0, 0, 0 };
+BOOL WINAPI SetWindowCompositionAttribute(HWND, const struct WINCOMPATTRDATA*);
+
/**********************************************************************/
/* helper for Get/SetWindowLong */
@@ -191,7 +194,7 @@ void *free_user_handle( HANDLE handle, enum user_obj_type type )
* Create a window handle with the server.
*/
static WND *create_window_handle( HWND parent, HWND owner, LPCWSTR name,
- HINSTANCE instance, BOOL unicode )
+ HINSTANCE instance, BOOL unicode, BOOL *needs_cloak )
{
WORD index;
WND *win;
@@ -219,6 +222,7 @@ static WND *create_window_handle( HWND parent, HWND owner, LPCWSTR name,
dpi = reply->dpi;
awareness = reply->awareness;
class = wine_server_get_ptr( reply->class_ptr );
+ *needs_cloak = reply->needs_cloak;
}
}
SERVER_END_REQ;
@@ -749,6 +753,7 @@ HWND WIN_GetFullHandle( HWND hwnd )
static HWND WIN_SetOwner( HWND hwnd, HWND owner )
{
WND *win = WIN_GetPtr( hwnd );
+ BOOL needs_cloak = FALSE;
HWND ret = 0;
if (!win || win == WND_DESKTOP) return 0;
@@ -765,10 +770,19 @@ static HWND WIN_SetOwner( HWND hwnd, HWND owner )
{
win->owner = wine_server_ptr_handle( reply->full_owner );
ret = wine_server_ptr_handle( reply->prev_owner );
+ needs_cloak = reply->needs_cloak;
}
}
SERVER_END_REQ;
WIN_ReleasePtr( win );
+ if (needs_cloak)
+ {
+ struct WINCOMPATTRDATA data;
+ data.attribute = WCA_CLOAK;
+ data.pData = &needs_cloak;
+ data.dataSize = sizeof(needs_cloak);
+ SetWindowCompositionAttribute( hwnd, &data );
+ }
return ret;
}
@@ -1349,6 +1363,7 @@ HWND WIN_CreateWindowEx( CREATESTRUCTW *cs, LPCWSTR className, HINSTANCE module,
MDICREATESTRUCTW mdi_cs;
CBT_CREATEWNDW cbtc;
CREATESTRUCTW cbcs;
+ BOOL needs_cloak;
className = CLASS_GetVersionedName(className, NULL, NULL, TRUE);
@@ -1476,13 +1491,13 @@ HWND WIN_CreateWindowEx( CREATESTRUCTW *cs, LPCWSTR className, HINSTANCE module,
/* Create the window structure */
- if (!(wndPtr = create_window_handle( parent, owner, className, module, unicode )))
+ if (!(wndPtr = create_window_handle( parent, owner, className, module, unicode, &needs_cloak )))
{
WNDCLASSW wc;
/* if it's a comctl32 class, GetClassInfo will load it, then we can retry */
if (GetLastError() != ERROR_INVALID_HANDLE ||
!GetClassInfoW( 0, className, &wc ) ||
- !(wndPtr = create_window_handle( parent, owner, className, module, unicode )))
+ !(wndPtr = create_window_handle( parent, owner, className, module, unicode, &needs_cloak )))
return 0;
}
hwnd = wndPtr->obj.handle;
@@ -1663,6 +1678,8 @@ HWND WIN_CreateWindowEx( CREATESTRUCTW *cs, LPCWSTR className, HINSTANCE module,
/* call the driver */
if (!USER_Driver->pCreateWindow( hwnd )) goto failed;
+ if (needs_cloak)
+ USER_Driver->pSetWindowCompositionAttribute( hwnd, WCA_CLOAK, &needs_cloak );
NotifyWinEvent(EVENT_OBJECT_CREATE, hwnd, OBJID_WINDOW, 0);
@@ -4233,9 +4250,99 @@ BOOL WINAPI SetWindowDisplayAffinity(HWND hwnd, DWORD affinity)
/**********************************************************************
* SetWindowCompositionAttribute (USER32.@)
*/
-BOOL WINAPI SetWindowCompositionAttribute(HWND hwnd, void *data)
+BOOL WINAPI SetWindowCompositionAttribute(HWND hwnd, const struct WINCOMPATTRDATA *data)
{
- FIXME("(%p, %p): stub\n", hwnd, data);
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
+ user_handle_t *list;
+ unsigned i, size;
+ NTSTATUS status;
+ HWND parent;
+ DWORD ret;
+ WND *win;
+
+ TRACE("(%p, %p)\n", hwnd, data);
+
+ if (!data || !data->pData)
+ {
+ SetLastError( ERROR_NOACCESS );
+ return FALSE;
+ }
+ if (!hwnd || is_broadcast(hwnd) || !(win = WIN_GetPtr(hwnd)))
+ {
+ SetLastError( ERROR_INVALID_HANDLE );
+ return FALSE;
+ }
+ if (win == WND_DESKTOP || win == WND_OTHER_PROCESS)
+ {
+ SetLastError( ERROR_ACCESS_DENIED );
+ return FALSE;
+ }
+ parent = win->parent;
+ WIN_ReleasePtr(win);
+ if (parent && parent != GetDesktopWindow())
+ {
+ SetLastError( ERROR_INVALID_HANDLE );
+ return FALSE;
+ }
+
+ switch (data->attribute)
+ {
+ case WCA_CLOAK:
+ if (data->dataSize < sizeof(BOOL))
+ {
+ SetLastError( ERROR_INSUFFICIENT_BUFFER );
+ return FALSE;
+ }
+
+ ret = USER_Driver->pSetWindowCompositionAttribute( hwnd, WCA_CLOAK, data->pData );
+ if (ret == ~0) return FALSE;
+
+ size = 128;
+ for (;;)
+ {
+ unsigned count = 0;
+
+ if (!(list = HeapAlloc( GetProcessHeap(), 0, size * sizeof(user_handle_t) )))
+ {
+ SetLastError( ERROR_OUTOFMEMORY );
+ return FALSE;
+ }
+ SERVER_START_REQ( set_window_cloaked )
+ {
+ req->handle = wine_server_user_handle( hwnd );
+ req->cloaked = ret;
+ wine_server_set_reply( req, list, size * sizeof(user_handle_t) );
+ if (!(status = wine_server_call( req ))) count = reply->count;
+ }
+ SERVER_END_REQ;
+ if (count < size)
+ {
+ /* Go through the list to cloak the windows that inherit it */
+ for (i = 0; i < count; i++)
+ {
+ HWND full_handle, handle = wine_server_ptr_handle( list[i] );
+
+ if ((full_handle = WIN_IsCurrentProcess( handle )))
+ USER_Driver->pSetWindowCompositionAttribute( full_handle, WCA_CLOAK, data->pData );
+ else
+ SendMessageW( handle, WM_WINE_SETWINDOWCLOAKED, *(BOOL*)(data->pData), 0 );
+ }
+ count = 0;
+ }
+ HeapFree( GetProcessHeap(), 0, list );
+ if (!count) break;
+ size = count; /* restart with a large enough buffer */
+ }
+ if (status)
+ {
+ SetLastError( RtlNtStatusToDosError( status ));
+ return FALSE;
+ }
+ return TRUE;
+
+ default:
+ FIXME("unimplemented attribute %d, size %u, for hwnd %p.\n", data->attribute, data->dataSize, hwnd);
+ SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
+ return FALSE;
+ }
+ return TRUE;
}
diff --git a/server/protocol.def b/server/protocol.def
index 846d2e1..d96d2e7 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -2226,6 +2226,7 @@ enum message_type
client_ptr_t class_ptr; /* pointer to class in client address space */
int dpi; /* window DPI if not per-monitor aware */
int awareness; /* window DPI awareness */
+ int needs_cloak; /* the window needs to be cloaked by the driver */
@END
@@ -2251,6 +2252,7 @@ enum message_type
@REPLY
user_handle_t full_owner; /* full handle of new owner */
user_handle_t prev_owner; /* full handle of previous owner */
+ int needs_cloak; /* the owned window needs to be cloaked */
@END
@@ -2299,6 +2301,17 @@ enum message_type
#define SET_WIN_UNICODE 0x40
+/* Set the window's cloaked attribute */
+(a)REQ(set_window_cloaked)
+ user_handle_t handle; /* handle to the window */
+ unsigned int cloaked; /* cloaked attribute to set (see below) */
+(a)REPLY
+ unsigned int count; /* total count of windows inheriting it */
+ VARARG(windows,user_handles); /* window handles that inherit it */
+(a)END
+#define SET_WINDOW_CLOAKED_ON 0x01
+
+
/* Set the parent of a window */
@REQ(set_parent)
user_handle_t handle; /* handle to the window */
diff --git a/server/window.c b/server/window.c
index 3a88b7f..e6fc90c 100644
--- a/server/window.c
+++ b/server/window.c
@@ -81,6 +81,7 @@ struct window
unsigned int is_unicode : 1; /* ANSI or unicode */
unsigned int is_linked : 1; /* is it linked into the parent z-order list? */
unsigned int is_layered : 1; /* has layered info been set? */
+ unsigned int is_cloaked : 1; /* is the window cloaked by the app? */
unsigned int color_key; /* color key for a layered window */
unsigned int alpha; /* alpha value for a layered window */
unsigned int layered_flags; /* flags for a layered window */
@@ -503,6 +504,7 @@ static struct window *create_window( struct window *parent, struct window *owner
win->is_unicode = 1;
win->is_linked = 0;
win->is_layered = 0;
+ win->is_cloaked = 0;
win->dpi_awareness = DPI_AWARENESS_PER_MONITOR_AWARE;
win->dpi = 0;
win->user_data = 0;
@@ -784,6 +786,7 @@ static int get_window_children_from_point( struct window *parent, int x, int y,
{
int x_child = x, y_child = y;
+ if (is_desktop_window( parent ) && ptr->is_cloaked) continue;
if (!is_point_in_window( ptr, &x_child, &y_child, parent->dpi )) continue; /* skip it */
/* if point is in client area, and window is not minimized or disabled, check children */
@@ -856,6 +859,21 @@ static int all_windows_from_point( struct window *top, int x, int y, unsigned in
return 1;
}
+/* fill an array with the handles of all the owned windows, recursively */
+static unsigned int get_owned_windows( struct window *win, user_handle_t *handles )
+{
+ struct window *ptr, *parent = win->parent;
+ unsigned int count = 0;
+
+ LIST_FOR_EACH_ENTRY( ptr, &parent->children, struct window, entry )
+ {
+ if (ptr->owner != win->handle) continue;
+ if (handles) handles[count] = ptr->handle;
+ count++;
+ count += get_owned_windows( ptr, handles ? handles + count : NULL );
+ }
+ return count;
+}
/* return the thread owning a window */
struct thread *get_window_thread( user_handle_t handle )
@@ -1965,14 +1983,16 @@ DECL_HANDLER(create_window)
win->dpi_awareness = req->awareness;
win->dpi = req->dpi;
}
+ win->is_cloaked = owner ? owner->is_cloaked : 0;
- reply->handle = win->handle;
- reply->parent = win->parent ? win->parent->handle : 0;
- reply->owner = win->owner;
- reply->extra = win->nb_extra_bytes;
- reply->dpi = win->dpi;
- reply->awareness = win->dpi_awareness;
- reply->class_ptr = get_class_client_ptr( win->class );
+ reply->handle = win->handle;
+ reply->parent = win->parent ? win->parent->handle : 0;
+ reply->owner = win->owner;
+ reply->extra = win->nb_extra_bytes;
+ reply->dpi = win->dpi;
+ reply->awareness = win->dpi_awareness;
+ reply->class_ptr = get_class_client_ptr( win->class );
+ reply->needs_cloak = win->is_cloaked;
}
@@ -2072,8 +2092,9 @@ DECL_HANDLER(set_window_owner)
}
}
- reply->prev_owner = win->owner;
- reply->full_owner = win->owner = owner ? owner->handle : 0;
+ reply->prev_owner = win->owner;
+ reply->full_owner = win->owner = owner ? owner->handle : 0;
+ reply->needs_cloak = owner ? owner->is_cloaked : 0;
}
@@ -2151,6 +2172,47 @@ DECL_HANDLER(set_window_info)
}
+/* set the window's cloaked attribute */
+DECL_HANDLER(set_window_cloaked)
+{
+ struct window *win = get_window( req->handle );
+ unsigned int i, total;
+ user_handle_t *data;
+
+ if (!win) return;
+ if (is_desktop_window( win ))
+ {
+ set_error( STATUS_ACCESS_DENIED );
+ return;
+ }
+ if (!is_desktop_window( win->parent ))
+ {
+ set_error( STATUS_INVALID_HANDLE );
+ return;
+ }
+
+ reply->count = total = get_owned_windows( win, NULL );
+ if (get_reply_max_size() < total * sizeof(user_handle_t))
+ return;
+
+ if (total)
+ {
+ if (!(data = set_reply_data_size( total * sizeof(user_handle_t) )))
+ {
+ set_error( STATUS_NO_MEMORY );
+ return;
+ }
+ get_owned_windows( win, data );
+ }
+
+ win->is_cloaked = req->cloaked;
+
+ for (i = 0; i < total; i++)
+ if ((win = get_window( data[i] )))
+ win->is_cloaked = req->cloaked;
+}
+
+
/* get a list of the window parents, up to the root of the tree */
DECL_HANDLER(get_window_parents)
{
--
2.21.0
2
11
[PATCH] include: Add DEFINE_ENUM_FLAG_OPERATORS macro for enumerations in d3d12.idl.
by Biswapriyo Nath Nov. 6, 2020
by Biswapriyo Nath Nov. 6, 2020
Nov. 6, 2020
2
1
This is required by several Call of Duty games that are calling this
directly after loading gdi32.dll from disk.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=48171
Signed-off-by: Rémi Bernon <rbernon(a)codeweavers.com>
---
Now that gdi32 is PE, this can be useful to get the remaining CoD games
to start. A bit late for the release, but maybe?
dlls/gdi32/gdi32.spec | 2 +-
dlls/gdi32/gdiobj.c | 9 +++++++++
2 files changed, 10 insertions(+), 1 deletion(-)
diff --git a/dlls/gdi32/gdi32.spec b/dlls/gdi32/gdi32.spec
index 725afebb8eb..dc63dbcbf32 100644
--- a/dlls/gdi32/gdi32.spec
+++ b/dlls/gdi32/gdi32.spec
@@ -182,7 +182,7 @@
@ stub GdiDeleteLocalObject
# @ stub GdiDeleteSpoolFileHandle
@ stdcall GdiDescribePixelFormat(long long long ptr)
-@ stub GdiDllInitialize
+@ stdcall GdiDllInitialize(ptr long ptr)
@ stdcall GdiDrawStream(long long ptr)
# @ stub GdiEndDocEMF
# @ stub GdiEndPageEMF
diff --git a/dlls/gdi32/gdiobj.c b/dlls/gdi32/gdiobj.c
index d717476027b..3a556c600ef 100644
--- a/dlls/gdi32/gdiobj.c
+++ b/dlls/gdi32/gdiobj.c
@@ -734,6 +734,15 @@ BOOL WINAPI DllMain( HINSTANCE inst, DWORD reason, LPVOID reserved )
return TRUE;
}
+
+/* Stub entry point, some games (CoD: Black Ops 3) call it directly. */
+BOOL WINAPI GdiDllInitialize( HINSTANCE inst, DWORD reason, LPVOID reserved )
+{
+ FIXME("stub\n");
+ return TRUE;
+}
+
+
static const char *gdi_obj_type( unsigned type )
{
switch ( type )
--
2.29.2
1
0
Nov. 6, 2020
Signed-off-by: Robert Wilhelm <robert.wilhelm(a)gmx.net>
---
v2: Jacek's patch which puts logic in one place.
---
dlls/vbscript/parser.y | 10 +++++-----
dlls/vbscript/tests/lang.vbs | 22 ++++++++++++++++++++++
2 files changed, 27 insertions(+), 5 deletions(-)
diff --git a/dlls/vbscript/parser.y b/dlls/vbscript/parser.y
index 942e76459c2..7c749b5ef77 100644
--- a/dlls/vbscript/parser.y
+++ b/dlls/vbscript/parser.y
@@ -490,11 +490,11 @@ ArgumentDecl
/* these keywords may also be an identifier, depending on context */
Identifier
: tIdentifier { $$ = $1; }
- | tDEFAULT { $$ = $1; }
- | tERROR { $$ = $1; }
- | tEXPLICIT { $$ = $1; }
- | tPROPERTY { $$ = $1; }
- | tSTEP { $$ = $1; }
+ | tDEFAULT { ctx->last_token = tIdentifier; $$ = $1; }
+ | tERROR { ctx->last_token = tIdentifier; $$ = $1; }
+ | tEXPLICIT { ctx->last_token = tIdentifier; $$ = $1; }
+ | tPROPERTY { ctx->last_token = tIdentifier; $$ = $1; }
+ | tSTEP { ctx->last_token = tIdentifier; $$ = $1; }
/* Most statements accept both new line and ':' as separators */
StSep
diff --git a/dlls/vbscript/tests/lang.vbs b/dlls/vbscript/tests/lang.vbs
index 65f8a458cd7..570bb7fbcb3 100644
--- a/dlls/vbscript/tests/lang.vbs
+++ b/dlls/vbscript/tests/lang.vbs
@@ -1631,9 +1631,31 @@ sub test_identifiers
Dim step
step = "xx"
Call ok(step = "xx", "step = " & step & " expected ""xx""")
+
+ Dim property
+ property = "xx"
+ Call ok(property = "xx", "property = " & property & " expected ""xx""")
end sub
call test_identifiers()
+Class class_test_identifiers_as_function_name
+ Sub Property ( par )
+ End Sub
+
+ Function Error( par )
+ End Function
+
+ Sub Default ()
+ End Sub
+
+ Function Explicit (par)
+ Explicit = par
+ End Function
+
+ Sub Step ( default )
+ End Sub
+End Class
+
sub test_dotIdentifiers
' test keywords that can also be an identifier after a dot
Call ok(testObj.rem = 10, "testObj.rem = " & testObj.rem & " expected 10")
--
2.26.2
2
1
Nov. 6, 2020
Signed-off-by: Nikolay Sivov <nsivov(a)codeweavers.com>
---
Main motivation is to break dependency on mfplat queues, EVR should not depend
on that, notifications work correctly on Windows without initializing MF platform.
This also helps DirectShow case.
dlls/evr/sample.c | 280 +++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 275 insertions(+), 5 deletions(-)
diff --git a/dlls/evr/sample.c b/dlls/evr/sample.c
index 39520cb6020..729f279fafe 100644
--- a/dlls/evr/sample.c
+++ b/dlls/evr/sample.c
@@ -103,6 +103,276 @@ static struct surface_buffer *impl_from_IMFGetService(IMFGetService *iface)
return CONTAINING_RECORD(iface, struct surface_buffer, IMFGetService_iface);
}
+struct tracked_async_result
+{
+ MFASYNCRESULT result;
+ LONG refcount;
+ IUnknown *object;
+ IUnknown *state;
+};
+
+static struct tracked_async_result *impl_from_IMFAsyncResult(IMFAsyncResult *iface)
+{
+ return CONTAINING_RECORD(iface, struct tracked_async_result, result.AsyncResult);
+}
+
+static HRESULT WINAPI tracked_async_result_QueryInterface(IMFAsyncResult *iface, REFIID riid, void **obj)
+{
+ TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), obj);
+
+ if (IsEqualIID(riid, &IID_IMFAsyncResult) ||
+ IsEqualIID(riid, &IID_IUnknown))
+ {
+ *obj = iface;
+ IMFAsyncResult_AddRef(iface);
+ return S_OK;
+ }
+
+ *obj = NULL;
+ WARN("Unsupported interface %s.\n", debugstr_guid(riid));
+ return E_NOINTERFACE;
+}
+
+static ULONG WINAPI tracked_async_result_AddRef(IMFAsyncResult *iface)
+{
+ struct tracked_async_result *result = impl_from_IMFAsyncResult(iface);
+ ULONG refcount = InterlockedIncrement(&result->refcount);
+
+ TRACE("%p, %u.\n", iface, refcount);
+
+ return refcount;
+}
+
+static ULONG WINAPI tracked_async_result_Release(IMFAsyncResult *iface)
+{
+ struct tracked_async_result *result = impl_from_IMFAsyncResult(iface);
+ ULONG refcount = InterlockedDecrement(&result->refcount);
+
+ TRACE("%p, %u.\n", iface, refcount);
+
+ if (!refcount)
+ {
+ if (result->result.pCallback)
+ IMFAsyncCallback_Release(result->result.pCallback);
+ if (result->object)
+ IUnknown_Release(result->object);
+ if (result->state)
+ IUnknown_Release(result->state);
+ heap_free(result);
+ }
+
+ return refcount;
+}
+
+static HRESULT WINAPI tracked_async_result_GetState(IMFAsyncResult *iface, IUnknown **state)
+{
+ struct tracked_async_result *result = impl_from_IMFAsyncResult(iface);
+
+ TRACE("%p, %p.\n", iface, state);
+
+ if (!result->state)
+ return E_POINTER;
+
+ *state = result->state;
+ IUnknown_AddRef(*state);
+
+ return S_OK;
+}
+
+static HRESULT WINAPI tracked_async_result_GetStatus(IMFAsyncResult *iface)
+{
+ struct tracked_async_result *result = impl_from_IMFAsyncResult(iface);
+
+ TRACE("%p.\n", iface);
+
+ return result->result.hrStatusResult;
+}
+
+static HRESULT WINAPI tracked_async_result_SetStatus(IMFAsyncResult *iface, HRESULT status)
+{
+ struct tracked_async_result *result = impl_from_IMFAsyncResult(iface);
+
+ TRACE("%p, %#x.\n", iface, status);
+
+ result->result.hrStatusResult = status;
+
+ return S_OK;
+}
+
+static HRESULT WINAPI tracked_async_result_GetObject(IMFAsyncResult *iface, IUnknown **object)
+{
+ struct tracked_async_result *result = impl_from_IMFAsyncResult(iface);
+
+ TRACE("%p, %p.\n", iface, object);
+
+ if (!result->object)
+ return E_POINTER;
+
+ *object = result->object;
+ IUnknown_AddRef(*object);
+
+ return S_OK;
+}
+
+static IUnknown * WINAPI tracked_async_result_GetStateNoAddRef(IMFAsyncResult *iface)
+{
+ struct tracked_async_result *result = impl_from_IMFAsyncResult(iface);
+
+ TRACE("%p.\n", iface);
+
+ return result->state;
+}
+
+static const IMFAsyncResultVtbl tracked_async_result_vtbl =
+{
+ tracked_async_result_QueryInterface,
+ tracked_async_result_AddRef,
+ tracked_async_result_Release,
+ tracked_async_result_GetState,
+ tracked_async_result_GetStatus,
+ tracked_async_result_SetStatus,
+ tracked_async_result_GetObject,
+ tracked_async_result_GetStateNoAddRef,
+};
+
+static HRESULT create_async_result(IUnknown *object, IMFAsyncCallback *callback,
+ IUnknown *state, IMFAsyncResult **out)
+{
+ struct tracked_async_result *result;
+
+ result = heap_alloc_zero(sizeof(*result));
+ if (!result)
+ return E_OUTOFMEMORY;
+
+ result->result.AsyncResult.lpVtbl = &tracked_async_result_vtbl;
+ result->refcount = 1;
+ result->object = object;
+ if (result->object)
+ IUnknown_AddRef(result->object);
+ result->result.pCallback = callback;
+ if (result->result.pCallback)
+ IMFAsyncCallback_AddRef(result->result.pCallback);
+ result->state = state;
+ if (result->state)
+ IUnknown_AddRef(result->state);
+
+ *out = &result->result.AsyncResult;
+
+ return S_OK;
+}
+
+struct tracking_thread
+{
+ HANDLE hthread;
+ DWORD tid;
+ LONG refcount;
+};
+static struct tracking_thread tracking_thread;
+
+static CRITICAL_SECTION tracking_thread_cs = { NULL, -1, 0, 0, 0, 0 };
+
+enum tracking_thread_message
+{
+ TRACKM_STOP = WM_USER,
+ TRACKM_INVOKE = WM_USER + 1,
+};
+
+static DWORD CALLBACK tracking_thread_proc(void *arg)
+{
+ HANDLE ready_event = arg;
+ BOOL stop_thread = FALSE;
+ IMFAsyncResult *result;
+ MFASYNCRESULT *data;
+ MSG msg;
+
+ PeekMessageW(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE);
+
+ SetEvent(ready_event);
+
+ while (!stop_thread)
+ {
+ MsgWaitForMultipleObjects(0, NULL, FALSE, INFINITE, QS_POSTMESSAGE);
+
+ while (PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE))
+ {
+ switch (msg.message)
+ {
+ case TRACKM_INVOKE:
+ result = (IMFAsyncResult *)msg.lParam;
+ data = (MFASYNCRESULT *)result;
+ if (data->pCallback)
+ IMFAsyncCallback_Invoke(data->pCallback, result);
+ IMFAsyncResult_Release(result);
+ break;
+
+ case TRACKM_STOP:
+ stop_thread = TRUE;
+ break;
+
+ default:
+ ;
+ }
+ }
+ }
+
+ TRACE("Tracking thread exiting.\n");
+
+ return 0;
+}
+
+static void video_sample_create_tracking_thread(void)
+{
+ EnterCriticalSection(&tracking_thread_cs);
+
+ if (++tracking_thread.refcount == 1)
+ {
+ HANDLE ready_event;
+
+ ready_event = CreateEventW(NULL, FALSE, FALSE, NULL);
+
+ if (!(tracking_thread.hthread = CreateThread(NULL, 0, tracking_thread_proc,
+ ready_event, 0, &tracking_thread.tid)))
+ {
+ WARN("Failed to create sample tracking thread.\n");
+ CloseHandle(ready_event);
+ return;
+ }
+
+ WaitForSingleObject(ready_event, INFINITE);
+ CloseHandle(ready_event);
+
+ TRACE("Create tracking thread %#x.\n", tracking_thread.tid);
+ }
+
+ LeaveCriticalSection(&tracking_thread_cs);
+}
+
+static void video_sample_stop_tracking_thread(void)
+{
+ EnterCriticalSection(&tracking_thread_cs);
+
+ if (!--tracking_thread.refcount)
+ {
+ PostThreadMessageW(tracking_thread.tid, TRACKM_STOP, 0, 0);
+ CloseHandle(tracking_thread.hthread);
+ memset(&tracking_thread, 0, sizeof(tracking_thread));
+ }
+
+ LeaveCriticalSection(&tracking_thread_cs);
+}
+
+static void video_sample_tracking_thread_invoke(IMFAsyncResult *result)
+{
+ if (!tracking_thread.tid)
+ {
+ WARN("Sample tracking thread is not initialized.\n");
+ return;
+ }
+
+ IMFAsyncResult_AddRef(result);
+ PostThreadMessageW(tracking_thread.tid, TRACKM_INVOKE, 0, (LPARAM)result);
+}
+
struct sample_allocator
{
IMFVideoSampleAllocator IMFVideoSampleAllocator_iface;
@@ -628,14 +898,11 @@ static ULONG WINAPI video_sample_Release(IMFSample *iface)
{
struct video_sample *sample = impl_from_IMFSample(iface);
ULONG refcount;
- HRESULT hr;
IMFSample_LockStore(sample->sample);
if (sample->tracked_result && sample->tracked_refcount == (sample->refcount - 1))
{
- /* Call could fail if queue system is not initialized, it's not critical. */
- if (FAILED(hr = MFInvokeCallback(sample->tracked_result)))
- WARN("Failed to invoke tracking callback, hr %#x.\n", hr);
+ video_sample_tracking_thread_invoke(sample->tracked_result);
IMFAsyncResult_Release(sample->tracked_result);
sample->tracked_result = NULL;
sample->tracked_refcount = 0;
@@ -648,6 +915,7 @@ static ULONG WINAPI video_sample_Release(IMFSample *iface)
if (!refcount)
{
+ video_sample_stop_tracking_thread();
if (sample->sample)
IMFSample_Release(sample->sample);
heap_free(sample);
@@ -1132,7 +1400,7 @@ static HRESULT WINAPI tracked_video_sample_SetAllocator(IMFTrackedSample *iface,
hr = MF_E_NOTACCEPTING;
else
{
- if (SUCCEEDED(hr = MFCreateAsyncResult((IUnknown *)iface, sample_allocator, state, &sample->tracked_result)))
+ if (SUCCEEDED(hr = create_async_result((IUnknown *)iface, sample_allocator, state, &sample->tracked_result)))
{
/* Account for additional refcount brought by 'state' object. This threshold is used
on Release() to invoke tracker callback. */
@@ -1428,6 +1696,8 @@ HRESULT WINAPI MFCreateVideoSampleFromSurface(IUnknown *surface, IMFSample **sam
if (buffer)
IMFSample_AddBuffer(object->sample, buffer);
+ video_sample_create_tracking_thread();
+
*sample = &object->IMFSample_iface;
return S_OK;
--
2.28.0
1
0
Signed-off-by: Vijay Kiran Kamuju <infyquest(a)gmail.com>
1
0
Signed-off-by: Vijay Kiran Kamuju <infyquest(a)gmail.com>
1
0
Nov. 6, 2020
Signed-off-by: Paul Gofman <pgofman(a)codeweavers.com>
---
dlls/ntdll/loader.c | 353 +++++++++++++++++++++++++++++++++++---------
1 file changed, 286 insertions(+), 67 deletions(-)
diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c
index 368448c9f8d..e6895d66bd4 100644
--- a/dlls/ntdll/loader.c
+++ b/dlls/ntdll/loader.c
@@ -132,6 +132,7 @@ typedef struct _wine_modref
int alloc_deps;
int nDeps;
struct _wine_modref **deps;
+ RTL_CRITICAL_SECTION module_section;
} WINE_MODREF;
static UINT tls_module_count; /* number of modules with TLS directory */
@@ -147,6 +148,30 @@ static RTL_CRITICAL_SECTION_DEBUG critsect_debug =
};
static RTL_CRITICAL_SECTION loader_section = { &critsect_debug, -1, 0, 0, 0, 0 };
+/* ldr_data_section allows for read only access to module linked lists in PEB and
+ * the underlying structures without taking loader lock. The relations between
+ * ldr_data_section, loader_section and module_section from WINE_MODREF are:
+ * - modification to the module linked lists is done with both ldr_data_ and loader_
+ * sections locked;
+ * - read only access to loader linked lists is allowed with either loader_ or ldr_data_
+ * section locked;
+ * - the WINE_MODREF pointer (and the underlying module mapping) should stay valid
+ * while any of three locks is held; if loader_ or ldr_data_ section is held module_section
+ * can be unlocked and locked again without the risk of loosing the module reference;
+ * - query or modification if WINE_MODREF must be done with module_section locked, except for
+ * reading the fields initialized on module reference creation which don't change after
+ * (those can be accessed whenever module reference is valid);
+ * - the order of locking is: loader_section, ldr_data_section, module_section;
+ * - thread should not have any module_section locked when requesting loader_ or ldr_data_ lock. */
+static CRITICAL_SECTION ldr_data_section;
+static CRITICAL_SECTION_DEBUG ldr_data_section_debug =
+{
+ 0, 0, &ldr_data_section,
+ { &ldr_data_section_debug.ProcessLocksList, &ldr_data_section_debug.ProcessLocksList },
+ 0, 0, { (DWORD_PTR)(__FILE__ ": ldr_data_section") }
+};
+static CRITICAL_SECTION ldr_data_section = { &ldr_data_section_debug, -1, 0, 0, 0, 0 };
+
static CRITICAL_SECTION dlldir_section;
static CRITICAL_SECTION_DEBUG dlldir_critsect_debug =
{
@@ -176,11 +201,23 @@ static WINE_MODREF *last_failed_modref;
static NTSTATUS load_dll( const WCHAR *load_path, const WCHAR *libname, const WCHAR *default_ext,
DWORD flags, WINE_MODREF** pwm );
static NTSTATUS process_attach( WINE_MODREF *wm, LPVOID lpReserved );
-static FARPROC find_ordinal_export( HMODULE module, const IMAGE_EXPORT_DIRECTORY *exports,
+static FARPROC find_ordinal_export( WINE_MODREF **wm, const IMAGE_EXPORT_DIRECTORY *exports,
DWORD exp_size, DWORD ordinal, LPCWSTR load_path );
-static FARPROC find_named_export( HMODULE module, const IMAGE_EXPORT_DIRECTORY *exports,
+static FARPROC find_named_export( WINE_MODREF **wm, const IMAGE_EXPORT_DIRECTORY *exports,
DWORD exp_size, const char *name, int hint, LPCWSTR load_path );
+static void lock_ldr_data( BOOL lock_always )
+{
+ if (lock_always || !RtlIsCriticalSectionLockedByThread( &loader_section ))
+ RtlEnterCriticalSection( &ldr_data_section );
+}
+
+static void unlock_ldr_data( BOOL unlock_always )
+{
+ if (unlock_always || !RtlIsCriticalSectionLockedByThread( &loader_section ))
+ RtlLeaveCriticalSection( &ldr_data_section );
+}
+
/* convert PE image VirtualAddress to Real Address */
static inline void *get_rva( HMODULE module, DWORD va )
{
@@ -462,27 +499,65 @@ static void call_ldr_notifications( ULONG reason, LDR_DATA_TABLE_ENTRY *module )
}
}
+
+/*************************************************************************
+ * lock_modref
+ *
+ * Locks module reference.
+ */
+static void lock_modref( WINE_MODREF *modref )
+{
+ RtlEnterCriticalSection( &modref->module_section );
+}
+
+
+/*************************************************************************
+ * unlock_modref
+ *
+ * Unlocks module reference.
+ */
+static void unlock_modref( WINE_MODREF *modref )
+{
+ assert(modref && RtlIsCriticalSectionLockedByThread( &modref->module_section ));
+ RtlLeaveCriticalSection( &modref->module_section );
+}
+
+
/*************************************************************************
* get_modref
*
* Looks for the referenced HMODULE in the current process
- * The loader_section must be locked while calling this function.
*/
static WINE_MODREF *get_modref( HMODULE hmod )
{
PLIST_ENTRY mark, entry;
PLDR_DATA_TABLE_ENTRY mod;
+ WINE_MODREF *ret = NULL;
+
+ lock_ldr_data( FALSE );
- if (cached_modref && cached_modref->ldr.DllBase == hmod) return cached_modref;
+ if (cached_modref && cached_modref->ldr.DllBase == hmod)
+ {
+ ret = cached_modref;
+ goto done;
+ }
mark = &NtCurrentTeb()->Peb->LdrData->InMemoryOrderModuleList;
for (entry = mark->Flink; entry != mark; entry = entry->Flink)
{
mod = CONTAINING_RECORD(entry, LDR_DATA_TABLE_ENTRY, InMemoryOrderLinks);
if (mod->DllBase == hmod)
- return cached_modref = CONTAINING_RECORD(mod, WINE_MODREF, ldr);
+ {
+ ret = cached_modref = CONTAINING_RECORD(mod, WINE_MODREF, ldr);
+ break;
+ }
}
- return NULL;
+
+done:
+ if (ret)
+ lock_modref(ret);
+ unlock_ldr_data( FALSE );
+ return ret;
}
@@ -490,17 +565,22 @@ static WINE_MODREF *get_modref( HMODULE hmod )
* find_basename_module
*
* Find a module from its base name.
- * The loader_section must be locked while calling this function
*/
static WINE_MODREF *find_basename_module( LPCWSTR name )
{
PLIST_ENTRY mark, entry;
UNICODE_STRING name_str;
+ WINE_MODREF *ret = NULL;
RtlInitUnicodeString( &name_str, name );
+ lock_ldr_data( FALSE );
+
if (cached_modref && RtlEqualUnicodeString( &name_str, &cached_modref->ldr.BaseDllName, TRUE ))
- return cached_modref;
+ {
+ ret = cached_modref;
+ goto done;
+ }
mark = &NtCurrentTeb()->Peb->LdrData->InLoadOrderModuleList;
for (entry = mark->Flink; entry != mark; entry = entry->Flink)
@@ -508,11 +588,16 @@ static WINE_MODREF *find_basename_module( LPCWSTR name )
LDR_DATA_TABLE_ENTRY *mod = CONTAINING_RECORD(entry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
if (RtlEqualUnicodeString( &name_str, &mod->BaseDllName, TRUE ))
{
- cached_modref = CONTAINING_RECORD(mod, WINE_MODREF, ldr);
- return cached_modref;
+ ret = cached_modref = CONTAINING_RECORD(mod, WINE_MODREF, ldr);
+ break;
}
}
- return NULL;
+
+done:
+ if (ret)
+ lock_modref(ret);
+ unlock_ldr_data( FALSE );
+ return ret;
}
@@ -520,31 +605,39 @@ static WINE_MODREF *find_basename_module( LPCWSTR name )
* find_fullname_module
*
* Find a module from its full path name.
- * The loader_section must be locked while calling this function
*/
static WINE_MODREF *find_fullname_module( const UNICODE_STRING *nt_name )
{
PLIST_ENTRY mark, entry;
UNICODE_STRING name = *nt_name;
+ WINE_MODREF *ret = NULL;
if (name.Length <= 4 * sizeof(WCHAR)) return NULL;
name.Length -= 4 * sizeof(WCHAR); /* for \??\ prefix */
name.Buffer += 4;
- if (cached_modref && RtlEqualUnicodeString( &name, &cached_modref->ldr.FullDllName, TRUE ))
- return cached_modref;
+ lock_ldr_data( FALSE );
+ if (cached_modref && RtlEqualUnicodeString( &name, &cached_modref->ldr.FullDllName, TRUE ))
+ {
+ ret = cached_modref;
+ goto done;
+ }
mark = &NtCurrentTeb()->Peb->LdrData->InLoadOrderModuleList;
for (entry = mark->Flink; entry != mark; entry = entry->Flink)
{
LDR_DATA_TABLE_ENTRY *mod = CONTAINING_RECORD(entry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
if (RtlEqualUnicodeString( &name, &mod->FullDllName, TRUE ))
{
- cached_modref = CONTAINING_RECORD(mod, WINE_MODREF, ldr);
- return cached_modref;
+ ret = cached_modref = CONTAINING_RECORD(mod, WINE_MODREF, ldr);
+ break;
}
}
- return NULL;
+done:
+ if (ret)
+ lock_modref(ret);
+ unlock_ldr_data( FALSE );
+ return ret;
}
@@ -552,13 +645,19 @@ static WINE_MODREF *find_fullname_module( const UNICODE_STRING *nt_name )
* find_fileid_module
*
* Find a module from its file id.
- * The loader_section must be locked while calling this function
*/
static WINE_MODREF *find_fileid_module( const struct file_id *id )
{
LIST_ENTRY *mark, *entry;
+ WINE_MODREF *ret = NULL;
+
+ lock_ldr_data( FALSE );
- if (cached_modref && !memcmp( &cached_modref->id, id, sizeof(*id) )) return cached_modref;
+ if (cached_modref && !memcmp( &cached_modref->id, id, sizeof(*id) ))
+ {
+ ret = cached_modref;
+ goto done;
+ }
mark = &NtCurrentTeb()->Peb->LdrData->InLoadOrderModuleList;
for (entry = mark->Flink; entry != mark; entry = entry->Flink)
@@ -568,11 +667,15 @@ static WINE_MODREF *find_fileid_module( const struct file_id *id )
if (!memcmp( &wm->id, id, sizeof(*id) ))
{
- cached_modref = wm;
- return wm;
+ ret = cached_modref = wm;
+ break;
}
}
- return NULL;
+done:
+ if (ret)
+ lock_modref(ret);
+ unlock_ldr_data( FALSE );
+ return ret;
}
@@ -603,14 +706,16 @@ static WINE_MODREF **grow_module_deps( WINE_MODREF *wm, int count )
* Find the final function pointer for a forwarded function.
* The loader_section must be locked while calling this function.
*/
-static FARPROC find_forwarded_export( HMODULE module, const char *forward, LPCWSTR load_path )
+static FARPROC find_forwarded_export( WINE_MODREF **wm_imp, const char *forward, LPCWSTR load_path )
{
+ HMODULE module = (*wm_imp)->ldr.DllBase;
const IMAGE_EXPORT_DIRECTORY *exports;
DWORD exp_size;
WINE_MODREF *wm;
WCHAR mod_name[32];
const char *end = strrchr(forward, '.');
FARPROC proc = NULL;
+ char *name;
if (!end) return NULL;
if ((end - forward) * sizeof(WCHAR) >= sizeof(mod_name)) return NULL;
@@ -622,9 +727,19 @@ static FARPROC find_forwarded_export( HMODULE module, const char *forward, LPCWS
memcpy( mod_name + (end - forward), dllW, sizeof(dllW) );
}
+ if (!(name = RtlAllocateHeap( GetProcessHeap(), 0, strlen( end + 1 ) + 1 )))
+ {
+ ERR("no memory.\n");
+ return NULL;
+ }
+ strcpy( name, end + 1 );
+
+ TRACE( "loading %s for '%s' used by '%s'\n", debugstr_w(mod_name), forward,
+ debugstr_w((*wm_imp)->ldr.FullDllName.Buffer) );
+ unlock_modref( *wm_imp );
if (!(wm = find_basename_module( mod_name )))
{
- TRACE( "delay loading %s for '%s'\n", debugstr_w(mod_name), forward );
+ TRACE( "delay loading %s.\n", debugstr_w(mod_name) );
if (load_dll( load_path, mod_name, dllW, 0, &wm ) == STATUS_SUCCESS &&
!(wm->ldr.Flags & LDR_DONT_RESOLVE_REFS))
{
@@ -635,35 +750,36 @@ static FARPROC find_forwarded_export( HMODULE module, const char *forward, LPCWS
}
else if (process_attach( wm, NULL ) != STATUS_SUCCESS)
{
+ unlock_modref( wm );
LdrUnloadDll( wm->ldr.DllBase );
wm = NULL;
}
}
-
if (!wm)
{
- ERR( "module not found for forward '%s' used by %s\n",
- forward, debugstr_w(get_modref(module)->ldr.FullDllName.Buffer) );
- return NULL;
+ ERR( "module not found, mod_name %s, path %s.\n", debugstr_w(mod_name), debugstr_w(load_path) );
+ goto done;
}
}
if ((exports = RtlImageDirectoryEntryToData( wm->ldr.DllBase, TRUE,
IMAGE_DIRECTORY_ENTRY_EXPORT, &exp_size )))
{
- const char *name = end + 1;
if (*name == '#') /* ordinal */
- proc = find_ordinal_export( wm->ldr.DllBase, exports, exp_size, atoi(name+1), load_path );
+ proc = find_ordinal_export( &wm, exports, exp_size, atoi(name+1), load_path );
else
- proc = find_named_export( wm->ldr.DllBase, exports, exp_size, name, -1, load_path );
+ proc = find_named_export( &wm, exports, exp_size, name, -1, load_path );
}
+ if (wm)
+ unlock_modref(wm);
+
if (!proc)
{
- ERR("function not found for forward '%s' used by %s."
- " If you are using builtin %s, try using the native one instead.\n",
- forward, debugstr_w(get_modref(module)->ldr.FullDllName.Buffer),
- debugstr_w(get_modref(module)->ldr.BaseDllName.Buffer) );
+ ERR( "function not found for forward '%s'.", forward );
}
+done:
+ RtlFreeHeap( GetProcessHeap(), 0, name );
+ *wm_imp = get_modref( module );
return proc;
}
@@ -673,11 +789,11 @@ static FARPROC find_forwarded_export( HMODULE module, const char *forward, LPCWS
*
* Find an exported function by ordinal.
* The exports base must have been subtracted from the ordinal already.
- * The loader_section must be locked while calling this function.
*/
-static FARPROC find_ordinal_export( HMODULE module, const IMAGE_EXPORT_DIRECTORY *exports,
+static FARPROC find_ordinal_export( WINE_MODREF **wm, const IMAGE_EXPORT_DIRECTORY *exports,
DWORD exp_size, DWORD ordinal, LPCWSTR load_path )
{
+ HMODULE module = (*wm)->ldr.DllBase;
FARPROC proc;
const DWORD *functions = get_rva( module, exports->AddressOfFunctions );
@@ -693,16 +809,18 @@ static FARPROC find_ordinal_export( HMODULE module, const IMAGE_EXPORT_DIRECTORY
/* if the address falls into the export dir, it's a forward */
if (((const char *)proc >= (const char *)exports) &&
((const char *)proc < (const char *)exports + exp_size))
- return find_forwarded_export( module, (const char *)proc, load_path );
+ return find_forwarded_export( wm, (const char *)proc, load_path );
if (TRACE_ON(snoop))
{
- const WCHAR *user = current_modref ? current_modref->ldr.BaseDllName.Buffer : NULL;
+ const WCHAR *user = RtlIsCriticalSectionLockedByThread( &loader_section ) && current_modref
+ ? current_modref->ldr.BaseDllName.Buffer : NULL;
proc = SNOOP_GetProcAddress( module, exports, exp_size, proc, ordinal, user );
}
if (TRACE_ON(relay))
{
- const WCHAR *user = current_modref ? current_modref->ldr.BaseDllName.Buffer : NULL;
+ const WCHAR *user = RtlIsCriticalSectionLockedByThread( &loader_section ) && current_modref
+ ? current_modref->ldr.BaseDllName.Buffer : NULL;
proc = RELAY_GetProcAddress( module, exports, exp_size, proc, ordinal, user );
}
return proc;
@@ -713,11 +831,11 @@ static FARPROC find_ordinal_export( HMODULE module, const IMAGE_EXPORT_DIRECTORY
* find_named_export
*
* Find an exported function by name.
- * The loader_section must be locked while calling this function.
*/
-static FARPROC find_named_export( HMODULE module, const IMAGE_EXPORT_DIRECTORY *exports,
+static FARPROC find_named_export( WINE_MODREF **wm, const IMAGE_EXPORT_DIRECTORY *exports,
DWORD exp_size, const char *name, int hint, LPCWSTR load_path )
{
+ HMODULE module = (*wm)->ldr.DllBase;
const WORD *ordinals = get_rva( module, exports->AddressOfNameOrdinals );
const DWORD *names = get_rva( module, exports->AddressOfNames );
int min = 0, max = exports->NumberOfNames - 1;
@@ -727,7 +845,7 @@ static FARPROC find_named_export( HMODULE module, const IMAGE_EXPORT_DIRECTORY *
{
char *ename = get_rva( module, names[hint] );
if (!strcmp( ename, name ))
- return find_ordinal_export( module, exports, exp_size, ordinals[hint], load_path );
+ return find_ordinal_export( wm, exports, exp_size, ordinals[hint], load_path );
}
/* then do a binary search */
@@ -736,7 +854,7 @@ static FARPROC find_named_export( HMODULE module, const IMAGE_EXPORT_DIRECTORY *
int res, pos = (min + max) / 2;
char *ename = get_rva( module, names[pos] );
if (!(res = strcmp( ename, name )))
- return find_ordinal_export( module, exports, exp_size, ordinals[pos], load_path );
+ return find_ordinal_export( wm, exports, exp_size, ordinals[pos], load_path );
if (res > 0) max = pos - 1;
else min = pos + 1;
}
@@ -751,8 +869,9 @@ static FARPROC find_named_export( HMODULE module, const IMAGE_EXPORT_DIRECTORY *
* Import the dll specified by the given import descriptor.
* The loader_section must be locked while calling this function.
*/
-static BOOL import_dll( HMODULE module, const IMAGE_IMPORT_DESCRIPTOR *descr, LPCWSTR load_path, WINE_MODREF **pwm )
+static BOOL import_dll( WINE_MODREF *wm, const IMAGE_IMPORT_DESCRIPTOR *descr, LPCWSTR load_path, WINE_MODREF **pwm )
{
+ HMODULE module = wm->ldr.DllBase;
NTSTATUS status;
WINE_MODREF *wmImp;
HMODULE imp_mod;
@@ -780,6 +899,8 @@ static BOOL import_dll( HMODULE module, const IMAGE_IMPORT_DESCRIPTOR *descr, LP
return TRUE;
}
+ unlock_modref( wm );
+
while (len && name[len-1] == ' ') len--; /* remove trailing spaces */
if (len * sizeof(WCHAR) < sizeof(buffer))
@@ -791,7 +912,11 @@ static BOOL import_dll( HMODULE module, const IMAGE_IMPORT_DESCRIPTOR *descr, LP
else /* need to allocate a larger buffer */
{
WCHAR *ptr = RtlAllocateHeap( GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR) );
- if (!ptr) return FALSE;
+ if (!ptr)
+ {
+ lock_modref( wm );
+ return FALSE;
+ }
ascii_to_unicode( ptr, name, len );
ptr[len] = 0;
status = load_dll( load_path, ptr, dllW, 0, &wmImp );
@@ -806,6 +931,7 @@ static BOOL import_dll( HMODULE module, const IMAGE_IMPORT_DESCRIPTOR *descr, LP
else
ERR("Loading library %s (which is needed by %s) failed (error %x).\n",
name, debugstr_w(current_modref->ldr.FullDllName.Buffer), status);
+ lock_modref( wm );
return FALSE;
}
@@ -852,8 +978,9 @@ static BOOL import_dll( HMODULE module, const IMAGE_IMPORT_DESCRIPTOR *descr, LP
{
int ordinal = IMAGE_ORDINAL(import_list->u1.Ordinal);
- thunk_list->u1.Function = (ULONG_PTR)find_ordinal_export( imp_mod, exports, exp_size,
+ thunk_list->u1.Function = (ULONG_PTR)find_ordinal_export( &wmImp, exports, exp_size,
ordinal - exports->Base, load_path );
+ assert( wmImp );
if (!thunk_list->u1.Function)
{
thunk_list->u1.Function = allocate_stub( name, IntToPtr(ordinal) );
@@ -867,9 +994,10 @@ static BOOL import_dll( HMODULE module, const IMAGE_IMPORT_DESCRIPTOR *descr, LP
{
IMAGE_IMPORT_BY_NAME *pe_name;
pe_name = get_rva( module, (DWORD)import_list->u1.AddressOfData );
- thunk_list->u1.Function = (ULONG_PTR)find_named_export( imp_mod, exports, exp_size,
+ thunk_list->u1.Function = (ULONG_PTR)find_named_export( &wmImp, exports, exp_size,
(const char*)pe_name->Name,
pe_name->Hint, load_path );
+ assert( wmImp );
if (!thunk_list->u1.Function)
{
thunk_list->u1.Function = allocate_stub( name, (const char*)pe_name->Name );
@@ -888,6 +1016,7 @@ done:
/* restore old protection of the import address table */
NtProtectVirtualMemory( NtCurrentProcess(), &protect_base, &protect_size, protect_old, &protect_old );
*pwm = wmImp;
+ lock_modref(wm);
return TRUE;
}
@@ -1079,12 +1208,16 @@ static NTSTATUS fixup_imports_ilonly( WINE_MODREF *wm, LPCWSTR load_path, void *
prev = current_modref;
current_modref = wm;
- if (!(status = load_dll( load_path, mscoreeW, NULL, 0, &imp ))) wm->deps[0] = imp;
+ unlock_modref( wm );
+ if (!(status = load_dll( load_path, mscoreeW, NULL, 0, &imp )))
+ wm->deps[0] = imp;
+
current_modref = prev;
if (status)
{
ERR( "mscoree.dll not found, IL-only binary %s cannot be loaded\n",
debugstr_w(wm->ldr.BaseDllName.Buffer) );
+ lock_modref( wm );
return status;
}
@@ -1094,8 +1227,12 @@ static NTSTATUS fixup_imports_ilonly( WINE_MODREF *wm, LPCWSTR load_path, void *
IMAGE_DIRECTORY_ENTRY_EXPORT, &exp_size )))
{
const char *name = (wm->ldr.Flags & LDR_IMAGE_IS_DLL) ? "_CorDllMain" : "_CorExeMain";
- proc = find_named_export( imp->ldr.DllBase, exports, exp_size, name, -1, load_path );
+ proc = find_named_export( &imp, exports, exp_size, name, -1, load_path );
+ assert( imp );
}
+ unlock_modref( imp );
+ lock_modref( wm );
+
if (!proc) return STATUS_PROCEDURE_NOT_FOUND;
*entry = proc;
return STATUS_SUCCESS;
@@ -1145,12 +1282,13 @@ static NTSTATUS fixup_imports( WINE_MODREF *wm, LPCWSTR load_path )
{
dep = wm->nDeps++;
- if (!import_dll( wm->ldr.DllBase, &imports[i], load_path, &imp ))
+ if (!import_dll( wm, &imports[i], load_path, &imp ))
{
imp = NULL;
status = STATUS_DLL_NOT_FOUND;
}
wm->deps[dep] = imp;
+ unlock_modref( imp );
}
current_modref = prev;
if (wm->ldr.ActivationContext) RtlDeactivateActivationContext( 0, cookie );
@@ -1178,6 +1316,8 @@ static WINE_MODREF *alloc_module( HMODULE hModule, const UNICODE_STRING *nt_name
wm->ldr.Flags = LDR_DONT_RESOLVE_REFS | (builtin ? LDR_WINE_INTERNAL : 0);
wm->ldr.TlsIndex = -1;
wm->ldr.LoadCount = 1;
+ RtlInitializeCriticalSection( &wm->module_section );
+ wm->module_section.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": module_section");
if (!(buffer = RtlAllocateHeap( GetProcessHeap(), 0, nt_name->Length - 3 * sizeof(WCHAR) )))
{
@@ -1199,11 +1339,14 @@ static WINE_MODREF *alloc_module( HMODULE hModule, const UNICODE_STRING *nt_name
wm->ldr.EntryPoint = (char *)hModule + nt->OptionalHeader.AddressOfEntryPoint;
}
+ lock_ldr_data( TRUE );
InsertTailList(&NtCurrentTeb()->Peb->LdrData->InLoadOrderModuleList,
&wm->ldr.InLoadOrderLinks);
InsertTailList(&NtCurrentTeb()->Peb->LdrData->InMemoryOrderModuleList,
&wm->ldr.InMemoryOrderLinks);
/* wait until init is called for inserting into InInitializationOrderModuleList */
+ lock_modref( wm );
+ unlock_ldr_data( TRUE );
if (!(nt->OptionalHeader.DllCharacteristics & IMAGE_DLLCHARACTERISTICS_NX_COMPAT))
{
@@ -1402,19 +1545,28 @@ static NTSTATUS process_attach( WINE_MODREF *wm, LPVOID lpReserved )
if (lpReserved) wm->ldr.LoadCount = -1; /* pin it if imported by the main exe */
if (wm->ldr.ActivationContext) RtlActivateActivationContext( 0, wm->ldr.ActivationContext, &cookie );
+ unlock_modref( wm );
/* Recursively attach all DLLs this one depends on */
for ( i = 0; i < wm->nDeps; i++ )
{
if (!wm->deps[i]) continue;
- if ((status = process_attach( wm->deps[i], lpReserved )) != STATUS_SUCCESS) break;
+
+ lock_modref( wm->deps[i] );
+ status = process_attach( wm->deps[i], lpReserved );
+ unlock_modref( wm->deps[i] );
+ if (status != STATUS_SUCCESS) break;
}
if (!wm->ldr.InInitializationOrderLinks.Flink)
+ {
+ lock_ldr_data( TRUE );
InsertTailList(&NtCurrentTeb()->Peb->LdrData->InInitializationOrderModuleList,
&wm->ldr.InInitializationOrderLinks);
+ unlock_ldr_data( TRUE );
+ }
/* Call DLL entry point */
- if (status == STATUS_SUCCESS)
+ if (!status)
{
WINE_MODREF *prev = current_modref;
current_modref = wm;
@@ -1423,6 +1575,7 @@ static NTSTATUS process_attach( WINE_MODREF *wm, LPVOID lpReserved )
status = MODULE_InitDLL( wm, DLL_PROCESS_ATTACH, lpReserved );
if (status == STATUS_SUCCESS)
{
+ lock_modref( wm );
wm->ldr.Flags |= LDR_PROCESS_ATTACHED;
}
else
@@ -1436,6 +1589,8 @@ static NTSTATUS process_attach( WINE_MODREF *wm, LPVOID lpReserved )
}
current_modref = prev;
}
+ if (status)
+ lock_modref( wm );
if (wm->ldr.ActivationContext) RtlDeactivateActivationContext( 0, cookie );
/* Remove recursion flag */
@@ -1462,12 +1617,16 @@ static void attach_implicitly_loaded_dlls( LPVOID reserved )
for (entry = mark->Flink; entry != mark; entry = entry->Flink)
{
LDR_DATA_TABLE_ENTRY *mod = CONTAINING_RECORD(entry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
+ WINE_MODREF *wm;
if (!(mod->Flags & LDR_IMAGE_IS_DLL)) continue;
if (mod->Flags & (LDR_LOAD_IN_PROGRESS | LDR_PROCESS_ATTACHED)) continue;
TRACE( "found implicitly loaded %s, attaching to it\n",
debugstr_w(mod->BaseDllName.Buffer));
- process_attach( CONTAINING_RECORD(mod, WINE_MODREF, ldr), reserved );
+ wm = CONTAINING_RECORD(mod, WINE_MODREF, ldr);
+ lock_modref( wm );
+ process_attach( wm, reserved );
+ unlock_modref( wm );
break; /* restart the search from the start */
}
if (entry == mark) break; /* nothing found */
@@ -1485,6 +1644,7 @@ static void process_detach(void)
{
PLIST_ENTRY mark, entry;
PLDR_DATA_TABLE_ENTRY mod;
+ WINE_MODREF *wm;
mark = &NtCurrentTeb()->Peb->LdrData->InInitializationOrderModuleList;
do
@@ -1499,10 +1659,12 @@ static void process_detach(void)
if ( mod->LoadCount && !process_detaching )
continue;
+ wm = CONTAINING_RECORD(mod, WINE_MODREF, ldr);
+ lock_modref( wm );
/* Call detach notification */
mod->Flags &= ~LDR_PROCESS_ATTACHED;
- MODULE_InitDLL( CONTAINING_RECORD(mod, WINE_MODREF, ldr),
- DLL_PROCESS_DETACH, ULongToPtr(process_detaching) );
+ unlock_modref( wm );
+ MODULE_InitDLL( wm, DLL_PROCESS_DETACH, ULongToPtr(process_detaching) );
call_ldr_notifications( LDR_DLL_NOTIFICATION_REASON_UNLOADED, mod );
/* Restart at head of WINE_MODREF list, as entries might have
@@ -1554,6 +1716,7 @@ NTSTATUS WINAPI LdrDisableThreadCalloutsForDll(HMODULE hModule)
ret = STATUS_DLL_NOT_FOUND;
else
wm->ldr.Flags |= LDR_NO_DLL_CALLS;
+ unlock_modref( wm );
RtlLeaveCriticalSection( &loader_section );
@@ -1718,17 +1881,18 @@ NTSTATUS WINAPI LdrGetProcedureAddress(HMODULE module, const ANSI_STRING *name,
IMAGE_EXPORT_DIRECTORY *exports;
DWORD exp_size;
NTSTATUS ret = STATUS_PROCEDURE_NOT_FOUND;
+ WINE_MODREF *modref;
RtlEnterCriticalSection( &loader_section );
/* check if the module itself is invalid to return the proper error */
- if (!get_modref( module )) ret = STATUS_DLL_NOT_FOUND;
+ if (!(modref = get_modref( module ))) ret = STATUS_DLL_NOT_FOUND;
else if ((exports = RtlImageDirectoryEntryToData( module, TRUE,
IMAGE_DIRECTORY_ENTRY_EXPORT, &exp_size )))
{
LPCWSTR load_path = NtCurrentTeb()->Peb->ProcessParameters->DllPath.Buffer;
- void *proc = name ? find_named_export( module, exports, exp_size, name->Buffer, -1, load_path )
- : find_ordinal_export( module, exports, exp_size, ord - exports->Base, load_path );
+ void *proc = name ? find_named_export( &modref, exports, exp_size, name->Buffer, -1, load_path )
+ : find_ordinal_export( &modref, exports, exp_size, ord - exports->Base, load_path );
if (proc)
{
*address = proc;
@@ -1736,6 +1900,9 @@ NTSTATUS WINAPI LdrGetProcedureAddress(HMODULE module, const ANSI_STRING *name,
}
}
+ if (modref)
+ unlock_modref( modref );
+
RtlLeaveCriticalSection( &loader_section );
return ret;
}
@@ -1908,8 +2075,11 @@ static NTSTATUS build_module( LPCWSTR load_path, const UNICODE_STRING *nt_name,
if (status != STATUS_SUCCESS)
{
/* the module has only be inserted in the load & memory order lists */
+ unlock_modref( wm );
+ lock_ldr_data( TRUE );
RemoveEntryList(&wm->ldr.InLoadOrderLinks);
RemoveEntryList(&wm->ldr.InMemoryOrderLinks);
+ unlock_ldr_data( TRUE );
/* FIXME: there are several more dangling references
* left. Including dlls loaded by this dll before the
@@ -2653,6 +2823,8 @@ static NTSTATUS load_dll( const WCHAR *load_path, const WCHAR *libname, const WC
main_exe = get_modref( NtCurrentTeb()->Peb->ImageBaseAddress );
loadorder = get_load_order( main_exe ? main_exe->ldr.BaseDllName.Buffer : NULL, &nt_name );
+ if (main_exe)
+ unlock_modref( main_exe );
switch (nts)
{
@@ -2711,6 +2883,7 @@ static NTSTATUS load_dll( const WCHAR *load_path, const WCHAR *libname, const WC
{
/* stub-only dll, try native */
TRACE( "%s pre-attach returned FALSE, preferring native\n", debugstr_us(&nt_name) );
+ unlock_modref( *pwm );
LdrUnloadDll( (*pwm)->ldr.DllBase );
nts = STATUS_DLL_NOT_FOUND;
/* map the dll again if it was unmapped */
@@ -2770,6 +2943,7 @@ NTSTATUS __cdecl __wine_init_unix_lib( HMODULE module, DWORD reason, const void
if ((wm = get_modref( module )))
{
NTSTATUS (CDECL *init_func)( HMODULE, DWORD, const void *, void * ) = wm->unix_entry;
+ unlock_modref( wm );
if (init_func) ret = init_func( module, reason, ptr_in, ptr_out );
}
else ret = STATUS_INVALID_HANDLE;
@@ -2798,11 +2972,20 @@ NTSTATUS WINAPI DECLSPEC_HOTPATCH LdrLoadDll(LPCWSTR path_name, DWORD flags,
nts = process_attach( wm, NULL );
if (nts != STATUS_SUCCESS)
{
+ unlock_modref( wm );
LdrUnloadDll(wm->ldr.DllBase);
wm = NULL;
}
}
- *hModule = (wm) ? wm->ldr.DllBase : NULL;
+ if (wm)
+ {
+ *hModule = wm->ldr.DllBase;
+ unlock_modref( wm );
+ }
+ else
+ {
+ *hModule = NULL;
+ }
RtlLeaveCriticalSection( &loader_section );
return nts;
@@ -2827,7 +3010,11 @@ NTSTATUS WINAPI LdrGetDllHandle( LPCWSTR load_path, ULONG flags, const UNICODE_S
status = find_dll_file( load_path, name->Buffer, dllW, &nt_name, &wm, &module, &image_info, &id );
- if (wm) *base = wm->ldr.DllBase;
+ if (wm)
+ {
+ *base = wm->ldr.DllBase;
+ unlock_modref( wm );
+ }
else
{
if (status == STATUS_SUCCESS) NtUnmapViewOfSection( NtCurrentProcess(), module );
@@ -2860,6 +3047,7 @@ NTSTATUS WINAPI LdrAddRefDll( ULONG flags, HMODULE module )
else
if (wm->ldr.LoadCount != -1) wm->ldr.LoadCount++;
TRACE( "(%s) ldr.LoadCount: %d\n", debugstr_w(wm->ldr.BaseDllName.Buffer), wm->ldr.LoadCount );
+ unlock_modref( wm );
}
else ret = STATUS_INVALID_PARAMETER;
@@ -3236,6 +3424,7 @@ void WINAPI LdrShutdownThread(void)
RtlEnterCriticalSection( &loader_section );
wm = get_modref( NtCurrentTeb()->Peb->ImageBaseAddress );
+ unlock_modref( wm );
mark = &NtCurrentTeb()->Peb->LdrData->InInitializationOrderModuleList;
for (entry = mark->Blink; entry != mark; entry = entry->Blink)
@@ -3280,6 +3469,7 @@ static void free_modref( WINE_MODREF *wm )
RemoveEntryList(&wm->ldr.InMemoryOrderLinks);
if (wm->ldr.InInitializationOrderLinks.Flink)
RemoveEntryList(&wm->ldr.InInitializationOrderLinks);
+ if (cached_modref == wm) cached_modref = NULL;
TRACE(" unloading %s\n", debugstr_w(wm->ldr.FullDllName.Buffer));
if (!TRACE_ON(module))
@@ -3294,11 +3484,15 @@ static void free_modref( WINE_MODREF *wm )
}
SERVER_END_REQ;
+ unlock_modref( wm );
+
+ wm->module_section.DebugInfo->Spare[0] = 0;
+ RtlDeleteCriticalSection( &wm->module_section );
+
free_tls_slot( &wm->ldr );
RtlReleaseActivationContext( wm->ldr.ActivationContext );
unix_funcs->unload_builtin_dll( wm->ldr.DllBase );
NtUnmapViewOfSection( NtCurrentProcess(), wm->ldr.DllBase );
- if (cached_modref == wm) cached_modref = NULL;
RtlFreeUnicodeString( &wm->ldr.FullDllName );
RtlFreeHeap( GetProcessHeap(), 0, wm->deps );
RtlFreeHeap( GetProcessHeap(), 0, wm );
@@ -3318,13 +3512,18 @@ static void MODULE_FlushModrefs(void)
LDR_DATA_TABLE_ENTRY *mod;
WINE_MODREF*wm;
+ lock_ldr_data( TRUE );
mark = &NtCurrentTeb()->Peb->LdrData->InInitializationOrderModuleList;
for (entry = mark->Blink; entry != mark; entry = prev)
{
mod = CONTAINING_RECORD(entry, LDR_DATA_TABLE_ENTRY, InInitializationOrderLinks);
wm = CONTAINING_RECORD(mod, WINE_MODREF, ldr);
+ lock_modref( wm );
prev = entry->Blink;
- if (!mod->LoadCount) free_modref( wm );
+ if (!mod->LoadCount)
+ free_modref( wm );
+ else
+ unlock_modref( wm );
}
/* check load order list too for modules that haven't been initialized yet */
@@ -3333,9 +3532,14 @@ static void MODULE_FlushModrefs(void)
{
mod = CONTAINING_RECORD(entry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
wm = CONTAINING_RECORD(mod, WINE_MODREF, ldr);
+ lock_modref( wm );
prev = entry->Blink;
- if (!mod->LoadCount) free_modref( wm );
+ if (!mod->LoadCount)
+ free_modref( wm );
+ else
+ unlock_modref( wm );
}
+ unlock_ldr_data( TRUE );
}
/***********************************************************************
@@ -3362,7 +3566,11 @@ static void MODULE_DecRefCount( WINE_MODREF *wm )
for ( i = 0; i < wm->nDeps; i++ )
if ( wm->deps[i] )
+ {
+ lock_modref( wm->deps[i] );
MODULE_DecRefCount( wm->deps[i] );
+ unlock_modref( wm->deps[i] );
+ }
wm->ldr.Flags &= ~LDR_UNLOAD_IN_PROGRESS;
@@ -3393,8 +3601,8 @@ NTSTATUS WINAPI LdrUnloadDll( HMODULE hModule )
/* Recursively decrement reference counts */
MODULE_DecRefCount( wm );
-
/* Call process detach notifications */
+ unlock_modref( wm );
if ( free_lib_count <= 1 )
{
process_detach();
@@ -3513,6 +3721,8 @@ void WINAPI LdrInitializeThunk( CONTEXT *context, ULONG_PTR unknown2, ULONG_PTR
imports_fixup_done = TRUE;
}
+ unlock_modref( wm );
+
RtlAcquirePebLock();
InsertHeadList( &tls_links, &NtCurrentTeb()->TlsLinks );
RtlReleasePebLock();
@@ -3536,7 +3746,10 @@ void WINAPI LdrInitializeThunk( CONTEXT *context, ULONG_PTR unknown2, ULONG_PTR
for (i = 0; i < wm->nDeps; i++)
{
if (!wm->deps[i]) continue;
- if ((status = process_attach( wm->deps[i], context )) != STATUS_SUCCESS)
+ lock_modref( wm->deps[i] );
+ status = process_attach( wm->deps[i], context );
+ unlock_modref( wm->deps[i] );
+ if (status)
{
if (last_failed_modref)
ERR( "%s failed to initialize, aborting\n",
@@ -4048,12 +4261,15 @@ static NTSTATUS process_init(void)
&meminfo, sizeof(meminfo), NULL );
status = build_builtin_module( params->DllPath.Buffer, &nt_name, meminfo.AllocationBase, 0, &wm );
assert( !status );
+ unlock_modref( wm );
if ((status = load_dll( params->DllPath.Buffer, kernel32W, NULL, 0, &wm )) != STATUS_SUCCESS)
{
MESSAGE( "wine: could not load kernel32.dll, status %x\n", status );
NtTerminateProcess( GetCurrentProcess(), status );
}
+ unlock_modref( wm );
+
RtlInitAnsiString( &func_name, "BaseThreadInitThunk" );
if ((status = LdrGetProcedureAddress( wm->ldr.DllBase, &func_name,
0, (void **)&pBaseThreadInitThunk )) != STATUS_SUCCESS)
@@ -4067,6 +4283,8 @@ static NTSTATUS process_init(void)
if (!(status = load_dll( params->DllPath.Buffer, params->ImagePathName.Buffer, NULL,
DONT_RESOLVE_DLL_REFERENCES, &wm )))
{
+ unlock_modref( wm );
+
peb->ImageBaseAddress = wm->ldr.DllBase;
TRACE( "main exe loaded %s at %p\n", debugstr_us(¶ms->ImagePathName), peb->ImageBaseAddress );
if (wm->ldr.Flags & LDR_IMAGE_IS_DLL)
@@ -4125,7 +4343,8 @@ static NTSTATUS process_init(void)
}
#endif
- /* the main exe needs to be the first in the load order list */
+ /* the main exe needs to be the first in the load order list.
+ * ldr_data_section locking is redundant here. */
RemoveEntryList( &wm->ldr.InLoadOrderLinks );
InsertHeadList( &peb->LdrData->InLoadOrderModuleList, &wm->ldr.InLoadOrderLinks );
RemoveEntryList( &wm->ldr.InMemoryOrderLinks );
--
2.28.0
2
5
Nov. 6, 2020
Otherwise, freetype_get_glyph_outline() fails at FT_Load_Glyph due to
combination of base_font's ft_face and child font's glyph index.
i.e., ft_face was updated at the following point:
static DWORD CDECL freetype_get_glyph_outline( struct gdi_font *incoming_gdi_font, UINT glyph, UINT format,
GLYPHMETRICS *lpgm, ABC *abc, DWORD buflen, void *buf,
const MAT2 *lpmat )
{
: : :
FT_Face ft_face = incoming_font->ft_face;
: : :
if(format & GGO_GLYPH_INDEX) {
: : :
} else {
BOOL vert;
get_glyph_index_linked(incoming_gdi_font, glyph, &gdi_font, &glyph_index, &vert);
font = get_font_ptr( gdi_font );
ft_face = font->ft_face; // <-------- HERE
if (!vert && tategaki)
tategaki = check_unicode_tategaki(glyph);
}
: : :
}
Fixes a regression introduced by 044315c0b3890676d9fd751d8191b0b7381e0b97.
Signed-off-by: Akihiro Sagawa <sagawa.aki(a)gmail.com>
---
dlls/gdi32/freetype.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
1
0
[PATCH 5/5] riched20: Use paragraph and run ptrs in the cursor structure.
by Huw Davies Nov. 6, 2020
by Huw Davies Nov. 6, 2020
Nov. 6, 2020
Signed-off-by: Huw Davies <huw(a)codeweavers.com>
---
dlls/riched20/caret.c | 185 +++++++++++++++----------------
dlls/riched20/clipboard.c | 2 +-
dlls/riched20/editor.c | 221 ++++++++++++++++++--------------------
dlls/riched20/editstr.h | 4 +-
dlls/riched20/paint.c | 10 +-
dlls/riched20/para.c | 28 ++---
dlls/riched20/richole.c | 14 +--
dlls/riched20/row.c | 12 +--
dlls/riched20/run.c | 88 +++++++--------
dlls/riched20/style.c | 6 +-
dlls/riched20/table.c | 82 +++++++-------
dlls/riched20/undo.c | 14 +--
dlls/riched20/wrap.c | 8 +-
dlls/riched20/writer.c | 64 +++++------
14 files changed, 359 insertions(+), 379 deletions(-)
diff --git a/dlls/riched20/caret.c b/dlls/riched20/caret.c
index 68bf40c76de..813074599a7 100644
--- a/dlls/riched20/caret.c
+++ b/dlls/riched20/caret.c
@@ -26,16 +26,16 @@ WINE_DEFAULT_DEBUG_CHANNEL(richedit);
void ME_SetCursorToStart(ME_TextEditor *editor, ME_Cursor *cursor)
{
- cursor->pPara = para_get_di( editor_first_para( editor ) );
- cursor->pRun = run_get_di( para_first_run( &cursor->pPara->member.para ) );
+ cursor->para = editor_first_para( editor );
+ cursor->run = para_first_run( cursor->para );
cursor->nOffset = 0;
}
static void ME_SetCursorToEnd(ME_TextEditor *editor, ME_Cursor *cursor, BOOL final_eop)
{
- cursor->pPara = para_get_di( para_prev( editor_end_para( editor ) ) );
- cursor->pRun = run_get_di( para_end_run( &cursor->pPara->member.para ) );
- cursor->nOffset = final_eop ? cursor->pRun->member.run.len : 0;
+ cursor->para = para_prev( editor_end_para( editor ) );
+ cursor->run = para_end_run( cursor->para );
+ cursor->nOffset = final_eop ? cursor->run->len : 0;
}
@@ -205,12 +205,12 @@ int set_selection_cursors(ME_TextEditor *editor, int from, int to)
editor->pCursors[0] = editor->pCursors[1];
ME_MoveCursorChars(editor, &editor->pCursors[0], to - from, FALSE);
/* Selection is not allowed in the middle of an end paragraph run. */
- if (editor->pCursors[1].pRun->member.run.nFlags & MERF_ENDPARA)
+ if (editor->pCursors[1].run->nFlags & MERF_ENDPARA)
editor->pCursors[1].nOffset = 0;
- if (editor->pCursors[0].pRun->member.run.nFlags & MERF_ENDPARA)
+ if (editor->pCursors[0].run->nFlags & MERF_ENDPARA)
{
if (to > len)
- editor->pCursors[0].nOffset = editor->pCursors[0].pRun->member.run.len;
+ editor->pCursors[0].nOffset = editor->pCursors[0].run->len;
else
editor->pCursors[0].nOffset = 0;
}
@@ -222,8 +222,8 @@ void cursor_coords( ME_TextEditor *editor, ME_Cursor *cursor,
int *x, int *y, int *height )
{
ME_Row *row;
- ME_Run *run = &cursor->pRun->member.run;
- ME_Paragraph *para = &cursor->pPara->member.para;
+ ME_Run *run = cursor->run;
+ ME_Paragraph *para = cursor->para;
ME_Run *size_run = run, *prev;
ME_Context c;
int run_x;
@@ -302,7 +302,7 @@ BOOL ME_InternalDeleteText(ME_TextEditor *editor, ME_Cursor *start,
/* Prevent deletion past last end of paragraph run. */
nChars = min(nChars, text_len - nOfs);
if (nChars == text_len) delete_all = TRUE;
- start_para = &c.pPara->member.para;
+ start_para = c.para;
if (!bForce)
{
@@ -318,17 +318,17 @@ BOOL ME_InternalDeleteText(ME_TextEditor *editor, ME_Cursor *start,
{
/* We aren't deleting anything in this run, so we will go back to the
* last run we are deleting text in. */
- c.pRun = run_get_di( run_prev_all_paras( &c.pRun->member.run ) );
- c.pPara = para_get_di( c.pRun->member.run.para );
- c.nOffset = c.pRun->member.run.len;
+ c.run = run_prev_all_paras( c.run );
+ c.para = c.run->para;
+ c.nOffset = c.run->len;
}
- run = &c.pRun->member.run;
+ run = c.run;
if (run->nFlags & MERF_ENDPARA)
{
- int eollen = c.pRun->member.run.len;
+ int eollen = c.run->len;
BOOL keepFirstParaFormat;
- if (!para_next( para_next( &c.pPara->member.para ) )) return TRUE;
+ if (!para_next( para_next( c.para ) )) return TRUE;
keepFirstParaFormat = (totalChars == nChars && nChars <= eollen &&
run->nCharOfs);
@@ -354,7 +354,7 @@ BOOL ME_InternalDeleteText(ME_TextEditor *editor, ME_Cursor *start,
keepFirstParaFormat = TRUE;
}
}
- para_join( editor, &c.pPara->member.para, keepFirstParaFormat );
+ para_join( editor, c.para, keepFirstParaFormat );
/* ME_SkipAndPropagateCharOffset(p->pRun, shift); */
ME_CheckCharOffsets(editor);
nChars -= (eollen < nChars) ? eollen : nChars;
@@ -368,7 +368,7 @@ BOOL ME_InternalDeleteText(ME_TextEditor *editor, ME_Cursor *start,
c.nOffset -= nCharsToDelete;
- para_mark_rewrap( editor, c.pRun->member.run.para );
+ para_mark_rewrap( editor, c.run->para );
cursor = c;
/* nChars is the number of characters that should be deleted from the
@@ -393,7 +393,7 @@ BOOL ME_InternalDeleteText(ME_TextEditor *editor, ME_Cursor *start,
for (i=-1; i<editor->nCursors; i++) {
ME_Cursor *pThisCur = editor->pCursors + i;
if (i == -1) pThisCur = &c;
- if (pThisCur->pRun == cursor.pRun) {
+ if (pThisCur->run == cursor.run) {
if (pThisCur->nOffset > cursor.nOffset) {
if (pThisCur->nOffset-cursor.nOffset < nCharsToDelete)
pThisCur->nOffset = cursor.nOffset;
@@ -404,8 +404,8 @@ BOOL ME_InternalDeleteText(ME_TextEditor *editor, ME_Cursor *start,
}
if (pThisCur->nOffset == run->len)
{
- pThisCur->pRun = run_get_di( run_next( &pThisCur->pRun->member.run ) );
- assert( pThisCur->pRun );
+ pThisCur->run = run_next( pThisCur->run );
+ assert( pThisCur->run );
pThisCur->nOffset = 0;
}
}
@@ -413,22 +413,19 @@ BOOL ME_InternalDeleteText(ME_TextEditor *editor, ME_Cursor *start,
/* c = updated data now */
- if (c.pRun == cursor.pRun)
- ME_SkipAndPropagateCharOffset(c.pRun, shift);
+ if (c.run == cursor.run)
+ ME_SkipAndPropagateCharOffset( run_get_di( c.run ), shift );
else
- ME_PropagateCharOffset(c.pRun, shift);
+ ME_PropagateCharOffset( run_get_di( c.run ), shift );
- if (!cursor.pRun->member.run.len)
+ if (!cursor.run->len)
{
TRACE("Removing empty run\n");
- ME_Remove(cursor.pRun);
- ME_DestroyDisplayItem(cursor.pRun);
+ ME_Remove( run_get_di( cursor.run ));
+ ME_DestroyDisplayItem( run_get_di( cursor.run ));
}
shift = 0;
- /*
- ME_CheckCharOffsets(editor);
- */
continue;
}
}
@@ -590,15 +587,15 @@ void ME_InsertTextFromCursor(ME_TextEditor *editor, int nCursor,
eol_len = 1;
}
- if (cursor->nOffset == cursor->pRun->member.run.len)
+ if (cursor->nOffset == cursor->run->len)
{
- run = run_next( &cursor->pRun->member.run );
- if (!run) run = &cursor->pRun->member.run;
+ run = run_next( cursor->run );
+ if (!run) run = cursor->run;
}
else
{
if (cursor->nOffset) run_split( editor, cursor );
- run = &cursor->pRun->member.run;
+ run = cursor->run;
}
new_para = para_split( editor, run, style, eol_str, eol_len, 0 );
@@ -611,11 +608,11 @@ void ME_InsertTextFromCursor(ME_TextEditor *editor, int nCursor,
int i;
for (i = 0; i < editor->nCursors; i++)
{
- if (editor->pCursors[i].pRun == run_get_di( prev ) &&
+ if (editor->pCursors[i].run == prev &&
editor->pCursors[i].nOffset == prev->len)
{
- editor->pCursors[i].pPara = para_get_di( new_para );
- editor->pCursors[i].pRun = run_get_di( run );
+ editor->pCursors[i].para = new_para;
+ editor->pCursors[i].run = run;
editor->pCursors[i].nOffset = 0;
}
}
@@ -638,18 +635,18 @@ int ME_MoveCursorChars(ME_TextEditor *editor, ME_Cursor *cursor, int nRelOfs, BO
cursor->nOffset += nRelOfs;
if (cursor->nOffset < 0)
{
- cursor->nOffset += cursor->pRun->member.run.nCharOfs;
+ cursor->nOffset += cursor->run->nCharOfs;
if (cursor->nOffset >= 0)
{
/* new offset in the same paragraph */
do {
- cursor->pRun = run_get_di( run_prev( &cursor->pRun->member.run ) );
- } while (cursor->nOffset < cursor->pRun->member.run.nCharOfs);
- cursor->nOffset -= cursor->pRun->member.run.nCharOfs;
+ cursor->run = run_prev( cursor->run );
+ } while (cursor->nOffset < cursor->run->nCharOfs);
+ cursor->nOffset -= cursor->run->nCharOfs;
return nRelOfs;
}
- cursor->nOffset += cursor->pPara->member.para.nCharOfs;
+ cursor->nOffset += cursor->para->nCharOfs;
if (cursor->nOffset <= 0)
{
/* moved to the start of the text */
@@ -660,30 +657,29 @@ int ME_MoveCursorChars(ME_TextEditor *editor, ME_Cursor *cursor, int nRelOfs, BO
/* new offset in a previous paragraph */
do {
- cursor->pPara = para_get_di( para_prev( &cursor->pPara->member.para ) );
- } while (cursor->nOffset < cursor->pPara->member.para.nCharOfs);
- cursor->nOffset -= cursor->pPara->member.para.nCharOfs;
-
- cursor->pRun = run_get_di( para_end_run( &cursor->pPara->member.para ) );
- while (cursor->nOffset < cursor->pRun->member.run.nCharOfs) {
- cursor->pRun = run_get_di( run_prev( &cursor->pRun->member.run ) );
- }
- cursor->nOffset -= cursor->pRun->member.run.nCharOfs;
+ cursor->para = para_prev( cursor->para );
+ } while (cursor->nOffset < cursor->para->nCharOfs);
+ cursor->nOffset -= cursor->para->nCharOfs;
+
+ cursor->run = para_end_run( cursor->para );
+ while (cursor->nOffset < cursor->run->nCharOfs)
+ cursor->run = run_prev( cursor->run );
+ cursor->nOffset -= cursor->run->nCharOfs;
}
- else if (cursor->nOffset >= cursor->pRun->member.run.len)
+ else if (cursor->nOffset >= cursor->run->len)
{
ME_Paragraph *next_para;
int new_offset;
new_offset = ME_GetCursorOfs(cursor);
- next_para = para_next( &cursor->pPara->member.para );
+ next_para = para_next( cursor->para );
if (new_offset < next_para->nCharOfs)
{
/* new offset in the same paragraph */
do {
- cursor->nOffset -= cursor->pRun->member.run.len;
- cursor->pRun = run_get_di( run_next( &cursor->pRun->member.run ) );
- } while (cursor->nOffset >= cursor->pRun->member.run.len);
+ cursor->nOffset -= cursor->run->len;
+ cursor->run = run_next( cursor->run );
+ } while (cursor->nOffset >= cursor->run->len);
return nRelOfs;
}
@@ -697,16 +693,16 @@ int ME_MoveCursorChars(ME_TextEditor *editor, ME_Cursor *cursor, int nRelOfs, BO
/* new offset in a following paragraph */
do {
- cursor->pPara = para_get_di( next_para );
+ cursor->para = next_para;
next_para = para_next( next_para );
} while (new_offset >= next_para->nCharOfs);
- cursor->nOffset = new_offset - cursor->pPara->member.para.nCharOfs;
- cursor->pRun = run_get_di( para_first_run( &cursor->pPara->member.para ) );
- while (cursor->nOffset >= cursor->pRun->member.run.len)
+ cursor->nOffset = new_offset - cursor->para->nCharOfs;
+ cursor->run = para_first_run( cursor->para );
+ while (cursor->nOffset >= cursor->run->len)
{
- cursor->nOffset -= cursor->pRun->member.run.len;
- cursor->pRun = run_get_di( run_next( &cursor->pRun->member.run ) );
+ cursor->nOffset -= cursor->run->len;
+ cursor->run = run_next( cursor->run );
}
} /* else new offset is in the same run */
return nRelOfs;
@@ -716,8 +712,8 @@ int ME_MoveCursorChars(ME_TextEditor *editor, ME_Cursor *cursor, int nRelOfs, BO
BOOL
ME_MoveCursorWords(ME_TextEditor *editor, ME_Cursor *cursor, int nRelOfs)
{
- ME_Run *run = &cursor->pRun->member.run, *other_run;
- ME_Paragraph *para = &cursor->pPara->member.para;
+ ME_Run *run = cursor->run, *other_run;
+ ME_Paragraph *para = cursor->para;
int nOffset = cursor->nOffset;
if (nRelOfs == -1)
@@ -732,7 +728,7 @@ ME_MoveCursorWords(ME_TextEditor *editor, ME_Cursor *cursor, int nRelOfs)
{
if (ME_CallWordBreakProc( editor, get_text( other_run, 0 ), other_run->len, other_run->len - 1, WB_ISDELIMITER )
&& !(run->nFlags & MERF_ENDPARA)
- && !(&cursor->pRun->member.run == run && cursor->nOffset == 0)
+ && !(cursor->run == run && cursor->nOffset == 0)
&& !ME_CallWordBreakProc( editor, get_text( run, 0 ), run->len, 0, WB_ISDELIMITER ))
break;
run = other_run;
@@ -740,7 +736,7 @@ ME_MoveCursorWords(ME_TextEditor *editor, ME_Cursor *cursor, int nRelOfs)
}
else
{
- if (&cursor->pRun->member.run == run && cursor->nOffset == 0)
+ if (cursor->run == run && cursor->nOffset == 0)
{
para = run->para;
/* Skip empty start of table row paragraph */
@@ -776,21 +772,21 @@ ME_MoveCursorWords(ME_TextEditor *editor, ME_Cursor *cursor, int nRelOfs)
else
{
para = para_next( para );
- if (para_get_di( para )->type == diTextEnd)
+ if (!para_next( para ))
{
- if (&cursor->pRun->member.run == run) return FALSE;
+ if (cursor->run == run) return FALSE;
nOffset = 0;
break;
}
if (para->nFlags & MEPF_ROWSTART) para = para_next( para );
- if (&cursor->pRun->member.run == run) run = para_first_run( para );
+ if (cursor->run == run) run = para_first_run( para );
nOffset = 0;
break;
}
}
}
- cursor->pPara = para_get_di( para );
- cursor->pRun = run_get_di( run );
+ cursor->para = para;
+ cursor->run = run;
cursor->nOffset = nOffset;
return TRUE;
}
@@ -818,11 +814,11 @@ ME_SelectByType(ME_TextEditor *editor, ME_SelectionType selectionType)
case stParagraph:
editor->pCursors[1] = editor->pCursors[0];
- editor->pCursors[0].pRun = run_get_di( para_end_run( &editor->pCursors[0].pPara->member.para ) );
- editor->pCursors[0].pPara = para_get_di( editor->pCursors[0].pRun->member.run.para );
- editor->pCursors[0].nOffset = editor->pCursors[0].pRun->member.run.len;
+ editor->pCursors[0].run = para_end_run( editor->pCursors[0].para );
+ editor->pCursors[0].para = editor->pCursors[0].run->para;
+ editor->pCursors[0].nOffset = editor->pCursors[0].run->len;
- editor->pCursors[1].pRun = run_get_di( para_first_run( &editor->pCursors[1].pPara->member.para ) );
+ editor->pCursors[1].run = para_first_run( editor->pCursors[1].para );
editor->pCursors[1].nOffset = 0;
break;
case stLine:
@@ -847,8 +843,7 @@ ME_SelectByType(ME_TextEditor *editor, ME_SelectionType selectionType)
int ME_GetCursorOfs(const ME_Cursor *cursor)
{
- return cursor->pPara->member.para.nCharOfs
- + cursor->pRun->member.run.nCharOfs + cursor->nOffset;
+ return cursor->para->nCharOfs + cursor->run->nCharOfs + cursor->nOffset;
}
/* Helper function for cursor_from_virtual_coords() to find paragraph within tables */
@@ -910,8 +905,8 @@ static BOOL row_cursor( ME_TextEditor *editor, ME_Row *row, int x,
if (x >= run->pt.x && x < run->pt.x + run->nWidth)
{
cursor->nOffset = ME_CharFromPoint( editor, x - run->pt.x, run, TRUE, TRUE );
- cursor->pRun = run_get_di( run );
- cursor->pPara = para_get_di( run->para );
+ cursor->run = run;
+ cursor->para = run->para;
return exact;
}
last = run;
@@ -920,8 +915,8 @@ static BOOL row_cursor( ME_TextEditor *editor, ME_Row *row, int x,
run = last;
- cursor->pRun = run_get_di( run );
- cursor->pPara = para_get_di( run->para );
+ cursor->run = run;
+ cursor->para = run->para;
return FALSE;
}
@@ -1057,7 +1052,7 @@ static void ME_ExtendAnchorSelection(ME_TextEditor *editor)
}
case stParagraph:
- editor->pCursors[1].pRun = run_get_di( para_first_run( &editor->pCursors[1].pPara->member.para ) );
+ editor->pCursors[1].run = para_first_run( editor->pCursors[1].para );
editor->pCursors[1].nOffset = 0;
break;
@@ -1083,9 +1078,9 @@ static void ME_ExtendAnchorSelection(ME_TextEditor *editor)
}
case stParagraph:
- editor->pCursors[0].pRun = run_get_di( para_end_run( &editor->pCursors[0].pPara->member.para ) );
- editor->pCursors[0].pPara = para_get_di( editor->pCursors[0].pRun->member.run.para );
- editor->pCursors[0].nOffset = editor->pCursors[0].pRun->member.run.len;
+ editor->pCursors[0].run = para_end_run( editor->pCursors[0].para );
+ editor->pCursors[0].para = editor->pCursors[0].run->para;
+ editor->pCursors[0].nOffset = editor->pCursors[0].run->len;
break;
default:
@@ -1188,7 +1183,7 @@ void ME_MouseMove(ME_TextEditor *editor, int x, int y)
static int ME_GetXForArrow(ME_TextEditor *editor, ME_Cursor *pCursor)
{
- ME_Run *run = &pCursor->pRun->member.run;
+ ME_Run *run = pCursor->run;
int x;
if (editor->nUDArrowX != -1)
@@ -1206,8 +1201,8 @@ static int ME_GetXForArrow(ME_TextEditor *editor, ME_Cursor *pCursor)
static void
ME_MoveCursorLines(ME_TextEditor *editor, ME_Cursor *pCursor, int nRelOfs, BOOL extend)
{
- ME_DisplayItem *pRun = pCursor->pRun;
- ME_Paragraph *old_para = &pCursor->pPara->member.para, *new_para;
+ ME_DisplayItem *pRun = run_get_di( pCursor->run );
+ ME_Paragraph *old_para = pCursor->para, *new_para;
ME_DisplayItem *pItem;
int x = ME_GetXForArrow(editor, pCursor);
@@ -1277,8 +1272,6 @@ ME_MoveCursorLines(ME_TextEditor *editor, ME_Cursor *pCursor, int nRelOfs, BOOL
return;
}
row_cursor( editor, &pItem->member.row, x, pCursor );
- assert(pCursor->pRun);
- assert(pCursor->pRun->type == diRun);
}
static void ME_ArrowPageUp(ME_TextEditor *editor, ME_Cursor *pCursor)
@@ -1293,7 +1286,7 @@ static void ME_ArrowPageUp(ME_TextEditor *editor, ME_Cursor *pCursor)
* Doesn't make sense, but we try to be bug for bug compatible. */
editor->nUDArrowX = -1;
} else {
- ME_DisplayItem *pRun = pCursor->pRun;
+ ME_DisplayItem *pRun = run_get_di( pCursor->run );
ME_DisplayItem *pLast;
int x, y, yd, yp;
int yOldScrollPos = editor->vert_si.nPos;
@@ -1328,8 +1321,6 @@ static void ME_ArrowPageUp(ME_TextEditor *editor, ME_Cursor *pCursor)
row_cursor( editor, &pLast->member.row, x, pCursor );
}
- assert(pCursor->pRun);
- assert(pCursor->pRun->type == diRun);
}
static void ME_ArrowPageDown(ME_TextEditor *editor, ME_Cursor *pCursor)
@@ -1348,7 +1339,7 @@ static void ME_ArrowPageDown(ME_TextEditor *editor, ME_Cursor *pCursor)
{
ME_SetCursorToEnd(editor, pCursor, FALSE);
} else {
- ME_DisplayItem *pRun = pCursor->pRun;
+ ME_DisplayItem *pRun = run_get_di( pCursor->run );
ME_DisplayItem *p;
int yd, yp;
int yOldScrollPos = editor->vert_si.nPos;
@@ -1382,8 +1373,6 @@ static void ME_ArrowPageDown(ME_TextEditor *editor, ME_Cursor *pCursor)
row_cursor( editor, &pLast->member.row, x, pCursor );
}
- assert(pCursor->pRun);
- assert(pCursor->pRun->type == diRun);
}
static void ME_ArrowHome( ME_TextEditor *editor, ME_Cursor *cursor )
@@ -1412,7 +1401,7 @@ static void ME_ArrowCtrlEnd(ME_TextEditor *editor, ME_Cursor *pCursor)
BOOL ME_IsSelection(ME_TextEditor *editor)
{
- return editor->pCursors[0].pRun != editor->pCursors[1].pRun ||
+ return editor->pCursors[0].run != editor->pCursors[1].run ||
editor->pCursors[0].nOffset != editor->pCursors[1].nOffset;
}
diff --git a/dlls/riched20/clipboard.c b/dlls/riched20/clipboard.c
index f74ca2dae1a..10a814214be 100644
--- a/dlls/riched20/clipboard.c
+++ b/dlls/riched20/clipboard.c
@@ -348,7 +348,7 @@ static HGLOBAL get_unicode_text(ME_TextEditor *editor, const ME_Cursor *start, i
int nEnd = ME_GetCursorOfs(start) + nChars;
/* count paragraphs in range */
- para = &start->pPara->member.para;
+ para = start->para;
while ((para = para_next( para )) && para->nCharOfs <= nEnd)
pars++;
diff --git a/dlls/riched20/editor.c b/dlls/riched20/editor.c
index 36918c9dd79..2f7383e59a1 100644
--- a/dlls/riched20/editor.c
+++ b/dlls/riched20/editor.c
@@ -593,9 +593,9 @@ void ME_RTFParAttrHook(RTF_Info *info)
/* We are just after a table row. */
RTFFlushOutputBuffer(info);
cursor = info->editor->pCursors[0];
- para = &cursor.pPara->member.para;
+ para = cursor.para;
if (para == para_next( info->tableDef->row_start )
- && !cursor.nOffset && !cursor.pRun->member.run.nCharOfs)
+ && !cursor.nOffset && !cursor.run->nCharOfs)
{
/* Since the table row end, no text has been inserted, and the \intbl
* control word has not be used. We can confirm that we are not in a
@@ -632,7 +632,7 @@ void ME_RTFParAttrHook(RTF_Info *info)
ME_Cursor cursor;
WCHAR endl = '\r';
cursor = info->editor->pCursors[0];
- if (cursor.nOffset || cursor.pRun->member.run.nCharOfs)
+ if (cursor.nOffset || cursor.run->nCharOfs)
ME_InsertTextFromCursor(info->editor, 0, &endl, 1, info->style);
tableDef->row_start = table_insert_row_start( info->editor, info->editor->pCursors );
}
@@ -658,7 +658,7 @@ void ME_RTFParAttrHook(RTF_Info *info)
if (tableDef->row_start && tableDef->row_start->nFlags & MEPF_ROWEND)
para = para_next( tableDef->row_start );
else
- para = &info->editor->pCursors[0].pPara->member.para;
+ para = info->editor->pCursors[0].para;
tableDef->row_start = table_insert_row_start_at_para( info->editor, para );
@@ -901,7 +901,7 @@ void ME_RTFTblAttrHook(RTF_Info *info)
{
/* Tab stops were used to store cell positions before v4.1 but v4.1
* still seems to set the tabstops without using them. */
- PARAFORMAT2 *fmt = &info->editor->pCursors[0].pPara->member.para.fmt;
+ PARAFORMAT2 *fmt = &info->editor->pCursors[0].para->fmt;
fmt->rgxTabs[cellNum] &= ~0x00FFFFFF;
fmt->rgxTabs[cellNum] |= 0x00FFFFFF & info->rtfParam;
}
@@ -971,7 +971,7 @@ void ME_RTFSpecialCharHook(RTF_Info *info)
}
else /* v1.0 - v3.0 */
{
- ME_Paragraph *para = &info->editor->pCursors[0].pPara->member.para;
+ ME_Paragraph *para = info->editor->pCursors[0].para;
if (para_in_table( para ) && tableDef->numCellsInserted < tableDef->numCellsDefined)
{
@@ -1043,13 +1043,12 @@ void ME_RTFSpecialCharHook(RTF_Info *info)
}
run = para_first_run( cell_first_para( cell ) );
- if (&info->editor->pCursors[0].pRun->member.run != run ||
- info->editor->pCursors[0].nOffset)
+ if (info->editor->pCursors[0].run != run || info->editor->pCursors[0].nOffset)
{
int nOfs, nChars;
/* Delete inserted cells that aren't defined. */
- info->editor->pCursors[1].pRun = run_get_di( run );
- info->editor->pCursors[1].pPara = para_get_di( run->para );
+ info->editor->pCursors[1].run = run;
+ info->editor->pCursors[1].para = run->para;
info->editor->pCursors[1].nOffset = 0;
nOfs = ME_GetCursorOfs(&info->editor->pCursors[1]);
nChars = ME_GetCursorOfs(&info->editor->pCursors[0]) - nOfs;
@@ -1085,7 +1084,7 @@ void ME_RTFSpecialCharHook(RTF_Info *info)
{
WCHAR endl = '\r';
- para = &info->editor->pCursors[0].pPara->member.para;
+ para = info->editor->pCursors[0].para;
para->fmt.dxOffset = info->tableDef->gapH;
para->fmt.dxStartIndent = info->tableDef->leftEdge;
@@ -1110,7 +1109,7 @@ void ME_RTFSpecialCharHook(RTF_Info *info)
ME_Paragraph *para;
RTFFlushOutputBuffer(info);
- para = &info->editor->pCursors[0].pPara->member.para;
+ para = info->editor->pCursors[0].para;
if (para_in_table( para ))
{
/* rtfPar is treated like a space within a table. */
@@ -1609,20 +1608,20 @@ static LRESULT ME_StreamIn(ME_TextEditor *editor, DWORD format, EDITSTREAM *stre
/* Don't insert text at the end of the table row */
if (!editor->bEmulateVersion10) /* v4.1 */
{
- ME_Paragraph *para = &editor->pCursors->pPara->member.para;
+ ME_Paragraph *para = editor->pCursors->para;
if (para->nFlags & (MEPF_ROWSTART | MEPF_ROWEND))
{
para = para_next( para );
- editor->pCursors[0].pPara = para_get_di( para );
- editor->pCursors[0].pRun = run_get_di( para_first_run( para ) );
+ editor->pCursors[0].para = para;
+ editor->pCursors[0].run = para_first_run( para );
editor->pCursors[0].nOffset = 0;
}
editor->pCursors[1] = editor->pCursors[0];
}
else /* v1.0 - 3.0 */
{
- if (editor->pCursors[0].pRun->member.run.nFlags & MERF_ENDPARA &&
- para_in_table( &editor->pCursors[0].pPara->member.para ))
+ if (editor->pCursors[0].run->nFlags & MERF_ENDPARA &&
+ para_in_table( editor->pCursors[0].para ))
return 0;
}
}
@@ -1635,7 +1634,7 @@ static LRESULT ME_StreamIn(ME_TextEditor *editor, DWORD format, EDITSTREAM *stre
ME_GetTextLength(editor), FALSE);
from = to = 0;
ME_ClearTempStyle(editor);
- editor_set_default_para_fmt( editor, &editor->pCursors[0].pPara->member.para.fmt );
+ editor_set_default_para_fmt( editor, &editor->pCursors[0].para->fmt );
}
@@ -1724,8 +1723,8 @@ static LRESULT ME_StreamIn(ME_TextEditor *editor, DWORD format, EDITSTREAM *stre
para = para_next( para );
}
- editor->pCursors[1].pPara = para_get_di( para );
- editor->pCursors[1].pRun = run_get_di( para_first_run( para ) );
+ editor->pCursors[1].para = para;
+ editor->pCursors[1].run = para_first_run( para );
editor->pCursors[1].nOffset = 0;
nOfs = ME_GetCursorOfs(&editor->pCursors[1]);
nChars = ME_GetCursorOfs(&editor->pCursors[0]) - nOfs;
@@ -1921,14 +1920,14 @@ ME_FindText(ME_TextEditor *editor, DWORD flags, const CHARRANGE *chrg, const WCH
if ((flags & FR_WHOLEWORD) && nMin)
{
cursor_from_char_ofs( editor, nMin - 1, &cursor );
- wLastChar = *get_text( &cursor.pRun->member.run, cursor.nOffset );
+ wLastChar = *get_text( cursor.run, cursor.nOffset );
ME_MoveCursorChars(editor, &cursor, 1, FALSE);
}
else cursor_from_char_ofs( editor, nMin, &cursor );
- while (cursor.pRun && ME_GetCursorOfs(&cursor) + nLen <= nMax)
+ while (cursor.run && ME_GetCursorOfs(&cursor) + nLen <= nMax)
{
- ME_Run *run = &cursor.pRun->member.run;
+ ME_Run *run = cursor.run;
int nCurStart = cursor.nOffset;
int nMatched = 0;
@@ -1962,7 +1961,7 @@ ME_FindText(ME_TextEditor *editor, DWORD flags, const CHARRANGE *chrg, const WCH
break;
}
- cursor.nOffset += cursor.pPara->member.para.nCharOfs + cursor.pRun->member.run.nCharOfs;
+ cursor.nOffset += cursor.para->nCharOfs + cursor.run->nCharOfs;
if (chrgText)
{
chrgText->cpMin = cursor.nOffset;
@@ -1983,16 +1982,16 @@ ME_FindText(ME_TextEditor *editor, DWORD flags, const CHARRANGE *chrg, const WCH
wLastChar = ' ';
cursor.nOffset++;
- if (cursor.nOffset == cursor.pRun->member.run.len)
+ if (cursor.nOffset == cursor.run->len)
{
- if (run_next_all_paras( &cursor.pRun->member.run ))
+ if (run_next_all_paras( cursor.run ))
{
- cursor.pRun = run_get_di( run_next_all_paras( &cursor.pRun->member.run ) );
- cursor.pPara = para_get_di( cursor.pRun->member.run.para );
+ cursor.run = run_next_all_paras( cursor.run );
+ cursor.para = cursor.run->para;
cursor.nOffset = 0;
}
else
- cursor.pRun = NULL;
+ cursor.run = NULL;
}
}
}
@@ -2002,15 +2001,15 @@ ME_FindText(ME_TextEditor *editor, DWORD flags, const CHARRANGE *chrg, const WCH
if ((flags & FR_WHOLEWORD) && nMax < nTextLen - 1)
{
cursor_from_char_ofs( editor, nMax + 1, &cursor );
- wLastChar = *get_text( &cursor.pRun->member.run, cursor.nOffset );
+ wLastChar = *get_text( cursor.run, cursor.nOffset );
ME_MoveCursorChars(editor, &cursor, -1, FALSE);
}
else cursor_from_char_ofs( editor, nMax, &cursor );
- while (cursor.pRun && ME_GetCursorOfs(&cursor) - nLen >= nMin)
+ while (cursor.run && ME_GetCursorOfs(&cursor) - nLen >= nMin)
{
- ME_Run *run = &cursor.pRun->member.run;
- ME_Paragraph *para = &cursor.pPara->member.para;
+ ME_Run *run = cursor.run;
+ ME_Paragraph *para = cursor.para;
int nCurEnd = cursor.nOffset;
int nMatched = 0;
@@ -2080,14 +2079,14 @@ ME_FindText(ME_TextEditor *editor, DWORD flags, const CHARRANGE *chrg, const WCH
cursor.nOffset--;
if (cursor.nOffset < 0)
{
- if (run_prev_all_paras( &cursor.pRun->member.run ) )
+ if (run_prev_all_paras( cursor.run ) )
{
- cursor.pRun = run_get_di( run_prev_all_paras( &cursor.pRun->member.run ) );
- cursor.pPara = para_get_di( cursor.pRun->member.run.para );
- cursor.nOffset = cursor.pRun->member.run.len;
+ cursor.run = run_prev_all_paras( cursor.run );
+ cursor.para = cursor.run->para;
+ cursor.nOffset = cursor.run->len;
}
else
- cursor.pRun = NULL;
+ cursor.run = NULL;
}
}
}
@@ -2448,14 +2447,14 @@ static void ME_UpdateSelectionLinkAttribute(ME_TextEditor *editor)
ME_GetSelection(editor, &from, &to);
/* Find paragraph previous to the one that contains start cursor */
- start_para = &from->pPara->member.para;
+ start_para = from->para;
if (para_prev( start_para )) start_para = para_prev( start_para );
/* Find paragraph that contains end cursor */
- end_para = para_next( &to->pPara->member.para );
+ end_para = para_next( to->para );
- start.pPara = para_get_di( start_para );
- start.pRun = run_get_di( para_first_run( start_para ) );
+ start.para = start_para;
+ start.run = para_first_run( start_para );
start.nOffset = 0;
num_chars = end_para->nCharOfs - start_para->nCharOfs;
@@ -2497,7 +2496,7 @@ static BOOL handle_enter(ME_TextEditor *editor)
static const WCHAR endl = '\r';
static const WCHAR endlv10[] = {'\r','\n'};
ME_Cursor cursor = editor->pCursors[0];
- ME_Paragraph *para = &cursor.pPara->member.para;
+ ME_Paragraph *para = cursor.para;
int from, to;
ME_Style *style, *eop_style;
@@ -2517,33 +2516,32 @@ static BOOL handle_enter(ME_TextEditor *editor)
/* Add a new table row after this row. */
para = table_append_row( editor, para );
para = para_next( para );
- editor->pCursors[0].pPara = para_get_di( para );
- editor->pCursors[0].pRun = run_get_di( para_first_run( para ) );
+ editor->pCursors[0].para = para;
+ editor->pCursors[0].run = para_first_run( para );
editor->pCursors[0].nOffset = 0;
editor->pCursors[1] = editor->pCursors[0];
ME_CommitUndo(editor);
ME_UpdateRepaint(editor, FALSE);
return TRUE;
}
- else if (para == &editor->pCursors[1].pPara->member.para &&
- cursor.nOffset + cursor.pRun->member.run.nCharOfs == 0 &&
+ else if (para == editor->pCursors[1].para &&
+ cursor.nOffset + cursor.run->nCharOfs == 0 &&
para_prev( para ) && para_prev( para )->nFlags & MEPF_ROWSTART &&
!para_prev( para )->nCharOfs)
{
/* Insert a newline before the table. */
para = para_prev( para );
para->nFlags &= ~MEPF_ROWSTART;
- editor->pCursors[0].pPara = para_get_di( para );
- editor->pCursors[0].pRun = run_get_di( para_first_run( para ) );
+ editor->pCursors[0].para = para;
+ editor->pCursors[0].run = para_first_run( para );
editor->pCursors[1] = editor->pCursors[0];
- ME_InsertTextFromCursor(editor, 0, &endl, 1,
- editor->pCursors[0].pRun->member.run.style);
+ ME_InsertTextFromCursor( editor, 0, &endl, 1, editor->pCursors[0].run->style );
para = editor_first_para( editor );
editor_set_default_para_fmt( editor, ¶->fmt );
para->nFlags = 0;
para_mark_rewrap( editor, para );
- editor->pCursors[0].pPara = para_get_di( para );
- editor->pCursors[0].pRun = run_get_di( para_first_run( para ) );
+ editor->pCursors[0].para = para;
+ editor->pCursors[0].run = para_first_run( para );
editor->pCursors[1] = editor->pCursors[0];
para_next( para )->nFlags |= MEPF_ROWSTART;
ME_CommitCoalescingUndo(editor);
@@ -2553,17 +2551,17 @@ static BOOL handle_enter(ME_TextEditor *editor)
}
else /* v1.0 - 3.0 */
{
- ME_Paragraph *para = &cursor.pPara->member.para;
+ ME_Paragraph *para = cursor.para;
if (para_in_table( para ))
{
- if (cursor.pRun->member.run.nFlags & MERF_ENDPARA)
+ if (cursor.run->nFlags & MERF_ENDPARA)
{
if (from == to)
{
ME_ContinueCoalescingTransaction(editor);
para = table_append_row( editor, para );
- editor->pCursors[0].pPara = para_get_di( para );
- editor->pCursors[0].pRun = run_get_di( para_first_run( para ) );
+ editor->pCursors[0].para = para;
+ editor->pCursors[0].run = para_first_run( para );
editor->pCursors[0].nOffset = 0;
editor->pCursors[1] = editor->pCursors[0];
ME_CommitCoalescingUndo(editor);
@@ -2574,27 +2572,26 @@ static BOOL handle_enter(ME_TextEditor *editor)
else
{
ME_ContinueCoalescingTransaction(editor);
- if (cursor.pRun->member.run.nCharOfs + cursor.nOffset == 0 &&
+ if (cursor.run->nCharOfs + cursor.nOffset == 0 &&
para_prev( para ) && !para_in_table( para_prev( para ) ))
{
/* Insert newline before table */
- cursor.pRun = run_get_di( para_end_run( para_prev( para ) ) );
- if (cursor.pRun)
+ cursor.run = para_end_run( para_prev( para ) );
+ if (cursor.run)
{
- editor->pCursors[0].pRun = cursor.pRun;
- editor->pCursors[0].pPara = para_get_di( para_prev( para ) );
+ editor->pCursors[0].run = cursor.run;
+ editor->pCursors[0].para = para_prev( para );
}
editor->pCursors[0].nOffset = 0;
editor->pCursors[1] = editor->pCursors[0];
- ME_InsertTextFromCursor(editor, 0, &endl, 1,
- editor->pCursors[0].pRun->member.run.style);
+ ME_InsertTextFromCursor( editor, 0, &endl, 1, editor->pCursors[0].run->style );
}
else
{
editor->pCursors[1] = editor->pCursors[0];
para = table_append_row( editor, para );
- editor->pCursors[0].pPara = para_get_di( para );
- editor->pCursors[0].pRun = run_get_di( para_first_run( para ) );
+ editor->pCursors[0].para = para;
+ editor->pCursors[0].run = para_first_run( para );
editor->pCursors[0].nOffset = 0;
editor->pCursors[1] = editor->pCursors[0];
}
@@ -2795,7 +2792,7 @@ static LRESULT ME_Char(ME_TextEditor *editor, WPARAM charCode,
if ((unsigned)wstr >= ' ' || wstr == '\t')
{
ME_Cursor cursor = editor->pCursors[0];
- ME_Paragraph *para = &cursor.pPara->member.para;
+ ME_Paragraph *para = cursor.para;
int from, to;
BOOL ctrl_is_down = GetKeyState(VK_CONTROL) & 0x8000;
ME_GetSelectionOfs(editor, &from, &to);
@@ -2806,7 +2803,7 @@ static LRESULT ME_Char(ME_TextEditor *editor, WPARAM charCode,
BOOL selected_row = FALSE;
if (ME_IsSelection(editor) &&
- cursor.pRun->member.run.nCharOfs + cursor.nOffset == 0 &&
+ cursor.run->nCharOfs + cursor.nOffset == 0 &&
to == ME_GetCursorOfs(&editor->pCursors[0]) && para_prev( para ))
{
para = para_prev( para );
@@ -2827,8 +2824,8 @@ static LRESULT ME_Char(ME_TextEditor *editor, WPARAM charCode,
{
para = para_next( para );
if (para->nFlags & MEPF_ROWSTART) para = para_next( para );
- editor->pCursors[0].pPara = para_get_di( para );
- editor->pCursors[0].pRun = run_get_di( para_first_run( para ) );
+ editor->pCursors[0].para = para;
+ editor->pCursors[0].run = para_first_run( para );
editor->pCursors[0].nOffset = 0;
editor->pCursors[1] = editor->pCursors[0];
}
@@ -2836,9 +2833,7 @@ static LRESULT ME_Char(ME_TextEditor *editor, WPARAM charCode,
}
else /* v1.0 - 3.0 */
{
- if (para_in_table( para ) &&
- cursor.pRun->member.run.nFlags & MERF_ENDPARA &&
- from == to)
+ if (para_in_table( para ) && cursor.run->nFlags & MERF_ENDPARA && from == to)
{
/* Text should not be inserted at the end of the table. */
MessageBeep(-1);
@@ -2983,9 +2978,8 @@ static BOOL ME_SetCursor(ME_TextEditor *editor)
ME_CharFromPos(editor, pt.x, pt.y, &cursor, &isExact);
if (isExact)
{
- ME_Run *run;
+ ME_Run *run = cursor.run;
- run = &cursor.pRun->member.run;
if (is_link( run ))
{
ITextHost_TxSetCursor(editor->texthost,
@@ -3039,10 +3033,8 @@ static LONG ME_GetSelectionType(ME_TextEditor *editor)
ME_Cursor cursor;
cursor_from_char_ofs( editor, start + i, &cursor );
- if (cursor.pRun->member.run.reobj)
- object_count++;
- else
- character_count++;
+ if (cursor.run->reobj) object_count++;
+ else character_count++;
if (character_count >= 2 && object_count >= 2)
return (SEL_TEXT | SEL_MULTICHAR | SEL_OBJECT | SEL_MULTIOBJECT);
}
@@ -3138,7 +3130,7 @@ ME_TextEditor *ME_MakeEditor(ITextHost *texthost, BOOL bEmulateVersion10)
ed->nUndoMode = umAddToUndo;
ed->nParagraphs = 1;
ed->nLastSelStart = ed->nLastSelEnd = 0;
- ed->last_sel_start_para = ed->last_sel_end_para = &ed->pCursors[0].pPara->member.para;
+ ed->last_sel_start_para = ed->last_sel_end_para = ed->pCursors[0].para;
ed->bHideSelection = FALSE;
ed->pfnWordBreak = NULL;
ed->lpOleCallback = NULL;
@@ -3459,7 +3451,7 @@ static void ME_LinkNotify(ME_TextEditor *editor, UINT msg, WPARAM wParam, LPARAM
ME_CharFromPos(editor, x, y, &cursor, &isExact);
if (!isExact) return;
- if (is_link( &cursor.pRun->member.run ))
+ if (is_link( cursor.run ))
{ /* The clicked run has CFE_LINK set */
info.nmhdr.hwndFrom = NULL;
info.nmhdr.idFrom = 0;
@@ -3471,13 +3463,13 @@ static void ME_LinkNotify(ME_TextEditor *editor, UINT msg, WPARAM wParam, LPARAM
/* find the first contiguous run with CFE_LINK set */
info.chrg.cpMin = ME_GetCursorOfs(&cursor);
- run = &cursor.pRun->member.run;
+ run = cursor.run;
while ((run = run_prev( run )) && is_link( run ))
info.chrg.cpMin -= run->len;
/* find the last contiguous run with CFE_LINK set */
- info.chrg.cpMax = ME_GetCursorOfs(&cursor) + cursor.pRun->member.run.len;
- run = &cursor.pRun->member.run;
+ info.chrg.cpMax = ME_GetCursorOfs(&cursor) + cursor.run->len;
+ run = cursor.run;
while ((run = run_next( run )) && is_link( run ))
info.chrg.cpMax += run->len;
@@ -4253,13 +4245,13 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
row_first_cursor( row, &start );
row_end_cursor( row, &end, TRUE );
- run = &start.pRun->member.run;
+ run = start.run;
while (nCharsLeft)
{
WCHAR *str;
unsigned int nCopy;
- int ofs = (run == &start.pRun->member.run) ? start.nOffset : 0;
- int len = (run == &end.pRun->member.run) ? end.nOffset : run->len;
+ int ofs = (run == start.run) ? start.nOffset : 0;
+ int len = (run == end.run) ? end.nOffset : run->len;
str = get_text( run, ofs );
nCopy = min( nCharsLeft, len );
@@ -4271,7 +4263,7 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
nCharsLeft, NULL, NULL);
dest += nCopy * (unicode ? sizeof(WCHAR) : 1);
nCharsLeft -= nCopy;
- if (run == &end.pRun->member.run) break;
+ if (run == end.run) break;
run = row_next_run( row, run );
}
@@ -4457,18 +4449,17 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
nCharOfs = max(nCharOfs, 0);
cursor_from_char_ofs( editor, nCharOfs, &cursor );
- pt.y = cursor.pRun->member.run.pt.y;
- pt.x = cursor.pRun->member.run.pt.x +
- ME_PointFromChar( editor, &cursor.pRun->member.run, cursor.nOffset, TRUE );
- pt.y += cursor.pPara->member.para.pt.y + editor->rcFormat.top;
+ pt.y = cursor.run->pt.y;
+ pt.x = cursor.run->pt.x +
+ ME_PointFromChar( editor, cursor.run, cursor.nOffset, TRUE );
+ pt.y += cursor.para->pt.y + editor->rcFormat.top;
pt.x += editor->rcFormat.left;
pt.x -= editor->horz_si.nPos;
pt.y -= editor->vert_si.nPos;
- if (wParam >= 0x40000) {
- *(POINTL *)wParam = pt;
- }
+ if (wParam >= 0x40000) *(POINTL *)wParam = pt;
+
return (wParam >= 0x40000) ? 0 : MAKELONG( pt.x, pt.y );
}
case WM_CREATE:
@@ -4910,8 +4901,8 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
/* plain text can only have the default style. */
ME_ClearTempStyle(editor);
ME_AddRefStyle(editor->pBuffer->pDefaultStyle);
- ME_ReleaseStyle(editor->pCursors[0].pRun->member.run.style);
- editor->pCursors[0].pRun->member.run.style = editor->pBuffer->pDefaultStyle;
+ ME_ReleaseStyle( editor->pCursors[0].run->style );
+ editor->pCursors[0].run->style = editor->pBuffer->pDefaultStyle;
}
}
/* FIXME: Currently no support for undo level and code page options */
@@ -5165,7 +5156,7 @@ int ME_GetTextW(ME_TextEditor *editor, WCHAR *buffer, int buflen,
/* bCRLF flag is only honored in 2.0 and up. 1.0 must always return text verbatim */
if (editor->bEmulateVersion10) bCRLF = FALSE;
- run = &start->pRun->member.run;
+ run = start->run;
next_run = run_next_all_paras( run );
nLen = run->len - start->nOffset;
@@ -5358,8 +5349,8 @@ static BOOL ME_FindNextURLCandidate(ME_TextEditor *editor,
while (nChars > 0)
{
- WCHAR *str = get_text( &cursor.pRun->member.run, 0 );
- int run_len = cursor.pRun->member.run.len;
+ WCHAR *str = get_text( cursor.run, 0 );
+ int run_len = cursor.run->len;
nChars -= run_len - cursor.nOffset;
@@ -5373,8 +5364,8 @@ static BOOL ME_FindNextURLCandidate(ME_TextEditor *editor,
{
*candidate_min = cursor;
candidateStarted = TRUE;
- neutral_end.pPara = NULL;
- space_end.pPara = NULL;
+ neutral_end.para = NULL;
+ space_end.para = NULL;
cursor.nOffset++;
break;
}
@@ -5393,9 +5384,9 @@ static BOOL ME_FindNextURLCandidate(ME_TextEditor *editor,
{
if (quoted && c != '\r')
{
- if (!space_end.pPara)
+ if (!space_end.para)
{
- if (neutral_end.pPara)
+ if (neutral_end.para)
space_end = neutral_end;
else
space_end = cursor;
@@ -5408,15 +5399,15 @@ static BOOL ME_FindNextURLCandidate(ME_TextEditor *editor,
{
if (quoted && c == '>')
{
- neutral_end.pPara = NULL;
- space_end.pPara = NULL;
+ neutral_end.para = NULL;
+ space_end.para = NULL;
goto done;
}
- if (!neutral_end.pPara)
+ if (!neutral_end.para)
neutral_end = cursor;
}
else
- neutral_end.pPara = NULL;
+ neutral_end.para = NULL;
cursor.nOffset++;
}
@@ -5430,9 +5421,9 @@ static BOOL ME_FindNextURLCandidate(ME_TextEditor *editor,
done:
if (candidateStarted)
{
- if (space_end.pPara)
+ if (space_end.para)
*candidate_max = space_end;
- else if (neutral_end.pPara)
+ else if (neutral_end.para)
*candidate_max = neutral_end;
else
*candidate_max = cursor;
@@ -5521,7 +5512,7 @@ static BOOL ME_UpdateLinkAttribute(ME_TextEditor *editor, ME_Cursor *start, int
nChars = 0;
}
- if (startCur.pRun != candidateStart.pRun ||
+ if (startCur.run != candidateStart.run ||
startCur.nOffset != candidateStart.nOffset)
{
/* CFE_LINK effect should be consistently unset */
@@ -5538,15 +5529,15 @@ static BOOL ME_UpdateLinkAttribute(ME_TextEditor *editor, ME_Cursor *start, int
/* Update candidateEnd since setting character formats may split
* runs, which can cause a cursor to be at an invalid offset within
* a split run. */
- while (candidateEnd.nOffset >= candidateEnd.pRun->member.run.len)
+ while (candidateEnd.nOffset >= candidateEnd.run->len)
{
- candidateEnd.nOffset -= candidateEnd.pRun->member.run.len;
- candidateEnd.pRun = ME_FindItemFwd(candidateEnd.pRun, diRun);
+ candidateEnd.nOffset -= candidateEnd.run->len;
+ candidateEnd.run = run_next_all_paras( candidateEnd.run );
}
modified = TRUE;
}
}
- if (candidateStart.pRun != candidateEnd.pRun ||
+ if (candidateStart.run != candidateEnd.run ||
candidateStart.nOffset != candidateEnd.nOffset)
{
/* CFE_LINK effect should be consistently set */
diff --git a/dlls/riched20/editstr.h b/dlls/riched20/editstr.h
index 9c2cdd685b1..204e078c986 100644
--- a/dlls/riched20/editstr.h
+++ b/dlls/riched20/editstr.h
@@ -274,8 +274,8 @@ typedef struct tagME_TextBuffer
typedef struct tagME_Cursor
{
- ME_DisplayItem *pPara;
- ME_DisplayItem *pRun;
+ ME_Paragraph *para;
+ ME_Run *run;
int nOffset;
} ME_Cursor;
diff --git a/dlls/riched20/paint.c b/dlls/riched20/paint.c
index 6228c760295..ad2ffb9abb9 100644
--- a/dlls/riched20/paint.c
+++ b/dlls/riched20/paint.c
@@ -437,7 +437,7 @@ static void ME_DebugWrite(HDC hDC, const POINT *pt, LPCWSTR szText) {
static void draw_run( ME_Context *c, int x, int y, ME_Cursor *cursor )
{
ME_Row *row;
- ME_Run *run = &cursor->pRun->member.run;
+ ME_Run *run = cursor->run;
int runofs = run_char_ofs( run, cursor->nOffset );
int nSelFrom, nSelTo;
@@ -999,8 +999,8 @@ static void draw_paragraph( ME_Context *c, ME_Paragraph *para )
{
ME_Cursor cursor;
- cursor.pRun = run_get_di( run );
- cursor.pPara = para_get_di( para );
+ cursor.run = run;
+ cursor.para = para;
cursor.nOffset = 0;
draw_run( c, c->pt.x + run->pt.x, c->pt.y + para->pt.y + run->pt.y + baseline, &cursor );
}
@@ -1271,9 +1271,9 @@ void ME_UpdateScrollBar(ME_TextEditor *editor)
void editor_ensure_visible( ME_TextEditor *editor, ME_Cursor *cursor )
{
- ME_Run *run = &cursor->pRun->member.run;
+ ME_Run *run = cursor->run;
ME_Row *row = row_from_cursor( cursor );
- ME_Paragraph *para = &cursor->pPara->member.para;
+ ME_Paragraph *para = cursor->para;
int x, y, yheight;
diff --git a/dlls/riched20/para.c b/dlls/riched20/para.c
index d01a264765a..a8168ff0daa 100644
--- a/dlls/riched20/para.c
+++ b/dlls/riched20/para.c
@@ -581,10 +581,10 @@ ME_Paragraph *para_split( ME_TextEditor *editor, ME_Run *run, ME_Style *style,
/* Update selection cursors to point to the correct paragraph. */
for (i = 0; i < editor->nCursors; i++)
{
- if (editor->pCursors[i].pPara == para_get_di( old_para ) &&
- run->nCharOfs <= editor->pCursors[i].pRun->member.run.nCharOfs)
+ if (editor->pCursors[i].para == old_para &&
+ run->nCharOfs <= editor->pCursors[i].run->nCharOfs)
{
- editor->pCursors[i].pPara = para_get_di( new_para );
+ editor->pCursors[i].para = new_para;
}
}
@@ -708,10 +708,10 @@ ME_Paragraph *para_join( ME_TextEditor *editor, ME_Paragraph *para, BOOL use_fir
/* null char format operation to store the original char format for the ENDPARA run */
ME_InitCharFormat2W(&fmt);
- startCur.pPara = para_get_di( para );
- startCur.pRun = run_get_di( end_run );
- endCur.pPara = para_get_di( next );
- endCur.pRun = run_get_di( next_first_run );
+ startCur.para = para;
+ startCur.run = end_run;
+ endCur.para = next;
+ endCur.run = next_first_run;
startCur.nOffset = endCur.nOffset = 0;
ME_SetCharFormat(editor, &startCur, &endCur, &fmt);
@@ -757,13 +757,13 @@ ME_Paragraph *para_join( ME_TextEditor *editor, ME_Paragraph *para, BOOL use_fir
* paragraph run, and point to the correct paragraph. */
for (i = 0; i < editor->nCursors; i++)
{
- if (editor->pCursors[i].pRun == run_get_di( end_run ))
+ if (editor->pCursors[i].run == end_run)
{
- editor->pCursors[i].pRun = run_get_di( next_first_run );
+ editor->pCursors[i].run = next_first_run;
editor->pCursors[i].nOffset = 0;
}
- else if (editor->pCursors[i].pPara == para_get_di( next ))
- editor->pCursors[i].pPara = para_get_di( para );
+ else if (editor->pCursors[i].para == next)
+ editor->pCursors[i].para = para;
}
for (tmp_run = next_first_run; tmp_run; tmp_run = run_next( tmp_run ))
@@ -869,8 +869,8 @@ void editor_get_selection_paras( ME_TextEditor *editor, ME_Paragraph **para, ME_
{
ME_Cursor *pEndCursor = &editor->pCursors[1];
- *para = &editor->pCursors[0].pPara->member.para;
- *para_end = &editor->pCursors[1].pPara->member.para;
+ *para = editor->pCursors[0].para;
+ *para_end = editor->pCursors[1].para;
if (*para == *para_end)
return;
@@ -885,7 +885,7 @@ void editor_get_selection_paras( ME_TextEditor *editor, ME_Paragraph **para, ME_
/* The paragraph at the end of a non-empty selection isn't included
* if the selection ends at the start of the paragraph. */
- if (!pEndCursor->pRun->member.run.nCharOfs && !pEndCursor->nOffset)
+ if (!pEndCursor->run->nCharOfs && !pEndCursor->nOffset)
*para_end = para_prev( *para_end );
}
diff --git a/dlls/riched20/richole.c b/dlls/riched20/richole.c
index 015326c5abc..5d73731dedb 100644
--- a/dlls/riched20/richole.c
+++ b/dlls/riched20/richole.c
@@ -1390,20 +1390,20 @@ IRichEditOle_fnGetObject(IRichEditOle *me, LONG iob,
TRACE("character offset: %d\n", lpreobject->cp);
cursor_from_char_ofs( This->editor, lpreobject->cp, &cursor );
- if (!cursor.pRun->member.run.reobj)
+ if (!cursor.run->reobj)
return E_INVALIDARG;
else
- reobj = cursor.pRun->member.run.reobj;
+ reobj = cursor.run->reobj;
}
else if (iob == REO_IOB_SELECTION)
{
ME_Cursor *from, *to;
ME_GetSelection(This->editor, &from, &to);
- if (!from->pRun->member.run.reobj)
+ if (!from->run->reobj)
return E_INVALIDARG;
else
- reobj = from->pRun->member.run.reobj;
+ reobj = from->run->reobj;
}
else
{
@@ -1659,7 +1659,7 @@ static HRESULT WINAPI ITextRange_fnGetText(ITextRange *me, BSTR *str)
if (!*str)
return E_OUTOFMEMORY;
- bEOP = (end.pRun->next->type == diTextEnd && This->end > ME_GetTextLength(editor));
+ bEOP = (!para_next( para_next( end.para )) && This->end > ME_GetTextLength(editor));
ME_GetTextW(editor, *str, length, &start, length, FALSE, bEOP);
return S_OK;
}
@@ -1714,7 +1714,7 @@ static HRESULT range_GetChar(ME_TextEditor *editor, ME_Cursor *cursor, LONG *pch
{
WCHAR wch[2];
- ME_GetTextW(editor, wch, 1, cursor, 1, FALSE, cursor->pRun->next->type == diTextEnd);
+ ME_GetTextW(editor, wch, 1, cursor, 1, FALSE, !para_next( para_next( cursor->para ) ));
*pch = wch[0];
return S_OK;
@@ -4745,7 +4745,7 @@ static HRESULT WINAPI ITextSelection_fnGetText(ITextSelection *me, BSTR *pbstr)
if (!*pbstr)
return E_OUTOFMEMORY;
- bEOP = (end->pRun->next->type == diTextEnd && endOfs > ME_GetTextLength(This->reOle->editor));
+ bEOP = (!para_next( para_next( end->para ) ) && endOfs > ME_GetTextLength(This->reOle->editor));
ME_GetTextW(This->reOle->editor, *pbstr, nChars, start, nChars, FALSE, bEOP);
TRACE("%s\n", wine_dbgstr_w(*pbstr));
diff --git a/dlls/riched20/row.c b/dlls/riched20/row.c
index 9a87cf27fb5..f5d3ad15701 100644
--- a/dlls/riched20/row.c
+++ b/dlls/riched20/row.c
@@ -57,7 +57,7 @@ ME_Row *row_from_cursor( ME_Cursor *cursor )
{
ME_DisplayItem *item;
- item = ME_FindItemBack( cursor->pRun, diStartRow );
+ item = ME_FindItemBack( run_get_di( cursor->run ), diStartRow );
return &item->member.row;
}
@@ -66,8 +66,8 @@ void row_first_cursor( ME_Row *row, ME_Cursor *cursor )
ME_DisplayItem *item;
item = ME_FindItemFwd( row_get_di( row ), diRun );
- cursor->pRun = item;
- cursor->pPara = para_get_di( cursor->pRun->member.run.para );
+ cursor->run = &item->member.run;
+ cursor->para = cursor->run->para;
cursor->nOffset = 0;
}
@@ -77,9 +77,9 @@ void row_end_cursor( ME_Row *row, ME_Cursor *cursor, BOOL include_eop )
item = ME_FindItemFwd( row_get_di( row ), diStartRowOrParagraphOrEnd );
run = ME_FindItemBack( item, diRun );
- cursor->pRun = run;
- cursor->pPara = para_get_di( cursor->pRun->member.run.para );
- cursor->nOffset = (item->type == diStartRow || include_eop) ? cursor->pRun->member.run.len : 0;
+ cursor->run = &run->member.run;
+ cursor->para = cursor->run->para;
+ cursor->nOffset = (item->type == diStartRow || include_eop) ? cursor->run->len : 0;
}
ME_Row *row_from_row_number( ME_TextEditor *editor, int row_num )
diff --git a/dlls/riched20/run.c b/dlls/riched20/run.c
index 978f6691356..db0ae0a6aa0 100644
--- a/dlls/riched20/run.c
+++ b/dlls/riched20/run.c
@@ -29,15 +29,15 @@ WINE_DECLARE_DEBUG_CHANNEL(richedit_lists);
BOOL cursor_next_run( ME_Cursor *cursor, BOOL all_para )
{
- ME_DisplayItem *p = cursor->pRun->next;
+ ME_DisplayItem *p = run_get_di( cursor->run )->next;
while (p->type != diTextEnd)
{
if (p->type == diParagraph && !all_para) return FALSE;
else if (p->type == diRun)
{
- cursor->pRun = p;
- cursor->pPara = para_get_di( cursor->pRun->member.run.para );
+ cursor->run = &p->member.run;
+ cursor->para = cursor->run->para;
cursor->nOffset = 0;
return TRUE;
}
@@ -48,15 +48,15 @@ BOOL cursor_next_run( ME_Cursor *cursor, BOOL all_para )
BOOL cursor_prev_run( ME_Cursor *cursor, BOOL all_para )
{
- ME_DisplayItem *p = cursor->pRun->prev;
+ ME_DisplayItem *p = run_get_di( cursor->run )->prev;
while (p->type != diTextStart)
{
if (p->type == diParagraph && !all_para) return FALSE;
else if (p->type == diRun)
{
- cursor->pRun = p;
- cursor->pPara = para_get_di( cursor->pRun->member.run.para );
+ cursor->run = &p->member.run;
+ cursor->para = cursor->run->para;
cursor->nOffset = 0;
return TRUE;
}
@@ -69,12 +69,12 @@ ME_Run *run_next( ME_Run *run )
{
ME_Cursor cursor;
- cursor.pRun = run_get_di( run );
- cursor.pPara = para_get_di( run->para );
+ cursor.run = run;
+ cursor.para = run->para;
cursor.nOffset = 0;
if (cursor_next_run( &cursor, FALSE ))
- return &cursor.pRun->member.run;
+ return cursor.run;
return NULL;
}
@@ -83,12 +83,12 @@ ME_Run *run_prev( ME_Run *run )
{
ME_Cursor cursor;
- cursor.pRun = run_get_di( run );
- cursor.pPara = para_get_di( run->para );
+ cursor.run = run;
+ cursor.para = run->para;
cursor.nOffset = 0;
if (cursor_prev_run( &cursor, FALSE ))
- return &cursor.pRun->member.run;
+ return cursor.run;
return NULL;
}
@@ -97,12 +97,12 @@ ME_Run *run_next_all_paras( ME_Run *run )
{
ME_Cursor cursor;
- cursor.pRun = run_get_di( run );
- cursor.pPara = para_get_di( run->para );
+ cursor.run = run;
+ cursor.para = run->para;
cursor.nOffset = 0;
if (cursor_next_run( &cursor, TRUE ))
- return &cursor.pRun->member.run;
+ return cursor.run;
return NULL;
}
@@ -111,12 +111,12 @@ ME_Run *run_prev_all_paras( ME_Run *run )
{
ME_Cursor cursor;
- cursor.pRun = run_get_di( run );
- cursor.pPara = para_get_di( run->para );
+ cursor.run = run;
+ cursor.para = run->para;
cursor.nOffset = 0;
if (cursor_prev_run( &cursor, TRUE ))
- return &cursor.pRun->member.run;
+ return cursor.run;
return NULL;
}
@@ -282,8 +282,8 @@ void cursor_from_char_ofs( ME_TextEditor *editor, int char_ofs, ME_Cursor *curso
char_ofs -= run->nCharOfs;
- cursor->pPara = para_get_di( para );
- cursor->pRun = run_get_di( run );
+ cursor->para = para;
+ cursor->run = run;
cursor->nOffset = char_ofs;
}
@@ -304,9 +304,9 @@ void run_join( ME_TextEditor *editor, ME_Run *run )
/* Update all cursors so that they don't contain the soon deleted run */
for (i = 0; i < editor->nCursors; i++)
{
- if (&editor->pCursors[i].pRun->member.run == next)
+ if (editor->pCursors[i].run == next)
{
- editor->pCursors[i].pRun = run_get_di( run );
+ editor->pCursors[i].run = run;
editor->pCursors[i].nOffset += run->len;
}
}
@@ -326,7 +326,7 @@ void run_join( ME_TextEditor *editor, ME_Run *run )
*/
ME_Run *run_split( ME_TextEditor *editor, ME_Cursor *cursor )
{
- ME_Run *run = &cursor->pRun->member.run, *new_run;
+ ME_Run *run = cursor->run, *new_run;
int i;
int nOffset = cursor->nOffset;
@@ -337,7 +337,7 @@ ME_Run *run_split( ME_TextEditor *editor, ME_Cursor *cursor )
new_run->len = run->len - nOffset;
new_run->para = run->para;
run->len = nOffset;
- cursor->pRun = run_get_di( new_run );
+ cursor->run = new_run;
cursor->nOffset = 0;
ME_InsertBefore( run_get_di( run )->next, run_get_di( new_run ) );
@@ -346,10 +346,10 @@ ME_Run *run_split( ME_TextEditor *editor, ME_Cursor *cursor )
ME_UpdateRunFlags( editor, new_run );
for (i = 0; i < editor->nCursors; i++)
{
- if (editor->pCursors[i].pRun == run_get_di( run ) &&
+ if (editor->pCursors[i].run == run &&
editor->pCursors[i].nOffset >= nOffset)
{
- editor->pCursors[i].pRun = run_get_di( new_run );
+ editor->pCursors[i].run = new_run;
editor->pCursors[i].nOffset -= nOffset;
}
}
@@ -397,19 +397,19 @@ ME_Run *run_create( ME_Style *s, int flags )
ME_Run *run_insert( ME_TextEditor *editor, ME_Cursor *cursor, ME_Style *style,
const WCHAR *str, int len, int flags )
{
- ME_Run *insert_before = &cursor->pRun->member.run, *run, *prev;
+ ME_Run *insert_before = cursor->run, *run, *prev;
if (cursor->nOffset)
{
if (cursor->nOffset == insert_before->len)
{
insert_before = run_next_all_paras( insert_before );
- if (!insert_before) insert_before = &cursor->pRun->member.run; /* Always insert before the final eop run */
+ if (!insert_before) insert_before = cursor->run; /* Always insert before the final eop run */
}
else
{
run_split( editor, cursor );
- insert_before = &cursor->pRun->member.run;
+ insert_before = cursor->run;
}
}
@@ -433,10 +433,10 @@ ME_Run *run_insert( ME_TextEditor *editor, ME_Cursor *cursor, ME_Style *style,
for (i = 0; i < editor->nCursors; i++)
{
- if (editor->pCursors[i].pRun == run_get_di( prev ) &&
+ if (editor->pCursors[i].run == prev &&
editor->pCursors[i].nOffset == prev->len)
{
- editor->pCursors[i].pRun = run_get_di( run );
+ editor->pCursors[i].run = run;
editor->pCursors[i].nOffset = len;
}
}
@@ -795,35 +795,35 @@ void ME_SetSelectionCharFormat(ME_TextEditor *editor, CHARFORMAT2W *pFmt)
*/
void ME_SetCharFormat( ME_TextEditor *editor, ME_Cursor *start, ME_Cursor *end, CHARFORMAT2W *fmt )
{
- ME_Run *run, *start_run = &start->pRun->member.run, *end_run = NULL;
+ ME_Run *run, *start_run = start->run, *end_run = NULL;
- if (end && start->pRun == end->pRun && start->nOffset == end->nOffset)
+ if (end && start->run == end->run && start->nOffset == end->nOffset)
return;
- if (start->nOffset == start->pRun->member.run.len)
- start_run = run_next_all_paras( &start->pRun->member.run );
+ if (start->nOffset == start->run->len)
+ start_run = run_next_all_paras( start->run );
else if (start->nOffset)
{
/* run_split() may or may not update the cursors, depending on whether they
* are selection cursors, but we need to make sure they are valid. */
int split_offset = start->nOffset;
ME_Run *split_run = run_split( editor, start );
- start_run = &start->pRun->member.run;
- if (end && &end->pRun->member.run == split_run)
+ start_run = start->run;
+ if (end && end->run == split_run)
{
- end->pRun = start->pRun;
+ end->run = start->run;
end->nOffset -= split_offset;
}
}
if (end)
{
- if (end->nOffset == end->pRun->member.run.len)
- end_run = run_next_all_paras( &end->pRun->member.run );
+ if (end->nOffset == end->run->len)
+ end_run = run_next_all_paras( end->run );
else
{
if (end->nOffset) run_split( editor, end );
- end_run = &end->pRun->member.run;
+ end_run = end->run;
}
}
@@ -893,16 +893,16 @@ void ME_GetCharFormat( ME_TextEditor *editor, const ME_Cursor *from,
ME_Run *run, *run_end, *prev_run;
CHARFORMAT2W tmp;
- run = &from->pRun->member.run;
+ run = from->run;
/* special case - if selection is empty, take previous char's formatting */
- if (from->pRun == to->pRun && from->nOffset == to->nOffset)
+ if (from->run == to->run && from->nOffset == to->nOffset)
{
if (!from->nOffset && (prev_run = run_prev( run ))) run = prev_run;
run_copy_char_fmt( run, fmt );
return;
}
- run_end = &to->pRun->member.run;
+ run_end = to->run;
if (!to->nOffset) run_end = run_prev_all_paras( run_end );
run_copy_char_fmt( run, fmt );
diff --git a/dlls/riched20/style.c b/dlls/riched20/style.c
index 95d3d3b6b29..917a5bd8100 100644
--- a/dlls/riched20/style.c
+++ b/dlls/riched20/style.c
@@ -482,14 +482,14 @@ ME_Style *style_get_insert_style( ME_TextEditor *editor, ME_Cursor *cursor )
if (ME_IsSelection( editor ))
{
ME_GetSelection( editor, &from, &to );
- style = from->pRun->member.run.style;
+ style = from->run->style;
}
else if (editor->pBuffer->pCharStyle)
style = editor->pBuffer->pCharStyle;
- else if (!cursor->nOffset && (prev = run_prev( &cursor->pRun->member.run )))
+ else if (!cursor->nOffset && (prev = run_prev( cursor->run )))
style = prev->style;
else
- style = cursor->pRun->member.run.style;
+ style = cursor->run->style;
ME_AddRefStyle( style );
return style;
diff --git a/dlls/riched20/table.c b/dlls/riched20/table.c
index 8d58c3e4f8f..0ce5a2c32c0 100644
--- a/dlls/riched20/table.c
+++ b/dlls/riched20/table.c
@@ -64,10 +64,10 @@ static ME_Paragraph* table_insert_end_para( ME_TextEditor *editor, ME_Cursor *cu
if (cursor->nOffset) run_split( editor, cursor );
- para = para_split( editor, &cursor->pRun->member.run, style, eol_str, eol_len, para_flags );
+ para = para_split( editor, cursor->run, style, eol_str, eol_len, para_flags );
ME_ReleaseStyle( style );
- cursor->pPara = para_get_di( para );
- cursor->pRun = run_get_di( para_first_run( para ) );
+ cursor->para = para;
+ cursor->run = para_first_run( para );
return para;
}
@@ -84,13 +84,13 @@ ME_Paragraph* table_insert_row_start_at_para( ME_TextEditor *editor, ME_Paragrap
ME_Paragraph *prev_para, *end_para, *start_row;
ME_Cursor cursor;
- cursor.pPara = para_get_di( para );
- cursor.pRun = run_get_di( para_first_run( para ) );
+ cursor.para = para;
+ cursor.run = para_first_run( para );
cursor.nOffset = 0;
start_row = table_insert_row_start( editor, &cursor );
- end_para = para_next( &editor->pCursors[0].pPara->member.para );
+ end_para = para_next( editor->pCursors[0].para );
prev_para = para_next( start_row );
para = para_next( prev_para );
@@ -220,20 +220,20 @@ void table_protect_partial_deletion( ME_TextEditor *editor, ME_Cursor *c, int *n
{
int start_ofs = ME_GetCursorOfs( c );
ME_Cursor c2 = *c;
- ME_Paragraph *this_para = &c->pPara->member.para, *end_para;
+ ME_Paragraph *this_para = c->para, *end_para;
ME_MoveCursorChars( editor, &c2, *num_chars, FALSE );
- end_para = &c2.pPara->member.para;
- if (c2.pRun->member.run.nFlags & MERF_ENDPARA)
+ end_para = c2.para;
+ if (c2.run->nFlags & MERF_ENDPARA)
{
/* End offset might be in the middle of the end paragraph run.
* If this is the case, then we need to use the next paragraph as the last
* paragraphs.
*/
- int remaining = start_ofs + *num_chars - c2.pRun->member.run.nCharOfs - end_para->nCharOfs;
+ int remaining = start_ofs + *num_chars - c2.run->nCharOfs - end_para->nCharOfs;
if (remaining)
{
- assert( remaining < c2.pRun->member.run.len );
+ assert( remaining < c2.run->len );
end_para = para_next( end_para );
}
}
@@ -293,11 +293,11 @@ void table_protect_partial_deletion( ME_TextEditor *editor, ME_Cursor *c, int *n
if ((this_para->nCharOfs != start_ofs || this_para == end_para) && para_in_table( this_para ))
{
- run = &c->pRun->member.run;
+ run = c->run;
/* Find the next tab or end paragraph to use as a delete boundary */
while (!(run->nFlags & (MERF_TAB | MERF_ENDPARA)))
run = run_next( run );
- chars_to_boundary = run->nCharOfs - c->pRun->member.run.nCharOfs - c->nOffset;
+ chars_to_boundary = run->nCharOfs - c->run->nCharOfs - c->nOffset;
*num_chars = min( *num_chars, chars_to_boundary );
}
else if (para_in_table( end_para ))
@@ -341,8 +341,8 @@ ME_Paragraph* table_append_row( ME_TextEditor *editor, ME_Paragraph *table_row )
prev_table_end = table_row_end( table_row );
para = para_next( prev_table_end );
run = para_first_run( para );
- editor->pCursors[0].pPara = para_get_di( para );
- editor->pCursors[0].pRun = run_get_di( run );
+ editor->pCursors[0].para = para;
+ editor->pCursors[0].run = run;
editor->pCursors[0].nOffset = 0;
editor->pCursors[1] = editor->pCursors[0];
new_row_start = table_insert_row_start( editor, editor->pCursors );
@@ -368,12 +368,12 @@ ME_Paragraph* table_append_row( ME_TextEditor *editor, ME_Paragraph *table_row )
{
run = para_end_run( table_row );
assert( para_in_table( table_row ) );
- editor->pCursors[0].pPara = para_get_di( table_row );
- editor->pCursors[0].pRun = run_get_di( run );
+ editor->pCursors[0].para = table_row;
+ editor->pCursors[0].run = run;
editor->pCursors[0].nOffset = 0;
editor->pCursors[1] = editor->pCursors[0];
ME_InsertTextFromCursor( editor, 0, &endl, 1, run->style );
- run = &editor->pCursors[0].pRun->member.run;
+ run = editor->pCursors[0].run;
for (i = 0; i < table_row->fmt.cTabCount; i++)
ME_InsertTextFromCursor( editor, 0, &tab, 1, run->style );
@@ -410,8 +410,8 @@ static void table_select_next_cell_or_append( ME_TextEditor *editor, ME_Run *run
para = table_append_row( editor, table_row_start( para ) );
/* Put cursor at the start of the new table row */
para = para_next( para );
- editor->pCursors[0].pPara = para_get_di( para );
- editor->pCursors[0].pRun = run_get_di( para_first_run( para ) );
+ editor->pCursors[0].para = para;
+ editor->pCursors[0].run = para_first_run( para );
editor->pCursors[0].nOffset = 0;
editor->pCursors[1] = editor->pCursors[0];
ME_WrapMarkedParagraphs(editor);
@@ -419,11 +419,11 @@ static void table_select_next_cell_or_append( ME_TextEditor *editor, ME_Run *run
}
}
/* Select cell */
- editor->pCursors[1].pPara = para_get_di( cell_first_para( cell ) );
- editor->pCursors[1].pRun = run_get_di( para_first_run( &editor->pCursors[1].pPara->member.para ) );
+ editor->pCursors[1].para = cell_first_para( cell );
+ editor->pCursors[1].run = para_first_run( editor->pCursors[1].para );
editor->pCursors[1].nOffset = 0;
- editor->pCursors[0].pPara = para_get_di( cell_end_para( cell ) );
- editor->pCursors[0].pRun = run_get_di( para_end_run( &editor->pCursors[0].pPara->member.para ) );
+ editor->pCursors[0].para = cell_end_para( cell );
+ editor->pCursors[0].run = para_end_run( editor->pCursors[0].para );
editor->pCursors[0].nOffset = 0;
}
else /* v1.0 - 3.0 */
@@ -443,8 +443,8 @@ static void table_select_next_cell_or_append( ME_TextEditor *editor, ME_Run *run
if (para_in_table( para ))
{
run = para_first_run( para );
- editor->pCursors[0].pPara = para_get_di( para );
- editor->pCursors[0].pRun = run_get_di( run );
+ editor->pCursors[0].para = para;
+ editor->pCursors[0].run = run;
editor->pCursors[0].nOffset = 0;
i = 1;
}
@@ -453,8 +453,8 @@ static void table_select_next_cell_or_append( ME_TextEditor *editor, ME_Run *run
/* Insert table row */
para = table_append_row( editor, para_prev( para ) );
/* Put cursor at the start of the new table row */
- editor->pCursors[0].pPara = para_get_di( para );
- editor->pCursors[0].pRun = run_get_di( para_first_run( para ) );
+ editor->pCursors[0].para = para;
+ editor->pCursors[0].run = para_first_run( para );
editor->pCursors[0].nOffset = 0;
editor->pCursors[1] = editor->pCursors[0];
ME_WrapMarkedParagraphs(editor);
@@ -464,8 +464,8 @@ static void table_select_next_cell_or_append( ME_TextEditor *editor, ME_Run *run
else run = run_next( run );
}
if (i == 0) run = run_next_all_paras( run );
- editor->pCursors[i].pRun = run_get_di( run );
- editor->pCursors[i].pPara = para_get_di( run->para );
+ editor->pCursors[i].run = run;
+ editor->pCursors[i].para = run->para;
editor->pCursors[i].nOffset = 0;
}
}
@@ -494,32 +494,32 @@ void table_handle_tab( ME_TextEditor *editor, BOOL selected_row )
}
if (!editor->bEmulateVersion10) /* v4.1 */
{
- if (!para_in_table( &toCursor.pPara->member.para ))
+ if (!para_in_table( toCursor.para ))
{
editor->pCursors[0] = toCursor;
editor->pCursors[1] = toCursor;
}
- else table_select_next_cell_or_append( editor, &toCursor.pRun->member.run );
+ else table_select_next_cell_or_append( editor, toCursor.run );
}
else /* v1.0 - 3.0 */
{
- if (!para_in_table( &fromCursor.pPara->member.para) )
+ if (!para_in_table( fromCursor.para ))
{
editor->pCursors[0] = fromCursor;
editor->pCursors[1] = fromCursor;
/* FIXME: For some reason the caret is shown at the start of the
* previous paragraph in v1.0 to v3.0 */
}
- else if ((selected_row || !para_in_table( &toCursor.pPara->member.para )))
- table_select_next_cell_or_append( editor, &fromCursor.pRun->member.run );
+ else if ((selected_row || !para_in_table( toCursor.para )))
+ table_select_next_cell_or_append( editor, fromCursor.run );
else
{
- ME_Run *run = run_prev( &toCursor.pRun->member.run );
+ ME_Run *run = run_prev( toCursor.run );
if (ME_IsSelection(editor) && !toCursor.nOffset && run && run->nFlags & MERF_TAB)
table_select_next_cell_or_append( editor, run );
else
- table_select_next_cell_or_append( editor, &toCursor.pRun->member.run );
+ table_select_next_cell_or_append( editor, toCursor.run );
}
}
ME_InvalidateSelection(editor);
@@ -532,15 +532,15 @@ void table_handle_tab( ME_TextEditor *editor, BOOL selected_row )
* without a selection. */
void table_move_from_row_start( ME_TextEditor *editor )
{
- ME_Paragraph *para = &editor->pCursors[0].pPara->member.para;
+ ME_Paragraph *para = editor->pCursors[0].para;
- if (para == &editor->pCursors[1].pPara->member.para && para->nFlags & MEPF_ROWSTART)
+ if (para == editor->pCursors[1].para && para->nFlags & MEPF_ROWSTART)
{
/* The cursors should not be at the hidden start row paragraph without
* a selection, so the cursor is moved into the first cell. */
para = para_next( para );
- editor->pCursors[0].pPara = para_get_di( para );
- editor->pCursors[0].pRun = run_get_di( para_first_run( para ) );
+ editor->pCursors[0].para = para;
+ editor->pCursors[0].run = para_first_run( para );
editor->pCursors[0].nOffset = 0;
editor->pCursors[1] = editor->pCursors[0];
}
diff --git a/dlls/riched20/undo.c b/dlls/riched20/undo.c
index d6665bfd104..d95ce121234 100644
--- a/dlls/riched20/undo.c
+++ b/dlls/riched20/undo.c
@@ -336,10 +336,10 @@ static void ME_PlayUndoItem(ME_TextEditor *editor, struct undo_item *undo)
{
ME_Cursor tmp;
cursor_from_char_ofs( editor, undo->u.set_para_fmt.pos, &tmp );
- add_undo_set_para_fmt( editor, &tmp.pPara->member.para );
- tmp.pPara->member.para.fmt = undo->u.set_para_fmt.fmt;
- tmp.pPara->member.para.border = undo->u.set_para_fmt.border;
- para_mark_rewrap( editor, &tmp.pPara->member.para );
+ add_undo_set_para_fmt( editor, tmp.para );
+ tmp.para->fmt = undo->u.set_para_fmt.fmt;
+ tmp.para->border = undo->u.set_para_fmt.border;
+ para_mark_rewrap( editor, tmp.para );
break;
}
case undo_set_char_fmt:
@@ -371,7 +371,7 @@ static void ME_PlayUndoItem(ME_TextEditor *editor, struct undo_item *undo)
{
ME_Cursor tmp;
cursor_from_char_ofs( editor, undo->u.join_paras.pos, &tmp );
- para_join( editor, &tmp.pPara->member.para, TRUE );
+ para_join( editor, tmp.para, TRUE );
break;
}
case undo_split_para:
@@ -383,7 +383,7 @@ static void ME_PlayUndoItem(ME_TextEditor *editor, struct undo_item *undo)
cursor_from_char_ofs( editor, undo->u.split_para.pos, &tmp );
if (tmp.nOffset) run_split( editor, &tmp );
- this_para = &tmp.pPara->member.para;
+ this_para = tmp.para;
bFixRowStart = this_para->nFlags & MEPF_ROWSTART;
if (bFixRowStart)
{
@@ -391,7 +391,7 @@ static void ME_PlayUndoItem(ME_TextEditor *editor, struct undo_item *undo)
* is correct. */
this_para->nFlags &= ~MEPF_ROWSTART;
}
- new_para = para_split( editor, &tmp.pRun->member.run, tmp.pRun->member.run.style,
+ new_para = para_split( editor, tmp.run, tmp.run->style,
undo->u.split_para.eol_str->szData, undo->u.split_para.eol_str->nLen, paraFlags );
if (bFixRowStart)
new_para->nFlags |= MEPF_ROWSTART;
diff --git a/dlls/riched20/wrap.c b/dlls/riched20/wrap.c
index 5fc20dbf83b..0ca70b8a8ad 100644
--- a/dlls/riched20/wrap.c
+++ b/dlls/riched20/wrap.c
@@ -131,7 +131,7 @@ static ME_Run *split_run_extents( ME_WrapContext *wc, ME_Run *run, int nVChar )
{
ME_TextEditor *editor = wc->context->editor;
ME_Run *run2;
- ME_Cursor cursor = {para_get_di( wc->para ), run_get_di( run ), nVChar};
+ ME_Cursor cursor = { wc->para, run, nVChar };
assert( run->nCharOfs != -1 );
ME_CheckCharOffsets(editor);
@@ -141,7 +141,7 @@ static ME_Run *split_run_extents( ME_WrapContext *wc, ME_Run *run, int nVChar )
run_split( editor, &cursor );
- run2 = &cursor.pRun->member.run;
+ run2 = cursor.run;
run2->script_analysis = run->script_analysis;
shape_run( wc->context, run );
@@ -157,7 +157,7 @@ static ME_Run *split_run_extents( ME_WrapContext *wc, ME_Run *run, int nVChar )
debugstr_run( run ), run->pt.x, run->pt.y,
debugstr_run( run2 ), run2->pt.x, run2->pt.y);
- return &cursor.pRun->member.run;
+ return cursor.run;
}
/******************************************************************************
@@ -777,7 +777,7 @@ static HRESULT itemize_para( ME_Context *c, ME_Paragraph *para )
if (run->nCharOfs + run->len > items[cur_item+1].iCharPos)
{
- ME_Cursor cursor = {para_get_di( para ), run_get_di( run ), items[cur_item+1].iCharPos - run->nCharOfs};
+ ME_Cursor cursor = { para, run, items[cur_item + 1].iCharPos - run->nCharOfs };
run_split( c->editor, &cursor );
}
}
diff --git a/dlls/riched20/writer.c b/dlls/riched20/writer.c
index 1fc2bfad51e..49cbb0e021f 100644
--- a/dlls/riched20/writer.c
+++ b/dlls/riched20/writer.c
@@ -1003,7 +1003,7 @@ static BOOL ME_StreamOutRTF(ME_TextEditor *editor, ME_OutStream *pStream,
if (!ME_StreamOutRTFHeader(pStream, dwFormat))
return FALSE;
- if (!stream_out_font_and_colour_tbls( pStream, &cursor.pRun->member.run, &endCur.pRun->member.run ))
+ if (!stream_out_font_and_colour_tbls( pStream, cursor.run, endCur.run ))
return FALSE;
/* TODO: stylesheet table */
@@ -1021,29 +1021,29 @@ static BOOL ME_StreamOutRTF(ME_TextEditor *editor, ME_OutStream *pStream,
do
{
- if (&cursor.pPara->member.para != prev_para)
+ if (cursor.para != prev_para)
{
- prev_para = &cursor.pPara->member.para;
- if (!stream_out_para_props( editor, pStream, &cursor.pPara->member.para ))
+ prev_para = cursor.para;
+ if (!stream_out_para_props( editor, pStream, cursor.para ))
return FALSE;
}
- if (cursor.pRun == endCur.pRun && !endCur.nOffset)
+ if (cursor.run == endCur.run && !endCur.nOffset)
break;
- TRACE("flags %xh\n", cursor.pRun->member.run.nFlags);
+ TRACE("flags %xh\n", cursor.run->nFlags);
/* TODO: emit embedded objects */
- if (cursor.pPara->member.para.nFlags & (MEPF_ROWSTART | MEPF_ROWEND))
+ if (cursor.para->nFlags & (MEPF_ROWSTART | MEPF_ROWEND))
continue;
- if (cursor.pRun->member.run.nFlags & MERF_GRAPHICS)
+ if (cursor.run->nFlags & MERF_GRAPHICS)
{
- if (!stream_out_graphics(editor, pStream, &cursor.pRun->member.run))
+ if (!stream_out_graphics( editor, pStream, cursor.run ))
return FALSE;
}
- else if (cursor.pRun->member.run.nFlags & MERF_TAB)
+ else if (cursor.run->nFlags & MERF_TAB)
{
if (editor->bEmulateVersion10 && /* v1.0 - 3.0 */
- para_in_table( &cursor.pPara->member.para ))
+ para_in_table( cursor.para ))
{
if (!ME_StreamOutPrint(pStream, "\\cell "))
return FALSE;
@@ -1054,7 +1054,7 @@ static BOOL ME_StreamOutRTF(ME_TextEditor *editor, ME_OutStream *pStream,
return FALSE;
}
}
- else if (cursor.pRun->member.run.nFlags & MERF_ENDCELL)
+ else if (cursor.run->nFlags & MERF_ENDCELL)
{
if (pStream->nNestingLevel > 1)
{
@@ -1068,13 +1068,13 @@ static BOOL ME_StreamOutRTF(ME_TextEditor *editor, ME_OutStream *pStream,
}
nChars--;
}
- else if (cursor.pRun->member.run.nFlags & MERF_ENDPARA)
+ else if (cursor.run->nFlags & MERF_ENDPARA)
{
- if (!ME_StreamOutRTFCharProps(pStream, &cursor.pRun->member.run.style->fmt))
+ if (!ME_StreamOutRTFCharProps( pStream, &cursor.run->style->fmt ))
return FALSE;
- if (para_in_table( &cursor.pPara->member.para) &&
- !(cursor.pPara->member.para.nFlags & (MEPF_ROWSTART | MEPF_ROWEND | MEPF_CELL)))
+ if (para_in_table( cursor.para ) &&
+ !(cursor.para->nFlags & (MEPF_ROWSTART | MEPF_ROWEND | MEPF_CELL)))
{
if (!ME_StreamOutPrint(pStream, "\\row\r\n"))
return FALSE;
@@ -1085,9 +1085,9 @@ static BOOL ME_StreamOutRTF(ME_TextEditor *editor, ME_OutStream *pStream,
return FALSE;
}
/* Skip as many characters as required by current line break */
- nChars = max(0, nChars - cursor.pRun->member.run.len);
+ nChars = max(0, nChars - cursor.run->len);
}
- else if (cursor.pRun->member.run.nFlags & MERF_ENDROW)
+ else if (cursor.run->nFlags & MERF_ENDROW)
{
if (!ME_StreamOutPrint(pStream, "\\line\r\n"))
return FALSE;
@@ -1097,17 +1097,17 @@ static BOOL ME_StreamOutRTF(ME_TextEditor *editor, ME_OutStream *pStream,
{
int nEnd;
- TRACE("style %p\n", cursor.pRun->member.run.style);
- if (!ME_StreamOutRTFCharProps(pStream, &cursor.pRun->member.run.style->fmt))
+ TRACE("style %p\n", cursor.run->style);
+ if (!ME_StreamOutRTFCharProps( pStream, &cursor.run->style->fmt ))
return FALSE;
- nEnd = (cursor.pRun == endCur.pRun) ? endCur.nOffset : cursor.pRun->member.run.len;
- if (!ME_StreamOutRTFText(pStream, get_text( &cursor.pRun->member.run, cursor.nOffset ),
+ nEnd = (cursor.run == endCur.run) ? endCur.nOffset : cursor.run->len;
+ if (!ME_StreamOutRTFText(pStream, get_text( cursor.run, cursor.nOffset ),
nEnd - cursor.nOffset))
return FALSE;
cursor.nOffset = 0;
}
- } while (cursor.pRun != endCur.pRun && cursor_next_run( &cursor, TRUE ));
+ } while (cursor.run != endCur.run && cursor_next_run( &cursor, TRUE ));
if (!ME_StreamOutMove(pStream, "}\0", 2))
return FALSE;
@@ -1125,7 +1125,7 @@ static BOOL ME_StreamOutText(ME_TextEditor *editor, ME_OutStream *pStream,
int nBufLen = 0;
BOOL success = TRUE;
- if (!cursor.pRun)
+ if (!cursor.run)
return FALSE;
if (dwFormat & SF_USECODEPAGE)
@@ -1133,10 +1133,11 @@ static BOOL ME_StreamOutText(ME_TextEditor *editor, ME_OutStream *pStream,
/* TODO: Handle SF_TEXTIZED */
- while (success && nChars && cursor.pRun) {
- nLen = min(nChars, cursor.pRun->member.run.len - cursor.nOffset);
+ while (success && nChars && cursor.run)
+ {
+ nLen = min(nChars, cursor.run->len - cursor.nOffset);
- if (!editor->bEmulateVersion10 && cursor.pRun->member.run.nFlags & MERF_ENDPARA)
+ if (!editor->bEmulateVersion10 && cursor.run->nFlags & MERF_ENDPARA)
{
static const WCHAR szEOL[] = { '\r', '\n' };
@@ -1147,18 +1148,18 @@ static BOOL ME_StreamOutText(ME_TextEditor *editor, ME_OutStream *pStream,
success = ME_StreamOutMove(pStream, "\r\n", 2);
} else {
if (dwFormat & SF_UNICODE)
- success = ME_StreamOutMove(pStream, (const char *)(get_text( &cursor.pRun->member.run, cursor.nOffset )),
+ success = ME_StreamOutMove(pStream, (const char *)(get_text( cursor.run, cursor.nOffset )),
sizeof(WCHAR) * nLen);
else {
int nSize;
- nSize = WideCharToMultiByte(nCodePage, 0, get_text( &cursor.pRun->member.run, cursor.nOffset ),
+ nSize = WideCharToMultiByte(nCodePage, 0, get_text( cursor.run, cursor.nOffset ),
nLen, NULL, 0, NULL, NULL);
if (nSize > nBufLen) {
buffer = heap_realloc(buffer, nSize);
nBufLen = nSize;
}
- WideCharToMultiByte(nCodePage, 0, get_text( &cursor.pRun->member.run, cursor.nOffset ),
+ WideCharToMultiByte(nCodePage, 0, get_text( cursor.run, cursor.nOffset ),
nLen, buffer, nSize, NULL, NULL);
success = ME_StreamOutMove(pStream, buffer, nSize);
}
@@ -1166,8 +1167,7 @@ static BOOL ME_StreamOutText(ME_TextEditor *editor, ME_OutStream *pStream,
nChars -= nLen;
cursor.nOffset = 0;
- cursor.pRun = run_next_all_paras( &cursor.pRun->member.run ) ?
- run_get_di( run_next_all_paras( &cursor.pRun->member.run ) ) : NULL;
+ cursor.run = run_next_all_paras( cursor.run );
}
heap_free(buffer);
--
2.23.0
1
0