示例#1
0
int32_t RunJob(MainThreadRunner *runner, MainThreadJob *job){
  JobEntry entry;

  // initialize the entry
  entry.runner = runner;
  entry.pepper_instance = runner->pepper_instance_;
  entry.job = job;

  bool in_main_thread = IsMainThread();
  // Must be off main thread, or on a pseudothread.
  assert(!in_main_thread || in_pseudo_thread_);

  // Thread type specific initialization.
  if (in_main_thread) {
    entry.pseudo_thread_job = true;
  } else {
    entry.pseudo_thread_job = false;
    // Init condition variable.
    entry.is_done = false;
    int ret = pthread_mutex_init(&entry.done_mutex, NULL);
    assert(!ret);
    ret = pthread_cond_init(&entry.done_cond, NULL);
    assert(!ret);
  }

  // put the job on the queue
  pthread_mutex_lock(&(runner->lock_));
  //job_queue_.push_back(&entry);
  //JobEntry_list_push_back(&entry, &(runner->job_queue_));
  runner->job_queue_[runner->qtail]=&entry;
  runner->qtail = (runner->qtail+1)%QSIZE;
  runner->size++;
  pthread_mutex_unlock(&(runner->lock_));

#ifdef USE_PEPPER
  // Schedule the job.
  //pp::Module::Get()->core()->CallOnMainThread(0,
  //    pp::CompletionCallback(&DoWorkShim, this), PP_OK);
  g_core_interface->CallOnMainThread(0,
      PP_MakeCompletionCallback(&DoWorkShim, runner), PP_OK);
#endif
  // Block differntly on the main thread.
  if (entry.pseudo_thread_job) {
    // block pseudothread until job is done
    PseudoThreadBlock();
  } else {
    // wait on condition until the job is done
    pthread_mutex_lock(&entry.done_mutex);
    while (!entry.is_done) {
      pthread_cond_wait(&entry.done_cond, &entry.done_mutex);
    }
    pthread_mutex_unlock(&entry.done_mutex);
    pthread_mutex_destroy(&entry.done_mutex);
    pthread_cond_destroy(&entry.done_cond);
  }
  // Cleanup.
  //delete job;
  free(job);
  return entry.result;
}
示例#2
0
文件: Win32Wnd.cpp 项目: koz4k/soccer
void Ctrl::EventLoop(Ctrl *ctrl)
{
	GuiLock __;
	ASSERT_(IsMainThread(), "EventLoop can only run in the main thread");
	ASSERT(LoopLevel == 0 || ctrl);
	LoopLevel++;
	LLOG("Entering event loop at level " << LoopLevel << LOG_BEGIN);
	Ptr<Ctrl> ploop;
	if(ctrl) {
		ploop = LoopCtrl;
		LoopCtrl = ctrl;
		ctrl->inloop = true;
	}

	bool quit = false;
	int64 loopno = ++EventLoopNo;
	ProcessEvents(&quit);
	while(loopno > EndSessionLoopNo && !quit && (ctrl ? ctrl->IsOpen() && ctrl->InLoop() : GetTopCtrls().GetCount()))
	{
//		LLOG(GetSysTime() << " % " << (unsigned)msecs() % 10000 << ": EventLoop / GuiSleep");
		SyncCaret();
		GuiSleep(1000);
//		LLOG(GetSysTime() << " % " << (unsigned)msecs() % 10000 << ": EventLoop / ProcessEvents");
		ProcessEvents(&quit);
//		LLOG(GetSysTime() << " % " << (unsigned)msecs() % 10000 << ": EventLoop / after ProcessEvents");
	}

	if(ctrl)
		LoopCtrl = ploop;
	LoopLevel--;
	LLOG(LOG_END << "Leaving event loop ");
}
示例#3
0
void Ctrl::GuiSleep0(int ms)
{
	GuiLock __;
	ASSERT(IsMainThread());
	ELOG("GuiSleep");
	if(EndSession())
		return;
	ELOG("GuiSleep 2");
	int level = LeaveGuiMutexAll();
#if !defined(flagDLL) && !defined(PLATFORM_WINCE)
	if(!OverwatchThread) {
		DWORD dummy;
		OverwatchThread = CreateThread(NULL, 0x100000, Win32OverwatchThread, NULL, 0, &dummy);
		ELOG("ExitLoopEventWait 1");
		ExitLoopEvent().Wait();
	}
	HANDLE h[1];
	*h = ExitLoopEvent().GetHandle();
	ELOG("ExitLoopEventWait 2 " << (void *)*h);
	MsgWaitForMultipleObjects(1, h, FALSE, ms, QS_ALLINPUT);
#else
	MsgWaitForMultipleObjects(0, NULL, FALSE, ms, QS_ALLINPUT);
#endif
	EnterGuiMutex(level);
}
示例#4
0
文件: AlphaMask.cpp 项目: AZidan/nme
SpanRect::SpanRect(const Rect &inRect, int inAA)
{
   mAA =  inAA;
   mAAMask = ~(mAA-1);
   mRect = inRect * inAA;
   mWinding = 0xffffffff;
   mTransitions = 0;
   
   if (IsMainThread())
   {
      if (sTransitionsBuffer.size() < mRect.h)
         sTransitionsBuffer.resize(mRect.h);
      mTransitions = &sTransitionsBuffer[0];
   }
   else
   {
      mTransitions = new Transitions[mRect.h];
   }
   
   for (int y = 0; y < mRect.h; y++)
   {
      mTransitions[y].mLeft = 0;
      mTransitions[y].mX.resize(0);
   }
   
   mMinX = (mRect.x - 1) << 10;
   mMaxX = (mRect.x1()) << 10;
   mLeftPos = mRect.x;
}
示例#5
0
void Ctrl::EventLoop(Ctrl *ctrl)
{
	GuiLock __;
	ASSERT_(IsMainThread(), "EventLoop can only run in the main thread");
	ASSERT(LoopLevel == 0 || ctrl);
	LoopLevel++;
	LLOG("Entering event loop at level " << LoopLevel << LOG_BEGIN);
	if(!GetMouseRight() && !GetMouseMiddle() && !GetMouseLeft())
		ReleaseCtrlCapture();
	Ptr<Ctrl> ploop;
	if(ctrl) {
		ploop = LoopCtrl;
		LoopCtrl = ctrl;
		ctrl->inloop = true;
	}

	while(!IsEndSession() &&
	      (ctrl ? ctrl->IsOpen() && ctrl->InLoop() : GetTopCtrls().GetCount())) {
		FetchEvents(TRUE);
		ProcessEvents();
	}

	if(ctrl)
		LoopCtrl = ploop;
	LoopLevel--;
	LLOG(LOG_END << "Leaving event loop ");
}
示例#6
0
文件: Window.cpp 项目: uvbs/myduilib
	bool CWin::RegisterSkin(STRINGorID xml, LPCTSTR type /* = NULL */, IDialogBuilderCallback* pCallback /* = NULL */, CControlUI* pParent /* = NULL */)
	{
		DuiLogInfo(_T("RegisterSkin xml:%s,type:%s"), (LPCTSTR)xml.m_lpstr, type == NULL ? _T("0") : type);
		assert(IsWindow());
		assert(IsMainThread());

		UnRegisterSkin();

		_paintManager = new CPaintManagerUI();
		_paintManager->Init(m_hWnd);
		
		CControlUI* pRoot = this->CreateRoot(xml,type,pCallback,pParent);
		if (!pRoot)
			DuiLogError(_T("RegisterSkin xml:%s,type:%s"), (LPCTSTR)xml.m_lpstr, (type == NULL ? _T("0") : type));
		CDuiString sError = CDuiString::FormatString(_T("Failed to parse XML:%s"), (LPCTSTR)xml.m_lpstr);
		char serror[MAX_PATH] = { 0 };
		sprintf_s(serror, MAX_PATH, "Failed to parse XML:%s", (LPCTSTR)xml.m_lpstr);
		ASSERT(pRoot && "Failed to parse XML");
		DuiAssertX(pRoot, serror);
		if (pRoot)
		{
			_bValid = TRUE;
			return _paintManager->AttachDialog(pRoot);
		}
		return false;
	}
