All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] quick gtk2.c update
@ 2005-06-19 19:09 Jim C. Brown
  2005-06-19 22:25 ` Sebastien Bechet
  2005-06-19 22:57 ` jeebs
  0 siblings, 2 replies; 59+ messages in thread
From: Jim C. Brown @ 2005-06-19 19:09 UTC (permalink / raw)
  To: qemu-devel

[-- Attachment #1: Type: text/plain, Size: 650 bytes --]

Minor changes to gtk2_send_mouse_move() for GTK 2.6

First, it seems that once the mouse is moved, GDK 2.6 will keep sending updates
- even if no movement has occurred. Fix: check for this and return as fast as
possible to avoid hogging the cpu.

Also, GDK now seems able to see XWarpPointer() moves, causing the guest pointer
to be wrapped (if mouse acceleration is off, the guest pointer will be trapped
in the "box"). Fix: manually update the internal mosue position first, so
these moves will look like the "zero moves" above, so we can ignore them.

-- 
Infinite complexity begets infinite beauty.
Infinite precision begets infinite perfection.

[-- Attachment #2: gtk2.c --]
[-- Type: text/plain, Size: 21747 bytes --]

/*
 * QEMU GTK2 display driver
 * based on SDL driver by Fabrice
 * 
 * Copyright (c) 2005 Jim Brown
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
#include "vl.h"

#include <gtk/gtk.h>
#include <gdk/gdk.h>

#include "fullscreen.h"

/* define our own bitshift enums to allow qemugtk to know difference between left and right alt - something gtk doesnt provide in its modifiers mask. this uses qemu's own modifier_state[] map in order to guess correctly */
typedef enum
{
	gtkshiftleft = 1 << 0,
	gtkshiftright = 1 << 1,
	gtkcontrolleft = 1 << 2,
	gtkcontrolright = 1 << 3,
	gtkaltleft = 1 << 4,
	gtkaltright = 1 << 5,
	gtkcapslock = 1 << 6
} gtk2keymod;


static GtkWidget *screen;
static GdkImage *image=NULL;
static GdkCursor *invisible_cursor;
static int ox = 0, oy = 0;
static int gui_grab; /* if true, all keyboard/mouse events are grabbed */
static int last_vm_running;
static int gui_saved_grab;
static int gui_fullscreen;
static int gui_key_modifier_pressed;
static int gui_keysym;
static int gui_fullscreen_initial_grab;
static int gui_grab_code = gtkaltleft | gtkcontrolleft;
static uint8_t modifiers_state[256];
static unsigned int cw, ch;
static gint cx, cy;

static gboolean gtk2_expose(GtkWidget *wid, GdkEventExpose *event)
{
    gdk_draw_image(wid->window, wid->style->fg_gc[GTK_WIDGET_STATE(wid)], image, event->area.x, event->area.y, event->area.x, event->area.y, event->area.width, event->area.height);
    return TRUE;
}

static void gtk2_update(DisplayState *ds, int x, int y, int w, int h)
{
    //    printf("updating x=%d y=%d w=%d h=%d\n", x, y, w, h);
    GdkEventExpose ev;
    ev.area.x = x;
    ev.area.y = y;
    ev.area.width = w;
    ev.area.height = h;
    gtk2_expose(screen, &ev);
}

static void gtk2_resize(DisplayState *ds, int w, int h)
{

    //    printf(" resizing to %d %d\n", w, h);

    if (gui_fullscreen)
    {
        if (cw != w || ch != h)
            fullscreen_switch(cx, cy, w, h); /* changing video modes */
        //gtk_window_fullscreen(GTK_WINDOW(screen));
    }
    else
    {
        //gtk_window_unfullscreen(GTK_WINDOW(screen));
    }

    cw = w; ch = h;

    if (image)
	 g_object_unref(image);

/* gdk_visual_get_best_with_depth() ??? but then how to paint onto window? */
    image = gdk_image_new(GDK_IMAGE_NORMAL, gdk_visual_get_system(), w, h);
    gdk_image_set_colormap(image, gdk_colormap_get_system());

    gtk_window_set_default_size(GTK_WINDOW(screen), w, h);
    gtk_widget_set_size_request(screen, w, h);
    gtk_window_resize(GTK_WINDOW(screen), w, h);

    ds->data = image->mem;
    ds->linesize = image->bpl;
    ds->depth = image->bits_per_pixel;
    ds->width = w;
    ds->height = h;
    gtk2_update(ds, 0, 0, w, h);
}

/* generic keyboard conversion */

#include "gdk_keysym.h"
#include "keymaps.c"

static kbd_layout_t *kbd_layout = NULL;

static uint8_t gtk2_keyevent_to_keycode_generic(const GdkEventKey *ev)
{
    int keysym;
    /* workaround for X11+SDL bug with AltGR - is it still needed for Gtk2? */
    keysym = ev->keyval;
    if (keysym == 0 && ev->hardware_keycode == 113)
	keysym = GDK_Mode_switch;
    return keysym2scancode(kbd_layout, keysym);
}

/* specific keyboard conversions from scan codes */

#if defined(_WIN32)

static uint8_t gtk2_keyevent_to_keycode(const GdkEventKey *ev)
{
    return ev->hardware_keycode; /* does this work on win32 gtk? */
}

#else

static const uint8_t x_keycode_to_pc_keycode[61] = {
   0xc7,      /*  97  Home   */
   0xc8,      /*  98  Up     */
   0xc9,      /*  99  PgUp   */
   0xcb,      /* 100  Left   */
   0x4c,        /* 101  KP-5   */
   0xcd,      /* 102  Right  */
   0xcf,      /* 103  End    */
   0xd0,      /* 104  Down   */
   0xd1,      /* 105  PgDn   */
   0xd2,      /* 106  Ins    */
   0xd3,      /* 107  Del    */
   0x9c,      /* 108  Enter  */
   0x9d,      /* 109  Ctrl-R */
   0x0,       /* 110  Pause  */
   0xb7,      /* 111  Print  */
   0xb5,      /* 112  Divide */
   0xb8,      /* 113  Alt-R  */
   0xc6,      /* 114  Break  */   
   0x0,         /* 115 */
   0x0,         /* 116 */
   0x0,         /* 117 */
   0x0,         /* 118 */
   0x0,         /* 119 */
   0x70,         /* 120 Hiragana_Katakana */
   0x0,         /* 121 */
   0x0,         /* 122 */
   0x73,         /* 123 backslash */
   0x0,         /* 124 */
   0x0,         /* 125 */
   0x0,         /* 126 */
   0x0,         /* 127 */
   0x0,         /* 128 */
   0x79,         /* 129 Henkan */
   0x0,         /* 130 */
   0x7b,         /* 131 Muhenkan */
   0x0,         /* 132 */
   0x7d,         /* 133 Yen */
   0x0,         /* 134 */
   0x0,         /* 135 */
   0x47,         /* 136 KP_7 */
   0x48,         /* 137 KP_8 */
   0x49,         /* 138 KP_9 */
   0x4b,         /* 139 KP_4 */
   0x4c,         /* 140 KP_5 */
   0x4d,         /* 141 KP_6 */
   0x4f,         /* 142 KP_1 */
   0x50,         /* 143 KP_2 */
   0x51,         /* 144 KP_3 */
   0x52,         /* 145 KP_0 */
   0x53,         /* 146 KP_. */
   0x47,         /* 147 KP_HOME */
   0x48,         /* 148 KP_UP */
   0x49,         /* 149 KP_PgUp */
   0x4b,         /* 150 KP_Left */
   0x4c,         /* 151 KP_ */
   0x4d,         /* 152 KP_Right */
   0x4f,         /* 153 KP_End */
   0x50,         /* 154 KP_Down */
   0x51,         /* 155 KP_PgDn */
   0x52,         /* 156 KP_Ins */
   0x53,         /* 157 KP_Del */
};

static uint8_t gtk2_keyevent_to_keycode(const GdkEventKey *ev)
{
    int keycode;

    keycode = ev->hardware_keycode;

    if (keycode < 9) {
	keycode = 0;
    } else if (keycode < 97) {
	keycode -= 8; /* just an offset */
    } else if (keycode < 158) {
	/* use conversion table */
	keycode = x_keycode_to_pc_keycode[keycode - 97];
    } else {
	keycode = 0;
    }
    return keycode;
}

#endif

static void reset_keys(void)
{
    int i;
    for(i = 0; i < 256; i++) {
	if (modifiers_state[i]) {
	    if (i & 0x80)
		kbd_put_keycode(0xe0);
	    kbd_put_keycode(i | 0x80);
	    modifiers_state[i] = 0;
	}
    }
}

/* convert GDK modifiers and invoke ugly hack to distinguish
between left and right shift/control/alt */
static guint gtk2_GetModState(const GdkEventKey *ev)
{
	guint key = 0, keyval = ev->keyval, state = ev->state;
	switch(keyval)
	{
		case GDK_Shift_L:
			if (ev->type != GDK_KEY_RELEASE)
				key |= gtkshiftleft;
			keyval = 1;
			break;
		case GDK_Shift_R:
			if (ev->type != GDK_KEY_RELEASE)
				key |= gtkshiftright;
			keyval = 1;
			break;
		case GDK_Control_L:
			if (ev->type != GDK_KEY_RELEASE)
				key |= gtkcontrolleft;
			keyval = 2;
			break;
		case GDK_Control_R:
			if (ev->type != GDK_KEY_RELEASE)
				key |= gtkcontrolright;
			keyval = 2;
			break;
		case GDK_Alt_L:
			if (ev->type != GDK_KEY_RELEASE)
				key |= gtkaltleft;
			keyval = 3;
			break;
		case GDK_Alt_R:
			if (ev->type != GDK_KEY_RELEASE)
				key |= gtkaltright;
			keyval = 3;
			break;
		case GDK_Caps_Lock:
			if (ev->type != GDK_KEY_RELEASE)
				key |= gtkcapslock;
			keyval = 4;
			break;
		default:
			keyval = 0;
			break;
	}
	if (keyval != 1 && (state & GDK_SHIFT_MASK))
	{
		if (modifiers_state[0x2a])
			key |= gtkshiftleft;
		if (modifiers_state[0x36])
			key |= gtkshiftright;
	}
	if (keyval != 2 && (state & GDK_CONTROL_MASK))
	{
		if (modifiers_state[0x1d])
			key |= gtkcontrolleft;
		if (modifiers_state[0x9d])
			key |= gtkcontrolright;
	}
	if (keyval != 3 && (state & GDK_MOD1_MASK)) /* fixme: need to do a check to make sure that alt is mapped to GDK_MOD1_MASK in the GDK_Keymap */
	{
		if (modifiers_state[0x38])
			key |= gtkaltleft;
		if (modifiers_state[0xb8])
			key |= gtkaltright;
	}
	if (keyval != 4 && (state & GDK_LOCK_MASK))
		key |= gtkcapslock;
	return key;
}

static void gtk2_process_key(GdkEventKey *ev)
{
    int keycode, v;

    if (ev->keyval == GDK_Pause) {
	/* specific case */
	v = 0;
	if (ev->type == GDK_KEY_RELEASE)
	    v |= 0x80;
	kbd_put_keycode(0xe1);
	kbd_put_keycode(0x1d | v);
	kbd_put_keycode(0x45 | v);
	return;
    }

    if (kbd_layout) {
	keycode = gtk2_keyevent_to_keycode_generic(ev);
    } else {
	keycode = gtk2_keyevent_to_keycode(ev);
    }

    switch(keycode) {
    case 0x00:
	/* sent when leaving window: reset the modifiers state */
	reset_keys();
	return;
    case 0x2a:                          /* Left Shift */
    case 0x36:                          /* Right Shift */
    case 0x1d:                          /* Left CTRL */
    case 0x9d:                          /* Right CTRL */
    case 0x38:                          /* Left ALT */
    case 0xb8:                         /* Right ALT */
	if (ev->type == GDK_KEY_RELEASE)
	    modifiers_state[keycode] = 0;
	else
	    modifiers_state[keycode] = 1;
	break;
    case 0x45: /* num lock */
    case 0x3a: /* caps lock */
	/* GTK does send the key up event, so we dont generate it */
	/*kbd_put_keycode(keycode);
	kbd_put_keycode(keycode | 0x80);
	return;*/
	break;
    }

    /* now send the key code */
    if (keycode & 0x80)
	kbd_put_keycode(0xe0);
    if (ev->type == GDK_KEY_RELEASE)
	kbd_put_keycode(keycode | 0x80);
    else
	kbd_put_keycode(keycode & 0x7f);
}

static void gtk2_update_caption(void)
{
    char buf[1024];
    strcpy(buf, "QEMU");
    if (!vm_running) {
	strcat(buf, " [Stopped]");
    }
    if (gui_grab) {
	strcat(buf, " - Press Ctrl-Alt to exit grab");
    }
    gtk_window_set_title(GTK_WINDOW(screen), buf);
}

/* what a nasty hack. this should be a part of the GDK, not external!!! */
#include "gdk_set_window_pointer.c"

static void gtk2_grab_start(void)
{
    gint y;
    guint events;
    GdkModifierType state; /* dummy var */
    events = GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_SCROLL_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK;
    y = gdk_pointer_grab(screen->window, TRUE, events, screen->window, invisible_cursor, GDK_CURRENT_TIME);
    if (y)
	printf("GTK Warning - pointer grab failed!\n");
    y = gdk_keyboard_grab(screen->window, TRUE, GDK_CURRENT_TIME);
    if (y)
	printf("GTK Warning - keyboard grab failed!\n");
    /* do a dummy read to avoid moving mouse - set ox and oy to stay in sync */
    gdk_window_get_pointer(screen->window, &ox, &oy, &state);
    gui_grab = 1;
    gtk2_update_caption();
}

static void gtk2_grab_end(void)
{
    gdk_pointer_ungrab(GDK_CURRENT_TIME);
    gdk_keyboard_ungrab(GDK_CURRENT_TIME);
    gdk_window_set_pointer(screen->window, cx, cy);
    gui_grab = 0;
    gtk2_update_caption();
}

static gboolean gtk2_send_mouse_scroll(GtkWidget *wid, GdkEventScroll *ev)
{
    int x, y, dx, dy, dz, state, buttons;
    if (gui_grab)
    {

    x = ev->x;
    y = ev->y;
    state = ev->state;
    buttons = 0;
    dx = x - ox;
    dy = y - oy;
    ox = x;
    oy = y;
    buttons = 0;
    if ((state & GDK_BUTTON1_MASK))
	buttons |= MOUSE_EVENT_LBUTTON;
    if ((state & GDK_BUTTON3_MASK))
	buttons |= MOUSE_EVENT_RBUTTON;
    if ((state & GDK_BUTTON2_MASK))
	buttons |= MOUSE_EVENT_MBUTTON;
    /* test wheel - copied from Sebastien Bechet's gtk.c */
    dz = 0;
    if ((state & GDK_BUTTON4_MASK) || ev->direction == GDK_SCROLL_UP)
	dz--;
    if ((state & GDK_BUTTON5_MASK) || ev->direction == GDK_SCROLL_DOWN)
	dz++;
    kbd_mouse_event(dx, dy, dz, buttons);

    }
    return TRUE;
}

static gboolean gtk2_send_mouse_button(GtkWidget *wid, GdkEventButton *ev)
{
    int x, y, dx, dy, dz, state, buttons;
    if (ev->type == GDK_2BUTTON_PRESS || ev->type == GDK_3BUTTON_PRESS)
        return TRUE; /* double or triple click - superflurious - ignore */
    if (gui_grab)
    {

    x = ev->x;
    y = ev->y;
    state = ev->state;
    buttons = 0;
    dx = x - ox;
    dy = y - oy;
    ox = x;
    oy = y;
    buttons = 0;
    if ((state & GDK_BUTTON1_MASK) || ev->button == 1)
	buttons |= MOUSE_EVENT_LBUTTON;
    if ((state & GDK_BUTTON3_MASK) || ev->button == 3)
	buttons |= MOUSE_EVENT_RBUTTON;
    if ((state & GDK_BUTTON2_MASK) || ev->button == 2)
	buttons |= MOUSE_EVENT_MBUTTON;
    /* XXX: test wheel */
    dz = 0;
    if ((state & GDK_BUTTON4_MASK) || ev->button == 4)
	dz--;
    if ((state & GDK_BUTTON5_MASK) || ev->button == 5)
	dz++;
    kbd_mouse_event(dx, dy, dz, buttons);

    }
    else
    {

    if (ev->button == 1 && ev->type == GDK_BUTTON_PRESS)
    {
	/* start grabbing all events */
	gtk2_grab_start();
    }

    }
    return TRUE;
}

static gboolean gtk2_send_mouse_move(GtkWidget *wid, GdkEventMotion *ev)
{
    int x, y, dx, dy, dz, state, buttons;
    if (gui_grab)
    {

    if (ev->is_hint)
    {
	gdk_window_get_pointer(ev->window, &x, &y, (GdkModifierType*)&state);
    }
    else
    {
	x = ev->x;
	y = ev->y;
	state = ev->state;
    }
    dx = x - ox;
    dy = y - oy;
    if ((dx == 0) && (dy == 0)) return TRUE; // prevent infinite looping - 2.6.X
    ox = x;
    oy = y;
    buttons = 0;
    if (state & GDK_BUTTON1_MASK)
	buttons |= MOUSE_EVENT_LBUTTON;
    if (state & GDK_BUTTON3_MASK)
	buttons |= MOUSE_EVENT_RBUTTON;
    if (state & GDK_BUTTON2_MASK)
	buttons |= MOUSE_EVENT_MBUTTON;
    /* XXX: test wheel */
    dz = 0;
    if (state & GDK_BUTTON4_MASK)
	dz--;
    if (state & GDK_BUTTON5_MASK)
	dz++;

    /* wrap the x,y coordinates back onto the window */
    if (ev->x <= (cw/4))
        x = ((3*cw/4)-1);
    if (ev->y <= (ch/4))
        y = ((3*ch/4)-1);
    if (ev->x >= (3*cw/4))
        x = (cw/4)+1;
    if (ev->y >= (3*ch/4))
        y = (ch/4)+1;

    /* make internal mouse move invisible */
    ox = x;
    oy = y;

    gdk_window_set_pointer(screen->window, (gint)x, (gint)y);

    kbd_mouse_event(dx, dy, dz, buttons);

    }
    return TRUE;
}

static void toggle_full_screen(DisplayState *ds)
{
    gui_fullscreen = !gui_fullscreen;
    gtk2_resize(ds, image->width, image->height);
    if (gui_fullscreen) {
	gui_saved_grab = gui_grab;
	gtk2_grab_start();
        gtk_window_get_position(GTK_WINDOW(screen), &cx, &cy);
	/* ignore window manager decorations when in fullscreen mode */
	gtk_window_set_gravity(GTK_WINDOW(screen), GDK_GRAVITY_STATIC);
	gtk_window_move(GTK_WINDOW(screen), 0, 0);
        fullscreen_switch(cx, cy, ds->width, ds->height);
    } else {
        fullscreen_reset();
	gtk_window_set_gravity(GTK_WINDOW(screen), GDK_GRAVITY_NORTH_WEST);
	gtk_window_move(GTK_WINDOW(screen), cx, cy);
	if (!gui_saved_grab)
	    gtk2_grab_end();
    }
    vga_invalidate_display();
    vga_update_display();
}

static gboolean gtk2_key_press(GtkWidget *wid, GdkEventKey *ev, DisplayState *ds)
{
	int mod_state;
	    if (ev->type == GDK_KEY_PRESS) {
		mod_state = (gtk2_GetModState(ev) & (int)gui_grab_code) == (int)gui_grab_code;
		gui_key_modifier_pressed = mod_state;
		if (gui_key_modifier_pressed) {
		    int keycode;
		    keycode = gtk2_keyevent_to_keycode(ev);
		    switch(keycode) {
		    case 0x21: /* 'f' key on US keyboard */
			toggle_full_screen(ds);
			gui_keysym = 1;
			break;
		    case 0x02 ... 0x0a: /* '1' to '9' keys */ 
			console_select(keycode - 0x02);
			if (is_active_console(vga_console)) {
			    /* tell the vga console to redisplay itself */
			    vga_invalidate_display();
			} else {
			    /* display grab if going to a text console */
			    if (gui_grab)
				gtk2_grab_end();
			}
			gui_keysym = 1;
			break;
		    default:
			break;
		    }
		} else if (!is_active_console(vga_console)) {
		    int keysym;
		    keysym = 0;
		    if (ev->state & GDK_CONTROL_MASK) {
			switch(ev->keyval) {
			case GDK_Up: keysym = QEMU_KEY_CTRL_UP; break;
			case GDK_Down: keysym = QEMU_KEY_CTRL_DOWN; break;
			case GDK_Left: keysym = QEMU_KEY_CTRL_LEFT; break;
			case GDK_Right: keysym = QEMU_KEY_CTRL_RIGHT; break;
			case GDK_Home: keysym = QEMU_KEY_CTRL_HOME; break;
			case GDK_End: keysym = QEMU_KEY_CTRL_END; break;
			case GDK_Page_Up: keysym = QEMU_KEY_CTRL_PAGEUP; break;
			case GDK_Page_Down: keysym = QEMU_KEY_CTRL_PAGEDOWN; break;
			default: break;
			}
		    } else {
			switch(ev->keyval) {
			case GDK_Up: keysym = QEMU_KEY_UP; break;
			case GDK_Down: keysym = QEMU_KEY_DOWN; break;
			case GDK_Left: keysym = QEMU_KEY_LEFT; break;
			case GDK_Right: keysym = QEMU_KEY_RIGHT; break;
			case GDK_Home: keysym = QEMU_KEY_HOME; break;
			case GDK_End: keysym = QEMU_KEY_END; break;
			case GDK_Page_Up: keysym = QEMU_KEY_PAGEUP; break;
			case GDK_Page_Down: keysym = QEMU_KEY_PAGEDOWN; break;
			case GDK_BackSpace: keysym = QEMU_KEY_BACKSPACE; break;
			case GDK_Delete: keysym = QEMU_KEY_DELETE; break;
			default: break;
			}
		    }
		    if (keysym) {
			kbd_put_keysym(keysym);
		    } /*else if (ev->key.keysym.unicode != 0) {
			kbd_put_keysym(ev->key.keysym.unicode);
		    }*/
		}
	    } else if (ev->type == GDK_KEY_RELEASE) {
		mod_state = (gtk2_GetModState(ev) & gui_grab_code);
		if (!mod_state) {
		    if (gui_key_modifier_pressed) {
			if (gui_keysym == 0) {
			    /* exit/enter grab if pressing Ctrl-Alt */
			    if (!gui_grab)
				gtk2_grab_start();
			    else
				gtk2_grab_end();
			    /* SDL does not send back all the
			       modifiers key, so we must correct it */
			    reset_keys();
			    return TRUE;
			}
			gui_key_modifier_pressed = 0;
			gui_keysym = 0;
		    }
		}
	    }
	    if (is_active_console(vga_console)) 
		gtk2_process_key(ev);
	return TRUE;
}

static void gtk2_refresh(DisplayState *ds)
{
    if (last_vm_running != vm_running) {
	last_vm_running = vm_running;
	gtk2_update_caption();
    }
    if (ds->data != image->mem)
    {
	ds->data = image->mem;
    }

    if (is_active_console(vga_console))                                         
	vga_update_display();                                                   
    while (gtk_events_pending())
	gtk_main_iteration();
}

static void gtk2_cleanup(void) 
{
    gtk_main_quit();
    fullscreen_cleanup();
}

static gboolean gtk2_deletewin(void)
{
    /* signal qemu that its time to shut itself off - this is the place that we hook to trap attempts to close the main qemu window */
    qemu_system_shutdown_request();
    return FALSE;
    return TRUE; /* dont close the window right away! give qemu time to think */
}

static void gtk2_destroy(void)
{
    /* ideally we would call a hook here so qemu could clean itself up */
    gtk2_cleanup();
}

void gtk2_display_init(DisplayState *ds, int full_screen)
{
    int events;

#if defined(__APPLE__)
    /* always use generic keymaps */
    if (!keyboard_layout)
	keyboard_layout = "en-us";
#endif
    if(keyboard_layout) {
	kbd_layout = init_keyboard_layout(keyboard_layout);
	if (!kbd_layout)
	    exit(1);
    }

    if (!gtk_init_check (0,NULL))
    {
	fprintf(stderr, "Could not load GTK\n");
	exit(0);
    }
    fullscreen_init();

/* note: adding GDK_DRAG_* and GDK_DROP_* would provide a mechanism for supporting drag and drop between host and guest */
    events = GDK_EXPOSURE_MASK | GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK | GDK_FOCUS_CHANGE_MASK | GDK_SCROLL_MASK | GDK_STRUCTURE_MASK;

    screen = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_widget_set_events(screen, events);
    gtk_window_set_default_size(GTK_WINDOW(screen), 720, 400);
    gtk_widget_set_size_request(screen, 720, 400);

    g_signal_connect(G_OBJECT(screen), "delete_event", G_CALLBACK(gtk2_deletewin), NULL);
    g_signal_connect(G_OBJECT(screen), "destroy", G_CALLBACK(gtk2_destroy), NULL);
    gtk_container_set_border_width(GTK_CONTAINER(screen), 10);

    gtk_signal_connect(GTK_OBJECT(screen), "expose_event", (GtkSignalFunc) gtk2_expose, NULL);
    gtk_signal_connect(GTK_OBJECT(screen), "motion_notify_event", (GtkSignalFunc) gtk2_send_mouse_move, NULL);
    gtk_signal_connect(GTK_OBJECT(screen), "button_press_event", (GtkSignalFunc) gtk2_send_mouse_button, NULL);
    gtk_signal_connect(GTK_OBJECT(screen), "button_release_event", (GtkSignalFunc) gtk2_send_mouse_button, NULL);
    gtk_signal_connect(GTK_OBJECT(screen), "scroll_event", (GtkSignalFunc) gtk2_send_mouse_scroll, NULL);
    gtk_signal_connect(GTK_OBJECT(screen), "key_press_event", (GtkSignalFunc) gtk2_key_press, ds);
    gtk_signal_connect(GTK_OBJECT(screen), "key_release_event", (GtkSignalFunc) gtk2_key_press, ds);

    ds->dpy_update = gtk2_update;
    ds->dpy_resize = gtk2_resize;
    ds->dpy_refresh = gtk2_refresh;

    gchar nullpixdata[1] = { 0 };
    GdkColor nullcolor = { 0, 0, 0, 0 };
    GdkPixmap *invis = gdk_bitmap_create_from_data(screen->window, nullpixdata, 1, 1);
    invisible_cursor = gdk_cursor_new_from_pixmap(invis, invis, &nullcolor, &nullcolor, 0, 0);

    gtk2_resize(ds, 720, 400);
    gtk2_update_caption();
    gui_grab = 0;

    gtk_window_set_policy(GTK_WINDOW(screen), FALSE, FALSE, FALSE);
    gtk_widget_show(screen);
    if (full_screen) {
	gui_fullscreen = 1;
	gui_fullscreen_initial_grab = 1;
	gtk2_grab_start();
    }
}

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [Qemu-devel] quick gtk2.c update
  2005-06-19 19:09 [Qemu-devel] quick gtk2.c update Jim C. Brown
@ 2005-06-19 22:25 ` Sebastien Bechet
  2005-06-20  0:01   ` Jim C. Brown
  2005-06-19 22:57 ` jeebs
  1 sibling, 1 reply; 59+ messages in thread
From: Sebastien Bechet @ 2005-06-19 22:25 UTC (permalink / raw)
  To: qemu-devel

Hello Jim,

I have no time to test your patch :-( I think I can do it in august...
Nevertheless, now gtk driver works (i suppose :-p), i have some old
glade files on my hard disk to add Qemu-GTK GUI.

Do you want I send it on the ML ? Maybe it can give you some idea if you
have time to continue ? I tried to be as simple as firefox can be...

Le dimanche 19 juin 2005 à 15:09 -0400, Jim C. Brown a écrit :
> Minor changes to gtk2_send_mouse_move() for GTK 2.6
[...]

-- 
Sebastien Bechet <s.bechet@av7.net>
seb.av7.net

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [Qemu-devel] quick gtk2.c update
  2005-06-19 19:09 [Qemu-devel] quick gtk2.c update Jim C. Brown
  2005-06-19 22:25 ` Sebastien Bechet
@ 2005-06-19 22:57 ` jeebs
  2005-06-19 23:53   ` Jim C. Brown
  1 sibling, 1 reply; 59+ messages in thread
From: jeebs @ 2005-06-19 22:57 UTC (permalink / raw)
  To: qemu-devel

From: "Jim C. Brown"

> Minor changes to gtk2_send_mouse_move() for GTK 2.6

Under Windows with MingW & MSYS, I'm still getting the same compiler error 
that I reported to you before.

Along with an assortment of warnings in the GDK stuff.  Plus the usual qemu 
warnings.

I'm still using the same setup as before, except right after I sent you the 
report back then, I upgraded to the "bleeding edge" gtk stuff and tried it 
again.

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [Qemu-devel] quick gtk2.c update
  2005-06-19 22:57 ` jeebs
@ 2005-06-19 23:53   ` Jim C. Brown
       [not found]     ` <002c01c57535$60064fb0$334d21d1@organiza3bfb0e>
  0 siblings, 1 reply; 59+ messages in thread
From: Jim C. Brown @ 2005-06-19 23:53 UTC (permalink / raw)
  To: qemu-devel

[-- Attachment #1: Type: text/plain, Size: 1163 bytes --]

On Sun, Jun 19, 2005 at 05:57:46PM -0500, jeebs@yango.us wrote:
> From: "Jim C. Brown"
> 
> > Minor changes to gtk2_send_mouse_move() for GTK 2.6
> 
> Under Windows with MingW & MSYS, I'm still getting the same compiler error 
> that I reported to you before.
> 
> Along with an assortment of warnings in the GDK stuff.  Plus the usual qemu 
> warnings.
> 

I think you should be able to ignore the GDK warnings.

> I'm still using the same setup as before, except right after I sent you the 
> report back then, I upgraded to the "bleeding edge" gtk stuff and tried it 
> again.
> 

You are using the modified gdk_set_window_pointer.c right? The one that includes
gdk/gtkwin32.h directly? (I didn't get a response from you when I send the
updated version.)

If that one doesn't work, try this one. (The only different is that I include
<gdk/win32/gdkwin32.h> instead of <gdk/gdkwin32.h>)

I also attach a gdkprivate-win32.h in case yours is missing (google seems to
suggest that windows version of GTK is missing the gdkprivate-win32.h file).
This is from gtk-2.4.4

-- 
Infinite complexity begets infinite beauty.
Infinite precision begets infinite perfection.

[-- Attachment #2: gdk_set_window_pointer.c --]
[-- Type: text/plain, Size: 1315 bytes --]

/* TODO: figure out how to handle linux framebuffer case - need to call the gdk-fb specific handle_mouse_movement() function in gdkmouse-fb.c ... that gets ugly fast .. */

#ifndef _WIN32

#include <gdk/gdk.h>
#include <gdk/gdkx.h>
#include <X11/X.h>

 GdkWindow*
gdk_window_set_pointer (GdkWindow       *window,
                       gint            x,
                       gint            y)
{
  GdkWindow *return_val;

  return_val = NULL;
  XWarpPointer (GDK_WINDOW_XDISPLAY(window), None, GDK_WINDOW_XID(window), 0, 0, 0, 0, x, y);

  return return_val;
}

#else

/* untested code based on MSDN library code... URL is :

                  http://msdn.microsoft.com/library/default.asp?url=/library/
                  en-us/winui/winui/windowsuserinterface/resources/cursors/
                  usingcursors.asp         

Someone who codes on Windows want to tell me how to actually make this work??

*/

#include <gdk/gdk.h>
#include <gdk/win32/gdkwin32.h>
#include <windows.h>

 GdkWindow*
gdk_window_set_pointer (GdkWindow       *window,
                       gint            x,
                       gint            y)
{
	GdkWindow *return_val;
	POINT pt;
	pt.x = x;
	pt.y = y;
	ClientToScreen(GDK_WINDOW_HWND(window), &pt);
	SetCursorPos(pt.x, pt.y);
	return_val = NULL;
	return return_val;
}

#endif


[-- Attachment #3: gdkprivate-win32.h --]
[-- Type: text/plain, Size: 14568 bytes --]

/* GDK - The GIMP Drawing Kit
 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

/*
 * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
 * file for a list of people on the GTK+ Team.  See the ChangeLog
 * files for a list of changes.  These files are distributed with
 * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
 */

#ifndef __GDK_PRIVATE_WIN32_H__
#define __GDK_PRIVATE_WIN32_H__

#include <gdk/gdkprivate.h>
#include <gdk/win32/gdkwindow-win32.h>
#include <gdk/win32/gdkpixmap-win32.h>

#include "gdkinternals.h"

#include <config.h>

/* Make up for some minor w32api header lossage */

/* PS_JOIN_MASK is missing */
#ifndef PS_JOIN_MASK
#define PS_JOIN_MASK (PS_JOIN_BEVEL|PS_JOIN_MITER|PS_JOIN_ROUND)
#endif

/* CLR_INVALID is missing */
#ifndef CLR_INVALID
#define CLR_INVALID CLR_NONE
#endif

/* Some charsets are missing from MSVC 5 headers */
#ifndef JOHAB_CHARSET
#define JOHAB_CHARSET 130
#endif
#ifndef VIETNAMESE_CHARSET
#define VIETNAMESE_CHARSET 163
#endif

#ifndef FS_VIETNAMESE
#define FS_VIETNAMESE 0x100
#endif

/* Some virtual keycodes are missing */
#ifndef VK_OEM_PLUS
#define VK_OEM_PLUS 0xBB
#endif

#ifndef VK_OEM_COMMA
#define VK_OEM_COMMA 0xBC
#endif

#ifndef VK_OEM_MINUS
#define VK_OEM_MINUS 0xBD
#endif

#ifndef VK_OEM_PERIOD
#define VK_OEM_PERIOD 0xBE
#endif

#ifndef VK_OEM_1
#define VK_OEM_1 0xBA
#endif
#ifndef VK_OEM_2
#define VK_OEM_2 0xBF
#endif
#ifndef VK_OEM_3
#define VK_OEM_3 0xC0
#endif
#ifndef VK_OEM_4
#define VK_OEM_4 0xDB
#endif
#ifndef VK_OEM_5
#define VK_OEM_5 0xDC
#endif
#ifndef VK_OEM_6
#define VK_OEM_6 0xDD
#endif
#ifndef VK_OEM_7
#define VK_OEM_7 0xDE
#endif
#ifndef VK_OEM_8
#define VK_OEM_8 0xDF
#endif

/* Missing messages */
#ifndef WM_SYNCPAINT
#define WM_SYNCPAINT 0x88
#endif
#ifndef WM_MOUSEWHEEL
#define WM_MOUSEWHEEL 0X20A
#endif
#ifndef WM_GETOBJECT
#define WM_GETOBJECT 0x3D
#endif
#ifndef WM_NCXBUTTONDOWN
#define WM_NCXBUTTONDOWN 0xAB
#endif
#ifndef WM_NCXBUTTONUP
#define WM_NCXBUTTONUP 0xAC
#endif
#ifndef WM_NCXBUTTONDBLCLK
#define WM_NCXBUTTONDBLCLK 0xAD
#endif
#ifndef WM_MENURBUTTONUP
#define WM_MENURBUTTONUP 0x122
#endif
#ifndef WM_MENUDRAG
#define WM_MENUDRAG 0x123
#endif
#ifndef WM_MENUGETOBJECT
#define WM_MENUGETOBJECT 0x124
#endif
#ifndef WM_UNINITMENUPOPUP
#define WM_UNINITMENUPOPUP 0x125
#endif
#ifndef WM_MENUCOMMAND
#define WM_MENUCOMMAND 0x126
#endif
#ifndef WM_CHANGEUISTATE
#define WM_CHANGEUISTATE 0x127
#endif
#ifndef WM_UPDATEUISTATE
#define WM_UPDATEUISTATE 0x128
#endif
#ifndef WM_QUERYUISTATE
#define WM_QUERYUISTATE 0x129
#endif
#ifndef WM_XBUTTONDOWN
#define WM_XBUTTONDOWN 0x20B
#endif
#ifndef WM_XBUTTONUP
#define WM_XBUTTONUP 0x20C
#endif
#ifndef WM_XBUTTONDBLCLK
#define WM_XBUTTONDBLCLK 0x20D
#endif
#ifndef WM_IME_REQUEST
#define WM_IME_REQUEST 0x288
#endif
#ifndef WM_MOUSEHOVER
#define WM_MOUSEHOVER 0x2A1
#endif
#ifndef WM_MOUSELEAVE
#define WM_MOUSELEAVE 0x2A3
#endif
#ifndef WM_NCMOUSEHOVER
#define WM_NCMOUSEHOVER 0x2A0
#endif
#ifndef WM_NCMOUSELEAVE
#define WM_NCMOUSELEAVE 0x2A2
#endif
#ifndef WM_APPCOMMAND
#define WM_APPCOMMAND 0x319
#endif
#ifndef WM_HANDHELDFIRST
#define WM_HANDHELDFIRST 0x358
#endif
#ifndef WM_HANDHELDLAST
#define WM_HANDHELDLAST 0x35F
#endif
#ifndef WM_AFXFIRST
#define WM_AFXFIRST 0x360
#endif
#ifndef WM_AFXLAST
#define WM_AFXLAST 0x37F
#endif

#ifndef CopyCursor
#define CopyCursor(pcur) ((HCURSOR)CopyIcon((HICON)(pcur)))
#endif

/* Define some combinations of GdkDebugFlags */
#define GDK_DEBUG_EVENTS_OR_COLORMAP (GDK_DEBUG_EVENTS|GDK_DEBUG_COLORMAP)
#define GDK_DEBUG_EVENTS_OR_INPUT (GDK_DEBUG_EVENTS|GDK_DEBUG_INPUT)
#define GDK_DEBUG_PIXMAP_OR_COLORMAP (GDK_DEBUG_PIXMAP|GDK_DEBUG_COLORMAP)
#define GDK_DEBUG_MISC_OR_COLORMAP (GDK_DEBUG_MISC|GDK_DEBUG_COLORMAP)

#define GDK_TYPE_GC_WIN32              (_gdk_gc_win32_get_type ())
#define GDK_GC_WIN32(object)           (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_GC_WIN32, GdkGCWin32))
#define GDK_GC_WIN32_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_GC_WIN32, GdkGCWin32Class))
#define GDK_IS_GC_WIN32(object)        (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_GC_WIN32))
#define GDK_IS_GC_WIN32_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_GC_WIN32))
#define GDK_GC_WIN32_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_GC_WIN32, GdkGCWin32Class))

typedef struct _GdkColormapPrivateWin32 GdkColormapPrivateWin32;
typedef struct _GdkCursorPrivate        GdkCursorPrivate;
typedef struct _GdkWin32SingleFont      GdkWin32SingleFont;
typedef struct _GdkFontPrivateWin32     GdkFontPrivateWin32;
typedef struct _GdkGCWin32		GdkGCWin32;
typedef struct _GdkGCWin32Class		GdkGCWin32Class;

struct _GdkCursorPrivate
{
  GdkCursor cursor;
  HCURSOR hcursor;
};

struct _GdkWin32SingleFont
{
  HFONT hfont;
  UINT charset;
  UINT codepage;
  FONTSIGNATURE fs;
};

struct _GdkFontPrivateWin32
{
  GdkFontPrivate base;
  GSList *fonts;		/* List of GdkWin32SingleFonts */
  GSList *names;
};

struct _GdkVisualClass
{
  GObjectClass parent_class;
};

typedef enum {
  GDK_WIN32_PE_STATIC,
  GDK_WIN32_PE_AVAILABLE,
  GDK_WIN32_PE_INUSE
} GdkWin32PalEntryState;

struct _GdkColormapPrivateWin32
{
  HPALETTE hpal;
  gint current_size;		/* Current size of hpal */
  GdkWin32PalEntryState *use;
  gint private_val;

  GHashTable *hash;
  GdkColorInfo *info;
};

struct _GdkGCWin32
{
  GdkGC parent_instance;

  /* A Windows Device Context (DC) is not equivalent to an X11
   * GC. We can use a DC only in the window for which it was
   * allocated, or (in the case of a memory DC) with the bitmap that
   * has been selected into it. Thus, we have to release and
   * reallocate a DC each time the GdkGC is used to paint into a new
   * window or pixmap. We thus keep all the necessary values in the
   * GdkGCWin32 object.
   */

  HRGN hcliprgn;

  GdkGCValuesMask values_mask;

  gulong foreground;		/* Pixel values from GdkColor, */
  gulong background;		/* not Win32 COLORREFs */

  GdkFont *font;
  gint rop2;
  GdkFill fill_style;
  GdkPixmap *tile;
  GdkPixmap *stipple;
  GdkSubwindowMode subwindow_mode;
  gint graphics_exposures;
  gint pen_width;
  DWORD pen_style;
  DWORD *pen_dashes;		/* use for PS_USERSTYLE or step-by-step rendering */
  gint pen_num_dashes;

  /* Following fields are valid while the GC exists as a Windows DC */
  HDC hdc;
  int saved_dc;

  HANDLE hwnd;			/* For which window, or what bitmap is
				 * selected into it
				 */
  HPALETTE holdpal;
};

struct _GdkGCWin32Class
{
  GdkGCClass parent_class;
};

GType _gdk_gc_win32_get_type (void);

gulong _gdk_win32_get_next_tick (gulong suggested_tick);

void _gdk_window_init_position     (GdkWindow *window);
void _gdk_window_move_resize_child (GdkWindow *window,
				    gint       x,
				    gint       y,
				    gint       width,
				    gint       height);
void _gdk_window_process_expose    (GdkWindow *window,
                                    GdkRegion *invalidate_region);

void _gdk_win32_selection_init (void);
void _gdk_win32_dnd_exit (void);

void	 gdk_win32_handle_table_insert  (HANDLE   *handle,
					 gpointer data);
void	 gdk_win32_handle_table_remove  (HANDLE handle);

GdkGC    *_gdk_win32_gc_new             (GdkDrawable        *drawable,
					 GdkGCValues        *values,
					 GdkGCValuesMask     values_mask);

GdkImage *_gdk_win32_get_image 		(GdkDrawable *drawable,
					 gint         x,
					 gint         y,
					 gint         width,
					 gint         height);

GdkImage *_gdk_win32_copy_to_image      (GdkDrawable *drawable,
					 GdkImage    *image,
					 gint         src_x,
					 gint         src_y,
					 gint         dest_x,
					 gint         dest_y,
					 gint         width,
					 gint         height);

void      _gdk_win32_blit               (gboolean              use_fg_bg,
					 GdkDrawableImplWin32 *drawable,
					 GdkGC       	       *gc,
					 GdkDrawable   	       *src,
					 gint        	    	xsrc,
					 gint        	    	ysrc,
					 gint        	    	xdest,
					 gint        	    	ydest,
					 gint        	    	width,
					 gint        	    	height);

COLORREF  _gdk_win32_colormap_color     (GdkColormap *colormap,
				         gulong       pixel);

HRGN	  _gdk_win32_bitmap_to_hrgn     (GdkPixmap   *bitmap);

HRGN	  _gdk_win32_gdkregion_to_hrgn  (GdkRegion   *region,
					 gint         x_origin,
					 gint         y_origin);

void	_gdk_win32_adjust_client_rect   (GdkWindow *window,
					 RECT      *RECT);

void	_gdk_win32_get_adjusted_client_rect (GdkWindow *window,
					     RECT      *RECT);

void    _gdk_selection_property_delete (GdkWindow *);

void    _gdk_dropfiles_store (gchar *data);

void    _gdk_wchar_text_handle    (GdkFont       *font,
				   const wchar_t *wcstr,
				   int            wclen,
				   void         (*handler)(GdkWin32SingleFont *,
							   const wchar_t *,
							   int,
							   void *),
				   void          *arg);

#ifdef G_ENABLE_DEBUG
gchar *_gdk_win32_color_to_string      (const GdkColor *color);
void   _gdk_win32_print_paletteentries (const PALETTEENTRY *pep,
					const int           nentries);
void   _gdk_win32_print_system_palette (void);
void   _gdk_win32_print_hpalette       (HPALETTE     hpal);
void   _gdk_win32_print_dc             (HDC          hdc);

gchar *_gdk_win32_cap_style_to_string  (GdkCapStyle  cap_style);
gchar *_gdk_win32_fill_style_to_string (GdkFill      fill);
gchar *_gdk_win32_function_to_string   (GdkFunction  function);
gchar *_gdk_win32_join_style_to_string (GdkJoinStyle join_style);
gchar *_gdk_win32_line_style_to_string (GdkLineStyle line_style);
gchar *_gdk_win32_gcvalues_mask_to_string (GdkGCValuesMask mask);
gchar *_gdk_win32_window_state_to_string (GdkWindowState state);
gchar *_gdk_win32_drawable_description (GdkDrawable *d);

gchar *_gdk_win32_rop2_to_string       (int          rop2);
gchar *_gdk_win32_lbstyle_to_string    (UINT         brush_style);
gchar *_gdk_win32_pstype_to_string     (DWORD        pen_style);
gchar *_gdk_win32_psstyle_to_string    (DWORD        pen_style);
gchar *_gdk_win32_psendcap_to_string   (DWORD        pen_style);
gchar *_gdk_win32_psjoin_to_string     (DWORD        pen_style);
gchar *_gdk_win32_message_to_string    (UINT         msg);
gchar *_gdk_win32_rect_to_string       (const RECT  *rect);

gchar *_gdk_win32_gdkrectangle_to_string (const GdkRectangle *rect);
gchar *_gdk_win32_gdkregion_to_string    (const GdkRegion    *box);

#endif

gchar  *_gdk_win32_last_error_string (void);
void    _gdk_win32_api_failed        (const gchar *where,
				     gint line,
				     const gchar *api);
void    _gdk_other_api_failed        (const gchar *where,
				     gint line,
				     const gchar *api);
void    _gdk_win32_gdi_failed        (const gchar *where,
				     gint line,
				     const gchar *api);

#if defined(__GNUC__) && (__GNUC__ < 3)
#define WIN32_API_FAILED(api) _gdk_win32_api_failed (__FILE__ ":" __PRETTY_FUNCTION__, __LINE__, api)
#define WIN32_GDI_FAILED(api) _gdk_win32_gdi_failed (__FILE__ ":" __PRETTY_FUNCTION__, __LINE__, api)
#define OTHER_API_FAILED(api) _gdk_other_api_failed (__FILE__ ":" __PRETTY_FUNCTION__, __LINE__, api)
#else
#define WIN32_API_FAILED(api) _gdk_win32_api_failed (__FILE__, __LINE__, api)
#define WIN32_GDI_FAILED(api) _gdk_win32_gdi_failed (__FILE__, __LINE__, api)
#define OTHER_API_FAILED(api) _gdk_other_api_failed (__FILE__, __LINE__, api)
#endif
 
/* These two macros call a GDI or other Win32 API and if the return
 * value is zero or NULL, print a warning message. The majority of GDI
 * calls return zero or NULL on failure. The value of the macros is nonzero
 * if the call succeeded, zero otherwise.
 */

#define GDI_CALL(api, arglist) (api arglist ? 1 : (WIN32_GDI_FAILED (#api), 0))
#define API_CALL(api, arglist) (api arglist ? 1 : (WIN32_API_FAILED (#api), 0))
 
extern LRESULT CALLBACK _gdk_win32_window_procedure (HWND, UINT, WPARAM, LPARAM);

extern HWND		 _gdk_root_window;
extern GdkWindow        *_gdk_parent_root;

extern GdkDisplay       *_gdk_display;
extern GdkScreen        *_gdk_screen;

extern gint		 _gdk_num_monitors;
extern GdkRectangle     *_gdk_monitors;

/* Offsets to add to Windows coordinates (which are relative to the
 * primary monitor's origin, and thus might be negative for monitors
 * to the left and/or above the primary monitor) to get GDK
 * coordinates, which should be non-negative on the whole screen.
 */
extern gint		 _gdk_offset_x, _gdk_offset_y;

extern HDC		 _gdk_display_hdc;
extern HINSTANCE	 _gdk_dll_hinstance;
extern HINSTANCE	 _gdk_app_hmodule;

/* These are thread specific, but GDK/win32 works OK only when invoked
 * from a single thread anyway.
 */
extern HKL		 _gdk_input_locale;
extern gboolean		 _gdk_input_locale_is_ime;
extern UINT		 _gdk_input_codepage;

extern guint		 _gdk_keymap_serial;
extern gboolean		 _gdk_keyboard_has_altgr;

/* Registered clipboard formats */
extern WORD		 _cf_rtf;
extern WORD		 _cf_utf8_string;

/* GdkAtoms: Targets */
extern GdkAtom           _utf8_string;
extern GdkAtom		 _compound_text;
extern GdkAtom		 _text_uri_list;
extern GdkAtom		 _targets;

/* DND selections */
extern GdkAtom           _local_dnd;
extern GdkAtom		 _gdk_win32_dropfiles;
extern GdkAtom		 _gdk_ole2_dnd;

extern GdkAtom		 _gdk_selection_property;

extern GdkAtom		 _wm_transient_for;

extern DWORD		 _windows_version;
#define IS_WIN_NT()      (_windows_version < 0x80000000)

/* Options */
extern gboolean		 _gdk_input_ignore_wintab;
extern gint		 _gdk_max_colors;

#define GDK_WIN32_COLORMAP_DATA(cmap) ((GdkColormapPrivateWin32 *) GDK_COLORMAP (cmap)->windowing_data)

/* Initialization */
void _gdk_windowing_window_init (void);
void _gdk_visual_init (void);
void _gdk_dnd_init    (void);
void _gdk_windowing_image_init  (void);
void _gdk_events_init (void);
void _gdk_input_init  (GdkDisplay *display);

#endif /* __GDK_PRIVATE_WIN32_H__ */

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [Qemu-devel] quick gtk2.c update
  2005-06-19 22:25 ` Sebastien Bechet
@ 2005-06-20  0:01   ` Jim C. Brown
  0 siblings, 0 replies; 59+ messages in thread
From: Jim C. Brown @ 2005-06-20  0:01 UTC (permalink / raw)
  To: qemu-devel

On Mon, Jun 20, 2005 at 12:25:54AM +0200, Sebastien Bechet wrote:
> Hello Jim,
> 
> I have no time to test your patch :-( I think I can do it in august...

I have to know how you got GdkPixbuf to work with your GTK patch.
I looked at using GdkPixbuf but it seems not flexible enough to support
the graphic requirements of most OSes... I wish to understand how you got
your version to show graphics images correctly. I did not think it was possible
unless GdkImage was used directly.

> Nevertheless, now gtk driver works (i suppose :-p),

Depends on how you define "works".

It is usable. Still a few oddities that need tending to.

> i have some old
> glade files on my hard disk to add Qemu-GTK GUI.
> 
> Do you want I send it on the ML ? Maybe it can give you some idea if you
> have time to continue ? I tried to be as simple as firefox can be...
> 

I am not very good with GUI designing.. but I would not mind taking a look.

-- 
Infinite complexity begets infinite beauty.
Infinite precision begets infinite perfection.

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [Qemu-devel] quick gtk2.c update
       [not found]     ` <002c01c57535$60064fb0$334d21d1@organiza3bfb0e>
@ 2005-06-20  1:59       ` Jim C. Brown
  2005-06-21  2:27         ` jeebs
  2005-06-21 10:32         ` Jernej Simončič
  0 siblings, 2 replies; 59+ messages in thread
From: Jim C. Brown @ 2005-06-20  1:59 UTC (permalink / raw)
  To: jeebs; +Cc: qemu-devel

On Sun, Jun 19, 2005 at 08:13:55PM -0500, jeebs@yango.us wrote:
> > If that one doesn't work, try this one. (The only different is that I 
> > include
> > <gdk/win32/gdkwin32.h> instead of <gdk/gdkwin32.h>)
> 
> > I also attach a gdkprivate-win32.h in case yours is missing (google seems 
> > to
> 
> I'm not getting any errors about that.  But maybe the build isn't getting 
> that far.  I'll go ahead and drop it into the qemu directory just in case.
> 

If you are not getting any errors about it, then you don't need it.

Dropping it into the qemu directory probably wouldn't help at all. Shouldn't
mess anything up, though.

> Okay... In gdk_set_window_pointer.c, you include
> #include <gdk/win32/gdkwin32.h>
> 
> For my mingw / msys enviornment, that should be
> #include <gdk/gdkwin32.h>
> 
> Fixing that, I do get a sucessful build.
> 

Ok. I've seen it done both ways so I wasn't sure which was correct for
current GTK-win32.

> However, it doesn't run.
> 
> Qemu, as usual, doesn't print out anything that could possibly be of any use 
> to somebody having trouble.
> 
> So, I dropped down to the command line and ran it again.
> 
> This time I got a number of Windows errors saying it couldn't find the 
> proper gtk etc. libraries.
> 
> So I copied about 6 meg of library files to my qemu test directory.
> 

Strange. I'm not too familiar with the Windows equivulent of LD_LIBRARY_PATH.

I did find a GTK Windows tutorial at http://wolfpack.twu.net/docs/gtkwin32/,
but that says to install the dlls to the System folder.

> This time it stopped complaining, but after a couple seconds, a Windows box 
> poped up saying an error occured and that it was shutting qemu down.
> 
> I don't have any further information to give you.  Sorry.
> 

I could make a modified gtk2.c which would printf() more debugging information.
One that would print out enough information to tell me exactly which part of the
code was causing the error and what the error was.

If you are willing to help me do the debugging, I'll email you the modified code
as well as detailed instructions and wait back for the results. This will have
a slightly higher time commitment though.

Thanks for helping me get this far.

-- 
Infinite complexity begets infinite beauty.
Infinite precision begets infinite perfection.

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [Qemu-devel] quick gtk2.c update
  2005-06-20  1:59       ` Jim C. Brown
@ 2005-06-21  2:27         ` jeebs
  2005-06-21  2:39           ` Jim C. Brown
  2005-06-21 10:39           ` Jernej Simončič
  2005-06-21 10:32         ` Jernej Simončič
  1 sibling, 2 replies; 59+ messages in thread
From: jeebs @ 2005-06-21  2:27 UTC (permalink / raw)
  To: Jim C. Brown, qemu-devel

"Jim C. Brown"

Sorry I hadn't got back to you sooner, but I was busy....  Some good news... 
Keep reading.

>> So I copied about 6 meg of library files to my qemu test directory.
>
> Strange. I'm not too familiar with the Windows equivulent of 
> LD_LIBRARY_PATH.

MingW's MSYS is a seperate, isolated linux style environment.

My qemu directory is outside of that, in normal Windows XP area.

So it wouldn't know about those libraries unless they all get copied to the 
same directory as qemu.

> I did find a GTK Windows tutorial at 
> http://wolfpack.twu.net/docs/gtkwin32/,
> but that says to install the dlls to the System folder.

I'm an old windows user.... Any thing that says it's okay to drop random 
libraries into the system folder is something that I don't trust!

I'd rather keep them in the qemu directory.  Just like I do with sdl.dll


>> This time it stopped complaining, but after a couple seconds, a Windows 
>> box
>> poped up saying an error occured and that it was shutting qemu down.
>>
>> I don't have any further information to give you.  Sorry.

Good news...

Tonight I decided to test my Mingw/MSys environment.  I built the regular 
SDL version that I've done several times before.

It too failed.

There's not much telling what is causing it to fail.  Qemu seems rather 
sensitive to the slightest change in build environment.

Anyway, the last time I built it succesfully, I make an archive copy of my 
whole msys directory.  Which includes the compiler, and everything.

So I went back to it.  Rebuilt qemu just to make sure.  It worked.

I then copied the directory with your gtk version of qemu over to this new 
version of msys.

After a few problems getting the gtk stuff reinstalled, I rebuilt your gtk 
version.

This time, it's running!  (At least I *assume* it's running.  Everything 
looks identical to the sdl version, so I don't really have any way to know 
for sure.  In other words, there's a regular Windows title bar with nothing 
else.)

I haven't done any real testing of it yet, but I thought you'd at least want 
to know that it can be built under Mingw/MSys now.

So far, all I've really done is booted Win 3.11 and Win95.  Opened a few 
guest windows.  Moved the qemu window around a bit, and shut them down.

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [Qemu-devel] quick gtk2.c update
  2005-06-21  2:27         ` jeebs
@ 2005-06-21  2:39           ` Jim C. Brown
  2005-06-21  2:58             ` jeebs
  2005-06-21 10:39           ` Jernej Simončič
  1 sibling, 1 reply; 59+ messages in thread
From: Jim C. Brown @ 2005-06-21  2:39 UTC (permalink / raw)
  To: jeebs; +Cc: qemu-devel

On Mon, Jun 20, 2005 at 09:27:04PM -0500, jeebs@yango.us wrote:
> Good news...
> 
> Tonight I decided to test my Mingw/MSys environment.  I built the regular 
> SDL version that I've done several times before.
> 
> It too failed.
> 
> There's not much telling what is causing it to fail.  Qemu seems rather 
> sensitive to the slightest change in build environment.
> 

Not the most reliable development environment.

> This time, it's running!  (At least I *assume* it's running.  Everything 
> looks identical to the sdl version, so I don't really have any way to know 
> for sure.  In other words, there's a regular Windows title bar with nothing 
> else.)
> 

