mirror of
https://github.com/yann64/haikuports.git
synced 2026-05-04 22:18:55 +02:00
* cleanup * count repaints and discard unneeded ones, reduces flicker * implement mouse suppose (selection doesn't work yet) * implement window resizing * fix cursor drawing (map XOR mode for rectangles to B_OP_INVERT) * Add 1 to the font descent value, now draws text like Pe.
1403 lines
38 KiB
Diff
1403 lines
38 KiB
Diff
Index: Makefile
|
|
===================================================================
|
|
RCS file: /sources/qemacs/qemacs/Makefile,v
|
|
retrieving revision 1.50
|
|
diff -u -r1.50 Makefile
|
|
--- Makefile 5 Jun 2008 07:14:12 -0000 1.50
|
|
+++ Makefile 14 Mar 2013 18:45:07 -0000
|
|
@@ -63,7 +63,7 @@
|
|
endif
|
|
|
|
ifdef CONFIG_DLL
|
|
- LIBS+=-ldl
|
|
+ LIBS+=$(DLLIBS)
|
|
# export some qemacs symbols
|
|
LDFLAGS+=-Wl,-E
|
|
endif
|
|
@@ -72,6 +72,11 @@
|
|
TARGETS+= qe-doc.html
|
|
endif
|
|
|
|
+ifdef CONFIG_HAIKU
|
|
+ OBJS+= haiku.o
|
|
+ LIBS+= -lbe
|
|
+endif
|
|
+
|
|
ifdef CONFIG_WIN32
|
|
OBJS+= unix.o
|
|
TOBJS+= unix.o
|
|
@@ -84,7 +89,7 @@
|
|
else
|
|
OBJS+= unix.o tty.o
|
|
TOBJS+= unix.o tty.o
|
|
- LIBS+= -lm
|
|
+ LIBS+= $(EXTRALIBS)
|
|
endif
|
|
|
|
ifdef CONFIG_QSCRIPT
|
|
@@ -226,6 +231,9 @@
|
|
$(OBJS_DIR)/%.o: %.c qe.h qestyles.h config.h config.mak Makefile
|
|
$(CC) $(DEFINES) $(CFLAGS) -o $@ -c $<
|
|
|
|
+$(OBJS_DIR)/haiku.o: haiku.cpp qe.h qestyles.h config.h config.mak Makefile
|
|
+ g++ $(DEFINES) $(CFLAGS) -Wno-multichar -o $@ -c $<
|
|
+
|
|
#
|
|
# Test for bidir algorithm
|
|
#
|
|
@@ -391,7 +399,8 @@
|
|
charsetjis.def charsetmore.c clang.c config.eg config.h \
|
|
configure cptoqe.c cutils.c cutils.h dired.c display.c \
|
|
display.h docbook.c extras.c fbffonts.c fbfrender.c \
|
|
- fbfrender.h fbftoqe.c hex.c html.c html2png.c htmlsrc.c \
|
|
+ fbfrender.h fbftoqe.c haiku.cpp hex.c html.c html2png.c \
|
|
+ htmlsrc.c \
|
|
image.c indic.c input.c jistoqe.c kmap.c kmaptoqe.c \
|
|
latex-mode.c libfbf.c libfbf.h ligtoqe.c list.c makemode.c \
|
|
mpeg.c perl.c qe-doc.html qe-doc.texi qe.1 qe.c qe.h qe.tcc \
|
|
Index: cfb.c
|
|
===================================================================
|
|
RCS file: /sources/qemacs/qemacs/cfb.c,v
|
|
retrieving revision 1.8
|
|
diff -u -r1.8 cfb.c
|
|
--- cfb.c 8 Apr 2008 06:55:44 -0000 1.8
|
|
+++ cfb.c 14 Mar 2013 18:45:07 -0000
|
|
@@ -50,7 +50,7 @@
|
|
static void cfb16_fill_rectangle(QEditScreen *s,
|
|
int x1, int y1, int w, int h, QEColor color)
|
|
{
|
|
- CFBContext *cfb = s->private;
|
|
+ CFBContext *cfb = s->priv_data;
|
|
unsigned char *dest, *d;
|
|
int y, n;
|
|
unsigned int col;
|
|
@@ -101,7 +101,7 @@
|
|
static void cfb32_fill_rectangle(QEditScreen *s,
|
|
int x1, int y1, int w, int h, QEColor color)
|
|
{
|
|
- CFBContext *cfb = s->private;
|
|
+ CFBContext *cfb = s->priv_data;
|
|
unsigned char *dest, *d;
|
|
int y, n;
|
|
unsigned int col;
|
|
@@ -145,7 +145,7 @@
|
|
int x1, int y1, int w, int h, QEColor color,
|
|
unsigned char *glyph, int glyph_wrap)
|
|
{
|
|
- CFBContext *cfb = s1->private;
|
|
+ CFBContext *cfb = s1->priv_data;
|
|
unsigned char *dest, *d, *s, *src;
|
|
int n;
|
|
unsigned int col;
|
|
@@ -189,7 +189,7 @@
|
|
int x1, int y1, int w, int h, QEColor color,
|
|
unsigned char *glyph, int glyph_wrap)
|
|
{
|
|
- CFBContext *cfb = s1->private;
|
|
+ CFBContext *cfb = s1->priv_data;
|
|
unsigned char *dest, *d, *s, *src;
|
|
int n;
|
|
unsigned int col;
|
|
@@ -233,7 +233,7 @@
|
|
int x_start, int y, const unsigned int *str, int len,
|
|
QEColor color)
|
|
{
|
|
- CFBContext *cfb = s->private;
|
|
+ CFBContext *cfb = s->priv_data;
|
|
GlyphCache *g;
|
|
unsigned char *glyph_ptr;
|
|
int i, x1, y1, x2, y2, wrap, x;
|
|
@@ -309,7 +309,7 @@
|
|
int cfb_init(QEditScreen *s,
|
|
void *base, int wrap, int depth, const char *font_path)
|
|
{
|
|
- CFBContext *cfb = s->private;
|
|
+ CFBContext *cfb = s->priv_data;
|
|
|
|
cfb->base = base;
|
|
cfb->wrap = wrap;
|
|
Index: configure
|
|
===================================================================
|
|
RCS file: /sources/qemacs/qemacs/configure,v
|
|
retrieving revision 1.15
|
|
diff -u -r1.15 configure
|
|
--- configure 17 Apr 2008 15:06:44 -0000 1.15
|
|
+++ configure 14 Mar 2013 18:45:07 -0000
|
|
@@ -45,9 +45,11 @@
|
|
ptsname="yes"
|
|
gprof="no"
|
|
network="yes"
|
|
+haiku="no"
|
|
win32="no"
|
|
cygwin="no"
|
|
lshared="no"
|
|
+dllibs="-ldl"
|
|
extralibs=""
|
|
simpleidct="yes"
|
|
bigendian="no"
|
|
@@ -79,10 +81,10 @@
|
|
# no need for libm, but the inet stuff
|
|
# Check for BONE
|
|
if (echo $BEINCLUDES|grep 'headers/be/bone' >/dev/null); then
|
|
- extralibs="-lbind -lsocket -lm"
|
|
+ extralibs="-lbind -lsocket"
|
|
else
|
|
echo "Not sure building for net_server will succeed... good luck."
|
|
- extralibs="-lsocket -lm"
|
|
+ extralibs="-lsocket"
|
|
fi
|
|
;;
|
|
BSD/OS)
|
|
@@ -102,6 +104,19 @@
|
|
CYGWIN*)
|
|
cygwin="yes"
|
|
;;
|
|
+ Haiku)
|
|
+ prefix="`finddir B_COMMON_DIRECTORY`"
|
|
+ # no need for libm, but the network stuff
|
|
+ extralibs="-lnetwork"
|
|
+ # dlopen() is in libroot already
|
|
+ dllibs=""
|
|
+ # use Haiku GUI; avoid building for X11 even if there are headers around
|
|
+ haiku="yes"
|
|
+ html="yes"
|
|
+ png="yes"
|
|
+ x11="no"
|
|
+ xv="no"
|
|
+ ;;
|
|
*)
|
|
extralibs="-lm"
|
|
unlockio="yes"
|
|
@@ -256,8 +271,11 @@
|
|
if test "$x11" = "no" ; then
|
|
xv="no"
|
|
xrender="no"
|
|
- png="no"
|
|
+fi
|
|
+
|
|
+if test "$x11" = "no" -a "$haiku" = "no" ; then
|
|
ffmpeg="no"
|
|
+ png="no"
|
|
html="no"
|
|
fi
|
|
|
|
@@ -439,6 +457,7 @@
|
|
echo "BUILD_SHARED=yes" >> config.mak
|
|
echo "PIC=-fPIC" >> config.mak
|
|
fi
|
|
+echo "DLLIBS=$dllibs" >> config.mak
|
|
echo "EXTRALIBS=$extralibs" >> config.mak
|
|
echo -n "VERSION=" >>config.mak
|
|
echo -n `head $source_path/VERSION` >> config.mak
|
|
@@ -451,6 +470,11 @@
|
|
echo "CONFIG_NETWORK=yes" >> config.mak
|
|
fi
|
|
|
|
+if test "$haiku" = "yes" ; then
|
|
+ echo "#define CONFIG_HAIKU 1" >> $TMPH
|
|
+ echo "CONFIG_HAIKU=yes" >> config.mak
|
|
+fi
|
|
+
|
|
if test "$win32" = "yes" ; then
|
|
echo "#define CONFIG_WIN32 1" >> $TMPH
|
|
echo "CONFIG_WIN32=yes" >> config.mak
|
|
Index: display.h
|
|
===================================================================
|
|
RCS file: /sources/qemacs/qemacs/display.h,v
|
|
retrieving revision 1.11
|
|
diff -u -r1.11 display.h
|
|
--- display.h 11 Jan 2008 11:29:28 -0000 1.11
|
|
+++ display.h 14 Mar 2013 18:45:07 -0000
|
|
@@ -53,7 +53,7 @@
|
|
int refcount;
|
|
int ascent;
|
|
int descent;
|
|
- void *private;
|
|
+ void *priv_data;
|
|
int system_font; /* TRUE if system font */
|
|
/* cache data */
|
|
int style;
|
|
@@ -153,7 +153,7 @@
|
|
/* clip region handling */
|
|
int clip_x1, clip_y1;
|
|
int clip_x2, clip_y2;
|
|
- void *private;
|
|
+ void *priv_data;
|
|
};
|
|
|
|
int qe_register_display(QEDisplay *dpy);
|
|
Index: fbfrender.c
|
|
===================================================================
|
|
RCS file: /sources/qemacs/qemacs/fbfrender.c,v
|
|
retrieving revision 1.10
|
|
diff -u -r1.10 fbfrender.c
|
|
--- fbfrender.c 8 Jan 2008 16:37:54 -0000 1.10
|
|
+++ fbfrender.c 14 Mar 2013 18:45:07 -0000
|
|
@@ -124,7 +124,7 @@
|
|
|
|
static GlyphCache *fbf_decode_glyph1(QEFont *font, int code)
|
|
{
|
|
- UniFontData *uf = font->private;
|
|
+ UniFontData *uf = font->priv_data;
|
|
int glyph_index, size, src_width, src_height;
|
|
GlyphCache *glyph_cache;
|
|
GlyphEntry *fbf_glyph_entry;
|
|
@@ -270,7 +270,7 @@
|
|
}
|
|
}
|
|
}
|
|
- font->private = uf_found;
|
|
+ font->priv_data = uf_found;
|
|
font->ascent = uf_found->ascent;
|
|
font->descent = uf_found->descent;
|
|
return font;
|
|
Index: html2png.c
|
|
===================================================================
|
|
RCS file: /sources/qemacs/qemacs/html2png.c,v
|
|
retrieving revision 1.12
|
|
diff -u -r1.12 html2png.c
|
|
--- html2png.c 11 Jan 2008 11:29:28 -0000 1.12
|
|
+++ html2png.c 14 Mar 2013 18:45:07 -0000
|
|
@@ -135,7 +135,7 @@
|
|
/* realloc ppm bitmap */
|
|
static int ppm_resize(QEditScreen *s, int w, int h)
|
|
{
|
|
- CFBContext *cfb = s->private;
|
|
+ CFBContext *cfb = s->priv_data;
|
|
|
|
/* alloc bitmap */
|
|
if (!qe_realloc(&cfb->base, w * h * sizeof(int))) {
|
|
@@ -160,7 +160,7 @@
|
|
if (!cfb)
|
|
return -1;
|
|
|
|
- s->private = cfb;
|
|
+ s->priv_data = cfb;
|
|
s->media = CSS_MEDIA_SCREEN;
|
|
|
|
if (cfb_init(s, NULL, w * sizeof(int), 32, ".") < 0)
|
|
@@ -169,7 +169,7 @@
|
|
if (ppm_resize(s, w, h) < 0) {
|
|
fail:
|
|
qe_free(&cfb->base);
|
|
- qe_free(&s->private);
|
|
+ qe_free(&s->priv_data);
|
|
return -1;
|
|
}
|
|
return 0;
|
|
@@ -177,15 +177,15 @@
|
|
|
|
static void ppm_close(QEditScreen *s)
|
|
{
|
|
- CFBContext *cfb = s->private;
|
|
+ CFBContext *cfb = s->priv_data;
|
|
|
|
qe_free(&cfb->base);
|
|
- qe_free(&s->private);
|
|
+ qe_free(&s->priv_data);
|
|
}
|
|
|
|
static int ppm_save(QEditScreen *s, const char *filename)
|
|
{
|
|
- CFBContext *cfb = s->private;
|
|
+ CFBContext *cfb = s->priv_data;
|
|
int w, h, x, y;
|
|
unsigned int r, g, b, v;
|
|
unsigned int *data;
|
|
@@ -219,7 +219,7 @@
|
|
|
|
static int png_save(QEditScreen *s, const char *filename)
|
|
{
|
|
- CFBContext *cfb = s->private;
|
|
+ CFBContext *cfb = s->priv_data;
|
|
struct png_save_data {
|
|
FILE *f;
|
|
png_structp png_ptr;
|
|
Index: qe.h
|
|
===================================================================
|
|
RCS file: /sources/qemacs/qemacs/qe.h,v
|
|
retrieving revision 1.96
|
|
diff -u -r1.96 qe.h
|
|
--- qe.h 4 May 2008 15:54:39 -0000 1.96
|
|
+++ qe.h 14 Mar 2013 18:45:11 -0000
|
|
@@ -267,11 +267,11 @@
|
|
int ustristart(const unsigned int *str, const char *val, const unsigned int **ptr);
|
|
static inline unsigned int *umemmove(unsigned int *dest,
|
|
unsigned int *src, int count) {
|
|
- return memmove(dest, src, count * sizeof(unsigned int));
|
|
+ return (unsigned int *)memmove(dest, src, count * sizeof(unsigned int));
|
|
}
|
|
static inline unsigned int *umemcpy(unsigned int *dest,
|
|
unsigned int *src, int count) {
|
|
- return memcpy(dest, src, count * sizeof(unsigned int));
|
|
+ return (unsigned int *)memcpy(dest, src, count * sizeof(unsigned int));
|
|
}
|
|
int umemcmp(const unsigned int *s1, const unsigned int *s2, int count);
|
|
|
|
Index: tty.c
|
|
===================================================================
|
|
RCS file: /sources/qemacs/qemacs/tty.c,v
|
|
retrieving revision 1.50
|
|
diff -u -r1.50 tty.c
|
|
--- tty.c 23 Apr 2008 15:30:33 -0000 1.50
|
|
+++ tty.c 14 Mar 2013 18:45:11 -0000
|
|
@@ -118,7 +118,7 @@
|
|
|
|
tty_screen = s;
|
|
ts = &tty_state;
|
|
- s->private = ts;
|
|
+ s->priv_data = ts;
|
|
s->media = CSS_MEDIA_TTY;
|
|
|
|
/* Derive some settings from the TERM environment variable */
|
|
@@ -263,7 +263,7 @@
|
|
static void tty_term_exit(void)
|
|
{
|
|
QEditScreen *s = tty_screen;
|
|
- TTYState *ts = s->private;
|
|
+ TTYState *ts = s->priv_data;
|
|
|
|
tcsetattr(fileno(s->STDIN), TCSANOW, &ts->oldtty);
|
|
}
|
|
@@ -271,7 +271,7 @@
|
|
static void tty_resize(__unused__ int sig)
|
|
{
|
|
QEditScreen *s = tty_screen;
|
|
- TTYState *ts = s->private;
|
|
+ TTYState *ts = s->priv_data;
|
|
struct winsize ws;
|
|
int i, count, size;
|
|
TTYChar tc;
|
|
@@ -318,7 +318,7 @@
|
|
static void tty_term_cursor_at(QEditScreen *s, int x1, int y1,
|
|
__unused__ int w, __unused__ int h)
|
|
{
|
|
- TTYState *ts = s->private;
|
|
+ TTYState *ts = s->priv_data;
|
|
ts->cursor_x = x1;
|
|
ts->cursor_y = y1;
|
|
}
|
|
@@ -380,7 +380,7 @@
|
|
{
|
|
QEditScreen *s = opaque;
|
|
QEmacsState *qs = &qe_state;
|
|
- TTYState *ts = s->private;
|
|
+ TTYState *ts = s->priv_data;
|
|
int ch;
|
|
QEEvent ev1, *ev = &ev1;
|
|
|
|
@@ -425,6 +425,7 @@
|
|
ts->input_param = 0;
|
|
} else if (ch == 'O') {
|
|
ts->input_state = IS_ESC2;
|
|
+ ts->input_param = 0;
|
|
} else {
|
|
ch = KEY_META(ch);
|
|
ts->input_state = IS_NORM;
|
|
@@ -826,7 +827,7 @@
|
|
static void tty_term_fill_rectangle(QEditScreen *s,
|
|
int x1, int y1, int w, int h, QEColor color)
|
|
{
|
|
- TTYState *ts = s->private;
|
|
+ TTYState *ts = s->priv_data;
|
|
int x2 = x1 + w;
|
|
int y2 = y1 + h;
|
|
int x, y;
|
|
@@ -869,7 +870,7 @@
|
|
|
|
font->ascent = 0;
|
|
font->descent = 1;
|
|
- font->private = NULL;
|
|
+ font->priv_data = NULL;
|
|
return font;
|
|
}
|
|
|
|
@@ -958,7 +959,7 @@
|
|
int x, int y, const unsigned int *str, int len,
|
|
QEColor color)
|
|
{
|
|
- TTYState *ts = s->private;
|
|
+ TTYState *ts = s->priv_data;
|
|
TTYChar *ptr;
|
|
int fgcolor, w, n;
|
|
unsigned int cc;
|
|
@@ -1021,7 +1022,7 @@
|
|
|
|
static void tty_term_flush(QEditScreen *s)
|
|
{
|
|
- TTYState *ts = s->private;
|
|
+ TTYState *ts = s->priv_data;
|
|
TTYChar *ptr, *ptr1, *ptr2, *ptr3, *ptr4, cc, blankcc;
|
|
int y, shadow, ch, bgcolor, fgcolor, shifted;
|
|
|
|
Index: win32.c
|
|
===================================================================
|
|
RCS file: /sources/qemacs/qemacs/win32.c,v
|
|
retrieving revision 1.15
|
|
diff -u -r1.15 win32.c
|
|
--- win32.c 23 Apr 2008 15:29:35 -0000 1.15
|
|
+++ win32.c 14 Mar 2013 18:45:11 -0000
|
|
@@ -139,7 +139,7 @@
|
|
if (!_hPrev)
|
|
init_application();
|
|
|
|
- s->private = NULL;
|
|
+ s->priv_data = NULL;
|
|
s->media = CSS_MEDIA_SCREEN;
|
|
|
|
win_ctx.font = CreateFont(-12, 0, 0, 0, 0 , 0, 0, 0, 0, 0, 0, 0,
|
|
@@ -452,7 +452,7 @@
|
|
GetTextMetrics(win_ctx.hdc, &tm);
|
|
font->ascent = tm.tmAscent;
|
|
font->descent = tm.tmDescent;
|
|
- font->private = NULL;
|
|
+ font->priv_data = NULL;
|
|
return font;
|
|
}
|
|
|
|
Index: x11.c
|
|
===================================================================
|
|
RCS file: /sources/qemacs/qemacs/x11.c,v
|
|
retrieving revision 1.28
|
|
diff -u -r1.28 x11.c
|
|
--- x11.c 15 Apr 2008 23:24:04 -0000 1.28
|
|
+++ x11.c 14 Mar 2013 18:45:12 -0000
|
|
@@ -194,7 +194,7 @@
|
|
QEStyleDef default_style;
|
|
XGCValues gc_val;
|
|
|
|
- s->private = NULL;
|
|
+ s->priv_data = NULL;
|
|
s->media = CSS_MEDIA_SCREEN;
|
|
|
|
if (!display_str)
|
|
@@ -564,13 +564,13 @@
|
|
}
|
|
font->ascent = renderFont->ascent;
|
|
font->descent = renderFont->descent;
|
|
- font->private = renderFont;
|
|
+ font->priv_data = renderFont;
|
|
return font;
|
|
}
|
|
|
|
static void term_close_font(QEditScreen *s, QEFont *font)
|
|
{
|
|
- XftFont *renderFont = font->private;
|
|
+ XftFont *renderFont = font->priv_data;
|
|
|
|
XftFontClose(display, renderFont);
|
|
/* Clear structure to force crash if font is still used after
|
|
@@ -582,7 +582,7 @@
|
|
|
|
static int term_glyph_width(QEditScreen *s, QEFont *font, unsigned int cc)
|
|
{
|
|
- XftFont *renderFont = font->private;
|
|
+ XftFont *renderFont = font->priv_data;
|
|
XGlyphInfo gi;
|
|
|
|
XftTextExtents32(display, renderFont, &cc, 1, &gi);
|
|
@@ -593,7 +593,7 @@
|
|
int x, int y, const unsigned int *str, int len,
|
|
QEColor color)
|
|
{
|
|
- XftFont *renderFont = font->private;
|
|
+ XftFont *renderFont = font->priv_data;
|
|
XftColor col;
|
|
int r, g, b, a;
|
|
|
|
@@ -764,7 +764,7 @@
|
|
|
|
font->ascent = xfont->ascent;
|
|
font->descent = xfont->descent;
|
|
- font->private = xfont;
|
|
+ font->priv_data = xfont;
|
|
return font;
|
|
fail:
|
|
XFreeFontNames(list);
|
|
@@ -774,7 +774,7 @@
|
|
|
|
static void term_close_font(__unused__ QEditScreen *s, QEFont *font)
|
|
{
|
|
- XFontStruct *xfont = font->private;
|
|
+ XFontStruct *xfont = font->priv_data;
|
|
|
|
XFreeFont(display, xfont);
|
|
/* Clear structure to force crash if font is still used after
|
|
@@ -788,7 +788,7 @@
|
|
associated. */
|
|
static XCharStruct *get_char_struct(QEFont *font, int cc)
|
|
{
|
|
- XFontStruct *xfont = font->private;
|
|
+ XFontStruct *xfont = font->priv_data;
|
|
int b1, b2;
|
|
XCharStruct *cs;
|
|
|
|
@@ -856,7 +856,7 @@
|
|
|
|
/* really no glyph : use default char in current font */
|
|
/* Should have half-width and full-width default char patterns */
|
|
- xfont = font->private;
|
|
+ xfont = font->priv_data;
|
|
cs = get_char_struct(font, xfont->default_char);
|
|
*out_font = lock_font(s, font);
|
|
return cs;
|
|
@@ -928,13 +928,13 @@
|
|
cs = handle_fallback(s, &font1, font, cc);
|
|
if (!cs) {
|
|
/* still no char: use default glyph */
|
|
- xfont = font->private;
|
|
+ xfont = font->priv_data;
|
|
cc = xfont->default_char;
|
|
}
|
|
}
|
|
/* flush previous chars if font change needed */
|
|
if (font1 != last_font && q > x11_str) {
|
|
- xfont = last_font->private;
|
|
+ xfont = last_font->priv_data;
|
|
l = q - x11_str;
|
|
XSetFont(display, gc, xfont->fid);
|
|
XDrawString16(display, dbuffer, gc, x_start, y, x11_str, l);
|
|
@@ -950,7 +950,7 @@
|
|
}
|
|
if (q > x11_str) {
|
|
/* flush remaining chars (more common case) */
|
|
- xfont = last_font->private;
|
|
+ xfont = last_font->priv_data;
|
|
l = q - x11_str;
|
|
XSetFont(display, gc, xfont->fid);
|
|
XDrawString16(display, dbuffer, gc, x_start, y, x11_str, l);
|
|
--- /dev/null 2013-03-14 16:10:28.351668000 +0100
|
|
+++ haiku.cpp 2013-03-14 19:43:57.698351616 +0100
|
|
@@ -0,0 +1,831 @@
|
|
+/*
|
|
+ * Haiku driver for QEmacs
|
|
+ * Copyright (c) 2013 François Revol.
|
|
+ * Copyright (c) 2002 Fabrice Bellard.
|
|
+ *
|
|
+ * This library is free software; you can redistribute it and/or
|
|
+ * modify it under the terms of the GNU Lesser General Public
|
|
+ * License as published by the Free Software Foundation; either
|
|
+ * version 2 of the License, or (at your option) any later version.
|
|
+ *
|
|
+ * This library 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
|
|
+ * Lesser General Public License for more details.
|
|
+ *
|
|
+ * You should have received a copy of the GNU Lesser General Public
|
|
+ * License along with this library; if not, write to the Free Software
|
|
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
+ */
|
|
+extern "C" {
|
|
+#include "qe.h"
|
|
+}
|
|
+
|
|
+#include <Application.h>
|
|
+#include <FindDirectory.h>
|
|
+#include <Font.h>
|
|
+#include <InterfaceDefs.h>
|
|
+#include <Path.h>
|
|
+#include <Region.h>
|
|
+#include <String.h>
|
|
+#include <View.h>
|
|
+#include <Window.h>
|
|
+
|
|
+extern QEDisplay haiku_dpy;
|
|
+
|
|
+static int force_tty = 0;
|
|
+
|
|
+static int font_xsize;
|
|
+
|
|
+class QEWindow;
|
|
+class QEView;
|
|
+
|
|
+/* state of a single window */
|
|
+typedef struct WindowState {
|
|
+ BWindow *w;
|
|
+ BView *v;
|
|
+ BFont font;
|
|
+ int events_rd;
|
|
+ int events_wr;
|
|
+} WindowState;
|
|
+
|
|
+WindowState haiku_ctx;
|
|
+static thread_id bapp_thid;
|
|
+static int bapp_ref_count = 0;
|
|
+static int events_wr;
|
|
+
|
|
+/* count of pending repaints */
|
|
+static vint32 repaints = 0;
|
|
+//TODO:use double-buffering with a BBitmap
|
|
+
|
|
+static void haiku_handle_event(void *opaque);
|
|
+
|
|
+static status_t bmessage_input(QEWindow *win, QEView *view, BMessage *message)
|
|
+{
|
|
+ if (!message)
|
|
+ return EINVAL;
|
|
+ /* push the message into the pipe */
|
|
+ if (write(events_wr, &message, sizeof(BMessage *)) < 0)
|
|
+ return errno;
|
|
+ return B_OK;
|
|
+}
|
|
+
|
|
+class QEWindow: public BWindow
|
|
+{
|
|
+public:
|
|
+ QEWindow(BRect frame, const char *name, QEView *view)
|
|
+ :BWindow(frame, name, B_TITLED_WINDOW, 0)
|
|
+ ,fView(view)
|
|
+ {}
|
|
+
|
|
+ virtual ~QEWindow() {}
|
|
+
|
|
+//virtual void Show();
|
|
+//virtual void Hide();
|
|
+//virtual void Minimize(bool minimize);
|
|
+virtual bool QuitRequested();
|
|
+virtual void DispatchMessage(BMessage *message, BHandler *handler);
|
|
+
|
|
+private:
|
|
+ QEView *fView;
|
|
+};
|
|
+
|
|
+class QEView: public BView
|
|
+{
|
|
+public:
|
|
+ QEView(BRect frame, const char *name);
|
|
+ virtual ~QEView();
|
|
+
|
|
+virtual void MouseDown(BPoint where);
|
|
+virtual void MouseUp(BPoint where);
|
|
+virtual void MouseMoved(BPoint where, uint32 code, const BMessage *a_message);
|
|
+virtual void KeyDown(const char *bytes, int32 numBytes);
|
|
+virtual void KeyUp(const char *bytes, int32 numBytes);
|
|
+virtual void Draw(BRect updateRect);
|
|
+virtual void FrameResized(float new_width, float new_height);
|
|
+#if 0
|
|
+virtual void WindowActivated(bool state);
|
|
+virtual void MessageReceived(BMessage *message);
|
|
+#endif
|
|
+};
|
|
+
|
|
+
|
|
+bool QEWindow::QuitRequested()
|
|
+{
|
|
+ BMessage *message = new BMessage(B_QUIT_REQUESTED);
|
|
+ bmessage_input(this, NULL, message);
|
|
+ return false;
|
|
+}
|
|
+
|
|
+void QEWindow::DispatchMessage(BMessage *message, BHandler *handler)
|
|
+{
|
|
+ uint32 mods;
|
|
+ switch (message->what) {
|
|
+ case B_MOUSE_WHEEL_CHANGED:
|
|
+ {
|
|
+ BMessage *message = DetachCurrentMessage();
|
|
+ bmessage_input(this, NULL, message);
|
|
+ }
|
|
+ break;
|
|
+ case B_KEY_DOWN:
|
|
+ if ((message->FindInt32("modifiers", (int32 *)&mods) == B_OK) &&
|
|
+ (mods & B_COMMAND_KEY)) {
|
|
+ /* BWindow swallows KEY_DOWN when ALT is down...
|
|
+ * so this hack is needed.
|
|
+ */
|
|
+ fView->KeyDown(NULL, 0);
|
|
+ return;
|
|
+ }
|
|
+ break;
|
|
+ case B_UNMAPPED_KEY_DOWN:
|
|
+ case B_UNMAPPED_KEY_UP:
|
|
+ case B_KEY_UP:
|
|
+ //message->PrintToStream();
|
|
+ break;
|
|
+ }
|
|
+ BWindow::DispatchMessage(message, handler);
|
|
+}
|
|
+
|
|
+QEView::QEView(BRect frame, const char *name)
|
|
+ :BView(frame, name, B_FOLLOW_ALL_SIDES, B_WILL_DRAW|B_FRAME_EVENTS)
|
|
+{
|
|
+ SetViewColor(ui_color(B_DOCUMENT_BACKGROUND_COLOR));
|
|
+ //SetViewColor(0, 255, 0);
|
|
+}
|
|
+
|
|
+QEView::~QEView()
|
|
+{
|
|
+}
|
|
+
|
|
+void QEView::MouseDown(BPoint where)
|
|
+{
|
|
+ BMessage *message = Window()->DetachCurrentMessage();
|
|
+ bmessage_input(NULL, this, message);
|
|
+}
|
|
+
|
|
+void QEView::MouseUp(BPoint where)
|
|
+{
|
|
+ BMessage *message = Window()->DetachCurrentMessage();
|
|
+ bmessage_input(NULL, this, message);
|
|
+}
|
|
+
|
|
+void QEView::MouseMoved(BPoint where, uint32 code, const BMessage *a_message)
|
|
+{
|
|
+ BMessage *message = Window()->DetachCurrentMessage();
|
|
+ bmessage_input(NULL, this, message);
|
|
+}
|
|
+
|
|
+void QEView::KeyDown(const char *bytes, int32 numBytes)
|
|
+{
|
|
+ BMessage *message = Window()->DetachCurrentMessage();
|
|
+ //message->PrintToStream();
|
|
+ bmessage_input(NULL, this, message);
|
|
+}
|
|
+
|
|
+void QEView::KeyUp(const char *bytes, int32 numBytes)
|
|
+{
|
|
+ uint32 mods;
|
|
+ BMessage *message = Window()->DetachCurrentMessage();
|
|
+ //message->PrintToStream();
|
|
+ bmessage_input(NULL, this, message);
|
|
+}
|
|
+
|
|
+void QEView::Draw(BRect updateRect)
|
|
+{
|
|
+ BMessage *message;
|
|
+ message = new BMessage(_UPDATE_);
|
|
+ message->AddRect("update_rect", updateRect);
|
|
+ atomic_add(&repaints, 1);
|
|
+ bmessage_input(NULL, this, message);
|
|
+}
|
|
+
|
|
+void QEView::FrameResized(float new_width, float new_height)
|
|
+{
|
|
+ BMessage *message = Window()->DetachCurrentMessage();
|
|
+ atomic_set(&repaints, 0);
|
|
+ bmessage_input(NULL, this, message);
|
|
+ BView::FrameResized(new_width, new_height);
|
|
+}
|
|
+
|
|
+
|
|
+static int haiku_probe(void)
|
|
+{
|
|
+ if (force_tty)
|
|
+ return 0;
|
|
+ return 2;
|
|
+}
|
|
+
|
|
+static int32 bapp_quit_thread(void *arg)
|
|
+{
|
|
+ be_app->Lock();
|
|
+ be_app->Quit();
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+
|
|
+static int32 bapp_thread(void *arg)
|
|
+{
|
|
+ be_app->Lock();
|
|
+ be_app->Run();
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+
|
|
+
|
|
+static void init_application(void)
|
|
+{
|
|
+ bapp_ref_count++;
|
|
+ if (be_app)
|
|
+ return; /* done already! */
|
|
+ new BApplication("application/x-vnd.Bellard-QEmacs");
|
|
+ //new XEmacsApp;
|
|
+ bapp_thid = spawn_thread(bapp_thread, "BApplication(QEmacs)", B_NORMAL_PRIORITY, (void *)find_thread(NULL));
|
|
+ if (bapp_thid < B_OK)
|
|
+ return; /* #### handle errors */
|
|
+ if (resume_thread(bapp_thid) < B_OK)
|
|
+ return;
|
|
+ // This way we ensure we don't create BWindows before be_app is created
|
|
+ // (creating it in the thread doesn't ensure this)
|
|
+ be_app->Unlock();
|
|
+}
|
|
+
|
|
+static void uninit_application(void)
|
|
+{
|
|
+ status_t err;
|
|
+ if (--bapp_ref_count)
|
|
+ return;
|
|
+ be_app->Lock();
|
|
+ be_app->Quit();
|
|
+ //XXX:HACK
|
|
+ be_app->Unlock();
|
|
+ //be_app_messenger.SendMessage(B_QUIT_REQUESTED);
|
|
+ wait_for_thread(bapp_thid, &err);
|
|
+ //FIXME:leak or crash
|
|
+ //delete be_app;
|
|
+ be_app = NULL;
|
|
+}
|
|
+
|
|
+static int haiku_init(QEditScreen *s, int w, int h)
|
|
+{
|
|
+ int xsize, ysize, font_ysize;
|
|
+ WindowState *ctx;
|
|
+
|
|
+ if (!be_app)
|
|
+ init_application();
|
|
+
|
|
+ memcpy(&s->dpy, &haiku_dpy, sizeof(QEDisplay));
|
|
+
|
|
+ ctx = (WindowState *)malloc(sizeof(WindowState));
|
|
+ if (ctx == NULL)
|
|
+ return -1;
|
|
+ s->priv_data = ctx;
|
|
+ s->media = CSS_MEDIA_SCREEN;
|
|
+
|
|
+ int event_pipe[2];
|
|
+ if (pipe(event_pipe) < 0)
|
|
+ return -1;
|
|
+ fcntl(event_pipe[0], F_SETFD, FD_CLOEXEC);
|
|
+ fcntl(event_pipe[1], F_SETFD, FD_CLOEXEC);
|
|
+
|
|
+ ctx->events_rd = event_pipe[0];
|
|
+ ctx->events_wr = events_wr = event_pipe[1];
|
|
+
|
|
+ set_read_handler(event_pipe[0], haiku_handle_event, s);
|
|
+
|
|
+
|
|
+ ctx->font = BFont(be_fixed_font);
|
|
+
|
|
+ font_height height;
|
|
+ ctx->font.GetHeight(&height);
|
|
+
|
|
+ font_xsize = (int)ctx->font.StringWidth("n");
|
|
+ font_ysize = (int)(height.ascent + height.descent + height.leading + 1);
|
|
+
|
|
+ if (w == 0)
|
|
+ w = 80;
|
|
+ if (h == 0)
|
|
+ h = 25;
|
|
+ xsize = w * font_xsize;
|
|
+ ysize = h * font_ysize;
|
|
+
|
|
+ s->width = xsize;
|
|
+ s->height = ysize;
|
|
+ s->charset = &charset_utf8;
|
|
+
|
|
+ s->clip_x1 = 0;
|
|
+ s->clip_y1 = 0;
|
|
+ s->clip_x2 = s->width;
|
|
+ s->clip_y2 = s->height;
|
|
+
|
|
+ BRect frame(0, 0, s->width - 1, s->height - 1);
|
|
+
|
|
+ QEView *v = new QEView(frame, "qemacs");
|
|
+ ctx->v = v;
|
|
+
|
|
+ frame.OffsetTo(200, 200);
|
|
+
|
|
+ ctx->w = new QEWindow(frame, "qemacs", v);
|
|
+ ctx->w->AddChild(ctx->v);
|
|
+ ctx->v->MakeFocus();
|
|
+ //ctx->v->SetViewColor(B_TRANSPARENT_COLOR);
|
|
+ ctx->v->SetDrawingMode(B_OP_OVER);
|
|
+
|
|
+ ctx->w->Show();
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static void haiku_close(QEditScreen *s)
|
|
+{
|
|
+ WindowState *ctx = (WindowState *)s->priv_data;
|
|
+ ctx->w->Lock();
|
|
+ ctx->w->Quit();
|
|
+ free(s->priv_data);
|
|
+}
|
|
+
|
|
+static void haiku_flush(QEditScreen *s)
|
|
+{
|
|
+ WindowState *ctx = (WindowState *)s->priv_data;
|
|
+ //fprintf(stderr, "%s()\n", __FUNCTION__);
|
|
+
|
|
+ ctx->v->LockLooper();
|
|
+
|
|
+ // doesn't really help
|
|
+ ctx->v->Sync();
|
|
+
|
|
+ ctx->v->UnlockLooper();
|
|
+}
|
|
+
|
|
+static int haiku_is_user_input_pending(QEditScreen *s)
|
|
+{
|
|
+ /* XXX: do it */
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+/* called when an BMessage is forwarded. dispatch events to qe_handle_event() */
|
|
+static void haiku_handle_event(void *opaque)
|
|
+{
|
|
+ QEditScreen *s = (QEditScreen *)opaque;
|
|
+ WindowState *ctx = (WindowState *)s->priv_data;
|
|
+ unsigned char buf[16];
|
|
+ bigtime_t timestamp_ms;
|
|
+ BMessage *event;
|
|
+ //fprintf(stderr, "%s()\n", __FUNCTION__);
|
|
+/*
|
|
+ KeySym keysym;
|
|
+*/
|
|
+ int shift, ctrl, meta, len, key = 0;
|
|
+ QEEvent ev1, *ev = &ev1;
|
|
+
|
|
+ if (read(ctx->events_rd, &event, sizeof(BMessage *)) < sizeof(BMessage *))
|
|
+ return;
|
|
+ //event->PrintToStream();
|
|
+
|
|
+ switch(event->what) {
|
|
+ case B_QUIT_REQUESTED:
|
|
+
|
|
+ // cancel pending operation
|
|
+ ev->key_event.type = QE_KEY_EVENT;
|
|
+ ev->key_event.key = KEY_CTRL('g');
|
|
+ qe_handle_event(ev);
|
|
+
|
|
+ // simulate C-x C-c
|
|
+ ev->key_event.type = QE_KEY_EVENT;
|
|
+ ev->key_event.key = KEY_CTRL('x');
|
|
+ qe_handle_event(ev);
|
|
+ ev->key_event.type = QE_KEY_EVENT;
|
|
+ ev->key_event.key = KEY_CTRL('c');
|
|
+ qe_handle_event(ev);
|
|
+ break;
|
|
+
|
|
+ case _UPDATE_:
|
|
+ // flush queued repaints
|
|
+ if (atomic_set(&repaints, 0)) {
|
|
+ ev->expose_event.type = QE_EXPOSE_EVENT;
|
|
+ qe_handle_event(ev);
|
|
+ }
|
|
+ break;
|
|
+
|
|
+ case B_VIEW_RESIZED:
|
|
+ {
|
|
+ int32 width, height;
|
|
+ int columns, rows;
|
|
+ //event->PrintToStream();
|
|
+/*
|
|
+ if (event->FindInt32("width", &width) < B_OK)
|
|
+ break;
|
|
+ if (event->FindInt32("height", &height) < B_OK)
|
|
+ break;
|
|
+*/
|
|
+
|
|
+ ctx->v->LockLooper();
|
|
+
|
|
+ width = ctx->v->Bounds().IntegerWidth() + 1;
|
|
+ height = ctx->v->Bounds().IntegerHeight() + 1;
|
|
+
|
|
+ if (width != s->width || height != s->height)
|
|
+ ctx->v->Invalidate(ctx->v->Bounds());
|
|
+
|
|
+ s->width = width;
|
|
+ s->height = height;
|
|
+
|
|
+ ctx->v->UnlockLooper();
|
|
+
|
|
+ //ev->expose_event.type = QE_EXPOSE_EVENT;
|
|
+ //qe_handle_event(ev);
|
|
+ }
|
|
+ break;
|
|
+
|
|
+ case B_MOUSE_MOVED:
|
|
+ {
|
|
+ BPoint pt;
|
|
+
|
|
+ ev->button_event.type = QE_MOTION_EVENT;
|
|
+ ev->button_event.x = (int)pt.x;
|
|
+ ev->button_event.y = (int)pt.y;
|
|
+ qe_handle_event(ev);
|
|
+ }
|
|
+ break;
|
|
+
|
|
+ case B_MOUSE_DOWN:
|
|
+ case B_MOUSE_UP:
|
|
+ {
|
|
+ BPoint pt;
|
|
+ uint32 buttons;
|
|
+
|
|
+ if (event->what == B_MOUSE_DOWN)
|
|
+ ev->button_event.type = QE_BUTTON_PRESS_EVENT;
|
|
+ else
|
|
+ ev->button_event.type = QE_BUTTON_RELEASE_EVENT;
|
|
+
|
|
+ if (event->FindPoint("where", &pt) < B_OK)
|
|
+ pt = BPoint(0,0);
|
|
+ ev->button_event.x = (int)pt.x;
|
|
+ ev->button_event.y = (int)pt.y;
|
|
+
|
|
+ if (event->FindInt32("buttons", (int32 *)&buttons) < B_OK)
|
|
+ buttons = (event->what == B_MOUSE_UP)?0:B_PRIMARY_MOUSE_BUTTON;
|
|
+
|
|
+
|
|
+ if (buttons & B_PRIMARY_MOUSE_BUTTON)
|
|
+ ev->button_event.button = QE_BUTTON_LEFT;
|
|
+ else if (buttons & B_SECONDARY_MOUSE_BUTTON)
|
|
+ ev->button_event.button = QE_BUTTON_MIDDLE;
|
|
+ else if (buttons & B_TERTIARY_MOUSE_BUTTON)
|
|
+ ev->button_event.button = QE_BUTTON_RIGHT;
|
|
+
|
|
+ qe_handle_event(ev);
|
|
+ }
|
|
+ break;
|
|
+
|
|
+ case B_MOUSE_WHEEL_CHANGED:
|
|
+ {
|
|
+ float delta;
|
|
+
|
|
+ ev->button_event.type = QE_BUTTON_PRESS_EVENT;
|
|
+
|
|
+ if (event->FindFloat("be:wheel_delta_y", &delta) < B_OK)
|
|
+ delta = 0.0;
|
|
+
|
|
+ if (delta > 0)
|
|
+ ev->button_event.button = QE_WHEEL_DOWN;
|
|
+ else if (delta < 0)
|
|
+ ev->button_event.button = QE_WHEEL_UP;
|
|
+ else
|
|
+ break;
|
|
+
|
|
+ qe_handle_event(ev);
|
|
+ }
|
|
+ break;
|
|
+
|
|
+ case B_KEY_UP:
|
|
+ break;
|
|
+
|
|
+ case B_KEY_DOWN:
|
|
+ {
|
|
+ unsigned int mods = 0;
|
|
+ uint32 state;
|
|
+ //event->PrintToStream();
|
|
+ uint32 scancode;
|
|
+ uint32 raw_char;
|
|
+ const char *bytes;
|
|
+ char buff[6];
|
|
+ int numbytes = 0;
|
|
+ int i;
|
|
+
|
|
+ if (event->FindInt64("when", ×tamp_ms) < B_OK)
|
|
+ timestamp_ms = 0LL;
|
|
+ if (event->FindInt32("modifiers", (int32 *)&state) < B_OK)
|
|
+ state = modifiers();
|
|
+ if (event->FindInt32("key", (int32 *)&scancode) < B_OK)
|
|
+ scancode = 0;
|
|
+ if (event->FindInt32("raw_char", (int32 *)&raw_char) < B_OK)
|
|
+ raw_char = 0;
|
|
+
|
|
+ /* check for byte[] first,
|
|
+ because C-space gives bytes="" (and byte[0] = '\0') */
|
|
+ for (i = 0; i < 5; i++) {
|
|
+ buff[i] = '\0';
|
|
+ if (event->FindInt8("byte", i, (int8 *)&buff[i]) < B_OK)
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ if (i) {
|
|
+ bytes = buff;
|
|
+ numbytes = i;
|
|
+ } else if (event->FindString("bytes", &bytes) < B_OK)
|
|
+ bytes = "";
|
|
+
|
|
+ if (!numbytes)
|
|
+ numbytes = strlen(bytes);
|
|
+
|
|
+ shift = (state & B_SHIFT_KEY);
|
|
+ ctrl = (state & B_CONTROL_KEY);
|
|
+ meta = (state & (B_LEFT_OPTION_KEY | B_COMMAND_KEY));
|
|
+
|
|
+ //fprintf(stderr, "%cshift %cctrl %cmeta numbytes %d \n", shift ? ' ' : '!', ctrl ? ' ' : '!', meta ? ' ' : '!', numbytes);
|
|
+
|
|
+ char byte = 0;
|
|
+ if (numbytes == 1) {
|
|
+ byte = bytes[0];
|
|
+ if (state & B_CONTROL_KEY)
|
|
+ byte = (char)raw_char;
|
|
+ switch (byte) {
|
|
+ case B_BACKSPACE:
|
|
+ key = KEY_BS;
|
|
+ if (meta)
|
|
+ key = KEY_META(KEY_BS);
|
|
+ break;
|
|
+ case B_TAB:
|
|
+ key = KEY_TAB;
|
|
+ break;
|
|
+ case B_ENTER:
|
|
+ key = KEY_RET;
|
|
+ break;
|
|
+ case B_ESCAPE:
|
|
+ key = KEY_ESC;
|
|
+ break;
|
|
+ case B_SPACE:
|
|
+ key = KEY_SPC;
|
|
+ break;
|
|
+ case B_DELETE:
|
|
+ key = KEY_DELETE;
|
|
+ break;
|
|
+ case B_INSERT:
|
|
+ key = KEY_INSERT;
|
|
+ break;
|
|
+ case B_HOME:
|
|
+ key = ctrl ? KEY_CTRL_HOME : KEY_HOME;
|
|
+ break;
|
|
+ case B_END:
|
|
+ key = ctrl ? KEY_CTRL_END : KEY_END;
|
|
+ break;
|
|
+ case B_PAGE_UP:
|
|
+ key = KEY_PAGEUP;
|
|
+ break;
|
|
+ case B_PAGE_DOWN:
|
|
+ key = KEY_PAGEDOWN;
|
|
+ break;
|
|
+ case B_LEFT_ARROW:
|
|
+ key = ctrl ? KEY_CTRL_LEFT : KEY_LEFT;
|
|
+ break;
|
|
+ case B_RIGHT_ARROW:
|
|
+ key = ctrl ? KEY_CTRL_RIGHT : KEY_RIGHT;
|
|
+ break;
|
|
+ case B_UP_ARROW:
|
|
+ key = KEY_UP;
|
|
+ break;
|
|
+ case B_DOWN_ARROW:
|
|
+ key = KEY_DOWN;
|
|
+ break;
|
|
+ case B_FUNCTION_KEY:
|
|
+ switch (scancode) {
|
|
+ case B_F1_KEY:
|
|
+ case B_F2_KEY:
|
|
+ case B_F3_KEY:
|
|
+ case B_F4_KEY:
|
|
+ case B_F5_KEY:
|
|
+ case B_F6_KEY:
|
|
+ case B_F7_KEY:
|
|
+ case B_F8_KEY:
|
|
+ case B_F9_KEY:
|
|
+ case B_F10_KEY:
|
|
+ case B_F11_KEY:
|
|
+ case B_F12_KEY:
|
|
+ key = KEY_F1 + scancode - B_F1_KEY;
|
|
+ break;
|
|
+ case B_PRINT_KEY:
|
|
+ case B_SCROLL_KEY:
|
|
+ case B_PAUSE_KEY:
|
|
+ default:
|
|
+ break;
|
|
+ }
|
|
+ break;
|
|
+ case 0:
|
|
+ break;
|
|
+ default:
|
|
+ if (byte >= ' ' && byte <= '~')
|
|
+ if (meta)
|
|
+ key = KEY_META(' ') + byte - ' ';
|
|
+ else if (ctrl)
|
|
+ key = KEY_CTRL(byte);
|
|
+ else
|
|
+ key = byte;
|
|
+
|
|
+ }
|
|
+ } else {
|
|
+ const char *p = bytes;
|
|
+ key = utf8_decode(&p);
|
|
+ }
|
|
+
|
|
+ got_key:
|
|
+ if (key) {
|
|
+ ev->key_event.type = QE_KEY_EVENT;
|
|
+ ev->key_event.key = key;
|
|
+ qe_handle_event(ev);
|
|
+ }
|
|
+ }
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ delete event;
|
|
+}
|
|
+
|
|
+static void haiku_fill_rectangle(QEditScreen *s,
|
|
+ int x1, int y1, int w, int h, QEColor color)
|
|
+{
|
|
+ WindowState *ctx = (WindowState *)s->priv_data;
|
|
+ //fprintf(stderr, "%s()\n", __FUNCTION__);
|
|
+ drawing_mode oldMode;
|
|
+
|
|
+ BRect r(x1, y1, x1 + w - 1, y1 + h - 1);
|
|
+ rgb_color c = {(color >> 16) & 0xff, (color >> 8) & 0xff, color & 0xff,
|
|
+ 0xff};
|
|
+
|
|
+ ctx->v->LockLooper();
|
|
+
|
|
+ oldMode = ctx->v->DrawingMode();
|
|
+
|
|
+ /* XXX: suppress XOR mode */
|
|
+ if (color == QECOLOR_XOR)
|
|
+ ctx->v->SetDrawingMode(B_OP_INVERT);
|
|
+ else
|
|
+ ctx->v->SetHighColor(c);
|
|
+ ctx->v->FillRect(r);
|
|
+
|
|
+ /* XXX: suppress XOR mode */
|
|
+ if (color == QECOLOR_XOR)
|
|
+ ctx->v->SetDrawingMode(oldMode);
|
|
+
|
|
+ ctx->v->UnlockLooper();
|
|
+}
|
|
+
|
|
+static QEFont *haiku_open_font(QEditScreen *s, int style, int size)
|
|
+{
|
|
+ WindowState *ctx = (WindowState *)s->priv_data;
|
|
+ //fprintf(stderr, "%s()\n", __FUNCTION__);
|
|
+ QEFont *font;
|
|
+
|
|
+ font = (QEFont *)malloc(sizeof(QEFont));
|
|
+ if (!font)
|
|
+ return NULL;
|
|
+
|
|
+ // TODO: use style / size
|
|
+ BFont *f = new BFont(ctx->font);
|
|
+
|
|
+ font_height height;
|
|
+ f->GetHeight(&height);
|
|
+ font->ascent = (int)height.ascent;
|
|
+ font->descent = (int)(height.descent + height.leading + 1);
|
|
+ font->priv_data = f;
|
|
+ return font;
|
|
+}
|
|
+
|
|
+static void haiku_close_font(QEditScreen *s, QEFont *font)
|
|
+{
|
|
+ BFont *f = (BFont *)font->priv_data;
|
|
+ delete f;
|
|
+ free(font);
|
|
+}
|
|
+
|
|
+static void haiku_text_metrics(QEditScreen *s, QEFont *font,
|
|
+ QECharMetrics *metrics,
|
|
+ const unsigned int *str, int len)
|
|
+{
|
|
+ //TODO: use BFont::GetEscapements() or StringWidth()
|
|
+ int i, x;
|
|
+ metrics->font_ascent = font->ascent;
|
|
+ metrics->font_descent = font->descent;
|
|
+ x = 0;
|
|
+ for(i=0;i<len;i++)
|
|
+ x += font_xsize;
|
|
+ metrics->width = x;
|
|
+}
|
|
+
|
|
+static void haiku_draw_text(QEditScreen *s, QEFont *font,
|
|
+ int x1, int y, const unsigned int *str, int len,
|
|
+ QEColor color)
|
|
+{
|
|
+ WindowState *ctx = (WindowState *)s->priv_data;
|
|
+ BFont *f = (BFont *)(font->priv_data);
|
|
+ int i;
|
|
+ //fprintf(stderr, "%s()\n", __FUNCTION__);
|
|
+
|
|
+ /* XXX: suppress XOR mode */
|
|
+ if (color == QECOLOR_XOR)
|
|
+ color = QERGB(0xff, 0xff, 0xff);
|
|
+
|
|
+ rgb_color c = {(color >> 16) & 0xff, (color >> 8) & 0xff, color & 0xff,
|
|
+ 0xff};
|
|
+
|
|
+ ctx->v->LockLooper();
|
|
+
|
|
+ ctx->v->SetHighColor(c);
|
|
+ ctx->v->SetLowColor(B_TRANSPARENT_COLOR);
|
|
+ ctx->v->SetFont(f);
|
|
+ ctx->v->MovePenTo(x1, y - 1);
|
|
+
|
|
+ char buf[10];
|
|
+ unsigned int cc;
|
|
+
|
|
+ BString text;
|
|
+ for(i=0;i<len;i++) {
|
|
+ cc = str[i];
|
|
+ unicode_to_charset(buf, cc, &charset_utf8);
|
|
+ text << buf;
|
|
+ //ctx->v->DrawString(buf);
|
|
+ }
|
|
+ ctx->v->DrawString(text.String());
|
|
+
|
|
+ ctx->v->UnlockLooper();
|
|
+
|
|
+ //TextOutW(haiku_ctx.hdc, x1, y - font->ascent, buf, len);
|
|
+}
|
|
+
|
|
+static void haiku_set_clip(QEditScreen *s,
|
|
+ int x, int y, int w, int h)
|
|
+{
|
|
+ WindowState *ctx = (WindowState *)s->priv_data;
|
|
+ //fprintf(stderr, "%s(,%d, %d, %d, %d)\n", __FUNCTION__, x, y, w, h);
|
|
+
|
|
+ BRegion clip(BRect(x, y, x + w - 1, y + h - 1));
|
|
+
|
|
+ ctx->v->LockLooper();
|
|
+
|
|
+ ctx->v->ConstrainClippingRegion(&clip);
|
|
+
|
|
+ ctx->v->UnlockLooper();
|
|
+}
|
|
+
|
|
+extern QEDisplay haiku_dpy = {
|
|
+ "haiku",
|
|
+ haiku_probe,
|
|
+ haiku_init,
|
|
+ haiku_close,
|
|
+ haiku_flush,
|
|
+ haiku_is_user_input_pending,
|
|
+ haiku_fill_rectangle,
|
|
+ haiku_open_font,
|
|
+ haiku_close_font,
|
|
+ haiku_text_metrics,
|
|
+ haiku_draw_text,
|
|
+ haiku_set_clip,
|
|
+ NULL, /* no selection handling */
|
|
+ NULL, /* no selection handling */
|
|
+ NULL, /* dpy_invalidate */
|
|
+ NULL, /* dpy_cursor_at */
|
|
+ NULL, /* dpy_bmp_alloc */
|
|
+ NULL, /* dpy_bmp_free */
|
|
+ NULL, /* dpy_bmp_draw */
|
|
+ NULL, /* dpy_bmp_lock */
|
|
+ NULL, /* dpy_bmp_unlock */
|
|
+ NULL, /* dpy_full_screen */
|
|
+ NULL, /* next */
|
|
+};
|
|
+
|
|
+static CmdOptionDef cmd_options[] = {
|
|
+ { "no-windows", "nw", NULL, CMD_OPT_BOOL, "force tty terminal usage",
|
|
+ { int_ptr: &force_tty }},
|
|
+ { NULL, NULL, NULL, 0, NULL, { NULL }}
|
|
+};
|
|
+
|
|
+static int haiku_init(void)
|
|
+{
|
|
+ QEmacsState *qs = &qe_state;
|
|
+
|
|
+ /* override default res path, to find config file at native location */
|
|
+ BPath path;
|
|
+ BString old(":");
|
|
+ old << qs->res_path;
|
|
+ qs->res_path[0] = '\0';
|
|
+ if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) == B_OK) {
|
|
+ path.Append("qemacs");
|
|
+ pstrcat(qs->res_path, sizeof(qs->res_path), path.Path());
|
|
+ }
|
|
+ pstrcat(qs->res_path, sizeof(qs->res_path), old.String());
|
|
+
|
|
+ qe_register_cmd_line_options(cmd_options);
|
|
+ return qe_register_display(&haiku_dpy);
|
|
+}
|
|
+
|
|
+qe_module_init(haiku_init);
|