示例#7
0
void Ctrl::EventLoop0(Ctrl *ctrl)
{
	GuiLock __;
	ASSERT(IsMainThread());
	ASSERT(LoopLevel == 0 || ctrl);
	LoopLevel++;
	LLOG("Entering event loop at level " << LoopLevel << BeginIndent);
	Ptr<Ctrl> ploop;
	if(ctrl) {
		ploop = LoopCtrl;
		LoopCtrl = ctrl;
		ctrl->inloop = true;
	}

	bool quit = false;
	ProcessEvents(&quit);
	while(!EndSession() && !quit && ctrl ? ctrl->IsOpen() && ctrl->InLoop() : GetTopCtrls().GetCount())
	{
//		LLOG(GetSysTime() << " % " << (unsigned)msecs() % 10000 << ": EventLoop / GuiSleep");
		SyncCaret();
		GuiSleep(1000);
		if(EndSession()) break;
//		LLOG(GetSysTime() << " % " << (unsigned)msecs() % 10000 << ": EventLoop / ProcessEvents");
		ProcessEvents(&quit);
//		LLOG(GetSysTime() << " % " << (unsigned)msecs() % 10000 << ": EventLoop / after ProcessEvents");
	}

	if(ctrl)
		LoopCtrl = ploop;
	LoopLevel--;
	LLOG(EndIndent << "Leaving event loop ");
}
示例#8
0
////////////////////////////////////////////////
//
// CreateDeviceSecondCallCheck
//
// Check for, and handle subsequent calls to create device
// Know to occur with RTSSHooks.dll (EVGA Precision X on screen display)
//
////////////////////////////////////////////////
bool CreateDeviceSecondCallCheck(HRESULT& hOutResult, IDirect3D9* pDirect3D, UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow, DWORD BehaviorFlags,
                                 D3DPRESENT_PARAMETERS* pPresentationParameters, IDirect3DDevice9** ppReturnedDeviceInterface)
{
    static uint uiCreateCount = 0;

    // Also check for invalid size
    if (pPresentationParameters->BackBufferWidth == 0)
    {
        WriteDebugEvent(SString(" Passing through call #%d to CreateDevice because size is invalid", uiCreateCount));
        return true;
    }

    // Also check for calls from other threads
    if (!IsMainThread())
    {
        SString strMessage(" Passing through call #%d to CreateDevice because not main thread", uiCreateCount);
        WriteDebugEvent(strMessage);
        AddReportLog(8627, strMessage);
        return true;
    }

    if (++uiCreateCount == 1)
        return false;
    WriteDebugEvent(SString(" Passing through call #%d to CreateDevice", uiCreateCount));
    hOutResult = pDirect3D->CreateDevice(Adapter, DeviceType, hFocusWindow, BehaviorFlags, pPresentationParameters, ppReturnedDeviceInterface);
    return true;
}
示例#9
0
  bool SchedulerBase::CreateSignalChannel(int *outSigId, SignalCallback callback, void *userdata)
  {
    LogAssert(IsMainThread());

    if (!LogVerify(outSigId) || !LogVerify(callback))
      return false;

    *outSigId = -1;

    // Create a set of pipes
    int fdPipe[2];
    int flags;
    int ret = pipe(fdPipe);

    if (ret != 0)
    {
      gLog.ErrnoError(errno, "Unable to create pipe for signaling");
      return false;
    }

    FileDescriptor pipeRead(fdPipe[0]);
    FileDescriptor pipeWrite(fdPipe[1]);

    flags = fcntl(pipeRead, F_GETFL);
    flags = flags | O_NONBLOCK;
    if (-1 == fcntl(pipeRead, F_SETFL, flags))
    {
      gLog.LogError("Failed to set read pipe to non-blocking.");
      return false;
    }
    flags = fcntl(pipeWrite, F_GETFL);
    flags = flags | O_NONBLOCK;
    if (-1 == fcntl(pipeWrite, F_SETFL, flags))
    {
      gLog.LogError("Failed to set write pipe to non-blocking.");
      return false;
    }

    if (!watchSocket(pipeRead))
      return false;

    schedulerSignalItem item;

    item.callback = callback;
    item.userdata = userdata;
    item.fdWrite = pipeWrite;
    item.fdRead = pipeRead;

    m_signals[item.fdRead] = item;

    pipeWrite.Detach();
    pipeRead.Detach();

    *outSigId = item.fdWrite;

    gLog.Optional(Log::TimerDetail, "Created signal channel from %d to %d .", item.fdWrite, item.fdRead);

    return true;
  }
