Spelling fixes.
[wine] / server / clipboard.c
1 /*
2  * Server-side clipboard management
3  *
4  * Copyright (C) 2002 Ulrich Czekalla
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20
21 #include "config.h"
22 #include "wine/port.h"
23
24 #include <assert.h>
25 #include <stdlib.h>
26 #include <stdio.h>
27 #include <string.h>
28
29 #include "request.h"
30 #include "object.h"
31 #include "user.h"
32
33 static struct thread *cbthread; /* thread id that has clipboard open */
34 static user_handle_t clipboard; /* window that has clipboard open */
35
36 static struct thread *cbowner;  /* thread id that owns the clipboard */
37 static user_handle_t owner;     /* window that owns the clipboard data */
38
39 static user_handle_t viewer;    /* first window in clipboard viewer list */
40 static unsigned int seqno;      /* clipboard change sequence number */
41 static time_t seqnots;          /* time stamp of last seqno increment */
42
43 #define MINUPDATELAPSE 2
44
45 /* Called when thread terminates to allow release of clipboard */
46 void cleanup_clipboard_thread(struct thread *thread)
47 {
48     if (thread == cbthread)
49     {
50         clipboard = 0;
51         cbthread = NULL;
52     }
53     if (thread == cbowner)
54     {
55         owner = 0;
56         cbowner = NULL;
57     }
58 }
59
60 static int set_clipboard_window(user_handle_t win, int clear)
61 {
62     if (cbthread && cbthread != current)
63     {
64         set_error(STATUS_WAS_LOCKED);
65         return 0;
66     }
67     else if (!clear)
68     {
69         clipboard = win;
70         cbthread = current;
71     }
72     else
73     {
74         cbthread = NULL;
75         clipboard = 0;
76     }
77     return 1;
78 }
79
80
81 static int set_clipboard_owner(user_handle_t win, int clear)
82 {
83     if (cbthread && cbthread != current)
84     {
85         set_error(STATUS_WAS_LOCKED);
86         return 0;
87     }
88     else if (!clear)
89     {
90         owner = win;
91         cbowner = current;
92     }
93     else
94     {
95         owner = 0;
96         cbowner = NULL;
97     }
98     return 1;
99 }
100
101
102 static int get_seqno(void)
103 {
104     time_t tm = time(NULL);
105
106     if (!cbowner && (tm > (seqnots + MINUPDATELAPSE)))
107     {
108         seqnots = tm;
109         seqno++;
110     }
111     return seqno;
112 }
113
114
115 DECL_HANDLER(set_clipboard_info)
116 {
117     reply->old_clipboard = clipboard;
118     reply->old_owner = owner;
119     reply->old_viewer = viewer;
120
121     if (req->flags & SET_CB_OPEN)
122     {
123         if (cbthread)
124         {
125             /* clipboard already opened */
126             set_error(STATUS_WAS_LOCKED);
127             return;
128         }
129
130         if (!set_clipboard_window(req->clipboard, 0))
131             return;
132     }
133     else if (req->flags & SET_CB_CLOSE)
134     {
135         if (cbthread != current)
136         {
137             set_win32_error(ERROR_CLIPBOARD_NOT_OPEN);
138             return;
139         }
140
141         if (!set_clipboard_window(0, 1))
142             return;
143     }
144
145     if (req->flags & SET_CB_OWNER)
146     {
147         if (!set_clipboard_owner(req->owner, 0))
148             return;
149     }
150     else if (req->flags & SET_CB_RELOWNER)
151     {
152         if (!set_clipboard_owner(0, 1))
153             return;
154     }
155
156     if (req->flags & SET_CB_VIEWER)
157         viewer = req->viewer;
158
159     if (req->flags & SET_CB_SEQNO)
160         seqno++;
161
162     reply->seqno = get_seqno();
163
164     if (cbthread == current)
165         reply->flags |= CB_OPEN;
166
167     if (cbowner == current)
168         reply->flags |= CB_OWNER;
169 }