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