ubit
umserver.hpp
1 /*************************************************************************
2  *
3  * umserver.cpp: UMS Server [Ubit Multiple-Mouse/Message Server]
4  * Provides multiple event flows, pseudo pointers, two-handed interaction,
5  * RendezVous identification, remote control facilities, etc.
6  *
7  * NOTE: -lsocket -lnsl linking directives required on Solaris
8  *
9  * Ubit Project
10  * Author: Eric Lecolinet
11  * Part of the Ubit Toolkit: A Brick Construction Game Model for Creating GUIs
12  * (C) 2003-2008 Eric Lecolinet / ENST Paris / http://www.enst.fr/~elc/ubit
13  *
14  * ***********************************************************************
15  * COPYRIGHT NOTICE :
16  * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY AND WITHOUT EVEN THE
17  * IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
18  * YOU CAN REDISTRIBUTE IT AND/OR MODIFY IT UNDER THE TERMS OF THE GNU
19  * GENERAL PUBLIC LICENSE AS PUBLISHED BY THE FREE SOFTWARE FOUNDATION;
20  * EITHER VERSION 2 OF THE LICENSE, OR (AT YOUR OPTION) ANY LATER VERSION.
21  * SEE FILES 'COPYRIGHT' AND 'COPYING' FOR MORE DETAILS.
22  * ***********************************************************************/
23 
24 #ifndef _umserver_hpp_
25 #define _umserver_hpp_
26 #include <vector>
27 #include <list>
28 #include <iostream>
29 #include <string>
30 #include <ubit/udefs.hpp>
31 #include <ubit/usocket.hpp>
32 using namespace ubit;
33 
34 #if (defined(__MACH__) && defined(__APPLE__))
35 # define MACOSX 1
36 #endif
37 
38 /* ==================================================== [(c)Elc] ======= */
39 
40 typedef unsigned long WindowID;
41 typedef unsigned long AtomID;
42 typedef unsigned long CursorID;
43 typedef unsigned long TimeID;
44 typedef union _XEvent XEvent;
45 typedef struct _XDisplay XDisplay;
46 //typedef struct XScreen;
47 struct XScreen;
48 
49 enum {
50  MouseLeftID = (1<<8),
51  MouseMiddleID = (1<<9),
52  MouseRightID = (1<<10),
53  WheelUpID = (1<<11),
54  WheelDownID = (1<<12),
55  ALT_GRAPH_MASK = 0x2000
56 };
57 
58 class EventSource;
59 class EventFlow;
60 class MouseFlow;
61 struct RemoteUMS;
62 typedef std::list<RemoteUMS*> RemoteUMSList;
63 
64 /* ==================================================== ======== ======= */
65 /* Key mapping.
66  */
67 struct ActionKey {
68  ActionKey(unsigned int keycode, int modifier,
69  void (*press_action)(class UMServer&, XEvent&),
70  void (*release_action)(class UMServer&, XEvent&));
71 
72  unsigned int keycode;
73  int modifier;
74  void (*press_action)(class UMServer&, XEvent&);
75  void (*release_action)(class UMServer&, XEvent&);
76 };
77 
78 /* ==================================================== ======== ======= */
81 struct Pos {
82  Pos();
83  Pos(int rx, int ry, int wx, int wy, WindowID win,
84  bool in_ubitwin, int win_sock);
85 
86  int rx, ry;
87  int wx, wy;
88  WindowID win, subwin;
89  // att ubit_win n'est mis a jour que par getWinPos()
90  // cad quand on interagit avec un mouse flow non natif
91  bool in_ubitwin;
92  int win_sock;
93 };
94 
95 /* ==================================================== ======== ======= */
98 struct Win {
99  enum State {HIDE=0, SHOW=1, CREATE=2, DESTROY=3};
100 
101  ~Win();
102  Win(WindowID win, WindowID client_win);
104 
105  bool is_prop_init, is_shown, is_override, is_input_only, is_icon;
106  int win_sock;
107  WindowID win, client_win;
108  unsigned char* ubit_prop;
109 
110 private:
111  Win(const Win&);
112  Win& operator=(const Win&);
113 };
114 
115 typedef std::list<Win*> WinList;
116 
117 /* ==================================================== ======== ======= */
120 struct Cnx {
121  Cnx(USocket*);
122  ~Cnx();
123 
124  class USocket* sock;
125  bool browse_servers, browse_neigbors, browse_windows;
126 };
127 
128 typedef std::list<Cnx*> CnxList;
129 
130 /* ==================================================== [(c)Elc] ======= */
133 struct Edges {
134  static const int EDGE_THICKNESS = 1;
135  Edges(UMServer*, int neighbor_mode);
136  bool isEdge(WindowID);
137  void enterEdge(WindowID, int x_root, int y_root);
138  void raiseEdges();
139  void moveNativePointerBackHome(bool center);
140 
141  UMServer& ums;
142  bool is_outside;
143  int x_crossings, y_crossings;
144  int x_delta, y_delta;
145  WindowID left_edge, top_edge, right_edge, bottom_edge, h_where_win, v_where_win;
146 };
147 
148 /* ==================================================== [(c)Elc] ======= */
149 /* ==================================================== ======== ======= */
152 class UMServer {
153 public:
155  static const TimeID NEIGHBOR_RETRY_DELAY = 6*1000; // 1 mn
156 
157  // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
158 
159  UMServer(const char* display_name, int ums_port, bool reuse_address,
160  int cursor_mode, int neighbor_mode);
167  ~UMServer();
168 
169  bool isInit() const {return is_init;}
174  void start();
179  void setPublicDir(const char* s);
180  const std::string& getPublicDir() {return public_dir;}
181 
182  // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
183  // Emulation of mouse buttons 2 & 3, etc.
184 
185  void setNativeButton(int raw_btn_number, unsigned int raw_mod_mask,
186  unsigned int to_btn_mask, unsigned int ro_mod_mask);
187  /* changes the events generated by the buttons of the native mouse.
188  * for instance: setNativeButton(Button1, ControlMask, Button3Mask, 0);
189  * will emulate Button3 when ControlMask+Button1 are pressed/released
190  *
191  * this is useful for machines that do not have 3 buttons such as the IPAQ.
192  * see also: EventSource::SetButton() (to configurate other event sources)
193  */
194 
195  void setActionKey(unsigned int keycode, int modifier,
196  void (*press_action)(class UMServer&, XEvent&),
197  void (*release_action)(class UMServer&, XEvent&));
201  // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
202  // Browsed UMSs and Neighbor UMSs
203 
204  RemoteUMSList::iterator findRemoteUMS(const char* name);
205  RemoteUMS* addRemoteUMS(const char* name, const char* address,
206  int port, int pos);
207  void removeRemoteUMS(const char* name);
208 
209  RemoteUMS* getNeighborUMS(int pos) const;
210  RemoteUMS* setNeighborUMS(int pos, const char* name);
211 
212  void sendRemoteUMSState(RemoteUMS*, int state);
214 
215  void sendRemoteUMSList(Cnx* to);
217 
218  void sendNeighborList(Cnx* to);
219  void sendNeighborState(RemoteUMS*, int pos);
220 
221  // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
222  // Event Sources
223 
224  std::string resolveDeviceName(const char*);
226 
227  bool addEventSource(EventSource*);
235  bool removeEventSource(EventSource*);
243  // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
244  // Event Flows
245 
246  MouseFlow& getNativeMouseFlow() const;
251  MouseFlow* getMouseFlow(int id) const;
257  MouseFlow* getOrCreateMouseFlow(int id);
261  EventFlow* getEventFlow(int id) const;
267  bool addEventFlow(EventFlow*);
278  bool removeEventFlow(EventFlow*);
287  // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
288  // Connections
289 
290  CnxList::iterator findCnxIt(USocket*);
291  Cnx* findCnx(USocket*);
292  Cnx* addCnx(USocket*);
293  void removeCnx(USocket*);
294 
295  // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
296  // X Display and windows
297 
298  XDisplay* getDisplay() const {return xdisplay;}
299  XScreen* getScreen() const {return xscreen;}
300  WindowID getRoot() const {return xrootwin;}
301  int getXConnection() const {return xconnection;}
302  long getScreenWidth() const;
303  long getScreenHeight() const;
304  int getScreenDepth() const;
305 
306  // Calibration for the MIMIO
307  struct Calibration* getCalibration();
308 
309  // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
310  // Current (X) Windows
311 
312  Win* addWin(WindowID, bool notify);
313  void removeWin(WindowID, bool notify);
314  void reorderWin(WinList::iterator& from, const WinList::iterator& to);
315 
316  void retrieveXWindows();
317  void raiseXWindows();
318 
319  void sendWindowState(Win*, int state);
320  void sendWindowList(Cnx* to);
321 
322  Win* findWin(const char* name);
323  Win* findWin(WindowID);
324  WinList::iterator findWinIt(WindowID);
326 
327  bool getXWin(int root_x, int root_y, Pos&, bool check_props);
329 
330  bool getXSubwin(const Pos& wp, int x, int y, Pos&);
332 
333  bool getXWinPos(const Win* w, Pos&);
335 
336  // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
337  // Pointers
338 
339  bool isPointer(WindowID);
341 
342  void moveNativePointerBackHome(bool center);
344 
345  // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
346  // Implementation
347 
348  static TimeID getTime();
349 
350  class UServerSocket* getServerSocket() {return serv_sock;}
351  WinList& getWins() {return wins;}
352  CnxList& getCnxs() {return cnxs;}
353 
354  void processRequest(USocket*, class UInbuf&);
355 
356  // private:
357  AtomID _WM_DELETE_WINDOW;
358  AtomID _UMS_WINDOW;
359  AtomID _UMS_MESSAGE;
360 
361  bool initX(const char* display_name, int cursor_mode, int neighbor_mode);
362  void getAndProcessXEvents();
363 
364  bool addSourceToMainLoop(USocket*);
365  bool addSourceToMainLoop(EventSource*);
366  void initMainLoop();
367  void runMainLoop();
368 
369  // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
370 
371  bool is_init;
372  class UServerSocket* serv_sock;
373  int xconnection;
374  XDisplay* xdisplay;
375  XScreen* xscreen;
376  WindowID xrootwin;
377  CursorID root_cursor, grab_cursor;
378  struct Events& events;
379  struct Edges* edges;
380  struct Calibration* calib;
381  struct Mdns* mdns;
382  std::string hostname, system, public_dir;
384 
386  std::vector<EventSource*> sources;
387 
389  std::vector<EventFlow*> eflows;
390 
392  CnxList cnxs;
393 
395  WinList wins;
396 
398  RemoteUMSList remotes;
399 
401  RemoteUMS *l_neighbor, *r_neighbor, *t_neighbor, *b_neighbor;
402 
404  std::vector<ActionKey> action_keys;
405 };
406 
407 #endif
408 /* ==================================================== [TheEnd] ======= */
409 /* ==================================================== [(c)Elc] ======= */
EventSource & natsource
the native event source.
Definition: umserver.hpp:383
Definition: umserver.hpp:67
Definition: events.cpp:9
bool isInit() const
checks if the UMS is initialized.
Definition: umserver.hpp:169
RemoteUMSList remotes
the list of RemoteUMS that are currently browsed.
Definition: umserver.hpp:398
Definition: zeroconf.hpp:30
window (on the same display).
Definition: umserver.hpp:98
UInbuf (.
Definition: usocket.hpp:264
std::vector< ActionKey > action_keys
predefined keys that perform some action
Definition: umserver.hpp:404
UMS mouse event flow.
Definition: flow.hpp:40
UServerSocket.
Definition: usocket.hpp:156
UMS event flow.
Definition: flow.hpp:24
connection with a remote appli.
Definition: umserver.hpp:120
position on the screen
Definition: umserver.hpp:81
UMS server main class.
Definition: umserver.hpp:152
WinList wins
list of the windows of this X server
Definition: umserver.hpp:395
std::vector< EventSource * > sources
list of event sources (= the devices that are connected to the eflows)
Definition: umserver.hpp:386
std::vector< EventFlow * > eflows
list of event flows (eflows[0] corresponds to the standard X server)
Definition: umserver.hpp:389
Ubit Simple Sockets.
Definition: usocket.hpp:64
Remote UMServer.
Definition: remoteserver.hpp:24
screen edges.
Definition: umserver.hpp:133
Definition: uhardfont.hpp:31
UMS event source.
Definition: source.hpp:46
CnxList cnxs
lists of connections (= connected applications) and their opened windows
Definition: umserver.hpp:392
settings of the calibration window (used for absolute positioning devices such as the MIMIO) ...
Definition: calib.hpp:24
RemoteUMS * l_neighbor
neigbhors of this UMS server.
Definition: umserver.hpp:401