mirror of
https://github.com/holub/mame
synced 2025-05-14 01:48:19 +03:00

- Functionality now matches win32 debugger - Further code review/rewrite/simplification - Added more comment headings
415 lines
11 KiB
C
415 lines
11 KiB
C
|
|
#include "dview.h"
|
|
#ifndef SDLMAME_WIN32
|
|
#include <gconf/gconf-client.h>
|
|
#endif
|
|
|
|
G_DEFINE_TYPE(DView, dview, GTK_TYPE_CONTAINER);
|
|
|
|
static gboolean dview_expose(GtkWidget *wdv, GdkEventExpose *event)
|
|
{
|
|
const debug_view_char *viewdata;
|
|
DView *dv = DVIEW(wdv);
|
|
DViewClass *dvc = DVIEW_GET_CLASS(dv);
|
|
debug_view_xy vsize;
|
|
UINT32 i, j, xx, yy;
|
|
GdkColor bg, fg;
|
|
|
|
vsize = debug_view_get_visible_size(dv->view);
|
|
|
|
bg.red = bg.green = bg.blue = 0xffff;
|
|
gdk_gc_set_rgb_fg_color(dv->gc, &bg);
|
|
gdk_draw_rectangle(GDK_DRAWABLE(wdv->window), dv->gc, TRUE, 0, 0, wdv->allocation.width - (dv->vs ? dv->vsz : 0), wdv->allocation.height - (dv->hs ? dv->hsz : 0));
|
|
|
|
if(dv->hs && dv->vs) {
|
|
gdk_gc_set_foreground(dv->gc, &wdv->style->bg[GTK_STATE_NORMAL]);
|
|
gdk_draw_rectangle(GDK_DRAWABLE(wdv->window), dv->gc, TRUE,
|
|
wdv->allocation.width - dv->vsz, wdv->allocation.height - dv->hsz,
|
|
dv->vsz, dv->hsz);
|
|
}
|
|
|
|
viewdata = debug_view_get_chars(dv->view);
|
|
|
|
yy = wdv->style->ythickness;
|
|
for(j=0; j<vsize.y; j++) {
|
|
xx = wdv->style->xthickness;
|
|
for(i=0; i<vsize.x; i++) {
|
|
unsigned char attr = viewdata->attrib;
|
|
char s[3];
|
|
unsigned char v = viewdata->byte;
|
|
if(v < 128) {
|
|
s[0] = v;
|
|
s[1] = 0;
|
|
} else {
|
|
s[0] = 0xc0 | (v>>6);
|
|
s[1] = 0x80 | (v & 0x3f);
|
|
s[2] = 0;
|
|
}
|
|
|
|
bg.red = bg.green = bg.blue = 0xffff;
|
|
fg.red = fg.green = fg.blue = 0;
|
|
|
|
if(attr & DCA_ANCILLARY)
|
|
bg.red = bg.green = bg.blue = 0xe0e0;
|
|
if(attr & DCA_SELECTED) {
|
|
bg.red = 0xffff;
|
|
bg.green = bg.blue = 0x8080;
|
|
}
|
|
if(attr & DCA_CURRENT) {
|
|
bg.red = bg.green = 0xffff;
|
|
bg.blue = 0;
|
|
}
|
|
if(attr & DCA_CHANGED) {
|
|
fg.red = 0xffff;
|
|
fg.green = fg.blue = 0;
|
|
}
|
|
if(attr & DCA_INVALID) {
|
|
fg.red = fg.green = 0;
|
|
fg.blue = 0xffff;
|
|
}
|
|
if(attr & DCA_DISABLED) {
|
|
fg.red = (fg.red + bg.red) >> 1;
|
|
fg.green = (fg.green + bg.green) >> 1;
|
|
fg.blue = (fg.blue + bg.blue) >> 1;
|
|
}
|
|
if(attr & DCA_COMMENT) {
|
|
fg.red = fg.blue = 0;
|
|
fg.green = 0x8080;
|
|
}
|
|
|
|
pango_layout_set_text(dv->playout, s, -1);
|
|
gdk_gc_set_rgb_fg_color(dv->gc, &bg);
|
|
gdk_draw_rectangle(GDK_DRAWABLE(wdv->window), dv->gc, TRUE, xx, yy, dvc->fixedfont_width, dvc->fixedfont_height);
|
|
gdk_gc_set_rgb_fg_color(dv->gc, &fg);
|
|
gdk_draw_layout(GDK_DRAWABLE(wdv->window), dv->gc, xx, yy, dv->playout);
|
|
|
|
xx += dvc->fixedfont_width;
|
|
viewdata++;
|
|
}
|
|
yy += dvc->fixedfont_height;
|
|
}
|
|
|
|
gtk_paint_shadow(wdv->style, wdv->window,
|
|
GTK_STATE_NORMAL, GTK_SHADOW_IN,
|
|
&event->area, wdv, "scrolled_window",
|
|
0, 0,
|
|
wdv->allocation.width - (dv->vs ? dv->vsz : 0),
|
|
wdv->allocation.height - (dv->hs ? dv->hsz : 0));
|
|
|
|
GTK_WIDGET_CLASS(g_type_class_peek_parent(dvc))->expose_event(wdv, event);
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
static void dview_hadj_changed(GtkAdjustment *adj, DView *dv)
|
|
{
|
|
debug_view_xy pos;
|
|
UINT32 v = (UINT32)(adj->value);
|
|
|
|
pos = debug_view_get_visible_position(dv->view);
|
|
|
|
if (v != pos.x)
|
|
{
|
|
pos.x = v;
|
|
debug_view_set_visible_position(dv->view, pos);
|
|
gtk_widget_queue_draw(GTK_WIDGET(dv));
|
|
}
|
|
}
|
|
|
|
static void dview_vadj_changed(GtkAdjustment *adj, DView *dv)
|
|
{
|
|
debug_view_xy pos;
|
|
UINT32 v = (UINT32)(adj->value);
|
|
|
|
pos = debug_view_get_visible_position(dv->view);
|
|
|
|
if (v != pos.y)
|
|
{
|
|
pos.y = v;
|
|
debug_view_set_visible_position(dv->view, pos);
|
|
gtk_widget_queue_draw(GTK_WIDGET(dv));
|
|
}
|
|
}
|
|
|
|
static void dview_realize(GtkWidget *wdv)
|
|
{
|
|
GdkWindowAttr attributes;
|
|
gint attributes_mask;
|
|
DView *dv;
|
|
|
|
GTK_WIDGET_SET_FLAGS(wdv, GTK_REALIZED | GTK_CAN_FOCUS);
|
|
dv = DVIEW(wdv);
|
|
|
|
attributes.window_type = GDK_WINDOW_CHILD;
|
|
attributes.x = wdv->allocation.x;
|
|
attributes.y = wdv->allocation.y;
|
|
attributes.width = wdv->allocation.width;
|
|
attributes.height = wdv->allocation.height;
|
|
attributes.wclass = GDK_INPUT_OUTPUT;
|
|
attributes.visual = gtk_widget_get_visual(wdv);
|
|
attributes.colormap = gtk_widget_get_colormap(wdv);
|
|
attributes.event_mask = gtk_widget_get_events(wdv) | GDK_EXPOSURE_MASK
|
|
| GDK_BUTTON_PRESS_MASK | GDK_KEY_PRESS_MASK
|
|
| GDK_FOCUS_CHANGE_MASK;
|
|
|
|
attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
|
|
|
|
wdv->window = gdk_window_new(gtk_widget_get_parent_window(wdv), &attributes, attributes_mask);
|
|
gdk_window_set_user_data(wdv->window, dv);
|
|
dv->gc = gdk_gc_new(GDK_DRAWABLE(wdv->window));
|
|
wdv->style = gtk_style_attach(wdv->style, wdv->window);
|
|
}
|
|
|
|
static void dview_size_allocate(GtkWidget *wdv, GtkAllocation *allocation)
|
|
{
|
|
DView *dv = DVIEW(wdv);
|
|
DViewClass *dvc = DVIEW_GET_CLASS(dv);
|
|
UINT32 ah = allocation->height-2*wdv->style->ythickness;
|
|
UINT32 aw = allocation->width-2*wdv->style->xthickness;
|
|
int ohs = dv->hs;
|
|
int ovs = dv->vs;
|
|
debug_view_xy size, pos, col, vsize;
|
|
|
|
pos = debug_view_get_visible_position(dv->view);
|
|
size = debug_view_get_total_size(dv->view);
|
|
|
|
dv->tr = size.y;
|
|
dv->tc = size.x;
|
|
|
|
dv->hs = size.x*dvc->fixedfont_width > aw;
|
|
dv->vs = size.y*dvc->fixedfont_height > ah;
|
|
|
|
if(dv->hs)
|
|
ah -= dv->hsz;
|
|
if(dv->vs)
|
|
aw -= dv->vsz;
|
|
|
|
dv->hs = size.x*dvc->fixedfont_width > aw;
|
|
dv->vs = size.y*dvc->fixedfont_height > ah;
|
|
|
|
ah = allocation->height - (dv->hs ? dv->hsz : 0);
|
|
aw = allocation->width - (dv->vs ? dv->vsz : 0);
|
|
|
|
col.y = (ah-2*wdv->style->ythickness+dvc->fixedfont_height-1) / dvc->fixedfont_height;
|
|
col.x = (aw-2*wdv->style->xthickness+dvc->fixedfont_width-1) / dvc->fixedfont_width;
|
|
|
|
wdv->allocation = *allocation;
|
|
|
|
vsize.y = size.y-pos.y;
|
|
vsize.x = size.x-pos.x;
|
|
if(vsize.y > col.y)
|
|
vsize.y = col.y;
|
|
else if(vsize.y < col.y) {
|
|
pos.y = size.y-col.y;
|
|
if(pos.y < 0)
|
|
pos.y = 0;
|
|
vsize.y = size.y-pos.y;
|
|
}
|
|
if(vsize.x > col.x)
|
|
vsize.x = col.x;
|
|
else if(vsize.x < col.x) {
|
|
pos.x = size.x-col.x;
|
|
if(pos.x < 0)
|
|
pos.x = 0;
|
|
vsize.x = size.x-pos.x;
|
|
}
|
|
|
|
debug_view_set_visible_position(dv->view, pos);
|
|
debug_view_set_visible_size(dv->view, vsize);
|
|
|
|
if(GTK_WIDGET_REALIZED(wdv))
|
|
gdk_window_move_resize(wdv->window,
|
|
allocation->x, allocation->y,
|
|
allocation->width, allocation->height);
|
|
|
|
if(dv->hs) {
|
|
GtkAllocation al;
|
|
int span = (aw-2*wdv->style->xthickness) / dvc->fixedfont_width;
|
|
|
|
if(!ohs)
|
|
gtk_widget_show(dv->hscrollbar);
|
|
al.x = 0;
|
|
al.y = ah;
|
|
al.width = aw;
|
|
al.height = dv->hsz;
|
|
gtk_widget_size_allocate(dv->hscrollbar, &al);
|
|
if(pos.x+span > size.x)
|
|
pos.x = size.x-span;
|
|
if(pos.x < 0)
|
|
pos.x = 0;
|
|
dv->hadj->lower = 0;
|
|
dv->hadj->upper = size.x;
|
|
dv->hadj->value = pos.x;
|
|
dv->hadj->step_increment = 1;
|
|
dv->hadj->page_increment = span;
|
|
dv->hadj->page_size = span;
|
|
gtk_adjustment_changed(dv->hadj);
|
|
debug_view_set_visible_position(dv->view, pos);
|
|
} else {
|
|
if(ohs)
|
|
gtk_widget_hide(dv->hscrollbar);
|
|
}
|
|
|
|
if(dv->vs) {
|
|
GtkAllocation al;
|
|
int span = (ah-2*wdv->style->ythickness) / dvc->fixedfont_height;
|
|
|
|
if(!ovs)
|
|
gtk_widget_show(dv->vscrollbar);
|
|
al.x = aw;
|
|
al.y = 0;
|
|
al.width = dv->vsz;
|
|
al.height = ah;
|
|
gtk_widget_size_allocate(dv->vscrollbar, &al);
|
|
if(pos.y+span > size.y)
|
|
pos.y = size.y-span;
|
|
if(pos.y < 0)
|
|
pos.y = 0;
|
|
dv->vadj->lower = 0;
|
|
dv->vadj->upper = size.y;
|
|
dv->vadj->value = pos.y;
|
|
dv->vadj->step_increment = 1;
|
|
dv->vadj->page_increment = span;
|
|
dv->vadj->page_size = span;
|
|
gtk_adjustment_changed(dv->vadj);
|
|
debug_view_set_visible_position(dv->view, pos);
|
|
} else {
|
|
if(ovs)
|
|
gtk_widget_hide(dv->vscrollbar);
|
|
}
|
|
}
|
|
|
|
static void dview_size_request(GtkWidget *wdv, GtkRequisition *req)
|
|
{
|
|
GtkRequisition req2;
|
|
DView *dv = DVIEW(wdv);
|
|
DViewClass *dvc = DVIEW_GET_CLASS(dv);
|
|
int vs = 0, hs = 0;
|
|
debug_view_xy size;
|
|
|
|
size = debug_view_get_total_size(dv->view);
|
|
|
|
if(size.x > 50) {
|
|
size.x = 50;
|
|
hs = 1;
|
|
}
|
|
if(size.y > 20) {
|
|
size.y = 20;
|
|
vs = 1;
|
|
}
|
|
req->width = size.x*dvc->fixedfont_width+2*wdv->style->xthickness;
|
|
req->height = size.y*dvc->fixedfont_height+2*wdv->style->ythickness;
|
|
|
|
gtk_widget_size_request(dv->hscrollbar, &req2);
|
|
dv->hsz = req2.height;
|
|
|
|
gtk_widget_size_request(dv->vscrollbar, &req2);
|
|
dv->vsz = req2.width;
|
|
|
|
if(hs)
|
|
req->height += dv->hsz;
|
|
if(vs)
|
|
req->width += dv->vsz;
|
|
}
|
|
|
|
static void dview_forall(GtkContainer *dvc, gboolean include_internals, GtkCallback callback, gpointer callback_data)
|
|
{
|
|
if(include_internals) {
|
|
DView *dv = DVIEW(dvc);
|
|
callback(dv->hscrollbar, callback_data);
|
|
callback(dv->vscrollbar, callback_data);
|
|
}
|
|
}
|
|
|
|
|
|
static void dview_class_init(DViewClass *dvc)
|
|
{
|
|
#ifndef SDLMAME_WIN32
|
|
GConfClient *conf = gconf_client_get_default();
|
|
char *name = 0;
|
|
dvc->fixedfont = 0;
|
|
|
|
if(conf)
|
|
name = gconf_client_get_string(conf, "/desktop/gnome/interface/monospace_font_name", 0);
|
|
|
|
if(name) {
|
|
dvc->fixedfont = pango_font_description_from_string(name);
|
|
g_free(name);
|
|
}
|
|
|
|
if(!dvc->fixedfont)
|
|
#endif
|
|
dvc->fixedfont = pango_font_description_from_string("Monospace 10");
|
|
|
|
if(!dvc->fixedfont) {
|
|
mame_printf_error("Couldn't find a monospace font, aborting\n");
|
|
abort();
|
|
}
|
|
|
|
GTK_CONTAINER_CLASS(dvc)->forall = dview_forall;
|
|
GTK_WIDGET_CLASS(dvc)->expose_event = dview_expose;
|
|
GTK_WIDGET_CLASS(dvc)->realize = dview_realize;
|
|
GTK_WIDGET_CLASS(dvc)->size_request = dview_size_request;
|
|
GTK_WIDGET_CLASS(dvc)->size_allocate = dview_size_allocate;
|
|
}
|
|
|
|
|
|
static void dview_init(DView *dv)
|
|
{
|
|
DViewClass *dvc;
|
|
|
|
dvc = DVIEW_GET_CLASS(dv);
|
|
|
|
if(!dvc->fixedfont_width) {
|
|
PangoFontMetrics *metrics;
|
|
metrics = pango_context_get_metrics(gtk_widget_get_pango_context(GTK_WIDGET(dv)), dvc->fixedfont, 0);
|
|
|
|
dvc->fixedfont_width = PANGO_PIXELS(pango_font_metrics_get_approximate_char_width(metrics));
|
|
dvc->fixedfont_height = PANGO_PIXELS(pango_font_metrics_get_ascent(metrics) +
|
|
pango_font_metrics_get_descent(metrics));
|
|
}
|
|
|
|
dv->view = 0;
|
|
gtk_widget_modify_font(GTK_WIDGET(dv), dvc->fixedfont);
|
|
dv->playout = gtk_widget_create_pango_layout(GTK_WIDGET(dv), 0);
|
|
pango_layout_set_font_description(dv->playout, dvc->fixedfont);
|
|
dv->gc = 0;
|
|
|
|
dv->hadj = GTK_ADJUSTMENT(gtk_adjustment_new(0, 0, 1, 1, 1, 1));
|
|
dv->hscrollbar = gtk_hscrollbar_new(dv->hadj);
|
|
gtk_widget_set_parent(dv->hscrollbar, GTK_WIDGET(dv));
|
|
g_object_ref(dv->hscrollbar);
|
|
g_signal_connect(dv->hadj, "value-changed", G_CALLBACK(dview_hadj_changed), dv);
|
|
|
|
dv->vadj = GTK_ADJUSTMENT(gtk_adjustment_new(0, 0, 1, 1, 1, 1));
|
|
dv->vscrollbar = gtk_vscrollbar_new(dv->vadj);
|
|
gtk_widget_set_parent(dv->vscrollbar, GTK_WIDGET(dv));
|
|
g_object_ref(dv->vscrollbar);
|
|
g_signal_connect(dv->vadj, "value-changed", G_CALLBACK(dview_vadj_changed), dv);
|
|
}
|
|
|
|
static void dview_update(debug_view *dw, void *osdprivate)
|
|
{
|
|
DView *dv = (DView *) osdprivate;
|
|
debug_view_xy size = debug_view_get_total_size(dw);
|
|
|
|
if((dv->tr != size.y) || (dv->tc != size.x))
|
|
gtk_widget_queue_resize(GTK_WIDGET(dv));
|
|
else
|
|
gtk_widget_queue_draw(GTK_WIDGET(dv));
|
|
}
|
|
|
|
GtkWidget *dview_new(const gchar *widget_name, const gchar *string1, const gchar *string2, gint int1, gint int2)
|
|
{
|
|
GtkWidget *wdv = (GtkWidget *) g_object_new(DVIEW_TYPE, NULL);
|
|
DView *dv = DVIEW(wdv);
|
|
dv->name = (gchar *) widget_name;
|
|
return wdv;
|
|
}
|
|
|
|
void dview_set_debug_view(DView *dv, running_machine *machine, int type)
|
|
{
|
|
dv->view = debug_view_alloc(machine, type, dview_update, dv);
|
|
dv->dv_type = type;
|
|
}
|