summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog17
-rw-r--r--acconfig.h1
-rw-r--r--configure.in12
-rw-r--r--src/display.c16
-rw-r--r--src/frame.c28
-rw-r--r--src/frames.c158
-rw-r--r--src/frames.h5
-rw-r--r--src/main.c11
-rw-r--r--src/theme-parser.c38
-rw-r--r--src/theme.c5
-rw-r--r--src/theme.h12
-rw-r--r--src/tools/Makefile.am10
-rw-r--r--src/tools/metacity-grayscale.c109
-rw-r--r--src/ui.c9
-rw-r--r--src/ui.h5
15 files changed, 427 insertions, 9 deletions
diff --git a/ChangeLog b/ChangeLog
index ceb1f89..b66ed5a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,20 @@
+2002-05-30 Havoc Pennington <hp@redhat.com>
+
+ * src/main.c (main): verbose-log on startup whether we were
+ compiled with various extensions
+
+ * src/display.c (meta_display_queue_retheme_all_windows): reapply
+ shape mask when changing themes, sucks to do it here though, makes
+ theme changing slower. Needs fixing.
+
+ * src/theme-parser.c (parse_toplevel_element): parse rounded
+ corner options to frame_geometry
+
+ * src/frames.c (meta_frames_apply_shapes): apply rounded corners
+ if requested by the theme
+
+ * configure.in (HAVE_SHAPE): check for shape extension
+
2002-05-30 Stephen Browne <stephen.browne@sun.com>
* src/tools/metacity-properties.c:
diff --git a/acconfig.h b/acconfig.h
index 3a5b1a0..773ad19 100644
--- a/acconfig.h
+++ b/acconfig.h
@@ -11,3 +11,4 @@
#undef HAVE_XFT
#undef HAVE_SM
#undef HAVE_XINERAMA
+#undef HAVE_SHAPE
diff --git a/configure.in b/configure.in
index bf6a8c6..fcee26f 100644
--- a/configure.in
+++ b/configure.in
@@ -110,6 +110,18 @@ if test "$found_xinerama" = "true"; then
AC_DEFINE(HAVE_XINERAMA)
fi
+SHAPE_LIBS=
+found_shape=false
+AC_CHECK_LIB(Xext, XShapeQueryExtension,
+ [AC_CHECK_HEADERS(X11/extensions/shape.h,
+ SHAPE_LIBS=-lXext found_shape=true)],
+ , -lXext $X_LIBS $X_PRE_LIBS -lX11 $X_EXTRA_LIBS)
+
+if test "$found_shape" = "true"; then
+ AC_DEFINE(HAVE_SHAPE)
+fi
+
+## we don't put SHAPE_LIBS in here, they should be in X_EXTRA_LIBS I think. we'll see
METACITY_LIBS="$XINERAMA_LIBS $X_LIBS $X_PRE_LIBS -lX11 $X_EXTRA_LIBS $METACITY_LIBS"
METACITY_MESSAGE_LIBS="$X_LIBS $X_PRE_LIBS -lX11 $X_EXTRA_LIBS $METACITY_MESSAGE_LIBS"
METACITY_WINDOW_DEMO_LIBS="$X_LIBS $X_PRE_LIBS -lX11 $X_EXTRA_LIBS $METACITY_WINDOW_DEMO_LIBS"
diff --git a/src/display.c b/src/display.c
index 15f0d41..ef2a360 100644
--- a/src/display.c
+++ b/src/display.c
@@ -2543,7 +2543,21 @@ meta_display_queue_retheme_all_windows (MetaDisplay *display)
meta_window_queue_move_resize (window);
if (window->frame)
- meta_frame_queue_draw (window->frame);
+ {
+ meta_frame_queue_draw (window->frame);
+
+ /* FIXME this sucks and is slooooooooow. Do it in the idle with the
+ * redraw or the window resize.
+ */
+
+#if 0
+ /* in case the theme doesn't affect the frame size */
+ meta_ui_apply_frame_shape (window->screen->ui,
+ window->frame->xwindow,
+ window->frame->rect.width,
+ window->frame->rect.height);
+#endif
+ }
tmp = tmp->next;
}
diff --git a/src/frame.c b/src/frame.c
index 62aa3f9..7b7b973 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -138,6 +138,12 @@ meta_window_ensure_frame (MetaWindow *window)
/* Move keybindings to frame instead of window */
meta_window_grab_keys (window);
+ /* Shape mask */
+ meta_ui_apply_frame_shape (frame->window->screen->ui,
+ frame->xwindow,
+ frame->rect.width,
+ frame->rect.height);
+
meta_display_ungrab (window->display);
}
@@ -280,11 +286,25 @@ meta_frame_sync_to_window (MetaFrame *frame,
/* set bg to none to avoid flicker */
if (need_resize)
- meta_ui_unflicker_frame_bg (frame->window->screen->ui,
- frame->xwindow,
- frame->rect.width,
- frame->rect.height);
+ {
+ meta_ui_unflicker_frame_bg (frame->window->screen->ui,
+ frame->xwindow,
+ frame->rect.width,
+ frame->rect.height);
+ /* Done before the window resize, because doing it before means
+ * part of the window being resized becomes unshaped, which may
+ * be sort of hard to see with bg = None. If we did it after
+ * window resize, part of the window being resized would become
+ * shaped, which might be more visible.
+ */
+
+ meta_ui_apply_frame_shape (frame->window->screen->ui,
+ frame->xwindow,
+ frame->rect.width,
+ frame->rect.height);
+ }
+
if (need_move && need_resize)
XMoveResizeWindow (frame->window->display->xdisplay,
frame->xwindow,
diff --git a/src/frames.c b/src/frames.c
index 07c5be8..0a07e81 100644
--- a/src/frames.c
+++ b/src/frames.c
@@ -28,6 +28,10 @@
#include "theme.h"
#include "prefs.h"
+#ifdef HAVE_SHAPE
+#include <X11/extensions/shape.h>
+#endif
+
#define DEFAULT_INNER_BUTTON_BORDER 3
static void meta_frames_class_init (MetaFramesClass *klass);
@@ -201,7 +205,7 @@ meta_frames_destroy (GtkObject *object)
MetaFrames *frames;
frames = META_FRAMES (object);
-
+
meta_prefs_remove_listener (font_changed_callback, frames);
clear_tip (frames);
@@ -619,6 +623,158 @@ meta_frames_unflicker_bg (MetaFrames *frames,
}
void
+meta_frames_apply_shapes (MetaFrames *frames,
+ Window xwindow,
+ int new_window_width,
+ int new_window_height)
+{
+#ifdef HAVE_SHAPE
+ /* Apply shapes as if window had new_window_width, new_window_height */
+ GtkWidget *widget;
+ MetaUIFrame *frame;
+ MetaFrameGeometry fgeom;
+ XRectangle xrect;
+ Region corners_xregion;
+ Region window_xregion;
+
+ widget = GTK_WIDGET (frames);
+
+ frame = meta_frames_lookup_window (frames, xwindow);
+ g_return_if_fail (frame != NULL);
+
+ meta_frames_calc_geometry (frames, frame, &fgeom);
+
+ if (!(fgeom.top_left_corner_rounded ||
+ fgeom.top_right_corner_rounded ||
+ fgeom.bottom_left_corner_rounded ||
+ fgeom.bottom_right_corner_rounded))
+ {
+ XShapeCombineMask (gdk_display, frame->xwindow,
+ ShapeBounding, 0, 0, None, ShapeSet);
+
+ return; /* nothing to do */
+ }
+
+ corners_xregion = XCreateRegion ();
+
+ if (fgeom.top_left_corner_rounded)
+ {
+ xrect.x = 0;
+ xrect.y = 0;
+ xrect.width = 5;
+ xrect.height = 1;
+
+ XUnionRectWithRegion (&xrect, corners_xregion, corners_xregion);
+
+ xrect.y = 1;
+ xrect.width = 3;
+ XUnionRectWithRegion (&xrect, corners_xregion, corners_xregion);
+
+ xrect.y = 2;
+ xrect.width = 2;
+ XUnionRectWithRegion (&xrect, corners_xregion, corners_xregion);
+
+ xrect.y = 3;
+ xrect.width = 1;
+ xrect.height = 2;
+ XUnionRectWithRegion (&xrect, corners_xregion, corners_xregion);
+ }
+
+ if (fgeom.top_right_corner_rounded)
+ {
+ xrect.x = new_window_width - 5;
+ xrect.y = 0;
+ xrect.width = 5;
+ xrect.height = 1;
+
+ XUnionRectWithRegion (&xrect, corners_xregion, corners_xregion);
+
+ xrect.y = 1;
+ xrect.x = new_window_width - 3;
+ xrect.width = 3;
+ XUnionRectWithRegion (&xrect, corners_xregion, corners_xregion);
+
+ xrect.y = 2;
+ xrect.x = new_window_width - 2;
+ xrect.width = 2;
+ XUnionRectWithRegion (&xrect, corners_xregion, corners_xregion);
+
+ xrect.y = 3;
+ xrect.x = new_window_width - 1;
+ xrect.width = 1;
+ xrect.height = 2;
+ XUnionRectWithRegion (&xrect, corners_xregion, corners_xregion);
+ }
+
+ if (fgeom.bottom_left_corner_rounded)
+ {
+ xrect.x = 0;
+ xrect.y = new_window_height - 1;
+ xrect.width = 5;
+ xrect.height = 1;
+
+ XUnionRectWithRegion (&xrect, corners_xregion, corners_xregion);
+
+ xrect.y = new_window_height - 2;
+ xrect.width = 3;
+ XUnionRectWithRegion (&xrect, corners_xregion, corners_xregion);
+
+ xrect.y = new_window_height - 3;
+ xrect.width = 2;
+ XUnionRectWithRegion (&xrect, corners_xregion, corners_xregion);
+
+ xrect.y = new_window_height - 5;
+ xrect.width = 1;
+ xrect.height = 2;
+ XUnionRectWithRegion (&xrect, corners_xregion, corners_xregion);
+ }
+
+ if (fgeom.bottom_right_corner_rounded)
+ {
+ xrect.x = new_window_width - 5;
+ xrect.y = new_window_height - 1;
+ xrect.width = 5;
+ xrect.height = 1;
+
+ XUnionRectWithRegion (&xrect, corners_xregion, corners_xregion);
+
+ xrect.y = new_window_height - 2;
+ xrect.x = new_window_width - 3;
+ xrect.width = 3;
+ XUnionRectWithRegion (&xrect, corners_xregion, corners_xregion);
+
+ xrect.y = new_window_height - 3;
+ xrect.x = new_window_width - 2;
+ xrect.width = 2;
+ XUnionRectWithRegion (&xrect, corners_xregion, corners_xregion);
+
+ xrect.y = new_window_height - 5;
+ xrect.x = new_window_width - 1;
+ xrect.width = 1;
+ xrect.height = 2;
+ XUnionRectWithRegion (&xrect, corners_xregion, corners_xregion);
+ }
+
+ window_xregion = XCreateRegion ();
+
+ xrect.x = 0;
+ xrect.y = 0;
+ xrect.width = new_window_width;
+ xrect.height = new_window_height;
+
+ XUnionRectWithRegion (&xrect, window_xregion, window_xregion);
+
+ XSubtractRegion (window_xregion, corners_xregion, window_xregion);
+
+ XShapeCombineRegion (gdk_display, frame->xwindow,
+ ShapeBounding, 0, 0, window_xregion, ShapeSet);
+
+ XDestroyRegion (window_xregion);
+ XDestroyRegion (corners_xregion);
+#endif
+}
+
+void
meta_frames_queue_draw (MetaFrames *frames,
Window xwindow)
{
diff --git a/src/frames.h b/src/frames.h
index 10e9380..b0febb0 100644
--- a/src/frames.h
+++ b/src/frames.h
@@ -124,6 +124,11 @@ void meta_frames_unflicker_bg (MetaFrames *frames,
int target_width,
int target_height);
+void meta_frames_apply_shapes (MetaFrames *frames,
+ Window xwindow,
+ int new_window_width,
+ int new_window_height);
+
void meta_frames_queue_draw (MetaFrames *frames,
Window xwindow);
diff --git a/src/main.c b/src/main.c
index 4153ce6..9b6532e 100644
--- a/src/main.c
+++ b/src/main.c
@@ -225,6 +225,17 @@ main (int argc, char **argv)
g_type_init ();
+#ifdef HAVE_SHAPE
+ meta_verbose ("Compiled with shape extension\n");
+#else
+ meta_verbose ("Compiled without shape extension\n");
+#endif
+#ifdef HAVE_XINERAMA
+ meta_verbose ("Compiled with Xinerama extension\n");
+#else
+ meta_verbose ("Compiled without Xinerama extension\n");
+#endif
+
/* Load prefs */
meta_prefs_init ();
meta_prefs_add_listener (prefs_changed_callback, NULL);
diff --git a/src/theme-parser.c b/src/theme-parser.c
index 48b6328..cb68e7c 100644
--- a/src/theme-parser.c
+++ b/src/theme-parser.c
@@ -718,7 +718,15 @@ parse_toplevel_element (GMarkupParseContext *context,
const char *parent = NULL;
const char *has_title = NULL;
const char *title_scale = NULL;
+ const char *rounded_top_left = NULL;
+ const char *rounded_top_right = NULL;
+ const char *rounded_bottom_left = NULL;
+ const char *rounded_bottom_right = NULL;
gboolean has_title_val;
+ gboolean rounded_top_left_val;
+ gboolean rounded_top_right_val;
+ gboolean rounded_bottom_left_val;
+ gboolean rounded_bottom_right_val;
double title_scale_val;
MetaFrameLayout *parent_layout;
@@ -726,6 +734,10 @@ parse_toplevel_element (GMarkupParseContext *context,
error,
"name", &name, "parent", &parent,
"has_title", &has_title, "title_scale", &title_scale,
+ "rounded_top_left", &rounded_top_left,
+ "rounded_top_right", &rounded_top_right,
+ "rounded_bottom_left", &rounded_bottom_left,
+ "rounded_bottom_right", &rounded_bottom_right,
NULL))
return;
@@ -741,6 +753,20 @@ parse_toplevel_element (GMarkupParseContext *context,
if (has_title && !parse_boolean (has_title, &has_title_val, context, error))
return;
+ rounded_top_left_val = FALSE;
+ rounded_top_right_val = FALSE;
+ rounded_bottom_left_val = FALSE;
+ rounded_bottom_right_val = FALSE;
+
+ if (rounded_top_left && !parse_boolean (rounded_top_left, &rounded_top_left_val, context, error))
+ return;
+ if (rounded_top_right && !parse_boolean (rounded_top_right, &rounded_top_right_val, context, error))
+ return;
+ if (rounded_bottom_left && !parse_boolean (rounded_bottom_left, &rounded_bottom_left_val, context, error))
+ return;
+ if (rounded_bottom_right && !parse_boolean (rounded_bottom_right, &rounded_bottom_right_val, context, error))
+ return;
+
title_scale_val = 1.0;
if (title_scale && !parse_title_scale (title_scale, &title_scale_val, context, error))
return;
@@ -778,6 +804,18 @@ parse_toplevel_element (GMarkupParseContext *context,
if (title_scale)
info->layout->title_scale = title_scale_val;
+
+ if (rounded_top_left)
+ info->layout->top_left_corner_rounded = rounded_top_left_val;
+
+ if (rounded_top_right)
+ info->layout->top_right_corner_rounded = rounded_top_right_val;
+
+ if (rounded_bottom_left)
+ info->layout->bottom_left_corner_rounded = rounded_bottom_left_val;
+
+ if (rounded_bottom_right)
+ info->layout->bottom_right_corner_rounded = rounded_bottom_right_val;
meta_theme_insert_layout (info->theme, name, info->layout);
diff --git a/src/theme.c b/src/theme.c
index 1c106cf..c54e9ff 100644
--- a/src/theme.c
+++ b/src/theme.c
@@ -659,6 +659,11 @@ meta_frame_layout_calc_geometry (const MetaFrameLayout *layout,
fgeom->title_rect.width = 0;
fgeom->title_rect.height = 0;
}
+
+ fgeom->top_left_corner_rounded = layout->top_left_corner_rounded;
+ fgeom->top_right_corner_rounded = layout->top_right_corner_rounded;
+ fgeom->bottom_left_corner_rounded = layout->bottom_left_corner_rounded;
+ fgeom->bottom_right_corner_rounded = layout->bottom_right_corner_rounded;
}
diff --git a/src/theme.h b/src/theme.h
index eb54d74..6345a2e 100644
--- a/src/theme.h
+++ b/src/theme.h
@@ -84,6 +84,12 @@ struct _MetaFrameLayout
/* Whether title text will be displayed */
guint has_title : 1;
+
+ /* Round corners */
+ guint top_left_corner_rounded : 1;
+ guint top_right_corner_rounded : 1;
+ guint bottom_left_corner_rounded : 1;
+ guint bottom_right_corner_rounded : 1;
};
@@ -108,6 +114,12 @@ struct _MetaFrameGeometry
int right_titlebar_edge;
int top_titlebar_edge;
int bottom_titlebar_edge;
+
+ /* Round corners */
+ guint top_left_corner_rounded : 1;
+ guint top_right_corner_rounded : 1;
+ guint bottom_left_corner_rounded : 1;
+ guint bottom_right_corner_rounded : 1;
};
diff --git a/src/tools/Makefile.am b/src/tools/Makefile.am
index 5e9af94..9973db8 100644
--- a/src/tools/Makefile.am
+++ b/src/tools/Makefile.am
@@ -15,9 +15,12 @@ metacity_message_SOURCES= \
metacity_window_demo_SOURCES= \
metacity-window-demo.c
-metacity_mag_SOURCES= \
+metacity_mag_SOURCES= \
metacity-mag.c
+metacity_grayscale_SOURCES= \
+ metacity-grayscale.c
+
metacity_properties_SOURCES= \
metacity-properties.c
@@ -35,13 +38,14 @@ desktop_DATA=$(Desktop_in_files:.desktop.in=.desktop)
bin_PROGRAMS=metacity-message metacity-window-demo metacity-properties
-## cheesy hack I use, doesn't really have any business existing. ;-)
-noinst_PROGRAMS=metacity-mag
+## cheesy hacks I use, don't really have any business existing. ;-)
+noinst_PROGRAMS=metacity-mag metacity-grayscale
metacity_message_LDADD= @METACITY_MESSAGE_LIBS@
metacity_window_demo_LDADD= @METACITY_WINDOW_DEMO_LIBS@
metacity_properties_LDADD= @METACITY_PROPS_LIBS@
metacity_mag_LDADD= @METACITY_WINDOW_DEMO_LIBS@
+metacity_grayscale_LDADD = @METACITY_WINDOW_DEMO_LIBS@
EXTRA_DIST=$(icon_DATA) $(ui_DATA) $(propicon_DATA) $(Desktop_in_files)
diff --git a/src/tools/metacity-grayscale.c b/src/tools/metacity-grayscale.c
new file mode 100644
index 0000000..8d0cd68
--- /dev/null
+++ b/src/tools/metacity-grayscale.c
@@ -0,0 +1,109 @@
+/* Hack for grayscaling an image */
+
+/*
+ * Copyright (C) 2002 Red Hat Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#include <gdk-pixbuf/gdk-pixbuf.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <math.h>
+
+#define INTENSITY(r, g, b) ((r) * 0.30 + (g) * 0.59 + (b) * 0.11)
+
+static GdkPixbuf*
+grayscale_pixbuf (GdkPixbuf *pixbuf)
+{
+ GdkPixbuf *gray;
+ guchar *pixels;
+ int rowstride;
+ int pixstride;
+ int row;
+ int n_rows;
+ int width;
+
+ gray = gdk_pixbuf_copy (pixbuf);
+ rowstride = gdk_pixbuf_get_rowstride (gray);
+ pixstride = gdk_pixbuf_get_has_alpha (gray) ? 4 : 3;
+
+ pixels = gdk_pixbuf_get_pixels (gray);
+ n_rows = gdk_pixbuf_get_height (gray);
+ width = gdk_pixbuf_get_width (gray);
+
+ row = 0;
+ while (row < n_rows)
+ {
+ guchar *p = pixels + row * rowstride;
+ guchar *end = p + (pixstride * width);
+
+ while (p != end)
+ {
+ double v = INTENSITY (p[0], p[1], p[2]);
+
+ p[0] = (guchar) v;
+ p[1] = (guchar) v;
+ p[2] = (guchar) v;
+
+ p += pixstride;
+ }
+
+ ++row;
+ }
+
+ return gray;
+}
+
+int
+main (int argc, char **argv)
+{
+ GdkPixbuf *pixbuf;
+ GdkPixbuf *gray;
+ GError *err;
+
+ if (argc != 2)
+ {
+ g_printerr ("specify a single image on the command line\n");
+ return 1;
+ }
+
+ g_type_init ();
+
+ err = NULL;
+ pixbuf = gdk_pixbuf_new_from_file (argv[1], &err);
+ if (err != NULL)
+ {
+ g_printerr ("failed to load image: %s\n", err->message);
+ g_error_free (err);
+ return 1;
+ }
+
+ gray = grayscale_pixbuf (pixbuf);
+
+ err = NULL;
+ gdk_pixbuf_save (gray, "grayscale.png", "png", &err, NULL);
+ if (err != NULL)
+ {
+ g_printerr ("failed to save image: %s\n", err->message);
+ g_error_free (err);
+ return 1;
+ }
+
+ g_print ("wrote grayscale.png\n");
+
+ return 0;
+}
diff --git a/src/ui.c b/src/ui.c
index d59adb9..bc9684a 100644
--- a/src/ui.c
+++ b/src/ui.c
@@ -231,6 +231,15 @@ meta_ui_reset_frame_bg (MetaUI *ui,
}
void
+meta_ui_apply_frame_shape (MetaUI *ui,
+ Window xwindow,
+ int new_window_width,
+ int new_window_height)
+{
+ meta_frames_apply_shapes (ui->frames, xwindow, new_window_width, new_window_height);
+}
+
+void
meta_ui_queue_frame_draw (MetaUI *ui,
Window xwindow)
{
diff --git a/src/ui.h b/src/ui.h
index 39b1817..5623698 100644
--- a/src/ui.h
+++ b/src/ui.h
@@ -73,6 +73,11 @@ void meta_ui_unflicker_frame_bg (MetaUI *ui,
void meta_ui_reset_frame_bg (MetaUI *ui,
Window xwindow);
+void meta_ui_apply_frame_shape (MetaUI *ui,
+ Window xwindow,
+ int new_window_width,
+ int new_window_height);
+
void meta_ui_queue_frame_draw (MetaUI *ui,
Window xwindow);