mirror of
https://github.com/albfan/miraclecast.git
synced 2025-02-13 11:31:58 +00:00
demo/miracle-wfdctl: handle SIGINT to exit gracefully
This commit is contained in:
parent
a0d0c9bc8c
commit
57c4bbeae5
5 changed files with 153 additions and 30 deletions
|
@ -56,9 +56,8 @@ add_custom_command(OUTPUT wfdctl.c
|
||||||
COMMAND ${VALAC} --target-glib=2.50 -H wfdctl.h --use-header -C
|
COMMAND ${VALAC} --target-glib=2.50 -H wfdctl.h --use-header -C
|
||||||
--pkg=gio-2.0
|
--pkg=gio-2.0
|
||||||
--pkg=gdk-3.0
|
--pkg=gdk-3.0
|
||||||
--pkg=posix
|
|
||||||
--pkg=linux
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/wfdctl.vala
|
${CMAKE_CURRENT_SOURCE_DIR}/wfdctl.vala
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/sigint.vapi
|
||||||
org-freedesktop-networkmanager.vala
|
org-freedesktop-networkmanager.vala
|
||||||
org-freedesktop-miracle-wifi.vala
|
org-freedesktop-miracle-wifi.vala
|
||||||
org-freedesktop-miracle-wfd.vala
|
org-freedesktop-miracle-wfd.vala
|
||||||
|
@ -78,7 +77,9 @@ add_custom_command(OUTPUT wfdctl-res.c
|
||||||
${RES_DIR}/wfdctl-res.xml
|
${RES_DIR}/wfdctl-res.xml
|
||||||
WORKING_DIRECTORY ${RES_DIR})
|
WORKING_DIRECTORY ${RES_DIR})
|
||||||
|
|
||||||
include_directories(${GIO2_INCLUDE_DIRS} ${GDK3_INCLUDE_DIRS})
|
include_directories(${GIO2_INCLUDE_DIRS}
|
||||||
|
${GDK3_INCLUDE_DIRS}
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR})
|
||||||
|
|
||||||
# silent C compiler warning about valac generated code, bad practice
|
# silent C compiler warning about valac generated code, bad practice
|
||||||
set(CMAKE_C_FLAGS "-Wno-unused-label ${CMAKE_C_FLAGS}")
|
set(CMAKE_C_FLAGS "-Wno-unused-label ${CMAKE_C_FLAGS}")
|
||||||
|
@ -88,6 +89,7 @@ set(CMAKE_C_FLAGS "-Wno-unused-but-set-variable ${CMAKE_C_FLAGS}")
|
||||||
|
|
||||||
add_executable(miracle-wfdctl wfdctl
|
add_executable(miracle-wfdctl wfdctl
|
||||||
wfdctl-res.c
|
wfdctl-res.c
|
||||||
|
sigint.c
|
||||||
org-freedesktop-networkmanager.c
|
org-freedesktop-networkmanager.c
|
||||||
org-freedesktop-miracle-wifi.c
|
org-freedesktop-miracle-wifi.c
|
||||||
org-freedesktop-miracle-wfd.c)
|
org-freedesktop-miracle-wfd.c)
|
||||||
|
@ -96,4 +98,3 @@ target_link_libraries(miracle-wfdctl ${GIO2_LIBRARIES}
|
||||||
${GDK3_LIBRARIES})
|
${GDK3_LIBRARIES})
|
||||||
|
|
||||||
install(TARGETS miracle-wfdctl DESTINATION bin)
|
install(TARGETS miracle-wfdctl DESTINATION bin)
|
||||||
|
|
||||||
|
|
64
demo/sigint.c
Normal file
64
demo/sigint.c
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
/*
|
||||||
|
* MiracleCast - Wifi-Display/Miracast Implementation
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013-2014 David Herrmann <dh.herrmann@gmail.com>
|
||||||
|
*
|
||||||
|
* MiracleCast is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2.1 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* MiracleCast is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with MiracleCast; If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
#include <sys/signalfd.h>
|
||||||
|
#include "sigint.h"
|
||||||
|
|
||||||
|
typedef struct _SigintDelegate SigintDelegate;
|
||||||
|
|
||||||
|
struct _SigintDelegate
|
||||||
|
{
|
||||||
|
SigintHandler handler;
|
||||||
|
gpointer user_data;
|
||||||
|
};
|
||||||
|
|
||||||
|
static gboolean sigint_on_signal(GIOChannel *c, GIOCondition e, gpointer d)
|
||||||
|
{
|
||||||
|
struct signalfd_siginfo siginfo;
|
||||||
|
g_io_channel_read_chars(c, (gchar *) &siginfo, sizeof(siginfo), NULL, NULL);
|
||||||
|
|
||||||
|
SigintDelegate *delegate = d;
|
||||||
|
(*delegate->handler)(delegate->user_data);
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void sigint_add_watch(SigintHandler handler, gpointer user_data)
|
||||||
|
{
|
||||||
|
sigset_t mask;
|
||||||
|
sigemptyset(&mask);
|
||||||
|
sigaddset(&mask, SIGINT);
|
||||||
|
sigprocmask(SIG_BLOCK, &mask, NULL);
|
||||||
|
|
||||||
|
SigintDelegate *d = g_malloc(sizeof(SigintDelegate));
|
||||||
|
*d = (SigintDelegate) {
|
||||||
|
handler = handler,
|
||||||
|
user_data = user_data
|
||||||
|
};
|
||||||
|
|
||||||
|
int fd = signalfd(-1, &mask, SFD_CLOEXEC);
|
||||||
|
GIOChannel *c = g_io_channel_unix_new(fd);
|
||||||
|
g_io_add_watch_full(c,
|
||||||
|
G_PRIORITY_DEFAULT,
|
||||||
|
G_IO_IN | G_IO_ERR | G_IO_HUP,
|
||||||
|
sigint_on_signal,
|
||||||
|
d,
|
||||||
|
g_free);
|
||||||
|
g_io_channel_set_encoding(c, NULL, NULL);
|
||||||
|
/*g_io_channel_unref(c);*/
|
||||||
|
}
|
29
demo/sigint.h
Normal file
29
demo/sigint.h
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
/*
|
||||||
|
* MiracleCast - Wifi-Display/Miracast Implementation
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013-2014 David Herrmann <dh.herrmann@gmail.com>
|
||||||
|
*
|
||||||
|
* MiracleCast is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2.1 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* MiracleCast is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with MiracleCast; If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <glib.h>
|
||||||
|
|
||||||
|
#ifndef DISP_SIGFD_H
|
||||||
|
#define DISP_SIGFD_H
|
||||||
|
|
||||||
|
typedef void (*SigintHandler)(gpointer user_data);
|
||||||
|
|
||||||
|
void sigint_add_watch(SigintHandler handler, gpointer user_data);
|
||||||
|
|
||||||
|
#endif /* DISP_SIGFD_H */
|
8
demo/sigint.vapi
Normal file
8
demo/sigint.vapi
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
[CCode(cheader_filename="sigint.h")]
|
||||||
|
class Sigint
|
||||||
|
{
|
||||||
|
public delegate void Handler();
|
||||||
|
|
||||||
|
public static void add_watch(Handler handler);
|
||||||
|
public static void remove_watch();
|
||||||
|
}
|
|
@ -1,3 +1,22 @@
|
||||||
|
/*
|
||||||
|
* MiracleCast - Wifi-Display/Miracast Implementation
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013-2014 David Herrmann <dh.herrmann@gmail.com>
|
||||||
|
*
|
||||||
|
* MiracleCast is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2.1 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* MiracleCast is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with MiracleCast; If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
using Org.Freedesktop.NetworkManager;
|
using Org.Freedesktop.NetworkManager;
|
||||||
using Org.Freedesktop.Miracle.Wifi;
|
using Org.Freedesktop.Miracle.Wifi;
|
||||||
using Org.Freedesktop.Miracle.Wfd;
|
using Org.Freedesktop.Miracle.Wfd;
|
||||||
|
@ -82,14 +101,13 @@ private class WfdCtl : GLib.Application
|
||||||
string curr_sink_mac;
|
string curr_sink_mac;
|
||||||
Gdk.Display display;
|
Gdk.Display display;
|
||||||
Session curr_session;
|
Session curr_session;
|
||||||
IOChannel sig_channel;
|
|
||||||
|
|
||||||
const GLib.OptionEntry[] option_entries = {
|
const GLib.OptionEntry[] option_entries = {
|
||||||
{ "interface", 'i', 0, OptionArg.STRING, ref opt_iface, "name of wireless network interface", "WNIC name" },
|
{ "interface", 'i', 0, OptionArg.STRING, ref opt_iface, "name of wireless network interface", "WNIC name" },
|
||||||
{ "wfd-subelems", 'w', 0, OptionArg.STRING, ref opt_wfd_subelems, "device infomation. default: 000600111c4400c8", "device info subelems" },
|
{ "wfd-subelems", 'w', 0, OptionArg.STRING, ref opt_wfd_subelems, "device infomation. default: 000600111c4400c8", "device info subelems" },
|
||||||
{ "peer-mac", 'p', 0, OptionArg.STRING, ref opt_peer_mac, "MAC address of target peer", "peer MAC" },
|
{ "peer-mac", 'p', 0, OptionArg.STRING, ref opt_peer_mac, "MAC address of target peer", "peer MAC" },
|
||||||
{ "authority", 'x', 0, OptionArg.STRING, ref opt_authority, "authority to capture from display. default: XAUTHORITY environment variable", "display authority" },
|
{ "authority", 'x', 0, OptionArg.STRING, ref opt_authority, "authority to capture from display. default: XAUTHORITY environment variable", "display authority" },
|
||||||
{ "display", 'd', 0, OptionArg.STRING, ref opt_display, "display name. default: DISPLAY environment variable", "display name" },
|
{ "display", 'd', 0, OptionArg.STRING, ref opt_display, "display name. default: DISPLAY environment variable", "display name" },
|
||||||
{ "monitor-num", 'm', 0, OptionArg.INT, ref opt_monitor_num, "monitor number. default: -1, primary monitor", "monitor number" },
|
{ "monitor-num", 'm', 0, OptionArg.INT, ref opt_monitor_num, "monitor number. default: -1, primary monitor", "monitor number" },
|
||||||
{ "audio-device", 'a', 0, OptionArg.STRING, ref opt_audio_device, "pulseaudio device name", "audio device name" },
|
{ "audio-device", 'a', 0, OptionArg.STRING, ref opt_audio_device, "pulseaudio device name", "audio device name" },
|
||||||
{ null },
|
{ null },
|
||||||
|
@ -500,10 +518,31 @@ private class WfdCtl : GLib.Application
|
||||||
yield wait_for_session_ending();
|
yield wait_for_session_ending();
|
||||||
yield release_wnic_ownership();
|
yield release_wnic_ownership();
|
||||||
|
|
||||||
release();
|
quit();
|
||||||
|
|
||||||
print("Bye");
|
print("Bye");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void stop_wireless_display()
|
||||||
|
{
|
||||||
|
info("tearing down wireless display...");
|
||||||
|
|
||||||
|
try {
|
||||||
|
if(null != curr_session) {
|
||||||
|
curr_session.teardown();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
release_wnic_ownership.begin(() => {
|
||||||
|
quit();
|
||||||
|
print("Bye");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch(Error e) {
|
||||||
|
warning("%s", e.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private bool check_options()
|
private bool check_options()
|
||||||
{
|
{
|
||||||
if(null == opt_peer_mac) {
|
if(null == opt_peer_mac) {
|
||||||
|
@ -575,29 +614,6 @@ private class WfdCtl : GLib.Application
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* vala has bug in generatde C code looks like
|
|
||||||
* sigset_t _tmp2_ = {0};
|
|
||||||
* sigset_t _tmp3_ = {0};
|
|
||||||
* sigset_t _tmp4_ = {0};
|
|
||||||
* sigset_t _tmp5_ = {0};
|
|
||||||
* sigset_t _tmp6_ = {0};
|
|
||||||
* sigset_t _tmp7_ = {0};
|
|
||||||
* sigemptyset (&_tmp3_);
|
|
||||||
* sigaddset (&_tmp4_, SIGINT);
|
|
||||||
* sigprocmask (SIG_BLOCK, &_tmp5_, &_tmp6_); */
|
|
||||||
//Posix.sigset_t mask = {}, oldmask = {};
|
|
||||||
//Posix.sigemptyset(mask);
|
|
||||||
//Posix.sigaddset(mask, Posix.SIGINT);
|
|
||||||
//Posix.sigprocmask(Posix.SIG_BLOCK, mask, oldmask);
|
|
||||||
//sig_channel = new IOChannel.unix_new(Linux.signalfd(-1, mask));
|
|
||||||
//sig_channel.add_watch(IOCondition.IN, (s, e) => {
|
|
||||||
//info("Bye");
|
|
||||||
//release();
|
|
||||||
//return false;
|
|
||||||
//});
|
|
||||||
|
|
||||||
hold();
|
|
||||||
|
|
||||||
start_wireless_display.begin((o, r) => {
|
start_wireless_display.begin((o, r) => {
|
||||||
try {
|
try {
|
||||||
start_wireless_display.end(r);
|
start_wireless_display.end(r);
|
||||||
|
@ -607,6 +623,8 @@ private class WfdCtl : GLib.Application
|
||||||
release();
|
release();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
hold();
|
||||||
}
|
}
|
||||||
|
|
||||||
private unowned Device? find_device_by_name(string nic_name)
|
private unowned Device? find_device_by_name(string nic_name)
|
||||||
|
@ -694,9 +712,12 @@ int main(string[]? argv)
|
||||||
Intl.setlocale();
|
Intl.setlocale();
|
||||||
Environment.set_prgname(Path.get_basename(argv[0]));
|
Environment.set_prgname(Path.get_basename(argv[0]));
|
||||||
|
|
||||||
|
|
||||||
Application app = new WfdCtl();
|
Application app = new WfdCtl();
|
||||||
app.set_default();
|
app.set_default();
|
||||||
|
|
||||||
|
Sigint.add_watch((app as WfdCtl).stop_wireless_display);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
app.register();
|
app.register();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue