Bochs/bochs/gui/x.cc

2776 lines
79 KiB
C++
Raw Normal View History

/////////////////////////////////////////////////////////////////////////
// $Id$
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001-2016 The Bochs Project
//
// 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#define XK_PUBLISHING
#define XK_TECHNICAL
Add plugin support to Bochs by merging all the changes from the BRANCH_PLUGINS branch! Authors: Bryce Denney Christophe Bothamy Kevin Lawton (we grabbed a lot of plugin code from plex86) Testing help from: Volker Ruppert Don Becker (Psyon) Jeremy Parsons (Br'fin) The change log is too long to paste in here. To read the change log, do cvs log patches/patch.final-from-BRANCH_PLUGINS.gz All the changes and a detailed description are contained in a patch called patch.final-from-BRANCH_PLUGINS.gz. To look at the complete patch, do cvs upd -r1.1 patches/patch.final-from-BRANCH_PLUGINS.gz Then you will have a local copy of the patch, which you can gunzip and play with however you want. Modified Files: .bochsrc Makefile.in aclocal.m4 bochs.h config.h.in configure configure.in gdbstub.cc logio.cc main.cc pc_system.cc pc_system.h state_file.h bios/Makefile.in bios/rombios.c cpu/Makefile.in cpu/access.cc cpu/apic.cc cpu/arith16.cc cpu/arith32.cc cpu/arith8.cc cpu/cpu.cc cpu/cpu.h cpu/ctrl_xfer32.cc cpu/exception.cc cpu/fetchdecode.cc cpu/fetchdecode64.cc cpu/flag_ctrl.cc cpu/flag_ctrl_pro.cc cpu/init.cc cpu/io.cc cpu/logical16.cc cpu/logical32.cc cpu/logical8.cc cpu/paging.cc cpu/proc_ctrl.cc cpu/protect_ctrl.cc cpu/segment_ctrl_pro.cc cpu/shift16.cc cpu/shift32.cc cpu/stack64.cc cpu/string.cc cpu/tasking.cc debug/Makefile.in debug/dbg_main.cc disasm/Makefile.in doc/docbook/user/user.dbk dynamic/Makefile.in fpu/Makefile.in gui/Makefile.in gui/amigaos.cc gui/beos.cc gui/carbon.cc gui/control.cc gui/control.h gui/gui.cc gui/gui.h gui/keymap.cc gui/keymap.h gui/macintosh.cc gui/nogui.cc gui/rfb.cc gui/sdl.cc gui/sdlkeys.h gui/siminterface.cc gui/siminterface.h gui/term.cc gui/win32.cc gui/wx.cc gui/wxdialog.cc gui/wxdialog.h gui/wxmain.cc gui/wxmain.h gui/x.cc gui/keymaps/sdl-pc-de.map gui/keymaps/sdl-pc-us.map gui/keymaps/x11-pc-de.map instrument/example0/instrument.h instrument/example1/instrument.h instrument/stubs/instrument.cc instrument/stubs/instrument.h iodev/Makefile.in iodev/biosdev.cc iodev/biosdev.h iodev/cdrom.cc iodev/cmos.cc iodev/cmos.h iodev/devices.cc iodev/dma.cc iodev/dma.h iodev/eth_fbsd.cc iodev/eth_linux.cc iodev/eth_null.cc iodev/eth_tap.cc iodev/floppy.cc iodev/floppy.h iodev/guest2host.cc iodev/guest2host.h iodev/harddrv.cc iodev/harddrv.h iodev/iodebug.cc iodev/iodebug.h iodev/iodev.h iodev/keyboard.cc iodev/keyboard.h iodev/ne2k.cc iodev/ne2k.h iodev/parallel.cc iodev/parallel.h iodev/pci.cc iodev/pci.h iodev/pci2isa.cc iodev/pci2isa.h iodev/pic.cc iodev/pic.h iodev/pit.cc iodev/pit.h iodev/pit_wrap.cc iodev/pit_wrap.h iodev/sb16.cc iodev/sb16.h iodev/scancodes.cc iodev/scancodes.h iodev/serial.cc iodev/serial.h iodev/slowdown_timer.cc iodev/slowdown_timer.h iodev/unmapped.cc iodev/unmapped.h iodev/vga.cc iodev/vga.h memory/Makefile.in memory/memory.cc memory/memory.h memory/misc_mem.cc misc/bximage.c misc/niclist.c Added Files: README-plugins extplugin.h ltdl.c ltdl.h ltdlconf.h.in ltmain.sh plugin.cc plugin.h
2002-10-25 01:07:56 +04:00
// Define BX_PLUGGABLE in files that can be compiled into plugins. For
// platforms that require a special tag on exported symbols, BX_PLUGGABLE
Add plugin support to Bochs by merging all the changes from the BRANCH_PLUGINS branch! Authors: Bryce Denney Christophe Bothamy Kevin Lawton (we grabbed a lot of plugin code from plex86) Testing help from: Volker Ruppert Don Becker (Psyon) Jeremy Parsons (Br'fin) The change log is too long to paste in here. To read the change log, do cvs log patches/patch.final-from-BRANCH_PLUGINS.gz All the changes and a detailed description are contained in a patch called patch.final-from-BRANCH_PLUGINS.gz. To look at the complete patch, do cvs upd -r1.1 patches/patch.final-from-BRANCH_PLUGINS.gz Then you will have a local copy of the patch, which you can gunzip and play with however you want. Modified Files: .bochsrc Makefile.in aclocal.m4 bochs.h config.h.in configure configure.in gdbstub.cc logio.cc main.cc pc_system.cc pc_system.h state_file.h bios/Makefile.in bios/rombios.c cpu/Makefile.in cpu/access.cc cpu/apic.cc cpu/arith16.cc cpu/arith32.cc cpu/arith8.cc cpu/cpu.cc cpu/cpu.h cpu/ctrl_xfer32.cc cpu/exception.cc cpu/fetchdecode.cc cpu/fetchdecode64.cc cpu/flag_ctrl.cc cpu/flag_ctrl_pro.cc cpu/init.cc cpu/io.cc cpu/logical16.cc cpu/logical32.cc cpu/logical8.cc cpu/paging.cc cpu/proc_ctrl.cc cpu/protect_ctrl.cc cpu/segment_ctrl_pro.cc cpu/shift16.cc cpu/shift32.cc cpu/stack64.cc cpu/string.cc cpu/tasking.cc debug/Makefile.in debug/dbg_main.cc disasm/Makefile.in doc/docbook/user/user.dbk dynamic/Makefile.in fpu/Makefile.in gui/Makefile.in gui/amigaos.cc gui/beos.cc gui/carbon.cc gui/control.cc gui/control.h gui/gui.cc gui/gui.h gui/keymap.cc gui/keymap.h gui/macintosh.cc gui/nogui.cc gui/rfb.cc gui/sdl.cc gui/sdlkeys.h gui/siminterface.cc gui/siminterface.h gui/term.cc gui/win32.cc gui/wx.cc gui/wxdialog.cc gui/wxdialog.h gui/wxmain.cc gui/wxmain.h gui/x.cc gui/keymaps/sdl-pc-de.map gui/keymaps/sdl-pc-us.map gui/keymaps/x11-pc-de.map instrument/example0/instrument.h instrument/example1/instrument.h instrument/stubs/instrument.cc instrument/stubs/instrument.h iodev/Makefile.in iodev/biosdev.cc iodev/biosdev.h iodev/cdrom.cc iodev/cmos.cc iodev/cmos.h iodev/devices.cc iodev/dma.cc iodev/dma.h iodev/eth_fbsd.cc iodev/eth_linux.cc iodev/eth_null.cc iodev/eth_tap.cc iodev/floppy.cc iodev/floppy.h iodev/guest2host.cc iodev/guest2host.h iodev/harddrv.cc iodev/harddrv.h iodev/iodebug.cc iodev/iodebug.h iodev/iodev.h iodev/keyboard.cc iodev/keyboard.h iodev/ne2k.cc iodev/ne2k.h iodev/parallel.cc iodev/parallel.h iodev/pci.cc iodev/pci.h iodev/pci2isa.cc iodev/pci2isa.h iodev/pic.cc iodev/pic.h iodev/pit.cc iodev/pit.h iodev/pit_wrap.cc iodev/pit_wrap.h iodev/sb16.cc iodev/sb16.h iodev/scancodes.cc iodev/scancodes.h iodev/serial.cc iodev/serial.h iodev/slowdown_timer.cc iodev/slowdown_timer.h iodev/unmapped.cc iodev/unmapped.h iodev/vga.cc iodev/vga.h memory/Makefile.in memory/memory.cc memory/memory.h memory/misc_mem.cc misc/bximage.c misc/niclist.c Added Files: README-plugins extplugin.h ltdl.c ltdl.h ltdlconf.h.in ltmain.sh plugin.cc plugin.h
2002-10-25 01:07:56 +04:00
// is used to know when we are exporting symbols and when we are importing.
#define BX_PLUGGABLE
- apply patch.ifdef-disabled-options. Comments from that patch are below: For a whole lot of configure options, I put #if...#endif around code that is specific to the option, even in files which are normally only compiled when the option is on. This allows me to create a MS Visual C++ 6.0 workspace that supports many of these options. The workspace will basically compile every file all the time, but the code for disabled options will be commented out by the #if...#endif. This may one day lead to simplification of the Makefiles and configure scripts, but for the moment I'm leaving Makefiles and configure scripts alone. Affected options: BX_SUPPORT_APIC (cpu/apic.cc) BX_SUPPORT_X86_64 (cpu/*64.cc) BX_DEBUGGER (debug/*) BX_DISASM (disasm/*) BX_WITH_nameofgui (gui/*) BX_SUPPORT_CDROM (iodev/cdrom.cc) BX_NE2K_SUPPORT (iodev/eth*.cc, iodev/ne2k.cc) BX_SUPPORT_APIC (iodev/ioapic.cc) BX_IODEBUG_SUPPORT (iodev/iodebug.cc) BX_PCI_SUPPORT (iodev/pci*.cc) BX_SUPPORT_SB16 (iodev/sb*.cc) Modified Files: cpu/apic.cc cpu/arith64.cc cpu/ctrl_xfer64.cc cpu/data_xfer64.cc cpu/fetchdecode64.cc cpu/logical64.cc cpu/mult64.cc cpu/resolve64.cc cpu/shift64.cc cpu/stack64.cc debug/Makefile.in debug/crc.cc debug/dbg_main.cc debug/lexer.l debug/linux.cc debug/parser.c debug/parser.y disasm/dis_decode.cc disasm/dis_groups.cc gui/amigaos.cc gui/beos.cc gui/carbon.cc gui/macintosh.cc gui/rfb.cc gui/sdl.cc gui/term.cc gui/win32.cc gui/wx.cc gui/wxdialog.cc gui/wxmain.cc gui/x.cc iodev/cdrom.cc iodev/eth.cc iodev/eth_arpback.cc iodev/eth_fbsd.cc iodev/eth_linux.cc iodev/eth_null.cc iodev/eth_packetmaker.cc iodev/eth_tap.cc iodev/eth_tuntap.cc iodev/eth_win32.cc iodev/ioapic.cc iodev/iodebug.cc iodev/ne2k.cc iodev/pci.cc iodev/pci2isa.cc iodev/sb16.cc iodev/soundlnx.cc iodev/soundwin.cc
2002-11-19 08:47:45 +03:00
#include "bochs.h"
#include "param_names.h"
#include "keymap.h"
#include "iodev.h"
#include "enh_dbg.h"
- apply patch.ifdef-disabled-options. Comments from that patch are below: For a whole lot of configure options, I put #if...#endif around code that is specific to the option, even in files which are normally only compiled when the option is on. This allows me to create a MS Visual C++ 6.0 workspace that supports many of these options. The workspace will basically compile every file all the time, but the code for disabled options will be commented out by the #if...#endif. This may one day lead to simplification of the Makefiles and configure scripts, but for the moment I'm leaving Makefiles and configure scripts alone. Affected options: BX_SUPPORT_APIC (cpu/apic.cc) BX_SUPPORT_X86_64 (cpu/*64.cc) BX_DEBUGGER (debug/*) BX_DISASM (disasm/*) BX_WITH_nameofgui (gui/*) BX_SUPPORT_CDROM (iodev/cdrom.cc) BX_NE2K_SUPPORT (iodev/eth*.cc, iodev/ne2k.cc) BX_SUPPORT_APIC (iodev/ioapic.cc) BX_IODEBUG_SUPPORT (iodev/iodebug.cc) BX_PCI_SUPPORT (iodev/pci*.cc) BX_SUPPORT_SB16 (iodev/sb*.cc) Modified Files: cpu/apic.cc cpu/arith64.cc cpu/ctrl_xfer64.cc cpu/data_xfer64.cc cpu/fetchdecode64.cc cpu/logical64.cc cpu/mult64.cc cpu/resolve64.cc cpu/shift64.cc cpu/stack64.cc debug/Makefile.in debug/crc.cc debug/dbg_main.cc debug/lexer.l debug/linux.cc debug/parser.c debug/parser.y disasm/dis_decode.cc disasm/dis_groups.cc gui/amigaos.cc gui/beos.cc gui/carbon.cc gui/macintosh.cc gui/rfb.cc gui/sdl.cc gui/term.cc gui/win32.cc gui/wx.cc gui/wxdialog.cc gui/wxmain.cc gui/x.cc iodev/cdrom.cc iodev/eth.cc iodev/eth_arpback.cc iodev/eth_fbsd.cc iodev/eth_linux.cc iodev/eth_null.cc iodev/eth_packetmaker.cc iodev/eth_tap.cc iodev/eth_tuntap.cc iodev/eth_win32.cc iodev/ioapic.cc iodev/iodebug.cc iodev/ne2k.cc iodev/pci.cc iodev/pci2isa.cc iodev/sb16.cc iodev/soundlnx.cc iodev/soundwin.cc
2002-11-19 08:47:45 +03:00
#if BX_WITH_X11
extern "C" {
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xos.h>
#include <X11/Xatom.h>
#include <X11/keysym.h>
#include <X11/extensions/Xrandr.h>
#if BX_HAVE_XPM_H
#include <X11/xpm.h>
#endif
}
#if BX_HAVE_XPM_H
#include "icon_bochs.xpm"
#else
#include "icon_bochs.h"
#endif
#include "font/vga.bitmap.h"
Add plugin support to Bochs by merging all the changes from the BRANCH_PLUGINS branch! Authors: Bryce Denney Christophe Bothamy Kevin Lawton (we grabbed a lot of plugin code from plex86) Testing help from: Volker Ruppert Don Becker (Psyon) Jeremy Parsons (Br'fin) The change log is too long to paste in here. To read the change log, do cvs log patches/patch.final-from-BRANCH_PLUGINS.gz All the changes and a detailed description are contained in a patch called patch.final-from-BRANCH_PLUGINS.gz. To look at the complete patch, do cvs upd -r1.1 patches/patch.final-from-BRANCH_PLUGINS.gz Then you will have a local copy of the patch, which you can gunzip and play with however you want. Modified Files: .bochsrc Makefile.in aclocal.m4 bochs.h config.h.in configure configure.in gdbstub.cc logio.cc main.cc pc_system.cc pc_system.h state_file.h bios/Makefile.in bios/rombios.c cpu/Makefile.in cpu/access.cc cpu/apic.cc cpu/arith16.cc cpu/arith32.cc cpu/arith8.cc cpu/cpu.cc cpu/cpu.h cpu/ctrl_xfer32.cc cpu/exception.cc cpu/fetchdecode.cc cpu/fetchdecode64.cc cpu/flag_ctrl.cc cpu/flag_ctrl_pro.cc cpu/init.cc cpu/io.cc cpu/logical16.cc cpu/logical32.cc cpu/logical8.cc cpu/paging.cc cpu/proc_ctrl.cc cpu/protect_ctrl.cc cpu/segment_ctrl_pro.cc cpu/shift16.cc cpu/shift32.cc cpu/stack64.cc cpu/string.cc cpu/tasking.cc debug/Makefile.in debug/dbg_main.cc disasm/Makefile.in doc/docbook/user/user.dbk dynamic/Makefile.in fpu/Makefile.in gui/Makefile.in gui/amigaos.cc gui/beos.cc gui/carbon.cc gui/control.cc gui/control.h gui/gui.cc gui/gui.h gui/keymap.cc gui/keymap.h gui/macintosh.cc gui/nogui.cc gui/rfb.cc gui/sdl.cc gui/sdlkeys.h gui/siminterface.cc gui/siminterface.h gui/term.cc gui/win32.cc gui/wx.cc gui/wxdialog.cc gui/wxdialog.h gui/wxmain.cc gui/wxmain.h gui/x.cc gui/keymaps/sdl-pc-de.map gui/keymaps/sdl-pc-us.map gui/keymaps/x11-pc-de.map instrument/example0/instrument.h instrument/example1/instrument.h instrument/stubs/instrument.cc instrument/stubs/instrument.h iodev/Makefile.in iodev/biosdev.cc iodev/biosdev.h iodev/cdrom.cc iodev/cmos.cc iodev/cmos.h iodev/devices.cc iodev/dma.cc iodev/dma.h iodev/eth_fbsd.cc iodev/eth_linux.cc iodev/eth_null.cc iodev/eth_tap.cc iodev/floppy.cc iodev/floppy.h iodev/guest2host.cc iodev/guest2host.h iodev/harddrv.cc iodev/harddrv.h iodev/iodebug.cc iodev/iodebug.h iodev/iodev.h iodev/keyboard.cc iodev/keyboard.h iodev/ne2k.cc iodev/ne2k.h iodev/parallel.cc iodev/parallel.h iodev/pci.cc iodev/pci.h iodev/pci2isa.cc iodev/pci2isa.h iodev/pic.cc iodev/pic.h iodev/pit.cc iodev/pit.h iodev/pit_wrap.cc iodev/pit_wrap.h iodev/sb16.cc iodev/sb16.h iodev/scancodes.cc iodev/scancodes.h iodev/serial.cc iodev/serial.h iodev/slowdown_timer.cc iodev/slowdown_timer.h iodev/unmapped.cc iodev/unmapped.h iodev/vga.cc iodev/vga.h memory/Makefile.in memory/memory.cc memory/memory.h memory/misc_mem.cc misc/bximage.c misc/niclist.c Added Files: README-plugins extplugin.h ltdl.c ltdl.h ltdlconf.h.in ltmain.sh plugin.cc plugin.h
2002-10-25 01:07:56 +04:00
class bx_x_gui_c : public bx_gui_c {
public:
bx_x_gui_c (void);
DECLARE_GUI_VIRTUAL_METHODS()
DECLARE_GUI_NEW_VIRTUAL_METHODS()
#if BX_USE_IDLE_HACK
virtual void sim_is_idle(void);
#endif
virtual void beep_on(float frequency);
virtual void beep_off();
virtual void statusbar_setitem_specific(int element, bx_bool active, bx_bool w);
virtual void get_capabilities(Bit16u *xres, Bit16u *yres, Bit16u *bpp);
virtual void set_mouse_mode_absxy(bx_bool mode);
#if BX_SHOW_IPS
virtual void show_ips(Bit32u ips_count);
#endif
Add plugin support to Bochs by merging all the changes from the BRANCH_PLUGINS branch! Authors: Bryce Denney Christophe Bothamy Kevin Lawton (we grabbed a lot of plugin code from plex86) Testing help from: Volker Ruppert Don Becker (Psyon) Jeremy Parsons (Br'fin) The change log is too long to paste in here. To read the change log, do cvs log patches/patch.final-from-BRANCH_PLUGINS.gz All the changes and a detailed description are contained in a patch called patch.final-from-BRANCH_PLUGINS.gz. To look at the complete patch, do cvs upd -r1.1 patches/patch.final-from-BRANCH_PLUGINS.gz Then you will have a local copy of the patch, which you can gunzip and play with however you want. Modified Files: .bochsrc Makefile.in aclocal.m4 bochs.h config.h.in configure configure.in gdbstub.cc logio.cc main.cc pc_system.cc pc_system.h state_file.h bios/Makefile.in bios/rombios.c cpu/Makefile.in cpu/access.cc cpu/apic.cc cpu/arith16.cc cpu/arith32.cc cpu/arith8.cc cpu/cpu.cc cpu/cpu.h cpu/ctrl_xfer32.cc cpu/exception.cc cpu/fetchdecode.cc cpu/fetchdecode64.cc cpu/flag_ctrl.cc cpu/flag_ctrl_pro.cc cpu/init.cc cpu/io.cc cpu/logical16.cc cpu/logical32.cc cpu/logical8.cc cpu/paging.cc cpu/proc_ctrl.cc cpu/protect_ctrl.cc cpu/segment_ctrl_pro.cc cpu/shift16.cc cpu/shift32.cc cpu/stack64.cc cpu/string.cc cpu/tasking.cc debug/Makefile.in debug/dbg_main.cc disasm/Makefile.in doc/docbook/user/user.dbk dynamic/Makefile.in fpu/Makefile.in gui/Makefile.in gui/amigaos.cc gui/beos.cc gui/carbon.cc gui/control.cc gui/control.h gui/gui.cc gui/gui.h gui/keymap.cc gui/keymap.h gui/macintosh.cc gui/nogui.cc gui/rfb.cc gui/sdl.cc gui/sdlkeys.h gui/siminterface.cc gui/siminterface.h gui/term.cc gui/win32.cc gui/wx.cc gui/wxdialog.cc gui/wxdialog.h gui/wxmain.cc gui/wxmain.h gui/x.cc gui/keymaps/sdl-pc-de.map gui/keymaps/sdl-pc-us.map gui/keymaps/x11-pc-de.map instrument/example0/instrument.h instrument/example1/instrument.h instrument/stubs/instrument.cc instrument/stubs/instrument.h iodev/Makefile.in iodev/biosdev.cc iodev/biosdev.h iodev/cdrom.cc iodev/cmos.cc iodev/cmos.h iodev/devices.cc iodev/dma.cc iodev/dma.h iodev/eth_fbsd.cc iodev/eth_linux.cc iodev/eth_null.cc iodev/eth_tap.cc iodev/floppy.cc iodev/floppy.h iodev/guest2host.cc iodev/guest2host.h iodev/harddrv.cc iodev/harddrv.h iodev/iodebug.cc iodev/iodebug.h iodev/iodev.h iodev/keyboard.cc iodev/keyboard.h iodev/ne2k.cc iodev/ne2k.h iodev/parallel.cc iodev/parallel.h iodev/pci.cc iodev/pci.h iodev/pci2isa.cc iodev/pci2isa.h iodev/pic.cc iodev/pic.h iodev/pit.cc iodev/pit.h iodev/pit_wrap.cc iodev/pit_wrap.h iodev/sb16.cc iodev/sb16.h iodev/scancodes.cc iodev/scancodes.h iodev/serial.cc iodev/serial.h iodev/slowdown_timer.cc iodev/slowdown_timer.h iodev/unmapped.cc iodev/unmapped.h iodev/vga.cc iodev/vga.h memory/Makefile.in memory/memory.cc memory/memory.h memory/misc_mem.cc misc/bximage.c misc/niclist.c Added Files: README-plugins extplugin.h ltdl.c ltdl.h ltdlconf.h.in ltmain.sh plugin.cc plugin.h
2002-10-25 01:07:56 +04:00
};
// declare one instance of the gui object and call macro to insert the
// plugin code
static bx_x_gui_c *theGui = NULL;
IMPLEMENT_GUI_PLUGIN_CODE(x)
Add plugin support to Bochs by merging all the changes from the BRANCH_PLUGINS branch! Authors: Bryce Denney Christophe Bothamy Kevin Lawton (we grabbed a lot of plugin code from plex86) Testing help from: Volker Ruppert Don Becker (Psyon) Jeremy Parsons (Br'fin) The change log is too long to paste in here. To read the change log, do cvs log patches/patch.final-from-BRANCH_PLUGINS.gz All the changes and a detailed description are contained in a patch called patch.final-from-BRANCH_PLUGINS.gz. To look at the complete patch, do cvs upd -r1.1 patches/patch.final-from-BRANCH_PLUGINS.gz Then you will have a local copy of the patch, which you can gunzip and play with however you want. Modified Files: .bochsrc Makefile.in aclocal.m4 bochs.h config.h.in configure configure.in gdbstub.cc logio.cc main.cc pc_system.cc pc_system.h state_file.h bios/Makefile.in bios/rombios.c cpu/Makefile.in cpu/access.cc cpu/apic.cc cpu/arith16.cc cpu/arith32.cc cpu/arith8.cc cpu/cpu.cc cpu/cpu.h cpu/ctrl_xfer32.cc cpu/exception.cc cpu/fetchdecode.cc cpu/fetchdecode64.cc cpu/flag_ctrl.cc cpu/flag_ctrl_pro.cc cpu/init.cc cpu/io.cc cpu/logical16.cc cpu/logical32.cc cpu/logical8.cc cpu/paging.cc cpu/proc_ctrl.cc cpu/protect_ctrl.cc cpu/segment_ctrl_pro.cc cpu/shift16.cc cpu/shift32.cc cpu/stack64.cc cpu/string.cc cpu/tasking.cc debug/Makefile.in debug/dbg_main.cc disasm/Makefile.in doc/docbook/user/user.dbk dynamic/Makefile.in fpu/Makefile.in gui/Makefile.in gui/amigaos.cc gui/beos.cc gui/carbon.cc gui/control.cc gui/control.h gui/gui.cc gui/gui.h gui/keymap.cc gui/keymap.h gui/macintosh.cc gui/nogui.cc gui/rfb.cc gui/sdl.cc gui/sdlkeys.h gui/siminterface.cc gui/siminterface.h gui/term.cc gui/win32.cc gui/wx.cc gui/wxdialog.cc gui/wxdialog.h gui/wxmain.cc gui/wxmain.h gui/x.cc gui/keymaps/sdl-pc-de.map gui/keymaps/sdl-pc-us.map gui/keymaps/x11-pc-de.map instrument/example0/instrument.h instrument/example1/instrument.h instrument/stubs/instrument.cc instrument/stubs/instrument.h iodev/Makefile.in iodev/biosdev.cc iodev/biosdev.h iodev/cdrom.cc iodev/cmos.cc iodev/cmos.h iodev/devices.cc iodev/dma.cc iodev/dma.h iodev/eth_fbsd.cc iodev/eth_linux.cc iodev/eth_null.cc iodev/eth_tap.cc iodev/floppy.cc iodev/floppy.h iodev/guest2host.cc iodev/guest2host.h iodev/harddrv.cc iodev/harddrv.h iodev/iodebug.cc iodev/iodebug.h iodev/iodev.h iodev/keyboard.cc iodev/keyboard.h iodev/ne2k.cc iodev/ne2k.h iodev/parallel.cc iodev/parallel.h iodev/pci.cc iodev/pci.h iodev/pci2isa.cc iodev/pci2isa.h iodev/pic.cc iodev/pic.h iodev/pit.cc iodev/pit.h iodev/pit_wrap.cc iodev/pit_wrap.h iodev/sb16.cc iodev/sb16.h iodev/scancodes.cc iodev/scancodes.h iodev/serial.cc iodev/serial.h iodev/slowdown_timer.cc iodev/slowdown_timer.h iodev/unmapped.cc iodev/unmapped.h iodev/vga.cc iodev/vga.h memory/Makefile.in memory/memory.cc memory/memory.h memory/misc_mem.cc misc/bximage.c misc/niclist.c Added Files: README-plugins extplugin.h ltdl.c ltdl.h ltdlconf.h.in ltmain.sh plugin.cc plugin.h
2002-10-25 01:07:56 +04:00
#define LOG_THIS theGui->
#define MAX_MAPPED_STRING_LENGTH 10
/* These are used as arguments to nearly every Xlib routine, so it saves
* routine arguments to declare them global. If there were
* additional source files, they would be declared extern there. */
Display *bx_x_display;
int bx_x_screen_num;
static Visual *default_visual;
static Colormap default_cmap;
static bx_bool x11_private_colormap;
static unsigned long white_pixel=0, black_pixel=0;
static char *progname; /* name this program was invoked by */
// text display
static unsigned int text_rows=25, text_cols=80;
static unsigned font_width, font_height;
static Bit8u h_panning = 0, v_panning = 0;
static Bit16u line_compare = 1023;
static unsigned prev_cursor_x=0;
static unsigned prev_cursor_y=0;
// graphics display
static Window win;
static GC gc, gc_inv, gc_headerbar, gc_headerbar_inv;
static unsigned dimension_x=0, dimension_y=0;
static XImage *ximage = NULL;
static unsigned imDepth, imWide, imBPP;
// mouse cursor
static bx_bool mouse_captured = 0;
static int prev_x=-1, prev_y=-1;
static int current_x=-1, current_y=-1, current_z=0;
static unsigned mouse_button_state = 0;
static bx_bool x11_mouse_mode_absxy = 0;
static int warp_home_x = 200;
static int warp_home_y = 200;
static int mouse_enable_x = 0;
static int mouse_enable_y = 0;
static int warp_dx = 0;
static int warp_dy = 0;
static void warp_cursor(int dx, int dy);
static void disable_cursor();
static void enable_cursor();
// keyboard
static bx_bool x11_nokeyrepeat = 0;
static bx_bool x11_use_kbd_mapping = 0;
static Bit32u convertStringToXKeysym (const char *string);
static bx_bool x_init_done = 0;
static Pixmap vgafont[256];
2010-01-24 15:46:42 +03:00
static unsigned bx_bitmap_entries = 0;
static struct {
Pixmap bmap;
unsigned xdim;
unsigned ydim;
2010-01-24 15:46:42 +03:00
} bx_bitmaps[BX_MAX_PIXMAPS];
static struct {
Pixmap bitmap;
unsigned xdim;
unsigned ydim;
unsigned xorigin;
unsigned yorigin;
unsigned alignment;
void (*f)(void);
2010-01-24 15:46:42 +03:00
} bx_headerbar_entry[BX_MAX_HEADERBAR_ENTRIES];
static unsigned bx_headerbar_y = 0;
static unsigned bx_headerbar_entries = 0;
static unsigned bx_bitmap_left_xorigin = 0; // pixels from left
static unsigned bx_bitmap_right_xorigin = 0; // pixels from right
static unsigned bx_statusbar_y = 18;
static unsigned bx_statusitem_pos[12] = {
0, 200, 240, 280, 320, 360, 400, 440, 480, 520, 560, 600
2010-01-24 15:46:42 +03:00
};
static bx_bool bx_statusitem_active[12];
2008-10-13 11:31:23 +04:00
static long bx_status_led_green, bx_status_led_red, bx_status_graytext;
static char bx_status_info_text[34];
#if BX_SHOW_IPS
static bx_bool x11_ips_update = 0, x11_hide_ips = 0;
static char x11_ips_text[20];
static Bit8u x11_mouse_msg_counter = 0;
#endif
static void headerbar_click(int x, int y);
static void send_keyboard_mouse_status(void);
static void set_status_text(int element, const char *text, bx_bool active, bx_bool w=0);
Bit32u ascii_to_key_event[0x5f] = {
// !"#$%&'
BX_KEY_SPACE,
BX_KEY_1,
BX_KEY_SINGLE_QUOTE,
BX_KEY_3,
BX_KEY_4,
BX_KEY_5,
BX_KEY_7,
BX_KEY_SINGLE_QUOTE,
// ()*+,-./
BX_KEY_9,
BX_KEY_0,
BX_KEY_8,
BX_KEY_EQUALS,
BX_KEY_COMMA,
BX_KEY_MINUS,
BX_KEY_PERIOD,
BX_KEY_SLASH,
// 01234567
BX_KEY_0,
BX_KEY_1,
BX_KEY_2,
BX_KEY_3,
BX_KEY_4,
BX_KEY_5,
BX_KEY_6,
BX_KEY_7,
// 89:;<=>?
BX_KEY_8,
BX_KEY_9,
BX_KEY_SEMICOLON,
BX_KEY_SEMICOLON,
BX_KEY_COMMA,
BX_KEY_EQUALS,
BX_KEY_PERIOD,
BX_KEY_SLASH,
// @ABCDEFG
BX_KEY_2,
BX_KEY_A,
BX_KEY_B,
BX_KEY_C,
BX_KEY_D,
BX_KEY_E,
BX_KEY_F,
BX_KEY_G,
// HIJKLMNO
BX_KEY_H,
BX_KEY_I,
BX_KEY_J,
BX_KEY_K,
BX_KEY_L,
BX_KEY_M,
BX_KEY_N,
BX_KEY_O,
// PQRSTUVW
BX_KEY_P,
BX_KEY_Q,
BX_KEY_R,
BX_KEY_S,
BX_KEY_T,
BX_KEY_U,
BX_KEY_V,
BX_KEY_W,
// XYZ[\]^_
BX_KEY_X,
BX_KEY_Y,
BX_KEY_Z,
BX_KEY_LEFT_BRACKET,
BX_KEY_BACKSLASH,
BX_KEY_RIGHT_BRACKET,
BX_KEY_6,
BX_KEY_MINUS,
// `abcdefg
BX_KEY_GRAVE,
BX_KEY_A,
BX_KEY_B,
BX_KEY_C,
BX_KEY_D,
BX_KEY_E,
BX_KEY_F,
BX_KEY_G,
// hijklmno
BX_KEY_H,
BX_KEY_I,
BX_KEY_J,
BX_KEY_K,
BX_KEY_L,
BX_KEY_M,
BX_KEY_N,
BX_KEY_O,
// pqrstuvw
BX_KEY_P,
BX_KEY_Q,
BX_KEY_R,
BX_KEY_S,
BX_KEY_T,
BX_KEY_U,
BX_KEY_V,
BX_KEY_W,
// xyz{|}~
BX_KEY_X,
BX_KEY_Y,
BX_KEY_Z,
BX_KEY_LEFT_BRACKET,
BX_KEY_BACKSLASH,
BX_KEY_RIGHT_BRACKET,
BX_KEY_GRAVE
};
extern Bit8u graphics_snapshot[32 * 1024];
2003-01-17 21:16:02 +03:00
static void create_internal_vga_font(void);
static void xkeypress(KeySym keysym, int press_release);
// extern "C" void select_visual(void);
#define ROUNDUP(nbytes, pad) ((((nbytes) + ((pad)-1)) / (pad)) * ((pad)>>3))
#define MAX_VGA_COLORS 256
unsigned long col_vals[MAX_VGA_COLORS]; // 256 VGA colors
unsigned curr_foreground, curr_background;
BxEvent *x11_notify_callback (void *unused, BxEvent *event);
static bxevent_handler old_callback = NULL;
static void *old_callback_arg = NULL;
// Try to allocate NCOLORS at once in the colormap provided. If it can
// be done, return true. If not, return false. (In either case, free
// up the color cells so that we don't add to the problem!) This is used
// to determine whether Bochs should use a private colormap even when the
// user did not specify it.
- Apply patch.replace-Boolean rev 1.3. Every "Boolean" is now changed to a "bx_bool" which is always defined as Bit32u on all platforms. In Carbon specific code, Boolean is still used because the Carbon header files define it to unsigned char. - this fixes bug [ 623152 ] MacOSX: Triple Exception Booting win95. The bug was that some code in Bochs depends on Boolean to be a 32 bit value. (This should be fixed, but I don't know all the places where it needs to be fixed yet.) Because Carbon defined Boolean as an unsigned char, Bochs just followed along and used the unsigned char definition to avoid compile problems. This exposed the dependency on 32 bit Boolean on MacOS X only and led to major simulation problems, that could only be reproduced and debugged on that platform. - On the mailing list we debated whether to make all Booleans into "bool" or our own type. I chose bx_bool for several reasons. 1. Unlike C++'s bool, we can guarantee that bx_bool is the same size on all platforms, which makes it much less likely to have more platform-specific simulation differences in the future. (I spent hours on a borrowed MacOSX machine chasing bug 618388 before discovering that different sized Booleans were the problem, and I don't want to repeat that.) 2. We still have at least one dependency on 32 bit Booleans which must be fixed some time, but I don't want to risk introducing new bugs into the simulation just before the 2.0 release. Modified Files: bochs.h config.h.in gdbstub.cc logio.cc main.cc pc_system.cc pc_system.h plugin.cc plugin.h bios/rombios.c cpu/apic.cc cpu/arith16.cc cpu/arith32.cc cpu/arith64.cc cpu/arith8.cc cpu/cpu.cc cpu/cpu.h cpu/ctrl_xfer16.cc cpu/ctrl_xfer32.cc cpu/ctrl_xfer64.cc cpu/data_xfer16.cc cpu/data_xfer32.cc cpu/data_xfer64.cc cpu/debugstuff.cc cpu/exception.cc cpu/fetchdecode.cc cpu/flag_ctrl_pro.cc cpu/init.cc cpu/io_pro.cc cpu/lazy_flags.cc cpu/lazy_flags.h cpu/mult16.cc cpu/mult32.cc cpu/mult64.cc cpu/mult8.cc cpu/paging.cc cpu/proc_ctrl.cc cpu/segment_ctrl_pro.cc cpu/stack_pro.cc cpu/tasking.cc debug/dbg_main.cc debug/debug.h debug/sim2.cc disasm/dis_decode.cc disasm/disasm.h doc/docbook/Makefile docs-html/cosimulation.html fpu/wmFPUemu_glue.cc gui/amigaos.cc gui/beos.cc gui/carbon.cc gui/gui.cc gui/gui.h gui/keymap.cc gui/keymap.h gui/macintosh.cc gui/nogui.cc gui/rfb.cc gui/sdl.cc gui/siminterface.cc gui/siminterface.h gui/term.cc gui/win32.cc gui/wx.cc gui/wxmain.cc gui/wxmain.h gui/x.cc instrument/example0/instrument.cc instrument/example0/instrument.h instrument/example1/instrument.cc instrument/example1/instrument.h instrument/stubs/instrument.cc instrument/stubs/instrument.h iodev/cdrom.cc iodev/cdrom.h iodev/cdrom_osx.cc iodev/cmos.cc iodev/devices.cc iodev/dma.cc iodev/dma.h iodev/eth_arpback.cc iodev/eth_packetmaker.cc iodev/eth_packetmaker.h iodev/floppy.cc iodev/floppy.h iodev/guest2host.h iodev/harddrv.cc iodev/harddrv.h iodev/ioapic.cc iodev/ioapic.h iodev/iodebug.cc iodev/iodev.h iodev/keyboard.cc iodev/keyboard.h iodev/ne2k.h iodev/parallel.h iodev/pci.cc iodev/pci.h iodev/pic.h iodev/pit.cc iodev/pit.h iodev/pit_wrap.cc iodev/pit_wrap.h iodev/sb16.cc iodev/sb16.h iodev/serial.cc iodev/serial.h iodev/vga.cc iodev/vga.h memory/memory.h memory/misc_mem.cc
2002-10-25 15:44:41 +04:00
static bx_bool
test_alloc_colors (Colormap cmap, Bit32u n_tries) {
XColor color;
unsigned long pixel[MAX_VGA_COLORS];
- Apply patch.replace-Boolean rev 1.3. Every "Boolean" is now changed to a "bx_bool" which is always defined as Bit32u on all platforms. In Carbon specific code, Boolean is still used because the Carbon header files define it to unsigned char. - this fixes bug [ 623152 ] MacOSX: Triple Exception Booting win95. The bug was that some code in Bochs depends on Boolean to be a 32 bit value. (This should be fixed, but I don't know all the places where it needs to be fixed yet.) Because Carbon defined Boolean as an unsigned char, Bochs just followed along and used the unsigned char definition to avoid compile problems. This exposed the dependency on 32 bit Boolean on MacOS X only and led to major simulation problems, that could only be reproduced and debugged on that platform. - On the mailing list we debated whether to make all Booleans into "bool" or our own type. I chose bx_bool for several reasons. 1. Unlike C++'s bool, we can guarantee that bx_bool is the same size on all platforms, which makes it much less likely to have more platform-specific simulation differences in the future. (I spent hours on a borrowed MacOSX machine chasing bug 618388 before discovering that different sized Booleans were the problem, and I don't want to repeat that.) 2. We still have at least one dependency on 32 bit Booleans which must be fixed some time, but I don't want to risk introducing new bugs into the simulation just before the 2.0 release. Modified Files: bochs.h config.h.in gdbstub.cc logio.cc main.cc pc_system.cc pc_system.h plugin.cc plugin.h bios/rombios.c cpu/apic.cc cpu/arith16.cc cpu/arith32.cc cpu/arith64.cc cpu/arith8.cc cpu/cpu.cc cpu/cpu.h cpu/ctrl_xfer16.cc cpu/ctrl_xfer32.cc cpu/ctrl_xfer64.cc cpu/data_xfer16.cc cpu/data_xfer32.cc cpu/data_xfer64.cc cpu/debugstuff.cc cpu/exception.cc cpu/fetchdecode.cc cpu/flag_ctrl_pro.cc cpu/init.cc cpu/io_pro.cc cpu/lazy_flags.cc cpu/lazy_flags.h cpu/mult16.cc cpu/mult32.cc cpu/mult64.cc cpu/mult8.cc cpu/paging.cc cpu/proc_ctrl.cc cpu/segment_ctrl_pro.cc cpu/stack_pro.cc cpu/tasking.cc debug/dbg_main.cc debug/debug.h debug/sim2.cc disasm/dis_decode.cc disasm/disasm.h doc/docbook/Makefile docs-html/cosimulation.html fpu/wmFPUemu_glue.cc gui/amigaos.cc gui/beos.cc gui/carbon.cc gui/gui.cc gui/gui.h gui/keymap.cc gui/keymap.h gui/macintosh.cc gui/nogui.cc gui/rfb.cc gui/sdl.cc gui/siminterface.cc gui/siminterface.h gui/term.cc gui/win32.cc gui/wx.cc gui/wxmain.cc gui/wxmain.h gui/x.cc instrument/example0/instrument.cc instrument/example0/instrument.h instrument/example1/instrument.cc instrument/example1/instrument.h instrument/stubs/instrument.cc instrument/stubs/instrument.h iodev/cdrom.cc iodev/cdrom.h iodev/cdrom_osx.cc iodev/cmos.cc iodev/devices.cc iodev/dma.cc iodev/dma.h iodev/eth_arpback.cc iodev/eth_packetmaker.cc iodev/eth_packetmaker.h iodev/floppy.cc iodev/floppy.h iodev/guest2host.h iodev/harddrv.cc iodev/harddrv.h iodev/ioapic.cc iodev/ioapic.h iodev/iodebug.cc iodev/iodev.h iodev/keyboard.cc iodev/keyboard.h iodev/ne2k.h iodev/parallel.h iodev/pci.cc iodev/pci.h iodev/pic.h iodev/pit.cc iodev/pit.h iodev/pit_wrap.cc iodev/pit_wrap.h iodev/sb16.cc iodev/sb16.h iodev/serial.cc iodev/serial.h iodev/vga.cc iodev/vga.h memory/memory.h memory/misc_mem.cc
2002-10-25 15:44:41 +04:00
bx_bool pixel_valid[MAX_VGA_COLORS];
Bit32u n_allocated = 0;
Bit32u i;
color.flags = DoRed | DoGreen | DoBlue;
for (i=0; i<n_tries; i++) {
// choose wierd color values that are unlikely to already be in the
// colormap.
color.red = ((i+41)%MAX_VGA_COLORS) << 8;
color.green = ((i+42)%MAX_VGA_COLORS) << 8;
color.blue = ((i+43)%MAX_VGA_COLORS) << 8;
pixel_valid[i] = false;
if (XAllocColor (bx_x_display, cmap, &color)) {
pixel[i] = color.pixel;
pixel_valid[i] = true;
n_allocated++;
}
}
BX_INFO (("test_alloc_colors: %d colors available out of %d colors tried", n_allocated, n_tries));
// now free them all
for (i=0; i<n_tries; i++) {
if (pixel_valid[i]) XFreeColors (bx_x_display, cmap, &pixel[i], 1, 0);
}
return (n_allocated == n_tries);
}
bx_x_gui_c::bx_x_gui_c () {}
void bx_x_gui_c::specific_init(int argc, char **argv, unsigned headerbar_y)
{
int i;
int x, y; /* window position */
unsigned int border_width = 4; /* four pixels */
2007-10-25 03:09:59 +04:00
const char *window_name = BOCHS_WINDOW_NAME;
const char *icon_name = "Bochs";
Pixmap icon_pixmap;
#if BX_HAVE_XPM_H
Pixmap icon_mask;
#endif
XSizeHints size_hints;
char *display_name = NULL;
/* create GC for text and drawing */
unsigned long valuemask = 0; /* ignore XGCvalues and use defaults */
XGCValues values;
int default_depth;
XEvent report;
XSetWindowAttributes win_attr;
unsigned long plane_masks_return[1];
XColor color;
#if BX_DEBUGGER && BX_DEBUGGER_GUI
bx_bool x11_with_debug_gui = 0;
#endif
Add plugin support to Bochs by merging all the changes from the BRANCH_PLUGINS branch! Authors: Bryce Denney Christophe Bothamy Kevin Lawton (we grabbed a lot of plugin code from plex86) Testing help from: Volker Ruppert Don Becker (Psyon) Jeremy Parsons (Br'fin) The change log is too long to paste in here. To read the change log, do cvs log patches/patch.final-from-BRANCH_PLUGINS.gz All the changes and a detailed description are contained in a patch called patch.final-from-BRANCH_PLUGINS.gz. To look at the complete patch, do cvs upd -r1.1 patches/patch.final-from-BRANCH_PLUGINS.gz Then you will have a local copy of the patch, which you can gunzip and play with however you want. Modified Files: .bochsrc Makefile.in aclocal.m4 bochs.h config.h.in configure configure.in gdbstub.cc logio.cc main.cc pc_system.cc pc_system.h state_file.h bios/Makefile.in bios/rombios.c cpu/Makefile.in cpu/access.cc cpu/apic.cc cpu/arith16.cc cpu/arith32.cc cpu/arith8.cc cpu/cpu.cc cpu/cpu.h cpu/ctrl_xfer32.cc cpu/exception.cc cpu/fetchdecode.cc cpu/fetchdecode64.cc cpu/flag_ctrl.cc cpu/flag_ctrl_pro.cc cpu/init.cc cpu/io.cc cpu/logical16.cc cpu/logical32.cc cpu/logical8.cc cpu/paging.cc cpu/proc_ctrl.cc cpu/protect_ctrl.cc cpu/segment_ctrl_pro.cc cpu/shift16.cc cpu/shift32.cc cpu/stack64.cc cpu/string.cc cpu/tasking.cc debug/Makefile.in debug/dbg_main.cc disasm/Makefile.in doc/docbook/user/user.dbk dynamic/Makefile.in fpu/Makefile.in gui/Makefile.in gui/amigaos.cc gui/beos.cc gui/carbon.cc gui/control.cc gui/control.h gui/gui.cc gui/gui.h gui/keymap.cc gui/keymap.h gui/macintosh.cc gui/nogui.cc gui/rfb.cc gui/sdl.cc gui/sdlkeys.h gui/siminterface.cc gui/siminterface.h gui/term.cc gui/win32.cc gui/wx.cc gui/wxdialog.cc gui/wxdialog.h gui/wxmain.cc gui/wxmain.h gui/x.cc gui/keymaps/sdl-pc-de.map gui/keymaps/sdl-pc-us.map gui/keymaps/x11-pc-de.map instrument/example0/instrument.h instrument/example1/instrument.h instrument/stubs/instrument.cc instrument/stubs/instrument.h iodev/Makefile.in iodev/biosdev.cc iodev/biosdev.h iodev/cdrom.cc iodev/cmos.cc iodev/cmos.h iodev/devices.cc iodev/dma.cc iodev/dma.h iodev/eth_fbsd.cc iodev/eth_linux.cc iodev/eth_null.cc iodev/eth_tap.cc iodev/floppy.cc iodev/floppy.h iodev/guest2host.cc iodev/guest2host.h iodev/harddrv.cc iodev/harddrv.h iodev/iodebug.cc iodev/iodebug.h iodev/iodev.h iodev/keyboard.cc iodev/keyboard.h iodev/ne2k.cc iodev/ne2k.h iodev/parallel.cc iodev/parallel.h iodev/pci.cc iodev/pci.h iodev/pci2isa.cc iodev/pci2isa.h iodev/pic.cc iodev/pic.h iodev/pit.cc iodev/pit.h iodev/pit_wrap.cc iodev/pit_wrap.h iodev/sb16.cc iodev/sb16.h iodev/scancodes.cc iodev/scancodes.h iodev/serial.cc iodev/serial.h iodev/slowdown_timer.cc iodev/slowdown_timer.h iodev/unmapped.cc iodev/unmapped.h iodev/vga.cc iodev/vga.h memory/Makefile.in memory/memory.cc memory/memory.h memory/misc_mem.cc misc/bximage.c misc/niclist.c Added Files: README-plugins extplugin.h ltdl.c ltdl.h ltdlconf.h.in ltmain.sh plugin.cc plugin.h
2002-10-25 01:07:56 +04:00
put("XGUI");
bx_headerbar_y = headerbar_y;
progname = argv[0];
// parse x11 specific options
if (argc > 1) {
for (i = 1; i < argc; i++) {
if (!strcmp(argv[i], "nokeyrepeat")) {
BX_INFO(("disabled host keyboard repeat"));
x11_nokeyrepeat = 1;
#if BX_DEBUGGER && BX_DEBUGGER_GUI
} else if (!strcmp(argv[i], "gui_debug")) {
x11_with_debug_gui = 1;
#endif
#if BX_SHOW_IPS
} else if (!strcmp(argv[i], "hideIPS")) {
BX_INFO(("hide IPS display in status bar"));
x11_hide_ips = 1;
#endif
} else {
BX_PANIC(("Unknown x11 option '%s'", argv[i]));
}
}
}
#if BX_DEBUGGER && BX_DEBUGGER_GUI
if (x11_with_debug_gui) {
// This is only necessary when GTK+ and Xlib are sharing the same
// connection. XInitThreads() must finish before any calls to GTK+
// or Xlib are made.
if (XInitThreads() == 0) {
BX_PANIC(("trying to run Bochs with the GTK+ "
"debugger on a non-threading X11."));
}
}
#endif
/* connect to X server */
if ((bx_x_display=XOpenDisplay(display_name)) == NULL)
{
BX_PANIC(("%s: cannot connect to X server %s",
progname, XDisplayName(display_name)));
}
/* get screen size from display structure macro */
bx_x_screen_num = DefaultScreen(bx_x_display);
/* Note that in a real application, x and y would default to 0
* but would be settable from the command line or resource database.
*/
x = y = 0;
// Temporary values so we can create the window
font_width = 8;
font_height = 16;
dimension_x = text_cols * font_width;
dimension_y = text_rows * font_height;
/* create opaque window */
win = XCreateSimpleWindow(bx_x_display, RootWindow(bx_x_display,bx_x_screen_num),
x, y,
dimension_x,
dimension_y + bx_headerbar_y + bx_statusbar_y,
border_width,
BlackPixel(bx_x_display, bx_x_screen_num),
BlackPixel(bx_x_display, bx_x_screen_num));
// (attempt to) enable backing store
win_attr.save_under=1;
win_attr.backing_store=Always;
XChangeWindowAttributes(bx_x_display,win,CWSaveUnder|CWBackingStore,&win_attr);
default_depth = DefaultDepth(bx_x_display, bx_x_screen_num);
default_visual = DefaultVisual(bx_x_display, bx_x_screen_num);
x11_private_colormap = SIM->get_param_bool(BXPN_PRIVATE_COLORMAP)->get();
if (!x11_private_colormap) {
default_cmap = DefaultColormap(bx_x_display, bx_x_screen_num);
// try to use default colormap. If not enough colors are available,
// then switch to private colormap despite the user setting. There
// are too many cases when no colors are available and Bochs simply
// draws everything in black on black.
if (!test_alloc_colors (default_cmap, 16)) {
BX_ERROR (("I can't even allocate 16 colors! Switching to a private colormap"));
x11_private_colormap = 1;
}
col_vals[0] = BlackPixel(bx_x_display, bx_x_screen_num);
col_vals[15] = WhitePixel(bx_x_display, bx_x_screen_num);
for (i = 1; i < MAX_VGA_COLORS; i++) {
if (i==15) continue;
col_vals[i] = col_vals[0];
}
}
if (x11_private_colormap) {
default_cmap = XCreateColormap(bx_x_display, DefaultRootWindow(bx_x_display),
default_visual, AllocNone);
if (XAllocColorCells(bx_x_display, default_cmap, False,
plane_masks_return, 0, col_vals, MAX_VGA_COLORS) == 0) {
BX_PANIC(("XAllocColorCells returns error. Maybe your screen does not support a private colormap?"));
}
win_attr.colormap = default_cmap;
XChangeWindowAttributes(bx_x_display, win, CWColormap, &win_attr);
color.flags = DoRed | DoGreen | DoBlue;
for (i=0; i < MAX_VGA_COLORS; i++) {
color.pixel = i;
if (i==15) {
color.red = 0xffff;
color.green = 0xffff;
color.blue = 0xffff;
}
else {
color.red = 0;
color.green = 0;
color.blue = 0;
}
XStoreColor(bx_x_display, default_cmap, &color);
}
}
// convenience variables which hold the black & white color indeces
black_pixel = col_vals[0];
white_pixel = col_vals[15];
2001-08-31 20:06:32 +04:00
BX_INFO(("font %u wide x %u high, display depth = %d",
(unsigned) font_width, (unsigned) font_height, default_depth));
//select_visual();
/* Get available icon sizes from Window manager */
#if BX_HAVE_XPM_H
/* Create pixmap from XPM for icon */
XCreatePixmapFromData(bx_x_display, win, (char **)icon_bochs_xpm, &icon_pixmap, &icon_mask, NULL);
#else
/* Create pixmap of depth 1 (bitmap) for icon */
icon_pixmap = XCreateBitmapFromData(bx_x_display, win,
(char *)bochs_icon_bits, bochs_icon_width, bochs_icon_height);
#endif
/* Set size hints for window manager. The window manager may
* override these settings. Note that in a real
* application if size or position were set by the user
* the flags would be UPosition and USize, and these would
* override the window manager's preferences for this window. */
/* x, y, width, and height hints are now taken from
* the actual settings of the window when mapped. Note
* that PPosition and PSize must be specified anyway. */
size_hints.flags = PPosition | PSize | PMinSize | PMaxSize;
size_hints.max_width = size_hints.min_width = dimension_x;
size_hints.max_height = size_hints.min_height = dimension_y + bx_headerbar_y +
bx_statusbar_y;
{
XWMHints wm_hints;
XClassHint class_hints;
/* format of the window name and icon name
* arguments has changed in R4 */
XTextProperty windowName, iconName;
/* These calls store window_name and icon_name into
* XTextProperty structures and set their other
* fields properly. */
2007-10-25 03:09:59 +04:00
if (XStringListToTextProperty((char **)&window_name, 1, &windowName) == 0) {
BX_PANIC(("%s: structure allocation for windowName failed.",
progname));
}
2007-10-25 03:09:59 +04:00
if (XStringListToTextProperty((char **)&icon_name, 1, &iconName) == 0) {
BX_PANIC(("%s: structure allocation for iconName failed.",
progname));
}
wm_hints.initial_state = NormalState;
wm_hints.input = True;
wm_hints.icon_pixmap = icon_pixmap;
#if BX_HAVE_XPM_H
wm_hints.icon_mask = icon_mask;
wm_hints.flags = StateHint | IconPixmapHint | IconMaskHint | InputHint;
#else
wm_hints.flags = StateHint | IconPixmapHint | InputHint;
#endif
class_hints.res_name = progname;
2007-10-25 03:09:59 +04:00
class_hints.res_class = (char *)"Bochs";
XSetWMProperties(bx_x_display, win, &windowName, &iconName,
argv, argc, &size_hints, &wm_hints,
&class_hints);
2006-04-14 17:27:17 +04:00
XFree(windowName.value);
XFree(iconName.value);
Atom wm_delete = XInternAtom(bx_x_display, "WM_DELETE_WINDOW", 1);
XSetWMProtocols(bx_x_display, win, &wm_delete, 1);
}
/* Select event types wanted */
XSelectInput(bx_x_display, win, ExposureMask | KeyPressMask | KeyReleaseMask |
ButtonPressMask | ButtonReleaseMask | StructureNotifyMask | PointerMotionMask |
EnterWindowMask | LeaveWindowMask | FocusChangeMask);
/* Create default Graphics Context */
gc = XCreateGC(bx_x_display, win, valuemask, &values);
gc_inv = XCreateGC(bx_x_display, win, valuemask, &values);
gc_headerbar = XCreateGC(bx_x_display, win, valuemask, &values);
gc_headerbar_inv = XCreateGC(bx_x_display, win, valuemask, &values);
XSetState(bx_x_display, gc, white_pixel, black_pixel, GXcopy,AllPlanes);
XSetState(bx_x_display, gc_inv, black_pixel, white_pixel, GXinvert,AllPlanes);
XSetState(bx_x_display, gc_headerbar, black_pixel, white_pixel, GXcopy,AllPlanes);
XSetState(bx_x_display, gc_headerbar_inv, white_pixel, black_pixel, GXcopy,AllPlanes);
/* Display window */
XMapWindow(bx_x_display, win);
XSync(bx_x_display, /* no discard */ 0);
BX_DEBUG(("waiting for MapNotify"));
while (1) {
XNextEvent(bx_x_display, &report);
if (report.type == MapNotify) break;
}
BX_DEBUG(("MapNotify found."));
// Create the VGA font
2003-01-17 21:16:02 +03:00
create_internal_vga_font();
{
char *imagedata;
ximage = XCreateImage(bx_x_display, default_visual,
default_depth, // depth of image (bitplanes)
ZPixmap,
0, // offset
NULL, // malloc() space after
x_tilesize, y_tilesize, // x & y size of image
32, // # bits of padding
0); // bytes_per_line, let X11 calculate
if (!ximage)
BX_PANIC(("vga: couldn't XCreateImage()"));
imDepth = default_depth;
imWide = ximage->bytes_per_line;
imBPP = ximage->bits_per_pixel;
imagedata = (char *) malloc((size_t) (ximage->bytes_per_line * y_tilesize));
if (!imagedata) BX_PANIC(("imagedata: malloc returned error"));
ximage->data = imagedata;
if (imBPP < imDepth) {
BX_PANIC(("vga_x: bits_per_pixel < depth ?"));
}
for (i=0; i<12; i++) bx_statusitem_active[i] = 0;
switch (imBPP) {
case 16:
bx_status_led_green = 0x07e0;
bx_status_led_red = 0xf900;
bx_status_graytext = 0x8410;
break;
case 24:
case 32:
bx_status_led_green = 0x00ff00;
bx_status_led_red = 0xff4000;
bx_status_graytext = 0x808080;
break;
default:
bx_status_led_green = 0;
bx_status_graytext = 0;
}
sprintf(bx_status_info_text, "%s enables mouse", get_toggle_info());
x_init_done = 1;
}
curr_background = 0;
XSetBackground(bx_x_display, gc, col_vals[curr_background]);
curr_foreground = 1;
XSetForeground(bx_x_display, gc, col_vals[curr_foreground]);
//XGrabPointer(bx_x_display, win, True, 0, GrabModeAsync, GrabModeAsync,
// win, None, CurrentTime);
XFlush(bx_x_display);
// redirect notify callback to X11 specific code
SIM->get_notify_callback (&old_callback, &old_callback_arg);
assert (old_callback != NULL);
SIM->set_notify_callback (x11_notify_callback, NULL);
// loads keymap for x11
x11_use_kbd_mapping = SIM->get_param_bool(BXPN_KBD_USEMAPPING)->get();
if (x11_use_kbd_mapping) {
bx_keymap.loadKeymap(convertStringToXKeysym);
}
#if BX_DEBUGGER && BX_DEBUGGER_GUI
// initialize debugger gui
if (x11_with_debug_gui) {
SIM->set_debug_gui(1);
init_debug_dialog();
}
#endif
new_gfx_api = 1;
dialog_caps |= (BX_GUI_DLG_USER | BX_GUI_DLG_SNAPSHOT | BX_GUI_DLG_CDROM);
}
void set_status_text(int element, const char *text, bx_bool active, bx_bool w)
{
int xleft, xsize, sb_ypos;
xleft = bx_statusitem_pos[element] + 2;
xsize = bx_statusitem_pos[element+1] - xleft;
sb_ypos = dimension_y + bx_headerbar_y;
if (element < 1) {
if (strcmp(bx_status_info_text, text)) {
strcpy(bx_status_info_text, text);
}
XFillRectangle(bx_x_display, win, gc_headerbar_inv, xleft, sb_ypos+2, xsize,
bx_statusbar_y-2);
XDrawString(bx_x_display, win, gc_headerbar, xleft, sb_ypos+bx_statusbar_y-2,
text, strlen(text));
} else if (element <= BX_MAX_STATUSITEMS) {
bx_statusitem_active[element] = active;
if (active) {
if (w)
XSetForeground(bx_x_display, gc_headerbar, bx_status_led_red);
else
XSetForeground(bx_x_display, gc_headerbar, bx_status_led_green);
XFillRectangle(bx_x_display, win, gc_headerbar, xleft, sb_ypos+2, xsize-1, bx_statusbar_y-2);
XSetForeground(bx_x_display, gc_headerbar, black_pixel);
} else {
XFillRectangle(bx_x_display, win, gc_headerbar_inv, xleft, sb_ypos+2, xsize-1, bx_statusbar_y-2);
XSetForeground(bx_x_display, gc_headerbar, bx_status_graytext);
}
XDrawString(bx_x_display, win, gc_headerbar, xleft, sb_ypos+bx_statusbar_y-2,
text, strlen(text));
XSetForeground(bx_x_display, gc_headerbar, black_pixel);
}
}
void bx_x_gui_c::statusbar_setitem_specific(int element, bx_bool active, bx_bool w)
{
set_status_text(element+1, statusitem[element].text, active, w);
}
// This is called whenever the mouse_enabled parameter changes. It
// can change because of a gui event such as clicking on the mouse-enable
- I've added lots of comments in siminterface.h, and tried to clean up the terminology a bit. In particular, the term "gui" has started to mean different things in different contexts, so I've defined some more specific names for the parts of the user interface, and updated comments and some variable names to reflect it. See siminterface.h for a more complete description of all of these. VGAW: VGA display window and toolbar buttons, the traditional Bochs display which is ported to X, win32, MacOS X, etc. Implemented in gui/gui.* and platform dependent gui/*.cc files. CI: configuration interface that lets the user change settings such as floppy disk image, ne2k settings, log options. The CI consists of two parts: configuration user interface (CUI) which does the actual rendering to the screen and handles key/mouse/menu events, and the siminterface object. CUI: configuration user interface. This handles the user interactions that allow the user to configure Bochs. To actually change any values it talks to the siminterface object. One implementation of the CUI is the text-mode menus in gui/control.cc. Another implementation is (will be) the wxWindows menus and dialogs in gui/wxmain.cc. siminterface: the glue between the CUI and the simulation code, accessible throughout the code by the global variable bx_simulator_interface_c *SIM; Among other things, siminterface methods allow the simulator to ask the CUI to display things or ask for user input, and allows the CUI to query and modify variables in the simulation code. GUI: Literally, "graphical user interface". Until the configuration menus and wxWindows came along, everyone understood that "gui" referred to the VGA display window and the toolbar buttons because that's all there was. Now that we have the wxWindows code, which implements both the VGAW and the CUI, while all other platforms implement only the VGAW, it's not so clear. So, I'm trying to use VGAW, CI, and CUI consistently since they are more specific. control panel: This has been used as another name for the configuration interface. "control panel" is also somewhat unspecific and it sounds like it would be graphical with buttons and sliders, but our text-mode thing is not graphical at all. I've replaced "control panel" with "configuration interface" wherever I could find it. In configure script, the --disable-control-panel option is still supported, but it politely suggests that you use --disable-config-interface instead. - clean up comments in siminterface,wx* code - add comments and examples for bx_param_* and BxEvents - remove some obsolete stuff: notify_*_args, bx_simulator_interface_c::[sg]et_enabled() methods - in siminterface.cc, move a few bx_real_sim_c methods to where they belong, with the rest of the methods. No changes to the actual methods. - remove some DOS ^M's which crept in and confused my editor.
2002-08-26 19:31:23 +04:00
// bitmap or pressing the middle button, or from the configuration interface.
// In all those cases, setting the parameter value will get you here.
void bx_x_gui_c::mouse_enabled_changed_specific(bx_bool val)
{
if (val != mouse_captured) {
BX_INFO(("Mouse capture %s", val ? "on":"off"));
sprintf(bx_status_info_text, "%s %sables mouse", get_toggle_info(), val ? "dis":"en");
set_status_text(0, bx_status_info_text, 0);
}
mouse_captured = val;
if (val) {
mouse_enable_x = current_x;
mouse_enable_y = current_y;
disable_cursor();
// Move the cursor to a 'safe' place
warp_cursor(warp_home_x-current_x, warp_home_y-current_y);
} else {
enable_cursor();
warp_cursor(mouse_enable_x-current_x, mouse_enable_y-current_y);
}
#if BX_SHOW_IPS
x11_mouse_msg_counter = 3;
#endif
}
void create_internal_vga_font(void)
{
// Default values
font_width=8;
font_height=16;
for(int i=0; i<256; i++) {
vgafont[i]=XCreateBitmapFromData(bx_x_display, win, (const char*)bx_vgafont[i].data,
font_width, font_height);
if(vgafont[i] == None)
BX_PANIC(("Can't create vga font [%d]", i));
}
}
/* Check to see if this is a repeated key. (grabbed from SDL 1.2)
(idea shamelessly lifted from GII -- thanks guys! :)
*/
static int X11_KeyRepeat(Display *display, XEvent *event)
{
XEvent peekevent;
int repeated;
repeated = 0;
if (XPending(display)) {
XPeekEvent(display, &peekevent);
if ((peekevent.type == KeyPress) &&
(peekevent.xkey.keycode == event->xkey.keycode) &&
((peekevent.xkey.time-event->xkey.time) < 2)) {
repeated = 1;
XNextEvent(display, &peekevent);
}
}
return repeated;
}
void bx_x_gui_c::handle_events(void)
{
XEvent report;
XKeyEvent *key_event;
KeySym keysym;
char buffer[MAX_MAPPED_STRING_LENGTH];
int bufsize = MAX_MAPPED_STRING_LENGTH;
- Apply patch.replace-Boolean rev 1.3. Every "Boolean" is now changed to a "bx_bool" which is always defined as Bit32u on all platforms. In Carbon specific code, Boolean is still used because the Carbon header files define it to unsigned char. - this fixes bug [ 623152 ] MacOSX: Triple Exception Booting win95. The bug was that some code in Bochs depends on Boolean to be a 32 bit value. (This should be fixed, but I don't know all the places where it needs to be fixed yet.) Because Carbon defined Boolean as an unsigned char, Bochs just followed along and used the unsigned char definition to avoid compile problems. This exposed the dependency on 32 bit Boolean on MacOS X only and led to major simulation problems, that could only be reproduced and debugged on that platform. - On the mailing list we debated whether to make all Booleans into "bool" or our own type. I chose bx_bool for several reasons. 1. Unlike C++'s bool, we can guarantee that bx_bool is the same size on all platforms, which makes it much less likely to have more platform-specific simulation differences in the future. (I spent hours on a borrowed MacOSX machine chasing bug 618388 before discovering that different sized Booleans were the problem, and I don't want to repeat that.) 2. We still have at least one dependency on 32 bit Booleans which must be fixed some time, but I don't want to risk introducing new bugs into the simulation just before the 2.0 release. Modified Files: bochs.h config.h.in gdbstub.cc logio.cc main.cc pc_system.cc pc_system.h plugin.cc plugin.h bios/rombios.c cpu/apic.cc cpu/arith16.cc cpu/arith32.cc cpu/arith64.cc cpu/arith8.cc cpu/cpu.cc cpu/cpu.h cpu/ctrl_xfer16.cc cpu/ctrl_xfer32.cc cpu/ctrl_xfer64.cc cpu/data_xfer16.cc cpu/data_xfer32.cc cpu/data_xfer64.cc cpu/debugstuff.cc cpu/exception.cc cpu/fetchdecode.cc cpu/flag_ctrl_pro.cc cpu/init.cc cpu/io_pro.cc cpu/lazy_flags.cc cpu/lazy_flags.h cpu/mult16.cc cpu/mult32.cc cpu/mult64.cc cpu/mult8.cc cpu/paging.cc cpu/proc_ctrl.cc cpu/segment_ctrl_pro.cc cpu/stack_pro.cc cpu/tasking.cc debug/dbg_main.cc debug/debug.h debug/sim2.cc disasm/dis_decode.cc disasm/disasm.h doc/docbook/Makefile docs-html/cosimulation.html fpu/wmFPUemu_glue.cc gui/amigaos.cc gui/beos.cc gui/carbon.cc gui/gui.cc gui/gui.h gui/keymap.cc gui/keymap.h gui/macintosh.cc gui/nogui.cc gui/rfb.cc gui/sdl.cc gui/siminterface.cc gui/siminterface.h gui/term.cc gui/win32.cc gui/wx.cc gui/wxmain.cc gui/wxmain.h gui/x.cc instrument/example0/instrument.cc instrument/example0/instrument.h instrument/example1/instrument.cc instrument/example1/instrument.h instrument/stubs/instrument.cc instrument/stubs/instrument.h iodev/cdrom.cc iodev/cdrom.h iodev/cdrom_osx.cc iodev/cmos.cc iodev/devices.cc iodev/dma.cc iodev/dma.h iodev/eth_arpback.cc iodev/eth_packetmaker.cc iodev/eth_packetmaker.h iodev/floppy.cc iodev/floppy.h iodev/guest2host.h iodev/harddrv.cc iodev/harddrv.h iodev/ioapic.cc iodev/ioapic.h iodev/iodebug.cc iodev/iodev.h iodev/keyboard.cc iodev/keyboard.h iodev/ne2k.h iodev/parallel.h iodev/pci.cc iodev/pci.h iodev/pic.h iodev/pit.cc iodev/pit.h iodev/pit_wrap.cc iodev/pit_wrap.h iodev/sb16.cc iodev/sb16.h iodev/serial.cc iodev/serial.h iodev/vga.cc iodev/vga.h memory/memory.h memory/misc_mem.cc
2002-10-25 15:44:41 +04:00
bx_bool mouse_update;
int y, height;
XPointerMovedEvent *pointer_event;
XEnterWindowEvent *enter_event;
// XLeaveWindowEvent *leave_event;
XButtonEvent *button_event;
XExposeEvent *expose_event;
//current_x = -1;
//current_y = -1;
mouse_update = 0;
while (XPending(bx_x_display) > 0) {
XNextEvent(bx_x_display, &report);
current_z = 0;
if (x11_nokeyrepeat && (report.type == KeyRelease) && X11_KeyRepeat(bx_x_display, &report)) {
return;
}
switch (report.type) {
case Expose:
expose_event = &report.xexpose;
/* Adjust y, and reduce height if it overlaps headerbar. */
y = expose_event->y - BX_HEADER_BAR_Y;
height = expose_event->height;
if (y < 0) {
height += y;
y = 0;
}
Add plugin support to Bochs by merging all the changes from the BRANCH_PLUGINS branch! Authors: Bryce Denney Christophe Bothamy Kevin Lawton (we grabbed a lot of plugin code from plex86) Testing help from: Volker Ruppert Don Becker (Psyon) Jeremy Parsons (Br'fin) The change log is too long to paste in here. To read the change log, do cvs log patches/patch.final-from-BRANCH_PLUGINS.gz All the changes and a detailed description are contained in a patch called patch.final-from-BRANCH_PLUGINS.gz. To look at the complete patch, do cvs upd -r1.1 patches/patch.final-from-BRANCH_PLUGINS.gz Then you will have a local copy of the patch, which you can gunzip and play with however you want. Modified Files: .bochsrc Makefile.in aclocal.m4 bochs.h config.h.in configure configure.in gdbstub.cc logio.cc main.cc pc_system.cc pc_system.h state_file.h bios/Makefile.in bios/rombios.c cpu/Makefile.in cpu/access.cc cpu/apic.cc cpu/arith16.cc cpu/arith32.cc cpu/arith8.cc cpu/cpu.cc cpu/cpu.h cpu/ctrl_xfer32.cc cpu/exception.cc cpu/fetchdecode.cc cpu/fetchdecode64.cc cpu/flag_ctrl.cc cpu/flag_ctrl_pro.cc cpu/init.cc cpu/io.cc cpu/logical16.cc cpu/logical32.cc cpu/logical8.cc cpu/paging.cc cpu/proc_ctrl.cc cpu/protect_ctrl.cc cpu/segment_ctrl_pro.cc cpu/shift16.cc cpu/shift32.cc cpu/stack64.cc cpu/string.cc cpu/tasking.cc debug/Makefile.in debug/dbg_main.cc disasm/Makefile.in doc/docbook/user/user.dbk dynamic/Makefile.in fpu/Makefile.in gui/Makefile.in gui/amigaos.cc gui/beos.cc gui/carbon.cc gui/control.cc gui/control.h gui/gui.cc gui/gui.h gui/keymap.cc gui/keymap.h gui/macintosh.cc gui/nogui.cc gui/rfb.cc gui/sdl.cc gui/sdlkeys.h gui/siminterface.cc gui/siminterface.h gui/term.cc gui/win32.cc gui/wx.cc gui/wxdialog.cc gui/wxdialog.h gui/wxmain.cc gui/wxmain.h gui/x.cc gui/keymaps/sdl-pc-de.map gui/keymaps/sdl-pc-us.map gui/keymaps/x11-pc-de.map instrument/example0/instrument.h instrument/example1/instrument.h instrument/stubs/instrument.cc instrument/stubs/instrument.h iodev/Makefile.in iodev/biosdev.cc iodev/biosdev.h iodev/cdrom.cc iodev/cmos.cc iodev/cmos.h iodev/devices.cc iodev/dma.cc iodev/dma.h iodev/eth_fbsd.cc iodev/eth_linux.cc iodev/eth_null.cc iodev/eth_tap.cc iodev/floppy.cc iodev/floppy.h iodev/guest2host.cc iodev/guest2host.h iodev/harddrv.cc iodev/harddrv.h iodev/iodebug.cc iodev/iodebug.h iodev/iodev.h iodev/keyboard.cc iodev/keyboard.h iodev/ne2k.cc iodev/ne2k.h iodev/parallel.cc iodev/parallel.h iodev/pci.cc iodev/pci.h iodev/pci2isa.cc iodev/pci2isa.h iodev/pic.cc iodev/pic.h iodev/pit.cc iodev/pit.h iodev/pit_wrap.cc iodev/pit_wrap.h iodev/sb16.cc iodev/sb16.h iodev/scancodes.cc iodev/scancodes.h iodev/serial.cc iodev/serial.h iodev/slowdown_timer.cc iodev/slowdown_timer.h iodev/unmapped.cc iodev/unmapped.h iodev/vga.cc iodev/vga.h memory/Makefile.in memory/memory.cc memory/memory.h memory/misc_mem.cc misc/bximage.c misc/niclist.c Added Files: README-plugins extplugin.h ltdl.c ltdl.h ltdlconf.h.in ltmain.sh plugin.cc plugin.h
2002-10-25 01:07:56 +04:00
DEV_vga_redraw_area(
(unsigned) expose_event->x,
y,
(unsigned) expose_event->width,
height);
/* Always draw headerbar, even if not touched by expose event.
* As a small optimization, only do it on last contigous expose.
*/
if (expose_event->count == 0) {
show_headerbar();
}
break;
case ConfigureNotify:
BX_DEBUG(("ConfigureNotify Xevent"));
/* FIXME: It's not clear why we have to show the headerbar here.
* This should be forced by the following expose events.
*/
show_headerbar();
break;
case ButtonPress:
button_event = (XButtonEvent *) &report;
BX_DEBUG(("xxx: buttonpress"));
if (button_event->y < BX_HEADER_BAR_Y) {
BX_DEBUG(("xxx: in headerbar"));
if (mouse_update) {
BX_DEBUG(("xxx: mouse_update=1"));
send_keyboard_mouse_status();
mouse_update = 0;
}
prev_x = current_x = -1;
prev_y = current_y = -1;
headerbar_click(button_event->x, button_event->y);
break;
}
current_x = button_event->x;
current_y = button_event->y;
mouse_update = 1;
BX_DEBUG(("xxx: x,y=(%d,%d)", current_x, current_y));
switch (button_event->button) {
case Button1:
mouse_button_state |= 0x01;
send_keyboard_mouse_status();
mouse_update = 0;
break;
case Button2:
if (mouse_toggle_check(BX_MT_MBUTTON, 1)) {
toggle_mouse_enable();
} else {
mouse_button_state |= 0x04;
send_keyboard_mouse_status();
mouse_update = 0;
}
break;
case Button3:
mouse_button_state |= 0x02;
send_keyboard_mouse_status();
mouse_update = 0;
break;
}
break;
case ButtonRelease:
button_event = (XButtonEvent *) &report;
if (button_event->y < BX_HEADER_BAR_Y) {
if (mouse_update) {
send_keyboard_mouse_status();
mouse_update = 0;
}
prev_x = current_x = -1;
prev_y = current_y = -1;
// ignore, in headerbar area
break;
}
current_x = button_event->x;
current_y = button_event->y;
mouse_update = 1;
switch (button_event->button) {
case Button1:
mouse_button_state &= ~0x01;
send_keyboard_mouse_status();
mouse_update = 0;
break;
case Button2:
mouse_toggle_check(BX_MT_MBUTTON, 0);
mouse_button_state &= ~0x04;
send_keyboard_mouse_status();
mouse_update = 0;
break;
case Button3:
mouse_button_state &= ~0x02;
send_keyboard_mouse_status();
mouse_update = 0;
break;
case Button4:
current_z = 1;
send_keyboard_mouse_status();
mouse_update = 0;
break;
case Button5:
current_z = -1;
send_keyboard_mouse_status();
mouse_update = 0;
break;
}
break;
case KeyPress:
key_event = (XKeyEvent *) &report;
XLookupString(key_event, buffer, bufsize, &keysym, NULL);
xkeypress(keysym, 0);
break;
case KeyRelease:
key_event = (XKeyEvent *) &report;
XLookupString(key_event, buffer, bufsize, &keysym, NULL);
xkeypress(keysym, 1);
break;
case MotionNotify:
pointer_event = (XPointerMovedEvent *) &report;
current_x = pointer_event->x;
current_y = pointer_event->y;
mouse_update = 1;
break;
case EnterNotify:
enter_event = (XEnterWindowEvent *) &report;
prev_x = current_x = enter_event->x;
prev_y = current_y = enter_event->y;
break;
case LeaveNotify:
// leave_event = (XLeaveWindowEvent *) &report;
prev_x = current_x = -1;
prev_y = current_y = -1;
break;
case MapNotify:
/* screen needs redraw, since X would have tossed previous
* requests before window mapped
*/
//retval = 1;
break;
case FocusOut:
DEV_kbd_release_keys();
break;
case ClientMessage:
if (!strcmp(XGetAtomName(bx_x_display, report.xclient.message_type), "WM_PROTOCOLS")) {
bx_stop_simulation();
}
break;
default:
// (mch) Ignore...
BX_DEBUG(("XXX: default Xevent type"));
/* all events selected by StructureNotifyMask are thrown away here,
* since nothing is done with them */
break;
} /* end switch */
} /* end while */
if (mouse_update) {
BX_DEBUG(("handle_events(): send mouse status"));
send_keyboard_mouse_status();
}
#if BX_SHOW_IPS
if (x11_ips_update) {
x11_ips_update = 0;
set_status_text(0, x11_ips_text, 1);
}
#endif
}
void send_keyboard_mouse_status(void)
{
int dx, dy, dz;
BX_DEBUG(("XXX: prev=(%d,%d) curr=(%d,%d)",
prev_x, prev_y, current_x, current_y));
if (x11_mouse_mode_absxy) {
2013-12-23 15:31:32 +04:00
if ((current_y >= (int)bx_headerbar_y) && (current_y < (int)(dimension_y + bx_headerbar_y))) {
dx = current_x * 0x7fff / dimension_x;
dy = (current_y - bx_headerbar_y) * 0x7fff / dimension_y;
dz = current_z;
DEV_mouse_motion(dx, dy, dz, mouse_button_state, 1);
}
prev_x = current_x;
prev_y = current_y;
return;
}
if (((prev_x!=-1) && (current_x!=-1) && (prev_y!=-1) && (current_y!=-1)) ||
(current_z != 0)) {
// (mch) consider warping here
dx = current_x - prev_x - warp_dx;
dy = -(current_y - prev_y - warp_dy);
dz = current_z;
warp_cursor(warp_home_x-current_x, warp_home_y-current_y);
DEV_mouse_motion(dx, dy, dz, mouse_button_state, 0);
prev_x = current_x;
prev_y = current_y;
} else {
if ((current_x!=-1) && (current_y!=-1)) {
prev_x = current_x;
prev_y = current_y;
} else {
prev_x = current_x = -1;
prev_y = current_y = -1;
}
}
}
void bx_x_gui_c::flush(void)
{
if (bx_x_display)
XFlush(bx_x_display);
}
void xkeypress(KeySym keysym, int press_release)
{
Bit32u key_event;
bx_bool mouse_toggle = 0;
if ((keysym == XK_Control_L) || (keysym == XK_Control_R)) {
mouse_toggle = bx_gui->mouse_toggle_check(BX_MT_KEY_CTRL, !press_release);
} else if (keysym == XK_Alt_L) {
mouse_toggle = bx_gui->mouse_toggle_check(BX_MT_KEY_ALT, !press_release);
} else if (keysym == XK_F10) {
mouse_toggle = bx_gui->mouse_toggle_check(BX_MT_KEY_F10, !press_release);
} else if (keysym == XK_F12) {
mouse_toggle = bx_gui->mouse_toggle_check(BX_MT_KEY_F12, !press_release);
}
if (mouse_toggle) {
bx_gui->toggle_mouse_enable();
return;
}
/* Old (no mapping) behavior */
if (!x11_use_kbd_mapping) {
// this depends on the fact that the X11 keysyms which
// correspond to the ascii characters space .. tilde
// are in consequtive order.
if ((keysym >= XK_space) && (keysym <= XK_asciitilde)) {
key_event = ascii_to_key_event[keysym - XK_space];
}
else switch (keysym) {
case XK_KP_1:
#ifdef XK_KP_End
case XK_KP_End:
#endif
key_event = BX_KEY_KP_END; break;
case XK_KP_2:
#ifdef XK_KP_Down
case XK_KP_Down:
#endif
key_event = BX_KEY_KP_DOWN; break;
case XK_KP_3:
#ifdef XK_KP_Page_Down
case XK_KP_Page_Down:
#endif
key_event = BX_KEY_KP_PAGE_DOWN; break;
case XK_KP_4:
#ifdef XK_KP_Left
case XK_KP_Left:
#endif
key_event = BX_KEY_KP_LEFT; break;
case XK_KP_5:
#ifdef XK_KP_Begin
case XK_KP_Begin:
#endif
key_event = BX_KEY_KP_5; break;
case XK_KP_6:
#ifdef XK_KP_Right
case XK_KP_Right:
#endif
key_event = BX_KEY_KP_RIGHT; break;
case XK_KP_7:
#ifdef XK_KP_Home
case XK_KP_Home:
#endif
key_event = BX_KEY_KP_HOME; break;
case XK_KP_8:
#ifdef XK_KP_Up
case XK_KP_Up:
#endif
key_event = BX_KEY_KP_UP; break;
case XK_KP_9:
#ifdef XK_KP_Page_Up
case XK_KP_Page_Up:
#endif
key_event = BX_KEY_KP_PAGE_UP; break;
case XK_KP_0:
#ifdef XK_KP_Insert
case XK_KP_Insert:
#endif
key_event = BX_KEY_KP_INSERT; break;
case XK_KP_Decimal:
#ifdef XK_KP_Delete
case XK_KP_Delete:
#endif
key_event = BX_KEY_KP_DELETE; break;
#ifdef XK_KP_Enter
case XK_KP_Enter: key_event = BX_KEY_KP_ENTER; break;
#endif
case XK_KP_Subtract: key_event = BX_KEY_KP_SUBTRACT; break;
case XK_KP_Add: key_event = BX_KEY_KP_ADD; break;
case XK_KP_Multiply: key_event = BX_KEY_KP_MULTIPLY; break;
case XK_KP_Divide: key_event = BX_KEY_KP_DIVIDE; break;
case XK_Up: key_event = BX_KEY_UP; break;
case XK_Down: key_event = BX_KEY_DOWN; break;
case XK_Left: key_event = BX_KEY_LEFT; break;
case XK_Right: key_event = BX_KEY_RIGHT; break;
case XK_Delete: key_event = BX_KEY_DELETE; break;
case XK_BackSpace: key_event = BX_KEY_BACKSPACE; break;
case XK_Tab: key_event = BX_KEY_TAB; break;
#ifdef XK_ISO_Left_Tab
case XK_ISO_Left_Tab: key_event = BX_KEY_TAB; break;
#endif
case XK_Return: key_event = BX_KEY_ENTER; break;
case XK_Escape: key_event = BX_KEY_ESC; break;
case XK_F1: key_event = BX_KEY_F1; break;
case XK_F2: key_event = BX_KEY_F2; break;
case XK_F3: key_event = BX_KEY_F3; break;
case XK_F4: key_event = BX_KEY_F4; break;
case XK_F5: key_event = BX_KEY_F5; break;
case XK_F6: key_event = BX_KEY_F6; break;
case XK_F7: key_event = BX_KEY_F7; break;
case XK_F8: key_event = BX_KEY_F8; break;
case XK_F9: key_event = BX_KEY_F9; break;
case XK_F10: key_event = BX_KEY_F10; break;
case XK_F11: key_event = BX_KEY_F11; break;
case XK_F12: key_event = BX_KEY_F12; break;
case XK_Control_L: key_event = BX_KEY_CTRL_L; break;
#ifdef XK_Control_R
case XK_Control_R: key_event = BX_KEY_CTRL_R; break;
#endif
case XK_Shift_L: key_event = BX_KEY_SHIFT_L; break;
#ifdef XK_ISO_Prev_Group
case XK_ISO_Prev_Group: key_event = BX_KEY_SHIFT_L; break;
#endif
case XK_Shift_R: key_event = BX_KEY_SHIFT_R; break;
#ifdef XK_ISO_Next_Group
case XK_ISO_Next_Group: key_event = BX_KEY_SHIFT_R; break;
#endif
case XK_Alt_L: key_event = BX_KEY_ALT_L; break;
#ifdef XK_Alt_R
case XK_Alt_R: key_event = BX_KEY_ALT_R; break;
#endif
case XK_Caps_Lock: key_event = BX_KEY_CAPS_LOCK; break;
case XK_Num_Lock: key_event = BX_KEY_NUM_LOCK; break;
#ifdef XK_Scroll_Lock
case XK_Scroll_Lock: key_event = BX_KEY_SCRL_LOCK; break;
#endif
#ifdef XK_Print
case XK_Print: key_event = BX_KEY_PRINT; break;
#endif
#ifdef XK_Pause
case XK_Pause: key_event = BX_KEY_PAUSE; break;
#endif
#ifdef XK_Break
case XK_Break: key_event = BX_KEY_CTRL_BREAK; break;
#endif
case XK_Insert: key_event = BX_KEY_INSERT; break;
case XK_Home: key_event = BX_KEY_HOME; break;
case XK_End: key_event = BX_KEY_END; break;
case XK_Page_Up: key_event = BX_KEY_PAGE_UP; break;
case XK_Page_Down: key_event = BX_KEY_PAGE_DOWN; break;
default:
BX_ERROR(("xkeypress(): keysym %x unhandled!", (unsigned) keysym));
return;
break;
}
}
2002-03-11 18:04:58 +03:00
else {
/* use mapping */
BXKeyEntry *entry = bx_keymap.findHostKey (keysym);
if (!entry) {
BX_ERROR(("xkeypress(): keysym %x unhandled!", (unsigned) keysym));
return;
}
key_event = entry->baseKey;
}
if (press_release)
key_event |= BX_KEY_RELEASED;
Add plugin support to Bochs by merging all the changes from the BRANCH_PLUGINS branch! Authors: Bryce Denney Christophe Bothamy Kevin Lawton (we grabbed a lot of plugin code from plex86) Testing help from: Volker Ruppert Don Becker (Psyon) Jeremy Parsons (Br'fin) The change log is too long to paste in here. To read the change log, do cvs log patches/patch.final-from-BRANCH_PLUGINS.gz All the changes and a detailed description are contained in a patch called patch.final-from-BRANCH_PLUGINS.gz. To look at the complete patch, do cvs upd -r1.1 patches/patch.final-from-BRANCH_PLUGINS.gz Then you will have a local copy of the patch, which you can gunzip and play with however you want. Modified Files: .bochsrc Makefile.in aclocal.m4 bochs.h config.h.in configure configure.in gdbstub.cc logio.cc main.cc pc_system.cc pc_system.h state_file.h bios/Makefile.in bios/rombios.c cpu/Makefile.in cpu/access.cc cpu/apic.cc cpu/arith16.cc cpu/arith32.cc cpu/arith8.cc cpu/cpu.cc cpu/cpu.h cpu/ctrl_xfer32.cc cpu/exception.cc cpu/fetchdecode.cc cpu/fetchdecode64.cc cpu/flag_ctrl.cc cpu/flag_ctrl_pro.cc cpu/init.cc cpu/io.cc cpu/logical16.cc cpu/logical32.cc cpu/logical8.cc cpu/paging.cc cpu/proc_ctrl.cc cpu/protect_ctrl.cc cpu/segment_ctrl_pro.cc cpu/shift16.cc cpu/shift32.cc cpu/stack64.cc cpu/string.cc cpu/tasking.cc debug/Makefile.in debug/dbg_main.cc disasm/Makefile.in doc/docbook/user/user.dbk dynamic/Makefile.in fpu/Makefile.in gui/Makefile.in gui/amigaos.cc gui/beos.cc gui/carbon.cc gui/control.cc gui/control.h gui/gui.cc gui/gui.h gui/keymap.cc gui/keymap.h gui/macintosh.cc gui/nogui.cc gui/rfb.cc gui/sdl.cc gui/sdlkeys.h gui/siminterface.cc gui/siminterface.h gui/term.cc gui/win32.cc gui/wx.cc gui/wxdialog.cc gui/wxdialog.h gui/wxmain.cc gui/wxmain.h gui/x.cc gui/keymaps/sdl-pc-de.map gui/keymaps/sdl-pc-us.map gui/keymaps/x11-pc-de.map instrument/example0/instrument.h instrument/example1/instrument.h instrument/stubs/instrument.cc instrument/stubs/instrument.h iodev/Makefile.in iodev/biosdev.cc iodev/biosdev.h iodev/cdrom.cc iodev/cmos.cc iodev/cmos.h iodev/devices.cc iodev/dma.cc iodev/dma.h iodev/eth_fbsd.cc iodev/eth_linux.cc iodev/eth_null.cc iodev/eth_tap.cc iodev/floppy.cc iodev/floppy.h iodev/guest2host.cc iodev/guest2host.h iodev/harddrv.cc iodev/harddrv.h iodev/iodebug.cc iodev/iodebug.h iodev/iodev.h iodev/keyboard.cc iodev/keyboard.h iodev/ne2k.cc iodev/ne2k.h iodev/parallel.cc iodev/parallel.h iodev/pci.cc iodev/pci.h iodev/pci2isa.cc iodev/pci2isa.h iodev/pic.cc iodev/pic.h iodev/pit.cc iodev/pit.h iodev/pit_wrap.cc iodev/pit_wrap.h iodev/sb16.cc iodev/sb16.h iodev/scancodes.cc iodev/scancodes.h iodev/serial.cc iodev/serial.h iodev/slowdown_timer.cc iodev/slowdown_timer.h iodev/unmapped.cc iodev/unmapped.h iodev/vga.cc iodev/vga.h memory/Makefile.in memory/memory.cc memory/memory.h memory/misc_mem.cc misc/bximage.c misc/niclist.c Added Files: README-plugins extplugin.h ltdl.c ltdl.h ltdlconf.h.in ltmain.sh plugin.cc plugin.h
2002-10-25 01:07:56 +04:00
DEV_kbd_gen_scancode(key_event);
}
void bx_x_gui_c::clear_screen(void)
{
XClearArea(bx_x_display, win, 0, bx_headerbar_y, dimension_x, dimension_y, 0);
}
void bx_x_gui_c::text_update(Bit8u *old_text, Bit8u *new_text,
unsigned long cursor_x, unsigned long cursor_y,
bx_vga_tminfo_t *tm_info)
{
Bit8u *old_line, *new_line, *text_base;
Bit8u cChar, fbits, fmask, frow;
unsigned int curs, hchars, i, j, k, offset, rows, x, y, xc, yc, yc2, cs_y;
unsigned new_foreground, new_background;
Bit8u cfwidth, cfheight, cfheight2, font_col, font_row, font_row2;
Bit8u split_textrow, split_fontrows;
bx_bool forceUpdate = 0, split_screen;
bx_bool blink_state, blink_mode;
unsigned char cell[96];
unsigned long text_palette[16];
blink_mode = (tm_info->blink_flags & BX_TEXT_BLINK_MODE) > 0;
blink_state = (tm_info->blink_flags & BX_TEXT_BLINK_STATE) > 0;
if (blink_mode) {
if (tm_info->blink_flags & BX_TEXT_BLINK_TOGGLE)
forceUpdate = 1;
}
2003-01-17 21:16:02 +03:00
if (charmap_updated) {
BX_INFO(("charmap update. Font is %d x %d", font_width, font_height));
2003-01-17 21:16:02 +03:00
for (unsigned c = 0; c<256; c++) {
if (char_changed[c]) {
XFreePixmap(bx_x_display, vgafont[c]);
bx_bool gfxchar = tm_info->line_graphics && ((c & 0xE0) == 0xC0);
bx_bool dwidth = font_width > 9;
i = 0;
j = 0;
2003-01-17 21:16:02 +03:00
memset(cell, 0, sizeof(cell));
if (dwidth) {
do {
frow = vga_charmap[(c<<5)+j];
fmask = 0x80;
fbits = 0x03;
for (k=0; k<8; k++) {
if (frow & fmask) cell[i] |= fbits;
fmask >>= 1;
fbits <<= 2;
if (k == 3) {
i++;
fbits = 0x03;
}
}
if (gfxchar) {
if (frow & 0x01) cell[i+1] = 0x03;
}
i += 2;
} while (++j < font_height);
vgafont[c] = XCreateBitmapFromData(bx_x_display, win,
(const char*)cell, 18, font_height);
} else {
do {
frow = vga_charmap[(c<<5)+j];
fmask = 0x80;
fbits = 0x01;
for (k=0; k<8; k++) {
if (frow & fmask) cell[i] |= fbits;
fmask >>= 1;
fbits <<= 1;
}
if (gfxchar) {
if (frow & 0x01) cell[i+1] = 0x01;
}
i += 2;
} while (++j < font_height);
vgafont[c] = XCreateBitmapFromData(bx_x_display, win,
(const char*)cell, 9, font_height);
2003-01-17 21:16:02 +03:00
}
if(vgafont[c] == None)
BX_PANIC(("Can't create vga font [%d]", c));
2003-01-17 21:16:02 +03:00
char_changed[c] = 0;
}
}
forceUpdate = 1;
2003-01-17 21:16:02 +03:00
charmap_updated = 0;
}
for (i=0; i<16; i++) {
text_palette[i] = col_vals[tm_info->actl_palette[i]];
}
2003-01-17 21:16:02 +03:00
if((tm_info->h_panning != h_panning) || (tm_info->v_panning != v_panning)) {
forceUpdate = 1;
h_panning = tm_info->h_panning;
v_panning = tm_info->v_panning;
}
if(tm_info->line_compare != line_compare) {
forceUpdate = 1;
line_compare = tm_info->line_compare;
}
// first invalidate character at previous and new cursor location
if ((prev_cursor_y < text_rows) && (prev_cursor_x < text_cols)) {
curs = prev_cursor_y * tm_info->line_offset + prev_cursor_x * 2;
old_text[curs] = ~new_text[curs];
}
if((tm_info->cs_start <= tm_info->cs_end) && (tm_info->cs_start < font_height) &&
(cursor_y < text_rows) && (cursor_x < text_cols)) {
curs = cursor_y * tm_info->line_offset + cursor_x * 2;
old_text[curs] = ~new_text[curs];
} else {
curs = 0xffff;
}
rows = text_rows;
if (v_panning) rows++;
y = 0;
cs_y = 0;
text_base = new_text - tm_info->start_address;
if (line_compare < dimension_y) {
split_textrow = (line_compare + v_panning) / font_height;
split_fontrows = ((line_compare + v_panning) % font_height) + 1;
} else {
split_textrow = rows + 1;
split_fontrows = 0;
}
split_screen = 0;
do {
hchars = text_cols;
if (h_panning) hchars++;
if (split_screen) {
yc = bx_headerbar_y + line_compare + cs_y * font_height + 1;
font_row = 0;
if (rows == 1) {
cfheight = (dimension_y - line_compare - 1) % font_height;
if (cfheight == 0) cfheight = font_height;
} else {
cfheight = font_height;
}
} else if (v_panning) {
if (y == 0) {
yc = bx_headerbar_y;
font_row = v_panning;
cfheight = font_height - v_panning;
} else {
yc = y * font_height + bx_headerbar_y - v_panning;
font_row = 0;
if (rows == 1) {
cfheight = v_panning;
} else {
cfheight = font_height;
}
}
} else {
yc = y * font_height + bx_headerbar_y;
font_row = 0;
cfheight = font_height;
}
if (!split_screen && (y == split_textrow)) {
if (split_fontrows < cfheight) cfheight = split_fontrows;
}
new_line = new_text;
old_line = old_text;
x = 0;
offset = cs_y * tm_info->line_offset;
do {
if (h_panning) {
if (hchars > text_cols) {
xc = 0;
font_col = h_panning;
cfwidth = font_width - h_panning;
} else {
xc = x * font_width - h_panning;
font_col = 0;
if (hchars == 1) {
cfwidth = h_panning;
} else {
cfwidth = font_width;
}
}
} else {
xc = x * font_width;
font_col = 0;
cfwidth = font_width;
}
if (forceUpdate || (old_text[0] != new_text[0])
|| (old_text[1] != new_text[1])) {
cChar = new_text[0];
new_foreground = new_text[1] & 0x0f;
if (blink_mode) {
new_background = (new_text[1] & 0x70) >> 4;
if (!blink_state && (new_text[1] & 0x80))
new_foreground = new_background;
} else {
new_background = (new_text[1] & 0xf0) >> 4;
}
XSetForeground(bx_x_display, gc, text_palette[new_foreground]);
XSetBackground(bx_x_display, gc, text_palette[new_background]);
XCopyPlane(bx_x_display, vgafont[cChar], win, gc, font_col, font_row, cfwidth, cfheight,
xc, yc, 1);
if (offset == curs) {
XSetForeground(bx_x_display, gc, text_palette[new_background]);
XSetBackground(bx_x_display, gc, text_palette[new_foreground]);
if (font_row == 0) {
yc2 = yc + tm_info->cs_start;
font_row2 = tm_info->cs_start;
cfheight2 = tm_info->cs_end - tm_info->cs_start + 1;
if ((yc2 + cfheight2) > (dimension_y + bx_headerbar_y)) {
cfheight2 = dimension_y + bx_headerbar_y - yc2;
}
} else {
if (v_panning > tm_info->cs_start) {
yc2 = yc;
font_row2 = font_row;
cfheight2 = tm_info->cs_end - v_panning + 1;
} else {
yc2 = yc + tm_info->cs_start - v_panning;
font_row2 = tm_info->cs_start;
cfheight2 = tm_info->cs_end - tm_info->cs_start + 1;
}
}
if (yc2 < (dimension_y + bx_headerbar_y)) {
XCopyPlane(bx_x_display, vgafont[cChar], win, gc, font_col, font_row2, cfwidth,
cfheight2, xc, yc2, 1);
}
}
}
x++;
new_text+=2;
old_text+=2;
offset+=2;
} while (--hchars);
if (!split_screen && (y == split_textrow)) {
new_text = text_base;
forceUpdate = 1;
cs_y = 0;
if (tm_info->split_hpanning) h_panning = 0;
rows = ((dimension_y - line_compare + font_height - 2) / font_height) + 1;
split_screen = 1;
} else {
y++;
cs_y++;
new_text = new_line + tm_info->line_offset;
old_text = old_line + tm_info->line_offset;
}
} while (--rows);
h_panning = tm_info->h_panning;
prev_cursor_x = cursor_x;
prev_cursor_y = cursor_y;
XFlush(bx_x_display);
}
int bx_x_gui_c::get_clipboard_text(Bit8u **bytes, Bit32s *nbytes)
{
int len;
Bit8u *tmp = (Bit8u *)XFetchBytes (bx_x_display, &len);
// according to man XFetchBytes, tmp must be freed by XFree(). So allocate
// a new buffer with "new". The keyboard code will free it with delete []
// when the paste is done.
Bit8u *buf = new Bit8u[len];
memcpy (buf, tmp, len);
*bytes = buf;
*nbytes = len;
XFree (tmp);
return 1;
}
int bx_x_gui_c::set_clipboard_text(char *text_snapshot, Bit32u len)
{
// this writes data to the clipboard.
BX_INFO (("storing %d bytes to X windows clipboard", len));
XSetSelectionOwner(bx_x_display, XA_PRIMARY, None, CurrentTime);
XStoreBytes (bx_x_display, (char *)text_snapshot, len);
return 1;
}
void bx_x_gui_c::graphics_tile_update(Bit8u *tile, unsigned x0, unsigned y0)
{
unsigned x, y, y_size;
unsigned color, offset;
Bit8u b0, b1, b2, b3;
if ((y0 + y_tilesize) > dimension_y) {
y_size = dimension_y - y0;
} else {
y_size = y_tilesize;
}
switch (guest_bpp) {
case 8: // 8 bits per pixel
for (y=0; y<y_size; y++) {
for (x=0; x<x_tilesize; x++) {
color = col_vals[tile[y*x_tilesize + x]];
switch (imBPP) {
case 8: // 8 bits per pixel
ximage->data[imWide*y + x] = color;
break;
case 16: // 16 bits per pixel
offset = imWide*y + 2*x;
b0 = color >> 0;
b1 = color >> 8;
if (ximage->byte_order == LSBFirst) {
ximage->data[offset + 0] = b0;
ximage->data[offset + 1] = b1;
}
else { // MSBFirst
ximage->data[offset + 0] = b1;
ximage->data[offset + 1] = b0;
}
break;
case 24: // 24 bits per pixel
offset = imWide*y + 3*x;
b0 = color >> 0;
b1 = color >> 8;
b2 = color >> 16;
if (ximage->byte_order == LSBFirst) {
ximage->data[offset + 0] = b0;
ximage->data[offset + 1] = b1;
ximage->data[offset + 2] = b2;
}
else { // MSBFirst
ximage->data[offset + 0] = b2;
ximage->data[offset + 1] = b1;
ximage->data[offset + 2] = b0;
}
break;
case 32: // 32 bits per pixel
offset = imWide*y + 4*x;
b0 = color >> 0;
b1 = color >> 8;
b2 = color >> 16;
b3 = color >> 24;
if (ximage->byte_order == LSBFirst) {
ximage->data[offset + 0] = b0;
ximage->data[offset + 1] = b1;
ximage->data[offset + 2] = b2;
ximage->data[offset + 3] = b3;
}
else { // MSBFirst
ximage->data[offset + 0] = b3;
ximage->data[offset + 1] = b2;
ximage->data[offset + 2] = b1;
ximage->data[offset + 3] = b0;
}
break;
default:
BX_PANIC(("X_graphics_tile_update: bits_per_pixel %u not implemented",
(unsigned) imBPP));
return;
}
}
}
break;
default:
BX_PANIC(("X_graphics_tile_update: bits_per_pixel %u handled by new graphics API",
(unsigned) guest_bpp));
return;
}
XPutImage(bx_x_display, win, gc, ximage, 0, 0, x0, y0+bx_headerbar_y,
x_tilesize, y_size);
}
bx_svga_tileinfo_t *bx_x_gui_c::graphics_tile_info(bx_svga_tileinfo_t *info)
{
info->bpp = ximage->bits_per_pixel;
info->pitch = ximage->bytes_per_line;
info->red_shift = 0;
info->green_shift = 0;
info->blue_shift = 0;
info->red_mask = ximage->red_mask;
info->green_mask = ximage->green_mask;
info->blue_mask = ximage->blue_mask;
int i, rf, gf, bf;
unsigned long red, green, blue;
i = rf = gf = bf = 0;
red = ximage->red_mask;
green = ximage->green_mask;
blue = ximage->blue_mask;
while (red || rf || green || gf || blue || bf) {
if (rf) {
if (!(red & 1)) {
info->red_shift = i;
rf = 0;
}
}
else {
if (red & 1) {
rf = 1;
}
}
if (gf) {
if (!(green & 1)) {
info->green_shift = i;
gf = 0;
}
}
else {
if (green & 1) {
gf = 1;
}
}
if (bf) {
if (!(blue & 1)) {
info->blue_shift = i;
bf = 0;
}
}
else {
if (blue & 1) {
bf = 1;
}
}
i++;
red >>= 1;
green >>= 1;
blue >>= 1;
}
info->is_indexed = (default_visual->c_class != TrueColor) &&
(default_visual->c_class != DirectColor);
info->is_little_endian = (ximage->byte_order == LSBFirst);
return info;
}
Bit8u *bx_x_gui_c::graphics_tile_get(unsigned x0, unsigned y0,
unsigned *w, unsigned *h)
{
if (x0+x_tilesize > dimension_x) {
*w = dimension_x - x0;
}
else {
*w = x_tilesize;
}
if (y0+y_tilesize > dimension_y) {
*h = dimension_y - y0;
}
else {
*h = y_tilesize;
}
return (Bit8u *)ximage->data + ximage->xoffset*ximage->bits_per_pixel/8;
}
void bx_x_gui_c::graphics_tile_update_in_place(unsigned x0, unsigned y0,
unsigned w, unsigned h)
{
XPutImage(bx_x_display, win, gc, ximage, 0, 0,
x0, y0+bx_headerbar_y, w, h);
}
bx_bool bx_x_gui_c::palette_change(Bit8u index, Bit8u red, Bit8u green, Bit8u blue)
{
// returns: 0=no screen update needed (color map change has direct effect)
// 1=screen updated needed (redraw using current colormap)
XColor color;
color.flags = DoRed | DoGreen | DoBlue;
color.red = red << 8;
color.green = green << 8;
color.blue = blue << 8;
if (x11_private_colormap) {
color.pixel = index;
XStoreColor(bx_x_display, default_cmap, &color);
return(0); // no screen update needed
}
else {
XAllocColor(bx_x_display, DefaultColormap(bx_x_display, bx_x_screen_num),
&color);
col_vals[index] = color.pixel;
return(1); // screen update needed
}
}
void bx_x_gui_c::dimension_update(unsigned x, unsigned y, unsigned fheight, unsigned fwidth, unsigned bpp)
{
if ((bpp == 8) || (bpp == 15) || (bpp == 16) || (bpp == 24) || (bpp == 32)) {
guest_bpp = bpp;
} else {
BX_PANIC(("%d bpp graphics mode not supported", bpp));
}
guest_textmode = (fheight > 0);
guest_xres = x;
guest_yres = y;
if (guest_textmode) {
font_height = fheight;
if (fwidth != font_width) {
font_width = fwidth;
charmap_updated = 1;
for (int i = 0; i < 256; i++) char_changed[i] = 1;
}
text_cols = x / font_width;
text_rows = y / font_height;
}
if ((x != dimension_x) || (y != dimension_y)) {
XSizeHints hints;
long supplied_return;
if (XGetWMNormalHints(bx_x_display, win, &hints, &supplied_return) &&
supplied_return & PMaxSize) {
hints.max_width = hints.min_width = x;
hints.max_height = hints.min_height = y+bx_headerbar_y+bx_statusbar_y;
XSetWMNormalHints(bx_x_display, win, &hints);
}
XResizeWindow(bx_x_display, win, x, y+bx_headerbar_y+bx_statusbar_y);
dimension_x = x;
dimension_y = y;
warp_home_x = x / 2;
warp_home_y = y / 2;
}
}
void bx_x_gui_c::show_headerbar(void)
{
unsigned xorigin;
int xleft, xright, sb_ypos;
sb_ypos = dimension_y + bx_headerbar_y;
// clear header bar and status bar area to white
XFillRectangle(bx_x_display, win, gc_headerbar_inv, 0,0, dimension_x, bx_headerbar_y);
XFillRectangle(bx_x_display, win, gc_headerbar_inv, 0,sb_ypos, dimension_x, bx_statusbar_y);
xleft = 0;
xright = dimension_x;
for (unsigned i=0; i<bx_headerbar_entries; i++) {
if (bx_headerbar_entry[i].alignment == BX_GRAVITY_LEFT) {
xorigin = bx_headerbar_entry[i].xorigin;
xleft += bx_headerbar_entry[i].xdim;
}
else {
xorigin = dimension_x - bx_headerbar_entry[i].xorigin;
xright = xorigin;
}
if (xright < xleft) break;
XCopyPlane(bx_x_display, bx_headerbar_entry[i].bitmap, win, gc_headerbar,
0,0, bx_headerbar_entry[i].xdim, bx_headerbar_entry[i].ydim,
xorigin, 0, 1);
}
for (unsigned i=0; i<12; i++) {
xleft = bx_statusitem_pos[i];
if (i > 0) {
XDrawLine(bx_x_display, win, gc_inv, xleft, sb_ypos+1, xleft,
sb_ypos+bx_statusbar_y);
if (i <= statusitem_count) {
set_status_text(i, statusitem[i-1].text, bx_statusitem_active[i]);
}
} else {
set_status_text(0, bx_status_info_text, 0);
}
}
}
unsigned bx_x_gui_c::create_bitmap(const unsigned char *bmap, unsigned xdim, unsigned ydim)
{
if (bx_bitmap_entries >= BX_MAX_PIXMAPS) {
BX_PANIC(("x: too many pixmaps, increase BX_MAX_PIXMAPS"));
}
bx_bitmaps[bx_bitmap_entries].bmap =
XCreateBitmapFromData(bx_x_display, win, (const char *) bmap, xdim, ydim);
bx_bitmaps[bx_bitmap_entries].xdim = xdim;
bx_bitmaps[bx_bitmap_entries].ydim = ydim;
if (!bx_bitmaps[bx_bitmap_entries].bmap) {
BX_PANIC(("x: could not create bitmap"));
}
bx_bitmap_entries++;
return(bx_bitmap_entries-1); // return index as handle
}
unsigned bx_x_gui_c::headerbar_bitmap(unsigned bmap_id, unsigned alignment, void (*f)(void))
{
unsigned hb_index;
if ((bx_headerbar_entries+1) > BX_MAX_HEADERBAR_ENTRIES)
BX_PANIC(("x: too many headerbar entries, increase BX_MAX_HEADERBAR_ENTRIES"));
bx_headerbar_entries++;
hb_index = bx_headerbar_entries - 1;
bx_headerbar_entry[hb_index].bitmap = bx_bitmaps[bmap_id].bmap;
bx_headerbar_entry[hb_index].xdim = bx_bitmaps[bmap_id].xdim;
bx_headerbar_entry[hb_index].ydim = bx_bitmaps[bmap_id].ydim;
bx_headerbar_entry[hb_index].alignment = alignment;
bx_headerbar_entry[hb_index].f = f;
if (alignment == BX_GRAVITY_LEFT) {
bx_headerbar_entry[hb_index].xorigin = bx_bitmap_left_xorigin;
bx_headerbar_entry[hb_index].yorigin = 0;
bx_bitmap_left_xorigin += bx_bitmaps[bmap_id].xdim;
}
else { // BX_GRAVITY_RIGHT
bx_bitmap_right_xorigin += bx_bitmaps[bmap_id].xdim;
bx_headerbar_entry[hb_index].xorigin = bx_bitmap_right_xorigin;
bx_headerbar_entry[hb_index].yorigin = 0;
}
return(hb_index);
}
void bx_x_gui_c::replace_bitmap(unsigned hbar_id, unsigned bmap_id)
{
unsigned xorigin;
bx_headerbar_entry[hbar_id].bitmap = bx_bitmaps[bmap_id].bmap;
if (bx_headerbar_entry[hbar_id].alignment == BX_GRAVITY_LEFT)
xorigin = bx_headerbar_entry[hbar_id].xorigin;
else
xorigin = dimension_x - bx_headerbar_entry[hbar_id].xorigin;
XCopyPlane(bx_x_display, bx_headerbar_entry[hbar_id].bitmap, win, gc_headerbar,
0,0, bx_headerbar_entry[hbar_id].xdim, bx_headerbar_entry[hbar_id].ydim,
xorigin, 0, 1);
}
void headerbar_click(int x, int y)
{
int xorigin;
// assuming y is in bounds
UNUSED(y);
for (unsigned i=0; i<bx_headerbar_entries; i++) {
if (bx_headerbar_entry[i].alignment == BX_GRAVITY_LEFT)
xorigin = bx_headerbar_entry[i].xorigin;
else
xorigin = dimension_x - bx_headerbar_entry[i].xorigin;
if ((x>=xorigin) && (x<(xorigin+int(bx_headerbar_entry[i].xdim)))) {
bx_headerbar_entry[i].f();
return;
}
}
}
void bx_x_gui_c::exit(void)
{
if (!x_init_done) return;
2003-01-17 21:16:02 +03:00
// Delete the font bitmaps
for (int i=0; i<256; i++) {
//if (vgafont[i] != NULL)
XFreePixmap(bx_x_display,vgafont[i]);
2003-01-17 21:16:02 +03:00
}
if (mouse_captured)
enable_cursor();
#if BX_DEBUGGER && BX_DEBUGGER_GUI
if (SIM->has_debug_gui()) {
close_debug_dialog();
}
#endif
if (bx_x_display)
XCloseDisplay(bx_x_display);
BX_INFO(("Exit"));
}
static void warp_cursor (int dx, int dy)
{
if (mouse_captured && (warp_dx || warp_dy || dx || dy)) {
warp_dx = dx;
warp_dy = dy;
XWarpPointer(bx_x_display, None, None, 0, 0, 0, 0, dx, dy);
}
}
static void disable_cursor()
{
static Cursor cursor;
static unsigned cursor_created = 0;
static int shape_width = 16,
shape_height = 16,
mask_width = 16,
mask_height = 16;
static Bit32u shape_bits[(16*16)/32] = {
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
};
static Bit32u mask_bits[(16*16)/32] = {
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
};
if (!cursor_created) {
Pixmap shape, mask;
XColor white, black;
shape = XCreatePixmapFromBitmapData(bx_x_display,
RootWindow(bx_x_display,bx_x_screen_num),
(char*)shape_bits,
shape_width,
shape_height,
1, 0, 1);
mask = XCreatePixmapFromBitmapData(bx_x_display,
RootWindow(bx_x_display,bx_x_screen_num),
(char*)mask_bits,
mask_width,
mask_height,
1, 0, 1);
XParseColor(bx_x_display, default_cmap, "black", &black);
XParseColor(bx_x_display, default_cmap, "white", &white);
cursor = XCreatePixmapCursor(bx_x_display, shape, mask,
&white, &black, 1, 1);
cursor_created = 1;
}
XDefineCursor(bx_x_display, win, cursor);
}
static void enable_cursor()
{
XUndefineCursor(bx_x_display, win);
}
/* convertStringToXKeysym is a keymap callback
* used when reading the keymap file.
* It converts a Symblic String to a GUI Constant
*
* It returns a Bit32u constant or BX_KEYMAP_UNKNOWN if it fails
*/
static Bit32u convertStringToXKeysym (const char *string)
{
if (strncmp ("XK_", string, 3) != 0)
return BX_KEYMAP_UNKNOWN;
KeySym keysym=XStringToKeysym(string+3);
// failure, return unknown
if(keysym==NoSymbol) return BX_KEYMAP_UNKNOWN;
return((Bit32u)keysym);
}
#if BX_USE_IDLE_HACK
/* BX_USE_IDLE_HACK: a small idle hack by
* Roland.Mainz@informatik.med.uni-giessen.de to prevent bochs
* from consuming 100% CPU time even when it is not required (for
* example, the OS in the emulator calls HLT to wait for an interupt)
* pro:
* - no more 100% CPU usage
* contra:
* - we're sleeping too long
* - bochs still consumes ~10%-20% CPU time while executing an idle
* linux kernel
* - this is an hack
*/
/* XPeekEvent() with timeout
* (adopted from mozilla/gfx/src/xprint/xprintutil_printtofile.c#XNextEventTimeout())
*/
static
Bool XPeekEventTimeout(Display *display, XEvent *event_return, struct timeval *timeout)
{
int res;
fd_set readfds;
int display_fd = XConnectionNumber(display);
/* small shortcut... */
if(timeout == NULL)
{
XPeekEvent(display, event_return);
return(True);
}
FD_ZERO(&readfds);
FD_SET(display_fd, &readfds);
/* Note/bug: In the case of internal X events (like used to trigger callbacks
* registered by XpGetDocumentData()&co.) select() will return with "new info"
* - but XNextEvent() below processes these _internal_ events silently - and
* will block if there are no other non-internal events.
* The workaround here is to check with XEventsQueued() if there are non-internal
* events queued - if not select() will be called again - unfortunately we use
* the old timeout here instead of the "remaining" time... (this only would hurt
* if the timeout would be really long - but for current use with values below
* 1/2 secs it does not hurt... =:-)
*/
while(XEventsQueued(display, QueuedAfterFlush) == 0)
{
res = select(display_fd+1, &readfds, NULL, NULL, timeout);
switch(res)
{
case -1: /* select() error - should not happen */
if (errno == EINTR)
break; // caused e.g. by alarm(3)
perror("XPeekEventTimeout: select() failure");
return(False);
case 0: /* timeout */
return(False);
}
}
XPeekEvent(display, event_return);
return(True);
}
void bx_x_gui_c::sim_is_idle()
{
XEvent dummy;
struct timeval timeout;
timeout.tv_sec = 0;
timeout.tv_usec = 1000; /* 1/1000 s */
XPeekEventTimeout(bx_x_display, &dummy, &timeout);
}
#endif /* BX_USE_IDLE_HACK */
- apply patch.ifdef-disabled-options. Comments from that patch are below: For a whole lot of configure options, I put #if...#endif around code that is specific to the option, even in files which are normally only compiled when the option is on. This allows me to create a MS Visual C++ 6.0 workspace that supports many of these options. The workspace will basically compile every file all the time, but the code for disabled options will be commented out by the #if...#endif. This may one day lead to simplification of the Makefiles and configure scripts, but for the moment I'm leaving Makefiles and configure scripts alone. Affected options: BX_SUPPORT_APIC (cpu/apic.cc) BX_SUPPORT_X86_64 (cpu/*64.cc) BX_DEBUGGER (debug/*) BX_DISASM (disasm/*) BX_WITH_nameofgui (gui/*) BX_SUPPORT_CDROM (iodev/cdrom.cc) BX_NE2K_SUPPORT (iodev/eth*.cc, iodev/ne2k.cc) BX_SUPPORT_APIC (iodev/ioapic.cc) BX_IODEBUG_SUPPORT (iodev/iodebug.cc) BX_PCI_SUPPORT (iodev/pci*.cc) BX_SUPPORT_SB16 (iodev/sb*.cc) Modified Files: cpu/apic.cc cpu/arith64.cc cpu/ctrl_xfer64.cc cpu/data_xfer64.cc cpu/fetchdecode64.cc cpu/logical64.cc cpu/mult64.cc cpu/resolve64.cc cpu/shift64.cc cpu/stack64.cc debug/Makefile.in debug/crc.cc debug/dbg_main.cc debug/lexer.l debug/linux.cc debug/parser.c debug/parser.y disasm/dis_decode.cc disasm/dis_groups.cc gui/amigaos.cc gui/beos.cc gui/carbon.cc gui/macintosh.cc gui/rfb.cc gui/sdl.cc gui/term.cc gui/win32.cc gui/wx.cc gui/wxdialog.cc gui/wxmain.cc gui/x.cc iodev/cdrom.cc iodev/eth.cc iodev/eth_arpback.cc iodev/eth_fbsd.cc iodev/eth_linux.cc iodev/eth_null.cc iodev/eth_packetmaker.cc iodev/eth_tap.cc iodev/eth_tuntap.cc iodev/eth_win32.cc iodev/ioapic.cc iodev/iodebug.cc iodev/ne2k.cc iodev/pci.cc iodev/pci2isa.cc iodev/sb16.cc iodev/soundlnx.cc iodev/soundwin.cc
2002-11-19 08:47:45 +03:00
void bx_x_gui_c::beep_on(float frequency)
{
BX_INFO(("X11 Beep ON (frequency=%.2f)",frequency));
}
void bx_x_gui_c::beep_off()
{
BX_INFO(("X11 Beep OFF"));
}
void bx_x_gui_c::get_capabilities(Bit16u *xres, Bit16u *yres, Bit16u *bpp)
{
int num_sizes;
Rotation original_rotation;
int event_base, error_base;
Display *dpy = XOpenDisplay(NULL);
if (dpy == NULL) {
BX_PANIC(("Cannot connect to X display"));
}
Window root = RootWindow(dpy, 0);
if (XRRQueryExtension (dpy, &event_base, &error_base)) {
XRRScreenSize *xrrs = XRRSizes(dpy, 0, &num_sizes);
XRRScreenConfiguration *conf = XRRGetScreenInfo(dpy, root);
SizeID original_size_id = XRRConfigCurrentConfiguration(conf, &original_rotation);
*xres = xrrs[original_size_id].width;
*yres = xrrs[original_size_id].height;
2014-04-06 23:01:38 +04:00
free(conf);
}
else {
int screen = DefaultScreen(dpy);
*xres = DisplayWidth(dpy, screen);
*yres = DisplayHeight(dpy, screen);
}
XCloseDisplay(dpy);
// always return 32 bit depth
*bpp = 32;
}
void bx_x_gui_c::set_mouse_mode_absxy(bx_bool mode)
{
x11_mouse_mode_absxy = mode;
}
#if BX_SHOW_IPS
void bx_x_gui_c::show_ips(Bit32u ips_count)
{
if (x11_mouse_msg_counter == 0) {
if (!x11_ips_update && !x11_hide_ips) {
ips_count /= 1000;
sprintf(x11_ips_text, "IPS: %u.%3.3uM", ips_count / 1000, ips_count % 1000);
x11_ips_update = 1;
}
} else {
x11_mouse_msg_counter--;
}
}
#endif
// X11 control class
enum {
XDC_BUTTON = 0,
XDC_EDIT,
XDC_CHECKBOX
};
class x11_control_c {
public:
x11_control_c(int type, int x, int y, unsigned int w, unsigned int h,
const char *text);
virtual ~x11_control_c();
void draw(Display *display, Window win, GC gc);
void draw_rect(Display *display, Window win, GC gc);
void draw_text(Display *display, Window win, GC gc, const char *text);
void set_pos(int x, int y);
int test(XButtonEvent *bev);
int get_type() {return type;}
void set_param(int value) {param = value;}
int get_param() {return param;}
const char* get_text() {return text;}
// checkbox
int get_status() {return status;}
void set_status(bx_bool new_stat) {status = new_stat;}
// edit
void set_maxlen(unsigned int max);
int process_input(KeySym key, const char *str);
const char* get_value() {return value;}
private:
unsigned int width, height;
int type, param, xmin, xmax, ymin, ymax;
const char *text;
// checkbox
bx_bool status;
// edit
char *value;
char editstr[27];
unsigned int len, pos, max;
};
x11_control_c::x11_control_c(int _type, int x, int y, unsigned int w, unsigned int h,
const char *_text)
{
type = _type;
width = w;
height = h;
set_pos(x, y);
param = 0;
if (type == XDC_EDIT) {
len = strlen(_text);
max = len;
value = new char[max+1];
strcpy(value, _text);
pos = (len < 25) ? 0 : (len - 24);
strncpy(editstr, value+pos, 24);
editstr[len-pos] = 0;
text = editstr;
} else {
text = _text;
value = NULL;
if (type == XDC_CHECKBOX) {
status = !strcmp(text, "X");
}
}
}
x11_control_c::~x11_control_c()
{
if (value != NULL) free(value);
}
void x11_control_c::set_pos(int x, int y)
{
xmin = x;
ymin = y;
xmax = x + width;
ymax = y + height;
}
void x11_control_c::draw(Display *display, Window win, GC gc)
{
int ty;
XDrawRectangle(display, win, gc, xmin, ymin, width, height);
ty = ymin + height - (height - 12) / 2;
XDrawImageString(display, win, gc, xmin+4, ty, (char *)text, strlen(text));
}
void x11_control_c::draw_rect(Display *display, Window win, GC gc)
{
XDrawRectangle(display, win, gc, xmin - 2, ymin - 2, width + 4, height + 4);
}
void x11_control_c::draw_text(Display *display, Window win, GC gc, const char *_text)
{
int ty;
ty = ymin + height - (height - 12) / 2;
XDrawImageString(display, win, gc, xmin+4, ty, (char *)_text, strlen(_text));
}
int x11_control_c::test(XButtonEvent *bev)
{
if ((bev->y > ymin) && (bev->y < ymax)) {
if ((bev->x > xmin) && (bev->x < xmax)) {
return 1;
}
}
return 0;
}
void x11_control_c::set_maxlen(unsigned int _max)
{
max = _max;
char *newval = new char[max+1];
strcpy(newval, value);
delete [] value;
value = newval;
}
int x11_control_c::process_input(KeySym key, const char *str)
{
int ret = 0;
if (key == XK_BackSpace) {
if (len > 0) {
value[--len] = 0;
if (pos > 0) pos--;
ret = 1;
}
} else if ((key == 0) && (len < max)) {
strcat(value, str);
len = strlen(value);
if (len > 24) pos++;
ret = 1;
}
strncpy(editstr, value+pos, 24);
editstr[len-pos] = 0;
return ret;
}
// X11 static text structure
typedef struct _x11_static_t {
char *text;
int x, y;
struct _x11_static_t *next;
} x11_static_t;
// X11 dialog class
class x11_dialog_c {
public:
x11_dialog_c(const char *name, int width, int _height, int num_ctrls);
virtual ~x11_dialog_c();
int add_control(int type, int x, int y, unsigned int width, unsigned int height,
const char *text);
int add_button(const char *text);
void add_static_text(int x, int y, const char *text, int length);
void draw_text(Display *display, int x, int y, const char *text, int length);
void set_control_param(int id, int value);
int run(int start_ctrl, int ok, int cancel);
x11_control_c* get_control(int id);
private:
Window dlgwin;
GC gc, gc_inv;
int btn_base, ctrl_cnt, cur_ctrl, old_ctrl, height, width;
x11_control_c **controls;
x11_static_t *static_items;
};
x11_dialog_c::x11_dialog_c(const char *name, int _width, int _height, int num_ctrls)
{
Window dialogw;
XSizeHints hint;
unsigned long black_pixel, white_pixel;
width = _width;
height = _height;
hint.flags = PPosition | PSize | PMinSize | PMaxSize;
hint.x = 100;
hint.y = 100;
hint.width = hint.min_width = hint.max_width = width;
hint.height = hint.min_height = hint.max_height = height;
black_pixel = BlackPixel(bx_x_display, bx_x_screen_num);
white_pixel = WhitePixel(bx_x_display, bx_x_screen_num);
dialogw = XCreateSimpleWindow(bx_x_display, RootWindow(bx_x_display,bx_x_screen_num),
hint.x, hint.y, hint.width, hint.height, 4, black_pixel, white_pixel);
XSetStandardProperties(bx_x_display, dialogw, name, name, None, NULL, 0, &hint);
Atom wm_delete = XInternAtom(bx_x_display, "WM_DELETE_WINDOW", 1);
XSetWMProtocols(bx_x_display, dialogw, &wm_delete, 1);
gc = XCreateGC(bx_x_display, dialogw, 0, 0);
gc_inv = XCreateGC(bx_x_display, dialogw, 0, 0);
XSetState(bx_x_display, gc_inv, white_pixel, black_pixel, GXcopy, AllPlanes);
XSetBackground(bx_x_display, gc, WhitePixel(bx_x_display, bx_x_screen_num));
XSetForeground(bx_x_display, gc, BlackPixel(bx_x_display, bx_x_screen_num));
XSelectInput(bx_x_display, dialogw, ButtonPressMask
| ButtonReleaseMask
| KeyPressMask
| KeyReleaseMask
| ExposureMask
| PointerMotionMask
| EnterWindowMask
| LeaveWindowMask);
XMapWindow(bx_x_display, dialogw);
XFlush(bx_x_display);
dlgwin = dialogw;
btn_base = 0;
ctrl_cnt = num_ctrls;
controls = new x11_control_c* [num_ctrls];
static_items = NULL;
cur_ctrl = 0;
old_ctrl = -1;
}
x11_dialog_c::~x11_dialog_c()
{
x11_static_t *temp;
for (int i = 0; i < ctrl_cnt; i++) {
delete controls[i];
}
delete [] controls;
while (static_items != NULL) {
temp = static_items;
static_items = temp->next;
delete [] temp->text;
delete temp;
}
XFreeGC(bx_x_display, gc);
XFreeGC(bx_x_display, gc_inv);
XDestroyWindow(bx_x_display, dlgwin);
}
int x11_dialog_c::add_control(int type, int x, int y, unsigned int w,
unsigned int h, const char *text)
{
x11_control_c *xctrl = new x11_control_c(type, x, y, w, h, text);
if (cur_ctrl < ctrl_cnt) {
controls[cur_ctrl] = xctrl;
}
if (type != XDC_BUTTON) {
btn_base = cur_ctrl + 1;
}
return cur_ctrl++;
}
int x11_dialog_c::add_button(const char *text)
{
int btn_id = add_control(XDC_BUTTON, 0, height - 30, 65, 20, text);
int n = cur_ctrl - btn_base;
int x0 = (width - ((n * 65) + ((n - 1) * 20))) / 2;
for (int i = btn_base; i < cur_ctrl; i++) {
controls[i]->set_pos(x0, height - 30);
x0 += 85;
}
return btn_id;
}
void x11_dialog_c::add_static_text(int x, int y, const char *text, int length)
{
x11_static_t *static_item, *temp;
static_item = new x11_static_t;
static_item->x = x;
static_item->y = y;
static_item->text = new char[length+1];
strncpy(static_item->text, text, length);
static_item->text[length] = 0;
static_item->next = NULL;
if (static_items == NULL) {
static_items = static_item;
} else {
temp = static_items;
while (temp->next) {
temp = temp->next;
}
temp->next = static_item;
}
}
void x11_dialog_c::draw_text(Display *display, int x, int y, const char *text, int length)
{
XDrawImageString(display, dlgwin, gc, x, y, text, length);
}
void x11_dialog_c::set_control_param(int id, int value)
{
if (id < ctrl_cnt) {
controls[id]->set_param(value);
}
}
int x11_dialog_c::run(int start_ctrl, int ok, int cancel)
{
XEvent xevent;
KeySym key;
bx_bool done = 0, valid = 0, status;
int i, init = 0;
char text[10], editstr[27];
x11_static_t *temp;
if (start_ctrl < 0) {
cur_ctrl = ctrl_cnt - 1;
} else {
cur_ctrl = start_ctrl;
}
while (!done) {
XNextEvent(bx_x_display, &xevent);
switch (xevent.type) {
case Expose:
if (xevent.xexpose.count == 0) {
temp = static_items;
while (temp != NULL) {
draw_text(xevent.xexpose.display, temp->x, temp->y, temp->text, strlen(temp->text));
temp = temp->next;
}
for (i = 0; i < ctrl_cnt; i++) {
controls[i]->draw(xevent.xexpose.display, dlgwin, gc);
}
old_ctrl = cur_ctrl - 1;
if (old_ctrl < 0) old_ctrl = ctrl_cnt - 1;
init = 1;
}
break;
case ButtonPress:
if (xevent.xbutton.button == Button1) {
for (i = 0; i < ctrl_cnt; i++) {
if (controls[i]->test(&xevent.xbutton)) {
cur_ctrl = i;
if (controls[cur_ctrl]->get_type() == XDC_BUTTON) {
valid = 1;
} else if (controls[cur_ctrl]->get_type() == XDC_CHECKBOX) {
status = !controls[cur_ctrl]->get_status();
controls[cur_ctrl]->set_status(status);
controls[cur_ctrl]->draw_text(bx_x_display, dlgwin, gc, status ? "X":" ");
}
break;
}
}
}
break;
case ButtonRelease:
if ((xevent.xbutton.button == Button1) && (valid == 1)) {
done = 1;
}
break;
case KeyPress:
i = XLookupString((XKeyEvent *)&xevent, text, 10, &key, 0);
if (key == XK_Tab) {
cur_ctrl++;
if (cur_ctrl >= ctrl_cnt) cur_ctrl = 0;
} else if (key == XK_Escape) {
cur_ctrl = cancel;
done = 1;
} else if (controls[cur_ctrl]->get_type() == XDC_EDIT) {
if (key == XK_Return) {
cur_ctrl = ok;
done = 1;
} else if (key == XK_BackSpace) {
if (controls[cur_ctrl]->process_input(key, "")) {
old_ctrl = cur_ctrl ^ 1;
}
} else if (i == 1) {
if (controls[cur_ctrl]->process_input(0, text)) {
old_ctrl = cur_ctrl ^ 1;
}
}
} else if (controls[cur_ctrl]->get_type() == XDC_CHECKBOX) {
if (key == XK_space) {
status = !controls[cur_ctrl]->get_status();
controls[cur_ctrl]->set_status(status);
controls[cur_ctrl]->draw_text(bx_x_display, dlgwin, gc, status ? "X":" ");
} else if (key == XK_Return) {
cur_ctrl = ok;
done = 1;
}
} else if ((key == XK_space) || (key == XK_Return)) {
done = 1;
}
break;
case ClientMessage:
if (!strcmp(XGetAtomName(bx_x_display, xevent.xclient.message_type), "WM_PROTOCOLS")) {
cur_ctrl = cancel;
done = 1;
}
break;
case LeaveNotify:
valid = 0;
break;
}
if (init > 0) {
if ((init == 1) || (cur_ctrl != old_ctrl)) {
if (controls[old_ctrl]->get_type() == XDC_EDIT) {
sprintf(editstr, "%s ", controls[old_ctrl]->get_text());
controls[old_ctrl]->draw_text(bx_x_display, dlgwin, gc, editstr);
} else {
controls[old_ctrl]->draw_rect(bx_x_display, dlgwin, gc_inv);
}
if (controls[cur_ctrl]->get_type() == XDC_EDIT) {
sprintf(editstr, "%s_ ", controls[cur_ctrl]->get_text());
controls[cur_ctrl]->draw_text(bx_x_display, dlgwin, gc, editstr);
} else {
controls[cur_ctrl]->draw_rect(bx_x_display, dlgwin, gc);
}
old_ctrl = cur_ctrl;
init = 2;
}
}
}
return cur_ctrl;
}
x11_control_c* x11_dialog_c::get_control(int id)
{
if (id < ctrl_cnt) {
return controls[id];
} else {
return NULL;
}
}
// X11 dialog box functions
int x11_ask_dialog(BxEvent *event)
{
#if BX_DEBUGGER || BX_GDBSTUB
const int num_ctrls = 4;
int debug_id;
#else
const int num_ctrls = 3;
#endif
int level, cpos, retcode, cont_id, cont2_id, quit_id, ctrl_id;
const char *name;
char device[18], message[512];
level = event->u.logmsg.level;
name = SIM->get_log_level_name(level);
sprintf(device, "Device: %s", event->u.logmsg.prefix);
sprintf(message, "Message: %s", event->u.logmsg.msg);
x11_dialog_c *xdlg = new x11_dialog_c(name, 400, 110, num_ctrls);
xdlg->add_static_text(20, 25, device, strlen(device));
if (strlen(message) > 62) {
cpos = 62;
while ((cpos > 0) && (!isspace(message[cpos]))) cpos--;
xdlg->add_static_text(20, 45, message, cpos);
xdlg->add_static_text(74, 63, message+cpos+1, strlen(message)-cpos-1);
} else {
xdlg->add_static_text(20, 45, message, strlen(message));
}
cont_id = xdlg->add_button("Continue");
xdlg->set_control_param(cont_id, BX_LOG_ASK_CHOICE_CONTINUE);
cont2_id = xdlg->add_button("Alwayscont");
xdlg->set_control_param(cont2_id, BX_LOG_ASK_CHOICE_CONTINUE_ALWAYS);
#if BX_DEBUGGER || BX_GDBSTUB
debug_id = xdlg->add_button("Debugger");
xdlg->set_control_param(debug_id, BX_LOG_ASK_CHOICE_ENTER_DEBUG);
#endif
quit_id = xdlg->add_button("Quit");
xdlg->set_control_param(quit_id, BX_LOG_ASK_CHOICE_DIE);
ctrl_id = xdlg->run(quit_id, cont_id, quit_id);
retcode = xdlg->get_control(ctrl_id)->get_param();
delete xdlg;
return retcode;
}
int x11_string_dialog(bx_param_string_c *param, bx_param_enum_c *param2)
{
x11_control_c *xctl_edit, *xbtn_status = NULL;
int h, num_ctrls, ctrl_id, edit_id, status_id, ok_id, cancel_id, retcode = -1;
bx_bool status = 0;
char name[80], text[10];
const char *value;
if (param2 != NULL) {
strcpy(name, "First CD-ROM image/device");
status = (param2->get() == BX_INSERTED);
h = 110;
num_ctrls = 4;
} else {
if (param->get_label() != NULL) {
strcpy(name, param->get_label());
} else {
strcpy(name, param->get_name());
}
h = 90;
num_ctrls = 3;
}
x11_dialog_c *xdlg = new x11_dialog_c(name, 250, h, num_ctrls);
edit_id = xdlg->add_control(XDC_EDIT, 45, 20, 160, 20, param->getptr());
xctl_edit = xdlg->get_control(edit_id);
xctl_edit->set_maxlen(param->get_maxsize());
if (param2 != NULL) {
strcpy(text, status ? "X":" ");
status_id = xdlg->add_control(XDC_CHECKBOX, 45, 50, 15, 16, text);
xbtn_status = xdlg->get_control(status_id);
xdlg->add_static_text(70, 62, "Inserted", 8);
}
ok_id = xdlg->add_button("OK");
cancel_id = xdlg->add_button("Cancel");
ctrl_id = xdlg->run(edit_id, ok_id, cancel_id);
if (ctrl_id == ok_id) {
value = xctl_edit->get_value();
if (param2 != NULL) {
status = xbtn_status->get_status();
if (status == 1) {
if (strlen(value) > 0) {
param->set(value);
param2->set(1);
} else {
param2->set(0);
}
} else {
param2->set(0);
}
} else {
param->set(value);
}
retcode = 1;
}
delete xdlg;
return retcode;
}
#define XDLG_SIMPLE 0
#define XDLG_OK_CANCEL 1
#define XDLG_YES_NO 2
int x11_message_box(bx_param_bool_c *param, int mode)
{
int size_x, size_y;
int ctrl_id, yes_id, no_id, ypos;
unsigned int loffs[10], llen[10];
unsigned int i, cpos, len, maxlen, lines;
const char *name, *message;
if (param->get_label() != NULL) {
name = param->get_label();
} else {
name = param->get_name();
}
message = param->get_description();
cpos = 0;
lines = 0;
maxlen = 0;
while (cpos < strlen(message) && (lines < 10)) {
loffs[lines] = cpos;
while ((cpos < strlen(message)) && (message[cpos] != 0x0a)) cpos++;
len = cpos - loffs[lines];
llen[lines] = len;
if (len > maxlen) maxlen = len;
lines++;
cpos++;
}
if (maxlen < 36) {
size_x = 250;
} else {
size_x = 30 + maxlen * 6;
}
diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/bochs.h ./bochs.h --- /home/volker/bochs/bochs/bochs.h 2016-08-12 19:06:18.803209189 +0200 +++ ./bochs.h 2016-12-28 00:41:20.000627252 +0100 @@ -2,7 +2,7 @@ // $Id: bochs.h 12935 2016-08-12 17:06:14Z vruppert $ ///////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2001-2015 The Bochs Project +// Copyright (C) 2001-2016 The Bochs Project // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -276,8 +276,9 @@ void error(const char *fmt, ...) BX_CPP_AttrPrintf(2, 3); void panic(const char *fmt, ...) BX_CPP_AttrPrintf(2, 3); void ldebug(const char *fmt, ...) BX_CPP_AttrPrintf(2, 3); - void fatal (const char *prefix, const char *fmt, va_list ap, int exit_status); - void ask (int level, const char *prefix, const char *fmt, va_list ap); + void fatal(const char *prefix, const char *fmt, va_list ap, int exit_status); + void warn(int level, const char *prefix, const char *fmt, va_list ap); + void ask(int level, const char *prefix, const char *fmt, va_list ap); void put(const char *p); void put(const char *n, const char *p); void setio(class iofunctions *); @@ -334,7 +335,8 @@ void set_log_action(int loglevel, int action); const char *getlevel(int i) const; const char *getaction(int i) const; - + int isaction(const char *val) const; + protected: int n_logfn; #define MAX_LOGFNS 512 diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/CHANGES ./CHANGES --- /home/volker/bochs/bochs/CHANGES 2016-12-26 10:45:44.000000000 +0100 +++ ./CHANGES 2016-12-28 15:54:25.127088081 +0100 @@ -1,5 +1,8 @@ Changes after 2.6.8 release: +- General + - Added new log action "warn", designed to show a message box on error events. + - Configure and compile - Added Android host platform support. diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/config.cc ./config.cc --- /home/volker/bochs/bochs/config.cc 2016-05-03 21:15:09.158016000 +0200 +++ ./config.cc 2016-12-27 19:53:10.461420368 +0100 @@ -2062,15 +2062,8 @@ actstr = strtok(NULL, ""); if (actstr != NULL) { def_action = !strcmp(module, "action"); - if (!strcmp(actstr, "fatal")) - action = ACT_FATAL; - else if (!strcmp (actstr, "report")) - action = ACT_REPORT; - else if (!strcmp (actstr, "ignore")) - action = ACT_IGNORE; - else if (!strcmp (actstr, "ask")) - action = ACT_ASK; - else { + action = SIM->is_action_name(actstr); + if (action < ACT_IGNORE) { PARSE_ERR(("%s: %s directive malformed.", context, params[0])); free(param); return -1; diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/gui/sdl2.cc ./gui/sdl2.cc --- /home/volker/bochs/bochs/gui/sdl2.cc 2016-08-12 19:06:18.811209142 +0200 +++ ./gui/sdl2.cc 2016-12-28 12:33:39.534288819 +0100 @@ -2,7 +2,7 @@ // $Id: sdl2.cc 12935 2016-08-12 17:06:14Z vruppert $ ///////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2014-2015 The Bochs Project +// Copyright (C) 2014-2016 The Bochs Project // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -1478,20 +1478,16 @@ SDL_MessageBoxData msgboxdata; SDL_MessageBoxButtonData buttondata[4]; int level, retcode; -#if BX_DEBUGGER || BX_GDBSTUB - int defbtn = 3; -#else - int defbtn = 2; -#endif char message[512]; level = event->u.logmsg.level; - sprintf(message, "%s %s", event->u.logmsg.prefix, event->u.logmsg.msg); + sprintf(message, "Device: %s\nMessage: %s", event->u.logmsg.prefix, + event->u.logmsg.msg); msgboxdata.flags = SDL_MESSAGEBOX_ERROR; msgboxdata.window = window; msgboxdata.title = SIM->get_log_level_name(level); msgboxdata.message = message; - msgboxdata.numbuttons = defbtn + 1; + msgboxdata.numbuttons = 2; msgboxdata.buttons = buttondata; msgboxdata.colorScheme = NULL; buttondata[0].flags = 0; @@ -1500,14 +1496,18 @@ buttondata[1].flags = 0; buttondata[1].buttonid = BX_LOG_ASK_CHOICE_CONTINUE_ALWAYS; buttondata[1].text = "Alwayscont"; + if (event->u.logmsg.flag == BX_LOG_ASK_ASKDLG) { + msgboxdata.numbuttons = 3; + buttondata[2].flags = SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT; + buttondata[2].buttonid = BX_LOG_ASK_CHOICE_DIE; + buttondata[2].text = "Quit"; #if BX_DEBUGGER || BX_GDBSTUB - buttondata[2].flags = 0; - buttondata[2].buttonid = BX_LOG_ASK_CHOICE_ENTER_DEBUG; - buttondata[2].text = "Debugger"; -#endif - buttondata[defbtn].flags = SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT; - buttondata[defbtn].buttonid = BX_LOG_ASK_CHOICE_DIE; - buttondata[defbtn].text = "Quit"; + msgboxdata.numbuttons = 4; + buttondata[3].flags = 0; + buttondata[3].buttonid = BX_LOG_ASK_CHOICE_ENTER_DEBUG; + buttondata[3].text = "Debugger"; +#endif + } if (SDL_ShowMessageBox(&msgboxdata, &retcode) < 0) { return -1; } else { diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/gui/siminterface.cc ./gui/siminterface.cc --- /home/volker/bochs/bochs/gui/siminterface.cc 2016-12-05 19:56:56.729685000 +0100 +++ ./gui/siminterface.cc 2016-12-28 11:14:02.004075717 +0100 @@ -2,7 +2,7 @@ // $Id: siminterface.cc 12981 2016-12-05 18:56:56Z sshwarts $ ///////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2002-2015 The Bochs Project +// Copyright (C) 2002-2016 The Bochs Project // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -100,6 +100,7 @@ virtual int get_log_action(int mod, int level); virtual void set_log_action(int mod, int level, int action); virtual const char *get_action_name(int action); + virtual int is_action_name(const char *val); virtual int get_default_log_action(int level) { return logfunctions::get_default_action(level); } @@ -123,6 +124,7 @@ virtual void set_notify_callback(bxevent_handler func, void *arg); virtual void get_notify_callback(bxevent_handler *func, void **arg); virtual BxEvent* sim_to_ci_event(BxEvent *event); + virtual int log_warn(const char *prefix, int level, const char *msg); virtual int log_ask(const char *prefix, int level, const char *msg); virtual void log_msg(const char *prefix, int level, const char *msg); virtual void set_log_viewer(bx_bool val) { bx_log_viewer = val; } @@ -420,6 +422,11 @@ return io->getaction(action); } +int bx_real_sim_c::is_action_name(const char *val) +{ + return io->isaction(val); +} + const char *bx_real_sim_c::get_log_level_name(int level) { return io->getlevel(level); @@ -575,6 +582,21 @@ } } +int bx_real_sim_c::log_warn(const char *prefix, int level, const char *msg) +{ + BxEvent be; + be.type = BX_SYNC_EVT_LOG_ASK; + be.u.logmsg.prefix = prefix; + be.u.logmsg.level = level; + be.u.logmsg.msg = msg; + be.u.logmsg.flag = BX_LOG_ASK_MSGBOX_WARN; + // default return value in case something goes wrong. + be.retcode = BX_LOG_NOTIFY_FAILED; + // calling notify + sim_to_ci_event(&be); + return be.retcode; +} + // returns 0 for continue, 1 for alwayscontinue, 2 for die. int bx_real_sim_c::log_ask(const char *prefix, int level, const char *msg) { @@ -583,6 +605,7 @@ be.u.logmsg.prefix = prefix; be.u.logmsg.level = level; be.u.logmsg.msg = msg; + be.u.logmsg.flag = BX_LOG_ASK_ASKDLG; // default return value in case something goes wrong. be.retcode = BX_LOG_NOTIFY_FAILED; // calling notify @@ -1157,16 +1180,10 @@ } else if (!strncmp(string, "PANIC=", 6)) { type = LOGLEV_PANIC; } - if (!strcmp(string+j, "ignore")) { - action = ACT_IGNORE; - } else if (!strcmp(string+j, "report")) { - action = ACT_REPORT; - } else if (!strcmp(string+j, "ask")) { - action = ACT_ASK; - } else if (!strcmp(string+j, "fatal")) { - action = ACT_FATAL; + action = is_action_name(string+j); + if (action >= ACT_IGNORE) { + set_log_action(dev, type, action); } - set_log_action(dev, type, action); } else { if (i == 1) { BX_ERROR(("restore_logopts(): log module '%s' not found", devname)); diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/gui/siminterface.h ./gui/siminterface.h --- /home/volker/bochs/bochs/gui/siminterface.h 2016-03-31 19:24:37.451025427 +0200 +++ ./gui/siminterface.h 2016-12-28 11:11:21.036683362 +0100 @@ -168,6 +168,7 @@ typedef enum { ACT_IGNORE = 0, ACT_REPORT, + ACT_WARN, ACT_ASK, ACT_FATAL, N_ACT @@ -178,11 +179,11 @@ // normally all action choices are available for all event types. The exclude // expression allows some choices to be eliminated if they don't make any // sense. For example, it would be stupid to ignore a panic. -#define BX_LOG_OPTS_EXCLUDE(type, choice) ( \ - /* can't die or ask, on debug or info events */ \ - (type <= LOGLEV_INFO && (choice == ACT_ASK || choice == ACT_FATAL)) \ - /* can't ignore panics */ \ - || (type == LOGLEV_PANIC && choice == ACT_IGNORE) \ +#define BX_LOG_OPTS_EXCLUDE(type, choice) ( \ + /* can't die, ask or warn, on debug or info events */ \ + (type <= LOGLEV_INFO && (choice >= ACT_WARN)) \ + /* can't ignore panics */ \ + || (type == LOGLEV_PANIC && choice == ACT_IGNORE) \ ) // floppy / cdrom media status @@ -392,6 +393,7 @@ // synchronizing threads, etc. for each. typedef struct { Bit8u level; + Bit8u flag; const char *prefix; const char *msg; } BxLogMsgEvent; @@ -419,6 +421,12 @@ BX_LOG_NOTIFY_FAILED }; +enum { + BX_LOG_ASK_ASKDLG, + BX_LOG_ASK_MSGBOX_WARN, + BX_LOG_ASK_MSGBOX_QUIT +}; + // Event type: BX_SYNC_EVT_GET_DBG_COMMAND // // This is a synchronous event sent from the simulator to the debugger @@ -675,6 +683,7 @@ virtual int get_default_log_action(int level) {return -1;} virtual void set_default_log_action(int level, int action) {} virtual const char *get_action_name(int action) {return NULL;} + virtual int is_action_name(const char *val) {return -1;} virtual const char *get_log_level_name(int level) {return NULL;} virtual int get_max_log_level() {return -1;} @@ -715,6 +724,9 @@ // send an event from the simulator to the CI. virtual BxEvent* sim_to_ci_event(BxEvent *event) {return NULL;} + // called from simulator when it hits errors, to warn the user + // before continuing simulation + virtual int log_warn(const char *prefix, int level, const char *msg) {return -1;} // called from simulator when it hits serious errors, to ask if the user // wants to continue or not virtual int log_ask(const char *prefix, int level, const char *msg) {return -1;} diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/gui/textconfig.cc ./gui/textconfig.cc --- /home/volker/bochs/bochs/gui/textconfig.cc 2016-12-05 20:15:59.112637000 +0100 +++ ./gui/textconfig.cc 2016-12-28 12:44:43.079411258 +0100 @@ -2,7 +2,7 @@ // $Id: textconfig.cc 12983 2016-12-05 19:15:59Z sshwarts $ ///////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2002-2013 The Bochs Project +// Copyright (C) 2002-2016 The Bochs Project // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -552,8 +552,8 @@ } static const char *log_options_prompt1 = "Enter the ID of the device to edit, or -1 to return: [-1] "; -static const char *log_level_choices[] = { "ignore", "report", "ask", "fatal", "no change" }; -static int log_level_n_choices_normal = 4; +static const char *log_level_choices[N_ACT+1] = { "ignore", "report", "warn", "ask", "fatal", "no change" }; +static int log_level_n_choices_normal = N_ACT; void bx_log_options(int individual) { @@ -589,7 +589,7 @@ bx_print_log_action_table(); for (int level=0; level<SIM->get_max_log_level(); level++) { char prompt[1024]; - int action, default_action = 4; // default to no change + int action, default_action = N_ACT; // default to no change sprintf(prompt, "Enter action for %s event on all devices: [no change] ", SIM->get_log_level_name(level)); // do show the no change choice (choices=4) if (ask_menu(prompt, "", log_level_n_choices_normal+1, log_level_choices, default_action, &action)<0) @@ -718,47 +718,50 @@ event->retcode = event->u.param.param->text_ask(stdin, stderr); return event; case BX_SYNC_EVT_LOG_ASK: - { - int level = event->u.logmsg.level; - fprintf(stderr, "========================================================================\n"); - fprintf(stderr, "Event type: %s\n", SIM->get_log_level_name (level)); - fprintf(stderr, "Device: %s\n", event->u.logmsg.prefix); - fprintf(stderr, "Message: %s\n\n", event->u.logmsg.msg); - fprintf(stderr, "A %s has occurred. Do you want to:\n", SIM->get_log_level_name (level)); - fprintf(stderr, " cont - continue execution\n"); - fprintf(stderr, " alwayscont - continue execution, and don't ask again.\n"); - fprintf(stderr, " This affects only %s events from device %s\n", SIM->get_log_level_name (level), event->u.logmsg.prefix); - fprintf(stderr, " die - stop execution now\n"); - fprintf(stderr, " abort - dump core %s\n", - BX_HAVE_ABORT ? "" : "(Disabled)"); + if (event->u.logmsg.flag == BX_LOG_ASK_ASKDLG) { + int level = event->u.logmsg.level; + fprintf(stderr, "========================================================================\n"); + fprintf(stderr, "Event type: %s\n", SIM->get_log_level_name (level)); + fprintf(stderr, "Device: %s\n", event->u.logmsg.prefix); + fprintf(stderr, "Message: %s\n\n", event->u.logmsg.msg); + fprintf(stderr, "A %s has occurred. Do you want to:\n", SIM->get_log_level_name (level)); + fprintf(stderr, " cont - continue execution\n"); + fprintf(stderr, " alwayscont - continue execution, and don't ask again.\n"); + fprintf(stderr, " This affects only %s events from device %s\n", SIM->get_log_level_name (level), event->u.logmsg.prefix); + fprintf(stderr, " die - stop execution now\n"); + fprintf(stderr, " abort - dump core %s\n", + BX_HAVE_ABORT ? "" : "(Disabled)"); #if BX_DEBUGGER - fprintf(stderr, " debug - continue and return to bochs debugger\n"); + fprintf(stderr, " debug - continue and return to bochs debugger\n"); #endif #if BX_GDBSTUB - fprintf(stderr, " debug - hand control to gdb\n"); + fprintf(stderr, " debug - hand control to gdb\n"); #endif - int choice; + int choice; ask: - if (ask_menu("Choose one of the actions above: [%s] ", "", - log_action_n_choices, log_action_ask_choices, 2, &choice) < 0) - event->retcode = -1; - // return 0 for continue, 1 for alwayscontinue, 2 for die, 3 for debug. - if (!BX_HAVE_ABORT && choice==BX_LOG_ASK_CHOICE_DUMP_CORE) goto ask; - fflush(stdout); - fflush(stderr); - event->retcode = choice; - } - return event; - case BX_ASYNC_EVT_REFRESH: - case BX_ASYNC_EVT_DBG_MSG: - case BX_ASYNC_EVT_LOG_MSG: - // The text mode interface does not use these events, so just ignore - // them. - return event; - default: - fprintf(stderr, "textconfig: notify callback called with event type %04x\n", event->type); - return event; + if (ask_menu("Choose one of the actions above: [%s] ", "", + log_action_n_choices, log_action_ask_choices, 2, &choice) < 0) + event->retcode = -1; + // return 0 for continue, 1 for alwayscontinue, 2 for die, 3 for debug. + if (!BX_HAVE_ABORT && choice==BX_LOG_ASK_CHOICE_DUMP_CORE) goto ask; + fflush(stdout); + fflush(stderr); + event->retcode = choice; + } else { + // warning prompt not implemented + event->retcode = 0; + } + return event; + case BX_ASYNC_EVT_REFRESH: + case BX_ASYNC_EVT_DBG_MSG: + case BX_ASYNC_EVT_LOG_MSG: + // The text mode interface does not use these events, so just ignore + // them. + return event; + default: + fprintf(stderr, "textconfig: notify callback called with event type %04x\n", event->type); + return event; } assert(0); // switch statement should return } diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/gui/win32dialog.cc ./gui/win32dialog.cc --- /home/volker/bochs/bochs/gui/win32dialog.cc 2014-06-20 11:32:02.034026376 +0200 +++ ./gui/win32dialog.cc 2016-12-28 12:50:14.148888740 +0100 @@ -2,7 +2,7 @@ // $Id: win32dialog.cc 12381 2014-06-20 09:31:56Z vruppert $ ///////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2003-2014 The Bochs Project +// Copyright (C) 2003-2016 The Bochs Project // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -27,7 +27,7 @@ #include "win32res.h" #include "win32paramdlg.h" -const char log_choices[5][16] = {"ignore", "log", "ask user", "end simulation", "no change"}; +const char log_choices[N_ACT+1][16] = {"ignore", "log", "warn user", "ask user", "end simulation", "no change"}; HWND GetBochsWindow() { @@ -97,12 +97,16 @@ SetWindowText(GetDlgItem(hDlg, IDASKMSG), event->u.logmsg.msg); SendMessage(GetDlgItem(hDlg, IDASKLIST), LB_ADDSTRING, 0, (LPARAM)"Continue"); SendMessage(GetDlgItem(hDlg, IDASKLIST), LB_ADDSTRING, 0, (LPARAM)"Continue and don't ask again"); - SendMessage(GetDlgItem(hDlg, IDASKLIST), LB_ADDSTRING, 0, (LPARAM)"Kill simulation"); - SendMessage(GetDlgItem(hDlg, IDASKLIST), LB_ADDSTRING, 0, (LPARAM)"Abort (dump core)"); + if (event->u.logmsg.flag == BX_LOG_ASK_ASKDLG) { + SendMessage(GetDlgItem(hDlg, IDASKLIST), LB_ADDSTRING, 0, (LPARAM)"Kill simulation"); + SendMessage(GetDlgItem(hDlg, IDASKLIST), LB_ADDSTRING, 0, (LPARAM)"Abort (dump core)"); #if BX_DEBUGGER - SendMessage(GetDlgItem(hDlg, IDASKLIST), LB_ADDSTRING, 0, (LPARAM)"Continue and return to debugger"); + SendMessage(GetDlgItem(hDlg, IDASKLIST), LB_ADDSTRING, 0, (LPARAM)"Continue and return to debugger"); #endif - SendMessage(GetDlgItem(hDlg, IDASKLIST), LB_SETCURSEL, 2, 0); + SendMessage(GetDlgItem(hDlg, IDASKLIST), LB_SETCURSEL, 2, 0); + } else { + SendMessage(GetDlgItem(hDlg, IDASKLIST), LB_SETCURSEL, 0, 0); + } SetFocus(GetDlgItem(hDlg, IDASKLIST)); return FALSE; case WM_CLOSE: diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/gui/wxdialog.cc ./gui/wxdialog.cc --- /home/volker/bochs/bochs/gui/wxdialog.cc 2015-01-07 17:17:40.447882000 +0100 +++ ./gui/wxdialog.cc 2016-12-27 20:30:44.997609007 +0100 @@ -2,7 +2,7 @@ // $Id: wxdialog.cc 12594 2015-01-07 16:17:40Z sshwarts $ ///////////////////////////////////////////////////////////////// // -// Copyright (C) 2002-2014 The Bochs Project +// Copyright (C) 2002-2016 The Bochs Project // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -208,7 +208,6 @@ : wxDialog(parent, id, wxT(""), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) { - //static int integers[LOG_OPTS_N_CHOICES_NORMAL] = {0, 1, 2, 3}; static wxString names[] = ADVLOG_OPTS_TYPE_NAMES; SetTitle(ADVLOG_OPTS_TITLE); vertSizer = new wxBoxSizer(wxVERTICAL); @@ -1563,7 +1562,7 @@ bool includeNoChange) { static wxString choices[] = LOG_OPTS_CHOICES; - static int integers[LOG_OPTS_N_CHOICES] = {0, 1, 2, 3, 4}; + static int integers[LOG_OPTS_N_CHOICES] = {0, 1, 2, 3, 4, 5}; wxChoice *control = new wxChoice(parent, id, wxDefaultPosition, wxDefaultSize); int lastChoice = 0; // remember index of last choice int nchoice = includeNoChange? LOG_OPTS_N_CHOICES : LOG_OPTS_N_CHOICES_NORMAL; diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/gui/wxdialog.h ./gui/wxdialog.h --- /home/volker/bochs/bochs/gui/wxdialog.h 2014-12-23 20:30:12.896090221 +0100 +++ ./gui/wxdialog.h 2016-12-27 20:34:28.518389938 +0100 @@ -2,7 +2,7 @@ // $Id: wxdialog.h 12576 2014-12-23 19:30:03Z vruppert $ //////////////////////////////////////////////////////////////////// // -// Copyright (C) 2002-2014 The Bochs Project +// Copyright (C) 2002-2016 The Bochs Project // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -354,10 +354,10 @@ #define LOG_OPTS_PROMPT wxT("How should Bochs respond to each type of event?") #define LOG_OPTS_TYPE_NAMES { wxT("Debug events"), wxT("Info events"), wxT("Error events"), wxT("Panic events") } #define LOG_OPTS_N_TYPES 4 -#define LOG_OPTS_CHOICES { wxT("ignore"), wxT("log"), wxT("ask user"), wxT("end simulation"), wxT("no change") } -#define LOG_OPTS_N_CHOICES_NORMAL 4 -#define LOG_OPTS_N_CHOICES 5 // number of choices, including "no change" -#define LOG_OPTS_NO_CHANGE 4 // index of "no change" +#define LOG_OPTS_CHOICES { wxT("ignore"), wxT("log"), wxT("warn user"), wxT("ask user"), wxT("end simulation"), wxT("no change") } +#define LOG_OPTS_N_CHOICES_NORMAL 5 +#define LOG_OPTS_N_CHOICES 6 // number of choices, including "no change" +#define LOG_OPTS_NO_CHANGE 5 // index of "no change" #define LOG_OPTS_ADV wxT("For additional control over how each device responds to events, use the menu option \"Log ... By Device\".") wxFlexGridSizer *gridSizer; wxChoice *action[LOG_OPTS_N_TYPES]; diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/gui/wxmain.cc ./gui/wxmain.cc --- /home/volker/bochs/bochs/gui/wxmain.cc 2016-12-26 17:12:57.470174541 +0100 +++ ./gui/wxmain.cc 2016-12-28 12:15:26.035961463 +0100 @@ -2,7 +2,7 @@ // $Id: wxmain.cc 13006 2016-12-26 16:12:54Z vruppert $ ///////////////////////////////////////////////////////////////// // -// Copyright (C) 2002-2014 The Bochs Project +// Copyright (C) 2002-2016 The Bochs Project // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -1158,6 +1158,10 @@ #if !BX_DEBUGGER && !BX_GDBSTUB dlg.EnableButton(dlg.DEBUG, FALSE); #endif + if (be->u.logmsg.flag != BX_LOG_ASK_ASKDLG) { + dlg.EnableButton(dlg.DIE, FALSE); + dlg.EnableButton(dlg.DUMP, FALSE); + } dlg.SetContext(wxString(be->u.logmsg.prefix, wxConvUTF8)); dlg.SetMessage(wxString(be->u.logmsg.msg, wxConvUTF8)); int n = dlg.ShowModal(); diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/gui/x.cc ./gui/x.cc --- /home/volker/bochs/bochs/gui/x.cc 2016-12-27 17:26:59.622665119 +0100 +++ ./gui/x.cc 2016-12-28 12:03:10.963351647 +0100 @@ -2687,11 +2687,7 @@ } else { size_x = 30 + maxlen * 6; } - if (lines < 3) { - size_y = 90; - } else { - size_y = 60 + lines * 15; - } + size_y = 70 + lines * 15; x11_dialog_c *xdlg = new x11_dialog_c(name, size_x, size_y, (mode == XDLG_SIMPLE) ? 1 : 2); ypos = 34; @@ -2729,11 +2725,21 @@ bx_param_string_c *sparam; bx_param_enum_c *eparam; bx_list_c *list; + char message[256]; switch (event->type) { case BX_SYNC_EVT_LOG_ASK: - event->retcode = x11_ask_dialog(event); + if (event->u.logmsg.flag == BX_LOG_ASK_ASKDLG) { + event->retcode = x11_ask_dialog(event); + } else if (event->u.logmsg.flag == BX_LOG_ASK_MSGBOX_WARN) { + const char *title = SIM->get_log_level_name(event->u.logmsg.level); + sprintf(message, "Device: %s\n\nMessage: %s", event->u.logmsg.prefix, + event->u.logmsg.msg); + bx_param_bool_c bparam(NULL, "warn", title, message, 1); + x11_message_box(&bparam, XDLG_SIMPLE); + event->retcode = 0; + } return event; case BX_SYNC_EVT_ASK_PARAM: param = event->u.param.param; diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/logio.cc ./logio.cc --- /home/volker/bochs/bochs/logio.cc 2015-05-10 08:55:18.678940963 +0200 +++ ./logio.cc 2016-12-28 00:40:40.395736643 +0100 @@ -2,7 +2,7 @@ // $Id: logio.cc 12759 2015-05-10 06:55:16Z vruppert $ ///////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2001-2014 The Bochs Project +// Copyright (C) 2001-2016 The Bochs Project // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -50,11 +50,25 @@ else return "?"; } +static const char *act_name[N_ACT] = { "ignore", "report", "warn", "ask", "fatal" }; + const char* iofunctions::getaction(int i) const { - static const char *name[] = { "ignore", "report", "ask", "fatal" }; assert (i>=ACT_IGNORE && i<N_ACT); - return name[i]; + return act_name[i]; +} + +int iofunctions::isaction(const char *val) const +{ + int action = -1; + + for (int i = 0; i < N_ACT; i++) { + if (!strcmp(val, act_name[i])) { + action = ACT_IGNORE + i; + break; + } + } + return action; } void iofunctions::flush(void) @@ -414,6 +428,11 @@ logio->out(LOGLEV_ERROR, prefix, fmt, ap); va_end(ap); + if (onoff[LOGLEV_ERROR] == ACT_WARN) { + va_start(ap, fmt); + warn(LOGLEV_ERROR, prefix, fmt, ap); + va_end(ap); + } if (onoff[LOGLEV_ERROR] == ACT_ASK) { va_start(ap, fmt); ask(LOGLEV_ERROR, prefix, fmt, ap); @@ -438,6 +457,11 @@ logio->out(LOGLEV_PANIC, prefix, fmt, ap); va_end(ap); + if (onoff[LOGLEV_PANIC] == ACT_WARN) { + va_start(ap, fmt); + warn(LOGLEV_PANIC, prefix, fmt, ap); + va_end(ap); + } if (onoff[LOGLEV_PANIC] == ACT_ASK) { va_start(ap, fmt); ask(LOGLEV_PANIC, prefix, fmt, ap); @@ -465,6 +489,36 @@ // the actions ask() and fatal() are not supported here } +void logfunctions::warn(int level, const char *prefix, const char *fmt, va_list ap) +{ + // Guard against reentry on warn() function. The danger is that some + // function that's called within warn() could trigger another + // BX_ERROR that could call warn() again, leading to infinite + // recursion and infinite asks. + static char in_warn_already = 0; + char buf1[1024]; + if (in_warn_already) { + fprintf(stderr, "logfunctions::warn() should not reenter!!\n"); + return; + } + in_warn_already = 1; + vsnprintf(buf1, sizeof(buf1), fmt, ap); + // FIXME: facility set to 0 because it's unknown. + + // update vga screen. This is useful because sometimes useful messages + // are printed on the screen just before a panic. It's also potentially + // dangerous if this function calls ask again... That's why I added + // the reentry check above. + SIM->refresh_vga(); + + // ensure the text screen is showing + SIM->set_display_mode(DISP_MODE_CONFIG); + SIM->log_warn(prefix, level, buf1); + // return to simulation mode + SIM->set_display_mode(DISP_MODE_SIM); + in_warn_already = 0; +} + void logfunctions::ask(int level, const char *prefix, const char *fmt, va_list ap) { // Guard against reentry on ask() function. The danger is that some
2016-12-28 18:06:34 +03:00
size_y = 70 + lines * 15;
x11_dialog_c *xdlg = new x11_dialog_c(name, size_x, size_y,
(mode == XDLG_SIMPLE) ? 1 : 2);
ypos = 34;
for (i = 0; i < lines; i++) {
xdlg->add_static_text(20, ypos, message+loffs[i], llen[i]);
ypos += 15;
}
if ((mode == XDLG_OK_CANCEL) || (mode == XDLG_YES_NO)) {
if (mode == XDLG_YES_NO) {
yes_id = xdlg->add_button("Yes");
no_id = xdlg->add_button("No");
} else {
yes_id = xdlg->add_button("OK");
no_id = xdlg->add_button("Cancel");
}
ctrl_id = param->get() ? yes_id : no_id;
ctrl_id = xdlg->run(ctrl_id, yes_id, no_id);
param->set(ctrl_id == yes_id);
} else {
if (param->get()) {
ctrl_id = xdlg->add_button("OK");
} else {
ctrl_id = xdlg->add_button("Cancel");
}
xdlg->run(ctrl_id, ctrl_id, ctrl_id);
}
delete xdlg;
return 1;
}
BxEvent *x11_notify_callback(void *unused, BxEvent *event)
{
int opts;
bx_param_c *param;
bx_param_string_c *sparam;
bx_param_enum_c *eparam;
bx_list_c *list;
diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/bochs.h ./bochs.h --- /home/volker/bochs/bochs/bochs.h 2016-08-12 19:06:18.803209189 +0200 +++ ./bochs.h 2016-12-28 00:41:20.000627252 +0100 @@ -2,7 +2,7 @@ // $Id: bochs.h 12935 2016-08-12 17:06:14Z vruppert $ ///////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2001-2015 The Bochs Project +// Copyright (C) 2001-2016 The Bochs Project // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -276,8 +276,9 @@ void error(const char *fmt, ...) BX_CPP_AttrPrintf(2, 3); void panic(const char *fmt, ...) BX_CPP_AttrPrintf(2, 3); void ldebug(const char *fmt, ...) BX_CPP_AttrPrintf(2, 3); - void fatal (const char *prefix, const char *fmt, va_list ap, int exit_status); - void ask (int level, const char *prefix, const char *fmt, va_list ap); + void fatal(const char *prefix, const char *fmt, va_list ap, int exit_status); + void warn(int level, const char *prefix, const char *fmt, va_list ap); + void ask(int level, const char *prefix, const char *fmt, va_list ap); void put(const char *p); void put(const char *n, const char *p); void setio(class iofunctions *); @@ -334,7 +335,8 @@ void set_log_action(int loglevel, int action); const char *getlevel(int i) const; const char *getaction(int i) const; - + int isaction(const char *val) const; + protected: int n_logfn; #define MAX_LOGFNS 512 diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/CHANGES ./CHANGES --- /home/volker/bochs/bochs/CHANGES 2016-12-26 10:45:44.000000000 +0100 +++ ./CHANGES 2016-12-28 15:54:25.127088081 +0100 @@ -1,5 +1,8 @@ Changes after 2.6.8 release: +- General + - Added new log action "warn", designed to show a message box on error events. + - Configure and compile - Added Android host platform support. diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/config.cc ./config.cc --- /home/volker/bochs/bochs/config.cc 2016-05-03 21:15:09.158016000 +0200 +++ ./config.cc 2016-12-27 19:53:10.461420368 +0100 @@ -2062,15 +2062,8 @@ actstr = strtok(NULL, ""); if (actstr != NULL) { def_action = !strcmp(module, "action"); - if (!strcmp(actstr, "fatal")) - action = ACT_FATAL; - else if (!strcmp (actstr, "report")) - action = ACT_REPORT; - else if (!strcmp (actstr, "ignore")) - action = ACT_IGNORE; - else if (!strcmp (actstr, "ask")) - action = ACT_ASK; - else { + action = SIM->is_action_name(actstr); + if (action < ACT_IGNORE) { PARSE_ERR(("%s: %s directive malformed.", context, params[0])); free(param); return -1; diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/gui/sdl2.cc ./gui/sdl2.cc --- /home/volker/bochs/bochs/gui/sdl2.cc 2016-08-12 19:06:18.811209142 +0200 +++ ./gui/sdl2.cc 2016-12-28 12:33:39.534288819 +0100 @@ -2,7 +2,7 @@ // $Id: sdl2.cc 12935 2016-08-12 17:06:14Z vruppert $ ///////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2014-2015 The Bochs Project +// Copyright (C) 2014-2016 The Bochs Project // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -1478,20 +1478,16 @@ SDL_MessageBoxData msgboxdata; SDL_MessageBoxButtonData buttondata[4]; int level, retcode; -#if BX_DEBUGGER || BX_GDBSTUB - int defbtn = 3; -#else - int defbtn = 2; -#endif char message[512]; level = event->u.logmsg.level; - sprintf(message, "%s %s", event->u.logmsg.prefix, event->u.logmsg.msg); + sprintf(message, "Device: %s\nMessage: %s", event->u.logmsg.prefix, + event->u.logmsg.msg); msgboxdata.flags = SDL_MESSAGEBOX_ERROR; msgboxdata.window = window; msgboxdata.title = SIM->get_log_level_name(level); msgboxdata.message = message; - msgboxdata.numbuttons = defbtn + 1; + msgboxdata.numbuttons = 2; msgboxdata.buttons = buttondata; msgboxdata.colorScheme = NULL; buttondata[0].flags = 0; @@ -1500,14 +1496,18 @@ buttondata[1].flags = 0; buttondata[1].buttonid = BX_LOG_ASK_CHOICE_CONTINUE_ALWAYS; buttondata[1].text = "Alwayscont"; + if (event->u.logmsg.flag == BX_LOG_ASK_ASKDLG) { + msgboxdata.numbuttons = 3; + buttondata[2].flags = SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT; + buttondata[2].buttonid = BX_LOG_ASK_CHOICE_DIE; + buttondata[2].text = "Quit"; #if BX_DEBUGGER || BX_GDBSTUB - buttondata[2].flags = 0; - buttondata[2].buttonid = BX_LOG_ASK_CHOICE_ENTER_DEBUG; - buttondata[2].text = "Debugger"; -#endif - buttondata[defbtn].flags = SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT; - buttondata[defbtn].buttonid = BX_LOG_ASK_CHOICE_DIE; - buttondata[defbtn].text = "Quit"; + msgboxdata.numbuttons = 4; + buttondata[3].flags = 0; + buttondata[3].buttonid = BX_LOG_ASK_CHOICE_ENTER_DEBUG; + buttondata[3].text = "Debugger"; +#endif + } if (SDL_ShowMessageBox(&msgboxdata, &retcode) < 0) { return -1; } else { diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/gui/siminterface.cc ./gui/siminterface.cc --- /home/volker/bochs/bochs/gui/siminterface.cc 2016-12-05 19:56:56.729685000 +0100 +++ ./gui/siminterface.cc 2016-12-28 11:14:02.004075717 +0100 @@ -2,7 +2,7 @@ // $Id: siminterface.cc 12981 2016-12-05 18:56:56Z sshwarts $ ///////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2002-2015 The Bochs Project +// Copyright (C) 2002-2016 The Bochs Project // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -100,6 +100,7 @@ virtual int get_log_action(int mod, int level); virtual void set_log_action(int mod, int level, int action); virtual const char *get_action_name(int action); + virtual int is_action_name(const char *val); virtual int get_default_log_action(int level) { return logfunctions::get_default_action(level); } @@ -123,6 +124,7 @@ virtual void set_notify_callback(bxevent_handler func, void *arg); virtual void get_notify_callback(bxevent_handler *func, void **arg); virtual BxEvent* sim_to_ci_event(BxEvent *event); + virtual int log_warn(const char *prefix, int level, const char *msg); virtual int log_ask(const char *prefix, int level, const char *msg); virtual void log_msg(const char *prefix, int level, const char *msg); virtual void set_log_viewer(bx_bool val) { bx_log_viewer = val; } @@ -420,6 +422,11 @@ return io->getaction(action); } +int bx_real_sim_c::is_action_name(const char *val) +{ + return io->isaction(val); +} + const char *bx_real_sim_c::get_log_level_name(int level) { return io->getlevel(level); @@ -575,6 +582,21 @@ } } +int bx_real_sim_c::log_warn(const char *prefix, int level, const char *msg) +{ + BxEvent be; + be.type = BX_SYNC_EVT_LOG_ASK; + be.u.logmsg.prefix = prefix; + be.u.logmsg.level = level; + be.u.logmsg.msg = msg; + be.u.logmsg.flag = BX_LOG_ASK_MSGBOX_WARN; + // default return value in case something goes wrong. + be.retcode = BX_LOG_NOTIFY_FAILED; + // calling notify + sim_to_ci_event(&be); + return be.retcode; +} + // returns 0 for continue, 1 for alwayscontinue, 2 for die. int bx_real_sim_c::log_ask(const char *prefix, int level, const char *msg) { @@ -583,6 +605,7 @@ be.u.logmsg.prefix = prefix; be.u.logmsg.level = level; be.u.logmsg.msg = msg; + be.u.logmsg.flag = BX_LOG_ASK_ASKDLG; // default return value in case something goes wrong. be.retcode = BX_LOG_NOTIFY_FAILED; // calling notify @@ -1157,16 +1180,10 @@ } else if (!strncmp(string, "PANIC=", 6)) { type = LOGLEV_PANIC; } - if (!strcmp(string+j, "ignore")) { - action = ACT_IGNORE; - } else if (!strcmp(string+j, "report")) { - action = ACT_REPORT; - } else if (!strcmp(string+j, "ask")) { - action = ACT_ASK; - } else if (!strcmp(string+j, "fatal")) { - action = ACT_FATAL; + action = is_action_name(string+j); + if (action >= ACT_IGNORE) { + set_log_action(dev, type, action); } - set_log_action(dev, type, action); } else { if (i == 1) { BX_ERROR(("restore_logopts(): log module '%s' not found", devname)); diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/gui/siminterface.h ./gui/siminterface.h --- /home/volker/bochs/bochs/gui/siminterface.h 2016-03-31 19:24:37.451025427 +0200 +++ ./gui/siminterface.h 2016-12-28 11:11:21.036683362 +0100 @@ -168,6 +168,7 @@ typedef enum { ACT_IGNORE = 0, ACT_REPORT, + ACT_WARN, ACT_ASK, ACT_FATAL, N_ACT @@ -178,11 +179,11 @@ // normally all action choices are available for all event types. The exclude // expression allows some choices to be eliminated if they don't make any // sense. For example, it would be stupid to ignore a panic. -#define BX_LOG_OPTS_EXCLUDE(type, choice) ( \ - /* can't die or ask, on debug or info events */ \ - (type <= LOGLEV_INFO && (choice == ACT_ASK || choice == ACT_FATAL)) \ - /* can't ignore panics */ \ - || (type == LOGLEV_PANIC && choice == ACT_IGNORE) \ +#define BX_LOG_OPTS_EXCLUDE(type, choice) ( \ + /* can't die, ask or warn, on debug or info events */ \ + (type <= LOGLEV_INFO && (choice >= ACT_WARN)) \ + /* can't ignore panics */ \ + || (type == LOGLEV_PANIC && choice == ACT_IGNORE) \ ) // floppy / cdrom media status @@ -392,6 +393,7 @@ // synchronizing threads, etc. for each. typedef struct { Bit8u level; + Bit8u flag; const char *prefix; const char *msg; } BxLogMsgEvent; @@ -419,6 +421,12 @@ BX_LOG_NOTIFY_FAILED }; +enum { + BX_LOG_ASK_ASKDLG, + BX_LOG_ASK_MSGBOX_WARN, + BX_LOG_ASK_MSGBOX_QUIT +}; + // Event type: BX_SYNC_EVT_GET_DBG_COMMAND // // This is a synchronous event sent from the simulator to the debugger @@ -675,6 +683,7 @@ virtual int get_default_log_action(int level) {return -1;} virtual void set_default_log_action(int level, int action) {} virtual const char *get_action_name(int action) {return NULL;} + virtual int is_action_name(const char *val) {return -1;} virtual const char *get_log_level_name(int level) {return NULL;} virtual int get_max_log_level() {return -1;} @@ -715,6 +724,9 @@ // send an event from the simulator to the CI. virtual BxEvent* sim_to_ci_event(BxEvent *event) {return NULL;} + // called from simulator when it hits errors, to warn the user + // before continuing simulation + virtual int log_warn(const char *prefix, int level, const char *msg) {return -1;} // called from simulator when it hits serious errors, to ask if the user // wants to continue or not virtual int log_ask(const char *prefix, int level, const char *msg) {return -1;} diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/gui/textconfig.cc ./gui/textconfig.cc --- /home/volker/bochs/bochs/gui/textconfig.cc 2016-12-05 20:15:59.112637000 +0100 +++ ./gui/textconfig.cc 2016-12-28 12:44:43.079411258 +0100 @@ -2,7 +2,7 @@ // $Id: textconfig.cc 12983 2016-12-05 19:15:59Z sshwarts $ ///////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2002-2013 The Bochs Project +// Copyright (C) 2002-2016 The Bochs Project // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -552,8 +552,8 @@ } static const char *log_options_prompt1 = "Enter the ID of the device to edit, or -1 to return: [-1] "; -static const char *log_level_choices[] = { "ignore", "report", "ask", "fatal", "no change" }; -static int log_level_n_choices_normal = 4; +static const char *log_level_choices[N_ACT+1] = { "ignore", "report", "warn", "ask", "fatal", "no change" }; +static int log_level_n_choices_normal = N_ACT; void bx_log_options(int individual) { @@ -589,7 +589,7 @@ bx_print_log_action_table(); for (int level=0; level<SIM->get_max_log_level(); level++) { char prompt[1024]; - int action, default_action = 4; // default to no change + int action, default_action = N_ACT; // default to no change sprintf(prompt, "Enter action for %s event on all devices: [no change] ", SIM->get_log_level_name(level)); // do show the no change choice (choices=4) if (ask_menu(prompt, "", log_level_n_choices_normal+1, log_level_choices, default_action, &action)<0) @@ -718,47 +718,50 @@ event->retcode = event->u.param.param->text_ask(stdin, stderr); return event; case BX_SYNC_EVT_LOG_ASK: - { - int level = event->u.logmsg.level; - fprintf(stderr, "========================================================================\n"); - fprintf(stderr, "Event type: %s\n", SIM->get_log_level_name (level)); - fprintf(stderr, "Device: %s\n", event->u.logmsg.prefix); - fprintf(stderr, "Message: %s\n\n", event->u.logmsg.msg); - fprintf(stderr, "A %s has occurred. Do you want to:\n", SIM->get_log_level_name (level)); - fprintf(stderr, " cont - continue execution\n"); - fprintf(stderr, " alwayscont - continue execution, and don't ask again.\n"); - fprintf(stderr, " This affects only %s events from device %s\n", SIM->get_log_level_name (level), event->u.logmsg.prefix); - fprintf(stderr, " die - stop execution now\n"); - fprintf(stderr, " abort - dump core %s\n", - BX_HAVE_ABORT ? "" : "(Disabled)"); + if (event->u.logmsg.flag == BX_LOG_ASK_ASKDLG) { + int level = event->u.logmsg.level; + fprintf(stderr, "========================================================================\n"); + fprintf(stderr, "Event type: %s\n", SIM->get_log_level_name (level)); + fprintf(stderr, "Device: %s\n", event->u.logmsg.prefix); + fprintf(stderr, "Message: %s\n\n", event->u.logmsg.msg); + fprintf(stderr, "A %s has occurred. Do you want to:\n", SIM->get_log_level_name (level)); + fprintf(stderr, " cont - continue execution\n"); + fprintf(stderr, " alwayscont - continue execution, and don't ask again.\n"); + fprintf(stderr, " This affects only %s events from device %s\n", SIM->get_log_level_name (level), event->u.logmsg.prefix); + fprintf(stderr, " die - stop execution now\n"); + fprintf(stderr, " abort - dump core %s\n", + BX_HAVE_ABORT ? "" : "(Disabled)"); #if BX_DEBUGGER - fprintf(stderr, " debug - continue and return to bochs debugger\n"); + fprintf(stderr, " debug - continue and return to bochs debugger\n"); #endif #if BX_GDBSTUB - fprintf(stderr, " debug - hand control to gdb\n"); + fprintf(stderr, " debug - hand control to gdb\n"); #endif - int choice; + int choice; ask: - if (ask_menu("Choose one of the actions above: [%s] ", "", - log_action_n_choices, log_action_ask_choices, 2, &choice) < 0) - event->retcode = -1; - // return 0 for continue, 1 for alwayscontinue, 2 for die, 3 for debug. - if (!BX_HAVE_ABORT && choice==BX_LOG_ASK_CHOICE_DUMP_CORE) goto ask; - fflush(stdout); - fflush(stderr); - event->retcode = choice; - } - return event; - case BX_ASYNC_EVT_REFRESH: - case BX_ASYNC_EVT_DBG_MSG: - case BX_ASYNC_EVT_LOG_MSG: - // The text mode interface does not use these events, so just ignore - // them. - return event; - default: - fprintf(stderr, "textconfig: notify callback called with event type %04x\n", event->type); - return event; + if (ask_menu("Choose one of the actions above: [%s] ", "", + log_action_n_choices, log_action_ask_choices, 2, &choice) < 0) + event->retcode = -1; + // return 0 for continue, 1 for alwayscontinue, 2 for die, 3 for debug. + if (!BX_HAVE_ABORT && choice==BX_LOG_ASK_CHOICE_DUMP_CORE) goto ask; + fflush(stdout); + fflush(stderr); + event->retcode = choice; + } else { + // warning prompt not implemented + event->retcode = 0; + } + return event; + case BX_ASYNC_EVT_REFRESH: + case BX_ASYNC_EVT_DBG_MSG: + case BX_ASYNC_EVT_LOG_MSG: + // The text mode interface does not use these events, so just ignore + // them. + return event; + default: + fprintf(stderr, "textconfig: notify callback called with event type %04x\n", event->type); + return event; } assert(0); // switch statement should return } diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/gui/win32dialog.cc ./gui/win32dialog.cc --- /home/volker/bochs/bochs/gui/win32dialog.cc 2014-06-20 11:32:02.034026376 +0200 +++ ./gui/win32dialog.cc 2016-12-28 12:50:14.148888740 +0100 @@ -2,7 +2,7 @@ // $Id: win32dialog.cc 12381 2014-06-20 09:31:56Z vruppert $ ///////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2003-2014 The Bochs Project +// Copyright (C) 2003-2016 The Bochs Project // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -27,7 +27,7 @@ #include "win32res.h" #include "win32paramdlg.h" -const char log_choices[5][16] = {"ignore", "log", "ask user", "end simulation", "no change"}; +const char log_choices[N_ACT+1][16] = {"ignore", "log", "warn user", "ask user", "end simulation", "no change"}; HWND GetBochsWindow() { @@ -97,12 +97,16 @@ SetWindowText(GetDlgItem(hDlg, IDASKMSG), event->u.logmsg.msg); SendMessage(GetDlgItem(hDlg, IDASKLIST), LB_ADDSTRING, 0, (LPARAM)"Continue"); SendMessage(GetDlgItem(hDlg, IDASKLIST), LB_ADDSTRING, 0, (LPARAM)"Continue and don't ask again"); - SendMessage(GetDlgItem(hDlg, IDASKLIST), LB_ADDSTRING, 0, (LPARAM)"Kill simulation"); - SendMessage(GetDlgItem(hDlg, IDASKLIST), LB_ADDSTRING, 0, (LPARAM)"Abort (dump core)"); + if (event->u.logmsg.flag == BX_LOG_ASK_ASKDLG) { + SendMessage(GetDlgItem(hDlg, IDASKLIST), LB_ADDSTRING, 0, (LPARAM)"Kill simulation"); + SendMessage(GetDlgItem(hDlg, IDASKLIST), LB_ADDSTRING, 0, (LPARAM)"Abort (dump core)"); #if BX_DEBUGGER - SendMessage(GetDlgItem(hDlg, IDASKLIST), LB_ADDSTRING, 0, (LPARAM)"Continue and return to debugger"); + SendMessage(GetDlgItem(hDlg, IDASKLIST), LB_ADDSTRING, 0, (LPARAM)"Continue and return to debugger"); #endif - SendMessage(GetDlgItem(hDlg, IDASKLIST), LB_SETCURSEL, 2, 0); + SendMessage(GetDlgItem(hDlg, IDASKLIST), LB_SETCURSEL, 2, 0); + } else { + SendMessage(GetDlgItem(hDlg, IDASKLIST), LB_SETCURSEL, 0, 0); + } SetFocus(GetDlgItem(hDlg, IDASKLIST)); return FALSE; case WM_CLOSE: diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/gui/wxdialog.cc ./gui/wxdialog.cc --- /home/volker/bochs/bochs/gui/wxdialog.cc 2015-01-07 17:17:40.447882000 +0100 +++ ./gui/wxdialog.cc 2016-12-27 20:30:44.997609007 +0100 @@ -2,7 +2,7 @@ // $Id: wxdialog.cc 12594 2015-01-07 16:17:40Z sshwarts $ ///////////////////////////////////////////////////////////////// // -// Copyright (C) 2002-2014 The Bochs Project +// Copyright (C) 2002-2016 The Bochs Project // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -208,7 +208,6 @@ : wxDialog(parent, id, wxT(""), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) { - //static int integers[LOG_OPTS_N_CHOICES_NORMAL] = {0, 1, 2, 3}; static wxString names[] = ADVLOG_OPTS_TYPE_NAMES; SetTitle(ADVLOG_OPTS_TITLE); vertSizer = new wxBoxSizer(wxVERTICAL); @@ -1563,7 +1562,7 @@ bool includeNoChange) { static wxString choices[] = LOG_OPTS_CHOICES; - static int integers[LOG_OPTS_N_CHOICES] = {0, 1, 2, 3, 4}; + static int integers[LOG_OPTS_N_CHOICES] = {0, 1, 2, 3, 4, 5}; wxChoice *control = new wxChoice(parent, id, wxDefaultPosition, wxDefaultSize); int lastChoice = 0; // remember index of last choice int nchoice = includeNoChange? LOG_OPTS_N_CHOICES : LOG_OPTS_N_CHOICES_NORMAL; diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/gui/wxdialog.h ./gui/wxdialog.h --- /home/volker/bochs/bochs/gui/wxdialog.h 2014-12-23 20:30:12.896090221 +0100 +++ ./gui/wxdialog.h 2016-12-27 20:34:28.518389938 +0100 @@ -2,7 +2,7 @@ // $Id: wxdialog.h 12576 2014-12-23 19:30:03Z vruppert $ //////////////////////////////////////////////////////////////////// // -// Copyright (C) 2002-2014 The Bochs Project +// Copyright (C) 2002-2016 The Bochs Project // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -354,10 +354,10 @@ #define LOG_OPTS_PROMPT wxT("How should Bochs respond to each type of event?") #define LOG_OPTS_TYPE_NAMES { wxT("Debug events"), wxT("Info events"), wxT("Error events"), wxT("Panic events") } #define LOG_OPTS_N_TYPES 4 -#define LOG_OPTS_CHOICES { wxT("ignore"), wxT("log"), wxT("ask user"), wxT("end simulation"), wxT("no change") } -#define LOG_OPTS_N_CHOICES_NORMAL 4 -#define LOG_OPTS_N_CHOICES 5 // number of choices, including "no change" -#define LOG_OPTS_NO_CHANGE 4 // index of "no change" +#define LOG_OPTS_CHOICES { wxT("ignore"), wxT("log"), wxT("warn user"), wxT("ask user"), wxT("end simulation"), wxT("no change") } +#define LOG_OPTS_N_CHOICES_NORMAL 5 +#define LOG_OPTS_N_CHOICES 6 // number of choices, including "no change" +#define LOG_OPTS_NO_CHANGE 5 // index of "no change" #define LOG_OPTS_ADV wxT("For additional control over how each device responds to events, use the menu option \"Log ... By Device\".") wxFlexGridSizer *gridSizer; wxChoice *action[LOG_OPTS_N_TYPES]; diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/gui/wxmain.cc ./gui/wxmain.cc --- /home/volker/bochs/bochs/gui/wxmain.cc 2016-12-26 17:12:57.470174541 +0100 +++ ./gui/wxmain.cc 2016-12-28 12:15:26.035961463 +0100 @@ -2,7 +2,7 @@ // $Id: wxmain.cc 13006 2016-12-26 16:12:54Z vruppert $ ///////////////////////////////////////////////////////////////// // -// Copyright (C) 2002-2014 The Bochs Project +// Copyright (C) 2002-2016 The Bochs Project // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -1158,6 +1158,10 @@ #if !BX_DEBUGGER && !BX_GDBSTUB dlg.EnableButton(dlg.DEBUG, FALSE); #endif + if (be->u.logmsg.flag != BX_LOG_ASK_ASKDLG) { + dlg.EnableButton(dlg.DIE, FALSE); + dlg.EnableButton(dlg.DUMP, FALSE); + } dlg.SetContext(wxString(be->u.logmsg.prefix, wxConvUTF8)); dlg.SetMessage(wxString(be->u.logmsg.msg, wxConvUTF8)); int n = dlg.ShowModal(); diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/gui/x.cc ./gui/x.cc --- /home/volker/bochs/bochs/gui/x.cc 2016-12-27 17:26:59.622665119 +0100 +++ ./gui/x.cc 2016-12-28 12:03:10.963351647 +0100 @@ -2687,11 +2687,7 @@ } else { size_x = 30 + maxlen * 6; } - if (lines < 3) { - size_y = 90; - } else { - size_y = 60 + lines * 15; - } + size_y = 70 + lines * 15; x11_dialog_c *xdlg = new x11_dialog_c(name, size_x, size_y, (mode == XDLG_SIMPLE) ? 1 : 2); ypos = 34; @@ -2729,11 +2725,21 @@ bx_param_string_c *sparam; bx_param_enum_c *eparam; bx_list_c *list; + char message[256]; switch (event->type) { case BX_SYNC_EVT_LOG_ASK: - event->retcode = x11_ask_dialog(event); + if (event->u.logmsg.flag == BX_LOG_ASK_ASKDLG) { + event->retcode = x11_ask_dialog(event); + } else if (event->u.logmsg.flag == BX_LOG_ASK_MSGBOX_WARN) { + const char *title = SIM->get_log_level_name(event->u.logmsg.level); + sprintf(message, "Device: %s\n\nMessage: %s", event->u.logmsg.prefix, + event->u.logmsg.msg); + bx_param_bool_c bparam(NULL, "warn", title, message, 1); + x11_message_box(&bparam, XDLG_SIMPLE); + event->retcode = 0; + } return event; case BX_SYNC_EVT_ASK_PARAM: param = event->u.param.param; diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/logio.cc ./logio.cc --- /home/volker/bochs/bochs/logio.cc 2015-05-10 08:55:18.678940963 +0200 +++ ./logio.cc 2016-12-28 00:40:40.395736643 +0100 @@ -2,7 +2,7 @@ // $Id: logio.cc 12759 2015-05-10 06:55:16Z vruppert $ ///////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2001-2014 The Bochs Project +// Copyright (C) 2001-2016 The Bochs Project // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -50,11 +50,25 @@ else return "?"; } +static const char *act_name[N_ACT] = { "ignore", "report", "warn", "ask", "fatal" }; + const char* iofunctions::getaction(int i) const { - static const char *name[] = { "ignore", "report", "ask", "fatal" }; assert (i>=ACT_IGNORE && i<N_ACT); - return name[i]; + return act_name[i]; +} + +int iofunctions::isaction(const char *val) const +{ + int action = -1; + + for (int i = 0; i < N_ACT; i++) { + if (!strcmp(val, act_name[i])) { + action = ACT_IGNORE + i; + break; + } + } + return action; } void iofunctions::flush(void) @@ -414,6 +428,11 @@ logio->out(LOGLEV_ERROR, prefix, fmt, ap); va_end(ap); + if (onoff[LOGLEV_ERROR] == ACT_WARN) { + va_start(ap, fmt); + warn(LOGLEV_ERROR, prefix, fmt, ap); + va_end(ap); + } if (onoff[LOGLEV_ERROR] == ACT_ASK) { va_start(ap, fmt); ask(LOGLEV_ERROR, prefix, fmt, ap); @@ -438,6 +457,11 @@ logio->out(LOGLEV_PANIC, prefix, fmt, ap); va_end(ap); + if (onoff[LOGLEV_PANIC] == ACT_WARN) { + va_start(ap, fmt); + warn(LOGLEV_PANIC, prefix, fmt, ap); + va_end(ap); + } if (onoff[LOGLEV_PANIC] == ACT_ASK) { va_start(ap, fmt); ask(LOGLEV_PANIC, prefix, fmt, ap); @@ -465,6 +489,36 @@ // the actions ask() and fatal() are not supported here } +void logfunctions::warn(int level, const char *prefix, const char *fmt, va_list ap) +{ + // Guard against reentry on warn() function. The danger is that some + // function that's called within warn() could trigger another + // BX_ERROR that could call warn() again, leading to infinite + // recursion and infinite asks. + static char in_warn_already = 0; + char buf1[1024]; + if (in_warn_already) { + fprintf(stderr, "logfunctions::warn() should not reenter!!\n"); + return; + } + in_warn_already = 1; + vsnprintf(buf1, sizeof(buf1), fmt, ap); + // FIXME: facility set to 0 because it's unknown. + + // update vga screen. This is useful because sometimes useful messages + // are printed on the screen just before a panic. It's also potentially + // dangerous if this function calls ask again... That's why I added + // the reentry check above. + SIM->refresh_vga(); + + // ensure the text screen is showing + SIM->set_display_mode(DISP_MODE_CONFIG); + SIM->log_warn(prefix, level, buf1); + // return to simulation mode + SIM->set_display_mode(DISP_MODE_SIM); + in_warn_already = 0; +} + void logfunctions::ask(int level, const char *prefix, const char *fmt, va_list ap) { // Guard against reentry on ask() function. The danger is that some
2016-12-28 18:06:34 +03:00
char message[256];
switch (event->type)
{
case BX_SYNC_EVT_LOG_ASK:
diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/bochs.h ./bochs.h --- /home/volker/bochs/bochs/bochs.h 2016-08-12 19:06:18.803209189 +0200 +++ ./bochs.h 2016-12-28 00:41:20.000627252 +0100 @@ -2,7 +2,7 @@ // $Id: bochs.h 12935 2016-08-12 17:06:14Z vruppert $ ///////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2001-2015 The Bochs Project +// Copyright (C) 2001-2016 The Bochs Project // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -276,8 +276,9 @@ void error(const char *fmt, ...) BX_CPP_AttrPrintf(2, 3); void panic(const char *fmt, ...) BX_CPP_AttrPrintf(2, 3); void ldebug(const char *fmt, ...) BX_CPP_AttrPrintf(2, 3); - void fatal (const char *prefix, const char *fmt, va_list ap, int exit_status); - void ask (int level, const char *prefix, const char *fmt, va_list ap); + void fatal(const char *prefix, const char *fmt, va_list ap, int exit_status); + void warn(int level, const char *prefix, const char *fmt, va_list ap); + void ask(int level, const char *prefix, const char *fmt, va_list ap); void put(const char *p); void put(const char *n, const char *p); void setio(class iofunctions *); @@ -334,7 +335,8 @@ void set_log_action(int loglevel, int action); const char *getlevel(int i) const; const char *getaction(int i) const; - + int isaction(const char *val) const; + protected: int n_logfn; #define MAX_LOGFNS 512 diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/CHANGES ./CHANGES --- /home/volker/bochs/bochs/CHANGES 2016-12-26 10:45:44.000000000 +0100 +++ ./CHANGES 2016-12-28 15:54:25.127088081 +0100 @@ -1,5 +1,8 @@ Changes after 2.6.8 release: +- General + - Added new log action "warn", designed to show a message box on error events. + - Configure and compile - Added Android host platform support. diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/config.cc ./config.cc --- /home/volker/bochs/bochs/config.cc 2016-05-03 21:15:09.158016000 +0200 +++ ./config.cc 2016-12-27 19:53:10.461420368 +0100 @@ -2062,15 +2062,8 @@ actstr = strtok(NULL, ""); if (actstr != NULL) { def_action = !strcmp(module, "action"); - if (!strcmp(actstr, "fatal")) - action = ACT_FATAL; - else if (!strcmp (actstr, "report")) - action = ACT_REPORT; - else if (!strcmp (actstr, "ignore")) - action = ACT_IGNORE; - else if (!strcmp (actstr, "ask")) - action = ACT_ASK; - else { + action = SIM->is_action_name(actstr); + if (action < ACT_IGNORE) { PARSE_ERR(("%s: %s directive malformed.", context, params[0])); free(param); return -1; diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/gui/sdl2.cc ./gui/sdl2.cc --- /home/volker/bochs/bochs/gui/sdl2.cc 2016-08-12 19:06:18.811209142 +0200 +++ ./gui/sdl2.cc 2016-12-28 12:33:39.534288819 +0100 @@ -2,7 +2,7 @@ // $Id: sdl2.cc 12935 2016-08-12 17:06:14Z vruppert $ ///////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2014-2015 The Bochs Project +// Copyright (C) 2014-2016 The Bochs Project // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -1478,20 +1478,16 @@ SDL_MessageBoxData msgboxdata; SDL_MessageBoxButtonData buttondata[4]; int level, retcode; -#if BX_DEBUGGER || BX_GDBSTUB - int defbtn = 3; -#else - int defbtn = 2; -#endif char message[512]; level = event->u.logmsg.level; - sprintf(message, "%s %s", event->u.logmsg.prefix, event->u.logmsg.msg); + sprintf(message, "Device: %s\nMessage: %s", event->u.logmsg.prefix, + event->u.logmsg.msg); msgboxdata.flags = SDL_MESSAGEBOX_ERROR; msgboxdata.window = window; msgboxdata.title = SIM->get_log_level_name(level); msgboxdata.message = message; - msgboxdata.numbuttons = defbtn + 1; + msgboxdata.numbuttons = 2; msgboxdata.buttons = buttondata; msgboxdata.colorScheme = NULL; buttondata[0].flags = 0; @@ -1500,14 +1496,18 @@ buttondata[1].flags = 0; buttondata[1].buttonid = BX_LOG_ASK_CHOICE_CONTINUE_ALWAYS; buttondata[1].text = "Alwayscont"; + if (event->u.logmsg.flag == BX_LOG_ASK_ASKDLG) { + msgboxdata.numbuttons = 3; + buttondata[2].flags = SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT; + buttondata[2].buttonid = BX_LOG_ASK_CHOICE_DIE; + buttondata[2].text = "Quit"; #if BX_DEBUGGER || BX_GDBSTUB - buttondata[2].flags = 0; - buttondata[2].buttonid = BX_LOG_ASK_CHOICE_ENTER_DEBUG; - buttondata[2].text = "Debugger"; -#endif - buttondata[defbtn].flags = SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT; - buttondata[defbtn].buttonid = BX_LOG_ASK_CHOICE_DIE; - buttondata[defbtn].text = "Quit"; + msgboxdata.numbuttons = 4; + buttondata[3].flags = 0; + buttondata[3].buttonid = BX_LOG_ASK_CHOICE_ENTER_DEBUG; + buttondata[3].text = "Debugger"; +#endif + } if (SDL_ShowMessageBox(&msgboxdata, &retcode) < 0) { return -1; } else { diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/gui/siminterface.cc ./gui/siminterface.cc --- /home/volker/bochs/bochs/gui/siminterface.cc 2016-12-05 19:56:56.729685000 +0100 +++ ./gui/siminterface.cc 2016-12-28 11:14:02.004075717 +0100 @@ -2,7 +2,7 @@ // $Id: siminterface.cc 12981 2016-12-05 18:56:56Z sshwarts $ ///////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2002-2015 The Bochs Project +// Copyright (C) 2002-2016 The Bochs Project // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -100,6 +100,7 @@ virtual int get_log_action(int mod, int level); virtual void set_log_action(int mod, int level, int action); virtual const char *get_action_name(int action); + virtual int is_action_name(const char *val); virtual int get_default_log_action(int level) { return logfunctions::get_default_action(level); } @@ -123,6 +124,7 @@ virtual void set_notify_callback(bxevent_handler func, void *arg); virtual void get_notify_callback(bxevent_handler *func, void **arg); virtual BxEvent* sim_to_ci_event(BxEvent *event); + virtual int log_warn(const char *prefix, int level, const char *msg); virtual int log_ask(const char *prefix, int level, const char *msg); virtual void log_msg(const char *prefix, int level, const char *msg); virtual void set_log_viewer(bx_bool val) { bx_log_viewer = val; } @@ -420,6 +422,11 @@ return io->getaction(action); } +int bx_real_sim_c::is_action_name(const char *val) +{ + return io->isaction(val); +} + const char *bx_real_sim_c::get_log_level_name(int level) { return io->getlevel(level); @@ -575,6 +582,21 @@ } } +int bx_real_sim_c::log_warn(const char *prefix, int level, const char *msg) +{ + BxEvent be; + be.type = BX_SYNC_EVT_LOG_ASK; + be.u.logmsg.prefix = prefix; + be.u.logmsg.level = level; + be.u.logmsg.msg = msg; + be.u.logmsg.flag = BX_LOG_ASK_MSGBOX_WARN; + // default return value in case something goes wrong. + be.retcode = BX_LOG_NOTIFY_FAILED; + // calling notify + sim_to_ci_event(&be); + return be.retcode; +} + // returns 0 for continue, 1 for alwayscontinue, 2 for die. int bx_real_sim_c::log_ask(const char *prefix, int level, const char *msg) { @@ -583,6 +605,7 @@ be.u.logmsg.prefix = prefix; be.u.logmsg.level = level; be.u.logmsg.msg = msg; + be.u.logmsg.flag = BX_LOG_ASK_ASKDLG; // default return value in case something goes wrong. be.retcode = BX_LOG_NOTIFY_FAILED; // calling notify @@ -1157,16 +1180,10 @@ } else if (!strncmp(string, "PANIC=", 6)) { type = LOGLEV_PANIC; } - if (!strcmp(string+j, "ignore")) { - action = ACT_IGNORE; - } else if (!strcmp(string+j, "report")) { - action = ACT_REPORT; - } else if (!strcmp(string+j, "ask")) { - action = ACT_ASK; - } else if (!strcmp(string+j, "fatal")) { - action = ACT_FATAL; + action = is_action_name(string+j); + if (action >= ACT_IGNORE) { + set_log_action(dev, type, action); } - set_log_action(dev, type, action); } else { if (i == 1) { BX_ERROR(("restore_logopts(): log module '%s' not found", devname)); diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/gui/siminterface.h ./gui/siminterface.h --- /home/volker/bochs/bochs/gui/siminterface.h 2016-03-31 19:24:37.451025427 +0200 +++ ./gui/siminterface.h 2016-12-28 11:11:21.036683362 +0100 @@ -168,6 +168,7 @@ typedef enum { ACT_IGNORE = 0, ACT_REPORT, + ACT_WARN, ACT_ASK, ACT_FATAL, N_ACT @@ -178,11 +179,11 @@ // normally all action choices are available for all event types. The exclude // expression allows some choices to be eliminated if they don't make any // sense. For example, it would be stupid to ignore a panic. -#define BX_LOG_OPTS_EXCLUDE(type, choice) ( \ - /* can't die or ask, on debug or info events */ \ - (type <= LOGLEV_INFO && (choice == ACT_ASK || choice == ACT_FATAL)) \ - /* can't ignore panics */ \ - || (type == LOGLEV_PANIC && choice == ACT_IGNORE) \ +#define BX_LOG_OPTS_EXCLUDE(type, choice) ( \ + /* can't die, ask or warn, on debug or info events */ \ + (type <= LOGLEV_INFO && (choice >= ACT_WARN)) \ + /* can't ignore panics */ \ + || (type == LOGLEV_PANIC && choice == ACT_IGNORE) \ ) // floppy / cdrom media status @@ -392,6 +393,7 @@ // synchronizing threads, etc. for each. typedef struct { Bit8u level; + Bit8u flag; const char *prefix; const char *msg; } BxLogMsgEvent; @@ -419,6 +421,12 @@ BX_LOG_NOTIFY_FAILED }; +enum { + BX_LOG_ASK_ASKDLG, + BX_LOG_ASK_MSGBOX_WARN, + BX_LOG_ASK_MSGBOX_QUIT +}; + // Event type: BX_SYNC_EVT_GET_DBG_COMMAND // // This is a synchronous event sent from the simulator to the debugger @@ -675,6 +683,7 @@ virtual int get_default_log_action(int level) {return -1;} virtual void set_default_log_action(int level, int action) {} virtual const char *get_action_name(int action) {return NULL;} + virtual int is_action_name(const char *val) {return -1;} virtual const char *get_log_level_name(int level) {return NULL;} virtual int get_max_log_level() {return -1;} @@ -715,6 +724,9 @@ // send an event from the simulator to the CI. virtual BxEvent* sim_to_ci_event(BxEvent *event) {return NULL;} + // called from simulator when it hits errors, to warn the user + // before continuing simulation + virtual int log_warn(const char *prefix, int level, const char *msg) {return -1;} // called from simulator when it hits serious errors, to ask if the user // wants to continue or not virtual int log_ask(const char *prefix, int level, const char *msg) {return -1;} diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/gui/textconfig.cc ./gui/textconfig.cc --- /home/volker/bochs/bochs/gui/textconfig.cc 2016-12-05 20:15:59.112637000 +0100 +++ ./gui/textconfig.cc 2016-12-28 12:44:43.079411258 +0100 @@ -2,7 +2,7 @@ // $Id: textconfig.cc 12983 2016-12-05 19:15:59Z sshwarts $ ///////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2002-2013 The Bochs Project +// Copyright (C) 2002-2016 The Bochs Project // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -552,8 +552,8 @@ } static const char *log_options_prompt1 = "Enter the ID of the device to edit, or -1 to return: [-1] "; -static const char *log_level_choices[] = { "ignore", "report", "ask", "fatal", "no change" }; -static int log_level_n_choices_normal = 4; +static const char *log_level_choices[N_ACT+1] = { "ignore", "report", "warn", "ask", "fatal", "no change" }; +static int log_level_n_choices_normal = N_ACT; void bx_log_options(int individual) { @@ -589,7 +589,7 @@ bx_print_log_action_table(); for (int level=0; level<SIM->get_max_log_level(); level++) { char prompt[1024]; - int action, default_action = 4; // default to no change + int action, default_action = N_ACT; // default to no change sprintf(prompt, "Enter action for %s event on all devices: [no change] ", SIM->get_log_level_name(level)); // do show the no change choice (choices=4) if (ask_menu(prompt, "", log_level_n_choices_normal+1, log_level_choices, default_action, &action)<0) @@ -718,47 +718,50 @@ event->retcode = event->u.param.param->text_ask(stdin, stderr); return event; case BX_SYNC_EVT_LOG_ASK: - { - int level = event->u.logmsg.level; - fprintf(stderr, "========================================================================\n"); - fprintf(stderr, "Event type: %s\n", SIM->get_log_level_name (level)); - fprintf(stderr, "Device: %s\n", event->u.logmsg.prefix); - fprintf(stderr, "Message: %s\n\n", event->u.logmsg.msg); - fprintf(stderr, "A %s has occurred. Do you want to:\n", SIM->get_log_level_name (level)); - fprintf(stderr, " cont - continue execution\n"); - fprintf(stderr, " alwayscont - continue execution, and don't ask again.\n"); - fprintf(stderr, " This affects only %s events from device %s\n", SIM->get_log_level_name (level), event->u.logmsg.prefix); - fprintf(stderr, " die - stop execution now\n"); - fprintf(stderr, " abort - dump core %s\n", - BX_HAVE_ABORT ? "" : "(Disabled)"); + if (event->u.logmsg.flag == BX_LOG_ASK_ASKDLG) { + int level = event->u.logmsg.level; + fprintf(stderr, "========================================================================\n"); + fprintf(stderr, "Event type: %s\n", SIM->get_log_level_name (level)); + fprintf(stderr, "Device: %s\n", event->u.logmsg.prefix); + fprintf(stderr, "Message: %s\n\n", event->u.logmsg.msg); + fprintf(stderr, "A %s has occurred. Do you want to:\n", SIM->get_log_level_name (level)); + fprintf(stderr, " cont - continue execution\n"); + fprintf(stderr, " alwayscont - continue execution, and don't ask again.\n"); + fprintf(stderr, " This affects only %s events from device %s\n", SIM->get_log_level_name (level), event->u.logmsg.prefix); + fprintf(stderr, " die - stop execution now\n"); + fprintf(stderr, " abort - dump core %s\n", + BX_HAVE_ABORT ? "" : "(Disabled)"); #if BX_DEBUGGER - fprintf(stderr, " debug - continue and return to bochs debugger\n"); + fprintf(stderr, " debug - continue and return to bochs debugger\n"); #endif #if BX_GDBSTUB - fprintf(stderr, " debug - hand control to gdb\n"); + fprintf(stderr, " debug - hand control to gdb\n"); #endif - int choice; + int choice; ask: - if (ask_menu("Choose one of the actions above: [%s] ", "", - log_action_n_choices, log_action_ask_choices, 2, &choice) < 0) - event->retcode = -1; - // return 0 for continue, 1 for alwayscontinue, 2 for die, 3 for debug. - if (!BX_HAVE_ABORT && choice==BX_LOG_ASK_CHOICE_DUMP_CORE) goto ask; - fflush(stdout); - fflush(stderr); - event->retcode = choice; - } - return event; - case BX_ASYNC_EVT_REFRESH: - case BX_ASYNC_EVT_DBG_MSG: - case BX_ASYNC_EVT_LOG_MSG: - // The text mode interface does not use these events, so just ignore - // them. - return event; - default: - fprintf(stderr, "textconfig: notify callback called with event type %04x\n", event->type); - return event; + if (ask_menu("Choose one of the actions above: [%s] ", "", + log_action_n_choices, log_action_ask_choices, 2, &choice) < 0) + event->retcode = -1; + // return 0 for continue, 1 for alwayscontinue, 2 for die, 3 for debug. + if (!BX_HAVE_ABORT && choice==BX_LOG_ASK_CHOICE_DUMP_CORE) goto ask; + fflush(stdout); + fflush(stderr); + event->retcode = choice; + } else { + // warning prompt not implemented + event->retcode = 0; + } + return event; + case BX_ASYNC_EVT_REFRESH: + case BX_ASYNC_EVT_DBG_MSG: + case BX_ASYNC_EVT_LOG_MSG: + // The text mode interface does not use these events, so just ignore + // them. + return event; + default: + fprintf(stderr, "textconfig: notify callback called with event type %04x\n", event->type); + return event; } assert(0); // switch statement should return } diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/gui/win32dialog.cc ./gui/win32dialog.cc --- /home/volker/bochs/bochs/gui/win32dialog.cc 2014-06-20 11:32:02.034026376 +0200 +++ ./gui/win32dialog.cc 2016-12-28 12:50:14.148888740 +0100 @@ -2,7 +2,7 @@ // $Id: win32dialog.cc 12381 2014-06-20 09:31:56Z vruppert $ ///////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2003-2014 The Bochs Project +// Copyright (C) 2003-2016 The Bochs Project // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -27,7 +27,7 @@ #include "win32res.h" #include "win32paramdlg.h" -const char log_choices[5][16] = {"ignore", "log", "ask user", "end simulation", "no change"}; +const char log_choices[N_ACT+1][16] = {"ignore", "log", "warn user", "ask user", "end simulation", "no change"}; HWND GetBochsWindow() { @@ -97,12 +97,16 @@ SetWindowText(GetDlgItem(hDlg, IDASKMSG), event->u.logmsg.msg); SendMessage(GetDlgItem(hDlg, IDASKLIST), LB_ADDSTRING, 0, (LPARAM)"Continue"); SendMessage(GetDlgItem(hDlg, IDASKLIST), LB_ADDSTRING, 0, (LPARAM)"Continue and don't ask again"); - SendMessage(GetDlgItem(hDlg, IDASKLIST), LB_ADDSTRING, 0, (LPARAM)"Kill simulation"); - SendMessage(GetDlgItem(hDlg, IDASKLIST), LB_ADDSTRING, 0, (LPARAM)"Abort (dump core)"); + if (event->u.logmsg.flag == BX_LOG_ASK_ASKDLG) { + SendMessage(GetDlgItem(hDlg, IDASKLIST), LB_ADDSTRING, 0, (LPARAM)"Kill simulation"); + SendMessage(GetDlgItem(hDlg, IDASKLIST), LB_ADDSTRING, 0, (LPARAM)"Abort (dump core)"); #if BX_DEBUGGER - SendMessage(GetDlgItem(hDlg, IDASKLIST), LB_ADDSTRING, 0, (LPARAM)"Continue and return to debugger"); + SendMessage(GetDlgItem(hDlg, IDASKLIST), LB_ADDSTRING, 0, (LPARAM)"Continue and return to debugger"); #endif - SendMessage(GetDlgItem(hDlg, IDASKLIST), LB_SETCURSEL, 2, 0); + SendMessage(GetDlgItem(hDlg, IDASKLIST), LB_SETCURSEL, 2, 0); + } else { + SendMessage(GetDlgItem(hDlg, IDASKLIST), LB_SETCURSEL, 0, 0); + } SetFocus(GetDlgItem(hDlg, IDASKLIST)); return FALSE; case WM_CLOSE: diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/gui/wxdialog.cc ./gui/wxdialog.cc --- /home/volker/bochs/bochs/gui/wxdialog.cc 2015-01-07 17:17:40.447882000 +0100 +++ ./gui/wxdialog.cc 2016-12-27 20:30:44.997609007 +0100 @@ -2,7 +2,7 @@ // $Id: wxdialog.cc 12594 2015-01-07 16:17:40Z sshwarts $ ///////////////////////////////////////////////////////////////// // -// Copyright (C) 2002-2014 The Bochs Project +// Copyright (C) 2002-2016 The Bochs Project // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -208,7 +208,6 @@ : wxDialog(parent, id, wxT(""), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) { - //static int integers[LOG_OPTS_N_CHOICES_NORMAL] = {0, 1, 2, 3}; static wxString names[] = ADVLOG_OPTS_TYPE_NAMES; SetTitle(ADVLOG_OPTS_TITLE); vertSizer = new wxBoxSizer(wxVERTICAL); @@ -1563,7 +1562,7 @@ bool includeNoChange) { static wxString choices[] = LOG_OPTS_CHOICES; - static int integers[LOG_OPTS_N_CHOICES] = {0, 1, 2, 3, 4}; + static int integers[LOG_OPTS_N_CHOICES] = {0, 1, 2, 3, 4, 5}; wxChoice *control = new wxChoice(parent, id, wxDefaultPosition, wxDefaultSize); int lastChoice = 0; // remember index of last choice int nchoice = includeNoChange? LOG_OPTS_N_CHOICES : LOG_OPTS_N_CHOICES_NORMAL; diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/gui/wxdialog.h ./gui/wxdialog.h --- /home/volker/bochs/bochs/gui/wxdialog.h 2014-12-23 20:30:12.896090221 +0100 +++ ./gui/wxdialog.h 2016-12-27 20:34:28.518389938 +0100 @@ -2,7 +2,7 @@ // $Id: wxdialog.h 12576 2014-12-23 19:30:03Z vruppert $ //////////////////////////////////////////////////////////////////// // -// Copyright (C) 2002-2014 The Bochs Project +// Copyright (C) 2002-2016 The Bochs Project // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -354,10 +354,10 @@ #define LOG_OPTS_PROMPT wxT("How should Bochs respond to each type of event?") #define LOG_OPTS_TYPE_NAMES { wxT("Debug events"), wxT("Info events"), wxT("Error events"), wxT("Panic events") } #define LOG_OPTS_N_TYPES 4 -#define LOG_OPTS_CHOICES { wxT("ignore"), wxT("log"), wxT("ask user"), wxT("end simulation"), wxT("no change") } -#define LOG_OPTS_N_CHOICES_NORMAL 4 -#define LOG_OPTS_N_CHOICES 5 // number of choices, including "no change" -#define LOG_OPTS_NO_CHANGE 4 // index of "no change" +#define LOG_OPTS_CHOICES { wxT("ignore"), wxT("log"), wxT("warn user"), wxT("ask user"), wxT("end simulation"), wxT("no change") } +#define LOG_OPTS_N_CHOICES_NORMAL 5 +#define LOG_OPTS_N_CHOICES 6 // number of choices, including "no change" +#define LOG_OPTS_NO_CHANGE 5 // index of "no change" #define LOG_OPTS_ADV wxT("For additional control over how each device responds to events, use the menu option \"Log ... By Device\".") wxFlexGridSizer *gridSizer; wxChoice *action[LOG_OPTS_N_TYPES]; diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/gui/wxmain.cc ./gui/wxmain.cc --- /home/volker/bochs/bochs/gui/wxmain.cc 2016-12-26 17:12:57.470174541 +0100 +++ ./gui/wxmain.cc 2016-12-28 12:15:26.035961463 +0100 @@ -2,7 +2,7 @@ // $Id: wxmain.cc 13006 2016-12-26 16:12:54Z vruppert $ ///////////////////////////////////////////////////////////////// // -// Copyright (C) 2002-2014 The Bochs Project +// Copyright (C) 2002-2016 The Bochs Project // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -1158,6 +1158,10 @@ #if !BX_DEBUGGER && !BX_GDBSTUB dlg.EnableButton(dlg.DEBUG, FALSE); #endif + if (be->u.logmsg.flag != BX_LOG_ASK_ASKDLG) { + dlg.EnableButton(dlg.DIE, FALSE); + dlg.EnableButton(dlg.DUMP, FALSE); + } dlg.SetContext(wxString(be->u.logmsg.prefix, wxConvUTF8)); dlg.SetMessage(wxString(be->u.logmsg.msg, wxConvUTF8)); int n = dlg.ShowModal(); diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/gui/x.cc ./gui/x.cc --- /home/volker/bochs/bochs/gui/x.cc 2016-12-27 17:26:59.622665119 +0100 +++ ./gui/x.cc 2016-12-28 12:03:10.963351647 +0100 @@ -2687,11 +2687,7 @@ } else { size_x = 30 + maxlen * 6; } - if (lines < 3) { - size_y = 90; - } else { - size_y = 60 + lines * 15; - } + size_y = 70 + lines * 15; x11_dialog_c *xdlg = new x11_dialog_c(name, size_x, size_y, (mode == XDLG_SIMPLE) ? 1 : 2); ypos = 34; @@ -2729,11 +2725,21 @@ bx_param_string_c *sparam; bx_param_enum_c *eparam; bx_list_c *list; + char message[256]; switch (event->type) { case BX_SYNC_EVT_LOG_ASK: - event->retcode = x11_ask_dialog(event); + if (event->u.logmsg.flag == BX_LOG_ASK_ASKDLG) { + event->retcode = x11_ask_dialog(event); + } else if (event->u.logmsg.flag == BX_LOG_ASK_MSGBOX_WARN) { + const char *title = SIM->get_log_level_name(event->u.logmsg.level); + sprintf(message, "Device: %s\n\nMessage: %s", event->u.logmsg.prefix, + event->u.logmsg.msg); + bx_param_bool_c bparam(NULL, "warn", title, message, 1); + x11_message_box(&bparam, XDLG_SIMPLE); + event->retcode = 0; + } return event; case BX_SYNC_EVT_ASK_PARAM: param = event->u.param.param; diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/logio.cc ./logio.cc --- /home/volker/bochs/bochs/logio.cc 2015-05-10 08:55:18.678940963 +0200 +++ ./logio.cc 2016-12-28 00:40:40.395736643 +0100 @@ -2,7 +2,7 @@ // $Id: logio.cc 12759 2015-05-10 06:55:16Z vruppert $ ///////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2001-2014 The Bochs Project +// Copyright (C) 2001-2016 The Bochs Project // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -50,11 +50,25 @@ else return "?"; } +static const char *act_name[N_ACT] = { "ignore", "report", "warn", "ask", "fatal" }; + const char* iofunctions::getaction(int i) const { - static const char *name[] = { "ignore", "report", "ask", "fatal" }; assert (i>=ACT_IGNORE && i<N_ACT); - return name[i]; + return act_name[i]; +} + +int iofunctions::isaction(const char *val) const +{ + int action = -1; + + for (int i = 0; i < N_ACT; i++) { + if (!strcmp(val, act_name[i])) { + action = ACT_IGNORE + i; + break; + } + } + return action; } void iofunctions::flush(void) @@ -414,6 +428,11 @@ logio->out(LOGLEV_ERROR, prefix, fmt, ap); va_end(ap); + if (onoff[LOGLEV_ERROR] == ACT_WARN) { + va_start(ap, fmt); + warn(LOGLEV_ERROR, prefix, fmt, ap); + va_end(ap); + } if (onoff[LOGLEV_ERROR] == ACT_ASK) { va_start(ap, fmt); ask(LOGLEV_ERROR, prefix, fmt, ap); @@ -438,6 +457,11 @@ logio->out(LOGLEV_PANIC, prefix, fmt, ap); va_end(ap); + if (onoff[LOGLEV_PANIC] == ACT_WARN) { + va_start(ap, fmt); + warn(LOGLEV_PANIC, prefix, fmt, ap); + va_end(ap); + } if (onoff[LOGLEV_PANIC] == ACT_ASK) { va_start(ap, fmt); ask(LOGLEV_PANIC, prefix, fmt, ap); @@ -465,6 +489,36 @@ // the actions ask() and fatal() are not supported here } +void logfunctions::warn(int level, const char *prefix, const char *fmt, va_list ap) +{ + // Guard against reentry on warn() function. The danger is that some + // function that's called within warn() could trigger another + // BX_ERROR that could call warn() again, leading to infinite + // recursion and infinite asks. + static char in_warn_already = 0; + char buf1[1024]; + if (in_warn_already) { + fprintf(stderr, "logfunctions::warn() should not reenter!!\n"); + return; + } + in_warn_already = 1; + vsnprintf(buf1, sizeof(buf1), fmt, ap); + // FIXME: facility set to 0 because it's unknown. + + // update vga screen. This is useful because sometimes useful messages + // are printed on the screen just before a panic. It's also potentially + // dangerous if this function calls ask again... That's why I added + // the reentry check above. + SIM->refresh_vga(); + + // ensure the text screen is showing + SIM->set_display_mode(DISP_MODE_CONFIG); + SIM->log_warn(prefix, level, buf1); + // return to simulation mode + SIM->set_display_mode(DISP_MODE_SIM); + in_warn_already = 0; +} + void logfunctions::ask(int level, const char *prefix, const char *fmt, va_list ap) { // Guard against reentry on ask() function. The danger is that some
2016-12-28 18:06:34 +03:00
if (event->u.logmsg.flag == BX_LOG_ASK_ASKDLG) {
event->retcode = x11_ask_dialog(event);
} else if (event->u.logmsg.flag == BX_LOG_ASK_MSGBOX_WARN) {
const char *title = SIM->get_log_level_name(event->u.logmsg.level);
sprintf(message, "Device: %s\n\nMessage: %s", event->u.logmsg.prefix,
event->u.logmsg.msg);
bx_param_bool_c bparam(NULL, "warn", title, message, 1);
x11_message_box(&bparam, XDLG_SIMPLE);
event->retcode = 0;
}
return event;
case BX_SYNC_EVT_ASK_PARAM:
param = event->u.param.param;
if (param->get_type() == BXT_PARAM_STRING) {
sparam = (bx_param_string_c *)param;
opts = sparam->get_options();
if ((opts & sparam->IS_FILENAME) == 0) {
event->retcode = x11_string_dialog(sparam, NULL);
return event;
} else if ((opts & sparam->SAVE_FILE_DIALOG) ||
(opts & sparam->SELECT_FOLDER_DLG)) {
event->retcode = x11_string_dialog(sparam, NULL);
return event;
}
} else if (param->get_type() == BXT_LIST) {
list = (bx_list_c *)param;
sparam = (bx_param_string_c *)list->get_by_name("path");
eparam = (bx_param_enum_c *)list->get_by_name("status");
event->retcode = x11_string_dialog(sparam, eparam);
return event;
} else if (param->get_type() == BXT_PARAM_BOOL) {
event->retcode = x11_message_box((bx_param_bool_c*)param, XDLG_YES_NO);
return event;
}
case BX_SYNC_EVT_TICK: // called periodically by siminterface.
case BX_ASYNC_EVT_REFRESH: // called when some bx_param_c parameters have changed.
// fall into default case
default:
return (*old_callback)(old_callback_arg, event);
}
}
- apply patch.ifdef-disabled-options. Comments from that patch are below: For a whole lot of configure options, I put #if...#endif around code that is specific to the option, even in files which are normally only compiled when the option is on. This allows me to create a MS Visual C++ 6.0 workspace that supports many of these options. The workspace will basically compile every file all the time, but the code for disabled options will be commented out by the #if...#endif. This may one day lead to simplification of the Makefiles and configure scripts, but for the moment I'm leaving Makefiles and configure scripts alone. Affected options: BX_SUPPORT_APIC (cpu/apic.cc) BX_SUPPORT_X86_64 (cpu/*64.cc) BX_DEBUGGER (debug/*) BX_DISASM (disasm/*) BX_WITH_nameofgui (gui/*) BX_SUPPORT_CDROM (iodev/cdrom.cc) BX_NE2K_SUPPORT (iodev/eth*.cc, iodev/ne2k.cc) BX_SUPPORT_APIC (iodev/ioapic.cc) BX_IODEBUG_SUPPORT (iodev/iodebug.cc) BX_PCI_SUPPORT (iodev/pci*.cc) BX_SUPPORT_SB16 (iodev/sb*.cc) Modified Files: cpu/apic.cc cpu/arith64.cc cpu/ctrl_xfer64.cc cpu/data_xfer64.cc cpu/fetchdecode64.cc cpu/logical64.cc cpu/mult64.cc cpu/resolve64.cc cpu/shift64.cc cpu/stack64.cc debug/Makefile.in debug/crc.cc debug/dbg_main.cc debug/lexer.l debug/linux.cc debug/parser.c debug/parser.y disasm/dis_decode.cc disasm/dis_groups.cc gui/amigaos.cc gui/beos.cc gui/carbon.cc gui/macintosh.cc gui/rfb.cc gui/sdl.cc gui/term.cc gui/win32.cc gui/wx.cc gui/wxdialog.cc gui/wxmain.cc gui/x.cc iodev/cdrom.cc iodev/eth.cc iodev/eth_arpback.cc iodev/eth_fbsd.cc iodev/eth_linux.cc iodev/eth_null.cc iodev/eth_packetmaker.cc iodev/eth_tap.cc iodev/eth_tuntap.cc iodev/eth_win32.cc iodev/ioapic.cc iodev/iodebug.cc iodev/ne2k.cc iodev/pci.cc iodev/pci2isa.cc iodev/sb16.cc iodev/soundlnx.cc iodev/soundwin.cc
2002-11-19 08:47:45 +03:00
#endif /* if BX_WITH_X11 */