gui.cpp

Go to the documentation of this file.
00001 /* ES40 emulator.
00002  * Copyright (C) 2007-2008 by the ES40 Emulator Project
00003  *
00004  * WWW    : http://sourceforge.net/projects/es40
00005  * E-mail : camiel@camicom.com
00006  * 
00007  *  This file is based upon Bochs.
00008  *
00009  *  Copyright (C) 2002  MandrakeSoft S.A.
00010  *
00011  *    MandrakeSoft S.A.
00012  *    43, rue d'Aboukir
00013  *    75002 Paris - France
00014  *    http://www.linux-mandrake.com/
00015  *    http://www.mandrakesoft.com/
00016  *
00017  *  This library is free software; you can redistribute it and/or
00018  *  modify it under the terms of the GNU Lesser General Public
00019  *  License as published by the Free Software Foundation; either
00020  *  version 2 of the License, or (at your option) any later version.
00021  *
00022  *  This library is distributed in the hope that it will be useful,
00023  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00024  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00025  *  Lesser General Public License for more details.
00026  *
00027  *  You should have received a copy of the GNU Lesser General Public
00028  *  License along with this library; if not, write to the Free Software
00029  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00030  */
00031 
00069 //#define DEBUG_LOCKS
00070 //#define NO_LOCK_TIMEOUTS
00071 
00072 #include "../StdAfx.h"
00073 
00074 #include <signal.h>
00075 
00076 #include "gui.h"
00077 
00078 bx_gui_c*   bx_gui = NULL;
00079 
00080 #define BX_KEY_UNKNOWN  0x7fffffff
00081 #define N_USER_KEYS     36
00082 
00083 typedef struct
00084 {
00085   const char*   key;
00086   u32     symbol;
00087 } user_key_t;
00088 
00089 static user_key_t user_keys[N_USER_KEYS] =
00090 {
00091   { "f1",    BX_KEY_F1 },
00092   { "f2",    BX_KEY_F2 },
00093   { "f3",    BX_KEY_F3 },
00094   { "f4",    BX_KEY_F4 },
00095   { "f5",    BX_KEY_F5 },
00096   { "f6",    BX_KEY_F6 },
00097   { "f7",    BX_KEY_F7 },
00098   { "f8",    BX_KEY_F8 },
00099   { "f9",    BX_KEY_F9 },
00100   { "f10",   BX_KEY_F10 },
00101   { "f11",   BX_KEY_F11 },
00102   { "f12",   BX_KEY_F12 },
00103   { "alt",   BX_KEY_ALT_L },
00104   { "bksl",  BX_KEY_BACKSLASH },
00105   { "bksp",  BX_KEY_BACKSPACE },
00106   { "ctrl",  BX_KEY_CTRL_L },
00107   { "del",   BX_KEY_DELETE },
00108   { "down",  BX_KEY_DOWN },
00109   { "end",   BX_KEY_END },
00110   { "enter", BX_KEY_ENTER },
00111   { "esc",   BX_KEY_ESC },
00112   { "home",  BX_KEY_HOME },
00113   { "ins",   BX_KEY_INSERT },
00114   { "left",  BX_KEY_LEFT },
00115   { "menu",  BX_KEY_MENU },
00116   { "minus", BX_KEY_MINUS },
00117   { "pgdwn", BX_KEY_PAGE_DOWN },
00118   { "pgup",  BX_KEY_PAGE_UP },
00119   { "plus",  BX_KEY_KP_ADD },
00120   { "right", BX_KEY_RIGHT },
00121   { "shift", BX_KEY_SHIFT_L },
00122   { "space", BX_KEY_SPACE },
00123   { "tab",   BX_KEY_TAB },
00124   { "up",    BX_KEY_UP },
00125   { "win",   BX_KEY_WIN_L },
00126   { "print", BX_KEY_PRINT }
00127 };
00128 
00129 bx_gui_c::bx_gui_c(void)
00130 {
00131   framebuffer = NULL;
00132   guiMutex = new CMutex("gui-lock");
00133 }
00134 
00135 bx_gui_c::~bx_gui_c()
00136 {
00137   if(framebuffer != NULL)
00138   {
00139     delete[] framebuffer;
00140   }
00141 }
00142 
00143 void bx_gui_c::init(unsigned tilewidth, unsigned tileheight)
00144 {
00145   new_gfx_api = 0;
00146   host_xres = 640;
00147   host_yres = 480;
00148   host_bpp = 8;
00149 
00150   specific_init(tilewidth, tileheight);
00151 
00152   charmap_updated = 0;
00153 
00154   if(!new_gfx_api && (framebuffer == NULL))
00155   {
00156     framebuffer = new u8[BX_MAX_XRES * BX_MAX_YRES * 4];
00157   }
00158 }
00159 
00160 void bx_gui_c::cleanup(void)
00161 { }
00162 u32 get_user_key(char* key)
00163 {
00164   int i = 0;
00165 
00166   while(i < N_USER_KEYS)
00167   {
00168     if(!strcmp(key, user_keys[i].key))
00169       return user_keys[i].symbol;
00170     i++;
00171   }
00172 
00173   return BX_KEY_UNKNOWN;
00174 }
00175 
00176 void bx_gui_c::mouse_enabled_changed(bool val)
00177 {
00178 
00179   // This is only called when SIM->get_init_done is 1.  Note that VAL
00180   // is the new value of mouse_enabled, which may not match the old
00181   // value which is still in SIM->get_param_bool(BXPN_MOUSE_ENABLED)->get().
00182   bx_gui->mouse_enabled_changed_specific(val);
00183 }
00184 
00185 void bx_gui_c::init_signal_handlers()
00186 {
00187 #if BX_GUI_SIGHANDLER
00188   if(bx_gui_sighandler)
00189   {
00190     u32 mask = bx_gui->get_sighandler_mask();
00191     for(u32 sig = 0; sig < 32; sig++)
00192     {
00193       if(mask & (1 << sig))
00194         signal(sig, bx_signal_handler);
00195     }
00196   }
00197 #endif
00198 }
00199 
00200 void bx_gui_c::set_text_charmap(u8* fbuffer)
00201 {
00202   memcpy(&bx_gui->vga_charmap, fbuffer, 0x2000);
00203   for(unsigned i = 0; i < 256; i++)
00204     bx_gui->char_changed[i] = 1;
00205   bx_gui->charmap_updated = 1;
00206 }
00207 
00208 void bx_gui_c::set_text_charbyte(u16 address, u8 data)
00209 {
00210   bx_gui->vga_charmap[address] = data;
00211   bx_gui->char_changed[address >> 5] = 1;
00212   bx_gui->charmap_updated = 1;
00213 }
00214 
00215 void bx_gui_c::beep_on(float frequency)
00216 {
00217   BX_INFO(("GUI Beep ON (frequency=%.2f)", frequency));
00218 }
00219 
00220 void bx_gui_c::beep_off()
00221 {
00222   BX_INFO(("GUI Beep OFF"));
00223 }
00224 
00225 void bx_gui_c::get_capabilities(u16* xres, u16* yres, u16* bpp)
00226 {
00227   *xres = 1024;
00228   *yres = 768;
00229   *bpp = 32;
00230 }
00231 
00232 bx_svga_tileinfo_t* bx_gui_c::graphics_tile_info(bx_svga_tileinfo_t* info)
00233 {
00234   if(!info)
00235   {
00236     info = (bx_svga_tileinfo_t*) malloc(sizeof(bx_svga_tileinfo_t));
00237     if(!info)
00238     {
00239       return NULL;
00240     }
00241   }
00242 
00243   host_pitch = host_xres * ((host_bpp + 1) >> 3);
00244 
00245   info->bpp = host_bpp;
00246   info->pitch = host_pitch;
00247   switch(info->bpp)
00248   {
00249   case 15:
00250     info->red_shift = 15;
00251     info->green_shift = 10;
00252     info->blue_shift = 5;
00253     info->red_mask = 0x7c00;
00254     info->green_mask = 0x03e0;
00255     info->blue_mask = 0x001f;
00256     break;
00257 
00258   case 16:
00259     info->red_shift = 16;
00260     info->green_shift = 11;
00261     info->blue_shift = 5;
00262     info->red_mask = 0xf800;
00263     info->green_mask = 0x07e0;
00264     info->blue_mask = 0x001f;
00265     break;
00266 
00267   case 24:
00268   case 32:
00269     info->red_shift = 24;
00270     info->green_shift = 16;
00271     info->blue_shift = 8;
00272     info->red_mask = 0xff0000;
00273     info->green_mask = 0x00ff00;
00274     info->blue_mask = 0x0000ff;
00275     break;
00276   }
00277 
00278   info->is_indexed = (host_bpp == 8);
00279 #ifdef BX_LITTLE_ENDIAN
00280   info->is_little_endian = 1;
00281 #else
00282   info->is_little_endian = 0;
00283 #endif
00284   return info;
00285 }
00286 
00287 u8* bx_gui_c::graphics_tile_get(unsigned x0, unsigned y0, unsigned*  w,
00288                                 unsigned*  h)
00289 {
00290   if(x0 + X_TILESIZE > host_xres)
00291   {
00292     *w = host_xres - x0;
00293   }
00294   else
00295   {
00296     *w = X_TILESIZE;
00297   }
00298 
00299   if(y0 + Y_TILESIZE > host_yres)
00300   {
00301     *h = host_yres - y0;
00302   }
00303   else
00304   {
00305     *h = Y_TILESIZE;
00306   }
00307 
00308   return (u8*) framebuffer + y0 * host_pitch + x0 * ((host_bpp + 1) >> 3);
00309 }
00310 
00311 void bx_gui_c::graphics_tile_update_in_place(unsigned x0, unsigned y0,
00312                                              unsigned w, unsigned h)
00313 {
00314   u8    tile[X_TILESIZE * Y_TILESIZE * 4];
00315   u8*   tile_ptr;
00316   u8 *fb_ptr;
00317   u16   xc;
00318   u16   yc;
00319   u16   fb_pitch;
00320   u16   tile_pitch;
00321   u8    r;
00322   u8    diffx;
00323   u8    diffy;
00324 
00325   diffx = (x0 % X_TILESIZE);
00326   diffy = (y0 % Y_TILESIZE);
00327   if(diffx > 0)
00328   {
00329     x0 -= diffx;
00330     w += diffx;
00331   }
00332 
00333   if(diffy > 0)
00334   {
00335     y0 -= diffy;
00336     h += diffy;
00337   }
00338 
00339   fb_pitch = host_pitch;
00340   tile_pitch = X_TILESIZE * ((host_bpp + 1) >> 3);
00341   for(yc = y0; yc < (y0 + h); yc += Y_TILESIZE)
00342   {
00343     for(xc = x0; xc < (x0 + w); xc += X_TILESIZE)
00344     {
00345       fb_ptr = framebuffer + (yc * fb_pitch + xc * ((host_bpp + 1) >> 3));
00346       tile_ptr = &tile[0];
00347       for(r = 0; r < h; r++)
00348       {
00349         memcpy(tile_ptr, fb_ptr, tile_pitch);
00350         fb_ptr += fb_pitch;
00351         tile_ptr += tile_pitch;
00352       }
00353 
00354       graphics_tile_update(tile, xc, yc);
00355     }
00356   }
00357 }
00358 
00359 void bx_gui_c::lock()
00360 {
00361   MUTEX_LOCK(guiMutex);
00362 }
00363 
00364 void bx_gui_c::unlock()
00365 {
00366   MUTEX_UNLOCK(guiMutex);
00367 }

SourceForge.net Logo
Project space on SourceForge.net