示例#10
0
void Ctrl::GuiSleep(int ms)
{
	GuiLock __;
	ASSERT_(IsMainThread(), "Only the main thread can perform GuiSleep");
	if(ms < 20) // Periodic timer is each 20ms, so that is the longest possible wait
		g_timeout_add(ms, (GSourceFunc) sOnce, NULL); // otherwise setup shorter timer
	FetchEvents(TRUE);
}
示例#11
0
void Ctrl::GuiSleep0(int ms)
{
	GuiLock __;
	ASSERT(IsMainThread());
	LLOG("GuiSleep");
	int level = LeaveGuiMutexAll();
	FBSleep(ms);
	EnterGuiMutex(level);
}
 void DestroyShader(unsigned int inShader)
 {
    if ( !IsMainThread() )
    {
       mHasZombie = true;
       mZombieShaders.push_back(inShader);
    }
    else
       glDeleteShader(inShader);
 }
 void DestroyProgram(unsigned int inProg)
 {
    if ( !IsMainThread() )
    {
       mHasZombie = true;
       mZombiePrograms.push_back(inProg);
    }
    else
       glDeleteProgram(inProg);
 }
 void DestroyVbo(unsigned int inVbo)
 {
    if ( !IsMainThread() )
    {
       mHasZombie = true;
       mZombieVbos.push_back(inVbo);
    }
    else
       glDeleteBuffers(1,&inVbo);
 }
