Commit fb0ff053 authored by Alexandre Julliard's avatar Alexandre Julliard

Added internal Wine messages to perform SetWindowPos, ShowWindow and

SetParent in the correct thread. Replace QUEUE_IsExitingQueue by USER_IsExitingThread. Store window rectangles in the server. Prevent DestroyWindow on windows not belonging to the current thread.
parent 0d50965a
......@@ -43,7 +43,6 @@ const struct builtin_class_descr ICONTITLE_builtin_class =
*/
HWND ICONTITLE_Create( HWND owner )
{
WND* wndPtr;
HWND hWnd;
HINSTANCE instance = GetWindowLongA( owner, GWL_HINSTANCE );
LONG style = WS_CLIPSIBLINGS;
......@@ -57,10 +56,9 @@ HWND ICONTITLE_Create( HWND owner )
hWnd = CreateWindowExA( 0, ICONTITLE_CLASS_ATOM, NULL,
style, 0, 0, 1, 1,
owner, 0, instance, NULL );
if (!(wndPtr = WIN_GetPtr( hWnd ))) return 0;
wndPtr->owner = owner; /* MDI depends on this */
wndPtr->dwStyle &= ~(WS_CAPTION | WS_BORDER);
WIN_ReleasePtr(wndPtr);
WIN_SetOwner( hWnd, owner ); /* MDI depends on this */
SetWindowLongW( hWnd, GWL_STYLE,
GetWindowLongW( hWnd, GWL_STYLE ) & ~(WS_CAPTION | WS_BORDER) );
return hWnd;
}
......
......@@ -566,9 +566,36 @@ BOOL TTYDRV_SetWindowPos( WINDOWPOS *winpos )
/* Send WM_NCCALCSIZE message to get new client area */
if( (winpos->flags & (SWP_FRAMECHANGED | SWP_NOSIZE)) != SWP_NOSIZE )
{
WINPOS_SendNCCalcSize( winpos->hwnd, TRUE, &newWindowRect,
&wndPtr->rectWindow, &wndPtr->rectClient,
winpos, &newClientRect );
NCCALCSIZE_PARAMS params;
WINDOWPOS winposCopy;
params.rgrc[0] = newWindowRect;
params.rgrc[1] = wndPtr->rectWindow;
params.rgrc[2] = wndPtr->rectClient;
params.lppos = &winposCopy;
winposCopy = *winpos;
SendMessageW( winpos->hwnd, WM_NCCALCSIZE, TRUE, (LPARAM)&params );
TRACE( "%d,%d-%d,%d\n", params.rgrc[0].left, params.rgrc[0].top,
params.rgrc[0].right, params.rgrc[0].bottom );
/* If the application send back garbage, ignore it */
if (params.rgrc[0].left <= params.rgrc[0].right &&
params.rgrc[0].top <= params.rgrc[0].bottom)
newClientRect = params.rgrc[0];
/* FIXME: WVR_ALIGNxxx */
if( newClientRect.left != wndPtr->rectClient.left ||
newClientRect.top != wndPtr->rectClient.top )
winpos->flags &= ~SWP_NOCLIENTMOVE;
if( (newClientRect.right - newClientRect.left !=
wndPtr->rectClient.right - wndPtr->rectClient.left) ||
(newClientRect.bottom - newClientRect.top !=
wndPtr->rectClient.bottom - wndPtr->rectClient.top) )
winpos->flags &= ~SWP_NOCLIENTSIZE;
}
if(!(winpos->flags & SWP_NOZORDER) && winpos->hwnd != winpos->hwndInsertAfter)
......@@ -579,8 +606,7 @@ BOOL TTYDRV_SetWindowPos( WINDOWPOS *winpos )
/* FIXME: actually do something with WVR_VALIDRECTS */
wndPtr->rectWindow = newWindowRect;
wndPtr->rectClient = newClientRect;
WIN_SetRectangles( winpos->hwnd, &newWindowRect, &newClientRect );
if( winpos->flags & SWP_SHOWWINDOW )
{
......
......@@ -533,6 +533,10 @@ static size_t pack_message( HWND hwnd, UINT message, WPARAM wparam, LPARAM lpara
if (lparam) return sizeof(BOOL);
return 0;
case WM_WINE_SETWINDOWPOS:
push_data( data, (WINDOWPOS *)lparam, sizeof(WINDOWPOS) );
return 0;
/* these contain an HFONT */
case WM_SETFONT:
case WM_GETFONT:
......@@ -644,6 +648,7 @@ static BOOL unpack_message( HWND hwnd, UINT message, WPARAM *wparam, LPARAM *lpa
break;
case WM_WINDOWPOSCHANGING:
case WM_WINDOWPOSCHANGED:
case WM_WINE_SETWINDOWPOS:
minsize = sizeof(WINDOWPOS);
break;
case WM_COPYDATA:
......@@ -1073,6 +1078,30 @@ static void reply_message( struct received_message_info *info, LRESULT result, B
/***********************************************************************
* handle_internal_message
*
* Handle an internal Wine message instead of calling the window proc.
*/
static LRESULT handle_internal_message( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam )
{
switch(msg)
{
case WM_WINE_SETWINDOWPOS:
return USER_Driver.pSetWindowPos( (WINDOWPOS *)lparam );
case WM_WINE_SHOWWINDOW:
return USER_Driver.pShowWindow( hwnd, wparam );
case WM_WINE_DESTROYWINDOW:
return WIN_DestroyWindow( hwnd );
case WM_WINE_SETPARENT:
return (LRESULT)WIN_SetParent( hwnd, (HWND)wparam );
default:
FIXME( "unknown internal message %x\n", msg );
return 0;
}
}
/***********************************************************************
* call_window_proc
*
* Call a window procedure and the corresponding hooks.
......@@ -1082,7 +1111,7 @@ static LRESULT call_window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpar
LRESULT result;
WNDPROC winproc;
/* FIXME: should check for exiting queue */
if (msg & 0x80000000) return handle_internal_message( hwnd, msg, wparam, lparam );
/* first the WH_CALLWNDPROC hook */
if (HOOK_IsHooked( WH_CALLWNDPROC ))
......@@ -1308,8 +1337,6 @@ static BOOL put_message_in_queue( DWORD dest_tid, const struct send_message_info
unsigned int res;
int timeout = -1;
/* FIXME: should check for exiting queue */
if (info->type != MSG_NOTIFY &&
info->type != MSG_CALLBACK &&
info->type != MSG_POSTED &&
......@@ -1489,7 +1516,9 @@ LRESULT WINAPI SendMessageTimeoutW( HWND hwnd, UINT msg, WPARAM wparam, LPARAM l
SPY_EnterMessage( SPY_SENDMESSAGE, hwnd, msg, wparam, lparam );
dest_tid = GetWindowThreadProcessId( hwnd, &dest_pid );
if (!(dest_tid = GetWindowThreadProcessId( hwnd, &dest_pid ))) return 0;
if (USER_IsExitingThread( dest_tid )) return 0;
if (dest_tid == GetCurrentThreadId())
{
......@@ -1535,7 +1564,9 @@ LRESULT WINAPI SendMessageTimeoutA( HWND hwnd, UINT msg, WPARAM wparam, LPARAM l
SPY_EnterMessage( SPY_SENDMESSAGE, hwnd, msg, wparam, lparam );
dest_tid = GetWindowThreadProcessId( hwnd, &dest_pid );
if (!(dest_tid = GetWindowThreadProcessId( hwnd, &dest_pid ))) return 0;
if (USER_IsExitingThread( dest_tid )) return 0;
if (dest_tid == GetCurrentThreadId())
{
......@@ -1624,7 +1655,9 @@ BOOL WINAPI SendNotifyMessageW( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpara
return TRUE;
}
dest_tid = GetWindowThreadProcessId( hwnd, NULL );
if (!(dest_tid = GetWindowThreadProcessId( hwnd, NULL ))) return FALSE;
if (USER_IsExitingThread( dest_tid )) return TRUE;
if (dest_tid == GetCurrentThreadId())
{
......@@ -1676,7 +1709,9 @@ BOOL WINAPI SendMessageCallbackW( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpa
return TRUE;
}
dest_tid = GetWindowThreadProcessId( hwnd, NULL );
if (!(dest_tid = GetWindowThreadProcessId( hwnd, NULL ))) return FALSE;
if (USER_IsExitingThread( dest_tid )) return TRUE;
if (dest_tid == GetCurrentThreadId())
{
......@@ -1740,6 +1775,7 @@ BOOL WINAPI PostMessageA( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam )
BOOL WINAPI PostMessageW( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam )
{
struct send_message_info info;
DWORD dest_tid;
if (is_pointer_message( msg ))
{
......@@ -1758,7 +1794,11 @@ BOOL WINAPI PostMessageW( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam )
EnumWindows( broadcast_message_callback, (LPARAM)&info );
return TRUE;
}
return put_message_in_queue( GetWindowThreadProcessId( hwnd, NULL ), &info, NULL );
if (!(dest_tid = GetWindowThreadProcessId( hwnd, NULL ))) return FALSE;
if (USER_IsExitingThread( dest_tid )) return TRUE;
return put_message_in_queue( dest_tid, &info, NULL );
}
......@@ -1783,6 +1823,7 @@ BOOL WINAPI PostThreadMessageW( DWORD thread, UINT msg, WPARAM wparam, LPARAM lp
SetLastError( ERROR_INVALID_PARAMETER );
return FALSE;
}
if (USER_IsExitingThread( thread )) return TRUE;
info.type = MSG_POSTED;
info.hwnd = 0;
......
......@@ -34,8 +34,10 @@ WINE_LOOK TWEAK_WineLook = WIN31_LOOK;
WORD USER_HeapSel = 0; /* USER heap selector */
static HMODULE graphics_driver;
static DWORD exiting_thread_id;
extern void COMM_Init(void);
extern void WDML_NotifyThreadDetach(void);
#define GET_USER_FUNC(name) USER_Driver.p##name = (void*)GetProcAddress( graphics_driver, #name )
......@@ -257,20 +259,29 @@ static BOOL process_attach(void)
/**********************************************************************
* thread
* USER_IsExitingThread
*/
BOOL USER_IsExitingThread( DWORD tid )
{
return (tid == exiting_thread_id);
}
/**********************************************************************
* thread_detach
*/
static void thread_detach(void)
{
HQUEUE16 hQueue = GetThreadQueue16( 0 );
extern void WDML_NotifyThreadDetach(void);
exiting_thread_id = GetCurrentThreadId();
WDML_NotifyThreadDetach();
if (hQueue)
{
TIMER_RemoveQueueTimers( hQueue );
HOOK_FreeQueueHooks();
QUEUE_SetExitingQueue( hQueue );
WIN_DestroyThreadWindows( GetDesktopWindow() );
QUEUE_DeleteMsgQueue();
}
......@@ -290,6 +301,7 @@ static void thread_detach(void)
CURSORICON_FreeModuleIcons( hModule );
}
}
exiting_thread_id = 0;
}
......
......@@ -872,7 +872,7 @@ BOOL X11DRV_CreateWindow( HWND hwnd, CREATESTRUCTA *cs, BOOL unicode )
rect = wndPtr->rectWindow;
SendMessageW( hwnd, WM_NCCALCSIZE, FALSE, (LPARAM)&rect );
if (rect.left > rect.right || rect.top > rect.bottom) rect = wndPtr->rectWindow;
wndPtr->rectClient = rect;
WIN_SetRectangles( hwnd, &wndPtr->rectWindow, &rect );
X11DRV_sync_client_window_position( display, wndPtr );
X11DRV_register_window( display, hwnd, data );
......@@ -1005,18 +1005,14 @@ HWND X11DRV_SetParent( HWND hwnd, HWND parent )
{
Display *display = thread_display();
WND *wndPtr;
DWORD dwStyle;
HWND retvalue;
if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
dwStyle = wndPtr->dwStyle;
if (!parent) parent = GetDesktopWindow();
/* Windows hides the window first, then shows it again
* including the WM_SHOWWINDOW messages and all */
if (dwStyle & WS_VISIBLE) ShowWindow( hwnd, SW_HIDE );
BOOL was_visible = ShowWindow( hwnd, SW_HIDE );
if (!IsWindow( parent )) return 0;
if (!(wndPtr = WIN_GetPtr(hwnd)) || wndPtr == WND_OTHER_PROCESS) return 0;
retvalue = wndPtr->parent; /* old parent */
if (parent != retvalue)
......@@ -1027,7 +1023,7 @@ HWND X11DRV_SetParent( HWND hwnd, HWND parent )
if (parent != GetDesktopWindow()) /* a child window */
{
if (!(dwStyle & WS_CHILD))
if (!(wndPtr->dwStyle & WS_CHILD))
{
HMENU menu = (HMENU)SetWindowLongW( hwnd, GWL_ID, 0 );
if (menu) DestroyMenu( menu );
......@@ -1041,15 +1037,14 @@ HWND X11DRV_SetParent( HWND hwnd, HWND parent )
data->whole_rect.left, data->whole_rect.top );
wine_tsx11_unlock();
}
WIN_ReleaseWndPtr( wndPtr );
WIN_ReleasePtr( wndPtr );
/* SetParent additionally needs to make hwnd the topmost window
in the x-order and send the expected WM_WINDOWPOSCHANGING and
WM_WINDOWPOSCHANGED notification messages.
*/
SetWindowPos( hwnd, HWND_TOPMOST, 0, 0, 0, 0,
SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOSIZE|
((dwStyle & WS_VISIBLE)?SWP_SHOWWINDOW:0));
SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | (was_visible ? SWP_SHOWWINDOW : 0) );
/* FIXME: a WM_MOVE is also generated (in the DefWindowProc handler
* for WM_WINDOWPOSCHANGED) in Windows, should probably remove SWP_NOMOVE */
......
......@@ -69,8 +69,6 @@ HWND PERQDATA_SetCaptureWnd( HWND hWndCapture, INT hittest );
extern MESSAGEQUEUE *QUEUE_Current(void);
extern MESSAGEQUEUE *QUEUE_Lock( HQUEUE16 hQueue );
extern void QUEUE_Unlock( MESSAGEQUEUE *queue );
extern BOOL QUEUE_IsExitingQueue( HQUEUE16 hQueue );
extern void QUEUE_SetExitingQueue( HQUEUE16 hQueue );
extern void QUEUE_DeleteMsgQueue(void);
#endif /* __WINE_QUEUE_H */
......@@ -35,7 +35,14 @@ struct DIDEVICEOBJECTDATA;
typedef VOID CALLBACK (*LPMOUSE_EVENT_PROC)(DWORD,DWORD,DWORD,DWORD,DWORD);
struct tagWND;
/* internal messages codes */
enum wine_internal_message
{
WM_WINE_DESTROYWINDOW = 0x80000000,
WM_WINE_SETWINDOWPOS,
WM_WINE_SHOWWINDOW,
WM_WINE_SETPARENT
};
typedef struct tagUSER_DRIVER {
/* keyboard functions */
......@@ -99,6 +106,8 @@ extern void USER_Lock(void);
extern void USER_Unlock(void);
extern void USER_CheckNotLock(void);
extern BOOL USER_IsExitingThread( DWORD tid );
VOID WINAPI MOUSE_Enable(LPMOUSE_EVENT_PROC lpMouseEventProc);
VOID WINAPI MOUSE_Disable(VOID);
......
......@@ -88,12 +88,16 @@ extern HWND WIN_IsCurrentProcess( HWND hwnd );
extern HWND WIN_IsCurrentThread( HWND hwnd );
extern void WIN_LinkWindow( HWND hwnd, HWND parent, HWND hwndInsertAfter );
extern void WIN_UnlinkWindow( HWND hwnd );
extern void WIN_SetOwner( HWND hwnd, HWND owner );
extern void WIN_SetRectangles( HWND hwnd, const RECT *rectWindow, const RECT *rectClient );
extern HWND WIN_FindWinToRepaint( HWND hwnd );
extern LRESULT WIN_DestroyWindow( HWND hwnd );
extern void WIN_DestroyThreadWindows( HWND hwnd );
extern BOOL WIN_CreateDesktopWindow(void);
extern BOOL WIN_IsWindowDrawable( HWND hwnd, BOOL );
extern HWND *WIN_ListParents( HWND hwnd );
extern HWND *WIN_ListChildren( HWND hwnd );
extern HWND WIN_SetParent( HWND hwnd, HWND parent );
extern BOOL WIN_InternalShowOwnedPopups( HWND owner, BOOL fShow, BOOL unmanagedOnly );
inline static HWND WIN_GetFullHandle( HWND hwnd )
......
......@@ -28,10 +28,6 @@ extern void WINPOS_GetMinMaxInfo( HWND hwnd, POINT *maxSize, POINT *maxPos, POIN
extern BOOL WINPOS_SetActiveWindow( HWND hWnd, BOOL fMouse,
BOOL fChangeFocus );
extern BOOL WINPOS_ChangeActiveWindow( HWND hwnd, BOOL mouseMsg );
extern LONG WINPOS_SendNCCalcSize(HWND hwnd, BOOL calcValidRect,
RECT *newWindowRect, RECT *oldWindowRect,
RECT *oldClientRect, WINDOWPOS *winpos,
RECT *newClientRect );
extern LONG WINPOS_HandleWindowPosChanging16(HWND hwnd, struct tagWINDOWPOS16 *winpos);
extern LONG WINPOS_HandleWindowPosChanging(HWND hwnd, WINDOWPOS *winpos);
extern HWND WINPOS_WindowFromPoint( HWND hwndScope, POINT pt, INT *hittest );
......
......@@ -144,11 +144,9 @@ DCE* DCE_FreeDCE( DCE *dce )
void DCE_FreeWindowDCE( HWND hwnd )
{
DCE *pDCE;
WND *pWnd = WIN_FindWndPtr( hwnd );
WND *pWnd = WIN_GetPtr( hwnd );
pDCE = firstDCE;
hwnd = pWnd->hwndSelf; /* make it a full handle */
while( pDCE )
{
if( pDCE->hwndCurrent == hwnd )
......@@ -189,8 +187,7 @@ void DCE_FreeWindowDCE( HWND hwnd )
}
pDCE = pDCE->next;
}
WIN_ReleaseWndPtr( pWnd );
WIN_ReleasePtr( pWnd );
}
......@@ -359,14 +356,19 @@ HDC WINAPI GetDCEx( HWND hwnd, HRGN hrgnClip, DWORD flags )
DWORD dcxFlags = 0;
BOOL bUpdateVisRgn = TRUE;
BOOL bUpdateClipOrigin = FALSE;
HWND parent;
HWND parent, full;
TRACE("hwnd %04x, hrgnClip %04x, flags %08x\n",
hwnd, hrgnClip, (unsigned)flags);
if (!hwnd) hwnd = GetDesktopWindow();
if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
hwnd = wndPtr->hwndSelf; /* make it a full handle */
if (!(full = WIN_IsCurrentProcess( hwnd )) && full != GetDesktopWindow())
{
FIXME( "not supported yet on other process window %x\n", full );
return 0;
}
hwnd = full;
if (!(wndPtr = WIN_GetPtr( hwnd ))) return 0;
/* fixup flags */
......@@ -494,7 +496,7 @@ HDC WINAPI GetDCEx( HWND hwnd, HRGN hrgnClip, DWORD flags )
TRACE("(%04x,%04x,0x%lx): returning %04x\n", hwnd, hrgnClip, flags, hdc);
END:
WIN_ReleaseWndPtr(wndPtr);
WIN_ReleasePtr(wndPtr);
return hdc;
}
......
......@@ -306,11 +306,20 @@ HDC WINAPI BeginPaint( HWND hwnd, PAINTSTRUCT *lps )
BOOL bIcon;
HRGN hrgnUpdate;
RECT clipRect, clientRect;
WND *wndPtr = WIN_FindWndPtr( hwnd );
if (!wndPtr) return 0;
HWND full_handle;
WND *wndPtr;
bIcon = (wndPtr->dwStyle & WS_MINIMIZE && GetClassLongA(hwnd, GCL_HICON));
if (!(full_handle = WIN_IsCurrentThread( hwnd )))
{
if (IsWindow(hwnd))
FIXME( "window %x belongs to other thread\n", hwnd );
return 0;
}
hwnd = full_handle;
bIcon = (IsIconic(hwnd) && GetClassLongA(hwnd, GCL_HICON));
if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
wndPtr->flags &= ~WIN_NEEDS_BEGINPAINT;
/* send WM_NCPAINT and make sure hrgnUpdate is a valid rgn handle */
......@@ -320,7 +329,7 @@ HDC WINAPI BeginPaint( HWND hwnd, PAINTSTRUCT *lps )
* Make sure the window is still a window. All window locks are suspended
* when the WM_NCPAINT is sent.
*/
if (!IsWindow(wndPtr->hwndSelf))
if (!IsWindow( hwnd ))
{
WIN_ReleaseWndPtr(wndPtr);
return 0;
......@@ -336,7 +345,7 @@ HDC WINAPI BeginPaint( HWND hwnd, PAINTSTRUCT *lps )
TRACE("hrgnUpdate = %04x, \n", hrgnUpdate);
if (GetClassLongA(wndPtr->hwndSelf, GCL_STYLE) & CS_PARENTDC)
if (GetClassLongA( hwnd, GCL_STYLE ) & CS_PARENTDC)
{
/* Don't clip the output to the update region for CS_PARENTDC window */
if( hrgnUpdate )
......
......@@ -24,7 +24,6 @@
DEFAULT_DEBUG_CHANNEL(msg);
static HQUEUE16 hExitingQueue = 0;
static PERQUEUEDATA *pQDataWin16 = NULL; /* Global perQData for Win16 tasks */
HQUEUE16 hActiveQueue = 0;
......@@ -325,24 +324,6 @@ void QUEUE_Unlock( MESSAGEQUEUE *queue )
/***********************************************************************
* QUEUE_IsExitingQueue
*/
BOOL QUEUE_IsExitingQueue( HQUEUE16 hQueue )
{
return (hExitingQueue && (hQueue == hExitingQueue));
}
/***********************************************************************
* QUEUE_SetExitingQueue
*/
void QUEUE_SetExitingQueue( HQUEUE16 hQueue )
{
hExitingQueue = hQueue;
}
/***********************************************************************
* QUEUE_CreateMsgQueue
*
* Creates a message queue. Doesn't link it into queue list!
......@@ -417,7 +398,6 @@ void QUEUE_DeleteMsgQueue(void)
msgQueue->magic = 0;
if( hActiveQueue == hQueue ) hActiveQueue = 0;
if (hExitingQueue == hQueue) hExitingQueue = 0;
HeapLock( GetProcessHeap() ); /* FIXME: a bit overkill */
......
......@@ -1200,7 +1200,6 @@ static void EVENT_DropFromOffiX( HWND hWnd, XClientMessageEvent *event )
LPDRAGINFO16 lpDragInfo = (LPDRAGINFO16) GlobalLock16(hDragInfo);
SEGPTR spDragInfo = K32WOWGlobalLock16(hDragInfo);
Window w_aux_root, w_aux_child;
WND* pDropWnd;
WND* pWnd;
if( !lpDragInfo || !spDragInfo ) return;
......@@ -1224,76 +1223,73 @@ static void EVENT_DropFromOffiX( HWND hWnd, XClientMessageEvent *event )
bAccept = DRAG_QueryUpdate( hWnd, spDragInfo, TRUE );
x = lpDragInfo->pt.x; y = lpDragInfo->pt.y;
}
pDropWnd = WIN_FindWndPtr( lpDragInfo->hScope );
WIN_ReleaseWndPtr(pWnd);
GlobalFree16( hDragInfo );
if( bAccept )
if (!bAccept) return;
TSXGetWindowProperty( event->display, DefaultRootWindow(event->display),
dndSelection, 0, 65535, FALSE,
AnyPropertyType, &u.atom_aux, (int *) &u.pt_aux.y,
&data_length, &aux_long, &p_data);
if( !aux_long && p_data) /* don't bother if > 64K */
{
TSXGetWindowProperty( event->display, DefaultRootWindow(event->display),
dndSelection, 0, 65535, FALSE,
AnyPropertyType, &u.atom_aux, (int *) &u.pt_aux.y,
&data_length, &aux_long, &p_data);
if( !aux_long && p_data) /* don't bother if > 64K */
{
signed char *p = (signed char*) p_data;
char *p_drop;
aux_long = 0;
while( *p ) /* calculate buffer size */
{
p_drop = p;
if((u.i = *p) != -1 )
{
INT len = GetShortPathNameA( p, NULL, 0 );
if (len) aux_long += len + 1;
else *p = -1;
}
p += strlen(p) + 1;
}
if( aux_long && aux_long < 65535 )
{
HDROP hDrop;
DROPFILES *lpDrop;
aux_long += sizeof(DROPFILES) + 1;
hDrop = GlobalAlloc( GMEM_SHARE, aux_long );
lpDrop = (DROPFILES*)GlobalLock( hDrop );
if( lpDrop )
{
lpDrop->pFiles = sizeof(DROPFILES);
lpDrop->pt.x = x;
lpDrop->pt.y = y;
lpDrop->fNC =
( x < (pDropWnd->rectClient.left - pDropWnd->rectWindow.left) ||
y < (pDropWnd->rectClient.top - pDropWnd->rectWindow.top) ||
x > (pDropWnd->rectClient.right - pDropWnd->rectWindow.left) ||
y > (pDropWnd->rectClient.bottom - pDropWnd->rectWindow.top) );
lpDrop->fWide = FALSE;
p_drop = (char *)(lpDrop + 1);
p = p_data;
while(*p)
{
if( *p != -1 ) /* use only "good" entries */
{
GetShortPathNameA( p, p_drop, 65535 );
p_drop += strlen( p_drop ) + 1;
}
p += strlen(p) + 1;
}
*p_drop = '\0';
PostMessageA( hWnd, WM_DROPFILES, (WPARAM)hDrop, 0L );
}
}
}
if( p_data ) TSXFree(p_data);
} /* WS_EX_ACCEPTFILES */
signed char *p = (signed char*) p_data;
char *p_drop;
WIN_ReleaseWndPtr(pDropWnd);
aux_long = 0;
while( *p ) /* calculate buffer size */
{
p_drop = p;
if((u.i = *p) != -1 )
{
INT len = GetShortPathNameA( p, NULL, 0 );
if (len) aux_long += len + 1;
else *p = -1;
}
p += strlen(p) + 1;
}
if( aux_long && aux_long < 65535 )
{
HDROP hDrop;
DROPFILES *lpDrop;
aux_long += sizeof(DROPFILES) + 1;
hDrop = GlobalAlloc( GMEM_SHARE, aux_long );
lpDrop = (DROPFILES*)GlobalLock( hDrop );
if( lpDrop )
{
WND *pDropWnd = WIN_FindWndPtr( lpDragInfo->hScope );
lpDrop->pFiles = sizeof(DROPFILES);
lpDrop->pt.x = x;
lpDrop->pt.y = y;
lpDrop->fNC =
( x < (pDropWnd->rectClient.left - pDropWnd->rectWindow.left) ||
y < (pDropWnd->rectClient.top - pDropWnd->rectWindow.top) ||
x > (pDropWnd->rectClient.right - pDropWnd->rectWindow.left) ||
y > (pDropWnd->rectClient.bottom - pDropWnd->rectWindow.top) );
lpDrop->fWide = FALSE;
WIN_ReleaseWndPtr(pDropWnd);
p_drop = (char *)(lpDrop + 1);
p = p_data;
while(*p)
{
if( *p != -1 ) /* use only "good" entries */
{
GetShortPathNameA( p, p_drop, 65535 );
p_drop += strlen( p_drop ) + 1;
}
p += strlen(p) + 1;
}
*p_drop = '\0';
PostMessageA( hWnd, WM_DROPFILES, (WPARAM)hDrop, 0L );
}
}
}
if( p_data ) TSXFree(p_data);
}
/**********************************************************************
......@@ -1306,8 +1302,6 @@ static void EVENT_DropFromOffiX( HWND hWnd, XClientMessageEvent *event )
*/
static void EVENT_DropURLs( HWND hWnd, XClientMessageEvent *event )
{
WND *pDropWnd;
WND *pWnd;
unsigned long data_length;
unsigned long aux_long, drop_len = 0;
unsigned char *p_data = NULL; /* property data */
......@@ -1322,14 +1316,7 @@ static void EVENT_DropURLs( HWND hWnd, XClientMessageEvent *event )
Window w_aux;
} u; /* unused */
pWnd = WIN_FindWndPtr(hWnd);
if (!(pWnd->dwExStyle & WS_EX_ACCEPTFILES))
{
WIN_ReleaseWndPtr(pWnd);
return;
}
WIN_ReleaseWndPtr(pWnd);
if (!(GetWindowLongW( hWnd, GWL_EXSTYLE ) & WS_EX_ACCEPTFILES)) return;
TSXGetWindowProperty( event->display, DefaultRootWindow(event->display),
dndSelection, 0, 65535, FALSE,
......@@ -1362,13 +1349,12 @@ static void EVENT_DropURLs( HWND hWnd, XClientMessageEvent *event )
TSXQueryPointer( event->display, root_window, &u.w_aux, &u.w_aux,
&x, &y, &u.i, &u.i, &u.i);
pDropWnd = WIN_FindWndPtr( hWnd );
drop_len += sizeof(DROPFILES) + 1;
hDrop = GlobalAlloc( GMEM_SHARE, drop_len );
lpDrop = (DROPFILES *) GlobalLock( hDrop );
if( lpDrop ) {
WND *pDropWnd = WIN_FindWndPtr( hWnd );
lpDrop->pFiles = sizeof(DROPFILES);
lpDrop->pt.x = (INT)x;
lpDrop->pt.y = (INT)y;
......@@ -1379,6 +1365,7 @@ static void EVENT_DropURLs( HWND hWnd, XClientMessageEvent *event )
y > (pDropWnd->rectClient.bottom - pDropWnd->rectWindow.top) );
lpDrop->fWide = FALSE;
p_drop = (char*)(lpDrop + 1);
WIN_ReleaseWndPtr(pDropWnd);
}
/* create message content */
......@@ -1411,7 +1398,6 @@ static void EVENT_DropURLs( HWND hWnd, XClientMessageEvent *event )
GlobalUnlock(hDrop);
PostMessageA( hWnd, WM_DROPFILES, (WPARAM)hDrop, 0L );
}
WIN_ReleaseWndPtr(pDropWnd);
}
if( p_data ) TSXFree(p_data);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment