From b9477d243c8299b177b13a7d95e06d664111a633 Mon Sep 17 00:00:00 2001
From: Gerasim Troeglazov <3deyes@gmail.com>
Date: Fri, 27 Mar 2015 13:07:06 +0300
Subject: Implement Haiku support


diff --git a/disk.c b/disk.c
index 07e12f3..a1191d1 100644
--- a/disk.c
+++ b/disk.c
@@ -32,7 +32,7 @@
 #include <utime.h>
 #include <time.h>		/* ctime */
 
-#if (defined(HAVE_DIRFD) || (HAVE_DECL_DIRFD == 1))
+#if (defined(HAVE_DIRFD) || (HAVE_DECL_DIRFD == 1)) || defined(__HAIKU__)
 #define DIRFD(a) (dirfd(a))
 #else
 #define DIRFD(a) ((a)->DIR_FD_MEMBER_NAME)
diff --git a/haiku/clip_haiku.cpp b/haiku/clip_haiku.cpp
new file mode 100644
index 0000000..a8dd0f9
--- /dev/null
+++ b/haiku/clip_haiku.cpp
@@ -0,0 +1,197 @@
+#include <Clipboard.h>
+#include <Window.h>
+#include <Message.h>
+#include <UTF8.h>
+#include "window_haiku.h"
+
+extern "C"
+{
+#include "../rdesktop.h"
+
+extern TWin	*BeWindow;
+
+#define NUM_TARGETS 6
+
+#ifdef USE_UNICODE_CLIPBOARD
+#define RDP_CF_TEXT CF_UNICODETEXT
+#else
+#define RDP_CF_TEXT CF_TEXT
+#endif
+
+static int have_primary = 0;
+static int rdesktop_is_selection_owner = 0;
+
+
+BClipboard *Clip;
+
+
+/* Replace CR-LF to LF (well, rather removing all CR:s) This is done
+   in-place. The length is updated. Handles embedded nulls */
+static void
+crlf2lf(uint8 * data, uint32 * length)
+{
+	uint8 *dst, *src;
+	src = dst = data;
+	while (src < data + *length)
+	{
+		if (*src != '\x0d')
+			*dst++ = *src;
+		src++;
+	}
+	*length = dst - data;
+}
+
+/* Translate LF to CR-LF. To do this, we must allocate more memory.  
+   The length is updated. */
+static uint8 *
+lf2crlf(uint8 * data, uint32 * length)
+{
+	uint8 *result, *p, *o;
+
+	/* Worst case: Every char is LF */
+	result = (uint8*)xmalloc(*length * 2);
+
+	p = data;
+	o = result;
+
+	while (p < data + *length)
+	{
+		if (*p == '\x0a')
+			*o++ = '\x0d';
+		*o++ = *p++;
+	}
+	*length = o - result;
+
+	/* Convenience */
+	*o++ = '\0';
+
+	return result;
+}
+
+void
+ui_clip_format_announce(uint8 * data, uint32 length)
+{
+  	
+  if(BeWindow!=NULL)
+   {
+    BeWindow->PostMessage('SCCH');
+   }
+}
+
+
+void
+ui_clip_handle_data(uint8 * data, uint32 length)
+{
+	  const char *text;
+	  int32 textLen;
+	  BMessage *clip = (BMessage *)NULL;
+	  
+	  
+	  
+	  if(be_clipboard->Lock())
+	   {
+	    be_clipboard->Clear();
+	    if(clip=be_clipboard->Data())
+	     {
+			if(length>0)
+			 {
+				char *ToUtf8=(char*)xmalloc((length*4)+4);
+				if(ToUtf8!=NULL)
+				 {
+					uint32 len=length;
+					crlf2lf(data,&len);
+					
+					int32 DestLen=len*4;
+					int32 State=0;
+		     		int32 SourceLen=len;
+			  		convert_to_utf8(B_MS_WINDOWS_1251_CONVERSION, (const char*)data, &SourceLen, ToUtf8, &DestLen, &State);
+			  		ToUtf8[DestLen]=0;
+					
+					//printf("ui_clip_handle_data: len=%d str=%s\n",DestLen, ToUtf8);
+					clip->AddData("text/plain", B_MIME_TYPE,ToUtf8,DestLen);				
+					
+	      			xfree(ToUtf8);
+			      	be_clipboard->Commit();
+   		    	 }
+   		     }
+	     }
+   		be_clipboard->Unlock();
+	   }	 
+}
+
+void
+ui_clip_request_failed()
+{
+	
+}
+
+void
+ui_clip_set_mode(const char *optarg)
+{
+	
+}
+
+void
+ui_clip_request_data(uint32 format)
+{
+	
+	if(format==1)
+	 {
+	  const char *text;
+	  ssize_t textLen;
+	  BMessage *clip = (BMessage *)NULL;
+	  if(be_clipboard->Lock())
+	   {
+	    if(clip = be_clipboard->Data())
+	     {
+	      	clip->FindData("text/plain", B_MIME_TYPE,(const void**)&text,&textLen);
+			if(textLen>0)
+			 {
+				char *ToAnsi=(char*)xmalloc(textLen+4);
+				if(ToAnsi!=NULL)
+				 {
+					int32 DestLen=textLen;
+					int32 State=0;
+		     		int32 SourceLen=textLen;
+
+			  		convert_from_utf8(B_MS_WINDOWS_1251_CONVERSION, text, &SourceLen, ToAnsi, &DestLen, &State);
+			  		ToAnsi[DestLen]=0;
+		  			      		
+		      		uint8 *translated_data;
+					uint32 length = DestLen;
+
+					translated_data = lf2crlf((uint8*)ToAnsi, &length);
+					cliprdr_send_data(translated_data, length);
+					xfree(translated_data);	
+					
+	      			cliprdr_send_simple_native_format_announce(RDP_CF_TEXT);
+	      			xfree(ToAnsi);
+   		    	 }
+   		     }
+	     }
+  		be_clipboard->Unlock();
+	   }
+	 }
+	else
+	{
+	 cliprdr_send_data(NULL, 0);
+	}
+}
+
+void
+ui_clip_sync(void)
+{
+	
+	cliprdr_send_simple_native_format_announce(RDP_CF_TEXT);	
+}
+
+
+
+void
+xclip_init(void)
+{
+	
+	if (!cliprdr_init())
+		return;
+}
+}
diff --git a/haiku/makefile_gcc2 b/haiku/makefile_gcc2
new file mode 100644
index 0000000..9e16505
--- /dev/null
+++ b/haiku/makefile_gcc2
@@ -0,0 +1,56 @@
+#-DRDPSND_BEOS=1  -DWITH_RDPSND=1 -DWITH_OPENSSL=1
+CC = gcc
+CFLAGS = -Os -DL_ENDIAN=1 -D_BONE_=1 -I./ -I./vgagl -g
+RESTOBJ = ../seamless.o ../printercache.o ../serial.o ../parallel.o ../printer.o ../rdpdr.o ../disk.o ../rdpsnd_dsp.o ../rdpsnd.o ../cliprdr.o ../tcp.o ../iso.o ../mcs.o ../secure.o ../rdp.o ../rdp5.o ../orders.o ../cache.o ../mppc.o ../licence.o ../bitmap.o ../channels.o ../pstcache.o ../ssl.o ../utils.o ../asn.o
+LDFLAGS = -L./ -L./vgagl -lvgagl -lbe -lroot -ltextencoding -lmedia -lnetwork -lstdc++.r4 -lcrypto -lssl
+
+all: svgard
+svgard: svga_to_haiku.o window_haiku.o clip_haiku.o  $(RESTOBJ)
+	${MAKE} -C vgagl
+	$(CC) -o rdesktop svga_to_haiku.o window_haiku.o clip_haiku.o $(RESTOBJ) $(LDFLAGS)
+	
+
+#rest: $(RESTOBJ)
+#rest: tcp.o iso.o mcs.o secure.o rdp.o rdp5.o orders.o cache.o mppc.o licence.o bitmap.o channels.o pstcache.o
+rest: ../seamless.c ../printercache.c ../serial.c ../parallel.c ../printer.c ../rdpdr.c ../disk.c ../rdpsnd_dsp.c ../rdpsnd.c ../cliprdr.c ../tcp.c ../iso.c ../mcs.c ../secure.c ../rdp.c ../rdp5.c ../orders.c ../cache.c ../mppc.c ../licence.c ../bitmap.c ../channels.c ../pstcache.c ../ssl.c ../utils.c ../asn.c
+#	$(CC) $(CFLAGS) -c ../rdpsnd.c -o ../rdpsnd.o
+#	$(CC) $(CFLAGS) -c ../rdpsnd_dsp.c -o ../rdpsnd_dsp.o
+	$(CC) $(CFLAGS) -c ../cliprdr.c -o ../cliprdr.o
+	$(CC) $(CFLAGS) -c ../tcp.c -o ../tcp.o
+	$(CC) $(CFLAGS) -c ../iso.c -o ../iso.o
+	$(CC) $(CFLAGS) -c ../mcs.c -o ../mcs.o
+	$(CC) $(CFLAGS) -c ../secure.c -o ../secue.o
+	$(CC) $(CFLAGS) -c ../rdp.c -o ../rdp.o
+	$(CC) $(CFLAGS) -c ../rdp5.c -o ../rdp5.o
+	$(CC) $(CFLAGS) -c ../orders.c -o ../orders.o
+	$(CC) $(CFLAGS) -c ../cache.c -o ../cache.o
+	$(CC) $(CFLAGS) -c ../mppc.c -o ../mppc.o
+	$(CC) $(CFLAGS) -c ../licence.c -o ../licence.o
+	$(CC) $(CFLAGS) -c ../ssl.c -o ../ssl.o	
+	$(CC) $(CFLAGS) -c ../bitmap.c -o ../bitmap.o
+	$(CC) $(CFLAGS) -c ../channels.c -o ../channels.o
+	$(CC) $(CFLAGS) -c ../pstcache.c -o ../pstcache.o
+	$(CC) $(CFLAGS) -c ../disk.c -o ../disk.o
+	$(CC) $(CFLAGS) -c ../rdpdr.c -o ../rdpdr.o
+	$(CC) $(CFLAGS) -c ../serial.c -o ../serial.o
+	$(CC) $(CFLAGS) -c ../printer.c -o ../printer.o
+	$(CC) $(CFLAGS) -c ../printercache.c -o ../printercache.o
+	$(CC) $(CFLAGS) -c ../parallel.c -o ../parallel.o
+	$(CC) $(CFLAGS) -c ../seamless.c -o ../seamless.o
+	$(CC) $(CFLAGS) -c ../utils.c -o ../utils.o
+	$(CC) $(CFLAGS) -c ../asn.c -o ../asn.o
+
+svga_to_haiku.o: svga_to_haiku.c
+	$(CC) $(CFLAGS) -c $*.c
+window_haiku.o: window_haiku.cpp
+	$(CC) $(CFLAGS) -c $*.cpp
+clip_haiku.o: clip_haiku.cpp
+	$(CC) $(CFLAGS) -c $*.cpp
+rdpsnd_haiku.o: rdpsnd_haiku.cpp
+	$(CC) $(CFLAGS) -c $*.cpp
+
+clean:
+	rm -f rdesktop
+	rm -f ./vgagl/*.o
+	rm -f *.o
+	rm -f ../*.o
diff --git a/haiku/makefile_gcc4 b/haiku/makefile_gcc4
new file mode 100644
index 0000000..129f42e
--- /dev/null
+++ b/haiku/makefile_gcc4
@@ -0,0 +1,56 @@
+#-DRDPSND_BEOS=1  -DWITH_RDPSND=1 
+CC = gcc
+CFLAGS = -Os -DL_ENDIAN=1 -D_BONE_=1 -DWITH_OPENSSL=1 -I./ -I./vgagl -Wno-write-strings
+RESTOBJ = ../seamless.o ../printercache.o ../serial.o ../parallel.o ../printer.o ../rdpdr.o ../disk.o ../rdpsnd_dsp.o ../rdpsnd.o ../cliprdr.o ../tcp.o ../iso.o ../mcs.o ../secure.o ../rdp.o ../rdp5.o ../orders.o ../cache.o ../mppc.o ../licence.o ../bitmap.o ../channels.o ../pstcache.o ../ssl.o ../utils.o ../asn.o
+LDFLAGS = -L./ -L./vgagl -lvgagl -lbe -lroot -ltextencoding -lmedia -lnetwork -lstdc++ -lcrypto -lssl
+
+all: svgard
+svgard: svga_to_haiku.o window_haiku.o clip_haiku.o  $(RESTOBJ)
+	${MAKE} -C vgagl
+	$(CC) -o rdesktop svga_to_haiku.o window_haiku.o clip_haiku.o $(RESTOBJ) $(LDFLAGS)
+	
+
+#rest: $(RESTOBJ)
+#rest: tcp.o iso.o mcs.o secure.o rdp.o rdp5.o orders.o cache.o mppc.o licence.o bitmap.o channels.o pstcache.o
+rest: ../seamless.c ../printercache.c ../serial.c ../parallel.c ../printer.c ../rdpdr.c ../disk.c ../rdpsnd_dsp.c ../rdpsnd.c ../cliprdr.c ../tcp.c ../iso.c ../mcs.c ../secure.c ../rdp.c ../rdp5.c ../orders.c ../cache.c ../mppc.c ../licence.c ../bitmap.c ../channels.c ../pstcache.c ../ssl.c ../utils.c ../asn.c
+#	$(CC) $(CFLAGS) -c ../rdpsnd.c -o ../rdpsnd.o
+#	$(CC) $(CFLAGS) -c ../rdpsnd_dsp.c -o ../rdpsnd_dsp.o
+	$(CC) $(CFLAGS) -c ../cliprdr.c -o ../cliprdr.o
+	$(CC) $(CFLAGS) -c ../tcp.c -o ../tcp.o
+	$(CC) $(CFLAGS) -c ../iso.c -o ../iso.o
+	$(CC) $(CFLAGS) -c ../mcs.c -o ../mcs.o
+	$(CC) $(CFLAGS) -c ../secure.c -o ../secue.o
+	$(CC) $(CFLAGS) -c ../rdp.c -o ../rdp.o
+	$(CC) $(CFLAGS) -c ../rdp5.c -o ../rdp5.o
+	$(CC) $(CFLAGS) -c ../orders.c -o ../orders.o
+	$(CC) $(CFLAGS) -c ../cache.c -o ../cache.o
+	$(CC) $(CFLAGS) -c ../mppc.c -o ../mppc.o
+	$(CC) $(CFLAGS) -c ../licence.c -o ../licence.o
+	$(CC) $(CFLAGS) -c ../ssl.c -o ../ssl.o	
+	$(CC) $(CFLAGS) -c ../bitmap.c -o ../bitmap.o
+	$(CC) $(CFLAGS) -c ../channels.c -o ../channels.o
+	$(CC) $(CFLAGS) -c ../pstcache.c -o ../pstcache.o
+	$(CC) $(CFLAGS) -c ../disk.c -o ../disk.o
+	$(CC) $(CFLAGS) -c ../rdpdr.c -o ../rdpdr.o
+	$(CC) $(CFLAGS) -c ../serial.c -o ../serial.o
+	$(CC) $(CFLAGS) -c ../printer.c -o ../printer.o
+	$(CC) $(CFLAGS) -c ../printercache.c -o ../printercache.o
+	$(CC) $(CFLAGS) -c ../parallel.c -o ../parallel.o
+	$(CC) $(CFLAGS) -c ../seamless.c -o ../seamless.o
+	$(CC) $(CFLAGS) -c ../utils.c -o ../utils.o
+	$(CC) $(CFLAGS) -c ../asn.c -o ../asn.o
+
+svga_to_haiku.o: svga_to_haiku.c
+	$(CC) $(CFLAGS) -c $*.c
+window_haiku.o: window_haiku.cpp
+	$(CC) $(CFLAGS) -c $*.cpp
+clip_haiku.o: clip_haiku.cpp
+	$(CC) $(CFLAGS) -c $*.cpp
+rdpsnd_haiku.o: rdpsnd_haiku.cpp
+	$(CC) $(CFLAGS) -c $*.cpp
+
+clean:
+	rm -f rdesktop
+	rm -f ./vgagl/*.o
+	rm -f *.o
+	rm -f ../*.o
diff --git a/haiku/rdpsnd_haiku.cpp b/haiku/rdpsnd_haiku.cpp
new file mode 100644
index 0000000..150c87d
--- /dev/null
+++ b/haiku/rdpsnd_haiku.cpp
@@ -0,0 +1,182 @@
+#include <SoundPlayer.h>
+#include <Application.h>
+#include <media/MediaDefs.h>
+#include <MediaRoster.h>
+#include <GameSoundDefs.h>
+#include <MediaDefs.h>
+#include <MediaFormats.h>
+#include <Screen.h>
+#include <GraphicsDefs.h>
+#include <SoundPlayer.h>
+
+extern "C"
+{
+#include "../rdesktop.h"
+#include "../rdpsnd.h"
+#include "../rdpsnd_dsp.h"
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+
+static short g_samplewidth;
+static BSoundPlayer *p = 0;
+static char *outbuf = 0;
+int	buf_len;
+static int g_snd_rate;
+bool	opened = false;
+
+void proc(void *cookie, void *buffer, size_t len, const media_raw_audio_format &format)
+{
+	//printf("proc:  %d\n", len);
+
+	struct audio_packet *packet;
+	unsigned int i;
+	STREAM out;
+
+	memset(buffer,0,len);
+	
+	if (rdpsnd_queue_empty())
+		return; 
+
+	packet = rdpsnd_queue_current_packet();
+	out = &packet->s;
+	
+	if(out->end != out->p)
+		memcpy(buffer,out->p,len);
+	
+	out->p += len;
+	
+	if (out->p >= out->end)	{			
+			rdpsnd_send_completion(packet->tick, packet->index);
+			rdpsnd_queue_next();
+	}	
+	
+}
+
+BOOL
+beos_open(void)
+{
+	//printf("beos_open\n");
+	
+   	buf_len=32768/8;
+
+	rdpsnd_queue_init();
+	if(opened==false)
+	{
+		media_raw_audio_format form = {
+			22050,
+			2,
+			media_raw_audio_format::B_AUDIO_SHORT,
+			B_MEDIA_LITTLE_ENDIAN,
+			buf_len /  2
+		};
+		outbuf = (char *)malloc(buf_len);
+		p = new BSoundPlayer(&form, "audio_play", proc);
+	
+		if(p->InitCheck() != B_OK) {
+			delete p; p = 0;
+			return 0;
+		}
+	
+		p->Start();
+		p->SetHasData(true);
+		opened = true;
+	}
+	
+	return True;
+}
+
+void
+beos_close(void)
+{
+	/* Ack all remaining packets */
+	//printf("beos_close\n");
+	
+	while (!rdpsnd_queue_empty())
+	{
+		rdpsnd_send_completion(rdpsnd_queue_current_packet()->tick,
+				       rdpsnd_queue_current_packet()->index);
+		rdpsnd_queue_next();
+	}
+}
+
+void be_close_sound()
+{
+	//printf("be_close_sound\n");
+
+	if(p) {
+		p->Stop();
+		delete p;
+		p = 0;
+	}
+	free(outbuf); 
+	outbuf = 0;
+}
+
+BOOL
+beos_format_supported(WAVEFORMATEX * pwfx)
+{
+	if (pwfx->wFormatTag != WAVE_FORMAT_PCM)return False;
+	if (pwfx->nChannels != 2)return False;
+	if (pwfx->wBitsPerSample != 16)return False;
+	//printf("wave_out_format_supported Ch:%d Bt:%d Sm:%d\n",pwfx->nChannels,pwfx->wBitsPerSample,pwfx->nSamplesPerSec);
+	return True;
+}
+
+BOOL
+beos_set_format(WAVEFORMATEX * pwfx)
+{
+	//printf("beos_set_format\n");
+	
+	g_samplewidth = pwfx->wBitsPerSample / 8;
+	if (pwfx->nChannels == 2)
+	{
+		g_samplewidth *= 2;
+	}	
+
+	g_snd_rate = pwfx->nSamplesPerSec;
+
+
+	return True;
+}
+
+void
+beos_volume(uint16 left, uint16 right)
+{
+	float l = left/65535.0;
+	float r = right/65535.0;
+	float gain = (l+r)/2;
+	float pan = (r-l)/(gain*2);
+}
+
+
+void
+beos_play(void)
+{
+
+}
+
+
+
+struct audio_driver *
+beos_register(char *options)
+{
+	static struct audio_driver beos_driver;
+
+	beos_driver.wave_out_write = rdpsnd_queue_write;
+	beos_driver.wave_out_open = beos_open;
+	beos_driver.wave_out_close = beos_close;
+	beos_driver.wave_out_format_supported = beos_format_supported;
+	beos_driver.wave_out_set_format = beos_set_format;
+	beos_driver.wave_out_volume = rdpsnd_dsp_softvol_set;
+	beos_driver.wave_out_play = beos_play;
+	beos_driver.name = xstrdup("beos");
+	beos_driver.description = xstrdup("BeOS output driver");
+	beos_driver.need_byteswap_on_be = 1;
+	beos_driver.need_resampling = 0;
+	beos_driver.next = NULL;
+
+
+	return &beos_driver;
+}
+}
\ No newline at end of file
diff --git a/haiku/svga_to_haiku.c b/haiku/svga_to_haiku.c
new file mode 100644
index 0000000..0178fcc
--- /dev/null
+++ b/haiku/svga_to_haiku.c
@@ -0,0 +1,2342 @@
+/* -*- c-basic-offset: 8 -*-
+   rdesktop: A Remote Desktop Protocol client.
+   User interface services - SVGA lib
+   Copyright (C) Jay Sorg 2004-2005
+
+   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.
+*/
+
+
+#include "../rdesktop.h"
+#include "../rdpsnd.h"
+
+extern int beapp_init(void);
+
+#include <vga.h>
+#include <vgakeyboard.h>
+#include <vgamouse.h>
+#include <vgagl.h>
+
+#include <unistd.h> // gethostname
+#include <pwd.h> // getpwuid
+#include <stdarg.h> // va_list va_start va_end
+
+#include <getopt.h>
+
+#include <sys/ioctl.h>
+//#include <linux/keyboard.h>
+//#include <linux/kd.h>
+#include <fcntl.h>
+
+extern int 	render;
+extern int vga_setmode_be(int,int,int,int);
+extern int g_tcp_port_rdp;
+extern char *g_keymapname;
+extern int vga_sync(int x,int y,int w,int h);
+extern int render_end(void);
+extern int render_beg(void);
+
+extern uint32 g_num_devices;
+extern int g_xpos;
+extern int g_ypos;
+extern int g_pos;
+extern RD_BOOL g_sendmotion;
+extern RD_BOOL g_grab_keyboard;
+extern RD_BOOL g_hide_decorations;
+extern char g_title[];
+extern int g_win_button_size;
+
+uint32 g_reconnect_logonid = 0;
+char g_reconnect_random[16];
+uint8 g_client_random[SEC_RANDOM_SIZE];
+RD_BOOL g_has_reconnect_random = False;
+RD_BOOL g_pending_resize = False;
+RD_BOOL g_user_quit = False;
+RD_BOOL g_network_error = False;
+RD_BOOL g_reconnect_loop = False;
+RDP_VERSION g_rdp_version = RDP_V5;	/* Default to version 5 */
+RD_BOOL g_encryption_initial = True;
+time_t g_reconnect_random_ts;
+
+uint32 flags = RDP_LOGON_NORMAL;
+RD_BOOL g_seamless_rdp = False;
+RD_BOOL g_fullscreen=False;
+char g_title[256];
+char g_hostname[16] = "";
+char g_domain[16] = "";
+//char g_username[64] = "";
+char *g_username;
+char g_password[64] = "";
+int g_cursor = 0;
+int g_height = 600;
+int g_width = 800;
+int g_server_depth = 16;
+int g_server_bpp = 16;
+int g_encryption = True;
+int g_desktop_save = True;
+int g_polygon_ellipse_orders = 0;
+int g_bitmap_cache = True;
+int g_bitmap_cache_persist_enable = False;
+int g_bitmap_cache_precache = True;
+int g_bitmap_compression = True;
+int g_rdp5_performanceflags = RDP5_NO_MENUANIMATIONS;//| RDP5_NO_WALLPAPER | RDP5_NO_FULLWINDOWDRAG | RDP5_NO_MENUANIMATIONS;
+int g_console_session = False;
+int g_keylayout = 0x409; /* Defaults to US keyboard layout */
+int g_keyboard_type = 0x4; /* Defaults to US keyboard layout */
+int g_keyboard_subtype = 0x0; /* Defaults to US keyboard layout */
+int g_keyboard_functionkeys = 0xc; /* Defaults to US keyboard layout */
+
+/* hack globals */
+int g_argc = 0;
+char** g_argv = 0;
+int UpAndRunning = 0;
+int g_sock = 0;
+int deactivated = 0;
+uint32 ext_disc_reason = 0;
+char g_servername[128] = "";
+static uint32* colmap = 0;
+static uint8* desk_save = 0;
+int g_server_Bpp = 2;
+char sndopt[32]={"beos:off"};
+char shell[256] = {""};
+char directory[256] = {""};
+RD_BOOL g_numlock_sync;
+RD_BOOL g_rdpsnd = False;
+
+/* Keyboard LEDS */
+static int numlock;
+static int capslock;
+static int scrolllock;
+
+// this is non null if vgalib has non accel functions available
+// reading from video memory is sooo slow
+static uint8* sdata = 0;
+static int g_save_mem = 0; // for video memory use eg sdata == 0
+
+// video acceleration
+static int use_accel = 1;
+static int has_fill_box = 0;
+static int has_screen_copy = 0;
+static int has_put_image = 0;
+
+// clip
+int clip_startx;
+int clip_starty;
+int clip_endx;
+int clip_endy;
+
+// mouse
+uint8 mouse_under[32 * 32 * 4]; // save area under mouse
+int mousex = 0;
+int mousey = 0;
+int mouseb = 0;
+
+// mouse info
+typedef struct
+{
+  uint8 andmask[32 * 32];
+  uint8 xormask[32 * 32];
+  int x;
+  int y;
+  int w;
+  int h;
+} tcursor;
+
+// mouse global
+static tcursor mcursor;
+
+static int g_draw_mouse = 0;
+
+/* Session Directory redirection */
+RD_BOOL g_redirect = False;
+char g_redirect_server[64];
+char g_redirect_domain[16];
+char g_redirect_password[64];
+char g_redirect_username[64];
+char g_redirect_cookie[128];
+uint32 g_redirect_flags = 0;
+
+// bitmap
+typedef struct
+{
+  int width;
+  int height;
+  uint8* data;
+  uint8 Bpp;
+} bitmap;
+
+typedef struct
+{
+  int x;
+  int y;
+  int cx;
+  int cy;
+  void* prev;
+  void* next;
+} myrect;
+
+myrect* head_rect = 0;
+
+//*****************************************************************************
+// Keyboard stuff - PeterS
+static void setled(int mask, int state)
+{
+/*  int fd;
+  long int leds;
+
+  if (( fd=open("/dev/console", O_NOCTTY)) != -1 )
+  {
+    if (ioctl (fd, KDGETLED, &leds) != -1)
+    {
+      leds &= 7;
+      if (state)
+        leds |= mask;
+      else
+        leds &= ~mask;
+      ioctl (fd, KDSETLED, leds);
+    }
+    close(fd);
+  }*/
+}
+
+
+/* create rdesktop ui */
+void
+rd_create_ui()
+{
+#if 0
+	if (!ui_have_window())
+	{
+		if (!ui_create_window())
+			exit(EX_OSERR);
+	}
+#endif
+}
+
+//*****************************************************************************
+// do a raster op
+int rop(int rop, int src, int dst)
+{
+  switch (rop)
+  {
+    case 0x0: return 0;
+    case 0x1: return ~(src | dst);
+    case 0x2: return (~src) & dst;
+    case 0x3: return ~src;
+    case 0x4: return src & (~dst);
+    case 0x5: return ~(dst);
+    case 0x6: return src ^ dst;
+    case 0x7: return ~(src & dst);
+    case 0x8: return src & dst;
+    case 0x9: return ~(src) ^ dst;
+    case 0xa: return dst;
+    case 0xb: return (~src) | dst;
+    case 0xc: return src;
+    case 0xd: return src | (~dst);
+    case 0xe: return src | dst;
+    case 0xf: return ~0;
+  }
+  return dst;
+}
+
+//*****************************************************************************
+// get a screen pixel
+int get_pixel(int x, int y)
+{
+  if (x >= 0 && x < g_width && y >= 0 && y < g_height)
+  {
+    if (sdata != 0)
+    {
+      if (g_server_Bpp == 1)
+        return sdata[y * g_width + x];
+      else if (g_server_Bpp == 2)
+        return ((uint16*)sdata)[y * g_width + x];
+      else
+        return 0;
+    }
+    else
+      return vga_getpixel(x, y);
+  }
+  else
+    return 0;
+}
+
+//*****************************************************************************
+// set a screen pixel
+void set_pixel(int x, int y, int pixel, int op)
+{
+  if (x >= clip_startx && x < clip_endx && y >= clip_starty && y < clip_endy)
+  {
+    if (x >= 0 && x < g_width && y >= 0 && y < g_height)
+    {
+      if (op == 0x0)
+        pixel = 0;
+      else if (op == 0xf)
+        pixel = -1;
+      else if (op != 0xc)
+        pixel = rop(op, pixel, get_pixel(x, y));
+      if (sdata != 0)
+      {
+        if (g_server_Bpp == 1)
+          sdata[y * g_width + x] = pixel;
+        else if (g_server_Bpp == 2)
+          ((uint16*)sdata)[y * g_width + x] = pixel;
+      }
+      else
+      {
+        vga_setcolor(pixel);
+        vga_drawpixel(x, y);
+      }
+    }
+  }
+}
+
+//*****************************************************************************
+// get a pixel from a bitmap
+int get_pixel2(int x, int y, uint8* data, int width, int bpp)
+{
+  if (bpp == 8)
+    return data[y * width + x];
+  else if (bpp == 16)
+    return ((uint16*)data)[y * width + x];
+  else
+    return 0;
+}
+
+//*****************************************************************************
+// set a pixel in a bitmap
+void set_pixel2(int x, int y, int pixel, uint8* data, int width, int bpp)
+{
+  if (bpp == 8)
+    data[y * width + x] = pixel;
+  else if (bpp == 16)
+    ((uint16*)data)[y * width + x] = pixel;
+}
+
+//*****************************************************************************
+// get a pointer into a bitmap
+uint8* get_ptr(int x, int y, uint8* data, int width, int bpp)
+{
+  if (bpp == 8)
+    return data + (y * width + x);
+  else if (bpp == 16)
+    return data + (y * width + x) * 2;
+  else
+    return 0;
+}
+
+//*****************************************************************************
+// check if a certain pixel is set in a bitmap
+RD_BOOL is_pixel_on(uint8* data, int x, int y, int width, int bpp)
+{
+  int start;
+  int shift;
+
+  if (bpp == 1)
+  {
+    width = (width + 7) / 8;
+    start = (y * width) + x / 8;
+    shift = x % 8;
+    return (data[start] & (0x80 >> shift)) != 0;
+  }
+  else if (bpp == 8)
+  {
+    return data[y * width + x] != 0;
+  }
+  else if (bpp == 24)
+  {
+    return data[(y * 3) * width + (x * 3)] != 0 &&
+           data[(y * 3) * width + (x * 3) + 1] != 0 &&
+           data[(y * 3) * width + (x * 3) + 2] != 0;
+  }
+  else
+    return False;
+}
+
+//*****************************************************************************
+void set_pixel_on(uint8* data, int x, int y, int width, int bpp, int pixel)
+{
+  if (bpp == 8)
+  {
+    data[y * width + x] = pixel;
+  }
+}
+
+/*****************************************************************************/
+int warp_coords(int* x, int* y, int* cx, int* cy, int* srcx, int* srcy)
+{
+  int dx;
+  int dy;
+//  int lx = *x, ly = *y, lcx = *cx, lcy = *cy;
+
+  if (clip_startx > *x)
+    dx = clip_startx - *x;
+  else
+    dx = 0;
+  if (clip_starty > *y)
+    dy = clip_starty - *y;
+  else
+    dy = 0;
+  if (*x + *cx > clip_endx)
+    *cx = (*cx - ((*x + *cx) - clip_endx)) /*+ 1*/;
+  if (*y + *cy > clip_endy)
+    *cy = (*cy - ((*y + *cy) - clip_endy)) /*+ 1*/;
+  *cx = *cx - dx;
+  *cy = *cy - dy;
+  if (*cx <= 0)
+    return False;
+  if (*cy <= 0)
+    return False;
+  *x = *x + dx;
+  *y = *y + dy;
+  if (srcx != NULL)
+    *srcx = *srcx + dx;
+  if (srcy != NULL)
+    *srcy = *srcy + dy;
+
+//  if (*x != lx || *y != ly || *cx != lcx || *cy != lcy)
+//    printf("%d %d %d %d to %d %d %d %d\n", lx, ly, lcx, lcy, *x, *y, *cx, *cy);
+
+  return True;
+}
+
+//*****************************************************************************
+void copy_mem(uint8* d, uint8* s, int n)
+{
+  while (n & (~7))
+  {
+    *(d++) = *(s++);
+    *(d++) = *(s++);
+    *(d++) = *(s++);
+    *(d++) = *(s++);
+    *(d++) = *(s++);
+    *(d++) = *(s++);
+    *(d++) = *(s++);
+    *(d++) = *(s++);
+    n = n - 8;
+  }
+  while (n > 0)
+  {
+    *(d++) = *(s++);
+    n--;
+  }
+}
+
+//*****************************************************************************
+void copy_memb(uint8* d, uint8* s, int n)
+{
+  d = (d + n) - 1;
+  s = (s + n) - 1;
+  while (n & (~7))
+  {
+    *(d--) = *(s--);
+    *(d--) = *(s--);
+    *(d--) = *(s--);
+    *(d--) = *(s--);
+    *(d--) = *(s--);
+    *(d--) = *(s--);
+    *(d--) = *(s--);
+    *(d--) = *(s--);
+    n = n - 8;
+  }
+  while (n > 0)
+  {
+    *(d--) = *(s--);
+    n--;
+  }
+}
+
+//*****************************************************************************
+// all in pixel except line_size is in bytes
+void accel_draw_box(int x, int y, int cx, int cy, uint8* data, int line_size)
+{
+  int i;
+  uint8* s;
+  uint8* d;
+
+  if (sdata != 0)
+  {
+    s = data;
+    d = get_ptr(x, y, sdata, g_width, g_server_bpp);
+    for (i = 0; i < cy; i++)
+    {
+      copy_mem(d, s, cx * g_server_Bpp);
+      s = s + line_size;
+      d = d + g_width * g_server_Bpp;
+    }
+  }
+  else if (has_put_image && line_size == cx * g_server_Bpp)
+  {
+    vga_accel(ACCEL_PUTIMAGE, x, y, cx, cy, data);
+  }
+  else
+  {
+    s = data;
+    for (i = 0; i < cy; i++)
+    {
+      vga_drawscansegment(s, x, y + i, cx * g_server_Bpp);
+      s = s + line_size;
+    }
+  }
+  //vga_sync(x,y,cx,cy);
+}
+
+//*****************************************************************************
+void accel_fill_rect(int x, int y, int cx, int cy, int color)
+{
+  int i;
+  uint8* temp;
+  uint8* d;
+
+  if (sdata != 0)
+  {
+    temp = xmalloc(cx * g_server_Bpp);
+    if (g_server_Bpp == 1)
+      for (i = 0; i < cx; i++)
+        temp[i] = color;
+    else if (g_server_Bpp == 2)
+      for (i = 0; i < cx; i++)
+        ((uint16*)temp)[i] = color;
+    d = get_ptr(x, y, sdata, g_width, g_server_bpp);
+    for (i = 0; i < cy; i++)
+    {
+      copy_mem(d, temp, cx * g_server_Bpp);
+      d = d + g_width * g_server_Bpp;
+    }
+    xfree(temp);
+  }
+  else if (has_fill_box)
+  {
+    vga_accel(ACCEL_SETFGCOLOR, color);
+    vga_accel(ACCEL_FILLBOX, x, y, cx, cy);
+  }
+  else
+  {
+    temp = xmalloc(cx * g_server_Bpp);
+    if (g_server_Bpp == 1)
+      for (i = 0; i < cx; i++)
+        temp[i] = color;
+    else if (g_server_Bpp == 2)
+      for (i = 0; i < cx; i++)
+        ((uint16*)temp)[i] = color;
+    for (i = 0; i < cy; i++)
+      vga_drawscansegment(temp, x, y + i, cx * g_server_Bpp);
+    xfree(temp);
+  }
+  //vga_sync(x,y,cx,cy);
+}
+
+//*****************************************************************************
+void accel_screen_copy(int x, int y, int cx, int cy, int srcx, int srcy)
+{
+  uint8* temp;
+  uint8* s;
+  uint8* d;
+  int i;
+
+  if (sdata != 0)
+  {
+    if (srcy < y)
+    { // bottom to top
+      s = get_ptr(srcx, (srcy + cy) - 1, sdata, g_width, g_server_bpp);
+      d = get_ptr(x, (y + cy) - 1, sdata, g_width, g_server_bpp);
+      for (i = 0; i < cy; i++)  // copy down
+      {
+        copy_mem(d, s, cx * g_server_Bpp);
+        s = s - g_width * g_server_Bpp;
+        d = d - g_width * g_server_Bpp;
+      }
+    }
+    else if (srcy > y || srcx > x) // copy up or left
+    { // top to bottom
+      s = get_ptr(srcx, srcy, sdata, g_width, g_server_bpp);
+      d = get_ptr(x, y, sdata, g_width, g_server_bpp);
+      for (i = 0; i < cy; i++)
+      {
+        copy_mem(d, s, cx * g_server_Bpp);
+        s = s + g_width * g_server_Bpp;
+        d = d + g_width * g_server_Bpp;
+      }
+    }
+    else // copy straight right
+    {
+      s = get_ptr(srcx, srcy, sdata, g_width, g_server_bpp);
+      d = get_ptr(x, y, sdata, g_width, g_server_bpp);
+      for (i = 0; i < cy; i++)
+      {
+        copy_memb(d, s, cx * g_server_Bpp);
+        s = s + g_width * g_server_Bpp;
+        d = d + g_width * g_server_Bpp;
+      }
+    }
+  }
+  else if (has_screen_copy)
+  {
+    vga_accel(ACCEL_SCREENCOPY, srcx, srcy, x, y, cx, cy);
+  }
+  else
+  {
+    // slow
+    temp = (uint8*)xmalloc(cx * cy * g_server_Bpp);
+    for (i = 0; i < cy; i++)
+      vga_getscansegment(get_ptr(0, i, temp, cx, g_server_bpp), srcx, srcy + i, cx * g_server_Bpp);
+    for (i = 0; i < cy; i++)
+      vga_drawscansegment(get_ptr(0, i, temp, cx, g_server_bpp), x, y + i, cx * g_server_Bpp);
+    xfree(temp);
+  }
+  //vga_sync(x,y,cx,cy);
+}
+
+//*****************************************************************************
+// return bool
+int contains_mouse(int x, int y, int cx, int cy)
+{
+  if (mousex + 32 >= x &&
+      mousey + 32 >= y &&
+      mousex <= x + cx &&
+      mousey <= y + cy)
+    return 1;
+  else
+    return 0;
+}
+
+//*****************************************************************************
+void fill_rect(int x, int y, int cx, int cy, int colour, int opcode)
+{
+  int i;
+  int j;
+
+  if (warp_coords(&x, &y, &cx, &cy, NULL, NULL))
+  {
+    if (opcode == 0xc)
+      accel_fill_rect(x, y, cx, cy, colour);
+    else if (opcode == 0xf)
+      accel_fill_rect(x, y, cx, cy, -1);
+    else if (opcode == 0x0)
+      accel_fill_rect(x, y, cx, cy, 0);
+    else
+    {
+      for (i = 0; i < cy; i++)
+        for (j = 0; j < cx; j++)
+          set_pixel(x + j, y + i, colour, opcode);
+    }
+  }
+}
+
+//*****************************************************************************
+void get_rect(int x, int y, int cx, int cy, uint8* p)
+{
+  int i;
+
+  if (x < 0)
+  {
+    cx = cx + x;
+    x = 0;
+  }
+  if (y < 0)
+  {
+    cy = cy + y;
+    y = 0;
+  }
+  if (sdata != 0)
+  {
+    for (i = 0; i < cy; i++)
+    {
+      copy_mem(p, get_ptr(x, y + i, sdata, g_width, g_server_bpp), cx * g_server_Bpp);
+      p = p + cx * g_server_Bpp;
+    }
+  }
+  else
+  {
+    for (i = 0; i < cy; i++)
+    {
+      vga_getscansegment(p, x, y + i, cx * g_server_Bpp);
+      p = p + cx * g_server_Bpp;
+    }
+  }
+}
+
+/*****************************************************************************/
+// return true if r1 is contained by r2
+int is_contained_by(myrect* r1, myrect* r2)
+{
+  if (r1->x >= r2->x &&
+      r1->y >= r2->y &&
+      r1->x + r1->cx <= r2->x + r2->cx &&
+      r1->y + r1->cy <= r2->y + r2->cy)
+    return 1;
+  else
+    return 0;
+}
+
+/*****************************************************************************/
+void draw_cursor_under(int ox, int oy)
+{
+if(g_cursor==1)
+{
+  int i;
+  int j;
+  int k;
+  uint8* ptr;
+  int len;
+
+  if (ox < 0)
+    k = -ox;
+  else
+    k = 0;
+  j = g_width - ox;
+  if (j > 32)
+    j = 32;
+  if (j > 0)
+  {
+    for (i = 0; i < 32; i++)
+    {
+      ptr = get_ptr(k, i, mouse_under, 32, g_server_bpp);
+      len = (j - k) * g_server_Bpp;
+      if (ox + k >= 0 && oy + i >= 0 && ox + k < g_width && oy + i < g_height)
+        vga_drawscansegment(ptr, ox + k, oy + i, len);
+    }
+  }
+  g_draw_mouse = 1;
+ }
+}
+
+/*****************************************************************************/
+void draw_cursor(void)
+{
+if(g_cursor==1)
+{
+  int i;
+  int j;
+  int k;
+  int pixel;
+  uint8 mouse_a[32 * 32 * 4];
+  uint8* ptr;
+  int len;
+
+  if (!g_draw_mouse)
+    return;
+  memset(mouse_under, 0, sizeof(mouse_under));
+  for (i = 0; i < 32; i++)
+  {
+    for (j = 0; j < 32; j++)
+    {
+      pixel = get_pixel(mousex + j, mousey + i);
+      set_pixel2(j, i, pixel, mouse_under, 32, g_server_bpp);
+      if (mcursor.andmask[i * 32 + j] == 0)
+        k = 0;
+      else
+        k = ~0;
+      pixel = rop(0x8, k, pixel);
+      if (mcursor.xormask[i * 32 + j] == 0)
+        k = 0;
+      else
+        k = ~0;
+      pixel = rop(0x6, k, pixel);
+      set_pixel2(j, i, pixel, mouse_a, 32, g_server_bpp);
+    }
+  }
+  if (mousex < 0)
+    k = -mousex;
+  else
+    k = 0;
+  j = g_width - mousex;
+  if (j > 32)
+    j = 32;
+  if (j > 0)
+  {
+    for (i = mousey; i < mousey + 32; i++)
+      if (i < g_height && i >= 0)
+      {
+        ptr = get_ptr(k, i - mousey, mouse_a, 32, g_server_bpp);
+        len = (j - k) * g_server_Bpp;
+        vga_drawscansegment(ptr, mousex + k, i, len);
+      }
+  }
+  g_draw_mouse = 0; 
+ }
+}
+
+/*****************************************************************************/
+// add a rect to cache
+void cache_rect(int x, int y, int cx, int cy, int do_warp)
+{
+  myrect* rect;
+  myrect* walk_rect;
+
+  if (sdata == 0)
+  {
+    draw_cursor();
+    return;
+  }
+  if (do_warp)
+    if (!warp_coords(&x, &y, &cx, &cy, NULL, NULL))
+      return;
+  rect = (myrect*)xmalloc(sizeof(myrect));
+  rect->x = x;
+  rect->y = y;
+  rect->cx = cx;
+  rect->cy = cy;
+  rect->next = 0;
+  rect->prev = 0;
+  if (head_rect == 0)
+    head_rect = rect;
+  else
+  {
+    walk_rect = 0;
+    do
+    {
+      if (walk_rect == 0)
+        walk_rect = head_rect;
+      else
+        walk_rect = walk_rect->next;
+      if (is_contained_by(rect, walk_rect))
+      {
+        xfree(rect);
+        return;
+      }
+    }
+    while (walk_rect->next != 0);
+    walk_rect->next = rect;
+    rect->prev = walk_rect;
+  }
+}
+
+//*****************************************************************************
+void draw_cache_rects(void)
+{
+  int i;
+  myrect* rect;
+  myrect* rect1;
+  uint8* p;
+  int min_x=g_width;
+  int min_y=g_height;
+  int max_x=0;
+  int max_y=0;
+
+  // draw all the rects
+  rect = head_rect;
+  while (rect != 0)
+  {
+    p = get_ptr(rect->x, rect->y, sdata, g_width, g_server_bpp);
+    for (i = 0; i < rect->cy; i++)
+    {
+      vga_drawscansegment(p, rect->x, rect->y + i, rect->cx * g_server_Bpp);
+      p = p + g_width * g_server_Bpp;
+    }
+   // vga_sync(rect->x, rect->y, rect->cx, rect->cy);
+   	if(rect->x<min_x)min_x=rect->x;
+   	if(rect->y<min_y)min_y=rect->y;
+   	if(rect->x+rect->cx>max_x)max_x=rect->x+rect->cx;
+   	if(rect->y+rect->cy>max_y)max_y=rect->y+rect->cy;
+   	
+    rect1 = rect;
+    rect = rect->next;
+    xfree(rect1);
+  }
+  head_rect = 0;
+  
+//  vga_sync(min_x,min_y,max_x,max_y);
+}
+
+
+/***************************************************/
+void key_event(int scancode, int pressed)
+{
+  int rdpkey;
+  int ext;
+
+  if (!UpAndRunning)
+    return;
+  rdpkey = scancode;
+  ext = 0;
+  
+  // Keyboard LEDS
+  if ((scancode == SCANCODE_CAPSLOCK) && pressed)
+  {
+     capslock = !capslock;
+//     setled(LED_CAP, capslock);
+  }
+  if ((scancode == SCANCODE_SCROLLLOCK) && pressed)
+  {
+     scrolllock = !scrolllock;
+ //    setled(LED_SCR, scrolllock);
+  }
+
+  if ((scancode == SCANCODE_NUMLOCK) && pressed)
+  {
+     numlock = !numlock;
+//     setled(LED_NUM, numlock);
+  }
+     
+  switch (scancode)
+  {
+    case SCANCODE_CURSORBLOCKUP:    rdpkey = 0xc8; ext = KBD_FLAG_EXT; break; // up arrow
+    case SCANCODE_CURSORBLOCKDOWN:  rdpkey = 0xd0; ext = KBD_FLAG_EXT; break; // down arrow
+    case SCANCODE_CURSORBLOCKRIGHT: rdpkey = 0xcd; ext = KBD_FLAG_EXT; break; // right arrow
+    case SCANCODE_CURSORBLOCKLEFT:  rdpkey = 0xcb; ext = KBD_FLAG_EXT; break; // left arrow
+    case SCANCODE_PAGEDOWN:         rdpkey = 0xd1; ext = KBD_FLAG_EXT; break; // page down
+    case SCANCODE_PAGEUP:           rdpkey = 0xc9; ext = KBD_FLAG_EXT; break; // page up
+    case SCANCODE_HOME:             rdpkey = 0xc7; ext = KBD_FLAG_EXT; break; // home
+    case SCANCODE_END:              rdpkey = 0xcf; ext = KBD_FLAG_EXT; break; // end
+    case SCANCODE_INSERT:           rdpkey = 0xd2; ext = KBD_FLAG_EXT; break; // insert
+    case SCANCODE_REMOVE:           rdpkey = 0xd3; ext = KBD_FLAG_EXT; break; // delete
+    case SCANCODE_KEYPADDIVIDE:     rdpkey = 0x35; break; // /
+    case SCANCODE_KEYPADENTER:      rdpkey = 0x1c; break; // enter
+    case SCANCODE_RIGHTCONTROL:     rdpkey = 0x1d; break; // right ctrl
+    case SCANCODE_RIGHTALT:         rdpkey = 0x38; break; // right alt
+    case SCANCODE_LEFTWIN:          rdpkey = 0x5b; ext = KBD_FLAG_EXT; break; // left win
+    case SCANCODE_RIGHTWIN:         rdpkey = 0x5c; ext = KBD_FLAG_EXT; break; // right win
+    case 127:                       rdpkey = 0x5d; ext = KBD_FLAG_EXT; break; // menu key
+    case SCANCODE_PRINTSCREEN:      rdpkey = 0x37; ext = KBD_FLAG_EXT; break; // print screen
+    case SCANCODE_BREAK:            //rdpkey = 0; break; // break
+    {
+      if (pressed)
+      {
+        ext = KBD_FLAG_EXT;
+        rdp_send_input(0, RDP_INPUT_SCANCODE, RDP_KEYPRESS | ext, 0x46, 0);
+        rdp_send_input(0, RDP_INPUT_SCANCODE, RDP_KEYPRESS | ext, 0xc6, 0);
+      }    
+      rdpkey = 0;
+    }
+    case SCANCODE_SCROLLLOCK:       rdpkey = 0x46; break; // scroll lock
+    case 112: // mouse down
+    {
+      rdp_send_input(0, RDP_INPUT_MOUSE, MOUSE_FLAG_DOWN | MOUSE_FLAG_BUTTON4,
+                     mouse_getx(), mouse_gety());
+      return;
+    }
+    case 113: // mouse up
+    {
+      rdp_send_input(0, RDP_INPUT_MOUSE, MOUSE_FLAG_DOWN | MOUSE_FLAG_BUTTON5,
+                     mouse_getx(), mouse_gety());
+      return;
+    }
+  }
+//  printf("%d %d\n", scancode, pressed);
+  if (pressed)
+    rdp_send_input(0, RDP_INPUT_SCANCODE, RDP_KEYPRESS | ext, rdpkey, 0);
+  else
+    rdp_send_input(0, RDP_INPUT_SCANCODE, RDP_KEYRELEASE | ext, rdpkey, 0);
+  
+
+}
+
+/*****************************************************************************/
+int ui_init(void)
+{
+  vga_init();
+  memset(&mcursor, 0, sizeof(tcursor));
+  if (g_server_depth==16) g_server_Bpp=2;
+  else {g_server_depth=8; g_server_Bpp=1;}  
+  desk_save = (uint8*)xmalloc(0x38400 * g_server_Bpp);
+  return 1;
+}
+
+/*****************************************************************************/
+void ui_deinit(void)
+{
+  xfree(desk_save);
+}
+
+/*****************************************************************************/
+int ui_create_window(void)
+{
+  int i;
+
+  ui_reset_clip();
+
+  vga_setmousesupport(1);
+  mouse_setposition(g_width / 2, g_height / 2);
+
+  vga_setmode_be(g_width,g_height,g_server_Bpp*8,g_fullscreen);
+    
+  if (keyboard_init())
+  {
+    error("Keyboard unavailable");
+    return 0;
+  }
+  keyboard_seteventhandler(key_event);
+  if (use_accel)
+  {
+    i = vga_ext_set(VGA_EXT_AVAILABLE, VGA_AVAIL_ACCEL);
+    if (i & ACCELFLAG_PUTIMAGE)
+      has_put_image = 1;
+    if (i & ACCELFLAG_SCREENCOPY)
+      has_screen_copy = 1;
+    if (i & ACCELFLAG_FILLBOX)
+      has_fill_box = 1;
+    //printf("accel %d\n", i);
+  }
+  if (!has_screen_copy && !g_save_mem)
+    sdata = xmalloc(g_width * g_height * g_server_Bpp);
+    
+  if (g_seamless_rdp)
+		seamless_init();
+        
+  return 1;
+}
+
+/*****************************************************************************/
+void ui_destroy_window(void)
+{
+  keyboard_close(); /* Don't forget this! */
+  vga_setmode_be(0,0,0,0);
+  if (sdata != 0)
+    xfree(sdata);
+}
+
+/*****************************************************************************/
+void process_mouse(void)
+{
+  int ox = mousex;
+  int oy = mousey;
+  int ob = mouseb;
+
+  if (!UpAndRunning)
+    return;
+  mousex = mouse_getx() - mcursor.x;
+  mousey = mouse_gety() - mcursor.y;
+  mouseb = mouse_getbutton();
+
+  if (mouseb != ob) // button
+  {
+    // right button
+    if (mouseb & 1)
+      if (!(ob & 1))
+        rdp_send_input(0, RDP_INPUT_MOUSE, MOUSE_FLAG_DOWN | MOUSE_FLAG_BUTTON2,
+                       mousex + mcursor.x, mousey + mcursor.y);
+    if (ob & 1)
+      if (!(mouseb & 1))
+        rdp_send_input(0, RDP_INPUT_MOUSE, MOUSE_FLAG_BUTTON2,
+                       mousex + mcursor.x, mousey + mcursor.y);
+    // middle button
+    if (mouseb & 2)
+      if (!(ob & 2))
+        rdp_send_input(0, RDP_INPUT_MOUSE, MOUSE_FLAG_DOWN | MOUSE_FLAG_BUTTON3,
+                       mousex + mcursor.x, mousey + mcursor.y);
+    if (ob & 2)
+      if (!(mouseb & 2))
+        rdp_send_input(0, RDP_INPUT_MOUSE, MOUSE_FLAG_BUTTON3,
+                       mousex + mcursor.x, mousey + mcursor.y);
+    // left button
+    if (mouseb & 4)
+      if (!(ob & 4))
+        rdp_send_input(0, RDP_INPUT_MOUSE, MOUSE_FLAG_DOWN | MOUSE_FLAG_BUTTON1,
+                       mousex + mcursor.x, mousey + mcursor.y);
+    if (ob & 4)
+      if (!(mouseb & 4))
+        rdp_send_input(0, RDP_INPUT_MOUSE, MOUSE_FLAG_BUTTON1,
+                       mousex + mcursor.x, mousey + mcursor.y);
+  }
+  if (mousex != ox || mousey != oy) // movement
+  {
+    rdp_send_input(0, RDP_INPUT_MOUSE, MOUSE_FLAG_MOVE,
+                   mousex + mcursor.x, mousey + mcursor.y);
+    draw_cursor_under(ox, oy);
+    draw_cursor();
+  }
+}
+
+/*****************************************************************************/
+void process_keyboard(void)
+{
+  if (!UpAndRunning)
+    return;
+}
+
+static void
+rdesktop_reset_state(void)
+{
+	rdp_reset_state();
+#ifdef WITH_SCARD
+	scard_reset_state();
+#endif
+#ifdef WITH_RDPSND
+	rdpsnd_reset_state();
+#endif
+}
+
+/*****************************************************************************/
+RD_BOOL ui_main_loop(void)
+{
+  int sel;
+  fd_set rfds;
+
+  //printf("g_username=%s, g_servername=%s, g_domain=%s, g_password=%s, shell=%s, directory=%s \n",g_username,g_servername, g_domain, g_password, shell, directory);
+  
+  if (!rdp_connect(g_servername, flags, g_domain, g_password, shell, directory, False))
+    return False;
+  UpAndRunning = 1;
+ while (True)
+ {  
+//  FD_ZERO(&rfds);
+//  FD_SET(g_sock, &rfds);
+//  sel = vga_waitevent(3, &rfds, NULL, NULL, NULL);
+//  while (sel >= 0)
+//  {
+//    if (sel & 1) /* mouse */
+//    {
+//      process_mouse();
+//    }
+//    else if (sel & 2) /* keyboard */
+//    {
+//      process_keyboard();
+//   }
+//    else
+//    {
+
+      if (!rdp_loop(&deactivated, &ext_disc_reason))
+        return True; /* ok */
+//   }
+//    FD_ZERO(&rfds);
+//    FD_SET(g_sock, &rfds);
+//   sel = vga_waitevent(3, &rfds, NULL, NULL, NULL);
+//  }
+ }
+  return True;
+}
+
+/*****************************************************************************/
+void ui_bell(void)
+{
+
+}
+
+
+/*****************************************************************************/
+void* ui_create_glyph(int width, int height, uint8* data)
+{
+  int i, j;
+  uint8* glyph_data;
+  bitmap* the_glyph;
+
+  glyph_data = (uint8*)xmalloc(width * height);
+  the_glyph = (bitmap*)xmalloc(sizeof(bitmap));
+  the_glyph->width = width;
+  the_glyph->height = height;
+  the_glyph->data = glyph_data;
+  memset(glyph_data, 0, width * height);
+  for (i = 0; i < height; i++)
+    for (j = 0; j < width; j++)
+      if (is_pixel_on(data, j, i, width, 1))
+        set_pixel_on(glyph_data, j, i, width, 8, 255);
+  return the_glyph;
+}
+
+/*****************************************************************************/
+void ui_destroy_glyph(void* glyph)
+{
+  bitmap* the_glyph;
+
+  the_glyph = (bitmap*)glyph;
+  if (the_glyph != NULL)
+  {
+    if (the_glyph->data != NULL)
+      xfree(the_glyph->data);
+    xfree(the_glyph);
+  }
+}
+
+/*****************************************************************************/
+void ui_destroy_bitmap(void* bmp)
+{
+  bitmap* b;
+
+  b = (bitmap*)bmp;
+  xfree(b->data);
+  xfree(b);
+}
+
+/*****************************************************************************/
+void ui_reset_clip(void)
+{
+  clip_startx = 0;
+  clip_starty = 0;
+  clip_endx = g_width;
+  clip_endy = g_height;
+}
+
+/*****************************************************************************/
+void ui_set_clip(int x, int y, int cx, int cy)
+{
+  clip_startx = x;
+  clip_starty = y;
+  clip_endx = x + cx;
+  clip_endy = y + cy;
+}
+
+/*****************************************************************************/
+void* ui_create_colourmap(COLOURMAP * colours)
+{
+  int i = 0;
+  int n = colours->ncolours;
+  COLOURENTRY* c = colours->colours;
+  int* cmap = (int*)xmalloc(3 * 256 * sizeof (int));
+  if (n > 256)
+    n = 256;
+  memset(cmap, 0, 256 * 3 * sizeof (int));
+  for (i = 0; i < (3 * n); c++)
+  {
+    cmap[i++] = (c->red) >> 2;
+    cmap[i++] = (c->green) >> 2;
+    cmap[i++] = (c->blue) >> 2;
+  }
+  return cmap;
+}
+
+/*****************************************************************************/
+void ui_destroy_colourmap(RD_HCOLOURMAP map)
+{
+  if (colmap == map)
+    colmap = 0;
+  xfree(map);
+}
+
+/*****************************************************************************/
+void ui_set_colourmap(void* map)
+{
+  if (colmap != 0)
+    xfree(colmap);
+  vga_setpalvec(0, 256, (int*)map);
+  colmap = map;
+}
+
+/*****************************************************************************/
+RD_HBITMAP ui_create_bitmap(int width, int height, uint8* data)
+{
+  bitmap* b;
+
+  b = (bitmap*)xmalloc(sizeof(bitmap));
+  b->data = (uint8*)xmalloc(width * height * g_server_Bpp);
+  b->width = width;
+  b->height = height;
+  b->Bpp = g_server_Bpp;
+  copy_mem(b->data, data, width * height * g_server_Bpp);
+  return (void*)b;
+}
+
+//*****************************************************************************
+void draw_glyph (int x, int y, RD_HGLYPH glyph, int fgcolour)
+{
+  bitmap* the_glyph;
+  int i, j;
+
+  the_glyph = (bitmap*)glyph;
+  if (the_glyph == NULL)
+    return;
+  for (i = 0; i < the_glyph->height; i++)
+    for (j = 0; j < the_glyph->width; j++)
+      if (is_pixel_on(the_glyph->data, j, i, the_glyph->width, 8))
+        set_pixel(x + j, y + i, fgcolour, 0xc);
+}
+
+#define DO_GLYPH(ttext,idx) {  glyph = cache_get_font (font, ttext[idx]);  if (!(flags & TEXT2_IMPLICIT_X))    {      xyoffset = ttext[++idx];      if ((xyoffset & 0x80))	{	  if (flags & TEXT2_VERTICAL) 	    y += ttext[idx+1] | (ttext[idx+2] << 8);	  else	    x += ttext[idx+1] | (ttext[idx+2] << 8);	  idx += 2;	}      else	{	  if (flags & TEXT2_VERTICAL) 	    y += xyoffset;	  else	    x += xyoffset;	}    }  if (glyph != NULL)    {      draw_glyph (x + glyph->offset, y + glyph->baseline, glyph->pixmap, fgcolour); if (flags & TEXT2_IMPLICIT_X)	x += glyph->width;    } }
+
+/*****************************************************************************/
+void ui_draw_text(uint8 font, uint8 flags, uint8 opcode, int mixmode,
+                  int x, int y,
+                  int clipx, int clipy, int clipcx, int clipcy,
+                  int boxx, int boxy, int boxcx, int boxcy, BRUSH * brush,
+                  int bgcolour, int fgcolour, uint8* text, uint8 length)
+{
+  int i;
+  int j;
+  int xyoffset;
+  DATABLOB* entry;
+  FONTGLYPH* glyph;
+
+  if (boxcx > 1)
+  {
+    if (contains_mouse(boxx, boxy, boxcx, boxcy))
+      draw_cursor_under(mousex, mousey);
+    fill_rect(boxx, boxy, boxcx, boxcy, bgcolour, 0xc);
+  }
+  else
+  {
+    if (contains_mouse(clipx, clipy, clipcx, clipcy))
+      draw_cursor_under(mousex, mousey);
+    if (mixmode == MIX_OPAQUE)
+      fill_rect(clipx, clipy, clipcx, clipcy, bgcolour, 0xc);
+  }
+
+  /* Paint text, character by character */
+  for (i = 0; i < length;)
+  {
+    switch (text[i])
+    {
+      case 0xff:
+        if (i + 2 < length)
+          cache_put_text(text[i + 1], text, text[i + 2]);
+        else
+        {
+          error("this shouldn't be happening\n");
+          exit(1);
+        }
+        /* this will move pointer from start to first character after FF command */
+        length -= i + 3;
+        text = &(text[i + 3]);
+        i = 0;
+        break;
+
+      case 0xfe:
+        entry = cache_get_text(text[i + 1]);
+        if (entry != NULL)
+        {
+          if ((((uint8 *) (entry->data))[1] == 0) && (!(flags & TEXT2_IMPLICIT_X)))
+          {
+            if (flags & TEXT2_VERTICAL)
+              y += text[i + 2];
+            else
+              x += text[i + 2];
+          }
+          for (j = 0; j < entry->size; j++)
+            DO_GLYPH(((uint8 *) (entry->data)), j);
+        }
+        if (i + 2 < length)
+          i += 3;
+        else
+          i += 2;
+        length -= i;
+        /* this will move pointer from start to first character after FE command */
+        text = &(text[i]);
+        i = 0;
+        break;
+
+      default:
+        DO_GLYPH(text, i);
+        i++;
+        break;
+    }
+  }
+  if (boxcx > 1)
+    cache_rect(boxx, boxy, boxcx, boxcy, True);
+  else
+    cache_rect(clipx, clipy, clipcx, clipcy, True);
+}
+
+//*****************************************************************************
+// Bresenham's line drawing algorithm
+void ui_line(uint8 opcode, int startx, int starty, int endx,
+             int endy, PEN* pen)
+{
+  int dx;
+  int dy;
+  int incx;
+  int incy;
+  int dpr;
+  int dpru;
+  int p;
+  int left;
+  int top;
+  int right;
+  int bottom;
+
+  if (startx > endx)
+  {
+    dx = startx - endx;
+    incx = -1;
+    left = endx;
+    right = startx;
+  }
+  else
+  {
+    dx = endx - startx;
+    incx = 1;
+    left = startx;
+    right = endx;
+  }
+  if (starty > endy)
+  {
+    dy = starty - endy;
+    incy = -1;
+    top = endy;
+    bottom = starty;
+  }
+  else
+  {
+    dy = endy - starty;
+    incy = 1;
+    top = starty;
+    bottom = endy;
+  }
+  if (contains_mouse(left, top, (right - left) + 1, (bottom - top) + 1))
+    draw_cursor_under(mousex, mousey);
+  if (dx >= dy)
+  {
+    dpr = dy << 1;
+    dpru = dpr - (dx << 1);
+    p = dpr - dx;
+    for (; dx >= 0; dx--)
+    {
+      set_pixel(startx, starty, pen->colour, opcode);
+      if (p > 0)
+      {
+        startx += incx;
+        starty += incy;
+        p += dpru;
+      }
+      else
+      {
+        startx += incx;
+        p += dpr;
+      }
+    }
+  }
+  else
+  {
+    dpr = dx << 1;
+    dpru = dpr - (dy << 1);
+    p = dpr - dy;
+    for (; dy >= 0; dy--)
+    {
+      set_pixel(startx, starty, pen->colour, opcode);
+      if (p > 0)
+      {
+        startx += incx;
+        starty += incy;
+        p += dpru;
+      }
+      else
+      {
+        starty += incy;
+        p += dpr;
+      }
+    }
+  }
+  cache_rect(left, top, (right - left) + 1, (bottom - top) + 1, True);
+}
+
+/*****************************************************************************/
+void ui_triblt(uint8 opcode, int x, int y, int cx, int cy,
+               RD_HBITMAP src, int srcx, int srcy,
+               BRUSH* brush, int bgcolour, int fgcolour)
+{
+  // non used
+}
+
+/*****************************************************************************/
+void ui_memblt(uint8 opcode, int x, int y, int cx, int cy,
+               RD_HBITMAP src, int srcx, int srcy)
+{
+  bitmap* b;
+  int i;
+  int j;
+  int pixel;
+
+  if (warp_coords(&x, &y, &cx, &cy, &srcx, &srcy))
+  {
+    if (contains_mouse(x, y, cx, cy))
+      draw_cursor_under(mousex, mousey);
+    b = (bitmap*)src;
+    if (opcode == 0xc)
+      accel_draw_box(x, y, cx, cy, get_ptr(srcx, srcy, b->data, b->width, g_server_bpp),
+                     b->width * g_server_Bpp);
+    else
+    {
+      for (i = 0; i < cy; i++)
+      {
+        for (j = 0; j < cx; j++)
+        {
+          pixel = get_pixel2(srcx + j, srcy + i, b->data, b->width, g_server_bpp);
+          set_pixel(x + j, y + i, pixel, opcode);
+        }
+      }
+    }
+    cache_rect(x, y, cx, cy, False);
+  }
+}
+
+/*****************************************************************************/
+void ui_desktop_restore(uint32 offset, int x, int y, int cx, int cy)
+{
+  uint8* p;
+
+  if (offset > 0x38400)
+    offset = 0;
+  if (offset + cx * cy > 0x38400)
+    return;
+  p = desk_save + offset * g_server_Bpp;
+  ui_paint_bitmap(x, y, cx, cy, cx, cy, p);
+}
+
+/*****************************************************************************/
+void ui_desktop_save(uint32 offset, int x, int y, int cx, int cy)
+{
+  uint8* p;
+
+  if (offset > 0x38400)
+    offset = 0;
+  if (offset + cx * cy > 0x38400)
+    return;
+  if (contains_mouse(x, y, cx, cy))
+    draw_cursor_under(mousex, mousey);
+  p = desk_save + offset * g_server_Bpp;
+  get_rect(x, y, cx, cy, p);
+}
+
+/*****************************************************************************/
+void ui_rect(int x, int y, int cx, int cy, int colour)
+{
+  if (warp_coords(&x, &y, &cx, &cy, NULL, NULL))
+  {
+    if (contains_mouse(x, y, cx, cy))
+      draw_cursor_under(mousex, mousey);
+    accel_fill_rect(x, y, cx, cy, colour);
+    cache_rect(x, y, cx, cy, False);
+  }
+}
+
+/*****************************************************************************/
+void ui_screenblt(uint8 opcode, int x, int y, int cx, int cy,
+                  int srcx, int srcy)
+{
+  int i;
+  int j;
+  uint8* temp;
+
+  if (x == srcx && y == srcy)
+    return;
+  if (warp_coords(&x, &y, &cx, &cy, &srcx, &srcy))
+  {
+    if (contains_mouse(x, y, cx, cy) || contains_mouse(srcx, srcy, cx, cy))
+      draw_cursor_under(mousex, mousey);
+    if (opcode == 0xc) /* copy */
+      accel_screen_copy(x, y, cx, cy, srcx, srcy);
+    else
+    {
+      temp = (uint8*)xmalloc(cx * cy * g_server_Bpp);
+      for (i = 0; i < cy; i++)
+        for (j = 0; j < cx; j++)
+          set_pixel2(j, i, get_pixel(srcx + j, srcy + i), temp, cx, g_server_bpp);
+      for (i = 0; i < cy; i++)
+        for (j = 0; j < cx; j++)
+          set_pixel(x + j, y + i, get_pixel2(j, i, temp, cx, g_server_bpp), opcode);
+      xfree(temp);
+    }
+    cache_rect(x, y, cx, cy, False);
+    draw_cache_rects(); // draw them all so screen is not jumpy
+  }
+}
+
+/*****************************************************************************/
+void ui_patblt(uint8 opcode, int x, int y, int cx, int cy,
+               BRUSH * brush, int bgcolour, int fgcolour)
+{
+  int i;
+  int j;
+  uint8 ipattern[8];
+
+  if (warp_coords(&x, &y, &cx, &cy, NULL, NULL))
+  {
+    if (contains_mouse(x, y, cx, cy))
+      draw_cursor_under(mousex, mousey);
+    switch (brush->style)
+    {
+      case 0:
+        fill_rect(x, y, cx, cy, fgcolour, opcode);
+        break;
+      case 3:
+        for (i = 0; i < 8; i++)
+          ipattern[i] = ~brush->pattern[7 - i];
+        for (i = 0; i < cy; i++)
+          for (j = 0; j < cx; j++)
+            if (is_pixel_on(ipattern, (x + j + brush->xorigin) % 8,
+                              (y + i + brush->yorigin) % 8, 8, 1))
+              set_pixel(x + j, y + i, fgcolour, opcode);
+            else
+              set_pixel(x + j, y + i, bgcolour, opcode);
+        break;
+    }
+    cache_rect(x, y, cx, cy, False);
+  }
+}
+
+/*****************************************************************************/
+void ui_destblt(uint8 opcode, int x, int y, int cx, int cy)
+{
+  if (warp_coords(&x, &y, &cx, &cy, NULL, NULL))
+  {
+    if (contains_mouse(x, y, cx, cy))
+      draw_cursor_under(mousex, mousey);
+    fill_rect(x, y, cx, cy, -1, opcode);
+    cache_rect(x, y, cx, cy, False);
+  }
+}
+
+/*****************************************************************************/
+void ui_move_pointer(int x, int y)
+{
+}
+
+/*****************************************************************************/
+void ui_set_null_cursor(void)
+{
+  draw_cursor_under(mousex, mousey);
+  mousex = mousex - mcursor.x;
+  mousey = mousey - mcursor.y;
+  memset(&mcursor, 0, sizeof(mcursor));
+  memset(mcursor.andmask, 255, sizeof(mcursor.andmask));
+  memset(mcursor.xormask, 0, sizeof(mcursor.xormask));
+  draw_cursor();
+}
+
+/*****************************************************************************/
+void ui_paint_bitmap(int x, int y, int cx, int cy,
+                     int width, int height, uint8* data)
+{
+  if (warp_coords(&x, &y, &cx, &cy, NULL, NULL))
+  {
+    if (contains_mouse(x, y, cx, cy))
+      draw_cursor_under(mousex, mousey);
+    accel_draw_box(x, y, cx, cy, data, width * g_server_Bpp);
+    cache_rect(x, y, cx, cy, False);
+  }
+}
+
+/*****************************************************************************/
+void* ui_create_cursor(unsigned int x, unsigned int y,
+                       int width, int height,
+                       uint8* andmask, uint8* xormask, int bpp)
+{
+  tcursor* c;
+  int i;
+  int j;
+
+  c = (tcursor*)xmalloc(sizeof(tcursor));
+  memset(c, 0, sizeof(tcursor));
+  c->w = width;
+  c->h = height;
+  c->x = x;
+  c->y = y;
+  for (i = 0; i < 32; i++)
+  {
+    for (j = 0; j < 32; j++)
+    {
+      if (is_pixel_on(andmask, j, i, 32, 1))
+        set_pixel_on(c->andmask, j, 31 - i, 32, 8, 255);
+      if (is_pixel_on(xormask, j, i, 32, 24))
+        set_pixel_on(c->xormask, j, 31 - i, 32, 8, 255);
+    }
+  }
+  return (void*)c;
+}
+
+/*****************************************************************************/
+void ui_destroy_cursor(void* cursor)
+{
+  if (cursor != NULL)
+    xfree(cursor);
+}
+
+/*****************************************************************************/
+void ui_set_cursor(void* cursor)
+{
+  int x;
+  int y;
+  int ox;
+  int oy;
+
+  ox = mousex;
+  oy = mousey;
+  x = mousex + mcursor.x;
+  y = mousey + mcursor.y;
+  memcpy(&mcursor, cursor, sizeof(tcursor));
+  mousex = x - mcursor.x;
+  mousey = y - mcursor.y;
+  draw_cursor_under(ox, oy);
+  draw_cursor();
+}
+
+/*****************************************************************************/
+uint16 ui_get_numlock_state(unsigned int state)
+{
+  return 0;
+}
+
+/*****************************************************************************/
+unsigned int read_keyboard_state(void)
+{
+  return 0;
+}
+
+/*****************************************************************************/
+void ui_resize_window(void)
+{
+	vga_resize_window(g_width,g_height);	
+}
+
+/*****************************************************************************/
+void ui_begin_update(void)
+{
+//  render_beg();
+}
+
+/*****************************************************************************/
+void ui_end_update(void)
+{
+  draw_cache_rects();
+  draw_cursor();
+//  render_end();
+}
+
+/*****************************************************************************/
+void ui_polygon(uint8 opcode, uint8 fillmode, RD_POINT * point, int npoints, BRUSH * brush,
+		int bgcolour, int fgcolour)
+{
+}
+
+/*****************************************************************************/
+void ui_polyline(uint8 opcode, RD_POINT * points, int npoints, PEN * pen)
+{
+}
+
+/*****************************************************************************/
+void ui_ellipse(uint8 opcode, uint8 fillmode,
+                int x, int y, int cx, int cy,
+                BRUSH * brush, int bgcolour, int fgcolour)
+{
+}
+
+/*****************************************************************************/
+void generate_random(uint8* random)
+{
+  memcpy(random, "12345678901234567890123456789012", 32);
+}
+
+/*****************************************************************************/
+void save_licence(uint8* data, int length)
+{
+}
+
+/*****************************************************************************/
+int load_licence(uint8** data)
+{
+  return 0;
+}
+
+/*****************************************************************************/
+void *xrealloc(void *oldmem, size_t size)
+{
+  return realloc(oldmem, size);
+}
+
+/*****************************************************************************/
+void* xmalloc(int size)
+{
+  return malloc(size);
+}
+
+/*****************************************************************************/
+void xfree(void* in_val)
+{
+  free(in_val);
+}
+
+/*****************************************************************************/
+char * xstrdup(const char * s)
+{
+  char * mem = strdup(s);
+  if (mem == NULL)
+  {
+    perror("strdup");
+    exit(1);
+  }
+  return mem;
+}
+
+/*****************************************************************************/
+void warning(char* format, ...)
+{
+  va_list ap;
+
+  fprintf(stderr, "WARNING: ");
+  va_start(ap, format);
+  vfprintf(stderr, format, ap);
+  va_end(ap);
+}
+
+/*****************************************************************************/
+void unimpl(char* format, ...)
+{
+  va_list ap;
+
+  fprintf(stderr, "NOT IMPLEMENTED: ");
+  va_start(ap, format);
+  vfprintf(stderr, format, ap);
+  va_end(ap);
+}
+
+/*****************************************************************************/
+void error(char* format, ...)
+{
+  va_list ap;
+
+  fprintf(stderr, "ERROR: ");
+  va_start(ap, format);
+  vfprintf(stderr, format, ap);
+  va_end(ap);
+}
+
+RD_BOOL rd_pstcache_mkdir(void)
+{
+  return 0;
+}
+
+/*****************************************************************************/
+int rd_open_file(char *filename)
+{
+  return 0;
+}
+
+/*****************************************************************************/
+void rd_close_file(int fd)
+{
+  return;
+}
+
+/*****************************************************************************/
+int rd_read_file(int fd, void *ptr, int len)
+{
+  return 0;
+}
+
+/*****************************************************************************/
+int rd_write_file(int fd, void* ptr, int len)
+{
+  return 0;
+}
+
+/*****************************************************************************/
+int rd_lseek_file(int fd, int offset)
+{
+  return 0;
+}
+
+/*****************************************************************************/
+RD_BOOL rd_lock_file(int fd, int start, int len)
+{
+  return False;
+}
+
+/*****************************************************************************/
+void get_username_and_hostname(void)
+{
+  char fullhostname[64];
+  char* p;
+  struct passwd* pw;
+
+  g_username = (char *) xmalloc(64);
+
+  STRNCPY(g_username, "unknown", 8);
+  STRNCPY(g_hostname, "unknown", 8);
+  pw = getpwuid(getuid());
+  if (pw != NULL && pw->pw_name != NULL)
+  {
+    STRNCPY(g_username, pw->pw_name, strlen(pw->pw_name)+1);
+  }
+  if (gethostname(fullhostname, sizeof(fullhostname)) != -1)
+  {
+    p = strchr(fullhostname, '.');
+    if (p != NULL)
+      *p = 0;
+    STRNCPY(g_hostname, fullhostname, sizeof(g_hostname));
+  }
+}
+
+/*****************************************************************************/
+void out_params(void)
+{
+	fprintf(stderr, "rdesktop: A Remote Desktop Protocol client.\n");
+	fprintf(stderr,
+		"Version 1.8.0 Copyright (C) 1999-2013 Matthew Chapman et al.\n");
+	fprintf(stderr, "See http://www.rdesktop.org/ for more information.\n\n");
+
+	fprintf(stderr, "Usage: rdesktop [options] server\n");	
+  	fprintf(stderr, "   -g: desktop geometry (WxH)\n");
+  	fprintf(stderr, "   -4: use RDP version 4\n");
+  	fprintf(stderr, "   -5: use RDP version 5 (default)\n");
+  	fprintf(stderr, "   -t: tcp port\n");
+  	fprintf(stderr, "   -u: user name\n");
+  	fprintf(stderr, "   -p: password\n");
+  	fprintf(stderr, "   -d: domain\n");
+  	fprintf(stderr, "   -s: shell\n");
+  	fprintf(stderr, "   -c: working directory\n");  
+  	fprintf(stderr, "   -A: enable SeamlessRDP mode\n");  
+  	fprintf(stderr, "   -n: client hostname\n");
+  	fprintf(stderr, "   -T  title: window title\n");  
+  	fprintf(stderr, "   -a: connection colour depth\n");
+  	fprintf(stderr, "   -l: low memory\n");
+  	fprintf(stderr, "   -z: enable rdp compression\n");
+  	fprintf(stderr, "   -x: RDP5 experience (m[odem 28.8], b[roadband], l[an] or hex nr.)\n");
+  	fprintf(stderr, "   -r: enable specified device redirection (this flag can be repeated)\n");
+#ifdef WITH_RDPSND
+	fprintf(stderr,
+		"         '-r sound:[local|off|remote]': enable sound redirection\n");
+	fprintf(stderr, "                     remote would leave sound on server\n");
+#endif
+  
+  fprintf(stderr, "\n");
+}
+
+void hexdump(unsigned char *p, unsigned int len)
+{
+  uint8* line;
+  int i;
+  int thisline;
+  int offset;
+
+  line = p;
+  offset = 0;
+  while (offset < len)
+  {
+    printf("%04x ", offset);
+    thisline = len - offset;
+    if (thisline > 16)
+      thisline = 16;
+
+    for (i = 0; i < thisline; i++)
+      printf("%02x ", line[i]);
+
+    for (; i < 16; i++)
+      printf("   ");
+
+    for (i = 0; i < thisline; i++)
+      printf("%c", (line[i] >= 0x20 && line[i] < 0x7f) ? line[i] : '.');
+
+    printf("\n");
+    offset += thisline;
+    line += thisline;
+  }
+}
+
+/*****************************************************************************/
+int parse_parameters(int in_argc, char** in_argv)
+{
+  int i;
+  char* p;
+
+  if (in_argc <= 1)
+  {
+    out_params();
+    return 0;
+  }
+  g_argc = in_argc;
+  g_argv = in_argv;
+  for (i = 1; i < in_argc; i++)
+  {
+    strcpy(g_servername, in_argv[i]);
+    if (strcmp(in_argv[i], "-g") == 0)
+    {
+      g_width = strtol(in_argv[i + 1], &p, 10);
+      if (g_width <= 0)
+      {
+        error("invalid geometry\n");
+        return 0;
+      }
+      if (*p == 'x')
+        g_height = strtol(p + 1, NULL, 10);
+      if (g_height <= 0)
+      {
+        error("invalid geometry\n");
+        return 0;
+      }
+      g_width = (g_width + 3) & ~3;
+    } 
+    else if (strcmp(in_argv[i], "-T") == 0)
+    {
+      strcpy(g_title, in_argv[i + 1]);
+    }
+    else if (strcmp(in_argv[i], "-0") == 0)
+      g_console_session = True;
+    else if (strcmp(in_argv[i], "-4") == 0)
+      g_rdp_version = RDP_V4;
+    else if (strcmp(in_argv[i], "-5") == 0)
+      g_rdp_version = RDP_V5;
+    else if (strcmp(in_argv[i], "-t") == 0)
+      g_tcp_port_rdp = strtol(in_argv[i + 1], &p, 10);
+    else if (strcmp(in_argv[i], "-h") == 0)
+    {
+      out_params();
+      return 0;
+    }
+    else if (strcmp(in_argv[i], "-n") == 0)
+    {
+      STRNCPY(g_hostname, in_argv[i + 1], sizeof(g_hostname));
+    }
+    else if (strcmp(in_argv[i], "-u") == 0)
+    {
+	  int pwlen = strlen(in_argv[i + 1]) + 1;
+	  g_username = (char *) xmalloc(pwlen);
+      STRNCPY(g_username, in_argv[i + 1], strlen(in_argv[i + 1])+1);
+    }
+    else if (strcmp(in_argv[i], "-p") == 0)
+    {
+      STRNCPY(g_password, in_argv[i + 1], sizeof(g_password));
+	  flags |= RDP_LOGON_AUTO;      
+    }
+    else if (strcmp(in_argv[i], "-z") == 0)
+    {
+	  flags |= (RDP_LOGON_COMPRESSION | RDP_LOGON_COMPRESSION2);   
+    }    
+    else if (strcmp(in_argv[i], "-s") == 0)
+    {
+      STRNCPY(shell, in_argv[i + 1], sizeof(shell));
+    }
+    else if (strcmp(in_argv[i], "-c") == 0)
+    {
+      STRNCPY(directory, in_argv[i + 1], sizeof(directory));
+    }    
+    else if (strcmp(in_argv[i], "-0") == 0)
+    {    
+     g_console_session = True;
+    }
+    else if (strcmp(in_argv[i], "-d") == 0)
+    {
+     STRNCPY(g_domain, in_argv[i + 1], sizeof(g_domain));
+    }            
+    else if (strcmp(in_argv[i], "-f") == 0)
+    {
+     	g_fullscreen = True;
+ 		g_width=vga_getscreen_width();
+		g_height=vga_getscreen_height();      
+    }         
+    else if (strcmp(in_argv[i], "-a") == 0)
+    {
+      g_server_bpp = strtol(in_argv[i + 1], NULL, 10);
+      g_server_depth = g_server_bpp;
+      if (g_server_bpp != 8 && g_server_bpp != 16)
+      {
+        error("invalid server bpp\n");
+        return 0;
+      }
+      g_server_Bpp = (g_server_bpp + 7) / 8;
+    }
+    else if (strcmp(in_argv[i], "-l") == 0)
+    {
+      g_save_mem = 1;
+    } 
+    else if (strcmp(in_argv[i], "-x") == 0)
+    {
+		if (str_startswith(in_argv[i+1], "m"))	// modem 
+		{
+					g_rdp5_performanceflags =
+						RDP5_NO_WALLPAPER | RDP5_NO_FULLWINDOWDRAG |
+						RDP5_NO_MENUANIMATIONS | RDP5_NO_THEMING;
+				}
+				else if (str_startswith(in_argv[i+1], "b"))	// broadband 
+				{
+					g_rdp5_performanceflags = RDP5_NO_WALLPAPER;
+				}
+				else if (str_startswith(in_argv[i+1], "l"))	// lan 
+				{
+					g_rdp5_performanceflags = RDP5_DISABLE_NOTHING;
+				}
+				else
+				{
+					g_rdp5_performanceflags = strtol(optarg, NULL, 16);
+				}
+
+	}
+	else if (strcmp(in_argv[i], "-A") == 0)
+    {
+	 g_seamless_rdp = True;
+	 g_width=vga_getscreen_width();
+	 g_height=vga_getscreen_height(); 
+	 g_rdp5_performanceflags &= ~RDP5_NO_FULLWINDOWDRAG;
+	 flags |= RDP_LOGON_LEAVE_AUDIO;
+    }  
+    else if (strcmp(in_argv[i], "-r") == 0)
+    {
+      if(strncmp(in_argv[i+1], "sound:",6)==0)
+       {
+       	char *mode=in_argv[i+1] + 6;
+       	if(strncmp(mode,"local",5)==0)
+       		g_rdpsnd=True;
+       	if(strncmp(mode,"remote",6)==0)
+       	{
+       		g_rdpsnd=True;
+       		flags |= RDP_LOGON_LEAVE_AUDIO;
+       	}
+       	if(strncmp(mode,"off",3)==0)
+       		g_rdpsnd=False;
+       	
+       	sprintf(sndopt,"beos:%s",mode);
+       }
+      if(strncmp(in_argv[i+1], "disk:",5)==0)
+       {       
+       	disk_enum_devices(&g_num_devices, in_argv[i+1] + 4);
+       }
+    }
+  }
+  return 1;
+}
+
+
+/* not all clibs got ltoa */
+#define LTOA_BUFSIZE (sizeof(long) * 8 + 1)
+
+char *
+l_to_a(long N, int base)
+{
+	static char ret[LTOA_BUFSIZE];
+
+	char *head = ret, buf[LTOA_BUFSIZE], *tail = buf + sizeof(buf);
+
+	register int divrem;
+
+	if (base < 36 || 2 > base)
+		base = 10;
+
+	if (N < 0)
+	{
+		*head++ = '-';
+		N = -N;
+	}
+
+	tail = buf + sizeof(buf);
+	*--tail = 0;
+
+	do
+	{
+		divrem = N % base;
+		*--tail = (divrem <= 9) ? divrem + '0' : divrem + 'a' - 10;
+		N /= base;
+	}
+	while (N);
+
+	strcpy(head, tail);
+	return ret;
+}
+
+/*
+  input: src is the string we look in for needle.
+  	 Needle may be escaped by a backslash, in
+	 that case we ignore that particular needle.
+  return value: returns next src pointer, for
+  	succesive executions, like in a while loop
+	if retval is 0, then there are no more args.
+  pitfalls:
+  	src is modified. 0x00 chars are inserted to
+	terminate strings.
+	return val, points on the next val chr after ins
+	0x00
+
+	example usage:
+	while( (pos = next_arg( optarg, ',')) ){
+		printf("%s\n",optarg);
+		optarg=pos;
+	}
+
+*/
+char *
+next_arg(char *src, char needle)
+{
+	char *nextval;
+	char *p;
+	char *mvp = 0;
+
+	/* EOS */
+	if (*src == (char) 0x00)
+		return 0;
+
+	p = src;
+	/*  skip escaped needles */
+	while ((nextval = strchr(p, needle)))
+	{
+		mvp = nextval - 1;
+		/* found backslashed needle */
+		if (*mvp == '\\' && (mvp > src))
+		{
+			/* move string one to the left */
+			while (*(mvp + 1) != (char) 0x00)
+			{
+				*mvp = *(mvp + 1);
+				mvp++;
+			}
+			*mvp = (char) 0x00;
+			p = nextval;
+		}
+		else
+		{
+			p = nextval + 1;
+			break;
+		}
+
+	}
+
+	/* more args available */
+	if (nextval)
+	{
+		*nextval = (char) 0x00;
+		return ++nextval;
+	}
+
+	/* no more args after this, jump to EOS */
+	nextval = src + strlen(src);
+	return nextval;
+}
+
+void
+toupper_str(char *p)
+{
+	while (*p)
+	{
+		if ((*p >= 'a') && (*p <= 'z'))
+			*p = toupper((int) *p);
+		p++;
+	}
+}
+
+
+RD_BOOL
+str_startswith(const char *s, const char *prefix)
+{
+	return (strncmp(s, prefix, strlen(prefix)) == 0);
+}
+
+/* Split input into lines, and call linehandler for each
+   line. Incomplete lines are saved in the rest variable, which should
+   initially point to NULL. When linehandler returns False, stop and
+   return False. Otherwise, return True.  */
+RD_BOOL
+str_handle_lines(const char *input, char **rest, str_handle_lines_t linehandler, void *data)
+{
+	char *buf, *p;
+	char *oldrest;
+	size_t inputlen;
+	size_t buflen;
+	size_t restlen = 0;
+	RD_BOOL ret = True;
+
+	/* Copy data to buffer */
+	inputlen = strlen(input);
+	if (*rest)
+		restlen = strlen(*rest);
+	buflen = restlen + inputlen + 1;
+	buf = (char *) xmalloc(buflen);
+	buf[0] = '\0';
+	if (*rest)
+		STRNCPY(buf, *rest, buflen);
+	strncat(buf, input, inputlen);
+	p = buf;
+
+	while (1)
+	{
+		char *newline = strchr(p, '\n');
+		if (newline)
+		{
+			*newline = '\0';
+			if (!linehandler(p, data))
+			{
+				p = newline + 1;
+				ret = False;
+				break;
+			}
+			p = newline + 1;
+		}
+		else
+		{
+			break;
+
+		}
+	}
+
+	/* Save in rest */
+	oldrest = *rest;
+	restlen = buf + buflen - p;
+	*rest = (char *) xmalloc(restlen);
+	STRNCPY((*rest), p, restlen);
+	xfree(oldrest);
+
+	xfree(buf);
+	return ret;
+}
+
+
+
+
+
+/*****************************************************************************/
+int main(int in_argc, char** in_argv)
+{  				
+  beapp_init();
+  get_username_and_hostname();
+  g_num_devices = 0;  
+  if (!parse_parameters(in_argc, in_argv))
+    return 0;
+  if (!ui_init())
+    return 1;
+  if(strlen(g_title)==0)
+   sprintf(g_title,"rdesktop - %s",g_hostname);
+   
+#ifdef WITH_RDPSND
+	if (g_rdpsnd)
+	{
+		if (!rdpsnd_init(rdpsnd_optarg))
+			warning("Initializing sound-support failed!\n");
+	}
+#endif
+
+	rdpdr_init();
+
+	while (1)
+	{
+		printf("rdesktop_reset_state.\n");
+		rdesktop_reset_state();
+		printf("rdp_connect().\n");
+		
+		if (!rdp_connect(g_servername, flags, g_domain, g_password, shell, directory, False))
+			return EX_PROTOCOL;
+
+		UpAndRunning = 1;
+		
+		printf("Connection successful.\n");
+		memset(g_password, 0, sizeof(g_password));	
+		
+		if (!ui_create_window())
+    		break;	
+
+		rdp_main_loop(&deactivated, &ext_disc_reason);
+		
+		UpAndRunning = 0;
+
+		printf("Disconnecting...\n");
+		rdp_disconnect();
+
+		if (g_redirect)
+			continue;
+			
+		break;
+	}	
+	cache_save_state();
+	ui_destroy_window();
+	ui_deinit();
+			   
+   
+/*  rdpdr_init();
+  
+  if(g_rdpsnd==True)
+    	rdpsnd_init(sndopt);
+   
+  if (!ui_create_window())
+    return 1;
+  ui_main_loop();
+  //be_close_sound();
+  ui_destroy_window();
+  ui_deinit();*/
+  
+  return 0;
+}
diff --git a/haiku/vgagl/.depend.gl b/haiku/vgagl/.depend.gl
new file mode 100644
index 0000000..8ae9b6f
--- /dev/null
+++ b/haiku/vgagl/.depend.gl
@@ -0,0 +1,10 @@
+# GL Module dependencies
+grlib.o: grlib.c vga.h inlstring.h vgagl.h def.h driver.h
+driver.o: driver.c vga.h inlstring.h vgagl.h def.h driver.h
+line.o: line.c vga.h inlstring.h vgagl.h def.h driver.h
+palette.o: palette.c vga.h vgagl.h def.h
+scale.o: scale.c vga.h inlstring.h vgagl.h def.h
+text.o: text.c vga.h inlstring.h vgagl.h def.h
+font8x8.o: font8x8.c
+cbitmap.o: cbitmap.c vga.h inlstring.h vgagl.h def.h
+mem.o: mem.c
diff --git a/haiku/vgagl/Makefile b/haiku/vgagl/Makefile
new file mode 100644
index 0000000..a10f1e0
--- /dev/null
+++ b/haiku/vgagl/Makefile
@@ -0,0 +1,74 @@
+#----------------------------------------------------------------------
+# Makefile for SVGAlib GL routines.
+#----------------------------------------------------------------------
+
+# *** NO SERVICIBLE PARTS HERE!
+#     All options are in Makefile.cfg.
+
+include ./Makefile.cfg
+CC = gcc
+
+srcdir    = .
+VPATH     = .
+
+ifeq (a.out, $(TARGET_FORMAT))
+  DEFINES += -DSVGA_AOUT
+endif
+
+#ifeq (y, $(NO_ASM))
+  DEFINES += -DNO_ASSEMBLY
+#endif
+
+#----------------------------------------------------------------------
+# Rules Section
+#----------------------------------------------------------------------
+
+MODULES	 = grlib.o driver.o line.o palette.o scale.o text.o font8x8.o \
+	   cbitmap.o mem.o 
+
+all:	libvgagl.a
+.PHONY: all clean dep
+
+libvgagl.so.$(VERSION): $(MODULES)
+	$(CC) -s -shared -Wl,-soname,libvgagl.so.$(MAJOR_VER) -o libvgagl.so.$(VERSION) \
+	  $(MODULES)
+
+libvgagl.a: $(MODULES)
+	rm -f libvgagl.a
+	$(AR) rcs libvgagl.a $(MODULES)
+
+.c.o:
+	$(CC) $(CFLAGS) -c -o $*.o $<
+
+.S.s:
+	$(CC) $(CFLAGS) -E $< >$@
+
+.s.o:
+	$(CC) $(CFLAGS) -c -o $*.o $<
+
+.c.s:
+	$(CC) $(CFLAGS) -S -o $*.s $<
+
+.o:
+	$(CC) $(CFLAGS) $(LDFLAGS) -o $* $*.o $(LIBS)
+	chmod 4755 $*
+
+$(MODULES): .depend.gl
+
+dep:
+	rm -f .depend.gl
+	make depend
+
+.depend.gl:
+	echo '# GL Module dependencies' >>.depend.gl
+	$(CC) $(INCLUDES) -MM $(patsubst %.o,%.c,$(MODULES)) >>.depend.gl
+
+clean:
+	rm -f .depend.gl *.bak *.o *~ libvgagl.a libvgagl.so.$(VERSION)
+
+#
+# include a dependency file if one exists
+#
+ifeq (.depend.gl,$(wildcard .depend.gl))
+include .depend.gl
+endif
diff --git a/haiku/vgagl/Makefile.cfg b/haiku/vgagl/Makefile.cfg
new file mode 100644
index 0000000..f726c8b
--- /dev/null
+++ b/haiku/vgagl/Makefile.cfg
@@ -0,0 +1,294 @@
+#----------------------------------------------------------------------
+# SVGAlib Compile-time configuration file
+#----------------------------------------------------------------------
+# If you change ANYTHING in here you MUST 'make clean' and remake what
+# you need.
+#
+# BEWARE! The toggle settings (INCLUDE_*_DRIVER and such) are set when
+# the symbols are set. The value is pointless. Even setting a variable
+# to n means yes!
+
+MAJOR_VER = 1
+MINOR_VER = 4.3
+VERSION = $(MAJOR_VER).$(MINOR_VER)
+
+#----------------------------------------------------------------------
+# Configuration Section
+#----------------------------------------------------------------------
+
+# Source directory.
+#srcdir = /usr/local/src/svgalib-$(VERSION)
+srcdir = $(shell sh -c pwd)
+
+confdir = $(srcdir)/src/config
+
+# Common prefix for installation directories.
+# NOTE: This directory must exist when you start the install.
+TOPDIR=
+prefix = $(TOPDIR)/boot/home/config
+exec_prefix = $(prefix)
+
+# Directory where the shared stubs and static library will be installed.
+libdir = $(exec_prefix)/lib
+
+# Directory where the shared library will be installed.
+sharedlibdir = $(prefix)/lib
+
+# Directory where the font and textmode utilities will be installed.
+bindir = $(exec_prefix)/bin
+
+# Directory where the run-time configuration files will be installed.
+datadir = $(TOPDIR)/etc/vga
+
+# Directory where the header files will be installed.
+includedir = $(prefix)/include
+
+# Directory where the man files will be installed.
+mandir = $(prefix)/man
+
+# Target binary format.
+# TARGET_FORMAT = a.out
+TARGET_FORMAT = elf
+
+#uncomment this if your compiler fails on compiling the assembler in
+#src/vgaconvplanar.c, gl/inlstring.h, gl/line.c or gl/scale.c
+NO_ASM = y
+
+# Uncomment this if you want root processes to be able to always get a new
+# VC. Alas, some games misuse suid root privs and become root, svgalib cannot
+# detect this and will allow Joe blow user to open a new virtual VC. If this
+# annoys you, comment out the next line (which is the default already)
+ROOT_VC_SHORTCUT = y
+
+# Uncomment to enable run in background mode
+# This doesn't work at all at the moment on linux-alpha-machines
+#
+# IMPORTANT NOTE: THIS ONLY WORKS WITH KERNEL >= 2.0.36 or KERNEL >= 2.1.123
+#                 and KERNEL < 2.3.27
+#                 If you compile with BACKGROUND=y, and run any
+#                 program on a machine with an old kernel, the machine
+#                 will crash hard as soon as the program tries to enter
+#                 linear mode (or even before). 
+#		  If you compile with BACKGROUND=y, and run any
+#                 program on a machine with a new kernel (>=2.3.27)
+#		  the program will fail with error message:
+#		  svgalib: mmap error in paged screen memory.
+#                 Enable this only if the resulting libraries will only be
+#                 used on 2.2 (or 2.0.36+) kernels. 
+#
+# NOTE: I found it very slow on occasion. There are several case not handled
+# optimal. (Like checking for console changes even when hardware is not
+# accessed at all). You might really consider to disable it.   (MW)
+# BACKGROUND = y
+
+# Uncomment this if you want to compile and install the static libs.
+# INSTALLSTATICLIB = installstaticlib
+
+# Comment this out if you don't want to install the shared libs.
+# If you do not install the shared nor the static libs, 'make static'
+# first to enforce just building the static lib, then the demos will
+# use this local static library!
+INSTALLSHAREDLIB = installsharedlib
+
+# In case your TARGET_FORMAT is elf and if a pre-compiled shared library
+# a.out image is available install it in the first directory named something
+# like *aout/ in /etc/ld.so.conf.
+# If you want this, do not comment out the next line:
+INSTALLAOUTLIB = installaoutcompat
+
+# Comment this out if you want to keep old shared images. Old header files,
+# library stubs and static libraries CANNOT be kept in public locations
+# except when you rename them yourself.
+# KEEPSHAREDLIBS = keep
+
+# Comment this out if you don't want to compile and install the utilities.
+INSTALLUTILS = installutils
+
+# Comment this out if you don't want to install the man pages by default
+INSTALLMAN = installman
+
+# Remove the '# ' from one of the next two lines if you want to install the
+# man pages compressed (with gzip) or not. If you comment out both lines,
+# the Makefiles will try to figure out if your system supports gzipped man
+# pages and install them when possible.
+
+# MANFORMAT = compressed
+# MANFORMAT = uncompressed
+
+# This is the command to update the man pages whatis database.
+# This is a slow command. If you are not very patient, simple
+# comment out this line
+# MAKEWHATIS = makewhatis # Beware, this will really need a few minutes!
+
+#
+# Comment out any driver that you don't want included in the library.
+#
+INCLUDE_ET4000_DRIVER = y
+INCLUDE_CIRRUS_DRIVER = y
+INCLUDE_TVGA_DRIVER = y
+#INCLUDE_OAK_DRIVER = y
+#INCLUDE_EGA_DRIVER = y
+INCLUDE_MACH32_DRIVER = y
+INCLUDE_S3_DRIVER = y
+#INCLUDE_ET3000_DRIVER = y
+#INCLUDE_GVGA6400_DRIVER = y
+#INCLUDE_ARK_DRIVER = y
+#INCLUDE_ATI_DRIVER = y
+#INCLUDE_ALI_DRIVER = y
+INCLUDE_CHIPS_DRIVER = y
+INCLUDE_APM_DRIVER = y
+INCLUDE_NV3_DRIVER = y
+INCLUDE_ET6000_DRIVER = y
+INCLUDE_VESA_DRIVER = y
+INCLUDE_MX_DRIVER = y
+INCLUDE_PARADISE_DRIVER = y
+INCLUDE_RAGE_DRIVER = y
+INCLUDE_BANSHEE_DRIVER = y
+INCLUDE_SIS_DRIVER = y
+INCLUDE_I740_DRIVER = y
+INCLUDE_LAGUNA_DRIVER = y
+INCLUDE_NEO_DRIVER = y
+INCLUDE_R128_DRIVER = y
+INCLUDE_G400_DRIVER = y
+INCLUDE_FBDEV_DRIVER = y
+INCLUDE_SAVAGE_DRIVER = y
+#
+# Comment out any adapter you don't want to autodetect.
+#
+INCLUDE_ET4000_DRIVER_TEST = y
+INCLUDE_CIRRUS_DRIVER_TEST = y
+INCLUDE_TVGA_DRIVER_TEST = y
+#INCLUDE_OAK_DRIVER_TEST = y
+#INCLUDE_EGA_DRIVER_TEST = y
+INCLUDE_MACH32_DRIVER_TEST = y
+#INCLUDE_GVGA6400_DRIVER_TEST = y
+INCLUDE_S3_DRIVER_TEST = y
+#INCLUDE_ET3000_DRIVER_TEST = y
+#INCLUDE_ARK_DRIVER_TEST = y
+#INCLUDE_ATI_DRIVER_TEST = y
+#INCLUDE_ALI_DRIVER_TEST = y
+INCLUDE_CHIPS_DRIVER_TEST = y
+INCLUDE_APM_DRIVER_TEST = y
+INCLUDE_NV3_DRIVER_TEST = y
+INCLUDE_ET6000_DRIVER_TEST = y
+INCLUDE_MX_DRIVER_TEST = y
+INCLUDE_PARADISE_DRIVER_TEST = y
+INCLUDE_RAGE_DRIVER_TEST = y
+INCLUDE_BANSHEE_DRIVER_TEST = y
+INCLUDE_SIS_DRIVER_TEST = y
+INCLUDE_I740_DRIVER_TEST = y
+INCLUDE_LAGUNA_DRIVER_TEST = y
+INCLUDE_NEO_DRIVER_TEST = y
+INCLUDE_G400_DRIVER_TEST = y
+INCLUDE_R128_DRIVER_TEST = y
+#INCLUDE_FBDEV_DRIVER_TEST = y
+INCLUDE_SAVAGE_DRIVER_TEST = y
+
+#Might be too dangerous:
+INCLUDE_VESA_DRIVER_TEST = y
+
+#
+# Comment out any dac support that you don't want included in the library.
+#
+# you must include SIERRA_DAC, if you include any of SCxxxx DACs.
+
+INCLUDE_NORMAL_DAC = y
+INCLUDE_S3_SDAC_DAC = y
+INCLUDE_S3_GENDAC_DAC = y
+INCLUDE_S3_TRIO64_DAC = y
+INCLUDE_SIERRA_DAC = y
+INCLUDE_SC15025_DAC = y
+INCLUDE_ATT20C490_DAC = y
+INCLUDE_ATT20C498_DAC = y
+INCLUDE_ICW_DAC = y
+INCLUDE_IBMRGB52x_DAC = y
+INCLUDE_SC1148X_DAC = y
+
+#
+# Comment out any dac you don't want to autodetect.
+# (not all dacs can be autodetected, at this time)
+#
+INCLUDE_S3_SDAC_DAC_TEST = y
+INCLUDE_S3_GENDAC_DAC_TEST = y
+INCLUDE_SC15025_DAC_TEST = y
+INCLUDE_ATT20C490_DAC_TEST = y
+INCLUDE_IBMRGB52x_DAC_TEST = y
+INCLUDE_SC1148X_DAC_TEST = y
+
+# Location of the svgalib configuration file.
+SVGALIB_CONFIG_FILE = $(datadir)/libvga.config
+
+# Defining DYNAMIC enables runtime parsing of the file defined by
+# ET4000_REGS (usually /etc/libvga.et4000) for the et4000 
+# driver. See et4000/README for details. Commenting this out again
+# saves binary space.
+#
+# If you just want to use the et4000.regs in the source directory,
+# comment out the definition of DYNAMIC.  DYNAMIC allows development of new
+# resolutions without recompiling.
+DYNAMIC = y
+ET4000_REGS = $(datadir)/libvga.et4000
+
+# The EGA driver may load additional modes (SuperEGA cards) like the
+# et4000 driver does. Just define the configuration file below.
+# [This should be taken with a grain of salt, EGA is untested.]
+#EGA_REGS = $(datadir)/libvga.ega
+
+# Defining USE_CLOCKS will cause the ET4000 driver to measure clock
+# frequencies (they are not actually used yet).
+#USE_CLOCKS = y
+
+# Uncomment to allow mouse type overrides
+ALLOW_MOUSE_OVERRIDE = y
+
+#----------------------------------------------------------------------
+# Compiler Section
+#----------------------------------------------------------------------
+
+# Compiler used.
+PC	 = ppc386
+
+ifndef CC
+	CC	= gcc
+#	CC	= i686-pc-linux-gnu-gcc
+#	CC      = gcc -b i486-linuxaout
+#	CC      = gcc -b i486-linux
+endif
+
+
+ifndef CFLAGS
+	OPTIMIZE = -fomit-frame-pointer -O2 -fno-strength-reduce -pipe -g
+else
+	OPTIMIZE := $(CFLAGS)
+endif
+
+# You might want to add -m386 here if you have a recently installed 
+# (486 configured) compiler on a 386. The only real difference is the
+# generous alignment padding of function entry-points for the 486.
+WARN     = 
+INCLUDES = -I$(srcdir)/include -I.
+CFLAGS   = $(WARN) $(DLLFLAGS) $(INCLUDES) $(OPTIMIZE) $(DEFINES)
+# ELF doesn't like -N. It is beneficial for small tools with a.out
+ifeq (a.out, $(TARGET_FORMAT))
+	LDFLAGS   = -N -s
+else
+	LDFLAGS   = -s
+endif
+
+# Uncomment the following if you are compiling a.out shared libraries
+# with an ELF ld.
+#
+#MKIMAGEFLAGS = -m i386linux -oformat a.out-i386-linux -qmagic
+
+# additional flags for shared lib.
+ifeq (a.out, $(TARGET_FORMAT))
+	DLLFLAGS = -B/usr/dll/jump/
+else
+	DLLFLAGS = -fPIC
+endif
+
+# Utilites used.
+AR	  = ar
+INSTALL_PROGRAM	= install -c -s -m 755 -o root -g bin
+INSTALL_SHLIB	= install -c -m 755 -o root -g bin
+INSTALL_DATA	= install -c -m 644 -o root -g bin
diff --git a/haiku/vgagl/_mem.S b/haiku/vgagl/_mem.S
new file mode 100644
index 0000000..8893da0
--- /dev/null
+++ b/haiku/vgagl/_mem.S
@@ -0,0 +1,481 @@
+#define __ASSEMBLY__
+#include <linux/linkage.h>
+
+#ifndef	SYMBOL_NAME
+#define	SYMBOL_NAME(name)	_ ## name
+#endif
+#ifndef ENTRY
+#define ENTRY(name) .align 4; .globl _ ## name ## ; _ ## name ## :
+#endif
+	
+	.file "mem.S"
+
+ /* This file contains unrolled memcpy functions. */
+
+
+ /* Prototype: memcpy4to3( void *dest, void *src, int n ) */
+ /* Copies pixels from 4-byte-per-pixel screen to 3-byte-per-pixel screen,
+*/
+ /* discarding the last byte of each pixel. */
+ /* Only uses 32-bit aligned word accesses. */
+ /* Instructions have been shuffled a bit for possible avoidance of */
+ /* pipeline hazards. */
+
+.text
+ENTRY(memcpy4to3)
+	pushl %ebp
+	movl %esp,%ebp
+	pushl %edi
+	pushl %esi
+	pushl %ebx
+	pushl %ecx
+	movl 8(%ebp),%edi	/* destination address */
+	movl 12(%ebp),%esi	/* source address */
+	movl 16(%ebp),%ecx	/* number of pixels */
+
+	/* Handle chunks of 8 pixels. */
+1:	cmpl $8,%ecx
+	jl 2f
+
+	movl (%esi),%eax	/* pixel 0 */
+	movl 4(%esi),%ebx	/* pixel 1 */
+	shll $8,%eax		/* BGR0 in 8-31 */
+	shrd $8,%ebx,%eax	/* BGR0 in 0-23, B1 in 24-31 */
+	movl %eax,(%edi)	/* write word */
+	shll $8,%ebx		/* GR1 in 16-31 */
+	movl 8(%esi),%eax	/* pixel 2 */
+	shrd $16,%eax,%ebx	/* GR1 in 0-15, BG2 in 16-31 */
+	movl %ebx,4(%edi)	/* write word */
+	shll $8,%eax		/* move R2 into 24-31 */
+	movl 12(%esi),%ebx	/* pixel 3 */
+	shrd $24,%ebx,%eax	/* R2 in 0-7, BGR3 in 8-31 */
+	movl %eax,8(%edi)	/* write word */
+
+	movl 16(%esi),%eax	/* pixel 4 */
+	shll $8,%eax		/* BGR4 in 8-31 */
+	movl 20(%esi),%ebx	/* pixel 5 */
+	shrd $8,%ebx,%eax	/* BGR4 in 0-23, B5 in 24-31 */
+	movl %eax,12(%edi)	/* write word */
+	shll $8,%ebx		/* GR5 in 16-31 */
+	movl 24(%esi),%eax	/* pixel 6 */
+	shrd $16,%eax,%ebx	/* GR5 in 0-15, BG6 in 16-31 */
+	movl %ebx,16(%edi)	/* write word */
+	subl $8,%ecx		/* blended end-of-loop instruction */
+	shll $8,%eax		/* move R6 into 24-31 */
+	movl 28(%esi),%ebx	/* pixel 7 */
+	shrd $24,%ebx,%eax	/* R6 in 0-7, BGR7 in 8-31 */
+	addl $32,%esi		/* blended end-of-loop instruction */
+	movl %eax,20(%edi)	/* write word */
+
+	addl $24,%edi
+	jmp 1b
+
+2:	/* Do the remaining pixels. */
+
+	andl %ecx,%ecx
+	jz 4f			/* none left */
+
+3:	movl (%esi),%eax
+	movw %eax,(%edi)
+	shrl $16,%eax
+	movb %al,2(%edi)
+	addl $4,%esi
+	addl $3,%edi
+	decl %ecx
+	jnz 3b
+
+4:
+	popl %ecx
+	popl %ebx
+	popl %esi
+	popl %edi
+	popl %ebp
+	ret
+
+ /* Prototype: memcpy32shift8( void *dest, void *src, int n ) */
+ /* Copies pixels from 4-byte-per-pixel screen organized as BGR0 to */
+ /* 0BGR 4-byte-per-pixel screen. */
+ /* Used by copyscreen for ATI mach32 32-bit truecolor modes. */
+
+.text
+ENTRY(memcpy32shift8)
+	pushl %ebp
+	movl %esp,%ebp
+	pushl %edi
+	pushl %esi
+	pushl %ecx
+	pushl %ebx
+	movl 8(%ebp),%edi	/* destination address */
+	movl 12(%ebp),%esi	/* source address */
+	movl 16(%ebp),%ecx	/* number of pixels */
+
+	/* Handle chunks of 8 pixels. */
+1:	cmpl $8,%ecx
+	jl 2f
+
+	movl (%esi),%eax
+	shll $8,%eax
+	movl %eax,(%edi)
+	movl 4(%esi),%edx
+	shll $8,%edx
+	movl %edx,4(%edi)
+	movl 8(%esi),%eax
+	shll $8,%eax
+	movl %eax,8(%edi)
+	movl 12(%esi),%edx
+	shll $8,%edx
+	movl %edx,12(%edi)
+	movl 16(%esi),%eax
+	shll $8,%eax
+	movl %eax,16(%edi)
+	movl 20(%esi),%edx
+	shll $8,%edx
+	movl %edx,20(%edi)
+	movl 24(%esi),%eax
+	subl $8,%ecx
+	shll $8,%eax
+	movl %eax,24(%edi)
+	movl 28(%esi),%edx
+	addl $32,%esi
+	shll $8,%edx
+	movl %edx,28(%edi)
+	addl $32,%edi
+	jmp 1b
+
+2:	andl %ecx,%ecx
+	jz 4f
+
+3:	movl (%esi),%eax
+	shll $8,%eax
+	movl %eax,(%edi)
+	addl $4,%esi
+	addl $4,%edi
+	decl %ecx
+	jnz 3b
+
+4:	
+	popl %ebx
+	popl %ecx
+	popl %esi
+	popl %edi
+	popl %ebp
+	ret
+
+
+/* Optimized memcpy. */
+/* Performance on par with inlined 32-bit aligned rep movsl on slow */
+/* motherboard. */
+/* Hypothesized to be fast on motherboards that handle writes efficiently */
+/* and suffer with slow rep movsl microcode in 486/Pentium. */
+/* (esp. Cyrix 486DX WB, Headland HTK 486 chipset, Pentium). */
+
+/* Arguments passed in registers: */
+/* destination address in %esi */
+/* source address in %edx */
+/* count in %ecx */
+
+#define MOVEBYTE(n) movb n(%edx),%al; movb %al,n(%esi)
+
+#define MOVESHORT(n) movw n(%edx),%ax; movw %ax,n(%esi)
+
+#define MOVEWORD(n) movl n(%edx),%eax; movl %eax,n(%esi)
+
+ENTRY(_memcpy_jumptable)
+	.long copy0
+	.long copy1, copy2, copy3, copy4
+	.long copy5, copy6, copy7, copy8
+	.long copy9, copy10, copy11, copy12
+	.long copy13, copy14, copy15, copy16
+	.long copy17, copy18, copy19, copy20
+	.long copy21, copy22, copy23, copy24
+	.long copy25, copy26, copy27, copy28
+	.long copy29, copy30, copy31, copy32
+
+jumptable2:
+	.long align0, align1, align2, align3
+
+ENTRY(_memcpyasm_regargs)
+
+	/* This is only valid if nu_bytes >= 3. */
+
+	/* Align destination to 32-bit boundary */
+	movl %esi,%eax
+	andl $3,%eax
+	jmp *jumptable2(,%eax,4)
+
+align1:	MOVESHORT(0)
+	MOVEBYTE(2)
+	addl $3,%edx
+	addl $3,%esi
+	subl $3,%ecx
+	jmp copyaligned
+
+align3:	MOVEBYTE(0)
+	incl %edx
+	incl %esi
+	decl %ecx
+	jmp copyaligned
+
+align2:	MOVESHORT(0)
+	addl $2,%edx
+	addl $2,%esi
+	subl $2,%ecx
+align0:
+
+copyaligned:
+	cmpl $32,%ecx
+	ja copyunrolled
+	/* <= 32 bytes. */
+	/* Copy remaining bytes (0-32). */
+	jmp *SYMBOL_NAME(_memcpy_jumptable)(,%ecx,4)
+	.align 4,0x90
+
+/* memcpyasm_regargs_aligned is only called if nu_bytes > 32. */
+ENTRY(_memcpyasm_regargs_aligned)
+
+copyunrolled:	
+	/* Copy chunks of 32 bytes. */
+	/* End-of-loop increment instructions blended in. */
+	addl $32,%esi			/*P ok */
+	movl (%edx),%eax
+	movl %eax,(0-32)(%esi)		/*P ok */
+	movl 4(%edx),%eax
+	movl %eax,(4-32)(%esi)		/*P ok */
+	movl 8(%edx),%eax
+	movl %eax,(8-32)(%esi)		/*P ok */
+	movl 12(%edx),%eax
+	movl %eax,(12-32)(%esi)		/*P ok */
+	movl 16(%edx),%eax
+	addl $32,%edx			/*P ok */
+	movl %eax,(16-32)(%esi)
+	subl $32,%ecx			/*P ok */
+	movl (20-32)(%edx),%eax
+	movl %eax,(20-32)(%esi)		/*P ok */
+	movl (24-32)(%edx),%eax
+	movl %eax,(24-32)(%esi)		/*P ok */
+	movl (28-32)(%edx),%eax
+	movl %eax,(28-32)(%esi)		/*P ok */
+	cmpl $32,%ecx
+	jge copyunrolled		/*P fail */
+	/* Copy remaining bytes (less than 32). */
+	jmp *SYMBOL_NAME(_memcpy_jumptable)(,%ecx,4)
+
+#define END ret
+
+copy0:	END
+
+copy1:	MOVEBYTE(0)
+	END
+
+copy2:	MOVESHORT(0)
+	END
+
+copy3:	MOVESHORT(0)
+	MOVEBYTE(2)
+	END
+
+copy4:	MOVEWORD(0)
+	END
+
+copy5:	MOVEWORD(0)
+	MOVEBYTE(4)
+	END
+
+copy6:	MOVEWORD(0)
+	MOVESHORT(4)
+	END
+
+copy7:	MOVEWORD(0)
+	MOVESHORT(4)
+	MOVEBYTE(6)
+	END
+
+copy8:	MOVEWORD(0)
+	MOVEWORD(4)
+	END
+
+copy9:	MOVEWORD(0)
+	MOVEWORD(4)
+	MOVEBYTE(8)
+	END
+
+copy10:	MOVEWORD(0)
+	MOVEWORD(4)
+	MOVESHORT(8)
+	END
+
+copy11:	MOVEWORD(0)
+	MOVEWORD(4)
+	MOVESHORT(8)
+	MOVEBYTE(10)
+	END
+
+copy12:	MOVEWORD(0)
+	MOVEWORD(4)
+	MOVEWORD(8)
+	END
+
+copy13:	MOVEWORD(0)
+	MOVEWORD(4)
+	MOVEWORD(8)
+	MOVEBYTE(12)
+	END
+
+copy14:	MOVEWORD(0)
+	MOVEWORD(4)
+	MOVEWORD(8)
+	MOVESHORT(12)
+	END
+
+copy15:	MOVEWORD(0)
+	MOVEWORD(4)
+	MOVEWORD(8)
+	MOVESHORT(12)
+	MOVEBYTE(14)
+	END
+
+copy16:	MOVEWORD(0)
+	MOVEWORD(4)
+	MOVEWORD(8)
+	MOVEWORD(12)
+	END
+
+copy17:	MOVEWORD(0)
+	MOVEWORD(4)
+	MOVEWORD(8)
+	MOVEWORD(12)
+	MOVEBYTE(16)
+	END
+
+copy18:	MOVEWORD(0)
+	MOVEWORD(4)
+	MOVEWORD(8)
+	MOVEWORD(12)
+	MOVESHORT(16)
+	END
+
+copy19:	MOVEWORD(0)
+	MOVEWORD(4)
+	MOVEWORD(8)
+	MOVEWORD(12)
+	MOVESHORT(16)
+	MOVEBYTE(18)
+	END
+
+copy20:	MOVEWORD(0)
+	MOVEWORD(4)
+	MOVEWORD(8)
+	MOVEWORD(12)
+	MOVEWORD(16)
+	END
+
+copy21:	MOVEWORD(0)
+	MOVEWORD(4)
+	MOVEWORD(8)
+	MOVEWORD(12)
+	MOVEWORD(16)
+	MOVEBYTE(20)
+	END
+
+copy22:	MOVEWORD(0)
+	MOVEWORD(4)
+	MOVEWORD(8)
+	MOVEWORD(12)
+	MOVEWORD(16)
+	MOVESHORT(20)
+	END
+
+copy23:	MOVEWORD(0)
+	MOVEWORD(4)
+	MOVEWORD(8)
+	MOVEWORD(12)
+	MOVEWORD(16)
+	MOVESHORT(20)
+	MOVEBYTE(22)
+	END
+
+copy24:	MOVEWORD(0)
+	MOVEWORD(4)
+	MOVEWORD(8)
+	MOVEWORD(12)
+	MOVEWORD(16)
+	MOVEWORD(20)
+	END
+
+copy25:	MOVEWORD(0)
+	MOVEWORD(4)
+	MOVEWORD(8)
+	MOVEWORD(12)
+	MOVEWORD(16)
+	MOVEWORD(20)
+	MOVEBYTE(24)
+	END
+
+copy26:	MOVEWORD(0)
+	MOVEWORD(4)
+	MOVEWORD(8)
+	MOVEWORD(12)
+	MOVEWORD(16)
+	MOVEWORD(20)
+	MOVESHORT(24)
+	END
+
+copy27:	MOVEWORD(0)
+	MOVEWORD(4)
+	MOVEWORD(8)
+	MOVEWORD(12)
+	MOVEWORD(16)
+	MOVEWORD(20)
+	MOVESHORT(24)
+	MOVEBYTE(26)
+	END
+
+copy28:	MOVEWORD(0)
+	MOVEWORD(4)
+	MOVEWORD(8)
+	MOVEWORD(12)
+	MOVEWORD(16)
+	MOVEWORD(20)
+	MOVEWORD(24)
+	END
+
+copy29:	MOVEWORD(0)
+	MOVEWORD(4)
+	MOVEWORD(8)
+	MOVEWORD(12)
+	MOVEWORD(16)
+	MOVEWORD(20)
+	MOVEWORD(24)
+	MOVEBYTE(28)
+	END
+
+copy30:	MOVEWORD(0)
+	MOVEWORD(4)
+	MOVEWORD(8)
+	MOVEWORD(12)
+	MOVEWORD(16)
+	MOVEWORD(20)
+	MOVEWORD(24)
+	MOVESHORT(28)
+	END
+
+copy31:	MOVEWORD(0)
+	MOVEWORD(4)
+	MOVEWORD(8)
+	MOVEWORD(12)
+	MOVEWORD(16)
+	MOVEWORD(20)
+	MOVEWORD(24)
+	MOVESHORT(28)
+	MOVEBYTE(30)
+	END
+
+copy32:	MOVEWORD(0)
+	MOVEWORD(4)
+	MOVEWORD(8)
+	MOVEWORD(12)
+	MOVEWORD(16)
+	MOVEWORD(20)
+	MOVEWORD(24)
+	MOVEWORD(28)
+	END
diff --git a/haiku/vgagl/cbitmap.c b/haiku/vgagl/cbitmap.c
new file mode 100644
index 0000000..4826bd9
--- /dev/null
+++ b/haiku/vgagl/cbitmap.c
@@ -0,0 +1,186 @@
+/* Framebuffer Graphics Libary for Linux, Copyright 1993 Harm Hanemaayer */
+/* cbitmap.c    Compiled bitmaps */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <vga.h>
+#include "inlstring.h"		/* include inline string operations */
+
+#include "vgagl.h"
+#include "def.h"
+
+
+
+void gl_compileboxmask(int w, int h, void *_dp1, void *_dp2)
+{
+/* Compiled format: <bytes_to_skip (0-254)><number_of_pixels (0-255)> */
+/*                  <pixel_data>[<end_of_line(255)>]... */
+    uchar *dp1 = _dp1;
+    uchar *dp2 = _dp2;
+    int i;
+    for (i = 0; i < h; i++) {
+	int x = 0;
+	while (x < w) {
+	    int count;
+	    /* count zeroes */
+	    count = 0;
+	    while (x < w && *(dp1 + count) == 0 && count < 254) {
+		count++;
+		x++;
+	    }
+	    dp1 += count;
+	    if (x < w) {
+		*dp2++ = count;
+		/* count nonzeroes */
+		count = 0;
+		while (x < w && *(dp1 + count) != 0 && count < 255) {
+		    *(dp2 + count + 1) = *(dp1 + count);
+		    count++;
+		    x++;
+		}
+		*dp2 = count;
+		dp2 += count + 1;
+		dp1 += count;
+	    }
+	}
+	*dp2++ = 0xff;
+    }
+}
+
+int gl_compiledboxmasksize(int w, int h, void *_dp1)
+{
+/* Compiled format: <bytes_to_skip (0-254)><number_of_pixels (0-255)> */
+/*                  <pixel_data>[<end_of_line(255)>]... */
+    uchar *dp1 = _dp1;
+    int size = 0;
+    int i;
+    for (i = 0; i < h; i++) {
+	int x = 0;
+	while (x < w) {
+	    int count;
+	    /* count zeroes */
+	    count = 0;
+	    while (x < w && *(dp1 + count) == 0 && count < 254) {
+		count++;
+		x++;
+	    }
+	    size++;
+	    dp1 += count;
+	    /* count nonzeroes */
+	    if (x < w) {
+		count = 0;
+		while (x < w && *(dp1 + count) != 0 && count < 255) {
+		    count++;
+		    x++;
+		}
+		size += count + 1;
+		dp1 += count;
+	    }
+	}
+	size++;
+    }
+    return size;
+}
+
+static void gl_putboxmaskcompiledclip(int nx, int ny, int nw, int nh, int _x,
+				      int _y, int w, int h, void *_dp)
+{
+/* Special case costly clipping */
+    uchar *dp = _dp;
+    uchar *vp, *vpline;
+    int y;
+    vpline = VBUF + _y * BYTEWIDTH + _x;
+    for (y = _y; y < ny + nh; y++) {
+	int x = _x;
+	vp = vpline;
+	for (;;) {
+	    int count = *dp++;
+	    if (count == 0xff)
+		break;		/* end of line */
+	    vp += count;
+	    x += count;
+	    count = *dp++;
+	    /* __memcpy gives severe bug here */
+	    if (y >= ny) {
+		if (x >= nx)
+		    if (x + count > __clipx2 + 1) {
+			if (x <= __clipx2)
+			    __memcpyb(vp, dp, __clipx2 - x + 1);
+		    } else
+			__memcpyb(vp, dp, count);
+		else if (x + count > __clipx1) {
+		    if (x + count > __clipx2 + 1)
+			__memcpyb(vp + __clipx1 - x,
+				  dp + __clipx1 - x,
+				  __clipx2 - __clipx1 + 1);
+		    else
+			__memcpy(vp + __clipx1 - x,
+				 dp + __clipx1 - x,
+				 count - __clipx1 + x);
+                };
+            };
+	    x += count;
+	    vp += count;
+	    dp += count;
+	}
+	vpline += BYTEWIDTH;
+    }
+}
+
+#define ADJUSTBITMAPBOX() \
+	nw = w; nh = h; nx = x; ny = y;				\
+	if (nx + nw < __clipx1 || nx > __clipx2)		\
+		return;						\
+	if (ny + nh < __clipy1 || ny > __clipy2)		\
+		return;						\
+	if (nx < __clipx1) {		/* left adjust */	\
+		nw += nx - __clipx1;				\
+		nx = __clipx1;					\
+	}							\
+	if (ny < __clipy1) {		/* top adjust */	\
+		nh += ny - __clipy1;				\
+		ny = __clipy1;					\
+	}							\
+	if (nx + nw > __clipx2)		/* right adjust */	\
+		nw = __clipx2 - nx + 1;				\
+	if (ny + nh > __clipy2)		/* bottom adjust */	\
+		nh = __clipy2 - ny + 1;				\
+
+
+void gl_putboxmaskcompiled(int x, int y, int w, int h, void *_dp)
+{
+/* no clipping */
+    uchar *dp = _dp;
+    uchar *vp, *vpline;
+    int i;
+    if (MODETYPE != CONTEXT_LINEAR && MODETYPE != CONTEXT_VIRTUAL) {
+	printf("vgagl: putboxmaskcompiled only supported in linear framebuffer\n");
+	return;
+    }
+    if (__clip) {
+	int nx, ny, nw, nh;
+	ADJUSTBITMAPBOX();
+	if (nw != w || nh != h) {
+	    gl_putboxmaskcompiledclip(nx, ny, nw, nh, x, y, w, h,
+				      dp);
+	    return;
+	}
+    }
+    vpline = VBUF + y * BYTEWIDTH + x;
+    for (i = 0; i < h; i++) {
+	vp = vpline;
+	for (;;) {
+	    int count = *dp++;
+	    if (count == 0xff)
+		break;		/* end of line */
+	    vp += count;
+	    count = *dp++;
+	    /* __memcpy gives severe bug here */
+	    __memcpyb(vp, dp, count);
+	    vp += count;
+	    dp += count;
+	}
+	vpline += BYTEWIDTH;
+    }
+}
diff --git a/haiku/vgagl/def.h b/haiku/vgagl/def.h
new file mode 100644
index 0000000..e3540f0
--- /dev/null
+++ b/haiku/vgagl/def.h
@@ -0,0 +1,72 @@
+
+
+#define uchar unsigned char
+#define swap(x, y) { int temp = x; x = y; y = temp; }
+#define swapb(x, y) { uchar temp = x; x = y; y = temp; }
+#define max(x, y) ((x > y) ? x : y)
+#define min(x, y) ((x > y) ? y : x)
+#define outside(x, y) (x < __clipx1 || x > __clipx2 || y < __clipy1 \
+	|| y > __clipy2)
+#define x_outside(x) (x < __clipx1 || x > __clipx2)
+#define y_outside(y) (y < __clipy1 || y > __clipy2)
+#define clipxleft(x) if (x < __clipx1) x = __clipx1;
+#define clipxright(x) if (x > __clipx2) x = __clipx2;
+#define clipytop(y) if (y < __clipy1) y = __clipy1;
+#define clipybottom(y) if (y > __clipy2) y = __clipy2;
+
+
+#define setpixel (*(__currentcontext.ff.driver_setpixel_func))
+#define getpixel (*(__currentcontext.ff.driver_getpixel_func))
+#define hline (*(__currentcontext.ff.driver_hline_func))
+#define fillbox (*(__currentcontext.ff.driver_fillbox_func))
+#define putbox (*(__currentcontext.ff.driver_putbox_func))
+#define getbox (*(__currentcontext.ff.driver_getbox_func))
+#define putboxmask (*(__currentcontext.ff.driver_putboxmask_func))
+#define putboxpart (*(__currentcontext.ff.driver_putboxpart_func))
+#define getboxpart (*(__currentcontext.ff.driver_getboxpart_func))
+#define copybox (*(__currentcontext.ff.driver_copybox_func))
+
+#define TEXT_TABSIZE 8
+
+#ifdef DLL_CONTEXT_SHADOW
+
+/* Library uses internal currentcontext for faster DLL library. */
+
+#undef BYTESPERPIXEL
+#undef BYTEWIDTH
+#undef WIDTH
+#undef HEIGHT
+#undef VBUF
+#undef MODETYPE
+#undef MODEFLAGS
+#undef BITSPERPIXEL
+#undef COLORS
+#undef __clip
+#undef __clipx1
+#undef __clipy1
+#undef __clipx2
+#undef __clipy2
+
+extern GraphicsContext __currentcontext;
+
+#define BYTESPERPIXEL (__currentcontext.bytesperpixel)
+#define BYTEWIDTH (__currentcontext.bytewidth)
+#define WIDTH (__currentcontext.width)
+#define HEIGHT (__currentcontext.height)
+#define VBUF (__currentcontext.vbuf)
+#define MODETYPE (__currentcontext.modetype)
+#define MODEFLAGS (__currentcontext.modeflags)
+#define BITSPERPIXEL (__currentcontext.bitsperpixel)
+#define COLORS (__currentcontext.colors)
+
+#define __clip (__currentcontext.clip)
+#define __clipx1 (__currentcontext.clipx1)
+#define __clipy1 (__currentcontext.clipy1)
+#define __clipx2 (__currentcontext.clipx2)
+#define __clipy2 (__currentcontext.clipy2)
+
+#else
+
+#define __currentcontext currentcontext
+
+#endif
diff --git a/haiku/vgagl/driver.c b/haiku/vgagl/driver.c
new file mode 100644
index 0000000..cfdc4e4
--- /dev/null
+++ b/haiku/vgagl/driver.c
@@ -0,0 +1,1374 @@
+/* driver.c     Framebuffer primitives */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <vga.h>
+
+#include "inlstring.h"		/* include inline string operations */
+#include "vgagl.h"
+#include "def.h"
+#include "driver.h"
+
+
+#define MAXBYTEWIDTH 4096	/* used in bitblt emulation */
+
+/* All functions that simply call another function with slightly different
+ * parameter values are declared inline. */
+#define INLINE inline
+
+#define NOTIMPL(s) { notimplemented(s); return; }
+
+/* in: vp = video offset; out: rvp = video pointer, chunksize, page */
+#define SETWRITEPAGED(vp, rvp, chunksize, page) \
+	page = vp >> 16; \
+	vga_setpage(page); \
+	rvp = (vp & 0xffff) + VBUF; \
+	chunksize = 0x10000 - (vp & 0xffff);
+
+static inline int RGB2BGR(int c)
+{
+/* a bswap would do the same as the first 3 but in only ONE! cycle. */
+/* However bswap is not supported by 386 */
+
+    if (MODEFLAGS & MODEFLAG_24BPP_REVERSED)
+	c = ((c >> 0) & 0xff) << 16 |
+	    ((c >> 8) & 0xff) << 8 |
+	    ((c >> 16) & 0xff) << 0;
+
+    return c;
+}
+
+/* RGB_swapped_memcopy returns the amount of bytes unhandled */
+static inline int RGB_swapped_memcpy(char *dest, char *source, int len)
+{
+    int rest, tmp;
+
+    tmp = len / 3;
+    rest = len - 3 * tmp;
+    len = tmp;
+
+    while (len--) {
+	*dest++ = source[2];
+	*dest++ = source[1];
+	*dest++ = source[0];
+	source += 3;
+    }
+
+    return rest;
+}
+
+static void notimplemented(char *s)
+{
+    printf("vgagl: %s not implemented.\n", s);
+}
+
+
+
+/* One byte per pixel frame buffer primitives */
+
+#define ASSIGNVP8(x, y, vp) vp = VBUF + (y) * BYTEWIDTH + (x);
+#define ASSIGNVPOFFSET8(x, y, vp) vp = (y) * BYTEWIDTH + (x);
+
+void __svgalib_driver8_setpixel(int x, int y, int c)
+{
+#ifdef __alpha__
+    vga_setcolor(c);
+    vga_drawpixel(x, y);
+#else
+    char *vp;
+    ASSIGNVP8(x, y, vp);
+    *vp = c;
+#endif
+}
+
+void __svgalib_driver8p_setpixel(int x, int y, int c)
+{
+    int vp;
+    ASSIGNVPOFFSET8(x, y, vp);
+    vga_setpage(vp >> 16);
+    *(VBUF + (vp & 0xffff)) = c;
+}
+
+int __svgalib_driver8_getpixel(int x, int y)
+{
+    char *vp;
+    ASSIGNVP8(x, y, vp);
+    return *vp;
+}
+
+int __svgalib_driver8p_getpixel(int x, int y)
+{
+    int vp;
+    ASSIGNVPOFFSET8(x, y, vp);
+    vga_setpage(vp >> 16);
+    return *(VBUF + (vp & 0xffff));
+}
+
+void __svgalib_driver8_hline(int x1, int y, int x2, int c)
+{
+    char *vp;
+    ASSIGNVP8(x1, y, vp);
+    __memset(vp, c, x2 - x1 + 1);
+}
+
+void __svgalib_driver8p_hline(int x1, int y, int x2, int c)
+{
+    int vp;
+    char *rvp;
+    int l;
+    int chunksize, page;
+    ASSIGNVPOFFSET8(x1, y, vp);
+    SETWRITEPAGED(vp, rvp, chunksize, page);
+    l = x2 - x1 + 1;
+    if (l <= chunksize)
+	__memset(rvp, c, l);
+    else {
+	__memset(rvp, c, chunksize);
+	vga_setpage(page + 1);
+	__memset(VBUF, c, l - chunksize);
+    }
+}
+
+void __svgalib_driver8_fillbox(int x, int y, int w, int h, int c)
+{
+    char *vp;
+    int i;
+    ASSIGNVP8(x, y, vp);
+    for (i = 0; i < h; i++) {
+	__memset(vp, c, w);
+	vp += BYTEWIDTH;
+    }
+}
+
+void __svgalib_driver8a_fillbox(int x, int y, int w, int h, int c)
+{
+    if (w * h < 128)
+	(*__svgalib_nonaccel_fillbox)(x, y, w, h, c);
+    else {
+	vga_accel(ACCEL_SETFGCOLOR, c);
+	vga_accel(ACCEL_FILLBOX, x, y, w, h);
+    }
+}
+
+void __svgalib_driver8p_fillbox(int x, int y, int w, int h, int c)
+{
+    int vp;
+    int page;
+    int i;
+    ASSIGNVPOFFSET8(x, y, vp);
+    page = vp >> 16;
+    vp &= 0xffff;
+    vga_setpage(page);
+    for (i = 0; i < h; i++) {
+	if (vp + w > 0x10000) {
+	    if (vp >= 0x10000) {
+		page++;
+		vga_setpage(page);
+		vp &= 0xffff;
+	    } else {		/* page break within line */
+		__memset(VBUF + vp, c, 0x10000 - vp);
+		page++;
+		vga_setpage(page);
+		__memset(VBUF, c, (vp + w) & 0xffff);
+		vp = (vp + BYTEWIDTH) & 0xffff;
+		continue;
+	    }
+        };
+	__memset(VBUF + vp, c, w);
+	vp += BYTEWIDTH;
+    }
+}
+
+void __svgalib_driver8_putbox(int x, int y, int w, int h, void *b, int bw)
+{
+    char *vp;			/* screen pointer */
+    char *bp;			/* bitmap pointer */
+    int i;
+    ASSIGNVP8(x, y, vp);
+    bp = b;
+    for (i = 0; i < h; i++) {
+	__memcpy(vp, bp, w);
+	bp += bw;
+	vp += BYTEWIDTH;
+    }
+}
+
+void __svgalib_driver8p_putbox(int x, int y, int w, int h, void *b, int bw)
+{
+/* extra argument width of source bitmap, so that putboxpart can use this */
+    int vp;
+    int page;
+    char *bp = b;
+    int i;
+    ASSIGNVPOFFSET8(x, y, vp);
+    page = vp >> 16;
+    vp &= 0xffff;
+    vga_setpage(page);
+    for (i = 0; i < h; i++) {
+	if (vp + w > 0x10000) {
+	    if (vp >= 0x10000) {
+		page++;
+		vga_setpage(page);
+		vp &= 0xffff;
+	    } else {		/* page break within line */
+		__memcpy(VBUF + vp, bp, 0x10000 - vp);
+		page++;
+		vga_setpage(page);
+		__memcpy(VBUF, bp + 0x10000 - vp,
+			 (vp + w) & 0xffff);
+		vp = (vp + BYTEWIDTH) & 0xffff;
+		bp += bw;
+		continue;
+	    }
+        };
+	__memcpy(VBUF + vp, bp, w);
+	bp += bw;
+	vp += BYTEWIDTH;
+    }
+}
+
+void __svgalib_driver8_getbox(int x, int y, int w, int h, void *b, int bw)
+{
+    char *vp;			/* screen pointer */
+    char *bp;			/* bitmap pointer */
+    int i;
+    ASSIGNVP8(x, y, vp);
+    bp = b;
+    for (i = 0; i < h; i++) {
+	__memcpy(bp, vp, w);
+	bp += bw;
+	vp += BYTEWIDTH;
+    }
+}
+
+void __svgalib_driver8p_getbox(int x, int y, int w, int h, void *b, int bw)
+{
+    int vp;
+    int page;
+    char *bp = b;
+    int i;
+    ASSIGNVPOFFSET8(x, y, vp);
+    page = vp >> 16;
+    vp &= 0xffff;
+    vga_setpage(page);
+    for (i = 0; i < h; i++) {
+	if (vp + w > 0x10000) {
+	    if (vp >= 0x10000) {
+		page++;
+		vga_setpage(page);
+		vp &= 0xffff;
+	    } else {		/* page break within line */
+		__memcpy(bp, VBUF + vp, 0x10000 - vp);
+		page++;
+		vga_setpage(page);
+		__memcpy(bp + 0x10000 - vp, VBUF,
+			 (vp + w) & 0xffff);
+		vp = (vp + BYTEWIDTH) & 0xffff;
+		bp += bw;
+		continue;
+	    }
+        };
+	__memcpy(bp, VBUF + vp, w);
+	bp += bw;
+	vp += BYTEWIDTH;
+    }
+}
+
+void __svgalib_driver8_putboxmask(int x, int y, int w, int h, void *b)
+{
+    uchar *bp = b;
+    uchar *vp;
+    int i;
+    ASSIGNVP8(x, y, vp);
+    for (i = 0; i < h; i++) {
+	uchar *endoflinebp = bp + w;
+	while (bp < endoflinebp - 3) {
+	    unsigned int c4 = *(unsigned int *) bp;
+	    if (c4 & 0xff)
+		*vp = (uchar) c4;
+	    c4 >>= 8;
+	    if (c4 & 0xff)
+		*(vp + 1) = (uchar) c4;
+	    c4 >>= 8;
+	    if (c4 & 0xff)
+		*(vp + 2) = (uchar) c4;
+	    c4 >>= 8;
+	    if (c4 & 0xff)
+		*(vp + 3) = (uchar) c4;
+	    bp += 4;
+	    vp += 4;
+	}
+	while (bp < endoflinebp) {
+	    uchar c = *bp;
+	    if (c)
+		*vp = c;
+	    bp++;
+	    vp++;
+	}
+	vp += BYTEWIDTH - w;
+    }
+}
+
+void __svgalib_driver8_putboxpart(int x, int y, int w, int h, int ow, int oh,
+			void *b, int xo, int yo)
+{
+    __svgalib_driver8_putbox(x, y, w, h, b + yo * ow + xo, ow);	/* inlined */
+}
+
+void __svgalib_driver8p_putboxpart(int x, int y, int w, int h, int ow, int oh,
+			 void *b, int xo, int yo)
+{
+    __svgalib_driver8p_putbox(x, y, w, h, b + yo * ow + xo, ow);	/* inlined */
+}
+
+void __svgalib_driver8_getboxpart(int x, int y, int w, int h, int ow, int oh,
+			void *b, int xo, int yo)
+{
+    __svgalib_driver8_getbox(x, y, w, h, b + yo * ow + xo, ow);
+}
+
+void __svgalib_driver8p_getboxpart(int x, int y, int w, int h, int ow, int oh,
+			 void *b, int xo, int yo)
+{
+    __svgalib_driver8p_getbox(x, y, w, h, b + yo * ow + xo, ow);
+}
+
+void __svgalib_driver8_copybox(int x1, int y1, int w, int h, int x2, int y2)
+{
+    char *svp, *dvp;
+    /* I hope this works now. */
+    if (y1 >= y2) {
+	if (y1 == y2 && x2 >= x1) {	/* tricky */
+	    int i;
+	    if (x1 == x2)
+		return;
+	    /* use a temporary buffer to store a line */
+	    /* using reversed movs would be much faster */
+	    ASSIGNVP8(x1, y1, svp);
+	    ASSIGNVP8(x2, y2, dvp);
+	    for (i = 0; i < h; i++) {
+		uchar linebuf[MAXBYTEWIDTH];
+		__memcpy(linebuf, svp, w);
+		__memcpy(dvp, linebuf, w);
+		svp += BYTEWIDTH;
+		dvp += BYTEWIDTH;
+	    }
+	} else {		/* copy from top to bottom */
+	    int i;
+	    ASSIGNVP8(x1, y1, svp);
+	    ASSIGNVP8(x2, y2, dvp);
+	    for (i = 0; i < h; i++) {
+		__memcpy(dvp, svp, w);
+		svp += BYTEWIDTH;
+		dvp += BYTEWIDTH;
+	    }
+	}
+    } else {			/* copy from bottom to top */
+	int i;
+	ASSIGNVP8(x1, y1 + h, svp);
+	ASSIGNVP8(x2, y2 + h, dvp);
+	for (i = 0; i < h; i++) {
+	    svp -= BYTEWIDTH;
+	    dvp -= BYTEWIDTH;
+	    __memcpy(dvp, svp, w);
+	}
+    }
+}
+
+void __svgalib_driver8a_copybox(int x1, int y1, int w, int h, int x2, int y2)
+{
+    vga_accel(ACCEL_SCREENCOPY, x1, y1, x2, y2, w, h);
+}
+
+
+
+/* Two bytes per pixel graphics primitives */
+
+#define ASSIGNVP16(x, y, vp) vp = VBUF + (y) * BYTEWIDTH + (x) * 2;
+#define ASSIGNVPOFFSET16(x, y, vp) vp = (y) * BYTEWIDTH + (x) * 2;
+
+void __svgalib_driver16_setpixel(int x, int y, int c)
+{
+    char *vp;
+    ASSIGNVP16(x, y, vp);
+    *(unsigned short *) vp = c;
+}
+
+void __svgalib_driver16p_setpixel(int x, int y, int c)
+{
+    int vp;
+    ASSIGNVPOFFSET16(x, y, vp);
+    vga_setpage(vp >> 16);
+    *(unsigned short *) (VBUF + (vp & 0xffff)) = c;
+}
+
+int __svgalib_driver16_getpixel(int x, int y)
+{
+    char *vp;
+    ASSIGNVP16(x, y, vp);
+    return *(unsigned short *) vp;
+}
+
+int __svgalib_driver16p_getpixel(int x, int y)
+{
+    int vp;
+    ASSIGNVPOFFSET16(x, y, vp);
+    vga_setpage(vp >> 16);
+    return *(unsigned short *) (VBUF + (vp & 0xffff));
+}
+
+void __svgalib_driver16_hline(int x1, int y, int x2, int c)
+{
+    char *vp;
+    ASSIGNVP16(x1, y, vp);
+    __memset2(vp, c, x2 - x1 + 1);
+}
+
+void __svgalib_driver16p_hline(int x1, int y, int x2, int c)
+{
+    int vp;
+    char *rvp;
+    int l;
+    int chunksize, page;
+    ASSIGNVPOFFSET16(x1, y, vp);
+    SETWRITEPAGED(vp, rvp, chunksize, page);
+    l = (x2 - x1 + 1) * 2;
+    if (l <= chunksize)
+	__memset2(rvp, c, l / 2);
+    else {
+	__memset2(rvp, c, chunksize / 2);
+	vga_setpage(page + 1);
+	__memset2(VBUF, c, (l - chunksize) / 2);
+    }
+}
+
+void __svgalib_driver16_fillbox(int x, int y, int w, int h, int c)
+{
+    char *vp;
+    int i;
+    ASSIGNVP16(x, y, vp);
+    for (i = 0; i < h; i++) {
+	__memset2(vp, c, w);
+	vp += BYTEWIDTH;
+    }
+}
+
+void __svgalib_driver16p_fillbox(int x, int y, int w, int h, int c)
+{
+    int vp;
+    int page;
+    int i;
+    ASSIGNVPOFFSET16(x, y, vp);
+    page = vp >> 16;
+    vp &= 0xffff;
+    vga_setpage(page);
+    for (i = 0; i < h; i++) {
+	if (vp + w * 2 > 0x10000) {
+	    if (vp >= 0x10000) {
+		page++;
+		vga_setpage(page);
+		vp &= 0xffff;
+	    } else {		/* page break within line */
+		__memset2(VBUF + vp, c, (0x10000 - vp) / 2);
+		page++;
+		vga_setpage(page);
+		__memset2(VBUF, c, ((vp + w * 2) & 0xffff) / 2);
+		vp = (vp + BYTEWIDTH) & 0xffff;
+		continue;
+	    }
+        };
+	__memset2(VBUF + vp, c, w);
+	vp += BYTEWIDTH;
+    }
+}
+
+void __svgalib_driver16_putbox(int x, int y, int w, int h, void *b, int bw)
+{
+    char *vp;			/* screen pointer */
+    char *bp;			/* bitmap pointer */
+    int i;
+    ASSIGNVP16(x, y, vp);
+    bp = b;
+    for (i = 0; i < h; i++) {
+	__memcpy(vp, bp, w * 2);
+	bp += bw * 2;
+	vp += BYTEWIDTH;
+    }
+}
+
+void __svgalib_driver16p_putbox(int x, int y, int w, int h, void *b, int bw)
+{
+    __svgalib_driver8p_putbox(x * 2, y, w * 2, h, b, bw * 2);
+}
+
+void __svgalib_driver16_getbox(int x, int y, int w, int h, void *b, int bw)
+{
+    char *vp;			/* screen pointer */
+    char *bp;			/* bitmap pointer */
+    int i;
+    ASSIGNVP16(x, y, vp);
+    bp = b;
+    for (i = 0; i < h; i++) {
+	__memcpy(bp, vp, w * 2);
+	bp += bw * 2;
+	vp += BYTEWIDTH;
+    }
+}
+
+INLINE void __svgalib_driver16p_getbox(int x, int y, int w, int h, void *b, int bw)
+{
+    __svgalib_driver8p_getbox(x * 2, y, w * 2, h, b, bw * 2);
+}
+
+void __svgalib_driver16_putboxmask(int x, int y, int w, int h, void *b)
+{
+    uchar *bp = b;
+    uchar *vp;
+    int i;
+    ASSIGNVP16(x, y, vp);
+    for (i = 0; i < h; i++) {
+	uchar *endoflinebp = bp + w * 2;
+	while (bp < endoflinebp - 7) {
+	    unsigned c2 = *(unsigned *) bp;
+	    if (c2 & 0xffff)
+		*(ushort *) vp = (ushort) c2;
+	    c2 >>= 16;
+	    if (c2 & 0xffff)
+		*(ushort *) (vp + 2) = (ushort) c2;
+	    c2 = *(unsigned *) (bp + 4);
+	    if (c2 & 0xffff)
+		*(ushort *) (vp + 4) = (ushort) c2;
+	    c2 >>= 16;
+	    if (c2 & 0xffff)
+		*(ushort *) (vp + 6) = (ushort) c2;
+	    bp += 8;
+	    vp += 8;
+	}
+	while (bp < endoflinebp) {
+	    ushort c = *(ushort *) bp;
+	    if (c)
+		*(ushort *) vp = c;
+	    bp += 2;
+	    vp += 2;
+	}
+	vp += BYTEWIDTH - w * 2;
+    }
+}
+
+INLINE void __svgalib_driver16_putboxpart(int x, int y, int w, int h, int ow, int oh,
+				void *b, int xo, int yo)
+{
+    __svgalib_driver8_putbox(x * 2, y, w * 2, h, b + yo * ow * 2 + xo * 2, ow * 2);
+    /* inlined */
+}
+
+INLINE void __svgalib_driver16p_putboxpart(int x, int y, int w, int h, int ow, int oh,
+				 void *b, int xo, int yo)
+{
+    __svgalib_driver8p_putbox(x * 2, y, w * 2, h, b + yo * ow * 2 + xo * 2, ow * 2);
+}
+
+INLINE void __svgalib_driver16_getboxpart(int x, int y, int w, int h, int ow, int oh,
+				void *b, int xo, int yo)
+{
+    __svgalib_driver16_getbox(x, y, w, h, b + yo * ow + xo, ow);
+}
+
+INLINE void __svgalib_driver16p_getboxpart(int x, int y, int w, int h, int ow, int oh,
+				 void *b, int xo, int yo)
+{
+    __svgalib_driver16p_getbox(x, y, w, h, b + yo * ow + xo, ow);
+}
+
+INLINE void __svgalib_driver16_copybox(int x1, int y1, int w, int h, int x2, int y2)
+{
+    __svgalib_driver8_copybox(x1 * 2, y1, w * 2, h, x2 * 2, y2);
+}
+
+void __svgalib_driver16a_copybox(int x1, int y1, int w, int h, int x2, int y2)
+{
+    int svp, dvp;
+    ASSIGNVPOFFSET16(x1, y1, svp);
+    ASSIGNVPOFFSET16(x2, y2, dvp);
+    vga_bitblt(svp, dvp, w * 2, h, BYTEWIDTH);
+}
+
+
+
+/* Three bytes per pixel graphics primitives */
+
+#define ASSIGNVP24(x, y, vp) vp = VBUF + (y) * BYTEWIDTH + (x) * 3;
+#define ASSIGNVPOFFSET24(x, y, vp) vp = (y) * BYTEWIDTH + (x) * 3;
+#define RGBEQUAL(c) ((c & 0xff) == ((c >> 8) & 0xff) && \
+	(c & 0xff) == ((c >> 16) & 0xff))
+
+void __svgalib_driver24_setpixel(int x, int y, int c)
+{
+    char *vp;
+    c = RGB2BGR(c);
+    ASSIGNVP24(x, y, vp);
+    *(unsigned short *) vp = c;
+    *(unsigned char *) (vp + 2) = c >> 16;
+}
+
+void __svgalib_driver24p_setpixel(int x, int y, int c)
+{
+    int vp, vpo;
+    char *vbuf;
+    int page;
+    c = RGB2BGR(c);
+    ASSIGNVPOFFSET24(x, y, vp);
+    vbuf = VBUF;
+    page = vp >> 16;
+    vga_setpage(page);
+    vpo = vp & 0xffff;
+    if (vpo <= 0xfffd) {
+	*(unsigned short *) (vbuf + vpo) = c;
+	*(unsigned char *) (vbuf + vpo + 2) = c >> 16;
+    } else if (vpo == 0xfffe) {
+	*(unsigned short *) (vbuf + 0xfffe) = c;
+	vga_setpage(page + 1);
+	*(unsigned char *) vbuf = c >> 16;
+    } else {			/* vpo == 0xffff */
+	*(unsigned char *) (vbuf + 0xffff) = c;
+	vga_setpage(page + 1);
+	*(unsigned short *) vbuf = c >> 8;
+    }
+}
+
+int __svgalib_driver24_getpixel(int x, int y)
+{
+    char *vp;
+    ASSIGNVP24(x, y, vp);
+    return RGB2BGR(*(unsigned short *) vp + (*(unsigned char *) (vp + 2) << 16));
+}
+
+int __svgalib_driver24p_getpixel(int x, int y)
+{
+    int vp, vpo;
+    char *vbuf;
+    int page;
+    ASSIGNVPOFFSET24(x, y, vp);
+    vbuf = VBUF;
+    page = vp >> 16;
+    vga_setpage(page);
+    vpo = vp & 0xffff;
+    if (vpo <= 0xfffd)
+	return RGB2BGR(*(unsigned short *) (vbuf + vpo) +
+		       (*(unsigned char *) (vbuf + vpo + 2) << 16));
+    else if (vpo == 0xfffe) {
+	int c;
+	c = *(unsigned short *) (vbuf + 0xfffe);
+	vga_setpage(page + 1);
+	return RGB2BGR((*(unsigned char *) vbuf << 16) + c);
+    } else {			/* vpo == 0xffff */
+	int c;
+	c = *(unsigned char *) (vbuf + 0xffff);
+	vga_setpage(page + 1);
+	return RGB2BGR((*(unsigned short *) vbuf << 8) + c);
+    }
+}
+
+void __svgalib_driver24_hline(int x1, int y, int x2, int c)
+{
+    char *vp;
+    c = RGB2BGR(c);
+    ASSIGNVP24(x1, y, vp);
+    if (RGBEQUAL(c))
+	__memset(vp, c, (x2 - x1 + 1) * 3);
+    else
+	__memset3(vp, c, x2 - x1 + 1);
+}
+
+void __svgalib_driver24p_hline(int x1, int y, int x2, int c)
+{
+    int vp;
+    char *rvp;
+    int l;
+    int chunksize, page;
+    c = RGB2BGR(c);
+    ASSIGNVPOFFSET24(x1, y, vp);
+    SETWRITEPAGED(vp, rvp, chunksize, page);
+    l = (x2 - x1 + 1) * 3;
+    if (l <= chunksize)
+	__memset3(rvp, c, l / 3);
+    else {
+	int n, m, o;
+	n = chunksize / 3;
+	m = chunksize % 3;
+	__memset3(rvp, c, n);
+	/* Handle page break within pixel. */
+	if (m >= 1)
+	    *(rvp + n * 3) = c;
+	if (m == 2)
+	    *(rvp + n * 3 + 1) = c >> 8;
+	vga_setpage(page + 1);
+	o = 0;
+	if (m == 2) {
+	    *(VBUF) = c >> 16;
+	    o = 1;
+	}
+	if (m == 1) {
+	    *(unsigned short *) (VBUF) = c >> 8;
+	    o = 2;
+	}
+	__memset3(VBUF + o, c, (l - chunksize) / 3);
+    }
+}
+
+void __svgalib_driver24_fillbox(int x, int y, int w, int h, int c)
+{
+    char *vp;
+    int i, j;
+    c = RGB2BGR(c);
+    ASSIGNVP24(x, y, vp);
+    if (RGBEQUAL(c))
+	for (i = 0; i < h; i++) {
+	    __memset(vp, c, w * 3);
+	    vp += BYTEWIDTH;
+    } else
+	for (j = 0; j < h; j++) {
+	    __memset3(vp, c, w);
+	    vp += BYTEWIDTH;
+	}
+}
+
+void __svgalib_driver24p_fillbox(int x, int y, int w, int h, int c)
+{
+    int vp;
+    int page;
+    int i;
+    c = RGB2BGR(c);
+    ASSIGNVPOFFSET24(x, y, vp);
+    page = vp >> 16;
+    vp &= 0xffff;
+    vga_setpage(page);
+    if (RGBEQUAL(c)) {
+	for (i = 0; i < h; i++) {
+	    if (vp + w * 3 > 0x10000) {
+		if (vp >= 0x10000) {
+		    page++;
+		    vga_setpage(page);
+		    vp &= 0xffff;
+		} else {	/* Page break within line. */
+		    __memset(VBUF + vp, c, 0x10000 - vp);
+		    page++;
+		    vga_setpage(page);
+		    __memset(VBUF, c, (vp + w * 3) & 0xffff);
+		    vp = (vp + BYTEWIDTH) & 0xffff;
+		    continue;
+		}
+            };
+	    __memset(VBUF + vp, c, w * 3);
+	    vp += BYTEWIDTH;
+	}
+    } else
+	for (i = 0; i < h; i++) {
+	    if (vp + w * 3 > 0x10000) {
+		if (vp >= 0x10000) {
+		    page++;
+		    vga_setpage(page);
+		    vp &= 0xffff;
+		} else {	/* Page break within line. */
+		    int n, m, o;
+		    n = (0x10000 - vp) / 3;
+		    m = (0x10000 - vp) % 3;
+		    __memset3(VBUF + vp, c, n);
+		    /* Handle page break within pixel. */
+		    if (m >= 1)
+			*(VBUF + vp + n * 3) = c;
+		    if (m == 2)
+			*(VBUF + vp + n * 3 + 1) = c >> 8;
+		    page++;
+		    vga_setpage(page);
+		    o = 0;
+		    if (m == 2) {
+			*(VBUF) = c >> 16;
+			o = 1;
+		    }
+		    if (m == 1) {
+			*(unsigned short *) (VBUF) = c >> 8;
+			o = 2;
+		    }
+		    __memset3(VBUF + o, c, ((vp + w * 3) & 0xffff) / 3);
+		    vp = (vp + BYTEWIDTH) & 0xffff;
+		    continue;
+		}
+            };
+	    __memset3(VBUF + vp, c, w);
+	    vp += BYTEWIDTH;
+	}
+}
+
+void __svgalib_driver24_putbox(int x, int y, int w, int h, void *b, int bw)
+{
+    char *vp;			/* screen pointer */
+    char *bp;			/* bitmap pointer */
+    int i;
+    ASSIGNVP24(x, y, vp);
+    bp = b;
+    if (MODEFLAGS & MODEFLAG_24BPP_REVERSED) {
+	for (i = 0; i < h; i++) {
+	    RGB_swapped_memcpy(vp, bp, w * 3);
+	    bp += bw * 3;
+	    vp += BYTEWIDTH;
+	}
+    } else {
+	for (i = 0; i < h; i++) {
+	    __memcpy(vp, bp, w * 3);
+	    bp += bw * 3;
+	    vp += BYTEWIDTH;
+	}
+    }
+}
+
+static void driver24_rev_putbox(int x, int y, int w, int h, void *b, int bw)
+{
+/* extra argument width of source bitmap, so that putboxpart can use this */
+    int vp;
+    int page;
+    char *bp = b, *bp2;
+    int i, left;
+
+    ASSIGNVPOFFSET8(x, y, vp);
+    page = vp >> 16;
+    vp &= 0xffff;
+    vga_setpage(page);
+    for (i = 0; i < h; i++) {
+	if (vp + w > 0x10000) {
+	    if (vp >= 0x10000) {
+		page++;
+		vga_setpage(page);
+		vp &= 0xffff;
+	    } else {		/* page break within line */
+		left = RGB_swapped_memcpy(VBUF + vp, bp, 0x10000 - vp);
+		bp2 = bp + (0x10000 - vp - left);
+		switch (left) {
+		case 2:
+		    *(VBUF + 0xFFFE) = bp2[2];
+		    *(VBUF + 0xFFFF) = bp2[1];
+		    break;
+		case 1:
+		    *(VBUF + 0xFFFF) = bp2[2];
+		    break;
+		}
+
+		page++;
+		vga_setpage(page);
+
+		switch (left) {
+		case 1:
+		    *(VBUF) = bp2[1];
+		    *(VBUF + 1) = bp2[0];
+		    left = 3 - left;
+		    bp2 += 3;
+		    break;
+		case 2:
+		    *(VBUF) = bp2[0];
+		    left = 3 - left;
+		    bp2 += 3;
+		    break;
+		}
+
+		RGB_swapped_memcpy(VBUF + left, bp2, ((vp + w) & 0xffff) - left);
+		vp = (vp + BYTEWIDTH) & 0xffff;
+		bp += bw;
+		continue;
+	    }
+        };
+	RGB_swapped_memcpy(VBUF + vp, bp, w);
+	bp += bw;
+	vp += BYTEWIDTH;
+    }
+}
+
+INLINE void __svgalib_driver24p_putbox(int x, int y, int w, int h, void *b, int bw)
+{
+    if (MODEFLAGS & MODEFLAG_24BPP_REVERSED) {
+	driver24_rev_putbox(x * 3, y, w * 3, h, b, bw * 3);
+    } else {
+	__svgalib_driver8p_putbox(x * 3, y, w * 3, h, b, bw * 3);
+    }
+}
+
+void __svgalib_driver24_putbox32(int x, int y, int w, int h, void *b, int bw)
+{
+    char *vp;			/* screen pointer */
+    char *bp;			/* bitmap pointer */
+    int i;
+    ASSIGNVP24(x, y, vp);
+    bp = b;
+    for (i = 0; i < h; i++) {
+	__svgalib_memcpy4to3(vp, bp, w);
+	bp += bw * 4;
+	vp += BYTEWIDTH;
+    }
+}
+
+void __svgalib_driver24_getbox(int x, int y, int w, int h, void *b, int bw)
+{
+    char *vp;			/* screen pointer */
+    char *bp;			/* bitmap pointer */
+    int i;
+    ASSIGNVP24(x, y, vp);
+    bp = b;
+    if (MODEFLAGS & MODEFLAG_24BPP_REVERSED) {
+	for (i = 0; i < h; i++) {
+	    RGB_swapped_memcpy(bp, vp, w * 3);
+	    bp += bw * 3;
+	    vp += BYTEWIDTH;
+	}
+    } else {
+	for (i = 0; i < h; i++) {
+	    __memcpy(bp, vp, w * 3);
+	    bp += bw * 3;
+	    vp += BYTEWIDTH;
+	}
+    }
+}
+
+static void driver24_rev_getbox(int x, int y, int w, int h, void *b, int bw)
+{
+/* extra argument width of source bitmap, so that putboxpart can use this */
+    int vp;
+    int page;
+    char *bp = b, *bp2;
+    int i, left;
+
+    ASSIGNVPOFFSET8(x, y, vp);
+    page = vp >> 16;
+    vp &= 0xffff;
+    vga_setpage(page);
+    for (i = 0; i < h; i++) {
+	if (vp + w > 0x10000) {
+	    if (vp >= 0x10000) {
+		page++;
+		vga_setpage(page);
+		vp &= 0xffff;
+	    } else {		/* page break within line */
+		left = RGB_swapped_memcpy(bp, VBUF + vp, 0x10000 - vp);
+		bp2 = bp + (0x10000 - vp - left);
+		switch (left) {
+		case 2:
+		    bp2[2] = *(VBUF + 0xFFFE);
+		    bp2[1] = *(VBUF + 0xFFFF);
+		    break;
+		case 1:
+		    bp2[2] = *(VBUF + 0xFFFF);
+		    break;
+		}
+
+		page++;
+		vga_setpage(page);
+
+		switch (left) {
+		case 1:
+		    bp2[1] = *(VBUF);
+		    bp2[0] = *(VBUF + 1);
+		    left = 3 - left;
+		    bp2 += 3;
+		    break;
+		case 2:
+		    bp2[0] = *(VBUF);
+		    left = 3 - left;
+		    bp2 += 3;
+		    break;
+		}
+
+		RGB_swapped_memcpy(bp2, VBUF + left, ((vp + w) & 0xffff) - left);
+		vp = (vp + BYTEWIDTH) & 0xffff;
+		bp += bw;
+		continue;
+	    }
+        };
+	RGB_swapped_memcpy(bp, VBUF + vp, w);
+	bp += bw;
+	vp += BYTEWIDTH;
+    }
+}
+
+INLINE void __svgalib_driver24p_getbox(int x, int y, int w, int h, void *b, int bw)
+{
+    if (MODEFLAGS & MODEFLAG_24BPP_REVERSED) {
+	driver24_rev_getbox(x * 3, y, w * 3, h, b, bw * 3);
+    } else {
+	__svgalib_driver8p_getbox(x * 3, y, w * 3, h, b, bw * 3);
+    }
+}
+
+void __svgalib_driver24_putboxmask(int x, int y, int w, int h, void *b)
+{
+    uchar *bp = b;
+    uchar *vp;
+    int i;
+    ASSIGNVP24(x, y, vp);
+    for (i = 0; i < h; i++) {
+	uchar *endoflinebp = bp + w * 3;
+	while (bp < endoflinebp - 11) {
+	    unsigned c = RGB2BGR(*(unsigned *) bp);
+	    if (c & 0xffffff) {
+		*(ushort *) vp = (ushort) c;
+		*(vp + 2) = c >> 16;
+	    }
+	    c = RGB2BGR(*(unsigned *) (bp + 3));
+	    if (c & 0xffffff) {
+		*(ushort *) (vp + 3) = (ushort) c;
+		*(vp + 5) = c >> 16;
+	    }
+	    c = RGB2BGR(*(unsigned *) (bp + 6));
+	    if (c & 0xffffff) {
+		*(ushort *) (vp + 6) = (ushort) c;
+		*(vp + 8) = c >> 16;
+	    }
+	    c = RGB2BGR(*(unsigned *) (bp + 9));
+	    if (c & 0xffffff) {
+		*(ushort *) (vp + 9) = (ushort) c;
+		*(vp + 11) = c >> 16;
+	    }
+	    bp += 12;
+	    vp += 12;
+	}
+	while (bp < endoflinebp) {
+	    uint c = RGB2BGR(*(uint *) bp);
+	    if (c & 0xffffff) {
+		*(ushort *) vp = (ushort) c;
+		*(vp + 2) = c >> 16;
+	    }
+	    bp += 3;
+	    vp += 3;
+	}
+	vp += BYTEWIDTH - w * 3;
+    }
+}
+
+INLINE void __svgalib_driver24_putboxpart(int x, int y, int w, int h, int ow, int oh,
+				void *b, int xo, int yo)
+{
+    /*
+     * Actually I think all this could be done by just calling __svgalib_driver24_putbox
+     * with correct args. But I'm too fearful. - Michael.
+     */
+    if (MODEFLAGS & MODEFLAG_24BPP_REVERSED) {
+	__svgalib_driver24_putbox(x, y, w, h, b + yo * ow + xo, ow);
+    } else {
+	__svgalib_driver8_putbox(x * 3, y, w * 3, h, b + yo * ow * 3 + xo * 3, ow * 3);
+    }
+}
+
+INLINE void __svgalib_driver24p_putboxpart(int x, int y, int w, int h, int ow, int oh,
+				 void *b, int xo, int yo)
+{
+    if (MODEFLAGS & MODEFLAG_24BPP_REVERSED) {
+	driver24_rev_putbox(x * 3, y, w * 3, h, b + yo * ow * 3 + xo * 3, ow * 3);
+    } else {
+	__svgalib_driver8p_putbox(x * 3, y, w * 3, h, b + yo * ow * 3 + xo * 3, ow * 3);
+    }
+}
+
+INLINE void __svgalib_driver24_getboxpart(int x, int y, int w, int h, int ow, int oh,
+				void *b, int xo, int yo)
+{
+    __svgalib_driver24_getbox(x, y, w, h, b + yo * ow + xo, ow);
+}
+
+INLINE void __svgalib_driver24p_getboxpart(int x, int y, int w, int h, int ow, int oh,
+				 void *b, int xo, int yo)
+{
+    __svgalib_driver24p_getbox(x, y, w, h, b + yo * ow + xo, ow);
+}
+
+void __svgalib_driver24_copybox(int x1, int y1, int w, int h, int x2, int y2)
+{
+    __svgalib_driver8_copybox(x1 * 3, y1, w * 3, h, x2 * 3, y2);
+}
+
+void __svgalib_driver24a_copybox(int x1, int y1, int w, int h, int x2, int y2)
+{
+    int svp, dvp;
+    ASSIGNVPOFFSET24(x1, y1, svp);
+    ASSIGNVPOFFSET24(x2, y2, dvp);
+    vga_bitblt(svp, dvp, w * 3, h, BYTEWIDTH);
+}
+
+
+
+/* Four bytes per pixel graphics primitives */
+
+#define ASSIGNVP32(x, y, vp) vp = VBUF + (y) * BYTEWIDTH + (x) * 4;
+#define ASSIGNVPOFFSET32(x, y, vp) vp = (y) * BYTEWIDTH + (x) * 4;
+
+void __svgalib_driver32_setpixel(int x, int y, int c)
+{
+    char *vp;
+    ASSIGNVP32(x, y, vp);
+    *(unsigned *) vp = c;
+}
+
+void __svgalib_driver32p_setpixel(int x, int y, int c)
+{
+    int vp;
+    ASSIGNVPOFFSET32(x, y, vp);
+    vga_setpage(vp >> 16);
+    *(unsigned *) (VBUF + (vp & 0xffff)) = c;
+}
+
+int __svgalib_driver32_getpixel(int x, int y)
+{
+    char *vp;
+    ASSIGNVP32(x, y, vp);
+    return *(unsigned *) vp;
+}
+
+int __svgalib_driver32p_getpixel(int x, int y)
+{
+    int vp;
+    ASSIGNVPOFFSET32(x, y, vp);
+    vga_setpage(vp >> 16);
+    return *(unsigned *) (VBUF + (vp & 0xffff));
+}
+
+void __svgalib_driver32_hline(int x1, int y, int x2, int c)
+{
+    char *vp;
+    ASSIGNVP32(x1, y, vp);
+    __memsetlong(vp, c, x2 - x1 + 1);
+}
+
+void __svgalib_driver32p_hline(int x1, int y, int x2, int c)
+{
+    int vp;
+    char *rvp;
+    int l;
+    int chunksize, page;
+    ASSIGNVPOFFSET32(x1, y, vp);
+    SETWRITEPAGED(vp, rvp, chunksize, page);
+    l = (x2 - x1 + 1) * 4;
+    if (l <= chunksize)
+	__memsetlong(rvp, c, l / 4);
+    else {
+	__memsetlong(rvp, c, chunksize / 4);
+	vga_setpage(page + 1);
+	__memsetlong(VBUF, c, (l - chunksize) / 4);
+    }
+}
+
+void __svgalib_driver32_fillbox(int x, int y, int w, int h, int c)
+{
+    char *vp;
+    int i;
+    ASSIGNVP32(x, y, vp);
+    for (i = 0; i < h; i++) {
+	__memsetlong(vp, c, w);
+	vp += BYTEWIDTH;
+    }
+}
+
+void __svgalib_driver32p_fillbox(int x, int y, int w, int h, int c)
+{
+    int vp;
+    int page;
+    int i;
+    ASSIGNVPOFFSET32(x, y, vp);
+    page = vp >> 16;
+    vp &= 0xffff;
+    vga_setpage(page);
+    for (i = 0; i < h; i++) {
+	if (vp + w * 4 > 0x10000) {
+	    if (vp >= 0x10000) {
+		page++;
+		vga_setpage(page);
+		vp &= 0xffff;
+	    } else {		/* page break within line */
+		__memsetlong(VBUF + vp, c, (0x10000 - vp) / 4);
+		page++;
+		vga_setpage(page);
+		__memsetlong(VBUF, c, ((vp + w * 4) & 0xffff) / 4);
+		vp = (vp + BYTEWIDTH) & 0xffff;
+		continue;
+	    }
+        };
+	__memsetlong(VBUF + vp, c, w);
+	vp += BYTEWIDTH;
+    }
+}
+
+INLINE void __svgalib_driver32_putbox(int x, int y, int w, int h, void *b, int bw)
+{
+    __svgalib_driver8_putbox(x * 4, y, w * 4, h, b, bw * 4);
+}
+
+INLINE void __svgalib_driver32p_putbox(int x, int y, int w, int h, void *b, int bw)
+{
+    __svgalib_driver8p_putbox(x * 4, y, w * 4, h, b, bw * 4);
+}
+
+INLINE void __svgalib_driver32_getbox(int x, int y, int w, int h, void *b, int bw)
+{
+    __svgalib_driver8_getbox(x * 4, y, w * 4, h, b, bw * 4);
+}
+
+INLINE void __svgalib_driver32p_getbox(int x, int y, int w, int h, void *b, int bw)
+{
+    __svgalib_driver8p_getbox(x * 4, y, w * 4, h, b, bw * 4);
+}
+
+void __svgalib_driver32_putboxmask(int x, int y, int w, int h, void *b)
+{
+    uchar *bp = b;
+    uchar *vp;
+    int i;
+    ASSIGNVP32(x, y, vp);
+    for (i = 0; i < h; i++) {
+	uchar *endoflinebp = bp + w * 4;
+	while (bp < endoflinebp - 15) {
+	    unsigned c = *(unsigned *) bp;
+	    if (c)
+		*(unsigned *) vp = c;
+	    c = *(unsigned *) (bp + 4);
+	    if (c)
+		*(unsigned *) (vp + 4) = c;
+	    c = *(unsigned *) (bp + 8);
+	    if (c)
+		*(unsigned *) (vp + 8) = c;
+	    c = *(unsigned *) (bp + 12);
+	    if (c)
+		*(unsigned *) (vp + 12) = c;
+	    bp += 16;
+	    vp += 16;
+	}
+	while (bp < endoflinebp) {
+	    unsigned c = *(unsigned *) bp;
+	    if (c)
+		*(unsigned *) vp = c;
+	    bp += 4;
+	    vp += 4;
+	}
+	vp += BYTEWIDTH - w * 4;
+    }
+}
+
+INLINE void __svgalib_driver32_putboxpart(int x, int y, int w, int h, int ow, int oh,
+				void *b, int xo, int yo)
+{
+    __svgalib_driver32_putbox(x, y, w, h, b + yo * ow * 4 + xo * 4 , ow );
+    /* inlined */
+}
+
+INLINE void __svgalib_driver32p_putboxpart(int x, int y, int w, int h, int ow, int oh,
+				 void *b, int xo, int yo)
+{
+    __svgalib_driver32p_putbox(x, y, w, h, b + yo * ow * 4 + xo * 4, ow );
+    /* inlined */
+}
+
+INLINE void __svgalib_driver32_getboxpart(int x, int y, int w, int h, int ow, int oh,
+				void *b, int xo, int yo)
+{
+    __svgalib_driver32_getbox(x, y, w, h, b + yo * ow * 4 + xo * 4 , ow );
+}
+
+INLINE void __svgalib_driver32p_getboxpart(int x, int y, int w, int h, int ow, int oh,
+				 void *b, int xo, int yo)
+{
+    __svgalib_driver32p_getbox(x, y, w, h, b + yo * ow * 4 + xo * 4 , ow );
+}
+
+INLINE void __svgalib_driver32_copybox(int x1, int y1, int w, int h, int x2, int y2)
+{
+    __svgalib_driver8_copybox(x1 * 4, y1, w * 4, h, x2 * 4, y2);
+}
+
+
+
+/* Planar 256 color mode graphics primitives (only putbox) */
+
+void __svgalib_driverplanar256_nothing(void)
+{
+    NOTIMPL("planar 256 color mode primitive");
+}
+
+void __svgalib_driverplanar256_putbox(int x, int y, int w, int h, void *b, int bw)
+{
+    if ((w & 3) != 0 || (x & 3) != 0)
+	NOTIMPL("planar 256 color mode unaligned putbox");
+    vga_copytoplanar256(b, bw, y * BYTEWIDTH + x / 4, BYTEWIDTH,
+			w, h);
+}
+
+void __svgalib_driverplanar16_nothing(void)
+{
+    NOTIMPL("planar 16 color mode primitive");
+}
+
+
+/* Memory primitives */
+
+int __svgalib_driver_setread(GraphicsContext * gc, int i, void **vp)
+{
+    if (gc->modetype == CONTEXT_PAGED) {
+	vga_setpage(i >> 16);
+	*vp = (i & 0xffff) + gc->vbuf;
+	return 0x10000 - (i & 0xffff);
+    } else {
+	*vp = gc->vbuf + i;
+	return 0x10000;
+    }
+}
+
+int __svgalib_driver_setwrite(GraphicsContext * gc, int i, void **vp)
+{
+    if (gc->modetype == CONTEXT_PAGED) {
+	vga_setpage(i >> 16);
+	*vp = (i & 0xffff) + gc->vbuf;
+	return 0x10000 - (i & 0xffff);
+    } else {
+	*vp = gc->vbuf + i;
+	return 0x10000;
+    }
+}
+
+
+
+/* Functions that are not yet implemented */
+
+void __svgalib_driver8p_putboxmask(int x, int y, int w, int h, void *b)
+{
+    NOTIMPL("8-bit paged putboxmask");
+}
+
+void __svgalib_driver8p_copybox(int x1, int y1, int w, int h, int x2, int y2)
+{
+    NOTIMPL("8-bit paged copybox (bitblt)");
+}
+
+void __svgalib_driver16p_putboxmask(int x, int y, int w, int h, void *b)
+{
+    NOTIMPL("16-bit paged putboxmask");
+}
+
+void __svgalib_driver16p_copybox(int x1, int y1, int w, int h, int x2, int y2)
+{
+    NOTIMPL("16-bit paged copybox");
+}
+
+void __svgalib_driver24p_putboxmask(int x, int y, int w, int h, void *b)
+{
+    NOTIMPL("24-bit paged putboxmask");
+}
+
+void __svgalib_driver24p_copybox(int x1, int y1, int w, int h, int x2, int y2)
+{
+    NOTIMPL("24-bit paged copybox");
+}
+
+void __svgalib_driver32p_putboxmask(int x, int y, int w, int h, void *b)
+{
+    NOTIMPL("32-bit paged putboxmask");
+}
+
+void __svgalib_driver32p_copybox(int x1, int y1, int w, int h, int x2, int y2)
+{
+    NOTIMPL("32-bit paged copybox");
+}
diff --git a/haiku/vgagl/driver.h b/haiku/vgagl/driver.h
new file mode 100644
index 0000000..77e79a3
--- /dev/null
+++ b/haiku/vgagl/driver.h
@@ -0,0 +1,104 @@
+void __svgalib_driver8_setpixel(int, int, int);
+int __svgalib_driver8_getpixel(int, int);
+void __svgalib_driver8_hline(int, int, int, int);
+void __svgalib_driver8_fillbox(int, int, int, int, int);
+void __svgalib_driver8_putbox(int, int, int, int, void *, int);
+void __svgalib_driver8_getbox(int, int, int, int, void *, int);
+void __svgalib_driver8_putboxmask(int, int, int, int, void *);
+void __svgalib_driver8_putboxpart(int, int, int, int, int, int, void *, int, int);
+void __svgalib_driver8_getboxpart(int, int, int, int, int, int, void *, int, int);
+void __svgalib_driver8_copybox(int, int, int, int, int, int);
+
+void __svgalib_driver16_setpixel(int, int, int);
+int __svgalib_driver16_getpixel(int, int);
+void __svgalib_driver16_hline(int, int, int, int);
+void __svgalib_driver16_fillbox(int, int, int, int, int);
+void __svgalib_driver16_putbox(int, int, int, int, void *, int);
+void __svgalib_driver16_getbox(int, int, int, int, void *, int);
+void __svgalib_driver16_putboxmask(int, int, int, int, void *);
+void __svgalib_driver16_putboxpart(int, int, int, int, int, int, void *, int, int);
+void __svgalib_driver16_getboxpart(int, int, int, int, int, int, void *, int, int);
+void __svgalib_driver16_copybox(int, int, int, int, int, int);
+
+void __svgalib_driver24_setpixel(int, int, int);
+int __svgalib_driver24_getpixel(int, int);
+void __svgalib_driver24_hline(int, int, int, int);
+void __svgalib_driver24_fillbox(int, int, int, int, int);
+void __svgalib_driver24_putbox(int, int, int, int, void *, int);
+void __svgalib_driver24_getbox(int, int, int, int, void *, int);
+void __svgalib_driver24_putboxmask(int, int, int, int, void *);
+void __svgalib_driver24_putboxpart(int, int, int, int, int, int, void *, int, int);
+void __svgalib_driver24_getboxpart(int, int, int, int, int, int, void *, int, int);
+void __svgalib_driver24_copybox(int, int, int, int, int, int);
+void __svgalib_driver24_putbox32(int, int, int, int, void *, int);
+
+void __svgalib_driver32_setpixel(int, int, int);
+int __svgalib_driver32_getpixel(int, int);
+void __svgalib_driver32_hline(int, int, int, int);
+void __svgalib_driver32_fillbox(int, int, int, int, int);
+void __svgalib_driver32_putbox(int, int, int, int, void *, int);
+void __svgalib_driver32_getbox(int, int, int, int, void *, int);
+void __svgalib_driver32_putboxmask(int, int, int, int, void *);
+void __svgalib_driver32_putboxpart(int, int, int, int, int, int, void *, int, int);
+void __svgalib_driver32_getboxpart(int, int, int, int, int, int, void *, int, int);
+void __svgalib_driver32_copybox(int, int, int, int, int, int);
+
+void __svgalib_driver8p_setpixel(int, int, int);
+int __svgalib_driver8p_getpixel(int, int);
+void __svgalib_driver8p_hline(int, int, int, int);
+void __svgalib_driver8p_fillbox(int, int, int, int, int);
+void __svgalib_driver8p_putbox(int, int, int, int, void *, int);
+void __svgalib_driver8p_getbox(int, int, int, int, void *, int);
+void __svgalib_driver8p_putboxmask(int, int, int, int, void *);
+void __svgalib_driver8p_putboxpart(int, int, int, int, int, int, void *, int, int);
+void __svgalib_driver8p_getboxpart(int, int, int, int, int, int, void *, int, int);
+void __svgalib_driver8p_copybox(int, int, int, int, int, int);
+
+void __svgalib_driver16p_setpixel(int, int, int);
+int __svgalib_driver16p_getpixel(int, int);
+void __svgalib_driver16p_hline(int, int, int, int);
+void __svgalib_driver16p_fillbox(int, int, int, int, int);
+void __svgalib_driver16p_putbox(int, int, int, int, void *, int);
+void __svgalib_driver16p_getbox(int, int, int, int, void *, int);
+void __svgalib_driver16p_putboxmask(int, int, int, int, void *);
+void __svgalib_driver16p_putboxpart(int, int, int, int, int, int, void *, int, int);
+void __svgalib_driver16p_getboxpart(int, int, int, int, int, int, void *, int, int);
+void __svgalib_driver16p_copybox(int, int, int, int, int, int);
+
+void __svgalib_driver24p_setpixel(int, int, int);
+int __svgalib_driver24p_getpixel(int, int);
+void __svgalib_driver24p_hline(int, int, int, int);
+void __svgalib_driver24p_fillbox(int, int, int, int, int);
+void __svgalib_driver24p_putbox(int, int, int, int, void *, int);
+void __svgalib_driver24p_getbox(int, int, int, int, void *, int);
+void __svgalib_driver24p_putboxmask(int, int, int, int, void *);
+void __svgalib_driver24p_putboxpart(int, int, int, int, int, int, void *, int, int);
+void __svgalib_driver24p_getboxpart(int, int, int, int, int, int, void *, int, int);
+void __svgalib_driver24p_copybox(int, int, int, int, int, int);
+
+void __svgalib_driver32p_setpixel(int, int, int);
+int __svgalib_driver32p_getpixel(int, int);
+void __svgalib_driver32p_hline(int, int, int, int);
+void __svgalib_driver32p_fillbox(int, int, int, int, int);
+void __svgalib_driver32p_putbox(int, int, int, int, void *, int);
+void __svgalib_driver32p_getbox(int, int, int, int, void *, int);
+void __svgalib_driver32p_putboxmask(int, int, int, int, void *);
+void __svgalib_driver32p_putboxpart(int, int, int, int, int, int, void *, int, int);
+void __svgalib_driver32p_getboxpart(int, int, int, int, int, int, void *, int, int);
+void __svgalib_driver32p_copybox(int, int, int, int, int, int);
+
+void __svgalib_driver8a_fillbox(int, int, int, int, int);
+void __svgalib_driver8a_copybox(int, int, int, int, int, int);
+
+void __svgalib_driverplanar256_nothing(void);
+void __svgalib_driverplanar256_putbox(int, int, int, int, void *, int);
+
+void __svgalib_driverplanar16_nothing(void);
+
+/* Generic functions */
+
+int __svgalib_driver_setread(GraphicsContext * gc, int i, void **vp);
+int __svgalib_driver_setwrite(GraphicsContext * gc, int i, void **vp);
+
+/* internal globals: */
+extern void (*__svgalib_nonaccel_fillbox)(int, int, int, int, int);
diff --git a/haiku/vgagl/font8x8.c b/haiku/vgagl/font8x8.c
new file mode 100644
index 0000000..b98c12c
--- /dev/null
+++ b/haiku/vgagl/font8x8.c
@@ -0,0 +1,137 @@
+
+/* binary image of font8x8 follows */
+
+
+static unsigned char __font8x8[] =
+{
+    0, 0, 0, 0, 0, 0, 0, 0, 126, 129, 165, 129, 189, 129, 126, 0,	/* 0 to 15 */
+    126, 255, 219, 255, 195, 255, 126, 0, 54, 127, 127, 127, 62, 28, 8, 0,	/* 16 to 31 */
+    8, 28, 62, 127, 62, 28, 8, 0, 28, 28, 8, 107, 127, 107, 8, 28,	/* 32 to 47 */
+    8, 28, 62, 127, 62, 8, 28, 62, 0, 0, 24, 60, 60, 24, 0, 0,	/* 48 to 63 */
+  255, 255, 231, 195, 195, 231, 255, 255, 0, 60, 102, 66, 66, 102, 60, 0,	/* 64 to 79 */
+255, 195, 153, 189, 189, 153, 195, 255, 15, 7, 13, 60, 102, 102, 102, 60,	/* 80 to 95 */
+    60, 102, 102, 102, 60, 24, 126, 24, 48, 56, 60, 54, 52, 112, 240, 224,	/* 96 to 111 */
+127, 99, 127, 99, 99, 103, 230, 192, 24, 219, 126, 102, 102, 126, 219, 24,	/* 112 to 127 */
+    64, 112, 124, 127, 124, 112, 64, 0, 1, 7, 31, 127, 31, 7, 1, 0,	/* 128 to 143 */
+    24, 60, 126, 24, 24, 126, 60, 24, 102, 102, 102, 102, 102, 0, 102, 0,	/* 144 to 159 */
+    63, 122, 122, 58, 10, 10, 10, 0, 30, 51, 28, 54, 54, 28, 102, 60,	/* 160 to 175 */
+    0, 0, 0, 0, 126, 126, 126, 0, 24, 60, 126, 24, 126, 60, 24, 126,	/* 176 to 191 */
+    24, 60, 126, 24, 24, 24, 24, 0, 24, 24, 24, 24, 126, 60, 24, 0,	/* 192 to 207 */
+    0, 12, 14, 127, 14, 12, 0, 0, 0, 24, 56, 127, 56, 24, 0, 0,		/* 208 to 223 */
+    0, 0, 96, 96, 96, 127, 0, 0, 0, 36, 102, 255, 102, 36, 0, 0,	/* 224 to 239 */
+    0, 24, 60, 126, 255, 255, 0, 0, 0, 255, 255, 126, 60, 24, 0, 0,	/* 240 to 255 */
+    0, 0, 0, 0, 0, 0, 0, 0, 24, 24, 24, 24, 24, 0, 24, 0,	/* 256 to 271 */
+    102, 102, 102, 0, 0, 0, 0, 0, 108, 108, 254, 108, 254, 108, 108, 0,		/* 272 to 287 */
+    16, 124, 208, 124, 22, 124, 16, 0, 0, 198, 204, 24, 48, 102, 198, 0,	/* 288 to 303 */
+    56, 108, 56, 118, 220, 204, 118, 0, 24, 24, 48, 0, 0, 0, 0, 0,	/* 304 to 319 */
+    12, 24, 48, 48, 48, 24, 12, 0, 48, 24, 12, 12, 12, 24, 48, 0,	/* 320 to 335 */
+    0, 108, 56, 254, 56, 108, 0, 0, 0, 24, 24, 126, 24, 24, 0, 0,	/* 336 to 351 */
+    0, 0, 0, 0, 0, 24, 24, 48, 0, 0, 0, 126, 0, 0, 0, 0,	/* 352 to 367 */
+    0, 0, 0, 0, 0, 48, 48, 0, 0, 6, 12, 24, 48, 96, 192, 0,	/* 368 to 383 */
+    60, 102, 110, 126, 118, 102, 60, 0, 12, 28, 60, 12, 12, 12, 12, 0,	/* 384 to 399 */
+    60, 102, 6, 28, 48, 96, 126, 0, 60, 102, 6, 28, 6, 102, 60, 0,	/* 400 to 415 */
+    28, 60, 108, 204, 254, 12, 12, 0, 126, 96, 96, 124, 6, 102, 60, 0,	/* 416 to 431 */
+    60, 96, 96, 124, 102, 102, 60, 0, 126, 6, 6, 12, 24, 48, 48, 0,	/* 432 to 447 */
+    60, 102, 102, 60, 102, 102, 60, 0, 60, 102, 102, 62, 6, 6, 60, 0,	/* 448 to 463 */
+    0, 48, 48, 0, 0, 48, 48, 0, 0, 24, 24, 0, 0, 24, 24, 48,	/* 464 to 479 */
+    12, 24, 48, 96, 48, 24, 12, 0, 0, 0, 126, 0, 0, 126, 0, 0,	/* 480 to 495 */
+    48, 24, 12, 6, 12, 24, 48, 0, 60, 102, 6, 12, 24, 0, 24, 0,		/* 496 to 511 */
+    60, 102, 110, 110, 108, 96, 60, 0, 24, 60, 102, 102, 126, 102, 102, 0,	/* 512 to 527 */
+    124, 102, 102, 124, 102, 102, 124, 0, 60, 102, 96, 96, 96, 102, 60, 0,	/* 528 to 543 */
+  124, 102, 102, 102, 102, 102, 124, 0, 126, 96, 96, 124, 96, 96, 126, 0,	/* 544 to 559 */
+    126, 96, 96, 124, 96, 96, 96, 0, 60, 102, 96, 110, 102, 102, 60, 0,		/* 560 to 575 */
+    102, 102, 102, 126, 102, 102, 102, 0, 60, 24, 24, 24, 24, 24, 60, 0,	/* 576 to 591 */
+    6, 6, 6, 6, 102, 102, 60, 0, 102, 108, 120, 112, 120, 108, 102, 0,	/* 592 to 607 */
+    96, 96, 96, 96, 96, 96, 126, 0, 198, 238, 254, 214, 198, 198, 198, 0,	/* 608 to 623 */
+102, 118, 126, 110, 102, 102, 102, 0, 60, 102, 102, 102, 102, 102, 60, 0,	/* 624 to 639 */
+    124, 102, 102, 124, 96, 96, 96, 0, 60, 102, 102, 102, 102, 110, 60, 6,	/* 640 to 655 */
+    124, 102, 102, 124, 102, 102, 102, 0, 60, 102, 96, 60, 6, 102, 60, 0,	/* 656 to 671 */
+    126, 24, 24, 24, 24, 24, 24, 0, 102, 102, 102, 102, 102, 102, 60, 0,	/* 672 to 687 */
+102, 102, 102, 102, 102, 60, 24, 0, 198, 198, 198, 214, 254, 238, 198, 0,	/* 688 to 703 */
+    102, 102, 60, 24, 60, 102, 102, 0, 102, 102, 102, 60, 24, 24, 24, 0,	/* 704 to 719 */
+    126, 6, 12, 24, 48, 96, 126, 0, 60, 48, 48, 48, 48, 48, 60, 0,	/* 720 to 735 */
+    0, 192, 96, 48, 24, 12, 6, 0, 60, 12, 12, 12, 12, 12, 60, 0,	/* 736 to 751 */
+    24, 60, 102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255,	/* 752 to 767 */
+    24, 24, 12, 0, 0, 0, 0, 0, 0, 0, 60, 6, 62, 102, 62, 0,	/* 768 to 783 */
+    96, 96, 96, 124, 102, 102, 124, 0, 0, 0, 60, 102, 96, 102, 60, 0,	/* 784 to 799 */
+    6, 6, 6, 62, 102, 102, 62, 0, 0, 0, 60, 102, 126, 96, 62, 0,	/* 800 to 815 */
+    28, 54, 48, 124, 48, 48, 48, 0, 0, 0, 62, 102, 102, 62, 6, 60,	/* 816 to 831 */
+    96, 96, 124, 102, 102, 102, 102, 0, 24, 0, 24, 24, 24, 24, 24, 0,	/* 832 to 847 */
+    12, 0, 12, 12, 12, 12, 108, 56, 96, 96, 102, 108, 120, 108, 102, 0,		/* 848 to 863 */
+    48, 48, 48, 48, 48, 48, 24, 0, 0, 0, 236, 254, 214, 214, 198, 0,	/* 864 to 879 */
+    0, 0, 124, 102, 102, 102, 102, 0, 0, 0, 60, 102, 102, 102, 60, 0,	/* 880 to 895 */
+    0, 0, 124, 102, 102, 124, 96, 96, 0, 0, 62, 102, 102, 62, 6, 6,	/* 896 to 911 */
+    0, 0, 124, 102, 96, 96, 96, 0, 0, 0, 62, 96, 60, 6, 124, 0,		/* 912 to 927 */
+    48, 48, 124, 48, 48, 54, 28, 0, 0, 0, 102, 102, 102, 102, 62, 0,	/* 928 to 943 */
+    0, 0, 102, 102, 102, 60, 24, 0, 0, 0, 198, 214, 254, 238, 68, 0,	/* 944 to 959 */
+    0, 0, 102, 60, 24, 60, 102, 0, 0, 0, 102, 102, 102, 62, 6, 60,	/* 960 to 975 */
+    0, 0, 126, 12, 24, 48, 126, 0, 28, 48, 48, 96, 48, 48, 28, 0,	/* 976 to 991 */
+    24, 24, 24, 24, 24, 24, 24, 0, 56, 12, 12, 6, 12, 12, 56, 0,	/* 992 to 1007 */
+    118, 220, 0, 0, 0, 0, 0, 0, 0, 0, 24, 60, 102, 102, 126, 0,		/* 1008 to 1023 */
+    60, 102, 96, 96, 102, 60, 24, 48, 102, 0, 102, 102, 102, 102, 62, 0,	/* 1024 to 1039 */
+    14, 0, 60, 102, 126, 96, 60, 0, 60, 102, 60, 6, 62, 102, 62, 0,	/* 1040 to 1055 */
+    102, 0, 60, 6, 62, 102, 62, 0, 112, 0, 60, 6, 62, 102, 62, 0,	/* 1056 to 1071 */
+    24, 24, 60, 6, 62, 102, 62, 0, 0, 0, 62, 96, 96, 62, 24, 48,	/* 1072 to 1087 */
+    60, 102, 60, 102, 126, 96, 60, 0, 102, 0, 60, 102, 126, 96, 60, 0,	/* 1088 to 1103 */
+    112, 0, 60, 102, 126, 96, 60, 0, 102, 0, 24, 24, 24, 24, 24, 0,	/* 1104 to 1119 */
+    60, 102, 24, 24, 24, 24, 24, 0, 112, 0, 24, 24, 24, 24, 24, 0,	/* 1120 to 1135 */
+    198, 56, 108, 198, 254, 198, 198, 0, 24, 24, 0, 60, 102, 126, 102, 0,	/* 1136 to 1151 */
+    14, 0, 124, 96, 120, 96, 124, 0, 0, 0, 126, 26, 126, 216, 126, 0,	/* 1152 to 1167 */
+  62, 120, 216, 222, 248, 216, 222, 0, 60, 102, 60, 102, 102, 102, 60, 0,	/* 1168 to 1183 */
+    102, 0, 60, 102, 102, 102, 60, 0, 112, 0, 60, 102, 102, 102, 60, 0,		/* 1184 to 1199 */
+    60, 102, 0, 102, 102, 102, 62, 0, 112, 0, 102, 102, 102, 102, 62, 0,	/* 1200 to 1215 */
+    102, 0, 102, 102, 102, 62, 6, 60, 102, 60, 102, 102, 102, 102, 60, 0,	/* 1216 to 1231 */
+    102, 0, 102, 102, 102, 102, 60, 0, 12, 12, 62, 96, 96, 62, 12, 12,	/* 1232 to 1247 */
+    56, 108, 96, 240, 96, 102, 252, 0, 102, 102, 60, 24, 126, 24, 126, 24,	/* 1248 to 1263 */
+  124, 102, 102, 124, 102, 111, 102, 99, 14, 27, 24, 60, 24, 24, 120, 48,	/* 1264 to 1279 */
+    14, 0, 60, 6, 62, 102, 62, 0, 14, 0, 24, 24, 24, 24, 24, 0,		/* 1280 to 1295 */
+    14, 0, 60, 102, 102, 102, 60, 0, 14, 0, 102, 102, 102, 102, 62, 0,	/* 1296 to 1311 */
+  118, 220, 0, 124, 102, 102, 102, 0, 126, 0, 102, 118, 126, 110, 102, 0,	/* 1312 to 1327 */
+    62, 102, 102, 62, 0, 126, 0, 0, 60, 102, 102, 60, 0, 126, 0, 0,	/* 1328 to 1343 */
+    24, 0, 24, 48, 96, 102, 60, 0, 0, 0, 0, 126, 96, 96, 0, 0,	/* 1344 to 1359 */
+    0, 0, 0, 126, 6, 6, 0, 0, 198, 204, 216, 62, 99, 198, 12, 31,	/* 1360 to 1375 */
+    198, 204, 216, 54, 110, 214, 31, 6, 24, 0, 24, 24, 24, 24, 24, 0,	/* 1376 to 1391 */
+    0, 54, 108, 216, 108, 54, 0, 0, 0, 216, 108, 54, 108, 216, 0, 0,	/* 1392 to 1407 */
+  34, 136, 34, 136, 34, 136, 34, 136, 85, 170, 85, 170, 85, 170, 85, 170,	/* 1408 to 1423 */
+    221, 119, 221, 119, 221, 119, 221, 119, 8, 8, 8, 8, 8, 8, 8, 8,	/* 1424 to 1439 */
+    8, 8, 8, 8, 248, 8, 8, 8, 8, 8, 8, 248, 248, 8, 8, 8,	/* 1440 to 1455 */
+    28, 28, 28, 28, 252, 28, 28, 28, 0, 0, 0, 0, 252, 28, 28, 28,	/* 1456 to 1471 */
+    0, 0, 0, 248, 248, 8, 8, 8, 28, 28, 28, 252, 252, 28, 28, 28,	/* 1472 to 1487 */
+    28, 28, 28, 28, 28, 28, 28, 28, 0, 0, 0, 252, 252, 28, 28, 28,	/* 1488 to 1503 */
+    28, 28, 28, 252, 252, 0, 0, 0, 28, 28, 28, 28, 252, 0, 0, 0,	/* 1504 to 1519 */
+    8, 8, 8, 248, 248, 0, 0, 0, 0, 0, 0, 0, 248, 8, 8, 8,	/* 1520 to 1535 */
+    8, 8, 8, 8, 15, 0, 0, 0, 8, 8, 8, 8, 255, 0, 0, 0,	/* 1536 to 1551 */
+    0, 0, 0, 0, 255, 8, 8, 8, 8, 8, 8, 8, 15, 8, 8, 8,	/* 1552 to 1567 */
+    0, 0, 0, 0, 255, 0, 0, 0, 8, 8, 8, 8, 255, 8, 8, 8,		/* 1568 to 1583 */
+    8, 8, 8, 15, 15, 8, 8, 8, 28, 28, 28, 28, 31, 28, 28, 28,	/* 1584 to 1599 */
+    28, 28, 28, 31, 31, 0, 0, 0, 0, 0, 0, 31, 31, 28, 28, 28,	/* 1600 to 1615 */
+    28, 28, 28, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 28, 28, 28,	/* 1616 to 1631 */
+    28, 28, 28, 31, 31, 28, 28, 28, 0, 0, 0, 255, 255, 0, 0, 0,		/* 1632 to 1647 */
+    28, 28, 28, 255, 255, 28, 28, 28, 8, 8, 8, 255, 255, 0, 0, 0,	/* 1648 to 1663 */
+    28, 28, 28, 28, 255, 0, 0, 0, 0, 0, 0, 255, 255, 8, 8, 8,	/* 1664 to 1679 */
+    0, 0, 0, 0, 255, 28, 28, 28, 28, 28, 28, 28, 31, 0, 0, 0,	/* 1680 to 1695 */
+    8, 8, 8, 15, 15, 0, 0, 0, 0, 0, 0, 15, 15, 8, 8, 8,		/* 1696 to 1711 */
+    0, 0, 0, 0, 31, 28, 28, 28, 28, 28, 28, 28, 255, 28, 28, 28,	/* 1712 to 1727 */
+    8, 8, 8, 255, 255, 8, 8, 8, 8, 8, 8, 8, 248, 0, 0, 0,	/* 1728 to 1743 */
+    0, 0, 0, 0, 15, 8, 8, 8, 255, 255, 255, 255, 255, 255, 255, 255,	/* 1744 to 1759 */
+  0, 0, 0, 0, 255, 255, 255, 255, 240, 240, 240, 240, 240, 240, 240, 240,	/* 1760 to 1775 */
+    15, 15, 15, 15, 15, 15, 15, 15, 255, 255, 255, 255, 0, 0, 0, 0,	/* 1776 to 1791 */
+  0, 0, 118, 204, 204, 204, 118, 0, 60, 102, 102, 124, 102, 102, 124, 96,	/* 1792 to 1807 */
+    126, 102, 96, 96, 96, 96, 96, 0, 0, 0, 254, 108, 108, 108, 102, 0,	/* 1808 to 1823 */
+    126, 102, 48, 24, 48, 102, 126, 0, 0, 0, 62, 108, 108, 108, 56, 0,	/* 1824 to 1839 */
+    0, 0, 102, 102, 102, 102, 127, 192, 0, 0, 126, 216, 24, 24, 12, 0,	/* 1840 to 1855 */
+    124, 56, 124, 214, 214, 124, 56, 124, 124, 198, 198, 254, 198, 198, 124, 0,		/* 1856 to 1871 */
+    124, 198, 198, 198, 108, 108, 238, 0, 30, 48, 24, 60, 102, 102, 60, 0,	/* 1872 to 1887 */
+    0, 0, 126, 219, 219, 126, 0, 0, 3, 6, 62, 107, 115, 62, 96, 192,	/* 1888 to 1903 */
+    30, 48, 96, 126, 96, 48, 30, 0, 124, 198, 198, 198, 198, 198, 198, 0,	/* 1904 to 1919 */
+    0, 126, 0, 126, 0, 126, 0, 0, 24, 24, 126, 24, 24, 0, 126, 0,	/* 1920 to 1935 */
+    48, 24, 12, 24, 48, 0, 126, 0, 12, 24, 48, 24, 12, 0, 126, 0,	/* 1936 to 1951 */
+    14, 27, 27, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 216, 216, 112,	/* 1952 to 1967 */
+    24, 24, 0, 126, 0, 24, 24, 0, 0, 118, 220, 0, 118, 220, 0, 0,	/* 1968 to 1983 */
+    60, 102, 102, 60, 0, 0, 0, 0, 0, 0, 0, 24, 24, 0, 0, 0,	/* 1984 to 1999 */
+    0, 0, 0, 0, 24, 0, 0, 0, 30, 24, 24, 24, 24, 216, 120, 56,	/* 2000 to 2015 */
+    120, 108, 108, 108, 108, 0, 0, 0, 56, 12, 24, 48, 60, 0, 0, 0,	/* 2016 to 2031 */
+    0, 0, 60, 60, 60, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0	/* 2032 to 2047 */
+};
+
+unsigned char *gl_font8x8 = __font8x8;
diff --git a/haiku/vgagl/grlib.c b/haiku/vgagl/grlib.c
new file mode 100644
index 0000000..d446fb6
--- /dev/null
+++ b/haiku/vgagl/grlib.c
@@ -0,0 +1,993 @@
+/* Framebuffer Graphics Libary for Linux, Copyright 1993 Harm Hanemaayer */
+/* grlib.c      Main module */
+
+
+#include <stdlib.h>
+#include <vga.h>
+#include "inlstring.h"		/* include inline string operations */
+
+#include "vgagl.h"
+#include "def.h"
+#include "driver.h"
+
+
+/* Global variables */
+
+#ifdef DLL_CONTEXT_SHADOW
+
+/* The current context variable is shadowed in a read-only variable for */
+/* external use. */
+
+GraphicsContext __currentcontext;	/* Internal current context. */
+GraphicsContext currentcontext;	/* Copy for external use. */
+
+#else
+
+GraphicsContext currentcontext;
+
+#endif
+
+void (*__svgalib_nonaccel_fillbox)(int, int, int, int, int);
+static int screenoffset = 0;	/* Used by copy(box)toscreen. */
+
+
+/* Framebuffer function pointers */
+
+static framebufferfunctions ff8 =
+{
+    __svgalib_driver8_setpixel,
+    __svgalib_driver8_getpixel,
+    __svgalib_driver8_hline,
+    __svgalib_driver8_fillbox,
+    __svgalib_driver8_putbox,
+    __svgalib_driver8_getbox,
+    __svgalib_driver8_putboxmask,
+    __svgalib_driver8_putboxpart,
+    __svgalib_driver8_getboxpart,
+    __svgalib_driver8_copybox
+};
+
+static framebufferfunctions ff16 =
+{
+    __svgalib_driver16_setpixel,
+    __svgalib_driver16_getpixel,
+    __svgalib_driver16_hline,
+    __svgalib_driver16_fillbox,
+    __svgalib_driver16_putbox,
+    __svgalib_driver16_getbox,
+    __svgalib_driver16_putboxmask,
+    __svgalib_driver16_putboxpart,
+    __svgalib_driver16_getboxpart,
+    __svgalib_driver16_copybox
+};
+
+static framebufferfunctions ff24 =
+{
+    __svgalib_driver24_setpixel,
+    __svgalib_driver24_getpixel,
+    __svgalib_driver24_hline,
+    __svgalib_driver24_fillbox,
+    __svgalib_driver24_putbox,
+    __svgalib_driver24_getbox,
+    __svgalib_driver24_putboxmask,
+    __svgalib_driver24_putboxpart,
+    __svgalib_driver24_getboxpart,
+    __svgalib_driver24_copybox
+};
+
+static framebufferfunctions ff32 =
+{
+    __svgalib_driver32_setpixel,
+    __svgalib_driver32_getpixel,
+    __svgalib_driver32_hline,
+    __svgalib_driver32_fillbox,
+    __svgalib_driver32_putbox,
+    __svgalib_driver32_getbox,
+    __svgalib_driver32_putboxmask,
+    __svgalib_driver32_putboxpart,
+    __svgalib_driver32_getboxpart,
+    __svgalib_driver32_copybox
+};
+
+static framebufferfunctions ff8paged =
+{
+    __svgalib_driver8p_setpixel,
+    __svgalib_driver8p_getpixel,
+    __svgalib_driver8p_hline,
+    __svgalib_driver8p_fillbox,
+    __svgalib_driver8p_putbox,
+    __svgalib_driver8p_getbox,
+    __svgalib_driver8p_putboxmask,
+    __svgalib_driver8p_putboxpart,
+    __svgalib_driver8p_getboxpart,
+    __svgalib_driver8p_copybox
+};
+
+static framebufferfunctions ff16paged =
+{
+    __svgalib_driver16p_setpixel,
+    __svgalib_driver16p_getpixel,
+    __svgalib_driver16p_hline,
+    __svgalib_driver16p_fillbox,
+    __svgalib_driver16p_putbox,
+    __svgalib_driver16p_getbox,
+    __svgalib_driver16p_putboxmask,
+    __svgalib_driver16p_putboxpart,
+    __svgalib_driver16p_getboxpart,
+    __svgalib_driver16p_copybox
+};
+
+static framebufferfunctions ff24paged =
+{
+    __svgalib_driver24p_setpixel,
+    __svgalib_driver24p_getpixel,
+    __svgalib_driver24p_hline,
+    __svgalib_driver24p_fillbox,
+    __svgalib_driver24p_putbox,
+    __svgalib_driver24p_getbox,
+    __svgalib_driver24p_putboxmask,
+    __svgalib_driver24p_putboxpart,
+    __svgalib_driver24p_getboxpart,
+    __svgalib_driver24p_copybox
+};
+
+static framebufferfunctions ff32paged =
+{
+    __svgalib_driver32p_setpixel,
+    __svgalib_driver32p_getpixel,
+    __svgalib_driver32p_hline,
+    __svgalib_driver32p_fillbox,
+    __svgalib_driver32p_putbox,
+    __svgalib_driver32p_getbox,
+    __svgalib_driver32p_putboxmask,
+    __svgalib_driver32p_putboxpart,
+    __svgalib_driver32p_getboxpart,
+    __svgalib_driver32p_copybox
+};
+
+static framebufferfunctions ffplanar256 =
+{
+    (void *) __svgalib_driverplanar256_nothing,
+    (void *) __svgalib_driverplanar256_nothing,
+    (void *) __svgalib_driverplanar256_nothing,
+    (void *) __svgalib_driverplanar256_nothing,
+    __svgalib_driverplanar256_putbox,
+    (void *) __svgalib_driverplanar256_nothing,
+    (void *) __svgalib_driverplanar256_nothing,
+    (void *) __svgalib_driverplanar256_nothing,
+    (void *) __svgalib_driverplanar256_nothing,
+    (void *) __svgalib_driverplanar256_nothing,
+};
+
+#if 0				/* Not yet used */
+static framebufferfunctions ffplanar16 =
+{
+    (void *) __svgalib_driverplanar16_nothing,
+    (void *) __svgalib_driverplanar16_nothing,
+    (void *) __svgalib_driverplanar16_nothing,
+    (void *) __svgalib_driverplanar16_nothing,
+    (void *) __svgalib_driverplanar16_nothing,
+    (void *) __svgalib_driverplanar16_nothing,
+    (void *) __svgalib_driverplanar16_nothing,
+    (void *) __svgalib_driverplanar16_nothing,
+    (void *) __svgalib_driverplanar16_nothing,
+    (void *) __svgalib_driverplanar16_nothing,
+};
+#endif
+
+
+/* Initialization and graphics contexts */
+
+#define SCREENSIZE(gc) ((gc).bytewidth * (gc).height)
+
+static int colorbits(int c)
+{
+    switch (c) {
+    default:
+    case 256:
+	return 8;
+    case 32768:
+	return 15;
+    case 65536:
+	return 16;
+    case 256 * 65536:
+	return 24;
+    }
+}
+
+int gl_setcontextvga(int m)
+{
+    framebufferfunctions *ff;
+    vga_modeinfo *modeinfo;
+    int accelfuncs;
+    if (!vga_hasmode(m))
+	return -1;
+    modeinfo = vga_getmodeinfo(m);
+    /* Set graphics context */
+    WIDTH = modeinfo->width;
+    HEIGHT = modeinfo->height;
+    BYTESPERPIXEL = modeinfo->bytesperpixel;
+    COLORS = modeinfo->colors;
+    BITSPERPIXEL = colorbits(COLORS);
+    BYTEWIDTH = modeinfo->linewidth;
+    VBUF = vga_getgraphmem();
+    MODEFLAGS = 0;
+    __clip = 0;
+    ff = &(__currentcontext.ff);
+    if (modeinfo->flags & IS_MODEX) {
+	/* Pretend it's a regular (linear) context. */
+	BYTESPERPIXEL = 1;
+	BYTEWIDTH *= 4;
+	MODETYPE = CONTEXT_MODEX;
+	if (BYTEWIDTH * HEIGHT * 2 <= 256 * 1024)
+	    MODEFLAGS |= MODEFLAG_PAGEFLIPPING_CAPABLE;
+	if (BYTEWIDTH * HEIGHT * 3 <= 256 * 1024)
+	    MODEFLAGS |= MODEFLAG_TRIPLEBUFFERING_CAPABLE;
+	__currentcontext.ff = ffplanar256;
+    } else if (modeinfo->colors == 16) {
+	/* Pretend it's a regular one byte per pixel context. */
+	BYTESPERPIXEL = 1;
+	BYTEWIDTH *= 8;
+	MODETYPE = CONTEXT_PLANAR16;
+	if (BYTEWIDTH * HEIGHT <= 256 * 1024)
+	    MODEFLAGS |= MODEFLAG_PAGEFLIPPING_CAPABLE;
+	if (BYTEWIDTH * HEIGHT * 3 / 2 <= 256 * 1024)
+	    MODEFLAGS |= MODEFLAG_TRIPLEBUFFERING_CAPABLE;
+    } else if ((m == G320x200x256 && modeinfo->maxpixels <= 65536) ||
+	       (modeinfo->flags & IS_LINEAR)
+#if 0				/* svgalib doesn't VT-switch correctly with linear addressing. */
+	       || ((modeinfo->flags & CAPABLE_LINEAR)
+	/* Creepy. Try linear addressing only if the mode is set. */
+	&& vga_getcurrentmode() == m && (vga_setlinearaddressing() != -1))
+#endif
+	) {
+	/* No banking. */
+	/* Get get the fb address in case we set linear addressing. */
+	VBUF = vga_getgraphmem();
+	MODETYPE = CONTEXT_LINEAR;
+	if (modeinfo->maxpixels >= WIDTH * HEIGHT * 2)
+	    MODEFLAGS |= MODEFLAG_PAGEFLIPPING_CAPABLE;
+	if (modeinfo->maxpixels >= WIDTH * HEIGHT * 3)
+	    MODEFLAGS |= MODEFLAG_TRIPLEBUFFERING_CAPABLE;
+	switch (BYTESPERPIXEL) {
+	case 1:
+	    __currentcontext.ff = ff8;
+	    break;
+	case 2:
+	    __currentcontext.ff = ff16;
+	    break;
+	case 3:
+	    __currentcontext.ff = ff24;
+	    break;
+	case 4:
+	    __currentcontext.ff = ff32;
+	    break;
+	}
+	if (modeinfo->flags & RGB_MISORDERED)
+	    MODEFLAGS |= MODEFLAG_32BPP_SHIFT8;
+    } else {
+	/* Banked mode. */
+	MODETYPE = CONTEXT_PAGED;
+	if (modeinfo->maxpixels >= WIDTH * HEIGHT * 2)
+	    MODEFLAGS |= MODEFLAG_PAGEFLIPPING_CAPABLE;
+	if (modeinfo->maxpixels >= WIDTH * HEIGHT * 3)
+	    MODEFLAGS |= MODEFLAG_TRIPLEBUFFERING_CAPABLE;
+	if ((modeinfo->startaddressrange & 0x1ffff) == 0x10000) {
+	    /* This hack is required for 320x200x256 page flipping */
+	    /* on Trident, which doesn't work with bank boundary */
+	    /* within the second page. */
+	    MODEFLAGS |= MODEFLAG_FLIPPAGE_BANKALIGNED;
+	}
+	switch (BYTESPERPIXEL) {
+	case 1:
+	    __currentcontext.ff = ff8paged;
+	    break;
+	case 2:
+	    __currentcontext.ff = ff16paged;
+	    break;
+	case 3:
+	    __currentcontext.ff = ff24paged;
+	    break;
+	case 4:
+	    __currentcontext.ff = ff32paged;
+	    break;
+	}
+	if (modeinfo->flags & RGB_MISORDERED)
+	    MODEFLAGS |= MODEFLAG_32BPP_SHIFT8;
+    }
+    if (vga_getcurrentmode() == m) {
+	accelfuncs = vga_ext_set(VGA_EXT_AVAILABLE, VGA_AVAIL_ACCEL);
+	__svgalib_nonaccel_fillbox = __currentcontext.ff.driver_fillbox_func;
+	if (accelfuncs & ACCELFLAG_FILLBOX)
+	    __currentcontext.ff.driver_fillbox_func =
+		__svgalib_driver8a_fillbox;
+	if (accelfuncs & ACCELFLAG_SCREENCOPY)
+	    __currentcontext.ff.driver_copybox_func =
+		__svgalib_driver8a_copybox;
+    }
+#ifdef DLL_CONTEXT_SHADOW
+    currentcontext = __currentcontext;
+#endif
+    return 0;
+}
+
+int gl_setcontextvgavirtual(int m)
+{
+    vga_modeinfo *modeinfo;
+    if (!vga_hasmode(m))
+	return -1;
+    modeinfo = vga_getmodeinfo(m);
+    /* Set graphics context */
+    WIDTH = modeinfo->width;
+    HEIGHT = modeinfo->height;
+    if (modeinfo->flags & IS_MODEX) {
+	/* Use a regular virtual screen for planar 256 color modes. */
+	BYTESPERPIXEL = 1;
+	BYTEWIDTH = modeinfo->linewidth * 4;
+    } else if (modeinfo->colors == 16) {
+	/* Use a regular one byte per pixel virtual screen for */
+	/* planar 16 color modes. */
+	BYTESPERPIXEL = 1;
+	BYTEWIDTH = modeinfo->linewidth * 8;
+    } else {
+	BYTESPERPIXEL = modeinfo->bytesperpixel;
+	BYTEWIDTH = modeinfo->linewidth;
+    }
+    COLORS = modeinfo->colors;
+    BITSPERPIXEL = colorbits(COLORS);
+    VBUF = malloc(SCREENSIZE(__currentcontext));
+    MODETYPE = CONTEXT_VIRTUAL;
+    MODEFLAGS = 0;
+    __clip = 0;
+    switch (BYTESPERPIXEL) {
+    case 1:
+	__currentcontext.ff = ff8;
+	break;
+    case 2:
+	__currentcontext.ff = ff16;
+	break;
+    case 3:
+	__currentcontext.ff = ff24;
+	break;
+    case 4:
+	__currentcontext.ff = ff32;
+	break;
+    }
+#ifdef DLL_CONTEXT_SHADOW
+    currentcontext = __currentcontext;
+#endif
+    return 0;
+}
+
+void gl_setcontextvirtual(int w, int h, int bpp, int bitspp, void *v)
+{
+    WIDTH = w;
+    HEIGHT = h;
+    BYTESPERPIXEL = bpp;
+    BITSPERPIXEL = bitspp;
+    COLORS = 1 << bitspp;
+    BYTEWIDTH = WIDTH * BYTESPERPIXEL;
+    VBUF = v;
+    MODETYPE = CONTEXT_VIRTUAL;
+    MODEFLAGS = 0;
+    switch (BYTESPERPIXEL) {
+    case 1:
+	__currentcontext.ff = ff8;
+	break;
+    case 2:
+	__currentcontext.ff = ff16;
+	break;
+    case 3:
+	__currentcontext.ff = ff24;
+	break;
+    case 4:
+	__currentcontext.ff = ff32;
+	break;
+    }
+    __clip = 0;
+#ifdef DLL_CONTEXT_SHADOW
+    currentcontext = __currentcontext;
+#endif
+}
+
+GraphicsContext *
+ gl_allocatecontext()
+{
+    return malloc(sizeof(GraphicsContext));
+}
+
+void gl_setcontext(GraphicsContext * gc)
+{
+    __currentcontext = *gc;
+#ifdef DLL_CONTEXT_SHADOW
+    currentcontext = *gc;
+#endif
+}
+
+void gl_getcontext(GraphicsContext * gc)
+{
+    *gc = __currentcontext;
+}
+
+void gl_freecontext(GraphicsContext * gc)
+{
+    if (gc->modetype == CONTEXT_VIRTUAL)
+	free(gc->vbuf);
+}
+
+void gl_setcontextwidth(int w)
+{
+    __currentcontext.width = currentcontext.width = w;
+    __currentcontext.bytewidth = currentcontext.bytewidth =
+	w * BYTESPERPIXEL;
+}
+
+void gl_setcontextheight(int h)
+{
+    __currentcontext.height = currentcontext.height = h;
+}
+
+
+/* Clipping */
+
+void gl_setclippingwindow(int x1, int y1, int x2, int y2)
+{
+    __clip = 1;
+    __clipx1 = x1;
+    __clipy1 = y1;
+    __clipx2 = x2;
+    __clipy2 = y2;
+}
+
+void gl_enableclipping()
+{
+    __clip = 1;
+    __clipx1 = 0;
+    __clipy1 = 0;
+    __clipx2 = WIDTH - 1;
+    __clipy2 = HEIGHT - 1;
+}
+
+void gl_disableclipping()
+{
+    __clip = 0;
+}
+
+
+/* Primitive functions */
+
+void gl_setpixel(int x, int y, int c)
+{
+    if (__clip && outside(x, y))
+	return;
+    setpixel(x, y, c);
+}
+
+int gl_getpixel(int x, int y)
+{
+    if (__clip && outside(x, y))
+	return -1;
+    return getpixel(x, y);
+}
+
+void gl_hline(int x1, int y, int x2, int c)
+{
+    if (__clip) {
+	if (y_outside(y))
+	    return;
+	clipxleft(x1);
+	clipxright(x2);
+    }
+    if (x1 > x2)
+	return;
+    hline(x1, y, x2, c);
+}
+
+#define ADJUSTBITMAPBOX() \
+	nw = w; nh = h; nx = x; ny = y;				\
+	if (nx + nw < __clipx1 || nx > __clipx2)		\
+		return;						\
+	if (ny + nh < __clipy1 || ny > __clipy2)		\
+		return;						\
+	if (nx < __clipx1) {		/* left adjust */	\
+		nw += nx - __clipx1;				\
+		nx = __clipx1;					\
+	}							\
+	if (ny < __clipy1) {		/* top adjust */	\
+		nh += ny - __clipy1;				\
+		ny = __clipy1;					\
+	}							\
+	if (nx + nw > __clipx2)		/* right adjust */	\
+		nw = __clipx2 - nx + 1;				\
+	if (ny + nh > __clipy2)		/* bottom adjust */	\
+		nh = __clipy2 - ny + 1;				\
+
+void gl_fillbox(int x, int y, int w, int h, int c)
+{
+    if (__clip) {
+	if (x + w < __clipx1 || x > __clipx2)
+	    return;
+	if (y + h < __clipy1 || y > __clipy2)
+	    return;
+	if (x < __clipx1) {
+	    w -= __clipx1 - x;
+	    x = __clipx1;
+	}
+	if (y < __clipy1) {
+	    h -= __clipy1 - y;
+	    y = __clipy1;
+	}
+	if (x + w > __clipx2 + 1)
+	    w = __clipx2 - x + 1;
+	if (y + h > __clipy2 + 1)
+	    h = __clipy2 - y + 1;
+    }
+    if (w <= 0 || h <= 0)
+	return;
+    fillbox(x, y, w, h, c);
+}
+
+void gl_putboxpart(int x, int y, int w, int h, int ow, int oh, void *b,
+		   int ox, int oy)
+{
+    putboxpart(x, y, w, h, ow, oh, b, ox, oy);
+}
+
+void gl_putbox(int x, int y, int w, int h, void *b)
+{
+    uchar *bp = b;
+    if (w <= 0 || h <= 0)
+	return;
+    if (__clip) {
+	int nx, ny, nw, nh;
+	ADJUSTBITMAPBOX();
+	if (nw <= 0 || nh <= 0)
+	    return;
+	if (nw != w || nh != h) {
+	    putboxpart(nx, ny, nw, nh, w, h, bp, nx - x, ny - y);
+	    return;
+	}
+    }
+    putbox(x, y, w, h, bp, w);
+}
+
+static void emulate_putboxmask(int x, int y, int w, int h, void *b)
+{
+    void *box;
+    GraphicsContext gc;
+    box = alloca(w * h * BYTESPERPIXEL);
+    gl_getbox(x, y, w, h, box);	/* does clipping */
+
+    gl_getcontext(&gc);		/* save context */
+
+    /* create context that is only the box */
+    gl_setcontextvirtual(w, h, BYTESPERPIXEL, BITSPERPIXEL, box);
+    gl_putboxmask(0, 0, w, h, b);
+
+    gl_setcontext(&gc);		/* restore context */
+    gl_putbox(x, y, w, h, box);
+}
+
+void gl_putboxmask(int x, int y, int w, int h, void *b)
+{
+    if (w <= 0 || h <= 0)
+	return;
+    if (__clip) {
+	if (x + w < __clipx1 || x > __clipx2)
+	    return;
+	if (y + h < __clipy1 || y > __clipy2)
+	    return;
+	if (x < __clipx1 || y < __clipy1
+	    || x + w > __clipx2 + 1 || y + h > __clipy2 + 1) {
+	    /* clipping is not directly implemented */
+	    emulate_putboxmask(x, y, w, h, b);
+	    return;
+	}
+    }
+    if (MODETYPE == CONTEXT_PAGED)
+	/* paged primitive is not implemented */
+	emulate_putboxmask(x, y, w, h, b);
+    else
+	putboxmask(x, y, w, h, b);
+}
+
+void gl_getbox(int x, int y, int w, int h, void *b)
+{
+    if (__clip) {
+	int nx, ny, nw, nh;
+	ADJUSTBITMAPBOX();
+	if (nw <= 0 || nh <= 0)
+	    return;
+	if (nw != w || nh != h) {
+	    getboxpart(nx, ny, nw, nh, w, h, b, nx - x, ny - y);
+	    return;
+	}
+    }
+    getbox(x, y, w, h, b, w);
+}
+
+void gl_copybox(int x1, int y1, int w, int h, int x2, int y2)
+{
+/* Doesn't handle clipping. */
+    if (MODETYPE == CONTEXT_PAGED) {
+	/* Paged primitive is not implemented. */
+	void *box;
+	box = alloca(w * h * BYTESPERPIXEL);
+	getbox(x1, y1, w, h, box, w);
+	putbox(x2, y2, w, h, box, w);
+	return;
+    }
+    copybox(x1, y1, w, h, x2, y2);
+}
+
+
+/* Miscellaneous functions */
+
+void gl_clearscreen(int c)
+{
+    gl_fillbox(0, 0, WIDTH, HEIGHT, c);
+}
+
+int gl_rgbcolor(int r, int g, int b)
+{
+    unsigned v;
+    switch (BITSPERPIXEL) {
+    case 8:
+	/* assumes RGB palette at index 0-255 */
+	/* bits 0-2 = blue (3 bits) */
+	/*      3-5 = green (3 bits) */
+	/*      6-7 = red (2 bits) */
+	return (r & 0xc0) + ((g & 0xe0) >> 2) + (b >> 5);
+    case 24:
+    case 32:
+	v = (r << 16) + (g << 8) + b;
+	if (MODEFLAGS & MODEFLAG_32BPP_SHIFT8)
+	    return v << 8;
+	return v;
+    case 15:
+	return ((r & 0xf8) << 7) + ((g & 0xf8) << 2) + (b >> 3);
+    case 16:
+	return ((r & 0xf8) << 8) + ((g & 0xfc) << 3) + (b >> 3);
+    case 4:
+	/* Now this is real fun. Map to standard EGA palette. */
+	v = 0;
+	if (b >= 64)
+	    v += 1;
+	if (g >= 64)
+	    v += 2;
+	if (r >= 64)
+	    v += 4;
+	if (b >= 192 || g >= 192 || r >= 192)
+	    v += 8;
+	return v;
+    }
+    return -1;
+}
+
+void gl_setpixelrgb(int x, int y, int r, int g, int b)
+{
+/* Color components range from 0 to 255 */
+    if (__clip && outside(x, y))
+	return;
+    setpixel(x, y, gl_rgbcolor(r, g, b));
+}
+
+void gl_getpixelrgb(int x, int y, int *r, int *g, int *b)
+{
+    unsigned c;
+    if (__clip && outside(x, y)) {
+	*r = *g = *b = -1;
+	return;
+    }
+    c = getpixel(x, y);
+    switch (BITSPERPIXEL) {
+    case 8:
+	*b = (c & (1 + 2 + 4)) << 5;	/* bits 0-2 */
+	*g = (c & (8 + 16 + 32)) << 2;	/* bits 3-5 */
+	*r = (c & (64 + 128));	/* bits 6-7 */
+	break;
+    case 32:
+	if (MODEFLAGS & MODEFLAG_32BPP_SHIFT8) {
+	    *b = (c & 0xff00) >> 8;
+	    *g = (c & 0xff0000) >> 16;
+	    *r = c >> 24;
+	    break;
+	}
+    case 24:
+	*b = c & 0xff;
+	*g = (c & 0xff00) >> 8;
+	*r = c >> 16;
+	break;
+    case 15:
+	*b = (c & (1 + 2 + 4 + 8 + 16)) << 3;
+	*g = (c & (32 + 64 + 128 + 256 + 512)) >> 2;
+	*r = (c & (1024 + 2048 + 4096 + 8192 + 16384)) >> 7;
+	break;
+    case 16:
+	*b = (c & (1 + 2 + 4 + 8 + 16)) << 3;
+	*g = (c & (32 + 64 + 128 + 256 + 512 + 1024)) >> 3;
+	*r = (c & (2048 + 4096 + 8192 + 16384 + 32768)) >> 8;
+	break;
+    case 4:
+	*b = (c & 1) * ((c & 8) ? 255 : 128);
+	*g = (c & 2) * ((c & 8) ? 255 : 128);
+	*r = (c & 4) * ((c & 8) ? 255 : 128);
+	break;
+    }
+}
+
+void gl_setdisplaystart(int x, int y)
+{
+    vga_setdisplaystart(y * BYTEWIDTH + x * BYTESPERPIXEL);
+}
+
+
+/* Screen copying */
+
+void gl_setscreenoffset(int o)
+{
+    screenoffset = o;
+}
+
+int gl_enablepageflipping(GraphicsContext * gc)
+{
+    if (gc->modeflags & MODEFLAG_PAGEFLIPPING_CAPABLE) {
+	gc->modeflags |= MODEFLAG_PAGEFLIPPING_ENABLED;
+    }
+    if (gc->modeflags & MODEFLAG_TRIPLEBUFFERING_CAPABLE) {
+	gc->modeflags &= ~(MODEFLAG_PAGEFLIPPING_ENABLED);
+	gc->modeflags |= MODEFLAG_TRIPLEBUFFERING_ENABLED;
+    }
+    gc->flippage = 0;
+    if (gc->modeflags & MODEFLAG_TRIPLEBUFFERING_ENABLED)
+	return 3;
+    if (gc->modeflags & MODEFLAG_PAGEFLIPPING_ENABLED)
+	return 2;
+    return 0;
+}
+
+void gl_copyscreen(GraphicsContext * gc)
+{
+    int size;
+    void *svp, *dvp;
+
+    if (gc->modeflags & MODEFLAG_PAGEFLIPPING_ENABLED)
+	gc->flippage ^= 1;
+    if (gc->modeflags & MODEFLAG_TRIPLEBUFFERING_ENABLED)
+	gc->flippage = (gc->flippage + 1) % 3;
+    if (gc->modeflags & (MODEFLAG_PAGEFLIPPING_ENABLED |
+			 MODEFLAG_TRIPLEBUFFERING_ENABLED)) {
+	/* Calculate screen offset in bytes. */
+	screenoffset = gc->bytewidth * HEIGHT * gc->flippage;
+	if (gc->modeflags & MODEFLAG_FLIPPAGE_BANKALIGNED)
+	    screenoffset = ((screenoffset + 0xffff) & ~0xffff);
+    }
+    if (gc->modetype == CONTEXT_MODEX) {
+	vga_copytoplanar256(VBUF, BYTEWIDTH, screenoffset / 4,
+			    gc->bytewidth / 4, WIDTH, HEIGHT);
+	goto end;
+    }
+    if (gc->modetype == CONTEXT_PLANAR16) {
+	if (WIDTH == 1024 && HEIGHT >= 512 &&
+	    ((screenoffset / 8) & 0xffff) == 0) {
+	    /* Kludge to allow 1024x768x16 with page flipping. */
+	    int page;
+	    page = (screenoffset / 8) >> 16;
+	    vga_setpage(page);
+	    vga_copytoplanar16(VBUF, BYTEWIDTH, 0,
+			       gc->bytewidth / 8, WIDTH, 512);
+	    vga_setpage(page + 1);
+	    vga_copytoplanar16(VBUF + WIDTH * 512, BYTEWIDTH,
+			       0, gc->bytewidth / 8, WIDTH, HEIGHT - 512);
+	    return;
+	}
+	if (WIDTH * HEIGHT >= 512 * 1024)
+	    /* We don't handle banking. */
+	    return;
+
+	vga_copytoplanar16(VBUF, BYTEWIDTH, screenoffset / 8,
+			   gc->bytewidth / 8, WIDTH, HEIGHT);
+	goto end;
+    }
+    if (BYTESPERPIXEL == 4 && gc->bytesperpixel == 3) {
+	/* Special case. */
+	int soffset, doffset;
+	if (BYTEWIDTH / 4 != gc->bytewidth / 3) {
+	    /* Even more special case for physical truecolor */
+	    /* modes that have extra scanline padding. */
+	    /* This has the effect of slowing down */
+	    /* '3d' in some truecolor modes on ATI mach32. */
+	    gl_copyboxtocontext(0, 0, WIDTH, HEIGHT, gc, 0, 0);
+	    goto end;
+	}
+	soffset = 0;
+	doffset = screenoffset;
+	size = WIDTH * HEIGHT;
+	while (soffset / 4 < size) {
+	    int schunk, dchunk;
+	    int count;
+	    schunk = __svgalib_driver_setread(&__currentcontext, soffset, &svp);
+	    dchunk = __svgalib_driver_setwrite(gc, doffset, &dvp);
+	    if (dchunk == 1) {
+		/* One byte left in segment. */
+		int pix;
+		pix = *(unsigned *) svp;	/* 32-bit pixel */
+		*(unsigned char *) dvp = pix;
+		dchunk = __svgalib_driver_setwrite(gc, doffset + 1, &dvp);
+		*(unsigned short *) dvp = pix >> 8;
+		count = 1;	/* 1 pixel handled. */
+	    } else if (dchunk == 2) {
+		/* Two bytes left. */
+		int pix;
+		pix = *(unsigned *) svp;	/* 32-bit pixel */
+		*(unsigned short *) dvp = pix;
+		dchunk = __svgalib_driver_setwrite(gc, doffset + 2, &dvp);
+		*(unsigned char *) dvp = pix >> 16;
+		count = 1;	/* 1 pixel handled. */
+	    } else {
+		count = min(min(schunk / 4, dchunk / 3),
+			    size - (soffset / 4));
+		__svgalib_memcpy4to3(dvp, svp, count);
+	    }
+	    soffset += count * 4;
+	    doffset += count * 3;
+	}
+	goto end;
+    }
+    if (BYTESPERPIXEL == 4 && gc->bytesperpixel == 4 &&
+	(gc->modeflags & MODEFLAG_32BPP_SHIFT8)) {
+	int soffset = 0;
+	int doffset = screenoffset;
+	size = SCREENSIZE(__currentcontext);
+	while (soffset < size) {
+	    int schunk, dchunk;
+	    int count;
+	    schunk = __svgalib_driver_setread(&__currentcontext, soffset, &svp);
+	    dchunk = __svgalib_driver_setwrite(gc, doffset, &dvp);
+	    count = min(min(schunk, dchunk), (size - soffset));
+	    __svgalib_memcpy32shift8(dvp, svp, count / 4);
+	    soffset += count;
+	    doffset += count;
+	}
+    } else {
+	int soffset = 0;
+	int doffset = screenoffset;
+	size = SCREENSIZE(__currentcontext);
+	while (soffset < size) {
+	    int schunk, dchunk;
+	    int count;
+	    schunk = __svgalib_driver_setread(&__currentcontext, soffset, &svp);
+	    dchunk = __svgalib_driver_setwrite(gc, doffset, &dvp);
+	    count = min(min(schunk, dchunk), (size - soffset));
+	    __memcpy(dvp, svp, count);
+	    soffset += count;
+	    doffset += count;
+	}
+    }
+
+  end:
+    if (gc->modeflags & (MODEFLAG_PAGEFLIPPING_ENABLED |
+			 MODEFLAG_TRIPLEBUFFERING_ENABLED)) {
+	GraphicsContext save;
+	/* setdisplaystart will use BYTEWIDTH of the virtual screen, */
+	/* which is what we want since vga_setdisplaystart is */
+	/* defined in terms of pixel offset (except for hicolor */
+	/* modes, which are defined in terms of bytes). */
+	gl_getcontext(&save);
+	gl_setcontext(gc);
+	if (gc->modeflags & MODEFLAG_FLIPPAGE_BANKALIGNED)
+	    vga_setdisplaystart(screenoffset);
+	else
+	    gl_setdisplaystart(0, gc->height * gc->flippage);
+	gl_setcontext(&save);
+	/* For page flipping, it might be appropriate to add a */
+	/* waitverticalretrace here. */
+    }
+    screenoffset = 0;
+}
+
+void gl_copyboxtocontext(int x1, int y1, int w, int h, GraphicsContext * gc,
+			 int x2, int y2)
+{
+/* This is now reasonably efficient if clipping is not enabled. */
+    void *buf;
+    GraphicsContext save;
+    gl_getcontext(&save);
+    if ((MODETYPE == CONTEXT_LINEAR || MODETYPE == CONTEXT_VIRTUAL) &&
+	(BYTESPERPIXEL == gc->bytesperpixel) &&
+	!__clip && !gc->clip) {
+#ifdef DLL_CONTEXT_SHADOW
+	__currentcontext = *gc;
+#else
+	gl_setcontext(gc);
+#endif
+/*
+ * Note: Using save.bytewidth / BYTESPERPIXEL is probably not an optimal hack here.
+ * it would be better to transfer save.bytewidth to putbox as it is what is really
+ * used there. However, putbox is used all over interpreting the last entry as a
+ * pixel count, so we keep it this way to avoid problems if some other place not
+ * updated by accident.
+ */
+	putbox(x2, y2 + screenoffset / BYTEWIDTH, w, h, save.vbuf +
+	       y1 * save.bytewidth + x1 * BYTESPERPIXEL,
+	       save.bytewidth / BYTESPERPIXEL);
+	goto end;
+    }
+    buf = alloca(w * h * BYTESPERPIXEL);
+    gl_getbox(x1, y1, w, h, buf);
+#ifdef DLL_CONTEXT_SHADOW
+    __currentcontext = *gc;
+#else
+    gl_setcontext(gc);
+#endif
+
+    if (save.bytesperpixel == 4 && gc->bytesperpixel == 3) {
+	/* Special case conversion from 32-bit virtual screen to */
+	/* 24-bit truecolor framebuffer. */
+	if (gc->modetype == CONTEXT_PAGED || gc->clip) {
+	    /* For paged modes or clipping, use another buffer. */
+	    void *buf2;
+	    buf2 = alloca(w * h * 3);
+	    __svgalib_memcpy4to3(buf2, buf, w * h);
+	    gl_putbox(x2, y2 + screenoffset / BYTEWIDTH, w, h,
+		      buf2);
+	} else
+	    /* No clipping, linear. */
+	    __svgalib_driver24_putbox32(x2, y2, w, h, buf, w);
+    } else			/* Contexts assumed to have same pixel size. */
+	gl_putbox(x2, y2 + screenoffset / BYTEWIDTH, w, h, buf);
+
+  end:
+#ifdef DLL_CONTEXT_SHADOW
+    __currentcontext = save;
+#else
+    gl_setcontext(&save);
+#endif
+}
+
+void gl_copyboxfromcontext(GraphicsContext * gc, int x1, int y1, int w, int h,
+			   int x2, int y2)
+{
+    void *buf;
+    GraphicsContext save;
+    if ((gc->modetype == CONTEXT_LINEAR || gc->modetype == CONTEXT_VIRTUAL) &&
+	(BYTESPERPIXEL == gc->bytesperpixel) &&
+	!__clip && !gc->clip) {
+/*
+ * see above on  gc->bytewidth / BYTESPERPIXEL.
+ */
+	putbox(x2, y2 + screenoffset / BYTEWIDTH, w, h, gc->vbuf +
+	       y1 * gc->bytewidth + x1 * BYTESPERPIXEL,
+	       gc->bytewidth / BYTESPERPIXEL);
+	return;
+    }
+    gl_getcontext(&save);
+#ifdef DLL_CONTEXT_SHADOW
+    __currentcontext = *gc;
+#else
+    gl_setcontext(gc);
+#endif
+    buf = alloca(w * h * BYTESPERPIXEL);
+    gl_getbox(x1, y1, w, h, buf);
+#ifdef DLL_CONTEXT_SHADOW
+    __currentcontext = save;
+#else
+    gl_setcontext(&save);
+#endif
+
+    if (gc->bytesperpixel == 4 && save.bytesperpixel == 3) {
+	/* Special case conversion from 32-bit virtual screen to */
+	/* 24-bit truecolor framebuffer. */
+	if (save.modetype == CONTEXT_PAGED || save.clip) {
+	    /* For paged modes or clipping, use another buffer. */
+	    void *buf2;
+	    buf2 = alloca(w * h * 3);
+	    __svgalib_memcpy4to3(buf2, buf, w * h);
+	    gl_putbox(x2, y2 + screenoffset / BYTEWIDTH, w, h,
+		      buf2);
+	} else
+	    /* No clipping, linear. */
+	    __svgalib_driver24_putbox32(x2, y2, w, h, buf, w);
+    } else			/* Contexts assumed to have same pixel size. */
+	gl_putbox(x2, y2 + screenoffset / BYTEWIDTH, w, h, buf);
+}
diff --git a/haiku/vgagl/inlstring.h b/haiku/vgagl/inlstring.h
new file mode 100644
index 0000000..2e6ec7f
--- /dev/null
+++ b/haiku/vgagl/inlstring.h
@@ -0,0 +1,321 @@
+/* Based on functions in linux/string.h */
+
+#include <sys/types.h>	/* for size_t */
+
+#if defined(__alpha__) || defined (NO_ASSEMBLY)
+
+#define __memcpy(dst,src,n)			memcpy((dst),(src),(n))
+#define __memcpy_conventional(dst,src,n)	memcpy((dst),(src),(n))
+#define __memcpyb(dst,src,n)			memcpy((dst),(src),(n))
+#define __memsetb(dst,c,n)			memset((dst),(c),(n))
+#define __memsetlong(dst,c,n)			memset((dst),(c),(n))
+#define __memset(dst,c,n)			memset((dst),(c),(n))
+#define __memset2(dst,c,n)			memset((dst),(c),2*(n))
+#define __memset3(dst,c,n)			memset((dst),(c),3*(n))
+
+#else
+
+static inline void *
+ __memcpy_conventional(void *to, const void *from, size_t n)
+{
+  int dummy1;
+  long dummy2, dummy3;
+    __asm__ __volatile__("cld\n\t"
+    	    "cmpl $0,%%edx\n\t"
+    	    "jle 2f\n\t"
+	    "movl %%edi,%%ecx\n\t"
+	    "andl $1,%%ecx\n\t"
+	    "subl %%ecx,%%edx\n\t"
+	    "rep ; movsb\n\t"	/* 16-bit align destination */
+	    "movl %%edx,%%ecx\n\t"
+	    "shrl $2,%%ecx\n\t"
+	    "jz 3f\n\t"
+	    "rep ; movsl\n\t"
+	    "3:\n\t"
+	    "testb $1,%%dl\n\t"
+	    "je 1f\n\t"
+	    "movsb\n"
+	    "1:\ttestb $2,%%dl\n\t"
+	    "je 2f\n\t"
+	    "movsw\n"
+	    "2:\n"
+  :         "=d"(dummy1), "=D"(dummy2), "=S"(dummy3)   /* fake output */ 
+  :	    "0"(n), "1"((long) to), "2"((long) from)
+  :	    "cx"/***rjr***, "dx", "di", "si"***/
+  );
+    return (to);
+}
+
+
+static inline void *
+ __memcpyb(void *to, const void *from, size_t n)
+{
+  int dummy1;
+  long dummy2, dummy3;
+    __asm__ __volatile__("cld\n\t"
+	    "rep ; movsb\n\t"
+  :         "=c"(dummy1), "=D"(dummy2), "=S"(dummy3) /* fake output */
+  :	    "0"(n), "1"((long) to), "2"((long) from)
+			 /***rjr***:	    "cx", "di", "si"***/
+  );
+    return (to);
+}
+
+static inline void *
+ __memsetb(void *s, char c, size_t count)
+{
+    __asm__("cld\n\t"
+	    "rep\n\t"
+	    "stosb"
+  : :	    "a"(c), "D"(s), "c"(count)
+  :	    "cx", "di");
+    return s;
+}
+
+static inline void *
+ __memsetlong(void *s, unsigned c, size_t count)
+{
+  long dummy1;
+  int dummy2;
+    __asm__ __volatile__("cld\n\t"
+	    "rep\n\t"
+	    "stosl"
+  :         "=D"(dummy1), "=c"(dummy2) /* fake outputs */
+  :	    "a"(c), "0"(s), "1"(count)
+			 /***rjr***:	    "cx", "di"***/
+  );
+    return s;
+}
+
+static inline void *
+ __memset(void *s, char c, size_t count)
+{
+  int dummy1;
+  long dummy2;
+  int dummy3;
+    __asm__ __volatile__(
+	       "cld\n\t"
+	       "cmpl $12,%%edx\n\t"
+	       "jl 1f\n\t"	/* if (count >= 12) */
+
+	       "movzbl %%al,%%ax\n\t"
+	       "movl %%eax,%%ecx\n\t"
+	       "shll $8,%%ecx\n\t"	/* c |= c << 8 */
+	       "orl %%ecx,%%eax\n\t"
+	       "movl %%eax,%%ecx\n\t"
+	       "shll $16,%%ecx\n\t"	/* c |= c << 16 */
+	       "orl %%ecx,%%eax\n\t"
+
+	       "movl %%edx,%%ecx\n\t"
+	       "negl %%ecx\n\t"
+	       "andl $3,%%ecx\n\t"	/* (-s % 4) */
+	       "subl %%ecx,%%edx\n\t"	/* count -= (-s % 4) */
+	       "rep ; stosb\n\t"	/* align to longword boundary */
+
+	       "movl %%edx,%%ecx\n\t"
+	       "shrl $2,%%ecx\n\t"
+	       "rep ; stosl\n\t"	/* fill longwords */
+
+	       "andl $3,%%edx\n"	/* fill last few bytes */
+	       "1:\tmovl %%edx,%%ecx\n\t"	/* <= 12 entry point */
+	       "rep ; stosb\n\t"
+  :            "=a"(dummy1), "=D"(dummy2), "=d"(dummy3) /* fake outputs */
+  :	       "0"(c), "1"(s), "2"(count)
+  :	       /***rjr***"ax",*/ "cx"/*, "dx", "di"*/
+  );
+    return s;
+}
+
+static inline void *
+ __memset2(void *s, short c, size_t count)
+/* count is in 16-bit pixels */
+/* s is assumed to be 16-bit aligned */
+{
+  int dummy1;
+  long dummy2;
+  int dummy3;
+    __asm__ __volatile__(
+	       "cld\n\t"
+	       "cmpl $12,%%edx\n\t"
+	       "jl 1f\n\t"	/* if (count >= 12) */
+
+	       "movzwl %%ax,%%eax\n\t"
+	       "movl %%eax,%%ecx\n\t"
+	       "shll $16,%%ecx\n\t"	/* c |= c << 16 */
+	       "orl %%ecx,%%eax\n\t"
+
+	       "movl %%edi,%%ecx\n\t"
+	       "andl $2,%%ecx\n\t"	/* s & 2 */
+	       "jz 2f\n\t"
+	       "decl %%edx\n\t"	/* count -= 1 */
+	       "movw %%ax,(%%edi)\n\t"	/* align to longword boundary */
+	       "addl $2,%%edi\n\t"
+
+	       "2:\n\t"
+	       "movl %%edx,%%ecx\n\t"
+	       "shrl $1,%%ecx\n\t"
+	       "rep ; stosl\n\t"	/* fill longwords */
+
+	       "andl $1,%%edx\n"	/* one 16-bit word left? */
+	       "jz 3f\n\t"	/* no, finished */
+	       "1:\tmovl %%edx,%%ecx\n\t"	/* <= 12 entry point */
+	       "rep ; stosw\n\t"
+	       "3:\n\t"
+  :            "=a"(dummy1), "=D"(dummy2), "=d"(dummy3) /* fake outputs */
+  :	       "0"(c), "1"(s), "2"(count)
+  :	       /***rjr***"ax",*/ "cx"/*, "dx", "di"*/
+  );
+    return s;
+}
+
+static inline void *
+ __memset3(void *s, int c, size_t count)
+/* count is in 24-bit pixels (3 bytes per pixel) */
+{
+  int dummy1;
+  long dummy2;
+  int dummy3;
+    __asm__ __volatile__(
+	       "cmpl $8,%%edx\n\t"
+    /*      "jmp 2f\n\t" *//* debug */
+	       "jl 2f\n\t"
+
+	       "movl %%eax,%%esi\n\t"	/* esi = (low) BGR0 (high) */
+	       "shll $24,%%eax\n\t"	/* eax = 000B */
+	       "orl %%eax,%%esi\n\t"	/* esi = BGRB */
+
+	       "movl %%esi,%%eax\n\t"
+	       "shrl $8,%%eax\n\t"	/* eax = GRB0 */
+	       "movl %%eax,%%ecx\n\t"
+	       "shll $24,%%ecx\n\t"	/* ecx = 000G */
+	       "orl %%ecx,%%eax\n\t"	/* eax = GRBG */
+
+	       "movl %%esi,%%ecx\n\t"
+	       "shll $8,%%ecx\n\t"	/* ecx = 0BGR */
+	       "movb %%ah,%%cl\n\t"	/* ecx = RBGR */
+
+	       "cmpl $16,%%edx\n\t"
+	       "jl 1f\n\t"
+	       "jmp 5f\n\t"
+	       ".align 4,0x90\n\t"
+
+	       "5:\n\t"		/* loop unrolling */
+	       "movl %%esi,(%%edi)\n\t"		/* write BGRB */
+	       "movl %%eax,4(%%edi)\n\t"	/* write GRBG */
+	       "movl %%ecx,8(%%edi)\n\t"	/* write RBGR */
+	       "movl %%esi,12(%%edi)\n\t"
+	       "movl %%eax,16(%%edi)\n\t"
+	       "movl %%ecx,20(%%edi)\n\t"
+	       "movl %%esi,24(%%edi)\n\t"
+	       "movl %%eax,28(%%edi)\n\t"
+	       "movl %%ecx,32(%%edi)\n\t"
+	       "movl %%esi,36(%%edi)\n\t"
+	       "subl $16,%%edx\n\t"	/* blend end-of-loop instr. */
+	       "movl %%eax,40(%%edi)\n\t"
+	       "movl %%ecx,44(%%edi)\n\t"
+	       "addl $48,%%edi\n\t"
+	       "cmpl $16,%%edx\n\t"
+	       "jge 5b\n\t"
+	       "andl %%edx,%%edx\n\t"
+	       "jz 4f\n\t"	/* finished */
+	       "cmpl $4,%%edx\n\t"
+	       "jl 2f\n\t"	/* less than 4 pixels left */
+	       "jmp 1f\n\t"
+	       ".align 4,0x90\n\t"
+
+	       "1:\n\t"
+	       "movl %%esi,(%%edi)\n\t"		/* write BGRB */
+	       "movl %%eax,4(%%edi)\n\t"	/* write GRBG */
+	       "movl %%ecx,8(%%edi)\n\t"	/* write RBGR */
+	       "addl $12,%%edi\n\t"
+	       "subl $4,%%edx\n\t"
+	       "cmpl $4,%%edx\n\t"
+	       "jge 1b\n\t"
+
+	       "2:\n\t"
+	       "cmpl $0,%%edx\n\t"	/* none left? */
+	       "jle 4f\n\t"	/* finished */
+
+	       "mov %%ecx,%%eax\n\t"
+	       "shrl $8,%%ecx\n\t"	/* R in cl */
+
+	       "3:\n\t"		/* write last few pixels */
+	       "movw %%cx,(%%edi)\n\t"	/* write BG */
+	       "movb %%al,2(%%edi)\n\t"		/* write R */
+	       "addl $3,%%edi\n\t"
+	       "decl %%edx\n\t"
+	       "jnz 3b\n\t"
+
+	       "4:\n\t"
+  :            "=a"(dummy1), "=D"(dummy2), "=d"(dummy3) /* fake outputs */
+  :	       "0"(c), "1"(s), "2"(count)
+  :	       /***rjr***"ax",*/ "cx", /*"dx",*/ "si"/*, "di"*/
+  );
+    return s;
+}
+
+/* Functions defined in mem.S */
+
+extern void __svgalib_memcpy4to3(void *dest, void *src, int n);
+extern void __svgalib_memcpy32shift8(void *dest, void *src, int n);
+
+/* Functions for which arguments must be passed in %ebx, %edx, and %ecx. */
+#if 0				/* Why declare 'em? Just confuses the compiler and can't be called from C
+				   anyway */
+extern __memcpyasm_regargs();	/* nu_bytes >= 3 */
+extern __memcpyasm_regargs_aligned();	/* nu_bytes >= 32 */
+#endif
+
+
+/* Always 32-bit align destination, even for a small number of bytes. */
+static inline void *
+ __memcpy_aligndest(void *dest, const void *src, int n)
+{
+    __asm__ __volatile__("cmpl $3, %%ecx\n\t"
+			 "ja 1f\n\t"
+			 "call * __memcpy_jumptable (, %%ecx, 4)\n\t"
+			 "jmp 2f\n\t"
+			 "1:call __memcpyasm_regargs\n\t"
+			 "2:":
+			 :"S"(dest), "d"(src), "c"(n)
+			 :"ax", "0", "1", "2");
+    return dest;
+}
+
+
+/* Optimized version for 32-bit aligned destination. */
+static inline void *
+ __memcpy_destaligned(void *dest, const void *src, int n)
+{
+    __asm__ __volatile__("cmpl $32, %%ecx\n\t"
+			 "ja 1f\n\t"
+			 "call * __memcpy_jumptable (, %%ecx, 4)\n\t"
+			 "jmp 2f\n\t"
+			 "1:call __memcpyasm_regargs_aligned\n\t"
+			 "2:\n\t":
+			 :"S"(dest), "d"(src), "c"(n)
+			 :"ax", "0", "1", "2");
+    return dest;
+}
+
+
+/* Balanced inline memcpy; 32-bit align destination if nu_bytes >= 20. */
+static inline void *
+ __memcpy_balanced(void *dest, const void *src, int n)
+{
+    __asm__ __volatile__("cmpl $19, %%ecx\n\t"
+			 "ja 1f\n\t"
+			 "call * __memcpy_jumptable (, %%ecx, 4)\n\t"
+			 "jmp 2f\n\t"
+			 "1:call __memcpyasm_regargs\n\t"
+			 "2:\n\t"
+			 :
+			 :"S"((long) dest), "d"((long) src), "c"((long) n)
+			 :"ax", "0", "1", "2");
+    return dest;
+}
+
+
+#define __memcpy __memcpy_conventional
+
+#endif				/* !__alpha__ */
diff --git a/haiku/vgagl/line.c b/haiku/vgagl/line.c
new file mode 100644
index 0000000..6691471
--- /dev/null
+++ b/haiku/vgagl/line.c
@@ -0,0 +1,633 @@
+/* Framebuffer Graphics Libary for Linux, Copyright 1993 Harm Hanemaayer */
+/* line.c       Line drawing */
+
+
+#include <stdlib.h>
+
+#ifndef DO_NOT_USE_VGALIB
+#include <vga.h>
+#endif
+
+#include "inlstring.h"		/* include inline string operations */
+
+#include "vgagl.h"
+#include "def.h"
+#include "driver.h"
+
+
+#ifdef __alpha__
+
+static inline int muldiv64(int m1, int m2, int d)
+{
+    return (long) m1 *(long) m2 / (long) d;
+}
+
+#else
+
+#ifdef NO_ASSEMBLY
+
+static inline int muldiv64(int m1, int m2, int d)
+{
+    return (float) m1 * (float) m2 / ((float) d);
+}
+
+#else
+
+/* We use the 32-bit to 64-bit multiply and 64-bit to 32-bit divide of the */
+/* 386 (which gcc doesn't know well enough) to efficiently perform integer */
+/* scaling without having to worry about overflows. */
+
+static inline int muldiv64(int m1, int m2, int d)
+{
+/* int32 * int32 -> int64 / int32 -> int32 */
+    int result;
+    int dummy;
+    __asm__(
+	       "imull %%edx\n\t"
+	       "idivl %4\n\t"
+  :	       "=a"(result), "=d"(dummy)	/* out */
+  :	       "0"(m1), "1"(m2), "g"(d)		/* in */
+	       /***rjr***:	       "ax", "dx" ***/	/* mod */
+	);
+    return result;
+}
+
+#endif				/* !NO_ASSEMBLY */
+#endif				/* !__alpha__ */
+
+#ifdef __alpha__
+
+static inline int gl_regioncode(int x, int y)
+{
+    int result = 0;
+    if (x < __clipx1)
+	result |= 1;
+    else if (x > __clipx2)
+	result |= 2;
+    if (y < __clipy1)
+	result |= 4;
+    else if (y > __clipy2)
+	result |= 8;
+    return result;
+}
+
+#else
+#ifdef NO_ASSEMBLY
+
+static inline int gl_regioncode (int x, int y)
+{
+    int result = 0;
+    if (x < __clipx1)
+	result |= 1;
+    else if (x > __clipx2)
+	result |= 2;
+    if (y < __clipy1)
+	result |= 4;
+    else if (y > __clipy2)
+	result |= 8;
+    return result;
+}
+
+#else
+
+#define INC_IF_NEG(y, result)				\
+{							\
+	__asm__("btl $31,%1\n\t"			\
+		"adcl $0,%0"				\
+		: "=r" ((int) result)			\
+		: "rm" ((int) (y)), "0" ((int) result)	\
+		);					\
+}
+
+static inline int gl_regioncode (int x, int y)
+{
+    int dx1, dx2, dy1, dy2;
+    int result;
+    result = 0;
+    dy2 = __clipy2 - y;
+    INC_IF_NEG (dy2, result);
+    result <<= 1;
+    dy1 = y - __clipy1;
+    INC_IF_NEG (dy1, result);
+    result <<= 1;
+    dx2 = __clipx2 - x;
+    INC_IF_NEG (dx2, result);
+    result <<= 1;
+    dx1 = x - __clipx1;
+    INC_IF_NEG (dx1, result);
+    return result;
+}
+
+#endif				/* ! NO_ASSEMBLY */
+#endif				/* !__alpha__ */
+
+
+#define line_start_paged(s) \
+	    fp = y * bytesperrow + x * s;	\
+	    vga_setpage (fpp = (fp >> 16));	\
+	    fp &= 0xFFFF;
+
+#define line_start_linear(s) \
+	    vp = VBUF + y * bytesperrow + x * s;
+
+
+#define line_loop_paged_a(m,i,u,v)	\
+	    {    \
+	    int d = ay - (ax >> 1);	\
+	    if ((x = abs (dx)))	\
+		do {	\
+		    i;	\
+		    if (d m 0) {	\
+			fp v;	\
+			d -= ax;	\
+		    }	\
+		    fp u;	\
+		    d += ay;	\
+		    if (fp & 0xFFFF0000) {	/* has it cross a page boundary ? */	\
+			fpp += fp >> 16;	\
+			vga_setpage (fpp);	\
+		    }	\
+		    fp &= 0x0000FFFF;	\
+		} while (--x);    \
+	    }
+
+#define line_loop_linear_a(m,i,u,v)	\
+	    {    \
+	    int d = ay - (ax >> 1);	\
+	    if ((x = abs (dx)))	\
+		do {	\
+		    i;	\
+		    if (d m 0) {	\
+			vp v;	\
+			d -= ax;	\
+		    }	\
+		    vp u;	\
+		    d += ay;	\
+		} while (--x);    \
+	    }
+
+
+#define line_loop_paged_b(m,i,u,v)	\
+		{    \
+		int d = ax - (ay >> 1);	\
+		if ((y = abs (dy)))	\
+		    do {	\
+			i;	\
+			if (d m 0) {	\
+			    fp u;	\
+			    d -= ay;	\
+			}	\
+			fp v;	\
+			d += ax;	\
+			if (fp & 0xFFFF0000) {	\
+			    fpp += fp >> 16;	\
+			    vga_setpage (fpp);	\
+			}	\
+			fp &= 0x0000FFFF;	\
+		    } while (--y);    \
+		}
+
+
+#define line_loop_linear_b(m,i,u,v)	\
+		{    \
+		int d = ax - (ay >> 1);	\
+		if ((y = abs (dy)))	\
+		    do {	\
+			i;	\
+			if (d m 0) {	\
+			    vp u;	\
+			    d -= ay;	\
+			}	\
+			vp v;	\
+			d += ax;	\
+		    } while (--y);    \
+		}
+
+
+
+/* Partly based on the work which was partly based on vgalib by Tommy Frandsen */
+/* This is a lot faster now that setpixel is inlined */
+
+void gl_line (int x1, int y1, int x2, int y2, int c)
+{
+    int dx, dy, ax, ay, sx, sy, x, y;
+    int bytesperrow;
+    unsigned char *vp = NULL;
+
+    if (__clip)
+	/* Cohen & Sutherland algorithm */
+	for (;;) {
+	    int r1 = gl_regioncode (x1, y1);
+	    int r2 = gl_regioncode (x2, y2);
+	    if (!(r1 | r2))
+		break;		/* completely inside */
+	    if (r1 & r2)
+		return;		/* completely outside */
+	    if (r1 == 0) {
+		swap (x1, x2);	/* make sure first */
+		swap (y1, y2);	/* point is outside */
+		r1 = r2;
+	    }
+	    if (r1 & 1) {	/* left */
+		y1 += muldiv64 (__clipx1 - x1, y2 - y1, x2 - x1);
+		x1 = __clipx1;
+	    } else if (r1 & 2) {	/* right */
+		y1 += muldiv64 (__clipx2 - x1, y2 - y1, x2 - x1);
+		x1 = __clipx2;
+	    } else if (r1 & 4) {	/* top */
+		x1 += muldiv64 (__clipy1 - y1, x2 - x1, y2 - y1);
+		y1 = __clipy1;
+	    } else if (r1 & 8) {	/* bottom */
+		x1 += muldiv64 (__clipy2 - y1, x2 - x1, y2 - y1);
+		y1 = __clipy2;
+	    }
+	}
+    dx = x2 - x1;
+    dy = y2 - y1;
+    ax = abs (dx) << 1;
+    ay = abs (dy) << 1;
+    sx = (dx >= 0) ? 1 : -1;
+    sy = (dy >= 0) ? 1 : -1;
+    x = x1;
+    y = y1;
+
+#ifdef __alpha__
+    if (ax > ay) {
+	int d = ay - (ax >> 1);
+	while (x != x2) {
+	    setpixel (x, y, c);
+
+	    if (d > 0 || (d == 0 && sx == 1)) {
+		y += sy;
+		d -= ax;
+	    }
+	    x += sx;
+	    d += ay;
+	}
+    } else {
+	int d = ax - (ay >> 1);
+	while (y != y2) {
+	    setpixel (x, y, c);
+
+	    if (d > 0 || (d == 0 && sy == 1)) {
+		x += sx;
+		d -= ay;
+	    }
+	    y += sy;
+	    d += ax;
+	}
+    }
+
+    setpixel (x, y, c);
+
+#else
+
+#define insert_pixel_1 *((unsigned char *) vp) = c;
+#define insert_pixel_2 *((unsigned short *) vp) = c;
+
+#define insert_pixel_3 *((unsigned char *) vp) = c;    \
+		    *((unsigned char *) (vp + 1)) = (c>>8);    \
+		    *((unsigned char *) (vp + 2)) = (c>>16);
+
+#define insert_pixel_4 *((unsigned long *) vp) = c;
+
+    bytesperrow = BYTEWIDTH;
+
+    if (MODETYPE == CONTEXT_VIRTUAL || MODETYPE == CONTEXT_LINEAR) {
+	switch BYTESPERPIXEL {
+	case 1:
+	    line_start_linear(1);
+	    if (ax > ay) {
+		if(sx > 0) {
+		    line_loop_linear_a(>=,insert_pixel_1,++,+=bytesperrow*sy);
+		} else {
+		    line_loop_linear_a(>,insert_pixel_1,--,+=bytesperrow*sy);
+		}
+	    } else {
+		if(sy > 0) {
+		    line_loop_linear_b(>=,insert_pixel_1,+=sx,+=bytesperrow);
+		} else {
+		    line_loop_linear_b(>,insert_pixel_1,+=sx,-=bytesperrow);
+		}
+	    }
+	    insert_pixel_1;
+	    break;
+	case 2:
+	    line_start_linear(2);
+	    if (ax > ay) {
+		if(sx > 0) {
+		    line_loop_linear_a(>=,insert_pixel_2,+=2,+=bytesperrow*sy);
+		} else {
+		    line_loop_linear_a(>,insert_pixel_2,-=2,+=bytesperrow*sy);
+		}
+	    } else {
+		sx <<= 1;
+		if(sy > 0) {
+		    line_loop_linear_b(>=,insert_pixel_2,+=sx,+=bytesperrow);
+		} else {
+		    line_loop_linear_b(>,insert_pixel_2,+=sx,-=bytesperrow);
+		}
+	    }
+	    insert_pixel_2;
+	    break;
+	case 3:
+	    line_start_linear(3);
+	    if (ax > ay) {
+		if(sx > 0) {
+		    line_loop_linear_a(>=,insert_pixel_3,+=3,+=bytesperrow*sy);
+		} else {
+		    line_loop_linear_a(>,insert_pixel_3,-=3,+=bytesperrow*sy);
+		}
+	    } else {
+		sx *= 3;
+		if(sy > 0) {
+		    line_loop_linear_b(>=,insert_pixel_3,+=sx,+=bytesperrow);
+		} else {
+		    line_loop_linear_b(>,insert_pixel_3,+=sx,-=bytesperrow);
+		}
+	    }
+	    insert_pixel_3;
+	    break;
+	case 4:
+	    line_start_linear(4);
+	    if (ax > ay) {
+		if(sx > 0) {
+		    line_loop_linear_a(>=,insert_pixel_4,+=4,+=bytesperrow*sy);
+		} else {
+		    line_loop_linear_a(>,insert_pixel_4,-=4,+=bytesperrow*sy);
+		}
+	    } else {
+		sx <<= 2;
+		if(sy > 0) {
+		    line_loop_linear_b(>=,insert_pixel_4,+=sx,+=bytesperrow);
+		} else {
+		    line_loop_linear_b(>,insert_pixel_4,+=sx,-=bytesperrow);
+		}
+	    }
+	    insert_pixel_4;
+	    break;
+	}
+    }
+
+
+
+
+#ifndef DO_NOT_USE_VGALIB
+
+#undef insert_pixel_1
+#undef insert_pixel_2
+#undef insert_pixel_3
+#undef insert_pixel_4
+
+#define insert_pixel_1 *((unsigned char *) (vp + fp)) = c;
+#define insert_pixel_2 *((unsigned short *) (vp + fp)) = c;
+
+#define insert_pixel_3 *((unsigned char *) (vp + fp)) = c;    \
+		    *((unsigned char *) (vp + fp + 1)) = (c>>8);    \
+		    *((unsigned char *) (vp + fp + 2)) = (c>>16);
+
+#define insert_pixel_4 *((unsigned long *) (vp + fp)) = c;
+
+
+    if (MODETYPE == CONTEXT_PAGED) {
+	vp = VBUF;
+	switch BYTESPERPIXEL {
+	int fpp;
+	int fp;
+	case 1:
+	    line_start_paged(1);
+	    if (ax > ay) {
+		if(sx > 0) {
+		    line_loop_paged_a(>=,insert_pixel_1,++,+=bytesperrow*sy);
+		} else {
+		    line_loop_paged_a(>,insert_pixel_1,--,+=bytesperrow*sy);
+		}
+	    } else {
+		if(sy > 0) {
+		    line_loop_paged_b(>=,insert_pixel_1,+=sx,+=bytesperrow);
+		} else {
+		    line_loop_paged_b(>,insert_pixel_1,+=sx,-=bytesperrow);
+		}
+	    }
+	    insert_pixel_1;
+	    break;
+	case 2:
+	    line_start_paged(2);
+	    if (ax > ay) {
+		if(sx > 0) {
+		    line_loop_paged_a(>=,insert_pixel_2,+=2,+=bytesperrow*sy);
+		} else {
+		    line_loop_paged_a(>,insert_pixel_2,-=2,+=bytesperrow*sy);
+		}
+	    } else {
+		sx <<= 1;
+		if(sy > 0) {
+		    line_loop_paged_b(>=,insert_pixel_2,+=sx,+=bytesperrow);
+		} else {
+		    line_loop_paged_b(>,insert_pixel_2,+=sx,-=bytesperrow);
+		}
+	    }
+	    insert_pixel_2;
+	    break;
+	case 3:
+	    line_start_paged(3);
+	    if (ax > ay) {
+		if(sx > 0) {
+		    line_loop_paged_a(>=,insert_pixel_3,+=3,+=bytesperrow*sy);
+		} else {
+		    line_loop_paged_a(>,insert_pixel_3,-=3,+=bytesperrow*sy);
+		}
+	    } else {
+		sx *= 3;
+		if(sy > 0) {
+		    line_loop_paged_b(>=,insert_pixel_3,+=sx,+=bytesperrow);
+		} else {
+		    line_loop_paged_b(>,insert_pixel_3,+=sx,-=bytesperrow);
+		}
+	    }
+	    insert_pixel_3;
+	    break;
+	case 4:
+	    line_start_paged(4);
+	    if (ax > ay) {
+		if(sx > 0) {
+		    line_loop_paged_a(>=,insert_pixel_4,+=4,+=bytesperrow*sy);
+		} else {
+		    line_loop_paged_a(>,insert_pixel_4,-=4,+=bytesperrow*sy);
+		}
+	    } else {
+		sx <<= 2;
+		if(sy > 0) {
+		    line_loop_paged_b(>=,insert_pixel_4,+=sx,+=bytesperrow);
+		} else {
+		    line_loop_paged_b(>,insert_pixel_4,+=sx,-=bytesperrow);
+		}
+	    }
+	    insert_pixel_4;
+	    break;
+	}
+    }
+
+#endif
+
+    if (!vp) {
+
+	if (ax > ay) {
+	    int d = ay - (ax >> 1);
+	    while (x != x2) {
+		setpixel (x, y, c);
+
+		if (d > 0 || (d == 0 && sx == 1)) {
+		    y += sy;
+		    d -= ax;
+		}
+		x += sx;
+		d += ay;
+	    }
+	} else {
+	    int d = ax - (ay >> 1);
+	    while (y != y2) {
+		setpixel (x, y, c);
+
+		if (d > 0 || (d == 0 && sy == 1)) {
+		    x += sx;
+		    d -= ay;
+		}
+		y += sy;
+		d += ax;
+	    }
+	}
+	setpixel (x, y, c);
+    }
+#endif
+}
+
+
+static void gl_setcirclepixels(int x, int y, int sx, int sy, int c)
+{
+    if (__clip) {
+	int z = max(x, y);
+	if (sx - z < __clipx1 || sx + z > __clipx2
+	    || sy - z < __clipy1 || sy + z > __clipy2) {
+	    /* use setpixel clipping */
+	    gl_setpixel(sx + x, sy + y, c);
+	    gl_setpixel(sx - x, sy + y, c);
+	    gl_setpixel(sx + x, sy - y, c);
+	    gl_setpixel(sx - x, sy - y, c);
+	    gl_setpixel(sx + y, sy + x, c);
+	    gl_setpixel(sx - y, sy + x, c);
+	    gl_setpixel(sx + y, sy - x, c);
+	    gl_setpixel(sx - y, sy - x, c);
+	    return;
+	}
+    }
+    setpixel(sx + x, sy + y, c);
+    setpixel(sx - x, sy + y, c);
+    setpixel(sx + x, sy - y, c);
+    setpixel(sx - x, sy - y, c);
+    setpixel(sx + y, sy + x, c);
+    setpixel(sx - y, sy + x, c);
+    setpixel(sx + y, sy - x, c);
+    setpixel(sx - y, sy - x, c);
+}
+
+void gl_circle(int sx, int sy, int r, int c)
+{
+    int x, y, d;
+    if (r < 1) {
+	gl_setpixel(sx, sy, c);
+	return;
+    }
+    if (__clip)
+	if (sx + r < __clipx1 || sx - r > __clipx2
+	    || sy + r < __clipy1 || sy - r > __clipy2)
+	    return;
+    x = 0;
+    y = r;
+    d = 1 - r;
+    gl_setcirclepixels(x, y, sx, sy, c);
+    while (x < y) {
+	if (d < 0)
+	    d += x * 2 + 3;
+	else {
+	    d += x * 2 - y * 2 + 5;
+	    y--;
+	}
+	x++;
+	gl_setcirclepixels(x, y, sx, sy, c);
+    }
+}
+
+void gl_fillcircle(int sx, int sy, int r, int c)
+{
+    int x = 0,
+        y = r,
+        d = 1 - r;
+
+    if (r < 1) {
+	gl_setpixel(sx, sy, c);
+	return;
+    }
+    if (__clip)
+	if (sx + r < __clipx1 || sx - r > __clipx2
+	    || sy + r < __clipy1 || sy - r > __clipy2)
+	    return;
+     gl_hline(sx - x, sy + y, sx + x, c);
+     gl_hline(sx - x, sy - y, sx + x, c);
+     gl_hline(sx - y, sy + x, sx + y, c);
+     gl_hline(sx - y, sy - x, sx + y, c);
+     while (x < y)
+     {
+        if (d < 0)
+        {
+            d += x * 2 + 3;
+        } else {
+            d += x * 2 - y * 2 + 5;
+            y--;
+        }
+        x++;
+        gl_hline(sx - x, sy + y, sx + x, c);
+        gl_hline(sx - x, sy - y, sx + x, c);
+        gl_hline(sx - y, sy + x, sx + y, c);
+        gl_hline(sx - y, sy - x, sx + y, c);
+     }
+}
+
+void gl_bcircle(int sx, int sy, int r, int c, int fill)
+{
+    int x = 0,
+        y = r,
+        d = 2 * (1 - r);
+
+    if (r < 1) {
+	gl_setpixel(sx, sy, c);
+	return;
+    }
+    if (__clip)
+	if (sx + r < __clipx1 || sx - r > __clipx2
+	    || sy + r < __clipy1 || sy - r > __clipy2)
+	    return;
+    while (y >= 0)
+    {
+        if (fill == 0)
+        {
+            gl_setpixel(sx + x, sy + y, c);
+            gl_setpixel(sx + x, sy - y, c);
+            gl_setpixel(sx - x, sy + y, c);
+            gl_setpixel(sx - x, sy - y, c);
+        } else {
+            gl_hline(sx - x, sy + y, sx + x, c);
+            gl_hline(sx - x, sy - y, sx + x, c);
+        }
+        if ((d + y) > 0)
+        {
+            y--;
+            d -= (2 * y * WIDTH / HEIGHT) - 1;
+        }
+        if (x > d)
+        {
+            x++;
+            d += (2 * x) + 1;
+        }
+    }
+}
diff --git a/haiku/vgagl/mem.c b/haiku/vgagl/mem.c
new file mode 100644
index 0000000..79bec46
--- /dev/null
+++ b/haiku/vgagl/mem.c
@@ -0,0 +1,23 @@
+#include <stdio.h>
+
+ /*
+  * Copies pixels from 4-byte-per-pixel screen to 3-byte-per-pixel screen,
+  * 
+  * discarding the last byte of each pixel.  Only uses 32-bit aligned word
+  * accesses.  Instructions have been shuffled a bit for possible
+  * avoidance of pipeline hazards.
+  */
+void __svgalib_memcpy4to3(void *dest, void *src, int n)
+{
+    printf("libgl: __svgalib_memcpy4to3 not done yet\n");
+}
+
+/* 
+ * Copies pixels from 4-byte-per-pixel screen organized as BGR0 to
+ * 0BGR 4-byte-per-pixel screen.
+ * Used by copyscreen for ATI mach32 32-bit truecolor modes.
+ */
+void __svgalib_memcpy32shift8(void *dest, void *src, int n)
+{
+    printf("libgl: __svgalib_memcpy32shift8 not done yet\n");
+}
diff --git a/haiku/vgagl/palette.c b/haiku/vgagl/palette.c
new file mode 100644
index 0000000..b20bb18
--- /dev/null
+++ b/haiku/vgagl/palette.c
@@ -0,0 +1,71 @@
+/* Framebuffer Graphics Libary for Linux, Copyright 1993 Harm Hanemaayer */
+/* palette.c    Palette functions (wrapper over vgalib) */
+
+
+#include <stdlib.h>
+#include <vga.h>
+
+#include "vgagl.h"
+#include "def.h"
+
+
+/* 256-color palette functions */
+
+/* There was a horrible bug here in 0.8x -- green and blue were swapped... */
+void gl_getpalettecolor(int c, int *r, int *g, int *b)
+{
+    vga_getpalette(c, r, g, b);
+}
+
+void gl_setpalettecolor(int c, int r, int g, int b)
+{
+    vga_setpalette(c, r, g, b);
+}
+
+void gl_setpalettecolors(int s, int n, void *_dp)
+{
+    uchar *dp = _dp;
+    int i;
+    for (i = s; i < s + n; i++) {
+	unsigned char r, g, b;
+	r = *(dp++);
+	g = *(dp++);
+	b = *(dp++);
+	vga_setpalette(i, r, g, b);
+    }
+}
+
+void gl_getpalettecolors(int s, int n, void *_dp)
+{
+    uchar *dp = _dp;
+    int i;
+    for (i = s; i < s + n; i++) {
+	int r, g, b;
+	vga_getpalette(i, &r, &g, &b);
+	*(dp++) = (unsigned char) r;
+	*(dp++) = (unsigned char) g;
+	*(dp++) = (unsigned char) b;
+    }
+}
+
+void gl_getpalette(void *p)
+{
+    gl_getpalettecolors(0, 256, p);
+}
+
+void gl_setpalette(void *p)
+{
+    gl_setpalettecolors(0, 256, p);
+}
+
+void gl_setrgbpalette()
+{
+    int i;
+    Palette pal;
+    for (i = 0; i < 256; i++) {
+	pal.color[i].blue = (i & 7) * (64 / 8);		/* 3 bits */
+	pal.color[i].green = ((i & 56) >> 3) * (64 / 8);	/* 3 bits */
+	pal.color[i].red = ((i & 192) >> 6) * (64 / 4);		/* 2 bits */
+    }
+    gl_setpalette(&pal);
+}
diff --git a/haiku/vgagl/scale.c b/haiku/vgagl/scale.c
new file mode 100644
index 0000000..1f9d8f8
--- /dev/null
+++ b/haiku/vgagl/scale.c
@@ -0,0 +1,278 @@
+/* Framebuffer Graphics Libary for Linux, Copyright 1993 Harm Hanemaayer */
+/* scale.c      Scaling routine */
+
+
+#include <stdlib.h>
+#include <vga.h>
+#include "inlstring.h"		/* include inline string operations */
+
+#include "vgagl.h"
+#include "def.h"
+
+
+/* #define USE_ASM */
+
+
+#ifdef __alpha__
+
+static inline int muldiv64(int m1, int m2, int d)
+{
+    return (long) m1 *(long) m2 / (long) d;
+}
+
+#else
+
+/* We use the 32-bit to 64-bit multiply and 64-bit to 32-bit divide of the */
+/* 386 (which gcc doesn't know well enough) to efficiently perform integer */
+/* scaling without having to worry about overflows. */
+
+static inline int muldiv64(int m1, int m2, int d)
+{
+/* int32 * int32 -> int64 / int32 -> int32 */
+    int result;
+    int dummy;
+    __asm__(
+	       "imull %%edx\n\t"
+	       "idivl %4\n\t"
+  :	       "=a"(result), "=d"(dummy)	/* out */
+  :	       "0"(m1), "1"(m2), "g"(d)		/* in */
+	       /***rjr***:	       "ax", "dx"***/	/* mod */
+	);
+    return result;
+}
+
+#endif				/* !__alpha__ */
+
+/* This is a DDA-based algorithm. */
+/* Iteration over target bitmap. */
+
+void gl_scalebox(int w1, int h1, void *_dp1, int w2, int h2, void *_dp2)
+{
+    uchar *dp1 = _dp1;
+    uchar *dp2 = _dp2;
+    int xfactor;
+    int yfactor;
+
+    if (w2 == 0 || h2 == 0)
+	return;
+
+    xfactor = muldiv64(w1, 65536, w2);	/* scaled by 65536 */
+    yfactor = muldiv64(h1, 65536, h2);	/* scaled by 65536 */
+
+    switch (BYTESPERPIXEL) {
+    case 1:
+	{
+	    int y, sy;
+	    sy = 0;
+	    for (y = 0; y < h2;) {
+		int sx = 0;
+		uchar *dp2old = dp2;
+		int x;
+		x = 0;
+		while (x < w2 - 8) {
+#ifdef USE_ASM
+
+		    /* This saves just a couple of cycles per */
+		    /* pixel on a 486, but I couldn't resist. */
+		    __asm__ __volatile__("movl %4, %%eax\n\t"
+					 "shrl $16, %%eax\n\t"
+					 "addl %5, %4\n\t"
+					 "movb (%3, %%eax), %%al\n\t"
+					 "movb %%al, (%1, %2)\n\t"
+					 "movl %4, %%eax\n\t"
+					 "shrl $16, %%eax\n\t"
+					 "addl %5, %4\n\t"
+					 "movb (%3, %%eax), %%al\n\t"
+					 "movb %%al, 1 (%1, %2)\n\t"
+					 "movl %4, %%eax\n\t"
+					 "shrl $16, %%eax\n\t"
+					 "addl %5, %4\n\t"
+					 "movb (%3, %%eax), %%al\n\t"
+					 "movb %%al, 2 (%1, %2)\n\t"
+					 "movl %4, %%eax\n\t"
+					 "shrl $16, %%eax\n\t"
+					 "addl %5, %4\n\t"
+					 "movb (%3, %%eax), %%al\n\t"
+					 "movb %%al, 3 (%1, %2)\n\t"
+					 "movl %4, %%eax\n\t"
+					 "shrl $16, %%eax\n\t"
+					 "addl %5, %4\n\t"
+					 "movb (%3, %%eax), %%al\n\t"
+					 "movb %%al, 4 (%1, %2)\n\t"
+					 "movl %4, %%eax\n\t"
+					 "shrl $16, %%eax\n\t"
+					 "addl %5, %4\n\t"
+					 "movb (%3, %%eax), %%al\n\t"
+					 "movb %%al, 5 (%1, %2)\n\t"
+					 "movl %4, %%eax\n\t"
+					 "shrl $16, %%eax\n\t"
+					 "addl %5, %4\n\t"
+					 "movb (%3, %%eax), %%al\n\t"
+					 "movb %%al, 6 (%1, %2)\n\t"
+					 "movl %4, %%eax\n\t"
+					 "shrl $16, %%eax\n\t"
+					 "addl %5, %4\n\t"
+					 "movb (%3, %%eax), %%al\n\t"
+					 "movb %%al, 7 (%1, %2)\n\t"
+					 :	/* output */
+					 :	/* input */
+				     "ax"(0), "r"(dp2), "r"(x), "r"(dp1),
+					 "r"(sx), "r"(xfactor)
+					 :"ax", "4"
+		    );
+#else
+		    *(dp2 + x) = *(dp1 + (sx >> 16));
+		    sx += xfactor;
+		    *(dp2 + x + 1) = *(dp1 + (sx >> 16));
+		    sx += xfactor;
+		    *(dp2 + x + 2) = *(dp1 + (sx >> 16));
+		    sx += xfactor;
+		    *(dp2 + x + 3) = *(dp1 + (sx >> 16));
+		    sx += xfactor;
+		    *(dp2 + x + 4) = *(dp1 + (sx >> 16));
+		    sx += xfactor;
+		    *(dp2 + x + 5) = *(dp1 + (sx >> 16));
+		    sx += xfactor;
+		    *(dp2 + x + 6) = *(dp1 + (sx >> 16));
+		    sx += xfactor;
+		    *(dp2 + x + 7) = *(dp1 + (sx >> 16));
+		    sx += xfactor;
+#endif
+		    x += 8;
+		}
+		while (x < w2) {
+		    *(dp2 + x) = *(dp1 + (sx >> 16));
+		    sx += xfactor;
+		    x++;
+		}
+		dp2 += w2;
+		y++;
+		while (y < h2) {
+		    int l;
+		    int syint = sy >> 16;
+		    sy += yfactor;
+		    if ((sy >> 16) != syint)
+			break;
+		    /* Copy identical lines. */
+		    l = dp2 - dp2old;
+		    __memcpy(dp2, dp2old, l);
+		    dp2old = dp2;
+		    dp2 += l;
+		    y++;
+		}
+		dp1 = _dp1 + (sy >> 16) * w1;
+	    }
+	}
+	break;
+    case 2:
+	{
+	    int y, sy;
+	    sy = 0;
+	    for (y = 0; y < h2;) {
+		int sx = 0;
+		uchar *dp2old = dp2;
+		int x;
+		x = 0;
+		/* This can be greatly optimized with loop */
+		/* unrolling; omitted to save space. */
+		while (x < w2) {
+		    *(unsigned short *) (dp2 + x * 2) =
+			*(unsigned short *) (dp1 + (sx >> 16) * 2);
+		    sx += xfactor;
+		    x++;
+		}
+		dp2 += w2 * 2;
+		y++;
+		while (y < h2) {
+		    int l;
+		    int syint = sy >> 16;
+		    sy += yfactor;
+		    if ((sy >> 16) != syint)
+			break;
+		    /* Copy identical lines. */
+		    l = dp2 - dp2old;
+		    __memcpy(dp2, dp2old, l);
+		    dp2old = dp2;
+		    dp2 += l;
+		    y++;
+		}
+		dp1 = _dp1 + (sy >> 16) * w1 * 2;
+	    }
+	}
+	break;
+    case 3:
+	{
+	    int y, sy;
+	    sy = 0;
+	    for (y = 0; y < h2;) {
+		int sx = 0;
+		uchar *dp2old = dp2;
+		int x;
+		x = 0;
+		/* This can be greatly optimized with loop */
+		/* unrolling; omitted to save space. */
+		while (x < w2) {
+		    *(unsigned short *) (dp2 + x * 3) =
+			*(unsigned short *) (dp1 + (sx >> 16) * 3);
+		    *(unsigned char *) (dp2 + x * 3 + 2) =
+			*(unsigned char *) (dp1 + (sx >> 16) * 3 + 2);
+		    sx += xfactor;
+		    x++;
+		}
+		dp2 += w2 * 3;
+		y++;
+		while (y < h2) {
+		    int l;
+		    int syint = sy >> 16;
+		    sy += yfactor;
+		    if ((sy >> 16) != syint)
+			break;
+		    /* Copy identical lines. */
+		    l = dp2 - dp2old;
+		    __memcpy(dp2, dp2old, l);
+		    dp2old = dp2;
+		    dp2 += l;
+		    y++;
+		}
+		dp1 = _dp1 + (sy >> 16) * w1 * 3;
+	    }
+	}
+	break;
+    case 4:
+	{
+	    int y, sy;
+	    sy = 0;
+	    for (y = 0; y < h2;) {
+		int sx = 0;
+		uchar *dp2old = dp2;
+		int x;
+		x = 0;
+		/* This can be greatly optimized with loop */
+		/* unrolling; omitted to save space. */
+		while (x < w2) {
+		    *(unsigned *) (dp2 + x * 4) =
+			*(unsigned *) (dp1 + (sx >> 16) * 4);
+		    sx += xfactor;
+		    x++;
+		}
+		dp2 += w2 * 4;
+		y++;
+		while (y < h2) {
+		    int l;
+		    int syint = sy >> 16;
+		    sy += yfactor;
+		    if ((sy >> 16) != syint)
+			break;
+		    /* Copy identical lines. */
+		    l = dp2 - dp2old;
+		    __memcpy(dp2, dp2old, l);
+		    dp2old = dp2;
+		    dp2 += l;
+		    y++;
+		}
+		dp1 = _dp1 + (sy >> 16) * w1 * 4;
+	    }
+	}
+	break;
+    }
+}
diff --git a/haiku/vgagl/text.c b/haiku/vgagl/text.c
new file mode 100644
index 0000000..c10900d
--- /dev/null
+++ b/haiku/vgagl/text.c
@@ -0,0 +1,328 @@
+/* Framebuffer Graphics Libary for Linux, Copyright 1993 Harm Hanemaayer */
+/* text.c       Text writing and fonts */
+
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <vga.h>
+#include "inlstring.h"		/* include inline string operations */
+
+#include "vgagl.h"
+#include "def.h"
+
+
+
+/* Text/font functions */
+
+static int font_width = 8;
+static int font_height = 8;
+static char *font_address;
+static int font_charactersize = 64;
+static int font_writemode = WRITEMODE_OVERWRITE;
+static int compressed_font_bg = 0;
+static int compressed_font_fg = 15;
+
+static void writecompressed(int x, int y, int n, unsigned char *s);
+
+
+void gl_colorfont(int fw, int fh, int fg, void *_dp)
+{
+    uchar *dp = _dp;
+    int i;
+    i = fw * fh * 256;
+    switch (BYTESPERPIXEL) {
+    case 1:
+	while (i > 0) {
+	    if (*dp)
+		*dp = fg;
+	    dp++;
+	    i--;
+	}
+	break;
+    case 2:
+	while (i > 0) {
+	    if (*(ushort *) dp)
+		*(ushort *) dp = fg;
+	    dp += 2;
+	    i--;
+	}
+	break;
+    case 3:
+	while (i > 0) {
+	    if (*(ushort *) dp || *(dp + 2)) {
+		*(ushort *) dp = fg;
+		*(dp + 2) = fg >> 16;
+	    }
+	    dp += 3;
+	    i--;
+	}
+	break;
+    case 4:
+	while (i > 0) {
+	    if (*(int *) dp)
+		*(int *) dp = fg;
+	    dp += 4;
+	    i--;
+	}
+	break;
+
+    }
+}
+
+void gl_setfont(int fw, int fh, void *font)
+{
+    font_width = fw;
+    font_height = fh;
+    font_charactersize = font_width * font_height * BYTESPERPIXEL;
+    font_address = font;
+}
+
+void gl_setwritemode(int m)
+{
+    font_writemode = m;
+}
+
+void gl_writen(int x, int y, int n, char *s)
+{
+/* clipping in putbox */
+    int i;
+    if (font_writemode & FONT_COMPRESSED) {
+	writecompressed(x, y, n, s);
+	return;
+    }
+    if (!(font_writemode & WRITEMODE_MASKED)) {
+        for (i=0; i<n; i++) {
+	    gl_putbox(x + i * font_width, y, font_width,
+		      font_height, font_address +
+		      (unsigned char) s[i] * font_charactersize);
+	}
+    } else {			/* masked write */
+        for (i=0; i<n; i++) {
+	    gl_putboxmask(x + i * font_width, y, font_width,
+			  font_height, font_address +
+			  (unsigned char) s[i] * font_charactersize);
+	}
+    }
+}
+
+void gl_write(int x, int y, char *s)
+{
+    int n;
+    for (n=0; s[n]; n++);
+    gl_writen(x, y, n, s);
+}
+
+#ifndef SVGA_AOUT
+
+static int gl_nprintf(int sx, int sy, size_t bufs, const char *fmt, va_list args)
+{
+    unsigned char *buf;
+    static int x = 0, y = 0, x_start = 0;
+    int n;
+
+    buf = alloca(bufs);
+    n = vsnprintf(buf, bufs, fmt, args);
+    if (n < 0)
+	return n; /* buffer did not suffice, return and retry */
+
+    if ((sx >= 0) && (sy >= 0)) {
+	x = x_start = sx;
+	y = sy;
+    }
+	
+    for (; *buf; buf++)
+	switch (*buf) {
+	case '\a':		/* badly implemented */
+	    fputc('\a', stdout);
+	    fflush(stdout);
+	    break;
+	case '\b':
+	    x -= font_width;
+	    if (x < x_start) {
+		x = WIDTH + (x_start % font_width);
+		while(x + font_width > WIDTH)
+		    x -= font_width;
+		if (y >= font_height)
+		    y -= font_height;
+	    }
+	    break;
+	case '\n':
+	  newline:
+	    y += font_height;
+	    if (y + font_height > HEIGHT)
+		y %= font_height;
+	case '\r':
+	    x = x_start;
+	    break;
+	case '\t':
+	    x += ((TEXT_TABSIZE - ((x - x_start) / font_width) % TEXT_TABSIZE) * font_width);
+	    goto chk_wrap;
+	    break;
+	case '\v':
+	    y += font_height;
+	    if (y + font_height > HEIGHT)
+		y %= font_height;
+	    break;
+	default:
+	    gl_writen(x, y, 1, buf);
+	    x += font_width;
+	  chk_wrap:
+	    if (x + font_width > WIDTH)
+		goto newline;
+	}
+    return n;
+}
+
+int gl_printf(int x, int y, const char *fmt, ...)
+{
+    size_t bufs = BUFSIZ;
+    int result;
+    va_list args;
+
+    va_start(args, fmt);
+
+    /* Loop until buffer size suffices */
+    do {
+	result = gl_nprintf(x, y, bufs, fmt, args);
+	bufs <<= 1;
+    } while(result < 0);
+	
+    va_end(args);
+    return result;
+}
+
+#endif
+void gl_expandfont(int fw, int fh, int fg, void *_f1, void *_f2)
+{
+/* Convert bit-per-pixel font to byte(s)-per-pixel font */
+    uchar *f1 = _f1;
+    uchar *f2 = _f2;
+    int i, x, y, b = 0;		/* keep gcc happy with b = 0 - MW */
+
+    for (i = 0; i < 256; i++) {
+	for (y = 0; y < fh; y++)
+	    for (x = 0; x < fw; x++) {
+		if (x % 8 == 0)
+		    b = *f1++;
+		if (b & (128 >> (x % 8)))	/* pixel */
+		    switch (BYTESPERPIXEL) {
+		    case 1:
+			*f2 = fg;
+			f2++;
+			break;
+		    case 2:
+			*(ushort *) f2 = fg;
+			f2 += 2;
+			break;
+		    case 3:
+			*(ushort *) f2 = fg;
+			*(f2 + 2) = fg >> 16;
+			f2 += 3;
+			break;
+		    case 4:
+			*(uint *) f2 = fg;
+			f2 += 4;
+		} else		/* no pixel */
+		    switch (BYTESPERPIXEL) {
+		    case 1:
+			*f2 = 0;
+			f2++;
+			break;
+		    case 2:
+			*(ushort *) f2 = 0;
+			f2 += 2;
+			break;
+		    case 3:
+			*(ushort *) f2 = 0;
+			*(f2 + 2) = 0;
+			f2 += 3;
+			break;
+		    case 4:
+			*(uint *) f2 = 0;
+			f2 += 4;
+		    }
+	    }
+    }
+}
+
+static void expandcharacter(int bg, int fg, int c, unsigned char *bitmap)
+{
+    int x, y;
+    unsigned char *font;
+    int b = 0;			/* keep gcc happy with b = 0 - MW */
+
+    font = font_address + c * (font_height * ((font_width + 7) / 8));
+
+    for (y = 0; y < font_height; y++)
+	for (x = 0; x < font_width; x++) {
+	    if (x % 8 == 0)
+		b = *font++;
+	    if (b & (128 >> (x % 8)))	/* pixel */
+		switch (BYTESPERPIXEL) {
+		case 1:
+		    *bitmap = fg;
+		    bitmap++;
+		    break;
+		case 2:
+		    *(ushort *) bitmap = fg;
+		    bitmap += 2;
+		    break;
+		case 3:
+		    *(ushort *) bitmap = fg;
+		    *(bitmap + 2) = fg >> 16;
+		    bitmap += 3;
+		    break;
+		case 4:
+		    *(uint *) bitmap = fg;
+		    bitmap += 4;
+	    } else		/* background pixel */
+		switch (BYTESPERPIXEL) {
+		case 1:
+		    *bitmap = bg;
+		    bitmap++;
+		    break;
+		case 2:
+		    *(ushort *) bitmap = bg;
+		    bitmap += 2;
+		    break;
+		case 3:
+		    *(ushort *) bitmap = bg;
+		    *(bitmap + 2) = bg;
+		    bitmap += 3;
+		    break;
+		case 4:
+		    *(uint *) bitmap = bg;
+		    bitmap += 4;
+		}
+	}
+}
+
+/* Write using compressed font. */
+
+static void writecompressed(int x, int y, int n, unsigned char *s)
+{
+    unsigned char *bitmap;
+    int i;
+    bitmap = alloca(font_width * font_height * BYTESPERPIXEL);
+    if (!(font_writemode & WRITEMODE_MASKED)) {
+        for (i=0; i<n; i++) {
+	    expandcharacter(compressed_font_bg,
+			    compressed_font_fg, s[i], bitmap);
+	    gl_putbox(x + i * font_width, y, font_width,
+		      font_height, bitmap);
+	}
+    } else {			/* masked write */
+        for (i=0; i<n; i++) {
+	    expandcharacter(0, compressed_font_fg, s[i], bitmap);
+	    gl_putboxmask(x + i * font_width, y, font_width,
+			  font_height, bitmap);
+	}
+    }
+}
+
+void gl_setfontcolors(int bg, int fg)
+{
+    compressed_font_bg = bg;
+    compressed_font_fg = fg;
+}
diff --git a/haiku/vgagl/vga.h b/haiku/vgagl/vga.h
new file mode 100644
index 0000000..67c2502
--- /dev/null
+++ b/haiku/vgagl/vga.h
@@ -0,0 +1,551 @@
+/* VGAlib version 1.2 - (c) 1993 Tommy Frandsen                    */
+/*                                                                 */
+/* This library is free software; you can redistribute it and/or   */
+/* modify it without any restrictions. This library is distributed */
+/* in the hope that it will be useful, but without any warranty.   */
+
+/* Extended for svgalib by Harm Hanemaayer and Hartmut Schirmer */
+
+#ifndef VGA_H
+#define VGA_H
+
+#include <sys/types.h>
+#include <sys/time.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#define TEXT 	     0		/* Compatible with VGAlib v1.2 */
+#define G320x200x16  1
+#define G640x200x16  2
+#define G640x350x16  3
+#define G640x480x16  4
+#define G320x200x256 5
+#define G320x240x256 6
+#define G320x400x256 7
+#define G360x480x256 8
+#define G640x480x2   9
+
+#define G640x480x256 10
+#define G800x600x256 11
+#define G1024x768x256 12
+
+#define G1280x1024x256 13	/* Additional modes. */
+
+#define G320x200x32K 14
+#define G320x200x64K 15
+#define G320x200x16M 16
+#define G640x480x32K 17
+#define G640x480x64K 18
+#define G640x480x16M 19
+#define G800x600x32K 20
+#define G800x600x64K 21
+#define G800x600x16M 22
+#define G1024x768x32K 23
+#define G1024x768x64K 24
+#define G1024x768x16M 25
+#define G1280x1024x32K 26
+#define G1280x1024x64K 27
+#define G1280x1024x16M 28
+
+#define G800x600x16 29
+#define G1024x768x16 30
+#define G1280x1024x16 31
+
+#define G720x348x2 32		/* Hercules emulation mode */
+
+#define G320x200x16M32 33	/* 32-bit per pixel modes. */
+#define G640x480x16M32 34
+#define G800x600x16M32 35
+#define G1024x768x16M32 36
+#define G1280x1024x16M32 37
+
+/* additional resolutions */
+#define G1152x864x16 38
+#define G1152x864x256 39
+#define G1152x864x32K 40
+#define G1152x864x64K 41
+#define G1152x864x16M 42
+#define G1152x864x16M32 43
+
+#define G1600x1200x16 44
+#define G1600x1200x256 45
+#define G1600x1200x32K 46
+#define G1600x1200x64K 47
+#define G1600x1200x16M 48
+#define G1600x1200x16M32 49
+
+#define G320x240x256V 50
+#define G320x240x32K 51
+#define G320x240x64K 52
+#define G320x240x16M 53
+#define G320x240x16M32 54
+
+#define G400x300x256 55
+#define G400x300x32K 56
+#define G400x300x64K 57
+#define G400x300x16M 58
+#define G400x300x16M32 59
+
+#define G512x384x256 60
+#define G512x384x32K 61
+#define G512x384x64K 62
+#define G512x384x16M 63
+#define G512x384x16M32 64
+
+#define G960x720x256 65
+#define G960x720x32K 66
+#define G960x720x64K 67
+#define G960x720x16M 68
+#define G960x720x16M32 69
+
+#define G1920x1440x256 70
+#define G1920x1440x32K 71
+#define G1920x1440x64K 72
+#define G1920x1440x16M 73
+#define G1920x1440x16M32 74
+
+/* The following modes have been introduced by SciTech Display Doctor */
+
+#define G320x400x256V 75
+#define G320x400x32K 76
+#define G320x400x64K 77
+#define G320x400x16M 78
+#define G320x400x16M32 79
+
+#define G640x400x256 80
+#define G640x400x32K 81
+#define G640x400x64K 82
+#define G640x400x16M 83
+#define G640x400x16M32 84
+
+#define G320x480x256 85
+#define G320x480x32K 86
+#define G320x480x64K 87
+#define G320x480x16M 88
+#define G320x480x16M32 89
+
+#define G720x540x256 90
+#define G720x540x32K 91
+#define G720x540x64K 92
+#define G720x540x16M 93
+#define G720x540x16M32 94
+
+#define G848x480x256 95
+#define G848x480x32K 96
+#define G848x480x64K 97
+#define G848x480x16M 98
+#define G848x480x16M32 99
+
+#define G1072x600x256 100
+#define G1072x600x32K 101
+#define G1072x600x64K 102
+#define G1072x600x16M 103
+#define G1072x600x16M32 104
+
+#define G1280x720x256 105
+#define G1280x720x32K 106
+#define G1280x720x64K 107
+#define G1280x720x16M 108
+#define G1280x720x16M32 109
+
+#define G1360x768x256 110
+#define G1360x768x32K 111
+#define G1360x768x64K 112
+#define G1360x768x16M 113
+#define G1360x768x16M32 114
+
+#define G1800x1012x256 115
+#define G1800x1012x32K 116
+#define G1800x1012x64K 117
+#define G1800x1012x16M 118
+#define G1800x1012x16M32 119
+
+#define G1920x1080x256 120
+#define G1920x1080x32K 121
+#define G1920x1080x64K 122
+#define G1920x1080x16M 123
+#define G1920x1080x16M32 124
+
+#define G2048x1152x256 125
+#define G2048x1152x32K 126
+#define G2048x1152x64K 127
+#define G2048x1152x16M 128
+#define G2048x1152x16M32 129
+
+#define G2048x1536x256 130
+#define G2048x1536x32K 131
+#define G2048x1536x64K 132
+#define G2048x1536x16M 133
+#define G2048x1536x16M32 134
+
+#define G512x480x256 135
+#define G512x480x32K 136
+#define G512x480x64K 137
+#define G512x480x16M 138
+#define G512x480x16M32 139
+
+#define G400x600x256 140
+#define G400x600x32K 141
+#define G400x600x64K 142
+#define G400x600x16M 143
+#define G400x600x16M32 144
+
+#define __GLASTMODE G400x600x16M32
+#define GLASTMODE vga_lastmodenumber()
+
+    extern int vga_version;
+
+    extern int vga_setmode(int mode);
+    extern int vga_hasmode(int mode);
+    extern int vga_setflipchar(int c);
+
+    extern int vga_clear(void);
+    extern int vga_flip(void);
+
+    extern int vga_getxdim(void);
+    extern int vga_getydim(void);
+    extern int vga_getcolors(void);
+
+    extern int vga_setpalette(int index, int red, int green, int blue);
+    extern int vga_getpalette(int index, int *red, int *green, int *blue);
+    extern int vga_setpalvec(int start, int num, int *pal);
+    extern int vga_getpalvec(int start, int num, int *pal);
+
+    extern int vga_screenoff(void);
+    extern int vga_screenon(void);
+
+    extern int vga_setcolor(int color);
+    extern int vga_drawpixel(int x, int y);
+    extern int vga_drawline(int x1, int y1, int x2, int y2);
+    extern int vga_drawscanline(int line, unsigned char *colors);
+    extern int vga_drawscansegment(unsigned char *colors, int x, int y, int length);
+    extern int vga_getpixel(int x, int y);	/* Added. */
+    extern int vga_getscansegment(unsigned char *colors, int x, int y, int length);
+
+    extern int vga_getch(void);
+
+    extern int vga_dumpregs(void);
+
+
+/* Extensions to VGAlib v1.2: */
+
+/* blit flags */
+#define HAVE_BITBLIT 1
+#define HAVE_FILLBLIT 2
+#define HAVE_IMAGEBLIT 4
+#define HAVE_HLINELISTBLIT 8
+#define HAVE_BLITWAIT 16
+
+/* other flags */
+#define HAVE_RWPAGE 1		/* vga_setreadpage() / vga_setwritepage() available */
+#define IS_INTERLACED 2		/* mode is interlaced */
+#define IS_MODEX 4		/* ModeX style 256 colors */
+#define IS_DYNAMICMODE 8	/* Dynamic defined mode */
+#define CAPABLE_LINEAR 16	/* Can go to linear addressing mode. */
+#define IS_LINEAR 32		/* Linear addressing enabled. */
+#define EXT_INFO_AVAILABLE 64	/* Returned modeinfo contains valid extended fields */
+#define RGB_MISORDERED 128	/* Mach32 32bpp uses 0BGR instead of BGR0. */
+    /* As of this version 1.25 also used to signal if real RGB
+       (red first in memory) is used instead of BGR (Mach32 DAC 4) */
+#define HAVE_EXT_SET 256	/* vga_ext_set() available */
+
+#define IS_IN_STANDARD_VGA_DRIVER(mode) ( \
+        ((mode) < G640x480x256) || ((mode) == G720x348x2) )
+
+    typedef struct {
+	int width;
+	int height;
+	int bytesperpixel;
+	int colors;
+	int linewidth;		/* scanline width in bytes */
+	int maxlogicalwidth;	/* maximum logical scanline width */
+	int startaddressrange;	/* changeable bits set */
+	int maxpixels;		/* video memory / bytesperpixel */
+	int haveblit;		/* mask of blit functions available */
+	int flags;		/* other flags */
+
+	/* Extended fields: */
+
+	int chiptype;		/* Chiptype detected */
+	int memory;		/* videomemory in KB */
+	int linewidth_unit;	/* Use only a multiple of this as parameter for set_logicalwidth and
+				   set_displaystart */
+	char *linear_aperture;	/* points to mmap secondary mem aperture of card (NULL if unavailable) */
+	int aperture_size;	/* size of aperture in KB if size>=videomemory. 0 if unavail */
+	void (*set_aperture_page) (int page);
+	/* if aperture_size<videomemory select a memory page */
+	void *extensions;	/* points to copy of eeprom for mach32 */
+	/* depends from actual driver/chiptype.. etc. */
+    } vga_modeinfo;
+
+    extern vga_modeinfo *vga_getmodeinfo(int mode);
+    extern int vga_getdefaultmode(void);
+    extern int vga_getcurrentmode(void);
+    extern int vga_getcurrentchipset(void);
+    extern char *vga_getmodename(int mode);
+    extern int vga_getmodenumber(char *name);
+    extern int vga_lastmodenumber(void);
+    extern int vga_getoptmode(int x, int y, int colors, int bytesperpixel, int c);
+
+    extern unsigned char *graph_mem;
+    extern unsigned char *vga_getgraphmem(void);
+
+    extern void vga_setpage(int p);
+    extern void vga_setreadpage(int p);
+    extern void vga_setwritepage(int p);
+    extern void vga_setlogicalwidth(int w);
+    extern void vga_setdisplaystart(int a);
+    extern void vga_waitretrace(void);
+    extern int vga_claimvideomemory(int n);
+    extern void vga_disabledriverreport(void);
+    extern int vga_setmodeX(void);
+    extern int vga_init(void);	/* Used to return void in svgalib <= 1.12. */
+    extern int vga_initf(int);
+    extern int vga_getmousetype(void);
+    extern int vga_getmonitortype(void);
+    extern void vga_setmousesupport(int s);
+    extern void vga_lockvc(void);
+    extern void vga_unlockvc(void);
+    extern int vga_getkey(void);
+    extern int vga_oktowrite(void);
+    extern void vga_copytoplanar256(unsigned char *virtualp, int pitch,
+				  int voffset, int vpitch, int w, int h);
+    extern void vga_copytoplanar16(unsigned char *virtualp, int pitch,
+				   int voffset, int vpitch, int w, int h);
+    extern void vga_copytoplane(unsigned char *virtualp, int pitch,
+		       int voffset, int vpitch, int w, int h, int plane);
+    extern int vga_setlinearaddressing(void);
+    extern void vga_safety_fork(void (*shutdown_routine) (void));
+
+    extern int vga_simple_init(void);
+    extern void vga_chipset_saveregs(unsigned char *);
+    extern void vga_chipset_setregs(unsigned char *);
+
+#ifdef EGA			/* Kernel headers may define this. */
+#undef EGA
+#endif
+
+#define UNDEFINED	0
+#define VGA		1
+#define ET4000		2
+#define CIRRUS		3
+#define TVGA8900	4
+#define OAK		5
+#define EGA		6
+#define S3		7
+#define ET3000		8
+#define MACH32		9
+#define GVGA6400	10
+#define ARK		11
+#define ATI		12
+#define ALI		13
+#define MACH64		14
+#define CHIPS		15
+#define APM             16
+#define NV3		17
+#define ET6000		18
+#define VESA		19
+#define MX              20
+#define PARADISE	21
+#define RAGE		22
+#define BANSHEE		23
+#define SIS		24
+#define I740		25
+#define NEOMAGIC	26
+#define LAGUNA		27
+#define FBDEV		28
+#define G400		29
+#define R128		30
+#define SAVAGE		31
+
+    /* Hor. sync: */
+#define MON640_60	0	/* 31.5 KHz (standard VGA) */
+#define MON800_56	1	/* 35.1 KHz (old SVGA) */
+#define MON1024_43I	2	/* 35.5 KHz (low-end SVGA, 8514) */
+#define MON800_60	3	/* 37.9 KHz (SVGA) */
+#define MON1024_60	4	/* 48.3 KHz (SVGA non-interlaced) */
+#define MON1024_70	5	/* 56.0 KHz (SVGA high frequency) */
+#define MON1024_72	6
+
+    extern void vga_setchipset(int c);
+    extern void vga_setchipsetandfeatures(int c, int par1, int par2);
+    extern void vga_gettextfont(void *font);
+    extern void vga_puttextfont(void *font);
+    extern void vga_settextmoderegs(void *regs);
+    extern void vga_gettextmoderegs(void *regs);
+
+    extern int vga_white(void);
+    extern int vga_setegacolor(int c);
+    extern int vga_setrgbcolor(int r, int g, int b);
+
+    extern void vga_bitblt(int srcaddr, int destaddr, int w, int h, int pitch);
+    extern void vga_imageblt(void *srcaddr, int destaddr, int w, int h, int pitch);
+    extern void vga_fillblt(int destaddr, int w, int h, int pitch, int c);
+    extern void vga_hlinelistblt(int ymin, int n, int *xmin, int *xmax, int pitch, int c);
+    extern void vga_blitwait(void);
+    extern int vga_ext_set(unsigned what,...);
+    extern int vga_accel(unsigned operation,...);
+
+    extern int vga_setcrtcregs(unsigned char *);
+    extern int vga_getcrtcregs(unsigned char *);
+
+    extern int vga_addtiming(int pixelClock,
+       			      int HDisplay,		
+                              int HSyncStart,
+                              int HSyncEnd,
+                              int HTotal,
+                              int VDisplay,
+                              int VSyncStart,
+                              int VSyncEnd,
+                              int VTotal,
+                              int flags);
+
+    extern int vga_changetiming(int pixelClock,
+       			      int HDisplay,		
+                              int HSyncStart,
+                              int HSyncEnd,
+                              int HTotal,
+                              int VDisplay,
+                              int VSyncStart,
+                              int VSyncEnd,
+                              int VTotal,
+                              int flags);
+
+   extern int vga_getcurrenttiming(int *pixelClock,
+       			      int *HDisplay,		
+                              int *HSyncStart,
+                              int *HSyncEnd,
+                              int *HTotal,
+                              int *VDisplay,
+                              int *VSyncStart,
+                              int *VSyncEnd,
+                              int *VTotal,
+                              int *flags);
+
+   extern int vga_addmode(int xdim, int ydim, int cols, 
+                          int xbytes, int bytespp);
+
+   extern int vga_guesstiming(int x, int y, int clue, int arg);
+
+/* Valid values for what in vga_ext_set: */
+#define VGA_EXT_AVAILABLE	0	/* supported flags */
+#define VGA_EXT_SET		1	/* set flag(s) */
+#define VGA_EXT_CLEAR		2	/* clear flag(s) */
+#define VGA_EXT_RESET		3	/* set/clear flag(s) */
+#define VGA_EXT_PAGE_OFFSET	4	/* set an offset for all subsequent vga_set*page() calls */
+    /* Like: vga_ext_set(VGA_EXT_PAGE_OFFSET, 42);           */
+    /* returns the previous offset value.                    */
+#define VGA_EXT_FONT_SIZE	5	/* the (maximal) size of the font buffer */
+
+/* Valid params for VGA_EXT_AVAILABLE: */
+#define VGA_AVAIL_SET		0	/* vga_ext_set sub funcs */
+#define VGA_AVAIL_ACCEL		1	/* vga_accel sub funcs */
+#define VGA_AVAIL_FLAGS		2	/* known flags for VGA_EXT_SET */
+#define VGA_AVAIL_ROP		3	/* vga_accel ROP sub funcs */
+#define VGA_AVAIL_TRANSPARENCY	4	/* vga_accel TRANSPARENCY sub funcs */
+#define VGA_AVAIL_ROPMODES	5	/* vga_accel ROP modes supported funcs */
+#define VGA_AVAIL_TRANSMODES	6	/* vga_accel TRANSPARENCY modes supported */
+
+/* Known flags to vga_ext_set() */
+#define VGA_CLUT8		1	/* 8 bit DAC entries */
+
+/* Acceleration interface. */
+
+/* Accel operations. */
+#define ACCEL_FILLBOX			1	/* Simple solid fill. */
+#define ACCEL_SCREENCOPY		2	/* Simple screen-to-screen BLT. */
+#define ACCEL_PUTIMAGE			3	/* Straight image transfer. */
+#define ACCEL_DRAWLINE			4	/* General line draw. */
+#define ACCEL_SETFGCOLOR		5	/* Set foreground color. */
+#define ACCEL_SETBGCOLOR		6	/* Set background color. */
+#define ACCEL_SETTRANSPARENCY		7	/* Set transparency mode. */
+#define ACCEL_SETRASTEROP		8	/* Set raster-operation. */
+#define ACCEL_PUTBITMAP			9	/* Color-expand bitmap. */
+#define ACCEL_SCREENCOPYBITMAP		10	/* Color-expand from screen. */
+#define ACCEL_DRAWHLINELIST		11	/* Draw horizontal spans. */
+#define ACCEL_SETMODE			12	/* Set blit strategy. */
+#define ACCEL_SYNC			13	/* Wait for blits to finish. */
+#define ACCEL_SETOFFSET			14	/* Set screen offset */
+#define ACCEL_SCREENCOPYMONO		15	/* Monochrome screen-to-screen BLT. */
+#define ACCEL_POLYLINE			16	/* Draw multiple lines. */
+#define ACCEL_POLYHLINE			17	/* Draw multiple horizontal spans. */
+#define ACCEL_POLYFILLMODE		18	/* Set polygon mode. */
+
+/* Corresponding bitmask. */
+#define ACCELFLAG_FILLBOX		0x1	/* Simple solid fill. */
+#define ACCELFLAG_SCREENCOPY		0x2	/* Simple screen-to-screen BLT. */
+#define ACCELFLAG_PUTIMAGE		0x4	/* Straight image transfer. */
+#define ACCELFLAG_DRAWLINE		0x8	/* General line draw. */
+#define ACCELFLAG_SETFGCOLOR		0x10	/* Set foreground color. */
+#define ACCELFLAG_SETBGCOLOR		0x20	/* Set background color. */
+#define ACCELFLAG_SETTRANSPARENCY	0x40	/* Set transparency mode. */
+#define ACCELFLAG_SETRASTEROP		0x80	/* Set raster-operation. */
+#define ACCELFLAG_PUTBITMAP		0x100	/* Color-expand bitmap. */
+#define ACCELFLAG_SCREENCOPYBITMAP	0x200	/* Color-exand from screen. */
+#define ACCELFLAG_DRAWHLINELIST		0x400	/* Draw horizontal spans. */
+#define ACCELFLAG_SETMODE		0x800	/* Set blit strategy. */
+#define ACCELFLAG_SYNC			0x1000	/* Wait for blits to finish. */
+#define ACCELFLAG_SETOFFSET		0x2000	/* Set screen offset */
+#define ACCELFLAG_SCREENCOPYMONO	0x4000	/* Monochrome screen-to-screen BLT. */
+#define ACCELFLAG_POLYLINE		0x8000	/* Draw multiple lines. */
+#define ACCELFLAG_POLYHLINE		0x10000	/* Draw multiple horizontal spans. */
+#define ACCELFLAG_POLYFILLMODE		0x20000	/* Set polygon mode. */
+
+/* Mode for SetTransparency. */
+#define DISABLE_TRANSPARENCY_COLOR	0
+#define ENABLE_TRANSPARENCY_COLOR	1
+#define DISABLE_BITMAP_TRANSPARENCY	2
+#define ENABLE_BITMAP_TRANSPARENCY	3
+
+/* Flags for SetMode (accelerator interface). */
+#define BLITS_SYNC			0
+#define BLITS_IN_BACKGROUND		0x1
+
+/* Raster ops. */
+#define ROP_COPY			0	/* Straight copy. */
+#define ROP_OR				1	/* Source OR destination. */
+#define ROP_AND				2	/* Source AND destination. */
+#define ROP_XOR				3	/* Source XOR destination. */
+#define ROP_INVERT			4	/* Invert destination. */
+
+/* For the poly funcs */
+#define ACCEL_START			1
+#define ACCEL_END			2
+
+/*
+ * wait for keypress, mousemove, I/O, timeout. cf. select (3) for details on
+ * all parameters execept which.
+ * NULL is a valid argument for any of the ptrs.
+ */
+
+    extern int vga_waitevent(int which, fd_set * in, fd_set * out, fd_set * except,
+			     struct timeval *timeout);
+
+/*
+ * valid values for what ( | is valid to combine them )
+ */
+#define VGA_MOUSEEVENT	1
+#define VGA_KEYEVENT	2
+
+/*
+ * return value >= has bits set for mouse/keyboard events detected.
+ * mouse and raw keyboard events are already handled and their bits removed
+ * from *in when vga_waitevent returns.
+ * VGA_KEYEVENT relates to vga_getch NOT vga_getkey.
+ * return values < 0 signal errors. In this case check errno.
+ */
+
+/* Background running */
+extern void vga_runinbackground(int stat, ...);
+#define VGA_GOTOBACK -1
+#define VGA_COMEFROMBACK -2
+extern int vga_runinbackground_version(void);
+
+#ifdef __cplusplus
+}
+
+#endif
+#endif				/* VGA_H */
diff --git a/haiku/vgagl/vgagl.h b/haiku/vgagl/vgagl.h
new file mode 100644
index 0000000..fe2cf8d
--- /dev/null
+++ b/haiku/vgagl/vgagl.h
@@ -0,0 +1,188 @@
+/* Graphics Library headerfile */
+
+#ifndef VGAGL_H
+#define VGAGL_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+/* Graphics context */
+
+#define CONTEXT_VIRTUAL		0x0
+#define CONTEXT_PAGED		0x1
+#define CONTEXT_LINEAR		0x2
+#define CONTEXT_MODEX		0x3
+#define CONTEXT_PLANAR16	0x4
+
+#define MODEFLAG_PAGEFLIPPING_CAPABLE		0x01
+#define MODEFLAG_TRIPLEBUFFERING_CAPABLE	0x02
+#define MODEFLAG_PAGEFLIPPING_ENABLED		0x04
+#define MODEFLAG_TRIPLEBUFFERING_ENABLED	0x08
+#define MODEFLAG_FLIPPAGE_BANKALIGNED		0x10
+/*
+ * The next two can never occur together, thus we use the same flag
+ * (as svgalib does).
+ */
+#define MODEFLAG_32BPP_SHIFT8			0x20
+#define MODEFLAG_24BPP_REVERSED			0x20
+
+    typedef struct {
+	void (*driver_setpixel_func) (int, int, int);
+	int (*driver_getpixel_func) (int, int);
+	void (*driver_hline_func) (int, int, int, int);
+	void (*driver_fillbox_func) (int, int, int, int, int);
+	void (*driver_putbox_func) (int, int, int, int, void *, int);
+	void (*driver_getbox_func) (int, int, int, int, void *, int);
+	void (*driver_putboxmask_func) (int, int, int, int, void *);
+	void (*driver_putboxpart_func) (int, int, int, int, int, int, void *,
+					int, int);
+	void (*driver_getboxpart_func) (int, int, int, int, int, int, void *,
+					int, int);
+	void (*driver_copybox_func) (int, int, int, int, int, int);
+    } framebufferfunctions;
+
+    typedef struct {
+	unsigned char modetype;	/* virtual, paged, linear, mode X */
+	unsigned char modeflags;	/* or planar16 */
+	unsigned char dummy;
+	unsigned char flippage;
+	int width;		/* width in pixels */
+	int height;		/* height in pixels */
+	int bytesperpixel;	/* bytes per pixel (1, 2, 3, or 4) */
+	int colors;		/* number of colors */
+	int bitsperpixel;	/* bits per pixel (8, 15, 16 or 24) */
+	int bytewidth;		/* length of a scanline in bytes */
+	char *vbuf;		/* address of framebuffer */
+	int clip;		/* clipping enabled? */
+	int clipx1;		/* top-left coordinate of clip window */
+	int clipy1;
+	int clipx2;		/* bottom-right coordinate of clip window */
+	int clipy2;
+	framebufferfunctions ff;
+    } GraphicsContext;
+
+    extern GraphicsContext currentcontext;
+
+#define BYTESPERPIXEL (currentcontext.bytesperpixel)
+#define BYTEWIDTH (currentcontext.bytewidth)
+#define WIDTH (currentcontext.width)
+#define HEIGHT (currentcontext.height)
+#define VBUF (currentcontext.vbuf)
+#define MODETYPE (currentcontext.modetype)
+#define MODEFLAGS (currentcontext.modeflags)
+#define BITSPERPIXEL (currentcontext.bitsperpixel)
+#define COLORS (currentcontext.colors)
+
+#define __clip (currentcontext.clip)
+#define __clipx1 (currentcontext.clipx1)
+#define __clipy1 (currentcontext.clipy1)
+#define __clipx2 (currentcontext.clipx2)
+#define __clipy2 (currentcontext.clipy2)
+
+
+/* Configuration */
+
+    int gl_setcontextvga(int m);
+    int gl_setcontextvgavirtual(int m);
+    void gl_setcontextvirtual(int w, int h, int bpp, int bitspp, void *vbuf);
+    void gl_setcontextwidth(int w);
+    void gl_setcontextheight(int h);
+    GraphicsContext *gl_allocatecontext(void);
+    void gl_setcontext(GraphicsContext * gc);
+    void gl_getcontext(GraphicsContext * gc);
+    void gl_freecontext(GraphicsContext * gc);
+
+/* Line drawing */
+
+    void gl_setpixel(int x, int y, int c);
+    void gl_setpixelrgb(int x, int y, int r, int g, int b);
+    int gl_getpixel(int x, int y);
+    void gl_getpixelrgb(int x, int y, int *r, int *g, int *b);
+    int gl_rgbcolor(int r, int g, int b);
+    void gl_hline(int x1, int y, int x2, int c);
+    void gl_line(int x1, int y1, int x2, int y2, int c);
+    void gl_circle(int x, int y, int r, int c);
+    void gl_fillcircle(int sx, int sy, int r, int c);
+    void gl_bcircle(int sx, int sy, int r, int c, int fill);
+ 
+/* Box (bitmap) functions */
+
+    void gl_fillbox(int x, int y, int w, int h, int c);
+    void gl_getbox(int x, int y, int w, int h, void *dp);
+    void gl_putbox(int x, int y, int w, int h, void *dp);
+    void gl_putboxpart(int x, int y, int w, int h, int bw, int bh, void *b,
+		       int xo, int yo);
+    void gl_putboxmask(int x, int y, int w, int h, void *dp);
+    void gl_copybox(int x1, int y1, int w, int h, int x2, int y2);
+    void gl_copyboxtocontext(int x1, int y1, int w, int h, GraphicsContext * gc,
+			     int x2, int y2);
+    void gl_copyboxfromcontext(GraphicsContext * gc, int x1, int y1, int w, int h,
+			       int x2, int y2);
+/* The following functions only work in 256-color modes: */
+    void gl_compileboxmask(int w, int h, void *sdp, void *ddp);
+    int gl_compiledboxmasksize(int w, int h, void *sdp);
+    void gl_putboxmaskcompiled(int x, int y, int w, int h, void *dp);
+
+/* Miscellaneous */
+
+    void gl_clearscreen(int c);
+    void gl_scalebox(int w1, int h1, void *sb, int w2, int h2, void *db);
+    void gl_setdisplaystart(int x, int y);
+    void gl_enableclipping(void);
+    void gl_setclippingwindow(int x1, int y1, int x2, int y2);
+    void gl_disableclipping(void);
+
+/* Screen buffering */
+
+    void gl_copyscreen(GraphicsContext * gc);
+    void gl_setscreenoffset(int o);
+    int gl_enablepageflipping(GraphicsContext * gc);
+
+/* Text */
+
+/* Writemode flags. */
+#define WRITEMODE_OVERWRITE 0
+#define WRITEMODE_MASKED 1
+#define FONT_EXPANDED 0
+#define FONT_COMPRESSED 2
+
+    void gl_expandfont(int fw, int fh, int c, void *sfdp, void *dfdp);
+    void gl_setfont(int fw, int fh, void *fdp);
+    void gl_colorfont(int fw, int fh, int c, void *fdp);
+    void gl_setwritemode(int wm);
+    void gl_write(int x, int y, char *s);
+    void gl_writen(int x, int y, int n, char *s);
+    void gl_setfontcolors(int bg, int fg);
+
+/* gl_printf is only available in ELF libraries!! */
+    int gl_printf(int x, int y, const char *fmt,...);
+
+    extern unsigned char *gl_font8x8;	/* compressed 8x8 font */
+
+/* 256-color Palette */
+
+    typedef struct {
+	struct {
+	    unsigned char red;	/* 6-bit values */
+	    unsigned char green;
+	    unsigned char blue;
+	} color[256];
+    } Palette;
+
+    void gl_setpalettecolor(int c, int r, int b, int g);
+    void gl_getpalettecolor(int c, int *r, int *b, int *g);
+    void gl_setpalettecolors(int s, int n, void *dp);
+    void gl_getpalettecolors(int s, int n, void *dp);
+    void gl_setpalette(void *p);
+    void gl_getpalette(void *p);
+    void gl_setrgbpalette(void);
+
+
+#ifdef __cplusplus
+}
+
+#endif
+#endif
diff --git a/haiku/vgagl/vgajoystick.h b/haiku/vgagl/vgajoystick.h
new file mode 100644
index 0000000..4028d34
--- /dev/null
+++ b/haiku/vgagl/vgajoystick.h
@@ -0,0 +1,68 @@
+#ifndef VGAJOYSTICK_H
+#define VGAJOYSTICK_H
+/* Joystick interface modeled after svgalibs keyboard and mouse interfaces 
+ * Copyright 1998 Daniel Engström <daniel.engstrom@riksnett.no> 
+ * Partly based on code from 
+ * joystick-0.7.3 Copyright (C) 1992, 1993 Author C. Smith
+ * and 
+ * joystick-1.0.6 Copyright (C) 1997 Vojtech Pavlik 
+ *
+ * Extension and modifications. Multiple joystick support, VC switching,
+ * etc. Michael Weller <eowmob@exp-math.uni-essen.de>.
+ */
+
+/* event for joystick handlers */
+#define JOY_EVENTBUTTONDOWN 1
+#define JOY_EVENTBUTTONUP   2
+#define JOY_EVENTAXIS       3
+
+/* file is a struct FILE to output calibration instructions to,
+ * set to NULL to skip calibration 
+ */
+
+typedef void (*__joystick_output) (const char *msg);
+
+int joystick_init(int joydev, __joystick_output jo);
+
+/* This is guaranteed not to collide with any user definition */
+#define JOY_CALIB_STDOUT ((__joystick_output)(void *)joystick_init)
+
+void joystick_close(int joydev);
+
+/* polls the joystick and calls the eventhandler */
+int joystick_update(void);
+
+typedef void (*__joystick_handler) (int event, int number, char value, int joydev); 
+ /* event - event type; see above
+ * number - the axis or button number for this event 0=x axis or button 1, etc.
+ * value - value for axis events -128 - 0 - +127
+ */
+void joystick_sethandler(int joydev, __joystick_handler jh);
+void joystick_setdefaulthandler(int joydev);
+
+char joystick_getnumaxes(int joydev);
+char joystick_getnumbuttons(int joydev);
+
+/* querys the default handler if used */
+char joystick_getaxis(int joydev, int a);
+char joystick_getbutton(int joydev, int b);
+
+#define joystick_button1(i) joystick_getbutton(i, 0)
+#define joystick_button2(i) joystick_getbutton(i, 1)
+#define joystick_button3(i) joystick_getbutton(i, 2)
+#define joystick_button4(i) joystick_getbutton(i, 3)
+
+#define joystick_getb1() joystick_getbutton(0, 0)
+#define joystick_getb2() joystick_getbutton(0, 1)
+#define joystick_getb3() joystick_getbutton(0, 2)
+#define joystick_getb4() joystick_getbutton(0, 3)
+
+#define joystick_x(i) joystick_getaxis(i, 0)
+#define joystick_y(i) joystick_getaxis(i, 1)
+#define joystick_z(i) joystick_getaxis(i, 2)
+
+#define joystick_getx() joystick_getaxis(0, 0)
+#define joystick_gety() joystick_getaxis(0, 1)
+#define joystick_getz() joystick_getaxis(0, 2)
+
+#endif
diff --git a/haiku/vgagl/vgakeyboard.h b/haiku/vgagl/vgakeyboard.h
new file mode 100644
index 0000000..914ca88
--- /dev/null
+++ b/haiku/vgagl/vgakeyboard.h
@@ -0,0 +1,198 @@
+/* Keyboard interface for svgalib. */
+/* Can be used independently. */
+
+#ifndef VGAKEYBOARD_H
+#define VGAKEYBOARD_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#define SCANCODE_ESCAPE			1
+
+#define SCANCODE_1			2
+#define SCANCODE_2			3
+#define SCANCODE_3			4
+#define SCANCODE_4			5
+#define SCANCODE_5			6
+#define SCANCODE_6			7
+#define SCANCODE_7			8
+#define SCANCODE_8			9
+#define SCANCODE_9			10
+#define SCANCODE_0			11
+
+#define SCANCODE_MINUS			12
+#define SCANCODE_EQUAL			13
+
+#define SCANCODE_BACKSPACE		14
+#define SCANCODE_TAB			15
+
+#define SCANCODE_Q			16
+#define SCANCODE_W			17
+#define SCANCODE_E			18
+#define SCANCODE_R			19
+#define SCANCODE_T			20
+#define SCANCODE_Y			21
+#define SCANCODE_U			22
+#define SCANCODE_I			23
+#define SCANCODE_O			24
+#define SCANCODE_P			25
+#define SCANCODE_BRACKET_LEFT		26
+#define SCANCODE_BRACKET_RIGHT		27
+
+#define SCANCODE_ENTER			28
+
+#define SCANCODE_LEFTCONTROL		29
+
+#define SCANCODE_A			30
+#define SCANCODE_S			31
+#define SCANCODE_D			32
+#define SCANCODE_F			33
+#define SCANCODE_G			34
+#define SCANCODE_H			35
+#define SCANCODE_J			36
+#define SCANCODE_K			37
+#define SCANCODE_L			38
+#define SCANCODE_SEMICOLON		39
+#define SCANCODE_APOSTROPHE		40
+#define SCANCODE_GRAVE			41
+
+#define SCANCODE_LEFTSHIFT		42
+#define SCANCODE_BACKSLASH		43
+
+#define SCANCODE_Z			44
+#define SCANCODE_X			45
+#define SCANCODE_C			46
+#define SCANCODE_V			47
+#define SCANCODE_B			48
+#define SCANCODE_N			49
+#define SCANCODE_M			50
+#define SCANCODE_COMMA			51
+#define SCANCODE_PERIOD			52
+#define SCANCODE_SLASH			53
+
+#define SCANCODE_RIGHTSHIFT		54
+#define SCANCODE_KEYPADMULTIPLY		55
+
+#define SCANCODE_LEFTALT		56
+#define SCANCODE_SPACE			57
+#define SCANCODE_CAPSLOCK		58
+
+#define SCANCODE_F1			59
+#define SCANCODE_F2			60
+#define SCANCODE_F3			61
+#define SCANCODE_F4			62
+#define SCANCODE_F5			63
+#define SCANCODE_F6			64
+#define SCANCODE_F7			65
+#define SCANCODE_F8			66
+#define SCANCODE_F9			67
+#define SCANCODE_F10			68
+
+#define SCANCODE_NUMLOCK		69
+#define SCANCODE_SCROLLLOCK		70
+
+#define SCANCODE_KEYPAD7		71
+#define SCANCODE_CURSORUPLEFT		71
+#define SCANCODE_KEYPAD8		72
+#define SCANCODE_CURSORUP		72
+#define SCANCODE_KEYPAD9		73
+#define SCANCODE_CURSORUPRIGHT		73
+#define SCANCODE_KEYPADMINUS		74
+#define SCANCODE_KEYPAD4		75
+#define SCANCODE_CURSORLEFT		75
+#define SCANCODE_KEYPAD5		76
+#define SCANCODE_KEYPAD6		77
+#define SCANCODE_CURSORRIGHT		77
+#define SCANCODE_KEYPADPLUS		78
+#define SCANCODE_KEYPAD1		79
+#define SCANCODE_CURSORDOWNLEFT		79
+#define SCANCODE_KEYPAD2		80
+#define SCANCODE_CURSORDOWN		80
+#define SCANCODE_KEYPAD3		81
+#define SCANCODE_CURSORDOWNRIGHT	81
+#define SCANCODE_KEYPAD0		82
+#define SCANCODE_KEYPADPERIOD		83
+
+#define SCANCODE_LESS			86
+
+#define SCANCODE_F11			87
+#define SCANCODE_F12			88
+
+#define SCANCODE_KEYPADENTER		96
+#define SCANCODE_RIGHTCONTROL		97
+#define SCANCODE_CONTROL		97
+#define SCANCODE_KEYPADDIVIDE		98
+#define SCANCODE_PRINTSCREEN		99
+#define SCANCODE_RIGHTALT		100
+#define SCANCODE_BREAK			101	/* Beware: is 119     */
+#define SCANCODE_BREAK_ALTERNATIVE	119	/* on some keyboards! */
+
+#define SCANCODE_HOME			102
+#define SCANCODE_CURSORBLOCKUP		103	/* Cursor key block */
+#define SCANCODE_PAGEUP			104
+#define SCANCODE_CURSORBLOCKLEFT	105	/* Cursor key block */
+#define SCANCODE_CURSORBLOCKRIGHT	106	/* Cursor key block */
+#define SCANCODE_END			107
+#define SCANCODE_CURSORBLOCKDOWN	108	/* Cursor key block */
+#define SCANCODE_PAGEDOWN		109
+#define SCANCODE_INSERT			110
+#define SCANCODE_REMOVE			111
+
+#define SCANCODE_RIGHTWIN		126
+#define SCANCODE_LEFTWIN		125
+
+#define KEY_EVENTRELEASE 0
+#define KEY_EVENTPRESS 1
+
+#define MAX_KEYNAME_LEN 20
+
+/* Initialize keyboard handler (brings keyboard into RAW mode). Returns */
+/* 0 if succesful, -1 otherwise. */
+    int keyboard_init(void);
+/* Similar, but returns console fd if succesful. */
+    int keyboard_init_return_fd(void);
+/* Set event handler invoked by keyboard_update(). */
+    typedef void (*__keyboard_handler) (int scancode, int press);
+    void keyboard_seteventhandler(__keyboard_handler handler);
+/* Return keyboard to normal state. */
+    void keyboard_close(void);
+/* Read raw keyboard device and handle events. Returns 0 if no event. */
+    int keyboard_update(void);
+/* Similar to keyboard_update, but wait for an event to happen. */
+/* [This doesn't seem to work very well -- use select on fd] */
+    void keyboard_waitforupdate(void);
+
+/* keyboard_init sets default event handler that keeps track of complete */
+/* keyboard state: */
+
+/* Result of keypressed. */
+#define KEY_NOTPRESSED 0
+#define KEY_PRESSED 1
+
+/* Modes for translatekeys. */
+#define TRANSLATE_CURSORKEYS 1	/* Map cursor block to keypad cursor. */
+#define TRANSLATE_DIAGONAL 2	/* Map keypad diagonal to keypad cursor. */
+#define TRANSLATE_KEYPADENTER 4	/* Map keypad enter to main enter key. */
+#define DONT_CATCH_CTRLC 8	/* Disable Crtl-C check. */
+
+/* Revert to default handler. */
+    void keyboard_setdefaulteventhandler(void);
+/* Return pointer to buffer holding state of each key (scancode). */
+/* Value 1 corresponds to key that is pressed, 0 means not pressed. */
+    char *keyboard_getstate(void);
+/* Force keyboard state to nothing pressed (all zeroes). */
+    void keyboard_clearstate(void);
+/* Let default handler translate cursor key block events to numeric keypad */
+/* cursor key events and other translations. */
+    void keyboard_translatekeys(int mask);
+
+/* Return nonzero if key is depressed. */
+    int keyboard_keypressed(int scancode);
+
+#ifdef __cplusplus
+}
+
+#endif
+#endif
diff --git a/haiku/vgagl/vgamouse.h b/haiku/vgagl/vgamouse.h
new file mode 100644
index 0000000..f63438b
--- /dev/null
+++ b/haiku/vgagl/vgamouse.h
@@ -0,0 +1,185 @@
+/* Mouse interface for svgalib. */
+/* Can be used independently. */
+
+#ifndef VGAMOUSE_H
+#define VGAMOUSE_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#define	MOUSE_MICROSOFT 0
+#define MOUSE_MOUSESYSTEMS 1
+#define MOUSE_MMSERIES 2
+#define MOUSE_LOGITECH 3
+#define MOUSE_BUSMOUSE 4
+#define MOUSE_PS2 5
+#define MOUSE_LOGIMAN 6
+#define MOUSE_GPM 7
+#define MOUSE_SPACEBALL 8
+#define MOUSE_NONE 9 		/* Some special number for a non supported/existing mouse */
+#define MOUSE_INTELLIMOUSE 10
+#define MOUSE_IMPS2 11
+#define MOUSE_PNP 12
+#define MOUSE_WACOM_GRAPHIRE 13
+#define MOUSE_DRMOUSE4DS 14
+#define MOUSE_LAST MOUSE_DRMOUSE4DS
+
+#define MOUSE_ORIENTATION_VERTICAL 0
+#define MOUSE_ORIENTATION_HORIZONTAL 1
+
+#define MOUSE_ACCEL_TYPE_NORMAL 1
+#define MOUSE_ACCEL_TYPE_POWER  2
+
+#define DEFAULT_ACCEL_THRESH	5
+#define DEFAULT_ACCEL_POWER	1.2
+#define DEFAULT_ACCEL_OFFSET	1
+#define DEFAULT_ACCEL_MULT	10
+#define DEFAULT_MAXDELTA	0
+#define DEFAULT_ACCEL_MAXDELTA	0
+#define DEFAULT_ACCEL_TYPE	0	/* MOUSE_ACCEL_TYPE_POWER */
+
+/* MS IntelliMouse has 18 steps, Logitech FirstMouse+ has 24 */
+#define DEFAULT_WHEEL_STEPS     18
+#define DEFAULT_WHEEL_DELTA     (360 / DEFAULT_WHEEL_STEPS)
+
+/* Logical or the following values to one of the above at will and give that for
+   type in mouse_init (still they make only sense for serial mice) */
+
+#define MOUSE_CHG_DTR	0x80000000	/* CLEAR (!) the DTR line */
+#define MOUSE_DTR_HIGH	0x40000000	/* when used with MOUSE_CHG_DTR set DTR not clear it */
+#define MOUSE_CHG_RTS	0x20000000	/* CLEAR (!) the RTS line */
+#define MOUSE_RTS_HIGH	0x10000000	/* when used with MOUSE_CHG_RTS set RTS not clear it */
+
+/* If MOUSE_CHG_DTR is not given the DTR state is not touched.. same with RTS resp. */
+/* So I use MOUSE_MOUSESYSTEMS|MOUSE_CHG_RTS to force my
+   multiprotocol mouse to MOUSESYSTEMS and use init the driver to MOUSESYSTEMS */
+
+#define MOUSE_TYPE_MASK 0xffff	/* the upper 16bit are reserved for future flags */
+
+#define MOUSE_LEFTBUTTON 4
+#define MOUSE_MIDDLEBUTTON 2
+#define MOUSE_RIGHTBUTTON 1
+#define MOUSE_FOURTHBUTTON 8
+#define MOUSE_FIFTHBUTTON 16
+#define MOUSE_SIXTHBUTTON 32
+#define MOUSE_RESETBUTTON 64
+
+#define MOUSE_XDIM 1
+#define MOUSE_YDIM 2
+#define MOUSE_ZDIM 4
+#define MOUSE_RXDIM 8
+#define MOUSE_RYDIM 16
+#define MOUSE_RZDIM 32
+#define MOUSE_2DIM 3
+#define MOUSE_3DIM 7
+#define MOUSE_6DIM 63
+
+#define MOUSE_DEFAULTSAMPLERATE 150
+
+/* Initialize mouse device. Returns 0 if succesful, -1 otherwise. */
+/* (Get the svgalib configured type with vga_getmousetype()). */
+    int mouse_init(char *dev, int type, int samplerate);
+/* Similar but returns the mouse fd if succesful. */
+    int mouse_init_return_fd(char *dev, int type, int samplerate);
+/* Set event handler invoked by mouse_update(). */
+#if 0 /* This is the actual definition */
+    typedef void (*__mouse_handler) (int button, int dx, int dy, int dz,
+                                     int drx, int dry, int drz);
+#else /* For backwards compatibility with:
+        typedef void (*__mouse_handler) (int button, int dx, int dy) we use: */
+    typedef void *__mouse_handler;
+#endif
+    void mouse_seteventhandler(__mouse_handler handler);
+/* Close mouse device. */
+    void mouse_close(void);
+/* Read mouse and handle events. Returns 0 if no event. */
+    int mouse_update(void);
+/* Similar to mouse_update, but wait for an event to happen. */
+    void mouse_waitforupdate(void);
+
+/* mouse_init sets default event handler that keeps track of absolute */
+/* coordinates: */
+
+#define MOUSE_NOWRAP 0
+#define MOUSE_WRAPX 1
+#define MOUSE_WRAPY 2
+#define MOUSE_WRAPZ 4
+#define MOUSE_WRAPRX 8
+#define MOUSE_WRAPRY 16
+#define MOUSE_WRAPRZ 32
+#define MOUSE_WRAP 63
+#define MOUSE_ROT_COORDS 196
+#define MOUSE_ROT_INFINITESIMAL 0 /* report changes in angle about axes */
+#define MOUSE_ROT_RX_RY_RZ 64     /* report angle about axes */
+
+/* Warning! Next two not yet supported! */
+#define MOUSE_ROT_ZXZ 128	  /* use x convention Euler angles */
+#define MOUSE_ROT_YPR 196	  /* use yaw, pitch, and roll */
+
+/* Revert to default handler. */
+    void mouse_setdefaulteventhandler(void);
+/* Set position of mouse. */
+    void mouse_setposition(int x, int y);
+/* Set position of mouse in all 6 dimensions. */
+    void mouse_setposition_6d(int x, int y, int z,
+                              int rx, int ry, int rz, int dim_mask);
+/* Set horizontal range of mouse to [x1, x2] incl. */
+    void mouse_setxrange(int x1, int x2);
+/* Set vertical range of mouse to [y1, y2] incl. */
+    void mouse_setyrange(int y1, int y2);
+/* Set all ranges of mouse in 6 dimensions. */
+    void mouse_setrange_6d(int x1, int x2, int y1, int y2, int z1, int z2,
+           int rx1, int rx2, int ry1, int ry2, int rz1, int rz2, int dim_mask);
+/* Set scale factor by which raw mouse coordinates are divided. */
+    void mouse_setscale(int s);
+/* Enable/disable wrapping of mouse in horizontal and/or vertical range. */
+    void mouse_setwrap(int w);
+
+/* Get current mouse x-coordinate. */
+    int mouse_getx(void);
+/* Get current mouse y-coordinate. */
+    int mouse_gety(void);
+/* Get position of mouse in all 6 dimensions. */
+    void mouse_getposition_6d(int *x, int *y, int *z,
+                              int *rx, int *ry, int *rz);
+/* Get current mouse button status. */
+    int mouse_getbutton(void);
+
+
+#define MOUSE_CAPS     1024
+#define MOUSE_WANTCAPS 0x002b0042
+#define MOUSE_GOTCAPS  0x0042ffd4
+
+#define MOUSE_INFO_WHEEL 0x00000001 /* The mouse has a wheel */
+
+    struct MouseCaps {
+        int key;       /* MOUSE_GOTCAPS */
+        int buttons;   /* MOUSE_*BUTTON */
+        int axes;      /* MOUSE_*DIM */
+        int info;      /* MOUSE_INFO_* */
+        int reserved0; /* Don't use these! */
+        int reserved1; /* The names may change in the future... */
+    };
+
+/* Use this function to get information about the mouse without depending on
+ mouse types known when your app was made. The weirdness is so that you
+ don't need to depend on having svgalib 1.3.0; as long as you don't depend
+ on other features your app should be able to work with older versions too,
+ just without this info... In a future version this will be made a real
+ function. Returns 0 on success or -1 on failure. */
+
+    static inline int mouse_getcaps(struct MouseCaps *caps)
+    {
+        mouse_setposition_6d(MOUSE_WANTCAPS,0,0, 0,0,0, MOUSE_CAPS);
+        mouse_getposition_6d(&(caps->key), &(caps->buttons), &(caps->axes),
+                             &(caps->info), &(caps->reserved0), &(caps->reserved1));
+        return ((caps->key == MOUSE_GOTCAPS) ? (0) : (-1));
+    }
+
+#ifdef __cplusplus
+}
+
+#endif
+#endif
diff --git a/haiku/window_haiku.cpp b/haiku/window_haiku.cpp
new file mode 100644
index 0000000..b6b17a5
--- /dev/null
+++ b/haiku/window_haiku.cpp
@@ -0,0 +1,1384 @@
+#include <Application.h>
+#include <Window.h>
+#include <View.h>
+#include <Rect.h>
+#include <Bitmap.h>
+#include <Clipboard.h>
+#include <Screen.h>
+#include <String.h>
+
+extern "C"
+{
+
+#include "../rdesktop.h"
+#include "window_haiku.h"
+
+#include "vga.h"
+#include "vgakeyboard.h"
+#include "vgamouse.h"
+#include "vgagl.h"
+
+extern void process_mouse(int);
+extern int g_sock;
+extern int deactivated;
+extern uint32 ext_disc_reason;
+extern RD_BOOL rdp_loop(RD_BOOL * deactivated, uint32 * ext_disc_reason);
+extern char *g_hostname;
+extern char *g_username;
+extern int g_width;// = 1024;
+extern int g_height;// = 768;
+extern int g_server_depth;// = 16;
+extern int g_encryption;// = 1;
+
+extern int g_xpos;
+extern int g_ypos;
+extern int g_pos;
+
+extern RD_BOOL g_sendmotion;
+extern RD_BOOL g_fullscreen;
+extern RD_BOOL g_grab_keyboard;
+extern RD_BOOL g_hide_decorations;
+extern RD_BOOL g_pending_resize;
+
+extern char g_title[];
+extern int g_server_bpp;
+extern int g_win_button_size;
+
+
+static sem_id block_sem = -1;
+
+/* SeamlessRDP support */
+typedef struct _seamless_group
+{
+	BWindow *wnd;
+	unsigned long id;
+	unsigned int refcnt;
+} seamless_group;
+
+typedef struct _seamless_window
+{
+//	Window wnd;
+	BWindow *wnd;
+	unsigned long id;
+	unsigned long behind;
+	seamless_group *group;
+	int xoffset, yoffset;
+	int width, height;
+	int state;		/* normal/minimized/maximized. */
+	unsigned int desktop;
+	struct timeval *position_timer;
+
+	RD_BOOL outstanding_position;
+	unsigned int outpos_serial;
+	int outpos_xoffset, outpos_yoffset;
+	int outpos_width, outpos_height;
+
+	struct _seamless_window *next;
+} seamless_window;
+
+static seamless_window *g_seamless_windows = NULL;
+static unsigned long g_seamless_focused = 0;
+static RD_BOOL g_seamless_started = False;	/* Server end is up and running */
+static RD_BOOL g_seamless_active = False;	/* We are currently in seamless mode */
+static RD_BOOL g_seamless_hidden = False;	/* Desktop is hidden on server */
+extern RD_BOOL g_seamless_rdp;
+
+//#include "info.h"
+////////////////////////////////////////////////////////////////////////////////
+int		WW=0;
+int		HH=0;
+int	CurCol=0;
+int		MouseX=0;
+int		MouseY=0;
+int		oldMouseX=0;
+int		oldMouseY=0;
+int		MouseB=0;
+int MouseEvent=0;
+int KeybEvent=0;
+thread_id MainThreadID;
+thread_id BAppThreadID;
+int		NeedUpdate=1;
+unsigned char   *BeBuffer=NULL;
+BView	*BeView=NULL;
+TWin	*BeWindow=NULL;
+BBitmap *BeBitmap=NULL;
+bool	BEWIN = true;
+
+
+
+struct col{
+unsigned short r,g,b;
+};
+
+col palette[256];
+
+void (*__svgalib_keyboard_eventhandler) (int, int);
+
+static const uint8 be_to_scan_codes[] = {
+SCANCODE_ESCAPE,   SCANCODE_F1, SCANCODE_F2, SCANCODE_F3, SCANCODE_F4, SCANCODE_F5,
+SCANCODE_F6, SCANCODE_F7, SCANCODE_F8, SCANCODE_F9, SCANCODE_F10, SCANCODE_F11, SCANCODE_F12,SCANCODE_PRINTSCREEN,SCANCODE_SCROLLLOCK,0,
+//////////
+SCANCODE_GRAVE,SCANCODE_1,SCANCODE_2,SCANCODE_3,SCANCODE_4,SCANCODE_5,SCANCODE_6,SCANCODE_7,SCANCODE_8,
+SCANCODE_9,SCANCODE_0,SCANCODE_MINUS,SCANCODE_EQUAL,SCANCODE_BACKSPACE,SCANCODE_INSERT,
+SCANCODE_HOME,SCANCODE_PAGEUP,SCANCODE_NUMLOCK,SCANCODE_KEYPADDIVIDE,SCANCODE_KEYPADMULTIPLY,SCANCODE_KEYPADMINUS,
+//////////
+SCANCODE_TAB,SCANCODE_Q,SCANCODE_W,SCANCODE_E,SCANCODE_R,SCANCODE_T,SCANCODE_Y,SCANCODE_U,SCANCODE_I,
+SCANCODE_O,SCANCODE_P,SCANCODE_BRACKET_LEFT,SCANCODE_BRACKET_RIGHT,SCANCODE_BACKSLASH,SCANCODE_REMOVE,SCANCODE_END,SCANCODE_PAGEDOWN,
+SCANCODE_KEYPAD7,SCANCODE_KEYPAD8,SCANCODE_KEYPAD9,SCANCODE_KEYPADPLUS,
+//////////
+SCANCODE_CAPSLOCK,SCANCODE_A,SCANCODE_S,SCANCODE_D,SCANCODE_F,SCANCODE_G,SCANCODE_H,SCANCODE_J,SCANCODE_K,SCANCODE_L,SCANCODE_SEMICOLON,SCANCODE_APOSTROPHE,SCANCODE_ENTER,
+SCANCODE_KEYPAD4,SCANCODE_KEYPAD5,SCANCODE_KEYPAD6,
+//////////
+SCANCODE_LEFTSHIFT,SCANCODE_Z,SCANCODE_X,SCANCODE_C,SCANCODE_V,SCANCODE_B,SCANCODE_N,SCANCODE_M,SCANCODE_COMMA,SCANCODE_PERIOD,SCANCODE_SLASH,
+SCANCODE_RIGHTSHIFT,SCANCODE_CURSORBLOCKUP,SCANCODE_KEYPAD1,SCANCODE_KEYPAD2,SCANCODE_KEYPAD3,SCANCODE_KEYPADENTER,
+//////////
+SCANCODE_LEFTCONTROL,SCANCODE_LEFTALT,SCANCODE_SPACE,SCANCODE_RIGHTALT,SCANCODE_RIGHTCONTROL,SCANCODE_CURSORBLOCKLEFT,SCANCODE_CURSORBLOCKDOWN,SCANCODE_CURSORBLOCKRIGHT,SCANCODE_KEYPAD0,SCANCODE_KEYPADPERIOD,
+SCANCODE_LEFTWIN,SCANCODE_RIGHTWIN,127,0
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
+static seamless_window *
+sw_get_window_by_id(unsigned long id)
+{
+	seamless_window *sw;
+	for (sw = g_seamless_windows; sw; sw = sw->next)
+	{
+		if (sw->id == id)
+			return sw;
+	}
+	return NULL;
+}
+
+
+static seamless_window *
+sw_get_window_by_wnd(BWindow *wnd)
+{
+	seamless_window *sw;
+	for (sw = g_seamless_windows; sw; sw = sw->next)
+	{
+		if (sw->wnd == wnd)
+			return sw;
+	}
+	return NULL;
+}
+
+static void
+sw_remove_window(seamless_window * win)
+{
+	seamless_window *sw, **prevnext = &g_seamless_windows;
+	for (sw = g_seamless_windows; sw; sw = sw->next)
+	{
+		if (sw == win)
+		{
+			*prevnext = sw->next;
+			sw->group->refcnt--;
+			if (sw->group->refcnt == 0)
+			{
+				if(sw->group->wnd!=NULL)
+					{
+						sw->group->wnd->Hide();
+						sw->group->wnd->PostMessage('QUIT');
+					}
+				xfree(sw->group);
+			}
+			xfree(sw->position_timer);
+			xfree(sw);
+			return;
+		}
+		prevnext = &sw->next;
+	}
+	return;
+}
+
+
+/* Move all windows except wnd to new desktop */
+static void
+sw_all_to_desktop(BWindow *wnd, unsigned int desktop)
+{
+	seamless_window *sw;
+	for (sw = g_seamless_windows; sw; sw = sw->next)
+	{
+		if (sw->wnd == wnd)
+			continue;
+		if (sw->desktop != desktop)
+		{
+//			ewmh_move_to_desktop(sw->wnd, desktop);
+//			sw->desktop = desktop;
+		}
+	}
+}
+
+/* Send our position */
+static void
+sw_update_position(seamless_window * sw)
+{
+	int x, y, w, h;
+	unsigned int serial;
+	
+	x=(int)sw->wnd->Frame().left;
+	y=(int)sw->wnd->Frame().top;
+	w=(int)sw->wnd->Bounds().Width();
+	h=(int)sw->wnd->Bounds().Height();
+	
+	serial = seamless_send_position(sw->id, x, y, w, h, 0);
+
+	sw->outstanding_position = True;
+	sw->outpos_serial = serial;
+
+	sw->outpos_xoffset = x;
+	sw->outpos_yoffset = y;
+	sw->outpos_width = w;
+	sw->outpos_height = h;
+}
+
+/* Check if it's time to send our position */
+static void
+sw_check_timers()
+{
+	seamless_window *sw;
+	struct timeval now;
+
+	gettimeofday(&now, NULL);
+	for (sw = g_seamless_windows; sw; sw = sw->next)
+	{
+		if (timerisset(sw->position_timer) && timercmp(sw->position_timer, &now, <))
+		{
+			timerclear(sw->position_timer);
+			sw_update_position(sw);
+		}
+	}
+}
+
+static void
+sw_restack_window(seamless_window * sw, unsigned long behind)
+{
+	seamless_window *sw_above;
+
+	/* Remove window from stack */
+	for (sw_above = g_seamless_windows; sw_above; sw_above = sw_above->next)
+	{
+		if (sw_above->behind == sw->id)
+			break;
+	}
+
+	if (sw_above)
+		sw_above->behind = sw->behind;
+
+	/* And then add it at the new position */
+	for (sw_above = g_seamless_windows; sw_above; sw_above = sw_above->next)
+	{
+		if (sw_above->behind == behind)
+			break;
+	}
+
+	if (sw_above)
+		sw_above->behind = sw->id;
+
+	sw->behind = behind;
+}
+
+
+static seamless_group *
+sw_find_group(unsigned long id, RD_BOOL dont_create)
+{
+	seamless_window *sw;
+	seamless_group *sg;
+
+	for (sw = g_seamless_windows; sw; sw = sw->next)
+	{
+		if (sw->group->id == id)
+			return sw->group;
+	}
+
+	if (dont_create)
+		return NULL;
+
+	sg = (seamless_group*)malloc(sizeof(seamless_group));
+
+	sg->wnd = NULL;
+
+	sg->id = id;
+	sg->refcnt = 0;
+
+	return sg;
+}
+
+/////////////////////////////////////////////////////////////////////////////////
+
+
+int32 lister(void *data)
+{
+  IterView *obj=(IterView*)data;
+  seamless_window *sw;
+  struct timeval now;
+  
+	for(;;)
+	{
+		if(NeedUpdate==1)
+		 {
+		  NeedUpdate=0;
+
+		  if(!g_seamless_rdp)
+		  		obj->MyDraw();	
+		  else {	
+					for (sw = g_seamless_windows; sw; sw = sw->next)
+					{
+						//gettimeofday(&now, NULL);		  	  		  		  	  
+						//if (!timerisset(sw->position_timer))
+				 		SeamWin *win = (SeamWin*)sw->wnd;
+						if(win->Frame().left==sw->xoffset && win->Frame().top==sw->yoffset)
+						{
+							win->view->MyDraw(win->Bounds());
+						}
+					}					
+		  }
+		  
+		 }
+	  if (g_seamless_active)
+			sw_check_timers();		  
+		snooze(1000000/18);
+	}
+}
+
+
+
+
+
+SeamView::SeamView(BRect R) : BView(R, "seamview", B_FOLLOW_ALL, B_WILL_DRAW)
+{
+	SetViewColor(B_TRANSPARENT_COLOR);
+	SetDrawingMode(B_OP_COPY); 	
+}
+
+SeamView::~SeamView()
+{
+	
+}
+
+
+void SeamView::MouseMoved(BPoint p, uint32 transit,const BMessage *message)
+{
+	int _MouseX=(int)(p.x+Window()->Frame().left);
+	int _MouseY=(int)(p.y+Window()->Frame().top);
+		
+	MouseX=_MouseX;
+	MouseY=_MouseY;
+	MouseEvent=1;
+	process_mouse(0);
+}
+
+void SeamView::MouseDown(BPoint p)
+{
+	uint32 buttons = Window()->CurrentMessage()->FindInt32("buttons");
+	int butt=0;
+	
+	if (buttons & B_PRIMARY_MOUSE_BUTTON)
+			butt |= 4;
+	if (buttons & B_SECONDARY_MOUSE_BUTTON)
+			butt |= 1;
+	if (buttons & B_TERTIARY_MOUSE_BUTTON)
+			butt |= 2;
+
+			
+	MouseB=butt;	
+	process_mouse(0);
+
+//	Window()->Activate(true);
+	SetMouseEventMask(B_POINTER_EVENTS,0);
+}
+
+void SeamView::MouseUp(BPoint p)
+{
+	MouseB=0;
+	process_mouse(0);
+
+}
+
+void
+SeamView::Draw(BRect r)
+{
+ MyDraw(r);
+}
+
+void
+SeamView::MyDraw(BRect r)
+{
+  bool s=LockLooper();
+  if(s==true)
+	{
+	 BRect from=r;	 
+	 from.OffsetBy(Window()->Frame().left,Window()->Frame().top);
+ 	 DrawBitmap(BeBitmap,from,r);
+	 UnlockLooper();
+	}	
+
+}
+
+SeamWin::SeamWin(int x,int y, int w,int h,window_look look,int _id,int _group)
+	: BWindow(BRect(x, y, x+w-1, y+h-1), g_title, look,B_NORMAL_WINDOW_FEEL, B_WILL_ACCEPT_FIRST_CLICK|B_OUTLINE_RESIZE)
+{
+	id=_id;
+	group=_group;
+	
+	view = new SeamView(Bounds());
+	
+	AddChild(view);
+	be_clipboard->StartWatching(this);	
+}
+
+SeamWin::~SeamWin()
+{
+//	RemoveChild(view);
+//	delete view;
+ 	be_clipboard->StopWatching(this);
+}
+
+
+void SeamWin::MessageReceived(BMessage *message)
+{
+	switch(message->what) {
+		case 'QUIT':
+		{
+			Quit();
+			break;
+		}	
+		case B_UNMAPPED_KEY_DOWN:
+		case B_KEY_DOWN:
+		{
+			const char *bytes;
+			int32 key;
+			message->FindInt32("key",&key);
+			if (key < sizeof(be_to_scan_codes))
+			{
+			 // printf("B_KEY_DOWN %d\n",key);
+			  key = be_to_scan_codes[(uint8)key-1];
+			  __svgalib_keyboard_eventhandler(key, KEY_EVENTPRESS);
+			}
+			break;
+		}
+		case B_UNMAPPED_KEY_UP:
+		case B_KEY_UP:
+		{
+			const char *bytes;
+			int32 key;
+			message->FindInt32("key",&key);
+			if (key < sizeof(be_to_scan_codes))
+			{
+			  key = be_to_scan_codes[(uint8)key-1];			
+		 	  __svgalib_keyboard_eventhandler(key, KEY_EVENTRELEASE);
+		 	}
+			 break;
+		} 
+		case B_MOUSE_WHEEL_CHANGED:
+			{
+			 float shift=0;
+			 if(message->FindFloat("be:wheel_delta_y",&shift)==B_OK)
+			 {
+		        if(shift<0)
+		        {
+		         rdp_send_input(0, RDP_INPUT_MOUSE, MOUSE_FLAG_DOWN | MOUSE_FLAG_BUTTON4, MouseX,MouseY);
+		        }
+				if(shift>0)
+				{
+		         rdp_send_input(0, RDP_INPUT_MOUSE, MOUSE_FLAG_DOWN | MOUSE_FLAG_BUTTON5, MouseX,MouseY);
+		        }
+			 }			 
+			 break;
+			}		
+		case B_CLIPBOARD_CHANGED:
+			{
+			 ui_clip_request_data(CF_TEXT);
+			 break;
+			}
+		case 'SCCH':
+			{
+			 snooze(200000);
+			 cliprdr_send_data_request(CF_TEXT);
+			 break;
+			}
+		case B_WINDOW_ACTIVATED:
+		case B_WORKSPACE_ACTIVATED:
+			{
+			 NeedUpdate = 1;
+//			 release_sem(loop_sem); 		  
+			 break;
+			}
+		default:
+			BWindow::MessageReceived(message);
+			break;		
+	}
+}
+
+void 
+SeamWin::WindowActivated(bool f)
+{
+	printf("WindowActivated - %d,%d\n",id,f);
+	seamless_window *sw;
+	sw = sw_get_window_by_id(id);
+	if (!sw)return;
+
+/*	if(f==1)
+	{	
+		seamless_send_state(sw->id, SEAMLESSRDP_NORMAL, 0);		
+		if(Look()==B_TITLED_WINDOW_LOOK)
+		{
+			MouseX=sw->xoffset+sw->width/2;
+			MouseY=sw->yoffset+10;
+			MouseB=4;			
+			process_mouse(0);	
+			MouseB=0;			
+			process_mouse(0);	
+		}
+	}
+	else
+	{
+		//seamless_send_state(sw->id, SEAMLESSRDP_NORMAL, 0);			
+	}*/
+}
+
+void 
+SeamWin::FrameResized(float width, float height)
+{
+	//seamless_send_position(id, Frame().left, Frame().top, width, height, 0);
+	seamless_window *sw;
+	
+	if (!g_seamless_active)
+		return;
+
+	sw = sw_get_window_by_id(id);
+	if (!sw)
+		return;
+
+	gettimeofday(sw->position_timer, NULL);
+	if (sw->position_timer->tv_usec + SEAMLESSRDP_POSITION_TIMER >= 1000000) {
+		sw->position_timer->tv_usec += SEAMLESSRDP_POSITION_TIMER - 1000000;
+		sw->position_timer->tv_sec += 1;
+	} else {
+		sw->position_timer->tv_usec += SEAMLESSRDP_POSITION_TIMER;
+	}	
+}
+
+void
+SeamWin::FrameMoved(BPoint p)
+{
+	seamless_window *sw;
+	
+	if (!g_seamless_active)
+		return;
+
+	sw = sw_get_window_by_id(id);
+	if (!sw)
+		return;
+
+	gettimeofday(sw->position_timer, NULL);
+	if (sw->position_timer->tv_usec + SEAMLESSRDP_POSITION_TIMER >= 1000000) {
+		sw->position_timer->tv_usec += SEAMLESSRDP_POSITION_TIMER - 1000000;
+		sw->position_timer->tv_sec += 1;
+	} else {
+		sw->position_timer->tv_usec += SEAMLESSRDP_POSITION_TIMER;
+	}
+
+	//sw_handle_restack(sw);
+}
+
+
+
+
+bool
+SeamWin::QuitRequested()
+{    
+	return true;
+}
+
+TWin::TWin(int x,int y, int w,int h,window_look look)
+	: BWindow(BRect(x, y, x+w-1, y+h-1), g_title, look,B_NORMAL_WINDOW_FEEL, 0)//B_NOT_RESIZABLE|B_NOT_ZOOMABLE
+{
+	WW=w;
+	HH=h;
+	view = new IterView(BRect(0,0,w-1,h-1));
+	AddChild(view);
+	view->SetViewColor(0,0,0);
+	be_clipboard->StartWatching(this);
+	block_sem = create_sem(1, "blocker");
+}
+
+TWin::~TWin()
+{
+ 	be_clipboard->StopWatching(this);
+}
+
+void TWin::MessageReceived(BMessage *message)
+{
+	switch(message->what) {
+		case B_UNMAPPED_KEY_DOWN:
+		case B_KEY_DOWN:
+		{
+			const char *bytes;
+			int32 key;
+			message->FindInt32("key",&key);
+			if (key < sizeof(be_to_scan_codes))
+			{
+			 // printf("B_KEY_DOWN %d\n",key);
+			  key = be_to_scan_codes[(uint8)key-1];
+			  __svgalib_keyboard_eventhandler(key, KEY_EVENTPRESS);
+			}
+			break;
+		}
+		case B_UNMAPPED_KEY_UP:
+		case B_KEY_UP:
+		{
+			const char *bytes;
+			int32 key;
+			message->FindInt32("key",&key);
+			if (key < sizeof(be_to_scan_codes))
+			{
+			  key = be_to_scan_codes[(uint8)key-1];			
+		 	  __svgalib_keyboard_eventhandler(key, KEY_EVENTRELEASE);
+		 	}
+			 break;
+		} 
+		case B_MOUSE_WHEEL_CHANGED:
+			{
+			 float shift=0;
+			 if(message->FindFloat("be:wheel_delta_y",&shift)==B_OK)
+			 {
+		        if(shift<0)
+		        {
+		         rdp_send_input(0, RDP_INPUT_MOUSE, MOUSE_FLAG_DOWN | MOUSE_FLAG_BUTTON4, MouseX,MouseY);
+		        }
+				if(shift>0)
+				{
+		         rdp_send_input(0, RDP_INPUT_MOUSE, MOUSE_FLAG_DOWN | MOUSE_FLAG_BUTTON5, MouseX,MouseY);
+		        }
+			 }			 
+			 break;
+			}		
+		case B_CLIPBOARD_CHANGED:
+			{
+			 ui_clip_request_data(CF_TEXT);
+			 break;
+			}
+		case 'SCCH':
+			{
+			 snooze(200000);
+			 cliprdr_send_data_request(CF_TEXT);
+			 break;
+			}
+		case B_WINDOW_ACTIVATED:
+		case B_WORKSPACE_ACTIVATED:
+			{
+			 NeedUpdate=1;
+			 break;
+			}
+		default:
+			BWindow::MessageReceived(message);
+			break;		
+	}
+}
+
+void 
+TWin::FrameResized(float width, float height)
+{
+	NeedUpdate=1;
+//	g_pending_resize = True;
+//	snooze(10000);
+//	g_height = height;
+//	g_width = width;
+}
+
+
+
+bool
+TWin::QuitRequested()
+{    
+   	kill_thread(find_thread("rdpgui"));
+	be_app->PostMessage(B_QUIT_REQUESTED);
+	exit(0);
+	return true;
+}
+
+IterView::IterView(BRect R) : BView(R, "iterview", B_FOLLOW_ALL, B_WILL_DRAW)
+{
+	SetViewColor(255,255,255);
+	bufferView=new BView(R,"bufferview",B_FOLLOW_ALL_SIDES,B_WILL_DRAW);
+    buffer=new BBitmap(R,B_RGB16,true);
+
+	buffer->AddChild(bufferView);
+	
+	ScrBuff=(unsigned char*)buffer->Bits();
+	BeBuffer=ScrBuff;
+	BeView=bufferView;
+	BeBitmap = buffer;
+		
+ 	my_thread = spawn_thread(lister,"rdpgui",1,(void*)this);
+	resume_thread(my_thread);
+	
+	SetDrawingMode(B_OP_COPY); 	
+}
+
+IterView::~IterView()
+{
+	
+}
+
+
+void IterView::MouseMoved(BPoint p, uint32 transit,const BMessage *message)
+{
+	MouseX=(int)p.x * buffer->Bounds().Width() / Bounds().Width();
+	MouseY=(int)p.y * buffer->Bounds().Height() / Bounds().Height();
+	
+	//if(transit==B_ENTERED_VIEW)be_app->HideCursor();
+	//if((transit==B_EXITED_VIEW || transit==B_OUTSIDE_VIEW))be_app->ShowCursor();
+	process_mouse(0);
+	MouseEvent=1;
+}
+
+void IterView::MouseDown(BPoint p)
+{
+	uint32 buttons = Window()->CurrentMessage()->FindInt32("buttons");
+	int butt=0;
+	
+	if (buttons & B_PRIMARY_MOUSE_BUTTON)
+			butt |= 4;
+	if (buttons & B_SECONDARY_MOUSE_BUTTON)
+			butt |= 1;
+	if (buttons & B_TERTIARY_MOUSE_BUTTON)
+			butt |= 2;
+			
+	MouseB=butt;
+	
+	process_mouse(0);
+
+}
+
+void IterView::MouseUp(BPoint p)
+{
+	uint32 buttons = Window()->CurrentMessage()->FindInt32("buttons");
+	int butt=0;
+
+	if ((buttons ^ MouseB) & B_PRIMARY_MOUSE_BUTTON)
+			butt |= 4;
+		if ((buttons ^ MouseB) & B_SECONDARY_MOUSE_BUTTON)
+			butt |= 1;
+		if ((buttons ^ MouseB) & B_TERTIARY_MOUSE_BUTTON)
+			butt |= 2;
+	MouseB=0;
+	process_mouse(0);
+}
+
+void
+IterView::Draw(BRect r)
+{
+ MyDraw();
+}
+
+void
+IterView::MyDraw(void)
+{
+  bool s=LockLooper();
+  if(s==true)
+	{
+ 	 bufferView->LockLooper();
+ 	 DrawBitmap(buffer, buffer->Bounds(), Bounds(), B_FILTER_BITMAP_BILINEAR);
+	 bufferView->UnlockLooper();
+	 UnlockLooper();
+	}	
+
+}
+
+
+///////////////////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////////
+
+
+void vga_resize_window(int w,int h)
+{
+	//BeWindow->ResizeTo(w,h);
+}
+
+int beapp_init(void)
+ {
+  BApplication *app;
+  if(be_app==NULL)app=new BApplication("application/x-vnd.Be-RDesktop");
+  }
+
+ int vga_init(void)
+ {
+  xclip_init();
+  return 0;
+ }
+ 
+ int vga_getpixel(int x, int y)
+ {
+  // printf("vga_getpixel (%d,%d)\n",x,y);
+   return 0;
+ }
+ 
+ int vga_setcolor(int color)
+ {
+  CurCol=color;
+  return 0;
+ }
+ 
+ int vga_drawpixel(int x, int y)
+ {
+//  BeBuffer[y*WW+x]=CurCol;
+  NeedUpdate=1;
+  return 0;
+ }
+ 
+ 
+int vga_accel(unsigned operation,...)
+{
+    return 0;
+}
+ 
+ int vga_drawscansegment(unsigned char *colors, int x, int y, int length)
+ {  
+    if(x<0 || y<0)return 0;
+    if(g_server_bpp==16)memcpy((unsigned char*)BeBuffer+(y*WW*2)+(x*2),colors,length);
+    if(g_server_bpp==8)
+    {
+     unsigned char* p=(unsigned char*)BeBuffer+(y*WW*2)+(x*2);
+     unsigned short *s=(unsigned short*)p;
+     for(int i=0;i<length;i++)
+      {
+       col c=palette[ colors[i]];
+       s[i]=( (c.b>>1) & 31) | ((c.g&63)<<5) | (((c.r>>1)&31)<<11);
+      }
+    }
+    NeedUpdate=1;
+    return 0;
+ }
+
+ 
+ int vga_getscansegment(unsigned char *colors, int x, int y, int length)
+ {
+    return 0;
+ }
+ 
+ int mouse_getx(void)
+ {
+    return MouseX;
+ }
+
+ int mouse_gety(void)
+ {
+    return MouseY;
+ }
+ 
+ int vga_getscreen_width(void)
+ {
+  BScreen *Screen=new BScreen(B_MAIN_SCREEN_ID);
+  int w=(int)(Screen->Frame().Width()+1);
+  delete Screen;	   
+  return w;
+ }
+
+ int vga_getscreen_height(void)
+ {
+  BScreen *Screen=new BScreen(B_MAIN_SCREEN_ID);
+  int w=(int)(Screen->Frame().Height()+1);
+  delete Screen;	   
+  return w;
+ }
+ 
+ int vga_setmode_be(int xdim,int ydim,int colors,int full)
+ {
+  if(xdim==0 || ydim==0 || colors==0)
+   {   	
+    NeedUpdate=0;
+    snooze(100000);
+    kill_thread(find_thread("rdpgui"));
+    if(BeWindow != NULL) {
+    	BeWindow->Lock();
+    	BeWindow->Quit();
+    	BeWindow = NULL;
+    }
+	return 0;
+   }
+ 
+  if(BeWindow!=NULL)
+   {
+    BeWindow->Lock();
+    BeWindow->Quit();
+   }
+
+   BeWindow=new TWin(100,100,xdim,ydim,B_TITLED_WINDOW_LOOK);
+   
+   if(full)
+    {
+	   BScreen *Screen=new BScreen(B_MAIN_SCREEN_ID);
+   	   BeWindow->LockLooper();
+	   BPoint viewRect=BeWindow->view->ConvertToScreen(BPoint(0,0));	
+	   BPoint winRect=BPoint(BeWindow->Frame().left,BeWindow->Frame().top);			   
+	   BeWindow->MoveTo(winRect-viewRect);
+ 	   BeWindow->UnlockLooper(); 
+	   delete Screen;	   
+    }    	   
+  if(!g_seamless_rdp)
+   	BeWindow->Show();
+
+  return 0;
+ }
+
+ 
+ int vga_hasmode(int mode)
+ {
+   return true;
+ }
+ 
+ void vga_setmousesupport(int s)
+ {
+ }
+ 
+ void mouse_setposition(int x, int y)
+ {
+ }
+
+ int keyboard_init(void)
+ {
+  return 0;
+ }
+
+ void keyboard_close(void)
+ {
+ }
+
+ void keyboard_seteventhandler(void (*handler) (int, int))
+ { 
+   __svgalib_keyboard_eventhandler = handler;
+ }
+ 
+ void keyboard_translatekeys(int mode)
+ {
+ }
+ 
+ int vga_ext_set(unsigned what,...)
+{
+  return 0;
+}
+
+ int mouse_getbutton()
+ {
+   return MouseB;
+ }
+ 
+ int vga_waitevent(int which, fd_set * in, fd_set * out, fd_set * except,
+		  struct timeval *timeout)
+ {
+  return 0;
+ }
+ 
+ int vga_setpalvec(int start, int num, int *pal)
+ {
+  int i;
+
+  for (i = start; i < start + num; ++i)
+  {
+	palette[i].r=pal[0] , palette[i].g=pal[1] , palette[i].b=pal[2] ;
+	pal += 3;
+  }
+  return num;
+ }
+ 
+
+/*****************************************************************************/
+
+/*****************************************************************************/
+int ui_select(int in)
+{
+  g_sock = in; 
+
+  return 1;
+}
+
+
+
+void
+ui_seamless_begin(RD_BOOL hidden)
+{
+	if (!g_seamless_rdp)
+		return;
+
+	if (g_seamless_started)
+		return;
+
+	g_seamless_started = True;
+	g_seamless_hidden = hidden;
+
+	if (!hidden)
+		ui_seamless_toggle();
+}
+
+
+void
+ui_seamless_hide_desktop()
+{
+	if (!g_seamless_rdp)
+		return;
+
+	if (!g_seamless_started)
+		return;
+
+	if (g_seamless_active)
+		ui_seamless_toggle();
+
+	g_seamless_hidden = True;
+}
+
+
+void
+ui_seamless_unhide_desktop()
+{
+	if (!g_seamless_rdp)
+		return;
+
+	if (!g_seamless_started)
+		return;
+
+	g_seamless_hidden = False;
+
+	ui_seamless_toggle();
+}
+
+
+void
+ui_seamless_toggle()
+{
+	if (!g_seamless_rdp)
+		return;
+
+	if (!g_seamless_started)
+		return;
+
+	if (g_seamless_hidden)
+		return;
+
+	if (g_seamless_active)
+	{
+		/* Deactivate */
+		while (g_seamless_windows)
+		{
+//			XDestroyWindow(g_display, g_seamless_windows->wnd);
+//			sw_remove_window(g_seamless_windows);
+		}
+//		XMapWindow(g_display, g_wnd);
+	}
+	else
+	{
+		/* Activate */
+//		XUnmapWindow(g_display, g_wnd);
+		seamless_send_sync();
+	}
+
+	g_seamless_active = !g_seamless_active;
+}
+
+
+void
+ui_seamless_create_window(unsigned long id, unsigned long group, unsigned long parent,
+			  unsigned long flags)
+{
+	SeamWin *wnd=NULL;
+	seamless_window *sw, *sw_parent;
+
+	if (!g_seamless_active)
+		return;
+
+	printf("ui_seamless_create_window id=%d, grp=%d, parent=%d, flags=0x%lx\n",id, group, parent, flags);
+
+	// Ignore CREATEs for existing windows 
+	sw = sw_get_window_by_id(id);
+	if (sw)
+		return;
+		
+	wnd = new SeamWin(-100,-100,80,20, B_NO_BORDER_WINDOW_LOOK, id, group);
+	
+	// Parent-less transient windows 
+	if (parent == 0xFFFFFFFF)
+	{
+		wnd->SetLook(B_NO_BORDER_WINDOW_LOOK);
+	}
+	// Normal transient windows 
+	else if (parent != 0x00000000)
+	{
+		sw_parent = sw_get_window_by_id(parent);
+		if (sw_parent)
+				wnd->SetLook(B_NO_BORDER_WINDOW_LOOK);
+		else
+			warning("ui_seamless_create_window: No parent window 0x%lx\n", parent);
+	}
+
+	if (flags & SEAMLESSRDP_CREATE_MODAL)
+	{
+		wnd->SetLook(B_MODAL_WINDOW_LOOK);
+		wnd->SetFeel(B_MODAL_APP_WINDOW_FEEL);
+		wnd->SetFlags(B_NOT_RESIZABLE|B_NOT_MINIMIZABLE|B_NOT_ZOOMABLE);
+	}
+	
+	wnd->Show();
+
+	sw = (seamless_window*)malloc(sizeof(seamless_window));
+	sw->wnd = wnd;
+	sw->id = id;
+	sw->behind = 0;
+	sw->group = sw_find_group(group, False);
+	sw->group->refcnt++;
+	sw->xoffset = 0;
+	sw->yoffset = 0;
+	sw->width = 0;
+	sw->height = 0;
+	sw->state = SEAMLESSRDP_NOTYETMAPPED;
+	sw->desktop = 0;
+	sw->position_timer = (timeval*)malloc(sizeof(struct timeval));
+	timerclear(sw->position_timer);
+
+	sw->outstanding_position = False;
+	sw->outpos_serial = 0;
+	sw->outpos_xoffset = sw->outpos_yoffset = 0;
+	sw->outpos_width = sw->outpos_height = 0;
+
+	sw->next = g_seamless_windows;
+	g_seamless_windows = sw;
+}
+
+
+void
+ui_seamless_destroy_window(unsigned long id, unsigned long flags)
+{
+	seamless_window *sw;
+
+	if (!g_seamless_active)
+		return;
+
+	printf("ui_seamless_destroy_window - %d beg\n",id);
+
+	sw = sw_get_window_by_id(id);
+	if (!sw)
+	{
+		warning("ui_seamless_destroy_window: No information for window 0x%lx\n", id);
+		return;
+	}
+
+	sw->wnd->Hide();
+	sw->wnd->PostMessage('QUIT');
+	sw_remove_window(sw);
+}
+
+
+void
+ui_seamless_destroy_group(unsigned long id, unsigned long flags)
+{
+	seamless_window *sw, *sw_next;
+
+	if (!g_seamless_active)
+		return;
+
+	printf("ui_seamless_destroy_group group=%d, flags=0x%lx\n",id, flags);
+
+	for (sw = g_seamless_windows; sw; sw = sw_next)
+	{
+		sw_next = sw->next;
+
+		if (sw->group->id == id)
+		{
+			sw->wnd->Hide();
+			sw->wnd->PostMessage('QUIT');
+			sw_remove_window(sw);
+		}
+	}	
+}
+
+
+void
+ui_seamless_move_window(unsigned long id, int x, int y, int width, int height, unsigned long flags)
+{
+	seamless_window *sw;
+
+	if (!g_seamless_active)
+		return;
+
+	sw = sw_get_window_by_id(id);
+	if (!sw)
+	{
+		warning("ui_seamless_move_window: No information for window 0x%lx\n", id);
+		return;
+	}
+
+	/* We ignore server updates until it has handled our request. */
+	if (sw->outstanding_position)
+		return;
+
+	if (!width || !height)
+		/* X11 windows must be at least 1x1 */
+		return;
+
+	sw->xoffset = x;
+	sw->yoffset = y;
+	sw->width = width;
+	sw->height = height;
+
+	/* If we move the window in a maximized state, then KDE won't
+	   accept restoration */
+	switch (sw->state)
+	{
+		case SEAMLESSRDP_MINIMIZED:
+		case SEAMLESSRDP_MAXIMIZED:
+			return;
+	}
+	
+	sw->wnd->MoveTo(x,y);
+	sw->wnd->ResizeTo(width,height);
+}
+
+
+void
+ui_seamless_restack_window(unsigned long id, unsigned long behind, unsigned long flags)
+{
+	seamless_window *sw;
+
+	if (!g_seamless_active)
+		return;
+
+	sw = sw_get_window_by_id(id);
+	if (!sw)
+	{
+		warning("ui_seamless_restack_window: No information for window 0x%lx\n", id);
+		return;
+	}
+
+	if (behind)
+	{
+		seamless_window *sw_behind;
+		BWindow *wnds[2];
+
+		sw_behind = sw_get_window_by_id(behind);
+		if (!sw_behind)
+		{
+			warning("ui_seamless_restack_window: No information for window 0x%lx\n",
+				behind);
+			return;
+		}
+
+		wnds[1] = sw_behind->wnd;
+		wnds[0] = sw->wnd;
+
+//		sw->wnd->Activate(true);
+	}
+	else
+	{
+//		sw->wnd->Activate(false);
+	}
+
+	sw_restack_window(sw, behind);
+}
+
+
+void
+ui_seamless_settitle(unsigned long id, const char *title, unsigned long flags)
+{
+	seamless_window *sw;
+
+	if (!g_seamless_active)
+		return;
+
+	sw = sw_get_window_by_id(id);
+	if (!sw)
+	{
+		warning("ui_seamless_settitle: No information for window 0x%lx\n", id);
+		return;
+	}
+	
+	sw->wnd->SetTitle(title);
+}
+
+
+void
+ui_seamless_setstate(unsigned long id, unsigned int state, unsigned long flags)
+{
+	seamless_window *sw;
+
+	if (!g_seamless_active)
+		return;
+
+	sw = sw_get_window_by_id(id);
+	if (!sw)
+	{
+		warning("ui_seamless_setstate: No information for window 0x%lx\n", id);
+		return;
+	}
+
+	switch (state)
+	{
+		case SEAMLESSRDP_NORMAL:
+		case SEAMLESSRDP_MAXIMIZED:
+			sw->wnd->Activate(true);
+			break;
+		case SEAMLESSRDP_MINIMIZED:
+			sw->wnd->Minimize(true);
+			break;
+		default:
+			warning("SeamlessRDP: Invalid state %d\n", state);
+			break;
+	}
+	
+	sw->state = state;
+}
+
+
+void
+ui_seamless_syncbegin(unsigned long flags)
+{
+	if (!g_seamless_active)
+		return;
+		
+	printf("ui_seamless_syncbegin\n");
+
+	// Destroy all seamless windows 
+	while (g_seamless_windows)
+	{
+		g_seamless_windows->wnd->Hide();
+		g_seamless_windows->wnd->PostMessage('QUIT');
+		sw_remove_window(g_seamless_windows);
+	}
+}
+
+
+void
+ui_seamless_ack(unsigned int serial)
+{
+	seamless_window *sw;
+	for (sw = g_seamless_windows; sw; sw = sw->next)
+	{
+		if (sw->outstanding_position && (sw->outpos_serial == serial))
+		{
+			sw->xoffset = sw->outpos_xoffset;
+			sw->yoffset = sw->outpos_yoffset;
+			sw->width = sw->outpos_width;
+			sw->height = sw->outpos_height;
+			sw->outstanding_position = False;
+
+			//((SeamWin*)(sw->wnd))->view->MyDraw(BRect(0, 0, sw->width, sw->height));
+			break;
+		}
+	}
+}
+ 
+
+void
+ui_seamless_seticon(unsigned long id, const char *format, int width, int height, int chunk,
+		    const char *data, int chunk_len)
+{
+}
+
+
+void
+ui_seamless_delicon(unsigned long id, const char *format, int width, int height)
+{
+
+}
+
+
+}
diff --git a/haiku/window_haiku.h b/haiku/window_haiku.h
new file mode 100644
index 0000000..16b2f35
--- /dev/null
+++ b/haiku/window_haiku.h
@@ -0,0 +1,68 @@
+#include <Application.h>
+#include <Window.h>
+#include <View.h>
+#include <Rect.h>
+#include <Bitmap.h>
+#include <Clipboard.h>
+
+class IterView : public BView
+{
+ public:
+					IterView(BRect R);
+					~IterView();
+	void			MyDraw(void);
+				
+	BBitmap 		*buffer;	
+    BView 	 		*bufferView;
+    
+    unsigned char	*ScrBuff;
+    
+    thread_id 		my_thread;
+
+protected:
+	virtual void	Draw(BRect r);
+	virtual void 	MouseDown(BPoint p);
+ 	virtual void 	MouseUp(BPoint p);
+ 	virtual void 	MouseMoved(BPoint point, uint32 transit, const BMessage *message);	
+};
+
+
+class TWin : public BWindow
+{
+ public:
+				TWin(int x,int y, int w,int h,window_look look);
+				~TWin();
+	bool		QuitRequested();
+ 	virtual void FrameResized(float width, float height);		
+	virtual void MessageReceived(BMessage *message);	
+	IterView *view;
+};
+
+
+class SeamView : public BView
+{
+ public:
+					SeamView(BRect R);
+					~SeamView();
+	void			MyDraw(BRect r);				
+protected:
+	virtual void	Draw(BRect r);
+	virtual void 	MouseDown(BPoint p);
+ 	virtual void 	MouseUp(BPoint p);
+ 	virtual void 	MouseMoved(BPoint point, uint32 transit, const BMessage *message);	
+};
+
+class SeamWin : public BWindow
+{
+ public:
+				SeamWin(int x,int y, int w,int h,window_look look,int id=0,int group=0);
+				~SeamWin();
+ 	virtual void 	FrameResized(float width, float height);
+ 	virtual void 	FrameMoved(BPoint p);
+	virtual void MessageReceived(BMessage *message);	
+	virtual	void WindowActivated(bool f);
+	bool		QuitRequested();
+	SeamView	*view;
+	int			id;
+	int			group;	
+};
diff --git a/serial.c b/serial.c
index 7f3318e..ed82020 100644
--- a/serial.c
+++ b/serial.c
@@ -277,12 +277,14 @@ get_termios(SERIAL_DEVICE * pser_inf, RD_NTHANDLE serial_fd)
 		case CS5:
 			pser_inf->word_length = 5;
 			break;
+#ifndef __HAIKU__
 		case CS6:
 			pser_inf->word_length = 6;
 			break;
 		case CS7:
 			pser_inf->word_length = 7;
 			break;
+#endif
 		default:
 			pser_inf->word_length = 8;
 			break;
@@ -482,6 +484,7 @@ set_termios(SERIAL_DEVICE * pser_inf, RD_NTHANDLE serial_fd)
 	}
 
 
+#ifndef __HAIKU__
 	if (pser_inf->xonoff & SERIAL_XON_HANDSHAKE)
 	{
 		ptermios->c_iflag |= IXON | IMAXBEL;
@@ -490,6 +493,7 @@ set_termios(SERIAL_DEVICE * pser_inf, RD_NTHANDLE serial_fd)
 	{
 		ptermios->c_iflag |= IXOFF | IMAXBEL;
 	}
+#endif
 
 	if ((pser_inf->xonoff & (SERIAL_XOFF_HANDSHAKE | SERIAL_XON_HANDSHAKE)) == 0)
 	{
@@ -855,10 +859,12 @@ serial_device_control(RD_NTHANDLE handle, uint32 request, STREAM in, STREAM out)
 				modemstate |= SERIAL_MS_CTS;
 			if (result & TIOCM_DSR)
 				modemstate |= SERIAL_MS_DSR;
+#ifndef __HAIKU__
 			if (result & TIOCM_RNG)
 				modemstate |= SERIAL_MS_RNG;
 			if (result & TIOCM_CAR)
 				modemstate |= SERIAL_MS_CAR;
+#endif
 			if (result & TIOCM_DTR)
 				modemstate |= SERIAL_MS_DTR;
 			if (result & TIOCM_RTS)
diff --git a/types.h b/types.h
index 09ddf0f..8f365c8 100644
--- a/types.h
+++ b/types.h
@@ -24,12 +24,19 @@ typedef int RD_BOOL;
 #define False (0)
 #endif
 
+#ifdef __HAIKU__
+#include <SupportDefs.h>
+typedef int8 sint8;
+typedef int16 sint16;
+typedef int32 sint32;
+#else
 typedef unsigned char uint8;
 typedef signed char sint8;
 typedef unsigned short uint16;
 typedef signed short sint16;
 typedef unsigned int uint32;
 typedef signed int sint32;
+#endif
 
 typedef void *RD_HBITMAP;
 typedef void *RD_HGLYPH;
-- 
2.2.2

