diff options
Diffstat (limited to 'src/frontend/hd24connect.cpp')
-rwxr-xr-x | src/frontend/hd24connect.cpp | 326 |
1 files changed, 326 insertions, 0 deletions
diff --git a/src/frontend/hd24connect.cpp b/src/frontend/hd24connect.cpp new file mode 100755 index 0000000..b31b758 --- /dev/null +++ b/src/frontend/hd24connect.cpp | |||
@@ -0,0 +1,326 @@ | |||
1 | #define MAINDEBUG 0 | ||
2 | #include <FL/Fl.H> | ||
3 | #include <FL/Fl_Window.H> | ||
4 | #include <FL/Fl_Box.H> | ||
5 | #include "ui_hd24connect.h" | ||
6 | #include <hd24fs.h> | ||
7 | #include <hd24utils.h> | ||
8 | #include <FL/x.H> //dave | ||
9 | #ifdef LINUX | ||
10 | #include <X11/xpm.h> //dave | ||
11 | #endif | ||
12 | #include "images/hd24connect_64x64.xpm" //dave | ||
13 | #include <iostream> | ||
14 | #include <string> | ||
15 | #include <stdlib.h> | ||
16 | #include <hd24utils.h> | ||
17 | #ifndef MAX_PATH | ||
18 | #define MAX_PATH 127 | ||
19 | #endif | ||
20 | |||
21 | #ifdef WINDOWS | ||
22 | #include <windows.h> | ||
23 | #define IDI_ICON1 101 | ||
24 | #endif | ||
25 | string device; | ||
26 | string headerfilename; | ||
27 | int force; | ||
28 | int maintmode; | ||
29 | int wavefixmode; | ||
30 | int testmode; | ||
31 | #ifdef LINUX | ||
32 | #define TIMEOUT 0.03 | ||
33 | #endif | ||
34 | #define ARGDEV "--dev=" | ||
35 | #define ARGHEADER "--header=" | ||
36 | #define ARGFORCE "--force" | ||
37 | #define ARGMAINT "--maint" | ||
38 | #define ARGWAVEFIX "--wavefix" | ||
39 | #define ARGTEST "--test" | ||
40 | |||
41 | #include "selftest.cpp" | ||
42 | |||
43 | int parsecommandline(int argc, char ** argv) | ||
44 | { | ||
45 | int invalid=0; | ||
46 | force=0; | ||
47 | maintmode=0; | ||
48 | wavefixmode=0; | ||
49 | testmode=0; | ||
50 | device=""; | ||
51 | for (int c=1;c<argc;c++) { | ||
52 | |||
53 | string arg=argv[c]; | ||
54 | if (arg.substr(0,1)=="-") { | ||
55 | if (arg.substr(1,1)!="-") { | ||
56 | continue; // skip single-dash arguments | ||
57 | // for instance to skip -display | ||
58 | // and to skip macOS process number | ||
59 | } | ||
60 | } | ||
61 | if (arg.substr(0,strlen(ARGTEST))==ARGTEST) { | ||
62 | testmode=1; | ||
63 | continue; | ||
64 | } | ||
65 | if (arg.substr(0,strlen(ARGDEV))==ARGDEV) { | ||
66 | device=arg.substr(strlen(ARGDEV)); | ||
67 | continue; | ||
68 | } | ||
69 | if (arg.substr(0,strlen(ARGMAINT))==ARGMAINT) { | ||
70 | maintmode=1; | ||
71 | #if (MAINDEBUG==1) | ||
72 | cout << "Running in maintenance mode." << endl; | ||
73 | #endif | ||
74 | continue; | ||
75 | } | ||
76 | if (arg.substr(0,strlen(ARGWAVEFIX))==ARGWAVEFIX) { | ||
77 | wavefixmode=1; | ||
78 | #if (MAINDEBUG==1) | ||
79 | cout << "Running in wavefix mode." << endl; | ||
80 | #endif | ||
81 | continue; | ||
82 | } | ||
83 | if (arg.substr(0,strlen(ARGHEADER))==ARGHEADER) { | ||
84 | headerfilename=arg.substr(strlen(ARGHEADER)); | ||
85 | continue; | ||
86 | } | ||
87 | if (arg.substr(0,strlen(ARGFORCE))==(ARGFORCE)) { | ||
88 | force=1; | ||
89 | continue; | ||
90 | } | ||
91 | #ifdef DARWIN | ||
92 | // on MacOS ignore all crap on the command line | ||
93 | // (system adds process ID info etc) | ||
94 | continue; | ||
95 | #endif | ||
96 | |||
97 | #if (MAINDEBUG==1) | ||
98 | cout << "Invalid argument: " << arg << endl; | ||
99 | #endif | ||
100 | invalid=1; | ||
101 | } | ||
102 | return invalid; | ||
103 | } | ||
104 | |||
105 | int isabsolutepath(const char* pathname) { | ||
106 | if (pathname[0]=='/') return (1==1); | ||
107 | if (pathname[0]=='\\') return (1==1); | ||
108 | if (pathname[1]==':') return (1==1); | ||
109 | return (1==0); | ||
110 | } | ||
111 | |||
112 | void getprogdir(const char* currpath,const char* callpath,char* result) { | ||
113 | if (isabsolutepath(callpath)) { | ||
114 | strncpy(result,callpath,strlen(callpath)+1); | ||
115 | return; | ||
116 | } | ||
117 | strcat(result,currpath); | ||
118 | #ifdef WINDOWS | ||
119 | strcat(result,"\\\0"); | ||
120 | #else | ||
121 | strcat(result,"/\0"); | ||
122 | #endif | ||
123 | |||
124 | if (strcmp(callpath,"./")!=0) { | ||
125 | strcat(result,callpath); | ||
126 | } | ||
127 | return; | ||
128 | } | ||
129 | |||
130 | |||
131 | int main(int argc, char **argv) { | ||
132 | |||
133 | int result=0; | ||
134 | |||
135 | /* First, the program will figure out its own | ||
136 | absolute program path. This will be used | ||
137 | for loading libraries after program startup, | ||
138 | rather than having hard dependencies *during*. */ | ||
139 | char* currentworkingdir=(char*)malloc(2048); | ||
140 | #if (MAINDEBUG==1) | ||
141 | cout << "Welcome to HD24connect" << endl; | ||
142 | #endif | ||
143 | string currname=argv[0]; | ||
144 | string rawname=""; | ||
145 | #if (MAINDEBUG==1) | ||
146 | cout << "Currname=" << currname << endl; | ||
147 | #endif | ||
148 | do { | ||
149 | string lastchar=""; | ||
150 | lastchar+=currname.substr(currname.length()-1,1); | ||
151 | if ((lastchar=="/") || (lastchar=="\\")) { | ||
152 | break; | ||
153 | } | ||
154 | rawname=currname.substr(currname.length()-1,1)+rawname; | ||
155 | currname=currname.substr(0,currname.length()-1); | ||
156 | |||
157 | if (currname=="") break; | ||
158 | } while (1==1); | ||
159 | // currname=path given on commandline | ||
160 | |||
161 | char cwd[2048]; | ||
162 | char* mycwd=getcwd(&cwd[0],2048); | ||
163 | mycwd=&cwd[0]; | ||
164 | #if (MAINDEBUG==1) | ||
165 | cout << "cwd=" << cwd << endl; | ||
166 | #endif | ||
167 | char absprogpath[2048]; | ||
168 | char fullname[2048]; | ||
169 | absprogpath[0]='\0'; | ||
170 | getprogdir(&cwd[0],currname.c_str(),&absprogpath[0]); | ||
171 | |||
172 | #if (MAINDEBUG==1) | ||
173 | cout << "absprogpath=" << absprogpath << endl; | ||
174 | #endif | ||
175 | free(currentworkingdir); | ||
176 | |||
177 | /* | ||
178 | * Either absprogpath now contains absolute program path | ||
179 | * (if called from current path or by specifying path) | ||
180 | * or we need to traverse the OS PATH. | ||
181 | */ | ||
182 | strncpy(fullname,absprogpath,2048); | ||
183 | strcat(fullname,rawname.c_str()); | ||
184 | #if (MAINDEBUG==1) | ||
185 | cout << "fullname=" << fullname << endl; | ||
186 | #endif | ||
187 | if (!(hd24utils::fileExists(fullname))) { | ||
188 | /* File according to full name does not exist. */ | ||
189 | #if (MAINDEBUG==1) | ||
190 | cout << "rawname=" << rawname << ", path=" << getenv("PATH") << endl; | ||
191 | #endif | ||
192 | hd24utils::findfile(&rawname[0],getenv("PATH"),&absprogpath[0]); | ||
193 | if (strlen(absprogpath)==0) { | ||
194 | cout << "Cannot find executable. "<< endl; | ||
195 | return 0; | ||
196 | } | ||
197 | } | ||
198 | // The final word on which path contains the exe is absprogpath. | ||
199 | #if (MAINDEBUG==1) | ||
200 | cout << "The final word on where the exe is, is: " << absprogpath << endl; | ||
201 | cout << "main debugmode enabled." << endl; | ||
202 | cout << " Sizeof float=" << sizeof(float) << endl; | ||
203 | #endif | ||
204 | char initial_path[MAX_PATH]; | ||
205 | mycwd=getcwd(initial_path,MAX_PATH); | ||
206 | // This prints the path+filename to ourselves: | ||
207 | // If we run from current dir, argv is just filename; | ||
208 | // otherwise missing part of path+filename. | ||
209 | // So initial path+filename always renders the complete path. | ||
210 | int invalid=parsecommandline(argc,argv); | ||
211 | if (invalid!=0) { | ||
212 | return invalid; | ||
213 | } | ||
214 | //force=0; | ||
215 | |||
216 | hd24fs* sysob=NULL; | ||
217 | if (testmode==1) | ||
218 | { | ||
219 | #ifdef LINUX | ||
220 | fl_open_display(); | ||
221 | #endif | ||
222 | HD24UserInterface ui(argc,argv,absprogpath); | ||
223 | // testmode active- run self test. | ||
224 | result=runselftest(&ui); | ||
225 | cout << "Selftest run complete - Thank you for using HD24connect." << endl; | ||
226 | ui.finish(); | ||
227 | return result; | ||
228 | } | ||
229 | |||
230 | string* imagedir=hd24utils::getlastdir("driveimagedir"); | ||
231 | #if (MAINDEBUG==1) | ||
232 | cout << "imagedir="<<*imagedir<< endl; | ||
233 | #endif | ||
234 | if (device=="") { | ||
235 | sysob=new hd24fs(imagedir->c_str(),hd24fs::MODE_RDWR); | ||
236 | } else { | ||
237 | cout << "Trying to use " << device << " as hd24 device." << endl; | ||
238 | sysob=new hd24fs(imagedir->c_str(),hd24fs::MODE_RDWR,&device,(force==1)); | ||
239 | if (!(sysob->isOpen())) | ||
240 | { | ||
241 | if (!force) { | ||
242 | cout << "Cannot open hd24 device" << endl; | ||
243 | delete sysob; | ||
244 | return 1; | ||
245 | } | ||
246 | } | ||
247 | } | ||
248 | delete imagedir; | ||
249 | if (headerfilename!="") | ||
250 | { | ||
251 | if (!(sysob->useheaderfile(headerfilename))) | ||
252 | { | ||
253 | cout << "Couldn't load header file "<<headerfilename << endl; | ||
254 | }; | ||
255 | } | ||
256 | #if (MAINDEBUG==1) | ||
257 | cout << "mdb(2)" << endl; | ||
258 | #endif | ||
259 | // Fl::scheme("gtk+"); | ||
260 | #ifdef LINUX | ||
261 | fl_open_display(); | ||
262 | #endif | ||
263 | HD24UserInterface ui(argc,argv,absprogpath); | ||
264 | #if (MAINDEBUG==1) | ||
265 | cout << "mdb(3b)" << endl; | ||
266 | #endif | ||
267 | sysob->setmaintenancemode(maintmode); | ||
268 | sysob->setwavefixmode(wavefixmode); | ||
269 | #if (MAINDEBUG==1) | ||
270 | cout << "mdb(3c)" << endl; | ||
271 | #endif | ||
272 | Fl_Window *window = ui.make_window(sysob); | ||
273 | #if (MAINDEBUG==1) | ||
274 | cout << "mdb(3d)" << endl; | ||
275 | #endif | ||
276 | #ifdef WINDOWS | ||
277 | |||
278 | window->icon((char *)LoadIcon(fl_display,MAKEINTRESOURCE(IDI_ICON1))); | ||
279 | #endif | ||
280 | window->end(); | ||
281 | window->show(); //argc, argv); | ||
282 | |||
283 | #ifdef LINUX //dave | ||
284 | Pixmap p, mask; | ||
285 | XpmCreatePixmapFromData(fl_display,DefaultRootWindow(fl_display),(char **)hd24connect_xpm, &p, &mask, NULL); | ||
286 | |||
287 | /* | ||
288 | FLTK support for transparent background is broken. So instead of this: | ||
289 | window->icon((char *)p); | ||
290 | We will write the following: */ | ||
291 | XWMHints *hints=NULL; | ||
292 | hints = XGetWMHints(fl_display, fl_xid(window)); | ||
293 | hints->icon_pixmap = p; | ||
294 | hints->icon_mask = mask; | ||
295 | hints->flags = IconPixmapHint | IconMaskHint; | ||
296 | XSetWMHints(fl_display, fl_xid(window), hints); | ||
297 | /* -- end of transparency fix */ | ||
298 | #endif | ||
299 | #if (MAINDEBUG==1) | ||
300 | cout << "mdb(3)" << endl; | ||
301 | #endif | ||
302 | #if (MAINDEBUG==1) | ||
303 | cout << "mdb(4)" << endl; | ||
304 | #endif | ||
305 | if (!(sysob->isOpen())) | ||
306 | { | ||
307 | window->deactivate(); | ||
308 | fl_message("No valid HD24 drive is connected to the system.\nUse the File menu to resolve this problem."); | ||
309 | window->activate(); | ||
310 | } | ||
311 | // run normally. | ||
312 | result= Fl::run(); | ||
313 | ui.control->ready(0); | ||
314 | #ifndef WINDOWS | ||
315 | cout << "Thank you for using HD24connect." << endl; | ||
316 | #endif | ||
317 | // ui.finish(); | ||
318 | |||
319 | #ifdef hints | ||
320 | if (hints!=NULL) | ||
321 | { | ||
322 | delete hints; | ||
323 | } | ||
324 | #endif | ||
325 | return result; | ||
326 | } | ||