Subversion Repositories Kolibri OS

Rev

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