vigsp_surface_format /*format*/);
typedef void (*vigs_composite_end_cb)(void */*user_data*/,
- bool /*was_started*/);
+ bool /*was_started*/,
+ bool /*dirty*/);
struct vigs_backend
{
#define VIGS_IO_SIZE 0x1000
+#ifndef CONFIG_USE_SHM
+#define VIGS_EXTRA_INVALIDATION (9)
+#else
+#define VIGS_EXTRA_INVALIDATION (0)
+#endif
+
struct work_queue;
typedef struct VIGSState
* Our console.
*/
QemuConsole *con;
+ int invalidate_cnt;
uint32_t reg_con;
uint32_t reg_int;
return;
}
- vigs_server_update_display(s->server);
+ if (vigs_server_update_display(s->server, s->invalidate_cnt)) {
+ /*
+ * 'vigs_server_update_display' could have updated the surface,
+ * so fetch it again.
+ */
+ ds = qemu_console_surface(s->con);
- /*
- * 'vigs_server_update_display' could have updated the surface,
- * so fetch it again.
- */
- ds = qemu_console_surface(s->con);
+ dpy_gfx_update(s->con, 0, 0, surface_width(ds), surface_height(ds));
+ }
- dpy_gfx_update(s->con, 0, 0, surface_width(ds), surface_height(ds));
+ if (s->invalidate_cnt > 0) {
+ s->invalidate_cnt--;
+ }
if (s->reg_con & VIGS_REG_CON_VBLANK_ENABLE) {
s->reg_int |= VIGS_REG_INT_VBLANK_PENDING;
static void vigs_hw_invalidate(void *opaque)
{
+ VIGSState *s = opaque;
+
+ s->invalidate_cnt = 1 + VIGS_EXTRA_INVALIDATION;
}
static void vigs_dpy_resize(void *user_data,
backend->read_pixels_make_current(backend, false);
}
- item->end_cb(item->user_data, (dst != NULL));
+ item->end_cb(item->user_data, (dst != NULL), true);
g_free(item);
}
}
static void vigs_server_update_display_end_cb(void *user_data,
- bool was_started)
+ bool was_started,
+ bool dirty)
{
struct vigs_server *server = user_data;
uint32_t capture_fence_seq;
qemu_mutex_lock(&server->capture_mutex);
}
+ if (dirty) {
+ server->captured.dirty = true;
+ }
+
server->is_capturing = false;
capture_fence_seq = server->capture_fence_seq;
server->capture_fence_seq = 0;
* If no root surface then this is a no-op.
* TODO: Can planes be enabled without a root surface ?
*/
- vigs_server_update_display_end_cb(server, false);
+ vigs_server_update_display_end_cb(server, false, false);
goto out;
}
root_sfc->ptr,
root_sfc->stride * root_sfc->ws_sfc->height);
- vigs_server_update_display_end_cb(server, true);
+ vigs_server_update_display_end_cb(server, true, true);
} else if (root_sfc->ptr || root_sfc->is_dirty || planes_dirty) {
/*
* Composite root surface and planes.
/*
* No changes, no-op.
*/
- vigs_server_update_display_end_cb(server, false);
+ vigs_server_update_display_end_cb(server, false, false);
}
out:
server);
}
-void vigs_server_update_display(struct vigs_server *server)
+bool vigs_server_update_display(struct vigs_server *server, int invalidate_cnt)
{
+ bool updated = false;
uint32_t sfc_bpp;
uint32_t display_stride, display_bpp;
uint8_t *display_data;
qemu_mutex_lock(&server->capture_mutex);
- if (!server->captured.data) {
+ if (!server->captured.data ||
+ (!server->captured.dirty && invalidate_cnt <= 0)) {
goto out;
}
+ server->captured.dirty = false;
+ updated = true;
+
sfc_bpp = vigs_format_bpp(server->captured.format);
server->display_ops->resize(server->display_user_data,
work_queue_add_item(server->render_queue, &item->base);
}
+
+ return updated;
}
uint32_t height;
uint32_t stride;
vigsp_surface_format format;
+ bool dirty;
} captured;
/*
void vigs_server_dispatch(struct vigs_server *server,
uint32_t ram_offset);
-void vigs_server_update_display(struct vigs_server *server);
+bool vigs_server_update_display(struct vigs_server *server, int invalidate_cnt);
#endif
surface->stride * surface->ws_sfc->height);
}
- end_cb(user_data, true);
+ end_cb(user_data, true, true);
}
static void vigs_sw_backend_batch_end(struct vigs_backend *backend)
#include "hw/i386/pc.h"
-#ifdef TARGET_ARM
#include "ui/console.h"
-#endif
#include "hw/pci/pci.h"
#include "maru_device_ids.h"
#include "maru_brightness.h"
}
level_color.alpha = value << 8;
brightness_image = pixman_image_create_solid_fill(&level_color);
+
+ graphic_hw_invalidate(NULL);
}
static void brightness_reg_write(void *opaque,
} else {
brightness_level = val;
maru_pixman_image_set_alpha(brightness_tbl[brightness_level]);
-#ifdef TARGET_ARM
- graphic_hw_invalidate(NULL);
-#endif
}
return;
case BRIGHTNESS_OFF:
maru_pixman_image_set_alpha(brightness_tbl[brightness_level]);
}
-#ifdef TARGET_ARM
- graphic_hw_invalidate(NULL);
-#endif
-
/* notify to skin process */
qemu_bh_schedule(bh);
#endif
}
+void maru_display_update(void)
+{
+#ifndef CONFIG_USE_SHM
+ maruskin_sdl_update();
+#else
+ /* do nothing */
+#endif
+}
+
+void maru_display_invalidate(bool on)
+{
+#ifndef CONFIG_USE_SHM
+ maruskin_sdl_invalidate(on);
+#else
+ /* do nothing */
+#endif
+}
+
void maru_display_interpolation(bool on)
{
#ifndef CONFIG_USE_SHM
void maru_display_init(DisplayState *ds);
void maru_display_fini(void);
+void maru_display_update(void);
+void maru_display_invalidate(bool on);
void maru_display_interpolation(bool on);
void maruskin_init(uint64 swt_handle,
unsigned int display_width, unsigned int display_height,
static QEMUBH *sdl_init_bh;
static QEMUBH *sdl_resize_bh;
+static QEMUBH *sdl_update_bh;
static DisplaySurface *dpy_surface;
static SDL_Surface *surface_screen;
static double current_screen_degree;
static pixman_filter_t sdl_pixman_filter;
+static bool sdl_invalidate;
static int sdl_alteration;
static unsigned int sdl_skip_update;
}
}
+ if (sdl_invalidate) {
+ graphic_hw_invalidate(NULL);
+ }
graphic_hw_update(NULL);
/* Usually, continuously updated.
}
#endif
+static void maru_sdl_update_bh(void *opaque)
+{
+ qemu_ds_sdl_update(NULL, 0, 0, 0, 0);
+}
+
static void maru_sdl_resize_bh(void *opaque)
{
int surface_width = 0, surface_height = 0;
return;
}
+ SDL_UpdateRect(surface_screen, 0, 0, 0, 0);
+
/* create buffer for image processing */
SDL_FreeSurface(scaled_screen);
scaled_screen = SDL_CreateRGBSurface(SDL_SWSURFACE,
#ifdef SDL_THREAD
pthread_mutex_unlock(&sdl_mutex);
#endif
+
+ graphic_hw_invalidate(NULL);
}
static void maru_sdl_init_bh(void *opaque)
sdl_init_bh = qemu_bh_new(maru_sdl_init_bh, NULL);
sdl_resize_bh = qemu_bh_new(maru_sdl_resize_bh, NULL);
+ sdl_update_bh = qemu_bh_new(maru_sdl_update_bh, NULL);
sprintf(SDL_windowhack, "%ld", window_id);
g_setenv("SDL_WINDOWID", SDL_windowhack, 1);
qemu_bh_schedule(sdl_resize_bh);
}
+
+void maruskin_sdl_update(void)
+{
+ qemu_bh_schedule(sdl_update_bh);
+}
+
+void maruskin_sdl_invalidate(bool on)
+{
+ sdl_invalidate = on;
+}
unsigned int display_width, unsigned int display_height,
bool blank_guide);
void maruskin_sdl_resize(void);
+void maruskin_sdl_update(void);
+void maruskin_sdl_invalidate(bool on);
void maruskin_sdl_interpolation(bool on);
void maruskin_sdl_quit(void);
if (finger.getMultiTouchEnable() == 1) {
finger.maruFingerProcessing1(eventType,
e.x, e.y, geometry[0], geometry[1]);
+
+ lcdCanvas.redraw();
return;
} else if (finger.getMultiTouchEnable() == 2) {
finger.maruFingerProcessing2(eventType,
e.x, e.y, geometry[0], geometry[1]);
+
+ lcdCanvas.redraw();
return;
}
logger.info("maruFingerProcessing 1");
finger.maruFingerProcessing1(MouseEventType.RELEASE.value(),
e.x, e.y, geometry[0], geometry[1]);
+
+ lcdCanvas.redraw();
return;
} else if (finger.getMultiTouchEnable() == 2) {
logger.info("maruFingerProcessing 2");
finger.maruFingerProcessing2(MouseEventType.RELEASE.value(),
e.x, e.y, geometry[0], geometry[1]);
+
+ lcdCanvas.redraw();
return;
}
logger.info("maruFingerProcessing 1");
finger.maruFingerProcessing1(MouseEventType.PRESS.value(),
e.x, e.y, geometry[0], geometry[1]);
+
+ lcdCanvas.redraw();
return;
} else if (finger.getMultiTouchEnable() == 2) {
logger.info("maruFingerProcessing 2");
finger.maruFingerProcessing2(MouseEventType.PRESS.value(),
e.x, e.y, geometry[0], geometry[1]);
+
+ lcdCanvas.redraw();
return;
}
logger.info("enable multi-touch = mode 1");
} else {
finger.clearFingerSlot(false);
+ updateDisplay();
logger.info("disable multi-touch");
}
public void grabShell(int x, int y) {
shellGrabPosition.x = x;
shellGrabPosition.y = y;
+
+ if (SwtUtil.isWindowsPlatform() == true) {
+ final BooleanData dataGrabbing = new BooleanData(
+ true, SendCommand.SEND_SKIN_GRABBED.toString());
+ communicator.sendToQEMU(SendCommand.SEND_SKIN_GRABBED, dataGrabbing, false);
+ }
}
public void ungrabShell() {
shellGrabPosition.x = -1;
shellGrabPosition.y = -1;
+
+ if (SwtUtil.isWindowsPlatform() == true) {
+ final BooleanData dataGrabbing = new BooleanData(
+ false, SendCommand.SEND_SKIN_GRABBED.toString());
+ communicator.sendToQEMU(SendCommand.SEND_SKIN_GRABBED, dataGrabbing, false);
+ }
}
public boolean isShellGrabbing() {
currentState.getCurrentScale(), rotationId);
communicator.sendToQEMU(SendCommand.SEND_DISPLAY_STATE,
stateData, false);
+
+ updateDisplay();
}
};
communicator.sendToQEMU(SendCommand.SEND_DISPLAY_STATE,
stateData, false);
+ updateDisplay();
}
};
/* This values must match the QEMU definitions */
SEND_SKIN_OPENED((short) 1),
+ SEND_SKIN_GRABBED((short) 2),
SEND_MOUSE_EVENT((short) 10),
SEND_KEYBOARD_KEY_EVENT((short) 11),
display_width, display_height, blank_guide);
}
+void do_grabbing_enable(bool on)
+{
+ INFO("skin grabbing enable : %d\n", on);
+
+ maru_display_invalidate(on);
+}
+
void do_mouse_event(int button_type, int event_type,
int origin_x, int origin_y, int x, int y, int z)
{
/* multi-touch */
if (get_emul_multi_touch_state()->multitouch_enable == 1) {
maru_finger_processing_1(event_type, origin_x, origin_y, x, y);
+
+ maru_display_update();
return;
} else if (get_emul_multi_touch_state()->multitouch_enable == 2) {
maru_finger_processing_2(event_type, origin_x, origin_y, x, y);
+
+ maru_display_update();
return;
}
#endif
ERR("undefined mouse event type passed : %d\n", event_type);
break;
}
-
-#if 0
-#ifdef CONFIG_WIN32
- Sleep(1);
-#else
- usleep(1000);
-#endif
-#endif
}
void do_keyboard_key_event(int event_type,
clear_finger_slot(false);
INFO("disable multi-touch\n");
}
+
+ maru_display_update();
}
}
INFO("do_scale_event scale_factor : %lf\n", scale_factor);
set_emul_win_scale(scale_factor);
-
-#if 0
- //TODO: thread safe
- //qemu refresh
- vga_hw_invalidate();
- vga_hw_update();
-#endif
}
void do_rotation_event(int rotation_type)
unsigned int display_width, unsigned int display_height,
double scale_factor, short rotation_type, bool blank_guide);
+void do_grabbing_enable(bool on);
void do_mouse_event(int button_type, int event_type,
int origin_x, int origin_y, int x, int y, int z);
void do_keyboard_key_event(int event_type,
in Skin process */
RECV_SKIN_OPENED = 1,
+ RECV_SKIN_GRABBED = 2,
RECV_MOUSE_EVENT = 10,
RECV_KEYBOARD_KEY_EVENT = 11,
break;
}
+ case RECV_SKIN_GRABBED: {
+ char on = 0;
+
+ log_cnt += sprintf(log_buf + log_cnt, "RECV_SKIN_GRABBED ==\n");
+ TRACE(log_buf);
+
+ if (length <= 0) {
+ INFO("there is no data looking at 0 length.\n");
+ continue;
+ }
+
+ memcpy(&on, recvbuf, sizeof(on));
+
+ if (on == 0) {
+ do_grabbing_enable(false);
+ } else {
+ do_grabbing_enable(true);
+ }
+
+ break;
+ }
case RECV_MOUSE_EVENT: {
log_cnt += sprintf( log_buf + log_cnt, "RECV_MOUSE_EVENT ==\n" );
TRACE( log_buf );