3 * Micropolis, Unix Version. This game was released for the Unix platform
4 * in or about 1990 and has been modified for inclusion in the One Laptop
5 * Per Child program. Copyright (C) 1989 - 2007 Electronic Arts Inc. If
6 * you need assistance with this program, you may contact:
7 * http://wiki.laptop.org/go/Micropolis or email micropolis@laptop.org.
9 * This program is free software: you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation, either version 3 of the License, or (at
12 * your option) any later version.
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details. You should have received a
18 * copy of the GNU General Public License along with this program. If
19 * not, see <http://www.gnu.org/licenses/>.
21 * ADDITIONAL TERMS per GNU GPL Section 7
23 * No trademark or publicity rights are granted. This license does NOT
24 * give you any right, title or interest in the trademark SimCity or any
25 * other Electronic Arts trademark. You may not distribute any
26 * modification of this program using the trademark SimCity or claim any
27 * affliation or association with Electronic Arts Inc. or its employees.
29 * Any propagation or conveyance of this program must include this
30 * copyright notice and these terms.
32 * If you convey this program (or any modifications of it) and assume
33 * contractual liability for the program to recipients of it, you agree
34 * to indemnify Electronic Arts for any liability that those contractual
35 * assumptions impose on Electronic Arts.
37 * You may not misrepresent the origins of this program; modified
38 * versions of the program must be marked as such and not identified as
39 * the original program.
41 * This disclaimer supplements the one included in the General Public
42 * License. TO THE FULLEST EXTENT PERMISSIBLE UNDER APPLICABLE LAW, THIS
43 * PROGRAM IS PROVIDED TO YOU "AS IS," WITH ALL FAULTS, WITHOUT WARRANTY
44 * OF ANY KIND, AND YOUR USE IS AT YOUR SOLE RISK. THE ENTIRE RISK OF
45 * SATISFACTORY QUALITY AND PERFORMANCE RESIDES WITH YOU. ELECTRONIC ARTS
46 * DISCLAIMS ANY AND ALL EXPRESS, IMPLIED OR STATUTORY WARRANTIES,
47 * INCLUDING IMPLIED WARRANTIES OF MERCHANTABILITY, SATISFACTORY QUALITY,
48 * FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT OF THIRD PARTY
49 * RIGHTS, AND WARRANTIES (IF ANY) ARISING FROM A COURSE OF DEALING,
50 * USAGE, OR TRADE PRACTICE. ELECTRONIC ARTS DOES NOT WARRANT AGAINST
51 * INTERFERENCE WITH YOUR ENJOYMENT OF THE PROGRAM; THAT THE PROGRAM WILL
52 * MEET YOUR REQUIREMENTS; THAT OPERATION OF THE PROGRAM WILL BE
53 * UNINTERRUPTED OR ERROR-FREE, OR THAT THE PROGRAM WILL BE COMPATIBLE
54 * WITH THIRD PARTY SOFTWARE OR THAT ANY ERRORS IN THE PROGRAM WILL BE
55 * CORRECTED. NO ORAL OR WRITTEN ADVICE PROVIDED BY ELECTRONIC ARTS OR
56 * ANY AUTHORIZED REPRESENTATIVE SHALL CREATE A WARRANTY. SOME
57 * JURISDICTIONS DO NOT ALLOW THE EXCLUSION OF OR LIMITATIONS ON IMPLIED
58 * WARRANTIES OR THE LIMITATIONS ON THE APPLICABLE STATUTORY RIGHTS OF A
59 * CONSUMER, SO SOME OR ALL OF THE ABOVE EXCLUSIONS AND LIMITATIONS MAY
67 unsigned char *History10
[HISTORIES
];
68 unsigned char *History120
[HISTORIES
];
69 int HistoryInitialized
= 0;
70 short Graph10Max
, Graph120Max
;
71 Tcl_HashTable GraphCmds
;
72 int GraphUpdateTime
= 100;
75 #define DEF_GRAPH_FONT "-Adobe-Helvetica-Bold-R-Normal-*-140-*"
76 #define DEF_GRAPH_BG_COLOR "#b0b0b0"
77 #define DEF_GRAPH_BG_MONO "#ffffff"
78 #define DEF_GRAPH_BORDER_WIDTH "0"
79 #define DEF_GRAPH_RELIEF "flat"
81 Tk_ConfigSpec GraphConfigSpecs
[] = {
82 {TK_CONFIG_FONT
, "-font", (char *) NULL
, (char *) NULL
,
83 DEF_GRAPH_FONT
, Tk_Offset(SimGraph
, fontPtr
), 0},
84 {TK_CONFIG_BORDER
, "-background", "background", "Background",
85 DEF_GRAPH_BG_COLOR
, Tk_Offset(SimGraph
, border
),
86 TK_CONFIG_COLOR_ONLY
},
87 {TK_CONFIG_BORDER
, "-background", "background", "Background",
88 DEF_GRAPH_BG_MONO
, Tk_Offset(SimGraph
, border
),
90 {TK_CONFIG_PIXELS
, "-borderwidth", "borderWidth", "BorderWidth",
91 DEF_GRAPH_BORDER_WIDTH
, Tk_Offset(SimGraph
, borderWidth
), 0},
92 {TK_CONFIG_RELIEF
, "-relief", "relief", "Relief",
93 DEF_GRAPH_RELIEF
, Tk_Offset(SimGraph
, relief
), 0},
94 {TK_CONFIG_END
, (char *) NULL
, (char *) NULL
, (char *) NULL
,
99 XDisplay
*FindXDisplay();
103 DisplaySimGraph(ClientData clientData
)
105 SimGraph
*graph
= (SimGraph
*) clientData
;
106 Tk_Window tkwin
= graph
->tkwin
;
110 graph
->flags
&= ~VIEW_REDRAW_PENDING
;
112 //fprintf(stderr, "DisplaySimGraph token %d\n", graph->draw_graph_token);
114 assert(graph
->draw_graph_token
!= 0);
116 if (graph
->draw_graph_token
!= 0) {
117 // Tk_DeleteTimerHandler(graph->draw_graph_token);
118 graph
->draw_graph_token
= 0;
121 if (graph
->visible
&& (tkwin
!= NULL
) && Tk_IsMapped(tkwin
)) {
122 DoUpdateGraph(graph
);
128 DestroySimGraph(ClientData clientData
)
130 SimGraph
*graph
= (SimGraph
*) clientData
;
136 EventuallyRedrawGraph(SimGraph
*graph
)
138 if (!(graph
->flags
& VIEW_REDRAW_PENDING
)) {
139 assert(graph
->draw_graph_token
== 0);
140 if (graph
->draw_graph_token
== 0) {
141 graph
->draw_graph_token
=
142 Tk_CreateTimerHandler(
146 graph
->flags
|= VIEW_REDRAW_PENDING
;
147 //fprintf(stderr, "EventuallyRedrawGraph token %d\n", graph->draw_graph_token);
154 SimGraphEventProc(ClientData clientData
, XEvent
*eventPtr
)
156 SimGraph
*graph
= (SimGraph
*) clientData
;
158 if ((eventPtr
->type
== Expose
) && (eventPtr
->xexpose
.count
== 0)) {
160 EventuallyRedrawGraph(graph
);
161 } else if (eventPtr
->type
== MapNotify
) {
163 } else if (eventPtr
->type
== UnmapNotify
) {
165 } else if (eventPtr
->type
== VisibilityNotify
) {
166 if (eventPtr
->xvisibility
.state
== VisibilityFullyObscured
)
170 } else if (eventPtr
->type
== ConfigureNotify
) {
172 eventPtr
->xconfigure
.width
,
173 eventPtr
->xconfigure
.height
);
174 EventuallyRedrawGraph(graph
);
175 } else if (eventPtr
->type
== DestroyNotify
) {
176 Tcl_DeleteCommand(graph
->interp
, Tk_PathName(graph
->tkwin
));
178 if (graph
->flags
& VIEW_REDRAW_PENDING
) {
179 //fprintf(stderr, "SimGraphEventProc Destroy token %d\n", graph->draw_graph_token);
180 assert(graph
->draw_graph_token
!= 0);
181 if (graph
->draw_graph_token
!= 0) {
182 Tk_DeleteTimerHandler(graph
->draw_graph_token
);
183 graph
->draw_graph_token
= 0;
185 graph
->flags
&= ~VIEW_REDRAW_PENDING
;
187 Tk_EventuallyFree((ClientData
) graph
, DestroySimGraph
);
192 int GraphCmdconfigure(GRAPH_ARGS
)
197 result
= Tk_ConfigureInfo(interp
, graph
->tkwin
, GraphConfigSpecs
,
198 (char *) graph
, (char *) NULL
, 0);
199 } else if (argc
== 3) {
200 result
= Tk_ConfigureInfo(interp
, graph
->tkwin
, GraphConfigSpecs
,
201 (char *) graph
, argv
[2], 0);
203 result
= ConfigureSimGraph(interp
, graph
, argc
-2, argv
+2,
204 TK_CONFIG_ARGV_ONLY
);
210 int GraphCmdposition(GRAPH_ARGS
)
214 if ((argc
!= 2) && (argc
!= 4)) {
218 if ((Tcl_GetInt(interp
, argv
[2], &graph
->w_x
) != TCL_OK
)
219 || (Tcl_GetInt(interp
, argv
[3], &graph
->w_y
) != TCL_OK
)) {
223 sprintf(interp
->result
, "%d %d", graph
->w_x
, graph
->w_y
);
228 int GraphCmdsize(GRAPH_ARGS
)
230 if ((argc
!= 2) && (argc
!= 4)) {
236 if (Tcl_GetInt(interp
, argv
[2], &w
) != TCL_OK
) {
239 if (Tcl_GetInt(interp
, argv
[3], &h
) != TCL_OK
) {
245 sprintf(interp
->result
, "%d %d", graph
->w_width
, graph
->w_height
);
250 int GraphCmdVisible(GRAPH_ARGS
)
254 if ((argc
!= 2) && (argc
!= 3)) {
255 Tcl_AppendResult(interp
, "wrong # args", (char *) NULL
);
260 if ((Tcl_GetInt(interp
, argv
[2], &visible
) != TCL_OK
) ||
261 (visible
< 0) || (visible
> 1)) {
262 Tcl_AppendResult(interp
, " bogus args", (char *) NULL
);
266 graph
->visible
= visible
;
269 sprintf(interp
->result
, "%d", graph
->visible
);
275 int GraphCmdRange(GRAPH_ARGS
)
279 if ((argc
!= 2) && (argc
!= 3)) {
280 Tcl_AppendResult(interp
, "wrong # args", (char *) NULL
);
285 if ((Tcl_GetInt(interp
, argv
[2], &range
) != TCL_OK
) ||
286 ((range
!= 10) && (range
!= 120))) {
287 Tcl_AppendResult(interp
, " bogus args", (char *) NULL
);
291 graph
->range
= range
;
295 sprintf(interp
->result
, "%d", graph
->range
);
301 int GraphCmdMask(GRAPH_ARGS
)
305 if ((argc
!= 2) && (argc
!= 3)) {
306 Tcl_AppendResult(interp
, "wrong # args", (char *) NULL
);
311 if ((Tcl_GetInt(interp
, argv
[2], &mask
) != TCL_OK
) ||
312 (mask
< 0) || (mask
> 63)) {
313 Tcl_AppendResult(interp
, " bogus args", (char *) NULL
);
321 sprintf(interp
->result
, "%d", graph
->mask
);
328 DoGraphCmd(CLIENT_ARGS
)
330 SimGraph
*graph
= (SimGraph
*) clientData
;
339 if (ent
= Tcl_FindHashEntry(&GraphCmds
, argv
[1])) {
340 cmd
= (int (*)())ent
->clientData
;
341 Tk_Preserve((ClientData
) graph
);
342 result
= cmd(graph
, interp
, argc
, argv
);
343 Tk_Release((ClientData
) graph
);
345 Tcl_AppendResult(interp
, "unknown command name: \"",
346 argv
[0], " ", argv
[1], "\".", (char *) NULL
);
354 GraphViewCmd(CLIENT_ARGS
)
357 Tk_Window tkwin
= (Tk_Window
) clientData
;
360 Tcl_AppendResult(interp
, "wrong # args: should be \"",
361 argv
[0], " pathName ?options?\"", (char *) NULL
);
365 tkwin
= Tk_CreateWindowFromPath(interp
, tkwin
,
366 argv
[1], (char *) NULL
);
371 graph
= (SimGraph
*)ckalloc(sizeof (SimGraph
));
373 graph
->tkwin
= tkwin
;
374 graph
->interp
= interp
;
377 Tk_SetClass(graph
->tkwin
, "GraphView");
378 Tk_CreateEventHandler(graph
->tkwin
,
379 VisibilityChangeMask
|
382 SimGraphEventProc
, (ClientData
) graph
);
383 Tcl_CreateCommand(interp
, Tk_PathName(graph
->tkwin
),
384 DoGraphCmd
, (ClientData
) graph
, (void (*)()) NULL
);
387 Tk_MakeWindowExist(graph->tkwin);
390 if (getenv("XSYNCHRONIZE") != NULL
) {
391 XSynchronize(Tk_Display(tkwin
), 1);
397 if (ConfigureSimGraph(interp
, graph
, argc
-2, argv
+2, 0) != TCL_OK
) {
398 /* XXX: destroy graph */
399 Tk_DestroyWindow(graph
->tkwin
);
403 interp
->result
= Tk_PathName(graph
->tkwin
);
409 ConfigureSimGraph(Tcl_Interp
*interp
, SimGraph
*graph
,
410 int argc
, char **argv
, int flags
)
412 if (Tk_ConfigureWidget(interp
, graph
->tkwin
, GraphConfigSpecs
,
413 argc
, argv
, (char *) graph
, flags
) != TCL_OK
) {
417 Tk_SetBackgroundFromBorder(graph
->tkwin
, graph
->border
);
419 EventuallyRedrawGraph(graph
);
427 "Residential", "Commercial", "Industrial",
428 "Cash Flow", "Crime", "Pollution"
431 unsigned char HistColor
[] = {
432 COLOR_LIGHTGREEN
, COLOR_DARKBLUE
, COLOR_YELLOW
,
433 COLOR_DARKGREEN
, COLOR_RED
, COLOR_OLIVE
441 Tcl_CreateCommand(tk_mainInterp
, "graphview", GraphViewCmd
,
442 (ClientData
)MainWindow
, (void (*)()) NULL
);
444 Tcl_InitHashTable(&GraphCmds
, TCL_STRING_KEYS
);
446 #define GRAPH_CMD(name) HASHED_CMD(Graph, name)
448 GRAPH_CMD(configure
);
459 drawMonth(short *hist
, unsigned char *s
, float scale
)
464 for (x
= 0; x
< 120; x
++) {
465 val
= hist
[x
] * scale
;
466 if (val
< 0) val
= 0;
467 if (val
> 255) val
= 255;
479 if (ResHisMax
> AllMax
) AllMax
= ResHisMax
;
480 if (ComHisMax
> AllMax
) AllMax
= ComHisMax
;
481 if (IndHisMax
> AllMax
) AllMax
= IndHisMax
;
482 if (AllMax
<= 128) AllMax
= 0;
485 scaleValue
= 128.0 / AllMax
;
490 // scaleValue = 0.5; // XXX
492 drawMonth(ResHis
, History10
[RES_HIST
], scaleValue
);
493 drawMonth(ComHis
, History10
[COM_HIST
], scaleValue
);
494 drawMonth(IndHis
, History10
[IND_HIST
], scaleValue
);
495 drawMonth(MoneyHis
, History10
[MONEY_HIST
], 1.0);
496 drawMonth(CrimeHis
, History10
[CRIME_HIST
], 1.0);
497 drawMonth(PollutionHis
, History10
[POLLUTION_HIST
], 1.0);
500 if (Res2HisMax
> AllMax
) AllMax
= Res2HisMax
;
501 if (Com2HisMax
> AllMax
) AllMax
= Com2HisMax
;
502 if (Ind2HisMax
> AllMax
) AllMax
= Ind2HisMax
;
503 if (AllMax
<= 128) AllMax
= 0;
506 scaleValue
= 128.0 / AllMax
;
511 // scaleValue = 0.5; // XXX
513 drawMonth(ResHis
+ 120, History120
[RES_HIST
], scaleValue
);
514 drawMonth(ComHis
+ 120, History120
[COM_HIST
], scaleValue
);
515 drawMonth(IndHis
+ 120, History120
[IND_HIST
], scaleValue
);
516 drawMonth(MoneyHis
+ 120, History120
[MONEY_HIST
], 1.0);
517 drawMonth(CrimeHis
+ 120, History120
[CRIME_HIST
], 1.0);
518 drawMonth(PollutionHis
+ 120, History120
[POLLUTION_HIST
], 1.0);
541 for (graph
= sim
->graph
; graph
!= NULL
; graph
= graph
->next
) {
542 EventuallyRedrawGraph(graph
);
555 for (graph
= sim
->graph
; graph
!= NULL
; graph
= graph
->next
) {
557 graph
->mask
= ALL_HISTORIES
;
560 if (!HistoryInitialized
) {
561 HistoryInitialized
= 1;
562 for (i
= 0; i
< HISTORIES
; i
++) {
563 History10
[i
] = (unsigned char *)ckalloc(120);
564 History120
[i
] = (unsigned char *)ckalloc(120);
570 /* comefrom: InitWillStuff */
578 for (x
= 118; x
>= 0; x
--) {
579 if (ResHis
[x
] > ResHisMax
) ResHisMax
= ResHis
[x
];
580 if (ComHis
[x
] > ComHisMax
) ComHisMax
= ComHis
[x
];
581 if (IndHis
[x
] > IndHisMax
) IndHisMax
= IndHis
[x
];
582 if (ResHis
[x
] < 0) ResHis
[x
] = 0;
583 if (ComHis
[x
] < 0) ComHis
[x
] = 0;
584 if (IndHis
[x
] < 0) IndHis
[x
] = 0;
586 Graph10Max
= ResHisMax
;
587 if (ComHisMax
> Graph10Max
) Graph10Max
= ComHisMax
;
588 if (IndHisMax
> Graph10Max
) Graph10Max
= IndHisMax
;
593 for (x
= 238; x
>= 120; x
--) {
594 if (ResHis
[x
] > Res2HisMax
) Res2HisMax
= ResHis
[x
];
595 if (ComHis
[x
] > Com2HisMax
) Com2HisMax
= ComHis
[x
];
596 if (IndHis
[x
] > Ind2HisMax
) Ind2HisMax
= IndHis
[x
];
597 if (ResHis
[x
] < 0) ResHis
[x
] = 0;
598 if (ComHis
[x
] < 0) ComHis
[x
] = 0;
599 if (IndHis
[x
] < 0) IndHis
[x
] = 0;
601 Graph120Max
= Res2HisMax
;
602 if (Com2HisMax
> Graph120Max
) Graph120Max
= Com2HisMax
;
603 if (Ind2HisMax
> Graph120Max
) Graph120Max
= Ind2HisMax
;
607 InitNewGraph(SimGraph
*graph
)
614 graph
->mask
= ALL_HISTORIES
;
616 /* This stuff was initialized in our caller (GraphCmd) */
617 /* graph->tkwin = NULL; */
618 /* graph->interp = NULL; */
619 /* graph->flags = 0; */
623 graph
->w_x
= graph
->w_y
= 0;
624 graph
->w_width
= graph
->w_height
= 0;
625 graph
->pixmap
= None
;
626 graph
->pixels
= NULL
;
627 graph
->fontPtr
= NULL
;
628 graph
->border
= NULL
;
629 graph
->borderWidth
= 0;
630 graph
->relief
= TK_RELIEF_FLAT
;
631 graph
->draw_graph_token
= 0;
632 //fprintf(stderr, "InitNewGraph token %d\n", graph->draw_graph_token);
634 graph
->x
= FindXDisplay(graph
->tkwin
);
635 IncRefDisplay(graph
->x
);
637 graph
->pixels
= graph
->x
->pixels
;
638 graph
->fontPtr
= NULL
;
640 DoResizeGraph(graph
, 16, 16);
644 DestroyGraph(SimGraph
*graph
)
648 for (gp
= &sim
->graph
;
650 gp
= &((*gp
)->next
)) {
651 if ((*gp
) == graph
) {
658 if (graph
->pixmap
!= None
) {
659 XFreePixmap(graph
->x
->dpy
, graph
->pixmap
);
660 graph
->pixmap
= None
;
663 DecRefDisplay(graph
->x
);
665 ckfree((char *) graph
);
669 DoResizeGraph(SimGraph
*graph
, int w
, int h
)
673 graph
->w_width
= w
; graph
->w_height
= h
;
675 if (graph
->pixmap
!= None
) {
676 XFreePixmap(graph
->x
->dpy
, graph
->pixmap
);
677 graph
->pixmap
= None
;
679 graph
->pixmap
= XCreatePixmap(graph
->x
->dpy
, graph
->x
->root
,
680 w
, h
, graph
->x
->depth
);
681 if (graph
->pixmap
== None
) {
683 "Sorry, Micropolis can't create a pixmap on X display \"%s\".\n",
685 sim_exit(1); // Just sets tkMustExit and ExitReturn
691 DoNewGraph(SimGraph
*graph
)
693 sim
->graphs
++; graph
->next
= sim
->graph
; sim
->graph
= graph
;
701 DoUpdateGraph(SimGraph
*graph
)
707 unsigned char **hist
;
708 int w
, h
, mask
, i
, j
, x
, y
;
710 int year
= (CityTime
/ 48) + StartingYear
;
711 int month
= (CityTime
/ 4) % 12;
712 int do_top_labels
= 0;
713 int do_right_labels
= 0;
714 int top_label_height
= 30;
715 int right_label_width
= 65;
719 if (!graph
->visible
) {
723 if (graph
->range
== 10) {
737 XSetFont(graph
->x
->dpy
, graph
->x
->gc
, graph
->fontPtr
->fid
);
738 XSetLineAttributes(dpy
, gc
, 3, LineSolid
, CapButt
, JoinBevel
);
739 if (graph
->x
->color
) {
740 XSetForeground(dpy
, gc
, pix
[COLOR_LIGHTGRAY
]);
742 XSetForeground(dpy
, gc
, pix
[COLOR_WHITE
]);
744 XFillRectangle(dpy
, pm
, gc
, 0, 0, w
, h
);
746 tx
= BORDER
; ty
= BORDER
;
748 if ((w
-= (2 * BORDER
)) < 1) w
= 1;
749 if ((h
-= (2 * BORDER
)) < 1) h
= 1;
751 if (w
> (4 * right_label_width
)) {
752 w
-= right_label_width
;
756 if (do_right_labels
&&
757 (h
> (3 * top_label_height
))) {
758 ty
+= top_label_height
;
759 h
-= top_label_height
;
763 sx
= ((float)w
) / 120.0; sy
= ((float)h
) / 256.0;
766 for (i
= 0; i
< HISTORIES
; i
++, mask
>>= 1, hist
++) {
768 int fg
= COLOR_WHITE
;
769 int bg
= COLOR_BLACK
;
770 Pixmap stipple
= None
;
772 for (j
= 0; j
< 120; j
++) {
774 y
= ty
+ ((int)(h
- (((float)(*hist
)[j
]) * sy
)));
775 points
[j
].x
= x
; points
[j
].y
= y
;
778 points
[j
].x
= x
; points
[j
].y
= y
;
780 if (graph
->x
->color
) {
781 XSetForeground(dpy
, gc
, pix
[HistColor
[i
]]);
785 stipple
= graph
->x
->gray50_stipple
;
788 stipple
= graph
->x
->gray25_stipple
;
791 stipple
= graph
->x
->gray75_stipple
;
797 stipple
= graph
->x
->horiz_stipple
;
800 stipple
= graph
->x
->vert_stipple
;
803 if (stipple
!= None
) {
804 XSetStipple(graph
->x
->dpy
, gc
, stipple
);
805 XSetTSOrigin(graph
->x
->dpy
, gc
, 0, 0);
806 XSetForeground(graph
->x
->dpy
, gc
, pix
[fg
]);
807 XSetBackground(graph
->x
->dpy
, gc
, pix
[bg
]);
808 XSetFillStyle(graph
->x
->dpy
, gc
, FillOpaqueStippled
);
810 XSetForeground(graph
->x
->dpy
, gc
, pix
[fg
]);
814 XDrawLines(dpy
, pm
, gc
, points
, 121, CoordModeOrigin
);
816 if (!graph
->x
->color
&& (stipple
!= None
)) {
817 XSetFillStyle(graph
->x
->dpy
, gc
, FillSolid
);
820 if (do_right_labels
) {
821 if (graph
->x
->color
) {
822 XSetForeground(dpy
, gc
, pix
[HistColor
[i
]]);
823 XDrawString(graph
->x
->dpy
, pm
, graph
->x
->gc
,
825 HistName
[i
], strlen(HistName
[i
]));
826 XDrawString(graph
->x
->dpy
, pm
, graph
->x
->gc
,
828 HistName
[i
], strlen(HistName
[i
]));
830 XSetForeground(dpy
, gc
, pix
[COLOR_BLACK
]);
831 XDrawString(graph
->x
->dpy
, pm
, graph
->x
->gc
,
833 HistName
[i
], strlen(HistName
[i
]));
835 XSetForeground(dpy
, gc
, pix
[COLOR_BLACK
]);
836 XDrawString(graph
->x
->dpy
, pm
, graph
->x
->gc
,
838 HistName
[i
], strlen(HistName
[i
]));
844 XSetLineAttributes(dpy
, gc
, 1, LineSolid
, CapButt
, JoinMiter
);
846 XSetForeground(dpy
, gc
, pix
[COLOR_BLACK
]);
847 XDrawLine(dpy
, pm
, gc
, tx
, ty
- 1, tx
+ w
, ty
- 1);
848 XDrawLine(dpy
, pm
, gc
, tx
, ty
+ h
, tx
+ w
, ty
+ h
);
850 if (graph
->range
== 10) {
851 for (x
= 120 - month
; x
>= 0; x
-= 12) {
854 XDrawLine(dpy
, pm
, gc
, xx
, ty
- 1, xx
, ty
+ h
);
858 sprintf(buf
, "%d", year
--);
859 xx
= tx
+ (x
* sx
) + 2;
860 yy
= ty
- ((year
& 1) ? 4 : 20);
861 XDrawString(graph
->x
->dpy
, pm
, graph
->x
->gc
,
862 xx
, yy
, buf
, strlen(buf
));
869 past
= 10 * (year
% 10);
872 for (x
= 1200 - past
; x
>= 0; x
-= 120) {
875 XDrawLine(dpy
, pm
, gc
, xx
, ty
- 1, xx
, ty
+ h
);
879 sprintf(buf
, "%d0", year
--);
881 xx
= tx
+ (x
* sx
) + 2;
882 yy
= ty
- ((year
& 1) ? 4 : 20);
883 XDrawString(graph
->x
->dpy
, pm
, graph
->x
->gc
,
884 xx
, yy
, buf
, strlen(buf
));
889 XCopyArea(graph
->x
->dpy
, graph
->pixmap
,
890 Tk_WindowId(graph
->tkwin
), graph
->x
->gc
,
891 0, 0, graph
->w_width
, graph
->w_height
, 0, 0);