From bbf663ff8712fd4dbf53ac5a277dfb0daa142afe Mon Sep 17 00:00:00 2001
From: Adrien Destugues <pulkomandy@pulkomandy.tk>
Date: Fri, 15 Mar 2019 08:17:45 +0100
Subject: Fix build on Haiku using Unix makefiles.


diff --git a/src/unix-aux.mak b/src/unix-aux.mak
index 6bbf607..76ab802 100644
--- a/src/unix-aux.mak
+++ b/src/unix-aux.mak
@@ -79,7 +79,7 @@ $(GENINIT_XE): $(GLSRC)geninit.c $(AK) $(GENINIT_DEPS)
 # The "else true;" is required because Ultrix's implementation of sh -e
 # terminates execution of a command if any error occurs, even if the command
 # traps the error with ||.
-INCLUDE=/usr/include
+INCLUDE=/system/develop/headers/posix
 $(gconfig__h): $(UNIX_AUX_MAK) $(ECHOGS_XE)
 	$(ECHOGS_XE) -w $(gconfig__h) -x 2f2a -s This file was generated automatically by unix-aux.mak. -s -x 2a2f
 	if ( test -f $(INCLUDE)/dirent.h ); then $(ECHOGS_XE) -a $(gconfig__h) -x 23 define HAVE_DIRENT_H; else true; fi
diff --git a/src/unix-dll.mak b/src/unix-dll.mak
index 2570d69..8626ba4 100644
--- a/src/unix-dll.mak
+++ b/src/unix-dll.mak
@@ -87,13 +87,13 @@ SODEFS=LDFLAGS='$(LDFLAGS) $(CFLAGS_SO) -shared -Wl,-soname=$(GS_SONAME_MAJOR)'\
 
 # Normal shared object
 so: SODIRS
-	$(MAKE) $(SODEFS) CFLAGS='$(CFLAGS_STANDARD) $(CFLAGS_SO) $(GCFLAGS) $(XCFLAGS)' prefix=$(prefix) $(GSSOC) $(GSSOX)
+	$(MAKE) $(SODEFS) CFLAGS='$(CFLAGS_STANDARD) $(CFLAGS_SO) $(GCFLAGS) $(XCFLAGS)' prefix=$(prefix) $(GSSOC)
 
 # Debug shared object
 # Note that this is in the same directory as the normal shared
 # object, so you will need to use 'make soclean', 'make sodebug'
 sodebug: SODIRS
-	$(MAKE) $(SODEFS) GENOPT='-DDEBUG' CFLAGS='$(CFLAGS_DEBUG) $(CFLAGS_SO) $(GCFLAGS) $(XCFLAGS)' $(GSSOC) $(GSSOX)
+	$(MAKE) $(SODEFS) GENOPT='-DDEBUG' CFLAGS='$(CFLAGS_DEBUG) $(CFLAGS_SO) $(GCFLAGS) $(XCFLAGS)' $(GSSOC)
 
 install-so: so
 	-mkdir -p $(prefix)
@@ -103,7 +103,6 @@ install-so: so
 	-mkdir -p $(bindir)
 	-mkdir -p $(libdir)
 	$(INSTALL_PROGRAM) $(GSSOC) $(bindir)/$(GSSOC_XENAME)
-	$(INSTALL_PROGRAM) $(GSSOX) $(bindir)/$(GSSOX_XENAME)
 	$(INSTALL_PROGRAM) $(BINDIR)/$(SOBINRELDIR)/$(GS_SONAME_MAJOR_MINOR) $(libdir)/$(GS_SONAME_MAJOR_MINOR)
 	$(RM_) $(libdir)/$(GS_SONAME)
 	ln -s $(GS_SONAME_MAJOR_MINOR) $(libdir)/$(GS_SONAME)
-- 
2.19.1


From 755d5a40ca11958285eec7b23b374f534d035e9b Mon Sep 17 00:00:00 2001
From: Adrien Destugues <pulkomandy@pulkomandy.tk>
Date: Fri, 15 Mar 2019 10:16:42 +0100
Subject: Import the BeOS patches.


diff --git a/src/contrib.mak b/src/contrib.mak
index 2e868e3..bc889fb 100644
--- a/src/contrib.mak
+++ b/src/contrib.mak
@@ -122,6 +122,12 @@ CONTRIB_MAK=$(GLSRC)contrib.mak
 #	mgr8	8-bit color MGR devices
 #	sgirgb	SGI RGB pixmap format
 #	sunhmono  Harlequin variant of 1-bit Sun raster file
+# BeOS:
+#	beos			BeOS standard non-anti-aliasing
+#	bealpha2		BeOS anti-aliasing device (2 bits for alpha channel)
+#	bealpha4		BeOS anti-aliasing device (4 bits for alpha channel)
+#	bealpht2		BeOS text only anti-aliasing device (2 bits for alpha channel)
+#	bealpht4		BeOS text only anti-aliasing device (4 bits for alpha channel)
 
 # If you add drivers, it would be nice if you kept each list
 # in alphabetical order.
@@ -850,3 +856,27 @@ $(DD)sunhmono.dev : $(sunr_) $(DD)page.dev
 $(GLOBJ)gdevsunr.$(OBJ) : $(GLSRC)gdevsunr.c $(PDEVH)
 	$(GLCC) $(GLO_)gdevsunr.$(OBJ) $(C_) $(GLSRC)gdevsunr.c
 
