+// Callback for cursor timer
+void BufferView::Pimpl::cursorToggle()
+{
+ // Quite a nice place for asyncron Inset updating, isn't it?
+ // Actually no! This is run even if no buffer exist... so (Lgb)
+ if (!buffer_) {
+ goto set_timer_and_return;
+ }
+
+ // NOTE:
+ // On my quest to solve the gs render hangups I am now
+ // disabling the SIGHUP completely, and will do a wait
+ // now and then instead. If the guess that xforms somehow
+ // destroys something is true, this is likely (hopefully)
+ // to solve the problem...at least I hope so. Lgb
+
+ // ...Ok this seems to work...at least it does not make things
+ // worse so far. However I still see gs processes that hangs.
+ // I would really like to know _why_ they are hanging. Anyway
+ // the solution without the SIGCHLD handler seems to be easier
+ // to debug.
+
+ // When attaching gdb to a a running gs that hangs it shows
+ // that it is waiting for input(?) Is it possible for us to
+ // provide that input somehow? Or figure what it is expecing
+ // to read?
+
+ // One solution is to, after some time, look if there are some
+ // old gs processes still running and if there are: kill them
+ // and re render.
+
+ // Another solution is to provide the user an option to rerender
+ // a picture. This would, for the picture in question, check if
+ // there is a gs running for it, if so kill it, and start a new
+ // rendering process.
+
+ // these comments posted to lyx@via
+ {
+ int status = 1;
+ int pid = waitpid(static_cast<pid_t>(0), &status, WNOHANG);
+ if (pid == -1) // error find out what is wrong
+ ; // ignore it for now.
+ else if (pid > 0)
+ sigchldhandler(pid, &status);
+ }
+
+ updatelist.update(bv_);
+
+ if (!screen_) {
+ goto set_timer_and_return;
+ }
+
+ if (!bv_->the_locking_inset) {
+ screen_->CursorToggle(bv_->text);
+ } else {
+ bv_->the_locking_inset->
+ ToggleInsetCursor(bv_);
+ }
+
+ set_timer_and_return:
+ cursor_timeout.restart();
+ return;
+}
+
+
+void BufferView::Pimpl::cursorPrevious()
+{
+ if (!bv_->text->cursor.row()->previous()) return;
+
+ int y = bv_->text->first;
+ Row * cursorrow = bv_->text->cursor.row();
+ bv_->text->SetCursorFromCoordinates(bv_, bv_->text->cursor.x_fix(), y);
+ bv_->text->FinishUndo();
+ // This is to allow jumping over large insets
+ if ((cursorrow == bv_->text->cursor.row()))
+ bv_->text->CursorUp(bv_);
+
+ if (bv_->text->cursor.row()->height() < workarea_->height())
+ screen_->Draw(bv_->text,
+ bv_->text->cursor.y()
+ - bv_->text->cursor.row()->baseline()
+ + bv_->text->cursor.row()->height()
+ - workarea_->height() + 1 );
+ updateScrollbar();
+}
+
+
+void BufferView::Pimpl::cursorNext()
+{
+ if (!bv_->text->cursor.row()->next()) return;
+
+ int y = bv_->text->first;
+ bv_->text->GetRowNearY(y);
+ Row * cursorrow = bv_->text->cursor.row();
+ bv_->text->SetCursorFromCoordinates(bv_, bv_->text->cursor.x_fix(), y
+ + workarea_->height());
+ bv_->text->FinishUndo();
+ // This is to allow jumping over large insets
+ if ((cursorrow == bv_->text->cursor.row()))
+ bv_->text->CursorDown(bv_);
+
+ if (bv_->text->cursor.row()->height() < workarea_->height())
+ screen_->Draw(bv_->text, bv_->text->cursor.y()
+ - bv_->text->cursor.row()->baseline());
+ updateScrollbar();
+}
+
+
+bool BufferView::Pimpl::available() const
+{
+ if (buffer_ && bv_->text) return true;
+ return false;
+}
+
+
+void BufferView::Pimpl::beforeChange()
+{
+ toggleSelection();
+ bv_->text->ClearSelection();
+
+ // CHECK
+ //owner_->update_timeout.stop();
+}
+
+
+void BufferView::Pimpl::savePosition()
+{
+ backstack.push(buffer_->fileName(),
+ bv_->text->cursor.x(),
+ bv_->text->cursor.y());
+}
+
+
+void BufferView::Pimpl::restorePosition()
+{
+ if (backstack.empty()) return;
+
+ int x, y;
+ string fname = backstack.pop(&x, &y);
+
+ beforeChange();
+
+ if( fname != buffer_->fileName() ) {
+ Buffer * b = bufferlist.exists(fname) ?
+ bufferlist.getBuffer(fname) :
+ bufferlist.loadLyXFile(fname); // don't ask, just load it
+ if( b != 0 ) buffer(b);
+ }
+
+ bv_->text->SetCursorFromCoordinates(bv_, x, y);
+ update(BufferView::SELECT|BufferView::FITCUR);
+}
+
+
+bool BufferView::Pimpl::NoSavedPositions()
+{
+ return backstack.empty();
+}
+
+
+void BufferView::Pimpl::setState()
+{
+ if (!lyxrc.rtl_support)
+ return;
+
+ if (bv_->text->real_current_font.isRightToLeft() &&
+ bv_->text->real_current_font.latex() != LyXFont::ON) {
+ if (owner_->getIntl()->primarykeymap)
+ owner_->getIntl()->KeyMapSec();
+ } else {
+ if (!owner_->getIntl()->primarykeymap)
+ owner_->getIntl()->KeyMapPrim();
+ }
+}
+
+
+void BufferView::Pimpl::insetSleep()
+{
+ if (bv_->the_locking_inset && !bv_->inset_slept) {
+ bv_->the_locking_inset->GetCursorPos(bv_, bv_->slx, bv_->sly);
+ bv_->the_locking_inset->InsetUnlock(bv_);
+ bv_->inset_slept = true;
+ }
+}
+
+
+void BufferView::Pimpl::insetWakeup()
+{
+ if (bv_->the_locking_inset && bv_->inset_slept) {
+ bv_->the_locking_inset->Edit(bv_, bv_->slx, bv_->sly, 0);
+ bv_->inset_slept = false;
+ }
+}
+
+
+void BufferView::Pimpl::insetUnlock()
+{
+ if (bv_->the_locking_inset) {
+ if (!bv_->inset_slept) bv_->the_locking_inset->InsetUnlock(bv_);
+ bv_->the_locking_inset = 0;
+ bv_->text->FinishUndo();
+ bv_->inset_slept = false;
+ }
+}
+
+
+bool BufferView::Pimpl::focus() const
+{
+ return workarea_->hasFocus();
+}
+
+
+void BufferView::Pimpl::focus(bool f)
+{
+ if (f) workarea_->setFocus();
+}
+
+
+bool BufferView::Pimpl::active() const
+{
+ return workarea_->active();
+}
+
+
+bool BufferView::Pimpl::belowMouse() const
+{
+ return workarea_->belowMouse();
+}
+
+
+void BufferView::Pimpl::showCursor()
+{
+ if (screen_)
+ screen_->ShowCursor(bv_->text);
+}
+
+
+void BufferView::Pimpl::hideCursor()
+{
+ if (screen_)
+ screen_->HideCursor();
+}
+
+
+void BufferView::Pimpl::toggleSelection(bool b)
+{
+ if (screen_)
+ screen_->ToggleSelection(bv_->text, b);
+}
+
+
+void BufferView::Pimpl::toggleToggle()
+{
+ if (screen_)
+ screen_->ToggleToggle(bv_->text);
+}
+
+
+void BufferView::Pimpl::center()
+{
+ beforeChange();
+ if (bv_->text->cursor.y() > workarea_->height() / 2) {
+ screen_->Draw(bv_->text, bv_->text->cursor.y() - workarea_->height() / 2);
+ } else {
+ screen_->Draw(bv_->text, 0);
+ }
+ update(BufferView::SELECT|BufferView::FITCUR);
+ redraw();
+}
+
+
+void BufferView::Pimpl::pasteClipboard(bool asPara)