Subversion Repositories Kolibri OS

Rev

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