Index: gui/gtk_glue_agg.cpp
===================================================================
RCS file: /sources/gnash/gnash/gui/gtk_glue_agg.cpp,v
retrieving revision 1.36
diff -p -u -r1.36 gtk_glue_agg.cpp
--- gui/gtk_glue_agg.cpp	17 Jun 2008 17:32:04 -0000	1.36
+++ gui/gtk_glue_agg.cpp	20 Jun 2008 21:58:44 -0000
@@ -55,183 +55,29 @@
 #include "render_handler_agg.h"
 #include "gtk_glue_agg.h"
 
-#ifdef ENABLE_MIT_SHM
-#include <X11/Xlib.h>
-#include <sys/ipc.h>
-#include <sys/shm.h>
-#include <X11/extensions/XShm.h>
-#include <gdk/gdkprivate.h>
-#endif
-
-
 namespace gnash
 {
 
 GtkAggGlue::GtkAggGlue() :
 	_offscreenbuf(NULL),
-	_offscreenbuf_size(0),
-	_agg_renderer(NULL),
-	_width(0),
-	_height(0),
-	_bpp(0),
-	_have_shm(false)
-#ifdef ENABLE_MIT_SHM
-  ,_shm_image(NULL)
-  ,_shm_info(NULL)
-#endif	
+	_agg_renderer(NULL)
 {
 }
 
 GtkAggGlue::~GtkAggGlue()
 {
   if (_offscreenbuf) {
-    free(_offscreenbuf);
-    _offscreenbuf=NULL;
+    gdk_image_destroy(_offscreenbuf);
   }
   
-  destroy_shm_image();
 }
 
 bool
 GtkAggGlue::init(int /*argc*/, char **/*argv*/[])
 {
-    gdk_rgb_init();
-    
-#ifdef ENABLE_MIT_SHM
-    _have_shm = check_mit_shm(gdk_display);
-#else
-    _have_shm = false;
-#endif
-    
-    if (!detect_pixelformat()) {
-      printf("FATAL: Could not detect the pixel format used by your X server.\n");
-      printf("Please report this problem to the Gnash developer team.\n");
-      return false;
-    }
-    
-    log_debug("Your X server expects %s pixmap data for standard mode.", _pixelformat);
-    
     return true;
 }
 
-bool 
-#ifdef ENABLE_MIT_SHM
-GtkAggGlue::check_mit_shm(Display *display) 
-#else
-GtkAggGlue::check_mit_shm(void *display) 
-#endif
-{
-#ifdef ENABLE_MIT_SHM
-  int major, minor, dummy;
-  Bool pixmaps;
-  
-  log_debug("Checking support for MIT-SHM...");
-  
-  if (!XQueryExtension(display, "MIT-SHM", &dummy, &dummy, &dummy)) 
-  {
-    log_debug("WARNING: No MIT-SHM extension available, using standard XLib "
-      "calls (slower)");
-    return false;
-  }
-  
-  if (XShmQueryVersion(display, &major, &minor, &pixmaps )!=True)
-	{
-    log_debug("WARNING: MIT-SHM not ready (network link?), using standard XLib "
-      "calls (slower)");
-    return false;
-	}
-	
-	log_debug("NOTICE: MIT-SHM available (version %d.%d)!", major, minor);
-	
-	return true;
-	
-	
-#else
-	return false; // !ifdef ENABLE_MIT_SHM
-#endif
-  
-}
-
-void 
-GtkAggGlue::create_shm_image(unsigned int width, unsigned int height)
-{
-
-  // destroy any already existing structures
-  destroy_shm_image();
-
-#ifdef ENABLE_MIT_SHM
-  GdkVisual* visual = gdk_drawable_get_visual(_drawing_area->window);
-  Visual* xvisual = GDK_VISUAL_XVISUAL(visual); 
-  
-  // prepare segment info (populated by XShmCreateImage)
-  _shm_info = (XShmSegmentInfo*) malloc(sizeof(XShmSegmentInfo));  
-  assert(_shm_info != NULL);
-  
-  // create shared memory XImage
-  _shm_image = XShmCreateImage(gdk_display, xvisual, visual->depth, 
-    ZPixmap, NULL, _shm_info, width, height);
-    
-  if (!_shm_image) {
-    log_debug("Failed creating the shared memory XImage!");
-    destroy_shm_image();
-    return;
-  }
-  
-  // create shared memory segment
-  _shm_info->shmid = shmget(IPC_PRIVATE, 
-    _shm_image->bytes_per_line * _shm_image->height, IPC_CREAT|0777);
-    
-  if (_shm_info->shmid == -1) {
-    log_debug("Failed requesting shared memory segment (%s). Perhaps the "
-      "required memory size is bigger than the limit set by the kernel.",
-      strerror(errno));
-    destroy_shm_image();
-    return;
-  }
-  
-  // attach the shared memory segment to our process
-  _shm_info->shmaddr = _shm_image->data = (char*) shmat(_shm_info->shmid, 0, 0);
-  
-  if (_shm_info->shmaddr == (char*) -1) {
-    log_debug("Failed attaching to shared memory segment: %s", strerror(errno));
-    destroy_shm_image();
-    return;
-  }
-  
-  // Give the server full access to our memory segment. We just follow
-  // the documentation which recommends this, but we could also give him
-  // just read-only access since we don't need XShmGetImage...
-  _shm_info->readOnly = False;
-  
-  // Finally, tell the server to attach to our shared memory segment  
-  if (!XShmAttach(gdk_display, _shm_info)) {
-    log_debug("Server failed attaching to the shared memory segment");
-    destroy_shm_image();
-    return;
-  }
-  
-  //log_debug("create_shm_image() OK"); // <-- remove this
-#endif // ENABLE_MIT_SHM
-   
-}
-
-void 
-GtkAggGlue::destroy_shm_image()
-{
-#ifdef ENABLE_MIT_SHM
-  if (_shm_image) {  
-    XDestroyImage(_shm_image);
-    _shm_image=NULL;
-  }
-  
-  if (_shm_info) {
-    free(_shm_info);
-    _shm_info=NULL;
-  }
-  
-#endif
-}
-
 void
 GtkAggGlue::prepDrawingArea(GtkWidget *drawing_area)
 {
@@ -242,125 +88,34 @@ GtkAggGlue::prepDrawingArea(GtkWidget *d
     gtk_widget_set_double_buffered(_drawing_area, FALSE);
 }
 
-bool 
-GtkAggGlue::detect_pixelformat() 
+render_handler*
+GtkAggGlue::createRenderHandler()
 {
+  assert(_drawing_area);
+  assert(_drawing_area->window);
 
-  // By definition, GTK/GDK *always* expects RGB24 data for 
-  // gdk_draw_rgb_image(). However, we want to support the OLPC which uses a 
-  // hacked GTK that works with RGB565 data.
-  
-#ifdef PIXELFORMAT_RGB24   // normal case 
-  
-  _bpp = 24;
-  strcpy(_pixelformat, "RGB24");
-  return true;
-
-#else
-
-#ifdef PIXELFORMAT_RGB565  // OLPC
-
-#warning A pixel format of RGB565; you must have a (hacked) GTK which supports \
-         this format (e.g., GTK on the OLPC).
-                  
-  _bpp = 16;
-  strcpy(_pixelformat, "RGB565");
-  return true;
-  
-#else
+#if 0
+  GdkVisual* wvisual = gdk_drawable_get_visual(_drawing_area->window);
 
-#warning GTK GUI requires --with-pixelformat=RGB24 for AGG renderer
- 
-  printf("Missing a supported pixel format for GTK GUI. You probably want to "
-    "configure --with-pixelformat=RGB24\n");
-  return false;   
-
-#endif  //ifdef PIXELFORMAT_RGB565   
- 
-#endif  //ifdef PIXELFORMAT_RGB24
-  
-  
-}
+  GdkImage* tmpimage = gdk_image_new (GDK_IMAGE_FASTEST, wvisual, 1,
+                                      1);
 
-render_handler*
-GtkAggGlue::create_shm_handler()
-{
-#ifdef ENABLE_MIT_SHM
-  GdkVisual *visual = gdk_drawable_get_visual(_drawing_area->window);
-  
-  // Create a dummy SHM image to detect it's pixel format (we can't use the 
-  // info from "visual"). 
-  // Is there a better way??
-  
-  create_shm_image(256,256);
-  
-  if (!_shm_image) return NULL;
-  
-  unsigned int red_shift, red_prec;
-  unsigned int green_shift, green_prec;
-  unsigned int blue_shift, blue_prec;
-
-  decode_mask(_shm_image->red_mask,   &red_shift,   &red_prec);
-  decode_mask(_shm_image->green_mask, &green_shift, &green_prec);
-  decode_mask(_shm_image->blue_mask,  &blue_shift,  &blue_prec);
-  
-  
-  log_debug("X server pixel format is (R%d:%d, G%d:%d, B%d:%d, %d bpp)",
-    red_shift, red_prec,
-    green_shift, green_prec,
-    blue_shift, blue_prec,
-    _shm_image->bits_per_pixel);
-  
-  
-  const char *pixelformat = agg_detect_pixel_format(
-    red_shift, red_prec,
-    green_shift, green_prec,
-    blue_shift, blue_prec,
-    _shm_image->bits_per_pixel);
+  GdkVisual* visual = tmpimage->visual;
 
-  destroy_shm_image();
 
-  if (!pixelformat) {
-    log_debug("Pixel format of X server not recognized!");
-    
-    // disable use of shared memory pixmaps
-    _have_shm = false;
-    
-    return NULL; 
-  }
-
-  log_debug("X server is using %s pixel format", pixelformat);
-  
-  render_handler* res = create_render_handler_agg(pixelformat);
-  
-  if (!res) {
-    log_debug("Failed creating a renderer instance for this pixel format. "
-      "Most probably Gnash has not compiled in (configured) support "
-      "for this pixel format - using standard pixmaps instead");
-      
-    // disable use of shared memory pixmaps
-    _have_shm = false;
-  }      
-  
-  
-  return res;
-    
-#else
-  return NULL;
-#endif
-}
+  const char *pixelformat = agg_detect_pixel_format(
+    visual->red_shift, visual->red_prec,
+    visual->green_shift, visual->green_prec,
+    visual->blue_shift, visual->blue_prec,
+    tmpimage->depth);
 
-render_handler*
-GtkAggGlue::createRenderHandler()
-{
+  gdk_image_destroy(tmpimage);
 
-  // try with MIT-SHM
-  if (_have_shm) {
-    _agg_renderer = create_shm_handler();
-    if (_agg_renderer) return _agg_renderer;
-  }
+  assert(pixelformat);
 
-  _agg_renderer = create_render_handler_agg(_pixelformat);
+  std::cout << "PIXELFORMAT: " << pixelformat << " but " << tmpimage->bpp << " bytes per pixel" <<  std::endl;
+#endif
+  _agg_renderer = create_render_handler_agg(/*pixelformat*/ "BGRA32");
   return _agg_renderer;
 }
 
@@ -370,184 +125,62 @@ GtkAggGlue::setRenderHandlerSize(int wid
 	assert(width>0);
 	assert(height>0);
 	assert(_agg_renderer!=NULL);
+        assert(_drawing_area);
+        assert(_drawing_area->window);
 
-	#define CHUNK_SIZE (100*100*(_bpp/8))
-	
-	if (width == _width && height == _height)
-	   return;
-	   
-  _width = width;
-	_height = height;
-	   
+	if (_offscreenbuf && _offscreenbuf->width == width &&
+            _offscreenbuf->height == height) {
+	   return; 
+	}
 	   
-	// try shared image first
-	if (_have_shm)
-	  create_shm_image(width, height);
-	  
-#ifdef ENABLE_MIT_SHM
-	if (_shm_image) {
-	
-	  // ==> use shared memory image (faster)
-	  
-	  log_debug("GTK-AGG: Using shared memory image");
-    
-    if (_offscreenbuf) {  
-      free(_offscreenbuf);
-      _offscreenbuf = NULL;
-    }
-	  
-  	static_cast<render_handler_agg_base *>(_agg_renderer)->init_buffer(
-  	  (unsigned char*) _shm_info->shmaddr,
-  		_shm_image->bytes_per_line * _shm_image->height,
-  		_width,
-  		_height,
-  		_shm_image->bytes_per_line
-  	);
-	
-  } else {
-#endif  	
-  
-    // ==> use standard pixmaps (slower, but should work in any case)
+	if (_offscreenbuf) {
+		gdk_image_destroy(_offscreenbuf);
+	}
 
-  	int new_bufsize = width*height*((_bpp+7)/8);
-  	
-  	// TODO: At the moment we only increase the buffer and never decrease it. Should be
-  	// changed sometime.
-  	if (new_bufsize > _offscreenbuf_size) {
-  		new_bufsize = static_cast<int>(new_bufsize / CHUNK_SIZE + 1) * CHUNK_SIZE;
-  		// TODO: C++ conform alternative to realloc?
-  		_offscreenbuf	= static_cast<unsigned char *>( realloc(_offscreenbuf, new_bufsize) );
-  
-  		if (!_offscreenbuf) {
-  		  log_debug("Could not allocate %i bytes for offscreen buffer: %s\n",
-  				new_bufsize, strerror(errno)
-  			);
-  			return;
-  		}
-  
-  		log_debug("GTK-AGG: %i bytes offscreen buffer allocated\n", new_bufsize);
-  
-  		_offscreenbuf_size = new_bufsize;
-  		memset(_offscreenbuf, 0, new_bufsize);
-  	}
-  	
-  	// Only the AGG renderer has the function init_buffer, which is *not* part of
-  	// the renderer api. It allows us to change the renderers movie size (and buffer
-  	// address) during run-time.
+        GdkVisual* visual = gdk_drawable_get_visual(_drawing_area->window);
+
+        _offscreenbuf = gdk_image_new (GDK_IMAGE_FASTEST, visual, width,
+                                       height);
+	   
   	static_cast<render_handler_agg_base *>(_agg_renderer)->init_buffer(
-  	  _offscreenbuf,
-  		_offscreenbuf_size,
-  		_width,
-  		_height,
-  		_width*((_bpp+7)/8)
+  		(unsigned char*) _offscreenbuf->mem,
+  		_offscreenbuf->bpl * _offscreenbuf->height,
+  		_offscreenbuf->width,
+  		_offscreenbuf->height,
+  		_offscreenbuf->bpl
   	);
-  	
-  	
-#ifdef ENABLE_MIT_SHM
-  }
-#endif  
-	
 }
 
 void 
 GtkAggGlue::beforeRendering()
 {
-#ifdef ENABLE_MIT_SHM
-  if (_shm_image) {
-    // The shared memory buffer is copied in background(!) since the X 
-    // calls are executed asynchroneously. This is dangerous because it
-    // may happen that the renderer updates the buffer while the X server
-    // still copies the data to the VRAM (flicker can occurr).
-    // Instead of using the XShmCompletionEvent for this we just call XSync
-    // right before writing to the shared memory again. This will make sure
-    // that the X server finishes to copy the data to VRAM before we
-    // change it again.
-    XSync(gdk_display, False);
+  if (_offscreenbuf && _offscreenbuf->type == GDK_IMAGE_SHARED) {
+    gdk_flush();
   }
-#endif  
 }
 
 void
 GtkAggGlue::render()
 {
-
-#ifdef ENABLE_MIT_SHM
-  if (_shm_image) {
-  
-    XShmPutImage(
-      gdk_display, 
-      GDK_WINDOW_XWINDOW(_drawing_area->window), 
-      GDK_GC_XGC(_drawing_area->style->fg_gc[GTK_STATE_NORMAL]),  // ???
-      _shm_image,
-      0, 0,
-      0, 0,
-      _width, _height,
-      False); 
-      
-      // NOTE: Data will be copied in background, see beforeRendering()
-      
-  } else {
-#endif  
-
-  	// Update the entire screen
-  	gdk_draw_rgb_image (
-  		_drawing_area->window,
-  		_drawing_area->style->fg_gc[GTK_STATE_NORMAL],
-  		0,
-  		0,
-  		_width,
-  		_height,
-  		GDK_RGB_DITHER_NONE,
-  		_offscreenbuf,
-  		_width*((_bpp+7)/8)
-  	);  	
-
-#ifdef ENABLE_MIT_SHM
-  }
-#endif  
-	
+    render(0, 0, _offscreenbuf->width, _offscreenbuf->height);
 }
 
 void
 GtkAggGlue::render(int minx, int miny, int maxx, int maxy)
 {
-#ifdef ENABLE_MIT_SHM
-  if (_shm_image) {
-  
-    XShmPutImage(
-      gdk_display, 
-      GDK_WINDOW_XWINDOW(_drawing_area->window), 
-      GDK_GC_XGC(_drawing_area->style->fg_gc[GTK_STATE_NORMAL]),  // ???
-      _shm_image,
-      minx, miny,
-      minx, miny,
-  		maxx-minx+1, maxy-miny+1,
-      False);
-      
-    // NOTE: Data will be copied in background, see beforeRendering()
-  
-  } else {
-#endif
-	size_t copy_width = std::min(_width * (_bpp/8), maxx - minx + 1);
-	size_t copy_height = std::min(_height, maxy - miny + 1);
-  	size_t stride = _width*((_bpp+7)/8);
-
-  	// Update only the invalidated rectangle
-  	gdk_draw_rgb_image (
-  		_drawing_area->window,
-  		_drawing_area->style->fg_gc[GTK_STATE_NORMAL],
-  		minx,
-	    	miny,
-  		copy_width,
-  		copy_height,
-  		GDK_RGB_DITHER_NORMAL,
-  		_offscreenbuf + miny*stride + minx*(_bpp/8),
-  		stride
-  	);
-
-#ifdef ENABLE_MIT_SHM
-  }
-#endif  
+    if (!_offscreenbuf) {
+      return;
+    }
+    const int& x = minx;
+    const int& y = miny;
+    size_t width = std::min(_offscreenbuf->width * (_offscreenbuf->depth/8), maxx - minx /*+ 1*/);
+    size_t height = std::min(_offscreenbuf->height, maxy - miny /*+ 1*/);
+
+    GdkGC* gc = gdk_gc_new(_drawing_area->window);
+    
+    gdk_draw_image(_drawing_area->window, gc, _offscreenbuf, x, y, x, y, width,
+                   height);
+    gdk_gc_unref(gc);
 }
 
 void
@@ -557,25 +190,5 @@ GtkAggGlue::configure(GtkWidget *const /
 		setRenderHandlerSize(event->width, event->height);
 }
 
-
-void 
-GtkAggGlue::decode_mask(unsigned long mask, unsigned int *shift, unsigned int *size)
-{
-  *shift = 0;
-  *size = 0;
-  
-  if (mask==0) return; // invalid mask
-  
-  while (!(mask & 1)) {
-    (*shift)++;
-    mask = mask >> 1;
-  }
-  
-  while (mask & 1) {
-    (*size)++;
-    mask = mask >> 1;
-  }
-}
-
 } // namespace gnash
 
