From 242e7b03d24b6df25772e87bef1d73d6bce8d1e1 Mon Sep 17 00:00:00 2001
From: Florent Berthaut <florent@hitmuri.net>
Date: Thu, 15 Dec 2016 14:04:13 +0100
Subject: [PATCH] Transfered files from private repo

---
 COPYING                                       |  674 +++++++
 data/Info.plist                               |   27 +
 data/controllar.icns                          |  Bin 0 -> 40371 bytes
 data/controllar.xml                           |    8 +
 data/controllar128.png                        |  Bin 0 -> 9998 bytes
 data/controllar16.png                         |  Bin 0 -> 884 bytes
 data/controllar256.png                        |  Bin 0 -> 20518 bytes
 data/controllar32.png                         |  Bin 0 -> 2097 bytes
 data/controllar48.png                         |  Bin 0 -> 3478 bytes
 data/controllar512.png                        |  Bin 0 -> 41500 bytes
 data/vjpirate.desktop                         |   12 +
 example.car                                   |    7 +
 src/Controlar.cpp                             | 1664 +++++++++++++++++
 src/Controlar.hpp                             |  372 ++++
 src/CutWindow.hpp                             |   86 +
 src/CutWindowsManager.hpp                     |   58 +
 src/FlipGroup.cpp                             |   96 +
 src/FlipGroup.hpp                             |   49 +
 src/FlipMenu.cpp                              |  377 ++++
 src/FlipMenu.hpp                              |   99 +
 src/GroupWidget.cpp                           |  203 ++
 src/GroupWidget.hpp                           |   74 +
 src/MainPanel.cpp                             |  138 ++
 src/MainPanel.hpp                             |   85 +
 src/ZonePanel.cpp                             |  282 +++
 src/ZonePanel.hpp                             |  124 ++
 src/ZoneWidget.cpp                            | 1077 +++++++++++
 src/ZoneWidget.hpp                            |  195 ++
 src/mac/MacWindow.cpp                         |  172 ++
 src/mac/MacWindow.hpp                         |   62 +
 src/mac/MacWindowsManager.cpp                 |   89 +
 src/mac/MacWindowsManager.hpp                 |   42 +
 src/osc/ip/IpEndpointName.cpp                 |   81 +
 src/osc/ip/IpEndpointName.h                   |   74 +
 src/osc/ip/NetworkingUtils.h                  |   49 +
 src/osc/ip/PacketListener.h                   |   43 +
 src/osc/ip/TimerListener.h                    |   40 +
 src/osc/ip/UdpSocket.h                        |  158 ++
 src/osc/ip/posix/NetworkingUtils.cpp          |   57 +
 src/osc/ip/posix/UdpSocket.cpp                |  546 ++++++
 src/osc/osc/MessageMappingOscPacketListener.h |   73 +
 src/osc/osc/OscException.h                    |   54 +
 src/osc/osc/OscHostEndianness.h               |   70 +
 src/osc/osc/OscOutboundPacketStream.cpp       |  639 +++++++
 src/osc/osc/OscOutboundPacketStream.h         |  142 ++
 src/osc/osc/OscPacketListener.h               |   72 +
 src/osc/osc/OscPrintReceivedElements.cpp      |  241 +++
 src/osc/osc/OscPrintReceivedElements.h        |   49 +
 src/osc/osc/OscReceivedElements.cpp           |  722 +++++++
 src/osc/osc/OscReceivedElements.h             |  486 +++++
 src/osc/osc/OscTypes.cpp                      |   40 +
 src/osc/osc/OscTypes.h                        |  178 ++
 src/win/WinWindow.cpp                         |  122 ++
 src/win/WinWindow.hpp                         |   53 +
 src/win/WinWindowsManager.cpp                 |   75 +
 src/win/WinWindowsManager.hpp                 |   42 +
 src/x11/XWindow.cpp                           |  154 ++
 src/x11/XWindow.hpp                           |   62 +
 src/x11/XWindowsManager.cpp                   |   93 +
 src/x11/XWindowsManager.hpp                   |   49 +
 waf                                           |  Bin 0 -> 87674 bytes
 wscript                                       |   93 +
 62 files changed, 10629 insertions(+)
 create mode 100644 COPYING
 create mode 100644 data/Info.plist
 create mode 100644 data/controllar.icns
 create mode 100755 data/controllar.xml
 create mode 100644 data/controllar128.png
 create mode 100644 data/controllar16.png
 create mode 100644 data/controllar256.png
 create mode 100644 data/controllar32.png
 create mode 100644 data/controllar48.png
 create mode 100644 data/controllar512.png
 create mode 100755 data/vjpirate.desktop
 create mode 100644 example.car
 create mode 100755 src/Controlar.cpp
 create mode 100755 src/Controlar.hpp
 create mode 100644 src/CutWindow.hpp
 create mode 100644 src/CutWindowsManager.hpp
 create mode 100644 src/FlipGroup.cpp
 create mode 100644 src/FlipGroup.hpp
 create mode 100644 src/FlipMenu.cpp
 create mode 100644 src/FlipMenu.hpp
 create mode 100644 src/GroupWidget.cpp
 create mode 100644 src/GroupWidget.hpp
 create mode 100644 src/MainPanel.cpp
 create mode 100644 src/MainPanel.hpp
 create mode 100644 src/ZonePanel.cpp
 create mode 100644 src/ZonePanel.hpp
 create mode 100644 src/ZoneWidget.cpp
 create mode 100644 src/ZoneWidget.hpp
 create mode 100644 src/mac/MacWindow.cpp
 create mode 100644 src/mac/MacWindow.hpp
 create mode 100644 src/mac/MacWindowsManager.cpp
 create mode 100644 src/mac/MacWindowsManager.hpp
 create mode 100755 src/osc/ip/IpEndpointName.cpp
 create mode 100755 src/osc/ip/IpEndpointName.h
 create mode 100755 src/osc/ip/NetworkingUtils.h
 create mode 100755 src/osc/ip/PacketListener.h
 create mode 100755 src/osc/ip/TimerListener.h
 create mode 100755 src/osc/ip/UdpSocket.h
 create mode 100755 src/osc/ip/posix/NetworkingUtils.cpp
 create mode 100755 src/osc/ip/posix/UdpSocket.cpp
 create mode 100755 src/osc/osc/MessageMappingOscPacketListener.h
 create mode 100755 src/osc/osc/OscException.h
 create mode 100755 src/osc/osc/OscHostEndianness.h
 create mode 100755 src/osc/osc/OscOutboundPacketStream.cpp
 create mode 100755 src/osc/osc/OscOutboundPacketStream.h
 create mode 100755 src/osc/osc/OscPacketListener.h
 create mode 100755 src/osc/osc/OscPrintReceivedElements.cpp
 create mode 100755 src/osc/osc/OscPrintReceivedElements.h
 create mode 100755 src/osc/osc/OscReceivedElements.cpp
 create mode 100755 src/osc/osc/OscReceivedElements.h
 create mode 100755 src/osc/osc/OscTypes.cpp
 create mode 100755 src/osc/osc/OscTypes.h
 create mode 100644 src/win/WinWindow.cpp
 create mode 100644 src/win/WinWindow.hpp
 create mode 100644 src/win/WinWindowsManager.cpp
 create mode 100644 src/win/WinWindowsManager.hpp
 create mode 100644 src/x11/XWindow.cpp
 create mode 100644 src/x11/XWindow.hpp
 create mode 100644 src/x11/XWindowsManager.cpp
 create mode 100644 src/x11/XWindowsManager.hpp
 create mode 100755 waf
 create mode 100755 wscript

diff --git a/COPYING b/COPYING
new file mode 100644
index 0000000..94a9ed0
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,674 @@
+                    GNU 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.
+
+                            Preamble
+
+  The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+  The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works.  By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users.  We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors.  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+  To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights.  Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received.  You must make sure that they, too, receive
+or can get the source code.  And you must show them these terms so they
+know their rights.
+
+  Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+  For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software.  For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+  Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so.  This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software.  The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable.  Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products.  If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+  Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary.  To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                       TERMS AND CONDITIONS
+
+  0. Definitions.
+
+  "This License" refers to version 3 of the GNU General Public License.
+
+  "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+  "The Program" refers to any copyrightable work licensed under this
+License.  Each licensee is addressed as "you".  "Licensees" and
+"recipients" may be individuals or organizations.
+
+  To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy.  The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+  A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+  To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy.  Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+  To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies.  Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+  An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License.  If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+  1. Source Code.
+
+  The "source code" for a work means the preferred form of the work
+for making modifications to it.  "Object code" means any non-source
+form of a work.
+
+  A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+  The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form.  A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+  The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities.  However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work.  For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+  The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+  The Corresponding Source for a work in source code form is that
+same work.
+
+  2. Basic Permissions.
+
+  All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met.  This License explicitly affirms your unlimited
+permission to run the unmodified Program.  The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work.  This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+  You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force.  You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright.  Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+  Conveying under any other circumstances is permitted solely under
+the conditions stated below.  Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+  No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+  When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+  4. Conveying Verbatim Copies.
+
+  You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+  You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+  5. Conveying Modified Source Versions.
+
+  You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+    a) The work must carry prominent notices stating that you modified
+    it, and giving a relevant date.
+
+    b) The work must carry prominent notices stating that it is
+    released under this License and any conditions added under section
+    7.  This requirement modifies the requirement in section 4 to
+    "keep intact all notices".
+
+    c) You must license the entire work, as a whole, under this
+    License to anyone who comes into possession of a copy.  This
+    License will therefore apply, along with any applicable section 7
+    additional terms, to the whole of the work, and all its parts,
+    regardless of how they are packaged.  This License gives no
+    permission to license the work in any other way, but it does not
+    invalidate such permission if you have separately received it.
+
+    d) If the work has interactive user interfaces, each must display
+    Appropriate Legal Notices; however, if the Program has interactive
+    interfaces that do not display Appropriate Legal Notices, your
+    work need not make them do so.
+
+  A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit.  Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+  6. Conveying Non-Source Forms.
+
+  You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+    a) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by the
+    Corresponding Source fixed on a durable physical medium
+    customarily used for software interchange.
+
+    b) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by a
+    written offer, valid for at least three years and valid for as
+    long as you offer spare parts or customer support for that product
+    model, to give anyone who possesses the object code either (1) a
+    copy of the Corresponding Source for all the software in the
+    product that is covered by this License, on a durable physical
+    medium customarily used for software interchange, for a price no
+    more than your reasonable cost of physically performing this
+    conveying of source, or (2) access to copy the
+    Corresponding Source from a network server at no charge.
+
+    c) Convey individual copies of the object code with a copy of the
+    written offer to provide the Corresponding Source.  This
+    alternative is allowed only occasionally and noncommercially, and
+    only if you received the object code with such an offer, in accord
+    with subsection 6b.
+
+    d) Convey the object code by offering access from a designated
+    place (gratis or for a charge), and offer equivalent access to the
+    Corresponding Source in the same way through the same place at no
+    further charge.  You need not require recipients to copy the
+    Corresponding Source along with the object code.  If the place to
+    copy the object code is a network server, the Corresponding Source
+    may be on a different server (operated by you or a third party)
+    that supports equivalent copying facilities, provided you maintain
+    clear directions next to the object code saying where to find the
+    Corresponding Source.  Regardless of what server hosts the
+    Corresponding Source, you remain obligated to ensure that it is
+    available for as long as needed to satisfy these requirements.
+
+    e) Convey the object code using peer-to-peer transmission, provided
+    you inform other peers where the object code and Corresponding
+    Source of the work are being offered to the general public at no
+    charge under subsection 6d.
+
+  A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+  A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling.  In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage.  For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product.  A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+  "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source.  The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+  If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information.  But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+  The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed.  Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+  Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+  7. Additional Terms.
+
+  "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law.  If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+  When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it.  (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.)  You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+  Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+    a) Disclaiming warranty or limiting liability differently from the
+    terms of sections 15 and 16 of this License; or
+
+    b) Requiring preservation of specified reasonable legal notices or
+    author attributions in that material or in the Appropriate Legal
+    Notices displayed by works containing it; or
+
+    c) Prohibiting misrepresentation of the origin of that material, or
+    requiring that modified versions of such material be marked in
+    reasonable ways as different from the original version; or
+
+    d) Limiting the use for publicity purposes of names of licensors or
+    authors of the material; or
+
+    e) Declining to grant rights under trademark law for use of some
+    trade names, trademarks, or service marks; or
+
+    f) Requiring indemnification of licensors and authors of that
+    material by anyone who conveys the material (or modified versions of
+    it) with contractual assumptions of liability to the recipient, for
+    any liability that these contractual assumptions directly impose on
+    those licensors and authors.
+
+  All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10.  If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term.  If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+  If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+  Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+  8. Termination.
+
+  You may not propagate or modify a covered work except as expressly
+provided under this License.  Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+  However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+  Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+  Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License.  If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+  9. Acceptance Not Required for Having Copies.
+
+  You are not required to accept this License in order to receive or
+run a copy of the Program.  Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance.  However,
+nothing other than this License grants you permission to propagate or
+modify any covered work.  These actions infringe copyright if you do
+not accept this License.  Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+  10. Automatic Licensing of Downstream Recipients.
+
+  Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License.  You are not responsible
+for enforcing compliance by third parties with this License.
+
+  An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations.  If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+  You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License.  For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+  11. Patents.
+
+  A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based.  The
+work thus licensed is called the contributor's "contributor version".
+
+  A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version.  For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+  Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+  In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement).  To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+  If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients.  "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+  If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+  A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License.  You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+  Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+  12. No Surrender of Others' Freedom.
+
+  If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all.  For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+  13. Use with the GNU Affero General Public License.
+
+  Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work.  The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+  14. Revised Versions of this License.
+
+  The Free Software Foundation may publish revised and/or new versions of
+the GNU 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
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation.  If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+  If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+  Later license versions may give you additional or different
+permissions.  However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+  15. Disclaimer of Warranty.
+
+  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. Limitation of Liability.
+
+  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+  17. Interpretation of Sections 15 and 16.
+
+  If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program 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 General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+  If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+    <program>  Copyright (C) <year>  <name of author>
+    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+  You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<http://www.gnu.org/licenses/>.
+
+  The GNU General Public License does not permit incorporating your program
+into proprietary programs.  If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.  But first, please read
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
diff --git a/data/Info.plist b/data/Info.plist
new file mode 100644
index 0000000..5331787
--- /dev/null
+++ b/data/Info.plist
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+    <key>CFBundleDevelopmentRegion</key>
+    <string>English</string>
+    <key>CFBundleExecutable</key>
+    <string>controllar</string>
+    <key>CFBundleIconFile</key>
+    <string>controllar.icns</string>
+    <key>CFBundleIdentifier</key>
+    <string>net.hitmuri.www</string>
+    <key>CFBundleInfoDictionaryVersion</key>
+    <string>6.0</string>
+    <key>CFBundleName</key>
+    <string>ControllAR</string>
+    <key>CFBundlePackageType</key>
+    <string>APPL</string>
+    <key>CFBundleShortVersionString</key>
+    <string>0.0.1</string>
+    <key>LSMinimumSystemVersion</key>
+    <string>10.4</string>
+    <key>CFBundleVersion</key>
+    <string>1</string>
+</dict>
+</plist>
+
diff --git a/data/controllar.icns b/data/controllar.icns
new file mode 100644
index 0000000000000000000000000000000000000000..a75da2a2869f74f7ca265973366d9e165cf6df81
GIT binary patch
literal 40371
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
a|7>%EuLuq`G!^Eb@@8j?Kgtw4Ui$z!_a0FI

literal 0
HcmV?d00001

diff --git a/data/controllar.xml b/data/controllar.xml
new file mode 100755
index 0000000..0991c65
--- /dev/null
+++ b/data/controllar.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<mime-info xmlns="http://www.freedesktop.org/standards/shared-mime-info">
+        <mime-type type="application/x-vjpirate-file">
+		<comment>VjPirate file</comment>
+		<glob pattern="*.vjp"/>
+		<generic-icon name="vjp"/>
+	</mime-type>
+</mime-info>
diff --git a/data/controllar128.png b/data/controllar128.png
new file mode 100644
index 0000000000000000000000000000000000000000..5006ce7874f071fb4f9c6a7fc39539a2040b01a3
GIT binary patch
literal 9998
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
Gp$P!E96>Gs

literal 0
HcmV?d00001

diff --git a/data/controllar16.png b/data/controllar16.png
new file mode 100644
index 0000000000000000000000000000000000000000..a8c0ddfcdf01122b8ba178b115486c8f718bcc53
GIT binary patch
literal 884
zcmeAS@N?(olHy`uVBq!ia0y~yU=RRd4mJh`2Kmqb6B!s7Sc;uILpV4%IBGajIv5xj
zI14-?iy0W$nn9S6b<?Ly3=9mCC9V-A!TD(=<%vb94CUqJdYO6I#mR{Use1WE>9gP2
zNHH)lee`s346*1fopjb;IaTKP{?BKOYnNRvvzn`Wp)0lg_=!9P?Uhnr8#+5VJLP)3
z4pbPvI6GVAAEQdu$Aq5gy^3->DlSUs$CX`lNxeQ@Bjsk^u}v%y36+{tjK1V9JHN+f
zp2D@M?|**(U9*3`_)Fi5RlLtn+}Kqfcwejk(zlNtBCcA3jdC-lyV=(!Ub0)e@c;E0
zv420W+PCpf-i!8C$CplCToo}{qIk1r;?D=MTVokCc|0F(Uw?nH|D2??Yjao^K5~^^
z$1q`*^={jnt8M#d%w^;#&wTe=-~QXu86mGX{AN%%G(l!+xW2ml`S3ljHcGb6{19{C
zz}kGf4=qjXr=?d_W-2^0mEt@l;U6t7e=O*vS!!1Mi7y-f3vn<!nU=Rl<yKt%<^H#^
z6`wvmJ8UmD-%-SK<Cc3#RhPUsZ7`o7Uc|*IH?vXb-K8V{e%-EaKbZD8!T$QK)nA^@
zm)&`JU5Kw5yPKNm)4L`2`LC|odO~|G&+n}&rElN<y&WH0{{G(VI}tJ7uKU)XFl_y9
z_xH-Co3od2ni_oX|B}1^+KxxX>#oSQr*12cUL_EpG3(pKH*ePH*H(P~9CUW#tGL6$
z=WeAb7Tn!oH^F|xx|B1r_v#-%SigI6_UhHQRzCiyzx|_2eSLL7K|#CWHzP&I3&Jgv
zp6_0F%IB}j_n3`S-g+PNU-G1BOYx6mC$?tKTBMOau~i@<GV)^1?QMq)YUXlqFfwFC
z<uf&KFj-FQ)9me%_^~_WQts_zU%r^MwYBY<7QQwt_5Szxr7j%0s@rw;U+!D2rfT@?
zrN}0^%wJ4Pzx*uP+4J>lX-|KDvtgTj{XSNP71v)g82D74s&K!m<mvjX=Ul4N6Knp8
zr0VZee|vjNGVJ(wnTbK+Qw&4Hy4MOV7P0C-x2vhCJ(_aq?a!Y-x##*V|6R#(@WzcB
z3lk+4f2w4-y{$QE<BpujYu)?aAD2D8aFdSm?6XM~6+1E|j-?kD7vG;d`$0%>aIn_%
wKf(<8oQiymf7WH*I_tFX!`m}we7^8|>v@>EJ`xaPU|?YIboFyt=akR{0G3Ft4gdfE

literal 0
HcmV?d00001

diff --git a/data/controllar256.png b/data/controllar256.png
new file mode 100644
index 0000000000000000000000000000000000000000..c4c8373e05e7e56d58d8cea0c1738283792b7f27
GIT binary patch
literal 20518
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
XTAt~MUe?LLz`)??>gTe~DWM4f{%QLx

literal 0
HcmV?d00001

diff --git a/data/controllar32.png b/data/controllar32.png
new file mode 100644
index 0000000000000000000000000000000000000000..cda0544d56cdabf242d4fd643f7ad4493018da79
GIT binary patch
literal 2097
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
bpYe(01j_)8Ro@vH7#KWV{an^LB{Ts5WbEx<

literal 0
HcmV?d00001

diff --git a/data/controllar48.png b/data/controllar48.png
new file mode 100644
index 0000000000000000000000000000000000000000..ac1febf8d339a5e5a83f9fb1ef10fdf0faef3b84
GIT binary patch
literal 3478
zcmeAS@N?(olHy`uVBq!ia0y~yU@!n-4mJh`hH$2z?F<YIEX7WqAsieW95oy%9SjT%
zoCO|{#S9F>T_DVOr{vT^1_lPn64!{5;QX|b^2DN4hVt@qz0ADq;^f4FRK5J7^x5xh
zq!<`@g*{yyLoyooMn>nv9IyPB_UumC_cwE&6jchU#<@;i<UMnm>V2&P8OmGw0@Mq8
zr8Z9L$m`<Tn#fYcF=0_a@{^;XTH<TDPcKbT;CGc3)lAsx*1W(q^rV@x*Oj9}M@2Qe
zPFqjE6Z@{U`rDhGKJqh`Y8H7;oHFHoXLZ`Y`hEG&=Fj{uKPmr1tMd<C$7_?i%1th*
zEK4p;vJ+qAX6KWu>|mk3Ay=Jo#yid5Cr_sD`}|${tEP?Lp(C3zKD=8R`^x7_W}x@>
z;Nbgg4eQbm=S1H+Bhl~LkpCrZuKlm4*O#<D`Mg2*{He0pllP<wpWV`#R=B8G;Iyuo
zl;eqI$E#A9EF84*|K=~R&U!I>&4R6Z`I{|bPe_-X+YqUhzi~>cVDi$v(Pq*Iel8QW
z5n>emD{gHg{P%uZ+r5ZCY0XczHd)Lxj#!g$@y@4zD<5WT-M%mHQDD#C0H!N9A8xv^
zmb+f<$)(?2_j$U{rt>P!x*W;W@*${f+B)wImW;Z0_ethNI((g4%pSY(;(Nh7ZH9zf
zI&;r;AD(qmh@qjh$+2WL_sx|r7evX<yZ!2iYfe<dq+aXQ>;60sEL8kz!*HWv=H;c;
zE1OLC&V`@Xc%Jgq%Yy0Ol`Bj4@oimYwC|c$uE=Y-Oznk!ye--G_P;MH{cQ4lym8HD
z^`+g(swZ#H@u?}?nf&zGl}DcIXI`JX^5Mi+Yjf^Az43u-3h%dfJon!I70fw(*zt#x
zqlBO66OA{eY7>O~80K}{S<C$<M<!Bb{s)~iXQnYbBz=h6Jn!VHz61rv{(NsIGnEBO
zmp0!vFL`OfA!wl<<~4bLj6oz*#fMj`L#JN;*my9^cIqcCKX<>6RhL9}N5Aih{j)W`
zZ1u{n`*&>_7!)l3Mf6>KaA9fK{SQ<3E46U2o;~nojp31+b4T3fWPfaF?>Mt$QA9w^
zy~=v;<SjRz-HtO(dQw`sxg|X5uI&Tq*Xw!t;(lcx%55zcdFT2lc=7Z+(^NIJ)7LjW
zTz2r1^5dx=Z<m)DcpBZk8oK%3TT|s_b@q|vp`ksUO+Rn2SX|=Vy6FF*evapU=Mv9l
z_GM?)9?s3r4J~<hx^df=6A=|ld)JB|`FOtCdTYud`JCK+>N~H>F#IUXng3wg*>}=6
z6vZ`?uN~&nkaUt!xVm?~jB=PFPlNjBPiLDvH!}!i<nD84IoQL`vn}i7lJoZ?<fq2y
z>59torY}#L`t<GoV(*WYo4;EwX_@{$Z|~+JnVavuZN(T(_s;(#c-dH%VZzm=if0Ah
zbywC0|CJD(F}34P?#Z)fS~-_adr<IX)wi;k#hbQhoo8fF;#i#)&B?Y&X{#*LR?!<~
zl`1Faq$>qIoh5C}qciWbrn8iG>8*<LE51U9-uyT)H}=l9nL;1bt|{%85!yW0@8TMP
znW6$K-zqMVI2OH|FN|}A#E(b6TW%XYH<&!js6ptvFhjxRl%GGB_;dbv{^{h;gtDSt
zRu@9#mrmMJm0aXEXOn1%>SDho+sb+MWTxmwOcC3rqj07E-^rvGDO{H(oa~ItIej$k
z@1n~S*%^+pXqRbU;%R9AUUug~n()0FUuVBv`J&>+{Sf<Yca|$f$n~$;-qEvr`i!7y
zCUfqcuFQYorWav3X=TQYEvoID3@mTVKFmGKy<nQ_oyW}gnHf$i-Slys6(wi2=<-tE
zFEO`H`$jKV6v5E2X|69b!vhWeC5Qaq?=&iYTD5!0uA+4X8h#w=aW`)~oOE{ABi7WD
z=b~qxYO9}r`=`(Rqf0`on=&c`J@j*4<wXbu)cyW*`HapLrUO@8)a>l7W0iNua<@$j
z-|}P6{m5tj9bL%_C&YfZ)utHeXb=;+u;OA|(dwPA{?4s64&Q%A)kDPe_LW?r&3_*>
z=yptAIcpn#^6q)Ncez~Kv_e2~&BA11UK7jv9^zZrCY?9mF!Scjb?er>pKn+DYrmON
zgGl$UxAXV>FW;14{-V<O{{Pn(Qxs<hTW()5Q{N)twg|%vl~;3$59!WsY|^%?x4Ck$
zY_>s~xNOkvDYZ#y>kq4TG6V!L@0Y57_4<EK|M_1>UsMQps?YK;yY2GT$@b0BkQ&Py
zS9o6d@G$&q75LQr?%lhY>|7suW7hM3{eRz+q2mirVwnk_XX#SL0~buxx4#LU9s99T
z=-%6{i(5LUEw-7!#K3i~X<beGksN;Z9bsYRX<nH-6yx7iw%_=+>Xrn9&t(_0*{*7n
z8<%BrM9VPNX3DE`D%!7Ex$>o5-Jcz?r{>i(>&vYA{pRs|t(7-Uo2eg*=!x-jKkj_<
zWyFnBuls`Be1uAuY0TPuM*h2b{nYy`bE{S>%}8W85&Fi$^x8l6{UP<=KHgWFpU=Q>
zd)vgbY128<jU=CZ{`tG+`8ys(o~Cc#$~X=^+EaMWUcKed&zF~%=dXLB6mVK8NbRQ$
z!wa=;PQFO)H#t(AZ*rtg9!>lE^5RJ?-HAH-ZGsF1x6?M{uKH2C^3E5Z1Cf$mD<%nQ
zO*&ugykFvV&CB59`semWsmOP_7?_)fZ_0__J7?MU?%vTOM_8<^tOA0AnVn7;GyLk4
zvHWz|NA2_D&FSZ}yeI#>^U%KLq^bF*;|vq@I-HmJPG9Cyvh!0`=+iaZmt`HgV$x}l
z7TMbLW{t+|KyB@`qRk%{L|#yxeta#vZJM-V!m=k461D%XPJZ*uVQ$6eZ~Pn%$r~k(
z9XsZAA(mHpUc*G6LngjGy}gPveHN`*!?Q@k$mvA!CY}E;C;Qt~E?&PrpM`-%Rqie?
zgUpdDzF|h@3pb^#c-SSGo~n_UQtXvhv#6-fVwZD?m3U0!g*`nb!m56q%wc;f-`huu
zEr@$n&E2rzwN+btySd9g5jAynLu2FSZQIODOideuqVjKl^JlQ(W(Ya8>=wfTgUqha
zm%eIl*U5?$V`c~}ea37(+bxUV=Jw;ef!52;t2f8(mtkOV=KXX2&$e$X9^2RbT$}X5
z$ItJOiM(F+HXZKk>*J4a&A!gS&@#a`f8Wn#JPcDri@q`}h%PyM#=zPzRBu<ztyAy&
zK5hCbJNK-oV*<;Z<W)t_)erSX-+uYz%Y24z^)uG*_cULRtLB}wWu^GxNi*io)%~|J
zW7aiB1}4V%J9AjR%Le~+xg`63|K+4-rR}-1niik2kKUI3e8Gc~7pH$~p5b9^SZVS5
z^X+o~9d+N<zn^r!rB8ul!IVcA7COIp^XACP;N=3HF57ez=K38r;OSVzaqedwgYBE0
z`Tzg%b3XSvnAG{S+M&RLD{Dp4G|!}Yv(=b2a$?1OeJ7`Gw`O;8IIz;)Fp7im>Yvc(
zJ*N-9HJSO#mO(;B=Ez*@@`8VVDnr7;7A;-M%FZX_pdjE-U;lqrV(6VC*@_}uj-jCp
z9`SptzP{O|sybEm@aDZ`UYtKBJ=`m6{ztbruspYP&5uQDhVK@&7&AnC2)~~eY<!<d
zY`T?P{28N3Csq9BSTugWSIvJjM@)a;4<)~OHl63ro$K}gYjozU?%vk7%w`|-j`&WV
zS+y{Qq5Di36N7q7diJcvF+%DL2Mofdv)bC)T9mz!(2Lo@u>XF4^6|chZ@1rXyZtuq
zYPqe5I-A2=>HIx`pB)%~hD61#zOmrSG{%PDX+|<~b601vFzmT^NwZ#S>Y?B7_xG3I
zuND7TA@lp&+ryp0>K_hq>*shmd^CD8=Y9OCLXk99R(HoI+kACTFG`D>zP3qG$h+9`
zbgGuFPxZ<JI)`SsYHnS5Kxd|qxPya(DZ>V)eT-86G9?x=2|Wild0l@~TU#q3A#vdK
z`u%;(?0gSiTwELwDmuUJ*GpzriMB=`HRk@~%nb3I0yE!=&wLyI>g5#16AV`#O`mj9
zg5kyn@y~zX-d1|_z(8YZK&a@-E4NIm^`;+Q8NB?%&Gh*Xr-sKJY~>c0^Vru>VG}2^
z!G8nmQ=^A9#f>|JrYz$);<<TWX4jH)XNAwz>fLq7$-3(!!BCKz#TH)o^}hH1wXLnC
zzlEK;o-i)>wooq2`{9X+%Fj6z^?m*P9z8nR-G9qADk|#35n+D@1`fsbIj>5qntw1c
zG#z}PT>hqP_r+`1!v6d$EHD4Q-`0$Ala9Fl9Cs!sj(JtDG!2e1B>0IO-QM8)uRcLJ
zKxC<S11H17538;p*Im4Gr(|ksDg%SliTIii2iXl75?)8;GVa~Gx7D`#+a4YT8NT+1
zWxEZ{&A$got~~zu;J?4W9W_}MpFF>N_pZI(HrqY{rUpHR>5K`tx8+(?d{B7x`t|lF
z8I>;z&LvMv{rmLOH}`!^3<Y0bU441%*fHa-MMoHIPD@N)y=s*JSL*~1l?AVVG1oFQ
zoPO$*ovodfoz2KF<<k3kmc`FLeX{HSBN5wqxSc=Td(s#FIiIID9zA3y)VW~){{Q=C
zM+J(oFfso4TgTGu_~UQgiBIAAG5a~^hKK*Ef5X)E;?=8PRt@zm8+aKu-PBohQDaY>
zK2syZ9KUo=Yp0H5miu#Ve>1oL^<weO(6{|lzjDdgR)t(G{hQCQr}dKmZ?%SKhAPYF
z(<PGkUcGwNykFja-!sk+(V_t^;o;%z&;N)h9%*;ow6|qK+_4*1`R)H0e0N|!{o((s
YggdEhIhT?c7#J8lUHx3vIVCg!0O1CgQ2+n{

literal 0
HcmV?d00001

diff --git a/data/controllar512.png b/data/controllar512.png
new file mode 100644
index 0000000000000000000000000000000000000000..773cc2ec98f7f9d74359886586d4dfd4f5372d00
GIT binary patch
literal 41500
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

literal 0
HcmV?d00001

diff --git a/data/vjpirate.desktop b/data/vjpirate.desktop
new file mode 100755
index 0000000..65995b5
--- /dev/null
+++ b/data/vjpirate.desktop
@@ -0,0 +1,12 @@
+[Desktop Entry]
+Name=ControllAR
+Comment=Remixing visual feedback 
+Icon=controllar
+Type=Application
+Exec=controllar %f
+FilePattern=controllar;
+Terminal=false
+StartupNotify=false
+Categories=Audio;AudioVideo;Application;
+GenericName=ControllAR
+MimeType=application/x-controllar-file
diff --git a/example.car b/example.car
new file mode 100644
index 0000000..07bb594
--- /dev/null
+++ b/example.car
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ControllAR>
+  <Scene/>
+  <Zone win_name="pipeline.tex - QtikZ" win_x="70" win_y="67" win_w="87" win_h="83" zone_x="159" zone_y="94" zone_w="491" zone_h="434" alpha="255" transform="1" shape="1" effect="0" midi_type="0" midi_channel="32" midi_control="32752" color="0" visible="-1" update="-1" content="0"/>
+  <Zone win_name="xfce4-panel" win_x="0" win_y="0" win_w="241" win_h="36" zone_x="11" zone_y="54" zone_w="241" zone_h="194" alpha="255" transform="0" shape="0" effect="0" midi_type="0" midi_channel="16777216" midi_control="21848" color="0" visible="-1" update="-1" content="0"/>
+  <Midi device="" set_channel="0" set_type="0" set_control="0"/>
+</ControllAR>
diff --git a/src/Controlar.cpp b/src/Controlar.cpp
new file mode 100755
index 0000000..c3aae16
--- /dev/null
+++ b/src/Controlar.cpp
@@ -0,0 +1,1664 @@
+/***************************************************************************
+ *  Controlar.cpp
+ *  Part of ControllAR
+ *  2016-  Florent Berthaut
+ *  hitmuri.net
+ ****************************************************************************/
+/*
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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 General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "Controlar.hpp"
+
+#include <iostream>
+#include <sstream>
+#include <stdio.h>
+#include <inttypes.h>
+#include <unistd.h>
+#include <portmidi.h>
+#include <porttime.h>
+#include <FL/fl_ask.H>
+#include <FL/Fl.H>
+#include "osc/osc/OscReceivedElements.h"
+#include "osc/osc/OscOutboundPacketStream.h"
+#include "MainPanel.hpp"
+#include "ZonePanel.hpp"
+
+#ifdef OSX
+    #include "mac/MacWindowsManager.hpp"
+#else 
+    #ifdef WINDOWS
+        #include "win/WinWindowsManager.hpp"
+    #else 
+        #include "x11/XWindowsManager.hpp"
+    #endif
+#endif
+
+using namespace std;
+
+void idleFunc(void* data) {
+    Controlar::getInstance()->update();
+    usleep(10000);    
+}
+ 
+void* oscThreadFunction(void* pvParam) {
+    Controlar::getInstance()->m_socket->Run();
+    return 0;
+}
+
+#ifdef GL
+Controlar::Controlar(): Fl_Gl_Window(800, 600, "ControllAR") {
+#else 
+Controlar::Controlar(): Fl_Double_Window(800, 600, "ControllAR") {
+#endif
+    Fl::set_color(FL_BACKGROUND_COLOR, 200, 200, 200);
+    Fl::set_color(FL_BACKGROUND2_COLOR, 150, 150, 150);
+    Fl::set_color(FL_SELECTION_COLOR, 250, 250, 250);
+    box(FL_FLAT_BOX);
+    end();
+
+    m_drawing=false;
+    m_flipped=false;
+    m_fullscreen=false;
+    m_duplicating=false;
+    m_midiLearning=false;
+    m_askedScene=-1;
+    m_displayScale=1;
+
+    m_alphaLevels[0] = 65;
+    m_alphaLevels[1] = 125;
+    m_alphaLevels[2] = 190;
+    m_alphaLevels[3] = 255;
+    for(int i=0;i<10;++i) {
+        m_menuValues[i]=i;
+    }
+
+    //add a first set
+    //m_currentSet=0;
+    //m_zonesSets.push_back(map<unsigned int, ZoneWidget*>());
+    m_scenes[0]="scene";
+    m_currentScene=0;
+
+    //create menus
+    m_zoneMenu = new FlipMenu();
+    m_zoneMenu->hide();
+    m_zoneMenu->end();
+    add(m_zoneMenu);
+    m_mainMenu = new FlipMenu();
+    m_mainMenu->end();
+    m_mainMenu->hide();
+    add(m_mainMenu);
+    m_mainMenu->addWithSub("File/Open", statOpen, this);
+    m_mainMenu->addWithSub("File/Save", statSave, this);
+    m_mainMenu->addWithSub("File/Save As", statSaveAs, this);
+    m_mainMenu->addWithSub("View/FullScreen", statFullscreen, this);
+    m_mainMenu->addWithSub("View/Mirror", statFlip, this);
+    m_mainMenu->addWithSub("Scenes/Next", statSceneNext, this);
+    m_mainMenu->addWithSub("Scenes/Prev", statScenePrev, this);
+    m_mainMenu->addWithSub("Scenes/Delete", statSceneDel, this);
+    m_mainMenu->addWithSub("Scenes/Learn Input", statSceneLearn, this);
+    m_mainMenu->addSub("Midi Input");
+    m_mainMenu->add("Quit", statQuit, this);
+
+    m_mainPanel = MainPanel::getInstance();
+    //add(m_mainPanel);
+    m_mainPanel->hide();
+    m_zonePanel= ZonePanel::getInstance();
+    //add(m_zonePanel);
+    m_zonePanel->hide();
+
+    //initialize main loop function
+    Fl::add_idle(idleFunc, NULL);
+
+    //create windows manager and get display scale if needed
+    #ifdef OSX
+        m_winsMan = new MacWindowsManager();
+    #else
+        #ifdef WINDOWS
+            m_winsMan = new WinWindowsManager();
+        #else
+            m_winsMan = new XWindowsManager();
+        #endif
+    #endif
+    
+    updateTitle();
+
+    //initialise midi
+    m_midiStream=NULL;
+    Pm_Initialize();
+    detectMidiDevices();
+    Pt_Start(1, NULL, NULL);
+
+    //initialize osc 
+    try { 
+        m_socket = new UdpListeningReceiveSocket(
+                            IpEndpointName(IpEndpointName::ANY_ADDRESS, 8327),
+                            this);
+        pthread_mutex_init(&m_zonesMutex, NULL);
+        pthread_create(&m_oscThread, NULL, oscThreadFunction , this);   
+    }
+    catch(const exception& e) {
+        DEBUG("Error in the OscManager "<<e.what());
+    }
+}
+
+void Controlar::refreshWindowList() {
+    //recreate windows list
+    m_winsMan->updateWindowsList();
+
+    //clean all zones and reassign windows
+    map<unsigned int, ZoneWidget*>::iterator itZo = m_zones.begin();
+    for(; itZo!=m_zones.end(); ++itZo) {
+        itZo->second->refreshCutWin();
+    }
+
+    //rebuild zone menu
+    m_zoneMenu->clear();
+    vector<CutWindow*>::iterator itWin = m_winsMan->editWindowList().begin();
+    for(; itWin!=m_winsMan->editWindowList().end(); ++itWin) {
+        m_zoneMenu->addWithSub((string("Select/")+(*itWin)->getName()).c_str(), 
+                                statZoneSelect, (*itWin));
+    }
+    m_zonePanel->setWindowList(m_winsMan->editWindowList());
+
+
+    m_zoneMenu->addWithSub("Alpha/Opaque", statZoneAlpha, &m_alphaLevels[3]);
+    m_zoneMenu->addWithSub("Alpha/Mostly Opaque", 
+                           statZoneAlpha, &m_alphaLevels[2]);
+    m_zoneMenu->addWithSub("Alpha/Half Transparent",  
+                           statZoneAlpha, &m_alphaLevels[1]);
+    m_zoneMenu->addWithSub("Alpha/Mostly Transparent",
+                           statZoneAlpha, &m_alphaLevels[0]);
+    m_zoneMenu->addWithSub("Transform/No Rotation",
+                       statZoneTrans, &m_menuValues[ZoneWidget::NONE]);
+    m_zoneMenu->addWithSub("Transform/Rotate 90",
+                       statZoneTrans, &m_menuValues[ZoneWidget::ROTATE_90]);
+    m_zoneMenu->addWithSub("Transform/Rotate 180",
+                       statZoneTrans, &m_menuValues[ZoneWidget::ROTATE_180]);
+    m_zoneMenu->addWithSub("Transform/Rotate 270",
+                       statZoneTrans, &m_menuValues[ZoneWidget::ROTATE_270]);
+    m_zoneMenu->addWithSub("Shape/Box",
+                           statZoneShape, &m_menuValues[ZoneWidget::BOX]);
+    m_zoneMenu->addWithSub("Shape/Circle",
+                           statZoneShape, &m_menuValues[ZoneWidget::CIRCLE]);
+    m_zoneMenu->addWithSub("Shape/Frame",
+                           statZoneShape, &m_menuValues[ZoneWidget::FRAME]);
+    m_zoneMenu->addWithSub("Color/Normal",
+                           statZoneCol, &m_menuValues[ZoneWidget::NORMAL]);
+    m_zoneMenu->addWithSub("Color/Inverse",
+                           statZoneCol, &m_menuValues[ZoneWidget::INVERT]);
+    m_zoneMenu->addWithSub("Visible/All Scenes",
+                           statZoneVisible, 
+                           &m_menuValues[ZoneWidget::VISIBLE_ALL]);
+    m_zoneMenu->addWithSub("Visible/Current Scene Only",
+                           statZoneVisible, 
+                           &m_menuValues[ZoneWidget::VISIBLE_CURRENT]);
+    m_zoneMenu->addWithSub("Update/All Scenes",
+                           statZoneUpdate, 
+                           &m_menuValues[ZoneWidget::UPDATE_ALL]);
+    m_zoneMenu->addWithSub("Update/Current Scene Only",
+                           statZoneUpdate, 
+                           &m_menuValues[ZoneWidget::UPDATE_CURRENT]);
+    m_zoneMenu->addWithSub("Content/Global",
+                           statZoneContent, 
+                           &m_menuValues[ZoneWidget::CONTENT_GLOBAL]);
+    m_zoneMenu->addWithSub("Content/Local",
+                           statZoneContent, 
+                           &m_menuValues[ZoneWidget::CONTENT_LOCAL]);
+    m_zoneMenu->addWithSub("MIDI Input/Learn",
+                           statZoneMidiLearn, this);
+    m_zoneMenu->addWithSub("MIDI Input/No effect",
+                   statZoneMidiEffect, &m_menuValues[ZoneWidget::NO_EFFECT]);
+    m_zoneMenu->addWithSub("MIDI Input/Show",
+                   statZoneMidiEffect, &m_menuValues[ZoneWidget::SHOW]);
+    m_zoneMenu->addWithSub("MIDI Input/Hide",
+                   statZoneMidiEffect, &m_menuValues[ZoneWidget::HIDE]);
+
+    m_zoneMenu->add("Clear", statZoneClear, this);
+    m_zoneMenu->add("Delete", statZoneDelete, this);
+
+    m_mainMenu->hide();
+    m_zoneMenu->hide();
+}
+
+void Controlar::update() {
+    Controlar::getInstance()->damage(FL_DAMAGE_USER1);
+    parseMidi();
+}
+
+
+void Controlar::parseMidi() {
+    PmEvent buffer[10];
+    vector<PortMidiStream*>::iterator itSt = m_midiStreamsVec.begin();
+    for(; itSt!=m_midiStreamsVec.end();++itSt) {
+        int nb = Pm_Read((*itSt), buffer, 10);
+        for(int i=0;i<nb;++i) {
+            long status = Pm_MessageStatus(buffer[i].message);
+            int msgType = status >> 4;
+            int msgChannel = (status & 15) + 1;
+            int control = Pm_MessageData1(buffer[i].message);
+            int value = Pm_MessageData2(buffer[i].message);
+            if(m_midiLearning) {
+                m_midiType = msgType;
+                m_midiChannel = msgChannel;
+                m_midiControl = control;
+                m_midiLearning=false;
+            }
+            if(msgType==m_midiType 
+                    && msgChannel==m_midiChannel 
+                    && control==m_midiControl) {
+                setScene(value);
+            } 
+            map<unsigned int, ZoneWidget*>::iterator itZo = m_zones.begin();
+            for(; itZo!=m_zones.end(); ++itZo) {
+                itZo->second->processMidi(msgType, msgChannel, 
+                                          control, value);
+            }
+        }
+    }
+}
+
+void Controlar::openMidiDevice(const std::string& devName) {
+    map<string, int>::iterator itDev=m_midiDevMap.find(devName);
+    if(itDev!=m_midiDevMap.end()) {
+        if(m_midiStreamsMap.find(devName)!=m_midiStreamsMap.end()) {
+            Pm_Close(m_midiStreamsMap[devName]);
+        }
+        m_midiStreamsMap[devName]=NULL;
+        Pm_OpenInput(&m_midiStreamsMap[devName], 
+                     itDev->second, NULL, 100, NULL, NULL);
+    }
+    refreshMidiStreams();
+}
+
+void Controlar::closeMidiDevice(const std::string& devName) {
+    map<string, PortMidiStream*>::iterator itSt=m_midiStreamsMap.find(devName);
+    if(itSt!=m_midiStreamsMap.end()) {
+        Pm_Close(itSt->second);
+        m_midiStreamsMap.erase(devName);
+    }
+    refreshMidiStreams();
+}
+
+void Controlar::refreshMidiStreams() {
+    m_midiStreamsVec.clear();
+    map<string, PortMidiStream*>::iterator itSt=m_midiStreamsMap.begin();
+    for(; itSt!=m_midiStreamsMap.end(); ++itSt) {
+        m_midiStreamsVec.push_back(itSt->second);
+    }
+}
+
+void Controlar::detectMidiDevices() {
+
+    Pm_Terminate();
+    Pm_Initialize();
+    int nbDevices = Pm_CountDevices();
+/*
+    FlipMenu* midiMenu = m_mainMenu->getSub("Midi Input");
+    midiMenu->clear();
+    m_midiDevices.clear();
+    m_midiDeviceNames.clear();
+    m_midiStreamsMap.clear();
+*/
+    vector<bool> devOps;
+    vector<string> devNames;
+    for(int i=0; i<nbDevices; ++i) {
+        const PmDeviceInfo* info = Pm_GetDeviceInfo(i);
+        if(info->input>0) {
+            string devName = string(info->name);
+/*
+            m_midiDevices.push_back(i);
+            m_midiDeviceNames.push_back(devName);
+            midiMenu->add(devName, statMidiDev, &m_midiDevices.back());
+*/
+            m_midiDevMap[devName]=i;
+            devNames.push_back(devName);
+            if(m_midiStreamsMap.find(devName)!=m_midiStreamsMap.end()) {
+                openMidiDevice(devName);
+                devOps.push_back(true);
+            }
+            else {
+                devOps.push_back(false);
+            }
+        }
+    }
+    m_mainPanel->setMidiDevices(devNames, devOps);
+/*
+    if(m_currentMidiDeviceName.compare("")!=0) {
+        setMidiDeviceFromName(m_currentMidiDeviceName);
+    }
+*/
+}
+
+ZoneWidget* Controlar::startDuplicating(ZoneWidget* dupWid) {
+    m_duplicatedZone = new ZoneWidget();
+    m_duplicatedZone->copy(dupWid);
+    addZone(m_duplicatedZone);
+    m_duplicatedZone->forceDraggingZone();
+    return m_duplicatedZone;
+}
+
+int Controlar::handle(int event) {
+    int res=0;
+    if(!m_drawing) {
+        res=Fl_Group::handle(event);
+    }
+    if(res>0) {
+        redraw();
+    }
+    else {
+        switch(event) {
+            case FL_KEYDOWN: {
+                if(Fl::event_command()) {
+                    switch(Fl::event_key()) {
+                        case 'o': cbOpen(); break;
+                        case 's': cbSave(); break;
+                        case 'f': cbFullscreen(); break;
+                        case 'm': cbFlip(); break;
+                        case 'q': cbQuit(); break;
+                        default:break;
+                    }
+                    res=1;
+                }
+            }break; 
+            case FL_PUSH: 
+                if(m_duplicating) {
+                    m_duplicating=false;
+                }
+                switch(Fl::event_button()) {
+                    case FL_LEFT_MOUSE: {
+                        m_drawStartX=Fl::event_x();
+                        m_drawStartY=Fl::event_y();
+                        m_drawCurX=Fl::event_x();
+                        m_drawCurY=Fl::event_y();
+                        m_drawing=true;
+                        m_drawingGroup=false;
+                        if(Fl::event_shift()) {
+                            m_drawingGroup=true;
+                        }
+                        m_mainMenu->hide();
+                        m_zoneMenu->hide();
+                        m_mainPanel->hide();
+                        m_zonePanel->hide();
+                        redraw();
+                    }break;
+                    case FL_RIGHT_MOUSE: {
+                        detectMidiDevices();
+                        insert(*m_mainMenu, children());
+                        int menPosX = (Fl::event_x()>w()-m_mainPanel->w())? 
+                                Fl::event_x()-m_mainPanel->w():Fl::event_x();
+                        int menPosY = (Fl::event_y()>h()-m_mainPanel->h())? 
+                                Fl::event_y()-m_mainPanel->h():Fl::event_y();
+                        //m_mainMenu->position(menPosX, menPosY);
+                        //m_mainMenu->show();
+                        //m_zoneMenu->hide();
+                        m_mainPanel->position(menPosX, menPosY);
+                        insert(*m_mainPanel,children());
+                        m_mainPanel->show();
+                    }break;
+                    default:break;
+                }
+                res=1;
+            break;
+            case FL_DRAG: 
+                m_drawCurX=Fl::event_x();
+                m_drawCurY=Fl::event_y();
+            break;
+            case FL_RELEASE: 
+                switch(Fl::event_button()) {
+                    case FL_LEFT_MOUSE: {
+                        int minPixels=20;
+                        int drawStopX = Fl::event_x();
+                        int drawStopY = Fl::event_y();
+                        if(m_drawing) {
+                            if(abs(m_drawStartX-drawStopX)>minPixels && 
+                                    abs(m_drawStartY-drawStopY)>minPixels) {
+                                if(m_drawingGroup) {
+                                    addGroup(new GroupWidget(m_drawStartX, 
+                                                           m_drawStartY, 
+                                                  abs(m_drawStartX-drawStopX), 
+                                                  abs(m_drawStartY-drawStopY)));
+                                }
+                                else {
+                                    addZone(new ZoneWidget(
+                                              m_drawStartX-ZoneWidget::OUTER, 
+                                              m_drawStartY-ZoneWidget::OUTER, 
+                                              abs(m_drawStartX-drawStopX)
+                                                +ZoneWidget::OUTER*2, 
+                                              abs(m_drawStartY-drawStopY)
+                                                +ZoneWidget::OUTER*2)); 
+                                }
+                            }
+                        }
+                        m_drawing=false;
+                        res=1;
+                    }break;
+                    default:break;
+                }
+            break;
+            default:break;
+        }
+    }
+    redraw();
+    return res;
+}
+
+void Controlar::ProcessMessage(const osc::ReceivedMessage& mess,
+                                const IpEndpointName& remoteEndpoint) {
+    try {
+        string name = string(mess.AddressPattern());
+        if(name.find("/controllar/")!=string::npos) {
+            if(name.find("/scene")!=string::npos && mess.ArgumentCount()>0) {
+                pthread_mutex_lock(&m_zonesMutex);
+                    m_askedScene=mess.ArgumentsBegin()->AsInt32();
+                pthread_mutex_unlock(&m_zonesMutex);
+            }
+        }
+    } 
+    catch(const exception& e) {
+        cout<<"Exception when receiving osc message "<<e.what()<<endl;
+    }
+}
+
+
+void Controlar::cbZone(Fl_Widget* wid) {
+    refreshWindowList();
+
+    m_clickedZone = static_cast<ZoneWidget*>(wid);
+    int menPosX = (Fl::event_x()>w()-m_zonePanel->w())? 
+                    Fl::event_x()-m_zonePanel->w():Fl::event_x();
+    int menPosY = (Fl::event_y()>h()-m_zonePanel->h())? 
+                    Fl::event_y()-m_zonePanel->h():Fl::event_y();
+    //m_zoneMenu->position(menPosX, menPosY);
+    //insert(*m_zoneMenu, children());
+    //m_zoneMenu->show();
+    m_zonePanel->setZone(m_clickedZone);
+    m_zonePanel->position(menPosX, menPosY);
+    m_zonePanel->refresh();
+    insert(*m_zonePanel,children());
+    m_zonePanel->show();
+}
+
+void Controlar::cbSceneNext() {
+    if(m_scenes.find(m_currentScene+1)==m_scenes.end()) {
+        m_scenes[m_currentScene+1]="scene";
+    }
+    setScene(m_currentScene+1);
+}
+
+void Controlar::cbScenePrev() {
+    setScene(m_currentScene-1);
+}
+
+/*
+void Controlar::cbSceneDuplicate() {
+    //save ref to current set
+    int cur=m_currentSet;
+
+    //create new set and make it current
+    m_zonesSets.push_back(map<unsigned int, ZoneWidget*>());
+    setSet(m_zonesSets.size()-1);
+
+    //copy zones 
+    map<unsigned int, ZoneWidget*>::iterator itZo = m_zonesSets[cur].begin();
+    for(; itZo!=m_zonesSets[cur].end(); ++itZo) {
+        ZoneWidget* newZo = new ZoneWidget();
+        newZo->copy(itZo->second);
+        addZone(newZo);
+    }
+    setSet(m_currentSet);
+}
+*/
+
+void Controlar::cbSceneDelete() {
+/*
+    if(m_zonesSets.size()>1) {
+        if(fl_choice("Are you sure you want to delete the current set ?", 
+                "No", "Yes", "")) {
+            map<unsigned int, ZoneWidget*>::iterator itZo 
+                = m_zonesSets[m_currentSet].begin();
+            for(; itZo!=m_zonesSets[m_currentSet].end(); ++itZo) {
+                Fl::delete_widget(itZo->second);
+            }
+            m_zonesSets.erase(m_zonesSets.begin()+m_currentSet);
+            setSet(0);
+        }
+    }
+*/
+}
+
+void Controlar::setScene(const int& scene) {
+    if(m_scenes.find(scene)!=m_scenes.end()) {
+        //store images for zones that only update on current scene
+        map<unsigned int, ZoneWidget*>::iterator itZo = m_zones.begin();
+        for(; itZo!=m_zones.end(); ++itZo) {
+            itZo->second->setScene(scene);
+        }
+        //change scene
+        m_currentScene=scene;
+        m_mainPanel->setCurrentScene(scene);
+        m_mainPanel->refresh();
+        updateTitle();
+    }
+    m_mainMenu->hide();
+}
+
+void Controlar::updateTitle() {
+    ostringstream oss;
+    oss<<m_currentScene;
+    m_title = "ControllAR - "+m_fileName+" - Scene "+oss.str();
+    label(m_title.c_str());
+}
+
+void Controlar::cbSceneLearn() {
+    m_midiLearning=true;
+    m_mainMenu->hide();
+}
+
+void Controlar::cbFlip() {
+    m_flipped=!m_flipped;
+    resize(x(),y(),w(),h());
+    m_mainMenu->hide();
+    map<unsigned int, ZoneWidget*>::iterator itZo=m_zones.begin();
+    for(; itZo!=m_zones.end(); ++itZo) {
+        itZo->second->recomputePixels();
+    }
+}
+
+void Controlar::cbFullscreen() {
+    m_fullscreen=!m_fullscreen;
+    if(m_fullscreen) {
+        fullscreen();
+    }
+    else {
+        fullscreen_off();
+    }
+    m_mainMenu->hide();
+    fl_cursor(FL_CURSOR_NONE);
+}
+
+#ifdef GL
+void Controlar::initGL() {
+    #ifdef OSX
+        glewExperimental = GL_TRUE; 
+    #endif
+    glewInit();
+    glGenVertexArrays(1, &m_vertexArrayID);
+    glBindVertexArray(m_vertexArrayID); 
+    glGenBuffers(1, &m_vertexBuffer);
+    glBindBuffer(GL_ARRAY_BUFFER, m_vertexBuffer);
+    m_vertexBufferData[0]=0;m_vertexBufferData[1]=0;m_vertexBufferData[2]=0;
+    m_vertexBufferData[3]=1;m_vertexBufferData[4]=0;m_vertexBufferData[5]=0;
+    m_vertexBufferData[6]=1;m_vertexBufferData[7]=1;m_vertexBufferData[8]=0;
+    m_vertexBufferData[9]=0;m_vertexBufferData[10]=0;m_vertexBufferData[11]=0;
+    m_vertexBufferData[12]=1;m_vertexBufferData[13]=1;m_vertexBufferData[14]=0;
+    m_vertexBufferData[15]=0;m_vertexBufferData[16]=1;m_vertexBufferData[17]=0;
+    glBufferData(GL_ARRAY_BUFFER, sizeof(m_vertexBufferData), 
+                 m_vertexBufferData, GL_STATIC_DRAW);
+
+    GLint compile_ok = GL_FALSE, link_ok = GL_FALSE;
+
+    GLuint vertexShader, fragmentShader;
+
+    //ZONE PROGRAM
+    {
+    vertexShader = glCreateShader(GL_VERTEX_SHADER);
+    const char *vs_source =
+        "#version 110\n"
+        "attribute vec3 coord;\n"
+        "uniform vec2 winSize;\n"
+        "uniform vec2 zonePos;\n"
+        "uniform vec2 zoneSize;\n"
+        "uniform vec2 cutPos;\n"
+        "uniform vec2 cutSize;\n"
+        "uniform float mirrored;\n"
+        "uniform float outer;\n"
+        "varying vec2 pixRatio;\n"
+        "varying vec4 pixToSides;\n" //T,B,L,R
+        "void main(void) {\n"
+        "   vec2 zonePixRatio;\n"
+        "   if(mirrored>0.0) {\n"
+        "       zonePixRatio = vec2(coord.x, coord.y);\n"
+        "       pixRatio = vec2(\n"
+        "               (coord.x*zoneSize.x-outer)/cutSize.x,\n"
+        "               (coord.y*zoneSize.y-outer)/cutSize.y);\n"
+        "   }\n"
+        "   else {\n"
+        "       zonePixRatio = vec2(coord.x, 1.0-coord.y);\n"
+        "       pixRatio = vec2(\n"
+        "               (coord.x*zoneSize.x-outer)/cutSize.x,\n"
+        "               ((1.0-coord.y)*zoneSize.y-outer)/cutSize.y);\n"
+        "   }\n"
+        "   vec2 cutPixPos = pixRatio*cutSize;\n"
+        "   vec2 pos = ((cutPixPos+cutPos)/winSize)*2.0-1.0;\n"
+        "   if(mirrored>0.0) {\n"
+        "       gl_Position = vec4(pos.x, pos.y, 0.0, 1.0);\n"
+        "   }\n"
+        "   else {\n"
+        "       gl_Position = vec4(pos.x, -pos.y, 0.0, 1.0);\n"
+        "   }\n"
+        "   vec2 zonePixPos = zonePixRatio*zoneSize;\n"
+        "   pixToSides = vec4(zonePixPos.y,\n"
+        "                     zoneSize.y-zonePixPos.y,\n"
+        "                     zonePixPos.x,\n"
+        "                     zoneSize.x-zonePixPos.x);\n"
+        "}\n";
+    glShaderSource(vertexShader, 1, &vs_source, NULL);
+    glCompileShader(vertexShader);
+    glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &compile_ok);
+    if (!compile_ok) {
+        cout << "Error in vertex shader" << endl;
+        GLint maxLength = 0;
+        glGetShaderiv(vertexShader, GL_INFO_LOG_LENGTH, &maxLength);
+        std::vector<GLchar> errorLog(maxLength);
+        glGetShaderInfoLog(vertexShader, maxLength, &maxLength, &errorLog[0]);
+        vector<GLchar>::iterator itC=errorLog.begin();
+        for(; itC!=errorLog.end(); ++itC) {
+            cout<<*itC;
+        }
+        cout<<endl;
+    } 
+
+    fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
+    const char *fs_source =
+        "#version 110\n"
+        "varying vec2 pixRatio;\n"
+        "varying vec4 pixToSides;\n" //T,B,L,R
+        "uniform sampler2D windowTexture;\n"
+        "uniform sampler2D coordsTexture;\n"
+        "uniform vec2 winSize;\n"
+        "uniform vec2 zonePos;\n"
+        "uniform vec2 zoneSize;\n"
+        "uniform vec2 cutPos;\n"
+        "uniform vec2 cutSize;\n"
+        "uniform float mirrored;\n"
+        "uniform int state;\n"//NORMAL,MOVE_CUT,RESIZE_CUT,MOVE_ZONE,RESIZE_ZONE
+        "uniform float alpha;\n"
+        "uniform float filled;\n"
+        "uniform float invert;\n"
+        "uniform float outer;\n"
+        "uniform float inner;\n"
+        "void main(void) {       \n"
+        "   float thick=1.0;\n"
+        "   if(filled>0.0) {\n"
+        "       if(texture2D(coordsTexture, pixRatio).r>=0.0 \n"
+        "               && pixRatio.x>0.0 && pixRatio.x<1.0 \n"
+        "               && pixRatio.y>0.0 && pixRatio.y<1.0) {\n"
+        "           vec4 winCol = texture2D(windowTexture, \n"
+        "                         texture2D(coordsTexture, pixRatio).rg);\n"
+#ifdef WINDOWS
+        "           winCol = texture2D(windowTexture, pixRatio);\n"
+#else
+        "           winCol = vec4(winCol.b,winCol.g,winCol.r,winCol.a);\n"
+#endif
+        "           if(invert>0.0) {\n" 
+        "               gl_FragColor=vec4(1.0-winCol.r, 1.0-winCol.g, \n"
+        "                                 1.0-winCol.b, alpha);\n"
+        "           }\n"
+        "           else {\n" 
+        "               gl_FragColor=vec4(winCol.rgb, alpha);\n"
+        "           }\n"
+        "       }\n"
+        "       else {\n"
+        "           gl_FragColor=vec4(0.0, 0.0, 0.0, 0.0);\n"
+        "       }\n"
+        "       if(state>0) {\n"
+        //outer border
+        "           if(pixToSides.x<thick ||  pixToSides.y<thick \n"
+        "                   || pixToSides.z<thick || pixToSides.w<thick) { \n"
+        "               if(state==3) {\n"
+        "                   gl_FragColor=vec4(1.0,0.0,0.0,1.0);\n"
+        "               }\n"
+        "               else {\n"
+        "                   gl_FragColor=vec4(1.0,1.0,1.0,1.0);\n"
+        "               }\n"
+        "           }\n"
+        //inner     border
+        "           if(((abs(pixToSides.x-inner)<thick \n"
+        "                       || abs(pixToSides.y-inner)<thick)\n"
+        "                   && (pixToSides.z>inner && pixToSides.w>inner))\n"
+        "                  || (abs(pixToSides.z-inner)<thick \n"
+        "                       || abs(pixToSides.w-inner)<thick)\n"
+        "                   && (pixToSides.x>inner && pixToSides.y>inner)) {\n"
+        "               if(state==1) {\n"
+        "                   gl_FragColor=vec4(1.0,0.0,0.0,1.0);\n"
+        "               }\n"
+        "               else {\n"
+        "                   gl_FragColor=vec4(1.0,1.0,1.0,1.0);\n"
+        "               }\n"
+        "           }\n"
+        //outer     corner
+        "           if(abs(sqrt(pow(pixToSides.w, 2.0)\n"
+        "                        +pow(pixToSides.y, 2.0))-inner)<thick) {\n"
+        "               if(state==4) {\n"
+        "                   gl_FragColor=vec4(1.0,0.0,0.0,1.0);\n"
+        "               }\n"
+        "               else {\n"
+        "                   gl_FragColor=vec4(1.0,1.0,1.0,1.0);\n"
+        "               }\n"
+        "           }\n"
+        //inner     corner
+        "           if(( abs(sqrt(pow(pixToSides.w, 2.0)\n"
+        "                       +pow(pixToSides.y, 2.0))-inner*3.0)<thick)\n"
+        "                   && pixToSides.x>inner && pixToSides.y>inner \n"
+        "                   && pixToSides.z>inner && pixToSides.w>inner ){\n"
+        "               if(state==2) {\n"
+        "                   gl_FragColor=vec4(1.0,0.0,0.0,1.0);\n"
+        "               }\n"
+        "               else {\n"
+        "                   gl_FragColor=vec4(1.0,1.0,1.0,1.0);\n"
+        "               }\n"
+        "           }\n"
+        "       }\n"
+        "   }\n"
+        "   else {\n"
+        "       if(pixToSides.x<thick ||  pixToSides.y<thick \n"
+        "               || pixToSides.z<thick || pixToSides.w<thick) { \n"
+        "           if(state>0) {\n"
+        "               gl_FragColor=vec4(1.0,0.0,0.0,1.0);\n"
+        "           }\n"
+        "           else {\n"
+        "               gl_FragColor=vec4(1.0,1.0,1.0,1.0);\n"
+        "           }\n"
+        "       }\n"
+        "       else {\n"
+        "           gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);\n"
+        "       }\n"
+        "   }\n"
+        "}\n";
+    glShaderSource(fragmentShader, 1, &fs_source, NULL);
+    glCompileShader(fragmentShader);
+    glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &compile_ok);
+    if (!compile_ok) {
+        cout << "Error in fragment shader" << endl;
+        GLint maxLength = 0;
+        glGetShaderiv(fragmentShader, GL_INFO_LOG_LENGTH, &maxLength);
+        std::vector<GLchar> errorLog(maxLength);
+        glGetShaderInfoLog(fragmentShader, maxLength, &maxLength, &errorLog[0]);
+        vector<GLchar>::iterator itC=errorLog.begin();
+        for(; itC!=errorLog.end(); ++itC) {
+            cout<<*itC;
+        }
+        cout<<endl;
+    }
+    m_zoneProgram = glCreateProgram();
+    glAttachShader(m_zoneProgram, vertexShader);
+    glAttachShader(m_zoneProgram, fragmentShader);
+    glLinkProgram(m_zoneProgram);
+    glGetProgramiv(m_zoneProgram, GL_LINK_STATUS, &link_ok);
+    if (!link_ok) {
+        cout << "Error in glLinkProgram" << endl;
+    }
+    m_zoneWinSizeUniform = glGetUniformLocation(m_zoneProgram, "winSize");
+    m_zoneSizeUniform = glGetUniformLocation(m_zoneProgram, "zoneSize");
+    m_zonePosUniform = glGetUniformLocation(m_zoneProgram, "zonePos");
+    m_cutSizeUniform = glGetUniformLocation(m_zoneProgram, "cutSize");
+    m_cutPosUniform = glGetUniformLocation(m_zoneProgram, "cutPos");
+    m_zoneMirrorUniform = glGetUniformLocation(m_zoneProgram, "mirrored");
+    m_zoneStateUniform = glGetUniformLocation(m_zoneProgram, "state");
+    m_zoneAlphaUniform = glGetUniformLocation(m_zoneProgram, "alpha");
+    m_zoneInvertUniform = glGetUniformLocation(m_zoneProgram, "invert");
+    m_zoneFilledUniform = glGetUniformLocation(m_zoneProgram, "filled");
+    m_zoneWindowUniform = glGetUniformLocation(m_zoneProgram, "windowTexture");
+    m_zoneCoordsUniform = glGetUniformLocation(m_zoneProgram, "coordsTexture");
+    m_zoneInnerUniform = glGetUniformLocation(m_zoneProgram, "inner");
+    m_zoneOuterUniform = glGetUniformLocation(m_zoneProgram, "outer");
+
+    glActiveTexture(GL_TEXTURE0);
+    glGenTextures(1, &m_firstTextureID);
+    glBindTexture(GL_TEXTURE_2D, m_firstTextureID);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+    glActiveTexture(GL_TEXTURE1);
+    glGenTextures(1, &m_secondTextureID);
+    glBindTexture(GL_TEXTURE_2D, m_secondTextureID);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+    }
+
+    //GROUP PROGRAM
+    {
+    vertexShader = glCreateShader(GL_VERTEX_SHADER);
+    const char *vs_source =
+        "#version 110\n"
+        "attribute vec3 coord;\n"
+        "uniform vec2 winSize;\n"
+        "uniform vec2 groupPos;\n"
+        "uniform vec2 groupSize;\n"
+        "uniform float mirrored;\n"
+        "varying vec2 pixPos;\n"
+        "void main(void) {\n"
+        "   if(mirrored>0.0) {\n"
+        "       pixPos = vec2(coord.x, coord.y);\n"
+        "   }\n"
+        "   else {\n"
+        "       pixPos = vec2(coord.x, 1.0-coord.y);\n"
+        "   }\n"
+        "   vec2 pos = ((pixPos*groupSize+groupPos)/winSize)*2.0-1.0;\n"
+        "   if(mirrored>0.0) {\n"
+        "       gl_Position = vec4(pos.x, pos.y, 0.0, 1.0);\n"
+        "   }\n"
+        "   else {\n"
+        "       gl_Position = vec4(pos.x, -pos.y, 0.0, 1.0);\n"
+        "   }\n"
+        "}\n";
+    glShaderSource(vertexShader, 1, &vs_source, NULL);
+    glCompileShader(vertexShader);
+    glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &compile_ok);
+    if (!compile_ok) {
+        cout << "Error in vertex shader" << endl;
+        GLint maxLength = 0;
+        glGetShaderiv(vertexShader, GL_INFO_LOG_LENGTH, &maxLength);
+        std::vector<GLchar> errorLog(maxLength);
+        glGetShaderInfoLog(vertexShader, maxLength, &maxLength, &errorLog[0]);
+        vector<GLchar>::iterator itC=errorLog.begin();
+        for(; itC!=errorLog.end(); ++itC) {
+            cout<<*itC;
+        }
+        cout<<endl;
+    } 
+
+    fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
+    const char *fs_source =
+        "#version 110\n"
+        "varying vec2 pixPos;\n"
+        "uniform vec2 winSize;\n"
+        "uniform float mirrored;\n"
+        "uniform float editing;\n"
+        "uniform float highlight;\n"
+        "void main(void) {       \n"
+        "   if(editing>0.0) {\n"
+        "           gl_FragColor = vec4(0.0,1.0,0.0,1.0);\n"
+        "   }\n"
+        "   else {\n" 
+        "       if(pixPos.x<0.01 ||  pixPos.x>0.99 \n"
+        "                   || pixPos.y<0.01 || pixPos.y>0.99) { \n"
+        "             gl_FragColor=vec4(0.0,0.5+highlight*0.5,0.0,1.0);\n"
+        "       }\n"
+        "       else {\n"
+        "           gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);\n"
+        "       }\n"
+        "   }\n"
+        "}\n";
+    glShaderSource(fragmentShader, 1, &fs_source, NULL);
+    glCompileShader(fragmentShader);
+    glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &compile_ok);
+    if (!compile_ok) {
+        cout << "Error in fragment shader" << endl;
+        GLint maxLength = 0;
+        glGetShaderiv(fragmentShader, GL_INFO_LOG_LENGTH, &maxLength);
+        std::vector<GLchar> errorLog(maxLength);
+        glGetShaderInfoLog(fragmentShader, maxLength, &maxLength, &errorLog[0]);
+        vector<GLchar>::iterator itC=errorLog.begin();
+        for(; itC!=errorLog.end(); ++itC) {
+            cout<<*itC;
+        }
+        cout<<endl;
+    }
+    m_groupProgram = glCreateProgram();
+    glAttachShader(m_groupProgram, vertexShader);
+    glAttachShader(m_groupProgram, fragmentShader);
+    glLinkProgram(m_groupProgram);
+    glGetProgramiv(m_groupProgram, GL_LINK_STATUS, &link_ok);
+    if (!link_ok) {
+        cout << "Error in glLinkProgram" << endl;
+    }
+    m_groupWinSizeUniform = glGetUniformLocation(m_groupProgram, "winSize");
+    m_groupSizeUniform = glGetUniformLocation(m_groupProgram, "groupSize");
+    m_groupPosUniform = glGetUniformLocation(m_groupProgram, "groupPos");
+    m_groupMirrorUniform = glGetUniformLocation(m_groupProgram, "mirrored");
+    m_groupEditingUniform = glGetUniformLocation(m_groupProgram, "editing");
+    m_groupHighlightUniform = glGetUniformLocation(m_groupProgram, "highlight");
+    }
+    
+    //CURSOR PROGRAM
+    {
+    vertexShader = glCreateShader(GL_VERTEX_SHADER);
+    const char *vs_source =
+        "#version 110\n"
+        "attribute vec3 coord;\n"
+        "uniform vec2 winSize;\n"
+        "uniform vec2 cursPos;\n"
+        "uniform float mirrored;\n"
+        "varying vec2 pixPos;\n"
+        "void main(void) {\n"
+        "   if(mirrored>0.0) {\n"
+        "       pixPos = vec2(coord.x, coord.y);\n"
+        "   }\n"
+        "   else {\n"
+        "       pixPos = vec2(coord.x, 1.0-coord.y);\n"
+        "   }\n"
+        "   vec2 pos = ((pixPos*vec2(10,10)+cursPos)/winSize)*2.0-1.0;\n"
+        "   if(mirrored>0.0) {\n"
+        "       gl_Position = vec4(pos.x, pos.y, 0.0, 1.0);\n"
+        "   }\n"
+        "   else {\n"
+        "       gl_Position = vec4(pos.x, -pos.y, 0.0, 1.0);\n"
+        "   }\n"
+        "}\n";
+    glShaderSource(vertexShader, 1, &vs_source, NULL);
+    glCompileShader(vertexShader);
+    glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &compile_ok);
+    if (!compile_ok) {
+        cout << "Error in cursor vertex shader" << endl;
+    } 
+
+    fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
+    const char *fs_source =
+        "#version 110\n"
+        "uniform vec2 winSize;\n"
+        "uniform vec2 cursPos;\n"
+        "uniform float mirrored;\n"
+        "varying vec2 pixPos;\n"
+        "void main(void) {\n"
+        "   if(pixPos.x<0.1 ||  pixPos.x>0.9 \n"
+        "           || pixPos.y<0.1 || pixPos.y>0.9) { \n"
+        "       gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);\n"
+        "   }\n"
+        "   else {\n"
+        "       gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);\n"
+        "   }\n"
+        "}\n";
+    glShaderSource(fragmentShader, 1, &fs_source, NULL);
+    glCompileShader(fragmentShader);
+    glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &compile_ok);
+    if (!compile_ok) {
+        cout << "Error in cursor fragment shader" << endl;
+    }
+    m_cursorProgram = glCreateProgram();
+    glAttachShader(m_cursorProgram, vertexShader);
+    glAttachShader(m_cursorProgram, fragmentShader);
+    glLinkProgram(m_cursorProgram);
+    glGetProgramiv(m_cursorProgram, GL_LINK_STATUS, &link_ok);
+    if (!link_ok) {
+        cout << "Error in cursor glLinkProgram" << endl;
+    }
+    m_cursorWinSizeUniform = glGetUniformLocation(m_cursorProgram, "winSize");
+    m_cursorPosUniform = glGetUniformLocation(m_cursorProgram, "cursPos");
+    m_cursorMirrorUniform = glGetUniformLocation(m_cursorProgram, "mirrored");
+    }
+
+
+    //DRAW PROGRAM
+    {
+    vertexShader = glCreateShader(GL_VERTEX_SHADER);
+    const char *vs_source =
+        "#version 110\n"
+        "attribute vec3 coord;\n"
+        "uniform vec2 winSize;\n"
+        "uniform vec2 drawPos;\n"
+        "uniform vec2 drawSize;\n"
+        "uniform float mirrored;\n"
+        "void main(void) {\n"
+        "   vec2 pixPos;\n"
+        "   if(mirrored>0.0) {\n"
+        "       pixPos = vec2(coord.x, coord.y);\n"
+        "   }\n"
+        "   else {\n"
+        "       pixPos = vec2(coord.x, 1.0-coord.y);\n"
+        "   }\n"
+        "   vec2 pos = ((pixPos*drawSize+drawPos)/winSize)*2.0-1.0;\n"
+        "   if(mirrored>0.0) {\n"
+        "       gl_Position = vec4(pos.x, pos.y, 0.0, 1.0);\n"
+        "   }\n"
+        "   else {\n"
+        "       gl_Position = vec4(pos.x, -pos.y, 0.0, 1.0);\n"
+        "   }\n"
+        "}\n";
+    glShaderSource(vertexShader, 1, &vs_source, NULL);
+    glCompileShader(vertexShader);
+    glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &compile_ok);
+    if (!compile_ok) {
+        cout << "Error in draw vertex shader" << endl;
+    } 
+
+    fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
+    const char *fs_source =
+        "#version 110\n"
+        "uniform vec2 winSize;\n"
+        "uniform vec2 cursPos;\n"
+        "uniform float mirrored;\n"
+        "uniform float drawingGroup;\n"
+        "void main(void) {\n"
+        "   gl_FragColor = vec4(1.0-drawingGroup, drawingGroup, 0.0, 1.0);\n"
+        "}\n";
+    glShaderSource(fragmentShader, 1, &fs_source, NULL);
+    glCompileShader(fragmentShader);
+    glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &compile_ok);
+    if (!compile_ok) {
+        cout << "Error in draw fragment shader" << endl;
+    }
+    m_drawingProgram = glCreateProgram();
+    glAttachShader(m_drawingProgram, vertexShader);
+    glAttachShader(m_drawingProgram, fragmentShader);
+    glLinkProgram(m_drawingProgram);
+    glGetProgramiv(m_drawingProgram, GL_LINK_STATUS, &link_ok);
+    if (!link_ok) {
+        cout << "Error in cursor glLinkProgram" << endl;
+    }
+    m_drawWinSizeUniform = glGetUniformLocation(m_drawingProgram, "winSize");
+    m_drawPosUniform = glGetUniformLocation(m_drawingProgram, "drawPos");
+    m_drawSizeUniform = glGetUniformLocation(m_drawingProgram, "drawSize");
+    m_drawMirrorUniform = glGetUniformLocation(m_drawingProgram, "mirrored");
+    m_drawGroupUniform = glGetUniformLocation(m_drawingProgram, "drawingGroup");
+    }
+
+    //MENU PROGRAM
+    {
+    vertexShader = glCreateShader(GL_VERTEX_SHADER);
+    const char *vs_source =
+        "#version 110\n"
+        "attribute vec3 coord;\n"
+        "uniform vec2 winSize;\n"
+        "uniform vec2 menuPos;\n"
+        "uniform vec2 menuSize;\n"
+        "uniform float mirrored;\n"
+        "varying vec2 pixPos;\n"
+        "void main(void) {\n"
+        "   if(mirrored>0.0) {\n"
+        "       pixPos = vec2(coord.x, coord.y);\n"
+        "   }\n"
+        "   else {\n"
+        "       pixPos = vec2(coord.x, 1.0-coord.y);\n"
+        "   }\n"
+        "   vec2 pos = ((pixPos*menuSize+menuPos)/winSize)*2.0-1.0;\n"
+        "   if(mirrored>0.0) {\n"
+        "       gl_Position = vec4(pos.x, pos.y, 0.0, 1.0);\n"
+        "   }\n"
+        "   else {\n"
+        "       gl_Position = vec4(pos.x, -pos.y, 0.0, 1.0);\n"
+        "   }\n"
+        "}\n";
+    glShaderSource(vertexShader, 1, &vs_source, NULL);
+    glCompileShader(vertexShader);
+    glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &compile_ok);
+    if (!compile_ok) {
+        cout << "Error in menu vertex shader" << endl;
+    } 
+
+    fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
+    const char *fs_source =
+        "#version 110\n"
+        "varying vec2 pixPos;\n"
+        "uniform float mirrored;\n"
+        "uniform sampler2D menuTexture;\n"
+        "void main(void) {\n"
+        "   gl_FragColor = texture2D(menuTexture, pixPos);\n"
+        "}\n";
+    glShaderSource(fragmentShader, 1, &fs_source, NULL);
+    glCompileShader(fragmentShader);
+    glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &compile_ok);
+    if (!compile_ok) {
+        cout << "Error in menu fragment shader" << endl;
+    }
+    m_menuProgram = glCreateProgram();
+    glAttachShader(m_menuProgram, vertexShader);
+    glAttachShader(m_menuProgram, fragmentShader);
+    glLinkProgram(m_menuProgram);
+    glGetProgramiv(m_menuProgram, GL_LINK_STATUS, &link_ok);
+    if (!link_ok) {
+        cout << "Error in cursor glLinkProgram" << endl;
+    }
+    m_menuWinSizeUniform = glGetUniformLocation(m_menuProgram, "winSize");
+    m_menuPosUniform = glGetUniformLocation(m_menuProgram, "menuPos");
+    m_menuSizeUniform = glGetUniformLocation(m_menuProgram, "menuSize");
+    m_menuMirrorUniform = glGetUniformLocation(m_menuProgram, "mirrored");
+    m_menuTextureUniform = glGetUniformLocation(m_menuProgram, "menuTexture");
+    }
+    glActiveTexture(GL_TEXTURE0);
+    glGenTextures(1, &m_firstTextureID);
+    glBindTexture(GL_TEXTURE_2D, m_firstTextureID);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+}
+#endif
+
+void Controlar::draw() {
+
+
+
+/*
+    pthread_mutex_lock(&m_zonesMutex);
+    if(m_askedScene>-1) {
+        setScene(m_askedScene);
+        m_askedScene=-1;
+    }
+    pthread_mutex_unlock(&m_zonesMutex);
+*/
+#ifdef GL
+    if(!valid()) {
+        initGL();
+    }
+
+    glViewport(0, 0, w(), h());
+    glClearColor(0, 0, 0, 1);
+    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
+    glEnable (GL_BLEND);
+    glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+    
+    glEnableVertexAttribArray(0);
+    glBindBuffer(GL_ARRAY_BUFFER, m_vertexBuffer);
+    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
+
+    //reset each window
+    vector<CutWindow*>::iterator itWin = m_winsMan->editWindowList().begin();
+    for(; itWin!=m_winsMan->editWindowList().end(); ++itWin) {
+        (*itWin)->releaseImage();
+    }
+
+    //draw groups
+    glUseProgram(m_groupProgram);
+    glUniform1f(m_groupMirrorUniform, m_flipped);
+    glUniform2f(m_groupWinSizeUniform, w(), h());
+    map<unsigned int, GroupWidget*>::iterator itGr = m_groups.begin();
+    for(; itGr!=m_groups.end(); ++itGr) {
+        itGr->second->draw();
+    }
+
+    //draw zones
+    m_currentWindowName="";
+    glUseProgram(m_zoneProgram);
+    glUniform1f(m_zoneMirrorUniform, m_flipped);
+    glUniform2f(m_zoneWinSizeUniform, w(), h());
+    glUniform1i(m_zoneWindowUniform, 0);
+    glUniform1i(m_zoneCoordsUniform, 1);
+    glUniform1f(m_zoneInnerUniform, ZoneWidget::INNER);
+    glUniform1f(m_zoneOuterUniform, ZoneWidget::OUTER);
+    map<unsigned int, ZoneWidget*>::iterator itZo = m_zones.begin();
+    for(; itZo!=m_zones.end(); ++itZo) {
+        itZo->second->drawZone(m_currentScene);
+    }
+
+    //draw menus 
+    glUseProgram(m_menuProgram);
+    glUniform1f(m_menuMirrorUniform, m_flipped);
+    glUniform2f(m_menuWinSizeUniform, w(), h());
+    glUniform1i(m_menuTextureUniform, 0);
+    if(m_mainMenu->visible()) {
+        m_mainMenu->draw();
+    }
+    else if(m_zoneMenu->visible()) {
+        m_zoneMenu->draw();
+    }
+    if(m_mainPanel->visible()) {
+        m_mainPanel->draw();
+    }
+    if(m_zonePanel->visible()) {
+        m_zonePanel->draw();
+    }
+    //draw drawing
+    if(m_drawing) {
+        glUseProgram(m_drawingProgram);
+        glUniform1f(m_drawMirrorUniform, m_flipped);
+        glUniform2f(m_drawWinSizeUniform, w(), h());
+        glUniform2f(m_drawSizeUniform, m_drawCurX-m_drawStartX, 
+                                       m_drawCurY-m_drawStartY);
+        glUniform2f(m_drawPosUniform, m_drawStartX, 
+                                      m_drawStartY);
+        glUniform1f(m_drawGroupUniform, m_drawingGroup);
+        glDrawArrays(GL_TRIANGLES, 0, 6);
+    }
+
+#ifndef LINUX
+    //draw cursor
+    glUseProgram(m_cursorProgram);
+    glUniform1f(m_cursorMirrorUniform, m_flipped);
+    glUniform2f(m_cursorWinSizeUniform, w(), h());
+    glUniform2f(m_cursorPosUniform, Fl::event_x_root()-x(), 
+                                    Fl::event_y_root()-y());
+    glDrawArrays(GL_TRIANGLES, 3, 3);
+#endif
+
+    glDisableVertexAttribArray(0);
+
+#else 
+    //redraw whole background only when needed
+    if(damage()&FL_DAMAGE_ALL) {
+        fl_draw_box(box(), 0, 0, w(), h(), FL_BLACK);
+        map<unsigned int, ZoneWidget*>::iterator itZo 
+            = m_zonesSets[m_currentSet].begin();
+        for(; itZo!=m_zonesSets[m_currentSet].end(); ++itZo) {
+            itZo->second->setRateReached();
+        }
+    }
+    else { //redraw only dynamic zones background and mask prev curs
+        fl_rect(m_cursPosX-5, 
+                m_cursPosY-5, 
+                10, 10, FL_BLACK);
+        map<unsigned int, ZoneWidget*>::iterator itZo 
+            = m_zonesSets[m_currentSet].begin();
+        for(; itZo!=m_zonesSets[m_currentSet].end(); ++itZo) {
+            if(itZo->second->getRate()==ZoneWidget::DYNAMIC) {
+                ZoneWidget* wid = itZo->second;
+                fl_rectf(wid->x(),
+                         m_flipped?h()-wid->y()-wid->h():wid->y(),
+                         wid->w(),
+                         wid->h(),
+                         FL_BLACK);
+            }
+        }
+    }
+
+    //reset windows
+    vector<CutWindow*>::iterator itWin = m_winsMan->editWindowList().begin();
+    for(; itWin!=m_winsMan->editWindowList().end(); ++itWin) {
+        (*itWin)->releaseImage();
+    }
+
+    //draw groups
+    map<unsigned int, GroupWidget*>::iterator itGr = m_groups.begin();
+    for(; itGr!=m_groups.end(); ++itGr) {
+        itGr->second->draw();
+    }
+
+
+    //draw zones
+    map<unsigned int, ZoneWidget*>::iterator itZo 
+        = m_zones.begin();
+    for(; itZo!=m_zones.end(); ++itZo) {
+        itZo->second->draw();
+    }
+
+    //draw menus 
+    if(m_mainMenu->visible()) {
+        m_mainMenu->draw();
+    }
+    else if(m_zoneMenu->visible()) {
+        m_zoneMenu->draw();
+    }
+    if(m_mainBar->visible()) {
+        m_mainBar->draw();
+    }
+    if(m_zoneBar->visible()) {
+        m_zoneBar->draw();
+    }
+    //draw zone creation rectangles
+    if(m_drawing) {
+        fl_rectf(m_drawStartX, 
+             m_flipped?h()-m_drawStartY-(m_drawCurY-m_drawStartY):m_drawStartY,
+             m_drawCurX-m_drawStartX, 
+             m_drawCurY-m_drawStartY, 
+             m_drawingGroup?FL_GREEN:FL_RED);
+    }
+
+    //draw cursor replacement
+    m_cursPosX = Fl::event_x_root()-x();
+    m_cursPosY=m_flipped?h()-(Fl::event_y_root()-y()):Fl::event_y_root()-y();
+    fl_rectf(m_cursPosX-5, 
+             m_cursPosY-5, 
+             10, 10, FL_BLACK);
+    fl_rect(m_cursPosX-5, 
+            m_cursPosY-5, 
+            10, 10, FL_WHITE);
+#endif
+
+}
+
+void Controlar::resize(int x, int y, int w, int h) {
+    #ifdef GL
+        Fl_Gl_Window::resize(x,y,w,h);
+    #else 
+        Fl_Double_Window::resize(x,y,w,h);
+    #endif
+}
+
+CutWindow* Controlar::getWindow(const string& name) {
+    return m_winsMan->getWindow(name);
+}
+
+CutWindow* Controlar::getWindow(const int& win) {
+    return m_winsMan->editWindowList()[win];
+}
+
+void Controlar::cbOpen() {
+    Fl_Native_File_Chooser fnfc;
+    fnfc.title("Open ControlAR File");
+    fnfc.type(Fl_Native_File_Chooser::BROWSE_FILE);
+    if(fnfc.show()==0) {
+        load(fnfc.filename());
+    }
+    m_mainMenu->hide();
+}
+
+
+void Controlar::cbSaveAs() {
+    Fl_Native_File_Chooser fnfc;
+    fnfc.title("Save ControlAR File");
+    fnfc.type(Fl_Native_File_Chooser::BROWSE_SAVE_FILE);
+    if(fnfc.show()==0) {
+        save(fnfc.filename());
+    }
+    m_mainMenu->hide();
+}
+
+void Controlar::cbSave() {
+    if(m_fileName.compare("")!=0) {
+        save(m_fileName);
+    }
+    else {
+        cbSaveAs();
+    }
+    m_mainMenu->hide();
+}
+
+void Controlar::load(const std::string& fileName) {
+
+    DEBUG("Opening "<<fileName);
+    bool open=true;
+    xmlDocPtr doc = xmlReadFile(fileName.c_str(), NULL, 0);
+    xmlNodePtr rootNode = xmlDocGetRootElement(doc);
+    if(doc==NULL || rootNode==NULL) {
+        DEBUG("Could not open file "<<fileName);
+        open=false;
+    }
+    else if(xmlStrcmp(rootNode->name, (const xmlChar*)"ControllAR")) {
+        xmlFreeDoc(doc);
+        DEBUG("Could not open file "<<fileName);
+        open=false;
+    }
+    if(open) { //if the file is valid
+        m_fileName=fileName;
+
+        //delete all widgets
+        map<unsigned int, ZoneWidget*>::iterator itZo = m_zones.begin();
+        for(; itZo!=m_zones.end(); ++itZo) {
+            Fl::delete_widget(itZo->second);
+        }
+        m_zones.clear();
+        m_scenes.clear();
+        map<unsigned int, GroupWidget*>::iterator itGr = m_groups.begin();
+        for(; itGr!=m_groups.end(); ++itGr) {
+            Fl::delete_widget(itGr->second);
+        }
+        m_groups.clear();
+
+        m_winsMan->updateWindowsList();
+
+        //load/create all zone sets and retrieve midi parameters
+        m_currentScene=0;
+        xmlNodePtr sNode;
+        for(sNode=rootNode->children; sNode; sNode=sNode->next) {
+            if(sNode->type == XML_ELEMENT_NODE) {
+                if(!xmlStrcmp(sNode->name, (const xmlChar *)"Group")) {
+                    GroupWidget* wid = new GroupWidget();
+                    addGroup(wid);
+                    wid->load(sNode);
+                }
+                else if(!xmlStrcmp(sNode->name, (const xmlChar *)"Scene")) {
+                    string sceneStr;
+                    char* value = NULL;
+                    value = (char*)xmlGetProp(sNode, (xmlChar*)"name");
+                    if(value!=NULL) {
+                        sceneStr=string(value);
+                    }
+                    m_scenes[m_currentScene]=sceneStr;
+                    m_currentScene++;
+                }
+                else if (!xmlStrcmp(sNode->name, (const xmlChar *)"Zone")) {
+                    ZoneWidget* wid = new ZoneWidget();
+                    addZone(wid);
+                    wid->load(sNode);
+                }
+                else if(!xmlStrcmp(sNode->name, (const xmlChar *)"Midi")) {
+                    char* value = NULL;
+                    value = (char*)xmlGetProp(sNode,(xmlChar*)"device");
+                    if(value!=NULL) {
+                        setMidiDeviceFromName(string(value));
+                    }
+                    value = (char*)xmlGetProp(sNode,(xmlChar*)"set_channel");
+                    if(value!=NULL) {
+                        m_midiChannel=atoi(value);
+                    }
+                    value = (char*)xmlGetProp(sNode,(xmlChar*)"set_type");
+                    if(value!=NULL) {
+                        m_midiType=atoi(value);
+                    }
+                    value = (char*)xmlGetProp(sNode,(xmlChar*)"set_control");
+                    if(value!=NULL) {
+                        m_midiControl=atoi(value);
+                    }
+                }
+            }
+        }
+
+        //set current scene to 0
+        m_currentScene=0;
+        setScene(0);
+        DEBUG("Opened file "<<fileName);
+    }
+    updateTitle();
+    m_mainPanel->hide();
+}
+
+void Controlar::save(const std::string& fileName) {
+    DEBUG("Saving to "<<fileName);
+    xmlDocPtr doc = xmlNewDoc(BAD_CAST "1.0");
+    xmlNodePtr rootNode = xmlNewNode(NULL, BAD_CAST "ControllAR");
+
+    //save groups
+    map<unsigned int, GroupWidget*>::iterator itGr = m_groups.begin();
+    for(; itGr!=m_groups.end(); ++itGr) {
+        itGr->second->save(rootNode);
+    }
+
+    //save scenes
+    map<int, string>::iterator itSc = m_scenes.begin();
+    for(; itSc!=m_scenes.end(); ++itSc) {
+        xmlNewChild(rootNode, NULL, BAD_CAST "Scene", NULL);
+    }
+
+    //save zone
+    map<unsigned int, ZoneWidget*>::iterator itZo = m_zones.begin();
+    for(; itZo!=m_zones.end(); ++itZo) {
+        itZo->second->save(rootNode);
+    }
+
+    //save midi 
+    xmlNodePtr setNode = xmlNewChild(rootNode, NULL, 
+                                     BAD_CAST "Midi", NULL);
+    xmlNewProp(setNode, BAD_CAST "device", 
+               BAD_CAST m_currentMidiDeviceName.c_str());
+    ostringstream oss1, oss2, oss3;
+    oss1<<m_midiChannel;
+    xmlNewProp(setNode, BAD_CAST "set_channel", 
+               BAD_CAST oss1.str().c_str());
+    oss2<<m_midiType;
+    xmlNewProp(setNode, BAD_CAST "set_type", 
+               BAD_CAST oss2.str().c_str());
+    oss3<<m_midiControl;
+    xmlNewProp(setNode, BAD_CAST "set_control", 
+               BAD_CAST oss3.str().c_str());
+
+
+    xmlDocSetRootElement(doc, rootNode);
+    xmlSaveFormatFileEnc(fileName.c_str(), doc, "UTF-8", 1);
+    xmlFreeDoc(doc);
+    xmlCleanupParser();
+    m_fileName=fileName;
+    updateTitle();
+    m_mainPanel->hide();
+}
+
+void Controlar::addZone(ZoneWidget* zone) {
+    unsigned int newID=0;
+    while(m_zones.find(newID)!=m_zones.end()) {
+        newID++;
+    }
+    zone->setID(newID);
+    m_zones[newID] = zone;
+    zone->callback(statZone, this);
+    add(zone);
+    m_zoneMenu->hide();
+}
+
+void Controlar::addGroup(GroupWidget* group) {
+    unsigned int newID=0;
+    while(m_groups.find(newID)!=m_groups.end()) {
+        newID++;
+    }
+    group->setID(newID);
+    m_groups[newID] = group;
+    add(group);
+}
+
+void Controlar::moveAllZonesInsideGroupBy(GroupWidget* group, int dx, int dy) {
+    map<unsigned int, ZoneWidget*>::iterator itZo = m_zones.begin();
+    for(; itZo!=m_zones.end(); ++itZo) {
+        if(itZo->second->x()>group->x() 
+                && itZo->second->x()<group->x()+group->w() 
+                && itZo->second->y()>group->y() 
+                && itZo->second->y()<group->y()+group->h()) {
+            itZo->second->position(itZo->second->x()+dx, 
+                                   itZo->second->y()+dy);
+        }
+    }
+}
+
+void Controlar::cbZoneSelect(CutWindow* win) {
+    m_clickedZone->setCutWin(win);
+    m_zoneMenu->hide();
+}
+
+void Controlar::cbZoneClear() {
+    m_clickedZone->setCutWin(NULL);
+    m_zoneMenu->hide();
+}
+
+void Controlar::cbZoneDelete() {
+    m_zones.erase(m_clickedZone->getID());
+    Fl::delete_widget(m_clickedZone);
+    m_zoneMenu->hide();
+    m_zonePanel->hide();
+}
+
+void Controlar::cbZoneMove() {
+    
+}
+
+void Controlar::cbZoneAlpha(const int& alpha) {
+    m_clickedZone->setAlpha(alpha);
+    m_zoneMenu->hide();
+}
+
+void Controlar::cbZoneTrans(const ZoneWidget::ZONE_TRANSFO& trans) {
+    m_clickedZone->setTransformation(trans);
+    m_zoneMenu->hide();
+}
+
+void Controlar::cbZoneShape(const ZoneWidget::ZONE_SHAPE& shape) {
+    m_clickedZone->setShape(shape);
+    m_zoneMenu->hide();
+}
+
+void Controlar::cbZoneMidiLearn() {
+    m_clickedZone->learnMidi();
+    m_zoneMenu->hide();
+}
+
+void Controlar::cbZoneMidiEffect(const ZoneWidget::ZONE_INPUT_EFFECT& effect) {
+    m_clickedZone->setInputEffect(effect);
+    m_zoneMenu->hide();
+}
+
+void Controlar::cbZoneCol(const ZoneWidget::ZONE_COLOR& col) {
+    m_clickedZone->setColor(col);
+    m_zoneMenu->hide();
+}
+
+void Controlar::cbZoneVisible(const ZoneWidget::ZONE_VISIBLE& vis) {
+    if(vis==ZoneWidget::VISIBLE_CURRENT) {
+        m_clickedZone->setVisible(m_currentScene);
+    }
+    else if(vis==ZoneWidget::VISIBLE_ALL) {
+        m_clickedZone->setVisible();
+    }
+    m_zoneMenu->hide();
+}
+
+void Controlar::cbZoneUpdate(const ZoneWidget::ZONE_UPDATE& up) {
+    if(up==ZoneWidget::UPDATE_CURRENT) {
+        m_clickedZone->setUpdate(m_currentScene);
+    }
+    else if(up==ZoneWidget::UPDATE_ALL) {
+        m_clickedZone->setUpdate();
+    }
+    m_zoneMenu->hide();
+}
+
+void Controlar::cbZoneContent(const ZoneWidget::ZONE_CONTENT& cont) {
+    m_clickedZone->setContent(cont);
+    m_zoneMenu->hide();
+}
+
+void Controlar::init() {
+    this->show();
+}
+
+Controlar::~Controlar() {}
+
+Controlar* Controlar::getInstance() {
+    static Controlar instance;
+    return &instance;
+}
+
+void Controlar::cbQuit() {
+    remove(m_zonePanel);
+    remove(m_mainPanel);
+    exit(0);
+}
+
+void Controlar::cbMidiDev(const int& dev) {
+    if(m_midiStream!=NULL) {
+       Pm_Close(m_midiStream);
+    }
+    Pm_OpenInput(&m_midiStream, dev, NULL, 100, NULL, NULL);
+    const PmDeviceInfo* info = Pm_GetDeviceInfo(dev);
+    m_currentMidiDeviceName = string(info->name);
+    m_mainMenu->hide();
+    m_zoneMenu->hide();
+}
+
+void Controlar::setMidiDeviceFromName(const string& name) {
+    for(unsigned int d=0; d<m_midiDeviceNames.size(); ++d) {
+        if(m_midiDeviceNames[d].compare(name)==0) {
+            cbMidiDev(m_midiDevices[d]);
+        }
+    }
+}
+
+void DetectionWindow::draw() {
+    #ifdef OSX
+    CGRect rect = CGRectMake(0,0,100,100);
+    CGRect deviceRect = CGContextConvertRectToDeviceSpace(fl_gc, rect);
+    Controlar::getInstance()->setDisplayScale(deviceRect.size.width
+                                                / rect.size.width);
+    #endif
+    Fl::delete_widget(this);
+}
+
+
+int main(int argc, char* argv[]) {
+    #ifndef GL
+    Fl::visual(FL_DOUBLE|FL_RGB);
+    #endif
+
+    //first grab the display scale 
+    DetectionWindow* detWin = new DetectionWindow();
+    detWin->show();
+
+    //then init controllar
+    Controlar::getInstance()->init();
+    fl_cursor(FL_CURSOR_NONE);
+    return Fl::run();
+}
+
+
diff --git a/src/Controlar.hpp b/src/Controlar.hpp
new file mode 100755
index 0000000..13ed121
--- /dev/null
+++ b/src/Controlar.hpp
@@ -0,0 +1,372 @@
+/***************************************************************************
+ *  Controlar.hpp
+ *  Part of ControllAR
+ *  2016-  Florent Berthaut
+ *  hitmuri.net
+ ****************************************************************************/
+/*
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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 General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#ifndef Controlar_h
+#define Controlar_h
+
+#include <string>
+#include <map>
+#include <vector>
+#include <sys/time.h>
+
+#ifdef GL
+#include <FL/Fl_Gl_Window.H>
+#else
+#include <FL/Fl_Double_Window.H>
+#endif
+
+#include <FL/Fl_Tile.H>
+#include <FL/Fl_Pack.H>
+#include <FL/Fl_Scroll.H>
+#include <FL/Fl_Hold_Browser.H>
+#include <FL/Fl_Menu_Button.H>
+#include <FL/Fl_Toggle_Button.H>
+#include <FL/Fl_Native_File_Chooser.H>
+#include <FL/Fl.H>
+#include <FL/fl_draw.H>
+#include <FL/Fl_Overlay_Window.H>
+
+#include <portmidi.h>
+
+#include "osc/ip/IpEndpointName.h"
+#include "osc/ip/UdpSocket.h"
+#include "osc/osc/OscPacketListener.h"
+
+#include "FlipMenu.hpp"
+#include "ZoneWidget.hpp"
+#include "GroupWidget.hpp"
+#include "CutWindowsManager.hpp"
+class MainPanel;
+class ZonePanel;
+
+#define IP_MTU_SIZE 2048
+
+#ifdef GL
+class Controlar: public Fl_Gl_Window, public osc::OscPacketListener {
+#else 
+class Controlar: public Fl_Double_Window, public osc::OscPacketListener  {
+#endif
+    public:
+        static Controlar* getInstance();
+        ~Controlar();
+        void init();
+        void load(const std::string& fileName);
+        void save(const std::string& fileName);
+
+        void update();
+        int handle(int event);
+        void draw();
+        void resize(int x, int y, int w, int h);
+        CutWindow* getWindow(const std::string& name);
+        inline int getNbWindows() {return m_winsMan->getNbWindows();}
+        CutWindow* getWindow(const int&);
+        void addZone(ZoneWidget*);
+        void addGroup(GroupWidget*);
+        void moveAllZonesInsideGroupBy(GroupWidget*, int dx, int dy);
+        void refreshWindowList();
+
+        //ZONE CALLBACKS
+        static void statZone(Fl_Widget* w, void* f){ 
+            Controlar *tmpf = static_cast<Controlar *>(f);
+            tmpf->cbZone(w);
+        }    
+        void cbZone(Fl_Widget*);
+
+        static void statZoneSelect(Fl_Widget* w, void* f){ 
+            Controlar::getInstance()->cbZoneSelect(static_cast<CutWindow*>(f));
+        }    
+        void cbZoneSelect(CutWindow*);
+        static void statZoneClear(Fl_Widget* w, void* f){ 
+            Controlar::getInstance()->cbZoneClear();
+        }    
+        void cbZoneClear();
+        static void statZoneDelete(Fl_Widget* w, void* f){ 
+            Controlar::getInstance()->cbZoneDelete();
+        }    
+        void cbZoneDelete();
+        static void statZoneMove(Fl_Widget* w, void* f){ 
+            Controlar::getInstance()->cbZoneMove();
+        }    
+        void cbZoneMove();
+        static void statZoneAlpha(Fl_Widget* w, void* f){ 
+            Controlar::getInstance()->cbZoneAlpha(*((int*)f));
+        }    
+        void cbZoneAlpha(const int& alpha);
+        static void statZoneShape(Fl_Widget* w, void* f){ 
+            Controlar::getInstance()
+                ->cbZoneShape(*((ZoneWidget::ZONE_SHAPE*)f));
+        }    
+        void cbZoneShape(const ZoneWidget::ZONE_SHAPE& shape);
+        static void statZoneTrans(Fl_Widget* w, void* f){ 
+            Controlar::getInstance()
+                ->cbZoneTrans(*((ZoneWidget::ZONE_TRANSFO*)f));
+        }    
+        void cbZoneTrans(const ZoneWidget::ZONE_TRANSFO& trans);
+        static void statZoneMidiLearn(Fl_Widget* w, void* f){ 
+            Controlar::getInstance()->cbZoneMidiLearn();
+        }    
+        void cbZoneMidiLearn();
+        static void statZoneMidiEffect(Fl_Widget* w, void* f){ 
+            Controlar::getInstance()
+                ->cbZoneMidiEffect(*((ZoneWidget::ZONE_INPUT_EFFECT*)f));
+        }    
+        void cbZoneMidiEffect(const ZoneWidget::ZONE_INPUT_EFFECT& trans);
+        static void statZoneCol(Fl_Widget* w, void* f){ 
+            Controlar::getInstance()->cbZoneCol(*((ZoneWidget::ZONE_COLOR*)f));
+        }    
+        void cbZoneCol(const ZoneWidget::ZONE_COLOR& col);
+        static void statZoneVisible(Fl_Widget* w, void* f){ 
+            Controlar::getInstance()
+                        ->cbZoneVisible(*((ZoneWidget::ZONE_VISIBLE*)f));
+        }    
+        void cbZoneVisible(const ZoneWidget::ZONE_VISIBLE& vis);
+        static void statZoneUpdate(Fl_Widget* w, void* f){ 
+            Controlar::getInstance()
+                        ->cbZoneUpdate(*((ZoneWidget::ZONE_UPDATE*)f));
+        }    
+        void cbZoneUpdate(const ZoneWidget::ZONE_UPDATE& up);
+        static void statZoneContent(Fl_Widget* w, void* f){ 
+            Controlar::getInstance()
+                        ->cbZoneContent(*((ZoneWidget::ZONE_CONTENT*)f));
+        }    
+        void cbZoneContent(const ZoneWidget::ZONE_CONTENT& up);
+
+        //MAIN CALLBACKS
+        static void statOpen(Fl_Widget* w,void* f){ 
+            Controlar *tmpf = static_cast<Controlar *>(f);
+            tmpf->cbOpen();
+        }    
+        void cbOpen();
+
+        static void statSave(Fl_Widget* w, void* f){ 
+            Controlar::getInstance()->cbSave();
+        }    
+        void cbSave();
+        static void statSaveAs(Fl_Widget* w, void* f){ 
+            Controlar::getInstance()->cbSaveAs();
+        }    
+        void cbSaveAs();
+
+        static void statSceneNext(Fl_Widget* w, void* f){ 
+            Controlar::getInstance()->cbSceneNext();
+        }    
+        void cbSceneNext();
+        static void statScenePrev(Fl_Widget* w, void* f){ 
+            Controlar::getInstance()->cbScenePrev();
+        }    
+        void cbScenePrev();
+/*
+        static void statSetDup(Fl_Widget* w,void* f){ 
+            Controlar::getInstance()->cbSetDuplicate();
+        }    
+        void cbSetDuplicate();
+*/
+        static void statSceneDel(Fl_Widget* w,void* f){ 
+            Controlar::getInstance()->cbSceneDelete();
+        }    
+        void cbSceneDelete();
+        static void statSceneLearn(Fl_Widget* w,void* f){ 
+            Controlar::getInstance()->cbSceneLearn();
+        }    
+        void cbSceneLearn();
+        void setScene(const int&);
+
+        static void statFlip(Fl_Widget* w,void* f){ 
+            Controlar::getInstance()->cbFlip();
+        }    
+        void cbFlip();
+        inline bool isFlipped(){return m_flipped;}
+        
+        static void statFullscreen(Fl_Widget* w,void* f){ 
+            Controlar::getInstance()->cbFullscreen();
+        }    
+        void cbFullscreen();
+        static void statMidiDev(Fl_Widget* w,void* f){ 
+            Controlar::getInstance()->cbMidiDev(*(int*)(f));
+        }    
+        void cbMidiDev(const int&);
+        void setMidiDeviceFromName(const std::string&);
+
+        static void statQuit(Fl_Widget* w,void* f){ 
+            Controlar *tmpf = static_cast<Controlar *>(f);
+            tmpf->cbQuit();
+        }    
+        void cbQuit();
+        static void statZoneMenuWin(Fl_Widget* w, void* f){ 
+            static_cast<ZoneWidget*>(w)->setCutWin(static_cast<CutWindow*>(f));
+        }    
+
+        void parseMidi();
+        void openMidiDevice(const std::string& devName);
+        void closeMidiDevice(const std::string& devName);
+        void refreshMidiStreams();
+        void detectMidiDevices();
+        void updateTitle();
+
+        ZoneWidget* startDuplicating(ZoneWidget* dupWid);
+
+        virtual void ProcessMessage(const osc::ReceivedMessage& m,
+                                    const IpEndpointName& remoteEndpoint);
+
+        inline const int& getDisplayScale(){return m_displayScale;}
+        inline void setDisplayScale(const int& s){m_displayScale=s;}
+
+#ifdef GL
+        void initGL();
+        inline GLint getZoneSizeUniform(){return m_zoneSizeUniform;}
+        inline GLint getZonePosUniform(){return m_zonePosUniform;}
+        inline GLint getCutSizeUniform(){return m_cutSizeUniform;}
+        inline GLint getCutPosUniform(){return m_cutPosUniform;}
+        inline GLint getZoneStateUniform(){return m_zoneStateUniform;}
+        inline GLint getZoneWindowUniform(){return m_zoneWindowUniform;}
+        inline GLint getZoneCoordsUniform(){return m_zoneCoordsUniform;}
+        inline GLint getZoneFilledUniform(){return m_zoneFilledUniform;}
+        inline GLint getZoneAlphaUniform(){return m_zoneAlphaUniform;}
+        inline GLint getZoneInvertUniform(){return m_zoneInvertUniform;}
+        inline GLint getGroupSizeUniform(){return m_groupSizeUniform;}
+        inline GLint getGroupPosUniform(){return m_groupPosUniform;}
+        inline GLint getGroupEditingUniform(){return m_groupEditingUniform;}
+        inline GLint getGroupHighlightUniform(){return m_groupHighlightUniform;}
+        inline GLint getMenuSizeUniform(){return m_menuSizeUniform;}
+        inline GLint getMenuPosUniform(){return m_menuPosUniform;}
+        inline GLuint getFirstTextureID(){return m_firstTextureID;}
+        inline GLuint getSecondTextureID(){return m_secondTextureID;}
+        inline const std::string& getCurrentWindowName() { 
+            return m_currentWindowName;
+        }
+        inline void setCurrentWindowName(const std::string& n) { 
+            m_currentWindowName=n;
+        }
+#endif
+        
+    protected:  
+        friend void* oscThreadFunction(void*);
+
+    protected:
+        UdpListeningReceiveSocket* m_socket;
+
+    private:
+        Controlar();
+        std::string m_title;
+        std::string m_fileName;
+        int m_drawStartX, m_drawStartY;
+        int m_drawCurX, m_drawCurY;
+        bool m_drawing, m_drawingGroup;
+        FlipMenu* m_zoneMenu;
+        FlipMenu* m_mainMenu;
+        MainPanel* m_mainPanel;
+        ZonePanel* m_zonePanel;
+        CutWindowsManager* m_winsMan;
+        //std::vector<std::map<unsigned int, ZoneWidget*> > m_zonesSets;
+        std::map<int, std::string> m_scenes;
+        std::map<unsigned int, ZoneWidget*> m_zones;
+        std::map<unsigned int, GroupWidget*> m_groups;
+        int m_alphaLevels[4];
+        int m_menuValues[10];
+        //unsigned int m_currentSet;
+        int m_currentScene;
+        ZoneWidget* m_clickedZone;
+        bool m_flipped;
+        bool m_fullscreen;
+        bool m_duplicating;
+        ZoneWidget* m_duplicatedZone;
+        PortMidiStream* m_midiStream;
+        std::map<std::string, int> m_midiDevMap;
+        std::map<std::string, PortMidiStream*> m_midiStreamsMap;
+        std::vector<PortMidiStream*> m_midiStreamsVec;
+        bool m_midiLearning;
+        int m_midiType;
+        int m_midiChannel;
+        int m_midiControl;
+        std::vector<int> m_midiDevices;
+        std::vector<std::string> m_midiDeviceNames;
+        std::string m_currentMidiDeviceName;
+        pthread_t m_oscThread;
+        pthread_mutex_t m_zonesMutex;
+        int m_askedScene;
+        int m_displayScale;
+
+#ifdef GL
+        GLuint m_vertexArrayID;
+        GLuint m_vertexBuffer;
+        GLfloat m_vertexBufferData[18];
+
+        GLuint m_zoneProgram;
+        GLint m_zoneWinSizeUniform;
+        GLint m_zoneSizeUniform;
+        GLint m_zonePosUniform;
+        GLint m_cutSizeUniform;
+        GLint m_cutPosUniform;
+        GLint m_zoneMirrorUniform;
+        GLint m_zoneStateUniform;
+        GLint m_zoneFilledUniform;
+        GLint m_zoneAlphaUniform;
+        GLint m_zoneInvertUniform;
+        GLint m_zoneWindowUniform;
+        GLint m_zoneCoordsUniform;
+        GLint m_zoneOuterUniform;
+        GLint m_zoneInnerUniform;
+
+        GLuint m_cursorProgram;
+        GLint m_cursorWinSizeUniform;
+        GLint m_cursorPosUniform;
+        GLint m_cursorMirrorUniform;
+
+        GLuint m_drawingProgram;
+        GLint m_drawWinSizeUniform;
+        GLint m_drawPosUniform;
+        GLint m_drawSizeUniform;
+        GLint m_drawMirrorUniform;
+        GLint m_drawGroupUniform;
+
+        GLuint m_menuProgram;
+        GLint m_menuWinSizeUniform;
+        GLint m_menuPosUniform;
+        GLint m_menuSizeUniform;
+        GLint m_menuMirrorUniform;
+        GLint m_menuTextureUniform;
+        GLuint m_firstTextureID;
+        GLuint m_secondTextureID;
+        std::string m_currentWindowName;
+        
+        GLuint m_groupProgram;
+        GLint m_groupWinSizeUniform;
+        GLint m_groupPosUniform;
+        GLint m_groupSizeUniform;
+        GLint m_groupMirrorUniform;
+        GLint m_groupEditingUniform;
+        GLint m_groupHighlightUniform;
+#else
+        int m_cursPosX;
+        int m_cursPosY;
+#endif
+};
+
+class DetectionWindow: public Fl_Double_Window {
+    public:
+        DetectionWindow():Fl_Double_Window(10, 10, ""){}
+        void draw();
+};
+
+#endif
+
diff --git a/src/CutWindow.hpp b/src/CutWindow.hpp
new file mode 100644
index 0000000..3fdffd3
--- /dev/null
+++ b/src/CutWindow.hpp
@@ -0,0 +1,86 @@
+/***************************************************************************
+ *  CutWindow.hpp
+ *  Part of Controlar
+ *  2016-  Florent Berthaut
+ *  hitmuri.net
+ ****************************************************************************/
+/*
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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 General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#ifndef CutWindow_h
+#define CutWindow_h
+
+#include <vector>
+#include <map>
+#include <string>
+
+#include <FL/Fl.H>
+#include <FL/Fl_RGB_Image.H>
+
+class CutWindowsManager;
+#include "ZoneWidget.hpp"
+
+class CutWindow {
+    public :
+        CutWindow(CutWindowsManager* man):m_winsMan(man){}
+        virtual ~CutWindow(){}
+
+        void setName(const std::string& name){m_name=name;}
+        const std::string& getName(){return m_name;}
+        virtual void getPixels(const int& x, const int& y, 
+                               const int& sx, const int& sy,
+                               const std::vector<int>& srcIndices,
+                               const std::vector<std::vector<int> >& srcCoords,
+                               const std::vector<int>& destIndices,
+                               const uchar& alpha,
+                               const ZoneWidget::ZONE_COLOR& color,
+                               uchar* destImg)=0;
+        
+        virtual int computeNbPixPerRow(const int& srcW, const int& srcH)=0;
+        inline const int& getWidth(){return m_width;}
+        inline const int& getHeight(){return m_height;}
+        inline const int& getOffsetX(){return m_offsetX;}
+        inline const int& getOffsetY(){return m_offsetY;}
+        inline const int& getPixPerRow(){return m_pixPerRow;}
+        inline bool isBGR(){return m_isBGR;}
+        inline bool needsOffset(){return m_needsOffset;}
+        inline void setWinID(const int& id){m_winID=id;}
+        inline const int& getWinID(){return m_winID;}
+    
+        virtual uchar* grabImage()=0;
+        virtual void releaseImage()=0;
+
+        virtual void storeImage(const int& id)=0;
+        virtual uchar* retrieveImage(const int& id)=0;
+
+    protected:
+        int m_winID;
+        std::string m_name;
+        int m_posX, m_posY, m_width, m_height;
+        int m_offsetX, m_offsetY, m_pixPerRow;
+        bool m_isBGR;
+        bool m_needsOffset;
+        CutWindowsManager* m_winsMan;
+        bool m_grabbed;
+        uchar* m_imgData;
+        uchar* m_defaultImgData;
+
+        std::map<int, uchar*> m_storedImgData;
+};
+
+#endif
+
diff --git a/src/CutWindowsManager.hpp b/src/CutWindowsManager.hpp
new file mode 100644
index 0000000..6d44f66
--- /dev/null
+++ b/src/CutWindowsManager.hpp
@@ -0,0 +1,58 @@
+/***************************************************************************
+ *  CutWindowsManager.hpp
+ *  Part of Over 
+ *  2013  Florent Berthaut
+ *  hitmuri.net
+ ****************************************************************************/
+/*
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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 General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#ifndef CutWindowsManager_h
+#define CutWindowsManager_h
+
+#include <vector>
+#include <string>
+#include <iostream>
+
+#include "CutWindow.hpp"
+
+class CutWindowsManager {
+    public :
+        CutWindowsManager(){}
+        virtual ~CutWindowsManager(){}
+
+        virtual void updateWindowsList()=0;
+        std::vector<CutWindow*>& editWindowList(){return m_windowList;}
+        CutWindow* getWindow(const std::string& name) {
+            CutWindow* res=NULL;
+            std::vector<CutWindow*>::iterator itWin=m_windowList.begin();
+            for(; itWin!=m_windowList.end(); ++itWin) {
+                if((*itWin)->getName().compare(name)==0 && name.compare("")!=0){
+                    res=(*itWin);
+                }
+            }
+            return res;
+        }
+        int getNbWindows(){return m_windowList.size();}
+
+    protected:
+        std::vector<CutWindow*> m_windowList;
+        std::map<unsigned int, CutWindow*> m_windowMap;
+};
+
+#endif
+
diff --git a/src/FlipGroup.cpp b/src/FlipGroup.cpp
new file mode 100644
index 0000000..5a06987
--- /dev/null
+++ b/src/FlipGroup.cpp
@@ -0,0 +1,96 @@
+/***************************************************************************
+ *  FlipGroup.cpp
+ *  Part of 
+ *  2016-  Florent Berthaut
+ *  hitmuri.net
+ ****************************************************************************/
+/*
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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 General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "FlipGroup.hpp"
+#include <FL/Fl_Button.H>
+#include <FL/fl_draw.H>
+#include <algorithm>
+#include <iostream>
+#include "Controlar.hpp"
+
+using namespace std;
+
+FlipGroup::FlipGroup(int x, int y, int w, int h): Fl_Group(x, y, w, h, "") {
+    end();
+    box(FL_FLAT_BOX);
+    m_wasChanged=true;
+}
+
+void FlipGroup::draw() {
+    Controlar* cont = Controlar::getInstance();
+    if(m_wasChanged) {
+        Fl_Image_Surface* surf = new Fl_Image_Surface(w(), h());
+        surf->set_current();
+        fl_draw_box(box(), 0, 0, 
+                    w(), h(), color());
+        for(int c=0; c<children(); ++c) {
+            surf->draw(child(c), 
+                       child(c)->x()-x(), 
+                       child(c)->y()-y());
+        }
+        m_flipImg = surf->image();
+        delete surf;
+        Fl_Display_Device::display_device()->set_current();
+        m_wasChanged=false;
+    }
+#ifdef GL
+    glActiveTexture(GL_TEXTURE0);
+    glBindTexture(GL_TEXTURE_2D, cont->getFirstTextureID());
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
+                 w(), h(),
+                 0, GL_RGB, GL_UNSIGNED_BYTE,
+                 m_flipImg->array);
+    glUniform2f(cont->getMenuPosUniform(), x(), y());
+    glUniform2f(cont->getMenuSizeUniform(), w(), h());
+    glDrawArrays(GL_TRIANGLES, 0, 6);
+#else 
+    fl_draw_image(statDrawFlipImg, this, 
+                  x(), cont->isFlipped()?cont->h()-y()-h():y(), 
+                  w(), h(), m_flipImg->d());
+#endif
+}
+
+int FlipGroup::handle(int event) {
+    int res=Fl_Group::handle(event);
+    if(res) {
+        refresh();
+    }
+    return 1;
+}
+
+void FlipGroup::resize(int x, int y, int w, int h) {
+    Fl_Group::resize(x,y,w,h);
+    m_wasChanged=true;
+}
+
+void FlipGroup::refresh() {
+    m_wasChanged=true;
+    redraw();
+}
+
+void FlipGroup::addWid(Fl_Widget* wid) {
+    m_wasChanged=true;
+    add(wid);
+    wid->box(FL_BORDER_BOX);
+    wid->visible_focus(0);
+}
+
diff --git a/src/FlipGroup.hpp b/src/FlipGroup.hpp
new file mode 100644
index 0000000..312e34c
--- /dev/null
+++ b/src/FlipGroup.hpp
@@ -0,0 +1,49 @@
+/***************************************************************************
+ *  FlipGroup.hpp
+ *  Part of ControllAR
+ *  2016-  Florent Berthaut
+ *  hitmuri.net
+ ****************************************************************************/
+/*
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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 General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#ifndef FlipGroup_h
+#define FlipGroup_h
+
+#include <string>
+#include <map>
+#include <vector>
+
+#include <FL/Fl_Pack.H>
+#include <FL/Fl_Button.H>
+#include <FL/Fl_Image_Surface.H>
+
+class FlipGroup: public Fl_Group {
+    public :
+        FlipGroup(int x, int y, int w, int h);
+        void draw();
+        int handle(int event);
+        void addWid(Fl_Widget*);
+        void resize(int x, int y, int w, int h);
+        void refresh();
+
+    protected:
+        Fl_RGB_Image* m_flipImg;
+        bool m_wasChanged;
+};
+
+#endif
diff --git a/src/FlipMenu.cpp b/src/FlipMenu.cpp
new file mode 100644
index 0000000..422dd92
--- /dev/null
+++ b/src/FlipMenu.cpp
@@ -0,0 +1,377 @@
+/***************************************************************************
+ *  FlipMenu.cpp
+ *  Part of 
+ *  2016-  Florent Berthaut
+ *  hitmuri.net
+ ****************************************************************************/
+/*
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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 General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "FlipMenu.hpp"
+#include <FL/Fl_Button.H>
+#include <FL/fl_draw.H>
+#include <algorithm>
+#include <iostream>
+#include "Controlar.hpp"
+
+using namespace std;
+
+FlipMenu::FlipMenu():Fl_Pack(0, 0, 100, 100, "") {
+    type(Fl_Pack::VERTICAL);
+    end();
+}
+
+void FlipMenu::addWithSub(const std::string& itemName,Fl_Callback* cb,void* p) {
+    //parse submenu, create flip menu if needed  
+    size_t pos = itemName.find_first_of('/');
+    if(pos==string::npos) {
+        add(itemName, cb, p);
+    }
+    else {
+        string subName = itemName.substr(0, pos);
+        addSub(subName);
+        string subItemName = itemName.substr(pos+1);
+        m_subMenuMap[subName]->add(subItemName, cb, p);
+    }
+}
+
+void FlipMenu::add(const std::string& itemName, Fl_Callback* cb, void* p) {
+    FlipItem* but = new FlipItem(this);
+    but->copy_label(itemName.c_str());
+    but->callback(cb, p);
+    Fl_Pack::add(but);
+    resize(0, 0, 
+           max(w(), 
+                int(float(itemName.length()*FL_NORMAL_SIZE)/4.0)*4), 
+                children()*20);
+}
+
+void FlipMenu::addSub(const string& subName) {
+    if(m_subMenuMap.find(subName)==m_subMenuMap.end()) {
+        m_subMenuMap[subName] = new FlipMenu();
+        FlipItemMenu* men = new FlipItemMenu(this, m_subMenuMap[subName]);
+        men->copy_label(subName.c_str());
+        Fl_Pack::add(men);
+    }
+}
+
+FlipMenu* FlipMenu::getSub(const string& subName) {
+    FlipMenu* res=NULL;
+    if(m_subMenuMap.find(subName)!=m_subMenuMap.end()) {
+        res=m_subMenuMap[subName];
+    }
+    return res;
+}
+
+void FlipMenu::clear() {
+    map<string, FlipMenu*>::iterator itSub = m_subMenuMap.begin();
+    for(; itSub!=m_subMenuMap.end(); ++itSub) {
+        itSub->second->clear();
+        Controlar::getInstance()->remove(itSub->second);
+        Fl::delete_widget(itSub->second);
+    }
+    m_subMenuMap.clear();
+    Fl_Pack::clear();
+    resize(x(), y(), 100, 100);
+}
+
+void FlipMenu::hide() {
+    Fl_Pack::hide();
+    hideSubMenus();
+}
+
+void FlipMenu::draw() {
+    Fl_Pack::draw();
+}
+
+void FlipMenu::hideSubMenus() {
+    map<string, FlipMenu*>::iterator itSub = m_subMenuMap.begin();
+    for(; itSub!=m_subMenuMap.end(); ++itSub) {
+        itSub->second->hide();
+    }
+}
+
+
+//--------------------------------ITEM MENU
+FlipItemMenu::FlipItemMenu(FlipMenu* men, FlipMenu* subMen):
+                                          Fl_Button(0,0,20,20,""), 
+                                          m_menu(men),
+                                          m_subMenu(subMen) {
+    align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE);
+    box(FL_THIN_DOWN_BOX);
+    visible_focus(false);
+    m_wasResized=true;
+    m_highlight=false;
+}
+
+int FlipItemMenu::handle(int event) {
+    switch(event) {
+        case FL_ENTER: { 
+            m_menu->hideSubMenus();
+            color(FL_SELECTION_COLOR);
+            m_subMenu->position(x()+w(), y());
+            Controlar* cont = Controlar::getInstance();
+            cont->insert(*m_subMenu, cont->children());
+            m_subMenu->show();
+            m_highlight=true;
+            return 1;
+        }break;
+        case FL_LEAVE: { 
+            color(FL_BACKGROUND_COLOR);
+            m_highlight=false;
+            return 1; 
+        }break;
+        default:break;
+    }
+    return 0;
+}
+
+void FlipItemMenu::resize(int x, int y, int w, int h) {
+    Fl_Button::resize(x,y,w,h);
+    m_wasResized=true;
+}
+
+void FlipItemMenu::draw() {
+    Controlar* cont = Controlar::getInstance();
+    if(m_wasResized) {
+        Fl_Image_Surface* surf = new Fl_Image_Surface(w(), h());
+        surf->set_current();
+        fl_draw_box(box(), 0, 0, 
+                    w(), h(), color());
+        fl_color(FL_BLACK);
+        fl_draw(label(), 
+                0, 0, 
+                w(), h(), 
+                align(), NULL, 0);
+        m_flipImg = surf->image();
+        delete surf;
+
+        Fl_Display_Device::display_device()->set_current();
+        surf = new Fl_Image_Surface(w(), h());
+        surf->set_current();
+        fl_draw_box(box(), 0, 0, 
+                    w(), h(), FL_SELECTION_COLOR);
+        fl_color(FL_BLACK);
+        fl_draw(label(), 
+                0, 0, 
+                w(), h(), 
+                align(), NULL, 0);
+        m_flipImgH = surf->image();
+        delete surf;
+
+        Fl_Display_Device::display_device()->set_current();
+        m_wasResized=false;
+    }
+
+#ifdef GL
+    glActiveTexture(GL_TEXTURE0);
+    glBindTexture(GL_TEXTURE_2D, cont->getFirstTextureID());
+    if(m_highlight) {
+        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
+                     w(), h(),
+                     0, GL_RGB, GL_UNSIGNED_BYTE,
+                     m_flipImgH->array);
+    }
+    else {
+        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
+                     w(), h(),
+                     0, GL_RGB, GL_UNSIGNED_BYTE,
+                     m_flipImg->array);
+    }
+    glUniform2f(cont->getMenuPosUniform(), x(), y());
+    glUniform2f(cont->getMenuSizeUniform(), w(), h());
+    glDrawArrays(GL_TRIANGLES, 0, 6);
+#else 
+    if(m_highlight) {
+        fl_draw_image(statDrawFlipImg, this, 
+                      x(), cont->isFlipped()?cont->h()-y()-h():y(), 
+                      w(), h(), m_flipImgH->d());
+    }
+    else {
+        fl_draw_image(statDrawFlipImg, this, 
+                      x(), cont->isFlipped()?cont->h()-y()-h():y(), 
+                      w(), h(), m_flipImg->d());
+    }
+#endif
+    if(m_subMenu->visible()) {
+        m_subMenu->draw();
+    }
+}
+
+void FlipItemMenu::drawFlipImg(int x, int y, int w, uchar* buf) {
+    if(Controlar::getInstance()->isFlipped()) {
+        if(m_highlight) {
+            memcpy(buf, 
+                   &m_flipImgH->array[((m_flipImgH->h()-y)*m_flipImgH->w()+x)
+                        *m_flipImgH->d()], 
+                   w*m_flipImgH->d());
+        }
+        else {
+            memcpy(buf, 
+                   &m_flipImg->array[((m_flipImg->h()-y)*m_flipImg->w()+x)
+                        *m_flipImg->d()], 
+                   w*m_flipImg->d());
+        }
+    }
+    else {
+        if(m_highlight) {
+            memcpy(buf, 
+                   &m_flipImgH->array[(y*m_flipImgH->w()+x)*m_flipImgH->d()], 
+                   w*m_flipImgH->d());
+        }
+        else {
+            memcpy(buf, 
+                   &m_flipImg->array[(y*m_flipImg->w()+x)*m_flipImg->d()], 
+                   w*m_flipImg->d());
+        }
+    }
+}
+
+//-------------------------------ITEM 
+FlipItem::FlipItem(FlipMenu* men):Fl_Button(0,0,20,20,""),
+                                  m_menu(men) {
+    align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE);
+    box(FL_THIN_UP_BOX);
+    visible_focus(false);
+    m_wasResized=true;
+    m_highlight=false;
+}
+
+int FlipItem::handle(int event) {
+    switch(event) {
+        case FL_ENTER: { 
+            m_menu->hideSubMenus();
+            color(FL_SELECTION_COLOR);
+            m_highlight=true;
+            return 1;
+        }break;
+        case FL_LEAVE: { 
+            color(FL_BACKGROUND_COLOR);
+            m_highlight=false;
+            return 1; 
+        }break;
+        case FL_PUSH: {
+            if(Fl::event_button()==FL_LEFT_MOUSE) {
+                do_callback();
+                color(FL_BACKGROUND_COLOR);
+                m_menu->hide();
+                return 1;
+            }
+        }break;
+        default:break;
+    }
+    return 0;
+}
+
+void FlipItem::resize(int x, int y, int w, int h) {
+    Fl_Button::resize(x,y,w,h);
+    m_wasResized=true;
+}
+
+void FlipItem::draw() {
+
+    Controlar* cont = Controlar::getInstance();
+    if(m_wasResized) {
+        Fl_Image_Surface* surf = new Fl_Image_Surface(w(), h());
+        surf->set_current();
+        fl_draw_box(box(), 0, 0, 
+                    w(), h(), color());
+        fl_color(FL_BLACK);
+        fl_draw(label(), 
+                0, 0, 
+                w(), h(), 
+                align(), NULL, 0);
+        m_flipImg = surf->image();
+        delete surf;
+
+        Fl_Display_Device::display_device()->set_current();
+        surf = new Fl_Image_Surface(w(), h());
+        surf->set_current();
+        fl_draw_box(box(), 0, 0, 
+                    w(), h(), FL_SELECTION_COLOR);
+        fl_color(FL_BLACK);
+        fl_draw(label(), 
+                0, 0, 
+                w(), h(), 
+                align(), NULL, 0);
+        m_flipImgH = surf->image();
+
+        delete surf;
+        Fl_Display_Device::display_device()->set_current();
+        m_wasResized=false;
+    }
+
+#ifdef GL
+    glActiveTexture(GL_TEXTURE0);
+    glBindTexture(GL_TEXTURE_2D, cont->getFirstTextureID());
+    if(m_highlight) {
+        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
+                     w(), h(),
+                     0, GL_RGB, GL_UNSIGNED_BYTE,
+                     m_flipImgH->array);
+    }
+    else {
+        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
+                     w(), h(),
+                     0, GL_RGB, GL_UNSIGNED_BYTE,
+                     m_flipImg->array);
+    }
+    glUniform2f(cont->getMenuPosUniform(), x(), y());
+    glUniform2f(cont->getMenuSizeUniform(), w(), h());
+    glDrawArrays(GL_TRIANGLES, 0, 6);
+#else 
+    if(m_highlight) {
+        fl_draw_image(statDrawFlipImg, this, 
+                      x(), cont->isFlipped()?cont->h()-y()-h():y(), 
+                      w(), h(), m_flipImgH->d());
+    }
+    else {
+        fl_draw_image(statDrawFlipImg, this, 
+                      x(), cont->isFlipped()?cont->h()-y()-h():y(), 
+                      w(), h(), m_flipImg->d());
+    }
+#endif
+}
+
+void FlipItem::drawFlipImg(int x, int y, int w, uchar* buf) {
+    if(Controlar::getInstance()->isFlipped()) {
+        if(m_highlight) {
+            memcpy(buf, 
+                   &m_flipImgH->array[((m_flipImgH->h()-y)*m_flipImgH->w()+x)
+                        *m_flipImgH->d()], 
+                   w*m_flipImgH->d());
+        }
+        else {
+            memcpy(buf, 
+                   &m_flipImg->array[((m_flipImg->h()-y)*m_flipImg->w()+x)
+                        *m_flipImg->d()], 
+                   w*m_flipImg->d());
+        }
+    }
+    else {
+        if(m_highlight) {
+            memcpy(buf, 
+                   &m_flipImgH->array[(y*m_flipImgH->w()+x)*m_flipImgH->d()], 
+                   w*m_flipImgH->d());
+        }
+        else {
+            memcpy(buf, 
+                   &m_flipImg->array[(y*m_flipImg->w()+x)*m_flipImg->d()], 
+                   w*m_flipImg->d());
+        }
+    }
+}
+
diff --git a/src/FlipMenu.hpp b/src/FlipMenu.hpp
new file mode 100644
index 0000000..bcbaa87
--- /dev/null
+++ b/src/FlipMenu.hpp
@@ -0,0 +1,99 @@
+/***************************************************************************
+ *  FlipMenu.hpp
+ *  Part of 
+ *  2016-  Florent Berthaut
+ *  hitmuri.net
+ ****************************************************************************/
+/*
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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 General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#ifndef FlipMenu_h
+#define FlipMenu_h
+
+#include <string>
+#include <map>
+#include <vector>
+
+#include <FL/Fl_Pack.H>
+#include <FL/Fl_Button.H>
+#include <FL/Fl_Image_Surface.H>
+#include <map>
+#include <string>
+
+class FlipItemMenu;
+class FlipItem;
+
+class FlipMenu: public Fl_Pack {
+    public :
+        FlipMenu();
+        void draw();
+        void addWithSub(const std::string& itemName, Fl_Callback*, void* p);
+        void add(const std::string& itemName, Fl_Callback*, void* p);
+        void addSub(const std::string& subName);
+        FlipMenu* getSub(const std::string& subName);
+        void hide();
+        void clear();
+        void hideSubMenus();
+
+    private:
+        std::map<std::string, FlipMenu*> m_subMenuMap;
+
+};
+
+class FlipItemMenu : public Fl_Button {
+    public :
+        FlipItemMenu(FlipMenu* menu, FlipMenu* subMenu);
+        int handle(int event);
+        void draw();
+        void resize(int x, int y, int w, int h);
+        static void statDrawFlipImg(void *data,int x,int y, int w, uchar *buf) {
+            FlipItemMenu *item = static_cast<FlipItemMenu*>(data);
+            item->drawFlipImg(x, y, w, buf);
+        }
+        void drawFlipImg(int x, int y, int w, uchar* buf);
+
+    private:
+        FlipMenu* m_menu;
+        FlipMenu* m_subMenu;
+        Fl_RGB_Image* m_flipImg;
+        Fl_RGB_Image* m_flipImgH;
+        bool m_wasResized;
+        bool m_highlight;
+};
+
+class FlipItem : public Fl_Button {
+    public :
+        FlipItem(FlipMenu*);
+        int handle(int event);
+        void draw();
+        void resize(int x, int y, int w, int h);
+        static void statDrawFlipImg(void *data,int x,int y, int w, uchar *buf) {
+            FlipItem *item = static_cast<FlipItem*>(data);
+            item->drawFlipImg(x, y, w, buf);
+        }
+        void drawFlipImg(int x, int y, int w, uchar* buf);
+
+    private:
+        FlipMenu* m_menu;
+        Fl_RGB_Image* m_flipImg;
+        Fl_RGB_Image* m_flipImgH;
+        bool m_wasResized;
+        bool m_highlight;
+};
+
+#endif
+
diff --git a/src/GroupWidget.cpp b/src/GroupWidget.cpp
new file mode 100644
index 0000000..6c439ff
--- /dev/null
+++ b/src/GroupWidget.cpp
@@ -0,0 +1,203 @@
+/***************************************************************************
+ *  GroupWidget.cpp
+ *  Part of 
+ *  2016-  Florent Berthaut
+ *  hitmuri.net
+ ****************************************************************************/
+/*
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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 General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#include "GroupWidget.hpp"
+#include <iostream>
+#include <sstream>
+#include <cmath>
+
+#include "Controlar.hpp"
+
+using namespace std;
+
+GroupWidget::GroupWidget(int x, int y, int w, int h):Fl_Widget(x,y,w,h,"") {
+    box(FL_FLAT_BOX);
+    m_dragging=false;
+    m_highlight=false;
+    m_editing=false;
+    m_scaleX=1;
+    m_scaleY=1;
+}
+
+void GroupWidget::copy(GroupWidget* original) {
+    resize(original->x(), original->y(), original->w(), original->h());
+}
+
+GroupWidget::~GroupWidget() {}
+
+void GroupWidget::draw() {
+    Controlar* cont = Controlar::getInstance();
+
+    //draw
+#ifdef GL
+    glUniform1f(cont->getGroupHighlightUniform(), m_highlight);
+    glUniform1f(cont->getGroupEditingUniform(), m_editing);
+    glUniform2f(cont->getGroupSizeUniform(), w(), h());
+    glUniform2f(cont->getGroupPosUniform(), x(), y());
+    glDrawArrays(GL_TRIANGLES, 0, 6);
+#else 
+    //process drawing
+    fl_rect(x(), cont->isFlipped()?cont->h()-y()-h():y(),w(),h(),FL_DARK_GREEN);
+    if(m_highlight) {
+        fl_rect(x(), cont->isFlipped()?cont->h()-y()-h():y(),w(),h(),FL_GREEN);
+    }
+
+#endif
+}
+
+int GroupWidget::handle(int event) {
+    int res=0;
+    switch(event) {
+        case FL_PUSH:{
+            switch(Fl::event_button()) {
+                case FL_RIGHT_MOUSE: {
+                    do_callback();
+                    res=1;
+                }break;
+                case FL_LEFT_MOUSE: {
+                    if(Fl::event_shift()) {
+                        startDraggingGroup();
+                        m_editing=true;
+                        m_dragging=true;
+                        res=1;
+                    }
+                }break;
+                default:break;
+            }
+        }break;
+        case FL_DRAG: {
+            if(m_dragging) {
+                if(Fl::event_button()==FL_LEFT_MOUSE) {
+                    if(Fl::event_command()) { 
+                        size(m_dragW+Fl::event_x(), m_dragH+Fl::event_y());
+                    }
+                    else {
+                        Controlar* cont = Controlar::getInstance();
+                        cont->moveAllZonesInsideGroupBy(this, 
+                                        m_dragX+Fl::event_x()-x(),
+                                        m_dragY+Fl::event_y()-y());
+                        position(m_dragX+Fl::event_x(), 
+                                 m_dragY+Fl::event_y());
+                    }
+                    res=1;
+                }
+            }
+        }break;
+        case FL_SHORTCUT: {
+            if(m_highlight && Fl::event_key()==FL_Shift_L) {
+                m_editing=true;
+                res=1;
+            }
+        }break;
+        case FL_KEYUP: {
+            if(m_highlight && Fl::event_key()==FL_Shift_L) {
+                m_editing=false;
+                res=1;
+            }
+        }break;
+        case FL_RELEASE: {
+            if(m_dragging) {
+                m_editing=false;
+                m_dragging=false;
+                res=1;
+            }
+        }break;
+        case FL_MOVE:{
+            m_highlight=true;
+            if(Fl::event_shift()) { 
+                m_editing=true;
+                res=1;
+            }
+        }break;
+        case FL_ENTER: {
+            m_highlight=true;
+            res=1;
+        }break;
+        case FL_LEAVE: {
+            m_highlight=false;
+            res=1;
+        }break;
+        default:break;
+    }
+    if(res==1) {
+        parent()->redraw();
+    }
+    return res;
+}
+
+void GroupWidget::startDraggingGroup() {
+    m_dragX=x()-Fl::event_x();
+    m_dragY=y()-Fl::event_y();
+    m_dragW=w()-Fl::event_x();
+    m_dragH=h()-Fl::event_y();
+}
+
+void GroupWidget::resize(int nx, int ny, int nw, int nh) {
+    Fl_Widget::resize(nx, ny, nw, nh);
+}
+
+void GroupWidget::load(xmlNodePtr groupNode) {
+    char* value = NULL;
+
+    int x=0,y=0,w=20,h=20;
+    value = (char*)xmlGetProp(groupNode,(xmlChar*)"group_x");
+    if(value!=NULL) {
+        x = atoi(value);
+    }
+    value = (char*)xmlGetProp(groupNode,(xmlChar*)"group_y");
+    if(value!=NULL) {
+        y = atoi(value);
+    }
+    value = (char*)xmlGetProp(groupNode,(xmlChar*)"group_w");
+    if(value!=NULL) {
+        w = atoi(value);
+    }
+    value = (char*)xmlGetProp(groupNode,(xmlChar*)"group_h");
+    if(value!=NULL) {
+        h = atoi(value);
+    }
+    resize(x,y,w,h);
+}
+
+void GroupWidget::save(xmlNodePtr parentNode) {
+    xmlNodePtr newNode = xmlNewChild(parentNode, NULL, 
+                                      BAD_CAST "Group", NULL);
+    ostringstream oss1, oss2, oss3, oss4, oss5, 
+                  oss6, oss7, oss8, oss9, oss10, 
+                  oss11, oss12, oss13, oss14, oss15,
+                  oss16, oss17;
+    oss5<<x();
+    xmlNewProp(newNode, BAD_CAST "group_x", 
+               BAD_CAST oss5.str().c_str());
+    oss6<<y();
+    xmlNewProp(newNode, BAD_CAST "group_y", 
+               BAD_CAST oss6.str().c_str());
+    oss7<<w();
+    xmlNewProp(newNode, BAD_CAST "group_w", 
+               BAD_CAST oss7.str().c_str());
+    oss8<<h();
+    xmlNewProp(newNode, BAD_CAST "group_h", 
+               BAD_CAST oss8.str().c_str());
+}
+
+
diff --git a/src/GroupWidget.hpp b/src/GroupWidget.hpp
new file mode 100644
index 0000000..dffc234
--- /dev/null
+++ b/src/GroupWidget.hpp
@@ -0,0 +1,74 @@
+/***************************************************************************
+ *  GroupWidget.hpp
+ *  Part of 
+ *  2016-  Florent Berthaut
+ *  hitmuri.net
+ ****************************************************************************/
+/*
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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 General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef GroupWidget_h
+#define GroupWidget_h
+
+#include <FL/Fl.H>
+#include <FL/Fl_Widget.H>
+#include <FL/fl_draw.H>
+#include <GL/glew.h>
+#include <FL/gl.h>
+
+#include <libxml/parser.h>
+#include <libxml/tree.h>
+
+#include <sys/time.h>
+#include <string>
+#include <vector>
+
+class GroupWidget : public Fl_Widget {
+
+    public:
+        GroupWidget(int x=0, int y=0, int w=10, int h=10);
+        ~GroupWidget();
+        void copy(GroupWidget*);
+        void draw();
+        int handle(int event);
+        void save(xmlNodePtr parentNode);
+        void load(xmlNodePtr);
+        void resize(int x, int y, int w, int h);
+        inline void setID(const unsigned int& id){m_id=id;}
+        inline const unsigned int& getID(){return m_id;}
+        void startDraggingGroup();
+        void forceDraggingGroup();
+
+    private:
+        unsigned int m_id;
+        bool m_dragging;
+        bool m_highlight;
+        bool m_editing;
+        float m_dragX, m_dragY;
+        float m_dragW, m_dragH;
+        float m_dragStartX, m_dragStartY;
+        float m_scaleX, m_scaleY;
+    
+#ifdef GL
+        GLint m_sizeUniform;
+        GLint m_posUniform;
+        GLint m_editingUniform;
+#endif
+};
+
+
+#endif
+
diff --git a/src/MainPanel.cpp b/src/MainPanel.cpp
new file mode 100644
index 0000000..053775c
--- /dev/null
+++ b/src/MainPanel.cpp
@@ -0,0 +1,138 @@
+/***************************************************************************
+ *  MainPanel.cpp
+ *  Part of ControllAR
+ *  2016-  Florent Berthaut
+ *  hitmuri.net
+ ****************************************************************************/
+/*
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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 General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "MainPanel.hpp"
+#include <FL/Fl_Button.H>
+#include <FL/fl_draw.H>
+#include <algorithm>
+#include <iostream>
+#include "Controlar.hpp"
+
+using namespace std;
+
+MainPanel::MainPanel(): FlipGroup(0, 0, 240, 160) {
+    int labW=60;
+    int butW=40;
+    int smButW=20;
+    int butH=20;
+    int sep=5;
+    Fl_Pack* fileP = new Fl_Pack(sep, sep, (butW+sep)*3, butH, "File");
+    fileP->type(Fl_Pack::HORIZONTAL);
+    fileP->align(FL_ALIGN_LEFT | FL_ALIGN_INSIDE);
+    fileP->spacing(sep);
+    fileP->box(FL_NO_BOX);
+    add(fileP);
+    fileP->add(new Fl_Group(0,0,labW,0,""));
+    Fl_Button* opBut = new Fl_Button(0, 0, butW, butH, "open");
+    opBut->callback(statOpen,this);
+    fileP->add(opBut);
+    Fl_Button* saBut = new Fl_Button(0, 0, butW, butH, "save");
+    saBut->callback(statSave,this);
+    fileP->add(saBut);
+    Fl_Button* quBut = new Fl_Button(0, 0, butW, butH, "quit");
+    quBut->callback(statQuit,this);
+    fileP->add(quBut);
+
+    Fl_Pack* disP = new Fl_Pack(sep, sep+(butH+sep), 
+                                (butW+sep)*3, butH, "Display");
+    disP->type(Fl_Pack::HORIZONTAL);
+    disP->align(FL_ALIGN_LEFT | FL_ALIGN_INSIDE);
+    disP->spacing(sep);
+    disP->box(FL_NO_BOX);
+    add(disP);
+    disP->add(new Fl_Group(0,0,labW,0,""));
+    Fl_Button* fsBut = new Fl_Button(0, 0, butW*2, butH, "fullscreen");
+    fsBut->callback(statFullscreen,this);
+    disP->add(fsBut);
+    Fl_Button* mirBut = new Fl_Button(0, 0, butW*2, butH, "mirror");
+    mirBut->callback(statMirror,this);
+    disP->add(mirBut);
+
+    int brW=160;
+    int brH=70;
+    Fl_Group* inps = new Fl_Group(sep,sep+(butH+sep)*2,brW+labW, brH, "Inputs");
+    inps->box(FL_NO_BOX);
+    inps->align(FL_ALIGN_TOP|FL_ALIGN_LEFT|FL_ALIGN_INSIDE);
+    add(inps);
+    m_midiBr = new Fl_Multi_Browser(sep*2+labW, sep+(butH+sep)*2, brW, brH, "");
+    m_midiBr->align(FL_ALIGN_TOP);
+    m_midiBr->has_scrollbar(Fl_Browser_::VERTICAL_ALWAYS);
+    m_midiBr->callback(statMidiBr, this);
+    inps->add(m_midiBr);
+
+    Fl_Pack* scnP = new Fl_Pack(sep, sep+(butH+sep)*2+brH+sep, 
+                                  brW, butH, "Scenes");
+    scnP->align(FL_ALIGN_TOP|FL_ALIGN_LEFT|FL_ALIGN_INSIDE);
+    scnP->type(Fl_Pack::HORIZONTAL);
+    scnP->spacing(sep);
+    scnP->box(FL_NO_BOX);
+    add(scnP);
+    scnP->add(new Fl_Group(0, 0, labW, 0, ""));
+    Fl_Button* prevSc = new Fl_Button(0, 0, smButW, butH, "<");
+    prevSc->callback(statScenePrev, this);
+    scnP->add(prevSc);
+    m_sceneOut = new Fl_Value_Output(0, 0, butW, butH, "");
+    m_sceneOut->value(0);
+    scnP->add(m_sceneOut);
+    Fl_Button* nextSc = new Fl_Button(0, 0, smButW, butH, ">");
+    nextSc->callback(statSceneNext, this);
+    scnP->add(nextSc);
+    Fl_Button* delSc = new Fl_Button(0, 0, smButW, butH, "x");
+    delSc->callback(statSceneDel, this);
+    scnP->add(delSc);
+    Fl_Button* learnSc = new Fl_Button(0, 0, butW, butH, "learn");
+    learnSc->callback(statSceneLearn, this);
+    scnP->add(learnSc);
+}
+
+MainPanel* MainPanel::getInstance() {
+    static MainPanel instance;
+    return &instance;
+}
+
+
+void MainPanel::cbMidiBr() {
+    for(int i=1; i<=m_midiBr->size(); ++i) {
+        if(m_midiBr->selected(i)) {
+            Controlar::getInstance()->openMidiDevice(m_midiBr->text(i));
+        }
+        else {
+            Controlar::getInstance()->closeMidiDevice(m_midiBr->text(i));
+        }
+    }
+}
+
+void MainPanel::setMidiDevices(const vector<string>& devs, 
+                               const vector<bool>& opened) {
+    m_midiBr->clear();
+    vector<string>::const_iterator itDev = devs.begin();
+    vector<bool>::const_iterator itOp = opened.begin();
+    int el=1;
+    for(; itDev!=devs.end(); ++itDev, ++itOp, ++el) {
+        m_midiBr->add((*itDev).c_str(), NULL);
+        if((*itOp)) {
+            m_midiBr->select(el);
+        }
+    }
+}
+
+
diff --git a/src/MainPanel.hpp b/src/MainPanel.hpp
new file mode 100644
index 0000000..a2bd11e
--- /dev/null
+++ b/src/MainPanel.hpp
@@ -0,0 +1,85 @@
+/***************************************************************************
+ *  MainPanel.hpp
+ *  Part of ControllAR
+ *  2016-  Florent Berthaut
+ *  hitmuri.net
+ ****************************************************************************/
+/*
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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 General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#ifndef MainPanel_h
+#define MainPanel_h
+
+#include <FL/Fl_Multi_Browser.H>
+#include <FL/Fl_Value_Output.H>
+
+#include "Controlar.hpp"
+#include "FlipGroup.hpp"
+
+class MainPanel: public FlipGroup {
+    public :
+        static MainPanel* getInstance();
+        ~MainPanel(){};
+        static void statOpen(Fl_Widget* w,void* f){ 
+            Controlar::getInstance()->cbOpen();
+        }    
+        static void statSave(Fl_Widget* w, void* f){ 
+            Controlar::getInstance()->cbSave();
+        }    
+        static void statQuit(Fl_Widget* w,void* f){ 
+            Controlar::getInstance()->cbQuit();
+        }    
+
+        static void statMidiBr(Fl_Widget* w, void* f){ 
+            MainPanel::getInstance()->cbMidiBr();
+        }    
+        void cbMidiBr();
+        static void statSceneNext(Fl_Widget* w, void* f){ 
+            Controlar::getInstance()->cbSceneNext();
+            MainPanel::getInstance()->refresh();
+        }    
+        static void statScenePrev(Fl_Widget* w, void* f){ 
+            Controlar::getInstance()->cbScenePrev();
+            MainPanel::getInstance()->refresh();
+        }    
+        static void statSceneDel(Fl_Widget* w,void* f){ 
+            Controlar::getInstance()->cbSceneDelete();
+            MainPanel::getInstance()->refresh();
+        }    
+        static void statSceneLearn(Fl_Widget* w,void* f){ 
+            Controlar::getInstance()->cbSceneLearn();
+            MainPanel::getInstance()->refresh();
+        }    
+        static void statFullscreen(Fl_Widget* w,void* f){ 
+            Controlar::getInstance()->cbFullscreen();
+            MainPanel::getInstance()->refresh();
+        }    
+        static void statMirror(Fl_Widget* w,void* f){ 
+            Controlar::getInstance()->cbFlip();
+            MainPanel::getInstance()->refresh();
+        }    
+        void setMidiDevices(const std::vector<std::string>& midiDeviceNames,
+                            const std::vector<bool>& midiDeviceOp);
+        inline void setCurrentScene(const int& sc){m_sceneOut->value(sc);}
+
+    private:
+        MainPanel();
+        Fl_Multi_Browser* m_midiBr;
+        Fl_Value_Output* m_sceneOut;
+};
+
+#endif
diff --git a/src/ZonePanel.cpp b/src/ZonePanel.cpp
new file mode 100644
index 0000000..f34e349
--- /dev/null
+++ b/src/ZonePanel.cpp
@@ -0,0 +1,282 @@
+/***************************************************************************
+ *  ZonePanel.cpp
+ *  Part of 
+ *  2016-  Florent Berthaut
+ *  hitmuri.net
+ ****************************************************************************/
+/*
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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 General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "ZonePanel.hpp"
+#include <FL/Fl_Button.H>
+#include <FL/fl_draw.H>
+#include <algorithm>
+#include <iostream>
+#include "Controlar.hpp"
+#include "ZoneWidget.hpp"
+
+using namespace std;
+
+ZonePanel::ZonePanel(): FlipGroup(0, 0, 420, 200) {
+    int sep=5;
+    int butH=20;
+    int offY=sep;
+    int brW=200;
+    int brH=160;
+    int labW=60;
+    m_winsBr = new Fl_Hold_Browser(sep, offY, brW, brH, "window:");
+    m_winsBr->align(FL_ALIGN_TOP);
+    m_winsBr->has_scrollbar(Fl_Browser_::VERTICAL_ALWAYS);
+    m_winsBr->callback(statWinBr, this);
+    addWid(m_winsBr);
+
+    //transformations
+    Fl_Pack* radButs=new Fl_Pack(2*sep+brW, sep,(butH+sep)*4+50, 
+                                 butH,"Transfo");
+    add(radButs);
+    radButs->align(FL_ALIGN_INSIDE|FL_ALIGN_LEFT);
+    radButs->type(Fl_Pack::HORIZONTAL);
+    radButs->spacing(sep);
+    radButs->box(FL_NO_BOX);
+    radButs->add(new Fl_Group(0, 0, labW, butH, ""));
+    for(int i=0; i<ZoneWidget::NB_TRANSFO; ++i) {
+        m_transfos[i]=ZoneWidget::ZONE_TRANSFO(i);
+        m_transfoButs[i]= new Fl_Radio_Button(0, 0, butH, butH, "");
+        m_transfoButs[i]->callback(statZoneTransfo, &m_transfos[i]);
+        radButs->add(m_transfoButs[i]);
+    }
+    m_transfoButs[0]->label("@8->");
+    m_transfoButs[1]->label("@6->");
+    m_transfoButs[2]->label("@2->");
+    m_transfoButs[3]->label("@4->");
+
+    //shapes
+    radButs=new Fl_Pack(2*sep+brW, sep*2+butH, 0, butH, "Shape");
+    add(radButs);
+    radButs->align(FL_ALIGN_INSIDE|FL_ALIGN_LEFT);
+    radButs->type(Fl_Pack::HORIZONTAL);
+    radButs->spacing(sep);
+    radButs->box(FL_NO_BOX);
+    radButs->add(new Fl_Group(0, 0, labW, butH, ""));
+    for(int i=0; i<ZoneWidget::NB_SHAPES; ++i) {
+        m_shapes[i]=ZoneWidget::ZONE_SHAPE(i);
+        m_shapeButs[i] = new Fl_Radio_Button(0, 0, butH, butH, "");
+        m_shapeButs[i]->callback(statZoneShape, &m_shapes[i]);
+        radButs->add(m_shapeButs[i]);
+    }
+    m_shapeButs[0]->label("@-1square");
+    m_shapeButs[1]->label("@-1circle");
+    m_shapeButs[2]->label("@-1||");
+    
+    //alpha
+    radButs=new Fl_Pack(2*sep+brW, sep+(sep+butH)*2, 
+                         (butH+sep)*3+60, butH, "Alpha");
+    add(radButs);
+    radButs->align(FL_ALIGN_INSIDE|FL_ALIGN_LEFT);
+    radButs->type(Fl_Pack::HORIZONTAL);
+    radButs->spacing(sep);
+    radButs->box(FL_NO_BOX);
+    radButs->add(new Fl_Group(0, 0, labW, butH, ""));
+    m_alphaSlider=new Fl_Slider(0, 0, (butH+sep)*3, butH, "");
+    m_alphaSlider->callback(statZoneAlpha, this);
+    m_alphaSlider->type(FL_HORIZONTAL);
+    m_alphaSlider->bounds(0, 255);
+    radButs->add(m_alphaSlider);
+
+    //colors
+    radButs=new Fl_Pack(2*sep+brW, sep+(sep+butH)*3, 
+                         (butH+sep)*2+50, butH, "Color");
+    add(radButs);
+    radButs->align(FL_ALIGN_INSIDE|FL_ALIGN_LEFT);
+    radButs->type(Fl_Pack::HORIZONTAL);
+    radButs->spacing(sep);
+    radButs->box(FL_NO_BOX);
+    radButs->add(new Fl_Group(0, 0, labW, butH, ""));
+    for(int i=0; i<ZoneWidget::NB_COLORS; ++i) {
+        m_colors[i]=ZoneWidget::ZONE_COLOR(i);
+        m_colorButs[i] = new Fl_Radio_Button(0,0, 
+                                             butH, butH, "");
+        m_colorButs[i]->callback(statZoneColor, &m_colors[i]);
+        radButs->add(m_colorButs[i]);
+    }
+    m_colorButs[0]->label("N");
+    m_colorButs[1]->label("I");
+
+    //activity 
+    radButs=new Fl_Pack(2*sep+brW, sep+(sep+butH)*4, 
+                         (butH+sep)*3+50, butH, "Activity");
+    add(radButs);
+    radButs->align(FL_ALIGN_INSIDE|FL_ALIGN_LEFT);
+    radButs->type(Fl_Pack::HORIZONTAL);
+    radButs->spacing(sep);
+    radButs->box(FL_NO_BOX);
+    radButs->add(new Fl_Group(0, 0, 60, butH, ""));
+    for(int i=0; i<ZoneWidget::NB_EFFECTS; ++i) {
+        m_inputs[i]=ZoneWidget::ZONE_INPUT_EFFECT(i);
+        m_inputButs[i] = new Fl_Radio_Button(0, 0, butH, butH, "");
+        m_inputButs[i]->callback(statZoneInput, &m_inputs[i]);
+        radButs->add(m_inputButs[i]);
+    }
+    m_inputButs[0]->label("-");
+    m_inputButs[1]->label("S");
+    m_inputButs[2]->label("H");
+    Fl_Button* learnBut = new Fl_Button(0, 0, 50, butH, "Learn");
+    radButs->add(learnBut);
+    learnBut->callback(statZoneLearn,this);
+
+    //content
+    radButs=new Fl_Pack(2*sep+brW, sep+(sep+butH)*6, 
+                         (butH+sep)*3+50, butH, "Content");
+    add(radButs);
+    radButs->align(FL_ALIGN_INSIDE|FL_ALIGN_LEFT);
+    radButs->type(Fl_Pack::HORIZONTAL);
+    radButs->spacing(sep);
+    radButs->box(FL_NO_BOX);
+    radButs->add(new Fl_Group(0, 0, 60, butH, ""));
+    for(int i=0; i<ZoneWidget::NB_CONTENTS; ++i) {
+        m_contents[i]=ZoneWidget::ZONE_CONTENT(i);
+        m_contentButs[i] = new Fl_Radio_Button(0, 0, butH*3, butH, "");
+        m_contentButs[i]->callback(statZoneContent, &m_contents[i]);
+        radButs->add(m_contentButs[i]);
+    }
+    m_contentButs[0]->label("global");
+    m_contentButs[1]->label("local");
+
+    //update
+    radButs=new Fl_Pack(2*sep+brW, sep+(sep+butH)*5, 
+                         (butH+sep)*3+50, butH, "Update");
+    add(radButs);
+    radButs->align(FL_ALIGN_INSIDE|FL_ALIGN_LEFT);
+    radButs->type(Fl_Pack::HORIZONTAL);
+    radButs->spacing(sep);
+    radButs->box(FL_NO_BOX);
+    radButs->add(new Fl_Group(0, 0, 60, butH, ""));
+    for(int i=0; i<ZoneWidget::NB_UPDATES; ++i) {
+        m_updates[i]=ZoneWidget::ZONE_UPDATE(i);
+        m_updateButs[i] = new Fl_Radio_Button(0, 0, butH*3, butH, "");
+        m_updateButs[i]->callback(statZoneUpdate, &m_updates[i]);
+        radButs->add(m_updateButs[i]);
+    }
+    m_updateButs[0]->label("all");
+    m_updateButs[1]->label("current");
+
+    //delete
+    Fl_Button* delBut = new Fl_Button(sep, h()-sep-butH, 60, butH, "Delete");
+    delBut->callback(statZoneDelete,this);
+    add(delBut);
+}
+
+void ZonePanel::setWindowList(vector<CutWindow*>& wins) {
+    m_winsBr->clear();
+    m_winsBr->add("none", NULL);
+    vector<CutWindow*>::iterator itWin = wins.begin();
+    for(; itWin!=wins.end(); ++itWin) {
+        m_winsBr->add(((*itWin)->getName()).c_str(), (*itWin));
+    }
+    m_winsBr->value(1);
+}
+
+void ZonePanel::setZone(ZoneWidget* z) {
+    m_curZone=z;
+
+    //retrieve values 
+    if(m_curZone) {
+        CutWindow* cutW = m_curZone->getCutWin();
+        if(cutW) {
+            string cutWN = cutW->getName();
+            for(int i=1; i<=m_winsBr->size(); ++i) {
+                if(cutWN.compare(m_winsBr->text(i))==0) {
+                    m_winsBr->value(i);
+                }
+            }
+        }
+        else {
+            m_winsBr->value(1);
+        }
+
+        for(int i=0; i<int(ZoneWidget::NB_TRANSFO); ++i) {
+            m_transfoButs[i]->value(0);
+        }
+        m_transfoButs[int(m_curZone->getTransformation())]->value(1);
+        for(int i=0; i<int(ZoneWidget::NB_SHAPES); ++i) {
+            m_shapeButs[i]->value(0);
+        }
+        m_shapeButs[int(m_curZone->getShape())]->value(1);
+        for(int i=0; i<int(ZoneWidget::NB_COLORS); ++i) {
+            m_colorButs[i]->value(0);
+        }
+        m_colorButs[int(m_curZone->getColor())]->value(1);
+        for(int i=0; i<int(ZoneWidget::NB_EFFECTS); ++i) {
+            m_inputButs[i]->value(0);
+        }
+        m_inputButs[int(m_curZone->getEffect())]->value(1);
+        for(int i=0; i<int(ZoneWidget::NB_UPDATES); ++i) {
+            m_updateButs[i]->value(0);
+        }
+        m_updateButs[int(m_curZone->getZoneUpdate())]->value(1);
+        for(int i=0; i<int(ZoneWidget::NB_CONTENTS); ++i) {
+            m_contentButs[i]->value(0);
+        }
+        m_contentButs[int(m_curZone->getContent())]->value(1);
+        m_alphaSlider->value(m_curZone->getAlpha());
+    }
+}
+
+void ZonePanel::cbWinBr(Fl_Widget*) {
+    m_curZone->setCutWin((CutWindow*)(m_winsBr->data(m_winsBr->value())));
+    refresh();
+}
+
+void ZonePanel::cbZoneTransfo(const ZoneWidget::ZONE_TRANSFO& trans) {
+    m_curZone->setTransformation(trans);
+    refresh();
+}
+
+void ZonePanel::cbZoneShape(const ZoneWidget::ZONE_SHAPE& shape) {
+    m_curZone->setShape(shape);
+    refresh();
+}
+
+void ZonePanel::cbZoneAlpha() {
+    m_curZone->setAlpha(m_alphaSlider->value());
+    refresh();
+}
+
+void ZonePanel::cbZoneColor(const ZoneWidget::ZONE_COLOR& color) {
+    m_curZone->setColor(color);
+    refresh();
+}
+
+void ZonePanel::cbZoneInput(const ZoneWidget::ZONE_INPUT_EFFECT& inp) {
+    m_curZone->setInputEffect(inp);
+    refresh();
+}
+
+void ZonePanel::cbZoneUpdate(const ZoneWidget::ZONE_UPDATE& up) {
+    Controlar::getInstance()->cbZoneUpdate(up);
+    refresh();
+}
+
+void ZonePanel::cbZoneContent(const ZoneWidget::ZONE_CONTENT& cont) {
+    m_curZone->setContent(cont);
+    refresh();
+}
+
+ZonePanel* ZonePanel::getInstance() {
+    static ZonePanel instance;
+    return &instance;
+}
+
diff --git a/src/ZonePanel.hpp b/src/ZonePanel.hpp
new file mode 100644
index 0000000..fb95307
--- /dev/null
+++ b/src/ZonePanel.hpp
@@ -0,0 +1,124 @@
+/***************************************************************************
+ *  ZonePanel.hpp
+ *  Part of ControllAR
+ *  2016-  Florent Berthaut
+ *  hitmuri.net
+ ****************************************************************************/
+/*
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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 General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#ifndef ZonePanel_h
+#define ZonePanel_h
+
+#include <string>
+#include <map>
+#include <vector>
+
+#include <FL/Fl_Choice.H>
+#include <FL/Fl_Hold_Browser.H>
+#include <FL/Fl_Radio_Round_Button.H>
+#include <FL/Fl_Radio_Button.H>
+#include <FL/Fl_Slider.H>
+#include "Controlar.hpp"
+#include "FlipGroup.hpp"
+#include "CutWindow.hpp"
+
+class ZoneWidget;
+
+class ZonePanel: public FlipGroup {
+    public :
+        static ZonePanel* getInstance();
+        ~ZonePanel(){};
+        void setWindowList(std::vector<CutWindow*>& wins);
+
+        static void statWinBr(Fl_Widget* w, void* f){ 
+            ZonePanel *tmpf = static_cast<ZonePanel *>(f);
+            tmpf->cbWinBr(w);
+        }    
+        void cbWinBr(Fl_Widget*);
+
+        static void statZoneTransfo(Fl_Widget* w, void* f){ 
+            ZonePanel::getInstance()
+                ->cbZoneTransfo(*(ZoneWidget::ZONE_TRANSFO*)(f));
+        }    
+        void cbZoneTransfo(const ZoneWidget::ZONE_TRANSFO&);
+
+        static void statZoneShape(Fl_Widget* w, void* f){ 
+            ZonePanel::getInstance()
+                ->cbZoneShape(*(ZoneWidget::ZONE_SHAPE*)(f));
+        }    
+        void cbZoneShape(const ZoneWidget::ZONE_SHAPE&);
+
+        static void statZoneAlpha(Fl_Widget* w, void* f){ 
+            ZonePanel::getInstance()->cbZoneAlpha();
+        }    
+        void cbZoneAlpha();
+
+        static void statZoneColor(Fl_Widget* w, void* f){ 
+            ZonePanel::getInstance()
+                        ->cbZoneColor(*(ZoneWidget::ZONE_COLOR*)(f));
+        }    
+        void cbZoneColor(const ZoneWidget::ZONE_COLOR&);
+
+        static void statZoneInput(Fl_Widget* w, void* f){ 
+            ZonePanel::getInstance()
+                        ->cbZoneInput(*(ZoneWidget::ZONE_INPUT_EFFECT*)(f));
+        }    
+        void cbZoneInput(const ZoneWidget::ZONE_INPUT_EFFECT&);
+
+        static void statZoneContent(Fl_Widget* w, void* f){ 
+            ZonePanel::getInstance()
+                        ->cbZoneContent(*(ZoneWidget::ZONE_CONTENT*)(f));
+        }    
+        void cbZoneContent(const ZoneWidget::ZONE_CONTENT&);
+
+        static void statZoneUpdate(Fl_Widget* w, void* f){ 
+            ZonePanel::getInstance()
+                        ->cbZoneUpdate(*(ZoneWidget::ZONE_UPDATE*)(f));
+        }    
+        void cbZoneUpdate(const ZoneWidget::ZONE_UPDATE&);
+
+        static void statZoneLearn(Fl_Widget* w, void* f){ 
+            Controlar::getInstance()->cbZoneMidiLearn();
+        }    
+
+        static void statZoneDelete(Fl_Widget* w, void* f){ 
+            Controlar::getInstance()->cbZoneDelete();
+        }    
+            
+        void setZone(ZoneWidget*);
+
+    private:
+        ZonePanel();
+        Fl_Hold_Browser* m_winsBr;
+        ZoneWidget* m_curZone;
+        ZoneWidget::ZONE_TRANSFO m_transfos[ZoneWidget::NB_TRANSFO];
+        Fl_Radio_Button* m_transfoButs[ZoneWidget::NB_TRANSFO];
+        ZoneWidget::ZONE_SHAPE m_shapes[ZoneWidget::NB_SHAPES];
+        Fl_Radio_Button* m_shapeButs[ZoneWidget::NB_SHAPES];
+        ZoneWidget::ZONE_COLOR m_colors[ZoneWidget::NB_COLORS];
+        Fl_Radio_Button* m_colorButs[ZoneWidget::NB_COLORS];
+        ZoneWidget::ZONE_INPUT_EFFECT m_inputs[ZoneWidget::NB_EFFECTS];
+        Fl_Radio_Button* m_inputButs[ZoneWidget::NB_EFFECTS];
+        ZoneWidget::ZONE_CONTENT m_contents[ZoneWidget::NB_CONTENTS];
+        Fl_Radio_Button* m_contentButs[ZoneWidget::NB_CONTENTS];
+        ZoneWidget::ZONE_UPDATE m_updates[ZoneWidget::NB_UPDATES];
+        Fl_Radio_Button* m_updateButs[ZoneWidget::NB_UPDATES];
+        Fl_Slider* m_alphaSlider;
+};
+
+#endif
diff --git a/src/ZoneWidget.cpp b/src/ZoneWidget.cpp
new file mode 100644
index 0000000..a6c542e
--- /dev/null
+++ b/src/ZoneWidget.cpp
@@ -0,0 +1,1077 @@
+/***************************************************************************
+ *  ZoneWidget.cpp
+ *  Part of 
+ *  2016-  Florent Berthaut
+ *  hitmuri.net
+ ****************************************************************************/
+/*
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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 General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#include "ZoneWidget.hpp"
+#include <iostream>
+#include <sstream>
+#include <cmath>
+
+#include "Controlar.hpp"
+
+using namespace std;
+
+const int ZoneWidget::GLOBAL_PROPS;
+
+ZoneWidget::ZoneWidget(int x, int y, int w, int h): Fl_Widget(x,y,w,h,"") {
+    box(FL_FLAT_BOX);
+    m_state=NORMAL_STATE;
+    m_imageData=NULL;
+    m_image=NULL;
+    m_coordImage=NULL;
+    recreateImage();
+    m_dragging=false;
+    m_forcedDragging=false;
+    m_editing=false;
+    m_highlight=false;
+    m_scaleX=1;
+    m_scaleY=1;
+    m_midiLearning=false;
+    m_effectDelay.tv_sec=0;
+    m_effectDelay.tv_usec=250000;
+    m_hiddenByEffect=false;
+    m_effectDelayOver=true;
+    m_rateReached=false;
+    m_initialized=false;
+    m_visibleInScene=-1;
+    m_updateInScene=-1;
+    m_content=CONTENT_GLOBAL;
+
+    m_curCutProps=ZoneWidget::GLOBAL_PROPS;
+    m_cutProps[m_curCutProps]=CutProps();
+    m_currentScene=0;
+}
+
+void ZoneWidget::copy(ZoneWidget* original) {
+    resize(original->x(), original->y(), original->w(), original->h());
+    m_cutProps=original->m_cutProps;
+    m_curCutProps=original->m_curCutProps;
+    m_visibleInScene=original->m_visibleInScene;
+    m_updateInScene=original->m_updateInScene;
+    m_content = original->m_content;
+    recomputePixels();
+}
+
+ZoneWidget::~ZoneWidget() {}
+
+void ZoneWidget::setScene(const int& scene) {
+    if(m_updateInScene==m_currentScene && m_cutProps[m_curCutProps].m_ovWin) {
+        m_cutProps[m_curCutProps].m_ovWin->storeImage(m_currentScene);
+    }
+    if(m_content==CONTENT_LOCAL) {
+        m_curCutProps=scene;
+    }
+    else {
+        m_curCutProps=ZoneWidget::GLOBAL_PROPS;
+    }
+    m_currentScene=scene;
+    recomputePixels();
+}
+
+void ZoneWidget::setContent(const ZONE_CONTENT& cont) { 
+    m_content=cont;
+    //set current scene to define current cut props
+    setScene(m_currentScene);
+    //copy props
+    if(m_content==CONTENT_LOCAL) {
+        //copy from global to local
+        m_cutProps[m_curCutProps]=m_cutProps[ZoneWidget::GLOBAL_PROPS];
+    }
+    else {
+        //copy from local to global
+        m_cutProps[ZoneWidget::GLOBAL_PROPS]=m_cutProps[m_curCutProps];
+    }
+}
+
+void ZoneWidget::refreshCutWin() {
+    setCutWin(Controlar::getInstance()
+                ->getWindow(m_cutProps[m_curCutProps].m_ovWinName));
+}
+
+void ZoneWidget::setCutWin(CutWindow* ow) { 
+    CutProps& props = m_cutProps[m_curCutProps];
+    props.m_ovWin=ow;
+    if(props.m_ovWin) { //if the window exists
+        if(props.m_ovWinName.compare(props.m_ovWin->getName())==0) { //same name
+            //preserve coordinates if possible
+            props.m_winW = max(1, min(props.m_winW,
+                              props.m_ovWin->getWidth()));
+            props.m_winH = max(1, min(props.m_winH, 
+                              props.m_ovWin->getHeight()));
+            props.m_winX = max(0, min(props.m_winX, 
+                              props.m_ovWin->getWidth()-props.m_winW));
+            props.m_winY = max(0, min(props.m_winY, 
+                              props.m_ovWin->getHeight()-props.m_winH));
+            m_nbPixPerRow=props.m_winW;
+        }
+        else { //different window
+            //reset position and size of the cut
+            props.m_ovWinName=props.m_ovWin->getName();
+            props.m_winX=0;
+            props.m_winY=0;
+            props.m_winW = max(1, min(w(), props.m_ovWin->getWidth()));
+            props.m_winH = max(1, min(h(), props.m_ovWin->getHeight()));
+            m_nbPixPerRow=props.m_winW;
+        }
+        recomputePixels();
+    }
+}
+
+CutWindow* ZoneWidget::getCutWin() {
+    return m_cutProps[m_curCutProps].m_ovWin;
+}
+
+void ZoneWidget::setInputEffect(const ZONE_INPUT_EFFECT& effect) {
+    ZONE_INPUT_EFFECT& meffect = m_cutProps[m_curCutProps].m_effect;
+    meffect=effect;
+    m_hiddenByEffect=(meffect==SHOW)?true:false;
+}
+
+void ZoneWidget::setVisible(const int& vis) {
+    m_visibleInScene=vis;
+}
+
+void ZoneWidget::setUpdate(const int& up) {
+    m_updateInScene=up;
+}
+
+void ZoneWidget::processMidi(const int& midiType, 
+                             const int& midiChannel, 
+                             const int& midiControl, 
+                             const int& midiValue) {
+    if(m_midiLearning) {
+        m_midiType=midiType;
+        m_midiChannel=midiChannel;
+        m_midiControl=midiControl;
+        m_midiLearning=false;
+    }
+    ZONE_INPUT_EFFECT& meffect = m_cutProps[m_curCutProps].m_effect;
+    if(meffect!=NO_EFFECT) {
+        if(midiType==m_midiType 
+                && midiChannel==m_midiChannel 
+                && midiControl==m_midiControl) {
+            m_effectDelayOver=false;
+            gettimeofday(&m_effectStartTime, NULL);
+            switch(meffect) {
+                case SHOW:{
+                    m_hiddenByEffect=false;
+                }break;
+                case HIDE:{
+                    m_hiddenByEffect=true;
+                }break;
+                default:break;
+            }
+        }
+    }
+}
+
+void ZoneWidget::drawZone(const int& currentScene) {
+    int nw=w()-OUTER*2;
+    int nh=h()-OUTER*2;
+
+    CutProps& props = m_cutProps[m_curCutProps];
+
+    Controlar* cont = Controlar::getInstance();
+    //process effect
+    if(props.m_effect!=NO_EFFECT && !m_effectDelayOver) {
+        timeval curTime, diffTime;
+        gettimeofday(&curTime, NULL);
+        timersub(&curTime, &m_effectStartTime, &diffTime);
+        if(timercmp(&diffTime, &m_effectDelay, >)) {
+            m_effectDelayOver=true; 
+            switch(props.m_effect) {
+                case SHOW:{
+                    m_hiddenByEffect=true;
+                }break;
+                case HIDE:{
+                    m_hiddenByEffect=false;
+                }break;
+                default:break;
+            }
+        }
+    }
+
+    //draw
+#ifdef GL
+    if(m_visibleInScene<0 || m_visibleInScene==currentScene) {  
+        glUniform1f(cont->getZoneFilledUniform(), 0.0);
+        glUniform1i(cont->getZoneStateUniform(), int(m_state));
+        glUniform2f(cont->getZoneSizeUniform(), w(), h());
+        glUniform2f(cont->getZonePosUniform(), x(), y());
+        glUniform2f(cont->getCutSizeUniform(), nw, nh);
+        glUniform2f(cont->getCutPosUniform(), x()+OUTER, y()+OUTER);
+        glUniform1f(cont->getZoneAlphaUniform(), 
+                    m_hiddenByEffect?0.0:float(props.m_alpha)/255.0);
+        glUniform1f(cont->getZoneInvertUniform(), props.m_color==INVERT);
+        if(props.m_ovWin) {
+            glUniform1f(cont->getZoneFilledUniform(), 1.0);
+            //if using stored image from other scene
+            if(m_updateInScene>=0 && m_updateInScene!=currentScene) {
+                uchar* storedData=props.m_ovWin->retrieveImage(m_updateInScene);
+                if(storedData) {
+                    glActiveTexture(GL_TEXTURE0);
+                    glBindTexture(GL_TEXTURE_2D, cont->getFirstTextureID());
+                    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
+                                 m_nbPixPerRow, props.m_ovWin->getHeight(),
+                                 0, GL_RGBA, GL_UNSIGNED_BYTE,
+                                 storedData);
+                    cont->setCurrentWindowName("");
+                }
+            }
+            else if(cont->getCurrentWindowName()
+                                .compare(props.m_ovWin->getName())!=0) {
+                glActiveTexture(GL_TEXTURE0);
+                glBindTexture(GL_TEXTURE_2D, cont->getFirstTextureID());
+                glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
+                             m_nbPixPerRow, props.m_ovWin->getHeight(),
+                             0, GL_RGBA, GL_UNSIGNED_BYTE,
+                             props.m_ovWin->grabImage());
+                cont->setCurrentWindowName(props.m_ovWin->getName());
+            }
+            glActiveTexture(GL_TEXTURE1);
+            glBindTexture(GL_TEXTURE_2D, cont->getSecondTextureID());
+            glTexImage2D(GL_TEXTURE_2D, 0, GL_RG16F,
+                         nw, nh,
+                         0, GL_RG, GL_FLOAT,
+                         m_coordImage);
+        }
+        glDrawArrays(GL_TRIANGLES, 0, 6);
+    }
+
+#else 
+    
+    //process drawing
+    if(props.m_ovWin) {
+        if(m_visibleInScene<0 || m_visibleInScene==currentScene) {  
+            if(!m_hiddenByEffect && m_rateReached) {
+                m_image->uncache();
+                m_ovWin->getPixels(props.m_winX, props.m_winY, 
+                                   props.m_winW, props.m_winH, 
+                                   m_srcIndices, m_srcCoords, m_destIndices, 
+                                   props.m_alpha, props.m_color, m_imageData);
+                m_image->draw(x(), cont->isFlipped()?cont->h()-y()-h():y(), 
+                                  w(), h());
+            }
+            switch(m_rate) {
+                case STATIC:m_rateReached=false;break;
+                default:m_rateReached=true;break;
+            }
+        }
+    }
+    else {
+        fl_rect(x(), cont->isFlipped()?cont->h()-y()-h():y(), 
+                w(), h(), FL_WHITE);
+    }
+    if(m_editing) {
+        fl_rectf(x(), cont->isFlipped()?cont->h()-y()-h():y(), 
+                 w(), h(), FL_RED);
+    }
+    if(m_highlight) {
+        fl_rect(x(), cont->isFlipped()?cont->h()-y()-h():y(), 
+                w(), h(), FL_RED);
+    }
+
+#endif
+}
+
+void ZoneWidget::recomputePixels() {
+    CutProps& props = m_cutProps[m_curCutProps];
+
+    //if window attached, recompute correspondance between pixel coordinates 
+    if(props.m_ovWin) {
+
+        //get new pixperrow in window
+        m_nbPixPerRow = props.m_ovWin->computeNbPixPerRow(props.m_winW, 
+                                                          props.m_winH);
+
+        //clear existing coordinates 
+        m_srcIndices.clear();
+        m_srcCoords.clear();
+        m_destIndices.clear();
+        vector<float> coord(2,0);
+        vector<float> start(2,0);
+        vector<bool> restart(2,false);
+        vector<float> stepY(2,0);
+        vector<float> stepX(2,0);
+        int nw=w()-OUTER*2;
+        int nh=h()-OUTER*2;
+
+        //compute the pixels offset and steps depending on transformation
+        switch(props.m_transfo) {
+            case ROTATE_90 : {
+                start[0]=props.m_ovWin->needsOffset()?props.m_winX:0;
+                start[1]=props.m_ovWin->needsOffset()?props.m_winY+props.m_winH
+                                                     :props.m_winH;
+                stepY[0]=float(props.m_winW)/float(nh);
+                restart[1]=true;
+                stepX[1]=-float(props.m_winH)/float(nw);
+            }break;
+            case ROTATE_180 : {
+                start[0]=props.m_ovWin->needsOffset()?props.m_winX+props.m_winW
+                                                     :props.m_winW;
+                start[1]=props.m_ovWin->needsOffset()?props.m_winY+props.m_winH
+                                                     :props.m_winH;
+                stepY[1]=-float(props.m_winH)/float(nh);
+                restart[0]=true;
+                stepX[0]=-float(props.m_winW)/float(nw);
+            }break;
+            case ROTATE_270 : {
+                start[0]=props.m_ovWin->needsOffset()?props.m_winX+props.m_winW
+                                                     :props.m_winW;
+                start[1]=props.m_ovWin->needsOffset()?props.m_winY:0;
+                stepY[0]=-float(props.m_winW)/float(nh);
+                restart[1]=true;
+                stepX[1]=float(props.m_winH)/float(nw);
+            }break;
+            default : {
+                start[0]=props.m_ovWin->needsOffset()?props.m_winX:0;
+                start[1]=props.m_ovWin->needsOffset()?props.m_winY:0;
+                stepY[1]=float(props.m_winH)/float(nh);
+                restart[0]=true;
+                stepX[0]=float(props.m_winW)/float(nw);
+            }break;
+        }
+
+        vector<int> intCoord(2,0);
+        coord[0]=start[0];
+        coord[1]=start[1];
+
+        Controlar* cont = Controlar::getInstance();
+
+        //compute coordinates according to shape
+        switch(props.m_shape) { 
+            case CIRCLE : { //circle shape
+                int radius = min(nw,nh);
+                for(int py = 0; py < nh; py++) {
+                    for(int px = 0; px < nw; px++) {
+                        float distX = px-nw/2;
+                        float distY = py-nh/2;
+                        float dist = sqrt(distX*distX + distY*distY);
+                        if(dist>radius/4 && dist<radius/2) { //inside the circle
+                            distX/=float(radius);
+                            distY/=float(radius);
+                            float angleY = (atan2(distY,distX)-M_PI/2.0)
+                                            / (2.0*M_PI)*float(nh);
+                            if(angleY<0) {
+                                angleY=nh+angleY;
+                            }
+                            float radiusX = 
+                                (dist-radius/4)/(radius/4)*float(nw);
+                            intCoord[0] = 
+                                start[0]+stepY[0]*angleY+stepX[0]*radiusX;
+                            intCoord[1] = 
+                                start[1]+stepY[1]*angleY+stepX[1]*radiusX;
+                        }
+                        else {
+                            intCoord[0]=-1; intCoord[1]=-1; 
+                        }
+                        m_srcCoords.push_back(intCoord);
+                        int srcInd = (m_nbPixPerRow*intCoord[1]
+                                        +intCoord[0])*4;
+                        if(props.m_ovWin->isBGR()) {
+                            m_srcIndices.push_back(srcInd+2);
+                            m_srcIndices.push_back(srcInd+1);
+                            m_srcIndices.push_back(srcInd);
+                        }
+                        else {
+                            m_srcIndices.push_back(srcInd);
+                            m_srcIndices.push_back(srcInd+1);
+                            m_srcIndices.push_back(srcInd+2);
+                        }
+                        m_srcIndices.push_back(srcInd+3);
+                        for(int c=0; c<4; ++c) {
+                            if(cont->isFlipped()) {
+                               m_destIndices.push_back((nw*(nh-1-py)+px)*4+c);
+                            }
+                            else {
+                                m_destIndices.push_back((nw*py+px)*4+c);
+                            }
+                        }
+                        m_coordImage[(nw*py+px)*2]=float(intCoord[0]) 
+                                            / float(props.m_ovWin->getWidth());
+                        m_coordImage[(nw*py+px)*2+1]=float(intCoord[1]) 
+                                            / float(props.m_ovWin->getHeight());
+                    }
+                }
+            }break;
+            case FRAME : { //frame shape
+                int border=20;
+                for(int py = 0; py < nh; py++) {
+                    coord[0]=restart[0]?start[0]:coord[0];
+                    coord[1]=restart[1]?start[1]:coord[1];
+                    for(int px = 0; px < nw; px++) {
+                        if(px>border && px<nw-border
+                                && py>border && py<nh-border) {
+                            intCoord[0]=-1; intCoord[1]=-1; 
+                        }
+                        else {
+                            float nbSrcPix=0;
+                            if(py<border) {
+                                nbSrcPix = float(py)/float(border)*float(nh/2);
+                                intCoord[0]=coord[0];
+                                intCoord[1]=start[1]
+                                            +nbSrcPix*stepX[1]
+                                            +nbSrcPix*stepY[1];
+                            }
+                            else if(py>nh-border) {
+                                nbSrcPix= float(nh)
+                                          -(float(nh-py)
+                                              /float(border)
+                                              *float(nh/2));
+                                intCoord[0]=coord[0];
+                                intCoord[1]=start[1]
+                                            +nbSrcPix*stepX[1]
+                                            +nbSrcPix*stepY[1];
+                            }
+                            else if(px<border) {
+                                nbSrcPix = float(px)/float(border)*float(nw/2);
+                                intCoord[0]=start[0]
+                                            +nbSrcPix*stepX[0]
+                                            +nbSrcPix*stepY[0];
+                                intCoord[1]=coord[1];
+                            }
+                            else {
+                                nbSrcPix= float(nw)
+                                          -(float(nw-px)
+                                              /float(border)
+                                              *float(nw/2));
+                                intCoord[0]=start[0]
+                                            +nbSrcPix*stepX[0]
+                                            +nbSrcPix*stepY[0];
+                                intCoord[1]=coord[1];
+                            }
+                        }
+                        m_srcCoords.push_back(intCoord);
+                        int srcInd = (m_nbPixPerRow*intCoord[1]
+                                        +intCoord[0])*4;
+                        if(props.m_ovWin->isBGR()) {
+                            m_srcIndices.push_back(srcInd+2);
+                            m_srcIndices.push_back(srcInd+1);
+                            m_srcIndices.push_back(srcInd);
+                        }
+                        else {
+                            m_srcIndices.push_back(srcInd);
+                            m_srcIndices.push_back(srcInd+1);
+                            m_srcIndices.push_back(srcInd+2);
+                        }
+                        m_srcIndices.push_back(srcInd+3);
+                        for(int c=0; c<4; ++c) {
+                            if(cont->isFlipped()) {
+                               m_destIndices.push_back((nw*(nh-1-py)+px)*4+c);
+                            }
+                            else {
+                                m_destIndices.push_back((nw*py+px)*4+c);
+                            }
+                        }
+                        coord[0]+=stepX[0];
+                        coord[1]+=stepX[1];
+                        m_coordImage[(nw*py+px)*2]=float(intCoord[0]) 
+                                          / float(props.m_ovWin->getWidth());
+                        m_coordImage[(nw*py+px)*2+1]=float(intCoord[1]) 
+                                          / float(props.m_ovWin->getHeight());
+                    }
+                    coord[0]+=stepY[0];
+                    coord[1]+=stepY[1];
+                }
+            }break;
+            default: { //box shape
+                for(int py = 0; py < nh; py++) {
+                    coord[0]=restart[0]?start[0]:coord[0];
+                    coord[1]=restart[1]?start[1]:coord[1];
+                    for(int px = 0; px < nw; px++) {
+                        intCoord[0]=coord[0]; intCoord[1]=coord[1];
+                        m_srcCoords.push_back(intCoord);
+                        int srcInd = (m_nbPixPerRow*intCoord[1]
+                                        +intCoord[0])*4;
+                        if(props.m_ovWin->isBGR()) {
+                            m_srcIndices.push_back(srcInd+2);
+                            m_srcIndices.push_back(srcInd+1);
+                            m_srcIndices.push_back(srcInd);
+                        }
+                        else {
+                            m_srcIndices.push_back(srcInd);
+                            m_srcIndices.push_back(srcInd+1);
+                            m_srcIndices.push_back(srcInd+2);
+                        }
+                        m_srcIndices.push_back(srcInd+3);
+                        for(int c=0; c<4; ++c) {
+                            if(cont->isFlipped()) {
+                               m_destIndices.push_back((nw*(nh-1-py)+px)*4+c);
+                            }
+                            else {
+                                m_destIndices.push_back((nw*py+px)*4+c);
+                            }
+                        }
+                        coord[0]+=stepX[0];
+                        coord[1]+=stepX[1];
+                        m_coordImage[(nw*py+px)*2]=float(intCoord[0]) 
+                                         / float(props.m_ovWin->getWidth());
+                        m_coordImage[(nw*py+px)*2+1]=float(intCoord[1]) 
+                                         / float(props.m_ovWin->getHeight());
+                    }
+                    coord[0]+=stepY[0];
+                    coord[1]+=stepY[1];
+                }
+            }break;
+        }
+        m_scaleX=(stepY[0]!=0)?abs(stepY[0]):abs(stepX[0]);
+        m_scaleY=(stepY[1]!=0)?abs(stepY[1]):abs(stepX[1]);
+    }
+}
+
+void ZoneWidget::recreateImage() {
+    int nw=w()-OUTER*2;
+    int nh=h()-OUTER*2;
+    if(m_imageData) {
+        delete [] m_imageData;
+    }
+    m_imageData = new uchar[nw*nh*4];
+    if(m_image) {
+        delete m_image;
+    }
+    m_image = new Fl_RGB_Image(m_imageData, nw, nh, 4);
+
+    if(m_coordImage) {
+        delete m_coordImage;
+    }
+    m_coordImage = new float[nw*nh*2];
+}
+
+int ZoneWidget::handle(int event) {
+    CutProps& props = m_cutProps[m_curCutProps];
+    int res=0;
+    switch(event) {
+        case FL_MOUSEWHEEL : {
+            Fl_Widget* wid = Fl::belowmouse();
+            if(parent()!=NULL) {
+                parent()->insert(*wid,0);
+            }
+            res=1;
+        }break;
+        case FL_PUSH:{
+            if(Fl::event_inside(this)) { 
+                m_forcedDragging=false;
+                switch(Fl::event_button()) {
+                    case FL_RIGHT_MOUSE: {
+                        do_callback();
+                        res=1;
+                    }break;
+                    case FL_LEFT_MOUSE: {
+                        //if(Fl::event_shift()) { //move/resize zone
+                        if(m_state==MOVE_ZONE || m_state==RESIZE_ZONE) { 
+                            startDraggingZone();
+                            m_editing=true;
+                        }
+                        //else if(props.m_ovWin) { //move/resize window
+                        else if(props.m_ovWin) { //move/resize window
+                            m_editing=true;
+                            switch(props.m_transfo) {
+                                case ROTATE_90: {
+                                    m_dragStartX=props.m_winY;
+                                    m_dragStartY=props.m_winX;
+                                    m_dragX=Fl::event_x();
+                                    m_dragY=Fl::event_y();
+                                    m_dragW=props.m_winW+Fl::event_y();
+                                    m_dragH=props.m_winH-Fl::event_x();
+                                }break;
+                                case ROTATE_180: {
+                                    m_dragStartX=props.m_winX;
+                                    m_dragStartY=props.m_winY;
+                                    m_dragX=Fl::event_x();
+                                    m_dragY=Fl::event_y();
+                                    m_dragW=props.m_winW-Fl::event_x();
+                                    m_dragH=props.m_winH-Fl::event_y();
+                                }break;
+                                case ROTATE_270: {
+                                    m_dragStartX=props.m_winY;
+                                    m_dragStartY=props.m_winX;
+                                    m_dragX=Fl::event_x();
+                                    m_dragY=Fl::event_y();
+                                    m_dragW=props.m_winW-Fl::event_y();
+                                    m_dragH=props.m_winH+Fl::event_x();
+                                }break;
+                                default: {
+                                    m_dragStartX=props.m_winX;
+                                    m_dragStartY=props.m_winY;
+                                    m_dragX=Fl::event_x();
+                                    m_dragY=Fl::event_y();
+                                    m_dragW=props.m_winW+Fl::event_x();
+                                    m_dragH=props.m_winH+Fl::event_y();
+                                }break;
+                            }
+                        }
+                        m_dragging=true;
+                        res=1;
+                    }break;
+                    default:break;
+                }
+            }
+        }break;
+        case FL_DRAG: {
+            if(m_dragging) {
+                if(Fl::event_button()==FL_LEFT_MOUSE) {
+/*
+                    if(Fl::event_shift()) { //move/resize zone
+                        m_editing=true;
+                        if(Fl::event_command()) { 
+                            size(m_dragW+Fl::event_x(), m_dragH+Fl::event_y());
+                        }
+                        else {
+                            position(m_dragX+Fl::event_x(), 
+                                     m_dragY+Fl::event_y());
+                        }
+                    }
+*/
+                    if(m_state==MOVE_ZONE) {
+                        m_editing=true;
+                        position(m_dragX+Fl::event_x(), 
+                                 m_dragY+Fl::event_y());
+                    }
+                    else if(m_state==RESIZE_ZONE) {
+                        m_editing=true;
+                        size(max(float(OUTER*2), m_dragW+Fl::event_x()), 
+                             max(float(OUTER*2), m_dragH+Fl::event_y()));
+                    }
+                    else if(props.m_ovWin) { //move/resize window
+                        int transDW, transDH, transDX, transDY;
+                        switch(props.m_transfo) {
+                            case ROTATE_90: {
+                                transDW=m_dragW-Fl::event_y();
+                                transDH=m_dragH+Fl::event_x();
+                                transDX=m_dragStartY
+                                        - m_scaleX*(Fl::event_y()-m_dragY);
+                                transDY=m_dragStartX
+                                        + m_scaleY*(Fl::event_x()-m_dragX);
+                            }break;
+                            case ROTATE_180: {
+                                transDW=m_dragW+Fl::event_x();
+                                transDH=m_dragH+Fl::event_y();
+                                transDX=m_dragStartX
+                                        + m_scaleX*(Fl::event_x()-m_dragX);
+                                transDY=m_dragStartY
+                                        + m_scaleY*(Fl::event_y()-m_dragY);
+                            }break;
+                            case ROTATE_270: {
+                                transDW=m_dragW+Fl::event_y();
+                                transDH=m_dragH-Fl::event_x();
+                                transDX=m_dragStartY
+                                        + m_scaleX*(Fl::event_y()-m_dragY);
+                                transDY=m_dragStartX
+                                        - m_scaleY*(Fl::event_x()-m_dragX);
+                            }break;
+                            default: {
+                                transDW=m_dragW-Fl::event_x();
+                                transDH=m_dragH-Fl::event_y();
+                                transDX=m_dragStartX
+                                        - m_scaleX*(Fl::event_x()-m_dragX);
+                                transDY=m_dragStartY
+                                        - m_scaleY*(Fl::event_y()-m_dragY);
+                            }break;
+                        }
+                        //if(Fl::event_command()) {
+                        if(m_state==RESIZE_CUT) {
+                            props.m_winW = max(1, min(transDW,
+                                            props.m_ovWin->getWidth()));
+                            props.m_winH = max(1, min(transDH, 
+                                            props.m_ovWin->getHeight()));
+                            props.m_winX = max(0, min(props.m_winX, 
+                                            props.m_ovWin->getWidth()
+                                                - props.m_winW));
+                            props.m_winY = max(0, min(props.m_winY, 
+                                            props.m_ovWin->getHeight() 
+                                                - props.m_winH));
+                        }
+                        else {
+                            props.m_winX = max(0, min(transDX, 
+                                            props.m_ovWin->getWidth()
+                                                - props.m_winW));
+                            props.m_winY = max(0, min(transDY, 
+                                            props.m_ovWin->getHeight()
+                                                - props.m_winH));
+                        }
+                        recomputePixels();
+                    }
+                    res=1;
+                }
+            }
+        }break;
+        case FL_RELEASE: {
+            m_editing=false;
+            res=1;
+        }break;
+        case FL_SHORTCUT: {
+            if(m_highlight && Fl::event_key()==FL_Shift_L) {
+                m_editing=true;
+                return 1;
+            }
+            else  {
+                switch(Fl::event_key()) {
+                    case 'd': {
+                        m_forcedDragging=false;
+                        Controlar::getInstance()->startDuplicating(this);
+                        res=1;
+                    }break;
+                    case 'a': {
+                        props.m_alpha=(props.m_alpha<255)?props.m_alpha+10:255;
+                        res=1;
+                    }break;
+                    case 'q': {
+                        props.m_alpha=(props.m_alpha>0)?props.m_alpha-10:0;
+                        res=1;
+                    }break;
+                    case 's' : {
+                        props.m_shape = ZONE_SHAPE((props.m_shape+1)%NB_SHAPES);
+                        recomputePixels();
+                        res=1;
+                    }break;
+                    case 't' : {
+                        props.m_transfo 
+                            = ZONE_TRANSFO((props.m_transfo+1)%NB_TRANSFO);
+                        recomputePixels();
+                        res=1;
+                    }break;
+                    case 'c' : {
+                        props.m_color= ZONE_COLOR((props.m_color+1)%NB_COLORS);
+                        res=1;
+                    }break;
+                    case 'e' : {
+                        setInputEffect(ZONE_INPUT_EFFECT((props.m_effect+1)
+                                        %NB_EFFECTS));
+                        res=1;
+                    }break;
+                    case FL_Left : 
+                    case FL_Right : 
+                    case FL_Down :
+                    case FL_Up : {
+                        int transDX=props.m_winX;
+                        int transDY=props.m_winY;
+                        int transDW=props.m_ovWin->getWidth();
+                        int transDH=props.m_ovWin->getHeight();
+                        if((Fl::event_key()==FL_Left && props.m_transfo==NONE) 
+                                || (Fl::event_key()==FL_Right 
+                                        && props.m_transfo==ROTATE_180) 
+                                || (Fl::event_key()==FL_Down
+                                        && props.m_transfo==ROTATE_270) 
+                                || (Fl::event_key()==FL_Up
+                                        && props.m_transfo==ROTATE_90) ) {
+                            transDX-=10*m_scaleX;
+                            transDW-=10*m_scaleX;
+                        }
+                        else if((Fl::event_key()==FL_Right 
+                                    && props.m_transfo==NONE)
+                                || (Fl::event_key()==FL_Left 
+                                        && props.m_transfo==ROTATE_180) 
+                                || (Fl::event_key()==FL_Up
+                                        && props.m_transfo==ROTATE_270) 
+                                || (Fl::event_key()==FL_Down
+                                        && props.m_transfo==ROTATE_90) ) {
+                            transDX+=10*m_scaleX;
+                            transDW+=10*m_scaleX;
+                        }
+                        else if((Fl::event_key()==FL_Down 
+                                    && props.m_transfo==NONE) 
+                                || (Fl::event_key()==FL_Up 
+                                        && props.m_transfo==ROTATE_180) 
+                                || (Fl::event_key()==FL_Right
+                                        && props.m_transfo==ROTATE_270) 
+                                || (Fl::event_key()==FL_Left
+                                        && props.m_transfo==ROTATE_90) ) {
+                            transDY+=10*m_scaleY;
+                            transDH+=10*m_scaleY;
+                        }
+                        else if((Fl::event_key()==FL_Up 
+                                    && props.m_transfo==NONE) 
+                                || (Fl::event_key()==FL_Down
+                                        && props.m_transfo==ROTATE_180) 
+                                || (Fl::event_key()==FL_Left
+                                        && props.m_transfo==ROTATE_270) 
+                                || (Fl::event_key()==FL_Right
+                                        && props.m_transfo==ROTATE_90) ) {
+                            transDY-=10*m_scaleY;
+                            transDH-=10*m_scaleY;
+                        }
+                        if(Fl::event_command()) {
+                            props.m_winW = max(1, min(transDW,
+                                                props.m_ovWin->getWidth()));
+                            props.m_winH = max(1, min(transDH, 
+                                                props.m_ovWin->getHeight()));
+                            props.m_winX = max(0, min(props.m_winX, 
+                                                props.m_ovWin->getWidth()
+                                                - props.m_winW));
+                            props.m_winY = max(0, min(props.m_winY, 
+                                                props.m_ovWin->getHeight()
+                                                - props.m_winH));
+                        }
+                        else {
+                            props.m_winX = max(0, min(transDX, 
+                                                props.m_ovWin->getWidth()
+                                                - props.m_winW));
+                            props.m_winY = max(0, min(transDY, 
+                                                props.m_ovWin->getHeight()
+                                                - props.m_winH));
+                        }
+                        recomputePixels();
+                        res=1;
+                    }break;
+                }
+            }
+        }break;
+        case FL_KEYUP: {
+            if(m_highlight && Fl::event_key()==FL_Shift_L) {
+                m_editing=false;
+                res=1;
+            }
+        }break;
+        case FL_MOVE:{
+            if(!m_editing) {
+                int inPosX = Fl::event_x()-x();
+                int inPosY = Fl::event_y()-y();
+                if(inPosX>OUTER && inPosY>OUTER 
+                        && inPosX<w()-OUTER && inPosY<h()-OUTER) {
+                    if(sqrt(pow(inPosX-w(),2)+pow(inPosY-h(),2))<OUTER*3) {
+                        m_state=RESIZE_CUT;
+                    }
+                    else {
+                        m_state=MOVE_CUT;
+                    }
+                }
+                else {
+                    if(sqrt(pow(inPosX-w(),2)+pow(inPosY-h(),2))<OUTER) {
+                        m_state=RESIZE_ZONE;
+                    }
+                    else {
+                        m_state=MOVE_ZONE;
+                    }
+                }
+            }
+            if(m_forcedDragging) {
+                position(m_dragX+Fl::event_x(), 
+                         m_dragY+Fl::event_y());
+            }
+            res=1;
+        }break;
+        case FL_ENTER: {
+            m_highlight=true;
+            m_editing=false;
+            res=1;
+        }break;
+        case FL_LEAVE: {
+            m_state=NORMAL_STATE;
+            m_highlight=false;
+            m_editing=false;
+            res=1;
+        }break;
+        default:break;
+    }
+    if(res==1) {
+        parent()->redraw();
+    }
+    return res;
+}
+
+void ZoneWidget::forceDraggingZone() {
+    startDraggingZone();
+    m_forcedDragging=true;
+}
+
+void ZoneWidget::startDraggingZone() {
+    m_dragX=x()-Fl::event_x();
+    m_dragY=y()-Fl::event_y();
+    m_dragW=w()-Fl::event_x();
+    m_dragH=h()-Fl::event_y();
+}
+
+void ZoneWidget::resize(int nx, int ny, int nw, int nh) {
+    bool recImg=false;
+    if(nw!=w() || nh!=h()) {
+        recImg=true;
+    }
+    Fl_Widget::resize(nx, ny, nw, nh);
+    if(recImg) {
+        recreateImage();
+        recomputePixels();
+    }
+}
+
+void ZoneWidget::load(xmlNodePtr zoneNode) {
+    CutProps& props = m_cutProps[m_curCutProps];
+
+    char* value = NULL;
+
+    value = (char*)xmlGetProp(zoneNode,(xmlChar*)"win_name");
+    if(value!=NULL) {
+        props.m_ovWinName = string(value);
+        props.m_ovWin = Controlar::getInstance()->getWindow(props.m_ovWinName);
+    }
+
+    value = (char*)xmlGetProp(zoneNode,(xmlChar*)"win_x");
+    if(value!=NULL) {
+        props.m_winX = atoi(value);
+    }
+    value = (char*)xmlGetProp(zoneNode,(xmlChar*)"win_y");
+    if(value!=NULL) {
+        props.m_winY = atoi(value);
+    }
+    value = (char*)xmlGetProp(zoneNode,(xmlChar*)"win_w");
+    if(value!=NULL) {
+        props.m_winW = atoi(value);
+    }
+    value = (char*)xmlGetProp(zoneNode,(xmlChar*)"win_h");
+    if(value!=NULL) {
+        props.m_winH = atoi(value);
+    }
+    int x=0,y=0,w=20,h=20;
+    value = (char*)xmlGetProp(zoneNode,(xmlChar*)"zone_x");
+    if(value!=NULL) {
+        x = atoi(value);
+    }
+    value = (char*)xmlGetProp(zoneNode,(xmlChar*)"zone_y");
+    if(value!=NULL) {
+        y = atoi(value);
+    }
+    value = (char*)xmlGetProp(zoneNode,(xmlChar*)"zone_w");
+    if(value!=NULL) {
+        w = atoi(value);
+    }
+    value = (char*)xmlGetProp(zoneNode,(xmlChar*)"zone_h");
+    if(value!=NULL) {
+        h = atoi(value);
+    }
+    value = (char*)xmlGetProp(zoneNode,(xmlChar*)"alpha");
+    if(value!=NULL) {
+        props.m_alpha = atoi(value);
+    }
+    value = (char*)xmlGetProp(zoneNode,(xmlChar*)"transform");
+    if(value!=NULL) {
+        props.m_transfo = ZONE_TRANSFO(atoi(value));
+    }
+    value = (char*)xmlGetProp(zoneNode,(xmlChar*)"shape");
+    if(value!=NULL) {
+        props.m_shape = ZONE_SHAPE(atoi(value));
+    }
+    value = (char*)xmlGetProp(zoneNode,(xmlChar*)"effect");
+    if(value!=NULL) {
+        setInputEffect(ZONE_INPUT_EFFECT(atoi(value)));
+    }
+    value = (char*)xmlGetProp(zoneNode,(xmlChar*)"color");
+    if(value!=NULL) {
+        setColor(ZONE_COLOR(atoi(value)));
+    }
+    value = (char*)xmlGetProp(zoneNode,(xmlChar*)"midi_type");
+    if(value!=NULL) {
+        m_midiType=atoi(value);
+    }
+    value = (char*)xmlGetProp(zoneNode,(xmlChar*)"midi_channel");
+    if(value!=NULL) {
+        m_midiChannel=atoi(value);
+    }
+    value = (char*)xmlGetProp(zoneNode,(xmlChar*)"midi_control");
+    if(value!=NULL) {
+        m_midiControl=atoi(value);
+    }
+    value = (char*)xmlGetProp(zoneNode,(xmlChar*)"visible");
+    if(value!=NULL) {
+        m_visibleInScene=atoi(value);
+    }
+    value = (char*)xmlGetProp(zoneNode,(xmlChar*)"update");
+    if(value!=NULL) {
+        m_updateInScene=atoi(value);
+    }
+    value = (char*)xmlGetProp(zoneNode,(xmlChar*)"content");
+    if(value!=NULL) {
+        m_content=ZONE_CONTENT(atoi(value));
+    }
+    resize(x,y,w,h);
+}
+
+void ZoneWidget::save(xmlNodePtr parentNode) {
+    CutProps& props = m_cutProps[m_curCutProps];
+    xmlNodePtr newNode = xmlNewChild(parentNode, NULL, 
+                                      BAD_CAST "Zone", NULL);
+    if(props.m_ovWin) {
+        xmlNewProp(newNode, BAD_CAST "win_name", 
+                   BAD_CAST props.m_ovWinName.c_str());
+    }
+    ostringstream oss1, oss2, oss3, oss4, oss5, 
+                  oss6, oss7, oss8, oss9, oss10, 
+                  oss11, oss12, oss13, oss14, oss15,
+                  oss16, oss17, oss18, oss19;
+    oss1<<props.m_winX;
+    xmlNewProp(newNode, BAD_CAST "win_x", 
+               BAD_CAST oss1.str().c_str());
+    oss2<<props.m_winY;
+    xmlNewProp(newNode, BAD_CAST "win_y", 
+               BAD_CAST oss2.str().c_str());
+    oss3<<props.m_winW;
+    xmlNewProp(newNode, BAD_CAST "win_w", 
+               BAD_CAST oss3.str().c_str());
+    oss4<<props.m_winH;
+    xmlNewProp(newNode, BAD_CAST "win_h", 
+               BAD_CAST oss4.str().c_str());
+    oss5<<x();
+    xmlNewProp(newNode, BAD_CAST "zone_x", 
+               BAD_CAST oss5.str().c_str());
+    oss6<<y();
+    xmlNewProp(newNode, BAD_CAST "zone_y", 
+               BAD_CAST oss6.str().c_str());
+    oss7<<w();
+    xmlNewProp(newNode, BAD_CAST "zone_w", 
+               BAD_CAST oss7.str().c_str());
+    oss8<<h();
+    xmlNewProp(newNode, BAD_CAST "zone_h", 
+               BAD_CAST oss8.str().c_str());
+    oss9<<props.m_alpha;
+    xmlNewProp(newNode, BAD_CAST "alpha", 
+               BAD_CAST oss9.str().c_str());
+    oss10<<props.m_transfo;
+    xmlNewProp(newNode, BAD_CAST "transform", 
+               BAD_CAST oss10.str().c_str());
+    oss11<<props.m_shape;
+    xmlNewProp(newNode, BAD_CAST "shape", 
+               BAD_CAST oss11.str().c_str());
+    oss12<<props.m_effect;
+    xmlNewProp(newNode, BAD_CAST "effect", 
+               BAD_CAST oss12.str().c_str());
+    oss13<<m_midiType;
+    xmlNewProp(newNode, BAD_CAST "midi_type", 
+               BAD_CAST oss13.str().c_str());
+    oss14<<m_midiChannel;
+    xmlNewProp(newNode, BAD_CAST "midi_channel", 
+               BAD_CAST oss14.str().c_str());
+    oss15<<m_midiControl;
+    xmlNewProp(newNode, BAD_CAST "midi_control", 
+               BAD_CAST oss15.str().c_str());
+    oss16<<props.m_color;
+    xmlNewProp(newNode, BAD_CAST "color", 
+               BAD_CAST oss16.str().c_str());
+    oss17<<m_visibleInScene;
+    xmlNewProp(newNode, BAD_CAST "visible", 
+               BAD_CAST oss17.str().c_str());
+    oss18<<m_updateInScene;
+    xmlNewProp(newNode, BAD_CAST "update", 
+               BAD_CAST oss18.str().c_str());
+    oss19<<m_content;
+    xmlNewProp(newNode, BAD_CAST "content", 
+               BAD_CAST oss19.str().c_str());
+}
+
+
diff --git a/src/ZoneWidget.hpp b/src/ZoneWidget.hpp
new file mode 100644
index 0000000..ebbbe36
--- /dev/null
+++ b/src/ZoneWidget.hpp
@@ -0,0 +1,195 @@
+/***************************************************************************
+ *  ZoneWidget.hpp
+ *  Part of 
+ *  2016-  Florent Berthaut
+ *  hitmuri.net
+ ****************************************************************************/
+/*
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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 General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef ZoneWidget_h
+#define ZoneWidget_h
+
+#include <FL/Fl.H>
+#include <FL/Fl_Widget.H>
+#include <FL/fl_draw.H>
+#include <GL/glew.h>
+#include <FL/gl.h>
+
+#include <libxml/parser.h>
+#include <libxml/tree.h>
+
+#include <sys/time.h>
+#include <string>
+#include <vector>
+#include <map>
+
+class CutWindow;
+
+class ZoneWidget : public Fl_Widget {
+
+    public:
+        enum ZONE_TRANSFO{NONE, ROTATE_90, ROTATE_180, ROTATE_270, NB_TRANSFO};
+        enum ZONE_SHAPE{BOX, CIRCLE, FRAME, NB_SHAPES};
+        enum ZONE_INPUT_EFFECT{NO_EFFECT, SHOW, HIDE, NB_EFFECTS};
+        enum ZONE_COLOR{NORMAL, INVERT, NB_COLORS};
+        enum ZONE_VISIBLE{VISIBLE_ALL, VISIBLE_CURRENT};
+        enum ZONE_UPDATE{UPDATE_ALL, UPDATE_CURRENT, NB_UPDATES};
+        enum ZONE_CONTENT{CONTENT_GLOBAL, CONTENT_LOCAL, NB_CONTENTS};
+        enum ZONE_STATE{NORMAL_STATE,MOVE_CUT,RESIZE_CUT,MOVE_ZONE,RESIZE_ZONE};
+
+        static const int INNER=20;
+        static const int OUTER=20;
+
+    struct CutProps {
+        CutProps(): m_ovWin(NULL), m_ovWinName(""), m_winX(0), m_winY(0), 
+                    m_winW(0), m_winH(0), m_alpha(255), m_transfo(NONE), 
+                    m_color(NORMAL), m_shape(BOX), m_effect(NO_EFFECT){}
+        CutWindow* m_ovWin;
+        std::string m_ovWinName;
+        int m_winX, m_winY;
+        int m_winW, m_winH;
+        int m_alpha;
+        ZONE_TRANSFO m_transfo;
+        ZONE_COLOR m_color;
+        ZONE_SHAPE m_shape;
+        ZONE_INPUT_EFFECT m_effect;
+    };
+
+    public:
+        ZoneWidget(int x=0, int y=0, int w=10, int h=10);
+        ~ZoneWidget();
+        void copy(ZoneWidget*);
+        inline void draw(){drawZone(-1);}
+        void drawZone(const int&);
+        int handle(int event);
+        void setCutWin(CutWindow* ow);
+        CutWindow* getCutWin();
+        void save(xmlNodePtr parentNode);
+        void load(xmlNodePtr);
+        void resize(int x, int y, int w, int h);
+        inline void setID(const unsigned int& id){m_id=id;}
+        inline const unsigned int& getID(){return m_id;}
+        inline void setAlpha(const int& alpha) { 
+            m_cutProps[m_curCutProps].m_alpha=alpha;
+            recomputePixels();
+        }
+        inline const int& getAlpha(){return m_cutProps[m_curCutProps].m_alpha;}
+        inline void setTransformation(const ZONE_TRANSFO& transfo) { 
+            m_cutProps[m_curCutProps].m_transfo=transfo;
+            recomputePixels();
+        }
+        inline const ZONE_TRANSFO& getTransformation() { 
+            return m_cutProps[m_curCutProps].m_transfo;
+        }
+        inline void setShape(const ZONE_SHAPE& shape) {
+            m_cutProps[m_curCutProps].m_shape=shape;
+            recomputePixels();
+        }
+        inline const ZONE_SHAPE& getShape() { 
+            return m_cutProps[m_curCutProps].m_shape;
+        }
+        void setScene(const int& scene);
+        void setInputEffect(const ZONE_INPUT_EFFECT& effect);
+        inline const ZONE_INPUT_EFFECT& getEffect() { 
+            return m_cutProps[m_curCutProps].m_effect;
+        }
+        void setColor(const ZONE_COLOR& color) { 
+            m_cutProps[m_curCutProps].m_color=color;
+        }
+        inline const ZONE_COLOR& getColor() { 
+            return m_cutProps[m_curCutProps].m_color;
+        }
+        void setVisible(const int& vis=-1);
+        void setUpdate(const int& up=-1);
+        inline int getUpdate(){return m_updateInScene;}
+        inline ZONE_UPDATE getZoneUpdate() { 
+            return ZONE_UPDATE(m_updateInScene>=0);
+        }
+        void setContent(const ZONE_CONTENT& cont);
+        inline const ZONE_CONTENT& getContent() { 
+            return m_content;
+        }
+        inline void learnMidi(){m_midiLearning=true;}
+        void refreshCutWin();
+        void startDraggingZone();
+        void forceDraggingZone();
+        inline void setRateReached(){m_rateReached=true;}
+
+        void processMidi(const int& midiType, 
+                         const int& midiChannel, 
+                         const int& midiControl,
+                         const int& midiValue);
+
+        void recomputePixels();
+
+    private:
+        void recreateImage();
+
+    private:
+        unsigned int m_id;
+//        CutWindow* m_ovWin;
+//        std::string m_ovWinName;
+        Fl_RGB_Image* m_image;
+        uchar* m_imageData;
+/*
+        int m_winX, m_winY;
+        int m_winW, m_winH;
+*/
+        std::map<int, CutProps> m_cutProps;
+        static const int GLOBAL_PROPS=-1;
+        int m_curCutProps;
+        int m_currentScene;
+
+        ZONE_STATE m_state;
+        bool m_editing;
+        bool m_highlight;
+        bool m_dragging;
+        bool m_forcedDragging;
+        float m_dragX, m_dragY;
+        float m_dragW, m_dragH;
+        float m_dragStartX, m_dragStartY;
+        float m_scaleX, m_scaleY;
+        int m_nbPixPerRow;
+        std::vector<int> m_srcIndices;
+        std::vector<std::vector<int> > m_srcCoords;
+        std::vector<int> m_destIndices;
+/*
+        int m_alpha;
+        ZONE_TRANSFO m_transfo;
+        ZONE_SHAPE m_shape;
+*/
+        bool m_rateReached;
+//        ZONE_COLOR m_color;
+        ZONE_CONTENT m_content;
+        bool m_midiLearning;
+        int m_midiControl;
+        int m_midiChannel;
+        int m_midiType;
+//        ZONE_INPUT_EFFECT m_effect;
+        timeval m_effectDelay;
+        timeval m_effectStartTime;
+        bool m_hiddenByEffect;
+        bool m_effectDelayOver;
+        bool m_initialized;
+        float* m_coordImage;
+        int m_visibleInScene;
+        int m_updateInScene;
+};
+
+
+#endif
+
diff --git a/src/mac/MacWindow.cpp b/src/mac/MacWindow.cpp
new file mode 100644
index 0000000..5c30444
--- /dev/null
+++ b/src/mac/MacWindow.cpp
@@ -0,0 +1,172 @@
+/***************************************************************************
+ *  MacWindow.cpp
+ *  Part of 
+ *  2016-  Florent Berthaut
+ *  hitmuri.net
+ ****************************************************************************/
+/*
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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 General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "MacWindow.hpp"
+#include <iostream>
+
+#include "../Controlar.hpp"
+
+using namespace std;
+
+MacWindow::MacWindow(CutWindowsManager* man, CGWindowID id): CutWindow(man) { 
+    CGRect rect = CGRectMake(0, 0, 100, 100);
+    m_idCArray[0] = id;
+    m_idArray = CFArrayCreate(NULL, (const void **) m_idCArray, 1, NULL);
+    CFArrayRef descArray = CGWindowListCreateDescriptionFromArray(m_idArray);
+    if(CFArrayGetCount(descArray)>0) {
+        CFDictionaryRef description = 
+            (CFDictionaryRef) CFArrayGetValueAtIndex(descArray, 0);
+        if (CFDictionaryContainsKey(description, kCGWindowBounds)) {
+            CFDictionaryRef bounds = 
+                    (CFDictionaryRef) CFDictionaryGetValue(description, 
+                                                           kCGWindowBounds);
+            if (bounds) {
+                CGRectMakeWithDictionaryRepresentation(bounds, &rect);
+            }
+        }
+    }
+    CFRelease(descArray);
+
+    m_posX = rect.origin.x; 
+    m_posY = rect.origin.y; 
+    m_width = rect.size.width;
+    m_height = rect.size.height;
+    m_offsetX = m_posX;
+    m_offsetY = m_posY;
+    m_pixPerRow = m_width;
+    m_isBGR=true;
+    m_needsOffset=true;
+    m_pixPerRow=m_width;
+    m_grabbed=false;
+    m_defaultImgData = new uchar[m_width*m_height*3];
+}
+
+MacWindow::~MacWindow() {
+    CFRelease(m_idArray);
+}
+
+int MacWindow::computeNbPixPerRow(const int& srcW, const int& srcH) {
+    CGImageRef img = CGWindowListCreateImageFromArray(CGRectNull,
+                                         m_idArray,
+                                         kCGWindowImageBoundsIgnoreFraming);
+         
+    int nb = CGImageGetBytesPerRow(img)/4;
+    m_width=CGImageGetWidth(img)*Controlar::getInstance()->getDisplayScale();
+    m_height=CGImageGetHeight(img)*Controlar::getInstance()->getDisplayScale();
+    CFRelease(img);
+    return nb;
+}
+
+void MacWindow::getPixels(const int& srcX, const int& srcY, 
+                          const int& srcW, const int& srcH, 
+                          const vector<int>& srcIndices,
+                          const vector<vector<int> >& srcCoords,
+                          const vector<int>& destIndices,
+                          const uchar& alpha,
+                          const ZoneWidget::ZONE_COLOR& color,
+                          uchar* destImg) {
+    //CGRect rect = CGRectMake(m_posX+srcX, m_posY+srcY, srcW, srcH);
+    //CGImageRef img = CGWindowListCreateImageFromArray(rect,
+    CGImageRef img = CGWindowListCreateImageFromArray(CGRectNull,
+                                             m_idArray,
+                                             kCGWindowImageBoundsIgnoreFraming);
+    if(img!=NULL) {
+        CFDataRef data = CGDataProviderCopyData(CGImageGetDataProvider(img));
+        uchar* buf = (uchar*)CFDataGetBytePtr(data);
+        vector<int>::const_iterator itId = srcIndices.begin();
+        vector<vector<int> >::const_iterator itCo = srcCoords.begin();
+        vector<int>::const_iterator itDe = destIndices.begin();
+        for(; itCo!=srcCoords.end(); ++itCo) {
+            if((*itCo)[0]>=0) { 
+                //copy rgb
+                for(int c=0; c<3; ++c) {
+                    destImg[(*itDe)] = (color==ZoneWidget::NORMAL)
+                                            ?buf[(*itId)]
+                                            :255-buf[(*itId)];
+                    ++itId;
+                    ++itDe;
+                }
+                //copy alpha
+                destImg[(*itDe)] = alpha;
+                ++itId;
+                ++itDe;
+            }
+            else { //black
+                for(int c=0; c<4; ++c) {
+                    destImg[(*itDe)] = 0;
+                    ++itId;
+                    ++itDe;
+                }
+            }
+        }
+        //release CG stuff
+        CFRelease(data);
+        CFRelease(img);
+    }
+    else {
+        cout<<"Error getting image of window "<<m_name<<endl;
+    }
+}
+
+void MacWindow::releaseImage() {
+    if(m_grabbed) {
+        CFRelease(m_data);
+        CFRelease(m_img);
+        m_grabbed=false;
+    }
+}
+
+uchar* MacWindow::grabImage() {
+    if(!m_grabbed) {
+        m_img = CGWindowListCreateImageFromArray(CGRectNull,
+                                            m_idArray,
+                                            kCGWindowImageBoundsIgnoreFraming);
+        if(m_img) {
+            m_data = CGDataProviderCopyData(CGImageGetDataProvider(m_img));
+            m_imgData = (uchar*)CFDataGetBytePtr(m_data);
+            m_grabbed=true;
+        }
+        else {
+            m_imgData=m_defaultImgData;
+        }
+    }
+    return m_imgData;
+}
+
+void MacWindow::storeImage(const int& id) {
+    int size = m_pixPerRow*m_height*4;
+    if(m_storedImgData.find(id)!=m_storedImgData.end()) {
+        delete [] m_storedImgData[id];
+    }
+    m_storedImgData[id] = new uchar[size];
+    memcpy(m_storedImgData[id], m_imgData, size);
+}
+
+uchar* MacWindow::retrieveImage(const int& id) {
+    map<int, uchar*>::iterator itSt = m_storedImgData.find(id);
+    if(itSt!=m_storedImgData.end()) {
+        return itSt->second;
+    }
+    return NULL;
+}
+
+
diff --git a/src/mac/MacWindow.hpp b/src/mac/MacWindow.hpp
new file mode 100644
index 0000000..9ace8e9
--- /dev/null
+++ b/src/mac/MacWindow.hpp
@@ -0,0 +1,62 @@
+/***************************************************************************
+ *  MacWindow.hpp
+ *  Part of 
+ *  2016-  Florent Berthaut
+ *  hitmuri.net
+ ****************************************************************************/
+/*
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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 General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#ifndef MacWindow_h
+#define MacWindow_h
+
+#include <vector>
+#include <string>
+
+#include "../CutWindow.hpp"
+#import <ApplicationServices/ApplicationServices.h>
+//#import <Cocoa/Cocoa.h>
+//#import <QuartzCore/QuartzCore.h>
+//#import <AppKit/AppKit.h>
+
+class MacWindow: public CutWindow {
+    public :
+        MacWindow(CutWindowsManager* man, CGWindowID winID);
+        virtual ~MacWindow();
+        virtual void getPixels(const int& x, const int& y, 
+                               const int& sx, const int& sy,
+                               const std::vector<int>& srcIndices,
+                               const std::vector<std::vector<int> >& srcCoords,
+                               const std::vector<int>& destIndices,
+                               const uchar& alpha,
+                               const ZoneWidget::ZONE_COLOR& color,
+                               uchar* destImg);
+        int computeNbPixPerRow(const int& srcW, const int& srcH);
+        virtual uchar* grabImage();
+        virtual void releaseImage();
+        virtual void storeImage(const int& id);
+        virtual uchar* retrieveImage(const int& id);
+
+    protected:
+        CGWindowID m_idCArray[1];
+        CFArrayRef m_idArray;
+        CGImageRef m_img;
+        CFDataRef m_data;
+};
+
+#endif
+
diff --git a/src/mac/MacWindowsManager.cpp b/src/mac/MacWindowsManager.cpp
new file mode 100644
index 0000000..43d09d0
--- /dev/null
+++ b/src/mac/MacWindowsManager.cpp
@@ -0,0 +1,89 @@
+/***************************************************************************
+ *  MacWindowsManager.cpp
+ *  Part of 
+ *  2016-  Florent Berthaut
+ *  hitmuri.net
+ ****************************************************************************/
+/*
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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 General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/*
+    Relies on code from:
+    https://github.com/JoelSjogren/window-copy/blob/master/windowutils.cpp
+*/
+
+#include "MacWindowsManager.hpp"
+#include <iostream>
+#include <stdlib.h>
+
+#include "../Controlar.hpp"
+
+using namespace std;
+
+MacWindowsManager::MacWindowsManager(): CutWindowsManager() {}
+
+MacWindowsManager::~MacWindowsManager() {}
+
+void MacWindowsManager::updateWindowsList() {
+    map<unsigned int, CutWindow*> eraseWindows = m_windowMap;
+    m_windowList.clear();
+    CFArrayRef windowArray = 
+      CGWindowListCreate(kCGWindowListExcludeDesktopElements
+                         |kCGWindowListOptionOnScreenOnly, kCGNullWindowID);
+    CFArrayRef descArray = CGWindowListCreateDescriptionFromArray(windowArray);
+    if(descArray!=NULL) {
+        for(int i=0; i<CFArrayGetCount(descArray); ++i) {
+            CFDictionaryRef win = 
+                (CFDictionaryRef)CFArrayGetValueAtIndex(descArray,i);
+            CFStringRef name = 
+                (CFStringRef) CFDictionaryGetValue(win, kCGWindowName);
+            if(name!=NULL) {
+                if(CFStringGetLength(name)>0) {
+                    char tempStr[128];
+                    CFStringGetCString(name,tempStr,128,kCFStringEncodingUTF8);
+                    string nameStr(tempStr);
+                    unsigned int winID=(uintptr_t)
+                                    CFArrayGetValueAtIndex(windowArray,i);
+                    if(m_windowMap.find(winID)==m_windowMap.end()) {
+                        MacWindow* newWin 
+                            = new MacWindow(this, 
+                               (CGWindowID)(uintptr_t)
+                                    CFArrayGetValueAtIndex(windowArray,i));
+                        newWin->setName(nameStr);
+                        newWin->setWinID(winID);
+                        m_windowMap[winID]=newWin;
+                    }
+                    m_windowList.push_back(m_windowMap[winID]);
+                    eraseWindows.erase(winID);
+                }
+            }
+            CFRelease(win);
+        }
+
+        //remove/delete windows not present anymore
+        map<unsigned int, CutWindow*>::iterator itWin = eraseWindows.begin();
+        for(; itWin!=eraseWindows.end(); ++itWin) {
+            m_windowMap.erase(itWin->first);
+            delete itWin->second;
+        }
+    }
+    else {
+        cout<<"Error: No windows found"<<endl;
+    }
+
+}
+
+
diff --git a/src/mac/MacWindowsManager.hpp b/src/mac/MacWindowsManager.hpp
new file mode 100644
index 0000000..f3d5590
--- /dev/null
+++ b/src/mac/MacWindowsManager.hpp
@@ -0,0 +1,42 @@
+/***************************************************************************
+ *  MacWindowsManager.hpp
+ *  Part of Over 
+ *  2013  Florent Berthaut
+ *  hitmuri.net
+ ****************************************************************************/
+/*
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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 General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#ifndef MacWindowsManager_h
+#define MacWindowsManager_h
+
+#include <vector>
+#include <string>
+
+#include "../CutWindowsManager.hpp"
+#include "MacWindow.hpp"
+
+class MacWindowsManager : public CutWindowsManager {
+    public :
+        MacWindowsManager();
+        virtual ~MacWindowsManager();
+        virtual void updateWindowsList();
+    protected:
+};
+
+#endif
+
diff --git a/src/osc/ip/IpEndpointName.cpp b/src/osc/ip/IpEndpointName.cpp
new file mode 100755
index 0000000..33fdd98
--- /dev/null
+++ b/src/osc/ip/IpEndpointName.cpp
@@ -0,0 +1,81 @@
+/*
+	oscpack -- Open Sound Control packet manipulation library
+	http://www.audiomulch.com/~rossb/oscpack
+
+	Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>
+
+	Permission is hereby granted, free of charge, to any person obtaining
+	a copy of this software and associated documentation files
+	(the "Software"), to deal in the Software without restriction,
+	including without limitation the rights to use, copy, modify, merge,
+	publish, distribute, sublicense, and/or sell copies of the Software,
+	and to permit persons to whom the Software is furnished to do so,
+	subject to the following conditions:
+
+	The above copyright notice and this permission notice shall be
+	included in all copies or substantial portions of the Software.
+
+	Any person wishing to distribute modifications to the Software is
+	requested to send the modifications to the original developer so that
+	they can be incorporated into the canonical version.
+
+	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+	EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+	MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+	IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+	ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+	CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+	WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+#include "IpEndpointName.h"
+
+#include <stdio.h>
+
+#include "NetworkingUtils.h"
+
+
+unsigned long IpEndpointName::GetHostByName( const char *s )
+{
+	return ::GetHostByName(s);
+}
+
+
+void IpEndpointName::AddressAsString( char *s ) const
+{
+	if( address == ANY_ADDRESS ){
+		sprintf( s, "<any>" );
+	}else{
+		sprintf( s, "%d.%d.%d.%d",
+				(int)((address >> 24) & 0xFF),
+				(int)((address >> 16) & 0xFF),
+				(int)((address >> 8) & 0xFF),
+				(int)(address & 0xFF) );
+	}
+}
+
+
+void IpEndpointName::AddressAndPortAsString( char *s ) const
+{
+	if( port == ANY_PORT ){
+		if( address == ANY_ADDRESS ){
+			sprintf( s, "<any>:<any>" );
+		}else{
+			sprintf( s, "%d.%d.%d.%d:<any>",
+				(int)((address >> 24) & 0xFF),
+				(int)((address >> 16) & 0xFF),
+				(int)((address >> 8) & 0xFF),
+				(int)(address & 0xFF) );
+		}
+	}else{
+		if( address == ANY_ADDRESS ){
+			sprintf( s, "<any>:%d", port );
+		}else{
+			sprintf( s, "%d.%d.%d.%d:%d",
+				(int)((address >> 24) & 0xFF),
+				(int)((address >> 16) & 0xFF),
+				(int)((address >> 8) & 0xFF),
+				(int)(address & 0xFF),
+				(int)port );
+		}
+	}	
+}
diff --git a/src/osc/ip/IpEndpointName.h b/src/osc/ip/IpEndpointName.h
new file mode 100755
index 0000000..c7b078e
--- /dev/null
+++ b/src/osc/ip/IpEndpointName.h
@@ -0,0 +1,74 @@
+/*
+	oscpack -- Open Sound Control packet manipulation library
+	http://www.audiomulch.com/~rossb/oscpack
+
+	Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>
+
+	Permission is hereby granted, free of charge, to any person obtaining
+	a copy of this software and associated documentation files
+	(the "Software"), to deal in the Software without restriction,
+	including without limitation the rights to use, copy, modify, merge,
+	publish, distribute, sublicense, and/or sell copies of the Software,
+	and to permit persons to whom the Software is furnished to do so,
+	subject to the following conditions:
+
+	The above copyright notice and this permission notice shall be
+	included in all copies or substantial portions of the Software.
+
+	Any person wishing to distribute modifications to the Software is
+	requested to send the modifications to the original developer so that
+	they can be incorporated into the canonical version.
+
+	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+	EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+	MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+	IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+	ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+	CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+	WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+#ifndef INCLUDED_IPENDPOINTNAME_H
+#define INCLUDED_IPENDPOINTNAME_H
+
+
+class IpEndpointName{
+    static unsigned long GetHostByName( const char *s );
+public:
+    static const unsigned long ANY_ADDRESS = 0xFFFFFFFF;
+    static const int ANY_PORT = -1;
+
+    IpEndpointName()
+		: address( ANY_ADDRESS ), port( ANY_PORT ) {}
+    IpEndpointName( int port_ ) 
+		: address( ANY_ADDRESS ), port( port_ ) {}
+    IpEndpointName( unsigned long ipAddress_, int port_ ) 
+		: address( ipAddress_ ), port( port_ ) {}
+    IpEndpointName( const char *addressName, int port_=ANY_PORT )
+		: address( GetHostByName( addressName ) )
+		, port( port_ ) {}
+    IpEndpointName( int addressA, int addressB, int addressC, int addressD, int port_=ANY_PORT )
+		: address( ( (addressA << 24) | (addressB << 16) | (addressC << 8) | addressD ) )
+		, port( port_ ) {}
+
+	// address and port are maintained in host byte order here
+    unsigned long address;
+    int port;
+
+	enum { ADDRESS_STRING_LENGTH=17 };
+	void AddressAsString( char *s ) const;
+
+	enum { ADDRESS_AND_PORT_STRING_LENGTH=23};
+	void AddressAndPortAsString( char *s ) const;
+};
+
+inline bool operator==( const IpEndpointName& lhs, const IpEndpointName& rhs )
+{	
+	return (lhs.address == rhs.address && lhs.port == rhs.port );
+}
+
+inline bool operator!=( const IpEndpointName& lhs, const IpEndpointName& rhs )
+{
+	return !(lhs == rhs);
+}
+
+#endif /* INCLUDED_IPENDPOINTNAME_H */
diff --git a/src/osc/ip/NetworkingUtils.h b/src/osc/ip/NetworkingUtils.h
new file mode 100755
index 0000000..0d6901c
--- /dev/null
+++ b/src/osc/ip/NetworkingUtils.h
@@ -0,0 +1,49 @@
+/*
+	oscpack -- Open Sound Control packet manipulation library
+	http://www.audiomulch.com/~rossb/oscpack
+
+	Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>
+
+	Permission is hereby granted, free of charge, to any person obtaining
+	a copy of this software and associated documentation files
+	(the "Software"), to deal in the Software without restriction,
+	including without limitation the rights to use, copy, modify, merge,
+	publish, distribute, sublicense, and/or sell copies of the Software,
+	and to permit persons to whom the Software is furnished to do so,
+	subject to the following conditions:
+
+	The above copyright notice and this permission notice shall be
+	included in all copies or substantial portions of the Software.
+
+	Any person wishing to distribute modifications to the Software is
+	requested to send the modifications to the original developer so that
+	they can be incorporated into the canonical version.
+
+	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+	EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+	MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+	IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+	ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+	CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+	WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+#ifndef INCLUDED_NETWORKINGUTILS_H
+#define INCLUDED_NETWORKINGUTILS_H
+
+
+// in general NetworkInitializer is only used internally, but if you're 
+// application creates multiple sockets from different threads at runtime you
+// should instantiate one of these in main just to make sure the networking
+// layer is initialized.
+class NetworkInitializer{
+public:
+    NetworkInitializer();
+    ~NetworkInitializer();
+};
+
+
+// return ip address of host name in host byte order
+unsigned long GetHostByName( const char *name );
+
+
+#endif /* INCLUDED_NETWORKINGUTILS_H */
diff --git a/src/osc/ip/PacketListener.h b/src/osc/ip/PacketListener.h
new file mode 100755
index 0000000..6647209
--- /dev/null
+++ b/src/osc/ip/PacketListener.h
@@ -0,0 +1,43 @@
+/*
+	oscpack -- Open Sound Control packet manipulation library
+	http://www.audiomulch.com/~rossb/oscpack
+
+	Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>
+
+	Permission is hereby granted, free of charge, to any person obtaining
+	a copy of this software and associated documentation files
+	(the "Software"), to deal in the Software without restriction,
+	including without limitation the rights to use, copy, modify, merge,
+	publish, distribute, sublicense, and/or sell copies of the Software,
+	and to permit persons to whom the Software is furnished to do so,
+	subject to the following conditions:
+
+	The above copyright notice and this permission notice shall be
+	included in all copies or substantial portions of the Software.
+
+	Any person wishing to distribute modifications to the Software is
+	requested to send the modifications to the original developer so that
+	they can be incorporated into the canonical version.
+
+	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+	EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+	MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+	IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+	ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+	CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+	WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+#ifndef INCLUDED_PACKETLISTENER_H
+#define INCLUDED_PACKETLISTENER_H
+
+
+class IpEndpointName;
+
+class PacketListener{
+public:
+    virtual ~PacketListener() {}
+    virtual void ProcessPacket( const char *data, int size, 
+			const IpEndpointName& remoteEndpoint ) = 0;
+};
+
+#endif /* INCLUDED_PACKETLISTENER_H */
diff --git a/src/osc/ip/TimerListener.h b/src/osc/ip/TimerListener.h
new file mode 100755
index 0000000..82b1181
--- /dev/null
+++ b/src/osc/ip/TimerListener.h
@@ -0,0 +1,40 @@
+/*
+	oscpack -- Open Sound Control packet manipulation library
+	http://www.audiomulch.com/~rossb/oscpack
+
+	Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>
+
+	Permission is hereby granted, free of charge, to any person obtaining
+	a copy of this software and associated documentation files
+	(the "Software"), to deal in the Software without restriction,
+	including without limitation the rights to use, copy, modify, merge,
+	publish, distribute, sublicense, and/or sell copies of the Software,
+	and to permit persons to whom the Software is furnished to do so,
+	subject to the following conditions:
+
+	The above copyright notice and this permission notice shall be
+	included in all copies or substantial portions of the Software.
+
+	Any person wishing to distribute modifications to the Software is
+	requested to send the modifications to the original developer so that
+	they can be incorporated into the canonical version.
+
+	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+	EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+	MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+	IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+	ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+	CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+	WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+#ifndef INCLUDED_TIMERLISTENER_H
+#define INCLUDED_TIMERLISTENER_H
+
+
+class TimerListener{
+public:
+    virtual ~TimerListener() {}
+    virtual void TimerExpired() = 0;
+};
+
+#endif /* INCLUDED_TIMERLISTENER_H */
diff --git a/src/osc/ip/UdpSocket.h b/src/osc/ip/UdpSocket.h
new file mode 100755
index 0000000..6d9c26d
--- /dev/null
+++ b/src/osc/ip/UdpSocket.h
@@ -0,0 +1,158 @@
+/*
+	oscpack -- Open Sound Control packet manipulation library
+	http://www.audiomulch.com/~rossb/oscpack
+
+	Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>
+
+	Permission is hereby granted, free of charge, to any person obtaining
+	a copy of this software and associated documentation files
+	(the "Software"), to deal in the Software without restriction,
+	including without limitation the rights to use, copy, modify, merge,
+	publish, distribute, sublicense, and/or sell copies of the Software,
+	and to permit persons to whom the Software is furnished to do so,
+	subject to the following conditions:
+
+	The above copyright notice and this permission notice shall be
+	included in all copies or substantial portions of the Software.
+
+	Any person wishing to distribute modifications to the Software is
+	requested to send the modifications to the original developer so that
+	they can be incorporated into the canonical version.
+
+	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+	EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+	MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+	IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+	ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+	CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+	WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+#ifndef INCLUDED_UDPSOCKET_H
+#define INCLUDED_UDPSOCKET_H
+
+#ifndef INCLUDED_NETWORKINGUTILITIES_H
+#include "NetworkingUtils.h"
+#endif /* INCLUDED_NETWORKINGUTILITIES_H */
+
+#ifndef INCLUDED_IPENDPOINTNAME_H
+#include "IpEndpointName.h"
+#endif /* INCLUDED_IPENDPOINTNAME_H */
+
+
+class PacketListener;
+class TimerListener;
+
+class UdpSocket;
+
+class SocketReceiveMultiplexer{
+    class Implementation;
+    Implementation *impl_;
+
+	friend class UdpSocket;
+
+public:
+    SocketReceiveMultiplexer();
+    ~SocketReceiveMultiplexer();
+
+	// only call the attach/detach methods _before_ calling Run
+
+    // only one listener per socket, each socket at most once
+    void AttachSocketListener( UdpSocket *socket, PacketListener *listener );
+    void DetachSocketListener( UdpSocket *socket, PacketListener *listener );
+
+    void AttachPeriodicTimerListener( int periodMilliseconds, TimerListener *listener );
+	void AttachPeriodicTimerListener(
+            int initialDelayMilliseconds, int periodMilliseconds, TimerListener *listener );
+    void DetachPeriodicTimerListener( TimerListener *listener );  
+
+    void Run();      // loop and block processing messages indefinitely
+	void RunUntilSigInt();
+    void Break();    // call this from a listener to exit once the listener returns
+    void AsynchronousBreak(); // call this from another thread or signal handler to exit the Run() state
+};
+
+
+class UdpSocket{
+    class Implementation;
+    Implementation *impl_;
+    
+	friend class SocketReceiveMultiplexer::Implementation;
+    
+public:
+
+	// ctor throws std::runtime_error if there's a problem
+	// initializing the socket.
+	UdpSocket();
+	virtual ~UdpSocket();
+
+	// the socket is created in an unbound, unconnected state
+	// such a socket can only be used to send to an arbitrary
+	// address using SendTo(). To use Send() you need to first
+	// connect to a remote endpoint using Connect(). To use
+	// ReceiveFrom you need to first bind to a local endpoint
+	// using Bind().
+
+	// retrieve the local endpoint name when sending to 'to'
+    IpEndpointName LocalEndpointFor( const IpEndpointName& remoteEndpoint ) const;
+
+	// Connect to a remote endpoint which is used as the target
+	// for calls to Send()
+	void Connect( const IpEndpointName& remoteEndpoint );	
+	void Send( const char *data, int size );
+    void SendTo( const IpEndpointName& remoteEndpoint, const char *data, int size );
+
+
+	// Bind a local endpoint to receive incoming data. Endpoint
+	// can be 'any' for the system to choose an endpoint
+	void Bind( const IpEndpointName& localEndpoint );
+	bool IsBound() const;
+
+	int ReceiveFrom( IpEndpointName& remoteEndpoint, char *data, int size );
+};
+
+
+// convenience classes for transmitting and receiving
+// they just call Connect and/or Bind in the ctor.
+// note that you can still use a receive socket
+// for transmitting etc
+
+class UdpTransmitSocket : public UdpSocket{
+public:
+	UdpTransmitSocket( const IpEndpointName& remoteEndpoint )
+		{ Connect( remoteEndpoint ); }
+};
+
+
+class UdpReceiveSocket : public UdpSocket{
+public:
+	UdpReceiveSocket( const IpEndpointName& localEndpoint )
+		{ Bind( localEndpoint ); }
+};
+
+
+// UdpListeningReceiveSocket provides a simple way to bind one listener
+// to a single socket without having to manually set up a SocketReceiveMultiplexer
+
+class UdpListeningReceiveSocket : public UdpSocket{
+    SocketReceiveMultiplexer mux_;
+    PacketListener *listener_;
+public:
+	UdpListeningReceiveSocket( const IpEndpointName& localEndpoint, PacketListener *listener )
+        : listener_( listener )
+    {
+        Bind( localEndpoint );
+        mux_.AttachSocketListener( this, listener_ );
+    }
+
+    ~UdpListeningReceiveSocket()
+        { mux_.DetachSocketListener( this, listener_ ); }
+
+    // see SocketReceiveMultiplexer above for the behaviour of these methods...
+    void Run() { mux_.Run(); }
+	void RunUntilSigInt() { mux_.RunUntilSigInt(); }
+    void Break() { mux_.Break(); }
+    void AsynchronousBreak() { mux_.AsynchronousBreak(); }
+};
+
+
+#endif /* INCLUDED_UDPSOCKET_H */
diff --git a/src/osc/ip/posix/NetworkingUtils.cpp b/src/osc/ip/posix/NetworkingUtils.cpp
new file mode 100755
index 0000000..d3e595c
--- /dev/null
+++ b/src/osc/ip/posix/NetworkingUtils.cpp
@@ -0,0 +1,57 @@
+/*
+	oscpack -- Open Sound Control packet manipulation library
+	http://www.audiomulch.com/~rossb/oscpack
+
+	Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>
+
+	Permission is hereby granted, free of charge, to any person obtaining
+	a copy of this software and associated documentation files
+	(the "Software"), to deal in the Software without restriction,
+	including without limitation the rights to use, copy, modify, merge,
+	publish, distribute, sublicense, and/or sell copies of the Software,
+	and to permit persons to whom the Software is furnished to do so,
+	subject to the following conditions:
+
+	The above copyright notice and this permission notice shall be
+	included in all copies or substantial portions of the Software.
+
+	Any person wishing to distribute modifications to the Software is
+	requested to send the modifications to the original developer so that
+	they can be incorporated into the canonical version.
+
+	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+	EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+	MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+	IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+	ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+	CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+	WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+#include "../NetworkingUtils.h"
+
+#include <netdb.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <string.h>
+#include <stdio.h>
+
+
+
+NetworkInitializer::NetworkInitializer() {}
+
+NetworkInitializer::~NetworkInitializer() {}
+
+
+unsigned long GetHostByName( const char *name )
+{
+    unsigned long result = 0;
+
+    struct hostent *h = gethostbyname( name );
+    if( h ){
+        struct in_addr a;
+        memcpy( &a, h->h_addr_list[0], h->h_length );
+        result = ntohl(a.s_addr);
+    }
+
+    return result;
+}
diff --git a/src/osc/ip/posix/UdpSocket.cpp b/src/osc/ip/posix/UdpSocket.cpp
new file mode 100755
index 0000000..01565ca
--- /dev/null
+++ b/src/osc/ip/posix/UdpSocket.cpp
@@ -0,0 +1,546 @@
+/*
+	oscpack -- Open Sound Control packet manipulation library
+	http://www.audiomulch.com/~rossb/oscpack
+
+	Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>
+
+	Permission is hereby granted, free of charge, to any person obtaining
+	a copy of this software and associated documentation files
+	(the "Software"), to deal in the Software without restriction,
+	including without limitation the rights to use, copy, modify, merge,
+	publish, distribute, sublicense, and/or sell copies of the Software,
+	and to permit persons to whom the Software is furnished to do so,
+	subject to the following conditions:
+
+	The above copyright notice and this permission notice shall be
+	included in all copies or substantial portions of the Software.
+
+	Any person wishing to distribute modifications to the Software is
+	requested to send the modifications to the original developer so that
+	they can be incorporated into the canonical version.
+
+	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+	EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+	MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+	IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+	ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+	CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+	WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+#include "..//UdpSocket.h"
+
+#include <vector>
+#include <algorithm>
+#include <stdexcept>
+#include <assert.h>
+#include <signal.h>
+#include <math.h>
+#include <errno.h>
+#include <string.h> // for memset
+
+#include <pthread.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <netdb.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <netinet/in.h> // for sockaddr_in
+
+#include "../PacketListener.h"
+#include "../TimerListener.h"
+
+
+#if defined(__APPLE__) && !defined(_SOCKLEN_T)
+// pre system 10.3 didn have socklen_t
+typedef ssize_t socklen_t;
+#endif
+
+
+static void SockaddrFromIpEndpointName( struct sockaddr_in& sockAddr, const IpEndpointName& endpoint )
+{
+    memset( (char *)&sockAddr, 0, sizeof(sockAddr ) );
+    sockAddr.sin_family = AF_INET;
+
+	sockAddr.sin_addr.s_addr = 
+		(endpoint.address == IpEndpointName::ANY_ADDRESS)
+		? INADDR_ANY
+		: htonl( endpoint.address );
+
+	sockAddr.sin_port =
+		(endpoint.port == IpEndpointName::ANY_PORT)
+		? 0
+		: htons( endpoint.port );
+}
+
+
+static IpEndpointName IpEndpointNameFromSockaddr( const struct sockaddr_in& sockAddr )
+{
+	return IpEndpointName( 
+		(sockAddr.sin_addr.s_addr == INADDR_ANY) 
+			? IpEndpointName::ANY_ADDRESS 
+			: ntohl( sockAddr.sin_addr.s_addr ),
+		(sockAddr.sin_port == 0)
+			? IpEndpointName::ANY_PORT
+			: ntohs( sockAddr.sin_port )
+		);
+}
+
+
+class UdpSocket::Implementation{
+	bool isBound_;
+	bool isConnected_;
+
+	int socket_;
+	struct sockaddr_in connectedAddr_;
+	struct sockaddr_in sendToAddr_;
+
+public:
+
+	Implementation()
+		: isBound_( false )
+		, isConnected_( false )
+		, socket_( -1 )
+	{
+		if( (socket_ = socket( AF_INET, SOCK_DGRAM, 0 )) == -1 ){
+            throw std::runtime_error("unable to create udp socket\n");
+        }
+
+		memset( &sendToAddr_, 0, sizeof(sendToAddr_) );
+        sendToAddr_.sin_family = AF_INET;
+	}
+
+	~Implementation()
+	{
+		if (socket_ != -1) close(socket_);
+	}
+
+	IpEndpointName LocalEndpointFor( const IpEndpointName& remoteEndpoint ) const
+	{
+		assert( isBound_ );
+
+		// first connect the socket to the remote server
+        
+        struct sockaddr_in connectSockAddr;
+		SockaddrFromIpEndpointName( connectSockAddr, remoteEndpoint );
+       
+        if (connect(socket_, (struct sockaddr *)&connectSockAddr, sizeof(connectSockAddr)) < 0) {
+            throw std::runtime_error("unable to connect udp socket\n");
+        }
+
+        // get the address
+
+        struct sockaddr_in sockAddr;
+        memset( (char *)&sockAddr, 0, sizeof(sockAddr ) );
+        socklen_t length = sizeof(sockAddr);
+        if (getsockname(socket_, (struct sockaddr *)&sockAddr, &length) < 0) {
+            throw std::runtime_error("unable to getsockname\n");
+        }
+        
+		if( isConnected_ ){
+			// reconnect to the connected address
+			
+			if (connect(socket_, (struct sockaddr *)&connectedAddr_, sizeof(connectedAddr_)) < 0) {
+				throw std::runtime_error("unable to connect udp socket\n");
+			}
+
+		}else{
+			// unconnect from the remote address
+		
+			struct sockaddr_in unconnectSockAddr;
+			memset( (char *)&unconnectSockAddr, 0, sizeof(unconnectSockAddr ) );
+			unconnectSockAddr.sin_family = AF_UNSPEC;
+			// address fields are zero
+			int connectResult = connect(socket_, (struct sockaddr *)&unconnectSockAddr, sizeof(unconnectSockAddr));
+			if ( connectResult < 0 && errno != EAFNOSUPPORT ) {
+				throw std::runtime_error("unable to un-connect udp socket\n");
+			}
+		}
+
+		return IpEndpointNameFromSockaddr( sockAddr );
+	}
+
+	void Connect( const IpEndpointName& remoteEndpoint )
+	{
+		SockaddrFromIpEndpointName( connectedAddr_, remoteEndpoint );
+       
+        if (connect(socket_, (struct sockaddr *)&connectedAddr_, sizeof(connectedAddr_)) < 0) {
+            throw std::runtime_error("unable to connect udp socket\n");
+        }
+
+		isConnected_ = true;
+	}
+
+	void Send( const char *data, int size )
+	{
+		assert( isConnected_ );
+
+        send( socket_, data, size, 0 );
+	}
+
+    void SendTo( const IpEndpointName& remoteEndpoint, const char *data, int size )
+	{
+		sendToAddr_.sin_addr.s_addr = htonl( remoteEndpoint.address );
+        sendToAddr_.sin_port = htons( remoteEndpoint.port );
+
+        sendto( socket_, data, size, 0, (sockaddr*)&sendToAddr_, sizeof(sendToAddr_) );
+	}
+
+	void Bind( const IpEndpointName& localEndpoint )
+	{
+		struct sockaddr_in bindSockAddr;
+		SockaddrFromIpEndpointName( bindSockAddr, localEndpoint );
+
+        if (bind(socket_, (struct sockaddr *)&bindSockAddr, sizeof(bindSockAddr)) < 0) {
+            throw std::runtime_error("unable to bind udp socket\n");
+        }
+
+		isBound_ = true;
+	}
+
+	bool IsBound() const { return isBound_; }
+
+    int ReceiveFrom( IpEndpointName& remoteEndpoint, char *data, int size )
+	{
+		assert( isBound_ );
+
+		struct sockaddr_in fromAddr;
+        socklen_t fromAddrLen = sizeof(fromAddr);
+             	 
+        int result = recvfrom(socket_, data, size, 0,
+                    (struct sockaddr *) &fromAddr, (socklen_t*)&fromAddrLen);
+		if( result < 0 )
+			return 0;
+
+		remoteEndpoint.address = ntohl(fromAddr.sin_addr.s_addr);
+		remoteEndpoint.port = ntohs(fromAddr.sin_port);
+
+		return result;
+	}
+
+	int Socket() { return socket_; }
+};
+
+UdpSocket::UdpSocket()
+{
+	impl_ = new Implementation();
+}
+
+UdpSocket::~UdpSocket()
+{
+	delete impl_;
+}
+
+IpEndpointName UdpSocket::LocalEndpointFor( const IpEndpointName& remoteEndpoint ) const
+{
+	return impl_->LocalEndpointFor( remoteEndpoint );
+}
+
+void UdpSocket::Connect( const IpEndpointName& remoteEndpoint )
+{
+	impl_->Connect( remoteEndpoint );
+}
+
+void UdpSocket::Send( const char *data, int size )
+{
+	impl_->Send( data, size );
+}
+
+void UdpSocket::SendTo( const IpEndpointName& remoteEndpoint, const char *data, int size )
+{
+	impl_->SendTo( remoteEndpoint, data, size );
+}
+
+void UdpSocket::Bind( const IpEndpointName& localEndpoint )
+{
+	impl_->Bind( localEndpoint );
+}
+
+bool UdpSocket::IsBound() const
+{
+	return impl_->IsBound();
+}
+
+int UdpSocket::ReceiveFrom( IpEndpointName& remoteEndpoint, char *data, int size )
+{
+	return impl_->ReceiveFrom( remoteEndpoint, data, size );
+}
+
+
+struct AttachedTimerListener{
+	AttachedTimerListener( int id, int p, TimerListener *tl )
+		: initialDelayMs( id )
+		, periodMs( p )
+		, listener( tl ) {}
+	int initialDelayMs;
+	int periodMs;
+	TimerListener *listener;
+};
+
+
+static bool CompareScheduledTimerCalls( 
+		const std::pair< double, AttachedTimerListener > & lhs, const std::pair< double, AttachedTimerListener > & rhs )
+{
+	return lhs.first < rhs.first;
+}
+
+
+SocketReceiveMultiplexer *multiplexerInstanceToAbortWithSigInt_ = 0;
+
+extern "C" /*static*/ void InterruptSignalHandler( int );
+/*static*/ void InterruptSignalHandler( int )
+{
+	multiplexerInstanceToAbortWithSigInt_->AsynchronousBreak();
+	signal( SIGINT, SIG_DFL );
+}
+
+
+class SocketReceiveMultiplexer::Implementation{
+	std::vector< std::pair< PacketListener*, UdpSocket* > > socketListeners_;
+	std::vector< AttachedTimerListener > timerListeners_;
+
+	volatile bool break_;
+	int breakPipe_[2]; // [0] is the reader descriptor and [1] the writer
+
+	double GetCurrentTimeMs() const
+	{
+		struct timeval t;
+
+		gettimeofday( &t, 0 );
+
+		return ((double)t.tv_sec*1000.) + ((double)t.tv_usec / 1000.);
+	}
+
+public:
+    Implementation()
+	{
+		if( pipe(breakPipe_) != 0 )
+			throw std::runtime_error( "creation of asynchronous break pipes failed\n" );
+	}
+
+    ~Implementation()
+	{
+		close( breakPipe_[0] );
+		close( breakPipe_[1] );
+	}
+
+    void AttachSocketListener( UdpSocket *socket, PacketListener *listener )
+	{
+		assert( std::find( socketListeners_.begin(), socketListeners_.end(), std::make_pair(listener, socket) ) == socketListeners_.end() );
+		// we don't check that the same socket has been added multiple times, even though this is an error
+		socketListeners_.push_back( std::make_pair( listener, socket ) );
+	}
+
+    void DetachSocketListener( UdpSocket *socket, PacketListener *listener )
+	{
+		std::vector< std::pair< PacketListener*, UdpSocket* > >::iterator i = 
+				std::find( socketListeners_.begin(), socketListeners_.end(), std::make_pair(listener, socket) );
+		assert( i != socketListeners_.end() );
+
+		socketListeners_.erase( i );
+	}
+
+    void AttachPeriodicTimerListener( int periodMilliseconds, TimerListener *listener )
+	{
+		timerListeners_.push_back( AttachedTimerListener( periodMilliseconds, periodMilliseconds, listener ) );
+	}
+
+	void AttachPeriodicTimerListener( int initialDelayMilliseconds, int periodMilliseconds, TimerListener *listener )
+	{
+		timerListeners_.push_back( AttachedTimerListener( initialDelayMilliseconds, periodMilliseconds, listener ) );
+	}
+
+    void DetachPeriodicTimerListener( TimerListener *listener )
+	{
+		std::vector< AttachedTimerListener >::iterator i = timerListeners_.begin();
+		while( i != timerListeners_.end() ){
+			if( i->listener == listener )
+				break;
+			++i;
+		}
+
+		assert( i != timerListeners_.end() );
+
+		timerListeners_.erase( i );
+	}
+
+    void Run()
+	{
+		break_ = false;
+
+		// configure the master fd_set for select()
+
+		fd_set masterfds, tempfds;
+		FD_ZERO( &masterfds );
+		FD_ZERO( &tempfds );
+		
+		// in addition to listening to the inbound sockets we
+		// also listen to the asynchronous break pipe, so that AsynchronousBreak()
+		// can break us out of select() from another thread.
+		FD_SET( breakPipe_[0], &masterfds );
+		int fdmax = breakPipe_[0];		
+
+		for( std::vector< std::pair< PacketListener*, UdpSocket* > >::iterator i = socketListeners_.begin();
+				i != socketListeners_.end(); ++i ){
+
+			if( fdmax < i->second->impl_->Socket() )
+				fdmax = i->second->impl_->Socket();
+			FD_SET( i->second->impl_->Socket(), &masterfds );
+		}
+
+
+		// configure the timer queue
+		double currentTimeMs = GetCurrentTimeMs();
+
+		// expiry time ms, listener
+		std::vector< std::pair< double, AttachedTimerListener > > timerQueue_;
+		for( std::vector< AttachedTimerListener >::iterator i = timerListeners_.begin();
+				i != timerListeners_.end(); ++i )
+			timerQueue_.push_back( std::make_pair( currentTimeMs + i->initialDelayMs, *i ) );
+		std::sort( timerQueue_.begin(), timerQueue_.end(), CompareScheduledTimerCalls );
+
+		const int MAX_BUFFER_SIZE = 4098;
+		char *data = new char[ MAX_BUFFER_SIZE ];
+		IpEndpointName remoteEndpoint;
+
+		struct timeval timeout;
+
+		while( !break_ ){
+			tempfds = masterfds;
+
+			struct timeval *timeoutPtr = 0;
+			if( !timerQueue_.empty() ){
+				double timeoutMs = timerQueue_.front().first - GetCurrentTimeMs();
+				if( timeoutMs < 0 )
+					timeoutMs = 0;
+			
+				// 1000000 microseconds in a second
+				timeout.tv_sec = (long)(timeoutMs * .001);
+				timeout.tv_usec = (long)((timeoutMs - (timeout.tv_sec * 1000)) * 1000);
+				timeoutPtr = &timeout;
+			}
+
+			if( select( fdmax + 1, &tempfds, 0, 0, timeoutPtr ) < 0 && errno != EINTR ){
+   				throw std::runtime_error("select failed\n");
+			}
+
+			if ( FD_ISSET( breakPipe_[0], &tempfds ) ){
+				// clear pending data from the asynchronous break pipe
+				char c;
+				read( breakPipe_[0], &c, 1 );
+			}
+			
+			if( break_ )
+				break;
+
+			for( std::vector< std::pair< PacketListener*, UdpSocket* > >::iterator i = socketListeners_.begin();
+					i != socketListeners_.end(); ++i ){
+
+				if( FD_ISSET( i->second->impl_->Socket(), &tempfds ) ){
+
+					int size = i->second->ReceiveFrom( remoteEndpoint, data, MAX_BUFFER_SIZE );
+					if( size > 0 ){
+						i->first->ProcessPacket( data, size, remoteEndpoint );
+						if( break_ )
+							break;
+					}
+				}
+			}
+
+			// execute any expired timers
+			currentTimeMs = GetCurrentTimeMs();
+			bool resort = false;
+			for( std::vector< std::pair< double, AttachedTimerListener > >::iterator i = timerQueue_.begin();
+					i != timerQueue_.end() && i->first <= currentTimeMs; ++i ){
+
+				i->second.listener->TimerExpired();
+				if( break_ )
+					break;
+
+				i->first += i->second.periodMs;
+				resort = true;
+			}
+			if( resort )
+				std::sort( timerQueue_.begin(), timerQueue_.end(), CompareScheduledTimerCalls );
+		}
+
+		delete [] data;
+	}
+
+    void Break()
+	{
+		break_ = true;
+	}
+
+    void AsynchronousBreak()
+	{
+		break_ = true;
+
+		// Send a termination message to the asynchronous break pipe, so select() will return
+		write( breakPipe_[1], "!", 1 );
+	}
+};
+
+
+
+SocketReceiveMultiplexer::SocketReceiveMultiplexer()
+{
+	impl_ = new Implementation();
+}
+
+SocketReceiveMultiplexer::~SocketReceiveMultiplexer()
+{	
+	delete impl_;
+}
+
+void SocketReceiveMultiplexer::AttachSocketListener( UdpSocket *socket, PacketListener *listener )
+{
+	impl_->AttachSocketListener( socket, listener );
+}
+
+void SocketReceiveMultiplexer::DetachSocketListener( UdpSocket *socket, PacketListener *listener )
+{
+	impl_->DetachSocketListener( socket, listener );
+}
+
+void SocketReceiveMultiplexer::AttachPeriodicTimerListener( int periodMilliseconds, TimerListener *listener )
+{
+	impl_->AttachPeriodicTimerListener( periodMilliseconds, listener );
+}
+
+void SocketReceiveMultiplexer::AttachPeriodicTimerListener( int initialDelayMilliseconds, int periodMilliseconds, TimerListener *listener )
+{
+	impl_->AttachPeriodicTimerListener( initialDelayMilliseconds, periodMilliseconds, listener );
+}
+
+void SocketReceiveMultiplexer::DetachPeriodicTimerListener( TimerListener *listener )
+{
+	impl_->DetachPeriodicTimerListener( listener );
+}
+
+void SocketReceiveMultiplexer::Run()
+{
+	impl_->Run();
+}
+
+void SocketReceiveMultiplexer::RunUntilSigInt()
+{
+	assert( multiplexerInstanceToAbortWithSigInt_ == 0 ); /* at present we support only one multiplexer instance running until sig int */
+	multiplexerInstanceToAbortWithSigInt_ = this;
+	signal( SIGINT, InterruptSignalHandler );
+	impl_->Run();
+	signal( SIGINT, SIG_DFL );
+	multiplexerInstanceToAbortWithSigInt_ = 0;
+}
+
+void SocketReceiveMultiplexer::Break()
+{
+	impl_->Break();
+}
+
+void SocketReceiveMultiplexer::AsynchronousBreak()
+{
+	impl_->AsynchronousBreak();
+}
+
diff --git a/src/osc/osc/MessageMappingOscPacketListener.h b/src/osc/osc/MessageMappingOscPacketListener.h
new file mode 100755
index 0000000..017bf05
--- /dev/null
+++ b/src/osc/osc/MessageMappingOscPacketListener.h
@@ -0,0 +1,73 @@
+/*
+	oscpack -- Open Sound Control packet manipulation library
+	http://www.audiomulch.com/~rossb/oscpack
+
+	Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>
+
+	Permission is hereby granted, free of charge, to any person obtaining
+	a copy of this software and associated documentation files
+	(the "Software"), to deal in the Software without restriction,
+	including without limitation the rights to use, copy, modify, merge,
+	publish, distribute, sublicense, and/or sell copies of the Software,
+	and to permit persons to whom the Software is furnished to do so,
+	subject to the following conditions:
+
+	The above copyright notice and this permission notice shall be
+	included in all copies or substantial portions of the Software.
+
+	Any person wishing to distribute modifications to the Software is
+	requested to send the modifications to the original developer so that
+	they can be incorporated into the canonical version.
+
+	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+	EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+	MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+	IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+	ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+	CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+	WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+#ifndef INCLUDED_MESSAGEMAPPINGOSCPACKETLISTENER_H
+#define INCLUDED_MESSAGEMAPPINGOSCPACKETLISTENER_H
+
+#include <string.h>
+#include <map>
+
+#include "OscPacketListener.h"
+
+
+
+namespace osc{
+
+template< class T >
+class MessageMappingOscPacketListener : public OscPacketListener{
+public:
+    typedef void (T::*function_type)(const osc::ReceivedMessage&, const IpEndpointName&);
+
+protected:
+    void RegisterMessageFunction( const char *addressPattern, function_type f )
+    {
+        functions_.insert( std::make_pair( addressPattern, f ) );
+    }
+
+    virtual void ProcessMessage( const osc::ReceivedMessage& m,
+		const IpEndpointName& remoteEndpoint )
+    {
+        typename function_map_type::iterator i = functions_.find( m.AddressPattern() );
+        if( i != functions_.end() )
+            (dynamic_cast<T*>(this)->*(i->second))( m, remoteEndpoint );
+    }
+    
+private:
+    struct cstr_compare{
+        bool operator()( const char *lhs, const char *rhs ) const
+            { return strcmp( lhs, rhs ) < 0; }
+    };
+
+    typedef std::map<const char*, function_type, cstr_compare> function_map_type;
+    function_map_type functions_;
+};
+
+} // namespace osc
+
+#endif /* INCLUDED_MESSAGEMAPPINGOSCPACKETLISTENER_H */
\ No newline at end of file
diff --git a/src/osc/osc/OscException.h b/src/osc/osc/OscException.h
new file mode 100755
index 0000000..cd8d567
--- /dev/null
+++ b/src/osc/osc/OscException.h
@@ -0,0 +1,54 @@
+/*
+	oscpack -- Open Sound Control packet manipulation library
+	http://www.audiomulch.com/~rossb/oscpack
+
+	Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>
+
+	Permission is hereby granted, free of charge, to any person obtaining
+	a copy of this software and associated documentation files
+	(the "Software"), to deal in the Software without restriction,
+	including without limitation the rights to use, copy, modify, merge,
+	publish, distribute, sublicense, and/or sell copies of the Software,
+	and to permit persons to whom the Software is furnished to do so,
+	subject to the following conditions:
+
+	The above copyright notice and this permission notice shall be
+	included in all copies or substantial portions of the Software.
+
+	Any person wishing to distribute modifications to the Software is
+	requested to send the modifications to the original developer so that
+	they can be incorporated into the canonical version.
+
+	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+	EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+	MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+	IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+	ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+	CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+	WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+#ifndef INCLUDED_OSC_EXCEPTION_H
+#define INCLUDED_OSC_EXCEPTION_H
+
+#include <exception>
+
+namespace osc{
+
+class Exception : public std::exception {
+    const char *what_;
+    
+public:
+    Exception() throw() {}
+    Exception( const Exception& src ) throw()
+        : what_( src.what_ ) {}
+    Exception( const char *w ) throw()
+        : what_( w ) {}
+    Exception& operator=( const Exception& src ) throw()
+        { what_ = src.what_; return *this; }
+    virtual ~Exception() throw() {}
+    virtual const char* what() const throw() { return what_; }
+};
+
+} // namespace osc
+
+#endif /* INCLUDED_OSC_EXCEPTION_H */
diff --git a/src/osc/osc/OscHostEndianness.h b/src/osc/osc/OscHostEndianness.h
new file mode 100755
index 0000000..b542ef5
--- /dev/null
+++ b/src/osc/osc/OscHostEndianness.h
@@ -0,0 +1,70 @@
+/*
+	oscpack -- Open Sound Control packet manipulation library
+	http://www.audiomulch.com/~rossb/oscpack
+
+	Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>
+
+	Permission is hereby granted, free of charge, to any person obtaining
+	a copy of this software and associated documentation files
+	(the "Software"), to deal in the Software without restriction,
+	including without limitation the rights to use, copy, modify, merge,
+	publish, distribute, sublicense, and/or sell copies of the Software,
+	and to permit persons to whom the Software is furnished to do so,
+	subject to the following conditions:
+
+	The above copyright notice and this permission notice shall be
+	included in all copies or substantial portions of the Software.
+
+	Any person wishing to distribute modifications to the Software is
+	requested to send the modifications to the original developer so that
+	they can be incorporated into the canonical version.
+
+	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+	EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+	MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+	IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+	ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+	CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+	WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+#ifndef OSC_HOSTENDIANNESS_H
+#define OSC_HOSTENDIANNESS_H
+
+/*
+    Make sure either OSC_HOST_LITTLE_ENDIAN or OSC_HOST_BIG_ENDIAN is defined
+
+    If you know a way to enhance the detection below for Linux and/or MacOSX
+    please let me know! I've tried a few things which don't work.
+*/
+#define OSC_HOST_LITTLE_ENDIAN 1
+
+#if defined(OSC_HOST_LITTLE_ENDIAN) || defined(OSC_HOST_BIG_ENDIAN)
+
+// you can define one of the above symbols from the command line
+// then you don't have to edit this file.
+
+#elif defined(__WIN32__) || defined(WIN32)
+
+// assume that __WIN32__ is only defined on little endian systems
+
+#define OSC_HOST_LITTLE_ENDIAN 1
+#undef OSC_HOST_BIG_ENDIAN
+
+#elif defined(__APPLE__)
+
+#if defined(__LITTLE_ENDIAN__)
+#define OSC_HOST_LITTLE_ENDIAN 1
+#undef OSC_HOST_BIG_ENDIAN
+#else
+#define OSC_HOST_BIG_ENDIAN 1
+#undef OSC_HOST_LITTLE_ENDIAN
+#endif
+
+#else
+
+#error please edit OSCHostEndianness.h to configure endianness
+
+#endif
+
+#endif /* OSC_HOSTENDIANNESS_H */
+
diff --git a/src/osc/osc/OscOutboundPacketStream.cpp b/src/osc/osc/OscOutboundPacketStream.cpp
new file mode 100755
index 0000000..75b1800
--- /dev/null
+++ b/src/osc/osc/OscOutboundPacketStream.cpp
@@ -0,0 +1,639 @@
+/*
+	oscpack -- Open Sound Control packet manipulation library
+	http://www.audiomulch.com/~rossb/oscpack
+
+	Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>
+
+	Permission is hereby granted, free of charge, to any person obtaining
+	a copy of this software and associated documentation files
+	(the "Software"), to deal in the Software without restriction,
+	including without limitation the rights to use, copy, modify, merge,
+	publish, distribute, sublicense, and/or sell copies of the Software,
+	and to permit persons to whom the Software is furnished to do so,
+	subject to the following conditions:
+
+	The above copyright notice and this permission notice shall be
+	included in all copies or substantial portions of the Software.
+
+	Any person wishing to distribute modifications to the Software is
+	requested to send the modifications to the original developer so that
+	they can be incorporated into the canonical version.
+
+	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+	EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+	MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+	IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+	ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+	CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+	WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+#include "OscOutboundPacketStream.h"
+
+#include <string.h>
+#include <stdlib.h>
+#include <assert.h>
+
+#if defined(__WIN32__) || defined(WIN32)
+#include <malloc.h> // for alloca
+#endif
+
+#include "OscHostEndianness.h"
+
+
+namespace osc{
+
+static void FromInt32( char *p, int32 x )
+{
+#ifdef OSC_HOST_LITTLE_ENDIAN
+    union{
+        osc::int32 i;
+        char c[4];
+    } u;
+
+    u.i = x;
+
+    p[3] = u.c[0];
+    p[2] = u.c[1];
+    p[1] = u.c[2];
+    p[0] = u.c[3];
+#else
+    *reinterpret_cast<int32*>(p) = x;
+#endif
+}
+
+
+static void FromUInt32( char *p, uint32 x )
+{
+#ifdef OSC_HOST_LITTLE_ENDIAN
+    union{
+        osc::uint32 i;
+        char c[4];
+    } u;
+
+    u.i = x;
+
+    p[3] = u.c[0];
+    p[2] = u.c[1];
+    p[1] = u.c[2];
+    p[0] = u.c[3];
+#else
+    *reinterpret_cast<uint32*>(p) = x;
+#endif
+}
+
+
+static void FromInt64( char *p, int64 x )
+{
+#ifdef OSC_HOST_LITTLE_ENDIAN
+    union{
+        osc::int64 i;
+        char c[8];
+    } u;
+
+    u.i = x;
+
+    p[7] = u.c[0];
+    p[6] = u.c[1];
+    p[5] = u.c[2];
+    p[4] = u.c[3];
+    p[3] = u.c[4];
+    p[2] = u.c[5];
+    p[1] = u.c[6];
+    p[0] = u.c[7];
+#else
+    *reinterpret_cast<int64*>(p) = x;
+#endif
+}
+
+
+static void FromUInt64( char *p, uint64 x )
+{
+#ifdef OSC_HOST_LITTLE_ENDIAN
+    union{
+        osc::uint64 i;
+        char c[8];
+    } u;
+
+    u.i = x;
+
+    p[7] = u.c[0];
+    p[6] = u.c[1];
+    p[5] = u.c[2];
+    p[4] = u.c[3];
+    p[3] = u.c[4];
+    p[2] = u.c[5];
+    p[1] = u.c[6];
+    p[0] = u.c[7];
+#else
+    *reinterpret_cast<uint64*>(p) = x;
+#endif
+}
+
+
+static inline long RoundUp4( long x )
+{
+    return ((x-1) & (~0x03L)) + 4;
+}
+
+
+OutboundPacketStream::OutboundPacketStream( char *buffer, unsigned long capacity )
+    : data_( buffer )
+    , end_( data_ + capacity )
+    , typeTagsCurrent_( end_ )
+    , messageCursor_( data_ )
+    , argumentCurrent_( data_ )
+    , elementSizePtr_( 0 )
+    , messageIsInProgress_( false )
+{
+
+}
+
+
+OutboundPacketStream::~OutboundPacketStream()
+{
+
+}
+
+
+char *OutboundPacketStream::BeginElement( char *beginPtr )
+{
+    if( elementSizePtr_ == 0 ){
+
+        elementSizePtr_ = reinterpret_cast<uint32*>(data_);
+
+        return beginPtr;
+
+    }else{
+        // store an offset to the old element size ptr in the element size slot
+        // we store an offset rather than the actual pointer to be 64 bit clean.
+        *reinterpret_cast<uint32*>(beginPtr) =
+                (uint32)(reinterpret_cast<char*>(elementSizePtr_) - data_);
+
+        elementSizePtr_ = reinterpret_cast<uint32*>(beginPtr);
+
+        return beginPtr + 4;
+    }
+}
+
+
+void OutboundPacketStream::EndElement( char *endPtr )
+{
+    assert( elementSizePtr_ != 0 );
+
+    if( elementSizePtr_ == reinterpret_cast<uint32*>(data_) ){
+
+        elementSizePtr_ = 0;
+
+    }else{
+        // while building an element, an offset to the containing element's
+        // size slot is stored in the elements size slot (or a ptr to data_
+        // if there is no containing element). We retrieve that here
+        uint32 *previousElementSizePtr =
+                (uint32*)(data_ + *reinterpret_cast<uint32*>(elementSizePtr_));
+
+        // then we store the element size in the slot, note that the element
+        // size does not include the size slot, hence the - 4 below.
+        uint32 elementSize =
+                (endPtr - reinterpret_cast<char*>(elementSizePtr_)) - 4;
+        FromUInt32( reinterpret_cast<char*>(elementSizePtr_), elementSize );
+
+        // finally, we reset the element size ptr to the containing element
+        elementSizePtr_ = previousElementSizePtr;
+    }
+}
+
+
+bool OutboundPacketStream::ElementSizeSlotRequired() const
+{
+    return (elementSizePtr_ != 0);
+}
+
+
+void OutboundPacketStream::CheckForAvailableBundleSpace()
+{
+    unsigned long required = Size() + ((ElementSizeSlotRequired())?4:0) + 16;
+
+    if( required > Capacity() )
+        throw OutOfBufferMemoryException();
+}
+
+
+void OutboundPacketStream::CheckForAvailableMessageSpace( const char *addressPattern )
+{
+    // plus 4 for at least four bytes of type tag
+     unsigned long required = Size() + ((ElementSizeSlotRequired())?4:0)
+            + RoundUp4(strlen(addressPattern) + 1) + 4;
+
+    if( required > Capacity() )
+        throw OutOfBufferMemoryException();
+}
+
+
+void OutboundPacketStream::CheckForAvailableArgumentSpace( long argumentLength )
+{
+    // plus three for extra type tag, comma and null terminator
+     unsigned long required = (argumentCurrent_ - data_) + argumentLength
+            + RoundUp4( (end_ - typeTagsCurrent_) + 3 );
+
+    if( required > Capacity() )
+        throw OutOfBufferMemoryException();
+}
+
+
+void OutboundPacketStream::Clear()
+{
+    typeTagsCurrent_ = end_;
+    messageCursor_ = data_;
+    argumentCurrent_ = data_;
+    elementSizePtr_ = 0;
+    messageIsInProgress_ = false;
+}
+
+
+unsigned int OutboundPacketStream::Capacity() const
+{
+    return end_ - data_;
+}
+
+
+unsigned int OutboundPacketStream::Size() const
+{
+    unsigned int result = argumentCurrent_ - data_;
+    if( IsMessageInProgress() ){
+        // account for the length of the type tag string. the total type tag
+        // includes an initial comma, plus at least one terminating \0
+        result += RoundUp4( (end_ - typeTagsCurrent_) + 2 );
+    }
+
+    return result;
+}
+
+
+const char *OutboundPacketStream::Data() const
+{
+    return data_;
+}
+
+
+bool OutboundPacketStream::IsReady() const
+{
+    return (!IsMessageInProgress() && !IsBundleInProgress());
+}
+
+
+bool OutboundPacketStream::IsMessageInProgress() const
+{
+    return messageIsInProgress_;
+}
+
+
+bool OutboundPacketStream::IsBundleInProgress() const
+{
+    return (elementSizePtr_ != 0);
+}
+
+
+OutboundPacketStream& OutboundPacketStream::operator<<( const BundleInitiator& rhs )
+{
+    if( IsMessageInProgress() )
+        throw MessageInProgressException();
+
+    CheckForAvailableBundleSpace();
+
+    messageCursor_ = BeginElement( messageCursor_ );
+
+    memcpy( messageCursor_, "#bundle\0", 8 );
+    FromUInt64( messageCursor_ + 8, rhs.timeTag );
+
+    messageCursor_ += 16;
+    argumentCurrent_ = messageCursor_;
+
+    return *this;
+}
+
+
+OutboundPacketStream& OutboundPacketStream::operator<<( const BundleTerminator& rhs )
+{
+    (void) rhs;
+
+    if( !IsBundleInProgress() )
+        throw BundleNotInProgressException();
+    if( IsMessageInProgress() )
+        throw MessageInProgressException();
+
+    EndElement( messageCursor_ );
+
+    return *this;
+}
+
+
+OutboundPacketStream& OutboundPacketStream::operator<<( const BeginMessage& rhs )
+{
+    if( IsMessageInProgress() )
+        throw MessageInProgressException();
+
+    CheckForAvailableMessageSpace( rhs.addressPattern );
+
+    messageCursor_ = BeginElement( messageCursor_ );
+
+    strcpy( messageCursor_, rhs.addressPattern );
+    unsigned long rhsLength = strlen(rhs.addressPattern);
+    messageCursor_ += rhsLength + 1;
+
+    // zero pad to 4-byte boundary
+    unsigned long i = rhsLength + 1;
+    while( i & 0x3 ){
+        *messageCursor_++ = '\0';
+        ++i;
+    }
+
+    argumentCurrent_ = messageCursor_;
+    typeTagsCurrent_ = end_;
+
+    messageIsInProgress_ = true;
+
+    return *this;
+}
+
+
+OutboundPacketStream& OutboundPacketStream::operator<<( const MessageTerminator& rhs )
+{
+    (void) rhs;
+
+    if( !IsMessageInProgress() )
+        throw MessageNotInProgressException();
+
+    int typeTagsCount = end_ - typeTagsCurrent_;
+
+    if( typeTagsCount ){
+
+        char *tempTypeTags = (char*)alloca(typeTagsCount);
+        memcpy( tempTypeTags, typeTagsCurrent_, typeTagsCount );
+
+        // slot size includes comma and null terminator
+        int typeTagSlotSize = RoundUp4( typeTagsCount + 2 );
+
+        uint32 argumentsSize = argumentCurrent_ - messageCursor_;
+
+        memmove( messageCursor_ + typeTagSlotSize, messageCursor_, argumentsSize );
+
+        messageCursor_[0] = ',';
+        // copy type tags in reverse (really forward) order
+        for( int i=0; i < typeTagsCount; ++i )
+            messageCursor_[i+1] = tempTypeTags[ (typeTagsCount-1) - i ];
+
+        char *p = messageCursor_ + 1 + typeTagsCount;
+        for( int i=0; i < (typeTagSlotSize - (typeTagsCount + 1)); ++i )
+            *p++ = '\0';
+
+        typeTagsCurrent_ = end_;
+
+        // advance messageCursor_ for next message
+        messageCursor_ += typeTagSlotSize + argumentsSize;
+
+    }else{
+        // send an empty type tags string
+        memcpy( messageCursor_, ",\0\0\0", 4 );
+
+        // advance messageCursor_ for next message
+        messageCursor_ += 4;
+    }
+
+    argumentCurrent_ = messageCursor_;
+
+    EndElement( messageCursor_ );
+
+    messageIsInProgress_ = false;
+
+    return *this;
+}
+
+
+OutboundPacketStream& OutboundPacketStream::operator<<( bool rhs )
+{
+    CheckForAvailableArgumentSpace(0);
+
+    *(--typeTagsCurrent_) = (char)((rhs) ? TRUE_TYPE_TAG : FALSE_TYPE_TAG);
+
+    return *this;
+}
+
+
+OutboundPacketStream& OutboundPacketStream::operator<<( const NilType& rhs )
+{
+    (void) rhs;
+    CheckForAvailableArgumentSpace(0);
+
+    *(--typeTagsCurrent_) = NIL_TYPE_TAG;
+
+    return *this;
+}
+
+
+OutboundPacketStream& OutboundPacketStream::operator<<( const InfinitumType& rhs )
+{
+    (void) rhs;
+    CheckForAvailableArgumentSpace(0);
+
+    *(--typeTagsCurrent_) = INFINITUM_TYPE_TAG;
+
+    return *this;
+}
+
+
+OutboundPacketStream& OutboundPacketStream::operator<<( int32 rhs )
+{
+    CheckForAvailableArgumentSpace(4);
+
+    *(--typeTagsCurrent_) = INT32_TYPE_TAG;
+    FromInt32( argumentCurrent_, rhs );
+    argumentCurrent_ += 4;
+
+    return *this;
+}
+
+
+OutboundPacketStream& OutboundPacketStream::operator<<( float rhs )
+{
+    CheckForAvailableArgumentSpace(4);
+
+    *(--typeTagsCurrent_) = FLOAT_TYPE_TAG;
+
+#ifdef OSC_HOST_LITTLE_ENDIAN
+    union{
+        float f;
+        char c[4];
+    } u;
+
+    u.f = rhs;
+
+    argumentCurrent_[3] = u.c[0];
+    argumentCurrent_[2] = u.c[1];
+    argumentCurrent_[1] = u.c[2];
+    argumentCurrent_[0] = u.c[3];
+#else
+    *reinterpret_cast<float*>(argumentCurrent_) = rhs;
+#endif
+
+    argumentCurrent_ += 4;
+
+    return *this;
+}
+
+
+OutboundPacketStream& OutboundPacketStream::operator<<( char rhs )
+{
+    CheckForAvailableArgumentSpace(4);
+
+    *(--typeTagsCurrent_) = CHAR_TYPE_TAG;
+    FromInt32( argumentCurrent_, rhs );
+    argumentCurrent_ += 4;
+
+    return *this;
+}
+
+
+OutboundPacketStream& OutboundPacketStream::operator<<( const RgbaColor& rhs )
+{
+    CheckForAvailableArgumentSpace(4);
+
+    *(--typeTagsCurrent_) = RGBA_COLOR_TYPE_TAG;
+    FromUInt32( argumentCurrent_, rhs );
+    argumentCurrent_ += 4;
+
+    return *this;
+}
+
+
+OutboundPacketStream& OutboundPacketStream::operator<<( const MidiMessage& rhs )
+{
+    CheckForAvailableArgumentSpace(4);
+
+    *(--typeTagsCurrent_) = MIDI_MESSAGE_TYPE_TAG;
+    FromUInt32( argumentCurrent_, rhs );
+    argumentCurrent_ += 4;
+
+    return *this;
+}
+
+
+OutboundPacketStream& OutboundPacketStream::operator<<( int64 rhs )
+{
+    CheckForAvailableArgumentSpace(8);
+
+    *(--typeTagsCurrent_) = INT64_TYPE_TAG;
+    FromInt64( argumentCurrent_, rhs );
+    argumentCurrent_ += 8;
+
+    return *this;
+}
+
+
+OutboundPacketStream& OutboundPacketStream::operator<<( const TimeTag& rhs )
+{
+    CheckForAvailableArgumentSpace(8);
+
+    *(--typeTagsCurrent_) = TIME_TAG_TYPE_TAG;
+    FromUInt64( argumentCurrent_, rhs );
+    argumentCurrent_ += 8;
+
+    return *this;
+}
+
+
+OutboundPacketStream& OutboundPacketStream::operator<<( double rhs )
+{
+    CheckForAvailableArgumentSpace(8);
+
+    *(--typeTagsCurrent_) = DOUBLE_TYPE_TAG;
+
+#ifdef OSC_HOST_LITTLE_ENDIAN
+    union{
+        double f;
+        char c[8];
+    } u;
+
+    u.f = rhs;
+
+    argumentCurrent_[7] = u.c[0];
+    argumentCurrent_[6] = u.c[1];
+    argumentCurrent_[5] = u.c[2];
+    argumentCurrent_[4] = u.c[3];
+    argumentCurrent_[3] = u.c[4];
+    argumentCurrent_[2] = u.c[5];
+    argumentCurrent_[1] = u.c[6];
+    argumentCurrent_[0] = u.c[7];
+#else
+    *reinterpret_cast<double*>(argumentCurrent_) = rhs;
+#endif
+
+    argumentCurrent_ += 8;
+
+    return *this;
+}
+
+
+OutboundPacketStream& OutboundPacketStream::operator<<( const char *rhs )
+{
+    CheckForAvailableArgumentSpace( RoundUp4(strlen(rhs) + 1) );
+
+    *(--typeTagsCurrent_) = STRING_TYPE_TAG;
+    strcpy( argumentCurrent_, rhs );
+    unsigned long rhsLength = strlen(rhs);
+    argumentCurrent_ += rhsLength + 1;
+
+    // zero pad to 4-byte boundary
+    unsigned long i = rhsLength + 1;
+    while( i & 0x3 ){
+        *argumentCurrent_++ = '\0';
+        ++i;
+    }
+
+    return *this;
+}
+
+
+OutboundPacketStream& OutboundPacketStream::operator<<( const Symbol& rhs )
+{
+    CheckForAvailableArgumentSpace( RoundUp4(strlen(rhs) + 1) );
+
+    *(--typeTagsCurrent_) = SYMBOL_TYPE_TAG;
+    strcpy( argumentCurrent_, rhs );
+    unsigned long rhsLength = strlen(rhs);
+    argumentCurrent_ += rhsLength + 1;
+
+    // zero pad to 4-byte boundary
+    unsigned long i = rhsLength + 1;
+    while( i & 0x3 ){
+        *argumentCurrent_++ = '\0';
+        ++i;
+    }
+
+    return *this;
+}
+
+
+OutboundPacketStream& OutboundPacketStream::operator<<( const Blob& rhs )
+{
+    CheckForAvailableArgumentSpace( 4 + RoundUp4(rhs.size) );
+
+    *(--typeTagsCurrent_) = BLOB_TYPE_TAG;
+    FromUInt32( argumentCurrent_, rhs.size );
+    argumentCurrent_ += 4;
+    
+    memcpy( argumentCurrent_, rhs.data, rhs.size );
+    argumentCurrent_ += rhs.size;
+
+    // zero pad to 4-byte boundary
+    unsigned long i = rhs.size;
+    while( i & 0x3 ){
+        *argumentCurrent_++ = '\0';
+        ++i;
+    }
+
+    return *this;
+}
+
+} // namespace osc
+
+
diff --git a/src/osc/osc/OscOutboundPacketStream.h b/src/osc/osc/OscOutboundPacketStream.h
new file mode 100755
index 0000000..317e4b2
--- /dev/null
+++ b/src/osc/osc/OscOutboundPacketStream.h
@@ -0,0 +1,142 @@
+/*
+	oscpack -- Open Sound Control packet manipulation library
+	http://www.audiomulch.com/~rossb/oscpack
+
+	Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>
+
+	Permission is hereby granted, free of charge, to any person obtaining
+	a copy of this software and associated documentation files
+	(the "Software"), to deal in the Software without restriction,
+	including without limitation the rights to use, copy, modify, merge,
+	publish, distribute, sublicense, and/or sell copies of the Software,
+	and to permit persons to whom the Software is furnished to do so,
+	subject to the following conditions:
+
+	The above copyright notice and this permission notice shall be
+	included in all copies or substantial portions of the Software.
+
+	Any person wishing to distribute modifications to the Software is
+	requested to send the modifications to the original developer so that
+	they can be incorporated into the canonical version.
+
+	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+	EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+	MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+	IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+	ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+	CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+	WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+#ifndef INCLUDED_OSCOUTBOUNDPACKET_H
+#define INCLUDED_OSCOUTBOUNDPACKET_H
+
+#include "OscTypes.h"
+#include "OscException.h"
+
+
+namespace osc{
+
+class OutOfBufferMemoryException : public Exception{
+public:
+    OutOfBufferMemoryException( const char *w="out of buffer memory" )
+        : Exception( w ) {}
+};
+
+class BundleNotInProgressException : public Exception{
+public:
+    BundleNotInProgressException(
+            const char *w="call to EndBundle when bundle is not in progress" )
+        : Exception( w ) {}
+};
+
+class MessageInProgressException : public Exception{
+public:
+    MessageInProgressException(
+            const char *w="opening or closing bundle or message while message is in progress" )
+        : Exception( w ) {}
+};
+
+class MessageNotInProgressException : public Exception{
+public:
+    MessageNotInProgressException(
+            const char *w="call to EndMessage when message is not in progress" )
+        : Exception( w ) {}
+};
+
+
+class OutboundPacketStream{
+public:
+	OutboundPacketStream( char *buffer, unsigned long capacity );
+	~OutboundPacketStream();
+
+    void Clear();
+
+    unsigned int Capacity() const;
+
+    // invariant: size() is valid even while building a message.
+    unsigned int Size() const;
+
+    const char *Data() const;
+
+    // indicates that all messages have been closed with a matching EndMessage
+    // and all bundles have been closed with a matching EndBundle
+    bool IsReady() const;
+
+    bool IsMessageInProgress() const;
+    bool IsBundleInProgress() const;
+
+    OutboundPacketStream& operator<<( const BundleInitiator& rhs );
+    OutboundPacketStream& operator<<( const BundleTerminator& rhs );
+    
+    OutboundPacketStream& operator<<( const BeginMessage& rhs );
+    OutboundPacketStream& operator<<( const MessageTerminator& rhs );
+
+    OutboundPacketStream& operator<<( bool rhs );
+    OutboundPacketStream& operator<<( const NilType& rhs );
+    OutboundPacketStream& operator<<( const InfinitumType& rhs );
+    OutboundPacketStream& operator<<( int32 rhs );
+
+#ifndef x86_64
+    OutboundPacketStream& operator<<( int rhs )
+            { *this << (int32)rhs; return *this; }
+#endif
+
+    OutboundPacketStream& operator<<( float rhs );
+    OutboundPacketStream& operator<<( char rhs );
+    OutboundPacketStream& operator<<( const RgbaColor& rhs );
+    OutboundPacketStream& operator<<( const MidiMessage& rhs );
+    OutboundPacketStream& operator<<( int64 rhs );
+    OutboundPacketStream& operator<<( const TimeTag& rhs );
+    OutboundPacketStream& operator<<( double rhs );
+    OutboundPacketStream& operator<<( const char* rhs );
+    OutboundPacketStream& operator<<( const Symbol& rhs );
+    OutboundPacketStream& operator<<( const Blob& rhs );
+
+private:
+
+    char *BeginElement( char *beginPtr );
+    void EndElement( char *endPtr );
+
+    bool ElementSizeSlotRequired() const;
+    void CheckForAvailableBundleSpace();
+    void CheckForAvailableMessageSpace( const char *addressPattern );
+    void CheckForAvailableArgumentSpace( long argumentLength );
+
+    char *data_;
+    char *end_;
+
+    char *typeTagsCurrent_; // stored in reverse order
+    char *messageCursor_;
+    char *argumentCurrent_;
+
+    // elementSizePtr_ has two special values: 0 indicates that a bundle
+    // isn't open, and elementSizePtr_==data_ indicates that a bundle is
+    // open but that it doesn't have a size slot (ie the outermost bundle)
+    uint32 *elementSizePtr_;
+
+    bool messageIsInProgress_;
+};
+
+} // namespace osc
+
+#endif /* INCLUDED_OSC_OUTBOUND_PACKET_H */
diff --git a/src/osc/osc/OscPacketListener.h b/src/osc/osc/OscPacketListener.h
new file mode 100755
index 0000000..bc322b7
--- /dev/null
+++ b/src/osc/osc/OscPacketListener.h
@@ -0,0 +1,72 @@
+/*
+	oscpack -- Open Sound Control packet manipulation library
+	http://www.audiomulch.com/~rossb/oscpack
+
+	Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>
+
+	Permission is hereby granted, free of charge, to any person obtaining
+	a copy of this software and associated documentation files
+	(the "Software"), to deal in the Software without restriction,
+	including without limitation the rights to use, copy, modify, merge,
+	publish, distribute, sublicense, and/or sell copies of the Software,
+	and to permit persons to whom the Software is furnished to do so,
+	subject to the following conditions:
+
+	The above copyright notice and this permission notice shall be
+	included in all copies or substantial portions of the Software.
+
+	Any person wishing to distribute modifications to the Software is
+	requested to send the modifications to the original developer so that
+	they can be incorporated into the canonical version.
+
+	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+	EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+	MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+	IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+	ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+	CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+	WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+#ifndef INCLUDED_OSCPACKETLISTENER_H
+#define INCLUDED_OSCPACKETLISTENER_H
+
+#include "OscReceivedElements.h"
+#include "../ip/PacketListener.h"
+
+
+namespace osc{
+
+class OscPacketListener : public PacketListener{ 
+protected:
+    virtual void ProcessBundle( const osc::ReceivedBundle& b, 
+				const IpEndpointName& remoteEndpoint )
+    {
+        // ignore bundle time tag for now
+
+        for( ReceivedBundle::const_iterator i = b.ElementsBegin(); 
+				i != b.ElementsEnd(); ++i ){
+            if( i->IsBundle() )
+                ProcessBundle( ReceivedBundle(*i), remoteEndpoint );
+            else
+                ProcessMessage( ReceivedMessage(*i), remoteEndpoint );
+        }
+    }
+
+    virtual void ProcessMessage( const osc::ReceivedMessage& m, 
+				const IpEndpointName& remoteEndpoint ) = 0;
+    
+public:
+	virtual void ProcessPacket( const char *data, int size, 
+			const IpEndpointName& remoteEndpoint )
+    {
+        osc::ReceivedPacket p( data, size );
+        if( p.IsBundle() )
+            ProcessBundle( ReceivedBundle(p), remoteEndpoint );
+        else
+            ProcessMessage( ReceivedMessage(p), remoteEndpoint );
+    }
+};
+
+} // namespace osc
+
+#endif /* INCLUDED_OSCPACKETLISTENER_H */
diff --git a/src/osc/osc/OscPrintReceivedElements.cpp b/src/osc/osc/OscPrintReceivedElements.cpp
new file mode 100755
index 0000000..430cf92
--- /dev/null
+++ b/src/osc/osc/OscPrintReceivedElements.cpp
@@ -0,0 +1,241 @@
+/*
+	oscpack -- Open Sound Control packet manipulation library
+	http://www.audiomulch.com/~rossb/oscpack
+
+	Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>
+
+	Permission is hereby granted, free of charge, to any person obtaining
+	a copy of this software and associated documentation files
+	(the "Software"), to deal in the Software without restriction,
+	including without limitation the rights to use, copy, modify, merge,
+	publish, distribute, sublicense, and/or sell copies of the Software,
+	and to permit persons to whom the Software is furnished to do so,
+	subject to the following conditions:
+
+	The above copyright notice and this permission notice shall be
+	included in all copies or substantial portions of the Software.
+
+	Any person wishing to distribute modifications to the Software is
+	requested to send the modifications to the original developer so that
+	they can be incorporated into the canonical version.
+
+	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+	EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+	MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+	IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+	ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+	CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+	WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+#include "OscPrintReceivedElements.h"
+
+#include <iostream>
+#include <iomanip>
+#include <ctime>
+#include <string.h>
+
+
+namespace osc{
+
+
+std::ostream& operator<<( std::ostream & os,
+        const ReceivedMessageArgument& arg )
+{
+    switch( arg.TypeTag() ){
+        case TRUE_TYPE_TAG:
+            os << "bool:true";
+            break;
+                
+        case FALSE_TYPE_TAG:
+            os << "bool:false";
+            break;
+
+        case NIL_TYPE_TAG:
+            os << "(Nil)";
+            break;
+
+        case INFINITUM_TYPE_TAG:
+            os << "(Infinitum)";
+            break;
+
+        case INT32_TYPE_TAG:
+            os << "int32:" << arg.AsInt32Unchecked();
+            break;
+
+        case FLOAT_TYPE_TAG:
+            os << "float32:" << arg.AsFloatUnchecked();
+            break;
+
+        case CHAR_TYPE_TAG:
+            {
+                char s[2] = {0};
+                s[0] = arg.AsCharUnchecked();
+                os << "char:'" << s << "'";
+            }
+            break;
+
+        case RGBA_COLOR_TYPE_TAG:
+            {
+                uint32 color = arg.AsRgbaColorUnchecked();
+                
+                os << "RGBA:0x"
+                        << std::hex << std::setfill('0')
+                        << std::setw(2) << (int)((color>>24) & 0xFF)
+                        << std::setw(2) << (int)((color>>16) & 0xFF)
+                        << std::setw(2) << (int)((color>>8) & 0xFF)
+                        << std::setw(2) << (int)(color & 0xFF)
+                        << std::setfill(' ');
+                os.unsetf(std::ios::basefield);
+            }
+            break;
+
+        case MIDI_MESSAGE_TYPE_TAG:
+            {
+                uint32 m = arg.AsMidiMessageUnchecked();
+                os << "midi (port, status, data1, data2):<<"
+                        << std::hex << std::setfill('0')
+                        << "0x" << std::setw(2) << (int)((m>>24) & 0xFF)
+                        << " 0x" << std::setw(2) << (int)((m>>16) & 0xFF)
+                        << " 0x" << std::setw(2) << (int)((m>>8) & 0xFF)
+                        << " 0x" << std::setw(2) << (int)(m & 0xFF)
+                        << std::setfill(' ') << ">>";
+                os.unsetf(std::ios::basefield);
+            }
+            break;
+				
+        case INT64_TYPE_TAG:
+            os << "int64:" << arg.AsInt64Unchecked();
+            break;
+
+        case TIME_TAG_TYPE_TAG:
+            {
+                os << "OSC-timetag:" << arg.AsTimeTagUnchecked();
+
+                std::time_t t =
+                        (unsigned long)( arg.AsTimeTagUnchecked() >> 32 );
+
+                // strip trailing newline from string returned by ctime
+                const char *timeString = std::ctime( &t );
+                size_t len = strlen( timeString );
+                char *s = new char[ len + 1 ];
+                strcpy( s, timeString );
+                if( len )
+                    s[ len - 1 ] = '\0';
+                    
+                os << " " << s;
+            }
+            break;
+                
+        case DOUBLE_TYPE_TAG:
+            os << "double:" << arg.AsDoubleUnchecked();
+            break;
+
+        case STRING_TYPE_TAG:
+            os << "OSC-string:`" << arg.AsStringUnchecked() << "'";
+            break;
+                
+        case SYMBOL_TYPE_TAG: 
+            os << "OSC-string (symbol):`" << arg.AsSymbolUnchecked() << "'";
+            break;
+
+        case BLOB_TYPE_TAG:
+            {
+                unsigned long size;
+                const void *data;
+                arg.AsBlobUnchecked( data, size );
+                os << "OSC-blob:<<" << std::hex << std::setfill('0');
+                unsigned char *p = (unsigned char*)data;
+                for( unsigned long i = 0; i < size; ++i ){
+                    os << "0x" << std::setw(2) << int(p[i]);
+                    if( i != size-1 )
+                        os << ' ';
+                }
+                os.unsetf(std::ios::basefield);
+                os << ">>" << std::setfill(' ');
+            }
+            break;
+
+        default:
+            os << "unknown";
+    }
+
+    return os;
+}
+
+
+std::ostream& operator<<( std::ostream & os, const ReceivedMessage& m )
+{
+
+    os << "[" << m.AddressPattern();
+    bool first = true;
+
+    for( ReceivedMessage::const_iterator i = m.ArgumentsBegin();
+            i != m.ArgumentsEnd(); ++i ){
+        if( first ){
+            os << " ";
+            first = false;
+        }else{
+            os << ", ";
+        }
+
+        os << *i;
+    }
+
+    os << "]";
+
+    return os;
+}
+
+
+std::ostream& operator<<( std::ostream & os, const ReceivedBundle& b )
+{
+    static int indent = 0;
+
+    for( int j=0; j < indent; ++j )
+        os << "  ";
+    os << "{ ( ";
+    if( b.TimeTag() == 1 )
+        os << "immediate";
+    else
+        os << b.TimeTag();
+    os << " )\n";
+
+    ++indent;
+    
+    for( ReceivedBundle::const_iterator i = b.ElementsBegin();
+            i != b.ElementsEnd(); ++i ){
+        if( i->IsBundle() ){
+            ReceivedBundle b(*i);
+            os << b << "\n";
+        }else{
+            ReceivedMessage m(*i);
+            for( int j=0; j < indent; ++j )
+                os << "  ";
+            os << m << "\n";
+        }
+    }
+
+    --indent;
+
+    for( int j=0; j < indent; ++j )
+        os << "  ";
+    os << "}";
+
+    return os;
+}
+
+
+std::ostream& operator<<( std::ostream & os, const ReceivedPacket& p )
+{
+    if( p.IsBundle() ){
+        ReceivedBundle b(p);
+        os << b << "\n";
+    }else{
+        ReceivedMessage m(p);
+        os << m << "\n";
+    }
+
+    return os;
+}
+
+} // namespace osc
diff --git a/src/osc/osc/OscPrintReceivedElements.h b/src/osc/osc/OscPrintReceivedElements.h
new file mode 100755
index 0000000..c42cfa5
--- /dev/null
+++ b/src/osc/osc/OscPrintReceivedElements.h
@@ -0,0 +1,49 @@
+/*
+	oscpack -- Open Sound Control packet manipulation library
+	http://www.audiomulch.com/~rossb/oscpack
+
+	Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>
+
+	Permission is hereby granted, free of charge, to any person obtaining
+	a copy of this software and associated documentation files
+	(the "Software"), to deal in the Software without restriction,
+	including without limitation the rights to use, copy, modify, merge,
+	publish, distribute, sublicense, and/or sell copies of the Software,
+	and to permit persons to whom the Software is furnished to do so,
+	subject to the following conditions:
+
+	The above copyright notice and this permission notice shall be
+	included in all copies or substantial portions of the Software.
+
+	Any person wishing to distribute modifications to the Software is
+	requested to send the modifications to the original developer so that
+	they can be incorporated into the canonical version.
+
+	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+	EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+	MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+	IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+	ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+	CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+	WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+#ifndef INCLUDED_OSCPRINTRECEIVEDELEMENTS_H
+#define INCLUDED_OSCPRINTRECEIVEDELEMENTS_H
+
+#include <iosfwd>
+
+#ifndef INCLUDED_OSCRECEIVEDELEMENTS_H
+#include "OscReceivedElements.h"
+#endif /* INCLUDED_OSCRECEIVEDELEMENTS_H */
+
+
+namespace osc{
+
+std::ostream& operator<<( std::ostream & os, const ReceivedPacket& p );
+std::ostream& operator<<( std::ostream & os, const ReceivedMessageArgument& arg );
+std::ostream& operator<<( std::ostream & os, const ReceivedMessage& m );
+std::ostream& operator<<( std::ostream & os, const ReceivedBundle& b );
+
+} // namespace osc
+
+#endif /* INCLUDED_OSCPRINTRECEIVEDELEMENTS_H */
diff --git a/src/osc/osc/OscReceivedElements.cpp b/src/osc/osc/OscReceivedElements.cpp
new file mode 100755
index 0000000..326fd62
--- /dev/null
+++ b/src/osc/osc/OscReceivedElements.cpp
@@ -0,0 +1,722 @@
+/*
+	oscpack -- Open Sound Control packet manipulation library
+	http://www.audiomulch.com/~rossb/oscpack
+
+	Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>
+
+	Permission is hereby granted, free of charge, to any person obtaining
+	a copy of this software and associated documentation files
+	(the "Software"), to deal in the Software without restriction,
+	including without limitation the rights to use, copy, modify, merge,
+	publish, distribute, sublicense, and/or sell copies of the Software,
+	and to permit persons to whom the Software is furnished to do so,
+	subject to the following conditions:
+
+	The above copyright notice and this permission notice shall be
+	included in all copies or substantial portions of the Software.
+
+	Any person wishing to distribute modifications to the Software is
+	requested to send the modifications to the original developer so that
+	they can be incorporated into the canonical version.
+
+	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+	EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+	MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+	IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+	ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+	CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+	WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+#include "OscReceivedElements.h"
+
+#include <cassert>
+
+#include "OscHostEndianness.h"
+
+
+namespace osc{
+
+
+// return the first 4 byte boundary after the end of a str4
+// be careful about calling this version if you don't know whether
+// the string is terminated correctly.
+static inline const char* FindStr4End( const char *p )
+{
+	if( p[0] == '\0' )    // special case for SuperCollider integer address pattern
+		return p + 4;
+
+    p += 3;
+
+    while( *p )
+        p += 4;
+
+    return p + 1;
+}
+
+
+// return the first 4 byte boundary after the end of a str4
+// returns 0 if p == end or if the string is unterminated
+static inline const char* FindStr4End( const char *p, const char *end )
+{
+    if( p >= end )
+        return 0;
+
+	if( p[0] == '\0' )    // special case for SuperCollider integer address pattern
+		return p + 4;
+
+    p += 3;
+    end -= 1;
+
+    while( p < end && *p )
+        p += 4;
+
+    if( *p )
+        return 0;
+    else
+        return p + 1;
+}
+
+
+static inline unsigned long RoundUp4( unsigned long x )
+{
+    unsigned long remainder = x & 0x3UL;
+    if( remainder )
+        return x + (4 - remainder);
+    else
+        return x;
+}
+
+
+static inline int32 ToInt32( const char *p )
+{
+#ifdef OSC_HOST_LITTLE_ENDIAN
+    union{
+        osc::int32 i;
+        char c[4];
+    } u;
+
+    u.c[0] = p[3];
+    u.c[1] = p[2];
+    u.c[2] = p[1];
+    u.c[3] = p[0];
+
+    return u.i;
+#else
+	return *(int32*)p;
+#endif
+}
+
+
+static inline uint32 ToUInt32( const char *p )
+{
+#ifdef OSC_HOST_LITTLE_ENDIAN
+    union{
+        osc::uint32 i;
+        char c[4];
+    } u;
+
+    u.c[0] = p[3];
+    u.c[1] = p[2];
+    u.c[2] = p[1];
+    u.c[3] = p[0];
+
+    return u.i;
+#else
+	return *(uint32*)p;
+#endif
+}
+
+
+int64 ToInt64( const char *p )
+{
+#ifdef OSC_HOST_LITTLE_ENDIAN
+    union{
+        osc::int64 i;
+        char c[4];
+    } u;
+
+    u.c[0] = p[7];
+    u.c[1] = p[6];
+    u.c[2] = p[5];
+    u.c[3] = p[4];
+    u.c[4] = p[3];
+    u.c[5] = p[2];
+    u.c[6] = p[1];
+    u.c[7] = p[0];
+
+    return u.i;
+#else
+	return *(int64*)p;
+#endif
+}
+
+
+uint64 ToUInt64( const char *p )
+{
+#ifdef OSC_HOST_LITTLE_ENDIAN
+    union{
+        osc::uint64 i;
+        char c[4];
+    } u;
+
+    u.c[0] = p[7];
+    u.c[1] = p[6];
+    u.c[2] = p[5];
+    u.c[3] = p[4];
+    u.c[4] = p[3];
+    u.c[5] = p[2];
+    u.c[6] = p[1];
+    u.c[7] = p[0];
+
+    return u.i;
+#else
+	return *(uint64*)p;
+#endif
+}
+
+//------------------------------------------------------------------------------
+
+bool ReceivedPacket::IsBundle() const
+{
+    return (Size() > 0 && Contents()[0] == '#');
+}
+
+//------------------------------------------------------------------------------
+
+bool ReceivedBundleElement::IsBundle() const
+{
+    return (Size() > 0 && Contents()[0] == '#');
+}
+
+
+int32 ReceivedBundleElement::Size() const
+{
+    return ToUInt32( size_ );
+}
+
+//------------------------------------------------------------------------------
+
+bool ReceivedMessageArgument::AsBool() const
+{
+    if( !typeTag_ )
+        throw MissingArgumentException();
+	else if( *typeTag_ == TRUE_TYPE_TAG )
+		return true;
+	else if( *typeTag_ == FALSE_TYPE_TAG )
+		return false;
+	else
+		throw WrongArgumentTypeException();
+}
+
+
+bool ReceivedMessageArgument::AsBoolUnchecked() const
+{
+    if( !typeTag_ )
+        throw MissingArgumentException();
+	else if( *typeTag_ == TRUE_TYPE_TAG )
+		return true;
+    else
+	    return false;
+}
+
+
+int32 ReceivedMessageArgument::AsInt32() const
+{
+    if( !typeTag_ )
+        throw MissingArgumentException();
+	else if( *typeTag_ == INT32_TYPE_TAG )
+		return AsInt32Unchecked();
+	else
+		throw WrongArgumentTypeException();
+}
+
+
+int32 ReceivedMessageArgument::AsInt32Unchecked() const
+{
+#ifdef OSC_HOST_LITTLE_ENDIAN
+    union{
+        osc::int32 i;
+        char c[4];
+    } u;
+
+    u.c[0] = argument_[3];
+    u.c[1] = argument_[2];
+    u.c[2] = argument_[1];
+    u.c[3] = argument_[0];
+
+    return u.i;
+#else
+	return *(int32*)argument_;
+#endif
+}
+
+
+float ReceivedMessageArgument::AsFloat() const
+{
+    if( !typeTag_ )
+        throw MissingArgumentException();
+	else if( *typeTag_ == FLOAT_TYPE_TAG )
+		return AsFloatUnchecked();
+	else
+		throw WrongArgumentTypeException();
+}
+
+
+float ReceivedMessageArgument::AsFloatUnchecked() const
+{
+#ifdef OSC_HOST_LITTLE_ENDIAN
+    union{
+        float f;
+        char c[4];
+    } u;
+
+    u.c[0] = argument_[3];
+    u.c[1] = argument_[2];
+    u.c[2] = argument_[1];
+    u.c[3] = argument_[0];
+
+    return u.f;
+#else
+	return *(float*)argument_;
+#endif
+}
+
+
+char ReceivedMessageArgument::AsChar() const
+{
+    if( !typeTag_ )
+        throw MissingArgumentException();
+	else if( *typeTag_ == CHAR_TYPE_TAG )
+		return AsCharUnchecked();
+	else
+		throw WrongArgumentTypeException();
+}
+
+
+char ReceivedMessageArgument::AsCharUnchecked() const
+{
+    return (char)ToInt32( argument_ );
+}
+
+
+uint32 ReceivedMessageArgument::AsRgbaColor() const
+{
+    if( !typeTag_ )
+        throw MissingArgumentException();
+	else if( *typeTag_ == RGBA_COLOR_TYPE_TAG )
+		return AsRgbaColorUnchecked();
+	else
+		throw WrongArgumentTypeException();
+}
+
+
+uint32 ReceivedMessageArgument::AsRgbaColorUnchecked() const
+{
+	return ToUInt32( argument_ );
+}
+
+
+uint32 ReceivedMessageArgument::AsMidiMessage() const
+{
+    if( !typeTag_ )
+        throw MissingArgumentException();
+	else if( *typeTag_ == MIDI_MESSAGE_TYPE_TAG )
+		return AsMidiMessageUnchecked();
+	else
+		throw WrongArgumentTypeException();
+}
+
+
+uint32 ReceivedMessageArgument::AsMidiMessageUnchecked() const
+{
+	return ToUInt32( argument_ );
+}
+
+
+int64 ReceivedMessageArgument::AsInt64() const
+{
+    if( !typeTag_ )
+        throw MissingArgumentException();
+	else if( *typeTag_ == INT64_TYPE_TAG )
+		return AsInt64Unchecked();
+	else
+		throw WrongArgumentTypeException();
+}
+
+
+int64 ReceivedMessageArgument::AsInt64Unchecked() const
+{
+    return ToInt64( argument_ );
+}
+
+
+uint64 ReceivedMessageArgument::AsTimeTag() const
+{
+    if( !typeTag_ )
+        throw MissingArgumentException();
+	else if( *typeTag_ == TIME_TAG_TYPE_TAG )
+		return AsTimeTagUnchecked();
+	else
+		throw WrongArgumentTypeException();
+}
+
+
+uint64 ReceivedMessageArgument::AsTimeTagUnchecked() const
+{
+    return ToUInt64( argument_ );
+}
+
+
+double ReceivedMessageArgument::AsDouble() const
+{
+    if( !typeTag_ )
+        throw MissingArgumentException();
+	else if( *typeTag_ == DOUBLE_TYPE_TAG )
+		return AsDoubleUnchecked();
+	else
+		throw WrongArgumentTypeException();
+}
+
+
+double ReceivedMessageArgument::AsDoubleUnchecked() const
+{
+#ifdef OSC_HOST_LITTLE_ENDIAN
+    union{
+        double d;
+        char c[8];
+    } u;
+
+    u.c[0] = argument_[7];
+    u.c[1] = argument_[6];
+    u.c[2] = argument_[5];
+    u.c[3] = argument_[4];
+    u.c[4] = argument_[3];
+    u.c[5] = argument_[2];
+    u.c[6] = argument_[1];
+    u.c[7] = argument_[0];
+
+    return u.d;
+#else
+	return *(double*)argument_;
+#endif
+}
+
+
+const char* ReceivedMessageArgument::AsString() const
+{
+    if( !typeTag_ )
+        throw MissingArgumentException();
+	else if( *typeTag_ == STRING_TYPE_TAG )
+		return argument_;
+	else
+		throw WrongArgumentTypeException();
+}
+
+
+const char* ReceivedMessageArgument::AsSymbol() const
+{
+    if( !typeTag_ )
+        throw MissingArgumentException();
+	else if( *typeTag_ == SYMBOL_TYPE_TAG )
+		return argument_;
+	else
+		throw WrongArgumentTypeException();
+}
+
+
+void ReceivedMessageArgument::AsBlob( const void*& data, unsigned long& size ) const
+{
+    if( !typeTag_ )
+        throw MissingArgumentException();
+	else if( *typeTag_ == BLOB_TYPE_TAG )
+		AsBlobUnchecked( data, size );
+	else
+		throw WrongArgumentTypeException();
+}
+
+
+void ReceivedMessageArgument::AsBlobUnchecked( const void*& data, unsigned long& size ) const
+{
+    size = ToUInt32( argument_ );
+	data = (void*)(argument_+4);
+}
+
+//------------------------------------------------------------------------------
+
+void ReceivedMessageArgumentIterator::Advance()
+{
+    if( !value_.typeTag_ )
+        return;
+        
+    switch( *value_.typeTag_++ ){
+        case '\0':
+            // don't advance past end
+            --value_.typeTag_;
+            break;
+            
+        case TRUE_TYPE_TAG:
+        case FALSE_TYPE_TAG:
+        case NIL_TYPE_TAG:
+        case INFINITUM_TYPE_TAG:
+
+            // zero length
+            break;
+
+        case INT32_TYPE_TAG:
+        case FLOAT_TYPE_TAG: 					
+        case CHAR_TYPE_TAG:
+        case RGBA_COLOR_TYPE_TAG:
+        case MIDI_MESSAGE_TYPE_TAG:
+
+            value_.argument_ += 4;
+            break;
+
+        case INT64_TYPE_TAG:
+        case TIME_TAG_TYPE_TAG:
+        case DOUBLE_TYPE_TAG:
+				
+            value_.argument_ += 8;
+            break;
+
+        case STRING_TYPE_TAG: 
+        case SYMBOL_TYPE_TAG:
+
+            // we use the unsafe function FindStr4End(char*) here because all of
+            // the arguments have already been validated in
+            // ReceivedMessage::Init() below.
+            
+            value_.argument_ = FindStr4End( value_.argument_ );
+            break;
+
+        case BLOB_TYPE_TAG:
+            {
+                uint32 blobSize = ToUInt32( value_.argument_ );
+                value_.argument_ = value_.argument_ + 4 + RoundUp4( blobSize );
+            }
+            break;
+
+        default:    // unknown type tag
+            // don't advance
+            --value_.typeTag_;
+            break;
+            
+
+        //    not handled:
+        //    [ Indicates the beginning of an array. The tags following are for
+        //        data in the Array until a close brace tag is reached.
+        //    ] Indicates the end of an array.
+    }
+}
+
+//------------------------------------------------------------------------------
+
+ReceivedMessage::ReceivedMessage( const ReceivedPacket& packet )
+    : addressPattern_( packet.Contents() )
+{
+    Init( packet.Contents(), packet.Size() );
+}
+
+
+ReceivedMessage::ReceivedMessage( const ReceivedBundleElement& bundleElement )
+    : addressPattern_( bundleElement.Contents() )
+{
+    Init( bundleElement.Contents(), bundleElement.Size() );
+}
+
+
+bool ReceivedMessage::AddressPatternIsUInt32() const
+{
+	return (addressPattern_[0] == '\0');
+}
+
+
+uint32 ReceivedMessage::AddressPatternAsUInt32() const
+{
+    return ToUInt32( addressPattern_ );
+}
+
+
+void ReceivedMessage::Init( const char *message, unsigned long size )
+{
+    if( size == 0 )
+        throw MalformedMessageException( "zero length messages not permitted" );
+
+    if( (size & 0x03L) != 0 )
+        throw MalformedMessageException( "message size must be multiple of four" );
+
+    const char *end = message + size;
+
+    typeTagsBegin_ = FindStr4End( addressPattern_, end );
+    if( typeTagsBegin_ == 0 ){
+        // address pattern was not terminated before end
+        throw MalformedMessageException( "unterminated address pattern" );
+    }
+
+    if( typeTagsBegin_ == end ){
+        // message consists of only the address pattern - no arguments or type tags.
+        typeTagsBegin_ = 0;
+        typeTagsEnd_ = 0;
+        arguments_ = 0;
+            
+    }else{
+        if( *typeTagsBegin_ != ',' )
+            throw MalformedMessageException( "type tags not present" );
+
+        if( *(typeTagsBegin_ + 1) == '\0' ){
+            // zero length type tags
+            typeTagsBegin_ = 0;
+            typeTagsEnd_ = 0;
+            arguments_ = 0;
+
+        }else{
+            // check that all arguments are present and well formed
+                
+            arguments_ = FindStr4End( typeTagsBegin_, end );
+            if( arguments_ == 0 ){
+                throw MalformedMessageException( "type tags were not terminated before end of message" );
+            }
+
+            ++typeTagsBegin_; // advance past initial ','
+            
+            const char *typeTag = typeTagsBegin_;
+            const char *argument = arguments_;
+                        
+            do{
+                switch( *typeTag ){
+                    case TRUE_TYPE_TAG:
+                    case FALSE_TYPE_TAG:
+                    case NIL_TYPE_TAG:
+                    case INFINITUM_TYPE_TAG:
+
+                        // zero length
+                        break;
+
+                    case INT32_TYPE_TAG:
+                    case FLOAT_TYPE_TAG:
+                    case CHAR_TYPE_TAG:
+                    case RGBA_COLOR_TYPE_TAG:
+                    case MIDI_MESSAGE_TYPE_TAG:
+
+                        if( argument == end )
+                            throw MalformedMessageException( "arguments exceed message size" );
+                        argument += 4;
+                        if( argument > end )
+                            throw MalformedMessageException( "arguments exceed message size" );
+                        break;
+
+                    case INT64_TYPE_TAG:
+                    case TIME_TAG_TYPE_TAG:
+                    case DOUBLE_TYPE_TAG:
+
+                        if( argument == end )
+                            throw MalformedMessageException( "arguments exceed message size" );
+                        argument += 8;
+                        if( argument > end )
+                            throw MalformedMessageException( "arguments exceed message size" );
+                        break;
+
+                    case STRING_TYPE_TAG: 
+                    case SYMBOL_TYPE_TAG:
+                    
+                        if( argument == end )
+                            throw MalformedMessageException( "arguments exceed message size" );
+                        argument = FindStr4End( argument, end );
+                        if( argument == 0 )
+                            throw MalformedMessageException( "unterminated string argument" );
+                        break;
+
+                    case BLOB_TYPE_TAG:
+                        {
+                            if( argument + 4 > end )
+                                MalformedMessageException( "arguments exceed message size" );
+                                
+                            uint32 blobSize = ToUInt32( argument );
+                            argument = argument + 4 + RoundUp4( blobSize );
+                            if( argument > end )
+                                MalformedMessageException( "arguments exceed message size" );
+                        }
+                        break;
+                        
+                    default:
+                        throw MalformedMessageException( "unknown type tag" );
+
+                    //    not handled:
+                    //    [ Indicates the beginning of an array. The tags following are for
+                    //        data in the Array until a close brace tag is reached.
+                    //    ] Indicates the end of an array.
+                }
+
+            }while( *++typeTag != '\0' );
+            typeTagsEnd_ = typeTag;
+        }
+    }
+}
+
+//------------------------------------------------------------------------------
+
+ReceivedBundle::ReceivedBundle( const ReceivedPacket& packet )
+    : elementCount_( 0 )
+{
+    Init( packet.Contents(), packet.Size() );
+}
+
+
+ReceivedBundle::ReceivedBundle( const ReceivedBundleElement& bundleElement )
+    : elementCount_( 0 )
+{
+    Init( bundleElement.Contents(), bundleElement.Size() );
+}
+
+
+void ReceivedBundle::Init( const char *bundle, unsigned long size )
+{
+    if( size < 16 )
+        throw MalformedBundleException( "packet too short for bundle" );
+
+    if( (size & 0x03L) != 0 )
+        throw MalformedBundleException( "bundle size must be multiple of four" );
+
+    if( bundle[0] != '#'
+        || bundle[1] != 'b'
+        || bundle[2] != 'u'
+        || bundle[3] != 'n'
+        || bundle[4] != 'd'
+        || bundle[5] != 'l'
+        || bundle[6] != 'e'
+        || bundle[7] != '\0' )
+            throw MalformedBundleException( "bad bundle address pattern" );    
+
+    end_ = bundle + size;
+
+    timeTag_ = bundle + 8;
+
+    const char *p = timeTag_ + 8;
+        
+    while( p < end_ ){
+        if( p + 4 > end_ )
+            throw MalformedBundleException( "packet too short for elementSize" );
+
+        uint32 elementSize = ToUInt32( p );
+        if( (elementSize & 0x03L) != 0 )
+            throw MalformedBundleException( "bundle element size must be multiple of four" );
+
+        p += 4 + elementSize;
+        if( p > end_ )
+            throw MalformedBundleException( "packet too short for bundle element" );
+
+        ++elementCount_;
+    }
+
+    if( p != end_ )
+        throw MalformedBundleException( "bundle contents " );
+}
+
+
+uint64 ReceivedBundle::TimeTag() const
+{
+    return ToUInt64( timeTag_ );
+}
+
+
+} // namespace osc
+
diff --git a/src/osc/osc/OscReceivedElements.h b/src/osc/osc/OscReceivedElements.h
new file mode 100755
index 0000000..f438757
--- /dev/null
+++ b/src/osc/osc/OscReceivedElements.h
@@ -0,0 +1,486 @@
+/*
+	oscpack -- Open Sound Control packet manipulation library
+	http://www.audiomulch.com/~rossb/oscpack
+
+	Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>
+
+	Permission is hereby granted, free of charge, to any person obtaining
+	a copy of this software and associated documentation files
+	(the "Software"), to deal in the Software without restriction,
+	including without limitation the rights to use, copy, modify, merge,
+	publish, distribute, sublicense, and/or sell copies of the Software,
+	and to permit persons to whom the Software is furnished to do so,
+	subject to the following conditions:
+
+	The above copyright notice and this permission notice shall be
+	included in all copies or substantial portions of the Software.
+
+	Any person wishing to distribute modifications to the Software is
+	requested to send the modifications to the original developer so that
+	they can be incorporated into the canonical version.
+
+	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+	EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+	MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+	IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+	ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+	CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+	WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+#ifndef INCLUDED_OSCRECEIVEDELEMENTS_H
+#define INCLUDED_OSCRECEIVEDELEMENTS_H
+
+#include "OscTypes.h"
+#include "OscException.h"
+
+
+namespace osc{
+
+
+class MalformedMessageException : public Exception{
+public:
+    MalformedMessageException( const char *w="malformed message" )
+        : Exception( w ) {}
+};
+
+class MalformedBundleException : public Exception{
+public:
+    MalformedBundleException( const char *w="malformed bundle" )
+        : Exception( w ) {}
+};
+
+class WrongArgumentTypeException : public Exception{
+public:
+    WrongArgumentTypeException( const char *w="wrong argument type" )
+        : Exception( w ) {}
+};
+
+class MissingArgumentException : public Exception{
+public:
+    MissingArgumentException( const char *w="missing argument" )
+        : Exception( w ) {}
+};
+
+class ExcessArgumentException : public Exception{
+public:
+    ExcessArgumentException( const char *w="too many arguments" )
+        : Exception( w ) {}
+};
+
+
+class ReceivedPacket{
+public:
+    ReceivedPacket( const char *contents, int32 size )
+        : contents_( contents )
+        , size_( size ) {}
+
+    bool IsMessage() const { return !IsBundle(); }
+    bool IsBundle() const;
+
+    int32 Size() const { return size_; }
+    const char *Contents() const { return contents_; }
+
+private:
+    const char *contents_;
+    int32 size_;
+};
+
+
+class ReceivedBundleElement{
+public:
+    ReceivedBundleElement( const char *size )
+        : size_( size ) {}
+
+    friend class ReceivedBundleElementIterator;
+
+    bool IsMessage() const { return !IsBundle(); }
+    bool IsBundle() const;
+
+    int32 Size() const;
+    const char *Contents() const { return size_ + 4; }
+
+private:
+    const char *size_;
+};
+
+
+class ReceivedBundleElementIterator{
+public:
+	ReceivedBundleElementIterator( const char *sizePtr )
+        : value_( sizePtr ) {}
+
+	ReceivedBundleElementIterator operator++()
+	{
+        Advance();
+        return *this;
+	}
+
+    ReceivedBundleElementIterator operator++(int)
+    {
+        ReceivedBundleElementIterator old( *this );
+        Advance();
+        return old;
+    }
+
+	const ReceivedBundleElement& operator*() const { return value_; }
+
+    const ReceivedBundleElement* operator->() const { return &value_; }
+
+	friend bool operator==(const ReceivedBundleElementIterator& lhs,
+            const ReceivedBundleElementIterator& rhs );
+
+private:
+	ReceivedBundleElement value_;
+
+	void Advance() { value_.size_ = value_.Contents() + value_.Size(); }
+
+    bool IsEqualTo( const ReceivedBundleElementIterator& rhs ) const
+    {
+        return value_.size_ == rhs.value_.size_;
+    }
+};
+
+inline bool operator==(const ReceivedBundleElementIterator& lhs,
+        const ReceivedBundleElementIterator& rhs )
+{	
+	return lhs.IsEqualTo( rhs );
+}
+
+inline bool operator!=(const ReceivedBundleElementIterator& lhs,
+        const ReceivedBundleElementIterator& rhs )
+{
+	return !( lhs == rhs );
+}
+
+
+class ReceivedMessageArgument{
+public:
+	ReceivedMessageArgument( const char *typeTag, const char *argument )
+		: typeTag_( typeTag )
+		, argument_( argument ) {}
+
+    friend class ReceivedMessageArgumentIterator;
+    
+	const char TypeTag() const { return *typeTag_; }
+
+    // the unchecked methods below don't check whether the argument actually
+    // is of the specified type. they should only be used if you've already
+    // checked the type tag or the associated IsType() method.
+
+    bool IsBool() const
+        { return *typeTag_ == TRUE_TYPE_TAG || *typeTag_ == FALSE_TYPE_TAG; }
+    bool AsBool() const;
+    bool AsBoolUnchecked() const;
+
+    bool IsNil() const { return *typeTag_ == NIL_TYPE_TAG; }
+    bool IsInfinitum() const { return *typeTag_ == INFINITUM_TYPE_TAG; }
+
+    bool IsInt32() const { return *typeTag_ == INT32_TYPE_TAG; }
+    int32 AsInt32() const;
+    int32 AsInt32Unchecked() const;
+
+    bool IsFloat() const { return *typeTag_ == FLOAT_TYPE_TAG; }
+    float AsFloat() const;
+    float AsFloatUnchecked() const;
+
+    bool IsChar() const { return *typeTag_ == CHAR_TYPE_TAG; }
+    char AsChar() const;
+    char AsCharUnchecked() const;
+
+    bool IsRgbaColor() const { return *typeTag_ == RGBA_COLOR_TYPE_TAG; }
+    uint32 AsRgbaColor() const;
+    uint32 AsRgbaColorUnchecked() const;
+
+    bool IsMidiMessage() const { return *typeTag_ == MIDI_MESSAGE_TYPE_TAG; }
+    uint32 AsMidiMessage() const;
+    uint32 AsMidiMessageUnchecked() const;
+
+    bool IsInt64() const { return *typeTag_ == INT64_TYPE_TAG; }
+    int64 AsInt64() const;
+    int64 AsInt64Unchecked() const;
+
+    bool IsTimeTag() const { return *typeTag_ == TIME_TAG_TYPE_TAG; }
+    uint64 AsTimeTag() const;
+    uint64 AsTimeTagUnchecked() const;
+
+    bool IsDouble() const { return *typeTag_ == DOUBLE_TYPE_TAG; }
+    double AsDouble() const;
+    double AsDoubleUnchecked() const;
+
+    bool IsString() const { return *typeTag_ == STRING_TYPE_TAG; }
+    const char* AsString() const;
+    const char* AsStringUnchecked() const { return argument_; }
+
+    bool IsSymbol() const { return *typeTag_ == SYMBOL_TYPE_TAG; }
+    const char* AsSymbol() const;
+    const char* AsSymbolUnchecked() const { return argument_; }
+
+    bool IsBlob() const { return *typeTag_ == BLOB_TYPE_TAG; }
+    void AsBlob( const void*& data, unsigned long& size ) const;
+    void AsBlobUnchecked( const void*& data, unsigned long& size ) const;
+    
+private:
+	const char *typeTag_;
+	const char *argument_;
+};
+
+
+class ReceivedMessageArgumentIterator{
+public:
+	ReceivedMessageArgumentIterator( const char *typeTags, const char *arguments )
+        : value_( typeTags, arguments ) {}
+
+	ReceivedMessageArgumentIterator operator++()
+	{
+        Advance();
+        return *this;
+	}
+
+    ReceivedMessageArgumentIterator operator++(int)
+    {
+        ReceivedMessageArgumentIterator old( *this );
+        Advance();
+        return old;
+    }
+
+	const ReceivedMessageArgument& operator*() const { return value_; }
+
+    const ReceivedMessageArgument* operator->() const { return &value_; }
+
+	friend bool operator==(const ReceivedMessageArgumentIterator& lhs,
+            const ReceivedMessageArgumentIterator& rhs );
+
+private:
+	ReceivedMessageArgument value_;
+
+	void Advance();
+
+    bool IsEqualTo( const ReceivedMessageArgumentIterator& rhs ) const
+    {
+        return value_.typeTag_ == rhs.value_.typeTag_;
+    }
+};
+
+inline bool operator==(const ReceivedMessageArgumentIterator& lhs,
+        const ReceivedMessageArgumentIterator& rhs )
+{	
+	return lhs.IsEqualTo( rhs );
+}
+
+inline bool operator!=(const ReceivedMessageArgumentIterator& lhs,
+        const ReceivedMessageArgumentIterator& rhs )
+{	
+	return !( lhs == rhs );
+}
+
+
+class ReceivedMessageArgumentStream{
+    friend class ReceivedMessage;
+    ReceivedMessageArgumentStream( const ReceivedMessageArgumentIterator& begin,
+            const ReceivedMessageArgumentIterator& end )
+        : p_( begin )
+        , end_( end ) {}
+
+    ReceivedMessageArgumentIterator p_, end_;
+    
+public:
+
+    // end of stream
+    bool Eos() const { return p_ == end_; }
+
+    ReceivedMessageArgumentStream& operator>>( bool& rhs )
+    {
+        if( Eos() )
+            throw MissingArgumentException();
+
+        rhs = (*p_++).AsBool();
+        return *this;
+    }
+
+    // not sure if it would be useful to stream Nil and Infinitum
+    // for now it's not possible
+
+    ReceivedMessageArgumentStream& operator>>( int32& rhs )
+    {
+        if( Eos() )
+            throw MissingArgumentException();
+
+        rhs = (*p_++).AsInt32();
+        return *this;
+    }     
+
+    ReceivedMessageArgumentStream& operator>>( float& rhs )
+    {
+        if( Eos() )
+            throw MissingArgumentException();
+
+        rhs = (*p_++).AsFloat();
+        return *this;
+    }
+
+    ReceivedMessageArgumentStream& operator>>( char& rhs )
+    {
+        if( Eos() )
+            throw MissingArgumentException();
+
+        rhs = (*p_++).AsChar();
+        return *this;
+    }
+
+    ReceivedMessageArgumentStream& operator>>( RgbaColor& rhs )
+    {
+        if( Eos() )
+            throw MissingArgumentException();
+
+        rhs.value = (*p_++).AsRgbaColor();
+        return *this;
+    }
+
+    ReceivedMessageArgumentStream& operator>>( MidiMessage& rhs )
+    {
+        if( Eos() )
+            throw MissingArgumentException();
+
+        rhs.value = (*p_++).AsMidiMessage();
+        return *this;
+    }
+
+    ReceivedMessageArgumentStream& operator>>( int64& rhs )
+    {
+        if( Eos() )
+            throw MissingArgumentException();
+
+        rhs = (*p_++).AsInt64();
+        return *this;
+    }
+    
+    ReceivedMessageArgumentStream& operator>>( TimeTag& rhs )
+    {
+        if( Eos() )
+            throw MissingArgumentException();
+
+        rhs.value = (*p_++).AsTimeTag();
+        return *this;
+    }
+
+    ReceivedMessageArgumentStream& operator>>( double& rhs )
+    {
+        if( Eos() )
+            throw MissingArgumentException();
+
+        rhs = (*p_++).AsDouble();
+        return *this;
+    }
+
+    ReceivedMessageArgumentStream& operator>>( Blob& rhs )
+    {
+        if( Eos() )
+            throw MissingArgumentException();
+
+        (*p_++).AsBlob( rhs.data, rhs.size );
+        return *this;
+    }
+    
+    ReceivedMessageArgumentStream& operator>>( const char*& rhs )
+    {
+        if( Eos() )
+            throw MissingArgumentException();
+
+        rhs = (*p_++).AsString();
+        return *this;
+    }
+    
+    ReceivedMessageArgumentStream& operator>>( Symbol& rhs )
+    {
+        if( Eos() )
+            throw MissingArgumentException();
+
+        rhs.value = (*p_++).AsSymbol();
+        return *this;
+    }
+
+    ReceivedMessageArgumentStream& operator>>( MessageTerminator& rhs )
+    {
+        if( !Eos() )
+            throw ExcessArgumentException();
+
+        return *this;
+    }
+};
+
+
+class ReceivedMessage{
+    void Init( const char *bundle, unsigned long size );
+public:
+    explicit ReceivedMessage( const ReceivedPacket& packet );
+    explicit ReceivedMessage( const ReceivedBundleElement& bundleElement );
+
+	const char *AddressPattern() const { return addressPattern_; }
+
+	// Support for non-standad SuperCollider integer address patterns:
+	bool AddressPatternIsUInt32() const;
+	uint32 AddressPatternAsUInt32() const;
+
+	unsigned long ArgumentCount() const { return static_cast<unsigned long>(typeTagsEnd_ - typeTagsBegin_); }
+
+    const char *TypeTags() const { return typeTagsBegin_; }
+
+
+    typedef ReceivedMessageArgumentIterator const_iterator;
+    
+	ReceivedMessageArgumentIterator ArgumentsBegin() const
+    {
+        return ReceivedMessageArgumentIterator( typeTagsBegin_, arguments_ );
+    }
+     
+	ReceivedMessageArgumentIterator ArgumentsEnd() const
+    {
+        return ReceivedMessageArgumentIterator( typeTagsEnd_, 0 );
+    }
+
+    ReceivedMessageArgumentStream ArgumentStream() const
+    {
+        return ReceivedMessageArgumentStream( ArgumentsBegin(), ArgumentsEnd() );
+    }
+
+private:
+	const char *addressPattern_;
+	const char *typeTagsBegin_;
+	const char *typeTagsEnd_;
+    const char *arguments_;
+};
+
+
+class ReceivedBundle{
+    void Init( const char *message, unsigned long size );
+public:
+    explicit ReceivedBundle( const ReceivedPacket& packet );
+    explicit ReceivedBundle( const ReceivedBundleElement& bundleElement );
+
+    uint64 TimeTag() const;
+
+    unsigned long ElementCount() const { return elementCount_; }
+
+    typedef ReceivedBundleElementIterator const_iterator;
+    
+	ReceivedBundleElementIterator ElementsBegin() const
+    {
+        return ReceivedBundleElementIterator( timeTag_ + 8 );
+    }
+     
+	ReceivedBundleElementIterator ElementsEnd() const
+    {
+        return ReceivedBundleElementIterator( end_ );
+    }
+
+private:
+    const char *timeTag_;
+    const char *end_;
+    unsigned long elementCount_;
+};
+
+
+} // namespace osc
+
+
+#endif /* INCLUDED_OSCRECEIVEDELEMENTS_H */
diff --git a/src/osc/osc/OscTypes.cpp b/src/osc/osc/OscTypes.cpp
new file mode 100755
index 0000000..889ab43
--- /dev/null
+++ b/src/osc/osc/OscTypes.cpp
@@ -0,0 +1,40 @@
+/*
+	oscpack -- Open Sound Control packet manipulation library
+	http://www.audiomulch.com/~rossb/oscpack
+
+	Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>
+
+	Permission is hereby granted, free of charge, to any person obtaining
+	a copy of this software and associated documentation files
+	(the "Software"), to deal in the Software without restriction,
+	including without limitation the rights to use, copy, modify, merge,
+	publish, distribute, sublicense, and/or sell copies of the Software,
+	and to permit persons to whom the Software is furnished to do so,
+	subject to the following conditions:
+
+	The above copyright notice and this permission notice shall be
+	included in all copies or substantial portions of the Software.
+
+	Any person wishing to distribute modifications to the Software is
+	requested to send the modifications to the original developer so that
+	they can be incorporated into the canonical version.
+
+	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+	EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+	MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+	IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+	ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+	CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+	WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+#include "OscTypes.h"
+
+namespace osc{
+
+BundleInitiator BeginBundleImmediate(1);
+BundleTerminator EndBundle;
+MessageTerminator EndMessage;
+NilType Nil;
+InfinitumType Infinitum;
+
+} // namespace osc
diff --git a/src/osc/osc/OscTypes.h b/src/osc/osc/OscTypes.h
new file mode 100755
index 0000000..81549b5
--- /dev/null
+++ b/src/osc/osc/OscTypes.h
@@ -0,0 +1,178 @@
+/*
+	oscpack -- Open Sound Control packet manipulation library
+	http://www.audiomulch.com/~rossb/oscpack
+
+	Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>
+
+	Permission is hereby granted, free of charge, to any person obtaining
+	a copy of this software and associated documentation files
+	(the "Software"), to deal in the Software without restriction,
+	including without limitation the rights to use, copy, modify, merge,
+	publish, distribute, sublicense, and/or sell copies of the Software,
+	and to permit persons to whom the Software is furnished to do so,
+	subject to the following conditions:
+
+	The above copyright notice and this permission notice shall be
+	included in all copies or substantial portions of the Software.
+
+	Any person wishing to distribute modifications to the Software is
+	requested to send the modifications to the original developer so that
+	they can be incorporated into the canonical version.
+
+	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+	EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+	MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+	IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+	ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+	CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+	WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+#ifndef INCLUDED_OSCTYPES_H
+#define INCLUDED_OSCTYPES_H
+
+
+namespace osc{
+
+// basic types
+
+#if defined(__BORLANDC__) || defined(_MSC_VER)
+
+typedef __int64 int64;
+typedef unsigned __int64 uint64;
+
+#else
+
+typedef long long int64;
+typedef unsigned long long uint64;
+
+#endif
+
+
+
+#ifdef x86_64
+
+typedef signed int int32;
+typedef unsigned int uint32;
+
+#else
+
+typedef signed long int32;
+typedef unsigned long uint32;
+
+#endif
+
+
+
+enum TypeTagValues {
+    TRUE_TYPE_TAG = 'T',
+    FALSE_TYPE_TAG = 'F',
+    NIL_TYPE_TAG = 'N',
+    INFINITUM_TYPE_TAG = 'I',
+    INT32_TYPE_TAG = 'i',
+    FLOAT_TYPE_TAG = 'f',
+    CHAR_TYPE_TAG = 'c',
+    RGBA_COLOR_TYPE_TAG = 'r',
+    MIDI_MESSAGE_TYPE_TAG = 'm',
+    INT64_TYPE_TAG = 'h',
+    TIME_TAG_TYPE_TAG = 't',
+    DOUBLE_TYPE_TAG = 'd',
+    STRING_TYPE_TAG = 's',
+    SYMBOL_TYPE_TAG = 'S',
+    BLOB_TYPE_TAG = 'b'
+};
+
+
+
+// i/o manipulators used for streaming interfaces
+
+struct BundleInitiator{
+    explicit BundleInitiator( uint64 timeTag_ ) : timeTag( timeTag_ ) {}
+    uint64 timeTag;
+};
+
+extern BundleInitiator BeginBundleImmediate;
+
+inline BundleInitiator BeginBundle( uint64 timeTag=1 )
+{
+    return BundleInitiator(timeTag);
+}
+
+
+struct BundleTerminator{
+};
+
+extern BundleTerminator EndBundle;
+
+struct BeginMessage{
+    explicit BeginMessage( const char *addressPattern_ ) : addressPattern( addressPattern_ ) {}
+    const char *addressPattern;
+};
+
+struct MessageTerminator{
+};
+
+extern MessageTerminator EndMessage;
+
+
+// osc specific types. they are defined as structs so they can be used
+// as separately identifiable types with the streaming operators.
+
+struct NilType{
+};
+
+extern NilType Nil;
+
+
+struct InfinitumType{
+};
+
+extern InfinitumType Infinitum;
+
+struct RgbaColor{
+    RgbaColor() {}
+    explicit RgbaColor( uint32 value_ ) : value( value_ ) {}
+    uint32 value;
+
+    operator uint32() const { return value; }
+};
+
+
+struct MidiMessage{
+    MidiMessage() {}
+    explicit MidiMessage( uint32 value_ ) : value( value_ ) {}
+    uint32 value;
+
+    operator uint32() const { return value; }
+};
+
+
+struct TimeTag{
+    TimeTag() {}
+    explicit TimeTag( uint64 value_ ) : value( value_ ) {}
+    uint64 value;
+
+    operator uint64() const { return value; }
+};
+
+
+struct Symbol{
+    Symbol() {}
+    explicit Symbol( const char* value_ ) : value( value_ ) {}
+    const char* value;
+
+    operator const char *() const { return value; }
+};
+
+
+struct Blob{
+    Blob() {}
+    explicit Blob( const void* data_, unsigned long size_ )
+            : data( data_ ), size( size_ ) {}
+    const void* data;
+    unsigned long size;
+};
+
+} // namespace osc
+
+
+#endif /* INCLUDED_OSCTYPES_H */
diff --git a/src/win/WinWindow.cpp b/src/win/WinWindow.cpp
new file mode 100644
index 0000000..5620406
--- /dev/null
+++ b/src/win/WinWindow.cpp
@@ -0,0 +1,122 @@
+/***************************************************************************
+ *  MacWindow.cpp
+ *  Part of 
+ *  2016-  Florent Berthaut
+ *  hitmuri.net
+ ****************************************************************************/
+/*
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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 General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "MacWindow.hpp"
+#include <iostream>
+
+using namespace std;
+
+MacWindow::MacWindow(OvWindowsManager* man, CGWindowID id): OvWindow(man) { 
+    CGRect rect = CGRectMake(0, 0, 100, 100);
+    m_idCArray[0] = id;
+    m_idArray = CFArrayCreate(NULL, (const void **) m_idCArray, 1, NULL);
+    CFArrayRef descArray = CGWindowListCreateDescriptionFromArray(m_idArray);
+    if(CFArrayGetCount(descArray)>0) {
+        CFDictionaryRef description = 
+            (CFDictionaryRef) CFArrayGetValueAtIndex(descArray, 0);
+        if (CFDictionaryContainsKey(description, kCGWindowBounds)) {
+            CFDictionaryRef bounds = 
+                    (CFDictionaryRef) CFDictionaryGetValue(description, 
+                                                           kCGWindowBounds);
+            if (bounds) {
+                CGRectMakeWithDictionaryRepresentation(bounds, &rect);
+            }
+        }
+    }
+    CFRelease(descArray);
+
+    m_posX = rect.origin.x; 
+    m_posY = rect.origin.y; 
+    m_width = rect.size.width;
+    m_height = rect.size.height;
+    m_offsetX = m_posX;
+    m_offsetY = m_posY;
+    m_pixPerRow = m_width;
+    m_isBGR=true;
+    m_needsOffset=false;
+    m_pixPerRow=m_width;
+}
+
+MacWindow::~MacWindow() {
+    CFRelease(m_idArray);
+}
+
+int MacWindow::computeNbPixPerRow(const int& srcW, const int& srcH) {
+    CGRect rect = CGRectMake(m_posX, m_posY, srcW, srcH);
+    CGImageRef img = CGWindowListCreateImageFromArray(rect,
+                                             m_idArray,
+                                             kCGWindowImageBoundsIgnoreFraming);
+    int nb = CGImageGetBytesPerRow(img)/4;
+    CFRelease(img);
+    return nb;
+}
+
+void MacWindow::getPixels(const int& srcX, const int& srcY, 
+                          const int& srcW, const int& srcH, 
+                          const vector<int>& srcIndices,
+                          const vector<vector<int> >& srcCoords,
+                          const vector<int>& destIndices,
+                          const uchar& alpha,
+                          const ZoneWidget::ZONE_COLOR& color,
+                          uchar* destImg) {
+    CGRect rect = CGRectMake(m_posX+srcX, m_posY+srcY, srcW, srcH);
+    CGImageRef img = CGWindowListCreateImageFromArray(rect,
+                                             m_idArray,
+                                             kCGWindowImageBoundsIgnoreFraming);
+    if(img!=NULL) {
+        CFDataRef data = CGDataProviderCopyData(CGImageGetDataProvider(img));
+        uchar* buf = (uchar*)CFDataGetBytePtr(data);
+        vector<int>::const_iterator itId = srcIndices.begin();
+        vector<vector<int> >::const_iterator itCo = srcCoords.begin();
+        vector<int>::const_iterator itDe = destIndices.begin();
+        for(; itCo!=srcCoords.end(); ++itCo) {
+            if((*itCo)[0]>=0) { 
+                //copy rgb
+                for(int c=0; c<3; ++c) {
+                    destImg[(*itDe)] = (color==ZoneWidget::NORMAL)
+                                            ?buf[(*itId)]
+                                            :255-buf[(*itId)];
+                    ++itId;
+                    ++itDe;
+                }
+                //copy alpha
+                destImg[(*itDe)] = alpha;
+                ++itId;
+                ++itDe;
+            }
+            else { //black
+                for(int c=0; c<4; ++c) {
+                    destImg[(*itDe)] = 0;
+                    ++itId;
+                    ++itDe;
+                }
+            }
+        }
+        //release CG stuff
+        CFRelease(data);
+        CFRelease(img);
+    }
+    else {
+        cout<<"Error getting image of window "<<m_name<<endl;
+    }
+}
+
diff --git a/src/win/WinWindow.hpp b/src/win/WinWindow.hpp
new file mode 100644
index 0000000..2c2cfb0
--- /dev/null
+++ b/src/win/WinWindow.hpp
@@ -0,0 +1,53 @@
+/***************************************************************************
+ *  MacWindow.hpp
+ *  Part of 
+ *  2016-  Florent Berthaut
+ *  hitmuri.net
+ ****************************************************************************/
+/*
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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 General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#ifndef MacWindow_h
+#define MacWindow_h
+
+#include <vector>
+#include <string>
+
+#include "../OvWindow.hpp"
+#import <ApplicationServices/ApplicationServices.h>
+
+class MacWindow: public OvWindow {
+    public :
+        MacWindow(OvWindowsManager* man, CGWindowID winID);
+        virtual ~MacWindow();
+        virtual void getPixels(const int& x, const int& y, 
+                               const int& sx, const int& sy,
+                               const std::vector<int>& srcIndices,
+                               const std::vector<std::vector<int> >& srcCoords,
+                               const std::vector<int>& destIndices,
+                               const uchar& alpha,
+                               const ZoneWidget::ZONE_COLOR& color,
+                               uchar* destImg);
+        int computeNbPixPerRow(const int& srcW, const int& srcH);
+
+    protected:
+        CGWindowID m_idCArray[1];
+        CFArrayRef m_idArray;
+};
+
+#endif
+
diff --git a/src/win/WinWindowsManager.cpp b/src/win/WinWindowsManager.cpp
new file mode 100644
index 0000000..5a4e6a6
--- /dev/null
+++ b/src/win/WinWindowsManager.cpp
@@ -0,0 +1,75 @@
+/***************************************************************************
+ *  MacWindowsManager.cpp
+ *  Part of 
+ *  2016-  Florent Berthaut
+ *  hitmuri.net
+ ****************************************************************************/
+/*
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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 General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/*
+    Relies on code from:
+    https://github.com/JoelSjogren/window-copy/blob/master/windowutils.cpp
+*/
+
+#include "MacWindowsManager.hpp"
+#include <iostream>
+#include <stdlib.h>
+
+using namespace std;
+
+MacWindowsManager::MacWindowsManager(): OvWindowsManager() {
+
+}
+
+MacWindowsManager::~MacWindowsManager() {
+
+}
+
+void MacWindowsManager::updateWindowsList() {
+    m_windowList.clear();
+    CFArrayRef windowArray = 
+      CGWindowListCreate(kCGWindowListExcludeDesktopElements
+                         |kCGWindowListOptionOnScreenOnly, kCGNullWindowID);
+    CFArrayRef descArray = CGWindowListCreateDescriptionFromArray(windowArray);
+    if(descArray!=NULL) {
+        for(int i=0; i<CFArrayGetCount(descArray); ++i) {
+            CFDictionaryRef win = 
+                (CFDictionaryRef)CFArrayGetValueAtIndex(descArray,i);
+            CFStringRef name = 
+                (CFStringRef) CFDictionaryGetValue(win, kCGWindowName);
+            if(name!=NULL) {
+                if(CFStringGetLength(name)>0) {
+                    char tempStr[128];
+                    CFStringGetCString(name,tempStr,128,kCFStringEncodingUTF8);
+                    string nameStr(tempStr);
+                    MacWindow* newWin = 
+                        new MacWindow(this, 
+                           (CGWindowID)(uintptr_t)
+                                CFArrayGetValueAtIndex(windowArray,i));
+                    newWin->setName(nameStr);
+                    m_windowList.push_back(newWin);
+                }
+            }
+            CFRelease(win);
+        }
+    }
+    else {
+        cout<<"Error: No windows found"<<endl;
+    }
+}
+
+
diff --git a/src/win/WinWindowsManager.hpp b/src/win/WinWindowsManager.hpp
new file mode 100644
index 0000000..fd5de79
--- /dev/null
+++ b/src/win/WinWindowsManager.hpp
@@ -0,0 +1,42 @@
+/***************************************************************************
+ *  MacWindowsManager.hpp
+ *  Part of Over 
+ *  2013  Florent Berthaut
+ *  hitmuri.net
+ ****************************************************************************/
+/*
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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 General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#ifndef MacWindowsManager_h
+#define MacWindowsManager_h
+
+#include <vector>
+#include <string>
+
+#include "../OvWindowsManager.hpp"
+#include "MacWindow.hpp"
+
+class MacWindowsManager : public OvWindowsManager {
+    public :
+        MacWindowsManager();
+        virtual ~MacWindowsManager();
+        virtual void updateWindowsList();
+    protected:
+};
+
+#endif
+
diff --git a/src/x11/XWindow.cpp b/src/x11/XWindow.cpp
new file mode 100644
index 0000000..d1eb557
--- /dev/null
+++ b/src/x11/XWindow.cpp
@@ -0,0 +1,154 @@
+/***************************************************************************
+ *  XWindow.cpp
+ *  Part of 
+ *  2016-  Florent Berthaut
+ *  hitmuri.net
+ ****************************************************************************/
+/*
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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 General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "XWindow.hpp"
+#include <iostream>
+
+using namespace std;
+
+XWindow::XWindow(CutWindowsManager* man, 
+                 Display* disp, 
+                 const Window& win): CutWindow(man), 
+                                     m_disp(disp), 
+                                     m_win(win) { 
+    Window root;
+    unsigned int bw, d, w, h;
+    XGetGeometry(m_disp, m_win, &root, &m_posX, &m_posY, 
+                 &w, &h, &bw, &d);
+    m_width=w;
+    m_height=h;
+    m_offsetX=0;
+    m_offsetY=0;
+    m_pixPerRow=m_width;
+    m_isBGR=false;
+    m_needsOffset=true;
+    m_grabbed=false;
+    m_defaultImgData = new uchar[m_width*m_height*3];
+}
+
+int XWindow::computeNbPixPerRow(const int& srcW, const int& srcH) {
+    XWindowAttributes attrs;
+    XGetWindowAttributes(m_disp, m_win, &attrs);
+    m_width=attrs.width;
+    m_height=attrs.height;
+    m_pixPerRow=m_width;
+    return m_width;
+}
+
+void XWindow::getPixels(const int& srcX, const int& srcY, 
+                        const int& srcW, const int& srcH, 
+                        const vector<int>& srcIndices,
+                        const vector<vector<int> >& srcCoords,
+                        const vector<int>& destIndices,
+                        const uchar& alpha,
+                        const ZoneWidget::ZONE_COLOR& color,
+                        uchar* destImg) {
+    XImage* ximg = XGetImage(m_disp, m_win, 
+                             srcX, srcY, 
+                             srcW, srcH, 
+                             AllPlanes, XYPixmap);
+    if(ximg!=NULL) {
+        unsigned long red_mask = ximg->red_mask;
+        unsigned long green_mask = ximg->green_mask;
+        unsigned long blue_mask = ximg->blue_mask;
+
+        vector<int>::const_iterator itId = srcIndices.begin();
+        vector<vector<int> >::const_iterator itCo = srcCoords.begin();
+        vector<int>::const_iterator itDe = destIndices.begin();
+        for(; itCo!=srcCoords.end(); ++itCo) {
+            if((*itCo)[0]>=0) {//get and copy pixel
+                unsigned long pixel = XGetPixel(ximg, (*itCo)[0], (*itCo)[1]);
+                destImg[(*itDe)] = (color==ZoneWidget::NORMAL) 
+                                        ?(pixel & red_mask) >> 16
+                                        :255-((pixel & red_mask) >> 16);
+                ++itDe;
+                destImg[(*itDe)] = (color==ZoneWidget::NORMAL) 
+                                        ?(pixel & green_mask) >> 8
+                                        :255-((pixel & green_mask) >> 8);
+                ++itDe;
+                destImg[(*itDe)] = (color==ZoneWidget::NORMAL) 
+                                        ?(pixel & blue_mask)
+                                        :255-(pixel & blue_mask);
+                ++itDe;
+                destImg[(*itDe)] = alpha;
+                ++itDe;
+            }
+            else { //black
+                destImg[(*itDe)] = 0;
+                ++itDe;
+                destImg[(*itDe)] = 0;
+                ++itDe;
+                destImg[(*itDe)] = 0;
+                ++itDe;
+                destImg[(*itDe)] = 0;
+                ++itDe;
+            }
+        }
+        XDestroyImage(ximg);
+    }
+}
+
+void XWindow::releaseImage() {
+    if(m_grabbed) {
+        if(m_ximg) {
+            XDestroyImage(m_ximg);
+        }
+        m_grabbed=false;
+    }
+}
+
+uchar* XWindow::grabImage() {
+    if(!m_grabbed) {
+        m_ximg = XGetImage(m_disp, m_win, 
+                           0, 0, 
+                           m_width, m_height, 
+                           AllPlanes, ZPixmap);
+        if(m_ximg) {
+            m_imgData=(uchar*)m_ximg->data;
+        }
+        else {
+            m_imgData=m_defaultImgData;
+        }
+        m_grabbed=true;
+    }
+    return m_imgData;
+}
+
+void XWindow::storeImage(const int& id) {
+    int size = m_pixPerRow*m_height*4;
+    if(m_storedImgData.find(id)!=m_storedImgData.end()) {
+        delete [] m_storedImgData[id];
+    }
+    m_storedImgData[id] = new uchar[size];
+    memcpy(m_storedImgData[id], m_imgData, size);
+}
+
+uchar* XWindow::retrieveImage(const int& id) {
+    map<int, uchar*>::iterator itSt = m_storedImgData.find(id);
+    if(itSt!=m_storedImgData.end()) {
+        return itSt->second;
+    }
+    return m_imgData;
+}
+
+
+    
diff --git a/src/x11/XWindow.hpp b/src/x11/XWindow.hpp
new file mode 100644
index 0000000..0d36a61
--- /dev/null
+++ b/src/x11/XWindow.hpp
@@ -0,0 +1,62 @@
+/***************************************************************************
+ *  CutWindow.hpp
+ *  Part of Over 
+ *  2013  Florent Berthaut
+ *  hitmuri.net
+ ****************************************************************************/
+/*
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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 General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#ifndef XWindow_h
+#define XWindow_h
+
+#include <vector>
+#include <string>
+
+#include "../CutWindow.hpp"
+
+#include <X11/Xlib.h>
+#include <X11/Xatom.h>
+#include <X11/Xutil.h>
+
+class XWindow: public CutWindow {
+    public :
+        XWindow(CutWindowsManager* man, Display* disp, const Window& win);
+        virtual ~XWindow(){}
+        virtual void getPixels(const int& x, const int& y, 
+                               const int& sx, const int& sy,
+                               const std::vector<int>& srcIndices,
+                               const std::vector<std::vector<int> >& srcCoords,
+                               const std::vector<int>& destIndices,
+                               const uchar& alpha,
+                               const ZoneWidget::ZONE_COLOR& color,
+                               uchar* destImg);
+        int computeNbPixPerRow(const int& srcW, const int& srcH);
+        virtual uchar* grabImage();
+        virtual void releaseImage();
+
+        virtual void storeImage(const int& id);
+        virtual uchar* retrieveImage(const int& id);
+
+    protected:
+        Display* m_disp;
+        Window m_win;
+        XImage* m_ximg;
+};
+
+#endif
+
diff --git a/src/x11/XWindowsManager.cpp b/src/x11/XWindowsManager.cpp
new file mode 100644
index 0000000..cab2c04
--- /dev/null
+++ b/src/x11/XWindowsManager.cpp
@@ -0,0 +1,93 @@
+/***************************************************************************
+ *  XWindowsManager.cpp
+ *  Part of 
+ *  2016-  Florent Berthaut
+ *  hitmuri.net
+ ****************************************************************************/
+/*
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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 General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "XWindowsManager.hpp"
+#include <iostream>
+#include <stdlib.h>
+
+using namespace std;
+
+XWindowsManager::XWindowsManager(): CutWindowsManager() {
+    m_disp = XOpenDisplay(NULL);
+    if (!m_disp) {
+        cout<<"No display found"<<endl;
+    }
+}
+
+XWindowsManager::~XWindowsManager() {
+    XCloseDisplay(m_disp);
+}
+
+void XWindowsManager::updateWindowsList() {
+    map<string, CutWindow*> prevWins;
+    vector<CutWindow*>::iterator itWin=m_windowList.begin();
+    for(; itWin!=m_windowList.end(); ++itWin) {
+        prevWins[(*itWin)->getName()]=(*itWin);
+    }
+    m_windowList.clear();
+    unsigned long len;
+    Window *list = getWinList(m_disp, &len);
+    for(int i=0;i<(int)len;i++) {
+        char* name = getWinName(m_disp, list[i]);
+        CutWindow* newWin=NULL;
+        if(prevWins.find(string(name))!=prevWins.end()) {
+            newWin = prevWins[string(name)];
+        }
+        else {
+            newWin = new XWindow(this, m_disp, list[i]);
+        }
+        newWin->setName(string(name));
+        m_windowList.push_back(newWin);
+        free(name);
+    }
+    XFree(list);
+}
+
+char* XWindowsManager::getWinName(Display* disp, Window win) {
+    Atom prop = XInternAtom(disp,"WM_NAME",False), type;
+    int form;
+    unsigned long remain, len;
+    unsigned char *list;
+
+    if (XGetWindowProperty(disp,win,prop,0,1024,False,XA_STRING,
+            &type,&form,&len,&remain,&list) != Success) {
+        cout<<"Error getting window name"<<endl;
+        return NULL;
+    }
+    return (char*)list;
+}
+
+Window* XWindowsManager::getWinList(Display* disp, unsigned long* len) {
+    Atom prop = XInternAtom(disp,"_NET_CLIENT_LIST",False), type;
+    int form;
+    unsigned long remain;
+    unsigned char *list;
+    if(XGetWindowProperty(disp,XDefaultRootWindow(disp), 
+                          prop,0,1024,False,XA_WINDOW,
+                          &type,&form,len,&remain,&list) != Success) {
+        cout<<"Error getting windows list"<<endl;
+        return 0;
+    }
+    return (Window*)list;
+}
+
+
diff --git a/src/x11/XWindowsManager.hpp b/src/x11/XWindowsManager.hpp
new file mode 100644
index 0000000..a5d99e8
--- /dev/null
+++ b/src/x11/XWindowsManager.hpp
@@ -0,0 +1,49 @@
+/***************************************************************************
+ *  XWindowsManager.hpp
+ *  Part of Over 
+ *  2013  Florent Berthaut
+ *  hitmuri.net
+ ****************************************************************************/
+/*
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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 General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#ifndef XWindowsManager_h
+#define XWindowsManager_h
+
+#include <vector>
+#include <string>
+#include <X11/Xlib.h>
+#include <X11/Xatom.h>
+
+#include "../CutWindowsManager.hpp"
+#include "XWindow.hpp"
+
+class XWindowsManager : public CutWindowsManager {
+    public :
+        XWindowsManager();
+        virtual ~XWindowsManager();
+        virtual void updateWindowsList();
+
+        Window* getWinList(Display* disp, unsigned long* len);
+        char* getWinName(Display* disp, Window);
+
+    protected:
+        Display* m_disp;
+};
+
+#endif
+
diff --git a/waf b/waf
new file mode 100755
index 0000000000000000000000000000000000000000..e1e34d431afba28d52add07a6094226a1a74374b
GIT binary patch
literal 87674
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
X|Is@W{X|qm`WE{za4Fl^+HwH^ejc=>

literal 0
HcmV?d00001

diff --git a/wscript b/wscript
new file mode 100755
index 0000000..698afce
--- /dev/null
+++ b/wscript
@@ -0,0 +1,93 @@
+#!/usr/bin/env python
+
+import sys, os 
+
+def options(opt):
+    opt.load('compiler_cxx')
+    opt.load('compiler_c')
+
+def configure(conf):
+    conf.load('compiler_cxx')
+    conf.load('compiler_c')
+    
+    #platform specific
+    if sys.platform == 'darwin': 
+        conf.env.INCLUDES_OS = ['/opt/local/include',
+                                '/opt/local/include/libxml2']
+        conf.env.LIBPATH_OS = ['/opt/local/lib']
+        conf.env.LIB_OS = ['m', 'xml2', 'fltk', 'fltk_gl', 'portmidi','GLEW']
+        conf.env.FRAMEWORK_OS = ['Cocoa','OpenGL', 'AGL', 'Carbon', 
+                                 'Accelerate', 'IOKit','System', 'AppKit',
+                                 'CoreFoundation']
+        conf.env.DEFINES_OS  = ['OSX=1']
+        conf.env.DEFINES_GL  = ['GL=1']
+    elif sys.platform == 'win32' or sys.platform == 'cygwin':
+        conf.env.INCLUDES_OS = ['os/win/include/', 'C:\MinGW\include']
+        conf.env.LIBPATH_OS = [os.path.join(os.getcwd(), 'os/win/lib/')]
+        conf.env.LIB_OS = ['m', 'ws2_32', 'xml2', 'GLU', 'GL',
+                           'fltk', 'fltk_gl','boost_system']
+        conf.env.DEFINES_OS  = ['WINDOWS=1']
+    else :
+        conf.env.INCLUDES_OS = ['/usr/include', '/usr/local/include',
+                                '/usr/include/libxml2']
+        conf.env.LIB_OS = ['X11', 'Xxf86vm', 'm','portmidi','porttime',
+                           'xml2', 'pthread','GL','GLEW',
+                           'fltk', 'fltk_gl', 'boost_system']
+        conf.env.LIBPATH_OS = ['/usr/local/lib/']
+        conf.env.DEFINES_OS  = ['LINUX=1']
+        conf.env.DEFINES_GL  = ['GL=1']
+   
+
+    #release specific
+    conf.env.CXXFLAGS = ['-O3', '-Wall'] 
+    conf.env.DEFINES  = ['DEBUG(x)=//x']
+
+    #debug specific
+    conf.setenv('debug', env=conf.env.derive())
+    conf.env.CXXFLAGS = ['-g', '-Wall']
+    conf.env.DEFINES  = ['DEBUG(x)=std::cout<< x <<std::endl;']
+
+def build(bld):
+    installPath = '/usr/local/bin'
+    macApp = False
+
+    if sys.platform == 'darwin': 
+        installPath = '/opt/bin/'
+        macApp = 'True'
+        osCode = 'src/mac/*.cpp'
+    elif sys.platform == 'win32' or sys.platform == 'cygwin':
+        osCode = 'src/win/*.cpp'
+    else :
+        osCode = 'src/x11/*.cpp'
+
+    bld.objects(
+          source  = bld.path.ant_glob('src/osc/ip/posix/*.cpp')
+                    +bld.path.ant_glob('src/osc/ip/*.cpp')
+                    +bld.path.ant_glob('src/osc/osc/*.cpp'),
+          use     = ['OS'],
+          target  = 'oscpack')
+
+    bld.objects(
+        source  = bld.path.ant_glob(osCode),
+        use     = ['OS','GL'],
+        target  = 'winsman')
+
+    bld.program(
+        source       = bld.path.ant_glob('src/*.cpp'),
+        use          = ['OS', 'GL', 'winsman', 'oscpack'],
+        target       = 'controllar'+bld.variant,
+        vnum         = '0.0.1',
+        install_path = installPath,
+        mac_app      = macApp,
+        mac_plist     = 'data/Info.plist',
+        mac_resources = 'data/controllar.icns',
+    )
+
+def install(bld):
+    bld.install('${PREFIX}/bin', 'controllar')
+
+from waflib.Build import BuildContext, CleanContext
+class debug(BuildContext): 
+    cmd = 'debug'
+    variant = 'debug' 
+
-- 
GitLab