Assists music production by grouping standalone programs into sessions. Community version of "Non Session Manager".
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

287 lines
5.9KB

  1. /*******************************************************************************/
  2. /* Copyright (C) 2008 Jonathan Moore Liles */
  3. /* */
  4. /* This program is free software; you can redistribute it and/or modify it */
  5. /* under the terms of the GNU General Public License as published by the */
  6. /* Free Software Foundation; either version 2 of the License, or (at your */
  7. /* option) any later version. */
  8. /* */
  9. /* This program is distributed in the hope that it will be useful, but WITHOUT */
  10. /* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
  11. /* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for */
  12. /* more details. */
  13. /* */
  14. /* You should have received a copy of the GNU General Public License along */
  15. /* with This program; see the file COPYING. If not,write to the Free Software */
  16. /* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
  17. /*******************************************************************************/
  18. /* Routings for opening/closing/creation of projects. All the actual
  19. project state belongs to Timeline and other classes. */
  20. #include <stdio.h>
  21. #include <stdlib.h>
  22. #include <string.h>
  23. #include <sys/stat.h>
  24. #include <sys/types.h>
  25. #include <fcntl.h>
  26. #include <errno.h>
  27. #include "Loggable.H"
  28. #include "Project.H"
  29. #include "Timeline.H" // for sample_rate();
  30. #include "TLE.H" // all this just for load and save...
  31. #include <FL/filename.H>
  32. extern TLE *tle;
  33. /* FIXME: wrong place for this */
  34. #define APP_TITLE "Non-DAW"
  35. #define PROJECT_VERSION "0.28.0"
  36. #include "util/debug.h"
  37. char Project::_name[256];
  38. char Project::_path[512];
  39. bool Project::_is_open = false;
  40. int Project::_lockfd = 0;
  41. bool
  42. Project::get_lock ( const char *filename )
  43. {
  44. struct flock fl;
  45. fl.l_type = F_WRLCK;
  46. fl.l_whence = SEEK_SET;
  47. fl.l_start = 0;
  48. fl.l_len = 0;
  49. assert( ! _lockfd );
  50. _lockfd = ::creat( filename, 0777 );
  51. if ( fcntl( _lockfd, F_SETLK, &fl ) != 0 )
  52. return false;
  53. return true;
  54. }
  55. void
  56. Project::release_lock ( const char *filename )
  57. {
  58. unlink( filename );
  59. ::close( _lockfd );
  60. _lockfd = 0;
  61. }
  62. static int
  63. exists ( const char *name )
  64. {
  65. struct stat st;
  66. return 0 == stat( name, &st );
  67. }
  68. void
  69. Project::set_name ( const char *name )
  70. {
  71. strcpy( Project::_name, name );
  72. if ( Project::_name[ strlen( Project::_name ) - 1 ] == '/' )
  73. Project::_name[ strlen( Project::_name ) - 1 ] = '\0';
  74. char *s = rindex( Project::_name, '/' );
  75. s = s ? s + 1 : Project::_name;
  76. memmove( Project::_name, s, strlen( s ) + 1 );
  77. for ( s = Project::_name; *s; ++s )
  78. if ( *s == '_' || *s == '-' )
  79. *s = ' ';
  80. }
  81. bool
  82. Project::close ( void )
  83. {
  84. if ( ! open() )
  85. return true;
  86. tle->save_timeline_settings();
  87. Loggable::close();
  88. write_info();
  89. _is_open = false;
  90. *Project::_name = '\0';
  91. release_lock( ".lock" );
  92. return true;
  93. }
  94. bool
  95. Project::write_info ( void )
  96. {
  97. if ( ! open() )
  98. return true;
  99. FILE *fp;
  100. if ( ! ( fp = fopen( "info", "w" ) ) )
  101. {
  102. WARNING( "could not open project info file for writing." );
  103. return false;
  104. }
  105. fprintf( fp, "created by\n\t%s\nversion\n\t%s\nsample rate\n\t%lu\n",
  106. APP_TITLE " " VERSION,
  107. PROJECT_VERSION,
  108. (unsigned long)timeline->sample_rate() );
  109. fclose( fp );
  110. return true;
  111. }
  112. bool
  113. Project::read_info ( void )
  114. {
  115. FILE *fp;
  116. if ( ! ( fp = fopen( "info", "r" ) ) )
  117. {
  118. WARNING( "could not open project info file for reading." );
  119. return false;
  120. }
  121. /* TODO: something */
  122. fclose( fp );
  123. return true;
  124. }
  125. /** ensure a project is valid before opening it... */
  126. bool
  127. Project::validate ( const char *name )
  128. {
  129. bool r = true;
  130. char pwd[512];
  131. fl_filename_absolute( pwd, sizeof( pwd ), "." );
  132. if ( chdir( name ) )
  133. {
  134. WARNING( "Cannot change to project dir \"%s\"", name );
  135. return false;
  136. }
  137. if ( ! exists( "info" ) ||
  138. ! exists( "history" ) ||
  139. ! exists( "sources" ) )
  140. // ! exists( "options" ) )
  141. {
  142. WARNING( "Not a Non-DAW project: \"%s\"", name );
  143. r = false;
  144. }
  145. chdir( pwd );
  146. return r;
  147. }
  148. bool
  149. Project::open ( const char *name )
  150. {
  151. if ( ! validate( name ) )
  152. return false;
  153. close();
  154. chdir( name );
  155. if ( ! get_lock( ".lock" ) )
  156. {
  157. WARNING( "Could not open project: locked by another process!" );
  158. return false;
  159. }
  160. if ( ! Loggable::open( "history" ) )
  161. FATAL( "error opening journal" );
  162. set_name( name );
  163. *_path = '\0';
  164. fl_filename_absolute( _path, sizeof( _path ), "." );
  165. read_info();
  166. _is_open = true;
  167. tle->load_timeline_settings();
  168. timeline->zoom_fit();
  169. return true;
  170. }
  171. bool
  172. Project::create ( const char *name, const char *template_name )
  173. {
  174. if ( exists( name ) )
  175. {
  176. WARNING( "Project already exists" );
  177. return false;
  178. }
  179. close();
  180. if ( mkdir( name, 0777 ) )
  181. {
  182. WARNING( "Cannot create project directory" );
  183. return false;
  184. }
  185. if ( chdir( name ) )
  186. FATAL( "WTF? Cannot change to new project directory" );
  187. mkdir( "sources", 0777 );
  188. creat( "info", 0666 );
  189. creat( "history", 0666 );
  190. /* TODO: copy template */
  191. if ( open( name ) )
  192. {
  193. write_info();
  194. /* add the bare essentials */
  195. timeline->beats_per_minute( 0, 120 );
  196. timeline->time( 0, 4, 4 );
  197. return true;
  198. }
  199. else
  200. return false;
  201. }