aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexandre Quessy <alexandrequessy@users.sourceforge.net>2006-07-19 00:27:57 +0000
committerAlexandre Quessy <alexandrequessy@users.sourceforge.net>2006-07-19 00:27:57 +0000
commit3f0c36f57af40e853ece2c5889a05120129f649b (patch)
treec14c69616f82123aa5378cf3c7f4eb3e7a2ea340
This commit was generated by cvs2svn to compensate for changes in r5374,svn2git-root
which included commits to RCS files with non-trunk default branches. svn path=/trunk/externals/aalex/; revision=5375
-rw-r--r--LICENSE.txt340
-rw-r--r--README.txt53
-rw-r--r--makefile48
-rw-r--r--matches-help.pd26
-rw-r--r--matches.c193
-rw-r--r--pcre-help.pd38
-rw-r--r--pcre.c172
-rw-r--r--x11key-help.pd43
-rw-r--r--x11key.c162
-rw-r--r--x11mouse-help.pd76
-rw-r--r--x11mouse.c181
-rw-r--r--xmms-help.pd40
-rw-r--r--xmms.c148
13 files changed, 1520 insertions, 0 deletions
diff --git a/LICENSE.txt b/LICENSE.txt
new file mode 100644
index 0000000..67282dd
--- /dev/null
+++ b/LICENSE.txt
@@ -0,0 +1,340 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) 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
+this service 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 make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. 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.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute 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 and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+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
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the 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 a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, 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.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE 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.
+
+ 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
+convey 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 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision 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, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This 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.
diff --git a/README.txt b/README.txt
new file mode 100644
index 0000000..df8afc3
--- /dev/null
+++ b/README.txt
@@ -0,0 +1,53 @@
+ABOUT aalex's
+
+These are objects for Pure Data.
+
+[x11mouse] generates a X11 mouse event
+[x11key] generates a X11 keyboard event
+[xmms] controls the X Multimedia System
+[pcre] matches a symbol against a Perl compatible regular expression. Still needs symbol as a selector for arguments.
+
+
+I also include a few of my abstractions :
+
+
+=================================================
+INSTALL
+
+To use on Linux, add the path to this directory into your ~/.pdrc invisible file.
+Currenly, the only one to work on Mac is [matches]. All the others are for GNU/Linux.
+
+
+=================================================
+COMPILE
+
+To compile on Debian, execute the follwing command in a terminal.
+It could probably work on Mac too, instlaling the packages with Fink. Tell
+me if ever you need some of them for Mac, as the makefile will need to be modified.
+
+
+sudo apt-get install xlib-dev xmms-dev
+cd aalex
+make
+
+
+=================================================
+AUTHOR
+
+Alexandre Quessy
+alex@sourcelibre.com
+
+
+=================================================
+LICENSE
+
+GNU Public License
+)c( Copyleft 2006
+Enjoy at your own risks !
+
+
+=================================================
+HISTORY
+
+2006-07-18 Fixed *MD64 compilation flag (thanks to r1). Changed [matches] for [pcre].
+2006-07 Initial release of old externals plus x11 objects.
diff --git a/makefile b/makefile
new file mode 100644
index 0000000..3a8e66a
--- /dev/null
+++ b/makefile
@@ -0,0 +1,48 @@
+#
+# For Debian :
+# apt-get install xlib-dev xmms-dev
+#
+
+
+
+current: pd_linux
+ @echo make pd_linux, pd_darwin, clean ... you must be specific
+ @echo default to pd_linux
+
+
+clean: ; rm -f *.pd_linux *.o
+
+# ----------------------- LINUX i386 -----------------------
+
+pd_linux: pcre.pd_linux xmms.pd_linux x11mouse.pd_linux x11key.pd_linux
+
+.SUFFIXES: .pd_linux
+
+LINUXCFLAGS = -DPD -O2 -funroll-loops -fomit-frame-pointer \
+ -Wall -W -Wshadow -Wstrict-prototypes -Werror \
+ -Wno-unused -Wno-parentheses -Wno-switch -fPIC
+
+LINUXINCLUDE = -I../src -L/usr/lib/X11 -I/usr/include/X11 -L/usr/X11R6/lib
+LINUXLINKS = -lX11 -lXtst -lgtk -lgdk -lgmodule -lglib -ldl -lXi -lXext -lX11 -lm -lxmms
+
+.c.pd_linux:
+ cc $(LINUXCFLAGS) $(LINUXINCLUDE) -o $*.o -c $*.c \
+ `xmms-config --cflags`
+ ld -export_dynamic -shared -o $*.pd_linux $*.o -lpcre -lc -lm\
+ -L/usr/lib -L/usr/X11R6/lib $(LINUXLINKS)
+ strip --strip-unneeded $*.pd_linux
+ rm $*.o
+# ----------------------- Mac OSX -----------------------
+
+pd_darwin: matches.pd_darwin concat.pd_darwin
+
+.SUFFIXES: .pd_darwin
+
+DARWINCFLAGS = -DPD -O2 -Wall -W -Wshadow -Wstrict-prototypes \
+ -Wno-unused -Wno-parentheses -Wno-switch
+
+.c.pd_darwin:
+ cc $(DARWINCFLAGS) $(LINUXINCLUDE) -o $*.o -c $*.c -lpcre
+ cc -bundle -undefined suppress -flat_namespace -o $*.pd_darwin $*.o
+ rm -f $*.o
+
diff --git a/matches-help.pd b/matches-help.pd
new file mode 100644
index 0000000..1485071
--- /dev/null
+++ b/matches-help.pd
@@ -0,0 +1,26 @@
+#N canvas 0 0 786 271 10;
+#X obj 239 110 symbol;
+#X obj 205 202 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0
+1;
+#X obj 205 180 matches b9;
+#X obj 118 200 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0
+1;
+#X obj 118 179 matches #9;
+#X msg 199 36 F#9;
+#X msg 231 35 D7b9;
+#X text 395 60 Matches a symbol against a Perl-compatible regular expression.
+See man pcre.;
+#X text 399 30 matches;
+#X obj 293 205 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0
+1;
+#X obj 293 183 matches !9;
+#X msg 273 34 Am7;
+#X connect 0 0 2 0;
+#X connect 0 0 4 0;
+#X connect 0 0 10 0;
+#X connect 2 0 1 0;
+#X connect 4 0 3 0;
+#X connect 5 0 0 0;
+#X connect 6 0 0 0;
+#X connect 10 0 9 0;
+#X connect 11 0 0 0;
diff --git a/matches.c b/matches.c
new file mode 100644
index 0000000..13c3b1d
--- /dev/null
+++ b/matches.c
@@ -0,0 +1,193 @@
+/**
+ * The [matches] class in Pure Data is an external to verify that a subject
+ * matches a Perl-compatible regular expression mask.
+ *
+ * http://alexandre.quessy.net
+ *
+ * @author Alexandre Quessy
+ * @c GNU General Public License 2006
+ */
+
+#include "m_pd.h"
+#include <string.h>
+#include <stdlib.h>
+#include <pcre.h>
+
+#define CAPTUREVECTORSIZE 30 /* multiple of 3 */
+#define MATCHES_ERROR_PREFIX "[matches]: "
+#define MATCHES_FALSE_MASK "xxxxxxxxxxxxxxxxxxxxxx"
+#define MATCHES_DECIMAL_PRECISION_SIZE_T 4
+
+/** variables of the pd object */
+typedef struct matches {
+ t_object x_ob; /* contient inlets et outlets */
+ t_outlet *x_outlet;
+ pcre *regex; /* mask */
+} t_matches;
+
+/** functions */
+char *_str_replace(const char search, const char replace, const char *subject);
+int _isMatching(t_matches *x, char *text);
+void _compile_pattern(t_matches *x, const char *pattern);
+
+
+/** left inlet: subject */
+void matches_symbol0(t_matches *x, t_symbol *arg) {
+ int isOk =_isMatching(x, arg->s_name);
+ outlet_float(x->x_outlet, isOk);
+}
+
+/* left inlet: subject (when a float)
+void matches_float0(t_matches *x, t_floatarg arg) {
+ char *str_float = sprintf("%f0", arg);
+ int isOk =_isMatching(x, str_float);
+ outlet_float(x->x_outlet, isOk);
+}
+*/
+
+
+/** right inlet : mask */
+void matches_symbol1(t_matches *x, t_symbol *arg) {
+ _compile_pattern(x, arg->s_name);
+}
+
+/* right inlet
+void matches_float1(t_matches *x, t_floatarg arg) {
+ char *str_float = sprintf("%f0", arg);
+ _compile_pattern(x, str_float);
+}
+*/
+t_class *matches_class;
+
+/** constructor */
+void *matches_new(t_symbol *selector, int argc, t_atom *argv) {
+ int is_valid = 0;
+ t_matches *x = (t_matches *) pd_new(matches_class);
+
+ /* set the mask */
+ if (argc < 1) {
+ post("%s No mask given as argument. Please supply one as message.\n", MATCHES_ERROR_PREFIX);
+ } else {
+ /* if (argv[0].a_type == A_SYMBOL) { */
+ t_symbol *tmp = atom_getsymbol(&argv[0]);
+ _compile_pattern(x, tmp->s_name);
+ is_valid = 1;
+ /*
+ } else {
+ post("%s Argument should be a symbol\n", MATCHES_ERROR_PREFIX);
+ }
+ */
+ }
+ if (is_valid == 0) {
+ _compile_pattern(x, MATCHES_FALSE_MASK);
+ }
+ /* add inlets */
+ inlet_new(&x->x_ob, &x->x_ob.ob_pd, gensym("symbol"), gensym("mask")); /* selecteur, renomme mask */
+
+ /* add outlet */
+ x->x_outlet = outlet_new(&x->x_ob, gensym("float"));
+ return (void *)x;
+}
+
+/** setup */
+void matches_setup(void) {
+ matches_class = class_new(gensym("matches"), (t_newmethod) matches_new, 0, sizeof(t_matches), 0, A_GIMME, 0);
+ class_addmethod(matches_class, (t_method) matches_symbol0, gensym("symbol"), A_SYMBOL, 0);
+ class_addmethod(matches_class, (t_method) matches_symbol1, gensym("mask"), A_SYMBOL, 0);
+ /*
+ class_addmethod(matches_class, (t_method) matches_float0, gensym("float"), A_FLOAT, 0);
+ class_addmethod(matches_class, (t_method) matches_float1, gensym("float"), A_FLOAT, 0);
+ */
+}
+
+
+
+/*
+
+matju aalex: pour les inlets acceptant plusieurs sélecteurs, check gridflow/bridge/puredata.c
+matju aalex: ça fait: inlet_new(self->bself, &p->ob_pd, 0,0);
+matju aalex: avec un proxy inlet
+aalex ???? MiS : http://www.tigerdirect.ca/applications/SearchTools/item-details.asp?EdpNo=1068181&CatId=107
+aalex ah
+aalex matju : il me faut absolument un proxy-inlet, donc
+matju aalex: dans cet exemple, self->bself est d'un soustype de t_object* et &p->ob_pd est un t_pd*
+matju aalex: je crois que oui
+matju aalex: &p->ob_pd est en fait la même chose que (t_pd *)p, si je ne m'abuse
+
+*/
+
+
+
+/* ############################### functions ###################### */
+
+
+
+
+/** clone of the PHP function */
+char *_str_replace(const char search, const char replace, const char *subject) {
+ int i, len;
+ char *result = strdup(subject);
+ len = strlen(result);
+ for (i = 0; i <= len; i++) {
+ if(result[i] == search) {
+ result[i] = replace;
+ }
+ }
+ return result;
+}
+
+/**
+ * returns 1 if matches, 0 if not
+ * TODO use stdbool.h, I think
+ */
+int _isMatching(t_matches *x, char *text) { /* 2nd is const */
+ int capturevector[CAPTUREVECTORSIZE];
+ int rc;
+ int i;
+ int result = 0;
+
+ rc = pcre_exec(x->regex, NULL, text, (int) strlen(text), 0, 0, capturevector, CAPTUREVECTORSIZE);
+
+ if (rc < 0) {
+ result = 0;
+ } else {
+ result = 1;
+ }
+
+ /* ok, a partir d'ici c'est different de l'autre exemple, sauf qu'on avait mis des parentheses dans le pattern */
+ if (rc == 0) {
+ rc = CAPTUREVECTORSIZE / 3;
+ post("ovector only has room for %d captured substrings\n", rc - 1);
+ }
+ for (i = 0; i < rc; i++) {
+ char *substring_start = text + capturevector[2 * i]; /* ovector */
+ int substring_length = capturevector[2 * i + 1] - capturevector[2 * i];
+ post("%2d matching: %.*s", i, substring_length, substring_start);
+ }
+ /* I think that from here I should clean up my memory */
+
+ return result;
+}
+
+/* ############## begin class matches ####################### */
+
+/**
+ * private method to set and compile the mask
+ * TODO : use pcre_malloc() and pcre_free()
+ */
+void _compile_pattern(t_matches *x, const char *pattern) {
+ pcre *regex;
+ const char *regex_error;
+ int erroroffset;
+ char *mask = _str_replace('`', '\\', pattern);
+
+ regex = pcre_compile(mask, 0, &regex_error, &erroroffset, NULL);
+ if (regex == NULL) {
+ post("%s Compilation failed at offset %d : %s", MATCHES_ERROR_PREFIX, erroroffset, regex_error);
+ regex = pcre_compile(MATCHES_FALSE_MASK, 0, &regex_error, &erroroffset, NULL); /* will always return false if invalid pattern */
+ } else {
+ post("%s New PCRE mask: %s", MATCHES_ERROR_PREFIX, mask);
+ }
+ /* free(x->regex); */
+ x->regex = regex;
+}
diff --git a/pcre-help.pd b/pcre-help.pd
new file mode 100644
index 0000000..4a65e0f
--- /dev/null
+++ b/pcre-help.pd
@@ -0,0 +1,38 @@
+#N canvas 4 301 765 489 10;
+#X obj 136 -59 cnv 15 200 140 empty empty empty 20 12 0 14 -258699
+-66577 0;
+#X obj 129 161 cnv 15 300 140 empty empty empty 20 12 0 14 -258699
+-66577 0;
+#X obj 176 107 symbol;
+#X obj 239 259 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0
+1;
+#X obj 152 257 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1
+1;
+#X msg 148 -23 F#9;
+#X msg 214 -23 D7b9;
+#X text 395 60 Matches a symbol against a Perl-compatible regular expression.
+See man pcre.;
+#X obj 327 262 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0
+1;
+#X msg 265 -10 Am7;
+#X obj 152 236 pcre #9;
+#X obj 239 237 pcre b9;
+#X obj 327 240 pcre !9;
+#X text 399 30 pcre;
+#X text 166 -53 patterns;
+#X text 140 170 masks;
+#X msg 298 127 foo;
+#X msg 86 11 foo;
+#X obj 317 162 symbol;
+#X connect 2 0 10 0;
+#X connect 2 0 11 0;
+#X connect 2 0 12 0;
+#X connect 5 0 2 0;
+#X connect 6 0 2 0;
+#X connect 9 0 2 0;
+#X connect 10 0 4 0;
+#X connect 11 0 3 0;
+#X connect 12 0 8 0;
+#X connect 16 0 18 0;
+#X connect 17 0 2 0;
+#X connect 18 0 10 1;
diff --git a/pcre.c b/pcre.c
new file mode 100644
index 0000000..7477938
--- /dev/null
+++ b/pcre.c
@@ -0,0 +1,172 @@
+/**
+ * The [pcre] class in Pure Data is an external to verify that a subject
+ * matches a Perl-compatible regular expression mask.
+ *
+ * http://alexandre.quessy.net
+ *
+ * @author Alexandre Quessy
+ * @c GNU General Public License 2006
+ */
+
+#include "m_pd.h"
+#include <string.h>
+#include <stdlib.h>
+#include <pcre.h>
+
+#define CAPTUREVECTORSIZE 30 /* multiple of 3 */
+#define pdpcre_ERROR_PREFIX "[pdpcre]: "
+#define pdpcre_FALSE_MASK "xxxxxxxxxxxxxxxxxxxxxx"
+#define pdpcre_DECIMAL_PRECISION_SIZE_T 4
+
+/** variables of the pd object */
+typedef struct pdpcre {
+ t_object x_ob; /* contient inlets et outlets */
+ t_outlet *x_outlet;
+ pcre *regex; /* mask */
+} t_pdpcre;
+
+/** functions */
+char *_str_replace(const char search, const char replace, const char *subject);
+int _isMatching(t_pdpcre *x, char *text);
+void _compile_pattern(t_pdpcre *x, const char *pattern);
+
+
+/** left inlet: subject */
+void pdpcre_symbol0(t_pdpcre *x, t_symbol *arg) {
+ int isOk =_isMatching(x, arg->s_name);
+ outlet_float(x->x_outlet, isOk);
+}
+
+/* left inlet: subject (when a float)
+void pdpcre_float0(t_pdpcre *x, t_floatarg arg) {
+ char *str_float = sprintf("%f0", arg);
+ int isOk =_isMatching(x, str_float);
+ outlet_float(x->x_outlet, isOk);
+}
+*/
+
+
+/** right inlet : mask */
+void pdpcre_symbol1(t_pdpcre *x, t_symbol *arg) {
+ _compile_pattern(x, arg->s_name);
+}
+
+/* right inlet
+void pdpcre_float1(t_pdpcre *x, t_floatarg arg) {
+ char *str_float = sprintf("%f0", arg);
+ _compile_pattern(x, str_float);
+}
+*/
+t_class *pdpcre_class;
+
+/** constructor */
+void *pdpcre_new(t_symbol *selector, int argc, t_atom *argv) {
+ int is_valid = 0;
+ t_pdpcre *x = (t_pdpcre *) pd_new(pdpcre_class);
+
+ /* set the mask */
+ if (argc < 1) {
+ post("%s No mask given as argument. Please supply one as message.\n", pdpcre_ERROR_PREFIX);
+ } else {
+ if (argv[0].a_type == A_SYMBOL) {
+ t_symbol *tmp = atom_getsymbol(&argv[0]);
+ _compile_pattern(x, tmp->s_name);
+ is_valid = 1;
+ } else {
+ post("%s Argument should be a symbol\n", pdpcre_ERROR_PREFIX);
+ }
+ }
+ if (is_valid == 0) {
+ _compile_pattern(x, pdpcre_FALSE_MASK);
+ }
+ /* add inlets */
+ inlet_new(&x->x_ob, &x->x_ob.ob_pd, gensym("symbol"), gensym("mask")); /* selecteur, renomme mask */
+
+ /* add outlet */
+ x->x_outlet = outlet_new(&x->x_ob, gensym("float"));
+ return (void *)x;
+}
+
+/** setup */
+void pcre_setup(void) {
+ pdpcre_class = class_new(gensym("pcre"), (t_newmethod) pdpcre_new, 0, sizeof(t_pdpcre), 0, A_GIMME, 0);
+ class_addmethod(pdpcre_class, (t_method) pdpcre_symbol0, gensym("symbol"), A_SYMBOL, 0);
+ class_addmethod(pdpcre_class, (t_method) pdpcre_symbol1, gensym("mask"), A_SYMBOL, 0);
+}
+
+
+
+
+/* ############################### functions ###################### */
+
+
+
+
+/** clone of the PHP function */
+char *_str_replace(const char search, const char replace, const char *subject) {
+ int i, len;
+ char *result = strdup(subject);
+ len = strlen(result);
+ for (i = 0; i <= len; i++) {
+ if(result[i] == search) {
+ result[i] = replace;
+ }
+ }
+ return result;
+}
+
+/**
+ * returns 1 if pdpcre, 0 if not
+ * TODO use stdbool.h, I think
+ */
+int _isMatching(t_pdpcre *x, char *text) { /* 2nd is const */
+ int capturevector[CAPTUREVECTORSIZE];
+ int rc;
+ int i;
+ int result = 0;
+
+ rc = pcre_exec(x->regex, NULL, text, (int) strlen(text), 0, 0, capturevector, CAPTUREVECTORSIZE);
+
+ if (rc < 0) {
+ result = 0;
+ } else {
+ result = 1;
+ }
+
+ /* ok, a partir d'ici c'est different de l'autre exemple, sauf qu'on avait mis des parentheses dans le pattern */
+ if (rc == 0) {
+ rc = CAPTUREVECTORSIZE / 3;
+ post("ovector only has room for %d captured substrings\n", rc - 1);
+ }
+ for (i = 0; i < rc; i++) {
+ char *substring_start = text + capturevector[2 * i]; /* ovector */
+ int substring_length = capturevector[2 * i + 1] - capturevector[2 * i];
+ //post("%2d matching: %.*s", i, substring_length, substring_start);
+ }
+ /* I think that from here I should clean up my memory */
+
+ return result;
+}
+
+/* ############## begin class pdpcre ####################### */
+
+/**
+ * private method to set and compile the mask
+ * TODO : use pcre_malloc() and pcre_free()
+ */
+void _compile_pattern(t_pdpcre *x, const char *pattern) {
+ pcre *regex;
+ const char *regex_error;
+ int erroroffset;
+ char *mask = _str_replace('`', '\\', pattern);
+
+ regex = pcre_compile(mask, 0, &regex_error, &erroroffset, NULL);
+ if (regex == NULL) {
+ post("%s Compilation failed at offset %d : %s", pdpcre_ERROR_PREFIX, erroroffset, regex_error);
+ regex = pcre_compile(pdpcre_FALSE_MASK, 0, &regex_error, &erroroffset, NULL); /* will always return false if invalid pattern */
+ } else {
+ post("%s New PCRE mask: %s", pdpcre_ERROR_PREFIX, mask);
+ }
+ /* free(x->regex); */
+ x->regex = regex;
+}
diff --git a/x11key-help.pd b/x11key-help.pd
new file mode 100644
index 0000000..616c91b
--- /dev/null
+++ b/x11key-help.pd
@@ -0,0 +1,43 @@
+#N canvas 466 121 703 480 10;
+#X obj 89 21 cnv 15 150 140 empty empty empty 20 12 0 14 -258699 -66577
+0;
+#X obj 334 26 cnv 15 200 140 empty empty empty 20 12 0 14 -258699 -66577
+0;
+#X obj 230 191 cnv 15 420 230 empty empty x11key_object 20 12 0 14 -258699
+-66577 0;
+#X obj 166 365 x11key;
+#X msg 22 61 help;
+#X msg 104 106 letter a;
+#X msg 103 40 bang;
+#X msg 348 50 bang;
+#X msg 29 305 display :0.0;
+#X obj 347 114 delay 1000;
+#X obj 105 84 delay 1000;
+#X obj 446 116 delay 2000;
+#X msg 344 139 keysym A 1;
+#X msg 448 136 keysym A 0;
+#X obj 349 92 t b b;
+#X text 341 34 2 triggers on and of a key;
+#X text 109 25 1 types a key;
+#X text 25 273 Not yet implemented;
+#X text 243 231 [x11key] simulates X11 keyboard events.;
+#X text 240 262 Try examples 1 and 2 They generate keys as if you typed
+it on your keyboard. Give the focus to an other application than PD
+\, in order to see that you really fake letters typing.;
+#X text 240 322 Comments are welcome. The API (the messages for every
+is likely to change.;
+#X text 242 384 )c( Copyleft 2006 Alexandre Quessy;
+#X text 245 399 Released under the GNU Public License;
+#X text 245 368 pureX11;
+#X connect 4 0 3 0;
+#X connect 5 0 3 0;
+#X connect 6 0 10 0;
+#X connect 7 0 14 0;
+#X connect 8 0 3 0;
+#X connect 9 0 12 0;
+#X connect 10 0 5 0;
+#X connect 11 0 13 0;
+#X connect 12 0 3 0;
+#X connect 13 0 3 0;
+#X connect 14 0 9 0;
+#X connect 14 1 11 0;
diff --git a/x11key.c b/x11key.c
new file mode 100644
index 0000000..2134019
--- /dev/null
+++ b/x11key.c
@@ -0,0 +1,162 @@
+/**
+ * [x11kry] Generates X11 keyboard events on Linux
+ * @author Alexandre Quessy <alex@sourcelibre.com>
+ * @license GNU Public License )c( 2006
+ */
+
+#include <X11/Xlib.h>
+#include <X11/Xresource.h>
+#include <X11/extensions/XTest.h>
+#include <X11/keysym.h>
+// #include <stdio.h>
+#include <stdbool.h>
+#include <unistd.h>
+#include "m_pd.h"
+
+#define PUREX11_DEFAULT_KEYSTATE 0
+#define PUREX11_DEFAULT_DISPLAY 0
+
+/** variables of the pd object */
+typedef struct x11key {
+ t_object x_ob; /* The instance. Contains inlets and outlets */
+ int *displayName;
+} t_x11key;
+
+/**
+ * letter : types the letter you give it.
+ */
+void x11key_letter(t_x11key *x, t_symbol *s, int argc, t_atom *argv) {
+ Display *display;
+ KeySym keysym;
+ KeyCode keycode;
+ int result;
+
+ if (argc == 1) {
+ if (argv[0].a_type == A_SYMBOL) {
+ t_symbol *sym = atom_getsymbolarg(0, argc, argv);
+ char *theChars = sym->s_name;
+ //keysym = XK_q;
+ keysym = XStringToKeysym(theChars);
+ /* should be hostname:number.screen_number */
+ display = XOpenDisplay(NULL); /* defaults to $DISPLAY */
+ if (display == NULL) {
+ post("Error : could not open display.\n");
+ }else {
+ // printf("Display opened successfully.\n");
+ keycode = XKeysymToKeycode(display, keysym);
+ //post("letter = %s", theChars);
+ //post("keycode = %d", (int) keycode);
+ /** Pushes on and off the letter */
+ result = XTestFakeKeyEvent(display, keycode, True, 0);
+ //post("result = %d", result);
+ if (result == 0) {
+ post("Error : could not simulate typing the letter.");
+ }
+ result = XTestFakeKeyEvent(display, keycode, False, 0);
+ if (result == 0) {
+ post("Error : could not simulate typing the letter.");
+ }
+ XCloseDisplay(display);
+ }
+ } else {
+ post("Error : Bad argument type. Must be a symbol. Try [symbol 7< if you want to type a number.");
+ }
+ } else {
+ post("Error : Missing argument. The letter to type.");
+ }
+}
+
+
+
+/**
+ * key : types the key symbol you give it. See /usr/include/X11/keysymdef.h
+ */
+void x11key_keysym(t_x11key *x, t_symbol *s, int argc, t_atom *argv) {
+ Display *display;
+ KeySym keysym;
+ KeyCode keycode;
+ int result;
+ int state = PUREX11_DEFAULT_KEYSTATE;
+ bool boolState;
+
+ if (argc >= 2) {
+ if (argv[1].a_type == A_FLOAT) {
+ state = (int) atom_getfloatarg(1, argc, argv);
+ }
+ }
+
+ if (argc >= 1) {
+ if (argv[0].a_type == A_SYMBOL) {
+ t_symbol *sym = atom_getsymbolarg(0, argc, argv);
+ char *theChars = sym->s_name;
+ //keysym = XK_q;
+ keysym = XStringToKeysym(theChars);
+ /* should be hostname:number.screen_number */
+ display = XOpenDisplay(NULL); /* defaults to $DISPLAY */
+ if (display == NULL) {
+ post("Error : could not open display.\n");
+ }else {
+ // printf("Display opened successfully.\n");
+ keycode = XKeysymToKeycode(display, keysym);
+
+ /** Pushes on and off the letter */
+ boolState = (state == 0) ? False : True;
+ result = XTestFakeKeyEvent(display, keycode, boolState, 0);
+ if (result == 0) {
+ post("Error : could not simulate typing the letter.");
+ }
+ XCloseDisplay(display);
+ }
+ } else {
+ post("Error : Bad argument type. Must be a symbol. ");
+ }
+ } else {
+ post("Error : Missing argument. The letter to type.");
+ }
+}
+
+
+
+/** display */
+void x11key_display(t_x11key *x, t_symbol *s, int argc, t_atom *argv) {
+ post("Not yet implemented.");
+}
+
+/** help */
+void x11key_help(t_x11key *x, t_symbol *s, int argc, t_atom *argv) {
+ post("keysym [see /usr/include/X11/keysymdef.h for the key symbols]");
+ post("letter [letter a-zA-Z0-9...]");
+ post("help");
+ post("display : not yet implemented");
+}
+
+
+
+
+
+/** The class */
+t_class *x11key_class;
+
+/** constructor */
+void *x11key_new(t_symbol *selector, int argc, t_atom *argv) {
+ t_x11key *x = (t_x11key *) pd_new(x11key_class);
+ //x->displayName = PUREX11_DEFAULT_DISPLAY;
+ return (void *)x;
+}
+
+/** setup */
+void x11key_setup(void) {
+ x11key_class = class_new(gensym("x11key"), (t_newmethod) x11key_new, 0, sizeof(t_x11key), 0, A_GIMME, 0);
+ class_addmethod(x11key_class, (t_method)x11key_letter, gensym("letter"), A_GIMME, 0);
+ class_addmethod(x11key_class, (t_method)x11key_keysym, gensym("keysym"), A_GIMME, 0);
+ class_addmethod(x11key_class, (t_method)x11key_display, gensym("display"), A_GIMME, 0);
+ class_addmethod(x11key_class, (t_method)x11key_help, gensym("help"), A_GIMME, 0);
+
+ post("==============================================");
+ post(" Pure X11");
+ post("Copyleft 2006 Alexandre Quessy");
+ post("GNU Public License");
+ post("[x11key] simulates X11 keyboard events.");
+ post("==============================================");
+
+}
diff --git a/x11mouse-help.pd b/x11mouse-help.pd
new file mode 100644
index 0000000..4555b04
--- /dev/null
+++ b/x11mouse-help.pd
@@ -0,0 +1,76 @@
+#N canvas 63 104 997 560 10;
+#X obj 13 10 cnv 15 150 140 empty empty empty 20 12 0 14 -258699 -66577
+0;
+#X obj 385 63 cnv 15 100 100 empty empty empty 20 12 0 14 -258699 -66577
+0;
+#X obj 521 275 cnv 15 420 230 empty empty x11mouse_object 20 12 0 14
+-258699 -66577 0;
+#X obj 189 152 cnv 15 150 140 empty empty empty 20 12 0 14 -258699
+-66577 0;
+#X obj 569 70 cnv 15 100 100 empty empty empty 20 12 0 14 -258699 -66577
+0;
+#X obj 760 23 cnv 15 200 200 empty empty empty 20 12 0 14 -258699 -66577
+0;
+#X obj 271 468 x11mouse;
+#X msg 32 107 click;
+#X msg 199 261 press 1 1;
+#X msg 49 339 help;
+#X obj 848 95 f 0;
+#X obj 889 95 + 1;
+#X msg 927 58 0;
+#X obj 802 41 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1
+;
+#X msg 810 186 move \$1 \$1;
+#X obj 848 125 > 50;
+#X obj 32 85 delay 500;
+#X msg 32 30 bang;
+#X obj 90 158 print;
+#X obj 199 240 delay 500;
+#X msg 196 189 bang;
+#X obj 587 116 delay 500;
+#X msg 587 76 bang;
+#X msg 587 137 press 3 1;
+#X msg 392 124 move 400 200;
+#X floatatom 763 186 5 0 0 0 - - -;
+#X obj 847 146 sel 1;
+#X obj 848 65 metro 50;
+#X obj 813 123 * 4;
+#X text 542 395 Comments are welcome. The API (the messages for every
+is likely to change.;
+#X text 544 457 )c( Copyleft 2006 Alexandre Quessy;
+#X text 547 472 Released under the GNU Public License;
+#X text 547 441 pureX11;
+#X text 16 -10 1 Click and keep your mouse over the message;
+#X text 197 164 2 Click and keep your mouse over the message;
+#X text 388 48 3 Moves the mouse;
+#X text 766 7 5 Moves the mouse around;
+#X text 548 306 [x11mouse] simulates X11 mouse events.;
+#X text 564 51 4 Right-clicks (button 3);
+#X text 545 337 Try all examples.;
+#X text 221 297 press 1 on;
+#X text 218 320 press 1 off;
+#X connect 7 0 6 0;
+#X connect 7 0 18 0;
+#X connect 8 0 6 0;
+#X connect 9 0 6 0;
+#X connect 10 0 11 0;
+#X connect 10 0 15 0;
+#X connect 10 0 28 0;
+#X connect 11 0 10 1;
+#X connect 12 0 10 1;
+#X connect 12 0 27 0;
+#X connect 13 0 27 0;
+#X connect 14 0 6 0;
+#X connect 15 0 26 0;
+#X connect 16 0 7 0;
+#X connect 17 0 16 0;
+#X connect 19 0 8 0;
+#X connect 20 0 19 0;
+#X connect 21 0 23 0;
+#X connect 22 0 21 0;
+#X connect 23 0 6 0;
+#X connect 24 0 6 0;
+#X connect 26 0 12 0;
+#X connect 27 0 10 0;
+#X connect 28 0 14 0;
+#X connect 28 0 25 0;
diff --git a/x11mouse.c b/x11mouse.c
new file mode 100644
index 0000000..b13ace0
--- /dev/null
+++ b/x11mouse.c
@@ -0,0 +1,181 @@
+/**
+ * [x11mouse] Generates X11 mouse events on Linux
+ * @author Alexandre Quessy <alex@sourcelibre.com>
+ * @license GNU Public License )c( 2006
+ */
+
+#include <X11/Xlib.h>
+#include <X11/Xresource.h>
+#include <X11/extensions/XTest.h>
+#include <stdio.h>
+#include <stdbool.h>
+#include <unistd.h>
+#include "m_pd.h"
+
+#define PUREX11_DEFAULT_MOUSEBUTTON 1
+#define PUREX11_DEFAULT_MOUSESTATE 0
+#define PUREX11_DEFAULT_DISPLAY 0
+#define PUREX11_DEFAULT_XVALUE 0
+#define PUREX11_DEFAULT_YVALUE 0
+
+
+/** variables of the pd object */
+typedef struct x11mouse {
+ t_object x_ob; /* The instance. Contains inlets and outlets */
+ int *displayName;
+} t_x11mouse;
+
+
+
+/**
+ * Mouse click
+ * @param int Button number
+ */
+void x11mouse_click(t_x11mouse *x, t_symbol *s, int argc, t_atom *argv) {
+ Display *display;
+ int result;
+
+ int button = PUREX11_DEFAULT_MOUSEBUTTON;
+
+ display = XOpenDisplay(0); /* defaults to $DISPLAY if 0 */
+ if (display == NULL) {
+ post("[x11mouse] error : could not open display.");
+ }
+ if (argc >= 1) {
+ if (argv[0].a_type == A_FLOAT) {
+ button = (int) atom_getfloatarg(0, argc, argv);
+ }
+ }
+
+ result = XTestFakeButtonEvent(display, button, True, CurrentTime);
+ result = XTestFakeButtonEvent(display, button, False, CurrentTime);
+ XCloseDisplay(display);
+}
+
+/**
+ * Mouse button press or release
+ * @param int State. Defaults to 0.
+ * @param int Button number
+ */
+void x11mouse_press(t_x11mouse *x, t_symbol *s, int argc, t_atom *argv) {
+ Display *display;
+ int result;
+
+ int button = PUREX11_DEFAULT_MOUSEBUTTON;
+ int state = PUREX11_DEFAULT_MOUSESTATE;
+ bool boolState;
+
+ display = XOpenDisplay(0); /* defaults to $DISPLAY if 0 */
+ if (display == NULL) {
+ post("[x11mouse] error : could not open display.");
+ }
+
+ if (argc >= 2) {
+ if (argv[1].a_type == A_FLOAT) {
+ button = (int) atom_getfloatarg(1, argc, argv);
+ }
+ if (argv[0].a_type == A_FLOAT) {
+ state = (int) atom_getfloatarg(0, argc, argv);
+ }
+ } else if (argc >= 1) {
+ if (argv[0].a_type == A_FLOAT) {
+ state = (int) atom_getfloatarg(0, argc, argv);
+ }
+ }
+
+ boolState = (state == 0) ? False : True;
+ result = XTestFakeButtonEvent(display, button, boolState, CurrentTime);
+ if (!result) {
+ post("[x11mouse] error : could not fake button event.");
+ }
+ XCloseDisplay(display);
+}
+
+/**
+ * Moves the mouse to the coordonates you give it.
+ */
+void x11mouse_move(t_x11mouse *x, t_symbol *s, int argc, t_atom *argv) {
+ Display *display;
+ int result;
+ int xCoord = PUREX11_DEFAULT_XVALUE;
+ int yCoord = PUREX11_DEFAULT_YVALUE;
+
+ display = XOpenDisplay(0); /* defaults to $DISPLAY if 0 */
+ if (display == NULL) {
+ post("[x11mouse] error : could not open display.");
+ }
+
+ if (argc >= 2) {
+ if (argv[1].a_type == A_FLOAT) {
+ yCoord = (int) atom_getfloatarg(0, argc, argv);
+ }
+ if (argv[0].a_type == A_FLOAT) {
+ xCoord = (int) atom_getfloatarg(0, argc, argv);
+ }
+ } else if (argc >= 1) {
+ if (argv[0].a_type == A_FLOAT) {
+ xCoord = (int) atom_getfloatarg(0, argc, argv);
+ }
+ }
+
+ result = XTestFakeMotionEvent(display, 0, xCoord, yCoord, CurrentTime);
+ if (!result) {
+ post("[x11mouse] error : could not fake motion event.");
+ }
+ XCloseDisplay(display);
+}
+
+/**
+ * Sets the X11 display name.
+ * Defaults to $DISPLAY, usually :0.0
+ *
+ * Not currently implemented. You cannot change the display. (for now)
+ * @todo Allow the user to change the display
+ */
+void x11mouse_display(t_x11mouse *x, t_symbol *s, int argc, t_atom *argv) {
+ Display *display;
+ display = XOpenDisplay(0); /* defaults to $DISPLAY if 0 */
+ if (display == NULL) {
+ post("[x11mouse] error : could not open display.");
+ }
+ XCloseDisplay(display);
+}
+
+void x11mouse_help(t_x11mouse *x, t_symbol *s, int argc, t_atom *argv) {
+ post("press [state 0/1] [button number 1-3]");
+ post("move [x] [y]");
+ post("click [button number 1-3]");
+ post("help");
+ post("display not yet implemented");
+
+
+
+}
+
+/** The class */
+t_class *x11mouse_class;
+
+/** constructor */
+void *x11mouse_new(t_symbol *selector, int argc, t_atom *argv) {
+ t_x11mouse *x = (t_x11mouse *) pd_new(x11mouse_class);
+ //x->displayName = PUREX11_DEFAULT_DISPLAY;
+ return (void *)x;
+}
+
+/** setup */
+void x11mouse_setup(void) {
+ x11mouse_class = class_new(gensym("x11mouse"), (t_newmethod) x11mouse_new, 0, sizeof(t_x11mouse), 0, A_GIMME, 0);
+ class_addmethod(x11mouse_class, (t_method)x11mouse_press, gensym("press"), A_GIMME, 0);
+ class_addmethod(x11mouse_class, (t_method)x11mouse_move, gensym("move"), A_GIMME, 0);
+ class_addmethod(x11mouse_class, (t_method)x11mouse_display, gensym("display"), A_GIMME, 0);
+ class_addmethod(x11mouse_class, (t_method)x11mouse_click, gensym("click"), A_GIMME, 0);
+ class_addmethod(x11mouse_class, (t_method)x11mouse_help, gensym("help"), A_GIMME, 0);
+
+ post("==============================================");
+ post(" Pure X11");
+ post("Copyleft 2006 Alexandre Quessy");
+ post("GNU Public License");
+ post("[x11mouse] simulates X11 mouse events.");
+ post("==============================================");
+
+}
diff --git a/xmms-help.pd b/xmms-help.pd
new file mode 100644
index 0000000..4ea2c27
--- /dev/null
+++ b/xmms-help.pd
@@ -0,0 +1,40 @@
+#N canvas 603 220 447 336 10;
+#X obj 14 113 cnv 15 50 50 empty empty empty 20 12 0 14 -258699 -66577
+0;
+#X obj 79 112 cnv 15 50 50 empty empty empty 20 12 0 14 -24198 -66577
+0;
+#X obj 158 105 cnv 15 50 50 empty empty empty 20 12 0 14 -258699 -66577
+0;
+#X obj 259 104 cnv 15 50 50 empty empty empty 20 12 0 14 -24198 -66577
+0;
+#X obj 208 105 cnv 15 50 50 empty empty empty 20 12 0 14 -241291 -66577
+0;
+#X obj 60 274 xmms;
+#X msg 79 112 next;
+#X msg 15 113 prev;
+#X msg 265 122 play;
+#X msg 165 121 stop;
+#X msg 213 122 pause;
+#X obj 56 11 keyname;
+#X obj 99 35 select h j k l;
+#X msg 317 232 volume \$1;
+#X obj 318 172 vsl 15 50 0 100 0 0 empty empty empty 0 -8 0 8 -62784
+-1 -1 0 1;
+#X msg 213 206 forward 4000;
+#X msg 214 183 backward 4000;
+#X msg 210 229 backward;
+#X connect 6 0 5 0;
+#X connect 7 0 5 0;
+#X connect 8 0 5 0;
+#X connect 9 0 5 0;
+#X connect 10 0 5 0;
+#X connect 11 1 12 0;
+#X connect 12 0 16 0;
+#X connect 12 1 10 0;
+#X connect 12 2 8 0;
+#X connect 12 3 15 0;
+#X connect 13 0 5 0;
+#X connect 14 0 13 0;
+#X connect 15 0 5 0;
+#X connect 16 0 5 0;
+#X connect 17 0 5 0;
diff --git a/xmms.c b/xmms.c
new file mode 100644
index 0000000..ef17659
--- /dev/null
+++ b/xmms.c
@@ -0,0 +1,148 @@
+/**
+ * [xmms] is a Pure Data object to control the X Multimedia System, an audio player.
+ *
+ * @url http://alexandre.quessy.net/
+ * @author Alexandre Quessy <alexandre@quessy.net>
+ * @license GNU General Public License 2006
+ * thanks to Andy Gimblett for code examples
+ */
+/*
+To know which flags to use for compilation:
+`xmms-config --cflags --libs`
+
+On Debian, you need libxmms and xmms-festalon if you want to read nsf files.
+*/
+
+//#define _GNU_SOURCE
+
+/* PD includes */
+#include "m_pd.h"
+#include <math.h>
+// #include <string.h>
+#include <stdlib.h>
+// #include <stdio.h>
+
+/* XMMS includes */
+#include <xmms/xmmsctrl.h>
+// #include <glib.h>
+/* local constants */
+#define PDXMMS_DEFAULTSKIP 5000
+
+
+//need following declarations so internal XMMS functions can be called
+//(ripped from XMMS source)
+//from xmms.c
+//gboolean playlist_load(gchar * inpipefile);
+
+
+/** variables of the pd object */
+typedef struct xmms {
+ t_object x_ob; /* The instance. Contains inlets and outlets */
+ /* xmms session. 0 is the first one when we start it */
+ int session;
+ //t_outlet *x_outlet;
+} t_xmms;
+
+
+
+void xmms_prev(t_xmms *x, t_symbol *s, int argc, t_atom *argv) {
+ xmms_remote_playlist_prev(x->session);
+}
+
+void xmms_next(t_xmms *x, t_symbol *s, int argc, t_atom *argv) {
+ xmms_remote_playlist_next(x->session);
+}
+
+void xmms_play(t_xmms *x, t_symbol *s, int argc, t_atom *argv) {
+ xmms_remote_play(x->session);
+}
+
+void xmms_pause(t_xmms *x, t_symbol *s, int argc, t_atom *argv) {
+ xmms_remote_pause(x->session);
+}
+
+void xmms_stop(t_xmms *x, t_symbol *s, int argc, t_atom *argv) {
+ xmms_remote_stop(x->session);
+}
+
+void xmms_volume(t_xmms *x, t_symbol *s, int argc, t_atom *argv) {
+ float f;
+ int l, r;
+ if (argc >= 1) {
+ if (argv[0].a_type == A_FLOAT) {
+ f = (float) atom_getfloatarg(0, argc, argv);
+ l = (int) f;
+ //if (mute_flag) mute_flag = 0;
+ if (l > 100) l = 100;
+ else if (l < 0) l = 0;
+ //if (r > 100) r = 100;
+ //else if (r < 0) r = 0;
+ r = f;
+ xmms_remote_set_volume(x->session, l, r);
+ }
+ }
+}
+
+
+/* skipf and skipb */
+void xmms_forward(t_xmms *x, t_symbol *s, int argc, t_atom *argv) {
+ int time = xmms_remote_get_output_time(x->session);
+ double skip = PDXMMS_DEFAULTSKIP;
+
+ if (argc >= 1) {
+ if (argv[0].a_type == A_FLOAT) {
+ skip = (double) atom_getfloatarg(0, argc, argv);
+ }
+ }
+ xmms_remote_jump_to_time(x->session, (int) rint(time + skip));
+}
+
+void xmms_backward(t_xmms *x, t_symbol *s, int argc, t_atom *argv) {
+ int time = xmms_remote_get_output_time(x->session);
+ double skip = PDXMMS_DEFAULTSKIP;
+
+ if (argc >= 1) {
+ if (argv[0].a_type == A_FLOAT) {
+ skip = (double) atom_getfloatarg(0, argc, argv);
+ }
+ }
+ xmms_remote_jump_to_time(x->session, (int) rint(time - skip));
+}
+
+/*
+void xmms_load0(t_xmms *x, t_symbol *s, int argc, t_atom *argv) {
+ if (argc >= 1) {
+ if (argv[0].a_type == A_SYMBOL) {
+ t_symbol *tmp = atom_getsymbol(&argv[0]);
+ playlist_load(tmp->s_name);
+ }
+ }
+}
+ */
+/** The class */
+t_class *xmms_class;
+
+/** constructor */
+void *xmms_new(t_symbol *selector, int argc, t_atom *argv) {
+ t_xmms *x = (t_xmms *) pd_new(xmms_class);
+ //x->x_outlet = outlet_new(&x->x_ob, gensym("symbol"));
+ x->session = 0;
+ // if (!xmms_remote_is_running(x->session)) return 0;
+ return (void *)x;
+}
+
+/** setup */
+void xmms_setup(void) {
+ xmms_class = class_new(gensym("xmms"), (t_newmethod) xmms_new, 0, sizeof(t_xmms), 0, A_GIMME, 0);
+
+ class_addmethod(xmms_class, (t_method)xmms_stop, gensym("stop"), A_GIMME, 0);
+ class_addmethod(xmms_class, (t_method)xmms_play, gensym("play"), A_GIMME, 0);
+ class_addmethod(xmms_class, (t_method)xmms_pause, gensym("pause"), A_GIMME, 0);
+ class_addmethod(xmms_class, (t_method)xmms_next, gensym("next"), A_GIMME, 0);
+ class_addmethod(xmms_class, (t_method)xmms_prev, gensym("prev"), A_GIMME, 0);
+ class_addmethod(xmms_class, (t_method)xmms_forward, gensym("forward"), A_GIMME, 0);
+ class_addmethod(xmms_class, (t_method)xmms_backward, gensym("backward"), A_GIMME, 0);
+ class_addmethod(xmms_class, (t_method)xmms_volume, gensym("volume"), A_GIMME, 0);
+ //class_addmethod(xmms_class, (t_method)xmms_load0, gensym("load"), A_GIMME, 0);
+}
+