FreeCAD

Форк
0
/
GuiNativeEventLinuxX11.cpp 
146 строк · 5.3 Кб
1
/***************************************************************************
2
 *   Copyright (c) 2018 Torsten Sadowski <tsadowski[at]gmx.net>            *
3
 *                                                                         *
4
 *   This file is part of the FreeCAD CAx development system.              *
5
 *                                                                         *
6
 *   This library is free software; you can redistribute it and/or         *
7
 *   modify it under the terms of the GNU Library General Public           *
8
 *   License as published by the Free Software Foundation; either          *
9
 *   version 2 of the License, or (at your option) any later version.      *
10
 *                                                                         *
11
 *   This library  is distributed in the hope that it will be useful,      *
12
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
13
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
14
 *   GNU Library General Public License for more details.                  *
15
 *                                                                         *
16
 *   You should have received a copy of the GNU Library General Public     *
17
 *   License along with this library; see the file COPYING.LIB. If not,    *
18
 *   write to the Free Software Foundation, Inc., 59 Temple Place,         *
19
 *   Suite 330, Boston, MA  02111-1307, USA                                *
20
 *                                                                         *
21
 ***************************************************************************/
22

23
#include <FCConfig.h>
24
#include "SpaceballEvent.h"
25

26
#include <QMainWindow>
27

28
#include "GuiNativeEventLinuxX11.h"
29

30
#include "GuiApplicationNativeEventAware.h"
31
#include <Base/Console.h>
32

33
#include <QX11Info>
34
#include <spnav.h>
35

36
#include "GuiRawInputEventFilter.h"
37
#undef Bool
38
#undef CursorShape
39
#undef Expose
40
#undef KeyPress
41
#undef KeyRelease
42
#undef FocusIn
43
#undef FocusOut
44
#undef FontChange
45
#undef None
46
#undef Status
47
#undef Unsorted
48
#undef False
49
#undef True
50
#undef Complex
51

52

53
Gui::GuiNativeEvent::GuiNativeEvent(Gui::GUIApplicationNativeEventAware *app)
54
: GuiAbstractNativeEvent(app)
55
{
56
}
57

58
Gui::GuiNativeEvent::~GuiNativeEvent()
59
{
60
    if (spnav_close())
61
        Base::Console().Log("Couldn't disconnect from spacenav daemon\n");
62
    else
63
        Base::Console().Log("Disconnected from spacenav daemon\n");
64
}
65

66
void Gui::GuiNativeEvent::initSpaceball(QMainWindow *window)
67
{
68
    if (!QX11Info::isPlatformX11()) {
69
        Base::Console().Log("Application is not running on X11\n");
70
        return;
71
    }
72
    if (spnav_x11_open(QX11Info::display(), window->winId()) == -1) {
73
        Base::Console().Log("Couldn't connect to spacenav daemon on X11. Please ignore if you don't have a spacemouse.\n");
74
    } else {
75
        Base::Console().Log("Connected to spacenav daemon on X11\n");
76
        mainApp->setSpaceballPresent(true);
77
        mainApp->installNativeEventFilter(new Gui::RawInputEventFilter(&xcbEventFilter));
78
    }
79
}
80

81
bool Gui::GuiNativeEvent::xcbEventFilter(void *xcb_void, long* result)
82
{
83
    Q_UNUSED(result);
84
    auto inst(dynamic_cast<Gui::GUIApplicationNativeEventAware *>(QApplication::instance()));
85
    if (!inst)
86
      return false;
87

88
    spnav_event navEvent;
89

90
    const xcb_client_message_event_t* xcb_ev = static_cast<const xcb_client_message_event_t*>(xcb_void);
91
    // Qt4 used XEvents in native event filters, but Qt5 changed to XCB.  The
92
    // SpaceNavigator API only works with XEvent, so we need to construct a
93
    // temporary XEvent with just enough information for spnav_x11_event()
94
    if ((xcb_ev->response_type & 0x7F) == XCB_CLIENT_MESSAGE) {
95
        XClientMessageEvent xev;
96

97
        xev.type = ClientMessage;
98
        xev.message_type = xcb_ev->type;
99
        memcpy(xev.data.b, xcb_ev->data.data8, sizeof(xev.data.b));
100
        xev.serial = 0; // These are just to squash warnings...
101
        xev.send_event = 0;
102
        xev.display = 0;
103
        xev.window = 0;
104
        xev.format = 0;
105

106
        if (!spnav_x11_event(reinterpret_cast<XEvent *>(&xev), &navEvent)) {
107
            return false;
108
        }
109
    } else {
110
        return false;
111
    }
112
    // navEvent is now initialised
113

114
    switch (navEvent.type) {
115
        case SPNAV_EVENT_MOTION:
116
        {
117
            motionDataArray[0] = -navEvent.motion.x;
118
            motionDataArray[1] = -navEvent.motion.z;
119
            motionDataArray[2] = -navEvent.motion.y;
120
            motionDataArray[3] = -navEvent.motion.rx;
121
            motionDataArray[4] = -navEvent.motion.rz;
122
            motionDataArray[5] = -navEvent.motion.ry;
123

124
            inst->postMotionEvent(motionDataArray);
125
            return true;
126
        }
127

128
        case SPNAV_EVENT_BUTTON:
129
        {
130
            auto buttonEvent(new Spaceball::ButtonEvent());
131
            buttonEvent->setButtonNumber(navEvent.button.bnum);
132
            if (navEvent.button.press) {
133
                buttonEvent->setButtonStatus(Spaceball::BUTTON_PRESSED);
134
            } else {
135
                buttonEvent->setButtonStatus(Spaceball::BUTTON_RELEASED);
136
            }
137
            inst->postButtonEvent(navEvent.button.bnum, navEvent.button.press);
138
            return true;
139
        }
140
        default:
141
            Base::Console().Log("Unknown spaceball event\n");
142
            return true;
143
    } // end switch (navEvent.type) {
144
}
145

146
#include "3Dconnexion/moc_GuiNativeEventLinuxX11.cpp"
147

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.