-
Notifications
You must be signed in to change notification settings - Fork 87
/
grabber.h
131 lines (112 loc) · 3.23 KB
/
grabber.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
/*
* Copyright (c) 2008-2009, Thomas Jaeger <ThJaeger@gmail.com>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef __GRABBER_H__
#define __GRABBER_H__
#include "prefdb.h"
#include <string>
#include <map>
#include <X11/extensions/XInput2.h>
#include <X11/Xatom.h>
#define MAX_BUTTONS 256
class XAtom {
const char *name;
Atom atom;
public:
XAtom(const char *name_) : name(name_), atom(0) {}
Atom operator*();
Atom operator->() { return operator*(); }
};
class Children {
Window parent;
public:
Children(Window);
bool handle(XEvent &ev);
void add(Window);
void remove(Window);
void destroy(Window);
};
class Grabber;
extern Grabber *grabber;
class Grabber {
friend class Handler;
friend class StrokeHandler;
friend class Button;
friend class Prefs;
public:
Children children;
enum State { NONE, BUTTON, SELECT, RAW };
enum GrabState { GrabNo, GrabYes, GrabRaw };
static const char *state_name[4];
struct XiDevice {
int dev;
std::string name;
bool absolute;
bool active;
int proximity_axis;
double scale_x, scale_y;
int num_buttons;
int master;
XiDevice(Grabber *, XIDeviceInfo *);
void grab_device(GrabState grab);
void grab_button(ButtonInfo &bi, bool grab);
};
typedef std::map<XID, boost::shared_ptr<XiDevice> > DeviceMap;
int opcode, event, error;
XiDevice *get_xi_dev(int id);
private:
bool init_xi();
DeviceMap xi_devs;
State current, grabbed;
bool xi_grabbed;
GrabState xi_devs_grabbed;
int suspended;
bool active;
Cursor cursor_select;
ButtonInfo grabbed_button;
std::vector<ButtonInfo> buttons;
void set();
void grab_xi(bool);
void grab_xi_devs(GrabState);
void update_excluded();
void grab(State s) { current = s; set(); }
void suspend() { suspended++; set(); }
void resume() { if (suspended) suspended--; set(); }
void update();
public:
Grabber();
~Grabber();
bool handle(XEvent &ev) { return children.handle(ev); }
Out<std::string> *current_class;
void queue_suspend();
void queue_resume();
std::string select_window();
void new_device(XIDeviceInfo *);
bool is_grabbed(guint b);
bool is_instant(guint b);
bool is_click_hold(guint b);
bool hierarchy_changed(XIHierarchyEvent *);
int get_default_button() { return grabbed_button.button; }
guint get_default_mods(guint button);
void unminimize();
};
class GrabFailedException : public std::exception {
char *msg;
public:
GrabFailedException(int code) { if (asprintf(&msg, "Grab Failed: %d", code) == -1) msg = nullptr; }
virtual const char* what() const throw() { return msg ? msg : "Grab Failed"; }
~GrabFailedException() throw() { free(msg); }
};
#endif