/Users/ericb/Desktop/NATIVEPRINTDLG01/extensions/source/scanner/twain.cxx

Go to the documentation of this file.
00001 /*************************************************************************
00002  *
00003  *  OpenOffice.org - a multi-platform office productivity suite
00004  *
00005  *  $RCSfile: twain.cxx,v $
00006  *
00007  *  $Revision: 1.5 $
00008  *
00009  *  last change: $Author: vg $ $Date: 2007/09/20 14:27:58 $
00010  *
00011  *  The Contents of this file are made available subject to
00012  *  the terms of GNU Lesser General Public License Version 2.1.
00013  *
00014  *
00015  *    GNU Lesser General Public License Version 2.1
00016  *    =============================================
00017  *    Copyright 2005 by Sun Microsystems, Inc.
00018  *    901 San Antonio Road, Palo Alto, CA 94303, USA
00019  *
00020  *    This library is free software; you can redistribute it and/or
00021  *    modify it under the terms of the GNU Lesser General Public
00022  *    License version 2.1, as published by the Free Software Foundation.
00023  *
00024  *    This library is distributed in the hope that it will be useful,
00025  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
00026  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00027  *    Lesser General Public License for more details.
00028  *
00029  *    You should have received a copy of the GNU Lesser General Public
00030  *    License along with this library; if not, write to the Free Software
00031  *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
00032  *    MA  02111-1307  USA
00033  *
00034  ************************************************************************/
00035 
00036 // MARKER(update_precomp.py): autogen include statement, do not remove
00037 #include "precompiled_extensions.hxx"
00038 
00039 #include <string.h>
00040 #include <math.h>
00041 
00042 #if defined( WNT ) || defined (WIN)
00043 #include <tools/svwin.h>
00044 #endif  
00045 #ifdef OS2
00046 #include <svpm.h>
00047 #endif // OS2
00048 #include <vos/module.hxx>
00049 #include <tools/stream.hxx>
00050 #include <vcl/svapp.hxx>
00051 #include <vcl/wrkwin.hxx>
00052 #include <vcl/sysdata.hxx>
00053 #include "twain.hxx"
00054 
00055 // -----------
00056 // - Defines -
00057 // -----------
00058 
00059 #define PFUNC                                           (*pDSM)
00060 #define FIXTODOUBLE( nFix )             ((double)nFix.Whole+(double)nFix.Frac/65536.)
00061 #define FIXTOLONG( nFix )                       ((long)floor(FIXTODOUBLE(nFix)+0.5))
00062 
00063 #if defined WIN
00064 #define TWAIN_LIBNAME                           "TWAIN.DLL"
00065 #define TWAIN_FUNCNAME                          "DSM_Entry"
00066 #elif defined WNT
00067 #define TWAIN_LIBNAME                           "TWAIN_32.DLL"
00068 #define TWAIN_FUNCNAME                          "DSM_Entry"
00069 #elif defined OS2
00070 #define TWAIN_LIBNAME                           "twain"
00071 #define TWAIN_FUNCNAME                          "DSM_ENTRY"
00072 #endif
00073 
00074 // -----------
00075 // - Statics -
00076 // -----------
00077 
00078 static ImpTwain* pImpTwainInstance = NULL;
00079 
00080 // ---------
00081 // - Procs -
00082 // ---------
00083 
00084 #ifdef OS2
00085 
00086         #define PTWAINMSG QMSG*
00087 
00088         MRESULT EXPENTRY TwainWndProc( HWND hWnd, ULONG nMsg, MPARAM nParam1, MPARAM nParam2 )
00089         {
00090                 return (MRESULT) TRUE;
00091         }
00092 
00093 
00094 #else // OS2
00095 
00096         #define PTWAINMSG MSG*
00097 
00098         // -------------------------------------------------------------------------
00099 
00100         LRESULT CALLBACK TwainWndProc( HWND hWnd,UINT nMsg, WPARAM nPar1, LPARAM nPar2 )
00101         {
00102                 return DefWindowProc( hWnd, nMsg, nPar1, nPar2 );
00103         }
00104 
00105         // -------------------------------------------------------------------------
00106 
00107         LRESULT CALLBACK TwainMsgProc( int nCode, WPARAM wParam, LPARAM lParam )
00108         {
00109                 MSG* pMsg = (MSG*) lParam;
00110 
00111                 if( ( nCode < 0 ) || 
00112                         ( pImpTwainInstance->hTwainWnd != pMsg->hwnd ) ||
00113                         !pImpTwainInstance->ImplHandleMsg( (void*) lParam ) )
00114                 {
00115                         return CallNextHookEx( pImpTwainInstance->hTwainHook, nCode, wParam, lParam );
00116                 }
00117                 else
00118                 {
00119                         pMsg->message = WM_USER;
00120                         pMsg->lParam = 0;
00121                         
00122                         return 0;
00123                 }
00124         }
00125 
00126 #endif // OS2
00127 
00128 // ------------
00129 // - ImpTwain -
00130 // ------------
00131 
00132 ImpTwain::ImpTwain( const Link& rNotifyLink ) :
00133                         aNotifyLink ( rNotifyLink ),
00134                         pDSM            ( NULL ),
00135                         pMod            ( NULL ),
00136                         hTwainWnd       ( 0 ),
00137                         hTwainHook      ( 0 ),
00138                         nCurState       ( 1 )
00139 {
00140         pImpTwainInstance = this;
00141 
00142         aAppIdent.Id = 0;
00143         aAppIdent.Version.MajorNum = 1;
00144         aAppIdent.Version.MinorNum = 0;
00145         aAppIdent.Version.Language = TWLG_USA;
00146         aAppIdent.Version.Country = TWCY_USA;
00147         aAppIdent.ProtocolMajor = TWON_PROTOCOLMAJOR;
00148         aAppIdent.ProtocolMinor = TWON_PROTOCOLMINOR;
00149         aAppIdent.SupportedGroups =     DG_IMAGE | DG_CONTROL;
00150         strcpy( aAppIdent.Version.Info, "6.0" );
00151         strcpy( aAppIdent.Manufacturer, "Sun Microsystems");
00152         strcpy( aAppIdent.ProductFamily,"Office");
00153         strcpy( aAppIdent.ProductName, "Office");
00154 
00155 #ifdef OS2
00156 
00157         hAB = Sysdepen::GethAB();
00158         ImplFallback( TWAIN_EVENT_QUIT );
00159         // hTwainWnd = WinCreateWindow( HWND_DESKTOP, WC_FRAME, "dummy", 0, 0, 0, 0, 0, HWND_DESKTOP, HWND_BOTTOM, 0, 0, 0 );
00160 
00161 #else
00162 
00163         HWND            hParentWnd = HWND_DESKTOP;
00164         WNDCLASS        aWc = { 0, &TwainWndProc, 0, sizeof( WNDCLASS ), GetModuleHandle( NULL ), 
00165                                                 NULL, NULL, NULL, NULL, "TwainClass" };
00166 
00167         RegisterClass( &aWc );
00168         hTwainWnd = CreateWindowEx( WS_EX_TOPMOST, aWc.lpszClassName, "TWAIN", 0, 0, 0, 0, 0, hParentWnd, NULL, aWc.hInstance, 0 );
00169         hTwainHook = SetWindowsHookEx( WH_GETMESSAGE, &TwainMsgProc, NULL, GetCurrentThreadId() );
00170 
00171 #endif
00172 }
00173 
00174 // -----------------------------------------------------------------------------
00175 
00176 ImpTwain::~ImpTwain()
00177 {
00178 }
00179 
00180 // -----------------------------------------------------------------------------
00181 
00182 void ImpTwain::Destroy()
00183 {
00184         ImplFallback( TWAIN_EVENT_NONE );
00185         Application::PostUserEvent( LINK( this, ImpTwain, ImplDestroyHdl ), NULL );
00186 }
00187 
00188 // -----------------------------------------------------------------------------
00189 
00190 BOOL ImpTwain::SelectSource()
00191 {
00192         TW_UINT16 nRet = TWRC_FAILURE;
00193 
00194         if( !!aBitmap )
00195                 aBitmap = Bitmap();
00196 
00197         ImplOpenSourceManager();
00198 
00199         if( 3 == nCurState )
00200         {
00201                 TW_IDENTITY aIdent;
00202 
00203                 aIdent.Id = 0, aIdent.ProductName[ 0 ] = '\0';
00204                 aNotifyLink.Call( (void*) TWAIN_EVENT_SCANNING );
00205                 nRet = PFUNC( &aAppIdent, NULL, DG_CONTROL, DAT_IDENTITY, MSG_USERSELECT, &aIdent );
00206         }
00207 
00208         ImplFallback( TWAIN_EVENT_QUIT );
00209 
00210         return( nRet == TWRC_SUCCESS || nRet == TWRC_CANCEL );
00211 }
00212 
00213 // -----------------------------------------------------------------------------
00214 
00215 BOOL ImpTwain::InitXfer()
00216 {
00217         BOOL bRet = FALSE;
00218 
00219         if( !!aBitmap )
00220                 aBitmap = Bitmap();
00221 
00222         ImplOpenSourceManager();
00223 
00224         if( 3 == nCurState )
00225         {
00226                 ImplOpenSource();
00227 
00228                 if( 4 == nCurState )
00229                         bRet = ImplEnableSource();
00230         }
00231 
00232         if( !bRet )
00233                 ImplFallback( TWAIN_EVENT_QUIT );
00234 
00235         return bRet;
00236 }
00237 
00238 // -----------------------------------------------------------------------------
00239 
00240 Bitmap ImpTwain::GetXferBitmap()
00241 {
00242         Bitmap aRet( aBitmap );
00243         aBitmap = Bitmap();
00244         return aRet;
00245 }
00246 
00247 // -----------------------------------------------------------------------------
00248 
00249 void ImpTwain::ImplOpenSourceManager()
00250 {
00251         if( 1 == nCurState )
00252         {
00253                 pMod = new NAMESPACE_VOS( OModule )();
00254 
00255                 if( pMod->load( TWAIN_LIBNAME ) )
00256                 {
00257                         nCurState = 2;
00258 
00259                         if( ( ( pDSM = (DSMENTRYPROC) pMod->getSymbol( TWAIN_FUNCNAME ) ) != NULL ) &&
00260                                 ( PFUNC( &aAppIdent, NULL, DG_CONTROL, DAT_PARENT, MSG_OPENDSM, &hTwainWnd ) == TWRC_SUCCESS ) )
00261                         {
00262                                 nCurState = 3;
00263                         }
00264                 }
00265                 else
00266                 {
00267                         delete pMod;
00268                         pMod = NULL;
00269                 }
00270         }
00271 }
00272 
00273 // -----------------------------------------------------------------------------
00274 
00275 void ImpTwain::ImplOpenSource()
00276 {
00277         if( 3 == nCurState )
00278         {
00279                 if( ( PFUNC( &aAppIdent, NULL, DG_CONTROL, DAT_IDENTITY, MSG_GETDEFAULT, &aSrcIdent ) == TWRC_SUCCESS ) &&
00280                         ( PFUNC( &aAppIdent, NULL, DG_CONTROL, DAT_IDENTITY, MSG_OPENDS, &aSrcIdent ) == TWRC_SUCCESS ) )
00281                 {
00282 #ifdef OS2
00283 
00284                         // negotiate capabilities
00285                         
00286 #else
00287 
00288                         TW_CAPABILITY   aCap = { CAP_XFERCOUNT, TWON_ONEVALUE, GlobalAlloc( GHND, sizeof( TW_ONEVALUE ) ) };
00289                         TW_ONEVALUE*    pVal = (TW_ONEVALUE*) GlobalLock( aCap.hContainer );
00290 
00291                         pVal->ItemType = TWTY_INT16, pVal->Item = 1;
00292                         GlobalUnlock( aCap.hContainer );
00293                         PFUNC( &aAppIdent, &aSrcIdent, DG_CONTROL, DAT_CAPABILITY, MSG_SET, &aCap );
00294                         GlobalFree( aCap.hContainer );
00295 #endif
00296 
00297                         nCurState = 4;
00298                 }
00299         }
00300 }
00301 
00302 // -----------------------------------------------------------------------------
00303 
00304 BOOL ImpTwain::ImplEnableSource()
00305 {
00306         BOOL bRet = FALSE;
00307 
00308         if( 4 == nCurState )
00309         {
00310                 TW_USERINTERFACE aUI = { TRUE, TRUE, hTwainWnd };
00311 
00312                 aNotifyLink.Call( (void*) TWAIN_EVENT_SCANNING );
00313                 nCurState = 5;
00314 
00315                 if( PFUNC( &aAppIdent, &aSrcIdent, DG_CONTROL, DAT_USERINTERFACE, MSG_ENABLEDS, &aUI ) == TWRC_SUCCESS )
00316                         bRet = TRUE;
00317                 else
00318                         nCurState = 4;
00319         }
00320 
00321         return bRet;
00322 }
00323 
00324 // -----------------------------------------------------------------------------
00325 
00326 BOOL ImpTwain::ImplHandleMsg( void* pMsg )
00327 {
00328         TW_UINT16       nRet;
00329         PTWAINMSG       pMess = (PTWAINMSG) pMsg;
00330         TW_EVENT        aEvt = { pMess, MSG_NULL };
00331 
00332         nRet = PFUNC( &aAppIdent, &aSrcIdent, DG_CONTROL, DAT_EVENT, MSG_PROCESSEVENT, &aEvt );
00333 
00334         if( aEvt.TWMessage != MSG_NULL )
00335         {
00336                 switch( aEvt.TWMessage )
00337                 {
00338                         case MSG_XFERREADY:
00339                         {
00340                                 ULONG nEvent = TWAIN_EVENT_QUIT;
00341 
00342                                 if( 5 == nCurState )
00343                                 {
00344                                         nCurState = 6;
00345                                         ImplXfer();
00346 
00347                                         if( !!aBitmap )
00348                                                 nEvent = TWAIN_EVENT_XFER;
00349                                 }
00350 
00351                                 ImplFallback( nEvent );
00352                         }
00353                         break;
00354                         
00355                         case MSG_CLOSEDSREQ:
00356                                 ImplFallback( TWAIN_EVENT_QUIT );
00357                         break;
00358 
00359                         default:
00360                         break;
00361                 }
00362         }
00363         else
00364                 nRet = TWRC_NOTDSEVENT;
00365 
00366         return( TWRC_DSEVENT == nRet );
00367 }
00368 
00369 // -----------------------------------------------------------------------------
00370 
00371 void ImpTwain::ImplXfer()
00372 {
00373         if( nCurState == 6 )
00374         {
00375                 TW_IMAGEINFO    aInfo;
00376                 TW_UINT32               hDIB = 0;
00377                 long                    nWidth = aInfo.ImageWidth;
00378                 long                    nHeight = aInfo.ImageLength;
00379                 long                    nXRes = FIXTOLONG( aInfo.XResolution );
00380                 long                    nYRes = FIXTOLONG( aInfo.YResolution );
00381 
00382                 if( PFUNC( &aAppIdent, &aSrcIdent, DG_IMAGE, DAT_IMAGEINFO, MSG_GET, &aInfo ) == TWRC_SUCCESS )
00383                 {
00384                         nWidth = aInfo.ImageWidth;
00385                         nHeight = aInfo.ImageLength;
00386                         nXRes = FIXTOLONG( aInfo.XResolution );
00387                         nYRes = FIXTOLONG( aInfo.YResolution );
00388                 }
00389                 else
00390                         nWidth = nHeight = nXRes = nYRes = -1L;
00391 
00392                 switch( PFUNC( &aAppIdent, &aSrcIdent, DG_IMAGE, DAT_IMAGENATIVEXFER, MSG_GET, &hDIB ) )
00393                 {
00394                         case( TWRC_CANCEL ):
00395                                 nCurState = 7;
00396                         break;
00397 
00398                         case( TWRC_XFERDONE ):
00399                         {
00400 #ifdef OS2
00401 
00402                                 // get OS/2-Bitmap
00403 
00404 #else // OS2
00405                                 const ULONG nSize = GlobalSize( (HGLOBAL) hDIB );
00406                                 char*           pBuf = (char*) GlobalLock( (HGLOBAL) hDIB );
00407 
00408                                 if( pBuf )
00409                                 {
00410                                         SvMemoryStream aMemStm;
00411                                         aMemStm.SetBuffer( pBuf, nSize, FALSE, nSize );
00412                                         aBitmap.Read( aMemStm, FALSE );
00413                                         GlobalUnlock( (HGLOBAL) hDIB );
00414                                 }
00415 
00416                                 GlobalFree( (HGLOBAL) hDIB );
00417 #endif // OS2
00418 
00419                                 // set resolution of bitmap if neccessary
00420                                 if ( ( nXRes != -1 ) && ( nYRes != - 1 ) && ( nWidth != - 1 ) && ( nHeight != - 1 ) )
00421                                 {
00422                                         const MapMode aMapMode( MAP_100TH_INCH, Point(), Fraction( 100, nXRes ), Fraction( 100, nYRes ) );
00423                                         aBitmap.SetPrefMapMode( aMapMode );
00424                                         aBitmap.SetPrefSize( Size( nWidth, nHeight ) );
00425                                 }
00426 
00427                                 nCurState = 7;
00428                         }
00429                         break;
00430 
00431                         default:
00432                         break;
00433                 }
00434         }
00435 }
00436 
00437 // -----------------------------------------------------------------------------
00438 
00439 void ImpTwain::ImplFallback( ULONG nEvent )
00440 {
00441         Application::PostUserEvent( LINK( this, ImpTwain, ImplFallbackHdl ), (void*) nEvent );
00442 }
00443 
00444 // -----------------------------------------------------------------------------
00445 
00446 IMPL_LINK( ImpTwain, ImplFallbackHdl, void*, pData )
00447 {
00448         const ULONG     nEvent = (ULONG) pData;
00449         BOOL            bFallback = TRUE;
00450 
00451         switch( nCurState )
00452         {
00453                 case( 7 ):
00454                 case( 6 ):
00455                 {
00456                         TW_PENDINGXFERS aXfers;
00457 
00458                         if( PFUNC( &aAppIdent, &aSrcIdent, DG_CONTROL, DAT_PENDINGXFERS, MSG_ENDXFER, &aXfers ) == TWRC_SUCCESS )
00459                         {
00460                                 if( aXfers.Count != 0 )
00461                                         PFUNC( &aAppIdent, &aSrcIdent, DG_CONTROL, DAT_PENDINGXFERS, MSG_RESET, &aXfers );
00462                         }
00463 
00464                         nCurState = 5;
00465                 }
00466                 break;
00467 
00468                 case( 5 ):
00469                 {
00470                         TW_USERINTERFACE aUI = { TRUE, TRUE, hTwainWnd };
00471                 
00472                         PFUNC( &aAppIdent, &aSrcIdent, DG_CONTROL, DAT_USERINTERFACE, MSG_DISABLEDS, &aUI );
00473                         nCurState = 4;
00474                 }
00475                 break;
00476 
00477                 case( 4 ):
00478                 {
00479                         PFUNC( &aAppIdent, NULL, DG_CONTROL, DAT_IDENTITY, MSG_CLOSEDS, &aSrcIdent );
00480                         nCurState = 3;
00481                 }
00482                 break;
00483 
00484                 case( 3 ):
00485                 {
00486                         PFUNC( &aAppIdent, NULL, DG_CONTROL, DAT_PARENT, MSG_CLOSEDSM, &hTwainWnd );
00487                         nCurState = 2;
00488                 }
00489                 break;
00490 
00491                 case( 2 ):
00492                 {
00493                         delete pMod;
00494                         pMod = NULL;
00495                         nCurState = 1;
00496                 }
00497                 break;
00498 
00499                 default:
00500                 {
00501                         if( nEvent != TWAIN_EVENT_NONE )
00502                                 aNotifyLink.Call( (void*) nEvent );
00503 
00504                         bFallback = FALSE;
00505                 }
00506                 break;
00507         }
00508 
00509         if( bFallback )
00510                 ImplFallback( nEvent );
00511 
00512         return 0L;
00513 }
00514 
00515 // -----------------------------------------------------------------------------
00516 
00517 IMPL_LINK( ImpTwain, ImplDestroyHdl, void*, p )
00518 {
00519 #ifdef OS2
00520 
00521         if( hWndTwain )
00522                 WinDestroyWindow( hWndTwain );
00523 
00524         // unset hook
00525 
00526 #else
00527 
00528         if( hTwainWnd )
00529                 DestroyWindow( hTwainWnd );
00530 
00531         if( hTwainHook )
00532                 UnhookWindowsHookEx( hTwainHook );
00533 
00534 #endif
00535 
00536         delete this;
00537         pImpTwainInstance = NULL;
00538 
00539         return 0L;
00540 }

Generated on Thu Feb 28 17:53:27 2008 for AquaScanner by  doxygen 1.5.1