home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC Shareware 1999 March
/
PCShareware-3-99.iso
/
IMPLE
/
DJGPP.RAR
/
DJGPP2
/
XLIB-SR0.ZIP
/
SRC
/
XLIBEMU
/
CURSOR.C
< prev
next >
Wrap
C/C++ Source or Header
|
1994-01-14
|
9KB
|
410 lines
/* $Id: cursor.c 1.2 1994/01/15 01:59:26 ulrich Exp $ */
/*
* cursor.c
*
* X library cursor functions.
*/
#include "Xlibemu.h"
#include <X11/cursorfont.h>
#include "cursor.h"
#include <grxfont.h>
#define CURSOR_TABLE_MAX 100
_WCursor cursor_table[CURSOR_TABLE_MAX] = { 0 };
static int cursor_table_max_used = 0;
GrCursor *
GrBuildCursorFromBits (char *bits, char *mask_bits, int width, int height, int x_hot, int y_hot,
int fg, int bg)
{
int x, y;
unsigned char mask;
char *data, *data_ptr;
int colors[3];
data_ptr = data = (char *) alloca (width * height);
for (y = 0; y < height; y++)
{
mask = 0x01;
for (x = 0; x < width; x++)
{
if (*(unsigned char *)bits & mask)
*data_ptr++ = 2;
else if (*(unsigned char *)mask_bits & mask)
*data_ptr++ = 1;
else
*data_ptr++ = 0;
if (mask == 0x80) {
bits++;
mask_bits++;
mask = 0x01;
}
else mask <<= 1;
}
if (mask != 0x01) {
bits++;
mask_bits++;
}
}
colors[0] = 2;
colors[1] = bg;
colors[2] = fg;
return GrBuildCursor (data, width, height, x_hot, y_hot, colors);
}
GrCursor *
GrBuildXCursor (int shape, int fg, int bg)
{
int width, height, x_hot, y_hot;
char *bits, *mask_bits;
switch (shape) {
#define CASE_XC(name) \
case XC_ ## name: \
width = name ## _width; \
height = name ## _height; \
x_hot = name ## _x_hot; \
y_hot = name ## _y_hot; \
bits = name ## _bits; \
mask_bits = name ## _mask_bits; \
break
CASE_XC(X_cursor);
CASE_XC(arrow);
CASE_XC(based_arrow_down);
CASE_XC(based_arrow_up);
CASE_XC(boat);
CASE_XC(bogosity);
CASE_XC(bottom_left_corner);
CASE_XC(bottom_right_corner);
CASE_XC(bottom_side);
CASE_XC(bottom_tee);
CASE_XC(box_spiral);
CASE_XC(center_ptr);
CASE_XC(circle);
CASE_XC(clock);
CASE_XC(coffee_mug);
CASE_XC(cross);
CASE_XC(cross_reverse);
CASE_XC(crosshair);
CASE_XC(diamond_cross);
CASE_XC(dot);
CASE_XC(dotbox);
CASE_XC(double_arrow);
CASE_XC(draft_large);
CASE_XC(draft_small);
CASE_XC(draped_box);
CASE_XC(exchange);
CASE_XC(fleur);
CASE_XC(gobbler);
CASE_XC(gumby);
CASE_XC(hand1);
CASE_XC(hand2);
CASE_XC(heart);
CASE_XC(icon);
CASE_XC(iron_cross);
CASE_XC(left_ptr);
CASE_XC(left_side);
CASE_XC(left_tee);
CASE_XC(leftbutton);
CASE_XC(ll_angle);
CASE_XC(lr_angle);
CASE_XC(man);
CASE_XC(middlebutton);
CASE_XC(mouse);
CASE_XC(pencil);
CASE_XC(pirate);
CASE_XC(plus);
CASE_XC(question_arrow);
CASE_XC(right_ptr);
CASE_XC(right_side);
CASE_XC(right_tee);
CASE_XC(rightbutton);
CASE_XC(rtl_logo);
CASE_XC(sailboat);
CASE_XC(sb_down_arrow);
CASE_XC(sb_h_double_arrow);
CASE_XC(sb_left_arrow);
CASE_XC(sb_right_arrow);
CASE_XC(sb_up_arrow);
CASE_XC(sb_v_double_arrow);
CASE_XC(shuttle);
CASE_XC(sizing);
CASE_XC(spider);
CASE_XC(spraycan);
CASE_XC(star);
CASE_XC(target);
CASE_XC(tcross);
CASE_XC(top_left_arrow);
CASE_XC(top_left_corner);
CASE_XC(top_right_corner);
CASE_XC(top_side);
CASE_XC(top_tee);
CASE_XC(trek);
CASE_XC(ul_angle);
CASE_XC(umbrella);
CASE_XC(ur_angle);
CASE_XC(watch);
CASE_XC(xterm);
#undef CASE_XC
default:
return (GrCursor *) 0;
}
return GrBuildCursorFromBits (bits, mask_bits, width, height, x_hot, y_hot, fg, bg);
}
Cursor
XCreateGlyphCursor
(Display* display,
Font source_font,
Font mask_font,
unsigned int source_char,
unsigned int mask_char,
XColor* foreground_color,
XColor* background_color)
{
char *src_bitmap;
char *msk_bitmap;
char *pixmap;
int src_width, src_height;
int msk_width, msk_height;
int width, height;
int chr;
int x, y;
XColor fgc, bgc;
Cursor cursor;
int colors[3];
if (source_font == None) {
_WError (display, (XID) source_font, BadFont, X_CreateGlyphCursor);
return None;
}
if (mask_font == None) {
mask_font = source_font;
}
if (source_char < source_font->fnt_minchar ||
source_char > source_font->fnt_maxchar) {
_WError (display, (XID) source_font, BadValue, X_CreateGlyphCursor);
return None;
}
if (mask_char < mask_font->fnt_minchar ||
mask_char > mask_font->fnt_maxchar) {
_WError (display, (XID) mask_font, BadValue, X_CreateGlyphCursor);
return None;
}
chr = source_char - source_font->fnt_minchar;
if (source_font->fnt_isfixed) {
src_bitmap = FFP(source_font)->ff_bits + (chr * FFP(source_font)->ff_chrsize);
src_width = source_font->fnt_width;
src_height = source_font->fnt_height;
}
else {
src_bitmap = PFP(source_font)->pf_bits[chr];
src_width = PFP(source_font)->pf_width[chr];
src_height = source_font->fnt_height;
}
chr = source_char - mask_font->fnt_minchar;
if (mask_font->fnt_isfixed) {
msk_bitmap = FFP(mask_font)->ff_bits + (chr * FFP(mask_font)->ff_chrsize);
msk_width = mask_font->fnt_width;
msk_height = mask_font->fnt_height;
}
else {
msk_bitmap = PFP(mask_font)->pf_bits[chr];
msk_width = PFP(mask_font)->pf_width[chr];
msk_height = mask_font->fnt_height;
}
width = src_width;
if (msk_width > width) width = msk_width;
height = src_height;
if (msk_height > height) height = msk_height;
fgc = *foreground_color;
bgc = *background_color;
fgc.pixel = WhitePixel (display, DefaultScreen (display));
bgc.pixel = BlackPixel (display, DefaultScreen (display));
XAllocColor (display, DefaultColormap(display, DefaultScreen (display)), &fgc);
XAllocColor (display, DefaultColormap(display, DefaultScreen (display)), &bgc);
#define getbit(p,w,x,y) ((p[y * ((w+7)/8) + (x/8)] & (0x80 >> (x%8))) ? 1 : 0)
pixmap = (char *) calloc (1, width * height);
for (y = 0; y < msk_height; y++)
for (x = 0; x < msk_width; x++) {
if (getbit (msk_bitmap, msk_width, x, y))
pixmap[y * width + x] = 1;
}
for (y = 0; y < src_height; y++)
for (x = 0; x < src_width; x++) {
if (getbit (src_bitmap, src_width, x, y))
pixmap[y * width + x] = 2;
}
#undef getbit
colors[0] = 2;
colors[1] = bgc.pixel;
colors[2] = fgc.pixel;
cursor = GrBuildCursor (pixmap, width, height,
source_font->fnt_undwidth,
source_font->fnt_baseline,
colors);
free (pixmap);
return cursor;
}
Cursor
XCreateFontCursor
(Display* display,
unsigned int shape)
{
int i, first_free;
if (shape > XC_num_glyphs)
return None;
/* first look if cursor alread loaded */
first_free = cursor_table_max_used;
for (i = 0; i < cursor_table_max_used; i++) {
if (cursor_table[i].cursor != NULL) {
if (cursor_table[i].shape == shape)
{
cursor_table[i].refcount++;
return cursor_table[i].cursor;
}
}
else {
if (i < first_free) first_free = i;
}
}
if (first_free >= CURSOR_TABLE_MAX)
return None;
cursor_table[first_free].shape = shape;
cursor_table[first_free].refcount = 1;
cursor_table[first_free].cursor =
GrBuildXCursor (shape,
BlackPixel(display, DefaultScreen (display)),
WhitePixel(display, DefaultScreen (display)));
return cursor_table[first_free].cursor;
}
Cursor XCreatePixmapCursor(
Display* display,
Pixmap source,
Pixmap mask,
XColor* foreground_color,
XColor* background_color,
unsigned int x,
unsigned int y)
{
return XCreateFontCursor (display, XC_X_cursor);
}
Status
XQueryBestCursor
(Display* display,
Drawable d,
unsigned int width,
unsigned int height,
unsigned int* width_return,
unsigned int* height_return)
{
*width_return = (width + 7) & ~7;
*height_return = (height + 7) & ~7;
return Success;
}
int
XFreeCursor
(Display* display,
Cursor cursor)
{
int i;
for (i = 0; i < cursor_table_max_used; i++) {
if (cursor_table[i].cursor == cursor &&
cursor_table[i].refcount > 0)
{
if (--cursor_table[i].refcount == 0) {
GrDestroyCursor (cursor_table[i].cursor);
cursor_table[i].cursor = NULL;
if (i == (cursor_table_max_used - 1))
--cursor_table_max_used;
}
return 1;
}
}
return 0;
}
int
XRecolorCursor
(Display* display,
Cursor cursor,
XColor* foreground_color,
XColor* background_color)
{
return 0;
}
#ifdef TEST
int
main()
{
int xc, x, y, dx, dy, yellow;
GrCursor *cr;
GrSetMode (GR_default_graphics);
GrClearScreen (GrAllocColor (84, 112, 170));
yellow = GrAllocColor (250, 250, 0);
dx = dy = 64;
x = dx;
y = dy;
for (xc = 0; xc < XC_num_glyphs; xc += 2)
{
cr = GrBuildXCursor (xc, GrBlack(), GrWhite());
GrLine (x-20, y, x+20, y, yellow);
GrLine (x, y-20, x, y+20, yellow);
GrMoveCursor (cr, x, y);
GrDisplayCursor (cr);
x += dx;
if (x >= GrScreenX() - dx)
y += dy, x = dx;
}
MouseEventMode (1);
for (xc = 0; xc < XC_num_glyphs; )
{
MouseEvent event;
MouseGetEvent (M_EVENT|M_KEYPRESS, &event);
if (event.flags & M_KEYPRESS) {
break;
}
if (event.flags & M_BUTTON_DOWN) {
cr = GrBuildXCursor (xc, GrBlack(), GrWhite());
MouseSetCursor (cr);
xc += 2;
}
}
GrSetMode (GR_default_text);
exit (0);
}
#endif