Merge pull request #506 from andrewcsmith/patch-2
[supercollider.git] / editors / scapp / post_queue.M
blobcea16edd397c8251fb6736c4574c2f1472cdda15
1 /*
2 SuperCollider real time audio synthesis system
3 Copyright (c) 2002 James McCartney. All rights reserved.
4 http://www.audiosynth.com
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 #include <unistd.h>
23 #include <stdlib.h>
24 #include <stdio.h>
25 #include <stdarg.h>
26 #include <pthread.h>
27 #include <SCGeom.h>
28 #import <Cocoa/Cocoa.h>
30 char *gHomePath;
31 CFBundleRef gMainBundle;
32 NSTextView *gPostView;
33 SCColor postTextColor;
35 void SetupHomeDirectory();
36 void SetupHomeDirectory()
38 char path[2048];
39 gMainBundle = CFBundleGetMainBundle();
40 CFURLRef mainURL = CFBundleCopyBundleURL(gMainBundle);
41 CFStringRef mainPath = CFURLCopyFileSystemPath(mainURL, kCFURLPOSIXPathStyle);
42 CFStringGetCString(mainPath, path, 2048, kCFStringEncodingUTF8);
43 *strrchr(path, '/') = 0;
44 int mainPathLen = strlen(path);
47 path[mainPathLen] = '/';
49 CFURLRef sharedURL = CFBundleCopySharedSupportURL(gMainBundle);
50 CFStringRef sharedPath = CFURLCopyFileSystemPath(sharedURL, kCFURLPOSIXPathStyle);
51 CFStringGetCString(sharedPath, path+mainPathLen+1, 2048-mainPathLen-1, kCFStringEncodingUTF8);
54 gHomePath = (char*)malloc(mainPathLen + 1);
55 strcpy(gHomePath, path);
56 chdir(gHomePath);
61 struct PostBuf {
62 char *buf;
63 long wrpos;
64 long rdpos;
65 pthread_mutex_t mutex;
67 void Init();
68 void Flush();
71 static PostBuf mainPostBuf;
73 #define POSTBUFLEN 131072
74 #define POSTBUFMASK 131071
76 FILE *postfile=NULL;
78 void PostBuf::Init()
80 buf = (char *)malloc(POSTBUFLEN);
81 //HoldMemory(buf, POSTBUFLEN);
82 postTextColor = SCMakeColor(0.0, 0.0, 0.0, 1.0); //default black
83 wrpos = 0;
84 rdpos = 0;
85 pthread_mutex_init(&mutex, NULL);
88 void initPostBuffer();
89 void initPostBuffer()
91 mainPostBuf.Init();
94 void setPostFile(FILE *file)
96 postfile = file;
99 void vposttext(const char *str, int length);
100 void vposttext(const char *str, int length)
102 pthread_mutex_lock(&mainPostBuf.mutex);
104 if (postfile) {
105 fwrite(str, length, 1, postfile);
106 fflush(postfile);
109 for (int i=0; i<length && str[i]; ++i) {
110 if (((mainPostBuf.wrpos+1) & POSTBUFMASK) == mainPostBuf.rdpos) {
111 break;
112 //mainPostBuf.Flush(); CANNOT DO THIS FROM OTHER THAN COCOA'S THREAD!
114 if (str[i] == '\n') mainPostBuf.buf[mainPostBuf.wrpos] = '\r';
115 else mainPostBuf.buf[mainPostBuf.wrpos] = str[i];
116 mainPostBuf.wrpos = (mainPostBuf.wrpos+1) & POSTBUFMASK;
118 pthread_mutex_unlock(&mainPostBuf.mutex);
121 extern "C" {
122 int vpost(const char *fmt, va_list vargs);
125 int vpost(const char *fmt, va_list vargs)
127 char str[512];
129 int len = vsnprintf(str, 512, fmt, vargs);
130 vposttext(str, len);
131 return 0;
134 void postfl(const char *fmt, ...);
135 void postfl(const char *fmt, ...)
137 va_list vargs;
139 if (gPostView) {
140 va_start(vargs, fmt);
141 vpost(fmt, vargs);
145 void post(const char *fmt, ...);
146 void post(const char *fmt, ...)
148 va_list vargs;
150 if (gPostView) {
151 va_start(vargs, fmt);
152 vpost(fmt, vargs);
156 void error(const char *fmt, ...);
157 void error(const char *fmt, ...)
159 va_list vargs;
161 if (gPostView) {
162 post("\xa5 ERROR: ");
163 va_start(vargs, fmt);
164 vpost(fmt, vargs);
170 void postText(const char *text, long length);
171 void postText(const char *text, long length)
173 if (gPostView) {
174 vposttext(text, length);
178 void postChar(char c);
179 void postChar(char c)
181 if (gPostView) {
182 vposttext(&c, 1);
187 void flushPostBuf();
188 void flushPostBuf()
190 // can't from other threads..
191 mainPostBuf.Flush();
194 void PostBuf::Flush()
196 long numtoread;
197 long localwritepos = wrpos;
199 if (localwritepos >= rdpos) {
200 numtoread = localwritepos - rdpos;
201 } else {
202 numtoread = POSTBUFLEN - (rdpos - localwritepos);
204 if (numtoread > 0) {
205 long endpos;
206 endpos = rdpos + numtoread;
207 if (endpos > POSTBUFLEN) {
208 // wrap around end in two copies
209 long firstpart, secondpart;
211 firstpart = POSTBUFLEN - rdpos;
212 endpos -= POSTBUFLEN;
213 secondpart = endpos;
215 if (gPostView) {
216 NSString* string;
217 NSRange range = [gPostView selectedRange];
219 if ([gPostView shouldChangeTextInRange: range replacementString: nil]) {
220 // string = [NSString stringWithCString: buf + rdpos length: firstpart];
221 string = [NSString stringWithCString: buf + rdpos encoding:NSASCIIStringEncoding];
222 string = [string substringToIndex:firstpart];
223 [gPostView replaceCharactersInRange: range withString: string];
225 // string = [NSString stringWithCString: buf length: secondpart];
226 string = [NSString stringWithCString: buf encoding:NSASCIIStringEncoding];
227 string = [string substringToIndex: secondpart];
228 range = [gPostView selectedRange];
229 [gPostView replaceCharactersInRange: range withString: string];
230 [gPostView didChangeText];
232 range = [gPostView selectedRange];
233 [gPostView scrollRangeToVisible: range];
236 rdpos = endpos;
237 } else {
238 if (gPostView) {
239 // NSString* string = [NSString stringWithCString: buf + rdpos length: numtoread];
240 NSString* string = [NSString stringWithCString:buf + rdpos encoding:NSASCIIStringEncoding];
241 string = [string substringToIndex:numtoread];
242 NSRange range = [gPostView selectedRange];
244 if ([gPostView shouldChangeTextInRange: range replacementString: string]) {
245 [gPostView replaceCharactersInRange: range withString: string];
246 [gPostView setTextColor: [NSColor colorWithCalibratedRed: postTextColor.red
247 green: postTextColor.green
248 blue: postTextColor.blue
249 alpha: postTextColor.alpha]
250 range: NSMakeRange(range.location, [gPostView selectedRange].location - range.location)];
251 [gPostView didChangeText];
253 range = [gPostView selectedRange];
254 [gPostView scrollRangeToVisible: range];
257 if (endpos == POSTBUFLEN) rdpos = 0;
258 else rdpos = endpos;