Adding the SANE plugin as an example Linux XPCOM plugin.

This check-in related to bug #25068.  This isn't part of the build.
This commit is contained in:
rusty.lynch%intel.com 2000-06-02 04:11:45 +00:00
Родитель 9a72cc8908
Коммит 79196ab9b1
20 изменённых файлов: 8008 добавлений и 0 удалений

Просмотреть файл

@ -0,0 +1,57 @@
############################################################################
## Makefile.in (Generic SANE Plugin Tree)
##
## The contents of this file are subject to the Mozilla Public
## License Version 1.1 (the "License"); you may not use this file
## except in compliance with the License. You may obtain a copy of
## the License at http://www.mozilla.org/MPL/
##
## Software distributed under the License is distributed on an "AS
## IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
## implied. See the License for the specific language governing
## rights and limitations under the License.
## Contributor(s):
##
## Rusty Lynch <rusty.lynch@intel.com>
############################################################################
DEPTH = ../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
MODULE = SanePlugin
LIBRARY_NAME = Sane
IS_COMPONENT = 1
REQUIRES = raptor xpcom
CPPSRCS = \
nsSanePluginFactory.cpp \
nsSanePlugin.cpp \
$(NULL)
LOCAL_INCLUDES = -I$(srcdir)/.. -I$(srcdir)/../../public \
-I/usr/lib/glib/include
EXTRA_DSO_LDOPTS += -L$(DIST)/lib -lgtksuperwin \
$(TK_LIBS) -lsane -ljpeg
XPIDLSRCS = nsSanePluginControl.idl
include $(topsrcdir)/config/rules.mk
install:: $(TARGETS)
$(INSTALL) $(srcdir)/test/camera.html $(DIST)/bin/res/samples
$(INSTALL) $(srcdir)/test/scanner.html $(DIST)/bin/res/samples
$(INSTALL) $(srcdir)/test/camera.html /home/httpd/html/test
$(INSTALL) $(srcdir)/test/scanner.html /home/httpd/html/test
superclean: clean
rm -f *~ test/*~

Просмотреть файл

@ -0,0 +1,45 @@
What is this plug-in?
---------------------
This is a Linux/Mozilla plug-in that enables a scanner/digital
camera application to be created with JavaScript. To this end
the SANE plug-in provides two things:
1. I have attempted to export all of the SANE API's
from the SANE native libraries to JavaScript.
(I have provided two brain-dead samples for a
CPia USB digital camera and HP 6300 scanner.)
2. A drawing surface for displaying the scanned image.
=====================================================================
Why did you bother?
------------------
Originally, I used this plug-in to cut my teeth on the new Mozilla
XPCom plug-in model. Now I am hoping to provide a Linux/Mozilla
plug-in sample that exercises most of the functionality that the
Linux community would want to use (like connecting JavaScript
to native code.)
=====================================================================
You know, Linux isn't the only UN*X around!
-------------------------------------------
I say Linux because that is the only platform I have built/tested on.
SANE is supported by a long list of UN*X OS's so there is no reason
that other platforms shouldn't work with this plug-in.
(I have tried to stick to NSPR functions for this reason, but it's easy
to over look a couple of Linux specific functions.)
======================================================================
How do I build this beast?
-------------------------
In order to build this plug-in, you need the SANE (Scanner Access
Now Easy) libraries/headers installed on your system. For more
info on SANE, go to http://www.mostang.com/sane.

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -0,0 +1,238 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
* Contributor(s):
*
* Rusty Lynch <rusty.lynch@intel.com>
*/
/*
* Declares the nsSanePluginInterface class for the SANE plugin.
*/
#ifndef __NS_SANE_PLUGIN_H__
#define __NS_SANE_PLUGIN_H__
#include "prthread.h"
#include "nscore.h"
#include "nsplugin.h"
#include "gdksuperwin.h"
#include "gtkmozbox.h"
#include "gtk/gtk.h"
#include "nsIPlugin.h"
#include "nsSanePluginControl.h"
#include "nsIScriptContext.h"
#include "nsIServiceManager.h"
#include "nsISupports.h"
#include "nsISupportsUtils.h"
#include "nsIEventQueueService.h"
#include "nsIEventQueue.h"
///////////////////////////////////
// Needed for encoding jpeg images
extern "C"
{
#include <jpeglib.h>
}
///////////////////////////////////
// Needed for SANE interface
extern "C"
{
#include <sane/sane.h>
#include <sane/sanei.h>
#include <sane/saneopts.h>
}
typedef struct _PlatformInstance
{
Window window;
GtkWidget * widget;
GdkSuperWin * superwin;
Display * display;
uint16 x;
uint16 y;
uint32 width;
uint32 height;
} PlatformInstance;
// Threaded routine for grabbing a frame from device.
// If a callback for onScanComplete was set in the embed/object
// tag, then this routine will call it before exiting.
//void PR_CALLBACK scanimage_thread_routine( void * arg);
void PR_CALLBACK scanimage_thread_routine( void * arg );
class nsSanePluginInstance : public nsIPluginInstance,
public nsISanePluginInstance
{
friend void PR_CALLBACK scanimage_thread_routine( void *);
public:
nsSanePluginInstance(void);
virtual ~nsSanePluginInstance(void);
/////////////////////////////////////////////////////////////////////
// nsIPluginInstance inherited interface
NS_IMETHOD Initialize(nsIPluginInstancePeer* peer);
NS_IMETHOD GetPeer(nsIPluginInstancePeer* *result);
NS_IMETHOD Start(void);
NS_IMETHOD Stop(void);
NS_IMETHOD Destroy( void );
NS_IMETHOD SetWindow( nsPluginWindow* window );
NS_IMETHOD NewStream( nsIPluginStreamListener** listener );
NS_IMETHOD Print( nsPluginPrint* platformPrint );
NS_IMETHOD GetValue( nsPluginInstanceVariable variable, void *value );
// Not used for this platform! Only a placeholder.
NS_IMETHOD HandleEvent( nsPluginEvent* event, PRBool* handled );
// End of nsIPlugIninstance inherited interface.
/////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////
// nsSanePluginInstance specific methods:
NS_DECL_ISUPPORTS ;
// Execute given callback in window's JavaScript
NS_IMETHOD DoScanCompleteCallback();
NS_IMETHOD DoInitCompleteCallback();
void SetMode(nsPluginMode mode) { fMode = mode; }
void SetState(PRInt32 aState) { mState = aState; };
NS_IMETHOD PaintImage(void);
char * GetImageFilename();
GtkWidget * GetFileSelection();
PRBool IsUIThread();
nsresult OpenSaneDeviceIF( void );
//*** Methods exposed through the XPConnect interface ***
NS_DECL_NSISANEPLUGININSTANCE
private:
GtkWidget *mDrawing_area;
GtkWidget *mEvent_box;
PlatformInstance fPlatform;
char mImageFilename[255];
GtkWidget *mFileSelection;
GdkRectangle mZoom_box;
unsigned char *mRGBData;
int mRGBWidth, mRGBHeight;
// line attributes for zoom box
PRInt32 mLineWidth;
GdkLineStyle mLineStyle;
GdkCapStyle mCapStyle;
GdkJoinStyle mJoinStyle;
// zoom box change variables
float mTopLeftXChange;
float mTopLeftYChange;
float mBottomRightXChange;
float mBottomRightYChange;
// jpeg compression attributes
int mCompQuality;
enum J_DCT_METHOD mCompMethod;
// sane specific members
SANE_Handle mSaneHandle;
SANE_String mSaneDevice;
SANE_Bool mSaneOpen;
PRBool mSuccess;
PRInt32 mState;
// needed for JavaScript Callbacks
char *mOnScanCompleteScript;
char *mOnInitCompleteScript;
PRThread *mScanThread;
PRThread *mUIThread;
protected:
nsIPluginInstancePeer* fPeer;
nsPluginWindow* fWindow;
nsPluginMode fMode;
nsIPluginManager* mPluginManager;
private:
int WritePNMHeader (int fd, SANE_Frame format,
int width, int height,
int depth);
void PlatformNew( void );
nsresult PlatformDestroy( void );
PRInt16 PlatformHandleEvent( nsPluginEvent* event );
nsresult PlatformSetWindow( nsPluginWindow* window );
};
class nsSanePluginStreamListener : public nsIPluginStreamListener
{
public:
NS_DECL_ISUPPORTS ;
/*
* Notify the observer that the URL has started to load. This method is
* called only once, at the beginning of a URL load.<BR><BR>
*
* @return The return value is currently ignored. In the future it may be
* used to cancel the URL load..
*/
NS_IMETHOD OnStartBinding( nsIPluginStreamInfo* pluginInfo );
/**
* Notify the client that data is available in the input stream. This
* method is called whenver data is written into the input stream by the
* networking library...<BR><BR>
*
* @param aIStream The input stream containing the data. This stream can
* be either a blocking or non-blocking stream.
* @param length The amount of data that was just pushed into the
* stream.
* @return The return value is currently ignored.
*/
NS_IMETHOD OnDataAvailable( nsIPluginStreamInfo* pluginInfo,
nsIInputStream* input,
PRUint32 length );
NS_IMETHOD OnFileAvailable( nsIPluginStreamInfo* pluginInfo,
const char* fileName );
/**
* Notify the observer that the URL has finished loading. This method is
* called once when the networking library has finished processing the
* URL transaction initiatied via the nsINetService::Open(...) call.
* <BR><BR>
*
* This method is called regardless of whether the URL loaded
* successfully.<BR><BR>
*
* @param status Status code for the URL load.
* @param msg A text string describing the error.
* @return The return value is currently ignored.
*/
NS_IMETHOD OnStopBinding( nsIPluginStreamInfo* pluginInfo,
nsresult status );
NS_IMETHOD OnNotify( const char* url, nsresult status );
NS_IMETHOD GetStreamType( nsPluginStreamType *result );
///////////////////////////////////////////////////////////////////////////
// snPluginStreamListener specific methods:
nsSanePluginStreamListener( nsSanePluginInstance* inst );
virtual ~nsSanePluginStreamListener( void );
nsSanePluginInstance* mPlugInst;
};
#endif // __NS_SANE_PLUGIN_H__

