Esempio n. 1
0
Renderer*
GtkOvgGlue::createRenderHandler()
{
    GNASH_REPORT_FUNCTION;

    if (!_drawing_area) {
        log_error("No area to draw in!");
        return 0;
    }
    
    GdkVisual* wvisual = gdk_drawable_get_visual(_drawing_area->window);
    GdkImage* tmpimage = gdk_image_new (GDK_IMAGE_FASTEST, wvisual, 1, 1);
    // const GdkVisual* visual = tmpimage->visual;
    gdk_image_destroy(tmpimage);

    _renderer.reset(reinterpret_cast<renderer::openvg::Renderer_ovg *>
                    (renderer::openvg::create_handler(0)));
    if (!_renderer) {
        boost::format fmt = boost::format(
            _("Could not create OPENVG renderer"));
        throw GnashException(fmt.str());
    }

    return reinterpret_cast<Renderer *>(_renderer.get());
}
Esempio n. 2
0
void
GtkAggGlue::setRenderHandlerSize(int width, int height)
{
    assert(width > 0);
    assert(height > 0);
    assert(_agg_renderer != NULL);
    
    if (_offscreenbuf && _offscreenbuf->width == width &&
        _offscreenbuf->height == height) {
        return; 
    }

    if (_offscreenbuf) {
        gdk_image_destroy(_offscreenbuf);
    }

    GdkVisual* visual = gdk_drawable_get_visual(_drawing_area->window);

    _offscreenbuf = gdk_image_new (GDK_IMAGE_FASTEST, visual, width,
                                   height);

   	static_cast<Renderer_agg_base *>(_agg_renderer)->init_buffer(
        (unsigned char*) _offscreenbuf->mem,
        _offscreenbuf->bpl * _offscreenbuf->height,
        _offscreenbuf->width,
        _offscreenbuf->height,
        _offscreenbuf->bpl); 
}
Esempio n. 3
0
Renderer*
GtkAggGlue::createRenderHandler()
{
    GdkVisual* wvisual = gdk_drawable_get_visual(_drawing_area->window);

    GdkImage* tmpimage = gdk_image_new (GDK_IMAGE_FASTEST, wvisual, 1, 1);

    const GdkVisual* visual = tmpimage->visual;

    // FIXME: we use bpp instead of depth, because depth doesn't appear to
    // include the padding byte(s) the GdkImage actually has.
    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->bpp * 8);

    gdk_image_destroy(tmpimage);

    _agg_renderer = create_Renderer_agg(pixelformat);
    if (! _agg_renderer) {
        boost::format fmt = boost::format(
            _("Could not create AGG renderer with pixelformat %s")
            ) % pixelformat;
        throw GnashException(fmt.str());
    }

    return _agg_renderer;
}
Esempio n. 4
0
int main (int argc, char *argv[])
{
	int i;
	GdkImage *image;

	rfbClientLog = GtkDefaultLog;
	rfbClientErr = GtkErrorLog;

	gtk_init (&argc, &argv);

	/* create a dummy image just to make use of its properties */
	image = gdk_image_new (GDK_IMAGE_FASTEST, gdk_visual_get_system(),
				200, 100);

	cl = rfbGetClient (image->depth / 3, 3, image->bpp);

	cl->format.redShift     = image->visual->red_shift;
	cl->format.greenShift   = image->visual->green_shift;
	cl->format.blueShift    = image->visual->blue_shift;

	cl->format.redMax   = (1 << image->visual->red_prec) - 1;
	cl->format.greenMax = (1 << image->visual->green_prec) - 1;
	cl->format.blueMax  = (1 << image->visual->blue_prec) - 1;

	g_object_unref (image);

	cl->MallocFrameBuffer = resize;
	cl->canHandleNewFBSize = TRUE;
	cl->GotFrameBufferUpdate = update;
	cl->GotXCutText = got_cut_text;
	cl->HandleKeyboardLedState = kbd_leds;
	cl->HandleTextChat = text_chat;
	cl->GetPassword = get_password;
	cl->GetCredential = get_credential;

	show_connect_window (argc, argv);

	if (!rfbInitClient (cl, &argc, argv))
		return 1;

	while (1) {
		while (gtk_events_pending ())
			gtk_main_iteration ();
		i = WaitForMessage (cl, 500);
		if (i < 0)
			return 0;
		if (i && framebuffer_allocated == TRUE)
			if (!HandleRFBServerMessage(cl))
				return 0;
	}

	gtk_main ();

	return 0;
}
Esempio n. 5
0
/**
 *	Function that calculates a fractal and shows it in a GTK+ pixbuf
 *
 * @param[in] 	_oZmid		Center coordinate for the Mandelbrot fractal
 * @param[in] 	_oZxy		Size of the Mandelbrot window
 * @param[in] 	_rZoomFactor	Zoom factor ( Deduces the size of the window)
 * @return		Returns true success, otherwise false
 */
