]> git.saurik.com Git - wxWidgets.git/commitdiff
It's possible now to save to a PNG. OK, I still
authorRobert Roebling <robert@roebling.de>
Thu, 3 Sep 1998 21:46:47 +0000 (21:46 +0000)
committerRobert Roebling <robert@roebling.de>
Thu, 3 Sep 1998 21:46:47 +0000 (21:46 +0000)
    have performance problems, but it's a start.
  Updated install.txt.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@662 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

17 files changed:
docs/gtk/install.txt
include/wx/gtk/bitmap.h
include/wx/gtk/dc.h
include/wx/gtk1/bitmap.h
include/wx/gtk1/dc.h
samples/png/pngdemo.cpp
samples/png/pngdemo.h
src/gtk/bitmap.cpp
src/gtk/dc.cpp
src/gtk/dcclient.cpp
src/gtk/dcmemory.cpp
src/gtk/menu.cpp
src/gtk1/bitmap.cpp
src/gtk1/dc.cpp
src/gtk1/dcclient.cpp
src/gtk1/dcmemory.cpp
src/gtk1/menu.cpp

index 24286b8abfb590c13700899706df2d2486799b54..0eb9f235a2e1975fcedebc2d26e00e97a588252a 100644 (file)
@@ -4,11 +4,20 @@
 If you compile wxWindows on Unix for the first time and don't like
 to read install instructions just do (in the base dir):
 
-./configure --with-gtk --with-shared --without-threads
+./configure --without-threads
 make
 
-and drink 10 coffees.
+and drink 10 coffees. Then you may log in as root and type
 
+make install
+
+You can leave out the --without-threads option if you have a NEW
+Linux distribution based on glibc (e.g. RedHat 5.1) or any other
+Unix that comes with Posix threads or SGI threads.
+
+Now create your super-application myfoo.app and compile anywhere with
+
+gcc -o -c myfoo.cpp -I/usr/local/include -L/usr/local/lib -lwx_gtk
 
 * General
 -----------------------
@@ -141,8 +150,10 @@ not been defined. And Make in some circumstances as well...
 * General options
 -------------------
 
-Obviously, you have to choose a toolkit. You must do this by
-running configure with either of
+Normally, you won't have to choose a toolkit, because when
+you download wxGTK, it will default to --with-gtk etc. But
+if you use all of our CVS repository you have to choose a 
+toolkit. You must do this by running configure with either of:
 
         --with-gtk               Use the GIMP ToolKit (GTK)
        
@@ -155,7 +166,7 @@ The following options handle the kind of library you want to build.
 
        --without-threads       Compile without thread support.
 
-       --with-shared           Create shared libraries.
+       --without-shared        Do not create shared libraries.
 
        --without-optimise      Do not optimise the code.
 
@@ -191,25 +202,21 @@ implemented.
 -------------
 
 The following must be done in the base directory (e.g. ~/wxGTK
-or ~/wxWin)
-
-First you have to create all makefiles in all subdirectories:
-
-       make Makefiles
+or ~/wxWin or whatever)
 
 Dependencies are generated automatically using
 
        make depend
        
