mirror of
https://github.com/KolibriOS/kolibrios.git
synced 2024-12-23 23:26:49 +03:00
382 lines
10 KiB
C
382 lines
10 KiB
C
|
#include "gr-draw.h"
|
||
|
|
||
|
#ifndef _DOS_GRAPHIC_DRAW_H
|
||
|
#define _DOS_GRAPHIC_DRAW_H
|
||
|
|
||
|
#include "dosmouse.h"
|
||
|
#include "keysym.h"
|
||
|
#include <graphics.h>
|
||
|
#include <conio.h>
|
||
|
#include <stdio.h>
|
||
|
#include <limits.h>
|
||
|
|
||
|
class TDosGraphDraw : public TGraphDraw
|
||
|
{
|
||
|
public:
|
||
|
TDosGraphDraw(const char *s = 0);
|
||
|
~TDosGraphDraw() {}
|
||
|
public:
|
||
|
static unsigned long GetKeySym(unsigned int key);
|
||
|
protected:
|
||
|
unsigned long bgcolor;
|
||
|
int quit;
|
||
|
TCursorVisible cursor;
|
||
|
public:
|
||
|
unsigned long GetBlackColor() {return 0;}
|
||
|
unsigned long GetWhiteColor() {return 15;}
|
||
|
unsigned long CreateColor(unsigned short red,
|
||
|
unsigned short green, unsigned short blue);
|
||
|
void FreeColor(unsigned long c) {}
|
||
|
unsigned long GetBgColor() {return bgcolor;}
|
||
|
void SetBgColor(unsigned long c) {bgcolor = c;}
|
||
|
|
||
|
int GetStatus() {return (graphresult() == grOk) ? 1 : 0;}
|
||
|
int Init() {return 0;}
|
||
|
int Run(int evmask = 0, int w = INT_MIN, int h = INT_MIN);
|
||
|
|
||
|
void GetSize(int &w, int &h);
|
||
|
int OpenDraw();
|
||
|
int IsDraw() {return graphresult() == grOk && cursor.IsHidden();}
|
||
|
void CloseDraw() {cursor.Show();}
|
||
|
|
||
|
int SetColor(unsigned long c);
|
||
|
int DrawLine(int x0, int y0, int x1, int y1);
|
||
|
int DrawText(int x0, int y0, char *text);
|
||
|
int DrawClear();
|
||
|
int GetTextH(const char *s) {return 8;}
|
||
|
int GetTextW(const char *s) {return 8 * sizeof(s);}
|
||
|
void Quit(int q = 1) {quit = (q > 0) ? q : 0;}
|
||
|
};
|
||
|
|
||
|
unsigned long TDosGraphDraw::GetKeySym(unsigned int key)
|
||
|
{
|
||
|
switch(key)
|
||
|
{
|
||
|
case 331: return XK_Left;
|
||
|
case 333: return XK_Right;
|
||
|
case 328: return XK_Up;
|
||
|
case 336: return XK_Down;
|
||
|
case 13: return XK_Return;
|
||
|
case 32: return XK_space;
|
||
|
case 27: return XK_Escape;
|
||
|
case 44: return XK_comma;
|
||
|
case 46: return XK_period;
|
||
|
case 60: return XK_comma;
|
||
|
case 62: return XK_period;
|
||
|
case 45: return XK_minus;
|
||
|
case 61: return XK_equal;
|
||
|
case 95: return XK_underscore;
|
||
|
case 43: return XK_plus;
|
||
|
case 339: return XK_Delete;
|
||
|
case 47: return XK_slash;
|
||
|
case 63: return XK_question;
|
||
|
case 315: return XK_F1;
|
||
|
case 316: return XK_F2;
|
||
|
case 317: return XK_F3;
|
||
|
case 318: return XK_F4;
|
||
|
case 319: return XK_F5;
|
||
|
case 320: return XK_F6;
|
||
|
case 321: return XK_F7;
|
||
|
case 322: return XK_F8;
|
||
|
case 323: return XK_F9;
|
||
|
case 324: return XK_F10;
|
||
|
case 389: return XK_F11;
|
||
|
case 390: return XK_F12;
|
||
|
case 97: return XK_a;
|
||
|
case 98: return XK_b;
|
||
|
case 99: return XK_c;
|
||
|
case 100: return XK_d;
|
||
|
case 101: return XK_e;
|
||
|
case 102: return XK_f;
|
||
|
case 103: return XK_g;
|
||
|
case 104: return XK_h;
|
||
|
case 105: return XK_i;
|
||
|
case 106: return XK_j;
|
||
|
case 107: return XK_k;
|
||
|
case 108: return XK_l;
|
||
|
case 109: return XK_m;
|
||
|
case 110: return XK_n;
|
||
|
case 111: return XK_o;
|
||
|
case 112: return XK_p;
|
||
|
case 113: return XK_q;
|
||
|
case 114: return XK_r;
|
||
|
case 115: return XK_s;
|
||
|
case 116: return XK_t;
|
||
|
case 117: return XK_u;
|
||
|
case 118: return XK_v;
|
||
|
case 119: return XK_w;
|
||
|
case 120: return XK_x;
|
||
|
case 121: return XK_y;
|
||
|
case 122: return XK_z;
|
||
|
case 65: return XK_A;
|
||
|
case 66: return XK_B;
|
||
|
case 67: return XK_C;
|
||
|
case 68: return XK_D;
|
||
|
case 69: return XK_E;
|
||
|
case 70: return XK_F;
|
||
|
case 71: return XK_G;
|
||
|
case 72: return XK_H;
|
||
|
case 73: return XK_I;
|
||
|
case 74: return XK_J;
|
||
|
case 75: return XK_K;
|
||
|
case 76: return XK_L;
|
||
|
case 77: return XK_M;
|
||
|
case 78: return XK_N;
|
||
|
case 79: return XK_O;
|
||
|
case 80: return XK_P;
|
||
|
case 81: return XK_Q;
|
||
|
case 82: return XK_R;
|
||
|
case 83: return XK_S;
|
||
|
case 84: return XK_T;
|
||
|
case 85: return XK_U;
|
||
|
case 86: return XK_V;
|
||
|
case 87: return XK_W;
|
||
|
case 88: return XK_X;
|
||
|
case 89: return XK_Y;
|
||
|
case 90: return XK_Z;
|
||
|
default: return XK_VoidSymbol;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
TDosGraphDraw::TDosGraphDraw(const char *s) : TGraphDraw(s)
|
||
|
{
|
||
|
bgcolor = GetWhiteColor();
|
||
|
}
|
||
|
|
||
|
unsigned long TDosGraphDraw::CreateColor(unsigned short red,
|
||
|
unsigned short green, unsigned short blue)
|
||
|
{
|
||
|
const unsigned short PD = 12288U, PM = 36863U, PL = 65535U;
|
||
|
const unsigned short COLOR[16][3] =
|
||
|
{{0U, 0U, 0U}, {0U, 0U, PM}, {0U, PM, 0U}, {0U, PM, PM},
|
||
|
{PM, 0U, 0U}, {PM, 0U, PM}, {PM, PM, 0U}, {PM, PM, PM},
|
||
|
{PD, PD, PD}, {PD, PD, PL}, {PD, PL, PD}, {PD, PL, PL},
|
||
|
{PL, PD, PD}, {PL, PD, PL}, {PL, PL, PD}, {PL, PL, PL}};
|
||
|
int b[3];
|
||
|
if (red > green)
|
||
|
{
|
||
|
if (green > blue) {b[0] = 4; b[1] = 2; b[2] = 1;}
|
||
|
else if (red > blue) {b[0] = 4; b[1] = 1; b[2] = 2;}
|
||
|
else {b[0] = 1; b[1] = 4; b[2] = 2;}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (red > blue) {b[0] = 2; b[1] = 4; b[2] = 1;}
|
||
|
else if (green > blue) {b[0] = 2; b[1] = 1; b[2] = 4;}
|
||
|
else {b[0] = 1; b[1] = 2; b[2] = 4;}
|
||
|
}
|
||
|
int i, j, c, c0 = 0;
|
||
|
long d, d0 = LONG_MAX;
|
||
|
for (j = 0; j <= 8; j += 8) for (i = 0, c = j; i <= 3; c |= b[i++])
|
||
|
{
|
||
|
d = labs((long)red - COLOR[c][0]) + labs((long)green - COLOR[c][1]) +
|
||
|
labs((long)blue - COLOR[c][2]);
|
||
|
if (d0 >= d) {d0 = d; c0 = c;}
|
||
|
}
|
||
|
return c0;
|
||
|
}
|
||
|
|
||
|
void TDosGraphDraw::GetSize(int &w, int &h)
|
||
|
{
|
||
|
if (graphresult() == grOk)
|
||
|
{
|
||
|
w = getmaxx() + 1; h = getmaxy() + 1;
|
||
|
}
|
||
|
else TGraphDraw::GetSize(w, h);
|
||
|
}
|
||
|
|
||
|
int TDosGraphDraw::OpenDraw()
|
||
|
{
|
||
|
if (graphresult() == grOk)
|
||
|
{
|
||
|
cursor.Hide();
|
||
|
return 1;
|
||
|
}
|
||
|
else return 0;
|
||
|
}
|
||
|
|
||
|
int TDosGraphDraw::SetColor(unsigned long c)
|
||
|
{
|
||
|
if (!IsDraw()) return 0;
|
||
|
else {setcolor((int)c); return 1;}
|
||
|
}
|
||
|
|
||
|
int TDosGraphDraw::DrawLine(int x0, int y0, int x1, int y1)
|
||
|
{
|
||
|
if (!IsDraw()) return 0;
|
||
|
else {line(x0, y0, x1, y1); return 1;}
|
||
|
}
|
||
|
|
||
|
int TDosGraphDraw::DrawText(int x0, int y0, char *text)
|
||
|
{
|
||
|
if (!IsDraw()) return 0;
|
||
|
else {outtextxy(x0, y0, text); return 1;}
|
||
|
}
|
||
|
|
||
|
int TDosGraphDraw::DrawClear()
|
||
|
{
|
||
|
if (!IsDraw()) return 0;
|
||
|
setbkcolor((int)bgcolor); setcolor((int)bgcolor);
|
||
|
bar(0, 0, getmaxx(), getmaxy());
|
||
|
setbkcolor(0);
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
int TDosGraphDraw::Run(int evmask, int /*w*/, int /*h*/)
|
||
|
{
|
||
|
if (!evfunc) return -2;
|
||
|
int wasgraph = graphresult();
|
||
|
if (!wasgraph)
|
||
|
{
|
||
|
int gdriver = DETECT, gmode, errorcode;
|
||
|
initgraph(&gdriver, &gmode, "");
|
||
|
if ((errorcode = graphresult()) != grOk)
|
||
|
{
|
||
|
printf("Graphics error: %s\n", grapherrormsg(errorcode));
|
||
|
return -1;
|
||
|
}
|
||
|
}
|
||
|
event ev;
|
||
|
int ch = INT_MIN, stpr = 0;
|
||
|
int old_mx = -1000, old_my = -1000;
|
||
|
clock_t old_mtime = clock();
|
||
|
int show_cur = TCursorVisible::C.IsShowed();
|
||
|
freopen("NUL", "wt", stdout);
|
||
|
quit = 0;
|
||
|
while (quit == 0)
|
||
|
{
|
||
|
if (stpr == 0)
|
||
|
{
|
||
|
ev.type = event::start;
|
||
|
ev.any.drw = this;
|
||
|
evfunc(ev);
|
||
|
CloseDraw();
|
||
|
stpr = 1;
|
||
|
}
|
||
|
else if (stpr == 1)
|
||
|
{
|
||
|
ev.type = event::draw;
|
||
|
ev.any.drw = this;
|
||
|
evfunc(ev);
|
||
|
CloseDraw();
|
||
|
stpr = 2;
|
||
|
}
|
||
|
else if (ch >= 0 && (evmask & key_down_mask))
|
||
|
{
|
||
|
ev.type = event::key_up;
|
||
|
ev.key.drw = this;
|
||
|
ev.key.k = ch;
|
||
|
evfunc(ev);
|
||
|
CloseDraw();
|
||
|
ch = INT_MIN;
|
||
|
}
|
||
|
else if (kbhit())
|
||
|
{
|
||
|
if (MouseStatus && TCursorVisible::C.IsShowed() &&
|
||
|
(unsigned long)(clock() - old_mtime) > 5 * CLK_TCK)
|
||
|
{
|
||
|
TCursorVisible::C.Hide();
|
||
|
old_mtime = clock();
|
||
|
}
|
||
|
int ch = (unsigned char)getch();
|
||
|
if (!ch && kbhit()) ch = 0x100 | (unsigned char)getch();
|
||
|
if (evmask & key_down_mask)
|
||
|
{
|
||
|
ev.type = event::key_down;
|
||
|
ev.key.drw = this;
|
||
|
ev.key.k = GetKeySym(ch);
|
||
|
evfunc(ev);
|
||
|
CloseDraw();
|
||
|
}
|
||
|
}
|
||
|
else if (MouseStatus && (evmask & (button_down_mask |
|
||
|
button_up_mask | mouse_move_mask | mouse_drag_mask)))
|
||
|
{
|
||
|
int k, x, y, z;
|
||
|
for (k = 0; k < MouseStatus; k++)
|
||
|
{
|
||
|
z = GetButtonDown(k, x, y);
|
||
|
if (z)
|
||
|
{
|
||
|
TCursorVisible::C.Show();
|
||
|
old_mx = x; old_my = y;
|
||
|
old_mtime = clock();
|
||
|
if (evmask & button_down_mask)
|
||
|
{
|
||
|
ev.type = event::button_down;
|
||
|
ev.button.drw = this;
|
||
|
ev.button.x = x; ev.button.y = y;
|
||
|
ev.button.n = k + 1;
|
||
|
evfunc(ev);
|
||
|
CloseDraw();
|
||
|
}
|
||
|
old_mtime = clock();
|
||
|
k = -1; break;
|
||
|
}
|
||
|
z = GetButtonUp(k, x, y);
|
||
|
if (z)
|
||
|
{
|
||
|
TCursorVisible::C.Show();
|
||
|
old_mx = x; old_my = y;
|
||
|
old_mtime = clock();
|
||
|
if (evmask & button_up_mask)
|
||
|
{
|
||
|
ev.type = event::button_up;
|
||
|
ev.button.drw = this;
|
||
|
ev.button.x = x; ev.button.y = y;
|
||
|
ev.button.n = k + 1;
|
||
|
evfunc(ev);
|
||
|
CloseDraw();
|
||
|
}
|
||
|
k = -1; break;
|
||
|
}
|
||
|
}
|
||
|
if (k >= 0)
|
||
|
{
|
||
|
z = PosCursor(x, y);
|
||
|
if (x != old_mx || y != old_my)
|
||
|
{
|
||
|
TCursorVisible::C.Show();
|
||
|
old_mx = x; old_my = y;
|
||
|
old_mtime = clock();
|
||
|
if (evmask & (mouse_move_mask | mouse_drag_mask))
|
||
|
{
|
||
|
for (k = 0; k < MouseStatus; k++)
|
||
|
{
|
||
|
if (z & (1 << k)) break;
|
||
|
}
|
||
|
if (evmask & ((k == MouseStatus) ? mouse_move_mask : mouse_drag_mask))
|
||
|
{
|
||
|
ev.type = event::mouse_move;
|
||
|
ev.button.drw = this;
|
||
|
ev.button.x = x; ev.button.y = y;
|
||
|
ev.button.n = (k >= MouseStatus) ? 0 : (k + 1);
|
||
|
evfunc(ev);
|
||
|
CloseDraw();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else if (TCursorVisible::C.IsShowed() &&
|
||
|
(unsigned long)(clock() - old_mtime) > 30 * CLK_TCK)
|
||
|
{
|
||
|
TCursorVisible::C.Hide();
|
||
|
old_mtime = clock();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if (quit == 1)
|
||
|
{
|
||
|
ev.type = event::close;
|
||
|
ev.any.drw = this;
|
||
|
Quit(evfunc(ev));
|
||
|
CloseDraw();
|
||
|
}
|
||
|
}
|
||
|
TCursorVisible::C.Set(show_cur);
|
||
|
if (!wasgraph) closegraph();
|
||
|
freopen("CON", "wt", stdout);
|
||
|
return quit;
|
||
|
}
|
||
|
|
||
|
#endif //_DOS_GRAPHIC_DRAW_H
|