Пример #1
0
/* Subtracts one region from another. The result is a region containing
 * all the pixels which are in source1, but which are not in source2. */
int
clip_GDK_REGIONSUBTRACT(ClipMachine * ClipMachineMemory)
{
   C_object *creg = _fetch_co_arg(ClipMachineMemory);

   C_object *creg2 = _fetch_cobject(ClipMachineMemory, _clip_spar(ClipMachineMemory, 2));

   C_object *cdest;

   CHECKCOBJ(creg, GDK_IS_REGION(creg->object));
   CHECKARG2(2, MAP_type_of_ClipVarType, NUMERIC_type_of_ClipVarType);
   CHECKCOBJ(creg2, GDK_IS_REGION(creg->object));

   gdk_region_subtract(GDK_REGION(creg), GDK_REGION(creg2));

   if (creg)
    {
       cdest = _register_object(ClipMachineMemory, GDK_REGION(creg), GDK_TYPE_REGION, NULL, NULL);
       if (cdest)
	  _clip_mclone(ClipMachineMemory, RETPTR(ClipMachineMemory), &cdest->obj);
    }

   return 0;
 err:
   return 1;
}
Пример #2
0
void ChromeClient::scroll(const IntSize& delta, const IntRect& rectToScroll, const IntRect& clipRect)
{
    GdkWindow* window = GTK_WIDGET(m_webView)->window;
    if (!window)
        return;

    // We cannot use gdk_window_scroll here because it is only able to
    // scroll the whole window at once, and we often need to scroll
    // portions of the window only (think frames).
    GdkRectangle area = clipRect;
    GdkRectangle moveRect;

    GdkRectangle sourceRect = area;
    sourceRect.x -= delta.width();
    sourceRect.y -= delta.height();

    GdkRegion* invalidRegion = gdk_region_rectangle(&area);

    if (gdk_rectangle_intersect(&area, &sourceRect, &moveRect)) {
        GdkRegion* moveRegion = gdk_region_rectangle(&moveRect);
        gdk_window_move_region(window, moveRegion, delta.width(), delta.height());
        gdk_region_offset(moveRegion, delta.width(), delta.height());
        gdk_region_subtract(invalidRegion, moveRegion);
        gdk_region_destroy(moveRegion);
    }

    gdk_window_invalidate_region(window, invalidRegion, FALSE);
    gdk_region_destroy(invalidRegion);
}
Пример #3
0
void ChromeClient::scroll(const IntSize& delta, const IntRect& rectToScroll, const IntRect& clipRect)
{
    if (!m_webView)
        return;

    GdkWindow* window = GTK_WIDGET(m_webView)->window;
    if (!window)
        return;

    GdkRectangle area = clipRect;
    GdkRectangle moveRect;

    GdkRectangle sourceRect = area;
    sourceRect.x -= delta.width();
    sourceRect.y -= delta.height();

    GdkRegion* invalidRegion = gdk_region_rectangle(&area);

    if (gdk_rectangle_intersect(&area, &sourceRect, &moveRect)) {
        GdkRegion* moveRegion = gdk_region_rectangle(&moveRect);
        gdk_window_move_region(window, moveRegion, delta.width(), delta.height());
        gdk_region_offset(moveRegion, delta.width(), delta.height());
        gdk_region_subtract(invalidRegion, moveRegion);
        gdk_region_destroy(moveRegion);
    }

    gdk_window_invalidate_region(window, invalidRegion, FALSE);
    gdk_region_destroy(invalidRegion);
}
Пример #4
0
//__________________________________________________________________
void		_HYPlatformButton::_Paint (Ptr p)
{	
	_HYButton * theParent = (_HYButton*)this;

	GdkRectangle    	cRect = HYRect2GDKRect(*(_HYRect*)p);
	
	if (!(theParent->settings.width&HY_COMPONENT_TRANSP_BG))
	{
		if (theParent->parentWindow->window)
		{
			GdkGC *buttonGC				 = gdk_gc_new (theParent->parentWindow->window);
			gdk_gc_set_foreground(buttonGC,&bgColor);
			GdkRegion * r1 = gdk_region_rectangle(&cRect), 
					  * r2 = gdk_region_rectangle (&buttonRect);

			gdk_region_subtract	   (r1,r2);
			gdk_region_offset	   (r1,theParent->parentWindow->allocation.x,theParent->parentWindow->allocation.y);
			gdk_gc_set_clip_region (buttonGC,r1);
			gdk_draw_rectangle(theParent->parentWindow->window,buttonGC,true,cRect.x+theParent->parentWindow->allocation.x, 
							   cRect.y+theParent->parentWindow->allocation.y, cRect.width, cRect.height);
			gdk_region_destroy(r1);
			gdk_region_destroy(r2);
			g_object_unref (buttonGC);
		}
	}
		
  	(*theParent)._HYPlatformComponent::_Paint(p);
}
Пример #5
0
bool wxRegion::DoSubtract( const wxRegion& region )
{
    if (region.m_refData == NULL || m_refData == NULL)
        return false;

    AllocExclusive();

#ifdef __WXGTK3__
    cairo_region_subtract(M_REGIONDATA->m_region, M_REGIONDATA_OF(region)->m_region);
#else
    gdk_region_subtract( M_REGIONDATA->m_region, region.GetRegion() );
#endif

    return true;
}
Пример #6
0
bool wxRegion::DoSubtract( const wxRegion& region )
{
    wxCHECK_MSG( region.Ok(), false, _T("invalid region") );

    if (!m_refData)
    {
        // subtracting from an invalid region doesn't make sense
        return false;
    }

    AllocExclusive();

    gdk_region_subtract( M_REGIONDATA->m_region, region.GetRegion() );

    return true;
}
void ChromeClient::scroll(const IntSize& delta, const IntRect& rectToScroll, const IntRect& clipRect)
{
    GdkWindow* window = gtk_widget_get_window(GTK_WIDGET(m_webView));
    if (!window)
        return;

    m_pendingScrollInvalidations = true;

    // We cannot use gdk_window_scroll here because it is only able to
    // scroll the whole window at once, and we often need to scroll
    // portions of the window only (think frames).
    GdkRectangle area = clipRect;
    GdkRectangle moveRect;

    GdkRectangle sourceRect = area;
    sourceRect.x -= delta.width();
    sourceRect.y -= delta.height();

#ifdef GTK_API_VERSION_2
    GdkRegion* invalidRegion = gdk_region_rectangle(&area);

    if (gdk_rectangle_intersect(&area, &sourceRect, &moveRect)) {
        GdkRegion* moveRegion = gdk_region_rectangle(&moveRect);
        gdk_window_move_region(window, moveRegion, delta.width(), delta.height());
        gdk_region_offset(moveRegion, delta.width(), delta.height());
        gdk_region_subtract(invalidRegion, moveRegion);
        gdk_region_destroy(moveRegion);
    }

    gdk_window_invalidate_region(window, invalidRegion, FALSE);
    gdk_region_destroy(invalidRegion);
#else
    cairo_region_t* invalidRegion = cairo_region_create_rectangle(&area);

    if (gdk_rectangle_intersect(&area, &sourceRect, &moveRect)) {
        cairo_region_t* moveRegion = cairo_region_create_rectangle(&moveRect);
        gdk_window_move_region(window, moveRegion, delta.width(), delta.height());
        cairo_region_translate(moveRegion, delta.width(), delta.height());
        cairo_region_subtract(invalidRegion, moveRegion);
        cairo_region_destroy(moveRegion);
    }

    gdk_window_invalidate_region(window, invalidRegion, FALSE);
    cairo_region_destroy(invalidRegion);
#endif
}
Пример #8
0
Файл: cdgdk.c Проект: LuaDist/cd
static void sCombineRegion(cdCtxCanvas *ctxcanvas, GdkRegion* rgn)
{
  switch(ctxcanvas->canvas->combine_mode)
  {                          
  case CD_UNION:
    gdk_region_union(ctxcanvas->new_rgn, rgn);
    break;
  case CD_INTERSECT:   
    gdk_region_intersect(ctxcanvas->new_rgn, rgn);
    break;
  case CD_DIFFERENCE:           
    gdk_region_subtract(ctxcanvas->new_rgn, rgn);
    break;
  case CD_NOTINTERSECT:
    gdk_region_xor(ctxcanvas->new_rgn, rgn);
    break;
  }

  gdk_region_destroy(rgn);
}
Пример #9
0
static GdkRegion *
gdk_window_clip_changed (GdkWindow    *window,
			 GdkRectangle *old_clip,
			 GdkRectangle *new_clip)
{
  GdkWindowImplWin32 *impl;
  GdkWindowObject *obj;
  GdkRegion *old_clip_region;
  GdkRegion *new_clip_region;
  
  if (((GdkWindowObject *)window)->input_only)
    return NULL;

  obj = (GdkWindowObject *) window;
  impl = GDK_WINDOW_IMPL_WIN32 (obj->impl);
  
  old_clip_region = gdk_region_rectangle (old_clip);
  new_clip_region = gdk_region_rectangle (new_clip);

  /* Trim invalid region of window to new clip rectangle
   */
  if (obj->update_area)
    gdk_region_intersect (obj->update_area, new_clip_region);

  /* Invalidate newly exposed portion of window
   */
  gdk_region_subtract (new_clip_region, old_clip_region);
  if (!gdk_region_empty (new_clip_region))
    gdk_window_tmp_unset_bg (window);
  else
    {
      gdk_region_destroy (new_clip_region);
      new_clip_region = NULL;
    }
  gdk_region_destroy (old_clip_region);

  return new_clip_region;
}
Пример #10
0
static VALUE
rg_subtract(VALUE self, VALUE region)
{
    gdk_region_subtract(_SELF(self), _SELF(region));
    return self;
}
Пример #11
0
void
gdk_window_move_region (GdkWindow *window,
			GdkRegion *region,
			gint       dx,
			gint       dy)
{
  GdkRegion *invalidate_region;
  GdkWindowImplWin32 *impl;
  GdkWindowObject *obj;
  GdkRectangle src_rect, dest_rect;
  HRGN hrgn;
  RECT clipRect, destRect;

  g_return_if_fail (GDK_IS_WINDOW (window));

  if (GDK_WINDOW_DESTROYED (window))
    return;
  
  obj = GDK_WINDOW_OBJECT (window);
  impl = GDK_WINDOW_IMPL_WIN32 (obj->impl);  

  if (dx == 0 && dy == 0)
    return;
  
  /* Move the current invalid region */
  if (obj->update_area)
    gdk_region_offset (obj->update_area, dx, dy);
  
  /* impl->position_info.clip_rect isn't meaningful for toplevels */
  if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_CHILD)
    src_rect = impl->position_info.clip_rect;
  else
    {
      src_rect.x = 0;
      src_rect.y = 0;
      src_rect.width = impl->width;
      src_rect.height = impl->height;
    }
  
  invalidate_region = gdk_region_rectangle (&src_rect);

  dest_rect = src_rect;
  dest_rect.x += dx;
  dest_rect.y += dy;
  gdk_rectangle_intersect (&dest_rect, &src_rect, &dest_rect);

  if (dest_rect.width > 0 && dest_rect.height > 0)
    {
      GdkRegion *tmp_region;

      tmp_region = gdk_region_rectangle (&dest_rect);
      gdk_region_subtract (invalidate_region, tmp_region);
      gdk_region_destroy (tmp_region);
    }
  
  /* no guffaw scroll on win32 */
  hrgn = _gdk_win32_gdkregion_to_hrgn(invalidate_region, 0, 0);
  gdk_region_destroy (invalidate_region);
  destRect.left = dest_rect.y;
  destRect.top = dest_rect.x;
  destRect.right = dest_rect.x + dest_rect.width;
  destRect.bottom = dest_rect.y + dest_rect.height;
  clipRect.left = src_rect.y;
  clipRect.top = src_rect.x;
  clipRect.right = src_rect.x + src_rect.width;
  clipRect.bottom = src_rect.y + src_rect.height;

  g_print ("ScrollWindowEx(%d, %d, ...) - if you see this work, remove trace;)\n", dx, dy);
  API_CALL(ScrollWindowEx, (GDK_WINDOW_HWND (window),
                       dx, dy, /* in: scroll offsets */
                       NULL, /* in: scroll rect, NULL == entire client area */
                       &clipRect, /* in: restrict to */
                       hrgn, /* in: update region */
                       NULL, /* out: update rect */
                       SW_INVALIDATE));
  API_CALL(DeleteObject, (hrgn));
}
Пример #12
0
void FloatingWindow::display(bool startup)
// Does the bookkeeping necessary for displaying the floating box.
// startup: whether the box is started at program startup.
{
  // Settings.
  extern Settings *settings;

  // The parameters of all the windows.
  WindowData window_parameters(false);

  // Clear the new window's position.
  my_gdk_rectangle.x = 0;
  my_gdk_rectangle.y = 0;
  my_gdk_rectangle.width = 0;
  my_gdk_rectangle.height = 0;

  // At program startup extract the position and size of the window from the general configuration.
  // It does not matter whether the space for the window is already taken up by another window,
  // because the user wishes to use the coordinates that he has set for this window.
  for (unsigned int i = 0; i < window_parameters.widths.size(); i++) {
    if ((window_parameters.ids[i] == window_id) && (window_parameters.titles[i] == title) && startup) {
      my_gdk_rectangle.x = window_parameters.x_positions[i];
      my_gdk_rectangle.y = window_parameters.y_positions[i];
      my_gdk_rectangle.width = window_parameters.widths[i];
      my_gdk_rectangle.height = window_parameters.heights[i];
    }
  }

  // Reject zero width and zero height values on startup.
  if ((my_gdk_rectangle.width == 0) || (my_gdk_rectangle.height == 0))
    startup = false;

  // When a new window needs to be allocated, there are a few steps to be taken.
  if (!startup) {

    // Step 1: The area rectangle where the window should fit in is defined. 
    GdkRectangle area_rectangle;
    area_rectangle.x = 0;
    area_rectangle.y = 0;
    area_rectangle.width = 0;
    area_rectangle.height = 0;
    {
      guint width, height;
      gtk_layout_get_size (GTK_LAYOUT (layout), &width, &height);
      area_rectangle.width = width;
      area_rectangle.height = height;
    }

    // Step 2: An available region is made of that whole area.
    GdkRegion *available_region = gdk_region_rectangle(&area_rectangle);

    // Step 3: The regions of each of the open windows is substracted from the available region.
    for (unsigned int i = 0; i < settings->session.open_floating_windows.size(); i++) {
      FloatingWindow * floating_window = (FloatingWindow *) settings->session.open_floating_windows[i];
      GdkRectangle rectangle = floating_window->rectangle_get();
      GdkRegion *region = gdk_region_rectangle(&rectangle);
      gdk_region_subtract(available_region, region);
      gdk_region_destroy(region);
    }

    // Step 4: The rectangles that the area region consists of are requested,
    // and the biggest suitable rectangle is chosen for the window.
    // A rectangle is considered suitable if it has at least 10% of the width, and 10% of the height of the area rectangle.
    GdkRectangle *gdk_rectangles = NULL;
    gint rectangle_count = 0;
    gdk_region_get_rectangles(available_region, &gdk_rectangles, &rectangle_count);
    for (int i = 0; i < rectangle_count; ++i) {
      GdkRectangle & rectangle = gdk_rectangles[i];
      if (rectangle.width >= (area_rectangle.width / 10)) {
        if (rectangle.height >= (area_rectangle.height / 10)) {
          if ((rectangle.width * rectangle.height) > (my_gdk_rectangle.width * my_gdk_rectangle.height)) {
            my_gdk_rectangle = rectangle;
          }
        }
      }
    }
    g_free(gdk_rectangles);

    // Step 5: The available region is destroyed.
    gdk_region_destroy(available_region);

    // Step 6: If no area big enough is found, then the window that takes most space in the area is chosen, 
    // the longest side is halved, and the new window is put in that freed area.
    if ((my_gdk_rectangle.width == 0) || (my_gdk_rectangle.height == 0)) {
      FloatingWindow * resize_window_pointer = NULL;
      int largest_size = 0;
      for (unsigned int i = 0; i < settings->session.open_floating_windows.size(); i++) {
        FloatingWindow *floating_window = (FloatingWindow *) settings->session.open_floating_windows[i];
        GdkRectangle rectangle = floating_window->rectangle_get ();
        int size = rectangle.width * rectangle.height;
        if (size > largest_size) {
          resize_window_pointer = floating_window;
          largest_size = size;
        }
      }
      if (resize_window_pointer) {
        GdkRectangle resize_window_rectangle = resize_window_pointer->rectangle_get();
        my_gdk_rectangle = resize_window_pointer->rectangle_get();
        if (resize_window_rectangle.width > resize_window_rectangle.height) {
          resize_window_rectangle.width /= 2;
          my_gdk_rectangle.width /= 2;
          my_gdk_rectangle.x += resize_window_rectangle.width;
        } else {
          resize_window_rectangle.height /= 2;
          my_gdk_rectangle.height /= 2;
          my_gdk_rectangle.y += resize_window_rectangle.height;
        }
        resize_window_pointer->rectangle_set (resize_window_rectangle);
      }
    }
  }
  // Add the window to the layout and set its position and size.
  gtk_layout_put (GTK_LAYOUT (layout), vbox_window, my_gdk_rectangle.x, my_gdk_rectangle.y);
  rectangle_set (my_gdk_rectangle);
  // Store a pointer to this window in the Session.
  settings->session.open_floating_windows.push_back(gpointer (this));
}
Пример #13
0
static void
display_entry (MetaTabPopup *popup,
               TabEntry     *te)
{
  GdkRectangle rect;
  GdkRegion *region;
  GdkRegion *inner_region;
  GdkWindow *window;


  if (popup->current_selected_entry)
  {
    if (popup->outline)
      unselect_image (popup->current_selected_entry->widget);
    else
      unselect_workspace (popup->current_selected_entry->widget);
  }

  gtk_label_set_markup (GTK_LABEL (popup->label), te->title);

  if (popup->outline)
    select_image (te->widget);
  else
    select_workspace (te->widget);

  if (popup->outline)
    {
      /* Do stuff behind gtk's back */
      gdk_window_hide (gtk_widget_get_window(popup->outline_window));
      meta_core_increment_event_serial (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()));

      rect = te->rect;
      rect.x = 0;
      rect.y = 0;

      window = gtk_widget_get_window(GTK_WIDGET(popup->outline_window));

      gdk_window_move_resize (window,
                              te->rect.x, te->rect.y,
                              te->rect.width, te->rect.height);

      #if GTK_CHECK_VERSION(3, 0, 0)
      GdkRGBA black = { 0.0, 0.0, 0.0, 1.0 };
      gdk_window_set_background_rgba (window, &black);
      #else
      gdk_window_set_background (window,
                                 &popup->outline_window->style->black);
      #endif

      region = gdk_region_rectangle (&rect);
      inner_region = gdk_region_rectangle (&te->inner_rect);
      gdk_region_subtract (region, inner_region);
      gdk_region_destroy (inner_region);

      gdk_window_shape_combine_region (window,
                                       region,
                                       0, 0);

      gdk_region_destroy (region);

      /* This should piss off gtk a bit, but we don't want to raise
       * above the tab popup.  So, instead of calling gtk_widget_show,
       * we manually set the window as mapped and then manually map it
       * with gdk functions.
       */
      #if GTK_CHECK_VERSION(3, 0, 0)
      gtk_widget_set_mapped (popup->outline_window, TRUE);
      #else
      GTK_WIDGET_SET_FLAGS (popup->outline_window, GTK_MAPPED);
      #endif
      gdk_window_show_unraised (window);
    }

  /* Must be before we handle an expose for the outline window */
  popup->current_selected_entry = te;
}
Пример #14
0
/* Doesn't handle HIPPO_WINDOW_STATE_ACTIVE - see comment below */
static HippoWindowState
get_window_state(Display *display, Window window)
{
    HippoWindowState result =  HIPPO_WINDOW_STATE_HIDDEN;
    XWindowAttributes window_attributes;
    GdkRectangle rect;
    GdkRegion *visible_region = NULL;
    Window child = None;
    
    Window root;
    Window parent;
    Window *children = NULL;
    guint n_children;

    gdk_error_trap_push();
    
    /* First check if the window and all ancestors are mapped
     */

    if (!XGetWindowAttributes(display, window, &window_attributes)) {
        g_debug("XGetWindowAttributes failed\n");
        goto out;
    }

    if (window_attributes.map_state != IsViewable)
        goto out;

    /* Get the area of the window in parent coordinates
     */
    rect.x = window_attributes.x;
    rect.y = window_attributes.y;
    rect.width = window_attributes.width;
    rect.height = window_attributes.height;

    visible_region = gdk_region_rectangle(&rect);

    if (!XQueryTree(display, window, &root, &parent, &children, &n_children)) {
        g_debug("XQueryTree failed\n");
        goto out;
    }

    XFree(children);
    children = NULL;

    child = window;
    window = parent;

    /* Walk up the hierarchy, clipping to parents, and subtracting
     * overlayed siblings (yuck!)
     */
    while (TRUE) {
        GdkRegion *parent_region;
        gboolean seen_child = FALSE;
        int x, y;
        unsigned int width, height, border, depth;
        unsigned int i;

        gdk_region_get_clipbox(visible_region, &rect);
        
        /* Clip to parent */
        if (!XGetGeometry(display, window, &root, &x, &y, &width, &height, &border, &depth)) {
            g_debug("XGetGeometry failed\n");
            goto out;
        }

        rect.x = 0;
        rect.y = 0;
        rect.width = width;
        rect.height= height;

        parent_region = gdk_region_rectangle(&rect);
        gdk_region_intersect(visible_region, parent_region);
        gdk_region_destroy(parent_region);

        if (gdk_region_empty(visible_region))
            goto out;
                
        if (!XQueryTree(display, window, &root, &parent, &children, &n_children)) {
            g_debug("XQueryTree failed\n");
            goto out;
        }

        for (i = 0; i < n_children; i++) {
            if (seen_child) {
                /* A sibling above */
                GdkRegion *child_region;
                XWindowAttributes child_attributes;
                
                if (!XGetWindowAttributes(display, children[i], &child_attributes)) {
                    g_debug("XGetWindowAttributes failed for child\n");
                    goto out;
                }

                if (child_attributes.map_state == IsViewable) {
                    rect.x = child_attributes.x - child_attributes.border_width;
                    rect.y = child_attributes.y - child_attributes.border_width;
                    rect.width = child_attributes.width + 2 * child_attributes.border_width;
                    rect.height = child_attributes.height + 2 * child_attributes.border_width;

                    child_region = gdk_region_rectangle(&rect);
                    gdk_region_subtract(visible_region, child_region);
                    gdk_region_destroy(child_region);
                    
                    if (gdk_region_empty(visible_region))
                        goto out;
                }
                
            } else if (children[i] == child) {
                seen_child = TRUE;
            }
        }
    
        XFree(children);
        children = NULL;

        if (window == root)
            break;
        
        child = window;
        window = parent;

        /* Translate to parent coordinates */
        gdk_region_offset(visible_region, x, y);
    }

    if (!gdk_region_empty(visible_region))
        result = HIPPO_WINDOW_STATE_ONSCREEN;

 out:
    gdk_error_trap_pop();

    if (children)
        XFree(children);

    if (visible_region)
        gdk_region_destroy(visible_region);

    return result;
}