예제 #1
0
/* Redraw the screen from the backing pixmap */
static gboolean expose_event (GtkWidget      *widget,
                              GdkEventExpose *event)
{
	static GdkImage *image = NULL;
	GdkCursor *cursor;
	GdkPixbuf *pixbuf;

	if (framebuffer_allocated == FALSE) {

		rfbClientSetClientData (cl, gtk_init, widget);

		image = gdk_drawable_get_image (widget->window, 0, 0,
		                                widget->allocation.width,
		                                widget->allocation.height);

		cl->frameBuffer= image->mem;

		cl->width  = widget->allocation.width;
		cl->height = widget->allocation.height;

		cl->format.bitsPerPixel = image->bits_per_pixel;
		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;

#ifdef LIBVNCSERVER_CONFIG_LIBVA
		/* Allow libvncclient to use a more efficient way
		 * of putting the framebuffer on the screen when
		 * using the H.264 format.
		 */
		cl->outputWindow = GDK_WINDOW_XID(widget->window);
#endif

		SetFormatAndEncodings (cl);

		framebuffer_allocated = TRUE;

		/* Also disable local cursor */
                pixbuf = gdk_pixbuf_new_from_xpm_data(dot_cursor_xpm);
	        cursor = gdk_cursor_new_from_pixbuf(gdk_display_get_default(), pixbuf, dot_cursor_x_hot, dot_cursor_y_hot);
		g_object_unref(pixbuf);	
		gdk_window_set_cursor (gtk_widget_get_window(GTK_WIDGET(window)), cursor);
		gdk_cursor_unref(cursor);
	}

#ifndef LIBVNCSERVER_CONFIG_LIBVA
	gdk_draw_image (GDK_DRAWABLE (widget->window),
	                widget->style->fg_gc[gtk_widget_get_state(widget)],
	                image,
	                event->area.x, event->area.y,
	                event->area.x, event->area.y,
	                event->area.width, event->area.height);
#endif

	return FALSE;
}
예제 #2
0
static VALUE
rg_get_image(VALUE self, VALUE x, VALUE y, VALUE w, VALUE h)
{
    return GOBJ2RVAL(gdk_drawable_get_image(_SELF(self), 
                                            NUM2INT(x), NUM2INT(y), 
                                            NUM2INT(w), NUM2INT(h)));
}
예제 #3
0
static void
draw_light_marker (gint xpos,
		   gint ypos)
{
  GdkColor  color;

  color.red   = 0x0;
  color.green = 0x0;
  color.blue  = 0x0;
  gdk_gc_set_rgb_bg_color (gc, &color);

  color.red   = 0x0;
  color.green = 0x4000;
  color.blue  = 0xFFFF;
  gdk_gc_set_rgb_fg_color (gc, &color);

  gdk_gc_set_function (gc, GDK_COPY);

  if (mapvals.lightsource.type == POINT_LIGHT)
    {
      lightx = xpos;
      lighty = ypos;

      /* Save background */
      /* =============== */

      backbuf.x = lightx - 7;
      backbuf.y = lighty - 7;
      backbuf.w = 14;
      backbuf.h = 14;

      /* X doesn't like images that's outside a window, make sure */
      /* we get the backbuffer image from within the boundaries   */
      /* ======================================================== */

      if (backbuf.x < 0)
        backbuf.x = 0;
      else if ((backbuf.x + backbuf.w) > PREVIEW_WIDTH)
        backbuf.w = (PREVIEW_WIDTH - backbuf.x);
      if (backbuf.y < 0)
        backbuf.y = 0;
      else if ((backbuf.y + backbuf.h) > PREVIEW_HEIGHT)
        backbuf.h = (PREVIEW_WIDTH - backbuf.y);

      backbuf.image = gdk_drawable_get_image (previewarea->window,
                                              backbuf.x, backbuf.y,
                                              backbuf.w, backbuf.h);

      gdk_draw_arc (previewarea->window, gc,
		    TRUE,
		    lightx - 7, lighty - 7, 14, 14,
		    0, 360 * 64);
    }
}
예제 #4
0
/****************************************************************************
  Converts a pixmap/mask sprite to a GdkPixbuf.

  This is just a helper function for sprite_get_pixbuf().  Most callers
  should use that function instead.
****************************************************************************/
static GdkPixbuf *gdk_pixbuf_new_from_pixmap_sprite(struct sprite *src)
{
  GdkPixbuf *dst;
  int w, h;

  w = src->width;
  h = src->height;
  
  /* convert pixmap */
  dst = gdk_pixbuf_new(GDK_COLORSPACE_RGB, src->mask != NULL, 8, w, h);
  gdk_pixbuf_get_from_drawable(dst, src->pixmap, NULL, 0, 0, 0, 0, w, h);

  /* convert mask */
  if (src->mask) {
    GdkImage *img;
    int x, y, rowstride;
    guchar *pixels;

    img = gdk_drawable_get_image(src->mask, 0, 0, w, h);

    pixels = gdk_pixbuf_get_pixels(dst);
    rowstride = gdk_pixbuf_get_rowstride(dst);

    for (y = 0; y < h; y++) {
      for (x = 0; x < w; x++) {
	guchar *pixel = pixels + y * rowstride + x * 4 + 3;

	if (gdk_image_get_pixel(img, x, y)) {
	  *pixel = 255;
	} else {
	  *pixel = 0;
	}
      }
    }
    g_object_unref(img);
  }

  return dst;
}
예제 #5
0
/****************************************************************************
  Method returns the bounding box of a sprite. It assumes a rectangular
  object/mask. The bounding box contains the border (pixel which have
  unset pixel as neighbours) pixel.
****************************************************************************/
void sprite_get_bounding_box(struct sprite * sprite, int *start_x,
			     int *start_y, int *end_x, int *end_y)
{
  GdkImage *mask_image;
  GdkBitmap *mask = sprite_get_mask(sprite);
  int i, j;

  if (!mask) {
    *start_x = 0;
    *start_y = 0;
    *end_x = sprite->width - 1;
    *end_y = sprite->height - 1;
    return;
  }

  mask_image
    = gdk_drawable_get_image(mask, 0, 0, sprite->width, sprite->height);


  /* parses mask image for the first column that contains a visible pixel */
  *start_x = -1;
  for (i = 0; i < sprite->width && *start_x == -1; i++) {
    for (j = 0; j < sprite->height; j++) {
      if (gdk_image_get_pixel(mask_image, i, j) != 0) {
	*start_x = i;
	break;
      }
    }
  }

  /* parses mask image for the last column that contains a visible pixel */
  *end_x = -1;
  for (i = sprite->width - 1; i >= *start_x && *end_x == -1; i--) {
    for (j = 0; j < sprite->height; j++) {
      if (gdk_image_get_pixel(mask_image, i, j) != 0) {
	*end_x = i;
	break;
      }
    }
  }

  /* parses mask image for the first row that contains a visible pixel */
  *start_y = -1;
  for (i = 0; i < sprite->height && *start_y == -1; i++) {
    for (j = *start_x; j <= *end_x; j++) {
      if (gdk_image_get_pixel(mask_image, j, i) != 0) {
	*start_y = i;
	break;
      }
    }
  }

  /* parses mask image for the last row that contains a visible pixel */
  *end_y = -1;
  for (i = sprite->height - 1; i >= *end_y && *end_y == -1; i--) {
    for (j = *start_x; j <= *end_x; j++) {
      if (gdk_image_get_pixel(mask_image, j, i) != 0) {
	*end_y = i;
	break;
      }
    }
  }

  g_object_unref(mask_image);
}
예제 #6
0
static void
draw_handles (void)
{
  gdouble     dxpos, dypos;
  gint        startx, starty, pw, ph;
  GimpVector3 viewpoint;
  GimpVector3 light_position;
  gint        k      = mapvals.light_selected;

  gfloat length;
  gfloat delta_x = 0.0;
  gfloat delta_y = 0.0;

  /* calculate handle position */
  compute_preview_rectangle (&startx, &starty, &pw, &ph);
  switch (mapvals.lightsource[k].type)
    {
    case NO_LIGHT:
      return;
    case POINT_LIGHT:
    case SPOT_LIGHT:
      /* swap z to reverse light position */
      viewpoint = mapvals.viewpoint;
      viewpoint.z = -viewpoint.z;
      light_position = mapvals.lightsource[k].position;
      gimp_vector_3d_to_2d (startx, starty, pw, ph, &dxpos, &dypos,
                            &viewpoint, &light_position);
      handle_xpos = (gint) (dxpos + 0.5);
      handle_ypos = (gint) (dypos + 0.5);
      break;
    case DIRECTIONAL_LIGHT:
      light_position.x = light_position.y = 0.5;
      light_position.z = 0;
      viewpoint.z = -viewpoint.z;
      gimp_vector_3d_to_2d (startx, starty, pw, ph, &dxpos, &dypos,
                            &viewpoint, &light_position);
      length = PREVIEW_HEIGHT / 4;
      delta_x = mapvals.lightsource[k].direction.x * length;
      delta_y = mapvals.lightsource[k].direction.y * length;
      handle_xpos = dxpos + delta_x;
      handle_ypos = dypos + delta_y;
      break;
    }

  gdk_gc_set_function (gc, GDK_COPY);

  if (mapvals.lightsource[k].type != NO_LIGHT)
    {
      GdkColor  color;

      /* Restore background if it has been saved */
      /* ======================================= */

      if (backbuf.image != NULL)
        {
          gdk_gc_set_function (gc, GDK_COPY);
          gdk_draw_image (previewarea->window, gc,
                          backbuf.image, 0, 0, backbuf.x,
                          backbuf.y, backbuf.w, backbuf.h);
          g_object_unref (backbuf.image);
          backbuf.image = NULL;
        }

      /* calculate backbuffer */
      switch (mapvals.lightsource[k].type)
        {
        case POINT_LIGHT:
          backbuf.x = handle_xpos - LIGHT_SYMBOL_SIZE / 2;
          backbuf.y = handle_ypos - LIGHT_SYMBOL_SIZE / 2;
          backbuf.w = LIGHT_SYMBOL_SIZE;
          backbuf.h = LIGHT_SYMBOL_SIZE;
          break;
        case DIRECTIONAL_LIGHT:
          if (delta_x <= 0)
            backbuf.x = handle_xpos;
          else
            backbuf.x = startx + pw/2;
          if (delta_y <= 0)
            backbuf.y = handle_ypos;
          else
            backbuf.y = starty + ph/2;
          backbuf.x -= LIGHT_SYMBOL_SIZE/2;
          backbuf.y -= LIGHT_SYMBOL_SIZE/2;
          backbuf.w = fabs(delta_x) + LIGHT_SYMBOL_SIZE;
          backbuf.h = fabs(delta_y) + LIGHT_SYMBOL_SIZE;
          break;
        case SPOT_LIGHT:
          backbuf.x = handle_xpos - LIGHT_SYMBOL_SIZE / 2;
          backbuf.y = handle_ypos - LIGHT_SYMBOL_SIZE / 2;
          backbuf.w = LIGHT_SYMBOL_SIZE;
          backbuf.h = LIGHT_SYMBOL_SIZE;
          break;
        case NO_LIGHT:
          break;
        }

      /* Save background */
      /* =============== */
      if ((backbuf.x >= 0) &&
          (backbuf.x <= PREVIEW_WIDTH) &&
          (backbuf.y >= 0) && (backbuf.y <= PREVIEW_HEIGHT))
        {
          /* clip coordinates to preview widget sizes */
          if ((backbuf.x + backbuf.w) > PREVIEW_WIDTH)
            backbuf.w = (PREVIEW_WIDTH - backbuf.x);

          if ((backbuf.y + backbuf.h) > PREVIEW_HEIGHT)
            backbuf.h = (PREVIEW_HEIGHT - backbuf.y);

          backbuf.image = gdk_drawable_get_image (previewarea->window,
                                                  backbuf.x, backbuf.y,
                                                  backbuf.w, backbuf.h);
        }

      color.red   = 0x0;
      color.green = 0x0;
      color.blue  = 0x0;
      gdk_gc_set_rgb_bg_color (gc, &color);

      color.red   = 0x0;
      color.green = 0x4000;
      color.blue  = 0xFFFF;
      gdk_gc_set_rgb_fg_color (gc, &color);

      /* draw circle at light position */
      switch (mapvals.lightsource[k].type)
        {
        case POINT_LIGHT:
        case SPOT_LIGHT:
          gdk_draw_arc (previewarea->window, gc, TRUE,
                        handle_xpos - LIGHT_SYMBOL_SIZE / 2,
                        handle_ypos - LIGHT_SYMBOL_SIZE / 2,
                        LIGHT_SYMBOL_SIZE,
                        LIGHT_SYMBOL_SIZE, 0, 360 * 64);
          break;
        case DIRECTIONAL_LIGHT:
          gdk_draw_arc (previewarea->window, gc, TRUE,
                        handle_xpos - LIGHT_SYMBOL_SIZE / 2,
                        handle_ypos - LIGHT_SYMBOL_SIZE / 2,
                        LIGHT_SYMBOL_SIZE,
                        LIGHT_SYMBOL_SIZE, 0, 360 * 64);
          gdk_draw_line (previewarea->window, gc,
                         handle_xpos, handle_ypos, startx+pw/2 , starty + ph/2);
          break;
        case NO_LIGHT:
          break;
        }
    }
}
예제 #7
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;
}