XISelEv.c revision f1ee322d
1c27c18e8Smrg/************************************************************ 2c27c18e8Smrg 3c27c18e8SmrgCopyright 2009 Red Hat, Inc. 4c27c18e8Smrg 5c27c18e8SmrgPermission to use, copy, modify, distribute, and sell this software and its 6c27c18e8Smrgdocumentation for any purpose is hereby granted without fee, provided that 7c27c18e8Smrgthe above copyright notice appear in all copies and that both that 8c27c18e8Smrgcopyright notice and this permission notice appear in supporting 9c27c18e8Smrgdocumentation. 10c27c18e8Smrg 11c27c18e8SmrgThe above copyright notice and this permission notice shall be included in 12c27c18e8Smrgall copies or substantial portions of the Software. 13c27c18e8Smrg 14c27c18e8SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15c27c18e8SmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16c27c18e8SmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17c27c18e8SmrgAUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 18c27c18e8SmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 19c27c18e8SmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 20c27c18e8Smrg 21c27c18e8SmrgExcept as contained in this notice, the name of the author shall not be 22c27c18e8Smrgused in advertising or otherwise to promote the sale, use or other dealings 23c27c18e8Smrgin this Software without prior written authorization from the author. 24c27c18e8Smrg 25c27c18e8Smrg*/ 26c27c18e8Smrg 27c27c18e8Smrg/*********************************************************************** 28c27c18e8Smrg * 29c27c18e8Smrg * XISelectEvent - Select for XI2 events. 30c27c18e8Smrg * 31c27c18e8Smrg */ 32c27c18e8Smrg 33f1ee322dSmrg#ifdef HAVE_CONFIG_H 34f1ee322dSmrg#include <config.h> 35f1ee322dSmrg#endif 36c27c18e8Smrg 37c27c18e8Smrg#include <stdint.h> 38c27c18e8Smrg#include <X11/Xlibint.h> 39c27c18e8Smrg#include <X11/extensions/XI2proto.h> 40c27c18e8Smrg#include <X11/extensions/XInput2.h> 41c27c18e8Smrg#include <X11/extensions/extutil.h> 42c27c18e8Smrg#include <X11/extensions/ge.h> 43c27c18e8Smrg#include <X11/extensions/geproto.h> 44c27c18e8Smrg#include "XIint.h" 45c27c18e8Smrg 46c27c18e8Smrgint 47c27c18e8SmrgXISelectEvents(Display* dpy, Window win, XIEventMask* masks, int num_masks) 48c27c18e8Smrg{ 49c27c18e8Smrg XIEventMask *current; 50c27c18e8Smrg xXISelectEventsReq *req; 51c27c18e8Smrg xXIEventMask mask; 52c27c18e8Smrg int i; 53c27c18e8Smrg int len = 0; 543e256790Smrg int r = Success; 55c27c18e8Smrg 56c27c18e8Smrg XExtDisplayInfo *info = XInput_find_display(dpy); 57c27c18e8Smrg LockDisplay(dpy); 58b789ec8aSmrg if (_XiCheckExtInit(dpy, XInput_2_0, info) == -1) { 593e256790Smrg r = NoSuchExtension; 603e256790Smrg goto out; 613e256790Smrg } 62c27c18e8Smrg GetReq(XISelectEvents, req); 63c27c18e8Smrg 64c27c18e8Smrg req->reqType = info->codes->major_opcode; 65c27c18e8Smrg req->ReqType = X_XISelectEvents; 66c27c18e8Smrg req->win = win; 67c27c18e8Smrg req->num_masks = num_masks; 68c27c18e8Smrg 69c27c18e8Smrg /* get the right length */ 70c27c18e8Smrg for (i = 0; i < num_masks; i++) 71c27c18e8Smrg { 72c27c18e8Smrg len++; 73c27c18e8Smrg current = &masks[i]; 74c27c18e8Smrg len += (current->mask_len + 3)/4; 75c27c18e8Smrg } 76c27c18e8Smrg 77c27c18e8Smrg SetReqLen(req, len, len); 78c27c18e8Smrg 79c27c18e8Smrg for (i = 0; i < num_masks; i++) 80c27c18e8Smrg { 81c27c18e8Smrg char *buff; 82c27c18e8Smrg current = &masks[i]; 83c27c18e8Smrg mask.deviceid = current->deviceid; 84c27c18e8Smrg mask.mask_len = (current->mask_len + 3)/4; 85c27c18e8Smrg /* masks.mask_len is in bytes, but we need 4-byte units on the wire, 86c27c18e8Smrg * and they need to be padded with 0 */ 87c27c18e8Smrg buff = calloc(1, mask.mask_len * 4); 88c27c18e8Smrg memcpy(buff, current->mask, current->mask_len); 89b789ec8aSmrg Data(dpy, (char*)&mask, sizeof(xXIEventMask)); 90c27c18e8Smrg Data(dpy, buff, mask.mask_len * 4); 91c27c18e8Smrg free(buff); 92c27c18e8Smrg } 93c27c18e8Smrg 943e256790Smrgout: 95c27c18e8Smrg UnlockDisplay(dpy); 96c27c18e8Smrg SyncHandle(); 973e256790Smrg return r; 98c27c18e8Smrg 99c27c18e8Smrg} 100c27c18e8Smrg 101c27c18e8SmrgXIEventMask* 102c27c18e8SmrgXIGetSelectedEvents(Display* dpy, Window win, int *num_masks_return) 103c27c18e8Smrg{ 104c27c18e8Smrg int i, len = 0; 105c27c18e8Smrg unsigned char *mask; 106c27c18e8Smrg XIEventMask *mask_out = NULL; 107c27c18e8Smrg xXIEventMask *mask_in = NULL, *mi; 108c27c18e8Smrg xXIGetSelectedEventsReq *req; 109c27c18e8Smrg xXIGetSelectedEventsReply reply; 11037eb1ca1Smrg XExtDisplayInfo *info = XInput_find_display(dpy); 111c27c18e8Smrg 1123e256790Smrg *num_masks_return = -1; 113c27c18e8Smrg LockDisplay(dpy); 114b789ec8aSmrg if (_XiCheckExtInit(dpy, XInput_2_0, info) == -1) 1153e256790Smrg goto out; 116c27c18e8Smrg 117c27c18e8Smrg GetReq(XIGetSelectedEvents, req); 118c27c18e8Smrg 119c27c18e8Smrg req->reqType = info->codes->major_opcode; 120c27c18e8Smrg req->ReqType = X_XIGetSelectedEvents; 121c27c18e8Smrg req->win = win; 122c27c18e8Smrg 123c27c18e8Smrg if (!_XReply(dpy, (xReply *) &reply, 0, xFalse)) 1243e256790Smrg goto out; 125c27c18e8Smrg 126c27c18e8Smrg if (reply.num_masks == 0) 127c27c18e8Smrg { 128c27c18e8Smrg *num_masks_return = 0; 1293e256790Smrg goto out; 130c27c18e8Smrg } 131c27c18e8Smrg 132c27c18e8Smrg mask_in = Xmalloc(reply.length * 4); 133c27c18e8Smrg if (!mask_in) 1343e256790Smrg goto out; 135c27c18e8Smrg 136c27c18e8Smrg _XRead(dpy, (char*)mask_in, reply.length * 4); 137c27c18e8Smrg 138c27c18e8Smrg /* Memory layout of the XIEventMask for a 3 mask reply: 139c27c18e8Smrg * [struct a][struct b][struct c][masks a][masks b][masks c] 140c27c18e8Smrg */ 141c27c18e8Smrg len = reply.num_masks * sizeof(XIEventMask); 142c27c18e8Smrg 143c27c18e8Smrg for (i = 0, mi = mask_in; i < reply.num_masks; i++) 144c27c18e8Smrg { 145c27c18e8Smrg len += mi->mask_len * 4; 146c27c18e8Smrg mi = (xXIEventMask*)((char*)mi + mi->mask_len * 4); 147c27c18e8Smrg mi++; 148c27c18e8Smrg } 149c27c18e8Smrg 150c27c18e8Smrg mask_out = Xmalloc(len); 151c27c18e8Smrg if (!mask_out) 1523e256790Smrg goto out; 153c27c18e8Smrg 154c27c18e8Smrg mi = mask_in; 155c27c18e8Smrg mask = (unsigned char*)&mask_out[reply.num_masks]; 156c27c18e8Smrg for (i = 0; i < reply.num_masks; i++) 157c27c18e8Smrg { 158c27c18e8Smrg mask_out[i].deviceid = mi->deviceid; 159c27c18e8Smrg mask_out[i].mask_len = mi->mask_len * 4; 160c27c18e8Smrg mask_out[i].mask = mask; 161c27c18e8Smrg memcpy(mask_out[i].mask, &mi[1], mask_out[i].mask_len); 162c27c18e8Smrg mask += mask_out[i].mask_len; 163c27c18e8Smrg mi = (xXIEventMask*)((char*)mi + mi->mask_len * 4); 164c27c18e8Smrg mi++; 165c27c18e8Smrg } 166c27c18e8Smrg 167c27c18e8Smrg *num_masks_return = reply.num_masks; 168c27c18e8Smrg 1693e256790Smrgout: 1703e256790Smrg Xfree(mask_in); 171c27c18e8Smrg 172c27c18e8Smrg UnlockDisplay(dpy); 173c27c18e8Smrg SyncHandle(); 174c27c18e8Smrg 1753e256790Smrg return mask_out; 176c27c18e8Smrg} 177