Просмотреть файл

@ -0,0 +1,148 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
* Contributor(s):
*
* Rusty Lynch <rusty.lynch@intel.com>
*/
/*
* Defines scriptable interface to SANE plugin.
*/
#include "nsISupports.idl"
#include "domstubs.idl"
[scriptable, uuid(10982800-365e-11d3-a2bf-0004ac779ef3)]
/**
* This interface can be obtained with the following HTML/JavaScript sequence:
*
* <pre>
* <EMBED type="application/X-sane-plugin"
* id="SaneObject"
* onScanComplete="ScanCompleteCallback()"
* device="hp:/dev/usbscanner"
* line_width="5"
* line_style="dash"
* cap_style="round"
* join_style="round"
* width=320 height=240>
*
* <form name="myForm">
* <!-- Scan Selected Region -->
* <input type="button"
* value="Start Scan"
* onClick="scanner.ScanImage()">
* <!-- many more buttons for controlling scanner/camera... -->
* </form>
* <script>
* var scanner = document.SaneObject.nsISaneControl;
* dump("scanner = "+ scanner + "\n");
* </script>
* </pre>
*
* This fragment will create an embedded plugin, which can then be accessed
* and controlled by the nsISanePluginInstance interface which is instantiated
* in the script.
*/
interface nsISanePluginInstance : nsISupports
{
/////////////////////////////////////////////////////////////////////
// Plugin Status Interface
// Read-Only: Contains completion status of last operation
attribute boolean Success;
// Read-Only: Contains the current state of the scanner (IDLE|BUSY)
attribute string State;
/////////////////////////////////////////////////////////////////////
// Image Preview Interface
// Move zoom box to a given geometry in one step
void ZoomImage(in unsigned short x, in unsigned short y,
in unsigned short width, in unsigned short height);
void ZoomImageWithAttributes(in unsigned short x,
in unsigned short y,
in unsigned short width,
in unsigned short height,
in long req_line_width,
in string req_line_style,
in string req_cap_style,
in string req_join_style);
// Undo all croping and reset zoom box for entire image
void Restore ();
// Zoom in on the image and reset the zoom box to contain
// the entire image.
void Crop(in unsigned short x, in unsigned short y,
in unsigned short width, in unsigned short height);
// Read/Write zoom box geometry
// (Each write will trigger a refresh!)
attribute unsigned short ZoomX;
attribute unsigned short ZoomY;
attribute unsigned short ZoomWidth;
attribute unsigned short ZoomHeight;
// Read/Write zoom box line attributes
// (Each write will trigger a refresh!)
attribute long ZoomLineWidth;
attribute string ZoomLineStyle;
attribute string ZoomCapStyle;
attribute string ZoomJoinStyle;
// Read-Only zoom box change indicators
// (For SANE devices that support changing the scan area,
// this allows for the controling JavaScript to safely adjust
// the scan area in a device specific manner.)
attribute float ZoomBR_XChange; // % bottom right x change on last zoom
attribute float ZoomBR_YChange; // % bottom right y ...
attribute float ZoomTL_XChange; // % top left x ...
attribute float ZoomTL_YChange; // % top left y ...
// Read/Write JPEG compression attributes
attribute long Quality;
attribute string Method;
//////////////////////////////////////////////////////////////////////
// Generic SANE Interface
// READ_ONLY: returns a colon delimeted list of option descriptions
// where each option description is a comma delimited
// list of values
attribute string DeviceOptions;
// Returns or sets the active device.
attribute string ActiveDevice;
// READ_ONLY: returns a comma delimited list of image parameters
attribute string ImageParameters;
// READ_ONLY: returns a comma delimited list of available devices
attribute string AvailableDevices;
// Pull image from device with current option settings.
// As a side effect, the zoom box is set to contain the
// entire image.
void ScanImage();
void SetOption(in string name, in string value);
// Pop up a dialog to save current image to a file
void SaveImage();
};
%{ C++
//10982800-365e-11d3-a2bf-0004ac780ef3
#define NS_SANE_PLUGIN_CONTROL_CID \
{ 0x10982800, 0x365e, 0x11d3, { 0xa2, 0xbf, 0x0, 0x04, 0xac, 0x78, 0x0e, 0xf3 }}
%}

Просмотреть файл

