mirror of
https://github.com/albfan/miraclecast.git
synced 2025-02-13 02:51: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
|
||||
--pkg=gio-2.0
|
||||
--pkg=gdk-3.0
|
||||
--pkg=posix
|
||||
--pkg=linux
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/wfdctl.vala
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/sigint.vapi
|
||||
org-freedesktop-networkmanager.vala
|
||||
org-freedesktop-miracle-wifi.vala
|
||||
org-freedesktop-miracle-wfd.vala
|
||||
|
@ -78,7 +77,9 @@ add_custom_command(OUTPUT wfdctl-res.c
|
|||
${RES_DIR}/wfdctl-res.xml
|
||||
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
|
||||
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
|
||||
wfdctl-res.c
|
||||
sigint.c
|
||||
org-freedesktop-networkmanager.c
|
||||
org-freedesktop-miracle-wifi.c
|
||||
org-freedesktop-miracle-wfd.c)
|
||||
|
@ -96,4 +98,3 @@ target_link_libraries(miracle-wfdctl ${GIO2_LIBRARIES}
|
|||
${GDK3_LIBRARIES})
|
||||
|
||||
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.Miracle.Wifi;
|
||||
using Org.Freedesktop.Miracle.Wfd;
|
||||
|
@ -82,14 +101,13 @@ private class WfdCtl : GLib.Application
|
|||
string curr_sink_mac;
|
||||
Gdk.Display display;
|
||||
Session curr_session;
|
||||
IOChannel sig_channel;
|
||||
|
||||
const GLib.OptionEntry[] option_entries = {
|
||||
{ "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" },
|
||||
{ "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" },
|
||||
{ "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" },
|
||||
{ "audio-device", 'a', 0, OptionArg.STRING, ref opt_audio_device, "pulseaudio device name", "audio device name" },
|
||||
{ null },
|
||||
|
@ -500,10 +518,31 @@ private class WfdCtl : GLib.Application
|
|||
yield wait_for_session_ending();
|
||||
yield release_wnic_ownership();
|
||||
|
||||
release();
|
||||
quit();
|
||||
|
||||
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()
|
||||
{
|
||||
if(null == opt_peer_mac) {
|
||||
|
@ -575,29 +614,6 @@ private class WfdCtl : GLib.Application
|
|||
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) => {
|
||||
try {
|
||||
start_wireless_display.end(r);
|
||||
|
@ -607,6 +623,8 @@ private class WfdCtl : GLib.Application
|
|||
release();
|
||||
}
|
||||
});
|
||||
|
||||
hold();
|
||||
}
|
||||
|
||||
private unowned Device? find_device_by_name(string nic_name)
|
||||
|
@ -694,9 +712,12 @@ int main(string[]? argv)
|
|||
Intl.setlocale();
|
||||
Environment.set_prgname(Path.get_basename(argv[0]));
|
||||
|
||||
|
||||
Application app = new WfdCtl();
|
||||
app.set_default();
|
||||
|
||||
Sigint.add_watch((app as WfdCtl).stop_wireless_display);
|
||||
|
||||
try {
|
||||
app.register();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue