/* 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; }
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); }
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); }
//__________________________________________________________________ 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); }
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; }
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 }
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); }
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; }
static VALUE rg_subtract(VALUE self, VALUE region) { gdk_region_subtract(_SELF(self), _SELF(region)); return self; }
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)); }
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)); }
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; }
/* 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; }