XIProperties.c revision b789ec8a
1c27c18e8Smrg/* 2c27c18e8Smrg * Copyright © 2009 Red Hat, Inc. 3c27c18e8Smrg * 4c27c18e8Smrg * Permission is hereby granted, free of charge, to any person obtaining a 5c27c18e8Smrg * copy of this software and associated documentation files (the "Software"), 6c27c18e8Smrg * to deal in the Software without restriction, including without limitation 7c27c18e8Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8c27c18e8Smrg * and/or sell copies of the Software, and to permit persons to whom the 9c27c18e8Smrg * Software is furnished to do so, subject to the following conditions: 10c27c18e8Smrg * 11c27c18e8Smrg * The above copyright notice and this permission notice (including the next 12c27c18e8Smrg * paragraph) shall be included in all copies or substantial portions of the 13c27c18e8Smrg * Software. 14c27c18e8Smrg * 15c27c18e8Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16c27c18e8Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17c27c18e8Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18c27c18e8Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19c27c18e8Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20c27c18e8Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21c27c18e8Smrg * DEALINGS IN THE SOFTWARE. 22c27c18e8Smrg * 23c27c18e8Smrg */ 24c27c18e8Smrg 25c27c18e8Smrg/*********************************************************************** 26c27c18e8Smrg * XI2 property requests, list, change, delete and get properties. 27c27c18e8Smrg */ 28c27c18e8Smrg 29c27c18e8Smrg 30c27c18e8Smrg#ifdef HAVE_CONFIG_H 31c27c18e8Smrg#include <config.h> 32c27c18e8Smrg#endif 33c27c18e8Smrg 34c27c18e8Smrg#include <stdint.h> 35c27c18e8Smrg#include <X11/Xlibint.h> 36c27c18e8Smrg#include <X11/extensions/XI2.h> 37c27c18e8Smrg#include <X11/extensions/XI2proto.h> 38c27c18e8Smrg#include <X11/extensions/XInput2.h> 39c27c18e8Smrg#include <X11/extensions/extutil.h> 40c27c18e8Smrg#include "XIint.h" 41c27c18e8Smrg 42c27c18e8SmrgAtom* 43c27c18e8SmrgXIListProperties(Display* dpy, int deviceid, int *num_props_return) 44c27c18e8Smrg{ 45c27c18e8Smrg xXIListPropertiesReq *req; 46c27c18e8Smrg xXIListPropertiesReply rep; 47c27c18e8Smrg XExtDisplayInfo *info = XInput_find_display(dpy); 48c27c18e8Smrg Atom *props = NULL; 49c27c18e8Smrg 50c27c18e8Smrg LockDisplay(dpy); 51c27c18e8Smrg *num_props_return = 0; 52b789ec8aSmrg if (_XiCheckExtInit(dpy, XInput_2_0, info) == -1) 53c27c18e8Smrg goto cleanup; 54c27c18e8Smrg 55c27c18e8Smrg GetReq(XIListProperties, req); 56c27c18e8Smrg req->reqType = info->codes->major_opcode; 57c27c18e8Smrg req->ReqType = X_XIListProperties; 58c27c18e8Smrg req->deviceid = deviceid; 59c27c18e8Smrg 60c27c18e8Smrg if (!_XReply(dpy, (xReply*)&rep, 0, xFalse)) 61c27c18e8Smrg goto cleanup; 62c27c18e8Smrg 63c27c18e8Smrg if (rep.num_properties) { 64c27c18e8Smrg props = (Atom*)Xmalloc(rep.num_properties * sizeof(Atom)); 65c27c18e8Smrg if (!props) 66c27c18e8Smrg { 67c27c18e8Smrg _XEatData(dpy, rep.num_properties << 2); 68c27c18e8Smrg goto cleanup; 69c27c18e8Smrg } 70c27c18e8Smrg 71c27c18e8Smrg _XRead32(dpy, (long*)props, rep.num_properties << 2); 72c27c18e8Smrg } 73c27c18e8Smrg 74c27c18e8Smrg *num_props_return = rep.num_properties; 75c27c18e8Smrg 76c27c18e8Smrgcleanup: 77c27c18e8Smrg UnlockDisplay(dpy); 78c27c18e8Smrg SyncHandle(); 79c27c18e8Smrg return props; 80c27c18e8Smrg} 81c27c18e8Smrg 82c27c18e8Smrg 83c27c18e8Smrgvoid 84c27c18e8SmrgXIDeleteProperty(Display* dpy, int deviceid, Atom property) 85c27c18e8Smrg{ 86c27c18e8Smrg xXIDeletePropertyReq *req; 87c27c18e8Smrg 88c27c18e8Smrg XExtDisplayInfo *info = XInput_find_display(dpy); 89c27c18e8Smrg 90c27c18e8Smrg LockDisplay(dpy); 91b789ec8aSmrg if (_XiCheckExtInit(dpy, XInput_2_0, info) == -1) 92c27c18e8Smrg return; 93c27c18e8Smrg 94c27c18e8Smrg GetReq(XIDeleteProperty, req); 95c27c18e8Smrg req->reqType = info->codes->major_opcode; 96c27c18e8Smrg req->ReqType = X_XIDeleteProperty; 97c27c18e8Smrg req->deviceid = deviceid; 98c27c18e8Smrg req->property = property; 99c27c18e8Smrg 100c27c18e8Smrg UnlockDisplay(dpy); 101c27c18e8Smrg SyncHandle(); 102c27c18e8Smrg} 103c27c18e8Smrg 104c27c18e8Smrgvoid 105c27c18e8SmrgXIChangeProperty(Display* dpy, int deviceid, Atom property, Atom type, 106c27c18e8Smrg int format, int mode, unsigned char *data, int num_items) 107c27c18e8Smrg{ 108c27c18e8Smrg xXIChangePropertyReq *req; 109c27c18e8Smrg int len; 110c27c18e8Smrg 111c27c18e8Smrg XExtDisplayInfo *info = XInput_find_display(dpy); 112c27c18e8Smrg 113c27c18e8Smrg LockDisplay(dpy); 114b789ec8aSmrg if (_XiCheckExtInit(dpy, XInput_2_0, info) == -1) 115c27c18e8Smrg return; 116c27c18e8Smrg 117c27c18e8Smrg GetReq(XIChangeProperty, req); 118c27c18e8Smrg req->reqType = info->codes->major_opcode; 119c27c18e8Smrg req->ReqType = X_XIChangeProperty; 120c27c18e8Smrg req->deviceid = deviceid; 121c27c18e8Smrg req->property = property; 122c27c18e8Smrg req->type = type; 123c27c18e8Smrg req->mode = mode; 124c27c18e8Smrg if (num_items < 0) { 125c27c18e8Smrg req->num_items = 0; 126c27c18e8Smrg req->format = 0; /* ask for garbage, get garbage */ 127c27c18e8Smrg } else { 128c27c18e8Smrg req->num_items = num_items; 129c27c18e8Smrg req->format = format; 130c27c18e8Smrg } 131c27c18e8Smrg 132c27c18e8Smrg switch (req->format) { 133c27c18e8Smrg case 8: 134c27c18e8Smrg len = (num_items + 3)/4; 135c27c18e8Smrg SetReqLen(req, len, len); 136c27c18e8Smrg len = num_items; 137c27c18e8Smrg break; 138c27c18e8Smrg 139c27c18e8Smrg case 16: 140c27c18e8Smrg len = (num_items + 1)/2; 141c27c18e8Smrg SetReqLen(req, len, len); 142c27c18e8Smrg len = num_items * 2; 143c27c18e8Smrg break; 144c27c18e8Smrg 145c27c18e8Smrg case 32: 146c27c18e8Smrg len = num_items; 147c27c18e8Smrg SetReqLen(req, len, len); 148c27c18e8Smrg len = num_items * 4; 149c27c18e8Smrg break; 150c27c18e8Smrg 151c27c18e8Smrg default: 152c27c18e8Smrg /* BadValue will be generated */ ; 1533e256790Smrg len = 0; 154c27c18e8Smrg } 155c27c18e8Smrg 156c27c18e8Smrg /* we use data instead of Data32 and friends to avoid Xlib's braindead 157c27c18e8Smrg * 64 bit handling.*/ 158c27c18e8Smrg 159c27c18e8Smrg Data(dpy, (const char*)data, len); 160c27c18e8Smrg UnlockDisplay(dpy); 161c27c18e8Smrg SyncHandle(); 162c27c18e8Smrg} 163c27c18e8Smrg 164c27c18e8SmrgStatus 165c27c18e8SmrgXIGetProperty(Display* dpy, int deviceid, Atom property, long offset, 166c27c18e8Smrg long length, Bool delete_property, Atom type, 167c27c18e8Smrg Atom *type_return, int *format_return, 168c27c18e8Smrg unsigned long *num_items_return,unsigned long *bytes_after_return, 169c27c18e8Smrg unsigned char **data) 170c27c18e8Smrg{ 171c27c18e8Smrg xXIGetPropertyReq *req; 172c27c18e8Smrg xXIGetPropertyReply rep; 173c27c18e8Smrg long nbytes, rbytes; 174c27c18e8Smrg 175c27c18e8Smrg XExtDisplayInfo *info = XInput_find_display(dpy); 176c27c18e8Smrg 177c27c18e8Smrg LockDisplay(dpy); 178b789ec8aSmrg if (_XiCheckExtInit(dpy, XInput_2_0, info) == -1) 179c27c18e8Smrg return 1; 180c27c18e8Smrg 181c27c18e8Smrg GetReq(XIGetProperty, req); 182c27c18e8Smrg req->reqType = info->codes->major_opcode; 183c27c18e8Smrg req->ReqType = X_XIGetProperty; 184c27c18e8Smrg req->deviceid = deviceid; 185c27c18e8Smrg req->property = property; 186c27c18e8Smrg req->type = type; 187c27c18e8Smrg req->offset = offset; 188c27c18e8Smrg req->len = length; 189c27c18e8Smrg req->delete = delete_property; 190c27c18e8Smrg 191c27c18e8Smrg if (!_XReply (dpy, (xReply *) &rep, 0, xFalse)) 192c27c18e8Smrg { 193c27c18e8Smrg UnlockDisplay (dpy); 194c27c18e8Smrg SyncHandle (); 195c27c18e8Smrg return 1; 196c27c18e8Smrg } 197c27c18e8Smrg 198c27c18e8Smrg *data = NULL; 199c27c18e8Smrg 200c27c18e8Smrg if (rep.type != None) { 201c27c18e8Smrg if (rep.format != 8 && rep.format != 16 && rep.format != 32) { 202c27c18e8Smrg /* 203c27c18e8Smrg * This part of the code should never be reached. If it is, 204c27c18e8Smrg * the server sent back a property with an invalid format. 205c27c18e8Smrg */ 206c27c18e8Smrg nbytes = rep.length << 2; 207c27c18e8Smrg _XEatData(dpy, nbytes); 208c27c18e8Smrg UnlockDisplay(dpy); 209c27c18e8Smrg SyncHandle(); 210c27c18e8Smrg return(BadImplementation); 211c27c18e8Smrg } 212c27c18e8Smrg 213c27c18e8Smrg /* 214c27c18e8Smrg * One extra byte is malloced than is needed to contain the property 215c27c18e8Smrg * data, but this last byte is null terminated and convenient for 216c27c18e8Smrg * returning string properties, so the client doesn't then have to 217c27c18e8Smrg * recopy the string to make it null terminated. 218c27c18e8Smrg */ 219c27c18e8Smrg 220c27c18e8Smrg nbytes = rep.num_items * rep.format/8; 221c27c18e8Smrg rbytes = nbytes + 1; 222c27c18e8Smrg *data = Xmalloc(rbytes); 223c27c18e8Smrg 224c27c18e8Smrg if (!(*data)) { 225c27c18e8Smrg _XEatData(dpy, nbytes); 226c27c18e8Smrg UnlockDisplay(dpy); 227c27c18e8Smrg SyncHandle(); 228c27c18e8Smrg return(BadAlloc); 229c27c18e8Smrg } 230c27c18e8Smrg 231c27c18e8Smrg _XReadPad (dpy, (char *)*data, nbytes); 232c27c18e8Smrg (*data)[rbytes - 1] = '\0'; 233c27c18e8Smrg } 234c27c18e8Smrg 235c27c18e8Smrg *type_return = rep.type; 236c27c18e8Smrg *format_return = rep.format; 237c27c18e8Smrg *num_items_return = rep.num_items; 238c27c18e8Smrg *bytes_after_return = rep.bytes_after; 239c27c18e8Smrg UnlockDisplay (dpy); 240c27c18e8Smrg SyncHandle(); 241c27c18e8Smrg return Success; 242c27c18e8Smrg} 243