Initial release of Maemo 5 port of gnuplot
[gnuplot] / src / beos / GPApp.cpp
1 /*[
2  * Copyright 1986 - 1993, 1998, 2004   Thomas Williams, Colin Kelley
3  *
4  * Permission to use, copy, and distribute this software and its
5  * documentation for any purpose with or without fee is hereby granted,
6  * provided that the above copyright notice appear in all copies and
7  * that both that copyright notice and this permission notice appear
8  * in supporting documentation.
9  *
10  * Permission to modify the software is granted, but not the right to
11  * distribute the complete modified source code.  Modifications are to
12  * be distributed as patches to the released version.  Permission to
13  * distribute binaries produced by compiling modified sources is granted,
14  * provided you
15  *   1. distribute the corresponding source modifications from the
16  *    released version in the form of a patch file along with the binaries,
17  *   2. add special version identification to distinguish your version
18  *    in addition to the base release version number,
19  *   3. provide your name and address as the primary contact for the
20  *    support of your modified version, and
21  *   4. retain our contact information in regard to use of the base
22  *    software.
23  * Permission to distribute the released version of the source code along
24  * with corresponding source modifications in the form of a patch file is
25  * granted with same provisions 2 through 4 for binary distributions.
26  *
27  * This software is provided "as is" without express or implied warranty
28  * to the extent permitted by applicable law.
29 ]*/
30
31 #include <Application.h>
32 #include <Messenger.h>
33 #include <Message.h>
34 #include <Roster.h>
35 #include <Window.h>
36 #include <View.h>
37 #include <MenuBar.h>
38 #include <Menu.h>
39 #include <MenuItem.h>
40 #include <FilePanel.h>
41 #include <Path.h>
42 #include <Entry.h>
43 #include <TextView.h>
44 #include <ScrollView.h>
45 #include <string.h>
46 #include <stdio.h>
47 #include <stdlib.h>
48
49 #include "constants.h"
50 #include "GPBitmap.h"
51 #include "GPView.h"
52 #include "GPApp.h"
53 #include "GPWindow.h"
54
55 // Application's signature
56
57 const char *APP_SIGNATURE                               = "application/x-vnd.Xingo-gnuplotViewer";
58
59 BRect windowRect(50,50,600,400);
60
61 //
62 // main
63 //
64 // The main() function's only real job in a basic BeOS
65 // application is to create the BApplication object
66 // and run it.
67 //
68 int main(void) {
69         GPApp theApp;           // The application object
70         theApp.Run();
71         return 0;
72 }
73
74 //
75 // GPApp::GPApp
76 //
77 // The constructor for the WEApp class.  This
78 // will create our window.
79 //
80 GPApp::GPApp()
81                         : BApplication(APP_SIGNATURE) {
82         
83         window_count = 0;                       // No windows yet
84         next_untitled_number = 1;       // Next window is "Untitled 1"
85         
86         // Create the Open file panel
87 //      openPanel = new BFilePanel;
88 }
89
90
91 //
92 // GPApp::MessageReceived
93 //
94 // Handle incoming messages.  In particular, handle the
95 // WINDOW_REGISTRY_ADD and WINDOW_REGISTRY_SUB messages.
96 //
97 void GPApp::MessageReceived(BMessage *message) {
98         switch(message->what) {
99                 case WINDOW_REGISTRY_ADD:
100                         {
101                                 bool need_id = false;
102                                 BMessage reply(WINDOW_REGISTRY_ADDED);
103                                 
104                                 if (message->FindBool("need_id", &need_id) == B_OK) {
105                                         if (need_id) {
106                                                 reply.AddInt32("new_window_number", next_untitled_number);
107                                                 next_untitled_number++;
108                                         }
109                                         window_count++;
110                                 }
111                                 reply.AddRect("rect", windowRect);
112                                 windowRect.OffsetBy(20,20);
113                                 message->SendReply(&reply);
114                                 break;
115                         }
116                 case WINDOW_REGISTRY_SUB:
117                         window_count--;
118                         if (!window_count) {
119                                 Quit();
120                         }
121                         break;
122                 case MENU_FILE_OPEN:
123 //                      openPanel->Show();              // Show the file panel
124                         break;
125                 default:
126                         BApplication::MessageReceived(message);
127                         break;
128         }
129 }
130
131 //
132 // GPApp::RefsReceived
133 //
134 // Handle a refs received message.
135 //
136 void GPApp::RefsReceived(BMessage *message) {
137         entry_ref       ref;            // The entry_ref to open
138         status_t        err;            // The error code
139         int32           ref_num;        // The index into the ref list
140         
141         // Loop through the ref list and open each one
142 #if 0
143         ref_num = 0;
144         do {
145                 if ((err = message->FindRef("refs", ref_num, &ref)) != B_OK) {
146                         return;
147                 }
148                 new GPWindow(windowRect, &ref);
149                 ref_num++;
150         } while (1);
151 #endif
152 }
153
154 void GPApp::ReadyToRun(void)
155 {
156     io_thread = spawn_thread(&io_loop, "gnuplot io_loop", B_LOW_PRIORITY, NULL); 
157     resume_thread(io_thread); 
158 }
159
160 int32 GPApp::io_loop(void* data)
161 {
162         static plot_struct      plot_array[MAX_WINDOWS];
163         int32 res = 1;
164         while(res)
165                 res = io_task(plot_array);
166         return res;
167 }
168
169 int32 GPApp::io_task(plot_struct *plot_array) 
170
171     char        buf[256];
172         struct  plot_struct *plot = plot_array;
173         FILE    *fp = stdin;
174         BMessage msg(bmsgNewCmd);
175         int             cnt = 0;
176
177         while (fgets(buf, 256, fp)) {
178 //              printf("Got : %s", buf);
179                 switch (*buf) {
180                         case 'G':               /* enter graphics mode */
181                         {
182                                 //printf("entering gfx mode\n");
183                                 int plot_number = atoi(buf + 1);        /* 0 if none specified */
184
185                                 if (plot_number < 0 || plot_number >= MAX_WINDOWS)
186                                         plot_number = 0;
187
188                                 //printf("plot for window number %d\n", plot_number);
189                                 plot = plot_array + plot_number;
190                                 prepare_plot(plot, plot_number);
191                                 continue;
192                         }
193                         case 'E':               /* leave graphics mode / suspend */
194                         {
195 //                              BMessage msg(bmsgBitmapDirty);
196                                 msg.AddInt32("numcmds",cnt);
197                                 msg.AddPointer("cmds", plot->commands);
198                                 if(plot->window)
199                                         plot->window->PostMessage(&msg);
200 //                              printf("displaying %d cmds, %X at %X\n",cnt,plot->commands[0],&plot->commands[0]);
201 //                              display(plot);
202                                 cnt = 0;
203                                 return 1;
204                         }
205                         case 'R':               /* leave x11 mode */
206                         {
207                                 //printf("leaving gfx mode\n");
208                                 return 0;
209                         }
210                         default:
211                         {
212 //                              msg.AddString("cmd",buf);
213 //                              plot->window->PostMessage(&msg);
214                                 store_command(buf, plot);
215                                 cnt++;
216                                 continue;
217                         }
218                 }
219         }
220         /* get here if fgets fails */
221         return (feof(fp) || ferror(fp)) ? 0 : 1;
222
223
224 void GPApp::prepare_plot(plot_struct *plot, int term_number)
225 {
226         int i;
227
228         for (i = 0; i < plot->ncommands; ++i)
229                 free(plot->commands[i]);
230         plot->ncommands = 0;
231
232         if (!plot->posn_flags) {
233                 /* first time this window has been used - use default or -geometry
234                  * settings
235                  */
236                 plot->posn_flags = 1;
237                 plot->x = 50;
238                 plot->y = 20;
239                 plot->width = 400;
240                 plot->height = 400;
241         }
242
243         if (!plot->window) {
244                 windowRect.Set(plot->x,plot->y,plot->width,plot->height);
245                 plot->window = new GPWindow(windowRect);
246         } else {
247                 BMessage msg(bmsgClrCmd);
248                 plot->window->PostMessage(&msg);
249         }
250 }
251
252 void GPApp::display(plot_struct *plot)
253 {
254         BMessage msg(bmsgBitmapDirty);
255         if(plot->window)
256                 plot->window->PostMessage(&msg);
257 }
258
259 /* store a command in a plot structure */
260
261 void GPApp::store_command(char *buffer, plot_struct *plot)
262 {
263         char *p;
264 //      BMessage msg(bmsgNewCmd);
265
266 //      FPRINTF((stderr, "Store in %d : %s", plot - plot_array, buffer));
267
268         if (plot->ncommands >= plot->max_commands) {
269                 plot->max_commands = plot->max_commands * 2 + 1;
270                 plot->commands = (plot->commands)
271                         ? (char **) realloc(plot->commands, plot->max_commands * sizeof(char *))
272                         : (char **) malloc(sizeof(char *));
273         }
274         p = (char *) malloc((unsigned) strlen(buffer) + 1);
275         if (!plot->commands || !p) {
276                 fputs("gnuplot: can't get memory. aborted.\n", stderr);
277                 exit(1);
278         }
279         plot->commands[plot->ncommands++] = strcpy(p, buffer);
280
281 //      msg.AddString("cmd",buffer);
282 //      plot->window->PostMessage(&msg);
283 }
284