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

📄 gdkwindow.c

📁 gtk是linux一款强大的夸平台的图形化开发工具
💻 C
📖 第 1 页 / 共 5 页
字号:
  while (tmp_list)    {      new_list = g_list_prepend (new_list, tmp_list->data);      tmp_list = tmp_list->next;    }    return new_list;}/*  * propagate the shapes from all child windows of a GDK window to the parent  * window. Shamelessly ripped from Enlightenment's code *  * - Raster */struct _gdk_span{  gint                start;  gint                end;  struct _gdk_span    *next;};static voidgdk_add_to_span (struct _gdk_span **s,		 gint               x,		 gint               xx){  struct _gdk_span *ptr1, *ptr2, *noo, *ss;  gchar             spanning;    ptr2 = NULL;  ptr1 = *s;  spanning = 0;  ss = NULL;  /* scan the spans for this line */  while (ptr1)    {      /* -- -> new span */      /* == -> existing span */      /* ## -> spans intersect */      /* if we are in the middle of spanning the span into the line */      if (spanning)	{	  /* case: ---- ==== */	  if (xx < ptr1->start - 1)	    {	      /* ends before next span - extend to here */	      ss->end = xx;	      return;	    }	  /* case: ----##=== */	  else if (xx <= ptr1->end)	    {	      /* crosses into next span - delete next span and append */	      ss->end = ptr1->end;	      ss->next = ptr1->next;	      g_free (ptr1);	      return;	    }	  /* case: ---###--- */	  else	    {	      /* overlaps next span - delete and keep checking */	      ss->next = ptr1->next;	      g_free (ptr1);	      ptr1 = ss;	    }	}      /* otherwise havent started spanning it in yet */      else	{	  /* case: ---- ==== */	  if (xx < ptr1->start - 1)	    {	      /* insert span here in list */	      noo = g_malloc (sizeof (struct _gdk_span));	      	      if (noo)		{		  noo->start = x;		  noo->end = xx;		  noo->next = ptr1;		  if (ptr2)		    ptr2->next = noo;		  else		    *s = noo;		}	      return;	    }	  /* case: ----##=== */	  else if ((x < ptr1->start) && (xx <= ptr1->end))	    {	      /* expand this span to the left point of the new one */	      ptr1->start = x;	      return;	    }	  /* case: ===###=== */	  else if ((x >= ptr1->start) && (xx <= ptr1->end))	    {	      /* throw the span away */	      return;	    }	  /* case: ---###--- */	  else if ((x < ptr1->start) && (xx > ptr1->end))	    {	      ss = ptr1;	      spanning = 1;	      ptr1->start = x;	      ptr1->end = xx;	    }	  /* case: ===##---- */	  else if ((x >= ptr1->start) && (x <= ptr1->end + 1) && (xx > ptr1->end))	    {	      ss = ptr1;	      spanning = 1;	      ptr1->end = xx;	    }	  /* case: ==== ---- */	  /* case handled by next loop iteration - first case */	}      ptr2 = ptr1;      ptr1 = ptr1->next;    }  /* it started in the middle but spans beyond your current list */  if (spanning)    {      ptr2->end = xx;      return;    }  /* it does not start inside a span or in the middle, so add it to the end */  noo = g_malloc (sizeof (struct _gdk_span));    if (noo)    {      noo->start = x;      noo->end = xx;      if (ptr2)	{	  noo->next = ptr2->next;	  ptr2->next = noo;	}      else	{	  noo->next = NULL;	  *s = noo;	}    }  return;}static voidgdk_add_rectangles (Display           *disp,		    Window             win,		    struct _gdk_span **spans,		    gint               basew,		    gint               baseh,		    gint               x,		    gint               y){  gint a, k;  gint x1, y1, x2, y2;  gint rn, ord;  XRectangle *rl;    rl = XShapeGetRectangles (disp, win, ShapeBounding, &rn, &ord);  if (rl)    {      /* go through all clip rects in this window's shape */      for (k = 0; k < rn; k++)	{	  /* for each clip rect, add it to each line's spans */	  x1 = x + rl[k].x;	  x2 = x + rl[k].x + (rl[k].width - 1);	  y1 = y + rl[k].y;	  y2 = y + rl[k].y + (rl[k].height - 1);	  if (x1 < 0)	    x1 = 0;	  if (y1 < 0)	    y1 = 0;	  if (x2 >= basew)	    x2 = basew - 1;	  if (y2 >= baseh)	    y2 = baseh - 1;	  for (a = y1; a <= y2; a++)	    {	      if ((x2 - x1) >= 0)		gdk_add_to_span (&spans[a], x1, x2);	    }	}      XFree (rl);    }}static voidgdk_propagate_shapes (Display *disp,		      Window   win,		      gboolean merge){  Window              rt, par, *list = NULL;  gint                i, j, num = 0, num_rects = 0;  gint                x, y, contig;  guint               w, h, d;  gint                baseh, basew;  XRectangle         *rects = NULL;  struct _gdk_span  **spans = NULL, *ptr1, *ptr2, *ptr3;  XWindowAttributes   xatt;    XGetGeometry (disp, win, &rt, &x, &y, &w, &h, &d, &d);  if (h <= 0)    return;  basew = w;  baseh = h;  spans = g_malloc (sizeof (struct _gdk_span *) * h);    for (i = 0; i < h; i++)    spans[i] = NULL;  XQueryTree (disp, win, &rt, &par, &list, (unsigned int *)&num);  if (list)    {      /* go through all child windows and create/insert spans */      for (i = 0; i < num; i++)	{	  if (XGetWindowAttributes (disp, list[i], &xatt) && (xatt.map_state != IsUnmapped))	    if (XGetGeometry (disp, list[i], &rt, &x, &y, &w, &h, &d, &d))	      gdk_add_rectangles (disp, list[i], spans, basew, baseh, x, y);	}      if (merge)	gdk_add_rectangles (disp, win, spans, basew, baseh, x, y);            /* go through the spans list and build a list of rects */      rects = g_malloc (sizeof (XRectangle) * 256);      num_rects = 0;      for (i = 0; i < baseh; i++)	{	  ptr1 = spans[i];	  /* go through the line for all spans */	  while (ptr1)	    {	      rects[num_rects].x = ptr1->start;	      rects[num_rects].y = i;	      rects[num_rects].width = ptr1->end - ptr1->start + 1;	      rects[num_rects].height = 1;	      j = i + 1;	      /* if there are more lines */	      contig = 1;	      /* while contigous rects (same start/end coords) exist */	      while ((contig) && (j < baseh))		{		  /* search next line for spans matching this one */		  contig = 0;		  ptr2 = spans[j];		  ptr3 = NULL;		  while (ptr2)		    {		      /* if we have an exact span match set contig */		      if ((ptr2->start == ptr1->start) &&			  (ptr2->end == ptr1->end))			{			  contig = 1;			  /* remove the span - not needed */			  if (ptr3)			    {			      ptr3->next = ptr2->next;			      g_free (ptr2);			      ptr2 = NULL;			    }			  else			    {			      spans[j] = ptr2->next;			      g_free (ptr2);			      ptr2 = NULL;			    }			  break;			}		      /* gone past the span point no point looking */		      else if (ptr2->start < ptr1->start)			break;		      if (ptr2)			{			  ptr3 = ptr2;			  ptr2 = ptr2->next;			}		    }		  /* if a contiguous span was found increase the rect h */		  if (contig)		    {		      rects[num_rects].height++;		      j++;		    }		}	      /* up the rect count */	      num_rects++;	      /* every 256 new rects increase the rect array */	      if ((num_rects % 256) == 0)		rects = g_realloc (rects, sizeof (XRectangle) * (num_rects + 256));	      ptr1 = ptr1->next;	    }	}      /* set the rects as the shape mask */      if (rects)	{	  XShapeCombineRectangles (disp, win, ShapeBounding, 0, 0, rects, num_rects,				   ShapeSet, YXSorted);	  g_free (rects);	}      XFree (list);    }  /* free up all the spans we made */  for (i = 0; i < baseh; i++)    {      ptr1 = spans[i];      while (ptr1)	{	  ptr2 = ptr1;	  ptr1 = ptr1->next;	  g_free (ptr2);	}    }  g_free (spans);}voidgdk_window_set_child_shapes (GdkWindow *window){  GdkWindowPrivate *private;    g_return_if_fail (window != NULL);  #ifdef HAVE_SHAPE_EXT  private = (GdkWindowPrivate*) window;  if (private->destroyed)    return;    if (gdk_window_have_shape_ext ())    gdk_propagate_shapes (private->xdisplay, private->xwindow, FALSE);#endif   }voidgdk_window_merge_child_shapes (GdkWindow *window){  GdkWindowPrivate *private;    g_return_if_fail (window != NULL);  #ifdef HAVE_SHAPE_EXT  private = (GdkWindowPrivate*) window;  if (private->destroyed)    return;    if (gdk_window_have_shape_ext ())    gdk_propagate_shapes (private->xdisplay, private->xwindow, TRUE);#endif   }/************************************************************* * gdk_window_is_visible: *     Check if the given window is mapped. *   arguments: *     window:  *   results: *     is the window mapped *************************************************************/gboolean gdk_window_is_visible (GdkWindow *window){  GdkWindowPrivate *private = (GdkWindowPrivate *)window;    g_return_val_if_fail (window != NULL, FALSE);    return private->mapped;}/************************************************************* * gdk_window_is_viewable: *     Check if the window and all ancestors of the window *     are mapped. (This is not necessarily "viewable" in *     the X sense, since we only check as far as we have *     GDK window parents, not to the root window) *   arguments: *     window: *   results: *     is the window viewable *************************************************************/gboolean gdk_window_is_viewable (GdkWindow *window){  GdkWindowPrivate *private = (GdkWindowPrivate *)window;    g_return_val_if_fail (window != NULL, FALSE);    while (private && 	 (private != &gdk_root_parent) &&	 (private->window_type != GDK_WINDOW_FOREIGN))    {      if (!private->mapped)	return FALSE;            private = (GdkWindowPrivate *)private->parent;    }    return TRUE;}void          gdk_drawable_set_data (GdkDrawable   *drawable,		       const gchar   *key,		       gpointer	      data,		       GDestroyNotify destroy_func){  g_dataset_set_data_full (drawable, key, data, destroy_func);}/* Support for windows that can be guffaw-scrolled * (See http://www.gtk.org/~otaylor/whitepapers/guffaw-scrolling.txt) */static gbooleangdk_window_gravity_works (void){  enum { UNKNOWN, NO, YES };  static gint gravity_works = UNKNOWN;    if (gravity_works == UNKNOWN)    {      GdkWindowAttr attr;      GdkWindow *parent;      GdkWindow *child;      gint y;            /* This particular server apparently has a bug so that the test       * works but the actual code crashes it       */      if ((!strcmp (XServerVendor (gdk_display), "Sun Microsystems, Inc.")) &&	  (VendorRelease (gdk_display) == 3400))	{	  gravity_works = NO;	  return FALSE;	}            attr.window_type = GDK_WINDOW_TEMP;      attr.wclass = GDK_INPUT_OUTPUT;      attr.x = 0;      attr.y = 0;      attr.width = 100;      attr.height = 100;      attr.event_mask = 0;            parent = gdk_window_new (NULL, &attr, GDK_WA_X | GDK_WA_Y);            attr.window_type = GDK_WINDOW_CHILD;      child = gdk_window_new (parent, &attr, GDK_WA_X | GDK_WA_Y);            gdk_window_set_static_win_gravity (child, TRUE);            gdk_window_resize (parent, 100, 110);      gdk_window_move (parent, 0, -10);      gdk_window_move_resize (parent, 0, 0, 100, 100);            gdk_window_resize (parent, 100, 110);      gdk_window_move (parent, 0, -10);      gdk_window_move_resize (parent, 0, 0, 100, 100);            gdk_window_get_geometry (child, NULL, &y, NULL, NULL, NULL);            gdk_window_destroy (parent);      gdk_window_destroy (child);            gravity_works = ((y == -20) ? YES : NO);    }    return (gravity_works == YES);}static voidgdk_window_set_static_bit_gravity (GdkWindow *window, gboolean on){  GdkWindowPrivate *private = (GdkWindowPrivate *)window;  XSetWindowAttributes xattributes;    g_return_if_fail (window != NULL);    xattributes.bit_gravity = on ? StaticGravity : ForgetGravity;  XChangeWindowAttributes (private->xdisplay,			   private->xwindow,			   CWBitGravity,  &xattributes);}static voidgdk_window_set_static_win_gravity (GdkWindow *window, gboolean on){  GdkWindowPrivate *private = (GdkWindowPrivate *)window;  XSetWindowAttributes xattributes;    g_return_if_fail (window != NULL);    xattributes.win_gravity = on ? StaticGravity : NorthWestGravity;    XChangeWindowAttributes (private->xdisplay,			   private->xwindow,			   CWWinGravity,  &xattributes);}/************************************************************* * gdk_window_set_static_gravities: *     Set the bit gravity of the given window to static, *     and flag it so all children get static subwindow *     gravity. *   arguments: *     window: window for which to set static gravity *     use_static: Whether to turn static gravity on or off. *   results: *     Does the XServer support static gravity? *************************************************************/gboolean gdk_window_set_static_gravities (GdkWindow *window,				 gboolean   use_static){  GdkWindowPrivate *private = (GdkWindowPrivate *)window;  GList *tmp_list;    g_return_val_if_fail (window != NULL, FALSE);    if (!use_static == !private->guffaw_gravity)    return TRUE;    if (use_static && !gdk_window_gravity_works ())    return FALSE;    private->guffaw_gravity = use_static;    gdk_window_set_static_bit_gravity (window, use_static);    tmp_list = private->children;  while (tmp_list)    {      gdk_window_set_static_win_gravity (window, use_static);            tmp_list = tmp_list->next;    }    return TRUE;}

⌨️ 快捷键说明

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