diff --git a/GNUmakefile b/GNUmakefile index 2b53b91..01ec37b 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -35,6 +35,7 @@ E_LIBS = $(LIBS) -lMw L_OBJS = src/core.o src/default.o src/draw.o src/lowlevel.o src/font.o src/boldfont.o src/error.o L_OBJS += src/external/ds.o src/external/image.o L_OBJS += src/widget/window.o src/widget/button.o src/widget/frame.o src/widget/menu.o src/widget/submenu.o src/widget/image.o src/widget/scrollbar.o +L_OBJS += src/cursor/default.o ifeq ($(TARGET),NetBSD) CFLAGS += -I/usr/X11R7/include -I/usr/pkg/include @@ -66,7 +67,7 @@ endif ifeq ($(UNIX),1) L_CFLAGS += -DUSE_X11 L_OBJS += src/backend/x11.o -L_LIBS += -lm -lX11 -lXrender -lXext +L_LIBS += -lm -lX11 -lXrender -lXext -lXcursor GL = -lGL -lGLU diff --git a/doc/index.html b/doc/index.html index f403327..89060cb 100644 --- a/doc/index.html +++ b/doc/index.html @@ -92,6 +92,15 @@
MwForceRender
+
+ Mw/Cursor.h +
+
+ MwCursorDefault +
+
+ MwCursorDefaultMask +
Mw/Default.h
@@ -1033,6 +1042,27 @@
+

Mw/Cursor.h

+
+
+ Cursor externs. +
+
+
+
MWDECL MwCursor MwCursorDefault;
+
+
+ Default cursor. +
+
+
+
MWDECL MwCursor MwCursorDefaultMask;
+
+
+ Default cursor mask. +
+
+

Mw/Default.h

