Logo Search packages:      
Sourcecode: wallp version File versions  Download package

wallp_root.c

/* Copyright (C) 1999 Rafal Wierzbicki <rafal@mcss.mcmaster.ca>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

static char *cvsident = "$Id: wallp_root.c,v 1.14 1999/01/31 07:48:37 rafal Exp $";

#include "wallp.h"

#include "wallp.xpm"
#include "error.xpm"
#include <X11/extensions/shape.h>
#include <Imlib.h>

ImlibData *imdata = NULL;
int width, height, rgb_width, rgb_height;

typedef struct
{
    Window root;
    Window window;
    int rheight;
    int rwidth;
    int screen;
    Display *display;
    int depth;
    Window preview;
    int pheight;
    int pwidth;
}wallp_data;

wallp_data *wallp;

void
init_wallp(void)
{
    Screen *scr;

    wallp = malloc (sizeof(wallp_data));
    if (!wallp)
    {
        fprintf (stderr, "Error allocating %d of memory\n",
                 sizeof (wallp_data));
        exit (-1);
    }

    wallp->display = XOpenDisplay(NULL);
    if (!wallp->display)
    {
        fprintf (stderr, "Can't open display\nCheck your DISPLAY variable\n");
        exit (1);
    }
    dpy = wallp->display;
    wallp->screen = DefaultScreen (wallp->display);
    wallp->depth = DefaultDepth (wallp->display, wallp->screen);
    wallp->root = RootWindow(wallp->display, wallp->screen);
    scr = ScreenOfDisplay (wallp->display, wallp->screen);
    wallp->rwidth = scr->width;
    wallp->rheight = scr->height;
    imdata = Imlib_init(wallp->display);

    /*select_row (0);*/

    if (preview_area)
    {
        wallp->pwidth = 256;
        wallp->pheight = 192;
        wallp->preview = GDK_WINDOW_XWINDOW (preview_area->window);
    }

    if (icon_area)
    {
        wallp->window = GDK_WINDOW_XWINDOW (icon_area->window);
    }
}

void
wallp_logo (void)
{
    ImlibImage *image;
    Pixmap logo;

    image = Imlib_create_image_from_xpm_data (imdata, (char **)wallp_xpm);

    Imlib_render (imdata, image, image->rgb_width, image->rgb_height);
    logo = Imlib_move_image (imdata, image);

    XSetWindowBackgroundPixmap (wallp->display, wallp->preview, logo);
    XClearWindow (wallp->display, wallp->preview);
    XFlush (wallp->display);
    XFreePixmap (wallp->display, logo);
    Imlib_kill_image (imdata, image);
}

void wharf_logo (void)
{
    ImlibImage *image;
    Pixmap logo;

    image = Imlib_create_image_from_xpm_data (imdata, (char **)wallp_xpm);

    Imlib_render (imdata, image, 54              , 44               );
    logo = Imlib_move_image (imdata, image);

    XSetWindowBackgroundPixmap (wallp->display, wallp->window , logo);
    XClearWindow (wallp->display, wallp->window );
    XFlush (wallp->display);
    XFreePixmap (wallp->display, logo);
    Imlib_kill_image (imdata, image);
}
void
wallp_error (void)
{
    ImlibImage *image;
    Pixmap errpix;

    image = Imlib_create_image_from_xpm_data (imdata, (char **)error_xpm);
    Imlib_render (imdata, image, image->rgb_width, image->rgb_height);
    errpix = Imlib_move_image (imdata, image);

    XSetWindowBackgroundPixmap (wallp->display, wallp->preview, errpix);
    XClearWindow (wallp->display, wallp->preview);
    XFlush (wallp->display);
    XFreePixmap (wallp->display, errpix);
    Imlib_kill_image (imdata, image);
}

/* Most of this function based on code from Esetroot
 * by Nat Friedman <ndf@mit.edu> with modifications by Gerald Britton
 * <gbritton@mit.edu> and Michael Jennings <mej@tcserv.com>
 */

