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;
74 void DoUpdateGraph(SimGraph
*graph
);
75 void DoNewGraph(SimGraph
*graph
);
76 void DoResizeGraph(SimGraph
*graph
, int w
, int h
);
77 void InitNewGraph(SimGraph
*graph
);
80 #define DEF_GRAPH_FONT "-Adobe-Helvetica-Bold-R-Normal-*-140-*"
81 #define DEF_GRAPH_BG_COLOR "#b0b0b0"
82 #define DEF_GRAPH_BG_MONO "#ffffff"
83 #define DEF_GRAPH_BORDER_WIDTH "0"
84 #define DEF_GRAPH_RELIEF "flat"
86 Tk_ConfigSpec GraphConfigSpecs
[] = {
87 {TK_CONFIG_FONT
, "-font", (char *) NULL
, (char *) NULL
,
88 DEF_GRAPH_FONT
, Tk_Offset(SimGraph
, fontPtr
), 0},
89 {TK_CONFIG_BORDER
, "-background", "background", "Background",
90 DEF_GRAPH_BG_COLOR
, Tk_Offset(SimGraph
, border
),
91 TK_CONFIG_COLOR_ONLY
},
92 {TK_CONFIG_BORDER
, "-background", "background", "Background",
93 DEF_GRAPH_BG_MONO
, Tk_Offset(SimGraph
, border
),
95 {TK_CONFIG_PIXELS
, "-borderwidth", "borderWidth", "BorderWidth",
96 DEF_GRAPH_BORDER_WIDTH
, Tk_Offset(SimGraph
, borderWidth
), 0},
97 {TK_CONFIG_RELIEF
, "-relief", "relief", "Relief",
98 DEF_GRAPH_RELIEF
, Tk_Offset(SimGraph
, relief
), 0},
99 {TK_CONFIG_END
, (char *) NULL
, (char *) NULL
, (char *) NULL
,
104 XDisplay
*FindXDisplay();
108 DisplaySimGraph(ClientData clientData
)
110 SimGraph
*graph
= (SimGraph
*) clientData
;
111 Tk_Window tkwin
= graph
->tkwin
;
113 graph
->flags
&= ~VIEW_REDRAW_PENDING
;
115 //fprintf(stderr, "DisplaySimGraph token %d\n", graph->draw_graph_token);
117 assert(graph
->draw_graph_token
!= 0);
119 if (graph
->draw_graph_token
!= 0) {
120 // Tk_DeleteTimerHandler(graph->draw_graph_token);
121 graph
->draw_graph_token
= 0;
124 if (graph
->visible
&& (tkwin
!= NULL
) && Tk_IsMapped(tkwin
)) {
125 DoUpdateGraph(graph
);
131 DestroySimGraph(ClientData clientData
)
133 SimGraph
*graph
= (SimGraph
*) clientData
;
140 EventuallyRedrawGraph(SimGraph
*graph
)
142 if (!(graph
->flags
& VIEW_REDRAW_PENDING
)) {
143 assert(graph
->draw_graph_token
== 0);
144 if (graph
->draw_graph_token
== 0) {
145 graph
->draw_graph_token
=
146 Tk_CreateTimerHandler(
150 graph
->flags
|= VIEW_REDRAW_PENDING
;
151 //fprintf(stderr, "EventuallyRedrawGraph token %d\n", graph->draw_graph_token);
158 SimGraphEventProc(ClientData clientData
, XEvent
*eventPtr
)
160 SimGraph
*graph
= (SimGraph
*) clientData
;
162 if ((eventPtr
->type
== Expose
) && (eventPtr
->xexpose
.count
== 0)) {
164 EventuallyRedrawGraph(graph
);
165 } else if (eventPtr
->type
== MapNotify
) {
167 } else if (eventPtr
->type
== UnmapNotify
) {
169 } else if (eventPtr
->type
== VisibilityNotify
) {
170 if (eventPtr
->xvisibility
.state
== VisibilityFullyObscured
)
174 } else if (eventPtr
->type
== ConfigureNotify
) {
176 eventPtr
->xconfigure
.width
,
177 eventPtr
->xconfigure
.height
);
178 EventuallyRedrawGraph(graph
);
179 } else if (eventPtr
->type
== DestroyNotify
) {
180 Tcl_DeleteCommand(graph
->interp
, Tk_PathName(graph
->tkwin
));
182 if (graph
->flags
& VIEW_REDRAW_PENDING
) {
183 //fprintf(stderr, "SimGraphEventProc Destroy token %d\n", graph->draw_graph_token);
184 assert(graph
->draw_graph_token
!= 0);
185 if (graph
->draw_graph_token
!= 0) {
186 Tk_DeleteTimerHandler(graph
->draw_graph_token
);
187 graph
->draw_graph_token
= 0;
189 graph
->flags
&= ~VIEW_REDRAW_PENDING
;
191 Tk_EventuallyFree((ClientData
) graph
, DestroySimGraph
);
196 int GraphCmdconfigure(GRAPH_ARGS
)
201 result
= Tk_ConfigureInfo(interp
, graph
->tkwin
, GraphConfigSpecs
,
202 (char *) graph
, (char *) NULL
, 0);
203 } else if (argc
== 3) {
204 result
= Tk_ConfigureInfo(interp
, graph
->tkwin
, GraphConfigSpecs
,
205 (char *) graph
, argv
[2], 0);
207 result
= ConfigureSimGraph(interp
, graph
, argc
-2, argv
+2,
208 TK_CONFIG_ARGV_ONLY
);
214 int GraphCmdposition(GRAPH_ARGS
)
216 if ((argc
!= 2) && (argc
!= 4)) {
220 if ((Tcl_GetInt(interp
, argv
[2], &graph
->w_x
) != TCL_OK
)
221 || (Tcl_GetInt(interp
, argv
[3], &graph
->w_y
) != TCL_OK
)) {
225 sprintf(interp
->result
, "%d %d", graph
->w_x
, graph
->w_y
);
230 int GraphCmdsize(GRAPH_ARGS
)
232 if ((argc
!= 2) && (argc
!= 4)) {
238 if (Tcl_GetInt(interp
, argv
[2], &w
) != TCL_OK
) {
241 if (Tcl_GetInt(interp
, argv
[3], &h
) != TCL_OK
) {
247 sprintf(interp
->result
, "%d %d", graph
->w_width
, graph
->w_height
);
252 int GraphCmdVisible(GRAPH_ARGS
)
256 if ((argc
!= 2) && (argc
!= 3)) {
257 Tcl_AppendResult(interp
, "wrong # args", (char *) NULL
);
262 if ((Tcl_GetInt(interp
, argv
[2], &visible
) != TCL_OK
) ||
263 (visible
< 0) || (visible
> 1)) {
264 Tcl_AppendResult(interp
, " bogus args", (char *) NULL
);
268 graph
->visible
= visible
;
271 sprintf(interp
->result
, "%d", graph
->visible
);
277 int GraphCmdRange(GRAPH_ARGS
)
281 if ((argc
!= 2) && (argc
!= 3)) {
282 Tcl_AppendResult(interp
, "wrong # args", (char *) NULL
);
287 if ((Tcl_GetInt(interp
, argv
[2], &range
) != TCL_OK
) ||
288 ((range
!= 10) && (range
!= 120))) {
289 Tcl_AppendResult(interp
, " bogus args", (char *) NULL
);
293 graph
->range
= range
;
297 sprintf(interp
->result
, "%d", graph
->range
);
303 int GraphCmdMask(GRAPH_ARGS
)
307 if ((argc
!= 2) && (argc
!= 3)) {
308 Tcl_AppendResult(interp
, "wrong # args", (char *) NULL
);
313 if ((Tcl_GetInt(interp
, argv
[2], &mask
) != TCL_OK
) ||
314 (mask
< 0) || (mask
> 63)) {
315 Tcl_AppendResult(interp
, " bogus args", (char *) NULL
);
323 sprintf(interp
->result
, "%d", graph
->mask
);
330 DoGraphCmd(CLIENT_ARGS
)
332 SimGraph
*graph
= (SimGraph
*) clientData
;
341 if ((ent
= Tcl_FindHashEntry(&GraphCmds
, argv
[1]))) {
342 cmd
= (int (*)())ent
->clientData
;
343 Tk_Preserve((ClientData
) graph
);
344 result
= cmd(graph
, interp
, argc
, argv
);
345 Tk_Release((ClientData
) graph
);
347 Tcl_AppendResult(interp
, "unknown command name: \"",
348 argv
[0], " ", argv
[1], "\".", (char *) NULL
);
356 GraphViewCmd(CLIENT_ARGS
)
359 Tk_Window tkwin
= (Tk_Window
) clientData
;
362 Tcl_AppendResult(interp
, "wrong # args: should be \"",
363 argv
[0], " pathName ?options?\"", (char *) NULL
);
367 tkwin
= Tk_CreateWindowFromPath(interp
, tkwin
,
368 argv
[1], (char *) NULL
);
373 graph
= (SimGraph
*)ckalloc(sizeof (SimGraph
));
375 graph
->tkwin
= tkwin
;
376 graph
->interp
= interp
;
379 Tk_SetClass(graph
->tkwin
, "GraphView");
380 Tk_CreateEventHandler(graph
->tkwin
,
381 VisibilityChangeMask
|
384 SimGraphEventProc
, (ClientData
) graph
);
385 Tcl_CreateCommand(interp
, Tk_PathName(graph
->tkwin
),
386 DoGraphCmd
, (ClientData
) graph
, (void (*)()) NULL
);
389 Tk_MakeWindowExist(graph->tkwin);
392 if (getenv("XSYNCHRONIZE") != NULL
) {
393 XSynchronize(Tk_Display(tkwin
), 1);
399 if (ConfigureSimGraph(interp
, graph
, argc
-2, argv
+2, 0) != TCL_OK
) {
400 /* XXX: destroy graph */
401 Tk_DestroyWindow(graph
->tkwin
);
405 interp
->result
= Tk_PathName(graph
->tkwin
);
411 ConfigureSimGraph(Tcl_Interp
*interp
, SimGraph
*graph
,
412 int argc
, char **argv
, int flags
)
414 if (Tk_ConfigureWidget(interp
, graph
->tkwin
, GraphConfigSpecs
,
415 argc
, argv
, (char *) graph
, flags
) != TCL_OK
) {
419 Tk_SetBackgroundFromBorder(graph
->tkwin
, graph
->border
);
421 EventuallyRedrawGraph(graph
);
429 "Residential", "Commercial", "Industrial",
430 "Cash Flow", "Crime", "Pollution"
433 unsigned char HistColor
[] = {
434 COLOR_LIGHTGREEN
, COLOR_DARKBLUE
, COLOR_YELLOW
,
435 COLOR_DARKGREEN
, COLOR_RED
, COLOR_OLIVE
440 graph_command_init(void)
442 Tcl_CreateCommand(tk_mainInterp
, "graphview", GraphViewCmd
,
443 (ClientData
)MainWindow
, (void (*)()) NULL
);
445 Tcl_InitHashTable(&GraphCmds
, TCL_STRING_KEYS
);
447 #define GRAPH_CMD(name) HASHED_CMD(Graph, name)
449 GRAPH_CMD(configure
);
460 drawMonth(short *hist
, unsigned char *s
, float scale
)
465 for (x
= 0; x
< 120; x
++) {
466 val
= hist
[x
] * scale
;
467 if (val
< 0) val
= 0;
468 if (val
> 255) val
= 255;
480 if (ResHisMax
> AllMax
) AllMax
= ResHisMax
;
481 if (ComHisMax
> AllMax
) AllMax
= ComHisMax
;
482 if (IndHisMax
> AllMax
) AllMax
= IndHisMax
;
483 if (AllMax
<= 128) AllMax
= 0;
486 scaleValue
= 128.0 / AllMax
;
491 // scaleValue = 0.5; // XXX
493 drawMonth(ResHis
, History10
[RES_HIST
], scaleValue
);
494 drawMonth(ComHis
, History10
[COM_HIST
], scaleValue
);
495 drawMonth(IndHis
, History10
[IND_HIST
], scaleValue
);
496 drawMonth(MoneyHis
, History10
[MONEY_HIST
], 1.0);
497 drawMonth(CrimeHis
, History10
[CRIME_HIST
], 1.0);
498 drawMonth(PollutionHis
, History10
[POLLUTION_HIST
], 1.0);
501 if (Res2HisMax
> AllMax
) AllMax
= Res2HisMax
;
502 if (Com2HisMax
> AllMax
) AllMax
= Com2HisMax
;
503 if (Ind2HisMax
> AllMax
) AllMax
= Ind2HisMax
;
504 if (AllMax
<= 128) AllMax
= 0;
507 scaleValue
= 128.0 / AllMax
;
512 // scaleValue = 0.5; // XXX
514 drawMonth(ResHis
+ 120, History120
[RES_HIST
], scaleValue
);
515 drawMonth(ComHis
+ 120, History120
[COM_HIST
], scaleValue
);
516 drawMonth(IndHis
+ 120, History120
[IND_HIST
], scaleValue
);
517 drawMonth(MoneyHis
+ 120, History120
[MONEY_HIST
], 1.0);
518 drawMonth(CrimeHis
+ 120, History120
[CRIME_HIST
], 1.0);
519 drawMonth(PollutionHis
+ 120, History120
[POLLUTION_HIST
], 1.0);
542 for (graph
= sim
->graph
; graph
!= NULL
; graph
= graph
->next
) {
543 EventuallyRedrawGraph(graph
);
556 for (graph
= sim
->graph
; graph
!= NULL
; graph
= graph
->next
) {
558 graph
->mask
= ALL_HISTORIES
;
561 if (!HistoryInitialized
) {
562 HistoryInitialized
= 1;
563 for (i
= 0; i
< HISTORIES
; i
++) {
564 History10
[i
] = (unsigned char *)ckalloc(120);
565 History120
[i
] = (unsigned char *)ckalloc(120);
571 /* comefrom: InitWillStuff */
580 for (x
= 118; x
>= 0; x
--) {
581 if (ResHis
[x
] > ResHisMax
) ResHisMax
= ResHis
[x
];
582 if (ComHis
[x
] > ComHisMax
) ComHisMax
= ComHis
[x
];
583 if (IndHis
[x
] > IndHisMax
) IndHisMax
= IndHis
[x
];
584 if (ResHis
[x
] < 0) ResHis
[x
] = 0;
585 if (ComHis
[x
] < 0) ComHis
[x
] = 0;
586 if (IndHis
[x
] < 0) IndHis
[x
] = 0;
588 Graph10Max
= ResHisMax
;
589 if (ComHisMax
> Graph10Max
) Graph10Max
= ComHisMax
;
590 if (IndHisMax
> Graph10Max
) Graph10Max
= IndHisMax
;
595 for (x
= 238; x
>= 120; x
--) {
596 if (ResHis
[x
] > Res2HisMax
) Res2HisMax
= ResHis
[x
];
597 if (ComHis
[x
] > Com2HisMax
) Com2HisMax
= ComHis
[x
];
598 if (IndHis
[x
] > Ind2HisMax
) Ind2HisMax
= IndHis
[x
];
599 if (ResHis
[x
] < 0) ResHis
[x
] = 0;
600 if (ComHis
[x
] < 0) ComHis
[x
] = 0;
601 if (IndHis
[x
] < 0) IndHis
[x
] = 0;
603 Graph120Max
= Res2HisMax
;
604 if (Com2HisMax
> Graph120Max
) Graph120Max
= Com2HisMax
;
605 if (Ind2HisMax
> Graph120Max
) Graph120Max
= Ind2HisMax
;
610 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);
645 DestroyGraph(SimGraph
*graph
)
649 for (gp
= &sim
->graph
;
651 gp
= &((*gp
)->next
)) {
652 if ((*gp
) == graph
) {
659 if (graph
->pixmap
!= None
) {
660 XFreePixmap(graph
->x
->dpy
, graph
->pixmap
);
661 graph
->pixmap
= None
;
664 DecRefDisplay(graph
->x
);
666 ckfree((char *) graph
);
671 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
692 DoNewGraph(SimGraph
*graph
)
694 sim
->graphs
++; graph
->next
= sim
->graph
; sim
->graph
= graph
;
703 DoUpdateGraph(SimGraph
*graph
)
709 unsigned char **hist
;
710 int w
, h
, mask
, i
, j
, x
, y
;
712 int year
= (CityTime
/ 48) + StartingYear
;
713 int month
= (CityTime
/ 4) % 12;
714 int do_top_labels
= 0;
715 int do_right_labels
= 0;
716 int top_label_height
= 30;
717 int right_label_width
= 65;
721 if (!graph
->visible
) {
725 if (graph
->range
== 10) {
739 XSetFont(graph
->x
->dpy
, graph
->x
->gc
, graph
->fontPtr
->fid
);
740 XSetLineAttributes(dpy
, gc
, 3, LineSolid
, CapButt
, JoinBevel
);
741 if (graph
->x
->color
) {
742 XSetForeground(dpy
, gc
, pix
[COLOR_LIGHTGRAY
]);
744 XSetForeground(dpy
, gc
, pix
[COLOR_WHITE
]);
746 XFillRectangle(dpy
, pm
, gc
, 0, 0, w
, h
);
748 tx
= BORDER
; ty
= BORDER
;
750 if ((w
-= (2 * BORDER
)) < 1) w
= 1;
751 if ((h
-= (2 * BORDER
)) < 1) h
= 1;
753 if (w
> (4 * right_label_width
)) {
754 w
-= right_label_width
;
758 if (do_right_labels
&&
759 (h
> (3 * top_label_height
))) {
760 ty
+= top_label_height
;
761 h
-= top_label_height
;
765 sx
= ((float)w
) / 120.0; sy
= ((float)h
) / 256.0;
768 for (i
= 0; i
< HISTORIES
; i
++, mask
>>= 1, hist
++) {
770 int fg
= COLOR_WHITE
;
771 int bg
= COLOR_BLACK
;
772 Pixmap stipple
= None
;
774 for (j
= 0; j
< 120; j
++) {
776 y
= ty
+ ((int)(h
- (((float)(*hist
)[j
]) * sy
)));
777 points
[j
].x
= x
; points
[j
].y
= y
;
780 points
[j
].x
= x
; points
[j
].y
= y
;
782 if (graph
->x
->color
) {
783 XSetForeground(dpy
, gc
, pix
[HistColor
[i
]]);
787 stipple
= graph
->x
->gray50_stipple
;
790 stipple
= graph
->x
->gray25_stipple
;
793 stipple
= graph
->x
->gray75_stipple
;
799 stipple
= graph
->x
->horiz_stipple
;
802 stipple
= graph
->x
->vert_stipple
;
805 if (stipple
!= None
) {
806 XSetStipple(graph
->x
->dpy
, gc
, stipple
);
807 XSetTSOrigin(graph
->x
->dpy
, gc
, 0, 0);
808 XSetForeground(graph
->x
->dpy
, gc
, pix
[fg
]);
809 XSetBackground(graph
->x
->dpy
, gc
, pix
[bg
]);
810 XSetFillStyle(graph
->x
->dpy
, gc
, FillOpaqueStippled
);
812 XSetForeground(graph
->x
->dpy
, gc
, pix
[fg
]);
816 XDrawLines(dpy
, pm
, gc
, points
, 121, CoordModeOrigin
);
818 if (!graph
->x
->color
&& (stipple
!= None
)) {
819 XSetFillStyle(graph
->x
->dpy
, gc
, FillSolid
);
822 if (do_right_labels
) {
823 if (graph
->x
->color
) {
824 XSetForeground(dpy
, gc
, pix
[HistColor
[i
]]);
825 XDrawString(graph
->x
->dpy
, pm
, graph
->x
->gc
,
827 HistName
[i
], strlen(HistName
[i
]));
828 XDrawString(graph
->x
->dpy
, pm
, graph
->x
->gc
,
830 HistName
[i
], strlen(HistName
[i
]));
832 XSetForeground(dpy
, gc
, pix
[COLOR_BLACK
]);
833 XDrawString(graph
->x
->dpy
, pm
, graph
->x
->gc
,
835 HistName
[i
], strlen(HistName
[i
]));
837 XSetForeground(dpy
, gc
, pix
[COLOR_BLACK
]);
838 XDrawString(graph
->x
->dpy
, pm
, graph
->x
->gc
,
840 HistName
[i
], strlen(HistName
[i
]));
846 XSetLineAttributes(dpy
, gc
, 1, LineSolid
, CapButt
, JoinMiter
);
848 XSetForeground(dpy
, gc
, pix
[COLOR_BLACK
]);
849 XDrawLine(dpy
, pm
, gc
, tx
, ty
- 1, tx
+ w
, ty
- 1);
850 XDrawLine(dpy
, pm
, gc
, tx
, ty
+ h
, tx
+ w
, ty
+ h
);
852 if (graph
->range
== 10) {
853 for (x
= 120 - month
; x
>= 0; x
-= 12) {
856 XDrawLine(dpy
, pm
, gc
, xx
, ty
- 1, xx
, ty
+ h
);
860 sprintf(buf
, "%d", year
--);
861 xx
= tx
+ (x
* sx
) + 2;
862 yy
= ty
- ((year
& 1) ? 4 : 20);
863 XDrawString(graph
->x
->dpy
, pm
, graph
->x
->gc
,
864 xx
, yy
, buf
, strlen(buf
));
871 past
= 10 * (year
% 10);
874 for (x
= 1200 - past
; x
>= 0; x
-= 120) {
877 XDrawLine(dpy
, pm
, gc
, xx
, ty
- 1, xx
, ty
+ h
);
881 sprintf(buf
, "%d0", year
--);
883 xx
= tx
+ (x
* sx
) + 2;
884 yy
= ty
- ((year
& 1) ? 4 : 20);
885 XDrawString(graph
->x
->dpy
, pm
, graph
->x
->gc
,
886 xx
, yy
, buf
, strlen(buf
));
891 XCopyArea(graph
->x
->dpy
, graph
->pixmap
,
892 Tk_WindowId(graph
->tkwin
), graph
->x
->gc
,
893 0, 0, graph
->w_width
, graph
->w_height
, 0, 0);