Skip to content
Snippets Groups Projects
mypixmap.c 28.2 KiB
Newer Older
        This program is free software; you can redistribute it and/or modify
        it under the terms of the GNU General Public License as published by
        the Free Software Foundation; either version 2, or (at your option)
        any later version.
        This program is distributed in the hope that it will be useful,
        but WITHOUT ANY WARRANTY; without even the implied warranty of
        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        GNU General Public License for more details.
        You should have received a copy of the GNU General Public License
        along with this program; if not, write to the Free Software
Olivier Fourdan's avatar
Olivier Fourdan committed
        Foundation, Inc., Inc., 51 Franklin Street, Fifth Floor, Boston,
        MA 02110-1301, USA.

Olivier Fourdan's avatar
Olivier Fourdan committed
        Original XPM load routines from gdk-pixbuf:
        Copyright (C) 1999 Mark Crichton
        Copyright (C) 1999 The Free Software Foundation
        Authors: Mark Crichton <crichton@gimp.org>
                 Federico Mena-Quintero <federico@gimp.org>
        A specific version of the gdk-pixbuf routines are required to support
Olivier Fourdan's avatar
Olivier Fourdan committed
        XPM color substitution used by the themes to apply gtk+ colors.
Olivier Fourdan's avatar
Olivier Fourdan committed
        xfwm4    - (c) 2002-2008 Olivier Fourdan
Olivier Fourdan's avatar
Olivier Fourdan committed
 */

#ifdef HAVE_CONFIG_H
Olivier Fourdan's avatar
Olivier Fourdan committed
#include "config.h"
Olivier Fourdan's avatar
Olivier Fourdan committed
#endif

#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <gdk/gdk.h>
#include <gdk/gdkx.h>
#include <libxfce4util/libxfce4util.h>
Olivier Fourdan's avatar
Olivier Fourdan committed
#include <stdlib.h>
#include <stdio.h>
{
    gchar *color_string;
    guint16 red;
    guint16 green;
    guint16 blue;
    gint transparent;
}
XPMColor;

{
    FILE *infile;
    gchar *buffer;
    guint buffer_size;
};

/* The following 2 routines (parse_color, find_color) come from Tk, via the Win32
 * port of GDK. The licensing terms on these (longer than the functions) is:
 *
 * This software is copyrighted by the Regents of the University of
 * California, Sun Microsystems, Inc., and other parties.  The following
 * terms apply to all files associated with the software unless explicitly
 * disclaimed in individual files.
 * The authors hereby grant permission to use, copy, modify, distribute,
 * and license this software and its documentation for any purpose, provided
 * that existing copyright notices are retained in all copies and that this
 * notice is included verbatim in any distributions. No written agreement,
 * license, or royalty fee is required for any of the authorized uses.
 * Modifications to this software may be copyrighted by their authors
 * and need not follow the licensing terms described here, provided that
 * the new terms are clearly indicated on the first page of each file where
 * they apply.
 * IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY
 * FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
 * ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY
 * DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 * THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.  THIS SOFTWARE
 * IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE
 * NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
 * MODIFICATIONS.
 * GOVERNMENT USE: If you are acquiring this software on behalf of the
 * U.S. government, the Government shall have only "Restricted Rights"
 * in the software and related documentation as defined in the Federal
 * Acquisition Regulations (FARs) in Clause 52.227.19 (c) (2).  If you
 * are acquiring the software on behalf of the Department of Defense, the
 * software shall be classified as "Commercial Computer Software" and the
 * Government shall have only "Restricted Rights" as defined in Clause
 * 252.227-7013 (c) (1) of DFARs.  Notwithstanding the foregoing, the
 * authors grant the U.S. Government and others acting in its behalf
 * permission to use and distribute the software in accordance with the
 * terms specified in this license.
 */
static int
compare_xcolor_entries (const void *a, const void *b)
{
    return g_ascii_strcasecmp ((const char *) a,
                               color_names + ((const XPMColorEntry *) b)->name_offset);
}

