ffd2de7147a6981157699d90dd62b906c11cc924
[sdk] / ecere / src / gfx / drivers / NCursesDisplayDriver.ec
1 namespace gfx::drivers;
2
3 import "instance"
4
5 #undef __BLOCKS__
6
7 #if (defined(__unix__) || defined(__APPLE__)) && !defined(__DOS__)
8
9 #include <curses.h>
10
11 import "Display"
12
13 static int CC(int color)
14 {
15    int result = 0;
16    int foreground = (color & 0x0700) >> 8;
17    int background = (color & 0x7000) >> 9;
18    int character = color & 0xFF;
19    int pair = background|foreground;
20    if(pair == 0) result |= A_REVERSE;
21    result |= COLOR_PAIR(pair);
22    if(character == 127 || character == 132 || character == 133 || character == 136 ||
23       character == 141 || character == 142 || character == 143 || character == 155 ||
24       character == 156)
25       character = 32;
26    else if(character < 32)
27    {
28       character += 95;
29       result |= A_ALTCHARSET;
30    }
31    if(color == 0x0800)
32       result |= A_DIM;
33    else if(color & 0x0800)
34       result |= A_BOLD;
35    if(color & 0x8000)
36       result |= A_BLINK;
37    result |= character;
38    return result;
39 }
40
41 class CursesDisplay : LFBDisplay
42 {
43    Box updateBox;
44 };
45
46 class NCursesDisplayDriver : DisplayDriver
47 {
48    class_property(name) = "NCurses";
49
50    bool CreateDisplaySystem(DisplaySystem displaySystem)
51    {
52       displaySystem.flags.text = true;
53       return true;
54    }
55
56    void DestroyDisplaySystem(DisplaySystem displaySystem)
57    {
58
59    }
60
61    void DestroyDisplay(Display display)
62    {
63       CursesDisplay cursesDisplay = display.driverData;
64       delete cursesDisplay.bitmap.picture;
65       ((subclass(DisplayDriver))class(LFBDisplayDriver)).DestroyDisplay(display);
66       delete cursesDisplay;
67       display.driverData = null;
68    }
69
70    void SetPalette(Display display, ColorAlpha * palette, bool colorMatch)
71    {
72
73    }
74
75    bool CreateDisplay(Display display)
76    {
77       bool result = false;
78       CursesDisplay cursesDisplay = display.driverData = CursesDisplay { };
79
80       if(cursesDisplay)
81       {
82          if(((subclass(DisplayDriver))class(LFBDisplayDriver)).CreateDisplay(display))
83          {
84             cursesDisplay.bitmap.pixelFormat = pixelFormatText;
85             result = true;
86          }
87       }
88       return result;
89    }
90
91    bool DisplaySize(Display display, int width, int height)
92    {
93       bool result = false;
94       CursesDisplay cursesDisplay = display.driverData;
95
96       delete cursesDisplay.bitmap.picture;
97
98       cursesDisplay.bitmap.picture = new0 byte[2 * width / textCellW * height / textCellW];
99       if(cursesDisplay.bitmap.picture)
100       {
101          cursesDisplay.bitmap.stride = width / textCellW;
102          cursesDisplay.bitmap.pixelFormat = pixelFormatText;
103          cursesDisplay.bitmap.size = width / textCellW * height / textCellH;
104          display.width = width;
105          display.height = height;
106
107          ((subclass(DisplayDriver))class(LFBDisplayDriver)).DisplaySize(display, width, height);
108          result = true;
109       }
110       return result;
111    }
112
113    void DisplayPosition(Display display, int x, int y)
114    {
115
116    }
117
118    void RestorePalette(Display display)
119    {
120
121    }
122
123    void FreeBitmap(DisplaySystem displaySystem, Bitmap bitmap)
124    {
125
126    }
127
128    bool MakeDDBitmap(DisplaySystem displaySystem, Bitmap bitmap, bool mipMaps)
129    {
130       return true;
131    }
132
133    bool GetSurface(Display display, Surface surface, int x, int y, Box clip)
134    {
135       if((surface.driverData = LFBSurface { }))
136          return ((subclass(DisplayDriver))class(LFBDisplayDriver)).GetSurface(display, surface, x, y, clip);
137       return false;
138    }
139
140    bool GetBitmapSurface(DisplaySystem displaySystem, Surface surface, Bitmap bitmap, int x, int y, Box clip)
141    {
142       return false;
143    }
144
145    void ReleaseSurface(Display display, Surface surface)
146    {
147       ((subclass(DisplayDriver))class(LFBDisplayDriver)).ReleaseSurface(display, surface);
148    }
149
150    void Clip(Display display, Surface surface, Box clip)
151    {
152       ((subclass(DisplayDriver))class(LFBDisplayDriver)).Clip(display, surface, clip);
153    }
154
155    bool GrabScreen(Display display, Bitmap bitmapAddress, int x, int y, unsigned int w, unsigned int h)
156    {
157
158       return false;
159    }
160
161    void SetForeground(Display display, Surface surface, ColorAlpha color)
162    {
163       ((subclass(DisplayDriver))class(LFBDisplayDriver)).SetForeground(display, surface, color);
164    }
165
166    void SetBackground(Display display, Surface surface, ColorAlpha color)
167    {
168       ((subclass(DisplayDriver))class(LFBDisplayDriver)).SetBackground(display, surface, color);
169    }
170
171    ColorAlpha GetPixel(Display display, Surface surface,int x,int y)
172    {
173       return 0;
174    }
175
176    void PutPixel(Display display, Surface surface,int x,int y)
177    {
178       LFBSurface lfbSurface = surface.driverData;
179       ((subclass(DisplayDriver))class(LFBDisplayDriver)).PutPixel(display, surface, x, y);
180       x /= textCellW;
181       y /= textCellH;
182       if((x<=surface.box.right)&&(y<=surface.box.bottom)&&(x>=surface.box.left)&&(y>=surface.box.top))
183       {
184
185          if(lfbSurface.opaqueText)
186          {
187             mvaddch((y+surface.offset.y),x+surface.offset.x,
188                CC(lfbSurface.background|lfbSurface.foreground|lfbSurface.drawingChar));
189          }
190          else
191          {
192             mvaddch((y+surface.offset.y),x+surface.offset.x,
193               CC(lfbSurface.background|lfbSurface.foreground|lfbSurface.drawingChar));
194          }
195       }
196    }
197
198    void DrawLine(Display display, Surface surface, int x1, int y1, int x2, int y2)
199    {
200       LFBSurface lfbSurface = surface.driverData;
201       ((subclass(DisplayDriver))class(LFBDisplayDriver)).DrawLine(display, surface, x1, y1, x2, y2);
202       x1 /= textCellW;
203       x2 /= textCellW;
204       y1 /= textCellH;
205       y2 /= textCellH;
206       if(x1 == x2)
207       {
208          if(y1>y2) { int tmp = y2; y2 = y1; y1 = tmp; }
209
210          if((x1>surface.box.right)||(x1<surface.box.left))return;
211          if((y1>surface.box.bottom)||(y2<surface.box.top))return;
212          if(y1<surface.box.top)y1=surface.box.top;
213          if(y2>surface.box.bottom)y2=surface.box.bottom;
214          if(y2 < y1) return;
215
216          if(lfbSurface.opaqueText)
217          {
218             mvvline(y1+surface.offset.y,x1+surface.offset.x,
219                CC(lfbSurface.background | lfbSurface.foreground | lfbSurface.drawingChar),y2-y1+1);
220          }
221          else
222          {
223             uint16 * lfbPtr = ((uint16 *)lfbSurface.bitmap.picture) +
224                (y1+surface.offset.y)*lfbSurface.bitmap.stride+x1+surface.offset.x;
225             int y;
226             for(y=y1;y<=y2; y++, lfbPtr += lfbSurface.bitmap.stride)
227             {
228                mvaddch(y+surface.offset.y,x1+surface.offset.x,
229                   CC((*lfbPtr & 0xF000) | lfbSurface.foreground | lfbSurface.drawingChar));
230             }
231          }
232
233       }
234       else if(y1 == y2)
235       {
236          if(x1>x2) { int tmp = x2; x2 = x1; x1 = tmp; }
237
238          if((y1>surface.box.bottom)||(y1<surface.box.top)) return;
239          if((x1>surface.box.right)||(x2<surface.box.left)) return;
240          if(x1<surface.box.left)x1=surface.box.left;
241          if(x2>surface.box.right)x2=surface.box.right;
242          if(x2 < x1) return;
243
244          if(lfbSurface.opaqueText)
245          {
246             mvhline(y1+surface.offset.y,x1+surface.offset.x,
247                CC(lfbSurface.background | lfbSurface.foreground | lfbSurface.drawingChar),x2-x1+1);
248          }
249          else
250          {
251             uint16 * lfbPtr = ((uint16 *)lfbSurface.bitmap.picture) +
252                (y1+surface.offset.y)*display.width / textCellW+x1+surface.offset.x;
253             int x;
254             for(x=x1;x<=x2; x++, lfbPtr++)
255             {
256                mvaddch(y1+surface.offset.y,x+surface.offset.x,
257                   CC((*lfbPtr & 0xF000) | lfbSurface.foreground | lfbSurface.drawingChar));
258             }
259          }
260       }
261    }
262
263    void Rectangle(Display display, Surface surface,int x1,int y1,int x2,int y2)
264    {
265
266    }
267
268    void Area(Display display, Surface surface,int x1,int y1,int x2,int y2)
269    {
270       LFBSurface lfbSurface = surface.driverData;
271       ((subclass(DisplayDriver))class(LFBDisplayDriver)).Area(display, surface, x1, y1, x2, y2);
272
273       x1 /= textCellW;
274       x2 /= textCellW;
275       y1 /= textCellH;
276       y2 /= textCellH;
277
278       if(x1>x2) { int tmp = x2; x2 = x1; x1 = tmp; }
279
280       if(x1<surface.box.left)  x1=surface.box.left;
281       if(x2>surface.box.right) x2=surface.box.right;
282       if(y1<surface.box.top)   y1=surface.box.top;
283       if(y2>surface.box.bottom)  y2=surface.box.bottom;
284
285       if(x2>=x1 && y2>=y1)
286       {
287          int y;
288          for(y=y1;y<=y2; y++)
289          {
290             mvhline(y+surface.offset.y,x1+surface.offset.x,
291                CC(lfbSurface.background | lfbSurface.foreground | lfbSurface.drawingChar),x2-x1+1);
292          }
293       }
294    }
295
296    void Clear(Display display, Surface surface, ClearType flags)
297    {
298       if(flags != depthBuffer)
299          Area(display, surface, 0, 0, surface.width - 1, surface.height - 1);
300    }
301
302    bool ConvertBitmap(DisplaySystem displaySystem, Bitmap src, PixelFormat format, ColorAlpha * palette)
303    {
304       return true;
305    }
306
307    bool AllocateBitmap(DisplaySystem displaySystem, Bitmap bitmap, int width, int height, int stride, PixelFormat format, bool allocatePalette)
308    {
309       return false;
310    }
311
312    void Blit(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h)
313    {
314
315    }
316
317    void Stretch(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
318    {
319
320    }
321
322    void Filter(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
323    {
324
325    }
326
327    void BlitDI(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h)
328    {
329
330    }
331
332    void StretchDI(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
333    {
334
335    }
336
337    void FilterDI(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
338    {
339
340    }
341
342    Font LoadFont(DisplaySystem displaySystem, char * faceName, float size, FontFlags flags)
343    {
344       return (void *) true;
345    }
346
347    void UnloadFont(DisplaySystem displaySystem, Font font)
348    {
349
350    }
351
352    void TextFont(Display display, Surface surface, Font font)
353    {
354    }
355
356    void TextOpacity(Display display, Surface surface, bool opaque)
357    {
358       ((subclass(DisplayDriver))class(LFBDisplayDriver)).TextOpacity(display, surface, opaque);
359    }
360
361    void WriteText(Display display, Surface surface, int x, int y, char * text, int len)
362    {
363       LFBSurface lfbSurface = surface.driverData;
364       int c;
365       uint16 * lfbPtr;
366
367       ((subclass(DisplayDriver))class(LFBDisplayDriver)).WriteText(display, surface, x, y, text, len);
368
369       x /= textCellW;
370       y /= textCellH;
371
372       if(y > surface.box.bottom || y < surface.box.top)
373          return;
374       y += surface.offset.y;
375       lfbPtr = ((uint16 *)lfbSurface.bitmap.picture) + y * lfbSurface.bitmap.stride + x + surface.offset.x;
376       for(c=0; (c<len && x < surface.box.left); c++, x++, lfbPtr++);
377       for(; (c<len && x <= surface.box.right); c++, x++, lfbPtr++)
378       {
379          if(lfbSurface.opaqueText)
380             mvaddch(y,x+surface.offset.x,CC(lfbSurface.background|lfbSurface.foreground|text[c]));
381          else
382             mvaddch(y,x+surface.offset.x,CC( (*lfbPtr & 0xF000)|lfbSurface.foreground|text[c] ));
383       }
384    }
385
386    void FontExtent(DisplaySystem displaySystem, Font font, char * text, int len, int * width, int * height)
387    {
388       ((subclass(DisplayDriver))class(LFBDisplayDriver)).FontExtent(displaySystem, font, text, len, width, height);
389    }
390
391    void TextExtent(Display display, Surface surface, char * text, int len, int * width, int * height)
392    {
393       FontExtent(display.displaySystem, null, text, len, width, height);
394    }
395
396    void DrawingChar(Display display, Surface surface, char character)
397    {
398       ((subclass(DisplayDriver))class(LFBDisplayDriver)).DrawingChar(display, surface, character);
399    }
400
401
402    void LineStipple(Display display, Surface surface, uint stipple)
403    {
404
405    }
406
407    bool Lock(Display display)
408    {
409       return true;
410    }
411
412    void Unlock(Display display)
413    {
414    }
415
416    void StartUpdate(Display display)
417    {
418
419    }
420
421    void Scroll(Display display, Box scroll, int x, int y, Extent dirty)
422    {
423
424    }
425
426    void Update(Display display, Box updateBox)
427    {
428       CursesDisplay cursesDisplay = display.driverData;
429       curs_set(false);
430       leaveok(stdscr, true);
431       refresh();
432       if(updateBox == null)
433       {
434          cursesDisplay.updateBox.left = display.width;
435          cursesDisplay.updateBox.top = display.height;
436          cursesDisplay.updateBox.right = 0;
437          cursesDisplay.updateBox.bottom = 0;
438       }
439       // Log("Here in displayscreen\n");
440    }
441
442    void EndUpdate(Display display)
443    {
444
445    }
446 }
447
448 #endif