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. #include <X11/Xlib.h>
  3. #include <X11/Xutil.h>
  4. #include <X11/Xos.h>
  5. #include <X11/keysym.h>
  6. #include <stdio.h>
  7.  
  8. #ifndef _GNU_GRAPHIC_DRAW_H
  9. #define _GNU_GRAPHIC_DRAW_H
  10.  
  11. class TGnuGraphDraw : public TGraphDraw
  12. {
  13. public:
  14.   TGnuGraphDraw(const char *s = 0);
  15.   ~TGnuGraphDraw();
  16.  
  17.   static unsigned long GetKeySym(unsigned int key) {return key;}
  18.  
  19.   unsigned long GetBlackColor();
  20.   unsigned long GetWhiteColor();
  21.   unsigned long CreateColor(unsigned short red,
  22.                             unsigned short green, unsigned short blue);
  23.   void FreeColor(unsigned long c);
  24.   unsigned int GetBgColor() const {return bgcolor;}
  25.   void SetBgColor(unsigned long c) {bgcolor = c;}
  26.  
  27.   int GetStatus() {return disp ? (win ? 1 : 0) : (-1);}
  28.   int Init() {return disp ? 0 : -1;}
  29.   int Run(int evmask = 0, int w = INT_MIN, int h = INT_MIN);
  30.  
  31.   void GetSize(int &w, int &h);
  32.   int OpenDraw();
  33.   int IsDraw() {return disp && win && prGC;}
  34.   void CloseDraw() {if (prGC) {XFreeGC(disp, prGC); prGC = 0;}}
  35.  
  36.   int SetColor(unsigned long c);
  37.   int DrawLine(int x0, int y0, int x1, int y1);
  38.   int DrawText(int x0, int y0, char *text);
  39.   int DrawClear();
  40.   int GetTextH(const char *s) {return 10;}
  41.   int GetTextW(const char *s) {return 6 * strlen(s);}
  42.   void Quit(int q = 1) {quit = (q > 0) ? q : 0;}
  43.   void ResReinit(int w = INT_MIN, int h = INT_MIN);
  44. protected:
  45.   void InitDisplay();
  46.   void InitWindow(int w = INT_MIN, int h = INT_MIN);
  47. protected:
  48.   int quit;
  49.   unsigned long bgcolor;
  50.   Display *disp;
  51.   Window win;
  52.   int ScrNum;
  53.   GC prGC;
  54.   Mask xmask;
  55. };
  56.  
  57. TGnuGraphDraw::TGnuGraphDraw(const char *s /*= 0*/) : TGraphDraw(s), prGC(0)
  58. {
  59.   xmask = 0;
  60.   InitDisplay();
  61. }
  62.  
  63. TGnuGraphDraw::~TGnuGraphDraw()
  64. {
  65.   CloseDraw();
  66.   if (disp) XCloseDisplay(disp);
  67. }
  68.  
  69. void TGnuGraphDraw::InitDisplay()
  70. {
  71.   disp = XOpenDisplay(NULL);
  72.   if (disp) ScrNum = DefaultScreen(disp);
  73.   else
  74.   {
  75.     int L = 100;
  76.     if (title) L += strlen(title);
  77.     char *str = new char[L];
  78.     if (str)
  79.     {
  80.       strcpy(str, "\n");
  81.       if (title && title[0]) {strcat(str, title); strcat(str, ": ");}
  82.       strcat(str, "Can't connect to X Server.\n");
  83.       printf("%s", str);
  84.     }
  85.   }
  86.   bgcolor = GetWhiteColor();
  87. }
  88.  
  89. unsigned long TGnuGraphDraw::GetBlackColor()
  90. {
  91.   if (disp) return BlackPixel(disp, ScrNum);
  92.   else return TGraphDraw::GetBlackColor();
  93. }
  94.  
  95. unsigned long TGnuGraphDraw::GetWhiteColor()
  96. {
  97.   if (disp) return WhitePixel(disp, ScrNum);
  98.   else return TGraphDraw::GetWhiteColor();
  99. }
  100.  
  101. unsigned long TGnuGraphDraw::CreateColor(unsigned short red,
  102.                             unsigned short green, unsigned short blue)
  103. {
  104.   if (disp)
  105.   {
  106.     XColor color;
  107.     color.red = red; color.green = green; color.blue = blue;
  108.     if (XAllocColor(disp, DefaultColormap(disp, ScrNum), &color))
  109.     {
  110.       return color.pixel;
  111.     }
  112.     else return BlackPixel(disp, ScrNum);
  113.   }
  114.   else return TGraphDraw::CreateColor(red, green, blue);
  115. }
  116.  
  117. void TGnuGraphDraw::FreeColor(unsigned long c)
  118. {
  119.   if (disp && c != BlackPixel(disp, ScrNum))
  120.   {
  121.     XFreeColors(disp, DefaultColormap(disp, ScrNum), &c, 1, 0);
  122.   }
  123. }
  124.  
  125. void TGnuGraphDraw::GetSize(int &w, int &h)
  126. {
  127.   if (disp)
  128.   {
  129.     int x, y;
  130.     Window w_ret;
  131.     unsigned int br, dr, width = 0, height = 0;
  132.     XGetGeometry(disp, win, &w_ret, &x, &y, &width, &height, &br, &dr);
  133.     w = width; h = height;
  134.   }
  135.   else TGraphDraw::GetSize(w, h);
  136. }
  137.  
  138. int TGnuGraphDraw::OpenDraw()
  139. {
  140.   if (!disp && !win) return 0;
  141.   if (!prGC) prGC = XCreateGC(disp, win, 0, NULL);
  142.   return 1;
  143. }
  144.  
  145. int TGnuGraphDraw::SetColor(unsigned long c)
  146. {
  147.   if (!disp || !prGC) return 0;
  148.   XSetForeground(disp, prGC, c);
  149.   return 1;
  150. }
  151.  
  152. int TGnuGraphDraw::DrawLine(int x0, int y0, int x1, int y1)
  153. {
  154.   if (!disp || !prGC) return 0;
  155.   XDrawLine(disp, win, prGC, x0, y0, x1, y1);
  156.   return 1;
  157. }
  158.  
  159. int TGnuGraphDraw::DrawText(int x0, int y0, char *text)
  160. {
  161.   if (!disp || !prGC) return 0;
  162.   XDrawString(disp, win, prGC, x0, y0 + GetTextH(text), text, strlen(text));
  163.   return 1;
  164. }
  165.  
  166. int TGnuGraphDraw::DrawClear()
  167. {
  168.   if (!disp || !prGC) return 0;
  169.   XClearWindow(disp, win);
  170.   return 1;
  171. }
  172.  
  173. void TGnuGraphDraw::InitWindow(int w, int h)
  174. {
  175.   if (w <= 0 || h <= 0) TGraphDraw::GetSize(w, h);
  176.   win = XCreateSimpleWindow(disp, RootWindow(disp, ScrNum),
  177.             100, 100, w, h, 2, BlackPixel(disp, ScrNum), GetBgColor());
  178.   XSelectInput(disp, win, xmask);
  179.   XMapWindow(disp, win);
  180. }
  181.  
  182. void TGnuGraphDraw::ResReinit(int w, int h)
  183. {
  184.   if (disp) {free(disp); disp = 0;}
  185.   InitDisplay();
  186.   if (!disp) exit(1);
  187.   else if (win) InitWindow(w, h);
  188. }
  189.  
  190. int TGnuGraphDraw::Run(int evmask, int w, int h)
  191. {
  192.   if (!disp) return -1;
  193.   if (!evfunc) return -2;
  194.   xmask = ExposureMask;
  195.   if (evmask & button_down_mask) xmask |= ButtonPressMask;
  196.   if (evmask & button_up_mask) xmask |= ButtonReleaseMask;
  197.   if (evmask & key_down_mask) xmask |= KeyPressMask;
  198.   if (evmask & key_up_mask) xmask |= KeyReleaseMask;
  199.   if (evmask & mouse_move_mask) xmask |= PointerMotionMask;
  200.   if (evmask & mouse_drag_mask)
  201.   {
  202.     xmask |= ButtonMotionMask | Button1MotionMask | Button2MotionMask |
  203.              Button3MotionMask | Button4MotionMask | Button5MotionMask;
  204.   }
  205.   InitWindow(w, h);
  206.   XEvent xevent;
  207.   KeySym sym;
  208.   char str[50];
  209.   event ev;
  210.   int stpr = 0;
  211.   quit = 0;
  212.   while (quit == 0)
  213.   {
  214.     if (stpr == 0)
  215.     {
  216.       ev.type = event::start;
  217.       ev.any.drw = this;
  218.       evfunc(ev);
  219.       CloseDraw();
  220.       stpr = 1;
  221.     }
  222.     else
  223.     {
  224.       XNextEvent(disp, &xevent);
  225.       switch(xevent.type)
  226.       {
  227.       case Expose:
  228.         if (xevent.xexpose.count != 0) break;
  229.         ev.type = event::draw;
  230.         ev.any.drw = this;
  231.         evfunc(ev);
  232.         CloseDraw();
  233.         break;
  234.       case ButtonPress:
  235.         ev.type = event::button_down;
  236.         ev.button.drw = this;
  237.         ev.button.x = xevent.xbutton.x;
  238.         ev.button.y = xevent.xbutton.y;
  239.         ev.button.n = xevent.xbutton.button;
  240.         evfunc(ev);
  241.         CloseDraw();
  242.         break;
  243.       case ButtonRelease:
  244.         ev.type = event::button_up;
  245.         ev.button.drw = this;
  246.         ev.button.x = xevent.xbutton.x;
  247.         ev.button.y = xevent.xbutton.y;
  248.         ev.button.n = xevent.xbutton.button;
  249.         evfunc(ev);
  250.         CloseDraw();
  251.         break;
  252.       case MotionNotify:
  253.         ev.type = event::mouse_move;
  254.         ev.button.drw = this;
  255.         ev.button.x = xevent.xbutton.x;
  256.         ev.button.y = xevent.xbutton.y;
  257.         ev.button.n = xevent.xbutton.button;
  258.         evfunc(ev);
  259.         CloseDraw();
  260.         break;
  261.       case KeyPress:
  262.         memset(str, 0, 20);
  263.         XLookupString(&xevent.xkey, str, 20, &sym, 0);
  264.         ev.type = event::key_down;
  265.         ev.key.drw = this;
  266.         ev.key.k = (unsigned long)sym;
  267.         evfunc(ev);
  268.         CloseDraw();
  269.         break;
  270.       case KeyRelease:
  271.         memset(str, 0, 20);
  272.         XLookupString(&xevent.xkey, str, 20, &sym, 0);
  273.         ev.type = event::key_up;
  274.         ev.key.drw = this;
  275.         ev.key.k = (unsigned long)sym;
  276.         evfunc(ev);
  277.         CloseDraw();
  278.         break;
  279.       }
  280.     }
  281.     if (quit == 1)
  282.     {
  283.       ev.type = event::close;
  284.       ev.any.drw = this;
  285.       Quit(evfunc(ev));
  286.       CloseDraw();
  287.     }
  288.   }
  289.   CloseDraw();
  290.   XDestroyWindow(disp, win);
  291.   win = 0;
  292.   return quit;
  293. }
  294.  
  295. #endif  //_GNU_GRAPHIC_DRAW_H
  296.