static gboolean
find_color(const char *name, XPMColor *colorPtr)
{
    XPMColorEntry *found;

    found = bsearch (name, xColors, G_N_ELEMENTS (xColors), sizeof (XPMColorEntry),
                     compare_xcolor_entries);
    if (found == NULL)
    {
        return FALSE;
    }

    colorPtr->red   = (found->red   * 0xFFFF) / 0xFF;
    colorPtr->green = (found->green * 0xFFFF) / 0xFF;
    colorPtr->blue  = (found->blue  * 0xFFFF) / 0xFF;

    return TRUE;
}

static gboolean
parse_color (const char *spec, XPMColor   *colorPtr)
{
        if ((i = strlen (spec + 1)) % 3)
        {
                return FALSE;
        }
        i /= 3;

        g_snprintf (fmt, 16, "%%%dx%%%dx%%%dx", i, i, i);

        if (sscanf (spec + 1, fmt, &red, &green, &blue) != 3)
        {
            return FALSE;
        }
            colorPtr->red   = (red   * 0xFFFF) / 0xF;
            colorPtr->green = (green * 0xFFFF) / 0xF;
            colorPtr->blue  = (blue  * 0xFFFF) / 0xF;
            colorPtr->red   = (red   * 0xFFFF) / 0xFF;
            colorPtr->green = (green * 0xFFFF) / 0xFF;
            colorPtr->blue  = (blue  * 0xFFFF) / 0xFF;
            colorPtr->red   = (red   * 0xFFFF) / 0xFFF;
            colorPtr->green = (green * 0xFFFF) / 0xFFF;
            colorPtr->blue  = (blue  * 0xFFFF) / 0xFFF;
    {
        if (!find_color(spec, colorPtr))
        {
            return FALSE;
        }
    }
    return TRUE;
}

static gint
xpm_seek_string (FILE *infile, const gchar *str)
{
    char instr[1024];

    {
        if (fscanf (infile, "%1023s", instr) < 0)
        {
                return FALSE;
        }
        if (strcmp (instr, str) == 0)
        {
                return TRUE;
        }
    }

    return FALSE;
}

static gint
xpm_seek_char (FILE *infile, gchar c)
{
    gint b, oldb;

    while ((b = getc (infile)) != EOF)
        else if (c == b)
        {
            return TRUE;
        }
    }

    return FALSE;
}

static gint
xpm_read_string (FILE *infile, gchar **buffer, guint *buffer_size)
{
    gint c;
Olivier Fourdan's avatar
Olivier Fourdan committed
    guint cnt = 0, bufsiz, ret;
Olivier Fourdan's avatar
Olivier Fourdan committed
    ret = FALSE;

    {
        bufsiz = 10 * sizeof (gchar);
        buf = g_new (gchar, bufsiz);
    }

    while ((c = getc (infile)) != EOF)
        {
            guint new_size = bufsiz * 2;

            if (new_size > bufsiz)
            {
                bufsiz = new_size;
            }
            else
            {
                goto out;
            }
            buf = g_realloc (buf, bufsiz);
            buf[bufsiz - 1] = '\0';
        }

        if (c != '"')
        {
            buf[cnt++] = c;
        }
        {
            buf[cnt] = 0;
            ret = TRUE;
            break;
        }
    }

out:
    buf[bufsiz - 1] = '\0';     /* ensure null termination for errors */
    *buffer = buf;
    *buffer_size = bufsiz;
    return ret;
}

static gchar *
search_color_symbol (gchar *symbol, xfwmColorSymbol *color_sym)
{
    xfwmColorSymbol *i;
    i = color_sym;
    while (i && i->name)
    {
        if (!g_ascii_strcasecmp (i->name, symbol))
        {
            return i->value;
        }
        ++i;
    }
    return NULL;
}

