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 #include /* 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 +#include +#include +#include +#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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern "C" +{ +#include "../rdesktop.h" +#include "../rdpsnd.h" +#include "../rdpsnd_dsp.h" +#include +#include +#include + +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 +#include +#include +#include + +#include // gethostname +#include // getpwuid +#include // va_list va_start va_end + +#include + +#include +//#include +//#include +#include + +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->xx; + if(rect->yy; + 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 + +#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 +#include +#include +#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: */ +/* []... */ + 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: */ +/* []... */ + 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 +#include +#include +#include + +#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 +#include +#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 /* 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 + +#ifndef DO_NOT_USE_VGALIB +#include +#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 + + /* + * 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 +#include + +#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 +#include +#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 +#include +#include +#include +#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= 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 +#include + +#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= 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 + * 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 . + */ + +/* 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 +#include +#include +#include +#include +#include +#include +#include + +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>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 +#include +#include +#include +#include +#include + +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 +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