EAPI int ecore_evas_init(void);
EAPI int ecore_evas_shutdown(void);
+EAPI void ecore_evas_app_comp_sync_set(int do_sync);
+EAPI int ecore_evas_app_comp_sync_get(void);
+
EAPI Eina_List *ecore_evas_engines_get(void);
EAPI void ecore_evas_engines_free(Eina_List *engines);
EAPI Ecore_Evas *ecore_evas_new(const char *engine_name, int x, int y, int w, int h, const char *extra_options);
EAPI void ecore_evas_manual_render_set(Ecore_Evas *ee, int manual_render);
EAPI int ecore_evas_manual_render_get(const Ecore_Evas *ee);
EAPI void ecore_evas_manual_render(Ecore_Evas *ee);
+EAPI void ecore_evas_comp_sync_set(Ecore_Evas *ee, int do_sync);
+EAPI int ecore_evas_comp_sync_get(const Ecore_Evas *ee);
EAPI Ecore_Window ecore_evas_window_get(const Ecore_Evas *ee);
return _ecore_evas_init_count;
}
+int _ecore_evas_app_comp_sync = 1;
+
+EAPI void
+ecore_evas_app_comp_sync_set(int do_sync)
+{
+ _ecore_evas_app_comp_sync = do_sync;
+}
+
+EAPI int
+ecore_evas_app_comp_sync_get(void)
+{
+ return _ecore_evas_app_comp_sync;
+}
+
struct ecore_evas_engine {
const char *name;
Ecore_Evas *(*constructor)(int x, int y, int w, int h, const char *extra_options);
ee->engine.func->fn_render(ee);
}
+EAPI void
+ecore_evas_comp_sync_set(Ecore_Evas *ee, int do_sync)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_comp_sync_set");
+ return;
+ }
+ ee->no_comp_sync = !do_sync;
+}
+
+EAPI int
+ecore_evas_comp_sync_get(const Ecore_Evas *ee)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_comp_sync_get");
+ return 0;
+ }
+ return !ee->no_comp_sync;
+}
+
EAPI Ecore_Window
ecore_evas_window_get(const Ecore_Evas *ee)
{
ee = data;
ee->prop.focused = 1;
+ evas_focus_in(ee->evas);
if (ee->func.fn_focus_in) ee->func.fn_focus_in(ee);
}
ee = data;
ee->prop.focused = 0;
+ evas_focus_out(ee->evas);
if (ee->func.fn_focus_out) ee->func.fn_focus_out(ee);
}
evas_key_lock_add(ee->evas, "Num_Lock");
evas_key_lock_add(ee->evas, "Scroll_Lock");
- evas_event_feed_mouse_in(ee->evas, (unsigned int)((unsigned long long)(ecore_time_get() * 1000.0) & 0xffffffff), NULL);
-
ee->engine.func->fn_render = _ecore_evas_buffer_render;
_ecore_evas_register(ee);
fb_ee = ee;
+ evas_event_feed_mouse_in(ee->evas, (unsigned int)((unsigned long long)(ecore_time_get() * 1000.0) & 0xffffffff), NULL);
+ evas_focus_in(ee->evas);
+
return ee;
}
#else
Ecore_X_GC gc;
Ecore_X_XRegion *damages;
Ecore_X_Sync_Counter sync_counter;
+ int sync_val; // bigger! this will screw up at 2 billion frames (414 days of continual rendering @ 60fps)
int screen_num;
int px, py, pw, ph;
unsigned char direct_resize : 1;
unsigned char using_bg_pixmap : 1;
unsigned char managed : 1;
+ unsigned char sync_began : 1;
+ unsigned char sync_cancel : 1;
struct {
unsigned char modal : 1;
unsigned char sticky : 1;
unsigned char ignore_events : 1;
unsigned char manual_render : 1;
unsigned char registered : 1;
+ unsigned char no_comp_sync : 1;
};
#ifdef BUILD_ECORE_EVAS_X11
void _ecore_evas_idle_timeout_update(Ecore_Evas *ee);
void _ecore_evas_mouse_move_process(Ecore_Evas *ee, int x, int y, unsigned int timestamp);
+extern int _ecore_evas_app_comp_sync;
+
#endif
einfo->info.context = [[evas_view context] retain];
evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
- evas_event_feed_mouse_in(ee->evas, (unsigned int)((unsigned long long)(ecore_time_get() * 1000.0) & 0xffffffff), NULL);
-
ecore_evases = (Ecore_Evas *) eina_inlist_prepend(EINA_INLIST_GET(ecore_evases), EINA_INLIST_GET(ee));
+ evas_event_feed_mouse_in(ee->evas, (unsigned int)((unsigned long long)(ecore_time_get() * 1000.0) & 0xffffffff), NULL);
+ evas_focus_in(ee->evas);
+
return ee;
free_window:
ecore_event_window_register(0, ee, ee->evas, (Ecore_Event_Mouse_Move_Cb) _ecore_evas_mouse_move_process);
- evas_event_feed_mouse_in(ee->evas, (unsigned int)((unsigned long long)(ecore_time_get() * 1000.0) & 0xffffffff), NULL);
-
SDL_ShowCursor(SDL_DISABLE);
ee->engine.func->fn_render = _ecore_evas_sdl_render;
sdl_ee = ee;
+ evas_event_feed_mouse_in(ee->evas, (unsigned int)((unsigned long long)(ecore_time_get() * 1000.0) & 0xffffffff), NULL);
+ evas_focus_in(ee->evas);
+
return ee;
}
#endif
/* FIXME to do */
/* _ecore_evas_x_modifier_locks_update(ee, e->modifiers); */
evas_event_feed_mouse_in(ee->evas, e->time, NULL);
+ evas_focus_in(ee->evas);
_ecore_evas_mouse_move_process(ee, e->x, e->y, e->time);
return 1;
ee->engine.func->fn_render = _ecore_evas_wince_render;
_ecore_evas_register(ee);
ecore_event_window_register(ee->prop.window, ee, ee->evas, (Ecore_Event_Mouse_Move_Cb)_ecore_evas_mouse_move_process);
+ evas_focus_in(ee->evas);
return ee;
}
#ifdef BUILD_ECORE_EVAS_X11
static int _ecore_evas_init_count = 0;
-static Ecore_Event_Handler *ecore_evas_event_handlers[12];
+static Ecore_Event_Handler *ecore_evas_event_handlers[13];
static void
_ecore_evas_x_protocols_set(Ecore_Evas *ee)
static void
_ecore_evas_x_sync_set(Ecore_Evas *ee)
{
- if (!ee->engine.x.sync_counter)
- ee->engine.x.sync_counter = ecore_x_sync_counter_new(0);
+ if ((ecore_x_e_comp_sync_supported_get(ee->engine.x.win_root)) &&
+ (!ee->no_comp_sync) && (_ecore_evas_app_comp_sync))
+ {
+ if (!ee->engine.x.sync_counter)
+ ee->engine.x.sync_counter = ecore_x_sync_counter_new(0);
+ }
+ else
+ {
+ if (ee->engine.x.sync_counter)
+ ecore_x_sync_counter_free(ee->engine.x.sync_counter);
+ ee->engine.x.sync_counter = 0;
+ }
ecore_x_e_comp_sync_counter_set(ee->prop.window, ee->engine.x.sync_counter);
}
Eina_List *ll;
Ecore_Evas *ee2;
+ if ((!ee->no_comp_sync) && (_ecore_evas_app_comp_sync) &&
+ (ee->engine.x.sync_counter) && (!ee->engine.x.sync_began) &&
+ (!ee->engine.x.sync_cancel))
+ return 0;
+
EINA_LIST_FOREACH(ee->sub_ecore_evas, ll, ee2)
{
if (ee2->func.fn_pre_render) ee2->func.fn_pre_render(ee2);
else
evas_norender(ee->evas);
if (ee->func.fn_post_render) ee->func.fn_post_render(ee);
+/*
+ if (rend)
+ {
+ static int frames = 0;
+ static double t0 = 0.0;
+ double t, td;
+
+ t = ecore_time_get();
+ frames++;
+ if ((t - t0) > 1.0)
+ {
+ td = t - t0;
+ printf("FPS: %3.3f\n", (double)frames / td);
+ frames = 0;
+ t0 = t;
+ }
+ }
+ */
return rend;
}
}
static int
+_ecore_evas_x_event_client_message(void *data __UNUSED__, int type __UNUSED__, void *event)
+{
+ Ecore_Evas *ee;
+ Ecore_X_Event_Client_Message *e;
+
+ e = event;
+ if (e->format != 32) return 1;
+ if (e->message_type == ECORE_X_ATOM_E_COMP_SYNC_BEGIN)
+ {
+ ee = ecore_event_window_match(e->data.l[0]);
+ if (!ee) return 1; /* pass on event */
+ if (e->data.l[0] != ee->prop.window) return;
+ ee->engine.x.sync_began = 1;
+ ee->engine.x.sync_cancel = 0;
+ }
+ else if (e->message_type == ECORE_X_ATOM_E_COMP_SYNC_END)
+ {
+ ee = ecore_event_window_match(e->data.l[0]);
+ if (!ee) return 1; /* pass on event */
+ if (e->data.l[0] != ee->prop.window) return;
+ ee->engine.x.sync_began = 0;
+ ee->engine.x.sync_cancel = 0;
+ }
+ else if (e->message_type == ECORE_X_ATOM_E_COMP_SYNC_CANCEL)
+ {
+ ee = ecore_event_window_match(e->data.l[0]);
+ if (!ee) return 1; /* pass on event */
+ if (e->data.l[0] != ee->prop.window) return;
+ ee->engine.x.sync_began = 0;
+ ee->engine.x.sync_cancel = 1;
+ }
+ return 1;
+}
+
+static int
_ecore_evas_x_event_mouse_in(void *data __UNUSED__, int type __UNUSED__, void *event)
{
Ecore_Evas *ee;
ee = ecore_event_window_match(e->win);
if ((!ee) || (ee->ignore_events)) return 1; /* pass on event */
if (e->win != ee->prop.window) return 1;
+ if (e->mode == ECORE_X_EVENT_MODE_UNGRAB) return 1;
ee->prop.focused = 1;
+ evas_focus_in(ee->evas);
if (ee->func.fn_focus_in) ee->func.fn_focus_in(ee);
return 1;
}
ee = ecore_event_window_match(e->win);
if ((!ee) || (ee->ignore_events)) return 1; /* pass on event */
if (e->win != ee->prop.window) return 1;
- if (ee->prop.fullscreen)
- ecore_x_window_focus(ee->prop.window);
+ if (e->mode == ECORE_X_EVENT_MODE_GRAB) return 1;
+// if (ee->prop.fullscreen)
+// ecore_x_window_focus(ee->prop.window);
+ evas_focus_out(ee->evas);
ee->prop.focused = 0;
if (ee->func.fn_focus_out) ee->func.fn_focus_out(ee);
return 1;
if (!ee) return 1; /* pass on event */
if (e->win != ee->prop.window) return 1;
if (ee->func.fn_destroy) ee->func.fn_destroy(ee);
+ _ecore_evas_x_sync_clear(ee);
ecore_evas_free(ee);
return 1;
}
ecore_evas_event_handlers[9] = ecore_event_handler_add(ECORE_X_EVENT_WINDOW_HIDE, _ecore_evas_x_event_window_hide, NULL);
ecore_evas_event_handlers[10] = ecore_event_handler_add(ECORE_X_EVENT_WINDOW_PROPERTY, _ecore_evas_x_event_property_change, NULL);
ecore_evas_event_handlers[11] = ecore_event_handler_add(ECORE_X_EVENT_WINDOW_VISIBILITY_CHANGE, _ecore_evas_x_event_visibility_change, NULL);
+ ecore_evas_event_handlers[12] = ecore_event_handler_add(ECORE_X_EVENT_CLIENT_MESSAGE, _ecore_evas_x_event_client_message, NULL);
ecore_event_evas_init();
return _ecore_evas_init_count;
}
unsigned int i;
for (i = 0; i < sizeof(ecore_evas_event_handlers) / sizeof(Ecore_Event_Handler*); i++)
- ecore_event_handler_del(ecore_evas_event_handlers[i]);
+ {
+ if (ecore_evas_event_handlers[i])
+ ecore_event_handler_del(ecore_evas_event_handlers[i]);
+ }
ecore_event_evas_shutdown();
}
if (_ecore_evas_init_count < 0) _ecore_evas_init_count = 0;
* ecore_x_init in 2 functions and supress some round trips.
*/
+static void
+_ecore_evas_x_flush_pre(void *data, Evas *e, Evas_Object *obj, void *event_info)
+{
+ Ecore_Evas *ee = data;
+
+ if (ee->no_comp_sync) return;
+ if (!_ecore_evas_app_comp_sync) return;
+ if (ee->engine.x.sync_counter)
+ {
+ if (ee->engine.x.sync_began)
+ {
+ ee->engine.x.sync_val++;
+ if (!ee->engine.x.sync_cancel)
+ ecore_x_sync_counter_val_wait(ee->engine.x.sync_counter,
+ ee->engine.x.sync_val);
+ }
+ }
+}
+
+static void
+_ecore_evas_x_flush_post(void *data, Evas *e, Evas_Object *obj, void *event_info)
+{
+ Ecore_Evas *ee = data;
+
+ if (ee->no_comp_sync) return;
+ if (!_ecore_evas_app_comp_sync) return;
+ if (ee->engine.x.sync_counter)
+ {
+ ecore_x_e_comp_sync_draw_done_send(ee->engine.x.win_root,
+ ee->prop.window);
+ }
+}
+
/**
* To be documented.
*
/* init evas here */
ee->evas = evas_new();
+ evas_event_callback_add(ee->evas, EVAS_CALLBACK_RENDER_FLUSH_PRE, _ecore_evas_x_flush_pre, ee);
+ evas_event_callback_add(ee->evas, EVAS_CALLBACK_RENDER_FLUSH_POST, _ecore_evas_x_flush_post, ee);
evas_data_attach_set(ee->evas, ee);
evas_output_method_set(ee->evas, rmethod);
evas_output_size_set(ee->evas, w, h);
/* init evas here */
ee->evas = evas_new();
+ evas_event_callback_add(ee->evas, EVAS_CALLBACK_RENDER_FLUSH_PRE, _ecore_evas_x_flush_pre, ee);
+ evas_event_callback_add(ee->evas, EVAS_CALLBACK_RENDER_FLUSH_POST, _ecore_evas_x_flush_post, ee);
evas_data_attach_set(ee->evas, ee);
evas_output_method_set(ee->evas, rmethod);
evas_output_size_set(ee->evas, w, h);
/* init evas here */
ee->evas = evas_new();
+ evas_event_callback_add(ee->evas, EVAS_CALLBACK_RENDER_FLUSH_PRE, _ecore_evas_x_flush_pre, ee);
+ evas_event_callback_add(ee->evas, EVAS_CALLBACK_RENDER_FLUSH_POST, _ecore_evas_x_flush_post, ee);
evas_data_attach_set(ee->evas, ee);
evas_output_method_set(ee->evas, rmethod);
evas_output_size_set(ee->evas, w, h);
/* init evas here */
ee->evas = evas_new();
+ evas_event_callback_add(ee->evas, EVAS_CALLBACK_RENDER_FLUSH_PRE, _ecore_evas_x_flush_pre, ee);
+ evas_event_callback_add(ee->evas, EVAS_CALLBACK_RENDER_FLUSH_POST, _ecore_evas_x_flush_post, ee);
evas_data_attach_set(ee->evas, ee);
evas_output_method_set(ee->evas, rmethod);
evas_output_size_set(ee->evas, w, h);
EAPI void ecore_x_e_comp_sync_counter_set(Ecore_X_Window win, Ecore_X_Sync_Counter counter);
EAPI Ecore_X_Sync_Counter ecore_x_e_comp_sync_counter_get(Ecore_X_Window win);
-EAPI void ecore_x_e_comp_sync_draw_done_send(Ecore_X_Window win);
+EAPI void ecore_x_e_comp_sync_draw_done_send(Ecore_X_Window root, Ecore_X_Window win);
EAPI void ecore_x_e_comp_sync_supported_set(Ecore_X_Window root, Eina_Bool enabled);
EAPI Eina_Bool ecore_x_e_comp_sync_supported_get(Ecore_X_Window root);
EAPI void ecore_x_e_comp_sync_begin_send(Ecore_X_Window win);
EAPI void ecore_x_e_comp_sync_end_send(Ecore_X_Window win);
+EAPI void ecore_x_e_comp_sync_cancel_send(Ecore_X_Window win);
EAPI Ecore_X_Sync_Alarm ecore_x_sync_alarm_new(Ecore_X_Sync_Counter counter);
EAPI int ecore_x_sync_alarm_free(Ecore_X_Sync_Alarm alarm);
EAPI int ecore_x_sync_counter_query(Ecore_X_Sync_Counter counter, unsigned int *val);
EAPI Ecore_X_Sync_Counter ecore_x_sync_counter_new(int val);
EAPI void ecore_x_sync_counter_free(Ecore_X_Sync_Counter counter);
-EAPI void ecore_x_sync_counter_inc(Ecore_X_Sync_Counter counter, int val);
-EAPI void ecore_x_sync_counter_inc_wait(Ecore_X_Sync_Counter counter, int val);
+EAPI void ecore_x_sync_counter_inc(Ecore_X_Sync_Counter counter, int by);
+EAPI void ecore_x_sync_counter_val_wait(Ecore_X_Sync_Counter counter, int val);
EAPI void ecore_x_xinerama_query_screens_prefetch(void);
EAPI void ecore_x_xinerama_query_screens_fetch(void);
EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_COMP_SYNC_SUPPORTED;
EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_COMP_SYNC_BEGIN;
EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_COMP_SYNC_END;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_COMP_SYNC_CANCEL;
#endif /* _ECORE_X_ATOMS_H */
EAPI Ecore_X_Atom ECORE_X_ATOM_E_COMP_SYNC_SUPPORTED = 0;
EAPI Ecore_X_Atom ECORE_X_ATOM_E_COMP_SYNC_BEGIN = 0;
EAPI Ecore_X_Atom ECORE_X_ATOM_E_COMP_SYNC_END = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_COMP_SYNC_CANCEL = 0;
FocusChangeMask |
ColormapChangeMask |
VisibilityChangeMask |
- StructureNotifyMask
+ StructureNotifyMask |
+ SubstructureNotifyMask
);
XShapeSelectInput(_ecore_x_disp, win, ShapeNotifyMask);
}
FocusChangeMask |
ColormapChangeMask |
VisibilityChangeMask |
- StructureNotifyMask);
+ StructureNotifyMask |
+ SubstructureNotifyMask);
XShapeSelectInput(_ecore_x_disp, win, ShapeNotifyMask);
}
{ "_E_COMP_SYNC_DRAW_DONE", &ECORE_X_ATOM_E_COMP_SYNC_DRAW_DONE },
{ "_E_COMP_SYNC_SUPPORTED", &ECORE_X_ATOM_E_COMP_SYNC_SUPPORTED },
{ "_E_COMP_SYNC_BEGIN", &ECORE_X_ATOM_E_COMP_SYNC_BEGIN },
- { "_E_COMP_SYNC_END", &ECORE_X_ATOM_E_COMP_SYNC_END }
+ { "_E_COMP_SYNC_END", &ECORE_X_ATOM_E_COMP_SYNC_END },
+ { "_E_COMP_SYNC_CANCEL", &ECORE_X_ATOM_E_COMP_SYNC_CANCEL }
};
Atom *atoms;
char **names;
}
EAPI void
-ecore_x_e_comp_sync_draw_done_send(Ecore_X_Window win)
+ecore_x_e_comp_sync_draw_done_send(Ecore_X_Window root, Ecore_X_Window win)
{
XEvent xev;
+ if (!root) root = DefaultRootWindow(_ecore_x_disp);
xev.xclient.type = ClientMessage;
xev.xclient.display = _ecore_x_disp;
xev.xclient.window = win;
xev.xclient.data.l[3] = 0; // later
xev.xclient.data.l[4] = 0; // later
- XSendEvent(_ecore_x_disp, win, False,
- SubstructureRedirectMask | SubstructureNotifyMask, &xev);
+ XSendEvent(_ecore_x_disp, root, False,
+ SubstructureRedirectMask | SubstructureNotifyMask,
+ &xev);
}
EAPI void
{
Ecore_X_Window win;
+ if (!root) root = DefaultRootWindow(_ecore_x_disp);
if (enabled)
{
win = ecore_x_window_new(root, 1, 2, 3, 4);
Ecore_X_Window win, win2;
int ret;
+ if (!root) root = DefaultRootWindow(_ecore_x_disp);
ret =
ecore_x_window_prop_xid_get(root,
ECORE_X_ATOM_E_COMP_SYNC_SUPPORTED,
xev.xclient.data.l[4] = 0; // later
XSendEvent(_ecore_x_disp, win, False,
- SubstructureRedirectMask | SubstructureNotifyMask, &xev);
+ NoEventMask, //SubstructureRedirectMask | SubstructureNotifyMask,
+ &xev);
}
EAPI void
xev.xclient.data.l[4] = 0; // later
XSendEvent(_ecore_x_disp, win, False,
- SubstructureRedirectMask | SubstructureNotifyMask, &xev);
+ NoEventMask, //SubstructureRedirectMask | SubstructureNotifyMask,
+ &xev);
+}
+
+EAPI void
+ecore_x_e_comp_sync_cancel_send(Ecore_X_Window win)
+{
+ XEvent xev;
+
+ xev.xclient.type = ClientMessage;
+ xev.xclient.display = _ecore_x_disp;
+ xev.xclient.window = win;
+ xev.xclient.message_type = ECORE_X_ATOM_E_COMP_SYNC_CANCEL;
+ xev.xclient.format = 32;
+ xev.xclient.data.l[0] = win;
+ xev.xclient.data.l[1] = 0; // later
+ xev.xclient.data.l[2] = 0; // later
+ xev.xclient.data.l[3] = 0; // later
+ xev.xclient.data.l[4] = 0; // later
+
+ XSendEvent(_ecore_x_disp, win, False,
+ NoEventMask, //SubstructureRedirectMask | SubstructureNotifyMask,
+ &xev);
}
}
EAPI void
-ecore_x_sync_counter_inc(Ecore_X_Sync_Counter counter, int val)
+ecore_x_sync_counter_inc(Ecore_X_Sync_Counter counter, int by)
{
XSyncValue v;
- XSyncIntToValue(&v, val);
+ XSyncIntToValue(&v, by);
XSyncChangeCounter(_ecore_x_disp, counter, v);
}
EAPI void
-ecore_x_sync_counter_inc_wait(Ecore_X_Sync_Counter counter, int val)
+ecore_x_sync_counter_val_wait(Ecore_X_Sync_Counter counter, int val)
{
XSyncWaitCondition cond;
XSyncValue v, v2;
-
+
+ XSyncQueryCounter(_ecore_x_disp, counter, &v);
XSyncIntToValue(&v, val);
- XSyncIntToValue(&v2, val + 2);
+ XSyncIntToValue(&v2, val + 1);
cond.trigger.counter = counter;
- cond.trigger.value_type = XSyncRelative;
+ cond.trigger.value_type = XSyncAbsolute;
cond.trigger.wait_value = v;
- cond.trigger.test_type = XSyncPositiveTransition;
+ cond.trigger.test_type = XSyncPositiveComparison;
cond.event_threshold = v2;
XSyncAwait(_ecore_x_disp, &cond, 1);
XSync(_ecore_x_disp, False);