static gchar *
xpm_extract_color (const gchar *buffer, xfwmColorSymbol *color_sym)
{
Olivier Fourdan's avatar
Olivier Fourdan committed
    const gchar *p;
    gchar word[129], color[129], current_color[129];
Olivier Fourdan's avatar
Olivier Fourdan committed
    gint new_key;
    gint key;
    gint current_key;
    gint space;
Olivier Fourdan's avatar
Olivier Fourdan committed
    p = &buffer[0];
    space = 128;
    word[0] = '\0';
    color[0] = '\0';
    current_color[0] = '\0';
Olivier Fourdan's avatar
Olivier Fourdan committed
    current_key = 1;
    new_key = 0;
    key = 0;

        for (; *p != '\0' && g_ascii_isspace (*p); p++)
        for (r = word;
                 (*p != '\0') &&
                 (!g_ascii_isspace (*p)) &&
                 (r - word < sizeof (word) - 1);
             p++, r++)
        {
            if (color[0] == '\0')  /* incomplete colormap entry */
            {
Olivier Fourdan's avatar
Olivier Fourdan committed
                return NULL;
            }
            else  /* end of entry, still store the last color */
            {
                new_key = 1;
            }
        }
        else if (key > 0 && color[0] == '\0')  /* next word must be a color name part */
        {
                new_key = 0;
        {
            if (strcmp (word, "s") == 0)
            {
                new_key = 5;
            }
            else if (strcmp (word, "c") == 0)
            {
                new_key = 4;
            }
            else if (strcmp (word, "g") == 0)
            {
                new_key = 3;
            }
            else if (strcmp (word, "g4") == 0)
            {
                new_key = 2;
            }
            else if (strcmp (word, "m") == 0)
            {
                new_key = 1;
            }
        {  /* word is a color name part */
            if (key == 0)  /* key expected */
            {
                return NULL;
            }
            /* accumulate color name */
            {
                strncat (color, " ", space);
                space -= MIN (space, 1);
            }
            strncat (color, word, space);
            space -= MIN (space, strlen (word));
        }
        else if (key == 5)
        {
            gchar *new_color = NULL;
            new_color = search_color_symbol (color, color_sym);
            if (new_color)
            {
                current_key = key;
                strcpy (current_color, new_color);
            }
            space = 128;
            color[0] = '\0';
            key = new_key;
            {
                current_key = key;
                strcpy (current_color, color);
            }
            space = 128;
            color[0] = '\0';
            key = new_key;
    }
}

static const gchar *
file_buffer (enum buf_op op, gpointer handle)
{
Olivier Fourdan's avatar
Olivier Fourdan committed
    struct file_handle *h;
Olivier Fourdan's avatar
Olivier Fourdan committed
    h = handle;
    {
        case op_header:
            if (xpm_seek_string (h->infile, "XPM") != TRUE)
            {
                break;
            }
            if (xpm_seek_char (h->infile, '{') != TRUE)
            {
                break;
            }
            /* Fall through to the next xpm_seek_char. */

        case op_cmap:
            xpm_seek_char (h->infile, '"');
            fseek (h->infile, -1, SEEK_CUR);
            /* Fall through to the xpm_read_string. */

        case op_body:
            if(!xpm_read_string (h->infile, &h->buffer, &h->buffer_size))
            {
                return NULL;
            }
            return h->buffer;

        default:
            g_assert_not_reached ();
    }

    return NULL;
}

/* This function does all the work. */
static GdkPixbuf *
pixbuf_create_from_xpm (gpointer handle, xfwmColorSymbol *color_sym)
    gint w, h, n_col, cpp, items;
    gint cnt, xcnt, ycnt, wbytes, n;
    GHashTable *color_hash;
    XPMColor *colors, *color, *fallbackcolor;
    guchar *pixtmp;
    GdkPixbuf *pixbuf;

    fallbackcolor = NULL;

    buffer = file_buffer (op_header, handle);
        g_warning ("Cannot read Pixmap header");
    items = sscanf (buffer, "%d %d %d %d", &w, &h, &n_col, &cpp);
        g_warning ("Pixmap definition contains invalid number attributes (expecting at least 4, got %i)", items);
    if ((w <= 0) ||
        (h <= 0) ||
        (cpp <= 0) ||
        (cpp >= 32) ||
        (n_col <= 0) ||
        (n_col >= G_MAXINT / (cpp + 1)) ||
        (n_col >= G_MAXINT / sizeof (XPMColor)))
    {
        g_warning ("Pixmap definition contains invalid attributes");
        return NULL;
    }

    /* The hash is used for fast lookups of color from chars */
    color_hash = g_hash_table_new (g_str_hash, g_str_equal);

    name_buf = g_try_malloc (n_col * (cpp + 1));
    if (!name_buf) {
        g_hash_table_destroy (color_hash);
        g_warning ("Cannot allocate buffer");
        return NULL;
    }

    colors = (XPMColor *) g_try_malloc (sizeof (XPMColor) * n_col);
        g_hash_table_destroy (color_hash);
        g_free (name_buf);
        g_warning ("Cannot allocate colors for Pixmap");
    for (cnt = 0; cnt < n_col; cnt++)
        buffer = file_buffer (op_cmap, handle);
        {
            g_hash_table_destroy (color_hash);
            g_free (name_buf);
            g_free (colors);
            g_warning ("Cannot load colormap attributes");
            return NULL;
        }

        color = &colors[cnt];
        color->color_string = &name_buf[cnt * (cpp + 1)];
        strncpy (color->color_string, buffer, cpp);
        color->color_string[cpp] = 0;
        buffer += strlen (color->color_string);
        color->transparent = FALSE;

        color_name = xpm_extract_color (buffer, color_sym);

            (g_ascii_strcasecmp (color_name, "None") == 0) ||
            (parse_color (color_name, color) == FALSE))
        {
            color->transparent = TRUE;
            color->red = 0;
            color->green = 0;
            color->blue = 0;
        }

        g_free (color_name);
        g_hash_table_insert (color_hash, color->color_string, color);

        if (cnt == 0)
        {
            fallbackcolor = color;
        }
    }

    pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, w, h);
    {
        g_hash_table_destroy (color_hash);
        g_free (colors);
        g_free (name_buf);
        g_warning ("Cannot allocate Pixbuf");
    for (ycnt = 0; ycnt < h; ycnt++)
    {
        pixtmp = gdk_pixbuf_get_pixels (pixbuf) + ycnt * gdk_pixbuf_get_rowstride(pixbuf);

        buffer = file_buffer (op_body, handle);
        if ((!buffer) || (strlen (buffer) < wbytes))
        {
            continue;
        }

        for (n = 0, cnt = 0, xcnt = 0; n < wbytes; n += cpp, xcnt++)
        {
            strncpy (pixel_str, &buffer[n], cpp);
            pixel_str[cpp] = 0;

            color = g_hash_table_lookup (color_hash, pixel_str);

            /* Bad XPM...punt */
            if (!color)
            {
                color = fallbackcolor;
            }

            *pixtmp++ = color->blue  >> 8;
            {
                *pixtmp++ = 0xFF;
            }
        }
    }

    g_hash_table_destroy (color_hash);
    g_free (colors);
    g_free (name_buf);

    return pixbuf;
}


