]> git.lyx.org Git - lyx.git/blob - src/Server.h
Fix text direction issue for InsetInfo in RTL context
[lyx.git] / src / Server.h
1 // -*- C++ -*-
2 /**
3  * \file Server.h
4  * This file is part of LyX, the document processor.
5  * Licence details can be found in the file COPYING.
6  *
7  * \author Lars Gullik Bjønnes
8  * \author Jean-Marc Lasgouttes
9  * \author Enrico Forestieri
10  *
11  * Full author contact details are available in file CREDITS.
12  */
13
14 #ifndef SERVER_H
15 #define SERVER_H
16
17 #include "support/signals.h"
18
19 #include <vector>
20
21 #ifdef _WIN32
22 #include <windows.h>
23 #include <QObject>
24 #include <QEvent>
25 #endif
26
27
28 namespace lyx {
29
30 class Server;
31
32
33 /** This class manages the pipes used for communicating with clients.
34  Usage: Initialize with pipe-filename-base, client class to receive
35  messages, and callback-function that will be called with the messages.
36  When you want to send, use "send()".
37  This class encapsulates all the dirty communication and thus provides
38  a clean string interface.
39  */
40 #ifndef _WIN32
41 class LyXComm {
42 #else
43 class LyXComm : public QObject {
44         Q_OBJECT
45
46         friend DWORD WINAPI pipeServerWrapper(void *);
47
48 public:
49         /// Max number of clients
50         enum { MAX_CLIENTS = 10 };
51
52 private:
53         /// Max number of pipe instances
54         enum { MAX_PIPES = 2 * MAX_CLIENTS };
55
56         /// I/O buffer size
57         enum { PIPE_BUFSIZE = 512 };
58
59         /// Pipe client time-out
60         enum { PIPE_TIMEOUT = 5000 };
61
62         /// Pipe states
63         enum PipeState {
64                 CONNECTING_STATE,
65                 READING_STATE,
66                 WRITING_STATE
67         };
68
69         /// Pipe instances
70         typedef struct {
71                 OVERLAPPED overlap;
72                 HANDLE handle;
73                 std::string iobuf;
74                 char readbuf[PIPE_BUFSIZE];
75                 DWORD nbytes;
76                 PipeState state;
77                 bool pending_io;
78         } PipeInst;
79 #endif
80 public:
81         /** When we receive a message, we send it to a client.
82           This is one of the small things that would have been a lot
83           cleaner with a Signal/Slot thing.
84          */
85         typedef void (*ClientCallbackfct)(Server *, std::string const &);
86
87         /// Construct with pipe-basename and callback to receive messages
88         LyXComm(std::string const & pip, Server * cli, ClientCallbackfct ccb = 0);
89
90         ///
91         ~LyXComm() { closeConnection(); }
92
93         /// clean up in emergency
94         void emergencyCleanup();
95
96         /// Send message
97         void send(std::string const &);
98
99         /// asynch ready-to-be-read notification
100 #ifndef _WIN32
101         void read_ready();
102 #else
103         void read_ready(DWORD);
104 #endif
105
106         /// Tell whether we asked another instance of LyX to open the files
107         bool deferredLoading() { return deferred_loading_; }
108
109 private:
110         /// the filename of the in pipe
111         std::string const inPipeName() const;
112
113         /// the filename of the out pipe
114         std::string const outPipeName() const;
115
116         /// Open pipes
117         void openConnection();
118
119         /// Close pipes
120         void closeConnection();
121
122         /// Load files in another running instance of LyX
123         bool loadFilesInOtherInstance();
124
125 #ifndef _WIN32
126         /// start a pipe
127         int startPipe(std::string const &, bool);
128
129         /// finish a pipe
130         void endPipe(int &, std::string const &, bool);
131
132         /// This is -1 if not open
133         int infd_;
134
135         /// This is -1 if not open
136         int outfd_;
137 #else
138         /// The pipe server returns false when exiting due to an error
139         bool pipeServer();
140
141         /// Start an overlapped connection
142         bool startPipe(DWORD);
143
144         /// Reset an overlapped connection
145         bool resetPipe(DWORD, bool close_handle = false);
146
147         /// Close event and pipe handles
148         void closeHandles();
149
150         /// Catch pipe ready-to-be-read notification
151         bool event(QEvent *);
152
153         /// Check whether the pipe server must be stopped
154         bool checkStopServer(DWORD timeout = 0);
155
156         /// The filename of a (in or out) pipe instance
157         std::string const pipeName(DWORD) const;
158
159         /// Pipe instances
160         PipeInst pipe_[MAX_PIPES];
161
162         /// Pipe server control events
163         HANDLE event_[MAX_PIPES + 1];
164
165         /// Reply buffer
166         std::string outbuf_;
167
168         /// Synchronize access to outbuf_
169         HANDLE outbuf_mutex_;
170
171         /// Windows event for stopping the pipe server
172         HANDLE stopserver_;
173
174         /// Pipe server thread handle
175         HANDLE server_thread_;
176 #endif
177
178         /// Are we up and running?
179         bool ready_;
180
181         /// Base of pipename including path
182         std::string pipename_;
183
184         /// The client
185         Server * client_;
186
187         /// The client callback function
188         ClientCallbackfct clientcb_;
189
190         /// Did we defer loading of files to another instance?
191         bool deferred_loading_;
192
193         /// Track object's liveness
194         support::Trackable tracker_;
195 };
196
197
198 ///
199 class Server {
200 public:
201         // FIXME IN 0.13
202         // Hack! This should be changed in 0.13
203
204         // IMO lyxserver is atypical, and for the moment the only one, non-gui
205         // bufferview. We just have to find a way to handle situations like if
206         // lyxserver is using a buffer that is being edited with a bufferview.
207         // With a common buffer list this is not a problem, maybe. (Alejandro)
208         ///
209         Server(std::string const & pip);
210         ///
211         ~Server();
212         ///
213         void notifyClient(std::string const &);
214         ///
215         bool deferredLoadingToOtherInstance() { return pipes_.deferredLoading(); }
216
217         /// whilst crashing etc.
218         void emergencyCleanup() { pipes_.emergencyCleanup(); }
219         ///
220         void callback(std::string const & msg);
221
222 private:
223         /// Names and number of current clients
224 #ifndef _WIN32
225         enum { MAX_CLIENTS = 10 };
226 #else
227         enum { MAX_CLIENTS = LyXComm::MAX_CLIENTS };
228 #endif
229         ///
230         std::string clients_[MAX_CLIENTS];
231         ///
232         int numclients_;
233         ///
234         LyXComm pipes_;
235 };
236
237 /// Implementation is in LyX.cpp
238 Server & theServer();
239
240 /// Implementation is in LyX.cpp
241 extern std::vector<std::string> & theFilesToLoad();
242
243
244 } // namespace lyx
245
246 #endif // SERVER_H