diff -urN libwnck.orig/config.h.in libwnck.new/config.h.in
--- libwnck.orig/config.h.in 2008-08-06 23:43:14.009985000 +0100
+++ libwnck.new/config.h.in 2008-08-06 23:43:40.045900000 +0100
@@ -32,6 +32,7 @@
/* Define if you have libstartup-notification */
#undef HAVE_STARTUP_NOTIFICATION
+#undef HAVE_XTSOL
/* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H
diff -urN libwnck.orig/configure.in libwnck.new/configure.in
--- libwnck.orig/configure.ac 2008-08-06 23:43:14.618321000 +0100
+++ libwnck.new/configure.ac 2008-08-06 23:43:40.049192000 +0100
@@ -172,6 +172,15 @@ fi
AC_SUBST(GDK_PIXBUF_CSOURCE)
+case "$host" in
+ *-*-solaris*)
+ AC_CHECK_HEADERS(X11/extensions/Xtsol.h sys/tsol/label_macro.h libgnometsol/userattr.h,
+ AC_DEFINE(HAVE_XTSOL, , [Building with XTSOL support]))
+ ;;
+ *)
+ ;;
+esac
+
##################################################
# Checks for gtk-doc and docbook-tools
##################################################
diff -urN libwnck.orig/libwnck/pager.c libwnck.new/libwnck/pager.c
--- libwnck.orig/libwnck/pager.c 2008-08-06 23:43:13.356087000 +0100
+++ libwnck.new/libwnck/pager.c 2008-08-06 23:43:40.066590000 +0100
@@ -29,6 +29,7 @@
#include <math.h>
#include <glib/gi18n-lib.h>
+#include <config.h>
#include "pager.h"
#include "workspace.h"
#include "window.h"
@@ -59,6 +60,11 @@
* layout.
*/
+#ifdef HAVE_XTSOL
+#include "trusted-tooltips.h"
+#include "wnck-tsol.h"
+#endif
+
#define N_SCREEN_CONNECTIONS 11
struct _WnckPagerPrivate
@@ -82,6 +88,9 @@ struct _WnckPagerPrivate
WnckWindow *drag_window;
GdkPixbuf *bg_cache;
+#ifdef HAVE_XTSOL
+ TrustedTooltips *tooltips;
+#endif /* HAVE_XTSOL */
int layout_manager_token;
@@ -368,8 +377,8 @@ wnck_pager_realize (GtkWidget *widget)
attributes.visual = gtk_widget_get_visual (widget);
attributes.event_mask = gtk_widget_get_events (widget) | GDK_EXPOSURE_MASK |
GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
- GDK_LEAVE_NOTIFY_MASK | GDK_POINTER_MOTION_MASK |
- GDK_POINTER_MOTION_HINT_MASK;
+ GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK |
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK;
attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL;
@@ -1463,6 +1472,53 @@ wnck_pager_draw_workspace (WnckPager
MAX (0, rect->width - 1), MAX (0, rect->height - 1));
cairo_stroke (cr);
}
+#ifdef HAVE_XTSOL
+ {
+ #define DEFAULT_COLOR "white"
+ const char *label = NULL;
+ char *colorname;
+ int error;
+ GdkColor label_color;
+ m_label_t *mlabel = NULL;
+
+ if (_wnck_check_xtsol_extension() && _wnck_use_trusted_extensions())
+ {
+ label = wnck_workspace_get_label (wnck_screen_get_workspace(pager->priv->screen, workspace));
+ if (label != NULL && (libtsol_str_to_label (label, &mlabel, MAC_LABEL, L_NO_CORRECTION, &error) == 0))
+ {
+ cairo_t *cr;
+ cr = gdk_cairo_create (gtk_widget_get_window(widget));
+
+ libtsol_label_to_str (mlabel, &colorname, M_COLOR, DEF_NAMES);
+
+ if (colorname == NULL)
+ colorname = g_strdup(DEFAULT_COLOR);
+
+ gdk_color_parse ((const char*)colorname, &label_color);
+
+ g_free (colorname);
+
+ cairo_set_source_rgba (cr,
+ (double) label_color.red / 65535,
+ (double) label_color.green / 65535,
+ (double) label_color.blue / 65535,
+ 0.5);
+ cairo_set_line_width (cr, 1.0);
+ cairo_rectangle (cr,
+ rect->x + 0.5, rect->y + 0.5,
+ rect->width - 1, rect->height - 1);
+ cairo_fill (cr);
+ cairo_destroy (cr);
+ }
+ else
+ {
+ g_warning("Could not validate sensitivity label \"%s\"", label ? label : "no label defined");
+ }
+ }
+
+ }
+#endif /*HAVE_XTSOL*/
+
}
static gboolean
@@ -2244,6 +2300,13 @@ wnck_pager_new (void)
WnckPager *pager;
pager = g_object_new (WNCK_TYPE_PAGER, NULL);
+#ifdef HAVE_XTSOL
+ if (_wnck_use_trusted_extensions () == TRUE) {
+ pager->priv->tooltips = trusted_tooltips_new ();
+ trusted_tooltips_set_pager (pager->priv->tooltips, pager);
+ g_object_ref_sink (G_OBJECT (pager->priv->tooltips));
+ }
+#endif /* HAVE_XTSOL */
return GTK_WIDGET (pager);
}
diff -urN libwnck.orig/libwnck/private.h libwnck.new/libwnck/private.h
--- libwnck.orig/libwnck/private.h 2008-08-06 23:43:13.349065000 +0100
+++ libwnck.new/libwnck/private.h 2008-08-06 23:43:40.073263000 +0100
@@ -35,6 +35,9 @@
#ifdef HAVE_STARTUP_NOTIFICATION
#include <libsn/sn.h>
#endif
+#ifdef HAVE_XTSOL
+#include <tsol/label.h>
+#endif
G_BEGIN_DECLS
@@ -102,9 +105,23 @@
void _wnck_workspace_update_name (WnckWorkspace *workspace,
const char *name);
+#ifdef HAVE_XTSOL
+void _wnck_workspace_update_label (WnckWorkspace *workspace,
+ const char *label);
+void _wnck_workspace_update_role (WnckWorkspace *workspace,
+ const char *role);
+blrange_t * _wnck_workspace_get_range (WnckWorkspace *space);
+#endif
void _wnck_screen_change_workspace_name (WnckScreen *screen,
int number,
const char *name);
+#ifdef HAVE_XTSOL
+void _wnck_screen_change_workspace_label (WnckScreen *screen,
+ int number,
+ const char *label);
+gboolean _wnck_check_xtsol_extension ();
+gboolean _wnck_use_trusted_extensions ();
+#endif
gboolean _wnck_workspace_set_geometry (WnckWorkspace *space, int w, int h);
gboolean _wnck_workspace_set_viewport (WnckWorkspace *space, int x, int y);
diff -urN libwnck.orig/libwnck/screen.c libwnck.new/libwnck/screen.c
--- libwnck.orig/libwnck/screen.c 2008-08-06 23:43:13.472108000 +0100
+++ libwnck.new/libwnck/screen.c 2008-08-06 23:43:40.084085000 +0100
@@ -35,11 +35,17 @@
#include "class-group.h"
#include "xutils.h"
#include "private.h"
+#include "wnck-tsol.h"
#include <gdk/gdk.h>
#include <gdk/gdkx.h>
#include <string.h>
#include <stdlib.h>
+#ifdef HAVE_XTSOL
+#include <tsol/label.h>
+#include <sys/tsol/label_macro.h>
+#endif
+
/**
* SECTION:screen
* @short_description: an object representing a screen.
@@ -124,6 +130,10 @@ struct _WnckScreenPrivate
guint need_update_active_window : 1;
guint need_update_workspace_layout : 1;
guint need_update_workspace_names : 1;
+#ifdef HAVE_XTSOL
+ guint need_update_workspace_labels : 1;
+ guint need_update_workspace_roles : 1;
+#endif
guint need_update_bg_pixmap : 1;
guint need_update_showing_desktop : 1;
guint need_update_wm : 1;
@@ -148,6 +158,8 @@ enum {
SHOWING_DESKTOP_CHANGED,
VIEWPORTS_CHANGED,
WM_CHANGED,
+ ROLES_CHANGED,
+ LABELS_CHANGED,
LAST_SIGNAL
};
@@ -162,6 +174,10 @@ static void update_active_workspace (W
static void update_active_window (WnckScreen *screen);
static void update_workspace_layout (WnckScreen *screen);
static void update_workspace_names (WnckScreen *screen);
+#ifdef HAVE_XTSOL
+static void update_workspace_labels (WnckScreen *screen);
+static void update_workspace_roles (WnckScreen *screen);
+#endif
static void update_showing_desktop (WnckScreen *screen);
static void queue_update (WnckScreen *screen);
@@ -193,6 +209,9 @@ static void emit_showing_desktop_changed
static void emit_viewports_changed (WnckScreen *screen);
static void emit_wm_changed (WnckScreen *screen);
+void wnck_screen_emit_roles_changed (WnckScreen *screen);
+void wmck_screen_emit_labels_changed (WnckScreen *screen);
+
static guint signals[LAST_SIGNAL] = { 0 };
static void
@@ -502,6 +521,27 @@ wnck_screen_class_init (WnckScreenClass
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
+
+ /**
+ * Solaris specific signals
+ */
+ signals[ROLES_CHANGED] =
+ g_signal_new ("roles_changed",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (WnckScreenClass, roles_changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ signals[LABELS_CHANGED] =
+ g_signal_new ("labels_changed",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (WnckScreenClass, labels_changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
}
static void
@@ -606,6 +646,10 @@ wnck_screen_construct (Display *displ
screen->priv->need_update_active_window = TRUE;
screen->priv->need_update_workspace_layout = TRUE;
screen->priv->need_update_workspace_names = TRUE;
+#ifdef HAVE_XTSOL
+ screen->priv->need_update_workspace_labels = TRUE;
+ screen->priv->need_update_workspace_roles = TRUE;
+#endif
screen->priv->need_update_bg_pixmap = TRUE;
screen->priv->need_update_showing_desktop = TRUE;
screen->priv->need_update_wm = TRUE;
@@ -1050,6 +1094,20 @@ _wnck_screen_process_property_notify (Wn
screen->priv->need_update_workspace_names = TRUE;
queue_update (screen);
}
+#ifdef HAVE_XTSOL
+ else if (xevent->xproperty.atom ==
+ _wnck_atom_get ("_NET_DESKTOP_LABELS"))
+ {
+ screen->priv->need_update_workspace_labels = TRUE;
+ queue_update (screen);
+ }
+ else if (xevent->xproperty.atom ==
+ _wnck_atom_get ("_NET_DESKTOP_ROLES"))
+ {
+ screen->priv->need_update_workspace_roles = TRUE;
+ queue_update (screen);
+ }
+#endif
else if (xevent->xproperty.atom ==
_wnck_atom_get ("_XROOTPMAP_ID"))
{
@@ -2155,6 +2213,85 @@ update_workspace_names (WnckScreen *scre
g_list_free (copy);
}
+#ifdef HAVE_XTSOL
+static void
+update_workspace_labels (WnckScreen *screen)
+{
+ char **labels;
+ int i;
+ GList *tmp;
+ GList *copy;
+
+ if (!screen->priv->need_update_workspace_labels)
+ return;
+
+ screen->priv->need_update_workspace_labels = FALSE;
+
+ labels = _wnck_get_utf8_list (screen->priv->xscreen, screen->priv->xroot,
+ _wnck_atom_get ("_NET_DESKTOP_LABELS"));
+
+ copy = g_list_copy (screen->priv->workspaces);
+
+ i = 0;
+ tmp = copy;
+ while (tmp != NULL)
+ {
+ if (labels && labels[i])
+ {
+ _wnck_workspace_update_label (tmp->data, labels[i]);
+ ++i;
+ }
+ else
+ _wnck_workspace_update_label (tmp->data, NULL);
+
+ tmp = tmp->next;
+ }
+
+ g_strfreev (labels);
+
+ g_list_free (copy);
+}
+
+static void
+update_workspace_roles (WnckScreen *screen)
+{
+ char **roles;
+ int i;
+ GList *tmp;
+ GList *copy;
+
+ if (!screen->priv->need_update_workspace_roles)
+ return;
+
+ screen->priv->need_update_workspace_roles = FALSE;
+
+ roles = _wnck_get_utf8_list (screen->priv->xscreen, screen->priv->xroot,
+ _wnck_atom_get ("_NET_DESKTOP_ROLES"));
+
+ copy = g_list_copy (screen->priv->workspaces);
+
+ i = 0;
+ tmp = copy;
+ while (tmp != NULL)
+ {
+ if (roles && roles[i])
+ {
+ _wnck_workspace_update_role (tmp->data, roles[i]);
+ ++i;
+ }
+ else
+ _wnck_workspace_update_role (tmp->data, NULL);
+
+ tmp = tmp->next;
+ }
+
+ g_strfreev (roles);
+
+ g_list_free (copy);
+}
+#endif /* HAVE_XTSOL */
+
+
static void
update_bg_pixmap (WnckScreen *screen)
{
@@ -2244,6 +2381,10 @@ do_update_now (WnckScreen *screen)
{
screen->priv->need_update_viewport_settings = TRUE;
screen->priv->need_update_workspace_names = TRUE;
+#ifdef HAVE_XTSOL
+ screen->priv->need_update_workspace_labels = TRUE;
+ screen->priv->need_update_workspace_roles = TRUE;
+#endif
}
/* First get our big-picture state in order */
@@ -2256,6 +2397,15 @@ do_update_now (WnckScreen *screen)
update_active_window (screen);
update_workspace_layout (screen);
update_workspace_names (screen);
+#ifdef HAVE_XTSOL
+ /* IMPORTANT
+ * Workspace roles MUST be set before labels
+ * as the valid label range for role workspaces
+ * is different from the user's min and max label
+ */
+ update_workspace_roles (screen);
+ update_workspace_labels (screen);
+#endif
update_showing_desktop (screen);
update_wm (screen);
@@ -2424,6 +2574,22 @@ emit_wm_changed (WnckScreen *screen)
0);
}
+void
+wnck_screen_emit_roles_changed (WnckScreen *screen)
+{
+ g_signal_emit (G_OBJECT (screen),
+ signals[ROLES_CHANGED],
+ 0);
+}
+
+void
+wnck_screen_emit_labels_changed (WnckScreen *screen)
+{
+ g_signal_emit (G_OBJECT (screen),
+ signals[LABELS_CHANGED],
+ 0);
+}
+
/**
* wnck_screen_get_window_manager_name:
* @screen: a #WnckScreen.
@@ -2755,3 +2921,86 @@ _wnck_screen_change_workspace_name (Wnck
g_free (names);
}
+
+#ifdef HAVE_XTSOL
+void
+_wnck_screen_change_workspace_label (WnckScreen *screen,
+ int number,
+ const char *label)
+{
+ int n_spaces;
+ char **labels;
+ int i;
+ int error=-2;
+ m_label_t *mlabel = NULL;
+
+ static char *lower_sl_str = NULL;
+ static char *upper_clear_str = NULL;
+ static blrange_t *workspace_range = NULL;
+
+ WnckWorkspace *tmp_space = NULL;
+
+ /* First check that we are running in a trusted windowing environment */
+ if (! _wnck_check_xtsol_extension ()) {
+ g_warning("Workspace labelling can not work with out the SUN_TSOL X extension");
+ return;
+ }
+
+ if (!_wnck_use_trusted_extensions())
+ return;
+
+ /*
+ * Label must be validated.
+ * Convert the label string to a binary MAC_LABEL type.
+ * Then check that it is in the workspace's range which
+ * depends on what role (if any) the workspace has.
+ */
+
+ if (libtsol_str_to_label (label, &mlabel, MAC_LABEL, L_NO_CORRECTION, &error) < 0) {
+ g_warning("Could not validate sensitivity label \"%s\"", label);
+ return;
+ }
+
+ tmp_space = wnck_screen_get_workspace (screen, number);
+ /* need to refresh the role cache if an app is calling change label
+ * after setting directly the _NET_DESKTOP_ROLES as this wouldn't have been
+ * updated in libwnck yet */
+ screen->priv->need_update_workspace_roles = TRUE;
+ update_workspace_roles (screen);
+ workspace_range = _wnck_workspace_get_range (tmp_space);
+
+ if (!libtsol_blinrange (mlabel, workspace_range)) {
+ g_warning("Could not change the sensitivity label of workspace %d because \"%s\" "
+ "appears to be outside of the workspace's label range", number, label);
+ libtsol_m_label_free (mlabel);
+ return;
+ }
+
+ n_spaces = wnck_screen_get_workspace_count (screen);
+
+ labels = g_new0 (char*, n_spaces + 1);
+
+ i = 0;
+ while (i < n_spaces) {
+ if (i == number)
+ labels[i] = (char*) label;
+ else {
+ WnckWorkspace *workspace;
+ workspace = wnck_screen_get_workspace (screen, i);
+ if (workspace) {
+ labels[i] = (char*) wnck_workspace_get_label (workspace);
+ if (labels[i] == NULL)
+ labels[i] = (char*) ""; /* Maybe a g_warning too ? */
+ } else
+ labels[i] = (char*) ""; /* maybe this should be a g_warning too */
+ }
+ i++;
+ }
+
+ _wnck_set_utf8_list (screen->priv->xscreen, screen->priv->xroot,
+ _wnck_atom_get ("_NET_DESKTOP_LABELS"),
+ labels);
+ libtsol_m_label_free (mlabel);
+ g_free (labels);
+}
+#endif /* HAVE_XTSOL */
diff -urN libwnck.orig/libwnck/screen.h libwnck.new/libwnck/screen.h
--- libwnck.orig/libwnck/screen.h 2011-02-18 04:01:52.526645403 -0600
+++ libwnck.new/libwnck/screen.h 2011-02-18 04:03:08.974857147 -0600
@@ -109,6 +109,12 @@ struct _WnckScreenClass
/* Window manager changed */
void (* window_manager_changed) (WnckScreen *screen);
+ /* Roles changed */
+ void (* roles_changed) (WnckScreen *screen);
+
+ /* Labels changed */
+ void (* labels_changed) (WnckScreen *screen);
+
/* Padding for future expansion */
void (* pad2) (void);
void (* pad3) (void);
@@ -270,6 +276,9 @@ void wnck_screen_calc_workspac
void wnck_screen_free_workspace_layout (WnckWorkspaceLayout *layout);
#endif /* WNCK_DISABLE_DEPRECATED */
+void wnck_screen_emit_roles_changed (WnckScreen *screen);
+void wnck_screen_emit_labels_changed (WnckScreen *screen);
+
G_END_DECLS
diff -urN libwnck.orig/libwnck/tasklist.c libwnck.new/libwnck/tasklist.c
--- libwnck.orig/libwnck/tasklist.c 2008-08-06 23:43:13.368589000 +0100
+++ libwnck.new/libwnck/tasklist.c 2008-08-06 23:43:40.101354000 +0100
@@ -36,6 +36,10 @@
#include "workspace.h"
#include "xutils.h"
#include "private.h"
+#ifdef HAVE_XTSOL
+#include "wnck-tsol.h"
+#include "trusted-tooltips.h"
+#endif /* HAVE_XTSOL */
/**
* SECTION:tasklist
@@ -198,6 +202,10 @@
GHashTable *class_group_hash;
GHashTable *win_hash;
+#ifdef HAVE_XTSOL
+ TrustedTooltips *tooltips;
+#endif /*HAVE_XTSOL*/
+
gint max_button_width;
gint max_button_height;
@@ -1970,6 +1978,10 @@
WnckTasklist *tasklist;
tasklist = g_object_new (WNCK_TYPE_TASKLIST, NULL);
+#ifdef HAVE_XTSOL
+ if (_wnck_use_trusted_extensions () == TRUE)
+ tasklist->priv->tooltips = trusted_tooltips_new ();
+#endif /*HAVE_XTSOL*/
return GTK_WIDGET (tasklist);
}
@@ -2833,6 +2845,10 @@
{
image = gtk_image_new_from_pixbuf (pixbuf);
gtk_widget_show (image);
+#ifdef HAVE_XTSOL
+ if (_wnck_check_xtsol_extension() && _wnck_use_trusted_extensions())
+ image = window_menu_create_label_indicator (win_task->window, image);
+#endif /*HAVE_XTSOL*/
gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu_item),
image);
g_object_unref (pixbuf);
@@ -3225,6 +3241,15 @@
text = wnck_task_get_text (task, TRUE, TRUE);
if (text != NULL)
{
+#ifdef HAVE_XTSOL
+ if (_wnck_use_trusted_extensions () == TRUE)
+ trusted_tooltips_set_tip (task->tasklist->priv->tooltips,
+ task->button,
+ text,
+ task->window ? wnck_window_get_label_human_readable (task->window) : "",
+ task->window ? wnck_window_get_label_color (task->window) : NULL,
+ NULL);
+#endif /* HAVE_XTSOL */
gtk_label_set_text (GTK_LABEL (task->label), text);
if (wnck_task_get_needs_attention (task))
{
@@ -3706,7 +3731,24 @@
g_free (text);
text = wnck_task_get_text (task, FALSE, FALSE);
+#ifdef HAVE_XTSOL
+ if (_wnck_use_trusted_extensions () == TRUE)
+ {
+ if (task->window)
+ {
+ trusted_tooltips_set_tip (task->tasklist->priv->tooltips,
+ task->button,
+ text,
+ wnck_window_get_label_human_readable (task->window),
+ wnck_window_get_label_color (task->window),
+ NULL);
+ }
+ else
+ trusted_tooltips_set_tip (task->tasklist->priv->tooltips, task->button, text, "Hum No Label", NULL, NULL);
+ }
+#else
gtk_widget_set_tooltip_text (task->button, text);
+#endif /*HAVE_XTSOL*/
g_free (text);
/* Set up signals */
@@ -4032,6 +4074,56 @@
#endif
}
+#ifdef HAVE_XTSOL
+static void
+draw_trusted_label (GtkWidget* widget, WnckTask *task)
+{
+ GtkStyle *style;
+ int x_offset;
+ ConstraintImage *cimage;
+ GdkRectangle area;
+ GtkAllocation image_allocation;
+ GtkAllocation allocation;
+ GtkAllocation label_allocation;
+ GtkAllocation button_allocation;
+
+ style = gtk_widget_get_style(task->button);
+ /* get the width of the icon and the padding */
+ gtk_widget_get_allocation (task->image, &image_allocation);
+ x_offset = image_allocation.width + (style->xthickness *2);
+
+ gtk_widget_get_allocation (widget, &allocation);
+ area.x = allocation.x + x_offset;
+ area.y = allocation.y + 2;
+ area.width = allocation.width - x_offset;
+ gtk_widget_get_allocation (task->label, &label_allocation);
+ gtk_widget_get_allocation (task->button, &button_allocation);
+ area.height = label_allocation.y - button_allocation.y;
+
+ cimage = get_highlight_stripe ((char*)wnck_window_get_label (task->window),
+ wnck_window_get_label_color (task->window));
+
+ if (cimage)
+ libgnome_tsol_constraint_image_render (cimage, gtk_widget_get_window(widget),
+ NULL, &area,
+ FALSE,
+ area.x,
+ area.y,
+ area.width,
+ area.height);
+}
+
+
+gboolean
+wnck_task_class_expose (GtkWidget *widget,
+ GdkEventExpose *event,
+ gpointer data)
+{
+ draw_trusted_label (widget, (WnckTask*) data);
+ return FALSE;
+}
+#endif /* HAVE_XTSOL */
+
static WnckTask *
wnck_task_new_from_window (WnckTasklist *tasklist,
WnckWindow *window)
@@ -4047,6 +4139,14 @@
wnck_task_create_widgets (task, tasklist->priv->relief);
+#ifdef HAVE_XTSOL
+ if (_wnck_check_xtsol_extension() && _wnck_use_trusted_extensions())
+ g_signal_connect_object (task->button, "expose_event",
+ G_CALLBACK (wnck_task_class_expose),
+ G_OBJECT (task),
+ G_CONNECT_AFTER);
+#endif /* HAVE_XTSOL */
+
remove_startup_sequences_for_window (tasklist, window);
return task;
--- /dev/null 2011-08-19 15:42:51.000000000 +0100
+++ libwnck-3.0.2/libwnck/trusted-tooltips.c 2011-08-19 15:41:16.282867297 +0100
@@ -0,0 +1,921 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
+ * file for a list of people on the GTK+ Team. See the ChangeLog
+ * files for a list of changes. These files are distributed with
+ * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
+ *
+ * Modified for trusted JDS by Erwann Chenede - <erwann.chenede@sun.com> 2005
+ * Copyright (C) Sun Microsystems 2005
+ */
+
+#include <config.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+#ifdef HAVE_XTSOL
+#include "trusted-tooltips.h"
+#include "workspace.h"
+#include <wnck-tsol.h>
+#include <gtk/gtk.h>
+
+
+#define DEFAULT_DELAY 500 /* Default delay in ms */
+#define STICKY_DELAY 0 /* Delay before popping up next tip
+ * if we're sticky
+ */
+#define STICKY_REVERT_DELAY 1000 /* Delay before sticky tooltips revert
+ * to normal
+ */
+
+static void trusted_tooltips_class_init (TrustedTooltipsClass *klass);
+static void trusted_tooltips_init (TrustedTooltips *tooltips);
+static void trusted_tooltips_destroy (GObject *object);
+
+static void trusted_tooltips_event_handler (GtkWidget *widget,
+ GdkEvent *event);
+static void trusted_tooltips_widget_unmap (GtkWidget *widget,
+ gpointer data);
+static void trusted_tooltips_widget_remove (GtkWidget *widget,
+ gpointer data);
+static void trusted_tooltips_set_active_widget (TrustedTooltips *tooltips,
+ GtkWidget *widget);
+static gint trusted_tooltips_timeout (gpointer data);
+
+static gint trusted_tooltips_paint_window (TrustedTooltips *tooltips,
+ cairo_t *cr);
+static void trusted_tooltips_draw_tips (TrustedTooltips *tooltips);
+static void trusted_tooltips_unset_tip_window (TrustedTooltips *tooltips);
+
+static gboolean get_keyboard_mode (GtkWidget *widget);
+
+static GObjectClass *parent_class;
+static const gchar tooltips_data_key[] = "_TrustedTooltipsData";
+static const gchar tooltips_info_key[] = "_TrustedTooltipsInfo";
+
+GType
+trusted_tooltips_get_type (void)
+{
+ static GType tooltips_type = 0;
+
+ if (!tooltips_type)
+ {
+ static const GTypeInfo tooltips_info =
+ {
+ sizeof (TrustedTooltipsClass),
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ (GClassInitFunc) trusted_tooltips_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof (TrustedTooltips),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) trusted_tooltips_init,
+ };
+
+ tooltips_type = g_type_register_static (G_TYPE_OBJECT, "TrustedTooltips",
+ &tooltips_info, 0);
+ }
+
+ return tooltips_type;
+}
+
+static void
+trusted_tooltips_class_init (TrustedTooltipsClass *class)
+{
+ GObjectClass *object_class;
+
+ object_class = (GObjectClass*) class;
+
+ parent_class = g_type_class_peek_parent (class);
+
+ /*object_class->destroy = trusted_tooltips_destroy;*/
+}
+
+static void
+trusted_tooltips_init (TrustedTooltips *tooltips)
+{
+ tooltips->tip_window = NULL;
+ tooltips->active_tips_data = NULL;
+ tooltips->tips_data_list = NULL;
+
+ tooltips->delay = DEFAULT_DELAY;
+ tooltips->enabled = TRUE;
+ tooltips->timer_tag = 0;
+ tooltips->use_sticky_delay = FALSE;
+ tooltips->last_popdown.tv_sec = -1;
+ tooltips->last_popdown.tv_usec = -1;
+ tooltips->pager = NULL;
+}
+
+TrustedTooltips *
+trusted_tooltips_new (void)
+{
+ return g_object_new (TRUSTED_TOOLTIPS_TYPE, NULL);
+}
+
+static void
+trusted_tooltips_destroy_data (TrustedTooltipsData *tooltipsdata)
+{
+ g_free (tooltipsdata->tip_text);
+ g_free (tooltipsdata->trusted_label);
+ g_free (tooltipsdata->tip_private);
+
+ g_signal_handlers_disconnect_by_func (tooltipsdata->widget,
+ (gpointer)trusted_tooltips_event_handler,
+ tooltipsdata);
+ g_signal_handlers_disconnect_by_func (tooltipsdata->widget,
+ (gpointer)trusted_tooltips_widget_unmap,
+ tooltipsdata);
+ g_signal_handlers_disconnect_by_func (tooltipsdata->widget,
+ (gpointer)trusted_tooltips_widget_remove,
+ tooltipsdata);
+
+ g_object_set_data (G_OBJECT (tooltipsdata->widget), tooltips_data_key, NULL);
+ g_object_unref (tooltipsdata->widget);
+ g_free (tooltipsdata);
+}
+
+static void
+tip_window_display_closed (GdkDisplay *display,
+ gboolean was_error,
+ TrustedTooltips *tooltips)
+{
+ trusted_tooltips_unset_tip_window (tooltips);
+}
+
+static void
+disconnect_tip_window_display_closed (TrustedTooltips *tooltips)
+{
+ g_signal_handlers_disconnect_by_func (gtk_widget_get_display (tooltips->tip_window),
+ (gpointer) tip_window_display_closed,
+ tooltips);
+}
+
+static void
+trusted_tooltips_unset_tip_window (TrustedTooltips *tooltips)
+{
+ if (tooltips->tip_window)
+ {
+ disconnect_tip_window_display_closed (tooltips);
+
+ gtk_widget_destroy (tooltips->tip_window);
+ tooltips->tip_window = NULL;
+ }
+}
+
+static void
+trusted_tooltips_destroy (GObject *object)
+{
+ TrustedTooltips *tooltips = TRUSTED_TOOLTIPS (object);
+ GList *current;
+ TrustedTooltipsData *tooltipsdata;
+
+ g_return_if_fail (tooltips != NULL);
+
+ if (tooltips->timer_tag)
+ {
+ g_source_remove (tooltips->timer_tag);
+ tooltips->timer_tag = 0;
+ }
+
+ if (tooltips->tips_data_list != NULL)
+ {
+ current = g_list_first (tooltips->tips_data_list);
+ while (current != NULL)
+ {
+ tooltipsdata = (TrustedTooltipsData*) current->data;
+ current = current->next;
+ trusted_tooltips_widget_remove (tooltipsdata->widget, tooltipsdata);
+ }
+ }
+
+ trusted_tooltips_unset_tip_window (tooltips);
+
+ /*G_OBJECT_CLASS (parent_class)->destroy (object);*/
+}
+
+static void
+trusted_tooltips_update_screen (TrustedTooltips *tooltips,
+ gboolean new_window)
+{
+ gboolean screen_changed = FALSE;
+
+ if (tooltips->active_tips_data &&
+ tooltips->active_tips_data->widget)
+ {
+ GdkScreen *screen = gtk_widget_get_screen (tooltips->active_tips_data->widget);
+
+ screen_changed = (screen != gtk_widget_get_screen (tooltips->tip_window));
+
+ if (screen_changed)
+ {
+ if (!new_window)
+ disconnect_tip_window_display_closed (tooltips);
+
+ gtk_window_set_screen (GTK_WINDOW (tooltips->tip_window), screen);
+ }
+ }
+
+ if (screen_changed || new_window)
+ g_signal_connect (gtk_widget_get_display (tooltips->tip_window), "closed",
+ G_CALLBACK (tip_window_display_closed), tooltips);
+
+}
+
+void
+trusted_tooltips_force_window (TrustedTooltips *tooltips)
+{
+ g_return_if_fail (IS_TRUSTED_TOOLTIPS (tooltips));
+
+ if (!tooltips->tip_window)
+ {
+ GtkWidget * vbox;
+
+ tooltips->tip_window = gtk_window_new (GTK_WINDOW_POPUP);
+ trusted_tooltips_update_screen (tooltips, TRUE);
+ gtk_widget_set_app_paintable (tooltips->tip_window, TRUE);
+ gtk_window_set_resizable (GTK_WINDOW (tooltips->tip_window), FALSE);
+ gtk_widget_set_name (tooltips->tip_window, "gtk-tooltips");
+ gtk_container_set_border_width (GTK_CONTAINER (tooltips->tip_window), 2);
+
+ g_signal_connect_swapped (tooltips->tip_window,
+ "draw",
+ G_CALLBACK (trusted_tooltips_paint_window),
+ tooltips);
+
+ tooltips->tip_label = gtk_label_new (NULL);
+ gtk_label_set_line_wrap (GTK_LABEL (tooltips->tip_label), FALSE);
+ gtk_misc_set_alignment (GTK_MISC (tooltips->tip_label), 0.5, 0.5);
+ gtk_widget_show (tooltips->tip_label);
+
+ tooltips->tip_trusted_label = gtk_label_new (NULL);
+ gtk_label_set_line_wrap (GTK_LABEL (tooltips->tip_trusted_label), FALSE);
+ gtk_misc_set_alignment (GTK_MISC (tooltips->tip_trusted_label), 0.5, 0.5);
+ gtk_widget_show (tooltips->tip_trusted_label);
+
+ vbox = gtk_vbox_new (FALSE, 1);
+ tooltips->event = gtk_event_box_new ();
+
+ gtk_container_add (GTK_CONTAINER (tooltips->event), tooltips->tip_trusted_label);
+
+ gtk_container_add (GTK_CONTAINER (vbox), tooltips->event);
+
+ gtk_container_add (GTK_CONTAINER (vbox), tooltips->tip_label);
+ gtk_container_add (GTK_CONTAINER (tooltips->tip_window), vbox);
+
+ gtk_widget_show (vbox);
+ gtk_widget_show (tooltips->event);
+
+ g_signal_connect (tooltips->tip_window,
+ "destroy",
+ G_CALLBACK (gtk_widget_destroyed),
+ &tooltips->tip_window);
+ }
+}
+
+void
+trusted_tooltips_enable (TrustedTooltips *tooltips)
+{
+ g_return_if_fail (tooltips != NULL);
+
+ tooltips->enabled = TRUE;
+}
+
+void
+trusted_tooltips_disable (TrustedTooltips *tooltips)
+{
+ g_return_if_fail (tooltips != NULL);
+
+ trusted_tooltips_set_active_widget (tooltips, NULL);
+
+ tooltips->enabled = FALSE;
+}
+
+void
+trusted_tooltips_set_delay (TrustedTooltips *tooltips,
+ guint delay)
+{
+ g_return_if_fail (tooltips != NULL);
+
+ tooltips->delay = delay;
+}
+
+TrustedTooltipsData*
+trusted_tooltips_data_get (GtkWidget *widget)
+{
+ g_return_val_if_fail (widget != NULL, NULL);
+
+ return g_object_get_data (G_OBJECT (widget), tooltips_data_key);
+}
+
+void
+trusted_tooltips_set_tip (TrustedTooltips *tooltips,
+ GtkWidget *widget,
+ const gchar *tip_text,
+ const gchar *trusted_label,
+ GdkColor *trusted_color,
+ const gchar *tip_private)
+{
+ TrustedTooltipsData *tooltipsdata;
+
+ g_return_if_fail (IS_TRUSTED_TOOLTIPS (tooltips));
+ g_return_if_fail (widget != NULL);
+
+ tooltipsdata = trusted_tooltips_data_get (widget);
+
+ if (!tip_text)
+ {
+ if (tooltipsdata)
+ trusted_tooltips_widget_remove (tooltipsdata->widget, tooltipsdata);
+ return;
+ }
+
+ if (tooltips->active_tips_data
+ && tooltips->active_tips_data->widget == widget
+ && gtk_widget_is_drawable (tooltips->active_tips_data->widget))
+ {
+ g_free (tooltipsdata->tip_text);
+ g_free (tooltipsdata->tip_private);
+
+ tooltipsdata->tip_text = g_strdup (tip_text);
+ tooltipsdata->tip_private = g_strdup (tip_private);
+
+ trusted_tooltips_draw_tips (tooltips);
+ }
+ else
+ {
+ g_object_ref (widget);
+
+ if (tooltipsdata)
+ trusted_tooltips_widget_remove (tooltipsdata->widget, tooltipsdata);
+
+ tooltipsdata = g_new0 (TrustedTooltipsData, 1);
+
+ tooltipsdata->tooltips = tooltips;
+ tooltipsdata->widget = widget;
+
+ tooltipsdata->tip_text = g_strdup (tip_text);
+ tooltipsdata->trusted_label = g_strdup (trusted_label);
+ tooltipsdata->tip_private = g_strdup (tip_private);
+ if (trusted_color)
+ tooltipsdata->trusted_color = trusted_color;
+
+ tooltips->tips_data_list = g_list_append (tooltips->tips_data_list,
+ tooltipsdata);
+ g_signal_connect_after (widget, "event-after",
+ G_CALLBACK (trusted_tooltips_event_handler),
+ tooltipsdata);
+
+ g_object_set_data (G_OBJECT (widget), tooltips_data_key,
+ tooltipsdata);
+
+ g_signal_connect (widget, "unmap",
+ G_CALLBACK (trusted_tooltips_widget_unmap),
+ tooltipsdata);
+
+ g_signal_connect (widget, "unrealize",
+ G_CALLBACK (trusted_tooltips_widget_unmap),
+ tooltipsdata);
+
+ g_signal_connect (widget, "destroy",
+ G_CALLBACK (trusted_tooltips_widget_remove),
+ tooltipsdata);
+ }
+}
+
+static gint
+trusted_tooltips_paint_window (TrustedTooltips *tooltips,
+ cairo_t *cr)
+{
+ GtkRequisition req;
+ GtkStyleContext *context;
+
+ context = gtk_widget_get_style_context (tooltips->tip_window);
+
+ gtk_widget_size_request (tooltips->tip_window, &req);
+ gtk_render_background (context, cr, 0, 0, req.width, req.height);
+ gtk_render_frame (context, cr, 0, 0, req.width, req.height);
+
+ return FALSE;
+}
+
+static void
+trusted_tooltips_draw_tips (TrustedTooltips *tooltips)
+{
+ GtkRequisition requisition;
+ GtkAllocation allocation;
+ GtkWidget *widget;
+ GtkStyle *style;
+ gint x, y, w, h;
+ TrustedTooltipsData *data;
+ gboolean keyboard_mode;
+ GdkScreen *screen;
+ GdkScreen *pointer_screen;
+ gint monitor_num, px, py;
+ GdkRectangle monitor;
+
+ if (!tooltips->tip_window)
+ trusted_tooltips_force_window (tooltips);
+ else if (gtk_widget_get_visible (tooltips->tip_window))
+ g_get_current_time (&tooltips->last_popdown);
+
+ gtk_widget_ensure_style (tooltips->tip_window);
+ style = gtk_widget_get_style(tooltips->tip_window);
+
+ widget = tooltips->active_tips_data->widget;
+ g_object_set_data (G_OBJECT (tooltips->tip_window), tooltips_info_key,
+ tooltips);
+
+ keyboard_mode = get_keyboard_mode (widget);
+
+ trusted_tooltips_update_screen (tooltips, FALSE);
+
+ screen = gtk_widget_get_screen (widget);
+
+ data = tooltips->active_tips_data;
+
+ if (tooltips->pager) /* pager special case */
+ {
+ char *colorname;
+ int error;
+ GdkColor label_color;
+ m_label_t *mlabel = NULL;
+ WnckWorkspace *tip_ws = g_object_get_data (G_OBJECT (tooltips->pager),
+ "tip_ws");
+
+ const char *label = wnck_workspace_get_label (tip_ws);
+
+ gtk_label_set_text (GTK_LABEL (tooltips->tip_label),
+ wnck_workspace_get_name (tip_ws));
+
+ if (_wnck_use_trusted_extensions ())
+ {
+ if (label != NULL &&
+ (error = libtsol_str_to_label (label, &mlabel, MAC_LABEL,
+ L_NO_CORRECTION, &error)) == 0)
+ {
+ GdkPixbuf *pb;
+ guint32 rgba;
+ char *readable_label;
+
+ error = libtsol_label_to_str (mlabel, &colorname, M_COLOR, DEF_NAMES);
+
+#define DEFAULT_COLOR "white"
+ if (colorname == NULL)
+ colorname = g_strdup(DEFAULT_COLOR);
+
+ gdk_color_parse ((const char*)colorname, &label_color);
+
+ g_free (colorname);
+
+
+ readable_label = wnck_workspace_get_human_readable_label (tip_ws);
+
+ gtk_label_set_text (GTK_LABEL (tooltips->tip_trusted_label), readable_label);
+
+ g_free (readable_label);
+
+ gtk_widget_modify_bg (tooltips->event, GTK_STATE_NORMAL, &label_color);
+
+ gtk_widget_show (tooltips->event);
+ }
+ else /* failed call to libtsol_label_to_str */
+ gtk_widget_hide (tooltips->event);
+ }
+ else /* not using trusted_extensions */
+ gtk_widget_hide (tooltips->event);
+ }
+ else
+ {
+ gtk_label_set_text (GTK_LABEL (tooltips->tip_label), data->tip_text);
+ gtk_label_set_text (GTK_LABEL (tooltips->tip_trusted_label), data->trusted_label);
+ gtk_widget_modify_bg (tooltips->event, GTK_STATE_NORMAL, data->trusted_color);
+ if (data->trusted_color == NULL)
+ gtk_widget_hide (tooltips->event);
+ else
+ gtk_widget_show (tooltips->event);
+ }
+
+
+ gtk_widget_size_request (tooltips->tip_window, &requisition);
+ w = requisition.width;
+ h = requisition.height;
+
+ gdk_window_get_origin (gtk_widget_get_window(widget), &x, &y);
+ gtk_widget_get_allocation(widget, &allocation);
+ if (!gtk_widget_get_has_window (widget))
+ {
+ x += allocation.x;
+ y += allocation.y;
+ }
+
+ x += allocation.width / 2;
+
+ if (!keyboard_mode)
+ gdk_window_get_pointer (gdk_screen_get_root_window (screen),
+ &x, NULL, NULL);
+
+ x -= (w / 2 + 4);
+
+ gdk_display_get_pointer (gdk_screen_get_display (screen),
+ &pointer_screen, &px, &py, NULL);
+ if (pointer_screen != screen)
+ {
+ px = x;
+ py = y;
+ }
+ monitor_num = gdk_screen_get_monitor_at_point (screen, px, py);
+ gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
+
+ if ((x + w) > monitor.x + monitor.width)
+ x -= (x + w) - (monitor.x + monitor.width);
+ else if (x < monitor.x)
+ x = monitor.x;
+
+ if ((y + h + allocation.height + 4) > monitor.y + monitor.height)
+ y = y - h - 4;
+ else
+ y = y + allocation.height + 4;
+
+ gtk_window_move (GTK_WINDOW (tooltips->tip_window), x, y);
+ gtk_widget_show (tooltips->tip_window);
+}
+
+static gint
+trusted_tooltips_timeout (gpointer data)
+{
+ TrustedTooltips *tooltips = (TrustedTooltips *) data;
+
+ GDK_THREADS_ENTER ();
+
+ if (tooltips->active_tips_data != NULL &&
+ gtk_widget_is_drawable (tooltips->active_tips_data->widget))
+ trusted_tooltips_draw_tips (tooltips);
+
+ GDK_THREADS_LEAVE ();
+
+ return FALSE;
+}
+
+static void
+trusted_tooltips_set_active_widget (TrustedTooltips *tooltips,
+ GtkWidget *widget)
+{
+ if (tooltips->tip_window)
+ {
+ if (gtk_widget_get_visible (tooltips->tip_window))
+ g_get_current_time (&tooltips->last_popdown);
+ gtk_widget_hide (tooltips->tip_window);
+ }
+ if (tooltips->timer_tag)
+ {
+ g_source_remove (tooltips->timer_tag);
+ tooltips->timer_tag = 0;
+ }
+
+ tooltips->active_tips_data = NULL;
+
+ if (widget)
+ {
+ GList *list;
+
+ for (list = tooltips->tips_data_list; list; list = list->next)
+ {
+ TrustedTooltipsData *tooltipsdata;
+
+ tooltipsdata = list->data;
+
+ if (tooltipsdata->widget == widget &&
+ gtk_widget_is_drawable (widget))
+ {
+ tooltips->active_tips_data = tooltipsdata;
+ break;
+ }
+ }
+ }
+ else
+ {
+ tooltips->use_sticky_delay = FALSE;
+ }
+}
+
+static void
+trusted_tooltips_show_tip (GtkWidget *widget)
+{
+ TrustedTooltipsData *tooltipsdata;
+
+ tooltipsdata = trusted_tooltips_data_get (widget);
+
+ if (tooltipsdata &&
+ (!tooltipsdata->tooltips->active_tips_data ||
+ tooltipsdata->tooltips->active_tips_data->widget != widget))
+ {
+ trusted_tooltips_set_active_widget (tooltipsdata->tooltips, widget);
+ trusted_tooltips_draw_tips (tooltipsdata->tooltips);
+ }
+}
+
+static void
+trusted_tooltips_hide_tip (GtkWidget *widget)
+{
+ TrustedTooltipsData *tooltipsdata;
+
+ tooltipsdata = trusted_tooltips_data_get (widget);
+
+ if (tooltipsdata &&
+ (tooltipsdata->tooltips->active_tips_data &&
+ tooltipsdata->tooltips->active_tips_data->widget == widget))
+ trusted_tooltips_set_active_widget (tooltipsdata->tooltips, NULL);
+}
+
+static gboolean
+trusted_tooltips_recently_shown (TrustedTooltips *tooltips)
+{
+ GTimeVal now;
+ glong msec;
+
+ g_get_current_time (&now);
+ msec = (now.tv_sec - tooltips->last_popdown.tv_sec) * 1000 +
+ (now.tv_usec - tooltips->last_popdown.tv_usec) / 1000;
+ return (msec < STICKY_REVERT_DELAY);
+}
+
+static gboolean
+get_keyboard_mode (GtkWidget *widget)
+{
+ GtkWidget *toplevel = gtk_widget_get_toplevel (widget);
+ if (GTK_IS_WINDOW (toplevel))
+ return GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (toplevel), "gtk-tooltips-keyboard-mode"));
+ else
+ return FALSE;
+}
+
+static void
+start_keyboard_mode (GtkWidget *widget)
+{
+ GtkWidget *toplevel = gtk_widget_get_toplevel (widget);
+ if (GTK_IS_WINDOW (toplevel))
+ {
+ GtkWidget *focus = gtk_window_get_focus(GTK_WINDOW (toplevel));
+
+ g_object_set_data (G_OBJECT (toplevel), "gtk-tooltips-keyboard-mode", GUINT_TO_POINTER (TRUE));
+
+ if (focus)
+ trusted_tooltips_show_tip (focus);
+ }
+}
+
+static void
+stop_keyboard_mode (GtkWidget *widget)
+{
+ GtkWidget *toplevel = gtk_widget_get_toplevel (widget);
+ if (GTK_IS_WINDOW (toplevel))
+ {
+ GtkWidget *focus = gtk_window_get_focus(GTK_WINDOW (toplevel));
+ if (focus)
+ trusted_tooltips_hide_tip (focus);
+
+ g_object_set_data (G_OBJECT (toplevel), "gtk-tooltips-keyboard-mode", GUINT_TO_POINTER (FALSE));
+ }
+}
+
+static void
+trusted_tooltips_start_delay (TrustedTooltips *tooltips,
+ GtkWidget *widget)
+{
+ TrustedTooltipsData *old_tips_data;
+
+ old_tips_data = tooltips->active_tips_data;
+ if (tooltips->enabled &&
+ (!old_tips_data || old_tips_data->widget != widget))
+ {
+ guint delay;
+
+ trusted_tooltips_set_active_widget (tooltips, widget);
+
+ if (tooltips->use_sticky_delay &&
+ trusted_tooltips_recently_shown (tooltips))
+ delay = STICKY_DELAY;
+ else
+ delay = tooltips->delay;
+ tooltips->timer_tag = g_timeout_add (delay,
+ trusted_tooltips_timeout,
+ (gpointer) tooltips);
+ }
+}
+
+static void
+trusted_tooltips_event_handler (GtkWidget *widget,
+ GdkEvent *event)
+{
+ TrustedTooltips *tooltips;
+ TrustedTooltipsData *old_tips_data;
+ GtkWidget *event_widget;
+ gboolean keyboard_mode = get_keyboard_mode (widget);
+
+
+ if ((event->type == GDK_LEAVE_NOTIFY || event->type == GDK_ENTER_NOTIFY) &&
+ event->crossing.detail == GDK_NOTIFY_INFERIOR)
+ return;
+
+ old_tips_data = trusted_tooltips_data_get (widget);
+ tooltips = old_tips_data->tooltips;
+
+ if (keyboard_mode)
+ {
+ switch (event->type)
+ {
+ case GDK_FOCUS_CHANGE:
+ if (event->focus_change.in)
+ trusted_tooltips_show_tip (widget);
+ else
+ trusted_tooltips_hide_tip (widget);
+ break;
+ default:
+ break;
+ }
+ }
+ else
+ {
+ if (event->type != GDK_KEY_PRESS && event->type != GDK_KEY_RELEASE)
+ {
+ event_widget = gtk_get_event_widget (event);
+ if (event_widget != widget)
+ return;
+ }
+
+ if (tooltips->pager != NULL) /* handler pager tooltips special case */
+ {
+ static WnckWorkspace *current = NULL;
+ if (event->type == GDK_MOTION_NOTIFY || event->type == GDK_ENTER_NOTIFY)
+ {
+ WnckWorkspace *tip_ws = g_object_get_data (G_OBJECT (tooltips->pager),
+ "tip_ws");
+
+ if (current != tip_ws)
+ {
+ /* do something only if the workspace changed */
+ current = tip_ws;
+ trusted_tooltips_set_active_widget (tooltips, NULL);
+ trusted_tooltips_start_delay (tooltips, widget);
+ }
+ }
+ if (event->type == GDK_LEAVE_NOTIFY)
+ {
+ trusted_tooltips_set_active_widget (tooltips, NULL);
+ current = NULL;
+ }
+ }
+ else
+ {
+ switch (event->type)
+ {
+ case GDK_EXPOSE:
+ /* do nothing */
+ break;
+ case GDK_ENTER_NOTIFY:
+ if (!(GTK_IS_MENU_ITEM (widget) && gtk_menu_item_get_submenu(GTK_MENU_ITEM (widget))))
+ trusted_tooltips_start_delay (tooltips, widget);
+ break;
+
+ case GDK_LEAVE_NOTIFY:
+ {
+ gboolean use_sticky_delay;
+
+ use_sticky_delay = tooltips->tip_window &&
+ gtk_widget_get_visible (tooltips->tip_window);
+ trusted_tooltips_set_active_widget (tooltips, NULL);
+ tooltips->use_sticky_delay = use_sticky_delay;
+ }
+ break;
+
+ case GDK_MOTION_NOTIFY:
+ /* Handle menu items specially ... pend popup for each motion
+ * on other widgets, we ignore motion.
+ */
+ if (GTK_IS_MENU_ITEM (widget) && !gtk_menu_item_get_submenu(GTK_MENU_ITEM (widget)))
+ {
+ /* Completely evil hack to make sure we get the LEAVE_NOTIFY
+ */
+ /* GTK_PRIVATE_SET_FLAG (widget, GTK_LEAVE_PENDING); */
+ trusted_tooltips_set_active_widget (tooltips, NULL);
+ trusted_tooltips_start_delay (tooltips, widget);
+ break;
+ }
+ break; /* ignore */
+ case GDK_BUTTON_PRESS:
+ case GDK_BUTTON_RELEASE:
+ case GDK_KEY_PRESS:
+ case GDK_KEY_RELEASE:
+ case GDK_PROXIMITY_IN:
+ case GDK_SCROLL:
+ trusted_tooltips_set_active_widget (tooltips, NULL);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+}
+
+static void
+trusted_tooltips_widget_unmap (GtkWidget *widget,
+ gpointer data)
+{
+ TrustedTooltipsData *tooltipsdata = (TrustedTooltipsData *)data;
+ TrustedTooltips *tooltips = tooltipsdata->tooltips;
+
+ if (tooltips->active_tips_data &&
+ (tooltips->active_tips_data->widget == widget))
+ trusted_tooltips_set_active_widget (tooltips, NULL);
+}
+
+static void
+trusted_tooltips_widget_remove (GtkWidget *widget,
+ gpointer data)
+{
+ TrustedTooltipsData *tooltipsdata = (TrustedTooltipsData*) data;
+ TrustedTooltips *tooltips = tooltipsdata->tooltips;
+
+ trusted_tooltips_widget_unmap (widget, data);
+ tooltips->tips_data_list = g_list_remove (tooltips->tips_data_list,
+ tooltipsdata);
+ trusted_tooltips_destroy_data (tooltipsdata);
+}
+
+void
+_trusted_tooltips_toggle_keyboard_mode (GtkWidget *widget)
+{
+ if (get_keyboard_mode (widget))
+ stop_keyboard_mode (widget);
+ else
+ start_keyboard_mode (widget);
+}
+
+/**
+ * trusted_tooltips_get_info_from_tip_window:
+ * @tip_window: a #GtkWindow
+ * @tooltips: the return location for the tooltips which are displayed
+ * in @tip_window, or %NULL
+ * @current_widget: the return location for the widget whose tooltips
+ * are displayed, or %NULL
+ *
+ * Determines the tooltips and the widget they belong to from the window in
+ * which they are displayed.
+ *
+ * This function is mostly intended for use by accessibility technologies;
+ * applications should have little use for it.
+ *
+ * Return value: %TRUE if @tip_window is displaying tooltips, otherwise %FALSE.
+ *
+ * Since: 2.4
+ **/
+gboolean
+trusted_tooltips_get_info_from_tip_window (GtkWindow *tip_window,
+ TrustedTooltips **tooltips,
+ GtkWidget **current_widget)
+{
+ TrustedTooltips *current_tooltips;
+ gboolean has_tips;
+
+ g_return_val_if_fail (GTK_IS_WINDOW (tip_window), FALSE);
+
+ current_tooltips = g_object_get_data (G_OBJECT (tip_window), tooltips_info_key);
+
+ has_tips = current_tooltips != NULL;
+
+ if (tooltips)
+ *tooltips = current_tooltips;
+ if (current_widget)
+ *current_widget = has_tips ? current_tooltips->active_tips_data->widget : NULL;
+
+ return has_tips;
+}
+void
+trusted_tooltips_set_pager (TrustedTooltips *tooltips,
+ WnckPager *pager)
+{
+ tooltips->pager = pager;
+}
+#endif /* HAVE_XTSOL */
+#define __TRUSTED_TOOLTIPS_C__
diff -urN libwnck.orig/libwnck/trusted-tooltips.h libwnck.new/libwnck/trusted-tooltips.h
--- libwnck.orig/libwnck/trusted-tooltips.h 1970-01-01 01:00:00.000000000 +0100
+++ libwnck.new/libwnck/trusted-tooltips.h 2008-08-06 23:43:40.108722000 +0100
@@ -0,0 +1,119 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
+ * file for a list of people on the GTK+ Team. See the ChangeLog
+ * files for a list of changes. These files are distributed with
+ * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+#ifndef __TRUSTED_TOOLTIPS_H__
+#define __TRUSTED_TOOLTIPS_H__
+
+#include <gtk/gtk.h>
+#include "pager.h"
+
+G_BEGIN_DECLS
+
+#define TRUSTED_TOOLTIPS_TYPE (trusted_tooltips_get_type ())
+#define TRUSTED_TOOLTIPS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TRUSTED_TOOLTIPS_TYPE, TrustedTooltips))
+#define TRUSTED_TOOLTIPS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TRUSTED_TOOLTIPS_TYPE, TrustedTooltipsClass))
+#define IS_TRUSTED_TOOLTIPS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TRUSTED_TOOLTIPS_TYPE))
+#define IS_TRUSTED_TOOLTIPS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TRUSTED_TOOLTIPS_TYPE))
+#define TRUSTED_TOOLTIPS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TRUSTED_TOOLTIPS_TYPE, TrustedTooltipsClass))
+
+
+typedef struct _TrustedTooltips TrustedTooltips;
+typedef struct _TrustedTooltipsClass TrustedTooltipsClass;
+typedef struct _TrustedTooltipsData TrustedTooltipsData;
+
+struct _TrustedTooltipsData
+{
+ TrustedTooltips *tooltips;
+ GtkWidget *widget;
+ gchar *tip_text;
+ gchar *trusted_label;
+ GdkColor *trusted_color;
+ gchar *tip_private;
+};
+
+struct _TrustedTooltips
+{
+ GObject parent_instance;
+
+ GtkWidget *tip_window;
+ GtkWidget *tip_label;
+ GtkWidget *tip_trusted_label;
+ GtkWidget *event;
+ TrustedTooltipsData *active_tips_data;
+ GList *tips_data_list;
+
+ guint delay : 30;
+ guint enabled : 1;
+ guint have_grab : 1;
+ guint use_sticky_delay : 1;
+ gint timer_tag;
+ GTimeVal last_popdown;
+ WnckPager *pager;
+};
+
+struct _TrustedTooltipsClass
+{
+ GObjectClass parent_class;
+
+ /* Padding for future expansion */
+ void (*_gtk_reserved1) (void);
+ void (*_gtk_reserved2) (void);
+ void (*_gtk_reserved3) (void);
+ void (*_gtk_reserved4) (void);
+};
+
+GType trusted_tooltips_get_type (void) G_GNUC_CONST;
+TrustedTooltips* trusted_tooltips_new (void);
+
+void trusted_tooltips_enable (TrustedTooltips *tooltips);
+void trusted_tooltips_disable (TrustedTooltips *tooltips);
+#ifndef GTK_DISABLE_DEPRECATED
+void trusted_tooltips_set_delay (TrustedTooltips *tooltips,
+ guint delay);
+#endif /* GTK_DISABLE_DEPRECATED */
+void trusted_tooltips_set_tip (TrustedTooltips *tooltips,
+ GtkWidget *widget,
+ const gchar *tip_text,
+ const gchar *trusted_label,
+ GdkColor *trusted_color,
+ const gchar *tip_private);
+TrustedTooltipsData* trusted_tooltips_data_get (GtkWidget *widget);
+void trusted_tooltips_force_window (TrustedTooltips *tooltips);
+
+
+void _trusted_tooltips_toggle_keyboard_mode (GtkWidget *widget);
+
+gboolean trusted_tooltips_get_info_from_tip_window (GtkWindow *tip_window,
+ TrustedTooltips **tooltips,
+ GtkWidget **current_widget);
+
+void trusted_tooltips_set_pager (TrustedTooltips *tooltips,
+ WnckPager *pager);
+
+
+G_END_DECLS
+
+#endif /* __TRUSTED_TOOLTIPS_H__ */
diff -urN libwnck.orig/libwnck/tsol-pics.h libwnck.new/libwnck/tsol-pics.h
--- libwnck.orig/libwnck/tsol-pics.h 1970-01-01 01:00:00.000000000 +0100
+++ libwnck.new/libwnck/tsol-pics.h 2008-08-06 23:43:40.110678000 +0100
@@ -0,0 +1,43 @@
+/* GdkPixbuf RGBA C-Source image dump */
+
+#ifdef __SUNPRO_C
+#pragma align 4 (highlight_stripe_pb)
+#endif
+#ifdef __GNUC__
+static const guint8 highlight_stripe_pb[] __attribute__ ((__aligned__ (4))) =
+#else
+static const guint8 highlight_stripe_pb[] =
+#endif
+{ ""
+ /* Pixbuf magic (0x47646b50) */
+ "GdkP"
+ /* length: header (24) + pixel_data (704) */
+ "\0\0\2\330"
+ /* pixdata_type (0x1010002) */
+ "\1\1\0\2"
+ /* rowstride (176) */
+ "\0\0\0\260"
+ /* width (44) */
+ "\0\0\0,"
+ /* height (4) */
+ "\0\0\0\4"
+ /* pixel_data: */
+ "\0\0\0\0^^^\377^^^\377^^^\377^^^\377^^^\377^^^\377^^^\377^^^\377^^^\377"
+ "^^^\377^^^\377^^^\377^^^\377^^^\377^^^\377^^^\377^^^\377^^^\377^^^\377"
+ "^^^\377^^^\377^^^\377^^^\377^^^\377^^^\377^^^\377^^^\377^^^\377^^^\377"
+ "^^^\377^^^\377^^^\377^^^\377^^^\365^^^\336^^^\303^^^\246^^^\207^^^[^"
+ "^^3^^^\26^^^\5^^^\2^^^\360^^^\377^^^\377^^^\377^^^\377^^^\377^^^\377"
+ "^^^\377^^^\377^^^\377^^^\377^^^\377^^^\377^^^\377^^^\377^^^\377^^^\377"
+ "^^^\377^^^\377^^^\377^^^\377^^^\377^^^\377^^^\377^^^\377^^^\377^^^\377"
+ "^^^\377^^^\377^^^\377^^^\377^^^\377^^^\377^^^\377^^^\365^^^\336^^^\303"
+ "^^^\246^^^\207^^^[^^^3^^^\26^^^\5^^^\2^^^\360^^^\377^^^\377^^^\377^^"
+ "^\377^^^\377^^^\377^^^\377^^^\377^^^\377^^^\377^^^\377^^^\377^^^\377"
+ "^^^\377^^^\377^^^\377^^^\377^^^\377^^^\377^^^\377^^^\377^^^\377^^^\377"
+ "^^^\377^^^\377^^^\377^^^\377^^^\377^^^\377^^^\377^^^\377^^^\377^^^\377"
+ "^^^\365^^^\336^^^\303^^^\246^^^\207^^^[^^^3^^^\26^^^\5^^^\2\0\0\0\0^"
+ "^^\377^^^\377^^^\377^^^\377^^^\377^^^\377^^^\377^^^\377^^^\377^^^\377"
+ "^^^\377^^^\377^^^\377^^^\377^^^\377^^^\377^^^\377^^^\377^^^\377^^^\377"
+ "^^^\377^^^\377^^^\377^^^\377^^^\377^^^\377^^^\377^^^\377^^^\377^^^\377"
+ "^^^\377^^^\377^^^\377^^^\365^^^\336^^^\303^^^\246^^^\207^^^[^^^3^^^\26"
+ "^^^\5^^^\2"};
+
diff -urN libwnck.orig/libwnck/window.c libwnck.new/libwnck/window.c
--- libwnck.orig/libwnck/window.c 2008-08-06 23:43:13.689319000 +0100
+++ libwnck.new/libwnck/window.c 2008-08-06 23:43:40.130350000 +0100
@@ -47,6 +47,13 @@
* referenced or unreferenced.
*/
+#ifdef HAVE_XTSOL
+#include <strings.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <wnck-tsol.h>
+#endif
+
#define FALLBACK_NAME _("Untitled window")
#define ALL_WORKSPACES (0xFFFFFFFF)
@@ -83,6 +90,12 @@ struct _WnckWindowPrivate
char *icon_name;
char *session_id;
char *session_id_utf8;
+#ifdef HAVE_XTSOL
+ char *label;
+ GdkColor *label_color;
+ char *label_color_str;
+ char *role;
+#endif
int pid;
int workspace;
gint sort_order;
@@ -100,6 +113,9 @@ struct _WnckWindowPrivate
int y;
int width;
int height;
+#ifdef HAVE_XTSOL
+ int is_trusted;
+#endif
int left_frame;
int right_frame;
@@ -161,6 +177,9 @@ struct _WnckWindowPrivate
guint need_emit_name_changed : 1;
guint need_emit_icon_changed : 1;
+#ifdef HAVE_XTSOL
+ guint need_update_label : 1;
+#endif
};
G_DEFINE_TYPE (WnckWindow, wnck_window, G_TYPE_OBJECT);
@@ -223,6 +242,9 @@ wnck_window_init (WnckWindow *window)
window->priv->group_leader = None;
window->priv->transient_for = None;
window->priv->icon_geometry.width = -1; /* invalid cached value */
+#ifdef HAVE_XTSOL
+ window->priv->is_trusted = -1;
+#endif
window->priv->name = NULL;
window->priv->icon_name = NULL;
window->priv->session_id = NULL;
@@ -446,6 +468,12 @@ wnck_window_finalize (GObject *object)
_wnck_icon_cache_free (window->priv->icon_cache);
window->priv->icon_cache = NULL;
+#ifdef HAVE_XTSOL
+ g_free (window->priv->label);
+ g_free (window->priv->label_color);
+ g_free (window->priv->role);
+#endif
+
g_free (window->priv->startup_id);
window->priv->startup_id = NULL;
g_free (window->priv->res_class);
@@ -563,11 +591,40 @@ _wnck_window_create (Window xwindow
window->priv->need_update_frame_extents = TRUE;
window->priv->need_emit_name_changed = FALSE;
window->priv->need_emit_icon_changed = FALSE;
+#ifdef HAVE_XTSOL
+ window->priv->need_update_label = TRUE;
+#endif
force_update_now (window);
return window;
}
+#ifdef HAVE_XTSOL
+/**
+ * wnck_window_is_trusted:
+ * @window: a #WnckWindow
+ *
+ * Trusted here means that the application running in the window is
+ * in the trusted path.
+ *
+ * Return value: %TRUE if the window is trusted.
+ **/
+gboolean
+wnck_window_is_trusted (WnckWindow *window)
+{
+ g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE);
+ if (!_wnck_check_xtsol_extension()) {
+ g_warning ("wnck_window_is_trusted() was called but the X server does not support the SUN_TSOL extension");
+ return 0;
+ }
+ if (!_wnck_use_trusted_extensions()) {
+ g_warning ("wnck_window_is_trusted(): Can not initialise the trusted extensions libraries. Check your installation");
+ return 0;
+ }
+ return window->priv->is_trusted;
+}
+#endif
+
void
_wnck_window_destroy (WnckWindow *window)
{
@@ -721,6 +778,92 @@ _wnck_window_get_name_for_display (WnckW
return g_strdup (name);
}
+#ifdef HAVE_XTSOL
+/**
+ * wnck_window_get_label:
+ * @window: a #WnckWindow
+ *
+ * Gets the sensitivity label of the window in it's long string
+ * representation.
+ *
+ * Return value: sensitivity label of the window.
+ * If the window has no sensitivity label set, %NULL is returned.
+ **/
+const char*
+wnck_window_get_label (WnckWindow *window)
+{
+ g_return_val_if_fail (WNCK_IS_WINDOW (window), NULL);
+ if (_wnck_check_xtsol_extension() && _wnck_use_trusted_extensions())
+ return window->priv->label;
+ return NULL;
+}
+/**
+ * wnck_window_get_label_human_readable:
+ * @window: a #WnckWindow
+ *
+ * Gets the sensitivity label of the window and returns it in a
+ * form suitable for presentation in a user visible interface.
+ *
+ * Return value: sensitivity label of the window appropriate for
+ * human presentation.
+ * If the window has no sensitivity label set, %NULL is returned.
+ **/
+char*
+wnck_window_get_label_human_readable (WnckWindow *window)
+{
+ char *human_readable_label;
+ g_return_val_if_fail (WNCK_IS_WINDOW (window), NULL);
+ if (_wnck_check_xtsol_extension() && _wnck_use_trusted_extensions())
+ {
+ int error;
+ m_label_t *mlabel = NULL;
+
+ if (wnck_window_is_trusted (window))
+ /* SUN_BRANDING TJDS */
+ return g_strdup (_("Trusted Path"));
+
+ if (window->priv->label != NULL &&
+ (error = libtsol_str_to_label (window->priv->label,
+ &mlabel, MAC_LABEL,
+ L_NO_CORRECTION, &error)) == 0)
+ {
+ error = libtsol_label_to_str (mlabel,
+ &human_readable_label,
+ M_LABEL, DEF_NAMES);
+ return human_readable_label;
+ }
+ }
+ return NULL;
+}
+
+GdkColor *
+wnck_window_get_label_color (WnckWindow *window)
+{
+ g_return_val_if_fail (WNCK_IS_WINDOW (window), NULL);
+ if (_wnck_check_xtsol_extension() && _wnck_use_trusted_extensions())
+ return window->priv->label_color;
+ else
+ return NULL;
+}
+
+const char *
+wnck_window_get_label_color_str (WnckWindow *window)
+{
+ g_return_val_if_fail (WNCK_IS_WINDOW (window), NULL);
+ if (_wnck_check_xtsol_extension() && _wnck_use_trusted_extensions())
+ return window->priv->label_color_str;
+ else
+ return NULL;
+}
+
+const char *
+wnck_window_get_role (WnckWindow *window)
+{
+ g_return_val_if_fail (WNCK_IS_WINDOW (window), NULL);
+
+ return window->priv->role;
+}
+#endif
/**
* wnck_window_get_application:
@@ -1793,9 +1936,44 @@ void
wnck_window_move_to_workspace (WnckWindow *window,
WnckWorkspace *space)
{
+#ifdef HAVE_XTSOL
+ static char *workstationowner = NULL;
+#endif
+
g_return_if_fail (WNCK_IS_WINDOW (window));
g_return_if_fail (WNCK_IS_WORKSPACE (space));
+#ifdef HAVE_XTSOL
+ if ((_wnck_check_xtsol_extension) && (_wnck_use_trusted_extensions ())) {
+ char *windowrole = NULL;
+ char *workspacerole = wnck_workspace_get_role (space);
+ windowrole = wnck_window_get_role (window);
+ /*
+ * Only windows that are in the Trusted Path
+ * are allowed to be move onto a role workspace
+ * This could be implemented in _wnck_window_change_workspace() but
+ * it's less complicated to do so here.
+ */
+ if (workstationowner == NULL) {
+ uid_t wsuid;
+ struct passwd *pwd;
+ if ((libxtsol_XTSOLgetWorkstationOwner (gdk_x11_get_default_xdisplay (), &wsuid)) < 0) {
+ g_warning ("XTSOLgetWorkstationOwner() failed. Using getuid() instead");
+ pwd = getpwuid (getuid ());
+ } else
+ pwd = getpwuid (wsuid);
+ workstationowner = g_strdup (pwd->pw_name);
+ }
+
+ /* Don't allow non-trusted path windows into role workspaces unless the window role
+ * matches the workspace role
+ */
+ if ((workspacerole != NULL) && (strcmp (workstationowner, workspacerole)) &&
+ (!wnck_window_is_trusted (window)) && (strcmp (workspacerole, windowrole)))
+ return;
+ }
+#endif
+
_wnck_change_workspace (WNCK_SCREEN_XSCREEN (window->priv->screen),
window->priv->xwindow,
wnck_workspace_get_number (space));
@@ -2405,9 +2583,39 @@ gboolean
wnck_window_is_on_workspace (WnckWindow *window,
WnckWorkspace *workspace)
{
+#ifdef HAVE_XTSOL
+ static char *workstationowner = NULL;
+#endif
+
g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE);
g_return_val_if_fail (WNCK_IS_WORKSPACE (workspace), FALSE);
+#ifdef HAVE_XTSOL
+ /*
+ * Non trusted path windows will not be visible on role workspaces
+ * unless the window role matches the workspace role.
+ */
+ if (_wnck_use_trusted_extensions () && _wnck_check_xtsol_extension ()) {
+ char *windowrole = g_strdup (wnck_window_get_role (window));
+ char *workspacerole = wnck_workspace_get_role (workspace);
+
+ if (workstationowner == NULL) {
+ uid_t wsuid;
+ struct passwd *pwd;
+ if ((libxtsol_XTSOLgetWorkstationOwner (gdk_x11_get_default_xdisplay (), &wsuid)) < 0) {
+ g_warning ("XTSOLgetWorkstationOwner() failed. Using getuid() instead");
+ pwd = getpwuid (getuid ());
+ } else
+ pwd = getpwuid (wsuid);
+ workstationowner = g_strdup (pwd->pw_name);
+ }
+ if ((workspacerole != NULL) && (strcmp (workstationowner, workspacerole)) &&
+ (!wnck_window_is_trusted (window)) && (strcmp (workspacerole, windowrole))) {
+ return FALSE;
+ }
+ }
+#endif
+
return wnck_window_is_pinned (window) ||
wnck_window_get_workspace (window) == workspace;
}
@@ -2434,8 +2642,12 @@ wnck_window_is_in_viewport (WnckWindow
g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE);
g_return_val_if_fail (WNCK_IS_WORKSPACE (workspace), FALSE);
+ /* Being pinned is no guarantee in a trusted desktop */
+ /* TESTME */
+#ifndef HAVE_XTSOL
if (wnck_window_is_pinned (window) )
return TRUE;
+#endif
if (wnck_window_get_workspace (window) != workspace)
return FALSE;
@@ -2805,6 +3017,91 @@ update_icon_name (WnckWindow *window)
window->priv->icon_name = new_name;
}
+#ifdef HAVE_XTSOL
+
+static void
+update_label_color (WnckWindow *window, m_label_t* label)
+{
+ #define DEFAULT_COLOR "white"
+ int error;
+
+ if (window->priv->label_color)
+ g_free (window->priv->label_color);
+
+ if (window->priv->label_color_str)
+ g_free (window->priv->label_color_str);
+
+ window->priv->label_color = g_new0 (GdkColor, 1);
+
+ error = libtsol_label_to_str (label, &window->priv->label_color_str, M_COLOR, DEF_NAMES);
+ if (window->priv->label_color_str == NULL)
+ window->priv->label_color_str = g_strdup(DEFAULT_COLOR);
+
+ gdk_color_parse ((const char*)window->priv->label_color_str, window->priv->label_color);
+}
+
+static void
+update_window_role (WnckWindow *window)
+{
+ int error;
+ gulong xid;
+ uid_t uid = -1;
+ struct passwd *pwd;
+
+ if (window->priv->role)
+ g_free (window->priv->role);
+ xid = wnck_window_get_xid (window);
+ error = libxtsol_XTSOLgetResUID (gdk_x11_get_default_xdisplay (),
+ xid, IsWindow, &uid);
+ if ((error < 0) || (uid < 0)) {
+ pwd = getpwuid (getuid);
+ g_warning ("XTSOLgetResUID() failed. Assuming window %d belongs to %s\n", xid, pwd->pw_name);
+ } else
+ pwd = getpwuid (uid);
+ window->priv->role = g_strdup (pwd->pw_name);
+}
+
+/*
+ * Since window sensitivity labels are static, this is a one time
+ * only function for each window.
+ */
+void
+wnck_window_update_label (WnckWindow *window)
+{
+ g_return_if_fail (window->priv->label == NULL);
+
+ if (!window->priv->need_update_label)
+ return;
+ window->priv->need_update_label = FALSE;
+
+ if (!_wnck_use_trusted_extensions())
+ return;
+
+ /* Check for a trusted windowing environment first */
+ if (_wnck_check_xtsol_extension () && _wnck_use_trusted_extensions()) {
+ if (window->priv->label == NULL) {
+ m_label_t label;
+ int error;
+ if (libxtsol_XTSOLgetResLabel(gdk_x11_display_get_xdisplay(gdk_display_get_default), window->priv->xwindow,
+ IsWindow, &label)) {
+ error = libtsol_label_to_str (&label, &window->priv->label, M_INTERNAL,
+ LONG_NAMES);
+ /* add label color */
+ update_label_color (window, &label);
+ update_window_role (window);
+
+ } else {
+ window->priv->label = NULL;
+ }
+ }
+ } else {
+ g_warning("Window labelling needs the SUN_TSOL X server extension");
+ return;
+ }
+
+}
+#endif
+
static void
update_workspace (WnckWindow *window)
{
@@ -3172,6 +3469,14 @@ force_update_now (WnckWindow *window)
if (window->priv->need_emit_name_changed)
emit_name_changed (window);
+#ifdef HAVE_XTSOL
+ if (_wnck_check_xtsol_extension () && _wnck_use_trusted_extensions()) {
+ if (window->priv->is_trusted < 0)
+ window->priv->is_trusted = libxtsol_XTSOLIsWindowTrusted (gdk_x11_display_get_xdisplay(gdk_display_get_default), window->priv->xwindow);
+ if (window->priv->label == NULL)
+ wnck_window_update_label (window);
+ }
+#endif
old_state = COMPRESS_STATE (window);
old_actions = window->priv->actions;
diff -urN libwnck.orig/libwnck/window.h libwnck.new/libwnck/window.h
--- libwnck.orig/libwnck/window.h 2008-08-06 23:43:13.423557000 +0100
+++ libwnck.new/libwnck/window.h 2008-08-06 23:43:40.134710000 +0100
@@ -31,6 +31,7 @@
#include <glib-object.h>
#include <libwnck/screen.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
+#include <gdk/gdk.h>
G_BEGIN_DECLS
@@ -289,6 +290,14 @@
const char* wnck_window_get_name (WnckWindow *window);
gboolean wnck_window_has_icon_name (WnckWindow *window);
const char* wnck_window_get_icon_name (WnckWindow *window);
+#ifdef HAVE_XTSOL
+const char* wnck_window_get_label (WnckWindow *window);
+char* wnck_window_get_label_human_readable (WnckWindow *window);
+GdkColor* wnck_window_get_label_color (WnckWindow *window);
+const char* wnck_window_get_label_color_str (WnckWindow *window);
+void wnck_window_update_label (WnckWindow *window);
+const char* wnck_window_get_role (WnckWindow *window);
+#endif
WnckApplication* wnck_window_get_application (WnckWindow *window);
WnckWindow* wnck_window_get_transient (WnckWindow *window);
@@ -321,6 +330,9 @@
gboolean wnck_window_is_sticky (WnckWindow *window);
gboolean wnck_window_needs_attention (WnckWindow *window);
gboolean wnck_window_or_transient_needs_attention (WnckWindow *window);
+#ifdef HAVE_XTSOL
+gboolean wnck_window_is_trusted (WnckWindow *window);
+#endif
void wnck_window_set_skip_pager (WnckWindow *window,
gboolean skip);
diff -urN libwnck.orig/libwnck/wnck-tsol.c libwnck.new/libwnck/wnck-tsol.c
--- libwnck.orig/libwnck/wnck-tsol.c 1970-01-01 01:00:00.000000000 +0100
+++ libwnck.new/libwnck/wnck-tsol.c 2008-08-06 23:43:40.140377000 +0100
@@ -0,0 +1,289 @@
+#include <config.h>
+#ifdef HAVE_XTSOL
+
+#include <stdlib.h>
+#include <strings.h>
+#include <dlfcn.h>
+#include <link.h>
+#include <glib.h>
+#include "wnck-tsol.h"
+#include "tsol-pics.h"
+
+static
+void * dlopen_bsm (void)
+{
+ return dlopen ("/usr/lib/libbsm.so", RTLD_LAZY);
+}
+
+static
+void * dlopen_tsol (void)
+{
+ void *handle = NULL;
+
+ /*
+ * No 64-bit version of libwnck so we can get away with hardcoding
+ * to a single path on this occasion
+ */
+ if ((handle = dlopen ("/usr/lib/libtsol.so.2", RTLD_LAZY)) != NULL)
+ return handle;
+
+ return handle;
+}
+
+static
+void * dlopen_gnometsol (void)
+{
+ void *handle = NULL;
+
+ if ((handle = dlopen ("/usr/lib/libgnometsol.so", RTLD_LAZY)) != NULL)
+ return handle;
+
+ return handle;
+}
+
+static
+void * dlopen_xtsol (void)
+{
+ void *handle = NULL;
+
+ if ((handle = dlopen ("/usr/lib/libXtsol.so.1", RTLD_LAZY)) != NULL)
+ return handle;
+ if ((handle = dlopen ("/usr/openwin/lib/libXtsol.so.1", RTLD_LAZY)) != NULL)
+ return handle;
+
+ return handle;
+}
+
+gboolean
+_wnck_use_trusted_extensions (void)
+{
+
+ static int trusted = -1;
+
+ /*
+ * Sun Trusted Extensions (tm) for Solaris (tm) support.
+ *
+ * It is necessary to use dlopen because the label aware extensions to libwnck work
+ * only on systems with the trusted extensions installed and with the SUN_TSOL
+ * xserver extension present
+ */
+
+ if (trusted < 0) {
+ static gpointer bsm_handle = NULL;
+ static gpointer tsol_handle = NULL;
+ static gpointer xtsol_handle = NULL;
+ static gpointer gnometsol_handle = NULL;
+
+ if (getenv ("TRUSTED_SESSION") == NULL) {
+ trusted = 0;
+ return 0;
+ }
+
+ bsm_handle = dlopen_bsm ();
+ tsol_handle = dlopen_tsol ();
+ xtsol_handle = dlopen_xtsol ();
+
+ if (bsm_handle && tsol_handle && xtsol_handle) {
+ /* libbsm function (only interested in the one) */
+ libbsm_getdevicerange = (bsm_getdevicerange) dlsym (bsm_handle, "getdevicerange");
+
+ /* libtsol functions */
+ libtsol_label_to_str = (tsol_label_to_str) dlsym (tsol_handle, "label_to_str");
+ libtsol_str_to_label = (tsol_str_to_label) dlsym (tsol_handle, "str_to_label");
+ libtsol_m_label_free = (tsol_m_label_free) dlsym (tsol_handle, "m_label_free");
+
+ /* Other misc. libtsol functions */
+ libtsol_blminimum = (tsol_blminimum) dlsym (tsol_handle, "blminimum");
+ libtsol_blmaximum = (tsol_blmaximum) dlsym (tsol_handle, "blmaximum");
+ libtsol_blinrange = (tsol_blinrange) dlsym (tsol_handle, "blinrange");
+ libtsol_getuserrange = (tsol_getuserrange) dlsym (tsol_handle, "getuserrange");
+ libtsol_blabel_alloc = (tsol_blabel_alloc) dlsym (tsol_handle, "blabel_alloc");
+ libtsol_blabel_free = (tsol_blabel_free) dlsym (tsol_handle, "blabel_free");
+ libtsol_bsllow = (tsol_bsllow) dlsym (tsol_handle, "bsllow");
+ libtsol_bslhigh = (tsol_bslhigh) dlsym (tsol_handle, "bslhigh");
+
+
+
+ /* libXtsol functions */
+ libxtsol_XTSOLgetResLabel = (xtsol_XTSOLgetResLabel) dlsym (xtsol_handle,
+ "XTSOLgetResLabel");
+ libxtsol_XTSOLgetResUID = (xtsol_XTSOLgetResUID) dlsym (xtsol_handle,
+ "XTSOLgetResUID");
+ libxtsol_XTSOLgetWorkstationOwner = (xtsol_XTSOLgetWorkstationOwner) dlsym (xtsol_handle,
+ "XTSOLgetWorkstationOwner");
+ libxtsol_XTSOLIsWindowTrusted = (xtsol_XTSOLIsWindowTrusted) dlsym (xtsol_handle,
+ "XTSOLIsWindowTrusted");
+
+ if (libbsm_getdevicerange == NULL ||
+ libtsol_label_to_str == NULL ||
+ libtsol_str_to_label == NULL ||
+ libtsol_m_label_free == NULL ||
+ libtsol_blminimum == NULL ||
+ libtsol_blmaximum == NULL ||
+ libtsol_blinrange == NULL ||
+ libtsol_getuserrange == NULL ||
+ libtsol_blabel_alloc == NULL ||
+ libtsol_blabel_free == NULL ||
+ libtsol_bsllow == NULL ||
+ libtsol_bslhigh == NULL ||
+ libxtsol_XTSOLgetResLabel == NULL ||
+ libxtsol_XTSOLgetResUID == NULL ||
+ libxtsol_XTSOLgetWorkstationOwner == NULL ||
+ libxtsol_XTSOLIsWindowTrusted == NULL) {
+ dlclose (bsm_handle);
+ dlclose (tsol_handle);
+ dlclose (xtsol_handle);
+ bsm_handle = NULL;
+ tsol_handle = NULL;
+ xtsol_handle = NULL;
+ }
+ }
+ gnometsol_handle = dlopen_gnometsol ();
+ if (gnometsol_handle != NULL)
+ {
+ libgnome_tsol_constraint_image_render = (gnome_tsol_constraint_image_render) dlsym (gnometsol_handle, "gnome_tsol_constraint_image_render");
+ libgnome_tsol_constraint_image_set_border = (gnome_tsol_constraint_image_set_border) dlsym (gnometsol_handle, "gnome_tsol_constraint_image_set_border");
+ libgnome_tsol_constraint_image_set_stretch = (gnome_tsol_constraint_image_set_stretch) dlsym (gnometsol_handle, "gnome_tsol_constraint_image_set_stretch");
+ libgnome_tsol_constraint_image_colorize = (gnome_tsol_constraint_image_colorize) dlsym (gnometsol_handle, "gnome_tsol_constraint_image_colorize");
+
+ if (libgnome_tsol_constraint_image_render == NULL ||
+ libgnome_tsol_constraint_image_set_border == NULL ||
+ libgnome_tsol_constraint_image_set_stretch == NULL ||
+ libgnome_tsol_constraint_image_colorize == NULL)
+ gnometsol_handle = NULL;
+
+ }
+ trusted = ((bsm_handle != NULL) && (tsol_handle != NULL) && (xtsol_handle != NULL) && (gnometsol_handle != NULL)) ? 1 : 0;
+ }
+ return trusted ? TRUE : FALSE;
+}
+
+const char *
+_wnck_get_min_label ()
+{
+ static char *min_label = NULL;
+
+ if (!min_label) {
+ min_label = (char *) getenv ("USER_MIN_SL");
+ }
+ return min_label;
+}
+
+const char*
+_wnck_get_max_label()
+{
+ static char *max_label = NULL;
+
+ if (!max_label) {
+ max_label = (char *) getenv ("USER_MAX_SL");
+ }
+ return max_label;
+}
+
+
+/* GFX part */
+
+
+typedef struct _HighlightStripe HighlightStripe;
+
+struct _HighlightStripe
+{
+ ConstraintImage *image;
+ char *name;
+};
+
+static gint
+label_string_compare (HighlightStripe *tmp, char *searched_label)
+{
+ return strcmp (searched_label, tmp->name);
+}
+
+ConstraintImage *
+get_highlight_stripe (char *name,
+ GdkColor *label_color)
+{
+ static GSList *hl_stripe_list = NULL;
+ GSList *stored_hl_stripe = NULL;
+ HighlightStripe *hl_stripe;
+
+ if ((name == NULL) || (label_color == NULL))
+ return NULL;
+
+
+ stored_hl_stripe = g_slist_find_custom (hl_stripe_list,
+ name,
+ (GCompareFunc)label_string_compare);
+ if (stored_hl_stripe)
+ return ((HighlightStripe* )stored_hl_stripe->data)->image;
+
+ hl_stripe = g_new0 (HighlightStripe, 1);
+
+ hl_stripe->name = g_strdup (name);
+
+ hl_stripe->image = g_new0 (ConstraintImage, 1);
+
+ hl_stripe->image->pixbuf = gdk_pixbuf_new_from_inline (-1,
+ highlight_stripe_pb,
+ TRUE, NULL);
+
+ libgnome_tsol_constraint_image_set_border (hl_stripe->image, 3, 0, 1, 1);
+ libgnome_tsol_constraint_image_set_stretch (hl_stripe->image, TRUE);
+ libgnome_tsol_constraint_image_colorize (hl_stripe->image, label_color, 255, TRUE);
+
+ hl_stripe_list = g_slist_append (hl_stripe_list, hl_stripe);
+ return hl_stripe->image;
+}
+
+static gboolean label_expose_event (GtkWidget *widget,
+ GdkEventExpose *event,
+ gpointer data)
+{
+ WnckWindow *window = (WnckWindow *) data;
+
+ GdkGC *tmp_gc = gdk_gc_new (widget->window);
+ gdk_gc_set_rgb_fg_color (tmp_gc, wnck_window_get_label_color (window));
+
+ gdk_draw_rectangle (widget->window,
+ widget->style->black_gc,
+ FALSE,
+ event->area.x, event->area.y,
+ event->area.width - 1, event->area.height - 1);
+
+ gdk_draw_rectangle (widget->window,
+ tmp_gc,
+ TRUE,
+ event->area.x + 1, event->area.y + 1,
+ event->area.width - 2, event->area.height - 2);
+
+ g_object_unref (tmp_gc);
+
+ return FALSE;
+}
+
+GtkWidget *
+window_menu_create_label_indicator (WnckWindow *window,
+ GtkWidget *image)
+{
+ GtkWidget *da, *hbox;
+ da = gtk_drawing_area_new ();
+
+ g_signal_connect (G_OBJECT (da), "expose_event",
+ G_CALLBACK (label_expose_event),
+ window);
+
+ gtk_widget_set_size_request (da, 5, -1);
+
+ hbox = gtk_hbox_new (FALSE, 4);
+
+ gtk_container_add (GTK_CONTAINER (hbox), da);
+ gtk_container_add (GTK_CONTAINER (hbox), image);
+
+ gtk_widget_show (da);
+ gtk_widget_show (hbox);
+ gtk_widget_show (image);
+
+ return hbox;
+}
+
+
+#endif /* HAVE_XTSOL */
diff -urN libwnck.orig/libwnck/wnck-tsol.h libwnck.new/libwnck/wnck-tsol.h
--- libwnck.orig/libwnck/wnck-tsol.h 1970-01-01 01:00:00.000000000 +0100
+++ libwnck.new/libwnck/wnck-tsol.h 2008-08-06 23:43:40.142752000 +0100
@@ -0,0 +1,133 @@
+#ifndef __WNCK_TSOL_H__
+#define __WNCK_TSOL_H__
+
+#include <config.h>
+
+#ifdef HAVE_XTSOL
+#include <pwd.h>
+#include <glib-2.0/glib.h>
+#include <tsol/label.h>
+#include <sys/tsol/label_macro.h>
+#include <X11/Xlib.h>
+#include <X11/extensions/Xtsol.h>
+#include <gtk/gtk.h>
+#include "libwnck.h"
+
+typedef struct _ConstraintImage ConstraintImage;
+struct _ConstraintImage
+{
+ gchar *filename;
+ GdkPixbuf *pixbuf;
+ GdkPixbuf *scaled;
+ gboolean stretch;
+ gint border_left;
+ gint border_right;
+ gint border_bottom;
+ gint border_top;
+ guint hints[3][3];
+ gboolean recolorable;
+ GdkColor colorize_color;
+ gboolean use_as_bkg_mask;
+};
+
+/* libbsm provides getdevicerange(3TSOL) - don't believe the man page */
+typedef blrange_t* (*bsm_getdevicerange) (const char *device);
+
+/* Libtsol functions */
+typedef int (*tsol_label_to_str) (const m_label_t *label, char **string,
+ const m_label_str_t conversion_type,
+ uint_t flags);
+typedef int (*tsol_str_to_label) (const char *string, m_label_t **label,
+ const m_label_type_t label_type,
+ uint_t flags,
+ int *error);
+
+typedef void (*tsol_m_label_free) (m_label_t *label);
+
+/* Other misc. libtsol functions */
+typedef blrange_t* (*tsol_getuserrange) (const char *username);
+typedef int (*tsol_blinrange) (const m_label_t *label,
+ const blrange_t *range);
+typedef void (*tsol_blminimum) (m_label_t *minimum_label,
+ const m_label_t *bounding_label);
+typedef void (*tsol_blmaximum) (m_label_t *maximum_label,
+ const m_label_t *bounding_label);
+typedef m_label_t* (*tsol_blabel_alloc) (void);
+typedef void (*tsol_blabel_free) (m_label_t *label_p);
+typedef void (*tsol_bsllow) (m_label_t *label);
+typedef void (*tsol_bslhigh) (m_label_t *label);
+
+/* libXtsol functions */
+typedef Status (*xtsol_XTSOLgetResLabel) (Display *dpy, XID xid,
+ ResourceType resourceFlag, bslabel_t *sl);
+typedef Status (*xtsol_XTSOLgetResUID) (Display *dpy, XID object,
+ ResourceType resourceFlag,
+ uid_t *uidp);
+typedef Status (*xtsol_XTSOLgetWorkstationOwner) (Display *dpy, uid_t *uidp);
+typedef Bool (*xtsol_XTSOLIsWindowTrusted) (Display *dpy, Window win);
+
+/* libgnometsol functions */
+typedef void (*gnome_tsol_constraint_image_render) (ConstraintImage *cimage,
+ GdkWindow *window,
+ void *mask,
+ GdkRectangle *clip_rect,
+ gboolean center,
+ gint x,
+ gint y,
+ gint width,
+ gint height);
+
+typedef void (*gnome_tsol_constraint_image_set_border) (ConstraintImage *pb,
+ gint left,
+ gint right,
+ gint top,
+ gint bottom);
+
+typedef void (*gnome_tsol_constraint_image_set_stretch) (ConstraintImage *pb,
+ gboolean stretch);
+
+typedef void (*gnome_tsol_constraint_image_colorize) (ConstraintImage *image,
+ GdkColor *color,
+ int alpha,
+ gboolean use_alpha);
+
+/* libbsm functions */
+bsm_getdevicerange libbsm_getdevicerange;
+/* libtsol functions*/
+tsol_label_to_str libtsol_label_to_str;
+tsol_str_to_label libtsol_str_to_label;
+tsol_m_label_free libtsol_m_label_free;
+/* Other misc. libtsol functions */
+tsol_blminimum libtsol_blminimum;
+tsol_blmaximum libtsol_blmaximum;
+tsol_blinrange libtsol_blinrange;
+tsol_getuserrange libtsol_getuserrange;
+tsol_blabel_alloc libtsol_blabel_alloc;
+tsol_blabel_free libtsol_blabel_free;
+tsol_bsllow libtsol_bsllow;
+tsol_bslhigh libtsol_bslhigh;
+
+xtsol_XTSOLgetResLabel libxtsol_XTSOLgetResLabel;
+xtsol_XTSOLgetResUID libxtsol_XTSOLgetResUID;
+xtsol_XTSOLgetWorkstationOwner libxtsol_XTSOLgetWorkstationOwner;
+xtsol_XTSOLIsWindowTrusted libxtsol_XTSOLIsWindowTrusted;
+
+gnome_tsol_constraint_image_render libgnome_tsol_constraint_image_render;
+gnome_tsol_constraint_image_set_border libgnome_tsol_constraint_image_set_border;
+gnome_tsol_constraint_image_set_stretch libgnome_tsol_constraint_image_set_stretch;
+gnome_tsol_constraint_image_colorize libgnome_tsol_constraint_image_colorize;
+
+const char* _wnck_get_min_label ();
+const char* _wnck_get_max_label ();
+
+
+/* GFX part */
+
+ConstraintImage* get_highlight_stripe (char* name,
+ GdkColor* label_color);
+
+GtkWidget* window_menu_create_label_indicator (WnckWindow *window,
+ GtkWidget *image);
+
+#endif /* HAVE_XTSOL */
+#endif
diff -urN libwnck.orig/libwnck/workspace.c libwnck.new/libwnck/workspace.c
--- libwnck.orig/libwnck/workspace.c 2008-08-06 23:43:13.502854000 +0100
+++ libwnck.new/libwnck/workspace.c 2008-08-06 23:51:01.138260000 +0100
@@ -26,6 +26,16 @@
#include <config.h>
#include <glib/gi18n-lib.h>
+#ifdef HAVE_XTSOL
+#include <stdlib.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <user_attr.h>
+#include <X11/Xlib.h>
+#include <X11/extensions/Xtsol.h>
+#include <libgnometsol/userattr.h>
+#include <wnck-tsol.h>
+#endif
#include "workspace.h"
#include "xutils.h"
#include "private.h"
@@ -69,6 +79,13 @@ struct _WnckWorkspacePrivate
WnckScreen *screen;
int number;
char *name;
+#ifdef HAVE_XTSOL /* TSOL */
+ char *label; /* Workspace sensitivity label */
+ char *role; /* Workspace role : login name. Set only once */
+ /* The workspace range can differ for Workstation Owner and role workspaces */
+ const blrange_t *ws_range;
+#endif
+
int width, height; /* Workspace size */
int viewport_x, viewport_y; /* Viewport origin */
gboolean is_virtual;
@@ -79,6 +96,10 @@ G_DEFINE_TYPE (WnckWorkspace, wnck_works
enum {
NAME_CHANGED,
+#ifdef HAVE_XTSOL
+ LABEL_CHANGED,
+ ROLE_CHANGED,
+#endif
LAST_SIGNAL
};
@@ -91,6 +112,12 @@ static void emit_name_changed (WnckWorks
static guint signals[LAST_SIGNAL] = { 0 };
+#ifdef HAVE_XTSOL
+static void emit_label_changed (WnckWorkspace *space);
+static void emit_role_changed (WnckWorkspace *space);
+static blrange_t * get_display_range (void);
+#endif
+
static void
wnck_workspace_init (WnckWorkspace *workspace)
{
@@ -104,6 +131,9 @@ wnck_workspace_init (WnckWorkspace *work
workspace->priv->viewport_x = 0;
workspace->priv->viewport_y = 0;
workspace->priv->is_virtual = FALSE;
+#ifdef HAVE_XTSOL
+ workspace->priv->ws_range = NULL;
+#endif
}
static void
@@ -129,6 +159,24 @@ wnck_workspace_class_init (WnckWorkspace
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
+#ifdef HAVE_XTSOL
+ signals[LABEL_CHANGED] =
+ g_signal_new ("label_changed",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (WnckWorkspaceClass, label_changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+ signals[ROLE_CHANGED] =
+ g_signal_new ("role_changed",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (WnckWorkspaceClass, role_changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+#endif
}
static void
@@ -141,6 +189,11 @@ wnck_workspace_finalize (GObject *object
g_free (workspace->priv->name);
workspace->priv->name = NULL;
+#ifdef HAVE_XTSOL
+ g_free (workspace->priv->role);
+ g_free (workspace->priv->label);
+#endif
+
G_OBJECT_CLASS (wnck_workspace_parent_class)->finalize (object);
}
@@ -179,6 +232,134 @@ wnck_workspace_get_name (WnckWorkspace *
return space->priv->name;
}
+#ifdef HAVE_XTSOL
+/**
+ * wnck_workspace_get_label_range:
+ * @space: a #WnckWorkspace
+ * @min_label: a string pointer to pointer to the minimum valid label value for @space
+ * @max_label: a string pointer to pointer to the maximum valid label value for @space
+ *
+ * Gets the sensitivity label range for the specified workspace when
+ * running in a label aware desktop session. @min_label represents the minimum
+ * sensitivity label that the #WnckWorkspace, @space, may be assigned.
+ * @max_label represents the maximum sensitivity label thatthe #WnckWorkspace,
+ * @space may be assigned. Both min_label and max_label are allocated memory
+ * on behalf of the caller. It is the caller's responsibility to free the memory
+ * pointed to by @min_label and @max_label.
+ *
+ * Return value: 0 on success, non zero on failure.
+ **/
+int
+wnck_workspace_get_label_range (WnckWorkspace *space, char **min_label, char **max_label)
+{
+ int error = 0;
+ blrange_t *brange;
+ g_return_val_if_fail (WNCK_IS_WORKSPACE (space), -1);
+
+ if (! _wnck_check_xtsol_extension ())
+ return -1;
+
+ if (!_wnck_use_trusted_extensions())
+ return -1;
+
+ brange = _wnck_workspace_get_range (space);
+ if (!brange)
+ return -1;
+
+ if (libtsol_label_to_str (brange->lower_bound, min_label, M_INTERNAL,
+ LONG_NAMES) != 0) {
+ g_warning ("wnck_workspace_get_label_range: Workspace has an invalid minimum label bound");
+ return -1;
+ }
+
+ if (libtsol_label_to_str (brange->upper_bound, max_label, M_INTERNAL,
+ LONG_NAMES) != 0) {
+ g_warning ("wnck_workspace_get_label_range: Workspace has an invalid maximum label bound");
+ return -1;
+ }
+ return 0;
+}
+
+/**
+ * wnck_workspace_get_label:
+ * @space: a #WnckWorkspace
+ *
+ * Gets the sensitivity label as an hex number for the specified
+ * workspace when running in a label aware desktop session.
+ *
+ * Return value: workspace sensitivity label, %NULL on failure.
+ **/
+const char*
+wnck_workspace_get_label (WnckWorkspace *space)
+{
+ g_return_val_if_fail (WNCK_IS_WORKSPACE (space), NULL);
+ /* A bit anal perhaps but I'd rather make sure nothing useful is returned */
+ if (! (_wnck_check_xtsol_extension() && _wnck_use_trusted_extensions()) )
+ return NULL;
+ return space->priv->label;
+}
+
+/**
+ * wnck_workspace_get_human_readable_label:
+ * @space: a #WnckWorkspace
+ *
+ * Gets the sensitivity label as a string for the specified workspace when
+ * running in a label aware desktop session.
+ *
+ *
+ * Return value: workspace sensitivity label, %NULL on failure.
+ **/
+char*
+wnck_workspace_get_human_readable_label (WnckWorkspace *space)
+{
+ const char *hex_label;
+ char *human_readable_label;
+ int error;
+ m_label_t *mlabel = NULL;
+
+ g_return_val_if_fail (WNCK_IS_WORKSPACE (space), NULL);
+ if (! (_wnck_check_xtsol_extension() && _wnck_use_trusted_extensions()) )
+ return NULL;
+
+ hex_label = space->priv->label;
+
+ if (hex_label && (error = libtsol_str_to_label (hex_label, &mlabel, MAC_LABEL,
+ L_NO_CORRECTION, &error) == 0))
+ {
+ error = libtsol_label_to_str (mlabel,
+ &human_readable_label,
+ M_LABEL, DEF_NAMES);
+ if (strcmp (human_readable_label, "ADMIN_HIGH") == 0 ||
+ strcmp (human_readable_label, "ADMIN_LOW") == 0)
+ /* SUN_BRANDING TJDS */
+ return g_strdup (_("Trusted Path"));
+ return human_readable_label;
+ }
+ return NULL;
+}
+
+
+/**
+ * wnck_workspace_get_role:
+ * @space: a #WnckWorkspace
+ *
+ * Gets the role (login name) for the specified workspace when
+ * running in a trusted desktop session.
+ *
+ * Return value: workspace user role, %NULL on failure.
+ **/
+const char*
+wnck_workspace_get_role (WnckWorkspace *space)
+{
+ g_return_val_if_fail (WNCK_IS_WORKSPACE (space), NULL);
+ /* Make sure to return NULL for non-tsol */
+ if (! (_wnck_check_xtsol_extension() && _wnck_use_trusted_extensions()) )
+ return NULL;
+ return space->priv->role;
+}
+#endif /* HAVE_XTSOL */
+
+
/**
* wnck_workspace_change_name:
* @space: a #WnckWorkspace.
@@ -217,6 +398,29 @@ wnck_workspace_get_screen (WnckWorkspace
return space->priv->screen;
}
+#ifdef HAVE_XTSOL
+/**
+ * wnck_workspace_change_label:
+ * @space: a #WnckWorkspace
+ * @label: new workspace sensitivity label
+ *
+ * Try changing the sensitivity label of the workspace.
+ *
+ **/
+
+void
+wnck_workspace_change_label (WnckWorkspace *space,
+ const char *label)
+{
+ g_return_if_fail (WNCK_IS_WORKSPACE (space));
+ g_return_if_fail (label != NULL);
+
+ _wnck_screen_change_workspace_label (space->priv->screen,
+ space->priv->number,
+ label);
+}
+#endif
+
/**
* wnck_workspace_activate:
* @space: a #WnckWorkspace.
@@ -254,6 +458,7 @@ _wnck_workspace_create (int number, Wnck
space->priv->screen = screen;
_wnck_workspace_update_name (space, NULL);
+ /* FIXME - do label and role need to be updated here? */
/* Just set reasonable defaults */
space->priv->width = wnck_screen_get_width (screen);
@@ -289,6 +494,251 @@ _wnck_workspace_update_name (WnckWorkspa
g_free (old);
}
+#ifdef HAVE_XTSOL
+
+static char*
+get_workstationowner (void)
+{
+ static char *workstationowner = NULL;
+ uid_t wsuid;
+ struct passwd *pwd;
+
+ if (workstationowner == NULL) {
+ if ((libxtsol_XTSOLgetWorkstationOwner (gdk_x11_get_default_xdisplay (),
+ &wsuid)) < 0) {
+ g_warning ("XTSOLgetWorkstationOwner() failed. Using getuid() instead");
+ pwd = getpwuid (getuid ());
+ } else {
+ pwd = getpwuid (wsuid);
+ }
+
+ workstationowner = g_strdup (pwd->pw_name);
+ }
+
+ return workstationowner;
+}
+
+void
+_wnck_workspace_update_label (WnckWorkspace *space,
+ const char *label)
+{
+ char *old;
+
+ g_return_if_fail (WNCK_IS_WORKSPACE (space));
+ /* Don't do anything unless this is a trusted system */
+ if (!(_wnck_check_xtsol_extension() && _wnck_use_trusted_extensions()))
+ return;
+
+ /* Should a warning be called here? */
+ if (label == NULL)
+ g_warning("Workspace %d label is null\n",
+ wnck_workspace_get_number (space));
+
+ old = space->priv->label;
+ space->priv->label = g_strdup (label);
+
+ /*
+ *Initialise the label range for this workspace
+ */
+
+ if (!space->priv->ws_range) {
+ if ((!space->priv->role) || (strlen (space->priv->role) == 0) ||
+ (strcmp (space->priv->role, get_workstationowner ()) == 0)) {
+ blrange_t *range;
+ int error;
+ char *min_label = NULL;
+ char *max_label = NULL;
+ range = g_malloc (sizeof (blrange_t));
+ range->lower_bound = range->upper_bound = NULL;
+
+ min_label = g_strdup (_wnck_get_min_label ());
+ max_label = g_strdup (_wnck_get_max_label ());
+
+ if (libtsol_str_to_label (min_label, &(range->lower_bound),
+ MAC_LABEL, L_NO_CORRECTION, &error) < 0) {
+ g_warning ("Couldn't determine minimum workspace label");
+ g_free (min_label);
+ g_free (max_label);
+ return;
+ }
+ if (libtsol_str_to_label (max_label, &(range->upper_bound),
+ USER_CLEAR, L_NO_CORRECTION, &error) < 0) {
+ g_warning ("Couldn't determine workspace clearance");
+ g_free (min_label);
+ g_free (max_label);
+ return;
+ }
+ space->priv->ws_range = range;
+ g_free (min_label);
+ g_free (max_label);
+
+ } else {
+ int error;
+ blrange_t *role_range;
+ blrange_t *disp_range;
+ userattr_t *u_ent;
+ /*
+ * This is a role workspace so we need to construct the correct label range
+ * instead of relying on USER_MIN_SL and USER_MAX_SL
+ */
+ if ((role_range = libtsol_getuserrange (space->priv->role)) == NULL) {
+ g_warning ("Couldn't get label range for %s\n", space->priv->role);
+ return;
+ }
+
+ /* Get display device's range */
+ if ((disp_range = get_display_range ()) == NULL) {
+ g_warning ("Couldn't get the display's device range");
+ return;
+ }
+
+ /*
+ * Determine the low & high bound of the label range
+ * where the role user can operate. This is the
+ * intersection of display label range & role label
+ * range.
+ */
+ libtsol_blmaximum (role_range->lower_bound, disp_range->lower_bound);
+ libtsol_blminimum (role_range->upper_bound, disp_range->upper_bound);
+ space->priv->ws_range = role_range;
+ libtsol_blabel_free (disp_range->lower_bound);
+ libtsol_blabel_free (disp_range->upper_bound);
+ free (disp_range);
+ }
+ }
+ /* Should we put a g_warning here? */
+ /* if (space->priv->label == NULL) */
+
+ if ((!old && label) ||
+ (old && label && strcmp (old, label) != 0))
+ emit_label_changed (space);
+
+ g_free (old);
+}
+
+void
+_wnck_workspace_update_role (WnckWorkspace *space,
+ const char *role)
+{
+ char *workstationowner = NULL;
+ char *old;
+
+ g_return_if_fail (WNCK_IS_WORKSPACE (space));
+ /* Check for a multi label trusted environment first */
+ if (!(_wnck_check_xtsol_extension() && _wnck_use_trusted_extensions()))
+ return;
+ workstationowner = get_workstationowner ();
+
+ if (role == NULL)
+ return;
+ old = space->priv->role;
+
+ /* Check the the workspace role really is changing */
+ if ((!old && role) ||
+ (old && role && strcmp (old, role) != 0)) {
+ g_free (space->priv->role);
+ if (strlen (role) ==0)
+ { space->priv->role = g_strdup (workstationowner); return;}
+ else
+ space->priv->role = g_strdup (role);
+
+ /*
+ * A role change requires that the label range of the
+ * workspace be reset. The label also needs to be
+ * silently set to the lowest in the range.
+ */
+
+ if (space->priv->ws_range) {
+ libtsol_blabel_free (space->priv->ws_range->lower_bound);
+ libtsol_blabel_free (space->priv->ws_range->upper_bound);
+ /* FIXME - man pages tell me to use free but generates a compiler warning */
+ free ((void *)space->priv->ws_range);
+ }
+
+ if (strcmp (space->priv->role, workstationowner) == 0) {
+ /* Workstation owner, so it's not a real role */
+ blrange_t *range;
+ int error;
+ char *min_label = NULL;
+ char *max_label = NULL;
+ range = g_malloc (sizeof (blrange_t));
+ range->lower_bound = range->upper_bound = NULL;
+
+ min_label = g_strdup (_wnck_get_min_label ());
+ max_label = g_strdup (_wnck_get_max_label ());
+
+ /* Workspace label must be reset by default to the min_label value */
+ if (space->priv->label)
+ g_free (space->priv->label);
+ space->priv->label = g_strdup (min_label);
+
+ if (libtsol_str_to_label (min_label, &(range->lower_bound),
+ MAC_LABEL, L_NO_CORRECTION, &error) < 0) {
+ g_warning ("Couldn't determine minimum workspace label");
+ g_free (min_label);
+ g_free (max_label);
+ return;
+ }
+
+ if (libtsol_str_to_label (max_label, &(range->upper_bound),
+ USER_CLEAR, L_NO_CORRECTION, &error) < 0) {
+ g_warning ("Couldn't determine workspace clearance");
+ g_free (min_label);
+ g_free (max_label);
+ return;
+ }
+
+ space->priv->ws_range = range;
+ g_free (min_label);
+ g_free (max_label);
+
+ } else {
+ int error;
+ blrange_t *role_range;
+ blrange_t *disp_range;
+ userattr_t *u_ent;
+
+ /*
+ * This is a role workspace so we need to construct the correct label range
+ * instead of relying on USER_MIN_SL and USER_MAX_SL
+ */
+ if ((role_range = libtsol_getuserrange (space->priv->role)) == NULL) {
+ g_warning ("Couldn't get label range for %s\n", space->priv->role);
+ return;
+ }
+
+ /* Get display device's range */
+ if ((disp_range = get_display_range ()) == NULL) {
+ g_warning ("Couldn't get the display's device range");
+ return;
+ }
+
+ /*
+ * Determine the low & high bound of the label range
+ * where the role user can operate. This is the
+ * intersection of display label range & role label
+ * range.
+ */
+ libtsol_blmaximum (role_range->lower_bound, disp_range->lower_bound);
+ libtsol_blminimum (role_range->upper_bound, disp_range->upper_bound);
+ space->priv->ws_range = role_range;
+
+ /* Workspace label must be reset by default to the lower_bound value */
+ if (libtsol_label_to_str (role_range->lower_bound, &space->priv->label, M_INTERNAL,
+ LONG_NAMES) != 0) {
+ /* Weird - default to admin_low */
+ space->priv->label = g_strup ("ADMIN_LOW");
+ }
+
+ libtsol_blabel_free (disp_range->lower_bound);
+ libtsol_blabel_free (disp_range->upper_bound);
+ free (disp_range);
+ }
+ emit_role_changed (space);
+ }
+}
+#endif /* HAVE_XTSOL */
+
static void
emit_name_changed (WnckWorkspace *space)
{
@@ -297,6 +747,26 @@ emit_name_changed (WnckWorkspace *space)
0);
}
+#ifdef HAVE_XTSOL
+static void
+emit_label_changed (WnckWorkspace *space)
+{
+ g_signal_emit (G_OBJECT (space),
+ signals[LABEL_CHANGED],
+ 0);
+ wnck_screen_emit_labels_changed (space->priv->screen);
+}
+
+static void
+emit_role_changed (WnckWorkspace *space)
+{
+ g_signal_emit (G_OBJECT (space),
+ signals[ROLE_CHANGED],
+ 0);
+ wnck_screen_emit_roles_changed (space->priv->screen);
+}
+#endif /* HAVE_XTSOL */
+
gboolean
_wnck_workspace_set_geometry (WnckWorkspace *space,
int w,
@@ -612,3 +1082,33 @@ wnck_workspace_get_neighbor (WnckWorkspa
return wnck_screen_get_workspace (space->priv->screen, index);
}
+
+#ifdef HAVE_XTSOL
+/*
+ * These private (hint hint) functions assume that they have been called
+ * from within a trusted desktop session. The caller must ensure that
+ * this is the case otherwise it will trigger a load of the potentially
+ * non existant tsol and xtsol libs. That would be bad!
+ */
+static blrange_t *
+get_display_range (void)
+{
+ blrange_t *range = NULL;
+
+ range = libbsm_getdevicerange ("framebuffer");
+ if (range == NULL) {
+ range = g_malloc (sizeof (blrange_t));
+ range->lower_bound = libtsol_blabel_alloc ();
+ range->upper_bound = libtsol_blabel_alloc ();
+ libtsol_bsllow (range->lower_bound);
+ libtsol_bslhigh (range->upper_bound);
+ }
+ return (range);
+}
+
+blrange_t *
+_wnck_workspace_get_range (WnckWorkspace *space)
+{
+ return space->priv->ws_range;
+}
+#endif
diff -urN libwnck.orig/libwnck/workspace.h libwnck.new/libwnck/workspace.h
--- libwnck.orig/libwnck/workspace.h 2008-08-06 23:43:13.464638000 +0100
+++ libwnck.new/libwnck/workspace.h 2008-08-06 23:43:40.159050000 +0100
@@ -57,6 +57,11 @@
GObjectClass parent_class;
void (* name_changed) (WnckWorkspace *space);
+
+#ifdef HAVE_XTSOL
+ void (* label_changed) (WnckWorkspace *space);
+ void (* role_changed) (WnckWorkspace *space);
+#endif
/* Padding for future expansion */
void (* pad1) (void);
@@ -69,9 +74,22 @@
int wnck_workspace_get_number (WnckWorkspace *space);
const char* wnck_workspace_get_name (WnckWorkspace *space);
+#ifdef HAVE_XTSOL
+int wnck_workspace_get_label_range(WnckWorkspace *space,
+ char **min_label,
+ char **max_label);
+const char* wnck_workspace_get_label (WnckWorkspace *space);
+char* wnck_workspace_get_human_readable_label (WnckWorkspace *space);
+const char* wnck_workspace_get_role (WnckWorkspace *space);
+#endif
+
void wnck_workspace_change_name (WnckWorkspace *space,
const char *name);
WnckScreen* wnck_workspace_get_screen (WnckWorkspace *space);
+#ifdef HAVE_XTSOL
+void wnck_workspace_change_label (WnckWorkspace *space,
+ const char *label);
+#endif
void wnck_workspace_activate (WnckWorkspace *space,
guint32 timestamp);
int wnck_workspace_get_width (WnckWorkspace *space);
diff -urN libwnck.orig/libwnck/xutils.c libwnck.new/libwnck/xutils.c
--- libwnck.orig/libwnck/xutils.c 2008-08-06 23:43:13.631420000 +0100
+++ libwnck.new/libwnck/xutils.c 2008-08-06 23:43:40.166864000 +0100
@@ -28,6 +28,7 @@
#include <cairo-xlib.h>
#include "screen.h"
#include "window.h"
+#include "wnck-tsol.h"
#include "private.h"
#include "inlinepixbufs.h"
@@ -252,6 +253,21 @@ _wnck_get_atom (Screen *screen,
return TRUE;
}
+#ifdef HAVE_XTSOL
+gboolean
+_wnck_check_xtsol_extension ()
+{
+ static int foundxtsol = -1;
+ int major_code, first_event, first_error;
+
+ if (foundxtsol < 0) {
+ foundxtsol = XQueryExtension (gdk_x11_display_get_xdisplay(gdk_display_get_default()), "SUN_TSOL", &major_code,
+ &first_event, &first_error);
+ }
+ return foundxtsol;
+}
+#endif
+
static char*
text_property_to_utf8 (Display *display,
const XTextProperty *prop)
diff -ruN libwnck-2.30.0.orig/libwnck/Makefile.am libwnck-2.30.0/libwnck/Makefile.am
--- libwnck-2.30.0.orig/libwnck/Makefile.am 2010-04-03 21:06:32.639895227 +0100
+++ libwnck-2.30.0/libwnck/Makefile.am 2010-04-03 21:08:33.899401342 +0100
@@ -65,6 +65,11 @@ wnck_accessibility_files = \
wnck_built_headers = $(wnck_built_installed_headers) wnck-marshal.h inlinepixbufs.h
wnck_built_cfiles = wnck-enum-types.c wnck-marshal.c
+wncktsol_sources = \
+ wnck-tsol.c
+wncktsol_h_sources = \
+ wnck-tsol.h
+
libwnck_3_la_SOURCES = \
$(wnck_built_headers) \
$(wnck_built_cfiles) \
@@ -72,6 +77,11 @@ libwnck_3_la_SOURCES = \
private.h \
xutils.c \
xutils.h \
+ tsol-pics.h \
+ trusted-tooltips.c \
+ trusted-tooltips.h \
+ $(wncktsol_sources) \
+ $(wncktsol_h_sources) \
$(wnck_accessibility_files)
$(libwnck_3_la_OBJECTS): $(wnck_built_headers)