• Main Page
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

wxwidgets.cpp

Go to the documentation of this file.
00001 // $Id: wxwidgets.cpp 11760 2011-06-01 19:29:11Z airwin $
00002 //
00003 // Copyright (C) 2005  Werner Smekal, Sjaak Verdoold
00004 // Copyright (C) 2005  Germain Carrera Corraleche
00005 // Copyright (C) 1999  Frank Huebner
00006 //
00007 // This file is part of PLplot.
00008 //
00009 // PLplot is free software; you can redistribute it and/or modify
00010 // it under the terms of the GNU Library General Public License as published
00011 // by the Free Software Foundation; either version 2 of the License, or
00012 // (at your option) any later version.
00013 //
00014 // PLplot is distributed in the hope that it will be useful,
00015 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00016 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017 // GNU Library General Public License for more details.
00018 //
00019 // You should have received a copy of the GNU Library General Public License
00020 // along with PLplot; if not, write to the Free Software
00021 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00022 //
00023 
00024 // TODO:
00025 // - NA
00026 //
00027 
00028 // wxwidgets headers
00029 #include <wx/wx.h>
00030 #include <wx/wfstream.h>
00031 #include <wx/except.h>
00032 
00033 #include "plDevs.h"
00034 
00035 // plplot headers
00036 #include "plplotP.h"
00037 #include "drivers.h"
00038 
00039 // C/C++ headers
00040 #include <cstdio>
00041 
00042 #include "wxwidgets.h"
00043 
00044 #ifdef __WXMAC__
00045         #include <Carbon/Carbon.h>
00046 extern "C" { void CPSEnableForegroundOperation( ProcessSerialNumber* psn ); }
00047 #endif
00048 
00049 DECLARE_PLAPP( wxPLplotApp )
00050 
00051 //--------------------------------------------------------------------------
00052 //  void Log_Verbose( const char *fmt, ... )
00053 //
00054 //  Print verbose debug message to stderr (printf style).
00055 //--------------------------------------------------------------------------
00056 void Log_Verbose( const char *fmt, ... )
00057 {
00058 #ifdef _DEBUG_VERBOSE
00059     va_list args;
00060     va_start( args, fmt );
00061     fprintf( stderr, "Verbose: " );
00062     vfprintf( stderr, fmt, args );
00063     fprintf( stderr, "\n" );
00064     va_end( args );
00065     fflush( stderr );
00066 #endif
00067 }
00068 
00069 
00070 //--------------------------------------------------------------------------
00071 //  void Log_Debug( const char *fmt, ... )
00072 //
00073 //  Print debug message to stderr (printf style).
00074 //--------------------------------------------------------------------------
00075 void Log_Debug( const char *fmt, ... )
00076 {
00077 #ifdef _DEBUG
00078     va_list args;
00079     va_start( args, fmt );
00080     fprintf( stderr, "Debug: " );
00081     vfprintf( stderr, fmt, args );
00082     fprintf( stderr, "\n" );
00083     va_end( args );
00084     fflush( stderr );
00085 #endif
00086 }
00087 
00088 
00089 //--------------------------------------------------------------------------
00090 //  In the following you'll find the driver functions which are
00091 //  are needed by the plplot core.
00092 //--------------------------------------------------------------------------
00093 
00094 // Device info
00095 #ifdef __cplusplus
00096 extern "C" {
00097 #endif
00098 
00099 PLDLLIMPEXP_DRIVER const char* plD_DEVICE_INFO_wxwidgets =
00100 #ifdef PLD_wxwidgets
00101     "wxwidgets:wxWidgets Driver:1:wxwidgets:51:wxwidgets\n"
00102 #endif
00103 #ifdef PLD_wxpng
00104     "wxpng:wxWidgets PNG Driver:0:wxwidgets:52:wxpng\n"
00105 #endif
00106 ;
00107 
00108 #ifdef __cplusplus
00109 }
00110 #endif
00111 
00112 
00113 //--------------------------------------------------------------------------
00114 //  wxPLDevBase::wxPLDevBase( void )
00115 //
00116 //  Contructor of base class of wxPLDev classes.
00117 //--------------------------------------------------------------------------
00118 wxPLDevBase::wxPLDevBase( int bcknd ) : backend( bcknd )
00119 {
00120     // Log_Verbose( "wxPLDevBase::wxPLDevBase()" );
00121 
00122     ready    = false;
00123     ownGUI   = false;
00124     waiting  = false;
00125     resizing = false;
00126     exit     = false;
00127 
00128     comcount = 0;
00129 
00130     m_frame = NULL;
00131     xpos    = 0;
00132     ypos    = 0;
00133     // width, height are set in plD_init_wxwidgets
00134     // bm_width, bm_height are set in install_buffer
00135 
00136     // xmin, xmax, ymin, ymax are set in plD_init_wxwidgets
00137     // scalex, scaley are set in plD_init_wxwidgets
00138 
00139     plstate_width  = false;
00140     plstate_color0 = false;
00141     plstate_color1 = false;
00142 
00143     locate_mode = 0;
00144     draw_xhair  = false;
00145 
00146     newclipregion = true;
00147     clipminx      = 1024;
00148     clipmaxx      = 0;
00149     clipminy      = 800;
00150     clipmaxy      = 0;
00151 
00152     freetype    = 0;
00153     smooth_text = 0;
00154 
00155     devName = (const char **) malloc( NDEV * sizeof ( char** ) );
00156     memset( devName, '\0', NDEV * sizeof ( char** ) );
00157     devDesc = (const char **) malloc( NDEV * sizeof ( char** ) );
00158     memset( devDesc, '\0', NDEV * sizeof ( char** ) );
00159     ndev = NDEV;
00160 }
00161 
00162 
00163 wxPLDevBase::~wxPLDevBase( void )
00164 {
00165     if ( devDesc )
00166         free( devDesc );
00167     if ( devName )
00168         free( devName );
00169 }
00170 
00171 
00172 void wxPLDevBase::AddtoClipRegion( int x1, int y1, int x2, int y2 )
00173 {
00174     newclipregion = false;
00175     if ( x1 < x2 )
00176     {
00177         if ( x1 < clipminx )
00178             clipminx = x1;
00179         if ( x2 > clipmaxx )
00180             clipmaxx = x2;
00181     }
00182     else
00183     {
00184         if ( x2 < clipminx )
00185             clipminx = x2;
00186         if ( x1 > clipmaxx )
00187             clipmaxx = x1;
00188     }
00189     if ( y1 < y2 )
00190     {
00191         if ( y1 < clipminy )
00192             clipminy = y1;
00193         if ( y2 > clipmaxy )
00194             clipmaxy = y2;
00195     }
00196     else
00197     {
00198         if ( y2 < clipminy )
00199             clipminy = y2;
00200         if ( y1 > clipmaxy )
00201             clipmaxy = y1;
00202     }
00203 }
00204 
00205 
00206 void wxPLDevBase::PSDrawText( PLUNICODE* ucs4, int ucs4Len, bool drawText )
00207 {
00208     int  i = 0;
00209 
00210     char utf8_string[max_string_length];
00211     char utf8[5];
00212     memset( utf8_string, '\0', max_string_length );
00213 
00214     // Get PLplot escape character
00215     char plplotEsc;
00216     plgesc( &plplotEsc );
00217 
00218     // Get the curent font
00219     fontScale = 1.0;
00220     yOffset   = 0.0;
00221     PLUNICODE fci;
00222     plgfci( &fci );
00223     PSSetFont( fci );
00224     textWidth  = 0;
00225     textHeight = 0;
00226 
00227     while ( i < ucs4Len )
00228     {
00229         if ( ucs4[i] < PL_FCI_MARK )                // not a font change
00230         {
00231             if ( ucs4[i] != (PLUNICODE) plplotEsc ) // a character to display
00232             {
00233                 ucs4_to_utf8( ucs4[i], utf8 );
00234                 strncat( utf8_string, utf8, max_string_length );
00235                 i++;
00236                 continue;
00237             }
00238             i++;
00239             if ( ucs4[i] == (PLUNICODE) plplotEsc ) // a escape character to display
00240             {
00241                 ucs4_to_utf8( ucs4[i], utf8 );
00242                 strncat( utf8_string, utf8, max_string_length );
00243                 i++;
00244                 continue;
00245             }
00246             else
00247             {
00248                 if ( ucs4[i] == (PLUNICODE) 'u' ) // Superscript
00249                 {                                 // draw string so far
00250                     PSDrawTextToDC( utf8_string, drawText );
00251 
00252                     // change font scale
00253                     if ( yOffset < -0.0001 )
00254                         fontScale *= 1.25; // Subscript scaling parameter
00255                     else
00256                         fontScale *= 0.8;  // Subscript scaling parameter
00257                     PSSetFont( fci );
00258 
00259                     yOffset += scaley * fontSize * fontScale / 2.;
00260                 }
00261                 if ( ucs4[i] == (PLUNICODE) 'd' ) // Subscript
00262                 {                                 // draw string so far
00263                     PSDrawTextToDC( utf8_string, drawText );
00264 
00265                     // change font scale
00266                     double old_fontScale = fontScale;
00267                     if ( yOffset > 0.0001 )
00268                         fontScale *= 1.25; // Subscript scaling parameter
00269                     else
00270                         fontScale *= 0.8;  // Subscript scaling parameter
00271                     PSSetFont( fci );
00272 
00273                     yOffset -= scaley * fontSize * old_fontScale / 2.;
00274                 }
00275                 if ( ucs4[i] == (PLUNICODE) '-' ) // underline
00276                 {                                 // draw string so far
00277                     PSDrawTextToDC( utf8_string, drawText );
00278 
00279                     underlined = !underlined;
00280                     PSSetFont( fci );
00281                 }
00282                 if ( ucs4[i] == (PLUNICODE) '+' ) // overline
00283                 {                                 // not implemented yet
00284                 }
00285                 i++;
00286             }
00287         }
00288         else // a font change
00289         {
00290             // draw string so far
00291             PSDrawTextToDC( utf8_string, drawText );
00292 
00293             // get new font
00294             fci = ucs4[i];
00295             PSSetFont( fci );
00296             i++;
00297         }
00298     }
00299 
00300     PSDrawTextToDC( utf8_string, drawText );
00301 }
00302 
00303 
00304 //--------------------------------------------------------------------------
00305 //  void common_init(  PLStream *pls )
00306 //
00307 //  Basic initialization for all devices.
00308 //--------------------------------------------------------------------------
00309 wxPLDevBase* common_init( PLStream *pls )
00310 {
00311     // Log_Verbose( "common_init()" );
00312 
00313     wxPLDevBase* dev;
00314 
00315     // default options
00316     static PLINT freetype    = -1;
00317     static PLINT smooth_text = 1;
00318     static PLINT text        = -1;
00319     static PLINT hrshsym     = 0;
00320 
00321     // default backend uses wxGraphicsContext, if not available
00322     // the agg library will be used, if not available the basic
00323     // backend will be used.
00324     static PLINT backend = wxBACKEND_DC;
00325   #if wxUSE_GRAPHICS_CONTEXT
00326     backend = wxBACKEND_GC;
00327         #else
00328                 #ifdef HAVE_AGG
00329     backend = wxBACKEND_AGG;
00330                 #endif
00331         #endif
00332 
00333     DrvOpt wx_options[] = {
00334 #ifdef HAVE_FREETYPE
00335         { "freetype", DRV_INT, &freetype,    "Use FreeType library"                                                             },
00336         { "smooth",   DRV_INT, &smooth_text, "Turn text smoothing on (1) or off (0)"                                            },
00337 #endif
00338         { "hrshsym",  DRV_INT, &hrshsym,     "Use Hershey symbol set (hrshsym=0|1)"                                             },
00339         { "backend",  DRV_INT, &backend,     "Choose backend: (0) standard, (1) using AGG library, (2) using wxGraphicsContext" },
00340         { "text",     DRV_INT, &text,        "Use own text routines (text=0|1)"                                                 },
00341         { NULL,       DRV_INT, NULL,         NULL                                                                               }
00342     };
00343 
00344     // Check for and set up driver options
00345     plParseDrvOpts( wx_options );
00346 
00347     // allocate memory for the device storage
00348     switch ( backend )
00349     {
00350     case wxBACKEND_GC:
00351         // in case wxGraphicsContext isn't available, the next backend (agg
00352         // if available) in this list will be used
00353 #if wxUSE_GRAPHICS_CONTEXT
00354         dev = new wxPLDevGC;
00355         // by default the own text routines are used for wxGC
00356         if ( text == -1 )
00357             text = 1;
00358         freetype = 0; // this backend is vector oriented and doesn't know pixels
00359         break;
00360 #endif
00361     case wxBACKEND_AGG:
00362         // in case the agg library isn't available, the standard backend
00363         // will be used
00364 #ifdef HAVE_AGG
00365         dev = new wxPLDevAGG;
00366         // by default the freetype text routines are used for wxAGG
00367         text = 0; // text processing doesn't work yet for the AGG backend
00368         if ( freetype == -1 )
00369             freetype = 1;
00370         break;
00371 #endif
00372     default:
00373         dev = new wxPLDevDC;
00374         // by default the own text routines are used for wxDC
00375         if ( text == -1 )
00376             if ( freetype != 1 )
00377                 text = 1;
00378             else
00379                 text = 0;
00380         if ( freetype == -1 )
00381             freetype = 0;
00382         break;
00383     }
00384     if ( dev == NULL )
00385     {
00386         plexit( "Insufficient memory" );
00387     }
00388     pls->dev = (void *) dev;
00389 
00390 // be verbose and write out debug messages
00391 #ifdef _DEBUG
00392     pls->verbose = 1;
00393     pls->debug   = 1;
00394 #endif
00395 
00396     pls->color     = 1;             // Is a color device
00397     pls->dev_flush = 1;             // Handles flushes
00398     pls->dev_fill0 = 1;             // Can handle solid fills
00399     pls->dev_fill1 = 0;             // Can't handle pattern fills
00400     pls->dev_dash  = 0;
00401     pls->dev_clear = 1;             // driver supports clear
00402 
00403     if ( text )
00404     {
00405         pls->dev_text    = 1; // want to draw text
00406         pls->dev_unicode = 1; // want unicode
00407         if ( hrshsym )
00408             pls->dev_hrshsym = 1;
00409     }
00410 
00411 #ifdef HAVE_FREETYPE
00412     // own text routines have higher priority over freetype
00413     // if text and freetype option are set to 1
00414     if ( !text )
00415     {
00416         dev->smooth_text = smooth_text;
00417         dev->freetype    = freetype;
00418     }
00419 
00420     if ( dev->freetype )
00421     {
00422         pls->dev_text    = 1; // want to draw text
00423         pls->dev_unicode = 1; // want unicode
00424         if ( hrshsym )
00425             pls->dev_hrshsym = 1;
00426 
00427         init_freetype_lv1( pls );
00428         FT_Data* FT = (FT_Data *) pls->FT;
00429         FT->want_smooth_text = smooth_text;
00430     }
00431 #endif
00432 
00433     // initialize frame size and position
00434     if ( pls->xlength <= 0 || pls->ylength <= 0 )
00435         plspage( 0.0, 0.0, (PLINT) ( CANVAS_WIDTH * DEVICE_PIXELS_PER_IN ),
00436             (PLINT) ( CANVAS_HEIGHT * DEVICE_PIXELS_PER_IN ), 0, 0 );
00437 
00438     dev->width    = pls->xlength;
00439     dev->height   = pls->ylength;
00440     dev->clipminx = pls->xlength;
00441     dev->clipminy = pls->ylength;
00442 
00443     if ( pls->xoffset != 0 || pls->yoffset != 0 )
00444     {
00445         dev->xpos = (int) ( pls->xoffset );
00446         dev->ypos = (int) ( pls->yoffset );
00447     }
00448 
00449 
00450     // If portrait mode, apply a rotation and set freeaspect
00451     if ( pls->portrait )
00452     {
00453         plsdiori( (PLFLT) ( 4 - ORIENTATION ) );
00454         pls->freeaspect = 1;
00455     }
00456 
00457     // Set the number of pixels per mm
00458     plP_setpxl( (PLFLT) VIRTUAL_PIXELS_PER_MM, (PLFLT) VIRTUAL_PIXELS_PER_MM );
00459 
00460     // Set up physical limits of plotting device (in drawing units)
00461     plP_setphy( (PLINT) 0, (PLINT) ( CANVAS_WIDTH * VIRTUAL_PIXELS_PER_IN ),
00462         (PLINT) 0, (PLINT) ( CANVAS_HEIGHT * VIRTUAL_PIXELS_PER_IN ) );
00463 
00464     // get physical device limits coordinates
00465     plP_gphy( &dev->xmin, &dev->xmax, &dev->ymin, &dev->ymax );
00466 
00467     // setting scale factors
00468     dev->scalex = (PLFLT) ( dev->xmax - dev->xmin ) / ( dev->width );
00469     dev->scaley = (PLFLT) ( dev->ymax - dev->ymin ) / ( dev->height );
00470 
00471     // set dpi
00472     plspage( VIRTUAL_PIXELS_PER_IN / dev->scalex, VIRTUAL_PIXELS_PER_IN / dev->scaley, 0, 0, 0, 0 );
00473 
00474 #ifdef HAVE_FREETYPE
00475     if ( dev->freetype )
00476         init_freetype_lv2( pls );
00477 #endif
00478 
00479     // find out what file drivers are available
00480     plgFileDevs( &dev->devDesc, &dev->devName, &dev->ndev );
00481 
00482     return dev;
00483 }
00484 
00485 
00486 #ifdef PLD_wxwidgets
00487 
00488 //--------------------------------------------------------------------------
00489 //  void plD_dispatch_init_wxwidgets( PLDispatchTable *pdt )
00490 //
00491 //  Make wxwidgets driver functions known to plplot.
00492 //--------------------------------------------------------------------------
00493 void plD_dispatch_init_wxwidgets( PLDispatchTable *pdt )
00494 {
00495 #ifndef ENABLE_DYNDRIVERS
00496     pdt->pl_MenuStr = "wxWidgets DC";
00497     pdt->pl_DevName = "wxwidgets";
00498 #endif
00499     pdt->pl_type     = plDevType_Interactive;
00500     pdt->pl_seq      = 51;
00501     pdt->pl_init     = (plD_init_fp) plD_init_wxwidgets;
00502     pdt->pl_line     = (plD_line_fp) plD_line_wxwidgets;
00503     pdt->pl_polyline = (plD_polyline_fp) plD_polyline_wxwidgets;
00504     pdt->pl_eop      = (plD_eop_fp) plD_eop_wxwidgets;
00505     pdt->pl_bop      = (plD_bop_fp) plD_bop_wxwidgets;
00506     pdt->pl_tidy     = (plD_tidy_fp) plD_tidy_wxwidgets;
00507     pdt->pl_state    = (plD_state_fp) plD_state_wxwidgets;
00508     pdt->pl_esc      = (plD_esc_fp) plD_esc_wxwidgets;
00509 }
00510 
00511 //--------------------------------------------------------------------------
00512 //  plD_init_wxwidgets( PLStream* pls )
00513 //
00514 //  Initialize wxWidgets device.
00515 //--------------------------------------------------------------------------
00516 void plD_init_wxwidgets( PLStream* pls )
00517 {
00518     // Log_Verbose( "plD_init_wxwidgets()" );
00519 
00520     wxPLDevBase* dev;
00521     dev = common_init( pls );
00522 
00523     pls->plbuf_write = 1;             // use the plot buffer!
00524     pls->termin      = 1;             // interactive device
00525     pls->graphx      = GRAPHICS_MODE; //  No text mode for this driver (at least for now, might add a console window if I ever figure it out and have the inclination)
00526 
00527     dev->showGUI    = true;
00528     dev->bitmapType = (wxBitmapType) 0;
00529 }
00530 
00531 #endif  // PLD_wxwidgets
00532 
00533 
00534 #ifdef PLD_wxpng
00535 
00536 //--------------------------------------------------------------------------
00537 //  void plD_dispatch_init_wxpng( PLDispatchTable *pdt )
00538 //
00539 //  Make wxpng driver functions known to plplot.
00540 //--------------------------------------------------------------------------
00541 void plD_dispatch_init_wxpng( PLDispatchTable *pdt )
00542 {
00543 #ifndef ENABLE_DYNDRIVERS
00544     pdt->pl_MenuStr = "wxWidgets PNG driver";
00545     pdt->pl_DevName = "wxpng";
00546 #endif
00547     pdt->pl_type     = plDevType_FileOriented;
00548     pdt->pl_seq      = 52;
00549     pdt->pl_init     = (plD_init_fp) plD_init_wxpng;
00550     pdt->pl_line     = (plD_line_fp) plD_line_wxwidgets;
00551     pdt->pl_polyline = (plD_polyline_fp) plD_polyline_wxwidgets;
00552     pdt->pl_eop      = (plD_eop_fp) plD_eop_wxwidgets;
00553     pdt->pl_bop      = (plD_bop_fp) plD_bop_wxwidgets;
00554     pdt->pl_tidy     = (plD_tidy_fp) plD_tidy_wxwidgets;
00555     pdt->pl_state    = (plD_state_fp) plD_state_wxwidgets;
00556     pdt->pl_esc      = (plD_esc_fp) plD_esc_wxwidgets;
00557 }
00558 
00559 //--------------------------------------------------------------------------
00560 //  void plD_init_wxpng( PLStream *pls )
00561 //
00562 //  Initialize wxpng device.
00563 //--------------------------------------------------------------------------
00564 void plD_init_wxpng( PLStream *pls )
00565 {
00566     // Log_Verbose( "plD_init_wxwidgets()" );
00567 
00568     wxPLDevBase* dev;
00569     dev = common_init( pls );
00570 
00571     // Initialize family file info
00572     plFamInit( pls );
00573 
00574     // Prompt for a file name if not already set.
00575     plOpenFile( pls );
00576 
00577     pls->plbuf_write = 1;             // use the plot buffer!
00578     pls->dev_flush   = 0;             // No need for flushes
00579     pls->termin      = 0;             // file oriented device
00580     pls->graphx      = GRAPHICS_MODE; //  No text mode for this driver (at least for now, might add a console window if I ever figure it out and have the inclination)
00581     pls->page        = 0;
00582 
00583     dev->showGUI    = false;
00584     dev->bitmapType = wxBITMAP_TYPE_PNG;
00585 }
00586 
00587 #endif  // PLD_wxpng
00588 
00589 
00590 //--------------------------------------------------------------------------
00591 //  void plD_line_wxwidgets( PLStream *pls, short x1a, short y1a,
00592 //                                                                                                       short x2a, short y2a )
00593 //
00594 //  Draws a line from (x1a, y1a) to (x2a, y2a).
00595 //--------------------------------------------------------------------------
00596 void plD_line_wxwidgets( PLStream *pls, short x1a, short y1a, short x2a, short y2a )
00597 {
00598     // Log_Verbose( "plD_line_wxwidgets(x1a=%d, y1a=%d, x2a=%d, y2a=%d)", x1a, y1a, x2a, y2a );
00599 
00600     wxPLDevBase* dev = (wxPLDevBase *) pls->dev;
00601 
00602     if ( !( dev->ready ) )
00603         install_buffer( pls );
00604 
00605     dev->DrawLine( x1a, y1a, x2a, y2a );
00606 
00607     if ( !( dev->resizing ) && dev->ownGUI )
00608     {
00609         dev->comcount++;
00610         if ( dev->comcount > MAX_COMCOUNT )
00611         {
00612             wxRunApp( pls, true );
00613             dev->comcount = 0;
00614         }
00615     }
00616 }
00617 
00618 
00619 //--------------------------------------------------------------------------
00620 //  void plD_polyline_wxwidgets( PLStream *pls, short *xa, short *ya,
00621 //                                                                                                                       PLINT npts )
00622 //
00623 //  Draw a poly line - points are in xa and ya arrays.
00624 //--------------------------------------------------------------------------
00625 void plD_polyline_wxwidgets( PLStream *pls, short *xa, short *ya, PLINT npts )
00626 {
00627     // Log_Verbose( "plD_polyline_wxwidgets()" );
00628 
00629     // should be changed to use the wxDC::DrawLines function?
00630     wxPLDevBase* dev = (wxPLDevBase *) pls->dev;
00631 
00632     if ( !( dev->ready ) )
00633         install_buffer( pls );
00634 
00635     dev->DrawPolyline( xa, ya, npts );
00636 
00637     if ( !( dev->resizing ) && dev->ownGUI )
00638     {
00639         dev->comcount++;
00640         if ( dev->comcount > MAX_COMCOUNT )
00641         {
00642             wxRunApp( pls, true );
00643             dev->comcount = 0;
00644         }
00645     }
00646 }
00647 
00648 
00649 //--------------------------------------------------------------------------
00650 //  void plD_eop_wxwidgets( PLStream *pls )
00651 //
00652 //  End of Page. This function is called if a "end of page" is send by the
00653 //  user. This command is ignored if we have the plot embedded in a
00654 //  wxWidgets application, otherwise the application created by the device
00655 //  takes over.
00656 //--------------------------------------------------------------------------
00657 void plD_eop_wxwidgets( PLStream *pls )
00658 {
00659     // Log_Verbose( "plD_eop_wxwidgets()" );
00660 
00661     wxPLDevBase* dev = (wxPLDevBase *) pls->dev;
00662 
00663     if ( dev->bitmapType )
00664     {
00665         wxMemoryDC memDC;
00666         wxBitmap   bitmap( dev->width, dev->height, -1 );
00667         memDC.SelectObject( bitmap );
00668 
00669         dev->BlitRectangle( &memDC, 0, 0, dev->width, dev->height );
00670         wxImage             buffer = bitmap.ConvertToImage();
00671         wxFFileOutputStream fstream( pls->OutFile );
00672         if ( !( buffer.SaveFile( fstream, dev->bitmapType ) ) )
00673             puts( "Troubles saving file!" );
00674         memDC.SelectObject( wxNullBitmap );
00675     }
00676 
00677     if ( dev->ownGUI )
00678         if ( pls->nopause || !dev->showGUI )
00679             wxRunApp( pls, true );
00680         else
00681             wxRunApp( pls );
00682 }
00683 
00684 
00685 //--------------------------------------------------------------------------
00686 //  void plD_bop_wxwidgets( PLStream *pls )
00687 //
00688 //  Begin of page. Before any plot command, this function is called, If we
00689 //  have already a dc the background is cleared in background color and some
00690 //  state calls are resent - this is because at the first call of this
00691 //  function, a dc does most likely not exist, but state calls are recorded
00692 //  and when a new dc is created this function is called again.
00693 //--------------------------------------------------------------------------
00694 void plD_bop_wxwidgets( PLStream *pls )
00695 {
00696     // Log_Verbose( "plD_bop_wxwidgets()" );
00697 
00698     wxPLDevBase* dev = (wxPLDevBase *) pls->dev;
00699 
00700     if ( dev->ready )
00701     {
00702         //if( pls->termin==0 ) {
00703         // plGetFam( pls );
00704         // force new file if pls->family set for all subsequent calls to plGetFam
00705         // n.b. putting this after plGetFam call is important since plinit calls
00706         // bop, and you don't want the familying sequence started until after
00707         // that first call to bop.
00708 
00709         // n.b. pls->dev can change because of an indirect call to plD_init_png
00710         // from plGetFam if familying is enabled.  Thus, wait to define dev until
00711         // now.
00712         //dev = (wxPLDevBase*)pls->dev;
00713         //
00714         // pls->famadv = 1;
00715         // pls->page++;
00716         // }
00717 
00718         // clear background
00719         PLINT bgr, bgg, bgb;                  // red, green, blue
00720         plgcolbg( &bgr, &bgg, &bgb );         // get background color information
00721         dev->ClearBackground( bgr, bgg, bgb );
00722 
00723         // Replay escape calls that come in before PLESC_DEVINIT.  All of them
00724         // required a DC that didn't exist yet.
00725         //
00726         if ( dev->plstate_width )
00727             plD_state_wxwidgets( pls, PLSTATE_WIDTH );
00728         dev->plstate_width = false;
00729 
00730         if ( dev->plstate_color0 )
00731             plD_state_wxwidgets( pls, PLSTATE_COLOR0 );
00732         dev->plstate_color0 = false;
00733 
00734         if ( dev->plstate_color1 )
00735             plD_state_wxwidgets( pls, PLSTATE_COLOR1 );
00736         dev->plstate_color1 = false;
00737 
00738         // why this? xwin driver has this
00739         // pls->page++;
00740     }
00741 }
00742 
00743 
00744 //--------------------------------------------------------------------------
00745 //  void plD_tidy_wxwidgets( PLStream *pls )
00746 //
00747 //  This function is called, if all plots are done.
00748 //--------------------------------------------------------------------------
00749 void plD_tidy_wxwidgets( PLStream *pls )
00750 {
00751     // Log_Verbose( "plD_tidy_wxwidgets()" );
00752 
00753     wxPLDevBase* dev = (wxPLDevBase *) pls->dev;
00754 
00755 #ifdef HAVE_FREETYPE
00756     if ( dev->freetype )
00757     {
00758         FT_Data *FT = (FT_Data *) pls->FT;
00759         plscmap0n( FT->ncol0_org );
00760         plD_FreeType_Destroy( pls );
00761     }
00762 #endif
00763 
00764     if ( dev->ownGUI )
00765     {
00766         wxPLGetApp().RemoveFrame( dev->m_frame );
00767         if ( !wxPLGetApp().FrameCount() )
00768             wxUninitialize();
00769     }
00770 
00771     delete dev;
00772     pls->dev = NULL; // since in plcore.c pls->dev is free_mem'd
00773 }
00774 
00775 
00776 //--------------------------------------------------------------------------
00777 //  void plD_state_wxwidgets( PLStream *pls, PLINT op )
00778 //
00779 //  Handler for several state codes. Here we take care of setting the width
00780 //  and color of the pen.
00781 //--------------------------------------------------------------------------
00782 void plD_state_wxwidgets( PLStream *pls, PLINT op )
00783 {
00784     // Log_Verbose( "plD_state_wxwidgets(op=%d)", op );
00785 
00786     wxPLDevBase* dev = (wxPLDevBase *) pls->dev;
00787 
00788     switch ( op )
00789     {
00790     case PLSTATE_WIDTH: // 1
00791         if ( dev->ready )
00792             dev->SetWidth( pls );
00793         else
00794             dev->plstate_width = true;
00795         break;
00796 
00797     case PLSTATE_COLOR0: // 2
00798         if ( dev->ready )
00799             dev->SetColor0( pls );
00800         else
00801             dev->plstate_color0 = true;
00802         break;
00803 
00804     case PLSTATE_COLOR1: // 3
00805         if ( dev->ready )
00806             dev->SetColor1( pls );
00807         else
00808             dev->plstate_color1 = true;
00809         break;
00810 
00811     default:
00812         if ( !( dev->ready ) )
00813             install_buffer( pls );
00814     }
00815 }
00816 
00817 
00818 //--------------------------------------------------------------------------
00819 //  void plD_esc_wxwidgets( PLStream *pls, PLINT op, void *ptr )
00820 //
00821 //  Handler for several escape codes. Here we take care of filled polygons,
00822 //  XOR or copy mode, initialize device (install dc from outside), and if
00823 //  there is freetype support, rerendering of text.
00824 //--------------------------------------------------------------------------
00825 void plD_esc_wxwidgets( PLStream *pls, PLINT op, void *ptr )
00826 {
00827     // Log_Verbose( "plD_esc_wxwidgets(op=%d, ptr=%x)", op, ptr );
00828 
00829     wxPLDevBase* dev = (wxPLDevBase *) pls->dev;
00830 
00831     switch ( op )
00832     {
00833     case PLESC_FILL:
00834         fill_polygon( pls );
00835         break;
00836 
00837     case PLESC_XORMOD:
00838         // switch between wxXOR and wxCOPY
00839         // if( dev->ready ) {
00840         //                  if( dev->m_dc->GetLogicalFunction() == wxCOPY )
00841         //                          dev->m_dc->SetLogicalFunction( wxXOR );
00842         //                  else if( dev->m_dc->GetLogicalFunction() == wxXOR )
00843         //                          dev->m_dc->SetLogicalFunction( wxCOPY );
00844         //          }
00845         break;
00846 
00847     case PLESC_DEVINIT:
00848         dev->SetExternalBuffer( ptr );
00849 
00850         // replay begin of page call and state settings
00851         plD_bop_wxwidgets( pls );
00852         break;
00853 
00854     case PLESC_HAS_TEXT:
00855         if ( !( dev->ready ) )
00856             install_buffer( pls );
00857 
00858         if ( dev->freetype )
00859         {
00860 #ifdef HAVE_FREETYPE
00861             plD_render_freetype_text( pls, (EscText *) ptr );
00862 #endif
00863         }
00864         else
00865             dev->ProcessString( pls, (EscText *) ptr );
00866         break;
00867 
00868     case PLESC_RESIZE:
00869     {
00870         wxSize* size = (wxSize *) ptr;
00871         wx_set_size( pls, size->GetWidth(), size->GetHeight() );
00872     }
00873     break;
00874 
00875     case PLESC_CLEAR:
00876         if ( !( dev->ready ) )
00877             install_buffer( pls );
00878         // Since the plot is updated only every MAX_COMCOUNT commands (usually 5000)
00879         //       before we clear the screen we need to show the plot at least once :)
00880         if ( !( dev->resizing ) && dev->ownGUI )
00881         {
00882             wxRunApp( pls, true );
00883             dev->comcount = 0;
00884         }
00885         dev->ClearBackground( pls->cmap0[0].r, pls->cmap0[0].g, pls->cmap0[0].b,
00886             pls->sppxmi, pls->sppymi, pls->sppxma, pls->sppyma );
00887         break;
00888 
00889     case PLESC_FLUSH:        // forced update of the window
00890         if ( !( dev->resizing ) && dev->ownGUI )
00891         {
00892             wxRunApp( pls, true );
00893             dev->comcount = 0;
00894         }
00895         break;
00896 
00897     case PLESC_GETC:
00898         if ( dev->ownGUI )
00899             GetCursorCmd( pls, (PLGraphicsIn *) ptr );
00900         break;
00901 
00902     case PLESC_GETBACKEND:
00903         *( (int *) ptr ) = dev->backend;
00904         break;
00905 
00906     default:
00907         break;
00908     }
00909 }
00910 
00911 
00912 //--------------------------------------------------------------------------
00913 //  static void fill_polygon( PLStream *pls )
00914 //
00915 //  Fill polygon described in points pls->dev_x[] and pls->dev_y[].
00916 //--------------------------------------------------------------------------
00917 static void fill_polygon( PLStream *pls )
00918 {
00919     // Log_Verbose( "fill_polygon(), npts=%d, x[0]=%d, y[0]=%d", pls->dev_npts, pls->dev_y[0], pls->dev_y[0] );
00920 
00921     wxPLDevBase* dev = (wxPLDevBase *) pls->dev;
00922 
00923     if ( !( dev->ready ) )
00924         install_buffer( pls );
00925 
00926     dev->FillPolygon( pls );
00927 
00928     if ( !( dev->resizing ) && dev->ownGUI )
00929     {
00930         dev->comcount += 10;
00931         if ( dev->comcount > MAX_COMCOUNT )
00932         {
00933             wxRunApp( pls, true );
00934             dev->comcount = 0;
00935         }
00936     }
00937 }
00938 
00939 
00940 //--------------------------------------------------------------------------
00941 //  void wx_set_size( PLStream* pls, int width, int height )
00942 //
00943 //  Adds a dc to the stream. The associated device is attached to the canvas
00944 //  as the property "dev".
00945 //--------------------------------------------------------------------------
00946 void wx_set_size( PLStream* pls, int width, int height )
00947 {
00948     // TODO: buffer must be resized here or in wxplotstream
00949     // Log_Verbose( "wx_set_size()" );
00950 
00951     wxPLDevBase* dev = (wxPLDevBase *) pls->dev;
00952 
00953     // set new size and scale parameters
00954     dev->width  = width;
00955     dev->height = height;
00956     dev->scalex = (PLFLT) ( dev->xmax - dev->xmin ) / dev->width;
00957     dev->scaley = (PLFLT) ( dev->ymax - dev->ymin ) / dev->height;
00958 
00959     // recalculate the dpi used in calculation of fontsize
00960     pls->xdpi = VIRTUAL_PIXELS_PER_IN / dev->scalex;
00961     pls->ydpi = VIRTUAL_PIXELS_PER_IN / dev->scaley;
00962 
00963     // clear background if we have a dc, since it's invalid (TODO: why, since in bop
00964     // it must be cleared anyway?)
00965     if ( dev->ready )
00966     {
00967         PLINT bgr, bgg, bgb;                  // red, green, blue
00968         plgcolbg( &bgr, &bgg, &bgb );         // get background color information
00969 
00970         dev->CreateCanvas();
00971         dev->ClearBackground( bgr, bgg, bgb );
00972     }
00973 
00974     // freetype parameters must also be changed
00975 #ifdef HAVE_FREETYPE
00976     if ( dev->freetype )
00977     {
00978         FT_Data *FT = (FT_Data *) pls->FT;
00979         FT->scalex = dev->scalex;
00980         FT->scaley = dev->scaley;
00981         FT->ymax   = dev->height;
00982     }
00983 #endif
00984 }
00985 
00986 
00987 //--------------------------------------------------------------------------
00988 //  int plD_errorexithandler_wxwidgets( const char *errormessage )
00989 //
00990 //  If an PLplot error occurs, this function shows a dialog regarding
00991 //  this error and than exits.
00992 //--------------------------------------------------------------------------
00993 int plD_errorexithandler_wxwidgets( const char *errormessage )
00994 {
00995     if ( errormessage[0] )
00996     {
00997         wxMessageDialog dialog( 0, wxString( errormessage, *wxConvCurrent ), wxString( "wxWidgets PLplot App error", *wxConvCurrent ), wxOK | wxICON_ERROR );
00998         dialog.ShowModal();
00999     }
01000 
01001     return 0;
01002 }
01003 
01004 
01005 //--------------------------------------------------------------------------
01006 //  void plD_erroraborthandler_wxwidgets( const char *errormessage )
01007 //
01008 //  If PLplot aborts, this function shows a dialog regarding
01009 //  this error.
01010 //--------------------------------------------------------------------------
01011 void plD_erroraborthandler_wxwidgets( const char *errormessage )
01012 {
01013     if ( errormessage[0] )
01014     {
01015         wxMessageDialog dialog( 0, ( wxString( errormessage, *wxConvCurrent ) + wxString( " aborting operation...", *wxConvCurrent ) ), wxString( "wxWidgets PLplot App abort", *wxConvCurrent ), wxOK | wxICON_ERROR );
01016         dialog.ShowModal();
01017     }
01018 }
01019 
01020 
01021 
01022 
01023 #ifdef HAVE_FREETYPE
01024 
01025 //--------------------------------------------------------------------------
01026 //  static void plD_pixel_wxwidgets( PLStream *pls, short x, short y )
01027 //
01028 //  callback function, of type "plD_pixel_fp", which specifies how a single
01029 //  pixel is set in the current colour.
01030 //--------------------------------------------------------------------------
01031 static void plD_pixel_wxwidgets( PLStream *pls, short x, short y )
01032 {
01033     // Log_Verbose( "plD_pixel_wxwidgets" );
01034 
01035     wxPLDevBase *dev = (wxPLDevBase *) pls->dev;
01036 
01037     if ( !( dev->ready ) )
01038         install_buffer( pls );
01039 
01040     dev->PutPixel( x, y );
01041 
01042     if ( !( dev->resizing ) && dev->ownGUI )
01043     {
01044         dev->comcount++;
01045         if ( dev->comcount > MAX_COMCOUNT )
01046         {
01047             wxRunApp( pls, true );
01048             dev->comcount = 0;
01049         }
01050     }
01051 }
01052 
01053 
01054 //--------------------------------------------------------------------------
01055 //  static void plD_pixel_wxwidgets( PLStream *pls, short x, short y )
01056 //
01057 //  callback function, of type "plD_pixel_fp", which specifies how a single
01058 //  pixel is set in the current colour.
01059 //--------------------------------------------------------------------------
01060 static void plD_set_pixel_wxwidgets( PLStream *pls, short x, short y, PLINT colour )
01061 {
01062     // Log_Verbose( "plD_set_pixel_wxwidgets" );
01063 
01064     wxPLDevBase *dev = (wxPLDevBase *) pls->dev;
01065 
01066     if ( !( dev->ready ) )
01067         install_buffer( pls );
01068 
01069     dev->PutPixel( x, y, colour );
01070 
01071     if ( !( dev->resizing ) && dev->ownGUI )
01072     {
01073         dev->comcount++;
01074         if ( dev->comcount > MAX_COMCOUNT )
01075         {
01076             wxRunApp( pls, true );
01077             dev->comcount = 0;
01078         }
01079     }
01080 }
01081 
01082 
01083 //--------------------------------------------------------------------------
01084 //  void plD_read_pixel_wxwidgets (PLStream *pls, short x, short y)
01085 //
01086 //  callback function, of type "plD_pixel_fp", which specifies how a single
01087 //  pixel is read.
01088 //--------------------------------------------------------------------------
01089 static PLINT plD_read_pixel_wxwidgets( PLStream *pls, short x, short y )
01090 {
01091     // Log_Verbose( "plD_read_pixel_wxwidgets" );
01092 
01093     wxPLDevBase *dev = (wxPLDevBase *) pls->dev;
01094 
01095     if ( !( dev->ready ) )
01096         install_buffer( pls );
01097 
01098     return dev->GetPixel( x, y );
01099 }
01100 
01101 
01102 //--------------------------------------------------------------------------
01103 //  void init_freetype_lv1 (PLStream *pls)
01104 //
01105 //  "level 1" initialisation of the freetype library.
01106 //  "Level 1" initialisation calls plD_FreeType_init(pls) which allocates
01107 //  memory to the pls->FT structure, then sets up the pixel callback
01108 //  function.
01109 //--------------------------------------------------------------------------
01110 static void init_freetype_lv1( PLStream *pls )
01111 {
01112     // Log_Verbose( "init_freetype_lv1" );
01113 
01114     wxPLDevBase *dev = (wxPLDevBase *) pls->dev;
01115 
01116     plD_FreeType_init( pls );
01117 
01118     FT_Data *FT = (FT_Data *) pls->FT;
01119     FT->pixel = (plD_pixel_fp) plD_pixel_wxwidgets;
01120 
01121     //
01122     //  See if we have a 24 bit device (or better), in which case
01123     //  we can use the better antialising.
01124     //
01125     // the bitmap we are using in the antialized case has always
01126     // 32 bit depth
01127     FT->BLENDED_ANTIALIASING = 1;
01128     FT->read_pixel           = (plD_read_pixel_fp) plD_read_pixel_wxwidgets;
01129     FT->set_pixel            = (plD_set_pixel_fp) plD_set_pixel_wxwidgets;
01130 }
01131 
01132 
01133 //--------------------------------------------------------------------------
01134 //  void init_freetype_lv2 (PLStream *pls)
01135 //
01136 //  "Level 2" initialisation of the freetype library.
01137 //  "Level 2" fills in a few setting that aren't public until after the
01138 //  graphics sub-syetm has been initialised.
01139 //  The "level 2" initialisation fills in a few things that are defined
01140 //  later in the initialisation process for the GD driver.
01141 //
01142 //  FT->scale is a scaling factor to convert co-ordinates. This is used by
01143 //  the GD and other drivers to scale back a larger virtual page and this
01144 //  eliminate the "hidden line removal bug". Set it to 1 if your device
01145 //  doesn't have scaling.
01146 //
01147 //  Some coordinate systems have zero on the bottom, others have zero on
01148 //  the top. Freetype does it one way, and most everything else does it the
01149 //  other. To make sure everything is working ok, we have to "flip" the
01150 //  coordinates, and to do this we need to know how big in the Y dimension
01151 //  the page is, and whether we have to invert the page or leave it alone.
01152 //
01153 //  FT->ymax specifies the size of the page FT->invert_y=1 tells us to
01154 //  invert the y-coordinates, FT->invert_y=0 will not invert the
01155 //  coordinates.
01156 //--------------------------------------------------------------------------
01157 
01158 static void init_freetype_lv2( PLStream *pls )
01159 {
01160     // Log_Verbose( "init_freetype_lv2" );
01161 
01162     wxPLDevBase *dev = (wxPLDevBase *) pls->dev;
01163     FT_Data     *FT  = (FT_Data *) pls->FT;
01164 
01165     FT->scalex      = dev->scalex;
01166     FT->scaley      = dev->scaley;
01167     FT->ymax        = dev->height;
01168     FT->invert_y    = 1;
01169     FT->smooth_text = 0;
01170 
01171     if ( ( FT->want_smooth_text == 1 ) && ( FT->BLENDED_ANTIALIASING == 0 ) ) // do we want to at least *try* for smoothing ?
01172     {
01173         FT->ncol0_org   = pls->ncol0;                                         // save a copy of the original size of ncol0
01174         FT->ncol0_xtra  = 16777216 - ( pls->ncol1 + pls->ncol0 );             // work out how many free slots we have
01175         FT->ncol0_width = FT->ncol0_xtra / ( pls->ncol0 - 1 );                // find out how many different shades of anti-aliasing we can do
01176         if ( FT->ncol0_width > 4 )                                            // are there enough colour slots free for text smoothing ?
01177         {
01178             if ( FT->ncol0_width > max_number_of_grey_levels_used_in_text_smoothing )
01179                 FT->ncol0_width = max_number_of_grey_levels_used_in_text_smoothing;           // set a maximum number of shades
01180             plscmap0n( FT->ncol0_org + ( FT->ncol0_width * pls->ncol0 ) );                    // redefine the size of cmap0
01181             // the level manipulations are to turn off the plP_state(PLSTATE_CMAP0)
01182             // call in plscmap0 which (a) leads to segfaults since the GD image is
01183             // not defined at this point and (b) would be inefficient in any case since
01184             // setcmap is always called later (see plD_bop_png) to update the driver
01185             // color palette to be consistent with cmap0.
01186             {
01187                 PLINT level_save;
01188                 level_save = pls->level;
01189                 pls->level = 0;
01190                 pl_set_extended_cmap0( pls, FT->ncol0_width, FT->ncol0_org ); // call the function to add the extra cmap0 entries and calculate stuff
01191                 pls->level = level_save;
01192             }
01193             FT->smooth_text = 1; // Yippee ! We had success setting up the extended cmap0
01194         }
01195         else
01196             plwarn( "Insufficient colour slots available in CMAP0 to do text smoothing." );
01197     }
01198     else if ( ( FT->want_smooth_text == 1 ) && ( FT->BLENDED_ANTIALIASING == 1 ) )    // If we have a truecolour device, we wont even bother trying to change the palette
01199     {
01200         FT->smooth_text = 1;
01201     }
01202 }
01203 
01204 #endif
01205 
01206 
01207 //--------------------------------------------------------------------------
01208 // GetCursorCmd()
01209 //
01210 // Waits for a graphics input event and returns coordinates.
01211 //--------------------------------------------------------------------------
01212 static void GetCursorCmd( PLStream* pls, PLGraphicsIn* ptr )
01213 {
01214     // Log_Verbose( "GetCursorCmd" );
01215 
01216     wxPLDevBase  *dev = (wxPLDevBase *) pls->dev;
01217     PLGraphicsIn *gin = &( dev->gin );
01218 
01219     // Initialize
01220     plGinInit( gin );
01221     dev->locate_mode = LOCATE_INVOKED_VIA_API;
01222     dev->draw_xhair  = true;
01223 
01224     // Run event loop until a point is selected
01225     wxRunApp( pls, false );
01226 
01227     *ptr = *gin;
01228     if ( dev->locate_mode )
01229     {
01230         dev->locate_mode = 0;
01231         dev->draw_xhair  = false;
01232     }
01233 }
01234 
01235 
01236 
01237 
01238 //--------------------------------------------------------------------------
01239 //  This part includes wxWidgets specific functions, which allow to
01240 //  open a window from the command line, if needed.
01241 //--------------------------------------------------------------------------
01242 
01243 
01244 //--------------------------------------------------------------------------
01245 //  void install_buffer( PLStream *pls )
01246 //
01247 //  If this driver is called from a command line executable (and not
01248 //  from within a wxWidgets program), this function prepares a DC and a
01249 //  bitmap to plot into.
01250 //--------------------------------------------------------------------------
01251 static void install_buffer( PLStream *pls )
01252 {
01253     // Log_Verbose( "install_buffer" );
01254 
01255     wxPLDevBase * dev   = (wxPLDevBase *) pls->dev;
01256     static bool initApp = false;
01257 
01258     if ( !initApp )
01259     {
01260         // this hack enables to have a GUI on Mac OSX even if the
01261         // program was called from the command line (and isn't a bundle)
01262 #ifdef __WXMAC__
01263         ProcessSerialNumber psn;
01264 
01265         GetCurrentProcess( &psn );
01266         CPSEnableForegroundOperation( &psn );
01267         SetFrontProcess( &psn );
01268 #endif
01269 
01270         // initialize wxWidgets
01271         wxInitialize();
01272         wxLog::GetActiveTarget();
01273         wxTRY {
01274             wxPLGetApp().CallOnInit();
01275         }
01276         wxCATCH_ALL( wxPLGetApp().OnUnhandledException(); plexit( "Can't init wxWidgets!" ); )
01277         initApp = true;
01278     }
01279 
01280 
01281     wxString title( pls->plwindow, *wxConvCurrent );
01282     switch ( dev->backend )
01283     {
01284     case wxBACKEND_DC:
01285         title += wxT( " - wxWidgets (basic)" );
01286         break;
01287     case wxBACKEND_GC:
01288         title += wxT( " - wxWidgets (wxGC)" );
01289         break;
01290     case wxBACKEND_AGG:
01291         title += wxT( " - wxWidgets (AGG)" );
01292         break;
01293     default:
01294         break;
01295     }
01296     dev->m_frame = new wxPLplotFrame( title, pls );
01297     wxPLGetApp().AddFrame( dev->m_frame );
01298 
01299     // set size and position of window
01300     dev->m_frame->SetClientSize( dev->width, dev->height );
01301     if ( dev->xpos != 0 || dev->ypos != 0 )
01302         dev->m_frame->SetSize( dev->xpos, dev->ypos,
01303             wxDefaultCoord, wxDefaultCoord,
01304             wxSIZE_USE_EXISTING );
01305 
01306     if ( dev->showGUI )
01307     {
01308         dev->m_frame->Show( true );
01309         dev->m_frame->Raise();
01310     }
01311     else
01312         dev->m_frame->Show( false );
01313 
01314     // get a DC and a bitmap or an imagebuffer
01315     dev->ownGUI    = true;
01316     dev->bm_width  = dev->width;
01317     dev->bm_height = dev->height;
01318     dev->CreateCanvas();
01319     dev->ready = true;
01320 
01321     // Set wx error handler for various errors in plplot
01322     plsexit( plD_errorexithandler_wxwidgets );
01323     plsabort( plD_erroraborthandler_wxwidgets );
01324 
01325     // replay command we may have missed
01326     plD_bop_wxwidgets( pls );
01327 }
01328 
01329 
01330 //--------------------------------------------------------------------------
01331 //  void wxRunApp( PLStream *pls, bool runonce )
01332 //
01333 //  This is a hacked wxEntry-function, so that wxUninitialize is not
01334 //  called twice. Here we actually start the wxApplication.
01335 //--------------------------------------------------------------------------
01336 static void wxRunApp( PLStream *pls, bool runonce )
01337 {
01338     // Log_Verbose( "wxRunApp" );
01339 
01340     wxPLDevBase* dev = (wxPLDevBase *) pls->dev;
01341 
01342     dev->waiting = true;
01343     wxTRY
01344     {
01345         class CallOnExit
01346         {
01347 public:
01348             // only call OnExit if exit is true (i.e. due an exception)
01349             ~CallOnExit() { if ( exit ) wxPLGetApp().OnExit();}
01350             bool exit;
01351         } callOnExit;
01352 
01353         callOnExit.exit = true;
01354         wxPLGetApp().SetAdvanceFlag( runonce );
01355         wxPLGetApp().SetRefreshFlag();
01356 
01357         // add an idle event is necessary for Linux (wxGTK2)
01358         // but not for Windows, but it doesn't harm
01359         wxIdleEvent event;
01360         wxPLGetApp().AddPendingEvent( event );
01361         wxPLGetApp().OnRun();           // start wxWidgets application
01362         callOnExit.exit = false;
01363     }
01364     wxCATCH_ALL( wxPLGetApp().OnUnhandledException(); plexit( "Problem running wxWidgets!" ); )
01365 
01366     if ( dev->exit )
01367     {
01368         wxPLGetApp().OnExit();
01369         plexit( "" );
01370     }
01371 
01372     dev->waiting = false;
01373 }

Generated on Wed Oct 12 2011 20:42:23 for PLplot by  doxygen 1.7.1