示例#1
0
/*!
 * Method to handle expose events with a background repainter. Events that
 * Pass through here are rapidly delt with by either expanding an
 * already existing expose rectangle to cover the expose rectangle of
 *  the current event or if there is no pending expose rectangle, because
 *  the background repainter has cleared it, set a new expose rectangle.
\param UT_Rect *rClip the rectangle of the expose event.
*/
void GR_Graphics::doRepaint( UT_Rect * rClip)
{
//
// Look if we have a pending expose left over.
//
	xxx_UT_DEBUGMSG(("SEVIOR: Starting doRepaint \n"));
	while(isSpawnedRedraw())
	{
		UT_usleep(100);
	}
//
// Stop the repainter
//
	setDontRedraw(true);
//
// Get a lock on the expose rectangle
//
	while(isExposedAreaAccessed())
	{
		UT_usleep(10); // 10 microseconds
	}
	setExposedAreaAccessed(true);
	if(isExposePending() || doMerge())
	{
		//
        // If so merge in the current expose area
        //
		xxx_UT_DEBUGMSG(("Doing a union in expose handler\n"));
		unionPendingRect( rClip);
		setRecentRect(rClip);
		setDoMerge(false);
	}
	else
	{
//
// Otherwise Load the current expose area into the redraw area.
//
		xxx_UT_DEBUGMSG(("Setting Exposed Area in expose handler \n"));
		setPendingRect(rClip->left,rClip->top,rClip->width,rClip->height);
		setRecentRect(rClip);
  	}
//
// Release expose rectangle lock
//
	setExposedAreaAccessed(false);
//
// Tell the repainter there is something to repaint.
//
	setExposePending(true);
//
// Allow the repainter to paint
//
	setDontRedraw(false);
	xxx_UT_DEBUGMSG(("SEVIOR: Finished doRepaint \n"));
//
// OK this event is handled.
//
}
示例#2
0
AP_UnixLeftRuler::~AP_UnixLeftRuler(void)
{
	GtkWidget * toplevel = static_cast<XAP_UnixFrameImpl *>(m_pFrame->getFrameImpl())->getTopLevelWindow();
	if (toplevel && g_signal_handler_is_connected(G_OBJECT(toplevel), m_iBackgroundRedrawID)) {
		g_signal_handler_disconnect(G_OBJECT(toplevel),m_iBackgroundRedrawID);
	}
	while(m_pG && m_pG->isSpawnedRedraw())
	{
		UT_usleep(100);
	}
	DELETEP(m_pG);
}
示例#3
0
/*!
 * Background abi repaint function.
\param XAP_UnixFrame * p pointer to the Frame that initiated this background
       repainter.
 */