Well, remember to pass the "-use-gtk" option to qemu. By default qemu will
build with both sdl and gtk support, and if it has both, it will use the sdl
support unless told to use gtk.

Quick way to verify if its using gtk or not - try to go into fullscreen mode.
If it actually does go into fullscreen mode, its using SDL .. if the window just
moves around, its using GTK.

> I haven't done any real testing of it yet, but I thought you'd at least want 
> to know that it can be built under Mingw/MSys now.
> 

Yes, I am very pleased to hear this.

> So far, all I've really done is booted Win 3.11 and Win95.  Opened a few 
> guest windows.  Moved the qemu window around a bit, and shut them down.

Try resizing. The SDL window can be resized (at least under X11) but the GTK
window can't.

-- 
Infinite complexity begets infinite beauty.
Infinite precision begets infinite perfection.

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [Qemu-devel] quick gtk2.c update
  2005-06-21  2:39           ` Jim C. Brown
@ 2005-06-21  2:58             ` jeebs
  2005-06-21  4:28               ` Jim C. Brown
  2005-06-21 10:42               ` [Qemu-devel] quick gtk2.c update Jernej Simončič
  0 siblings, 2 replies; 59+ messages in thread
From: jeebs @ 2005-06-21  2:58 UTC (permalink / raw)
  To: Jim C. Brown; +Cc: qemu-devel

"Jim C. Brown"

>> There's not much telling what is causing it to fail.  Qemu seems rather
>> sensitive to the slightest change in build environment.
>
> Not the most reliable development environment.

No, it's not...

I think some of it is inherent in the GCC stuff.  Others, just the general 
build environment.

