tachometer.c

来自「gpsd, a popular GPS daemon.」· C语言 代码 · 共 582 行 · 第 1/2 页

C
582
字号
/* $Id: Tachometer.c 4427 2007-10-16 13:40:03Z esr $ *//* * Tachometer Widget Implementation * * Author: Kazuhiko Shutoh, 1989. * Revised by Shinji Sumimoto, 1989/9 (xtachos) * Modifications : ilham@mit.edu   (July 10 '90) * Cleaned up and simplified by Eric S. Raymond, December 2004. */#include <sys/types.h>#include <X11/IntrinsicP.h>#include <X11/StringDefs.h>#include <TachometerP.h>#include <math.h>#include "gpsd_config.h"	/* must define UNUSED */#define D2R  0.0174532925199432957692369076848861271 /* radians = pi/180 *//**************************************************************** * * Full class record constant * ****************************************************************/typedef struct {		unsigned char	digit[7];		} DigitRec;typedef struct {		int	nofline;		XPoint	point_list[5];		} StringRec;/*@ +charint @*//*	Number character database - like an LED */static DigitRec num_segment[] = {    {{1,1,1,1,1,1,0}},    {{0,1,1,0,0,0,0}},    {{1,1,0,1,1,0,1}},    {{1,1,1,1,0,0,1}},    {{0,1,1,0,0,1,1}},    {{1,0,1,1,0,1,1}},    {{1,0,1,1,1,1,1}},    {{1,1,1,0,0,0,0}},    {{1,1,1,1,1,1,1}},    {{1,1,1,1,0,1,1}}};static XSegment	offset[] = {		{-10,-10, 10,-10},		{ 10,-10, 10,  0},		{ 10,  0, 10, 10},		{ 10, 10,-10, 10},		{-10, 10,-10,  0},		{-10,  0,-10,-10},		{-10,  0, 10,  0}};/*@ -initallelements @*//*	" X 10 %" character database	*/static StringRec	char_data[] = {		{ 2,				/* "X" */			{{-17, -5},			  	{-7, 5}}},		{ 2,			{{-7, -5},			{-17, 5}}},		{ 2,				/* "1" */			{{-2, -5},			{-2,  5}}},		{ 5,				/* "0" */			{{2, -5},			{12, -5},			{12, 5},			{2, 5},			 {2, -5}}}};#if 0{{{{			{2, -5}}},		{ 5, 				/* "%" */			{{17, -5},			{20, -5},			{20, -2},			{17, -2},			{17, -5}}},		{ 2, 			{{27, -5},			{17, 5}}},		{5, 				{{24, 2},			{27, 2},			{27, 5},			{24, 5},			{24, 2}}}};#endif/*@ -initallelements @*//*@ -charint @*//*@ -nullderef -immediatetrans -type -nullassign @*/#define offst(field) XtOffset(TachometerWidget, field)static XtResource resources[] = {    {XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel),	  offst(tachometer.scale), XtRString, "XtDefaultForeground"},    {XtNtachometerCircleColor, XtCBorderColor, XtRPixel, sizeof(Pixel),	  offst(tachometer.circle), XtRString, "XtDefaultForeground"},    {XtNtachometerNeedleColor, XtCBorderColor, XtRPixel, sizeof(Pixel),	  offst(tachometer.needle), XtRString, "XtDefaultForeground"},    {XtNtachometerNeedleSpeed, XtCtachometerNeedleSpeed, XtRInt,	  sizeof(int), offst(tachometer.speed), XtRImmediate, (caddr_t) 1},    {XtNvalue, XtCValue, XtRInt, sizeof(int),	  offst(tachometer.value), XtRImmediate, (caddr_t) 0},    {XtNheight, XtCHeight, XtRDimension, sizeof(Dimension),	  offst(core.height), XtRImmediate, (caddr_t) 100},    {XtNwidth, XtCWidth, XtRDimension, sizeof(Dimension),	  offst(core.width), XtRImmediate, (caddr_t) 100},    {XtNborderWidth, XtCBorderWidth, XtRDimension, sizeof(Dimension),	  offst(core.border_width), XtRImmediate, (caddr_t) 0},    {XtNinternalBorderWidth, XtCBorderWidth, XtRDimension, sizeof(Dimension),	  offst(tachometer.internal_border), XtRImmediate, (caddr_t) 0},};/*@ -nullderef -immediatetrans +type +nullassign @*/static void Initialize(Widget request, Widget new),  Realize(Widget w, Mask *valueMask, XSetWindowAttributes *attributes),  Resize(Widget w), Redisplay(Widget w, XEvent *event, Region region),  Destroy(Widget w);static Boolean SetValues(Widget current, Widget request UNUSED, Widget new);/*@ -fullinitblock @*/TachometerClassRec tachometerClassRec = {  {/* core_class fields */	#define superclass		(&simpleClassRec)    /* superclass	  	*/	(WidgetClass) superclass,    /* class_name	  	*/	"Tachometer",    /* widget_size	  	*/	sizeof(TachometerRec),    /* class_initialize   	*/	NULL,    /* class_part_initialize	*/	NULL,    /* class_inited       	*/	FALSE,    /* initialize	  	*/	(XtInitProc) Initialize,    /* initialize_hook		*/	NULL,    /* realize		  	*/	Realize,    /* actions		  	*/	NULL,    /* num_actions	  	*/	0,    /* resources	  	*/	resources,    /* num_resources	  	*/	XtNumber(resources),    /* xrm_class	  	*/	NULLQUARK,    /* compress_motion	  	*/	TRUE,    /* compress_exposure  	*/	TRUE,    /* compress_enterleave	*/	TRUE,    /* visible_interest	  	*/	FALSE,    /* destroy		  	*/	Destroy,    /* resize		  	*/	Resize,    /* expose		  	*/	Redisplay,    /* set_values	  	*/	(XtSetValuesFunc) SetValues,    /* set_values_hook		*/	NULL,    /* set_values_almost	*/	XtInheritSetValuesAlmost,    /* get_values_hook		*/	NULL,    /* accept_focus	 	*/	NULL,    /* version			*/	XtVersion,    /* callback_private   	*/	NULL,    /* tm_table		   	*/	NULL,    /* query_geometry		*/	NULL,    /* display_accelerator	*/	XtInheritDisplayAccelerator,    /* extension		*/	NULL  },/* Simple class fields initialization */  {	    /* change_sensitive         */      XtInheritChangeSensitive  }};/*@ +fullinitblock @*/WidgetClass tachometerWidgetClass = (WidgetClass)&tachometerClassRec;/* Private procedures */static void FastFillCircle(    Display *d, Drawable w, GC gc,    Cardinal center_x, Cardinal center_y, Cardinal radius_x, Cardinal radius_y){    /*@ -compdef @*/     XPoint          points[360];     Cardinal        angle;     for (angle = 0; angle < 360; angle++) {	  points[angle].x = (short) (sin((double) angle * D2R) *				     (double) radius_x + (double) center_x);	  points[angle].y = (short) (cos((double) angle * D2R) *				     (double) radius_y + (double) center_y);     }     (void)XFillPolygon(d, w, gc, points, 360, Complex, CoordModeOrigin);    /*@ +compdef @*/}static void DrawSingleNumber(TachometerWidget w, int which, Cardinal x, Cardinal y){     XSegment        segments[7];     Cardinal        nsegments, width, height, count;          width = (Cardinal)((w->core.width / 2) - w->tachometer.internal_border);     height = (Cardinal)((w->core.height / 2) - w->tachometer.internal_border);     if ((width == 0) || (height == 0))	  return;     /*@ +charint -compdef */     for (count = 0, nsegments = 0; count < 7; count++)	  if (num_segment[which].digit[count] == 1) {	       segments[nsegments].x1 = (short)		    (x + ((double)offset[count].x1 * ((double)width/200.0)));	       segments[nsegments].y1 = (short)		    (y + ((double)offset[count].y1 * ((double)height/200.0)));	       segments[nsegments].x2 = (short)		    (x + ((double)offset[count].x2 * ((double)width/200.0)));	       segments[nsegments].y2 = (short)		    (y + ((double)offset[count].y2 * ((double)height/200.0)));	       nsegments++;	  }     (void)XDrawSegments(XtDisplay(w), XtWindow(w), 			 w->tachometer.scale_GC, segments, (int)nsegments);     /*@ -charint +compdef */}static void DrawNumbers(TachometerWidget w, int which, Cardinal x, Cardinal y){     if (which == 10) {	  DrawSingleNumber(w, 1, (Cardinal) ((double) x * 0.9), y);	  DrawSingleNumber(w, 0, x, y);     } else	  DrawSingleNumber(w, which, x, y);}static void DrawLabelString(TachometerWidget w){     XPoint     points[5];     int        char_count, data_count;     Cardinal	ry, center_x, center_y, radius_x, radius_y;     GC gc;     center_x = (Cardinal)(w->core.width / 2);      center_y = (Cardinal)(w->core.height / 2);     radius_x = center_x - w->tachometer.internal_border;     radius_y = center_y - w->tachometer.internal_border;          if (!(center_x != 0 && center_y != 0 && (radius_x > 0) && (radius_y > 0)))	  return;          ry = (Cardinal)(radius_y * 0.35 + center_y);     gc = w->tachometer.scale_GC;     /*@ -compdef @*/     for (char_count = 0; char_count < 4; char_count++) {	  for (data_count = 0; data_count < char_data[char_count].nofline	       ; data_count++) {	       points[data_count].x = (short)		   ((char_data[char_count].point_list[data_count].x) *		    (double) radius_x * 0.01 + center_x);	       points[data_count].y = (short)		   ((char_data[char_count].point_list[data_count].y) *		    (double) radius_y * 0.01 + ry);	  }	  (void)XDrawLines(XtDisplay(w), XtWindow(w), gc, points,		     char_data[char_count].nofline, CoordModeOrigin);     }     /*@ +compdef @*/}static void DrawGauge(TachometerWidget w){     XPoint	points[4];     Cardinal	in_gauge_x, in_gauge_y, out_gauge_x, out_gauge_y;     Cardinal	number_x, number_y, center_x, center_y, radius_x, radius_y;     GC		gc;     double     step, jump = 1.0;     /*@ -type -unsignedcompare -compdef @*/     center_x = w->core.width / 2; center_y = w->core.height / 2;     radius_x = center_x - w->tachometer.internal_border;     radius_y = center_y - w->tachometer.internal_border;     if ((center_x==0) || (center_y==0) || (radius_x<=0) || (radius_y<=0))	  return;	  /* Can't draw anything */     gc = w->tachometer.scale_GC;     for (step = 330.0; step >= 30.0; step -= jump) {	  if ((Cardinal) (step) % 30 == 0) {	       points[0].x = sin((step + 1.0)*D2R) * radius_x*0.75 + center_x;	       points[0].y = cos((step + 1.0)*D2R) * radius_y*0.75 + center_y;	       points[1].x = sin((step - 1.0)*D2R) * radius_x*0.75 + center_x;	       points[1].y = cos((step - 1.0)*D2R) * radius_y*0.75 + center_y;	       points[2].x = sin((step - 1.0)*D2R) * radius_x*0.85 + center_x;	       points[2].y = cos((step - 1.0)*D2R) * radius_y*0.85 + center_y;	       points[3].x = sin((step + 1.0)*D2R) * radius_x*0.85 + center_x;	       points[3].y = cos((step + 1.0)*D2R) * radius_y*0.85 + center_y;	       (void)XFillPolygon(XtDisplay(w), XtWindow(w), gc, points, 4,			    Complex, CoordModeOrigin);

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?