-(For some reason, this doesn't seem to work completely.)
+(For some reason, this doesn't seem to work.)
 
 Now the makefiles are created you can compile everything is as simple
 as typing:
 
        make
 
-make yourself some coffee, as it will try to compile
-ALL the files in this distribution.
+make yourself some coffee, as it will try to compile ALL the 
+files in this distribution.
 
 if you want to be more selective:
 
@@ -219,6 +226,13 @@ if you want to be more selective:
        make other      will build the other samples
        make user       will build the files in the directory other
 
+Then you may install the library and it's header files under
+/usr/local/include/wx and /usr/local/lib respectively. You
+have to log in as root (i.e. run "su" and enter the root
+password) and type
+
+        make install   
+       
 Depending on the configuration of some files, the libraries
 and binaries will be placed in different directories.
 The "global" binaries and libraries will be placed in:
@@ -242,8 +256,10 @@ will do the work for you.
 * Creating a new Project
 --------------------------
 
-I propose to put all contributed programs in the directory
-"~/wxWin/user", with a directory of its own.
+There are two ways to create your own project. The first creates
+a project within the source code directories of wxWindows: In this
+case I propose to put all contributed programs in the directory
+"/user", with a directory of its own.
 
 This directory then should include the following files:
 
@@ -258,6 +274,13 @@ Makefile.in        (This is the base application-Makefile template, from
 put ALL your source code along with all the other stuff you need for
 your application in this directory (subdirectories are welcome).
 
+The other way uses the installed libraries and header files in 
+/usr/local/include/wx and /usr/local/lib. In this case, just
+compile your program like this:
+
+gcc -o -c myfoo.cpp -I/usr/local/include -L/usr/local/lib -lwx_gtk
+
+
 ** Something about Makefiles
 ------------------------------
 
index 18f13ad7e3fe0d3e81f91f60d433028e4a616086..dcf1d232689bcf7f58fab43e23f27de735d12f3b 100644 (file)
@@ -131,7 +131,7 @@ class wxBitmap: public wxObject
 
     GdkPixmap *GetPixmap() const;
     GdkBitmap *GetBitmap() const;
-
+  
     void DestroyImage();
     void RecreateImage();
     void Render();
index 683413cd6763bee43025ab90cc787bb2fbdff445..2e3fe8290e13a1b6752c69343ff1f56bb120430b 100644 (file)
@@ -66,7 +66,7 @@ class wxDC: public wxObject
     void BeginDrawing(void) {};
     void EndDrawing(void) {};
     
-    virtual bool Ok(void) const { return m_ok; };
+    virtual bool Ok(void) const;
 
     virtual void FloodFill( long x1, long y1, wxColour *col, int style=wxFLOOD_SURFACE ) = 0;
     virtual bool GetPixel( long x1, long y1, wxColour *col ) const = 0;
index 18f13ad7e3fe0d3e81f91f60d433028e4a616086..dcf1d232689bcf7f58fab43e23f27de735d12f3b 100644 (file)
@@ -131,7 +131,7 @@ class wxBitmap: public wxObject
 
     GdkPixmap *GetPixmap() const;
     GdkBitmap *GetBitmap() const;
-
+  
     void DestroyImage();
     void RecreateImage();
     void Render();
index 683413cd6763bee43025ab90cc787bb2fbdff445..2e3fe8290e13a1b6752c69343ff1f56bb120430b 100644 (file)
@@ -66,7 +66,7 @@ class wxDC: public wxObject
     void BeginDrawing(void) {};
     void EndDrawing(void) {};
     
-    virtual bool Ok(void) const { return m_ok; };
+    virtual bool Ok(void) const;
 
     virtual void FloodFill( long x1, long y1, wxColour *col, int style=wxFLOOD_SURFACE ) = 0;
     virtual bool GetPixel( long x1, long y1, wxColour *col ) const = 0;
index edbaea70a2c0c2235451dd38642e90df966a7dd9..d97f4058ddbc31139610bd5f3c0ab9e241b8df2c 100644 (file)
@@ -52,6 +52,7 @@ bool MyApp::OnInit(void)
   wxMenu *help_menu = new wxMenu;
 
   file_menu->Append(PNGDEMO_LOAD_FILE, "&Load file",                "Load file");
+  file_menu->Append(PNGDEMO_SAVE_FILE, "&Save file",                "Save file");
   file_menu->Append(PNGDEMO_QUIT, "E&xit",                "Quit program");
   help_menu->Append(PNGDEMO_ABOUT, "&About",              "About PNG demo");
 
@@ -80,6 +81,7 @@ BEGIN_EVENT_TABLE(MyFrame, wxFrame)
     EVT_MENU(PNGDEMO_QUIT,      MyFrame::OnQuit)
     EVT_MENU(PNGDEMO_ABOUT,     MyFrame::OnAbout)
     EVT_MENU(PNGDEMO_LOAD_FILE, MyFrame::OnLoadFile)
+    EVT_MENU(PNGDEMO_SAVE_FILE, MyFrame::OnSaveFile)
 END_EVENT_TABLE()
 
 // Define my frame constructor
@@ -100,6 +102,33 @@ void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
             "About PNG Demo", wxOK);
 }
 
+void MyFrame::OnSaveFile(wxCommandEvent& WXUNUSED(event))
+{
+  char *f = wxFileSelector( "Save Image", (const char *)NULL, (const char *)NULL, 
+                            "png", "PNG files (*.png)|*.png" );
+
+  if (!f)  return;
+  
+  wxBitmap *backstore = new wxBitmap( 150, 150 );
+  
+  wxMemoryDC memDC;
+  memDC.SelectObject( *backstore );
+  memDC.Clear();
+  memDC.SetBrush( *wxBLACK_BRUSH );
+  memDC.SetPen( *wxWHITE_PEN );
+  memDC.DrawRectangle( 0, 0, 150, 150 );
+  memDC.SetPen( *wxBLACK_PEN );
+  memDC.DrawLine( 0, 0, 0, 10 );
+  memDC.SetTextForeground( *wxWHITE );
+  memDC.DrawText( "This is a memory dc.", 10, 10 );
+  
+  memDC.SelectObject( wxNullBitmap );
+  
+  backstore->SaveFile( f, wxBITMAP_TYPE_PNG, (wxPalette*)NULL );
+  
+  delete backstore;
+}
+
 void MyFrame::OnLoadFile(wxCommandEvent& WXUNUSED(event))
 {
        // Show file selector.
index e4be03ed4b648e7bc9306eea22e748907aa9c605..eef3432f116cdd15892e314c0a8dbbd86fa96ce8 100644 (file)
@@ -35,6 +35,7 @@ class MyFrame: public wxFrame
     bool OnClose(void);
     void OnActivate(bool) {}
     void OnLoadFile(wxCommandEvent& event);
+    void OnSaveFile(wxCommandEvent& event);
     void OnQuit(wxCommandEvent& event);
     void OnAbout(wxCommandEvent& event);
 DECLARE_EVENT_TABLE()
@@ -54,4 +55,5 @@ DECLARE_EVENT_TABLE()
 #define PNGDEMO_QUIT       100
 #define PNGDEMO_ABOUT      101
 #define PNGDEMO_LOAD_FILE  102
+#define PNGDEMO_SAVE_FILE  103
 
index b06f111e55edc921f33db0902a253c02aab38b6b..e4adea4dd18fd9f0142adc82326db8fae2af0b86 100644 (file)
 #include "gdk/gdkprivate.h"
 
 #ifdef USE_GDK_IMLIB
+
 #include "../gdk_imlib/gdk_imlib.h"
+#include "gdk/gdkx.h"        // GDK_DISPLAY
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+
 #endif
 
 //-----------------------------------------------------------------------------
@@ -223,7 +228,8 @@ bool wxBitmap::operator != ( const wxBitmap& bmp )
   
 bool wxBitmap::Ok(void) const
 {
-  return m_refData != NULL;
+  wxASSERT_MSG( m_refData != NULL, "invalid bitmap" );
+  return (m_refData != NULL);
 }
   
 int wxBitmap::GetHeight(void) const
@@ -247,18 +253,27 @@ int wxBitmap::GetDepth(void) const
 void wxBitmap::SetHeight( int height )
 {
   if (!Ok()) return;
+  
+  wxFAIL_MSG( "wxBitmap::SetHeight not implemented" );
+  
   M_BMPDATA->m_height = height;
 }
 
 void wxBitmap::SetWidth( int width )
 {
   if (!Ok()) return;
+  
+  wxFAIL_MSG( "wxBitmap::SetWidth not implemented" );
+  
   M_BMPDATA->m_width = width;
 }
 
 void wxBitmap::SetDepth( int depth )
 {
   if (!Ok()) return;
+  
+  wxFAIL_MSG( "wxBitmap::SetDepth not implemented" );
+  
   M_BMPDATA->m_bpp = depth;
 }
 
@@ -274,6 +289,7 @@ void wxBitmap::SetMask( wxMask *mask )
   if (!Ok()) return;
   
   if (M_BMPDATA->m_mask) delete M_BMPDATA->m_mask;
+  
   M_BMPDATA->m_mask = mask;
 }
 
@@ -298,6 +314,10 @@ void wxBitmap::Resize( int height, int width )
   
   Render();
   
+#else
+  
+  wxFAIL_MSG( "wxBitmap::Resize not implemented without GdkImlib" );
+  
 #endif
 }
 
