Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download

open-axiom repository from github

24005 views
1
/*
2
Copyright (C) 1991-2002, The Numerical Algorithms Group Ltd.
3
All rights reserved.
4
Copyright (C) 2007-2011, Gabriel Dos Reis.
5
All rights reserved.
6
7
Redistribution and use in source and binary forms, with or without
8
modification, are permitted provided that the following conditions are
9
met:
10
11
- Redistributions of source code must retain the above copyright
12
notice, this list of conditions and the following disclaimer.
13
14
- Redistributions in binary form must reproduce the above copyright
15
notice, this list of conditions and the following disclaimer in
16
the documentation and/or other materials provided with the
17
distribution.
18
19
- Neither the name of The Numerical Algorithms Group Ltd. nor the
20
names of its contributors may be used to endorse or promote products
21
derived from this software without specific prior written permission.
22
23
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
24
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
25
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
26
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
27
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
28
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
29
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34
*/
35
36
#define _CONTROL2D_C
37
#include "openaxiom-c-macros.h"
38
39
#include <stdlib.h>
40
#include <unistd.h>
41
#include <stdio.h>
42
#include <string.h>
43
#include <X11/X.h>
44
#include <X11/Xlib.h>
45
#include <X11/Xutil.h>
46
47
#include "cfuns.h"
48
#include "header2.h"
49
#include "buttons2d.H1"
50
#include "all_2d.H1"
51
#include "Gfun.H1"
52
#include "XSpadFill.h"
53
#include "util.H1"
54
55
56
#include "mouse11.bitmap"
57
#include "mouse11.mask"
58
59
/* Defines the pixmap for the arrow displayed in the scale window */
60
61
#define scaleArrowN 11
62
static XPoint scaleArrow[scaleArrowN] = {
63
{55,14},{64,23},{59,23},
64
{66,45},{79,45},
65
{55,69},
66
{31,45},{44,45},
67
{51,23},{46,23},{55,14} };
68
69
/* Defines the pixmap for the arrows displayed in the translate window */
70
71
#define translateArrowN 25
72
static XPoint translateArrow[translateArrowN] = {
73
{55,2},{60,10},{58,10},{58,37},
74
{85,37},{85,35},{93,40},{85,45},{85,43},{58,43},
75
{58,70},{60,70},{55,78},{50,70},{52,70},{52,43},
76
{25,43}, {25,45}, {17,40}, {25,35}, {25,37}, {52,37},
77
{52,10},{50,10},{55,2} };
78
79
/****************************
80
* void writeControlTitle() *
81
****************************/
82
83
void
84
writeControlTitle(void)
85
{
86
87
int strlength;
88
89
s = viewport->title;
90
strlength = strlen(s);
91
XClearArea(dsply,control->controlWindow,0,0,controlWidth,potA,False);
92
GSetForeground(anotherGC,(float)controlTitleColor,Xoption);
93
GDrawImageString(anotherGC,control->controlWindow,
94
centerX(anotherGC,s,strlength,controlWidth),
95
15,s,strlength,Xoption);
96
97
} /* writeControlTitle() */
98
99
void
100
makeMessageFromData(int whichGraph)
101
{
102
if (viewport->haveControl) {
103
if ((graphStateArray[whichGraph].scaleX) > 99.0) {
104
strcpy(scaleXReport,"big");
105
} else {
106
sprintf(scaleXReport,"%4.1f",graphStateArray[whichGraph].scaleX);
107
}
108
if ((graphStateArray[whichGraph].scaleY) > 99.0) {
109
strcpy(scaleYReport,"big");
110
} else {
111
sprintf(scaleYReport,"%4.1f",graphStateArray[whichGraph].scaleY);
112
}
113
if ((graphStateArray[whichGraph].centerX) > 999.0) {
114
strcpy(deltaXReport,"+big");
115
} else if ((graphStateArray[whichGraph].centerX) < -999.0) {
116
strcpy(deltaXReport,"-big");
117
} else {
118
sprintf(deltaXReport,"%4.0f",
119
-graphStateArray[whichGraph].centerX /
120
graphArray[whichGraph].unitX);
121
}
122
if ((graphStateArray[whichGraph].centerY) > 999.0) {
123
strcpy(deltaYReport,"+big");
124
} else if ((graphStateArray[whichGraph].centerY) < -999.0) {
125
strcpy(deltaYReport,"-big");
126
} else {
127
sprintf(deltaYReport,"%4.0f",
128
-graphStateArray[whichGraph].centerY /
129
graphArray[whichGraph].unitY);
130
}
131
sprintf(viewport->controlPanel->message,"[%s,%s] >%d< [%s,%s]",
132
scaleXReport,scaleYReport,whichGraph+1,deltaXReport,deltaYReport);
133
} /* if haveControl */
134
135
} /* makeMessageFromData() */
136
137
138
void
139
writeControlMessage(void)
140
{
141
int strlength;
142
controlPanelStruct *cp;
143
XWindowAttributes cwInfo;
144
145
cp = viewport->controlPanel;
146
XGetWindowAttributes(dsply,cp->controlWindow,&cwInfo);
147
strlength = strlen(cp->message);
148
149
150
151
GDrawImageString(controlMessageGC,cp->controlWindow,
152
centerX(globalGC1,cp->message,strlength,controlWidth),
153
controlMessageY + globalFont->max_bounds.ascent - 2,
154
cp->message,strlength,Xoption);
155
}
156
157
/*********************************/
158
/*** void drawControlPanel() ***/
159
/*********************************/
160
161
void
162
drawControlPanel(void)
163
{
164
165
controlPanelStruct *cp;
166
int i,strlength;
167
const char* s;
168
169
cp = viewport->controlPanel;
170
/* Draw border lines to separate the potentiometer, message, graph select
171
and button regions of the control panel. */
172
GSetForeground(trashGC,(float)foregroundColor,Xoption);
173
GSetLineAttributes(trashGC,3,LineSolid,CapButt,JoinMiter,Xoption);
174
GDrawLine(trashGC, cp->controlWindow, 0, potA, controlWidth, potA, Xoption);
175
GSetLineAttributes(trashGC,2,LineSolid,CapButt,JoinMiter,Xoption);
176
GDrawLine(trashGC, cp->controlWindow, 0, potB, controlWidth, potB, Xoption);
177
GDrawLine(trashGC, cp->controlWindow, 0, messageBot,
178
controlWidth, messageBot, Xoption);
179
GDrawLine(trashGC, cp->controlWindow, 0, 286, controlWidth, 286, Xoption);
180
181
/** put the line width as 1 last because used below as well **/
182
GSetLineAttributes(trashGC,1,LineSolid,CapButt,JoinMiter,Xoption);
183
GDrawRectangle(trashGC,cp->controlWindow,closeLeft,closeTop,
184
(controlWidth-closeLeft+8),(controlHeight-closeTop+8),Xoption);
185
186
/* Write potentiometer titles on the control panel. */
187
writeControlTitle();
188
GSetForeground(globGC,(float)controlPotHeaderColor,Xoption);
189
s = "Scale";
190
strlength = strlen(s);
191
GDrawString(globGC,cp->controlWindow,
192
centerX(globGC,s,strlength,
193
cp->buttonQueue[scale2D].buttonWidth) +
194
cp->buttonQueue[scale2D].buttonX, 31+headerHeight,s,strlength,Xoption);
195
196
s = "Translate";
197
strlength = strlen(s);
198
GDrawString(globGC,cp->controlWindow,
199
centerX(globGC,s,strlength,
200
cp->buttonQueue[translate2D].buttonWidth) +
201
cp->buttonQueue[translate2D].buttonX,
202
31+headerHeight,s,strlen(s),Xoption);
203
204
GSetForeground(globGC,(float)controlColorColor,Xoption);
205
206
/* Write title of the graph selection window. */
207
s = "Graphs";
208
strlength = strlen(s);
209
GDrawString(globGC,cp->controlWindow,
210
centerX(globGC,s,strlength,controlWidth),graphHeaderHeight,
211
s,strlength,Xoption);
212
213
/* Write titles on regular buttons and draw pixmaps on potentiometers. */
214
215
for (i=0; i<(maxButtons2D); i++) {
216
if ((cp->buttonQueue[i]).pot) {
217
218
GSetForeground(globalGC1,(float)buttonColor,Xoption);
219
GDrawRectangle(globalGC1,cp->controlWindow,
220
(cp->buttonQueue[i]).buttonX,
221
(cp->buttonQueue[i]).buttonY,
222
(cp->buttonQueue[i]).buttonWidth,
223
(cp->buttonQueue[i]).buttonHeight,Xoption);
224
225
GSetForeground(trashGC,
226
(float)monoColor((cp->buttonQueue[i]).textColor),Xoption);
227
228
GDrawLine(globalGC1,cp->controlWindow, /* trashGC, */
229
(cp->buttonQueue[i]).buttonX + (cp->buttonQueue[i]).xHalf,
230
(cp->buttonQueue[i]).buttonY,
231
(cp->buttonQueue[i]).buttonX + (cp->buttonQueue[i]).xHalf,
232
(cp->buttonQueue[i]).buttonY + 2*(cp->buttonQueue[i]).yHalf,Xoption);
233
GDrawLine(globalGC1,cp->controlWindow, /* trashGC, */
234
(cp->buttonQueue[i]).buttonX,
235
(cp->buttonQueue[i]).buttonY + (cp->buttonQueue[i]).yHalf,
236
(cp->buttonQueue[i]).buttonX + 2*(cp->buttonQueue[i]).xHalf,
237
(cp->buttonQueue[i]).buttonY + (cp->buttonQueue[i]).yHalf,Xoption);
238
switch (i) {
239
case scale2D:
240
GDrawLines(trashGC,cp->controlWindow,scaleArrow,
241
scaleArrowN,CoordModeOrigin,Xoption);
242
break;
243
case translate2D:
244
GDrawLines(trashGC,cp->controlWindow,translateArrow,
245
translateArrowN,CoordModeOrigin,Xoption);
246
break;
247
} /* switch i */
248
} else if (cp->buttonQueue[i].graphNum) {
249
250
if (mono) {
251
if (graphStateArray[i-graphStart].showing) {
252
GSetForeground(graphGC,(float)backgroundColor,Xoption);
253
GSetBackground(graphGC,(float)foregroundColor,Xoption);
254
} else {
255
GSetForeground(graphGC,(float)foregroundColor,Xoption);
256
GSetBackground(graphGC,(float)backgroundColor,Xoption);
257
}
258
strlength = strlen((cp->buttonQueue[i]).text);
259
GDrawImageString(graphGC,cp->controlWindow,
260
(cp->buttonQueue[i]).buttonX +
261
centerX(graphGC,cp->buttonQueue[i].text,
262
strlength,(cp->buttonQueue[i]).buttonWidth),
263
(cp->buttonQueue[i]).buttonY +
264
centerY(graphGC,(cp->buttonQueue[i]).buttonHeight),
265
cp->buttonQueue[i].text,strlength,Xoption);
266
} else {
267
if (graphStateArray[i-graphStart].showing)
268
GSetForeground(graphGC,(float)graphBarShowingColor,Xoption);
269
else
270
GSetForeground(graphGC,(float)graphBarHiddenColor,Xoption);
271
strlength = strlen((cp->buttonQueue[i]).text);
272
GDrawString(graphGC,cp->controlWindow,
273
(cp->buttonQueue[i]).buttonX +
274
centerX(graphGC,cp->buttonQueue[i].text,
275
strlength,(cp->buttonQueue[i]).buttonWidth),
276
(cp->buttonQueue[i]).buttonY +
277
centerY(graphGC,(cp->buttonQueue[i]).buttonHeight),
278
cp->buttonQueue[i].text,strlength,Xoption);
279
}
280
} else if (cp->buttonQueue[i].graphSelect) {
281
/* The select characters are defined as: "^" for on and "-" for off. */
282
if (graphStateArray[i-graphSelectStart].selected) {
283
GSetForeground(graphGC,(float)graphBarSelectColor,Xoption);
284
strcpy((cp->buttonQueue[i]).text,"^");
285
} else {
286
GSetForeground(graphGC,(float)graphBarNotSelectColor,Xoption);
287
*(cp->buttonQueue[i]).text = '-';
288
strcpy((cp->buttonQueue[i]).text,"-");
289
}
290
GDrawString(graphGC,cp->controlWindow,
291
(cp->buttonQueue[i]).buttonX +
292
centerX(graphGC,cp->buttonQueue[i].text,
293
strlength,(cp->buttonQueue[i]).buttonWidth),
294
(cp->buttonQueue[i]).buttonY +
295
centerY(graphGC,(cp->buttonQueue[i]).buttonHeight),
296
cp->buttonQueue[i].text,strlength,Xoption);
297
}
298
else { /* a regular button */
299
int isOn = 1;
300
301
switch(i) {
302
case pointsOnOff:
303
isOn = pointsON = graphStateArray[0].pointsOn;
304
if (graphStateArray[0].pointsOn)
305
strcpy((cp->buttonQueue[i]).text,"Pts On ");
306
else
307
strcpy((cp->buttonQueue[i]).text,"Pts Off");
308
break;
309
310
case spline2D:
311
isOn = splineON = graphStateArray[0].splineOn;
312
if (graphStateArray[0].splineOn)
313
strcpy((cp->buttonQueue[i]).text, "Box On ");
314
else
315
strcpy((cp->buttonQueue[i]).text, "Box Off");
316
break;
317
318
case connectOnOff:
319
isOn = connectON = graphStateArray[0].connectOn;
320
if (graphStateArray[0].connectOn)
321
strcpy((cp->buttonQueue[i]).text, "Lines On ");
322
else
323
strcpy((cp->buttonQueue[i]).text, "Lines Off");
324
break;
325
326
case axesOnOff2D:
327
isOn = axesON = graphStateArray[0].axesOn;
328
if (graphStateArray[0].axesOn)
329
strcpy((cp->buttonQueue[i]).text , "Axes On ");
330
else
331
strcpy((cp->buttonQueue[i]).text , "Axes Off");
332
break;
333
334
case unitsOnOff2D:
335
isOn = unitsON = graphStateArray[0].unitsOn;
336
if (graphStateArray[0].unitsOn)
337
strcpy( (cp->buttonQueue[i]).text , "Units On ");
338
else
339
strcpy( (cp->buttonQueue[i]).text , "Units Off");
340
break;
341
case closeAll2D:
342
isOn = 0;
343
344
default:
345
break;
346
} /* switch i */
347
348
s = (cp->buttonQueue[i]).text;
349
strlength = strlen(s);
350
351
GDrawPushButton(dsply, globalGC1, trashGC, processGC, cp->controlWindow,
352
(cp->buttonQueue[i]).buttonX, (cp->buttonQueue[i]).buttonY,
353
(cp->buttonQueue[i]).buttonWidth, (cp->buttonQueue[i]).buttonHeight,
354
isOn, s,buttonColor,
355
monoColor((cp->buttonQueue[i]).textColor), Xoption);
356
357
} /* else a regular button */
358
} /* for each button */
359
360
/* Refresh the latest message */
361
makeMessageFromData(0);
362
writeControlMessage();
363
XFlush(dsply);
364
365
} /*** drawControlPanel ***/
366
367
controlXY
368
getControlXY(int whereDoYouWantPanel)
369
{
370
XWindowAttributes wAttr, wAttrib;
371
controlXY cXY;
372
int tmp=1;
373
Window rootW, parentW, *childrenWs, tmpW;
374
unsigned int nChildren;
375
376
tmpW = viewport->titleWindow;
377
while(tmp) {
378
XQueryTree(dsply,tmpW,&rootW,&parentW,&childrenWs,&nChildren);
379
XFree(childrenWs);
380
if (parentW == rtWindow) tmp = 0;
381
else tmpW = parentW;
382
}
383
XGetWindowAttributes(dsply,tmpW,&wAttrib);
384
385
XGetWindowAttributes(dsply,viewport->titleWindow,&wAttr);
386
if (whereDoYouWantPanel) {
387
switch (whereDoYouWantPanel) {
388
case 1: /* right */
389
cXY.putX = wAttrib.x + wAttrib.width;
390
cXY.putY = wAttrib.y;
391
break;
392
case 2: /* bottom */
393
cXY.putX = wAttrib.x + (wAttr.width - controlWidth)/2; /* center it */
394
cXY.putY = wAttrib.y + wAttrib.height;
395
break;
396
case 3: /* left */
397
cXY.putX = wAttrib.x - controlWidth - borderWidth;
398
cXY.putY = wAttrib.y;
399
break;
400
case 4: /* top */
401
cXY.putX = wAttrib.x + (wAttr.width - controlWidth)/2;
402
cXY.putY = wAttrib.y - controlHeight - borderHeight;
403
}
404
} else {
405
if ((physicalWidth - (wAttrib.x + wAttr.width)) >= controlWidth) {
406
cXY.putX = wAttrib.x + wAttrib.width;
407
cXY.putY = wAttrib.y;
408
} else if ((physicalHeight - (wAttrib.y + wAttr.height)) >=
409
controlHeight) {
410
cXY.putX = wAttrib.x + (wAttr.width - controlWidth)/2;
411
cXY.putY = wAttrib.y + wAttrib.height;
412
} else if (wAttrib.x >= controlWidth) {
413
cXY.putX = wAttrib.x - controlWidth - borderWidth;
414
cXY.putY = wAttrib.y;
415
} else if (wAttrib.y >= controlHeight) {
416
cXY.putX = wAttrib.x + (wAttr.width - controlWidth)/2;
417
cXY.putY = wAttrib.y - controlHeight - borderHeight;
418
} else { /* put inside of viewport */
419
cXY.putX = wAttrib.x + wAttr.width - controlWidth;
420
cXY.putY = wAttrib.y + wAttr.height - controlHeight;
421
}
422
}
423
return(cXY);
424
425
}
426
427
/************************************************/
428
/*** controlPanelStruct *makeControlPanel() ***/
429
/************************************************/
430
431
controlPanelStruct *
432
makeControlPanel(void)
433
{
434
435
Window cw;
436
int i,num;
437
controlPanelStruct *control;
438
buttonStruct *buttons;
439
controlXY cXY;
440
XSetWindowAttributes cwAttrib, controlAttrib;
441
XSizeHints sizehints;
442
Pixmap mousebits,mousemask;
443
XColor foreColor, backColor;
444
445
if (!(control = (controlPanelStruct *)malloc(sizeof(controlPanelStruct)))) {
446
fprintf(stderr,"Ran out of memory trying to create a control panel.\n");
447
exitWithAck(RootWindow(dsply,scrn),Window,-1);
448
}
449
450
cXY = getControlXY(0);
451
452
/* Define and assign a mouse cursor. */
453
mousebits = XCreateBitmapFromData(dsply,rtWindow,
454
(const char*) mouseBitmap_bits,
455
mouseBitmap_width,mouseBitmap_height);
456
mousemask = XCreateBitmapFromData(dsply,rtWindow,
457
(const char*) mouseMask_bits,
458
mouseMask_width,mouseMask_height);
459
cwAttrib.background_pixel = backgroundColor; /* controlBackground; */
460
cwAttrib.border_pixel = foregroundColor;
461
cwAttrib.backing_store = WhenMapped;
462
cwAttrib.event_mask = controlMASK;
463
cwAttrib.colormap = colorMap;
464
cwAttrib.override_redirect = overrideManager;
465
foreColor.pixel = controlCursorForeground;
466
XQueryColor(dsply,colorMap,&foreColor);
467
backColor.pixel = controlCursorBackground;
468
XQueryColor(dsply,colorMap,&backColor);
469
cwAttrib.cursor = XCreatePixmapCursor(dsply,mousebits,mousemask,
470
&foreColor,&backColor,
471
mouseBitmap_x_hot,mouseBitmap_y_hot);
472
473
cw = XCreateWindow(dsply,rtWindow,
474
cXY.putX,cXY.putY,controlWidth,controlHeight,3,
475
CopyFromParent,InputOutput,CopyFromParent,
476
controlCreateMASK,&cwAttrib);
477
478
sizehints.flags = PPosition | PSize;
479
sizehints.x = cXY.putX;
480
sizehints.y = cXY.putY;
481
sizehints.width = controlWidth;
482
sizehints.height = controlHeight;
483
484
/*** the None stands for icon pixmap...change.... ***/
485
486
XSetNormalHints(dsply,cw,&sizehints);
487
XSetStandardProperties(dsply,cw,"2D Control Panel","2D Control Panel",
488
None,NULL,0,&sizehints);
489
490
control->controlWindow = cw;
491
num = initButtons(control->buttonQueue);
492
control->numOfButtons = num;
493
buttons = control->buttonQueue;
494
495
for (i=0; i<num; i++) {
496
controlAttrib.event_mask = (control->buttonQueue[i]).mask;
497
(control->buttonQueue[i]).self = XCreateWindow(dsply,cw,
498
(control->buttonQueue[i]).buttonX,
499
(control->buttonQueue[i]).buttonY,
500
(control->buttonQueue[i]).buttonWidth,
501
(control->buttonQueue[i]).buttonHeight,
502
0,0,InputOnly,CopyFromParent,
503
buttonCreateMASK,&controlAttrib);
504
505
XMakeAssoc(dsply,table,(control->buttonQueue[i]).self,
506
&((control->buttonQueue[i]).buttonKey));
507
/* Use buttonKey instead of i because buttonKey has a permanent address */
508
XMapWindow(dsply,(control->buttonQueue[i]).self);
509
}
510
511
/* Create message window */
512
control->messageWindow = XCreateWindow(dsply,cw,0,controlMessageY,
513
controlWidth,controlMessageHeight,
514
0,0,InputOnly,CopyFromParent,
515
messageCreateMASK,&cwAttrib);
516
XMapWindow(dsply,control->messageWindow);
517
518
for (i=0; i<scaleArrowN; i++) {
519
scaleArrow[i].x += buttons[scale2D].buttonX;
520
scaleArrow[i].y += buttons[scale2D].buttonY;
521
}
522
for (i=0; i<translateArrowN; i++) {
523
translateArrow[i].x += buttons[translate2D].buttonX;
524
translateArrow[i].y += buttons[translate2D].buttonY;
525
}
526
527
viewport->justMadeControl = yes;
528
return(control);
529
530
} /* makeControlPanel() */
531
532
533
534
535
536
537
/*****************************************/
538
/*** void putControlPanelSomewhere() ***/
539
/*****************************************/
540
541
/* This routine puts up the control panel associated with the viewport
542
passed in. It first tries to put it to the right of the viewport. If
543
there isn't enough room there, it tries the bottom and so on going
544
clockwise. If the viewport is too big and there is no room to put the
545
control panel outside of it, it placed the control panel in the bottom
546
right hand corner of the viewport window. */
547
548
void
549
putControlPanelSomewhere(int whereDoesPanelGo)
550
{
551
controlPanelStruct *control;
552
controlXY whereControl;
553
554
control = viewport->controlPanel;
555
whereControl = getControlXY(whereDoesPanelGo);
556
557
viewport->haveControl = yes;
558
559
XRaiseWindow(dsply,control->controlWindow);
560
XMoveWindow(dsply,control->controlWindow,whereControl.putX,
561
whereControl.putY);
562
563
drawControlPanel();
564
if (viewport->justMadeControl) {
565
XMapWindow(dsply,control->controlWindow);
566
viewport->justMadeControl = no;
567
}
568
XMapWindow(dsply,control->controlWindow);
569
}
570
571
572
573
574
575
/************************************/
576
/*** void clearControlMessage() ***/
577
/************************************/
578
579
void
580
clearControlMessage(void)
581
{
582
583
strcpy(viewport->controlPanel->message,"");
584
585
XClearArea(dsply,viewport->controlPanel->controlWindow,
586
0,controlMessageY-2,controlWidth,controlMessageHeight,False);
587
}
588
589
590
591