示例#15
0
 void DestroyTexture(unsigned int inTex)
 {
    if ( !IsMainThread() )
    {
       mHasZombie = true;
       mZombieTextures.push_back(inTex);
    }
    else
       glDeleteTextures(1,&inTex);
 }
示例#16
0
void Ctrl::GuiSleep(int ms)
{
	GuiLock __;
	ASSERT(IsMainThread());
//	LLOG("GuiSleep");
	int level = LeaveGuiMutexAll();
	socket.Timeout(ms).WaitRead();
	socket.Timeout(20000);
	EnterGuiMutex(level);
}
 void DestroyRenderbuffer(unsigned int inBuffer)
 {
    if ( !IsMainThread() )
    {
       mHasZombie = true;
       mZombieRenderbuffers.push_back(inBuffer);
    }
    else
       glDeleteRenderbuffers(1,&inBuffer);
 }
示例#18
0
bool Ctrl::SetWndCapture()
{
	GuiLock __;
	ASSERT(IsMainThread());
	HWND hwnd = GetHWND();
	if(hwnd) {
		::SetCapture(hwnd);
		return true;
	}
	return false;
}
示例#19
0
   void DestroyNativeTexture(void *inNativeTexture)
   {
      GLuint tid = (GLuint)(size_t)inNativeTexture;
      if ( !IsMainThread() )
      {
         //printf("Warning - leaking texture %d", tid );
		 mZombieTextures.push_back(tid);
      }
      else
         glDeleteTextures(1,&tid);
   }
示例#20
0
文件: Win32Wnd.cpp 项目: koz4k/soccer
bool Ctrl::ProcessEvents(bool *quit)
{
	ASSERT_(IsMainThread(), "ProcessEvents can only run in the main thread");
	if(ProcessEvent(quit)) {
		while(ProcessEvent(quit) && (!LoopCtrl || LoopCtrl->InLoop())); // LoopCtrl-MF 071008
		SweepMkImageCache();
		return true;
	}
	SweepMkImageCache();
	return false;
}
示例#21
0
bool Ctrl::ReleaseWndCapture()
{
	GuiLock __;
	ASSERT(IsMainThread());
	HWND hwnd = GetHWND();
	if(hwnd && HasWndCapture())
	{
		::ReleaseCapture();
		return true;
	}
	return false;
}
示例#22
0
// Fix to avoid black corners temorarily artifact
void Ctrl::Create0(Ctrl::CreateBox *cr)
{
	GuiLock __;
	ASSERT(IsMainThread());
	LLOG("Ctrl::Create(parent = " << (void *)parent << ") in " <<UPP::Name(this) << BeginIndent);
	ASSERT(!IsChild() && !IsOpen());
	Rect r = GetRect();
	AdjustWindowRectEx(r, cr->style, FALSE, cr->exstyle);
	isopen = true;
	top = new Top;
	ASSERT(!cr->parent || IsWindow(cr->parent));
	cr->style &= ~WS_VISIBLE;
	if(!IsWinXP())
		cr->dropshadow = false;
#ifdef PLATFORM_WINCE
		if(parent)
			top->hwnd = CreateWindowExW(cr->exstyle,
			                            cr->savebits ? cr->dropshadow ? L"UPP-CLASS-SB-DS-W" : L"UPP-CLASS-SB-W"
			                                         : cr->dropshadow ? L"UPP-CLASS-DS-W"    : L"UPP-CLASS-W",
			                            L"", cr->style, 0, 0, 0, 0,
			                            cr->parent, NULL, hInstance, this);
		else
			top->hwnd = CreateWindowW(L"UPP-CLASS-W",
			                          L"", WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
			                          cr->parent, NULL, hInstance, this);
#else
	if(IsWinNT() && (!cr->parent || IsWindowUnicode(cr->parent)))
		top->hwnd = CreateWindowExW(cr->exstyle,
		                            cr->savebits ? cr->dropshadow ? L"UPP-CLASS-SB-DS-W" : L"UPP-CLASS-SB-W"
		                                         : cr->dropshadow ? L"UPP-CLASS-DS-W"    : L"UPP-CLASS-W",
		                            L"", cr->style, 0, 0, 0, 0,
		                            cr->parent, NULL, hInstance, this);
	else
		top->hwnd = CreateWindowEx(cr->exstyle,
		                           cr->savebits ? cr->dropshadow ? "UPP-CLASS-SB-DS-A" : "UPP-CLASS-SB-A"
		                                        : cr->dropshadow ? "UPP-CLASS-DS-A"    : "UPP-CLASS-A",
		                           "", cr->style, 0, 0, 0, 0,
		                           cr->parent, NULL, hInstance, this);
#endif

	inloop = false;

	ASSERT(top->hwnd);

	::MoveWindow(top->hwnd, r.left, r.top, r.Width(), r.Height(), false); // To avoid "black corners" artifact effect
	::ShowWindow(top->hwnd, visible ? cr->show : SW_HIDE);
//	::UpdateWindow(hwnd);
	StateH(OPEN);
	LLOG(EndIndent << "//Ctrl::Create in " <<UPP::Name(this));
	RegisterDragDrop(top->hwnd, (LPDROPTARGET) (top->dndtgt = NewUDropTarget(this)));
	CancelMode();
	RefreshLayoutDeep();
}
示例#23
0
文件: Win32Wnd.cpp 项目: koz4k/soccer
void Ctrl::Create(HWND parent, DWORD style, DWORD exstyle, bool savebits, int show, bool dropshadow)
{
	GuiLock __;
	ASSERT_(IsMainThread(), "Window creation can only happen in the main thread");
	LLOG("Ctrl::Create(parent = " << (void *)parent << ") in " <<UPP::Name(this) << LOG_BEGIN);
	ASSERT(!IsChild() && !IsOpen());
	Rect r = GetRect();
	AdjustWindowRectEx(r, style, FALSE, exstyle);
	isopen = true;
	top = new Top;
	ASSERT(!parent || IsWindow(parent));
	style &= ~WS_VISIBLE;
	if(!IsWinXP())
		dropshadow = false;
#ifdef PLATFORM_WINCE
		if(parent)
			top->hwnd = CreateWindowExW(exstyle,
			                            savebits ? dropshadow ? L"UPP-CLASS-SB-DS-W" : L"UPP-CLASS-SB-W"
			                                         : dropshadow ? L"UPP-CLASS-DS-W"    : L"UPP-CLASS-W",
			                            L"", style, 0, 0, 0, 0,
			                            parent, NULL, hInstance, this);
		else
			top->hwnd = CreateWindowW(L"UPP-CLASS-W",
			                          L"", WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
			                          parent, NULL, hInstance, this);
#else
	if(IsWinNT() && (!parent || IsWindowUnicode(parent)))
		top->hwnd = CreateWindowExW(exstyle,
		                            savebits ? dropshadow ? L"UPP-CLASS-SB-DS-W" : L"UPP-CLASS-SB-W"
		                                         : dropshadow ? L"UPP-CLASS-DS-W"    : L"UPP-CLASS-W",
		                            L"", style, 0, 0, 0, 0,
		                            parent, NULL, hInstance, this);
	else
		top->hwnd = CreateWindowEx(exstyle,
		                           savebits ? dropshadow ? "UPP-CLASS-SB-DS-A" : "UPP-CLASS-SB-A"
		                                        : dropshadow ? "UPP-CLASS-DS-A"    : "UPP-CLASS-A",
		                           "", style, 0, 0, 0, 0,
		                           parent, NULL, hInstance, this);
#endif

	inloop = false;

	ASSERT(top->hwnd);
	::MoveWindow(top->hwnd, r.left, r.top, r.Width(), r.Height(), false); // To avoid "black corners" artifact effect
	::ShowWindow(top->hwnd, visible ? show : SW_HIDE);
//	::UpdateWindow(hwnd);
	StateH(OPEN);
	LLOG(LOG_END << "//Ctrl::Create in " <<UPP::Name(this));
	RegisterDragDrop(top->hwnd, (LPDROPTARGET) (top->dndtgt = NewUDropTarget(this)));
	CancelMode();
	RefreshLayoutDeep();
}
示例#24
0
void PseudoThreadResume(){
  // Must be run from the main thread.
  assert(IsMainThread());
  // Pseudothread must have been forked.
  assert(forked_pseudo_thread_);
  // Can only be run from the main thread.
  assert(!in_pseudo_thread_);
  if (!setjmp(main_thread_state_)) {
    // Go back to the pseudo thread after saving state.
    longjmp(pseudo_thread_state_, 1);
  }
  in_pseudo_thread_ = false;
}
示例#25
0
   bool nmeCoInitialize()
   {
      if (!IsMainThread())
         return CoInitializeEx(NULL,0)==S_OK;

      if (!nmeIsCoInit)
      {
         nmeIsCoInit = true;
         HRESULT result = CoInitializeEx(NULL,0);
         nmeIsCoInitOk = result==S_OK || result==S_FALSE || result==RPC_E_CHANGED_MODE;
      }
      return nmeIsCoInitOk;
   }
