1 /* antimicro Gamepad to KB+M event mapper
2 * Copyright (C) 2015 Travis Nickles <nickles.travis@gmail.com>
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18 //#include <QDebug>
19 #include <QDataStream>
20
21 #include <X11/Xlib.h>
22 #include <X11/cursorfont.h> // for XGrabPointer
23 #include "x11extras.h"
24 #include "qtx11keymapper.h"
25 #include "unixcapturewindowutility.h"
26
UnixCaptureWindowUtility(QObject * parent)27 UnixCaptureWindowUtility::UnixCaptureWindowUtility(QObject *parent) :
28 QObject(parent)
29 {
30 targetPath = "";
31 failed = false;
32 targetWindow = None;
33 }
34
35 /**
36 * @brief Attempt to capture window selected with the mouse
37 */
attemptWindowCapture()38 void UnixCaptureWindowUtility::attemptWindowCapture()
39 {
40 // Only create instance when needed.
41 static QtX11KeyMapper x11KeyMapper;
42
43 targetPath = "";
44 targetWindow = None;
45 failed = false;
46
47 bool escaped = false;
48
49 Cursor cursor;
50 Window target_window = None;
51 int status = 0;
52 Display *display = 0;
53
54 QString potentialXDisplayString = X11Extras::getInstance()->getXDisplayString();
55 if (!potentialXDisplayString.isEmpty())
56 {
57 QByteArray tempByteArray = potentialXDisplayString.toLocal8Bit();
58 display = XOpenDisplay(tempByteArray.constData());
59 }
60 else
61 {
62 display = XOpenDisplay(NULL);
63 }
64
65 Window rootWin = XDefaultRootWindow(display);
66
67 cursor = XCreateFontCursor(display, XC_crosshair);
68 status = XGrabPointer(display, rootWin, False, ButtonPressMask,
69 GrabModeSync, GrabModeAsync, None,
70 cursor, CurrentTime);
71 if (status == Success)
72 {
73 XGrabKey(display, XKeysymToKeycode(display, x11KeyMapper.returnVirtualKey(Qt::Key_Escape)), 0, rootWin,
74 true, GrabModeAsync, GrabModeAsync);
75
76 XEvent event;
77 XAllowEvents(display, SyncPointer, CurrentTime);
78 XWindowEvent(display, rootWin, ButtonPressMask|KeyPressMask, &event);
79 switch (event.type)
80 {
81 case (ButtonPress):
82 target_window = event.xbutton.subwindow;
83 if (target_window == None)
84 {
85 target_window = event.xbutton.window;
86 }
87
88 //qDebug() << QString::number(target_window, 16);
89 break;
90
91 case (KeyPress):
92 {
93 escaped = true;
94 break;
95 }
96 }
97
98 XUngrabKey(display, XKeysymToKeycode(display, x11KeyMapper.returnVirtualKey(Qt::Key_Escape)),
99 0, rootWin);
100 XUngrabPointer(display, CurrentTime);
101 XFlush(display);
102 }
103
104 if (target_window != None)
105 {
106 targetWindow = target_window;
107 }
108 else if (!escaped)
109 {
110 failed = true;
111 }
112
113 XCloseDisplay(display);
114 emit captureFinished();
115 }
116
117 /**
118 * @brief Get the saved path for a window
119 * @return Program path
120 */
getTargetPath()121 QString UnixCaptureWindowUtility::getTargetPath()
122 {
123 return targetPath;
124 }
125
126 /**
127 * @brief Check if attemptWindowCapture failed to obtain an application
128 * @return Error status
129 */
hasFailed()130 bool UnixCaptureWindowUtility::hasFailed()
131 {
132 return failed;
133 }
134
getTargetWindow()135 unsigned long UnixCaptureWindowUtility::getTargetWindow()
136 {
137 return targetWindow;
138 }
139