+### ------------------------ The BeOS devices ------------------------- ###
+### Note: these drivers are maintained by users:                        ###
+###       Original BeOS device by Jake Hamby, ported to GS 6.01         ###
+###       by Sander Stoks <sanders@sumware.demon.nl>, ported to GS 8.14 ### 
+###       by Michael Pfeiffer <michael.pfeiffer@utanet.at>;             ###
+###       anti-aliasing drivers by Michael Pfeiffer.                    ###
+
+$(DD)beos.dev: $(GLOBJ)gdevbe.$(OBJ)
+	$(SETDEV) $(DD)beos $(GLOBJ)gdevbe.$(OBJ)
+
+$(DD)bealpha2.dev: $(GLOBJ)gdevbe.$(OBJ)
+	$(SETDEV) $(DD)bealpha2 $(GLOBJ)gdevbe.$(OBJ)
+
+$(DD)bealpha4.dev: $(GLOBJ)gdevbe.$(OBJ)
+	$(SETDEV) $(DD)bealpha4 $(GLOBJ)gdevbe.$(OBJ)
+ 
+$(DD)bealpht2.dev: $(GLOBJ)gdevbe.$(OBJ)
+	$(SETDEV) $(DD)bealpht2 $(GLOBJ)gdevbe.$(OBJ)
+
+$(DD)bealpht4.dev: $(GLOBJ)gdevbe.$(OBJ)
+	$(SETDEV) $(DD)bealpht4 $(GLOBJ)gdevbe.$(OBJ)
+
+ $(GLOBJ)gdevbe.$(OBJ): $(GLSRC)gdevbe.cpp $(GLSRC)gdevbe.h $(GDEV)
+	$(GLCC) $(GLO_)gdevbe.$(OBJ) $(C_) $(GLSRC)gdevbe.cpp
diff --git a/src/gdevbe.cpp b/src/gdevbe.cpp
new file mode 100644
index 0000000..3aff1ff
--- /dev/null
+++ b/src/gdevbe.cpp
@@ -0,0 +1,1435 @@
+/* BeOS driver for Ghostscript using a BBitmap for buffering.
+ * This driver has been heavily rewritten from the previous version.
+ *
+ * Copyright 1998, Jake Hamby
+ * Send all comments, bug fixes, etc. to:  jehamby@lightside.com
+ *
+ * Anti-Aliasing drivers: bealpha2, bealpht2, bealpha4 and bealpht4 
+ * Copyright 2000, Michael Pfeiffer
+ * Email: laplace@users.sourceforge.net
+ *
+ * Description: bealpha2 and bealpha4 anti-alias text and graphic. 
+ * bealpht2 and bealpht4 anti-alias text only.
+ * 
+ * History
+ * 1998 initial port by Jake Hamby
+ * 2000 ported version 7 by Sander Stoks 
+ *      anti-aliasing driver by Michael Pfeiffer
+ * 2004 ported version 8, by Michael Pfeiffer
+ *		documented, refactored and improved AA device
+ *      (about 50% faster for certain kind of PS files e.g. tiger.eps) 
+ *      
+ *
+ * To do (eventually): 
+ * -  Creating and deleting BBitmap object is an inefficient operation!
+ *    If BE_ALPHA_BITMAP_CACHE then
+ *    - check if temporary list is faster on SMP then _cached_bitmap
+ *    - on cache overflow try to reuse a large enough bitmap instead
+ *      of deleting bitmaps from cache and creating a new one
+ *    - on cache overflow delete large bitmaps first
+ * -  Find optimal values for (see gdevbe.h):
+ *    - BE_ALPHA_HASHTABLE_SIZE
+ *    - BE_ALPHA_MAX_BITMAPS
+ *    - BE_ALPHA_REMOVE_BITMAPS
+ *    - BE_ALPHA_MAX_SIZE
+ *    and an optimal hash function HASH_FUNC in this file.
+ * -  Set the bits per pixel for the internal bitmap with a 
+ *    parameter (e.g. gs -dBitsPerPixel={8,16,32}).
+ * -  Limit the number of bitmaps in the mono bitmap cache.
+ * -  Let the GS interpreter be interruptible (return a negative number
+ *    in the device-callback functions).
+ */
+
+// set PROFILE to 1 to enable profiling
+#define PROFILE 0
+// set TRACE_COPY_CALLS to 1 to enable tracing of copy mono and alpha function calls
+#define TRACE_COPY_CALLS 0
+
+// define macro if certain functions should be inlined
+//#define INLINE inline
+// define macro if inlining should be disabled
+#define INLINE 
+
+#include <View.h>
+#include <Window.h>
+#include <Bitmap.h>
+
+typedef void* HWND;       // For old DLL interface
+
+extern "C" {
+	void gsdll_draw(unsigned char *device, BView *view, BRect dest, BRect src);
+
+	#define __PROTOTYPES__    // C++ needs prototypes, of course
+	#include "gx.h"			  // for gx_bitmap; includes std.h 
+	#include "math_.h"
+	#include "memory_.h"
+	#include "gserrors.h"
+	#include "gsparam.h"
+	#include "gsstruct.h"
+	#include "gxdevice.h"
+	#include "gsdevice.h"
+	#include "gdevbe.h"
+	#include "gsdll.h"
+
+	// Intel does name mangling on variables, so define these here.
+	extern gx_device_be gs_bealpha2_device;	
+	extern gx_device_be gs_bealpha4_device;	
+	extern gx_device_be gs_bealpht2_device;	
+	extern gx_device_be gs_bealpht4_device;	
+	extern gx_device_be gs_beos_device;	
+	extern HWND hwndtext;		        
+} // extern "C"
+
+// Macros
+#if 0
+#pragma mark *********** Macros ***************
+#endif
+// The hash function
+#define BE_ALPHA_HASH(key) ((key) % BE_ALPHA_HASHTABLE_SIZE)
+// Color compare function
+#define SAME_COLOR(c1, c2) (*((uint32*)&(c1)) == *((uint32*)&(c2)))
+
+
+// Types
+#if 0
+#pragma mark *********** Types ***************
+#endif
+// type to convert values between rgb_color and gx_color_index
+typedef union {
+	rgb_color rgb;
+	gx_color_index index;
+} colorcast_t;
+
+// The BBitmap cache entry
+// The bitmaps are stored in a linked list
+typedef struct bmapcache_s {
+	gx_bitmap_id id;          // the id of the bitmap
+	struct bmapcache_s *next; // the next entry in the linked list
+	BBitmap bitmap;           // the BBitmap
+	
+	// constructor
+	bmapcache_s(
+		gx_bitmap_id id, 
+		BRect bounds, 
+		color_space mode) 
+	: 
+		id(id), 
+		next(NULL), 
+		bitmap(bounds, mode) // construct the BBitmap
+	{ 
+		// nothing to do
+	}
+} bmapcache;
+
+
+// The BBitmap alpha cache struct 
+typedef struct bmap_alpha_cache_s {
+	gx_bitmap_id id; // the id of the bitmap stored in this entry
+	rgb_color color; // the color of this bitmap
+	long size;       // the size of this bitmap in 4 bytes
+	struct bmap_alpha_cache_s *of_next;   // the next entry in the overflow list
+	struct bmap_alpha_cache_s *of_prev;   // the previous entry in the overflow list
+	struct bmap_alpha_cache_s *mru_next;  // the next entry in the MRU list (most recently used)
+	struct bmap_alpha_cache_s *mru_prev;  // the previous entry in the MRU list
+	struct bmap_alpha_cache_s **ht_entry; // the hashtable entry with this bitmap 	
+	BBitmap bitmap;
+
+	// constructor	
+	bmap_alpha_cache_s(
+		struct bmap_alpha_cache_s **ht_entry, 
+		gx_bitmap_id id, 
+		rgb_color color, 
+		int w, int h, 
+		color_space mode) 
+	:
+		id(id), 
+		color(color), 
+		size(w*h), 
+		of_next(NULL), 
+		of_prev(NULL), 
+		mru_next(NULL), 
+		mru_prev(NULL), 
+		ht_entry(ht_entry),
+		bitmap(BRect(0, 0, w-1, h-1), mode) // construct BBitmap
+	{ 
+		// nothing to do
+	}
+} bmap_alpha_cache;
+
+// Global variables
+HWND hwndtext;               /* currently unused */
+
+// alpha conversion table
+// 2 bit alpha -> 8 bit alpha (= 255/((1 << 2) - 1) * alpha)
+static unsigned char g_alpha2[4] = {0, 85, 170, 255};
+// 4 bit alpha -> 8 bit alpha (= 255/((1 << 4) - 1) * alpha)
+static unsigned char g_alpha4[16] = {0, 17, 34, 51, 68, 85, 102, 119, 136, 153, 170, 187, 204, 221, 238, 255};
+
+
+
+// Procedures for non anti-aliased device (named beos)
+#if 0
+#pragma mark *********** GS Procedures ***************
+#endif
+
+private dev_proc_open_device(be_open);
+private dev_proc_sync_output(be_sync);
+private dev_proc_output_page(be_output_page);
+private dev_proc_close_device(be_close);
+private dev_proc_map_rgb_color(be_map_rgb_color);
+private dev_proc_map_color_rgb(be_map_color_rgb);
+private dev_proc_fill_rectangle(be_fill_rectangle);
+private dev_proc_copy_mono(be_copy_mono);
+#if 0
+private dev_proc_copy_color(be_copy_color);
+#endif
+private dev_proc_draw_line(be_draw_line);
+
+#if 0
+// Not Implemented
+private dev_proc_strip_tile_rectangle(be_strip_tile_rectangle);
+
+private dev_proc_get_params(be_get_params);
+private dev_proc_put_params(be_put_params);
+#endif
+
+// Procedures for anti-aliased devices (bealpha2, bealpha4, bealpht2, bealpht4)
+private dev_proc_map_color_rgb(be_alpha_map_color_rgb);
+private dev_proc_map_rgb_alpha_color(be_alpha_map_rgb_alpha_color);
+private dev_proc_copy_alpha(be_alpha_copy_alpha);
+
+
+#if 0
+#pragma mark *********** Device Descriptors & Devices ***************
+#endif
+#if 0
+#pragma mark ** beos **
+#endif
+// The device descriptor used by gs_beos_device
+private gx_device_procs be_procs = {
+	be_open,
+	gx_default_get_initial_matrix,
+	be_sync,
+	be_output_page,
+	be_close,
+	be_map_rgb_color,
+	be_map_color_rgb,
+	be_fill_rectangle,
+	NULL,			/* tile_rectangle */
+	be_copy_mono,
+	NULL,			/* copy_color */
+	be_draw_line,
+	NULL,			/* get_bits */
+	NULL, // be_get_params,			/* get_params */
+	NULL, // be_put_params,			/* put_params */
+	NULL,			/* map_cmyk_color */
+	NULL,			/* get_xfont_procs */
+	NULL,			/* get_xfont_device */
+	NULL,			/* map_rgb_alpha_color */
+	gx_page_device_get_page_device,
+	NULL,			/* get_alpha_bits */
+	NULL,			/* copy_alpha */
+	NULL,			/* get_band */
+	NULL,			/* copy_rop */
+	NULL,			/* fill_path */
+	NULL,			/* stroke_path */
+	NULL,			/* fill_mask */
+	NULL,			/* fill_trapezoid */
+	NULL,			/* fill_parallelogram */
+	NULL,			/* fill_triangle */
+	NULL,			/* draw_thin_line */
+	NULL,			/* begin_image */
+	NULL,			/* image_data */
+	NULL,			/* end_image */
+	NULL			/* be_strip_tile_rectangle */
+};
+
+/* The instance is public. */
+gx_device_be gs_beos_device = {
+	std_device_color_body(gx_device_be, &be_procs, "beos",
+	  INITIAL_WIDTH, INITIAL_HEIGHT,
+	  INITIAL_RESOLUTION, INITIAL_RESOLUTION,
+	  24, 255, 256),
+	{ 0 },			/* std_procs */
+	-1,				/* mutex */
+	NULL,			/* main bitmap */
+	NULL,			/* offscreen view */
+	NULL,			/* bmapcache ptr */
+	0,				/* next bitmap to use */
+};
+
+/* ---------------------------------- */
+/* ------------ bealpha2 ------------ */
+/* ---------------------------------- */
+#if 0
+#pragma mark ** bealpha2 **
+#endif
+
+/* The device descriptor */
+private gx_device_procs be_alpha2_procs = {
+	be_open,
+	gx_default_get_initial_matrix,
+	be_sync,
+	be_output_page,
+	be_close,
+	be_map_rgb_color,
+	be_alpha_map_color_rgb, // be_map_color_rgb,
+	be_fill_rectangle,
+	NULL,			/* tile_rectangle */
+	be_copy_mono,
+	NULL,			/* copy_color */
+	be_draw_line,
+	NULL,			/* get_bits */
+	NULL,			/* get_params */
+	NULL,			/* put_params */
+	NULL,			/* map_cmyk_color */
+	NULL,			/* get_xfont_procs */
+	NULL,			/* get_xfont_device */
+	be_alpha_map_rgb_alpha_color,			/* map_rgb_alpha_color */
+	gx_page_device_get_page_device,
+	NULL,           /* get_alpha_bits */
+	be_alpha_copy_alpha,			/* copy_alpha */
+	NULL,			/* get_band */
+	NULL,			/* copy_rop */
+	NULL,			/* fill_path */
+	NULL,			/* stroke_path */
+	NULL,			/* fill_mask */
+	NULL,			/* fill_trapezoid */
+	NULL,			/* fill_parallelogram */
+	NULL,			/* fill_triangle */
+	NULL,			/* draw_thin_line */
+	NULL,			/* begin_image */
+	NULL,			/* image_data */
+	NULL,			/* end_image */
+	NULL			/* be_strip_tile_rectangle */
+};
+
+/* The instance is public. */
+gx_device_be gs_bealpha2_device = {
+    std_device_dci_alpha_type_body(gx_device_be, &be_alpha2_procs,
+	"bealpha2", NULL,
+	  INITIAL_WIDTH, INITIAL_HEIGHT,
+	  INITIAL_RESOLUTION, INITIAL_RESOLUTION,
+	3, 32, 255, 255, 256, 256, 2, 2),
+	{ 0 },			/* std_procs */
+	-1,				/* mutex */
+	NULL,			/* main bitmap */
+	NULL,			/* offscreen view */
+	NULL,			/* bmapcache ptr */
+	0,				/* next bitmap to use */
+};
+
+
+/* ---------------------------------- */
+/* ------------ bealpha4 ------------ */
+/* ---------------------------------- */
+#if 0
+#pragma mark ** bealpha4 **
+#endif
+
+/* The device descriptor */
+private gx_device_procs be_alpha4_procs = {
+	be_open,
+	gx_default_get_initial_matrix,
+	be_sync,
+	be_output_page,
+	be_close,
+	be_map_rgb_color,
+	be_alpha_map_color_rgb, // be_map_color_rgb,
+	be_fill_rectangle,
+	NULL,			/* tile_rectangle */
+	be_copy_mono,
+	NULL,			/* copy_color */
+	be_draw_line,
+	NULL,			/* get_bits */
+	NULL,			/* get_params */
+	NULL,			/* put_params */
+	NULL,			/* map_cmyk_color */
+	NULL,			/* get_xfont_procs */
+	NULL,			/* get_xfont_device */
+	be_alpha_map_rgb_alpha_color,			/* map_rgb_alpha_color */
+	gx_page_device_get_page_device,
+	NULL, // be_alpha4_get_alpha_bits,			/* get_alpha_bits */
+	be_alpha_copy_alpha,			/* copy_alpha */
+	NULL,			/* get_band */
+	NULL,			/* copy_rop */
+	NULL,			/* fill_path */
+	NULL,			/* stroke_path */
+	NULL,			/* fill_mask */
+	NULL,			/* fill_trapezoid */
+	NULL,			/* fill_parallelogram */
+	NULL,			/* fill_triangle */
+	NULL,			/* draw_thin_line */
+	NULL,			/* begin_image */
+	NULL,			/* image_data */
+	NULL,			/* end_image */
+	NULL			/* be_strip_tile_rectangle */
+};
+
+/* The instance is public. */
+gx_device_be gs_bealpha4_device = {
+    std_device_dci_alpha_type_body(gx_device_be, &be_alpha4_procs,
+	"bealpha4", NULL,
+	  INITIAL_WIDTH, INITIAL_HEIGHT,
+	  INITIAL_RESOLUTION, INITIAL_RESOLUTION,
+	3, 32, 255, 255, 256, 256, 4, 4),
+	{ 0 },			/* std_procs */
+	-1,				/* mutex */
+	NULL,			/* main bitmap */
+	NULL,			/* offscreen view */
+	NULL,			/* bmapcache ptr */
+	0,				/* next bitmap to use */
+};
+
+/* ---------------------------------- */
+/* ------------ bealpht2 ------------ */
+/* ---------------------------------- */
+#if 0
+#pragma mark ** bealpht2 **
+#endif
+
+/* The device descriptor */
+private gx_device_procs be_alpht2_procs = {
+	be_open,
+	gx_default_get_initial_matrix,
+	be_sync,
+	be_output_page,
+	be_close,
+	be_map_rgb_color,
+	be_alpha_map_color_rgb, // be_map_color_rgb,
+	be_fill_rectangle,
+	NULL,			/* tile_rectangle */
+	be_copy_mono,
+	NULL,			/* copy_color */
+	be_draw_line,
+	NULL,			/* get_bits */
+	NULL,			/* get_params */
+	NULL,			/* put_params */
+	NULL,			/* map_cmyk_color */
+	NULL,			/* get_xfont_procs */
+	NULL,			/* get_xfont_device */
+	be_alpha_map_rgb_alpha_color,			/* map_rgb_alpha_color */
+	gx_page_device_get_page_device,
+	NULL,			/* get_alpha_bits */
+	be_alpha_copy_alpha,			/* copy_alpha */
+	NULL,			/* get_band */
+	NULL,			/* copy_rop */
+	NULL,			/* fill_path */
+	NULL,			/* stroke_path */
+	NULL,			/* fill_mask */
+	NULL,			/* fill_trapezoid */
+	NULL,			/* fill_parallelogram */
+	NULL,			/* fill_triangle */
+	NULL,			/* draw_thin_line */
+	NULL,			/* begin_image */
+	NULL,			/* image_data */
+	NULL,			/* end_image */
+	NULL			/* be_strip_tile_rectangle */
+};
+
+/* The instance is public. */
+gx_device_be gs_bealpht2_device = {
+    std_device_dci_alpha_type_body(gx_device_be, &be_alpht2_procs,
+	"bealpht2", NULL,
+	  INITIAL_WIDTH, INITIAL_HEIGHT,
+	  INITIAL_RESOLUTION, INITIAL_RESOLUTION,
+	3, 32, 255, 255, 256, 256, 2, 1),
+	{ 0 },			/* std_procs */
+	-1,				/* mutex */
+	NULL,			/* main bitmap */
+	NULL,			/* offscreen view */
+	NULL,			/* bmapcache ptr */
+	0,				/* next bitmap to use */
+};
+
+/* ---------------------------------- */
+/* ------------ bealpht4 ------------ */
+/* ---------------------------------- */
+#if 0
+#pragma mark ** bealphat4 **
+#endif
+
+/* The device descriptor */
+private gx_device_procs be_alpht4_procs = {
+	be_open,
+	gx_default_get_initial_matrix,
+	be_sync,
+	be_output_page,
+	be_close,
+	be_map_rgb_color,
+	be_alpha_map_color_rgb, // be_map_color_rgb,
+	be_fill_rectangle,
+	NULL,			/* tile_rectangle */
+	be_copy_mono,
+	NULL,			/* copy_color */
+	be_draw_line,
+	NULL,			/* get_bits */
+	NULL,			/* get_params */
+	NULL,			/* put_params */
+	NULL,			/* map_cmyk_color */
+	NULL,			/* get_xfont_procs */
+	NULL,			/* get_xfont_device */
+	be_alpha_map_rgb_alpha_color,			/* map_rgb_alpha_color */
+	gx_page_device_get_page_device,
+	NULL, 			/* get_alpha_bits */
+	be_alpha_copy_alpha,			/* copy_alpha */
+	NULL,			/* get_band */
+	NULL,			/* copy_rop */
+	NULL,			/* fill_path */
+	NULL,			/* stroke_path */
+	NULL,			/* fill_mask */
+	NULL,			/* fill_trapezoid */
+	NULL,			/* fill_parallelogram */
+	NULL,			/* fill_triangle */
+	NULL,			/* draw_thin_line */
+	NULL,			/* begin_image */
+	NULL,			/* image_data */
+	NULL,			/* end_image */
+	NULL			/* be_strip_tile_rectangle */
+};
+
+/* The instance is public. */
+gx_device_be gs_bealpht4_device = {
+    std_device_dci_alpha_type_body(gx_device_be, &be_alpht4_procs,
+	"bealpht4", NULL,
+	  INITIAL_WIDTH, INITIAL_HEIGHT,
+	  INITIAL_RESOLUTION, INITIAL_RESOLUTION,
+	3, 32, 255, 255, 256, 256, 4, 1),
+	{ 0 },			/* std_procs */
+	-1,				/* mutex */
+	NULL,			/* main bitmap */
+	NULL,			/* offscreen view */
+	NULL,			/* bmapcache ptr */
+	0,				/* next bitmap to use */
+};
+
+
+// -----------------------------------------------------------------------------
+// Bitmap Cache Functions
+// -----------------------------------------------------------------------------
+
+// Initialize the bitmap cache
+private void
+initialize_bitmap_cache(gx_device_be* bdev)
+{
+	bdev->_bmapcache_current = &(bdev->_bmapcache);
+}
+
+// flush
+private void
+flush_bitmap_cache(gx_device_be* bdev) 
+{
+	bmapcache_s *cur = bdev->_bmapcache;
+	while(cur) {
+		bmapcache_s *next = cur->next;
+		delete cur;
+		cur = next;
+	}
+	bdev->_bmapcache = NULL;
+	bdev->_bmapcache_current = &(bdev->_bmapcache);
+}
+
+// store bitmap in bitmap cache
+private void
+add_to_bitmap_cache(gx_device_be* bdev, bmapcache_s* bmapc)
+{
+	*(bdev->_bmapcache_current) = bmapc;
+	bdev->_bmapcache_current = &(bmapc->next);
+}
+
+// find bitmap in bitmap cache
+private BBitmap*
+find_bitmap(gx_device_be* bdev, gx_bitmap_id id)
+{
+	if(id != gx_no_bitmap_id) {
+		bmapcache_s *current = bdev->_bmapcache;
+		while(current) {
+		    if(current->id == id) {
+		    	return &(current->bitmap);
+		    }
+			current = current->next;
+		}
+	}
+	return NULL;
+}
+
+
+// -----------------------------------------------------------------------------
+// Alpha Bitmap Cache Functions
+// -----------------------------------------------------------------------------
+
+// Initialize cache
+private void
+be_alpha_initialize(gx_device_be* bdev)
+{
+	// initialize hash table
+	for (int i = 0; i < BE_ALPHA_HASHTABLE_SIZE; i++) {
+		bdev->_alpha_hashtable[i] = NULL;
+	}
+	// initialize MRU list
+	bdev->_alpha_mru_first = NULL;
+	bdev->_alpha_mru_last = NULL;
+	// initialize run time statistics
+	bdev->_alpha_num_bmaps = 0;
+	bdev->_alpha_size = 0;
+}
+
+// Uninitialize cache
+private void
+be_alpha_uninitialize(gx_device_be* bdev)
+{
+	// remove bitmaps from hash table
+	bmap_alpha_cache *current, *old;
+	for (int i = 0; i < BE_ALPHA_HASHTABLE_SIZE; i++) {
+		current = bdev->_alpha_hashtable[i];
+		while (current) {
+			old = current;
+			current = current->of_next;
+			delete old;
+		}
+		bdev->_alpha_hashtable[i] = NULL;
+	}
+		
+	bdev->_alpha_mru_first = NULL;
+	bdev->_alpha_mru_last  = NULL;
+	bdev->_alpha_num_bmaps = 0;
+	bdev->_alpha_size      = 0;
+}
+
+// Find bmapc in hash table
+// Returns entry in hash table and bmapc if it is in overflow list
+private INLINE bmap_alpha_cache **
+be_alpha_find_bmap(
+	gx_device_be *bdev, 
+	gx_bitmap_id id, 
+	rgb_color color, 
+	bmap_alpha_cache **bmapc) 
+{
+	bmap_alpha_cache **ht_entry = &bdev->_alpha_hashtable[BE_ALPHA_HASH(id)];
+	bmap_alpha_cache *current = *ht_entry;
+	// find bitmap in overflow list
+	while (current) {
+	 	if ((current->id == id) && SAME_COLOR(current->color, color)) {
+	 		break; // found
+	 	}
+		current = current->of_next;
+	}
+	*bmapc = current;
+	return ht_entry;
+}
+
+// Insert bmapc at top of overflow list of hashtable entry ht_entry
+private INLINE void 
+be_alpha_ht_insert(
+	gx_device_be *bdev, 
+	bmap_alpha_cache **ht_entry, 
+	bmap_alpha_cache *bmapc) 
+{
+	bmapc->of_next = *ht_entry;
+	bmapc->of_prev = NULL;
+	if (*ht_entry) {
+		(*ht_entry)->of_prev = bmapc;
+	}
+	*ht_entry = bmapc;
+}
+
+// Remove bmapc from overflow list of hasttable entry ht_entry
+private INLINE void 
+be_alpha_ht_remove(
+	gx_device_be *bdev, 
+	bmap_alpha_cache **ht_entry, 
+	bmap_alpha_cache *bmapc) 
+{
+	// is bmapc on top of overflow list?
+	if (*ht_entry == bmapc) {
+		*ht_entry = bmapc->of_next;
+	}
+	// update doubly linked overflow list
+	if (bmapc->of_next) {
+		bmapc->of_next->of_prev = bmapc->of_prev;
+	}
+	if (bmapc->of_prev) {
+		bmapc->of_prev->of_next = bmapc->of_next;
+	}
+}
+
+// Insert bmapc at top of MRU list. bmpac must not be in list already!
+private INLINE void 
+be_alpha_mru_insert(
+	gx_device_be *bdev, 
+	bmap_alpha_cache *bmapc) 
+{
+	// update doubly linked list
+	bmapc->mru_next = bdev->_alpha_mru_first;
+	bmapc->mru_prev = NULL;
+	if (bdev->_alpha_mru_first) {
+		// MRU list was not empty
+		bdev->_alpha_mru_first->mru_prev = bmapc;
+	} else { 
+		// bmapc is first element in MRU list
+		bdev->_alpha_mru_last = bmapc; 
+	}
+	// bmapc becomes top of MRU list	
+	bdev->_alpha_mru_first = bmapc;
+}
+
+// Remove bmapc from MRU list
+private INLINE void 
+be_alpha_mru_remove(
+	gx_device_be *bdev, 
+	bmap_alpha_cache *bmapc) 
+{
+	if (bdev->_alpha_mru_first == bmapc) { 
+		bdev->_alpha_mru_first = bmapc->mru_next;
+	}
+	if (bdev->_alpha_mru_last == bmapc) {
+		bdev->_alpha_mru_last = bmapc->mru_prev;
+	}
+	if (bmapc->mru_next) {
+		bmapc->mru_next->mru_prev = bmapc->mru_prev;
+	}
+	if (bmapc->mru_prev) {
+		bmapc->mru_prev->mru_next = bmapc->mru_next;
+	}
+}
+
+// Move bmapc on top of overflow list of hashtable entry ht_entry
+private INLINE void 
+be_alpha_update_of_list(
+	gx_device_be *bdev, 
+	bmap_alpha_cache **ht_entry, 
+	bmap_alpha_cache *bmapc) 
+{
+	if (*ht_entry != bmapc) {
+		be_alpha_ht_remove(bdev, ht_entry, bmapc);
+		be_alpha_ht_insert(bdev, ht_entry, bmapc);
+	}
+}
+
+// Move bmapc in front of mru list
+private INLINE void 
+be_alpha_update_mru_list(
+	gx_device_be *bdev, 
+	bmap_alpha_cache *bmapc) 
+{
+	if (bdev->_alpha_mru_first != bmapc) {
+		be_alpha_mru_remove(bdev, bmapc);
+		be_alpha_mru_insert(bdev, bmapc);
+	}
+}
+
+// Move bmapc on top of overflow list and MRU list
+private INLINE void 
+be_alpha_move_to_top(
+	gx_device_be *bdev, 
+	bmap_alpha_cache **ht_entry, 
+	bmap_alpha_cache *bmapc) 
+{
+	be_alpha_update_of_list(bdev, ht_entry, bmapc);
+	be_alpha_update_mru_list(bdev, bmapc);
+}
+
+// Add bmapc to overflow list and MRU list
+private INLINE void 
+be_alpha_insert_bmap(
+	gx_device_be *bdev, 
+	bmap_alpha_cache **ht_entry, 
+	bmap_alpha_cache *bmapc) 
+{
+	be_alpha_ht_insert(bdev, ht_entry, bmapc);
+	be_alpha_mru_insert(bdev, bmapc);
+	bdev->_alpha_num_bmaps ++;
+	bdev->_alpha_size += bmapc->size;
+}
+
+// Remove bmapc from overflow list and MRU list
+private INLINE void 
+be_alpha_remove_bmap(
+	gx_device_be *bdev, 
+	bmap_alpha_cache **ht_entry, 
+	bmap_alpha_cache *bmapc) 
+{
+	be_alpha_ht_remove(bdev, ht_entry, bmapc);
+	be_alpha_mru_remove(bdev, bmapc);
+	bdev->_alpha_num_bmaps --;
+	bdev->_alpha_size -= bmapc->size;
+}
+
+
+// -----------------------------------------------------------------------------
+// Device functions
+// -----------------------------------------------------------------------------
+
+/* Open the device. */
+private int
+be_open(gx_device *dev)
+{
+	// gx_device_be has been created for us
+    gx_device_be *bdev = (gx_device_be *)dev;
+    initialize_bitmap_cache(bdev);
+	// create semaphore for locking
+	bdev->_mutex = create_sem(1, "gsdll sem");
+	
+	if (dev->width == INITIAL_WIDTH)
+		dev->width = (int)(8.5 * dev->x_pixels_per_inch);
+	if (dev->height == INITIAL_HEIGHT)
+		dev->height = (int)(11.0 * dev->y_pixels_per_inch);
+
+	// initialize cached bitmap
+	bdev->_cached_bitmap = NULL;
+	bdev->_cached_width  = 0;
+	bdev->_cached_height = 0;
+
+	// setup BBitmap and BView
+	BRect frame(0.0, 0.0, dev->width-1, dev->height-1);
+	bdev->_bitmap = new BBitmap(frame, B_RGB_32_BIT, true);
+	bdev->_view = new BView(frame, "bitmap view", B_FOLLOW_NONE, B_WILL_DRAW);
+	bdev->_bitmap->AddChild(bdev->_view);
+	bdev->_view->Window()->Lock();
+	bdev->_view->SetBlendingMode(B_PIXEL_ALPHA, B_ALPHA_OVERLAY);
+
+	be_alpha_initialize(bdev);
+
+#if PROFILE
+	// initialize profiler statistics
+	bdev->_fillrect  = 0;
+	bdev->_copymono  = 0;
+	bdev->_drawline  = 0;
+	bdev->_copyalpha = 0;
+	bdev->_size      = 0; 
+	bdev->_bitmaps   = 0;
+#endif
+
+	// Notify caller about new device
+	(*pgsdll_callback)(GSDLL_DEVICE, (char *)dev, 1);
+	// Notify caller about the page size
+	(*pgsdll_callback)(GSDLL_SIZE, (char *)dev,
+			(dev->width & 0xffff) +
+			((ulong)(dev->height & 0xffff) << 16));
+    return 0;
+}
+
+#if PROFILE
+private void
+print_profile_statistics(gx_device_be* bdev)
+{
+    fprintf(stderr, "fillrect=%d copymono=%d drawline=%d copyalpha=%d "
+    	"bitmaps=%ld size=%ld\n",
+    	bdev->_fillrect, 
+    	bdev->_copymono, 
+    	bdev->_drawline, 
+    	bdev->_copyalpha,
+   		bdev->_bitmaps, 
+   		bdev->_size);
+
+    fprintf(stderr, "alpha_num_bmaps=%d alpha_size=%ld\n",
+   		bdev->_alpha_num_bmaps, 
+   		bdev->_alpha_size);
+
+}
+#endif
+
+/* Close the device. */
+private int
+be_close(gx_device *dev)
+{
+    gx_device_be *bdev = (gx_device_be *)dev;
+
+    // wait until bitmap is not being used by caller
+    gsdll_lock_device((unsigned char*)dev, 1);
+
+    // notify caller that device has been closed
+	(*pgsdll_callback)(GSDLL_DEVICE, (char *)dev, 0);
+	gsdll_lock_device((unsigned char*)dev, 0);
+
+
+	// complete all drawing operations
+	bdev->_view->Sync();
+	
+	// delete bitmap; deletes view too
+	delete bdev->_bitmap;
+	
+	// delete cached bitmap
+	delete bdev->_cached_bitmap;
+	
+	// delete monochrome bitmap cache
+	flush_bitmap_cache(bdev);
+
+	be_alpha_uninitialize(bdev);
+
+	delete_sem(bdev->_mutex);
+
+#if PROFILE
+	print_profile_statistics(bdev);
+#endif
+
+    return 0;
+}
+
+/* Map a color to index.  */
+private gx_color_index
+be_map_rgb_color(
+	register gx_device *dev,
+	const gx_color_value rgb[])
+{
+    colorcast_t colorcast;
+	colorcast.rgb.red   = rgb[0] >> 8;
+	colorcast.rgb.green = rgb[1] >> 8;
+	colorcast.rgb.blue  = rgb[2] >> 8;
+	colorcast.rgb.alpha = 0;
+	return colorcast.index;
+}
+
+
+/* Map a "device color" back to r-g-b. */
+private int
+be_map_color_rgb(
+	register gx_device *dev, 
+	gx_color_index color,
+	gx_color_value prgb[3])
+{
+	colorcast_t colorcast;
+	
+	colorcast.index = color;
+	prgb[0] = colorcast.rgb.red << 8;
+	prgb[1] = colorcast.rgb.green << 8;
+	prgb[2] = colorcast.rgb.blue << 8;
+	return 0;
+}
+
+// Synchronize the display with the commands already given 
+private int
+be_sync(register gx_device *dev)
+{
+    gx_device_be *bdev = (gx_device_be *)dev;
+    
+    bdev->_view->Sync();
+    
+    return (*pgsdll_callback)(GSDLL_SYNC, (char *)dev, 0);
+}
+
+// Display the output.
+int
+be_output_page(gx_device *dev, int copies, int flush)
+{
+    gx_device_be *bdev = (gx_device_be *)dev;
+    
+    bdev->_view->Sync();
+    
+	int ret = (*pgsdll_callback)(GSDLL_PAGE, (char *)dev, 0);
+
+#if PROFILE
+	print_profile_statistics(bdev);
+#endif
+
+    return ret;
+}
+
+// Fill a rectangle with a color.
+private int
+be_fill_rectangle(register gx_device *dev,
+		 int x, int y, int w, int h, gx_color_index color)
+{
+#if PROFILE
+    bigtime_t start = system_time();
+#endif
+
+    gx_device_be *bdev = (gx_device_be *)dev;
+    
+	colorcast_t colorcast;
+	colorcast.index = color;
+	bdev->_view->SetDrawingMode(B_OP_COPY);
+	bdev->_view->SetHighColor(colorcast.rgb);
+	bdev->_view->FillRect(BRect(x, y, w+x-1, y+h-1));
+
+	if(x <= 0 && y <= 0 && w >= bdev->width && h >= bdev->height) {
+		bdev->_view->Sync();
+		// Just cleared the screen so clear the bitmap cache 
+		flush_bitmap_cache(bdev);
+	}
+
+#if PROFILE
+	bdev->_fillrect += (int)(system_time() - start);
+#endif
+
+	return 0;
+}
+
+/* Copy a monochrome bitmap. */
+private int
+be_copy_mono(register gx_device *dev,
+	    const byte *base, int sourcex, int raster, gx_bitmap_id id,
+	    int x, int y, int w, int h,
+	    gx_color_index zero, gx_color_index one)
+{
+#if TRACE_COPY_CALLS
+	fprintf(stderr, "*+-m\t%d\t%d\t%d\t%ld\t%ld\n",
+		(int)id,
+		w, h,
+		(unsigned long)zero,
+		(unsigned long)one);
+#endif
+
+#if PROFILE
+    bigtime_t start = system_time();
+#endif
+
+    gx_device_be *bdev = (gx_device_be *)dev;
+
+    if(raster > 0) {
+		colorcast_t colorcast;
+		
+		// set high color
+		colorcast.index = one;
+		bdev->_view->SetHighColor(colorcast.rgb);
+		
+		// set low color
+		if(zero == gx_no_color_index) {
+			// transparent pixels
+			bdev->_view->SetDrawingMode(B_OP_OVER);
+		} else {
+			colorcast.index = zero;
+			bdev->_view->SetLowColor(colorcast.rgb);
+			bdev->_view->SetDrawingMode(B_OP_COPY);
+		}
+	
+		BBitmap *bitmap = NULL;
+		bitmap = find_bitmap(bdev, id);
+		bool bitmapInCache = bitmap != NULL;
+		
+		BRect from(sourcex, 0, sourcex + w - 1, h - 1);
+		BRect to(x, y, x + w - 1, y + h - 1);
+		
+		bmapcache_s *bmapc = NULL;
+		if(!bitmapInCache) {
+			// create new bitmap
+			bmapc = new bmapcache_s(id, BRect(0.0, 0.0, (raster << 3) - 1, h - 1), B_MONOCHROME_1_BIT);
+		    bmapc->bitmap.SetBits(base, raster * h, 0, B_MONOCHROME_1_BIT);
+			bitmap = &(bmapc->bitmap);
+			
+		    if (id != gx_no_bitmap_id) {
+		    	// store bitmap in cache
+		    	add_to_bitmap_cache(bdev, bmapc);
+				bdev->_view->DrawBitmapAsync(bitmap, from, to);
+				bitmapInCache = true;
+			}
+		}
+		
+		if (bitmapInCache) {
+			bdev->_view->DrawBitmapAsync(bitmap, from, to);
+		} else {
+			bdev->_view->DrawBitmap(bitmap, from, to);
+			delete bmapc;
+		}
+    }
+    
+#if PROFILE
+	bdev->_copymono += (int)(system_time() - start);
+#endif
+
+    return 0;
+}
+
+/* Copy a color bitmap. */
+/* Note:  I couldn't find any PS file which uses this function, so I left
+ * it unimplemented for now.  -jeh
+ */
+#if 0
+private int
+be_copy_color(register gx_device *dev,
+	     const byte *base, int sourcex, int raster, gx_bitmap_id id,
+	     int x, int y, int w, int h)
+{
+    fprintf(stderr, "copy color!\n");
+    return 0;
+}
+#endif
+
+/* Draw a line */
+private int
+be_draw_line(register gx_device *dev,
+  	     int x0, int y0, int x1, int y1, 
+  	     gx_color_index color)
+{
+#if PROFILE
+    bigtime_t start = system_time();
+#endif
+
+    gx_device_be *bdev = (gx_device_be *)dev;
+	colorcast_t colorcast;
+	colorcast.index = color;
+	bdev->_view->SetDrawingMode(B_OP_COPY);
+	bdev->_view->SetHighColor(colorcast.rgb);
+	bdev->_view->StrokeLine(BPoint(x0, y0), BPoint(x1, y1));
+
+#if PROFILE
+	bdev->_drawline += (int)(system_time() - start);
+#endif
+
+    return 0;
+}
+
+/* Tile a rectangle. */
+/* Note:  Because the Be GUI always has at least 256 colors, and because
+ *   this function is only used for halftoning, I left it unimplemented for
+ *   now.  -jeh
+ */
+#if 0
+private int
+be_strip_tile_rectangle(register gx_device *dev, const gx_strip_bitmap *tiles,
+		       int x, int y, int w, int h,
+		       gx_color_index zero, gx_color_index one,
+		       int px, int py)
+{
+    fprintf(stderr, "Striptile rectangle\n");
+    return 0;
+}
+#endif
+
+// Lock to make DLL threadsafe
+#if defined(__POWERPC__)
+__declspec(export)
+#endif
+int gsdll_lock_device(unsigned char *dev, int flag) {
+	gx_device_be *bdev = (gx_device_be *)dev;
+	
+    if (flag) {
+    	acquire_sem(bdev->_mutex);
+    	return 1;
+    }
+    
+    release_sem(bdev->_mutex);
+    return 0;
+}
+
+// Draw to on-screen BView 
+#if defined(__POWERPC__)
+__declspec(export)
+#endif
+void gsdll_draw(unsigned char *dev, BView *view, BRect dest, BRect src) {
+	gx_device_be *bdev = (gx_device_be *)dev;
+	view->SetDrawingMode(B_OP_COPY);
+	view->DrawBitmapAsync(bdev->_bitmap, src, dest);
+}
+
+#if 0
+// TODO Use an argument to specify whether to use anti-aliasing or not
+// and the the bit depth of the alpha channel.
+int be_get_params(gx_device *dev, gs_param_list *plist) {
+	if (plist) {
+		gs_param_enumerator_t iterator;
+		gs_param_key_t key;
+		param_init_enumerator(&iterator);
+		while (0 == param_get_next_key(plist, &iterator, &key)) {
+			if (key.data) {
+				fprintf(stderr, "%*.*s %d\n", (int)key.size, (int)key.size, key.data);
+			}
+		}
+	}
+	return 0;
+}
+
+int be_put_params(gx_device *dev, gs_param_list *plist) {	
+	if (plist) {
+		gs_param_enumerator_t iterator;
+		gs_param_key_t key;
+		param_init_enumerator(&iterator);
+		while (0 == param_get_next_key(plist, &iterator, &key)) {
+			if (key.data) {
+				fprintf(stderr, "%*.*s %d\n", (int)key.size, (int)key.size, key.data);
+			}
+		}
+	
+		int bpp;
+		param_read_int(plist, "BitsPerPixel", &bpp);
+		long l;
+		param_read_long(plist, "BitsPerPixel", &l);
+	}
+	return 0;
+}
+#endif
+
+
+/* Anti-aliasing Devices: bealpha2, bealpha4, bealpht2, bealpht4 */
+
+// Color conversion from gx_color_index to gx_color_value
+private int
+be_alpha_map_color_rgb(
+	gx_device * dev, 
+	gx_color_index color,
+	gx_color_value prgb[3])
+{
+    colorcast_t colorcast;
+	colorcast.index = color;
+	prgb[0] = colorcast.rgb.red   << 8;
+	prgb[1] = colorcast.rgb.green << 8;
+	prgb[2] = colorcast.rgb.blue  << 8;
+	return 0;	
+}
+
+// Color conversion from gx_color_values to index
+private gx_color_index
+be_alpha_map_rgb_alpha_color(
+	gx_device * dev,
+	gx_color_value r, 
+	gx_color_value g, 
+	gx_color_value b, 
+	gx_color_value alpha)
+{
+    colorcast_t colorcast;
+	colorcast.rgb.red   = r >> 8;
+	colorcast.rgb.green = g >> 8;
+	colorcast.rgb.blue  = b >> 8;
+	colorcast.rgb.alpha = alpha >> 8;
+	return colorcast.index;
+}
+
+
+private void
+make_room_in_alpha_cache(gx_device_be* bdev)
+{
+	bmap_alpha_cache *bmapc;
+	// Remove bitmaps from cache if required
+	if ((bdev->_alpha_num_bmaps >= BE_ALPHA_MAX_BITMAPS) || (bdev->_alpha_size >= BE_ALPHA_MAX_SIZE)) {
+		bdev->_view->Sync();
+		// Do we need to remove more bitmaps?
+		bmapc = bdev->_alpha_mru_last;
+		if (bmapc && 
+			((bdev->_alpha_num_bmaps >= BE_ALPHA_MAX_BITMAPS) || (bdev->_alpha_size >= BE_ALPHA_MAX_SIZE))) {
+			// Remove the least recently used bitmaps
+			do {
+				be_alpha_remove_bmap(bdev, bmapc->ht_entry, bmapc);
+				delete bmapc;
+				bmapc = bdev->_alpha_mru_last;
+			} while (bmapc && 
+				((bdev->_alpha_num_bmaps >= (BE_ALPHA_MAX_BITMAPS - BE_ALPHA_REMOVE_BITMAPS)) || 
+				(bdev->_alpha_size >= BE_ALPHA_MAX_SIZE)));
+		}
+	}
+} 
+
+// 2 alpha bits per pixel  (4 alpha values per byte in base)
+private void
+alpha2_to_bitmap(const unsigned char *base, int raster, int w, int h, BBitmap* bitmap, colorcast_t colorcast)
+{
+	unsigned char *bmp = (unsigned char*)bitmap->Bits();
+	int32 bpr = bitmap->BytesPerRow();
+	const unsigned char *data = base;
+	int32 w4 = w/4;
+	int32 rest = w & 3;
+	
+	for (int32 line = h; line; line --) {
+		// start of line
+		const unsigned char *src = data; 
+		rgb_color *dst = (rgb_color*)bmp; 
+		
+		// next line
+		data += raster;
+		bmp += bpr;
+		
+		// fill bitmap
+		for (int32 column = w4; column; column --) {
+			colorcast.rgb.alpha = g_alpha2[(*src) >> 6];
+			*dst = colorcast.rgb;
+			dst++;
+			
+			colorcast.rgb.alpha = g_alpha2[((*src) >> 4) & 0x03];
+			*dst = colorcast.rgb;
+			dst++;
+			
+			colorcast.rgb.alpha = g_alpha2[((*src) >> 2) & 0x03];
+			*dst = colorcast.rgb;
+			dst++;
+			
+			colorcast.rgb.alpha = g_alpha2[(*src) & 0x03];
+			*dst = colorcast.rgb;
+			dst++; src++;
+		}
+		
+		switch (rest) {
+			case 1:
+				colorcast.rgb.alpha = g_alpha2[(*src) >> 6];
+				*dst = colorcast.rgb;
+				break;
+
+			case 2:
+				colorcast.rgb.alpha = g_alpha2[(*src) >> 6];
+				*dst = colorcast.rgb;
+				dst++;
+				
+				colorcast.rgb.alpha = g_alpha2[((*src) >> 4) & 0x03];
+				*dst = colorcast.rgb;
+				break;
+				
+			case 3:
+				colorcast.rgb.alpha = g_alpha2[(*src) >> 6];
+				*dst = colorcast.rgb;
+				dst++;
+				
+				colorcast.rgb.alpha = g_alpha2[((*src) >> 4) & 0x03];
+				*dst = colorcast.rgb;
+				dst++;
+				
+				colorcast.rgb.alpha = g_alpha2[((*src) >> 2) & 0x03];
+				*dst = colorcast.rgb;
+				break;
+		}
+	}
+}
+
+
+// 4 alpha bits per pixel (2 alpha values per byte in base)
+private void
+alpha4_to_bitmap(const unsigned char *base, int raster, int w, int h, BBitmap* bitmap, colorcast_t colorcast)
+{
+	unsigned char *bmp = (unsigned char*)bitmap->Bits();
+	int32 bpr = bitmap->BytesPerRow();
+	const unsigned char *data = base;
+	int32 w2 = w/2;
+	bool rest = (w & 1) > 0;
+	
+	for (int32 line = h; line; line --) {
+		// start of line
+		const unsigned char *src = data; 
+		rgb_color *dst = (rgb_color*)bmp;
+		
+		// next line
+		data += raster;
+		bmp += bpr;
+		
+		// fill bitmap
+		for (int32 column = w2; column; column --) {
+			colorcast.rgb.alpha = g_alpha4[(*src) >> 4];
+			*dst = colorcast.rgb;
+			dst++;
+			
+			colorcast.rgb.alpha = g_alpha4[(*src) & 0x0F];
+			*dst = colorcast.rgb;
+			src++; dst++;
+		}
+	
+		if (rest) {
+			colorcast.rgb.alpha = g_alpha4[(*src) >> 4];
+			*dst = colorcast.rgb;
+		}
+	}
+}
+
+// return a bitmap that is large enough (if necessary delete the cached bitmap
+// and create a new one)
+private BBitmap*
+get_cached_bitmap(gx_device_be* bdev, int w, int h)
+{
+	BBitmap* bitmap = bdev->_cached_bitmap;
+	if (bitmap == NULL || (bdev->_cached_width < w) || (bdev->_cached_height < h)) {
+		delete bitmap;
+		bitmap = new BBitmap(BRect(0.0, 0.0, w-1, h-1), B_RGBA32);
+		bdev->_cached_bitmap = bitmap;
+		bdev->_cached_width = w;
+		bdev->_cached_height = h;
+	}
+	return bitmap;
+}
+
+// Copy alpha mask
+private int
+be_alpha_copy_alpha(
+	gx_device * dev, 
+	const unsigned char *base, 
+	int sourcex,
+	int raster, 
+	gx_bitmap_id id, 
+	int x, int y, int w, int h,
+	gx_color_index color, 
+	int depth)
+{
+#if TRACE_COPY_CALLS
+	fprintf(stderr, "*+-a\t%d\t%d\t%d\t%ld\t%d\n",
+		(int)id,
+		w, h,
+		(unsigned long)color,
+		depth);
+#endif
+
+#if PROFILE
+    bigtime_t start = system_time();
+#endif
+
+    gx_device_be *bdev = (gx_device_be *)dev;
+
+    if(raster > 0) {
+		colorcast_t colorcast;
+		colorcast.index = color;
+	
+		// We have to swap red and blue values, so we can use colorcast.rgb to write directly to memory
+		unsigned char swap = colorcast.rgb.red; 
+		colorcast.rgb.red = colorcast.rgb.blue; 
+		colorcast.rgb.blue = swap;
+	
+		BBitmap *bitmap = NULL;
+	
+		bmap_alpha_cache **ht_entry = NULL;
+		bmap_alpha_cache *bmapc;
+		
+		
+		// look in alpha cache
+		if (id != gx_no_bitmap_id) {
+			ht_entry = be_alpha_find_bmap(bdev, id, colorcast.rgb, &bmapc);
+			if (bmapc != NULL) { 
+				// cache hit 
+				bitmap = &(bmapc->bitmap);
+				be_alpha_move_to_top(bdev, ht_entry, bmapc);
+			}
+		}
+	
+		if(bitmap == NULL) {
+			// Create a bitmap in the color 'color'; take alpha channel from 'base'
+			if (ht_entry) {
+			#if 0
+				// if cache is full
+				//   if cache has reuseable bitmap
+				//      take bitmap, move to top, sync
+				//   else
+				//      delete some bitmaps from cache
+				// else
+				//   create a new bitmap
+			#else
+				make_room_in_alpha_cache(bdev);
+				bmapc = new bmap_alpha_cache_s(ht_entry, id, colorcast.rgb, w, h, B_RGBA32);
+				bitmap = &(bmapc->bitmap); 
+				be_alpha_insert_bmap(bdev, ht_entry, bmapc);
+			#endif
+			} else {
+				// Because bitmaps are drawn asynchronously wait for completion
+				// otherwise we could delete or overwrite a currently being drawn bitmap!
+				bdev->_view->Sync();
+				bitmap = get_cached_bitmap(bdev, w, h);
+			}
+
+			// convert the alpha mask to BBitmap
+			if (depth == 2) { 
+				alpha2_to_bitmap(base, raster, w, h, bitmap, colorcast);
+			} else if (depth == 4) { 
+				alpha4_to_bitmap(base, raster, w, h, bitmap, colorcast);
+			} else { 
+				// should not reach here!
+			}
+		} // bitmap == NULL
+
+		bdev->_view->SetDrawingMode(B_OP_ALPHA);
+
+		if (bitmap != NULL) {		
+			BRect from(sourcex, 0, sourcex + w - 1, h - 1);
+			BRect to(x, y, x + w - 1, y + h - 1);
+			bdev->_view->DrawBitmapAsync(bitmap, from, to);
+		} // bitmap != NULL
+    } // raster > 0
+    
+#if PROFILE
+	bdev->_copyalpha += (int)(system_time() - start);
+	bdev->_bitmaps++; bdev->_size += w * h;
+#endif
+    
+    return 0;
+}
+
diff --git a/src/gdevbe.h b/src/gdevbe.h
new file mode 100644
index 0000000..fd3d61d
--- /dev/null
+++ b/src/gdevbe.h
@@ -0,0 +1,65 @@
+/* BeOS driver for Ghostscript using a BBitmap for buffering.
+ * This driver has been heavily rewritten from the previous version.
+ *
+ * Copyright 1998, Jake Hamby
+ * Send all comments, bug fixes, etc. to:  jehamby@lightside.com
+ * 
+ * Anti-Aliasing drivers: bealpha2, bealpht2, bealpha4 and bealpht4 
+ * Copyright 2000-2004, Michael Pfeiffer
+ */
+
+/* Size of the hashtable */
+#define BE_ALPHA_HASHTABLE_SIZE 255
+/* Max number of bitmaps in cache */
+#define BE_ALPHA_MAX_BITMAPS 500
+/* On overflow remove this number of bitmaps */
+#define BE_ALPHA_REMOVE_BITMAPS 100 
+/* Max size */
+/* 4 MBytes (divide by 4, because bitmaps have 4 bytes per pixel) */
+#define BE_ALPHA_MAX_SIZE 4*1024*1024/4 
+
+/* Contains a BBitmap, so can't define from C */
+struct bmapcache_s;         /* the cache entry for a monochrome bitmap */
+struct bmap_alpha_cache_s;  /* the cache entry for a color bitmap with an alpha channel */
+
+/* Define the BeOS device */
+typedef struct gx_device_be_s {
+	gx_device_common;
+	sem_id _mutex;      /* for gsdll_lock_device */
+	BBitmap *_bitmap; /* the bitmap for buffering */
+	BView *_view;     /* offscreen view for drawing into the bitmap */
+	struct bmapcache_s *_bmapcache;          /* the monochrome bitmap cache */
+	struct bmapcache_s **_bmapcache_current; /* the most recently used bitmap in monochrome bitmap cache */
+
+	/* The hash table of the color bitmap cache */
+	struct bmap_alpha_cache_s *_alpha_hashtable[BE_ALPHA_HASHTABLE_SIZE];
+	/* The MRU list */ 
+	/* used to delete the least recently used bitmaps */	
+	struct bmap_alpha_cache_s *_alpha_mru_first;
+	struct bmap_alpha_cache_s *_alpha_mru_last;
+	/* Number of bitmaps in cache */
+	int _alpha_num_bmaps;
+	/* The size of all bitmaps in hashtable list in units of 4 bytes */
+	long _alpha_size; 
+
+	/* Single bitmap used to convert from alpha mask to BBitmap */
+	BBitmap* _cached_bitmap;
+	int      _cached_width;
+	int      _cached_height;
+
+#if PROFILE
+	/* Statistics */
+	int  _fillrect;
+	int  _copymono;
+	int  _drawline;
+	int  _copyalpha;
+	long _size;
+	long _bitmaps;
+#endif
+} gx_device_be;
+
+/* Default dots-per-inch (be sure to choose an even number!) */
+/* Macros are duplicated in gsfront.cpp; synchronize them if necessary! */
+#define INITIAL_RESOLUTION ((int)96.0)
+#define INITIAL_WIDTH ((int)(INITIAL_RESOLUTION * 85 / 10 + 1))
+#define INITIAL_HEIGHT ((int)(INITIAL_RESOLUTION * 11 + 1))
diff --git a/src/gsdll.c b/src/gsdll.c
index ea9b0ce..3ceb6cb 100644
--- a/src/gsdll.c
+++ b/src/gsdll.c
@@ -52,6 +52,10 @@
 extern HWND hwndtext;
 #endif
 
