Hello,

regarding that bug:
https://bugs.launchpad.net/ubuntu/+source/emerald/+bug/726229

The situation is so, that Ubuntu is delivering for Oneiric (11.10) 
compiz based on master 0.9.5, but emerald based on compiz++ branch 
with API level of 0.9.4. The decor_quads_to_property() has changed,
thats that crash.

As appropriate, I forward ported the changes in gtk-window-decorator
to emerald. In between it had worked, but now after cleaning and completing
compiz segfaults in "decor" plugin. So, please find attached my patch:
- patch-emerald.txt 

Thats now time for code-review, as suggested earlier on mailing list.

Thanks in advance,

       Roland "Test-tools" Baer


-- 
/------------------------------------------------------------------------------\
| Verifysoft Technology GmbH | Registergericht: Amtsgericht Freiburg HRB 472242|
| In der Spoeck 10           | Geschaeftsfuehrer: Klaus Lambertz               |
| 77656 Offenburg            | Telefon: +49-781-12781189 Skype: twiddletec     |
\------------------------------------------------------------------------------/
diff --git a/src/main.c b/src/main.c
index eddd11c..4b06e91 100644
--- a/src/main.c
+++ b/src/main.c
@@ -38,8 +38,22 @@
 #define wnck_window_get_geometry wnck_window_get_client_window_geometry
 #endif
 
+#define WINDOW_TYPE_FRAMES_NUM 5
+
 void reload_all_settings(int sig);
 
+static unsigned int
+populate_frame_type (decor_t *d);
+
+static unsigned int
+populate_frame_state (decor_t *d);
+
+static unsigned int
+populate_frame_actions (decor_t *d);
+
+static const gchar *
+get_frame_type (WnckWindow *win);
+
 GdkPixmap *pdeb;
 static gboolean do_reload = FALSE;
 
@@ -93,6 +107,10 @@ static Atom emerald_sigusr1_atom;
 
 static Atom utf8_string_atom;
 
+static Atom net_wm_state_atom;
+static Atom net_wm_state_modal_atom;
+
+
 static Time dm_sn_timestamp;
 
 #define C(name) { 0, XC_ ## name }
@@ -472,12 +490,16 @@ decor_update_blur_property (decor_t *d,
 
 static void decor_update_window_property(decor_t * d)
 {
-    long data[256];
+    long *data;
     Display *xdisplay = GDK_DISPLAY_XDISPLAY(gdk_display_get_default());
     window_settings *ws = d->fs->ws;
     decor_extents_t maxextents;
     decor_extents_t extents = ws->win_extents;
     gint nQuad;
+    unsigned int    nOffset = 1;
+    unsigned int   frame_type = populate_frame_type (d);
+    unsigned int   frame_state = populate_frame_state (d);
+    unsigned int   frame_actions = populate_frame_actions (d);
     decor_quad_t quads[N_QUADS_MAX];
     int                    w, h;
     gint           stretch_offset;
@@ -504,15 +526,19 @@ static void decor_update_window_property(decor_t * d)
     else
        maxextents = extents;
 
-    decor_quads_to_property(data, GDK_PIXMAP_XID(d->pixmap),
-                           &extents, &maxextents, &maxextents, &maxextents, 0, 
0, quads, nQuad);
-
+    data = decor_alloc_property (nOffset, WINDOW_DECORATION_TYPE_PIXMAP);
+    decor_quads_to_property (data, nOffset - 1, GDK_PIXMAP_XID (d->pixmap),
+                            &extents, &extents,
+                            &extents, &extents,
+                            0 /* ICON_SPACE  + d->button_width */,
+                            0,
+                            quads, nQuad, frame_type, frame_state, 
frame_actions);
     gdk_error_trap_push();
     XChangeProperty(xdisplay, d->prop_xid,
                    win_decor_atom,
                    XA_INTEGER,
                    32, PropModeReplace, (guchar *) data,
-                   BASE_PROP_SIZE + QUAD_PROP_SIZE * nQuad);
+                   PROP_HEADER_SIZE +BASE_PROP_SIZE + QUAD_PROP_SIZE * nQuad);
     XSync(xdisplay, FALSE);
     gdk_error_trap_pop();
 
@@ -554,6 +580,7 @@ static void decor_update_window_property(decor_t * d)
                                &bottom, w / 2,
                                &left, h / 2,
                                &right, h / 2); 
+    free(data);
 }
 
 static int