int
setprop (Pixmap pix)
{
    Atom root_prop, wallp_prop, type;
    unsigned long length, after;
    int format;
    unsigned char *data, *wallpdata;

    root_prop = XInternAtom (wallp->display, "_XROOTPMAP_ID", True);
    wallp_prop = XInternAtom (wallp->display, "WALLPMAP_ID", True);

    if (root_prop != None && wallp_prop != None)
    {
        XGetWindowProperty (wallp->display, wallp->root, root_prop, 0L, 1L,False,
                            AnyPropertyType,&type,&format,&length,&after,&data);
        if (type == XA_PIXMAP)
        {
            XGetWindowProperty (wallp->display, wallp->root, wallp_prop, 0L, 1L,
                                False,AnyPropertyType,&type,&format,&length,
                                &after, &wallpdata);
            if (data && wallpdata)
            {
                if (type == XA_PIXMAP && *((Pixmap *) data)
                            == *((Pixmap *)wallpdata))
                    XKillClient (wallp->display, *((Pixmap *)data));
            }
        }
    }
    root_prop = XInternAtom (wallp->display, "_XROOTPMAP_ID", False);
    wallp_prop = XInternAtom (wallp->display, "WALLPMAP_ID", False);
    if (root_prop != None && wallp_prop != None)
    {
        XChangeProperty (wallp->display, wallp->root, root_prop, XA_PIXMAP, 32,
                         PropModeReplace, (unsigned char *) &pix, 1);
        XChangeProperty (wallp->display, wallp->root, wallp_prop, XA_PIXMAP, 32,
                         PropModeReplace, (unsigned char *) &pix, 1);
        XSetCloseDownMode (wallp->display, RetainPermanent);
        XFlush (wallp->display);
        return True;
    }
    else
        return False;
}

void
center (ImlibImage *image, Pixmap *pix)
{
    Pixmap tmp;
    GC gc;
    XGCValues gcv;
    int x,y;


    x = width/2 - rgb_width/2;
    y = height/2 - rgb_height/2;

    Imlib_render (imdata, image, rgb_width, rgb_height);
    tmp = Imlib_move_image (imdata, image);

    if (!tmp)
        return;

    /*fprintf (stderr, "Centering a %d by %d image at %d %d in a %d by %d win\n",
      rgb_width, rgb_height, x, y, width, height);*/

    gcv.foreground = gcv.background = BlackPixel(wallp->display, wallp->screen);
    gc = XCreateGC(wallp->display, *pix, (GCForeground | GCBackground), &gcv);
    XFillRectangle (wallp->display, *pix, gc, 0, 0,
                    width, height);

    XSetTile (wallp->display, gc, tmp);
    XSetTSOrigin (wallp->display, gc, x, y);
    XSetFillStyle (wallp->display, gc, FillTiled);
    XFillRectangle (wallp->display, *pix, gc, x, y,
                    rgb_width, rgb_height);
    XFreeGC (wallp->display, gc);
    Imlib_free_pixmap (imdata, tmp);
    XFreePixmap (wallp->display, tmp);
    return;
}

void
aspect (ImlibImage *image, Pixmap *pix)
{
    Pixmap tmp;
    GC gc;
    XGCValues gcv;
    int x, y, w, h;
    float math;

    /* done by Cory Visi <visi@cmu.edu> */

    if (rgb_height > rgb_width)
    {
        h = height;
        math = (float)h * ((float)rgb_width /
                           (float)rgb_height);
        w = (int)math;
        if (w > width)
        {
            w = width;
            math = (float) w * ((float)rgb_height /
                                (float)rgb_width);
            h=(int)math;
        }
    }
    else
    {
        w = width;
        math = (float)w * ((float)rgb_height /
                           (float)rgb_width);
        h = (int)math;
        if (h > height)
        {
            h = height;
            math = (float)h * ((float)rgb_width /
                               (float)rgb_height);
            w = (int)math;
        }
    }

    x = width/2 - w/2;
    y = height/2 -  h/2;

    /*      fprintf (stderr, "stretching a %d by %d image, the resulting size: %d %d\n",
    rgb_width, rgb_height, w, h);*/

    Imlib_render (imdata, image, w, h);
    tmp = Imlib_move_image (imdata, image);

    if (!tmp)
        return;

    gc = XCreateGC (wallp->display, *pix, 0, &gcv);
    XFillRectangle (wallp->display, *pix, gc, 0, 0,
                    width, height);

    XSetTile (wallp->display, gc, tmp);
    XSetTSOrigin (wallp->display, gc, x, y);
    XSetFillStyle (wallp->display, gc, FillTiled);
    XFillRectangle (wallp->display, *pix, gc, x, y,
                    w, h);
    XFreeGC (wallp->display, gc);
    Imlib_free_pixmap (imdata, tmp);
    XFreePixmap (wallp->display, tmp);
    return;
}

void
scale (ImlibImage *image, Pixmap *pix)
{
    Pixmap tmp;
    GC gc;
    XGCValues gcv;

    Imlib_render (imdata, image, width, height);
    tmp = Imlib_move_image (imdata, image);
    if (!tmp)
        return;

    gc = XCreateGC (wallp->display, *pix, 0, &gcv);
    XFillRectangle (wallp->display, *pix, gc, 0, 0,
                    width, height);

    XSetTile (wallp->display, gc, tmp);
    XSetTSOrigin (wallp->display, gc, 0, 0);
    XSetFillStyle (wallp->display, gc, FillTiled);
    XFillRectangle (wallp->display, *pix, gc, 0, 0,
                    width, height);
    XFreeGC (wallp->display, gc);
    Imlib_free_pixmap (imdata, tmp);
    XFreePixmap (wallp->display, tmp);
    return;
}

