start of shaped client/border/menu support ... dropshaodw is SLOW with this.

SVN revision: 14173
This commit is contained in:
Carsten Haitzler 2005-04-13 15:52:34 +00:00
parent 896b4c34ca
commit 0939b44ff7
11 changed files with 569 additions and 164 deletions

View File

@ -232,7 +232,8 @@ images {
group {
name: "widgets/border/default/border";
data {
// item: "client_inset" "4 4 24 4";
// this tells e the border is shaped
// item: "shaped" "1";
}
parts {
part {

View File

@ -10,6 +10,10 @@ images {
}
group {
name: "widgets/menu/default/background";
data {
// this tells e the border is shaped
// item: "shaped" "1";
}
parts {
part {
name: "base";

View File

@ -212,6 +212,7 @@ e_border_new(E_Container *con, Ecore_X_Window win, int first_map)
bd->w = 1;
bd->h = 1;
bd->win = ecore_x_window_override_new(bd->container->win, 0, 0, bd->w, bd->h);
ecore_x_window_shape_events_select(bd->win, 1);
mwin = e_menu_grab_window_get();
if (!mwin) mwin = e_init_window_get();
if (mwin)
@ -236,6 +237,7 @@ e_border_new(E_Container *con, Ecore_X_Window win, int first_map)
bd->event_win = ecore_x_window_input_new(bd->win, 0, 0, bd->w, bd->h);
bd->bg_evas = ecore_evas_get(bd->bg_ecore_evas);
bd->bg_win = ecore_evas_software_x11_window_get(bd->bg_ecore_evas);
ecore_x_window_shape_events_select(bd->bg_win, 1);
ecore_evas_name_class_set(bd->bg_ecore_evas, "E", "Frame_Window");
ecore_evas_title_set(bd->bg_ecore_evas, "Enlightenment Frame");
bd->client.shell_win = ecore_x_window_override_new(bd->win, 0, 0, 1, 1);
@ -298,6 +300,7 @@ e_border_new(E_Container *con, Ecore_X_Window win, int first_map)
bd->w = bd->client.w;
bd->h = bd->client.h;
bd->changes.size = 1;
bd->changes.shape = 1;
printf("##- ON MAP CLIENT 0x%x SIZE %ix%i\n",
bd->client.win, bd->client.w, bd->client.h);
@ -1058,6 +1061,36 @@ e_border_find_by_client_window(Ecore_X_Window win)
return NULL;
}
E_Border *
e_border_find_by_frame_window(Ecore_X_Window win)
{
Evas_List *l;
for (l = borders; l; l = l->next)
{
E_Border *bd;
bd = l->data;
if (bd->bg_win == win) return bd;
}
return NULL;
}
E_Border *
e_border_find_by_window(Ecore_X_Window win)
{
Evas_List *l;
for (l = borders; l; l = l->next)
{
E_Border *bd;
bd = l->data;
if (bd->win == win) return bd;
}
return NULL;
}
E_Border *
e_border_focused_get(void)
{
@ -1543,7 +1576,26 @@ _e_border_cb_window_shape(void *data, int ev_type, void *ev)
e = ev;
bd = e_border_find_by_client_window(e->win);
if (!bd) return 1;
if (bd)
{
bd->changes.shape = 1;
bd->changed = 1;
return 1;
}
bd = e_border_find_by_window(e->win);
if (bd)
{
bd->need_shape_export = 1;
bd->changed = 1;
return 1;
}
bd = e_border_find_by_frame_window(e->win);
if (bd)
{
bd->need_shape_merge = 1;
bd->changed = 1;
return 1;
}
return 1;
}
@ -2518,6 +2570,39 @@ _e_border_eval(E_Border *bd)
bd->client.netwm.fetch.desktop = 0;
}
if (bd->changes.shape)
{
Ecore_X_Rectangle *rects;
int num;
rects = ecore_x_window_shape_rectangles_get(bd->client.win, &num);
if (rects)
{
if ((num == 1) &&
(rects[0].x == 0) &&
(rects[0].y == 0) &&
(rects[0].width == bd->client.w) &&
(rects[0].height == bd->client.h))
{
if (bd->client.shaped)
{
bd->client.shaped = 0;
}
}
else
{
if (!bd->client.shaped)
{
bd->client.shaped = 1;
}
}
free(rects);
}
bd->need_shape_merge = 1;
/* is the client shaped? */
bd->changes.shape = 0;
}
if (bd->client.border.changed)
{
Evas_Object *o;
@ -2551,6 +2636,37 @@ _e_border_eval(E_Border *bd)
ok = edje_object_file_set(o, path, buf);
if (ok)
{
const char *shape_option;
shape_option = edje_object_data_get(o, "shaped");
if (shape_option)
{
if (!strcmp(shape_option, "1"))
{
if (!bd->shaped)
{
bd->shaped = 1;
ecore_evas_shaped_set(bd->bg_ecore_evas, bd->shaped);
}
}
else
{
if (bd->shaped)
{
bd->shaped = 0;
ecore_evas_shaped_set(bd->bg_ecore_evas, bd->shaped);
}
}
}
else
{
if (bd->shaped)
{
bd->shaped = 0;
ecore_evas_shaped_set(bd->bg_ecore_evas, bd->shaped);
}
}
edje_object_part_text_set(o, "title_text",
// "Japanese (hiragana): いろはにほへとちりぬるを");
bd->client.icccm.title);
@ -2926,6 +3042,68 @@ _e_border_eval(E_Border *bd)
GRAV_SET(bd, ECORE_X_GRAVITY_NW);
bd->changes.reset_gravity = 0;
}
if (bd->need_shape_merge)
{
if ((bd->shaped) || (bd->client.shaped))
{
Ecore_X_Window twin;
twin = ecore_x_window_override_new(bd->win, 0, 0, bd->w, bd->h);
if (bd->shaped)
{
ecore_x_window_shape_window_set(twin, bd->bg_win);
}
else
{
Ecore_X_Rectangle rects[4];
rects[0].x = 0;
rects[0].y = 0;
rects[0].width = bd->w;
rects[0].height = bd->client_inset.t;
rects[1].x = 0;
rects[1].y = bd->client_inset.t;
rects[1].width = bd->client_inset.l;
rects[1].height = bd->client.h;
rects[2].x = bd->w - bd->client_inset.r;
rects[2].y = bd->client_inset.t;
rects[2].width = bd->client_inset.r;
rects[2].height = bd->client.h;
rects[3].x = 0;
rects[3].y = bd->h - bd->client_inset.b;
rects[3].width = bd->w;
rects[3].height = bd->client_inset.b;
ecore_x_window_shape_rectangles_set(twin, rects, 4);
}
ecore_x_window_shape_window_add_xy(twin, bd->client.win, bd->client_inset.l, bd->client_inset.t);
ecore_x_window_shape_window_set(bd->win, twin);
ecore_x_window_del(twin);
}
else
{
ecore_x_window_shape_mask_set(bd->win, 0);
}
bd->need_shape_merge = 0;
}
if (bd->need_shape_export)
{
Ecore_X_Rectangle *rects;
int num;
rects = ecore_x_window_shape_rectangles_get(bd->win, &num);
if (rects)
{
if (bd->client.shaped)
e_container_shape_solid_rect_set(bd->shape, 0, 0, 0, 0);
else
e_container_shape_solid_rect_set(bd->shape, bd->client_inset.l, bd->client_inset.t, bd->client.w, bd->client.h);
e_container_shape_rects_set(bd->shape, rects, num);
free(rects);
}
bd->need_shape_export = 0;
}
bd->changed = 0;
@ -3705,3 +3883,4 @@ _e_border_reorder_before(E_Border *bd, E_Border *before)
borders = evas_list_prepend(borders, bd);
}
}

View File

@ -71,7 +71,7 @@ struct _E_Border
Evas_List *handlers;
struct {
int l, r, t, b;
int l, r, t, b;
} client_inset;
Ecore_Evas *bg_ecore_evas;
@ -80,88 +80,90 @@ struct _E_Border
Evas_Object *bg_object;
Evas_Object *icon_object;
Ecore_X_Window event_win;
struct {
Ecore_X_Window shell_win;
Ecore_X_Window win;
int x, y, w, h;
struct {
unsigned char changed : 1;
char *name;
} border;
struct {
char *title;
char *name;
char *class;
char *icon_name;
char *machine;
int min_w, min_h;
int max_w, max_h;
int base_w, base_h;
int step_w, step_h;
int start_x, start_y;
double min_aspect, max_aspect;
Ecore_X_Window_State_Hint initial_state;
Ecore_X_Pixmap icon_pixmap;
Ecore_X_Pixmap icon_mask;
Ecore_X_Window icon_window;
Ecore_X_Window window_group;
Ecore_X_Gravity gravity;
unsigned char take_focus : 1;
unsigned char accepts_focus : 1;
unsigned char urgent : 1;
unsigned char delete_request : 1;
unsigned char withdrawn : 1;
unsigned char iconic : 1;
unsigned char request_pos : 1;
struct {
unsigned int title : 1;
unsigned int name_class : 1;
unsigned int icon_name : 1;
unsigned int machine : 1;
unsigned int hints : 1;
unsigned int size_pos_hints : 1;
unsigned int protocol : 1;
} fetch;
} icccm;
struct {
Ecore_X_MWM_Hint_Func func;
Ecore_X_MWM_Hint_Decor decor;
Ecore_X_MWM_Hint_Input input;
unsigned char exists : 1;
unsigned char borderless : 1;
struct {
unsigned int hints : 1;
} fetch;
} mwm;
struct {
pid_t pid;
int desktop;
struct {
unsigned int pid : 1;
unsigned int desktop : 1;
} fetch;
/* NetWM Window state */
struct {
unsigned char modal : 1;
unsigned char maximized_v : 1;
unsigned char maximized_h : 1;
unsigned char skip_taskbar : 1;
unsigned char skip_pager : 1;
unsigned char fullscreen : 1;
unsigned char stacking : 2; /* 0 = None, 1 = Above, 2 = Below */
} state;
} netwm;
Ecore_X_Window_Attributes initial_attributes;
Ecore_X_Window shell_win;
Ecore_X_Window win;
int x, y, w, h;
struct {
unsigned char changed : 1;
char *name;
} border;
unsigned char shaped : 1;
struct {
char *title;
char *name;
char *class;
char *icon_name;
char *machine;
int min_w, min_h;
int max_w, max_h;
int base_w, base_h;
int step_w, step_h;
int start_x, start_y;
double min_aspect, max_aspect;
Ecore_X_Window_State_Hint initial_state;
Ecore_X_Pixmap icon_pixmap;
Ecore_X_Pixmap icon_mask;
Ecore_X_Window icon_window;
Ecore_X_Window window_group;
Ecore_X_Gravity gravity;
unsigned char take_focus : 1;
unsigned char accepts_focus : 1;
unsigned char urgent : 1;
unsigned char delete_request : 1;
unsigned char withdrawn : 1;
unsigned char iconic : 1;
unsigned char request_pos : 1;
struct {
unsigned int title : 1;
unsigned int name_class : 1;
unsigned int icon_name : 1;
unsigned int machine : 1;
unsigned int hints : 1;
unsigned int size_pos_hints : 1;
unsigned int protocol : 1;
} fetch;
} icccm;
struct {
Ecore_X_MWM_Hint_Func func;
Ecore_X_MWM_Hint_Decor decor;
Ecore_X_MWM_Hint_Input input;
unsigned char exists : 1;
unsigned char borderless : 1;
struct {
unsigned int hints : 1;
} fetch;
} mwm;
struct {
pid_t pid;
int desktop;
struct {
unsigned int pid : 1;
unsigned int desktop : 1;
} fetch;
/* NetWM Window state */
struct {
unsigned char modal : 1;
unsigned char maximized_v : 1;
unsigned char maximized_h : 1;
unsigned char skip_taskbar : 1;
unsigned char skip_pager : 1;
unsigned char fullscreen : 1;
unsigned char stacking : 2; /* 0 = None, 1 = Above, 2 = Below */
} state;
} netwm;
Ecore_X_Window_Attributes initial_attributes;
} client;
E_Container_Shape *shape;
unsigned char visible : 1;
unsigned char moving : 1;
unsigned char focused : 1;
@ -172,38 +174,42 @@ struct _E_Border
unsigned char maximized : 1;
unsigned char iconic : 1;
unsigned char sticky : 1;
unsigned char shaped : 1;
unsigned char need_shape_merge : 1;
unsigned char need_shape_export : 1;
unsigned char changed : 1;
unsigned char ignore_first_unmap;
unsigned char resize_mode;
struct {
int x, y, w, h;
int x, y, w, h;
} saved;
struct {
double start;
double val;
int x, y;
E_Direction dir;
Ecore_Animator *anim;
double start;
double val;
int x, y;
E_Direction dir;
Ecore_Animator *anim;
} shade;
Evas_List *stick_desks;
E_Menu *border_menu;
Evas_List *pending_move_resize;
struct {
unsigned int visible : 1;
unsigned int pos : 1;
unsigned int size : 1;
unsigned int stack : 1;
unsigned int prop : 1;
unsigned int border : 1;
unsigned int reset_gravity : 1;
unsigned int shading : 1;
unsigned int shaded : 1;
unsigned int visible : 1;
unsigned int pos : 1;
unsigned int size : 1;
unsigned int stack : 1;
unsigned int prop : 1;
unsigned int border : 1;
unsigned int reset_gravity : 1;
unsigned int shading : 1;
unsigned int shaded : 1;
unsigned int shape : 1;
} changes;
};
@ -321,6 +327,8 @@ EAPI void e_border_stick(E_Border *bd);
EAPI void e_border_unstick(E_Border *bd);
EAPI E_Border *e_border_find_by_client_window(Ecore_X_Window win);
EAPI E_Border *e_border_find_by_frame_window(Ecore_X_Window win);
EAPI E_Border *e_border_find_by_window(Ecore_X_Window win);
EAPI E_Border *e_border_focused_get(void);
EAPI void e_border_idler_before(void);

View File

@ -394,8 +394,59 @@ e_container_shape_rects_get(E_Container_Shape *es)
return es->shape;
}
void
e_container_shape_rects_set(E_Container_Shape *es, Ecore_X_Rectangle *rects, int num)
{
Evas_List *l;
int i;
E_OBJECT_CHECK(es);
E_OBJECT_TYPE_CHECK(es, E_CONTAINER_SHAPE_TYPE);
if (es->shape)
{
for (l = es->shape; l; l = l->next)
free(l->data);
evas_list_free(es->shape);
es->shape = NULL;
}
if (rects)
{
for (i = 0; i < num; i++)
{
E_Rect *r;
r = malloc(sizeof(E_Rect));
if (r)
{
r->x = rects[i].x;
r->y = rects[i].y;
r->w = rects[i].width;
r->h = rects[i].height;
es->shape = evas_list_append(es->shape, r);
}
}
}
_e_container_shape_change_call(es, E_CONTAINER_SHAPE_RECTS);
}
void
e_container_shape_solid_rect_set(E_Container_Shape *es, int x, int y, int w, int h)
{
es->solid_rect.x = x;
es->solid_rect.y = y;
es->solid_rect.w = w;
es->solid_rect.h = h;
}
void
e_container_shape_solid_rect_get(E_Container_Shape *es, int *x, int *y, int *w, int *h)
{
if (x) *x = es->solid_rect.x;
if (y) *y = es->solid_rect.y;
if (w) *w = es->solid_rect.w;
if (h) *h = es->solid_rect.h;
}
/* local subsystem functions */
static void

View File

@ -57,6 +57,9 @@ struct _E_Container_Shape
E_Container *con;
int x, y, w, h;
unsigned char visible : 1;
struct {
int x, y, w, h;
} solid_rect;
Evas_List *shape;
};
@ -98,6 +101,9 @@ EAPI E_Container *e_container_shape_container_get(E_Container_Shape *es);
EAPI void e_container_shape_change_callback_add(E_Container *con, void (*func) (void *data, E_Container_Shape *es, E_Container_Shape_Change ch), void *data);
EAPI void e_container_shape_change_callback_del(E_Container *con, void (*func) (void *data, E_Container_Shape *es, E_Container_Shape_Change ch), void *data);
EAPI Evas_List *e_container_shape_rects_get(E_Container_Shape *es);
EAPI void e_container_shape_rects_set(E_Container_Shape *es, Ecore_X_Rectangle *rects, int num);
EAPI void e_container_shape_solid_rect_set(E_Container_Shape *es, int x, int y, int w, int h);
EAPI void e_container_shape_solid_rect_get(E_Container_Shape *es, int *x, int *y, int *w, int *h);
extern EAPI int E_EVENT_CONTAINER_RESIZE;

View File

@ -38,10 +38,7 @@ e_intl_shutdown(void)
free(_e_intl_language);
_e_intl_language = NULL;
while (_e_intl_languages)
{
free(_e_intl_languages->data);
_e_intl_languages = evas_list_remove_list(_e_intl_languages, _e_intl_languages);
}
_e_intl_languages = evas_list_remove_list(_e_intl_languages, _e_intl_languages);
return 1;
}

