Home | History | Annotate | Line # | Download | only in src
      1 /************************************************************
      2 
      3 Copyright 2007 Peter Hutterer <peter (at) cs.unisa.edu.au>
      4 
      5 Permission to use, copy, modify, distribute, and sell this software and its
      6 documentation for any purpose is hereby granted without fee, provided that
      7 the above copyright notice appear in all copies and that both that
      8 copyright notice and this permission notice appear in supporting
      9 documentation.
     10 
     11 The above copyright notice and this permission notice shall be included in
     12 all copies or substantial portions of the Software.
     13 
     14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
     17 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
     18 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
     19 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     20 
     21 Except as contained in this notice, the name of The Open Group shall not be
     22 used in advertising or otherwise to promote the sale, use or other dealings
     23 in this Software without prior written authorization from The Open Group.
     24 
     25 */
     26 
     27 /***********************************************************************
     28  *
     29  * XIChangeHierarchy - change the device hierarchy, i.e. which slave
     30  * device is attached to which master, etc.
     31  */
     32 #ifdef HAVE_CONFIG_H
     33 #include <config.h>
     34 #endif
     35 
     36 #include <stdint.h>
     37 #include <X11/extensions/XI2proto.h>
     38 #include <X11/Xlibint.h>
     39 #include <X11/extensions/XInput2.h>
     40 #include <X11/extensions/extutil.h>
     41 #include "XIint.h"
     42 
     43 int
     44 XIChangeHierarchy(Display* dpy,
     45                         XIAnyHierarchyChangeInfo* changes,
     46                         int num_changes)
     47 {
     48     XIAnyHierarchyChangeInfo* any;
     49     xXIChangeHierarchyReq *req;
     50     XExtDisplayInfo *info = XInput_find_display(dpy);
     51     char *data = NULL, *dptr;
     52     int dlen = 0, i, ret = Success;
     53 
     54     LockDisplay(dpy);
     55     if (_XiCheckExtInit(dpy, XInput_2_0, info) == -1)
     56 	return (NoSuchExtension);
     57 
     58     if (num_changes <= 0)
     59         goto out;
     60 
     61     GetReq(XIChangeHierarchy, req);
     62     req->reqType = info->codes->major_opcode;
     63     req->ReqType = X_XIChangeHierarchy;
     64     req->num_changes = num_changes;
     65 
     66     /* alloc required memory */
     67     for (i = 0, any = changes; i < num_changes; i++, any++)
     68     {
     69         switch(any->type)
     70         {
     71             case XIAddMaster:
     72                 {
     73                     int slen = (strlen(any->add.name));
     74                     dlen += sizeof(xXIAddMasterInfo) +
     75                         slen + (4 - (slen % 4));
     76                 }
     77                 break;
     78             case XIRemoveMaster:
     79                 dlen += sizeof(xXIRemoveMasterInfo);
     80                 break;
     81             case XIAttachSlave:
     82                 dlen += sizeof(xXIAttachSlaveInfo);
     83                 break;
     84             case XIDetachSlave:
     85                 dlen += sizeof(xXIDetachSlaveInfo);
     86                 break;
     87             default:
     88                 return BadValue;
     89         }
     90     }
     91 
     92     req->length += dlen / 4; /* dlen is 4-byte aligned */
     93     data = Xmalloc(dlen);
     94     if (!data) {
     95         ret = BadAlloc;
     96         goto out;
     97     }
     98 
     99     dptr = data;
    100     for (i = 0, any = changes; i < num_changes; i++, any++)
    101     {
    102         switch(any->type)
    103         {
    104                 case XIAddMaster:
    105                 {
    106                     XIAddMasterInfo* C = &any->add;
    107                     xXIAddMasterInfo* c = (xXIAddMasterInfo*)dptr;
    108                     c->type = C->type;
    109                     c->send_core = C->send_core;
    110                     c->enable = C->enable;
    111                     c->name_len = strlen(C->name);
    112                     c->length = (sizeof(xXIAddMasterInfo) + c->name_len + 3)/4;
    113                     strncpy((char*)&c[1], C->name, c->name_len);
    114                     dptr += 4 * c->length;
    115                 }
    116                 break;
    117             case XIRemoveMaster:
    118                 {
    119                     XIRemoveMasterInfo* R = &any->remove;
    120                     xXIRemoveMasterInfo* r = (xXIRemoveMasterInfo*)dptr;
    121                     r->type = R->type;
    122                     r->return_mode = R->return_mode;
    123                     r->deviceid = R->deviceid;
    124                     r->length = sizeof(xXIRemoveMasterInfo)/4;
    125                     if (r->return_mode == XIAttachToMaster)
    126                     {
    127                         r->return_pointer = R->return_pointer;
    128                         r->return_keyboard = R->return_keyboard;
    129                     }
    130                     dptr += sizeof(xXIRemoveMasterInfo);
    131                 }
    132                 break;
    133             case XIAttachSlave:
    134                 {
    135                     XIAttachSlaveInfo* C = &any->attach;
    136                     xXIAttachSlaveInfo* c = (xXIAttachSlaveInfo*)dptr;
    137 
    138                     c->type = C->type;
    139                     c->deviceid = C->deviceid;
    140                     c->length = sizeof(xXIAttachSlaveInfo)/4;
    141                     c->new_master = C->new_master;
    142 
    143                     dptr += sizeof(xXIAttachSlaveInfo);
    144                 }
    145                 break;
    146             case XIDetachSlave:
    147                 {
    148                     XIDetachSlaveInfo *D = &any->detach;
    149                     xXIDetachSlaveInfo *d = (xXIDetachSlaveInfo*)dptr;
    150 
    151                     d->type = D->type;
    152                     d->deviceid = D->deviceid;
    153                     d->length = sizeof(xXIDetachSlaveInfo)/4;
    154                     dptr += sizeof(xXIDetachSlaveInfo);
    155                 }
    156         }
    157     }
    158 
    159     Data(dpy, data, dlen);
    160 
    161 out:
    162     Xfree(data);
    163     UnlockDisplay(dpy);
    164     SyncHandle();
    165     return ret;
    166 }
    167