@@ -312,6 +332,10 @@ bool wxBitmap::SaveFile( const wxString &name, int WXUNUSED(type),
   
   return gdk_imlib_save_image( M_BMPDATA->m_image, WXSTRINGCAST name, (GdkImlibSaveInfo *) NULL );
 
+#else
+  
+  wxFAIL_MSG( "wxBitmap::SaveFile not implemented without GdkImlib" );
+  
 #endif
 
   return FALSE;
@@ -338,6 +362,11 @@ bool wxBitmap::LoadFile( const wxString &name, int WXUNUSED(type) )
   M_BMPDATA->m_bpp = 24; // ?
   
   return TRUE;
+  
+#else
+  
+  wxFAIL_MSG( "wxBitmap::LoadFile not implemented without GdkImlib" );
+  
 #endif
 
   return FALSE;
@@ -352,6 +381,9 @@ wxPalette *wxBitmap::GetPalette(void) const
 GdkPixmap *wxBitmap::GetPixmap(void) const
 {
   if (!Ok()) return (GdkPixmap *) NULL;
+  
+//  if (!M_BMPDATA->m_image) RecreateImage();
+  
   return M_BMPDATA->m_pixmap;
 }
   
@@ -375,6 +407,53 @@ void wxBitmap::DestroyImage(void)
 
 void wxBitmap::RecreateImage(void)
 {
+  if (!Ok()) return;
+  
+#ifdef USE_GDK_IMLIB
+
+  DestroyImage();
+  
+  wxCHECK_RET( M_BMPDATA->m_pixmap != NULL, "invalid bitmap" );
+  
+  long size = (long)(M_BMPDATA->m_width)*(long)(M_BMPDATA->m_height)*(long)3;
+  unsigned char *data = new unsigned char[size];
+  for (long i = 0; i < size; i++) data[i] = 100;
+  
+  GdkImage *image = gdk_image_get( M_BMPDATA->m_pixmap, 0, 0, M_BMPDATA->m_width, M_BMPDATA->m_height );
+  
+  long pos = 0;
+  for (int j = 0; j < M_BMPDATA->m_height; j++)
+  {
+    for (int i = 0; i < M_BMPDATA->m_width; i++)
+    {
+      XColor xcol;
+      xcol.pixel = gdk_image_get_pixel( image, i, j );
+      Colormap cm = ((GdkColormapPrivate*)gdk_imlib_get_colormap())->xcolormap;
+      XQueryColor( gdk_display, cm, &xcol );
+      
+      data[pos] = xcol.red;
+      data[pos+1] = xcol.green;
+      data[pos+2] = xcol.blue;
+      pos += 3;
+    }
+  }
+  
+  wxCHECK_RET( M_BMPDATA->m_pixmap != NULL, "invalid bitmap" );
+  
+  M_BMPDATA->m_image = gdk_imlib_create_image_from_data( 
+     data, (unsigned char*)NULL, M_BMPDATA->m_width, M_BMPDATA->m_height );
+  
+  delete[] data;
+  
+  gdk_image_destroy( image );
+  
+  Render();
+  
+#else
+  
+  wxFAIL_MSG( "wxBitmap::RecreateImage not implemented without GdkImlib" );
+  
+#endif
 }
 
 void wxBitmap::Render(void)
@@ -383,10 +462,26 @@ void wxBitmap::Render(void)
   
 #ifdef USE_GDK_IMLIB
 
+  if (!M_BMPDATA->m_image) RecreateImage();
+  
+  if (M_BMPDATA->m_pixmap)
+  { 
+    gdk_imlib_free_pixmap( M_BMPDATA->m_pixmap );
+    M_BMPDATA->m_pixmap = (GdkPixmap*) NULL;
+  }
+  if (M_BMPDATA->m_mask)
+  {
+    delete M_BMPDATA->m_mask;
+    M_BMPDATA->m_mask = (wxMask*) NULL;
+  }
+  
   gdk_imlib_render( M_BMPDATA->m_image, M_BMPDATA->m_image->rgb_width, M_BMPDATA->m_image->rgb_height );
   M_BMPDATA->m_width = M_BMPDATA->m_image->rgb_width;
   M_BMPDATA->m_height = M_BMPDATA->m_image->rgb_height;
   M_BMPDATA->m_pixmap = gdk_imlib_move_image( M_BMPDATA->m_image );
+  
+  wxCHECK_RET( M_BMPDATA->m_pixmap != NULL, "pixmap rendering failed" ) 
+  
   GdkBitmap *mask = gdk_imlib_move_mask( M_BMPDATA->m_image );
   if (mask)
   {
@@ -394,6 +489,10 @@ void wxBitmap::Render(void)
     M_BMPDATA->m_mask->m_bitmap = mask;
   }
   
+#else
+  
+  wxFAIL_MSG( "wxBitmap::Render not implemented without GdkImlib" );
+  
 #endif
 }
 
index ff6f369904c140192885dc278223f51207fd1cfd..a7c77998bc209455c7c40d1b49c212d01d1f2c6b 100644 (file)
@@ -83,6 +83,12 @@ wxDC::~wxDC(void)
 {
 }
 