@ -0,0 +1,320 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
* Contributor(s):
*
* Rusty Lynch <rusty.lynch@intel.com>
*/
/*
* Implements the SANE plugin factory class.
*/
#include "nsString.h"
#include "nsCOMPtr.h"
#include "nsIServiceManager.h"
#include "nsSanePlugin_CID.h"
#include "nsSanePlugin.h"
#include "nsSanePluginFactory.h"
#include "plstr.h"
#define PLUGIN_NAME "SANE Plugin"
#define PLUGIN_DESCRIPTION "SANE Plugin is a generic scanner interface"
#define PLUGIN_MIME_DESCRIPTION "application/X-sane-plugin::Scanner/Camera"
#define PLUGIN_MIME_TYPE "application/X-sane-plugin"
static NS_DEFINE_IID( kISupportsIID, NS_ISUPPORTS_IID );
static NS_DEFINE_IID( kIFactoryIID, NS_IFACTORY_IID );
static NS_DEFINE_IID( kIPluginIID, NS_IPLUGIN_IID );
static NS_DEFINE_CID( kComponentManagerCID, NS_COMPONENTMANAGER_CID );
static NS_DEFINE_CID( knsSanePluginControlCID, NS_SANE_PLUGIN_CONTROL_CID );
static NS_DEFINE_CID( knsSanePluginInst, NS_SANE_PLUGIN_CID );
////////////////////////////////////////////////////////////////////////
nsSanePluginFactoryImpl::nsSanePluginFactoryImpl( const nsCID &aClass,
const char* className,
const char* progID )
: mClassID(aClass), mClassName(className), mProgID(progID)
{
#ifdef DEBUG
printf("nsSanePluginFactoryImpl::nsSanePluginFactoryImpl()\n");
#endif
NS_INIT_REFCNT();
}
nsSanePluginFactoryImpl::~nsSanePluginFactoryImpl()
{
#ifdef DEBUG
printf("nsSanePluginFactoryImpl::~nsSanePluginFactoryImpl()\n");
#endif
printf("mRefCnt = %i\n", mRefCnt);
NS_ASSERTION(mRefCnt == 0, "non-zero refcnt at destruction");
}
NS_IMETHODIMP
nsSanePluginFactoryImpl::QueryInterface(const nsIID &aIID,
void **aInstancePtr)
{
#ifdef DEBUG
printf("nsSanePluginFactoryImpl::QueryInterface()\n");
#endif
if (!aInstancePtr)
return NS_ERROR_NULL_POINTER;
if (aIID.Equals(kISupportsIID)) {
*aInstancePtr = NS_STATIC_CAST(nsISupports*,this);
} else if (aIID.Equals(kIFactoryIID)) {
*aInstancePtr = NS_STATIC_CAST(nsISupports*,
NS_STATIC_CAST(nsIFactory*,this));
} else if (aIID.Equals(kIPluginIID)) {
*aInstancePtr = NS_STATIC_CAST(nsISupports*,
NS_STATIC_CAST(nsIPlugin*,this));
} else {
*aInstancePtr = nsnull;
return NS_ERROR_NO_INTERFACE;
}
NS_ADDREF(NS_REINTERPRET_CAST(nsISupports*,*aInstancePtr));
return NS_OK;
}
// Standard implementation of AddRef and Release
NS_IMPL_ADDREF( nsSanePluginFactoryImpl );
NS_IMPL_RELEASE( nsSanePluginFactoryImpl );
NS_IMETHODIMP
nsSanePluginFactoryImpl::CreateInstance( nsISupports *aOuter,
const nsIID &aIID,
void **aResult)
{
#ifdef DEBUG
printf("nsSanePluginFactoryImpl::CreateInstance()\n");
#endif
if ( !aResult )
return NS_ERROR_NULL_POINTER;
if ( aOuter )
return NS_ERROR_NO_AGGREGATION;
nsSanePluginInstance * inst = new nsSanePluginInstance();
if (!inst)
return NS_ERROR_OUT_OF_MEMORY;
inst->AddRef();
*aResult = inst;
return NS_OK;
}
nsresult
nsSanePluginFactoryImpl::LockFactory(PRBool aLock)
{
#ifdef DEBUG
printf("nsSanePluginFactoryImpl::LockFactory()\n");
#endif
// Needs to be implemented
return NS_OK;
}
NS_METHOD
nsSanePluginFactoryImpl::Initialize()
{
#ifdef DEBUG
printf("nsSanePluginFactoryImpl::Initialize()\n");
#endif
return NS_OK;
}
NS_METHOD
nsSanePluginFactoryImpl::Shutdown( void )
{
#ifdef DEBUG
printf("nsSanePluginFactoryImpl::Shutdown()\n");
#endif
return NS_OK;
}
NS_METHOD
nsSanePluginFactoryImpl::GetMIMEDescription(const char* *result)
{
#ifdef DEBUG
printf("nsSanePluginFactoryImpl::GetMIMEDescription()\n");
#endif
// caller is responsible for releasing
*result = PL_strdup( PLUGIN_MIME_DESCRIPTION );
return NS_OK;
}
NS_METHOD
nsSanePluginFactoryImpl::GetValue( nsPluginVariable variable, void *value )
{
#ifdef DEBUG
printf("nsSanePluginFactoryImpl::GetValue()\n");
#endif
nsresult err = NS_OK;
if ( variable == nsPluginVariable_NameString ) {
*( ( char ** )value ) = strdup( PLUGIN_NAME );
} else if ( variable == nsPluginVariable_DescriptionString ) {
*( ( char ** )value ) = strdup( PLUGIN_DESCRIPTION );
} else {
err = NS_ERROR_FAILURE;
}
return err;
}
NS_IMETHODIMP
nsSanePluginFactoryImpl::CreatePluginInstance( nsISupports *aOuter,
REFNSIID aIID,
const char* aPluginMIMEType,
void **aResult)
{
#ifdef DEBUG
printf("nsSanePluginFactoryImpl::CreatePluginInstance()\n");
#endif
// Need to find out what this is used for. The npsimple
// plugin looks like it just does a CreateInstance and
// ignores the mime type.
return NS_ERROR_NOT_IMPLEMENTED;
}
////////////////////////////////////////////////////////////////////////
/**
* The XPCOM runtime will call this to get a new factory object for the
* CID/progID it passes in. XPCOM is responsible for caching the resulting
* factory.
*
* return the proper factory to the caller
*/
extern "C" PR_IMPLEMENT(nsresult)
NSGetFactory( nsISupports* aServMgr,
const nsCID &aClass,
const char *aClassName,
const char *aProgID,
nsIFactory **aFactory)
{
if (! aFactory)
return NS_ERROR_NULL_POINTER;
nsSanePluginFactoryImpl* factory = new nsSanePluginFactoryImpl(aClass,
aClassName,
aProgID);
if ( factory == nsnull )
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(factory);
*aFactory = factory;
return NS_OK;
}
char *buf;
extern "C" PR_IMPLEMENT( nsresult )
NSRegisterSelf( nsISupports* aServMgr, const char* aPath )
{
nsresult rv;
nsCOMPtr<nsIServiceManager> servMgr( do_QueryInterface( aServMgr, &rv ) );
if ( NS_FAILED( rv ) )
return rv;
NS_WITH_SERVICE( nsIComponentManager, compMgr, kComponentManagerCID, &rv );
if ( NS_FAILED( rv ) )
return rv;
// Register the plugin control portion.
rv = compMgr->RegisterComponent(knsSanePluginControlCID,
"SANE Plugin Control",
"component://netscape/plugins/sane-control",
aPath, PR_TRUE, PR_TRUE );
// Register the plugin portion.
nsString progID;
progID.AssignWithConversion( NS_INLINE_PLUGIN_PROGID_PREFIX );
progID.AppendWithConversion(PLUGIN_MIME_TYPE);
buf = ( char * )calloc( 2000, sizeof( char ) );
progID.ToCString( buf, 1999 );
rv = compMgr->RegisterComponent( knsSanePluginInst,
"SANE Plugin Component",
buf,
aPath, PR_TRUE, PR_TRUE);
free( buf );
if ( NS_FAILED( rv ) )
return rv;
return NS_OK;
}
extern "C" PR_IMPLEMENT( nsresult )
NSUnregisterSelf(nsISupports* aServMgr, const char* aPath)
{
nsresult rv;
nsCOMPtr<nsIServiceManager> servMgr(do_QueryInterface(aServMgr, &rv));
if (NS_FAILED(rv)) return rv;
NS_WITH_SERVICE(nsIComponentManager, compMgr, kComponentManagerCID, &rv);
if (NS_FAILED(rv)) return rv;
rv = compMgr->UnregisterComponent(knsSanePluginControlCID, aPath);
if (NS_FAILED(rv)) return rv;
return NS_OK;
}

Просмотреть файл

@ -0,0 +1,60 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* Contributor(s):
* Rusty Lynch <rusty.lynch@intel.com>
*/
/*
* Declares the SANE plugin factory class.
*/
#ifndef __NS_SANE_PLUGIN_FACTORY_H__
#define __NS_SANE_PLUGIN_FACTORY_H__
class nsSanePluginFactoryImpl : public nsIPlugin
{
public:
nsSanePluginFactoryImpl(const nsCID &aClass, const char* className,
const char* progID);
// nsISupports methods
NS_DECL_ISUPPORTS ;
// nsIFactory methods
NS_IMETHOD CreateInstance(nsISupports *aOuter,
const nsIID &aIID,
void **aResult);
NS_IMETHOD LockFactory(PRBool aLock);
NS_IMETHOD Initialize(void);
NS_IMETHOD Shutdown(void);
NS_IMETHOD GetMIMEDescription(const char* *result);
NS_IMETHOD GetValue(nsPluginVariable variable, void *value);
NS_IMETHOD CreatePluginInstance(nsISupports *aOuter, REFNSIID aIID,
const char* aPluginMIMEType,
void **aResult);
protected:
virtual ~nsSanePluginFactoryImpl();
nsCID mClassID;
const char* mClassName;
const char* mProgID;
};
#endif // __NS_SANE_PLUGIN_FACTORY_H__

Просмотреть файл

@ -0,0 +1,25 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
* Contributor(s):
*
* Rusty Lynch <rusty.lynch@intel.com>
*/
/*
* Defines the CID for the SANE plugin.
*/
#ifndef __NS_SANE_PLUGIN_CID_H__
#define __NS_SANE_PLUGIN_CID_H__
#define NS_SANE_PLUGIN_CID { 0x302da841, 0x3dbf, 0x11d3, { 0xbc, 0xfb, 0x0, 0xa0, 0xc9, 0xc8, 0xd9, 0x1d } }
#endif // __NS_SANE_PLUGIN_CID_H__

Просмотреть файл

@ -0,0 +1,167 @@
<HTML>
<HEAD>
<TITLE>CPia Digital Camera Test Application</TITLE>
</HEAD>
<BODY>
<P>
This is a test page for grabing frames from a USB Cpia camera
using the v4l (Video4Linux) SANE module.
</P>
<TABLE>
<TR>
<TD>
<CENTER>
<EMBED type="application/X-sane-plugin"
name="camera"
onScanComplete="ScanCompleteCallback()"
onInitComplete="InitCompleteCallback()"
device="v4l:/dev/video"
width="400" height="400"
line_width="0" line_style="solid">
</CENTER>
</TD>
<TD>
<CENTER>
<!-- Start grabbing frames once a second -->
<INPUT type="button" onclick="start()" value="Start">
<!-- Stop grabbing frames -->
<INPUT type="button" onclick="stop()" value="Stop">
<!-- Save the current image to a file -->
<INPUT type="button" onclick="save()" value="Save"><BR>
<input type="button" onclick="doDump()" value="Dump">
<input type="button"
onclick="document.camera.nsISanePluginInstance.ScanImage()"
value="Single Shot">
</CENTER>
</TD>
</TR>
</TABLE>
<input type="text" id="status" size="20">
<!--
<textarea id="status" rows="20" cols="80"></textarea>
-->
<SCRIPT>
// globals
var gdelay = 500;
var multigrab = false;
var ingrab = false;
function sdump(str)
{
var status = document.getElementById('status');
status.value = str;
dump(str + "\n");
}
function doDump()
{
var aCamera = new Object;
try {
aCamera = document.camera.nsISanePluginInstance;
sdump("ActiveDevice = " + aCamera.ActiveDevice + "\n" +
"State = " + aCamera.State + "\n" +
"Quality = " + aCamera.Quality + "\n" +
"Method = " + aCamera.Method + "\n" +
"DeviceOptions = " + aCamera.DeviceOptions + "\n" +
"ImageParameters = " + aCamera.ImageParameters + "\n" +
"AvailableDevices = " + aCamera.AvailableDevices + "\n");
} catch (ex) {
sdump("Error trying dump data: " + ex + "\n");
}
}
function grabImage()
{
if (multigrab || ingrab)
return;
try {
document.camera.nsISanePluginInstance.ScanImage();
} catch (ex) {
sdump("Error trying to grab image!\n");
}
}
function save()
{
document.camera.nsISanePluginInstance.SaveImage();
}
function InitCompleteCallback()
{
try {
var aCamera = document.camera.nsISanePluginInstance;
aCamera.Quality = 100;
aCamera.ScanImage();
sdump("Initialization complete!\n");
} catch (ex) {
sdump("Error trying to set additional device specific parameters!" + ex);
}
}
function ScanCompleteCallback()
{
sdump("Scan Complete!\n");
ingrab = false;
if (multigrab)
window.setTimeout("document.camera.nsISanePluginInstance.ScanImage()",
gdelay);
}
function stop()
{
multigrab = false;
}
function start()
{
if (multigrab)
return;
multigrab = true;
if (!ingrab) {
try {
sdump("About to scan image!\n");
ingrab = true;
document.camera.nsISanePluginInstance.ScanImage();
} catch (ex) {
sdump("Error trying to grab frame!\n" + ex + "\n");
}
}
}
</SCRIPT>
</BODY>
</HTML>

