netview.cc.tk
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:11k
源码类别:

通讯编程

开发平台:

Visual C++

  1. /*
  2.  * Copyright (c) 1991,1993 Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice, this list of conditions and the following disclaimer.
  10.  * 2. Redistributions in binary form must reproduce the above copyright
  11.  *    notice, this list of conditions and the following disclaimer in the
  12.  *    documentation and/or other materials provided with the distribution.
  13.  * 3. All advertising materials mentioning features or use of this software
  14.  *    must display the following acknowledgement:
  15.  * This product includes software developed by the Computer Systems
  16.  * Engineering Group at Lawrence Berkeley Laboratory.
  17.  * 4. Neither the name of the University nor of the Laboratory may be used
  18.  *    to endorse or promote products derived from this software without
  19.  *    specific prior written permission.
  20.  *
  21.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  22.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31.  * SUCH DAMAGE.
  32.  */
  33. #ifndef lint
  34. static char rcsid[] =
  35.     "@(#) $Header: /cvsroot/nsnam/nam-1/netview.cc.tk,v 1.1.1.1 1997/06/16 22:40:30 mjh Exp $ (LBL)";
  36. #endif
  37. #define OLDX
  38. #include <osfcn.h>
  39. #include <ctype.h>
  40. extern "C" {
  41. #include <tk.h>
  42. }
  43. #include "bbox.h"
  44. #include "netview.h"
  45. #include "netmodel.h"
  46. #include "Tcl.h"
  47. #include "paint.h"
  48. #include "packet.h"
  49. #include "xstuff.h"
  50. void NetView::resize(int width, int height)
  51. {
  52. width_ = width;
  53. height_ = height;
  54. matrix_.clear();
  55. BBox bb;
  56. model_->BoundingBox(bb);
  57. double x = 0;
  58. double y = 0;
  59. double w = width;
  60. double h = height;
  61. /*
  62.  * Set up a transform that maps bb -> canvas.  I.e,
  63.  * bb -> unit square -> allocation, but which retains
  64.  * the aspect ratio.  Also, add a margin.
  65.  */
  66. double nw = bb.xmax - bb.xmin;
  67. double nh = bb.ymax - bb.ymin;
  68. /* 
  69.  * Grow a margin.
  70.  */
  71. double bbw = 1.1 * nw;
  72. double bbh = 1.1 * nh;
  73. double tx = bb.xmin - 0.5 * (bbw - nw);
  74. double ty = bb.ymin - 0.5 * (bbh - nh);
  75. /*
  76.  * move base coordinate system to origin
  77.  */
  78. matrix_.translate(-tx, -ty);
  79. /*
  80.  * flip vertical axis because X is backwards.
  81.  */
  82. matrix_.scale(1., -1.);
  83. matrix_.translate(0., bbh);
  84. double ws = w / bbw;
  85. double hs = h / bbh;
  86. if (ws <= hs) {
  87. matrix_.scale(ws, ws);
  88. matrix_.translate(x, y + 0.5 * (h - ws * bbh));
  89. } else {
  90. matrix_.scale(hs, hs);
  91. matrix_.translate(x + 0.5 * (w - hs * bbw), y);
  92. }
  93. XWindowAttributes xwa;
  94. XGetWindowAttributes(dpy_, drawable_, &xwa);
  95. offscreen_ = XCreatePixmap(dpy_, drawable_, width_, height_, xwa.depth);
  96. }
  97. void NetView::draw()
  98. {
  99. if (offscreen_ == 0)
  100. return;
  101. #ifdef OLDX
  102. XFillRectangle(dpy_, offscreen_, background_, 0, 0, width_, height_);
  103. #endif
  104. ClearDisplay();
  105. model_->render(this);
  106. #ifdef OLDX
  107. XCopyArea(dpy_, offscreen_, drawable_, background_,
  108.   0, 0, width_, height_, 0, 0);
  109. #endif
  110. UpdateDisplay();
  111. }
  112. NetView::NetView(const char* name, NetModel* m) 
  113.         : model_(m)
  114. {
  115. Tcl& tcl = Tcl::instance();
  116. tk_ = Tk_CreateWindowFromPath(tcl.interp(), tcl.tkmain(),
  117.       (char*)name, 0);
  118. if (tk_ == 0)
  119. abort();
  120. Tk_SetClass(tk_, "NetView");
  121. /*XXX*/
  122. /* Specify preferred window size. */
  123. Tk_GeometryRequest(tk_, 50, 50);
  124. Tk_CreateEventHandler(tk_, ExposureMask|StructureNotifyMask,
  125.       handle, (ClientData)this);
  126. width_ = height_ = 0;
  127. tcl.CreateCommand(Tk_PathName(tk_), command, (ClientData)this, 0);
  128.     
  129. dpy_ = Tk_Display(tk_);
  130. background_ = Paint::instance()->background_gc();
  131. Tk_MakeWindowExist(tk_);
  132.     
  133. drawable_ = Tk_WindowId(tk_);
  134. offscreen_ = 0;
  135.     
  136. load_fonts();
  137. }
  138. /* Handler for the Expose, DestroyNotify and ConfigureNotify events. */
  139. void NetView::handle(ClientData cd, XEvent* ep)
  140. {
  141. NetView* nv = (NetView*)cd;
  142. switch (ep->type) {
  143. case Expose:
  144. if (ep->xexpose.count == 0)
  145. /*XXX*/
  146. nv->draw();
  147. break;
  148. case DestroyNotify:
  149. /*XXX kill ourself */
  150. break;
  151. case ConfigureNotify:
  152. if (nv->width_ != ep->xconfigure.width ||
  153.     nv->height_ != ep->xconfigure.height)
  154. nv->resize(ep->xconfigure.width,
  155.    ep->xconfigure.height);
  156. break;
  157. }
  158. }
  159. extern void Parse(NetModel*, const char* layout);
  160. int NetView::command(ClientData cd, Tcl_Interp* tcl, int argc, char **argv)
  161. {
  162. if (argc < 2) {
  163. Tcl_AppendResult(tcl, """, argv[0], "": arg mismatch", 0);
  164. return (TCL_ERROR);
  165. }
  166. #ifdef notdef
  167. /*
  168.  * $w chart -v variable -s src -d dst -w width -h height
  169.  */
  170. NetView* nv = (NetView*)cd;
  171. if (strcmp(argv[1], "layout") == 0) {
  172. /*   <window> layout <net> */
  173. if (argc != 3) {
  174. Tcl_AppendResult(tcl, """, argv[0],
  175.  "": arg mismatch", 0);
  176. return (TCL_ERROR);
  177. }
  178. Parse(nv->model_, argv[2]);
  179. return (TCL_OK);
  180. }
  181. if (strcmp(argv[1], "clock") == 0) {
  182. /*   <window> clock <proc> <interval> */
  183. if (argc != 4) {
  184. Tcl_AppendResult(tcl, """, argv[0],
  185.  "": arg mismatch", 0);
  186. return (TCL_ERROR); }
  187. const char* proc = argv[2];
  188. double interval = atof(argv[3]);
  189. master->clock(proc, interval);
  190. return (TCL_OK);
  191. }
  192. /*
  193.  * $nv trace callback var
  194.  * $nv trace callback etype src dst tag
  195.  */
  196. if (strcmp(argv[1], "trace") == 0) {
  197. if (argc == 4)
  198. nv->trace(argv[2], argv[3]);
  199. else if (argc == 7)
  200. nv->trace(argv[2], argv[3], argv[4], argv[5], argv[6]);
  201. else {
  202. Tcl_AppendResult(tcl, """, argv[0],
  203.  "": arg mismatch", 0);
  204. return (TCL_ERROR);
  205. }
  206. return (TCL_OK);
  207. }
  208. #endif
  209. if (strcmp(argv[1], "info") == 0) {
  210. if (argc == 3) {
  211. NetView *nv = (NetView *)cd;
  212. Tcl& tcl = Tcl::instance();
  213. Animation* a;
  214. double now = atof(argv[2]);
  215. Window root, child;
  216. int rootX, rootY, winX, winY;
  217. unsigned int state;
  218. float px, py;
  219. #ifdef OLDX
  220.   XQueryPointer(nv->dpy_, Tk_WindowId(nv->tk_), &root,
  221.         &child, &rootX, &rootY, &winX, &winY,
  222.         &state);
  223.   nv->matrix_.imap(float(winX), float(winY), px, py);
  224. if ((a = nv->model_->inside(now, px, py)) != 0) {
  225. tcl.result(a->info());
  226. return TCL_OK;
  227. }
  228. #endif
  229. return TCL_OK;
  230. }
  231. Tcl_AppendResult(tcl, """, argv[0],
  232.  "": arg mismatch", 0);
  233. return TCL_ERROR;
  234. }
  235. Tcl_AppendResult(tcl, """, argv[0], "": unknown arg: ", argv[1], 0);
  236. return (TCL_ERROR);
  237. }
  238. #ifdef notdef
  239. void 
  240. NetView::trace(const char* cmd, const char* varname)
  241. {
  242. master->addFilter(new VarFilter(tcl_, cmd, varname));
  243. }
  244. void 
  245. NetView::trace(const char* cmd, const char* etype,
  246.        const char* src, const char* dst, const char* tag)
  247. {
  248. master->addFilter(new GenericFilter(tcl_, cmd, etype, src, dst, tag));
  249. }
  250. #endif
  251. void 
  252. NetView::line(float x0, float y0, float x1, float y1, int paint)
  253. {
  254. int ax, ay;
  255. matrix_.map(x0, y0, ax, ay);
  256. int bx, by;
  257. matrix_.map(x1, y1, bx, by);
  258. #ifdef OLDX
  259. GC gc = Paint::instance()->paint_to_gc(paint);
  260. XDrawLine(dpy_, offscreen_, gc, ax, ay, bx, by);
  261. #endif
  262. DrawLine(ax, ay, bx, by, 1);
  263. }
  264. void NetView::rect(float x0, float y0, float x1, float y1, int paint)
  265. {
  266. int x, y;
  267. matrix_.map(x0, y0, x, y);
  268. int xx, yy;
  269. matrix_.map(x1, y1, xx, yy);
  270. int w = xx - x;
  271. if (w < 0) {
  272. x = xx;
  273. w = -w;
  274. }
  275. int h = yy - y;
  276. if (h < 0) {
  277. h = -h;
  278. y = yy;
  279. }
  280. #ifdef OLDX
  281. GC gc = Paint::instance()->paint_to_gc(paint);
  282. XDrawRectangle(dpy_, offscreen_, gc, x, y, w, h);
  283. #endif
  284. DrawRectangle(x, y, w, h, 1);
  285. }
  286. void NetView::polygon(const float* x, const float* y, int n, int paint)
  287. {
  288. /*XXX*/
  289. XPoint pts[10];
  290. for (int i = 0; i < n; ++i) {
  291. float tx, ty;
  292. matrix_.map(x[i], y[i], tx, ty);
  293. pts[i].x = int(tx);
  294. pts[i].y = int(ty);
  295. }
  296. pts[n] = pts[0];
  297. #ifdef OLDX
  298. GC gc = Paint::instance()->paint_to_gc(paint);
  299. XDrawLines(dpy_, offscreen_, gc, pts, n + 1, CoordModeOrigin);
  300. #endif
  301. DrawPolygon(pts, n+1, 1);
  302. }
  303. void NetView::fill(const float* x, const float* y, int n, int paint)
  304. {
  305. /*XXX*/
  306. XPoint pts[10];
  307. for (int i = 0; i < n; ++i) {
  308. float tx, ty;
  309. matrix_.map(x[i], y[i], tx, ty);
  310. pts[i].x = int(tx);
  311. pts[i].y = int(ty);
  312. }
  313. pts[n] = pts[0];
  314. #ifdef OLDX       
  315. GC gc = Paint::instance()->paint_to_gc(paint);
  316. XFillPolygon(dpy_, offscreen_, gc, pts, n + 1,
  317.      Convex, CoordModeOrigin);
  318. #endif
  319.         FillPolygon(pts, n+1, 1);
  320. }
  321. void NetView::circle(float x, float y, float r, int paint)
  322. {
  323. int tx, ty;
  324. matrix_.map(x, y, tx, ty);
  325. int tr, dummy;
  326. matrix_.map(x + r, y, tr, dummy);
  327. tr -= tx;
  328. tx -= tr;
  329. ty -= tr;
  330. tr *= 2;
  331. #ifdef OLDX
  332. GC gc = Paint::instance()->paint_to_gc(paint);
  333. XDrawArc(dpy_, offscreen_, gc, tx, ty, tr, tr, 0, 64 * 360);
  334. #endif
  335. DrawOval(tx, ty, tr, tr, 1);
  336. }
  337. static char* fontName[NFONT] = {
  338. "-adobe-times-medium-r-normal-*-8-*-*-*-*-*-*-*",
  339. "-adobe-times-medium-r-normal-*-10-*-*-*-*-*-*-*",
  340. "-adobe-times-medium-r-normal-*-12-*-*-*-*-*-*-*",
  341. "-adobe-times-medium-r-normal-*-14-*-*-*-*-*-*-*",
  342. "-adobe-times-medium-r-normal-*-18-*-*-*-*-*-*-*",
  343. "-adobe-times-medium-r-normal-*-20-*-*-*-*-*-*-*",
  344. "-adobe-times-medium-r-normal-*-24-*-*-*-*-*-*-*",
  345. "-adobe-times-medium-r-normal-*-34-*-*-*-*-*-*-*",
  346. };
  347. static Font* font[sizeof(fontName)/sizeof(fontName[0])];
  348. /* Set the font structures using values in 'fontName' (defined above). */
  349. void NetView::load_fonts()
  350. {
  351. Tcl_Interp* tcl = Tcl::instance().interp();
  352. nfont_ = 0;
  353. for (int i = 0; i < NFONT; ++i) {
  354. fonts_[nfont_] = Tk_GetFontStruct(tcl, tk_, fontName[i]);
  355. if (fonts_[nfont_] == 0)
  356. continue;
  357. font_gc_[nfont_] =
  358. Paint::instance()->text_gc(fonts_[nfont_]->fid);
  359. ++nfont_;
  360. }
  361. if (nfont_ == 0)
  362. fprintf(stderr, "nam: warning no fonts foundn");
  363. }
  364. void NetView::free_fonts()
  365. {
  366. /*XXX Tk_FreeFontStruct*/
  367. }
  368. int NetView::lookup_font(int d)
  369. {
  370. int i = nfont_;
  371. while (--i > 0) {
  372. XFontStruct* p = fonts_[i];
  373. if (d >= p->ascent + p->descent)
  374. return (i);
  375. }
  376. return (0);
  377. }
  378. void NetView::string(float fx, float fy, float dim, const char* s, int anchor)
  379. {
  380. if (nfont_ <= 0)
  381. return;
  382. int dummy;
  383. int dlow, dhigh;
  384. /*XXX this could be cached*/
  385. matrix_.map(0., 0., dummy, dlow);
  386. matrix_.map(0., 0.9 * dim, dummy, dhigh);
  387. int d = dhigh - dlow;
  388. if (d < 0)
  389. d = -d;
  390. int font = lookup_font(d);
  391. XFontStruct* p = fonts_[font];
  392. /*int h = p->ascent + p->descent;*/
  393. int h = p->ascent;
  394. int len = strlen(s);
  395. int w = XTextWidth(p, s, len);
  396. int x, y;
  397. matrix_.map(fx, fy, x, y);
  398. /* XXX still need to adjust for mismatch between d and actual height*/
  399. switch (anchor) {
  400. case ANCHOR_CENTER:
  401. x -= w / 2;
  402. y += h / 2;
  403. break;
  404. case ANCHOR_NORTH:
  405. x -= w / 2;
  406. y -= d;
  407. break;
  408. case ANCHOR_SOUTH:
  409. x -= w / 2;
  410. y += d + h;
  411. break;
  412. case ANCHOR_WEST:
  413. x -= d + w;
  414. y += h / 2;
  415. break;
  416. case ANCHOR_EAST:
  417. x += d;
  418. y += h / 2;
  419. break;
  420. }
  421. #ifdef OLDX
  422. XDrawString(dpy_, offscreen_, font_gc_[font], x, y, s, len);
  423. #endif
  424. DrawString("fixed", s, x, y, 1);
  425. }