Commit b2df5f9f authored by Ulrich Czekalla's avatar Ulrich Czekalla Committed by Alexandre Julliard

- use global atoms for the format ids

- add timeout when calling XCheckTypedWindowEvent - fix broken IsClipboardFormatAvailable; it tried to do a trick with EnumClipboardFormats by making incorrect assumptions - in X11DRV_IsClipboardFormatAvailable do a quick exit if no one owns the selection - add 1 second *minimum* time lapse between XSelectionOwner calls - sync clipboard ownership between different wine processes - prevents apps from getting into wierd state where they thought they didn't own the selection but they did and as a result queried themselves for available selection data
parent a3c10cf1
......@@ -715,12 +715,6 @@
################################################################
# Wine dll separation hacks, these will go away, don't use them
#
@ cdecl CLIPBOARD_DeleteRecord(ptr long)
@ cdecl CLIPBOARD_EmptyCache(long)
@ cdecl CLIPBOARD_GetFormatName(long ptr long)
@ cdecl CLIPBOARD_IsPresent(long)
@ cdecl CLIPBOARD_LookupFormat(long)
@ cdecl CLIPBOARD_ReleaseOwner()
@ cdecl DCE_InvalidateDCE(long ptr)
@ cdecl HOOK_CallHooks(long long long long long)
@ cdecl NC_GetInsideRect(long ptr)
......
......@@ -89,13 +89,15 @@ static BOOL load_driver(void)
GET_USER_FUNC(GetScreenSaveActive);
GET_USER_FUNC(SetScreenSaveActive);
GET_USER_FUNC(AcquireClipboard);
GET_USER_FUNC(ReleaseClipboard);
GET_USER_FUNC(EmptyClipboard);
GET_USER_FUNC(SetClipboardData);
GET_USER_FUNC(GetClipboardData);
GET_USER_FUNC(CountClipboardFormats);
GET_USER_FUNC(EnumClipboardFormats);
GET_USER_FUNC(IsClipboardFormatAvailable);
GET_USER_FUNC(RegisterClipboardFormat);
GET_USER_FUNC(GetClipboardFormatName);
GET_USER_FUNC(IsSelectionOwner);
GET_USER_FUNC(EndClipboardUpdate);
GET_USER_FUNC(ResetSelectionOwner);
GET_USER_FUNC(ChangeDisplaySettingsExW);
GET_USER_FUNC(EnumDisplaySettingsExW);
......
......@@ -373,15 +373,59 @@ extern Atom _kde_net_wm_system_tray_window_for;
/* X11 clipboard driver */
extern void X11DRV_CLIPBOARD_FreeResources( Atom property );
extern BOOL X11DRV_CLIPBOARD_RegisterPixmapResource( Atom property, Pixmap pixmap );
extern BOOL X11DRV_CLIPBOARD_IsNativeProperty(Atom prop);
extern UINT X11DRV_CLIPBOARD_MapPropertyToFormat(char *itemFmtName);
extern Atom X11DRV_CLIPBOARD_MapFormatToProperty(UINT id);
typedef struct tagPROPERTYFORMATMAP
{
LPCSTR lpszProperty;
LPCSTR lpszFormat;
} PROPERTYFORMATMAP;
typedef struct tagPROPERTYALIASMAP
{
LPCSTR lpszProperty;
UINT drvDataProperty;
LPCSTR lpszAlias;
UINT drvDataAlias;
} PROPERTYALIASMAP;
typedef struct tagWINE_CLIPDATA {
UINT wFormatID;
HANDLE16 hData16;
HANDLE hData32;
UINT wFlags;
struct tagWINE_CLIPDATA *PrevData;
struct tagWINE_CLIPDATA *NextData;
} WINE_CLIPDATA, *LPWINE_CLIPDATA;
typedef HANDLE (*DRVEXPORTFUNC)(LPWINE_CLIPDATA lpData, LPDWORD lpBytes);
typedef HANDLE (*DRVIMPORTFUNC)(LPBYTE hData, UINT cBytes);
typedef struct tagWINE_CLIPFORMAT {
UINT wFormatID;
LPSTR Name;
UINT drvData;
UINT wFlags;
DRVIMPORTFUNC lpDrvImportFunc;
DRVEXPORTFUNC lpDrvExportFunc;
struct tagWINE_CLIPFORMAT *PrevFormat;
struct tagWINE_CLIPFORMAT *NextFormat;
} WINE_CLIPFORMAT, *LPWINE_CLIPFORMAT;
#define CF_FLAG_BUILTINFMT 1 /* Built-in windows format */
#define CF_FLAG_SYNTHESIZED 8 /* Implicitly converted data */
extern Atom xaClipboard;
extern Atom xaTargets;
extern Atom xaMultiple;
extern BOOL X11DRV_InitClipboard(Display *display);
extern void X11DRV_CLIPBOARD_ReleaseSelection(Atom selType, Window w, HWND hwnd);
extern BOOL X11DRV_IsSelectionOwner(void);
extern BOOL X11DRV_GetClipboardData(UINT wFormat);
extern HANDLE X11DRV_CLIPBOARD_SerializeMetafile(INT wformat, HANDLE hdata, INT cbytes, BOOL out);
extern INT X11DRV_CountClipboardFormats(void);
extern UINT X11DRV_EnumClipboardFormats(UINT wFormat);
extern LPWINE_CLIPFORMAT X11DRV_CLIPBOARD_LookupFormat(WORD wID);
extern LPWINE_CLIPFORMAT X11DRV_CLIPBOARD_LookupProperty(UINT drvData);
extern LPWINE_CLIPDATA X11DRV_CLIPBOARD_LookupData(DWORD wID);
extern UINT X11DRV_CLIPBOARD_LookupPropertyAlias(UINT drvDataProperty);
extern LPWINE_CLIPFORMAT X11DRV_CLIPBOARD_LookupAliasProperty(UINT drvDataAlias);
/* X11 event driver */
......
......@@ -74,32 +74,34 @@
@ cdecl SetScreenSaveActive(long) X11DRV_SetScreenSaveActive
@ cdecl ChangeDisplaySettingsExW (ptr ptr long long long) X11DRV_ChangeDisplaySettingsExW
@ cdecl EnumDisplaySettingsExW (ptr long ptr long) X11DRV_EnumDisplaySettingsExW
@ cdecl AcquireClipboard() X11DRV_AcquireClipboard
@ cdecl CountClipboardFormats() X11DRV_CountClipboardFormats
@ cdecl CreateWindow(long ptr long) X11DRV_CreateWindow
@ cdecl DestroyWindow(long) X11DRV_DestroyWindow
@ cdecl GetDC(long long long long) X11DRV_GetDC
@ cdecl EmptyClipboard() X11DRV_EmptyClipboard
@ cdecl EndClipboardUpdate(long) X11DRV_EndClipboardUpdate
@ cdecl EnumClipboardFormats(long) X11DRV_EnumClipboardFormats
@ cdecl ForceWindowRaise(long) X11DRV_ForceWindowRaise
@ cdecl GetClipboardData(long ptr ptr) X11DRV_GetClipboardData
@ cdecl GetClipboardFormatName(long str long) X11DRV_GetClipboardFormatName
@ cdecl GetDC(long long long long) X11DRV_GetDC
@ cdecl IsClipboardFormatAvailable(long) X11DRV_IsClipboardFormatAvailable
@ cdecl MsgWaitForMultipleObjectsEx(long ptr long long long) X11DRV_MsgWaitForMultipleObjectsEx
@ cdecl RegisterClipboardFormat(str) X11DRV_RegisterClipboardFormat
@ cdecl ReleaseDC(long long) X11DRV_ReleaseDC
@ cdecl ResetSelectionOwner(long long) X11DRV_ResetSelectionOwner
@ cdecl ScrollDC(long long long ptr ptr long ptr) X11DRV_ScrollDC
@ cdecl ScrollWindowEx(long long long ptr ptr long ptr long) X11DRV_ScrollWindowEx
@ cdecl SetClipboardData(long long long) X11DRV_SetClipboardData
@ cdecl SetFocus(long) X11DRV_SetFocus
@ cdecl SetParent(long long) X11DRV_SetParent
@ cdecl SetWindowIcon(long long long) X11DRV_SetWindowIcon
@ cdecl SetWindowPos(ptr) X11DRV_SetWindowPos
@ cdecl SetWindowRgn(long long long) X11DRV_SetWindowRgn
@ cdecl SetWindowIcon(long long long) X11DRV_SetWindowIcon
@ cdecl SetWindowStyle(ptr long) X11DRV_SetWindowStyle
@ cdecl SetWindowText(long wstr) X11DRV_SetWindowText
@ cdecl ShowWindow(long long) X11DRV_ShowWindow
@ cdecl SysCommandSizeMove(long long) X11DRV_SysCommandSizeMove
@ cdecl AcquireClipboard() X11DRV_AcquireClipboard
@ cdecl ReleaseClipboard() X11DRV_ReleaseClipboard
@ cdecl SetClipboardData(long) X11DRV_SetClipboardData
@ cdecl GetClipboardData(long) X11DRV_GetClipboardData
@ cdecl IsClipboardFormatAvailable(long) X11DRV_IsClipboardFormatAvailable
@ cdecl RegisterClipboardFormat(str) X11DRV_RegisterClipboardFormat
@ cdecl GetClipboardFormatName(long str long) X11DRV_GetClipboardFormatName
@ cdecl IsSelectionOwner() X11DRV_IsSelectionOwner
@ cdecl ResetSelectionOwner(ptr long) X11DRV_ResetSelectionOwner
# X11 locks
@ cdecl -norelay wine_tsx11_lock()
......
......@@ -362,6 +362,13 @@ static void process_attach(void)
ExitProcess(1);
}
/* Initialize clipboard */
if (!X11DRV_InitClipboard( display ))
{
ERR( "Couldn't Initialize clipboard.\n" );
ExitProcess(1);
}
#ifdef HAVE_LIBXXF86VM
/* initialize XVidMode */
X11DRV_XF86VM_Init();
......
......@@ -2,6 +2,7 @@
* Copyright 1994 Martin Ayotte
* Copyright 1996 Alex Korobka
* Copyright 1999 Noel Borthwick
* Copyright 2003 Ulrich Czekalla for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
......@@ -22,29 +23,14 @@
#define __WINE_CLIPBOARD_H
#include "windef.h"
#include "wine/windef16.h"
struct tagWND;
typedef struct tagWINE_CLIPFORMAT {
UINT wFormatID;
UINT wRefCount;
BOOL wDataPresent;
LPSTR Name;
HANDLE16 hData16;
HANDLE hDataSrc32;
HANDLE hData32;
ULONG drvData;
struct tagWINE_CLIPFORMAT *PrevFormat;
struct tagWINE_CLIPFORMAT *NextFormat;
} WINE_CLIPFORMAT, *LPWINE_CLIPFORMAT;
extern LPWINE_CLIPFORMAT CLIPBOARD_LookupFormat( WORD wID );
extern BOOL CLIPBOARD_IsCacheRendered();
extern void CLIPBOARD_DeleteRecord(LPWINE_CLIPFORMAT lpFormat, BOOL bChange);
extern void CLIPBOARD_EmptyCache( BOOL bChange );
extern BOOL CLIPBOARD_IsPresent(WORD wFormat);
extern char * CLIPBOARD_GetFormatName(UINT wFormat, LPSTR buf, INT size);
extern void CLIPBOARD_ReleaseOwner();
typedef struct tagCLIPBOARDINFO
{
HWND hWndOpen;
HWND hWndOwner;
HWND hWndViewer;
UINT seqno;
UINT flags;
} CLIPBOARDINFO, *LPCLIPBOARDINFO;
#endif /* __WINE_CLIPBOARD_H */
......@@ -82,15 +82,17 @@ typedef struct tagUSER_DRIVER {
BOOL (*pGetScreenSaveActive)(void);
void (*pSetScreenSaveActive)(BOOL);
/* clipboard functions */
void (*pAcquireClipboard)(void); /* Acquire selection */
void (*pReleaseClipboard)(void); /* Release selection */
void (*pSetClipboardData)(UINT); /* Set specified selection data */
BOOL (*pGetClipboardData)(UINT); /* Get specified selection data */
BOOL (*pIsClipboardFormatAvailable)(UINT); /* Check if specified format is available */
INT (*pRegisterClipboardFormat)(LPCSTR); /* Register a clipboard format */
BOOL (*pGetClipboardFormatName)(UINT, LPSTR, UINT); /* Get a clipboard format name */
BOOL (*pIsSelectionOwner)(void); /* Check if we own the selection */
void (*pAcquireClipboard)(HWND); /* Acquire selection */
BOOL (*pCountClipboardFormats)(void); /* Count available clipboard formats */
void (*pEmptyClipboard)(void); /* Empty clipboard data */
BOOL (*pEndClipboardUpdate)(void); /* End clipboard update */
BOOL (*pEnumClipboardFormats)(UINT); /* Enumerate clipboard formats */
BOOL (*pGetClipboardData)(UINT, HANDLE16*, HANDLE*); /* Get specified selection data */
BOOL (*pGetClipboardFormatName)(UINT, LPSTR, UINT); /* Get a clipboard format name */
BOOL (*pIsClipboardFormatAvailable)(UINT); /* Check if specified format is available */
INT (*pRegisterClipboardFormat)(LPCSTR); /* Register a clipboard format */
void (*pResetSelectionOwner)(HWND, BOOL);
BOOL (*pSetClipboardData)(UINT, HANDLE16, HANDLE); /* Set specified selection data */
/* display modes */
LONG (*pChangeDisplaySettingsExW)(LPCWSTR,LPDEVMODEW,HWND,DWORD,LPVOID);
BOOL (*pEnumDisplaySettingsExW)(LPCWSTR,DWORD,LPDEVMODEW,DWORD);
......@@ -163,6 +165,8 @@ extern INT SYSPARAMS_GetMouseButtonSwap( void );
extern HPALETTE WINAPI SelectPalette( HDC hDC, HPALETTE hPal, BOOL bForceBackground );
extern BOOL CLIPBOARD_ReleaseOwner(void);
extern DWORD USER16_AlertableWait;
/* HANDLE16 <-> HANDLE conversions */
......
......@@ -3041,6 +3041,36 @@ struct get_next_hook_reply
};
struct set_clipboard_info_request
{
struct request_header __header;
unsigned int flags;
user_handle_t clipboard;
user_handle_t owner;
user_handle_t viewer;
unsigned int seqno;
};
struct set_clipboard_info_reply
{
struct reply_header __header;
unsigned int flags;
user_handle_t old_clipboard;
user_handle_t old_owner;
user_handle_t old_viewer;
unsigned int seqno;
};
#define SET_CB_OPEN 0x001
#define SET_CB_OWNER 0x002
#define SET_CB_VIEWER 0x004
#define SET_CB_SEQNO 0x008
#define SET_CB_RELOWNER 0x010
#define SET_CB_CLOSE 0x020
#define CB_OPEN 0x040
#define CB_OWNER 0x080
enum request
{
REQ_new_process,
......@@ -3218,6 +3248,7 @@ enum request
REQ_start_hook_chain,
REQ_finish_hook_chain,
REQ_get_next_hook,
REQ_set_clipboard_info,
REQ_NB_REQUESTS
};
......@@ -3400,6 +3431,7 @@ union generic_request
struct start_hook_chain_request start_hook_chain_request;
struct finish_hook_chain_request finish_hook_chain_request;
struct get_next_hook_request get_next_hook_request;
struct set_clipboard_info_request set_clipboard_info_request;
};
union generic_reply
{
......@@ -3580,8 +3612,9 @@ union generic_reply
struct start_hook_chain_reply start_hook_chain_reply;
struct finish_hook_chain_reply finish_hook_chain_reply;
struct get_next_hook_reply get_next_hook_reply;
struct set_clipboard_info_reply set_clipboard_info_reply;
};
#define SERVER_PROTOCOL_VERSION 111
#define SERVER_PROTOCOL_VERSION 112
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
......@@ -9,6 +9,7 @@ C_SRCS = \
async.c \
atom.c \
change.c \
clipboard.c \
console.c \
context_i386.c \
context_powerpc.c \
......
/*
* Server-side clipboard management
*
* Copyright (C) 2002 Ulrich Czekalla
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "config.h"
#include "wine/port.h"
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "request.h"
#include "object.h"
#include "user.h"
struct thread *cbthread; /* thread id that has clipboard open */
static user_handle_t clipboard; /* window that has clipboard open */
struct thread *cbowner; /* thread id that owns the clipboard */
static user_handle_t owner; /* window that owns the clipboard data */
static user_handle_t viewer; /* first window in clipboard viewer list */
static unsigned int seqno; /* clipboard change sequence number */
static time_t seqnots; /* time stamp of last seqno increment */
#define MINUPDATELAPSE 2
/* Called when thread terminates to allow release of clipboard */
void cleanup_clipboard_thread(struct thread *thread)
{
if (thread == cbthread)
{
clipboard = 0;
cbthread = NULL;
}
if (thread == cbowner)
{
owner = 0;
cbowner = NULL;
}
}
static int set_clipboard_window(user_handle_t win, int clear)
{
if (cbthread && cbthread != current)
{
set_error(STATUS_WAS_LOCKED);
return 0;
}
else if (!clear)
{
clipboard = win;
cbthread = current;
}
else
{
cbthread = NULL;
clipboard = 0;
}
return 1;
}
static int set_clipboard_owner(user_handle_t win, int clear)
{
if (cbthread == current)
{
if (!clear)
{
cbowner = current;
owner = win;
}
else
{
cbowner = 0;
owner = 0;
}
seqno++;
return 1;
}
else
{
set_error(STATUS_WAS_LOCKED);
return 0;
}
}
static int get_seqno(void)
{
time_t tm = time(NULL);
if (!cbowner && (tm > (seqnots + MINUPDATELAPSE)))
{
seqnots = tm;
seqno++;
}
return seqno;
}
DECL_HANDLER(set_clipboard_info)
{
reply->old_clipboard = clipboard;
reply->old_owner = owner;
reply->old_viewer = viewer;
if (req->flags & SET_CB_OPEN)
{
if (!set_clipboard_window(req->clipboard, 0))
return;
}
else if (req->flags & SET_CB_CLOSE)
{
if (!set_clipboard_window(0, 1))
return;
}
if (req->flags & SET_CB_OWNER)
{
if (!set_clipboard_owner(req->owner, 0))
return;
}
else if (req->flags & SET_CB_RELOWNER)
{
if (!set_clipboard_owner(0, 1))
return;
}
if (req->flags & SET_CB_VIEWER)
viewer = req->viewer;
if (req->flags & SET_CB_SEQNO)
seqno++;
reply->seqno = get_seqno();
if (cbthread == current)
reply->flags |= CB_OPEN;
if (cbowner == current)
reply->flags |= CB_OWNER;
}
......@@ -2124,3 +2124,28 @@ enum message_type
int next_unicode; /* is the next a unicode hook? */
VARARG(module,unicode_str); /* module name */
@END
/* Set/get clipboard information */
@REQ(set_clipboard_info)
unsigned int flags; /* flags for fields to set (see below) */
user_handle_t clipboard; /* clipboard window */
user_handle_t owner; /* clipboard owner */
user_handle_t viewer; /* first clipboard viewer */
unsigned int seqno; /* change sequence number */
@REPLY
unsigned int flags; /* status flags (see below) */
user_handle_t old_clipboard; /* old clipboard window */
user_handle_t old_owner; /* old clipboard owner */
user_handle_t old_viewer; /* old clipboard viewer */
unsigned int seqno; /* current sequence number */
@END
#define SET_CB_OPEN 0x001
#define SET_CB_OWNER 0x002
#define SET_CB_VIEWER 0x004
#define SET_CB_SEQNO 0x008
#define SET_CB_RELOWNER 0x010
#define SET_CB_CLOSE 0x020
#define CB_OPEN 0x040
#define CB_OWNER 0x080
......@@ -278,6 +278,7 @@ DECL_HANDLER(remove_hook);
DECL_HANDLER(start_hook_chain);
DECL_HANDLER(finish_hook_chain);
DECL_HANDLER(get_next_hook);
DECL_HANDLER(set_clipboard_info);
#ifdef WANT_REQUEST_HANDLERS
......@@ -459,6 +460,7 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
(req_handler)req_start_hook_chain,
(req_handler)req_finish_hook_chain,
(req_handler)req_get_next_hook,
(req_handler)req_set_clipboard_info,
};
#endif /* WANT_REQUEST_HANDLERS */
......
......@@ -210,6 +210,7 @@ static void cleanup_thread( struct thread *thread )
if (thread->wait_fd) release_object( thread->wait_fd );
if (thread->hooks) release_object( thread->hooks );
free_msg_queue( thread );
cleanup_clipboard_thread(thread);
destroy_thread_windows( thread );
for (i = 0; i < MAX_INFLIGHT_FDS; i++)
{
......
......@@ -2458,6 +2458,24 @@ static void dump_get_next_hook_reply( const struct get_next_hook_reply *req )
dump_varargs_unicode_str( cur_size );
}
static void dump_set_clipboard_info_request( const struct set_clipboard_info_request *req )
{
fprintf( stderr, " flags=%08x,", req->flags );
fprintf( stderr, " clipboard=%p,", req->clipboard );
fprintf( stderr, " owner=%p,", req->owner );
fprintf( stderr, " viewer=%p,", req->viewer );
fprintf( stderr, " seqno=%08x", req->seqno );
}
static void dump_set_clipboard_info_reply( const struct set_clipboard_info_reply *req )
{
fprintf( stderr, " flags=%08x,", req->flags );
fprintf( stderr, " old_clipboard=%p,", req->old_clipboard );
fprintf( stderr, " old_owner=%p,", req->old_owner );
fprintf( stderr, " old_viewer=%p,", req->old_viewer );
fprintf( stderr, " seqno=%08x", req->seqno );
}
static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_new_process_request,
(dump_func)dump_get_new_process_info_request,
......@@ -2634,6 +2652,7 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_start_hook_chain_request,
(dump_func)dump_finish_hook_chain_request,
(dump_func)dump_get_next_hook_request,
(dump_func)dump_set_clipboard_info_request,
};
static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
......@@ -2812,6 +2831,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_start_hook_chain_reply,
(dump_func)0,
(dump_func)dump_get_next_hook_reply,
(dump_func)dump_set_clipboard_info_reply,
};
static const char * const req_names[REQ_NB_REQUESTS] = {
......@@ -2990,6 +3010,7 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
"start_hook_chain",
"finish_hook_chain",
"get_next_hook",
"set_clipboard_info",
};
/* ### make_requests end ### */
......
......@@ -42,6 +42,10 @@ extern user_handle_t get_user_full_handle( user_handle_t handle );
extern void *free_user_handle( user_handle_t handle );
extern void *next_user_handle( user_handle_t *handle, enum user_object type );
/* clipboard functions */
extern void cleanup_clipboard_thread( struct thread *thread );
/* hook functions */
extern void close_global_hooks(void);
......
......@@ -1515,6 +1515,9 @@ BOOL WINAPI DestroyWindow( HWND hwnd )
WIN_SendDestroyMsg( hwnd );
if (!IsWindow( hwnd )) return TRUE;
if (GetClipboardOwner() == hwnd)
CLIPBOARD_ReleaseOwner();
/* Unlink now so we won't bother with the children later on */
WIN_UnlinkWindow( hwnd );
......
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