new_init_graphics.c 39 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409
  1. /*--------------------------------------------------------------------
  2. new_init_graphics.c
  3. Programmed by: Kenneth Sakai
  4. Company : Lockheed Martin
  5. Date : 3-6-00
  6. Note: The following code is not meant necessarily to be commercial grade
  7. code. It is just meant to be better than the original grad-student version.
  8. K.S.
  9. --------------------------------------------------------------------
  10. */
  11. #include <stdio.h>
  12. #include "vizual.h"
  13. #include <grass/config.h>
  14. #include <Xm/Xm.h>
  15. #include <Xm/Form.h>
  16. /* include file for GL drawing widget */
  17. #ifdef HAVE_GL_GLWMDRAWA_H
  18. #include <GL/GLwMDrawA.h>
  19. #else
  20. #ifdef HAVE_X11_GLW_GLWMDRAWA_H
  21. #include <X11/GLw/GLwMDrawA.h>
  22. #endif
  23. #endif
  24. #include "Ball.h"
  25. BallData Trackball;
  26. #include "kns_defines.h"
  27. #include "kns_globals.h"
  28. #include <X11/Xlib.h>
  29. #include <X11/extensions/XI.h>
  30. #include <X11/extensions/XInput.h>
  31. #include <X11/Xutil.h>
  32. #include <X11/keysym.h>
  33. #define MAXTHRESHOLDS 200
  34. static Widget Threshbutton[MAXTHRESHOLDS];
  35. static Widget Button_plus;
  36. static Widget Button_minus;
  37. static Widget SingleToggle, MultipleToggle;
  38. static Widget ThresholdRadio;
  39. static Widget PlotSelected;
  40. static int MultipleThresholdFlag;
  41. static int ProceedStatus;
  42. static GLuint FontBase;
  43. static int Attributes[] = { GLX_RGBA, GLX_DEPTH_SIZE, 16, GLX_RED_SIZE, 1,
  44. GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1, GLX_DOUBLEBUFFER, None
  45. };
  46. static int SingleAttributes[] = { GLX_RGBA, GLX_RED_SIZE, 1,
  47. GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1, GLX_DOUBLEBUFFER, None
  48. };
  49. static int RotationEnabled;
  50. void glinitCB(Widget widget, XtPointer client_data, XtPointer cdata);
  51. void glexposeCB(Widget widget, XtPointer client_data, XtPointer cdata);
  52. void glinputCB(Widget widget, XtPointer client_data, XtPointer cdata);
  53. void glresizeCB(Widget widget, XtPointer client_data, XtPointer cdata);
  54. void glexpose2CB(Widget widget, XtPointer client_data, XtPointer cdata);
  55. void glresize2CB(Widget widget, XtPointer client_data, XtPointer cdata);
  56. void ThresholdCB(Widget widget, XtPointer client_data, XtPointer call_data);
  57. void PlusMinusCB(Widget widget, XtPointer client_data, XtPointer call_data);
  58. void SingleMultipleCB(Widget widget, XtPointer client_data, XtPointer cdata);
  59. void PlotSelectedCB(Widget widget, XtPointer client_data, XtPointer cdata);
  60. void set_threshold_button(int iset);
  61. void draw_ctable();
  62. void rotateLoop();
  63. void draw_multiple();
  64. /*-------------------------------------------------------------------
  65. get_trackball_rotation_matrix()
  66. This functions retrieves the current trackball rotation matrix.
  67. -------------------------------------------------------------------
  68. */
  69. void get_trackball_rotation_matrix(float mat[4][4])
  70. {
  71. int i, j;
  72. HMatrix mNow;
  73. Ball_Value(&Trackball, mNow);
  74. for (i = 0; i < QuatLen; i++)
  75. for (j = 0; j < QuatLen; j++)
  76. mat[i][j] = mNow[i][j];
  77. }
  78. /*-------------------------------------------------------------------
  79. This functions set the trackball state based upon the set of rotation
  80. angles contained in the dspect struct.
  81. -------------------------------------------------------------------
  82. */
  83. void set_trackball_rotations(struct dspec *D_spec)
  84. {
  85. GLfloat tranmat[4][4];
  86. glPushMatrix();
  87. glLoadIdentity();
  88. glRotatef(.1 * (D_spec->yrot * 10), 0., 1., 0.);
  89. glRotatef(.1 * (D_spec->zrot * 10), 0., 0., 1.);
  90. glRotatef(.1 * (D_spec->xrot * 10), 1., 0., 0.);
  91. glGetFloatv(GL_MODELVIEW_MATRIX, (GLfloat *) tranmat);
  92. Ball_SetMatrix(&Trackball, tranmat);
  93. glPopMatrix();
  94. }
  95. /*-------------------------------------------------------------------
  96. new_swapbuffers()
  97. This is an OpenGL version of the IRISGL swapbuffers() function.
  98. -------------------------------------------------------------------
  99. */
  100. void new_swapbuffers()
  101. {
  102. glXSwapBuffers(XtDisplay(MainOGLWindow.widget), MainOGLWindow.window);
  103. }
  104. /*-------------------------------------------------------------------
  105. enableRotation()
  106. -------------------------------------------------------------------
  107. */
  108. void enableRotation()
  109. {
  110. RotationEnabled = 1;
  111. }
  112. /*-------------------------------------------------------------------
  113. disableRotation()
  114. -------------------------------------------------------------------
  115. */
  116. void disableRotation()
  117. {
  118. RotationEnabled = 0;
  119. }
  120. /*-------------------------------------------------------------------
  121. new_swapbuffers()
  122. This is a substitute for the IRISGL getsize() function.
  123. -------------------------------------------------------------------
  124. */
  125. void new_getsize(long *x, long *y)
  126. {
  127. *x = MainOGLWindow.width;
  128. *y = MainOGLWindow.height;
  129. }
  130. /*-------------------------------------------------------------------
  131. initializeFonts()
  132. This function initializes the OpenGL display lists required for drawing
  133. 2D text in a 3D window. FontBase will end up pointing to a sequence
  134. of display lists in which each individual display charactor in a font.
  135. The font chosen in a Courier Bold font chosen to match the font used
  136. by the IRISGL charstr() function.
  137. -------------------------------------------------------------------
  138. */
  139. void initializeFonts()
  140. {
  141. XFontStruct *fontInfo;
  142. Font id;
  143. GLuint base;
  144. unsigned int first, last;
  145. fontInfo = XLoadQueryFont(XtDisplay(MainOGLWindow.widget),
  146. "-adobe-courier-bold-r-normal--14-100-100-100-m-90-iso8859-1");
  147. id = fontInfo->fid;
  148. first = fontInfo->min_char_or_byte2;
  149. last = fontInfo->max_char_or_byte2;
  150. base = glGenLists((GLuint) last + 1);
  151. glXUseXFont(id, first, last - first + 1, base + first);
  152. XFreeFont(XtDisplay(MainOGLWindow.widget), fontInfo);
  153. FontBase = base;
  154. }
  155. /*-------------------------------------------------------------------
  156. new_charstr()
  157. This is an OpenGL version of the IRISGL charstr() function. The initializeFonts
  158. function must have been called prior to calling this function.
  159. -------------------------------------------------------------------
  160. */
  161. void new_charstr(char *str)
  162. {
  163. glPushAttrib(GL_LIST_BIT);
  164. glListBase(FontBase);
  165. glCallLists(strlen(str), GL_UNSIGNED_BYTE, (GLubyte *) str);
  166. glPopAttrib();
  167. }
  168. /*-------------------------------------------------------------------
  169. winset_main()
  170. This function is the equivalent of the IRISGL winset command for
  171. the main 3D drawing window.
  172. -------------------------------------------------------------------
  173. */
  174. void winset_main()
  175. {
  176. glXMakeCurrent(XtDisplay(MainOGLWindow.widget), MainOGLWindow.window,
  177. MainOGLWindow.glx_context);
  178. }
  179. /*-------------------------------------------------------------------
  180. loadrect()
  181. This function loads a file created via the loadrect() function into the
  182. framebuffer ff the main 3D drawing window
  183. -------------------------------------------------------------------
  184. */
  185. int loadrect(char *name)
  186. {
  187. FILE *fp;
  188. unsigned long *buffer;
  189. float xd, yd, zd, trd;
  190. float aspect;
  191. int xsiz, ysiz;
  192. long xsiz2, ysiz2;
  193. new_getsize(&xsiz2, &ysiz2);
  194. winset_main();
  195. fp = fopen(name, "r");
  196. if (!fp) {
  197. fprintf(stderr, "Unable to open file <%s>\n", name);
  198. G_free(buffer);
  199. return 0;
  200. }
  201. fread(&xsiz, sizeof(int), 1, fp);
  202. fread(&ysiz, sizeof(int), 1, fp);
  203. if (NULL ==
  204. (buffer = (unsigned long *)G_malloc(xsiz * ysiz * sizeof(long)))) {
  205. fprintf(stderr, "Out of memory\n");
  206. return -1;
  207. }
  208. if (ysiz != fread(buffer, xsiz * sizeof(long), ysiz, fp))
  209. fprintf(stderr, "Unable to write file <%s>\n", name);
  210. clear_screen();
  211. glMatrixMode(GL_PROJECTION);
  212. glLoadIdentity();
  213. glOrtho(0, xsiz2, 0, ysiz2, -100., 10);
  214. glMatrixMode(GL_MODELVIEW);
  215. glLoadIdentity();
  216. glRasterPos2i(0, 0);
  217. glDrawPixels(xsiz, ysiz, GL_RGBA, GL_BYTE, buffer);
  218. glXSwapBuffers(XtDisplay(MainOGLWindow.widget), MainOGLWindow.window);
  219. fclose(fp);
  220. G_free(buffer);
  221. aspect = (float)MainOGLWindow.width / (float)MainOGLWindow.height;
  222. glMatrixMode(GL_PROJECTION);
  223. glLoadIdentity();
  224. gluPerspective(45., aspect, .10, 1000.0);
  225. glMatrixMode(GL_MODELVIEW);
  226. glLoadIdentity();
  227. xd = Headfax.xdim * MainOGLWindow.ptr_D_spec->xscale;
  228. yd = Headfax.ydim * MainOGLWindow.ptr_D_spec->yscale;
  229. zd = Headfax.zdim * MainOGLWindow.ptr_D_spec->zscale;
  230. /* pick greatest dimension to use for translation of viewer from origin */
  231. if (xd < yd)
  232. trd = yd;
  233. else
  234. trd = xd;
  235. if (trd < zd)
  236. trd = zd;
  237. glTranslatef(0.0, 0.0, -trd * 1.6);
  238. return (0);
  239. }
  240. /*-------------------------------------------------------------------
  241. dumprect()
  242. This function dumps the framebuffer from the main 3D drawing window
  243. into a file.
  244. -------------------------------------------------------------------
  245. */
  246. int dumprect(char *name)
  247. {
  248. FILE *fp;
  249. long xsiz, ysiz;
  250. unsigned long *buffer;
  251. new_getsize(&xsiz, &ysiz);
  252. if (NULL ==
  253. (buffer = (unsigned long *)G_malloc(xsiz * ysiz * sizeof(long)))) {
  254. fprintf(stderr, "Out of memory\n");
  255. return -1;
  256. }
  257. winset_main();
  258. fp = fopen(name, "w");
  259. if (!fp) {
  260. fprintf(stderr, "Unable to open file <%s>\n", name);
  261. G_free(buffer);
  262. return 0;
  263. }
  264. /* write dims */
  265. fwrite(&xsiz, sizeof(int), 1, fp);
  266. fwrite(&ysiz, sizeof(int), 1, fp);
  267. glReadBuffer(GL_FRONT);
  268. glReadPixels(0, 0, xsiz, ysiz, GL_RGBA, GL_BYTE, buffer);
  269. if (ysiz != fwrite(buffer, xsiz * sizeof(long), ysiz, fp))
  270. fprintf(stderr, "Unable to write file <%s>\n", name);
  271. fclose(fp);
  272. G_free(buffer);
  273. return (0);
  274. }
  275. /*-------------------------------------------------------------------
  276. dumpgif()
  277. This function dumps the framebuffer from the main 3D drawing window
  278. into a GIF file.
  279. -------------------------------------------------------------------
  280. */
  281. #define CPACKTORGBA(l,r,g,b,a) \
  282. (r) = ((l)>>0) & 0xff; \
  283. (g) = ((l)>>8) & 0xff; \
  284. (b) = ((l)>>16) & 0xff; \
  285. (a) = ((l)>>24) & 0xff;
  286. #include "togif.h"
  287. int dumpgif(char *name)
  288. {
  289. FILE *fp;
  290. long xwid, ywid;
  291. unsigned long *pixels;
  292. long numpixels;
  293. vgl_GIFWriter *writer;
  294. int i;
  295. unsigned short red, green, blue, alpha;
  296. new_getsize(&xwid, &ywid);
  297. if (xwid % 2)
  298. xwid--;
  299. if (ywid % 2)
  300. ywid--;
  301. if (NULL ==
  302. (pixels = (unsigned long *)G_malloc(xwid * ywid * sizeof(long)))) {
  303. fprintf(stderr, "Out of memory\n");
  304. return -1;
  305. }
  306. winset_main();
  307. fp = fopen(name, "wb");
  308. if (!fp) {
  309. fprintf(stderr, "Unable to open file <%s>\n", name);
  310. G_free(pixels);
  311. return 0;
  312. }
  313. glReadBuffer(GL_FRONT);
  314. glReadPixels(0, 0, xwid, ywid, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
  315. numpixels = xwid * ywid;
  316. for (i = 0; i < numpixels; i++) {
  317. CPACKTORGBA(pixels[i], red, green, blue, alpha);
  318. #ifdef WIN32
  319. pixels[i] = red | (green << 8) | (blue << 16) | (alpha << 24);
  320. #else
  321. pixels[i] = alpha | (blue << 8) | (green << 16) | (red << 24);
  322. #endif
  323. }
  324. writer = vgl_GIFWriterBegin();
  325. vgl_GIFWriterWriteGIFFile(writer, pixels, xwid, ywid, 0, fp);
  326. fclose(fp);
  327. G_free(pixels);
  328. return (0);
  329. }
  330. /*-------------------------------------------------------------------
  331. winset_colortable()
  332. This function is the equivalent of the IRISGL winset command for
  333. the colormap window.
  334. -------------------------------------------------------------------
  335. */
  336. void winset_colortable()
  337. {
  338. glXMakeCurrent(XtDisplay(ColormapWindow.widget), ColormapWindow.window,
  339. ColormapWindow.glx_context);
  340. }
  341. /*-------------------------------------------------------------------
  342. init_graphics()
  343. This function creates both the main 3D drawing window and the 2D
  344. colormap window.
  345. -------------------------------------------------------------------
  346. */
  347. #include <Xm/PushB.h>
  348. #include <Xm/RowColumn.h>
  349. #include <Xm/Label.h>
  350. #include <Xm/ToggleB.h>
  351. #include <Xm/Frame.h>
  352. #include <Xm/SeparatoG.h>
  353. #include <grass/gis.h>
  354. static String Fallback_resources[] = {
  355. "*.fontList:-adobe-helvetica-bold-r-normal--12-120-75-75-p-70-iso8859-1",
  356. "*Thresholds.fontList:-adobe-helvetica-bold-r-normal--17-120-100-100-p-92-iso8859-1",
  357. };
  358. void init_graphics(char *name, int argc, char **argv, struct dspec *dspecptr)
  359. {
  360. int n;
  361. Arg args[20]; /* array used to set widget resources */
  362. XVisualInfo *vi;
  363. XEvent event;
  364. Widget toplevel, form;
  365. int i;
  366. char buffer[20];
  367. Widget separator;
  368. Widget gl_shell;
  369. Widget buttonrowcol, label1, radio;
  370. Widget frame;
  371. MainOGLWindow.ptr_D_spec = dspecptr;
  372. n = 0;
  373. XtSetArg(args[n], XmNwidth, 660);
  374. n++;
  375. XtSetArg(args[n], XmNheight, 600);
  376. n++;
  377. XtSetArg(args[n], XmNx, 10);
  378. n++;
  379. XtSetArg(args[n], XmNy, 100);
  380. n++;
  381. toplevel = XtAppInitialize(&App_context, "Showdspf", NULL,
  382. 0, &argc, argv, Fallback_resources, args, n);
  383. /*
  384. * Create the 3D drawing window
  385. */
  386. n = 0;
  387. XtSetArg(args[n], XmNwidth, 660);
  388. n++;
  389. XtSetArg(args[n], XmNheight, 600);
  390. n++;
  391. XtSetArg(args[n], XmNx, 10);
  392. n++;
  393. XtSetArg(args[n], XmNy, 100);
  394. n++;
  395. form = XmCreateForm(toplevel, "form", args, n);
  396. XtManageChild(form);
  397. vi = glXChooseVisual(XtDisplay(form), DefaultScreen(XtDisplay(form)),
  398. Attributes);
  399. if (!vi) {
  400. fprintf(stderr, "Fatal error: Couldn't get a visual\n");
  401. fprintf(stderr, "See program developer.\n");
  402. exit(1);
  403. }
  404. n = 0;
  405. XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM);
  406. n++;
  407. XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM);
  408. n++;
  409. XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM);
  410. n++;
  411. XtSetArg(args[n], XmNshadowThickness, 3);
  412. n++;
  413. XtSetArg(args[n], XmNshadowType, XmSHADOW_OUT);
  414. n++;
  415. frame = XmCreateFrame(form, "frame_r", args, n);
  416. XtManageChild(frame);
  417. n = 0;
  418. XtSetArg(args[n], XmNentryAlignment, XmALIGNMENT_CENTER);
  419. n++;
  420. XtSetArg(args[n], XmNpacking, XmPACK_TIGHT);
  421. n++;
  422. XtSetArg(args[n], XmNorientation, XmVERTICAL);
  423. n++;
  424. XtSetArg(args[n], XmNnumColumns, 1);
  425. n++;
  426. XtSetArg(args[n], XmNmarginHeight, 0);
  427. n++;
  428. XtSetArg(args[n], XmNmarginWidth, 0);
  429. n++;
  430. buttonrowcol = XmCreateRowColumn(frame, "rowcol", args, n);
  431. XtManageChild(buttonrowcol);
  432. label1 = XmCreateLabel(buttonrowcol, "Thresholds", args, n);
  433. XtManageChild(label1);
  434. n = 0;
  435. XtSetArg(args[n], XmNshadowThickness, 5);
  436. n++;
  437. separator = XmCreateSeparatorGadget(buttonrowcol, "separator1", args, n);
  438. XtManageChild(separator);
  439. n = 0;
  440. radio = XmCreateRadioBox(buttonrowcol, "radio", args, n);
  441. XtManageChild(radio);
  442. n = 0;
  443. SingleToggle =
  444. XtVaCreateManagedWidget("Single", xmToggleButtonWidgetClass, radio,
  445. NULL);
  446. XtAddCallback(SingleToggle, XmNarmCallback, SingleMultipleCB,
  447. (XtPointer) 1);
  448. MultipleToggle =
  449. XtVaCreateManagedWidget("Multiple", xmToggleButtonWidgetClass, radio,
  450. NULL);
  451. XtAddCallback(MultipleToggle, XmNarmCallback, SingleMultipleCB,
  452. (XtPointer) 0);
  453. XmToggleButtonSetState(SingleToggle, True, False);
  454. n = 0;
  455. XtSetArg(args[n], XmNshadowThickness, 5);
  456. n++;
  457. separator = XmCreateSeparatorGadget(buttonrowcol, "separator1", args, n);
  458. XtManageChild(separator);
  459. n = 0;
  460. Button_plus =
  461. XtCreateManagedWidget("Increase", xmPushButtonWidgetClass,
  462. buttonrowcol, args, n);
  463. XtAddCallback(Button_plus, XmNactivateCallback, PlusMinusCB,
  464. (XtPointer) 1);
  465. Button_minus =
  466. XtCreateManagedWidget("Decrease", xmPushButtonWidgetClass,
  467. buttonrowcol, args, n);
  468. XtAddCallback(Button_minus, XmNactivateCallback, PlusMinusCB,
  469. (XtPointer) 0);
  470. n = 0;
  471. PlotSelected = XmCreatePushButton(buttonrowcol, "Plot Selected", args, n);
  472. XtAddCallback(PlotSelected, XmNactivateCallback, PlotSelectedCB, NULL);
  473. n = 0;
  474. ThresholdRadio = XmCreateRadioBox(buttonrowcol, "radio", args, n);
  475. XtManageChild(ThresholdRadio);
  476. if (Headfax.linefax.nthres) {
  477. for (i = 1; i <= Headfax.linefax.nthres; i++) {
  478. n = 0;
  479. if (i <= MAXTHRESHOLDS) {
  480. sprintf(buffer, "Threshold %d", i);
  481. Threshbutton[i - 1] =
  482. XtVaCreateManagedWidget(buffer, xmToggleButtonWidgetClass,
  483. ThresholdRadio, NULL);
  484. XtAddCallback(Threshbutton[i - 1], XmNarmCallback,
  485. ThresholdCB, (XtPointer) (i - 1));
  486. }
  487. }
  488. XmToggleButtonSetState(Threshbutton[0], True, False);
  489. }
  490. n = 0;
  491. XtSetArg(args[n], XmNrightAttachment, XmATTACH_WIDGET);
  492. n++;
  493. XtSetArg(args[n], XmNrightWidget, frame);
  494. n++;
  495. XtSetArg(args[n], GLwNvisualInfo, vi);
  496. n++;
  497. XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM);
  498. n++;
  499. XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM);
  500. n++;
  501. XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM);
  502. n++;
  503. MainOGLWindow.widget = GLwCreateMDrawingArea(form, "glwidget", args, n);
  504. XtManageChild(MainOGLWindow.widget);
  505. XtAddCallback(MainOGLWindow.widget, GLwNginitCallback, glinitCB, 0);
  506. XtAddCallback(MainOGLWindow.widget, GLwNexposeCallback, glexposeCB, 0);
  507. XtAddCallback(MainOGLWindow.widget, GLwNinputCallback, glinputCB, 0);
  508. XtAddCallback(MainOGLWindow.widget, GLwNresizeCallback, glresizeCB, 0);
  509. /*
  510. * Create the colormap window
  511. */
  512. n = 0;
  513. XtSetArg(args[n], XmNwidth, 100);
  514. n++;
  515. XtSetArg(args[n], XmNheight, 500);
  516. n++;
  517. XtSetArg(args[n], XmNx, 5);
  518. n++;
  519. XtSetArg(args[n], XmNy, 5);
  520. n++;
  521. gl_shell = XtAppCreateShell("Colormap", "GL_window",
  522. topLevelShellWidgetClass, XtDisplay(toplevel),
  523. args, n);
  524. n = 0;
  525. XtSetArg(args[n], XmNwidth, 100);
  526. n++;
  527. XtSetArg(args[n], XmNheight, 500);
  528. n++;
  529. XtSetArg(args[n], XmNx, 5);
  530. n++;
  531. XtSetArg(args[n], XmNy, 5);
  532. n++;
  533. form = XmCreateForm(gl_shell, "form", args, n);
  534. XtManageChild(form);
  535. vi = glXChooseVisual(XtDisplay(form), DefaultScreen(XtDisplay(form)),
  536. SingleAttributes);
  537. if (!vi) {
  538. fprintf(stderr, "Fatal error: Couldn't get a visual\n");
  539. fprintf(stderr, "See program developer.\n");
  540. exit(1);
  541. }
  542. n = 0;
  543. XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM);
  544. n++;
  545. XtSetArg(args[n], GLwNvisualInfo, vi);
  546. n++;
  547. XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM);
  548. n++;
  549. XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM);
  550. n++;
  551. XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM);
  552. n++;
  553. ColormapWindow.widget = GLwCreateMDrawingArea(form, "glwidget", args, n);
  554. XtManageChild(ColormapWindow.widget);
  555. XtAddCallback(ColormapWindow.widget, GLwNginitCallback, glinitCB,
  556. (void *)1);
  557. XtAddCallback(ColormapWindow.widget, GLwNexposeCallback, glexpose2CB, 0);
  558. XtAddCallback(ColormapWindow.widget, GLwNresizeCallback, glresize2CB, 0);
  559. XtRealizeWidget(toplevel);
  560. XStoreName(XtDisplay(toplevel), XtWindow(toplevel), name);
  561. XtPopup(gl_shell, XtGrabNone);
  562. XMapRaised(XtDisplay(gl_shell), XtWindow(gl_shell));
  563. while (ProceedStatus < 4) {
  564. XtAppNextEvent(App_context, &event);
  565. XtDispatchEvent(&event);
  566. }
  567. }
  568. /*-------------------------------------------------------------------
  569. ThresholdCB()
  570. This is a Motif callback that is called when one of the threshold toggle
  571. buttons is hit.
  572. -------------------------------------------------------------------
  573. */
  574. void ThresholdCB(Widget widget, XtPointer client_data, XtPointer call_data)
  575. {
  576. int num = (int)client_data;
  577. if (MultipleThresholdFlag)
  578. return;
  579. MainOGLWindow.ptr_D_spec->Thresh = num;
  580. do_draw_immediate_mode();
  581. }
  582. /*-------------------------------------------------------------------
  583. PlusMinusCB()
  584. This is a Motif callback that is called when either the "Increase" or
  585. "Decrease" button is hit in the GUI interface.
  586. -------------------------------------------------------------------
  587. */
  588. void PlusMinusCB(Widget widget, XtPointer client_data, XtPointer call_data)
  589. {
  590. int flag = (int)client_data;
  591. if (flag) {
  592. MainOGLWindow.ptr_D_spec->Thresh++;
  593. if (MainOGLWindow.ptr_D_spec->Thresh > Headfax.linefax.nthres - 1)
  594. MainOGLWindow.ptr_D_spec->Thresh = 0;
  595. set_threshold_button(MainOGLWindow.ptr_D_spec->Thresh + 1);
  596. do_draw_immediate_mode();
  597. }
  598. else {
  599. MainOGLWindow.ptr_D_spec->Thresh--;
  600. if (MainOGLWindow.ptr_D_spec->Thresh < 0)
  601. MainOGLWindow.ptr_D_spec->Thresh = Headfax.linefax.nthres - 1;
  602. set_threshold_button(MainOGLWindow.ptr_D_spec->Thresh + 1);
  603. do_draw_immediate_mode();
  604. }
  605. }
  606. /*-------------------------------------------------------------------
  607. set_threshold_button(int iset)
  608. This function sets the GUI toggle button corresponding to a threshold value
  609. -------------------------------------------------------------------
  610. */
  611. void set_threshold_button(int iset)
  612. {
  613. int i;
  614. for (i = 1; i <= Headfax.linefax.nthres; i++) {
  615. if (i == iset) {
  616. if (i <= MAXTHRESHOLDS)
  617. XmToggleButtonSetState(Threshbutton[i - 1], True, False);
  618. }
  619. else {
  620. if ((i <= MAXTHRESHOLDS) && !MultipleThresholdFlag)
  621. XmToggleButtonSetState(Threshbutton[i - 1], False, False);
  622. }
  623. }
  624. }
  625. /*-------------------------------------------------------------------
  626. unset_threshold_button(int iset)
  627. This function unsets the GUI toggle button corresponding to a threshold value
  628. -------------------------------------------------------------------
  629. */
  630. void unset_threshold_button(int iset)
  631. {
  632. if (iset <= MAXTHRESHOLDS)
  633. XmToggleButtonSetState(Threshbutton[iset - 1], False, False);
  634. }
  635. /*-------------------------------------------------------------------
  636. rotateLoop()
  637. This function is executed while the user attempts to rotate/translate
  638. the 3D model in the main 3D drawing window
  639. -------------------------------------------------------------------
  640. */
  641. void rotateLoop()
  642. {
  643. XEvent event;
  644. XKeyPressedEvent *K;
  645. KeySym sym;
  646. int thresh = 1;
  647. for (;;) {
  648. XtAppNextEvent(App_context, &event);
  649. if (event.type == KeyPress) {
  650. K = (XKeyPressedEvent *) & event;
  651. sym =
  652. XKeycodeToKeysym(XtDisplay(MainOGLWindow.widget), K->keycode,
  653. 0);
  654. if (sym == XK_Escape) {
  655. fprintf(stderr, "Escape\n");
  656. return;
  657. }
  658. else if (sym == XK_equal) {
  659. if (K->state & ShiftMask) {
  660. MainOGLWindow.ptr_D_spec->Thresh++;
  661. if (MainOGLWindow.ptr_D_spec->Thresh >
  662. Headfax.linefax.nthres - 1)
  663. MainOGLWindow.ptr_D_spec->Thresh = 0;
  664. do_draw_immediate_mode();
  665. set_threshold_button(MainOGLWindow.ptr_D_spec->Thresh +
  666. 1);
  667. }
  668. }
  669. else if (sym == XK_minus) {
  670. if (!(K->state & ShiftMask)) {
  671. MainOGLWindow.ptr_D_spec->Thresh--;
  672. if (MainOGLWindow.ptr_D_spec->Thresh < 0)
  673. MainOGLWindow.ptr_D_spec->Thresh =
  674. Headfax.linefax.nthres - 1;
  675. do_draw_immediate_mode();
  676. set_threshold_button(MainOGLWindow.ptr_D_spec->Thresh +
  677. 1);
  678. }
  679. }
  680. else if (sym == XK_C) {
  681. clear_screen();
  682. }
  683. else if (sym == XK_1) {
  684. thresh = 0;
  685. if (thresh < Headfax.linefax.nthres) {
  686. MainOGLWindow.ptr_D_spec->Thresh = thresh;
  687. do_draw_immediate_mode();
  688. set_threshold_button(MainOGLWindow.ptr_D_spec->Thresh +
  689. 1);
  690. }
  691. }
  692. else if (sym == XK_2) {
  693. thresh = 1;
  694. if (thresh < Headfax.linefax.nthres) {
  695. MainOGLWindow.ptr_D_spec->Thresh = thresh;
  696. do_draw_immediate_mode();
  697. set_threshold_button(MainOGLWindow.ptr_D_spec->Thresh +
  698. 1);
  699. }
  700. }
  701. else if (sym == XK_3) {
  702. thresh = 2;
  703. if (thresh < Headfax.linefax.nthres) {
  704. MainOGLWindow.ptr_D_spec->Thresh = thresh;
  705. do_draw_immediate_mode();
  706. set_threshold_button(MainOGLWindow.ptr_D_spec->Thresh +
  707. 1);
  708. }
  709. }
  710. else if (sym == XK_4) {
  711. thresh = 3;
  712. if (thresh < Headfax.linefax.nthres) {
  713. MainOGLWindow.ptr_D_spec->Thresh = thresh;
  714. do_draw_immediate_mode();
  715. set_threshold_button(MainOGLWindow.ptr_D_spec->Thresh +
  716. 1);
  717. }
  718. }
  719. else if (sym == XK_5) {
  720. thresh = 4;
  721. if (thresh < Headfax.linefax.nthres) {
  722. MainOGLWindow.ptr_D_spec->Thresh = thresh;
  723. do_draw_immediate_mode();
  724. set_threshold_button(MainOGLWindow.ptr_D_spec->Thresh +
  725. 1);
  726. }
  727. }
  728. else if (sym == XK_6) {
  729. thresh = 5;
  730. if (thresh < Headfax.linefax.nthres) {
  731. MainOGLWindow.ptr_D_spec->Thresh = thresh;
  732. do_draw_immediate_mode();
  733. set_threshold_button(MainOGLWindow.ptr_D_spec->Thresh +
  734. 1);
  735. }
  736. }
  737. else if (sym == XK_7) {
  738. thresh = 6;
  739. if (thresh < Headfax.linefax.nthres) {
  740. MainOGLWindow.ptr_D_spec->Thresh = thresh;
  741. do_draw_immediate_mode();
  742. set_threshold_button(MainOGLWindow.ptr_D_spec->Thresh +
  743. 1);
  744. }
  745. }
  746. else if (sym == XK_8) {
  747. thresh = 7;
  748. if (thresh < Headfax.linefax.nthres) {
  749. MainOGLWindow.ptr_D_spec->Thresh = thresh;
  750. do_draw_immediate_mode();
  751. set_threshold_button(MainOGLWindow.ptr_D_spec->Thresh +
  752. 1);
  753. }
  754. }
  755. else if (sym == XK_9) {
  756. thresh = 8;
  757. if (thresh < Headfax.linefax.nthres) {
  758. MainOGLWindow.ptr_D_spec->Thresh = thresh;
  759. do_draw_immediate_mode();
  760. set_threshold_button(MainOGLWindow.ptr_D_spec->Thresh +
  761. 1);
  762. }
  763. }
  764. else if (sym == XK_Escape) {
  765. fprintf(stderr, "Escape\n");
  766. return;
  767. }
  768. }
  769. else if (MainOGLWindow.right_button_hit) {
  770. MainOGLWindow.right_button_hit = 0;
  771. return;
  772. }
  773. else {
  774. XtDispatchEvent(&event);
  775. }
  776. }
  777. }
  778. /*-------------------------------------------------------------------
  779. glinputCB()
  780. This function handles all mouse inputs in the main 3D drawing window
  781. -------------------------------------------------------------------
  782. */
  783. HVect vNow;
  784. HVect vNowLast;
  785. void glinputCB(Widget widget, XtPointer client_data, XtPointer cdata)
  786. {
  787. long xpos, ypos;
  788. static int tr_first = 0;
  789. static int rot_first = 0;
  790. static int tr_oymouse;
  791. static int rot_oxmouse, rot_oymouse;
  792. int dymouse;
  793. GLwDrawingAreaCallbackStruct *call_data =
  794. (GLwDrawingAreaCallbackStruct *) cdata;
  795. if (!RotationEnabled)
  796. return;
  797. switch (call_data->event->type) {
  798. case ButtonPress:
  799. if (call_data->event->xbutton.button == Button1) {
  800. if (MainOGLWindow.middle_button_status == 0) {
  801. MainOGLWindow.left_button_status = 1;
  802. rot_first = 1;
  803. xpos = call_data->event->xbutton.x;
  804. ypos = MainOGLWindow.height - call_data->event->xbutton.y;
  805. vNow.x = (2 * (float)xpos / MainOGLWindow.width) - 1.;
  806. vNow.y = (2 * (float)ypos / MainOGLWindow.height) - 1.;
  807. Ball_Mouse(&Trackball, vNow);
  808. Ball_Update(&Trackball);
  809. Ball_BeginDrag(&Trackball);
  810. }
  811. }
  812. else if (call_data->event->xbutton.button == Button2) {
  813. if (MainOGLWindow.left_button_status == 0) {
  814. tr_first = 1;
  815. MainOGLWindow.middle_button_status = 1;
  816. }
  817. }
  818. else if (call_data->event->xbutton.button == Button3) {
  819. MainOGLWindow.right_button_hit = 1;
  820. }
  821. break;
  822. case ButtonRelease:
  823. if (call_data->event->xbutton.button == Button1) {
  824. MainOGLWindow.left_button_status = 0;
  825. Ball_EndDrag(&Trackball);
  826. Ball_Mouse(&Trackball, vNow);
  827. Ball_Update(&Trackball);
  828. do_draw_with_display_list(MainOGLWindow.ptr_D_spec);
  829. }
  830. else if (call_data->event->xbutton.button == Button2) {
  831. MainOGLWindow.middle_button_status = 0;
  832. }
  833. break;
  834. case MotionNotify:
  835. if (MainOGLWindow.left_button_status) {
  836. /* Rotate 3D scene */
  837. xpos = call_data->event->xmotion.x;
  838. ypos = MainOGLWindow.height - call_data->event->xmotion.y;
  839. if (rot_first) {
  840. rot_oxmouse = xpos;
  841. rot_oymouse = ypos;
  842. rot_first = 0;
  843. }
  844. vNow.x = (2 * (float)xpos / MainOGLWindow.width) - 1.;
  845. vNow.y = (2 * (float)ypos / MainOGLWindow.height) - 1.;
  846. Ball_Mouse(&Trackball, vNow);
  847. Ball_Update(&Trackball);
  848. if (((vNowLast.x - vNow.x) * (vNowLast.x - vNow.x) +
  849. (vNowLast.y - vNow.y) * (vNowLast.y - vNow.y)) > .01) {
  850. vNowLast = vNow;
  851. do_draw_with_display_list(MainOGLWindow.ptr_D_spec);
  852. }
  853. }
  854. else if (MainOGLWindow.middle_button_status) {
  855. /* Translate 3D scene */
  856. xpos = call_data->event->xmotion.x;
  857. ypos = MainOGLWindow.height - call_data->event->xmotion.y;
  858. if (tr_first) {
  859. tr_oymouse = ypos;
  860. tr_first = 0;
  861. }
  862. dymouse = ypos - tr_oymouse;
  863. if (dymouse > 10 || dymouse < -10) {
  864. tr_oymouse = ypos;
  865. if (MainOGLWindow.ptr_D_spec) {
  866. MainOGLWindow.ptr_D_spec->ztrans -= (float)dymouse;
  867. do_draw_with_display_list(MainOGLWindow.ptr_D_spec);
  868. }
  869. }
  870. }
  871. break;
  872. }
  873. }
  874. /*-------------------------------------------------------------------
  875. glinitCB()
  876. This function is called during initialization of both the main 3D
  877. drawing window and colormap window
  878. -------------------------------------------------------------------
  879. */
  880. void glinitCB(Widget widget, XtPointer client_data, XtPointer cdata)
  881. {
  882. float xd, yd, zd, trd;
  883. Arg args[10];
  884. XVisualInfo *vi;
  885. int height, width;
  886. float aspect;
  887. GLwDrawingAreaCallbackStruct *call_data =
  888. (GLwDrawingAreaCallbackStruct *) cdata;
  889. int id = (int)client_data;
  890. XtSetArg(args[0], GLwNvisualInfo, &vi);
  891. XtGetValues(widget, args, 1);
  892. if (id == 0) {
  893. /* Main 3D window */
  894. MainOGLWindow.window = XtWindow(widget);
  895. MainOGLWindow.glx_context =
  896. glXCreateContext(XtDisplay(widget), vi, 0, GL_TRUE);
  897. glXMakeCurrent(XtDisplay(widget), MainOGLWindow.window,
  898. MainOGLWindow.glx_context);
  899. glDepthRange(0x0000, 0x7fffff);
  900. height = (GLuint) call_data->height - 1;
  901. width = (GLuint) call_data->width - 1;
  902. aspect = (float)width / (float)height;
  903. do_lights();
  904. clear_screen();
  905. glMatrixMode(GL_PROJECTION);
  906. glLoadIdentity();
  907. gluPerspective(45., aspect, .10, 1000.0);
  908. glMatrixMode(GL_MODELVIEW);
  909. glLoadIdentity();
  910. xd = Headfax.xdim * MainOGLWindow.ptr_D_spec->xscale;
  911. yd = Headfax.ydim * MainOGLWindow.ptr_D_spec->yscale;
  912. zd = Headfax.zdim * MainOGLWindow.ptr_D_spec->zscale;
  913. /* pick greatest dimension to use for translation of viewer from origin */
  914. if (xd < yd)
  915. trd = yd;
  916. else
  917. trd = xd;
  918. if (trd < zd)
  919. trd = zd;
  920. glTranslatef(0.0, 0.0, -trd * 1.6);
  921. glXSwapBuffers(XtDisplay(widget), MainOGLWindow.window);
  922. initializeFonts();
  923. MainDlist = glGenLists(1);
  924. glNewList(MainDlist, GL_COMPILE_AND_EXECUTE);
  925. glEndList();
  926. Ball_Init(&Trackball);
  927. Ball_Place(&Trackball, qOne, .90);
  928. ProceedStatus++;
  929. }
  930. else {
  931. ColormapWindow.window = XtWindow(widget);
  932. ColormapWindow.glx_context =
  933. glXCreateContext(XtDisplay(widget), vi, 0, GL_TRUE);
  934. glXMakeCurrent(XtDisplay(widget), ColormapWindow.window,
  935. ColormapWindow.glx_context);
  936. clear_screen();
  937. glMatrixMode(GL_PROJECTION);
  938. glLoadIdentity();
  939. gluOrtho2D(0, 100, 0, 1000);
  940. glMatrixMode(GL_MODELVIEW);
  941. draw_ctable();
  942. winset_main();
  943. ProceedStatus++;
  944. }
  945. }
  946. /*-------------------------------------------------------------------
  947. glexposeCB()
  948. This function is called when the main 3D drawing window is exposed
  949. -------------------------------------------------------------------
  950. */
  951. void glexposeCB(Widget widget, XtPointer client_data, XtPointer cdata)
  952. {
  953. Window wind;
  954. static int First = 1;
  955. GLwDrawingAreaCallbackStruct *call_data =
  956. (GLwDrawingAreaCallbackStruct *) cdata;
  957. wind = XtWindow(widget);
  958. glXMakeCurrent(XtDisplay(widget), wind, MainOGLWindow.glx_context);
  959. MainOGLWindow.height = (GLuint) (call_data->height);
  960. MainOGLWindow.width = (GLuint) (call_data->width);
  961. glViewport(0, 0, (GLuint) (call_data->width),
  962. (GLuint) (call_data->height));
  963. glScissor(0, 0, (GLuint) (call_data->width),
  964. (GLuint) (call_data->height));
  965. glEnable(GL_DEPTH_TEST);
  966. clear_screen();
  967. if (First) {
  968. do_draw_immediate_mode();
  969. First = 0;
  970. }
  971. else {
  972. do_draw_with_display_list(MainOGLWindow.ptr_D_spec);
  973. }
  974. ProceedStatus++;
  975. }
  976. /*-------------------------------------------------------------------
  977. glresizeCB()
  978. This function is called to clear the colomap window prior to redrawing
  979. -------------------------------------------------------------------
  980. */
  981. void glresizeCB(Widget widget, XtPointer client_data, XtPointer cdata)
  982. {
  983. Window wind;
  984. GLdouble aspect;
  985. GLwDrawingAreaCallbackStruct *call_data =
  986. (GLwDrawingAreaCallbackStruct *) cdata;
  987. wind = XtWindow(widget);
  988. glXMakeCurrent(XtDisplay(widget), wind, MainOGLWindow.glx_context);
  989. glViewport(0, 0, (GLuint) (call_data->width),
  990. (GLuint) (call_data->height));
  991. glScissor(0, 0, (GLuint) (call_data->width),
  992. (GLuint) (call_data->height));
  993. MainOGLWindow.height = (GLuint) (call_data->height);
  994. MainOGLWindow.width = (GLuint) (call_data->width);
  995. aspect = (float)MainOGLWindow.width / (float)MainOGLWindow.height;
  996. glMatrixMode(GL_PROJECTION);
  997. glLoadIdentity();
  998. gluPerspective(45., aspect, .10, 1000.0);
  999. glMatrixMode(GL_MODELVIEW);
  1000. do_draw_with_display_list(MainOGLWindow.ptr_D_spec);
  1001. }
  1002. /*-------------------------------------------------------------------
  1003. clear_screen2()
  1004. This function is called to clear the colomap window prior to redrawing
  1005. -------------------------------------------------------------------
  1006. */
  1007. void clear_screen2()
  1008. {
  1009. glDisable(GL_LIGHTING);
  1010. glClearColor(1., 1., 1., 1.);
  1011. glClear(GL_COLOR_BUFFER_BIT);
  1012. glClearDepth(1.);
  1013. glClear(GL_DEPTH_BUFFER_BIT);
  1014. }
  1015. /*-------------------------------------------------------------------
  1016. glexpose2CB()
  1017. This function is called when the colormap window gets an expose event
  1018. -------------------------------------------------------------------
  1019. */
  1020. void glexpose2CB(Widget widget, XtPointer client_data, XtPointer cdata)
  1021. {
  1022. Window wind;
  1023. GLwDrawingAreaCallbackStruct *call_data =
  1024. (GLwDrawingAreaCallbackStruct *) cdata;
  1025. wind = XtWindow(widget);
  1026. winset_colortable();
  1027. glXMakeCurrent(XtDisplay(widget), wind, ColormapWindow.glx_context);
  1028. glDisable(GL_DEPTH_TEST);
  1029. ColormapWindow.height = (GLuint) (call_data->height);
  1030. ColormapWindow.width = (GLuint) (call_data->width);
  1031. glViewport(0, 0, (GLuint) (call_data->width),
  1032. (GLuint) (call_data->height));
  1033. glScissor(0, 0, (GLuint) (call_data->width),
  1034. (GLuint) (call_data->height));
  1035. clear_screen2();
  1036. glMatrixMode(GL_PROJECTION);
  1037. glLoadIdentity();
  1038. glOrtho(0, 100, 0, 1000, -10000., 1000.);
  1039. glMatrixMode(GL_MODELVIEW);
  1040. glLoadIdentity();
  1041. draw_ctable();
  1042. glXSwapBuffers(XtDisplay(ColormapWindow.widget), ColormapWindow.window);
  1043. ProceedStatus++;
  1044. winset_main();
  1045. }
  1046. /*-------------------------------------------------------------------
  1047. glresize2CB()
  1048. This function is called when the colormap window is resized
  1049. -------------------------------------------------------------------
  1050. */
  1051. void glresize2CB(Widget widget, XtPointer client_data, XtPointer cdata)
  1052. {
  1053. Window wind;
  1054. GLwDrawingAreaCallbackStruct *call_data =
  1055. (GLwDrawingAreaCallbackStruct *) cdata;
  1056. wind = XtWindow(widget);
  1057. glXMakeCurrent(XtDisplay(widget), wind, ColormapWindow.glx_context);
  1058. glViewport(0, 0, (GLuint) (call_data->width),
  1059. (GLuint) (call_data->height));
  1060. glScissor(0, 0, (GLuint) (call_data->width),
  1061. (GLuint) (call_data->height));
  1062. ColormapWindow.height = (GLuint) (call_data->height);
  1063. ColormapWindow.width = (GLuint) (call_data->width);
  1064. clear_screen2();
  1065. glMatrixMode(GL_PROJECTION);
  1066. glLoadIdentity();
  1067. glOrtho(0, 100, 0, 1000, -10000., 1000.);
  1068. glMatrixMode(GL_MODELVIEW);
  1069. glLoadIdentity();
  1070. draw_ctable();
  1071. winset_main();
  1072. }
  1073. /*-------------------------------------------------------------------
  1074. rotate_model()
  1075. This function is called when the program is put into "Rotation Mode"
  1076. where the user is modifying the view using mouse input.
  1077. -------------------------------------------------------------------
  1078. */
  1079. void rotate_model(struct dspec *D_spec)
  1080. {
  1081. enableRotation();
  1082. rotateLoop();
  1083. disableRotation();
  1084. }
  1085. /*-------------------------------------------------------------------
  1086. SingleMultipleCB()
  1087. -------------------------------------------------------------------
  1088. */
  1089. void SingleMultipleCB(Widget widget, XtPointer client_data, XtPointer cdata)
  1090. {
  1091. int flag = (int)client_data;
  1092. Arg args[10];
  1093. int n;
  1094. int i;
  1095. if (flag == 1) {
  1096. MultipleThresholdFlag = 0;
  1097. n = 0;
  1098. XtSetArg(args[n], XmNradioBehavior, True);
  1099. n++;
  1100. XtSetValues(ThresholdRadio, args, n);
  1101. XtManageChild(Button_plus);
  1102. XtManageChild(Button_minus);
  1103. XtUnmanageChild(PlotSelected);
  1104. for (i = 1; i <= Headfax.linefax.nthres; i++) {
  1105. if (i <= MAXTHRESHOLDS)
  1106. XmToggleButtonSetState(Threshbutton[i - 1], False, False);
  1107. }
  1108. }
  1109. else {
  1110. MultipleThresholdFlag = 1;
  1111. for (i = 1; i <= Headfax.linefax.nthres; i++) {
  1112. if (i <= MAXTHRESHOLDS)
  1113. XmToggleButtonSetState(Threshbutton[i - 1], False, False);
  1114. }
  1115. n = 0;
  1116. XtSetArg(args[n], XmNradioBehavior, False);
  1117. n++;
  1118. XtSetValues(ThresholdRadio, args, n);
  1119. XtUnmanageChild(Button_plus);
  1120. XtUnmanageChild(Button_minus);
  1121. XtManageChild(PlotSelected);
  1122. }
  1123. }
  1124. /*-------------------------------------------------------------------
  1125. PlotSelectedCB()
  1126. This function is the callback function for the "Plot Selected" button.
  1127. A plot containing thresholds corresponding to all selected Threshold
  1128. toggle buttons will be drawn.
  1129. -------------------------------------------------------------------
  1130. */
  1131. void PlotSelectedCB(Widget widget, XtPointer client_data, XtPointer cdata)
  1132. {
  1133. int i;
  1134. int selectedList[200];
  1135. int numSelected = 0;
  1136. for (i = 1; i <= Headfax.linefax.nthres; i++) {
  1137. if (i <= MAXTHRESHOLDS) {
  1138. if (XmToggleButtonGetState(Threshbutton[i - 1]) == True) {
  1139. selectedList[numSelected] = i;
  1140. numSelected++;
  1141. }
  1142. }
  1143. }
  1144. for (i = 0; i < numSelected; i++) {
  1145. MainOGLWindow.ptr_D_spec->t[i] = selectedList[i] - 1;
  1146. }
  1147. MainOGLWindow.ptr_D_spec->nt = numSelected;
  1148. draw_multiple();
  1149. }
  1150. /*-------------------------------------------------------------------
  1151. setSingleSelectionMode()
  1152. This function causes the Motif GUI to act in Single Selection Mode
  1153. with regard to Threshold levels
  1154. -------------------------------------------------------------------
  1155. */
  1156. void setSingleSelectionMode()
  1157. {
  1158. Arg args[10];
  1159. int n;
  1160. int i;
  1161. XmToggleButtonSetState(SingleToggle, True, True);
  1162. MultipleThresholdFlag = 0;
  1163. n = 0;
  1164. XtSetArg(args[n], XmNradioBehavior, True);
  1165. n++;
  1166. XtSetValues(ThresholdRadio, args, n);
  1167. XtManageChild(Button_plus);
  1168. XtManageChild(Button_minus);
  1169. XtUnmanageChild(PlotSelected);
  1170. for (i = 1; i <= Headfax.linefax.nthres; i++) {
  1171. if (i <= MAXTHRESHOLDS)
  1172. XmToggleButtonSetState(Threshbutton[i - 1], False, False);
  1173. }
  1174. }
  1175. /*-------------------------------------------------------------------
  1176. setSingleSelectionMode()
  1177. This function causes the Motif GUI to act in Multiple Selection Mode
  1178. with regard to Threshold levels
  1179. -------------------------------------------------------------------
  1180. */
  1181. void setMultipleSelectionMode()
  1182. {
  1183. Arg args[10];
  1184. int n;
  1185. int i;
  1186. MultipleThresholdFlag = 1;
  1187. XmToggleButtonSetState(MultipleToggle, True, True);
  1188. for (i = 1; i <= Headfax.linefax.nthres; i++) {
  1189. if (i <= MAXTHRESHOLDS)
  1190. XmToggleButtonSetState(Threshbutton[i - 1], False, False);
  1191. }
  1192. n = 0;
  1193. XtSetArg(args[n], XmNradioBehavior, False);
  1194. n++;
  1195. XtSetValues(ThresholdRadio, args, n);
  1196. XtUnmanageChild(Button_plus);
  1197. XtUnmanageChild(Button_minus);
  1198. XtManageChild(PlotSelected);
  1199. }
  1200. /*-------------------------------------------------------------------
  1201. isSingleSelectionMode()
  1202. This function returns 1 if the GUI is currently behaving in Single
  1203. Selection Mode or returns 0 if the GUI is currently behaving in
  1204. Multiple selection mode.
  1205. -------------------------------------------------------------------
  1206. */
  1207. int isSingleSelectionMode()
  1208. {
  1209. return !MultipleThresholdFlag;
  1210. }