Put in a first, still wip, version of the python bindings in a merged tree.

This is meant to be the 1.8 version of the wrappers and will include everything
that now is in the python folder.

Atm this include evas, ecore, edje, elementary and emotion (emotion still commented
in the build couse it need some more testing). Eo is used as a base for all the
objects that inherit from it in C, but in real nothing is used from Eo, it is
used more like a container to share code between the libs.

All the docs has been stripped out because we want to use the new sphinx style 
docs that Kay has done in his git repo. (Kay: please wait a little bit to include
it, as working on the libs without docs is much more easy)

The new wrappers include a new container module called efl and thus you can live
with both the old and the new installation. This also means that you need to import
the new modules as:
"from efl import evas" (instead of the old "import evas")
The idea here is that you can make your code works with both version doing
something like:
try:
   import evas
except:
   from efl import evas
...like is done in the gtk bindings

Some stuff has been leaved out on purpose, because was old stuff (like the hacked 
evas rotation stuff) or because was not working as expected (like all the ecore.evas.XXX
modules). See the TODO.txt file for more info. Probably some stuff is out just because I
missed them, let me know if you miss something.

Improvements from the old version:
- Py3 compatible (still some work to be done, but really only TODO, no problems to resolv)
- Should also works on other platforms, like windoz (but not tested)
- Unittests greatly improved, you can also run ALL tests at once
- much more simpler :)


I will contine the works in the next weeks and hope someone will help too.

NOTE: I switched back to setup.py instead of autotools, because that is the right way to
compile python stuff. So to build just use:
 python setup.py install
or
 python3 setup.py install


Enjoy
davemds




SVN revision: 83831
This commit is contained in:
Davide Andreoli 2013-02-11 22:32:50 +00:00
commit 8b86398860
257 changed files with 40748 additions and 0 deletions

10
AUTHORS Normal file
View File

@ -0,0 +1,10 @@
Gustavo Sverzut Barbieri <barbieri@gmail.com>
Ulisses Furquim <ulissesf@gmail.com>
Davide 'DaveMDS' Andreoli <dave@gurumeditation.it>
Fabiano Fidêncio <fidencio@profusion.mobi>
Tiago Falcão <tiago@profusion.mobi>
Simon Busch <morphis@gravedo.de>
Boris 'billiob' Faure <billiob@gmail.com>
Bruno Dilly <bdilly@profusion.mobi>
Joost Albers <joost.albers@nomadrail.com>
Kai Huuhko <kai.huuhko@gmail.com>

165
COPYING Normal file
View File

@ -0,0 +1,165 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
This version of the GNU Lesser General Public License incorporates
the terms and conditions of version 3 of the GNU General Public
License, supplemented by the additional permissions listed below.
0. Additional Definitions.
As used herein, "this License" refers to version 3 of the GNU Lesser
General Public License, and the "GNU GPL" refers to version 3 of the GNU
General Public License.
"The Library" refers to a covered work governed by this License,
other than an Application or a Combined Work as defined below.
An "Application" is any work that makes use of an interface provided
by the Library, but which is not otherwise based on the Library.
Defining a subclass of a class defined by the Library is deemed a mode
of using an interface provided by the Library.
A "Combined Work" is a work produced by combining or linking an
Application with the Library. The particular version of the Library
with which the Combined Work was made is also called the "Linked
Version".
The "Minimal Corresponding Source" for a Combined Work means the
Corresponding Source for the Combined Work, excluding any source code
for portions of the Combined Work that, considered in isolation, are
based on the Application, and not on the Linked Version.
The "Corresponding Application Code" for a Combined Work means the
object code and/or source code for the Application, including any data
and utility programs needed for reproducing the Combined Work from the
Application, but excluding the System Libraries of the Combined Work.
1. Exception to Section 3 of the GNU GPL.
You may convey a covered work under sections 3 and 4 of this License
without being bound by section 3 of the GNU GPL.
2. Conveying Modified Versions.
If you modify a copy of the Library, and, in your modifications, a
facility refers to a function or data to be supplied by an Application
that uses the facility (other than as an argument passed when the
facility is invoked), then you may convey a copy of the modified
version:
a) under this License, provided that you make a good faith effort to
ensure that, in the event an Application does not supply the
function or data, the facility still operates, and performs
whatever part of its purpose remains meaningful, or
b) under the GNU GPL, with none of the additional permissions of
this License applicable to that copy.
3. Object Code Incorporating Material from Library Header Files.
The object code form of an Application may incorporate material from
a header file that is part of the Library. You may convey such object
code under terms of your choice, provided that, if the incorporated
material is not limited to numerical parameters, data structure
layouts and accessors, or small macros, inline functions and templates
(ten or fewer lines in length), you do both of the following:
a) Give prominent notice with each copy of the object code that the
Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the object code with a copy of the GNU GPL and this license
document.
4. Combined Works.
You may convey a Combined Work under terms of your choice that,
taken together, effectively do not restrict modification of the
portions of the Library contained in the Combined Work and reverse
engineering for debugging such modifications, if you also do each of
the following:
a) Give prominent notice with each copy of the Combined Work that
the Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the Combined Work with a copy of the GNU GPL and this license
document.
c) For a Combined Work that displays copyright notices during
execution, include the copyright notice for the Library among
these notices, as well as a reference directing the user to the
copies of the GNU GPL and this license document.
d) Do one of the following:
0) Convey the Minimal Corresponding Source under the terms of this
License, and the Corresponding Application Code in a form
suitable for, and under terms that permit, the user to
recombine or relink the Application with a modified version of
the Linked Version to produce a modified Combined Work, in the
manner specified by section 6 of the GNU GPL for conveying
Corresponding Source.
1) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (a) uses at run time
a copy of the Library already present on the user's computer
system, and (b) will operate properly with a modified version
of the Library that is interface-compatible with the Linked
Version.
e) Provide Installation Information, but only if you would otherwise
be required to provide such information under section 6 of the
GNU GPL, and only to the extent that such information is
necessary to install and execute a modified version of the
Combined Work produced by recombining or relinking the
Application with a modified version of the Linked Version. (If
you use option 4d0, the Installation Information must accompany
the Minimal Corresponding Source and Corresponding Application
Code. If you use option 4d1, you must provide the Installation
Information in the manner specified by section 6 of the GNU GPL
for conveying Corresponding Source.)
5. Combined Libraries.
You may place library facilities that are a work based on the
Library side by side in a single library together with other library
facilities that are not Applications and are not covered by this
License, and convey such a combined library under terms of your
choice, if you do both of the following:
a) Accompany the combined library with a copy of the same work based
on the Library, uncombined with any other library facilities,
conveyed under the terms of this License.
b) Give prominent notice with the combined library that part of it
is a work based on the Library, and explaining where to find the
accompanying uncombined form of the same work.
6. Revised Versions of the GNU Lesser General Public License.
The Free Software Foundation may publish revised and/or new versions
of the GNU Lesser General Public License from time to time. Such new
versions will be similar in spirit to the present version, but may
differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the
Library as you received it specifies that a certain numbered version
of the GNU Lesser General Public License "or any later version"
applies to it, you have the option of following the terms and
conditions either of that published version or of any later version
published by the Free Software Foundation. If the Library as you
received it does not specify a version number of the GNU Lesser
General Public License, you may choose any version of the GNU Lesser
General Public License ever published by the Free Software Foundation.
If the Library as you received it specifies that a proxy can decide
whether future versions of the GNU Lesser General Public License shall
apply, that proxy's public statement of acceptance of any version is
permanent authorization for you to choose that version for the
Library.

