$NetBSD: patch-an,v 1.1 2001/04/05 13:57:16 wiz Exp $ --- xvdial.c.orig Tue Jan 3 22:20:31 1995 +++ xvdial.c Sun Nov 14 14:05:49 1999 @@ -45,16 +45,17 @@ static void drawArrow PARM((DIAL *)); static void drawValStr PARM((DIAL *)); static void drawButt PARM((DIAL *, int, int)); -static int computeDialVal PARM((DIAL *, int, int)); +static double computeDialVal PARM((DIAL *, int, int)); static void dimDial PARM((DIAL *)); /***************************************************/ -void DCreate(dp, parent, x, y, w, h, minv, maxv, curv, page, +void DCreate(dp, parent, x, y, w, h, minv, maxv, curv, inc, page, fg, bg, hi, lo, title, units) DIAL *dp; Window parent; -int x,y,w,h,minv,maxv,curv,page; +int x,y,w,h; +double minv,maxv,curv,inc,page; unsigned long fg,bg,hi,lo; char *title, *units; { @@ -98,18 +99,18 @@ 1,fg,bg); if (!dp->win) FatalError("can't create dial window"); - DSetRange(dp, minv, maxv, curv, page); + DSetRange(dp, minv, maxv, curv, inc, page); XSelectInput(theDisp, dp->win, ExposureMask | ButtonPressMask); } /***************************************************/ -void DSetRange(dp, minv, maxv, curv, page) +void DSetRange(dp, minv, maxv, curv, inc, page) DIAL *dp; -int minv, maxv, curv, page; +double minv, maxv, curv, inc, page; { if (maxvmin = minv; dp->max = maxv; dp->page = page; + dp->min = minv; dp->max = maxv; dp->inc = inc; dp->page = page; dp->active = (minv < maxv); DSetVal(dp, curv); @@ -119,7 +120,7 @@ /***************************************************/ void DSetVal(dp, curv) DIAL *dp; -int curv; +double curv; { RANGE(curv, dp->min, dp->max); /* make sure curv is in-range */ @@ -129,7 +130,7 @@ XSetForeground(theDisp, theGC, dp->bg); drawArrow(dp); - dp->val = curv; + dp->val = (double)((int)(curv / dp->inc + (curv > 0 ? 0.5 : -0.5))) * dp->inc; /* draw new arrow and string */ XSetForeground(theDisp, theGC, dp->fg); @@ -202,7 +203,8 @@ int mx,my; { Window rW,cW; - int rx,ry, x,y, ipos, pos, lit, i, origval; + int rx, ry, x, y, ipos, pos, lit; + double origval; unsigned int mask; lit = 0; @@ -224,9 +226,9 @@ if (ipos != INDIAL) { drawButt(dp, ipos, 1); switch (ipos) { - case INCW1: if (dp->val < dp->max) DSetVal(dp, dp->val+1); break; + case INCW1: if (dp->val < dp->max) DSetVal(dp, dp->val+dp->inc); break; case INCW2: if (dp->val < dp->max) DSetVal(dp, dp->val+dp->page); break; - case INCCW1: if (dp->val > dp->min) DSetVal(dp, dp->val-1); break; + case INCCW1: if (dp->val > dp->min) DSetVal(dp, dp->val-dp->inc); break; case INCCW2: if (dp->val > dp->min) DSetVal(dp, dp->val-dp->page); break; } if (dp->drawobj != NULL) (dp->drawobj)(); @@ -235,8 +237,9 @@ } else { - i = computeDialVal(dp, mx, my); - DSetVal(dp, i); + double v; + v = computeDialVal(dp, mx, my); + DSetVal(dp, v); if (dp->drawobj != NULL) (dp->drawobj)(); } @@ -246,11 +249,11 @@ if (!(mask & Button1Mask)) break; /* button released */ if (ipos == INDIAL) { - int j; - i = computeDialVal(dp, x, y); - j = dp->val; - DSetVal(dp, i); - if (j != dp->val) { + double v, w; + v = computeDialVal(dp, x, y); + w = dp->val; + DSetVal(dp, v); + if (w != dp->val) { /* track whatever dial controls */ if (dp->drawobj != NULL) (dp->drawobj)(); } @@ -266,11 +269,11 @@ if (lit) { switch (ipos) { - case INCW1: if (dp->val < dp->max) DSetVal(dp, dp->val+1); + case INCW1: if (dp->val < dp->max) DSetVal(dp, dp->val+dp->inc); break; case INCW2: if (dp->val < dp->max) DSetVal(dp, dp->val+dp->page); break; - case INCCW1: if (dp->val > dp->min) DSetVal(dp, dp->val-1); + case INCCW1: if (dp->val > dp->min) DSetVal(dp, dp->val-dp->inc); break; case INCCW2: if (dp->val > dp->min) DSetVal(dp, dp->val-dp->page); break; @@ -320,19 +323,20 @@ static void drawArrow(dp) DIAL *dp; { - int i, rad, cx, cy; + int rad, cx, cy; + double v; XPoint arrow[4]; rad = dp->rad; cx = dp->cx; cy = dp->cy; /* map pos (range minv..maxv) into degrees (range 240..-60) */ - i = 240 + (-300 * (dp->val - dp->min)) / (dp->max - dp->min); - arrow[0].x = cx + (int) ((double) rad * .80 * cos(i * DEG2RAD)); - arrow[0].y = cy - (int) ((double) rad * .80 * sin(i * DEG2RAD)); - arrow[1].x = cx + (int) ((double) rad * .33 * cos((i+160) * DEG2RAD)); - arrow[1].y = cy - (int) ((double) rad * .33 * sin((i+160) * DEG2RAD)); - arrow[2].x = cx + (int) ((double) rad * .33 * cos((i-160) * DEG2RAD)); - arrow[2].y = cy - (int) ((double) rad * .33 * sin((i-160) * DEG2RAD)); + v = 240 + (-300 * (dp->val - dp->min)) / (dp->max - dp->min); + arrow[0].x = cx + (int) ((double) rad * .80 * cos(v * DEG2RAD)); + arrow[0].y = cy - (int) ((double) rad * .80 * sin(v * DEG2RAD)); + arrow[1].x = cx + (int) ((double) rad * .33 * cos((v+160) * DEG2RAD)); + arrow[1].y = cy - (int) ((double) rad * .33 * sin((v+160) * DEG2RAD)); + arrow[2].x = cx + (int) ((double) rad * .33 * cos((v-160) * DEG2RAD)); + arrow[2].y = cy - (int) ((double) rad * .33 * sin((v-160) * DEG2RAD)); arrow[3].x = arrow[0].x; arrow[3].y = arrow[0].y; XDrawLines(theDisp, dp->win, theGC, arrow, 4, CoordModeOrigin); @@ -343,23 +347,37 @@ static void drawValStr(dp) DIAL *dp; { - int i, x1, x2; + int tot, i, x1, x2; char foo[60], foo1[60]; /* compute longest string necessary so we can right-align this thing */ - sprintf(foo,"%d",dp->min); x1 = strlen(foo); - sprintf(foo,"%d",dp->max); x2 = strlen(foo); + sprintf(foo,"%d",(int)dp->min); x1 = strlen(foo); + sprintf(foo,"%d",(int)dp->max); x2 = strlen(foo); if (dp->min < 0 && dp->max > 0) x2++; /* put '+' at beginning */ i = x1; if (x2>x1) i = x2; if (dp->units) i += strlen(dp->units); - if (dp->min < 0 && dp->max > 0) sprintf(foo,"%+d", dp->val); - else sprintf(foo,"%d", dp->val); + sprintf(foo,"%g",dp->inc); /* space for decimal values */ + tot = i + strlen(foo) - 1; /* Take away the 0 from the beginning */ + + if (dp->min < 0.0 && dp->max > 0.0) sprintf(foo,"%+g", dp->val); + else sprintf(foo,"%g", dp->val); + + if (dp->inc < 1.0) + { + int j; + + if (dp->val == (double)((int)dp->val)) + strcat(foo,"."); + + for (j = strlen(foo); j < tot; j++) + strcat(foo,"0"); + } if (dp->units) strcat(foo,dp->units); foo1[0] = '\0'; if (strlen(foo) < (size_t) i) { - for (i = i - strlen(foo); i>0; i--) strcat(foo1," "); + for (i-=strlen(foo);i>0;i--) strcat(foo1," "); } strcat(foo1, foo); @@ -411,12 +429,13 @@ /***************************************************/ -static int computeDialVal(dp, x, y) +static double computeDialVal(dp, x, y) DIAL *dp; int x, y; { - int dx, dy, val; - double angle; + int dx, dy; + + double angle, val; /* compute dx, dy (distance from cx, cy). Note: +dy is *up* */ dx = x - dp->cx; dy = dp->cy - y; @@ -436,8 +455,10 @@ if (angle > 270.0) angle -= 360.0; if (angle < -90.0) angle += 360.0; - val = (int) ((dp->max - dp->min) * (240.0 - angle) / 300.0) + dp->min; + val = ((dp->max - dp->min) * (240.0 - angle) / 300.0) + dp->min; + /* round value to be an even multiple of dp->inc */ + val = (double)((int)(val / dp->inc + 0.5)) * dp->inc; return val; }