示例#26
0
文件: Win32Wnd.cpp 项目: koz4k/soccer
bool Ctrl::SetWndCapture()
{
	GuiLock __;
	LLOG("Ctrl::SetWndCapture() in " << UPP::Name(this));
	ASSERT(IsMainThread());
	HWND hwnd = GetHWND();
	if(hwnd) {
		::SetCapture(hwnd);
		LLOG("SetCapture succeeded");
		return true;
	}
	return false;
}
示例#27
0
bool Ctrl::ReleaseWndCapture0()
{
	GuiLock __;
	ASSERT(IsMainThread());
	LLOG("ReleaseWndCapture");
	if(grabwindow) {
		gdk_pointer_ungrab(CurrentTime);
		grabwindow = NULL;
		StartGrabPopup();
		return true;
	}
	return false;
}
示例#28
0
void PseudoThreadHeadroomFork(
	  int bytes_headroom, void *(*func)(void *arg), void *arg){
  // Must be run from the main thread.
  assert(IsMainThread());
  // Only one pseudothread can be forked.
  assert(!forked_pseudo_thread_);
  // Leave a gap of bytes_headroom on the stack between
  alloca(bytes_headroom);
  // Goto pseudothread, but remeber how to come back here.
  if (!setjmp(main_thread_state_)) {
    InnerPseudoThreadFork(func, arg);
  }
  in_pseudo_thread_ = false;
}
示例#29
0
void CInfoWindow::ShowInfo(HWND hparent,
	POINT pt,
	LPCTSTR pszText)
{
	assert(IsMainThread());
	this->KillTimer(_nTimerId);
	ShowWindow(SW_HIDE);
	SetText(pszText);

//	SetParent(hparent);
	AdjustWindow(hparent,pt);
	ShowWindow(SW_SHOWNORMAL);
	this->SetTimer(_nTimerId,1500);
}
示例#30
0
bool Ctrl::ProcessEvent(bool *quit)
{
	LLOG("@ ProcessEvent");
	ASSERT(IsMainThread());
	if(!GetMouseLeft() && !GetMouseRight() && !GetMouseMiddle())
		ReleaseCtrlCapture();
	if(FBProcessEvent(quit)) {
		LLOG("FBProcesEvent returned true");
		SyncTopWindows();
		DefferedFocusSync();
		SyncCaret();
		return true;
	}
	return false;
}