XISelEv.c revision b789ec8a
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 33c27c18e8Smrg 34c27c18e8Smrg#include <stdint.h> 35c27c18e8Smrg#include <X11/Xlibint.h> 36c27c18e8Smrg#include <X11/extensions/XI2proto.h> 37c27c18e8Smrg#include <X11/extensions/XInput2.h> 38c27c18e8Smrg#include <X11/extensions/extutil.h> 39c27c18e8Smrg#include <X11/extensions/ge.h> 40c27c18e8Smrg#include <X11/extensions/geproto.h> 41c27c18e8Smrg#include "XIint.h" 42c27c18e8Smrg 43c27c18e8Smrgint 44c27c18e8SmrgXISelectEvents(Display* dpy, Window win, XIEventMask* masks, int num_masks) 45c27c18e8Smrg{ 46c27c18e8Smrg XIEventMask *current; 47c27c18e8Smrg xXISelectEventsReq *req; 48c27c18e8Smrg xXIEventMask mask; 49c27c18e8Smrg int i; 50c27c18e8Smrg int len = 0; 513e256790Smrg int r = Success; 52c27c18e8Smrg 53c27c18e8Smrg XExtDisplayInfo *info = XInput_find_display(dpy); 54c27c18e8Smrg LockDisplay(dpy); 55b789ec8aSmrg if (_XiCheckExtInit(dpy, XInput_2_0, info) == -1) { 563e256790Smrg r = NoSuchExtension; 573e256790Smrg goto out; 583e256790Smrg } 59c27c18e8Smrg GetReq(XISelectEvents, req); 60c27c18e8Smrg 61c27c18e8Smrg req->reqType = info->codes->major_opcode; 62c27c18e8Smrg req->ReqType = X_XISelectEvents; 63c27c18e8Smrg req->win = win; 64c27c18e8Smrg req->num_masks = num_masks; 65c27c18e8Smrg 66c27c18e8Smrg /* get the right length */ 67c27c18e8Smrg for (i = 0; i < num_masks; i++) 68c27c18e8Smrg { 69c27c18e8Smrg len++; 70c27c18e8Smrg current = &masks[i]; 71c27c18e8Smrg len += (current->mask_len + 3)/4; 72c27c18e8Smrg } 73c27c18e8Smrg 74c27c18e8Smrg SetReqLen(req, len, len); 75c27c18e8Smrg 76c27c18e8Smrg for (i = 0; i < num_masks; i++) 77c27c18e8Smrg { 78c27c18e8Smrg char *buff; 79c27c18e8Smrg current = &masks[i]; 80c27c18e8Smrg mask.deviceid = current->deviceid; 81c27c18e8Smrg mask.mask_len = (current->mask_len + 3)/4; 82c27c18e8Smrg /* masks.mask_len is in bytes, but we need 4-byte units on the wire, 83c27c18e8Smrg * and they need to be padded with 0 */ 84c27c18e8Smrg buff = calloc(1, mask.mask_len * 4); 85c27c18e8Smrg memcpy(buff, current->mask, current->mask_len); 86b789ec8aSmrg Data(dpy, (char*)&mask, sizeof(xXIEventMask)); 87c27c18e8Smrg Data(dpy, buff, mask.mask_len * 4); 88c27c18e8Smrg free(buff); 89c27c18e8Smrg } 90c27c18e8Smrg 913e256790Smrgout: 92c27c18e8Smrg UnlockDisplay(dpy); 93c27c18e8Smrg SyncHandle(); 943e256790Smrg return r; 95c27c18e8Smrg 96c27c18e8Smrg} 97c27c18e8Smrg 98c27c18e8SmrgXIEventMask* 99c27c18e8SmrgXIGetSelectedEvents(Display* dpy, Window win, int *num_masks_return) 100c27c18e8Smrg{ 101c27c18e8Smrg int i, len = 0; 102c27c18e8Smrg unsigned char *mask; 103c27c18e8Smrg XIEventMask *mask_out = NULL; 104c27c18e8Smrg xXIEventMask *mask_in = NULL, *mi; 105c27c18e8Smrg xXIGetSelectedEventsReq *req; 106c27c18e8Smrg xXIGetSelectedEventsReply reply; 10737eb1ca1Smrg XExtDisplayInfo *info = XInput_find_display(dpy); 108c27c18e8Smrg 1093e256790Smrg *num_masks_return = -1; 110c27c18e8Smrg LockDisplay(dpy); 111b789ec8aSmrg if (_XiCheckExtInit(dpy, XInput_2_0, info) == -1) 1123e256790Smrg goto out; 113c27c18e8Smrg 114c27c18e8Smrg GetReq(XIGetSelectedEvents, req); 115c27c18e8Smrg 116c27c18e8Smrg req->reqType = info->codes->major_opcode; 117c27c18e8Smrg req->ReqType = X_XIGetSelectedEvents; 118c27c18e8Smrg req->win = win; 119c27c18e8Smrg 120c27c18e8Smrg if (!_XReply(dpy, (xReply *) &reply, 0, xFalse)) 1213e256790Smrg goto out; 122c27c18e8Smrg 123c27c18e8Smrg if (reply.num_masks == 0) 124c27c18e8Smrg { 125c27c18e8Smrg *num_masks_return = 0; 1263e256790Smrg goto out; 127c27c18e8Smrg } 128c27c18e8Smrg 129c27c18e8Smrg mask_in = Xmalloc(reply.length * 4); 130c27c18e8Smrg if (!mask_in) 1313e256790Smrg goto out; 132c27c18e8Smrg 133c27c18e8Smrg _XRead(dpy, (char*)mask_in, reply.length * 4); 134c27c18e8Smrg 135c27c18e8Smrg /* Memory layout of the XIEventMask for a 3 mask reply: 136c27c18e8Smrg * [struct a][struct b][struct c][masks a][masks b][masks c] 137c27c18e8Smrg */ 138c27c18e8Smrg len = reply.num_masks * sizeof(XIEventMask); 139c27c18e8Smrg 140c27c18e8Smrg for (i = 0, mi = mask_in; i < reply.num_masks; i++) 141c27c18e8Smrg { 142c27c18e8Smrg len += mi->mask_len * 4; 143c27c18e8Smrg mi = (xXIEventMask*)((char*)mi + mi->mask_len * 4); 144c27c18e8Smrg mi++; 145c27c18e8Smrg } 146c27c18e8Smrg 147c27c18e8Smrg mask_out = Xmalloc(len); 148c27c18e8Smrg if (!mask_out) 1493e256790Smrg goto out; 150c27c18e8Smrg 151c27c18e8Smrg mi = mask_in; 152c27c18e8Smrg mask = (unsigned char*)&mask_out[reply.num_masks]; 153c27c18e8Smrg for (i = 0; i < reply.num_masks; i++) 154c27c18e8Smrg { 155c27c18e8Smrg mask_out[i].deviceid = mi->deviceid; 156c27c18e8Smrg mask_out[i].mask_len = mi->mask_len * 4; 157c27c18e8Smrg mask_out[i].mask = mask; 158c27c18e8Smrg memcpy(mask_out[i].mask, &mi[1], mask_out[i].mask_len); 159c27c18e8Smrg mask += mask_out[i].mask_len; 160c27c18e8Smrg mi = (xXIEventMask*)((char*)mi + mi->mask_len * 4); 161c27c18e8Smrg mi++; 162c27c18e8Smrg } 163c27c18e8Smrg 164c27c18e8Smrg *num_masks_return = reply.num_masks; 165c27c18e8Smrg 1663e256790Smrgout: 1673e256790Smrg Xfree(mask_in); 168c27c18e8Smrg 169c27c18e8Smrg UnlockDisplay(dpy); 170c27c18e8Smrg SyncHandle(); 171c27c18e8Smrg 1723e256790Smrg return mask_out; 173c27c18e8Smrg} 174