bool  bCalc_Fractal( void )
{
  // Create fractal
  int iSizeX=800;
  int iSizeY=800;
  Fractal  *poFractal= new Cmandelbrot( iSizeX, iSizeY);

  if(!poFractal)
    return false;
  
  bool bRet=poFractal->bCalc(oZmid,oZxy,rScale, 255);

  if (sFractal.pGDKimage2 == NULL )
  {
    sFractal.pGDKvisual2 = gdk_visual_get_system();
    sFractal.pGDKimage2= gdk_image_new( GDK_IMAGE_NORMAL, sFractal.pGDKvisual2, poFractal->iSizeX,poFractal->iSizeY);
  }

  if (sFractal.pGDKimage2 == NULL )
  {
    fprintf( stderr, "Not able to create gdkimage object\n");
    return FALSE;
  }

  if(sFractal.pWindow2== NULL)
  {
    sFractal.pWindow2= gtk_window_new(GTK_WINDOW_TOPLEVEL);
  }

  if(sFractal.pImage2==NULL)
  {
    sFractal.pImage2= gtk_image_new_from_image( sFractal.pGDKimage2, NULL );
  }
  else
  {
     gtk_image_set_from_image(GTK_IMAGE(sFractal.pImage2), sFractal.pGDKimage2, NULL );
  }

  for (int i=0; i<poFractal->iSizeX; i++)
  {
    for (int j=0; j<poFractal->iSizeY; j++)
    {
      unsigned int uiColor = poFractal->uiGetPixBufColor(i,j);
      gdk_image_put_pixel( sFractal.pGDKimage2, i, j,(int) uiColor); //65535*rAbsSqr/rMax);
    }
  }

  if(poFractal)
    delete poFractal;

  return bRet;
}
Esempio n. 6
0
static VALUE
rg_initialize(VALUE self, VALUE type, VALUE visual, VALUE w, VALUE h)
{
    GdkImage* image = gdk_image_new((GdkImageType)RVAL2GENUM(type, GDK_TYPE_IMAGE_TYPE),
                                    GDK_VISUAL(RVAL2GOBJ(visual)),
                                    NUM2INT(w), NUM2INT(h));

    if (image)
        G_INITIALIZE(self, image);
    else
        rb_raise(rb_eArgError, "The image could not be created.");

    return Qnil;
}
Esempio n. 7
0
void video_setsize( int width, int height )
{
  video_buffer_width = width;
  video_buffer_height = height;

  if( video_buffer_1 )
  {
    free( video_buffer_1 );
  }

  if( image_1 )
  {
    gdk_image_destroy( image_1 );
  }

  if( video_buffer_2 )
  {
    free( video_buffer_2 );
  }

  if( image_2 )
  {
    gdk_image_destroy( image_2 );
  }

  gtk_widget_set_usize( GTK_WIDGET( nes_gtk_window ), width, height );

  /* Buffer allocation. */
  video_buffer_1 = (unsigned char*) malloc( width * height * 8 );
  image_1 = gdk_image_new( GDK_IMAGE_FASTEST, visual, width, height );
  video_buffer_2 = (unsigned char*) malloc( width * height * 8 );
  image_2 = gdk_image_new( GDK_IMAGE_FASTEST, visual, width, height );

  cur_image = image_1;
  cur_video_buffer = video_buffer_1;
}
Esempio n. 8
0
void
GtkOvgGlue::setRenderHandlerSize(int width, int height)
{
    GNASH_REPORT_FUNCTION;

    assert(width > 0);
    assert(height > 0);
    assert(_renderer != NULL);
    
#ifdef ENABLE_EGL_OFFSCREEN
    if (_offscreenbuf && _offscreenbuf->width == width &&
        _offscreenbuf->height == height) {
        return; 
    }

    if (_offscreenbuf) {
        gdk_image_destroy(_offscreenbuf);
    }

    GdkVisual* visual = gdk_drawable_get_visual(_drawing_area->window);
    _offscreenbuf = gdk_image_new (GDK_IMAGE_FASTEST, visual, width,
                                   height);
#endif

#if 1
    // if (_renderer) {
    //     vgScale(width, height);
    // }
#else
    // Attach the window to the low level device
    long xid = GDK_WINDOW_XID(gtk_widget_get_window(_drawing_area));
    _device->attachWindow(static_cast<renderer::GnashDevice::native_window_t>
                          (xid));

    vgLoadIdentity();

    // Allow drawing everywhere by default
    InvalidatedRanges ranges;
    ranges.setWorld();
    _renderer->set_invalidated_regions(ranges);    

    renderer::EGLDevice *egl = (renderer::EGLDevice*)_device.get();
    egl->swapBuffers();
#endif    
}
Esempio n. 9
0
void *pl_fbdev_set_mode(int w, int h, int bpp)
{
	if (w <= 0 || h <= 0)
		return pl_fbdev_buf;

	if (image) gdk_image_destroy(image);
	image = gdk_image_new( GDK_IMAGE_FASTEST, gdk_visual_get_system(), w, h );

	pl_fbdev_buf = (void *) image->mem;

	gtk_image_set_from_image (GTK_IMAGE(drawing), image, NULL);

	gtk_window_resize (GTK_WINDOW (actor), w, h);
	hildon_animation_actor_set_scale (actor,
				(gdouble)D_WIDTH / (gdouble)w,
				(gdouble)D_HEIGHT / (gdouble)h
	);

	return pl_fbdev_buf;
}
Esempio n. 10
0
void		creat_notebook(t_init *init, t_menu *menu, t_launch_infos *infos)
{
  infos->notebook->notebook = gtk_notebook_new();
  gtk_box_pack_start(GTK_BOX(init->vbox),
		     infos->notebook->notebook, TRUE, TRUE, 0);
  infos->notebook->text_view = gtk_text_view_new();
  infos->notebook->text_buffer = gtk_text_view_get_buffer(
							  GTK_TEXT_VIEW(infos->notebook->text_view));
  gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(infos->notebook->text_view),
			      GTK_WRAP_WORD);
  creat_editor(menu, infos);
  infos->notebook->tablabel = gtk_label_new("SCENE");
  infos->notebook->image = gdk_image_new(GDK_IMAGE_NORMAL,
					 gdk_visual_get_system(), 800, 600);
  infos->notebook->scene = gtk_image_new_from_image(infos->notebook->image,
						    NULL);
  gtk_notebook_append_page(GTK_NOTEBOOK(infos->notebook->notebook),
  			   infos->notebook->scene, infos->notebook->tablabel);
  gtk_notebook_set_tab_pos(GTK_NOTEBOOK(infos->notebook->notebook),
			   GTK_POS_TOP);
  gtk_notebook_set_scrollable(GTK_NOTEBOOK(infos->notebook->notebook), TRUE);
}
Esempio n. 11
0
/* Change the size of the canvas. */
void video_canvas_resize(video_canvas_t *canvas, char resize_canvas)
{
    if (console_mode || video_disabled_mode) {
        return;
    }
    canvas->videoconfig->readable = 1; /* it's not direct rendering */

    if (canvas->gdk_image != NULL) {
        g_object_unref(canvas->gdk_image);
    }
    canvas->gdk_image = gdk_image_new(GDK_IMAGE_FASTEST, gtk_widget_get_visual(canvas->emuwindow), canvas->draw_buffer->canvas_physical_width, canvas->draw_buffer->canvas_physical_height);

#ifdef HAVE_HWSCALE
    lib_free(canvas->hwscale_image);
    canvas->hwscale_image = lib_malloc(canvas->gdk_image->width * canvas->gdk_image->height * 4);
#endif

    if (video_canvas_set_palette(canvas, canvas->palette) < 0) {
        log_debug("Setting palette for this mode failed. (Try 16/24/32 bpp.)");
        exit(-1);
    }

    ui_resize_canvas_window(canvas);
}
Esempio n. 12
0
void WinDraw_ChangeSize(void)
{
	DWORD oldx = WindowX, oldy = WindowY;
	int dif;

	Mouse_ChangePos();

	switch (Config.WinStrech) {
	case 0:
		WindowX = TextDotX;
		WindowY = TextDotY;
		break;

	case 1:
		WindowX = 768;
		WindowY = 512;
		break;

	case 2:
		if (TextDotX <= 384)
			WindowX = TextDotX * 2;
		else
			WindowX = TextDotX;
		if (TextDotY <= 256)
			WindowY = TextDotY * 2;
		else
			WindowY = TextDotY;
		break;

	case 3:
		if (TextDotX <= 384)
			WindowX = TextDotX * 2;
		else
			WindowX = TextDotX;
		if (TextDotY <= 256)
			WindowY = TextDotY * 2;
		else
			WindowY = TextDotY;
		dif = WindowX - WindowY;
		if ((dif > -32) && (dif < 32)) {
			// 正方形に近い画面なら、としておこう
			WindowX = (int)(WindowX * 1.25);
		}
		break;
	}

	if ((WindowX > 768) || (WindowX <= 0)) {
		if (oldx)
			WindowX = oldx;
		else
			WindowX = oldx = 768;
	}
	if ((WindowY > 512) || (WindowY <= 0)) {
		if (oldy)
			WindowY = oldy;
		else
			WindowY = oldy = 512;
	}

	surface_rect.width = TextDotX;
	surface_rect.height = TextDotY;

	if ((oldx == WindowX) && (oldy == WindowY))
		return;

	if ((TextDotX == WindowX) && (TextDotY == WindowY))
		screen_mode = 0;
	else {
		screen_mode = 1;
		if (scaled_screen)
			gdk_image_destroy(scaled_screen);
		scaled_screen = gdk_image_new(GDK_IMAGE_FASTEST,
		    surface->visual, WindowX, WindowY);
	}
	if (surface) {
		bzero(ScrBuf, FULLSCREEN_WIDTH * FULLSCREEN_HEIGHT * 2);
#if 1
		gdk_draw_rectangle(pixmap, window->style->black_gc, TRUE,
		    0, 0, FULLSCREEN_WIDTH, FULLSCREEN_HEIGHT);
#else
		gdk_draw_rectangle(pixmap, window->style->black_gc, TRUE,
		    oldx, 0, FULLSCREEN_WIDTH - oldx, FULLSCREEN_HEIGHT);
		gdk_draw_rectangle(pixmap, window->style->black_gc, TRUE,
		    0, oldy, FULLSCREEN_WIDTH - oldx, FULLSCREEN_HEIGHT - oldy);
#endif
	}

	WinDraw_InitWindowSize((WORD)WindowX, (WORD)WindowY);
	gtk_widget_set_usize(drawarea, winw, winh);
	gtk_widget_set_uposition(window, winx, winy);
	StatBar_Show(Config.WindowFDDStat);
	Mouse_ChangePos();
}
Esempio n. 13
0
GdkImage* c_gdk_image_new (GdkVisual* visual, int width, int height)
{
	return gdk_image_new (GDK_IMAGE_FASTEST, visual, width, height);
}
Esempio n. 14
0
static GdkBitmap *
scale_bitmap (GdkWindow *window, GdkBitmap *bitmap, gdouble scale_x, gdouble scale_y)
{
  GdkGC *gc;
  GdkVisual *visual = NULL;
  GdkImage *image = NULL, *new_image = NULL;
  GdkBitmap *new_bitmap = NULL;
  gint x, y, width, height, new_width, new_height;
  GdkColor color;

  if(!bitmap) return NULL;
  if(!window) return NULL;

  gc = gdk_gc_new(bitmap);

  gdk_window_get_size(bitmap, &width, &height);

  if(scale_x == 1.0 && scale_y == 1.0){
    new_bitmap = gdk_pixmap_new(window, width, height, 1);
    color.pixel = 0;
    gdk_gc_set_foreground(gc, &color);
    gdk_draw_rectangle(new_bitmap, gc, TRUE, 0, 0, width, height);
    color.pixel = 1;
    gdk_gc_set_foreground(gc, &color);

    gdk_draw_pixmap(new_bitmap,
                    gc,
                    bitmap,
                    0, 0,
                    0, 0,
                    width, height);
    gdk_gc_unref(gc);
    return new_bitmap;
  }

  new_width = roundint(width * scale_x);
  new_height = roundint(height * scale_y);

  /* make a client side image of the bitmap, and
   * scale the data into a another client side image */
  visual = gdk_window_get_visual (bitmap);
  if(!visual) return NULL;
  new_image = gdk_image_new(GDK_IMAGE_FASTEST,visual,new_width,new_height);
  if(!new_image) return NULL;
  new_bitmap = gdk_pixmap_new(window, new_width, new_height, 1);

  image = gdk_drawable_get_image(bitmap,
                        0, 0,
                        width, height);

  color.pixel = 0;
  gdk_gc_set_foreground(gc, &color);
  gdk_draw_rectangle(new_bitmap, gc, TRUE, 0, 0, width, height);
  color.pixel = 1;
  gdk_gc_set_foreground(gc, &color);

  for(x = 0; x < new_width; x++){
    for(y = 0; y < new_height; y++){
      gint px, py;
      gulong pixel;

      px = MIN(roundint(x / scale_x), width - 1);
      py = MIN(roundint(y / scale_y), height - 1);

      pixel = gdk_image_get_pixel(image, px, py);
      gdk_image_put_pixel(new_image, x, y, pixel);
    }
  }

  /* draw the image into a new pixmap */
  gdk_draw_image(new_bitmap,gc,new_image,0,0,0,0,new_width,new_height);

  gdk_image_destroy(image);
  gdk_image_destroy(new_image);

  gdk_gc_unref(gc);

  return new_bitmap;
}
Esempio n. 15
0
int main(int argc, char *argv[])
{
	GtkWidget *window, *imagebox;
	GdkVisual *visual;
	GdkImage *image;
	FIBITMAP *dib;
	int y;

	// initialize the FreeImage library
	FreeImage_Initialise();

	dib = FreeImage_Load(FIF_PNG, "freeimage.png", PNG_DEFAULT);

	gtk_init(&argc, &argv);

	window = gtk_window_new(GTK_WINDOW_TOPLEVEL);

	gtk_signal_connect(GTK_OBJECT(window), "destroy",
				GTK_SIGNAL_FUNC(destroy), NULL);

	visual = gdk_visual_get_system();

	image = gdk_image_new(GDK_IMAGE_NORMAL,visual,
		FreeImage_GetWidth(dib),FreeImage_GetHeight(dib));

	g_print("picture: %d bpp\n"
		"system:  %d bpp   byteorder: %d\n"
		"  redbits: %d   greenbits: %d   bluebits: %d\n"
		"image:   %d bpp   %d bytes/pixel\n",
		FreeImage_GetBPP(dib),
		visual->depth,visual->byte_order,
		visual->red_prec,visual->green_prec,visual->blue_prec,
		image->depth,image->bpp );

	if (FreeImage_GetBPP(dib) != (image->bpp << 3)) {
		FIBITMAP *ptr;

		switch (image->bpp) {
			case 1:
				ptr = FreeImage_ConvertTo8Bits(dib);
				break;

			case 2:
				if (image->depth == 15) {
					ptr = FreeImage_ConvertTo16Bits555(dib);
				} else {
					ptr = FreeImage_ConvertTo16Bits565(dib);
				}

				break;
			case 3:
				ptr = FreeImage_ConvertTo24Bits(dib);
				break;

			default:
			case 4:
				ptr = FreeImage_ConvertTo32Bits(dib);
				break;
		}

		FreeImage_Unload(dib);
		dib = ptr;
	}

//makes it upside down :(
//	memcpy(image->mem, FreeImage_GetBits(dib), image->bpl * image->height);

	BYTE *ptr = FreeImage_GetBits(dib);

	for (y = 0; y < image->height; y++) {
		memcpy(image->mem + (y * image->bpl),
			ptr + ((image->height - y - 1) * image->bpl),
			image->bpl);
	}

	FreeImage_Unload(dib);

	imagebox = gtk_image_new(image, NULL);
	gtk_container_add(GTK_CONTAINER(window), imagebox);

	gtk_widget_show(imagebox);
	gtk_widget_show(window);

	gtk_main();

	// release the FreeImage library
	FreeImage_DeInitialise();

	return 0;
}
Esempio n. 16
0
static enum xshm_map_mode
x_tile_set_map_mode(TileTab *t, NhGtkProgressWindow *w)
{
    int i;
    enum xshm_map_mode mode;
    GdkPixbuf *copy;
    guchar *pixels;
    GdkGC *gc;
    if (!t->spread && !t->transparent)
	mode = XSHM_MAP_PIXMAP;
    else
	mode = getenv("HACKPIXBUF") ? XSHM_MAP_PIXBUF : XSHM_MAP_IMAGE;
    /*
     * Pixbufs use so much memory that it's not unexpected for us to
     * fail to generate the alpha channel correctly. This is not a
     * great problem since we carefully avoid using it ourselves
     * (preferring to use the transparent colour directly), but might
     * cause gdk_pixbuf_render_to_drawable() to get slightly confused
     * when it dithers the tile (the transparent colour may bleed into
     * the glyph). We therefore issue a warning.
     *
     * Note: It's not clear that gdk_pixbuf_render_to_drawable()
     * actually uses this information, but what more can we do?
     * There's little point using gdk_pixbuf_render_to_drawable_alpha()
     * since all that does is take care not to draw transparent pixels
     * (which we don't care about anyway; we'll never read them).
     */
    if (mode == XSHM_MAP_PIXBUF && gdk_pixbuf_get_has_alpha(tile_pixbuf)) {
	/* We can't trust the XPM alpha channel & it will
	 * overide if we don't get rid of it here */
	copy = gdk_pixbuf_new(gdk_pixbuf_get_colorspace(tile_pixbuf), FALSE,
	  gdk_pixbuf_get_bits_per_sample(tile_pixbuf),
	  t->tilemap_width, t->tilemap_height);
	nh_gtk_progress_window_stage_set_fraction(w, 0.25);
	if (copy) {
	    gdk_pixbuf_copy_area(tile_pixbuf, 0, 0,
	      t->tilemap_width, t->tilemap_height, copy, 0, 0);
	    gdk_pixbuf_unref(tile_pixbuf);
	    tile_pixbuf = copy;
	    nh_gtk_progress_window_stage_set_fraction(w, 0.5);
	} else {
	    pline("Warning: Not enough memory: Tiles may be degraded");
	    mode = XSHM_MAP_IMAGE;
	    nh_gtk_progress_window_stage_set_fraction(w, 0.0);
	}
    }
    if (mode == XSHM_MAP_PIXBUF && !gdk_pixbuf_get_has_alpha(tile_pixbuf)) {
	pixels = gdk_pixbuf_get_pixels(tile_pixbuf);
	nh_gtk_progress_window_stage_set_fraction(w, 0.75);
	copy = gdk_pixbuf_add_alpha(tile_pixbuf, TRUE,
	  pixels[0], pixels[1], pixels[2]);
	if (copy) {
	    gdk_pixbuf_unref(tile_pixbuf);
	    tile_pixbuf = copy;
	} else {
	    pline("Warning: Not enough memory: Tiles may be degraded");
	    mode = XSHM_MAP_IMAGE;
	    nh_gtk_progress_window_stage_set_fraction(w, 0.0);
	}
    }
    tmp_pixbuf = NULL;
    if (mode != XSHM_MAP_PIXBUF) {
	tile_pixmap = gdk_pixmap_new(main_window->window,
	  t->tilemap_width, t->tilemap_height, -1);
	if (!tile_pixmap)
	    panic("Not enough memory to load tiles!");
	nh_gtk_progress_window_stage_set_fraction(w,
	  mode == XSHM_MAP_IMAGE ? 0.025 : 0.3);
	gc = gdk_gc_new(tile_pixmap);
	gdk_pixbuf_render_to_drawable(tile_pixbuf, tile_pixmap, gc, 0, 0, 0, 0,
	  t->tilemap_width, t->tilemap_height, GDK_RGB_DITHER_NORMAL, 0, 0);
	gdk_gc_unref(gc);
	if (mode == XSHM_MAP_IMAGE) {
	    int step = total_tiles_used >= 100 ? total_tiles_used / 100 : 1;
	    nh_gtk_progress_window_stage_set_fraction(w, 0.1);
	    tile_transp = (struct tile_transp *)
	      alloc(total_tiles_used * sizeof(*tile_transp));
	    for(i = 0; i < total_tiles_used; i++) {
		calc_tile_transp(t, tile_pixbuf, i);
		if (i % step == 0)
		    nh_gtk_progress_window_stage_set_fraction(w,
		      0.1 + (i * 0.8) / total_tiles_used);
	    }
	    calc_tile_transp(t, tile_pixbuf, -1);
	    nh_gtk_progress_window_stage_set_fraction(w, 0.9);
	    /* TODO: Creating an image via a pixmap is very inefficient;
	     * this should be done directly from pixbuf, even if GTK+ doesn't
	     * provide any easy way to do this.
	     */
	    tile_image = gdk_image_get((GdkWindow *)tile_pixmap,
		0, 0, t->tilemap_width, t->tilemap_height);
	    if (!tile_image)
		panic("Not enough memory to load tiles!");
	    gdk_pixmap_unref(tile_pixmap);
	    tile_pixmap = NULL;
	    nh_gtk_progress_window_stage_set_fraction(w, 0.975);
	    tmp_img = gdk_image_new(GDK_IMAGE_NORMAL, gdk_visual_get_system(),
	      t->unit_width, t->unit_height);
	    if (!tmp_img)
		panic("Not enough memory to load tiles!");
#if GTK_CHECK_VERSION(1,3,3)
	    tile_bits_per_pixel = tile_image->bits_per_pixel;
#else
	    /*
	     * Technically, this could give an incorrect result. However, as
	     * long as the bitmap_pad is no more than 32 bits (max. X11 allows);
	     * the bytes/line is not larger than necessary; and the width is
	     * at least 32 pixels, then it will be correct.
	     */
	    tile_bits_per_pixel = tile_image->bpl * 8 / t->tilemap_width;
#endif
	} else
	    tmp_img = tile_image = NULL;
	gdk_pixbuf_unref(tile_pixbuf);
	tile_pixbuf = NULL;
    }
    nh_gtk_progress_window_stage_set_fraction(w, 1.0);
    return mode;
}
Esempio n. 17
0
void GtkViewWidget::repaint()	{
	GtkPaintContext &gtkContext = (GtkPaintContext&)view()->context();
	Angle angle = rotation();
	bool isRotated = (angle == DEGREES90) || (angle == DEGREES270);
	int w = isRotated ? myArea->allocation.height : myArea->allocation.width;
	int h = isRotated ? myArea->allocation.width : myArea->allocation.height;
	gtkContext.updatePixmap(myArea, w, h);
	view()->paint();
	switch (angle) {
		default:
			cleanOriginalPixbuf();
			cleanRotatedPixbuf();
			gdk_draw_pixmap(myArea->window, myArea->style->white_gc, gtkContext.pixmap(),
											0, 0, 0, 0, myArea->allocation.width, myArea->allocation.height);
			break;
		case DEGREES180:
			cleanRotatedPixbuf();
			if ((myOriginalPixbuf != 0) &&
					((gdk_pixbuf_get_width(myOriginalPixbuf) != w) ||
					 (gdk_pixbuf_get_height(myOriginalPixbuf) != h))) {
				cleanOriginalPixbuf();
			}
			if (myOriginalPixbuf == 0) {
				myOriginalPixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, false, 8, w, h);
				myImage = gdk_image_new(GDK_IMAGE_FASTEST, gdk_drawable_get_visual(gtkContext.pixmap()), w, h);
			}
			gdk_drawable_copy_to_image(gtkContext.pixmap(), myImage, 0, 0, 0, 0, w, h);
			gdk_pixbuf_get_from_image(myOriginalPixbuf, myImage, gdk_drawable_get_colormap(gtkContext.pixmap()),
																0, 0, 0, 0, w, h);
			::rotate180(myOriginalPixbuf);
			gdk_draw_pixbuf(myArea->window, myArea->style->white_gc, myOriginalPixbuf,
											0, 0, 0, 0, w, h, GDK_RGB_DITHER_NONE, 0, 0);
			break;
		case DEGREES90:
		case DEGREES270:
			if ((myOriginalPixbuf != 0) &&
					((gdk_pixbuf_get_width(myOriginalPixbuf) != w) ||
					 (gdk_pixbuf_get_height(myOriginalPixbuf) != h))) {
				cleanOriginalPixbuf();
			}
			if ((myRotatedPixbuf != 0) &&
					((gdk_pixbuf_get_width(myRotatedPixbuf) != h) ||
					 (gdk_pixbuf_get_height(myRotatedPixbuf) != w))) {
				cleanRotatedPixbuf();
			}
			if (myOriginalPixbuf == 0) {
				myOriginalPixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, false, 8, w, h);
				myImage = gdk_image_new(GDK_IMAGE_FASTEST, gdk_drawable_get_visual(gtkContext.pixmap()), w, h);
			}
			if (myRotatedPixbuf == 0) {
				myRotatedPixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, false, 8, h, w);
			}
			gdk_drawable_copy_to_image(gtkContext.pixmap(), myImage, 0, 0, 0, 0, w, h);
			gdk_pixbuf_get_from_image(myOriginalPixbuf, myImage, gdk_drawable_get_colormap(gtkContext.pixmap()),
																0, 0, 0, 0, w, h);
			::rotate90(myRotatedPixbuf, myOriginalPixbuf, angle == DEGREES90);
			gdk_draw_pixbuf(myArea->window, myArea->style->white_gc, myRotatedPixbuf,
											0, 0, 0, 0, h, w, GDK_RGB_DITHER_NONE, 0, 0);
			break;
	}
}
Esempio n. 18
0
int WinDraw_Init(void)
{
	GdkVisual *visual;
	GdkColormap *colormap;
	GdkBitmap *mask;

	WindowX = 768;
	WindowY = 512;

	if ((root_width < WindowX) || (root_height < WindowY)) {
		fprintf(stderr, "No support resolution.\n");
		return FALSE;
	}

	visual = gtk_widget_get_visual(drawarea);

	switch (visual->type) {
	case GDK_VISUAL_TRUE_COLOR:
		break;
	case GDK_VISUAL_DIRECT_COLOR:
		if (visual->depth >= 15)
			break;
		/* FALLTHROUGH */
	default:
		fprintf(stderr, "No support visual class.\n");
		return FALSE;
	}

	/* 15 or 16 bpp 以外はサポート外 */
	if (visual->depth != 15 && visual->depth != 16) {
		fprintf(stderr, "No support depth.\n");
		return FALSE;
	}
	WinDraw_Pal16R = visual->red_mask;
	WinDraw_Pal16G = visual->green_mask;
	WinDraw_Pal16B = visual->blue_mask;

	surface = gdk_image_new(GDK_IMAGE_FASTEST, visual, FULLSCREEN_WIDTH,
	    FULLSCREEN_HEIGHT);
	if (surface == NULL) {
		g_message("can't create surface.");
		return 1;
	}
	ScrBuf = (WORD *)(surface->mem);

	pixmap = gdk_pixmap_new(drawarea->window,
	    FULLSCREEN_WIDTH, FULLSCREEN_HEIGHT, visual->depth);
	if (pixmap == NULL) {
		g_message("can't create pixmap.");
		return FALSE;
	}
	gdk_draw_rectangle(pixmap, window->style->black_gc, TRUE, 0, 0,
	    FULLSCREEN_WIDTH, FULLSCREEN_HEIGHT);

	/* けろぴーすぷらっしゅ用意 */
	colormap = gtk_widget_get_colormap(window);
	splash_pixmap = gdk_pixmap_colormap_create_from_xpm_d(NULL, colormap,
	    &mask, NULL, keropi_xpm);
	if (splash_pixmap == NULL)
		g_error("Couldn't create replacement pixmap.");

	return TRUE;
}
Esempio n. 19
0
GdkImage *gdkimage_from_pikeimage(struct object *img, int fast, GdkImage *i) {
  GdkColormap *col=gdk_colormap_get_system();
  GdkVisual *vis=gdk_visual_get_system();
  struct image *img_data;
  INT_TYPE x,y;

  TIMER_INIT("Getting extents");

  img_data=(struct image*)get_storage(img, image_program);

  /* 1a: create the actual image... */
  x = img_data->xsize;
  y = img_data->ysize;


  if (x==0 || y==0)
    Pike_error("Size of image must be > 0x0\n");
  if (i) {
    if ((i->width!=x) || (i->height!=y)) {
      gdk_image_destroy((void *)i);
      i=NULL;
    }
  }
  if (!i) {
    PFTIME("Create");
    i=(void *)gdk_image_new(fast,vis,x,y);
  }

  if (!i)
    Pike_error("Failed to create gdkimage\n");

  /* 1b: do the work.. */

  if (vis->type==GDK_VISUAL_TRUE_COLOR || vis->type==GDK_VISUAL_STATIC_GRAY)
    /* no colormap.. */
  {
    int pad=0;
    int native_byteorder;
    PFTIME("Convert");
    if (vis->type==GDK_VISUAL_STATIC_GRAY)
      pgtk2_encode_grey(img_data,i->mem,i->bpp,i->bpl);
    else {
      if (i->bpl!=(i->bpp*x))
	switch(i->bpl & 3) {
	 case  0: pad = 4; break;
	 case  1: pad = 1; break;
	 case  2: pad = 2; break;
	 case  3: pad = 1; break;
	}
      else
	pad=0;
      pgtk2_encode_truecolor_masks(img_data,i->bpp*8,pad*8,
				   (i->byte_order!=1),vis->red_mask,
				   vis->green_mask,vis->blue_mask,
				   i->mem, i->bpl*y);
    }
  } else {
    static int colors_allocated=0;
    static struct object *pike_cmap;
    /* I hate this... colormaps, here we come.. */
    /* This is rather complicated, but:
       1/ build an array of the colors in the colormap
       2/ use that array to build a pike X-image colormap.
       3/ call Image.X.encode_pseudocolor( img, bpp, lpad, depth, colormp )
       4/ copy the actual data to the image..
    */
    if (!colors_allocated) {
#define COLORMAP_SIZE 256
      char allocated[COLORMAP_SIZE];
      int j,i,r,g,b;
      PFTIME("Creating colormap");
      colors_allocated=1;
      MEMSET(allocated,0,sizeof(allocated));
      for (r=0; r<3; r++) for (g=0; g<4; g++) for (b=0; b<3; b++) {
	GdkColor color;
	color.red = (guint16)(r * (65535/2.0));
	color.green = (guint16)(g * (65535/3.0));
	color.blue = (guint16)(b * (65535/2.0));
	color.pixel = 0;
	if (gdk_color_alloc(col,&color))
          if (color.pixel<COLORMAP_SIZE)
            allocated[color.pixel]=1;
      }
      for (r=0; r<6; r++) for (g=0; g<7; g++) for (b=0; b<6; b++) {
	GdkColor color;
	color.red=(guint16)(r*(65535/5.0));
	color.green=(guint16)(g*(65535/6.0));
	color.blue=(guint16)(b*(65535/5.0));
	color.pixel=0;
	if (gdk_color_alloc(col,&color))
          if (color.pixel<COLORMAP_SIZE)
            allocated[color.pixel]=1;
      }

      for (i=0; i<COLORMAP_SIZE; i++) {
	if (allocated[i]) {
	  push_int(col->colors[i].red>>8);
	  push_int(col->colors[i].green>>8);
	  push_int(col->colors[i].blue>>8);
	  f_aggregate(3);
	} else
	  push_int(0);
      }
      f_aggregate(256);
      /* now on stack: the array with colors. */
      pgtk2_get_image_module();
      pgtk2_index_stack("colortable");
      /* on stack: array function */
      Pike_sp[0]=Pike_sp[-1];
      Pike_sp[-1]=Pike_sp[-2];
      Pike_sp[-2]=Pike_sp[0];
      /* on stack: function array */
      PFTIME("Creating colormap obj");
      apply_svalue(Pike_sp-2,1);
      /* on stack: function cmap */
      get_all_args("internal",1,"%o",&pike_cmap);
      pike_cmap->refs+=100; /* lets keep this one.. :-) */
      push_int(8);
      push_int(8);
      push_int(8);
      apply(pike_cmap,"rigid",3);
      pop_stack();
      apply(pike_cmap,"ordered",0);
      pop_stack();
      pop_stack();
    }
Esempio n. 20
0
int main(int argc, char *argv[]) {
    //
    GtkWidget *window;
    GtkWidget *fixed;
    GtkWidget *area;

    //
    gtk_init(&argc, &argv);

    // Window
    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_title(GTK_WINDOW(window), "gui");
    gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
    gtk_container_set_border_width(GTK_CONTAINER(window), 0);
    gtk_window_set_default_size(GTK_WINDOW(window), width, height);
    printf("window ok\n");

    // layout
    fixed = gtk_fixed_new();
    gtk_container_add(GTK_CONTAINER(window), fixed);
    printf("fixed ok\n");

    // Image
    GList *visuals = gdk_list_visuals();
    void tst(gpointer data, gpointer udata) {
        if (((GdkVisual*)data)->depth == 32)
        printf("visual :\n\ttype = %d\n\ttype = %d\n\tdepth = %d\n\tbits/rgb = %d\n\torder = %d\n\tred = %08X\n\tgreen = %08X\n\tblue = %08X\n"
                , ((GdkVisual*)data)->type
                , ((GdkVisual*)data)->colormap_size
                , ((GdkVisual*)data)->depth
                , ((GdkVisual*)data)->bits_per_rgb
                , ((GdkVisual*)data)->byte_order
                , ((GdkVisual*)data)->red_mask
                , ((GdkVisual*)data)->green_mask
                , ((GdkVisual*)data)->blue_mask
        );
    }
    g_list_foreach(visuals, &tst, NULL);
    GdkVisual *visu = gdk_visual_get_best_with_depth(32);
    ximg = gdk_image_new(GDK_IMAGE_SHARED, visu, width, height);
    printf("GdkImage : bytes/pix = %d, linesize = %d, bits/pix = %d ; type %d (mem = %p)\n"
            , ximg->bpp, ximg->bpl, ximg->bits_per_pixel
            , ximg->type, ximg->mem
    );
    // GdkPixbufAnimation
    //gtk_image_set_from_pixbuf

    //
    GdkColormap *dcm = gdk_colormap_new(visu, FALSE);
    // drawing area
    area = gtk_drawing_area_new();
    gdk_drawable_set_colormap(window, dcm);
    gdk_drawable_set_colormap(area, dcm);
    gtk_drawing_area_size(GTK_DRAWING_AREA(area), width, height);
    printf("area ok\n");

    //
    gtk_fixed_put(GTK_FIXED(fixed), area, 0, 0);
    printf("fixed ok\n");


    //
    bgra_alloc650(&bgra, width, height);
    bgra_origin650(&bgra, +width/2, +height/2);
    bgra_scale650(&bgra, 1, -1);
    printf("bgra alloc ok\n");
    maj();
    printf("bgra maj done, still (%p <- %p)\n", ximg->mem, bgra.data);
//    // Ximg
//    memcpy(ximg->mem, bgra.data, bgra.size);
//    printf("mcpy done\n");
    // Pixmap
    GdkColor bg;
    GdkColor fg;
    fg.pixel = 0xff000000;
    fg.red = 0;
    fg.green = 0;
    fg.blue = 0;
    bg.pixel = 0xff000000;
    bg.red = 0;
    bg.green = 0;
    bg.blue = 0;
    pixmap = gdk_pixmap_create_from_data(
            GTK_WINDOW(window)
            , bgra.data
            , width
            , height
            , 32
            , &fg
            , &bg
    );


//    img = gdk_pixbuf_new_from_data(
//              (guchar*)bgra.data
//            , GDK_COLORSPACE_RGB
//            , TRUE
//            , 8
//            , width
//            , height
//            , width << 2
//            , &pbd, NULL
//    );
//    printf("PixBuf new ok\n");

    //
    // Image
//    frame = gtk_image_new_from_pixbuf(img);
////    frame = gtimg;
//    gtk_fixed_put(GTK_FIXED(fixed), frame, 0, 0);
//    printf("fixed ok\n");


    // Events
    g_signal_connect(area, "expose-event", G_CALLBACK (on_expose_event), NULL);
//    g_signal_connect(frame, "expose-event", G_CALLBACK (on_expose_event), NULL);
    g_signal_connect(window, "delete-event", G_CALLBACK (delete_event), NULL);
    g_signal_connect(window, "destroy", G_CALLBACK (destroy), NULL);
    printf("signals ok\n");

    // Show
//    gtk_widget_show(area);
    gtk_widget_show(fixed);
    gtk_widget_show_all(window);
    printf("show ok\n");

    // Timer
    g_timeout_add(500, (GSourceFunc)time_handler, (gpointer)area);
    printf("timer ok\n");

    gtk_main();

    return 0;
}
Esempio n. 21
0
static void file_info_box_build()
{
	GtkWidget *hbox1, *vbox1;
	GtkWidget *info_exit, *info_mute;
	GtkWidget *info_unmute, *info_about;
	GtkWidget *scrw1;
	GtkWidget *expander;
	GdkVisual *visual;
	PangoFontDescription *desc;

	info_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
	gtk_object_set_data(GTK_OBJECT(info_window),
					"info_window", info_window);
	gtk_window_set_title(GTK_WINDOW(info_window),"Extended Module Player");
	gtk_window_set_policy(GTK_WINDOW(info_window), FALSE, FALSE, TRUE);
	gtk_signal_connect(GTK_OBJECT(info_window), "destroy",
		GTK_SIGNAL_FUNC(gtk_widget_destroyed), &info_window);
	gtk_container_border_width(GTK_CONTAINER(info_window), 0);
	gtk_widget_realize (info_window);

	vbox1 = gtk_vbox_new(FALSE, 0);
	gtk_container_add(GTK_CONTAINER(info_window), vbox1);
	gtk_object_set_data(GTK_OBJECT(vbox1), "vbox1", vbox1);
	gtk_container_border_width(GTK_CONTAINER(vbox1), 4);

	visual = gdk_visual_get_system();

	/*
	 * Image
	 */

	frame1 = gtk_event_box_new();
	gtk_object_set_data(GTK_OBJECT(frame1), "frame1", frame1);
	gtk_widget_set_size_request(frame1, 300, 128);
	gtk_box_pack_start(GTK_BOX(vbox1), frame1, FALSE, FALSE, 0);

	image = gdk_image_new(GDK_IMAGE_FASTEST, visual, 300, 128);
	ximage = GDK_IMAGE_XIMAGE(image);
	image1 = gtk_image_new_from_image(image, NULL);

	gtk_object_set_data(GTK_OBJECT(image1), "image1", image1);
	gtk_container_add (GTK_CONTAINER(frame1), image1);
	gtk_widget_set_events (frame1, GDK_BUTTON_PRESS_MASK | GDK_KEY_PRESS_MASK);
	gtk_signal_connect (GTK_OBJECT (frame1), "button_press_event",
			(GtkSignalFunc)image1_clicked, NULL);

	/*
	 * Buttons
	 */

	hbox1 = gtk_hbox_new (TRUE, 0);
	gtk_object_set_data(GTK_OBJECT(hbox1), "hbox1", hbox1);
	gtk_box_pack_start(GTK_BOX(vbox1), hbox1, TRUE, FALSE, 0);

	info_mute = gtk_button_new_with_label("Mute");
	gtk_signal_connect (GTK_OBJECT (info_mute), "clicked",
                            (GtkSignalFunc) button_mute, NULL);
	gtk_object_set_data(GTK_OBJECT(info_mute), "info_mute", info_mute);
	gtk_box_pack_start(GTK_BOX(hbox1), info_mute, TRUE, TRUE, 0);

	info_unmute = gtk_button_new_with_label("Unmute");
	gtk_signal_connect (GTK_OBJECT (info_unmute), "clicked",
                            (GtkSignalFunc) button_unmute, NULL);
	gtk_object_set_data(GTK_OBJECT(info_unmute), "info_unmute", info_unmute);
	gtk_box_pack_start(GTK_BOX(hbox1), info_unmute, TRUE, TRUE, 0);

	info_about = gtk_button_new_with_label("About");
	gtk_signal_connect_object(GTK_OBJECT(info_about), "clicked",
			(GtkSignalFunc) aboutbox, NULL);
	gtk_object_set_data(GTK_OBJECT(info_about), "info_about", info_about);
	gtk_box_pack_start(GTK_BOX(hbox1), info_about, TRUE, TRUE, 0);

	info_exit = gtk_button_new_with_label("Close");
	gtk_signal_connect_object(GTK_OBJECT(info_exit), "clicked",
		GTK_SIGNAL_FUNC(gtk_widget_hide), GTK_OBJECT(info_window));
	gtk_object_set_data(GTK_OBJECT(info_exit), "info_exit", info_exit);
	gtk_box_pack_start(GTK_BOX(hbox1), info_exit, TRUE, TRUE, 0);

	/*
	 * Info area
	 */

	expander = gtk_expander_new("Module information");

	scrw1 = gtk_scrolled_window_new(NULL, NULL);
	gtk_object_set_data(GTK_OBJECT(scrw1), "scrw1", scrw1);
	gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrw1),
				GTK_POLICY_ALWAYS, GTK_POLICY_AUTOMATIC);

	gtk_container_add(GTK_CONTAINER(expander), scrw1);
	gtk_box_pack_start(GTK_BOX(vbox1), expander, TRUE, TRUE, 0);

	gtk_widget_set_size_request(scrw1, 290, 200);
	text1b = gtk_text_buffer_new(NULL);
	text1 = gtk_text_view_new_with_buffer(text1b);
	desc = pango_font_description_new();
	pango_font_description_set_family(desc, "Monospace");
	gtk_widget_modify_font(text1, desc);
	pango_font_description_free(desc);
	gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(text1), GTK_WRAP_NONE);

	gtk_object_set_data(GTK_OBJECT(text1), "text1", text1);
	gtk_container_add(GTK_CONTAINER(scrw1), text1);
	gtk_widget_realize(text1);

	gtk_widget_realize(image1);

	display = GDK_WINDOW_XDISPLAY(info_window->window);
	window = GDK_WINDOW_XWINDOW(info_window->window);
    	colormap = gdk_colormap_get_system();

	gdk_color_black(colormap, color_black);
	gdk_color_white(colormap, color_white);

	init_visual(visual);

	set_palette();
	clear_screen();

	ii->wresult = 0;

	panel_setup();
	gtk_timeout_add(50, (GtkFunction)panel_loop, NULL);
}
Esempio n. 22
0
/* this is called for a mode change: */
int
_tme_gtk_screen_mode_change(struct tme_fb_connection *conn_fb)
{
  struct tme_gtk_display *display;
  struct tme_gtk_screen *screen;
  struct tme_fb_connection *conn_fb_other;
  struct tme_fb_xlat fb_xlat_q;
  const struct tme_fb_xlat *fb_xlat_a;
  int scale;
  unsigned long fb_area, avail_area, percentage;
  gint width, height;
  gint height_extra;
  const void *map_g_old;
  const void *map_r_old;
  const void *map_b_old;
  const tme_uint32_t *map_pixel_old;
  tme_uint32_t map_pixel_count_old;  
  tme_uint32_t colorset;
  GdkImage *gdkimage;
  GdkVisual *visual;
  tme_uint32_t color_count, color_i;
  tme_uint32_t color_count_distinct;
  tme_uint32_t color_j;
  struct tme_fb_color *colors_tme;
  GdkColor *colors_gdk;
  gboolean *success;
  gboolean warned_color_alloc;

  /* recover our data structures: */
  display = conn_fb->tme_fb_connection.tme_connection_element->tme_element_private;
  conn_fb_other = (struct tme_fb_connection *) conn_fb->tme_fb_connection.tme_connection_other;

  /* lock our mutex: */
  tme_mutex_lock(&display->tme_gtk_display_mutex);

  /* find the screen that this framebuffer connection references: */
  for (screen = display->tme_gtk_display_screens;
       (screen != NULL
	&& screen->tme_gtk_screen_fb != conn_fb);
       screen = screen->tme_gtk_screen_next);
  assert (screen != NULL);

  /* if the user hasn't specified a scaling, pick one: */
  scale = screen->tme_gtk_screen_fb_scale;
  if (scale < 0) {

    /* calulate the areas, in square pixels, of the emulated
       framebuffer and the host's screen: */
    fb_area = (conn_fb_other->tme_fb_connection_width
	       * conn_fb_other->tme_fb_connection_height);
    avail_area = (gdk_screen_width()
		  * gdk_screen_height());

    /* see what percentage of the host's screen would be taken up by
       an unscaled emulated framebuffer: */
    percentage = (fb_area * 100) / avail_area;

    /* if this is at least 70%, halve the emulated framebuffer, else
       if this is 30% or less, double the emulated framebuffer: */
    if (percentage >= 70) {
      scale = TME_FB_XLAT_SCALE_HALF;
    }
    else if (percentage <= 30) {
      scale = TME_FB_XLAT_SCALE_DOUBLE;
    }
    else {
      scale = TME_FB_XLAT_SCALE_NONE;
    }

    screen->tme_gtk_screen_fb_scale = -scale;
  }

  /* get the system's default visual: */
  visual = gdk_visual_get_system();

  /* get the required dimensions for the GdkImage: */
  width = ((conn_fb_other->tme_fb_connection_width
	    * scale)
	   / TME_FB_XLAT_SCALE_NONE);
  height = ((conn_fb_other->tme_fb_connection_height
	     * scale)
	    / TME_FB_XLAT_SCALE_NONE);
  /* NB: we need to allocate an extra scanline's worth (or, if we're
     doubling, an extra two scanlines' worth) of image, because the
     framebuffer translation functions can sometimes overtranslate
     (see the explanation of TME_FB_XLAT_RUN in fb-xlat-auto.sh): */
  height_extra
    = (scale == TME_FB_XLAT_SCALE_DOUBLE
       ? 2
       : 1);

  /* if the previous gdkimage isn't the right size: */
  gdkimage = screen->tme_gtk_screen_gdkimage;
  if (gdkimage->width != width
      || gdkimage->height != (height + height_extra)) {

    /* allocate a new gdkimage: */
    gdkimage = gdk_image_new(GDK_IMAGE_FASTEST,
			     visual,
			     width,
			     height
			     + height_extra);

    /* set the new image on the image widget: */
    gtk_image_set(GTK_IMAGE(screen->tme_gtk_screen_gtkimage),
		  gdkimage,
		  NULL);

    /* destroy the previous gdkimage and remember the new one: */
    gdk_image_destroy(screen->tme_gtk_screen_gdkimage);
    screen->tme_gtk_screen_gdkimage = gdkimage;
  }

  /* remember all previously allocated maps and colors, but otherwise
     remove them from our framebuffer structure: */
  map_g_old = conn_fb->tme_fb_connection_map_g;
  map_r_old = conn_fb->tme_fb_connection_map_r;
  map_b_old = conn_fb->tme_fb_connection_map_b;
  map_pixel_old = conn_fb->tme_fb_connection_map_pixel;
  map_pixel_count_old = conn_fb->tme_fb_connection_map_pixel_count;
  conn_fb->tme_fb_connection_map_g = NULL;
  conn_fb->tme_fb_connection_map_r = NULL;
  conn_fb->tme_fb_connection_map_b = NULL;
  conn_fb->tme_fb_connection_map_pixel = NULL;
  conn_fb->tme_fb_connection_map_pixel_count = 0;

  /* update our framebuffer connection: */
  conn_fb->tme_fb_connection_width = width;
  conn_fb->tme_fb_connection_height = height;
  conn_fb->tme_fb_connection_depth = gdkimage->depth;
  conn_fb->tme_fb_connection_bits_per_pixel = _tme_gtk_gdkimage_bipp(gdkimage);
  conn_fb->tme_fb_connection_skipx = 0;
  conn_fb->tme_fb_connection_scanline_pad = _tme_gtk_gdkimage_scanline_pad(gdkimage);
  conn_fb->tme_fb_connection_order = (gdkimage->byte_order == GDK_LSB_FIRST
				      ? TME_ENDIAN_LITTLE
				      : TME_ENDIAN_BIG);
  conn_fb->tme_fb_connection_buffer = gdkimage->mem;
  switch (visual->type) {
  case GDK_VISUAL_STATIC_GRAY: 
  case GDK_VISUAL_GRAYSCALE:
    conn_fb->tme_fb_connection_class = TME_FB_XLAT_CLASS_MONOCHROME;
    break;
  default:
    assert(FALSE);
    /* FALLTHROUGH */
  case GDK_VISUAL_STATIC_COLOR:
  case GDK_VISUAL_PSEUDO_COLOR:
  case GDK_VISUAL_DIRECT_COLOR:
  case GDK_VISUAL_TRUE_COLOR:
    conn_fb->tme_fb_connection_class = TME_FB_XLAT_CLASS_COLOR;
    break;
  }
  switch (visual->type) {
  case GDK_VISUAL_DIRECT_COLOR:
    /* we set the primary maps to anything non-NULL, to indicate that
       primaries are index mapped: */
    conn_fb->tme_fb_connection_map_g = conn_fb;
    conn_fb->tme_fb_connection_map_r = conn_fb;
    conn_fb->tme_fb_connection_map_b = conn_fb;
    /* FALLTHROUGH */
  case GDK_VISUAL_TRUE_COLOR:
    conn_fb->tme_fb_connection_mask_g = visual->green_mask;
    conn_fb->tme_fb_connection_mask_r = visual->red_mask;
    conn_fb->tme_fb_connection_mask_b = visual->blue_mask;
    break;
  default:
    conn_fb->tme_fb_connection_mask_g = 0;
    conn_fb->tme_fb_connection_mask_r = 0;
    conn_fb->tme_fb_connection_mask_b = 0;
    break;
  }

  /* get the needed colors: */
  colorset = tme_fb_xlat_colors_get(conn_fb_other, scale, conn_fb, &colors_tme);
  color_count = conn_fb->tme_fb_connection_map_pixel_count;

  /* if we need to allocate colors, but the colorset is not tied to
     the source framebuffer characteristics, and is identical to the
     currently allocated colorset, we can reuse the previously
     allocated maps and colors: */
  if (color_count > 0
      && colorset != TME_FB_COLORSET_NONE
      && colorset == screen->tme_gtk_screen_colorset) {

    /* free the requested color array: */
    tme_free(colors_tme);

    /* restore the previously allocated maps and colors: */
    conn_fb->tme_fb_connection_map_g = map_g_old;
    conn_fb->tme_fb_connection_map_r = map_r_old;
    conn_fb->tme_fb_connection_map_b = map_b_old;
    conn_fb->tme_fb_connection_map_pixel = map_pixel_old;
    conn_fb->tme_fb_connection_map_pixel_count = map_pixel_count_old;
  }

  /* otherwise, we may need to free and/or allocate colors: */
  else {

    /* save the colorset signature: */
    screen->tme_gtk_screen_colorset = colorset;

    /* free any previously allocated maps and colors: */
    if (map_g_old != NULL) {
      tme_free((void *) map_g_old);
    }
    if (map_r_old != NULL) {
      tme_free((void *) map_r_old);
    }
    if (map_b_old != NULL) {
      tme_free((void *) map_b_old);
    }
    if (map_pixel_old != NULL) {

      /* recreate the array of GdkColor: */
      colors_gdk = tme_new(GdkColor, map_pixel_count_old);
      color_i = 0;
      do {
	colors_gdk[color_i].pixel = map_pixel_old[color_i];
      } while (++color_i < map_pixel_count_old);

      /* free the colors: */
      gdk_colormap_free_colors(gdk_colormap_get_system(),
			       colors_gdk,
			       map_pixel_count_old);
      tme_free(colors_gdk);
      tme_free((void *) map_pixel_old);
    }

    /* if we need to allocate colors: */
    if (color_count > 0) {

      /* make the GdkColor array, and count the number of distinct colors: */
      colors_gdk = tme_new(GdkColor, color_count * 2);
      color_count_distinct = 0;
      for (color_i = 0; color_i < color_count; color_i++) {
	color_j = colors_tme[color_i].tme_fb_color_pixel;
	colors_gdk[color_j].green = colors_tme[color_i].tme_fb_color_value_g;
	colors_gdk[color_j].red   = colors_tme[color_i].tme_fb_color_value_r;
	colors_gdk[color_j].blue  = colors_tme[color_i].tme_fb_color_value_b;
	if (color_j >= color_count_distinct) {
	  color_count_distinct = color_j + 1;
	}
      }
      success = tme_new(gboolean, color_count_distinct);

      /* allocate exact matches for as many colors as possible: */
      gdk_colormap_alloc_colors(gdk_colormap_get_system(),
				colors_gdk,
				color_count_distinct,
				FALSE,
				FALSE,
				success);

      /* allocate read-only best matches for any colors we failed to
	 allocate exactly: */
      warned_color_alloc = FALSE;
      for (color_i = 0; color_i < color_count; color_i++) {
	color_j = colors_tme[color_i].tme_fb_color_pixel;
	if (!success[color_j]) {
	  if (!gdk_colormap_alloc_color(gdk_colormap_get_system(),
					&colors_gdk[color_j],
					FALSE,
					TRUE)) {
	    if (!warned_color_alloc) {
	      warned_color_alloc = TRUE;
	      tme_log(&display->tme_gtk_display_element->tme_element_log_handle, 0, ENOMEM,
		      (&display->tme_gtk_display_element->tme_element_log_handle,
		       _("could not allocate all colors")));
	    }
	  }
	}
	colors_tme[color_i].tme_fb_color_pixel = colors_gdk[color_j].pixel;
      }

      /* free the arrays used with gdk_colormap_alloc_colors(): */
      tme_free(success);
      tme_free(colors_gdk);

      /* set the needed colors: */
      tme_fb_xlat_colors_set(conn_fb_other, scale, conn_fb, colors_tme);
    }
  }

  /* compose the framebuffer translation question: */
  fb_xlat_q.tme_fb_xlat_width			= conn_fb_other->tme_fb_connection_width;
  fb_xlat_q.tme_fb_xlat_height			= conn_fb_other->tme_fb_connection_height;
  fb_xlat_q.tme_fb_xlat_scale			= (unsigned int) scale;
  fb_xlat_q.tme_fb_xlat_src_depth		= conn_fb_other->tme_fb_connection_depth;
  fb_xlat_q.tme_fb_xlat_src_bits_per_pixel	= conn_fb_other->tme_fb_connection_bits_per_pixel;
  fb_xlat_q.tme_fb_xlat_src_skipx		= conn_fb_other->tme_fb_connection_skipx;
  fb_xlat_q.tme_fb_xlat_src_scanline_pad	= conn_fb_other->tme_fb_connection_scanline_pad;
  fb_xlat_q.tme_fb_xlat_src_order		= conn_fb_other->tme_fb_connection_order;
  fb_xlat_q.tme_fb_xlat_src_class		= conn_fb_other->tme_fb_connection_class;
  fb_xlat_q.tme_fb_xlat_src_map			= (conn_fb_other->tme_fb_connection_map_g != NULL
						   ? TME_FB_XLAT_MAP_INDEX
						   : TME_FB_XLAT_MAP_LINEAR);
  fb_xlat_q.tme_fb_xlat_src_map_bits		= conn_fb_other->tme_fb_connection_map_bits;
  fb_xlat_q.tme_fb_xlat_src_mask_g		= conn_fb_other->tme_fb_connection_mask_g;
  fb_xlat_q.tme_fb_xlat_src_mask_r		= conn_fb_other->tme_fb_connection_mask_r;
  fb_xlat_q.tme_fb_xlat_src_mask_b		= conn_fb_other->tme_fb_connection_mask_b;
  fb_xlat_q.tme_fb_xlat_dst_depth		= conn_fb->tme_fb_connection_depth;
  fb_xlat_q.tme_fb_xlat_dst_bits_per_pixel	= conn_fb->tme_fb_connection_bits_per_pixel;
  fb_xlat_q.tme_fb_xlat_dst_skipx		= conn_fb->tme_fb_connection_skipx;
  fb_xlat_q.tme_fb_xlat_dst_scanline_pad	= conn_fb->tme_fb_connection_scanline_pad;
  fb_xlat_q.tme_fb_xlat_dst_order		= conn_fb->tme_fb_connection_order;
  fb_xlat_q.tme_fb_xlat_dst_map			= (conn_fb->tme_fb_connection_map_g != NULL
						   ? TME_FB_XLAT_MAP_INDEX
						   : TME_FB_XLAT_MAP_LINEAR);
  fb_xlat_q.tme_fb_xlat_dst_mask_g		= conn_fb->tme_fb_connection_mask_g;
  fb_xlat_q.tme_fb_xlat_dst_mask_r		= conn_fb->tme_fb_connection_mask_r;
  fb_xlat_q.tme_fb_xlat_dst_mask_b		= conn_fb->tme_fb_connection_mask_b;

  /* ask the framebuffer translation question: */
  fb_xlat_a = tme_fb_xlat_best(&fb_xlat_q);

  /* if this translation isn't optimal, log a note: */
  if (!tme_fb_xlat_is_optimal(fb_xlat_a)) {
    tme_log(&display->tme_gtk_display_element->tme_element_log_handle, 0, TME_OK,
	    (&display->tme_gtk_display_element->tme_element_log_handle,
	     _("no optimal framebuffer translation function available")));
  }

  /* save the translation function: */
  screen->tme_gtk_screen_fb_xlat = fb_xlat_a->tme_fb_xlat_func;

  /* force the next translation to do a complete redraw: */
  screen->tme_gtk_screen_full_redraw = TRUE;

  /* unlock our mutex: */
  tme_mutex_unlock(&display->tme_gtk_display_mutex);

  /* done: */
  return (TME_OK);
}