📄 gdkwindow.c
字号:
/* 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 Library 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 * Library General Public License for more details. * * You should have received a copy of the GNU Library 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. *//* * Modified by the GTK+ Team and others 1997-1999. See the AUTHORS * file for a list of people on the GTK+ Team. See the ChangeLog * files for a list of changes. These files are distributed with * GTK+ at ftp://ftp.gtk.org/pub/gtk/. */#include <X11/Xlib.h>#include <X11/Xutil.h>#include <X11/Xatom.h>#include <netinet/in.h>#include "gdk.h"#include "config.h"#include "gdkinput.h"#include "gdkprivate.h"#include "MwmUtil.h"#include <stdlib.h>#include <stdio.h>#include <string.h>#ifdef HAVE_SHAPE_EXT#include <X11/extensions/shape.h>#endifconst int gdk_event_mask_table[20] ={ ExposureMask, PointerMotionMask, PointerMotionHintMask, ButtonMotionMask, Button1MotionMask, Button2MotionMask, Button3MotionMask, ButtonPressMask | OwnerGrabButtonMask, ButtonReleaseMask | OwnerGrabButtonMask, KeyPressMask, KeyReleaseMask, EnterWindowMask, LeaveWindowMask, FocusChangeMask, StructureNotifyMask, PropertyChangeMask, VisibilityChangeMask, 0, /* PROXIMITY_IN */ 0, /* PROXIMTY_OUT */ SubstructureNotifyMask};const int gdk_nevent_masks = sizeof (gdk_event_mask_table) / sizeof (int);/* Forward declarations */static gboolean gdk_window_gravity_works (void);static void gdk_window_set_static_win_gravity (GdkWindow *window, gboolean on);static gboolean gdk_window_have_shape_ext (void);/* internal function created for and used by gdk_window_xid_at_coords */Windowgdk_window_xid_at (Window base, gint bx, gint by, gint x, gint y, GList *excludes, gboolean excl_child){ GdkWindow *window; GdkWindowPrivate *private; Display *disp; Window *list = NULL; Window child = 0, parent_win = 0, root_win = 0; int i; unsigned int ww, wh, wb, wd, num; int wx, wy; window = (GdkWindow*) &gdk_root_parent; private = (GdkWindowPrivate*) window; disp = private->xdisplay; if (!XGetGeometry (disp, base, &root_win, &wx, &wy, &ww, &wh, &wb, &wd)) return 0; wx += bx; wy += by; if (!((x >= wx) && (y >= wy) && (x < (int) (wx + ww)) && (y < (int) (wy + wh)))) return 0; if (!XQueryTree (disp, base, &root_win, &parent_win, &list, &num)) return base; if (list) { for (i = num - 1; ; i--) { if ((!excl_child) || (!g_list_find (excludes, (gpointer *) list[i]))) { if ((child = gdk_window_xid_at (list[i], wx, wy, x, y, excludes, excl_child)) != 0) { XFree (list); return child; } } if (!i) break; } XFree (list); } return base;}/* * The following fucntion by The Rasterman <raster@redhat.com> * This function returns the X Window ID in which the x y location is in * (x and y being relative to the root window), excluding any windows listed * in the GList excludes (this is a list of X Window ID's - gpointer being * the Window ID). * * This is primarily designed for internal gdk use - for DND for example * when using a shaped icon window as the drag object - you exclude the * X Window ID of the "icon" (perhaps more if excludes may be needed) and * You can get back an X Window ID as to what X Window ID is infact under * those X,Y co-ordinates. */Windowgdk_window_xid_at_coords (gint x, gint y, GList *excludes, gboolean excl_child){ GdkWindow *window; GdkWindowPrivate *private; Display *disp; Window *list = NULL; Window root, child = 0, parent_win = 0, root_win = 0; unsigned int num; int i; window = (GdkWindow*) &gdk_root_parent; private = (GdkWindowPrivate*) window; disp = private->xdisplay; root = private->xwindow; num = g_list_length (excludes); XGrabServer (disp); if (!XQueryTree (disp, root, &root_win, &parent_win, &list, &num)) { XUngrabServer (disp); return root; } if (list) { i = num - 1; do { XWindowAttributes xwa; XGetWindowAttributes (disp, list [i], &xwa); if (xwa.map_state != IsViewable) continue; if (excl_child && g_list_find (excludes, (gpointer *) list[i])) continue; if ((child = gdk_window_xid_at (list[i], 0, 0, x, y, excludes, excl_child)) == 0) continue; if (excludes) { if (!g_list_find (excludes, (gpointer *) child)) { XFree (list); XUngrabServer (disp); return child; } } else { XFree (list); XUngrabServer (disp); return child; } } while (--i > 0); XFree (list); } XUngrabServer (disp); return root;}voidgdk_window_init (void){ XWindowAttributes xattributes; unsigned int width; unsigned int height; unsigned int border_width; unsigned int depth; int x, y; XGetGeometry (gdk_display, gdk_root_window, &gdk_root_window, &x, &y, &width, &height, &border_width, &depth); XGetWindowAttributes (gdk_display, gdk_root_window, &xattributes); gdk_root_parent.xwindow = gdk_root_window; gdk_root_parent.xdisplay = gdk_display; gdk_root_parent.window_type = GDK_WINDOW_ROOT; gdk_root_parent.window.user_data = NULL; gdk_root_parent.width = width; gdk_root_parent.height = height; gdk_root_parent.children = NULL; gdk_root_parent.colormap = NULL; gdk_root_parent.ref_count = 1; gdk_xid_table_insert (&gdk_root_window, &gdk_root_parent);}static GdkAtom wm_client_leader_atom = GDK_NONE;GdkWindow*gdk_window_new (GdkWindow *parent, GdkWindowAttr *attributes, gint attributes_mask){ GdkWindow *window; GdkWindowPrivate *private; GdkWindowPrivate *parent_private; GdkVisual *visual; Display *parent_display; Window xparent; Visual *xvisual; XSetWindowAttributes xattributes; long xattributes_mask; XSizeHints size_hints; XWMHints wm_hints; XClassHint *class_hint; int x, y, depth; unsigned int class; char *title; int i; g_return_val_if_fail (attributes != NULL, NULL); if (!parent) parent = (GdkWindow*) &gdk_root_parent; parent_private = (GdkWindowPrivate*) parent; if (parent_private->destroyed) return NULL; xparent = parent_private->xwindow; parent_display = parent_private->xdisplay; private = g_new (GdkWindowPrivate, 1); window = (GdkWindow*) private; private->parent = parent; private->xdisplay = parent_display; private->destroyed = FALSE; private->mapped = FALSE; private->guffaw_gravity = FALSE; private->resize_count = 0; private->ref_count = 1; xattributes_mask = 0; if (attributes_mask & GDK_WA_X) x = attributes->x; else x = 0; if (attributes_mask & GDK_WA_Y) y = attributes->y; else y = 0; private->x = x; private->y = y; private->width = (attributes->width > 1) ? (attributes->width) : (1); private->height = (attributes->height > 1) ? (attributes->height) : (1); private->window_type = attributes->window_type; private->extension_events = FALSE; private->filters = NULL; private->children = NULL; window->user_data = NULL; if (attributes_mask & GDK_WA_VISUAL) visual = attributes->visual; else visual = gdk_visual_get_system (); xvisual = ((GdkVisualPrivate*) visual)->xvisual; xattributes.event_mask = StructureNotifyMask; for (i = 0; i < gdk_nevent_masks; i++) { if (attributes->event_mask & (1 << (i + 1))) xattributes.event_mask |= gdk_event_mask_table[i]; } if (xattributes.event_mask) xattributes_mask |= CWEventMask; if (attributes_mask & GDK_WA_NOREDIR) { xattributes.override_redirect = (attributes->override_redirect == FALSE)?False:True; xattributes_mask |= CWOverrideRedirect; } else xattributes.override_redirect = False; if (parent_private && parent_private->guffaw_gravity) { xattributes.win_gravity = StaticGravity; xattributes_mask |= CWWinGravity; } if (attributes->wclass == GDK_INPUT_OUTPUT) { class = InputOutput; depth = visual->depth; if (attributes_mask & GDK_WA_COLORMAP) private->colormap = attributes->colormap; else { if ((((GdkVisualPrivate*)gdk_visual_get_system ())->xvisual) == xvisual) private->colormap = gdk_colormap_get_system (); else private->colormap = gdk_colormap_new (visual, False); } xattributes.background_pixel = BlackPixel (gdk_display, gdk_screen); xattributes.border_pixel = BlackPixel (gdk_display, gdk_screen); xattributes_mask |= CWBorderPixel | CWBackPixel; switch (private->window_type) { case GDK_WINDOW_TOPLEVEL: xattributes.colormap = ((GdkColormapPrivate*) private->colormap)->xcolormap; xattributes_mask |= CWColormap; xparent = gdk_root_window; break; case GDK_WINDOW_CHILD: xattributes.colormap = ((GdkColormapPrivate*) private->colormap)->xcolormap; xattributes_mask |= CWColormap; break; case GDK_WINDOW_DIALOG: xattributes.colormap = ((GdkColormapPrivate*) private->colormap)->xcolormap; xattributes_mask |= CWColormap; xparent = gdk_root_window; break; case GDK_WINDOW_TEMP: xattributes.colormap = ((GdkColormapPrivate*) private->colormap)->xcolormap; xattributes_mask |= CWColormap; xparent = gdk_root_window; xattributes.save_under = True; xattributes.override_redirect = True; xattributes.cursor = None; xattributes_mask |= CWSaveUnder | CWOverrideRedirect; break; case GDK_WINDOW_ROOT: g_error ("cannot make windows of type GDK_WINDOW_ROOT"); break; case GDK_WINDOW_PIXMAP: g_error ("cannot make windows of type GDK_WINDOW_PIXMAP (use gdk_pixmap_new)"); break; } } else { depth = 0; class = InputOnly; private->colormap = NULL; } private->xwindow = XCreateWindow (private->xdisplay, xparent, x, y, private->width, private->height, 0, depth, class, xvisual, xattributes_mask, &xattributes); gdk_window_ref (window); gdk_xid_table_insert (&private->xwindow, window); if (private->colormap) gdk_colormap_ref (private->colormap); gdk_window_set_cursor (window, ((attributes_mask & GDK_WA_CURSOR) ? (attributes->cursor) : NULL)); if (parent_private) parent_private->children = g_list_prepend (parent_private->children, window); switch (private->window_type) { case GDK_WINDOW_DIALOG: XSetTransientForHint (private->xdisplay, private->xwindow, xparent); case GDK_WINDOW_TOPLEVEL: case GDK_WINDOW_TEMP: XSetWMProtocols (private->xdisplay, private->xwindow, gdk_wm_window_protocols, 2); break; case GDK_WINDOW_CHILD: if ((attributes->wclass == GDK_INPUT_OUTPUT) && (private->colormap != gdk_colormap_get_system ()) && (private->colormap != gdk_window_get_colormap (gdk_window_get_toplevel (window)))) { GDK_NOTE (MISC, g_message ("adding colormap window\n")); gdk_window_add_colormap_windows (window); } return window; default: return window; } size_hints.flags = PSize; size_hints.width = private->width; size_hints.height = private->height; wm_hints.flags = InputHint | StateHint | WindowGroupHint; wm_hints.window_group = gdk_leader_window; wm_hints.input = True; wm_hints.initial_state = NormalState; /* FIXME: Is there any point in doing this? Do any WM's pay * attention to PSize, and even if they do, is this the * correct value??? */ XSetWMNormalHints (private->xdisplay, private->xwindow, &size_hints); XSetWMHints (private->xdisplay, private->xwindow, &wm_hints); if (!wm_client_leader_atom) wm_client_leader_atom = gdk_atom_intern ("WM_CLIENT_LEADER", FALSE); XChangeProperty (private->xdisplay, private->xwindow, wm_client_leader_atom, XA_WINDOW, 32, PropModeReplace, (guchar*) &gdk_leader_window, 1); if (attributes_mask & GDK_WA_TITLE) title = attributes->title; else title = g_get_prgname (); XmbSetWMProperties (private->xdisplay, private->xwindow, title, title, NULL, 0, NULL, NULL, NULL); if (attributes_mask & GDK_WA_WMCLASS) { class_hint = XAllocClassHint (); class_hint->res_name = attributes->wmclass_name; class_hint->res_class = attributes->wmclass_class; XSetClassHint (private->xdisplay, private->xwindow, class_hint); XFree (class_hint); } return window;}GdkWindow *gdk_window_foreign_new (guint32 anid){ GdkWindow *window; GdkWindowPrivate *private; GdkWindowPrivate *parent_private; XWindowAttributes attrs; Window root, parent; Window *children = NULL; guint nchildren; gboolean result; gdk_error_trap_push (); result = XGetWindowAttributes (gdk_display, anid, &attrs); if (gdk_error_trap_pop () || !result) return NULL; /* FIXME: This is pretty expensive. Maybe the caller should supply * the parent */ gdk_error_trap_push (); result = XQueryTree (gdk_display, anid, &root, &parent, &children, &nchildren); if (gdk_error_trap_pop () || !result) return NULL; private = g_new (GdkWindowPrivate, 1); window = (GdkWindow*) private; if (children) XFree (children); private->parent = gdk_xid_table_lookup (parent); parent_private = (GdkWindowPrivate *)private->parent; if (parent_private) parent_private->children = g_list_prepend (parent_private->children, window); private->xwindow = anid; private->xdisplay = gdk_display; private->x = attrs.x; private->y = attrs.y; private->width = attrs.width; private->height = attrs.height; private->resize_count = 0; private->ref_count = 1; private->window_type = GDK_WINDOW_FOREIGN; private->destroyed = FALSE; private->mapped = (attrs.map_state != IsUnmapped); private->guffaw_gravity = FALSE; private->extension_events = 0; private->colormap = NULL; private->filters = NULL; private->children = NULL; window->user_data = NULL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -