Merge remote-tracking branch 'remotes/afaerber/tags/qom-cpu-for-2.0' into staging

QOM CPUState refactorings / X86CPU

* Deadlock fix for exit requests around CPU reset
* X86CPU x2apic for KVM
* X86CPU model subclasses
* SPARCCPU preparations for model subclasses
* -cpu arguments for arm, cris, lm32, moxie, openrisc, ppc, sh4, uc32
* m68k assertion cleanups
* CPUClass hooks for cpu.h inline functions
* Field movements from CPU_COMMON to CPUState and follow-up cleanups

# gpg: Signature made Thu 13 Mar 2014 19:06:56 GMT using RSA key ID 3E7E013F
# gpg: Good signature from "Andreas Färber <afaerber@suse.de>"
# gpg:                 aka "Andreas Färber <afaerber@suse.com>"

* remotes/afaerber/tags/qom-cpu-for-2.0: (58 commits)
  user-exec: Change exception_action() argument to CPUState
  cputlb: Change tlb_set_page() argument to CPUState
  cputlb: Change tlb_flush() argument to CPUState
  cputlb: Change tlb_flush_page() argument to CPUState
  target-microblaze: Replace DisasContext::env field with MicroBlazeCPU
  target-cris: Replace DisasContext::env field with CRISCPU
  exec: Change cpu_abort() argument to CPUState
  exec: Change memory_region_section_get_iotlb() argument to CPUState
  cputlb: Change tlb_unprotect_code_phys() argument to CPUState
  cpu-exec: Change cpu_resume_from_signal() argument to CPUState
  exec: Change cpu_breakpoint_{insert,remove{,_by_ref,_all}} argument
  exec: Change cpu_watchpoint_{insert,remove{,_by_ref,_all}} argument
  target-ppc: Use PowerPCCPU in PowerPCCPUClass::handle_mmu_fault hook
  translate-all: Change tb_flush_jmp_cache() argument to CPUState
  translate-all: Change tb_gen_code() argument to CPUState
  translate-all: Change cpu_io_recompile() argument to CPUState
  translate-all: Change tb_check_watchpoint() argument to CPUState
  translate-all: Change cpu_restore_state_from_tb() argument to CPUState
  translate-all: Change cpu_restore_state() argument to CPUState
  cpu-exec: Change cpu_loop_exit() argument to CPUState
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
diff --git a/qemu-char.c b/qemu-char.c
index 4d50838..54ed244 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -213,7 +213,7 @@
     s->chr_read = fd_read;
     s->chr_event = fd_event;
     s->handler_opaque = opaque;
-    if (s->chr_update_read_handler)
+    if (fe_open && s->chr_update_read_handler)
         s->chr_update_read_handler(s);
 
     if (!s->explicit_fe_open) {
@@ -1136,13 +1136,14 @@
         if (!s->connected) {
             s->connected = 1;
             qemu_chr_be_generic_open(chr);
+        }
+        if (!chr->fd_in_tag) {
             chr->fd_in_tag = io_add_watch_poll(s->fd, pty_chr_read_poll,
                                                pty_chr_read, chr);
         }
     }
 }
 
-
 static void pty_chr_close(struct CharDriverState *chr)
 {
     PtyCharDriver *s = chr->opaque;
@@ -2509,6 +2510,17 @@
     qemu_chr_be_generic_open(chr);
 }
 
+static void tcp_chr_update_read_handler(CharDriverState *chr)
+{
+    TCPCharDriver *s = chr->opaque;
+
+    remove_fd_in_watch(chr);
+    if (s->chan) {
+        chr->fd_in_tag = io_add_watch_poll(s->chan, tcp_chr_read_poll,
+                                           tcp_chr_read, chr);
+    }
+}
+
 #define IACSET(x,a,b,c) x[0] = a; x[1] = b; x[2] = c;
 static void tcp_chr_telnet_init(int fd)
 {
@@ -2664,6 +2676,7 @@
     chr->get_msgfd = tcp_get_msgfd;
     chr->chr_add_client = tcp_chr_add_client;
     chr->chr_add_watch = tcp_chr_add_watch;
+    chr->chr_update_read_handler = tcp_chr_update_read_handler;
     /* be isn't opened until we get a connection */
     chr->explicit_be_open = true;
 
diff --git a/ui/gtk.c b/ui/gtk.c
index 1851495..c3ac448 100644
--- a/ui/gtk.c
+++ b/ui/gtk.c
@@ -683,6 +683,27 @@
     return TRUE;
 }
 
+static gboolean gd_scroll_event(GtkWidget *widget, GdkEventScroll *scroll,
+                                void *opaque)
+{
+    GtkDisplayState *s = opaque;
+    InputButton btn;
+
+    if (scroll->direction == GDK_SCROLL_UP) {
+        btn = INPUT_BUTTON_WHEEL_UP;
+    } else if (scroll->direction == GDK_SCROLL_DOWN) {
+        btn = INPUT_BUTTON_WHEEL_DOWN;
+    } else {
+        return TRUE;
+    }
+
+    qemu_input_queue_btn(s->dcl.con, btn, true);
+    qemu_input_event_sync();
+    qemu_input_queue_btn(s->dcl.con, btn, false);
+    qemu_input_event_sync();
+    return TRUE;
+}
+
 static gboolean gd_key_event(GtkWidget *widget, GdkEventKey *key, void *opaque)
 {
     GtkDisplayState *s = opaque;
@@ -1229,6 +1250,8 @@
                      G_CALLBACK(gd_button_event), s);
     g_signal_connect(s->drawing_area, "button-release-event",
                      G_CALLBACK(gd_button_event), s);
+    g_signal_connect(s->drawing_area, "scroll-event",
+                     G_CALLBACK(gd_scroll_event), s);
     g_signal_connect(s->drawing_area, "key-press-event",
                      G_CALLBACK(gd_key_event), s);
     g_signal_connect(s->drawing_area, "key-release-event",
diff --git a/ui/input-legacy.c b/ui/input-legacy.c
index 7dc486b..1aa2605 100644
--- a/ui/input-legacy.c
+++ b/ui/input-legacy.c
@@ -333,6 +333,7 @@
     entry->opaque = opaque;
     entry->s = qemu_input_handler_register((DeviceState *)entry,
                                            &legacy_kbd_handler);
+    qemu_input_handler_activate(entry->s);
     return entry;
 }