void
tile (ImlibImage *image, Pixmap *pix)
{
    Pixmap tmp;
    GC gc;
    XGCValues gcv;

    Imlib_render (imdata, image, rgb_width, rgb_height);
    tmp = Imlib_move_image (imdata, image);
    if (!tmp)
        return;

    gc = XCreateGC (wallp->display, *pix, 0, &gcv);
    XFillRectangle (wallp->display, *pix, gc, 0, 0,
                    width, height);

    XSetTile (wallp->display, gc, tmp);
    XSetTSOrigin (wallp->display, gc, 0, 0);
    XSetFillStyle (wallp->display, gc, FillTiled);
    XFillRectangle (wallp->display, *pix, gc, 0, 0,
                    width, height);
    XFreeGC (wallp->display, gc);
    Imlib_free_pixmap (imdata, tmp);
    XFreePixmap (wallp->display, tmp);
    return;
}

int
put_image_on_root (char *path, int STYLE)
{
    ImlibImage *image;
    Pixmap xpixmap = None;

    if (PREVIEW_ONLY)
    {
        return (preview (path, STYLE));
    }

#ifdef VERBOSE
    fprintf (stderr, "Loading: %s\n", path);
#endif
    image = Imlib_load_image (imdata, path);


    if (!image)
    {
        wallp_error ();
        return (1);
    }

    width = wallp->rwidth;
    height = wallp->rheight;
    rgb_width = image->rgb_width;
    rgb_height = image->rgb_height;

    xpixmap = XCreatePixmap (wallp->display, wallp->root,
                             width, height, wallp->depth);

    switch (STYLE)
    {
    case CENTER:
        center (image, &xpixmap);
        break;
    case SCALE:
        scale (image, &xpixmap);
        break;
    case ASPECT:
        aspect (image, &xpixmap);
        break;
    case TILE:
        tile (image, &xpixmap);
        break;
    default:
        fprintf(stderr, "Danger Danger, unknown image style\n");
        exit(-1);
    }
    if (xpixmap != None)
    {
        XSetWindowBackgroundPixmap (wallp->display, wallp->root, xpixmap);
        if (!setprop (xpixmap))
            fprintf (stderr, "Set Root Pixmap property failed\n");
        XClearWindow (wallp->display, wallp->root);
        XFlush (wallp->display);
        XSync (wallp->display, False);
        XFreePixmap (wallp->display, xpixmap);
        Imlib_destroy_image(imdata, image);
        return 0;
    }
    return 1;
}

int
preview (char *path, int STYLE)
{
    ImlibImage *image;
    Pixmap prexmap=None;

    /*fprintf (stderr, "Preview loading: %s\n", path);*/
    image = Imlib_load_image (imdata, path);

    if (!image)
    {
        wallp_error ();
        return (1);
    }

    width = wallp->pwidth;
    height = wallp->pheight;

    rgb_width = image->rgb_width / 4;
    rgb_height = image->rgb_height / 4;

    prexmap = XCreatePixmap (wallp->display, wallp->root,
                             width, height, wallp->depth);
    switch (STYLE)
    {
    case CENTER:
        center (image, &prexmap);
        break;
    case SCALE:
        scale (image, &prexmap);
        break;
    case ASPECT:
        aspect (image, &prexmap);
        break;
    case TILE:
        tile (image, &prexmap);
        break;
    default:
        fprintf(stderr, "Danger Danger, unknown image style\n");
        exit(-1);
    }
    if (prexmap != None)
    {
        XSetWindowBackgroundPixmap (wallp->display, wallp->preview, prexmap);
        XClearWindow (wallp->display, wallp->preview);
        XFlush (wallp->display);
        XFreePixmap (wallp->display, prexmap);
        Imlib_kill_image (imdata, image);
        return 0;
    }
    return 1;
}

int icon (char *path)
{
    ImlibImage *image;
    Pixmap pixmap;

    image = Imlib_load_image (imdata, path);
    Imlib_render (imdata, image, 50, 44);
    pixmap = Imlib_move_image (imdata, image);
    if (pixmap != None)
    {
        XSetWindowBackgroundPixmap (wallp->display, wallp->window, pixmap);
        XClearWindow (wallp->display, wallp->window);
        XFlush (wallp->display);
        XFreePixmap (wallp->display, pixmap);
        Imlib_kill_image (imdata, image);
        return 0;
    }
    return 1;
}

Generated by  Doxygen 1.6.0   Back to index