diff options
author | David Robillard <d@drobilla.net> | 2006-06-09 02:18:57 +0000 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2006-06-09 02:18:57 +0000 |
commit | 2f0e092964f800c0ff82cbd08bf2ee05db814e7b (patch) | |
tree | d35a09dc50535aae9292f8ca3262adc5526fe2a6 | |
download | patchage-2f0e092964f800c0ff82cbd08bf2ee05db814e7b.tar.gz patchage-2f0e092964f800c0ff82cbd08bf2ee05db814e7b.tar.bz2 patchage-2f0e092964f800c0ff82cbd08bf2ee05db814e7b.zip |
Added patchage
git-svn-id: http://svn.drobilla.net/lad/patchage@5 a436a847-0d15-0410-975c-d299462d15a1
-rw-r--r-- | AUTHORS | 4 | ||||
-rw-r--r-- | ChangeLog | 365 | ||||
-rw-r--r-- | Doxyfile | 1153 | ||||
-rw-r--r-- | Makefile.am | 4 | ||||
-rw-r--r-- | NEWS | 42 | ||||
-rw-r--r-- | README | 1 | ||||
-rw-r--r-- | THANKS | 12 | ||||
-rw-r--r-- | aclocal.m4 | 1007 | ||||
-rwxr-xr-x | autogen.sh | 6 | ||||
-rw-r--r-- | configure.ac | 117 | ||||
-rw-r--r-- | src/AlsaDriver.cpp | 484 | ||||
-rw-r--r-- | src/AlsaDriver.h | 72 | ||||
-rw-r--r-- | src/Driver.h | 55 | ||||
-rw-r--r-- | src/JackDriver.cpp | 258 | ||||
-rw-r--r-- | src/JackDriver.h | 68 | ||||
-rw-r--r-- | src/LashDriver.cpp | 146 | ||||
-rw-r--r-- | src/LashDriver.h | 50 | ||||
-rw-r--r-- | src/Makefile.am | 27 | ||||
-rw-r--r-- | src/Patchage.cpp | 411 | ||||
-rw-r--r-- | src/Patchage.h | 116 | ||||
-rw-r--r-- | src/PatchageFlowCanvas.cpp | 117 | ||||
-rw-r--r-- | src/PatchageFlowCanvas.h | 49 | ||||
-rw-r--r-- | src/PatchageModule.h | 120 | ||||
-rw-r--r-- | src/PatchagePort.h | 66 | ||||
-rw-r--r-- | src/StateManager.cpp | 246 | ||||
-rw-r--r-- | src/StateManager.h | 75 | ||||
-rw-r--r-- | src/main.cpp | 49 | ||||
-rw-r--r-- | src/patchage.glade | 607 | ||||
-rw-r--r-- | src/patchage.gladep | 9 |
29 files changed, 5736 insertions, 0 deletions
@@ -0,0 +1,4 @@ +Author: + +Dave Robillard <drobilla@connect.carleton.ca> + diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 0000000..488fc55 --- /dev/null +++ b/ChangeLog @@ -0,0 +1,365 @@ +2005-08-29 13:54 drobilla + + * ChangeLog, NEWS, configure.ac, src/PatchagePatchBayArea.cpp: + Fixed "Disconnect All" for real this time + +2005-08-23 05:06 drobilla + + * src/: StateManager.cpp, canvas/PatchBayArea.cpp: Fixed blatant + guaranteed segfault (shame) + +2005-08-19 21:51 drobilla + + * src/canvas/Module.cpp: Added middle click to show Node Control + Window, until scrolling actually works + +2005-08-19 21:30 drobilla + + * src/canvas/: Connection.cpp, Connection.h, Module.cpp, Module.h, + PatchBayArea.cpp, PatchBayArea.h, Port.cpp, Port.h: Updated + Copyright year in comment header + +2005-08-19 18:48 drobilla + + * src/canvas/: Module.cpp, Module.h: - Response time tuning in the + Gtk client - Segfault fixed in engine (destroy patch and other + recursive events) + +2005-08-17 20:45 drobilla + + * NEWS, configure.ac, src/AlsaDriver.cpp, src/Patchage.cpp, + src/PatchageModule.h, src/main.cpp: - Upped version number - + Fixed building without LASH (--disable-lash) + +2005-08-17 15:43 drobilla + + * src/canvas/: Module.cpp, Module.h: Added ability to show control + windows for DSSI plugins (in addition to the plugin's GUI) + +2005-08-15 15:50 drobilla + + * src/canvas/PatchBayArea.cpp: Fixed add pluginw window closing + +2005-08-14 16:24 drobilla + + * src/canvas/: PatchBayArea.cpp, Port.cpp, Port.h: Added port + hiliting on mouse hover + +2005-08-08 23:38 drobilla + + * src/canvas/: PatchBayArea.cpp, PatchBayArea.h: - Added patch + description and author (client-side only) - Reduced heavy + dependancy on PatchModel.h in GTK client + +2005-08-06 15:01 drobilla + + * src/: AlsaDriver.cpp, JackDriver.cpp, Patchage.cpp, + PatchageModule.h: Fixed problem with randomly moving modules when + moving others + +2005-08-05 19:06 drobilla + + * src/canvas/: PatchBayArea.cpp, PatchBayArea.h: Fixed subpatch + path problem by adding a patch path config option to the client. + More testing and better default values required.. + +2005-05-29 17:11 drobilla + + * .tm_project.cache, src/.PatchageModule.h.swp: Removed + accidentally checked in files + +2005-05-29 17:08 drobilla + + * .tm_project.cache, AUTHORS, Makefile.am, NEWS, README, THANKS, + autogen.sh, configure.ac, ChangeLog, src/PatchageModule.h, + src/AlsaDriver.cpp, src/JackDriver.cpp, + src/.PatchageModule.h.swp, src/AlsaDriver.h, src/JackDriver.h, + src/LashController.cpp, src/LashController.h, src/Makefile.am, + src/Patchage.cpp, src/Patchage.h, src/PatchagePatchBayArea.cpp, + src/PatchagePatchBayArea.h, src/PatchagePort.h, + src/StateManager.cpp, src/StateManager.h, src/main.cpp, + src/patchage.glade, src/patchage.gladep: Added patchage module to + repository + +2005-05-29 17:08 drobilla + + * .tm_project.cache, AUTHORS, Makefile.am, NEWS, README, THANKS, + autogen.sh, configure.ac, ChangeLog, src/PatchageModule.h, + src/AlsaDriver.cpp, src/JackDriver.cpp, + src/.PatchageModule.h.swp, src/AlsaDriver.h, src/JackDriver.h, + src/LashController.cpp, src/LashController.h, src/Makefile.am, + src/Patchage.cpp, src/Patchage.h, src/PatchagePatchBayArea.cpp, + src/PatchagePatchBayArea.h, src/PatchagePort.h, + src/StateManager.cpp, src/StateManager.h, src/main.cpp, + src/patchage.glade, src/patchage.gladep: Initial revision + +2005-05-28 12:44 drobilla + + * src/canvas/: Module.cpp, PatchBayArea.cpp, PatchBayArea.h: Failed + attempt at middle-dragging on canvas to scroll. + +2005-05-07 22:25 drobilla + + * src/canvas/: Module.cpp, Module.h, PatchBayArea.cpp, + PatchBayArea.h, Port.cpp, Port.h: - Fixed problem with slow + events depending on each other (ie create patch immediately + followed by add node, add node used to fail if patch event + wasn't finished yet) - Patch specific enable/disable - Vastly + improved patch loading (faster, better) - Updated canvas widget + to new Patchage version - Numerous bugfixes - Fixed HORRIBLE + problem with OSC communication (sending notifications to + clients many, many times, etc) - About 900 other things I've + probably forgotten. This commit is too big - Fixed race issue + with jack ports introduced by above. May be more... + +2005-04-18 02:29 drobilla + + * src/canvas/Makefile.am: Fixed File->Close on patch windows to + actually work + +2005-04-15 17:39 drobilla + + * src/canvas/Module.cpp: Fixed bug when removing connected + input/output nodes + +2005-04-13 00:22 drobilla + + * src/canvas/Module.cpp: Fixed some bugs introduced in the last few + committs (mostly subpatch related) + +2005-04-12 22:37 drobilla + + * src/canvas/: Module.cpp, Module.h, PatchBayArea.cpp, + PatchBayArea.h, Port.cpp, Port.h: Made patch loading about 5 + times as fast, as the expense of anti aliasing :( + +2005-03-30 01:05 drobilla + + * src/canvas/: Module.cpp, Module.h: Fixed placement of loaded + subpatches' modules, cleaned up some other things in the process. + +2005-03-29 20:40 drobilla + + * src/canvas/: Module.cpp, Module.h: - Numerous bugfixes - Fixed + removal of connected subpatches - Vastly improved + DisconnectAllEvent as a consequence of above - Improved gtk + client communication stuff - still too slow though + +2005-03-27 19:36 drobilla + + * src/canvas/Module.cpp: - disconnect_all command - Removing of + connected nodes - Minor documentation updates + +2005-03-26 20:36 drobilla + + * src/canvas/Module.cpp: - Fixed loading patches saved as mono as + polyphonic pathches - Sped up client side event stuff using lock + free queue instead of std::queue - Fixed a segfault on patch load + (and other events) - Changed Queue API to match that of + std::queue + +2005-03-21 20:46 drobilla + + * src/canvas/PatchBayArea.cpp: Added individual ALSA Midi port for + each patch. + +2005-03-16 20:49 drobilla + + * src/canvas/: Module.cpp, Module.h: - Proper subpatch module port + removal - Proper subpatch deletion - Minor optimizations and + de-braindead-izing of client + +2005-03-16 00:22 drobilla + + * src/canvas/PatchBayArea.cpp: - Patch control-rate inputs and + outputs - One or two minor GUI tweaks + +2005-03-12 01:27 drobilla + + * src/canvas/PatchBayArea.cpp: Fixed up the new shinier connection + stuff, it was messed up + +2005-03-11 18:44 drobilla + + * src/canvas/: Connection.cpp, Connection.h, Module.cpp, Module.h, + PatchBayArea.cpp, PatchBayArea.h, Port.cpp, Port.h: Some GUI + shinification, arrow on drag connections, snap to port, etc. + +2005-03-10 19:18 drobilla + + * src/canvas/: Module.cpp, Module.h, PatchBayArea.cpp, Port.cpp, + Port.h: Cleaned up API of patch bay widget. + +2005-03-10 18:12 drobilla + + * src/canvas/: Connection.cpp, Connection.h, Module.cpp, Module.h, + PatchBayArea.cpp, PatchBayArea.h, Port.cpp, Port.h: Finished + namespace-izing everything and some documentation updates. + +2005-02-27 20:37 drobilla + + * src/canvas/PatchBayArea.cpp: - More work on subpatching (almost + done!) - Made /om/send_all_objects not block the OSC thread and + eat CPU - GUI enhancements (better load patch dialogs, etc) - + Patch ports now take name of OutputNode (so user can define port + names) + +2005-02-27 15:15 drobilla + + * src/canvas/: Module.cpp, PatchBayArea.cpp: - Cleaned out + remainder of old MIDI binding cruft - Numerous GUI enhancements + (double clicking, etc) - More path-related bugfixes + +2005-02-09 12:18 drobilla + + * src/canvas/Makefile.am: - Fixed problem with plugins sometimes + not showing up in Load Plugin window - Revamped OSC->Gtk event + stuff, much cleaner and should be significantly faster now too + +2005-02-01 17:59 drobilla + + * src/canvas/: Canvas.cpp, Canvas.h, CanvasController.h, + CanvasStateManager.h, Connection.cpp, Makefile.am, Module.cpp, + Module.h, PatchBayArea.cpp, PatchBayArea.h, Port.cpp, Port.h, + constants.h: - Cleaned up much code in the GUI - Removed redudant + files/classes - Cleaned up the canvas widget for use by other + apps (ie Patchage) + +2005-01-26 20:37 drobilla + + * src/canvas/: Connection.cpp, Connection.h, Module.cpp, Module.h, + PatchBayArea.cpp, Port.cpp, Port.h: - Pretty crucial node + removing bug fix - Better solution to the connection/node-remove + lock problem - GUI visual tweaks (modules, etc) + +2005-01-25 13:07 drobilla + + * src/canvas/PatchBayArea.cpp: - Fixed many bugs - Re-enabled MIDI + trigger node + +2005-01-23 18:23 drobilla + + * src/canvas/: Module.cpp, Module.h, PatchBayArea.cpp, + PatchBayArea.h, Port.h: - Bugfixes - Made the engine capable of + handingg lots (and lots) of incoming connections etc (ie in the + case of Patch Loading, which was always pretty random until + now) - Switched the canvas stuff from using vectors to using map + like they obviously should (searching by name and all) - Kinda + sorta support for the client launching the engine, but not + really. :) + +2005-01-22 21:45 drobilla + + * src/canvas/: Module.h, PatchBayArea.cpp, Port.cpp: - OSC + communication stuff converging on the final solution, I think... + - Started work on client being able to reattach to running server + - MIDI bindings now update control sliders in control dialog - + Um.. bunch of other stuff. It's 6am, I can't remember. ;) + +2005-01-20 18:27 drobilla + + * src/canvas/: Module.cpp, Module.h, PatchBayArea.cpp, + PatchBayArea.h, README: Partially through the reworking of the + OSC communication stuff (finally!) Multiple client support almost + a reality Added simple om_patch_loader command line client MIDI + Binding saving Made controls in patch file part of a "preset" + Added preliminary concept of metadata + +2005-01-18 20:26 drobilla + + * src/canvas/Module.h: - MIDI binding range changing support + +2005-01-17 19:35 drobilla + + * src/canvas/: Module.cpp, Module.h, PatchBayArea.cpp, + PatchBayArea.h, Port.cpp, Port.h: - Preliminary MIDI binding (no + learn yet) - Minor refactoring everywhere - Some work on + subpatching, still not working though + +2005-01-11 18:50 drobilla + + * src/canvas/: CanvasController.h, Module.cpp, Module.h, + PatchBayArea.cpp, PatchBayArea.h, Port.cpp, Port.h: - Proper + voice stealing for polyphony - Multiple top-level patch support - + Fixed patch loading/saving - Added polyphonic information to + patch loading/saving + +2005-01-07 18:33 drobilla + + * src/canvas/: CanvasController.h, Module.cpp, Module.h, + PatchBayArea.cpp, PatchBayArea.h: - LOTS of changes, mostly + toward subpatching - Patch loading currently broken - Refactored + canvas widget API - Separated connection logic in engine - More + +2004-12-06 06:06 drobilla + + * src/canvas/Makefile.in: Removed a bunch of generated files from + CVS to make incoming patches manageable. + +2004-11-24 16:03 drobilla + + * src/canvas/: Connection.h, Module.cpp, Module.h, + PatchBayArea.cpp, PatchBayArea.h, Port.cpp, Port.h: - More work + on the event system - Created node tree, nodes in patch now + stored in one - Node adding now event-ized. Still has some + problems but you can add a node while the patch is running - + Lots of cleanup work in the PatchBayArea canvas widget + +2004-11-21 10:11 drobilla + + * src/canvas/PatchBayArea.cpp: - Added support for patch destroying + in both engine and gtk client + +2004-11-19 18:25 drobilla + + * src/canvas/: PatchBayArea.cpp, PatchBayArea.h: Node removing + support. + +2004-11-19 15:14 drobilla + + * src/canvas/: CanvasController.h, PatchBayArea.cpp, + PatchBayArea.h: Added support for disconnecting, numerous other + fixes. + +2004-11-15 19:19 drobilla + + * src/canvas/: Module.cpp, Module.h, PatchBayArea.cpp: Moved patch + loading stuff (PatchLibrarian) from gtk client to libomclient, so + all clients can use it. + + Did some more generic-izing of the client stuff, and separated + the control of the client from the status updates from the engine + (ie so multiple clients can control one engine and reflect each + other's changes) + + This that and the other thing.. + +2004-11-06 09:15 drobilla + + * src/canvas/: Module.cpp, Module.h, PatchBayArea.cpp, + PatchBayArea.h, Port.h: - More client fixes, connections now work + again - Replaced lots of #includes with forward class + declarations - reduces compile time drastically - More cleanups + +2004-11-05 20:15 drobilla + + * src/canvas/: CanvasController.h, CanvasStateManager.h, + Connection.h, Makefile.am, Makefile.in, Module.cpp, Module.h, + ModuleBox.cpp, ModuleBox.h, PatchBayArea.cpp, PatchBayArea.h, + Port.cpp, Port.h: Refactored om_gtk to facilitate multiple open + patch windows (eventually). Many other changes, cleanups, API + changes, etc. + +2004-11-01 07:05 drobilla + + * src/canvas/: PatchBayArea.cpp, PatchBayArea.h: Added preliminary + MIDI trigger node, added audio in node, minor cleanup. + +2004-10-29 16:10 drobilla + + * src/canvas/: Canvas.cpp, Canvas.h, CanvasController.h, + CanvasStateManager.h, Connection.cpp, Connection.h, Makefile.am, + Makefile.in, Module.cpp, Module.h, ModuleBox.cpp, ModuleBox.h, + PatchBayArea.cpp, PatchBayArea.h, Port.cpp, Port.h, README, + constants.h: Initial checkin. + diff --git a/Doxyfile b/Doxyfile new file mode 100644 index 0000000..cfc321a --- /dev/null +++ b/Doxyfile @@ -0,0 +1,1153 @@ +# Doxyfile 1.3.8 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project +# +# All text after a hash (#) is considered a comment and will be ignored +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" ") + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. + +PROJECT_NAME = Om + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = 0.0.1 + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = doc + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of source +# files, where putting all generated files in the same directory would otherwise +# cause performance problems for the file system. + +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, +# Dutch, Finnish, French, German, Greek, Hungarian, Italian, Japanese, +# Japanese-en (Japanese with English messages), Korean, Korean-en, Norwegian, +# Polish, Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish, +# Swedish, and Ukrainian. + +OUTPUT_LANGUAGE = English + +# This tag can be used to specify the encoding used in the generated output. +# The encoding is not always determined by the language that is chosen, +# but also whether or not the output is meant for Windows or non-Windows users. +# In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES +# forces the Windows encoding (this is the default for the Windows binary), +# whereas setting the tag to NO uses a Unix-style encoding (the default for +# all platforms other than Windows). + +USE_WINDOWS_ENCODING = NO + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is used +# as the annotated text. Otherwise, the brief description is used as-is. If left +# blank, the following values are used ("$name" is automatically replaced with the +# name of the entity): "The $name class" "The $name widget" "The $name file" +# "is" "provides" "specifies" "contains" "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all inherited +# members of a class in the documentation of that class as if those members were +# ordinary class members. Constructors, destructors and assignment operators of +# the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = YES + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful is your file systems +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like the Qt-style comments (thus requiring an +# explicit @brief command for a brief description. + +JAVADOC_AUTOBRIEF = YES + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the DETAILS_AT_TOP tag is set to YES then Doxygen +# will output the detailed description near the top, like JavaDoc. +# If set to NO, the detailed description appears after the member +# documentation. + +DETAILS_AT_TOP = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 4 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources +# only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = NO + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java sources +# only. Doxygen will then generate output that is more tailored for Java. +# For instance, namespaces will be presented as packages, qualified scopes +# will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = YES + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = YES + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = NO + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = NO + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = YES + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or define consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and defines in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = NO + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = src + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx *.hpp +# *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm + +FILE_PATTERNS = + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = NO + +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or directories +# that are symbolic links (a Unix filesystem feature) are excluded from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. + +EXCLUDE_PATTERNS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command <filter> <input-file>, where <filter> +# is the value of the INPUT_FILTER tag, and <input-file> is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. If FILTER_PATTERNS is specified, this tag will be +# ignored. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER +# is applied to all files. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. + +SOURCE_BROWSER = NO + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES (the default) +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = YES + +# If the REFERENCES_RELATION tag is set to YES (the default) +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = YES + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = NO + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own +# stylesheet in the HTML output directory as well, or it will be erased! + +HTML_STYLESHEET = + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + +HTML_ALIGN_MEMBERS = YES + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + +DISABLE_INDEX = NO + +# This tag can be used to set the number of enum values (range [1..20]) +# that doxygen will group on one line in the generated HTML documentation. + +ENUM_VALUES_PER_LINE = 4 + +# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be +# generated containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, +# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are +# probably better off using the HTML help feature. + +GENERATE_TREEVIEW = NO + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = NO + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, a4wide, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4wide + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = NO + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = NO + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. This is useful +# if you want to understand what is going on. On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_PREDEFINED tags. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# in the INCLUDE_PATH (see below) will be search if a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. + +PREDEFINED = + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all function-like macros that are alone +# on a line, have an all uppercase name, and do not end with a semicolon. Such +# function macros are typically used for boiler-plate code, and will confuse the +# parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. +# Optionally an initial location of the external documentation +# can be added for each tagfile. The format of a tag file without +# this location is as follows: +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths or +# URLs. If a location is present for each tag, the installdox tool +# does not have to be run to correct the links. +# Note that each tag file must have a unique name +# (where the name does NOT include the path) +# If a tag file is not located in the directory in which doxygen +# is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base or +# super classes. Setting the tag to NO turns the diagrams off. Note that this +# option is superseded by the HAVE_DOT option below. This is only a fallback. It is +# recommended to install and use dot, since it yields more powerful graphs. + +CLASS_DIAGRAMS = YES + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = YES + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# the CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will +# generate a call dependency graph for every global function or class method. +# Note that enabling this option will significantly increase the time of a run. +# So in most cases it will be better to enable call graphs for selected +# functions only using the \callgraph command. + +CALL_GRAPH = NO + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are png, jpg, or gif +# If left blank png will be used. + +DOT_IMAGE_FORMAT = png + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found on the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width +# (in pixels) of the graphs generated by dot. If a graph becomes larger than +# this value, doxygen will try to truncate the graph, so that it fits within +# the specified constraint. Beware that most browsers cannot cope with very +# large images. + +MAX_DOT_GRAPH_WIDTH = 1024 + +# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height +# (in pixels) of the graphs generated by dot. If a graph becomes larger than +# this value, doxygen will try to truncate the graph, so that it fits within +# the specified constraint. Beware that most browsers cannot cope with very +# large images. + +MAX_DOT_GRAPH_HEIGHT = 1024 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes that +# lay further from the root node will be omitted. Note that setting this option to +# 1 or 2 may greatly reduce the computation time needed for large code bases. Also +# note that a graph may be further truncated if the graph's image dimensions are +# not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH and MAX_DOT_GRAPH_HEIGHT). +# If 0 is used for the depth value (the default), the graph is not depth-constrained. + +MAX_DOT_GRAPH_DEPTH = 0 + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to the search engine +#--------------------------------------------------------------------------- + +# The SEARCHENGINE tag specifies whether or not a search engine should be +# used. If set to NO the values of all tags below this one will be ignored. + +SEARCHENGINE = NO diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..2ca5b07 --- /dev/null +++ b/Makefile.am @@ -0,0 +1,4 @@ +SUBDIRS = src + +doc: Doxyfile src/*.h src/*.cpp + doxygen @@ -0,0 +1,42 @@ +Patchage NEWS file + +0.2.4: + * Multiple module selection/moving + +0.2.3: + * Updated LASH support for LASH 0.5.0 + * Smarter module creation (modules not split unecessarily) + +0.2.2: + * Fixed blatant segfault bug (0.2.1 is unusable) + +0.2.1: + * Fixed "disconnect all" not working for Jack ports + * Minor GUI aesthetic improvements + * Preliminary LASH support + +0.2.0: + * Added ALSA midi patching + * Numerous crashes fixed + * Canvas widget overhauled (because of Om) + +0.1.0: + * Fixed refresh segfault problem properly, shouldn't be any more segfaults + * Added connection hiliting, mouse over a port and it's connections hilite + * Added drag-to-make-connection, Pd style + +0.0.4: + * You can now load patchage without installing (run from src directory) + * Fixed numerous bugs (segfaults) + +0.0.3: + * UI enhancements (switched UI to libglade) + * code cleanup (heavy overhaul) + * state saving (window location/size, modules location/size) + * put actual content in NEWS, ChangeLog, etc + +0.0.2: + * zoom support + +0.0.1: + * initial release @@ -0,0 +1 @@ +This is Patchage, a modular patch bay for Jack audio and Alsa Midi. @@ -0,0 +1,12 @@ +- Robert Ham + - For alsa-patch-bay and jack-patch-bay, which much code + was.... influenced.... by.. :) + +- Alessandro Cominu ("Comix") + - Thought of the zoom idea + +- Steve Harris + - Many good ideas, bug reports + +- pasp@ll.pl (?) + - Bug reports, ideas diff --git a/aclocal.m4 b/aclocal.m4 new file mode 100644 index 0000000..bc2e921 --- /dev/null +++ b/aclocal.m4 @@ -0,0 +1,1007 @@ +# generated automatically by aclocal 1.9.6 -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, +# 2005 Free Software Foundation, Inc. +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- +# +# Copyright © 2004 Scott James Remnant <scott@netsplit.com>. +# +# 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. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# PKG_PROG_PKG_CONFIG([MIN-VERSION]) +# ---------------------------------- +AC_DEFUN([PKG_PROG_PKG_CONFIG], +[m4_pattern_forbid([^_?PKG_[A-Z_]+$]) +m4_pattern_allow([^PKG_CONFIG(_PATH)?$]) +AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility])dnl +if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then + AC_PATH_TOOL([PKG_CONFIG], [pkg-config]) +fi +if test -n "$PKG_CONFIG"; then + _pkg_min_version=m4_default([$1], [0.9.0]) + AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version]) + if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + PKG_CONFIG="" + fi + +fi[]dnl +])# PKG_PROG_PKG_CONFIG + +# PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) +# +# Check to see whether a particular set of modules exists. Similar +# to PKG_CHECK_MODULES(), but does not set variables or print errors. +# +# +# Similar to PKG_CHECK_MODULES, make sure that the first instance of +# this or PKG_CHECK_MODULES is called, or make sure to call +# PKG_CHECK_EXISTS manually +# -------------------------------------------------------------- +AC_DEFUN([PKG_CHECK_EXISTS], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +if test -n "$PKG_CONFIG" && \ + AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then + m4_ifval([$2], [$2], [:]) +m4_ifvaln([$3], [else + $3])dnl +fi]) + + +# _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES]) +# --------------------------------------------- +m4_define([_PKG_CONFIG], +[if test -n "$PKG_CONFIG"; then + if test -n "$$1"; then + pkg_cv_[]$1="$$1" + else + PKG_CHECK_EXISTS([$3], + [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null`], + [pkg_failed=yes]) + fi +else + pkg_failed=untried +fi[]dnl +])# _PKG_CONFIG + +# _PKG_SHORT_ERRORS_SUPPORTED +# ----------------------------- +AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG]) +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi[]dnl +])# _PKG_SHORT_ERRORS_SUPPORTED + + +# PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], +# [ACTION-IF-NOT-FOUND]) +# +# +# Note that if there is a possibility the first call to +# PKG_CHECK_MODULES might not happen, you should be sure to include an +# explicit call to PKG_PROG_PKG_CONFIG in your configure.ac +# +# +# -------------------------------------------------------------- +AC_DEFUN([PKG_CHECK_MODULES], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl +AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl + +pkg_failed=no +AC_MSG_CHECKING([for $1]) + +_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2]) +_PKG_CONFIG([$1][_LIBS], [libs], [$2]) + +m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS +and $1[]_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details.]) + +if test $pkg_failed = yes; then + _PKG_SHORT_ERRORS_SUPPORTED + if test $_pkg_short_errors_supported = yes; then + $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --errors-to-stdout --print-errors "$2"` + else + $1[]_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "$2"` + fi + # Put the nasty error message in config.log where it belongs + echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD + + ifelse([$4], , [AC_MSG_ERROR(dnl +[Package requirements ($2) were not met: + +$$1_PKG_ERRORS + +Consider adjusting the PKG_CONFIG_PATH environment variable if you +installed software in a non-standard prefix. + +_PKG_TEXT +])], + [$4]) +elif test $pkg_failed = untried; then + ifelse([$4], , [AC_MSG_FAILURE(dnl +[The pkg-config script could not be found or is too old. Make sure it +is in your PATH or set the PKG_CONFIG environment variable to the full +path to pkg-config. + +_PKG_TEXT + +To get pkg-config, see <http://www.freedesktop.org/software/pkgconfig>.])], + [$4]) +else + $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS + $1[]_LIBS=$pkg_cv_[]$1[]_LIBS + AC_MSG_RESULT([yes]) + ifelse([$3], , :, [$3]) +fi[]dnl +])# PKG_CHECK_MODULES + +# Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_AUTOMAKE_VERSION(VERSION) +# ---------------------------- +# Automake X.Y traces this macro to ensure aclocal.m4 has been +# generated from the m4 files accompanying Automake X.Y. +AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version="1.9"]) + +# AM_SET_CURRENT_AUTOMAKE_VERSION +# ------------------------------- +# Call AM_AUTOMAKE_VERSION so it can be traced. +# This function is AC_REQUIREd by AC_INIT_AUTOMAKE. +AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], + [AM_AUTOMAKE_VERSION([1.9.6])]) + +# AM_AUX_DIR_EXPAND -*- Autoconf -*- + +# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets +# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to +# `$srcdir', `$srcdir/..', or `$srcdir/../..'. +# +# Of course, Automake must honor this variable whenever it calls a +# tool from the auxiliary directory. The problem is that $srcdir (and +# therefore $ac_aux_dir as well) can be either absolute or relative, +# depending on how configure is run. This is pretty annoying, since +# it makes $ac_aux_dir quite unusable in subdirectories: in the top +# source directory, any form will work fine, but in subdirectories a +# relative path needs to be adjusted first. +# +# $ac_aux_dir/missing +# fails when called from a subdirectory if $ac_aux_dir is relative +# $top_srcdir/$ac_aux_dir/missing +# fails if $ac_aux_dir is absolute, +# fails when called from a subdirectory in a VPATH build with +# a relative $ac_aux_dir +# +# The reason of the latter failure is that $top_srcdir and $ac_aux_dir +# are both prefixed by $srcdir. In an in-source build this is usually +# harmless because $srcdir is `.', but things will broke when you +# start a VPATH build or use an absolute $srcdir. +# +# So we could use something similar to $top_srcdir/$ac_aux_dir/missing, +# iff we strip the leading $srcdir from $ac_aux_dir. That would be: +# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` +# and then we would define $MISSING as +# MISSING="\${SHELL} $am_aux_dir/missing" +# This will work as long as MISSING is not called from configure, because +# unfortunately $(top_srcdir) has no meaning in configure. +# However there are other variables, like CC, which are often used in +# configure, and could therefore not use this "fixed" $ac_aux_dir. +# +# Another solution, used here, is to always expand $ac_aux_dir to an +# absolute PATH. The drawback is that using absolute paths prevent a +# configured tree to be moved without reconfiguration. + +AC_DEFUN([AM_AUX_DIR_EXPAND], +[dnl Rely on autoconf to set up CDPATH properly. +AC_PREREQ([2.50])dnl +# expand $ac_aux_dir to an absolute path +am_aux_dir=`cd $ac_aux_dir && pwd` +]) + +# AM_CONDITIONAL -*- Autoconf -*- + +# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 7 + +# AM_CONDITIONAL(NAME, SHELL-CONDITION) +# ------------------------------------- +# Define a conditional. +AC_DEFUN([AM_CONDITIONAL], +[AC_PREREQ(2.52)dnl + ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], + [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl +AC_SUBST([$1_TRUE]) +AC_SUBST([$1_FALSE]) +if $2; then + $1_TRUE= + $1_FALSE='#' +else + $1_TRUE='#' + $1_FALSE= +fi +AC_CONFIG_COMMANDS_PRE( +[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then + AC_MSG_ERROR([[conditional "$1" was never defined. +Usually this means the macro was only invoked conditionally.]]) +fi])]) + + +# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 8 + +# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be +# written in clear, in which case automake, when reading aclocal.m4, +# will think it sees a *use*, and therefore will trigger all it's +# C support machinery. Also note that it means that autoscan, seeing +# CC etc. in the Makefile, will ask for an AC_PROG_CC use... + + +# _AM_DEPENDENCIES(NAME) +# ---------------------- +# See how the compiler implements dependency checking. +# NAME is "CC", "CXX", "GCJ", or "OBJC". +# We try a few techniques and use that to set a single cache variable. +# +# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was +# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular +# dependency, and given that the user is not expected to run this macro, +# just rely on AC_PROG_CC. +AC_DEFUN([_AM_DEPENDENCIES], +[AC_REQUIRE([AM_SET_DEPDIR])dnl +AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl +AC_REQUIRE([AM_MAKE_INCLUDE])dnl +AC_REQUIRE([AM_DEP_TRACK])dnl + +ifelse([$1], CC, [depcc="$CC" am_compiler_list=], + [$1], CXX, [depcc="$CXX" am_compiler_list=], + [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'], + [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'], + [depcc="$$1" am_compiler_list=]) + +AC_CACHE_CHECK([dependency style of $depcc], + [am_cv_$1_dependencies_compiler_type], +[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_$1_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` + fi + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + case $depmode in + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + none) break ;; + esac + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. + if depmode=$depmode \ + source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_$1_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_$1_dependencies_compiler_type=none +fi +]) +AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) +AM_CONDITIONAL([am__fastdep$1], [ + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) +]) + + +# AM_SET_DEPDIR +# ------------- +# Choose a directory name for dependency files. +# This macro is AC_REQUIREd in _AM_DEPENDENCIES +AC_DEFUN([AM_SET_DEPDIR], +[AC_REQUIRE([AM_SET_LEADING_DOT])dnl +AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl +]) + + +# AM_DEP_TRACK +# ------------ +AC_DEFUN([AM_DEP_TRACK], +[AC_ARG_ENABLE(dependency-tracking, +[ --disable-dependency-tracking speeds up one-time build + --enable-dependency-tracking do not reject slow dependency extractors]) +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' +fi +AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) +AC_SUBST([AMDEPBACKSLASH]) +]) + +# Generate code to set up dependency tracking. -*- Autoconf -*- + +# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +#serial 3 + +# _AM_OUTPUT_DEPENDENCY_COMMANDS +# ------------------------------ +AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], +[for mf in $CONFIG_FILES; do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named `Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # So let's grep whole file. + if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then + dirpart=`AS_DIRNAME("$mf")` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running `make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # When using ansi2knr, U may be empty or an underscore; expand it + U=`sed -n 's/^U = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`AS_DIRNAME(["$file"])` + AS_MKDIR_P([$dirpart/$fdir]) + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done +done +])# _AM_OUTPUT_DEPENDENCY_COMMANDS + + +# AM_OUTPUT_DEPENDENCY_COMMANDS +# ----------------------------- +# This macro should only be invoked once -- use via AC_REQUIRE. +# +# This code is only required when automatic dependency tracking +# is enabled. FIXME. This creates each `.P' file that we will +# need in order to bootstrap the dependency handling code. +AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], +[AC_CONFIG_COMMANDS([depfiles], + [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], + [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) +]) + +# Do all the work for Automake. -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 12 + +# This macro actually does too much. Some checks are only needed if +# your package does certain things. But this isn't really a big deal. + +# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) +# AM_INIT_AUTOMAKE([OPTIONS]) +# ----------------------------------------------- +# The call with PACKAGE and VERSION arguments is the old style +# call (pre autoconf-2.50), which is being phased out. PACKAGE +# and VERSION should now be passed to AC_INIT and removed from +# the call to AM_INIT_AUTOMAKE. +# We support both call styles for the transition. After +# the next Automake release, Autoconf can make the AC_INIT +# arguments mandatory, and then we can depend on a new Autoconf +# release and drop the old call support. +AC_DEFUN([AM_INIT_AUTOMAKE], +[AC_PREREQ([2.58])dnl +dnl Autoconf wants to disallow AM_ names. We explicitly allow +dnl the ones we care about. +m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl +AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl +AC_REQUIRE([AC_PROG_INSTALL])dnl +# test to see if srcdir already configured +if test "`cd $srcdir && pwd`" != "`pwd`" && + test -f $srcdir/config.status; then + AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi +AC_SUBST([CYGPATH_W]) + +# Define the identity of the package. +dnl Distinguish between old-style and new-style calls. +m4_ifval([$2], +[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl + AC_SUBST([PACKAGE], [$1])dnl + AC_SUBST([VERSION], [$2])], +[_AM_SET_OPTIONS([$1])dnl + AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl + AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl + +_AM_IF_OPTION([no-define],, +[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) + AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl + +# Some tools Automake needs. +AC_REQUIRE([AM_SANITY_CHECK])dnl +AC_REQUIRE([AC_ARG_PROGRAM])dnl +AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}) +AM_MISSING_PROG(AUTOCONF, autoconf) +AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}) +AM_MISSING_PROG(AUTOHEADER, autoheader) +AM_MISSING_PROG(MAKEINFO, makeinfo) +AM_PROG_INSTALL_SH +AM_PROG_INSTALL_STRIP +AC_REQUIRE([AM_PROG_MKDIR_P])dnl +# We need awk for the "check" target. The system "awk" is bad on +# some platforms. +AC_REQUIRE([AC_PROG_AWK])dnl +AC_REQUIRE([AC_PROG_MAKE_SET])dnl +AC_REQUIRE([AM_SET_LEADING_DOT])dnl +_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], + [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], + [_AM_PROG_TAR([v7])])]) +_AM_IF_OPTION([no-dependencies],, +[AC_PROVIDE_IFELSE([AC_PROG_CC], + [_AM_DEPENDENCIES(CC)], + [define([AC_PROG_CC], + defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl +AC_PROVIDE_IFELSE([AC_PROG_CXX], + [_AM_DEPENDENCIES(CXX)], + [define([AC_PROG_CXX], + defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl +]) +]) + + +# When config.status generates a header, we must update the stamp-h file. +# This file resides in the same directory as the config header +# that is generated. The stamp files are numbered to have different names. + +# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the +# loop where config.status creates the headers, so we can generate +# our stamp files there. +AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], +[# Compute $1's index in $config_headers. +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $1 | $1:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $1" >`AS_DIRNAME([$1])`/stamp-h[]$_am_stamp_count]) + +# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_INSTALL_SH +# ------------------ +# Define $install_sh. +AC_DEFUN([AM_PROG_INSTALL_SH], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +install_sh=${install_sh-"$am_aux_dir/install-sh"} +AC_SUBST(install_sh)]) + +# Copyright (C) 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 2 + +# Check whether the underlying file-system supports filenames +# with a leading dot. For instance MS-DOS doesn't. +AC_DEFUN([AM_SET_LEADING_DOT], +[rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null +AC_SUBST([am__leading_dot])]) + +# Check to see how 'make' treats includes. -*- Autoconf -*- + +# Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 3 + +# AM_MAKE_INCLUDE() +# ----------------- +# Check to see how make treats includes. +AC_DEFUN([AM_MAKE_INCLUDE], +[am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo done +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +AC_MSG_CHECKING([for style of include used by $am_make]) +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# We grep out `Entering directory' and `Leaving directory' +# messages which can occur if `w' ends up in MAKEFLAGS. +# In particular we don't look at `^make:' because GNU make might +# be invoked under some other name (usually "gmake"), in which +# case it prints its new name instead of `make'. +if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then + am__include=include + am__quote= + _am_result=GNU +fi +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then + am__include=.include + am__quote="\"" + _am_result=BSD + fi +fi +AC_SUBST([am__include]) +AC_SUBST([am__quote]) +AC_MSG_RESULT([$_am_result]) +rm -f confinc confmf +]) + +# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- + +# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2005 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 4 + +# AM_MISSING_PROG(NAME, PROGRAM) +# ------------------------------ +AC_DEFUN([AM_MISSING_PROG], +[AC_REQUIRE([AM_MISSING_HAS_RUN]) +$1=${$1-"${am_missing_run}$2"} +AC_SUBST($1)]) + + +# AM_MISSING_HAS_RUN +# ------------------ +# Define MISSING if not defined so far and test if it supports --run. +# If it does, set am_missing_run to use it, otherwise, to nothing. +AC_DEFUN([AM_MISSING_HAS_RUN], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing" +# Use eval to expand $SHELL +if eval "$MISSING --run true"; then + am_missing_run="$MISSING --run " +else + am_missing_run= + AC_MSG_WARN([`missing' script is too old or missing]) +fi +]) + +# Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_MKDIR_P +# --------------- +# Check whether `mkdir -p' is supported, fallback to mkinstalldirs otherwise. +# +# Automake 1.8 used `mkdir -m 0755 -p --' to ensure that directories +# created by `make install' are always world readable, even if the +# installer happens to have an overly restrictive umask (e.g. 077). +# This was a mistake. There are at least two reasons why we must not +# use `-m 0755': +# - it causes special bits like SGID to be ignored, +# - it may be too restrictive (some setups expect 775 directories). +# +# Do not use -m 0755 and let people choose whatever they expect by +# setting umask. +# +# We cannot accept any implementation of `mkdir' that recognizes `-p'. +# Some implementations (such as Solaris 8's) are not thread-safe: if a +# parallel make tries to run `mkdir -p a/b' and `mkdir -p a/c' +# concurrently, both version can detect that a/ is missing, but only +# one can create it and the other will error out. Consequently we +# restrict ourselves to GNU make (using the --version option ensures +# this.) +AC_DEFUN([AM_PROG_MKDIR_P], +[if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then + # We used to keeping the `.' as first argument, in order to + # allow $(mkdir_p) to be used without argument. As in + # $(mkdir_p) $(somedir) + # where $(somedir) is conditionally defined. However this is wrong + # for two reasons: + # 1. if the package is installed by a user who cannot write `.' + # make install will fail, + # 2. the above comment should most certainly read + # $(mkdir_p) $(DESTDIR)$(somedir) + # so it does not work when $(somedir) is undefined and + # $(DESTDIR) is not. + # To support the latter case, we have to write + # test -z "$(somedir)" || $(mkdir_p) $(DESTDIR)$(somedir), + # so the `.' trick is pointless. + mkdir_p='mkdir -p --' +else + # On NextStep and OpenStep, the `mkdir' command does not + # recognize any option. It will interpret all options as + # directories to create, and then abort because `.' already + # exists. + for d in ./-p ./--version; + do + test -d $d && rmdir $d + done + # $(mkinstalldirs) is defined by Automake if mkinstalldirs exists. + if test -f "$ac_aux_dir/mkinstalldirs"; then + mkdir_p='$(mkinstalldirs)' + else + mkdir_p='$(install_sh) -d' + fi +fi +AC_SUBST([mkdir_p])]) + +# Helper functions for option handling. -*- Autoconf -*- + +# Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 3 + +# _AM_MANGLE_OPTION(NAME) +# ----------------------- +AC_DEFUN([_AM_MANGLE_OPTION], +[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) + +# _AM_SET_OPTION(NAME) +# ------------------------------ +# Set option NAME. Presently that only means defining a flag for this option. +AC_DEFUN([_AM_SET_OPTION], +[m4_define(_AM_MANGLE_OPTION([$1]), 1)]) + +# _AM_SET_OPTIONS(OPTIONS) +# ---------------------------------- +# OPTIONS is a space-separated list of Automake options. +AC_DEFUN([_AM_SET_OPTIONS], +[AC_FOREACH([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) + +# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) +# ------------------------------------------- +# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. +AC_DEFUN([_AM_IF_OPTION], +[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) + +# Check to make sure that the build environment is sane. -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 4 + +# AM_SANITY_CHECK +# --------------- +AC_DEFUN([AM_SANITY_CHECK], +[AC_MSG_CHECKING([whether build environment is sane]) +# Just in case +sleep 1 +echo timestamp > conftest.file +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null` + if test "$[*]" = "X"; then + # -L didn't work. + set X `ls -t $srcdir/configure conftest.file` + fi + rm -f conftest.file + if test "$[*]" != "X $srcdir/configure conftest.file" \ + && test "$[*]" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken +alias in your environment]) + fi + + test "$[2]" = conftest.file + ) +then + # Ok. + : +else + AC_MSG_ERROR([newly created file is older than distributed files! +Check your system clock]) +fi +AC_MSG_RESULT(yes)]) + +# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_INSTALL_STRIP +# --------------------- +# One issue with vendor `install' (even GNU) is that you can't +# specify the program used to strip binaries. This is especially +# annoying in cross-compiling environments, where the build's strip +# is unlikely to handle the host's binaries. +# Fortunately install-sh will honor a STRIPPROG variable, so we +# always use install-sh in `make install-strip', and initialize +# STRIPPROG with the value of the STRIP variable (set by the user). +AC_DEFUN([AM_PROG_INSTALL_STRIP], +[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +# Installed binaries are usually stripped using `strip' when the user +# run `make install-strip'. However `strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the `STRIP' environment variable to overrule this program. +dnl Don't test for $cross_compiling = yes, because it might be `maybe'. +if test "$cross_compiling" != no; then + AC_CHECK_TOOL([STRIP], [strip], :) +fi +INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s" +AC_SUBST([INSTALL_STRIP_PROGRAM])]) + +# Check how to create a tarball. -*- Autoconf -*- + +# Copyright (C) 2004, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 2 + +# _AM_PROG_TAR(FORMAT) +# -------------------- +# Check how to create a tarball in format FORMAT. +# FORMAT should be one of `v7', `ustar', or `pax'. +# +# Substitute a variable $(am__tar) that is a command +# writing to stdout a FORMAT-tarball containing the directory +# $tardir. +# tardir=directory && $(am__tar) > result.tar +# +# Substitute a variable $(am__untar) that extract such +# a tarball read from stdin. +# $(am__untar) < result.tar +AC_DEFUN([_AM_PROG_TAR], +[# Always define AMTAR for backward compatibility. +AM_MISSING_PROG([AMTAR], [tar]) +m4_if([$1], [v7], + [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'], + [m4_case([$1], [ustar],, [pax],, + [m4_fatal([Unknown tar format])]) +AC_MSG_CHECKING([how to create a $1 tar archive]) +# Loop over all known methods to create a tar archive until one works. +_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' +_am_tools=${am_cv_prog_tar_$1-$_am_tools} +# Do not fold the above two line into one, because Tru64 sh and +# Solaris sh will not grok spaces in the rhs of `-'. +for _am_tool in $_am_tools +do + case $_am_tool in + gnutar) + for _am_tar in tar gnutar gtar; + do + AM_RUN_LOG([$_am_tar --version]) && break + done + am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' + am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' + am__untar="$_am_tar -xf -" + ;; + plaintar) + # Must skip GNU tar: if it does not support --format= it doesn't create + # ustar tarball either. + (tar --version) >/dev/null 2>&1 && continue + am__tar='tar chf - "$$tardir"' + am__tar_='tar chf - "$tardir"' + am__untar='tar xf -' + ;; + pax) + am__tar='pax -L -x $1 -w "$$tardir"' + am__tar_='pax -L -x $1 -w "$tardir"' + am__untar='pax -r' + ;; + cpio) + am__tar='find "$$tardir" -print | cpio -o -H $1 -L' + am__tar_='find "$tardir" -print | cpio -o -H $1 -L' + am__untar='cpio -i -H $1 -d' + ;; + none) + am__tar=false + am__tar_=false + am__untar=false + ;; + esac + + # If the value was cached, stop now. We just wanted to have am__tar + # and am__untar set. + test -n "${am_cv_prog_tar_$1}" && break + + # tar/untar a dummy directory, and stop if the command works + rm -rf conftest.dir + mkdir conftest.dir + echo GrepMe > conftest.dir/file + AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) + rm -rf conftest.dir + if test -s conftest.tar; then + AM_RUN_LOG([$am__untar <conftest.tar]) + grep GrepMe conftest.dir/file >/dev/null 2>&1 && break + fi +done +rm -rf conftest.dir + +AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) +AC_MSG_RESULT([$am_cv_prog_tar_$1])]) +AC_SUBST([am__tar]) +AC_SUBST([am__untar]) +]) # _AM_PROG_TAR + diff --git a/autogen.sh b/autogen.sh new file mode 100755 index 0000000..68d4273 --- /dev/null +++ b/autogen.sh @@ -0,0 +1,6 @@ +#!/bin/sh + +aclocal-1.9 +autoheader -Wall +automake-1.9 --gnu --add-missing -Wall +autoconf -Wall diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..2e0c9cd --- /dev/null +++ b/configure.ac @@ -0,0 +1,117 @@ +# configure.in for patchage + +AC_INIT(patchage, 0.2.4pre, drobilla@connect.carleton.ca) +AC_CONFIG_SRCDIR([src/main.cpp]) +AC_CONFIG_HEADER([config.h]) +AM_INIT_AUTOMAKE + +# Checks for compilers +AC_PROG_CXX + +# Check other stuff.. +AC_TYPE_SIZE_T +AC_CHECK_FUNCS([strerror]) + +# Check for pthreads +AC_CHECK_LIB(pthread, pthread_create, [], + AC_MSG_ERROR([*** Patchage requires POSIX threads support])) +AC_CHECK_HEADER([pthread.h]) + +# Check for FlowCanvas +PKG_CHECK_MODULES(FLOWCANVAS, flowcanvas >= 0.1.0) +AC_SUBST(FLOWCANVAS_CFLAGS) +AC_SUBST(FLOWCANVAS_LIBS) + +# Check for Jack +PKG_CHECK_MODULES(JACK, jack >= 0.100.0) + +# Check for ALSA +enable_alsa="yes" +AC_ARG_ENABLE(alsa, +[AS_HELP_STRING(--enable-alsa, [Enable Alsa MIDI driver (yes)])], +[ enable_alsa="$enableval" ] +) + +if test "$enable_alsa" = "yes"; then + AC_CHECK_LIB(asound, snd_seq_open, ALSA_FOUND="yes", ALSA_FOUND="no", -lm -ldl -lpthread) + + if test "$ALSA_FOUND" = "yes"; then + AC_DEFINE(HAVE_ALSA, 1, [whether or not we have alsa]) + ALSA_CFLAGS="" + ALSA_LIBS="-lasound -lm -ldl -lpthread" + AC_SUBST(ALSA_CFLAGS) + AC_SUBST(ALSA_LIBS) + fi +else + ALSA_FOUND="no" +fi +AM_CONDITIONAL(ALSA, test "$ALSA_FOUND" = "yes") + +# LASH config option +build_lash="yes" +AC_ARG_ENABLE(lash, + [AS_HELP_STRING(--enable-lash, [Enable LASH session management support (yes)])], + [ if test x$enable_lash = xno ; then build_lash=no ; fi ]) + +have_lash="no" +if test "$build_lash" = "yes"; then + PKG_CHECK_MODULES(LASH, lash-1.0 >= 0.5.0, have_lash="yes", have_lash="no") +fi +if test "$have_lash" = "yes"; then + AC_DEFINE(HAVE_LASH, 1, [Has lash.h]) + AC_SUBST(LASH_CFLAGS) + AC_SUBST(LASH_LIBS) +else + AC_MSG_WARN([LASH not found, session support will not be built.]) +fi +AM_CONDITIONAL(WITH_LASH, [test "$have_lash" = "yes"]) + + +# Check for debugging flag +debug="no" +AC_ARG_ENABLE(debug, + [AS_HELP_STRING(--enable-debug, [Enable debugging (no)])], + [debug="$enableval"]) +if test "$debug" = "yes"; then + # Useless POS gnomecanvasmm doesn't build w/ -pedantic + CFLAGS="-O1 -g -DDEBUG" + CXXFLAGS="$CFLAGS" +else + CFLAGS="$CFLAGS -DNDEBUG" + CXXFLAGS="$CFLAGS -DNDEBUG" +fi + +# Check for strict flag +strict="no" +AC_ARG_ENABLE(strict, + [AS_HELP_STRING(--enable-strict, [Enable strict compiler warnings or errors (no)])], + [strict="$enableval"]) +if test "$strict" = "yes"; then + # Useless POS gnomecanvasmm doesn't build w/ -pedantic + CFLAGS="$CFLAGS -ansi -Wall -Wconversion -Winit-self" + CXXFLAGS="$CXXFLAGS -ansi -Wall -Wconversion -Winit-self -Woverloaded-virtual -Wsign-promo" +fi + +# Bolt on a few specific flags to CXXFLAGS that should always be used +CXXFLAGS="$CXXFLAGS -pipe -Wall -fmessage-length=139 -fdiagnostics-show-location=every-line" +CFLAGS="$CFLAGS -pipe -Wall -fmessage-length=139 -fdiagnostics-show-location=every-line" + +# Check for GTKMM +PKG_CHECK_MODULES(GTKMM, gtkmm-2.4) +AC_SUBST(GTKMM_CFLAGS) +AC_SUBST(GTKMM_LIBS) + +# Check for gnomecanvasmm +PKG_CHECK_MODULES(GNOMECANVASMM, libgnomecanvasmm-2.6) +AC_SUBST(GNOMECANVASMM_CFLAGS) +AC_SUBST(GNOMECANVASMM_LIBS) + +# Check for libglademm +PKG_CHECK_MODULES(LIBGLADEMM, libglademm-2.4) +AC_SUBST(LIBGLADEMM_CFLAGS) +AC_SUBST(LIBGLADEMM_LIBS) + +# Write it! +AC_CONFIG_FILES([Makefile]) +AC_CONFIG_FILES([src/Makefile]) +AC_OUTPUT diff --git a/src/AlsaDriver.cpp b/src/AlsaDriver.cpp new file mode 100644 index 0000000..2f4d52e --- /dev/null +++ b/src/AlsaDriver.cpp @@ -0,0 +1,484 @@ +/* This file is part of Patchage. Copyright (C) 2005 Dave Robillard. + * + * Om 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. + * + * Om 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 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 <string> +#include <iostream> +#include <cassert> +#include <sys/poll.h> +#include <errno.h> +#include "PatchageFlowCanvas.h" +#include "AlsaDriver.h" +#include "Patchage.h" +#include "PatchageModule.h" +#include "PatchagePort.h" + +using std::cerr; +using std::string; + + +using namespace LibFlowCanvas; + +AlsaDriver::AlsaDriver(Patchage* app) +: m_app(app), + m_canvas(app->canvas()), + m_seq(NULL) +{ +} + + +AlsaDriver::~AlsaDriver() +{ + detach(); +} + + +/** Attach to ALSA. + * @a launch_daemon is ignored, as ALSA has no daemon to launch/connect to. + */ +void +AlsaDriver::attach(bool launch_daemon) +{ + cout << "Connecting to Alsa... "; + cout.flush(); + + int ret = snd_seq_open(&m_seq, "default", + SND_SEQ_OPEN_DUPLEX, + SND_SEQ_NONBLOCK); + if (ret) { + cout << "Failed" << endl; + m_seq = NULL; + } else { + cout << "Connected" << endl; + + snd_seq_set_client_name(m_seq, "Patchage"); + + ret = pthread_create(&m_refresh_thread, NULL, &AlsaDriver::refresh_main, this); + if (ret) + cerr << "Couldn't start refresh thread" << endl; + } +} + + +void +AlsaDriver::detach() +{ + if (m_seq != NULL) { + pthread_cancel(m_refresh_thread); + pthread_join(m_refresh_thread, NULL); + snd_seq_close(m_seq); + m_seq = NULL; + cout << "Disconnected from Alsa" << endl; + } +} + + +/** Refresh all Alsa Midi ports and connections. + */ +void +AlsaDriver::refresh() +{ + if (!is_attached()) + return; + + assert(m_seq); + + refresh_ports(); + refresh_connections(); + + undirty(); +} + + +/** Refresh all Alsa Midi ports. + */ +void +AlsaDriver::refresh_ports() +{ + assert(is_attached()); + assert(m_seq); + + snd_seq_client_info_t* cinfo; + snd_seq_client_info_alloca(&cinfo); + snd_seq_client_info_set_client(cinfo, -1); + + snd_seq_port_info_t * pinfo; + snd_seq_port_info_alloca(&pinfo); + + string client_name; + string port_name; + bool is_input = false; + bool is_duplex = false; + bool is_application = true; + + while (snd_seq_query_next_client (m_seq, cinfo) >= 0) { + snd_seq_port_info_set_client(pinfo, snd_seq_client_info_get_client(cinfo)); + snd_seq_port_info_set_port(pinfo, -1); + + client_name = snd_seq_client_info_get_name(cinfo); + + while (snd_seq_query_next_port(m_seq, pinfo) >= 0) { + int caps = snd_seq_port_info_get_capability(pinfo); + int type = snd_seq_port_info_get_type(pinfo); + + // Skip ports we shouldn't show + if (caps & SND_SEQ_PORT_CAP_NO_EXPORT) + continue; + else if ( !( (caps & SND_SEQ_PORT_CAP_READ) + || (caps & SND_SEQ_PORT_CAP_WRITE) + || (caps & SND_SEQ_PORT_CAP_DUPLEX))) + continue; + else if ((snd_seq_client_info_get_type(cinfo) != SND_SEQ_USER_CLIENT) + && ((type == SND_SEQ_PORT_SYSTEM_TIMER + || type == SND_SEQ_PORT_SYSTEM_ANNOUNCE))) + continue; + + const snd_seq_addr_t addr = *snd_seq_port_info_get_addr(pinfo); + + is_duplex = false; + + // FIXME: Should be CAP_SUBS_READ etc? + if ((caps & SND_SEQ_PORT_CAP_READ) && (caps & SND_SEQ_PORT_CAP_WRITE)) + is_duplex = true; + else if (caps & SND_SEQ_PORT_CAP_READ) + is_input = false; + else if (caps & SND_SEQ_PORT_CAP_WRITE) + is_input = true; + + is_application = (type & SND_SEQ_PORT_TYPE_APPLICATION); + port_name = snd_seq_port_info_get_name(pinfo); + PatchageModule* m = NULL; + + //cout << client_name << " : " << port_name << " is_application = " << is_application + // << " is_duplex = " << is_duplex << endl; + + bool split = m_app->state_manager()->get_module_split(client_name, !is_application); + + // Application input/output ports go on the same module + if (!split) { + m = (PatchageModule*)m_canvas->find_module(client_name, InputOutput); + if (m == NULL) { + m = new PatchageModule(m_app, client_name, InputOutput); + m->load_location(); + m->store_location(); + m_canvas->add_module(m); + } + + if (!is_duplex) { + m->add_patchage_port(port_name, is_input, ALSA_MIDI, addr); + } else { + m->add_patchage_port(port_name, true, ALSA_MIDI, addr); + m->add_patchage_port(port_name, false, ALSA_MIDI, addr); + } + } else { // non-application input/output ports (hw interface, etc) go on separate modules + PatchageModule* m = NULL; + ModuleType type = InputOutput; + + // The 'application' hint isn't always set by clients, so this bit + // is pretty nasty... + + if (!is_duplex) { // just one port to add + if (is_input) type = Input; + else type = Output; + + // See if an InputOutput module exists (maybe with Jack ports on it) + m = (PatchageModule*)m_canvas->find_module(client_name, InputOutput); + + if (m == NULL) + m = (PatchageModule*)m_canvas->find_module(client_name, type); + if (m == NULL) { + m = new PatchageModule(m_app, client_name, type); + m->load_location(); + m->store_location(); + m_canvas->add_module(m); + } + m->add_patchage_port(port_name, is_input, ALSA_MIDI, addr); + } else { // two ports to add + type = Input; + + // See if an InputOutput module exists (maybe with Jack ports on it) + m = (PatchageModule*)m_canvas->find_module(client_name, InputOutput); + + if (m == NULL) + m = (PatchageModule*)m_canvas->find_module(client_name, type); + if (m == NULL) { + m = new PatchageModule(m_app, client_name, type); + m->load_location(); + m->store_location(); + m_canvas->add_module(m); + } + m->add_patchage_port(port_name, true, ALSA_MIDI, addr); + + type = Output; + + // See if an InputOutput module exists (maybe with Jack ports on it) + m = (PatchageModule*)m_canvas->find_module(client_name, InputOutput); + + if (m == NULL) + m = (PatchageModule*)m_canvas->find_module(client_name, type); + if (m == NULL) { + m = new PatchageModule(m_app, client_name, type); + m->load_location(); + m->store_location(); + m_canvas->add_module(m); + } + m->add_patchage_port(port_name, false, ALSA_MIDI, addr); + } + } + } + } +} + + +/** Refresh all Alsa Midi connections. + */ +void +AlsaDriver::refresh_connections() +{ + assert(is_attached()); + assert(m_seq); + + PatchageModule* m = NULL; + PatchagePort* p = NULL; + + for (ModuleMap::iterator i = m_canvas->modules().begin(); + i != m_canvas->modules().end(); ++i) { + m = (PatchageModule*)((*i).second); + for (PortList::iterator j = m->ports().begin(); j != m->ports().end(); ++j) { + p = (PatchagePort*)(*j); + if (p->type() == ALSA_MIDI) + add_connections(p); + } + } +} + + +/** Add all connections for the given port. + */ +void +AlsaDriver::add_connections(PatchagePort* port) +{ + assert(is_attached()); + assert(m_seq); + + const snd_seq_addr_t* addr = port->alsa_addr(); + PatchagePort* connected_port = NULL; + + // Fix a problem with duplex->duplex connections (would show up twice) + // No sense doing them all twice anyway.. + if (port->is_input()) + return; + + snd_seq_query_subscribe_t* subsinfo; + snd_seq_query_subscribe_alloca(&subsinfo); + snd_seq_query_subscribe_set_root(subsinfo, addr); + snd_seq_query_subscribe_set_index(subsinfo, 0); + + while(!snd_seq_query_port_subscribers(m_seq, subsinfo)) { + const snd_seq_addr_t* connected_addr = snd_seq_query_subscribe_get_addr(subsinfo); + + connected_port = m_canvas->find_port(connected_addr, !port->is_input()); + + if (connected_port != NULL) { + m_canvas->add_connection(port, connected_port); + } + + snd_seq_query_subscribe_set_index(subsinfo, snd_seq_query_subscribe_get_index(subsinfo) + 1); + } + +} + + +/** Connects two Alsa Midi ports. + * + * \return Whether connection succeeded. + */ +bool +AlsaDriver::connect(const PatchagePort* const src_port, const PatchagePort* const dst_port) +{ + const snd_seq_addr_t* src = src_port->alsa_addr(); + const snd_seq_addr_t* dst = dst_port->alsa_addr(); + + bool result = false; + + if (src && dst) { + snd_seq_port_subscribe_t* subs; + snd_seq_port_subscribe_malloc(&subs); + snd_seq_port_subscribe_set_sender(subs, src); + snd_seq_port_subscribe_set_dest(subs, dst); + snd_seq_port_subscribe_set_exclusive(subs, 0); + snd_seq_port_subscribe_set_time_update(subs, 0); + snd_seq_port_subscribe_set_time_real(subs, 0); + + // Already connected (shouldn't happen) + if (!snd_seq_get_port_subscription(m_seq, subs)) { + cerr << "Error: Attempt to subscribe Alsa ports that are already subscribed." << endl; + result = false; + } + + int ret = snd_seq_subscribe_port(m_seq, subs); + if (ret < 0) { + cerr << "Alsa subscription failed: " << snd_strerror(ret) << endl; + result = false; + } + } + + return (!result); +} + + +/** Disconnects two Alsa Midi ports. + * + * \return Whether disconnection succeeded. + */ +bool +AlsaDriver::disconnect(const PatchagePort* const src_port, const PatchagePort* const dst_port) +{ + const snd_seq_addr_t* src = src_port->alsa_addr(); + const snd_seq_addr_t* dst = dst_port->alsa_addr(); + + bool result = false; + + snd_seq_port_subscribe_t* subs; + snd_seq_port_subscribe_malloc(&subs); + snd_seq_port_subscribe_set_sender(subs, src); + snd_seq_port_subscribe_set_dest(subs, dst); + snd_seq_port_subscribe_set_exclusive(subs, 0); + snd_seq_port_subscribe_set_time_update(subs, 0); + snd_seq_port_subscribe_set_time_real(subs, 0); + + // Not connected (shouldn't happen) + if (snd_seq_get_port_subscription(m_seq, subs) != 0) { + cerr << "Error: Attempt to unsubscribe Alsa ports that are not subscribed." << endl; + result = false; + } + + int ret = snd_seq_unsubscribe_port(m_seq, subs); + if (ret < 0) { + cerr << "Alsa unsubscription failed: " << snd_strerror(ret) << endl; + result = false; + } + + return (!result); +} + + +bool +AlsaDriver::create_refresh_port() +{ + // Mostly lifted from alsa-patch-bay, (C) 2002 Robert Ham, released under GPL + + int ret; + snd_seq_port_info_t* port_info; + + snd_seq_port_info_alloca(&port_info); + snd_seq_port_info_set_name(port_info, "System Announcement Reciever"); + snd_seq_port_info_set_capability(port_info, + SND_SEQ_PORT_CAP_WRITE|SND_SEQ_PORT_CAP_SUBS_WRITE|SND_SEQ_PORT_CAP_NO_EXPORT); + + snd_seq_port_info_set_type(port_info, SND_SEQ_PORT_TYPE_APPLICATION); + + ret = snd_seq_create_port(m_seq, port_info); + if (ret) { + cerr << "Error creating alsa port: " << snd_strerror(ret) << endl; + return false; + } + + // Subscribe the port to the system announcer + ret = snd_seq_connect_from(m_seq, + snd_seq_port_info_get_port(port_info), + SND_SEQ_CLIENT_SYSTEM, + SND_SEQ_PORT_SYSTEM_ANNOUNCE); + + if (ret) { + cerr << "Could not connect to system announcer port: " << snd_strerror(ret) << endl; + return false; + } + + return true; +} + + +void* +AlsaDriver::refresh_main(void* me) +{ + AlsaDriver* ad = (AlsaDriver*)me; + ad->m_refresh_main(); + return NULL; +} + + +void +AlsaDriver::m_refresh_main() +{ + // "Heavily influenced" from alsa-patch-bay + // (C) 2002 Robert Ham, released under GPL + + int ret; + int nfds = snd_seq_poll_descriptors_count(m_seq, POLLIN); + struct pollfd* pfds = new struct pollfd[nfds]; + unsigned short* revents = new unsigned short[nfds]; + + if (!create_refresh_port()) { + cerr << "Could not create Alsa listen port. Auto refreshing will not work." << endl; + return; + } + + snd_seq_poll_descriptors(m_seq, pfds, nfds, POLLIN); + + while (true) { + ret = poll(pfds, nfds, -1); + if (ret == -1) { + if (errno == EINTR) + continue; + + cerr << "Error polling Alsa sequencer: " << strerror(errno) << endl; + continue; + } + + ret = snd_seq_poll_descriptors_revents(m_seq, pfds, nfds, revents); + if (ret) { + cerr << "Error getting Alsa sequencer poll events: " + << snd_strerror(ret) << endl; + continue; + } + + for (int i = 0; i < nfds; ++i) { + if (revents[i] > 0) { + snd_seq_event_t* ev; + snd_seq_event_input(m_seq, &ev); + + if (ev == NULL) + continue; + + switch (ev->type) { + case SND_SEQ_EVENT_RESET: + case SND_SEQ_EVENT_CLIENT_START: + case SND_SEQ_EVENT_CLIENT_EXIT: + case SND_SEQ_EVENT_CLIENT_CHANGE: + case SND_SEQ_EVENT_PORT_START: + case SND_SEQ_EVENT_PORT_EXIT: + case SND_SEQ_EVENT_PORT_CHANGE: + case SND_SEQ_EVENT_PORT_SUBSCRIBED: + case SND_SEQ_EVENT_PORT_UNSUBSCRIBED: + m_is_dirty = true; + break; + default: + break; + } + } + } + } +} diff --git a/src/AlsaDriver.h b/src/AlsaDriver.h new file mode 100644 index 0000000..d6e910f --- /dev/null +++ b/src/AlsaDriver.h @@ -0,0 +1,72 @@ +/* This file is part of Patchage. Copyright (C) 2005 Dave Robillard. + * + * Om 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. + * + * Om 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 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 ALSADRIVER_H +#define ALSADRIVER_H + +#include <iostream> +#include <alsa/asoundlib.h> +#include <pthread.h> +#include <queue> +#include <string> +#include "Driver.h" +class Patchage; +class PatchagePort; +class PatchageFlowCanvas; + +using std::queue; using std::string; + + +/** Handles all externally driven functionality, registering ports etc. + */ +class AlsaDriver : public Driver +{ +public: + AlsaDriver(Patchage* app); + ~AlsaDriver(); + + void attach(bool launch_daemon = false); + void detach(); + + bool is_attached() const { return (m_seq != NULL); } + + void refresh(); + + bool connect(const PatchagePort* const src_port, const PatchagePort* const dst_port); + bool disconnect(const PatchagePort* const src_port, const PatchagePort* const dst_port); + + PatchageFlowCanvas* canvas() { return m_canvas; } + +private: + void refresh_ports(); + void refresh_connections(); + + void add_connections(PatchagePort* port); + + bool create_refresh_port(); + static void* refresh_main(void* me); + void m_refresh_main(); + + Patchage* m_app; + PatchageFlowCanvas* m_canvas; + + snd_seq_t* m_seq; + + pthread_t m_refresh_thread; +}; + + +#endif // ALSADRIVER_H diff --git a/src/Driver.h b/src/Driver.h new file mode 100644 index 0000000..43b919a --- /dev/null +++ b/src/Driver.h @@ -0,0 +1,55 @@ +/* This file is part of Patchage. Copyright (C) 2005 Dave Robillard. + * + * Om 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. + * + * Om 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 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 DRIVER_H +#define DRIVER_H + +class PatchagePort; + +/** Trival driver base class */ +class Driver { +public: + virtual ~Driver() {} + + virtual void attach(bool launch_daemon) = 0; + virtual void detach() = 0; + virtual bool is_attached() const = 0; + + virtual void refresh() = 0; + + virtual bool connect(const PatchagePort* src_port, + const PatchagePort* dst_port) + { return false; } + + virtual bool disconnect(const PatchagePort* src_port, + const PatchagePort* dst_port) + { return false; } + + /** Returns whether or not a refresh is required. */ + bool is_dirty() const { return m_is_dirty; } + + /** Clear 'dirty' status after a refresh. */ + void undirty() { m_is_dirty = false; } + +protected: + Driver() : m_is_dirty(false) {} + + bool m_is_dirty; +}; + + +#endif // DRIVER_H + diff --git a/src/JackDriver.cpp b/src/JackDriver.cpp new file mode 100644 index 0000000..5bb084e --- /dev/null +++ b/src/JackDriver.cpp @@ -0,0 +1,258 @@ +/* This file is part of Patchage. Copyright (C) 2005 Dave Robillard. + * + * Om 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. + * + * Om 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 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 <cassert> +#include <cstring> +#include <string> +#include <iostream> +#include <jack/jack.h> +#include "PatchageFlowCanvas.h" +#include "JackDriver.h" +#include "Patchage.h" +#include "PatchageModule.h" + +using std::cerr; using std::endl; using std::cout; +using std::string; + +using namespace LibFlowCanvas; + + +JackDriver::JackDriver(Patchage* app) +: m_app(app), + m_canvas(app->canvas()), + m_client(NULL) +{ +} + + +JackDriver::~JackDriver() +{ + detach(); +} + + +/** Connect to Jack. + */ +void +JackDriver::attach(bool launch_daemon) +{ + cout << "Connecting to Jack... "; + cout.flush(); + + if (m_client != NULL) { + cout << "already connected. " << endl; + return; + } + + jack_options_t options = (!launch_daemon) ? JackNoStartServer : JackNullOption; + m_client = jack_client_open("Patchage", options, NULL); + if (m_client == NULL) { + cout << "Failed" << endl; + } else { + jack_set_port_registration_callback(m_client, jack_port_registration_cb, this); + jack_set_graph_order_callback(m_client, jack_graph_order_cb, this); + jack_on_shutdown(m_client, jack_shutdown_cb, this); + + jack_activate(m_client); + + cout << "Connected" << endl; + + m_canvas->destroy(); + + m_is_dirty = true; + } +} + + +void +JackDriver::detach() +{ + if (m_client != NULL) { + jack_deactivate(m_client); + jack_client_close(m_client); + m_client = NULL; + cout << "Disconnected from Jack" << endl; + } +} + + +/** Refresh all Jack audio ports/connections. + * To be called from GTK thread only. + */ +void +JackDriver::refresh() +{ + if (m_client == NULL) + return; + + const char** ports; + jack_port_t* port; + + ports = jack_get_ports(m_client, NULL, NULL, 0); // get all existing ports + + string client1_name; + string port1_name; + string client2_name; + string port2_name; + PatchageModule* m = NULL; + + // Add all ports + if (ports != NULL) + for (int i=0; ports[i]; ++i) { + port = jack_port_by_name(m_client, ports[i]); + client1_name = ports[i]; + client1_name = client1_name.substr(0, client1_name.find(":")); + + ModuleType type = InputOutput; + //if (m_app->state_manager()->get_module_split(client1_name) + // || jack_port_flags(port) & JackPortIsTerminal) { + if (m_app->state_manager()->get_module_split(client1_name, + (jack_port_flags(port) & JackPortIsTerminal))) { + if (jack_port_flags(port) & JackPortIsInput) { + type = Input; + } else { + type = Output; + } + } + + m = (PatchageModule*)m_canvas->find_module(client1_name, type); + + if (m == NULL) { + m = new PatchageModule(m_app, client1_name, type); + m->load_location(); + m->store_location(); + m_canvas->add_module(m); + } + + // FIXME: leak? jack docs don't say + const char* const type_str = jack_port_type(port); + PortType port_type = JACK_AUDIO; + if (!strcmp(type_str, "8 bit raw midi")) + port_type = JACK_MIDI; + + m->add_patchage_port(jack_port_short_name(port), + (jack_port_flags(port) & JackPortIsInput), + port_type); + } + + // Add all connections + if (ports != NULL) { + for (int i=0; ports[i]; ++i) { + port = jack_port_by_name(m_client, ports[i]); + const char** connected_ports = jack_port_get_all_connections(m_client, port); + + if (connected_ports != NULL) + for (int j=0; connected_ports[j]; ++j) { + client1_name = ports[i]; + port1_name = client1_name.substr(client1_name.find(':')+1); + client1_name = client1_name.substr(0, client1_name.find(':')); + + client2_name = connected_ports[j]; + port2_name = client2_name.substr(client2_name.find(':')+1); + client2_name = client2_name.substr(0, client2_name.find(':')); + + m_canvas->add_connection(client1_name, port1_name, client2_name, port2_name); + } + free(connected_ports); + } + free(ports); + } + + undirty(); +} + + +/** Connects two Jack audio ports. + * To be called from GTK thread only. + * \return Whether connection succeeded. + */ +bool +JackDriver::connect(const PatchagePort* const src_port, const PatchagePort* const dst_port) +{ + if (m_client == NULL) + return false; + + int result = jack_connect(m_client, src_port->full_name().c_str(), dst_port->full_name().c_str()); + + string msg; + + if (result == 0) { + msg = "Successfully connected jack ports"; + } else { + msg = "Unable to connect "; + msg += src_port->full_name() + " -> " + dst_port->full_name(); + } + m_app->status_message(msg); + + return (!result); +} + + +/** Disconnects two Jack audio ports. + * To be called from GTK thread only. + * \return Whether disconnection succeeded. + */ +bool +JackDriver::disconnect(const PatchagePort* const src_port, const PatchagePort* const dst_port) +{ + if (m_client == NULL) + return false; + + int result = jack_disconnect(m_client, src_port->full_name().c_str(), dst_port->full_name().c_str()); + + string msg; + + if (result == 0) { + msg = "Successfully disconnected jack ports"; + } else { + msg = "Unable to disconnect "; + msg += src_port->full_name() + " -> " + dst_port->full_name(); + } + m_app->status_message(msg); + + return (!result); +} + + +void +JackDriver::jack_port_registration_cb(jack_port_id_t port_id, int registered, void* me) +{ + assert(me != NULL); + assert(((JackDriver*)me)->m_client != NULL); + ((JackDriver*)me)->m_is_dirty = true; +} + + +int +JackDriver::jack_graph_order_cb(void* me) +{ + assert(me != NULL); + assert(((JackDriver*)me)->m_client != NULL); + ((JackDriver*)me)->m_is_dirty = true; + + return 0; +} + + +void +JackDriver::jack_shutdown_cb(void* me) +{ + assert(me != NULL); + ((JackDriver*)me)->m_client = NULL; + ((JackDriver*)me)->m_is_dirty = true; +} + + diff --git a/src/JackDriver.h b/src/JackDriver.h new file mode 100644 index 0000000..6b69900 --- /dev/null +++ b/src/JackDriver.h @@ -0,0 +1,68 @@ +/* This file is part of Patchage. Copyright (C) 2005 Dave Robillard. + * + * Om 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. + * + * Om 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 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 JACKDRIVER_H +#define JACKDRIVER_H + +#include <iostream> +#include <jack/jack.h> +#include <string> +#include "Driver.h" +class Patchage; +class PatchageFlowCanvas; +class PatchagePort; + +using std::string; + + +/** Handles all externally driven functionality, registering ports etc. + * + * Jack callbacks and connect methods and things like that live here. + * Right now just for jack ports, but that will change... + */ +class JackDriver : public Driver +{ +public: + JackDriver(Patchage* app); + ~JackDriver(); + + void attach(bool launch_daemon); + void detach(); + + bool is_attached() const { return (m_client != NULL); } + void refresh(); + + bool connect(const PatchagePort* const src_port, const PatchagePort* const dst_port); + bool disconnect(const PatchagePort* const src_port, const PatchagePort* const dst_port); + /*bool connect(const string& src_module_name, const string& src_port_name, + const string& dst_module_name, const string& dest_port_name); + + bool disconnect(const string& src_module_name, const string& src_port_name, + const string& dst_module_name, const string& dest_port_name);*/ + +private: + Patchage* m_app; + PatchageFlowCanvas* m_canvas; + + jack_client_t* m_client; + + static void jack_port_registration_cb(jack_port_id_t port_id, int registered, void* controller); + static int jack_graph_order_cb(void* controller); + static void jack_shutdown_cb(void* controller); +}; + + +#endif // JACKDRIVER_H diff --git a/src/LashDriver.cpp b/src/LashDriver.cpp new file mode 100644 index 0000000..c4a89b2 --- /dev/null +++ b/src/LashDriver.cpp @@ -0,0 +1,146 @@ +/* This file is part of Patchage. Copyright (C) 2005 Dave Robillard. + * + * Om 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. + * + * Om 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 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 "LashDriver.h" +#include "config.h" +#include <iostream> +#include <string> +#include "Patchage.h" +#include "StateManager.h" + +using std::cerr; using std::cout; using std::endl; +using std::string; + + +LashDriver::LashDriver(Patchage* app, int argc, char** argv) +: m_app(app), + m_client(NULL), + m_args(NULL) +{ + m_args = lash_extract_args(&argc, &argv); +} + + +LashDriver::~LashDriver() +{ + if (m_args) + lash_args_destroy(m_args); +} + + +void +LashDriver::attach(bool launch_daemon) +{ + cout << "Connecting to Lash... "; + cout.flush(); + + if (m_client != NULL) { + cout << "already connected." << endl; + return; + } + + int lash_flags = LASH_Config_File; + if (launch_daemon) + lash_flags |= LASH_No_Start_Server; + m_client = lash_init(m_args, PACKAGE_NAME, lash_flags, LASH_PROTOCOL(2, 0)); + if (m_client == NULL) { + cout << "Failed. Session management will not occur." << endl; + } else { + lash_event_t* event = lash_event_new_with_type(LASH_Client_Name); + lash_event_set_string(event, "Patchage"); + lash_send_event(m_client, event); + cout << "Connected" << endl; + } +} + + +void +LashDriver::detach() +{ + // FIXME: send some notification that we're gone?? + m_client = NULL; + cout << "Disconnected from Lash" << endl; +} + + +void +LashDriver::process_events() +{ + lash_event_t* ev = NULL; + lash_config_t* conf = NULL; + + // Process events + while ((ev = lash_get_event(m_client)) != NULL) { + handle_event(ev); + lash_event_destroy(ev); + } + + // Process configs + while ((conf = lash_get_config(m_client)) != NULL) { + handle_config(conf); + lash_config_destroy(conf); + } +} + + +void +LashDriver::handle_event(lash_event_t* ev) +{ + LASH_Event_Type type = lash_event_get_type(ev); + const char* c_str = lash_event_get_string(ev); + string str = (c_str == NULL) ? "" : c_str; + + //cout << "[LashDriver] LASH Event. Type = " << type << ", string = " << str << "**********" << endl; + + if (type == LASH_Save_File) { + //cout << "[LashDriver] LASH Save File - " << str << endl; + m_app->store_window_location(); + m_app->state_manager()->save(str.append("/locations")); + lash_send_event(m_client, lash_event_new_with_type(LASH_Save_File)); + } else if (type == LASH_Restore_File) { + //cout << "[LashDriver] LASH Restore File - " << str << endl; + m_app->state_manager()->load(str.append("/locations")); + m_app->update_state(); + lash_send_event(m_client, lash_event_new_with_type(LASH_Restore_File)); + } else if (type == LASH_Save_Data_Set) { + //cout << "[LashDriver] LASH Save Data Set - " << endl; + + // Tell LASH we're done + lash_send_event(m_client, lash_event_new_with_type(LASH_Save_Data_Set)); + } else if (type == LASH_Quit) { + //stop_thread(); + m_client = NULL; + m_app->quit(); + } +} + + +void +LashDriver::handle_config(lash_config_t* conf) +{ + const char* key = NULL; + const void* val = NULL; + size_t val_size = 0; + + //cout << "[LashDriver] LASH Config. Key = " << key << endl; + + key = lash_config_get_key(conf); + val = lash_config_get_value(conf); + val_size = lash_config_get_value_size(conf); +} + + + diff --git a/src/LashDriver.h b/src/LashDriver.h new file mode 100644 index 0000000..742c249 --- /dev/null +++ b/src/LashDriver.h @@ -0,0 +1,50 @@ +/* This file is part of Patchage. Copyright (C) 2005 Dave Robillard. + * + * Om 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. + * + * Om 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 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 LASHDRIVER_H +#define LASHDRIVER_H + +#include <lash/lash.h> +#include "Driver.h" + +class Patchage; + +class LashDriver : public Driver +{ +public: + LashDriver(Patchage* app, int argc, char** argv); + ~LashDriver(); + + void attach(bool launch_daemon); + void detach(); + + bool is_attached() const { return lash_enabled(m_client); } + + void refresh() {} + + void process_events(); + +private: + Patchage* m_app; + lash_client_t* m_client; + lash_args_t* m_args; + + void handle_event(lash_event_t* conf); + void handle_config(lash_config_t* conf); +}; + + +#endif // LASHDRIVER_H diff --git a/src/Makefile.am b/src/Makefile.am new file mode 100644 index 0000000..6e6eb5f --- /dev/null +++ b/src/Makefile.am @@ -0,0 +1,27 @@ +AM_CXXFLAGS = -DPKGDATADIR=\"$(pkgdatadir)\" @LIBGLADEMM_CFLAGS@ @GNOMECANVASMM_CFLAGS@ @JACK_CFLAGS@ @ALSA_CFLAGS@ @LASH_CFLAGS@ @FLOWCANVAS_CFLAGS@ +patchage_LDADD = @LIBGLADEMM_LIBS@ @GNOMECANVASMM_LIBS@ @JACK_LIBS@ @ALSA_LIBS@ @LASH_LIBS@ @FLOWCANVAS_LIBS@ + +EXTRA_DIST = patchage.gladep + +sharefilesdir = $(pkgdatadir) +dist_sharefiles_DATA = patchage.glade + +bin_PROGRAMS = patchage +patchage_SOURCES = \ + main.cpp \ + Patchage.h \ + Patchage.cpp \ + StateManager.h \ + StateManager.cpp \ + PatchageModule.h \ + PatchagePort.h \ + JackDriver.h \ + JackDriver.cpp \ + AlsaDriver.h \ + AlsaDriver.cpp \ + PatchageFlowCanvas.h \ + PatchageFlowCanvas.cpp + +if WITH_LASH +patchage_SOURCES += LashDriver.h LashDriver.cpp +endif diff --git a/src/Patchage.cpp b/src/Patchage.cpp new file mode 100644 index 0000000..38d17f7 --- /dev/null +++ b/src/Patchage.cpp @@ -0,0 +1,411 @@ +/* This file is part of Patchage. Copyright (C) 2005 Dave Robillard. + * + * Om 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. + * + * Om 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 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 "Patchage.h" +#include "config.h" +#include <libgnomecanvasmm.h> +#include <libglademm/xml.h> +#include <fstream> +#include <pthread.h> +#include "StateManager.h" +#include "PatchageFlowCanvas.h" +#include "AlsaDriver.h" +#include "JackDriver.h" +#ifdef HAVE_LASH +#include "LashDriver.h" +#endif + + +Patchage::Patchage(int argc, char** argv) +: +#ifdef HAVE_LASH + m_lash_driver(NULL), +#endif +#ifdef HAVE_ALSA + m_alsa_driver(NULL), +#endif + m_canvas(NULL), + m_jack_driver(NULL), + m_state_manager(NULL), + m_refresh(false) +{ + m_settings_filename = getenv("HOME"); + m_settings_filename += "/.patchagerc"; + + m_state_manager = new StateManager(); + m_canvas = new PatchageFlowCanvas(this, 1600*2, 1200*2); + m_jack_driver = new JackDriver(this); +#ifdef HAVE_ALSA + m_alsa_driver = new AlsaDriver(this); +#endif + + m_state_manager->load(m_settings_filename); + +#ifdef HAVE_LASH + m_lash_driver = new LashDriver(this, argc, argv); +#endif + + Glib::RefPtr<Gnome::Glade::Xml> refXml; + + // Check for the .glade file in current directory + string glade_filename = "./patchage.glade"; + ifstream fs(glade_filename.c_str()); + if (fs.fail()) { // didn't find it, check PKGDATADIR + fs.clear(); + glade_filename = PKGDATADIR; + glade_filename += "/patchage.glade"; + + fs.open(glade_filename.c_str()); + if (fs.fail()) { + cerr << "Unable to find patchage.glade in current directory or " << PKGDATADIR << "." << endl; + exit(EXIT_FAILURE); + } + fs.close(); + } + + try { + refXml = Gnome::Glade::Xml::create(glade_filename); + } catch(const Gnome::Glade::XmlError& ex) { + std::cerr << ex.what() << std::endl; + throw; + } + + refXml->get_widget("patchage_win", m_main_window); + refXml->get_widget("about_win", m_about_window); + refXml->get_widget("about_project_label", m_about_project_label); + refXml->get_widget("launch_jack_menuitem", m_menu_jack_launch); + refXml->get_widget("connect_to_jack_menuitem", m_menu_jack_connect); + refXml->get_widget("disconnect_from_jack_menuitem", m_menu_jack_disconnect); +#ifdef HAVE_LASH + refXml->get_widget("launch_lash_menuitem", m_menu_lash_launch); + refXml->get_widget("connect_to_lash_menuitem", m_menu_lash_connect); + refXml->get_widget("disconnect_from_lash_menuitem", m_menu_lash_disconnect); +#endif +#ifdef HAVE_ALSA + refXml->get_widget("connect_to_alsa_menuitem", m_menu_alsa_connect); + refXml->get_widget("disconnect_from_alsa_menuitem", m_menu_alsa_disconnect); +#endif + refXml->get_widget("file_save_menuitem", m_menu_file_save); + refXml->get_widget("file_quit_menuitem", m_menu_file_quit); + refXml->get_widget("view_refresh_menuitem", m_menu_view_refresh); + refXml->get_widget("help_about_menuitem", m_menu_help_about); + refXml->get_widget("canvas_scrolledwindow", m_canvas_scrolledwindow); + refXml->get_widget("zoom_scale", m_zoom_slider); + refXml->get_widget("about_close_button", m_about_close_button); + refXml->get_widget("status_lab", m_status_label); + + m_main_window->resize( + static_cast<int>(m_state_manager->get_window_size().x), + static_cast<int>(m_state_manager->get_window_size().y)); + + m_main_window->move( + static_cast<int>(m_state_manager->get_window_location().x), + static_cast<int>(m_state_manager->get_window_location().y)); + + m_canvas_scrolledwindow->add(*m_canvas); + //m_canvas_scrolledwindow->signal_event().connect(sigc::mem_fun(m_canvas, &FlowCanvas::scroll_event_handler)); + m_canvas->scroll_to(static_cast<int>(m_canvas->width()/2 - 320), + static_cast<int>(m_canvas->height()/2 - 240)); // FIXME: hardcoded + m_canvas->show(); + + // Idle callback, check if we need to refresh (every 250msec) + Glib::signal_timeout().connect(sigc::mem_fun(this, &Patchage::idle_callback), 250); + + m_zoom_slider->signal_value_changed().connect( sigc::mem_fun(this, &Patchage::zoom_changed)); + m_menu_jack_launch->signal_activate().connect( sigc::mem_fun(this, &Patchage::menu_jack_launch)); + m_menu_jack_connect->signal_activate().connect( sigc::mem_fun(this, &Patchage::menu_jack_connect)); + m_menu_jack_disconnect->signal_activate().connect(sigc::mem_fun(this, &Patchage::menu_jack_disconnect)); +#ifdef HAVE_LASH + m_menu_lash_launch->signal_activate().connect( sigc::mem_fun(this, &Patchage::menu_lash_launch)); + m_menu_lash_connect->signal_activate().connect( sigc::mem_fun(this, &Patchage::menu_lash_connect)); + m_menu_lash_disconnect->signal_activate().connect(sigc::mem_fun(this, &Patchage::menu_lash_disconnect)); +#endif + m_menu_alsa_connect->signal_activate().connect( sigc::mem_fun(this, &Patchage::menu_alsa_connect)); + m_menu_alsa_disconnect->signal_activate().connect(sigc::mem_fun(this, &Patchage::menu_alsa_disconnect)); + m_menu_file_save->signal_activate().connect( sigc::mem_fun(this, &Patchage::menu_file_save)); + m_menu_file_quit->signal_activate().connect( sigc::mem_fun(this, &Patchage::menu_file_quit)); + m_menu_view_refresh->signal_activate().connect( sigc::mem_fun(this, &Patchage::menu_view_refresh)); + m_menu_help_about->signal_activate().connect( sigc::mem_fun(this, &Patchage::menu_help_about)); + m_about_close_button->signal_clicked().connect( sigc::mem_fun(this, &Patchage::close_about)); + + //_about_project_label->use_markup(true); + m_about_project_label->set_markup("<span size=\"xx-large\" weight=\"bold\">Patchage " PACKAGE_VERSION "</span>"); +} + + +Patchage::~Patchage() +{ +#ifdef HAVE_LASH + delete m_lash_driver; +#endif + delete m_jack_driver; + delete m_alsa_driver; + delete m_canvas; + delete m_state_manager; +} + + +void +Patchage::attach() +{ + m_jack_driver->attach(false); + +#ifdef HAVE_LASH + m_lash_driver->attach(false); +#endif +#ifdef HAVE_ALSA + m_alsa_driver->attach(); +#endif + + update_menu_items(); + menu_view_refresh(); +} + + +bool +Patchage::idle_callback() +{ + // FIXME: no need to destroy the whole canvas every time + if (m_refresh || (m_jack_driver && m_jack_driver->is_dirty()) +#ifdef HAVE_ALSA + || (m_alsa_driver && m_alsa_driver->is_dirty()) +#endif + ) { + m_canvas->destroy(); + m_jack_driver->refresh(); +#ifdef HAVE_ALSA + m_alsa_driver->refresh(); +#endif + update_menu_items(); + m_refresh = false; + } + +#ifdef HAVE_LASH + if (m_lash_driver->is_attached()) + m_lash_driver->process_events(); +#endif + + return true; +} + + +void +Patchage::zoom_changed() +{ + const float z = m_zoom_slider->get_value(); + + m_canvas->zoom(z); + m_state_manager->set_zoom(z); +} + + +void +Patchage::update_state() +{ + for (ModuleMap::iterator i = m_canvas->modules().begin(); i != m_canvas->modules().end(); ++i) + (*i).second->load_location(); + + cerr << "[Patchage] Resizing window: (" << m_state_manager->get_window_size().x + << "," << m_state_manager->get_window_size().y << ")" << endl; + + m_main_window->resize( + static_cast<int>(m_state_manager->get_window_size().x), + static_cast<int>(m_state_manager->get_window_size().y)); + + cerr << "[Patchage] Moving window: (" << m_state_manager->get_window_location().x + << "," << m_state_manager->get_window_location().y << ")" << endl; + m_main_window->move( + static_cast<int>(m_state_manager->get_window_location().x), + static_cast<int>(m_state_manager->get_window_location().y)); +} + + +void +Patchage::status_message(const string& msg) +{ + m_status_label->set_text(msg); +} + + + + +/** Update the sensitivity status of menus to reflect the present. + * + * (eg. disable "Connect to Jack" when Patchage is already connected to Jack) + */ +void +Patchage::update_menu_items() +{ + // Update Jack menu items + const bool jack_attached = m_jack_driver->is_attached(); + m_menu_jack_launch->set_sensitive(!jack_attached); + m_menu_jack_connect->set_sensitive(!jack_attached); + m_menu_jack_disconnect->set_sensitive(jack_attached); + + // Update Lash menu items +#ifdef HAVE_LASH + const bool lash_attached = m_lash_driver->is_attached(); + m_menu_lash_launch->set_sensitive(!lash_attached); + m_menu_lash_connect->set_sensitive(!lash_attached); + m_menu_lash_disconnect->set_sensitive(lash_attached); +#endif + +#ifdef HAVE_ALSA + // Update Alsa menu items + const bool alsa_attached = m_alsa_driver->is_attached(); + m_menu_alsa_connect->set_sensitive(!alsa_attached); + m_menu_alsa_disconnect->set_sensitive(alsa_attached); +#endif +} + + +void +Patchage::menu_jack_launch() +{ + m_jack_driver->attach(true); + update_menu_items(); +} + + +void +Patchage::menu_jack_connect() +{ + m_jack_driver->attach(false); + update_menu_items(); +} + + +void +Patchage::menu_jack_disconnect() +{ + m_jack_driver->detach(); + menu_view_refresh(); + update_menu_items(); +} + +#ifdef HAVE_LASH +void +Patchage::menu_lash_launch() +{ + m_lash_driver->attach(true); + update_menu_items(); +} + + +void +Patchage::menu_lash_connect() +{ + m_lash_driver->attach(false); + update_menu_items(); +} + + +void +Patchage::menu_lash_disconnect() +{ + m_lash_driver->detach(); + update_menu_items(); +} +#endif + +#ifdef HAVE_ALSA +void +Patchage::menu_alsa_connect() +{ + m_alsa_driver->attach(false); + update_menu_items(); +} + + +void +Patchage::menu_alsa_disconnect() +{ + m_alsa_driver->detach(); + menu_view_refresh(); + update_menu_items(); +} +#endif + +void +Patchage::menu_file_save() +{ + store_window_location(); + m_state_manager->save(m_settings_filename); +} + + +void +Patchage::menu_file_quit() +{ +#ifdef HAVE_ALSA + m_alsa_driver->detach(); +#endif + m_jack_driver->detach(); + m_main_window->hide(); +} + + +void +Patchage::menu_view_refresh() +{ + assert(m_canvas); + + // FIXME: rebuilding the entire canvas each time is garbage + m_canvas->destroy(); + + if (m_jack_driver) + m_jack_driver->refresh(); + +#ifdef HAVE_ALSA + if (m_alsa_driver) + m_alsa_driver->refresh(); +#endif +} + + +void +Patchage::menu_help_about() +{ + m_about_window->show(); +} + + +void +Patchage::close_about() +{ + m_about_window->hide(); +} + + +/** Update the stored window location and size in the StateManager (in memory). + */ +void +Patchage::store_window_location() +{ + int loc_x, loc_y, size_x, size_y; + m_main_window->get_position(loc_x, loc_y); + m_main_window->get_size(size_x, size_y); + Coord window_location; + window_location.x = loc_x; + window_location.y = loc_y; + Coord window_size; + window_size.x = size_x; + window_size.y = size_y; + m_state_manager->set_window_location(window_location); + m_state_manager->set_window_size(window_size); +} + + diff --git a/src/Patchage.h b/src/Patchage.h new file mode 100644 index 0000000..f686e49 --- /dev/null +++ b/src/Patchage.h @@ -0,0 +1,116 @@ +/* This file is part of Patchage. Copyright (C) 2005 Dave Robillard. + * + * Om 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. + * + * Om 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 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 PATCHAGE_H +#define PATCHAGE_H + +#include "config.h" +#include <string> +#include <libgnomecanvasmm.h> + +using namespace std; + +class PatchageFlowCanvas; +class JackDriver; +class AlsaDriver; +class LashDriver; +class StateManager; + + +class Patchage +{ +public: + Patchage(int argc, char** argv); + ~Patchage(); + + PatchageFlowCanvas* canvas() { return m_canvas; } + StateManager* state_manager() { return m_state_manager; } + Gtk::Window* window() { return m_main_window; } + JackDriver* jack_driver() { return m_jack_driver; } +#ifdef HAVE_ALSA + AlsaDriver* alsa_driver() { return m_alsa_driver; } +#endif +#ifdef HAVE_LASH + LashDriver* lash_driver() { return m_lash_driver; } +#endif + + void attach(); + void quit() { m_main_window->hide(); } + + void update_state(); + void store_window_location(); + + void status_message(const string& msg); + inline void queue_refresh() { m_refresh = true; } + +protected: + void update_menu_items(); + + void menu_jack_launch(); + void menu_jack_connect(); + void menu_jack_disconnect(); + void menu_file_save(); + void menu_file_quit(); + void menu_view_refresh(); + void menu_help_about(); + void close_about(); + void zoom_changed(); + bool idle_callback(); + +#ifdef HAVE_LASH + LashDriver* m_lash_driver; + Gtk::MenuItem* m_menu_lash_launch; + Gtk::MenuItem* m_menu_lash_connect; + Gtk::MenuItem* m_menu_lash_disconnect; + void menu_lash_launch(); + void menu_lash_connect(); + void menu_lash_disconnect(); +#endif + +#ifdef HAVE_ALSA + AlsaDriver* m_alsa_driver; + Gtk::MenuItem* m_menu_alsa_connect; + Gtk::MenuItem* m_menu_alsa_disconnect; + void menu_alsa_connect(); + void menu_alsa_disconnect(); +#endif + + PatchageFlowCanvas* m_canvas; + JackDriver* m_jack_driver; + StateManager* m_state_manager; + + Gtk::Main* m_gtk_main; + + string m_settings_filename; + bool m_refresh; + + Gtk::Window* m_main_window; + Gtk::Window* m_about_window; + Gtk::Label* m_about_project_label; + Gtk::MenuItem* m_menu_jack_launch; + Gtk::MenuItem* m_menu_jack_connect; + Gtk::MenuItem* m_menu_jack_disconnect; + Gtk::MenuItem* m_menu_file_save; + Gtk::MenuItem* m_menu_file_quit; + Gtk::MenuItem* m_menu_view_refresh; + Gtk::MenuItem* m_menu_help_about; + Gtk::ScrolledWindow* m_canvas_scrolledwindow; + Gtk::HScale* m_zoom_slider; + Gtk::Button* m_about_close_button; + Gtk::Label* m_status_label; +}; + +#endif // PATCHAGE_H diff --git a/src/PatchageFlowCanvas.cpp b/src/PatchageFlowCanvas.cpp new file mode 100644 index 0000000..2b9b19d --- /dev/null +++ b/src/PatchageFlowCanvas.cpp @@ -0,0 +1,117 @@ +/* This file is part of Patchage. Copyright (C) 2004 Dave Robillard. + * + * Patchage 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. + * + * Patchage 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 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 "PatchageFlowCanvas.h" +#include "Patchage.h" +#include "JackDriver.h" +#include "AlsaDriver.h" +#include "PatchageModule.h" +#include "PatchagePort.h" + + +PatchageFlowCanvas::PatchageFlowCanvas(Patchage* app, int width, int height) +: FlowCanvas(width, height), + m_app(app) +{ +} + + +PatchageModule* +PatchageFlowCanvas::find_module(const string& name, ModuleType type) +{ + PatchageModule* pm = NULL; + + for (ModuleMap::iterator m = m_modules.begin(); m != m_modules.end(); ++m) { + pm = (PatchageModule*)(*m).second; + if (pm->name() == name && pm->type() == type) { + return pm; + } + } + + return NULL; +} + + +PatchagePort* +PatchageFlowCanvas::find_port(const snd_seq_addr_t* alsa_addr, bool is_input) +{ + PatchagePort* pp = NULL; + for (ModuleMap::iterator m = m_modules.begin(); m != m_modules.end(); ++m) { + for (PortList::iterator p = (*m).second->ports().begin(); p != (*m).second->ports().end(); ++p) { + pp = (PatchagePort*)(*p); + if (pp->type() == ALSA_MIDI && pp->alsa_addr() + && pp->alsa_addr()->client == alsa_addr->client + && pp->alsa_addr()->port == alsa_addr->port) + if (is_input == pp->is_input()) + return pp; + } + } + + return NULL; +} + + +void +PatchageFlowCanvas::connect(const Port* port1, const Port* port2) +{ + PatchagePort* p1 = (PatchagePort*)port1; + PatchagePort* p2 = (PatchagePort*)port2; + + if (p1->type() == JACK_AUDIO && p2->type() == JACK_AUDIO + || (p1->type() == JACK_MIDI && p2->type() == JACK_MIDI)) + /*m_app->jack_driver()->connect(p1->module()->name(), p1->name(), + p2->module()->name(), p2->name());*/ + m_app->jack_driver()->connect(p1, p2); + else if (p1->type() == ALSA_MIDI && p2->type() == ALSA_MIDI) + m_app->alsa_driver()->connect(p1, p2); + else + m_app->status_message("Cannot make connection, incompatible port types."); +} + + +void +PatchageFlowCanvas::disconnect(const Port* port1, const Port* port2) +{ + PatchagePort* input = NULL; + PatchagePort* output = NULL; + + if (port1->is_input() && !port2->is_input()) { + input = (PatchagePort*)port1; + output = (PatchagePort*)port2; + } else if (port2->is_input() && !port1->is_input()) { + input = (PatchagePort*)port2; + output = (PatchagePort*)port1; + } else { + m_app->status_message("Attempt to disconnect two input (or output) ports?? Please report bug."); + return; + } + + if (input->type() == JACK_AUDIO && output->type() == JACK_AUDIO + || input->type() == JACK_MIDI && output->type() == JACK_MIDI) + m_app->jack_driver()->disconnect(output, input); + else if (input->type() == ALSA_MIDI && output->type() == ALSA_MIDI) + m_app->alsa_driver()->disconnect(output, input); + else + m_app->status_message("Attempt to disconnect Jack audio port from Alsa Midi port?? Please report bug."); +} + + +void +PatchageFlowCanvas::status_message(const string& msg) +{ + m_app->status_message(msg); +} + diff --git a/src/PatchageFlowCanvas.h b/src/PatchageFlowCanvas.h new file mode 100644 index 0000000..2636920 --- /dev/null +++ b/src/PatchageFlowCanvas.h @@ -0,0 +1,49 @@ +/* This file is part of Patchage. Copyright (C) 2004 Dave Robillard. + * + * Patchage 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. + * + * Patchage 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 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 PATCHAGEPATCHBAYAREA_H +#define PATCHAGEPATCHBAYAREA_H + +#include <string> +#include <alsa/asoundlib.h> +#include <flowcanvas/FlowCanvas.h> +#include "StateManager.h" +class Patchage; +class PatchageModule; +class PatchagePort; + +using std::string; +using namespace LibFlowCanvas; + +class PatchageFlowCanvas : public FlowCanvas +{ +public: + PatchageFlowCanvas(Patchage* m_app, int width, int height); + + PatchageModule* find_module(const string& name, ModuleType type); + PatchagePort* find_port(const snd_seq_addr_t* alsa_addr, bool is_input); + + void connect(const Port* port1, const Port* port2); + void disconnect(const Port* port1, const Port* port2); + + void status_message(const string& msg); + +private: + Patchage* m_app; +}; + + +#endif // PATCHAGEPATCHBAYAREA_H diff --git a/src/PatchageModule.h b/src/PatchageModule.h new file mode 100644 index 0000000..b511eec --- /dev/null +++ b/src/PatchageModule.h @@ -0,0 +1,120 @@ +/* This file is part of Patchage. Copyright (C) 2004 Dave Robillard. + * + * Patchage 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. + * + * Patchage 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 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 PATCHAGEMODULE_H +#define PATCHAGEMODULE_H + +#include <string> +#include <libgnomecanvasmm.h> +#include <alsa/asoundlib.h> +#include <flowcanvas/FlowCanvas.h> +#include <flowcanvas/Module.h> +#include "PatchageFlowCanvas.h" +#include "StateManager.h" +#include "PatchagePort.h" + +using std::string; using std::list; + +using namespace LibFlowCanvas; + +class PatchageModule : public Module +{ +public: + PatchageModule(Patchage* app, const string& title, ModuleType type, double x=0, double y=0) + : Module(app->canvas(), title, x, y), + m_app(app), + m_type(type) + { + Gtk::Menu::MenuList& items = m_menu.items(); + if (type == InputOutput) { + items.push_back(Gtk::Menu_Helpers::MenuElem("Split", + sigc::mem_fun(this, &PatchageModule::split))); + } else { + items.push_back(Gtk::Menu_Helpers::MenuElem("Join", + sigc::mem_fun(this, &PatchageModule::join))); + } + items.push_back(Gtk::Menu_Helpers::MenuElem("Disconnect All", + sigc::mem_fun(this, &PatchageModule::menu_disconnect_all))); + } + + virtual ~PatchageModule() { } + + virtual void add_patchage_port(const string& port_name, bool is_input, PortType type) + { + PatchagePort* port = new PatchagePort(this, type, port_name, is_input, + m_app->state_manager()->get_port_color(type)); + + Module::add_port(port, true); + } + + virtual void add_patchage_port(const string& port_name, bool is_input, PortType type, const snd_seq_addr_t addr) + { + PatchagePort* port = new PatchagePort(this, type, port_name, is_input, + m_app->state_manager()->get_port_color(type)); + + port->alsa_addr(addr); + + Module::add_port(port, true); + } + + + virtual void load_location() { + Coord loc = m_app->state_manager()->get_module_location(m_name, m_type); + + //cerr << "******" << m_name << " MOVING TO (" << loc.x << "," << loc.y << ")" << endl; + + if (loc.x != -1) + move_to(loc.x, loc.y); + else + move_to((m_canvas->width()/2) - 100 + rand() % 400, + (m_canvas->height()/2) - 100 + rand() % 400); + } + + void split() { + assert(m_type == InputOutput); + m_app->state_manager()->set_module_split(m_name, true); + m_app->queue_refresh(); + } + + void join() { + assert(m_type != InputOutput); + m_app->state_manager()->set_module_split(m_name, false); + m_app->queue_refresh(); + } + + virtual void store_location() { + Coord loc = { property_x().get_value(), property_y().get_value() }; + m_app->state_manager()->set_module_location(m_name, m_type, loc); + } + + virtual void show_dialog() {} + virtual void on_right_click(GdkEventButton* ev) { m_menu.popup(ev->button, ev->time); } + virtual void menu_disconnect_all() { + for (PortList::iterator p = m_ports.begin(); p != m_ports.end(); ++p) + (*p)->disconnect_all(); + } + + ModuleType type() { return m_type; } + +protected: + Patchage* m_app; + Gtk::Menu m_menu; + ModuleType m_type; +}; + + +#endif // PATCHAGEMODULE_H diff --git a/src/PatchagePort.h b/src/PatchagePort.h new file mode 100644 index 0000000..601bce9 --- /dev/null +++ b/src/PatchagePort.h @@ -0,0 +1,66 @@ +/* This file is part of Om. Copyright (C) 2004 Dave Robillard. + * + * Om 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. + * + * Om 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 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 PATCHAGEPORT_H +#define PATCHAGEPORT_H + +#include <string> +#include <list> +#include <alsa/asoundlib.h> +#include <flowcanvas/Port.h> +#include <flowcanvas/Module.h> + +using namespace LibFlowCanvas; +using std::string; using std::list; + +enum PortType { JACK_AUDIO, JACK_MIDI, ALSA_MIDI }; + + +/** A Port on a PatchageModule + * + * \ingroup OmGtk + */ +class PatchagePort : public LibFlowCanvas::Port +{ +public: + PatchagePort(LibFlowCanvas::Module* module, PortType type, const string& name, bool is_input, int color) + : Port(module, name, is_input, color), + m_type(type) + { + m_alsa_addr.client = '\0'; + m_alsa_addr.port = '\0'; + } + + virtual ~PatchagePort() {} + + // FIXME: This driver specific crap really needs to go + void alsa_addr(const snd_seq_addr_t addr) { m_alsa_addr = addr; } + const snd_seq_addr_t* alsa_addr() const + { return (m_type == ALSA_MIDI) ? &m_alsa_addr : NULL; } + + /** Returns the full name of this port, as "modulename:portname" */ + string full_name() const { return m_module->name() + ":" + m_name; } + + PortType type() const { return m_type; } + +private: + snd_seq_addr_t m_alsa_addr; + PortType m_type; +}; + + +#endif // PATCHAGEPORT_H diff --git a/src/StateManager.cpp b/src/StateManager.cpp new file mode 100644 index 0000000..50429e1 --- /dev/null +++ b/src/StateManager.cpp @@ -0,0 +1,246 @@ +/* This file is part of Patchage. Copyright (C) 2005 Dave Robillard. + * + * Om 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. + * + * Om 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 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 "StateManager.h" +#include <stdlib.h> +#include <iostream> +#include <fstream> +#include "Patchage.h" + +using std::map; using std::list; +using std::cerr; using std::cout; using std::endl; + + +StateManager::StateManager() +{ + m_window_location.x = 0; + m_window_location.y = 0; + m_window_size.x = 640; + m_window_size.y = 480; + m_zoom = 1.0; +} + + +Coord +StateManager::get_module_location(const string& name, ModuleType type) +{ + for (std::list<ModuleLocation>::iterator i = m_module_locations.begin(); i != m_module_locations.end(); ++i) { + if ((*i).name == name && (*i).type == type) + return (*i).loc; + } + + // -1 used as a flag value + Coord r = { -1, -1 }; + return r; +} + + +void +StateManager::set_module_location(const string& name, ModuleType type, Coord loc) +{ + for (std::list<ModuleLocation>::iterator i = m_module_locations.begin(); i != m_module_locations.end(); ++i) { + if ((*i).name == name && (*i).type == type) { + (*i).loc = loc; + return; + } + } + + // If we get here, module isn't in list yet + ModuleLocation ml = { name, type, loc }; + m_module_locations.push_back(ml); +} + + +/** Returns whether or not this module should be split. + * + * If nothing is known about the given module, @a default_val is returned (this is + * to allow driver's to request terminal ports get split by default). + */ +bool +StateManager::get_module_split(const string& name, bool default_val) const +{ + map<string, bool>::const_iterator i = m_module_splits.find(name); + if (i == m_module_splits.end()) + return default_val; + else + return (*i).second; +} + + +void +StateManager::set_module_split(const string& name, bool split) +{ + m_module_splits[name] = split; +} + + +void +StateManager::load(const string& filename) +{ + m_module_locations.clear(); + + cerr << "Loading configuration file " << filename << endl; + + std::ifstream is; + is.open(filename.c_str(), std::ios::in); + + if ( ! is.good()) { + std::cerr << "Unable to load file " << filename << "!" << endl; + return; + } + + string s; + + is >> s; + if (s != "window_location") throw "Corrupt settings file."; + is >> s; + m_window_location.x = atoi(s.c_str()); + is >> s; + m_window_location.y = atoi(s.c_str()); + + is >> s; + if (s != "window_size") throw "Corrupt settings file."; + is >> s; + m_window_size.x = atoi(s.c_str()); + is >> s; + m_window_size.y = atoi(s.c_str()); + + is >> s; + if (s != "zoom_level") throw "Corrupt settings file."; + is >> s; + m_zoom = atof(s.c_str()); + + ModuleLocation ml; + while (1) { + is >> s; + if (is.eof()) break; + + // Old versions didn't quote, so need to support both :/ + if (s[0] == '\"') { + if (s.length() > 1 && s[s.length()-1] == '\"') { + ml.name = s.substr(1, s.length()-2); + } else { + ml.name = s.substr(1); + is >> s; + while (s[s.length()-1] != '\"') { + ml.name.append(" ").append(s); + is >> s; + } + ml.name.append(" ").append(s.substr(0, s.length()-1)); + } + } else { + ml.name = s; + } + + is >> s; + if (s == "input") ml.type = Input; + else if (s == "output") ml.type = Output; + else if (s == "inputoutput") ml.type = InputOutput; + else throw "Corrupt settings file."; + + is >> s; + ml.loc.x = atoi(s.c_str()); + is >> s; + ml.loc.y = atoi(s.c_str()); + + m_module_locations.push_back(ml); + } + + is.close(); +} + + +void +StateManager::save(const string& filename) +{ + std::ofstream os; + os.open(filename.c_str(), std::ios::out); + + os << "window_location " << m_window_location.x << " " << m_window_location.y << std::endl; + os << "window_size " << m_window_size.x << " " << m_window_size.y << std::endl; + os << "zoom_level " << m_zoom << std::endl; + + ModuleLocation ml; + for (std::list<ModuleLocation>::iterator i = m_module_locations.begin(); i != m_module_locations.end(); ++i) { + ml = *i; + os << "\"" << ml.name << "\""; + + if (ml.type == Input) os << " input "; + else if (ml.type == Output) os << " output "; + else if (ml.type == InputOutput) os << " inputoutput "; + else throw; + + os << ml.loc.x << " " << ml.loc.y << std::endl; + } + + os.close(); +} + + +Coord +StateManager::get_window_location() +{ + return m_window_location; +} + + +void +StateManager::set_window_location(Coord loc) +{ + m_window_location = loc; +} + + +Coord +StateManager::get_window_size() +{ + return m_window_size; +} + + +void +StateManager::set_window_size(Coord size) +{ + m_window_size = size; +} + + +float +StateManager::get_zoom() +{ + return m_zoom; +} + + +void +StateManager::set_zoom(float zoom) +{ + m_zoom = zoom; +} + + +int +StateManager::get_port_color(PortType type) +{ + if (type == JACK_AUDIO) + return 0x305171FF; + else if (type == JACK_MIDI) + return 0x663939FF; + else if (type == ALSA_MIDI) + return 0x307130FF; + else + return 0xFF0000FF; +} diff --git a/src/StateManager.h b/src/StateManager.h new file mode 100644 index 0000000..b584308 --- /dev/null +++ b/src/StateManager.h @@ -0,0 +1,75 @@ +/* This file is part of Patchage. Copyright (C) 2005 Dave Robillard. + * + * Om 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. + * + * Om 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 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 STATEMANAGER_H +#define STATEMANAGER_H + +#include <string> +#include <list> +#include <map> +#include <iostream> +#include "PatchagePort.h" + +using std::string; using std::list; using std::map; + + +enum ModuleType { Input, Output, InputOutput }; +struct Coord { double x; double y; }; + +// This should probably be moved out in to a seperate class/file.... +typedef struct ModuleLocation +{ + string name; + ModuleType type; // for distinguishing terminal modules (input or output) + Coord loc; +}; + + +class StateManager +{ +public: + StateManager(); + + void load(const string& filename); + void save(const string& filename); + + Coord get_module_location(const string& name, ModuleType type); + void set_module_location(const string& name, ModuleType type, Coord loc); + + void set_module_split(const string& name, bool split); + bool get_module_split(const string& name, bool default_val) const; + + Coord get_window_location(); + void set_window_location(Coord loc); + + Coord get_window_size(); + void set_window_size(Coord loc); + + float get_zoom(); + void set_zoom(float zoom); + + int get_port_color(PortType type); + +private: + list<ModuleLocation> m_module_locations; + map<string,bool> m_module_splits; + Coord m_window_location; + Coord m_window_size; + float m_zoom; +}; + + +#endif // STATEMANAGER_H diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..5646b1c --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,49 @@ +/* This file is part of Patchage. Copyright (C) 2005 Dave Robillard. + * + * Om 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. + * + * Om 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 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 "config.h" + +#include <iostream> +#include <libgnomecanvasmm.h> + +#include "Patchage.h" +#include "JackDriver.h" + +#ifdef HAVE_LASH +#include <lash/lash.h> +#endif // HAVE_LASH + +int main(int argc, char** argv) +{ + try { + + Gnome::Canvas::init(); + Gtk::Main app(argc, argv); + + Patchage patchage(argc, argv); + patchage.attach(); + + app.run(*patchage.window()); + + } catch (std::string msg) { + std::cerr << "Caught exception, aborting. Error message was: " << msg << std::endl; + return 1; + } + + return 0; +} + + diff --git a/src/patchage.glade b/src/patchage.glade new file mode 100644 index 0000000..322a714 --- /dev/null +++ b/src/patchage.glade @@ -0,0 +1,607 @@ +<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*--> +<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd"> + +<glade-interface> + +<widget class="GtkWindow" id="patchage_win"> + <property name="border_width">1</property> + <property name="visible">True</property> + <property name="title" translatable="yes">Patchage</property> + <property name="type">GTK_WINDOW_TOPLEVEL</property> + <property name="window_position">GTK_WIN_POS_NONE</property> + <property name="modal">False</property> + <property name="default_width">640</property> + <property name="default_height">480</property> + <property name="resizable">True</property> + <property name="destroy_with_parent">False</property> + <property name="decorated">True</property> + <property name="skip_taskbar_hint">False</property> + <property name="skip_pager_hint">False</property> + <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property> + <property name="gravity">GDK_GRAVITY_NORTH_WEST</property> + <property name="focus_on_map">True</property> + <property name="urgency_hint">False</property> + + <child> + <widget class="GtkVBox" id="main_vbox"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">0</property> + + <child> + <widget class="GtkMenuBar" id="menubar"> + <property name="visible">True</property> + <property name="pack_direction">GTK_PACK_DIRECTION_LTR</property> + <property name="child_pack_direction">GTK_PACK_DIRECTION_LTR</property> + + <child> + <widget class="GtkMenuItem" id="file_menu"> + <property name="visible">True</property> + <property name="label" translatable="yes">_File</property> + <property name="use_underline">True</property> + + <child> + <widget class="GtkMenu" id="file_menu_menu"> + + <child> + <widget class="GtkImageMenuItem" id="launch_jack_menuitem"> + <property name="visible">True</property> + <property name="label" translatable="yes">Launch Jack</property> + <property name="use_underline">True</property> + <signal name="activate" handler="on_launch_jack_menuitem_activate" last_modification_time="Wed, 05 Apr 2006 04:52:35 GMT"/> + <accelerator key="J" modifiers="GDK_CONTROL_MASK" signal="activate"/> + + <child internal-child="image"> + <widget class="GtkImage" id="image143"> + <property name="visible">True</property> + <property name="stock">gtk-execute</property> + <property name="icon_size">1</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + </child> + </widget> + </child> + + <child> + <widget class="GtkImageMenuItem" id="connect_to_jack_menuitem"> + <property name="visible">True</property> + <property name="label" translatable="yes">Connect to _Jack</property> + <property name="use_underline">True</property> + <signal name="activate" handler="on_connect_to_jack_menuitem_activate" last_modification_time="Wed, 05 Apr 2006 04:27:40 GMT"/> + <accelerator key="J" modifiers="GDK_MOD1_MASK" signal="activate"/> + + <child internal-child="image"> + <widget class="GtkImage" id="image144"> + <property name="visible">True</property> + <property name="stock">gtk-connect</property> + <property name="icon_size">1</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + </child> + </widget> + </child> + + <child> + <widget class="GtkImageMenuItem" id="disconnect_from_jack_menuitem"> + <property name="visible">True</property> + <property name="label" translatable="yes">Disconnect from Jack</property> + <property name="use_underline">True</property> + <signal name="activate" handler="on_disconnect_from_jack1_activate" last_modification_time="Sun, 21 May 2006 23:48:26 GMT"/> + <accelerator key="J" modifiers="GDK_SHIFT_MASK | GDK_MOD1_MASK" signal="activate"/> + + <child internal-child="image"> + <widget class="GtkImage" id="image145"> + <property name="visible">True</property> + <property name="stock">gtk-disconnect</property> + <property name="icon_size">1</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + </child> + </widget> + </child> + + <child> + <widget class="GtkSeparatorMenuItem" id="separator1"> + <property name="visible">True</property> + </widget> + </child> + + <child> + <widget class="GtkImageMenuItem" id="launch_lash_menuitem"> + <property name="visible">True</property> + <property name="label" translatable="yes">Launch Lash</property> + <property name="use_underline">True</property> + <signal name="activate" handler="on_launch_lash1_activate" last_modification_time="Mon, 22 May 2006 01:14:33 GMT"/> + <accelerator key="L" modifiers="GDK_CONTROL_MASK" signal="activate"/> + + <child internal-child="image"> + <widget class="GtkImage" id="image146"> + <property name="visible">True</property> + <property name="stock">gtk-execute</property> + <property name="icon_size">1</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + </child> + </widget> + </child> + + <child> + <widget class="GtkImageMenuItem" id="connect_to_lash_menuitem"> + <property name="visible">True</property> + <property name="label" translatable="yes">Connect to _Lash</property> + <property name="use_underline">True</property> + <signal name="activate" handler="on_connect_to_lash1_activate" last_modification_time="Mon, 22 May 2006 01:14:33 GMT"/> + <accelerator key="L" modifiers="GDK_MOD1_MASK" signal="activate"/> + + <child internal-child="image"> + <widget class="GtkImage" id="image147"> + <property name="visible">True</property> + <property name="stock">gtk-connect</property> + <property name="icon_size">1</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + </child> + </widget> + </child> + + <child> + <widget class="GtkImageMenuItem" id="disconnect_from_lash_menuitem"> + <property name="visible">True</property> + <property name="label" translatable="yes">Disconnect from Lash</property> + <property name="use_underline">True</property> + <signal name="activate" handler="on_disconnect_from_lash1_activate" last_modification_time="Mon, 22 May 2006 01:14:33 GMT"/> + <accelerator key="L" modifiers="GDK_SHIFT_MASK | GDK_MOD1_MASK" signal="activate"/> + + <child internal-child="image"> + <widget class="GtkImage" id="image148"> + <property name="visible">True</property> + <property name="stock">gtk-disconnect</property> + <property name="icon_size">1</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + </child> + </widget> + </child> + + <child> + <widget class="GtkSeparatorMenuItem" id="separator4"> + <property name="visible">True</property> + </widget> + </child> + + <child> + <widget class="GtkImageMenuItem" id="connect_to_alsa_menuitem"> + <property name="visible">True</property> + <property name="label" translatable="yes">Connect to _Alsa</property> + <property name="use_underline">True</property> + <signal name="activate" handler="on_connect_to_alsa_menuitem_activate" last_modification_time="Mon, 22 May 2006 00:10:31 GMT"/> + <accelerator key="A" modifiers="GDK_MOD1_MASK" signal="activate"/> + + <child internal-child="image"> + <widget class="GtkImage" id="image149"> + <property name="visible">True</property> + <property name="stock">gtk-connect</property> + <property name="icon_size">1</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + </child> + </widget> + </child> + + <child> + <widget class="GtkImageMenuItem" id="disconnect_from_alsa_menuitem"> + <property name="visible">True</property> + <property name="label" translatable="yes">Disconnect from Alsa</property> + <property name="use_underline">True</property> + <signal name="activate" handler="on_disconnect_from_alsa_menuitem_activate" last_modification_time="Mon, 22 May 2006 00:10:31 GMT"/> + <accelerator key="A" modifiers="GDK_SHIFT_MASK | GDK_MOD1_MASK" signal="activate"/> + + <child internal-child="image"> + <widget class="GtkImage" id="image150"> + <property name="visible">True</property> + <property name="stock">gtk-disconnect</property> + <property name="icon_size">1</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + </child> + </widget> + </child> + + <child> + <widget class="GtkSeparatorMenuItem" id="separator3"> + <property name="visible">True</property> + </widget> + </child> + + <child> + <widget class="GtkImageMenuItem" id="file_save_menuitem"> + <property name="visible">True</property> + <property name="label" translatable="yes">_Store Positions</property> + <property name="use_underline">True</property> + <signal name="activate" handler="on_save_settings1_activate" last_modification_time="Mon, 13 Sep 2004 02:42:14 GMT"/> + <accelerator key="S" modifiers="GDK_CONTROL_MASK" signal="activate"/> + + <child internal-child="image"> + <widget class="GtkImage" id="image151"> + <property name="visible">True</property> + <property name="stock">gtk-save</property> + <property name="icon_size">1</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + </child> + </widget> + </child> + + <child> + <widget class="GtkSeparatorMenuItem" id="separator2"> + <property name="visible">True</property> + </widget> + </child> + + <child> + <widget class="GtkImageMenuItem" id="file_quit_menuitem"> + <property name="visible">True</property> + <property name="label">gtk-quit</property> + <property name="use_stock">True</property> + <signal name="activate" handler="on_quit1_activate" last_modification_time="Sat, 11 Sep 2004 20:05:11 GMT"/> + </widget> + </child> + </widget> + </child> + </widget> + </child> + + <child> + <widget class="GtkMenuItem" id="view_menu"> + <property name="visible">True</property> + <property name="label" translatable="yes">_View</property> + <property name="use_underline">True</property> + + <child> + <widget class="GtkMenu" id="view_menu_menu"> + + <child> + <widget class="GtkImageMenuItem" id="view_refresh_menuitem"> + <property name="visible">True</property> + <property name="label">gtk-refresh</property> + <property name="use_stock">True</property> + <signal name="activate" handler="on_item1_activate" last_modification_time="Sat, 11 Sep 2004 20:05:50 GMT"/> + </widget> + </child> + </widget> + </child> + </widget> + </child> + + <child> + <widget class="GtkMenuItem" id="help_menu"> + <property name="visible">True</property> + <property name="label" translatable="yes">_Help</property> + <property name="use_underline">True</property> + + <child> + <widget class="GtkMenu" id="help_menu_menu"> + + <child> + <widget class="GtkImageMenuItem" id="help_about_menuitem"> + <property name="visible">True</property> + <property name="label">gtk-about</property> + <property name="use_stock">True</property> + <signal name="activate" handler="on_about1_activate" last_modification_time="Sat, 11 Sep 2004 20:05:11 GMT"/> + </widget> + </child> + </widget> + </child> + </widget> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkScrolledWindow" id="canvas_scrolledwindow"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="hscrollbar_policy">GTK_POLICY_ALWAYS</property> + <property name="vscrollbar_policy">GTK_POLICY_ALWAYS</property> + <property name="shadow_type">GTK_SHADOW_NONE</property> + <property name="window_placement">GTK_CORNER_TOP_LEFT</property> + + <child> + <placeholder/> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + + <child> + <widget class="GtkHBox" id="hbox1"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">0</property> + + <child> + <widget class="GtkLabel" id="status_lab"> + <property name="visible">True</property> + <property name="label" translatable="yes"></property> + <property name="use_underline">False</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> + <property name="width_chars">-1</property> + <property name="single_line_mode">False</property> + <property name="angle">0</property> + </widget> + <packing> + <property name="padding">2</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + + <child> + <widget class="GtkSeparatorToolItem" id="separatortoolitem1"> + <property name="visible">True</property> + <property name="draw">True</property> + <property name="visible_horizontal">False</property> + <property name="visible_vertical">True</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkHBox" id="hbox2"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">0</property> + + <child> + <widget class="GtkLabel" id="label1"> + <property name="visible">True</property> + <property name="label" translatable="yes">Zoom: </property> + <property name="use_underline">False</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> + <property name="width_chars">-1</property> + <property name="single_line_mode">False</property> + <property name="angle">0</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkHScale" id="zoom_scale"> + <property name="width_request">150</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="draw_value">True</property> + <property name="value_pos">GTK_POS_RIGHT</property> + <property name="digits">1</property> + <property name="update_policy">GTK_UPDATE_CONTINUOUS</property> + <property name="inverted">False</property> + <property name="adjustment">1 0.1 2 0 0 0</property> + </widget> + <packing> + <property name="padding">5</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + </widget> + <packing> + <property name="padding">2</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + </widget> + </child> +</widget> + +<widget class="GtkWindow" id="about_win"> + <property name="width_request">320</property> + <property name="height_request">200</property> + <property name="title" translatable="yes">About Patchage</property> + <property name="type">GTK_WINDOW_TOPLEVEL</property> + <property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property> + <property name="modal">False</property> + <property name="resizable">False</property> + <property name="destroy_with_parent">False</property> + <property name="decorated">True</property> + <property name="skip_taskbar_hint">True</property> + <property name="skip_pager_hint">True</property> + <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property> + <property name="gravity">GDK_GRAVITY_NORTH_WEST</property> + <property name="focus_on_map">True</property> + <property name="urgency_hint">False</property> + + <child> + <widget class="GtkVBox" id="vbox1"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">0</property> + + <child> + <widget class="GtkLabel" id="about_project_label"> + <property name="visible">True</property> + <property name="label" translatable="yes"><span size="xx-large" weight="bold">Patchage</span></property> + <property name="use_underline">False</property> + <property name="use_markup">True</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> + <property name="width_chars">-1</property> + <property name="single_line_mode">False</property> + <property name="angle">0</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + + <child> + <widget class="GtkLabel" id="label4"> + <property name="visible">True</property> + <property name="label" translatable="yes">A modular patch bay for: + +Jack Audio Connection Kit +ALSA Sequencer</property> + <property name="use_underline">False</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_CENTER</property> + <property name="wrap">True</property> + <property name="selectable">False</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> + <property name="width_chars">-1</property> + <property name="single_line_mode">False</property> + <property name="angle">0</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkLabel" id="label3"> + <property name="visible">True</property> + <property name="label" translatable="yes">Copyright © 2005 Dave Robillard</property> + <property name="use_underline">False</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> + <property name="width_chars">-1</property> + <property name="single_line_mode">False</property> + <property name="angle">0</property> + </widget> + <packing> + <property name="padding">10</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkHButtonBox" id="hbuttonbox1"> + <property name="visible">True</property> + <property name="layout_style">GTK_BUTTONBOX_DEFAULT_STYLE</property> + <property name="spacing">0</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkHButtonBox" id="hbuttonbox2"> + <property name="visible">True</property> + <property name="layout_style">GTK_BUTTONBOX_DEFAULT_STYLE</property> + <property name="spacing">0</property> + + <child> + <widget class="GtkButton" id="about_close_button"> + <property name="width_request">66</property> + <property name="height_request">26</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="label">gtk-close</property> + <property name="use_stock">True</property> + <property name="relief">GTK_RELIEF_NORMAL</property> + <property name="focus_on_click">True</property> + </widget> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + </widget> + </child> +</widget> + +</glade-interface> diff --git a/src/patchage.gladep b/src/patchage.gladep new file mode 100644 index 0000000..8d205c3 --- /dev/null +++ b/src/patchage.gladep @@ -0,0 +1,9 @@ +<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*--> +<!DOCTYPE glade-project SYSTEM "http://glade.gnome.org/glade-project-2.0.dtd"> + +<glade-project> + <name>Patchage</name> + <program_name>patchage</program_name> + <language>C++</language> + <gnome_support>FALSE</gnome_support> +</glade-project> |