@@ -1925,10 +1952,14 @@ static void draw_shadow_window(decor_t * d)
 
 static void decor_update_switcher_property(decor_t * d)
 {
-    long data[256];
+    long *data;
     Display *xdisplay = GDK_DISPLAY_XDISPLAY(gdk_display_get_default());
     gint nQuad;
     decor_quad_t quads[N_QUADS_MAX];
+    unsigned int    nOffset = 1;
+    unsigned int   frame_type = populate_frame_type (d);
+    unsigned int   frame_state = populate_frame_state (d);
+    unsigned int   frame_actions = populate_frame_actions (d);
     window_settings *ws = d->fs->ws;
     decor_extents_t extents = ws->switcher_extents;
     GtkStyle *style;
@@ -1936,8 +1967,10 @@ static void decor_update_switcher_property(decor_t * d)
 
     nQuad = set_switcher_quads(quads, d->width, d->height, ws);
 
-    decor_quads_to_property(data, GDK_PIXMAP_XID(d->pixmap),
-                           &extents, &extents, &extents, &extents, 0, 0, 
quads, nQuad);
+    data = decor_alloc_property (nOffset, WINDOW_DECORATION_TYPE_PIXMAP);
+    decor_quads_to_property (data, nOffset - 1, GDK_PIXMAP_XID (d->pixmap),
+                            &extents, &extents, &extents, &extents,
+                             0, 0, quads, nQuad, frame_type, frame_state, 
frame_actions);
 
     style = gtk_widget_get_style (style_window);
 
@@ -1956,6 +1989,8 @@ static void decor_update_switcher_property(decor_t * d)
                     XA_INTEGER, 32, PropModeReplace, (guchar *) fgColor, 4);
     XSync(xdisplay, FALSE);
     gdk_error_trap_pop();
+
+    free(data);
 }
 
 static void draw_switcher_background(decor_t * d)
