Initial release of Maemo 5 port of gnuplot
[gnuplot] / src / wxterminal / wxt_gui.h
1 /*
2  * $Id: wxt_gui.h,v 1.14.2.5 2008/07/15 18:51:40 sfeam Exp $
3  */
4
5 /* GNUPLOT - wxt_gui.h */
6
7 /*[
8  * Copyright 2005,2006   Timothee Lecomte
9  *
10  * Permission to use, copy, and distribute this software and its
11  * documentation for any purpose with or without fee is hereby granted,
12  * provided that the above copyright notice appear in all copies and
13  * that both that copyright notice and this permission notice appear
14  * in supporting documentation.
15  *
16  * Permission to modify the software is granted, but not the right to
17  * distribute the complete modified source code.  Modifications are to
18  * be distributed as patches to the released version.  Permission to
19  * distribute binaries produced by compiling modified sources is granted,
20  * provided you
21  *   1. distribute the corresponding source modifications from the
22  *    released version in the form of a patch file along with the binaries,
23  *   2. add special version identification to distinguish your version
24  *    in addition to the base release version number,
25  *   3. provide your name and address as the primary contact for the
26  *    support of your modified version, and
27  *   4. retain our contact information in regard to use of the base
28  *    software.
29  * Permission to distribute the released version of the source code along
30  * with corresponding source modifications in the form of a patch file is
31  * granted with same provisions 2 through 4 for binary distributions.
32  *
33  * This software is provided "as is" without express or implied warranty
34  * to the extent permitted by applicable law.
35  *
36  *
37  * Alternatively, the contents of this file may be used under the terms of the
38  * GNU General Public License Version 2 or later (the "GPL"), in which case the
39  * provisions of GPL are applicable instead of those above. If you wish to allow
40  * use of your version of this file only under the terms of the GPL and not
41  * to allow others to use your version of this file under the above gnuplot
42  * license, indicate your decision by deleting the provisions above and replace
43  * them with the notice and other provisions required by the GPL. If you do not
44  * delete the provisions above, a recipient may use your version of this file
45  * under either the GPL or the gnuplot license.
46 ]*/
47
48 /* -----------------------------------------------------
49  * The following code uses the wxWidgets library, which is
50  * distributed under its own licence (derivated from the LGPL).
51  *
52  * You can read it at the following address :
53  * http://www.wxwidgets.org/licence.htm
54  * -----------------------------------------------------*/
55
56 /* ------------------------------------------------------
57  * This file is the C++ header dedicated to wxt_gui.cpp
58  * Everything here is static.
59  * ------------------------------------------------------*/
60
61 /* ===========================================================
62  * includes
63  * =========================================================*/
64
65 #ifndef GNUPLOT_WXT_H
66 # define GNUPLOT_WXT_H
67
68 /* NOTE : Order of headers inclusion :
69  * - wxWidgets headers must be included before Windows.h
70  * to avoid conflicts on Unicode macros,
71  * - then stdfn.h must be included, to obtain definitions from config.h
72  * - then the rest */
73
74 /* main wxWidgets header */
75 #include <wx/wxprec.h>
76 #ifndef WX_PRECOMP
77 # include <wx/wx.h>
78 #endif /* WX_PRECOMP */
79
80 /* clipboard functionnality */
81 #include <wx/dataobj.h>
82 #include <wx/clipbrd.h>
83
84 /* wxImage facility */
85 #include <wx/image.h>
86
87 /* double buffering facility for the drawing context */
88 #include <wx/dcbuffer.h>
89
90 /* system options used with wxMSW to workaround PNG problem in the toolbar */
91 #include <wx/sysopt.h>
92
93 /* wxConfig stuff */
94 #include <wx/config.h>
95
96 /* wxGenericValidator */
97 #include <wx/valgen.h>
98
99 /* wxMemoryInputStream, for the embedded PNG icons */
100 #include <wx/mstream.h>
101
102 /* c++ vectors and lists, used to store gnuplot commands */
103 #include <vector>
104 #include <list>
105
106 extern "C" {
107 /* for interactive */
108 # include "plot.h"
109 /* for stdfn.h, JUSTIFY, encoding, *term definition, color.h */
110 # include "term_api.h"
111 /* for do_event declaration */
112 # include "mouse.h"
113 /* for rgb functions */
114 # include "getcolor.h"
115 /* for paused_for_mouse, PAUSE_BUTTON1 and friends */
116 # include "command.h"
117 }
118
119 /* if the gtk headers are available, use them to tweak some behaviours */
120 #if defined(__WXGTK__)&&defined(HAVE_GTK)
121 # define USE_GTK
122 #endif
123
124 /* With wxGTK, we use a different cairo surface starting from gtk28 */
125 #if defined(__WXGTK__)&&defined(HAVE_GTK28)
126 # define GTK_SURFACE
127 #endif
128 #if defined(__WXGTK__)&&!defined(HAVE_GTK28)
129 # define IMAGE_SURFACE
130 #endif
131
132 /* by default, enable IMAGE_SURFACE */
133 #if !defined(GTK_SURFACE)&&!defined(IMAGE_SURFACE)&&!defined(__WXMSW__)
134 # define IMAGE_SURFACE
135 #endif
136
137 /* temporarly undef GTK_SURFACE for two reasons :
138  * - because of a CAIRO_OPERATOR_SATURATE bug,
139  * - because as for now, it is slower than the pure image surface,
140  * (multiple copies between video memory and main memory for operations that are
141  * not supported by the X server) */
142 #ifdef GTK_SURFACE
143 # undef GTK_SURFACE
144 # define IMAGE_SURFACE
145 #endif
146
147 extern "C" {
148 /* Windows native backend,
149  * redefinition of fprintf, getch...
150  * console window */
151 # ifdef _Windows
152 #  include "Windows.h"
153 #  include "win/wtext.h"
154 #  include "win/winmain.h"
155 # endif
156
157 /* for cairo_t */
158 # include <cairo.h>
159
160 # ifdef USE_GTK
161 #  include <gdk/gdk.h>
162 #  include <gtk/gtk.h>
163 # endif
164
165 # ifdef _Windows
166 #  include <cairo-win32.h>
167 # endif
168
169 /* to avoid to receive SIGINT in wxWidgets threads,
170  * already included unconditionally in plot.c,
171  * only needed here when using WXGTK
172  * (or at least not needed on Windows) */
173 # include <signal.h>
174 }
175
176 /* interaction with wxt.trm(wxt_options) : plot number, enhanced state.
177  * Communication with gnuplot (wxt_exec_event)
178  * Initialization of the library, and checks */
179 #include "wxt_term.h"
180 /* drawing facility */
181 #include "gp_cairo.h"
182
183 /* ======================================================================
184  * declarations
185  * ====================================================================*/
186
187 #if defined(__WXGTK__)||defined(__WXMAC__)
188 /* thread class, where the gui loop runs.
189  * Not needed with Windows, where the main loop
190  * already processes the gui messages */
191 class wxtThread : public wxThread
192 {
193 public:
194         wxtThread() : wxThread(wxTHREAD_JOINABLE) {};
195
196         /* thread execution starts in the following */
197         void *Entry();
198 };
199
200 /* instance of the thread */
201 static wxtThread * thread;
202 #elif defined(__WXMSW__)
203 #else
204 # error "Not implemented"
205 #endif /* __WXGTK__ */
206
207 DECLARE_EVENT_TYPE(wxExitLoopEvent, -1)
208 DEFINE_EVENT_TYPE(wxExitLoopEvent)
209
210 /* Define a new application type, each gui should derive a class from wxApp */
211 class wxtApp : public wxApp
212 {
213 public:
214         /* This one is called just after wxWidgets initialization */
215         bool OnInit();
216         /* cleanup on exit */
217         int OnExit();
218         /* event handler */
219         void OnExitLoop( wxCommandEvent &event );
220
221 private:
222         /* load a toolbar icon */
223         void LoadPngIcon(const unsigned char *embedded_png, int length, int icon_number);
224         /* load a cursor */
225         void LoadCursor(wxCursor &cursor, const char* xpm_bits[]);
226 };
227
228 /* IDs for gnuplot commands */
229 typedef enum wxt_gp_command_t {
230         command_color = 1,
231         command_linetype,
232         command_linestyle,
233         command_move,
234         command_vector,
235         command_put_text,
236         command_enhanced_put_text,
237         command_set_font,
238         command_justify,
239         command_point,
240         command_pointsize,
241         command_linewidth,
242         command_text_angle,
243         command_fillbox,
244         command_filled_polygon
245 #ifdef WITH_IMAGE
246         ,command_image
247 #endif /* WITH_IMAGE */
248 } wxt_gp_command_t;
249
250 /* base structure for storing gnuplot commands */
251 typedef struct gp_command {
252         enum wxt_gp_command_t command;
253         unsigned int x1;
254         unsigned int y1;
255         unsigned int x2;
256         unsigned int y2;
257         unsigned int x3;
258         unsigned int y3;
259         unsigned int x4;
260         unsigned int y4;
261         int integer_value;
262         int integer_value2;
263         double double_value;
264         char *string;
265         gpiPoint *corners;
266         enum JUSTIFY mode;
267         rgb_color color;
268 #ifdef WITH_IMAGE
269         t_imagecolor color_mode;
270         coordval * image;
271 #endif /* WITH_IMAGE */
272 } gp_command;
273
274 /* declare a type for our list of gnuplot commands */
275 typedef std::list<gp_command> command_list_t;
276
277 /* panel class : this is the space between the toolbar
278  * and the status bar, where the plot is actually drawn. */
279 class wxtPanel : public wxPanel
280 {
281 public :
282         /* constructor*/
283         wxtPanel( wxWindow* parent, wxWindowID id, const wxSize& size );
284
285         /* event handlers (these functions should _not_ be virtual)*/
286         void OnPaint( wxPaintEvent &event );
287         void OnEraseBackground( wxEraseEvent &event );
288         void OnSize( wxSizeEvent& event );
289         void OnMotion( wxMouseEvent& event );
290         void OnLeftDown( wxMouseEvent& event );
291         void OnLeftUp( wxMouseEvent& event );
292         void OnMiddleDown( wxMouseEvent& event );
293         void OnMiddleUp( wxMouseEvent& event );
294         void OnRightDown( wxMouseEvent& event );
295         void OnRightUp( wxMouseEvent& event );
296         void OnKeyDownChar( wxKeyEvent& event );
297
298         void UpdateModifiers( wxMouseEvent& event );
299         void RaiseConsoleWindow();
300         void DrawToDC( wxDC& dc, wxRegion& region );
301         void Draw();
302
303         void wxt_settings_queue(TBOOLEAN antialiasing,
304                                         TBOOLEAN oversampling,
305                                         int hinting_setting);
306         void wxt_settings_apply();
307
308         /* list of commands sent by gnuplot */
309         command_list_t command_list;
310         /* mutex protecting this list */
311         wxMutex command_list_mutex;
312         /* method to clear the command list, free the allocated memory */
313         void ClearCommandlist();
314
315 #ifdef USE_MOUSE
316         /* mouse and zoom events datas */
317         bool wxt_zoombox;
318         int mouse_x, mouse_y;
319         int zoom_x1, zoom_y1;
320         wxString zoom_string1, zoom_string2;
321         bool wxt_ruler;
322         double wxt_ruler_x, wxt_ruler_y;
323         bool wxt_ruler_lineto;
324         /* modifier_mask for wxKeyEvents */
325         int modifier_mask;
326 #endif
327
328         /* cairo context creation */
329         void wxt_cairo_create_context();
330         void wxt_cairo_free_context();
331         /* platform-dependant cairo context creation */
332         int wxt_cairo_create_platform_context();
333         void wxt_cairo_free_platform_context();
334
335 #ifdef IMAGE_SURFACE
336         void wxt_cairo_create_bitmap();
337 #endif
338
339         /* functions used to process the command list */
340         void wxt_cairo_refresh();
341         void wxt_cairo_exec_command(gp_command command);
342
343         /* the plot structure, defined in gp_cairo.h */
344         plot_struct plot;
345
346         /* destructor*/
347         ~wxtPanel();
348
349 private:
350         /* any class wishing to process wxWidgets events must use this macro */
351         DECLARE_EVENT_TABLE()
352
353         bool settings_queued;
354         TBOOLEAN antialiasing_queued;
355         TBOOLEAN oversampling_queued;
356         int hinting_queued;
357         wxMutex mutex_queued;
358
359 #ifdef USE_MOUSE
360         /* watches for time between mouse clicks */
361         wxStopWatch left_button_sw;
362         wxStopWatch right_button_sw;
363         wxStopWatch middle_button_sw;
364 #endif /*USE_MOUSE*/
365
366         /* cairo surfaces, which depends on the implementation */
367 #if defined(GTK_SURFACE)
368         GdkPixmap *gdkpixmap;
369 #elif defined(__WXMSW__)
370         HDC hdc;
371         HBITMAP hbm;
372 #else /* generic 'image' surface */
373         unsigned int *data32;
374         wxBitmap* cairo_bitmap;
375 #endif
376 };
377
378
379 /* class implementing the configuration dialog */
380 class wxtConfigDialog : public wxDialog
381 {
382   public :
383         /* constructor*/
384         wxtConfigDialog(wxWindow* parent);
385
386         void OnRendering( wxCommandEvent& event );
387         void OnButton( wxCommandEvent& event );
388         void OnClose( wxCloseEvent& event );
389
390         /* destructor*/
391         ~wxtConfigDialog() {};
392   private:
393         /* any class wishing to process wxWidgets events must use this macro */
394         DECLARE_EVENT_TABLE()
395
396         /* these two elements are enabled/disabled dynamically */
397         wxSlider *slider;
398         wxStaticText *text_hinting;
399
400         /* settings */
401         bool raise_setting;
402         bool persist_setting;
403         bool ctrl_setting;
404         /* rendering_setting :
405          * 0 = no antialiasing, no oversampling
406          * 1 = antialiasing, no oversampling
407          * 2 = antialiasing and oversampling
408          * Note that oversampling without antialiasing makes no sense */
409         int rendering_setting;
410         int hinting_setting;
411 };
412
413
414 /* Define a new frame type: this is our main frame */
415 class wxtFrame : public wxFrame
416 {
417 public:
418         /* constructor*/
419         wxtFrame( const wxString& title, wxWindowID id, int xpos, int ypos, int width, int height );
420
421         /* event handlers (these functions should _not_ be virtual)*/
422         void OnClose( wxCloseEvent& event );
423         void OnSize( wxSizeEvent& event );
424         void OnCopy( wxCommandEvent& event );
425 #ifdef USE_MOUSE
426         void OnReplot( wxCommandEvent& event );
427         void OnToggleGrid( wxCommandEvent& event );
428         void OnZoomPrevious( wxCommandEvent& event );
429         void OnZoomNext( wxCommandEvent& event );
430         void OnAutoscale( wxCommandEvent& event );
431 #endif /*USE_MOUSE*/
432         void OnConfig( wxCommandEvent& event );
433         void OnHelp( wxCommandEvent& event );
434
435         /* destructor*/
436         ~wxtFrame() {};
437
438         wxtPanel * panel;
439         bool config_displayed;
440 private:
441         wxtConfigDialog * config_dialog;
442
443         /* any class wishing to process wxWidgets events must use this macro */
444         DECLARE_EVENT_TABLE()
445 };
446
447 /* IDs for the controls and the menu commands, and for wxEvents */
448 enum {
449 /* start at wxID_HIGHEST to avoid collisions */
450 Toolbar_CopyToClipboard = wxID_HIGHEST,
451 Toolbar_Replot,
452 Toolbar_ToggleGrid,
453 Toolbar_ZoomPrevious,
454 Toolbar_ZoomNext,
455 Toolbar_Autoscale,
456 Toolbar_Config,
457 Toolbar_Help,
458 Config_Rendering,
459 Config_OK,
460 Config_APPLY,
461 Config_CANCEL
462 };
463
464 /* array of toolbar icons */
465 #define ICON_NUMBER 8
466 static wxBitmap* toolBarBitmaps[ICON_NUMBER];
467
468 /* frames icons in the window manager */
469 static wxIconBundle icon;
470
471 /* mouse cursors */
472 static wxCursor wxt_cursor_cross;
473 static wxCursor wxt_cursor_right;
474 static wxCursor wxt_cursor_rotate;
475 static wxCursor wxt_cursor_size;
476
477 #ifdef DEBUG
478  /* performance watch */
479  static wxStopWatch sw;
480 #endif
481
482 /* wxt_abort_init is set to true if there is an error when
483  * wxWidgets is initialized, for example if the X server is unreachable.
484  * If there has been an error, we should not try to initialize again,
485  * because the following try-out will return that it succeeded,
486  * although this is false. */
487 static bool wxt_abort_init = false;
488
489 /* Sometimes, terminal functions are called although term->init() has not been called before.
490  * It's the case when you hit 'set terminal wxt' twice.
491  * So, we check for earlier initialisation.
492  * External module, such as cairo, can check for status!=0, instead of using the enums defined here.
493  * This is used to process interrupt (ctrl-c) */
494 enum {
495 STATUS_OK = 0,
496 STATUS_UNINITIALIZED,
497 STATUS_INCONSISTENT,
498 STATUS_INTERRUPT_ON_NEXT_CHECK,
499 STATUS_INTERRUPT
500 };
501 static int wxt_status = STATUS_UNINITIALIZED;
502
503 /* structure to store windows and their ID */
504 typedef struct wxt_window_t {
505         wxWindowID id;
506         wxtFrame * frame;
507 } wxt_window_t;
508
509 /* list of already created windows */
510 static std::vector<wxt_window_t> wxt_window_list;
511
512 /* given a window number, return the window structure */
513 static wxt_window_t* wxt_findwindowbyid(wxWindowID);
514
515 /* pointers to currently active instances */
516 static wxt_window_t *wxt_current_window;
517 static command_list_t *wxt_current_command_list;
518 static wxtPanel *wxt_current_panel;
519 static plot_struct *wxt_current_plot;
520
521 /* push a command to the commands list */
522 static void wxt_command_push(gp_command command);
523
524 #ifdef USE_MOUSE
525 /* routine to send an event to gnuplot */
526 static void wxt_exec_event(int type, int mx, int my, int par1, int par2, wxWindowID id);
527
528 /* process the event list */
529 static int wxt_process_events();
530
531 /* event queue and its mutex */
532 static wxMutex mutexProtectingEventList;
533 static std::list<gp_event_t> EventList;
534 static bool wxt_check_eventlist_empty();
535 static void wxt_clear_event_list();
536
537 /* state of the main thread, and its mutex, used to know when and how to wake it up */
538 typedef enum wxt_thread_state_t {
539         RUNNING = 0,
540         WAITING_FOR_STDIN
541 } wxt_thread_state_t;
542 static wxt_thread_state_t wxt_thread_state;
543 static wxMutex mutexProtectingThreadState;
544 static wxt_thread_state_t wxt_check_thread_state();
545 static void wxt_change_thread_state(wxt_thread_state_t state);
546 #endif /*USE_MOUSE*/
547
548 /* returns true if at least one plot window is opened.
549  * Used to handle 'persist' */
550 static bool wxt_window_opened();
551
552 /* helpers to handle the issues of the default Raise() and Lower() methods */
553 static void wxt_raise_window(wxt_window_t* window, bool force);
554 static void wxt_lower_window(wxt_window_t* window);
555
556 /* cleanup  on exit : close all created windows, delete thread if necessary */
557 static void wxt_cleanup();
558
559 /* helpers for gui mutex handling : they do nothing in WXMSW */
560 static void wxt_MutexGuiEnter();
561 static void wxt_MutexGuiLeave();
562
563 /* interrupt stuff */
564 static void (*original_siginthandler) (int);
565 static void wxt_sigint_handler(int WXUNUSED(sig));
566 static void wxt_sigint_return();
567 static void wxt_sigint_check();
568 static void wxt_sigint_init();
569 static void wxt_sigint_restore();
570 static int wxt_sigint_counter = 0;
571
572 /* cleanup at exit, and handle 'persist' setting */
573 void wxt_atexit();
574
575 #endif /*gnuplot_wxt_h*/