KOffice – TDE office suite
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

796 lines
18KB

  1. /*
  2. FILE: x_interface.c
  3. PURPOSE: Creation and access to an X windows interface
  4. to wet+sticky using Athena Widgets
  5. AUTHOR: David England
  6. VERSION: 1.00 (13-May-91)
  7. Copyright 1991, 1992, 2002, 2003 Tunde Cockshott, Kevin Waite, David England.
  8. Contact David England d.england@livjm.ac.uk
  9. School of Computing and Maths Sciences,
  10. Liverpool John Moores University
  11. Liverpool L3 3AF
  12. United Kingdom
  13. Phone +44 151 231 2271
  14. Wet and Sticky is free software; you can redistribute it and/or modify
  15. it under the terms of the GNU General Public License as published by
  16. the Free Software Foundation; either version 2 of the License, or (at
  17. your option) any later version. Wet and Sticky is distributed in the
  18. hope that it will be useful, but WITHOUT ANY WARRANTY; without even
  19. the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  20. PURPOSE. See the GNU General Public License for more details. You
  21. should have received a copy of the GNU General Public License along
  22. with Wet and Sticky; if not, write to the Free Software Foundation,
  23. Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  24. */
  25. #include <X11/Xos.h>
  26. #include <X11/Xlib.h>
  27. #include <X11/Xutil.h>
  28. #include <X11/Intrinsic.h>
  29. #include <X11/cursorfont.h>
  30. #include <X11/StringDefs.h>
  31. #include <X11/Shell.h>
  32. #include <X11/Xaw/Box.h>
  33. #include <X11/Xaw/Label.h>
  34. #include <stdio.h>
  35. #include "constants.h"
  36. #include "types.h"
  37. #include "engine.h"
  38. #include "canvas.h"
  39. /* Window Heirarchy -
  40. Three shell widgets, one for colour output, two for attributes output
  41. plus a back_up pixmap for redrawing
  42. */
  43. static Widget top_level;
  44. static Widget colour_shell;
  45. static Widget colour_box;
  46. static Widget colour_canvas;
  47. static Pixmap colour_pm;
  48. static Widget volume_shell;
  49. static Widget volume_box;
  50. static Widget volume_canvas;
  51. static Pixmap volume_pm;
  52. static Widget dryness_shell;
  53. static Widget dryness_box;
  54. static Widget dryness_canvas;
  55. static Pixmap dryness_pm;
  56. static GC gc;
  57. static GC tmp_gc;
  58. static long mask;
  59. static XGCValues values;
  60. static Colormap cmap;
  61. static XColor colours[256];
  62. void stroke();
  63. void stroke_motion();
  64. Display *display;
  65. int screen;
  66. Screen *screen_ptr;
  67. Window root;
  68. static int count=0;
  69. static int frame_count=0;
  70. char pix_file[64];
  71. static void
  72. expose_event(w, event)
  73. Widget w;
  74. XEvent *event;
  75. {
  76. /* Re-display the colour window if an exposure event is received */
  77. int width, height;
  78. width = height = 300;
  79. XCopyArea(XtDisplay(colour_canvas), colour_pm,
  80. XtWindow(colour_canvas), gc, 0, 0, width, height, 0,0);
  81. }
  82. static void
  83. expose_volume(w, event)
  84. Widget w;
  85. XEvent *event;
  86. {
  87. /* Re-display the volume window if an exposure event is received */
  88. int width, height;
  89. width = 300;
  90. height = 300;
  91. XCopyArea(XtDisplay(volume_canvas), volume_pm,
  92. XtWindow(volume_canvas), gc, 0, 0, width, height, 0,0);
  93. }
  94. static void
  95. expose_dryness(w, event)
  96. Widget w;
  97. XEvent *event;
  98. {
  99. /* Re-display the dryness window if an exposure event is received */
  100. int width, height;
  101. width = height = 300;
  102. XCopyArea(XtDisplay(dryness_canvas), dryness_pm,
  103. XtWindow(dryness_canvas), gc, 0, 0, width, height, 0,0);
  104. }
  105. void expose_canvases()
  106. {
  107. int width, height;
  108. width = height = 300;
  109. XCopyArea(XtDisplay(colour_canvas), colour_pm,
  110. XtWindow(colour_canvas), gc, 0, 0, width, height, 0,0);
  111. XCopyArea(XtDisplay(dryness_canvas), dryness_pm,
  112. XtWindow(dryness_canvas), gc, 0, 0, width, height, 0,0);
  113. XCopyArea(XtDisplay(dryness_canvas), dryness_pm,
  114. XtWindow(dryness_canvas), gc, 0, 0, 300, 300, 0,0);
  115. }
  116. int
  117. GetHueValue(red, green, blue)
  118. int red;
  119. int green;
  120. int blue;
  121. {
  122. XColor colour;
  123. colour.red = red * 257;
  124. colour.green = green * 257;
  125. colour.blue = blue * 257;
  126. colour.flags = DoRed | DoGreen | DoBlue;
  127. if (XAllocColor(display, cmap, &colour) == 0)
  128. fprintf(stderr,"colour allocation failed\n");
  129. return (colour.pixel);
  130. }
  131. void
  132. DrawPoint(x,y,colour)
  133. int x;
  134. int y;
  135. int colour;
  136. /* Draw a point on the window and the back-up Pixmap */
  137. {
  138. /* PROBS ? */
  139. XSetForeground(XtDisplay(top_level), gc, colours[colour].pixel);
  140. XDrawPoint(XtDisplay(top_level), XtWindow(colour_canvas), gc, x, y);
  141. XDrawPoint(XtDisplay(top_level), colour_pm, gc, x, y);
  142. }
  143. void
  144. DrawBackgroundPoint(x,y,colour)
  145. int x;
  146. int y;
  147. int colour;
  148. /* Draw a point on the window and the back-up Pixmap */
  149. {
  150. /* PROBS ? */
  151. XSetForeground(XtDisplay(top_level), gc, colours[colour].pixel);
  152. XDrawPoint(XtDisplay(top_level), colour_pm, gc, x, y);
  153. }
  154. int
  155. DrawVolumePoint(x,y,attr)
  156. int x;
  157. int y;
  158. int attr;
  159. /* Draw a point on the window and the back-up Pixmap */
  160. {
  161. if (XtWindow(volume_canvas) == NULL)
  162. return (-1);
  163. XSetForeground(XtDisplay(top_level), gc, colours[attr].pixel);
  164. XDrawPoint(XtDisplay(top_level), XtWindow(volume_canvas), gc, x, y);
  165. XDrawPoint(XtDisplay(top_level), volume_pm, gc, x, y);
  166. return(0);
  167. }
  168. int
  169. DrawBackgroundVolumePoint(x,y,attr)
  170. int x;
  171. int y;
  172. int attr;
  173. /* Draw a point on the window and the back-up Pixmap */
  174. {
  175. if (XtWindow(volume_canvas) == NULL)
  176. return (-1);
  177. XSetForeground(XtDisplay(top_level), gc, colours[attr].pixel);
  178. XDrawPoint(XtDisplay(top_level), volume_pm, gc, x, y);
  179. return(0);
  180. }
  181. int
  182. DrawDrynessPoint(x,y,attr)
  183. int x;
  184. int y;
  185. int attr;
  186. /* Draw a point on the window and the back-up Pixmap */
  187. {
  188. /* later - use the range of the dryness to affect the colour
  189. value
  190. */
  191. if (XtWindow(dryness_canvas) == NULL)
  192. return (-1);
  193. XSetForeground(XtDisplay(top_level), gc, colours[attr].pixel);
  194. /* XDrawPoint(XtDisplay(top_level), XtWindow(dryness_canvas), gc, x, y);
  195. */
  196. XDrawPoint(XtDisplay(top_level), dryness_pm, gc, x, y);
  197. return(0);
  198. }
  199. void
  200. ClearWindow()
  201. {
  202. XClearWindow(XtDisplay(top_level), XtWindow(colour_canvas));
  203. }
  204. static void
  205. CleanWindow(win)
  206. Drawable win;
  207. /* Fill a window with a solid, white rectangle */
  208. {
  209. XGCValues values;
  210. long mask;
  211. values.background = colours[0].pixel;
  212. values.foreground = colours[255].pixel;;
  213. values.fill_style = FillSolid;
  214. values.function = GXclear;
  215. mask = GCBackground| GCForeground| GCFillStyle | GCFunction;
  216. tmp_gc = XtGetGC(top_level, mask, &values);
  217. XFillRectangle(XtDisplay(top_level), win, tmp_gc, 0, 0, 300, 300);
  218. }
  219. void SetupCmap()
  220. {
  221. int i;
  222. for (i=0;i<256;i++) {
  223. colours[i].red = i*257;
  224. colours[i].flags = DoRed | DoBlue | DoGreen;
  225. }
  226. /* for (i=0;i<=127;i++)
  227. colours[i].green = i*2*257;
  228. for (i=128;i>0;i--)
  229. colours[255-i].green = (i-1)*2*257;*/
  230. for (i=0;i<64;i++)
  231. colours[i].green = i*4*257;
  232. for (i=64;i<128;i++)
  233. colours[i].green = 65536-i*4*257;
  234. for (i=128;i<192;i++)
  235. colours[i].green = (i-128)*2*257;
  236. for (i=192;i<255;i++)
  237. colours[i].green = 65536-(i-128)*2*257;
  238. for (i=0;i<256;i++)
  239. colours[i].blue = 65536 - i*257;
  240. colours[0].red = 65535;
  241. colours[0].green = 65535;
  242. colours[0].blue = 65535;
  243. }
  244. void
  245. SetupGreyMap()
  246. {
  247. int i;
  248. for (i=0;i<256;i++) {
  249. colours[i].red = i*257;
  250. colours[255 - i].flags = DoRed | DoBlue | DoGreen;
  251. }
  252. for (i=0;i<256;i++)
  253. colours[i].green = i*257;
  254. for (i=0;i<256;i++)
  255. colours[i].blue = i*257;
  256. colours[255].red = 255*257;
  257. colours[255].green = 255*257;
  258. colours[255].blue = 255*257;
  259. }
  260. void CreateWindows(argc, argv, width, height)
  261. int *argc;
  262. char **argv;
  263. int width;
  264. int height;
  265. /* Create colour window heirarchy and add event handlers */
  266. {
  267. static Arg args[]={
  268. {XtNwidth, (XtArgVal) 0},
  269. {XtNheight, (XtArgVal)0} };
  270. int i;
  271. args[0].value = (XtArgVal)width;
  272. args[1].value = (XtArgVal)height;
  273. top_level = XtInitialize("wet+sticky", "Wet+Sticky", NULL,
  274. 0, argc, argv);
  275. display = XtDisplay(top_level);
  276. screen = DefaultScreen(display);
  277. screen_ptr = ScreenOfDisplay(display, DefaultScreen(display));
  278. root = RootWindow(display, screen);
  279. colour_shell = XtCreateApplicationShell("colour_frame",
  280. topLevelShellWidgetClass, NULL, 0);
  281. colour_box = XtCreateManagedWidget("colour_box", boxWidgetClass,
  282. colour_shell, NULL, 0);
  283. colour_canvas = XtCreateManagedWidget("", labelWidgetClass,
  284. colour_box, args, XtNumber(args));
  285. XtAddEventHandler(colour_canvas, ExposureMask, False, expose_event, 0);
  286. XtAddEventHandler(colour_canvas, ButtonPressMask, False, stroke, 0);
  287. XtAddEventHandler(colour_canvas, Button1MotionMask,
  288. False, stroke_motion, 0);
  289. XtRealizeWidget(colour_shell);
  290. cmap = XCreateColormap( display, XtWindow(colour_shell),
  291. XDefaultVisualOfScreen(screen_ptr), AllocAll);
  292. for (i=0; i <= 255; i++)
  293. colours[i].pixel = i;
  294. XQueryColors(display, DefaultColormapOfScreen(screen_ptr),colours, 256);
  295. SetupCmap();
  296. /*SetupGreyMap();*/
  297. XStoreColors(display, cmap, colours, 256);
  298. i=0;
  299. while( XAllocColorCells( display, DefaultColormapOfScreen(screen_ptr),
  300. True, NULL, 0, &colours[i].pixel, 1 ) ) {
  301. colours[i].pixel = i;
  302. i++;
  303. }
  304. XSetWindowColormap(display, XtWindow(colour_shell), cmap);
  305. XInstallColormap(display, cmap);
  306. mask = GCBackground| GCForeground| GCFunction;
  307. values.function = GXcopy;
  308. values.background = colours[0].pixel;
  309. values.foreground = colours[255].pixel;
  310. gc = XtGetGC(colour_canvas, mask, &values);
  311. colour_pm = XCreatePixmap(XtDisplay(top_level),
  312. XtWindow(colour_shell), width, height,
  313. XDefaultDepth(XtDisplay(top_level), 0));
  314. CleanWindow(colour_pm);
  315. }
  316. void StartVolumeWindow(width, height)
  317. int width;
  318. int height;
  319. /* Create Volume heirarchy and add event handlers */
  320. {
  321. static Arg args[]={
  322. {XtNwidth, (XtArgVal) 0},
  323. {XtNheight, (XtArgVal)0} };
  324. args[0].value = (XtArgVal)width;
  325. args[1].value = (XtArgVal)height;
  326. volume_shell = XtCreateApplicationShell("volume_frame",
  327. topLevelShellWidgetClass, NULL, 0);
  328. volume_box = XtCreateManagedWidget("volume_box", boxWidgetClass,
  329. volume_shell, NULL, 0);
  330. volume_canvas = XtCreateManagedWidget("", labelWidgetClass,
  331. volume_box, args, XtNumber(args));
  332. XtAddEventHandler(volume_canvas, ExposureMask, False,
  333. expose_volume, 0);
  334. XtRealizeWidget(volume_shell);
  335. XSetWindowColormap(display, XtWindow(volume_shell), cmap);
  336. volume_pm = XCreatePixmap(XtDisplay(top_level),
  337. XtWindow(colour_shell), width, height,
  338. XDefaultDepth(XtDisplay(top_level), 0));
  339. CleanWindow(volume_pm);
  340. }
  341. void StartDrynessWindow(width, height)
  342. int width;
  343. int height;
  344. /* Create dryness heirarchy and add event handlers */
  345. {
  346. static Arg args[]={
  347. {XtNwidth, (XtArgVal) 0},
  348. {XtNheight, (XtArgVal)0} };
  349. char name[32];
  350. args[0].value = (XtArgVal)width;
  351. args[1].value = (XtArgVal)height;
  352. dryness_shell = XtCreateApplicationShell("dryness_frame",
  353. topLevelShellWidgetClass, NULL, 0);
  354. dryness_box = XtCreateManagedWidget("dryness_box", boxWidgetClass,
  355. dryness_shell, NULL, 0);
  356. dryness_canvas = XtCreateManagedWidget("Name", labelWidgetClass,
  357. dryness_box, args, XtNumber(args));
  358. fprintf(stderr,"Bumps %d\n",(int)dryness_canvas);
  359. XtAddEventHandler(dryness_canvas, ExposureMask, False,
  360. expose_dryness, 0);
  361. XtRealizeWidget(dryness_shell);
  362. XSetWindowColormap(display, XtWindow(dryness_shell), cmap);
  363. dryness_pm = XCreatePixmap(XtDisplay(top_level),
  364. XtWindow(colour_shell), width, height,
  365. XDefaultDepth(XtDisplay(top_level), 0));
  366. XStoreName(display, XtWindow(dryness_shell), "bumps");
  367. CleanWindow(dryness_pm);
  368. }
  369. static void
  370. draw_labels()
  371. {
  372. XSetForeground(XtDisplay(colour_shell), gc, colours[1].pixel);
  373. XDrawString(XtDisplay(colour_shell), XtWindow(colour_canvas), gc, 10, 10,
  374. "Colour", strlen("Colour"));
  375. XDrawString(XtDisplay(colour_shell), colour_pm, gc, 10, 10,
  376. "Colour", strlen("Colour"));
  377. XSetForeground(XtDisplay(colour_shell), gc, colours[128].pixel);
  378. XDrawString(XtDisplay(colour_shell), XtWindow(volume_canvas), gc, 10, 10,
  379. "Volume", strlen("Volume"));
  380. XDrawString(XtDisplay(colour_shell), volume_pm, gc, 10, 10,
  381. "Volume", strlen("Volume"));
  382. XSetForeground(XtDisplay(colour_shell), gc, colours[255].pixel);
  383. XDrawString(XtDisplay(colour_shell), XtWindow(dryness_canvas), gc, 10, 10,
  384. "Bump Map", strlen("Bump Map"));
  385. XDrawString(XtDisplay(colour_shell), dryness_pm, gc, 10, 10,
  386. "Bump Map", strlen("Bump Map"));
  387. }
  388. void paint_cell(cell, x, y)
  389. CELL_PTR cell;
  390. int x, y;
  391. {
  392. int colour, volColour, dryness;
  393. POINT p;
  394. p.x = x;
  395. p.y = y;
  396. /* The current display simply maps hue onto the indices of the colour
  397. table. This involves some scaling since hues are in the range [0,360)
  398. with the colour table being [0,256). */
  399. colour = (int) (cell->contents.colour.hue *
  400. ((float) MAX_COLOUR_INDEX / 360.0));
  401. DrawBackgroundPoint(x,y,colour);
  402. /* volColour is an index into the colour table in the range [0,255].
  403. It is used to give a false colour image of the canvas's volume. */
  404. /*if (x < SCALE_WIDTH) return; Don't draw over colour scale. */
  405. volColour = MIN(cell->volume * 2, 255);
  406. volColour = MAX(volColour, 0);
  407. /* Make unfilled cells have a zero vol. */
  408. DrawBackgroundVolumePoint(x,y,volColour);
  409. /* Dryness will be in the range [0,255]. */
  410. dryness = (cell->contents.liquid_content * 255) / 100;
  411. /*DrawDrynessPoint(x,y,dryness);*/
  412. }
  413. void draw_false_colour_scale()
  414. /* This routine places a scale along the top of the volume window
  415. showing the colours being used. Low is at the left edge.
  416. The colour palette has indices 0..255. */
  417. {
  418. int x, y;
  419. /*for (x=0; x < 255; x++)
  420. for (y=0; y < SCALE_WIDTH; y++) DrawVolumePoint(x,y,MIN(x, 255));*/
  421. }
  422. void draw_full_canvas()
  423. {
  424. int x, y;
  425. CELL_PTR cell;
  426. POINT p;
  427. if (DEBUG) {
  428. printf ("Starting to paint full canvas...");
  429. fflush(stdout);
  430. }
  431. for (y=0; y < CANVAS_HEIGHT; y++)
  432. for (x=0; x < CANVAS_WIDTH; x++) {
  433. p.x = x;
  434. p.y = y;
  435. cell = get_cell(p);
  436. paint_cell(cell, x, y);
  437. }
  438. expose_canvases();
  439. draw_false_colour_scale();
  440. if (DEBUG) printf ("done.\n");
  441. }
  442. void
  443. bump_map()
  444. {
  445. POINT p;
  446. CELL_PTR cell;
  447. register int x, y;
  448. register int colour;
  449. for (y=0; y < CANVAS_HEIGHT; y++) {
  450. for (x=0; x < CANVAS_WIDTH; x++) {
  451. p.x = x;
  452. p.y = y;
  453. cell = get_cell(p);
  454. colour = (int) new_intensity_value(p);
  455. /* colour = (int) (cell->contents.colour.hue *
  456. ((float) MAX_COLOUR_INDEX / 360.0));*/
  457. DrawDrynessPoint(x,y,colour);
  458. }
  459. }
  460. }
  461. draw_cmap_line()
  462. {
  463. int i;
  464. for (i=0; i< 255; i++) {
  465. DrawDrynessPoint(0,i,i);
  466. }
  467. }
  468. void evolve_paint()
  469. {
  470. int k;
  471. POINT p;
  472. CELL_PTR cell;
  473. int new_x, new_y;
  474. Window tempChild;
  475. extern Window root;
  476. extern int count;
  477. extern int frame_count;
  478. count++;
  479. if (count > 5000) {
  480. fprintf(stderr,".");
  481. fflush(stderr);
  482. bump_map();
  483. expose_canvases();
  484. /*XTranslateCoordinates(display,XtWindow(dryness_canvas), root,
  485. 0,0, &new_x, &new_y, &tempChild);*/
  486. /*if (frame_count < 10)
  487. sprintf(pix_file,"xwd -name bumps -out pixmap0%d.xwd &" ,frame_count);
  488. else
  489. sprintf(pix_file,"xwd -name bumps -out pixmap%d.xwd &" ,frame_count);
  490. */
  491. /*system(pix_file);*/
  492. /*XWriteBitmapFile(display, pix_file,dryness_pm, 300, 300,-1,-1 );*/
  493. count = 0;
  494. frame_count++;
  495. /*if (frame_count > 250) {
  496. fprintf(stderr,"Done\n");
  497. sleep(2);
  498. exit(0);
  499. } */
  500. /*exit(0)*/;
  501. }
  502. for (k=0; k < STEP_LIMIT; k++) single_step();
  503. while (TRUE) {
  504. next_cell_for_repaint(&cell, &p);
  505. if (cell == NIL) return;
  506. paint_cell(cell, p.x, p.y);
  507. }
  508. }
  509. void StartWindows()
  510. {
  511. /* Start the X windows event loop and paint processing */
  512. XEvent event;
  513. draw_full_canvas();
  514. compute_shade_vectors(); /* Set vectors for shading */
  515. draw_labels();
  516. for (;;) {
  517. if (XtPending()) {
  518. XtNextEvent(&event);
  519. XtDispatchEvent(&event);
  520. }
  521. else {
  522. /* Evolve paint and re-display*/
  523. evolve_paint();
  524. }
  525. } /* End for loop */
  526. }
  527. void
  528. stroke(w, client_data, event)
  529. Widget w;
  530. caddr_t client_data;
  531. XEvent *event;
  532. {
  533. /* brush_stroke(event->xbutton.x, event->xbutton.y);*/
  534. /*if ((XEvent *)event != (XEvent *)NULL)
  535. else
  536. printf("Null event\n"); */
  537. /* DrawPoint(event->xbutton.x, event->xbutton.y, 128);
  538. DrawVolumePoint(event->xbutton.x, event->xbutton.y, 128);
  539. DrawDrynessPoint(event->xbutton.x, event->xbutton.y, 128);*/
  540. XSetForeground(XtDisplay(top_level), gc, colours[128].pixel);
  541. XFillRectangle(XtDisplay(top_level), XtWindow(colour_canvas), gc,
  542. event->xmotion.x, event->xmotion.y ,1, 1);
  543. XFillRectangle(XtDisplay(top_level), XtWindow(volume_canvas), gc,
  544. event->xmotion.x, event->xmotion.y ,1, 1);
  545. XFillRectangle(XtDisplay(top_level), XtWindow(dryness_canvas), gc,
  546. event->xmotion.x, event->xmotion.y ,1, 1);
  547. brush_stroke(event->xbutton.x, event->xbutton.y);
  548. }
  549. void
  550. stroke_motion(w, client_data, event)
  551. Widget w;
  552. caddr_t client_data;
  553. XEvent *event;
  554. {
  555. /*if ((XEvent *)event != (XEvent *)NULL)
  556. else
  557. printf("Null event\n"); */
  558. XSetForeground(XtDisplay(top_level), gc, colours[128].pixel);
  559. XFillRectangle(XtDisplay(top_level), XtWindow(colour_canvas), gc,
  560. event->xmotion.x, event->xmotion.y ,1, 1);
  561. XFillRectangle(XtDisplay(top_level), XtWindow(volume_canvas), gc,
  562. event->xmotion.x, event->xmotion.y ,1, 1);
  563. XFillRectangle(XtDisplay(top_level), XtWindow(dryness_canvas), gc,
  564. event->xmotion.x, event->xmotion.y ,1, 1);
  565. brush_stroke(event->xbutton.x, event->xbutton.y);
  566. }