1 /*
2  *                           0BSD
3  *
4  *                    BSD Zero Clause License
5  *
6  *  Copyright (c) 2020 Hermann Meyer
7  *
8  * Permission to use, copy, modify, and/or distribute this software for any
9  * purpose with or without fee is hereby granted.
10 
11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
12  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13  * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
14  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
16  * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17  * PERFORMANCE OF THIS SOFTWARE.
18  *
19  */
20 
21 
22 #include <thread>
23 #include <stdio.h>
24 #include <cstdlib>
25 #include <atomic>
26 #include <future>
27 #include <sigc++/sigc++.h>
28 
29 #include "nsm.h"
30 
31 #pragma once
32 
33 #ifndef NSMHANDLER_H
34 #define NSMHANDLER_H
35 
36 
37 namespace nsmhandler {
38 
39 
40 /****************************************************************
41  ** class NsmSignalHandler
42  **
43  ** signal messages from GxNsmHandler to MainWindow and back.
44  **
45  */
46 
47 class NsmSignalHandler : public sigc::trackable {
48 
49 private:
50 
51 public:
52     bool nsm_session_control;
53 
54     sigc::signal<void > trigger_nsm_show_gui;
signal_trigger_nsm_show_gui()55     sigc::signal<void >& signal_trigger_nsm_show_gui() { return trigger_nsm_show_gui; }
56 
57     sigc::signal<void > trigger_nsm_hide_gui;
signal_trigger_nsm_hide_gui()58     sigc::signal<void >& signal_trigger_nsm_hide_gui() { return trigger_nsm_hide_gui; }
59 
60     sigc::signal<void > trigger_nsm_save_gui;
signal_trigger_nsm_save_gui()61     sigc::signal<void >& signal_trigger_nsm_save_gui() { return trigger_nsm_save_gui; }
62 
63     sigc::signal<void, const char*, const char*, bool> trigger_nsm_gui_open;
signal_trigger_nsm_gui_open()64     sigc::signal<void, const char*, const char*, bool>& signal_trigger_nsm_gui_open() { return trigger_nsm_gui_open; }
65 
66 public:
67     sigc::signal<void > trigger_nsm_gui_is_shown;
signal_trigger_nsm_gui_is_shown()68     sigc::signal<void >& signal_trigger_nsm_gui_is_shown() { return trigger_nsm_gui_is_shown; }
69 
70     sigc::signal<void > trigger_nsm_gui_is_hidden;
signal_trigger_nsm_gui_is_hidden()71     sigc::signal<void >& signal_trigger_nsm_gui_is_hidden() { return trigger_nsm_gui_is_hidden; }
72 
NsmSignalHandler()73     NsmSignalHandler() : sigc::trackable(), nsm_session_control(false) {};
~NsmSignalHandler()74     ~NsmSignalHandler() {};
75 };
76 
77 
78 /****************************************************************
79  ** class NsmWatchDog
80  **
81  ** Watch for incomming messages from NSM server in a extra thread
82  **
83  */
84 
85 class NsmWatchDog {
86 private:
87     std::atomic<bool> _execute;
88     std::thread _thd;
89 
90 public:
91     NsmWatchDog();
92     ~NsmWatchDog();
93     void stop();
94     void start(int interval, std::function<void(void)> func);
95     bool is_running() const noexcept;
96 };
97 
98 
99 /****************************************************************
100  ** class NsmHandler
101  **
102  ** Check if NSM is calling, if so, connect the handlers
103  */
104 
105 class NsmHandler {
106   private:
107     NsmWatchDog poll;
108     NsmSignalHandler *nsmsig;
109     int _nsm_open (const char *name, const char *display_name,
110             const char *client_id, char **out_msg);
111     int _nsm_save ( char **out_msg);
112     void _nsm_show ();
113     void _nsm_hide ();
114     void _on_nsm_is_shown();
115     void _on_nsm_is_hidden();
116     void _nsm_start_poll();
117     nsm_client_t *nsm;
118     bool wait_id;
119     bool optional_gui;
120 
121   public:
122     bool check_nsm(const char *name, char *argv[]);
123     static void _poll_nsm(void* arg);
124     static int nsm_open (const char *name, const char *display_name,
125             const char *client_id, char **out_msg,  void *userdata);
126     static int nsm_save ( char **out_msg, void *userdata );
127     static void nsm_show ( void *userdata );
128     static void nsm_hide ( void *userdata );
129     NsmHandler(NsmSignalHandler *nsmsig);
130     ~NsmHandler();
131 };
132 
133 } // namespace nsmhandler
134 
135 #endif //NSMHANDLER_H_
136 
137