+bool wxDC::Ok(void) const 
+{ 
+  wxASSERT_MSG( !ok, "invalid display context" );
+  return m_ok; 
+}
+
 void wxDC::DrawArc( long WXUNUSED(x1), long WXUNUSED(y1), long WXUNUSED(x2), long WXUNUSED(y2), 
   double WXUNUSED(xc), double WXUNUSED(yc) )
 {
index ca39cfbb84ef465c43e10fd48a34195b3f3f59bd..70bd684c1647aa3da4b2c577f713a8c52c67991e 100644 (file)
@@ -124,10 +124,12 @@ wxPaintDC::~wxPaintDC(void)
 void wxPaintDC::FloodFill( long WXUNUSED(x1), long WXUNUSED(y1), 
   wxColour *WXUNUSED(col), int WXUNUSED(style) )
 {
+  wxFAIL_MSG( "wxPaintDC::FloodFill not implemented" );
 }
 
 bool wxPaintDC::GetPixel( long WXUNUSED(x1), long WXUNUSED(y1), wxColour *WXUNUSED(col) ) const
 {
+  wxFAIL_MSG( "wxPaintDC::GetPixel not implemented" );
   return FALSE;
 }
 
@@ -135,6 +137,8 @@ void wxPaintDC::DrawLine( long x1, long y1, long x2, long y2 )
 {
   if (!Ok()) return;
   
+  if (!m_isDrawable) ((wxMemoryDC*)this)->m_selected.DestroyImage();
+  
   if (m_pen.GetStyle() != wxTRANSPARENT)
   {
     gdk_draw_line( m_window, m_penGC, 
@@ -146,6 +150,8 @@ void wxPaintDC::CrossHair( long x, long y )
 {
   if (!Ok()) return;
   
+  if (!m_isDrawable) ((wxMemoryDC*)this)->m_selected.DestroyImage();
+  
   if (m_pen.GetStyle() != wxTRANSPARENT)
   {
     int w = 0;
@@ -164,6 +170,8 @@ void wxPaintDC::DrawArc( long x1, long y1, long x2, long y2, double xc, double y
 {
   if (!Ok()) return;
   
+  if (!m_isDrawable) ((wxMemoryDC*)this)->m_selected.DestroyImage();
+  
   long xx1 = XLOG2DEV(x1); 
   long yy1 = YLOG2DEV(y1);
   long xx2 = XLOG2DEV(x2); 
@@ -212,6 +220,8 @@ void wxPaintDC::DrawEllipticArc( long x, long y, long width, long height, double
 {
   if (!Ok()) return;
   
+  if (!m_isDrawable) ((wxMemoryDC*)this)->m_selected.DestroyImage();
+  
   long xx = XLOG2DEV(x);    
   long yy = YLOG2DEV(y);
   long ww = m_signX * XLOG2DEVREL(width); 
@@ -234,6 +244,8 @@ void wxPaintDC::DrawPoint( long x, long y )
 {
   if (!Ok()) return;
   
+  if (!m_isDrawable) ((wxMemoryDC*)this)->m_selected.DestroyImage();
+  
   if (m_pen.GetStyle() != wxTRANSPARENT)
     gdk_draw_point( m_window, m_penGC, XLOG2DEV(x), YLOG2DEV(y) );
 }
@@ -242,6 +254,8 @@ void wxPaintDC::DrawLines( int n, wxPoint points[], long xoffset, long yoffset )
 {
   if (!Ok()) return;
   
+  if (!m_isDrawable) ((wxMemoryDC*)this)->m_selected.DestroyImage();
+  
   if (m_pen.GetStyle() == wxTRANSPARENT) return;
   
   for (int i = 0; i < n-1; i++)
@@ -258,6 +272,8 @@ void wxPaintDC::DrawLines( wxList *points, long xoffset, long yoffset )
 {
   if (!Ok()) return;
   
+  if (!m_isDrawable) ((wxMemoryDC*)this)->m_selected.DestroyImage();
+  
   if (m_pen.GetStyle() == wxTRANSPARENT) return;
   
   wxNode *node = points->First();
@@ -274,10 +290,12 @@ void wxPaintDC::DrawLines( wxList *points, long xoffset, long yoffset )
   }
 }
 
-void wxPaintDC::DrawPolygon( int n, wxPoint points[], 
-  long xoffset, long yoffset, int WXUNUSED(fillStyle) )
- {
-   if (!Ok()) return;
+void wxPaintDC::DrawPolygon( int n, wxPoint points[], long xoffset, long yoffset, int WXUNUSED(fillStyle) )
+{
+  if (!Ok()) return;
+  
+  if (!m_isDrawable) ((wxMemoryDC*)this)->m_selected.DestroyImage();
+  
    if (!n) return;    // Nothing to draw
    GdkPoint *gdkpoints = new GdkPoint[n+1];
    int i;
@@ -299,12 +317,13 @@ void wxPaintDC::DrawPolygon( int n, wxPoint points[],
    delete[] gdkpoints;
 }
 
-void wxPaintDC::DrawPolygon( wxList *lines, long xoffset, 
-                              long yoffset, int WXUNUSED(fillStyle))
- {
+void wxPaintDC::DrawPolygon( wxList *lines, long xoffset, long yoffset, int WXUNUSED(fillStyle))
+{
+  if (!Ok()) return;
+  
+  if (!m_isDrawable) ((wxMemoryDC*)this)->m_selected.DestroyImage();
+  
    int n = lines->Number();
-   if (!Ok()) return;
    GdkPoint *gdkpoints = new GdkPoint[n];
    wxNode *node = lines->First();
    int cnt=0;
@@ -336,6 +355,8 @@ void wxPaintDC::DrawRectangle( long x, long y, long width, long height )
 {
   if (!Ok()) return;
 
+  if (!m_isDrawable) ((wxMemoryDC*)this)->m_selected.DestroyImage();
+  
   long xx = XLOG2DEV(x);
   long yy = YLOG2DEV(y);
   long ww = m_signX * XLOG2DEVREL(width);
@@ -359,6 +380,8 @@ void wxPaintDC::DrawRoundedRectangle( long x, long y, long width, long height, d
 {
   if (!Ok()) return;
   
+  if (!m_isDrawable) ((wxMemoryDC*)this)->m_selected.DestroyImage();
+  
   if (radius < 0.0) radius = - radius * ((width < height) ? width : height);
   
   long xx = XLOG2DEV(x);    
@@ -424,6 +447,8 @@ void wxPaintDC::DrawEllipse( long x, long y, long width, long height )
 {
   if (!Ok()) return;
   
+  if (!m_isDrawable) ((wxMemoryDC*)this)->m_selected.DestroyImage();
+  
   long xx = XLOG2DEV(x);    
   long yy = YLOG2DEV(y);
   long ww = m_signX * XLOG2DEVREL(width); 
@@ -451,6 +476,8 @@ void wxPaintDC::DrawIcon( const wxIcon &icon, long x, long y, bool useMask )
   
   if (!icon.Ok()) return;
   
+  if (!m_isDrawable) ((wxMemoryDC*)this)->m_selected.DestroyImage();
+  
   int xx = XLOG2DEV(x);
   int yy = YLOG2DEV(y);
   
@@ -478,21 +505,22 @@ bool wxPaintDC::Blit( long xdest, long ydest, long width, long height,
 {
   if (!Ok()) return FALSE;
   
+  if (!m_isDrawable) ((wxMemoryDC*)this)->m_selected.DestroyImage();
+  
   // CMB 20/5/98: add blitting of bitmaps
   if (source->IsKindOf(CLASSINFO(wxMemoryDC)))
   {
     wxMemoryDC* srcDC = (wxMemoryDC*)source;
-       GdkBitmap* bmap = srcDC->m_selected.GetBitmap();
+    GdkBitmap* bmap = srcDC->m_selected.GetBitmap();
     if (bmap)
     {
-      gdk_draw_bitmap (
-          m_window,
-          m_textGC,
-          bmap,
-          source->DeviceToLogicalX(xsrc), source->DeviceToLogicalY(ysrc),
-          XLOG2DEV(xdest), YLOG2DEV(ydest),
-          source->DeviceToLogicalXRel(width), source->DeviceToLogicalYRel(height)
-          );
+      gdk_draw_bitmap( m_window, m_textGC, bmap,
+          source->DeviceToLogicalX(xsrc), 
+         source->DeviceToLogicalY(ysrc),
+          XLOG2DEV(xdest), 
+         YLOG2DEV(ydest),
+          source->DeviceToLogicalXRel(width), 
+         source->DeviceToLogicalYRel(height) );
       return TRUE;
     }
   }
@@ -519,6 +547,8 @@ void wxPaintDC::DrawText( const wxString &text, long x, long y, bool WXUNUSED(us
 {
   if (!Ok()) return;
 
+  if (!m_isDrawable) ((wxMemoryDC*)this)->m_selected.DestroyImage();
+  
   GdkFont *font = m_font.GetInternalFont( m_scaleY );
 
   x = XLOG2DEV(x);
@@ -588,7 +618,7 @@ void wxPaintDC::Clear(void)
 {
   if (!Ok()) return;
   
-//  DestroyClippingRegion();
+  if (!m_isDrawable) ((wxMemoryDC*)this)->m_selected.DestroyImage();
   
   if (m_isDrawable)
   {
index 5a6e982f9ef7e46a03bd7c81d216f4fd79efbb6a..4b19f89c29e97eea19faf4df474dc381ecf54b77 100644 (file)
 
 #include "wx/dcmemory.h"
 
+#ifdef USE_GDK_IMLIB
+#include "../gdk_imlib/gdk_imlib.h"
+#endif
+
 //-----------------------------------------------------------------------------
 // wxMemoryDC
 //-----------------------------------------------------------------------------
@@ -23,13 +27,23 @@ IMPLEMENT_DYNAMIC_CLASS(wxMemoryDC,wxPaintDC)
 wxMemoryDC::wxMemoryDC(void)
 {
   m_ok = FALSE;
+  
+#ifdef USE_GDK_IMLIB
+  m_cmap = gdk_imlib_get_colormap();
+#else
   m_cmap = gdk_colormap_get_system();
+#endif
 }
 
 wxMemoryDC::wxMemoryDC( wxDC *WXUNUSED(dc) )
 {
   m_ok = FALSE;
+  
+#ifdef USE_GDK_IMLIB
+  m_cmap = gdk_imlib_get_colormap();
+#else
   m_cmap = gdk_colormap_get_system();
+#endif
 }
 
 wxMemoryDC::~wxMemoryDC(void)
index fad9d5bb8efd99dde3efdbb73c5a1a69d5ab5130..9465c44a378a383f53706f05cd390a58e4f4d2a6 100644 (file)
@@ -150,7 +150,7 @@ bool wxMenuBar::Enabled( int id ) const
 }
 
 //-----------------------------------------------------------------------------
-// wxMenu
+// "activate"
 //-----------------------------------------------------------------------------
 
 static void gtk_menu_clicked_callback( GtkWidget *widget, wxMenu *menu )
@@ -161,7 +161,35 @@ static void gtk_menu_clicked_callback( GtkWidget *widget, wxMenu *menu )
 
   if (!menu->IsEnabled(id)) return;
 
-  wxCommandEvent event( wxEVENT_TYPE_MENU_COMMAND, id );
+  wxCommandEvent event( wxEVT_COMMAND_MENU_SELECTED, id );
+  event.SetEventObject( menu );
+  event.SetInt(id );
+  
+  if (menu->m_callback)
+  {
+     (void) (*(menu->m_callback)) (*menu, event);
+     return;
+  }
+
+  if (menu->GetEventHandler()->ProcessEvent(event)) return;
+
+  wxWindow *win = menu->GetInvokingWindow();
+  if (win) win->GetEventHandler()->ProcessEvent( event );
+}
+
+//-----------------------------------------------------------------------------
+// "select"
+//-----------------------------------------------------------------------------
+
+static void gtk_menu_hilight_callback( GtkWidget *widget, wxMenu *menu )
+{
+  int id = menu->FindMenuIdByMenuItem(widget);
+
+  wxASSERT( id != -1 ); // should find it!
+
+  if (!menu->IsEnabled(id)) return;
+
+  wxCommandEvent event( wxEVT_MENU_HIGHLIGHT, id );
   event.SetEventObject( menu );
   event.SetInt(id );
   
@@ -177,6 +205,10 @@ static void gtk_menu_clicked_callback( GtkWidget *widget, wxMenu *menu )
   if (win) win->GetEventHandler()->ProcessEvent( event );
 }
 
+//-----------------------------------------------------------------------------
+// wxMenu
+//-----------------------------------------------------------------------------
+
 IMPLEMENT_DYNAMIC_CLASS(wxMenuItem,wxObject)
 
 wxMenuItem::wxMenuItem()
@@ -283,6 +315,10 @@ void wxMenu::Append( int id, const wxString &item, const wxString &helpStr, bool
                       GTK_SIGNAL_FUNC(gtk_menu_clicked_callback),
                       (gpointer*)this );
 
+  gtk_signal_connect( GTK_OBJECT(menuItem), "select",
+                      GTK_SIGNAL_FUNC(gtk_menu_hilight_callback),
+                      (gpointer*)this );
+
   gtk_menu_append( GTK_MENU(m_menu), menuItem );
   gtk_widget_show( menuItem );
   m_items.Append( mitem );
index b06f111e55edc921f33db0902a253c02aab38b6b..e4adea4dd18fd9f0142adc82326db8fae2af0b86 100644 (file)
 #include "gdk/gdkprivate.h"
 
 #ifdef USE_GDK_IMLIB
+
 #include "../gdk_imlib/gdk_imlib.h"
+#include "gdk/gdkx.h"        // GDK_DISPLAY
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+
 #endif
 
 //-----------------------------------------------------------------------------
@@ -223,7 +228,8 @@ bool wxBitmap::operator != ( const wxBitmap& bmp )
   
 bool wxBitmap::Ok(void) const
 {
-  return m_refData != NULL;
+  wxASSERT_MSG( m_refData != NULL, "invalid bitmap" );
+  return (m_refData != NULL);
 }
   
 int wxBitmap::GetHeight(void) const
@@ -247,18 +253,27 @@ int wxBitmap::GetDepth(void) const
 void wxBitmap::SetHeight( int height )
 {
   if (!Ok()) return;
+  
+  wxFAIL_MSG( "wxBitmap::SetHeight not implemented" );
+  
   M_BMPDATA->m_height = height;
 }
 
 void wxBitmap::SetWidth( int width )
 {
   if (!Ok()) return;
+  
+  wxFAIL_MSG( "wxBitmap::SetWidth not implemented" );
+  
   M_BMPDATA->m_width = width;
 }
 
 void wxBitmap::SetDepth( int depth )
 {
   if (!Ok()) return;
+  
+  wxFAIL_MSG( "wxBitmap::SetDepth not implemented" );
+  
   M_BMPDATA->m_bpp = depth;
 }
 
@@ -274,6 +289,7 @@ void wxBitmap::SetMask( wxMask *mask )
   if (!Ok()) return;
   
   if (M_BMPDATA->m_mask) delete M_BMPDATA->m_mask;
+  
   M_BMPDATA->m_mask = mask;
 }
 
@@ -298,6 +314,10 @@ void wxBitmap::Resize( int height, int width )
   
   Render();
   
+#else
+  
+  wxFAIL_MSG( "wxBitmap::Resize not implemented without GdkImlib" );
+  
 #endif
 }
 
@@ -312,6 +332,10 @@ bool wxBitmap::SaveFile( const wxString &name, int WXUNUSED(type),
   
   return gdk_imlib_save_image( M_BMPDATA->m_image, WXSTRINGCAST name, (GdkImlibSaveInfo *) NULL );
 
+#else
+  
+  wxFAIL_MSG( "wxBitmap::SaveFile not implemented without GdkImlib" );
+  
 #endif
 
   return FALSE;
@@ -338,6 +362,11 @@ bool wxBitmap::LoadFile( const wxString &name, int WXUNUSED(type) )
   M_BMPDATA->m_bpp = 24; // ?
   
   return TRUE;
+  
+#else
+  
+  wxFAIL_MSG( "wxBitmap::LoadFile not implemented without GdkImlib" );
+  
 #endif
 
   return FALSE;
@@ -352,6 +381,9 @@ wxPalette *wxBitmap::GetPalette(void) const
 GdkPixmap *wxBitmap::GetPixmap(void) const
 {
   if (!Ok()) return (GdkPixmap *) NULL;
+  
+//  if (!M_BMPDATA->m_image) RecreateImage();
+  
   return M_BMPDATA->m_pixmap;
 }
   
@@ -375,6 +407,53 @@ void wxBitmap::DestroyImage(void)
 
 void wxBitmap::RecreateImage(void)
 {
+  if (!Ok()) return;
+  
+#ifdef USE_GDK_IMLIB
+
+  DestroyImage();
+  
+  wxCHECK_RET( M_BMPDATA->m_pixmap != NULL, "invalid bitmap" );
+  
+  long size = (long)(M_BMPDATA->m_width)*(long)(M_BMPDATA->m_height)*(long)3;
+  unsigned char *data = new unsigned char[size];
+  for (long i = 0; i < size; i++) data[i] = 100;
+  
+  GdkImage *image = gdk_image_get( M_BMPDATA->m_pixmap, 0, 0, M_BMPDATA->m_width, M_BMPDATA->m_height );
+  
+  long pos = 0;
+  for (int j = 0; j < M_BMPDATA->m_height; j++)
+  {
+    for (int i = 0; i < M_BMPDATA->m_width; i++)
+    {
+      XColor xcol;
+      xcol.pixel = gdk_image_get_pixel( image, i, j );
+      Colormap cm = ((GdkColormapPrivate*)gdk_imlib_get_colormap())->xcolormap;
+      XQueryColor( gdk_display, cm, &xcol );
+      
+      data[pos] = xcol.red;
+      data[pos+1] = xcol.green;
+      data[pos+2] = xcol.blue;
+      pos += 3;
+    }
+  }
+  
+  wxCHECK_RET( M_BMPDATA->m_pixmap != NULL, "invalid bitmap" );
+  
+  M_BMPDATA->m_image = gdk_imlib_create_image_from_data( 
+     data, (unsigned char*)NULL, M_BMPDATA->m_width, M_BMPDATA->m_height );
+  
+  delete[] data;
+  
+  gdk_image_destroy( image );
+  
+  Render();
+  
+#else
+  
+  wxFAIL_MSG( "wxBitmap::RecreateImage not implemented without GdkImlib" );
+  
+#endif
 }
 
 void wxBitmap::Render(void)
@@ -383,10 +462,26 @@ void wxBitmap::Render(void)
   
 #ifdef USE_GDK_IMLIB
 
+  if (!M_BMPDATA->m_image) RecreateImage();
+  
+  if (M_BMPDATA->m_pixmap)
+  { 
+    gdk_imlib_free_pixmap( M_BMPDATA->m_pixmap );
+    M_BMPDATA->m_pixmap = (GdkPixmap*) NULL;
+  }
+  if (M_BMPDATA->m_mask)
+  {
+    delete M_BMPDATA->m_mask;
+    M_BMPDATA->m_mask = (wxMask*) NULL;
+  }
+  
   gdk_imlib_render( M_BMPDATA->m_image, M_BMPDATA->m_image->rgb_width, M_BMPDATA->m_image->rgb_height );
   M_BMPDATA->m_width = M_BMPDATA->m_image->rgb_width;
   M_BMPDATA->m_height = M_BMPDATA->m_image->rgb_height;
   M_BMPDATA->m_pixmap = gdk_imlib_move_image( M_BMPDATA->m_image );
+  
+  wxCHECK_RET( M_BMPDATA->m_pixmap != NULL, "pixmap rendering failed" ) 
+  
   GdkBitmap *mask = gdk_imlib_move_mask( M_BMPDATA->m_image );
   if (mask)
   {
@@ -394,6 +489,10 @@ void wxBitmap::Render(void)
     M_BMPDATA->m_mask->m_bitmap = mask;
   }
   
+#else
+  
+  wxFAIL_MSG( "wxBitmap::Render not implemented without GdkImlib" );
+  
 #endif
 }
 
index ff6f369904c140192885dc278223f51207fd1cfd..a7c77998bc209455c7c40d1b49c212d01d1f2c6b 100644 (file)
@@ -83,6 +83,12 @@ wxDC::~wxDC(void)
 {
 }
 
+bool wxDC::Ok(void) const 
+{ 
+  wxASSERT_MSG( !ok, "invalid display context" );
+  return m_ok; 
+}
+
 void wxDC::DrawArc( long WXUNUSED(x1), long WXUNUSED(y1), long WXUNUSED(x2), long WXUNUSED(y2), 
   double WXUNUSED(xc), double WXUNUSED(yc) )
 {
index ca39cfbb84ef465c43e10fd48a34195b3f3f59bd..70bd684c1647aa3da4b2c577f713a8c52c67991e 100644 (file)
@@ -124,10 +124,12 @@ wxPaintDC::~wxPaintDC(void)
 void wxPaintDC::FloodFill( long WXUNUSED(x1), long WXUNUSED(y1), 
   wxColour *WXUNUSED(col), int WXUNUSED(style) )
 {
+  wxFAIL_MSG( "wxPaintDC::FloodFill not implemented" );
 }
 
 bool wxPaintDC::GetPixel( long WXUNUSED(x1), long WXUNUSED(y1), wxColour *WXUNUSED(col) ) const
 {
+  wxFAIL_MSG( "wxPaintDC::GetPixel not implemented" );
   return FALSE;
 }
 
@@ -135,6 +137,8 @@ void wxPaintDC::DrawLine( long x1, long y1, long x2, long y2 )
 {
   if (!Ok()) return;
   
+  if (!m_isDrawable) ((wxMemoryDC*)this)->m_selected.DestroyImage();
+  
   if (m_pen.GetStyle() != wxTRANSPARENT)
   {
     gdk_draw_line( m_window, m_penGC, 
@@ -146,6 +150,8 @@ void wxPaintDC::CrossHair( long x, long y )
 {
   if (!Ok()) return;
   
+  if (!m_isDrawable) ((wxMemoryDC*)this)->m_selected.DestroyImage();
+  
   if (m_pen.GetStyle() != wxTRANSPARENT)
   {
     int w = 0;
@@ -164,6 +170,8 @@ void wxPaintDC::DrawArc( long x1, long y1, long x2, long y2, double xc, double y
 {
   if (!Ok()) return;
   
+  if (!m_isDrawable) ((wxMemoryDC*)this)->m_selected.DestroyImage();
+  
   long xx1 = XLOG2DEV(x1); 
   long yy1 = YLOG2DEV(y1);
   long xx2 = XLOG2DEV(x2); 
@@ -212,6 +220,8 @@ void wxPaintDC::DrawEllipticArc( long x, long y, long width, long height, double
 {
   if (!Ok()) return;
   
+  if (!m_isDrawable) ((wxMemoryDC*)this)->m_selected.DestroyImage();
+  
   long xx = XLOG2DEV(x);    
   long yy = YLOG2DEV(y);
   long ww = m_signX * XLOG2DEVREL(width); 
@@ -234,6 +244,8 @@ void wxPaintDC::DrawPoint( long x, long y )
 {
   if (!Ok()) return;
   
+  if (!m_isDrawable) ((wxMemoryDC*)this)->m_selected.DestroyImage();
+  
   if (m_pen.GetStyle() != wxTRANSPARENT)
     gdk_draw_point( m_window, m_penGC, XLOG2DEV(x), YLOG2DEV(y) );
 }
@@ -242,6 +254,8 @@ void wxPaintDC::DrawLines( int n, wxPoint points[], long xoffset, long yoffset )
 {
   if (!Ok()) return;
   
+  if (!m_isDrawable) ((wxMemoryDC*)this)->m_selected.DestroyImage();
+  
   if (m_pen.GetStyle() == wxTRANSPARENT) return;
   
   for (int i = 0; i < n-1; i++)
@@ -258,6 +272,8 @@ void wxPaintDC::DrawLines( wxList *points, long xoffset, long yoffset )
 {
   if (!Ok()) return;
   
+  if (!m_isDrawable) ((wxMemoryDC*)this)->m_selected.DestroyImage();
+  
   if (m_pen.GetStyle() == wxTRANSPARENT) return;
   
   wxNode *node = points->First();
@@ -274,10 +290,12 @@ void wxPaintDC::DrawLines( wxList *points, long xoffset, long yoffset )
   }
 }
 
-void wxPaintDC::DrawPolygon( int n, wxPoint points[], 
-  long xoffset, long yoffset, int WXUNUSED(fillStyle) )
- {
-   if (!Ok()) return;
+void wxPaintDC::DrawPolygon( int n, wxPoint points[], long xoffset, long yoffset, int WXUNUSED(fillStyle) )
+{
+  if (!Ok()) return;
+  
+  if (!m_isDrawable) ((wxMemoryDC*)this)->m_selected.DestroyImage();
+  
    if (!n) return;    // Nothing to draw
    GdkPoint *gdkpoints = new GdkPoint[n+1];
    int i;
@@ -299,12 +317,13 @@ void wxPaintDC::DrawPolygon( int n, wxPoint points[],
    delete[] gdkpoints;
 }
 
-void wxPaintDC::DrawPolygon( wxList *lines, long xoffset, 
-                              long yoffset, int WXUNUSED(fillStyle))
- {
+void wxPaintDC::DrawPolygon( wxList *lines, long xoffset, long yoffset, int WXUNUSED(fillStyle))
+{
+  if (!Ok()) return;
+  
+  if (!m_isDrawable) ((wxMemoryDC*)this)->m_selected.DestroyImage();
+  
    int n = lines->Number();
-   if (!Ok()) return;
    GdkPoint *gdkpoints = new GdkPoint[n];
    wxNode *node = lines->First();
    int cnt=0;
@@ -336,6 +355,8 @@ void wxPaintDC::DrawRectangle( long x, long y, long width, long height )
 {
   if (!Ok()) return;
 
+  if (!m_isDrawable) ((wxMemoryDC*)this)->m_selected.DestroyImage();
+  
   long xx = XLOG2DEV(x);
   long yy = YLOG2DEV(y);
   long ww = m_signX * XLOG2DEVREL(width);
@@ -359,6 +380,8 @@ void wxPaintDC::DrawRoundedRectangle( long x, long y, long width, long height, d
 {
   if (!Ok()) return;
   
+  if (!m_isDrawable) ((wxMemoryDC*)this)->m_selected.DestroyImage();
+  
   if (radius < 0.0) radius = - radius * ((width < height) ? width : height);
   
   long xx = XLOG2DEV(x);    
@@ -424,6 +447,8 @@ void wxPaintDC::DrawEllipse( long x, long y, long width, long height )
 {
   if (!Ok()) return;
   
+  if (!m_isDrawable) ((wxMemoryDC*)this)->m_selected.DestroyImage();
+  
   long xx = XLOG2DEV(x);    
   long yy = YLOG2DEV(y);
   long ww = m_signX * XLOG2DEVREL(width); 
@@ -451,6 +476,8 @@ void wxPaintDC::DrawIcon( const wxIcon &icon, long x, long y, bool useMask )
   
   if (!icon.Ok()) return;
   
+  if (!m_isDrawable) ((wxMemoryDC*)this)->m_selected.DestroyImage();
+  
   int xx = XLOG2DEV(x);
   int yy = YLOG2DEV(y);
   
@@ -478,21 +505,22 @@ bool wxPaintDC::Blit( long xdest, long ydest, long width, long height,
 {
   if (!Ok()) return FALSE;
   
+  if (!m_isDrawable) ((wxMemoryDC*)this)->m_selected.DestroyImage();
+  
   // CMB 20/5/98: add blitting of bitmaps
   if (source->IsKindOf(CLASSINFO(wxMemoryDC)))
   {
     wxMemoryDC* srcDC = (wxMemoryDC*)source;
-       GdkBitmap* bmap = srcDC->m_selected.GetBitmap();
+    GdkBitmap* bmap = srcDC->m_selected.GetBitmap();
     if (bmap)
     {
-      gdk_draw_bitmap (
-          m_window,
-          m_textGC,
-          bmap,
-          source->DeviceToLogicalX(xsrc), source->DeviceToLogicalY(ysrc),
-          XLOG2DEV(xdest), YLOG2DEV(ydest),
-          source->DeviceToLogicalXRel(width), source->DeviceToLogicalYRel(height)
-          );
+      gdk_draw_bitmap( m_window, m_textGC, bmap,
+          source->DeviceToLogicalX(xsrc), 
+         source->DeviceToLogicalY(ysrc),
+          XLOG2DEV(xdest), 
+         YLOG2DEV(ydest),
+          source->DeviceToLogicalXRel(width), 
+         source->DeviceToLogicalYRel(height) );
       return TRUE;
     }
   }
@@ -519,6 +547,8 @@ void wxPaintDC::DrawText( const wxString &text, long x, long y, bool WXUNUSED(us
 {
   if (!Ok()) return;
 
+  if (!m_isDrawable) ((wxMemoryDC*)this)->m_selected.DestroyImage();
+  
   GdkFont *font = m_font.GetInternalFont( m_scaleY );
 
   x = XLOG2DEV(x);
@@ -588,7 +618,7 @@ void wxPaintDC::Clear(void)
 {
   if (!Ok()) return;
   
-//  DestroyClippingRegion();
+  if (!m_isDrawable) ((wxMemoryDC*)this)->m_selected.DestroyImage();
   
   if (m_isDrawable)
   {
index 5a6e982f9ef7e46a03bd7c81d216f4fd79efbb6a..4b19f89c29e97eea19faf4df474dc381ecf54b77 100644 (file)
 
 #include "wx/dcmemory.h"
 
+#ifdef USE_GDK_IMLIB
+#include "../gdk_imlib/gdk_imlib.h"
+#endif
+
 //-----------------------------------------------------------------------------
 // wxMemoryDC
 //-----------------------------------------------------------------------------
@@ -23,13 +27,23 @@ IMPLEMENT_DYNAMIC_CLASS(wxMemoryDC,wxPaintDC)
 wxMemoryDC::wxMemoryDC(void)
 {
   m_ok = FALSE;
+  
+#ifdef USE_GDK_IMLIB
+  m_cmap = gdk_imlib_get_colormap();
+#else
   m_cmap = gdk_colormap_get_system();
+#endif
 }
 
 wxMemoryDC::wxMemoryDC( wxDC *WXUNUSED(dc) )
 {
   m_ok = FALSE;
+  
+#ifdef USE_GDK_IMLIB
+  m_cmap = gdk_imlib_get_colormap();
+#else
   m_cmap = gdk_colormap_get_system();
+#endif
 }
 
 wxMemoryDC::~wxMemoryDC(void)
index fad9d5bb8efd99dde3efdbb73c5a1a69d5ab5130..9465c44a378a383f53706f05cd390a58e4f4d2a6 100644 (file)
@@ -150,7 +150,7 @@ bool wxMenuBar::Enabled( int id ) const
 }
 
 //-----------------------------------------------------------------------------
-// wxMenu
+// "activate"
 //-----------------------------------------------------------------------------
 
 static void gtk_menu_clicked_callback( GtkWidget *widget, wxMenu *menu )
@@ -161,7 +161,35 @@ static void gtk_menu_clicked_callback( GtkWidget *widget, wxMenu *menu )
 
   if (!menu->IsEnabled(id)) return;
 
-  wxCommandEvent event( wxEVENT_TYPE_MENU_COMMAND, id );
+  wxCommandEvent event( wxEVT_COMMAND_MENU_SELECTED, id );
+  event.SetEventObject( menu );
+  event.SetInt(id );
+  
+  if (menu->m_callback)
+  {
+     (void) (*(menu->m_callback)) (*menu, event);
+     return;
+  }
+
+  if (menu->GetEventHandler()->ProcessEvent(event)) return;
+
+  wxWindow *win = menu->GetInvokingWindow();
+  if (win) win->GetEventHandler()->ProcessEvent( event );
+}
+
+//-----------------------------------------------------------------------------
+// "select"
+//-----------------------------------------------------------------------------
+
+static void gtk_menu_hilight_callback( GtkWidget *widget, wxMenu *menu )
+{
+  int id = menu->FindMenuIdByMenuItem(widget);
+
+  wxASSERT( id != -1 ); // should find it!
+
+  if (!menu->IsEnabled(id)) return;
+
+  wxCommandEvent event( wxEVT_MENU_HIGHLIGHT, id );
   event.SetEventObject( menu );
   event.SetInt(id );
   
@@ -177,6 +205,10 @@ static void gtk_menu_clicked_callback( GtkWidget *widget, wxMenu *menu )
   if (win) win->GetEventHandler()->ProcessEvent( event );
 }
 
+//-----------------------------------------------------------------------------
+// wxMenu
+//-----------------------------------------------------------------------------
+
 IMPLEMENT_DYNAMIC_CLASS(wxMenuItem,wxObject)
 
 wxMenuItem::wxMenuItem()
@@ -283,6 +315,10 @@ void wxMenu::Append( int id, const wxString &item, const wxString &helpStr, bool
                       GTK_SIGNAL_FUNC(gtk_menu_clicked_callback),
                       (gpointer*)this );
 
+  gtk_signal_connect( GTK_OBJECT(menuItem), "select",
+                      GTK_SIGNAL_FUNC(gtk_menu_hilight_callback),
+                      (gpointer*)this );
+
   gtk_menu_append( GTK_MENU(m_menu), menuItem );
   gtk_widget_show( menuItem );
   m_items.Append( mitem );