Просмотреть файл

@ -0,0 +1,301 @@
<HTML>
<HEAD>
<TITLE>Image Scanner Application</TITLE>
</HEAD>
<BODY>
<P>
This is a simple test page for the HP 6300C USB scanner.
</P>
<TABLE>
<TR>
<TD>
<CENTER>
<EMBED type="application/X-sane-plugin"
name="scanner"
onScanComplete="ScanCompleteCallback()"
onInitComplete="InitCompleteCallback()"
device="hp:/dev/usbscanner"
width="300" height="413"
line_width="4" line_style="solid">
</CENTER>
</TD>
<TD>
<CENTER>
<!-- Pan zoom box -->
<INPUT type="button" onclick="panRegionVert(-10)"
value="Pan Up" ><BR>
<INPUT type="button" onclick="panRegionHor(-10)"
value="Pan Left" >
<INPUT type="button" onclick="panRegionHor(10)"
value="Pan Right" ><BR>
<INPUT type="button" onclick="panRegionVert(10)"
value="Pan Down" ><BR><BR>
<!-- Zoom in/out -->
<INPUT type="button" onclick="adjustRegion(-10)"
value="Zoom In" >
<INPUT type="button" onclick="adjustRegion(10)"
value="Zoom Out" ><BR><BR>
<!-- Scanner controls -->
<INPUT type="button" onclick="ScanHi()"
value="Scan Selected Region">
<INPUT type="button" onclick="GetPreview()"
value="Preview"><BR>
<INPUT type="button" onclick="Save()"
value="Save Current Image"><br><br>
<!-- SANE test -->
<INPUT type="button" onclick="doDump()"
value="Dump">
</CENTER>
</TD>
</TR>
</TABLE>
<TEXTAREA id="status" rows="20" cols="80"></TEXTAREA>
<SCRIPT>
// globals
var inscan = true;
var br_x = 0, br_y = 0, tl_x = 0, tl_y = 0;
var max_br_x = 0, max_br_y = 0;
var last_br_x, last_br_y, last_tl_x, last_tl_y;
function sdump(str)
{
var status = document.getElementById('status');
status.value = str;
dump(str + "\n");
}
function doDump()
{
try {
var aScanner = document.scanner.nsISanePluginInstance;
sdump("ActiveDevice = " + aScanner.ActiveDevice + "\n" +
"State = " + aScanner.State + "\n" +
"Quality = " + aScanner.Quality + "\n" +
"Method = " + aScanner.Method + "\n" +
"DeviceOptions = " + aScanner.DeviceOptions + "\n" +
"ImageParameters = " + aScanner.ImageParameters + "\n" +
"AvailableDevices = " + aScanner.AvailableDevices + "\n");
} catch (ex) {
sdump("Error trying to dump: \n" + ex + "\n");
}
}
function adjustRegion(factor) {
try {
var aScanner = document.scanner.nsISanePluginInstance;
var x, y, height, width;
x = aScanner.ZoomX;
y = aScanner.ZoomY;
width = aScanner.ZoomWidth
+ factor;
height = Math.floor(width * 413/300);
aScanner.Crop(x, y, width, height);
} catch (ex) {
dump("Unable to zoom by " + factor + "\n" + ex + "\n");
}
}
function panRegionHor(factor) {
try {
var x, y, height, width;
var aScanner = document.scanner.nsISanePluginInstance;
if (aScanner.ZoomX + factor < 0)
x = aScanner.ZoomX;
else
x = aScanner.ZoomX + factor;
y = aScanner.ZoomY;
width = aScanner.ZoomWidth;
height = aScanner.ZoomHeight;
aScanner.Crop(x, y, width, height);
} catch (ex) {
dump("Unable to pan to requested location!\n");
}
}
function panRegionVert(factor) {
try {
var x, y, height, width;
var aScanner = document.scanner.nsISanePluginInstance;
if (aScanner.ZoomY + factor < 0)
y = aScanner.ZoomY;
else
y = aScanner.ZoomY + factor;
x = aScanner.ZoomX;
width = aScanner.ZoomWidth;
height = aScanner.ZoomHeight;
aScanner.Crop(x, y, width, height);
} catch (ex) {
dump("Unable to pan to requested location!\n");
}
}
function Save() {
try {
var aScanner = document.scanner.nsISanePluginInstance;
aScanner.SaveImage();
} catch (ex) {
dump("Error trying to save current image!\n");
}
}
function GetPreview()
{
if (inscan)
return;
try {
var aScanner = document.scanner.nsISanePluginInstance;
// Reset scan area for entire bed
tl_x = tl_y = 0;
br_x = max_br_x;
br_y = max_br_y;
aScanner.SetOption("tl-x", tl_x.toString(10));
aScanner.SetOption("tl-y", tl_y.toString(10));
aScanner.SetOption("br-x", br_x.toString(10));
aScanner.SetOption("br-y", br_y.toString(10));
// Set the lowest resolution the HP ScanJet 6300C supports
aScanner.SetOption("mode", "Color");
aScanner.SetOption("resolution", "12");
inscan = true;
aScanner.ScanImage();
// Scanning is a threaded function, so getting here
// only means that a scan operation was successfully started.
} catch (ex) {
dump("Error trying to get preview image!");
}
}
function ScanHi()
{
if (inscan)
return;
try {
var aScanner = document.scanner.nsISanePluginInstance;
// store last scan area coordinates
// so that Restore() knows what scan
// area coordinates to restore to.
last_br_x = br_x;
last_br_y = br_y;
last_tl_x = tl_x;
last_tl_y = tl_y;
// factors used in converting from zoom box
// to scanner coordinates
var xfactor = last_br_x/300;
var yfactor = last_br_y/413;
// zoom box coordinates
var z_br_x = aScanner.ZoomWidth + aScanner.ZoomX;
var z_br_y = aScanner.ZoomHeight + aScanner.ZoomY;
var z_tl_x = aScanner.ZoomX;
var z_tl_y = aScanner.ZoomY;
br_x = Math.floor(z_br_x * xfactor);
br_y = Math.floor(z_br_y * yfactor);
tl_x = Math.floor((z_tl_x * xfactor) + last_tl_x);
tl_y = Math.floor((z_tl_y * yfactor) + last_tl_y);
last_br_x = br_x;
last_br_y = br_y;
last_tl_x = tl_x;
last_tl_y = tl_y;
// set the scan area for zoom box
aScanner.SetOption("tl-x", tl_x);
aScanner.SetOption("tl-y", tl_y);
aScanner.SetOption("br-x", br_x);
aScanner.SetOption("br-y", br_y);
// For speed of testing, high resolution is set to
// just 150dpi
aScanner.SetOption("resolution", "150");
inscan = true;
aScanner.ScanImage();
// Scanning is a threaded operation so getting here
// only means that we have successfully started a scan.
} catch (ex) {
dump("Error trying to scan at 150!\n"+ ex + "\n");
}
}
function ScanCompleteCallback()
{
inscan = false;
dump("Completed Scan!\n");
}
function InitCompleteCallback()
{
// Additional device specific initialization
try {
var aScanner = document.scanner.nsISanePluginInstance;
// Reset scan area for entire bed
tl_x = tl_y = 0;
br_x = max_br_x;
br_y = max_br_y;
aScanner.SetOption("tl-x", tl_x.toString(10));
aScanner.SetOption("tl-y", tl_y.toString(10));
aScanner.SetOption("br-x", br_x.toString(10));
aScanner.SetOption("br-y", br_y.toString(10));
// this particular scan seems to scan in a
// a little dark by default
aScanner.SetOption("brightness", "30");
aScanner.SetOption("contrast", "10");
aScanner.Quality = 80;
aScanner.Method = "FAST";
aScanner.SetOption("mode", "Color");
// Set the maximum bottom x and bottom y
// for the HP ScanJet 6300C
last_br_x = br_x = max_br_x = 14141852;
last_br_y = br_y = max_br_y = 19456836;
last_tl_x = tl_x;
last_tl_y = tl_y;
inscan = false;
} catch (ex) {
dump("Error trying to set device specific initialization!\n");
}
}
</SCRIPT>
</BODY>
</HTML>

