source: trunk/synergy/lib/platform/CMSWindowsDesks.h

Last change on this file was 2749, checked in by bird, 19 years ago

synergy v1.3.1 sources (zip).

File size: 7.8 KB
Line 
1/*
2 * synergy -- mouse and keyboard sharing utility
3 * Copyright (C) 2004 Chris Schoeneman
4 *
5 * This package is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * found in the file COPYING that should have accompanied this file.
8 *
9 * This package is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 */
14
15#ifndef CMSWINDOWSDESKS_H
16#define CMSWINDOWSDESKS_H
17
18#include "CSynergyHook.h"
19#include "KeyTypes.h"
20#include "MouseTypes.h"
21#include "OptionTypes.h"
22#include "CCondVar.h"
23#include "CMutex.h"
24#include "CString.h"
25#include "stdmap.h"
26#define WIN32_LEAN_AND_MEAN
27#include <windows.h>
28
29class CEvent;
30class CEventQueueTimer;
31class CThread;
32class IJob;
33class IScreenSaver;
34
35//! Microsoft Windows desk handling
36/*!
37Desks in Microsoft Windows are only remotely like desktops on X11
38systems. A desk is another virtual surface for windows but desks
39impose serious restrictions: a thread can interact with only one
40desk at a time, you can't switch desks if the thread has any hooks
41installed or owns any windows, windows cannot exist on multiple
42desks at once, etc. Basically, they're useless except for running
43the login window or the screensaver, which is what they're used
44for. Synergy must deal with them mainly because of the login
45window and screensaver but users can create their own desks and
46synergy should work on those too.
47
48This class encapsulates all the desk nastiness. Clients of this
49object don't have to know anything about desks.
50*/
51class CMSWindowsDesks {
52public:
53 //! Constructor
54 /*!
55 \p isPrimary is true iff the desk is for a primary screen.
56 \p screensaver points to a screensaver object and it's used
57 only to check if the screensaver is active. The \p updateKeys
58 job is adopted and is called when the key state should be
59 updated in a thread attached to the current desk.
60 \p hookLibrary must be a handle to the hook library.
61 */
62 CMSWindowsDesks(bool isPrimary, HINSTANCE hookLibrary,
63 const IScreenSaver* screensaver, IJob* updateKeys);
64 ~CMSWindowsDesks();
65
66 //! @name manipulators
67 //@{
68
69 //! Enable desk tracking
70 /*!
71 Enables desk tracking. While enabled, this object checks to see
72 if the desk has changed and ensures that the hooks are installed
73 on the new desk. \c setShape should be called at least once
74 before calling \c enable.
75 */
76 void enable();
77
78 //! Disable desk tracking
79 /*!
80 Disables desk tracking. \sa enable.
81 */
82 void disable();
83
84 //! Notify of entering a desk
85 /*!
86 Prepares a desk for when the cursor enters it.
87 */
88 void enter();
89
90 //! Notify of leaving a desk
91 /*!
92 Prepares a desk for when the cursor leaves it.
93 */
94 void leave(HKL keyLayout);
95
96 //! Notify of options changes
97 /*!
98 Resets all options to their default values.
99 */
100 void resetOptions();
101
102 //! Notify of options changes
103 /*!
104 Set options to given values. Ignores unknown options and doesn't
105 modify options that aren't given in \c options.
106 */
107 void setOptions(const COptionsList& options);
108
109 //! Update the key state
110 /*!
111 Causes the key state to get updated to reflect the physical keyboard
112 state and current keyboard mapping.
113 */
114 void updateKeys();
115
116 //! Tell desk about new size
117 /*!
118 This tells the desks that the display size has changed.
119 */
120 void setShape(SInt32 x, SInt32 y,
121 SInt32 width, SInt32 height,
122 SInt32 xCenter, SInt32 yCenter, bool isMultimon);
123
124 //! Install/uninstall screensaver hooks
125 /*!
126 If \p install is true then the screensaver hooks are installed and,
127 if desk tracking is enabled, updated whenever the desk changes. If
128 \p install is false then the screensaver hooks are uninstalled.
129 */
130 void installScreensaverHooks(bool install);
131
132 //! Start ignoring user input
133 /*!
134 Starts ignoring user input so we don't pick up our own synthesized events.
135 */
136 void fakeInputBegin();
137
138 //! Stop ignoring user input
139 /*!
140 Undoes whatever \c fakeInputBegin() did.
141 */
142 void fakeInputEnd();
143
144 //@}
145 //! @name accessors
146 //@{
147
148 //! Get cursor position
149 /*!
150 Return the current position of the cursor in \c x and \c y.
151 */
152 void getCursorPos(SInt32& x, SInt32& y) const;
153
154 //! Fake key press/release
155 /*!
156 Synthesize a press or release of key \c button.
157 */
158 void fakeKeyEvent(KeyButton button, UINT virtualKey,
159 bool press, bool isAutoRepeat) const;
160
161 //! Fake mouse press/release
162 /*!
163 Synthesize a press or release of mouse button \c id.
164 */
165 void fakeMouseButton(ButtonID id, bool press) const;
166
167 //! Fake mouse move
168 /*!
169 Synthesize a mouse move to the absolute coordinates \c x,y.
170 */
171 void fakeMouseMove(SInt32 x, SInt32 y) const;
172
173 //! Fake mouse move
174 /*!
175 Synthesize a mouse move to the relative coordinates \c dx,dy.
176 */
177 void fakeMouseRelativeMove(SInt32 dx, SInt32 dy) const;
178
179 //! Fake mouse wheel
180 /*!
181 Synthesize a mouse wheel event of amount \c delta in direction \c axis.
182 */
183 void fakeMouseWheel(SInt32 xDelta, SInt32 yDelta) const;
184
185 //@}
186
187private:
188 class CDesk {
189 public:
190 CString m_name;
191 CThread* m_thread;
192 DWORD m_threadID;
193 DWORD m_targetID;
194 HDESK m_desk;
195 HWND m_window;
196 HWND m_foregroundWindow;
197 bool m_lowLevel;
198 };
199 typedef std::map<CString, CDesk*> CDesks;
200
201 // initialization and shutdown operations
202 void queryHookLibrary(HINSTANCE hookLibrary);
203 HCURSOR createBlankCursor() const;
204 void destroyCursor(HCURSOR cursor) const;
205 ATOM createDeskWindowClass(bool isPrimary) const;
206 void destroyClass(ATOM windowClass) const;
207 HWND createWindow(ATOM windowClass, const char* name) const;
208 void destroyWindow(HWND) const;
209
210 // message handlers
211 void deskMouseMove(SInt32 x, SInt32 y) const;
212 void deskMouseRelativeMove(SInt32 dx, SInt32 dy) const;
213 void deskEnter(CDesk* desk);
214 void deskLeave(CDesk* desk, HKL keyLayout);
215 void deskThread(void* vdesk);
216
217 // desk switch checking and handling
218 CDesk* addDesk(const CString& name, HDESK hdesk);
219 void removeDesks();
220 void checkDesk();
221 bool isDeskAccessible(const CDesk* desk) const;
222 void handleCheckDesk(const CEvent& event, void*);
223
224 // communication with desk threads
225 void waitForDesk() const;
226 void sendMessage(UINT, WPARAM, LPARAM) const;
227
228 // work around for messed up keyboard events from low-level hooks
229 HWND getForegroundWindow() const;
230
231 // desk API wrappers
232 HDESK openInputDesktop();
233 void closeDesktop(HDESK);
234 CString getDesktopName(HDESK);
235
236 // our desk window procs
237 static LRESULT CALLBACK primaryDeskProc(HWND, UINT, WPARAM, LPARAM);
238 static LRESULT CALLBACK secondaryDeskProc(HWND, UINT, WPARAM, LPARAM);
239
240private:
241 // true if screen is being used as a primary screen, false otherwise
242 bool m_isPrimary;
243
244 // true if windows 95/98/me
245 bool m_is95Family;
246
247 // true if windows 98/2k or higher (i.e. not 95/nt)
248 bool m_isModernFamily;
249
250 // true if mouse has entered the screen
251 bool m_isOnScreen;
252
253 // our resources
254 ATOM m_deskClass;
255 HCURSOR m_cursor;
256
257 // screen shape stuff
258 SInt32 m_x, m_y;
259 SInt32 m_w, m_h;
260 SInt32 m_xCenter, m_yCenter;
261
262 // true if system appears to have multiple monitors
263 bool m_multimon;
264
265 // the timer used to check for desktop switching
266 CEventQueueTimer* m_timer;
267
268 // screen saver stuff
269 DWORD m_threadID;
270 const IScreenSaver* m_screensaver;
271 bool m_screensaverNotify;
272
273 // the current desk and it's name
274 CDesk* m_activeDesk;
275 CString m_activeDeskName;
276
277 // one desk per desktop and a cond var to communicate with it
278 CMutex m_mutex;
279 CCondVar<bool> m_deskReady;
280 CDesks m_desks;
281
282 // hook library stuff
283 InstallFunc m_install;
284 UninstallFunc m_uninstall;
285 InstallScreenSaverFunc m_installScreensaver;
286 UninstallScreenSaverFunc m_uninstallScreensaver;
287
288 // keyboard stuff
289 IJob* m_updateKeys;
290 HKL m_keyLayout;
291
292 // options
293 bool m_leaveForegroundOption;
294};
295
296#endif
Note: See TracBrowser for help on using the repository browser.