Skip to content

Commit 82fb68e

Browse files
authored
Merge pull request #93 from Philip-Scott/JoyCon-testing
Added Controller support to control slides
2 parents 29e7248 + 133e2d1 commit 82fb68e

23 files changed

Lines changed: 1200 additions & 1 deletion

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
src/config.vala
22
build/
3+
*~

CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,18 @@ set (PKG_DEPS
2121
gee-0.8
2222
gtk+-3.0>=3.9.10
2323
json-glib-1.0
24+
gudev-1.0
25+
libevdev
2426
)
2527
2628
set (VALA_DEPS
2729
granite
2830
gee-0.8
2931
gtk+-3.0
3032
json-glib-1.0
33+
gudev-1.0
34+
libevdev
35+
linux
3136
)
3237
3338
find_package(PkgConfig)

debian/control

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ Build-Depends: cmake,
88
valac (>= 0.26),
99
libgranite-dev,
1010
libjson-glib-dev
11+
gudev-1.0-dev
12+
libevdev-dev
1113

1214
Standards-Version: 3.9.6
1315
Package: com.github.philip-scott.spice-up

src/CMakeLists.txt

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ vala_precompile(VALA_C
1212
Services/FileManager.vala
1313
Services/HistoryManager.vala
1414
Services/Utils.vala
15+
Services/GamepadSlideController.vala
1516
Widgets/Canvas.vala
1617
Widgets/ColorButton.vala
1718
Widgets/EntryCombo.vala
@@ -33,13 +34,29 @@ vala_precompile(VALA_C
3334
Widgets/Toolbars/TextBar.vala
3435
Widgets/Toolbars/Toolbar.vala
3536
#${CMAKE_CURRENT_BINARY_DIR}/config.vala
37+
38+
# LibGamepad
39+
Services/libgamepad/libgamepad.vala
40+
Services/libgamepad/gamepad-monitor.vala
41+
Services/libgamepad/gamepad.vala
42+
Services/libgamepad/helpers.vala
43+
Services/libgamepad/input-type.vala
44+
Services/libgamepad/raw-gamepad-interface.vala
45+
Services/libgamepad/raw-gamepad-monitor-interface.vala
46+
Services/libgamepad/standard-gamepad-axis.vala
47+
Services/libgamepad/standard-gamepad-button.vala
48+
49+
Services/libgamepad/drivers/linux/guid-helpers.vala
50+
Services/libgamepad/drivers/linux/raw-gamepad.vala
51+
Services/libgamepad/drivers/linux/raw-gamepad-monitor.vala
3652
PACKAGES
3753
${VALA_DEPS}
3854
OPTIONS
3955
${GLOBAL_VALAC_OPTIONS}
4056
-g
4157
--thread
4258
--target-glib=2.38 # FIXME check before, and target the same version
59+
--vapidir=${CMAKE_SOURCE_DIR}/vapi
4360
)
4461

4562
add_executable(spice-up ${VALA_C})
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
/*
2+
* Copyright (c) 2017 Felipe Escoto (https://github.com/Philip-Scott/Spice-up)
3+
*
4+
* This program is free software; you can redistribute it and/or
5+
* modify it under the terms of the GNU General Public
6+
* License as published by the Free Software Foundation; either
7+
* version 2 of the License, or (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 GNU
12+
* General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU General Public
15+
* License along with this program; if not, write to the
16+
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17+
* Boston, MA 02111-1307, USA.
18+
*
19+
* Authored by: Felipe Escoto <felescoto95@hotmail.com>
20+
*/
21+
22+
public class Spice.GamepadSlideController : Object {
23+
private static GamepadSlideController? instance = null;
24+
private unowned SlideManager slide_manager;
25+
26+
private LibGamepad.GamepadMonitor gamepad_monitor;
27+
private LibGamepad.Gamepad[] gamepads = {};
28+
29+
public static void startup (SlideManager _slide_manager) {
30+
if (instance == null) {
31+
instance = new GamepadSlideController ();
32+
}
33+
34+
instance.slide_manager = _slide_manager;
35+
}
36+
37+
private GamepadSlideController () {
38+
gamepad_monitor = new LibGamepad.GamepadMonitor ();
39+
40+
// On plugin, connect signals to the gamepad and store it in the gamepads array so it is not deleted by reference counting
41+
gamepad_monitor.gamepad_plugged.connect ((gamepad) => {
42+
print (@"GM Plugged in $(gamepad.raw_gamepad.identifier)- $(gamepad.raw_name)\n");
43+
gamepads += gamepad;
44+
// Bind events
45+
gamepad.button_event.connect (button_event);
46+
//gamepad.axis_event.connect ((axis, value) => print (@"$(gamepad.raw_name) - $(axis.to_string ()) - $value\n"));
47+
gamepad.unplugged.connect (() => print (@"$(gamepad.raw_name) - G Unplugged\n"));
48+
});
49+
50+
// Initialize initially plugged in gamepads
51+
gamepad_monitor.foreach_gamepad ((gamepad) => {
52+
print (@"GM Initially Plugged in $(gamepad.raw_gamepad.identifier) - $(gamepad.guid) - $(gamepad.raw_name)\n");
53+
gamepads += gamepad;
54+
// Bind events
55+
gamepad.button_event.connect (button_event);
56+
//gamepad.axis_event.connect ((axis, value) => print (@"$(gamepad.name) - $(axis.to_string ()) - $value\n"));
57+
gamepad.unplugged.connect (() => print (@"$(gamepad.raw_name) - G Unplugged\n"));
58+
});
59+
}
60+
61+
private void button_event (int button) {
62+
debug ("Gamepad Button event: %d\n", button);
63+
64+
switch (button) {
65+
case 0:
66+
next_slide ();
67+
break;
68+
case 2:
69+
previous_slide ();
70+
break;
71+
case 12:
72+
toggle_present ();
73+
break;
74+
case 1:
75+
jump_to_checkpoint ();
76+
break;
77+
case 3:
78+
set_checkpoint ();
79+
break;
80+
}
81+
}
82+
83+
private void jump_to_checkpoint () {
84+
this.slide_manager.jump_to_checkpoint ();
85+
}
86+
87+
private void set_checkpoint () {
88+
this.slide_manager.set_checkpoint ();
89+
}
90+
91+
private void next_slide () {
92+
if (window.is_fullscreen) {
93+
this.slide_manager.next_slide ();
94+
}
95+
}
96+
97+
private void previous_slide () {
98+
if (window.is_fullscreen) {
99+
this.slide_manager.previous_slide ();
100+
}
101+
}
102+
103+
private void toggle_present () {
104+
if (window.is_fullscreen) {
105+
window.unfullscreen ();
106+
} else {
107+
window.fullscreen ();
108+
}
109+
}
110+
}

src/Services/SlideManager.vala

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,24 @@ public class Spice.SlideManager : Object {
5353
}
5454
}
5555