Просмотреть файл

@ -0,0 +1,57 @@
############################################################################
## Makefile.in (Generic SANE Plugin Tree)
##
## The contents of this file are subject to the Mozilla Public
## License Version 1.1 (the "License"); you may not use this file
## except in compliance with the License. You may obtain a copy of
## the License at http://www.mozilla.org/MPL/
##
## Software distributed under the License is distributed on an "AS
## IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
## implied. See the License for the specific language governing
## rights and limitations under the License.
## Contributor(s):
##
## Rusty Lynch <rusty.lynch@intel.com>
############################################################################
DEPTH = ../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
MODULE = SanePlugin
LIBRARY_NAME = Sane
IS_COMPONENT = 1
REQUIRES = raptor xpcom
CPPSRCS = \
nsSanePluginFactory.cpp \
nsSanePlugin.cpp \
$(NULL)
LOCAL_INCLUDES = -I$(srcdir)/.. -I$(srcdir)/../../public \
-I/usr/lib/glib/include
EXTRA_DSO_LDOPTS += -L$(DIST)/lib -lgtksuperwin \
$(TK_LIBS) -lsane -ljpeg
XPIDLSRCS = nsSanePluginControl.idl
include $(topsrcdir)/config/rules.mk
install:: $(TARGETS)
$(INSTALL) $(srcdir)/test/camera.html $(DIST)/bin/res/samples
$(INSTALL) $(srcdir)/test/scanner.html $(DIST)/bin/res/samples
$(INSTALL) $(srcdir)/test/camera.html /home/httpd/html/test
$(INSTALL) $(srcdir)/test/scanner.html /home/httpd/html/test
superclean: clean
rm -f *~ test/*~

Просмотреть файл

@ -0,0 +1,45 @@
What is this plug-in?
---------------------
This is a Linux/Mozilla plug-in that enables a scanner/digital
camera application to be created with JavaScript. To this end
the SANE plug-in provides two things:
1. I have attempted to export all of the SANE API's
from the SANE native libraries to JavaScript.
(I have provided two brain-dead samples for a
CPia USB digital camera and HP 6300 scanner.)
2. A drawing surface for displaying the scanned image.
=====================================================================
Why did you bother?
------------------
Originally, I used this plug-in to cut my teeth on the new Mozilla
XPCom plug-in model. Now I am hoping to provide a Linux/Mozilla
plug-in sample that exercises most of the functionality that the
Linux community would want to use (like connecting JavaScript
to native code.)
=====================================================================
You know, Linux isn't the only UN*X around!
-------------------------------------------
I say Linux because that is the only platform I have built/tested on.
SANE is supported by a long list of UN*X OS's so there is no reason
that other platforms shouldn't work with this plug-in.
(I have tried to stick to NSPR functions for this reason, but it's easy
to over look a couple of Linux specific functions.)
======================================================================
How do I build this beast?
-------------------------
In order to build this plug-in, you need the SANE (Scanner Access
Now Easy) libraries/headers installed on your system. For more
info on SANE, go to http://www.mostang.com/sane.

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -0,0 +1,238 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
* Contributor(s):
*
* Rusty Lynch <rusty.lynch@intel.com>
*/
/*
* Declares the nsSanePluginInterface class for the SANE plugin.
*/
#ifndef __NS_SANE_PLUGIN_H__
#define __NS_SANE_PLUGIN_H__
#include "prthread.h"
#include "nscore.h"
#include "nsplugin.h"
#include "gdksuperwin.h"
#include "gtkmozbox.h"
#include "gtk/gtk.h"
#include "nsIPlugin.h"
#include "nsSanePluginControl.h"
#include "nsIScriptContext.h"
#include "nsIServiceManager.h"
#include "nsISupports.h"
#include "nsISupportsUtils.h"
#include "nsIEventQueueService.h"
#include "nsIEventQueue.h"
///////////////////////////////////
// Needed for encoding jpeg images
extern "C"
{
#include <jpeglib.h>
}
///////////////////////////////////
// Needed for SANE interface
extern "C"
{
#include <sane/sane.h>
#include <sane/sanei.h>
#include <sane/saneopts.h>
}
typedef struct _PlatformInstance
{
Window window;
GtkWidget * widget;
GdkSuperWin * superwin;
Display * display;
uint16 x;
uint16 y;
uint32 width;
uint32 height;
} PlatformInstance;
// Threaded routine for grabbing a frame from device.
// If a callback for onScanComplete was set in the embed/object
// tag, then this routine will call it before exiting.
//void PR_CALLBACK scanimage_thread_routine( void * arg);
void PR_CALLBACK scanimage_thread_routine( void * arg );
class nsSanePluginInstance : public nsIPluginInstance,
public nsISanePluginInstance
{
friend void PR_CALLBACK scanimage_thread_routine( void *);
public:
nsSanePluginInstance(void);
virtual ~nsSanePluginInstance(void);
/////////////////////////////////////////////////////////////////////
// nsIPluginInstance inherited interface
NS_IMETHOD Initialize(nsIPluginInstancePeer* peer);
NS_IMETHOD GetPeer(nsIPluginInstancePeer* *result);
NS_IMETHOD Start(void);
NS_IMETHOD Stop(void);
NS_IMETHOD Destroy( void );
NS_IMETHOD SetWindow( nsPluginWindow* window );
NS_IMETHOD NewStream( nsIPluginStreamListener** listener );
NS_IMETHOD Print( nsPluginPrint* platformPrint );
NS_IMETHOD GetValue( nsPluginInstanceVariable variable, void *value );
// Not used for this platform! Only a placeholder.
NS_IMETHOD HandleEvent( nsPluginEvent* event, PRBool* handled );
// End of nsIPlugIninstance inherited interface.
/////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////
// nsSanePluginInstance specific methods:
NS_DECL_ISUPPORTS ;
// Execute given callback in window's JavaScript
NS_IMETHOD DoScanCompleteCallback();
NS_IMETHOD DoInitCompleteCallback();
void SetMode(nsPluginMode mode) { fMode = mode; }
void SetState(PRInt32 aState) { mState = aState; };
NS_IMETHOD PaintImage(void);
char * GetImageFilename();
GtkWidget * GetFileSelection();
PRBool IsUIThread();
nsresult OpenSaneDeviceIF( void );
//*** Methods exposed through the XPConnect interface ***
NS_DECL_NSISANEPLUGININSTANCE
private:
GtkWidget *mDrawing_area;
GtkWidget *mEvent_box;
PlatformInstance fPlatform;
char mImageFilename[255];
GtkWidget *mFileSelection;
GdkRectangle mZoom_box;
unsigned char *mRGBData;
int mRGBWidth, mRGBHeight;
// line attributes for zoom box
PRInt32 mLineWidth;
GdkLineStyle mLineStyle;
GdkCapStyle mCapStyle;
GdkJoinStyle mJoinStyle;
// zoom box change variables
float mTopLeftXChange;
float mTopLeftYChange;
float mBottomRightXChange;
float mBottomRightYChange;
// jpeg compression attributes
int mCompQuality;
enum J_DCT_METHOD mCompMethod;
// sane specific members
SANE_Handle mSaneHandle;
SANE_String mSaneDevice;
SANE_Bool mSaneOpen;
PRBool mSuccess;
PRInt32 mState;
// needed for JavaScript Callbacks
char *mOnScanCompleteScript;
char *mOnInitCompleteScript;
PRThread *mScanThread;
PRThread *mUIThread;
protected:
nsIPluginInstancePeer* fPeer;
nsPluginWindow* fWindow;
nsPluginMode fMode;
nsIPluginManager* mPluginManager;
private:
int WritePNMHeader (int fd, SANE_Frame format,
int width, int height,
int depth);
void PlatformNew( void );
nsresult PlatformDestroy( void );
PRInt16 PlatformHandleEvent( nsPluginEvent* event );
nsresult PlatformSetWindow( nsPluginWindow* window );
};
class nsSanePluginStreamListener : public nsIPluginStreamListener
{
public:
NS_DECL_ISUPPORTS ;
/*
* Notify the observer that the URL has started to load. This method is
* called only once, at the beginning of a URL load.<BR><BR>
*
* @return The return value is currently ignored. In the future it may be
* used to cancel the URL load..
*/
NS_IMETHOD OnStartBinding( nsIPluginStreamInfo* pluginInfo );
/**
* Notify the client that data is available in the input stream. This
* method is called whenver data is written into the input stream by the
* networking library...<BR><BR>
*
* @param aIStream The input stream containing the data. This stream can
* be either a blocking or non-blocking stream.
* @param length The amount of data that was just pushed into the
* stream.
* @return The return value is currently ignored.
*/
NS_IMETHOD OnDataAvailable( nsIPluginStreamInfo* pluginInfo,
nsIInputStream* input,
PRUint32 length );
NS_IMETHOD OnFileAvailable( nsIPluginStreamInfo* pluginInfo,
const char* fileName );
/**
* Notify the observer that the URL has finished loading. This method is
* called once when the networking library has finished processing the
* URL transaction initiatied via the nsINetService::Open(...) call.
* <BR><BR>
*
* This method is called regardless of whether the URL loaded
* successfully.<BR><BR>
*
* @param status Status code for the URL load.
* @param msg A text string describing the error.
* @return The return value is currently ignored.
*/
NS_IMETHOD OnStopBinding( nsIPluginStreamInfo* pluginInfo,
nsresult status );
NS_IMETHOD OnNotify( const char* url, nsresult status );
NS_IMETHOD GetStreamType( nsPluginStreamType *result );
///////////////////////////////////////////////////////////////////////////
// snPluginStreamListener specific methods:
nsSanePluginStreamListener( nsSanePluginInstance* inst );
virtual ~nsSanePluginStreamListener( void );
nsSanePluginInstance* mPlugInst;
};
#endif // __NS_SANE_PLUGIN_H__

