Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
45128bdc
Commit
45128bdc
authored
Jun 29, 2005
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Make the clipboard information local to the process window station.
parent
36b85d02
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
138 additions
and
61 deletions
+138
-61
clipboard.c
server/clipboard.c
+118
-59
user.h
server/user.h
+4
-0
winstation.c
server/winstation.c
+16
-2
No files found.
server/clipboard.c
View file @
45128bdc
...
@@ -29,145 +29,204 @@
...
@@ -29,145 +29,204 @@
#include "request.h"
#include "request.h"
#include "object.h"
#include "object.h"
#include "user.h"
#include "user.h"
#include "winuser.h"
static
struct
thread
*
cbthread
;
/* thread id that has clipboard open */
struct
clipboard
static
user_handle_t
clipboard
;
/* window that has clipboard open */
{
struct
object
obj
;
/* object header */
static
struct
thread
*
cbowner
;
/* thread id that owns the clipboard */
struct
thread
*
open_thread
;
/* thread id that has clipboard open */
static
user_handle_t
owner
;
/* window that owns the clipboard data */
user_handle_t
open_win
;
/* window that has clipboard open */
struct
thread
*
owner_thread
;
/* thread id that owns the clipboard */
user_handle_t
owner_win
;
/* window that owns the clipboard data */
user_handle_t
viewer
;
/* first window in clipboard viewer list */
unsigned
int
seqno
;
/* clipboard change sequence number */
time_t
seqno_timestamp
;
/* time stamp of last seqno increment */
};
static
void
clipboard_dump
(
struct
object
*
obj
,
int
verbose
);
static
const
struct
object_ops
clipboard_ops
=
{
sizeof
(
struct
clipboard
),
/* size */
clipboard_dump
,
/* dump */
no_add_queue
,
/* add_queue */
NULL
,
/* remove_queue */
NULL
,
/* signaled */
NULL
,
/* satisfied */
no_signal
,
/* signal */
no_get_fd
,
/* get_fd */
no_close_handle
,
/* close_handle */
no_destroy
/* destroy */
};
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
#define MINUPDATELAPSE 2
/* Called when thread terminates to allow release of clipboard */
/* dump a clipboard object */
void
cleanup_clipboard_thread
(
struct
thread
*
thread
)
static
void
clipboard_dump
(
struct
object
*
obj
,
int
verbose
)
{
struct
clipboard
*
clipboard
=
(
struct
clipboard
*
)
obj
;
fprintf
(
stderr
,
"Clipboard open_thread=%p open_win=%p owner_thread=%p owner_win=%p viewer=%p seq=%u
\n
"
,
clipboard
->
open_thread
,
clipboard
->
open_win
,
clipboard
->
owner_thread
,
clipboard
->
owner_win
,
clipboard
->
viewer
,
clipboard
->
seqno
);
}
/* retrieve the clipboard info for the current process, allocating it if needed */
static
struct
clipboard
*
get_process_clipboard
(
void
)
{
{
if
(
thread
==
cbthread
)
struct
clipboard
*
clipboard
;
struct
winstation
*
winstation
=
get_process_winstation
(
current
->
process
,
WINSTA_ACCESSCLIPBOARD
);
if
(
!
winstation
)
return
NULL
;
if
(
!
(
clipboard
=
get_winstation_clipboard
(
winstation
)))
{
{
clipboard
=
0
;
if
((
clipboard
=
alloc_object
(
&
clipboard_ops
)))
cbthread
=
NULL
;
{
clipboard
->
open_thread
=
NULL
;
clipboard
->
open_win
=
0
;
clipboard
->
owner_thread
=
NULL
;
clipboard
->
owner_win
=
0
;
clipboard
->
viewer
=
0
;
clipboard
->
seqno
=
0
;
clipboard
->
seqno_timestamp
=
0
;
set_winstation_clipboard
(
winstation
,
clipboard
);
}
}
}
if
(
thread
==
cbowner
)
release_object
(
winstation
);
return
clipboard
;
}
/* Called when thread terminates to allow release of clipboard */
void
cleanup_clipboard_thread
(
struct
thread
*
thread
)
{
struct
clipboard
*
clipboard
;
struct
winstation
*
winstation
=
get_process_winstation
(
thread
->
process
,
WINSTA_ACCESSCLIPBOARD
);
if
(
!
winstation
)
return
;
if
((
clipboard
=
get_winstation_clipboard
(
winstation
)))
{
{
owner
=
0
;
if
(
thread
==
clipboard
->
open_thread
)
cbowner
=
NULL
;
{
clipboard
->
open_win
=
0
;
clipboard
->
open_thread
=
NULL
;
}
if
(
thread
==
clipboard
->
owner_thread
)
{
clipboard
->
owner_win
=
0
;
clipboard
->
owner_thread
=
NULL
;
}
}
}
release_object
(
winstation
);
}
}
static
int
set_clipboard_window
(
user_handle_t
win
,
int
clear
)
static
int
set_clipboard_window
(
struct
clipboard
*
clipboard
,
user_handle_t
win
,
int
clear
)
{
{
if
(
c
bthread
&&
cb
thread
!=
current
)
if
(
c
lipboard
->
open_thread
&&
clipboard
->
open_
thread
!=
current
)
{
{
set_error
(
STATUS_WAS_LOCKED
);
set_error
(
STATUS_WAS_LOCKED
);
return
0
;
return
0
;
}
}
else
if
(
!
clear
)
else
if
(
!
clear
)
{
{
clipboard
=
win
;
clipboard
->
open_win
=
win
;
c
b
thread
=
current
;
c
lipboard
->
open_
thread
=
current
;
}
}
else
else
{
{
c
b
thread
=
NULL
;
c
lipboard
->
open_
thread
=
NULL
;
clipboard
=
0
;
clipboard
->
open_win
=
0
;
}
}
return
1
;
return
1
;
}
}
static
int
set_clipboard_owner
(
user_handle_t
win
,
int
clear
)
static
int
set_clipboard_owner
(
struct
clipboard
*
clipboard
,
user_handle_t
win
,
int
clear
)
{
{
if
(
c
bthread
&&
cb
thread
->
process
!=
current
->
process
)
if
(
c
lipboard
->
open_thread
&&
clipboard
->
open_
thread
->
process
!=
current
->
process
)
{
{
set_error
(
STATUS_WAS_LOCKED
);
set_error
(
STATUS_WAS_LOCKED
);
return
0
;
return
0
;
}
}
else
if
(
!
clear
)
else
if
(
!
clear
)
{
{
owner
=
win
;
clipboard
->
owner_win
=
win
;
c
bowner
=
current
;
c
lipboard
->
owner_thread
=
current
;
}
}
else
else
{
{
owner
=
0
;
clipboard
->
owner_win
=
0
;
c
bowner
=
NULL
;
c
lipboard
->
owner_thread
=
NULL
;
}
}
return
1
;
return
1
;
}
}
static
int
get_seqno
(
void
)
static
int
get_seqno
(
struct
clipboard
*
clipboard
)
{
{
time_t
tm
=
time
(
NULL
);
time_t
tm
=
time
(
NULL
);
if
(
!
c
bowner
&&
(
tm
>
(
seqnots
+
MINUPDATELAPSE
)))
if
(
!
c
lipboard
->
owner_thread
&&
(
tm
>
(
clipboard
->
seqno_timestamp
+
MINUPDATELAPSE
)))
{
{
seqnots
=
tm
;
clipboard
->
seqno_timestamp
=
tm
;
seqno
++
;
clipboard
->
seqno
++
;
}
}
return
seqno
;
return
clipboard
->
seqno
;
}
}
DECL_HANDLER
(
set_clipboard_info
)
DECL_HANDLER
(
set_clipboard_info
)
{
{
reply
->
old_clipboard
=
clipboard
;
struct
clipboard
*
clipboard
=
get_process_clipboard
();
reply
->
old_owner
=
owner
;
reply
->
old_viewer
=
viewer
;
if
(
!
clipboard
)
return
;
reply
->
old_clipboard
=
clipboard
->
open_win
;
reply
->
old_owner
=
clipboard
->
owner_win
;
reply
->
old_viewer
=
clipboard
->
viewer
;
if
(
req
->
flags
&
SET_CB_OPEN
)
if
(
req
->
flags
&
SET_CB_OPEN
)
{
{
if
(
c
b
thread
)
if
(
c
lipboard
->
open_
thread
)
{
{
/* clipboard already opened */
/* clipboard already opened */
set_error
(
STATUS_WAS_LOCKED
);
set_error
(
STATUS_WAS_LOCKED
);
return
;
return
;
}
}
if
(
!
set_clipboard_window
(
req
->
clipboard
,
0
))
if
(
!
set_clipboard_window
(
clipboard
,
req
->
clipboard
,
0
))
return
;
return
;
}
}
else
if
(
req
->
flags
&
SET_CB_CLOSE
)
else
if
(
req
->
flags
&
SET_CB_CLOSE
)
{
{
if
(
c
b
thread
!=
current
)
if
(
c
lipboard
->
open_
thread
!=
current
)
{
{
set_win32_error
(
ERROR_CLIPBOARD_NOT_OPEN
);
set_win32_error
(
ERROR_CLIPBOARD_NOT_OPEN
);
return
;
return
;
}
}
if
(
!
set_clipboard_window
(
0
,
1
))
if
(
!
set_clipboard_window
(
clipboard
,
0
,
1
))
return
;
return
;
}
}
if
(
req
->
flags
&
SET_CB_OWNER
)
if
(
req
->
flags
&
SET_CB_OWNER
)
{
{
if
(
!
set_clipboard_owner
(
req
->
owner
,
0
))
if
(
!
set_clipboard_owner
(
clipboard
,
req
->
owner
,
0
))
return
;
return
;
}
}
else
if
(
req
->
flags
&
SET_CB_RELOWNER
)
else
if
(
req
->
flags
&
SET_CB_RELOWNER
)
{
{
if
(
!
set_clipboard_owner
(
0
,
1
))
if
(
!
set_clipboard_owner
(
clipboard
,
0
,
1
))
return
;
return
;
}
}
if
(
req
->
flags
&
SET_CB_VIEWER
)
if
(
req
->
flags
&
SET_CB_VIEWER
)
clipboard
->
viewer
=
req
->
viewer
;
viewer
=
req
->
viewer
;
if
(
req
->
flags
&
SET_CB_SEQNO
)
seqno
++
;
reply
->
seqno
=
get_seqno
();
if
(
cbthread
==
current
)
if
(
req
->
flags
&
SET_CB_SEQNO
)
clipboard
->
seqno
++
;
reply
->
flags
|=
CB_OPEN
;
if
(
cbowner
==
current
)
reply
->
seqno
=
get_seqno
(
clipboard
);
reply
->
flags
|=
CB_OWNER
;
if
(
cbowner
&&
if
(
clipboard
->
open_thread
==
current
)
reply
->
flags
|=
CB_OPEN
;
cbowner
->
process
==
current
->
process
)
if
(
clipboard
->
owner_thread
==
current
)
reply
->
flags
|=
CB_OWNER
;
if
(
clipboard
->
owner_thread
&&
clipboard
->
owner_thread
->
process
==
current
->
process
)
reply
->
flags
|=
CB_PROCESS
;
reply
->
flags
|=
CB_PROCESS
;
}
}
server/user.h
View file @
45128bdc
...
@@ -29,6 +29,7 @@ struct window;
...
@@ -29,6 +29,7 @@ struct window;
struct
msg_queue
;
struct
msg_queue
;
struct
hook_table
;
struct
hook_table
;
struct
window_class
;
struct
window_class
;
struct
clipboard
;
enum
user_object
enum
user_object
{
{
...
@@ -120,6 +121,9 @@ extern void *get_class_client_ptr( struct window_class *class );
...
@@ -120,6 +121,9 @@ extern void *get_class_client_ptr( struct window_class *class );
/* windows station functions */
/* windows station functions */
extern
struct
winstation
*
get_process_winstation
(
struct
process
*
process
,
unsigned
int
access
);
extern
void
set_winstation_clipboard
(
struct
winstation
*
winstation
,
struct
clipboard
*
clipboard
);
extern
struct
clipboard
*
get_winstation_clipboard
(
struct
winstation
*
winstation
);
extern
void
connect_process_winstation
(
struct
process
*
process
,
const
WCHAR
*
name
,
size_t
len
);
extern
void
connect_process_winstation
(
struct
process
*
process
,
const
WCHAR
*
name
,
size_t
len
);
extern
void
connect_process_desktop
(
struct
process
*
process
,
const
WCHAR
*
name
,
size_t
len
);
extern
void
connect_process_desktop
(
struct
process
*
process
,
const
WCHAR
*
name
,
size_t
len
);
extern
void
close_thread_desktop
(
struct
thread
*
thread
);
extern
void
close_thread_desktop
(
struct
thread
*
thread
);
...
...
server/winstation.c
View file @
45128bdc
...
@@ -41,6 +41,7 @@ struct winstation
...
@@ -41,6 +41,7 @@ struct winstation
unsigned
int
flags
;
/* winstation flags */
unsigned
int
flags
;
/* winstation flags */
struct
list
entry
;
/* entry in global winstation list */
struct
list
entry
;
/* entry in global winstation list */
struct
list
desktops
;
/* list of desktops of this winstation */
struct
list
desktops
;
/* list of desktops of this winstation */
struct
clipboard
*
clipboard
;
/* clipboard information */
};
};
struct
desktop
struct
desktop
...
@@ -113,6 +114,7 @@ static struct winstation *create_winstation( const WCHAR *name, size_t len, unsi
...
@@ -113,6 +114,7 @@ static struct winstation *create_winstation( const WCHAR *name, size_t len, unsi
{
{
/* initialize it if it didn't already exist */
/* initialize it if it didn't already exist */
winstation
->
flags
=
flags
;
winstation
->
flags
=
flags
;
winstation
->
clipboard
=
NULL
;
list_add_tail
(
&
winstation_list
,
&
winstation
->
entry
);
list_add_tail
(
&
winstation_list
,
&
winstation
->
entry
);
list_init
(
&
winstation
->
desktops
);
list_init
(
&
winstation
->
desktops
);
}
}
...
@@ -140,16 +142,28 @@ static void winstation_destroy( struct object *obj )
...
@@ -140,16 +142,28 @@ static void winstation_destroy( struct object *obj )
if
(
winstation
==
interactive_winstation
)
interactive_winstation
=
NULL
;
if
(
winstation
==
interactive_winstation
)
interactive_winstation
=
NULL
;
list_remove
(
&
winstation
->
entry
);
list_remove
(
&
winstation
->
entry
);
if
(
winstation
->
clipboard
)
release_object
(
winstation
->
clipboard
);
}
}
/* retrieve the process window station, checking the handle access rights */
/* retrieve the process window station, checking the handle access rights */
inline
static
struct
winstation
*
get_process_winstation
(
struct
process
*
process
,
struct
winstation
*
get_process_winstation
(
struct
process
*
process
,
unsigned
int
access
)
unsigned
int
access
)
{
{
return
(
struct
winstation
*
)
get_handle_obj
(
process
,
process
->
winstation
,
return
(
struct
winstation
*
)
get_handle_obj
(
process
,
process
->
winstation
,
access
,
&
winstation_ops
);
access
,
&
winstation_ops
);
}
}
/* set the pointer to the (opaque) clipboard info */
void
set_winstation_clipboard
(
struct
winstation
*
winstation
,
struct
clipboard
*
clipboard
)
{
winstation
->
clipboard
=
clipboard
;
}
/* retrieve the pointer to the (opaque) clipboard info */
struct
clipboard
*
get_winstation_clipboard
(
struct
winstation
*
winstation
)
{
return
winstation
->
clipboard
;
}
/* build the full name of a desktop object */
/* build the full name of a desktop object */
static
WCHAR
*
build_desktop_name
(
const
WCHAR
*
name
,
size_t
len
,
static
WCHAR
*
build_desktop_name
(
const
WCHAR
*
name
,
size_t
len
,
struct
winstation
*
winstation
,
size_t
*
res_len
)
struct
winstation
*
winstation
,
size_t
*
res_len
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment