示例#1
0
文件: tkMacOSXMenus.c 项目: das/tcltk
static void
GenerateEditEvent(
    int flag)
{
    XVirtualEvent event;
    int x, y;
    Tk_Window tkwin;
    Window window;
    TkDisplay *dispPtr;

    window = TkMacOSXGetXWindow(ActiveNonFloatingWindow());
    dispPtr = TkGetDisplayList();
    tkwin = Tk_IdToWindow(dispPtr->display, window);
    tkwin = (Tk_Window) ((TkWindow *) tkwin)->dispPtr->focusPtr;
    if (tkwin == NULL) {
	return;
    }

    bzero(&event, sizeof(XVirtualEvent));
    event.type = VirtualEvent;
    event.serial = Tk_Display(tkwin)->request;
    event.send_event = false;
    event.display = Tk_Display(tkwin);
    event.event = Tk_WindowId(tkwin);
    event.root = XRootWindow(Tk_Display(tkwin), 0);
    event.subwindow = None;
    event.time = TkpGetMS();

    XQueryPointer(NULL, None, NULL, NULL,
	    &event.x_root, &event.y_root, &x, &y, &event.state);
    Tk_TopCoordsToWindow(tkwin, x, y, &event.x, &event.y);
    event.same_screen = true;

    switch (flag) {
    case EDIT_CUT:
	event.name = Tk_GetUid("Cut");
	break;
    case EDIT_COPY:
	event.name = Tk_GetUid("Copy");
	break;
    case EDIT_PASTE:
	event.name = Tk_GetUid("Paste");
	break;
    case EDIT_CLEAR:
	event.name = Tk_GetUid("Clear");
	break;
    }
    Tk_QueueWindowEvent((XEvent *) &event, TCL_QUEUE_TAIL);
}
示例#2
0
MODULE_SCOPE int
TkGenerateButtonEventForXPointer(
    Window window)	  /* X Window containing button event. */
{
    MouseEventData med;
    int global_x, global_y, local_x, local_y;

    bzero(&med, sizeof(MouseEventData));
    XQueryPointer(NULL, None, NULL, NULL, &global_x, &global_y,
	    &local_x, &local_y, &med.state);
    med.global.h = global_x;
    med.global.v = global_y;
    med.local.h = local_x;
    med.local.v = local_y;
    med.window = window;
    med.activeNonFloating = ActiveNonFloatingWindow();

    return GenerateButtonEvent(&med);
}
示例#3
0
int
TkGenerateButtonEvent(
    int x,		  /* X location of mouse */
    int y,		  /* Y location of mouse */
    Window window,	  /* X Window containing button event. */
    unsigned int state)	  /* Button Key state suitable for X event */
{
    MouseEventData med;

    bzero(&med, sizeof(MouseEventData));
    med.state = state;
    med.window = window;
    med.global.h = x;
    med.global.v = y;
    FindWindow(med.global, &med.whichWin);
    med.activeNonFloating = ActiveNonFloatingWindow();
    med.local = med.global;
    QDGlobalToLocalPoint(GetWindowPort(med.whichWin), &med.local);

    return GenerateButtonEvent(&med);
}
示例#4
0
void
XDestroyWindow(
    Display *display,		/* Display. */
    Window window)		/* Window. */
{
    MacDrawable *macWin = (MacDrawable *) window;
    WindowRef winRef;

    /*
     * Remove any dangling pointers that may exist if the window we are
     * deleting is being tracked by the grab code.
     */

    TkPointerDeadWindow(macWin->winPtr);
    macWin->toplevel->referenceCount--;

    if (!Tk_IsTopLevel(macWin->winPtr)) {
	TkMacOSXInvalidateWindow(macWin, TK_PARENT_WINDOW);
	if (macWin->winPtr->parentPtr != NULL) {
	    TkMacOSXInvalClipRgns((Tk_Window) macWin->winPtr->parentPtr);
	}
	if (macWin->visRgn) {
	    CFRelease(macWin->visRgn);
	}
	if (macWin->aboveVisRgn) {
	    CFRelease(macWin->aboveVisRgn);
	}

	if (macWin->toplevel->referenceCount == 0) {
	    ckfree((char *) macWin->toplevel);
	}
	ckfree((char *) macWin);
	return;
    }

    /*
     * We are relying on the Activate Mac OS event to pass the focus away from
     * a window that is getting Destroyed to the Front non-floating window. BUT
     * we don't get activate events when a floating window is destroyed, since
     * the front non-floating window doesn't in fact get activated... So maybe
     * we can check here and if we are destroying a floating window, we can
     * pass the focus back to the front non-floating window...
     */

    if (macWin->grafPtr != NULL) {
	TkWindow *focusPtr = TkGetFocusWin(macWin->winPtr);

	if (focusPtr == NULL
		|| (focusPtr->mainPtr->winPtr == macWin->winPtr)) {
	    winRef = TkMacOSXDrawableWindow(window);
	    if (TkpIsWindowFloating (winRef)) {
		Window window = TkMacOSXGetXWindow(ActiveNonFloatingWindow());

		if (window != None) {
		    TkMacOSXGenerateFocusEvent(window, 1);
		}
	    }
	}
    }
    if (macWin->visRgn) {
	CFRelease(macWin->visRgn);
    }
    if (macWin->aboveVisRgn) {
	CFRelease(macWin->aboveVisRgn);
    }

    /*
     * Delete the Mac window and remove it from the windowTable. The window
     * could be NULL if the window was never mapped. However, we don't do this
     * for embedded windows, they don't go in the window list, and they do not
     * own their portPtr's.
     */

    if (!Tk_IsEmbedded(macWin->winPtr)) {
	WindowRef winRef = TkMacOSXDrawableWindow(window);

	if (winRef) {
	    TkMacOSXWindowList *listPtr, *prevPtr;
	    WindowGroupRef group;

	    if (GetWindowProperty(winRef, 'Tk  ', 'TsGp', sizeof(group), NULL,
		    &group) == noErr) {
		TkDisplay *dispPtr = TkGetDisplayList();
		ItemCount i = CountWindowGroupContents(group,
			kWindowGroupContentsReturnWindows);
		WindowRef macWin;
		WindowGroupRef newGroup;
		Window window;

		while (i > 0) {
		    ChkErr(GetIndexedWindow, group, i--, 0, &macWin);
		    if (!macWin) {
			continue;
		    }

		    window = TkMacOSXGetXWindow(macWin);
		    newGroup = NULL;
		    if (window != None) {
			TkWindow *winPtr = (TkWindow *)
				Tk_IdToWindow(dispPtr->display, window);

			if (winPtr && winPtr->wmInfoPtr) {
			    newGroup = GetWindowGroupOfClass(
				    winPtr->wmInfoPtr->macClass);
			}
		    }
		    if (!newGroup) {
			newGroup =
				GetWindowGroupOfClass(kDocumentWindowClass);
		    }
		    ChkErr(SetWindowGroup, macWin, newGroup);
		}
		ChkErr(SetWindowGroupOwner, group, NULL);
		ChkErr(ReleaseWindowGroup, group);
	    }
	    TkMacOSXUnregisterMacWindow(winRef);
	    DisposeWindow(winRef);

	    for (listPtr=tkMacOSXWindowListPtr, prevPtr=NULL;
		    tkMacOSXWindowListPtr != NULL;
		    prevPtr=listPtr, listPtr=listPtr->nextPtr) {
		if (listPtr->winPtr == macWin->winPtr) {
		    if (prevPtr == NULL) {
			tkMacOSXWindowListPtr = listPtr->nextPtr;
		    } else {
			prevPtr->nextPtr = listPtr->nextPtr;
		    }
		    ckfree((char *) listPtr);
		    break;
		}
	    }
	}
    }

    macWin->grafPtr = NULL;

    /*
     * Delay deletion of a toplevel data structure untill all children have
     * been deleted.
     */

    if (macWin->toplevel->referenceCount == 0) {
	ckfree((char *) macWin->toplevel);
    }
}
示例#5
0
MODULE_SCOPE int
TkMacOSXProcessMouseEvent(TkMacOSXEvent *eventPtr, MacEventStatus * statusPtr)
{
    Tk_Window tkwin;
    Point where, where2;
    int result;
    TkDisplay * dispPtr;
    OSStatus err;
    MouseEventData mouseEventData, * medPtr = &mouseEventData;
    int isFrontProcess;

    switch (eventPtr->eKind) {
	case kEventMouseDown:
	case kEventMouseUp:
	case kEventMouseMoved:
	case kEventMouseDragged:
	case kEventMouseWheelMoved:
	    break;
	default:
	    return false;
	    break;
    }
    err = ChkErr(GetEventParameter, eventPtr->eventRef,
	    kEventParamMouseLocation,
	    typeQDPoint, NULL,
	    sizeof(where), NULL,
	    &where);
    if (err != noErr) {
	GetGlobalMouse(&where);
    }
    err = ChkErr(GetEventParameter, eventPtr->eventRef,
	    kEventParamWindowRef,
	    typeWindowRef, NULL,
	    sizeof(WindowRef), NULL,
	    &medPtr->whichWin);
    if (err == noErr) {
	err = ChkErr(GetEventParameter, eventPtr->eventRef,
		kEventParamWindowPartCode,
		typeWindowPartCode, NULL,
		sizeof(WindowPartCode), NULL,
		&medPtr->windowPart);
    }
    if (err != noErr) {
	medPtr->windowPart = FindWindow(where, &medPtr->whichWin);
    }
    medPtr->window = TkMacOSXGetXWindow(medPtr->whichWin);
    if (medPtr->whichWin != NULL && medPtr->window == None) {
	return false;
    }
    if (eventPtr->eKind == kEventMouseDown) {
	if (IsWindowActive(medPtr->whichWin) && IsWindowPathSelectEvent(
		medPtr->whichWin, eventPtr->eventRef)) {
	    ChkErr(WindowPathSelect, medPtr->whichWin, NULL, NULL);
	    return false;
	}
	if (medPtr->windowPart == inProxyIcon) {
	    TkMacOSXTrackingLoop(1);
	    err = ChkErr(TrackWindowProxyDrag, medPtr->whichWin, where);
	    TkMacOSXTrackingLoop(0);
	    if (err == errUserWantsToDragWindow) {
		medPtr->windowPart = inDrag;
	    } else {
		return false;
	    }
	}
    }
    isFrontProcess = Tk_MacOSXIsAppInFront();
    if (isFrontProcess) {
	medPtr->state = ButtonModifiers2State(GetCurrentEventButtonState(),
		GetCurrentEventKeyModifiers());
    } else {
	medPtr->state = ButtonModifiers2State(GetCurrentButtonState(),
		GetCurrentKeyModifiers());
    }
    medPtr->global = where;
    err = ChkErr(GetEventParameter, eventPtr->eventRef,
	    kEventParamWindowMouseLocation,
	    typeQDPoint, NULL,
	    sizeof(Point), NULL,
	    &medPtr->local);
    if (err == noErr) {
	if (medPtr->whichWin) {
	    Rect widths;
	    GetWindowStructureWidths(medPtr->whichWin, &widths);
	    medPtr->local.h -=	widths.left;
	    medPtr->local.v -=	widths.top;
	}
    } else {
	medPtr->local = where;
	if (medPtr->whichWin) {
	    QDGlobalToLocalPoint(GetWindowPort(medPtr->whichWin),
		    &medPtr->local);
	}
    }
    medPtr->activeNonFloating = ActiveNonFloatingWindow();
    dispPtr = TkGetDisplayList();
    tkwin = Tk_IdToWindow(dispPtr->display, medPtr->window);

    if (eventPtr->eKind != kEventMouseDown) {
	int res = false;

	switch (eventPtr->eKind) {
	    case kEventMouseUp:
		/*
		 * The window manager only needs to know about mouse down
		 * events and sometimes we need to "eat" the mouse up.
		 * Otherwise, we just pass the event to Tk.
		 */
		if (TkMacOSXGetEatButtonUp()) {
		    TkMacOSXSetEatButtonUp(false);
		} else {
		    res = GenerateButtonEvent(medPtr);
		}
		break;
	    case kEventMouseWheelMoved:
		err = ChkErr(GetEventParameter, eventPtr->eventRef,
			kEventParamMouseWheelDelta, typeLongInteger, NULL,
			sizeof(long), NULL, &medPtr->delta);
		if (err != noErr ) {
		    statusPtr->err = 1;
		} else {
		    EventMouseWheelAxis axis;
		    err = ChkErr(GetEventParameter, eventPtr->eventRef,
			    kEventParamMouseWheelAxis, typeMouseWheelAxis,
			    NULL, sizeof(EventMouseWheelAxis), NULL, &axis);
		    if (err == noErr && axis == kEventMouseWheelAxisX) {
			 medPtr->state |= ShiftMask;
		    }
		    res = GenerateMouseWheelEvent(medPtr);
		}
		break;
	    case kEventMouseMoved:
	    case kEventMouseDragged:
		res = GeneratePollingEvents(medPtr);
		break;
	    default:
		Tcl_Panic("Unknown mouse event !");
	}
	if (res) {
		statusPtr->stopProcessing = 1;
	}
	return res;
    }
    TkMacOSXSetEatButtonUp(false);
    if (medPtr->whichWin) {
	/*
	 * We got a mouse down in a window
	 * See if this is the activate click
	 * This click moves the window forward. We don't want
	 * the corresponding mouse-up to be reported to the application
	 * or else it will mess up some Tk scripts.
	 */

	if (!(TkpIsWindowFloating(medPtr->whichWin))
		&& (medPtr->whichWin != medPtr->activeNonFloating
		|| !isFrontProcess)) {
	    int frontWindowOnly = 1;
	    int cmdDragGrow = ((medPtr->windowPart == inDrag ||
		    medPtr->windowPart == inGrow) && medPtr->state & Mod1Mask);

	    if (!cmdDragGrow) {
		Tk_Window grabWin = GetGrabWindowForWindow(tkwin);

		frontWindowOnly = !grabWin;
		if (grabWin && grabWin != tkwin) {
		    TkMacOSXSetEatButtonUp(true);
		    BringWindowForward(TkMacOSXDrawableWindow(
			    ((TkWindow*)grabWin)->window), isFrontProcess,
			    frontWindowOnly);
		    return false;
		}
	    }

	    /*
	     * Clicks in the titlebar widgets are handled without bringing the
	     * window forward.
	     */
	    if ((result = HandleWindowTitlebarMouseDown(medPtr, tkwin)) != -1) {
		statusPtr->stopProcessing = 1;
		return result;
	    } else {
		/*
		 * Only windows with the kWindowNoActivatesAttribute can
		 * receive mouse events in the background.
		 */
		if (!(((TkWindow *)tkwin)->wmInfoPtr->attributes &
			kWindowNoActivatesAttribute)) {
		    /*
		     * Allow background window dragging & growing with Command
		     * down.
		     */
		    if (!cmdDragGrow) {
			TkMacOSXSetEatButtonUp(true);
			BringWindowForward(medPtr->whichWin, isFrontProcess,
				frontWindowOnly);
		    }
		    /*
		     * Allow dragging & growing of windows that were/are in the
		     * background.
		     */
		    if (!(medPtr->windowPart == inDrag ||
			    medPtr->windowPart == inGrow)) {
			return false;
		    }
		}
	    }
	} else {
	    if ((result = HandleWindowTitlebarMouseDown(medPtr, tkwin)) != -1) {
		statusPtr->stopProcessing = 1;
		return result;
	    }
	}
	switch (medPtr->windowPart) {
	    case inDrag: {
		WindowAttributes attributes;

		GetWindowAttributes(medPtr->whichWin, &attributes);
		if (!(attributes & kWindowAsyncDragAttribute)) {
		    TkMacOSXTrackingLoop(1);
		    DragWindow(medPtr->whichWin, where, NULL);
		    TkMacOSXTrackingLoop(0);
		    where2.h = where2.v = 0;
		    QDLocalToGlobalPoint(GetWindowPort(medPtr->whichWin),
			    &where2);
		    if (EqualPt(where, where2)) {
			return false;
		    }
		    return true;
		}
		break;
	    }
	    case inGrow:
		/*
		 * Generally the content region is the domain of Tk
		 * sub-windows. However, one exception is the grow
		 * region. A button down in this area will be handled
		 * by the window manager. Note: this means that Tk
		 * may not get button down events in this area!
		 */
		if (TkMacOSXGrowToplevel(medPtr->whichWin, where) == true) {
		    statusPtr->stopProcessing = 1;
		    return true;
		} else {
		    return GenerateButtonEvent(medPtr);
		}
		break;
	    case inContent:
		return GenerateButtonEvent(medPtr);
		break;
	    default:
		return false;
		break;
	}
    }
    return false;
}
示例#6
0
OSStatus ComboBoxHandler(EventHandlerCallRef next,
                         EventRef event, void *data)
{
    WindowRef window;
    HIViewRef combo;
    CFIndex index;
    UInt32 id;

    // Get the window
    
    window = ActiveNonFloatingWindow();

    // Get the control

    GetEventParameter(event, kEventParamDirectObject,
                      typeControlRef, NULL, sizeof(combo),
                      NULL, &combo);

    // Get the index

    GetEventParameter(event, kEventParamComboBoxListSelectedItemIndex,
                      typeCFIndex, NULL, sizeof(index),
                      NULL, &index);

    // Get the command id

    HIViewGetCommandID(combo, &id);

    // Switch on the command id
        
    switch (id)
    {
        // Instrument

    case kCommandInst:
        instrument = index;
        ChangeInstrument(instrument);
        break;

        // Key

    case kCommandKey:
        key = index;
	type = types[key];
	ChangeDisplay();
        break;

        // Something else

    default:
        return eventNotHandledErr;
    }

    // Clear the keyboard focus, otherwise the focus stays on the
    // combo box and makes it drop down when the user presses a key

    ClearKeyboardFocus(window);

    // Report success

    return noErr;
}
示例#7
0
OSStatus CommandHandler(EventHandlerCallRef next,
                        EventRef event, void *data)
{
    HICommandExtended command;
    WindowRef window;
    UInt32 value;

    // Get the command

    GetEventParameter(event, kEventParamDirectObject,
                      typeHICommand, NULL, sizeof(command),
                      NULL, &command);

    // Get the value

    value = HIViewGetValue(command.source.control);

    // Switch on the command ID

    switch (command.commandID)
    {
        // Key or instrument control

    case kCommandKey:
    case kCommandInst:

	// If the combo box list isn't visible (the user just closed
	// it)

        if (!HIComboBoxIsListVisible(command.source.control))
        {
            // Get the window
    
            window = ActiveNonFloatingWindow();

            // Clear the keyboard focus, otherwise the focus stays on the
            // combo box and makes it drop down when the user presses a key

            ClearKeyboardFocus(window);
        }
        break;

        // Reverse

    case kCommandReverse:
        reverse = value;
	ChangeDisplay();
        break;

        // Volume

    case kCommandVolume:
        volume = value;
        break;

	// Notes

    case kCommandNote:
	shownotes = value;
	ChangeDisplay();
	break;

        // Quit

    case kHICommandQuit:

        // Let the default handler handle it

    default:
        return eventNotHandledErr;
    }

    // Report success

    return noErr;
}
示例#8
0
文件: tkMacOSXMenus.c 项目: das/tcltk
void
TkMacOSXHandleMenuSelect(
    MenuID theMenu,
    MenuItemIndex theItem,
    int optionKeyPressed)
{
    Tk_Window tkwin;
    Window window;
    TkDisplay *dispPtr;
    Tcl_CmdInfo dummy;
    int code;

    if (theItem == 0) {
	TkMacOSXClearMenubarActive();
	return;
    }

    switch (theMenu) {
    case kAppleMenu:
	switch (theItem) {
	case kAppleAboutItem:
	    if (optionKeyPressed || gInterp == NULL ||
		Tcl_GetCommandInfo(gInterp, "tkAboutDialog", &dummy) == 0) {
		TkAboutDlg();
	    } else {
		code = Tcl_EvalEx(gInterp, "tkAboutDialog", -1,
			TCL_EVAL_GLOBAL);
		if (code != TCL_OK) {
		    Tcl_BackgroundException(gInterp, code);
		}
		Tcl_ResetResult(gInterp);
	    }
	    break;
	}
	break;
    case kFileMenu:
	switch (theItem) {
	case kSourceItem:
	    if (gInterp) {
		if (Tcl_EvalEx(gInterp, "tk_getOpenFile -filetypes {"
			"{{TCL Scripts} {.tcl} TEXT} {{Text Files} {} TEXT}}",
			-1, TCL_EVAL_GLOBAL) == TCL_OK) {
		    Tcl_Obj *path = Tcl_GetObjResult(gInterp);
		    int len;

		    Tcl_GetStringFromObj(path, &len);
		    if (len) {
			Tcl_IncrRefCount(path);
			code = Tcl_FSEvalFile(gInterp, path);
			if (code != TCL_OK) {
			    Tcl_BackgroundException(gInterp, code);
			}
			Tcl_DecrRefCount(path);
		    }
		}
		Tcl_ResetResult(gInterp);
	    }
	    break;
	case kDemoItem:
	    if (gInterp) {
		Tcl_Obj *path = GetWidgetDemoPath(gInterp);

		if (path) {
		    Tcl_IncrRefCount(path);
		    code = Tcl_FSEvalFile(gInterp, path);
		    if (code != TCL_OK) {
			Tcl_BackgroundException(gInterp, code);
		    }
		    Tcl_DecrRefCount(path);
		    Tcl_ResetResult(gInterp);
		}
	    }
	    break;
	case kCloseItem:
	    /* Send close event */
	    window = TkMacOSXGetXWindow(ActiveNonFloatingWindow());
	    dispPtr = TkGetDisplayList();
	    tkwin = Tk_IdToWindow(dispPtr->display, window);
	    TkGenWMDestroyEvent(tkwin);
	    break;
	}
	break;
    case kEditMenu:
	/*
	 * This implementation just send the keysyms Tk thinks are associated
	 * with function keys that do Cut, Copy & Paste on a Sun keyboard.
	 */

	GenerateEditEvent(theItem);
	break;
    default:
	TkMacOSXDispatchMenuEvent(theMenu, theItem);
	break;
    }

    /*
     * Finally we unhighlight the menu.
     */

    HiliteMenu(0);
}
// True for OK, false for cancel
bool Configure_ChaseCam(ChaseCamData &Data)
{
	short ItemType;
	Rect Bounds;
	
	DialogPtr Dialog = myGetNewDialog(ChaseCam_Dialog, NULL, (WindowPtr)(-1), 0);
	assert(Dialog);
	
	ControlHandle Behind_CHdl;
	GetDialogItem(Dialog, Behind_Item, &ItemType, (Handle *)&Behind_CHdl, &Bounds);
	SetFloat(Behind_CHdl,Data.Behind/FLOAT_WORLD_ONE);
	
	ControlHandle Upward_CHdl;
	GetDialogItem(Dialog, Upward_Item, &ItemType, (Handle *)&Upward_CHdl, &Bounds);
	SetFloat(Upward_CHdl,Data.Upward/FLOAT_WORLD_ONE);
	
	ControlHandle Rightward_CHdl;
	GetDialogItem(Dialog, Rightward_Item, &ItemType, (Handle *)&Rightward_CHdl, &Bounds);
	SetFloat(Rightward_CHdl,Data.Rightward/FLOAT_WORLD_ONE);
	
	MacCheckbox PassThruWall_CB(Dialog, PassThruWall_Item, TEST_FLAG(Data.Flags,_ChaseCam_ThroughWalls));
	MacCheckbox NeverActive_CB(Dialog, NeverActive_Item, TEST_FLAG(Data.Flags,_ChaseCam_NeverActive));
	MacCheckbox OnWhenEntering_CB(Dialog, OnWhenEntering_Item, TEST_FLAG(Data.Flags,_ChaseCam_OnWhenEntering));
	
	ControlHandle Damping_CHdl;
	GetDialogItem(Dialog, Damping_Item, &ItemType, (Handle *)&Damping_CHdl, &Bounds);
	SetFloat(Damping_CHdl,Data.Damping);
	
	ControlHandle Spring_CHdl;
	GetDialogItem(Dialog, Spring_Item, &ItemType, (Handle *)&Spring_CHdl, &Bounds);
	SetFloat(Spring_CHdl,Data.Spring);
	
	ControlHandle Opacity_CHdl;
	GetDialogItem(Dialog, CC_Opacity_Item, &ItemType, (Handle *)&Opacity_CHdl, &Bounds);
	SetFloat(Opacity_CHdl,Data.Opacity);
	
	// Where to make the color picker
	Point Center = {-1,-1};
	RGBColor NewColor;
	// Get void color from OpenGL-parameters data
	OGL_ConfigureData& OGLData = Get_OGL_ConfigureData();
	MacCheckbox VoidColorOnOff_CB(Dialog, VoidColorOnOff_Item, TEST_FLAG(OGLData.Flags,OGL_Flag_VoidColor));
	
	// Reveal it
#if USE_SHEETS
	SetThemeWindowBackground(GetDialogWindow(Dialog), kThemeBrushSheetBackgroundTransparent, false);
	ShowSheetWindow(GetDialogWindow(Dialog), ActiveNonFloatingWindow());
#else
	SelectWindow(GetDialogWindow(Dialog));
	ShowWindow(GetDialogWindow(Dialog));
#endif
	
	bool WillQuit = false;
	bool IsOK = false;
	short New_Behind = 0, New_Upward = 0, New_Rightward = 0;
	float FloatTemp = 0;
	bool BadValue;
	float New_Damping, New_Spring, New_Opacity;
	while(!WillQuit)
	{
		short ItemHit;
		ModalDialog(NULL, &ItemHit);
		
		switch(ItemHit)
		{
		case OK_Item:
		// Check before quitting
			BadValue = false;
			
			// Now doing roundoff correctly
			// Using a modification of AlexJLS's corrected version
			
			if (GetFloat(Behind_CHdl,FloatTemp))
				New_Behind = FloatRoundoff(WORLD_ONE * FloatTemp);
			else
				BadValue = true;
			
			if (GetFloat(Upward_CHdl,FloatTemp))
				New_Upward = FloatRoundoff(WORLD_ONE * FloatTemp);
			else
				BadValue = true;
			
			if (GetFloat(Rightward_CHdl,FloatTemp))
				New_Rightward = FloatRoundoff(WORLD_ONE * FloatTemp);
			else
				BadValue = true;
			
			if (GetFloat(Damping_CHdl,FloatTemp))
			{
				// Simple validation of the damping factor
				New_Damping = PIN(FloatTemp,-1,1);
				if (New_Damping != FloatTemp)
				{
					BadValue = true;
					SetFloat(Damping_CHdl,New_Damping);
				}
			}
			else
				BadValue = true;
			
			if (GetFloat(Spring_CHdl,FloatTemp))
			{
				New_Spring = FloatTemp;
			}
			else
				BadValue = true;
			
			if (GetFloat(Opacity_CHdl,FloatTemp))
			{
				New_Opacity = PIN(FloatTemp,0,1);
				if (New_Opacity != FloatTemp)
				{
					BadValue = true;
					SetFloat(Opacity_CHdl,New_Opacity);
				}
			}
			else
				BadValue = true;
			
			// Do validation: will the chase cam be unstable?			
			if (!BadValue)
			{
				if (New_Spring >= 0)
				{
					// Oscillatory case
					float NewDampSq = New_Damping*New_Damping;
					BadValue = ((NewDampSq + New_Spring) >= 1);
					if (BadValue)
					{
						New_Spring = 1 - NewDampSq;
						SetFloat(Spring_CHdl,New_Spring);
					}
				}
				else
				{
					// Overdamped case
					float NewDampAbs = fabs(New_Damping);
					BadValue = ((NewDampAbs + sqrt(-New_Spring)) >= 1);
					if (BadValue)
					{
						float Temp = 1 - NewDampAbs;
						New_Spring = - Temp*Temp;
						SetFloat(Spring_CHdl,New_Spring);
					}
				}	
			}
			
			if (BadValue)
			{
				SysBeep(30);
				break;
			}
		
			IsOK = true;
			WillQuit = true;
			break;
			
		case Cancel_Item:
			IsOK = false;
			WillQuit = true;
			break;
			
		case VoidColorSelect_Item:
			// Need to set color here so the preview can work properly
			if (GetColor(Center,"\pWhat color for the void?",&OGLData.VoidColor,&NewColor))
				OGLData.VoidColor = NewColor;
			break;
		
		default:
			if (PassThruWall_CB.ToggleIfHit(ItemHit)) break;
			if (NeverActive_CB.ToggleIfHit(ItemHit)) break;
			if (OnWhenEntering_CB.ToggleIfHit(ItemHit)) break;
			if (VoidColorOnOff_CB.ToggleIfHit(ItemHit)) break;
			break;
		}
	}
	
	if (IsOK)
	{
		Data.Behind = New_Behind;
		Data.Upward = New_Upward;
		Data.Rightward = New_Rightward;
		SET_FLAG(Data.Flags,_ChaseCam_ThroughWalls,PassThruWall_CB.GetState());
		SET_FLAG(Data.Flags,_ChaseCam_NeverActive,NeverActive_CB.GetState());
		SET_FLAG(Data.Flags,_ChaseCam_OnWhenEntering,OnWhenEntering_CB.GetState());
		SET_FLAG(OGLData.Flags,OGL_Flag_VoidColor,VoidColorOnOff_CB.GetState());
		Data.Damping = New_Damping;
		Data.Spring = New_Spring;
		Data.Opacity = New_Opacity;
	}
	
	// Clean up
#if USE_SHEETS
	HideSheetWindow(GetDialogWindow(Dialog));
#else
	HideWindow(GetDialogWindow(Dialog));
#endif
	DisposeDialog(Dialog);
	
	return IsOK;
}