@@ -2336,11 +2371,11 @@ static void
 update_default_decorations(GdkScreen * screen, frame_settings * fs_act,
                           frame_settings * fs_inact)
 {
-    long data[256];
+    long *data;
     Window xroot;
     GdkDisplay *gdkdisplay = gdk_display_get_default();
     Display *xdisplay = gdk_x11_display_get_xdisplay(gdkdisplay);
-    Atom bareAtom, normalAtom, activeAtom;
+    Atom bareAtom, activeAtom;
     decor_t d;
     gint nQuad;
     decor_quad_t quads[N_QUADS_MAX];
@@ -2352,20 +2387,21 @@ update_default_decorations(GdkScreen * screen, 
frame_settings * fs_act,
     xroot = RootWindowOfScreen(gdk_x11_screen_get_xscreen(screen));
 
     bareAtom = XInternAtom(xdisplay, DECOR_BARE_ATOM_NAME, FALSE);
-    normalAtom = XInternAtom(xdisplay, DECOR_NORMAL_ATOM_NAME, FALSE);
     activeAtom = XInternAtom(xdisplay, DECOR_ACTIVE_ATOM_NAME, FALSE);
 
     if (ws->shadow_pixmap)
     {
        int width, height;
 
+        long *data = decor_alloc_property (1, WINDOW_DECORATION_TYPE_PIXMAP);
+
        gdk_drawable_get_size(ws->shadow_pixmap, &width, &height);
 
        nQuad = set_shadow_quads(quads, width, height, ws);
 
-       decor_quads_to_property(data, GDK_PIXMAP_XID(ws->shadow_pixmap),
+       decor_quads_to_property(data, 0, GDK_PIXMAP_XID(ws->shadow_pixmap),
                                &ws->shadow_extents, &ws->shadow_extents, 
&ws->shadow_extents, &ws->shadow_extents, 0, 0,
-                               quads, nQuad);
+                               quads, nQuad, 0, 0, 0);
 
        XChangeProperty(xdisplay, xroot,
                        bareAtom,
@@ -2373,10 +2409,13 @@ update_default_decorations(GdkScreen * screen, 
frame_settings * fs_act,
                        32, PropModeReplace, (guchar *) data,
                        BASE_PROP_SIZE + QUAD_PROP_SIZE * nQuad);
 
+       free(data);
     }
     else
        XDeleteProperty(xdisplay, xroot, bareAtom);
 
+    data = decor_alloc_property (WINDOW_TYPE_FRAMES_NUM * 2, 
WINDOW_DECORATION_TYPE_PIXMAP); /* FIXME, first parameter most likely to be 1 */
+
     d.width =
        ws->left_space + ws->left_corner_space + 200 +
        ws->right_corner_space + ws->right_space;
@@ -2423,17 +2462,8 @@ update_default_decorations(GdkScreen * screen, 
frame_settings * fs_act,
 
        (*d.draw) (&d);
 
-       decor_quads_to_property(data, GDK_PIXMAP_XID(d.p_inactive),
-                               &extents, &extents, &extents, &extents, 0, 0, 
quads, nQuad);
-
-       XChangeProperty(xdisplay, xroot,
-                       normalAtom,
-                       XA_INTEGER,
-                       32, PropModeReplace, (guchar *) data,
-                       BASE_PROP_SIZE + QUAD_PROP_SIZE * nQuad);
-
-       decor_quads_to_property(data, GDK_PIXMAP_XID(d.p_active),
-                               &extents, &extents, &extents, &extents, 0, 0, 
quads, nQuad);
+       decor_quads_to_property(data, 0, GDK_PIXMAP_XID(d.p_active),
+                               &extents, &extents, &extents, &extents, 0, 0, 
quads, nQuad, 0, 0, 0);
 
        XChangeProperty(xdisplay, xroot,
                        activeAtom,
@@ -2441,6 +2471,8 @@ update_default_decorations(GdkScreen * screen, 
frame_settings * fs_act,
                        32, PropModeReplace, (guchar *) data,
                        BASE_PROP_SIZE + QUAD_PROP_SIZE * nQuad);
     }
+
+    free(data);
 }
 
 static gboolean get_window_prop(Window xwindow, Atom atom, Window * val)
@@ -5025,6 +5057,144 @@ static int update_shadow(frame_settings * fs)
 
     return 1;
 }
+
+/*
+ * populate_type
+ *
+ * Returns: void
+ * Description: Sets the window type flags for compiz to know what window type
+ * this decoration is for
+ *
+ */
+static unsigned int
+populate_frame_type (decor_t *d)
+{
+    /* FIXME: This would be nicer if Wnck actually worked here,
+     * but for now we need to use that frame string since that's
+     * the only way we can get the modal_dialog type */
+
+    const unsigned int n_type_strings = 5;
+    unsigned int       frame_type = 0;
+    unsigned int i;
+    WnckWindow *win;
+
+    struct typestrings {
+        const char   *type;
+        unsigned int flag;
+    } type_strings[] =
+    {
+        {"normal", DECOR_WINDOW_TYPE_NORMAL },
+        {"dialog", DECOR_WINDOW_TYPE_DIALOG },
+        {"modal_dialog", DECOR_WINDOW_TYPE_MODAL_DIALOG },
+        {"menu", DECOR_WINDOW_TYPE_MENU },
+        {"utility", DECOR_WINDOW_TYPE_UTILITY}
+    };
+
+    win = wnck_window_get(d->prop_xid);
+
+    if (win) {
+      const gchar* t = get_frame_type(win);
+      for (i = 0; i < n_type_strings; i++)
+       {
+         if (strcmp (t, type_strings[i].type) == 0)
+            frame_type |= type_strings[i].flag;
+       }
+    }
+
+    return frame_type;
+}
+
+/*
+ * populate_state
+ *
+ * Returns void
+ * Description: Sets the window state flags for compiz to know what state of
+ * window this decoration is for
+ */
+static unsigned int
+populate_frame_state (decor_t *d)
+{
+    unsigned int frame_state = 0;
+
+    WnckWindowState win_state;
+    const unsigned int n_state_bits = 3;
+    unsigned int i;
+
+    if (d->active)
+        frame_state |= DECOR_WINDOW_STATE_FOCUS;
+
+    struct typestrings {
+        unsigned int wnck_flag;
+        unsigned int decor_flag;
+    } state_bits[] =
+    {
+        { WNCK_WINDOW_STATE_MAXIMIZED_VERTICALLY, 
DECOR_WINDOW_STATE_MAXIMIZED_VERT },
+        { WNCK_WINDOW_STATE_MAXIMIZED_HORIZONTALLY, 
DECOR_WINDOW_STATE_MAXIMIZED_HORZ },
+        { WNCK_WINDOW_STATE_SHADED, DECOR_WINDOW_STATE_SHADED }
+    };
+
+    /* Not possible to match further than active or not if there is
+     * no window but FIXME we might want to do that later down the line */
+
+    win_state = d->state;
+
+    for (i = 0; i < n_state_bits; i++)
+    {
+        if (win_state & state_bits[i].wnck_flag)
+            frame_state |= state_bits[i].decor_flag;
+    }
+
+    return frame_state;
+}
+
+/*
+ * populate_actions
+ *
+ * Returns void
+ * Description: Sets the window actions flags for compiz to know what state of
+ * window this decoration is for
+ */
+static unsigned int
+populate_frame_actions (decor_t *d)
+{
+    unsigned int frame_actions = 0;
+
+    WnckWindowActions win_actions = d->actions;
+    const unsigned int n_action_bits = 16;
+    unsigned int i;
+    struct typestrings {
+        unsigned int decor_flag;
+        unsigned int wnck_flag;
+    } action_bits[] =
+    {
+        { DECOR_WINDOW_ACTION_RESIZE_HORZ, WNCK_WINDOW_ACTION_RESIZE },
+        { DECOR_WINDOW_ACTION_RESIZE_VERT, WNCK_WINDOW_ACTION_RESIZE },
+        { DECOR_WINDOW_ACTION_CLOSE, WNCK_WINDOW_ACTION_CLOSE },
+        { DECOR_WINDOW_ACTION_MINIMIZE, WNCK_WINDOW_ACTION_MINIMIZE },
+        { DECOR_WINDOW_ACTION_UNMINIMIZE, WNCK_WINDOW_ACTION_UNMINIMIZE },
+        { DECOR_WINDOW_ACTION_MAXIMIZE_HORZ, 
WNCK_WINDOW_ACTION_MAXIMIZE_HORIZONTALLY },
+        { DECOR_WINDOW_ACTION_MAXIMIZE_VERT, 
WNCK_WINDOW_ACTION_MAXIMIZE_VERTICALLY },
+        { DECOR_WINDOW_ACTION_UNMAXIMIZE_HORZ, 
WNCK_WINDOW_ACTION_UNMAXIMIZE_HORIZONTALLY },
+        { DECOR_WINDOW_ACTION_UNMAXIMIZE_VERT, 
WNCK_WINDOW_ACTION_UNMAXIMIZE_VERTICALLY },
+        { DECOR_WINDOW_ACTION_SHADE, WNCK_WINDOW_ACTION_SHADE },
+        { DECOR_WINDOW_ACTION_UNSHADE, WNCK_WINDOW_ACTION_UNSHADE },
+        { DECOR_WINDOW_ACTION_STICK, WNCK_WINDOW_ACTION_STICK },
+        { DECOR_WINDOW_ACTION_UNSTICK, WNCK_WINDOW_ACTION_UNSTICK },
+        { DECOR_WINDOW_ACTION_FULLSCREEN, WNCK_WINDOW_ACTION_FULLSCREEN },
+        { DECOR_WINDOW_ACTION_ABOVE, WNCK_WINDOW_ACTION_ABOVE },
+        { DECOR_WINDOW_ACTION_BELOW, WNCK_WINDOW_ACTION_BELOW },
+    };
+
+    for (i = 0; i < n_action_bits; i++)
+    {
+        if (win_actions & action_bits[i].wnck_flag)
+            frame_actions |= action_bits[i].decor_flag;
+    }
+
+    return frame_actions;
+}
+
+
 static void titlebar_font_changed(window_settings * ws)
 {
     PangoFontMetrics *metrics;
@@ -5536,6 +5706,9 @@ int main(int argc, char *argv[])
        XInternAtom(xdisplay, "_COMPIZ_TOOLKIT_ACTION_FORCE_QUIT_DIALOG",
                    FALSE);
 
+    net_wm_state_atom = XInternAtom (xdisplay,"_NET_WM_STATE", 0);
+    net_wm_state_modal_atom = XInternAtom (xdisplay, "_NET_WM_STATE_MODAL", 0);
+
     emerald_sigusr1_atom = XInternAtom(xdisplay, "emerald-sigusr1", FALSE);
 
     utf8_string_atom = XInternAtom(xdisplay, "UTF8_STRING", FALSE);
@@ -5629,3 +5802,51 @@ int main(int argc, char *argv[])
 
     return 0;
 }
+
+static const gchar *
+get_frame_type (WnckWindow *win)
+{
+  WnckWindowType wnck_type = wnck_window_get_window_type (win);
+
+  switch (wnck_type)
+    {
+    case WNCK_WINDOW_NORMAL:
+      return "normal";
+    case WNCK_WINDOW_DIALOG:
+      {
+       Atom          actual;
+       int           result, format;
+       unsigned long n, left;
+       unsigned char *data;
+
+       result = XGetWindowProperty (gdk_x11_get_default_xdisplay (), 
wnck_window_get_xid (win),
+                                    net_wm_state_atom,
+                                    0L, 1024L, FALSE, XA_ATOM, &actual, 
&format,
+                                    &n, &left, &data);
+
+       if (result == Success && data)
+         {
+           Atom *a = (Atom *) data;
+
+           while (n--)
+             if (*a++ == net_wm_state_modal_atom)
+               {
+                 XFree ((void *) data);
+                 return "modal_dialog";
+               }
+
+
+         }
+
+       return "dialog";
+      }
+    case WNCK_WINDOW_MENU:
+      return "menu";
+    case WNCK_WINDOW_UTILITY:
+      return "utility";
+    default:
+      return "bare";
+    }
+
+  return "normal";
+}
_______________________________________________
dev mailing list
[email protected]
http://lists.compiz.org/mailman/listinfo/dev

Reply via email to