Back to index

easystroke  0.5.5.1
grabber.h
Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2008-2009, Thomas Jaeger <ThJaeger@gmail.com>
00003  *
00004  * Permission to use, copy, modify, and/or distribute this software for any
00005  * purpose with or without fee is hereby granted, provided that the above
00006  * copyright notice and this permission notice appear in all copies.
00007  *
00008  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
00009  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
00010  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
00011  * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
00012  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
00013  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
00014  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
00015  */
00016 #ifndef __GRABBER_H__
00017 #define __GRABBER_H__
00018 #include "prefdb.h"
00019 #include <string>
00020 #include <map>
00021 #include <X11/extensions/XInput2.h>
00022 #include <X11/Xatom.h>
00023 
00024 #define MAX_BUTTONS 256
00025 
00026 class XAtom {
00027        const char *name;
00028        Atom atom;
00029 
00030 public:
00031        XAtom(const char *name_) : name(name_), atom(0) {}
00032        Atom operator*();
00033        Atom operator->() { return operator*(); }
00034 };
00035 
00036 class Children {
00037        Window parent;
00038 public:
00039        Children(Window);
00040        bool handle(XEvent &ev);
00041        void add(Window);
00042        void remove(Window);
00043        void destroy(Window);
00044 };
00045 
00046 class Grabber;
00047 extern Grabber *grabber;
00048 
00049 bool has_wm_state(Window w);
00050 bool has_atom(Window w, Atom prop, Atom value);
00051 
00052 void queue(sigc::slot<void> f);
00053 std::string select_window();
00054 void fake_core_button(guint b, bool press);
00055 
00056 class Grabber {
00057        friend class Handler;
00058        friend class StrokeHandler;
00059        friend class Button;
00060        friend class Prefs;
00061 public:
00062        Children children;
00063        enum State { NONE, BUTTON, SELECT, RAW };
00064        enum GrabState { GrabNo, GrabYes, GrabRaw };
00065        static const char *state_name[4];
00066 
00067        struct XiDevice {
00068               int dev;
00069               std::string name;
00070               bool supports_pressure;
00071               bool absolute;
00072               bool active;
00073               double scale_x, scale_y;
00074               int pressure_min, pressure_max;
00075               int num_buttons;
00076               int master;
00077               XiDevice(Grabber *, XIDeviceInfo *);
00078               int normalize_pressure(int pressure) {
00079                      return 255 * (pressure - pressure_min) / (pressure_max - pressure_min);
00080               }
00081               void grab_device(GrabState grab);
00082               void grab_button(ButtonInfo &bi, bool grab);
00083        };
00084 
00085        typedef std::map<XID, boost::shared_ptr<XiDevice> > DeviceMap;
00086        int opcode, event, error;
00087        XiDevice *get_xi_dev(int id);
00088 private:
00089        bool init_xi();
00090 
00091        DeviceMap xi_devs;
00092        State current, grabbed;
00093        bool xi_grabbed;
00094        GrabState xi_devs_grabbed;
00095        int suspended;
00096        bool active;
00097        Cursor cursor_select;
00098        ButtonInfo grabbed_button;
00099        std::vector<ButtonInfo> buttons;
00100 
00101        void set();
00102        void grab_xi(bool);
00103        void grab_xi_devs(GrabState);
00104 
00105        void update_excluded();
00106 
00107        void grab(State s) { current = s; set(); }
00108        void suspend() { suspended++; set(); }
00109        void resume() { if (suspended) suspended--; set(); }
00110        void update();
00111 public:
00112        Grabber();
00113        ~Grabber();
00114        bool handle(XEvent &ev) { return children.handle(ev); }
00115        Out<std::string> *current_class;
00116 
00117        void queue_suspend() { queue(sigc::mem_fun(*this, &Grabber::suspend)); }
00118        void queue_resume() { queue(sigc::mem_fun(*this, &Grabber::resume)); }
00119 
00120        void new_device(XIDeviceInfo *);
00121 
00122        bool is_grabbed(guint b);
00123        bool is_instant(guint b);
00124        bool is_click_hold(guint b);
00125        void hierarchy_changed(XIHierarchyEvent *);
00126 
00127        int get_default_button() { return grabbed_button.button; }
00128 
00129        void unminimize();
00130 };
00131 
00132 extern Grabber::XiDevice *current_dev;
00133 extern std::set<guint> xinput_pressed;
00134 
00135 class GrabFailedException : public std::exception {
00136        char *msg;
00137 public:
00138        GrabFailedException(int code) { if (asprintf(&msg, "Grab Failed: %d", code) == -1) msg = NULL; }
00139        virtual const char* what() const throw() { return msg ? msg : "Grab Failed"; }
00140        ~GrabFailedException() throw() { free(msg); }
00141 };
00142 
00143 #endif