gint AP_UnixLeftRuler::_fe::abi_expose_repaint( gpointer p)
{
//
// Grab our pointer so we can do useful stuff.
//
	UT_Rect localCopy;
	AP_UnixLeftRuler * pR = static_cast<AP_UnixLeftRuler *>(p);
	GR_Graphics * pG = pR->getGraphics();
	if(pG == NULL || pG->isDontRedraw())
	{
//
// Come back later
//
		return TRUE;
	}
	FV_View * pView = static_cast<FV_View *>(pR->m_pFrame->getCurrentView());
	if(pView && pView->getPoint()==0)
	{
//
// Come back later
//
		return TRUE;
	}
		
	pG->setSpawnedRedraw(true);
	if(pG->isExposePending())
	{
		while(pG->isExposedAreaAccessed())
		{
			UT_usleep(10); // 10 microseconds
		}
		pG->setExposedAreaAccessed(true);
		localCopy.set(pG->getPendingRect()->left,pG->getPendingRect()->top,
			      pG->getPendingRect()->width,pG->getPendingRect()->height);
//
// Clear out this set of expose info
//
		pG->setExposePending(false);
		pG->setExposedAreaAccessed(false);
		xxx_UT_DEBUGMSG(("Painting area on Left ruler:  left=%d, top=%d, width=%d, height=%d\n", localCopy.left, localCopy.top, localCopy.width, localCopy.height));
		xxx_UT_DEBUGMSG(("SEVIOR: Repaint now \n"));
		pR->draw(&localCopy);
	}
//
// OK we've finshed. Wait for the next signal
//
	pG->setSpawnedRedraw(false);
	return TRUE;
}
示例#4
0
/*!
  This function actually handles signals.  The most commonly recieved
  one is SIGSEGV, the segfault signal.  We want to clean up, save the
  user's files to backup locations (currently <filename>.saved) and then
  call abort, so we still get a core dump that we can debug.
  \param sig_num the integer representing which signal we recieved
*/
void AP_UnixApp::catchSignals(int /*sig_num*/)
{
    // Reset the signal handler 
    // (not that it matters - this is mostly for race conditions)
    signal(SIGSEGV, signalWrapper);

    s_signal_count = s_signal_count + 1;
    if(s_signal_count > 1)
    {
		UT_DEBUGMSG(("Crash during filesave - no file saved\n"));
		fflush(stdout);
		abort();
    }
    
    UT_DEBUGMSG(("Oh no - we just crashed!\n"));
//
// fixme: Enable this to help debug the bonobo component. After a crash the
// the program hangs here and you can connect to it from gdb and backtrace to
// the crash point
#ifdef LOGFILE
	fprintf(logfile,"abicrashed \n");
	fclose(logfile);
#endif

#if 0
	while(1)
	{
		UT_usleep(10000);
	}
#endif
    UT_sint32 i = 0;
	IEFileType abiType = IE_Imp::fileTypeForSuffix(".abw");
    for(;i<m_vecFrames.getItemCount();i++)
    {
		AP_UnixFrame * curFrame = const_cast<AP_UnixFrame*>(static_cast<const AP_UnixFrame*>(m_vecFrames[i]));
		UT_continue_if_fail(curFrame);
		if (NULL == curFrame->getFilename())
		  curFrame->backup(".abw.saved",abiType);
		else
		  curFrame->backup(".saved",abiType);
    }
    
    fflush(stdout);
    
    // Abort and dump core
    abort();
}
示例#5
0
//
// AbiPaint editImage
// ------------------
//   This is the function that we actually call to invoke the image editor.
//
//   parameters are:
//     AV_View* v
//     EV_EditMethodCallData *d
//
static DECLARE_ABI_PLUGIN_METHOD(editImage)
{
	UT_UNUSED(v);
    // Get the current view that the user is in.
    XAP_Frame *pFrame = XAP_App::getApp()->getLastFocussedFrame();
    FV_View* pView = static_cast<FV_View*>(pFrame->getCurrentView());

//
// get values from preference (initial plugin execution should have set sensible defaults)
//
	UT_String imageApp;  // holds MAXPATH\appName <space> MAXPATH\imagefilename
	bool bLeaveImageAsPNG;

	// read stuff from the preference value
	if (!prefsScheme->getValue(ABIPAINT_PREF_KEY_szProgramName, imageApp))
	{
		UT_ASSERT(UT_SHOULD_NOT_HAPPEN);
		getDefaultApp(imageApp, bLeaveImageAsPNG);
	}
	
	// now that we have program name, try to get other flag (allows overriding default value)
	// Note: we allow overriding, otherwise if we don't adhere to user's setting
	//       then the use BMP or not menu should be greyed to note it has no effect
	prefsScheme->getValueBool(ABIPAINT_PREF_KEY_bLeaveImageAsPNG, &bLeaveImageAsPNG);


//
// generate a temp file name...
//
	char *szTempFileName = NULL;
	GError *err = NULL;
	gint fp = g_file_open_tmp ("XXXXXX", &szTempFileName, &err);
	if (err) {
		g_warning ("%s", err->message);
		g_error_free (err); err = NULL;
		return FALSE;
	}
	close(fp);

	UT_String szTmpPng = szTempFileName;
	szTmpPng += ".png";
	UT_String szTmp = szTmpPng; // default: our temp file is the created png file
	
	PT_DocPosition pos = pView->saveSelectedImage((const char *)szTmpPng.c_str());
	if(pos == 0)
	{
		remove(szTempFileName);
		g_free (szTempFileName); szTempFileName = NULL;
		pFrame->showMessageBox("You must select an Image before editing it", XAP_Dialog_MessageBox::b_O,XAP_Dialog_MessageBox::a_OK);
		return false;
	}

#ifdef ENABLE_BMP
//
// Convert png into bmp for best compatibility with Windows programs
// NOTE: probably looses detail/information though!!! so if possible use PNG
//
	if (!bLeaveImageAsPNG)
	{
		szTmp = szTempFileName;
		szTmp += ".bmp";	// our temp file is a bmp file

		if (convertPNG2BMP(szTmpPng.c_str(), szTmp.c_str()))
		{
			pFrame->showMessageBox("Unable to convert PNG image data to BMP for external program use!", XAP_Dialog_MessageBox::b_O,XAP_Dialog_MessageBox::a_OK);
			UT_ASSERT(UT_SHOULD_NOT_HAPPEN);

			remove(szTempFileName);
			g_free (szTempFileName); szTempFileName = NULL;
			remove(szTmpPng.c_str());
			return false;
		}
		// remove(szTmpPng.c_str());

	}
#endif
	
	// remove the temp file (that lacks proper extension)
	remove(szTempFileName);
	g_free (szTempFileName); szTempFileName = NULL;

//
// Get the initial file status.
//
	struct stat myFileStat;
	int ok = stat(szTmp.c_str(),&myFileStat);
	if(ok < 0)
	{
		UT_ASSERT(UT_SHOULD_NOT_HAPPEN);
		remove(szTmpPng.c_str());
		remove(szTmp.c_str());	// should silently fail if exporting as PNG file
		return false;
	}
	time_t mod_time = myFileStat.st_mtime;

//	
// Fire up the image editor...
//
	ProcessInfo procInfo;
	if (!createChildProcess(imageApp.c_str(), szTmp.c_str(), &procInfo))

	{
		UT_String msg = "Unable to run program: ";  msg += imageApp + " " + szTmp;
		pFrame->showMessageBox(msg.c_str(), XAP_Dialog_MessageBox::b_O,XAP_Dialog_MessageBox::a_OK);

		// failed to spawn stuff, so do some cleanup and return failure
		remove(szTmpPng.c_str());
		remove(szTmp.c_str());	// should silently fail if exporting as PNG file
		return false;
	}

	lockGUI(d);

	while (isProcessStillAlive(procInfo))
	{
		UT_usleep(10000); // wait 10 milliseconds
		pFrame->nullUpdate();
		ok = stat(szTmp.c_str(),&myFileStat);
		if(ok == 0)
		{ 
			if(myFileStat.st_mtime != mod_time)
			{
				// wait for changes to settle (program done writing changes)
				// we use both modified time & file size, but really we
				// could just use file size as mod time doesn't appear to change for small images
				mod_time = myFileStat.st_mtime;
				off_t size = myFileStat.st_size;
				UT_usleep(100000); // wait 100 milliseconds (so program may have time to write something)
				ok = stat(szTmp.c_str(),&myFileStat);
				while((mod_time != myFileStat.st_mtime) || !size || (size > 0 && size != myFileStat.st_size))
				{
					mod_time = myFileStat.st_mtime;
					size = myFileStat.st_size;
					ok = stat(szTmp.c_str(),&myFileStat);
					UT_usleep(500000); // wait a while, let program write its data

					// just make sure the program is still running, otherwise we could get stuck in a loop
					if (!isProcessStillAlive(procInfo))
					{
						pFrame->showMessageBox("External image editor appears to have been terminated unexpectedly.", 
								XAP_Dialog_MessageBox::b_O,XAP_Dialog_MessageBox::a_OK);
						//procInfo.hProcess = 0;
						goto Cleanup;
					}
				}
				mod_time = myFileStat.st_mtime;
				UT_usleep(100000); // wait a while just to make sure program is done with file

//
// OK replace the current image with this.
//
				IEGraphicFileType iegft = IEGFT_Unknown;
				FG_Graphic* pFG;
		
				UT_Error errorCode;
		
#ifdef ENABLE_BMP
//
// Convert bmp back to png (as we can not assume AbiWord has builtin BMP support [as its now an optional plugin])
// NOTE: probably looses detail/information though!!! so if possible use only PNG
//
				if (!bLeaveImageAsPNG)
				{
					if (convertBMP2PNG(szTmp.c_str(), szTmpPng.c_str()))
					{
						pFrame->showMessageBox("Unable to convert BMP image data back to PNG for AbiWord to import!", XAP_Dialog_MessageBox::b_O,XAP_Dialog_MessageBox::a_OK);
						UT_ASSERT(UT_SHOULD_NOT_HAPPEN);
						goto Cleanup;
					}
				}
#endif

				errorCode = IE_ImpGraphic::loadGraphic(szTmpPng.c_str(), iegft, &pFG);
				if(errorCode)
				{
					UT_ASSERT(UT_SHOULD_NOT_HAPPEN);
					pFrame->showMessageBox("Error making pFG. Could not put image back into Abiword", XAP_Dialog_MessageBox::b_O,XAP_Dialog_MessageBox::a_OK);
					goto Cleanup;
				}

				unlockGUI(d);

				pView->cmdUnselectSelection();
				pView->setPoint(pos);
				pView->extSelHorizontal(true, 1); // move point forward one
				errorCode = pView->cmdInsertGraphic(pFG);
				if (errorCode)
				{
					pFrame->showMessageBox("Could not put image back into Abiword", XAP_Dialog_MessageBox::b_O,XAP_Dialog_MessageBox::a_OK);
					UT_ASSERT(UT_SHOULD_NOT_HAPPEN);
					DELETEP(pFG);
					goto Cleanup;
				}
				DELETEP(pFG);
//
// Reselect the image
//
				pView->setPoint(pos);
				pView->extSelHorizontal(true, 1); // move point forward one

				lockGUI(d);
			}
		}
	}

//
// Normal exit, delete the tempfile and return success
//
	remove(szTmpPng.c_str());
	remove(szTmp.c_str());	// should silently fail if exporting as PNG file
	unlockGUI(d);
	return true;

//
// Something went wrong.
//
 Cleanup: 
	remove(szTmpPng.c_str());
	remove(szTmp.c_str());	// should silently fail if exporting as PNG file
	unlockGUI(d);
//
// Kill the image editor.
//
	endProcess(procInfo);
	return false;
}