static GdkPixbuf *
xpm_image_load (const char *filename, xfwmColorSymbol *color_sym)
{
    guchar buffer[1024];
    GdkPixbuf *pixbuf;
    struct file_handle h;
    int size;
    FILE *f;

    f = g_fopen (filename, "rb");
    {
        return NULL;
    }

    size = fread (&buffer, 1, sizeof (buffer), f);
    {
        fclose (f);
        return NULL;
    }

    fseek (f, 0, SEEK_SET);
    memset (&h, 0, sizeof (h));
    h.infile = f;
    pixbuf = pixbuf_create_from_xpm (&h, color_sym);
Olivier Fourdan's avatar
Olivier Fourdan committed

static void
xfwmPixmapRefreshPict (xfwmPixmap * pm)
{
#ifdef HAVE_RENDER
Olivier Fourdan's avatar
Olivier Fourdan committed
    ScreenInfo * screen_info;
Olivier Fourdan's avatar
Olivier Fourdan committed

Olivier Fourdan's avatar
Olivier Fourdan committed
    screen_info = pm->screen_info;
    if (!pm->pict_format)
    {
        pm->pict_format = XRenderFindVisualFormat (myScreenGetXDisplay (screen_info),
                                                   screen_info->visual);
    }

    if (pm->pict != None)
    {
        XRenderFreePicture (myScreenGetXDisplay(pm->screen_info), pm->pict);
        pm->pict = None;
    }

    if ((pm->pixmap) && (pm->pict_format))
    {
        pm->pict = XRenderCreatePicture (myScreenGetXDisplay (screen_info),
Olivier Fourdan's avatar
Olivier Fourdan committed
                                         pm->pixmap, pm->pict_format, 0, NULL);
xfwmPixmapCompose (GdkPixbuf *pixbuf, gchar * dir, gchar * file)
Olivier Fourdan's avatar
Olivier Fourdan committed
    GdkPixbuf *alpha;
    gchar *filepng;
    gchar *filename;
    static const char* image_types[] = {
      "svg",
      "png",
      "gif",
      "jpg",
Olivier Fourdan's avatar
Olivier Fourdan committed
    alpha = NULL;
        filepng = g_strdup_printf ("%s.%s", file, image_types[i]);
        filename = g_build_filename (dir, filepng, NULL);
        g_free (filepng);
        if (g_file_test (filename, G_FILE_TEST_IS_REGULAR))
        {
            alpha = gdk_pixbuf_new_from_file (filename, NULL);
    if (!alpha)
    {
        /* We have no suitable image to layer on top of the XPM, stop here... */
        return (pixbuf);
    }

        /* We have no XPM canvas and found a suitable image, use it... */
        return (alpha);
    width  = MIN (gdk_pixbuf_get_width (pixbuf),
    height = MIN (gdk_pixbuf_get_height (pixbuf),
                  gdk_pixbuf_get_height (alpha));

    gdk_pixbuf_composite (alpha, pixbuf, 0, 0, width, height,
                          0, 0, 1.0, 1.0, GDK_INTERP_NEAREST, 0xFF);
}

static gboolean
xfwmPixmapDrawFromGdkPixbuf (xfwmPixmap * pm, GdkPixbuf *pixbuf)
{
    GdkPixmap *dest_pixmap;
    GdkPixmap *dest_bitmap;
    GdkVisual *gvisual;
    GdkColormap *cmap;
    gint width, height;
    gint dest_x, dest_y;

    g_return_val_if_fail (pm != NULL, FALSE);
    g_return_val_if_fail (pm->pixmap != None, FALSE);
    g_return_val_if_fail (pm->mask != None, FALSE);

    dest_pixmap = gdk_xid_table_lookup (pm->pixmap);
    if (dest_pixmap)
    {
        g_object_ref (G_OBJECT (dest_pixmap));
    }
    else
    {
        dest_pixmap = gdk_pixmap_foreign_new (pm->pixmap);
    }
    if (!dest_pixmap)
    {
        g_warning ("Cannot get pixmap");
        return FALSE;
    }

    dest_bitmap = gdk_xid_table_lookup (pm->mask);
    if (dest_bitmap)
    {
        g_object_ref (G_OBJECT (dest_bitmap));
    }
    else
    {
        dest_bitmap = gdk_pixmap_foreign_new (pm->mask);
    }
    if (!dest_bitmap)
    {
        g_warning ("Cannot get bitmap");
        g_object_unref (dest_pixmap);
        return FALSE;
    }

    gvisual = gdk_screen_get_system_visual (pm->screen_info->gscr);
    cmap = gdk_x11_colormap_foreign_new (gvisual, pm->screen_info->cmap);

    if (!cmap)
    {
        g_warning ("Cannot create colormap");
        g_object_unref (dest_pixmap);
        g_object_unref (dest_bitmap);
        return FALSE;
    }

    width = MIN (gdk_pixbuf_get_width (pixbuf), pm->width);
    height = MIN (gdk_pixbuf_get_height (pixbuf), pm->height);
    dest_x = (pm->width - width) / 2;
    dest_y = (pm->height - height) / 2;

    gdk_drawable_set_colormap (GDK_DRAWABLE (dest_pixmap), cmap);
    gdk_draw_pixbuf (GDK_DRAWABLE (dest_pixmap), NULL, pixbuf, 0, 0, dest_x, dest_y,
                     width, height, GDK_RGB_DITHER_NONE, 0, 0);

    gdk_pixbuf_render_threshold_alpha (pixbuf, dest_bitmap,
                                       0, 0, dest_x, dest_y,

    g_object_unref (cmap);
    g_object_unref (dest_pixmap);
    g_object_unref (dest_bitmap);

    return TRUE;
}

gboolean
xfwmPixmapRenderGdkPixbuf (xfwmPixmap * pm, GdkPixbuf *pixbuf)
{
    GdkPixbuf *src;
    GdkPixmap *destw;
    GdkVisual *gvisual;
    GdkColormap *cmap;
    gint width, height;
    gint dest_x, dest_y;

    g_return_val_if_fail (pm != NULL, FALSE);
    g_return_val_if_fail (pm->pixmap != None, FALSE);
    g_return_val_if_fail (pm->mask != None, FALSE);

    destw = gdk_xid_table_lookup (pm->pixmap);
    if (destw)
    {
        g_object_ref (G_OBJECT (destw));
    }
    else
    {
Olivier Fourdan's avatar
Olivier Fourdan committed
        destw = gdk_pixmap_foreign_new (pm->pixmap);
        g_warning ("Cannot get pixmap");
    gvisual = gdk_screen_get_system_visual (pm->screen_info->gscr);
    cmap = gdk_x11_colormap_foreign_new (gvisual, pm->screen_info->cmap);
        g_warning ("Cannot create colormap");
        g_object_unref (destw);
        return FALSE;
    width = MIN (gdk_pixbuf_get_width (pixbuf), pm->width);
    height = MIN (gdk_pixbuf_get_height (pixbuf), pm->height);

    /* Add 1 for rounding */
    dest_x = (pm->width - width + 1) / 2;
    dest_y = (pm->height - height + 1) / 2;
    src = gdk_pixbuf_get_from_drawable(NULL, GDK_DRAWABLE (destw), cmap,
                                        dest_x, dest_y, 0, 0, width, height);
    gdk_pixbuf_composite (pixbuf, src, 0, 0, width, height,
                          0, 0, 1.0, 1.0, GDK_INTERP_NEAREST, 0xFF);
    gdk_draw_pixbuf (GDK_DRAWABLE (destw), NULL, src, 0, 0, dest_x, dest_y,
                     width, height, GDK_RGB_DITHER_NONE, 0, 0);
    g_object_unref (src);
    g_object_unref (destw);

    return TRUE;
}

xfwmPixmapLoad (ScreenInfo * screen_info, xfwmPixmap * pm, gchar * dir, gchar * file, xfwmColorSymbol * cs)
Olivier Fourdan's avatar
Olivier Fourdan committed
{
Olivier Fourdan's avatar
Olivier Fourdan committed

    TRACE ("entering xfwmPixmapLoad");
    g_return_val_if_fail (pm != NULL, FALSE);
    g_return_val_if_fail (dir != NULL, FALSE);
    g_return_val_if_fail (file != NULL, FALSE);
Olivier Fourdan's avatar
Olivier Fourdan committed

    /*
     * Always try to load the XPM first, using our own routine
     * that supports XPM color symbol susbstitution (used to
Olivier Fourdan's avatar
Olivier Fourdan committed
     * apply the gtk+ colors to the pixmaps).
    filexpm = g_strdup_printf ("%s.%s", file, "xpm");
    filename = g_build_filename (dir, filexpm, NULL);
    g_free (filexpm);
    pixbuf = xpm_image_load (filename, cs);
Olivier Fourdan's avatar
Olivier Fourdan committed
    /* Compose with other image formats, if any available. */
    pixbuf = xfwmPixmapCompose (pixbuf, dir, file);
        /*
         * Cannot find a suitable image format for some part,
         * it's not critical though as most themes are missing
         * buttons
    xfwmPixmapCreate (screen_info, pm,
                      gdk_pixbuf_get_width (pixbuf),
                      gdk_pixbuf_get_height (pixbuf));
    xfwmPixmapDrawFromGdkPixbuf (pm, pixbuf);

    xfwmPixmapRefreshPict (pm);
Olivier Fourdan's avatar
Olivier Fourdan committed
    return TRUE;
}

xfwmPixmapCreate (ScreenInfo * screen_info, xfwmPixmap * pm,
Olivier Fourdan's avatar
Olivier Fourdan committed
                  gint width, gint height)
    TRACE ("entering xfwmPixmapCreate, width=%i, height=%i", width, height);
    g_return_if_fail (screen_info != NULL);

    if ((width < 1) || (height < 1))
        xfwmPixmapInit (screen_info, pm);
        pm->screen_info = screen_info;
        pm->pixmap = XCreatePixmap (myScreenGetXDisplay (screen_info),
                                    screen_info->xroot,
Olivier Fourdan's avatar
Olivier Fourdan committed
                                    width, height, screen_info->depth);
        pm->mask = XCreatePixmap (myScreenGetXDisplay (screen_info),
Olivier Fourdan's avatar
Olivier Fourdan committed
                                  pm->pixmap, width, height, 1);