+#ifdef __BEOS__
+#define HWND void *
+#endif
+
 /****** SINGLE-INSTANCE HACK ******/
 /* GLOBAL WARNING */
 GSDLL_CALLBACK pgsdll_callback = NULL;	/* callback for messages and stdio to caller */
diff --git a/src/gsdll.h b/src/gsdll.h
index 4316937..98b8dec 100644
--- a/src/gsdll.h
+++ b/src/gsdll.h
@@ -44,6 +44,10 @@
 #define GSDLLCALLLINK
 #endif
 
+#ifdef __BEOS__
+#define HWND void *
+#endif
+
 /* global pointer to callback */
 typedef int (* GSDLLCALLLINK GSDLL_CALLBACK) (int, char *, unsigned long);
 extern GSDLL_CALLBACK pgsdll_callback;
diff --git a/src/gsfcmap.c b/src/gsfcmap.c
index 4436a6c..e82ab0c 100644
--- a/src/gsfcmap.c
+++ b/src/gsfcmap.c
@@ -219,7 +219,7 @@ gs_cmap_create_char_identity(gs_cmap_t **ppcmap, int num_bytes, int wmode,
 /*
  * Check for identity CMap. Uses a fast check for special cases.
  */
-int
+bool
 gs_cmap_is_identity(const gs_cmap_t *pcmap, int font_index_only)
 {
     return pcmap->procs->is_identity(pcmap, font_index_only);
diff --git a/src/gsfront.cpp b/src/gsfront.cpp
new file mode 100644
index 0000000..db03cd6
--- /dev/null
+++ b/src/gsfront.cpp
@@ -0,0 +1,775 @@
+/* Copyright (C) 1998, Jake Hamby.  All rights reserved.
+
+  This file is part of Aladdin Ghostscript.
+
+  Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND.  No author
+  or distributor accepts any responsibility for the consequences of using it,
+  or for whether it serves any particular purpose or works at all, unless he
+  or she says so in writing.  Refer to the Aladdin Ghostscript Free Public
+  License (the "License") for full details.
+
+  Every copy of Aladdin Ghostscript must include a copy of the License,
+  normally in a plain ASCII text file named PUBLIC.  The License grants you
+  the right to copy, modify and redistribute Aladdin Ghostscript, but only
+  under certain conditions described in the License.  Among other things, the
+  License requires that the copyright notice and this notice be preserved on
+  all copies.
+  
+
+  gsfront.cpp
+
+  Shared library front-end to Ghostscript.  Simulates traditional "gs"
+  executable, but opens a window for the native BeOS GUI driver
+
+  History
+  1998 Initial port by Jake Hamby
+  2000 Ported version 7 by Sander Stoks (see comment below)
+  2004 Ported version 8 by Michael Pfeiffer (laplace@users.sourceforge.net)
+
+  Note by Sander Stoks:
+  This is mostly Jake Hamby's work.  All I did was modify it to use
+  ArgvReceived() and RefsReceived() properly, so you can set this front-end
+  to be the preferred app for application/postscript files and have it
+  launch with the file opened when you double-click a PS file. 
+  This is only of limited use since I left the "next page" stuff
+  unimplemented.  A "proper" front end would open a small window with
+  backward/forward buttons.  Maybe I'll write one on a rainy Sunday afternoon
+  (and although I have plenty of those here in London, don't hold your breath :-) 
+*/
+
+// set VERBOSE to 1 to print debugging output
+#define VERBOSE 0
+
+#include <stdio.h>
+#include <string.h>
+
+#include <Alert.h>
+#include <Application.h>
+#include <Autolock.h>
+#include <Beep.h>
+#include <Entry.h>
+#include <File.h>
+#include <FindDirectory.h>
+#include <MenuItem.h>
+#include <Path.h>
+#include <PopUpMenu.h>
+#include <Screen.h>
+#include <ScrollView.h>
+
+typedef void *HWND;
+
+extern "C" {
+#include "gsdll.h"
+void gsdll_draw(unsigned char *device, BView *view, BRect dest, BRect src);
+}
+
+#if VERBOSE
+	#define OUT(args) fprintf args
+#else
+	#define OUT(args)
+#endif
+
+// Constants
+
+// Default dots-per-inch (be sure to choose an even number!)
+// Copied from gdevbe.h
+#define INITIAL_RESOLUTION ((int)96.0)
+#define INITIAL_WIDTH ((int)(INITIAL_RESOLUTION * 85 / 10 + 1))
+#define INITIAL_HEIGHT ((int)(INITIAL_RESOLUTION * 11 + 1))
+
+// Preferences
+static const char* kPreferencesFile = "ghostscript_settings";
+static const char* kWindowLeft = "window_left";
+static const char* kWindowTop  = "window_top";
+
+// TODO query these from the system:
+static const int kWindowTabHeight = 24;
+static const int kWindowBorderSize = 4;
+
+// Prototypes
+long gsloop(void *foo);
+
+// Local class declarations
+
+
+class Preferences {
+public:
+	Preferences();
+	virtual ~Preferences();
+	bool GetPath(BPath* path);
+
+	BPoint GetWindowPosition()              { return fWindowPosition; }
+	void SetWindowPosition(BPoint position) { fWindowPosition = position; }
+	
+private:
+	BPoint fWindowPosition;
+};
+
+
+class PSView : public BView {
+public:
+	PSView(BRect area);
+	void Draw(BRect area);
+	void Pulse();
+	void UpdateScrollbar(orientation direction, float viewSize, float pageSize);
+	void UpdateScrollbars();
+	void SetPageSize(int width, int height);
+	
+	void ScrollTo(BPoint point);
+
+	BPoint GetMouseScreenPosition();
+
+	void ShowPopUpMenu(BPoint point);
+	void MouseDown(BPoint point);
+	void MouseMoved(BPoint point, uint32 transit, const BMessage *msg);
+	void MouseUp(BPoint point);
+	
+	void MouseWheelChanged(BMessage* msg);
+
+	void MessageReceived(BMessage* msg);
+	
+	
+private:
+	int         fPageWidth;
+	int         fPageHeight;
+	// fields used for dragging support
+	bool        fDragView;
+	BPoint      fLastMousePosition;
+};
+
+class PSWindow : public BWindow {
+public:
+	PSWindow(BRect frame, const char *title, window_type type, ulong flags, Preferences* prefs);
+	bool QuitRequested();
+	void MessageReceived(BMessage* msg);
+	
+	void GsDllSync();
+	void GsDllPage();
+	void GsDllSetPageSize(int width, int height);
+	void GsStopUpdate();
+	
+	void FrameMoved(BPoint position);
+	void FrameResized(float width, float height);	
+
+	PSView* GetView() { return fPSView; }
+	
+	
+private:
+	PSView      *fPSView;
+	BScrollView *fScrollView;
+	Preferences* fPreferences;
+};
+
+class PSApplication : public BApplication {
+public:
+    PSApplication(const char *sig);
+	virtual ~PSApplication();
+	
+    void AboutRequested();
+    void MessageReceived(BMessage *message);
+    bool QuitRequested();
+    void RefsReceived(BMessage *message);
+    void ReadyToRun();
+
+
+	PSWindow* GetWindow() { return fWindow; }
+	Preferences* GetPreferences() { return fPreferences; }
+
+private:
+	Preferences *fPreferences;
+    PSWindow    *fWindow;
+	thread_id   fGhostscriptThread;
+};
+
+// Private message types
+#define SHOW_FILE_PANEL	'SPNL'
+#define NEXT_PAGE		'NXPG'
+
+// The BeOS device to draw
+unsigned char *gBeDevice = NULL;
+
+// more global variables
+PSApplication *gApplication;
+int           gArgc;
+char          **gArgv;
+bool          gRunInTerminal;
+
+
+// Implementation of Preferences
+Preferences::Preferences()
+	: fWindowPosition(15, kWindowTabHeight)
+{
+	BPath path;
+	if (GetPath(&path)) {
+		BFile file(path.Path(), B_READ_ONLY);
+		BMessage data;
+		if (file.InitCheck() == B_OK &&
+			data.Unflatten(&file) == B_OK) {
+			
+			// read preferences
+			data.FindFloat(kWindowLeft, &fWindowPosition.x);
+			data.FindFloat(kWindowTop, &fWindowPosition.y);
+		}
+	}
+}
+
+Preferences::~Preferences()
+{
+	BPath path;
+	if (GetPath(&path)) {
+		// write preferences
+		BMessage data;
+		data.AddFloat(kWindowLeft, fWindowPosition.x);
+		data.AddFloat(kWindowTop, fWindowPosition.y);
+		
+		BFile file(path.Path(), B_WRITE_ONLY | B_CREATE_FILE | B_ERASE_FILE);
+		if (file.InitCheck() == B_OK) {
+			data.Flatten(&file);
+		}
+	}
+}
+
+bool Preferences::GetPath(BPath* path)
+{
+	return find_directory(B_COMMON_SETTINGS_DIRECTORY, path) == B_OK &&
+		path->Append(kPreferencesFile) == B_OK;
+}
+
+
+// Implementation of PSWindow
+
+PSWindow::PSWindow(BRect frame, const char *title, window_type type, ulong flags, Preferences* prefs) 
+	: BWindow(frame, title, type, flags)
+	, fPreferences(prefs)
+{
+	AddShortcut('a', B_COMMAND_KEY, new BMessage(B_ABOUT_REQUESTED));
+	
+	frame.OffsetTo(B_ORIGIN);
+	frame.right -= B_V_SCROLL_BAR_WIDTH;
+	frame.bottom -= B_H_SCROLL_BAR_HEIGHT;
+	fPSView = new PSView(frame);
+	
+	fScrollView = new BScrollView("Scroll View", fPSView, B_FOLLOW_ALL,
+			0, true, true, B_FANCY_BORDER);
+	fScrollView->ScrollBar(B_HORIZONTAL)->SetRange(0, 611);
+	fScrollView->ScrollBar(B_VERTICAL)->SetRange(0, 791);
+
+	AddChild(fScrollView);
+	fPSView->UpdateScrollbars();
+	fPSView->MakeFocus();
+}
+
+bool PSWindow::QuitRequested() 
+{
+	be_app_messenger.SendMessage(B_QUIT_REQUESTED);
+	return true;
+}
+
+void PSWindow::MessageReceived(BMessage* msg)
+{
+	if (msg->what == B_ABOUT_REQUESTED) {
+		be_app_messenger.SendMessage(B_ABOUT_REQUESTED);
+	}
+}
+
+void PSWindow::GsDllSync()
+{
+	BAutolock autoLock(this);
+	if (!autoLock.IsLocked()) return;
+	// Use pulse to update the view while the page is being rendered
+	fPSView->Invalidate();
+	SetPulseRate(1000000/10);
+}
+
+void PSWindow::GsDllPage()
+{
+	BAutolock autoLock(this);
+	if (!autoLock.IsLocked()) return;
+	// Stop pulse
+	SetPulseRate(0);
+	fPSView->Invalidate();
+}
+
+void PSWindow::GsStopUpdate()
+{
+	BAutolock autoLock(this);
+	if (autoLock.IsLocked()) {
+		SetPulseRate(0);
+	}
+}
+
+// Resize window but stay inside screen bounds
+void PSWindow::GsDllSetPageSize(int width, int height)
+{
+	BAutolock autoLock(this);
+	
+	fPSView->SetPageSize(width, height);
+	
+	BRect screensize;
+	BScreen screen;
+	if (screen.IsValid()) {
+		screensize = screen.Frame();
+	} else {
+		screensize = BRect(0, 0, 640, 480);
+	}
+	
+	// scroll bars should not overlap page
+	width += (int)B_V_SCROLL_BAR_WIDTH;
+	height += (int)B_H_SCROLL_BAR_HEIGHT;
+	
+	BRect frame(Frame());
+	// stay inside screen
+	if (frame.left + width - kWindowBorderSize > screensize.right) {
+		width = (int)(screensize.right - frame.left - kWindowBorderSize);
+	}
+	if (frame.top + height - kWindowBorderSize > screensize.bottom) {
+		height = (int)(screensize.bottom - frame.top - kWindowBorderSize);
+	}
+	ResizeTo(width, height);
+}
+
+void PSWindow::FrameMoved(BPoint position)
+{
+	if (fPreferences != NULL) {
+		fPreferences->SetWindowPosition(position);
+	}
+}
+
+void PSWindow::FrameResized(float width, float height)
+{
+	fPSView->UpdateScrollbars();
+}
+
+// Implementation of PSView
+
+PSView::PSView(BRect frame) 
+	: BView(frame, "PSView", B_FOLLOW_ALL_SIDES, B_WILL_DRAW | B_PULSE_NEEDED) 
+	, fPageWidth(INITIAL_WIDTH)
+	, fPageHeight(INITIAL_HEIGHT)
+{
+	SetViewColor(B_TRANSPARENT_COLOR);
+}
+
+void PSView::Draw(BRect area) 
+{
+	const rgb_color kWhite = {255, 255, 255, 0};
+	SetDrawingMode(B_OP_COPY);
+	SetHighColor(kWhite);
+
+	if(gBeDevice) {
+		// fill space around page with white color
+		if (area.left < 0) {
+			FillRect(BRect(area.left, area.top, -1, area.bottom));
+		}
+		if (fPageWidth <= area.right) {
+			FillRect(BRect(fPageWidth, area.top, area.right, area.bottom));
+		}
+		if (area.top < 0) {
+			FillRect(BRect(area.left, area.top, area.right, -1));
+		}
+		if (fPageHeight <= area.bottom) {
+			FillRect(BRect(area.left, fPageHeight, area.right, area.bottom));			
+		}
+		// paint page
+		gsdll_lock_device(gBeDevice, 1);
+		gsdll_draw(gBeDevice, this, area, area);
+		gsdll_lock_device(gBeDevice, 0);
+	} else {
+		FillRect(area);
+	}
+}
+
+void PSView::Pulse()
+{
+	Invalidate();
+}
+
+void PSView::SetPageSize(int width, int height)
+{
+	fPageWidth = width;
+	fPageHeight = height;
+}
+
+void PSView::UpdateScrollbar(orientation direction, float viewSize, float pageSize) 
+{
+	BScrollBar* scrollBar = ScrollBar(direction);
+	if (scrollBar != NULL) {
+		float outsideSize = pageSize - viewSize;
+		if (outsideSize < 0.0) {
+			outsideSize = 0.0;
+		}
+		
+		scrollBar->SetRange(0, outsideSize);
+		scrollBar->SetProportion(viewSize / pageSize);
+		scrollBar->SetSteps(viewSize / 10.0, viewSize);
+	}
+}
+
+void PSView::UpdateScrollbars() 
+{
+	BRect bounds(Bounds());
+	UpdateScrollbar(B_HORIZONTAL, bounds.Width(), fPageWidth);
+	UpdateScrollbar(B_VERTICAL, bounds.Height(), fPageHeight);
+}
+
+// scroll restricted within page size
+void PSView::ScrollTo(BPoint point) 
+{
+	BRect bounds(Bounds());
+	float xMax = fPageWidth - bounds.Width();
+	float yMax = fPageHeight - bounds.Height();
+	
+	if (xMax < 0) xMax = 0;	
+	if (yMax < 0) yMax = 0;
+	
+	if (point.x < 0) {
+		point.x = 0;
+	} else if (point.x > xMax) {
+		point.x = xMax;
+	}
+	
+	if (point.y < 0) {
+		point.y = 0;
+	} else if (point.y > yMax)  {
+		point.y = yMax;
+	}
+		
+	BView::ScrollTo(point); 
+}
+
+BPoint PSView::GetMouseScreenPosition()
+{
+	uint32 buttons;
+	BPoint position;
+	GetMouse(&position, &buttons, false);
+	ConvertToScreen(&position);
+	return position;
+}
+
+void PSView::ShowPopUpMenu(BPoint point)
+{
+	BPopUpMenu* menu = new BPopUpMenu("PopUpMenu");
+	menu->SetAsyncAutoDestruct(true);
+
+	BMessage* msg;
+	BMenuItem* i;
+
+	// About menu item
+	msg = new BMessage(B_ABOUT_REQUESTED);
+	i = new BMenuItem("About", msg);
+	i->SetTarget(this);
+	menu->AddItem(i);
+
+	point -= BPoint(10, 10);
+	menu->Go(point, true, false, false);	
+}
+
+void PSView::MouseDown(BPoint point)
+{
+	// 
+	if (modifiers() != 0) return;
+	
+	uint32 buttons;
+	GetMouse(&point, &buttons);
+	if (buttons & B_PRIMARY_MOUSE_BUTTON) {
+		MakeFocus();
+		SetMouseEventMask(B_POINTER_EVENTS);
+		fLastMousePosition = GetMouseScreenPosition();
+		fDragView = true;	
+	} else if (buttons & B_SECONDARY_MOUSE_BUTTON) {
+		ShowPopUpMenu(GetMouseScreenPosition());
+	}
+}
+
+void PSView::MouseMoved(BPoint point, uint32 transit, const BMessage *msg)
+{
+	if (fDragView) {
+		BPoint position(GetMouseScreenPosition());
+		BPoint delta(fLastMousePosition - position);
+		ScrollBy(delta.x, delta.y);
+		fLastMousePosition = position;
+	}
+}
+
+void PSView::MouseUp(BPoint point)
+{
+	if (fDragView) {
+		MouseMoved(point, 0, NULL);
+		fDragView = false;
+	}
+}
+
+void PSView::MouseWheelChanged(BMessage* msg)
+{
+	float scrollDistance = 25;
+	
+	// set scroll distance to 20% of the minimum of screen width and height
+	BScreen screen;
+	if (screen.IsValid()) {
+		BRect frame(screen.Frame());
+		if (frame.right < frame.bottom) {
+			scrollDistance = frame.right;
+		} else {
+			scrollDistance = frame.bottom;
+		}
+		scrollDistance *= 0.20;
+	}
+	
+	float dy, dx;
+	if (msg->FindFloat("be:wheel_delta_y", &dy) == B_OK && dy != 0.0) {
+		bool down = dy > 0;
+		// intelliMouse driver uses command key to simulate wheel_detla_x!
+		if ((modifiers() & (B_COMMAND_KEY | B_OPTION_KEY))) {
+			// Zoom(!down); // zoom in / out	
+		} else if ((modifiers() & (B_SHIFT_KEY | B_CONTROL_KEY))) {
+			// next/previous page
+			// MoveToPage(mCurrentPage + (down ? 1 : -1));
+		} else {
+			ScrollBy(0, scrollDistance * (down ? 1 : -1));
+		}
+	}
+	if (msg->FindFloat("be:wheel_delta_x", &dx) == B_OK && dx != 0.0) {
+		bool right = dx > 0;
+		ScrollBy(scrollDistance * (right ? 1 : -1), 0);
+	}
+}
+
+void PSView::MessageReceived(BMessage* msg)
+{
+//	if (msg->what == B_MOUSE_WHEEL_CHANGED) {
+		// MouseWheelChanged(msg);
+//	} else {
+		BView::MessageReceived(msg);
+//	}
+}
+
+// Implementation of PSApplication
+
+PSApplication::PSApplication(const char *sig) : BApplication(sig) 
+{
+	fPreferences = new Preferences();
+	
+	BScreen myscreen;
+	BRect screensize;
+	if (myscreen.IsValid()) {
+		screensize = myscreen.Frame();
+	} else {
+		screensize = BRect(0,0,640,480);
+	}
+	
+	BPoint position(15, kWindowTabHeight);
+	if (fPreferences != NULL) {
+		position = fPreferences->GetWindowPosition();
+	}
+	BRect frame(position.x, position.y, 
+		screensize.right - kWindowBorderSize, screensize.bottom - kWindowBorderSize);
+		
+    fWindow = new PSWindow(frame, "Ghostscript", B_DOCUMENT_WINDOW, 0, fPreferences);
+        		
+	fWindow->Run();
+}
+
+PSApplication::~PSApplication() {
+	delete fPreferences;
+	fPreferences = NULL;
+}
+
+void PSApplication::ReadyToRun ()
+{
+	fGhostscriptThread = spawn_thread(gsloop, "GS Loop", B_NORMAL_PRIORITY, (void *)GetWindow()->GetView());
+	resume_thread(fGhostscriptThread);
+}
+
+void PSApplication::AboutRequested() {
+   BAlert *alert;
+
+   alert = new BAlert("", "AFPL Ghostscript 8.14 (2004-02-20)\n\n"
+	"Copyright (C) 2004 artofcode LLC, Benicia, CA.  All rights reserved.\n"
+	"This software comes with NO WARRANTY: see the file PUBLIC for details.\n\n"
+	"BeOS port by Jake Hamby, Sander Stoks and Michael Pfeiffer.\n\n"
+	"Please send all comments to:\n"
+	"    laplace@users.sourceforge.net",
+   	"OK", NULL, NULL, B_WIDTH_AS_USUAL, B_INFO_ALERT);
+   alert->Go();
+}
+
+void PSApplication::MessageReceived(BMessage *message)
+{
+	switch (message->what) {
+		case SHOW_FILE_PANEL:
+//			RunFilePanel();         // Use default values
+			OUT((stderr, "Open file...\n"));
+			break;
+        case NEXT_PAGE:
+			OUT((stderr, "Next page...\n"));
+			break;
+		default:
+			BApplication::MessageReceived(message);
+            break;
+	}
+}
+
+bool PSApplication::QuitRequested() {
+	kill_thread(fGhostscriptThread);  // Kill Ghostscript thread if still running
+	return true;                      // and exit app
+}
+
+void PSApplication::RefsReceived(BMessage *message)
+{
+	gRunInTerminal = false;
+	BPath path;
+	entry_ref ref;
+	if (message->FindRef ("refs", &ref) == B_OK) {
+		gArgc = 2;
+		gArgv[0] = new char[16];
+		strcpy (gArgv[0], "gs");
+		path.SetTo (&ref);
+		gArgv[1] = new char[strlen(path.Path()) + 1];
+		strcpy (gArgv[1], path.Path());
+	}
+}
+
+// Only used to open and close BWindow
+int
+gsdll_callback(int message, char *str, unsigned long data)
+{
+	static bool child_added = 0;
+    char *p;
+    switch (message) {
+	    case GSDLL_STDIN:
+	    	OUT((stderr, "GSDLL_STDIN called\n"));
+	        p = fgets(str, data, stdin);
+	        if (p)
+	           return strlen(str);
+	        else
+	           return 0; 
+	    case GSDLL_STDOUT:
+	    	OUT((stderr, "GSDLL_STDOUT called\n"));
+	        if (str != (char *)NULL)
+				fwrite(str, 1, data, stderr);
+	        return data;
+	    case GSDLL_DEVICE:
+			OUT((stderr, "GSDLL_DEVICE called\n"));
+			gBeDevice = (unsigned char *)str;
+			if (data && !child_added) {	// open window
+				child_added = 1;
+				gApplication->GetWindow()->Lock();
+				gApplication->GetWindow()->Show();
+				gApplication->GetWindow()->Unlock();
+			} else {	// close window
+				// do nothing right now
+			}
+			break;
+	    case GSDLL_SYNC:
+	        OUT((stderr,"Callback: SYNC %p %ld\n", str, data));
+	        gApplication->GetWindow()->GsDllSync();
+	        break;
+	    case GSDLL_PAGE:
+	        OUT((stderr,"Callback: PAGE %p %ld\n", str, data));
+	        gApplication->GetWindow()->GsDllPage();
+	        break;
+	    case GSDLL_SIZE:
+	        OUT((stderr,"Callback: SIZE %p width=%d height=%d\n", str,
+	            (int)(data & 0xffff), (int)((data>>16) & 0xffff) ));
+			{
+				int width = (int)(data & 0xffff);
+				int height = (int)((data>>16) & 0xffff);
+				gApplication->GetWindow()->GsDllSetPageSize(width, height);
+			}
+	        break;
+	    case GSDLL_POLL:
+	        OUT((stderr,"Callback: POLL %p\n", str));
+	        return 0; /* no error */
+	    default:
+	        OUT((stderr,"Callback: Unknown message=%d\n",message));
+	        break;
+    }
+    return 0;
+}
+
+void stop_automatic_invalidation()
+{
+	if (gBeDevice != NULL) {
+		gApplication->GetWindow()->GsStopUpdate();
+	}
+}
+
+void prompt()
+{
+	fprintf(stdout, "GS> ");
+	fflush(stdout);
+}
+
+bool isBatchProcessing() {
+	for (int i = 1; i < gArgc; i ++) {
+		if (strcmp(gArgv[i], "-dBATCH") == 0) {
+			return true;
+		}
+	}
+	return false;
+}
+
+long gsloop(void *psview)
+{    
+    int code;
+    code = gsdll_init(gsdll_callback, NULL, gArgc, gArgv);
+	OUT((stderr, "gsdll_init returns %d\n", code));
+
+	if (code == GSDLL_INIT_QUIT) {
+		goto done;
+	}
+
+	if (code == 0) {
+    	code = gsdll_execute_begin();
+    }
+
+	OUT((stderr, "gsdll_execute_begin returns %d\n", code));
+    if (code == 0) {
+    	if (!isBatchProcessing()) { 
+			stop_automatic_invalidation();
+			prompt();
+			while(1)
+			{
+				char input[256];
+
+			    if(!fgets(input, sizeof(input)-1, stdin))
+					break;
+	
+				code = gsdll_execute_cont(input, strlen(input));
+				OUT((stderr, "gsdll_execute returns %d\n", code));
+	
+				if (code < 0)
+			    	break;
+				
+				stop_automatic_invalidation();
+				prompt();
+			}
+		}
+		
+		if (code < 0) {
+			code = gsdll_execute_end();
+			OUT((stderr, "gsdll_execute_end returns %d\n", code));
+		}
+		
+		code = gsdll_exit();
+		OUT((stderr, "gsdll_exit returns %d\n", code));
+	}
+
+done:
+	be_app_messenger.SendMessage(B_QUIT_REQUESTED);
+    return 0;
+}
+
+int main (int32 argc, char *argv[])
+{
+	gArgc = argc;
+	gArgv = argv;
+    PSApplication app("application/x-vnd.jehamby.gs");
+    gApplication = &app; // so global functions can find the app
+    
+    gRunInTerminal = true;
+    
+    app.Run();
+    return 0;
+}
+
diff --git a/src/gsovrc.c b/src/gsovrc.c
index 3eeaff9..24a8c47 100644
--- a/src/gsovrc.c
+++ b/src/gsovrc.c
@@ -263,7 +263,7 @@ gs_create_overprint(
  * This is used by the gs_pdf1.4_device (and eventually the PDFWrite
  * device), which implements overprint and overprint mode directly.
  */
-int
+bool
 gs_is_overprint_compositor(const gs_composite_t * pct)
 {
     return pct->type == &gs_composite_overprint_type;
diff --git a/src/gximag3x.c b/src/gximag3x.c
index b09b9cd..2fb6b79 100644
--- a/src/gximag3x.c
+++ b/src/gximag3x.c
@@ -374,7 +374,7 @@ check_image3x_extent(floatp mask_coeff, floatp data_coeff)
  * pmcs->{InterleaveType,width,height,full_height,depth,data,y,skip}.
  * If the mask is omitted, sets pmcs->depth = 0 and returns normally.
  */
-private bool
+private int
 check_image3x_mask(const gs_image3x_t *pim, const gs_image3x_mask_t *pimm,
 		   const image3x_channel_values_t *ppcv,
 		   image3x_channel_values_t *pmcv,
diff --git a/src/gxwts.c b/src/gxwts.c
index f1effcf..71d4b4a 100644
--- a/src/gxwts.c
+++ b/src/gxwts.c
@@ -493,7 +493,7 @@ gx_dc_wts_fill_rectangle(const gx_device_color *pdevc,
 }
 
 /* Compare two wts colors for equality. */
-private int
+private bool
 gx_dc_wts_equal(const gx_device_color *pdevc1,
 		const gx_device_color *pdevc2)
 {
diff --git a/src/unix-aux.mak b/src/unix-aux.mak
index 76ab802..6aded32 100644
--- a/src/unix-aux.mak
+++ b/src/unix-aux.mak
@@ -30,10 +30,32 @@ UNIX_AUX_MAK=$(GLSRC)unix-aux.mak
 
 # Unix platforms other than System V, and also System V Release 4
 # (SVR4) platforms.
-unix__=$(GLOBJ)gp_getnv.$(OBJ) $(GLOBJ)gp_unix.$(OBJ) $(GLOBJ)gp_unifs.$(OBJ) $(GLOBJ)gp_unifn.$(OBJ) $(GLOBJ)gp_stdia.$(OBJ)
+unix__=$(GLOBJ)gp_getnv.$(OBJ) $(GLOBJ)gp_unix.$(OBJ) $(GLOBJ)gp_unifs.$(OBJ) $(GLOBJ)gp_unifn.$(OBJ) $(GLOBJ)gp_stdia.$(OBJ) $(GLOBJ)gsdll.$(OBJ)
 $(GLGEN)unix_.dev: $(unix__) $(GLD)nosync.dev
 	$(SETMOD) $(GLGEN)unix_ $(unix__) -include $(GLD)nosync
 
+bealpha2__=$(GLOBJ)gp_getnv.$(OBJ) $(GLOBJ)gp_unix.$(OBJ) $(GLOBJ)gp_unifs.$(OBJ) $(GLOBJ)gp_unifn.$(OBJ) $(GLOBJ)gp_stdia.$(OBJ) $(GLOBJ)gsdll.$(OBJ)
+$(GLGEN)bealpha2_.dev: $(bealpha2__) $(GLD)nosync.dev
+	$(SETMOD) $(GLGEN)bealpha2_ $(bealpha2__) -include $(GLD)nosync
+#	$(ADDMOD) $(GLGEN)bealpha2_ -iodev wstdio
+
+bealpha4__=$(GLOBJ)gp_getnv.$(OBJ) $(GLOBJ)gp_unix.$(OBJ) $(GLOBJ)gp_unifs.$(OBJ) $(GLOBJ)gp_unifn.$(OBJ) $(GLOBJ)gp_stdia.$(OBJ) $(GLOBJ)gsdll.$(OBJ)
+$(GLGEN)bealpha4_.dev: $(bealpha4__) $(GLD)nosync.dev
+	$(SETMOD) $(GLGEN)bealpha4_ $(bealpha4__) -include $(GLD)nosync
+#	$(ADDMOD) $(GLGEN)bealpha4_ -iodev wstdio
+
+bealpht2__=$(GLOBJ)gp_getnv.$(OBJ) $(GLOBJ)gp_unix.$(OBJ) $(GLOBJ)gp_unifs.$(OBJ) $(GLOBJ)gp_unifn.$(OBJ) $(GLOBJ)gp_stdia.$(OBJ) $(GLOBJ)gsdll.$(OBJ)
+$(GLGEN)bealpht2_.dev: $(bealpht2__) $(GLD)nosync.dev
+	$(SETMOD) $(GLGEN)bealpht2_ $(bealpht2__) -include $(GLD)nosync
+#	$(ADDMOD) $(GLGEN)bealpht2_ -iodev wstdio
+
+bealpht4__=$(GLOBJ)gp_getnv.$(OBJ) $(GLOBJ)gp_unix.$(OBJ) $(GLOBJ)gp_unifs.$(OBJ) $(GLOBJ)gp_unifn.$(OBJ) $(GLOBJ)gp_stdia.$(OBJ) $(GLOBJ)gsdll.$(OBJ)
+$(GLGEN)bealpht4_.dev: $(bealpht4__) $(GLD)nosync.dev
+	$(SETMOD) $(GLGEN)bealpht4_ $(bealpht4__) -include $(GLD)nosync
+#	$(ADDMOD) $(GLGEN)bealpht4_ -iodev wstdio
+
+
+
 $(GLOBJ)gp_unix.$(OBJ): $(GLSRC)gp_unix.c $(AK)\
  $(pipe__h) $(string__h) $(time__h)\
  $(gx_h) $(gsexit_h) $(gp_h)
diff --git a/src/unix-dll.mak b/src/unix-dll.mak
index 8626ba4..ab84c1b 100644
--- a/src/unix-dll.mak
+++ b/src/unix-dll.mak
@@ -44,6 +44,11 @@ GSSOX_XENAME=$(GS)x$(XE)
 GSSOX_XE=$(BINDIR)/$(GSSOX_XENAME)
 GSSOX=$(BINDIR)/$(SOBINRELDIR)/$(GSSOX_XENAME)
 
+# loader suporting display device using BeOS
+GSSOBE_XENAME=$(GS)be$(XE)
+GSSOBE_XE=$(BINDIR)/$(GSSOBE_XENAME)
+GSSOBE=$(BINDIR)/$(SOBINRELDIR)/$(GSSOBE_XENAME)
+
 # shared library
 GS_SONAME=lib$(GS).so
 GS_SONAME_MAJOR=$(GS_SONAME).$(GS_VERSION_MAJOR)
@@ -72,6 +77,9 @@ $(GSSOX_XE): $(GS_SO) $(GLSRC)dxmain.c
 $(GSSOC_XE): $(GS_SO) $(GLSRC)dxmainc.c
 	$(GLCC) -g -o $(GSSOC_XE) $(GLSRC)dxmainc.c -L$(BINDIR) -l$(GS)
 
+$(GSSOBE_XE): $(GS_SO) $(GLSRC)gsfront.cpp
+	$(GLCC) -g -o $(GSSOBE_XE) $(GLSRC)gsfront.cpp -L$(BINDIR) -l$(GS) -lbe
+
 # ------------------------- Recursive make targets ------------------------- #
 
 SODEFS=LDFLAGS='$(LDFLAGS) $(CFLAGS_SO) -shared -Wl,-soname=$(GS_SONAME_MAJOR)'\
@@ -87,13 +95,13 @@ SODEFS=LDFLAGS='$(LDFLAGS) $(CFLAGS_SO) -shared -Wl,-soname=$(GS_SONAME_MAJOR)'\
 
 # Normal shared object
 so: SODIRS
-	$(MAKE) $(SODEFS) CFLAGS='$(CFLAGS_STANDARD) $(CFLAGS_SO) $(GCFLAGS) $(XCFLAGS)' prefix=$(prefix) $(GSSOC)
+	$(MAKE) $(SODEFS) CFLAGS='$(CFLAGS_STANDARD) $(CFLAGS_SO) $(GCFLAGS) $(XCFLAGS)' prefix=$(prefix) $(GSSOC) $(GSSOBE)
 
 # Debug shared object
 # Note that this is in the same directory as the normal shared
 # object, so you will need to use 'make soclean', 'make sodebug'
 sodebug: SODIRS
-	$(MAKE) $(SODEFS) GENOPT='-DDEBUG' CFLAGS='$(CFLAGS_DEBUG) $(CFLAGS_SO) $(GCFLAGS) $(XCFLAGS)' $(GSSOC)
+	$(MAKE) $(SODEFS) GENOPT='-DDEBUG' CFLAGS='$(CFLAGS_DEBUG) $(CFLAGS_SO) $(GCFLAGS) $(XCFLAGS)' $(GSSOC) $(GSSOBE)
 
 install-so: so
 	-mkdir -p $(prefix)
@@ -103,6 +111,7 @@ install-so: so
 	-mkdir -p $(bindir)
 	-mkdir -p $(libdir)
 	$(INSTALL_PROGRAM) $(GSSOC) $(bindir)/$(GSSOC_XENAME)
+	$(INSTALL_PROGRAM) $(GSSOBE) $(bindir)/$(GSSOBE_XENAME)
 	$(INSTALL_PROGRAM) $(BINDIR)/$(SOBINRELDIR)/$(GS_SONAME_MAJOR_MINOR) $(libdir)/$(GS_SONAME_MAJOR_MINOR)
 	$(RM_) $(libdir)/$(GS_SONAME)
 	ln -s $(GS_SONAME_MAJOR_MINOR) $(libdir)/$(GS_SONAME)
@@ -126,5 +135,6 @@ soclean: SODIRS
 	$(RM_) $(BINDIR)/$(SOBINRELDIR)/$(GS_SONAME_MAJOR)
 	$(RM_) $(GSSOC)
 	$(RM_) $(GSSOX)
+	$(RM_) $(GSSOBE)
 
 # End of unix-dll.mak
diff --git a/src/unix-gcc.mak b/src/unix-gcc.mak
index f0d4944..e4e3113 100644
--- a/src/unix-gcc.mak
+++ b/src/unix-gcc.mak
@@ -256,7 +256,7 @@ LDFLAGS=$(XLDFLAGS)
 # Solaris may need -lnsl -lsocket -lposix4.
 # (Libraries required by individual drivers are handled automatically.)
 
-EXTRALIBS=
+EXTRALIBS=-lbe
 
 # Define the standard libraries to search at the end of linking.
 # Most platforms require -lpthread for the POSIX threads library;
@@ -367,7 +367,8 @@ EXTEND_NAMES=0
 # Choose the device(s) to include.  See devs.mak for details,
 # devs.mak and contrib.mak for the list of available devices.
 
-DEVICE_DEVS=$(DISPLAY_DEV) $(DD)x11.dev $(DD)x11alpha.dev $(DD)x11cmyk.dev $(DD)x11gray2.dev $(DD)x11gray4.dev $(DD)x11mono.dev
+DEVICE_DEVS=$(DISPLAY_DEV) $(DD)beos.dev $(DD)bealpha2.dev $(DD)bealpha4.dev $(DD)bealpht2.dev $(DD)bealpht4.dev
+#DEVICE_DEVS=$(DISPLAY_DEV) $(DD)x11.dev $(DD)x11alpha.dev $(DD)x11cmyk.dev $(DD)x11gray2.dev $(DD)x11gray4.dev $(DD)x11mono.dev
 
 #DEVICE_DEVS1=
 #DEVICE_DEVS2=
-- 
2.19.1


From fce66044f86a06f28def6a45ae043b7aae9010aa Mon Sep 17 00:00:00 2001
From: Adrien Destugues <pulkomandy@pulkomandy.tk>
Date: Fri, 15 Mar 2019 19:30:01 +0100
Subject: Fix the build.

Move some of the BeOS changes into configure.ac/Makefile.in

diff --git a/src/Makefile.in b/src/Makefile.in
index 22c7773..5151451 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -282,6 +282,8 @@ XLIBDIR=
 #XLIBS=Xt Xext X11
 XLIBS=@XLIBS@
 
+BELIBS=@BELIBS@
+
 # Define whether this platform has floating point hardware:
 #	FPU_TYPE=2 means floating point is faster than fixed point.
 # (This is the case on some RISCs with multiple instruction dispatch.)
@@ -353,7 +355,7 @@ EXTEND_NAMES=0
 # devs.mak and contrib.mak for the list of available devices.
 
 #DEVICE_DEVS=$(DISPLAY_DEV) $(DD)x11.dev $(DD)x11alpha.dev $(DD)x11cmyk.dev $(DD)x11gray2.dev $(DD)x11gray4.dev $(DD)x11mono.dev
-DEVICE_DEVS=$(DISPLAY_DEV) @X11DEVS@
+DEVICE_DEVS=$(DISPLAY_DEV) @X11DEVS@ @BEDEVS@
 
 DEVICE_DEVS1=$(DD)bmpmono.dev $(DD)bmpgray.dev $(DD)bmpsep1.dev $(DD)bmpsep8.dev $(DD)bmp16.dev $(DD)bmp256.dev $(DD)bmp16m.dev $(DD)bmp32b.dev
 DEVICE_DEVS2=
diff --git a/src/configure.ac b/src/configure.ac
index a18f4d0..e145051 100644
--- a/src/configure.ac
+++ b/src/configure.ac
@@ -308,6 +308,12 @@ fi
 AC_SUBST(X11DEVS)
 AC_SUBST(XLIBS)
 
+BELIBS='-lbe'
+AC_SUBST(BELIBS)
+
+BEDEVS='$(DD)beos.dev $(DD)bealpha2.dev $(DD)bealpha4.dev $(DD)bealpht2.dev $(DD)bealpht4.dev'
+AC_SUBST(BEDEVS)
+
 dnl executible name
 AC_ARG_WITH(gs, AC_HELP_STRING([--with-gs=NAME],
 	[name of the ghostscript executible [[gs]]]),
diff --git a/src/contrib.mak b/src/contrib.mak
index bc889fb..a9eba37 100644
--- a/src/contrib.mak
+++ b/src/contrib.mak
@@ -865,18 +865,23 @@ $(GLOBJ)gdevsunr.$(OBJ) : $(GLSRC)gdevsunr.c $(PDEVH)
 
 $(DD)beos.dev: $(GLOBJ)gdevbe.$(OBJ)
 	$(SETDEV) $(DD)beos $(GLOBJ)gdevbe.$(OBJ)
+	$(ADDMOD) $(DD)beos -lib $(BELIBS)
 
 $(DD)bealpha2.dev: $(GLOBJ)gdevbe.$(OBJ)
 	$(SETDEV) $(DD)bealpha2 $(GLOBJ)gdevbe.$(OBJ)
+	$(ADDMOD) $(DD)bealpha2 -lib $(BELIBS)
 
 $(DD)bealpha4.dev: $(GLOBJ)gdevbe.$(OBJ)
 	$(SETDEV) $(DD)bealpha4 $(GLOBJ)gdevbe.$(OBJ)
- 
+	$(ADDMOD) $(DD)bealpha4 -lib $(BELIBS)
+
 $(DD)bealpht2.dev: $(GLOBJ)gdevbe.$(OBJ)
 	$(SETDEV) $(DD)bealpht2 $(GLOBJ)gdevbe.$(OBJ)
+	$(ADDMOD) $(DD)bealpht2 -lib $(BELIBS)
 
 $(DD)bealpht4.dev: $(GLOBJ)gdevbe.$(OBJ)
 	$(SETDEV) $(DD)bealpht4 $(GLOBJ)gdevbe.$(OBJ)
+	$(ADDMOD) $(DD)bealpht4 -lib $(BELIBS)
 
- $(GLOBJ)gdevbe.$(OBJ): $(GLSRC)gdevbe.cpp $(GLSRC)gdevbe.h $(GDEV)
+$(GLOBJ)gdevbe.$(OBJ): $(GLSRC)gdevbe.cpp $(GLSRC)gdevbe.h $(GDEV)
 	$(GLCC) $(GLO_)gdevbe.$(OBJ) $(C_) $(GLSRC)gdevbe.cpp
diff --git a/src/gsdll.h b/src/gsdll.h
index 98b8dec..5bc09e4 100644
--- a/src/gsdll.h
+++ b/src/gsdll.h
@@ -44,7 +44,7 @@
 #define GSDLLCALLLINK
 #endif
 
-#ifdef __BEOS__
+#if defined(__BEOS__) || defined(__HAIKU__)
 #define HWND void *
 #endif
 
diff --git a/src/gsfront.cpp b/src/gsfront.cpp
index db03cd6..ee3848a 100644
--- a/src/gsfront.cpp
+++ b/src/gsfront.cpp
@@ -231,7 +231,7 @@ Preferences::~Preferences()
 
 bool Preferences::GetPath(BPath* path)
 {
-	return find_directory(B_COMMON_SETTINGS_DIRECTORY, path) == B_OK &&
+	return find_directory(B_USER_SETTINGS_DIRECTORY, path) == B_OK &&
 		path->Append(kPreferencesFile) == B_OK;
 }
 
diff --git a/src/stdpre.h b/src/stdpre.h
index 101d4b9..932b678 100644
--- a/src/stdpre.h
+++ b/src/stdpre.h
@@ -281,13 +281,7 @@ typedef unsigned long ulong;
  * and the MetroWerks C++ compiler insists that bool be equivalent to
  * unsigned char.
  */
-#ifndef __cplusplus
-#ifdef __BEOS__
-typedef unsigned char bool;
-#else
-typedef int bool;
-#endif
-#endif
+#include <stdbool.h>
 /*
  * Older versions of MetroWerks CodeWarrior defined true and false, but they're now
  * an enum in the (MacOS) Universal Interfaces. The only way around this is to escape
diff --git a/src/unix-aux.mak b/src/unix-aux.mak
index 6aded32..29c585d 100644
--- a/src/unix-aux.mak
+++ b/src/unix-aux.mak
@@ -30,7 +30,7 @@ UNIX_AUX_MAK=$(GLSRC)unix-aux.mak
 
 # Unix platforms other than System V, and also System V Release 4
 # (SVR4) platforms.
-unix__=$(GLOBJ)gp_getnv.$(OBJ) $(GLOBJ)gp_unix.$(OBJ) $(GLOBJ)gp_unifs.$(OBJ) $(GLOBJ)gp_unifn.$(OBJ) $(GLOBJ)gp_stdia.$(OBJ) $(GLOBJ)gsdll.$(OBJ)
+unix__=$(GLOBJ)gp_getnv.$(OBJ) $(GLOBJ)gp_unix.$(OBJ) $(GLOBJ)gp_unifs.$(OBJ) $(GLOBJ)gp_unifn.$(OBJ) $(GLOBJ)gp_stdia.$(OBJ) $(GLOBJ)gsdll.$(OBJ) $(GLOBJ)gdevbe.$(OBJ)
 $(GLGEN)unix_.dev: $(unix__) $(GLD)nosync.dev
 	$(SETMOD) $(GLGEN)unix_ $(unix__) -include $(GLD)nosync
 
@@ -61,6 +61,11 @@ $(GLOBJ)gp_unix.$(OBJ): $(GLSRC)gp_unix.c $(AK)\
  $(gx_h) $(gsexit_h) $(gp_h)
 	$(GLCC) $(GLO_)gp_unix.$(OBJ) $(C_) $(GLSRC)gp_unix.c
 
+$(GLOBJ)gsdll.$(OBJ): $(GLSRC)gsdll.c $(gconfigv_h) $(AK)\
+ $(stdio__h) $(time__h) $(unistd__h) $(gx_h) $(gp_h)
+	$(GLCC) $(GLO_)gsdll.$(OBJ) $(C_) $(GLSRC)gsdll.c
+
+
 # assume all Unix platforms support unbuffered read
 $(GLOBJ)gp_stdia.$(OBJ): $(GLSRC)gp_stdia.c $(AK)\
   $(stdio__h) $(time__h) $(unistd__h) $(gx_h) $(gp_h)
diff --git a/src/unix-dll.mak b/src/unix-dll.mak
index ab84c1b..0c9c04a 100644
--- a/src/unix-dll.mak
+++ b/src/unix-dll.mak
@@ -78,7 +78,7 @@ $(GSSOC_XE): $(GS_SO) $(GLSRC)dxmainc.c
 	$(GLCC) -g -o $(GSSOC_XE) $(GLSRC)dxmainc.c -L$(BINDIR) -l$(GS)
 
 $(GSSOBE_XE): $(GS_SO) $(GLSRC)gsfront.cpp
-	$(GLCC) -g -o $(GSSOBE_XE) $(GLSRC)gsfront.cpp -L$(BINDIR) -l$(GS) -lbe
+	$(GLCC) -g -o $(GSSOBE_XE) $(GLSRC)gsfront.cpp -L$(BINDIR) -l$(GS) -lbe -lstdc++
 
 # ------------------------- Recursive make targets ------------------------- #
 
diff --git a/src/unix-gcc.mak b/src/unix-gcc.mak
index e4e3113..1d14d0a 100644
--- a/src/unix-gcc.mak
+++ b/src/unix-gcc.mak
@@ -256,7 +256,7 @@ LDFLAGS=$(XLDFLAGS)
 # Solaris may need -lnsl -lsocket -lposix4.
 # (Libraries required by individual drivers are handled automatically.)
 
-EXTRALIBS=-lbe
+EXTRALIBS=
 
 # Define the standard libraries to search at the end of linking.
 # Most platforms require -lpthread for the POSIX threads library;
@@ -367,7 +367,6 @@ EXTEND_NAMES=0
 # Choose the device(s) to include.  See devs.mak for details,
 # devs.mak and contrib.mak for the list of available devices.
 
-DEVICE_DEVS=$(DISPLAY_DEV) $(DD)beos.dev $(DD)bealpha2.dev $(DD)bealpha4.dev $(DD)bealpht2.dev $(DD)bealpht4.dev
 #DEVICE_DEVS=$(DISPLAY_DEV) $(DD)x11.dev $(DD)x11alpha.dev $(DD)x11cmyk.dev $(DD)x11gray2.dev $(DD)x11gray4.dev $(DD)x11mono.dev
 
 #DEVICE_DEVS1=
diff --git a/src/unixlink.mak b/src/unixlink.mak
index e8b122e..bcaf1a8 100644
--- a/src/unixlink.mak
+++ b/src/unixlink.mak
@@ -56,7 +56,7 @@ $(GS_XE): $(ld_tr) $(ECHOGS_XE) $(XE_ALL)
 	$(ECHOGS_XE) -w $(ldt_tr) -n - $(CCLD) $(LDFLAGS) -o $(GS_XE)
 	$(ECHOGS_XE) -a $(ldt_tr) -n -s $(PSOBJ)gs.$(OBJ) -s
 	cat $(ld_tr) >>$(ldt_tr)
-	$(ECHOGS_XE) -a $(ldt_tr) -s - $(EXTRALIBS) $(STDLIBS)
+	$(ECHOGS_XE) -a $(ldt_tr) -s - $(EXTRALIBS) -lbe -lstdc++ $(STDLIBS)
 	if [ x$(XLIBDIR) != x ]; then LD_RUN_PATH=$(XLIBDIR); export LD_RUN_PATH; fi; \
 	XCFLAGS= XINCLUDE= XLDFLAGS= XLIBDIRS= XLIBS= \
 	FEATURE_DEVS= DEVICE_DEVS= DEVICE_DEVS1= DEVICE_DEVS2= DEVICE_DEVS3= \
-- 
2.19.1

