PageRenderTime 210ms CodeModel.GetById 21ms RepoModel.GetById 1ms app.codeStats 0ms

/nas-1.9.3/clients/audio/auedit/Graph.c

#
C | 569 lines | 427 code | 102 blank | 40 comment | 60 complexity | a197039996cacaf430b9ed892015a6a8 MD5 | raw file
  1. /**
  2. * Copyright 1993 Network Computing Devices, Inc.
  3. *
  4. * Permission to use, copy, modify, distribute, and sell this software and
  5. * its documentation for any purpose is hereby granted without fee, provided
  6. * that the above copyright notice appear in all copies and that both that
  7. * copyright notice and this permission notice appear in supporting
  8. * documentation, and that the name Network Computing Devices, Inc. not be
  9. * used in advertising or publicity pertaining to distribution of this
  10. * software without specific, written prior permission.
  11. *
  12. * THIS SOFTWARE IS PROVIDED `AS-IS'. NETWORK COMPUTING DEVICES, INC.,
  13. * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING WITHOUT
  14. * LIMITATION ALL IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
  15. * PARTICULAR PURPOSE, OR NONINFRINGEMENT. IN NO EVENT SHALL NETWORK
  16. * COMPUTING DEVICES, INC., BE LIABLE FOR ANY DAMAGES WHATSOEVER, INCLUDING
  17. * SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES, INCLUDING LOSS OF USE, DATA,
  18. * OR PROFITS, EVEN IF ADVISED OF THE POSSIBILITY THEREOF, AND REGARDLESS OF
  19. * WHETHER IN AN ACTION IN CONTRACT, TORT OR NEGLIGENCE, ARISING OUT OF OR IN
  20. * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  21. *
  22. * Author: Greg Renda <greg@ncd.com>
  23. * Network Computing Devices, Inc.
  24. * 350 North Bernardo Ave.
  25. * Mountain View, CA 94043
  26. *
  27. * $NCDId: @(#)Graph.c,v 1.11 1995/12/06 01:11:03 greg Exp $
  28. */
  29. #include "config.h"
  30. #if defined(HAVE_LIMITS_H)
  31. # include <limits.h>
  32. # define MAXSHORT SHRT_MAX
  33. # define MINSHORT SHRT_MIN
  34. #elif defined(HAVE_VALUES_H)
  35. # include <values.h>
  36. #endif
  37. #if !defined(MAXSHORT)
  38. # define MAXSHORT 0x7fff
  39. #endif
  40. #if !defined(MINSHORT)
  41. # define MINSHORT -MAXSHORT
  42. #endif
  43. #include <X11/IntrinsicP.h>
  44. #include <X11/StringDefs.h>
  45. #include "GraphP.h"
  46. #define min(a, b) ((a) < (b) ? (a) : (b))
  47. #define max(a, b) ((a) > (b) ? (a) : (b))
  48. #define abs(a) ((a) < 0 ? -(a) : (a))
  49. #define offset(field) XtOffsetOf(GraphRec, graph.field)
  50. /* {name, class, type, size, offset, default_type, default_addr}, */
  51. static XtResource resources[] =
  52. {
  53. XtNgraphColor, XtCColor, XtRPixel, sizeof(Pixel), offset(graphColor),
  54. XtRString, XtDefaultForeground,
  55. XtNmarkerColor, XtCColor, XtRPixel, sizeof(Pixel), offset(markerColor),
  56. XtRString, "red",
  57. XtNpositionColor, XtCColor, XtRPixel, sizeof(Pixel), offset(positionColor),
  58. XtRString, "blue",
  59. XtNdata, XtCData, XtRPointer, sizeof(int *), offset(data), XtRImmediate,
  60. NULL,
  61. XtNnumSamples, XtCNumSamples, XtRInt, sizeof(int), offset(numSamples),
  62. XtRImmediate, 0,
  63. XtNnumTracks, XtCNumTracks, XtRInt, sizeof(int), offset(numTracks),
  64. XtRImmediate, (XtPointer) 1,
  65. XtNstart, XtCStart, XtRInt, sizeof(int), offset(start), XtRImmediate, 0,
  66. XtNend, XtCEnd, XtRInt, sizeof(int), offset(end), XtRImmediate, 0,
  67. XtNleftMarker, XtCLeftMarker, XtRInt, sizeof(int), offset(leftMarker),
  68. XtRImmediate, 0,
  69. XtNrightMarker, XtCRightMarker, XtRInt, sizeof(int), offset(rightMarker),
  70. XtRImmediate, 0,
  71. XtNposition, XtCPosition, XtRInt, sizeof(int), offset(position),
  72. XtRImmediate, 0,
  73. XtNleftProc, XtCCallback, XtRCallback, sizeof(XtPointer), offset(leftProc),
  74. XtRCallback, NULL,
  75. XtNrightProc, XtCCallback, XtRCallback, sizeof(XtPointer),
  76. offset(rightProc), XtRCallback, NULL,
  77. };
  78. #undef offset
  79. static void selectMarker(), moveMarker();
  80. static XtActionsRec actions[] =
  81. {
  82. /* {name, procedure}, */
  83. {"selectMarker", selectMarker},
  84. {"moveMarker", moveMarker},
  85. };
  86. static char translations[] =
  87. "\
  88. <BtnDown>: selectMarker()\n\
  89. <BtnMotion>: moveMarker()\n\
  90. ";
  91. static void Initialize(), Exposure(), Destroy(), Resize();
  92. static Boolean SetValues(), redrawPending;
  93. GraphClassRec graphClassRec =
  94. {
  95. { /* core fields */
  96. (WidgetClass) & widgetClassRec, /* superclass */
  97. "Graph", /* class_name */
  98. sizeof(GraphRec), /* widget_size */
  99. NULL, /* class_initialize */
  100. NULL, /* class_part_initialize */
  101. FALSE, /* class_inited */
  102. Initialize, /* initialize */
  103. NULL, /* initialize_hook */
  104. XtInheritRealize, /* realize */
  105. actions, /* actions */
  106. XtNumber(actions), /* num_actions */
  107. resources, /* resources */
  108. XtNumber(resources), /* num_resources */
  109. NULLQUARK, /* xrm_class */
  110. TRUE, /* compress_motion */
  111. TRUE, /* compress_exposure */
  112. TRUE, /* compress_enterleave */
  113. FALSE, /* visible_interest */
  114. Destroy, /* destroy */
  115. Resize, /* resize */
  116. Exposure, /* expose */
  117. SetValues, /* set_values */
  118. NULL, /* set_values_hook */
  119. XtInheritSetValuesAlmost, /* set_values_almost */
  120. NULL, /* get_values_hook */
  121. NULL, /* accept_focus */
  122. XtVersion, /* version */
  123. NULL, /* callback_private */
  124. translations, /* tm_table */
  125. XtInheritQueryGeometry, /* query_geometry */
  126. XtInheritDisplayAccelerator, /* display_accelerator */
  127. NULL, /* extension */
  128. },
  129. { /* graph fields */
  130. 0 /* empty */
  131. }
  132. };
  133. WidgetClass graphWidgetClass = (WidgetClass) & graphClassRec;
  134. static void
  135. CreateGC(w, which)
  136. GraphWidget w;
  137. unsigned int which;
  138. {
  139. XGCValues gcv;
  140. #if !defined(__alpha__) && !defined(__x86_64__) && !defined(__ia64__) && !defined(__LP64__)
  141. unsigned long commonMask;
  142. #else /* __alpha */
  143. unsigned int commonMask;
  144. #endif /* __alpha */
  145. gcv.graphics_exposures = FALSE;
  146. commonMask = GCGraphicsExposures;
  147. if (which & GRAPH_GC)
  148. {
  149. gcv.foreground = w->graph.graphColor;
  150. w->graph.graphGC = XtGetGC((Widget) w, commonMask | GCForeground, &gcv);
  151. }
  152. if (which & POSITION_GC)
  153. {
  154. gcv.foreground = w->graph.positionColor ^ w->core.background_pixel;
  155. gcv.function = GXxor;
  156. gcv.line_style = LineOnOffDash;
  157. w->graph.positionGC = XtGetGC((Widget) w,
  158. commonMask | GCForeground | GCLineStyle |
  159. GCFunction, &gcv);
  160. }
  161. if (which & MARKER_GC)
  162. {
  163. gcv.foreground = w->graph.markerColor ^ w->core.background_pixel;
  164. gcv.function = GXxor;
  165. w->graph.markerGC = XtGetGC((Widget) w,
  166. commonMask | GCForeground | GCFunction,
  167. &gcv);
  168. }
  169. }
  170. static void
  171. DestroyGC(w, which)
  172. GraphWidget w;
  173. unsigned int which;
  174. {
  175. if (which & GRAPH_GC)
  176. XtReleaseGC((Widget) w, w->graph.graphGC);
  177. if (which & POSITION_GC)
  178. XtReleaseGC((Widget) w, w->graph.positionGC);
  179. if (which & MARKER_GC)
  180. XtReleaseGC((Widget) w, w->graph.markerGC);
  181. }
  182. /* ARGSUSED */
  183. static void
  184. Initialize(req, new)
  185. Widget req,
  186. new;
  187. {
  188. CreateGC(new, (unsigned int) ALL_GCS);
  189. redrawPending = FALSE;
  190. }
  191. static void
  192. Destroy(w)
  193. Widget w;
  194. {
  195. DestroyGC(w, (unsigned int) ALL_GCS);
  196. }
  197. static void
  198. drawPosition(w)
  199. GraphWidget w;
  200. {
  201. int x;
  202. if (w->graph.position >= w->graph.end)
  203. w->graph.position = w->graph.end - 1;
  204. if (w->graph.position < w->graph.start)
  205. w->graph.position = w->graph.start;
  206. x = (w->graph.position - w->graph.start) * w->graph.hscale;
  207. XDrawLine(XtDisplay(w), XtWindow(w), w->graph.positionGC, x, 0, x,
  208. w->core.height - 1);
  209. }
  210. static void
  211. drawMarker(w, m)
  212. GraphWidget w;
  213. int m;
  214. {
  215. int *x,
  216. marker;
  217. if (m == GraphLeftMarker)
  218. {
  219. marker = w->graph.leftMarker;
  220. if (marker >= w->graph.rightMarker)
  221. marker = w->graph.rightMarker - 1;
  222. if (marker < w->graph.start)
  223. marker = w->graph.start;
  224. w->graph.leftMarker = marker;
  225. x = &w->graph.leftMarkerX;
  226. }
  227. else
  228. { /* right marker */
  229. marker = w->graph.rightMarker;
  230. if (marker <= w->graph.leftMarker)
  231. marker = w->graph.leftMarker + 1;
  232. if (marker > w->graph.end)
  233. marker = w->graph.end;
  234. w->graph.rightMarker = marker;
  235. x = &w->graph.rightMarkerX;
  236. }
  237. *x = (marker - w->graph.start) * w->graph.hscale;
  238. if (w->graph.leftMarkerX == w->graph.rightMarkerX)
  239. *x += m == GraphLeftMarker ? -1 : 1;
  240. XDrawLine(XtDisplay(w), XtWindow(w), w->graph.markerGC, *x, 0, *x,
  241. w->core.height - 1);
  242. }
  243. static void
  244. paintWindow(w)
  245. GraphWidget w;
  246. {
  247. Display *dpy = XtDisplay(w);
  248. Window win = XtWindow(w);
  249. int x,
  250. t,
  251. center;
  252. float k;
  253. GraphDataType *p,
  254. *end;
  255. redrawPending = FALSE;
  256. XClearWindow(dpy, win);
  257. if (w->graph.numSamples)
  258. for (t = 0; t < w->graph.numTracks; t++)
  259. {
  260. center = (int) w->core.height / (int) w->graph.numTracks / 2 *
  261. ((t + 1) * 2 - 1);
  262. /* draw center line */
  263. XDrawLine(dpy, win, w->graph.graphGC, 0, center, w->core.width,
  264. center);
  265. /* draw the data */
  266. p = w->graph.data + (w->graph.start * w->graph.numTracks) + t;
  267. end = w->graph.data + (w->graph.end * w->graph.numTracks);
  268. k = w->graph.hscale;
  269. if (k < 1)
  270. { /* multiple samples per pixel */
  271. GraphDataType minY,
  272. maxY,
  273. pminY,
  274. pmaxY,
  275. v;
  276. pminY = pmaxY = 0;
  277. for (x = 0; x < (int) w->core.width; x++)
  278. {
  279. minY = MAXSHORT;
  280. maxY = MINSHORT;
  281. for (; (int) k == x && p < end; k += w->graph.hscale)
  282. {
  283. v = *p;
  284. p += w->graph.numTracks;
  285. minY = min(v, minY);
  286. maxY = max(v, maxY);
  287. }
  288. minY = min(pmaxY, minY);
  289. maxY = max(pminY, maxY);
  290. pminY = minY;
  291. pmaxY = maxY;
  292. XDrawLine(dpy, win, w->graph.graphGC,
  293. x, (int) (-maxY * w->graph.vscale + center),
  294. x, (int) (-minY * w->graph.vscale + center));
  295. }
  296. }
  297. else
  298. { /* multiple pixels per sample */
  299. int px,
  300. py,
  301. y;
  302. px = 0;
  303. py = -*p * w->graph.vscale + center;
  304. p += w->graph.numTracks;
  305. x = k;
  306. k += w->graph.hscale;
  307. for (; p < end; k += w->graph.hscale, x = k)
  308. {
  309. y = -*p * w->graph.vscale + center;
  310. p += w->graph.numTracks;
  311. XDrawLine(dpy, win, w->graph.graphGC, px, py, x, y);
  312. px = x;
  313. py = y;
  314. }
  315. }
  316. }
  317. /* draw markers */
  318. w->graph.rightMarkerX = w->core.width;
  319. drawMarker(w, GraphLeftMarker);
  320. drawMarker(w, GraphRightMarker);
  321. drawPosition(w);
  322. }
  323. static void
  324. Exposure(w, event, region)
  325. Widget w;
  326. XEvent *event;
  327. Region region;
  328. {
  329. if (XtIsRealized((Widget) w))
  330. paintWindow(w);
  331. }
  332. static void
  333. recalc(w)
  334. GraphWidget w;
  335. {
  336. w->graph.vscale = (float) w->core.height / w->graph.numTracks /
  337. (MAXSHORT - MINSHORT + 1);
  338. w->graph.hscale = (float) ((int) w->core.width - 1) /
  339. (w->graph.end - w->graph.start);
  340. }
  341. static void
  342. validate(g)
  343. GraphPart *g;
  344. {
  345. if (g->start < 0)
  346. g->start = 0;
  347. else
  348. g->start = min(g->start, g->numSamples - 1);
  349. if (g->end <= g->start)
  350. g->end = g->start + 1;
  351. else
  352. g->end = min(g->end, g->numSamples);
  353. if (g->leftMarker >= g->rightMarker)
  354. g->leftMarker = g->rightMarker - 1;
  355. if (g->leftMarker < g->start)
  356. g->leftMarker = g->start;
  357. if (g->rightMarker <= g->leftMarker)
  358. g->rightMarker = g->leftMarker + 1;
  359. if (g->rightMarker > g->end)
  360. g->rightMarker = g->end;
  361. }
  362. /* ARGSUSED */
  363. static Boolean
  364. SetValues(old, req, w)
  365. GraphWidget old,
  366. req,
  367. w;
  368. {
  369. Boolean newGC = NO_GCS,
  370. redraw = FALSE;
  371. validate(&w->graph);
  372. if (w->graph.leftMarker != old->graph.leftMarker)
  373. {
  374. XtCallCallbacks((Widget) w, XtNleftProc,
  375. (XtPointer) w->graph.leftMarker);
  376. redraw = TRUE;
  377. }
  378. if (w->graph.rightMarker != old->graph.rightMarker)
  379. {
  380. XtCallCallbacks((Widget) w, XtNrightProc,
  381. (XtPointer) w->graph.rightMarker);
  382. redraw = TRUE;
  383. }
  384. if (w->graph.position != old->graph.position ||
  385. w->graph.data != old->graph.data)
  386. redraw = TRUE;
  387. if (w->graph.numSamples != old->graph.numSamples ||
  388. w->graph.start != old->graph.start ||
  389. w->graph.end != old->graph.end)
  390. {
  391. recalc(w);
  392. redraw = TRUE;
  393. }
  394. if (w->graph.graphColor != old->graph.graphColor)
  395. newGC |= GRAPH_GC;
  396. if (w->graph.positionColor != old->graph.positionColor)
  397. newGC |= POSITION_GC;
  398. if (w->graph.markerColor != old->graph.markerColor)
  399. newGC |= MARKER_GC;
  400. if (w->core.background_pixel != old->core.background_pixel)
  401. newGC |= MARKER_GC;
  402. if (newGC)
  403. {
  404. DestroyGC(old, newGC);
  405. CreateGC(w, newGC);
  406. redraw = TRUE;
  407. }
  408. if (redrawPending)
  409. return FALSE;
  410. else
  411. return redrawPending = redraw;
  412. }
  413. static void
  414. Resize(w)
  415. Widget w;
  416. {
  417. recalc(w);
  418. }
  419. static void
  420. selectMarker(w, event)
  421. GraphWidget w;
  422. XButtonEvent *event;
  423. {
  424. w->graph.marker = abs(event->x - w->graph.leftMarkerX) <
  425. abs(event->x - w->graph.rightMarkerX) ? GraphLeftMarker :
  426. GraphRightMarker;
  427. moveMarker(w, event);
  428. }
  429. static void
  430. moveMarker(w, event)
  431. GraphWidget w;
  432. XButtonEvent *event;
  433. {
  434. int marker = event->x / w->graph.hscale + w->graph.start;
  435. /* erase the old marker */
  436. drawMarker(w, w->graph.marker);
  437. if (w->graph.marker == GraphLeftMarker)
  438. w->graph.leftMarker = marker;
  439. else
  440. w->graph.rightMarker = marker;
  441. /* draw the new marker */
  442. drawMarker(w, w->graph.marker);
  443. if (w->graph.marker == GraphLeftMarker)
  444. XtCallCallbacks((Widget) w, XtNleftProc,
  445. (XtPointer) w->graph.leftMarker);
  446. else
  447. XtCallCallbacks((Widget) w, XtNrightProc,
  448. (XtPointer) w->graph.rightMarker);
  449. }
  450. /* public functions */
  451. void
  452. GraphSetPosition(w, p)
  453. GraphWidget w;
  454. int p;
  455. {
  456. /* erase the old position */
  457. drawPosition(w);
  458. w->graph.position = p;
  459. /* draw the new position */
  460. drawPosition(w);
  461. }
  462. void
  463. GraphRedraw(w)
  464. GraphWidget w;
  465. {
  466. paintWindow(w);
  467. }