Back to index

gcompris  8.2.2
cursor.c
Go to the documentation of this file.
00001 /* gcompris - cursor.c
00002  *
00003  * Copyright (C) 2002 Pascal Georges
00004  *
00005  *   This program is free software; you can redistribute it and/or modify
00006  *   it under the terms of the GNU General Public License as published by
00007  *   the Free Software Foundation; either version 2 of the License, or
00008  *   (at your option) any later version.
00009  *
00010  *   This program is distributed in the hope that it will be useful,
00011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  *   GNU General Public License for more details.
00014  *
00015  *   You should have received a copy of the GNU General Public License
00016  *   along with this program; if not, write to the Free Software
00017  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00018  */
00019 
00020 #include "gcompris.h"
00021 
00022 /* =====================================================================
00023  * This function is taken from stickers game
00024  * by Paul Kienzle and Tanya Riseman <stickers@kienzle.powernet.co.uk>
00025  * =====================================================================*/
00026 /* A routine that ought to be in the gdk library: build a cursor from
00027  * a text layout with '1' for foreground, '0' for background and ' '
00028  * for transparent.
00029  */
00030  /* If I got a function to generate mask, I could have used in gdk.h :
00031  GdkCursor* gdk_cursor_new_from_pixmap    (GdkPixmap   *source,
00032                       GdkPixmap   *mask,
00033                       GdkColor    *fg,
00034                       GdkColor    *bg,
00035                       gint         x,
00036                       gint         y);*/
00037 GdkCursor *gdk_cursor_new_from_data(const gchar *bits[],
00038                                 gint width, gint height,
00039                                 GdkColor *fg, GdkColor *bg,
00040                                 gint hot_x, gint hot_y)
00041 {
00042   GdkBitmap *bitmap, *mask;
00043   GdkCursor *cursor;
00044   guchar *data, *ptr;
00045   gint i, j;
00046 
00047   /* Though it does not say so on the X11 manual pages, the bitmap
00048    * format consists of scan lines padded to byte boundaries with the
00049    * bits in "reverse" order within each byte (lo bits come before hi
00050    * bits in the bitmap).  I assume this representation is platform
00051    * independent.  Let me know if it doesn't work for you. */
00052 
00053   /* Create space for the bitmap, padding the scanlines to byte boundaries. */
00054   data = g_new(guchar, ((width+7)/8)*height);
00055 
00056   /* Build bitmap */
00057   ptr = data;
00058   for (i=0; i < height; i++) {
00059     for (j=0; j < width; j++) {
00060       *ptr = (*ptr >> 1)|(bits[i][j]=='1'?0x80:0);
00061       if (j%8 == 7) ptr++;
00062     }
00063     if (j%8) *ptr++ >>= 8-j%8;
00064   }
00065   bitmap = gdk_bitmap_create_from_data(NULL, (gchar *)data, width, height);
00066 
00067   /* Build mask */
00068   ptr = data;
00069   for (i=0; i < height; i++) {
00070     for (j=0; j < width; j++) {
00071       *ptr = (*ptr >> 1)|(bits[i][j]==' '?0:0x80);
00072       if (j%8 == 7) ptr++;
00073     }
00074     if (j%8) *ptr++ >>= 8-j%8;
00075   }
00076   mask = gdk_bitmap_create_from_data(NULL, (gchar *)data, width, height);
00077 
00078   /* Build cursor from bitmap and mask */
00079   cursor = gdk_cursor_new_from_pixmap(bitmap, mask, /* Image and mask */
00080                                   fg, bg, /* colors */
00081                                   hot_x, hot_y); /* Hot point */
00082 
00083   /* No longer need bitmap or mask */
00084   gdk_pixmap_unref(bitmap);
00085   gdk_pixmap_unref(mask);
00086   g_free(data);
00087 
00088   return cursor;
00089 }