59
INSTALL.txt Normal file
View File

@ -0,0 +1,59 @@
1. REQUIREMENTS:
1. Python 2.7 or higher (http://www.python.org/)
- Tested with Python 2.7 / 3.2
2. Cython 0.17.3 or higher (http://cython.org/)
- Tested with Cython 0.17.3
3. EFL core library
- eo, evas, ecore, edje, elementary and, optionally, emotion
4. pkg-config (http://www.freedesktop.org/wiki/Software/pkg-config)
- Windows executable (and GLib dependency) can be downloaded from
http://www.gtk.org/download/win32.php
2. BUILDING EFL
Once EFL is built and installed in your desired destination, proceed with
building the wrapper.
2a. BUILDING WITH GCC/G++ (Linux, OS X, etc.)
python setup.py build_ext
2b. BUILDING WITH Visual Studio (Windows)
python setup.py build_ext
2c. BUILDING WITH MINGW (Windows)
python setup.py build_ext -c mingw32
4. INSTALLATION
4a. For system-wide installation (needs administrator privileges):
python setup.py install
4b. For user installation:
python setup.py install --user
4c. To install for python3:
python3 setup.py install (also cython need to be installed with py3)
5. DEMOS and TESTS
You can run individual tests or use the 00_run_all_tests.py in each folder or
even in the tests/ base dir to run all the tests at once.
The tests in elementary are not unittest and are meant to be run by the user
as they usually require some sort of interaction.

62
TODO.txt Normal file
View File

@ -0,0 +1,62 @@
BUGS:
* Ecore/Evas: 00_run_all_test.py, lots of errors
* Evas: smart object doesn't work
* object_from_instance fail with EdjeExternals
* test_map3.py is buggy
* test_mapbuf.py line 14 should work
* test_progressbar.py on exit cause an endless loop (Timer??)
* test_video.py have problems
* test_menu.py -> evas events cb
* test_naviframe is broken (also in the python-elementary version)
* test_core_evas_canvas_callbacks.py have 2 lines commented out
* test_emotion.py loop on shutdown (parent issue)
* edje.color_class_list() is broken in C (disabled in edje/test_01_basics.py)
* edje.text_class_list() is broken in C (disabled out in edje/test_01_basics.py)
TODO:
* Fix all the compilation warnings!
* ecore.Poller
* ecore.FileMonitor
* alert on signal and subprocess module usage (was in python-ecore/ecore/__init__.py)
* Ecore test_08_exe.py : Use unittests
* evas.SmartObject
* edje.Edit
* edje: complete the unit tests
* elm.Web need a test
* elm.GestureLayer need a test
* elm.PhotoCam need a test
* elm.Transit need a test
* elm.Conformant need a test
* include python-ethumb
* include python-e_dbus (or make edbus2 ??)
TODO FOR PYTHON 3:
* ecore.Exe (use new buffer interface)
* ecore.FdHandler (use new buffer interface)
* edje external
STUFF LEAVED OUT:
* EcoreEvas
* EcoreImf
* EcoreX
* EcoreWin32
* python-evas/evas/utils.py
* python-evas/evas/decorators.py
* python-evas/evas/debug.py
* python-evas old hack to rotate objects
* edje decorators callbacks
CHANGES FROM 1.7 to 1.8:
* added efl container package
* ecore.file.Download => efl.ecore.FileDownload

0
efl/__init__.py Normal file
View File

141
efl/ecore/efl.ecore.pyx Normal file
View File

@ -0,0 +1,141 @@
######################################################################
# Copyright (C) 2007-2013 Gustavo Sverzut Barbieri
#
# This file is part of Python-Ecore.
#
# Python-Ecore is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# Python-Ecore is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this Python-Ecore. If not, see <http://www.gnu.org/licenses/>.
######################################################################
import traceback
from efl.eo cimport Eo
from efl.eo cimport _fruni, _cfruni
from efl.eo cimport PY_REFCOUNT
from cpython cimport Py_INCREF, Py_DECREF
ECORE_CALLBACK_CANCEL = 0
ECORE_CALLBACK_RENEW = 1
# Ecore_Fd_Handler_Flags:
ECORE_FD_READ = 1
ECORE_FD_WRITE = 2
ECORE_FD_ERROR = 4
ECORE_FD_ALL = 7
# Ecore_Exe_Flags:
ECORE_EXE_PIPE_READ = 1
ECORE_EXE_PIPE_WRITE = 2
ECORE_EXE_PIPE_ERROR = 4
ECORE_EXE_PIPE_READ_LINE_BUFFERED = 8
ECORE_EXE_PIPE_ERROR_LINE_BUFFERED = 16
ECORE_EXE_PIPE_AUTO = 32
ECORE_EXE_RESPAWN = 64
ECORE_EXE_USE_SH = 128
ECORE_EXE_NOT_LEADER = 256
ECORE_EXE_TERM_WITH_PARENT = 512
ECORE_EXE_PRIORITY_INHERIT = 9999
# Ecore_File_Progress_Return:
ECORE_FILE_PROGRESS_CONTINUE = 0
ECORE_FILE_PROGRESS_ABORT = 1
cdef Eina_Bool _ecore_task_cb(void *data) with gil:
cdef Eo obj = <Eo>data
cdef Eina_Bool ret
try:
ret = bool(obj._task_exec())
except Exception, e:
traceback.print_exc()
ret = 0
if not ret:
obj.delete()
return ret
cdef int _ecore_events_registered = 0
def init():
global _ecore_events_registered
r = ecore_init()
if r > 0 and _ecore_events_registered == 0:
_ecore_events_registered = 1
global _event_type_mapping
_event_type_mapping = {
ECORE_EVENT_SIGNAL_USER: EventSignalUser,
ECORE_EVENT_SIGNAL_HUP: EventSignalHup,
ECORE_EVENT_SIGNAL_EXIT: EventSignalExit,
ECORE_EVENT_SIGNAL_POWER: EventSignalPower,
ECORE_EVENT_SIGNAL_REALTIME: EventSignalRealtime,
ECORE_EXE_EVENT_ADD: EventExeAdd,
ECORE_EXE_EVENT_DEL: EventExeDel,
ECORE_EXE_EVENT_DATA: EventExeData,
ECORE_EXE_EVENT_ERROR: EventExeData,
}
ecore_file_init()
return r
def shutdown():
ecore_file_shutdown()
return ecore_shutdown()
def main_loop_quit():
ecore_main_loop_quit()
def main_loop_begin():
with nogil:
ecore_main_loop_begin()
def main_loop_iterate():
with nogil:
ecore_main_loop_iterate()
def main_loop_glib_integrate():
if not ecore_main_loop_glib_integrate():
raise SystemError("failed to integrate GLib main loop into ecore.")
def time_get():
return ecore_time_get()
def loop_time_get():
return ecore_loop_time_get()
include "efl.ecore_animator.pxi"
include "efl.ecore_timer.pxi"
include "efl.ecore_idler.pxi"
include "efl.ecore_fd_handler.pxi"
include "efl.ecore_events.pxi"
include "efl.ecore_exe.pxi"
include "efl.ecore_file_download.pxi"
init()

View File

@ -0,0 +1,57 @@
# Copyright (C) 2007-2013 Gustavo Sverzut Barbieri, Ulisses Furquim
#
# This file is part of Python-Ecore.
#
# Python-Ecore is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# Python-Ecore is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this Python-Ecore. If not, see <http://www.gnu.org/licenses/>.
# This file is included verbatim by efl.ecore.pyx
cdef class Animator(Eo):
def __init__(self, func, *args, **kargs):
if not callable(func):
raise TypeError("Parameter 'func' must be callable")
self.func = func
self.args = args
self.kargs = kargs
self._set_obj(ecore_animator_add(_ecore_task_cb, <void *>self))
def __str__(self):
return "%s Animator(func=%s, args=%s, kargs=%s)" % (Eo.__repr__(self),
self.func, self.args, self.kargs)
def __repr__(self):
return "%s Animator(func=%s, args=%s, kargs=%s)" % (Eo.__repr__(self),
self.func, self.args, self.kargs)
cpdef object _task_exec(self):
return self.func(*self.args, **self.kargs)
def delete(self):
ecore_animator_del(self.obj)
def stop(self):
self.delete()
def animator_add(func, *args, **kargs):
return Animator(func, *args, **kargs)
def animator_frametime_set(double frametime):
ecore_animator_frametime_set(frametime)
def animator_frametime_get():
return ecore_animator_frametime_get()

View File

@ -0,0 +1,354 @@
# Copyright (C) 2007-2008 Gustavo Sverzut Barbieri
#
# This file is part of Python-Ecore.
#
# Python-Ecore is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# Python-Ecore is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this Python-Ecore. If not, see <http://www.gnu.org/licenses/>.
# This file is included verbatim by c_ecore.pyx
cdef object _event_type_mapping = dict()
def _event_mapping_register(int type, cls):
if type in _event_type_mapping:
raise ValueError("event type '%d' already registered." % type)
if not issubclass(cls, Event):
raise TypeError("cls (%s) must be subclass of Event" % cls)
_event_type_mapping[type] = cls
def _event_mapping_unregister(int type):
_event_type_mapping.pop(type)
cdef Eina_Bool event_handler_cb(void *data, int type, void *event) with gil:
cdef EventHandler handler
cdef Eina_Bool r
assert event != NULL
assert data != NULL
handler = <EventHandler>data
assert type == handler.type
try:
r = handler._exec(event)
except Exception, e:
traceback.print_exc()
r = 0
if not r:
handler.delete()
return r
cdef class Event(object):
def __init__(self):
if type(self) is Event:
raise TypeError("Must not instantiate Event, but subclasses")
def __str__(self):
attrs = []
for attr in dir(self):
if not attr.startswith("_"):
attrs.append("%s=%r" % (attr, getattr(self, attr)))
return "%s(%s)" % (self.__class__.__name__, ", ".join(attrs))
cdef int _set_obj(self, void *obj) except 0:
raise NotImplementedError("Event._set_obj() not implemented.")
cdef class EventHandler(object):
def __init__(self, int type, func, *args, **kargs):
"@parm: B{type} event type, as registered with ecore_event_type_new()."
if not callable(func):
raise TypeError("Parameter 'func' must be callable")
event_cls = _event_type_mapping.get(type, None)
if event_cls is None:
raise ValueError("Unknow Ecore_Event type %d" % type)
self.type = type
self.event_cls = event_cls
self.func = func
self.args = args
self.kargs = kargs
self._set_obj(ecore_event_handler_add(type, event_handler_cb,
<void *>self))
def __str__(self):
return "%s(type=%d, func=%s, args=%s, kargs=%s, event_cls=%s)" % \
(self.__class__.__name__, self.type,
self.func, self.args, self.kargs, self.event_cls)
def __repr__(self):
return ("%s(%#x, type=%d, func=%s, args=%s, kargs=%s, event_cls=%s, "
"Ecore_Event_Handler=%#x, refcount=%d)") % \
(self.__class__.__name__, <unsigned long><void *>self,
self.type, self.func, self.args, self.kargs, self.event_cls,
<unsigned long>self.obj, PY_REFCOUNT(self))
def __dealloc__(self):
if self.obj != NULL:
ecore_event_handler_del(self.obj)
cdef int _set_obj(self, Ecore_Event_Handler *obj) except 0:
assert self.obj == NULL, "Object must be clean"
assert obj != NULL, "Cannot set NULL as object"
self.obj = obj
Py_INCREF(self)
return 1
cdef int _unset_obj(self) except 0:
if self.obj != NULL:
ecore_event_handler_del(self.obj)
self.obj = NULL
self.event_cls = None
self.func = None
self.args = None
self.kargs = None
Py_DECREF(self)
return 1
cdef Eina_Bool _exec(self, void *event) except 2:
cdef Event e
e = self.event_cls()
e._set_obj(event)
return bool(self.func(e, *self.args, **self.kargs))
def delete(self):
if self.obj != NULL:
self._unset_obj()
def stop(self):
self.delete()
def event_handler_add(int type, func, *args, **kargs):
return EventHandler(type, func, *args, **kargs)
cdef class EventSignalUser(Event):
cdef int _set_obj(self, void *o) except 0:
cdef Ecore_Event_Signal_User *obj
obj = <Ecore_Event_Signal_User*>o
self.number = obj.number
return 1
def __str__(self):
return "%s(number=%d)" % (self.__class__.__name__, self.number)
def __repr__(self):
return "%s(number=%d)" % (self.__class__.__name__, self.number)
cdef class EventSignalUser1(EventSignalUser):
def __str__(self):
return "%s()" % (self.__class__.__name__,)
def __repr__(self):
return "%s()" % (self.__class__.__name__,)
cdef class EventSignalUser2(EventSignalUser):
def __str__(self):
return "%s()" % (self.__class__.__name__,)
def __repr__(self):
return "%s()" % (self.__class__.__name__,)
cdef class EventHandlerSignalUser(EventHandler):
def __init__(self, func, *args, **kargs):
EventHandler.__init__(self, ECORE_EVENT_SIGNAL_USER,
func, *args, **kargs)
cdef Eina_Bool _exec(self, void *event) except 2:
cdef Ecore_Event_Signal_User *obj = <Ecore_Event_Signal_User *>event
cdef EventSignalUser e
if obj.number == 1:
e = EventSignalUser1()
elif obj.number == 2:
e = EventSignalUser2()
else:
e = EventSignalUser()
e._set_obj(event)
return bool(self.func(e, *self.args, **self.kargs))
def on_signal_user(func, *args, **kargs):
return EventHandlerSignalUser(func, *args, **kargs)
cdef class EventSignalHup(Event):
cdef int _set_obj(self, void *o) except 0:
return 1
def __str__(self):
return "%s()" % (self.__class__.__name__,)
def __repr__(self):
return "%s()" % (self.__class__.__name__,)
def on_signal_hup(func, *args, **kargs):
return EventHandler(ECORE_EVENT_SIGNAL_HUP, func, *args, **kargs)
cdef class EventSignalExit(Event):
cdef int _set_obj(self, void *o) except 0:
cdef Ecore_Event_Signal_Exit *obj
obj = <Ecore_Event_Signal_Exit*>o
self.interrupt = bool(obj.interrupt)
self.quit = bool(obj.quit)
self.terminate = bool(obj.terminate)
return 1
def __str__(self):
return "%s(interrupt=%s, quit=%s, terminate=%s)" % \
(self.__class__.__name__, self.interrupt, self.quit, self.terminate)
def __repr__(self):
return "%s(interrupt=%s, quit=%s, terminate=%s)" % \
(self.__class__.__name__, self.interrupt, self.quit, self.terminate)
cdef class EventSignalQuit(EventSignalExit):
def __str__(self):
return "%s()" % (self.__class__.__name__,)
def __repr__(self):
return "%s()" % (self.__class__.__name__,)
cdef class EventSignalInterrupt(EventSignalExit):
def __str__(self):
return "%s()" % (self.__class__.__name__,)
def __repr__(self):
return "%s()" % (self.__class__.__name__,)
cdef class EventSignalTerminate(EventSignalExit):
def __str__(self):
return "%s()" % (self.__class__.__name__,)
def __repr__(self):
return "%s()" % (self.__class__.__name__,)
cdef class EventHandlerSignalExit(EventHandler):
def __init__(self, func, *args, **kargs):
EventHandler.__init__(self, ECORE_EVENT_SIGNAL_EXIT,
func, *args, **kargs)
cdef Eina_Bool _exec(self, void *event) except 2:
cdef Ecore_Event_Signal_Exit *obj = <Ecore_Event_Signal_Exit *>event
cdef EventSignalExit e
if obj.terminate:
e = EventSignalTerminate()
elif obj.interrupt:
e = EventSignalInterrupt()
elif obj.quit:
e = EventSignalQuit()
else:
e = EventSignalExit()
e._set_obj(event)
return bool(self.func(e, *self.args, **self.kargs))
def on_signal_exit(func, *args, **kargs):
return EventHandlerSignalExit(func, *args, **kargs)
cdef class EventSignalPower(Event):
cdef int _set_obj(self, void *o) except 0:
return 1
def __str__(self):
return "%s()" % (self.__class__.__name__,)
def __repr__(self):
return "%s()" % (self.__class__.__name__,)
def on_signal_power(func, *args, **kargs):
return EventHandler(ECORE_EVENT_SIGNAL_POWER, func, *args, **kargs)
cdef class EventSignalRealtime(Event):
cdef int _set_obj(self, void *o) except 0:
cdef Ecore_Event_Signal_Realtime *obj
obj = <Ecore_Event_Signal_Realtime*>o
self.num = obj.num
return 1
def __str__(self):
return "%s(num=%d)" % (self.__class__.__name__, self.num)
def __repr__(self):
return "%s(num=%d)" % (self.__class__.__name__, self.num)
def on_signal_realtime(func, *args, **kargs):
return EventHandler(ECORE_EVENT_SIGNAL_REALTIME, func, *args, **kargs)
cdef class CustomEvent(Event):
cdef int _set_obj(self, void *obj):
self.obj = <object>obj
return 1
def event_type_new(cls):
cdef int type
type = ecore_event_type_new()
_event_mapping_register(type, cls)
return type
cdef void _event_free_cb(void *data, void *event) with gil:
cdef QueuedEvent ev
ev = <QueuedEvent>data
ev._free()
cdef class QueuedEvent(object):
def __init__(self, int type, *args):
self.args = args
self._set_obj(ecore_event_add(type, <void *>self.args, _event_free_cb,
<void*>self))
cdef int _set_obj(self, Ecore_Event *ev):
assert self.obj == NULL, "Object must be clean"
assert ev != NULL, "Cannot set NULL as object"
self.obj = ev
Py_INCREF(self)
return 1
cdef int _unset_obj(self):
if self.obj != NULL:
self.obj = NULL
self.args = None
Py_DECREF(self)
return 1
def _free(self):
self._unset_obj()
def delete(self):
ecore_event_del(self.obj)
def event_add(int type, *args):
return QueuedEvent(type, args)

534
efl/ecore/efl.ecore_exe.pxi Normal file
View File

@ -0,0 +1,534 @@
# Copyright (C) 2010 Gustavo Sverzut Barbieri
#
# This file is part of Python-Ecore.
#
# Python-Ecore is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# Python-Ecore is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this Python-Ecore. If not, see <http://www.gnu.org/licenses/>.
# This file is included verbatim by c_ecore.pyx
# TODO: remove me after usage is update to new buffer api
cdef extern from "Python.h":
int PyObject_AsReadBuffer(obj, void **buffer, Py_ssize_t *buffer_len) except -1
object PyUnicode_FromStringAndSize(char *s, Py_ssize_t len)
cdef exe_flags2str(int value):
flags = []
if value & ECORE_EXE_PIPE_READ:
flags.append("PIPE_READ")
if value & ECORE_EXE_PIPE_WRITE:
flags.append("PIPE_WRITE")
if value & ECORE_EXE_PIPE_ERROR:
flags.append("PIPE_ERROR")
if value & ECORE_EXE_PIPE_READ_LINE_BUFFERED:
flags.append("PIPE_READ_LINE_BUFFERED")
if value & ECORE_EXE_PIPE_ERROR_LINE_BUFFERED:
flags.append("PIPE_ERROR_LINE_BUFFERED")
if value & ECORE_EXE_PIPE_AUTO:
flags.append("PIPE_AUTO")
if value & ECORE_EXE_RESPAWN:
flags.append("RESPAWN")
if value & ECORE_EXE_USE_SH:
flags.append("USE_SH")
if value & ECORE_EXE_NOT_LEADER:
flags.append("NOT_LEADER")
return ", ".join(flags)
cdef Eina_Bool _exe_event_filter_cb(void *data, int type, void *event) with gil:
cdef ExeEventFilter self = <ExeEventFilter>data
cdef Ecore_Exe_Event_Add *e_add
cdef Ecore_Exe_Event_Del *e_del
cdef Ecore_Exe_Event_Data *e_data
cdef Event e
try:
assert self.event_type == type, "event is not what we asked? impossible"
if type == ECORE_EXE_EVENT_ADD:
e_add = <Ecore_Exe_Event_Add *>event
if e_add.exe != self.exe:
return 1
e = EventExeAdd()
elif type == ECORE_EXE_EVENT_DEL:
e_del = <Ecore_Exe_Event_Del *>event
if e_del.exe != self.exe:
return 1
e = EventExeDel()
elif type == ECORE_EXE_EVENT_DATA or type == ECORE_EXE_EVENT_ERROR:
e_data = <Ecore_Exe_Event_Data *>event
if e_data.exe != self.exe:
return 1
e = EventExeData()
else:
raise SystemError("unknown event type=%d" % type)
r = e._set_obj(event)
assert r != -1, "exe is not known?! impossible!"
cb = tuple(self.callbacks) # copy, so we can change self.callbacks
for func, args, kargs in cb:
try:
func(self.owner, e, *args, **kargs)
except:
traceback.print_exc()
except:
traceback.print_exc()
return 1 # always return true, no matter what
cdef class ExeEventFilter:
def __cinit__(self, *a, **ka):
self.exe = NULL
self.handler = NULL
self.owner = None
self.event_type = -1
self.callbacks = []
def __dealloc__(self):
if self.handler != NULL:
ecore_event_handler_del(self.handler)
self.handler = NULL
self.exe = NULL
self.owner = None
self.event_type = None
self.callbacks = None
def __init__(self, Exe exe not None, int event_type):
self.exe = exe.exe
self.owner = exe
self.event_type = event_type
self.callbacks = []
def delete(self):
if self.handler != NULL:
ecore_event_handler_del(self.handler)
self.handler = NULL
self.callbacks = None
def callback_add(self, func, args, kargs):
if self.handler == NULL:
self.handler = ecore_event_handler_add(
self.event_type, _exe_event_filter_cb, <void *>self)
self.callbacks.append((func, args, kargs))
def callback_del(self, func, args, kargs):
try:
self.callbacks.remove((func, args, kargs))
except ValueError, e:
raise ValueError(
"callback is not registered: %s, args=%s, kargs=%s" %
(func, args, kargs))
if self.callbacks:
return
if self.handler != NULL:
ecore_event_handler_del(self.handler)
self.handler = NULL
def exe_run_priority_set(int pri):
ecore_exe_run_priority_set(pri)
def exe_run_priority_get():
return ecore_exe_run_priority_get()
cdef object _ecore_exe_event_mapping
_ecore_exe_event_mapping = {}
cdef void _ecore_exe_pre_free_cb(void *data, const_Ecore_Exe *exe) with gil:
cdef Exe obj
try:
if data == NULL:
raise ValueError("data parameter is NULL")
else:
obj = <Exe>data
obj._unset_obj()
except Exception, e:
traceback.print_exc()
cdef class Exe(object):
def __cinit__(self, *a, **ka):
self.exe = NULL
self.__data = None
self.__callbacks = {}
def __init__(self, exe_cmd, int flags=0, data=None):
if not exe_cmd:
raise ValueError("exe_cmd must not be empty!")
if flags is None:
flags = 0
self._set_obj(_fruni(exe_cmd), flags)
self.__data = data
self.__callbacks = {}
cdef int _set_obj(self, char *exe_cmd, int flags) except 0:
cdef Ecore_Exe *exe
assert self.exe == NULL, "Exe must be clean, not wrapping any Ecore_Exe"
exe = ecore_exe_pipe_run(exe_cmd, <Ecore_Exe_Flags>flags, <void *>self)
if exe == NULL:
raise SystemError("could not run subprocess %r, flags=%#x" %
(exe_cmd, flags))
Py_INCREF(self)
self.exe = exe
ecore_exe_callback_pre_free_set(exe, _ecore_exe_pre_free_cb)
_ecore_exe_event_mapping[<long><void *>exe] = self
return 1
cdef int _unset_obj(self) except 0:
assert self.exe != NULL, "Exe must wrap something"
for t, filter in self.__callbacks.iteritems():
filter.delete()
self.__callbacks = None
_ecore_exe_event_mapping.pop(<long><void *>self.exe)
self.exe = NULL
Py_DECREF(self)
return 1
def __str__(self):
if self.exe == NULL:
pid = None
cmd = None
flags = ""
data = None
else:
pid = self.pid
cmd = self.cmd
flags = exe_flags2str(self.flags)
data = None
return "%s(pid=%s, cmd=%r, flags=[%s], data=%r)" % \
(self.__class__.__name__, pid, cmd, flags, data)
def __repr__(self):
if self.exe == NULL:
pid = None
cmd = None
flags = ""
data = None
else:
pid = self.pid
cmd = self.cmd
flags = exe_flags2str(self.flags)
data = None
return ("%s(%#x, Ecore_Exe=%#x, refcount=%d, pid=%s, cmd=%r, "
"flags=[%s], data=%r)") % \
(self.__class__.__name__, <unsigned long><void *>self,
<unsigned long>self.exe, PY_REFCOUNT(self),
pid, cmd, flags, data)
def delete(self):
if self.exe == NULL:
raise ValueError("%s already deleted" % self.__class__.__name__)
ecore_exe_free(self.exe)
def free(self):
self.delete()
def send(self, buffer, long size=0):
cdef const_void *b_data
cdef Py_ssize_t b_size
# TODO: update to new buffer api
PyObject_AsReadBuffer(buffer, &b_data, &b_size)
if size <= 0:
size = b_size
elif size > b_size:
raise ValueError(
"given size (%d) is larger than buffer size (%d)." %
(size, b_size))
return bool(ecore_exe_send(self.exe, b_data, size))
def close_stdin(self):
ecore_exe_close_stdin(self.exe)
def auto_limits_set(self, int start_bytes, int end_bytes,
int start_lines, int end_lines):
ecore_exe_auto_limits_set(self.exe, start_bytes, end_bytes,
start_lines, end_lines)
def event_data_get(self, int flags):
pass
# TODO:
#Ecore_Exe_Event_Data *ecore_exe_event_data_get(Ecore_Exe *exe, Ecore_Exe_Flags flags)
#void ecore_exe_event_data_free(Ecore_Exe_Event_Data *data)
def cmd_get(self):
cdef const_char_ptr cmd = ecore_exe_cmd_get(self.exe)
if cmd != NULL:
return cmd
return None
property cmd:
def __get__(self):
return self.cmd_get()
def pid_get(self):
return ecore_exe_pid_get(self.exe)
property pid:
def __get__(self):
return self.pid_get()
def tag_set(self, char *tag):
cdef char *s
if tag is None:
s = NULL
else:
s = tag
ecore_exe_tag_set(self.exe, s)
def tag_get(self):
cdef const_char_ptr tag = ecore_exe_tag_get(self.exe)
if tag != NULL:
return tag
return None
property tag:
def __set__(self, char *tag):
self.tag_set(tag)
def __get__(self):
return self.tag_get()
def data_get(self):
return self.__data
property data:
def __get__(self):
return self.data_get()
def flags_get(self):
return ecore_exe_flags_get(self.exe)
property flags:
def __get__(self):
return self.flags_get()
def signal(self, int num):
if num != 1 or num != 2:
raise ValueError("num must be either 1 or 2. Got %d." % num)
ecore_exe_signal(self.exe, num)
def pause(self):
ecore_exe_pause(self.exe)
def stop(self):
self.pause()
def continue_(self):
ecore_exe_continue(self.exe)
def resume(self):
self.continue_()
def interrupt(self):
ecore_exe_interrupt(self.exe)
def quit(self):
ecore_exe_quit(self.exe)
def terminate(self):
ecore_exe_terminate(self.exe)
def kill(self):
ecore_exe_kill(self.exe)
def hup(self):
ecore_exe_hup(self.exe)
def on_add_event_add(self, func, *args, **kargs):
filter = self.__callbacks.get(ECORE_EXE_EVENT_ADD)
if filter is None:
filter = ExeEventFilter(self, ECORE_EXE_EVENT_ADD)
self.__callbacks[ECORE_EXE_EVENT_ADD] = filter
filter.callback_add(func, args, kargs)
def on_add_event_del(self, func, *args, **kargs):
filter = self.__callbacks.get(ECORE_EXE_EVENT_ADD)
if filter is None:
raise ValueError("callback not registered %s, args=%s, kargs=%s" %
(func, args, kargs))
filter.callback_del(func, args, kargs)
def on_del_event_add(self, func, *args, **kargs):
filter = self.__callbacks.get(ECORE_EXE_EVENT_DEL)
if filter is None:
filter = ExeEventFilter(self, ECORE_EXE_EVENT_DEL)
self.__callbacks[ECORE_EXE_EVENT_DEL] = filter
filter.callback_add(func, args, kargs)
def on_del_event_del(self, func, *args, **kargs):
filter = self.__callbacks.get(ECORE_EXE_EVENT_DEL)
if filter is None:
raise ValueError("callback not registered %s, args=%s, kargs=%s" %
(func, args, kargs))
filter.callback_del(func, args, kargs)
def on_data_event_add(self, func, *args, **kargs):
filter = self.__callbacks.get(ECORE_EXE_EVENT_DATA)
if filter is None:
filter = ExeEventFilter(self, ECORE_EXE_EVENT_DATA)
self.__callbacks[ECORE_EXE_EVENT_DATA] = filter
filter.callback_add(func, args, kargs)
def on_data_event_del(self, func, *args, **kargs):
filter = self.__callbacks.get(ECORE_EXE_EVENT_DATA)
if filter is None:
raise ValueError("callback not registered %s, args=%s, kargs=%s" %
(func, args, kargs))
filter.callback_del(func, args, kargs)
def on_error_event_add(self, func, *args, **kargs):
filter = self.__callbacks.get(ECORE_EXE_EVENT_ERROR)
if filter is None:
filter = ExeEventFilter(self, ECORE_EXE_EVENT_ERROR)
self.__callbacks[ECORE_EXE_EVENT_ERROR] = filter
filter.callback_add(func, args, kargs)
def on_error_event_del(self, func, *args, **kargs):
filter = self.__callbacks.get(ECORE_EXE_EVENT_ERROR)
if filter is None:
raise ValueError("callback not registered %s, args=%s, kargs=%s" %
(func, args, kargs))
filter.callback_del(func, args, kargs)
def exe_run(char *exe_cmd, data=None):
return Exe(exe_cmd, data=data)
def exe_pipe_run(char *exe_cmd, int flags=0, data=None):
return Exe(exe_cmd, flags, data)
cdef class EventExeAdd(Event):
cdef int _set_obj(self, void *o) except 0:
cdef Ecore_Exe_Event_Add *obj
obj = <Ecore_Exe_Event_Add*>o
self.exe = _ecore_exe_event_mapping.get(<long>obj.exe)
if self.exe is None:
return -1
return 1
def __str__(self):
return "%s(exe=%s)" % (self.__class__.__name__, self.exe)
def __repr__(self):
return "%s(exe=%r)" % (self.__class__.__name__, self.exe)
cdef class EventExeDel(Event):
cdef int _set_obj(self, void *o) except 0:
cdef Ecore_Exe_Event_Del *obj
obj = <Ecore_Exe_Event_Del*>o
self.exe = _ecore_exe_event_mapping.get(<long>obj.exe)
if self.exe is None:
return -1
self.pid = obj.pid
self.exit_code = obj.exit_code
self.exit_signal = obj.exit_signal
self.exited = bool(obj.exited)
self.signalled = bool(obj.signalled)
return 1
def __str__(self):
return ("%s(pid=%s, exit_code=%s, exit_signal=%s, exited=%s, "
"signalled=%s, exe=%s)") % \
(self.__class__.__name__, self.pid, self.exit_code,
self.exit_signal, self.exited, self.signalled, self.exe)
def __repr__(self):
return ("%s(pid=%s, exit_code=%s, exit_signal=%s, exited=%s, "
"signalled=%s, exe=%r)") % \
(self.__class__.__name__, self.pid, self.exit_code,
self.exit_signal, self.exited, self.signalled, self.exe)
cdef class EventExeData(Event):
cdef int _set_obj(self, void *o) except 0:
cdef Ecore_Exe_Event_Data *obj
cdef int i
obj = <Ecore_Exe_Event_Data*>o
self.exe = _ecore_exe_event_mapping.get(<long>obj.exe)
if self.exe is None:
return -1
self.data = PyUnicode_FromStringAndSize(<char*>obj.data, obj.size)
self.size = obj.size
self.lines = []
line_append = self.lines.append
if obj.lines:
i = 0
while obj.lines[i].line != NULL:
line_append(PyUnicode_FromStringAndSize(
obj.lines[i].line, obj.lines[i].size))
i += 1
return 1
def __str__(self):
if self.lines is None:
count = None
else:
count = len(self.lines)
return "%s(size=%d, lines=#%d, exe=%s)" % \
(self.__class__.__name__, self.size, count, self.exe)
def __repr__(self):
if self.lines is None:
count = None
else:
count = len(self.lines)
return "%s(size=%d, lines=#%d, exe=%r)" % \
(self.__class__.__name__, self.size, count, self.exe)
cdef class EventHandlerExe(EventHandler):
cdef Eina_Bool _exec(self, void *event) except 2:
cdef Event e
e = self.event_cls()
if e._set_obj(event) == -1: # no exe
return True
return bool(self.func(e, *self.args, **self.kargs))
def on_exe_add_event_add(func, *args, **kargs):
return EventHandlerExe(ECORE_EXE_EVENT_ADD, func, *args, **kargs)
def on_exe_del_event_add(func, *args, **kargs):
return EventHandlerExe(ECORE_EXE_EVENT_DEL, func, *args, **kargs)
def on_exe_data_event_add(func, *args, **kargs):
return EventHandlerExe(ECORE_EXE_EVENT_DATA, func, *args, **kargs)
def on_exe_error_event_add(func, *args, **kargs):
return EventHandlerExe(ECORE_EXE_EVENT_ERROR, func, *args, **kargs)

View File

@ -0,0 +1,164 @@
# Copyright (C) 2007-2008 Gustavo Sverzut Barbieri, Ulisses Furquim
#
# This file is part of Python-Ecore.
#
# Python-Ecore is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# Python-Ecore is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this Python-Ecore. If not, see <http://www.gnu.org/licenses/>.
# This file is included verbatim by c_ecore.pyx
cdef void fd_handler_prepare_cb(void *data, Ecore_Fd_Handler *fdh) with gil:
cdef FdHandler obj = <FdHandler>data
cdef int r
if obj._prepare_callback is None:
return
func, args, kargs = obj._prepare_callback
try:
func(obj, *args, **kargs)
except Exception, e:
traceback.print_exc()
cdef flags2str(int value):
flags = []
if value & <int>ECORE_FD_READ:
flags.append("READ")
if value & <int>ECORE_FD_WRITE:
flags.append("WRITE")
if value & <int>ECORE_FD_ERROR:
flags.append("ERROR")
return ", ".join(flags)
cdef Eina_Bool fd_handler_cb(void *data, Ecore_Fd_Handler *fdh) with gil:
cdef FdHandler obj = <FdHandler>data
cdef Eina_Bool r
try:
r = bool(obj._exec())
except Exception, e:
traceback.print_exc()
r = 0
if not r:
obj.delete()
return r
cdef class FdHandler(object):
def __init__(self, fd, int flags, func, *args, **kargs):
if not callable(func):
raise TypeError("Parameter 'func' must be callable")
self.func = func
self.args = args
self.kargs = kargs
self._prepare_callback = None
if self.obj == NULL:
if not isinstance(fd, (int, long)):
try:
fd = fd.fileno()
except AttributeError, e:
raise ValueError("fd must be integer or have fileno()")
self.obj = ecore_main_fd_handler_add(fd,
<Ecore_Fd_Handler_Flags>flags,
fd_handler_cb, <void *>self,
NULL, NULL)
if self.obj != NULL:
Py_INCREF(self)
def __str__(self):
if self.obj == NULL:
fd = None
flags = ""
else:
fd = self.fd_get()
flags = flags2str(self.active_get(7))
return "%s(func=%s, args=%s, kargs=%s, fd=%s, flags=[%s])" % \
(self.__class__.__name__, self.func, self.args, self.kargs,
fd, flags)
def __repr__(self):
if self.obj == NULL:
fd = None
flags = ""
else:
fd = self.fd_get()
flags = flags2str(self.active_get(7))
return ("%s(%#x, func=%s, args=%s, kargs=%s, fd=%s, flags=[%s], "
"Ecore_Fd_Handler=%#x, refcount=%d)") % \
(self.__class__.__name__, <unsigned long><void *>self,
self.func, self.args, self.kargs, fd, flags,
<unsigned long>self.obj, PY_REFCOUNT(self))
def __dealloc__(self):
if self.obj != NULL:
ecore_main_fd_handler_del(self.obj)
self.obj = NULL
self.func = None
self.args = None
self.kargs = None
cdef object _exec(self):
return self.func(self, *self.args, **self.kargs)
def delete(self):
if self.obj != NULL:
ecore_main_fd_handler_del(self.obj)
self.obj = NULL
Py_DECREF(self)
def stop(self):
self.delete()
def fd_get(self):
return ecore_main_fd_handler_fd_get(self.obj)
property fd:
def __get__(self):
return self.fd_get()
def active_get(self, int flags):
cdef Ecore_Fd_Handler_Flags v = <Ecore_Fd_Handler_Flags>flags
return bool(ecore_main_fd_handler_active_get(self.obj, v))
def active_set(self, int flags):
cdef Ecore_Fd_Handler_Flags v = <Ecore_Fd_Handler_Flags>flags
ecore_main_fd_handler_active_set(self.obj, v)
def can_read(self):
return bool(ecore_main_fd_handler_active_get(self.obj, ECORE_FD_READ))
def can_write(self):
return bool(ecore_main_fd_handler_active_get(self.obj, ECORE_FD_WRITE))
def has_error(self):
return bool(ecore_main_fd_handler_active_get(self.obj, ECORE_FD_ERROR))