From 473c1d4d7bef3755102e527e061ff1274bba9ae5 Mon Sep 17 00:00:00 2001 From: Owen Taylor Date: Fri, 27 Feb 1998 03:55:33 +0000 Subject: new functions for setting WM hints Thu Feb 26 22:36:46 1998 Owen Taylor * gdk/gdkwindow.c gdktypes.c gdk.h: new functions for setting WM hints gdk_window_set_icon() gdk_window_set_icon_name() gdk_window_set_group() gdk_window_set_decorations() gdk_window_set_functions() * gdk/MwmUtil.h: new uninstalled header file from lesstif distribution, used for setting MWM hints. * gdk/gdkdnd.c Makefile.am: renamed from gdk/gdk_dnd.c --- gdk/Makefile.am | 3 +- gdk/MwmUtil.h | 131 ++++++++++++++++++++++++++++++++++++++ gdk/gdk.h | 17 ++++- gdk/gdk_dnd.c | 138 ---------------------------------------- gdk/gdkcursor.c | 2 +- gdk/gdkdnd.c | 138 ++++++++++++++++++++++++++++++++++++++++ gdk/gdktypes.h | 26 ++++++++ gdk/gdkwindow.c | 165 ++++++++++++++++++++++++++++++++++++++++++++++++ gdk/x11/MwmUtil.h | 131 ++++++++++++++++++++++++++++++++++++++ gdk/x11/gdkcursor-x11.c | 2 +- gdk/x11/gdkdnd-x11.c | 138 ++++++++++++++++++++++++++++++++++++++++ gdk/x11/gdkwindow-x11.c | 165 ++++++++++++++++++++++++++++++++++++++++++++++++ 12 files changed, 913 insertions(+), 143 deletions(-) create mode 100644 gdk/MwmUtil.h delete mode 100644 gdk/gdk_dnd.c create mode 100644 gdk/gdkdnd.c create mode 100644 gdk/x11/MwmUtil.h create mode 100644 gdk/x11/gdkdnd-x11.c (limited to 'gdk') diff --git a/gdk/Makefile.am b/gdk/Makefile.am index 5be2dbdb9..30152085b 100644 --- a/gdk/Makefile.am +++ b/gdk/Makefile.am @@ -9,7 +9,7 @@ libgdk_la_SOURCES = \ gdkcc.c \ gdkcolor.c \ gdkcursor.c \ - gdk_dnd.c \ + gdkdnd.c \ gdkdraw.c \ gdkfont.c \ gdkgc.c \ @@ -28,6 +28,7 @@ libgdk_la_SOURCES = \ gdkvisual.c \ gdkwindow.c \ gdkxid.c \ + MwmUtil.h \ gxid_lib.h \ gxid_proto.h \ gxid_lib.c diff --git a/gdk/MwmUtil.h b/gdk/MwmUtil.h new file mode 100644 index 000000000..3628e9c0c --- /dev/null +++ b/gdk/MwmUtil.h @@ -0,0 +1,131 @@ +/** + * + * $Id$ + * + * Copyright (C) 1995 Free Software Foundation, Inc. + * + * This file is part of the GNU LessTif Library. + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + * + **/ + +#ifndef MWMUTIL_H_INCLUDED +#define MWMUTIL_H_INCLUDED + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + CARD32 flags; + CARD32 functions; + CARD32 decorations; + INT32 input_mode; + CARD32 status; +} MotifWmHints, MwmHints; + +#define MWM_HINTS_FUNCTIONS (1L << 0) +#define MWM_HINTS_DECORATIONS (1L << 1) +#define MWM_HINTS_INPUT_MODE (1L << 2) +#define MWM_HINTS_STATUS (1L << 3) + +#define MWM_FUNC_ALL (1L << 0) +#define MWM_FUNC_RESIZE (1L << 1) +#define MWM_FUNC_MOVE (1L << 2) +#define MWM_FUNC_MINIMIZE (1L << 3) +#define MWM_FUNC_MAXIMIZE (1L << 4) +#define MWM_FUNC_CLOSE (1L << 5) + +#define MWM_DECOR_ALL (1L << 0) +#define MWM_DECOR_BORDER (1L << 1) +#define MWM_DECOR_RESIZEH (1L << 2) +#define MWM_DECOR_TITLE (1L << 3) +#define MWM_DECOR_MENU (1L << 4) +#define MWM_DECOR_MINIMIZE (1L << 5) +#define MWM_DECOR_MAXIMIZE (1L << 6) + +#define MWM_INPUT_MODELESS 0 +#define MWM_INPUT_PRIMARY_APPLICATION_MODAL 1 +#define MWM_INPUT_SYSTEM_MODAL 2 +#define MWM_INPUT_FULL_APPLICATION_MODAL 3 +#define MWM_INPUT_APPLICATION_MODAL MWM_INPUT_PRIMARY_APPLICATION_MODAL + +#define MWM_TEAROFF_WINDOW (1L<<0) + +/* + * atoms + */ +#define _XA_MOTIF_BINDINGS "_MOTIF_BINDINGS" +#define _XA_MOTIF_WM_HINTS "_MOTIF_WM_HINTS" +#define _XA_MOTIF_WM_MESSAGES "_MOTIF_WM_MESSAGES" +#define _XA_MOTIF_WM_OFFSET "_MOTIF_WM_OFFSET" +#define _XA_MOTIF_WM_MENU "_MOTIF_WM_MENU" +#define _XA_MOTIF_WM_INFO "_MOTIF_WM_INFO" +#define _XA_MWM_HINTS _XA_MOTIF_WM_HINTS +#define _XA_MWM_MESSAGES _XA_MOTIF_WM_MESSAGES +#define _XA_MWM_MENU _XA_MOTIF_WM_MENU +#define _XA_MWM_INFO _XA_MOTIF_WM_INFO + + +/* + * _MWM_INFO property + */ +typedef struct { + long flags; + Window wm_window; +} MotifWmInfo; + +typedef MotifWmInfo MwmInfo; + +#define MWM_INFO_STARTUP_STANDARD (1L<<0) +#define MWM_INFO_STARTUP_CUSTOM (1L<<1) + +/* + * _MWM_HINTS property + */ +typedef struct { + CARD32 flags; + CARD32 functions; + CARD32 decorations; + INT32 inputMode; + CARD32 status; +} PropMotifWmHints; + +typedef PropMotifWmHints PropMwmHints; + +#define PROP_MOTIF_WM_HINTS_ELEMENTS 5 +#define PROP_MWM_HINTS_ELEMENTS PROP_MOTIF_WM_HINTS_ELEMENTS + +/* + * _MWM_INFO property, slight return + */ +typedef struct { + CARD32 flags; + CARD32 wmWindow; +} PropMotifWmInfo; + +typedef PropMotifWmInfo PropMwmInfo; + +#define PROP_MOTIF_WM_INFO_ELEMENTS 2 +#define PROP_MWM_INFO_ELEMENTS PROP_MOTIF_WM_INFO_ELEMENTS + +#ifdef __cplusplus +} +#endif + +#endif /* MWMUTIL_H_INCLUDED */ diff --git a/gdk/gdk.h b/gdk/gdk.h index ea7aa417a..f684fc359 100644 --- a/gdk/gdk.h +++ b/gdk/gdk.h @@ -286,6 +286,19 @@ GdkEventMask gdk_window_get_events (GdkWindow *window); void gdk_window_set_events (GdkWindow *window, GdkEventMask event_mask); +void gdk_window_set_icon (GdkWindow *window, + GdkWindow *icon_window, + GdkPixmap *pixmap, + GdkBitmap *mask); +void gdk_window_set_icon_name (GdkWindow *window, + gchar *name); +void gdk_window_set_group (GdkWindow *window, + GdkWindow *leader); +void gdk_window_set_decorations (GdkWindow *window, + GdkWMDecoration decorations); +void gdk_window_set_functions (GdkWindow *window, + GdkWMFunction functions); + /* Cursors */ GdkCursor* gdk_cursor_new (GdkCursorType cursor_type); @@ -293,8 +306,8 @@ GdkCursor* gdk_cursor_new_from_pixmap (GdkPixmap *source, GdkPixmap *mask, GdkColor *fg, GdkColor *bg, - int x, - int y); + gint x, + gint y); void gdk_cursor_destroy (GdkCursor *cursor); diff --git a/gdk/gdk_dnd.c b/gdk/gdk_dnd.c deleted file mode 100644 index 4f38fd94f..000000000 --- a/gdk/gdk_dnd.c +++ /dev/null @@ -1,138 +0,0 @@ -#include -#include -#include -#include "gdkx.h" -#include "gdk.h" - -/* Nothing much here now, but we have to make a start some time ;-) */ - -void -gdk_dnd_set_drag_cursors(GdkCursor *default_cursor, GdkCursor *goahead_cursor) -{ - gdk_dnd.c->gdk_cursor_dragdefault = - ((GdkCursorPrivate *)default_cursor)->xcursor; - gdk_dnd.c->gdk_cursor_dragok = ((GdkCursorPrivate *)goahead_cursor)->xcursor; - - if(gdk_dnd.dnd_grabbed) - { - if(gdk_dnd.c->drag_pm_default) - /* We were displaying pixmaps for the drag */ - { - gdk_window_hide(gdk_dnd.c->drag_pm_default); - gdk_window_unref(gdk_dnd.c->drag_pm_default); - if(gdk_dnd.c->drag_pm_ok) - { - gdk_window_hide(gdk_dnd.c->drag_pm_ok); - gdk_window_unref(gdk_dnd.c->drag_pm_ok); - } - gdk_dnd.c->drag_pm_default = gdk_dnd.c->drag_pm_ok = NULL; - } - gdk_dnd_display_drag_cursor(-1, -1, - gdk_dnd.dnd_drag_target?TRUE:FALSE, - TRUE); - } -} - -void -gdk_dnd_set_drag_shape(GdkWindow *default_pixmapwin, - GdkPoint *default_hotspot, - GdkWindow *goahead_pixmapwin, - GdkPoint *goahead_hotspot) -{ - g_return_if_fail(default_pixmapwin != NULL); - - if(gdk_dnd.c->drag_pm_default) - gdk_window_unref(gdk_dnd.c->drag_pm_default); - if(gdk_dnd.c->drag_pm_ok) - gdk_window_unref(gdk_dnd.c->drag_pm_ok); - - gdk_dnd.c->drag_pm_ok = NULL; - - gdk_window_ref(default_pixmapwin); - gdk_dnd.c->drag_pm_default = default_pixmapwin; - gdk_dnd.c->default_hotspot = *default_hotspot; - if(goahead_pixmapwin) - { - gdk_window_ref(goahead_pixmapwin); - gdk_dnd.c->drag_pm_ok = goahead_pixmapwin; - gdk_dnd.c->ok_hotspot = *goahead_hotspot; - } - - if(gdk_dnd.dnd_grabbed) - { - gdk_dnd_display_drag_cursor(-1, -1, - gdk_dnd.dnd_drag_target?TRUE:FALSE, - TRUE); - XChangeActivePointerGrab (gdk_display, - ButtonMotionMask | - ButtonPressMask | - ButtonReleaseMask | - EnterWindowMask | LeaveWindowMask, - None, - CurrentTime); - } -} - -void -gdk_dnd_display_drag_cursor(gint x, gint y, gboolean drag_ok, - gboolean change_made) -{ - if(!gdk_dnd.dnd_grabbed) - return; - - if(gdk_dnd.c->drag_pm_default) - { - /* We're doing pixmaps here... */ - GdkWindow *mypix, *opix; - GdkPoint *myhotspot; - gint itmp; - Window wtmp; - - if(x == -2 && y == -2) /* Hide the cursors */ - { - gdk_window_hide(gdk_dnd.c->drag_pm_ok); - gdk_window_hide(gdk_dnd.c->drag_pm_default); - return; - } - - if(x == -1 && y == -1) /* We're supposed to find it out for ourselves */ - XQueryPointer(gdk_display, gdk_root_window, - &wtmp, &wtmp, &x, &y, &itmp, &itmp, &itmp); - - if(drag_ok) - { - mypix = gdk_dnd.c->drag_pm_ok; - opix = gdk_dnd.c->drag_pm_default; - myhotspot = &gdk_dnd.c->ok_hotspot; - } - else - { - mypix = gdk_dnd.c->drag_pm_default; - opix = gdk_dnd.c->drag_pm_ok; - myhotspot = &gdk_dnd.c->default_hotspot; - } - if(change_made) - { - gdk_window_hide(opix); - gdk_window_show(mypix); /* There ought to be a way to know if - a window is already mapped etc. */ - } - gdk_window_move(mypix, x - myhotspot->x, y - myhotspot->y); - } - else if(change_made) - { - Cursor c; - /* Move cursors around */ - if(drag_ok) - c = gdk_dnd.c->gdk_cursor_dragok; - else - c = gdk_dnd.c->gdk_cursor_dragdefault; - XChangeActivePointerGrab (gdk_display, - ButtonMotionMask | - ButtonPressMask | - ButtonReleaseMask | - EnterWindowMask | LeaveWindowMask, - c, - CurrentTime); - } -} diff --git a/gdk/gdkcursor.c b/gdk/gdkcursor.c index b9b33ee51..83b95aa6c 100644 --- a/gdk/gdkcursor.c +++ b/gdk/gdkcursor.c @@ -39,7 +39,7 @@ gdk_cursor_new (GdkCursorType cursor_type) } GdkCursor* -gdk_cursor_new_from_pixmap (GdkPixmap *source, GdkPixmap *mask, GdkColor *fg, GdkColor *bg, int x, int y) +gdk_cursor_new_from_pixmap (GdkPixmap *source, GdkPixmap *mask, GdkColor *fg, GdkColor *bg, gint x, gint y) { GdkCursorPrivate *private; GdkCursor *cursor; diff --git a/gdk/gdkdnd.c b/gdk/gdkdnd.c new file mode 100644 index 000000000..4f38fd94f --- /dev/null +++ b/gdk/gdkdnd.c @@ -0,0 +1,138 @@ +#include +#include +#include +#include "gdkx.h" +#include "gdk.h" + +/* Nothing much here now, but we have to make a start some time ;-) */ + +void +gdk_dnd_set_drag_cursors(GdkCursor *default_cursor, GdkCursor *goahead_cursor) +{ + gdk_dnd.c->gdk_cursor_dragdefault = + ((GdkCursorPrivate *)default_cursor)->xcursor; + gdk_dnd.c->gdk_cursor_dragok = ((GdkCursorPrivate *)goahead_cursor)->xcursor; + + if(gdk_dnd.dnd_grabbed) + { + if(gdk_dnd.c->drag_pm_default) + /* We were displaying pixmaps for the drag */ + { + gdk_window_hide(gdk_dnd.c->drag_pm_default); + gdk_window_unref(gdk_dnd.c->drag_pm_default); + if(gdk_dnd.c->drag_pm_ok) + { + gdk_window_hide(gdk_dnd.c->drag_pm_ok); + gdk_window_unref(gdk_dnd.c->drag_pm_ok); + } + gdk_dnd.c->drag_pm_default = gdk_dnd.c->drag_pm_ok = NULL; + } + gdk_dnd_display_drag_cursor(-1, -1, + gdk_dnd.dnd_drag_target?TRUE:FALSE, + TRUE); + } +} + +void +gdk_dnd_set_drag_shape(GdkWindow *default_pixmapwin, + GdkPoint *default_hotspot, + GdkWindow *goahead_pixmapwin, + GdkPoint *goahead_hotspot) +{ + g_return_if_fail(default_pixmapwin != NULL); + + if(gdk_dnd.c->drag_pm_default) + gdk_window_unref(gdk_dnd.c->drag_pm_default); + if(gdk_dnd.c->drag_pm_ok) + gdk_window_unref(gdk_dnd.c->drag_pm_ok); + + gdk_dnd.c->drag_pm_ok = NULL; + + gdk_window_ref(default_pixmapwin); + gdk_dnd.c->drag_pm_default = default_pixmapwin; + gdk_dnd.c->default_hotspot = *default_hotspot; + if(goahead_pixmapwin) + { + gdk_window_ref(goahead_pixmapwin); + gdk_dnd.c->drag_pm_ok = goahead_pixmapwin; + gdk_dnd.c->ok_hotspot = *goahead_hotspot; + } + + if(gdk_dnd.dnd_grabbed) + { + gdk_dnd_display_drag_cursor(-1, -1, + gdk_dnd.dnd_drag_target?TRUE:FALSE, + TRUE); + XChangeActivePointerGrab (gdk_display, + ButtonMotionMask | + ButtonPressMask | + ButtonReleaseMask | + EnterWindowMask | LeaveWindowMask, + None, + CurrentTime); + } +} + +void +gdk_dnd_display_drag_cursor(gint x, gint y, gboolean drag_ok, + gboolean change_made) +{ + if(!gdk_dnd.dnd_grabbed) + return; + + if(gdk_dnd.c->drag_pm_default) + { + /* We're doing pixmaps here... */ + GdkWindow *mypix, *opix; + GdkPoint *myhotspot; + gint itmp; + Window wtmp; + + if(x == -2 && y == -2) /* Hide the cursors */ + { + gdk_window_hide(gdk_dnd.c->drag_pm_ok); + gdk_window_hide(gdk_dnd.c->drag_pm_default); + return; + } + + if(x == -1 && y == -1) /* We're supposed to find it out for ourselves */ + XQueryPointer(gdk_display, gdk_root_window, + &wtmp, &wtmp, &x, &y, &itmp, &itmp, &itmp); + + if(drag_ok) + { + mypix = gdk_dnd.c->drag_pm_ok; + opix = gdk_dnd.c->drag_pm_default; + myhotspot = &gdk_dnd.c->ok_hotspot; + } + else + { + mypix = gdk_dnd.c->drag_pm_default; + opix = gdk_dnd.c->drag_pm_ok; + myhotspot = &gdk_dnd.c->default_hotspot; + } + if(change_made) + { + gdk_window_hide(opix); + gdk_window_show(mypix); /* There ought to be a way to know if + a window is already mapped etc. */ + } + gdk_window_move(mypix, x - myhotspot->x, y - myhotspot->y); + } + else if(change_made) + { + Cursor c; + /* Move cursors around */ + if(drag_ok) + c = gdk_dnd.c->gdk_cursor_dragok; + else + c = gdk_dnd.c->gdk_cursor_dragdefault; + XChangeActivePointerGrab (gdk_display, + ButtonMotionMask | + ButtonPressMask | + ButtonReleaseMask | + EnterWindowMask | LeaveWindowMask, + c, + CurrentTime); + } +} diff --git a/gdk/gdktypes.h b/gdk/gdktypes.h index 4ea12a459..1a07bfae4 100644 --- a/gdk/gdktypes.h +++ b/gdk/gdktypes.h @@ -575,6 +575,32 @@ typedef enum GdkIMStatusNone = 0x0800L } GdkIMStyle; +/* The next two enumeration values current match the + * Motif constants. If this is changed, the implementation + * of gdk_window_set_decorations/gdk_window_set_functions + * will need to change as well. + */ +typedef enum +{ + GDK_DECOR_ALL = 1 << 0, + GDK_DECOR_BORDER = 1 << 1, + GDK_DECOR_RESIZEH = 1 << 2, + GDK_DECOR_TITLE = 1 << 3, + GDK_DECOR_MENU = 1 << 4, + GDK_DECOR_MINIMIZE = 1 << 5, + GDK_DECOR_MAXIMIZE = 1 << 6 +} GdkWMDecoration; + +typedef enum +{ + GDK_FUNC_ALL = 1 << 0, + GDK_FUNC_RESIZE = 1 << 1, + GDK_FUNC_MOVE = 1 << 2, + GDK_FUNC_MINIMIZE = 1 << 3, + GDK_FUNC_MAXIMIZE = 1 << 4, + GDK_FUNC_CLOSE = 1 << 5 +} GdkWMFunction; + #define GdkIMPreeditMask \ ( GdkIMPreeditArea | GdkIMPreeditCallbacks | \ GdkIMPreeditPosition | GdkIMPreeditNothing | \ diff --git a/gdk/gdkwindow.c b/gdk/gdkwindow.c index 90cfa4a5e..61d02b1f0 100644 --- a/gdk/gdkwindow.c +++ b/gdk/gdkwindow.c @@ -24,6 +24,7 @@ #include "../config.h" #include "gdkinput.h" #include "gdkprivate.h" +#include "MwmUtil.h" #include #include @@ -1543,3 +1544,167 @@ gdk_window_set_override_redirect(GdkWindow *window, CWOverrideRedirect, &attr); } + +void +gdk_window_set_icon (GdkWindow *window, + GdkWindow *icon_window, + GdkPixmap *pixmap, + GdkBitmap *mask) +{ + XWMHints wm_hints; + GdkWindowPrivate *window_private; + GdkWindowPrivate *private; + + g_return_if_fail (window != NULL); + window_private = (GdkWindowPrivate*) window; + if (window_private->destroyed) + return; + + wm_hints.flags = 0; + + if (icon_window != NULL) + { + private = (GdkWindowPrivate *)icon_window; + wm_hints.flags |= IconWindowHint; + wm_hints.icon_window = private->xwindow; + } + + if (pixmap != NULL) + { + private = (GdkWindowPrivate *)pixmap; + wm_hints.flags |= IconPixmapHint; + wm_hints.icon_pixmap = private->xwindow; + } + + if (mask != NULL) + { + private = (GdkWindowPrivate *)mask; + wm_hints.flags |= IconMaskHint; + wm_hints.icon_mask = private->xwindow; + } + + XSetWMHints (window_private->xdisplay, window_private->xwindow, &wm_hints); +} + +void +gdk_window_set_icon_name (GdkWindow *window, + gchar * name) +{ + GdkWindowPrivate *window_private; + XTextProperty property; + gint res; + + g_return_if_fail (window != NULL); + window_private = (GdkWindowPrivate*) window; + if (window_private->destroyed) + return; + res = XmbTextListToTextProperty (window_private->xdisplay, + &name, 1, XStdICCTextStyle, + &property); + if (res < 0) + { + g_warning("Error converting icon name to text property: %d\n", res); + return; + } + + XSetWMIconName (window_private->xdisplay, window_private->xwindow, + &property); + + XFree(property.value); +} + +void +gdk_window_set_group (GdkWindow *window, + GdkWindow *leader) +{ + XWMHints wm_hints; + GdkWindowPrivate *window_private; + GdkWindowPrivate *private; + + g_return_if_fail (window != NULL); + g_return_if_fail (leader != NULL); + window_private = (GdkWindowPrivate*) window; + if (window_private->destroyed) + return; + + private = (GdkWindowPrivate *)leader; + wm_hints.flags |= WindowGroupHint; + wm_hints.window_group = private->xwindow; + + XSetWMHints (window_private->xdisplay, window_private->xwindow, &wm_hints); +} + +static void +gdk_window_set_mwm_hints (GdkWindow *window, + MotifWmHints *new_hints) +{ + static Atom hints_atom = None; + MotifWmHints *hints; + Atom type; + gint format; + gulong nitems; + gulong bytes_after; + + GdkWindowPrivate *window_private; + + g_return_if_fail (window != NULL); + window_private = (GdkWindowPrivate*) window; + if (window_private->destroyed) + return; + + if (!hints_atom) + hints_atom = XInternAtom (window_private->xdisplay, + _XA_MOTIF_WM_HINTS, FALSE); + + XGetWindowProperty (window_private->xdisplay, window_private->xwindow, + hints_atom, 0, sizeof(MotifWmHints)/4, + False, AnyPropertyType, &type, &format, &nitems, + &bytes_after, (guchar **)&hints); + + if (type == None) + hints = new_hints; + else + { + if (new_hints->flags & MWM_HINTS_FUNCTIONS) + { + hints->flags |= MWM_HINTS_FUNCTIONS; + hints->functions = new_hints->functions; + } + if (new_hints->flags & MWM_HINTS_DECORATIONS) + { + hints->flags |= MWM_HINTS_DECORATIONS; + hints->decorations = new_hints->decorations; + } + } + + XChangeProperty (window_private->xdisplay, window_private->xwindow, + hints_atom, hints_atom, 32, PropModeReplace, + (guchar *)hints, sizeof(MotifWmHints)/4); + + if (hints != new_hints) + XFree (hints); +} + +void +gdk_window_set_decorations (GdkWindow *window, + GdkWMDecoration decorations) +{ + MotifWmHints hints; + + hints.flags = MWM_HINTS_DECORATIONS; + hints.decorations = decorations; + + gdk_window_set_mwm_hints (window, &hints); +} + +void +gdk_window_set_functions (GdkWindow *window, + GdkWMFunction functions) +{ + MotifWmHints hints; + + hints.flags = MWM_HINTS_FUNCTIONS; + hints.functions = functions; + + gdk_window_set_mwm_hints (window, &hints); +} diff --git a/gdk/x11/MwmUtil.h b/gdk/x11/MwmUtil.h new file mode 100644 index 000000000..3628e9c0c --- /dev/null +++ b/gdk/x11/MwmUtil.h @@ -0,0 +1,131 @@ +/** + * + * $Id$ + * + * Copyright (C) 1995 Free Software Foundation, Inc. + * + * This file is part of the GNU LessTif Library. + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + * + **/ + +#ifndef MWMUTIL_H_INCLUDED +#define MWMUTIL_H_INCLUDED + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + CARD32 flags; + CARD32 functions; + CARD32 decorations; + INT32 input_mode; + CARD32 status; +} MotifWmHints, MwmHints; + +#define MWM_HINTS_FUNCTIONS (1L << 0) +#define MWM_HINTS_DECORATIONS (1L << 1) +#define MWM_HINTS_INPUT_MODE (1L << 2) +#define MWM_HINTS_STATUS (1L << 3) + +#define MWM_FUNC_ALL (1L << 0) +#define MWM_FUNC_RESIZE (1L << 1) +#define MWM_FUNC_MOVE (1L << 2) +#define MWM_FUNC_MINIMIZE (1L << 3) +#define MWM_FUNC_MAXIMIZE (1L << 4) +#define MWM_FUNC_CLOSE (1L << 5) + +#define MWM_DECOR_ALL (1L << 0) +#define MWM_DECOR_BORDER (1L << 1) +#define MWM_DECOR_RESIZEH (1L << 2) +#define MWM_DECOR_TITLE (1L << 3) +#define MWM_DECOR_MENU (1L << 4) +#define MWM_DECOR_MINIMIZE (1L << 5) +#define MWM_DECOR_MAXIMIZE (1L << 6) + +#define MWM_INPUT_MODELESS 0 +#define MWM_INPUT_PRIMARY_APPLICATION_MODAL 1 +#define MWM_INPUT_SYSTEM_MODAL 2 +#define MWM_INPUT_FULL_APPLICATION_MODAL 3 +#define MWM_INPUT_APPLICATION_MODAL MWM_INPUT_PRIMARY_APPLICATION_MODAL + +#define MWM_TEAROFF_WINDOW (1L<<0) + +/* + * atoms + */ +#define _XA_MOTIF_BINDINGS "_MOTIF_BINDINGS" +#define _XA_MOTIF_WM_HINTS "_MOTIF_WM_HINTS" +#define _XA_MOTIF_WM_MESSAGES "_MOTIF_WM_MESSAGES" +#define _XA_MOTIF_WM_OFFSET "_MOTIF_WM_OFFSET" +#define _XA_MOTIF_WM_MENU "_MOTIF_WM_MENU" +#define _XA_MOTIF_WM_INFO "_MOTIF_WM_INFO" +#define _XA_MWM_HINTS _XA_MOTIF_WM_HINTS +#define _XA_MWM_MESSAGES _XA_MOTIF_WM_MESSAGES +#define _XA_MWM_MENU _XA_MOTIF_WM_MENU +#define _XA_MWM_INFO _XA_MOTIF_WM_INFO + + +/* + * _MWM_INFO property + */ +typedef struct { + long flags; + Window wm_window; +} MotifWmInfo; + +typedef MotifWmInfo MwmInfo; + +#define MWM_INFO_STARTUP_STANDARD (1L<<0) +#define MWM_INFO_STARTUP_CUSTOM (1L<<1) + +/* + * _MWM_HINTS property + */ +typedef struct { + CARD32 flags; + CARD32 functions; + CARD32 decorations; + INT32 inputMode; + CARD32 status; +} PropMotifWmHints; + +typedef PropMotifWmHints PropMwmHints; + +#define PROP_MOTIF_WM_HINTS_ELEMENTS 5 +#define PROP_MWM_HINTS_ELEMENTS PROP_MOTIF_WM_HINTS_ELEMENTS + +/* + * _MWM_INFO property, slight return + */ +typedef struct { + CARD32 flags; + CARD32 wmWindow; +} PropMotifWmInfo; + +typedef PropMotifWmInfo PropMwmInfo; + +#define PROP_MOTIF_WM_INFO_ELEMENTS 2 +#define PROP_MWM_INFO_ELEMENTS PROP_MOTIF_WM_INFO_ELEMENTS + +#ifdef __cplusplus +} +#endif + +#endif /* MWMUTIL_H_INCLUDED */ diff --git a/gdk/x11/gdkcursor-x11.c b/gdk/x11/gdkcursor-x11.c index b9b33ee51..83b95aa6c 100644 --- a/gdk/x11/gdkcursor-x11.c +++ b/gdk/x11/gdkcursor-x11.c @@ -39,7 +39,7 @@ gdk_cursor_new (GdkCursorType cursor_type) } GdkCursor* -gdk_cursor_new_from_pixmap (GdkPixmap *source, GdkPixmap *mask, GdkColor *fg, GdkColor *bg, int x, int y) +gdk_cursor_new_from_pixmap (GdkPixmap *source, GdkPixmap *mask, GdkColor *fg, GdkColor *bg, gint x, gint y) { GdkCursorPrivate *private; GdkCursor *cursor; diff --git a/gdk/x11/gdkdnd-x11.c b/gdk/x11/gdkdnd-x11.c new file mode 100644 index 000000000..4f38fd94f --- /dev/null +++ b/gdk/x11/gdkdnd-x11.c @@ -0,0 +1,138 @@ +#include +#include +#include +#include "gdkx.h" +#include "gdk.h" + +/* Nothing much here now, but we have to make a start some time ;-) */ + +void +gdk_dnd_set_drag_cursors(GdkCursor *default_cursor, GdkCursor *goahead_cursor) +{ + gdk_dnd.c->gdk_cursor_dragdefault = + ((GdkCursorPrivate *)default_cursor)->xcursor; + gdk_dnd.c->gdk_cursor_dragok = ((GdkCursorPrivate *)goahead_cursor)->xcursor; + + if(gdk_dnd.dnd_grabbed) + { + if(gdk_dnd.c->drag_pm_default) + /* We were displaying pixmaps for the drag */ + { + gdk_window_hide(gdk_dnd.c->drag_pm_default); + gdk_window_unref(gdk_dnd.c->drag_pm_default); + if(gdk_dnd.c->drag_pm_ok) + { + gdk_window_hide(gdk_dnd.c->drag_pm_ok); + gdk_window_unref(gdk_dnd.c->drag_pm_ok); + } + gdk_dnd.c->drag_pm_default = gdk_dnd.c->drag_pm_ok = NULL; + } + gdk_dnd_display_drag_cursor(-1, -1, + gdk_dnd.dnd_drag_target?TRUE:FALSE, + TRUE); + } +} + +void +gdk_dnd_set_drag_shape(GdkWindow *default_pixmapwin, + GdkPoint *default_hotspot, + GdkWindow *goahead_pixmapwin, + GdkPoint *goahead_hotspot) +{ + g_return_if_fail(default_pixmapwin != NULL); + + if(gdk_dnd.c->drag_pm_default) + gdk_window_unref(gdk_dnd.c->drag_pm_default); + if(gdk_dnd.c->drag_pm_ok) + gdk_window_unref(gdk_dnd.c->drag_pm_ok); + + gdk_dnd.c->drag_pm_ok = NULL; + + gdk_window_ref(default_pixmapwin); + gdk_dnd.c->drag_pm_default = default_pixmapwin; + gdk_dnd.c->default_hotspot = *default_hotspot; + if(goahead_pixmapwin) + { + gdk_window_ref(goahead_pixmapwin); + gdk_dnd.c->drag_pm_ok = goahead_pixmapwin; + gdk_dnd.c->ok_hotspot = *goahead_hotspot; + } + + if(gdk_dnd.dnd_grabbed) + { + gdk_dnd_display_drag_cursor(-1, -1, + gdk_dnd.dnd_drag_target?TRUE:FALSE, + TRUE); + XChangeActivePointerGrab (gdk_display, + ButtonMotionMask | + ButtonPressMask | + ButtonReleaseMask | + EnterWindowMask | LeaveWindowMask, + None, + CurrentTime); + } +} + +void +gdk_dnd_display_drag_cursor(gint x, gint y, gboolean drag_ok, + gboolean change_made) +{ + if(!gdk_dnd.dnd_grabbed) + return; + + if(gdk_dnd.c->drag_pm_default) + { + /* We're doing pixmaps here... */ + GdkWindow *mypix, *opix; + GdkPoint *myhotspot; + gint itmp; + Window wtmp; + + if(x == -2 && y == -2) /* Hide the cursors */ + { + gdk_window_hide(gdk_dnd.c->drag_pm_ok); + gdk_window_hide(gdk_dnd.c->drag_pm_default); + return; + } + + if(x == -1 && y == -1) /* We're supposed to find it out for ourselves */ + XQueryPointer(gdk_display, gdk_root_window, + &wtmp, &wtmp, &x, &y, &itmp, &itmp, &itmp); + + if(drag_ok) + { + mypix = gdk_dnd.c->drag_pm_ok; + opix = gdk_dnd.c->drag_pm_default; + myhotspot = &gdk_dnd.c->ok_hotspot; + } + else + { + mypix = gdk_dnd.c->drag_pm_default; + opix = gdk_dnd.c->drag_pm_ok; + myhotspot = &gdk_dnd.c->default_hotspot; + } + if(change_made) + { + gdk_window_hide(opix); + gdk_window_show(mypix); /* There ought to be a way to know if + a window is already mapped etc. */ + } + gdk_window_move(mypix, x - myhotspot->x, y - myhotspot->y); + } + else if(change_made) + { + Cursor c; + /* Move cursors around */ + if(drag_ok) + c = gdk_dnd.c->gdk_cursor_dragok; + else + c = gdk_dnd.c->gdk_cursor_dragdefault; + XChangeActivePointerGrab (gdk_display, + ButtonMotionMask | + ButtonPressMask | + ButtonReleaseMask | + EnterWindowMask | LeaveWindowMask, + c, + CurrentTime); + } +} diff --git a/gdk/x11/gdkwindow-x11.c b/gdk/x11/gdkwindow-x11.c index 90cfa4a5e..61d02b1f0 100644 --- a/gdk/x11/gdkwindow-x11.c +++ b/gdk/x11/gdkwindow-x11.c @@ -24,6 +24,7 @@ #include "../config.h" #include "gdkinput.h" #include "gdkprivate.h" +#include "MwmUtil.h" #include #include @@ -1543,3 +1544,167 @@ gdk_window_set_override_redirect(GdkWindow *window, CWOverrideRedirect, &attr); } + +void +gdk_window_set_icon (GdkWindow *window, + GdkWindow *icon_window, + GdkPixmap *pixmap, + GdkBitmap *mask) +{ + XWMHints wm_hints; + GdkWindowPrivate *window_private; + GdkWindowPrivate *private; + + g_return_if_fail (window != NULL); + window_private = (GdkWindowPrivate*) window; + if (window_private->destroyed) + return; + + wm_hints.flags = 0; + + if (icon_window != NULL) + { + private = (GdkWindowPrivate *)icon_window; + wm_hints.flags |= IconWindowHint; + wm_hints.icon_window = private->xwindow; + } + + if (pixmap != NULL) + { + private = (GdkWindowPrivate *)pixmap; + wm_hints.flags |= IconPixmapHint; + wm_hints.icon_pixmap = private->xwindow; + } + + if (mask != NULL) + { + private = (GdkWindowPrivate *)mask; + wm_hints.flags |= IconMaskHint; + wm_hints.icon_mask = private->xwindow; + } + + XSetWMHints (window_private->xdisplay, window_private->xwindow, &wm_hints); +} + +void +gdk_window_set_icon_name (GdkWindow *window, + gchar * name) +{ + GdkWindowPrivate *window_private; + XTextProperty property; + gint res; + + g_return_if_fail (window != NULL); + window_private = (GdkWindowPrivate*) window; + if (window_private->destroyed) + return; + res = XmbTextListToTextProperty (window_private->xdisplay, + &name, 1, XStdICCTextStyle, + &property); + if (res < 0) + { + g_warning("Error converting icon name to text property: %d\n", res); + return; + } + + XSetWMIconName (window_private->xdisplay, window_private->xwindow, + &property); + + XFree(property.value); +} + +void +gdk_window_set_group (GdkWindow *window, + GdkWindow *leader) +{ + XWMHints wm_hints; + GdkWindowPrivate *window_private; + GdkWindowPrivate *private; + + g_return_if_fail (window != NULL); + g_return_if_fail (leader != NULL); + window_private = (GdkWindowPrivate*) window; + if (window_private->destroyed) + return; + + private = (GdkWindowPrivate *)leader; + wm_hints.flags |= WindowGroupHint; + wm_hints.window_group = private->xwindow; + + XSetWMHints (window_private->xdisplay, window_private->xwindow, &wm_hints); +} + +static void +gdk_window_set_mwm_hints (GdkWindow *window, + MotifWmHints *new_hints) +{ + static Atom hints_atom = None; + MotifWmHints *hints; + Atom type; + gint format; + gulong nitems; + gulong bytes_after; + + GdkWindowPrivate *window_private; + + g_return_if_fail (window != NULL); + window_private = (GdkWindowPrivate*) window; + if (window_private->destroyed) + return; + + if (!hints_atom) + hints_atom = XInternAtom (window_private->xdisplay, + _XA_MOTIF_WM_HINTS, FALSE); + + XGetWindowProperty (window_private->xdisplay, window_private->xwindow, + hints_atom, 0, sizeof(MotifWmHints)/4, + False, AnyPropertyType, &type, &format, &nitems, + &bytes_after, (guchar **)&hints); + + if (type == None) + hints = new_hints; + else + { + if (new_hints->flags & MWM_HINTS_FUNCTIONS) + { + hints->flags |= MWM_HINTS_FUNCTIONS; + hints->functions = new_hints->functions; + } + if (new_hints->flags & MWM_HINTS_DECORATIONS) + { + hints->flags |= MWM_HINTS_DECORATIONS; + hints->decorations = new_hints->decorations; + } + } + + XChangeProperty (window_private->xdisplay, window_private->xwindow, + hints_atom, hints_atom, 32, PropModeReplace, + (guchar *)hints, sizeof(MotifWmHints)/4); + + if (hints != new_hints) + XFree (hints); +} + +void +gdk_window_set_decorations (GdkWindow *window, + GdkWMDecoration decorations) +{ + MotifWmHints hints; + + hints.flags = MWM_HINTS_DECORATIONS; + hints.decorations = decorations; + + gdk_window_set_mwm_hints (window, &hints); +} + +void +gdk_window_set_functions (GdkWindow *window, + GdkWMFunction functions) +{ + MotifWmHints hints; + + hints.flags = MWM_HINTS_FUNCTIONS; + hints.functions = functions; + + gdk_window_set_mwm_hints (window, &hints); +} -- cgit v1.2.1