Просмотреть файл

@ -0,0 +1,148 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
* Contributor(s):
*
* Rusty Lynch <rusty.lynch@intel.com>
*/
/*
* Defines scriptable interface to SANE plugin.
*/
#include "nsISupports.idl"
#include "domstubs.idl"
[scriptable, uuid(10982800-365e-11d3-a2bf-0004ac779ef3)]
/**
* This interface can be obtained with the following HTML/JavaScript sequence:
*
* <pre>
* <EMBED type="application/X-sane-plugin"
* id="SaneObject"
* onScanComplete="ScanCompleteCallback()"
* device="hp:/dev/usbscanner"
* line_width="5"
* line_style="dash"
* cap_style="round"
* join_style="round"
* width=320 height=240>
*
* <form name="myForm">
* <!-- Scan Selected Region -->
* <input type="button"
* value="Start Scan"
* onClick="scanner.ScanImage()">
* <!-- many more buttons for controlling scanner/camera... -->
* </form>
* <script>
* var scanner = document.SaneObject.nsISaneControl;
* dump("scanner = "+ scanner + "\n");
* </script>
* </pre>
*
* This fragment will create an embedded plugin, which can then be accessed
* and controlled by the nsISanePluginInstance interface which is instantiated
* in the script.
*/
interface nsISanePluginInstance : nsISupports
{
/////////////////////////////////////////////////////////////////////
// Plugin Status Interface
// Read-Only: Contains completion status of last operation
attribute boolean Success;
// Read-Only: Contains the current state of the scanner (IDLE|BUSY)
attribute string State;
/////////////////////////////////////////////////////////////////////
// Image Preview Interface
// Move zoom box to a given geometry in one step
void ZoomImage(in unsigned short x, in unsigned short y,
in unsigned short width, in unsigned short height);
void ZoomImageWithAttributes(in unsigned short x,
in unsigned short y,
in unsigned short width,
in unsigned short height,
in long req_line_width,
in string req_line_style,
in string req_cap_style,
in string req_join_style);
// Undo all croping and reset zoom box for entire image
void Restore ();
// Zoom in on the image and reset the zoom box to contain
// the entire image.
void Crop(in unsigned short x, in unsigned short y,
in unsigned short width, in unsigned short height);
// Read/Write zoom box geometry
// (Each write will trigger a refresh!)
attribute unsigned short ZoomX;
attribute unsigned short ZoomY;
attribute unsigned short ZoomWidth;
attribute unsigned short ZoomHeight;
// Read/Write zoom box line attributes
// (Each write will trigger a refresh!)
attribute long ZoomLineWidth;
attribute string ZoomLineStyle;
attribute string ZoomCapStyle;
attribute string ZoomJoinStyle;
// Read-Only zoom box change indicators
// (For SANE devices that support changing the scan area,
// this allows for the controling JavaScript to safely adjust
// the scan area in a device specific manner.)
attribute float ZoomBR_XChange; // % bottom right x change on last zoom
attribute float ZoomBR_YChange; // % bottom right y ...
attribute float ZoomTL_XChange; // % top left x ...
attribute float ZoomTL_YChange; // % top left y ...
// Read/Write JPEG compression attributes
attribute long Quality;
attribute string Method;
//////////////////////////////////////////////////////////////////////
// Generic SANE Interface
// READ_ONLY: returns a colon delimeted list of option descriptions
// where each option description is a comma delimited
// list of values
attribute string DeviceOptions;
// Returns or sets the active device.
attribute string ActiveDevice;
// READ_ONLY: returns a comma delimited list of image parameters
attribute string ImageParameters;
// READ_ONLY: returns a comma delimited list of available devices
attribute string AvailableDevices;
// Pull image from device with current option settings.
// As a side effect, the zoom box is set to contain the
// entire image.
void ScanImage();
void SetOption(in string name, in string value);
// Pop up a dialog to save current image to a file
void SaveImage();
};
%{ C++
//10982800-365e-11d3-a2bf-0004ac780ef3
#define NS_SANE_PLUGIN_CONTROL_CID \
{ 0x10982800, 0x365e, 0x11d3, { 0xa2, 0xbf, 0x0, 0x04, 0xac, 0x78, 0x0e, 0xf3 }}
%}

Просмотреть файл