View File

@ -65,6 +65,7 @@ static int _e_menu_cb_mouse_up (void *data, int type, void *e
static int _e_menu_cb_mouse_move (void *data, int type, void *event);
static int _e_menu_cb_mouse_wheel (void *data, int type, void *event);
static int _e_menu_cb_scroll_timer (void *data);
static int _e_menu_cb_window_shape (void *data, int ev_type, void *ev);
/* local subsystem globals */
static Ecore_X_Window _e_menu_win = 0;
@ -77,23 +78,25 @@ static int _e_menu_y = 0;
static Ecore_X_Time _e_menu_time = 0;
static int _e_menu_autoscroll_x = 0;
static int _e_menu_autoscroll_y = 0;
static Ecore_Event_Handler *_e_menu_key_down_handler = NULL;
static Ecore_Event_Handler *_e_menu_key_up_handler = NULL;
static Ecore_Event_Handler *_e_menu_mouse_down_handler = NULL;
static Ecore_Event_Handler *_e_menu_mouse_up_handler = NULL;
static Ecore_Event_Handler *_e_menu_mouse_move_handler = NULL;
static Ecore_Event_Handler *_e_menu_mouse_wheel_handler = NULL;
static Ecore_Event_Handler *_e_menu_key_down_handler = NULL;
static Ecore_Event_Handler *_e_menu_key_up_handler = NULL;
static Ecore_Event_Handler *_e_menu_mouse_down_handler = NULL;
static Ecore_Event_Handler *_e_menu_mouse_up_handler = NULL;
static Ecore_Event_Handler *_e_menu_mouse_move_handler = NULL;
static Ecore_Event_Handler *_e_menu_mouse_wheel_handler = NULL;
static Ecore_Event_Handler *_e_menu_window_shape_handler = NULL;
/* externally accessible functions */
int
e_menu_init(void)
{
_e_menu_key_down_handler = ecore_event_handler_add(ECORE_X_EVENT_KEY_DOWN, _e_menu_cb_key_down, NULL);
_e_menu_key_up_handler = ecore_event_handler_add(ECORE_X_EVENT_KEY_UP, _e_menu_cb_key_up, NULL);
_e_menu_mouse_down_handler = ecore_event_handler_add(ECORE_X_EVENT_MOUSE_BUTTON_DOWN, _e_menu_cb_mouse_down, NULL);
_e_menu_mouse_up_handler = ecore_event_handler_add(ECORE_X_EVENT_MOUSE_BUTTON_UP, _e_menu_cb_mouse_up, NULL);
_e_menu_mouse_move_handler = ecore_event_handler_add(ECORE_X_EVENT_MOUSE_MOVE, _e_menu_cb_mouse_move, NULL);
_e_menu_mouse_wheel_handler = ecore_event_handler_add(ECORE_X_EVENT_MOUSE_WHEEL, _e_menu_cb_mouse_wheel, NULL);
_e_menu_key_down_handler = ecore_event_handler_add(ECORE_X_EVENT_KEY_DOWN, _e_menu_cb_key_down, NULL);
_e_menu_key_up_handler = ecore_event_handler_add(ECORE_X_EVENT_KEY_UP, _e_menu_cb_key_up, NULL);
_e_menu_mouse_down_handler = ecore_event_handler_add(ECORE_X_EVENT_MOUSE_BUTTON_DOWN, _e_menu_cb_mouse_down, NULL);
_e_menu_mouse_up_handler = ecore_event_handler_add(ECORE_X_EVENT_MOUSE_BUTTON_UP, _e_menu_cb_mouse_up, NULL);
_e_menu_mouse_move_handler = ecore_event_handler_add(ECORE_X_EVENT_MOUSE_MOVE, _e_menu_cb_mouse_move, NULL);
_e_menu_mouse_wheel_handler = ecore_event_handler_add(ECORE_X_EVENT_MOUSE_WHEEL, _e_menu_cb_mouse_wheel, NULL);
_e_menu_window_shape_handler = ecore_event_handler_add(ECORE_X_EVENT_WINDOW_SHAPE, _e_menu_cb_window_shape, NULL);
return 1;
}
@ -104,9 +107,9 @@ e_menu_shutdown(void)
E_FN_DEL(ecore_event_handler_del, _e_menu_key_up_handler);
E_FN_DEL(ecore_event_handler_del, _e_menu_mouse_down_handler);
E_FN_DEL(ecore_event_handler_del, _e_menu_mouse_up_handler);
E_FN_DEL(ecore_event_handler_del, _e_menu_mouse_move_handler);
E_FN_DEL(ecore_event_handler_del, _e_menu_mouse_wheel_handler);
E_FN_DEL(ecore_event_handler_del, _e_menu_window_shape_handler);
while (_e_active_menus)
{
@ -611,7 +614,8 @@ e_menu_idler_before(void)
m->prev.visible = m->cur.visible;
ecore_evas_raise(m->ecore_evas);
ecore_evas_show(m->ecore_evas);
e_container_shape_show(m->shape);
if (!m->shaped)
e_container_shape_show(m->shape);
}
}
/* phase 4. de-activate... */
@ -639,6 +643,28 @@ e_menu_idler_before(void)
e_object_unref(E_OBJECT(m));
}
}
/* phase 5. shapes... */
for (l = _e_active_menus; l; l = l->next)
{
E_Menu *m;
m = l->data;
if (m->need_shape_export)
{
Ecore_X_Rectangle *rects;
int num;
rects = ecore_x_window_shape_rectangles_get(m->evas_win, &num);
if (rects)
{
e_container_shape_rects_set(m->shape, rects, num);
free(rects);
}
m->need_shape_export = 0;
if (m->cur.visible)
e_container_shape_show(m->shape);
}
}
/* del refcount to all menus we worked with */
while (tmp)
{
@ -981,6 +1007,7 @@ _e_menu_realize(E_Menu *m)
{
Evas_Object *o;
Evas_List *l;
int ok;
if (m->realized) return;
m->realized = 1;
@ -999,6 +1026,7 @@ _e_menu_realize(E_Menu *m)
evas_event_feed_mouse_in(m->evas, NULL);
evas_event_feed_mouse_move(m->evas, -1000000, -1000000, NULL);
m->evas_win = ecore_evas_software_x11_window_get(m->ecore_evas);
ecore_x_window_shape_events_select(m->evas_win, 1);
ecore_evas_name_class_set(m->ecore_evas, "E", "_e_menu_window");
ecore_evas_title_set(m->ecore_evas, "E Menu");
@ -1008,12 +1036,28 @@ _e_menu_realize(E_Menu *m)
evas_object_data_set(o, "e_menu", m);
evas_object_move(o, 0, 0);
evas_object_resize(o, m->cur.w, m->cur.h);
edje_object_file_set(o,
/* FIXME: "default.edj" needs to come from conf */
e_path_find(path_themes, "default.edj"),
"widgets/menu/default/background");
ok = edje_object_file_set(o,
/* FIXME: "default.edj" needs to come from conf */
e_path_find(path_themes, "default.edj"),
"widgets/menu/default/background");
if (ok)
{
const char *shape_option;
shape_option = edje_object_data_get(o, "shaped");
if (shape_option)
{
if (!strcmp(shape_option, "1"))
{
m->shaped = 1;
}
}
}
evas_object_show(o);
if (m->shaped)
ecore_evas_shaped_set(m->ecore_evas, m->shaped);
o = e_box_add(m->evas);
m->container_object = o;
evas_object_intercept_move_callback_add (o, _e_menu_cb_intercept_container_move, m);
@ -2123,3 +2167,21 @@ _e_menu_cb_scroll_timer(void *data)
}
return 1;
}
static int
_e_menu_cb_window_shape(void *data, int ev_type, void *ev)
{
Evas_List *l;
Ecore_X_Event_Window_Shape *e;
e = ev;
for (l = _e_active_menus; l; l = l->next)
{
E_Menu *m;
m = l->data;
if (m->evas_win == e->win)
m->need_shape_export = 1;
}
return 1;
}

