diff options
| -rw-r--r-- | CMakeLists.txt | 2 | ||||
| -rw-r--r-- | src/utouch.cpp | 197 | ||||
| -rw-r--r-- | src/utouch.h | 25 |
3 files changed, 206 insertions, 18 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 2e057dd..e36c58c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt | |||
| @@ -32,5 +32,5 @@ add_dependencies(distcheck dist) | |||
| 32 | 32 | ||
| 33 | find_package(Compiz REQUIRED) | 33 | find_package(Compiz REQUIRED) |
| 34 | include(CompizPlugin) | 34 | include(CompizPlugin) |
| 35 | compiz_plugin(utouch) | 35 | compiz_plugin(utouch PKGDEPS xi utouch-frame) |
| 36 | 36 | ||
diff --git a/src/utouch.cpp b/src/utouch.cpp index e55346c..09a4c53 100644 --- a/src/utouch.cpp +++ b/src/utouch.cpp | |||
| @@ -23,23 +23,202 @@ | |||
| 23 | 23 | ||
| 24 | COMPIZ_PLUGIN_20090315(utouch, UtouchVTable); | 24 | COMPIZ_PLUGIN_20090315(utouch, UtouchVTable); |
| 25 | 25 | ||
| 26 | bool | 26 | bool UtouchVTable::init() |
| 27 | UtouchVTable::init() | ||
| 28 | { | 27 | { |
| 29 | return true; | 28 | compLogMessage ("utouch", CompLogLevelInfo, "init"); |
| 29 | |||
| 30 | return true; | ||
| 31 | } | ||
| 32 | |||
| 33 | |||
| 34 | UtouchScreen::UtouchScreen(CompScreen* s) | ||
| 35 | : PluginClassHandler<UtouchScreen, CompScreen>(s) | ||
| 36 | , screen(s) | ||
| 37 | { | ||
| 38 | int ret, event, error; | ||
| 39 | XIEventMask mask; | ||
| 40 | |||
| 41 | ret = XQueryExtension(screen->dpy(), "XInputExtension", | ||
| 42 | &opcode, &event, &error); | ||
| 43 | |||
| 44 | compLogMessage ("utouch", CompLogLevelInfo, "ctor %d", ret); | ||
| 45 | |||
| 46 | mask.deviceid = XIAllMasterDevices; | ||
| 47 | mask.mask_len = XIMaskLen(XI_LASTEVENT); | ||
| 48 | mask.mask = (unsigned char *)calloc(mask.mask_len, sizeof(char)); | ||
| 49 | |||
| 50 | XISetMask(mask.mask, XI_TouchBegin); | ||
| 51 | XISetMask(mask.mask, XI_TouchUpdate); | ||
| 52 | XISetMask(mask.mask, XI_TouchEnd); | ||
| 53 | XISetMask(mask.mask, XI_TouchOwnership); | ||
| 54 | XISetMask(mask.mask, XI_TouchUpdateUnowned); | ||
| 55 | XISetMask(mask.mask, XI_DeviceChanged); | ||
| 56 | XISetMask(mask.mask, XI_PropertyEvent); | ||
| 57 | |||
| 58 | //XISelectEvents(screen->dpy(), screen->root(), &mask, 1); | ||
| 59 | XIGrabModifiers mods = { XIAnyModifier, 0 }; | ||
| 60 | XIGrabTouchBegin(screen->dpy(), XIAllMasterDevices, screen->root(), | ||
| 61 | False, &mask, 1, &mods); | ||
| 62 | |||
| 63 | ScreenInterface::setHandler(screen); | ||
| 30 | } | 64 | } |
| 31 | 65 | ||
| 32 | 66 | ||
| 33 | UtouchScreen:: | 67 | UtouchScreen::~UtouchScreen() |
| 34 | UtouchScreen(CompScreen* s) | ||
| 35 | : PluginClassHandler<UtouchScreen, CompScreen>(s) | ||
| 36 | , screen(s) | ||
| 37 | { | 68 | { |
| 69 | for (dev_map::iterator p = devices.begin(); p != devices.end(); ++p) | ||
| 70 | utouch_frame_delete_engine(p->second); | ||
| 71 | devices.clear(); | ||
| 38 | } | 72 | } |
| 39 | 73 | ||
| 74 | utouch_frame_handle UtouchScreen::createDevice(int devid) const | ||
| 75 | { | ||
| 76 | utouch_frame_handle fh; | ||
| 77 | XIDeviceInfo *info; | ||
| 78 | int ndevices; | ||
| 79 | |||
| 80 | info = XIQueryDevice(screen->dpy(), devid, &ndevices); | ||
| 81 | if (!info) { | ||
| 82 | compLogMessage ("utouch", CompLogLevelError, | ||
| 83 | "no info for device: %d", devid); | ||
| 84 | return 0; | ||
| 85 | } | ||
| 86 | |||
| 87 | fh = utouch_frame_new_engine(100, 32, 100); | ||
| 88 | if (fh && utouch_frame_init_xi2(fh, screen->dpy(), info)) { | ||
| 89 | compLogMessage ("utouch", CompLogLevelError, | ||
| 90 | "bad device: %d", devid); | ||
| 91 | utouch_frame_delete_engine(fh); | ||
| 92 | fh = 0; | ||
| 93 | } | ||
| 40 | 94 | ||
| 41 | UtouchScreen:: | 95 | XIFreeDeviceInfo(info); |
| 42 | ~UtouchScreen() | 96 | return fh; |
| 97 | } | ||
| 98 | |||
| 99 | static void report_device_caps(const struct utouch_surface *s) | ||
| 43 | { | 100 | { |
| 101 | fprintf(stderr, "device props:\n"); | ||
| 102 | if (s->needs_pointer) | ||
| 103 | fprintf(stderr, "\tpointer\n"); | ||
| 104 | if (s->is_direct) | ||
| 105 | fprintf(stderr, "\tdirect\n"); | ||
| 106 | if (s->is_buttonpad) | ||
| 107 | fprintf(stderr, "\tbuttonpad\n"); | ||
| 108 | if (s->is_semi_mt) | ||
| 109 | fprintf(stderr, "\tsemi_mt\n"); | ||
| 110 | fprintf(stderr, "device mt events:\n"); | ||
| 111 | if (s->use_touch_major) | ||
| 112 | fprintf(stderr, "\ttouch_major\n"); | ||
| 113 | if (s->use_touch_minor) | ||
| 114 | fprintf(stderr, "\ttouch_minor\n"); | ||
| 115 | if (s->use_width_major) | ||
| 116 | fprintf(stderr, "\twidth_major\n"); | ||
| 117 | if (s->use_width_minor) | ||
| 118 | fprintf(stderr, "\twidth_minor\n"); | ||
| 119 | if (s->use_orientation) | ||
| 120 | fprintf(stderr, "\torientation\n"); | ||
| 121 | if (s->use_pressure) | ||
| 122 | fprintf(stderr, "\tpressure\n"); | ||
| 123 | if (s->use_distance) | ||
| 124 | fprintf(stderr, "\tdistance\n"); | ||
| 125 | } | ||
| 126 | |||
| 127 | static void report_frame(const struct utouch_frame *frame) | ||
| 128 | { | ||
| 129 | int i; | ||
| 130 | |||
| 131 | for (i = 0; i < (int)frame->num_active; i++) { | ||
| 132 | const struct utouch_contact *t = frame->active[i]; | ||
| 133 | |||
| 134 | fprintf(stderr, "touch %d\n", i); | ||
| 135 | fprintf(stderr, " slot: %d\n", t->slot); | ||
| 136 | fprintf(stderr, " id: %d\n", t->id); | ||
| 137 | fprintf(stderr, " tool_type: %d\n", t->tool_type); | ||
| 138 | fprintf(stderr, " x: %f\n", t->x); | ||
| 139 | fprintf(stderr, " y: %f\n", t->y); | ||
| 140 | fprintf(stderr, " touch_major: %f\n", t->touch_major); | ||
| 141 | fprintf(stderr, " touch_minor: %f\n", t->touch_minor); | ||
| 142 | fprintf(stderr, " width_major: %f\n", t->width_major); | ||
| 143 | fprintf(stderr, " width_minor: %f\n", t->width_minor); | ||
| 144 | fprintf(stderr, " angle: %f\n", t->orientation); | ||
| 145 | fprintf(stderr, " pressure: %f\n", t->pressure); | ||
| 146 | fprintf(stderr, " distance: %f\n", t->distance); | ||
| 147 | } | ||
| 148 | |||
| 149 | fprintf(stderr, "sync %d %ld %d %d %d\n", | ||
| 150 | frame->num_active, | ||
| 151 | frame->time, | ||
| 152 | frame->sequence_id, | ||
| 153 | frame->revision, | ||
| 154 | frame->slot_revision); | ||
| 155 | } | ||
| 156 | |||
| 157 | void UtouchScreen::handleDeviceEvent(const XIDeviceEvent *ev) | ||
| 158 | { | ||
| 159 | utouch_frame_handle fh; | ||
| 160 | const struct utouch_frame *frame; | ||
| 161 | |||
| 162 | switch(ev->evtype) { | ||
| 163 | case XI_TouchOwnership: | ||
| 164 | compLogMessage ("utouch", CompLogLevelInfo, | ||
| 165 | "touch owner %d", ev->detail); | ||
| 166 | XIAllowTouchEvents(ev->display, ev->sourceid, ev->detail, | ||
| 167 | XITouchOwnerRejectContinue); | ||
| 168 | compLogMessage ("utouch", CompLogLevelInfo, | ||
| 169 | "rejected: %d %d %d %d", | ||
| 170 | ev->evtype, ev->deviceid, | ||
| 171 | ev->sourceid, ev->detail); | ||
| 172 | break; | ||
| 173 | case XI_TouchUpdateUnowned: | ||
| 174 | compLogMessage ("utouch", CompLogLevelInfo, "touch motion unowned"); | ||
| 175 | break; | ||
| 176 | case XI_DeviceChanged: | ||
| 177 | compLogMessage ("utouch", CompLogLevelInfo, "touch device changed"); | ||
| 178 | break; | ||
| 179 | case XI_PropertyEvent: | ||
| 180 | compLogMessage ("utouch", CompLogLevelInfo, "touch property changed"); | ||
| 181 | break; | ||
| 182 | case XI_TouchBegin: | ||
| 183 | case XI_TouchUpdate: | ||
| 184 | case XI_TouchEnd: | ||
| 185 | |||
| 186 | compLogMessage ("utouch", CompLogLevelInfo, | ||
| 187 | "touch: %d %d %d %d", | ||
| 188 | ev->evtype, ev->deviceid, | ||
| 189 | ev->sourceid, ev->detail); | ||
| 190 | |||
| 191 | fh = devices[ev->sourceid]; | ||
| 192 | if (!fh) { | ||
| 193 | fh = createDevice(ev->sourceid); | ||
| 194 | if (!fh) | ||
| 195 | return; | ||
| 196 | compLogMessage ("utouch", CompLogLevelInfo, | ||
| 197 | "new device: %d", ev->sourceid); | ||
| 198 | report_device_caps(utouch_frame_get_surface(fh)); | ||
| 199 | devices[ev->sourceid] = fh; | ||
| 200 | } | ||
| 201 | |||
| 202 | // update on property changes here? | ||
| 203 | // update on device going away here? | ||
| 204 | |||
| 205 | frame = utouch_frame_pump_xi2(fh, ev); | ||
| 206 | if (frame) | ||
| 207 | report_frame(frame); | ||
| 208 | break; | ||
| 209 | } | ||
| 210 | } | ||
| 211 | |||
| 212 | void UtouchScreen::handleEvent(XEvent *ev) | ||
| 213 | { | ||
| 214 | XGenericEventCookie *gev = &ev->xcookie; | ||
| 215 | |||
| 216 | if (XGetEventData(screen->dpy(), gev)) { | ||
| 217 | if (gev->type == GenericEvent && gev->extension == opcode) | ||
| 218 | handleDeviceEvent((XIDeviceEvent *)gev->data); | ||
| 219 | XFreeEventData(screen->dpy(), gev); | ||
| 220 | } | ||
| 221 | |||
| 222 | screen->handleEvent(ev); | ||
| 44 | } | 223 | } |
| 45 | 224 | ||
diff --git a/src/utouch.h b/src/utouch.h index c9f3a6d..3db32a7 100644 --- a/src/utouch.h +++ b/src/utouch.h | |||
| @@ -20,25 +20,34 @@ | |||
| 20 | */ | 20 | */ |
| 21 | #include <core/core.h> | 21 | #include <core/core.h> |
| 22 | #include <core/pluginclasshandler.h> | 22 | #include <core/pluginclasshandler.h> |
| 23 | 23 | #include <utouch/frame-xi2.h> | |
| 24 | 24 | ||
| 25 | class UtouchScreen | 25 | class UtouchScreen |
| 26 | : public ScreenInterface | 26 | : public ScreenInterface |
| 27 | , public PluginClassHandler<UtouchScreen, CompScreen> | 27 | , public PluginClassHandler<UtouchScreen, CompScreen> |
| 28 | { | 28 | { |
| 29 | public: | 29 | public: |
| 30 | UtouchScreen(CompScreen* s); | 30 | UtouchScreen(CompScreen* s); |
| 31 | |||
| 32 | virtual ~UtouchScreen(); | ||
| 33 | |||
| 34 | void handleEvent(XEvent *ev); | ||
| 31 | 35 | ||
| 32 | virtual ~UtouchScreen(); | 36 | protected: |
| 37 | utouch_frame_handle createDevice(int devid) const; | ||
| 38 | void handleDeviceEvent(const XIDeviceEvent *ev); | ||
| 33 | 39 | ||
| 34 | private: | 40 | private: |
| 35 | CompScreen* screen; | 41 | typedef std::map<int, utouch_frame_handle> dev_map; |
| 42 | CompScreen* screen; | ||
| 43 | dev_map devices; | ||
| 44 | int opcode; | ||
| 36 | }; | 45 | }; |
| 37 | 46 | ||
| 38 | 47 | ||
| 39 | class UtouchVTable | 48 | class UtouchVTable |
| 40 | : public CompPlugin::VTableForScreen<UtouchScreen> | 49 | : public CompPlugin::VTableForScreen<UtouchScreen> |
| 41 | { | 50 | { |
| 42 | bool init(); | 51 | bool init(); |
| 43 | }; | 52 | }; |
| 44 | 53 | ||
