extern "C" { #include #include #include #include }; #ifdef GLX_MOTIF #include #include #include #include #include #include #include #include #include #include #include #include #endif #include #include #include #include #include "scene.hxx" #include "cbacks.hxx" #include "menu.h" LRESULT APIENTRY MyWndProc(HWND, UINT, WPARAM, LPARAM); VOID SubclassWindow (HWND, WNDPROC); void vCustomizeWnd(void); extern light lights[]; extern GLboolean bAutoMotion(void); extern void draw(void); #ifdef GLX_MOTIF static Display *display; XtAppContext app_context; Widget glw; const int max_args = 20; #endif int quick_moves = 0; int auto_motion = 0; #ifdef GLX_MOTIF XVisualInfo *find_visual() { int attr[256], i, stencil, dbuffer; XVisualInfo *vi; i = 0; attr[i++] = GLX_RGBA; attr[i++] = GLX_RED_SIZE; attr[i++] = 1; attr[i++] = GLX_GREEN_SIZE; attr[i++] = 1; attr[i++] = GLX_BLUE_SIZE; attr[i++] = 1; attr[i++] = GLX_DEPTH_SIZE; attr[i++] = 1; dbuffer = i; attr[i++] = GLX_DOUBLEBUFFER; stencil = i; attr[i++] = GLX_STENCIL_SIZE; attr[i++] = 1; attr[i++] = (int)None; vi = glXChooseVisual(display, DefaultScreen(display), attr); if (vi == NULL) { fprintf(stderr, "Unable to find visual with stencil buffer.\n"); fprintf(stderr, "(Things won't look quite as good).\n"); attr[stencil] = (int)None; vi = glXChooseVisual(display, DefaultScreen(display), attr); if (vi == NULL) { fprintf(stderr, "Unable to find double-buffered visual.\n"); fprintf(stderr, "(Things will look even worse).\n"); attr[dbuffer] = (int)None; vi = glXChooseVisual(display, DefaultScreen(display), attr); if (vi == NULL) fprintf(stderr, "Can't find visual at all.\n"); } } return vi; } #endif #ifdef GLX_MOTIF Widget create_widgets(Widget parent) { Widget main_window; Widget menu_bar; Widget menu_pane; Widget button; Widget cascade; Widget frame; XVisualInfo *vi; Arg args[max_args]; int argcount; char buffer[128]; int i; main_window = XmCreateMainWindow(parent, "main1", NULL, 0); XtManageChild(main_window); menu_bar = XmCreateMenuBar(main_window, "menu_bar", NULL, 0); XtManageChild(menu_bar); menu_pane = XmCreatePulldownMenu(menu_bar, "menu_pane", NULL, 0); button = XmCreatePushButton(menu_pane, "Exit", NULL, 0); XtManageChild(button); XtAddCallback(button, XmNactivateCallback, (XtCallbackProc)exitCB, NULL); XtSetArg(args[0], XmNsubMenuId, menu_pane); cascade = XmCreateCascadeButton(menu_bar, "File", args, 1); XtManageChild(cascade); argcount = 0; XtSetArg(args[argcount], XmNradioBehavior, True); argcount++; menu_pane = XmCreatePulldownMenu(menu_bar, "menu_pane", args, argcount); XtSetArg(args[0], XmNset, TRUE); for (i = 0; i < nindices; i++) { if (i == def_refraction_index) argcount = 1; else argcount = 0; button = XmCreateToggleButton(menu_pane, (char *)indices[i].name, args, argcount); XtManageChild(button); XtAddCallback(button, XmNvalueChangedCallback, (XtCallbackProc)refractionCB, (XtPointer)(&indices[i].index)); } XtSetArg(args[0], XmNsubMenuId, menu_pane); cascade = XmCreateCascadeButton(menu_bar, "Material", args, 1); XtManageChild(cascade); menu_pane = XmCreatePulldownMenu(menu_bar, "menu_pane", NULL, 0); XtSetArg(args[0], XmNset, draw_square); button = XmCreateToggleButton(menu_pane, "Draw Square", args, 1); XtManageChild(button); XtAddCallback(button, XmNvalueChangedCallback, (XtCallbackProc)drawSomethingCB, &draw_square); XtSetArg(args[0], XmNset, draw_shadows); button = XmCreateToggleButton(menu_pane, "Draw Shadows", args, 1); XtManageChild(button); XtAddCallback(button, XmNvalueChangedCallback, (XtCallbackProc)drawSomethingCB, &draw_shadows); XtSetArg(args[0], XmNset, draw_refraction); button = XmCreateToggleButton(menu_pane, "Draw Refraction", args, 1); XtManageChild(button); XtAddCallback(button, XmNvalueChangedCallback, (XtCallbackProc)drawSomethingCB, &draw_refraction); XtSetArg(args[0], XmNset, draw_sphere); button = XmCreateToggleButton(menu_pane, "Draw Sphere", args, 1); XtManageChild(button); XtAddCallback(button, XmNvalueChangedCallback, (XtCallbackProc)drawSomethingCB, &draw_sphere); XtSetArg(args[0], XmNset, draw_lights); button = XmCreateToggleButton(menu_pane, "Draw Lights", args, 1); XtManageChild(button); XtAddCallback(button, XmNvalueChangedCallback, (XtCallbackProc)drawSomethingCB, &draw_lights); #ifdef TEXTURE XtSetArg(args[0], XmNset, draw_texture); button = XmCreateToggleButton(menu_pane, "Texture Map", args, 1); XtManageChild(button); XtAddCallback(button, XmNvalueChangedCallback, (XtCallbackProc)drawSomethingCB, &draw_texture); #endif XtSetArg(args[0], XmNsubMenuId, menu_pane); cascade = XmCreateCascadeButton(menu_bar, "Draw", args, 1); XtManageChild(cascade); argcount = 0; XtSetArg(args[argcount], XmNradioBehavior, True); argcount++; menu_pane = XmCreatePulldownMenu(menu_bar, "menu_pane", args, argcount); XtSetArg(args[0], XmNset, TRUE); for (i = 0; i < npossible_divisions; i++) { if (i == def_divisions_index) argcount = 1; else argcount = 0; sprintf(buffer, "%d", possible_divisions[i]); button = XmCreateToggleButton(menu_pane, buffer, args, argcount); XtManageChild(button); XtAddCallback(button, XmNvalueChangedCallback, (XtCallbackProc)subdivisionCB, &possible_divisions[i]); } XtSetArg(args[0], XmNsubMenuId, menu_pane); cascade = XmCreateCascadeButton(menu_bar, "Subdivision", args, 1); XtManageChild(cascade); menu_pane = XmCreatePulldownMenu(menu_bar, "menu_pane", args, argcount); button = XmCreatePushButton(menu_pane, "Reset Position", NULL, 0); XtManageChild(button); XtAddCallback(button, XmNactivateCallback, (XtCallbackProc)resetLightsCB, NULL); XtSetArg(args[0], XmNset, TRUE); for (i = 0; i < nlights; i++) { button = XmCreateToggleButton(menu_pane, lights[i].name, args, lights[i].on ? 1 : 0); XtManageChild(button); XtAddCallback(button, XmNvalueChangedCallback, (XtCallbackProc)light_onCB, &lights[i]); } XtSetArg(args[0], XmNsubMenuId, menu_pane); cascade = XmCreateCascadeButton(menu_bar, "Lights", args, 1); XtManageChild(cascade); menu_pane = XmCreatePulldownMenu(menu_bar, "menu_pane", args, argcount); XtSetArg(args[0], XmNset, quick_moves); button = XmCreateToggleButton(menu_pane, "Quick Motion", args, 1); XtManageChild(button); XtAddCallback(button, XmNvalueChangedCallback, (XtCallbackProc)intToggleCB, &quick_moves); XtSetArg(args[0], XmNset, auto_motion); button = XmCreateToggleButton(menu_pane, "Rotate Automatically", args, 1); XtManageChild(button); XtAddCallback(button, XmNvalueChangedCallback, (XtCallbackProc)autoMotionCB, NULL); XtSetArg(args[0], XmNsubMenuId, menu_pane); cascade = XmCreateCascadeButton(menu_bar, "Motion", args, 1); XtManageChild(cascade); argcount = 0; XtSetArg(args[argcount], XmNmarginWidth, 0); argcount++; XtSetArg(args[argcount], XmNmarginHeight, 0); argcount++; XtSetArg(args[argcount], XmNshadowThickness, 1); argcount++; XtSetArg(args[argcount], XmNshadowType, XmSHADOW_OUT); argcount++; frame = XmCreateFrame(main_window, "frame", args, argcount); XtManageChild(frame); argcount = 0; vi = find_visual(); if (vi) { XtSetArg(args[argcount], GLwNvisualInfo, vi); argcount++; } else { XtSetArg(args[argcount], GLwNrgba, TRUE); argcount++; XtSetArg(args[argcount], GLwNdepthSize, 1); argcount++; XtSetArg(args[argcount], GLwNdoublebuffer, TRUE); argcount++; } XtSetArg(args[argcount], XmNbottomAttachment, XmATTACH_FORM); argcount++; XtSetArg(args[argcount], XmNtopAttachment, XmATTACH_FORM); argcount++; XtSetArg(args[argcount], XmNleftAttachment, XmATTACH_FORM); argcount++; XtSetArg(args[argcount], XmNrightAttachment, XmATTACH_FORM); argcount++; glw = GLwCreateMDrawingArea(frame, "glwidget", args, argcount); XtManageChild(glw); XtAddCallback(glw, GLwNginitCallback, (XtCallbackProc)initCB, 0); XtAddCallback(glw, GLwNexposeCallback, (XtCallbackProc)exposeCB, 0); XtAddCallback(glw, GLwNresizeCallback, (XtCallbackProc)resizeCB, 0); XtAddCallback(glw, GLwNinputCallback, (XtCallbackProc)inputCB, 0); return main_window; } #endif void main(int argc, char **argv) { auxInitDisplayMode(AUX_RGBA | AUX_STENCIL | AUX_DOUBLE ); auxInitPosition(100, 100, 300, 300); auxInitWindow("BackTrace"); vCustomizeWnd(); scene_load_texture((char *)def_texfile); vInit(); auxReshapeFunc(vResize); // // we've a choice of using accelerator or auxKeyFunc // the use of auxKeyFunc here is solely for demonstration purpose // auxKeyFunc(AUX_SPACE, vQuickMove); auxKeyFunc(AUX_RETURN, vResetLights); auxKeyFunc(AUX_p, vAutoMotion); auxKeyFunc(AUX_q, vDrawAll); auxKeyFunc(AUX_w, vDrawSquare); auxKeyFunc(AUX_e, vDrawShadow); auxKeyFunc(AUX_r, vDrawRefraction); auxKeyFunc(AUX_t, vDrawSphere); auxKeyFunc(AUX_y, vDrawLight); auxKeyFunc(AUX_u, vDrawTexture); auxKeyFunc(AUX_a, vRefractionAIR); auxKeyFunc(AUX_s, vRefractionICE); auxKeyFunc(AUX_d, vRefractionWATER); auxKeyFunc(AUX_f, vRefractionZincGLASS); auxKeyFunc(AUX_g, vRefractionLightGLASS); auxKeyFunc(AUX_h, vRefractionHeavyGLASS); auxKeyFunc(AUX_1, vSubdivision10); auxKeyFunc(AUX_2, vSubdivision20); auxKeyFunc(AUX_3, vSubdivision30); auxKeyFunc(AUX_4, vSubdivision40); auxKeyFunc(AUX_R, vRLight_on); auxKeyFunc(AUX_G, vGLight_on); auxKeyFunc(AUX_B, vBLight_on); auxMouseFunc(AUX_LEFTBUTTON, AUX_MOUSEDOWN, vMouseDown); auxMouseFunc(AUX_MIDDLEBUTTON, AUX_MOUSEDOWN, vMouseDown); auxMouseFunc(AUX_RIGHTBUTTON, AUX_MOUSEDOWN, vMouseDown); auxMouseFunc(AUX_LEFTBUTTON, AUX_MOUSEUP, vLeftMouseUp); auxMouseFunc(AUX_MIDDLEBUTTON, AUX_MOUSEUP, vMiddleMouseUp); auxMouseFunc(AUX_RIGHTBUTTON, AUX_MOUSEUP, vRightMouseUp); auxMouseFunc(AUX_LEFTBUTTON, AUX_MOUSELOC, vMouseMove); auxMouseFunc(AUX_MIDDLEBUTTON, AUX_MOUSELOC, vMouseMove); auxMouseFunc(AUX_RIGHTBUTTON, AUX_MOUSELOC, vMouseMove); auxMainLoop(draw); return; } #ifdef GLX_MOTIF void main(int argc, char **argv) { Widget app_shell; Arg args[max_args]; int argcount; scene_load_texture((char *)def_texfile); XtToolkitInitialize(); app_context = XtCreateApplicationContext(); display = XtOpenDisplay(app_context, NULL, argv[0], "XMdemos", NULL, 0, &argc, argv); if (!display) { XtWarning("Can't open display."); exit(0); } argcount = 0; XtSetArg(args[argcount], XmNmaxAspectX, 1); argcount++; XtSetArg(args[argcount], XmNmaxAspectY, 1); argcount++; XtSetArg(args[argcount], XmNminAspectX, 1); argcount++; XtSetArg(args[argcount], XmNminAspectY, 1); argcount++; app_shell = XtAppCreateShell(argv[0], "XMdemos", applicationShellWidgetClass, display, args, argcount); create_widgets(app_shell); XtRealizeWidget(app_shell); XtAppMainLoop(app_context); } #endif /**************************************************************************\ * * function: MyWndProc * * input parameters: normal window procedure parameters. * \**************************************************************************/ LRESULT APIENTRY MyWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { WNDPROC pfnOldProc; static UINT_PTR uiTmID = 0; int wmId, wmEvent; pfnOldProc = (WNDPROC) GetWindowLongPtr (hwnd, GWLP_USERDATA); switch (message) { case WM_COMMAND: { HMENU hmenu; hmenu = GetMenu(auxGetHWND()); wmId = LOWORD(wParam); wmEvent = HIWORD(wParam); switch (wmId) { case IDM_EXIT : vExit(); break; case IDM_AIR : case IDM_ICE : case IDM_WATER : case IDM_ZINC : case IDM_LIGHT : case IDM_HEAVY : vRefraction(wmId - IDM_AIR); break; case IDM_SQUARE : { if (draw_square) CheckMenuItem(hmenu, IDM_SQUARE, MF_BYCOMMAND | MF_UNCHECKED); else CheckMenuItem(hmenu, IDM_SQUARE, MF_BYCOMMAND | MF_CHECKED); vDrawStuff(&draw_square); break; } case IDM_SHADOW : { if (draw_shadows) CheckMenuItem(hmenu, IDM_SHADOW, MF_BYCOMMAND | MF_UNCHECKED); else CheckMenuItem(hmenu, IDM_SHADOW, MF_BYCOMMAND | MF_CHECKED); vDrawStuff(&draw_shadows); break; } case IDM_REFRACTION: { if (draw_refraction) CheckMenuItem(hmenu, IDM_REFRACTION, MF_BYCOMMAND | MF_UNCHECKED); else CheckMenuItem(hmenu, IDM_REFRACTION, MF_BYCOMMAND | MF_CHECKED); vDrawStuff(&draw_refraction); break; } case IDM_SPHERE : { if (draw_sphere) CheckMenuItem(hmenu, IDM_SPHERE, MF_BYCOMMAND | MF_UNCHECKED); else CheckMenuItem(hmenu, IDM_SPHERE, MF_BYCOMMAND | MF_CHECKED); vDrawStuff(&draw_sphere); break; } case IDM_LIGHTS : { if (draw_lights) CheckMenuItem(hmenu, IDM_LIGHTS, MF_BYCOMMAND | MF_UNCHECKED); else CheckMenuItem(hmenu, IDM_LIGHTS, MF_BYCOMMAND | MF_CHECKED); vDrawStuff(&draw_lights); break; } case IDM_TEXTURE : { if (draw_texture) CheckMenuItem(hmenu, IDM_TEXTURE, MF_BYCOMMAND | MF_UNCHECKED); else CheckMenuItem(hmenu, IDM_TEXTURE, MF_BYCOMMAND | MF_CHECKED); vDrawStuff(&draw_texture); break; } case IDM_ALL : vDrawAll(); break; case IDM_10 : case IDM_20 : case IDM_30 : case IDM_40 : vSubdivision(wmId - IDM_10); break; case IDM_RESETLGT : vResetLights(); break; case IDM_RED : case IDM_GREEN : case IDM_BLUE : vLight_on(wmId - IDM_RED); break; case IDM_QUICK : vQuickMove(); break; case IDM_AUTO : vAutoMotion(); break; default: break; } } case WM_USER: if (auto_motion) { uiTmID = SetTimer(hwnd, 1, 1, NULL); if (uiTmID == 0) OutputDebugString("failed to create timer\n"); } else { if (uiTmID != 0) { KillTimer(hwnd, uiTmID); uiTmID = 0; } } return 0; case WM_TIMER: { //static int cnt=0; //char text[128]; bAutoMotion(); //wsprintf(text, "WM_TIMER %d\n", cnt++); //OutputDebugString(text); return 0; } case WM_DESTROY: if (uiTmID != 0) KillTimer(hwnd, uiTmID); return CallWindowProc(pfnOldProc, hwnd, message, wParam, lParam); default: return CallWindowProc(pfnOldProc, hwnd, message, wParam, lParam); } /* end switch */ return 0; } /**************************************************************************\ * function: SubclassWindow * * input parameters: * hwnd - window handle to be subclassed, * SubclassWndProc - the new window procedure. * \**************************************************************************/ VOID SubclassWindow (HWND hwnd, WNDPROC SubclassWndProc) { LONG_PTR pfnOldProc; pfnOldProc = GetWindowLongPtr (hwnd, GWLP_WNDPROC); SetWindowLongPtr (hwnd, GWLP_USERDATA, (LONG_PTR) pfnOldProc); SetWindowLongPtr (hwnd, GWLP_WNDPROC, (LONG_PTR) SubclassWndProc); } /******************************Public*Routine******************************\ * * vCustomizeWnd * * Effects: Subclass the window created by the toolkit * Add menu bar to the window * Setup timer * * History: * 01-Dec-1993 * \**************************************************************************/ void vCustomizeWnd(void) { HWND hWnd; if ((hWnd = auxGetHWND()) == NULL) { OutputDebugString("auxGetHWND() failed\n"); return; } SubclassWindow (hWnd, MyWndProc); SendMessage(hWnd, WM_USER, 0L, 0L); SetMenu(hWnd, LoadMenu(GetModuleHandle(NULL), "Backtrac")); DrawMenuBar(hWnd); return; }