View File

@ -68,6 +68,8 @@ struct _E_Menu
unsigned char pending_new_submenu : 1;
unsigned char have_submenu : 1;
unsigned char in_active_list : 1;
unsigned char shaped : 1;
unsigned char need_shape_export : 1;
};
struct _E_Menu_Item

View File

@ -157,6 +157,7 @@ _ds_init(E_Module *m)
E_CONFIG_VAL(D, T, shadow_x, INT);
E_CONFIG_VAL(D, T, shadow_y, INT);
E_CONFIG_VAL(D, T, blur_size, INT);
E_CONFIG_VAL(D, T, quality, INT);
E_CONFIG_VAL(D, T, shadow_darkness, DOUBLE);
ds->conf = e_config_domain_load("module.dropshadow", ds->conf_edd);
@ -166,13 +167,15 @@ _ds_init(E_Module *m)
ds->conf->shadow_x = 4;
ds->conf->shadow_y = 4;
ds->conf->blur_size = 10;
ds->conf->quality = 2;
ds->conf->shadow_darkness = 0.5;
}
E_CONFIG_LIMIT(ds->conf->shadow_x, -200, 200);
E_CONFIG_LIMIT(ds->conf->shadow_y, -200, 200);
E_CONFIG_LIMIT(ds->conf->blur_size, 1, 120);
E_CONFIG_LIMIT(ds->conf->quality, 1, 10);
E_CONFIG_LIMIT(ds->conf->shadow_darkness, 0.0, 1.0);
if (ds->conf->shadow_x >= ds->conf->blur_size)
ds->conf->shadow_x = ds->conf->blur_size - 1;
if (ds->conf->shadow_y >= ds->conf->blur_size)
@ -222,6 +225,7 @@ _ds_shutdown(Dropshadow *ds)
}
if (ds->idler_before) e_main_idler_before_del(ds->idler_before);
if (ds->table.gauss) free(ds->table.gauss);
if (ds->table.gauss2) free(ds->table.gauss2);
_ds_shared_free(ds);
free(ds);
}
@ -831,12 +835,23 @@ _ds_shadow_recalc(Shadow *sh)
Evas_List *l;
Shpix *sp;
int shw, shh, bsz, shx, shy;
int x1, y1, x2, y2;
int q;
q = sh->ds->conf->quality;
if ((!rects) && (sh->toosmall))
sh->square = 1;
else
sh->square = 0;
/* FIXME: find "minimum" center of the shape rects - if any */
/* idea - take rects, run thru list. for each rect start x
* check all rects with a y > than this one. (will come later
* in the list). keep track of the last y point and id this rect x
* spans this line then advance new y point by rect size if it
* immediately joins it...
*/
shx = sh->ds->conf->shadow_x;
shy = sh->ds->conf->shadow_y;
shw = sh->w;
@ -849,56 +864,114 @@ _ds_shadow_recalc(Shadow *sh)
sh->use_shared = 0;
}
sp = _ds_shpix_new(shw + (bsz * 2), shh + (bsz * 2));
sp = _ds_shpix_new((shw + (bsz * 2)) / q, (shh + (bsz * 2)) / q);
if (sp)
{
int slx, sly, slw, slh;
if (!rects)
{
_ds_shpix_fill(sp, 0, 0, shw + (bsz * 2), bsz, 0);
_ds_shpix_fill(sp, 0, bsz + shh, shw + (bsz * 2), bsz, 0);
_ds_shpix_fill(sp, 0, bsz, bsz, shh, 0);
_ds_shpix_fill(sp, bsz + shw, bsz, bsz, shh, 0);
_ds_shpix_fill(sp, bsz, bsz, shw, shh, 255);
/* FIXME; rounding errors - fix as below in else{} */
_ds_shpix_fill(sp, 0, 0, (shw + (bsz * 2)) / q, (bsz) / q, 0);
_ds_shpix_fill(sp, 0, (bsz + shh) / q, (shw + (bsz * 2)) / q, (bsz) / q, 0);
_ds_shpix_fill(sp, 0, (bsz) / q, (bsz) / q, (shh) / q, 0);
_ds_shpix_fill(sp, (bsz + shw) / q, (bsz) / q, (bsz) / q, (shh) / q, 0);
_ds_shpix_fill(sp, (bsz) / q, (bsz) / q, (shw) / q, (shh) / q, 255);
}
else
{
_ds_shpix_fill(sp, 0, 0, (shw + (bsz * 2)) / q, (shh + (bsz * 2)) / q, 0);
for (l = rects; l; l = l->next)
{
E_Rect *r;
r = l->data;
_ds_shpix_fill(sp, bsz + r->x, bsz + r->y, r->w, r->h, 255);
x1 = (bsz + r->x) / q;
y1 = (bsz + r->y) / q;
x2 = (bsz + r->x + r->w - 1) / q;
y2 = (bsz + r->y + r->h - 1) / q;
_ds_shpix_fill(sp, x1, y1, (x2 - x1) + 1, (y2 - y1) + 1, 255);
}
}
_ds_shpix_blur(sp, 0, 0, shw + (bsz * 2), shh + (bsz * 2),
sh->ds->table.gauss, bsz);
_ds_shpix_object_set(sp, sh->object[0], 0, 0,
shw + (bsz * 2), shh + (bsz * 2));
evas_object_move(sh->object[0],
sh->x + shx - bsz,
sh->y + shy - bsz);
evas_object_image_border_set(sh->object[0],
0, 0, 0, 0);
evas_object_resize(sh->object[0],
sh->w + (bsz * 2),
sh->h + (bsz * 2));
evas_object_image_fill_set(sh->object[0], 0, 0,
sh->w + (bsz * 2),
sh->h + (bsz * 2));
_ds_object_unset(sh->object[1]);
_ds_object_unset(sh->object[2]);
_ds_object_unset(sh->object[3]);
_ds_shpix_free(sp);
}
if (evas_object_visible_get(sh->object[0]))
{
evas_object_hide(sh->object[1]);
evas_object_hide(sh->object[2]);
evas_object_hide(sh->object[3]);
e_container_shape_solid_rect_get(sh->shape, &slx, &sly, &slw, &slh);
slx += bsz;
sly += bsz;
slw -= bsz * 2;
slh -= bsz * 2;
slw = (slw - 1 + slx) / q;
slh = (slh - 1 + sly) / q;
slx /= q;
sly /= q;
slw = slw - slx + 1;
slh = slh - sly + 1;
if ((slw > 0) && (slh > 0))
{
/* FIXME: handle as 4 separate shadow obj's - not 1 */
_ds_shpix_blur(sp, 0, 0,
(shw + (bsz * 2)) / q,
(shh + (bsz * 2)) / q,
sh->ds->table.gauss2, (bsz) / q);
_ds_shpix_object_set(sp, sh->object[0], 0, 0,
(shw + (bsz * 2)) / q, (shh + (bsz * 2)) / q);
evas_object_move(sh->object[0],
sh->x + shx - bsz,
sh->y + shy - bsz);
evas_object_image_smooth_scale_set(sh->object[0], 1);
evas_object_image_border_set(sh->object[0],
0, 0, 0, 0);
evas_object_resize(sh->object[0],
sh->w + (bsz * 2),
sh->h + (bsz * 2));
evas_object_image_fill_set(sh->object[0], 0, 0,
sh->w + (bsz * 2),
sh->h + (bsz * 2));
_ds_object_unset(sh->object[1]);
_ds_object_unset(sh->object[2]);
_ds_object_unset(sh->object[3]);
_ds_shpix_free(sp);
if (evas_object_visible_get(sh->object[0]))
{
evas_object_hide(sh->object[1]);
evas_object_hide(sh->object[2]);
evas_object_hide(sh->object[3]);
}
}
else
{
_ds_shpix_blur(sp, 0, 0,
(shw + (bsz * 2)) / q,
(shh + (bsz * 2)) / q,
sh->ds->table.gauss2, (bsz) / q);
_ds_shpix_object_set(sp, sh->object[0], 0, 0,
(shw + (bsz * 2)) / q, (shh + (bsz * 2)) / q);
evas_object_move(sh->object[0],
sh->x + shx - bsz,
sh->y + shy - bsz);
evas_object_image_smooth_scale_set(sh->object[0], 1);
evas_object_image_border_set(sh->object[0],
0, 0, 0, 0);
evas_object_resize(sh->object[0],
sh->w + (bsz * 2),
sh->h + (bsz * 2));
evas_object_image_fill_set(sh->object[0], 0, 0,
sh->w + (bsz * 2),
sh->h + (bsz * 2));
_ds_object_unset(sh->object[1]);
_ds_object_unset(sh->object[2]);
_ds_object_unset(sh->object[3]);
_ds_shpix_free(sp);
if (evas_object_visible_get(sh->object[0]))
{
evas_object_hide(sh->object[1]);
evas_object_hide(sh->object[2]);
evas_object_hide(sh->object[3]);
}
}
}
}
else
@ -965,6 +1038,7 @@ _ds_shadow_recalc(Shadow *sh)
_ds_shstore_object_set(sh->ds->shared.shadow[2], sh->object[2]);
_ds_shstore_object_set(sh->ds->shared.shadow[3], sh->object[3]);
evas_object_image_smooth_scale_set(sh->object[0], 0);
evas_object_move(sh->object[0],
sh->x + shx - bsz,
sh->y + shy - bsz);
@ -977,6 +1051,7 @@ _ds_shadow_recalc(Shadow *sh)
sh->w + (bsz) * 2,
bsz - shy);
evas_object_image_smooth_scale_set(sh->object[1], 0);
evas_object_move(sh->object[1],
sh->x + shx - bsz,
sh->y);
@ -989,6 +1064,7 @@ _ds_shadow_recalc(Shadow *sh)
bsz - shx,
sh->h);
evas_object_image_smooth_scale_set(sh->object[2], 0);
evas_object_move(sh->object[2],
sh->x + sh->w,
sh->y);
@ -1001,6 +1077,7 @@ _ds_shadow_recalc(Shadow *sh)
bsz + shx,
sh->h);
evas_object_image_smooth_scale_set(sh->object[3], 0);
evas_object_move(sh->object[3],
sh->x + shx - bsz,
sh->y + sh->h);
@ -1100,7 +1177,8 @@ static void
_ds_blur_init(Dropshadow *ds)
{
int i;
int q;
if (ds->table.gauss) free(ds->table.gauss);
ds->table.gauss_size = (ds->conf->blur_size * 2) - 1;
ds->table.gauss = calloc(1, ds->table.gauss_size * sizeof(unsigned char));
@ -1115,6 +1193,22 @@ _ds_blur_init(Dropshadow *ds)
ds->table.gauss[ds->conf->blur_size - 1 - i] =
_ds_gauss_int(-1.5 + (v * 3.0)) * 255.0;
}
q = ds->conf->quality;
if (ds->table.gauss2) free(ds->table.gauss2);
ds->table.gauss2_size = ((ds->conf->blur_size / q) * 2) - 1;
ds->table.gauss2 = calloc(1, ds->table.gauss2_size * sizeof(unsigned char));
ds->table.gauss[(ds->conf->blur_size / q) - 1] = 255;
for (i = 1; i < ((ds->conf->blur_size / q) - 1); i++)
{
double v;
v = (double)i / ((ds->conf->blur_size / q) - 2);
ds->table.gauss2[(ds->conf->blur_size / q) - 1 + i] =
ds->table.gauss2[(ds->conf->blur_size / q) - 1 - i] =
_ds_gauss_int(-1.5 + (v * 3.0)) * 255.0;
}
}
static double
@ -1420,7 +1514,6 @@ _ds_shpix_object_set(Shpix *sp, Evas_Object *o, int x, int y, int w, int h)
evas_object_image_size_set(o, w, h);
evas_object_image_alpha_set(o, 1);
evas_object_image_smooth_scale_set(o, 0);
pix2 = evas_object_image_data_get(o, 1);
if (pix2)
{
@ -1625,7 +1718,6 @@ _ds_shstore_object_set(Shstore *st, Evas_Object *o)
evas_object_image_data_set(o, st->pix);
evas_object_image_data_update_add(o, 0, 0, st->w, st->h);
evas_object_image_alpha_set(o, 1);
evas_object_image_smooth_scale_set(o, 0);
}
static void

View File

@ -23,6 +23,7 @@ struct _Config
{
int shadow_x, shadow_y;
int blur_size;
int quality;
double shadow_darkness;
};
@ -39,6 +40,8 @@ struct _Dropshadow
struct {
unsigned char *gauss;
int gauss_size;
unsigned char *gauss2;
int gauss2_size;
} table;
struct {