示例#1
0
文件: MainWindow.cpp 项目: ysei/haiku
void
MainWindow::WorkspaceActivated(int32 workspace, bool active)
{
	if (fShowOnAllWorkspaces) {
		if (!active)
			_GetLocation();
		else
			_AdjustLocation(Frame());
	}
}
示例#2
0
/***
* _fpieee_flt - IEEE fp filter routine
*
*Purpose:
*   Invokes the user's trap handler on IEEE fp exceptions and provides
*   it with all necessary information
*
*Entry:
*   unsigned long exc_code: the NT exception code
*   PEXCEPTION_POINTERS p: a pointer to the NT EXCEPTION_POINTERS struct
*   int handler (_FPIEEE_RECORD *): a user supplied ieee trap handler
*
*   Note: The IEEE filter routine does not handle some transcendental
*   instructions. This can be done at the cost of additional decoding.
*   Since the compiler does not generate these instructions, no portable
*   program should be affected by this fact.
*
*Exit:
*   returns the value returned by handler
*
*Exceptions:
*
*******************************************************************************/
int _fpieee_flt(unsigned long exc_code,
		PEXCEPTION_POINTERS p,
		int (__cdecl *handler) (_FPIEEE_RECORD *))
{
    PEXCEPTION_RECORD pexc;
    PCONTEXT pctxt;
    PFLOATING_SAVE_AREA pFloatSave;
    _FPIEEE_RECORD ieee;
    ULONG *pinfo;
    X87INSTR instr;
    PINSTR_INFO ptable;
    int ret, index;
    int mod;
    ULONG cw, sw;

    ULONG op1Location, op2Location, resultLocation;
    ULONG newOp1Location, newOp2Location, newResultLocation;



    //
    // If the exception is not an IEEE exception, continue search
    // for another handler
    //


    if (exc_code != STATUS_FLOAT_DIVIDE_BY_ZERO &&
	exc_code != STATUS_FLOAT_INEXACT_RESULT &&
	exc_code != STATUS_FLOAT_INVALID_OPERATION &&
	exc_code != STATUS_FLOAT_OVERFLOW &&
	exc_code != STATUS_FLOAT_UNDERFLOW) {

	return EXCEPTION_CONTINUE_SEARCH;
    }



    pexc = p->ExceptionRecord;
    pinfo = pexc->ExceptionInformation;
    pctxt = p->ContextRecord;
    pFloatSave = &pctxt->FloatSave;


    _asm{fninit}


    //
    // Check for software generated exception
    //
    // By convention the first argument to the exception is
    // 0 for h/w exception. For s/w exceptions it points
    // to the _FPIEEE_RECORD
    //

    if (pinfo[0]) {

	/*
	 * we have a software exception:
	 * the first parameter points to the IEEE structure
	 */

	if ((ret = handler((_FPIEEE_RECORD *)(pinfo[0]))) ==
	     EXCEPTION_CONTINUE_EXECUTION) {

	    //
	    // Sanitize status word only if there is continuation
	    //

	    SANITIZE_STATUS_WORD(pFloatSave);
	}

	return ret;
    }


    //
    // If control reaches here, then we have to deal with a
    // hardware exception
    //


    //
    // If the first byte of the instruction does not contain
    // the ESCAPE bit pattern (1101) there may be an instruction
    // prefix for segment override or address size. The filter
    // routine does not handle this.
    //

    if ((*(UCHAR *)(pFloatSave->ErrorOffset)&~MASK_OPCODE1) != ESC_PREFIX) {

	_ASSERT(0);
	return EXCEPTION_CONTINUE_SEARCH;
    }

    *(USHORT *)&instr = *(USHORT *)(pFloatSave->ErrorOffset);

    mod = instr.Mod == 0x3 ? 1 : 0;
    index = instr.Opcode1 << 4 | mod << 3 | instr.Opcode2;
    ptable = instr_info_table + index;

    ieee.Operation = ptable->Operation;


    cw = pFloatSave->ControlWord;
    sw = pFloatSave->StatusWord;



    //
    // decode fp environment information
    //


    switch (cw & IMCW_RC) {
    case IRC_NEAR:
	ieee.RoundingMode = _FpRoundNearest;
	break;

    case IRC_DOWN:
	ieee.RoundingMode = _FpRoundMinusInfinity;
	break;

    case IRC_UP:
	ieee.RoundingMode = _FpRoundPlusInfinity;
	break;

    case IRC_CHOP:
	ieee.RoundingMode = _FpRoundChopped;
	break;
    }

    switch (cw & IMCW_PC) {
    case IPC_64:
	ieee.Precision = _FpPrecisionFull;
	break;
    case IPC_53:
	ieee.Precision = _FpPrecision53;
	break;
    case IPC_24:
	ieee.Precision = _FpPrecision24;
	break;
    }

    ieee.Enable.Inexact = cw & IEM_INEXACT ? 0 : 1;
    ieee.Enable.Underflow = cw & IEM_UNDERFLOW ? 0 : 1;
    ieee.Enable.Overflow = cw & IEM_OVERFLOW ? 0 : 1;
    ieee.Enable.ZeroDivide = cw & IEM_ZERODIVIDE ? 0 : 1;
    ieee.Enable.InvalidOperation = cw & IEM_INVALID ? 0 : 1;

    ieee.Status.Inexact = sw & ISW_INEXACT ? 1 : 0;
    ieee.Status.Underflow = sw & ISW_UNDERFLOW ? 1 : 0;
    ieee.Status.Overflow = sw & ISW_OVERFLOW ? 1 : 0;
    ieee.Status.ZeroDivide = sw & ISW_ZERODIVIDE ? 1 : 0;
    ieee.Status.InvalidOperation = sw & ISW_INVALID ? 1 : 0;

    ieee.Cause.Inexact = ieee.Enable.Inexact && ieee.Status.Inexact;
    ieee.Cause.Underflow = ieee.Enable.Underflow && ieee.Status.Underflow;
    ieee.Cause.Overflow = ieee.Enable.Overflow && ieee.Status.Overflow;
    ieee.Cause.ZeroDivide = ieee.Enable.ZeroDivide && ieee.Status.ZeroDivide;
    ieee.Cause.InvalidOperation = ieee.Enable.InvalidOperation && ieee.Status.InvalidOperation;

    //
    // If location is REG, the register number is
    // encoded in the instruction
    //

    op1Location = ptable->Op1Location == REG ?
		  instr.Reg :
		  ptable->Op1Location;


    op2Location = ptable->Op2Location == REG ?
		  instr.Reg :
		  ptable->Op2Location;

    resultLocation = ptable->ResultLocation == REG ?
		  instr.Reg :
		  ptable->ResultLocation;


    switch (exc_code) {
    case STATUS_FLOAT_INVALID_OPERATION:
    case STATUS_FLOAT_DIVIDE_BY_ZERO:

	//
	// Invalid Operation and Divide by zero are detected
	// before the operation begins; therefore the NPX
	// register stack and memory have not been updated
	//

	_FillOperand(&ieee.Operand1, pFloatSave, op1Location);
	_FillOperand(&ieee.Operand2, pFloatSave, op2Location);

	_FillOperand(&ieee.Result, pFloatSave, resultLocation);

	//
	// The previous	call was only good for setting the
	// result Format. Since the
	// operation has not begun yet, the result location
	// may contain an incorrect value.
	// For this reason, set OperandValid to 0
	//

	ieee.Result.OperandValid = 0;


	if ((ret = handler (&ieee)) == EXCEPTION_CONTINUE_EXECUTION) {

	    _UpdateFpCtxt(pFloatSave,
			  &ieee.Result,
			  resultLocation,
			  ptable->PopStack);
	}

	break;


    case STATUS_FLOAT_OVERFLOW:
    case STATUS_FLOAT_UNDERFLOW:

	//
	// Overflow and Underflow exception
	// A result has already been computed and the stack has
	// been adjusted, unless the destination is memory (FST instruction)
	//

	if (_IsMemoryLocation(ptable->ResultLocation)) {
	    _FP80 tmp;
	    _FP32 ftmp;
	    _FP64 dtmp;

	    int adj;

	    //
	    // FST(P) instruction (takes only one argument)
	    //

	    _FillOperand(&ieee.Operand1, pFloatSave, op1Location);
	    tmp = _GetFpRegVal(pFloatSave, 0);

	    ieee.Result.OperandValid = 1;

	    if (resultLocation == M32R) {
		ieee.Result.Format = _FpFormatFp32;
		adj = _ieee_adj_single;
	    }
	    else {
		ieee.Result.Format = _FpFormatFp64;
		adj = _ieee_adj_double;
	    }

	    if (exc_code == STATUS_FLOAT_OVERFLOW) {
		adj = -adj;
	    }

	    SCALE(tmp, adj)

	    if (resultLocation == M32R){
		FP80_TO_FP32(ftmp,tmp)
		ieee.Result.Value.Fp32Value = ftmp;
	    }
	    else {
		FP80_TO_FP64(dtmp,tmp)
		ieee.Result.Value.Fp64Value = dtmp;
	    }
	    _asm{fnclex}


	    if ((ret = handler (&ieee)) == EXCEPTION_CONTINUE_EXECUTION) {

		_UpdateFpCtxt(pFloatSave,
			      &ieee.Result,
			      resultLocation,
			      ptable->PopStack);
	    }

	    break;
	}


	// NO BREAK

    case STATUS_FLOAT_INEXACT_RESULT:

	//
	// Stack has already been adjusted, so we should compute
	// the new location of operands and result
	//


	newOp1Location = _AdjustLocation(op1Location, ptable->PopStack);
	newOp2Location = _AdjustLocation(op2Location, ptable->PopStack);
	newResultLocation = _AdjustLocation(resultLocation, ptable->PopStack);

	if (newOp1Location == newResultLocation)
	    newOp1Location = INV;

	if (newOp2Location == newResultLocation)
	    newOp2Location = INV;

	_FillOperand(&ieee.Result, pFloatSave, newResultLocation);
	_FillOperand(&ieee.Operand1, pFloatSave, newOp1Location);
	_FillOperand(&ieee.Operand2, pFloatSave, newOp2Location);


	if ((ret = handler (&ieee)) == EXCEPTION_CONTINUE_EXECUTION) {

	    _UpdateFpCtxt(pFloatSave, &ieee.Result, newResultLocation, 0);

	    //
	    // no need to adjust the stack
	    //
	}

	break;
    }
示例#3
0
文件: MainWindow.cpp 项目: ysei/haiku
bool
MainWindow::LoadSettings(const BMessage* message)
{
	// restore window positioning
	BPoint point;
	bool useAdjust = false;
	if (message->FindPoint("window position", &point) == B_OK) {
		fScreenPosition = point;
		useAdjust = true;
	}
	float borderDist;
	if (message->FindFloat("border distance", &borderDist) == B_OK) {
		fBorderDist = borderDist;
	}
	// restore window frame
	BRect frame;
	if (message->FindRect("window frame", &frame) == B_OK) {
		if (useAdjust) {
			_AdjustLocation(frame);
		} else {
			make_sure_frame_is_on_screen(frame, this);
			MoveTo(frame.LeftTop());
			ResizeTo(frame.Width(), frame.Height());
		}
	}

	// restore window look
	window_look look;
	if (message->FindInt32("window look", (int32*)&look) == B_OK)
		SetLook(look);

	// restore orientation
	int32 orientation;
	if (message->FindInt32("orientation", &orientation) == B_OK)
		fPadView->SetOrientation((enum orientation)orientation);

	// restore icon size
	int32 iconSize;
	if (message->FindInt32("icon size", &iconSize) == B_OK)
		fPadView->SetIconSize(iconSize);

	// restore ignore double click
	bool ignoreDoubleClick;
	if (message->FindBool("ignore double click", &ignoreDoubleClick) == B_OK)
		fPadView->SetIgnoreDoubleClick(ignoreDoubleClick);

	// restore buttons
	const char* path;
	bool buttonAdded = false;
	for (int32 i = 0; message->FindString("path", i, &path) >= B_OK; i++) {
		LaunchButton* button = new LaunchButton("launch button",
			NULL, new BMessage(MSG_LAUNCH));
		fPadView->AddButton(button);
		BString signature;
		if (message->FindString("signature", i, &signature) >= B_OK
			&& signature.CountChars() > 0)  {
			button->SetTo(signature.String(), true);
		}

		BEntry entry(path, true);
		entry_ref ref;
		if (entry.Exists() && entry.GetRef(&ref) == B_OK)
			button->SetTo(&ref);

		const char* text;
		if (message->FindString("description", i, &text) >= B_OK)
			button->SetDescription(text);
		buttonAdded = true;
	}

	// restore auto raise setting
	bool autoRaise;
	if (message->FindBool("auto raise", &autoRaise) == B_OK && autoRaise)
		ToggleAutoRaise();

	// store workspace setting
	bool showOnAllWorkspaces;
	if (message->FindBool("all workspaces", &showOnAllWorkspaces) == B_OK)
		fShowOnAllWorkspaces = showOnAllWorkspaces;
		SetWorkspaces(showOnAllWorkspaces
			? B_ALL_WORKSPACES : 1L << current_workspace());
	if (!fShowOnAllWorkspaces) {
		uint32 workspaces;
		if (message->FindInt32("workspaces", (int32*)&workspaces) == B_OK)
			SetWorkspaces(workspaces);
	}

	return buttonAdded;
}
示例#4
0
文件: MainWindow.cpp 项目: ysei/haiku
void
MainWindow::ScreenChanged(BRect frame, color_space format)
{
	_AdjustLocation(Frame());
}