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 @@
#include "request.h"
#include "object.h"
#include "user.h"
#include "winuser.h"
static
struct
thread
*
cbthread
;
/* thread id that has clipboard open */
static
user_handle_t
clipboard
;
/* window that has clipboard open */
static
struct
thread
*
cbowner
;
/* thread id that owns the clipboard */
static
user_handle_t
owner
;
/* window that owns the clipboard data */
struct
clipboard
{
struct
object
obj
;
/* object header */
struct
thread
*
open_thread
;
/* thread id that has clipboard open */
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
/* Called when thread terminates to allow release of clipboard */
void
cleanup_clipboard_thread
(
struct
thread
*
thread
)
/* dump a clipboard object */
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
;
cbthread
=
NULL
;
if
((
clipboard
=
alloc_object
(
&
clipboard_ops
)))
{
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
;
cbowner
=
NULL
;
if
(
thread
==
clipboard
->
open_thread
)
{
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
);
return
0
;
}
else
if
(
!
clear
)
{
clipboard
=
win
;
c
b
thread
=
current
;
clipboard
->
open_win
=
win
;
c
lipboard
->
open_
thread
=
current
;
}
else
{
c
b
thread
=
NULL
;
clipboard
=
0
;
c
lipboard
->
open_
thread
=
NULL
;
clipboard
->
open_win
=
0
;
}
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
);
return
0
;
}
else
if
(
!
clear
)
{
owner
=
win
;
c
bowner
=
current
;
clipboard
->
owner_win
=
win
;
c
lipboard
->
owner_thread
=
current
;
}
else
{
owner
=
0
;
c
bowner
=
NULL
;
clipboard
->
owner_win
=
0
;
c
lipboard
->
owner_thread
=
NULL
;
}
return
1
;
}
static
int
get_seqno
(
void
)
static
int
get_seqno
(
struct
clipboard
*
clipboard
)
{
time_t
tm
=
time
(
NULL
);
if
(
!
c
bowner
&&
(
tm
>
(
seqnots
+
MINUPDATELAPSE
)))
if
(
!
c
lipboard
->
owner_thread
&&
(
tm
>
(
clipboard
->
seqno_timestamp
+
MINUPDATELAPSE
)))
{
seqnots
=
tm
;
seqno
++
;
clipboard
->
seqno_timestamp
=
tm
;
clipboard
->
seqno
++
;
}
return
seqno
;
return
clipboard
->
seqno
;
}
DECL_HANDLER
(
set_clipboard_info
)
{
reply
->
old_clipboard
=
clipboard
;
reply
->
old_owner
=
owner
;
reply
->
old_viewer
=
viewer
;
struct
clipboard
*
clipboard
=
get_process_clipboard
();
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
(
c
b
thread
)
if
(
c
lipboard
->
open_
thread
)
{
/* clipboard already opened */
set_error
(
STATUS_WAS_LOCKED
);
return
;
}
if
(
!
set_clipboard_window
(
req
->
clipboard
,
0
))
return
;
if
(
!
set_clipboard_window
(
clipboard
,
req
->
clipboard
,
0
))
return
;
}
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
);
return
;
}
if
(
!
set_clipboard_window
(
0
,
1
))
return
;
if
(
!
set_clipboard_window
(
clipboard
,
0
,
1
))
return
;
}
if
(
req
->
flags
&
SET_CB_OWNER
)
{
if
(
!
set_clipboard_owner
(
req
->
owner
,
0
))
return
;
if
(
!
set_clipboard_owner
(
clipboard
,
req
->
owner
,
0
))
return
;
}
else
if
(
req
->
flags
&
SET_CB_RELOWNER
)
{
if
(
!
set_clipboard_owner
(
0
,
1
))
return
;
if
(
!
set_clipboard_owner
(
clipboard
,
0
,
1
))
return
;
}
if
(
req
->
flags
&
SET_CB_VIEWER
)
viewer
=
req
->
viewer
;
if
(
req
->
flags
&
SET_CB_SEQNO
)
seqno
++
;
reply
->
seqno
=
get_seqno
();
if
(
req
->
flags
&
SET_CB_VIEWER
)
clipboard
->
viewer
=
req
->
viewer
;
if
(
cbthread
==
current
)
reply
->
flags
|=
CB_OPEN
;
if
(
req
->
flags
&
SET_CB_SEQNO
)
clipboard
->
seqno
++
;
if
(
cbowner
==
current
)
reply
->
flags
|=
CB_OWNER
;
reply
->
seqno
=
get_seqno
(
clipboard
);
if
(
cbowner
&&
cbowner
->
process
==
current
->
process
)
if
(
clipboard
->
open_thread
==
current
)
reply
->
flags
|=
CB_OPEN
;
if
(
clipboard
->
owner_thread
==
current
)
reply
->
flags
|=
CB_OWNER
;
if
(
clipboard
->
owner_thread
&&
clipboard
->
owner_thread
->
process
==
current
->
process
)
reply
->
flags
|=
CB_PROCESS
;
}
server/user.h
View file @
45128bdc
...
...
@@ -29,6 +29,7 @@ struct window;
struct
msg_queue
;
struct
hook_table
;
struct
window_class
;
struct
clipboard
;
enum
user_object
{
...
...
@@ -120,6 +121,9 @@ extern void *get_class_client_ptr( struct window_class *class );
/* 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_desktop
(
struct
process
*
process
,
const
WCHAR
*
name
,
size_t
len
);
extern
void
close_thread_desktop
(
struct
thread
*
thread
);
...
...
server/winstation.c
View file @
45128bdc
...
...
@@ -41,6 +41,7 @@ struct winstation
unsigned
int
flags
;
/* winstation flags */
struct
list
entry
;
/* entry in global winstation list */
struct
list
desktops
;
/* list of desktops of this winstation */
struct
clipboard
*
clipboard
;
/* clipboard information */
};
struct
desktop
...
...
@@ -113,6 +114,7 @@ static struct winstation *create_winstation( const WCHAR *name, size_t len, unsi
{
/* initialize it if it didn't already exist */
winstation
->
flags
=
flags
;
winstation
->
clipboard
=
NULL
;
list_add_tail
(
&
winstation_list
,
&
winstation
->
entry
);
list_init
(
&
winstation
->
desktops
);
}
...
...
@@ -140,16 +142,28 @@ static void winstation_destroy( struct object *obj )
if
(
winstation
==
interactive_winstation
)
interactive_winstation
=
NULL
;
list_remove
(
&
winstation
->
entry
);
if
(
winstation
->
clipboard
)
release_object
(
winstation
->
clipboard
);
}
/* retrieve the process window station, checking the handle access rights */
inline
static
struct
winstation
*
get_process_winstation
(
struct
process
*
process
,
unsigned
int
access
)
struct
winstation
*
get_process_winstation
(
struct
process
*
process
,
unsigned
int
access
)
{
return
(
struct
winstation
*
)
get_handle_obj
(
process
,
process
->
winstation
,
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 */
static
WCHAR
*
build_desktop_name
(
const
WCHAR
*
name
,
size_t
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