2018-09-29 09:06:41 -07:00
|
|
|
#include "private.h"
|
|
|
|
|
2014-03-18 14:53:02 -07:00
|
|
|
#include <Elementary.h>
|
|
|
|
#include <stdio.h>
|
2014-04-20 09:45:21 -07:00
|
|
|
#include <assert.h>
|
2014-07-15 03:20:19 -07:00
|
|
|
#include <math.h>
|
2014-04-20 09:45:21 -07:00
|
|
|
|
2014-03-18 14:53:02 -07:00
|
|
|
#include "col.h"
|
|
|
|
#include "termpty.h"
|
|
|
|
#include "termio.h"
|
2019-02-04 12:24:00 -08:00
|
|
|
#include "termiointernals.h"
|
|
|
|
#include "miniview.h"
|
2014-05-12 11:25:36 -07:00
|
|
|
#include "utils.h"
|
2014-03-26 12:37:35 -07:00
|
|
|
#include "main.h"
|
2019-11-23 14:31:21 -08:00
|
|
|
#include "backlog.h"
|
2014-03-26 12:37:35 -07:00
|
|
|
|
|
|
|
/* specific log domain to help debug only miniview */
|
|
|
|
int _miniview_log_dom = -1;
|
|
|
|
|
|
|
|
#undef CRITICAL
|
|
|
|
#undef ERR
|
|
|
|
#undef WRN
|
|
|
|
#undef INF
|
|
|
|
#undef DBG
|
|
|
|
|
|
|
|
#define CRIT(...) EINA_LOG_DOM_CRIT(_miniview_log_dom, __VA_ARGS__)
|
|
|
|
#define ERR(...) EINA_LOG_DOM_ERR(_miniview_log_dom, __VA_ARGS__)
|
|
|
|
#define WRN(...) EINA_LOG_DOM_WARN(_miniview_log_dom, __VA_ARGS__)
|
|
|
|
#define INF(...) EINA_LOG_DOM_INFO(_miniview_log_dom, __VA_ARGS__)
|
|
|
|
#define DBG(...) EINA_LOG_DOM_DBG(_miniview_log_dom, __VA_ARGS__)
|
|
|
|
|
2014-07-02 16:54:10 -07:00
|
|
|
static Eina_Bool _deferred_renderer(void *data);
|
|
|
|
|
2014-03-26 12:37:35 -07:00
|
|
|
void
|
|
|
|
miniview_init(void)
|
|
|
|
{
|
|
|
|
if (_miniview_log_dom >= 0) return;
|
|
|
|
|
|
|
|
_miniview_log_dom = eina_log_domain_register("miniview", NULL);
|
|
|
|
if (_miniview_log_dom < 0)
|
2014-07-20 13:35:28 -07:00
|
|
|
EINA_LOG_CRIT(_("Could not create logging domain '%s'."), "miniview");
|
2014-03-26 12:37:35 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
miniview_shutdown(void)
|
|
|
|
{
|
|
|
|
if (_miniview_log_dom < 0) return;
|
|
|
|
eina_log_domain_unregister(_miniview_log_dom);
|
|
|
|
_miniview_log_dom = -1;
|
|
|
|
}
|
2014-03-18 14:53:02 -07:00
|
|
|
|
|
|
|
typedef struct _Miniview Miniview;
|
|
|
|
|
|
|
|
struct _Miniview
|
|
|
|
{
|
2014-03-30 11:38:49 -07:00
|
|
|
Evas_Object *self;
|
2014-05-12 11:25:36 -07:00
|
|
|
Evas_Object *base;
|
2014-04-27 12:34:27 -07:00
|
|
|
Evas_Object *img;
|
2014-03-18 14:53:02 -07:00
|
|
|
Evas_Object *termio;
|
2014-04-26 14:42:17 -07:00
|
|
|
|
2014-05-03 13:16:27 -07:00
|
|
|
int img_hist; /* history rendered is between img_hist (<0) and
|
|
|
|
img_hist + img_h */
|
|
|
|
unsigned img_h;
|
|
|
|
unsigned rows;
|
|
|
|
unsigned cols;
|
2014-05-01 15:08:58 -07:00
|
|
|
|
2014-05-04 08:03:05 -07:00
|
|
|
Ecore_Timer *deferred_renderer;
|
|
|
|
|
2014-05-04 11:18:23 -07:00
|
|
|
unsigned int is_shown : 1;
|
|
|
|
unsigned int to_render : 1;
|
2014-07-20 12:33:38 -07:00
|
|
|
unsigned int initial_pos : 1;
|
2014-07-15 03:20:19 -07:00
|
|
|
|
|
|
|
Eina_Bool fits_to_img;
|
|
|
|
|
|
|
|
struct _screen {
|
|
|
|
double size;
|
|
|
|
double pos_val;
|
|
|
|
}screen;
|
2014-03-18 14:53:02 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
static Evas_Smart *_smart = NULL;
|
|
|
|
|
2014-05-08 13:23:30 -07:00
|
|
|
static void
|
2014-05-16 01:44:11 -07:00
|
|
|
_draw_cell(const Termpty *ty, unsigned int *pixel, const Termcell *cell, unsigned int *colors)
|
2014-05-08 13:23:30 -07:00
|
|
|
{
|
|
|
|
int fg, bg, fgext, bgext;
|
2015-04-19 10:59:29 -07:00
|
|
|
int inv = ty->termstate.reverse;
|
2014-05-16 01:57:12 -07:00
|
|
|
Eina_Unicode codepoint;
|
2014-04-27 14:48:54 -07:00
|
|
|
|
2014-05-16 01:57:12 -07:00
|
|
|
codepoint = cell->codepoint;
|
|
|
|
if ((codepoint == 0) || (cell->att.newline) || (cell->att.invisible))
|
2014-05-08 13:23:30 -07:00
|
|
|
{
|
|
|
|
*pixel = 0;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
// colors
|
|
|
|
fg = cell->att.fg;
|
|
|
|
bg = cell->att.bg;
|
|
|
|
fgext = cell->att.fg256;
|
|
|
|
bgext = cell->att.bg256;
|
|
|
|
|
2014-05-15 23:46:04 -07:00
|
|
|
if ((fg == COL_DEF) && (cell->att.inverse ^ inv)) fg = COL_INVERSEBG;
|
2014-05-08 13:23:30 -07:00
|
|
|
if (bg == COL_DEF)
|
|
|
|
{
|
2014-05-15 23:46:04 -07:00
|
|
|
if (cell->att.inverse ^ inv) bg = COL_INVERSE;
|
|
|
|
else if (!bgext) bg = COL_INVIS;
|
2014-05-08 13:23:30 -07:00
|
|
|
}
|
2014-05-15 23:46:04 -07:00
|
|
|
if ((cell->att.fgintense) && (!fgext)) fg += 48;
|
|
|
|
if ((cell->att.bgintense) && (!bgext)) bg += 48;
|
2014-05-16 01:44:11 -07:00
|
|
|
if (cell->att.inverse ^ inv)
|
|
|
|
{
|
|
|
|
int t;
|
|
|
|
t = fgext; fgext = bgext; bgext = t;
|
|
|
|
t = fg; fg = bg; bg = t;
|
|
|
|
}
|
2014-05-15 23:46:04 -07:00
|
|
|
if ((cell->att.bold) && (!fgext)) fg += 12;
|
|
|
|
if ((cell->att.faint) && (!fgext)) fg += 24;
|
|
|
|
|
2014-05-16 01:44:11 -07:00
|
|
|
if (bgext) *pixel = colors[bg + 256];
|
|
|
|
else if (bg && ((bg % 12) != COL_INVIS)) *pixel = colors[bg];
|
2014-10-28 12:52:35 -07:00
|
|
|
else if ((codepoint > 32) && (codepoint < 0x00110000))
|
2014-05-08 13:23:30 -07:00
|
|
|
{
|
2014-05-16 01:44:11 -07:00
|
|
|
if (fgext) *pixel = colors[fg + 256];
|
|
|
|
else *pixel = colors[fg];
|
2014-05-08 13:23:30 -07:00
|
|
|
}
|
|
|
|
else
|
2014-05-16 01:44:11 -07:00
|
|
|
*pixel = 0;
|
2014-05-08 13:23:30 -07:00
|
|
|
}
|
2014-04-27 14:48:54 -07:00
|
|
|
|
|
|
|
static void
|
2014-05-08 13:23:30 -07:00
|
|
|
_draw_line(const Termpty *ty, unsigned int *pixels,
|
2014-05-16 01:44:11 -07:00
|
|
|
const Termcell *cells, int length, unsigned int *colors)
|
2014-04-27 14:48:54 -07:00
|
|
|
{
|
|
|
|
int x;
|
|
|
|
|
|
|
|
for (x = 0 ; x < length; x++)
|
|
|
|
{
|
2014-05-16 01:44:11 -07:00
|
|
|
_draw_cell(ty, pixels + x, cells + x, colors);
|
2014-04-27 14:48:54 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-07-15 03:20:19 -07:00
|
|
|
Eina_Bool
|
|
|
|
_is_top_bottom_reached(Miniview *mv)
|
|
|
|
{
|
|
|
|
int history_len;
|
2015-06-28 14:37:04 -07:00
|
|
|
Termpty *ty;
|
2014-07-15 03:20:19 -07:00
|
|
|
|
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(mv, EINA_FALSE);
|
2015-04-06 09:08:23 -07:00
|
|
|
|
2015-06-28 14:37:04 -07:00
|
|
|
ty = termio_pty_get(mv->termio);
|
2016-06-04 06:43:23 -07:00
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(ty, EINA_FALSE);
|
2015-08-01 09:37:35 -07:00
|
|
|
history_len = termpty_backlog_length(ty);
|
2014-07-15 03:20:19 -07:00
|
|
|
|
|
|
|
if (( (- mv->img_hist) > (int)(mv->img_h - mv->rows - (mv->rows / 2))) &&
|
|
|
|
( (- mv->img_hist) < (int)(history_len + (mv->rows / 2))))
|
|
|
|
return EINA_FALSE;
|
|
|
|
|
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_screen_visual_bounds(Miniview *mv)
|
|
|
|
{
|
|
|
|
if ((mv->screen.pos_val > 1) || (mv->screen.pos_val < 0))
|
|
|
|
{
|
|
|
|
edje_object_part_drag_value_set(mv->base, "miniview_screen",
|
|
|
|
0.0, mv->screen.pos_val);
|
|
|
|
edje_object_signal_emit(mv->base, "miniview_screen,outbounds",
|
|
|
|
"miniview");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
edje_object_part_drag_value_set(mv->base, "miniview_screen",
|
|
|
|
0.0, mv->screen.pos_val);
|
|
|
|
edje_object_signal_emit(mv->base, "miniview_screen,inbounds",
|
|
|
|
"miniview");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-07-02 16:54:10 -07:00
|
|
|
static void
|
|
|
|
_queue_render(Miniview *mv)
|
|
|
|
{
|
|
|
|
mv->to_render = 1;
|
|
|
|
if ((!mv->deferred_renderer) && (mv->is_shown))
|
|
|
|
mv->deferred_renderer = ecore_timer_add(0.1, _deferred_renderer, mv);
|
|
|
|
}
|
|
|
|
|
2014-04-26 14:42:17 -07:00
|
|
|
static void
|
2016-10-05 13:00:22 -07:00
|
|
|
_smart_cb_mouse_wheel(void *data,
|
|
|
|
Evas *_e EINA_UNUSED,
|
|
|
|
Evas_Object *_obj EINA_UNUSED,
|
|
|
|
void *event)
|
2014-04-26 14:42:17 -07:00
|
|
|
{
|
|
|
|
Evas_Event_Mouse_Wheel *ev = event;
|
|
|
|
Miniview *mv = evas_object_smart_data_get(data);
|
|
|
|
|
|
|
|
EINA_SAFETY_ON_NULL_RETURN(mv);
|
|
|
|
|
|
|
|
/* do not handle horizontal scrolling */
|
|
|
|
if (ev->direction) return;
|
2014-05-13 14:04:44 -07:00
|
|
|
mv->img_hist += ev->z * 25;
|
2014-07-15 03:20:19 -07:00
|
|
|
|
|
|
|
if (!mv->fits_to_img && !_is_top_bottom_reached(mv))
|
|
|
|
{
|
|
|
|
mv->screen.pos_val = mv->screen.pos_val -
|
|
|
|
(double) (ev->z * 25) / (mv->img_h - mv->rows);
|
|
|
|
_screen_visual_bounds(mv);
|
|
|
|
}
|
2014-07-02 16:54:10 -07:00
|
|
|
_queue_render(mv);
|
2014-04-27 14:48:54 -07:00
|
|
|
}
|
|
|
|
|
2014-07-15 03:20:19 -07:00
|
|
|
void
|
2017-07-06 11:55:02 -07:00
|
|
|
miniview_position_offset(const Evas_Object *obj, int by, Eina_Bool sanitize)
|
2014-07-15 03:20:19 -07:00
|
|
|
{
|
|
|
|
Miniview *mv = evas_object_smart_data_get(obj);
|
|
|
|
|
|
|
|
termio_scroll_get(mv->termio);
|
|
|
|
EINA_SAFETY_ON_NULL_RETURN(mv);
|
|
|
|
if ((mv->screen.pos_val <= 1.0) && (mv->screen.pos_val >= 0.0))
|
|
|
|
edje_object_signal_emit(mv->base, "miniview_screen,inbounds", "miniview");
|
|
|
|
|
|
|
|
if (!mv->fits_to_img)
|
|
|
|
{
|
2020-04-17 14:09:07 -07:00
|
|
|
int remain;
|
|
|
|
|
2014-09-23 13:10:12 -07:00
|
|
|
mv->screen.pos_val += (double) by / (mv->img_h - mv->rows);
|
2014-07-15 03:20:19 -07:00
|
|
|
edje_object_part_drag_value_set(mv->base, "miniview_screen",
|
|
|
|
0.0, mv->screen.pos_val);
|
|
|
|
if ((mv->screen.pos_val <= 0) && (sanitize))
|
|
|
|
{
|
|
|
|
/* This is what remains when screen pos has to
|
|
|
|
go negative by some portion "by" */
|
|
|
|
remain = (int) round(mv->screen.pos_val * (mv->img_h - mv->rows));
|
|
|
|
mv->img_hist += remain;
|
|
|
|
mv->screen.pos_val = 0;
|
|
|
|
}
|
|
|
|
if ((mv->screen.pos_val > 1) && (sanitize))
|
|
|
|
{
|
|
|
|
remain = (int) round((1 - mv->screen.pos_val) *
|
|
|
|
(mv->img_h - mv->rows));
|
|
|
|
mv->img_hist -= remain;
|
|
|
|
mv->screen.pos_val = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2014-08-16 09:45:14 -07:00
|
|
|
if (sanitize)
|
|
|
|
{
|
2014-09-23 13:10:12 -07:00
|
|
|
mv->screen.pos_val += (double) by / (mv->img_h - mv->rows);
|
2014-08-16 09:45:14 -07:00
|
|
|
edje_object_part_drag_value_set(mv->base, "miniview_screen",
|
|
|
|
0.0, mv->screen.pos_val);
|
|
|
|
|
|
|
|
if (mv->screen.pos_val < 0) mv->screen.pos_val = 0;
|
|
|
|
if (mv->screen.pos_val > 1) mv->screen.pos_val = 1;
|
|
|
|
}
|
2014-07-15 03:20:19 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-05-13 14:09:29 -07:00
|
|
|
Eina_Bool
|
2014-08-19 14:09:50 -07:00
|
|
|
miniview_handle_key(Evas_Object *obj, const Evas_Event_Key_Down *ev)
|
2014-05-13 14:09:29 -07:00
|
|
|
{
|
|
|
|
Miniview *mv;
|
|
|
|
Evas_Coord ox, oy, ow, oh, mx, my;
|
|
|
|
int z = 25;
|
|
|
|
|
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
|
|
|
|
|
|
|
|
mv = evas_object_smart_data_get(obj);
|
2014-05-15 23:46:04 -07:00
|
|
|
if ((!mv) || (!mv->is_shown)) return EINA_FALSE;
|
2014-05-13 14:09:29 -07:00
|
|
|
|
|
|
|
evas_object_geometry_get(mv->img, &ox, &oy, &ow, &oh);
|
|
|
|
evas_pointer_canvas_xy_get(evas_object_evas_get(mv->base), &mx, &my);
|
|
|
|
|
2014-05-15 23:46:04 -07:00
|
|
|
if ((mx < ox) || (mx > ox + ow) || (my < oy) || (my > oy + oh))
|
2014-05-13 14:09:29 -07:00
|
|
|
return EINA_FALSE;
|
|
|
|
|
|
|
|
if (evas_key_modifier_is_set(ev->modifiers, "Alt") ||
|
|
|
|
evas_key_modifier_is_set(ev->modifiers, "Shift") ||
|
|
|
|
evas_key_modifier_is_set(ev->modifiers, "Control"))
|
|
|
|
z = mv->img_h;
|
|
|
|
|
|
|
|
if (!strcmp(ev->key, "Prior"))
|
|
|
|
{
|
2014-07-15 03:20:19 -07:00
|
|
|
if (!mv->fits_to_img)
|
|
|
|
{
|
|
|
|
mv->img_hist -= z;
|
|
|
|
if (_is_top_bottom_reached(mv))
|
|
|
|
{
|
|
|
|
miniview_position_offset(obj, -z, EINA_FALSE);
|
|
|
|
}
|
|
|
|
miniview_position_offset(obj, z, EINA_FALSE);
|
|
|
|
_screen_visual_bounds(mv);
|
|
|
|
}
|
2014-07-02 16:54:10 -07:00
|
|
|
_queue_render(mv);
|
2014-05-13 14:09:29 -07:00
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
|
|
|
else if (!strcmp(ev->key, "Next"))
|
|
|
|
{
|
2014-07-15 03:20:19 -07:00
|
|
|
if (!mv->fits_to_img)
|
|
|
|
{
|
|
|
|
mv->img_hist += z;
|
|
|
|
if (_is_top_bottom_reached(mv))
|
|
|
|
{
|
|
|
|
miniview_position_offset(obj, z, EINA_FALSE);
|
|
|
|
}
|
|
|
|
miniview_position_offset(obj, -z, EINA_FALSE);
|
|
|
|
_screen_visual_bounds(mv);
|
|
|
|
}
|
2014-07-02 16:54:10 -07:00
|
|
|
_queue_render(mv);
|
2014-05-13 14:09:29 -07:00
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
|
|
|
|
2014-05-04 08:15:39 -07:00
|
|
|
static void
|
2016-10-05 13:00:22 -07:00
|
|
|
_smart_cb_mouse_down(void *data,
|
|
|
|
Evas *_e EINA_UNUSED,
|
|
|
|
Evas_Object *_obj EINA_UNUSED,
|
|
|
|
void *event)
|
2014-05-04 08:15:39 -07:00
|
|
|
{
|
|
|
|
Evas_Event_Mouse_Down *ev = event;
|
|
|
|
Miniview *mv= evas_object_smart_data_get(data);
|
2014-07-15 03:20:19 -07:00
|
|
|
int pos, pos2;
|
2014-05-04 08:15:39 -07:00
|
|
|
Evas_Coord oy;
|
|
|
|
|
|
|
|
EINA_SAFETY_ON_NULL_RETURN(mv);
|
|
|
|
|
|
|
|
evas_object_geometry_get(mv->img, NULL, &oy, NULL, NULL);
|
|
|
|
pos = oy - ev->canvas.y;
|
|
|
|
pos -= mv->img_hist;
|
2014-05-15 23:46:04 -07:00
|
|
|
if (pos < 0) pos = 0;
|
|
|
|
else pos += mv->rows / 2;
|
2014-05-04 08:15:39 -07:00
|
|
|
termio_scroll_set(mv->termio, pos);
|
2014-07-15 03:20:19 -07:00
|
|
|
|
|
|
|
pos2 = ev->canvas.y - oy - (mv->rows / 2);
|
|
|
|
if (pos2 < 0) pos2 = 0;
|
|
|
|
if (pos2 > -mv->img_hist) pos2 = -mv->img_hist;
|
|
|
|
mv->screen.pos_val = (double) pos2 / (mv->img_h - mv->rows);
|
|
|
|
edje_object_part_drag_value_set(mv->base, "miniview_screen", 0.0, mv->screen.pos_val);
|
2014-07-20 12:33:38 -07:00
|
|
|
_screen_visual_bounds(mv);
|
2014-07-15 03:20:19 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2016-10-05 13:00:22 -07:00
|
|
|
_on_screen_stoped(void *data,
|
|
|
|
Evas_Object *_o EINA_UNUSED,
|
|
|
|
const char *_emission EINA_UNUSED,
|
|
|
|
const char *_source EINA_UNUSED)
|
2014-07-15 03:20:19 -07:00
|
|
|
{
|
|
|
|
Miniview *mv= evas_object_smart_data_get(data);
|
|
|
|
|
|
|
|
EINA_SAFETY_ON_NULL_RETURN(mv);
|
|
|
|
|
|
|
|
edje_object_part_drag_value_set(mv->base, "miniview_screen", 0.0,
|
|
|
|
mv->screen.pos_val);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2016-10-05 13:00:22 -07:00
|
|
|
_on_screen_moved(void *data,
|
|
|
|
Evas_Object *o,
|
|
|
|
const char *_emission EINA_UNUSED,
|
|
|
|
const char *_source EINA_UNUSED)
|
2014-07-15 03:20:19 -07:00
|
|
|
{
|
|
|
|
Miniview *mv = evas_object_smart_data_get(data);
|
|
|
|
double val = 0.0, pos = 0.0, bottom_bound = 0.0;
|
|
|
|
|
|
|
|
edje_object_part_drag_value_get(o, "miniview_screen", NULL, &val);
|
|
|
|
bottom_bound = ((double) (-mv->img_hist )) / (mv->img_h - mv->rows);
|
|
|
|
if (!mv->fits_to_img)
|
|
|
|
{
|
|
|
|
pos = (bottom_bound - val) * (mv->img_h - mv->rows);
|
|
|
|
mv->screen.pos_val = val;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
bottom_bound = ((double) (-mv->img_hist )) / (mv->img_h - mv->rows);
|
|
|
|
pos = (bottom_bound - val) * (mv->img_h - mv->rows);
|
|
|
|
if (val < bottom_bound)
|
|
|
|
mv->screen.pos_val = val;
|
|
|
|
if (val > bottom_bound)
|
|
|
|
{
|
|
|
|
mv->screen.pos_val = bottom_bound;
|
|
|
|
pos = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
termio_scroll_set(mv->termio, (int) pos);
|
2014-07-20 12:33:38 -07:00
|
|
|
_screen_visual_bounds(mv);
|
2014-05-04 08:15:39 -07:00
|
|
|
}
|
|
|
|
|
2014-03-18 14:53:02 -07:00
|
|
|
static void
|
|
|
|
_smart_add(Evas_Object *obj)
|
|
|
|
{
|
|
|
|
Miniview *mv;
|
2014-03-30 11:38:49 -07:00
|
|
|
|
2014-03-18 14:53:02 -07:00
|
|
|
mv = calloc(1, sizeof(Miniview));
|
|
|
|
EINA_SAFETY_ON_NULL_RETURN(mv);
|
|
|
|
evas_object_smart_data_set(obj, mv);
|
2014-03-30 11:38:49 -07:00
|
|
|
mv->self = obj;
|
2014-03-18 14:53:02 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2014-03-30 11:38:49 -07:00
|
|
|
_smart_del(Evas_Object *obj)
|
2014-03-18 14:53:02 -07:00
|
|
|
{
|
|
|
|
Miniview *mv = evas_object_smart_data_get(obj);
|
|
|
|
|
2014-03-30 11:38:49 -07:00
|
|
|
if (!mv) return;
|
2014-05-04 08:03:05 -07:00
|
|
|
ecore_timer_del(mv->deferred_renderer);
|
2014-05-12 11:25:36 -07:00
|
|
|
evas_object_del(mv->base);
|
2014-05-04 08:03:05 -07:00
|
|
|
evas_object_del(mv->img);
|
|
|
|
free(mv);
|
2014-03-18 14:53:02 -07:00
|
|
|
}
|
|
|
|
|
2014-05-16 01:44:11 -07:00
|
|
|
static void
|
|
|
|
_do_configure(Evas_Object *obj)
|
|
|
|
{
|
|
|
|
Miniview *mv = evas_object_smart_data_get(obj);
|
|
|
|
Evas_Coord ox, oy, ow, oh, font_w, font_h, w;
|
|
|
|
|
|
|
|
if (!mv) return;
|
|
|
|
|
|
|
|
evas_object_geometry_get(mv->termio, &ox, &oy, &ow, &oh);
|
|
|
|
evas_object_size_hint_min_get(mv->termio, &font_w, &font_h);
|
|
|
|
|
2014-07-21 13:18:59 -07:00
|
|
|
if ((font_w <= 0) || (font_h <= 0) || (ow == 0) || (oh == 0)) return;
|
|
|
|
|
|
|
|
mv->img_h = oh;
|
|
|
|
mv->rows = oh / font_h;
|
|
|
|
mv->cols = ow / font_w;
|
2014-05-16 01:44:11 -07:00
|
|
|
|
|
|
|
if ((mv->rows == 0) || (mv->cols == 0)) return;
|
|
|
|
|
2014-07-21 13:18:59 -07:00
|
|
|
mv->screen.size = (double) mv->rows / (double) mv->img_h;
|
|
|
|
edje_object_part_drag_size_set(mv->base, "miniview_screen", 1.0, mv->screen.size);
|
|
|
|
|
2014-05-16 01:44:11 -07:00
|
|
|
w = (mv->cols * font_w) / font_h;
|
|
|
|
|
|
|
|
evas_object_resize(mv->base, w, mv->img_h);
|
|
|
|
evas_object_move(mv->base, ox + ow - w, oy);
|
|
|
|
}
|
|
|
|
|
2014-03-18 14:53:02 -07:00
|
|
|
static void
|
2016-10-05 13:00:22 -07:00
|
|
|
_smart_move(Evas_Object *obj,
|
|
|
|
Evas_Coord _x EINA_UNUSED,
|
|
|
|
Evas_Coord _y EINA_UNUSED)
|
2014-03-18 14:53:02 -07:00
|
|
|
{
|
|
|
|
Miniview *mv = evas_object_smart_data_get(obj);
|
|
|
|
|
2014-03-30 11:38:49 -07:00
|
|
|
if (!mv) return;
|
2014-05-16 01:44:11 -07:00
|
|
|
_do_configure(obj);
|
2014-07-02 16:54:10 -07:00
|
|
|
_queue_render(mv);
|
2014-03-18 14:53:02 -07:00
|
|
|
}
|
|
|
|
|
2014-04-20 09:45:21 -07:00
|
|
|
static void
|
|
|
|
_smart_show(Evas_Object *obj)
|
|
|
|
{
|
|
|
|
Miniview *mv = evas_object_smart_data_get(obj);
|
|
|
|
|
|
|
|
if (!mv) return;
|
2014-05-01 15:08:58 -07:00
|
|
|
if (!mv->is_shown)
|
|
|
|
{
|
|
|
|
mv->is_shown = 1;
|
2014-05-03 13:16:27 -07:00
|
|
|
mv->img_hist = 0;
|
2014-07-20 12:33:38 -07:00
|
|
|
mv->initial_pos = 1;
|
2014-07-21 13:18:59 -07:00
|
|
|
|
2014-07-02 16:54:10 -07:00
|
|
|
_queue_render(mv);
|
2014-05-12 11:25:36 -07:00
|
|
|
evas_object_show(mv->base);
|
2014-05-01 15:08:58 -07:00
|
|
|
}
|
2014-04-20 09:45:21 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_smart_hide(Evas_Object *obj)
|
|
|
|
{
|
|
|
|
Miniview *mv = evas_object_smart_data_get(obj);
|
|
|
|
|
|
|
|
if (!mv) return;
|
2014-05-01 15:08:58 -07:00
|
|
|
if (mv->is_shown)
|
|
|
|
{
|
|
|
|
mv->is_shown = 0;
|
2014-05-12 11:25:36 -07:00
|
|
|
evas_object_hide(mv->base);
|
2014-05-01 15:08:58 -07:00
|
|
|
}
|
2014-04-20 09:45:21 -07:00
|
|
|
}
|
|
|
|
|
2014-05-01 15:08:58 -07:00
|
|
|
void
|
2017-07-06 11:55:02 -07:00
|
|
|
miniview_redraw(const Evas_Object *obj)
|
2014-03-18 14:53:02 -07:00
|
|
|
{
|
2014-05-01 15:08:58 -07:00
|
|
|
Miniview *mv;
|
2014-05-15 23:46:04 -07:00
|
|
|
|
2014-05-04 08:03:05 -07:00
|
|
|
if (!obj) return;
|
|
|
|
mv = evas_object_smart_data_get(obj);
|
2014-05-15 23:46:04 -07:00
|
|
|
if ((!mv) || (!mv->is_shown)) return;
|
2014-07-02 16:54:10 -07:00
|
|
|
_queue_render(mv);
|
2014-05-04 08:03:05 -07:00
|
|
|
}
|
|
|
|
|
2014-05-16 01:44:11 -07:00
|
|
|
static void
|
|
|
|
miniview_colors_get(Miniview *mv, unsigned int *colors)
|
|
|
|
{
|
|
|
|
Evas_Object *tg = termio_textgrid_get(mv->termio);
|
|
|
|
int r, g, b, a, c;
|
|
|
|
|
|
|
|
for (c = 0; c < 256; c++)
|
|
|
|
{
|
|
|
|
evas_object_textgrid_palette_get
|
|
|
|
(tg, EVAS_TEXTGRID_PALETTE_STANDARD, c, &r, &g, &b, &a);
|
|
|
|
colors[c] = (a << 24) | (r << 16) | (g << 8) | b;
|
|
|
|
}
|
|
|
|
for (c = 0; c < 256; c++)
|
|
|
|
{
|
|
|
|
evas_object_textgrid_palette_get
|
|
|
|
(tg, EVAS_TEXTGRID_PALETTE_EXTENDED, c, &r, &g, &b, &a);
|
|
|
|
colors[c + 256] = (a << 24) | (r << 16) | (g << 8) | b;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-05-04 08:03:05 -07:00
|
|
|
static Eina_Bool
|
|
|
|
_deferred_renderer(void *data)
|
|
|
|
{
|
|
|
|
Miniview *mv = data;
|
2014-05-01 15:08:58 -07:00
|
|
|
Evas_Coord ox, oy, ow, oh;
|
2015-08-09 05:10:12 -07:00
|
|
|
int history_len, pos;
|
|
|
|
ssize_t wret;
|
2014-05-03 13:16:27 -07:00
|
|
|
unsigned int *pixels, y;
|
2014-05-04 11:18:23 -07:00
|
|
|
Termpty *ty;
|
2014-05-16 01:44:11 -07:00
|
|
|
unsigned int colors[512];
|
2014-07-20 12:33:38 -07:00
|
|
|
double bottom_bound;
|
2014-04-26 14:42:17 -07:00
|
|
|
|
2014-07-03 11:56:36 -07:00
|
|
|
if (!mv) return EINA_FALSE;
|
|
|
|
|
|
|
|
if ((!mv->is_shown) || (!mv->to_render) || (mv->img_h == 0))
|
2014-07-02 16:54:10 -07:00
|
|
|
{
|
|
|
|
mv->deferred_renderer = NULL;
|
2014-07-02 20:10:46 -07:00
|
|
|
return EINA_FALSE;
|
2014-07-02 16:54:10 -07:00
|
|
|
}
|
2014-03-18 14:53:02 -07:00
|
|
|
|
2014-05-16 01:44:11 -07:00
|
|
|
miniview_colors_get(mv, colors);
|
2014-07-02 16:54:10 -07:00
|
|
|
|
2014-05-04 11:18:23 -07:00
|
|
|
ty = termio_pty_get(mv->termio);
|
2016-06-04 06:43:23 -07:00
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(ty, EINA_FALSE);
|
2014-03-30 11:38:49 -07:00
|
|
|
evas_object_geometry_get(mv->termio, &ox, &oy, &ow, &oh);
|
2015-08-05 12:42:21 -07:00
|
|
|
if ((ow == 0) || (oh == 0) || (mv->cols == 1)) return EINA_TRUE;
|
2014-03-18 14:53:02 -07:00
|
|
|
|
2015-08-01 09:37:35 -07:00
|
|
|
history_len = termpty_backlog_length(ty);
|
2014-03-18 14:53:02 -07:00
|
|
|
|
2014-05-16 01:44:11 -07:00
|
|
|
evas_object_image_size_set(mv->img, mv->cols, mv->img_h);
|
|
|
|
ow = mv->cols;
|
|
|
|
oh = mv->img_h;
|
2014-05-04 11:18:23 -07:00
|
|
|
|
2014-04-27 12:34:27 -07:00
|
|
|
pixels = evas_object_image_data_get(mv->img, EINA_TRUE);
|
2014-05-04 11:18:23 -07:00
|
|
|
memset(pixels, 0, sizeof(*pixels) * ow * oh);
|
|
|
|
mv->img_h = oh;
|
2014-04-26 14:42:17 -07:00
|
|
|
|
2014-05-03 13:16:27 -07:00
|
|
|
/* "current"? */
|
|
|
|
if (mv->img_hist >= - ((int)mv->img_h - (int)mv->rows))
|
|
|
|
mv->img_hist = -((int)mv->img_h - (int)mv->rows);
|
|
|
|
if (mv->img_hist < -history_len)
|
|
|
|
mv->img_hist = -history_len;
|
2014-04-26 14:42:17 -07:00
|
|
|
|
2014-04-27 12:34:27 -07:00
|
|
|
for (y = 0; y < mv->img_h; y++)
|
2014-04-26 14:42:17 -07:00
|
|
|
{
|
2020-04-17 14:09:07 -07:00
|
|
|
Termcell *cells = termpty_cellrow_get(ty, mv->img_hist + y, &wret);
|
|
|
|
|
|
|
|
if (!cells)
|
|
|
|
break;
|
2014-05-16 01:44:11 -07:00
|
|
|
_draw_line(ty, &pixels[y * mv->cols], cells, wret, colors);
|
2014-04-26 14:42:17 -07:00
|
|
|
}
|
2014-05-03 13:16:27 -07:00
|
|
|
evas_object_image_data_set(mv->img, pixels);
|
2014-05-04 11:18:23 -07:00
|
|
|
evas_object_image_pixels_dirty_set(mv->img, EINA_FALSE);
|
|
|
|
evas_object_image_data_update_add(mv->img, 0, 0, ow, oh);
|
2014-05-04 08:03:05 -07:00
|
|
|
|
2014-07-15 03:20:19 -07:00
|
|
|
if (history_len > (int)(mv->img_h - mv->rows)) mv->fits_to_img = EINA_FALSE;
|
|
|
|
else mv->fits_to_img = EINA_TRUE;
|
|
|
|
|
2014-07-20 12:33:38 -07:00
|
|
|
bottom_bound = ((double) (-mv->img_hist )) / (mv->img_h - mv->rows);
|
|
|
|
pos = termio_scroll_get(mv->termio);
|
|
|
|
if ((pos != 0) && (mv->initial_pos))
|
2014-07-15 03:20:19 -07:00
|
|
|
{
|
2014-07-20 12:33:38 -07:00
|
|
|
double val;
|
|
|
|
val = (double) pos / (mv->img_h - mv->rows);
|
|
|
|
if ((mv->fits_to_img))
|
|
|
|
{
|
|
|
|
mv->screen.pos_val = bottom_bound - val;
|
|
|
|
mv->initial_pos = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (val > 1)
|
|
|
|
{
|
|
|
|
mv->img_hist += (mv->img_hist * (int)val);
|
|
|
|
mv->screen.pos_val = (double)(1 - ( val - (int) val));
|
|
|
|
mv->initial_pos = 0;
|
|
|
|
mv->to_render = 1;
|
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
mv->screen.pos_val = bottom_bound - val;
|
|
|
|
mv->initial_pos = 0;
|
|
|
|
}
|
|
|
|
}
|
2014-07-15 03:20:19 -07:00
|
|
|
}
|
2014-07-20 12:33:38 -07:00
|
|
|
if (pos == 0)
|
|
|
|
mv->screen.pos_val = bottom_bound;
|
|
|
|
|
|
|
|
edje_object_part_drag_value_set(mv->base, "miniview_screen", 0.0, mv->screen.pos_val);
|
2014-07-15 03:20:19 -07:00
|
|
|
|
2014-05-04 08:03:05 -07:00
|
|
|
mv->to_render = 0;
|
2014-07-02 16:54:10 -07:00
|
|
|
mv->deferred_renderer = NULL;
|
2014-07-20 12:33:38 -07:00
|
|
|
_screen_visual_bounds(mv);
|
2014-07-02 16:54:10 -07:00
|
|
|
return EINA_FALSE;
|
2014-03-18 14:53:02 -07:00
|
|
|
}
|
|
|
|
|
2014-04-15 14:25:12 -07:00
|
|
|
|
2014-03-30 11:38:49 -07:00
|
|
|
static void
|
|
|
|
_smart_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h)
|
2014-03-18 14:53:02 -07:00
|
|
|
{
|
2014-05-04 11:18:23 -07:00
|
|
|
Evas_Coord font_w, font_h, ox, oy;
|
2014-03-18 14:53:02 -07:00
|
|
|
Miniview *mv = evas_object_smart_data_get(obj);
|
|
|
|
if (!mv) return;
|
|
|
|
|
2014-05-04 11:18:23 -07:00
|
|
|
mv->img_h = h;
|
|
|
|
|
|
|
|
evas_object_geometry_get(mv->termio, &ox, &oy, NULL, NULL);
|
|
|
|
evas_object_size_hint_min_get(mv->termio, &font_w, &font_h);
|
2014-05-15 23:46:04 -07:00
|
|
|
if ((font_w <= 0) || (font_h <= 0)) return;
|
2014-05-04 11:18:23 -07:00
|
|
|
|
|
|
|
mv->rows = h / font_h;
|
|
|
|
mv->cols = w / font_w;
|
|
|
|
|
2014-05-15 23:46:04 -07:00
|
|
|
if ((mv->rows == 0) || (mv->cols == 0)) return;
|
2014-05-04 11:18:23 -07:00
|
|
|
|
2014-05-16 01:44:11 -07:00
|
|
|
_do_configure(obj);
|
2014-07-02 16:54:10 -07:00
|
|
|
_queue_render(mv);
|
2014-03-18 14:53:02 -07:00
|
|
|
}
|
|
|
|
|
2014-03-30 11:38:49 -07:00
|
|
|
|
|
|
|
static void
|
|
|
|
_smart_init(void)
|
2014-03-18 14:53:02 -07:00
|
|
|
{
|
2014-03-30 11:38:49 -07:00
|
|
|
static Evas_Smart_Class sc = EVAS_SMART_CLASS_INIT_NULL;
|
2014-03-18 14:53:02 -07:00
|
|
|
|
2014-03-30 11:38:49 -07:00
|
|
|
sc.name = "miniview";
|
|
|
|
sc.version = EVAS_SMART_CLASS_VERSION;
|
|
|
|
sc.add = _smart_add;
|
|
|
|
sc.del = _smart_del;
|
|
|
|
sc.resize = _smart_resize;
|
|
|
|
sc.move = _smart_move;
|
|
|
|
sc.show = _smart_show;
|
|
|
|
sc.hide = _smart_hide;
|
|
|
|
_smart = evas_smart_class_new(&sc);
|
2014-03-18 14:53:02 -07:00
|
|
|
}
|
|
|
|
|
2014-05-12 14:11:49 -07:00
|
|
|
static void
|
2016-10-05 13:00:22 -07:00
|
|
|
_cb_miniview_close(void *data,
|
|
|
|
Evas_Object *_obj EINA_UNUSED,
|
|
|
|
const char *_sig EINA_UNUSED,
|
|
|
|
const char *_src EINA_UNUSED)
|
2014-05-12 14:11:49 -07:00
|
|
|
{
|
|
|
|
Miniview *mv = data;
|
|
|
|
|
|
|
|
EINA_SAFETY_ON_NULL_RETURN(mv);
|
|
|
|
EINA_SAFETY_ON_NULL_RETURN(mv->termio);
|
2014-05-15 23:46:04 -07:00
|
|
|
if (mv->is_shown) term_miniview_hide(termio_term_get(mv->termio));
|
2014-05-12 14:11:49 -07:00
|
|
|
}
|
|
|
|
|
2014-03-18 14:53:02 -07:00
|
|
|
Evas_Object *
|
2014-03-30 11:38:49 -07:00
|
|
|
miniview_add(Evas_Object *parent, Evas_Object *termio)
|
2014-03-18 14:53:02 -07:00
|
|
|
{
|
|
|
|
Evas *e;
|
2014-05-12 11:25:36 -07:00
|
|
|
Evas_Object *obj, *o;
|
2014-03-18 14:53:02 -07:00
|
|
|
Miniview *mv;
|
2014-05-12 11:25:36 -07:00
|
|
|
Evas *canvas = evas_object_evas_get(parent);
|
2014-03-18 14:53:02 -07:00
|
|
|
|
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
|
|
|
|
e = evas_object_evas_get(parent);
|
|
|
|
if (!e) return NULL;
|
|
|
|
|
|
|
|
if (!_smart) _smart_init();
|
2014-03-30 11:38:49 -07:00
|
|
|
|
2014-03-18 14:53:02 -07:00
|
|
|
obj = evas_object_smart_add(e, _smart);
|
|
|
|
mv = evas_object_smart_data_get(obj);
|
|
|
|
if (!mv) return obj;
|
|
|
|
|
2014-03-30 11:38:49 -07:00
|
|
|
mv->termio = termio;
|
2014-05-12 11:25:36 -07:00
|
|
|
|
|
|
|
mv->base = edje_object_add(canvas);
|
|
|
|
theme_apply(mv->base, termio_config_get(termio), "terminology/miniview");
|
|
|
|
|
|
|
|
evas_object_smart_member_add(mv->base, obj);
|
|
|
|
|
|
|
|
/* miniview output widget */
|
2014-05-16 01:44:11 -07:00
|
|
|
o = evas_object_image_filled_add(canvas);
|
2014-05-12 11:25:36 -07:00
|
|
|
evas_object_image_alpha_set(o, EINA_TRUE);
|
|
|
|
edje_object_part_swallow(mv->base, "miniview.img", o);
|
2014-05-16 01:44:11 -07:00
|
|
|
evas_object_show(o);
|
2014-05-12 11:25:36 -07:00
|
|
|
|
|
|
|
mv->img = o;
|
|
|
|
|
|
|
|
evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_WHEEL,
|
|
|
|
_smart_cb_mouse_wheel, obj);
|
|
|
|
evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_DOWN,
|
|
|
|
_smart_cb_mouse_down, obj);
|
2014-05-15 23:46:04 -07:00
|
|
|
edje_object_signal_callback_add(mv->base, "miniview,close", "terminology",
|
|
|
|
_cb_miniview_close, mv);
|
2014-07-15 03:20:19 -07:00
|
|
|
edje_object_signal_callback_add(mv->base, "drag", "miniview_screen",
|
|
|
|
_on_screen_moved, obj);
|
|
|
|
edje_object_signal_callback_add(mv->base, "drag,stop", "miniview_screen",
|
|
|
|
_on_screen_stoped, obj);
|
2014-03-18 14:53:02 -07:00
|
|
|
return obj;
|
|
|
|
}
|
|
|
|
|