56+
5657
public SlideManager () {
5758
slideshow = new Gtk.Stack ();
5859
slides = new Gee.ArrayList<Slide> ();
60+
61+
GamepadSlideController.startup (this);
62+
63+
/*joycon.output_changed.connect ((text) => {
64+
stderr.printf (text);
65+
66+
67+
});
68+
69+
joycon.done.connect ((i) => {
70+
stderr.printf ("Done :(\n");
71+
});
72+
73+
joycon.run ();*/
5974
}
6075

6176
public void reset () {
@@ -248,5 +263,22 @@ public class Spice.SlideManager : Object {
248263

249264
return item;
250265
}
266+
267+
public Slide? checkpoint = null;
268+
public void jump_to_checkpoint () {
269+
if (!window.is_fullscreen) return;
270+
271+
if (checkpoint != null) {
272+
var temp = checkpoint;
273+
checkpoint = current_slide;
274+
current_slide = temp;
275+
}
276+
}
277+
278+
public void set_checkpoint () {
279+
if (!window.is_fullscreen) return;
280+
281+
checkpoint = current_slide;
282+
}
251283
}
252284

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/*
2+
* Copyright 2016 Megh Parikh
3+
*
4+
* This file is part of LibGamepad.
5+
*
6+
* LibGamepad is free software: you can redistribute it and/or modify
7+
* it under the terms of the GNU Lesser General Public License as published by
8+
* the Free Software Foundation, either version 3 of the License, or
9+
* (at your option) any later version.
10+
*
11+
* LibGamepad 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 Lesser General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU Lesser General Public License
17+
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
18+
*/
19+
20+
private class LibGamepad.LinuxGuidHelpers : Object {
21+
public static string from_dev (Libevdev.Evdev dev) {
22+
uint16 guid[8];
23+
guid[0] = (uint16) dev.id_bustype.to_little_endian ();
24+
guid[1] = 0;
25+
guid[2] = (uint16) dev.id_vendor.to_little_endian ();
26+
guid[3] = 0;
27+
guid[4] = (uint16) dev.id_product.to_little_endian ();
28+
guid[5] = 0;
29+
guid[6] = (uint16) dev.id_version.to_little_endian ();
30+
guid[7] = 0;
31+
return uint16s_to_hex_string (guid);
32+
}
33+
34+
public static string from_file (string file_name) throws FileError {
35+
var fd = Posix.open (file_name, Posix.O_RDONLY | Posix.O_NONBLOCK);
36+
37+
if (fd < 0)
38+
throw new FileError.FAILED (@"Unable to open file $file_name: $(Posix.strerror (Posix.errno))");
39+
40+
var dev = new Libevdev.Evdev ();
41+
if (dev.set_fd (fd) < 0)
42+
throw new FileError.FAILED (@"Evdev error on opening file $file_name: $(Posix.strerror (Posix.errno))");
43+
44+
var guid = from_dev (dev);
45+
Posix.close (fd);
46+
return guid;
47+
}
48+
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/*
2+
* Copyright 2016 Megh Parikh
3+
*
4+
* This file is part of LibGamepad.
5+
*
6+
* LibGamepad is free software: you can redistribute it and/or modify
7+
* it under the terms of the GNU Lesser General Public License as published by
8+
* the Free Software Foundation, either version 3 of the License, or
9+
* (at your option) any later version.
10+
*
11+
* LibGamepad 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 Lesser General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU Lesser General Public License
17+
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
18+
*/
19+
20+
private class LibGamepad.LinuxRawGamepadMonitor : Object, RawGamepadMonitor {
21+
public delegate void RawGamepadCallback (RawGamepad raw_gamepad);
22+
23+
private GUdev.Client client;
24+
25+
public LinuxRawGamepadMonitor () {
26+
client = new GUdev.Client ({"input"});
27+
client.uevent.connect (handle_udev_client_callback);
28+
}
29+
30+
public void foreach_gamepad (RawGamepadCallback callback) {
31+
client.query_by_subsystem ("input").foreach ((dev) => {
32+
if (dev.get_device_file () == null)
33+
return;
34+
var identifier = dev.get_device_file ();
35+
if ((dev.has_property ("ID_INPUT_JOYSTICK") && dev.get_property ("ID_INPUT_JOYSTICK") == "1") ||
36+
(dev.has_property (".INPUT_CLASS") && dev.get_property (".INPUT_CLASS") == "joystick")) {
37+
RawGamepad raw_gamepad;
38+
try {
39+
raw_gamepad = new LinuxRawGamepad (identifier);
40+
} catch (FileError err) {
41+
return;
42+
}
43+
callback (raw_gamepad);
44+
}
45+
});
46+
}
47+
48+
private void handle_udev_client_callback (string action, GUdev.Device dev) {
49+
if (dev.get_device_file () == null)
50+
return;
51+
52+
var identifier = dev.get_device_file ();
53+
if ((dev.has_property ("ID_INPUT_JOYSTICK") && dev.get_property ("ID_INPUT_JOYSTICK") == "1") ||
54+
(dev.has_property (".INPUT_CLASS") && dev.get_property (".INPUT_CLASS") == "joystick")) {
55+
switch (action) {
56+
case "add":
57+
RawGamepad raw_gamepad;
58+
try {
59+
raw_gamepad = new LinuxRawGamepad (identifier);
60+
} catch (FileError err) {
61+
return;
62+
}
63+
gamepad_plugged (raw_gamepad);
64+
break;
65+
case "remove":
66+
gamepad_unplugged (identifier);
67+
break;
68+
}
69+
}
70+
}
71+
}

0 commit comments

Comments
 (0)