diff --git a/include/Mw/Cursor.h b/include/Mw/Cursor.h new file mode 100644 index 0000000..c7f9777 --- /dev/null +++ b/include/Mw/Cursor.h @@ -0,0 +1,31 @@ +/* $Id$ */ +/*! + * %file Mw/Cursor.h + * %brief Cursor externs + */ + +#ifndef __MW_CURSOR_H__ +#define __MW_CURSOR_H__ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/*! + * %brief Default cursor + */ +MWDECL MwCursor MwCursorDefault; + +/*! + * %brief Default cursor mask + */ +MWDECL MwCursor MwCursorDefaultMask; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/Mw/LowLevel.h b/include/Mw/LowLevel.h index db9db85..202482e 100644 --- a/include/Mw/LowLevel.h +++ b/include/Mw/LowLevel.h @@ -9,11 +9,11 @@ #include -typedef struct _MwLLHandler *MwLLHandler, MwLLHandlerRec; +typedef struct _MwLLHandler* MwLLHandler; #ifdef _MILSKO -typedef struct _MwLL * MwLL, MwLLRec; -typedef struct _MwLLColor * MwLLColor, MwLLColorRec; -typedef struct _MwLLPixmap *MwLLPixmap, MwLLPixmapRec; +typedef struct _MwLL* MwLL; +typedef struct _MwLLColor* MwLLColor; +typedef struct _MwLLPixmap* MwLLPixmap; #else typedef void* MwLL; typedef void* MwLLColor; @@ -76,6 +76,8 @@ MWDECL void MwLLSetIcon(MwLL handle, MwLLPixmap pixmap); MWDECL void MwLLForceRender(MwLL handle); +MWDECL void MwLLSetCursor(MwLL handle, MwCursor* image, MwCursor* mask); + #ifdef __cplusplus } #endif diff --git a/include/Mw/Milsko.h b/include/Mw/Milsko.h index 546e5e4..2a7eea6 100644 --- a/include/Mw/Milsko.h +++ b/include/Mw/Milsko.h @@ -15,6 +15,7 @@ #include #include #include +#include #include #include diff --git a/include/Mw/TypeDefs.h b/include/Mw/TypeDefs.h index e64fc45..de71a99 100644 --- a/include/Mw/TypeDefs.h +++ b/include/Mw/TypeDefs.h @@ -16,12 +16,12 @@ typedef struct _MwTextKeyValue MwTextKeyValue; typedef struct _MwUserHandlerKeyValue MwUserHandlerKeyValue; typedef struct _MwVoidKeyValue MwVoidKeyValue; typedef struct _MwFont MwFont; +typedef struct _MwMenu* MwMenu; +typedef struct _MwCursor MwCursor; #ifdef _MILSKO -typedef struct _MwWidget *MwWidget, MwWidgetRec; -typedef struct _MwMenu * MwMenu, MwMenuRec; +typedef struct _MwWidget* MwWidget; #else typedef void* MwWidget; -typedef void* MwMenu; #endif typedef void (*MwHandler)(MwWidget handle); typedef int (*MwHandler2)(MwWidget handle); @@ -88,6 +88,7 @@ struct _MwWidget { MwWidget* destroy_queue; }; +#endif struct _MwMenu { char* name; @@ -95,7 +96,15 @@ struct _MwMenu { MwWidget wsub; MwMenu* sub; }; -#endif + +#define MwCursorDataHeight 16 +struct _MwCursor { + int width; + int height; + int x; + int y; + unsigned int data[MwCursorDataHeight]; +}; struct _MwClass { MwHandler2 create; diff --git a/src/backend/gdi.c b/src/backend/gdi.c index 25a136e..3363d9a 100644 --- a/src/backend/gdi.c +++ b/src/backend/gdi.c @@ -319,3 +319,49 @@ void MwLLSetIcon(MwLL handle, MwLLPixmap pixmap) { void MwLLForceRender(MwLL handle) { InvalidateRect(handle->hWnd, NULL, FALSE); } + +void MwLLSetCursor(MwLL handle, MwCursor* image, MwCursor* mask) { + HCURSOR cursor; + BYTE* dmask = malloc((MwCursorDataHeight / 8) * MwCursorDataHeight); + BYTE* dimage = malloc((MwCursorDataHeight / 8) * MwCursorDataHeight); + int y, x; + + memset(dmask, 0xff, (MwCursorDataHeight / 8) * MwCursorDataHeight); + memset(dimage, 0, (MwCursorDataHeight / 8) * MwCursorDataHeight); + + for(y = 0; y < mask->height; y++) { + BYTE* l = &dmask[y * (MwCursorDataHeight / 8)]; + unsigned int n = mask->data[y]; + for(x = mask->width - 1; x >= 0; x--) { + l[x / 8] = l[x / 8] >> 1; + if(!(n & 1)) { + l[x / 8] |= 1 << 7; + } + + n = n >> 1; + } + } + + for(y = 0; y < image->height; y++) { + BYTE* l = &dimage[(y + (MwCursorDataHeight + mask->y)) * (MwCursorDataHeight / 8)]; + unsigned int n = image->data[y]; + + for(x = image->width - 1; x >= 0; x--) { + if(n & 1) { + l[(x - mask->x) / 8] |= (1 << (7 - ((x - mask->x) % 8))); + } + + n = n >> 1; + } + } + + cursor = CreateCursor(GetModuleHandle(NULL), -mask->x, MwCursorDataHeight + mask->y, MwCursorDataHeight, MwCursorDataHeight, dmask, dimage); + + SetClassLongPtr(handle->hWnd, GCLP_HCURSOR, (LONG_PTR)cursor); + SetCursor(cursor); + + DestroyCursor(cursor); + + free(dimage); + free(dmask); +} diff --git a/src/backend/x11.c b/src/backend/x11.c index a6f656e..0c2d782 100644 --- a/src/backend/x11.c +++ b/src/backend/x11.c @@ -334,3 +334,39 @@ void MwLLForceRender(MwLL handle) { ev.xexpose.window = handle->window; XSendEvent(handle->display, handle->window, False, ExposureMask, &ev); } + +void MwLLSetCursor(MwLL handle, MwCursor* image, MwCursor* mask) { + XcursorImage* img = XcursorImageCreate(MwCursorDataHeight, MwCursorDataHeight); + Cursor cur; + int y, x; + + img->xhot = -mask->x; + img->yhot = MwCursorDataHeight + mask->y; + + memset(img->pixels, 0, MwCursorDataHeight * MwCursorDataHeight * sizeof(XcursorPixel)); + for(y = 0; y < mask->height; y++) { + unsigned int l = mask->data[y]; + for(x = mask->width - 1; x >= 0; x--) { + if(l & 1) { + img->pixels[y * MwCursorDataHeight + x] = 0xff000000; + } + l = l >> 1; + } + } + for(y = 0; y < image->height; y++) { + unsigned int l = image->data[y]; + for(x = image->width - 1; x >= 0; x--) { + int px = 0; + if(l & 1) px = 255; + img->pixels[(img->yhot + y) * MwCursorDataHeight + (img->xhot + x)] |= (px << 16) | (px << 8) | (px); + + l = l >> 1; + } + } + + cur = XcursorImageLoadCursor(handle->display, img); + XDefineCursor(handle->display, handle->window, cur); + XFreeCursor(handle->display, cur); + + XcursorImageDestroy(img); +} diff --git a/src/backend/x11.h b/src/backend/x11.h index e693da2..d6eba6e 100644 --- a/src/backend/x11.h +++ b/src/backend/x11.h @@ -8,6 +8,7 @@ #include #include +#include #include #include diff --git a/src/core.c b/src/core.c index c16c954..6a0eb2d 100644 --- a/src/core.c +++ b/src/core.c @@ -299,6 +299,8 @@ void MwVaListApply(MwWidget handle, va_list va) { } void MwSetDefault(MwWidget handle) { + MwLLSetCursor(handle->lowlevel, &MwCursorDefault, &MwCursorDefaultMask); + MwSetText(handle, MwNbackground, MwDefaultBackground); MwSetText(handle, MwNforeground, MwDefaultForeground); } diff --git a/src/cursor/default.c b/src/cursor/default.c new file mode 100644 index 0000000..a32255e --- /dev/null +++ b/src/cursor/default.c @@ -0,0 +1,44 @@ +/* $Id$ */ +#include + +/** + * Created by bitmaptobdf + * + * Copyright notice: + * These ""glyphs"" are unencumbered + */ +MwCursor MwCursorDefault = { + 8, 14, 0, -14, {128, /* #....... */ + 192, /* ##...... */ + 224, /* ###..... */ + 240, /* ####.... */ + 248, /* #####... */ + 252, /* ######.. */ + 254, /* #######. */ + 255, /* ######## */ + 248, /* #####... */ + 216, /* ##.##... */ + 140, /* #...##.. */ + 12, /* ....##.. */ + 6, /* .....##. */ + 6, /* .....##. */ + 0, 0}}; +MwCursor MwCursorDefaultMask = { + 10, 16, -1, -15, { + 768, /* ##........ */ + 896, /* ###....... */ + 960, /* ####...... */ + 992, /* #####..... */ + 1008, /* ######.... */ + 1016, /* #######... */ + 1020, /* ########.. */ + 1022, /* #########. */ + 1023, /* ########## */ + 1023, /* ########## */ + 1016, /* #######... */ + 956, /* ###.####.. */ + 828, /* ##..####.. */ + 30, /* .....####. */ + 30, /* .....####. */ + 12 /* ......##.. */ + }}; diff --git a/src/widget/menu.c b/src/widget/menu.c index 8672810..40b24c3 100644 --- a/src/widget/menu.c +++ b/src/widget/menu.c @@ -106,9 +106,10 @@ static void draw(MwWidget handle) { MwDrawRect(handle, &r, base); BEGIN_MENU_LOOP; - (void)in_area; if(m->sub[i]->wsub != NULL) { MwDrawFrame(handle, &r, base, 0); + } else if(in_area && handle->pressed) { + MwDrawFrame(handle, &r, base, 0); } MwDrawText(handle, &p, m->sub[i]->name + incr, 1, text); diff --git a/tools/cursor.pl b/tools/cursor.pl new file mode 100755 index 0000000..a793a0b --- /dev/null +++ b/tools/cursor.pl @@ -0,0 +1,138 @@ +#!/usr/bin/env perl +# $Id$ +my $font = $ARGV[0]; +my $name = $ARGV[1]; +my $out = $ARGV[2]; +my $char = ""; +my $bmp = 0; + +my $w = 0; +my $h = 0; +my $ln = 0; +my $com = 0; +my $nocom = 0; + +my $MAX = 16; + +if ($name) { + print("/* \$Id\$ */\n"); + print("#include \n"); + print("\n"); +} + +open(IN, "<", $font) or die; +while (my $l = ) { + $l =~ s/\r?\n$//g; + if (!$name && ($l =~ /^STARTCHAR ("?)(.+)\1$/)) { + if (!($2 =~ /_mask$/)) { + print("$2\n"); + } + } + elsif ($name && ($l =~ /^COPYRIGHT ("?)(.+)\1$/)) { + if (!$com) { + print("/**\n"); + } + else { + print(" *\n"); + } + print(" * Copyright notice:\n"); + print(" * $2\n"); + if (!$com) { + print(" */\n"); + } + } + elsif ($name && ($l =~ /^COMMENT ("?)(.+)\1$/)) { + if (!$nocom) { + if (!$com) { + $com = 1; + print("/**\n"); + } + print(" * $2\n"); + } + } + elsif ($name && ($l =~ /^ENDPROPERTIES$/)) { + if ($com) { + print(" */\n"); + $com = 0; + $nocom = 1; + } + } + elsif ( + $name + && ( ($l =~ /^STARTCHAR ("?)\Q$name\E\1$/) + || ($l =~ /^STARTCHAR ("?)\Q${name}\E_(mask)\1$/)) + ) + { + my $suffix = ""; + if ($2) { + $suffix = "Mask"; + } + $char = $name; + print("MwCursor MwCursor$out$suffix = {\n"); + } + elsif ($name + && $char + && ($l =~ /^BBX (\-?[0-9]+) (\-?[0-9]+) (\-?[0-9]+) (\-?[0-9]+)$/)) + { + print(" $1, $2, $3, $4,\n"); + + $w = $1 + 0; + $h = $2 + 0; + } + elsif ($name && $char && ($l =~ /^BITMAP$/)) { + print(" {\n"); + $bmp = 1; + $ln = 0; + } + elsif ($name && $char && ($l =~ /^ENDCHAR$/)) { + $bmp = 0; + $char = ""; + for (my $i = 0 ; $i < ($MAX - $h) ; $i++) { + if ($i == ($MAX - $h - 1)) { + print(" 0\n"); + } + else { + print(" 0,\n"); + } + } + print(" }\n"); + print("};\n"); + } + elsif ($bmp) { + my $txt = ""; + + my $c = 0; + my $n = 0; + my $incr = 0; + + my $num = 0; + + while ($c < $w) { + if (($c % 8) == 0) { + $n = hex("0x" . substr($l, $incr, 2)); + $incr += 2; + } + + $num = $num << 1; + if ($n & (1 << 7)) { + $num = $num | 1; + $txt = $txt . "#"; + } + else { + $num = $num | 0; + $txt = $txt . "."; + } + + $n = $n << 1; + $c = $c + 1; + } + $ln = $ln + 1; + if ($ln == $MAX) { + print(" $num /* $txt */\n"); + } + else { + print(" $num, /* $txt */\n"); + } + } +} +close(IN);