AglShellGrpcClient: Add support for split windows
[src/window-management-client-grpc.git] / src / AglShellGrpcClient.h
1 #pragma once
2 #include <cstdio>
3
4 #include <mutex>
5 #include <condition_variable>
6 #include <grpc/grpc.h>
7 #include <grpcpp/grpcpp.h>
8 #include <grpcpp/server.h>
9 #include <grpcpp/server_builder.h>
10 #include <grpcpp/server_context.h>
11
12 #include <grpcpp/ext/proto_server_reflection_plugin.h>
13 #include <grpcpp/health_check_service_interface.h>
14
15 #include "agl_shell.grpc.pb.h"
16
17 typedef void (*Callback)(agl_shell_ipc::AppStateResponse app_response);
18
19 class Reader : public grpc::ClientReadReactor<::agl_shell_ipc::AppStateResponse> {
20 public:
21         Reader(agl_shell_ipc::AglShellManagerService::Stub *stub)
22                 : m_stub(stub)
23         {
24         }
25
26         void AppStatusState(Callback callback)
27         {
28                 ::agl_shell_ipc::AppStateRequest request;
29
30                 // set up the callback
31                 m_callback = callback;
32                 m_stub->async()->AppStatusState(&m_context, &request, this);
33
34                 StartRead(&m_app_state);
35                 StartCall();
36         }
37
38         void OnReadDone(bool ok) override
39         {
40                 if (ok) {
41                         m_callback(m_app_state);
42
43                         // blocks in StartRead() if the server doesn't send
44                         // antyhing
45                         StartRead(&m_app_state);
46                 }
47         }
48
49         void SetDone()
50         {
51                 fprintf(stderr, "%s()\n", __func__);
52                 std::unique_lock<std::mutex> l(m_mutex);
53                 m_done = true;
54         }
55
56         void OnDone(const grpc::Status& s) override
57         {
58                 fprintf(stderr, "%s()\n", __func__);
59                 std::unique_lock<std::mutex> l(m_mutex);
60
61                 m_status = s;
62
63                 fprintf(stderr, "%s() done\n", __func__);
64                 m_cv.notify_one();
65         }
66
67         grpc::Status Await()
68         {
69                 std::unique_lock<std::mutex> l(m_mutex);
70
71                 m_cv.wait(l, [this] { return m_done; });
72
73                 return std::move(m_status);
74         }
75 private:
76         grpc::ClientContext m_context;
77         ::agl_shell_ipc::AppStateResponse m_app_state;
78         agl_shell_ipc::AglShellManagerService::Stub *m_stub;
79
80         Callback m_callback;
81
82
83         std::mutex m_mutex;
84         std::condition_variable m_cv;
85         grpc::Status m_status;
86         bool m_done = false;
87 };
88
89 class GrpcClient {
90 public:
91         GrpcClient();
92         bool ActivateApp(const std::string& app_id, const std::string& output_name);
93         bool DeactivateApp(const std::string& app_id);
94         bool SetAppFloat(const std::string& app_id, int32_t x_pos, int32_t y_pos);
95         bool SetAppFullscreen(const std::string& app_id);
96         bool SetAppOnOutput(const std::string& app_id, const std::string& output);
97         bool SetAppNormal(const std::string& app_id);
98         bool SetAppPosition(const std::string& app_id, int32_t x, int32_t y);
99         bool SetAppScale(const std::string& app_id, int32_t width, int32_t height);
100         bool SetAppSplit(const std::string& app_id, uint32_t orientation,
101                          int32_t width, int32_t sticky, const std::string& output_name);
102         std::vector<std::string> GetOutputs();
103         void GetAppState();
104         void AppStatusState(Callback callback);
105         grpc::Status Wait();
106
107 private:
108         Reader *reader;
109         std::unique_ptr<agl_shell_ipc::AglShellManagerService::Stub> m_stub;
110 };
111