summaryrefslogtreecommitdiff
path: root/src/bin/e_grabinput.c
blob: a67d39f36df5f4a80678b7f6fc4305eeef13c689 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
#include "e.h"

/* local subsystem functions */
static void      _e_grabinput_focus_do(Ecore_Window win, E_Focus_Method method);
static void      _e_grabinput_focus(Ecore_Window win, E_Focus_Method method);

/* local subsystem globals */
static Ecore_Window grab_mouse_win = 0;
static Ecore_Window grab_key_win = 0;
static Ecore_Window focus_win = 0;
static E_Focus_Method focus_method = E_FOCUS_METHOD_NO_INPUT;
static double last_focus_time = 0.0;

static Ecore_Window focus_fix_win = 0;
static E_Focus_Method focus_fix_method = E_FOCUS_METHOD_NO_INPUT;

/* externally accessible functions */
EINTERN int
e_grabinput_init(void)
{
   return 1;
}

EINTERN int
e_grabinput_shutdown(void)
{
   return 1;
}

E_API int
e_grabinput_get(Ecore_Window mouse_win, int confine_mouse, Ecore_Window key_win)
{
   if (grab_mouse_win)
     {
#ifndef HAVE_WAYLAND_ONLY
        if (e_comp->comp_type == E_PIXMAP_TYPE_X)
          ecore_x_pointer_ungrab();
#endif
        grab_mouse_win = 0;
     }
   if (grab_key_win)
     {
#ifndef HAVE_WAYLAND_ONLY
        if (e_comp->comp_type == E_PIXMAP_TYPE_X)
          ecore_x_keyboard_ungrab();
#endif

        grab_key_win = 0;
        focus_win = 0;
     }
   if (mouse_win)
     {
#ifndef HAVE_WAYLAND_ONLY
        if (e_comp->comp_type == E_PIXMAP_TYPE_X)
          {
             int ret = 0;
             if (confine_mouse)
               ret = ecore_x_pointer_confine_grab(mouse_win);
             else
               ret = ecore_x_pointer_grab(mouse_win);
             if (!ret) return 0;
          }
#endif
        grab_mouse_win = mouse_win;
     }
   if (key_win)
     {
#ifndef HAVE_WAYLAND_ONLY
        if (e_comp->comp_type == E_PIXMAP_TYPE_X)
          {
             int ret = 0;

             ret = ecore_x_keyboard_grab(key_win);
             if (!ret)
               {
                  if (grab_mouse_win)
                    {
                       ecore_x_pointer_ungrab();
                       grab_mouse_win = 0;
                    }
                  return 0;
               }
          }
#endif
        grab_key_win = key_win;
     }
#ifdef HAVE_WAYLAND_ONLY
   (void)confine_mouse;
#endif
   return 1;
}

E_API void
e_grabinput_release(Ecore_Window mouse_win, Ecore_Window key_win)
{
   if (mouse_win == grab_mouse_win)
     {
#ifndef HAVE_WAYLAND_ONLY
        if (e_comp->comp_type == E_PIXMAP_TYPE_X)
          ecore_x_pointer_ungrab();
#endif

        grab_mouse_win = 0;
     }
   if (key_win == grab_key_win)
     {
#ifndef HAVE_WAYLAND_ONLY
        if (e_comp->comp_type == E_PIXMAP_TYPE_X)
          ecore_x_keyboard_ungrab();
#endif

        grab_key_win = 0;
        if (focus_win != 0)
          {
             /* fprintf(stderr, "release focus to %x\n", focus_win); */
             _e_grabinput_focus(focus_win, focus_method);
             focus_win = 0;
             focus_method = E_FOCUS_METHOD_NO_INPUT;
          }
     }
}

E_API void
e_grabinput_focus(Ecore_Window win, E_Focus_Method method)
{
   if (grab_key_win != 0)
     {
        /* fprintf(stderr, "while grabbed focus changed to %x\n", win); */
        focus_win = win;
        focus_method = method;
     }
   else
     {
        /* fprintf(stderr, "focus to %x\n", win); */
        _e_grabinput_focus(win, method);
     }
}

E_API double
e_grabinput_last_focus_time_get(void)
{
   return last_focus_time;
}

E_API Ecore_Window
e_grabinput_last_focus_win_get(void)
{
   return focus_fix_win;
}

E_API Ecore_Window
e_grabinput_key_win_get(void)
{
   return grab_key_win;
}

E_API Ecore_Window
e_grabinput_mouse_win_get(void)
{
   return grab_mouse_win;
}

static void
_e_grabinput_focus_do(Ecore_Window win, E_Focus_Method method)
{
   /* fprintf(stderr, "focus to %x method %i\n", win, method); */
   switch (method)
     {
      case E_FOCUS_METHOD_NO_INPUT:
        break;

      case E_FOCUS_METHOD_LOCALLY_ACTIVE:
#ifndef HAVE_WAYLAND_ONLY
        if (e_comp_util_has_x())
          {
             ecore_x_window_focus_at_time(win, ecore_x_current_time_get());
             ecore_x_icccm_take_focus_send(win, ecore_x_current_time_get());
          }
#endif
        break;

      case E_FOCUS_METHOD_GLOBALLY_ACTIVE:
#ifndef HAVE_WAYLAND_ONLY
        if (e_comp_util_has_x())
          ecore_x_icccm_take_focus_send(win, ecore_x_current_time_get());
#endif
        break;

      case E_FOCUS_METHOD_PASSIVE:
#ifndef HAVE_WAYLAND_ONLY
        if (e_comp_util_has_x())
          ecore_x_window_focus_at_time(win, ecore_x_current_time_get());
#endif
        break;

      default:
        break;
     }
}

static void
_e_grabinput_focus(Ecore_Window win, E_Focus_Method method)
{
   focus_fix_win = win;
   focus_fix_method = method;
   /* fprintf(stderr, "foc do 1\n"); */
   _e_grabinput_focus_do(win, method);
   last_focus_time = ecore_loop_time_get();
}