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