I've tried compiling some other gnu stuff under mingw, with varying success. 
(Meaning much of it didn't build, aborted, gave stack dumps, etc. etc.)

>> This time, it's running!  (At least I *assume* it's running.  Everything
>
> Well, remember to pass the "-use-gtk" option to qemu. By default qemu will
> build with both sdl and gtk support, and if it has both, it will use the 
> sdl
> support unless told to use gtk.

Okay, I didn't know that.  (Or I forgot about it.)  That means I was running 
SDL.

(That also means that even if it's ends up running in SDL mode, it still 
wants all those GTK libraries available.  If it isn't using GTK, then it 
shouldn't need them.)

Using that option now, I'm getting an error when I try to run qemu.

***
Incompatable build!  The code using GTK+ thinks GtkBox is of different size 
than it actually is in this build of GTK+.

On Windows, this probably means that you have compiled your code with gcc 
without the -fnative-struct (or -mms-bitfileds) switch, or that you are 
using an unsupported compiler.
***

No idea what it really means.  Other than what it actually says.

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [Qemu-devel] quick gtk2.c update
  2005-06-21  2:58             ` jeebs
@ 2005-06-21  4:28               ` Jim C. Brown
  2005-06-21 10:45                 ` Jernej Simončič
  2005-06-21 16:27                 ` jeebs
  2005-06-21 10:42               ` [Qemu-devel] quick gtk2.c update Jernej Simončič
  1 sibling, 2 replies; 59+ messages in thread
From: Jim C. Brown @ 2005-06-21  4:28 UTC (permalink / raw)
  To: qemu-devel

On Mon, Jun 20, 2005 at 09:58:06PM -0500, jeebs@yango.us wrote:
> Okay, I didn't know that.  (Or I forgot about it.)  That means I was running 
> SDL.
> 
> (That also means that even if it's ends up running in SDL mode, it still 
> wants all those GTK libraries available.  If it isn't using GTK, then it 
> shouldn't need them.)
> 

Perhaps you are right (it is less of an issue in Linux since most workstations
have GTK libraries installed anways ... if you have SDL then you probably have
GTK as well). However, this approach would a) require introducing dlopen()/
LoadLibrary() into qemu in the right places (something I really hesitate to do)
or b) require a link against glib for all cases (not just the GTK case) and
use glib code to handle that (something I am even more relutant to do).

> Using that option now, I'm getting an error when I try to run qemu.
> 
> ***
> Incompatable build!  The code using GTK+ thinks GtkBox is of different size 
> than it actually is in this build of GTK+.
> 
> On Windows, this probably means that you have compiled your code with gcc 
> without the -fnative-struct (or -mms-bitfileds) switch, or that you are 
> using an unsupported compiler.
> ***
> 
> No idea what it really means.  Other than what it actually says.
> 

This is a particularly perplexing error, considering that a) this error should
only show up if you 1) use a MSVC compiled GTK with a mingw/cygwin compiled
app or 2) use a mingw/cygwin compiled GTK with a MSVC compiled app. Since you
used mingw for both, I have not the slighest clue why this occurs. Especially
since I do not use GtkBox anywhere in the gtk code. (I don't use any sort of
Gtk Container period... other than GtkWindow.) There is also c) mixing GTK 2.2
and GTK 2.4 (or possibly GTK 2.4 and GTK 2.6) headers and libraries together
(e.g. including the GTK 2.2 headers in qemu but using the GTK 2.4 libraries
or something).

Technically, it means that the sizes of the structure types don't match, which
means that the library binary (GTK) and the application binary (qemu) are not
compatible.

It is possible that the 2 different mingw environments could have introduced
incompatibilities (a very remote possibility). Perhaps recompiling GTK and
its dependencies inside the new mingw environment would produce valid libraries.
Or it might trash the new environment completely...*shrug*

-- 
Infinite complexity begets infinite beauty.
Infinite precision begets infinite perfection.

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [Qemu-devel] quick gtk2.c update
  2005-06-20  1:59       ` Jim C. Brown
  2005-06-21  2:27         ` jeebs
@ 2005-06-21 10:32         ` Jernej Simončič
  1 sibling, 0 replies; 59+ messages in thread
From: Jernej Simončič @ 2005-06-21 10:32 UTC (permalink / raw)
  To: Jim C. Brown on [qemu-devel]

On Monday, June 20, 2005, 3:59:11, Jim C. Brown wrote:

> I did find a GTK Windows tutorial at
> http://wolfpack.twu.net/docs/gtkwin32/,
> but that says to install the dlls to the System folder.

Thanks to people like that I had to put detection of such broken installs to
the GTK+ installer distributed on <http://gimp-win.sf.net/> because we've
had too many problems with Gimp not starting thanks to old GTK+ libraries in
the PATH.

-- 
< Jernej Simoncic ><><><><>< http://deepthought.ena.si/ >

If it does exist, it's out of date.
       -- Arnold's Second Law of Documentation

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [Qemu-devel] quick gtk2.c update
  2005-06-21  2:27         ` jeebs
  2005-06-21  2:39           ` Jim C. Brown
@ 2005-06-21 10:39           ` Jernej Simončič
  1 sibling, 0 replies; 59+ messages in thread
From: Jernej Simončič @ 2005-06-21 10:39 UTC (permalink / raw)
  To: jeebs@yango.us on [qemu-devel]

On Tuesday, June 21, 2005, 4:27:04, jeebs@yango.us wrote:

> I'd rather keep them in the qemu directory.  Just like I do with sdl.dll

Semi-official place to put GTK+ libraries on Windows is C:\Program
Files\Common Files\GTK\2.0, and then adding bin\ subdirectory to PATH. This
is what GTK+ installers do by default.

BTW, for compiling GTK+ programs, I set the PATH specifically for MSys so
that my system-installed GTK+ doesn't interfere with the dev environment
(also, this allows me to compile for a certain GTK+ version without
configure complaining - GTK+ programs that are written for GTK+ 2.4 and
earlier won't be able to open filenames containing non-ascii characters on
Windows when compiled with GTK+ 2.6).

-- 
< Jernej Simoncic ><><><><>< http://deepthought.ena.si/ >

Hot glass looks the same as cold glass.
       -- Cirino's Law of Burnt Fingers

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [Qemu-devel] quick gtk2.c update
  2005-06-21  2:58             ` jeebs
  2005-06-21  4:28               ` Jim C. Brown
@ 2005-06-21 10:42               ` Jernej Simončič
  2005-06-21 12:36                 ` Jim C. Brown
  2005-06-21 16:30                 ` jeebs
  1 sibling, 2 replies; 59+ messages in thread
From: Jernej Simončič @ 2005-06-21 10:42 UTC (permalink / raw)
  To: jeebs@yango.us on [qemu-devel]

On Tuesday, June 21, 2005, 4:58:06, jeebs@yango.us wrote:

> No idea what it really means.  Other than what it actually says.

Do a export CFLAGS="$CFLAGS -mms-bitfields" before configuring and compiling
any GTK+ program on Windows - the libraries are always built to be
compatible with MSVC so that you can use 1 set of libraries for all
programs.

-- 
< Jernej Simoncic ><><><><>< http://deepthought.ena.si/ >

The world is more complicated than most of our theories make it out to be.
       -- Berkeley's First Law

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [Qemu-devel] quick gtk2.c update
  2005-06-21  4:28               ` Jim C. Brown
@ 2005-06-21 10:45                 ` Jernej Simončič
  2005-06-21 16:27                 ` jeebs
  1 sibling, 0 replies; 59+ messages in thread
From: Jernej Simončič @ 2005-06-21 10:45 UTC (permalink / raw)
  To: Jim C. Brown on [qemu-devel]

On Tuesday, June 21, 2005, 6:28:44, Jim C. Brown wrote:

> This is a particularly perplexing error, considering that a) this error should
> only show up if you 1) use a MSVC compiled GTK with a mingw/cygwin compiled
> app or 2) use a mingw/cygwin compiled GTK with a MSVC compiled app. Since you
> used mingw for both, I have not the slighest clue why this occurs.

GTK+ and it's dependencies automatically specify -mms-bitfields when they're
ocnfigured, so that you can use the same libraries for both MSVC and
MinGW-compiled programs.

-- 
< Jernej Simoncic ><><><><>< http://deepthought.ena.si/ >

Beauty times brains equals a constant.
       -- Beckhap's Law

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [Qemu-devel] quick gtk2.c update
  2005-06-21 10:42               ` [Qemu-devel] quick gtk2.c update Jernej Simončič
@ 2005-06-21 12:36                 ` Jim C. Brown
  2005-06-21 16:30                 ` jeebs
  1 sibling, 0 replies; 59+ messages in thread
From: Jim C. Brown @ 2005-06-21 12:36 UTC (permalink / raw)
  To: qemu-devel

On Tue, Jun 21, 2005 at 12:42:56PM +0200, Jernej Simon?i? wrote:
> On Tuesday, June 21, 2005, 4:58:06, jeebs@yango.us wrote:
> 
> > No idea what it really means.  Other than what it actually says.
> 
> Do a export CFLAGS="$CFLAGS -mms-bitfields" before configuring and compiling
> any GTK+ program on Windows - the libraries are always built to be
> compatible with MSVC so that you can use 1 set of libraries for all
> programs.
> 

Aha. I wasn't aware of that ... so qemu was most likely built without
-mms-bitfields. (I knew the option exists, but I didn't know it was the
default.)

I'll take a look at modifying the Makefile to support this.

> The world is more complicated than most of our theories make it out to be.
>        -- Berkeley's First Law

Indeed.

-- 
Infinite complexity begets infinite beauty.
Infinite precision begets infinite perfection.

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [Qemu-devel] quick gtk2.c update
  2005-06-21  4:28               ` Jim C. Brown
  2005-06-21 10:45                 ` Jernej Simončič
@ 2005-06-21 16:27                 ` jeebs
  2005-06-21 17:20                   ` Jernej Simončič
  2005-06-21 19:45                   ` Jim C. Brown
  1 sibling, 2 replies; 59+ messages in thread
From: jeebs @ 2005-06-21 16:27 UTC (permalink / raw)
  To: qemu-devel

> This is a particularly perplexing error, considering that a) this error 
> should
> only show up if you 1) use a MSVC compiled GTK with a mingw/cygwin 
> compiled

I downloaded the libraries and devel files from the link Jernej Simoncic 
recommended.  It does seem to be a main win gtk distrib location.  (As 
somebody pointed out, actually building gtk etc. under Mingw is a pita.  I 
haven't tried, but judging from all the stuff that would be needed to build 
it, I suspect that's true.)

The unzip into the proper mingw directory structure.

> Gtk Container period... other than GtkWindow.) There is also c) mixing GTK 
> 2.2
> and GTK 2.4 (or possibly GTK 2.4 and GTK 2.6) headers and libraries 
> together
> (e.g. including the GTK 2.2 headers in qemu but using the GTK 2.4 
> libraries
> or something).

I'm using the versions recommended and distributed on 
http://www.gimp.org/~tml/gimp/win32/

I get the same error regardless whether I'm using the recommended version or 
the bleeding edge version.

> It is possible that the 2 different mingw environments could have 
> introduced
> incompatibilities (a very remote possibility). Perhaps recompiling GTK and
> its dependencies inside the new mingw environment would produce valid 
> libraries.
> Or it might trash the new environment completely...*shrug*

I don't know how to recompile all that stuff.

I'm just downloading the pre-built devel libraries.

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [Qemu-devel] quick gtk2.c update
  2005-06-21 10:42               ` [Qemu-devel] quick gtk2.c update Jernej Simončič
  2005-06-21 12:36                 ` Jim C. Brown
@ 2005-06-21 16:30                 ` jeebs
  2005-06-21 17:25                   ` Jernej Simončič
  1 sibling, 1 reply; 59+ messages in thread
From: jeebs @ 2005-06-21 16:30 UTC (permalink / raw)
  To: qemu-devel

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 628 bytes --]

From: "Jernej Simonèiè"

>> No idea what it really means.  Other than what it actually says.

>Do a export CFLAGS="$CFLAGS -mms-bitfields" before configuring and 
>compiling
>any GTK+ program on Windows - the libraries are always built to be
>compatible with MSVC so that you can use 1 set of libraries for all
>programs.

I'll have to wait until Jim sends me the changes.

I'm not a developer and I have no idea what you mean by "export".

I'm just serving as a dumb build enviornment.

Although the mingw/msys devel environment might work under Linux & WINE, he 
wouldn't have any way to run & test the resulting executables.

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [Qemu-devel] quick gtk2.c update
  2005-06-21 16:27                 ` jeebs
@ 2005-06-21 17:20                   ` Jernej Simončič
  2005-06-21 19:40                     ` jeebs
  2005-06-21 19:45                   ` Jim C. Brown
  1 sibling, 1 reply; 59+ messages in thread
From: Jernej Simončič @ 2005-06-21 17:20 UTC (permalink / raw)
  To: jeebs@yango.us on [qemu-devel]

On Tuesday, June 21, 2005, 18:27:10, jeebs@yango.us wrote:

> I downloaded the libraries and devel files from the link Jernej Simoncic
> recommended.  It does seem to be a main win gtk distrib location.  (As 
> somebody pointed out, actually building gtk etc. under Mingw is a pita.  I 
> haven't tried, but judging from all the stuff that would be needed to build 
> it, I suspect that's true.)

> The unzip into the proper mingw directory structure.

Did you unzip to /mingw or to /? If the latter, you'll probably have
problems, since MSys expects that the executables in /bin use the MSys
runtime, and it won't pass the command-line parameters properly.

> I get the same error regardless whether I'm using the recommended version or
> the bleeding edge version.

Just adjust your CFLAGS to contain -mms-bitfields before configuring Qemu.

-- 
< Jernej Simoncic ><><><><>< http://deepthought.ena.si/ >

No matter what goes wrong, it will probably look right.
       -- Scott's First Law

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [Qemu-devel] quick gtk2.c update
  2005-06-21 16:30                 ` jeebs
@ 2005-06-21 17:25                   ` Jernej Simončič
  0 siblings, 0 replies; 59+ messages in thread
From: Jernej Simončič @ 2005-06-21 17:25 UTC (permalink / raw)
  To: jeebs@yango.us on [qemu-devel]

On Tuesday, June 21, 2005, 18:30:07, jeebs@yango.us wrote:

>>Do a export CFLAGS="$CFLAGS -mms-bitfields" before configuring and
>>compiling
>>any GTK+ program on Windows - the libraries are always built to be
>>compatible with MSVC so that you can use 1 set of libraries for all
>>programs.

> I'll have to wait until Jim sends me the changes.
> I'm not a developer and I have no idea what you mean by "export".

Type

export CFLAGS="$CFLAGS -mms-bitfields"

in MSys' bash before running ./configure (or simply add it to ~/.bashrc so
you don't have to type it every time).

> Although the mingw/msys devel environment might work under Linux & WINE, he
> wouldn't have any way to run & test the resulting executables.

MSys itself won't, since msys is actually stripped-down Cygwin. It is
possible to cross-compile GTK+ programs from Linux (and it's definitely
faster than under MSys, since bash+gcc are slow as hell on Win32;
apparently, it's also almost easier to set up a cross-compilation
environment in Linux than MSys on Windows for GTK+).

-- 
< Jernej Simoncic ><><><><>< http://deepthought.ena.si/ >

The larger the project or job, the less time there is to do it.
       -- Old Engineer's Law

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [Qemu-devel] quick gtk2.c update
  2005-06-21 17:20                   ` Jernej Simončič
@ 2005-06-21 19:40                     ` jeebs
  2005-06-21 20:22                       ` Jernej Simončič
  2005-06-21 21:52                       ` Jim C. Brown
  0 siblings, 2 replies; 59+ messages in thread
From: jeebs @ 2005-06-21 19:40 UTC (permalink / raw)
  To: qemu-devel

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 834 bytes --]

"Jernej Simonèiè" <jernej@ena.si>

>> The unzip into the proper mingw directory structure.

>Did you unzip to /mingw or to /? If the latter, you'll probably have

Into the mingw directory.

That part seems to compile etc.  It's the resulting program that is screwed 
up some how.


>export CFLAGS="$CFLAGS -mms-bitfields"

Okay, I tried that.

I then did a 'make clean'.  Then the config, then the regular make

But running the resulting qemu is still giving the same error.



Considering how big the GTK libraries are for Windows, to be honest, I'm not 
so sure it's a good idea, anyway.

The sdl library is only 300k and can be included with qemu.

The gtk libraries are more than 6 meg and would be a little big to include 
with qemu.  It just doesn't seem right to have the libraries being 8 times 
larger than the main program.

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [Qemu-devel] quick gtk2.c update
  2005-06-21 16:27                 ` jeebs
  2005-06-21 17:20                   ` Jernej Simončič
@ 2005-06-21 19:45                   ` Jim C. Brown
  2005-06-21 20:32                     ` [Qemu-devel] Build environment image Tim Walker
  1 sibling, 1 reply; 59+ messages in thread
From: Jim C. Brown @ 2005-06-21 19:45 UTC (permalink / raw)
  To: qemu-devel

[-- Attachment #1: Type: text/plain, Size: 1108 bytes --]

On Tue, Jun 21, 2005 at 11:27:10AM -0500, jeebs@yango.us wrote:
> I downloaded the libraries and devel files from the link Jernej Simoncic 
> recommended.  It does seem to be a main win gtk distrib location.  (As 
> somebody pointed out, actually building gtk etc. under Mingw is a pita.  I 
> haven't tried, but judging from all the stuff that would be needed to build 
> it, I suspect that's true.)
> 
> The unzip into the proper mingw directory structure.
> 
> I'm using the versions recommended and distributed on 
> http://www.gimp.org/~tml/gimp/win32/
> 
> I get the same error regardless whether I'm using the recommended version or 
> the bleeding edge version.
> 
> I'm just downloading the pre-built devel libraries.

That would explain the error. The pre-build devel libraries would have -mms-bitfields
set (in order to ensure compatibility).

Attached is a simple Makefile.target patch that will turn that option on when
building qemu on Windows. Just apply the patch, reconfigure, and rebuild qemu.

-- 
Infinite complexity begets infinite beauty.
Infinite precision begets infinite perfection.

[-- Attachment #2: Makefile.target.patch --]
[-- Type: text/plain, Size: 334 bytes --]

--- Makefile.target.old	Tue Jun 21 15:42:52 2005
+++ Makefile.target	Tue Jun 21 15:44:17 2005
@@ -211,6 +211,10 @@
 
 #########################################################
 
+ifdef CONFIG_WIN32
+CFLAGS+=-mms-bitfields
+endif
+
 DEFINES+=-D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
 LIBS+=-lm
 ifndef CONFIG_USER_ONLY

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [Qemu-devel] quick gtk2.c update
  2005-06-21 19:40                     ` jeebs
@ 2005-06-21 20:22                       ` Jernej Simončič
  2005-06-21 21:19                         ` jeebs
  2005-06-21 21:52                       ` Jim C. Brown
  1 sibling, 1 reply; 59+ messages in thread
From: Jernej Simončič @ 2005-06-21 20:22 UTC (permalink / raw)
  To: jeebs@yango.us on [qemu-devel]

On Tuesday, June 21, 2005, 21:40:26, jeebs@yango.us wrote:

>>export CFLAGS="$CFLAGS -mms-bitfields"

> Okay, I tried that.

> I then did a 'make clean'.  Then the config, then the regular make

> But running the resulting qemu is still giving the same error.

Hmm, it's been a while since I last tried compiling Qemu, but maybe you'll
need to edit the makefiles to actually include that flag.

> Considering how big the GTK libraries are for Windows, to be honest, I'm not
> so sure it's a good idea, anyway.

> The sdl library is only 300k and can be included with qemu.

> The gtk libraries are more than 6 meg and would be a little big to include
> with qemu.  It just doesn't seem right to have the libraries being 8 times
> larger than the main program.

I'd say it's worth it, if Qemu gains a usable GUI this way. GTK+ libraries
are ~3,5MB download, and only need to be installed once.

-- 
< Jernej Simoncic ><><><><>< http://deepthought.ena.si/ >

Possessions increase to fill the space available for their storage.
       -- Ryan's Application of Parkinson's Law

^ permalink raw reply	[flat|nested] 59+ messages in thread

* [Qemu-devel] Build environment image
  2005-06-21 19:45                   ` Jim C. Brown
@ 2005-06-21 20:32                     ` Tim Walker
  2005-06-24 17:19                       ` Tim Walker
  0 siblings, 1 reply; 59+ messages in thread
From: Tim Walker @ 2005-06-21 20:32 UTC (permalink / raw)
  To: qemu-devel

How difficult would it be to create a (presumably Linux) uniform build 
environment for all targets as a bootable Qemu image?

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [Qemu-devel] quick gtk2.c update
  2005-06-21 20:22                       ` Jernej Simončič
@ 2005-06-21 21:19                         ` jeebs
  2005-06-21 22:24                           ` Jim C. Brown
  0 siblings, 1 reply; 59+ messages in thread
From: jeebs @ 2005-06-21 21:19 UTC (permalink / raw)
  To: qemu-devel

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 1271 bytes --]

"Jernej Simonèiè"

>Hmm, it's been a while since I last tried compiling Qemu, but maybe you'll
>need to edit the makefiles to actually include that flag.

That's what I did.  He sent me the patch to do that.

It runs, but there are keyboard problems.


>> The gtk libraries are more than 6 meg and would be a little big to 
>> include
>> with qemu.  It just doesn't seem right to have the libraries being 8 
>> times
>> larger than the main program.

>I'd say it's worth it, if Qemu gains a usable GUI this way. GTK+ libraries
>are ~3,5MB download, and only need to be installed once.

Putting libraries like this in a common location is always a bad thing. 
That means the files whill have to be distributed with qemu

And not everybody installs qemu over old versions, so you can't really 
expect the files to already be there from last time.


It just seems fundamentally wrong to have a small emulator with very large 
libraries, just to satisfy some gui bloat.

As for the gui... Well, I haven't seen that yet.  What little I see looks 
the same boring Windows window that qemu always runs in.  The gtk version 
isn't usable yet.


I do like the idea of a gui...   Really.

I'm just saying that I think 6meg is a bit large for a program that's only 
780k by itself.

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [Qemu-devel] quick gtk2.c update
  2005-06-21 19:40                     ` jeebs
  2005-06-21 20:22                       ` Jernej Simončič
@ 2005-06-21 21:52                       ` Jim C. Brown
  1 sibling, 0 replies; 59+ messages in thread
From: Jim C. Brown @ 2005-06-21 21:52 UTC (permalink / raw)
  To: qemu-devel

On Tue, Jun 21, 2005 at 02:40:26PM -0500, jeebs@yango.us wrote:
> >export CFLAGS="$CFLAGS -mms-bitfields"
> 
> Okay, I tried that.
> 
> I then did a 'make clean'.  Then the config, then the regular make
> 
> But running the resulting qemu is still giving the same error.
> 
> 

Not the slightest clue why that should be. Unless make or gcc was ignoring
the CFLAGS variable (or you used different shells).

You can try the Makefile.target patch I sent, that may give better results.

> 
> Considering how big the GTK libraries are for Windows, to be honest, I'm not 
> so sure it's a good idea, anyway.
> 
> The sdl library is only 300k and can be included with qemu.
> 
> The gtk libraries are more than 6 meg and would be a little big to include 
> with qemu.  It just doesn't seem right to have the libraries being 8 times 
> larger than the main program.
> 

On Linux, the SDL library is 2.5M and the GTK library is 16.5M

So I understand the feeling. However, if we can keep the Windows and Linux
versions unified with GTK, I think that the benefit would be sigficant.

-- 
Infinite complexity begets infinite beauty.
Infinite precision begets infinite perfection.

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [Qemu-devel] quick gtk2.c update
  2005-06-21 21:19                         ` jeebs
@ 2005-06-21 22:24                           ` Jim C. Brown
  2005-06-21 22:45                             ` jeebs
  0 siblings, 1 reply; 59+ messages in thread
From: Jim C. Brown @ 2005-06-21 22:24 UTC (permalink / raw)
  To: jeebs; +Cc: qemu-devel

On Tue, Jun 21, 2005 at 04:19:33PM -0500, jeebs@yango.us wrote:
> >I'd say it's worth it, if Qemu gains a usable GUI this way. GTK+ libraries
> >are ~3,5MB download, and only need to be installed once.
> 
> Putting libraries like this in a common location is always a bad thing. 
> That means the files whill have to be distributed with qemu
> 

I disagree. I think distributing the GTK library with qemu (even for windows
versions) is a very bad idea. At most, the qemu installer should just download
and run the GTK installer. At most.

GTK libraries are not part of qemu, they are a separate resource that qemu
depends on.

> And not everybody installs qemu over old versions, so you can't really 
> expect the files to already be there from last time.
> 
> 
> It just seems fundamentally wrong to have a small emulator with very large 
> libraries, just to satisfy some gui bloat.
> 
> I do like the idea of a gui...   Really.
> 
> I'm just saying that I think 6meg is a bit large for a program that's only 
> 780k by itself.
> 

qemu is 3.4M here. So I don't think that is so bad. Especially when that one
set of 6M libs can be shared by many different applications (qemu, xchat, etc).

It is possible to rewrite the GTK code so it is only written in GDK (the only
GTK object we use is the GtkWindow, which I guess could be replaced by a
GdkWindow). GDK looks a lot smaller than GTK over here (4M vs 16M).

> As for the gui... Well, I haven't seen that yet.  What little I see looks 
> the same boring Windows window that qemu always runs in.  The gtk version 
> isn't usable yet.
> 

The GTK version, on Linux, is perfectly usable. It is no more usable than the
SDL version, but no less.

On Windows, you have no fullscreen support. Everything else should be exactly
the same. If it's not, I'll try to fix it.

A GUI is coming soon. I think.

> It runs, but there are keyboard problems.
> 

What keyboard problems? There shouldn't be any for the GTK version.

-- 
Infinite complexity begets infinite beauty.
Infinite precision begets infinite perfection.

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [Qemu-devel] quick gtk2.c update
  2005-06-21 22:24                           ` Jim C. Brown
@ 2005-06-21 22:45                             ` jeebs
  2005-06-21 23:58                               ` Jim C. Brown
  2005-06-22  3:53                               ` Herbert Poetzl
  0 siblings, 2 replies; 59+ messages in thread
From: jeebs @ 2005-06-21 22:45 UTC (permalink / raw)
  To: Jim C. Brown; +Cc: qemu-devel

"Jim C. Brown"
> I disagree. I think distributing the GTK library with qemu (even for 
> windows
> versions) is a very bad idea. At most, the qemu installer should just 
> download
> and run the GTK installer. At most.

It's a very bad idea to have the installer need to go back on to the net to 
download something else.

The user should get the whole thing at once.


> GTK libraries are not part of qemu, they are a separate resource that qemu
> depends on.

As far as the user is concerned, they are part of qemu.


> qemu is 3.4M here. So I don't think that is so bad. Especially when that 
> one

It shouldn't be.

There isn't that much conceptually different between windows and linux that 
should cause it to be that big.


> set of 6M libs can be shared by many different applications (qemu, xchat, 
> etc).

Not under windows, it wont be.

For us Windows users, qemu will be the only program we use that will need 
gtk libs.

Realistically, we don't need GTK.  We've already got a GUI with an api. 
That's what windows programmers use.  The vast majority of us will never use 
xchat etc.  Qemu may be the only one they use.


And it's not a good idea to distribute the libraries seperately.

Or put them in the Windows system directory.  Too much junk gets put there 
already due to years and years of poor programming, careless authors, 
indifferent programmers, and Microsoft's encouragement.


>> As for the gui... Well, I haven't seen that yet.  What little I see looks
>> the same boring Windows window that qemu always runs in.  The gtk version
>> isn't usable yet.

> The GTK version, on Linux, is perfectly usable. It is no more usable than 
> the
> SDL version, but no less.

But it's not usable on Windows yet.

As I said, so far, I'm not seeing *any* gui.  Even the keyboard is messed 
up, so you can't even use the guest OS.


> On Windows, you have no fullscreen support. Everything else should be 
> exactly
> the same. If it's not, I'll try to fix it.

I never use full screen, myself.

I much prefer a window.  Preferably one that's resizable, scroll bars, etc. 
etc.

>> It runs, but there are keyboard problems.
>>
>
> What keyboard problems? There shouldn't be any for the GTK version.

As I said in the other message (which I may have accidently sent directly to 
you, instead of the list)

It's not doing the regular US keyboard.  At least it doesn't eappear to be.

I can get symbols, a few letters, but not the whole thing.  And none of it
is normal.  Press '1' to get 'n' and so on.

However, it doesn't appear that the -k keyboard option works for the windows
version.

I tried my builds and the official 0.70 build and they don't accept it
either.

I tried -k fr -k de -k en-us and so on, and they don't recognise it.

(I've never tried the -k option before, but according to the docs, it isn't 
needed for Windows builds.  So it may not be enabled.)

So, assuming the problem is that gtk can't recognise I'm using a US
keyboard, I can't do anything to force it.

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [Qemu-devel] quick gtk2.c update
  2005-06-21 22:45                             ` jeebs
@ 2005-06-21 23:58                               ` Jim C. Brown
  2005-06-22  4:14                                 ` jeebs
                                                   ` (3 more replies)
  2005-06-22  3:53                               ` Herbert Poetzl
  1 sibling, 4 replies; 59+ messages in thread
From: Jim C. Brown @ 2005-06-21 23:58 UTC (permalink / raw)
  To: jeebs; +Cc: qemu-devel

On Tue, Jun 21, 2005 at 05:45:12PM -0500, jeebs@yango.us wrote:
> > GTK libraries are not part of qemu, they are a separate resource that qemu
> > depends on.
> 
> As far as the user is concerned, they are part of qemu.
> 

I must disagree here. If a user already has xchat 2 installed, and that person
wants to try to use qemu with the GTK interface, they already have the libraries
that they need.

Including a set of GTK libraries just for qemu would not only be redundant in
this case, it could potentially cause breakage to occur.

> 
> > I disagree. I think distributing the GTK library with qemu (even for 
> > windows
> > versions) is a very bad idea. At most, the qemu installer should just 
> > download
> > and run the GTK installer. At most.
> 
> It's a very bad idea to have the installer need to go back on to the net to 
> download something else.
> 
> The user should get the whole thing at once.
> 

They should only get this library if they don't already have a copy installed.

Of course there is a simple answer to this. Provide 3 qemu binaries for Windows:
one that includes GTK support as well as the GTK libraries (so the installer can
put them into the Common Files folder), one that includes GTK support but not
the libraries, and one that has only SDL support.

That's the dumb last resort option. Let's see who can come up with a smarter one.

> > set of 6M libs can be shared by many different applications (qemu, xchat, 
> > etc).
> 
> Not under windows, it wont be.
> 
> For us Windows users, qemu will be the only program we use that will need 
> gtk libs.
> 
> Realistically, we don't need GTK.  We've already got a GUI with an api. 
> That's what windows programmers use.  The vast majority of us will never use 
> xchat etc.  Qemu may be the only one they use.
> 

Ok, that is a valid point. I also agree that given what the GTK layer in qemu
actually does, that is too much lot of overkill. (It would be really simple to
just use pure GDK - the majority of the code is GDK.) However, I believe that
the benefit of sharing the same GUI between Windows and Linux outweights this
cost (esp. if what you say is true, that Windows builds are not very well
maintained).

> And it's not a good idea to distribute the libraries seperately.

Agreed.

> 
> Or put them in the Windows system directory.  Too much junk gets put there 
> already due to years and years of poor programming, careless authors, 
> indifferent programmers, and Microsoft's encouragement.
> 

I think the idea of using C:\Programing Files\Common Files\GTK 2.0 is a good
solution for that.

> 
> >> As for the gui... Well, I haven't seen that yet.  What little I see looks
> >> the same boring Windows window that qemu always runs in.  The gtk version
> >> isn't usable yet.
> 
> > The GTK version, on Linux, is perfectly usable. It is no more usable than 
> > the
> > SDL version, but no less.
> 
> But it's not usable on Windows yet.
> 
> As I said, so far, I'm not seeing *any* gui.  Even the keyboard is messed 
> up, so you can't even use the guest OS.
> 

There is no GUI yet. I could easily make a crappy one in, say, 20 minutes.
It'd work fine, but it may not be a lot of fun to use. For that matter, it
may not be that useful.

I'm waiting to hear from Fabrice and Sebastian for the GUI they have planned
on top of the GTK layer. It seems that Fabrice is very picky when it comes to
the GUI of choice for qemu.

> 
> > On Windows, you have no fullscreen support. Everything else should be 
> > exactly
> > the same. If it's not, I'll try to fix it.
> 
> I never use full screen, myself.
> 
> I much prefer a window.  Preferably one that's resizable, scroll bars, etc. 
> etc.
> 

This isn't very difficult to do at all, and the code to do this for Linux and
Windows should be identical. I'd like to fix the current bugs first though
(on the off chance that there happens to be a difference on Windows that I don't
know about). Once we fix those bugs, I'll look into making the qemu window
resizable.

> >> It runs, but there are keyboard problems.
> >>
> >
> > What keyboard problems? There shouldn't be any for the GTK version.
> 
> As I said in the other message (which I may have accidently sent directly to 
> you, instead of the list)
> 
> It's not doing the regular US keyboard.  At least it doesn't eappear to be.
> 

It should. But it doesn't. Disturbing.

> I can get symbols, a few letters, but not the whole thing.  And none of it
> is normal.  Press '1' to get 'n' and so on.
> 

Yes, that is quite disgusting.

> However, it doesn't appear that the -k keyboard option works for the windows
> version.
> 
> I tried my builds and the official 0.70 build and they don't accept it
> either.
> 
> I tried -k fr -k de -k en-us and so on, and they don't recognise it.
> 
> (I've never tried the -k option before, but according to the docs, it isn't 
> needed for Windows builds.  So it may not be enabled.)
> 
> So, assuming the problem is that gtk can't recognise I'm using a US
> keyboard, I can't do anything to force it.
> 

Well, no, that isn't it. The keymap files are based on X11 keycodes, so even if
you could use this option it wouldn't work at all.

I know the offending function. This is the culprit:

static uint8_t gtk2_keyevent_to_keycode(const GdkEventKey *ev)
{   
    return ev->hardware_keycode; /* does this work on win32 gtk? */
}

Apparently, that does not work for win32 gtk.

In fact, that is apparently the Windows virtual key code, not the raw scancode.
Hence the funny characters. The good news is that this is an easy fix. In fact,
here is the code that we would need:

static UINT vk2scan(UINT vk)
{
        static HKL layout=GetKeyboardLayout(0);
        return MapVirtualKeyEx(vk,0,layout);
}
static uint8_t gtk2_keyevent_to_keycode(const GdkEventKey *ev)
{   
    return vk2scan(ev->hardware_keycode); /* does this work on win32 gtk? */
}

At least, I think that is what it should look like. Looks like there will be
some minor problems casting as ev->hardware_keycode is an unsigned int of 16
bits, vk2scan requires a UINT (whatever size that is), and the main gtk2()
function here is expected to return an unsigned int of 8 bits. Hmm. Also, I
have no idea which files I'd need to include in order to be able to call
GetKeyboardLayout() or MakVirtualKeyEx(). What I really need is a Win32
programmer to proofread this, make sure I got it right.

-- 
Infinite complexity begets infinite beauty.
Infinite precision begets infinite perfection.

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [Qemu-devel] quick gtk2.c update
  2005-06-21 22:45                             ` jeebs
  2005-06-21 23:58                               ` Jim C. Brown
@ 2005-06-22  3:53                               ` Herbert Poetzl
  2005-06-22 12:41                                 ` Jim C. Brown
  1 sibling, 1 reply; 59+ messages in thread
From: Herbert Poetzl @ 2005-06-22  3:53 UTC (permalink / raw)
  To: jeebs; +Cc: Jim C. Brown, qemu-devel

On Tue, Jun 21, 2005 at 05:45:12PM -0500, jeebs@yango.us wrote:
> "Jim C. Brown"
> > I disagree. I think distributing the GTK library with qemu (even for 
> > windows
> > versions) is a very bad idea. At most, the qemu installer should just 
> > download
> > and run the GTK installer. At most.
> 
> It's a very bad idea to have the installer need to go back on to the net to 
> download something else.
> 
> The user should get the whole thing at once.

yes, that's what hyperlinks are for, just put _another_ one
on the download site saying something like: "this also 
requires that you install bla, bla and bla. you can get
a recent version of them here, here and here" ...

> > GTK libraries are not part of qemu, they are a separate resource that qemu
> > depends on.
> 
> As far as the user is concerned, they are part of qemu.

as is VBRUN.dll for each and every application .. NOT!

this is the windows concept of 'do not share libraries',
'do not trust installed resources' and 'do not keep any
compatibility' ...

> > qemu is 3.4M here. So I don't think that is so bad. Especially when that 
> > one
> 
> It shouldn't be.
> 
> There isn't that much conceptually different between windows and linux that 
> should cause it to be that big.
> 
> 
> > set of 6M libs can be shared by many different applications (qemu, xchat, 
> > etc).
> 
> Not under windows, it wont be.
> 
> For us Windows users, qemu will be the only program we use that will need 
> gtk libs.
> 
> Realistically, we don't need GTK.  We've already got a GUI with an api. 
> That's what windows programmers use.  The vast majority of us will never use 
> xchat etc.  Qemu may be the only one they use.

so why not make a native GUI for windows, and just
use that? (according to Micro$oft this could not take
longer than a five minutes with their advanced tools)

> And it's not a good idea to distribute the libraries seperately.

it's neither smart nor good to deploy apps bundled
with a complete operating system. period.

> Or put them in the Windows system directory.  Too much junk gets put there 
> already due to years and years of poor programming, careless authors, 
> indifferent programmers, and Microsoft's encouragement.

precisely, and every app wants to use their 'personal'
version of lib whatever, but that's a windows issue,
nothing which should concern QEMU ...

> >> As for the gui... Well, I haven't seen that yet.  What little I see looks
> >> the same boring Windows window that qemu always runs in.  The gtk version
> >> isn't usable yet.
> 
> > The GTK version, on Linux, is perfectly usable. It is no more usable than 
> > the
> > SDL version, but no less.
> 
> But it's not usable on Windows yet.
> 
> As I said, so far, I'm not seeing *any* gui.  Even the keyboard is messed 
> up, so you can't even use the guest OS.
> 
> 
> > On Windows, you have no fullscreen support. Everything else should be 
> > exactly
> > the same. If it's not, I'll try to fix it.
> 
> I never use full screen, myself.
> 
> I much prefer a window.  Preferably one that's resizable, scroll bars, etc. 
> etc.
> 
> >> It runs, but there are keyboard problems.
> >>
> >
> > What keyboard problems? There shouldn't be any for the GTK version.
> 
> As I said in the other message (which I may have accidently sent directly to 
> you, instead of the list)
> 
> It's not doing the regular US keyboard.  At least it doesn't eappear to be.
> 
> I can get symbols, a few letters, but not the whole thing.  And none of it
> is normal.  Press '1' to get 'n' and so on.
> 
> However, it doesn't appear that the -k keyboard option works for the windows
> version.
> 
> I tried my builds and the official 0.70 build and they don't accept it
> either.
> 
> I tried -k fr -k de -k en-us and so on, and they don't recognise it.
> 
> (I've never tried the -k option before, but according to the docs, it isn't 
> needed for Windows builds.  So it may not be enabled.)
> 
> So, assuming the problem is that gtk can't recognise I'm using a US
> keyboard, I can't do anything to force it.

best,
Herbert

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [Qemu-devel] quick gtk2.c update
  2005-06-21 23:58                               ` Jim C. Brown
@ 2005-06-22  4:14                                 ` jeebs
  2005-06-22  5:15                                   ` Damien Mascord
                                                     ` (2 more replies)
  2005-06-22  9:16                                 ` Jernej Simončič
                                                   ` (2 subsequent siblings)
  3 siblings, 3 replies; 59+ messages in thread
From: jeebs @ 2005-06-22  4:14 UTC (permalink / raw)
  To: qemu-devel

"Jim C. Brown"

> I must disagree here. If a user already has xchat 2 installed, and that 
> person
> wants to try to use qemu with the GTK interface, they already have the 
> libraries
> that they need.
>
> Including a set of GTK libraries just for qemu would not only be redundant 
> in
> this case, it could potentially cause breakage to occur.

That's why you are supposed to put them in the directory of the app.

It keeps from cluttering up the rest of the OS, possibly causing confusion, 
breakage, etc. with more than one version installed in various places (quite 
possible under windows) or having a damaged, broken one installed in the 
first place Windows looks.

> They should only get this library if they don't already have a copy 
> installed.

Which will be practically every qemu user.

> Of course there is a simple answer to this. Provide 3 qemu binaries for 
> Windows:
> one that includes GTK support as well as the GTK libraries (so the 
> installer can
> put them into the Common Files folder), one that includes GTK support but 
> not

Putting more stuff into the common files folders is just going to be 
'clutter'.

Things will never get used by any other application.  Eventually the user 
will even entirely forget they are there.

It just ends up being clutter.

>> Or put them in the Windows system directory.  Too much junk gets put 
>> there
>> already due to years and years of poor programming, careless authors,
>> indifferent programmers, and Microsoft's encouragement.
>
> I think the idea of using C:\Programing Files\Common Files\GTK 2.0 is a 
> good
> solution for that.

In theory.  That's kind of what the directory is for.

But that also assumes a few other things...

Like those files actually might possibly ever get used by some other app. 
Not too likely for a Windows user.

Second, by putting them in a common location, you open the possibility that 
they'll get replaced with newer versions.  Which may not work right, if at 
all.

That GTK website specifically mentions that certain versions are broken for 
Windows.

By bundling the libraries with qemu, and keeping them in the qemu directory, 
you can guarantee that the user has versions that work right and are 
compatible with qemu.  No -mms-whatever struct issue or anything else.


However, none of that's really relevant, since at this point the gtk stuff 
doesn't even work under windows, so there's no point in distributing 
anything.

> There is no GUI yet. I could easily make a crappy one in, say, 20 minutes.
> It'd work fine, but it may not be a lot of fun to use. For that matter, it
> may not be that useful.

Well, maybe not 'gui', but something that tells the user they are indeed 
running the GTK version and not the SDL version.


>> It's not doing the regular US keyboard.  At least it doesn't eappear to 
>> be.
>
> It should. But it doesn't. Disturbing.

[shrug]

All I can do is try to run it and report...

I don't know qemu, gtk, or general mingw development to be able to say more.

> GetKeyboardLayout() or MakVirtualKeyEx(). What I really need is a Win32
> programmer to proofread this, make sure I got it right.

That would help....

They could help you debug this stuff.

All I can do is try to compile it and run it.

Not very helpful.  Depending on how soon I can get to the patches you post, 
the test cycle may takes days for each event.

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [Qemu-devel] quick gtk2.c update
  2005-06-22  4:14                                 ` jeebs
@ 2005-06-22  5:15                                   ` Damien Mascord
  2005-06-22  9:31                                   ` Jernej Simončič
  2005-06-22 12:31                                   ` Jim C. Brown
  2 siblings, 0 replies; 59+ messages in thread
From: Damien Mascord @ 2005-06-22  5:15 UTC (permalink / raw)
  To: qemu-devel

jeebs@yango.us wrote:

<snip/>

> Putting more stuff into the common files folders is just going to be 
> 'clutter'.
> 
> Things will never get used by any other application.  Eventually the user 
> will even entirely forget they are there.
> 
> It just ends up being clutter.

Heya Jeebs,

There are numerous GTK applications that have already been ported to
Windows, and work very well.  gaim and gimp to name a few.  Both these
applications work fine with Windows and are very stable.

<snip/>

> Like those files actually might possibly ever get used by some other app. 
> Not too likely for a Windows user.
> 
> Second, by putting them in a common location, you open the possibility that 
> they'll get replaced with newer versions.  Which may not work right, if at 
> all.

Then it's a problem that needs to be fixed.  A work around is not always
the best thing to do.

> That GTK website specifically mentions that certain versions are broken for 
> Windows.

Then don't use those versions? :)

> By bundling the libraries with qemu, and keeping them in the qemu directory, 
> you can guarantee that the user has versions that work right and are 
> compatible with qemu.  No -mms-whatever struct issue or anything else.

By continuing to bundling the libraries with qemu, you are ensuring that
things aren't fixed in the upstream.  You aren't improving the general
playing field at all, and are not contributing to general GTK acceptance
on Windows.

If GTK installs over a previous version and breaks the API so that Qemu
doesn't work anymore, then there is an issue with the GTK installer,
and/or Qemu, and that issue to be fixed.

Having every application bundling it's own versions of DLLs, you are
making sure that dll compatibility is never obtained.  If one version of
vbrun300.dll breaks one app, but not another then it's a problem with
the app using non-standard API calls, or is a bug with the new version
of vbrun300.dll.

Windows XP even have manifests which allow applications to use a
particular version of a DLL, and have all those versions installed at once.

> However, none of that's really relevant, since at this point the gtk stuff 
> doesn't even work under windows, so there's no point in distributing 
> anything.

Hopefully all this attention will cause the problems with the Windows
build to be addressed.  Since the people that contribute to the Windows
build are probably quite busy, it's still productive to continue to
persist with sending bug reports as accurate as possible.  If that
doesn't seem like a great prospect, then learning bits and pieces of C
so that you can contribute to the project would be of great value!
(Especially as a Windows user, you can replicate issues that many of the
other developers would have a hard time to do so).

>>There is no GUI yet. I could easily make a crappy one in, say, 20 minutes.
>>It'd work fine, but it may not be a lot of fun to use. For that matter, it
>>may not be that useful.
>
> Well, maybe not 'gui', but something that tells the user they are indeed 
> running the GTK version and not the SDL version.
>

That's probably a good idea... maybe have some output to the monitor ?

>>>It's not doing the regular US keyboard.  At least it doesn't eappear to 
>>>be.
>>
>>It should. But it doesn't. Disturbing.
> 
> 
> [shrug]
> 
> All I can do is try to run it and report...
> 
> I don't know qemu, gtk, or general mingw development to be able to say more.
> 
> 
>>GetKeyboardLayout() or MakVirtualKeyEx(). What I really need is a Win32
>>programmer to proofread this, make sure I got it right.
> 
> 
> That would help....
> 
> They could help you debug this stuff.
> 
> All I can do is try to compile it and run it.
> 
> Not very helpful.  Depending on how soon I can get to the patches you post, 
> the test cycle may takes days for each event.

Even that time frame would be useful to the progression of Qemu on
Windows :)  I applaud that you still take the effort to test!

Cheers,

Damien

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [Qemu-devel] quick gtk2.c update
  2005-06-21 23:58                               ` Jim C. Brown
  2005-06-22  4:14                                 ` jeebs
@ 2005-06-22  9:16                                 ` Jernej Simončič
  2005-06-22 13:17                                 ` Jim C. Brown
  2005-06-22 13:22                                 ` Jim C. Brown
  3 siblings, 0 replies; 59+ messages in thread
From: Jernej Simončič @ 2005-06-22  9:16 UTC (permalink / raw)
  To: Jim C. Brown on [qemu-devel]

On Wednesday, June 22, 2005, 1:58:14, Jim C. Brown wrote:

>> > GTK libraries are not part of qemu, they are a separate resource that qemu
>> > depends on.
>> As far as the user is concerned, they are part of qemu.
> I must disagree here. If a user already has xchat 2 installed, and that person
> wants to try to use qemu with the GTK interface, they already have the libraries
> that they need.

Be careful with Xchat, some versions link to modified static GTK+, and a few
of them install GTK+ to it's own directory.

Problem here is, that there's no standarised installer for GTK+ - Tor only
provides zipfiles, and it's up to the developers how they use these ZIPs.
Hopefully this will change when porting of Evolution to Windows will be
completed.

>> It's a very bad idea to have the installer need to go back on to the net to
>> download something else.
>> 
>> The user should get the whole thing at once.

Many installers for Windows GTK+ programs do this, and nobody has a problem
with it. You could also make a ZIP file that includes both installers, and
if the user tries to install Qemu without the GTK+ libraries, the GTK+
installer could be automatically invoked in silent mode (this is what I plan
for the Gimp).

> I think the idea of using C:\Programing Files\Common Files\GTK 2.0 is a good
> solution for that.

It's Common Files\GTK\2.0 actually, since GTK+ 1.3 can also be installed
there.

-- 
< Jernej Simoncic ><><><><>< http://deepthought.ena.si/ >

Whenever you cut your fingernails, you will find a need for them an hour later.
       -- Witten's Law

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [Qemu-devel] quick gtk2.c update
  2005-06-22  4:14                                 ` jeebs
  2005-06-22  5:15                                   ` Damien Mascord
@ 2005-06-22  9:31                                   ` Jernej Simončič
  2005-06-22 12:31                                   ` Jim C. Brown
  2 siblings, 0 replies; 59+ messages in thread
From: Jernej Simončič @ 2005-06-22  9:31 UTC (permalink / raw)
  To: jeebs@yango.us on [qemu-devel]

On Wednesday, June 22, 2005, 6:14:50, jeebs@yango.us wrote:

> Like those files actually might possibly ever get used by some other app.
> Not too likely for a Windows user.

There's quite a selection of GTK+ programs for Windows available - Gimp,
Xchat, Gaim, Ethereal, ... BTW, it doesn't necesarily have to be Common
Files\GTK\2.0, it can be any directory as long as it's stored in registry in
HKEY_LOCAL_MACHINE\Software\GTK\2.0\Path - this is the key you should check
to see if GTK+ is installed.

> That GTK website specifically mentions that certain versions are broken for
> Windows.

The only broken versions of GTK+ in the last few years were 2.6.2-2.6.4, and
only on Windows 98/ME (Windows 95 isn't supported anymore, and even 98/ME
aren't officially supported, since none of the developers has them
installed).

> By bundling the libraries with qemu, and keeping them in the qemu directory,
> you can guarantee that the user has versions that work right and are 
> compatible with qemu.  No -mms-whatever struct issue or anything else.

The only way you'd get GTK+ libraries that wouldn't be compiled with
-mms-bitfields would be to compile them yourself after modifying configure
script to not automatically include it.

-- 
< Jernej Simoncic ><><><><>< http://deepthought.ena.si/ >

A good plan today is better than a perfect plan tomorrow.
       -- Patton's Law

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [Qemu-devel] quick gtk2.c update
  2005-06-22  4:14                                 ` jeebs
  2005-06-22  5:15                                   ` Damien Mascord
  2005-06-22  9:31                                   ` Jernej Simončič
@ 2005-06-22 12:31                                   ` Jim C. Brown
  2 siblings, 0 replies; 59+ messages in thread
From: Jim C. Brown @ 2005-06-22 12:31 UTC (permalink / raw)
  To: qemu-devel

On Tue, Jun 21, 2005 at 11:14:50PM -0500, jeebs@yango.us wrote:
> > They should only get this library if they don't already have a copy 
> > installed.
> 
> Which will be practically every qemu user.
> 

[ Technically not true. Most qemu users are Linux users, and most Linux users
have GTK. :) Sorry, I couldn't resist. ]

All your other arguments about GTK basicly break down to this. If only qemu
wants GTK, then your arguments make sense. However, if there are a lot of users
which use other GTK applications besides qemu, then your arguments do not apply.

A standard Joe Schmoe Windows user probably would not know what GTK is or ever
even hear the name mentioned. That user would have little if any FOSS software
and may not even be aware about FOSS in general. I won't argue about using
xchat, gaim, evolution, etc for this user. The person probably bought
all the applications that this person would ever use. This person is also
unlikely to need to run multiple OSes at once, and even if this person did,
the product used would probably be VMware or Virtual PC or some other commercial
product. Certainly not qemu, which AFAIK lacks corporate backing or commercial
support (unlike Linux which has dozens of companies funding development and
offering support). I am not saying that this can't change. I'm also not arguing
against trying to change this. I'm just saying that GTK vs no-GTK doesn't make
a difference here for qemu.

A Windows user who does use qemu will probably be very familar with OSS software.
That user may scoff at high priced programs and get software that is just as good
for free. That user may run Evolution instead of Outlook, gaim instead of AIM
Messenger, etc. That user will probably have GTK installed.

I realise that these two examples represent extremes of a continum, and that more
users better fit the first example. However, GTK is more well known than qemu
is, and one of GTK 2's goals is to be portable and easy to use on Windows.

> By bundling the libraries with qemu, and keeping them in the qemu directory, 
> you can guarantee that the user has versions that work right and are 
> compatible with qemu.  No -mms-whatever struct issue or anything else.
> 

No, that will always be an issue. But my latest patch fixed it, so qemu windows
users at least shouldn't see it anymore.

> > There is no GUI yet. I could easily make a crappy one in, say, 20 minutes.
> > It'd work fine, but it may not be a lot of fun to use. For that matter, it
> > may not be that useful.
> 
> Well, maybe not 'gui', but something that tells the user they are indeed 
> running the GTK version and not the SDL version.
> 

You're right, thats probably a good idea. On linux, you get some GTK warnings
in the console - so its pretty clear if you are using GTK or not. That's my
excuse. ;D How would you like me to fix this? Alter the title of the window
so it says "Qemu GTK" ? Show that GTK is on in the monitor interface, maybe
an "info gtk" that returns if gtk is on or not and what version is being used?

-- 
Infinite complexity begets infinite beauty.
Infinite precision begets infinite perfection.

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [Qemu-devel] quick gtk2.c update
  2005-06-22  3:53                               ` Herbert Poetzl
@ 2005-06-22 12:41                                 ` Jim C. Brown
  0 siblings, 0 replies; 59+ messages in thread
From: Jim C. Brown @ 2005-06-22 12:41 UTC (permalink / raw)
  To: Herbert Poetzl; +Cc: qemu-devel

On Wed, Jun 22, 2005 at 05:53:14AM +0200, Herbert Poetzl wrote:
> > It's a very bad idea to have the installer need to go back on to the net to 
> > download something else.
> > 
> > The user should get the whole thing at once.
> 

I already agreed to this.

> yes, that's what hyperlinks are for, just put _another_ one
> on the download site saying something like: "this also 
> requires that you install bla, bla and bla. you can get
> a recent version of them here, here and here" ...
> 

Well, the least that could be done would be to have two versions of qemu for
download, one that includes the gtk libs and one that doesnt. Along with a big
notice in red that says: IF YOU HAVE NO IDEA WHAT GTK IS THEN GET THE VERSION OF
QEMU THAT INCLUDES GTK. Or something.

> > > GTK libraries are not part of qemu, they are a separate resource that qemu
> > > depends on.
> > 
> > As far as the user is concerned, they are part of qemu.
> 
> as is VBRUN.dll for each and every application .. NOT!
> 
> this is the windows concept of 'do not share libraries',
> 'do not trust installed resources' and 'do not keep any
> compatibility' ...
> 

I agree. This should be avoided, especially because GTK is better well known
in the Windows world that qemu is currently.

> > Realistically, we don't need GTK.  We've already got a GUI with an api. 
> > That's what windows programmers use.  The vast majority of us will never use 
> > xchat etc.  Qemu may be the only one they use.
> 
> so why not make a native GUI for windows, and just
> use that? (according to Micro$oft this could not take
> longer than a five minutes with their advanced tools)
> 

A) Using microsoft tools may lead to slight incompatibilities with the qemu
code which requires gcc. [The -mms-bitfields problem discussed earlier in this
thread is a good example of that.]

B) Even if they didn't cause any problems (or the GUI was coded by hand), we
would still need a separate team of developers for the Win32 GUI. Considering
the lack of Windows build maintainers, let alone developers, this would not be
a favor to anyone, least of all the end user.

C) Sharing the same GTK GUI for Linux qemu and Windows qemu would provide a
consistent interface between the two platforms. IMHO this is the most important
one.

> > And it's not a good idea to distribute the libraries seperately.
> 
> it's neither smart nor good to deploy apps bundled
> with a complete operating system. period.
> 

Um...

> > Or put them in the Windows system directory.  Too much junk gets put there 
> > already due to years and years of poor programming, careless authors, 
> > indifferent programmers, and Microsoft's encouragement.
> 
> precisely, and every app wants to use their 'personal'
> version of lib whatever, but that's a windows issue,
> nothing which should concern QEMU ...
> 

Except it already does.

> 
> best,
> Herbert
> 

-- 
Infinite complexity begets infinite beauty.
Infinite precision begets infinite perfection.

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [Qemu-devel] quick gtk2.c update
  2005-06-21 23:58                               ` Jim C. Brown
  2005-06-22  4:14                                 ` jeebs
  2005-06-22  9:16                                 ` Jernej Simončič
@ 2005-06-22 13:17                                 ` Jim C. Brown
  2005-06-22 18:36                                   ` Jim C. Brown
  2005-06-22 18:53                                   ` Jim C. Brown
  2005-06-22 13:22                                 ` Jim C. Brown
  3 siblings, 2 replies; 59+ messages in thread
From: Jim C. Brown @ 2005-06-22 13:17 UTC (permalink / raw)
  To: jeebs; +Cc: qemu-devel

On Tue, Jun 21, 2005 at 07:58:14PM -0400, Jim C. Brown wrote:
> Well, no, that isn't it. The keymap files are based on X11 keycodes, so even if
> you could use this option it wouldn't work at all.
> 

More digging around in sdl.c revealed that SDL on Linux returns X11 keycodes
as GTK on Linux does, while on Windows SDL returns the raw scan code.

> I know the offending function. This is the culprit:
> 
> static uint8_t gtk2_keyevent_to_keycode(const GdkEventKey *ev)
> 
> Apparently, that does not work for win32 gtk.
> 
> In fact, that is apparently the Windows virtual key code, not the raw scancode.
> Hence the funny characters. The good news is that this is an easy fix.
> 

I've cleaned up the code a little bit, and attached a new gtk2.c to this email.

> What I really need is a Win32
> programmer to proofread this, make sure I got it right.
> 

Since no Win32 person on this list or in the qemu irc channel offered to help me,
I can not even guarrentee this will compile. And if it does compile, it is possible
that keys will not work right due to lost of information due to casting (this is
unlikely as all scancodes can be represented as a single byte, and it seems all
Windows virtual key codes can be represented in at least two bytes).

Still, I work with what I have to go on. Try this gtk2.c and report any errors
(be they compile errors or runtime errors or keyboard problems). Your help is
always greatly appreciated.


-- 
Infinite complexity begets infinite beauty.
Infinite precision begets infinite perfection.

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [Qemu-devel] quick gtk2.c update
  2005-06-21 23:58                               ` Jim C. Brown
                                                   ` (2 preceding siblings ...)
  2005-06-22 13:17                                 ` Jim C. Brown
@ 2005-06-22 13:22                                 ` Jim C. Brown
  3 siblings, 0 replies; 59+ messages in thread
From: Jim C. Brown @ 2005-06-22 13:22 UTC (permalink / raw)
  To: jeebs; +Cc: qemu-devel

[-- Attachment #1: Type: text/plain, Size: 1538 bytes --]

On Tue, Jun 21, 2005 at 07:58:14PM -0400, Jim C. Brown wrote:
> Well, no, that isn't it. The keymap files are based on X11 keycodes, so even if
> you could use this option it wouldn't work at all.
> 

More digging around in sdl.c revealed that SDL on Linux returns X11 keycodes
as GTK on Linux does, while on Windows SDL returns the raw scan code.

> I know the offending function. This is the culprit:
> 
> static uint8_t gtk2_keyevent_to_keycode(const GdkEventKey *ev)
> 
> Apparently, that does not work for win32 gtk.
> 
> In fact, that is apparently the Windows virtual key code, not the raw scancode.
> Hence the funny characters. The good news is that this is an easy fix.
> 

I've cleaned up the code a little bit, and attached a new gtk2.c to this email.

> What I really need is a Win32
> programmer to proofread this, make sure I got it right.
> 

Since no Win32 person on this list or in the qemu irc channel offered to help me,
I can not even guarrentee this will compile. And if it does compile, it is possible
that keys will not work right due to lost of information due to casting (this is
unlikely as all scancodes can be represented as a single byte, and it seems all
Windows virtual key codes can be represented in at least two bytes).

Still, I work with what I have to go on. Try this gtk2.c and report any errors
(be they compile errors or runtime errors or keyboard problems). Your help is
always greatly appreciated.


-- 
Infinite complexity begets infinite beauty.
Infinite precision begets infinite perfection.

[-- Attachment #2: gtk2.c --]
[-- Type: text/plain, Size: 21769 bytes --]

/*
 * QEMU GTK2 display driver
 * based on SDL driver by Fabrice
 * 
 * Copyright (c) 2005 Jim Brown
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
#include "vl.h"

#include <gtk/gtk.h>
#include <gdk/gdk.h>

#include "fullscreen.h"

/* define our own bitshift enums to allow qemugtk to know difference between left and right alt - something gtk doesnt provide in its modifiers mask. this uses qemu's own modifier_state[] map in order to guess correctly */
typedef enum
{
	gtkshiftleft = 1 << 0,
	gtkshiftright = 1 << 1,
	gtkcontrolleft = 1 << 2,
	gtkcontrolright = 1 << 3,
	gtkaltleft = 1 << 4,
	gtkaltright = 1 << 5,
	gtkcapslock = 1 << 6
} gtk2keymod;


static GtkWidget *screen;
static GdkImage *image=NULL;
static GdkCursor *invisible_cursor;
static int ox = 0, oy = 0;
static int gui_grab; /* if true, all keyboard/mouse events are grabbed */
static int last_vm_running;
static int gui_saved_grab;
static int gui_fullscreen;
static int gui_key_modifier_pressed;
static int gui_keysym;
static int gui_fullscreen_initial_grab;
static int gui_grab_code = gtkaltleft | gtkcontrolleft;
static uint8_t modifiers_state[256];
static unsigned int cw, ch;
static gint cx, cy;

static gboolean gtk2_expose(GtkWidget *wid, GdkEventExpose *event)
{
    gdk_draw_image(wid->window, wid->style->fg_gc[GTK_WIDGET_STATE(wid)], image, event->area.x, event->area.y, event->area.x, event->area.y, event->area.width, event->area.height);
    return TRUE;
}

static void gtk2_update(DisplayState *ds, int x, int y, int w, int h)
{
    //    printf("updating x=%d y=%d w=%d h=%d\n", x, y, w, h);
    GdkEventExpose ev;
    ev.area.x = x;
    ev.area.y = y;
    ev.area.width = w;
    ev.area.height = h;
    gtk2_expose(screen, &ev);
}

static void gtk2_resize(DisplayState *ds, int w, int h)
{

    //    printf(" resizing to %d %d\n", w, h);

    if (gui_fullscreen)
    {
	if (cw != w || ch != h)
	    fullscreen_switch(cx, cy, w, h); /* changing video modes */
	//gtk_window_fullscreen(GTK_WINDOW(screen));
    }
    else
    {
	//gtk_window_unfullscreen(GTK_WINDOW(screen));
    }

    cw = w; ch = h;

    if (image)
	 g_object_unref(image);

/* gdk_visual_get_best_with_depth() ??? but then how to paint onto window? */
    image = gdk_image_new(GDK_IMAGE_NORMAL, gdk_visual_get_system(), w, h);
    gdk_image_set_colormap(image, gdk_colormap_get_system());

    gtk_window_set_default_size(GTK_WINDOW(screen), w, h);
    gtk_widget_set_size_request(screen, w, h);
    gtk_window_resize(GTK_WINDOW(screen), w, h);

    ds->data = image->mem;
    ds->linesize = image->bpl;
    ds->depth = image->bits_per_pixel;
    ds->width = w;
    ds->height = h;
    gtk2_update(ds, 0, 0, w, h);
}

/* generic keyboard conversion */

#include "gdk_keysym.h"
#include "keymaps.c"

static kbd_layout_t *kbd_layout = NULL;

static uint8_t gtk2_keyevent_to_keycode_generic(const GdkEventKey *ev)
{
    int keysym;
    /* workaround for X11+SDL bug with AltGR - is it still needed for Gtk2? */
    keysym = ev->keyval;
    if (keysym == 0 && ev->hardware_keycode == 113)
	keysym = GDK_Mode_switch;
    return keysym2scancode(kbd_layout, keysym);
}

/* specific keyboard conversions from scan codes */

#if defined(_WIN32)

static UINT vk2scan(UINT vk)
{
	static HKL layout=GetKeyboardLayout(0);
	return MapVirtualKeyEx(vk,0,layout);
}
static uint8_t gtk2_keyevent_to_keycode(const GdkEventKey *ev)
{   
    return (uint8_t)vk2scan((UINT)(ev->hardware_keycode));
}

#else

static const uint8_t x_keycode_to_pc_keycode[61] = {
   0xc7,      /*  97  Home   */
   0xc8,      /*  98  Up     */
   0xc9,      /*  99  PgUp   */
   0xcb,      /* 100  Left   */
   0x4c,        /* 101  KP-5   */
   0xcd,      /* 102  Right  */
   0xcf,      /* 103  End    */
   0xd0,      /* 104  Down   */
   0xd1,      /* 105  PgDn   */
   0xd2,      /* 106  Ins    */
   0xd3,      /* 107  Del    */
   0x9c,      /* 108  Enter  */
   0x9d,      /* 109  Ctrl-R */
   0x0,       /* 110  Pause  */
   0xb7,      /* 111  Print  */
   0xb5,      /* 112  Divide */
   0xb8,      /* 113  Alt-R  */
   0xc6,      /* 114  Break  */   
   0x0,         /* 115 */
   0x0,         /* 116 */
   0x0,         /* 117 */
   0x0,         /* 118 */
   0x0,         /* 119 */
   0x70,         /* 120 Hiragana_Katakana */
   0x0,         /* 121 */
   0x0,         /* 122 */
   0x73,         /* 123 backslash */
   0x0,         /* 124 */
   0x0,         /* 125 */
   0x0,         /* 126 */
   0x0,         /* 127 */
   0x0,         /* 128 */
   0x79,         /* 129 Henkan */
   0x0,         /* 130 */
   0x7b,         /* 131 Muhenkan */
   0x0,         /* 132 */
   0x7d,         /* 133 Yen */
   0x0,         /* 134 */
   0x0,         /* 135 */
   0x47,         /* 136 KP_7 */
   0x48,         /* 137 KP_8 */
   0x49,         /* 138 KP_9 */
   0x4b,         /* 139 KP_4 */
   0x4c,         /* 140 KP_5 */
   0x4d,         /* 141 KP_6 */
   0x4f,         /* 142 KP_1 */
   0x50,         /* 143 KP_2 */
   0x51,         /* 144 KP_3 */
   0x52,         /* 145 KP_0 */
   0x53,         /* 146 KP_. */
   0x47,         /* 147 KP_HOME */
   0x48,         /* 148 KP_UP */
   0x49,         /* 149 KP_PgUp */
   0x4b,         /* 150 KP_Left */
   0x4c,         /* 151 KP_ */
   0x4d,         /* 152 KP_Right */
   0x4f,         /* 153 KP_End */
   0x50,         /* 154 KP_Down */
   0x51,         /* 155 KP_PgDn */
   0x52,         /* 156 KP_Ins */
   0x53,         /* 157 KP_Del */
};

static uint8_t gtk2_keyevent_to_keycode(const GdkEventKey *ev)
{
    int keycode;

    keycode = ev->hardware_keycode;

    if (keycode < 9) {
	keycode = 0;
    } else if (keycode < 97) {
	keycode -= 8; /* just an offset */
    } else if (keycode < 158) {
	/* use conversion table */
	keycode = x_keycode_to_pc_keycode[keycode - 97];
    } else {
	keycode = 0;
    }
    return keycode;
}

#endif

static void reset_keys(void)
{
    int i;
    for(i = 0; i < 256; i++) {
	if (modifiers_state[i]) {
	    if (i & 0x80)
		kbd_put_keycode(0xe0);
	    kbd_put_keycode(i | 0x80);
	    modifiers_state[i] = 0;
	}
    }
}

/* convert GDK modifiers and invoke ugly hack to distinguish
between left and right shift/control/alt */
static guint gtk2_GetModState(const GdkEventKey *ev)
{
	guint key = 0, keyval = ev->keyval, state = ev->state;
	switch(keyval)
	{
		case GDK_Shift_L:
			if (ev->type != GDK_KEY_RELEASE)
				key |= gtkshiftleft;
			keyval = 1;
			break;
		case GDK_Shift_R:
			if (ev->type != GDK_KEY_RELEASE)
				key |= gtkshiftright;
			keyval = 1;
			break;
		case GDK_Control_L:
			if (ev->type != GDK_KEY_RELEASE)
				key |= gtkcontrolleft;
			keyval = 2;
			break;
		case GDK_Control_R:
			if (ev->type != GDK_KEY_RELEASE)
				key |= gtkcontrolright;
			keyval = 2;
			break;
		case GDK_Alt_L:
			if (ev->type != GDK_KEY_RELEASE)
				key |= gtkaltleft;
			keyval = 3;
			break;
		case GDK_Alt_R:
			if (ev->type != GDK_KEY_RELEASE)
				key |= gtkaltright;
			keyval = 3;
			break;
		case GDK_Caps_Lock:
			if (ev->type != GDK_KEY_RELEASE)
				key |= gtkcapslock;
			keyval = 4;
			break;
		default:
			keyval = 0;
			break;
	}
	if (keyval != 1 && (state & GDK_SHIFT_MASK))
	{
		if (modifiers_state[0x2a])
			key |= gtkshiftleft;
		if (modifiers_state[0x36])
			key |= gtkshiftright;
	}
	if (keyval != 2 && (state & GDK_CONTROL_MASK))
	{
		if (modifiers_state[0x1d])
			key |= gtkcontrolleft;
		if (modifiers_state[0x9d])
			key |= gtkcontrolright;
	}
	if (keyval != 3 && (state & GDK_MOD1_MASK)) /* fixme: need to do a check to make sure that alt is mapped to GDK_MOD1_MASK in the GDK_Keymap */
	{
		if (modifiers_state[0x38])
			key |= gtkaltleft;
		if (modifiers_state[0xb8])
			key |= gtkaltright;
	}
	if (keyval != 4 && (state & GDK_LOCK_MASK))
		key |= gtkcapslock;
	return key;
}

static void gtk2_process_key(GdkEventKey *ev)
{
    int keycode, v;

    if (ev->keyval == GDK_Pause) {
	/* specific case */
	v = 0;
	if (ev->type == GDK_KEY_RELEASE)
	    v |= 0x80;
	kbd_put_keycode(0xe1);
	kbd_put_keycode(0x1d | v);
	kbd_put_keycode(0x45 | v);
	return;
    }

    if (kbd_layout) {
	keycode = gtk2_keyevent_to_keycode_generic(ev);
    } else {
	keycode = gtk2_keyevent_to_keycode(ev);
    }

    switch(keycode) {
    case 0x00:
	/* sent when leaving window: reset the modifiers state */
	reset_keys();
	return;
    case 0x2a:                          /* Left Shift */
    case 0x36:                          /* Right Shift */
    case 0x1d:                          /* Left CTRL */
    case 0x9d:                          /* Right CTRL */
    case 0x38:                          /* Left ALT */
    case 0xb8:                         /* Right ALT */
	if (ev->type == GDK_KEY_RELEASE)
	    modifiers_state[keycode] = 0;
	else
	    modifiers_state[keycode] = 1;
	break;
    case 0x45: /* num lock */
    case 0x3a: /* caps lock */
	/* GTK does send the key up event, so we dont generate it */
	/*kbd_put_keycode(keycode);
	kbd_put_keycode(keycode | 0x80);
	return;*/
	break;
    }

    /* now send the key code */
    if (keycode & 0x80)
	kbd_put_keycode(0xe0);
    if (ev->type == GDK_KEY_RELEASE)
	kbd_put_keycode(keycode | 0x80);
    else
	kbd_put_keycode(keycode & 0x7f);
}

static void gtk2_update_caption(void)
{
    char buf[1024];
    strcpy(buf, "QEMU");
    if (!vm_running) {
	strcat(buf, " [Stopped]");
    }
    if (gui_grab) {
	strcat(buf, " - Press Ctrl-Alt to exit grab");
    }
    gtk_window_set_title(GTK_WINDOW(screen), buf);
}

/* what a nasty hack. this should be a part of the GDK, not external!!! */
#include "gdk_set_window_pointer.c"

static void gtk2_grab_start(void)
{
    gint y;
    guint events;
    GdkModifierType state; /* dummy var */
    events = GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_SCROLL_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK;
    y = gdk_pointer_grab(screen->window, TRUE, events, screen->window, invisible_cursor, GDK_CURRENT_TIME);
    if (y)
	printf("GTK Warning - pointer grab failed!\n");
    y = gdk_keyboard_grab(screen->window, TRUE, GDK_CURRENT_TIME);
    if (y)
	printf("GTK Warning - keyboard grab failed!\n");
    /* do a dummy read to avoid moving mouse - set ox and oy to stay in sync */
    gdk_window_get_pointer(screen->window, &ox, &oy, &state);
    gui_grab = 1;
    gtk2_update_caption();
}

static void gtk2_grab_end(void)
{
    gdk_pointer_ungrab(GDK_CURRENT_TIME);
    gdk_keyboard_ungrab(GDK_CURRENT_TIME);
    gdk_window_set_pointer(screen->window, cx, cy);
    gui_grab = 0;
    gtk2_update_caption();
}

static gboolean gtk2_send_mouse_scroll(GtkWidget *wid, GdkEventScroll *ev)
{
    int x, y, dx, dy, dz, state, buttons;
    if (gui_grab)
    {

    x = ev->x;
    y = ev->y;
    state = ev->state;
    buttons = 0;
    dx = x - ox;
    dy = y - oy;
    ox = x;
    oy = y;
    buttons = 0;
    if ((state & GDK_BUTTON1_MASK))
	buttons |= MOUSE_EVENT_LBUTTON;
    if ((state & GDK_BUTTON3_MASK))
	buttons |= MOUSE_EVENT_RBUTTON;
    if ((state & GDK_BUTTON2_MASK))
	buttons |= MOUSE_EVENT_MBUTTON;
    /* test wheel - copied from Sebastien Bechet's gtk.c */
    dz = 0;
    if ((state & GDK_BUTTON4_MASK) || ev->direction == GDK_SCROLL_UP)
	dz--;
    if ((state & GDK_BUTTON5_MASK) || ev->direction == GDK_SCROLL_DOWN)
	dz++;
    kbd_mouse_event(dx, dy, dz, buttons);

    }
    return TRUE;
}

static gboolean gtk2_send_mouse_button(GtkWidget *wid, GdkEventButton *ev)
{
    int x, y, dx, dy, dz, state, buttons;
    if (ev->type == GDK_2BUTTON_PRESS || ev->type == GDK_3BUTTON_PRESS)
	return TRUE; /* double or triple click - superflurious - ignore */
    if (gui_grab)
    {

    x = ev->x;
    y = ev->y;
    state = ev->state;
    buttons = 0;
    dx = x - ox;
    dy = y - oy;
    ox = x;
    oy = y;
    buttons = 0;
    if ((state & GDK_BUTTON1_MASK) || ev->button == 1)
	buttons |= MOUSE_EVENT_LBUTTON;
    if ((state & GDK_BUTTON3_MASK) || ev->button == 3)
	buttons |= MOUSE_EVENT_RBUTTON;
    if ((state & GDK_BUTTON2_MASK) || ev->button == 2)
	buttons |= MOUSE_EVENT_MBUTTON;
    /* XXX: test wheel */
    dz = 0;
    if ((state & GDK_BUTTON4_MASK) || ev->button == 4)
	dz--;
    if ((state & GDK_BUTTON5_MASK) || ev->button == 5)
	dz++;
    kbd_mouse_event(dx, dy, dz, buttons);

    }
    else
    {

    if (ev->button == 1 && ev->type == GDK_BUTTON_PRESS)
    {
	/* start grabbing all events */
	gtk2_grab_start();
    }

    }
    return TRUE;
}

static gboolean gtk2_send_mouse_move(GtkWidget *wid, GdkEventMotion *ev)
{
    int x, y, dx, dy, dz, state, buttons;
    if (gui_grab)
    {

    if (ev->is_hint)
    {
	gdk_window_get_pointer(ev->window, &x, &y, (GdkModifierType*)&state);
    }
    else
    {
	x = ev->x;
	y = ev->y;
	state = ev->state;
    }
    dx = x - ox;
    dy = y - oy;
    if ((dx == 0) && (dy == 0)) return TRUE; // prevent infinite looping - 2.6.X
    ox = x;
    oy = y;
    buttons = 0;
    if (state & GDK_BUTTON1_MASK)
	buttons |= MOUSE_EVENT_LBUTTON;
    if (state & GDK_BUTTON3_MASK)
	buttons |= MOUSE_EVENT_RBUTTON;
    if (state & GDK_BUTTON2_MASK)
	buttons |= MOUSE_EVENT_MBUTTON;
    /* XXX: test wheel */
    dz = 0;
    if (state & GDK_BUTTON4_MASK)
	dz--;
    if (state & GDK_BUTTON5_MASK)
	dz++;

    /* wrap the x,y coordinates back onto the window */
    if (ev->x <= (cw/4))
	x = ((3*cw/4)-1);
    if (ev->y <= (ch/4))
	y = ((3*ch/4)-1);
    if (ev->x >= (3*cw/4))
	x = (cw/4)+1;
    if (ev->y >= (3*ch/4))
	y = (ch/4)+1;

    /* make internal mouse move invisible */
    ox = x;
    oy = y;

    gdk_window_set_pointer(screen->window, (gint)x, (gint)y);

    kbd_mouse_event(dx, dy, dz, buttons);

    }
    return TRUE;
}

static void toggle_full_screen(DisplayState *ds)
{
    gui_fullscreen = !gui_fullscreen;
    gtk2_resize(ds, image->width, image->height);
    if (gui_fullscreen) {
	gui_saved_grab = gui_grab;
	gtk2_grab_start();
	gtk_window_get_position(GTK_WINDOW(screen), &cx, &cy);
	/* ignore window manager decorations when in fullscreen mode */
	gtk_window_set_gravity(GTK_WINDOW(screen), GDK_GRAVITY_STATIC);
	gtk_window_move(GTK_WINDOW(screen), 0, 0);
	fullscreen_switch(cx, cy, ds->width, ds->height);
    } else {
	fullscreen_reset();
	gtk_window_set_gravity(GTK_WINDOW(screen), GDK_GRAVITY_NORTH_WEST);
	gtk_window_move(GTK_WINDOW(screen), cx, cy);
	if (!gui_saved_grab)
	    gtk2_grab_end();
    }
    vga_invalidate_display();
    vga_update_display();
}

static gboolean gtk2_key_press(GtkWidget *wid, GdkEventKey *ev, DisplayState *ds)
{
	int mod_state;
	    if (ev->type == GDK_KEY_PRESS) {
		mod_state = (gtk2_GetModState(ev) & (int)gui_grab_code) == (int)gui_grab_code;
		gui_key_modifier_pressed = mod_state;
		if (gui_key_modifier_pressed) {
		    int keycode;
		    keycode = gtk2_keyevent_to_keycode(ev);
		    switch(keycode) {
		    case 0x21: /* 'f' key on US keyboard */
			toggle_full_screen(ds);
			gui_keysym = 1;
			break;
		    case 0x02 ... 0x0a: /* '1' to '9' keys */ 
			console_select(keycode - 0x02);
			if (is_active_console(vga_console)) {
			    /* tell the vga console to redisplay itself */
			    vga_invalidate_display();
			} else {
			    /* display grab if going to a text console */
			    if (gui_grab)
				gtk2_grab_end();
			}
			gui_keysym = 1;
			break;
		    default:
			break;
		    }
		} else if (!is_active_console(vga_console)) {
		    int keysym;
		    keysym = 0;
		    if (ev->state & GDK_CONTROL_MASK) {
			switch(ev->keyval) {
			case GDK_Up: keysym = QEMU_KEY_CTRL_UP; break;
			case GDK_Down: keysym = QEMU_KEY_CTRL_DOWN; break;
			case GDK_Left: keysym = QEMU_KEY_CTRL_LEFT; break;
			case GDK_Right: keysym = QEMU_KEY_CTRL_RIGHT; break;
			case GDK_Home: keysym = QEMU_KEY_CTRL_HOME; break;
			case GDK_End: keysym = QEMU_KEY_CTRL_END; break;
			case GDK_Page_Up: keysym = QEMU_KEY_CTRL_PAGEUP; break;
			case GDK_Page_Down: keysym = QEMU_KEY_CTRL_PAGEDOWN; break;
			default: break;
			}
		    } else {
			switch(ev->keyval) {
			case GDK_Up: keysym = QEMU_KEY_UP; break;
			case GDK_Down: keysym = QEMU_KEY_DOWN; break;
			case GDK_Left: keysym = QEMU_KEY_LEFT; break;
			case GDK_Right: keysym = QEMU_KEY_RIGHT; break;
			case GDK_Home: keysym = QEMU_KEY_HOME; break;
			case GDK_End: keysym = QEMU_KEY_END; break;
			case GDK_Page_Up: keysym = QEMU_KEY_PAGEUP; break;
			case GDK_Page_Down: keysym = QEMU_KEY_PAGEDOWN; break;
			case GDK_BackSpace: keysym = QEMU_KEY_BACKSPACE; break;
			case GDK_Delete: keysym = QEMU_KEY_DELETE; break;
			default: break;
			}
		    }
		    if (keysym) {
			kbd_put_keysym(keysym);
		    } /*else if (ev->key.keysym.unicode != 0) {
			kbd_put_keysym(ev->key.keysym.unicode);
		    }*/
		}
	    } else if (ev->type == GDK_KEY_RELEASE) {
		mod_state = (gtk2_GetModState(ev) & gui_grab_code);
		if (!mod_state) {
		    if (gui_key_modifier_pressed) {
			if (gui_keysym == 0) {
			    /* exit/enter grab if pressing Ctrl-Alt */
			    if (!gui_grab)
				gtk2_grab_start();
			    else
				gtk2_grab_end();
			    /* SDL does not send back all the
			       modifiers key, so we must correct it */
			    reset_keys();
			    return TRUE;
			}
			gui_key_modifier_pressed = 0;
			gui_keysym = 0;
		    }
		}
	    }
	    if (is_active_console(vga_console)) 
		gtk2_process_key(ev);
	return TRUE;
}

static void gtk2_refresh(DisplayState *ds)
{
    if (last_vm_running != vm_running) {
	last_vm_running = vm_running;
	gtk2_update_caption();
    }
    if (ds->data != image->mem)
    {
	ds->data = image->mem;
    }

    if (is_active_console(vga_console))                                         
	vga_update_display();                                                   
    while (gtk_events_pending())
	gtk_main_iteration();
}

static void gtk2_cleanup(void) 
{
    gtk_main_quit();
    fullscreen_cleanup();
}

static gboolean gtk2_deletewin(void)
{
    /* signal qemu that its time to shut itself off - this is the place that we hook to trap attempts to close the main qemu window */
    qemu_system_shutdown_request();
    return FALSE;
    return TRUE; /* dont close the window right away! give qemu time to think */
}

static void gtk2_destroy(void)
{
    /* ideally we would call a hook here so qemu could clean itself up */
    gtk2_cleanup();
}

void gtk2_display_init(DisplayState *ds, int full_screen)
{
    int events;

#if defined(__APPLE__)
    /* always use generic keymaps */
    if (!keyboard_layout)
	keyboard_layout = "en-us";
#endif
    if(keyboard_layout) {
	kbd_layout = init_keyboard_layout(keyboard_layout);
	if (!kbd_layout)
	    exit(1);
    }

    if (!gtk_init_check (0,NULL))
    {
	fprintf(stderr, "Could not load GTK\n");
	exit(0);
    }
    fullscreen_init();

/* note: adding GDK_DRAG_* and GDK_DROP_* would provide a mechanism for supporting drag and drop between host and guest */
    events = GDK_EXPOSURE_MASK | GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK | GDK_FOCUS_CHANGE_MASK | GDK_SCROLL_MASK | GDK_STRUCTURE_MASK;

    screen = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_widget_set_events(screen, events);
    gtk_window_set_default_size(GTK_WINDOW(screen), 720, 400);
    gtk_widget_set_size_request(screen, 720, 400);

    g_signal_connect(G_OBJECT(screen), "delete_event", G_CALLBACK(gtk2_deletewin), NULL);
    g_signal_connect(G_OBJECT(screen), "destroy", G_CALLBACK(gtk2_destroy), NULL);
    gtk_container_set_border_width(GTK_CONTAINER(screen), 10);

    gtk_signal_connect(GTK_OBJECT(screen), "expose_event", (GtkSignalFunc) gtk2_expose, NULL);
    gtk_signal_connect(GTK_OBJECT(screen), "motion_notify_event", (GtkSignalFunc) gtk2_send_mouse_move, NULL);
    gtk_signal_connect(GTK_OBJECT(screen), "button_press_event", (GtkSignalFunc) gtk2_send_mouse_button, NULL);
    gtk_signal_connect(GTK_OBJECT(screen), "button_release_event", (GtkSignalFunc) gtk2_send_mouse_button, NULL);
    gtk_signal_connect(GTK_OBJECT(screen), "scroll_event", (GtkSignalFunc) gtk2_send_mouse_scroll, NULL);
    gtk_signal_connect(GTK_OBJECT(screen), "key_press_event", (GtkSignalFunc) gtk2_key_press, ds);
    gtk_signal_connect(GTK_OBJECT(screen), "key_release_event", (GtkSignalFunc) gtk2_key_press, ds);

    ds->dpy_update = gtk2_update;
    ds->dpy_resize = gtk2_resize;
    ds->dpy_refresh = gtk2_refresh;

    gchar nullpixdata[1] = { 0 };
    GdkColor nullcolor = { 0, 0, 0, 0 };
    GdkPixmap *invis = gdk_bitmap_create_from_data(screen->window, nullpixdata, 1, 1);
    invisible_cursor = gdk_cursor_new_from_pixmap(invis, invis, &nullcolor, &nullcolor, 0, 0);

    gtk2_resize(ds, 720, 400);
    gtk2_update_caption();
    gui_grab = 0;

    gtk_window_set_policy(GTK_WINDOW(screen), FALSE, FALSE, FALSE);
    gtk_widget_show(screen);
    if (full_screen) {
	gui_fullscreen = 1;
	gui_fullscreen_initial_grab = 1;
	gtk2_grab_start();
    }
}

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [Qemu-devel] quick gtk2.c update
  2005-06-22 13:17                                 ` Jim C. Brown
@ 2005-06-22 18:36                                   ` Jim C. Brown
  2005-06-22 18:53                                   ` Jim C. Brown
  1 sibling, 0 replies; 59+ messages in thread
From: Jim C. Brown @ 2005-06-22 18:36 UTC (permalink / raw)
  To: jeebs; +Cc: qemu-devel

On Wed, Jun 22, 2005 at 09:17:23AM -0400, Jim C. Brown wrote:
> Still, I work with what I have to go on. Try this gtk2.c and report any errors
> (be they compile errors or runtime errors or keyboard problems). Your help is
> always greatly appreciated.
> 

This version of gtk2.c includes the right header file (at least according to MSDN).

However, after some deeper examination of the issue, it looks like it would be
better to convert the virtual key codes to the us keyboard scancodes via some
sort of keymap (similar to the X11 case).

-- 
Infinite complexity begets infinite beauty.
Infinite precision begets infinite perfection.

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [Qemu-devel] quick gtk2.c update
  2005-06-22 13:17                                 ` Jim C. Brown
  2005-06-22 18:36                                   ` Jim C. Brown
@ 2005-06-22 18:53                                   ` Jim C. Brown
  2005-06-22 20:59                                     ` Jim C. Brown
  1 sibling, 1 reply; 59+ messages in thread
From: Jim C. Brown @ 2005-06-22 18:53 UTC (permalink / raw)
  To: jeebs; +Cc: qemu-devel

[-- Attachment #1: Type: text/plain, Size: 737 bytes --]

I seem to be having problems sending attachments. Hopefully this email
will get through this time.

On Wed, Jun 22, 2005 at 09:17:23AM -0400, Jim C. Brown wrote:
> Still, I work with what I have to go on. Try this gtk2.c and report any errors
> (be they compile errors or runtime errors or keyboard problems). Your help is
> always greatly appreciated.
> 

This version of gtk2.c includes the right header file (at least according to MSDN).

However, after some deeper examination of the issue, it looks like it would be
better to convert the virtual key codes to the us keyboard scancodes via some
sort of keymap (similar to the X11 case).

-- 
Infinite complexity begets infinite beauty.
Infinite precision begets infinite perfection.

[-- Attachment #2: gtk2.c --]
[-- Type: text/plain, Size: 21791 bytes --]

/*
 * QEMU GTK2 display driver
 * based on SDL driver by Fabrice
 * 
 * Copyright (c) 2005 Jim Brown
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
#include "vl.h"

#include <gtk/gtk.h>
#include <gdk/gdk.h>

#include "fullscreen.h"

/* define our own bitshift enums to allow qemugtk to know difference between left and right alt - something gtk doesnt provide in its modifiers mask. this uses qemu's own modifier_state[] map in order to guess correctly */
typedef enum
{
	gtkshiftleft = 1 << 0,
	gtkshiftright = 1 << 1,
	gtkcontrolleft = 1 << 2,
	gtkcontrolright = 1 << 3,
	gtkaltleft = 1 << 4,
	gtkaltright = 1 << 5,
	gtkcapslock = 1 << 6
} gtk2keymod;


static GtkWidget *screen;
static GdkImage *image=NULL;
static GdkCursor *invisible_cursor;
static int ox = 0, oy = 0;
static int gui_grab; /* if true, all keyboard/mouse events are grabbed */
static int last_vm_running;
static int gui_saved_grab;
static int gui_fullscreen;
static int gui_key_modifier_pressed;
static int gui_keysym;
static int gui_fullscreen_initial_grab;
static int gui_grab_code = gtkaltleft | gtkcontrolleft;
static uint8_t modifiers_state[256];
static unsigned int cw, ch;
static gint cx, cy;

static gboolean gtk2_expose(GtkWidget *wid, GdkEventExpose *event)
{
    gdk_draw_image(wid->window, wid->style->fg_gc[GTK_WIDGET_STATE(wid)], image, event->area.x, event->area.y, event->area.x, event->area.y, event->area.width, event->area.height);
    return TRUE;
}

static void gtk2_update(DisplayState *ds, int x, int y, int w, int h)
{
    //    printf("updating x=%d y=%d w=%d h=%d\n", x, y, w, h);
    GdkEventExpose ev;
    ev.area.x = x;
    ev.area.y = y;
    ev.area.width = w;
    ev.area.height = h;
    gtk2_expose(screen, &ev);
}

static void gtk2_resize(DisplayState *ds, int w, int h)
{

    //    printf(" resizing to %d %d\n", w, h);

    if (gui_fullscreen)
    {
	if (cw != w || ch != h)
	    fullscreen_switch(cx, cy, w, h); /* changing video modes */
	//gtk_window_fullscreen(GTK_WINDOW(screen));
    }
    else
    {
	//gtk_window_unfullscreen(GTK_WINDOW(screen));
    }

    cw = w; ch = h;

    if (image)
	 g_object_unref(image);

/* gdk_visual_get_best_with_depth() ??? but then how to paint onto window? */
    image = gdk_image_new(GDK_IMAGE_NORMAL, gdk_visual_get_system(), w, h);
    gdk_image_set_colormap(image, gdk_colormap_get_system());

    gtk_window_set_default_size(GTK_WINDOW(screen), w, h);
    gtk_widget_set_size_request(screen, w, h);
    gtk_window_resize(GTK_WINDOW(screen), w, h);

    ds->data = image->mem;
    ds->linesize = image->bpl;
    ds->depth = image->bits_per_pixel;
    ds->width = w;
    ds->height = h;
    gtk2_update(ds, 0, 0, w, h);
}

/* generic keyboard conversion */

#include "gdk_keysym.h"
#include "keymaps.c"

static kbd_layout_t *kbd_layout = NULL;

static uint8_t gtk2_keyevent_to_keycode_generic(const GdkEventKey *ev)
{
    int keysym;
    /* workaround for X11+SDL bug with AltGR - is it still needed for Gtk2? */
    keysym = ev->keyval;
    if (keysym == 0 && ev->hardware_keycode == 113)
	keysym = GDK_Mode_switch;
    return keysym2scancode(kbd_layout, keysym);
}

/* specific keyboard conversions from scan codes */

#if defined(_WIN32)

#include <windows.h>

static UINT vk2scan(UINT vk)
{
	static HKL layout=GetKeyboardLayout(0);
	return MapVirtualKeyEx(vk,0,layout);
}
static uint8_t gtk2_keyevent_to_keycode(const GdkEventKey *ev)
{   
    return (uint8_t)vk2scan((UINT)(ev->hardware_keycode));
}

#else

static const uint8_t x_keycode_to_pc_keycode[61] = {
   0xc7,      /*  97  Home   */
   0xc8,      /*  98  Up     */
   0xc9,      /*  99  PgUp   */
   0xcb,      /* 100  Left   */
   0x4c,        /* 101  KP-5   */
   0xcd,      /* 102  Right  */
   0xcf,      /* 103  End    */
   0xd0,      /* 104  Down   */
   0xd1,      /* 105  PgDn   */
   0xd2,      /* 106  Ins    */
   0xd3,      /* 107  Del    */
   0x9c,      /* 108  Enter  */
   0x9d,      /* 109  Ctrl-R */
   0x0,       /* 110  Pause  */
   0xb7,      /* 111  Print  */
   0xb5,      /* 112  Divide */
   0xb8,      /* 113  Alt-R  */
   0xc6,      /* 114  Break  */   
   0x0,         /* 115 */
   0x0,         /* 116 */
   0x0,         /* 117 */
   0x0,         /* 118 */
   0x0,         /* 119 */
   0x70,         /* 120 Hiragana_Katakana */
   0x0,         /* 121 */
   0x0,         /* 122 */
   0x73,         /* 123 backslash */
   0x0,         /* 124 */
   0x0,         /* 125 */
   0x0,         /* 126 */
   0x0,         /* 127 */
   0x0,         /* 128 */
   0x79,         /* 129 Henkan */
   0x0,         /* 130 */
   0x7b,         /* 131 Muhenkan */
   0x0,         /* 132 */
   0x7d,         /* 133 Yen */
   0x0,         /* 134 */
   0x0,         /* 135 */
   0x47,         /* 136 KP_7 */
   0x48,         /* 137 KP_8 */
   0x49,         /* 138 KP_9 */
   0x4b,         /* 139 KP_4 */
   0x4c,         /* 140 KP_5 */
   0x4d,         /* 141 KP_6 */
   0x4f,         /* 142 KP_1 */
   0x50,         /* 143 KP_2 */
   0x51,         /* 144 KP_3 */
   0x52,         /* 145 KP_0 */
   0x53,         /* 146 KP_. */
   0x47,         /* 147 KP_HOME */
   0x48,         /* 148 KP_UP */
   0x49,         /* 149 KP_PgUp */
   0x4b,         /* 150 KP_Left */
   0x4c,         /* 151 KP_ */
   0x4d,         /* 152 KP_Right */
   0x4f,         /* 153 KP_End */
   0x50,         /* 154 KP_Down */
   0x51,         /* 155 KP_PgDn */
   0x52,         /* 156 KP_Ins */
   0x53,         /* 157 KP_Del */
};

static uint8_t gtk2_keyevent_to_keycode(const GdkEventKey *ev)
{
    int keycode;

    keycode = ev->hardware_keycode;

    if (keycode < 9) {
	keycode = 0;
    } else if (keycode < 97) {
	keycode -= 8; /* just an offset */
    } else if (keycode < 158) {
	/* use conversion table */
	keycode = x_keycode_to_pc_keycode[keycode - 97];
    } else {
	keycode = 0;
    }
    return keycode;
}

#endif

static void reset_keys(void)
{
    int i;
    for(i = 0; i < 256; i++) {
	if (modifiers_state[i]) {
	    if (i & 0x80)
		kbd_put_keycode(0xe0);
	    kbd_put_keycode(i | 0x80);
	    modifiers_state[i] = 0;
	}
    }
}

/* convert GDK modifiers and invoke ugly hack to distinguish
between left and right shift/control/alt */
static guint gtk2_GetModState(const GdkEventKey *ev)
{
	guint key = 0, keyval = ev->keyval, state = ev->state;
	switch(keyval)
	{
		case GDK_Shift_L:
			if (ev->type != GDK_KEY_RELEASE)
				key |= gtkshiftleft;
			keyval = 1;
			break;
		case GDK_Shift_R:
			if (ev->type != GDK_KEY_RELEASE)
				key |= gtkshiftright;
			keyval = 1;
			break;
		case GDK_Control_L:
			if (ev->type != GDK_KEY_RELEASE)
				key |= gtkcontrolleft;
			keyval = 2;
			break;
		case GDK_Control_R:
			if (ev->type != GDK_KEY_RELEASE)
				key |= gtkcontrolright;
			keyval = 2;
			break;
		case GDK_Alt_L:
			if (ev->type != GDK_KEY_RELEASE)
				key |= gtkaltleft;
			keyval = 3;
			break;
		case GDK_Alt_R:
			if (ev->type != GDK_KEY_RELEASE)
				key |= gtkaltright;
			keyval = 3;
			break;
		case GDK_Caps_Lock:
			if (ev->type != GDK_KEY_RELEASE)
				key |= gtkcapslock;
			keyval = 4;
			break;
		default:
			keyval = 0;
			break;
	}
	if (keyval != 1 && (state & GDK_SHIFT_MASK))
	{
		if (modifiers_state[0x2a])
			key |= gtkshiftleft;
		if (modifiers_state[0x36])
			key |= gtkshiftright;
	}
	if (keyval != 2 && (state & GDK_CONTROL_MASK))
	{
		if (modifiers_state[0x1d])
			key |= gtkcontrolleft;
		if (modifiers_state[0x9d])
			key |= gtkcontrolright;
	}
	if (keyval != 3 && (state & GDK_MOD1_MASK)) /* fixme: need to do a check to make sure that alt is mapped to GDK_MOD1_MASK in the GDK_Keymap */
	{
		if (modifiers_state[0x38])
			key |= gtkaltleft;
		if (modifiers_state[0xb8])
			key |= gtkaltright;
	}
	if (keyval != 4 && (state & GDK_LOCK_MASK))
		key |= gtkcapslock;
	return key;
}

static void gtk2_process_key(GdkEventKey *ev)
{
    int keycode, v;

    if (ev->keyval == GDK_Pause) {
	/* specific case */
	v = 0;
	if (ev->type == GDK_KEY_RELEASE)
	    v |= 0x80;
	kbd_put_keycode(0xe1);
	kbd_put_keycode(0x1d | v);
	kbd_put_keycode(0x45 | v);
	return;
    }

    if (kbd_layout) {
	keycode = gtk2_keyevent_to_keycode_generic(ev);
    } else {
	keycode = gtk2_keyevent_to_keycode(ev);
    }

    switch(keycode) {
    case 0x00:
	/* sent when leaving window: reset the modifiers state */
	reset_keys();
	return;
    case 0x2a:                          /* Left Shift */
    case 0x36:                          /* Right Shift */
    case 0x1d:                          /* Left CTRL */
    case 0x9d:                          /* Right CTRL */
    case 0x38:                          /* Left ALT */
    case 0xb8:                         /* Right ALT */
	if (ev->type == GDK_KEY_RELEASE)
	    modifiers_state[keycode] = 0;
	else
	    modifiers_state[keycode] = 1;
	break;
    case 0x45: /* num lock */
    case 0x3a: /* caps lock */
	/* GTK does send the key up event, so we dont generate it */
	/*kbd_put_keycode(keycode);
	kbd_put_keycode(keycode | 0x80);
	return;*/
	break;
    }

    /* now send the key code */
    if (keycode & 0x80)
	kbd_put_keycode(0xe0);
    if (ev->type == GDK_KEY_RELEASE)
	kbd_put_keycode(keycode | 0x80);
    else
	kbd_put_keycode(keycode & 0x7f);
}

static void gtk2_update_caption(void)
{
    char buf[1024];
    strcpy(buf, "QEMU");
    if (!vm_running) {
	strcat(buf, " [Stopped]");
    }
    if (gui_grab) {
	strcat(buf, " - Press Ctrl-Alt to exit grab");
    }
    gtk_window_set_title(GTK_WINDOW(screen), buf);
}

/* what a nasty hack. this should be a part of the GDK, not external!!! */
#include "gdk_set_window_pointer.c"

static void gtk2_grab_start(void)
{
    gint y;
    guint events;
    GdkModifierType state; /* dummy var */
    events = GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_SCROLL_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK;
    y = gdk_pointer_grab(screen->window, TRUE, events, screen->window, invisible_cursor, GDK_CURRENT_TIME);
    if (y)
	printf("GTK Warning - pointer grab failed!\n");
    y = gdk_keyboard_grab(screen->window, TRUE, GDK_CURRENT_TIME);
    if (y)
	printf("GTK Warning - keyboard grab failed!\n");
    /* do a dummy read to avoid moving mouse - set ox and oy to stay in sync */
    gdk_window_get_pointer(screen->window, &ox, &oy, &state);
    gui_grab = 1;
    gtk2_update_caption();
}

static void gtk2_grab_end(void)
{
    gdk_pointer_ungrab(GDK_CURRENT_TIME);
    gdk_keyboard_ungrab(GDK_CURRENT_TIME);
    gdk_window_set_pointer(screen->window, cx, cy);
    gui_grab = 0;
    gtk2_update_caption();
}

static gboolean gtk2_send_mouse_scroll(GtkWidget *wid, GdkEventScroll *ev)
{
    int x, y, dx, dy, dz, state, buttons;
    if (gui_grab)
    {

    x = ev->x;
    y = ev->y;
    state = ev->state;
    buttons = 0;
    dx = x - ox;
    dy = y - oy;
    ox = x;
    oy = y;
    buttons = 0;
    if ((state & GDK_BUTTON1_MASK))
	buttons |= MOUSE_EVENT_LBUTTON;
    if ((state & GDK_BUTTON3_MASK))
	buttons |= MOUSE_EVENT_RBUTTON;
    if ((state & GDK_BUTTON2_MASK))
	buttons |= MOUSE_EVENT_MBUTTON;
    /* test wheel - copied from Sebastien Bechet's gtk.c */
    dz = 0;
    if ((state & GDK_BUTTON4_MASK) || ev->direction == GDK_SCROLL_UP)
	dz--;
    if ((state & GDK_BUTTON5_MASK) || ev->direction == GDK_SCROLL_DOWN)
	dz++;
    kbd_mouse_event(dx, dy, dz, buttons);

    }
    return TRUE;
}

static gboolean gtk2_send_mouse_button(GtkWidget *wid, GdkEventButton *ev)
{
    int x, y, dx, dy, dz, state, buttons;
    if (ev->type == GDK_2BUTTON_PRESS || ev->type == GDK_3BUTTON_PRESS)
	return TRUE; /* double or triple click - superflurious - ignore */
    if (gui_grab)
    {

    x = ev->x;
    y = ev->y;
    state = ev->state;
    buttons = 0;
    dx = x - ox;
    dy = y - oy;
    ox = x;
    oy = y;
    buttons = 0;
    if ((state & GDK_BUTTON1_MASK) || ev->button == 1)
	buttons |= MOUSE_EVENT_LBUTTON;
    if ((state & GDK_BUTTON3_MASK) || ev->button == 3)
	buttons |= MOUSE_EVENT_RBUTTON;
    if ((state & GDK_BUTTON2_MASK) || ev->button == 2)
	buttons |= MOUSE_EVENT_MBUTTON;
    /* XXX: test wheel */
    dz = 0;
    if ((state & GDK_BUTTON4_MASK) || ev->button == 4)
	dz--;
    if ((state & GDK_BUTTON5_MASK) || ev->button == 5)
	dz++;
    kbd_mouse_event(dx, dy, dz, buttons);

    }
    else
    {

    if (ev->button == 1 && ev->type == GDK_BUTTON_PRESS)
    {
	/* start grabbing all events */
	gtk2_grab_start();
    }

    }
    return TRUE;
}

static gboolean gtk2_send_mouse_move(GtkWidget *wid, GdkEventMotion *ev)
{
    int x, y, dx, dy, dz, state, buttons;
    if (gui_grab)
    {

    if (ev->is_hint)
    {
	gdk_window_get_pointer(ev->window, &x, &y, (GdkModifierType*)&state);
    }
    else
    {
	x = ev->x;
	y = ev->y;
	state = ev->state;
    }
    dx = x - ox;
    dy = y - oy;
    if ((dx == 0) && (dy == 0)) return TRUE; // prevent infinite looping - 2.6.X
    ox = x;
    oy = y;
    buttons = 0;
    if (state & GDK_BUTTON1_MASK)
	buttons |= MOUSE_EVENT_LBUTTON;
    if (state & GDK_BUTTON3_MASK)
	buttons |= MOUSE_EVENT_RBUTTON;
    if (state & GDK_BUTTON2_MASK)
	buttons |= MOUSE_EVENT_MBUTTON;
    /* XXX: test wheel */
    dz = 0;
    if (state & GDK_BUTTON4_MASK)
	dz--;
    if (state & GDK_BUTTON5_MASK)
	dz++;

    /* wrap the x,y coordinates back onto the window */
    if (ev->x <= (cw/4))
	x = ((3*cw/4)-1);
    if (ev->y <= (ch/4))
	y = ((3*ch/4)-1);
    if (ev->x >= (3*cw/4))
	x = (cw/4)+1;
    if (ev->y >= (3*ch/4))
	y = (ch/4)+1;

    /* make internal mouse move invisible */
    ox = x;
    oy = y;

    gdk_window_set_pointer(screen->window, (gint)x, (gint)y);

    kbd_mouse_event(dx, dy, dz, buttons);

    }
    return TRUE;
}

static void toggle_full_screen(DisplayState *ds)
{
    gui_fullscreen = !gui_fullscreen;
    gtk2_resize(ds, image->width, image->height);
    if (gui_fullscreen) {
	gui_saved_grab = gui_grab;
	gtk2_grab_start();
	gtk_window_get_position(GTK_WINDOW(screen), &cx, &cy);
	/* ignore window manager decorations when in fullscreen mode */
	gtk_window_set_gravity(GTK_WINDOW(screen), GDK_GRAVITY_STATIC);
	gtk_window_move(GTK_WINDOW(screen), 0, 0);
	fullscreen_switch(cx, cy, ds->width, ds->height);
    } else {
	fullscreen_reset();
	gtk_window_set_gravity(GTK_WINDOW(screen), GDK_GRAVITY_NORTH_WEST);
	gtk_window_move(GTK_WINDOW(screen), cx, cy);
	if (!gui_saved_grab)
	    gtk2_grab_end();
    }
    vga_invalidate_display();
    vga_update_display();
}

static gboolean gtk2_key_press(GtkWidget *wid, GdkEventKey *ev, DisplayState *ds)
{
	int mod_state;
	    if (ev->type == GDK_KEY_PRESS) {
		mod_state = (gtk2_GetModState(ev) & (int)gui_grab_code) == (int)gui_grab_code;
		gui_key_modifier_pressed = mod_state;
		if (gui_key_modifier_pressed) {
		    int keycode;
		    keycode = gtk2_keyevent_to_keycode(ev);
		    switch(keycode) {
		    case 0x21: /* 'f' key on US keyboard */
			toggle_full_screen(ds);
			gui_keysym = 1;
			break;
		    case 0x02 ... 0x0a: /* '1' to '9' keys */ 
			console_select(keycode - 0x02);
			if (is_active_console(vga_console)) {
			    /* tell the vga console to redisplay itself */
			    vga_invalidate_display();
			} else {
			    /* display grab if going to a text console */
			    if (gui_grab)
				gtk2_grab_end();
			}
			gui_keysym = 1;
			break;
		    default:
			break;
		    }
		} else if (!is_active_console(vga_console)) {
		    int keysym;
		    keysym = 0;
		    if (ev->state & GDK_CONTROL_MASK) {
			switch(ev->keyval) {
			case GDK_Up: keysym = QEMU_KEY_CTRL_UP; break;
			case GDK_Down: keysym = QEMU_KEY_CTRL_DOWN; break;
			case GDK_Left: keysym = QEMU_KEY_CTRL_LEFT; break;
			case GDK_Right: keysym = QEMU_KEY_CTRL_RIGHT; break;
			case GDK_Home: keysym = QEMU_KEY_CTRL_HOME; break;
			case GDK_End: keysym = QEMU_KEY_CTRL_END; break;
			case GDK_Page_Up: keysym = QEMU_KEY_CTRL_PAGEUP; break;
			case GDK_Page_Down: keysym = QEMU_KEY_CTRL_PAGEDOWN; break;
			default: break;
			}
		    } else {
			switch(ev->keyval) {
			case GDK_Up: keysym = QEMU_KEY_UP; break;
			case GDK_Down: keysym = QEMU_KEY_DOWN; break;
			case GDK_Left: keysym = QEMU_KEY_LEFT; break;
			case GDK_Right: keysym = QEMU_KEY_RIGHT; break;
			case GDK_Home: keysym = QEMU_KEY_HOME; break;
			case GDK_End: keysym = QEMU_KEY_END; break;
			case GDK_Page_Up: keysym = QEMU_KEY_PAGEUP; break;
			case GDK_Page_Down: keysym = QEMU_KEY_PAGEDOWN; break;
			case GDK_BackSpace: keysym = QEMU_KEY_BACKSPACE; break;
			case GDK_Delete: keysym = QEMU_KEY_DELETE; break;
			default: break;
			}
		    }
		    if (keysym) {
			kbd_put_keysym(keysym);
		    } /*else if (ev->key.keysym.unicode != 0) {
			kbd_put_keysym(ev->key.keysym.unicode);
		    }*/
		}
	    } else if (ev->type == GDK_KEY_RELEASE) {
		mod_state = (gtk2_GetModState(ev) & gui_grab_code);
		if (!mod_state) {
		    if (gui_key_modifier_pressed) {
			if (gui_keysym == 0) {
			    /* exit/enter grab if pressing Ctrl-Alt */
			    if (!gui_grab)
				gtk2_grab_start();
			    else
				gtk2_grab_end();
			    /* SDL does not send back all the
			       modifiers key, so we must correct it */
			    reset_keys();
			    return TRUE;
			}
			gui_key_modifier_pressed = 0;
			gui_keysym = 0;
		    }
		}
	    }
	    if (is_active_console(vga_console)) 
		gtk2_process_key(ev);
	return TRUE;
}

static void gtk2_refresh(DisplayState *ds)
{
    if (last_vm_running != vm_running) {
	last_vm_running = vm_running;
	gtk2_update_caption();
    }
    if (ds->data != image->mem)
    {
	ds->data = image->mem;
    }

    if (is_active_console(vga_console))                                         
	vga_update_display();                                                   
    while (gtk_events_pending())
	gtk_main_iteration();
}

static void gtk2_cleanup(void) 
{
    gtk_main_quit();
    fullscreen_cleanup();
}

static gboolean gtk2_deletewin(void)
{
    /* signal qemu that its time to shut itself off - this is the place that we hook to trap attempts to close the main qemu window */
    qemu_system_shutdown_request();
    return FALSE;
    return TRUE; /* dont close the window right away! give qemu time to think */
}

static void gtk2_destroy(void)
{
    /* ideally we would call a hook here so qemu could clean itself up */
    gtk2_cleanup();
}

void gtk2_display_init(DisplayState *ds, int full_screen)
{
    int events;

#if defined(__APPLE__)
    /* always use generic keymaps */
    if (!keyboard_layout)
	keyboard_layout = "en-us";
#endif
    if(keyboard_layout) {
	kbd_layout = init_keyboard_layout(keyboard_layout);
	if (!kbd_layout)
	    exit(1);
    }

    if (!gtk_init_check (0,NULL))
    {
	fprintf(stderr, "Could not load GTK\n");
	exit(0);
    }
    fullscreen_init();

/* note: adding GDK_DRAG_* and GDK_DROP_* would provide a mechanism for supporting drag and drop between host and guest */
    events = GDK_EXPOSURE_MASK | GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK | GDK_FOCUS_CHANGE_MASK | GDK_SCROLL_MASK | GDK_STRUCTURE_MASK;

    screen = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_widget_set_events(screen, events);
    gtk_window_set_default_size(GTK_WINDOW(screen), 720, 400);
    gtk_widget_set_size_request(screen, 720, 400);

    g_signal_connect(G_OBJECT(screen), "delete_event", G_CALLBACK(gtk2_deletewin), NULL);
    g_signal_connect(G_OBJECT(screen), "destroy", G_CALLBACK(gtk2_destroy), NULL);
    gtk_container_set_border_width(GTK_CONTAINER(screen), 10);

    gtk_signal_connect(GTK_OBJECT(screen), "expose_event", (GtkSignalFunc) gtk2_expose, NULL);
    gtk_signal_connect(GTK_OBJECT(screen), "motion_notify_event", (GtkSignalFunc) gtk2_send_mouse_move, NULL);
    gtk_signal_connect(GTK_OBJECT(screen), "button_press_event", (GtkSignalFunc) gtk2_send_mouse_button, NULL);
    gtk_signal_connect(GTK_OBJECT(screen), "button_release_event", (GtkSignalFunc) gtk2_send_mouse_button, NULL);
    gtk_signal_connect(GTK_OBJECT(screen), "scroll_event", (GtkSignalFunc) gtk2_send_mouse_scroll, NULL);
    gtk_signal_connect(GTK_OBJECT(screen), "key_press_event", (GtkSignalFunc) gtk2_key_press, ds);
    gtk_signal_connect(GTK_OBJECT(screen), "key_release_event", (GtkSignalFunc) gtk2_key_press, ds);

    ds->dpy_update = gtk2_update;
    ds->dpy_resize = gtk2_resize;
    ds->dpy_refresh = gtk2_refresh;

    gchar nullpixdata[1] = { 0 };
    GdkColor nullcolor = { 0, 0, 0, 0 };
    GdkPixmap *invis = gdk_bitmap_create_from_data(screen->window, nullpixdata, 1, 1);
    invisible_cursor = gdk_cursor_new_from_pixmap(invis, invis, &nullcolor, &nullcolor, 0, 0);

    gtk2_resize(ds, 720, 400);
    gtk2_update_caption();
    gui_grab = 0;

    gtk_window_set_policy(GTK_WINDOW(screen), FALSE, FALSE, FALSE);
    gtk_widget_show(screen);
    if (full_screen) {
	gui_fullscreen = 1;
	gui_fullscreen_initial_grab = 1;
	gtk2_grab_start();
    }
}

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [Qemu-devel] quick gtk2.c update
  2005-06-22 18:53                                   ` Jim C. Brown
@ 2005-06-22 20:59                                     ` Jim C. Brown
  2005-06-23  2:26                                       ` jeebs
  0 siblings, 1 reply; 59+ messages in thread
From: Jim C. Brown @ 2005-06-22 20:59 UTC (permalink / raw)
  To: qemu-devel

[-- Attachment #1: Type: text/plain, Size: 699 bytes --]

On Wed, Jun 22, 2005 at 02:53:03PM -0400, Jim C. Brown wrote:
> This version of gtk2.c includes the right header file (at least according to MSDN).
> 
> However, after some deeper examination of the issue, it looks like it would be
> better to convert the virtual key codes to the us keyboard scancodes via some
> sort of keymap (similar to the X11 case).
> 

Ok this is probably the final revision. I had the code vindicated by an actual
Windows programmer. He says it should work fine. It should compile, run, and make
qemu under gtk usable. Also I modified it so it lets u know when u are using GTK.

-- 
Infinite complexity begets infinite beauty.
Infinite precision begets infinite perfection.

[-- Attachment #2: gtk2.c --]
[-- Type: text/plain, Size: 21745 bytes --]

/*
 * QEMU GTK2 display driver
 * based on SDL driver by Fabrice
 * 
 * Copyright (c) 2005 Jim Brown
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
#include "vl.h"

#include <gtk/gtk.h>
#include <gdk/gdk.h>

#include "fullscreen.h"

/* define our own bitshift enums to allow qemugtk to know difference between left and right alt - something gtk doesnt provide in its modifiers mask. this uses qemu's own modifier_state[] map in order to guess correctly */
typedef enum
{
	gtkshiftleft = 1 << 0,
	gtkshiftright = 1 << 1,
	gtkcontrolleft = 1 << 2,
	gtkcontrolright = 1 << 3,
	gtkaltleft = 1 << 4,
	gtkaltright = 1 << 5,
	gtkcapslock = 1 << 6
} gtk2keymod;


static GtkWidget *screen;
static GdkImage *image=NULL;
static GdkCursor *invisible_cursor;
static int ox = 0, oy = 0;
static int gui_grab; /* if true, all keyboard/mouse events are grabbed */
static int last_vm_running;
static int gui_saved_grab;
static int gui_fullscreen;
static int gui_key_modifier_pressed;
static int gui_keysym;
static int gui_fullscreen_initial_grab;
static int gui_grab_code = gtkaltleft | gtkcontrolleft;
static uint8_t modifiers_state[256];
static unsigned int cw, ch;
static gint cx, cy;

static gboolean gtk2_expose(GtkWidget *wid, GdkEventExpose *event)
{
    gdk_draw_image(wid->window, wid->style->fg_gc[GTK_WIDGET_STATE(wid)], image, event->area.x, event->area.y, event->area.x, event->area.y, event->area.width, event->area.height);
    return TRUE;
}

static void gtk2_update(DisplayState *ds, int x, int y, int w, int h)
{
    //    printf("updating x=%d y=%d w=%d h=%d\n", x, y, w, h);
    GdkEventExpose ev;
    ev.area.x = x;
    ev.area.y = y;
    ev.area.width = w;
    ev.area.height = h;
    gtk2_expose(screen, &ev);
}

static void gtk2_resize(DisplayState *ds, int w, int h)
{

    //    printf(" resizing to %d %d\n", w, h);

    if (gui_fullscreen)
    {
	if (cw != w || ch != h)
	    fullscreen_switch(cx, cy, w, h); /* changing video modes */
	//gtk_window_fullscreen(GTK_WINDOW(screen));
    }
    else
    {
	//gtk_window_unfullscreen(GTK_WINDOW(screen));
    }

    cw = w; ch = h;

    if (image)
	 g_object_unref(image);

/* gdk_visual_get_best_with_depth() ??? but then how to paint onto window? */
    image = gdk_image_new(GDK_IMAGE_NORMAL, gdk_visual_get_system(), w, h);
    gdk_image_set_colormap(image, gdk_colormap_get_system());

    gtk_window_set_default_size(GTK_WINDOW(screen), w, h);
    gtk_widget_set_size_request(screen, w, h);
    gtk_window_resize(GTK_WINDOW(screen), w, h);

    ds->data = image->mem;
    ds->linesize = image->bpl;
    ds->depth = image->bits_per_pixel;
    ds->width = w;
    ds->height = h;
    gtk2_update(ds, 0, 0, w, h);
}

/* generic keyboard conversion */

#include "gdk_keysym.h"
#include "keymaps.c"

static kbd_layout_t *kbd_layout = NULL;

static uint8_t gtk2_keyevent_to_keycode_generic(const GdkEventKey *ev)
{
    int keysym;
    /* workaround for X11+SDL bug with AltGR - is it still needed for Gtk2? */
    keysym = ev->keyval;
    if (keysym == 0 && ev->hardware_keycode == 113)
	keysym = GDK_Mode_switch;
    return keysym2scancode(kbd_layout, keysym);
}

/* specific keyboard conversions from scan codes */

#if defined(_WIN32)

#include <windows.h>

static UINT vk2scan(UINT vk)
{
	return MapVirtualKey(vk,0);
}
static uint8_t gtk2_keyevent_to_keycode(const GdkEventKey *ev)
{   
    return (uint8_t)vk2scan((UINT)(ev->hardware_keycode));
}

#else

static const uint8_t x_keycode_to_pc_keycode[61] = {
   0xc7,      /*  97  Home   */
   0xc8,      /*  98  Up     */
   0xc9,      /*  99  PgUp   */
   0xcb,      /* 100  Left   */
   0x4c,        /* 101  KP-5   */
   0xcd,      /* 102  Right  */
   0xcf,      /* 103  End    */
   0xd0,      /* 104  Down   */
   0xd1,      /* 105  PgDn   */
   0xd2,      /* 106  Ins    */
   0xd3,      /* 107  Del    */
   0x9c,      /* 108  Enter  */
   0x9d,      /* 109  Ctrl-R */
   0x0,       /* 110  Pause  */
   0xb7,      /* 111  Print  */
   0xb5,      /* 112  Divide */
   0xb8,      /* 113  Alt-R  */
   0xc6,      /* 114  Break  */   
   0x0,         /* 115 */
   0x0,         /* 116 */
   0x0,         /* 117 */
   0x0,         /* 118 */
   0x0,         /* 119 */
   0x70,         /* 120 Hiragana_Katakana */
   0x0,         /* 121 */
   0x0,         /* 122 */
   0x73,         /* 123 backslash */
   0x0,         /* 124 */
   0x0,         /* 125 */
   0x0,         /* 126 */
   0x0,         /* 127 */
   0x0,         /* 128 */
   0x79,         /* 129 Henkan */
   0x0,         /* 130 */
   0x7b,         /* 131 Muhenkan */
   0x0,         /* 132 */
   0x7d,         /* 133 Yen */
   0x0,         /* 134 */
   0x0,         /* 135 */
   0x47,         /* 136 KP_7 */
   0x48,         /* 137 KP_8 */
   0x49,         /* 138 KP_9 */
   0x4b,         /* 139 KP_4 */
   0x4c,         /* 140 KP_5 */
   0x4d,         /* 141 KP_6 */
   0x4f,         /* 142 KP_1 */
   0x50,         /* 143 KP_2 */
   0x51,         /* 144 KP_3 */
   0x52,         /* 145 KP_0 */
   0x53,         /* 146 KP_. */
   0x47,         /* 147 KP_HOME */
   0x48,         /* 148 KP_UP */
   0x49,         /* 149 KP_PgUp */
   0x4b,         /* 150 KP_Left */
   0x4c,         /* 151 KP_ */
   0x4d,         /* 152 KP_Right */
   0x4f,         /* 153 KP_End */
   0x50,         /* 154 KP_Down */
   0x51,         /* 155 KP_PgDn */
   0x52,         /* 156 KP_Ins */
   0x53,         /* 157 KP_Del */
};

static uint8_t gtk2_keyevent_to_keycode(const GdkEventKey *ev)
{
    int keycode;

    keycode = ev->hardware_keycode;

    if (keycode < 9) {
	keycode = 0;
    } else if (keycode < 97) {
	keycode -= 8; /* just an offset */
    } else if (keycode < 158) {
	/* use conversion table */
	keycode = x_keycode_to_pc_keycode[keycode - 97];
    } else {
	keycode = 0;
    }
    return keycode;
}

#endif

static void reset_keys(void)
{
    int i;
    for(i = 0; i < 256; i++) {
	if (modifiers_state[i]) {
	    if (i & 0x80)
		kbd_put_keycode(0xe0);
	    kbd_put_keycode(i | 0x80);
	    modifiers_state[i] = 0;
	}
    }
}

/* convert GDK modifiers and invoke ugly hack to distinguish
between left and right shift/control/alt */
static guint gtk2_GetModState(const GdkEventKey *ev)
{
	guint key = 0, keyval = ev->keyval, state = ev->state;
	switch(keyval)
	{
		case GDK_Shift_L:
			if (ev->type != GDK_KEY_RELEASE)
				key |= gtkshiftleft;
			keyval = 1;
			break;
		case GDK_Shift_R:
			if (ev->type != GDK_KEY_RELEASE)
				key |= gtkshiftright;
			keyval = 1;
			break;
		case GDK_Control_L:
			if (ev->type != GDK_KEY_RELEASE)
				key |= gtkcontrolleft;
			keyval = 2;
			break;
		case GDK_Control_R:
			if (ev->type != GDK_KEY_RELEASE)
				key |= gtkcontrolright;
			keyval = 2;
			break;
		case GDK_Alt_L:
			if (ev->type != GDK_KEY_RELEASE)
				key |= gtkaltleft;
			keyval = 3;
			break;
		case GDK_Alt_R:
			if (ev->type != GDK_KEY_RELEASE)
				key |= gtkaltright;
			keyval = 3;
			break;
		case GDK_Caps_Lock:
			if (ev->type != GDK_KEY_RELEASE)
				key |= gtkcapslock;
			keyval = 4;
			break;
		default:
			keyval = 0;
			break;
	}
	if (keyval != 1 && (state & GDK_SHIFT_MASK))
	{
		if (modifiers_state[0x2a])
			key |= gtkshiftleft;
		if (modifiers_state[0x36])
			key |= gtkshiftright;
	}
	if (keyval != 2 && (state & GDK_CONTROL_MASK))
	{
		if (modifiers_state[0x1d])
			key |= gtkcontrolleft;
		if (modifiers_state[0x9d])
			key |= gtkcontrolright;
	}
	if (keyval != 3 && (state & GDK_MOD1_MASK)) /* fixme: need to do a check to make sure that alt is mapped to GDK_MOD1_MASK in the GDK_Keymap */
	{
		if (modifiers_state[0x38])
			key |= gtkaltleft;
		if (modifiers_state[0xb8])
			key |= gtkaltright;
	}
	if (keyval != 4 && (state & GDK_LOCK_MASK))
		key |= gtkcapslock;
	return key;
}

static void gtk2_process_key(GdkEventKey *ev)
{
    int keycode, v;

    if (ev->keyval == GDK_Pause) {
	/* specific case */
	v = 0;
	if (ev->type == GDK_KEY_RELEASE)
	    v |= 0x80;
	kbd_put_keycode(0xe1);
	kbd_put_keycode(0x1d | v);
	kbd_put_keycode(0x45 | v);
	return;
    }

    if (kbd_layout) {
	keycode = gtk2_keyevent_to_keycode_generic(ev);
    } else {
	keycode = gtk2_keyevent_to_keycode(ev);
    }

    switch(keycode) {
    case 0x00:
	/* sent when leaving window: reset the modifiers state */
	reset_keys();
	return;
    case 0x2a:                          /* Left Shift */
    case 0x36:                          /* Right Shift */
    case 0x1d:                          /* Left CTRL */
    case 0x9d:                          /* Right CTRL */
    case 0x38:                          /* Left ALT */
    case 0xb8:                         /* Right ALT */
	if (ev->type == GDK_KEY_RELEASE)
	    modifiers_state[keycode] = 0;
	else
	    modifiers_state[keycode] = 1;
	break;
    case 0x45: /* num lock */
    case 0x3a: /* caps lock */
	/* GTK does send the key up event, so we dont generate it */
	/*kbd_put_keycode(keycode);
	kbd_put_keycode(keycode | 0x80);
	return;*/
	break;
    }

    /* now send the key code */
    if (keycode & 0x80)
	kbd_put_keycode(0xe0);
    if (ev->type == GDK_KEY_RELEASE)
	kbd_put_keycode(keycode | 0x80);
    else
	kbd_put_keycode(keycode & 0x7f);
}

static void gtk2_update_caption(void)
{
    char buf[1024];
    strcpy(buf, "QEMU Gtk");
    if (!vm_running) {
	strcat(buf, " [Stopped]");
    }
    if (gui_grab) {
	strcat(buf, " - Press Ctrl-Alt to exit grab");
    }
    gtk_window_set_title(GTK_WINDOW(screen), buf);
}

/* what a nasty hack. this should be a part of the GDK, not external!!! */
#include "gdk_set_window_pointer.c"

static void gtk2_grab_start(void)
{
    gint y;
    guint events;
    GdkModifierType state; /* dummy var */
    events = GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_SCROLL_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK;
    y = gdk_pointer_grab(screen->window, TRUE, events, screen->window, invisible_cursor, GDK_CURRENT_TIME);
    if (y)
	printf("GTK Warning - pointer grab failed!\n");
    y = gdk_keyboard_grab(screen->window, TRUE, GDK_CURRENT_TIME);
    if (y)
	printf("GTK Warning - keyboard grab failed!\n");
    /* do a dummy read to avoid moving mouse - set ox and oy to stay in sync */
    gdk_window_get_pointer(screen->window, &ox, &oy, &state);
    gui_grab = 1;
    gtk2_update_caption();
}

static void gtk2_grab_end(void)
{
    gdk_pointer_ungrab(GDK_CURRENT_TIME);
    gdk_keyboard_ungrab(GDK_CURRENT_TIME);
    gdk_window_set_pointer(screen->window, cx, cy);
    gui_grab = 0;
    gtk2_update_caption();
}

static gboolean gtk2_send_mouse_scroll(GtkWidget *wid, GdkEventScroll *ev)
{
    int x, y, dx, dy, dz, state, buttons;
    if (gui_grab)
    {

    x = ev->x;
    y = ev->y;
    state = ev->state;
    buttons = 0;
    dx = x - ox;
    dy = y - oy;
    ox = x;
    oy = y;
    buttons = 0;
    if ((state & GDK_BUTTON1_MASK))
	buttons |= MOUSE_EVENT_LBUTTON;
    if ((state & GDK_BUTTON3_MASK))
	buttons |= MOUSE_EVENT_RBUTTON;
    if ((state & GDK_BUTTON2_MASK))
	buttons |= MOUSE_EVENT_MBUTTON;
    /* test wheel - copied from Sebastien Bechet's gtk.c */
    dz = 0;
    if ((state & GDK_BUTTON4_MASK) || ev->direction == GDK_SCROLL_UP)
	dz--;
    if ((state & GDK_BUTTON5_MASK) || ev->direction == GDK_SCROLL_DOWN)
	dz++;
    kbd_mouse_event(dx, dy, dz, buttons);

    }
    return TRUE;
}

static gboolean gtk2_send_mouse_button(GtkWidget *wid, GdkEventButton *ev)
{
    int x, y, dx, dy, dz, state, buttons;
    if (ev->type == GDK_2BUTTON_PRESS || ev->type == GDK_3BUTTON_PRESS)
	return TRUE; /* double or triple click - superflurious - ignore */
    if (gui_grab)
    {

    x = ev->x;
    y = ev->y;
    state = ev->state;
    buttons = 0;
    dx = x - ox;
    dy = y - oy;
    ox = x;
    oy = y;
    buttons = 0;
    if ((state & GDK_BUTTON1_MASK) || ev->button == 1)
	buttons |= MOUSE_EVENT_LBUTTON;
    if ((state & GDK_BUTTON3_MASK) || ev->button == 3)
	buttons |= MOUSE_EVENT_RBUTTON;
    if ((state & GDK_BUTTON2_MASK) || ev->button == 2)
	buttons |= MOUSE_EVENT_MBUTTON;
    /* XXX: test wheel */
    dz = 0;
    if ((state & GDK_BUTTON4_MASK) || ev->button == 4)
	dz--;
    if ((state & GDK_BUTTON5_MASK) || ev->button == 5)
	dz++;
    kbd_mouse_event(dx, dy, dz, buttons);

    }
    else
    {

    if (ev->button == 1 && ev->type == GDK_BUTTON_PRESS)
    {
	/* start grabbing all events */
	gtk2_grab_start();
    }

    }
    return TRUE;
}

static gboolean gtk2_send_mouse_move(GtkWidget *wid, GdkEventMotion *ev)
{
    int x, y, dx, dy, dz, state, buttons;
    if (gui_grab)
    {

    if (ev->is_hint)
    {
	gdk_window_get_pointer(ev->window, &x, &y, (GdkModifierType*)&state);
    }
    else
    {
	x = ev->x;
	y = ev->y;
	state = ev->state;
    }
    dx = x - ox;
    dy = y - oy;
    if ((dx == 0) && (dy == 0)) return TRUE; // prevent infinite looping - 2.6.X
    ox = x;
    oy = y;
    buttons = 0;
    if (state & GDK_BUTTON1_MASK)
	buttons |= MOUSE_EVENT_LBUTTON;
    if (state & GDK_BUTTON3_MASK)
	buttons |= MOUSE_EVENT_RBUTTON;
    if (state & GDK_BUTTON2_MASK)
	buttons |= MOUSE_EVENT_MBUTTON;
    /* XXX: test wheel */
    dz = 0;
    if (state & GDK_BUTTON4_MASK)
	dz--;
    if (state & GDK_BUTTON5_MASK)
	dz++;

    /* wrap the x,y coordinates back onto the window */
    if (ev->x <= (cw/4))
	x = ((3*cw/4)-1);
    if (ev->y <= (ch/4))
	y = ((3*ch/4)-1);
    if (ev->x >= (3*cw/4))
	x = (cw/4)+1;
    if (ev->y >= (3*ch/4))
	y = (ch/4)+1;

    /* make internal mouse move invisible */
    ox = x;
    oy = y;

    gdk_window_set_pointer(screen->window, (gint)x, (gint)y);

    kbd_mouse_event(dx, dy, dz, buttons);

    }
    return TRUE;
}

static void toggle_full_screen(DisplayState *ds)
{
    gui_fullscreen = !gui_fullscreen;
    gtk2_resize(ds, image->width, image->height);
    if (gui_fullscreen) {
	gui_saved_grab = gui_grab;
	gtk2_grab_start();
	gtk_window_get_position(GTK_WINDOW(screen), &cx, &cy);
	/* ignore window manager decorations when in fullscreen mode */
	gtk_window_set_gravity(GTK_WINDOW(screen), GDK_GRAVITY_STATIC);
	gtk_window_move(GTK_WINDOW(screen), 0, 0);
	fullscreen_switch(cx, cy, ds->width, ds->height);
    } else {
	fullscreen_reset();
	gtk_window_set_gravity(GTK_WINDOW(screen), GDK_GRAVITY_NORTH_WEST);
	gtk_window_move(GTK_WINDOW(screen), cx, cy);
	if (!gui_saved_grab)
	    gtk2_grab_end();
    }
    vga_invalidate_display();
    vga_update_display();
}

static gboolean gtk2_key_press(GtkWidget *wid, GdkEventKey *ev, DisplayState *ds)
{
	int mod_state;
	    if (ev->type == GDK_KEY_PRESS) {
		mod_state = (gtk2_GetModState(ev) & (int)gui_grab_code) == (int)gui_grab_code;
		gui_key_modifier_pressed = mod_state;
		if (gui_key_modifier_pressed) {
		    int keycode;
		    keycode = gtk2_keyevent_to_keycode(ev);
		    switch(keycode) {
		    case 0x21: /* 'f' key on US keyboard */
			toggle_full_screen(ds);
			gui_keysym = 1;
			break;
		    case 0x02 ... 0x0a: /* '1' to '9' keys */ 
			console_select(keycode - 0x02);
			if (is_active_console(vga_console)) {
			    /* tell the vga console to redisplay itself */
			    vga_invalidate_display();
			} else {
			    /* display grab if going to a text console */
			    if (gui_grab)
				gtk2_grab_end();
			}
			gui_keysym = 1;
			break;
		    default:
			break;
		    }
		} else if (!is_active_console(vga_console)) {
		    int keysym;
		    keysym = 0;
		    if (ev->state & GDK_CONTROL_MASK) {
			switch(ev->keyval) {
			case GDK_Up: keysym = QEMU_KEY_CTRL_UP; break;
			case GDK_Down: keysym = QEMU_KEY_CTRL_DOWN; break;
			case GDK_Left: keysym = QEMU_KEY_CTRL_LEFT; break;
			case GDK_Right: keysym = QEMU_KEY_CTRL_RIGHT; break;
			case GDK_Home: keysym = QEMU_KEY_CTRL_HOME; break;
			case GDK_End: keysym = QEMU_KEY_CTRL_END; break;
			case GDK_Page_Up: keysym = QEMU_KEY_CTRL_PAGEUP; break;
			case GDK_Page_Down: keysym = QEMU_KEY_CTRL_PAGEDOWN; break;
			default: break;
			}
		    } else {
			switch(ev->keyval) {
			case GDK_Up: keysym = QEMU_KEY_UP; break;
			case GDK_Down: keysym = QEMU_KEY_DOWN; break;
			case GDK_Left: keysym = QEMU_KEY_LEFT; break;
			case GDK_Right: keysym = QEMU_KEY_RIGHT; break;
			case GDK_Home: keysym = QEMU_KEY_HOME; break;
			case GDK_End: keysym = QEMU_KEY_END; break;
			case GDK_Page_Up: keysym = QEMU_KEY_PAGEUP; break;
			case GDK_Page_Down: keysym = QEMU_KEY_PAGEDOWN; break;
			case GDK_BackSpace: keysym = QEMU_KEY_BACKSPACE; break;
			case GDK_Delete: keysym = QEMU_KEY_DELETE; break;
			default: break;
			}
		    }
		    if (keysym) {
			kbd_put_keysym(keysym);
		    } /*else if (ev->key.keysym.unicode != 0) {
			kbd_put_keysym(ev->key.keysym.unicode);
		    }*/
		}
	    } else if (ev->type == GDK_KEY_RELEASE) {
		mod_state = (gtk2_GetModState(ev) & gui_grab_code);
		if (!mod_state) {
		    if (gui_key_modifier_pressed) {
			if (gui_keysym == 0) {
			    /* exit/enter grab if pressing Ctrl-Alt */
			    if (!gui_grab)
				gtk2_grab_start();
			    else
				gtk2_grab_end();
			    /* SDL does not send back all the
			       modifiers key, so we must correct it */
			    reset_keys();
			    return TRUE;
			}
			gui_key_modifier_pressed = 0;
			gui_keysym = 0;
		    }
		}
	    }
	    if (is_active_console(vga_console)) 
		gtk2_process_key(ev);
	return TRUE;
}

static void gtk2_refresh(DisplayState *ds)
{
    if (last_vm_running != vm_running) {
	last_vm_running = vm_running;
	gtk2_update_caption();
    }
    if (ds->data != image->mem)
    {
	ds->data = image->mem;
    }

    if (is_active_console(vga_console))                                         
	vga_update_display();                                                   
    while (gtk_events_pending())
	gtk_main_iteration();
}

static void gtk2_cleanup(void) 
{
    gtk_main_quit();
    fullscreen_cleanup();
}

static gboolean gtk2_deletewin(void)
{
    /* signal qemu that its time to shut itself off - this is the place that we hook to trap attempts to close the main qemu window */
    qemu_system_shutdown_request();
    return FALSE;
    return TRUE; /* dont close the window right away! give qemu time to think */
}

static void gtk2_destroy(void)
{
    /* ideally we would call a hook here so qemu could clean itself up */
    gtk2_cleanup();
}

void gtk2_display_init(DisplayState *ds, int full_screen)
{
    int events;

#if defined(__APPLE__)
    /* always use generic keymaps */
    if (!keyboard_layout)
	keyboard_layout = "en-us";
#endif
    if(keyboard_layout) {
	kbd_layout = init_keyboard_layout(keyboard_layout);
	if (!kbd_layout)
	    exit(1);
    }

    if (!gtk_init_check (0,NULL))
    {
	fprintf(stderr, "Could not load GTK\n");
	exit(0);
    }
    fullscreen_init();

/* note: adding GDK_DRAG_* and GDK_DROP_* would provide a mechanism for supporting drag and drop between host and guest */
    events = GDK_EXPOSURE_MASK | GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK | GDK_FOCUS_CHANGE_MASK | GDK_SCROLL_MASK | GDK_STRUCTURE_MASK;

    screen = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_widget_set_events(screen, events);
    gtk_window_set_default_size(GTK_WINDOW(screen), 720, 400);
    gtk_widget_set_size_request(screen, 720, 400);

    g_signal_connect(G_OBJECT(screen), "delete_event", G_CALLBACK(gtk2_deletewin), NULL);
    g_signal_connect(G_OBJECT(screen), "destroy", G_CALLBACK(gtk2_destroy), NULL);
    gtk_container_set_border_width(GTK_CONTAINER(screen), 10);

    gtk_signal_connect(GTK_OBJECT(screen), "expose_event", (GtkSignalFunc) gtk2_expose, NULL);
    gtk_signal_connect(GTK_OBJECT(screen), "motion_notify_event", (GtkSignalFunc) gtk2_send_mouse_move, NULL);
    gtk_signal_connect(GTK_OBJECT(screen), "button_press_event", (GtkSignalFunc) gtk2_send_mouse_button, NULL);
    gtk_signal_connect(GTK_OBJECT(screen), "button_release_event", (GtkSignalFunc) gtk2_send_mouse_button, NULL);
    gtk_signal_connect(GTK_OBJECT(screen), "scroll_event", (GtkSignalFunc) gtk2_send_mouse_scroll, NULL);
    gtk_signal_connect(GTK_OBJECT(screen), "key_press_event", (GtkSignalFunc) gtk2_key_press, ds);
    gtk_signal_connect(GTK_OBJECT(screen), "key_release_event", (GtkSignalFunc) gtk2_key_press, ds);

    ds->dpy_update = gtk2_update;
    ds->dpy_resize = gtk2_resize;
    ds->dpy_refresh = gtk2_refresh;

    gchar nullpixdata[1] = { 0 };
    GdkColor nullcolor = { 0, 0, 0, 0 };
    GdkPixmap *invis = gdk_bitmap_create_from_data(screen->window, nullpixdata, 1, 1);
    invisible_cursor = gdk_cursor_new_from_pixmap(invis, invis, &nullcolor, &nullcolor, 0, 0);

    gtk2_resize(ds, 720, 400);
    gtk2_update_caption();
    gui_grab = 0;

    gtk_window_set_policy(GTK_WINDOW(screen), FALSE, FALSE, FALSE);
    gtk_widget_show(screen);
    if (full_screen) {
	gui_fullscreen = 1;
	gui_fullscreen_initial_grab = 1;
	gtk2_grab_start();
    }
}

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [Qemu-devel] quick gtk2.c update
  2005-06-22 20:59                                     ` Jim C. Brown
@ 2005-06-23  2:26                                       ` jeebs
  2005-06-24  0:32                                         ` Jim C. Brown
  0 siblings, 1 reply; 59+ messages in thread
From: jeebs @ 2005-06-23  2:26 UTC (permalink / raw)
  To: qemu-devel

"Jim C. Brown"
>
> Ok this is probably the final revision. I had the code vindicated by an 
> actual
> Windows programmer. He says it should work fine. It should compile, run, 
> and make

Okay... I compiled it and the keys do appear to work.

That problem does appear to be fixed.

It doesn't look like the 'insert' key toggles between insert / overstrike 
when I use the Win3 wordpad to read a file.  However, this is in the regular 
qemu 0.70, so I don't know if it's a problem with qemu, or Win 3 wordpad.

Now, while running my Win 3 test image, I notice that double clicking 
doesn't work.  I couldn't get anything to open up no matter how fast I 
clicked.

Single clicking works okay, though.


> qemu under gtk usable. Also I modified it so it lets u know when u are 
> using GTK.

I noticed that immediately when I ran it...  Nice.  Thanks.

> Still, I work with what I have to go on. Try this gtk2.c and report any 
> errors
> (be they compile errors or runtime errors or keyboard problems). Your help 
> is
> always greatly appreciated.

I'm glad I'm able to help.

The previous qemu errors I've reported have been completely ignored!

At least you are taking an active interest in what a mere user has to 
say....

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [Qemu-devel] quick gtk2.c update
  2005-06-23  2:26                                       ` jeebs
@ 2005-06-24  0:32                                         ` Jim C. Brown
  2005-06-26 16:13                                           ` Jim C. Brown
  0 siblings, 1 reply; 59+ messages in thread
From: Jim C. Brown @ 2005-06-24  0:32 UTC (permalink / raw)
  To: qemu-devel

On Wed, Jun 22, 2005 at 09:26:11PM -0500, jeebs@yango.us wrote:
> "Jim C. Brown"
> >
> > Ok this is probably the final revision. I had the code vindicated by an 
> > actual
> > Windows programmer. He says it should work fine. It should compile, run, 
> > and make
> 
> Okay... I compiled it and the keys do appear to work.
> 
> That problem does appear to be fixed.
> 

Excellent news.

> It doesn't look like the 'insert' key toggles between insert / overstrike 
> when I use the Win3 wordpad to read a file.  However, this is in the regular 
> qemu 0.70, so I don't know if it's a problem with qemu, or Win 3 wordpad.
> 

I don't have a copy of Windows 3 (3.0, 3.1, WfW, or 3.11), so I am not able
to test this.

Windows 98 Wordpad has no issues with the insert key for qemu-gtk.

> Now, while running my Win 3 test image, I notice that double clicking 
> doesn't work.  I couldn't get anything to open up no matter how fast I 
> clicked.
> 
> Single clicking works okay, though.
> 

Again, I can't test Windows 3.

However, under Windows 98 double clicking does seem to have problems. It does
work for me ocassionally (if I keep clicking hard and fast enough - more
"stream clicking" than double clicking), but there are clear issues.

The way GTK/GDK deals with single, double, and triple clicks is weird. I'll
take a much closer look at it.

> 
> > qemu under gtk usable. Also I modified it so it lets u know when u are 
> > using GTK.
> 
> I noticed that immediately when I ran it...  Nice.  Thanks.
> 

Never a problem. Like I said, it was a dumb oversight on my part.

> > Still, I work with what I have to go on. Try this gtk2.c and report any 
> > errors
> > (be they compile errors or runtime errors or keyboard problems). Your help 
> > is
> > always greatly appreciated.
> 
> I'm glad I'm able to help.
> 
> The previous qemu errors I've reported have been completely ignored!
> 
> At least you are taking an active interest in what a mere user has to 
> say....
> 

I don't think that I am exceptional in this. Most developers are happy to
fix bugs that users report (time permitting of course). It simply looks like
qemu is lacking dedicated Windows developers. At least, thats how it looks to
me.

I know of only 1 real developer of qemu under windows. But he works on a
separate tree (C code cleaned up to compile under MSVC, different IDE and VGA/
Cirrus code, etc).

-- 
Infinite complexity begets infinite beauty.
Infinite precision begets infinite perfection.

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [Qemu-devel] Build environment image
  2005-06-21 20:32                     ` [Qemu-devel] Build environment image Tim Walker
@ 2005-06-24 17:19                       ` Tim Walker
  2005-06-24 17:48                         ` John R. Hogerhuis
  2005-06-24 18:07                         ` [Qemu-devel] " Christian MICHON
  0 siblings, 2 replies; 59+ messages in thread
From: Tim Walker @ 2005-06-24 17:19 UTC (permalink / raw)
  To: qemu-devel

Is this a bad idea for some reason, or is it just unnecessary? Some 
feedback would be appreciated.

Cheers,

Tim

Tim Walker wrote:

> How difficult would it be to create a (presumably Linux) uniform build 
> environment for all targets as a bootable Qemu image?
>
>
> _______________________________________________
> Qemu-devel mailing list
> Qemu-devel@nongnu.org
> http://lists.nongnu.org/mailman/listinfo/qemu-devel
>

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [Qemu-devel] Build environment image
  2005-06-24 17:19                       ` Tim Walker
@ 2005-06-24 17:48                         ` John R. Hogerhuis
  2005-06-24 18:24                           ` Christian MICHON
  2005-06-24 19:13                           ` jeebs
  2005-06-24 18:07                         ` [Qemu-devel] " Christian MICHON
  1 sibling, 2 replies; 59+ messages in thread
From: John R. Hogerhuis @ 2005-06-24 17:48 UTC (permalink / raw)
  To: qemu-devel

On Fri, 2005-06-24 at 18:19 +0100, Tim Walker wrote:
> Is this a bad idea for some reason, or is it just unnecessary? Some 
> feedback would be appreciated.
> 


It's a cool idea, I think. I went through the mingw thing a while back
and it's a PITA. It would be nice to have known working build platform
preconfigured that anyone can download.

I imagine the speed wouldn't be fantastic though. Another possibility:

To make it faster you could integrate the build into a Live CD like Damn
Small Linux (it can easily remaster itself with gcc and whatever other
Debian components you need to build QEMU).

Then any Windows user should be able to boot DSL, run a script to get
latest sources from CVS and build QEMU for Windows saving the .EXE to
their Windows partition.

BTW, one problem with WIndows is that QEMU developers do not have access
to Windows licenses. Might be nice for non-programmers who want to
contribute to donate old licensed copies of Windows for testing work. 

-- John.

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [Qemu-devel] Build environment image
  2005-06-24 17:19                       ` Tim Walker
  2005-06-24 17:48                         ` John R. Hogerhuis
@ 2005-06-24 18:07                         ` Christian MICHON
  1 sibling, 0 replies; 59+ messages in thread
From: Christian MICHON @ 2005-06-24 18:07 UTC (permalink / raw)
  To: qemu-devel

you would probably need to setup cross compilers at least,
find a global linux config file generic enough (ex: no framebuffer),
and at least a initrd with minimum bins (static busybox would be
best).

This also implies you've a lot of time free :) if you want to do it for
many architectures/targets.

I'm trying to build one on x86, but to gather the patches and
generic features I want (I want as small as possible) is consuming
much time already.

Christian

On 6/24/05, Tim Walker <tim@astolat-it.co.uk> wrote:
> Is this a bad idea for some reason, or is it just unnecessary? Some
> feedback would be appreciated.
> 
> Cheers,
> 
> Tim
> 
> Tim Walker wrote:
> 
> > How difficult would it be to create a (presumably Linux) uniform build
> > environment for all targets as a bootable Qemu image?
> >
> >
> > _______________________________________________
> > Qemu-devel mailing list
> > Qemu-devel@nongnu.org
> > http://lists.nongnu.org/mailman/listinfo/qemu-devel
> >
> 
> 
> 
> _______________________________________________
> Qemu-devel mailing list
> Qemu-devel@nongnu.org
> http://lists.nongnu.org/mailman/listinfo/qemu-devel
> 


-- 
Christian

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [Qemu-devel] Build environment image
  2005-06-24 17:48                         ` John R. Hogerhuis
@ 2005-06-24 18:24                           ` Christian MICHON
  2005-06-24 18:41                             ` John R. Hogerhuis
  2005-06-24 19:09                             ` jeebs
  2005-06-24 19:13                           ` jeebs
  1 sibling, 2 replies; 59+ messages in thread
From: Christian MICHON @ 2005-06-24 18:24 UTC (permalink / raw)
  To: jhoger, qemu-devel

> BTW, one problem with WIndows is that QEMU developers do not have access
> to Windows licenses. Might be nice for non-programmers who want to
> contribute to donate old licensed copies of Windows for testing work.
> 

untrue.
http://www.microsoft.com/windowsserver2003/evaluation/trial/default.mspx

that would give 6 months to complete development...

Christian

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [Qemu-devel] Build environment image
  2005-06-24 18:24                           ` Christian MICHON
@ 2005-06-24 18:41                             ` John R. Hogerhuis
  2005-06-24 18:41                               ` Christian MICHON
  2005-06-24 19:09                             ` jeebs
  1 sibling, 1 reply; 59+ messages in thread
From: John R. Hogerhuis @ 2005-06-24 18:41 UTC (permalink / raw)
  To: Christian MICHON; +Cc: qemu-devel

On Fri, 2005-06-24 at 20:24 +0200, Christian MICHON wrote:
> > BTW, one problem with WIndows is that QEMU developers do not have access
> > to Windows licenses. Might be nice for non-programmers who want to
> > contribute to donate old licensed copies of Windows for testing work.
> > 
> 
> untrue.
> http://www.microsoft.com/windowsserver2003/evaluation/trial/default.mspx
> 
> that would give 6 months to complete development...
> 
> Christian
> 
> 

For whatever reason I was thinking more along the lines of testing
historical Windows OSes under QEMU, but good suggestion.

-- John.

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [Qemu-devel] Build environment image
  2005-06-24 18:41                             ` John R. Hogerhuis
@ 2005-06-24 18:41                               ` Christian MICHON
  0 siblings, 0 replies; 59+ messages in thread
From: Christian MICHON @ 2005-06-24 18:41 UTC (permalink / raw)
  To: qemu-devel

> For whatever reason I was thinking more along the lines of testing
> historical Windows OSes under QEMU, but good suggestion.

but keep in mind the following. You can install the eval 2003 sp1 on
only one machine. So make it a qemu one :)

Christian

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [Qemu-devel] Build environment image
  2005-06-24 18:24                           ` Christian MICHON
  2005-06-24 18:41                             ` John R. Hogerhuis
@ 2005-06-24 19:09                             ` jeebs
  1 sibling, 0 replies; 59+ messages in thread
From: jeebs @ 2005-06-24 19:09 UTC (permalink / raw)
  To: Qemu mailing list

"Christian MICHON"
>untrue.
>http://www.microsoft.com/windowsserver2003/evaluation/trial/default.mspx
>
>that would give 6 months to complete development...

I think they did one of them for a year.

However, I doubt they'd appreciate you distributing anything of theirs...


Can ReactOS be used to host a Win build system?

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [Qemu-devel] Build environment image
  2005-06-24 17:48                         ` John R. Hogerhuis
  2005-06-24 18:24                           ` Christian MICHON
@ 2005-06-24 19:13                           ` jeebs
  2005-06-24 20:25                             ` John R. Hogerhuis
  1 sibling, 1 reply; 59+ messages in thread
From: jeebs @ 2005-06-24 19:13 UTC (permalink / raw)
  To: Qemu mailing list

"John R. Hogerhuis"

> BTW, one problem with WIndows is that QEMU developers do not have access
> to Windows licenses. Might be nice for non-programmers who want to
> contribute to donate old licensed copies of Windows for testing work.

Does the ReactOS build work well enough to do Mingw etc. development?


I know you were talking about testing etc., but I was thinking that way you
could have a window'ish environment to do some of the building.

You wouldn't have to do a linux cross compile which might introduce some
other issues or mask some Win32 host build problem.

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [Qemu-devel] Build environment image
  2005-06-24 19:13                           ` jeebs
@ 2005-06-24 20:25                             ` John R. Hogerhuis
  2005-06-24 20:52                               ` jeebs
  2005-06-24 21:30                               ` Tim Walker
  0 siblings, 2 replies; 59+ messages in thread
From: John R. Hogerhuis @ 2005-06-24 20:25 UTC (permalink / raw)
  To: qemu-devel

On Fri, 2005-06-24 at 14:13 -0500, jeebs@yango.us wrote:
> "John R. Hogerhuis"
> 
> > BTW, one problem with WIndows is that QEMU developers do not have access
> > to Windows licenses. Might be nice for non-programmers who want to
> > contribute to donate old licensed copies of Windows for testing work.
> 
> Does the ReactOS build work well enough to do Mingw etc. development?
> 
> 

I can't say. But even if it were, I'd guess most here would rather work
under Unix-like OS.

> I know you were talking about testing etc., but I was thinking that way you
> could have a window'ish environment to do some of the building.
> 
> You wouldn't have to do a linux cross compile which might introduce some
> other issues or mask some Win32 host build problem.

Nothing wrong with cross compiling, really. Get full power of any
necessary GNU utilities, editors, etc. in their "native environment."
The only trouble is getting mingw, library dependencies, etc. set up in
the first place, and having a standard build image or Live CD is one
possible solution to that problem.

-- John.

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [Qemu-devel] Build environment image
  2005-06-24 20:25                             ` John R. Hogerhuis
@ 2005-06-24 20:52                               ` jeebs
  2005-06-28 18:39                                 ` Jim C. Brown
  2005-06-24 21:30                               ` Tim Walker
  1 sibling, 1 reply; 59+ messages in thread
From: jeebs @ 2005-06-24 20:52 UTC (permalink / raw)
  To: qemu-devel

"John R. Hogerhuis"

>
> I can't say. But even if it were, I'd guess most here would rather work
> under Unix-like OS.

Undoubtably.

The Linux builders outnumber the Win builders by probably 50 to one.  If not 
more.

But I know from the effort I went through to get qemu to build under windows 
that it can indeed be a problem.

And it's a bit sensitive to what other stuff you may install.  And which 
version of Mingw you do.  (Older works, newer doesn't.)


> The only trouble is getting mingw, library dependencies, etc. set up in
> the first place, and having a standard build image or Live CD is one
> possible solution to that problem.

Well, when I was building the gtk version for Jim, we did encounter a 
situation with the libraries.

His build didn't use the same settings as the prebuilt ones did for Windows.

And a library header was in a different location than expected.

A linux environment might be inclined to just build the whole thing.  And to 
use paths as located in linux.

It's also possible that developers may introduce more linux specific stuff 
without even realizing it.

I'm just saying that some Win build issues might show up that you didn't 
think about while doing a Linux one.

And by providing both a Win and a Linux version, developers can test both 
build environments.


Realistically, it wouldn't be all that hard to set up a ReactOS setup. 
There are directions on the qemu user forum for doing a Mingw build.  I have 
a copy, so I could post those.  CoMiKe did an excellent job.

I could probably do it except that don't know how to do the scripts under 
msys (probably just command files, right?) and I have no way to send anybody 
a large disk image.

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [Qemu-devel] Build environment image
  2005-06-24 20:25                             ` John R. Hogerhuis
  2005-06-24 20:52                               ` jeebs
@ 2005-06-24 21:30                               ` Tim Walker
  2005-06-24 21:55                                 ` John R. Hogerhuis
  2005-06-24 22:46                                 ` [Qemu-devel] " Ronald
  1 sibling, 2 replies; 59+ messages in thread
From: Tim Walker @ 2005-06-24 21:30 UTC (permalink / raw)
  To: qemu-devel

Thanks for the replies.

I thought the Live CD was a bad idea until I realised it can still be 
booted under QEMU for non x86 users (Live CDs can be created for other 
platforms - have to pick one otherwise it'd be a nightmare). The 
tradeoff would be speed for x86 users vs ease of image maintenance and 
build environment precision (host processor). There is an appealing 
match between the desired uniformity of build environment and QEMU's aim 
to uniformly emulate different platforms regardless of host. It could 
also be a good test of QEMU itself in the same way GCC self compiles.

Cross compile to Windows from Linux is an unknown quantity to me - has 
anyone tried it yet with QEMU?

Depending on how it's used this could either be a two edged sword or a 
virtuous circle - headlines of "Convenient Build Environment demands 
massive investment of time to keep functional" or "Convenient Build 
Environment helps find QEMU inconsistencies and vice versa". Something 
like that.

Cheers,

Tim

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [Qemu-devel] Build environment image
  2005-06-24 21:30                               ` Tim Walker
@ 2005-06-24 21:55                                 ` John R. Hogerhuis
  2005-06-24 22:46                                 ` [Qemu-devel] " Ronald
  1 sibling, 0 replies; 59+ messages in thread
From: John R. Hogerhuis @ 2005-06-24 21:55 UTC (permalink / raw)
  To: qemu-devel

On Fri, 2005-06-24 at 22:30 +0100, Tim Walker wrote:
> Thanks for the replies.
> 
> I thought the Live CD was a bad idea until I realised it can still be 
> booted under QEMU for non x86 users (Live CDs can be created for other 
> platforms - have to pick one otherwise it'd be a nightmare). The 
> tradeoff would be speed for x86 users vs ease of image maintenance and 
> build environment precision (host processor). There is an appealing 
> match between the desired uniformity of build environment and QEMU's aim 
> to uniformly emulate different platforms regardless of host. It could 
> also be a good test of QEMU itself in the same way GCC self compiles.
> 

Yes, the idea would be to have a built QEMU.EXE so that you could boot
the livecd under windows.

I would think the more likely thing to do is to boot it into linux and
run it native. DSL will run completely from RAMdisk (in that mode it's
actually faster than a native install) but it depends on how much memory
you have.

As to non x86 platforms, yeah the the live CD could be run under QEMU. I
don't know how many folks are itching to build for Windows under PowerPC
or ARM, but hack, who knows...

> Cross compile to Windows from Linux is an unknown quantity to me - has 
> anyone tried it yet with QEMU?
> 

I believe I had it working at some point. mingw cross compiler is in
Debian.

> Depending on how it's used this could either be a two edged sword or a 
> virtuous circle - headlines of "Convenient Build Environment demands 
> massive investment of time to keep functional" or "Convenient Build 
> Environment helps find QEMU inconsistencies and vice versa". Something 
> like that.
> 

Yes, there would be no point in doing this if it is very hard to do and
keep maintained.  Which is why I suggest DSL which has some package
management and remastering stuff built-in. Also you have full access to
Debian apt repositories, including mingw.

-- John.

^ permalink raw reply	[flat|nested] 59+ messages in thread

* [Qemu-devel] Re: Build environment image
  2005-06-24 21:30                               ` Tim Walker
  2005-06-24 21:55                                 ` John R. Hogerhuis
@ 2005-06-24 22:46                                 ` Ronald
  1 sibling, 0 replies; 59+ messages in thread
From: Ronald @ 2005-06-24 22:46 UTC (permalink / raw)
  To: qemu-devel

Le Fri, 24 Jun 2005 22:30:40 +0100, Tim Walker a écrit :

> Cross compile to Windows from Linux is an unknown quantity to me - has
> anyone tried it yet with QEMU?

the win32 installers on FreeOSZoo are build on a linux box :) 
 
> Tim

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [Qemu-devel] quick gtk2.c update
  2005-06-24  0:32                                         ` Jim C. Brown
@ 2005-06-26 16:13                                           ` Jim C. Brown
  2005-06-27 17:11                                             ` jeebs
  0 siblings, 1 reply; 59+ messages in thread
From: Jim C. Brown @ 2005-06-26 16:13 UTC (permalink / raw)
  To: qemu-devel

[-- Attachment #1: Type: text/plain, Size: 851 bytes --]

On Wed, Jun 22, 2005 at 09:26:11PM -0500, jeebs@yango.us wrote:
> Now, while running my Win 3 test image, I notice that double clicking 
> doesn't work.  I couldn't get anything to open up no matter how fast I 
> clicked.
> 

This should be fixed now. (At least, this now works in Windows 98 and XP.) I
managed to combine the 3 separate mouse handlers into a single function as well,
so there is less redundant code.

Also, I managed to get rid of the all of the GTK warnings.

Most fullscreen glitches are gone now. (The only one left is that, if you change
video modes in the guest while in fullscreen mode, the window might move around
randomly. For now, switching out of fullscreen and then back in will set things
right again.)

New gtk2.c attached.

-- 
Infinite complexity begets infinite beauty.
Infinite precision begets infinite perfection.

[-- Attachment #2: gtk2.c --]
[-- Type: text/plain, Size: 21646 bytes --]

/*
 * QEMU GTK2 display driver
 * based on SDL driver by Fabrice
 * 
 * Copyright (c) 2005 Jim Brown
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
#include "vl.h"

#include <gtk/gtk.h>
#include <gdk/gdk.h>

#include "fullscreen.h"

/* define our own bitshift enums to allow qemugtk to know difference between left and right alt - something gtk doesnt provide in its modifiers mask. this uses qemu's own modifier_state[] map in order to guess correctly */
typedef enum
{
	gtkshiftleft = 1 << 0,
	gtkshiftright = 1 << 1,
	gtkcontrolleft = 1 << 2,
	gtkcontrolright = 1 << 3,
	gtkaltleft = 1 << 4,
	gtkaltright = 1 << 5,
	gtkcapslock = 1 << 6
} gtk2keymod;


static GtkWidget *screen;
static GdkImage *image=NULL;
static GdkCursor *invisible_cursor;
static int ox = 0, oy = 0;
static int gui_grab; /* if true, all keyboard/mouse events are grabbed */
static int last_vm_running;
static int gui_saved_grab;
static int gui_fullscreen;
static int gui_key_modifier_pressed;
static int gui_keysym;
static int gui_fullscreen_initial_grab;
static int gui_grab_code = gtkaltleft | gtkcontrolleft;
static uint8_t modifiers_state[256];
static unsigned int cw, ch;
static gint cx, cy;

static gboolean gtk2_expose(GtkWidget *wid, GdkEventExpose *event)
{
    gdk_draw_image(wid->window, wid->style->fg_gc[GTK_WIDGET_STATE(wid)], image, event->area.x, event->area.y, event->area.x, event->area.y, event->area.width, event->area.height);
    return TRUE;
}

static void gtk2_update(DisplayState *ds, int x, int y, int w, int h)
{
    //    printf("updating x=%d y=%d w=%d h=%d\n", x, y, w, h);
    GdkEventExpose ev;
    ev.area.x = x;
    ev.area.y = y;
    ev.area.width = w;
    ev.area.height = h;
    /* catch the first resize done by the init function - make sure we don't **
    ** try to draw an image until screen has been finalized/realized/etc */
    if (screen->window != NULL)
	gtk2_expose(screen, &ev);
}

static void gtk2_resize(DisplayState *ds, int w, int h)
{

    //    printf(" resizing to %d %d\n", w, h);

    if (gui_fullscreen)
    {
	if (cw != w || ch != h)
	{
	    fullscreen_switch(cx, cy, w, h); /* changing video modes */
/* apparently GTK enjoys moving static windows all over the place while
they are being resized - so we have to be tricky */
	    gtk_window_move(GTK_WINDOW(screen), cx, cy);
	    gtk_window_move(GTK_WINDOW(screen), 0, 0);
	}
    }

    cw = w; ch = h;

    if (image)
	 g_object_unref(image);

/* gdk_visual_get_best_with_depth() ??? but then how to paint onto window? */
    image = gdk_image_new(GDK_IMAGE_NORMAL, gdk_visual_get_system(), w, h);
    gdk_image_set_colormap(image, gdk_colormap_get_system());

    gtk_window_set_default_size(GTK_WINDOW(screen), w, h);
    gtk_widget_set_size_request(screen, w, h);
    gtk_window_resize(GTK_WINDOW(screen), w, h);

    ds->data = image->mem;
    ds->linesize = image->bpl;
    ds->depth = image->bits_per_pixel;
    ds->width = w;
    ds->height = h;
    gtk2_update(ds, 0, 0, w, h);
}

/* generic keyboard conversion */

#include "gdk_keysym.h"
#include "keymaps.c"

static kbd_layout_t *kbd_layout = NULL;

static uint8_t gtk2_keyevent_to_keycode_generic(const GdkEventKey *ev)
{
    int keysym;
    /* workaround for X11+SDL bug with AltGR - is it still needed for Gtk2? */
    keysym = ev->keyval;
    if (keysym == 0 && ev->hardware_keycode == 113)
	keysym = GDK_Mode_switch;
    return keysym2scancode(kbd_layout, keysym);
}

/* specific keyboard conversions from scan codes */

#if defined(_WIN32)

#include <windows.h>

static UINT vk2scan(UINT vk)
{
	return MapVirtualKey(vk,0);
}
static uint8_t gtk2_keyevent_to_keycode(const GdkEventKey *ev)
{   
    return (uint8_t)vk2scan((UINT)(ev->hardware_keycode));
}

#else

static const uint8_t x_keycode_to_pc_keycode[61] = {
   0xc7,      /*  97  Home   */
   0xc8,      /*  98  Up     */
   0xc9,      /*  99  PgUp   */
   0xcb,      /* 100  Left   */
   0x4c,        /* 101  KP-5   */
   0xcd,      /* 102  Right  */
   0xcf,      /* 103  End    */
   0xd0,      /* 104  Down   */
   0xd1,      /* 105  PgDn   */
   0xd2,      /* 106  Ins    */
   0xd3,      /* 107  Del    */
   0x9c,      /* 108  Enter  */
   0x9d,      /* 109  Ctrl-R */
   0x0,       /* 110  Pause  */
   0xb7,      /* 111  Print  */
   0xb5,      /* 112  Divide */
   0xb8,      /* 113  Alt-R  */
   0xc6,      /* 114  Break  */   
   0x0,         /* 115 */
   0x0,         /* 116 */
   0x0,         /* 117 */
   0x0,         /* 118 */
   0x0,         /* 119 */
   0x70,         /* 120 Hiragana_Katakana */
   0x0,         /* 121 */
   0x0,         /* 122 */
   0x73,         /* 123 backslash */
   0x0,         /* 124 */
   0x0,         /* 125 */
   0x0,         /* 126 */
   0x0,         /* 127 */
   0x0,         /* 128 */
   0x79,         /* 129 Henkan */
   0x0,         /* 130 */
   0x7b,         /* 131 Muhenkan */
   0x0,         /* 132 */
   0x7d,         /* 133 Yen */
   0x0,         /* 134 */
   0x0,         /* 135 */
   0x47,         /* 136 KP_7 */
   0x48,         /* 137 KP_8 */
   0x49,         /* 138 KP_9 */
   0x4b,         /* 139 KP_4 */
   0x4c,         /* 140 KP_5 */
   0x4d,         /* 141 KP_6 */
   0x4f,         /* 142 KP_1 */
   0x50,         /* 143 KP_2 */
   0x51,         /* 144 KP_3 */
   0x52,         /* 145 KP_0 */
   0x53,         /* 146 KP_. */
   0x47,         /* 147 KP_HOME */
   0x48,         /* 148 KP_UP */
   0x49,         /* 149 KP_PgUp */
   0x4b,         /* 150 KP_Left */
   0x4c,         /* 151 KP_ */
   0x4d,         /* 152 KP_Right */
   0x4f,         /* 153 KP_End */
   0x50,         /* 154 KP_Down */
   0x51,         /* 155 KP_PgDn */
   0x52,         /* 156 KP_Ins */
   0x53,         /* 157 KP_Del */
};

static uint8_t gtk2_keyevent_to_keycode(const GdkEventKey *ev)
{
    int keycode;

    keycode = ev->hardware_keycode;

    if (keycode < 9) {
	keycode = 0;
    } else if (keycode < 97) {
	keycode -= 8; /* just an offset */
    } else if (keycode < 158) {
	/* use conversion table */
	keycode = x_keycode_to_pc_keycode[keycode - 97];
    } else {
	keycode = 0;
    }
    return keycode;
}

#endif

static void reset_keys(void)
{
    int i;
    for(i = 0; i < 256; i++) {
	if (modifiers_state[i]) {
	    if (i & 0x80)
		kbd_put_keycode(0xe0);
	    kbd_put_keycode(i | 0x80);
	    modifiers_state[i] = 0;
	}
    }
}

/* convert GDK modifiers and invoke ugly hack to distinguish
between left and right shift/control/alt */
static guint gtk2_GetModState(const GdkEventKey *ev)
{
	guint key = 0, keyval = ev->keyval, state = ev->state;
	switch(keyval)
	{
		case GDK_Shift_L:
			if (ev->type != GDK_KEY_RELEASE)
				key |= gtkshiftleft;
			keyval = 1;
			break;
		case GDK_Shift_R:
			if (ev->type != GDK_KEY_RELEASE)
				key |= gtkshiftright;
			keyval = 1;
			break;
		case GDK_Control_L:
			if (ev->type != GDK_KEY_RELEASE)
				key |= gtkcontrolleft;
			keyval = 2;
			break;
		case GDK_Control_R:
			if (ev->type != GDK_KEY_RELEASE)
				key |= gtkcontrolright;
			keyval = 2;
			break;
		case GDK_Alt_L:
			if (ev->type != GDK_KEY_RELEASE)
				key |= gtkaltleft;
			keyval = 3;
			break;
		case GDK_Alt_R:
			if (ev->type != GDK_KEY_RELEASE)
				key |= gtkaltright;
			keyval = 3;
			break;
		case GDK_Caps_Lock:
			if (ev->type != GDK_KEY_RELEASE)
				key |= gtkcapslock;
			keyval = 4;
			break;
		default:
			keyval = 0;
			break;
	}
	if (keyval != 1 && (state & GDK_SHIFT_MASK))
	{
		if (modifiers_state[0x2a])
			key |= gtkshiftleft;
		if (modifiers_state[0x36])
			key |= gtkshiftright;
	}
	if (keyval != 2 && (state & GDK_CONTROL_MASK))
	{
		if (modifiers_state[0x1d])
			key |= gtkcontrolleft;
		if (modifiers_state[0x9d])
			key |= gtkcontrolright;
	}
	if (keyval != 3 && (state & GDK_MOD1_MASK)) /* fixme: need to do a check to make sure that alt is mapped to GDK_MOD1_MASK in the GDK_Keymap */
	{
		if (modifiers_state[0x38])
			key |= gtkaltleft;
		if (modifiers_state[0xb8])
			key |= gtkaltright;
	}
	if (keyval != 4 && (state & GDK_LOCK_MASK))
		key |= gtkcapslock;
	return key;
}

static void gtk2_process_key(GdkEventKey *ev)
{
    int keycode, v;

    if (ev->keyval == GDK_Pause) {
	/* specific case */
	v = 0;
	if (ev->type == GDK_KEY_RELEASE)
	    v |= 0x80;
	kbd_put_keycode(0xe1);
	kbd_put_keycode(0x1d | v);
	kbd_put_keycode(0x45 | v);
	return;
    }

    if (kbd_layout) {
	keycode = gtk2_keyevent_to_keycode_generic(ev);
    } else {
	keycode = gtk2_keyevent_to_keycode(ev);
    }

    switch(keycode) {
    case 0x00:
	/* sent when leaving window: reset the modifiers state */
	reset_keys();
	return;
    case 0x2a:                          /* Left Shift */
    case 0x36:                          /* Right Shift */
    case 0x1d:                          /* Left CTRL */
    case 0x9d:                          /* Right CTRL */
    case 0x38:                          /* Left ALT */
    case 0xb8:                         /* Right ALT */
	if (ev->type == GDK_KEY_RELEASE)
	    modifiers_state[keycode] = 0;
	else
	    modifiers_state[keycode] = 1;
	break;
    case 0x45: /* num lock */
    case 0x3a: /* caps lock */
	/* GTK does send the key up event, so we dont generate it */
	/*kbd_put_keycode(keycode);
	kbd_put_keycode(keycode | 0x80);
	return;*/
	break;
    }

    /* now send the key code */
    if (keycode & 0x80)
	kbd_put_keycode(0xe0);
    if (ev->type == GDK_KEY_RELEASE)
	kbd_put_keycode(keycode | 0x80);
    else
	kbd_put_keycode(keycode & 0x7f);
}

static void gtk2_update_caption(void)
{
    char buf[1024];
    strcpy(buf, "QEMU Gtk");
    if (!vm_running) {
	strcat(buf, " [Stopped]");
    }
    if (gui_grab) {
	strcat(buf, " - Press Ctrl-Alt to exit grab");
    }
    gtk_window_set_title(GTK_WINDOW(screen), buf);
}

/* what a nasty hack. this should be a part of the GDK, not external!!! */
#include "gdk_set_window_pointer.c"

static void gtk2_grab_start(void)
{
    gint y;
    guint events;
    GdkModifierType state; /* dummy var */
    events = GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_SCROLL_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK;
    y = gdk_pointer_grab(screen->window, TRUE, events, screen->window, invisible_cursor, GDK_CURRENT_TIME);
    if (y)
	printf("GTK Warning - pointer grab failed!\n");
    y = gdk_keyboard_grab(screen->window, TRUE, GDK_CURRENT_TIME);
    if (y)
	printf("GTK Warning - keyboard grab failed!\n");
    /* do a dummy read to avoid moving mouse - set ox and oy to stay in sync */
    gdk_window_get_pointer(screen->window, &ox, &oy, &state);
    gui_grab = 1;
    gtk2_update_caption();
}

static void gtk2_grab_end(void)
{
    gdk_pointer_ungrab(GDK_CURRENT_TIME);
    gdk_keyboard_ungrab(GDK_CURRENT_TIME);
    gdk_window_set_pointer(screen->window, cx, cy);
    gui_grab = 0;
    gtk2_update_caption();
}

static gboolean gtk2_send_mouse_event(GtkWidget *wid, GdkEvent *ev)
{
    int x, y, dx, dy, dz, state, buttons;

    if (ev->type == GDK_2BUTTON_PRESS || ev->type == GDK_3BUTTON_PRESS)
	return TRUE; /* double or triple click - superflurious - ignore */

    if (gui_grab)
    {

    if (ev->type == GDK_MOTION_NOTIFY && ev->motion.is_hint)
    {
	gdk_window_get_pointer(ev->motion.window, &x, &y, (GdkModifierType*)&state);
    }
    else
    {
	x = ev->motion.x;
	y = ev->motion.y;
	/* scroll.state occupies a different position in the union */
	if (ev->type == GDK_SCROLL)
	state = ev->scroll.state;
	else
	state = ev->motion.state;
    }

    dx = x - ox;
    dy = y - oy;
    // prevent infinite looping - 2.6.X
    if ((ev->type == GDK_MOTION_NOTIFY) && (dx == 0) && (dy == 0)) return TRUE;
    dz = 0;
    ox = x;
    oy = y;

    buttons = 0;
    if ((state & GDK_BUTTON1_MASK))
	buttons |= MOUSE_EVENT_LBUTTON;
    if ((state & GDK_BUTTON3_MASK))
	buttons |= MOUSE_EVENT_RBUTTON;
    if ((state & GDK_BUTTON2_MASK))
	buttons |= MOUSE_EVENT_MBUTTON;

    if (ev->type == GDK_BUTTON_PRESS)
    {
	if (ev->button.button == 1)
	    buttons |= MOUSE_EVENT_LBUTTON;
	if (ev->button.button == 3)
	    buttons |= MOUSE_EVENT_RBUTTON;
	if (ev->button.button == 2)
	    buttons |= MOUSE_EVENT_MBUTTON;
    }
    else if (ev->type == GDK_BUTTON_RELEASE)
    {
    /* not sure if this is really necessary, but just to be on the safe side **
    ** reset qemu's mask so that a button thats being released will be shown **
    * missing from the mask (which lets the guest know the button was relased */
	buttons = 0;

	if ((state & GDK_BUTTON1_MASK) && ev->button.button != 1)
	    buttons |= MOUSE_EVENT_LBUTTON;
	if ((state & GDK_BUTTON3_MASK) && ev->button.button != 3)
	    buttons |= MOUSE_EVENT_RBUTTON;
	if ((state & GDK_BUTTON2_MASK) && ev->button.button != 2)
	    buttons |= MOUSE_EVENT_MBUTTON;
    }
    else if (ev->type == GDK_SCROLL)
    {
	/* test wheel - copied from Sebastien Bechet's gtk.c */
	if (ev->scroll.direction == GDK_SCROLL_UP)
	    dz--;
	if (ev->scroll.direction == GDK_SCROLL_DOWN)
	    dz++;
    }

    if (ev->type == GDK_MOTION_NOTIFY)
    {
	/* wrap the x,y coordinates back onto the window */
	if (ev->motion.x <= (cw/4))
	    x = ((3*cw/4)-1);
	if (ev->motion.y <= (ch/4))
	    y = ((3*ch/4)-1);
	if (ev->motion.x >= (3*cw/4))
	    x = (cw/4)+1;
	if (ev->motion.y >= (3*ch/4))
	    y = (ch/4)+1;

	/* make internal mouse move invisible */
	ox = x;
	oy = y;

	gdk_window_set_pointer(screen->window, (gint)x, (gint)y);
    }

    kbd_mouse_event(dx, dy, dz, buttons);

    }
    else
    {

    if (ev->type == GDK_BUTTON_PRESS && ev->button.button == 1)
    {
	/* start grabbing all events */
	gtk2_grab_start();
    }

    }
    return TRUE;
}

static void toggle_full_screen(DisplayState *ds)
{
    gui_fullscreen = !gui_fullscreen;
    gtk2_resize(ds, image->width, image->height);
    if (gui_fullscreen) {
	gui_saved_grab = gui_grab;
	gtk2_grab_start();
	gtk_window_get_position(GTK_WINDOW(screen), &cx, &cy);
	gtk_window_move(GTK_WINDOW(screen), 0, 0);
	fullscreen_switch(cx, cy, ds->width, ds->height);
    } else {
	fullscreen_reset();
	gtk_window_move(GTK_WINDOW(screen), cx, cy);
	if (!gui_saved_grab)
	    gtk2_grab_end();
    }
    vga_invalidate_display();
    vga_update_display();
}

static gboolean gtk2_key_press(GtkWidget *wid, GdkEventKey *ev, DisplayState *ds)
{
	int mod_state;
	    if (ev->type == GDK_KEY_PRESS) {
		mod_state = (gtk2_GetModState(ev) & (int)gui_grab_code) == (int)gui_grab_code;
		gui_key_modifier_pressed = mod_state;
		if (gui_key_modifier_pressed) {
		    int keycode;
		    keycode = gtk2_keyevent_to_keycode(ev);
		    switch(keycode) {
		    case 0x21: /* 'f' key on US keyboard */
			toggle_full_screen(ds);
			gui_keysym = 1;
			break;
		    case 0x02 ... 0x0a: /* '1' to '9' keys */ 
			console_select(keycode - 0x02);
			if (is_active_console(vga_console)) {
			    /* tell the vga console to redisplay itself */
			    vga_invalidate_display();
			} else {
			    /* display grab if going to a text console */
			    if (gui_grab)
				gtk2_grab_end();
			}
			gui_keysym = 1;
			break;
		    default:
			break;
		    }
		} else if (!is_active_console(vga_console)) {
		    int keysym;
		    keysym = 0;
		    if (ev->state & GDK_CONTROL_MASK) {
			switch(ev->keyval) {
			case GDK_Up: keysym = QEMU_KEY_CTRL_UP; break;
			case GDK_Down: keysym = QEMU_KEY_CTRL_DOWN; break;
			case GDK_Left: keysym = QEMU_KEY_CTRL_LEFT; break;
			case GDK_Right: keysym = QEMU_KEY_CTRL_RIGHT; break;
			case GDK_Home: keysym = QEMU_KEY_CTRL_HOME; break;
			case GDK_End: keysym = QEMU_KEY_CTRL_END; break;
			case GDK_Page_Up: keysym = QEMU_KEY_CTRL_PAGEUP; break;
			case GDK_Page_Down: keysym = QEMU_KEY_CTRL_PAGEDOWN; break;
			default: break;
			}
		    } else {
			switch(ev->keyval) {
			case GDK_Up: keysym = QEMU_KEY_UP; break;
			case GDK_Down: keysym = QEMU_KEY_DOWN; break;
			case GDK_Left: keysym = QEMU_KEY_LEFT; break;
			case GDK_Right: keysym = QEMU_KEY_RIGHT; break;
			case GDK_Home: keysym = QEMU_KEY_HOME; break;
			case GDK_End: keysym = QEMU_KEY_END; break;
			case GDK_Page_Up: keysym = QEMU_KEY_PAGEUP; break;
			case GDK_Page_Down: keysym = QEMU_KEY_PAGEDOWN; break;
			case GDK_BackSpace: keysym = QEMU_KEY_BACKSPACE; break;
			case GDK_Delete: keysym = QEMU_KEY_DELETE; break;
			default: break;
			}
		    }
		    if (keysym) {
			kbd_put_keysym(keysym);
		    } /*else if (ev->key.keysym.unicode != 0) {
			kbd_put_keysym(ev->key.keysym.unicode);
		    }*/
		}
	    } else if (ev->type == GDK_KEY_RELEASE) {
		mod_state = (gtk2_GetModState(ev) & gui_grab_code);
		if (!mod_state) {
		    if (gui_key_modifier_pressed) {
			if (gui_keysym == 0) {
			    /* exit/enter grab if pressing Ctrl-Alt */
			    if (!gui_grab)
				gtk2_grab_start();
			    else
				gtk2_grab_end();
			    /* SDL does not send back all the
			       modifiers key, so we must correct it */
			    reset_keys();
			    return TRUE;
			}
			gui_key_modifier_pressed = 0;
			gui_keysym = 0;
		    }
		}
	    }
	    if (is_active_console(vga_console)) 
		gtk2_process_key(ev);
	return TRUE;
}

static void gtk2_refresh(DisplayState *ds)
{
    if (last_vm_running != vm_running) {
	last_vm_running = vm_running;
	gtk2_update_caption();
    }
    if (ds->data != image->mem)
    {
	ds->data = image->mem;
    }

    if (is_active_console(vga_console))                                         
	vga_update_display();                                                   
    while (gtk_events_pending())
	gtk_main_iteration();
}

static void gtk2_cleanup(void) 
{
    if (gtk_main_level() != 0)
	gtk_main_quit();
    fullscreen_cleanup();
}

static gboolean gtk2_deletewin(void)
{
    /* signal qemu that its time to shut itself off - this is the place that we hook to trap attempts to close the main qemu window */
    qemu_system_shutdown_request();
    return FALSE;
    return TRUE; /* dont close the window right away! give qemu time to think */
}

static void gtk2_destroy(void)
{
    /* ideally we would call a hook here so qemu could clean itself up */
    gtk2_cleanup();
}

void gtk2_display_init(DisplayState *ds, int full_screen)
{
    int events;

#if defined(__APPLE__)
    /* always use generic keymaps */
    if (!keyboard_layout)
	keyboard_layout = "en-us";
#endif
    if(keyboard_layout) {
	kbd_layout = init_keyboard_layout(keyboard_layout);
	if (!kbd_layout)
	    exit(1);
    }

    if (!gtk_init_check (0,NULL))
    {
	fprintf(stderr, "Could not load GTK\n");
	exit(0);
    }
    fullscreen_init();

/* note: adding GDK_DRAG_* and GDK_DROP_* would provide a mechanism for supporting drag and drop between host and guest */
    events = GDK_EXPOSURE_MASK | GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK | GDK_FOCUS_CHANGE_MASK | GDK_SCROLL_MASK | GDK_STRUCTURE_MASK;

    screen = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_widget_set_events(screen, events);
    gtk_window_set_default_size(GTK_WINDOW(screen), 720, 400);
    gtk_widget_set_size_request(screen, 720, 400);
    gtk_window_set_gravity(GTK_WINDOW(screen), GDK_GRAVITY_STATIC);
    gtk_window_set_position(GTK_WINDOW(screen), GTK_WIN_POS_CENTER);

    g_signal_connect(G_OBJECT(screen), "delete_event", G_CALLBACK(gtk2_deletewin), NULL);
    g_signal_connect(G_OBJECT(screen), "destroy", G_CALLBACK(gtk2_destroy), NULL);
    gtk_container_set_border_width(GTK_CONTAINER(screen), 10);

    g_signal_connect(G_OBJECT(screen), "expose_event", G_CALLBACK(gtk2_expose), NULL);
    g_signal_connect(G_OBJECT(screen), "motion_notify_event", G_CALLBACK(gtk2_send_mouse_event), NULL);
    g_signal_connect(G_OBJECT(screen), "button_press_event", G_CALLBACK(gtk2_send_mouse_event), NULL);
    g_signal_connect(G_OBJECT(screen), "button_release_event", G_CALLBACK(gtk2_send_mouse_event), NULL);
    g_signal_connect(G_OBJECT(screen), "scroll_event", G_CALLBACK(gtk2_send_mouse_event), NULL);
    g_signal_connect(G_OBJECT(screen), "key_press_event", G_CALLBACK(gtk2_key_press), ds);
    g_signal_connect(G_OBJECT(screen), "key_release_event", G_CALLBACK(gtk2_key_press), ds);

    ds->dpy_update = gtk2_update;
    ds->dpy_resize = gtk2_resize;
    ds->dpy_refresh = gtk2_refresh;

    gchar nullpixdata[1] = { 0 };
    GdkColor nullcolor = { 0, 0, 0, 0 };
    GdkPixmap *invis = gdk_bitmap_create_from_data(screen->window, nullpixdata, 1, 1);
    invisible_cursor = gdk_cursor_new_from_pixmap(invis, invis, &nullcolor, &nullcolor, 0, 0);

    gtk2_resize(ds, 720, 400);
    gtk2_update_caption();
    gui_grab = 0;

    gtk_window_set_policy(GTK_WINDOW(screen), FALSE, FALSE, FALSE);
    gtk_widget_show(screen);
    if (full_screen) {
	gui_fullscreen = 1;
	gui_fullscreen_initial_grab = 1;
	gtk2_grab_start();
    }
}

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [Qemu-devel] quick gtk2.c update
  2005-06-26 16:13                                           ` Jim C. Brown
@ 2005-06-27 17:11                                             ` jeebs
  2005-06-27 18:15                                               ` Jim C. Brown
  0 siblings, 1 reply; 59+ messages in thread
From: jeebs @ 2005-06-27 17:11 UTC (permalink / raw)
  To: qemu-devel

"Jm C. Brown"
>
> This should be fixed now. (At least, this now works in Windows 98 and XP.) 
> I
> managed to combine the 3 separate mouse handlers into a single function as 
> well,
> so there is less redundant code.

It does appear to be fixed.

> Also, I managed to get rid of the all of the GTK warnings.

That's always good.  Although this time I didn't watch it build to see if 
there were any new ones.


There *is* still an <insert> key problem.

I tested it under Win3, Win95 and Win98

That's the only key I've noticed that still has problems.  But I may not 
have tested them all, so I might have missed one or two others.


When I run the gtk version from the qgui program (which just lets you select 
which VM, what options etc., and then runs it) the qemu window doesn't pop 
up as visible.  I have to clcik on its title on the task bar to bring it 
forward.  Probably needs a command to bring it into 'focus' or some such.

> Most fullscreen glitches are gone now. (The only one left is that, if you 
> change

I haven't really tested that much...

Under Win95 guest it doesn't really go 'full screen'.  It's a borderless 
window.  That could be due to Win95 being in 640x480 mode and my real screen 
is larger?


Let me run a couple of tests with Win98.   (Win95 seems to have problems 
with the qemu cirrus card, but that could be due to it being a 'dirty' 
install.)

Okay, it looks like the full screen mode has problems.

First, it doesn't really go 'full screen'.  It just makes a borderless 
window.

That means you can't use a guest window the same size as the host, otherwise 
the host XP toolbar will cover up part of the guest window.  (XP's toolbar 
can be on any side of the screen.  There can even be multiple toobars.  So 
you really can't depend on having any certain amount of visible screen 
available.)

As a test, I decided to see what would happen if I made Win98's screen 
larger than what my real one is.  The results were interesting!

Naturally I couldn't see most of it.  After all, you haven't yet done any 
scrollbars or scaling of the window.  (Actually, scroll bars would be nice, 
but if you can scale the window, then the guest could think you are using 
any size while everything is still fiting nicely into the host window.  That 
could even let you resize the qemu screen to any size you want, and let the 
gtk driver resize the display as needed.)

The interesting part was the mouse behavior!  I ended up with *two* mouse 
cursors on the screen.  And they weren't moving quite right.  I couldn't 
move the guest Win98 one where I needed to.

I don't know if this was a gtk issue, or a Windows host issue....

Let me go try that with the 0.70 SDL build....

Hmmm... I can't get it to do it there.  But I'm not entirely sure of the 
exact steps I did to cause it under GTK.  And of course, the SDL version 
crashes when I try full screen.

Let me try it again with the GTK build...

This time, I didn't even test the full screen mode (since you said it does 
still have problems.).  But, I definetly have mouse problems.  After I 
switched to a screen larger than my real screen, I couldn't move the mouse 
much.  It was very limited amount of movement.  Much less than the visible 
part of the qemu screen was.

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [Qemu-devel] quick gtk2.c update
  2005-06-27 17:11                                             ` jeebs
@ 2005-06-27 18:15                                               ` Jim C. Brown
  0 siblings, 0 replies; 59+ messages in thread
From: Jim C. Brown @ 2005-06-27 18:15 UTC (permalink / raw)
  To: qemu-devel

On Mon, Jun 27, 2005 at 12:11:10PM -0500, jeebs@yango.us wrote:
> >
> > This should be fixed now. (At least, this now works in Windows 98 and XP.) 
> > I
> > managed to combine the 3 separate mouse handlers into a single function as 
> > well,
> > so there is less redundant code.
> 
> It does appear to be fixed.
> 

Excellent.

> > Also, I managed to get rid of the all of the GTK warnings.
> 
> That's always good.  Although this time I didn't watch it build to see if 
> there were any new ones.
> 

I meant the GTK warnings that appear at run time (the "assert failed" warnings).
I've never gotten GTK warnings when building a working version...but I've never
built under Windows either.

> 
> There *is* still an <insert> key problem.
> 
> I tested it under Win3, Win95 and Win98
> 
> That's the only key I've noticed that still has problems.  But I may not 
> have tested them all, so I might have missed one or two others.
> 

Did you test with Windows 98SE?

Windows 98SE has no issues with the insert key when running under GTK in Linux..
which would mean the problem is with VK_INSERT.

> 
> When I run the gtk version from the qgui program (which just lets you select 
> which VM, what options etc., and then runs it) the qemu window doesn't pop 
> up as visible.  I have to clcik on its title on the task bar to bring it 
> forward.  Probably needs a command to bring it into 'focus' or some such.
> 
> > Most fullscreen glitches are gone now. (The only one left is that, if you 
> > change

I should have been clearer.

The glitches that I fixed were for the Xvid fullscreen driver. Windows build
still uses the null fullscreen driver.

> 
> I haven't really tested that much...
> 
> Okay, it looks like the full screen mode has problems.
> 
> First, it doesn't really go 'full screen'.  It just makes a borderless 
> window.
> 

Thats to be expected with the null fullscreen driver. qemu's GTK support
expects the fullscreen driver to change the resolution of the host to match
that of the guest (that way the window will take up the entire screen).

I'm working on an SDL fullscreen driver, but it is uglier. (It'd require
usurping the internal DisplayState structure and replace the GTK routines with
custom SDL versions for the duration of fullscreen mode Exiting fullscreen mode
would then have to restore the GTK routines. Not to mention syncing the 2
frame buffers between switches.)

> That means you can't use a guest window the same size as the host, otherwise 
> the host XP toolbar will cover up part of the guest window.  (XP's toolbar 
> can be on any side of the screen.  There can even be multiple toobars.  So 
> you really can't depend on having any certain amount of visible screen 
> available.)
> 

I never thought about that. Does the XP toolbar show up when using SDL's
fullscreen mode?

> As a test, I decided to see what would happen if I made Win98's screen 
> larger than what my real one is.  The results were interesting!
> 
> The interesting part was the mouse behavior!  I ended up with *two* mouse 
> cursors on the screen. 

That is weird. I've seen that once before, when the pointer grab failed (because
the host pointer was outside the GTK window) but then GDK later grabbed it
anyways. When it did the grab, it failed to render the host pointer invisible.
The effect was a "swirling mouse" in the middle of the guest screen.

> And they weren't moving quite right.  I couldn't 
> move the guest Win98 one where I needed to.
> 

This is expected behavior. Currently the GTK code assumes that the entire window
fits in a single screen. When it grabs the mouse (and after it renders the mouse
invisible), it confines the pointer to an area in the very middle of the window
that is approximately half the size of the full area of the window. When the
host pointer hits the border of this inner area, it is wrapped to the other
side.

Because the GTK window was larger than the screen, when the host pointer hit the
edge of the screen it wouldn't be able to move any more .. which means the guest
pointer wouldn't be able to either. Even if it was at the top corner of the
window.

> I don't know if this was a gtk issue, or a Windows host issue....
> 

It's really a hack around a GDK limitation.

> This time, I didn't even test the full screen mode (since you said it does 
> still have problems.).  But, I definetly have mouse problems.  After I 
> switched to a screen larger than my real screen, I couldn't move the mouse 
> much.  It was very limited amount of movement.  Much less than the visible 
> part of the qemu screen was.
> 

-- 
Infinite complexity begets infinite beauty.
Infinite precision begets infinite perfection.

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [Qemu-devel] Build environment image
  2005-06-24 20:52                               ` jeebs
@ 2005-06-28 18:39                                 ` Jim C. Brown
  0 siblings, 0 replies; 59+ messages in thread
From: Jim C. Brown @ 2005-06-28 18:39 UTC (permalink / raw)
  To: qemu-devel

On Fri, Jun 24, 2005 at 03:52:20PM -0500, jeebs@yango.us wrote:
> "John R. Hogerhuis"
> 
> >
> > I can't say. But even if it were, I'd guess most here would rather work
> > under Unix-like OS.
> 
> Undoubtably.
> 
> The Linux builders outnumber the Win builders by probably 50 to one.  If not 
> more.
> 

I just installed cygwin in my Windows XP inside of qemu. Ah, home away from
home .. at home.

Anyways, this might make for an interesting testing server.

> But I know from the effort I went through to get qemu to build under windows 
> that it can indeed be a problem.
> 
> And it's a bit sensitive to what other stuff you may install.  And which 
> version of Mingw you do.  (Older works, newer doesn't.)
> 

What about cygwin with -mno-cygwin?

> And a library header was in a different location than expected.
> 

I didn't have an actual Windows GTK installation to look at, so I was just
guessing. If I had a properly set up cross compile environment, that probably
wouldn't have happened.

Of course, we'd have to get it right first, but that only has to be done once.

> Well, when I was building the gtk version for Jim, we did encounter a 
> situation with the libraries.
> 
> His build didn't use the same settings as the prebuilt ones did for Windows.
> 
> A linux environment might be inclined to just build the whole thing.  And to 
> use paths as located in linux.
> 
> It's also possible that developers may introduce more linux specific stuff 
> without even realizing it.
> 
> I'm just saying that some Win build issues might show up that you didn't 
> think about while doing a Linux one.
> 

The main issue is a testing environment. E.g. a way to run the compiled code
once the build completes to make sure everything works.

-- 
Infinite complexity begets infinite beauty.
Infinite precision begets infinite perfection.

^ permalink raw reply	[flat|nested] 59+ messages in thread

end of thread, other threads:[~2005-06-28 19:10 UTC | newest]

Thread overview: 59+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-06-19 19:09 [Qemu-devel] quick gtk2.c update Jim C. Brown
2005-06-19 22:25 ` Sebastien Bechet
2005-06-20  0:01   ` Jim C. Brown
2005-06-19 22:57 ` jeebs
2005-06-19 23:53   ` Jim C. Brown
     [not found]     ` <002c01c57535$60064fb0$334d21d1@organiza3bfb0e>
2005-06-20  1:59       ` Jim C. Brown
2005-06-21  2:27         ` jeebs
2005-06-21  2:39           ` Jim C. Brown
2005-06-21  2:58             ` jeebs
2005-06-21  4:28               ` Jim C. Brown
2005-06-21 10:45                 ` Jernej Simončič
2005-06-21 16:27                 ` jeebs
2005-06-21 17:20                   ` Jernej Simončič
2005-06-21 19:40                     ` jeebs
2005-06-21 20:22                       ` Jernej Simončič
2005-06-21 21:19                         ` jeebs
2005-06-21 22:24                           ` Jim C. Brown
2005-06-21 22:45                             ` jeebs
2005-06-21 23:58                               ` Jim C. Brown
2005-06-22  4:14                                 ` jeebs
2005-06-22  5:15                                   ` Damien Mascord
2005-06-22  9:31                                   ` Jernej Simončič
2005-06-22 12:31                                   ` Jim C. Brown
2005-06-22  9:16                                 ` Jernej Simončič
2005-06-22 13:17                                 ` Jim C. Brown
2005-06-22 18:36                                   ` Jim C. Brown
2005-06-22 18:53                                   ` Jim C. Brown
2005-06-22 20:59                                     ` Jim C. Brown
2005-06-23  2:26                                       ` jeebs
2005-06-24  0:32                                         ` Jim C. Brown
2005-06-26 16:13                                           ` Jim C. Brown
2005-06-27 17:11                                             ` jeebs
2005-06-27 18:15                                               ` Jim C. Brown
2005-06-22 13:22                                 ` Jim C. Brown
2005-06-22  3:53                               ` Herbert Poetzl
2005-06-22 12:41                                 ` Jim C. Brown
2005-06-21 21:52                       ` Jim C. Brown
2005-06-21 19:45                   ` Jim C. Brown
2005-06-21 20:32                     ` [Qemu-devel] Build environment image Tim Walker
2005-06-24 17:19                       ` Tim Walker
2005-06-24 17:48                         ` John R. Hogerhuis
2005-06-24 18:24                           ` Christian MICHON
2005-06-24 18:41                             ` John R. Hogerhuis
2005-06-24 18:41                               ` Christian MICHON
2005-06-24 19:09                             ` jeebs
2005-06-24 19:13                           ` jeebs
2005-06-24 20:25                             ` John R. Hogerhuis
2005-06-24 20:52                               ` jeebs
2005-06-28 18:39                                 ` Jim C. Brown
2005-06-24 21:30                               ` Tim Walker
2005-06-24 21:55                                 ` John R. Hogerhuis
2005-06-24 22:46                                 ` [Qemu-devel] " Ronald
2005-06-24 18:07                         ` [Qemu-devel] " Christian MICHON
2005-06-21 10:42               ` [Qemu-devel] quick gtk2.c update Jernej Simončič
2005-06-21 12:36                 ` Jim C. Brown
2005-06-21 16:30                 ` jeebs
2005-06-21 17:25                   ` Jernej Simončič
2005-06-21 10:39           ` Jernej Simončič
2005-06-21 10:32         ` Jernej Simončič

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.