1/*
2 * Copyright 2008 Red Hat, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 *
23 * Author: Peter Hutterer
24 */
25/***********************************************************************
26 *
27 * Request to set and get an input device's focus.
28 *
29 */
30
31#ifdef HAVE_DIX_CONFIG_H
32#include <dix-config.h>
33#endif
34
35#include "inputstr.h"           /* DeviceIntPtr      */
36#include "windowstr.h"          /* window structure  */
37#include <X11/extensions/XI2.h>
38#include <X11/extensions/XI2proto.h>
39
40#include "exglobals.h"          /* BadDevice */
41#include "xisetdevfocus.h"
42
43int _X_COLD
44SProcXISetFocus(ClientPtr client)
45{
46    REQUEST(xXISetFocusReq);
47    REQUEST_AT_LEAST_SIZE(xXISetFocusReq);
48
49    swaps(&stuff->length);
50    swaps(&stuff->deviceid);
51    swapl(&stuff->focus);
52    swapl(&stuff->time);
53
54    return ProcXISetFocus(client);
55}
56
57int _X_COLD
58SProcXIGetFocus(ClientPtr client)
59{
60    REQUEST(xXIGetFocusReq);
61    REQUEST_AT_LEAST_SIZE(xXIGetFocusReq);
62
63    swaps(&stuff->length);
64    swaps(&stuff->deviceid);
65
66    return ProcXIGetFocus(client);
67}
68
69int
70ProcXISetFocus(ClientPtr client)
71{
72    DeviceIntPtr dev;
73    int ret;
74
75    REQUEST(xXISetFocusReq);
76    REQUEST_AT_LEAST_SIZE(xXISetFocusReq);
77
78    ret = dixLookupDevice(&dev, stuff->deviceid, client, DixSetFocusAccess);
79    if (ret != Success)
80        return ret;
81    if (!dev->focus)
82        return BadDevice;
83
84    return SetInputFocus(client, dev, stuff->focus, RevertToParent,
85                         stuff->time, TRUE);
86}
87
88int
89ProcXIGetFocus(ClientPtr client)
90{
91    xXIGetFocusReply rep;
92    DeviceIntPtr dev;
93    int ret;
94
95    REQUEST(xXIGetFocusReq);
96    REQUEST_AT_LEAST_SIZE(xXIGetFocusReq);
97
98    ret = dixLookupDevice(&dev, stuff->deviceid, client, DixGetFocusAccess);
99    if (ret != Success)
100        return ret;
101    if (!dev->focus)
102        return BadDevice;
103
104    rep = (xXIGetFocusReply) {
105        .repType = X_Reply,
106        .RepType = X_XIGetFocus,
107        .sequenceNumber = client->sequence,
108        .length = 0
109    };
110
111    if (dev->focus->win == NoneWin)
112        rep.focus = None;
113    else if (dev->focus->win == PointerRootWin)
114        rep.focus = PointerRoot;
115    else if (dev->focus->win == FollowKeyboardWin)
116        rep.focus = FollowKeyboard;
117    else
118        rep.focus = dev->focus->win->drawable.id;
119
120    WriteReplyToClient(client, sizeof(xXIGetFocusReply), &rep);
121    return Success;
122}
123
124void
125SRepXIGetFocus(ClientPtr client, int len, xXIGetFocusReply * rep)
126{
127    swaps(&rep->sequenceNumber);
128    swapl(&rep->length);
129    swapl(&rep->focus);
130    WriteToClient(client, len, rep);
131}
132