From 8ef6568ea78d78b19b07a5e411ee946eb22ab279 Mon Sep 17 00:00:00 2001 From: Rafael Antognolli Date: Fri, 1 Mar 2013 14:19:10 -0300 Subject: [PATCH] ecore/evas wayland_shm: Add support for window rotation. --- .../wayland/ecore_evas_wayland_common.c | 12 +- .../engines/wayland/ecore_evas_wayland_shm.c | 129 +++++++++++++++++- .../evas/engines/wayland_shm/evas_swapbuf.c | 52 ++++++- .../evas/engines/wayland_shm/evas_swapper.c | 4 +- .../evas/engines/wayland_shm/evas_swapper.h | 2 +- 5 files changed, 184 insertions(+), 15 deletions(-) diff --git a/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_common.c b/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_common.c index 593e82cda9..146d607263 100644 --- a/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_common.c +++ b/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_common.c @@ -196,8 +196,16 @@ _ecore_evas_wl_common_cb_window_configure(void *data EINA_UNUSED, int type EINA_ int fw = 0, fh = 0; evas_output_framespace_get(ee->evas, NULL, NULL, &fw, &fh); - nw = ev->w - fw; - nh = ev->h - fh; + if ((ee->rotation == 90) || (ee->rotation == 270)) + { + nw = ev->w - fh; + nh = ev->h - fw; + } + else + { + nw = ev->w - fw; + nh = ev->h - fh; + } } if (ee->prop.min.w > nw) nw = ee->prop.min.w; diff --git a/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_shm.c b/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_shm.c index 384c710712..01b50fa649 100644 --- a/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_shm.c +++ b/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_shm.c @@ -16,6 +16,7 @@ static void _ecore_evas_wl_show(Ecore_Evas *ee); static void _ecore_evas_wl_hide(Ecore_Evas *ee); static void _ecore_evas_wl_alpha_set(Ecore_Evas *ee, int alpha); static void _ecore_evas_wl_transparent_set(Ecore_Evas *ee, int transparent); +static void _ecore_evas_wl_rotation_set(Ecore_Evas *ee, int rotation, int resize); static Ecore_Evas_Engine_Func _ecore_wl_engine_func = { @@ -38,7 +39,7 @@ static Ecore_Evas_Engine_Func _ecore_wl_engine_func = NULL, // managed_move _ecore_evas_wl_resize, _ecore_evas_wl_move_resize, - NULL, // rotation_set + _ecore_evas_wl_rotation_set, NULL, // shaped_set _ecore_evas_wl_show, _ecore_evas_wl_hide, @@ -277,8 +278,16 @@ _ecore_evas_wl_resize(Ecore_Evas *ee, int w, int h) orig_h = h; evas_output_framespace_get(ee->evas, NULL, NULL, &fw, &fh); - w += fw; - h += fh; + if ((ee->rotation == 90) || (ee->rotation == 270)) + { + w += fh; + h += fw; + } + else + { + w += fw; + h += fh; + } } if ((ee->w != w) || (ee->h != h)) @@ -341,6 +350,114 @@ _ecore_evas_wl_move_resize(Ecore_Evas *ee, int x, int y, int w, int h) _ecore_evas_wl_resize(ee, w, h); } +static void +_ecore_evas_wl_rotation_set(Ecore_Evas *ee, int rotation, int resize) +{ + Evas_Engine_Info_Wayland_Shm *einfo; + Ecore_Evas_Engine_Wl_Data *wdata; + int rot_dif; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (ee->rotation == rotation) return; + + einfo = (Evas_Engine_Info_Wayland_Shm *)evas_engine_info_get(ee->evas); + if (!einfo) + return; + einfo->info.rotation = rotation; + + wdata = ee->engine.data; + + rot_dif = ee->rotation - rotation; + if (rot_dif < 0) rot_dif = -rot_dif; + + if (rot_dif != 180) + { + int minw, minh, maxw, maxh, basew, baseh, stepw, steph; + int ww, hh; + + if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo)) + { + ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver); + } + + if (!resize) + { + // wdata->configure_coming = 1; + if (!ee->prop.fullscreen) + { + int fw, fh; + evas_output_framespace_get(ee->evas, NULL, NULL, &fw, &fh); + ecore_wl_window_resize(wdata->win, ee->h + fh, ee->w + fw, 0); + ecore_wl_window_update_size(wdata->win, ee->h + fh, ee->w + fw); + evas_output_size_set(ee->evas, ee->req.w + fw, ee->req.h + fh); + evas_output_viewport_set(ee->evas, 0, 0, ee->req.w + fw, ee->req.h + fh); + } + else + { + evas_output_size_set(ee->evas, ee->req.w, ee->req.h); + evas_output_viewport_set(ee->evas, 0, 0, ee->req.w, ee->req.h); + if (ee->func.fn_resize) ee->func.fn_resize(ee); + } + if ((ee->rotation == 90) || (ee->rotation == 270)) + evas_damage_rectangle_add(ee->evas, 0, 0, ee->req.h, ee->req.w); + else + evas_damage_rectangle_add(ee->evas, 0, 0, ee->req.w, ee->req.h); + ww = ee->h; + hh = ee->w; + ee->w = ww; + ee->h = hh; + ee->req.w = ww; + ee->req.h = hh; + } + else + { + if ((rotation == 0) || (rotation == 180)) + { + evas_output_size_set(ee->evas, ee->w, ee->h); + evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h); + } + else + { + evas_output_size_set(ee->evas, ee->h, ee->w); + evas_output_viewport_set(ee->evas, 0, 0, ee->h, ee->w); + } + if (ee->func.fn_resize) ee->func.fn_resize(ee); + if ((ee->rotation == 90) || (ee->rotation == 270)) + evas_damage_rectangle_add(ee->evas, 0, 0, ee->h, ee->w); + else + evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h); + } + ecore_evas_size_min_get(ee, &minw, &minh); + ecore_evas_size_max_get(ee, &maxw, &maxh); + ecore_evas_size_base_get(ee, &basew, &baseh); + ecore_evas_size_step_get(ee, &stepw, &steph); + ee->rotation = rotation; + ecore_evas_size_min_set(ee, minh, minw); + ecore_evas_size_max_set(ee, maxh, maxw); + ecore_evas_size_base_set(ee, baseh, basew); + ecore_evas_size_step_set(ee, steph, stepw); + _ecore_evas_mouse_move_process(ee, ee->mouse.x, ee->mouse.y, + ecore_loop_time_get()); + } + else + { + if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo)) + { + ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver); + } + ee->rotation = rotation; + // _ecore_evas_mouse_move_process(ee, ee->mouse.x, ee->mouse.y, + // ecore_x_current_time_get()); + if (ee->func.fn_resize) ee->func.fn_resize(ee); + + if ((ee->rotation == 90) || (ee->rotation == 270)) + evas_damage_rectangle_add(ee->evas, 0, 0, ee->h, ee->w); + else + evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h); + } +} + static void _ecore_evas_wl_show(Ecore_Evas *ee) { @@ -501,7 +618,11 @@ _ecore_evas_wayland_shm_resize(Ecore_Evas *ee, int location) einfo->info.edges = wdata->win->edges; evas_output_framespace_get(ee->evas, NULL, NULL, &fw, &fh); - ecore_wl_window_resize(wdata->win, ee->w + fw, ee->h + fh, location); + if ((ee->rotation == 90) || (ee->rotation == 270)) + ecore_wl_window_resize(wdata->win, ee->w + fh, ee->h + fw, location); + else + ecore_wl_window_resize(wdata->win, ee->w + fw, ee->h + fh, location); + } } #endif diff --git a/src/modules/evas/engines/wayland_shm/evas_swapbuf.c b/src/modules/evas/engines/wayland_shm/evas_swapbuf.c index 443b45f284..7542cfb854 100644 --- a/src/modules/evas/engines/wayland_shm/evas_swapbuf.c +++ b/src/modules/evas/engines/wayland_shm/evas_swapbuf.c @@ -16,7 +16,7 @@ #define RED_MASK 0x00ff0000 #define GREEN_MASK 0x0000ff00 -#define BLUE_MASK 0xff000000 +#define BLUE_MASK 0x000000ff /* local function prototypes */ @@ -153,7 +153,7 @@ evas_swapbuf_update_region_new(Outbuf *ob, int x, int y, int w, int h, int *cx, { void *data; - data = evas_swapper_buffer_map(ob->priv.swapper); + data = evas_swapper_buffer_map(ob->priv.swapper, NULL, NULL); #ifdef EVAS_CSERVE2 if (evas_cserve2_use_get()) @@ -242,10 +242,12 @@ void evas_swapbuf_update_region_push(Outbuf *ob, RGBA_Image *update, int x, int y, int w, int h) { Gfx_Func_Convert func = NULL; - Eina_Rectangle rect = {0, 0, 0, 0}; + Eina_Rectangle rect = {0, 0, 0, 0}, pr; DATA32 *src; DATA8 *dst; int depth = 32, bpp = 0, bpl = 0, wid = 0; + int ww = 0, hh = 0; + int rx = 0, ry = 0; LOGFN(__FILE__, __LINE__, __FUNCTION__); @@ -310,18 +312,54 @@ evas_swapbuf_update_region_push(Outbuf *ob, RGBA_Image *update, int x, int y, in /* check for valid update image data */ if (!(src = update->image.data)) return; - /* check for valid desination data */ - if (!(dst = evas_swapper_buffer_map(ob->priv.swapper))) return; bpp = depth / 8; if (bpp <= 0) return; - bpl = (ob->w * sizeof(int)); + /* check for valid desination data */ + if (!(dst = evas_swapper_buffer_map(ob->priv.swapper, &ww, &hh))) return; + + bpl = (ww * sizeof(int)); + + if (ob->rotation == 0) + { + RECTS_CLIP_TO_RECT(rect.x, rect.y, rect.w, rect.h, 0, 0, ww, hh); + dst += (bpl * rect.y) + (rect.x + bpp); + w -= rx; + } + else if (ob->rotation == 180) + { + pr = rect; + RECTS_CLIP_TO_RECT(rect.x, rect.y, rect.w, rect.h, 0, 0, ww, hh); + rx = pr.w - rect.w; + ry = pr.h - rect.h; + src += (update->cache_entry.w * ry) + rx; + w -= rx; + } + else if (ob->rotation == 90) + { + pr = rect; + RECTS_CLIP_TO_RECT(rect.x, rect.y, rect.w, rect.h, 0, 0, ww, hh); + rx = pr.w - rect.w; ry = pr.h - rect.h; + src += ry; + w -= ry; + } + else if (ob->rotation == 270) + { + pr = rect; + RECTS_CLIP_TO_RECT(rect.x, rect.y, rect.w, rect.h, 0, 0, ww, hh); + rx = pr.w - rect.w; ry = pr.h - rect.h; + src += (update->cache_entry.w * rx); + w -= ry; + } + + if ((rect.w <= 0) || (rect.h <= 0)) return; + wid = bpl / bpp; dst += (bpl * rect.y) + (rect.x * bpp); - func(src, dst, (update->cache_entry.w - w), (wid - rect.w), + func(src, dst, (update->cache_entry.w - w), (wid - rect.w), rect.w, rect.h, x, y, NULL); } diff --git a/src/modules/evas/engines/wayland_shm/evas_swapper.c b/src/modules/evas/engines/wayland_shm/evas_swapper.c index 49d7ccef1c..482183fa5b 100644 --- a/src/modules/evas/engines/wayland_shm/evas_swapper.c +++ b/src/modules/evas/engines/wayland_shm/evas_swapper.c @@ -204,7 +204,7 @@ evas_swapper_free(Wl_Swapper *ws) } void * -evas_swapper_buffer_map(Wl_Swapper *ws) +evas_swapper_buffer_map(Wl_Swapper *ws, int *w, int *h) { LOGFN(__FILE__, __LINE__, __FUNCTION__); @@ -213,6 +213,8 @@ evas_swapper_buffer_map(Wl_Swapper *ws) /* set mapped property */ ws->mapped = EINA_TRUE; + if (w) *w = ws->w; + if (h) *h = ws->h; /* return wl_buffer data */ return ws->buff[ws->buff_cur].data; diff --git a/src/modules/evas/engines/wayland_shm/evas_swapper.h b/src/modules/evas/engines/wayland_shm/evas_swapper.h index 8c21cc82c9..f9fc90a988 100644 --- a/src/modules/evas/engines/wayland_shm/evas_swapper.h +++ b/src/modules/evas/engines/wayland_shm/evas_swapper.h @@ -9,7 +9,7 @@ Wl_Swapper *evas_swapper_setup(int dx, int dy, int w, int h, Outbuf_Depth depth, Wl_Swapper *evas_swapper_reconfigure(Wl_Swapper *ws, int dx, int dy, int w, int h, Outbuf_Depth depth, Eina_Bool alpha); void evas_swapper_swap(Wl_Swapper *ws, Eina_Rectangle *rects, unsigned int count); void evas_swapper_free(Wl_Swapper *ws); -void *evas_swapper_buffer_map(Wl_Swapper *ws); +void *evas_swapper_buffer_map(Wl_Swapper *ws, int *w, int *h); void evas_swapper_buffer_unmap(Wl_Swapper *ws); int evas_swapper_buffer_state_get(Wl_Swapper *ws); void evas_swapper_buffer_idle_flush(Wl_Swapper *ws);