зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
9a72cc8908
Коммит
79196ab9b1
|
@ -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>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
Загрузка…
Ссылка в новой задаче