pcsxr-1.9.92
[pcsx_rearmed.git] / plugins / dfinput / xkb.c
1 /*
2  * Copyright (c) 2009, Wei Mingzhi <whistler@openoffice.org>.
3  * All Rights Reserved.
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, see <http://www.gnu.org/licenses>.
17  */
18
19 #include "pad.h"
20
21 static Atom wmprotocols, wmdelwindow;
22
23 void InitKeyboard() {
24         wmprotocols = XInternAtom(g.Disp, "WM_PROTOCOLS", 0);
25         wmdelwindow = XInternAtom(g.Disp, "WM_DELETE_WINDOW", 0);
26
27         XkbSetDetectableAutoRepeat(g.Disp, 1, NULL);
28
29         g.PadState[0].KeyStatus = 0xFFFF;
30         g.PadState[1].KeyStatus = 0xFFFF;
31 }
32
33 void DestroyKeyboard() {
34         XkbSetDetectableAutoRepeat(g.Disp, 0, NULL);
35 }
36
37 void CheckKeyboard() {
38         uint8_t                                 i, j, found;
39         XEvent                                  evt;
40         XClientMessageEvent             *xce;
41         uint16_t                                Key;
42
43         while (XPending(g.Disp)) {
44                 XNextEvent(g.Disp, &evt);
45                 switch (evt.type) {
46                         case KeyPress:
47                                 Key = XLookupKeysym((XKeyEvent *)&evt, 0);
48                                 found = 0;
49                                 for (i = 0; i < 2; i++) {
50                                         for (j = 0; j < DKEY_TOTAL; j++) {
51                                                 if (g.cfg.PadDef[i].KeyDef[j].Key == Key) {
52                                                         found = 1;
53                                                         g.PadState[i].KeyStatus &= ~(1 << j);
54                                                 }
55                                         }
56                                 }
57                                 if (!found && !AnalogKeyPressed(Key)) {
58                                         g.KeyLeftOver = Key;
59                                 }
60                                 return;
61
62                         case KeyRelease:
63                                 Key = XLookupKeysym((XKeyEvent *)&evt, 0);
64                                 found = 0;
65                                 for (i = 0; i < 2; i++) {
66                                         for (j = 0; j < DKEY_TOTAL; j++) {
67                                                 if (g.cfg.PadDef[i].KeyDef[j].Key == Key) {
68                                                         found = 1;
69                                                         g.PadState[i].KeyStatus |= (1 << j);
70                                                 }
71                                         }
72                                 }
73                                 if (!found && !AnalogKeyReleased(Key)) {
74                                         g.KeyLeftOver = ((long)Key | 0x40000000);
75                                 }
76                                 break;
77
78                         case ClientMessage:
79                                 xce = (XClientMessageEvent *)&evt;
80                                 if (xce->message_type == wmprotocols && (Atom)xce->data.l[0] == wmdelwindow) {
81                                         // Fake an ESC key if user clicked the close button on window
82                                         g.KeyLeftOver = XK_Escape;
83                                         return;
84                                 }
85                                 break;
86                 }
87         }
88 }