@ -0,0 +1,320 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
* Contributor(s):
*
* Rusty Lynch <rusty.lynch@intel.com>
*/
/*
* Implements the SANE plugin factory class.
*/
#include "nsString.h"
#include "nsCOMPtr.h"
#include "nsIServiceManager.h"
#include "nsSanePlugin_CID.h"
#include "nsSanePlugin.h"
#include "nsSanePluginFactory.h"
#include "plstr.h"
#define PLUGIN_NAME "SANE Plugin"
#define PLUGIN_DESCRIPTION "SANE Plugin is a generic scanner interface"
#define PLUGIN_MIME_DESCRIPTION "application/X-sane-plugin::Scanner/Camera"
#define PLUGIN_MIME_TYPE "application/X-sane-plugin"
static NS_DEFINE_IID( kISupportsIID, NS_ISUPPORTS_IID );
static NS_DEFINE_IID( kIFactoryIID, NS_IFACTORY_IID );
static NS_DEFINE_IID( kIPluginIID, NS_IPLUGIN_IID );
static NS_DEFINE_CID( kComponentManagerCID, NS_COMPONENTMANAGER_CID );
static NS_DEFINE_CID( knsSanePluginControlCID, NS_SANE_PLUGIN_CONTROL_CID );
static NS_DEFINE_CID( knsSanePluginInst, NS_SANE_PLUGIN_CID );
////////////////////////////////////////////////////////////////////////
nsSanePluginFactoryImpl::nsSanePluginFactoryImpl( const nsCID &aClass,
const char* className,
const char* progID )
: mClassID(aClass), mClassName(className), mProgID(progID)
{
#ifdef DEBUG
printf("nsSanePluginFactoryImpl::nsSanePluginFactoryImpl()\n");
#endif
NS_INIT_REFCNT();
}
nsSanePluginFactoryImpl::~nsSanePluginFactoryImpl()
{
#ifdef DEBUG
printf("nsSanePluginFactoryImpl::~nsSanePluginFactoryImpl()\n");
#endif
printf("mRefCnt = %i\n", mRefCnt);
NS_ASSERTION(mRefCnt == 0, "non-zero refcnt at destruction");
}
NS_IMETHODIMP
nsSanePluginFactoryImpl::QueryInterface(const nsIID &aIID,
void **aInstancePtr)
{
#ifdef DEBUG
printf("nsSanePluginFactoryImpl::QueryInterface()\n");
#endif
if (!aInstancePtr)
return NS_ERROR_NULL_POINTER;
if (aIID.Equals(kISupportsIID)) {
*aInstancePtr = NS_STATIC_CAST(nsISupports*,this);
} else if (aIID.Equals(kIFactoryIID)) {
*aInstancePtr = NS_STATIC_CAST(nsISupports*,
NS_STATIC_CAST(nsIFactory*,this));
} else if (aIID.Equals(kIPluginIID)) {
*aInstancePtr = NS_STATIC_CAST(nsISupports*,
NS_STATIC_CAST(nsIPlugin*,this));
} else {
*aInstancePtr = nsnull;
return NS_ERROR_NO_INTERFACE;
}
NS_ADDREF(NS_REINTERPRET_CAST(nsISupports*,*aInstancePtr));
return NS_OK;
}
// Standard implementation of AddRef and Release
NS_IMPL_ADDREF( nsSanePluginFactoryImpl );
NS_IMPL_RELEASE( nsSanePluginFactoryImpl );
NS_IMETHODIMP
nsSanePluginFactoryImpl::CreateInstance( nsISupports *aOuter,
const nsIID &aIID,
void **aResult)
{
#ifdef DEBUG
printf("nsSanePluginFactoryImpl::CreateInstance()\n");
#endif
if ( !aResult )
return NS_ERROR_NULL_POINTER;
if ( aOuter )
return NS_ERROR_NO_AGGREGATION;
nsSanePluginInstance * inst = new nsSanePluginInstance();
if (!inst)
return NS_ERROR_OUT_OF_MEMORY;
inst->AddRef();
*aResult = inst;
return NS_OK;
}
nsresult
nsSanePluginFactoryImpl::LockFactory(PRBool aLock)
{
#ifdef DEBUG
printf("nsSanePluginFactoryImpl::LockFactory()\n");
#endif
// Needs to be implemented
return NS_OK;
}
NS_METHOD
nsSanePluginFactoryImpl::Initialize()
{
#ifdef DEBUG
printf("nsSanePluginFactoryImpl::Initialize()\n");
#endif
return NS_OK;
}
NS_METHOD
nsSanePluginFactoryImpl::Shutdown( void )
{
#ifdef DEBUG
printf("nsSanePluginFactoryImpl::Shutdown()\n");
#endif
return NS_OK;
}
NS_METHOD
nsSanePluginFactoryImpl::GetMIMEDescription(const char* *result)
{
#ifdef DEBUG
printf("nsSanePluginFactoryImpl::GetMIMEDescription()\n");
#endif
// caller is responsible for releasing
*result = PL_strdup( PLUGIN_MIME_DESCRIPTION );
return NS_OK;
}
NS_METHOD
nsSanePluginFactoryImpl::GetValue( nsPluginVariable variable, void *value )
{
#ifdef DEBUG
printf("nsSanePluginFactoryImpl::GetValue()\n");
#endif
nsresult err = NS_OK;
if ( variable == nsPluginVariable_NameString ) {
*( ( char ** )value ) = strdup( PLUGIN_NAME );
} else if ( variable == nsPluginVariable_DescriptionString ) {
*( ( char ** )value ) = strdup( PLUGIN_DESCRIPTION );
} else {
err = NS_ERROR_FAILURE;
}
return err;
}
NS_IMETHODIMP
nsSanePluginFactoryImpl::CreatePluginInstance( nsISupports *aOuter,
REFNSIID aIID,
const char* aPluginMIMEType,
void **aResult)
{
#ifdef DEBUG
printf("nsSanePluginFactoryImpl::CreatePluginInstance()\n");
#endif
// Need to find out what this is used for. The npsimple
// plugin looks like it just does a CreateInstance and
// ignores the mime type.
return NS_ERROR_NOT_IMPLEMENTED;
}
////////////////////////////////////////////////////////////////////////
/**
* The XPCOM runtime will call this to get a new factory object for the
* CID/progID it passes in. XPCOM is responsible for caching the resulting
* factory.
*
* return the proper factory to the caller
*/
extern "C" PR_IMPLEMENT(nsresult)
NSGetFactory( nsISupports* aServMgr,
const nsCID &aClass,
const char *aClassName,
const char *aProgID,
nsIFactory **aFactory)
{
if (! aFactory)
return NS_ERROR_NULL_POINTER;
nsSanePluginFactoryImpl* factory = new nsSanePluginFactoryImpl(aClass,
aClassName,
aProgID);
if ( factory == nsnull )
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(factory);
*aFactory = factory;
return NS_OK;
}
char *buf;
extern "C" PR_IMPLEMENT( nsresult )
NSRegisterSelf( nsISupports* aServMgr, const char* aPath )
{
nsresult rv;
nsCOMPtr<nsIServiceManager> servMgr( do_QueryInterface( aServMgr, &rv ) );
if ( NS_FAILED( rv ) )
return rv;
NS_WITH_SERVICE( nsIComponentManager, compMgr, kComponentManagerCID, &rv );
if ( NS_FAILED( rv ) )
return rv;
// Register the plugin control portion.
rv = compMgr->RegisterComponent(knsSanePluginControlCID,
"SANE Plugin Control",
"component://netscape/plugins/sane-control",
aPath, PR_TRUE, PR_TRUE );
// Register the plugin portion.
nsString progID;
progID.AssignWithConversion( NS_INLINE_PLUGIN_PROGID_PREFIX );
progID.AppendWithConversion(PLUGIN_MIME_TYPE);
buf = ( char * )calloc( 2000, sizeof( char ) );
progID.ToCString( buf, 1999 );
rv = compMgr->RegisterComponent( knsSanePluginInst,
"SANE Plugin Component",
buf,
aPath, PR_TRUE, PR_TRUE);
free( buf );
if ( NS_FAILED( rv ) )
return rv;
return NS_OK;
}
extern "C" PR_IMPLEMENT( nsresult )
NSUnregisterSelf(nsISupports* aServMgr, const char* aPath)
{
nsresult rv;
nsCOMPtr<nsIServiceManager> servMgr(do_QueryInterface(aServMgr, &rv));
if (NS_FAILED(rv)) return rv;
NS_WITH_SERVICE(nsIComponentManager, compMgr, kComponentManagerCID, &rv);
if (NS_FAILED(rv)) return rv;
rv = compMgr->UnregisterComponent(knsSanePluginControlCID, aPath);
if (NS_FAILED(rv)) return rv;
return NS_OK;
}

Просмотреть файл

@ -0,0 +1,60 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* Contributor(s):
* Rusty Lynch <rusty.lynch@intel.com>
*/
/*
* Declares the SANE plugin factory class.
*/
#ifndef __NS_SANE_PLUGIN_FACTORY_H__
#define __NS_SANE_PLUGIN_FACTORY_H__
class nsSanePluginFactoryImpl : public nsIPlugin
{
public:
nsSanePluginFactoryImpl(const nsCID &aClass, const char* className,
const char* progID);
// nsISupports methods
NS_DECL_ISUPPORTS ;
// nsIFactory methods
NS_IMETHOD CreateInstance(nsISupports *aOuter,
const nsIID &aIID,
void **aResult);
NS_IMETHOD LockFactory(PRBool aLock);
NS_IMETHOD Initialize(void);
NS_IMETHOD Shutdown(void);
NS_IMETHOD GetMIMEDescription(const char* *result);
NS_IMETHOD GetValue(nsPluginVariable variable, void *value);
NS_IMETHOD CreatePluginInstance(nsISupports *aOuter, REFNSIID aIID,
const char* aPluginMIMEType,
void **aResult);
protected:
virtual ~nsSanePluginFactoryImpl();
nsCID mClassID;
const char* mClassName;
const char* mProgID;
};
#endif // __NS_SANE_PLUGIN_FACTORY_H__

Просмотреть файл

@ -0,0 +1,25 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
* Contributor(s):
*
* Rusty Lynch <rusty.lynch@intel.com>
*/
/*
* Defines the CID for the SANE plugin.
*/
#ifndef __NS_SANE_PLUGIN_CID_H__
#define __NS_SANE_PLUGIN_CID_H__
#define NS_SANE_PLUGIN_CID { 0x302da841, 0x3dbf, 0x11d3, { 0xbc, 0xfb, 0x0, 0xa0, 0xc9, 0xc8, 0xd9, 0x1d } }
#endif // __NS_SANE_PLUGIN_CID_H__

Просмотреть файл

@ -0,0 +1,167 @@
<HTML>
<HEAD>
<TITLE>CPia Digital Camera Test Application</TITLE>
</HEAD>
<BODY>
<P>
This is a test page for grabing frames from a USB Cpia camera
using the v4l (Video4Linux) SANE module.
</P>
<TABLE>
<TR>
<TD>
<CENTER>
<EMBED type="application/X-sane-plugin"
name="camera"
onScanComplete="ScanCompleteCallback()"
onInitComplete="InitCompleteCallback()"
device="v4l:/dev/video"
width="400" height="400"
line_width="0" line_style="solid">
</CENTER>
</TD>
<TD>
<CENTER>
<!-- Start grabbing frames once a second -->
<INPUT type="button" onclick="start()" value="Start">
<!-- Stop grabbing frames -->
<INPUT type="button" onclick="stop()" value="Stop">
<!-- Save the current image to a file -->
<INPUT type="button" onclick="save()" value="Save"><BR>
<input type="button" onclick="doDump()" value="Dump">
<input type="button"
onclick="document.camera.nsISanePluginInstance.ScanImage()"
value="Single Shot">
</CENTER>
</TD>
</TR>
</TABLE>
<input type="text" id="status" size="20">
<!--
<textarea id="status" rows="20" cols="80"></textarea>
-->
<SCRIPT>
// globals
var gdelay = 500;
var multigrab = false;
var ingrab = false;
function sdump(str)
{
var status = document.getElementById('status');
status.value = str;
dump(str + "\n");
}
function doDump()
{
var aCamera = new Object;
try {
aCamera = document.camera.nsISanePluginInstance;
sdump("ActiveDevice = " + aCamera.ActiveDevice + "\n" +
"State = " + aCamera.State + "\n" +
"Quality = " + aCamera.Quality + "\n" +
"Method = " + aCamera.Method + "\n" +
"DeviceOptions = " + aCamera.DeviceOptions + "\n" +
"ImageParameters = " + aCamera.ImageParameters + "\n" +
"AvailableDevices = " + aCamera.AvailableDevices + "\n");
} catch (ex) {
sdump("Error trying dump data: " + ex + "\n");
}
}
function grabImage()
{
if (multigrab || ingrab)
return;
try {
document.camera.nsISanePluginInstance.ScanImage();
} catch (ex) {
sdump("Error trying to grab image!\n");
}
}
function save()
{
document.camera.nsISanePluginInstance.SaveImage();
}
function InitCompleteCallback()
{
try {
var aCamera = document.camera.nsISanePluginInstance;
aCamera.Quality = 100;
aCamera.ScanImage();
sdump("Initialization complete!\n");
} catch (ex) {
sdump("Error trying to set additional device specific parameters!" + ex);
}
}
function ScanCompleteCallback()
{
sdump("Scan Complete!\n");
ingrab = false;
if (multigrab)
window.setTimeout("document.camera.nsISanePluginInstance.ScanImage()",
gdelay);
}
function stop()
{
multigrab = false;
}
function start()
{
if (multigrab)
return;
multigrab = true;
if (!ingrab) {
try {
sdump("About to scan image!\n");
ingrab = true;
document.camera.nsISanePluginInstance.ScanImage();
} catch (ex) {
sdump("Error trying to grab frame!\n" + ex + "\n");
}
}
}
</SCRIPT>
</BODY>
</HTML>

