Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. #include "gr-draw.h"
  2.  
  3. #ifndef _DOS_GRAPHIC_DRAW_H
  4. #define _DOS_GRAPHIC_DRAW_H
  5.  
  6. #include "dosmouse.h"
  7. #include "keysym.h"
  8. #include <graphics.h>
  9. #include <conio.h>
  10. #include <stdio.h>
  11. #include <limits.h>
  12.  
  13. class TDosGraphDraw : public TGraphDraw
  14. {
  15. public:
  16.   TDosGraphDraw(const char *s = 0);
  17.   ~TDosGraphDraw() {}
  18. public:
  19.   static unsigned long GetKeySym(unsigned int key);
  20. protected:
  21.   unsigned long bgcolor;
  22.   int quit;
  23.   TCursorVisible cursor;
  24. public:
  25.   unsigned long GetBlackColor() {return 0;}
  26.   unsigned long GetWhiteColor() {return 15;}
  27.   unsigned long CreateColor(unsigned short red,
  28.                  unsigned short green, unsigned short blue);
  29.   void FreeColor(unsigned long c) {}
  30.   unsigned long GetBgColor() {return bgcolor;}
  31.   void SetBgColor(unsigned long c) {bgcolor = c;}
  32.  
  33.   int GetStatus() {return (graphresult() == grOk) ? 1 : 0;}
  34.   int Init() {return 0;}
  35.   int Run(int evmask = 0, int w = INT_MIN, int h = INT_MIN);
  36.  
  37.   void GetSize(int &w, int &h);
  38.   int OpenDraw();
  39.   int IsDraw() {return graphresult() == grOk && cursor.IsHidden();}
  40.   void CloseDraw() {cursor.Show();}
  41.  
  42.   int SetColor(unsigned long c);
  43.   int DrawLine(int x0, int y0, int x1, int y1);
  44.   int DrawText(int x0, int y0, char *text);
  45.   int DrawClear();
  46.   int GetTextH(const char *s) {return 8;}
  47.   int GetTextW(const char *s) {return 8 * sizeof(s);}
  48.   void Quit(int q = 1) {quit = (q > 0) ? q : 0;}
  49. };
  50.  
  51. unsigned long TDosGraphDraw::GetKeySym(unsigned int key)
  52. {
  53.   switch(key)
  54.   {
  55.     case 331: return XK_Left;
  56.     case 333: return XK_Right;
  57.     case 328: return XK_Up;
  58.     case 336: return XK_Down;
  59.     case 13:  return XK_Return;
  60.     case 32:  return XK_space;
  61.     case 27:  return XK_Escape;
  62.     case 44:  return XK_comma;
  63.     case 46:  return XK_period;
  64.     case 60:  return XK_comma;
  65.     case 62:  return XK_period;
  66.     case 45:  return XK_minus;
  67.     case 61:  return XK_equal;
  68.     case 95:  return XK_underscore;
  69.     case 43:  return XK_plus;
  70.     case 339: return XK_Delete;
  71.     case 47:  return XK_slash;
  72.     case 63:  return XK_question;
  73.     case 315: return XK_F1;
  74.     case 316: return XK_F2;
  75.     case 317: return XK_F3;
  76.     case 318: return XK_F4;
  77.     case 319: return XK_F5;
  78.     case 320: return XK_F6;
  79.     case 321: return XK_F7;
  80.     case 322: return XK_F8;
  81.     case 323: return XK_F9;
  82.     case 324: return XK_F10;
  83.     case 389: return XK_F11;
  84.     case 390: return XK_F12;
  85.     case 97:  return XK_a;
  86.     case 98:  return XK_b;
  87.     case 99:  return XK_c;
  88.     case 100: return XK_d;
  89.     case 101: return XK_e;
  90.     case 102: return XK_f;
  91.     case 103: return XK_g;
  92.     case 104: return XK_h;
  93.     case 105: return XK_i;
  94.     case 106: return XK_j;
  95.     case 107: return XK_k;
  96.     case 108: return XK_l;
  97.     case 109: return XK_m;
  98.     case 110: return XK_n;
  99.     case 111: return XK_o;
  100.     case 112: return XK_p;
  101.     case 113: return XK_q;
  102.     case 114: return XK_r;
  103.     case 115: return XK_s;
  104.     case 116: return XK_t;
  105.     case 117: return XK_u;
  106.     case 118: return XK_v;
  107.     case 119: return XK_w;
  108.     case 120: return XK_x;
  109.     case 121: return XK_y;
  110.     case 122: return XK_z;
  111.     case 65:  return XK_A;
  112.     case 66:  return XK_B;
  113.     case 67:  return XK_C;
  114.     case 68:  return XK_D;
  115.     case 69:  return XK_E;
  116.     case 70:  return XK_F;
  117.     case 71:  return XK_G;
  118.     case 72:  return XK_H;
  119.     case 73:  return XK_I;
  120.     case 74:  return XK_J;
  121.     case 75:  return XK_K;
  122.     case 76:  return XK_L;
  123.     case 77:  return XK_M;
  124.     case 78:  return XK_N;
  125.     case 79:  return XK_O;
  126.     case 80:  return XK_P;
  127.     case 81:  return XK_Q;
  128.     case 82:  return XK_R;
  129.     case 83:  return XK_S;
  130.     case 84:  return XK_T;
  131.     case 85:  return XK_U;
  132.     case 86:  return XK_V;
  133.     case 87:  return XK_W;
  134.     case 88:  return XK_X;
  135.     case 89:  return XK_Y;
  136.     case 90:  return XK_Z;
  137.     default:  return XK_VoidSymbol;
  138.   }
  139. }
  140.  
  141. TDosGraphDraw::TDosGraphDraw(const char *s) : TGraphDraw(s)
  142. {
  143.   bgcolor = GetWhiteColor();
  144. }
  145.  
  146. unsigned long TDosGraphDraw::CreateColor(unsigned short red,
  147.                   unsigned short green, unsigned short blue)
  148. {
  149.   const unsigned short PD = 12288U, PM = 36863U, PL = 65535U;
  150.   const unsigned short COLOR[16][3] =
  151.          {{0U, 0U, 0U}, {0U, 0U, PM}, {0U, PM, 0U}, {0U, PM, PM},
  152.           {PM, 0U, 0U}, {PM, 0U, PM}, {PM, PM, 0U}, {PM, PM, PM},
  153.           {PD, PD, PD}, {PD, PD, PL}, {PD, PL, PD}, {PD, PL, PL},
  154.           {PL, PD, PD}, {PL, PD, PL}, {PL, PL, PD}, {PL, PL, PL}};
  155.   int b[3];
  156.   if (red > green)
  157.   {
  158.     if (green > blue) {b[0] = 4; b[1] = 2; b[2] = 1;}
  159.     else if (red > blue) {b[0] = 4; b[1] = 1; b[2] = 2;}
  160.     else {b[0] = 1; b[1] = 4; b[2] = 2;}
  161.   }
  162.   else
  163.   {
  164.     if (red > blue) {b[0] = 2; b[1] = 4; b[2] = 1;}
  165.     else if (green > blue) {b[0] = 2; b[1] = 1; b[2] = 4;}
  166.     else {b[0] = 1; b[1] = 2; b[2] = 4;}
  167.   }
  168.   int i, j, c, c0 = 0;
  169.   long d, d0 = LONG_MAX;
  170.   for (j = 0; j <= 8; j += 8) for (i = 0, c = j; i <= 3; c |= b[i++])
  171.   {
  172.     d = labs((long)red - COLOR[c][0]) + labs((long)green - COLOR[c][1]) +
  173.         labs((long)blue - COLOR[c][2]);
  174.     if (d0 >= d) {d0 = d; c0 = c;}
  175.   }
  176.   return c0;
  177. }
  178.  
  179. void TDosGraphDraw::GetSize(int &w, int &h)
  180. {
  181.   if (graphresult() == grOk)
  182.   {
  183.     w = getmaxx() + 1; h = getmaxy() + 1;
  184.   }
  185.   else TGraphDraw::GetSize(w, h);
  186. }
  187.  
  188. int TDosGraphDraw::OpenDraw()
  189. {
  190.   if (graphresult() == grOk)
  191.   {
  192.     cursor.Hide();
  193.     return 1;
  194.   }
  195.   else return 0;
  196. }
  197.  
  198. int TDosGraphDraw::SetColor(unsigned long c)
  199. {
  200.   if (!IsDraw()) return 0;
  201.   else {setcolor((int)c); return 1;}
  202. }
  203.  
  204. int TDosGraphDraw::DrawLine(int x0, int y0, int x1, int y1)
  205. {
  206.   if (!IsDraw()) return 0;
  207.   else {line(x0, y0, x1, y1); return 1;}
  208. }
  209.  
  210. int TDosGraphDraw::DrawText(int x0, int y0, char *text)
  211. {
  212.   if (!IsDraw()) return 0;
  213.   else {outtextxy(x0, y0, text); return 1;}
  214. }
  215.  
  216. int TDosGraphDraw::DrawClear()
  217. {
  218.   if (!IsDraw()) return 0;
  219.   setbkcolor((int)bgcolor); setcolor((int)bgcolor);
  220.   bar(0, 0, getmaxx(), getmaxy());
  221.   setbkcolor(0);
  222.   return 1;
  223. }
  224.  
  225. int TDosGraphDraw::Run(int evmask, int /*w*/, int /*h*/)
  226. {
  227.   if (!evfunc) return -2;
  228.   int wasgraph = graphresult();
  229.   if (!wasgraph)
  230.   {
  231.     int gdriver = DETECT, gmode, errorcode;
  232.     initgraph(&gdriver, &gmode, "");
  233.     if ((errorcode = graphresult()) != grOk)
  234.     {
  235.       printf("Graphics error: %s\n", grapherrormsg(errorcode));
  236.       return -1;
  237.     }
  238.   }
  239.   event ev;
  240.   int ch = INT_MIN, stpr = 0;
  241.   int old_mx = -1000, old_my = -1000;
  242.   clock_t old_mtime = clock();
  243.   int show_cur = TCursorVisible::C.IsShowed();
  244.   freopen("NUL", "wt", stdout);
  245.   quit = 0;
  246.   while (quit == 0)
  247.   {
  248.     if (stpr == 0)
  249.     {
  250.       ev.type = event::start;
  251.       ev.any.drw = this;
  252.       evfunc(ev);
  253.       CloseDraw();
  254.       stpr = 1;
  255.     }
  256.     else if (stpr == 1)
  257.     {
  258.       ev.type = event::draw;
  259.       ev.any.drw = this;
  260.       evfunc(ev);
  261.       CloseDraw();
  262.       stpr = 2;
  263.     }
  264.     else if (ch >= 0 && (evmask & key_down_mask))
  265.     {
  266.       ev.type = event::key_up;
  267.       ev.key.drw = this;
  268.       ev.key.k = ch;
  269.       evfunc(ev);
  270.       CloseDraw();
  271.       ch = INT_MIN;
  272.     }
  273.     else if (kbhit())
  274.     {
  275.       if (MouseStatus && TCursorVisible::C.IsShowed() &&
  276.          (unsigned long)(clock() - old_mtime) > 5 * CLK_TCK)
  277.       {
  278.         TCursorVisible::C.Hide();
  279.         old_mtime = clock();
  280.       }
  281.       int ch = (unsigned char)getch();
  282.       if (!ch && kbhit()) ch = 0x100 | (unsigned char)getch();
  283.       if (evmask & key_down_mask)
  284.       {
  285.         ev.type = event::key_down;
  286.         ev.key.drw = this;
  287.         ev.key.k = GetKeySym(ch);
  288.         evfunc(ev);
  289.         CloseDraw();
  290.       }
  291.     }
  292.     else if (MouseStatus && (evmask & (button_down_mask |
  293.              button_up_mask | mouse_move_mask | mouse_drag_mask)))
  294.     {
  295.       int k, x, y, z;
  296.       for (k = 0; k < MouseStatus; k++)
  297.       {
  298.         z = GetButtonDown(k, x, y);
  299.         if (z)
  300.         {
  301.           TCursorVisible::C.Show();
  302.           old_mx = x; old_my = y;
  303.           old_mtime = clock();
  304.           if (evmask & button_down_mask)
  305.           {
  306.             ev.type = event::button_down;
  307.             ev.button.drw = this;
  308.             ev.button.x = x; ev.button.y = y;
  309.             ev.button.n = k + 1;
  310.             evfunc(ev);
  311.             CloseDraw();
  312.           }
  313.           old_mtime = clock();
  314.           k = -1; break;
  315.         }
  316.         z = GetButtonUp(k, x, y);
  317.         if (z)
  318.         {
  319.           TCursorVisible::C.Show();
  320.           old_mx = x; old_my = y;
  321.           old_mtime = clock();
  322.           if (evmask & button_up_mask)
  323.           {
  324.             ev.type = event::button_up;
  325.             ev.button.drw = this;
  326.             ev.button.x = x; ev.button.y = y;
  327.             ev.button.n = k + 1;
  328.             evfunc(ev);
  329.             CloseDraw();
  330.           }
  331.           k = -1; break;
  332.         }
  333.       }
  334.       if (k >= 0)
  335.       {
  336.         z = PosCursor(x, y);
  337.         if (x != old_mx || y != old_my)
  338.         {
  339.           TCursorVisible::C.Show();
  340.           old_mx = x; old_my = y;
  341.           old_mtime = clock();
  342.           if (evmask & (mouse_move_mask | mouse_drag_mask))
  343.           {
  344.             for (k = 0; k < MouseStatus; k++)
  345.             {
  346.               if (z & (1 << k)) break;
  347.             }
  348.             if (evmask & ((k == MouseStatus) ? mouse_move_mask : mouse_drag_mask))
  349.             {
  350.               ev.type = event::mouse_move;
  351.               ev.button.drw = this;
  352.               ev.button.x = x; ev.button.y = y;
  353.               ev.button.n = (k >= MouseStatus) ? 0 : (k + 1);
  354.               evfunc(ev);
  355.               CloseDraw();
  356.             }
  357.           }
  358.         }
  359.         else if (TCursorVisible::C.IsShowed() &&
  360.                 (unsigned long)(clock() - old_mtime) > 30 * CLK_TCK)
  361.         {
  362.           TCursorVisible::C.Hide();
  363.           old_mtime = clock();
  364.         }
  365.       }
  366.     }
  367.     if (quit == 1)
  368.     {
  369.       ev.type = event::close;
  370.       ev.any.drw = this;
  371.       Quit(evfunc(ev));
  372.       CloseDraw();
  373.     }
  374.   }
  375.   TCursorVisible::C.Set(show_cur);
  376.   if (!wasgraph) closegraph();
  377.   freopen("CON", "wt", stdout);
  378.   return quit;
  379. }
  380.  
  381. #endif  //_DOS_GRAPHIC_DRAW_H
  382.