]> git.lyx.org Git - lyx.git/blob - development/lyxserver/server_monitor.c
76b1fcfd9bb26aca6a79897e227b614b526c9a00
[lyx.git] / development / lyxserver / server_monitor.c
1 /*
2  * LyXServer monitor. To send command to a running instance of LyX
3  * and receive information from LyX.
4  * 
5  * To build it type:
6  * > gcc -g server_monitor.c -o monitor -lforms -L/usr/X11/lib -lX11 -lm
7  * > ./monitor
8  * Before you run lyx uncomment the line "\serverpipe" from your
9  * ~/.lyx/lyxrc file, according with your home path.
10  * 
11  * Created: 970531
12  * Copyright (C) 1997 Alejandro Aguilar Sierra (asierra@servidor.unam.mx)
13  * Updated: 980104
14  * Copyright (C) 1998 Asger Alstrup (alstrup@diku.dk)
15  */
16
17
18 /* Form definition file generated with fdesign. */
19
20 #include "forms.h"
21 #include <stdlib.h>
22 #include <sys/types.h>
23 #include <sys/stat.h>
24 #include <fcntl.h>
25 #include <unistd.h>
26 #include <stdio.h>    
27
28 int lyx_listen = 0;
29 int  pipein=-1, pipeout=-1;
30 char pipename[100];        
31 char const *clientname = "monitor";
32
33 /**** Forms and Objects ****/
34
35 typedef struct {
36         FL_FORM *server;
37         void *vdata;
38         long ldata;
39         FL_OBJECT *pipename;
40         FL_OBJECT *command;
41         FL_OBJECT *arg;
42         FL_OBJECT *info;
43         FL_OBJECT *client;
44         FL_OBJECT *submit;
45         FL_OBJECT *notify;
46 } FD_server;
47
48
49 enum { LS_DUMMY=1, LS_OPEN, LS_CLOSE, LS_SUBMIT };
50
51 static FD_server *fd_server;
52
53 void closepipe();
54 void server_cb(FL_OBJECT *ob, long data);
55
56
57 FD_server *create_form_server(void)
58 {
59   FL_OBJECT *obj;
60   FD_server *fdui = (FD_server *) fl_calloc(1, sizeof(*fdui));
61
62   fdui->server = fl_bgn_form(FL_NO_BOX, 620, 260);
63   obj = fl_add_box(FL_UP_BOX,0,0,620,260,"");
64   fdui->pipename = obj = fl_add_input(FL_NORMAL_INPUT,110,10,190,40,"Pipe name");
65     fl_set_object_lsize(obj,FL_NORMAL_SIZE);
66     fl_set_object_callback(obj,server_cb,0);
67     fl_set_object_shortcut(obj,"#P",1);
68   fdui->client = obj = fl_add_input(FL_NORMAL_INPUT,410,10,190,40,"Client name");
69     fl_set_object_lsize(obj,FL_NORMAL_SIZE);
70     fl_set_object_callback(obj,server_cb,0);
71     fl_set_object_shortcut(obj,"#N",1);
72   fdui->command = obj = fl_add_input(FL_NORMAL_INPUT,110,60,190,40,"Command");
73     fl_set_object_lsize(obj,FL_NORMAL_SIZE);
74     fl_set_object_callback(obj,server_cb,0);
75     fl_set_object_shortcut(obj,"#C",1);
76   fdui->arg = obj = fl_add_input(FL_NORMAL_INPUT,410,60,190,40,"Argument");
77     fl_set_object_lsize(obj,FL_NORMAL_SIZE);
78     fl_set_object_callback(obj,server_cb,0);
79     fl_set_object_shortcut(obj,"#A",1);
80   obj = fl_add_text(FL_NORMAL_TEXT,10,110,100,40,"Info");
81     fl_set_object_lsize(obj,FL_NORMAL_SIZE);
82     fl_set_object_lalign(obj,FL_ALIGN_RIGHT|FL_ALIGN_INSIDE);
83   fdui->info = obj = fl_add_text(FL_NORMAL_TEXT,110,110,490,40,"");
84     fl_set_object_boxtype(obj,FL_DOWN_BOX);
85     fl_set_object_lsize(obj,FL_NORMAL_SIZE);
86     fl_set_object_lalign(obj,FL_ALIGN_LEFT|FL_ALIGN_INSIDE);
87   obj = fl_add_text(FL_NORMAL_TEXT,10,160,100,40,"Notify");
88     fl_set_object_lsize(obj,FL_NORMAL_SIZE);
89     fl_set_object_lalign(obj,FL_ALIGN_RIGHT|FL_ALIGN_INSIDE);
90   fdui->notify = obj = fl_add_text(FL_NORMAL_TEXT,110,160,490,40,"");
91     fl_set_object_boxtype(obj,FL_DOWN_BOX);
92     fl_set_object_lsize(obj,FL_NORMAL_SIZE);
93     fl_set_object_lalign(obj,FL_ALIGN_LEFT|FL_ALIGN_INSIDE);
94   obj = fl_add_button(FL_NORMAL_BUTTON,10,210,140,40,"Open pipes");
95     fl_set_object_lsize(obj,FL_NORMAL_SIZE);
96     fl_set_object_lstyle(obj,FL_BOLD_STYLE);
97     fl_set_object_callback(obj,server_cb,LS_OPEN);
98     fl_set_object_shortcut(obj,"#O",1);
99   obj = fl_add_button(FL_NORMAL_BUTTON,160,210,140,40,"Close pipes");
100     fl_set_object_lsize(obj,FL_NORMAL_SIZE);
101     fl_set_object_lstyle(obj,FL_BOLD_STYLE);
102     fl_set_object_callback(obj,server_cb,LS_CLOSE);
103     fl_set_object_shortcut(obj,"#l",1);
104   fdui->submit = obj = fl_add_button(FL_NORMAL_BUTTON,310,210,170,40,"Submit Command");
105     fl_set_object_lsize(obj,FL_NORMAL_SIZE);
106     fl_set_object_lstyle(obj,FL_BOLD_STYLE);
107     fl_set_object_callback(obj,server_cb,LS_SUBMIT);
108     fl_set_object_shortcut(obj,"#S",1);
109   obj = fl_add_button(FL_NORMAL_BUTTON,490,210,120,40,"Done");
110     fl_set_object_lsize(obj,FL_NORMAL_SIZE);
111     fl_set_object_lstyle(obj,FL_BOLD_STYLE);
112     fl_set_object_shortcut(obj,"#D^[",1);
113   fl_end_form();
114
115   fdui->server->fdui = fdui;
116
117   return fdui;
118 }
119 /*---------------------------------------*/
120
121
122 void io_cb(int fd, void *data)
123 {
124     int n;
125     char s[255];
126
127     n = read(fd, &s[0], 200);
128     if (n>=0)
129       s[n] = 0;
130     fprintf(stderr, "monitor: Coming: %s\n", s);
131     if (strncmp(s, "LYXSRV:", 7)==0) {
132         if (strstr(s, "bye")) {
133             lyx_listen = 0;
134             fprintf(stderr, "monitor: LyX has closed connection!\n");
135             closepipe();
136             return;
137         }
138         if (strstr(s, "hello")) {
139             lyx_listen = 1;
140             fprintf(stderr, "monitor: LyX is listening!\n");
141             fl_set_object_lcol(fd_server->submit,FL_BLACK);
142             fl_activate_object(fd_server->submit);
143         }                            
144     }
145     if (s[0]=='I')
146       fl_set_object_label(fd_server->info, s);
147     else
148       fl_set_object_label(fd_server->notify, s); 
149 }
150
151 void openpipe()
152 {
153     char buf[100];
154     clientname = fl_get_input(fd_server->client);
155     if (pipein==-1) {
156         char *pipename = strdup(fl_get_input(fd_server->pipename));
157         char s[255];
158
159         fprintf(stderr, "monitor: Opening pipes ");
160         strcpy(s, pipename);
161         strcat(s, ".in");
162         fprintf(stderr, "[%s] and ", s);
163         pipein = open(s, O_RDWR);
164         strcpy(s, pipename);
165         strcat(s, ".out");
166         fprintf(stderr, "[%s]\n", s);
167         pipeout = open(s, O_RDONLY|O_NONBLOCK);
168         fprintf(stderr, "monitor: Opened %d %d\n", pipein, pipeout);
169
170         if (pipein<0 || pipeout<0) {
171             perror("monitor: Couldn't open the pipes");
172             pipein = pipeout = -1;
173             return;
174         }
175         fl_add_io_callback(pipeout, FL_READ, io_cb, 0);
176         
177         // greet LyX
178         sprintf(buf, "LYXSRV:%s:hello", clientname);
179         write(pipein, buf, strlen(buf));
180         free(pipename);
181     } else 
182         fprintf(stderr, "monitor: Pipes already opened, close them first\n");
183 }             
184
185
186 void closepipe()
187 {
188     char buf[100];
189     
190     if (pipein==-1 && pipeout==-1) {
191         fprintf(stderr, "monitor: Pipes are not opened\n");
192         return;
193     }
194         
195     if (pipein>=0) {
196         close(pipein);
197     }
198               
199     if (pipeout>=0) {
200         if (lyx_listen) {
201             lyx_listen = 0;
202             /* Say goodbye */
203             sprintf(buf, "LYXSRV:%s:bye\n", clientname);
204             write(pipeout, buf, strlen(buf));
205         }
206         close(pipeout);
207         fl_remove_io_callback(pipeout, FL_READ, io_cb);
208     }     
209     pipein = pipeout = -1;
210     fl_set_object_lcol(fd_server->submit,FL_INACTIVE);
211     fl_deactivate_object(fd_server->submit);    
212 }
213
214
215 void submit()
216 {
217     char s[255];
218  
219     const char *clientname = fl_get_input(fd_server->client);
220     const char *argument = fl_get_input(fd_server->arg);
221     const char *command = fl_get_input(fd_server->command);
222     
223     sprintf(s, "LYXCMD:%s:%s:%s\n", clientname, command, argument);
224     fprintf(stderr, "monitor: command: %s\n", s);
225     if (pipein>=0) 
226       write(pipein, s, strlen(s));
227     else
228       fprintf(stderr, "monitor: Pipe is not opened\n");
229 }
230
231
232 /* callbacks for form server */
233 void server_cb(FL_OBJECT *ob, long data)
234 {
235
236     switch (data) {
237      case 0: break;
238      case LS_OPEN:
239         openpipe();
240         break;
241      case LS_CLOSE:
242         closepipe();
243         break;
244      case LS_SUBMIT:
245         submit();
246         break;
247      case LS_DUMMY:
248         break;
249     }
250 }
251
252
253 int main(int argc, char *argv[])
254 {
255     fl_initialize(&argc, argv, 0, 0, 0);
256     fd_server = create_form_server();
257
258     strcpy(pipename, getenv("HOME"));
259     strcat(pipename, "/.lyxpipe"),
260     
261     /* fill-in form initialization code */
262     fl_set_input(fd_server->pipename, pipename);
263     fl_set_input(fd_server->client, clientname);
264     fl_deactivate_object(fd_server->submit);
265     fl_set_object_lcol(fd_server->submit,FL_INACTIVE);
266     
267     /* show the first form */
268     fl_show_form(fd_server->server,FL_PLACE_MOUSE,FL_FULLBORDER,"LyX Server Monitor");
269     fl_do_forms();
270     if (pipein != -1)
271       closepipe();
272     return 0;
273 }
274