Просмотреть файл

@ -0,0 +1,301 @@
<HTML>
<HEAD>
<TITLE>Image Scanner Application</TITLE>
</HEAD>
<BODY>
<P>
This is a simple test page for the HP 6300C USB scanner.
</P>
<TABLE>
<TR>
<TD>
<CENTER>
<EMBED type="application/X-sane-plugin"
name="scanner"
onScanComplete="ScanCompleteCallback()"
onInitComplete="InitCompleteCallback()"
device="hp:/dev/usbscanner"
width="300" height="413"
line_width="4" line_style="solid">
</CENTER>
</TD>
<TD>
<CENTER>
<!-- Pan zoom box -->
<INPUT type="button" onclick="panRegionVert(-10)"
value="Pan Up" ><BR>
<INPUT type="button" onclick="panRegionHor(-10)"
value="Pan Left" >
<INPUT type="button" onclick="panRegionHor(10)"
value="Pan Right" ><BR>
<INPUT type="button" onclick="panRegionVert(10)"
value="Pan Down" ><BR><BR>
<!-- Zoom in/out -->
<INPUT type="button" onclick="adjustRegion(-10)"
value="Zoom In" >
<INPUT type="button" onclick="adjustRegion(10)"
value="Zoom Out" ><BR><BR>
<!-- Scanner controls -->
<INPUT type="button" onclick="ScanHi()"
value="Scan Selected Region">
<INPUT type="button" onclick="GetPreview()"
value="Preview"><BR>
<INPUT type="button" onclick="Save()"
value="Save Current Image"><br><br>
<!-- SANE test -->
<INPUT type="button" onclick="doDump()"
value="Dump">
</CENTER>
</TD>
</TR>
</TABLE>
<TEXTAREA id="status" rows="20" cols="80"></TEXTAREA>
<SCRIPT>
// globals
var inscan = true;
var br_x = 0, br_y = 0, tl_x = 0, tl_y = 0;
var max_br_x = 0, max_br_y = 0;
var last_br_x, last_br_y, last_tl_x, last_tl_y;
function sdump(str)
{
var status = document.getElementById('status');
status.value = str;
dump(str + "\n");
}
function doDump()
{
try {
var aScanner = document.scanner.nsISanePluginInstance;
sdump("ActiveDevice = " + aScanner.ActiveDevice + "\n" +
"State = " + aScanner.State + "\n" +
"Quality = " + aScanner.Quality + "\n" +
"Method = " + aScanner.Method + "\n" +
"DeviceOptions = " + aScanner.DeviceOptions + "\n" +
"ImageParameters = " + aScanner.ImageParameters + "\n" +
"AvailableDevices = " + aScanner.AvailableDevices + "\n");
} catch (ex) {
sdump("Error trying to dump: \n" + ex + "\n");
}
}
function adjustRegion(factor) {
try {
var aScanner = document.scanner.nsISanePluginInstance;
var x, y, height, width;
x = aScanner.ZoomX;
y = aScanner.ZoomY;
width = aScanner.ZoomWidth
+ factor;
height = Math.floor(width * 413/300);
aScanner.Crop(x, y, width, height);
} catch (ex) {
dump("Unable to zoom by " + factor + "\n" + ex + "\n");
}
}
function panRegionHor(factor) {
try {
var x, y, height, width;
var aScanner = document.scanner.nsISanePluginInstance;
if (aScanner.ZoomX + factor < 0)
x = aScanner.ZoomX;
else
x = aScanner.ZoomX + factor;
y = aScanner.ZoomY;
width = aScanner.ZoomWidth;
height = aScanner.ZoomHeight;
aScanner.Crop(x, y, width, height);
} catch (ex) {
dump("Unable to pan to requested location!\n");
}
}
function panRegionVert(factor) {
try {
var x, y, height, width;
var aScanner = document.scanner.nsISanePluginInstance;
if (aScanner.ZoomY + factor < 0)
y = aScanner.ZoomY;
else
y = aScanner.ZoomY + factor;
x = aScanner.ZoomX;
width = aScanner.ZoomWidth;
height = aScanner.ZoomHeight;
aScanner.Crop(x, y, width, height);
} catch (ex) {
dump("Unable to pan to requested location!\n");
}
}
function Save() {
try {
var aScanner = document.scanner.nsISanePluginInstance;
aScanner.SaveImage();
} catch (ex) {
dump("Error trying to save current image!\n");
}
}
function GetPreview()
{
if (inscan)
return;
try {
var aScanner = document.scanner.nsISanePluginInstance;
// Reset scan area for entire bed
tl_x = tl_y = 0;
br_x = max_br_x;
br_y = max_br_y;
aScanner.SetOption("tl-x", tl_x.toString(10));
aScanner.SetOption("tl-y", tl_y.toString(10));
aScanner.SetOption("br-x", br_x.toString(10));
aScanner.SetOption("br-y", br_y.toString(10));
// Set the lowest resolution the HP ScanJet 6300C supports
aScanner.SetOption("mode", "Color");
aScanner.SetOption("resolution", "12");
inscan = true;
aScanner.ScanImage();
// Scanning is a threaded function, so getting here
// only means that a scan operation was successfully started.
} catch (ex) {
dump("Error trying to get preview image!");
}
}
function ScanHi()
{
if (inscan)
return;
try {
var aScanner = document.scanner.nsISanePluginInstance;
// store last scan area coordinates
// so that Restore() knows what scan
// area coordinates to restore to.
last_br_x = br_x;
last_br_y = br_y;
last_tl_x = tl_x;
last_tl_y = tl_y;
// factors used in converting from zoom box
// to scanner coordinates
var xfactor = last_br_x/300;
var yfactor = last_br_y/413;
// zoom box coordinates
var z_br_x = aScanner.ZoomWidth + aScanner.ZoomX;
var z_br_y = aScanner.ZoomHeight + aScanner.ZoomY;
var z_tl_x = aScanner.ZoomX;
var z_tl_y = aScanner.ZoomY;
br_x = Math.floor(z_br_x * xfactor);
br_y = Math.floor(z_br_y * yfactor);
tl_x = Math.floor((z_tl_x * xfactor) + last_tl_x);
tl_y = Math.floor((z_tl_y * yfactor) + last_tl_y);
last_br_x = br_x;
last_br_y = br_y;
last_tl_x = tl_x;
last_tl_y = tl_y;
// set the scan area for zoom box
aScanner.SetOption("tl-x", tl_x);
aScanner.SetOption("tl-y", tl_y);
aScanner.SetOption("br-x", br_x);
aScanner.SetOption("br-y", br_y);
// For speed of testing, high resolution is set to
// just 150dpi
aScanner.SetOption("resolution", "150");
inscan = true;
aScanner.ScanImage();
// Scanning is a threaded operation so getting here
// only means that we have successfully started a scan.
} catch (ex) {
dump("Error trying to scan at 150!\n"+ ex + "\n");
}
}
function ScanCompleteCallback()
{
inscan = false;
dump("Completed Scan!\n");
}
function InitCompleteCallback()
{
// Additional device specific initialization
try {
var aScanner = document.scanner.nsISanePluginInstance;
// Reset scan area for entire bed
tl_x = tl_y = 0;
br_x = max_br_x;
br_y = max_br_y;
aScanner.SetOption("tl-x", tl_x.toString(10));
aScanner.SetOption("tl-y", tl_y.toString(10));
aScanner.SetOption("br-x", br_x.toString(10));
aScanner.SetOption("br-y", br_y.toString(10));
// this particular scan seems to scan in a
// a little dark by default
aScanner.SetOption("brightness", "30");
aScanner.SetOption("contrast", "10");
aScanner.Quality = 80;
aScanner.Method = "FAST";
aScanner.SetOption("mode", "Color");
// Set the maximum bottom x and bottom y
// for the HP ScanJet 6300C
last_br_x = br_x = max_br_x = 14141852;
last_br_y = br_y = max_br_y = 19456836;
last_tl_x = tl_x;
last_tl_y = tl_y;
inscan = false;
} catch (ex) {
dump("Error trying to set device specific initialization!\n");
}
}
</SCRIPT>
</BODY>
</HTML>