mirror of
https://github.com/brl/mutter.git
synced 2024-11-21 23:50:41 -05:00
Merge compositor branch.
2007-12-18 Iain Holmes <iain@gnome.org> * configure.in, src/theme.c, src/display.c, src/theme.h, src/display.h, src/theme-parser.c, src/compositor.c, src/c-screen.c, src/compositor.h, src/c-screen.h, src/ui.c, src/screen.c, src/ui.h, src/screen.h, src/c-window.c, src/c-window.h, src/theme-viewer.c, src/Makefile.am: Merge compositor branch. svn path=/trunk/; revision=3483
This commit is contained in:
parent
931d70d87f
commit
c2a6eeaf5e
@ -1,3 +1,12 @@
|
||||
2007-12-18 Iain Holmes <iain@gnome.org>
|
||||
|
||||
* configure.in, src/theme.c, src/display.c,
|
||||
src/theme.h, src/display.h, src/theme-parser.c,
|
||||
src/compositor.c, src/c-screen.c, src/compositor.h,
|
||||
src/c-screen.h, src/ui.c, src/screen.c, src/ui.h,
|
||||
src/screen.h, src/c-window.c, src/c-window.h,
|
||||
src/theme-viewer.c, src/Makefile.am: Merge compositor branch.
|
||||
|
||||
2007-12-14 Thomas Thurman <thomas@thurman.org.uk>
|
||||
|
||||
* configure.in: Post-release bump to 2.21.5.
|
||||
|
@ -231,7 +231,7 @@ fi
|
||||
|
||||
if test x$have_xcomposite = xyes; then
|
||||
echo "Building with CompositeExt"
|
||||
METACITY_PC_MODULES="$METACITY_PC_MODULES xcomposite >= $XCOMPOSITE_VERSION xfixes xrender xdamage cm"
|
||||
METACITY_PC_MODULES="$METACITY_PC_MODULES xcomposite >= $XCOMPOSITE_VERSION xfixes xrender xdamage"
|
||||
AC_DEFINE(HAVE_COMPOSITE_EXTENSIONS, , [Building with compositing manager support])
|
||||
|
||||
## force on render also
|
||||
@ -477,6 +477,12 @@ else
|
||||
GCONF_SCHEMAS_INSTALL_FALSE=
|
||||
fi
|
||||
|
||||
AC_ARG_ENABLE(debug,
|
||||
[ --enable-debug enable debugging],,
|
||||
enable_debug=no)
|
||||
if test "x$enable_debug" = "xyes"; then
|
||||
CFLAGS="$CFLAGS -g -O -Wall"
|
||||
fi
|
||||
AC_CONFIG_FILES([
|
||||
Makefile
|
||||
doc/Makefile
|
||||
|
@ -12,10 +12,6 @@ metacity_SOURCES= \
|
||||
boxes.h \
|
||||
boxes.c \
|
||||
common.h \
|
||||
c-screen.c \
|
||||
c-screen.h \
|
||||
c-window.c \
|
||||
c-window.h \
|
||||
compositor.c \
|
||||
compositor.h \
|
||||
constraints.c \
|
||||
|
677
src/c-screen.c
677
src/c-screen.c
@ -1,677 +0,0 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/*
|
||||
* Copyright (C) 2006 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 <config.h>
|
||||
|
||||
#ifdef HAVE_COMPOSITE_EXTENSIONS
|
||||
#include <cm/ws.h>
|
||||
#include <cm/stacker.h>
|
||||
#include <cm/wsint.h>
|
||||
#include <cm/drawable-node.h>
|
||||
#include <cm/state.h>
|
||||
#include <cm/magnifier.h>
|
||||
#include <cm/square.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "screen.h"
|
||||
#include "c-screen.h"
|
||||
#include "c-window.h"
|
||||
|
||||
struct MetaCompScreen
|
||||
{
|
||||
WsDisplay *display;
|
||||
CmStacker *stacker;
|
||||
CmMagnifier *magnifier;
|
||||
|
||||
WsWindow *gl_window;
|
||||
WsWindow *root_window;
|
||||
|
||||
WsScreen *screen;
|
||||
MetaScreen *meta_screen;
|
||||
|
||||
int repaint_id;
|
||||
int idle_id;
|
||||
|
||||
WsWindow *selection_window;
|
||||
|
||||
GHashTable *windows_by_xid;
|
||||
};
|
||||
|
||||
static MetaCompWindow *
|
||||
meta_comp_window_lookup (MetaCompScreen *info,
|
||||
Window xid)
|
||||
{
|
||||
MetaCompWindow *window;
|
||||
|
||||
window = g_hash_table_lookup (info->windows_by_xid, (gpointer)xid);
|
||||
|
||||
return window;
|
||||
}
|
||||
|
||||
MetaCompWindow *
|
||||
meta_comp_screen_lookup_window (MetaCompScreen *info,
|
||||
Window xwindow)
|
||||
{
|
||||
return meta_comp_window_lookup (info, xwindow);
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void
|
||||
update_frame_counter (void)
|
||||
{
|
||||
#define BUFSIZE 128
|
||||
static GTimer *timer;
|
||||
static double buffer [BUFSIZE];
|
||||
static int next = 0;
|
||||
|
||||
if (!timer)
|
||||
timer = g_timer_new ();
|
||||
|
||||
buffer[next++] = g_timer_elapsed (timer, NULL);
|
||||
|
||||
if (next == BUFSIZE)
|
||||
{
|
||||
int i;
|
||||
double total;
|
||||
|
||||
next = 0;
|
||||
|
||||
total = 0.0;
|
||||
for (i = 1; i < BUFSIZE; ++i)
|
||||
total += buffer[i] - buffer[i - 1];
|
||||
|
||||
g_print ("frames per second: %f\n", 1 / (total / (BUFSIZE - 1)));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
dump_stacking_order (GList *nodes)
|
||||
{
|
||||
GList *list;
|
||||
|
||||
for (list = nodes; list != NULL; list = list->next)
|
||||
{
|
||||
CmDrawableNode *node = list->data;
|
||||
|
||||
if (node)
|
||||
g_print ("%lx, ", WS_RESOURCE_XID (node->drawable));
|
||||
}
|
||||
g_print ("\n");
|
||||
}
|
||||
|
||||
static gboolean
|
||||
repaint (gpointer data)
|
||||
{
|
||||
MetaCompScreen *info = data;
|
||||
CmState *state;
|
||||
#if 0
|
||||
g_print ("repaint\n");
|
||||
#endif
|
||||
glViewport (0, 0,
|
||||
info->meta_screen->rect.width,
|
||||
info->meta_screen->rect.height);
|
||||
|
||||
glLoadIdentity();
|
||||
|
||||
#if 0
|
||||
glClearColor (0, 0, 0, 1.0);
|
||||
glClear (GL_COLOR_BUFFER_BIT);
|
||||
#endif
|
||||
|
||||
ws_window_raise (info->gl_window);
|
||||
|
||||
#if 0
|
||||
glDisable (GL_TEXTURE_2D);
|
||||
glDisable (GL_TEXTURE_RECTANGLE_ARB);
|
||||
glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
|
||||
glColor4f (0.0, 1.0, 0.0, 1.0);
|
||||
glRectf (-1.0, -1.0, 1.0, 1.0);
|
||||
glFinish();
|
||||
#endif
|
||||
|
||||
state = cm_state_new ();
|
||||
|
||||
cm_state_disable_depth_buffer_update (state);
|
||||
|
||||
cm_node_render (CM_NODE (info->magnifier), state);
|
||||
|
||||
cm_state_enable_depth_buffer_update (state);
|
||||
|
||||
g_object_unref (state);
|
||||
|
||||
ws_window_gl_swap_buffers (info->gl_window);
|
||||
glFinish();
|
||||
|
||||
#if 0
|
||||
dump_stacking_order (info->stacker->children);
|
||||
#endif
|
||||
|
||||
info->idle_id = 0;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static MetaCompWindow *
|
||||
find_comp_window (MetaCompScreen *info,
|
||||
Window xwindow)
|
||||
{
|
||||
return meta_comp_window_lookup (info, xwindow);
|
||||
}
|
||||
|
||||
static CmNode *
|
||||
find_node (MetaCompScreen *info,
|
||||
Window xwindow)
|
||||
{
|
||||
MetaCompWindow *window = meta_comp_window_lookup (info, xwindow);
|
||||
|
||||
if (window)
|
||||
return meta_comp_window_get_node (window);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static GList *all_screen_infos;
|
||||
|
||||
MetaCompScreen *
|
||||
meta_comp_screen_get_by_xwindow (Window xwindow)
|
||||
{
|
||||
GList *list;
|
||||
|
||||
for (list = all_screen_infos; list != NULL; list = list->next)
|
||||
{
|
||||
MetaCompScreen *info = list->data;
|
||||
|
||||
if (find_node (info, xwindow))
|
||||
return info;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
MetaCompScreen *
|
||||
meta_comp_screen_new (WsDisplay *display,
|
||||
MetaScreen *screen)
|
||||
{
|
||||
MetaCompScreen *scr_info = g_new0 (MetaCompScreen, 1);
|
||||
|
||||
scr_info->screen = ws_display_get_screen_from_number (
|
||||
display, screen->number);
|
||||
scr_info->root_window = ws_screen_get_root_window (scr_info->screen);
|
||||
scr_info->display = display;
|
||||
scr_info->meta_screen = screen;
|
||||
scr_info->windows_by_xid = g_hash_table_new (g_direct_hash, g_direct_equal);
|
||||
|
||||
all_screen_infos = g_list_prepend (all_screen_infos, scr_info);
|
||||
|
||||
return scr_info;
|
||||
}
|
||||
|
||||
static char *
|
||||
make_selection_name (MetaCompScreen *info)
|
||||
{
|
||||
char *buffer;
|
||||
|
||||
buffer = g_strdup_printf ("_NET_WM_CM_S%d", info->meta_screen->number);
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
static void
|
||||
on_selection_clear (WsWindow *window,
|
||||
WsSelectionClearEvent *event,
|
||||
gpointer data)
|
||||
{
|
||||
MetaCompScreen *info = data;
|
||||
char *buffer = make_selection_name (info);
|
||||
|
||||
if (strcmp (event->selection, buffer))
|
||||
{
|
||||
/* We lost the selection */
|
||||
meta_comp_screen_unredirect (info);
|
||||
}
|
||||
}
|
||||
|
||||
static WsWindow *
|
||||
claim_selection (MetaCompScreen *info)
|
||||
{
|
||||
WsWindow *window = ws_window_new (info->root_window);
|
||||
char *buffer = make_selection_name (info);
|
||||
|
||||
#if 0
|
||||
g_print ("selection window: %lx\n", WS_RESOURCE_XID (window));
|
||||
#endif
|
||||
|
||||
ws_window_own_selection (window, buffer, WS_CURRENT_TIME);
|
||||
|
||||
g_signal_connect (window, "selection_clear_event", G_CALLBACK (on_selection_clear), info);
|
||||
|
||||
g_free (buffer);
|
||||
|
||||
return window;
|
||||
}
|
||||
|
||||
static void
|
||||
queue_paint (CmNode *node,
|
||||
MetaCompScreen *info)
|
||||
{
|
||||
#if 0
|
||||
g_print ("queueing %s\n", G_OBJECT_TYPE_NAME (node));
|
||||
#endif
|
||||
meta_comp_screen_queue_paint (info);
|
||||
}
|
||||
|
||||
void
|
||||
meta_comp_screen_redirect (MetaCompScreen *info)
|
||||
{
|
||||
WsWindow *root = ws_screen_get_root_window (info->screen);
|
||||
WsRectangle source;
|
||||
WsRectangle target;
|
||||
WsServerRegion *region;
|
||||
int screen_w;
|
||||
int screen_h;
|
||||
CmSquare *square;
|
||||
|
||||
#if 0
|
||||
g_print ("redirecting %lx\n", WS_RESOURCE_XID (root));
|
||||
#endif
|
||||
|
||||
ws_window_redirect_subwindows (root);
|
||||
info->gl_window = ws_screen_get_gl_window (info->screen);
|
||||
/* FIXME: This should probably happen in libcm */
|
||||
ws_window_set_override_redirect (info->gl_window, TRUE);
|
||||
region = ws_server_region_new (info->display);
|
||||
ws_window_set_input_shape (info->gl_window, region);
|
||||
g_object_unref (G_OBJECT (region));
|
||||
|
||||
ws_display_begin_error_trap (info->display);
|
||||
|
||||
ws_window_unredirect (info->gl_window);
|
||||
|
||||
ws_display_end_error_trap (info->display);
|
||||
|
||||
info->selection_window = claim_selection (info);
|
||||
|
||||
ws_window_map (info->gl_window);
|
||||
|
||||
info->stacker = cm_stacker_new ();
|
||||
|
||||
square = cm_square_new (0.3, 0.3, 0.8, 1.0);
|
||||
|
||||
cm_stacker_add_child (info->stacker, CM_NODE (square));
|
||||
|
||||
g_object_unref (square);
|
||||
|
||||
screen_w = ws_screen_get_width (info->screen);
|
||||
screen_h = ws_screen_get_height (info->screen);
|
||||
|
||||
#if 0
|
||||
g_print ("width: %d height %d\n", screen_w, screen_h);
|
||||
#endif
|
||||
|
||||
source.x = (screen_w - (screen_w / 4)) / 2;
|
||||
source.y = screen_h / 16;
|
||||
source.width = screen_w / 4;
|
||||
source.height = screen_h / 16;
|
||||
|
||||
target.x = 0;
|
||||
target.y = screen_h - screen_h / 4;
|
||||
target.width = screen_w;
|
||||
target.height = screen_h / 4;
|
||||
|
||||
info->magnifier = cm_magnifier_new (CM_NODE (info->stacker), &source, &target);
|
||||
|
||||
if (g_getenv ("USE_MAGNIFIER"))
|
||||
cm_magnifier_set_active (info->magnifier, TRUE);
|
||||
else
|
||||
cm_magnifier_set_active (info->magnifier, FALSE);
|
||||
|
||||
info->repaint_id =
|
||||
g_signal_connect (info->magnifier, "need_repaint",
|
||||
G_CALLBACK (queue_paint), info);
|
||||
|
||||
ws_display_sync (info->display);
|
||||
}
|
||||
|
||||
static void
|
||||
listify (gpointer key,
|
||||
gpointer value,
|
||||
gpointer data)
|
||||
{
|
||||
GList **windows = data;
|
||||
|
||||
*windows = g_list_prepend (*windows, (gpointer)value);
|
||||
}
|
||||
|
||||
static void
|
||||
free_all_windows (MetaCompScreen *info)
|
||||
{
|
||||
GList *windows = NULL, *list;
|
||||
|
||||
g_hash_table_foreach (info->windows_by_xid, listify, &windows);
|
||||
|
||||
for (list = windows; list != NULL; list = list->next)
|
||||
{
|
||||
MetaCompWindow *window = list->data;
|
||||
|
||||
meta_comp_window_free (window);
|
||||
}
|
||||
|
||||
g_list_free (windows);
|
||||
}
|
||||
|
||||
void
|
||||
meta_comp_screen_unredirect (MetaCompScreen *info)
|
||||
{
|
||||
WsScreen *ws_screen = info->screen;
|
||||
WsWindow *root = ws_screen_get_root_window (ws_screen);
|
||||
|
||||
g_signal_handler_disconnect (info->magnifier, info->repaint_id);
|
||||
g_object_unref (info->magnifier);
|
||||
|
||||
ws_window_unredirect_subwindows (root);
|
||||
ws_screen_release_gl_window (ws_screen);
|
||||
|
||||
free_all_windows (info);
|
||||
|
||||
ws_display_sync (info->display);
|
||||
|
||||
/* FIXME: libcm needs a way to guarantee that a window is destroyed,
|
||||
* without relying on ref counting having it as a side effect
|
||||
*/
|
||||
g_object_unref (info->selection_window);
|
||||
}
|
||||
|
||||
void
|
||||
meta_comp_screen_queue_paint (MetaCompScreen *info)
|
||||
{
|
||||
#if 0
|
||||
g_print ("queuing\n");
|
||||
#endif
|
||||
if (!info->idle_id)
|
||||
info->idle_id = g_idle_add (repaint, info);
|
||||
}
|
||||
|
||||
void
|
||||
meta_comp_screen_restack (MetaCompScreen *info,
|
||||
Window window,
|
||||
Window above_this)
|
||||
{
|
||||
MetaCompWindow *comp_window = find_comp_window (info, window);
|
||||
MetaCompWindow *above_comp_window = find_comp_window (info, above_this);
|
||||
CmNode *window_node = find_node (info, window);
|
||||
CmNode *above_node = find_node (info, above_this);
|
||||
|
||||
if ((comp_window && meta_comp_window_stack_frozen (comp_window)) ||
|
||||
(above_comp_window && meta_comp_window_stack_frozen (above_comp_window)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
#if 0
|
||||
dump_stacking_order (info->stacker->children);
|
||||
#endif
|
||||
|
||||
if (window_node == above_node)
|
||||
return;
|
||||
|
||||
if (window_node && above_this == WS_RESOURCE_XID (info->gl_window))
|
||||
{
|
||||
cm_stacker_raise_child (info->stacker, window_node);
|
||||
}
|
||||
else if (window_node && above_this == None)
|
||||
{
|
||||
cm_stacker_lower_child (info->stacker, window_node);
|
||||
}
|
||||
else if (window_node && above_node)
|
||||
{
|
||||
cm_stacker_restack_child (info->stacker, window_node, above_node);
|
||||
}
|
||||
#if 0
|
||||
else
|
||||
g_print ("nothing happened\n");
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
g_print ("done restacking; new order:\n");
|
||||
#endif
|
||||
#if 0
|
||||
dump_stacking_order (info->stacker->children);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
meta_comp_screen_raise_window (MetaCompScreen *info,
|
||||
Window window)
|
||||
{
|
||||
CmNode *node = find_node (info, window);
|
||||
|
||||
if (node)
|
||||
cm_stacker_raise_child (info->stacker, node);
|
||||
}
|
||||
|
||||
void
|
||||
meta_comp_screen_set_size (MetaCompScreen *info,
|
||||
Window xwindow,
|
||||
gint x,
|
||||
gint y,
|
||||
gint width,
|
||||
gint height)
|
||||
{
|
||||
MetaCompWindow *comp_window = meta_comp_window_lookup (info, xwindow);
|
||||
|
||||
if (comp_window)
|
||||
{
|
||||
WsRectangle rect;
|
||||
|
||||
rect.x = x;
|
||||
rect.y = y;
|
||||
rect.width = width;
|
||||
rect.height = height;
|
||||
|
||||
meta_comp_window_set_size (comp_window, &rect);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
print_child_titles (WsWindow *window)
|
||||
{
|
||||
GList *children = ws_window_query_subwindows (window);
|
||||
GList *list;
|
||||
int i;
|
||||
|
||||
g_print ("window: %lx %s\n", WS_RESOURCE_XID (window), ws_window_query_title (window));
|
||||
|
||||
i = 0;
|
||||
for (list = children; list != NULL; list = list->next)
|
||||
{
|
||||
WsWindow *child = list->data;
|
||||
|
||||
g_print (" %d adding: %lx %s\n", i++, WS_RESOURCE_XID (child), ws_window_query_title (child));
|
||||
}
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
MetaCompScreen *cscreen;
|
||||
XID xid;
|
||||
} DestroyData;
|
||||
|
||||
static void
|
||||
on_window_destroy (MetaCompWindow *comp_window,
|
||||
gpointer closure)
|
||||
{
|
||||
DestroyData *data = closure;
|
||||
CmNode *node = meta_comp_window_get_node (comp_window);
|
||||
|
||||
cm_stacker_remove_child (data->cscreen->stacker, node);
|
||||
g_hash_table_remove (data->cscreen->windows_by_xid, (gpointer)data->xid);
|
||||
}
|
||||
|
||||
void
|
||||
meta_comp_screen_add_window (MetaCompScreen *info,
|
||||
Window xwindow)
|
||||
{
|
||||
WsDrawable *drawable;
|
||||
MetaCompWindow *comp_window;
|
||||
DestroyData *data;
|
||||
|
||||
ws_display_begin_error_trap (info->display);
|
||||
|
||||
comp_window = meta_comp_window_lookup (info, xwindow);
|
||||
|
||||
if (comp_window)
|
||||
goto out;
|
||||
|
||||
drawable = WS_DRAWABLE (ws_window_lookup (info->display, xwindow));
|
||||
|
||||
if (ws_window_query_input_only (WS_WINDOW (drawable)))
|
||||
goto out;
|
||||
|
||||
if (WS_WINDOW (drawable) == info->gl_window ||
|
||||
WS_WINDOW (drawable) == info->screen->overlay_window)
|
||||
{
|
||||
#if 0
|
||||
g_print ("gl window\n");
|
||||
#endif
|
||||
goto out;
|
||||
}
|
||||
|
||||
data = g_new (DestroyData, 1);
|
||||
data->cscreen = info;
|
||||
data->xid = WS_RESOURCE_XID (drawable);
|
||||
|
||||
comp_window = meta_comp_window_new (info->meta_screen, drawable,
|
||||
on_window_destroy, data);
|
||||
|
||||
g_hash_table_insert (info->windows_by_xid, (gpointer)WS_RESOURCE_XID (drawable), comp_window);
|
||||
|
||||
cm_stacker_add_child (info->stacker, meta_comp_window_get_node (comp_window));
|
||||
|
||||
out:
|
||||
if (comp_window)
|
||||
{
|
||||
/* This function is called both when windows are created and when they
|
||||
* are mapped, so for now we have this silly function.
|
||||
*/
|
||||
meta_comp_window_refresh_attrs (comp_window);
|
||||
}
|
||||
|
||||
ws_display_end_error_trap (info->display);
|
||||
|
||||
#if 0
|
||||
g_print ("done checking\n");
|
||||
#endif
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
meta_comp_screen_remove_window (MetaCompScreen *info,
|
||||
Window xwindow)
|
||||
{
|
||||
MetaCompWindow *comp_window = meta_comp_window_lookup (info, xwindow);
|
||||
|
||||
if (comp_window)
|
||||
meta_comp_window_free (comp_window);
|
||||
}
|
||||
|
||||
void
|
||||
meta_comp_screen_set_updates (MetaCompScreen *info,
|
||||
Window xwindow,
|
||||
gboolean updates)
|
||||
{
|
||||
MetaCompWindow *comp_window = meta_comp_window_lookup (info, xwindow);
|
||||
|
||||
meta_comp_window_set_updates (comp_window, updates);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
meta_comp_screen_set_patch (MetaCompScreen *info,
|
||||
Window xwindow,
|
||||
CmPoint points[4][4])
|
||||
{
|
||||
CmDrawableNode *node = CM_DRAWABLE_NODE (find_node (info, xwindow));
|
||||
|
||||
if (node)
|
||||
cm_drawable_node_set_patch (node, points);
|
||||
}
|
||||
|
||||
void
|
||||
meta_comp_screen_unset_patch (MetaCompScreen *info,
|
||||
Window xwindow)
|
||||
{
|
||||
CmDrawableNode *node = CM_DRAWABLE_NODE (find_node (info, xwindow));
|
||||
|
||||
if (node)
|
||||
cm_drawable_node_unset_patch (node);
|
||||
}
|
||||
|
||||
void
|
||||
meta_comp_screen_set_alpha (MetaCompScreen *info,
|
||||
Window xwindow,
|
||||
gdouble alpha)
|
||||
{
|
||||
CmDrawableNode *node = CM_DRAWABLE_NODE (find_node (info, xwindow));
|
||||
#if 0
|
||||
g_print ("alpha: %f\n", alpha);
|
||||
#endif
|
||||
cm_drawable_node_set_alpha (node, alpha);
|
||||
}
|
||||
|
||||
void
|
||||
meta_comp_screen_get_real_size (MetaCompScreen *info,
|
||||
Window xwindow,
|
||||
WsRectangle *size)
|
||||
{
|
||||
CmDrawableNode *node = CM_DRAWABLE_NODE (find_node (info, xwindow));
|
||||
|
||||
if (!size)
|
||||
return;
|
||||
|
||||
cm_drawable_node_get_clipbox (node, size);
|
||||
}
|
||||
|
||||
void
|
||||
meta_comp_screen_unmap (MetaCompScreen *info,
|
||||
Window xwindow)
|
||||
{
|
||||
MetaCompWindow *window = find_comp_window (info, xwindow);
|
||||
|
||||
if (window)
|
||||
meta_comp_window_hide (window);
|
||||
}
|
||||
|
||||
void
|
||||
meta_comp_screen_set_target_rect (MetaCompScreen *info,
|
||||
Window xwindow,
|
||||
WsRectangle *rect)
|
||||
{
|
||||
CmDrawableNode *node = CM_DRAWABLE_NODE (find_node (info, xwindow));
|
||||
|
||||
if (node)
|
||||
cm_drawable_node_set_scale_rect (node, rect);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -1,53 +0,0 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
#include "screen.h"
|
||||
#include "c-window.h"
|
||||
|
||||
typedef struct MetaCompScreen MetaCompScreen;
|
||||
|
||||
MetaCompScreen *meta_comp_screen_new (WsDisplay *display,
|
||||
MetaScreen *screen);
|
||||
MetaCompScreen *meta_comp_screen_get_by_xwindow (Window xwindow);
|
||||
void meta_comp_screen_destroy (MetaCompScreen *scr_info);
|
||||
void meta_comp_screen_redirect (MetaCompScreen *info);
|
||||
void meta_comp_screen_unredirect (MetaCompScreen *info);
|
||||
void meta_comp_screen_add_window (MetaCompScreen *scr_info,
|
||||
Window xwindow);
|
||||
void meta_comp_screen_remove_window (MetaCompScreen *scr_info,
|
||||
Window xwindow);
|
||||
void meta_comp_screen_restack (MetaCompScreen *scr_info,
|
||||
Window window,
|
||||
Window above_this);
|
||||
void meta_comp_screen_set_size (MetaCompScreen *info,
|
||||
Window window,
|
||||
gint x,
|
||||
gint y,
|
||||
gint width,
|
||||
gint height);
|
||||
void meta_comp_screen_raise_window (MetaCompScreen *scr_info,
|
||||
Window window);
|
||||
void meta_comp_screen_queue_paint (MetaCompScreen *info);
|
||||
void meta_comp_screen_set_updates (MetaCompScreen *info,
|
||||
Window xwindow,
|
||||
gboolean updates);
|
||||
void meta_comp_screen_set_patch (MetaCompScreen *info,
|
||||
Window xwindow,
|
||||
CmPoint points[4][4]);
|
||||
void meta_comp_screen_unset_patch (MetaCompScreen *info,
|
||||
Window xwindow);
|
||||
void meta_comp_screen_set_alpha (MetaCompScreen *info,
|
||||
Window xwindow,
|
||||
gdouble alpha);
|
||||
void meta_comp_screen_get_real_size (MetaCompScreen *info,
|
||||
Window xwindow,
|
||||
WsRectangle *size);
|
||||
void meta_comp_screen_set_target_rect (MetaCompScreen *info,
|
||||
Window xwindow,
|
||||
WsRectangle *rect);
|
||||
void meta_comp_screen_set_explode (MetaCompScreen *info,
|
||||
Window xwindow,
|
||||
gdouble level);
|
||||
void meta_comp_screen_unmap (MetaCompScreen *info,
|
||||
Window xwindow);
|
||||
MetaCompWindow *meta_comp_screen_lookup_window (MetaCompScreen *info,
|
||||
Window xwindow);
|
1259
src/c-window.c
1259
src/c-window.c
File diff suppressed because it is too large
Load Diff
@ -1,72 +0,0 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
/*
|
||||
* Copyright (C) 2006 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 <cm/node.h>
|
||||
#include "display.h"
|
||||
#include "effects.h"
|
||||
|
||||
#ifndef C_WINDOW_H
|
||||
#define C_WINDOW_H
|
||||
|
||||
typedef struct _MetaCompWindow MetaCompWindow;
|
||||
|
||||
typedef void (* MetaCompWindowDestroy) (MetaCompWindow *window,
|
||||
gpointer closure);
|
||||
|
||||
MetaCompWindow *meta_comp_window_new (MetaScreen *screen,
|
||||
WsDrawable *drawable,
|
||||
MetaCompWindowDestroy destroy,
|
||||
gpointer data);
|
||||
CmNode *meta_comp_window_get_node (MetaCompWindow *window);
|
||||
gboolean meta_comp_window_free (MetaCompWindow *window);
|
||||
void meta_comp_window_set_size (MetaCompWindow *window,
|
||||
WsRectangle *size);
|
||||
|
||||
void meta_comp_window_hide (MetaCompWindow *comp_window);
|
||||
void meta_comp_window_show (MetaCompWindow *comp_window);
|
||||
void meta_comp_window_refresh_attrs (MetaCompWindow *comp_window);
|
||||
void meta_comp_window_set_updates (MetaCompWindow *comp_window,
|
||||
gboolean updates);
|
||||
|
||||
void meta_comp_window_explode (MetaCompWindow *comp_window,
|
||||
MetaEffect *effect);
|
||||
void meta_comp_window_shrink (MetaCompWindow *comp_window,
|
||||
MetaEffect *effect);
|
||||
void meta_comp_window_unshrink (MetaCompWindow *comp_window,
|
||||
MetaEffect *effect);
|
||||
void meta_comp_window_run_focus (MetaCompWindow *comp_window,
|
||||
MetaEffect *effect);
|
||||
void meta_comp_window_restack (MetaCompWindow *comp_window,
|
||||
MetaCompWindow *above);
|
||||
void meta_comp_window_freeze_stack (MetaCompWindow *comp_window);
|
||||
void meta_comp_window_thaw_stack (MetaCompWindow *comp_window);
|
||||
gboolean meta_comp_window_stack_frozen (MetaCompWindow *comp_window);
|
||||
void meta_comp_window_run_minimize (MetaCompWindow *window,
|
||||
MetaEffect *effect);
|
||||
void meta_comp_window_run_unminimize (MetaCompWindow *comp_window,
|
||||
MetaEffect *effect);
|
||||
|
||||
#if 0
|
||||
void meta_comp_window_set_explode (MetaCompWindow *comp_window,
|
||||
double level);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
3149
src/compositor.c
3149
src/compositor.c
File diff suppressed because it is too large
Load Diff
@ -28,23 +28,12 @@
|
||||
#include "display.h"
|
||||
#include "spring-model.h"
|
||||
|
||||
#ifdef HAVE_COMPOSITE_EXTENSIONS
|
||||
#include "cm/deform.h"
|
||||
/* FIXME: Needs namespacing. */
|
||||
void get_patch_points (Model *model, CmPoint points[4][4]);
|
||||
#endif
|
||||
|
||||
typedef void (* MetaAnimationFinishedFunc) (gpointer data);
|
||||
|
||||
/* XXX namespace me */
|
||||
void compute_window_rect (MetaWindow *window, MetaRectangle *rect);
|
||||
|
||||
MetaCompositor* meta_compositor_new (MetaDisplay *display);
|
||||
void meta_compositor_unref (MetaCompositor *compositor);
|
||||
void meta_compositor_process_event (MetaCompositor *compositor,
|
||||
XEvent *xevent,
|
||||
MetaWindow *window);
|
||||
void meta_compositor_add_window (MetaCompositor *compositor,
|
||||
MetaWindow *window,
|
||||
Window xwindow,
|
||||
XWindowAttributes *attrs);
|
||||
void meta_compositor_remove_window (MetaCompositor *compositor,
|
||||
@ -57,23 +46,11 @@ void meta_compositor_manage_screen (MetaCompositor *compositor,
|
||||
void meta_compositor_unmanage_screen (MetaCompositor *compositor,
|
||||
MetaScreen *screen);
|
||||
|
||||
#if 0
|
||||
void meta_compositor_minimize (MetaCompositor *compositor,
|
||||
MetaWindow *window,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height,
|
||||
MetaAnimationFinishedFunc finished_cb,
|
||||
gpointer finished_data);
|
||||
#endif
|
||||
void meta_compositor_set_updates (MetaCompositor *compositor,
|
||||
MetaWindow *window,
|
||||
gboolean updates);
|
||||
|
||||
void
|
||||
meta_compositor_set_updates (MetaCompositor *compositor,
|
||||
MetaWindow *window,
|
||||
gboolean updates);
|
||||
void
|
||||
meta_compositor_destroy (MetaCompositor *compositor);
|
||||
void meta_compositor_destroy (MetaCompositor *compositor);
|
||||
|
||||
void meta_compositor_begin_move (MetaCompositor *compositor,
|
||||
MetaWindow *window,
|
||||
@ -86,7 +63,7 @@ void meta_compositor_end_move (MetaCompositor *compositor,
|
||||
MetaWindow *window);
|
||||
void meta_compositor_free_window (MetaCompositor *compositor,
|
||||
MetaWindow *window);
|
||||
void meta_compositor_free_window (MetaCompositor *compositor,
|
||||
MetaWindow *window);
|
||||
Pixmap meta_compositor_get_window_pixmap (MetaCompositor *compositor,
|
||||
MetaWindow *window);
|
||||
|
||||
#endif /* META_COMPOSITOR_H */
|
||||
|
106
src/display.c
106
src/display.c
@ -65,6 +65,11 @@
|
||||
#ifdef HAVE_XCURSOR
|
||||
#include <X11/Xcursor/Xcursor.h>
|
||||
#endif
|
||||
#ifdef HAVE_COMPOSITE_EXTENSIONS
|
||||
#include <X11/extensions/Xcomposite.h>
|
||||
#include <X11/extensions/Xdamage.h>
|
||||
#include <X11/extensions/Xfixes.h>
|
||||
#endif
|
||||
#include <string.h>
|
||||
|
||||
#define GRAB_OP_IS_WINDOW_SWITCH(g) \
|
||||
@ -186,10 +191,23 @@ sn_error_trap_pop (SnDisplay *sn_display,
|
||||
#endif
|
||||
|
||||
static void
|
||||
enable_compositor (MetaDisplay *display)
|
||||
enable_compositor (MetaDisplay *display,
|
||||
gboolean composite_windows)
|
||||
{
|
||||
GSList *list;
|
||||
|
||||
if (!META_DISPLAY_HAS_COMPOSITE (display) ||
|
||||
!META_DISPLAY_HAS_DAMAGE (display) ||
|
||||
!META_DISPLAY_HAS_XFIXES (display) ||
|
||||
!META_DISPLAY_HAS_RENDER (display))
|
||||
{
|
||||
meta_warning (_("Missing %s extension required for compositing"),
|
||||
!META_DISPLAY_HAS_COMPOSITE (display) ? "composite" :
|
||||
!META_DISPLAY_HAS_DAMAGE (display) ? "damage" :
|
||||
!META_DISPLAY_HAS_XFIXES (display) ? "xfixes" : "render");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!display->compositor)
|
||||
display->compositor = meta_compositor_new (display);
|
||||
|
||||
@ -203,7 +221,8 @@ enable_compositor (MetaDisplay *display)
|
||||
meta_compositor_manage_screen (screen->display->compositor,
|
||||
screen);
|
||||
|
||||
meta_screen_composite_all_windows (screen);
|
||||
if (composite_windows)
|
||||
meta_screen_composite_all_windows (screen);
|
||||
}
|
||||
}
|
||||
|
||||
@ -336,7 +355,7 @@ meta_display_open (void)
|
||||
"_NET_WM_VISIBLE_ICON_NAME",
|
||||
"_NET_WM_USER_TIME_WINDOW",
|
||||
"_NET_WM_ACTION_ABOVE",
|
||||
"_NET_WM_ACTION_BELOW"
|
||||
"_NET_WM_ACTION_BELOW",
|
||||
};
|
||||
Atom atoms[G_N_ELEMENTS(atom_names)];
|
||||
|
||||
@ -398,7 +417,8 @@ meta_display_open (void)
|
||||
update_window_grab_modifiers (display);
|
||||
|
||||
meta_prefs_add_listener (prefs_changed_callback, display);
|
||||
|
||||
|
||||
meta_verbose ("Creating %d atoms\n", G_N_ELEMENTS (atom_names));
|
||||
XInternAtoms (display->xdisplay, atom_names, G_N_ELEMENTS (atom_names),
|
||||
False, atoms);
|
||||
display->atom_net_wm_name = atoms[0];
|
||||
@ -647,6 +667,69 @@ meta_display_open (void)
|
||||
meta_verbose ("Not compiled with Render support\n");
|
||||
#endif /* !HAVE_RENDER */
|
||||
|
||||
#ifdef HAVE_COMPOSITE_EXTENSIONS
|
||||
{
|
||||
display->have_composite = FALSE;
|
||||
|
||||
display->composite_error_base = 0;
|
||||
display->composite_event_base = 0;
|
||||
|
||||
if (!XCompositeQueryExtension (display->xdisplay,
|
||||
&display->composite_event_base,
|
||||
&display->composite_error_base))
|
||||
{
|
||||
display->composite_error_base = 0;
|
||||
display->composite_event_base = 0;
|
||||
}
|
||||
else
|
||||
display->have_composite = TRUE;
|
||||
|
||||
meta_verbose ("Attempted to init Composite, found error base %d event base %d\n",
|
||||
display->composite_error_base,
|
||||
display->composite_event_base);
|
||||
|
||||
display->have_damage = FALSE;
|
||||
|
||||
display->damage_error_base = 0;
|
||||
display->damage_event_base = 0;
|
||||
|
||||
if (!XDamageQueryExtension (display->xdisplay,
|
||||
&display->damage_event_base,
|
||||
&display->damage_error_base))
|
||||
{
|
||||
display->damage_error_base = 0;
|
||||
display->damage_event_base = 0;
|
||||
}
|
||||
else
|
||||
display->have_damage = TRUE;
|
||||
|
||||
meta_verbose ("Attempted to init Damage, found error base %d event base %d\n",
|
||||
display->damage_error_base,
|
||||
display->damage_event_base);
|
||||
|
||||
display->have_xfixes = FALSE;
|
||||
|
||||
display->xfixes_error_base = 0;
|
||||
display->xfixes_event_base = 0;
|
||||
|
||||
if (!XFixesQueryExtension (display->xdisplay,
|
||||
&display->xfixes_event_base,
|
||||
&display->xfixes_error_base))
|
||||
{
|
||||
display->xfixes_error_base = 0;
|
||||
display->xfixes_event_base = 0;
|
||||
}
|
||||
else
|
||||
display->have_xfixes = TRUE;
|
||||
|
||||
meta_verbose ("Attempted to init XFixes, found error base %d event base %d\n",
|
||||
display->xfixes_error_base,
|
||||
display->xfixes_event_base);
|
||||
}
|
||||
#else /* HAVE_COMPOSITE_EXTENSIONS */
|
||||
meta_verbose ("Not compiled with Composite support\n");
|
||||
#endif /* !HAVE_COMPOSITE_EXTENSIONS */
|
||||
|
||||
#ifdef HAVE_XCURSOR
|
||||
{
|
||||
XcursorSetTheme (display->xdisplay, meta_prefs_get_cursor_theme ());
|
||||
@ -742,7 +825,13 @@ meta_display_open (void)
|
||||
meta_display_close (display, timestamp);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/* We don't composite the windows here because they will be composited
|
||||
faster with the call to meta_screen_manage_all_windows further down
|
||||
the code */
|
||||
if (meta_prefs_get_compositing_manager ())
|
||||
enable_compositor (display, FALSE);
|
||||
|
||||
meta_display_grab (display);
|
||||
|
||||
/* Now manage all existing windows */
|
||||
@ -796,9 +885,6 @@ meta_display_open (void)
|
||||
|
||||
meta_display_ungrab (display);
|
||||
|
||||
if (meta_prefs_get_compositing_manager ())
|
||||
enable_compositor (display);
|
||||
|
||||
/* Done opening new display */
|
||||
display->display_opening = FALSE;
|
||||
|
||||
@ -939,7 +1025,7 @@ meta_display_close (MetaDisplay *display,
|
||||
meta_display_shutdown_keys (display);
|
||||
|
||||
if (display->compositor)
|
||||
meta_compositor_unref (display->compositor);
|
||||
meta_compositor_destroy (display->compositor);
|
||||
|
||||
g_free (display);
|
||||
|
||||
@ -4830,7 +4916,7 @@ prefs_changed_callback (MetaPreference pref,
|
||||
gboolean cm = meta_prefs_get_compositing_manager ();
|
||||
|
||||
if (cm)
|
||||
enable_compositor (display);
|
||||
enable_compositor (display, TRUE);
|
||||
else
|
||||
disable_compositor (display);
|
||||
}
|
||||
|
@ -47,7 +47,7 @@
|
||||
|
||||
#define meta_XFree(p) do { if ((p)) XFree ((p)); } while (0)
|
||||
|
||||
typedef struct MetaCompositor MetaCompositor;
|
||||
typedef struct _MetaCompositor MetaCompositor;
|
||||
typedef struct _MetaDisplay MetaDisplay;
|
||||
typedef struct _MetaFrame MetaFrame;
|
||||
typedef struct _MetaKeyBinding MetaKeyBinding;
|
||||
@ -354,6 +354,14 @@ struct _MetaDisplay
|
||||
int render_event_base;
|
||||
int render_error_base;
|
||||
#endif
|
||||
#ifdef HAVE_COMPOSITE_EXTENSIONS
|
||||
int composite_event_base;
|
||||
int composite_error_base;
|
||||
int damage_event_base;
|
||||
int damage_error_base;
|
||||
int xfixes_event_base;
|
||||
int xfixes_error_base;
|
||||
#endif
|
||||
#ifdef HAVE_XSYNC
|
||||
unsigned int have_xsync : 1;
|
||||
#define META_DISPLAY_HAS_XSYNC(display) ((display)->have_xsync)
|
||||
@ -372,6 +380,18 @@ struct _MetaDisplay
|
||||
#else
|
||||
#define META_DISPLAY_HAS_RENDER(display) FALSE
|
||||
#endif
|
||||
#ifdef HAVE_COMPOSITE_EXTENSIONS
|
||||
unsigned int have_composite : 1;
|
||||
unsigned int have_damage : 1;
|
||||
unsigned int have_xfixes : 1;
|
||||
#define META_DISPLAY_HAS_COMPOSITE(display) ((display)->have_composite)
|
||||
#define META_DISPLAY_HAS_DAMAGE(display) ((display)->have_damage)
|
||||
#define META_DISPLAY_HAS_XFIXES(display) ((display)->have_xfixes)
|
||||
#else
|
||||
#define META_DISPLAY_HAS_COMPOSITE(display) FALSE
|
||||
#define META_DISPLAY_HAS_DAMAGE(display) FALSE
|
||||
#define META_DISPLAY_HAS_XFIXES(display) FALSE
|
||||
#endif
|
||||
};
|
||||
|
||||
/* Xserver time can wraparound, thus comparing two timestamps needs to take
|
||||
|
148
src/screen.c
148
src/screen.c
@ -535,7 +535,12 @@ meta_screen_new (MetaDisplay *display,
|
||||
screen->wm_sn_selection_window = new_wm_sn_owner;
|
||||
screen->wm_sn_atom = wm_sn_atom;
|
||||
screen->wm_sn_timestamp = manager_timestamp;
|
||||
|
||||
|
||||
#ifdef HAVE_COMPOSITE_EXTENSIONS
|
||||
screen->wm_cm_selection_window = meta_create_offscreen_window (xdisplay,
|
||||
xroot,
|
||||
NoEventMask);
|
||||
#endif
|
||||
screen->work_area_idle = 0;
|
||||
|
||||
screen->active_workspace = NULL;
|
||||
@ -807,9 +812,23 @@ meta_screen_manage_all_windows (MetaScreen *screen)
|
||||
for (list = windows; list != NULL; list = list->next)
|
||||
{
|
||||
WindowInfo *info = list->data;
|
||||
MetaWindow *window;
|
||||
|
||||
meta_window_new_with_attrs (screen->display, info->xwindow, TRUE,
|
||||
&info->attrs);
|
||||
window = meta_window_new_with_attrs (screen->display, info->xwindow, TRUE,
|
||||
&info->attrs);
|
||||
if (info->xwindow == screen->no_focus_window ||
|
||||
info->xwindow == screen->flash_window ||
|
||||
#ifdef HAVE_COMPOSITE_EXTENSIONS
|
||||
info->xwindow == screen->wm_cm_selection_window ||
|
||||
#endif
|
||||
info->xwindow == screen->wm_sn_selection_window) {
|
||||
meta_verbose ("Not managing our own windows\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (screen->display->compositor)
|
||||
meta_compositor_add_window (screen->display->compositor, window,
|
||||
info->xwindow, &info->attrs);
|
||||
}
|
||||
meta_stack_thaw (screen->stack);
|
||||
|
||||
@ -822,9 +841,12 @@ meta_screen_manage_all_windows (MetaScreen *screen)
|
||||
void
|
||||
meta_screen_composite_all_windows (MetaScreen *screen)
|
||||
{
|
||||
#ifdef HAVE_COMPOSITE_EXTENSIONS
|
||||
MetaDisplay *display;
|
||||
GList *windows, *list;
|
||||
|
||||
if (!screen->display->compositor)
|
||||
display = screen->display;
|
||||
if (!display->compositor)
|
||||
return;
|
||||
|
||||
windows = list_windows (screen);
|
||||
@ -835,7 +857,17 @@ meta_screen_composite_all_windows (MetaScreen *screen)
|
||||
{
|
||||
WindowInfo *info = list->data;
|
||||
|
||||
meta_compositor_add_window (screen->display->compositor,
|
||||
if (info->xwindow == screen->no_focus_window ||
|
||||
info->xwindow == screen->flash_window ||
|
||||
info->xwindow == screen->wm_sn_selection_window ||
|
||||
info->xwindow == screen->wm_cm_selection_window) {
|
||||
meta_verbose ("Not managing our own windows\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
meta_compositor_add_window (display->compositor,
|
||||
meta_display_lookup_x_window (display,
|
||||
info->xwindow),
|
||||
info->xwindow, &info->attrs);
|
||||
}
|
||||
|
||||
@ -843,6 +875,7 @@ meta_screen_composite_all_windows (MetaScreen *screen)
|
||||
|
||||
g_list_foreach (windows, (GFunc)g_free, NULL);
|
||||
g_list_free (windows);
|
||||
#endif
|
||||
}
|
||||
|
||||
MetaScreen*
|
||||
@ -1215,6 +1248,49 @@ meta_screen_update_cursor (MetaScreen *screen)
|
||||
XFreeCursor (screen->display->xdisplay, xcursor);
|
||||
}
|
||||
|
||||
#define MAX_PREVIEW_SIZE 150.0
|
||||
|
||||
static GdkPixbuf *
|
||||
get_window_pixbuf (MetaWindow *window,
|
||||
int *width,
|
||||
int *height)
|
||||
{
|
||||
Pixmap pmap;
|
||||
GdkPixbuf *pixbuf, *scaled;
|
||||
double ratio;
|
||||
|
||||
pmap = meta_compositor_get_window_pixmap (window->display->compositor,
|
||||
window);
|
||||
if (pmap == None)
|
||||
return NULL;
|
||||
|
||||
pixbuf = meta_ui_get_pixbuf_from_pixmap (pmap);
|
||||
if (pixbuf == NULL)
|
||||
return NULL;
|
||||
|
||||
*width = gdk_pixbuf_get_width (pixbuf);
|
||||
*height = gdk_pixbuf_get_height (pixbuf);
|
||||
|
||||
/* Scale pixbuf to max dimension MAX_PREVIEW_SIZE */
|
||||
if (*width > *height)
|
||||
{
|
||||
ratio = ((double) *width) / MAX_PREVIEW_SIZE;
|
||||
*width = (int) MAX_PREVIEW_SIZE;
|
||||
*height = (int) (((double) *height) / ratio);
|
||||
}
|
||||
else
|
||||
{
|
||||
ratio = ((double) *height) / MAX_PREVIEW_SIZE;
|
||||
*height = (int) MAX_PREVIEW_SIZE;
|
||||
*width = (int) (((double) *width) / ratio);
|
||||
}
|
||||
|
||||
scaled = gdk_pixbuf_scale_simple (pixbuf, *width, *height,
|
||||
GDK_INTERP_BILINEAR);
|
||||
g_object_unref (pixbuf);
|
||||
return scaled;
|
||||
}
|
||||
|
||||
void
|
||||
meta_screen_ensure_tab_popup (MetaScreen *screen,
|
||||
MetaTabList list_type,
|
||||
@ -1247,12 +1323,41 @@ meta_screen_ensure_tab_popup (MetaScreen *screen,
|
||||
{
|
||||
MetaWindow *window;
|
||||
MetaRectangle r;
|
||||
|
||||
GdkPixbuf *win_pixbuf;
|
||||
int width, height;
|
||||
|
||||
window = tmp->data;
|
||||
|
||||
entries[i].key = (MetaTabEntryKey) window->xwindow;
|
||||
entries[i].title = window->title;
|
||||
entries[i].icon = window->icon;
|
||||
|
||||
win_pixbuf = get_window_pixbuf (window, &width, &height);
|
||||
if (win_pixbuf == NULL)
|
||||
entries[i].icon = g_object_ref (window->icon);
|
||||
else
|
||||
{
|
||||
int icon_width, icon_height, t_width, t_height;
|
||||
#define ICON_OFFSET 6
|
||||
|
||||
icon_width = gdk_pixbuf_get_width (window->icon);
|
||||
icon_height = gdk_pixbuf_get_height (window->icon);
|
||||
|
||||
t_width = width + ICON_OFFSET;
|
||||
t_height = height + ICON_OFFSET;
|
||||
|
||||
entries[i].icon = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8,
|
||||
t_width, t_height);
|
||||
gdk_pixbuf_fill (entries[i].icon, 0x00000000);
|
||||
gdk_pixbuf_copy_area (win_pixbuf, 0, 0, width, height,
|
||||
entries[i].icon, 0, 0);
|
||||
g_object_unref (win_pixbuf);
|
||||
gdk_pixbuf_composite (window->icon, entries[i].icon,
|
||||
t_width - icon_width, t_height - icon_height,
|
||||
icon_width, icon_height,
|
||||
t_width - icon_width, t_height - icon_height,
|
||||
1.0, 1.0, GDK_INTERP_BILINEAR, 255);
|
||||
}
|
||||
|
||||
entries[i].blank = FALSE;
|
||||
entries[i].hidden = !meta_window_showing_on_its_workspace (window);
|
||||
entries[i].demands_attention = window->wm_state_demands_attention;
|
||||
@ -1312,6 +1417,10 @@ meta_screen_ensure_tab_popup (MetaScreen *screen,
|
||||
len,
|
||||
5, /* FIXME */
|
||||
TRUE);
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
g_object_unref (entries[i].icon);
|
||||
|
||||
g_free (entries);
|
||||
|
||||
g_list_free (tab_list);
|
||||
@ -2686,3 +2795,28 @@ meta_screen_apply_startup_properties (MetaScreen *screen,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#ifdef HAVE_COMPOSITE_EXTENSIONS
|
||||
void
|
||||
meta_screen_set_cm_selection (MetaScreen *screen)
|
||||
{
|
||||
char selection[32];
|
||||
Atom a;
|
||||
|
||||
g_snprintf (selection, sizeof(selection), "_NET_WM_CM_S%d", screen->number);
|
||||
meta_verbose ("Setting selection: %s\n", selection);
|
||||
a = XInternAtom (screen->display->xdisplay, selection, FALSE);
|
||||
XSetSelectionOwner (screen->display->xdisplay, a,
|
||||
screen->wm_cm_selection_window, CurrentTime);
|
||||
}
|
||||
|
||||
void
|
||||
meta_screen_unset_cm_selection (MetaScreen *screen)
|
||||
{
|
||||
char selection[32];
|
||||
Atom a;
|
||||
|
||||
g_snprintf (selection, sizeof(selection), "_NET_WM_CM_S%d", screen->number);
|
||||
a = XInternAtom (screen->display->xdisplay, selection, FALSE);
|
||||
XSetSelectionOwner (screen->display->xdisplay, a, None, CurrentTime);
|
||||
}
|
||||
#endif /* HAVE_COMPOSITE_EXTENSIONS */
|
||||
|
11
src/screen.h
11
src/screen.h
@ -102,7 +102,11 @@ struct _MetaScreen
|
||||
GSList *startup_sequences;
|
||||
guint startup_sequence_timeout;
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef HAVE_COMPOSITE_EXTENSIONS
|
||||
Window wm_cm_selection_window;
|
||||
#endif
|
||||
|
||||
guint work_area_idle;
|
||||
|
||||
int rows_of_workspaces;
|
||||
@ -211,4 +215,9 @@ gboolean meta_screen_apply_startup_properties (MetaScreen *screen,
|
||||
MetaWindow *window);
|
||||
void meta_screen_composite_all_windows (MetaScreen *screen);
|
||||
|
||||
#ifdef HAVE_COMPOSITE_EXTENSIONS
|
||||
void meta_screen_set_cm_selection (MetaScreen *screen);
|
||||
void meta_screen_unset_cm_selection (MetaScreen *screen);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -1638,8 +1638,10 @@ parse_geometry_element (GMarkupParseContext *context,
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
static gboolean
|
||||
check_expression (const char *expr,
|
||||
check_expression (PosToken *tokens,
|
||||
int n_tokens,
|
||||
gboolean has_object,
|
||||
MetaTheme *theme,
|
||||
GMarkupParseContext *context,
|
||||
@ -1678,7 +1680,7 @@ check_expression (const char *expr,
|
||||
env.mini_icon_height = 0;
|
||||
env.theme = theme;
|
||||
|
||||
if (!meta_parse_position_expression (expr,
|
||||
if (!meta_parse_position_expression (tokens, n_tokens,
|
||||
&env,
|
||||
&x, &y,
|
||||
error))
|
||||
@ -1689,16 +1691,7 @@ check_expression (const char *expr,
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static char*
|
||||
optimize_expression (MetaTheme *theme,
|
||||
const char *expr)
|
||||
{
|
||||
/* We aren't expecting an error here, since we already
|
||||
* did check_expression
|
||||
*/
|
||||
return meta_theme_replace_constants (theme, expr, NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
parse_draw_op_element (GMarkupParseContext *context,
|
||||
@ -1772,6 +1765,7 @@ parse_draw_op_element (GMarkupParseContext *context,
|
||||
return;
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (!check_expression (x1, FALSE, info->theme, context, error))
|
||||
return;
|
||||
|
||||
@ -1783,7 +1777,8 @@ parse_draw_op_element (GMarkupParseContext *context,
|
||||
|
||||
if (!check_expression (y2, FALSE, info->theme, context, error))
|
||||
return;
|
||||
|
||||
#endif
|
||||
|
||||
dash_on_val = 0;
|
||||
if (dash_on_length &&
|
||||
!parse_positive_integer (dash_on_length, &dash_on_val, context, info->theme, error))
|
||||
@ -1812,10 +1807,12 @@ parse_draw_op_element (GMarkupParseContext *context,
|
||||
op = meta_draw_op_new (META_DRAW_LINE);
|
||||
|
||||
op->data.line.color_spec = color_spec;
|
||||
op->data.line.x1 = optimize_expression (info->theme, x1);
|
||||
op->data.line.y1 = optimize_expression (info->theme, y1);
|
||||
op->data.line.x2 = optimize_expression (info->theme, x2);
|
||||
op->data.line.y2 = optimize_expression (info->theme, y2);
|
||||
|
||||
op->data.line.x1 = meta_draw_spec_new (info->theme, x1, NULL);
|
||||
op->data.line.y1 = meta_draw_spec_new (info->theme, y1, NULL);
|
||||
op->data.line.x2 = meta_draw_spec_new (info->theme, x2, NULL);
|
||||
op->data.line.y2 = meta_draw_spec_new (info->theme, y2, NULL);
|
||||
|
||||
op->data.line.width = width_val;
|
||||
op->data.line.dash_on_length = dash_on_val;
|
||||
op->data.line.dash_off_length = dash_off_val;
|
||||
@ -1882,6 +1879,7 @@ parse_draw_op_element (GMarkupParseContext *context,
|
||||
return;
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (!check_expression (x, FALSE, info->theme, context, error))
|
||||
return;
|
||||
|
||||
@ -1893,6 +1891,7 @@ parse_draw_op_element (GMarkupParseContext *context,
|
||||
|
||||
if (!check_expression (height, FALSE, info->theme, context, error))
|
||||
return;
|
||||
#endif
|
||||
|
||||
filled_val = FALSE;
|
||||
if (filled && !parse_boolean (filled, &filled_val, context, error))
|
||||
@ -1911,10 +1910,12 @@ parse_draw_op_element (GMarkupParseContext *context,
|
||||
op = meta_draw_op_new (META_DRAW_RECTANGLE);
|
||||
|
||||
op->data.rectangle.color_spec = color_spec;
|
||||
op->data.rectangle.x = optimize_expression (info->theme, x);
|
||||
op->data.rectangle.y = optimize_expression (info->theme, y);
|
||||
op->data.rectangle.width = optimize_expression (info->theme, width);
|
||||
op->data.rectangle.height = optimize_expression (info->theme, height);
|
||||
op->data.rectangle.x = meta_draw_spec_new (info->theme, x, NULL);
|
||||
op->data.rectangle.y = meta_draw_spec_new (info->theme, y, NULL);
|
||||
op->data.rectangle.width = meta_draw_spec_new (info->theme, width, NULL);
|
||||
op->data.rectangle.height = meta_draw_spec_new (info->theme,
|
||||
height, NULL);
|
||||
|
||||
op->data.rectangle.filled = filled_val;
|
||||
|
||||
g_assert (info->op_list);
|
||||
@ -2022,7 +2023,7 @@ parse_draw_op_element (GMarkupParseContext *context,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
if (!check_expression (x, FALSE, info->theme, context, error))
|
||||
return;
|
||||
|
||||
@ -2034,6 +2035,7 @@ parse_draw_op_element (GMarkupParseContext *context,
|
||||
|
||||
if (!check_expression (height, FALSE, info->theme, context, error))
|
||||
return;
|
||||
#endif
|
||||
|
||||
if (start_angle == NULL)
|
||||
{
|
||||
@ -2078,10 +2080,12 @@ parse_draw_op_element (GMarkupParseContext *context,
|
||||
op = meta_draw_op_new (META_DRAW_ARC);
|
||||
|
||||
op->data.arc.color_spec = color_spec;
|
||||
op->data.arc.x = optimize_expression (info->theme, x);
|
||||
op->data.arc.y = optimize_expression (info->theme, y);
|
||||
op->data.arc.width = optimize_expression (info->theme, width);
|
||||
op->data.arc.height = optimize_expression (info->theme, height);
|
||||
|
||||
op->data.arc.x = meta_draw_spec_new (info->theme, x, NULL);
|
||||
op->data.arc.y = meta_draw_spec_new (info->theme, y, NULL);
|
||||
op->data.arc.width = meta_draw_spec_new (info->theme, width, NULL);
|
||||
op->data.arc.height = meta_draw_spec_new (info->theme, height, NULL);
|
||||
|
||||
op->data.arc.filled = filled_val;
|
||||
op->data.arc.start_angle = start_angle_val;
|
||||
op->data.arc.extent_angle = extent_angle_val;
|
||||
@ -2135,6 +2139,7 @@ parse_draw_op_element (GMarkupParseContext *context,
|
||||
return;
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (!check_expression (x, FALSE, info->theme, context, error))
|
||||
return;
|
||||
|
||||
@ -2146,13 +2151,13 @@ parse_draw_op_element (GMarkupParseContext *context,
|
||||
|
||||
if (!check_expression (height, FALSE, info->theme, context, error))
|
||||
return;
|
||||
|
||||
#endif
|
||||
op = meta_draw_op_new (META_DRAW_CLIP);
|
||||
|
||||
op->data.clip.x = optimize_expression (info->theme, x);
|
||||
op->data.clip.y = optimize_expression (info->theme, y);
|
||||
op->data.clip.width = optimize_expression (info->theme, width);
|
||||
op->data.clip.height = optimize_expression (info->theme, height);
|
||||
op->data.clip.x = meta_draw_spec_new (info->theme, x, NULL);
|
||||
op->data.clip.y = meta_draw_spec_new (info->theme, y, NULL);
|
||||
op->data.clip.width = meta_draw_spec_new (info->theme, width, NULL);
|
||||
op->data.clip.height = meta_draw_spec_new (info->theme, height, NULL);
|
||||
|
||||
g_assert (info->op_list);
|
||||
|
||||
@ -2222,7 +2227,7 @@ parse_draw_op_element (GMarkupParseContext *context,
|
||||
_("No \"alpha\" attribute on element <%s>"), element_name);
|
||||
return;
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (!check_expression (x, FALSE, info->theme, context, error))
|
||||
return;
|
||||
|
||||
@ -2234,7 +2239,7 @@ parse_draw_op_element (GMarkupParseContext *context,
|
||||
|
||||
if (!check_expression (height, FALSE, info->theme, context, error))
|
||||
return;
|
||||
|
||||
#endif
|
||||
alpha_spec = NULL;
|
||||
if (!parse_alpha (alpha, &alpha_spec, context, error))
|
||||
return;
|
||||
@ -2256,10 +2261,11 @@ parse_draw_op_element (GMarkupParseContext *context,
|
||||
|
||||
op->data.tint.color_spec = color_spec;
|
||||
op->data.tint.alpha_spec = alpha_spec;
|
||||
op->data.tint.x = optimize_expression (info->theme, x);
|
||||
op->data.tint.y = optimize_expression (info->theme, y);
|
||||
op->data.tint.width = optimize_expression (info->theme, width);
|
||||
op->data.tint.height = optimize_expression (info->theme, height);
|
||||
|
||||
op->data.tint.x = meta_draw_spec_new (info->theme, x, NULL);
|
||||
op->data.tint.y = meta_draw_spec_new (info->theme, y, NULL);
|
||||
op->data.tint.width = meta_draw_spec_new (info->theme, width, NULL);
|
||||
op->data.tint.height = meta_draw_spec_new (info->theme, height, NULL);
|
||||
|
||||
g_assert (info->op_list);
|
||||
|
||||
@ -2322,6 +2328,7 @@ parse_draw_op_element (GMarkupParseContext *context,
|
||||
return;
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (!check_expression (x, FALSE, info->theme, context, error))
|
||||
return;
|
||||
|
||||
@ -2333,7 +2340,8 @@ parse_draw_op_element (GMarkupParseContext *context,
|
||||
|
||||
if (!check_expression (height, FALSE, info->theme, context, error))
|
||||
return;
|
||||
|
||||
#endif
|
||||
|
||||
type_val = meta_gradient_type_from_string (type);
|
||||
if (type_val == META_GRADIENT_LAST)
|
||||
{
|
||||
@ -2350,10 +2358,12 @@ parse_draw_op_element (GMarkupParseContext *context,
|
||||
g_assert (info->op == NULL);
|
||||
info->op = meta_draw_op_new (META_DRAW_GRADIENT);
|
||||
|
||||
info->op->data.gradient.x = optimize_expression (info->theme, x);
|
||||
info->op->data.gradient.y = optimize_expression (info->theme, y);
|
||||
info->op->data.gradient.width = optimize_expression (info->theme, width);
|
||||
info->op->data.gradient.height = optimize_expression (info->theme, height);
|
||||
info->op->data.gradient.x = meta_draw_spec_new (info->theme, x, NULL);
|
||||
info->op->data.gradient.y = meta_draw_spec_new (info->theme, y, NULL);
|
||||
info->op->data.gradient.width = meta_draw_spec_new (info->theme,
|
||||
width, NULL);
|
||||
info->op->data.gradient.height = meta_draw_spec_new (info->theme,
|
||||
height, NULL);
|
||||
|
||||
info->op->data.gradient.gradient_spec = meta_gradient_spec_new (type_val);
|
||||
|
||||
@ -2426,7 +2436,7 @@ parse_draw_op_element (GMarkupParseContext *context,
|
||||
_("No \"filename\" attribute on element <%s>"), element_name);
|
||||
return;
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (!check_expression (x, TRUE, info->theme, context, error))
|
||||
return;
|
||||
|
||||
@ -2438,7 +2448,7 @@ parse_draw_op_element (GMarkupParseContext *context,
|
||||
|
||||
if (!check_expression (height, TRUE, info->theme, context, error))
|
||||
return;
|
||||
|
||||
#endif
|
||||
fill_type_val = META_IMAGE_FILL_SCALE;
|
||||
if (fill_type)
|
||||
{
|
||||
@ -2490,10 +2500,12 @@ parse_draw_op_element (GMarkupParseContext *context,
|
||||
|
||||
op->data.image.pixbuf = pixbuf;
|
||||
op->data.image.colorize_spec = colorize_spec;
|
||||
op->data.image.x = optimize_expression (info->theme, x);
|
||||
op->data.image.y = optimize_expression (info->theme, y);
|
||||
op->data.image.width = optimize_expression (info->theme, width);
|
||||
op->data.image.height = optimize_expression (info->theme, height);
|
||||
|
||||
op->data.image.x = meta_draw_spec_new (info->theme, x, NULL);
|
||||
op->data.image.y = meta_draw_spec_new (info->theme, y, NULL);
|
||||
op->data.image.width = meta_draw_spec_new (info->theme, width, NULL);
|
||||
op->data.image.height = meta_draw_spec_new (info->theme, height, NULL);
|
||||
|
||||
op->data.image.alpha_spec = alpha_spec;
|
||||
op->data.image.fill_type = fill_type_val;
|
||||
|
||||
@ -2639,7 +2651,7 @@ parse_draw_op_element (GMarkupParseContext *context,
|
||||
_("No \"height\" attribute on element <%s>"), element_name);
|
||||
return;
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (!check_expression (x, FALSE, info->theme, context, error))
|
||||
return;
|
||||
|
||||
@ -2651,7 +2663,7 @@ parse_draw_op_element (GMarkupParseContext *context,
|
||||
|
||||
if (!check_expression (height, FALSE, info->theme, context, error))
|
||||
return;
|
||||
|
||||
#endif
|
||||
filled_val = TRUE;
|
||||
if (filled && !parse_boolean (filled, &filled_val, context, error))
|
||||
return;
|
||||
@ -2688,10 +2700,12 @@ parse_draw_op_element (GMarkupParseContext *context,
|
||||
|
||||
op = meta_draw_op_new (META_DRAW_GTK_ARROW);
|
||||
|
||||
op->data.gtk_arrow.x = optimize_expression (info->theme, x);
|
||||
op->data.gtk_arrow.y = optimize_expression (info->theme, y);
|
||||
op->data.gtk_arrow.width = optimize_expression (info->theme, width);
|
||||
op->data.gtk_arrow.height = optimize_expression (info->theme, height);
|
||||
op->data.gtk_arrow.x = meta_draw_spec_new (info->theme, x, NULL);
|
||||
op->data.gtk_arrow.y = meta_draw_spec_new (info->theme, y, NULL);
|
||||
op->data.gtk_arrow.width = meta_draw_spec_new (info->theme, width, NULL);
|
||||
op->data.gtk_arrow.height = meta_draw_spec_new (info->theme,
|
||||
height, NULL);
|
||||
|
||||
op->data.gtk_arrow.filled = filled_val;
|
||||
op->data.gtk_arrow.state = state_val;
|
||||
op->data.gtk_arrow.shadow = shadow_val;
|
||||
@ -2765,7 +2779,7 @@ parse_draw_op_element (GMarkupParseContext *context,
|
||||
_("No \"height\" attribute on element <%s>"), element_name);
|
||||
return;
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (!check_expression (x, FALSE, info->theme, context, error))
|
||||
return;
|
||||
|
||||
@ -2777,7 +2791,7 @@ parse_draw_op_element (GMarkupParseContext *context,
|
||||
|
||||
if (!check_expression (height, FALSE, info->theme, context, error))
|
||||
return;
|
||||
|
||||
#endif
|
||||
state_val = meta_gtk_state_from_string (state);
|
||||
if (((int) state_val) == -1)
|
||||
{
|
||||
@ -2800,10 +2814,11 @@ parse_draw_op_element (GMarkupParseContext *context,
|
||||
|
||||
op = meta_draw_op_new (META_DRAW_GTK_BOX);
|
||||
|
||||
op->data.gtk_box.x = optimize_expression (info->theme, x);
|
||||
op->data.gtk_box.y = optimize_expression (info->theme, y);
|
||||
op->data.gtk_box.width = optimize_expression (info->theme, width);
|
||||
op->data.gtk_box.height = optimize_expression (info->theme, height);
|
||||
op->data.gtk_box.x = meta_draw_spec_new (info->theme, x, NULL);
|
||||
op->data.gtk_box.y = meta_draw_spec_new (info->theme, y, NULL);
|
||||
op->data.gtk_box.width = meta_draw_spec_new (info->theme, width, NULL);
|
||||
op->data.gtk_box.height = meta_draw_spec_new (info->theme, height, NULL);
|
||||
|
||||
op->data.gtk_box.state = state_val;
|
||||
op->data.gtk_box.shadow = shadow_val;
|
||||
|
||||
@ -2857,6 +2872,7 @@ parse_draw_op_element (GMarkupParseContext *context,
|
||||
return;
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (!check_expression (x, FALSE, info->theme, context, error))
|
||||
return;
|
||||
|
||||
@ -2865,6 +2881,7 @@ parse_draw_op_element (GMarkupParseContext *context,
|
||||
|
||||
if (!check_expression (y2, FALSE, info->theme, context, error))
|
||||
return;
|
||||
#endif
|
||||
|
||||
state_val = meta_gtk_state_from_string (state);
|
||||
if (((int) state_val) == -1)
|
||||
@ -2878,9 +2895,10 @@ parse_draw_op_element (GMarkupParseContext *context,
|
||||
|
||||
op = meta_draw_op_new (META_DRAW_GTK_VLINE);
|
||||
|
||||
op->data.gtk_vline.x = optimize_expression (info->theme, x);
|
||||
op->data.gtk_vline.y1 = optimize_expression (info->theme, y1);
|
||||
op->data.gtk_vline.y2 = optimize_expression (info->theme, y2);
|
||||
op->data.gtk_vline.x = meta_draw_spec_new (info->theme, x, NULL);
|
||||
op->data.gtk_vline.y1 = meta_draw_spec_new (info->theme, y1, NULL);
|
||||
op->data.gtk_vline.y2 = meta_draw_spec_new (info->theme, y2, NULL);
|
||||
|
||||
op->data.gtk_vline.state = state_val;
|
||||
|
||||
g_assert (info->op_list);
|
||||
@ -2937,7 +2955,7 @@ parse_draw_op_element (GMarkupParseContext *context,
|
||||
_("No \"height\" attribute on element <%s>"), element_name);
|
||||
return;
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (!check_expression (x, FALSE, info->theme, context, error))
|
||||
return;
|
||||
|
||||
@ -2949,7 +2967,7 @@ parse_draw_op_element (GMarkupParseContext *context,
|
||||
|
||||
if (!check_expression (height, FALSE, info->theme, context, error))
|
||||
return;
|
||||
|
||||
#endif
|
||||
fill_type_val = META_IMAGE_FILL_SCALE;
|
||||
if (fill_type)
|
||||
{
|
||||
@ -2969,11 +2987,12 @@ parse_draw_op_element (GMarkupParseContext *context,
|
||||
return;
|
||||
|
||||
op = meta_draw_op_new (META_DRAW_ICON);
|
||||
|
||||
op->data.icon.x = meta_draw_spec_new (info->theme, x, NULL);
|
||||
op->data.icon.y = meta_draw_spec_new (info->theme, y, NULL);
|
||||
op->data.icon.width = meta_draw_spec_new (info->theme, width, NULL);
|
||||
op->data.icon.height = meta_draw_spec_new (info->theme, height, NULL);
|
||||
|
||||
op->data.icon.x = optimize_expression (info->theme, x);
|
||||
op->data.icon.y = optimize_expression (info->theme, y);
|
||||
op->data.icon.width = optimize_expression (info->theme, width);
|
||||
op->data.icon.height = optimize_expression (info->theme, height);
|
||||
op->data.icon.alpha_spec = alpha_spec;
|
||||
op->data.icon.fill_type = fill_type_val;
|
||||
|
||||
@ -3019,12 +3038,14 @@ parse_draw_op_element (GMarkupParseContext *context,
|
||||
return;
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (!check_expression (x, FALSE, info->theme, context, error))
|
||||
return;
|
||||
|
||||
if (!check_expression (y, FALSE, info->theme, context, error))
|
||||
return;
|
||||
|
||||
#endif
|
||||
|
||||
/* Check last so we don't have to free it when other
|
||||
* stuff fails
|
||||
*/
|
||||
@ -3038,8 +3059,9 @@ parse_draw_op_element (GMarkupParseContext *context,
|
||||
op = meta_draw_op_new (META_DRAW_TITLE);
|
||||
|
||||
op->data.title.color_spec = color_spec;
|
||||
op->data.title.x = optimize_expression (info->theme, x);
|
||||
op->data.title.y = optimize_expression (info->theme, y);
|
||||
|
||||
op->data.title.x = meta_draw_spec_new (info->theme, x, NULL);
|
||||
op->data.title.y = meta_draw_spec_new (info->theme, y, NULL);
|
||||
|
||||
g_assert (info->op_list);
|
||||
|
||||
@ -3075,7 +3097,7 @@ parse_draw_op_element (GMarkupParseContext *context,
|
||||
/* x/y/width/height default to 0,0,width,height - should
|
||||
* probably do this for all the draw ops
|
||||
*/
|
||||
|
||||
#if 0
|
||||
if (x && !check_expression (x, FALSE, info->theme, context, error))
|
||||
return;
|
||||
|
||||
@ -3087,6 +3109,7 @@ parse_draw_op_element (GMarkupParseContext *context,
|
||||
|
||||
if (height && !check_expression (height, FALSE, info->theme, context, error))
|
||||
return;
|
||||
#endif
|
||||
|
||||
op_list = meta_theme_lookup_draw_op_list (info->theme,
|
||||
name);
|
||||
@ -3115,15 +3138,16 @@ parse_draw_op_element (GMarkupParseContext *context,
|
||||
|
||||
meta_draw_op_list_ref (op_list);
|
||||
op->data.op_list.op_list = op_list;
|
||||
op->data.op_list.x = x ? optimize_expression (info->theme, x) :
|
||||
g_strdup ("0");
|
||||
op->data.op_list.y = y ? optimize_expression (info->theme, y) :
|
||||
g_strdup ("0");
|
||||
op->data.op_list.width = width ? optimize_expression (info->theme, width) :
|
||||
g_strdup ("width");
|
||||
op->data.op_list.height = height ? optimize_expression (info->theme, height) :
|
||||
g_strdup ("height");
|
||||
|
||||
|
||||
op->data.op_list.x = meta_draw_spec_new (info->theme, x ? x : "0", NULL);
|
||||
op->data.op_list.y = meta_draw_spec_new (info->theme, y ? y : "0", NULL);
|
||||
op->data.op_list.width = meta_draw_spec_new (info->theme,
|
||||
width ? width : "width",
|
||||
NULL);
|
||||
op->data.op_list.height = meta_draw_spec_new (info->theme,
|
||||
height ? height : "height",
|
||||
NULL);
|
||||
|
||||
meta_draw_op_list_append (info->op_list, op);
|
||||
|
||||
push_state (info, STATE_INCLUDE);
|
||||
@ -3176,6 +3200,7 @@ parse_draw_op_element (GMarkupParseContext *context,
|
||||
}
|
||||
|
||||
/* These default to 0 */
|
||||
#if 0
|
||||
if (tile_xoffset && !check_expression (tile_xoffset, FALSE, info->theme, context, error))
|
||||
return;
|
||||
|
||||
@ -3185,7 +3210,6 @@ parse_draw_op_element (GMarkupParseContext *context,
|
||||
/* x/y/width/height default to 0,0,width,height - should
|
||||
* probably do this for all the draw ops
|
||||
*/
|
||||
|
||||
if (x && !check_expression (x, FALSE, info->theme, context, error))
|
||||
return;
|
||||
|
||||
@ -3203,7 +3227,7 @@ parse_draw_op_element (GMarkupParseContext *context,
|
||||
|
||||
if (!check_expression (tile_height, FALSE, info->theme, context, error))
|
||||
return;
|
||||
|
||||
#endif
|
||||
op_list = meta_theme_lookup_draw_op_list (info->theme,
|
||||
name);
|
||||
if (op_list == NULL)
|
||||
@ -3230,23 +3254,25 @@ parse_draw_op_element (GMarkupParseContext *context,
|
||||
op = meta_draw_op_new (META_DRAW_TILE);
|
||||
|
||||
meta_draw_op_list_ref (op_list);
|
||||
|
||||
op->data.tile.x = meta_draw_spec_new (info->theme, x ? x : "0", NULL);
|
||||
op->data.tile.y = meta_draw_spec_new (info->theme, y ? y : "0", NULL);
|
||||
op->data.tile.width = meta_draw_spec_new (info->theme,
|
||||
width ? width : "width",
|
||||
NULL);
|
||||
op->data.tile.height = meta_draw_spec_new (info->theme,
|
||||
height ? height : "height",
|
||||
NULL);
|
||||
op->data.tile.tile_xoffset = meta_draw_spec_new (info->theme,
|
||||
tile_xoffset ? tile_xoffset : "0",
|
||||
NULL);
|
||||
op->data.tile.tile_yoffset = meta_draw_spec_new (info->theme,
|
||||
tile_yoffset ? tile_yoffset : "0",
|
||||
NULL);
|
||||
op->data.tile.tile_width = meta_draw_spec_new (info->theme, tile_width, NULL);
|
||||
op->data.tile.tile_height = meta_draw_spec_new (info->theme, tile_height, NULL);
|
||||
|
||||
op->data.tile.op_list = op_list;
|
||||
op->data.tile.x = x ? optimize_expression (info->theme, x) :
|
||||
g_strdup ("0");
|
||||
op->data.tile.y = y ? optimize_expression (info->theme, y) :
|
||||
g_strdup ("0");
|
||||
op->data.tile.width = width ? optimize_expression (info->theme, width) :
|
||||
g_strdup ("width");
|
||||
op->data.tile.height = height ? optimize_expression (info->theme, height) :
|
||||
g_strdup ("height");
|
||||
op->data.tile.tile_xoffset = tile_xoffset ?
|
||||
optimize_expression (info->theme, tile_xoffset) :
|
||||
g_strdup ("0");
|
||||
op->data.tile.tile_yoffset = tile_yoffset ?
|
||||
optimize_expression (info->theme, tile_yoffset) :
|
||||
g_strdup ("0");
|
||||
op->data.tile.tile_width = optimize_expression (info->theme, tile_width);
|
||||
op->data.tile.tile_height = optimize_expression (info->theme, tile_height);
|
||||
|
||||
meta_draw_op_list_append (info->op_list, op);
|
||||
|
||||
|
@ -1175,6 +1175,7 @@ static const PositionExpressionTest position_expression_tests[] = {
|
||||
static void
|
||||
run_position_expression_tests (void)
|
||||
{
|
||||
#if 0
|
||||
int i;
|
||||
MetaPositionExprEnv env;
|
||||
|
||||
@ -1184,6 +1185,8 @@ run_position_expression_tests (void)
|
||||
GError *err;
|
||||
gboolean retval;
|
||||
const PositionExpressionTest *test;
|
||||
PosToken *tokens;
|
||||
int n_tokens;
|
||||
int x, y;
|
||||
|
||||
test = &position_expression_tests[i];
|
||||
@ -1210,10 +1213,13 @@ run_position_expression_tests (void)
|
||||
env.mini_icon_height = 16;
|
||||
env.theme = NULL;
|
||||
|
||||
retval = meta_parse_position_expression (test->expr,
|
||||
&env,
|
||||
&x, &y,
|
||||
&err);
|
||||
if (err == NULL)
|
||||
{
|
||||
retval = meta_parse_position_expression (tokens, n_tokens,
|
||||
&env,
|
||||
&x, &y,
|
||||
&err);
|
||||
}
|
||||
|
||||
if (retval && err)
|
||||
g_error (_("position expression test returned TRUE but set error"));
|
||||
@ -1243,8 +1249,10 @@ run_position_expression_tests (void)
|
||||
if (err)
|
||||
g_error_free (err);
|
||||
|
||||
meta_pos_tokens_free (tokens, n_tokens);
|
||||
++i;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
724
src/theme.c
724
src/theme.c
@ -60,6 +60,8 @@ static void hls_to_rgb (gdouble *h,
|
||||
gdouble *l,
|
||||
gdouble *s);
|
||||
|
||||
static MetaTheme *meta_current_theme = NULL;
|
||||
|
||||
static GdkPixbuf *
|
||||
colorize_pixbuf (GdkPixbuf *orig,
|
||||
GdkColor *new_color)
|
||||
@ -1167,6 +1169,7 @@ meta_color_spec_new_from_string (const char *str,
|
||||
spec->data.blend.alpha = alpha;
|
||||
spec->data.blend.background = bg;
|
||||
spec->data.blend.foreground = fg;
|
||||
spec->data.blend.color_set = FALSE;
|
||||
}
|
||||
else if (str[0] == 's' && str[1] == 'h' && str[2] == 'a' && str[3] == 'd' &&
|
||||
str[4] == 'e' && str[5] == '/')
|
||||
@ -1225,6 +1228,7 @@ meta_color_spec_new_from_string (const char *str,
|
||||
spec = meta_color_spec_new (META_COLOR_SPEC_SHADE);
|
||||
spec->data.shade.factor = factor;
|
||||
spec->data.shade.base = base;
|
||||
spec->data.shade.color_set = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1312,49 +1316,38 @@ meta_color_spec_render (MetaColorSpec *spec,
|
||||
{
|
||||
GdkColor bg, fg;
|
||||
|
||||
meta_color_spec_render (spec->data.blend.background, widget, &bg);
|
||||
meta_color_spec_render (spec->data.blend.foreground, widget, &fg);
|
||||
if (spec->data.blend.color_set == FALSE)
|
||||
{
|
||||
meta_color_spec_render (spec->data.blend.background, widget, &bg);
|
||||
meta_color_spec_render (spec->data.blend.foreground, widget, &fg);
|
||||
|
||||
color_composite (&bg, &fg, spec->data.blend.alpha, color);
|
||||
color_composite (&bg, &fg, spec->data.blend.alpha,
|
||||
&spec->data.blend.color);
|
||||
spec->data.blend.color_set = TRUE;
|
||||
}
|
||||
|
||||
*color = spec->data.blend.color;
|
||||
}
|
||||
break;
|
||||
|
||||
case META_COLOR_SPEC_SHADE:
|
||||
{
|
||||
GdkColor base;
|
||||
|
||||
meta_color_spec_render (spec->data.shade.base, widget, &base);
|
||||
|
||||
gtk_style_shade (&base, &base, spec->data.shade.factor);
|
||||
if (spec->data.shade.color_set == FALSE)
|
||||
{
|
||||
meta_color_spec_render (spec->data.shade.base, widget,
|
||||
&spec->data.shade.color);
|
||||
|
||||
gtk_style_shade (&spec->data.shade.color,
|
||||
&spec->data.shade.color, spec->data.shade.factor);
|
||||
spec->data.shade.color_set = TRUE;
|
||||
}
|
||||
|
||||
*color = base;
|
||||
*color = spec->data.shade.color;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
typedef enum
|
||||
{
|
||||
POS_TOKEN_INT,
|
||||
POS_TOKEN_DOUBLE,
|
||||
POS_TOKEN_OPERATOR,
|
||||
POS_TOKEN_VARIABLE,
|
||||
POS_TOKEN_OPEN_PAREN,
|
||||
POS_TOKEN_CLOSE_PAREN
|
||||
} PosTokenType;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
POS_OP_NONE,
|
||||
POS_OP_ADD,
|
||||
POS_OP_SUBTRACT,
|
||||
POS_OP_MULTIPLY,
|
||||
POS_OP_DIVIDE,
|
||||
POS_OP_MOD,
|
||||
POS_OP_MAX,
|
||||
POS_OP_MIN
|
||||
} PosOperatorType;
|
||||
|
||||
static const char*
|
||||
op_name (PosOperatorType type)
|
||||
{
|
||||
@ -1429,33 +1422,6 @@ op_from_string (const char *p,
|
||||
return POS_OP_NONE;
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
PosTokenType type;
|
||||
|
||||
union
|
||||
{
|
||||
struct {
|
||||
int val;
|
||||
} i;
|
||||
|
||||
struct {
|
||||
double val;
|
||||
} d;
|
||||
|
||||
struct {
|
||||
PosOperatorType op;
|
||||
} o;
|
||||
|
||||
struct {
|
||||
char *name;
|
||||
} v;
|
||||
|
||||
} d;
|
||||
|
||||
} PosToken;
|
||||
|
||||
|
||||
static void
|
||||
free_tokens (PosToken *tokens,
|
||||
int n_tokens)
|
||||
@ -1550,6 +1516,46 @@ parse_number (const char *p,
|
||||
|
||||
#define IS_VARIABLE_CHAR(c) (g_ascii_isalpha ((c)) || (c) == '_')
|
||||
|
||||
#if 0
|
||||
static void
|
||||
debug_print_tokens (PosToken *tokens,
|
||||
int n_tokens)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < n_tokens; i++)
|
||||
{
|
||||
PosToken *t = &tokens[i];
|
||||
|
||||
g_print (" ");
|
||||
|
||||
switch (t->type)
|
||||
{
|
||||
case POS_TOKEN_INT:
|
||||
g_print ("\"%d\"", t->d.i.val);
|
||||
break;
|
||||
case POS_TOKEN_DOUBLE:
|
||||
g_print ("\"%g\"", t->d.d.val);
|
||||
break;
|
||||
case POS_TOKEN_OPEN_PAREN:
|
||||
g_print ("\"(\"");
|
||||
break;
|
||||
case POS_TOKEN_CLOSE_PAREN:
|
||||
g_print ("\")\"");
|
||||
break;
|
||||
case POS_TOKEN_VARIABLE:
|
||||
g_print ("\"%s\"", t->d.v.name);
|
||||
break;
|
||||
case POS_TOKEN_OPERATOR:
|
||||
g_print ("\"%s\"", op_name (t->d.o.op));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
g_print ("\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
static gboolean
|
||||
pos_tokenize (const char *expr,
|
||||
PosToken **tokens_p,
|
||||
@ -1675,46 +1681,6 @@ pos_tokenize (const char *expr,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void
|
||||
debug_print_tokens (PosToken *tokens,
|
||||
int n_tokens)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < n_tokens; i++)
|
||||
{
|
||||
PosToken *t = &tokens[i];
|
||||
|
||||
g_print (" ");
|
||||
|
||||
switch (t->type)
|
||||
{
|
||||
case POS_TOKEN_INT:
|
||||
g_print ("\"%d\"", t->d.i.val);
|
||||
break;
|
||||
case POS_TOKEN_DOUBLE:
|
||||
g_print ("\"%g\"", t->d.d.val);
|
||||
break;
|
||||
case POS_TOKEN_OPEN_PAREN:
|
||||
g_print ("\"(\"");
|
||||
break;
|
||||
case POS_TOKEN_CLOSE_PAREN:
|
||||
g_print ("\")\"");
|
||||
break;
|
||||
case POS_TOKEN_VARIABLE:
|
||||
g_print ("\"%s\"", t->d.v.name);
|
||||
break;
|
||||
case POS_TOKEN_OPERATOR:
|
||||
g_print ("\"%s\"", op_name (t->d.o.op));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
g_print ("\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
typedef enum
|
||||
{
|
||||
POS_EXPR_INT,
|
||||
@ -2010,6 +1976,100 @@ do_operations (PosExpr *exprs,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
pos_eval_get_variable (PosToken *t,
|
||||
int *result,
|
||||
const MetaPositionExprEnv *env,
|
||||
GError **err)
|
||||
{
|
||||
/* In certain circumstances (when the theme parser is used outside
|
||||
of metacity) env->theme will be NULL so we run the slow variable search */
|
||||
if (env->theme)
|
||||
{
|
||||
if (t->d.v.name_quark == env->theme->quark_width)
|
||||
*result = env->rect.width;
|
||||
else if (t->d.v.name_quark == env->theme->quark_height)
|
||||
*result = env->rect.height;
|
||||
else if (env->object_width >= 0 &&
|
||||
t->d.v.name_quark == env->theme->quark_object_width)
|
||||
*result = env->object_width;
|
||||
else if (env->object_height >= 0 &&
|
||||
t->d.v.name_quark == env->theme->quark_object_height)
|
||||
*result = env->object_height;
|
||||
else if (t->d.v.name_quark == env->theme->quark_left_width)
|
||||
*result = env->left_width;
|
||||
else if (t->d.v.name_quark == env->theme->quark_right_width)
|
||||
*result = env->right_width;
|
||||
else if (t->d.v.name_quark == env->theme->quark_top_height)
|
||||
*result = env->top_height;
|
||||
else if (t->d.v.name_quark == env->theme->quark_bottom_height)
|
||||
*result = env->bottom_height;
|
||||
else if (t->d.v.name_quark == env->theme->quark_mini_icon_width)
|
||||
*result = env->mini_icon_width;
|
||||
else if (t->d.v.name_quark == env->theme->quark_mini_icon_height)
|
||||
*result = env->mini_icon_height;
|
||||
else if (t->d.v.name_quark == env->theme->quark_icon_width)
|
||||
*result = env->icon_width;
|
||||
else if (t->d.v.name_quark == env->theme->quark_icon_height)
|
||||
*result = env->icon_height;
|
||||
else if (t->d.v.name_quark == env->theme->quark_title_width)
|
||||
*result = env->title_width;
|
||||
else if (t->d.v.name_quark == env->theme->quark_title_height)
|
||||
*result = env->title_height;
|
||||
else
|
||||
{
|
||||
g_set_error (err, META_THEME_ERROR,
|
||||
META_THEME_ERROR_UNKNOWN_VARIABLE,
|
||||
_("Coordinate expression had unknown variable or constant \"%s\""),
|
||||
t->d.v.name);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (strcmp (t->d.v.name, "width") == 0)
|
||||
*result = env->rect.width;
|
||||
else if (strcmp (t->d.v.name, "height") == 0)
|
||||
*result = env->rect.height;
|
||||
else if (env->object_width >= 0 &&
|
||||
strcmp (t->d.v.name, "object_width") == 0)
|
||||
*result = env->object_width;
|
||||
else if (env->object_height >= 0 &&
|
||||
strcmp (t->d.v.name, "object_height") == 0)
|
||||
*result = env->object_height;
|
||||
else if (strcmp (t->d.v.name, "left_width") == 0)
|
||||
*result = env->left_width;
|
||||
else if (strcmp (t->d.v.name, "right_width") == 0)
|
||||
*result = env->right_width;
|
||||
else if (strcmp (t->d.v.name, "top_height") == 0)
|
||||
*result = env->top_height;
|
||||
else if (strcmp (t->d.v.name, "bottom_height") == 0)
|
||||
*result = env->bottom_height;
|
||||
else if (strcmp (t->d.v.name, "mini_icon_width") == 0)
|
||||
*result = env->mini_icon_width;
|
||||
else if (strcmp (t->d.v.name, "mini_icon_height") == 0)
|
||||
*result = env->mini_icon_height;
|
||||
else if (strcmp (t->d.v.name, "icon_width") == 0)
|
||||
*result = env->icon_width;
|
||||
else if (strcmp (t->d.v.name, "icon_height") == 0)
|
||||
*result = env->icon_height;
|
||||
else if (strcmp (t->d.v.name, "title_width") == 0)
|
||||
*result = env->title_width;
|
||||
else if (strcmp (t->d.v.name, "title_height") == 0)
|
||||
*result = env->title_height;
|
||||
else
|
||||
{
|
||||
g_set_error (err, META_THEME_ERROR,
|
||||
META_THEME_ERROR_UNKNOWN_VARIABLE,
|
||||
_("Coordinate expression had unknown variable or constant \"%s\""),
|
||||
t->d.v.name);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
pos_eval_helper (PosToken *tokens,
|
||||
int n_tokens,
|
||||
@ -2024,13 +2084,10 @@ pos_eval_helper (PosToken *tokens,
|
||||
int i;
|
||||
PosExpr exprs[MAX_EXPRS];
|
||||
int n_exprs;
|
||||
int ival;
|
||||
double dval;
|
||||
int precedence;
|
||||
|
||||
#if 0
|
||||
g_print ("Pos eval helper on %d tokens:\n", n_tokens);
|
||||
debug_print_tokens (tokens, n_tokens);
|
||||
#endif
|
||||
|
||||
/* Our first goal is to get a list of PosExpr, essentially
|
||||
@ -2087,62 +2144,9 @@ pos_eval_helper (PosToken *tokens,
|
||||
* in a hash, maybe keep width/height out
|
||||
* for optimization purposes
|
||||
*/
|
||||
if (strcmp (t->d.v.name, "width") == 0)
|
||||
exprs[n_exprs].d.int_val = env->rect.width;
|
||||
else if (strcmp (t->d.v.name, "height") == 0)
|
||||
exprs[n_exprs].d.int_val = env->rect.height;
|
||||
else if (env->object_width >= 0 &&
|
||||
strcmp (t->d.v.name, "object_width") == 0)
|
||||
exprs[n_exprs].d.int_val = env->object_width;
|
||||
else if (env->object_height >= 0 &&
|
||||
strcmp (t->d.v.name, "object_height") == 0)
|
||||
exprs[n_exprs].d.int_val = env->object_height;
|
||||
else if (strcmp (t->d.v.name, "left_width") == 0)
|
||||
exprs[n_exprs].d.int_val = env->left_width;
|
||||
else if (strcmp (t->d.v.name, "right_width") == 0)
|
||||
exprs[n_exprs].d.int_val = env->right_width;
|
||||
else if (strcmp (t->d.v.name, "top_height") == 0)
|
||||
exprs[n_exprs].d.int_val = env->top_height;
|
||||
else if (strcmp (t->d.v.name, "bottom_height") == 0)
|
||||
exprs[n_exprs].d.int_val = env->bottom_height;
|
||||
else if (strcmp (t->d.v.name, "mini_icon_width") == 0)
|
||||
exprs[n_exprs].d.int_val = env->mini_icon_width;
|
||||
else if (strcmp (t->d.v.name, "mini_icon_height") == 0)
|
||||
exprs[n_exprs].d.int_val = env->mini_icon_height;
|
||||
else if (strcmp (t->d.v.name, "icon_width") == 0)
|
||||
exprs[n_exprs].d.int_val = env->icon_width;
|
||||
else if (strcmp (t->d.v.name, "icon_height") == 0)
|
||||
exprs[n_exprs].d.int_val = env->icon_height;
|
||||
else if (strcmp (t->d.v.name, "title_width") == 0)
|
||||
exprs[n_exprs].d.int_val = env->title_width;
|
||||
else if (strcmp (t->d.v.name, "title_height") == 0)
|
||||
exprs[n_exprs].d.int_val = env->title_height;
|
||||
/* In practice we only hit this code on initial theme
|
||||
* parse; after that we always optimize constants away
|
||||
*/
|
||||
else if (env->theme &&
|
||||
meta_theme_lookup_int_constant (env->theme,
|
||||
t->d.v.name,
|
||||
&ival))
|
||||
{
|
||||
exprs[n_exprs].d.int_val = ival;
|
||||
}
|
||||
else if (env->theme &&
|
||||
meta_theme_lookup_float_constant (env->theme,
|
||||
t->d.v.name,
|
||||
&dval))
|
||||
{
|
||||
exprs[n_exprs].type = POS_EXPR_DOUBLE;
|
||||
exprs[n_exprs].d.double_val = dval;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_set_error (err, META_THEME_ERROR,
|
||||
META_THEME_ERROR_UNKNOWN_VARIABLE,
|
||||
_("Coordinate expression had unknown variable or constant \"%s\""),
|
||||
t->d.v.name);
|
||||
return FALSE;
|
||||
}
|
||||
if (!pos_eval_get_variable (t, &exprs[n_exprs].d.int_val, env, err))
|
||||
return FALSE;
|
||||
|
||||
++n_exprs;
|
||||
break;
|
||||
|
||||
@ -2232,8 +2236,7 @@ pos_eval_helper (PosToken *tokens,
|
||||
* so very not worth fooling with bison, yet so very painful by hand.
|
||||
*/
|
||||
static gboolean
|
||||
pos_eval (PosToken *tokens,
|
||||
int n_tokens,
|
||||
pos_eval (MetaDrawSpec *spec,
|
||||
const MetaPositionExprEnv *env,
|
||||
int *val_p,
|
||||
GError **err)
|
||||
@ -2242,7 +2245,7 @@ pos_eval (PosToken *tokens,
|
||||
|
||||
*val_p = 0;
|
||||
|
||||
if (pos_eval_helper (tokens, n_tokens, env, &expr, err))
|
||||
if (pos_eval_helper (spec->tokens, spec->n_tokens, env, &expr, err))
|
||||
{
|
||||
switch (expr.type)
|
||||
{
|
||||
@ -2269,7 +2272,7 @@ pos_eval (PosToken *tokens,
|
||||
*/
|
||||
|
||||
gboolean
|
||||
meta_parse_position_expression (const char *expr,
|
||||
meta_parse_position_expression (MetaDrawSpec *spec,
|
||||
const MetaPositionExprEnv *env,
|
||||
int *x_return,
|
||||
int *y_return,
|
||||
@ -2281,73 +2284,55 @@ meta_parse_position_expression (const char *expr,
|
||||
* optionally "object_width" and object_height". Negative numbers
|
||||
* aren't allowed.
|
||||
*/
|
||||
PosToken *tokens;
|
||||
int n_tokens;
|
||||
int val;
|
||||
|
||||
if (!pos_tokenize (expr, &tokens, &n_tokens, err))
|
||||
{
|
||||
g_assert (err == NULL || *err != NULL);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#if 0
|
||||
g_print ("Tokenized \"%s\" to --->\n", expr);
|
||||
debug_print_tokens (tokens, n_tokens);
|
||||
#endif
|
||||
|
||||
if (pos_eval (tokens, n_tokens, env, &val, err))
|
||||
{
|
||||
if (x_return)
|
||||
*x_return = env->rect.x + val;
|
||||
if (y_return)
|
||||
*y_return = env->rect.y + val;
|
||||
free_tokens (tokens, n_tokens);
|
||||
return TRUE;
|
||||
}
|
||||
if (spec->constant)
|
||||
val = spec->value;
|
||||
else
|
||||
{
|
||||
g_assert (err == NULL || *err != NULL);
|
||||
free_tokens (tokens, n_tokens);
|
||||
return FALSE;
|
||||
if (pos_eval (spec, env, &spec->value, err) == FALSE)
|
||||
{
|
||||
g_assert (err == NULL || *err != NULL);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
val = spec->value;
|
||||
}
|
||||
|
||||
if (x_return)
|
||||
*x_return = env->rect.x + val;
|
||||
if (y_return)
|
||||
*y_return = env->rect.y + val;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
gboolean
|
||||
meta_parse_size_expression (const char *expr,
|
||||
meta_parse_size_expression (MetaDrawSpec *spec,
|
||||
const MetaPositionExprEnv *env,
|
||||
int *val_return,
|
||||
GError **err)
|
||||
{
|
||||
PosToken *tokens;
|
||||
int n_tokens;
|
||||
int val;
|
||||
|
||||
if (!pos_tokenize (expr, &tokens, &n_tokens, err))
|
||||
if (spec->constant)
|
||||
val = spec->value;
|
||||
else
|
||||
{
|
||||
g_assert (err == NULL || *err != NULL);
|
||||
return FALSE;
|
||||
if (pos_eval (spec, env, &spec->value, err) == FALSE)
|
||||
{
|
||||
g_assert (err == NULL || *err != NULL);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
val = spec->value;
|
||||
}
|
||||
|
||||
#if 0
|
||||
g_print ("Tokenized \"%s\" to --->\n", expr);
|
||||
debug_print_tokens (tokens, n_tokens);
|
||||
#endif
|
||||
if (val_return)
|
||||
*val_return = MAX (val, 1); /* require that sizes be at least 1x1 */
|
||||
|
||||
if (pos_eval (tokens, n_tokens, env, &val, err))
|
||||
{
|
||||
if (val_return)
|
||||
*val_return = MAX (val, 1); /* require that sizes be at least 1x1 */
|
||||
free_tokens (tokens, n_tokens);
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_assert (err == NULL || *err != NULL);
|
||||
free_tokens (tokens, n_tokens);
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* To do this we tokenize, replace variable tokens
|
||||
@ -2356,85 +2341,71 @@ meta_parse_size_expression (const char *expr,
|
||||
* lookups to eval them. Obviously it's a tradeoff that
|
||||
* slows down theme load times.
|
||||
*/
|
||||
char*
|
||||
gboolean
|
||||
meta_theme_replace_constants (MetaTheme *theme,
|
||||
const char *expr,
|
||||
PosToken *tokens,
|
||||
int n_tokens,
|
||||
GError **err)
|
||||
{
|
||||
PosToken *tokens;
|
||||
int n_tokens;
|
||||
int i;
|
||||
GString *str;
|
||||
char buf[G_ASCII_DTOSTR_BUF_SIZE];
|
||||
double dval;
|
||||
int ival;
|
||||
gboolean is_constant = TRUE;
|
||||
|
||||
if (!pos_tokenize (expr, &tokens, &n_tokens, err))
|
||||
{
|
||||
g_assert (err == NULL || *err != NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if 0
|
||||
g_print ("Tokenized \"%s\" to --->\n", expr);
|
||||
debug_print_tokens (tokens, n_tokens);
|
||||
#endif
|
||||
|
||||
str = g_string_new (NULL);
|
||||
|
||||
/* Loop through tokenized string looking for variables to replace */
|
||||
for (i = 0; i < n_tokens; i++)
|
||||
{
|
||||
PosToken *t = &tokens[i];
|
||||
|
||||
/* spaces so we don't accidentally merge variables
|
||||
* or anything like that
|
||||
*/
|
||||
if (i > 0)
|
||||
g_string_append_c (str, ' ');
|
||||
|
||||
switch (t->type)
|
||||
if (t->type == POS_TOKEN_VARIABLE)
|
||||
{
|
||||
case POS_TOKEN_INT:
|
||||
g_string_append_printf (str, "%d", t->d.i.val);
|
||||
break;
|
||||
case POS_TOKEN_DOUBLE:
|
||||
g_ascii_formatd (buf, G_ASCII_DTOSTR_BUF_SIZE,
|
||||
"%g", t->d.d.val);
|
||||
g_string_append (str, buf);
|
||||
break;
|
||||
case POS_TOKEN_OPEN_PAREN:
|
||||
g_string_append_c (str, '(');
|
||||
break;
|
||||
case POS_TOKEN_CLOSE_PAREN:
|
||||
g_string_append_c (str, ')');
|
||||
break;
|
||||
case POS_TOKEN_VARIABLE:
|
||||
if (meta_theme_lookup_int_constant (theme, t->d.v.name, &ival))
|
||||
g_string_append_printf (str, "%d", ival);
|
||||
{
|
||||
t->type = POS_TOKEN_INT;
|
||||
t->d.i.val = ival;
|
||||
}
|
||||
else if (meta_theme_lookup_float_constant (theme, t->d.v.name, &dval))
|
||||
{
|
||||
g_ascii_formatd (buf, G_ASCII_DTOSTR_BUF_SIZE,
|
||||
"%g", dval);
|
||||
g_string_append (str, buf);
|
||||
t->type = POS_TOKEN_DOUBLE;
|
||||
t->d.d.val = dval;
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
g_string_append (str, t->d.v.name);
|
||||
/* If we've found a variable that cannot be replaced then the
|
||||
expression is not a constant expression and we want to
|
||||
replace it with a GQuark */
|
||||
|
||||
t->d.v.name_quark = g_quark_from_string (t->d.v.name);
|
||||
is_constant = FALSE;
|
||||
}
|
||||
break;
|
||||
case POS_TOKEN_OPERATOR:
|
||||
g_string_append (str, op_name (t->d.o.op));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return is_constant;
|
||||
}
|
||||
|
||||
static int
|
||||
parse_x_position_unchecked (MetaDrawSpec *spec,
|
||||
const MetaPositionExprEnv *env)
|
||||
{
|
||||
int retval;
|
||||
GError *error;
|
||||
|
||||
retval = 0;
|
||||
error = NULL;
|
||||
if (!meta_parse_position_expression (spec, env, &retval, NULL, &error))
|
||||
{
|
||||
meta_warning (_("Theme contained an expression that resulted in an error: %s\n"),
|
||||
error->message);
|
||||
|
||||
g_error_free (error);
|
||||
}
|
||||
|
||||
free_tokens (tokens, n_tokens);
|
||||
|
||||
return g_string_free (str, FALSE);
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int
|
||||
parse_x_position_unchecked (const char *expr,
|
||||
parse_y_position_unchecked (MetaDrawSpec *spec,
|
||||
const MetaPositionExprEnv *env)
|
||||
{
|
||||
int retval;
|
||||
@ -2442,12 +2413,10 @@ parse_x_position_unchecked (const char *expr,
|
||||
|
||||
retval = 0;
|
||||
error = NULL;
|
||||
if (!meta_parse_position_expression (expr, env,
|
||||
&retval, NULL,
|
||||
&error))
|
||||
if (!meta_parse_position_expression (spec, env, NULL, &retval, &error))
|
||||
{
|
||||
meta_warning (_("Theme contained an expression \"%s\" that resulted in an error: %s\n"),
|
||||
expr, error->message);
|
||||
meta_warning (_("Theme contained an expression that resulted in an error: %s\n"),
|
||||
error->message);
|
||||
|
||||
g_error_free (error);
|
||||
}
|
||||
@ -2456,29 +2425,7 @@ parse_x_position_unchecked (const char *expr,
|
||||
}
|
||||
|
||||
static int
|
||||
parse_y_position_unchecked (const char *expr,
|
||||
const MetaPositionExprEnv *env)
|
||||
{
|
||||
int retval;
|
||||
GError *error;
|
||||
|
||||
retval = 0;
|
||||
error = NULL;
|
||||
if (!meta_parse_position_expression (expr, env,
|
||||
NULL, &retval,
|
||||
&error))
|
||||
{
|
||||
meta_warning (_("Theme contained an expression \"%s\" that resulted in an error: %s\n"),
|
||||
expr, error->message);
|
||||
|
||||
g_error_free (error);
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int
|
||||
parse_size_unchecked (const char *expr,
|
||||
parse_size_unchecked (MetaDrawSpec *spec,
|
||||
MetaPositionExprEnv *env)
|
||||
{
|
||||
int retval;
|
||||
@ -2486,11 +2433,10 @@ parse_size_unchecked (const char *expr,
|
||||
|
||||
retval = 0;
|
||||
error = NULL;
|
||||
if (!meta_parse_size_expression (expr, env,
|
||||
&retval, &error))
|
||||
if (!meta_parse_size_expression (spec, env, &retval, &error))
|
||||
{
|
||||
meta_warning (_("Theme contained an expression \"%s\" that resulted in an error: %s\n"),
|
||||
expr, error->message);
|
||||
meta_warning (_("Theme contained an expression that resulted in an error: %s\n"),
|
||||
error->message);
|
||||
|
||||
g_error_free (error);
|
||||
}
|
||||
@ -2498,6 +2444,41 @@ parse_size_unchecked (const char *expr,
|
||||
return retval;
|
||||
}
|
||||
|
||||
void
|
||||
meta_draw_spec_free (MetaDrawSpec *spec)
|
||||
{
|
||||
free_tokens (spec->tokens, spec->n_tokens);
|
||||
g_slice_free (MetaDrawSpec, spec);
|
||||
}
|
||||
|
||||
MetaDrawSpec *
|
||||
meta_draw_spec_new (MetaTheme *theme,
|
||||
const char *expr,
|
||||
GError **error)
|
||||
{
|
||||
MetaDrawSpec *spec;
|
||||
|
||||
spec = g_slice_new0 (MetaDrawSpec);
|
||||
|
||||
pos_tokenize (expr, &spec->tokens, &spec->n_tokens, NULL);
|
||||
|
||||
spec->constant = meta_theme_replace_constants (theme, spec->tokens,
|
||||
spec->n_tokens, NULL);
|
||||
if (spec->constant)
|
||||
{
|
||||
gboolean result;
|
||||
|
||||
result = pos_eval (spec, NULL, &spec->value, error);
|
||||
if (result == FALSE)
|
||||
{
|
||||
meta_draw_spec_free (spec);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return spec;
|
||||
}
|
||||
|
||||
MetaDrawOp*
|
||||
meta_draw_op_new (MetaDrawType type)
|
||||
{
|
||||
@ -2581,130 +2562,145 @@ meta_draw_op_free (MetaDrawOp *op)
|
||||
case META_DRAW_LINE:
|
||||
if (op->data.line.color_spec)
|
||||
meta_color_spec_free (op->data.line.color_spec);
|
||||
g_free (op->data.line.x1);
|
||||
g_free (op->data.line.y1);
|
||||
g_free (op->data.line.x2);
|
||||
g_free (op->data.line.y2);
|
||||
|
||||
meta_draw_spec_free (op->data.line.x1);
|
||||
meta_draw_spec_free (op->data.line.y1);
|
||||
meta_draw_spec_free (op->data.line.x2);
|
||||
meta_draw_spec_free (op->data.line.y2);
|
||||
break;
|
||||
|
||||
case META_DRAW_RECTANGLE:
|
||||
if (op->data.rectangle.color_spec)
|
||||
g_free (op->data.rectangle.color_spec);
|
||||
g_free (op->data.rectangle.x);
|
||||
g_free (op->data.rectangle.y);
|
||||
g_free (op->data.rectangle.width);
|
||||
g_free (op->data.rectangle.height);
|
||||
|
||||
meta_draw_spec_free (op->data.rectangle.x);
|
||||
meta_draw_spec_free (op->data.rectangle.y);
|
||||
meta_draw_spec_free (op->data.rectangle.width);
|
||||
meta_draw_spec_free (op->data.rectangle.height);
|
||||
break;
|
||||
|
||||
case META_DRAW_ARC:
|
||||
if (op->data.arc.color_spec)
|
||||
g_free (op->data.arc.color_spec);
|
||||
g_free (op->data.arc.x);
|
||||
g_free (op->data.arc.y);
|
||||
g_free (op->data.arc.width);
|
||||
g_free (op->data.arc.height);
|
||||
|
||||
meta_draw_spec_free (op->data.arc.x);
|
||||
meta_draw_spec_free (op->data.arc.y);
|
||||
meta_draw_spec_free (op->data.arc.width);
|
||||
meta_draw_spec_free (op->data.arc.height);
|
||||
break;
|
||||
|
||||
case META_DRAW_CLIP:
|
||||
g_free (op->data.clip.x);
|
||||
g_free (op->data.clip.y);
|
||||
g_free (op->data.clip.width);
|
||||
g_free (op->data.clip.height);
|
||||
meta_draw_spec_free (op->data.clip.x);
|
||||
meta_draw_spec_free (op->data.clip.y);
|
||||
meta_draw_spec_free (op->data.clip.width);
|
||||
meta_draw_spec_free (op->data.clip.height);
|
||||
break;
|
||||
|
||||
case META_DRAW_TINT:
|
||||
if (op->data.tint.color_spec)
|
||||
meta_color_spec_free (op->data.tint.color_spec);
|
||||
|
||||
if (op->data.tint.alpha_spec)
|
||||
meta_alpha_gradient_spec_free (op->data.tint.alpha_spec);
|
||||
g_free (op->data.tint.x);
|
||||
g_free (op->data.tint.y);
|
||||
g_free (op->data.tint.width);
|
||||
g_free (op->data.tint.height);
|
||||
|
||||
meta_draw_spec_free (op->data.tint.x);
|
||||
meta_draw_spec_free (op->data.tint.y);
|
||||
meta_draw_spec_free (op->data.tint.width);
|
||||
meta_draw_spec_free (op->data.tint.height);
|
||||
break;
|
||||
|
||||
case META_DRAW_GRADIENT:
|
||||
if (op->data.gradient.gradient_spec)
|
||||
meta_gradient_spec_free (op->data.gradient.gradient_spec);
|
||||
|
||||
if (op->data.gradient.alpha_spec)
|
||||
meta_alpha_gradient_spec_free (op->data.gradient.alpha_spec);
|
||||
g_free (op->data.gradient.x);
|
||||
g_free (op->data.gradient.y);
|
||||
g_free (op->data.gradient.width);
|
||||
g_free (op->data.gradient.height);
|
||||
|
||||
meta_draw_spec_free (op->data.gradient.x);
|
||||
meta_draw_spec_free (op->data.gradient.y);
|
||||
meta_draw_spec_free (op->data.gradient.width);
|
||||
meta_draw_spec_free (op->data.gradient.height);
|
||||
break;
|
||||
|
||||
case META_DRAW_IMAGE:
|
||||
if (op->data.image.alpha_spec)
|
||||
meta_alpha_gradient_spec_free (op->data.image.alpha_spec);
|
||||
|
||||
if (op->data.image.pixbuf)
|
||||
g_object_unref (G_OBJECT (op->data.image.pixbuf));
|
||||
|
||||
if (op->data.image.colorize_spec)
|
||||
meta_color_spec_free (op->data.image.colorize_spec);
|
||||
|
||||
if (op->data.image.colorize_cache_pixbuf)
|
||||
g_object_unref (G_OBJECT (op->data.image.colorize_cache_pixbuf));
|
||||
g_free (op->data.image.x);
|
||||
g_free (op->data.image.y);
|
||||
g_free (op->data.image.width);
|
||||
g_free (op->data.image.height);
|
||||
|
||||
meta_draw_spec_free (op->data.image.x);
|
||||
meta_draw_spec_free (op->data.image.y);
|
||||
meta_draw_spec_free (op->data.image.width);
|
||||
meta_draw_spec_free (op->data.image.height);
|
||||
break;
|
||||
|
||||
case META_DRAW_GTK_ARROW:
|
||||
g_free (op->data.gtk_arrow.x);
|
||||
g_free (op->data.gtk_arrow.y);
|
||||
g_free (op->data.gtk_arrow.width);
|
||||
g_free (op->data.gtk_arrow.height);
|
||||
meta_draw_spec_free (op->data.gtk_arrow.x);
|
||||
meta_draw_spec_free (op->data.gtk_arrow.y);
|
||||
meta_draw_spec_free (op->data.gtk_arrow.width);
|
||||
meta_draw_spec_free (op->data.gtk_arrow.height);
|
||||
break;
|
||||
|
||||
case META_DRAW_GTK_BOX:
|
||||
g_free (op->data.gtk_box.x);
|
||||
g_free (op->data.gtk_box.y);
|
||||
g_free (op->data.gtk_box.width);
|
||||
g_free (op->data.gtk_box.height);
|
||||
meta_draw_spec_free (op->data.gtk_box.x);
|
||||
meta_draw_spec_free (op->data.gtk_box.y);
|
||||
meta_draw_spec_free (op->data.gtk_box.width);
|
||||
meta_draw_spec_free (op->data.gtk_box.height);
|
||||
break;
|
||||
|
||||
case META_DRAW_GTK_VLINE:
|
||||
g_free (op->data.gtk_vline.x);
|
||||
g_free (op->data.gtk_vline.y1);
|
||||
g_free (op->data.gtk_vline.y2);
|
||||
meta_draw_spec_free (op->data.gtk_vline.x);
|
||||
meta_draw_spec_free (op->data.gtk_vline.y1);
|
||||
meta_draw_spec_free (op->data.gtk_vline.y2);
|
||||
break;
|
||||
|
||||
case META_DRAW_ICON:
|
||||
if (op->data.icon.alpha_spec)
|
||||
meta_alpha_gradient_spec_free (op->data.icon.alpha_spec);
|
||||
g_free (op->data.icon.x);
|
||||
g_free (op->data.icon.y);
|
||||
g_free (op->data.icon.width);
|
||||
g_free (op->data.icon.height);
|
||||
|
||||
meta_draw_spec_free (op->data.icon.x);
|
||||
meta_draw_spec_free (op->data.icon.y);
|
||||
meta_draw_spec_free (op->data.icon.width);
|
||||
meta_draw_spec_free (op->data.icon.height);
|
||||
break;
|
||||
|
||||
case META_DRAW_TITLE:
|
||||
if (op->data.title.color_spec)
|
||||
meta_color_spec_free (op->data.title.color_spec);
|
||||
g_free (op->data.title.x);
|
||||
g_free (op->data.title.y);
|
||||
|
||||
meta_draw_spec_free (op->data.title.x);
|
||||
meta_draw_spec_free (op->data.title.y);
|
||||
break;
|
||||
|
||||
case META_DRAW_OP_LIST:
|
||||
if (op->data.op_list.op_list)
|
||||
meta_draw_op_list_unref (op->data.op_list.op_list);
|
||||
g_free (op->data.op_list.x);
|
||||
g_free (op->data.op_list.y);
|
||||
g_free (op->data.op_list.width);
|
||||
g_free (op->data.op_list.height);
|
||||
|
||||
meta_draw_spec_free (op->data.op_list.x);
|
||||
meta_draw_spec_free (op->data.op_list.y);
|
||||
meta_draw_spec_free (op->data.op_list.width);
|
||||
meta_draw_spec_free (op->data.op_list.height);
|
||||
break;
|
||||
|
||||
case META_DRAW_TILE:
|
||||
if (op->data.tile.op_list)
|
||||
meta_draw_op_list_unref (op->data.tile.op_list);
|
||||
g_free (op->data.tile.x);
|
||||
g_free (op->data.tile.y);
|
||||
g_free (op->data.tile.width);
|
||||
g_free (op->data.tile.height);
|
||||
g_free (op->data.tile.tile_xoffset);
|
||||
g_free (op->data.tile.tile_yoffset);
|
||||
g_free (op->data.tile.tile_width);
|
||||
g_free (op->data.tile.tile_height);
|
||||
|
||||
meta_draw_spec_free (op->data.tile.x);
|
||||
meta_draw_spec_free (op->data.tile.y);
|
||||
meta_draw_spec_free (op->data.tile.width);
|
||||
meta_draw_spec_free (op->data.tile.height);
|
||||
meta_draw_spec_free (op->data.tile.tile_xoffset);
|
||||
meta_draw_spec_free (op->data.tile.tile_yoffset);
|
||||
meta_draw_spec_free (op->data.tile.tile_width);
|
||||
meta_draw_spec_free (op->data.tile.tile_height);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -3258,7 +3254,7 @@ fill_env (MetaPositionExprEnv *env,
|
||||
|
||||
env->title_width = info->title_layout_width;
|
||||
env->title_height = info->title_layout_height;
|
||||
env->theme = NULL; /* not required, constants have been optimized out */
|
||||
env->theme = meta_current_theme;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -3293,7 +3289,7 @@ meta_draw_op_draw_with_env (const MetaDrawOp *op,
|
||||
}
|
||||
|
||||
x1 = parse_x_position_unchecked (op->data.line.x1, env);
|
||||
y1 = parse_y_position_unchecked (op->data.line.y1, env);
|
||||
y1 = parse_y_position_unchecked (op->data.line.y1, env);
|
||||
x2 = parse_x_position_unchecked (op->data.line.x2, env);
|
||||
y2 = parse_y_position_unchecked (op->data.line.y2, env);
|
||||
|
||||
@ -4463,8 +4459,6 @@ meta_frame_style_set_validate (MetaFrameStyleSet *style_set,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static MetaTheme *meta_current_theme = NULL;
|
||||
|
||||
MetaTheme*
|
||||
meta_theme_get_current (void)
|
||||
{
|
||||
@ -4542,6 +4536,22 @@ meta_theme_new (void)
|
||||
g_free,
|
||||
(GDestroyNotify) meta_frame_style_set_unref);
|
||||
|
||||
/* Create our variable quarks so we can look up variables without
|
||||
having to strcmp for the names */
|
||||
theme->quark_width = g_quark_from_static_string ("width");
|
||||
theme->quark_height = g_quark_from_static_string ("height");
|
||||
theme->quark_object_width = g_quark_from_static_string ("object_width");
|
||||
theme->quark_object_height = g_quark_from_static_string ("object_height");
|
||||
theme->quark_left_width = g_quark_from_static_string ("left_width");
|
||||
theme->quark_right_width = g_quark_from_static_string ("right_width");
|
||||
theme->quark_top_height = g_quark_from_static_string ("top_height");
|
||||
theme->quark_bottom_height = g_quark_from_static_string ("bottom_height");
|
||||
theme->quark_mini_icon_width = g_quark_from_static_string ("mini_icon_width");
|
||||
theme->quark_mini_icon_height = g_quark_from_static_string ("mini_icon_height");
|
||||
theme->quark_icon_width = g_quark_from_static_string ("icon_width");
|
||||
theme->quark_icon_height = g_quark_from_static_string ("icon_height");
|
||||
theme->quark_title_width = g_quark_from_static_string ("title_width");
|
||||
theme->quark_title_height = g_quark_from_static_string ("title_height");
|
||||
return theme;
|
||||
}
|
||||
|
||||
|
212
src/theme.h
212
src/theme.h
@ -214,10 +214,16 @@ struct _MetaColorSpec
|
||||
MetaColorSpec *foreground;
|
||||
MetaColorSpec *background;
|
||||
double alpha;
|
||||
|
||||
gboolean color_set;
|
||||
GdkColor color;
|
||||
} blend;
|
||||
struct {
|
||||
MetaColorSpec *base;
|
||||
double factor;
|
||||
|
||||
gboolean color_set;
|
||||
GdkColor color;
|
||||
} shade;
|
||||
} data;
|
||||
};
|
||||
@ -275,6 +281,64 @@ typedef enum
|
||||
META_DRAW_TILE
|
||||
} MetaDrawType;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
POS_TOKEN_INT,
|
||||
POS_TOKEN_DOUBLE,
|
||||
POS_TOKEN_OPERATOR,
|
||||
POS_TOKEN_VARIABLE,
|
||||
POS_TOKEN_OPEN_PAREN,
|
||||
POS_TOKEN_CLOSE_PAREN
|
||||
} PosTokenType;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
POS_OP_NONE,
|
||||
POS_OP_ADD,
|
||||
POS_OP_SUBTRACT,
|
||||
POS_OP_MULTIPLY,
|
||||
POS_OP_DIVIDE,
|
||||
POS_OP_MOD,
|
||||
POS_OP_MAX,
|
||||
POS_OP_MIN
|
||||
} PosOperatorType;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
PosTokenType type;
|
||||
|
||||
union
|
||||
{
|
||||
struct {
|
||||
int val;
|
||||
} i;
|
||||
|
||||
struct {
|
||||
double val;
|
||||
} d;
|
||||
|
||||
struct {
|
||||
PosOperatorType op;
|
||||
} o;
|
||||
|
||||
struct {
|
||||
char *name;
|
||||
GQuark name_quark;
|
||||
} v;
|
||||
|
||||
} d;
|
||||
} PosToken;
|
||||
|
||||
typedef struct _MetaDrawSpec
|
||||
{
|
||||
int value;
|
||||
|
||||
PosToken *tokens;
|
||||
int n_tokens;
|
||||
|
||||
gboolean constant : 1; /* Does the expression contain any variables? */
|
||||
} MetaDrawSpec;
|
||||
|
||||
struct _MetaDrawOp
|
||||
{
|
||||
MetaDrawType type;
|
||||
@ -287,65 +351,66 @@ struct _MetaDrawOp
|
||||
int dash_on_length;
|
||||
int dash_off_length;
|
||||
int width;
|
||||
char *x1;
|
||||
char *y1;
|
||||
char *x2;
|
||||
char *y2;
|
||||
MetaDrawSpec *x1;
|
||||
MetaDrawSpec *y1;
|
||||
MetaDrawSpec *x2;
|
||||
MetaDrawSpec *y2;
|
||||
} line;
|
||||
|
||||
struct {
|
||||
MetaColorSpec *color_spec;
|
||||
gboolean filled;
|
||||
char *x;
|
||||
char *y;
|
||||
char *width;
|
||||
char *height;
|
||||
MetaDrawSpec *x;
|
||||
MetaDrawSpec *y;
|
||||
MetaDrawSpec *width;
|
||||
MetaDrawSpec *height;
|
||||
} rectangle;
|
||||
|
||||
struct {
|
||||
MetaColorSpec *color_spec;
|
||||
gboolean filled;
|
||||
char *x;
|
||||
char *y;
|
||||
char *width;
|
||||
char *height;
|
||||
MetaDrawSpec *x;
|
||||
MetaDrawSpec *y;
|
||||
MetaDrawSpec *width;
|
||||
MetaDrawSpec *height;
|
||||
double start_angle;
|
||||
double extent_angle;
|
||||
} arc;
|
||||
|
||||
struct {
|
||||
char *x;
|
||||
char *y;
|
||||
char *width;
|
||||
char *height;
|
||||
MetaDrawSpec *x;
|
||||
MetaDrawSpec *y;
|
||||
MetaDrawSpec *width;
|
||||
MetaDrawSpec *height;
|
||||
} clip;
|
||||
|
||||
struct {
|
||||
MetaColorSpec *color_spec;
|
||||
MetaAlphaGradientSpec *alpha_spec;
|
||||
char *x;
|
||||
char *y;
|
||||
char *width;
|
||||
char *height;
|
||||
MetaDrawSpec *x;
|
||||
MetaDrawSpec *y;
|
||||
MetaDrawSpec *width;
|
||||
MetaDrawSpec *height;
|
||||
} tint;
|
||||
|
||||
struct {
|
||||
MetaGradientSpec *gradient_spec;
|
||||
MetaAlphaGradientSpec *alpha_spec;
|
||||
char *x;
|
||||
char *y;
|
||||
char *width;
|
||||
char *height;
|
||||
MetaDrawSpec *x;
|
||||
MetaDrawSpec *y;
|
||||
MetaDrawSpec *width;
|
||||
MetaDrawSpec *height;
|
||||
} gradient;
|
||||
|
||||
struct {
|
||||
MetaColorSpec *colorize_spec;
|
||||
MetaAlphaGradientSpec *alpha_spec;
|
||||
GdkPixbuf *pixbuf;
|
||||
char *x;
|
||||
char *y;
|
||||
char *width;
|
||||
char *height;
|
||||
MetaDrawSpec *x;
|
||||
MetaDrawSpec *y;
|
||||
MetaDrawSpec *width;
|
||||
MetaDrawSpec *height;
|
||||
|
||||
guint32 colorize_cache_pixel;
|
||||
GdkPixbuf *colorize_cache_pixbuf;
|
||||
MetaImageFillType fill_type;
|
||||
@ -358,61 +423,62 @@ struct _MetaDrawOp
|
||||
GtkShadowType shadow;
|
||||
GtkArrowType arrow;
|
||||
gboolean filled;
|
||||
char *x;
|
||||
char *y;
|
||||
char *width;
|
||||
char *height;
|
||||
|
||||
MetaDrawSpec *x;
|
||||
MetaDrawSpec *y;
|
||||
MetaDrawSpec *width;
|
||||
MetaDrawSpec *height;
|
||||
} gtk_arrow;
|
||||
|
||||
struct {
|
||||
GtkStateType state;
|
||||
GtkShadowType shadow;
|
||||
char *x;
|
||||
char *y;
|
||||
char *width;
|
||||
char *height;
|
||||
MetaDrawSpec *x;
|
||||
MetaDrawSpec *y;
|
||||
MetaDrawSpec *width;
|
||||
MetaDrawSpec *height;
|
||||
} gtk_box;
|
||||
|
||||
struct {
|
||||
GtkStateType state;
|
||||
char *x;
|
||||
char *y1;
|
||||
char *y2;
|
||||
MetaDrawSpec *x;
|
||||
MetaDrawSpec *y1;
|
||||
MetaDrawSpec *y2;
|
||||
} gtk_vline;
|
||||
|
||||
struct {
|
||||
MetaAlphaGradientSpec *alpha_spec;
|
||||
char *x;
|
||||
char *y;
|
||||
char *width;
|
||||
char *height;
|
||||
MetaDrawSpec *x;
|
||||
MetaDrawSpec *y;
|
||||
MetaDrawSpec *width;
|
||||
MetaDrawSpec *height;
|
||||
MetaImageFillType fill_type;
|
||||
} icon;
|
||||
|
||||
struct {
|
||||
MetaColorSpec *color_spec;
|
||||
char *x;
|
||||
char *y;
|
||||
MetaDrawSpec *x;
|
||||
MetaDrawSpec *y;
|
||||
} title;
|
||||
|
||||
struct {
|
||||
MetaDrawOpList *op_list;
|
||||
char *x;
|
||||
char *y;
|
||||
char *width;
|
||||
char *height;
|
||||
MetaDrawSpec *x;
|
||||
MetaDrawSpec *y;
|
||||
MetaDrawSpec *width;
|
||||
MetaDrawSpec *height;
|
||||
} op_list;
|
||||
|
||||
struct {
|
||||
MetaDrawOpList *op_list;
|
||||
char *x;
|
||||
char *y;
|
||||
char *width;
|
||||
char *height;
|
||||
char *tile_xoffset;
|
||||
char *tile_yoffset;
|
||||
char *tile_width;
|
||||
char *tile_height;
|
||||
MetaDrawSpec *x;
|
||||
MetaDrawSpec *y;
|
||||
MetaDrawSpec *width;
|
||||
MetaDrawSpec *height;
|
||||
MetaDrawSpec *tile_xoffset;
|
||||
MetaDrawSpec *tile_yoffset;
|
||||
MetaDrawSpec *tile_width;
|
||||
MetaDrawSpec *tile_height;
|
||||
} tile;
|
||||
|
||||
} data;
|
||||
@ -597,6 +663,21 @@ struct _MetaTheme
|
||||
MetaFrameStyleSet *style_sets_by_type[META_FRAME_TYPE_LAST];
|
||||
|
||||
GdkPixbuf *fallback_icon, *fallback_mini_icon;
|
||||
|
||||
GQuark quark_width;
|
||||
GQuark quark_height;
|
||||
GQuark quark_object_width;
|
||||
GQuark quark_object_height;
|
||||
GQuark quark_left_width;
|
||||
GQuark quark_right_width;
|
||||
GQuark quark_top_height;
|
||||
GQuark quark_bottom_height;
|
||||
GQuark quark_mini_icon_width;
|
||||
GQuark quark_mini_icon_height;
|
||||
GQuark quark_icon_width;
|
||||
GQuark quark_icon_height;
|
||||
GQuark quark_title_width;
|
||||
GQuark quark_title_height;
|
||||
};
|
||||
|
||||
struct _MetaPositionExprEnv
|
||||
@ -643,16 +724,21 @@ void meta_frame_layout_calc_geometry (const MetaFrameLayout *layout
|
||||
gboolean meta_frame_layout_validate (const MetaFrameLayout *layout,
|
||||
GError **error);
|
||||
|
||||
gboolean meta_parse_position_expression (const char *expr,
|
||||
gboolean meta_parse_position_expression (MetaDrawSpec *spec,
|
||||
const MetaPositionExprEnv *env,
|
||||
int *x_return,
|
||||
int *y_return,
|
||||
GError **err);
|
||||
gboolean meta_parse_size_expression (const char *expr,
|
||||
gboolean meta_parse_size_expression (MetaDrawSpec *spec,
|
||||
const MetaPositionExprEnv *env,
|
||||
int *val_return,
|
||||
GError **err);
|
||||
|
||||
MetaDrawSpec* meta_draw_spec_new (MetaTheme *theme,
|
||||
const char *expr,
|
||||
GError **error);
|
||||
void meta_draw_spec_free (MetaDrawSpec *spec);
|
||||
|
||||
MetaColorSpec* meta_color_spec_new (MetaColorSpecType type);
|
||||
MetaColorSpec* meta_color_spec_new_from_string (const char *str,
|
||||
GError **err);
|
||||
@ -833,9 +919,10 @@ gboolean meta_theme_lookup_color_constant (MetaTheme *theme,
|
||||
const char *name,
|
||||
char **value);
|
||||
|
||||
char* meta_theme_replace_constants (MetaTheme *theme,
|
||||
const char *expr,
|
||||
GError **err);
|
||||
gboolean meta_theme_replace_constants (MetaTheme *theme,
|
||||
PosToken *tokens,
|
||||
int n_tokens,
|
||||
GError **err);
|
||||
|
||||
/* random stuff */
|
||||
|
||||
@ -877,6 +964,7 @@ const char* meta_image_fill_type_to_string (MetaImageFillType f
|
||||
|
||||
guint meta_theme_earliest_version_with_button (MetaButtonType type);
|
||||
|
||||
|
||||
#define META_THEME_ALLOWS(theme, feature) (theme->format_version >= feature)
|
||||
|
||||
/* What version of the theme file format were various features introduced in? */
|
||||
|
31
src/ui.c
31
src/ui.c
@ -961,3 +961,34 @@ meta_ui_get_direction (void)
|
||||
|
||||
return META_UI_DIRECTION_LTR;
|
||||
}
|
||||
|
||||
GdkPixbuf *
|
||||
meta_ui_get_pixbuf_from_pixmap (Pixmap pmap)
|
||||
{
|
||||
GdkPixmap *gpmap;
|
||||
GdkScreen *screen;
|
||||
GdkPixbuf *pixbuf;
|
||||
GdkColormap *cmap;
|
||||
int width, height, depth;
|
||||
|
||||
gpmap = gdk_pixmap_foreign_new (pmap);
|
||||
screen = gdk_drawable_get_screen (gpmap);
|
||||
|
||||
gdk_drawable_get_size (GDK_DRAWABLE (gpmap), &width, &height);
|
||||
|
||||
depth = gdk_drawable_get_depth (GDK_DRAWABLE (gpmap));
|
||||
if (depth <= 24)
|
||||
cmap = gdk_screen_get_rgb_colormap (screen);
|
||||
else
|
||||
cmap = gdk_screen_get_rgba_colormap (screen);
|
||||
|
||||
pixbuf = gdk_pixbuf_get_from_drawable (NULL, gpmap, cmap, 0, 0, 0, 0,
|
||||
width, height);
|
||||
|
||||
g_object_unref (gpmap);
|
||||
|
||||
return pixbuf;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user