Update debug info
[vlp.git] / src / graph / loggraph.cpp
1
2 #include <QtGui/QPainter>
3 #include <QtGui/QPrinter>
4 #include <QtGui/QPushButton>
5 #include <QtGui/QRadioButton>
6 #include <QtGui/QButtonGroup>
7 #include <QtGui/QApplication>
8 #include <QtGui/QMainWindow>
9 #include <QtGui/QFrame>
10 #include <math.h>
11 #include <QtGui/QPixmap>
12 #include <QtGui/QScrollBar>
13 #include <QtGui/QColor>
14 #include <stdio.h>
15 #include <QtGui/QFont>
16 #include <QtGui/QFontMetrics>
17 #include <QtCore/QList>
18 #include <fcntl.h>
19 #include <sys/stat.h>
20 #include <netinet/in.h>
21 #include "genint1.h"
22 #include "comm.h"
23 #include "socu.h"
24 #include <unistd.h>
25 #include <QtCore/QSocketNotifier>
26 #include <QtCore/QObject>
27 #include <errno.h>
28 #include <QtCore/QQueue>
29 #include <QtGui/QMessageBox>
30 #include <QtGui/QMenuBar>
31 #include <QtGui/QMouseEvent>
32 // #include <qpopmenu.h>
33 #include <QtCore/qnamespace.h>
34
35 #define MAXWIDTH        640
36 #define MAXHEIGHT       480
37 #define TEXT_LINES      50
38 #define TEXT_COLS       100
39 #define REQUEST_NAME    "gr.req"
40 #define PERM            0666
41
42 #include "loggraph.h"
43
44 /*
45  * Construct the DrawView with buttons.
46  */
47 VGR::VGR(int argc, char **argv)
48         :QMainWindow()
49 {
50         char *sockname = argv[1];
51
52         fprintf(stderr, "loggraph: inited with sockname = %s\n", sockname);
53
54         QPixmap mp;
55         struct sockaddr_un svr;
56         int len, i, optval, on;
57
58         normal_font = new QFont("lucidatypewriter", 10, QFont::Normal);
59         normal_font->setFixedPitch(TRUE);
60         bold_font = new QFont("lucidatypewriter", 10, QFont::Bold);
61         bold_font->setFixedPitch(TRUE);
62         italic_font = new QFont("lucidatypewriter", 10, QFont::Normal,TRUE);
63         italic_font->setFixedPitch(TRUE);
64
65         prv_font = normal_font;
66
67         MakeColors();
68         setCaption("graphic resource");
69 //      setBackgroundColor(white);
70         canvas = new QPixmap(640, 480);
71         canvas->fill(backgroundColor());
72
73         ox = oy = 0;
74         curx = cury = 0;
75         tx = ty = 0;
76         gx = gy = 0;
77         
78 //      maps.setAutoDelete(TRUE);
79         firstfreemap = 1;
80         Closed = FALSE;
81         GraphRead = FALSE;
82         lstep = 10;
83         pstep = 250;
84         hscroll = new QScrollBar(0, MAXWIDTH, lstep, pstep, 0, Qt::Orientation::Horizontal, this);
85         vscroll = new QScrollBar(0, MAXHEIGHT, lstep, pstep, 0, Qt::Orientation::Vertical, this);
86         hscroll->setTracking(TRUE);
87         vscroll->setTracking(TRUE);
88         resize(640, 300);
89
90         hscroll->setGeometry(0, height() - 16, width() - 16, 16);
91         vscroll->setGeometry(width() - 16, 0, 16, height() - 16);
92
93         connect(hscroll, SIGNAL(valueChanged(int)), this, SLOT(hscrolled(int)));
94         connect(vscroll, SIGNAL(valueChanged(int)), this, SLOT(vscrolled(int)));
95
96         close_btn = new QPushButton(this, "close");
97
98         if (mp.load("pics/close.bmp"))
99                 close_btn->setPixmap(mp);
100         else
101                 close_btn->setText("C");
102         
103         close_btn->setGeometry(width()-16,height()-16,16,16);
104         close_btn->setEnabled(FALSE);
105         connect(close_btn, SIGNAL(clicked()), this, SLOT(CloseMe()));
106
107
108         gfcol = fcol = 0;
109         gbcol = bcol = 15;
110         resp_sock = socket(AF_UNIX, SOCK_STREAM, 0);
111         bzero(&svr, sizeof(svr));
112         svr.sun_family = AF_UNIX;
113         strcpy(svr.sun_path, sockname);
114         len = strlen(svr.sun_path) + sizeof(svr.sun_family);
115         i = ::connect(resp_sock, (struct sockaddr*)&svr, len);
116         if (i == 0)
117                 fcntl(resp_sock, F_SETFL, O_NONBLOCK | 
118                                                 fcntl(resp_sock , F_GETFL, 0));
119         on = 1;
120         setsockopt(resp_sock, IPPROTO_TCP, TCP_NODELAY, (char*)&on, sizeof(on));
121         request = new QSocketNotifier(resp_sock, QSocketNotifier::Read);
122         connect(request, SIGNAL(activated(int)), this, SLOT(RequestMessage()));   
123         optval=TCP_BUFFER_SIZE;
124         /*
125         setsockopt(resp_sock,SOL_SOCKET,SO_SNDBUF,&optval,sizeof(optval));
126         setsockopt(resp_sock,SOL_SOCKET,SO_RCVBUF,&optval,sizeof(optval));
127         */
128
129         inkey_wait = string_wait = FALSE;
130         char_wait = line_wait = mouse_wait = FALSE;
131         was_line = FALSE;
132         CharBuffer.clear(); 
133 //      CharBuffer.setAutoDelete(TRUE);
134
135         setFocusPolicy(Qt::StrongFocus);
136         hscroll->setRange(0, MAXWIDTH - width() + 20);
137         vscroll->setRange(0, MAXHEIGHT - height() + 20);
138         hscroll->setSteps((int)(hscroll->width() / hscroll->maxValue()),
139                         (int)((hscroll->width() / hscroll->maxValue()) * 4));
140         vscroll->setSteps((int)(vscroll->height() / vscroll->maxValue()),
141                         (int)((vscroll->height() / vscroll->maxValue()) * 4));
142
143         setMaximumSize(MAXWIDTH + 16, MAXHEIGHT + 16);
144         setUpdatesEnabled(FALSE);
145 }
146
147 VGR::~VGR()
148 {
149         if (request != NULL)
150                 delete request;
151 }
152
153 void VGR::paintEvent(QPaintEvent *p)
154 {
155         /*if (isUpdatesEnabled()) {*/
156         bitBlt(this, 0, 0, canvas, ox, oy, width() - 16, height() - 16);
157         /*}*/
158         MustRepaint = FALSE;
159 }
160
161 void VGR::focusInEvent(QFocusEvent *)
162 {
163         setUpdatesEnabled(TRUE);
164         repaint();
165         setUpdatesEnabled(FALSE);
166 }
167
168
169 void VGR::resizeEvent( QResizeEvent *ev )
170 {
171         hscroll->setGeometry(0, height() - 16, width() - 16, 16);
172         vscroll->setGeometry(width() - 16, 0, 16, height() - 16);
173         close_btn->setGeometry(width() - 16, height() - 16, 16, 16);
174         hscroll->setRange(0, MAXWIDTH - width() + 20);
175         vscroll->setRange(0, MAXHEIGHT - height() + 20); 
176         pstep = height() - 32;
177         hscroll->setSteps(lstep, pstep);
178         vscroll->setSteps(lstep, pstep);
179 }
180
181 void VGR::closeEvent(QCloseEvent *ev)
182 {
183 // @TODO: Check this
184 //      if (Closed)
185 //              QFrame::closeEvent(ev);
186 }
187
188 void VGR::mousePressEvent(QMouseEvent *ev)
189 {
190         G_MESSAGE msg;
191
192         if (mouse_wait) {
193                 msg.msg_type = MSG_GRAPH;
194                 msg.param.pword[0] = GRAPH_MGETPRESS_RESPONSE;
195                 msg.param.pword[2] = ev->pos().x() - ox;
196                 msg.param.pword[3] = ev->pos().y() - oy;
197                 switch(ev->button()) {
198                 case Qt::LeftButton:
199                         msg.param.pword[7] = 1;
200                         break;
201                 case Qt::RightButton:
202                         msg.param.pword[7] = 3;
203                         break;
204                 case Qt::MidButton:
205                         msg.param.pword[7] = 2;
206                         break;
207                 default:
208                         msg.param.pword[7] = 0;
209                         break;
210                 }
211                 write(resp_sock, &msg, sizeof(G_MESSAGE));
212
213                 mouse_wait = FALSE;
214         }
215
216 // @TODO: check
217 //      QFrame::mousePressEvent(ev);
218 }
219
220
221 bool VGR::GetInput(int t)
222 {
223         G_MESSAGE msg;
224
225         if (!CharBuffer.isEmpty()) { 
226                 switch(t) {
227                 case 2: {
228                         msg.msg_type = MSG_GRAPH;
229                         msg.param.pword[0] = GRAPH_INKEY_RESPONSE;
230                         msg.param.pword[3] = *(CharBuffer.dequeue());
231                         write(resp_sock,&msg,sizeof(G_MESSAGE));
232                         inkey_wait = FALSE;
233                         return TRUE;
234                 };
235                 break;
236
237                 case 0:
238                         if (GraphRead) {
239                                 msg.msg_type = MSG_GRAPH;
240                                 msg.param.pword[0] = GRAPH_MAGIC_RESPONSE;
241                                 msg.param.pword[1] = 0;
242                                 msg.param.pchar = 
243                                                 (char)(*(CharBuffer.dequeue())); 
244                                 WriteChar(msg.param.pchar);
245                                 GraphRead = FALSE;
246                         } else {
247                                 msg.msg_type = MSG_GRAPH;
248                                 msg.param.pword[0] = GRAPH_READCHAR_RESPONSE;
249                                 msg.param.pchar = 
250                                                 (char)(*(CharBuffer.dequeue()));
251                         }
252
253                         write(resp_sock,&msg,sizeof(G_MESSAGE));
254                         char_wait = FALSE;
255                         return TRUE;
256
257                 case 1:
258                         while ( ((!CharBuffer.isEmpty()) &&
259                                         (!(*(CharBuffer.dequeue()) = 13))));
260                 
261                         if (!CharBuffer.isEmpty()) {
262                                 msg.msg_type = MSG_GRAPH;
263                                 msg.param.pword[0] = GRAPH_READLN_RESPONSE;
264                                 write(resp_sock, &msg, sizeof(G_MESSAGE));
265                                 line_wait = FALSE;
266                                 return TRUE;
267                         }
268                         /* line_wait */
269                         break;
270                 } /* switch */
271         } /* buffer empty */
272
273         if (CharBuffer.isEmpty() && (t == 2)) {
274                 msg.msg_type = MSG_GRAPH;
275                 msg.param.pword[0] = GRAPH_INKEY_RESPONSE;
276                 msg.param.pword[3] = 0;
277                 write(resp_sock, &msg, sizeof(G_MESSAGE));
278                 inkey_wait = FALSE;
279                 return TRUE;
280         }
281
282         return FALSE;   
283 }
284
285 void VGR::keyPressEvent(QKeyEvent *ev)
286 {
287         G_MESSAGE msg;
288         int *pom;
289
290         pom = new int[1];
291         *pom=ev->ascii();
292         if (*pom==0) {
293                 switch(ev->key()) {
294                 case Qt::Key_F1:
295                         *pom = -10;
296                         break;
297                 case Qt::Key_F2:
298                         *pom = -11;
299                         break;
300                 case Qt::Key_F3:
301                         *pom = -12;
302                         break;
303                 case Qt::Key_F4:
304                         *pom = -13;
305                         break;
306                 case Qt::Key_F5:
307                         *pom = -14;
308                         break;
309                 case Qt::Key_F6:
310                         *pom = -15;
311                         break;
312                 case Qt::Key_F7:
313                         *pom = -16;
314                         break;
315                 case Qt::Key_F8:
316                         *pom = -17;
317                         break;
318                 case Qt::Key_F9:
319                         *pom = -18;
320                         break;
321                 case Qt::Key_F10:
322                         *pom = -19;
323                         break;
324                 case Qt::Key_Insert:
325                         *pom = -20;
326                         break;
327                 case Qt::Key_Home:
328                         *pom = -21;
329                         break;
330                 case Qt::Key_End:
331                         *pom = -22;
332                         break;
333                 case Qt::Key_PageUp:
334                         *pom = -23;
335                         break;
336                 case Qt::Key_PageDown:
337                         *pom = -24;
338                         break;
339                 case Qt::Key_Left:
340                         *pom = -25;
341                         break;
342                 case Qt::Key_Right:
343                         *pom = -26;
344                         break;
345                 case Qt::Key_Up:
346                         *pom = -27;
347                         break;
348                 case Qt::Key_Down:
349                         *pom = -28;
350                         break;
351                 }/* switch */
352         }
353         if ((!string_wait) && (!inkey_wait) && (!char_wait) && (!line_wait))
354                 CharBuffer.enqueue(pom);
355
356
357         if (inkey_wait) {
358                 msg.msg_type = MSG_GRAPH;
359                 msg.param.pword[0] = GRAPH_INKEY_RESPONSE;
360                 msg.param.pword[3] = *pom;
361                 write(resp_sock, &msg, sizeof(G_MESSAGE));
362                 inkey_wait = FALSE;
363         };
364
365         if (char_wait) {
366                 if (GraphRead) {
367                         msg.msg_type = MSG_GRAPH;
368                         msg.param.pword[0] = GRAPH_MAGIC_RESPONSE;
369                         msg.param.pword[1] = 0;
370                         WriteChar((char)ev->ascii());
371                         GraphRead = FALSE;
372                 } else {
373                         msg.msg_type = MSG_GRAPH;
374                         msg.param.pword[0] = GRAPH_READCHAR_RESPONSE;
375                 }
376                 msg.param.pchar = (char)ev->ascii();
377                 write(resp_sock, &msg, sizeof(G_MESSAGE));
378                 char_wait = FALSE;
379         }
380
381         if ((line_wait) && (ev->ascii() == 13)) {
382                 msg.msg_type = MSG_GRAPH;
383                 msg.param.pword[0] = GRAPH_READLN_RESPONSE;
384                 write(resp_sock, &msg, sizeof(G_MESSAGE));
385                 line_wait = FALSE;
386         }
387
388         if (string_wait) {
389                 if (ev->ascii() == 13) {
390                         internal_buffer[strcnt] = '\0';
391                         DelChar();
392                         if (GraphRead) {
393                                 GraphRead = FALSE;
394                                 msg.msg_type = MSG_GRAPH;
395                                 msg.param.pword[0] = GRAPH_MAGIC_RESPONSE;
396                                 msg.param.pword[1] = 0;
397                         } else {
398                                 msg.msg_type = MSG_GRAPH;
399                                 msg.param.pword[0] = GRAPH_READSTR_RESPONSE;
400                         }
401                         strcpy(msg.param.pstr, internal_buffer);
402                         write(resp_sock, &msg, sizeof(G_MESSAGE));   
403                         string_wait = FALSE;
404                         was_line = TRUE;
405                         CharBuffer.clear();
406                 }
407                 else if (ev->ascii() == 8) {
408                         strcnt--;
409                         DelChar();
410                         DelChar();
411                         WriteChar('_');
412                 } else {
413                         internal_buffer[strcnt] = (char)ev->ascii();
414                         strcnt++;
415                         DelChar();
416                         WriteChar((char)ev->ascii());
417                         WriteChar('_');
418                 }
419         }
420 }
421
422
423 void VGR::CloseMe()
424 {
425         qApp->quit();
426 }
427
428
429
430 void VGR::hscrolled(int val)
431 {
432         ox = val;
433         setUpdatesEnabled(TRUE);
434         repaint();
435         setUpdatesEnabled(FALSE);
436 }
437
438 void VGR::vscrolled(int val)
439 {
440         oy = val;
441         setUpdatesEnabled(TRUE);
442         repaint();
443         setUpdatesEnabled(FALSE);
444 }
445
446 void VGR::MakeColors()
447 {
448   lcolors[0] = new QColor(0, 0, 0 ); /* black  */
449   lcolors[1] = new QColor(0, 0, 139);     /* blue dark */
450   lcolors[2] = new QColor(0, 100, 0 );     /* green dark  */
451   lcolors[3] = new QColor(0, 197, 205 );     /* turquoise dark   */
452   lcolors[4] = new QColor(205,0 , 0 );   /* red dark */
453   lcolors[5] = new QColor(238, 130,238); /* violet */
454   lcolors[6] = new QColor(139,35,35 ); /* brown   */
455   lcolors[7] = new QColor(190,190,190 );       /* grey light */
456   lcolors[8] = new QColor(97, 97, 97 );       /* grey dark */
457   lcolors[9] = new QColor(0, 0, 255 );       /* blue */
458   lcolors[10] = new QColor(0, 255, 0 );       /* green */
459   lcolors[11] = new QColor(0, 229,238 );       /* turquoise */
460   lcolors[12] = new QColor(255, 0, 0 );       /* red light */
461   lcolors[13] = new QColor(255, 110,180 );       /* rose */
462   lcolors[14] = new QColor(255,255, 0 );       /* yellow */
463   lcolors[15] = new QColor(255, 255, 255 );       /* white */
464 }
465
466 /****************************************/
467
468 void VGR::SetForeground(int col)
469 {
470         fcol = col;
471 }
472
473 void VGR::SetBackground(int col)
474 {
475         bcol = col;
476 }
477
478 void VGR::Line(int x1, int y1, int x2, int y2)
479 {
480         QPainter p;
481         p.begin(canvas);
482         p.setPen(*lcolors[fcol]);
483         p.drawLine(x1, y1, x2, y2);
484         p.end();
485
486         p.begin(this);
487         p.setPen(*lcolors[fcol]);
488         p.drawLine(x1 - ox, y1 - oy, x2 - ox, y2 - oy);
489         p.end();
490 }
491
492 void VGR::Ellipse(int x, int y, int a, int b, int alfa, int beta, int fill)
493 {
494         QPainter p;
495
496         p.begin(canvas);
497         p.setPen(*lcolors[fcol]);
498         p.setBrush(*lcolors[fcol]);
499         if (fill > 0)
500                 p.drawPie(x, y, a, b, alfa * 16, (beta - alfa) * 16);
501         else
502                 p.drawArc(x, y, a, b, alfa * 16, (beta - alfa) * 16); 
503
504         p.end();
505
506         p.begin(this);
507         p.setPen(*lcolors[fcol]);
508         p.setBrush(*lcolors[fcol]);
509         if (fill > 0)
510                 p.drawPie(x - ox, y - oy, a, b, alfa * 16, (beta - alfa) * 16);
511         else
512                 p.drawArc(x - ox, y - oy, a, b, alfa * 16, (beta - alfa) * 16); 
513         
514         p.end();
515 }
516
517 void VGR::Rect(int x1, int y1, int x2, int y2,int col, int fill)
518 {
519         QPainter p;
520         QBrush b(*lcolors[col]);
521         p.begin(canvas);
522         p.setPen(*lcolors[col]);
523         if (fill > 0)
524                 p.fillRect(x1 , y1 , x2 - x1, y2 - y1, b);
525         else
526                 p.drawRect(x1,y1,x2-x1,y2-y1);
527         
528         p.end();
529
530         p.begin(this);
531         p.setPen(*lcolors[col]);
532         if (fill > 0)
533                 p.fillRect(x1 - ox, y1 - oy, x2 - x1, y2 - y1, b);
534         else
535                 p.drawRect(x1 - ox, y1 - oy, x2 - x1, y2 - y1);
536         p.end();
537 }
538
539 void VGR::TextXY(int x, int y, char *s)
540 {
541         QPainter p;
542         QFontMetrics fm(*prv_font);
543
544         p.begin(canvas);
545         p.setPen(*lcolors[fcol]);
546         p.setBackgroundColor(*lcolors[bcol]);
547         p.setBackgroundMode(Qt::OpaqueMode);
548         p.setFont(*prv_font);
549         p.drawText(x, y + fm.height(), s, strlen(s));
550         p.end();
551
552
553         p.begin(this);
554         p.setPen(*lcolors[fcol]);
555         p.setBackgroundColor(*lcolors[bcol]);
556         p.setBackgroundMode(Qt::OpaqueMode);
557         p.setFont(*prv_font);
558         p.drawText(x - ox, y - oy + fm.height(), s, strlen(s));
559         p.end();
560 }
561
562
563 void VGR::CharXY(int x, int y, char a)
564 {
565         QPainter p;
566         char s[2];
567         QFontMetrics fm(*prv_font);
568
569         s[0] = a;
570         s[1] = '\0';
571         p.begin(canvas);
572         p.setPen(*lcolors[fcol]);
573         p.setBackgroundColor(*lcolors[bcol]);
574         p.setBackgroundMode(Qt::OpaqueMode);
575         p.setFont(*prv_font);
576         p.drawText(x , y + fm.height(), s, strlen(s));
577         p.end();
578
579         p.begin(this);
580         p.setPen(*lcolors[fcol]);
581         p.setBackgroundColor(*lcolors[bcol]);
582         p.setBackgroundMode(Qt::OpaqueMode);
583         p.setFont(*prv_font);
584         p.drawText(x - ox, y - oy + fm.height(), s, strlen(s));
585         p.end();
586 }
587
588
589 void VGR::IntXY(int x, int y, int val)
590 {
591         QPainter p;
592         char s[80];
593         QFontMetrics fm(*prv_font);
594
595         sprintf(s, "%d", val);
596         p.begin(canvas);
597         p.setPen(*lcolors[fcol]);
598         p.setBackgroundColor(*lcolors[bcol]);
599         p.setBackgroundMode(Qt::OpaqueMode);
600         p.setFont(*prv_font);
601         p.drawText(x, y + fm.height(), s, strlen(s));
602         p.end();
603
604         p.begin(this);
605         p.setPen(*lcolors[fcol]);
606         p.setBackgroundColor(*lcolors[bcol]);
607         p.setBackgroundMode(Qt::OpaqueMode);
608         p.setFont(*prv_font);
609         p.drawText(x - ox, y - oy + fm.height(), s, strlen(s));
610         p.end();
611 }
612
613 void VGR::WriteText(char *s)
614 {
615         QPainter p;
616         QFontMetrics fm(*prv_font);
617
618         p.begin(canvas);
619         p.setPen(*lcolors[fcol]);
620         p.setBackgroundColor(*lcolors[bcol]);
621         p.setBackgroundMode(Qt::OpaqueMode);
622         p.setFont(*prv_font);
623         p.drawText(tx * fm.maxWidth(), (ty + 1) * fm.height(), s, strlen(s));
624         p.end();
625
626         p.begin(this);
627         p.setPen(*lcolors[fcol]);
628         p.setBackgroundColor(*lcolors[bcol]);
629         p.setBackgroundMode(Qt::OpaqueMode);
630         p.setFont(*prv_font);
631         p.drawText(tx * fm.maxWidth() - ox, (ty + 1) * fm.height() - oy, s,
632                                                                 strlen(s));
633         p.end();
634
635         tx = tx + strlen(s);
636         if (tx > TEXT_COLS) {
637                 tx = 0;
638                 ty++;
639         }
640         if (ty > TEXT_LINES) {
641                 ClearAll();
642         }
643 }
644
645 void VGR::WriteChar(char a)
646 {
647         QPainter p;
648         QFontMetrics fm(*prv_font);
649         char s[2];
650
651         s[0] = a;
652         s[1] = '\0';
653
654         if (GraphRead) {
655                 p.begin(canvas);
656                 p.setPen(*lcolors[gfcol]);
657                 p.setBackgroundColor(*lcolors[gbcol]);
658                 p.setBackgroundMode(Qt::OpaqueMode);
659                 p.setFont(*prv_font);
660                 p.drawText(gx, gy + fm.height(), s, strlen(s));
661                 p.end();
662
663                 p.begin(this);
664                 p.setPen(*lcolors[gfcol]);
665                 p.setBackgroundColor(*lcolors[gbcol]);
666                 p.setBackgroundMode(Qt::OpaqueMode);
667                 p.setFont(*prv_font);
668                 p.drawText(gx - ox, gy - oy + fm.height(), s, strlen(s));
669                 p.end();
670
671                 gx = gx + strlen(s) * fm.maxWidth();
672                 if (gx > MAXWIDTH) {
673                         gy = gy + fm.height();
674                         gx=0;
675                 }
676                 if (gy > MAXHEIGHT) {
677                         ClearAll();
678                 }
679         } else {
680                 p.begin(canvas);
681                 p.setPen(*lcolors[fcol]);
682                 p.setBackgroundColor(*lcolors[bcol]);
683                 p.setBackgroundMode(Qt::OpaqueMode);
684                 p.setFont(*prv_font);
685                 p.drawText(tx * fm.maxWidth(), (ty + 1) * fm.height(), s, 
686                                                                 strlen(s));
687                 p.end();
688
689                 p.begin(this);
690                 p.setPen(*lcolors[fcol]);
691                 p.setBackgroundColor(*lcolors[bcol]);
692                 p.setBackgroundMode(Qt::OpaqueMode);
693                 p.setFont(*prv_font);
694                 p.drawText(tx * fm.maxWidth() - ox, (ty + 1) * fm.height() - oy,
695                                                                 s, strlen(s));
696                 p.end();
697
698                 tx = tx + strlen(s);
699                 if (tx > TEXT_COLS) {
700                         tx = 0;
701                         ty++;
702                 }
703                 if (ty > TEXT_LINES) {
704                         ClearAll();
705                 }
706         }
707 }
708
709 void VGR::DelChar()
710 {
711         QPainter p;
712         QFontMetrics fm(*prv_font);
713
714         if (GraphRead) {
715                 p.begin(canvas);
716                 p.setPen(*lcolors[fcol]);
717                 p.fillRect(gx - fm.maxWidth(), gy, fm.maxWidth(),
718                                 fm.height() + fm.descent() + 1, *lcolors[bcol]);
719                 p.end();
720
721                 p.begin(this);
722                 p.setPen(*lcolors[fcol]);
723
724                 p.fillRect(gx - ox - fm.maxWidth(), gy - oy, fm.maxWidth(),
725                                 fm.height() + fm.descent() + 1, *lcolors[bcol]);
726                 p.end();
727                 gx = gx - fm.maxWidth();
728         } else {
729                 /* Text read */
730                 p.begin(canvas);
731                 p.setPen(*lcolors[fcol]);
732                 p.fillRect((tx - 1) * fm.maxWidth(), (ty) * fm.height(), 
733                                                         tx * fm.maxWidth(),
734                                 (ty + 1) * fm.height() + fm.descent() + 1, 
735                                                                 *lcolors[bcol]);
736                 p.end();
737
738                 p.begin(this);
739                 p.setPen(*lcolors[fcol]);
740                 p.fillRect((tx - 1) * fm.maxWidth() - ox, (ty) * fm.height() - oy,
741                                                         tx * fm.maxWidth(),
742                                 (ty + 1) * fm.height() + fm.descent() + 1,
743                                                                 *lcolors[bcol]);
744                 p.end();
745
746                 tx--;
747                 if (tx < 0)
748                         tx = 0;
749         }
750 }
751
752 void VGR::PutChar(char a)
753 {
754         QPainter p;
755         QFontMetrics fm(*prv_font);
756         char s[2];
757
758         s[0] = a;
759         s[1] = '\0';
760         p.begin(canvas);
761         p.setPen(*lcolors[fcol]);
762         p.setBackgroundColor(*lcolors[bcol]);
763         p.setBackgroundMode(Qt::OpaqueMode);
764         p.setFont(*prv_font);
765         p.drawText(tx * fm.maxWidth(), (ty + 1) * fm.height(), s, strlen(s));
766         p.end();
767
768         p.begin(this);
769         p.setPen(*lcolors[fcol]);
770         p.setBackgroundColor(*lcolors[bcol]);
771         p.setBackgroundMode(Qt::OpaqueMode);
772         p.setFont(*prv_font);
773         p.drawText(tx * fm.maxWidth() - ox, (ty + 1) * fm.height() - oy, s,
774                                                                 strlen(s));
775         p.end();
776 }
777
778 void VGR::WriteLine()
779 {
780         tx = 0;
781         ty++;
782         if (ty > TEXT_LINES) {
783                 ClearAll();
784         }
785 }
786
787
788 void VGR::Point(int x, int y)
789 {
790         QPainter p;
791
792         p.begin(canvas);
793         p.setPen(*lcolors[fcol]);
794         p.drawPoint(x, y);
795         p.end();
796
797         p.begin(this);
798         p.setPen(*lcolors[fcol]);
799         p.drawPoint(x - ox, y - oy);
800         p.end();
801 }
802
803 void VGR::ClearArea(int x, int y, int w, int h)
804 {
805         QPainter p;
806         p.begin(canvas);
807         p.eraseRect(x, y, w, h);
808         p.end();
809
810         p.begin(this);
811         p.eraseRect(x - ox, y - oy, w, h);
812         p.end();
813 }
814
815 void VGR::ClearAll()
816 {
817         QPainter p;
818         QBrush b(QColor(white));
819
820         tx = ty = 0;
821         curx = cury = 0;
822         canvas->fill(backgroundColor());
823
824         p.begin(this);
825         p.fillRect(0, 0, width() - 16, height() - 16, backgroundColor());
826         p.end();
827 }
828
829 int VGR::Getmap(int w, int h)
830 {
831         QPixmap *m;
832
833         m = new QPixmap(w, h);
834         bitBlt(m, 0, 0, canvas, curx, cury, w, h);
835         maps.append(new VGRMap(firstfreemap, m));
836         firstfreemap++;
837         return(firstfreemap - 1);
838 }
839
840
841 void VGR::Putmap(int map)
842 {
843         VGRMap *m;
844         QListIterator<VGRMap *> mapsIterator(maps);
845
846         while (mapsIterator.hasNext()) {
847                 m = mapsIterator.next();
848                 if (m->number == map) {
849                         bitBlt(canvas, curx, cury, m->map, 0, 0,
850                                         m->map->width(), m->map->height());
851                         bitBlt(this, curx - ox, cury - oy, m->map, 0, 0,
852                                         m->map->width(), m->map->height());
853                         break;
854                 }
855         }
856 }
857
858 void VGR::Outstring(int x, int y, char *s, int b, int f)
859 {
860         QPainter p;
861         QFontMetrics fm(*prv_font);
862
863         p.begin(canvas);
864         p.setPen(*lcolors[f]);
865         p.setBackgroundColor(*lcolors[b]);
866         p.setBackgroundMode(Qt::OpaqueMode);
867         p.setFont(*prv_font);
868         p.drawText(x, y + fm.height(), s, strlen(s));
869         p.end();
870
871         p.begin(this);
872         p.setPen(*lcolors[f]);
873         p.setFont(*prv_font);
874         p.setBackgroundColor(*lcolors[b]);
875         p.setBackgroundMode(Qt::OpaqueMode);
876         p.drawText(x - ox, y - oy + fm.height(), s, strlen(s));
877         p.end();
878
879 }
880
881 void VGR::writeintxy(int x, int y, int val,int c)
882 {
883         QPainter p;
884         char s[80];
885         QFontMetrics fm(*prv_font);
886
887         sprintf(s, "%d", val);
888         p.begin(canvas);
889         p.setPen(*lcolors[c]);
890         p.setFont(*prv_font);
891         p.drawText(x, y, s, strlen(s));
892         p.end();
893
894         p.begin(this);
895         p.setPen(*lcolors[c]);
896         p.setFont(*prv_font);
897         p.drawText(x - ox, y - oy + fm.height(), s, strlen(s));
898         p.end();
899 }
900
901
902 void VGR::CurPos()
903 {
904         G_MESSAGE msg;
905         msg.msg_type = MSG_GRAPH;
906         msg.param.pword[0] = GRAPH_CURPOS_RESPONSE;
907         msg.param.pword[3] = curx;
908         msg.param.pword[4] = cury;
909         write(resp_sock, &msg, sizeof(G_MESSAGE));
910 }
911
912
913 void VGR::RequestMessage()
914 {
915         G_MESSAGE m,mm;
916         int stat;
917
918         bzero(&m, sizeof(G_MESSAGE));
919         stat = read(resp_sock, &m, sizeof(G_MESSAGE));
920         if (stat > 0) {
921                 if (m.msg_type == MSG_GRAPH) {
922                         switch(m.param.pword[0]) {
923                         case GRAPH_FREE: 
924                                 close_btn->setEnabled(TRUE);
925                                 delete request;
926                                 request = NULL;
927                                 break;
928                         case GRAPH_SET_TITLE:
929                                 setCaption(m.param.pstr);
930                                 break;
931                         case GRAPH_WRITE:
932                                 if (strcmp(m.param.pstr,"\n") == 0)
933                                         WriteLine();
934                                 else
935                                         WriteText(m.param.pstr);
936
937                                 break;
938                         case GRAPH_WRITEXY:
939                                 TextXY(
940                                         m.param.pword[3],
941                                         m.param.pword[4],
942                                         m.param.pstr
943                                 );
944                                 break;
945                         case GRAPH_READCHAR:
946                                 if (!GetInput(0))
947                                         char_wait = TRUE;
948
949                                 break;
950                         case GRAPH_READSTR:
951                                 strcpy(internal_buffer, "");
952                                 strcnt = 0;
953                                 string_wait = TRUE;
954                                 WriteChar('_');
955                                 break;
956                         case GRAPH_READLN:
957                                 if (was_line) {
958                                         m.msg_type = MSG_GRAPH;
959                                         m.param.pword[0] = GRAPH_READLN_RESPONSE;
960                                         write(resp_sock, &m, sizeof(G_MESSAGE));
961                                         was_line = FALSE;
962                                 } else if (!GetInput(1))
963                                         line_wait = TRUE;
964                                 break;
965                         case GRAPH_PUTCHAR:
966                                 WriteChar(m.param.pchar);
967                                 break;
968                         case GRAPH_LINETO:
969                                 Line(
970                                         curx,cury,
971                                         m.param.pword[3],
972                                         m.param.pword[4]
973                                 );
974                                 break;
975                         case GRAPH_ELLIPSE:
976                                 Ellipse(
977                                         m.param.pword[3],
978                                         m.param.pword[4],
979                                         m.param.pword[5],
980                                         m.param.pword[6],
981                                         m.param.pword[7],
982                                         m.param.pword[8],
983                                         m.param.pword[9]
984                                 );
985                                 break;
986                         case GRAPH_RECT:
987                                 Rect(
988                                         m.param.pword[3],
989                                         m.param.pword[4],
990                                         m.param.pword[5],
991                                         m.param.pword[6],
992                                         m.param.pword[7],
993                                         m.param.pword[8]
994                                 );
995                                 break;  
996                         case GRAPH_FOREGROUND:
997                                 SetForeground(m.param.pword[3]);
998                                 break;
999                         case GRAPH_BACKGROUND:
1000                                 SetBackground(m.param.pword[3]);
1001                                 break;
1002                         case GRAPH_POINT:
1003                                 Point(m.param.pword[3], m.param.pword[4]);
1004                                 break;
1005                         case GRAPH_CLEAR:
1006                                 ClearAll();
1007                                 break;
1008                         case GRAPH_INKEY:
1009                                 if (!GetInput(2))
1010                                         inkey_wait = TRUE;
1011
1012                                 break; 
1013                         case GRAPH_CURPOS:
1014                                 CurPos();
1015                                 break;
1016                         case GRAPH_OUTSTRING:
1017                                 Outstring(
1018                                         m.param.pword[2],
1019                                         m.param.pword[3],
1020                                         m.param.pstr,
1021                                         m.param.pword[4],
1022                                         m.param.pword[5]
1023                                 );
1024                                 break;
1025                         case GRAPH_WRITEINTXY:
1026                                 writeintxy(m.param.pword[2], m.param.pword[3],
1027                                         m.param.pword[4], m.param.pword[5]);
1028                                 break;
1029                         case GRAPH_GETMAP:
1030                                 bzero(&mm, sizeof(G_MESSAGE));
1031                                 mm.msg_type = MSG_GRAPH;
1032                                 mm.param.pword[0] = GRAPH_GETMAP_RESPONSE;
1033                                 mm.param.pword[2] = Getmap(m.param.pword[2] - curx, m.param.pword[3] - cury);
1034                                 mm.param.pword[3] = m.param.pword[2] - curx;
1035                                 mm.param.pword[4] = m.param.pword[3] - cury;
1036                                 write(resp_sock, &mm, sizeof(G_MESSAGE));
1037                                 break;
1038                         case GRAPH_PUTMAP:
1039                                 Putmap(m.param.pword[2]);
1040                                 break;
1041                         case GRAPH_MOVE:
1042                                 curx = m.param.pword[2];
1043                                 cury = m.param.pword[3];
1044                                 break;
1045                         case GRAPH_MGETPRESS:
1046                                 mouse_wait = TRUE;
1047                                 break;
1048                         case GRAPH_MAGIC:
1049                                 MagicGraph(&m);
1050                                 break;
1051                         case GRAPH_HASCII:
1052                                 if (m.param.pword[1] != 0)
1053                                         CharXY(curx, cury, (char)m.param.pword[1]);
1054                                 else
1055                                         CharXY(curx, cury, ' ');
1056                                 break;
1057                         } /* end switch */
1058                 } /* stat > 0 */
1059         }
1060 }
1061
1062
1063
1064
1065 void VGR::MagicGraph(G_MESSAGE *msg)
1066 {
1067         int f,b;
1068         char ss[255];
1069         QPixmap p;
1070         VGRMap *pmap;
1071
1072         switch(msg->param.pword[1]) {
1073         /* gotoxy */
1074         case 10:
1075                 tx = msg->param.pword[2];
1076                 ty = msg->param.pword[3];
1077                 break;
1078         /* forecolor */
1079         case 11:
1080                 fcol = msg->param.pword[2];
1081                 break;
1082         /* bkcolor */
1083         case 12:
1084                 bcol = msg->param.pword[2];
1085                 break;
1086         case 13:
1087                 prv_font = bold_font;
1088                 break;
1089         case 14:
1090                 prv_font = italic_font;
1091                 break;
1092         case 15:
1093                 prv_font = normal_font;
1094                 break; 
1095         case 16:
1096                 ClearAll();
1097                 break;
1098         /* Draw array_of char (x,y,fcol,bcol) */
1099         case 303:
1100                 f = fcol;
1101                 b = bcol;
1102                 fcol = msg->param.pword[4];
1103                 bcol = msg->param.pword[5];
1104                 TextXY(
1105                         msg->param.pword[2],
1106                         msg->param.pword[3],
1107                         msg->param.pstr
1108                 );
1109                 fcol = f;
1110                 bcol = b;
1111                 break;
1112         /* Draw int (x,y,int,fcol,bcol) */
1113         case 300:
1114                 f = fcol;
1115                 b = bcol;
1116                 fcol = msg->param.pword[5];
1117                 bcol = msg->param.pword[6];
1118                 IntXY(
1119                         msg->param.pword[2],
1120                         msg->param.pword[3],
1121                         msg->param.pword[4]
1122                 );
1123                 fcol = f;
1124                 bcol = b;
1125                 break;
1126         /* Draw char (x,y,char,fcol,bcol) */
1127         case 301:
1128                 f = fcol;
1129                 b = bcol;
1130                 fcol = msg->param.pword[5];
1131                 bcol = msg->param.pword[6];
1132                 CharXY(msg->param.pword[2], msg->param.pword[3], 
1133                                                 (char)(msg->param.pword[4]));
1134                 fcol = f;
1135                 bcol = b;
1136                 break;
1137         /* Draw real (x,y,int,frac,fcol,bcol) */
1138         case 302:
1139                 f = fcol;
1140                 b = bcol;
1141                 fcol = msg->param.pword[6];
1142                 bcol = msg->param.pword[7];
1143                 sprintf(ss, "%d.%d", msg->param.pword[4], msg->param.pword[5]);
1144                 TextXY(msg->param.pword[2], msg->param.pword[3], ss);
1145                 fcol = f;
1146                 bcol = b;
1147                 break;
1148         /* ReadText (x,y,fcol,bcol) */
1149         case -304:
1150         case -305:
1151         case -307:
1152                 gfcol = msg->param.pword[4];
1153                 gbcol = msg->param.pword[5];
1154                 strcpy(internal_buffer, "");
1155                 strcnt = 0;
1156                 GraphRead = TRUE;
1157                 gx = msg->param.pword[2];
1158                 gy = msg->param.pword[3]; 
1159                 string_wait = TRUE;
1160                 WriteChar('_');
1161                 break;
1162         case -306:
1163                 if (!GetInput(0)) {
1164                         gfcol = msg->param.pword[4];
1165                         gbcol = msg->param.pword[5];
1166                         strcpy(internal_buffer, "");
1167                         strcnt = 0;
1168                         GraphRead = TRUE;
1169                         gx = msg->param.pword[2];
1170                         gy = msg->param.pword[3]; 
1171                         char_wait = TRUE;
1172                 }
1173                 break;
1174         /* Put image from file (x,y,fname) */
1175         case 308:
1176                 if (p.load(msg->param.pstr)) {
1177                         bitBlt(canvas, msg->param.pword[2],
1178                                                 msg->param.pword[3], &p,
1179                                                 0, 0, p.width(), p.height());
1180                         bitBlt(this, msg->param.pword[2] - ox,
1181                                                 msg->param.pword[3] - oy, &p,
1182                                                 0, 0, p.width(), p.height());
1183                 }
1184                 break;
1185         /* Kill map */
1186         case 309: {
1187                 QListIterator<VGRMap *> mapsIterator(maps);
1188
1189                 while (mapsIterator.hasNext()) {
1190                         pmap = mapsIterator.next();
1191                         if (msg->param.pword[2] == pmap->number) {
1192                                 maps.remove(pmap);
1193                                 break;
1194                         }
1195                 }
1196                 break;
1197         }
1198         /* Line (x1,y1,x2,y2,col) */
1199         case 310:
1200                 f = fcol;
1201                 fcol = msg->param.pword[6];
1202                 Line(
1203                         msg->param.pword[2], msg->param.pword[3],
1204                         msg->param.pword[4], msg->param.pword[5]
1205                 );
1206                 fcol = f;
1207                 break;
1208         /* Rectangle(x1,y1,x2,y2,fcol,icol) */
1209         case 311:
1210                 Rect(
1211                         msg->param.pword[2], msg->param.pword[3],
1212                         msg->param.pword[4], msg->param.pword[5],
1213                         msg->param.pword[7],
1214                         1
1215                 );
1216                 Rect(msg->param.pword[2], msg->param.pword[3],
1217                                 msg->param.pword[4],msg->param.pword[5],
1218                                 msg->param.pword[6], 0);
1219                 break;
1220         /* ClearArea(x1,y1,w,h) */
1221         case 312:
1222                 ClearArea(msg->param.pword[2],msg->param.pword[3],
1223                                 msg->param.pword[4], msg->param.pword[5]);
1224                 break;
1225         }//switch
1226 }
1227
1228 int main(int argc, char **argv)
1229 {
1230         QApplication app(argc, argv);
1231         VGR gs(argc, argv);
1232         gs.show();
1233         return app.exec();
1234 }