Bochs/bochs/gui/sdl.cc

891 lines
20 KiB
C++
Raw Normal View History

2002-03-06 23:39:23 +03:00
/////////////////////////////////////////////////////////////////////////
// $Id: sdl.cc,v 1.19 2002-09-08 07:56:09 vruppert Exp $
2002-03-06 23:39:23 +03:00
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2002 MandrakeSoft S.A.
//
// MandrakeSoft S.A.
// 43, rue d'Aboukir
// 75002 Paris - France
// http://www.linux-mandrake.com/
// http://www.mandrakesoft.com/
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2002-02-05 08:51:38 +03:00
#define _MULTI_THREAD
#include <stdlib.h>
#include <SDL/SDL.h>
#include <SDL/SDL_endian.h>
#include <SDL/SDL_thread.h>
#include "bochs.h"
#include "icon_bochs.h"
#include "sdl.h"
#define LOG_THIS bx_gui.
#define _SDL_DEBUG_ME_
#ifdef _SDL_DEBUG_ME_
void we_are_here(void)
{
return;
}
#endif
static unsigned prev_cursor_x=0;
static unsigned prev_cursor_y=0;
#ifdef linux
#define FIX_SDL_SCANCODE(x) ((x)-8)
#else
#define FIX_SDL_SCANCODE(x) ((x))
#endif
#define MAX_SDL_BITMAPS 32
struct bitmaps {
SDL_Surface *surface;
SDL_Rect src,dst;
void (*cb)(void);
};
static struct {
unsigned bmp_id;
unsigned alignment;
void (*f)(void);
} hb_entry[BX_MAX_HEADERBAR_ENTRIES];
unsigned bx_headerbar_entries = 0;
2002-02-05 08:51:38 +03:00
SDL_Thread *sdl_thread;
SDL_Surface *sdl_screen, *sdl_fullscreen;
2002-02-05 08:51:38 +03:00
SDL_Event sdl_event;
int sdl_fullscreen_toggle;
int sdl_grab;
unsigned res_x, res_y;
int headerbar_height;
static unsigned bx_bitmap_left_xorigin = 0; // pixels from left
static unsigned bx_bitmap_right_xorigin = 0; // pixels from right
2002-02-05 08:51:38 +03:00
int textres_x, textres_y;
int fontwidth = 8, fontheight = 16;
unsigned tilewidth, tileheight;
unsigned char menufont[256][8];
Uint32 palette[256];
Uint32 headerbar_fg, headerbar_bg;
Bit8u old_mousebuttons=0, new_mousebuttons=0;
int old_mousex=0, new_mousex=0;
int old_mousey=0, new_mousey=0;
bitmaps *sdl_bitmaps[MAX_SDL_BITMAPS];
int n_sdl_bitmaps = 0;
2002-02-05 08:51:38 +03:00
#if SDL_BYTEORDER == SDL_LIL_ENDIAN
#define SWAP16(X) (X)
#define SWAP32(X) (X)
#else
#define SWAP16(X) SDL_Swap16(X)
#define SWAP32(X) SDL_Swap32(X)
#endif
static void headerbar_click(int x);
2002-02-05 08:51:38 +03:00
void switch_to_windowed(void)
{
SDL_Surface *tmp;
SDL_Rect src, dst;
src.x = 0; src.y = 0;
src.w = res_x; src.h = res_y;
dst.x = 0; dst.y = 0;
tmp = SDL_CreateRGBSurface(
SDL_SWSURFACE,
res_x,
res_y,
32,
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
0xff000000,
0x00ff0000,
0x0000ff00,
0x000000ff
#else
0x000000ff,
0x0000ff00,
0x00ff0000,
0xff000000
#endif
);
SDL_BlitSurface(sdl_fullscreen,&src,tmp,&dst);
SDL_UpdateRect(tmp,0,0,res_x,res_y);
SDL_FreeSurface(sdl_fullscreen);
sdl_fullscreen = NULL;
sdl_screen = SDL_SetVideoMode(res_x,res_y+headerbar_height,32, SDL_SWSURFACE);
dst.y = headerbar_height;
SDL_BlitSurface(tmp,&src,sdl_screen,&dst);
SDL_UpdateRect(tmp,0,0,res_x,res_y+headerbar_height);
SDL_FreeSurface(tmp);
SDL_ShowCursor(1);
SDL_WM_GrabInput(SDL_GRAB_OFF);
bx_gui.show_headerbar();
sdl_grab = 0;
}
void switch_to_fullscreen(void)
{
SDL_Surface *tmp;
SDL_Rect src, dst;
src.x = 0; src.y = headerbar_height;
src.w = res_x; src.h = res_y;
dst.x = 0; dst.y = 0;
tmp = SDL_CreateRGBSurface(
SDL_SWSURFACE,
res_x,
res_y,
32,
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
0xff000000,
0x00ff0000,
0x0000ff00,
0x000000ff
#else
0x000000ff,
0x0000ff00,
0x00ff0000,
0xff000000
#endif
);
SDL_BlitSurface(sdl_screen,&src,tmp,&dst);
SDL_UpdateRect(tmp,0,0,res_x,res_y);
SDL_FreeSurface(sdl_screen);
sdl_screen = NULL;
sdl_fullscreen = SDL_SetVideoMode(res_x,res_y,32, SDL_HWSURFACE|SDL_FULLSCREEN);
src.y = 0;
SDL_BlitSurface(tmp,&src,sdl_fullscreen,&dst);
SDL_UpdateRect(tmp,0,0,res_x,res_y);
SDL_FreeSurface(tmp);
SDL_ShowCursor(0);
SDL_WM_GrabInput(SDL_GRAB_ON);
sdl_grab = 1;
}
2002-02-05 08:51:38 +03:00
void bx_gui_c::specific_init(
bx_gui_c *th,
int argc,
char **argv,
unsigned x_tilesize,
unsigned y_tilesize,
unsigned header_bar_y)
{
int i,j;
th->put("SDL");
2002-02-05 08:51:38 +03:00
tilewidth = x_tilesize;
tileheight = y_tilesize;
headerbar_height = header_bar_y;
for(i=0;i<256;i++)
for(j=0;j<16;j++)
bx_gui.vga_charmap[i*32+j] = sdl_font8x16[i][j];
2002-02-05 08:51:38 +03:00
for(i=0;i<256;i++)
for(j=0;j<8;j++)
menufont[i][j] = sdl_font8x8[i][j];
if( SDL_Init(SDL_INIT_VIDEO) < 0 )
{
LOG_THIS setonoff(LOGLEV_PANIC, ACT_FATAL);
BX_PANIC (("Unable to initialize SDL libraries"));
return;
}
atexit(SDL_Quit);
sdl_screen = NULL;
th->dimension_update(640,480);
sdl_fullscreen_toggle = 0;
2002-02-05 08:51:38 +03:00
SDL_EnableKeyRepeat(250,50);
SDL_WM_SetCaption(
#if BX_CPU_LEVEL < 2
"Bochs 8086 emulator, http://bochs.sourceforge.net/",
#elif BX_CPU_LEVEL == 2
"Bochs 80286 emulator, http://bochs.sourceforge.net/",
#elif BX_CPU_LEVEL == 3
"Bochs 80386 emulator, http://bochs.sourceforge.net/",
#elif BX_CPU_LEVEL == 4
"Bochs 80486 emulator, http://bochs.sourceforge.net/",
#else
"Bochs Pentium emulator, http://bochs.sourceforge.net/",
#endif
"Bochs" );
SDL_WarpMouse(res_x/2, res_y/2);
}
void bx_gui_c::text_update(
Bit8u *old_text,
Bit8u *new_text,
unsigned long cursor_x,
unsigned long cursor_y,
Bit16u cursor_state,
unsigned rows)
{
unsigned char font_row, *pfont_row;
unsigned long x,y;
int hchars,fontrows,fontpixels;
2002-02-05 08:51:38 +03:00
int fgcolor_ndx;
int bgcolor_ndx;
Uint32 fgcolor;
Uint32 bgcolor;
Uint32 *buf, *buf_row, *buf_char;
Uint32 disp;
Bit8u cs_start, cs_end, cs_line, mask;
Boolean invert;
cs_start = (cursor_state >> 8) & 0x3f;
cs_end = cursor_state & 0x1f;
2002-02-05 08:51:38 +03:00
if( sdl_screen )
{
disp = sdl_screen->pitch/4;
buf_row = (Uint32 *)sdl_screen->pixels + headerbar_height*disp;
}
else
{
disp = sdl_fullscreen->pitch/4;
buf_row = (Uint32 *)sdl_fullscreen->pixels;
}
2002-02-05 08:51:38 +03:00
do
{
buf = buf_row;
hchars = textres_x;
x = 0;
y = textres_y - rows;
2002-02-05 08:51:38 +03:00
do
{
// check if char needs to be updated
if( (old_text[0] != new_text[0])
|| (old_text[1] != new_text[1])
|| ((y == cursor_y) && (x == cursor_x))
|| ((y == prev_cursor_y) && (x == prev_cursor_x)) )
2002-02-05 08:51:38 +03:00
{
// Get Foreground/Background pixel colors
fgcolor_ndx = new_text[1] & 0x0F;
bgcolor_ndx = (new_text[1] >> 4) & 0x07;
fgcolor = palette[fgcolor_ndx];
bgcolor = palette[bgcolor_ndx];
invert = ( (y == cursor_y) && (x == cursor_x) && (cs_start < cs_end) );
2002-02-05 08:51:38 +03:00
// Display this one char
fontrows = fontheight;
pfont_row = &bx_gui.vga_charmap[(new_text[0] << 5)];
2002-02-05 08:51:38 +03:00
buf_char = buf;
do
{
font_row = *pfont_row++;
fontpixels = fontwidth;
cs_line = (fontheight - fontrows);
if( (invert) && (cs_line >= cs_start) && (cs_line <= cs_end) )
mask = 0x80;
else
mask = 0x00;
2002-02-05 08:51:38 +03:00
do
{
if( (font_row & 0x80) == mask )
2002-02-05 08:51:38 +03:00
*buf = bgcolor;
else
*buf = fgcolor;
buf++;
font_row = font_row << 1;
} while( --fontpixels );
buf -= fontwidth;
buf += disp;
2002-02-05 08:51:38 +03:00
} while( --fontrows );
// restore output buffer ptr to start of this char
buf = buf_char;
}
// move to next char location on screen
buf += fontwidth;
// select next char in old/new text
new_text+=2;
old_text+=2;
x++;
2002-02-05 08:51:38 +03:00
// process one entire horizontal row
} while( --hchars );
// go to next character row location
buf_row += disp * fontheight;
2002-02-05 08:51:38 +03:00
} while( --rows );
prev_cursor_x = cursor_x;
prev_cursor_y = cursor_y;
2002-02-05 08:51:38 +03:00
}
int
bx_gui_c::get_clipboard_text(Bit8u **bytes, Bit32s *nbytes)
{
return 0;
}
int
bx_gui_c::set_clipboard_text(char *text_snapshot, Bit32u len)
{
return 0;
}
2002-02-05 08:51:38 +03:00
void bx_gui_c::graphics_tile_update(
Bit8u *snapshot,
unsigned x,
unsigned y)
{
Uint32 *buf, disp;
Uint32 *buf_row;
2002-02-05 08:51:38 +03:00
int i,j;
if( sdl_screen )
{
disp = sdl_screen->pitch/4;
buf = (Uint32 *)sdl_screen->pixels + (headerbar_height+y)*disp + x;
}
else
{
disp = sdl_fullscreen->pitch/4;
buf = (Uint32 *)sdl_fullscreen->pixels + y*disp + x;
}
i = tileheight;
if( i + y > res_y ) i = res_y - y;
// FIXME
if( i<=0 ) return;
do
2002-02-05 08:51:38 +03:00
{
buf_row = buf;
j = tilewidth;
do
2002-02-05 08:51:38 +03:00
{
*buf++ = palette[*snapshot++];
} while( --j );
buf = buf_row + disp;
} while( --i);
2002-02-05 08:51:38 +03:00
}
void bx_gui_c::handle_events(void)
{
Bit32u key_event;
Bit8u mouse_state;
2002-02-05 08:51:38 +03:00
while( SDL_PollEvent(&sdl_event) )
{
switch( sdl_event.type )
{
case SDL_VIDEOEXPOSE:
if( sdl_fullscreen_toggle == 0 )
SDL_UpdateRect( sdl_screen, 0,0, res_x, res_y+headerbar_height );
else
SDL_UpdateRect( sdl_screen, 0,headerbar_height, res_x, res_y );
2002-02-05 08:51:38 +03:00
break;
case SDL_MOUSEMOTION:
new_mousebuttons = ((sdl_event.motion.state & 0x01)|((sdl_event.motion.state>>1)&0x02));
bx_devices.keyboard->mouse_motion(
sdl_event.motion.xrel,
-sdl_event.motion.yrel,
new_mousebuttons );
old_mousebuttons = new_mousebuttons;
old_mousex = (int)(sdl_event.motion.x);
old_mousey = (int)(sdl_event.motion.y);
break;
case SDL_MOUSEBUTTONDOWN:
if( (sdl_event.button.button == SDL_BUTTON_MIDDLE)
&& (sdl_fullscreen_toggle == 0) )
{
if( sdl_grab == 0 )
{
SDL_ShowCursor(0);
SDL_WM_GrabInput(SDL_GRAB_ON);
}
else
{
SDL_ShowCursor(1);
SDL_WM_GrabInput(SDL_GRAB_OFF);
}
sdl_grab = ~sdl_grab;
toggle_mouse_enable();
break;
} else if (sdl_event.button.y < headerbar_height) {
headerbar_click(sdl_event.button.x);
break;
}
case SDL_MOUSEBUTTONUP:
// figure out mouse state
new_mousex = (int)(sdl_event.button.x);
new_mousey = (int)(sdl_event.button.y);
// SDL_GetMouseState() returns the state of all buttons
mouse_state = SDL_GetMouseState(NULL, NULL);
new_mousebuttons =
(mouse_state & 0x01) |
((mouse_state>>1)&0x02) |
((mouse_state<<1)&0x04) ;
// filter out middle button if not fullscreen
if( sdl_fullscreen_toggle == 0 )
new_mousebuttons &= 0x03;
// send motion information
bx_devices.keyboard->mouse_motion(
new_mousex - old_mousex,
-(new_mousey - old_mousey),
new_mousebuttons );
// mark current state to diff with next packet
old_mousebuttons = new_mousebuttons;
old_mousex = new_mousex;
old_mousey = new_mousey;
break;
2002-02-05 08:51:38 +03:00
case SDL_KEYDOWN:
// Windows/Fullscreen toggle-check
2002-02-05 08:51:38 +03:00
if( sdl_event.key.keysym.sym == SDLK_SCROLLOCK )
{
// SDL_WM_ToggleFullScreen( sdl_screen );
sdl_fullscreen_toggle = ~sdl_fullscreen_toggle;
if( sdl_fullscreen_toggle == 0 )
switch_to_windowed();
else
switch_to_fullscreen();
bx_gui.show_headerbar();
bx_gui.flush();
2002-02-05 08:51:38 +03:00
break;
}
// convert scancode->bochs code
2002-02-05 08:51:38 +03:00
if( sdl_event.key.keysym.scancode > _SCN2BX_LAST_ ) break;
key_event = scancodes2bx[ FIX_SDL_SCANCODE(sdl_event.key.keysym.scancode) ][1];
2002-02-05 08:51:38 +03:00
if( key_event == 0 ) break;
bx_devices.keyboard->gen_scancode( key_event );
break;
2002-02-05 08:51:38 +03:00
case SDL_KEYUP:
// filter out release of Windows/Fullscreen toggle and unsupported keys
if( (sdl_event.key.keysym.sym != SDLK_SCROLLOCK)
&& (sdl_event.key.keysym.scancode < _SCN2BX_LAST_ ))
{
// convert scancode->bochs code
key_event = scancodes2bx[ FIX_SDL_SCANCODE(sdl_event.key.keysym.scancode) ][1];
if( key_event == 0 ) break;
bx_devices.keyboard->gen_scancode( key_event | BX_KEY_RELEASED );
}
2002-02-05 08:51:38 +03:00
break;
2002-02-05 08:51:38 +03:00
case SDL_QUIT:
LOG_THIS setonoff(LOGLEV_PANIC, ACT_FATAL);
BX_PANIC (("User requested shutdown."));
}
}
}
void bx_gui_c::flush(void)
{
if( sdl_screen )
SDL_UpdateRect( sdl_screen,0,0,res_x,res_y+headerbar_height );
else
SDL_UpdateRect( sdl_fullscreen,0,0,res_x,res_y);
2002-02-05 08:51:38 +03:00
}
void bx_gui_c::clear_screen(void)
{
int i = res_y, j;
Uint32 color;
Uint32 *buf, *buf_row;
Uint32 disp;
2002-02-05 08:51:38 +03:00
if( sdl_screen )
2002-02-05 08:51:38 +03:00
{
color = SDL_MapRGB( sdl_screen->format, 0,0,0 );
disp = sdl_screen->pitch/4;
buf = (Uint32 *)sdl_screen->pixels + headerbar_height*disp;
}
else if( sdl_fullscreen )
{
color = SDL_MapRGB( sdl_fullscreen->format, 0,0,0 );
disp = sdl_fullscreen->pitch/4;
buf = (Uint32 *)sdl_fullscreen->pixels;
2002-02-05 08:51:38 +03:00
}
else return;
do
{
buf_row = buf;
j = res_x;
while( j-- ) *buf++ = color;
buf = buf_row + disp;
} while( --i );
if( sdl_screen )
SDL_UpdateRect(sdl_screen,0,0,res_x,res_y+headerbar_height);
else
SDL_UpdateRect(sdl_fullscreen,0,0,res_x,res_y);
2002-02-05 08:51:38 +03:00
}
Boolean bx_gui_c::palette_change(
unsigned index,
unsigned red,
unsigned green,
unsigned blue)
{
unsigned char palred = red & 0xFF;
unsigned char palgreen = green & 0xFF;
unsigned char palblue = blue & 0xFF;
if( index > 255 ) return 0;
if( sdl_screen )
palette[index] = SDL_MapRGB( sdl_screen->format, palred, palgreen, palblue );
else if( sdl_fullscreen )
palette[index] = SDL_MapRGB( sdl_fullscreen->format, palred, palgreen, palblue );
2002-02-05 08:51:38 +03:00
return 1;
}
void bx_gui_c::dimension_update(
unsigned x,
unsigned y,
unsigned fheight)
2002-02-05 08:51:38 +03:00
{
// TODO: remove this stupid check whenever the vga driver is fixed
if( y == 208 ) y = 200;
if( fheight > 0 )
{
if (bx_gui.charmap_changed) bx_gui.clear_screen();
bx_gui.charmap_changed = 0;
fontheight = fheight;
fontwidth = 8;
}
2002-02-05 08:51:38 +03:00
if( (x == res_x) && (y == res_y )) return;
if( sdl_screen )
{
2002-02-05 08:51:38 +03:00
SDL_FreeSurface( sdl_screen );
sdl_screen = NULL;
}
if( sdl_fullscreen )
2002-02-05 08:51:38 +03:00
{
SDL_FreeSurface( sdl_fullscreen );
sdl_fullscreen = NULL;
}
if( sdl_fullscreen_toggle == 0 )
{
sdl_screen = SDL_SetVideoMode( x, y+headerbar_height, 32, SDL_SWSURFACE );
if( !sdl_screen )
{
LOG_THIS setonoff(LOGLEV_PANIC, ACT_FATAL);
BX_PANIC (("Unable to set requested videomode: %ix%i: %s",x,y,SDL_GetError()));
}
headerbar_fg = SDL_MapRGB(
sdl_screen->format,
BX_HEADERBAR_FG_RED,
BX_HEADERBAR_FG_GREEN,
BX_HEADERBAR_FG_BLUE );
headerbar_bg = SDL_MapRGB(
sdl_screen->format,
BX_HEADERBAR_BG_RED,
BX_HEADERBAR_BG_GREEN,
BX_HEADERBAR_BG_BLUE );
}
else
{
sdl_fullscreen = SDL_SetVideoMode( x, y, 32, SDL_HWSURFACE|SDL_FULLSCREEN );
if( !sdl_fullscreen )
{
LOG_THIS setonoff(LOGLEV_PANIC, ACT_FATAL);
BX_PANIC (("Unable to set requested videomode: %ix%i: %s",x,y,SDL_GetError()));
}
2002-02-05 08:51:38 +03:00
}
res_x = x;
res_y = y;
if( fheight > 0 )
{
textres_x = x / fontwidth;
textres_y = y / fontheight;
}
bx_gui.show_headerbar();
2002-02-05 08:51:38 +03:00
}
unsigned bx_gui_c::create_bitmap(
const unsigned char *bmap,
unsigned xdim,
unsigned ydim)
{
bitmaps *tmp = new bitmaps;
Uint32 *buf, *buf_row;
Uint32 disp;
unsigned char pixels;
if (n_sdl_bitmaps >= MAX_SDL_BITMAPS) {
BX_PANIC (("too many SDL bitmaps. To fix, increase MAX_SDL_BITMAPS"));
return 0;
}
tmp->surface = SDL_CreateRGBSurface(
SDL_SWSURFACE,
xdim,
ydim,
32,
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
0xff000000,
0x00ff0000,
0x0000ff00,
0x00000000
#else
0x000000ff,
0x0000ff00,
0x00ff0000,
0x00000000
#endif
);
if( !tmp->surface )
{
delete tmp;
bx_gui.exit();
LOG_THIS setonoff(LOGLEV_PANIC, ACT_FATAL);
BX_PANIC (("Unable to create requested bitmap"));
}
tmp->src.w = xdim;
tmp->src.h = ydim;
tmp->src.x = 0;
tmp->src.y = 0;
tmp->dst.x = -1;
tmp->dst.y = 0;
tmp->dst.w = xdim;
tmp->dst.h = ydim;
tmp->cb = NULL;
buf = (Uint32 *)tmp->surface->pixels;
disp = tmp->surface->pitch/4;
do
{
buf_row = buf;
xdim = tmp->src.w / 8;
do
{
pixels = *bmap++;
for(unsigned i=0;i<8;i++)
{
if( (pixels & 0x01) == 0 )
*buf++ = headerbar_bg;
else
*buf++ = headerbar_fg;
pixels = pixels >> 1;
}
} while( --xdim );
buf = buf_row + disp;
} while( --ydim );
SDL_UpdateRect(
tmp->surface,
0, 0,
tmp->src.w,
tmp->src.h );
sdl_bitmaps[n_sdl_bitmaps] = tmp;
return n_sdl_bitmaps++;
2002-02-05 08:51:38 +03:00
}
unsigned bx_gui_c::headerbar_bitmap(
unsigned bmap_id,
unsigned alignment,
void (*f)(void))
{
unsigned hb_index;
if( bmap_id >= (unsigned)n_sdl_bitmaps ) return 0;
if ( (bx_headerbar_entries+1) > BX_MAX_HEADERBAR_ENTRIES )
BX_PANIC(("too many headerbar entries, increase BX_MAX_HEADERBAR_ENTRIES"));
bx_headerbar_entries++;
hb_index = bx_headerbar_entries - 1;
hb_entry[hb_index].bmp_id = bmap_id;
hb_entry[hb_index].alignment = alignment;
hb_entry[hb_index].f = f;
if (alignment == BX_GRAVITY_LEFT) {
sdl_bitmaps[bmap_id]->dst.x = bx_bitmap_left_xorigin;
bx_bitmap_left_xorigin += sdl_bitmaps[bmap_id]->src.w;
} else {
bx_bitmap_right_xorigin += sdl_bitmaps[bmap_id]->src.w;
sdl_bitmaps[bmap_id]->dst.x = bx_bitmap_right_xorigin;
}
return hb_index;
2002-02-05 08:51:38 +03:00
}
void bx_gui_c::replace_bitmap(
unsigned hbar_id,
unsigned bmap_id)
{
SDL_Rect hb_dst;
unsigned old_id;
old_id = hb_entry[hbar_id].bmp_id;
hb_dst = sdl_bitmaps[old_id]->dst;
sdl_bitmaps[old_id]->dst.x = -1;
hb_entry[hbar_id].bmp_id = bmap_id;
sdl_bitmaps[bmap_id]->dst.x = hb_dst.x;
if( sdl_bitmaps[bmap_id]->dst.x != -1 )
{
if (hb_entry[hbar_id].alignment == BX_GRAVITY_RIGHT) {
hb_dst.x = res_x - hb_dst.x;
}
SDL_BlitSurface(
sdl_bitmaps[bmap_id]->surface,
&sdl_bitmaps[bmap_id]->src,
sdl_screen,
&hb_dst);
SDL_UpdateRect(
sdl_screen,
hb_dst.x,
sdl_bitmaps[bmap_id]->dst.y,
sdl_bitmaps[bmap_id]->src.w,
sdl_bitmaps[bmap_id]->src.h );
}
2002-02-05 08:51:38 +03:00
}
void bx_gui_c::show_headerbar(void)
{
Uint32 *buf;
Uint32 *buf_row;
Uint32 disp;
int rowsleft = headerbar_height;
int colsleft;
int bitmapscount = bx_headerbar_entries;
unsigned current_bmp;
SDL_Rect hb_dst;
if( !sdl_screen ) return;
disp = sdl_screen->pitch/4;
buf = (Uint32 *)sdl_screen->pixels;
// draw headerbar background
do
{
colsleft = res_x;
buf_row = buf;
do
{
*buf++ = headerbar_bg;
} while( --colsleft );
buf = buf_row + disp;
} while( --rowsleft );
SDL_UpdateRect( sdl_screen, 0,0,res_x,headerbar_height);
2002-02-05 08:51:38 +03:00
we_are_here();
// go thru the bitmaps and display the active ones
while( bitmapscount-- )
{
current_bmp = hb_entry[bitmapscount].bmp_id;
if( sdl_bitmaps[current_bmp]->dst.x != -1 )
{
hb_dst = sdl_bitmaps[current_bmp]->dst;
if (hb_entry[bitmapscount].alignment == BX_GRAVITY_RIGHT) {
hb_dst.x = res_x - hb_dst.x;
}
SDL_BlitSurface(
sdl_bitmaps[current_bmp]->surface,
&sdl_bitmaps[current_bmp]->src,
sdl_screen,
&hb_dst);
SDL_UpdateRect(
sdl_screen,
hb_dst.x,
sdl_bitmaps[current_bmp]->dst.y,
sdl_bitmaps[current_bmp]->src.w,
sdl_bitmaps[current_bmp]->src.h );
}
}
2002-02-05 08:51:38 +03:00
}
void bx_gui_c::mouse_enabled_changed_specific (Boolean val)
{
if( val == 1 )
{
SDL_ShowCursor(0);
SDL_WM_GrabInput(SDL_GRAB_ON);
}
else
{
SDL_ShowCursor(1);
SDL_WM_GrabInput(SDL_GRAB_OFF);
}
sdl_grab = val;
2002-02-05 08:51:38 +03:00
}
void headerbar_click(int x)
{
int xdim,xorigin;
for (unsigned i=0; i<bx_headerbar_entries; i++) {
xdim = sdl_bitmaps[hb_entry[i].bmp_id]->src.w;
if (hb_entry[i].alignment == BX_GRAVITY_LEFT)
xorigin = sdl_bitmaps[hb_entry[i].bmp_id]->dst.x;
else
xorigin = res_x - sdl_bitmaps[hb_entry[i].bmp_id]->dst.x;
if ( (x>=xorigin) && (x<(xorigin+xdim)) ) {
hb_entry[i].f();
return;
}
}
}
2002-02-05 08:51:38 +03:00
void bx_gui_c::exit(void)
{
if( sdl_screen )
SDL_FreeSurface(sdl_screen);
if( sdl_fullscreen )
SDL_FreeSurface(sdl_fullscreen);
while( n_sdl_bitmaps )
{
SDL_FreeSurface( sdl_bitmaps[n_sdl_bitmaps-1]->surface );
n_sdl_bitmaps--;
}
2002-02-05 08:51:38 +03:00
}