3e55f54c2f42d93a1c3a0bd3e60ac21eca8445c5
[scilab.git] / scilab / modules / console / src / c / windows / TermLine.c
1 /*
2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2008 - DIGITEO - Allan CORNET
4
5 * This file must be used under the terms of the CeCILL.
6 * This source file is licensed as described in the file COPYING, which
7 * you should have received as part of this distribution.  The terms
8 * are also available at    
9 * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
10 *
11 */
12
13 /*--------------------------------------------------------------------------*/
14 #include <windows.h>
15 #include <wincon.h>
16 #include <stdio.h>
17 #include <string.h>
18 #include "stack-def.h"
19 #include "TermLine.h"
20 #include "HistoryManager.h"
21 #include "TermConsole.h"
22 #include "localization.h"
23 #include "MALLOC.h"
24 #include "strdup_windows.h"
25 #include "TermPosition.h"
26 #include "../../../windows_tools/src/c/scilab_windows/console.h"
27 #include "strdup_windows.h"
28 /*--------------------------------------------------------------------------*/
29 static int CURRENT_MAX_LINE_SIZE = bsiz;
30 static char *cur_line = NULL;   /* current contents of the line */      
31 static char *currentPrompt = NULL;
32 static int cur_pos = 0;         /* current position of the cursor */
33 static int max_pos = 0;
34 /*--------------------------------------------------------------------------*/
35 /* do backspace on line */
36 static void backSpace(void);
37 static void initializeLineBuffer(void);
38 static void reallocLineBuffer(void);
39 /*--------------------------------------------------------------------------*/
40 static void initializeLineBuffer(void)
41 {
42         int i = 0;
43         if (cur_line)
44         {
45                 FREE(cur_line);
46                 cur_line = NULL;
47         }
48         cur_line = (char*) MALLOC(sizeof(char)*CURRENT_MAX_LINE_SIZE);
49         if (cur_line)
50         {
51                 for (i = 0; i < CURRENT_MAX_LINE_SIZE; i++) cur_line[i] = '\0';
52         }
53         else
54         {
55                 fprintf(stderr, "Error: Buffer line allocation.\n");
56                 exit(1);
57         }
58 }
59 /*--------------------------------------------------------------------------*/
60 static void reallocLineBuffer(void)
61 {
62         if (cur_line)
63         {
64                 if ( max_pos > (CURRENT_MAX_LINE_SIZE - 1) )
65                 {
66                         char *ptrBackup = cur_line;
67                         int newCURRENT_MAX_LINE_SIZE = CURRENT_MAX_LINE_SIZE * 2;
68                         cur_line = (char*)REALLOC(cur_line, sizeof(char)*(newCURRENT_MAX_LINE_SIZE));
69                         if (cur_line == NULL)
70                         {
71                                 cur_line = ptrBackup;
72                         }
73                         else
74                         {
75                                 CURRENT_MAX_LINE_SIZE = newCURRENT_MAX_LINE_SIZE;
76                         }
77                 }
78         }
79         else
80         {
81                 initializeLineBuffer();
82         }
83 }
84 /*--------------------------------------------------------------------------*/
85 void moveBeginningLine(void)
86 {
87         reallocLineBuffer();
88         while (cur_pos > 0)
89         {
90                 cur_pos -= 1;
91                 backSpace();
92         }
93 }
94 /*--------------------------------------------------------------------------*/
95 void moveEndLine(void)
96 {
97         reallocLineBuffer();
98         while (cur_pos < max_pos)
99         {
100                 TerminalPutc (cur_line[cur_pos]);
101                 cur_pos += 1;
102         }
103 }
104 /*--------------------------------------------------------------------------*/
105 void moveBackSingleChar(void)
106 {
107         reallocLineBuffer();
108         if (cur_pos > 0)
109         {
110                 cur_pos -= 1;
111                 backSpace();
112         }
113 }
114 /*--------------------------------------------------------------------------*/
115 void moveForwardSingleChar(void)
116 {
117         reallocLineBuffer();
118         if (cur_pos < max_pos)
119         {
120                 TerminalPutc(cur_line[cur_pos]);
121                 cur_pos += 1;
122         }
123 }
124 /*--------------------------------------------------------------------------*/
125 void moveBackSingleWord(void)
126 {
127         reallocLineBuffer();
128         while ((cur_pos > 0) && (isspace(cur_line[cur_pos - 1]) ))
129         {
130                 cur_pos -= 1;
131                 backSpace ();
132         }
133         while ((cur_pos > 0) && ( !isspace(cur_line[cur_pos - 1]) ))
134         {
135                 cur_pos -= 1;
136                 backSpace ();
137         }
138         refreshLine();
139 }
140 /*--------------------------------------------------------------------------*/
141 void moveForwardSingleWord(void)
142 {
143         reallocLineBuffer();
144         while ( !isspace(cur_line[cur_pos]) && (cur_pos < max_pos) ) 
145         {
146                 TerminalPutc(cur_line[cur_pos]);
147                 cur_pos++;
148         }
149         while ( isspace(cur_line[cur_pos]) && (cur_pos < max_pos) ) 
150         {
151                 TerminalPutc(cur_line[cur_pos]);
152                 cur_pos++;
153         }
154         refreshLine();
155 }
156 /*--------------------------------------------------------------------------*/
157 void killCurrentPositionToEndLine(void)
158 {
159         int i = 0;
160         reallocLineBuffer();
161         for (i = cur_pos; i < max_pos; i++)  cur_line[i] = '\0';
162         for (i = cur_pos; i < max_pos; i++) TerminalPutc(VK_SPACE);
163         for (i = cur_pos; i < max_pos; i++) backSpace ();
164         max_pos = cur_pos;
165 }
166 /*--------------------------------------------------------------------------*/
167 void deletePreviousChar(void)
168 {
169         reallocLineBuffer();
170         if (cur_pos > 0)
171         {
172                 int i = 0;
173                 cur_pos -= 1;
174                 backSpace ();
175                 for (i = cur_pos; i < max_pos; i++) cur_line[i] = cur_line[i + 1];
176                 max_pos -= 1;
177                 refreshLine();
178         }
179         else TerminalBeep();
180 }
181 /*--------------------------------------------------------------------------*/
182 void deleteCurrentChar(void)
183 {
184         reallocLineBuffer();
185         if (max_pos == 0) 
186         {
187                 TerminalBeep();
188         }
189         else
190         {
191                 if (cur_pos < max_pos)
192                 {
193                         int i =0;
194                         for (i = cur_pos; i < max_pos; i++) cur_line[i] = cur_line[i + 1];
195                         max_pos -= 1;
196                         refreshLine();
197                 }
198         }
199 }
200 /*--------------------------------------------------------------------------*/
201 void moveBackHistory(void)
202 {
203         char *newline = NULL;
204
205         reallocLineBuffer();
206
207         cur_line[max_pos + 1] = '\0';
208         if (cur_line[0]== '\0')
209         {
210                 resetSearchedTokenInScilabHistory();
211                 setSearchedTokenInScilabHistory(NULL);
212         }
213
214         newline = getPreviousLineInScilabHistory();
215
216         if (newline)
217         {
218                 clearCurrentLine();
219                 copyLine(newline);
220                 FREE(newline);
221                 newline = NULL;
222         }
223 }
224 /*--------------------------------------------------------------------------*/
225 void moveForwardHistory(void)
226 {
227         char *newline = NULL;
228
229         reallocLineBuffer();
230
231         cur_line[max_pos + 1] = '\0';
232         if (cur_line[0]== '\0')
233         {
234                 resetSearchedTokenInScilabHistory();
235                 setSearchedTokenInScilabHistory(NULL);
236         }
237
238         newline = getNextLineInScilabHistory();
239
240         if (newline)
241         {
242                 clearCurrentLine();
243                 copyLine(newline);
244                 FREE(newline);
245                 newline = NULL;
246         }
247 }
248 /*--------------------------------------------------------------------------*/
249 void redrawLine(void)
250 {
251         int i =0;
252         char *line = getCurrentLine();
253
254         displayPrompt();
255         for (i = max_pos; i > cur_pos; i--)  backSpace ();
256         if (line)
257         {
258                 copyLine(line);
259                 FREE(line);
260                 line = NULL;
261         }
262 }
263 /*--------------------------------------------------------------------------*/
264 void copyLine(char *line)
265 {
266         reallocLineBuffer();
267
268         if (line)
269         {
270                 TerminalPrintf(line);
271                 CharToOem(line,cur_line);
272                 cur_pos = max_pos = (int)strlen (cur_line);
273         }
274 }
275 /*--------------------------------------------------------------------------*/
276 void killLastWord(void)
277 {
278         reallocLineBuffer();
279
280         while ((cur_pos > 0) && (cur_line[cur_pos - 1] == VK_SPACE))
281         {
282                 cur_pos -= 1;
283                 backSpace ();
284         }
285         while ((cur_pos > 0) && (cur_line[cur_pos - 1] != VK_SPACE))
286         {
287                 cur_pos -= 1;
288                 backSpace ();
289         }
290
291         killCurrentPositionToEndLine();
292 }
293 /*--------------------------------------------------------------------------*/
294 void newLine(void)
295 {
296         reallocLineBuffer();
297
298         cur_line[0] = '\0';
299         cur_pos = 0;
300         max_pos = 0;
301 }
302 /*--------------------------------------------------------------------------*/
303 void refreshLine(void)
304 {
305         int i = 0;
306
307         reallocLineBuffer();
308
309         /* write tail of string */
310         for (i = cur_pos; i < max_pos; i++) TerminalPutc(cur_line[i]);
311
312         /* write a space at the end of the line in case we deleted one */
313         TerminalPutc(VK_SPACE);
314
315         /* backup to original position */
316         for (i = max_pos + 1; i > cur_pos; i--) backSpace ();
317
318 }
319 /*--------------------------------------------------------------------------*/
320 void clearCurrentLine(void)
321 {
322         int i = 0;
323
324         reallocLineBuffer();
325
326         for (i = 0; i < max_pos; i++) cur_line[i] = '\0';
327
328         moveBeginningLine();
329         
330         for (i = 0; i < max_pos; i++) TerminalPutc(VK_SPACE);
331
332         TerminalPutc('\r');
333         displayPrompt();
334
335         newLine();
336 }
337 /*--------------------------------------------------------------------------*/
338 static void backSpace(void)
339 {
340         int X = 0, Y = 0;
341         reallocLineBuffer();
342
343         TermGetPosition(&X, &Y);
344         if ( (X - 1) < 0 )
345         {
346                 X = getXConsoleScreenSize();
347                 Y = Y - 1;
348                 TermSetPosition(X, Y);
349         }
350         else TerminalPutc(VK_BACK);
351 }
352 /*--------------------------------------------------------------------------*/
353 static char *getCurrentPrompt(void)
354 {
355         return currentPrompt;
356 }
357 /*--------------------------------------------------------------------------*/
358 void setCurrentPrompt(char *prompt)
359 {
360         currentPrompt = prompt;
361 }
362 /*--------------------------------------------------------------------------*/
363 void displayPrompt(void)
364 {
365         int X = 0, Y = 0;
366
367         /* check position */
368         TermGetPosition(&X, &Y);
369         if (X) TerminalPrintf("\n");
370
371         TerminalPrintf(getCurrentPrompt());
372 }
373 /*--------------------------------------------------------------------------*/
374 char *getCurrentLine(void)
375 {
376         char *line = NULL;
377
378         reallocLineBuffer();
379
380         cur_line[max_pos + 1] = '\0';
381         line = strdup_windows(cur_line);
382         if (line) OemToChar(cur_line, line);
383         return line;
384 }
385 /*--------------------------------------------------------------------------*/
386 char *getLineBeforeCaret(void)
387 {
388         char *line = NULL;
389
390         reallocLineBuffer();
391         line = strdup_windows(cur_line);
392         line[cur_pos] = '\0';
393         return line;
394 }
395 /*--------------------------------------------------------------------------*/
396 char *getLineAfterCaret(void)
397 {
398         char *line = NULL;
399
400         reallocLineBuffer();
401         if (cur_pos != max_pos)
402         {
403                 line = strdup_windows(&cur_line[cur_pos]);
404                 line[(max_pos - cur_pos) + 1] = '\0';
405         }
406         else
407         {
408                 line = strdup_windows("");
409         }
410         return line;
411 }
412 /*--------------------------------------------------------------------------*/
413 void addCharacterCurrentLine(unsigned char ch)
414 {
415         int i = 0;
416
417         reallocLineBuffer();
418
419         for (i = max_pos; i > cur_pos; i--) cur_line[i] = cur_line[i - 1];
420
421         cur_line[cur_pos] = ch;
422         cur_pos += 1;
423         max_pos += 1;
424         cur_line[max_pos] = '\0';
425
426         setSearchedTokenInScilabHistory(cur_line);
427
428         if (cur_pos < max_pos) refreshLine();
429 }
430 /*--------------------------------------------------------------------------*/
431 BOOL isHistorySearch(void)
432 {
433         return (cur_line[0] == '!');
434 }
435 /*--------------------------------------------------------------------------*/
436 void putLineSearchedHistory(void)
437 {
438         char *line = NULL;
439         char *token = getCurrentLine();
440
441         if (token)
442         {
443                 if ( (int)strlen(token) > 1 )
444                 {
445                         setSearchedTokenInScilabHistory(&token[1]);
446                         line = getNextLineInScilabHistory();
447                 }
448                 FREE(token);
449                 token = NULL;
450         }
451
452         clearCurrentLine();
453
454         if (line)
455         {
456                 copyLine(line);
457                 FREE(line);
458                 line = NULL;
459         }
460 }
461 /*--------------------------------------------------------------------------*/
462 void pasteClipBoard(void)
463 {
464         HGLOBAL hGMem = NULL;
465         LPSTR lpMem; /* Ptr on clipboard */
466
467         int typeClipboard = CF_TEXT;
468
469         OpenClipboard(NULL);
470
471         hGMem = GetClipboardData (typeClipboard);
472         if (hGMem)
473         {
474                 
475                 char *CurrentLine = getCurrentLine();
476
477                 lpMem  = GlobalLock( hGMem );
478                 if (lpMem)
479                 {
480                         char *newline = (char*)MALLOC(sizeof(char)*(strlen(CurrentLine)+ strlen(lpMem)));
481                         strncpy(newline, CurrentLine, cur_pos);
482                         strcat(newline, lpMem);
483                         strcat(newline, &CurrentLine[cur_pos]);
484
485                         clearCurrentLine();
486                         copyLine(newline);
487                         FREE(newline);
488                 }
489                 GlobalUnlock (hGMem);
490                 FREE(CurrentLine);
491         }
492
493         CloseClipboard ();
494 }
495 /*--------------------------------------------------------------------------*/