⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gdkgeometry-x11.c

📁 linux下电话本所依赖的一些图形库
💻 C
📖 第 1 页 / 共 3 页
字号:
/* GDK - The GIMP Drawing Kit * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. *//* gdkgeometry-x11.c: emulation of 32 bit coordinates within the * limits of X.  * * By Owen Taylor <otaylor@redhat.com> * Copyright Red Hat, Inc. 2000 * * The algorithms implemented in this file are an extension of the * idea of guffaw scrolling, a technique (and name) taken from the classic * Netscape source code. The basic idea of guffaw scrolling is a trick * to get around a limitation of X: there is no way of scrolling the * contents of a window. Guffaw scrolling exploits the X concepts of * window gravity and bit gravity: * *  window gravity: the window gravity of a window affects what happens *   to a windows position when _its parent_ is resized, or *   moved and resized simultaneously. * *  bit gravity: the bit gravity of a window affects what happens to *  the pixels of a window when _it_ is is resized, or moved and *  resized simultaneously. * * These were basically intended to do things like have right * justified widgets in a window automatically stay right justified * when the window was resized, but there is also the special * "StaticGravity" which means "do nothing." We can exploit * StaticGravity to scroll a window: * *     |  VISIBLE  | *  *     |abcdefghijk| *     |abcdefghijk    |   (1) Resize bigger * |    efghijk    |       (2) Move   *     |efghijk    |       (3) Move-resize back to the original size * * Or, going the other way: *     |abcdefghijk| * |    abcdefghijk|       (1) Move-resize bigger *     |    abcdefghijk|   (2) Move   *     |    abcdefg|       (4) Resize back to the original size * * By using this technique, we can simulate scrolling around in a * large virtual space without having to actually have windows that * big; for the pixels of the window, this is all we have to do.  For * subwindows, we have to take care of one other detail - since * coordinates in X are limited to 16 bits, subwindows scrolled off * will wrap around and come back eventually. So, we have to take care * to unmap windows that go outside the 16-bit range and remap them as * they come back in. * * Since we are temporarily making the window bigger, this only looks * good if the edges of the window are obscured. Typically, we do * this by making the window we are scrolling the immediate child * of a "clip window". * * But, this isn't a perfect API for applications for several reasons: * *  - We have to use this inefficient technique even for small windows *    if the window _could_ be big. *  - Applications have to use a special scrolling API. * * What we'd like is to simply have windows with 32 bit coordinates * so applications could scroll in the classic way - just move a big * window around. * * It turns out that StaticGravity can also be used to achieve emulation * of 32 bit coordinates with only 16 bit coordinates if we expand * our horizons just a bit; what guffaw scrolling really is is a way * to move the contents of a window a different amount than we move * the borders of of the window. In the above example pictures we * ended up with the borders of the window not moving at all, but * that isn't necessary. * * So, what we do is set up a mapping from virtual 32 bit window position/size * to: * *  - Real window position/size *  - Offset between virtual coordinates and real coordinates for the window *  - Map state (mapped or unmapped) * * By the following rules: * *  - If the window is less than 32767 pixels in width (resp. height), we use it's *    virtual width and position. *  - Otherwise, we use a width of 32767 and determine the position of the window *    so that the portion of the real window [16384, 16383] in _toplevel window *    coordinates_ is the same as the portion of the real window  * * This is implemented in gdk_window_compute_position(). Then the algorithm * for a moving a window (_window_move_resize_child ()) is: *  *  - Compute the new window mappings for the window and all subwindows *  - Expand out the boundary of the window and all subwindows by the amount *    that the real/virtual offset changes for each window.  *    (compute_intermediate_position() computes expanded boundary) *  - Move the toplevel by the amount that it's contents need to translate. *  - Move/resize the window and all subwindows to the newly computed *    positions. * * If we just are scrolling (gdk_window_guffaw_scroll()), then things * are similar, except that the final mappings for the toplevel are * the same as the initial mappings, but we act as if it moved by the * amount we are scrolling by. * * Note that we don't have to worry about a clip window in * _gdk_window_move_resize() since we have set up our translation so * that things in the range [16384,16383] in toplevel window * coordinates look exactly as they would if we were simply moving the * windows, and nothing outside this range is going to be visible * unless the user has a _really_ huge screen. */#include <config.h>#include "gdk.h"		/* For gdk_rectangle_intersect */#include "gdkprivate-x11.h"#include "gdkx.h"#include "gdkregion.h"#include "gdkinternals.h"#include "gdkscreen-x11.h"#include "gdkdisplay-x11.h"#include "gdkwindow-x11.h"#include "gdkalias.h"typedef struct _GdkWindowQueueItem GdkWindowQueueItem;typedef struct _GdkWindowParentPos GdkWindowParentPos;typedef enum {  GDK_WINDOW_QUEUE_TRANSLATE,  GDK_WINDOW_QUEUE_ANTIEXPOSE} GdkWindowQueueType;struct _GdkWindowQueueItem{  GdkWindow *window;  gulong serial;  GdkWindowQueueType type;  union {    struct {      gint dx;      gint dy;    } translate;    struct {      GdkRegion *area;    } antiexpose;  } u;};struct _GdkWindowParentPos{  gint x;  gint y;  gint x11_x;  gint x11_y;  GdkRectangle clip_rect;};static void gdk_window_compute_position   (GdkWindowImplX11      *window,					   GdkWindowParentPos *parent_pos,					   GdkXPositionInfo   *info);static void gdk_window_compute_parent_pos (GdkWindowImplX11      *window,					   GdkWindowParentPos *parent_pos);static void gdk_window_premove            (GdkWindow          *window,					   GdkWindowParentPos *parent_pos);static void gdk_window_postmove           (GdkWindow          *window,					   GdkWindowParentPos *parent_pos);static void gdk_window_queue_translation  (GdkWindow          *window,					   gint                dx,					   gint                dy);static void gdk_window_clip_changed       (GdkWindow          *window,					   GdkRectangle       *old_clip,					   GdkRectangle       *new_clip);void_gdk_windowing_window_get_offsets (GdkWindow *window,				   gint      *x_offset,				   gint      *y_offset){  GdkWindowImplX11 *impl =    GDK_WINDOW_IMPL_X11 (GDK_WINDOW_OBJECT (window)->impl);  *x_offset = impl->position_info.x_offset;  *y_offset = impl->position_info.y_offset;}void_gdk_window_init_position (GdkWindow *window){  GdkWindowParentPos parent_pos;  GdkWindowImplX11 *impl;    g_return_if_fail (GDK_IS_WINDOW (window));    impl =    GDK_WINDOW_IMPL_X11 (GDK_WINDOW_OBJECT (window)->impl);    gdk_window_compute_parent_pos (impl, &parent_pos);  gdk_window_compute_position (impl, &parent_pos, &impl->position_info);}static voidgdk_window_copy_area_scroll (GdkWindow    *window,			     GdkRectangle *dest_rect,			     gint          dx,			     gint          dy){  GdkWindowObject *obj = GDK_WINDOW_OBJECT (window);  GList *tmp_list;  if (dest_rect->width > 0 && dest_rect->height > 0)    {      GdkGC *gc;      gc = _gdk_drawable_get_scratch_gc (window, TRUE);            gdk_window_queue_translation (window, dx, dy);      XCopyArea (GDK_WINDOW_XDISPLAY (window),		 GDK_WINDOW_XID (window),		 GDK_WINDOW_XID (window),		 gdk_x11_gc_get_xgc (gc),		 dest_rect->x - dx, dest_rect->y - dy,		 dest_rect->width, dest_rect->height,		 dest_rect->x, dest_rect->y);    }  tmp_list = obj->children;  while (tmp_list)    {      GdkWindow *child = GDK_WINDOW (tmp_list->data);      GdkWindowObject *child_obj = GDK_WINDOW_OBJECT (child);	        gdk_window_move (child, child_obj->x + dx, child_obj->y + dy);            tmp_list = tmp_list->next;    }}static voidcompute_intermediate_position (GdkXPositionInfo *position_info,			       GdkXPositionInfo *new_info,			       gint              d_xoffset,			       gint              d_yoffset,			       GdkRectangle     *new_position){  gint new_x0, new_x1, new_y0, new_y1;    /* Wrap d_xoffset, d_yoffset into [-32768,32767] range. For the   * purposes of subwindow movement, it doesn't matter if we are   * off by a factor of 65536, and if we don't do this range   * reduction, we'll end up with invalid widths.   */  d_xoffset = (gint16)d_xoffset;  d_yoffset = (gint16)d_yoffset;    if (d_xoffset < 0)    {      new_x0 = position_info->x + d_xoffset;      new_x1 = position_info->x + position_info->width;    }  else    {      new_x0 = position_info->x;      new_x1 = position_info->x + new_info->width + d_xoffset;    }  new_position->x = new_x0;  new_position->width = new_x1 - new_x0;    if (d_yoffset < 0)    {      new_y0 = position_info->y + d_yoffset;      new_y1 = position_info->y + position_info->height;    }  else    {      new_y0 = position_info->y;      new_y1 = position_info->y + new_info->height + d_yoffset;    }    new_position->y = new_y0;  new_position->height = new_y1 - new_y0;}static voidgdk_window_guffaw_scroll (GdkWindow    *window,			  gint          dx,			  gint          dy){  GdkWindowObject *obj = GDK_WINDOW_OBJECT (window);  GdkWindowImplX11 *impl = GDK_WINDOW_IMPL_X11 (obj->impl);  gint d_xoffset = -dx;  gint d_yoffset = -dy;  GdkRectangle new_position;  GdkXPositionInfo new_info;  GdkWindowParentPos parent_pos;  GList *tmp_list;    gdk_window_compute_parent_pos (impl, &parent_pos);  gdk_window_compute_position (impl, &parent_pos, &new_info);  parent_pos.x += obj->x;  parent_pos.y += obj->y;  parent_pos.x11_x += new_info.x;  parent_pos.x11_y += new_info.y;  parent_pos.clip_rect = new_info.clip_rect;  _gdk_x11_window_tmp_unset_bg (window, FALSE);;  if (dx > 0 || dy > 0)    gdk_window_queue_translation (window, MAX (dx, 0), MAX (dy, 0));	  gdk_window_set_static_gravities (window, TRUE);  compute_intermediate_position (&impl->position_info, &new_info, d_xoffset, d_yoffset,				 &new_position);    XMoveResizeWindow (GDK_WINDOW_XDISPLAY (window),		     GDK_WINDOW_XID (window),		     new_position.x, new_position.y, new_position.width, new_position.height);    tmp_list = obj->children;  while (tmp_list)    {      GDK_WINDOW_OBJECT(tmp_list->data)->x -= d_xoffset;      GDK_WINDOW_OBJECT(tmp_list->data)->y -= d_yoffset;      gdk_window_premove (tmp_list->data, &parent_pos);      tmp_list = tmp_list->next;    }    XMoveWindow (GDK_WINDOW_XDISPLAY (window),	       GDK_WINDOW_XID (window),	       new_position.x - d_xoffset, new_position.y - d_yoffset);    if (dx < 0 || dy < 0)    gdk_window_queue_translation (window, MIN (dx, 0), MIN (dy, 0));    XMoveResizeWindow (GDK_WINDOW_XDISPLAY (window),		     GDK_WINDOW_XID (window),		     impl->position_info.x, impl->position_info.y,		     impl->position_info.width, impl->position_info.height);    if (impl->position_info.no_bg)    _gdk_x11_window_tmp_reset_bg (window, FALSE);    impl->position_info = new_info;    tmp_list = obj->children;  while (tmp_list)    {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -