Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

VFWSource.cpp

Go to the documentation of this file.
00001 /* ---------------------------------------------------------------------------
00002     Phission : 
00003         Realtime Vision Processing System
00004     
00005     Copyright (C) 2003-2006 Philip D.S. Thoren (pthoren@cs.uml.edu)
00006     University of Massachusetts at Lowell,
00007     Laboratory for Artificial Intelligence and Robotics
00008     
00009     This file is part of Phission.
00010 
00011     Phission is free software; you can redistribute it and/or modify
00012     it under the terms of the GNU Lesser General Public License as published by
00013     the Free Software Foundation; either version 2 of the License, or
00014     (at your option) any later version.
00015 
00016     Phission is distributed in the hope that it will be useful,
00017     but WITHOUT ANY WARRANTY; without even the implied warranty of
00018     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019     GNU Lesser General Public License for more details.
00020 
00021     You should have received a copy of the GNU Lesser General Public License
00022     along with Phission; if not, write to the Free Software
00023     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00024 
00025  ---------------------------------------------------------------------------*/
00026 #ifdef HAVE_CONFIG_H
00027     #include <phissionconfig.h>
00028 #endif
00029 
00030 #if !defined(UNICODE)
00031     #define UNICODE 1
00032 #endif
00033 
00034 #include <phStandard.h>
00035 #include <ImageConversions.h>
00036 
00037 #include <phObject.h>
00038 #include <phMutex.h>
00039 #include <phSemaphore.h>
00040 #include <phCondition.h>
00041 #include <phRWLock.h>
00042 #include <phThread.h>
00043 #include <phList.h>
00044 #include <phTimeStamp.h>
00045 #include <phTimeInterval.h>
00046 #include <phLiveObject.h>
00047 #include <phDataObject.h>
00048 #include <phImage.h>
00049 #include <phCaptureInterface.h>
00050 #include <phImageCapture.h>
00051 
00052 #include <phVFW.h>
00053 #include <VFWSource.h>
00054 
00055 #define TIMESTUFF() 0
00056 #if TIMESTUFF()
00057     #include <phTime.h>
00058 #endif
00059 
00060 #include <phError.h>
00061 #include <phMemory.h>
00062 #include <phPrint.h>
00063 
00064 /* ---------------------------------------------------------------------- */
00065 #define WM_USER_SHOW    (WM_USER + 200)
00066 #define WM_USER_HIDE    (WM_USER + 201)
00067 #define WM_USER_RESIZE  (WM_USER + 202)
00068 #define WM_USER_MOVE    (WM_USER + 203)
00069 #define WM_USER_UPDATE  (WM_USER + 204)
00070 #define WM_USER_REDRAW  (WM_USER + 205)
00071 
00072 #define phBITMAP_REALLOCED 1
00073 #define phDISPLAY_CHANGED  1
00074 
00075 /* ---------------------------------------------------------------------- */
00076 struct phVFWWindowInfo_t
00077 {
00078     HMODULE     module;
00079     HINSTANCE   instance;
00080     LPTSTR      command_line;
00081     STARTUPINFO startup_info;
00082     HWND        window;
00083     WNDCLASS    window_class;
00084     wchar_t     *window_class_name;
00085     ATOM        window_atom;
00086 
00087     /* Bitmap image info and structures */
00088     HBITMAP     bitmap;
00089     BITMAPINFO  bitmap_info;
00090     void        *pixels;
00091     uint32_t    bitmap_width;
00092     uint32_t    bitmap_height;
00093 
00094     /* Capture Variables */
00095     int             device;
00096     int             connected;
00097     int             started;
00098     HWND            capwin;
00099     CAPSTATUS       d_status;
00100     CAPDRIVERCAPS   d_caps;
00101     CAPTUREPARMS    d_setup;
00102     wchar_t         d_name[255];
00103     wchar_t         d_version[255];
00104     LPBITMAPINFO    d_lpbi;
00105 };
00106 
00107 /* ---------------------------------------------------------------------- */
00108 struct phVFW_pair_t
00109 {
00110     VFWSource    *thisptr;
00111     HHOOK               hook;
00112 };
00113 
00114 /* ---------------------------------------------------------------------- */
00115 struct phVFWHandlerParameters_t
00116 {
00117     HWND    window;
00118     UINT    message;
00119     WPARAM  wp;
00120     LPARAM  lp;
00121 };
00122 
00123 /* ---------------------------------------------------------------------- */
00124 static void print_POINT(POINT p)
00125 {
00126     phFUNCTION("print_POINT")
00127     DEBUG_PRINT("(%d,%d)",
00128           p.x,
00129           p.y);
00130 }
00131 
00132 /* ---------------------------------------------------------------------- */
00133 static void print_RECT(RECT rect)
00134 {
00135     phFUNCTION("print_RECT")
00136     DEBUG_PRINT("(%d,%d,%d,%d)",
00137           rect.left,
00138           rect.top,
00139           rect.right,
00140           rect.bottom);
00141 }
00142 
00143 /* ---------------------------------------------------------------------- */
00144 static void print_MINMAXINFO(MINMAXINFO m)
00145 {
00146     phFUNCTION("print_MINMAXINFO")
00147     DEBUG_PRINT("[reserved:");
00148     print_POINT(m.ptReserved);
00149     DEBUG_PRINT("maxsize:");
00150     print_POINT(m.ptMaxSize);
00151     DEBUG_PRINT("maxpos:");
00152     print_POINT(m.ptMaxPosition);
00153     DEBUG_PRINT("mintrack:");
00154     print_POINT(m.ptMinTrackSize);
00155     DEBUG_PRINT("maxtrack:");
00156     print_POINT(m.ptMaxTrackSize);
00157     DEBUG_PRINT("]");
00158 }
00159 
00160 /* ---------------------------------------------------------------------- */
00161 static void print_WINDOWPOS(WINDOWPOS w)
00162 {
00163     phFUNCTION("print_WINDOWPOS")
00164     DEBUG_PRINT("(%d,%d,x:%d,y:%d,cx:%d,cy:%d)",
00165           w.hwnd,w.hwndInsertAfter,
00166           w.x,w.y,w.cx,w.cy);
00167     if (w.flags & SWP_DRAWFRAME)
00168     {
00169         DEBUG_PRINT("SWP_DRAWFRAME:");
00170     }
00171     if (w.flags & SWP_FRAMECHANGED)
00172     {
00173         DEBUG_PRINT("SWP_FRAMECHANGED:");
00174     }
00175     if (w.flags & SWP_HIDEWINDOW)
00176     {
00177         DEBUG_PRINT("SWP_HIDEWINDOW:");
00178     }
00179     if (w.flags & SWP_NOACTIVATE)
00180     {
00181         DEBUG_PRINT("SWP_NOACTIVATE:");
00182     }
00183     if (w.flags & SWP_NOCOPYBITS)
00184     {
00185         DEBUG_PRINT("SWP_NOCOPYBITS:");
00186     }
00187     if (w.flags & SWP_NOMOVE)
00188     {
00189         DEBUG_PRINT("SWP_NOMOVE:");
00190     }
00191     if (w.flags & SWP_NOOWNERZORDER)
00192     {
00193         DEBUG_PRINT("SWP_NOOWNERZORDER:");
00194     }
00195     if (w.flags & SWP_NOREDRAW)
00196     {
00197         DEBUG_PRINT("SWP_NOREDRAW:");
00198     }
00199     if (w.flags & SWP_NOREPOSITION)
00200     {
00201         DEBUG_PRINT("SWP_NOREPOSITION:");
00202     }
00203     if (w.flags & SWP_NOSENDCHANGING)
00204     {
00205         DEBUG_PRINT("SWP_NOSENDCHANGING:");
00206     }
00207     if (w.flags & SWP_NOSIZE)
00208     {
00209         DEBUG_PRINT("SWP_NOSIZE:");
00210     }
00211     if (w.flags & SWP_NOZORDER)
00212     {
00213         DEBUG_PRINT("SWP_NOZORDER:");
00214     }
00215     if (w.flags & SWP_SHOWWINDOW )
00216     {
00217         DEBUG_PRINT("SWP_SHOWWINDOW:");
00218     }
00219 }
00220 
00221 /* ---------------------------------------------------------------------- */
00222 static void print_CREATESTRUCT(CREATESTRUCT c)
00223 {
00224     phFUNCTION("print_CREATESTRUCT")
00225     DEBUG_PRINT("(%p,%d,%d,%d,cy:%d,cx:%d,y:%d,x:%d,%ld,%s,%s,%ld)",
00226           c.lpCreateParams,
00227           c.hInstance,
00228           c.hMenu,
00229           c.hwndParent,
00230           c.cy,c.cx,c.y,c.x,
00231           c.style,c.lpszName,c.lpszClass,c.dwExStyle);
00232 }
00233 
00234 /* ---------------------------------------------------------------------- */
00235 static void print_SIDE(WPARAM fwSide)
00236 {
00237     phFUNCTION("print_SIDE")
00238     if (fwSide & WMSZ_BOTTOM)
00239     {
00240         DEBUG_PRINT("WMSZ_BOTTOM:");
00241     }
00242     if (fwSide == WMSZ_BOTTOMLEFT)
00243     {
00244         DEBUG_PRINT("WMSZ_BOTTOMLEFT:");
00245     }
00246     if (fwSide == WMSZ_BOTTOMRIGHT)
00247     {
00248         DEBUG_PRINT("WMSZ_BOTTOMRIGHT:");
00249     }
00250     if (fwSide & WMSZ_LEFT)
00251     {
00252         DEBUG_PRINT("WMSZ_LEFT:");
00253     }
00254     if (fwSide & WMSZ_RIGHT)
00255     {
00256         DEBUG_PRINT("WMSZ_RIGHT:");
00257     }
00258     if (fwSide & WMSZ_TOP)
00259     {
00260         DEBUG_PRINT("WMSZ_TOP:");
00261     }
00262     if (fwSide == WMSZ_TOPLEFT)
00263     {
00264         DEBUG_PRINT("WMSZ_TOPLEFT:");
00265     }
00266     if (fwSide == WMSZ_TOPRIGHT)
00267     {
00268         DEBUG_PRINT("WMSZ_TOPRIGHT:");
00269     }
00270 }
00271 
00272 /* ---------------------------------------------------------------------- */
00273 static BOOL CALLBACK phVFWSource_enumChildProc( HWND hwnd, LPARAM lParam )
00274 {
00275     phFUNCTION("phVFWSource_enumChildProc")
00276     wchar_t text[255];
00277     RECT rect;
00278     
00279     GetWindowText(hwnd,(LPWSTR)text,255);
00280     GetWindowRect( hwnd, &rect );
00281     print_RECT(rect);
00282     
00283     return TRUE;
00284 }
00285 
00286 /* ---------------------------------------------------------------------- */
00287 static void print_window_info(HWND window)
00288 {
00289     phFUNCTION("print_window_info")
00290     RECT rect;
00291     DEBUG_PRINT("Window(%d):",window);
00292     GetWindowRect( window, &rect );
00293     print_RECT(rect);
00294     DEBUG_PRINT("\n");
00295     DEBUG_PRINT("Client:");
00296     GetClientRect( window, &rect );
00297     print_RECT(rect);
00298     DEBUG_PRINT("\n");
00299 
00300     EnumChildWindows(window,phVFWSource_enumChildProc,0);
00301 }
00302 
00303 /* ---------------------------------------------------------------------- */
00304 static void print_CAPDRIVERCAPS(CAPDRIVERCAPS caps)
00305 {
00306     phFUNCTION("print_CAPDRIVERCAPS")
00307     DEBUG_PRINT("CAPDRIVERCAPS\n{\n");
00308     DEBUG_PRINT("\t%s:%d\n\t%s:%d\n\t%s:%d\n\t%s:%d\n\t%s:%d\n\t%s:%d\n\t%s:%d\n\t%s:0x%08x\n\t%s:0x%08x\n\t%s:0x%08x\n\t%s:0x%08x\n",
00309         "wNumAudioAllocated:    Driver index in system.ini  ",caps.wDeviceIndex,
00310         "fHasOverlay:           Can device overlay?         ",caps.fHasOverlay,
00311         "fHasDlgVideoSource:    Has Video source dlg?       ",caps.fHasDlgVideoSource,
00312         "fHasDlgVideoFormat:    Has Format dlg?             ",caps.fHasDlgVideoFormat,
00313         "fHasDlgVideoDisplay:   Has External out dlg?       ",caps.fHasDlgVideoDisplay,
00314         "fCaptureInitialized:   Driver ready to capture?    ",caps.fCaptureInitialized,
00315         "fDriverSuppliesPalettes:Can driver make palettes?  ",caps.fDriverSuppliesPalettes,
00316         "hVideoIn:              Driver In channel           ",caps.hVideoIn,
00317         "hVideoOut:             Driver Out channel          ",caps.hVideoOut,
00318         "hVideoExtIn:           Driver Ext In channel       ",caps.hVideoExtIn,
00319         "hVideoExtOut:          Driver Ext Out channel      ",caps.hVideoExtOut);
00320     DEBUG_PRINT("};\n");
00321 }
00322 
00323 /* ---------------------------------------------------------------------- */
00324 static void print_CAPSTATUS(CAPSTATUS stat)
00325 {
00326     phFUNCTION("print_CAPSTATUS")
00327     DEBUG_PRINT("CAPSTAUTS\n{\n");
00328     DEBUG_PRINT("\t%s:%d\n\t%s:%d\n\t%s:%d\n\t%s:%d\n\t%s:%d\n\t%s:%d\n\t%s:%d\n\t%s:%d\n\t%s:%d\n\t%s:%d\n",
00329         "uiImageWidth:          Width of the image              ",stat.uiImageWidth,
00330         "uiImageHeight:         Height of the image             ",stat.uiImageHeight,
00331         "fLiveWindow:           Now Previewing video?           ",stat.fLiveWindow,
00332         "fOverlayWindow:        Now Overlaying video?           ",stat.fOverlayWindow,
00333         "fScale:                Scale image to client?          ",stat.fScale,
00334         "fUsingDefaultPalette:  Using default driver palette?   ",stat.fUsingDefaultPalette,
00335         "fAudioHardware:        Audio hardware present?         ",stat.fAudioHardware,
00336         "fCapFileExists:        Does capture file exist?        ",stat.fCapFileExists,
00337         "dwCurrentVideoFrame:   # of video frames cap'td        ",stat.dwCurrentVideoFrame,
00338         "dwCurrentVideoFramesDropped:# of video frames dropped  ",stat.dwCurrentVideoFramesDropped
00339     );
00340     DEBUG_PRINT("\t%s:%d\n\t%s:%d\n\t%s:%d\n\t%s:%d\n\t%s:%d\n\t%s:%d\n\t%s:%d\n\t%s:%d\n",
00341         "dwCurrentWaveSamples:  # of wave samples cap'td        ",stat.dwCurrentWaveSamples,
00342         "dwCurrentTimeElapsedMS:Elapsed capture duration        ",stat.dwCurrentTimeElapsedMS,
00343         "hPalCurrent:           Current palette in use          ",stat.hPalCurrent,
00344         "fCapturingNow:         Capture in progress?            ",stat.fCapturingNow,
00345         "dwReturn:              Error value after any operation ",stat.dwReturn,
00346         "wNumVideoAllocated:    Actual number of video buffers  ",stat.wNumVideoAllocated,
00347         "wNumAudioAllocated:    Actual number of audio buffers  ",stat.wNumAudioAllocated);
00348     DEBUG_PRINT("\tScroll position:");
00349     print_POINT(stat.ptScroll);
00350     DEBUG_PRINT("\n");
00351     DEBUG_PRINT("};\n");
00352 }
00353 
00354 /* ---------------------------------------------------------------------- */
00355 static void print_CAPTUREPARMS(CAPTUREPARMS parms)
00356 {
00357     phFUNCTION("print_CAPTUREPARMS")
00358     DEBUG_PRINT("\nCAPTUREPARMS\n{\n\t%s:%d\n\t%s:%d\n\t%s:%d\n\t%s:%d\n\t%s:%d\n\t%s:%d\n\t%s:%d\n\t%s:%d\n\t%s:%d\n\t%s:%d\n",
00359     "dwRequestMicroSecPerFrame: Requested capture rate              ",parms.dwRequestMicroSecPerFrame,
00360     "fMakeUserHitOKToCapture:   Show \"Hit OK to cap\" dlg?         ",parms.fMakeUserHitOKToCapture,
00361     "wPercentDropForError:      Give error msg if > (10%)           ",parms.wPercentDropForError,
00362     "fYield:                    Capture via background task?        ",parms.fYield,
00363     "dwIndexSize:               Max index size in frames (32K)      ",parms.dwIndexSize,
00364     "wChunkGranularity:         Junk chunk granularity (2K)         ",parms.wChunkGranularity,
00365     "fUsingDOSMemory:           Use DOS buffers?                    ",parms.fUsingDOSMemory,
00366     "wNumVideoRequested:        # video buffers, If 0, autocalc     ",parms.wNumVideoRequested,
00367     "fCaptureAudio:             Capture audio?                      ",parms.fCaptureAudio,
00368     "wNumAudioRequested:        # audio buffers, If 0, autocalc     ",parms.wNumAudioRequested
00369     );
00370     DEBUG_PRINT("\t%s:%d\n\t%s:%d\n\t%s:%d\n\t%s:%d\n\t%s:%d\n\t%s:%d\n\t%s:%d\n\t%s:%d\n\t%s:%d\n\t%s:%d\n",
00371     "vKeyAbort:                 Virtual key causing abort           ",parms.vKeyAbort,
00372     "fAbortLeftMouse:           Abort on left mouse?                ",parms.fAbortLeftMouse,
00373     "fAbortRightMouse:          Abort on right mouse?               ",parms.fAbortRightMouse,
00374     "fLimitEnabled:             Use wTimeLimit?                     ",parms.fLimitEnabled,
00375     "wTimeLimit:                Seconds to capture                  ",parms.wTimeLimit,
00376     "fMCIControl:               Use MCI video source?               ",parms.fMCIControl,
00377     "fStepMCIDevice:            Step MCI device?                    ",parms.fStepMCIDevice,
00378     "dwMCIStartTime:            Time to start in MS                 ",parms.dwMCIStartTime,
00379     "dwMCIStopTime:             Time to stop in MS                  ",parms.dwMCIStopTime,
00380     "fStepCaptureAt2x:          Perform spatial averaging 2x        ",parms.fStepCaptureAt2x
00381     );
00382     DEBUG_PRINT("\t%s:%d\n\t%s:%d\n\t%s:%d\n\t%s:%d\n",
00383     "wStepCaptureAverageFrames: Temporal average n Frames           ",parms.wStepCaptureAverageFrames,
00384     "dwAudioBufferSize:         Size of audio bufs (0 = default)    ",parms.dwAudioBufferSize,
00385     "fDisableWriteCache:        Attempt to disable write cache      ",parms.fDisableWriteCache,
00386     "AVStreamMaster:            Which stream controls length?       ",parms.AVStreamMaster
00387     );
00388     DEBUG_PRINT("};\n");
00389 }
00390 
00391 /* ---------------------------------------------------------------------- */
00392 static void print_VIDEOHDR( VIDEOHDR v )
00393 {
00394     phFUNCTION("print_VIDEOHDR")
00395     DEBUG_PRINT("\nVIDEOHDR\n{\n\t%s:%p\n\t%s:%d\n\t%s:%d\n\t%s:%d\n\t%s:%d\n\t%s:%d\n\t%s:%d\n\t%s:%d\n\t%s:%d\n\t%s:%d\n",
00396           "pointer to locked data buffer        - lpData        ",v.lpData,
00397           "Length of data buffer                - dwBufferLength",v.dwBufferLength,
00398           "Bytes actually used                  - dwBytesUsed   ",v.dwBytesUsed,
00399           "Milliseconds from start of stream    - dwTimeCaptured",v.dwTimeCaptured,
00400           "for client's use                     - dwUser        ",v.dwUser,
00401           "assorted flags (see defines)         - dwFlags       ",v.dwFlags,
00402           "reserved for driver                  - dwReserved[0] ",v.dwReserved[0],
00403           "                                     - dwReserved[1] ",v.dwReserved[1],
00404           "                                     - dwReserved[2] ",v.dwReserved[2],
00405           "                                     - dwReserved[3] ",v.dwReserved[3]);
00406     DEBUG_PRINT("\tdwFlags:\n");
00407     if (v.dwFlags  & VHDR_DONE)
00408     {
00409         DEBUG_PRINT("\t\tVHDR_DONE\n");
00410     }
00411     if (v.dwFlags  & VHDR_PREPARED)
00412     {
00413         DEBUG_PRINT("\t\tVHDR_PREPARED\n");
00414     }
00415     if (v.dwFlags  & VHDR_INQUEUE)
00416     {
00417         DEBUG_PRINT("\t\tVHDR_INQUEUE\n");
00418     }
00419     if (v.dwFlags  & VHDR_KEYFRAME)
00420     {
00421         DEBUG_PRINT("\t\tVHDR_KEYFRAME\n");
00422     }
00423     DEBUG_PRINT("};\n");
00424 }
00425 
00426 /* ---------------------------------------------------------------------- */
00427 static void print_WAVEHDR( WAVEHDR w )
00428 {
00429     phFUNCTION("print_WAVEHDR")
00430     DEBUG_PRINT("\nWAVEHDR\n{\n\t%s:%p\n\t%s:%d\n\t%s:%d\n\t%s:%d\n\t%s:%d\n\t%s:%d\n\t%s:%p\n\t%s:%d\n",
00431         "pointer to locked data buffer: lpData          ", w.lpData,
00432         "length of data buffer:         dwBufferLength  ", w.dwBufferLength,
00433         "used for input only:           dwBytesRecorded ", w.dwBytesRecorded,
00434         "for client's use:              dwUser          ", w.dwUser,
00435         "assorted flags (see defines):  dwFlags         ", w.dwFlags,
00436         "loop control counter:          dwLoops         ", w.dwLoops,
00437         "reserved for driver:           lpNext          ", w.lpNext,
00438         "reserved for driver:           reserved        ", w.reserved );
00439 
00440     if (w.dwFlags & WHDR_BEGINLOOP)
00441     {
00442         DEBUG_PRINT("WHDR_BEGINLOOP\n");
00443     }
00444     if (w.dwFlags & WHDR_DONE)
00445     {
00446         DEBUG_PRINT("WHDR_DONE\n");
00447     }
00448     if (w.dwFlags & WHDR_ENDLOOP)
00449     {
00450         DEBUG_PRINT("WHDR_ENDLOOP\n");
00451     }
00452     if (w.dwFlags & WHDR_INQUEUE)
00453     {
00454         DEBUG_PRINT("WHDR_INQUEUE\n");
00455     }
00456     if (w.dwFlags & WHDR_PREPARED)
00457     {
00458         DEBUG_PRINT("\n");
00459     }
00460 /*
00461 This buffer is the first buffer in a loop.  This flag is used only with output buffers.
00462 Set by the device driver to indicate that it is finished with the buffer and is returning it to the application.
00463 This buffer is the last buffer in a loop.  This flag is used only with output buffers.
00464 Set by Windows to indicate that the buffer is queued for playback.
00465 Set by Windows to indicate that the buffer has been prepared with the waveInPrepareHeader or waveOutPrepareHeader function.
00466 */
00467     DEBUG_PRINT("};\n");
00468 }
00469 
00470 /* ---------------------------------------------------------------------- */
00471 static void print_BITMAPINFOHEADER( BITMAPINFOHEADER b )
00472 {
00473     phFUNCTION("print_BITMAPINFOHEADER")
00474     DEBUG_PRINT("\nBITMAPINFOHEADER\n{\n\t%s:%d\n\t%s:%d\n\t%s:%d\n\t%s:%d\n\t%s:%d\n\t%s:%d\n\t%s:%d\n\t%s:%d\n\t%s:%d\n\t%s:%d\n\t%s:%d\n",
00475         "biSize",b.biSize,
00476         "biWidth",b.biWidth,
00477         "biHeight",b.biHeight,
00478         "biPlanes",b.biPlanes,
00479         "biBitCount",b.biBitCount,
00480         "biCompression",b.biCompression,
00481         "biSizeImage",b.biSizeImage,
00482         "biXPelsPerMeter",b.biXPelsPerMeter,
00483         "biYPelsPerMeter",b.biYPelsPerMeter,
00484         "biClrUsed",b.biClrUsed,
00485         "biClrImportant",b.biClrImportant);
00486 
00487     if (b.biCompression == BI_RGB)
00488     {
00489         DEBUG_PRINT("BI_RGB\n");
00490     }
00491     if (b.biCompression == BI_RLE8)
00492     {
00493         DEBUG_PRINT("BI_RLE8\n");
00494     }
00495     if (b.biCompression == BI_RLE4)
00496     {
00497         DEBUG_PRINT("BI_RLE4\n");
00498     }
00499     if (b.biCompression == BI_BITFIELDS)
00500     {
00501         DEBUG_PRINT("BI_BITFIELDS\n");
00502     }
00503     if (b.biCompression == BI_JPEG)
00504     {
00505         DEBUG_PRINT("BI_JPEG\n");
00506     }
00507     if (b.biCompression == BI_PNG)
00508     {
00509         DEBUG_PRINT("BI_PNG\n");
00510     }
00511 
00512     DEBUG_PRINT("\n};\n");
00513 }
00514 
00515 /* ---------------------------------------------------------------------- */
00516 LRESULT CALLBACK phVFWSource_WndProc( HWND hw, UINT message,
00517                                            WPARAM wp, LPARAM lp )
00518 {
00519     phFUNCTION("phVFWSource_WndProc")
00520 
00521     VFWSource *win = (VFWSource *)(uint64_t)::GetWindowLongPtr(hw,GWL_USERDATA);
00522 
00523 /*
00524     DEBUG_PRINT("hw:%p msg:%u win:%p wp:%p lp:%p\n",
00525              hw,message,win,wp,lp);
00526 */
00527     if (win != NULL)
00528     {
00529         struct phVFWHandlerParameters_t params;
00530         params.window   = hw;
00531         params.message  = message;
00532         params.wp       = wp;
00533         params.lp       = lp;
00534 
00535         return win->handle_message(&params);
00536     }
00537     else
00538     {
00539         return DefWindowProc(hw,message,wp,lp);
00540     }
00541     
00542     return 0;
00543 }
00544 /* ---------------------------------------------------------------------- */
00545 /* The HOOK idea came from:
00546  *    http://www.rpi.edu/~pudeyo/articles/wndproc/hook.cpp                */
00547 /* ---------------------------------------------------------------------- */
00548 /* The CBT hook procedure. It is called during CreateWindow call before 
00549  * WndProc receives any messages. Its job is to set per-window Window 
00550  * pointer to the one passed through lpParam to CreateWindow.             */
00551 /* ---------------------------------------------------------------------- */
00552 LRESULT CALLBACK phVFWSource_CBTProc(int code, WPARAM wp, LPARAM lp)
00553 {
00554     phFUNCTION("phVFWSource_CBTProc")
00555 
00556     LONG_PTR        ptr_rc      = NULL;
00557 
00558     if (code != HCBT_CREATEWND) 
00559     {
00560         /* Ignore everything but create window requests
00561          * Note: generally, HCBT_CREATEWND is the only notification we 
00562          * will get, assuming the thread is hooked only for the duration 
00563          * of CreateWindow call. However, we may receive other 
00564          * notifications, in which case they will not be passed to other 
00565          * CBT hooks. */
00566         return 0;
00567     }
00568     /* Grab a pointer passed to CreateWindow as lpParam */
00569     phVFW_pair_t *p = (phVFW_pair_t *)LPCBT_CREATEWND(lp)->lpcs->lpCreateParams;
00570     /* Only handle this window if it wasn't handled before, to prevent
00571      * rehooking windows when CreateWindow is called recursively */
00572     /* ie, when you create windows from a WM_CREATE handler */
00573     if (p->thisptr != NULL) 
00574     {
00575         /* Stash the associated Window pointer, which is the first member 
00576          * of the pair, into per-window data area */
00577         ::SetLastError(ERROR_SUCCESS);
00578         ptr_rc = ::SetWindowLongPtr((HWND)wp,
00579                                     GWL_USERDATA, 
00580                                     (LONG)p->thisptr);
00581         if ((ptr_rc == NULL) && (GetLastError() != ERROR_SUCCESS))
00582             rc = phFAIL; 
00583         else 
00584             rc = phSUCCESS;
00585         phPRINT_RC(rc,"SetWindowLongPtr","SetWindowLongPtr failed.");
00586 
00587         /* Mark this window as handled */
00588         p->thisptr = NULL;
00589     }
00590     /* Call the next hook in chain, using the second member of the pair */
00591     return CallNextHookEx(p->hook, code, wp, lp);
00592 }
00593 
00594 /* ---------------------------------------------------------------------- */
00595 static LRESULT CALLBACK phVFWSource_ErrorCallbackProc(HWND hWnd, int nErrID, LPSTR lpErrorText)
00596 {
00597     phFUNCTION("phVFWSource_ErrorCallbackProc")
00598 
00599     VFWSource *win = (VFWSource *)(uint64_t)::GetWindowLongPtr(hWnd,GWL_USERDATA);
00600     
00601     phPRINT("(%s) thisptr:%p hWnd:%p nErrID:%d lpErrorText:%s\n",
00602              function,win,hWnd,nErrID,lpErrorText);
00603     if (win != NULL)
00604     {
00605     }
00606     
00607     return TRUE;
00608 }
00609 
00610 /* ---------------------------------------------------------------------- */
00611 static LRESULT CALLBACK phVFWSource_StatusCallbackProc(HWND hWnd, int nID, LPSTR lpStatusText)
00612 {
00613     phFUNCTION("phVFWSource_StatusCallbackProc")
00614 
00615     VFWSource *win = (VFWSource *)(uint64_t)::GetWindowLongPtr(hWnd,GWL_USERDATA);
00616     
00617     DEBUG_PRINT("(%s) thisptr:%p hWnd:%p nID:%d lpStatusText:%s\n",
00618              function,win,hWnd,nID,lpStatusText);
00619 
00620     if (win != NULL)
00621     {
00622     }
00623     
00624     return TRUE;
00625 }
00626 
00627 /* ---------------------------------------------------------------------- */
00628 static LRESULT CALLBACK phVFWSource_ControlCallbackProc(HWND hWnd, int nState)
00629 {
00630     phFUNCTION("phVFWSource_ControlCallbackProc")
00631 
00632     VFWSource *win = (VFWSource *)(uint64_t)::GetWindowLongPtr(hWnd,GWL_USERDATA);
00633     
00634     DEBUG_PRINT("(%s) thisptr:%p hWnd:%p nState:%d\n",
00635              function,win,hWnd,nState);
00636 
00637     if (win != NULL)
00638     {
00639         switch (nState)
00640         {
00641             case CONTROLCALLBACK_PREROLL:
00642                 DEBUG_PRINT("CONTROLCALLBACK_PREROLL\n");
00643                 break;
00644             case CONTROLCALLBACK_CAPTURING:
00645                 DEBUG_PRINT("CONTROLCALLBACK_CAPTURING\n");
00646                 #if 0
00647                 /* This doesn't work yet because isRunning is set after
00648                  * the device is opened */
00649                 if (!win->isRunning())
00650                 {
00651                     return FALSE;
00652                 }
00653                 #endif
00654                 break;
00655             default:
00656                 break;
00657         }
00658     }
00659     
00660     return TRUE;
00661 }
00662 
00663 /* ---------------------------------------------------------------------- */
00664 static LRESULT CALLBACK phVFWSource_VidStreamCallbackProc(HWND hWnd, LPVIDEOHDR lpVHdr)
00665 {
00666     phFUNCTION("phVFWSource_VidStreamCallbackProc")
00667 
00668     VFWSource *win = (VFWSource *)(uint64_t)::GetWindowLongPtr(hWnd,GWL_USERDATA);
00669     VFWSource *win2 = (VFWSource *)capGetUserData(hWnd);
00670     phImage         *img        = NULL;
00671     UINT            header_size = 0;
00672     DWORD           dwSize;
00673     LPBITMAPINFO    lpbi;
00674     int32_t         f           = phImageNOFORMAT;
00675     int32_t         out_format  = (win != NULL ? win->getFormat() : phImageRGB24);
00676 
00677     uint32_t        width   = 0;
00678     uint32_t        height  = 0;
00679     uint32_t        format  = 0;
00680     uint8_t         *data   = NULL;
00681     uint32_t        size    = 0;
00682     
00683     if ((win != NULL) && (lpVHdr != NULL))
00684     {
00685         DEBUG_PRINT("(%s) wthisptr:%p cthisptr:%p hWnd:%p lpVHdr:%p\n",
00686              function,win,win2,hWnd,lpVHdr);
00687 
00688         //print_VIDEOHDR(*lpVHdr);
00689 
00690         if (!win->isRunning()) return TRUE;
00691 
00692         img = win->getImage();
00693         
00694         dwSize = capGetVideoFormatSize(hWnd);
00695         lpbi = (LPBITMAPINFO)phCalloc(1,dwSize);
00696         phPRINT_PTR(lpbi,"phCalloc","phCalloc failed.");
00697 
00698         capGetVideoFormat(hWnd, lpbi, dwSize); 
00699 
00700         DEBUG_PRINT("updating with...\n");
00701         //print_BITMAPINFOHEADER(lpbi->bmiHeader);
00702             
00703         if ((lpbi->bmiHeader.biCompression == BI_RGB) && 
00704             (lpbi->bmiHeader.biPlanes == 1) &&
00705             (lpbi->bmiHeader.biSizeImage > 0))
00706         {
00707             if (lpbi->bmiHeader.biBitCount == 24)
00708                 f = phImageBGR24;
00709             else if (lpbi->bmiHeader.biBitCount == 32)
00710                 f = phImageBGRA32;
00711 
00712             if (lpbi->bmiHeader.biHeight < 0)
00713             {
00714                 lpbi->bmiHeader.biHeight *= -1;
00715             }
00716             if (f != phImageNOFORMAT)
00717             {
00718                 if (f != out_format)
00719                 {
00720                     /* We'll disable the notify signals here so we can use 
00721                      * the phImage::convert method without having clients 
00722                      * copy the data before the convert. Then we'll call 
00723                      * the convert method and do two fake swap datas, one 
00724                      * before we re-enable notify and the other after it's 
00725                      * re-enabled so we can get the notify signal out */
00726                     img->disableNotify();
00727                     #if 0
00728                     phPRINT("VFW(%u x %u)\n",
00729                             lpbi->bmiHeader.biWidth,
00730                             lpbi->bmiHeader.biHeight );
00731                     #endif
00732                     rc = img->setImage( lpbi->bmiHeader.biWidth,
00733                                         lpbi->bmiHeader.biHeight,
00734                                         f,
00735                                         lpbi->bmiHeader.biSizeImage,
00736                                         lpVHdr->lpData);
00737                     phPRINT_RC(rc,NULL,"img->setImage");
00738 
00739                     rc = img->convert(f);
00740                     phPRINT_RC(rc,NULL,"img->convert()");
00741 
00742                     rc = img->swapData(&width,&height,&format,&data,&size);
00743                     phPRINT_RC(rc,NULL,"img->swapData");
00744 
00745                     img->enableNotify();
00746 
00747                     rc = img->swapData(&width,&height,&format,&data,&size);
00748                     phPRINT_RC(rc,NULL,"img->swapData");
00749                 }
00750                 else
00751                 {
00752                     rc = img->setImage( lpbi->bmiHeader.biWidth,
00753                                         lpbi->bmiHeader.biHeight,
00754                                         f,
00755                                         lpbi->bmiHeader.biSizeImage,
00756                                         lpVHdr->lpData);
00757                     phPRINT_RC(rc,NULL,"img->setImage");
00758                 }
00759             }
00760         }
00761         
00762         phFree(lpbi);
00763     }
00764     return TRUE;
00765 }
00766 
00767 /* ---------------------------------------------------------------------- */
00768 static LRESULT CALLBACK phVFWSource_FrameCallbackProc(HWND hWnd, LPVIDEOHDR lpVHdr)
00769 {
00770     phFUNCTION("phVFWSource_FrameCallbackProc")
00771 
00772     VFWSource *win = (VFWSource *)(uint64_t)::GetWindowLongPtr(hWnd,GWL_USERDATA);
00773     VFWSource *win2 = (VFWSource *)capGetUserData(hWnd);
00774     
00775     if ((win != NULL) && (lpVHdr != NULL))
00776     {
00777         DEBUG_PRINT("(%s) wthisptr:%p cthisptr:%p hWnd:%p lpVHdr:%p\n",
00778              function,win,win2,hWnd,lpVHdr);
00779 
00780         //print_VIDEOHDR(*lpVHdr);
00781     }
00782     
00783     return TRUE;
00784 }
00785 
00786 /* ---------------------------------------------------------------------- */
00787 static LRESULT CALLBACK phVFWSource_WaveStreamCallbackProc( HWND hWnd, LPWAVEHDR lpWHdr )
00788 {
00789     phFUNCTION("phVFWSource_WaveStreamFrameCallbackProc")
00790 
00791     VFWSource *win = (VFWSource *)(uint64_t)::GetWindowLongPtr(hWnd,GWL_USERDATA);
00792     VFWSource *win2 = (VFWSource *)capGetUserData(hWnd);
00793     
00794     if ((win != NULL) && (lpWHdr != NULL))
00795     {
00796         DEBUG_PRINT("(%s) wthisptr:%p cthisptr:%p hWnd:%p lpWHdr:%p\n",
00797              function,win,win2,hWnd,lpWHdr);
00798 
00799         //print_WAVEHDR(*lpWHdr);
00800     }
00801     
00802     return TRUE;
00803 }
00804 /* ---------------------------------------------------------------------- */
00805 VFWSource::VFWSource(char *path)
00806 {
00807     phFUNCTION("VFWSource::VFWSource")
00808     
00809     rc = this->lock();
00810     phPRINT_RC(rc,NULL,"this->lock()");
00811    
00812     this->setName("VFWSource");
00813     
00814     if (path != NULL)
00815     {
00816         this->setPath(path);
00817     }
00818     else
00819     {
00820         this->setPath("0");
00821     }
00822 
00823     this->m_info                = NULL;
00824     this->m_show_first          = 0;
00825     this->m_image_size          = 0;
00826     this->m_private_format      = this->m_format;
00827     this->m_channel             = 0;
00828     this->m_changed_settings    = 0;
00829     this->m_changed_channel     = 0;
00830 
00831     /* This applies the default (1) picture/image settings[w,h,format,etc.]
00832      * (2) channel settings  */
00833     this->applySettings();
00834     
00835     /* opening the device must be explicitly done */
00836     /* capturing must be explicitly done. */
00837 #if 0
00838 error:
00839 #endif
00840     rc = this->unlock();
00841     phPRINT_RC(rc,NULL,"this->unlock()");
00842     
00843     return;
00844 }
00845 
00846 /* ---------------------------------------------------------------------- */
00847 VFWSource::~VFWSource ()
00848 {
00849     phFUNCTION("VFWSource::~VFWSource")
00850   
00851     rc = this->lock();
00852     phPRINT_RC(rc,NULL,"this->lock()");
00853 
00854     if (this->isRunning())
00855     {
00856         /* this unmaps the hw_buffer and closes the device */
00857         rc = this->stop();
00858         phPRINT_RC(rc,NULL,"this->stop()");
00859     }
00860    
00861     if (this->isOpen())
00862     {
00863         rc = this->close();
00864         phPRINT_RC(rc,NULL,"this->close()");
00865     }
00866     
00867     rc = this->unlock();
00868     phPRINT_RC(rc,NULL,"this->unlock()");
00869 }
00870     
00871 /* ---------------------------------------------------------------------- */
00872 int VFWSource::init_window()
00873 {
00874     phFUNCTION("VFWSource::init_window")
00875     int             locked      = 0;
00876     ATOM            arc         = 0;
00877     BOOL            brc         = FALSE;
00878     HHOOK           hook;
00879     phVFW_pair_t    pair;
00880     RECT            rect;
00881     LONG_PTR        ptr_rc      = NULL;
00882     
00883     phTHIS_LOCK(locked);
00884 
00885     if (this->m_info != NULL) goto error;
00886     
00887     this->m_info = (struct phVFWWindowInfo_t *)phCalloc(1,sizeof(struct phVFWWindowInfo_t));
00888     phPRINT_PTR(this->m_info,"phCalloc","phCalloc failed for m_info");
00889 
00890     this->m_info->device = -1;
00891     
00892     this->m_info->window_class_name = (wchar_t *)phCalloc(255,sizeof(wchar_t));
00893     phPRINT_PTR(this->m_info->window_class_name,"phCalloc",
00894               "phCalloc failed.");
00895                                   
00896     wsprintf(this->m_info->window_class_name,
00897              L"VFWSource%u%p",
00898              (unsigned int)phGetCurrentThreadId(),
00899              this);
00900     
00901     /* Create Window */
00902     this->m_info->module            = ::GetModuleHandle(NULL);
00903     this->m_info->instance          = (HINSTANCE)this->m_info->module;
00904     this->m_info->command_line      = GetCommandLine();
00905     GetStartupInfo(&(this->m_info->startup_info));
00906 
00907     /* Register the main window class. */
00908     this->m_info->window_class.style           = CS_OWNDC | CS_HREDRAW | CS_VREDRAW; 
00909     this->m_info->window_class.lpfnWndProc     = (WNDPROC)phVFWSource_WndProc; 
00910     this->m_info->window_class.cbClsExtra      = 0; 
00911     this->m_info->window_class.cbWndExtra      = sizeof(VFWSource *); 
00912     this->m_info->window_class.hInstance       = this->m_info->instance; 
00913     this->m_info->window_class.hIcon           = ::LoadIcon  (NULL, IDI_APPLICATION); 
00914     this->m_info->window_class.hCursor         = ::LoadCursor(NULL, IDC_ARROW); 
00915     this->m_info->window_class.hbrBackground   = (HBRUSH)(COLOR_WINDOW+1);//(COLOR_BACKGROUND);
00916     this->m_info->window_class.lpszMenuName    = NULL;
00917     this->m_info->window_class.lpszClassName   = (LPCWSTR)this->m_info->window_class_name;
00918  
00919     this->m_info->window_atom = arc = ::RegisterClass(&(this->m_info->window_class));
00920     if (arc == 0) rc = phFAIL; else rc = phSUCCESS;
00921     phPRINT_RC(rc,"RegisterClass","RegisterClass failed.");
00922     
00923     /* Setup the hooks */
00924     hook = SetWindowsHookEx(WH_CBT, phVFWSource_CBTProc, 0, GetCurrentThreadId());
00925     pair.thisptr    = this;
00926     pair.hook       = hook;
00927     
00928     SetLastError(ERROR_SUCCESS);
00929 
00930     this->m_info->window = ::CreateWindowEx(0,
00931                                         (LPCWSTR)this->m_info->window_class_name,
00932                                         (LPCWSTR)"VFWSource capture stuff",
00933                                         WS_BORDER | 
00934                                         WS_THICKFRAME | 
00935                                         WS_CAPTION | 
00936                                         WS_MINIMIZEBOX | 
00937                                         WS_MAXIMIZEBOX | 
00938                                         WS_SYSMENU,
00939                                         CW_USEDEFAULT,CW_USEDEFAULT,
00940                                         this->m_width,this->m_height,
00941                                         NULL,
00942                                         NULL,
00943                                         this->m_info->instance,
00944                                         &pair);
00945     phPRINT_PTR(this->m_info->window,"CreateWindow","CreateWindow failed.");
00946 
00947     /* Disable the hooks */
00948     UnhookWindowsHookEx(hook);
00949  
00950     /*
00951     DEBUG_PRINT("CreateWindowEx\n");
00952     print_window_info(this->m_info->window);
00953     DEBUG_PRINT("\n");
00954      */
00955 
00956     /* Make sure the client area is sized correctly */
00957     GetClientRect( this->m_info->window, &rect );
00958 
00959     MoveWindow(this->m_info->window,
00960                10,10,
00961                this->m_width + (this->m_width - (rect.right  -rect.left)),
00962                this->m_height + (this->m_height - (rect.bottom - rect.top)),
00963                FALSE);
00964 
00965     this->m_show_first = 1;
00966         
00967     this->m_info->capwin = capCreateCaptureWindow ((LPCWSTR) "My Capture Window",
00968                                                 WS_CHILD | WS_VISIBLE,
00969                                                 0, 0, this->m_width, this->m_height,
00970                                                 (HWND)this->m_info->window, 
00971                                                 (int) 10); 
00972     phPRINT_PTR(this->m_info->capwin,"capCreateCaptureWindow",
00973                 "capCreateCaptureWindow failed.");
00974     
00975     ::SetLastError(ERROR_SUCCESS);
00976     ptr_rc = ::SetWindowLongPtr((HWND)this->m_info->capwin,GWL_USERDATA,(LONG32)this);
00977     if ((ptr_rc == NULL) && (GetLastError() != ERROR_SUCCESS))
00978         rc = phFAIL; 
00979     else 
00980         rc = phSUCCESS;
00981     phPRINT_RC(rc,"SetWindowLongPtr","SetWindowLongPtr failed.");
00982 
00983     capSetUserData(this->m_info->capwin,this);
00984 
00985 error:
00986     phTHIS_ERROR_UNLOCK(locked);
00987     return phSUCCESS;
00988 }
00989 
00990 /* ---------------------------------------------------------------------- */
00991 int VFWSource::destroy_window()
00992 {
00993     phFUNCTION("VFWSource::destroy_window")
00994     BOOL brc = TRUE;
00995     int locked = 0;
00996     
00997     phTHIS_LOCK(locked);
00998     
00999     if (this->m_info != NULL)
01000     {    
01001         rc = this->disconnect_device();
01002         phPRINT_RC(rc,NULL,"disconnect_device");
01003 
01004         rc = this->remove_callbacks();
01005         phPRINT_RC(rc,NULL,"remove_callbacks");
01006 
01007         brc = DestroyWindow(this->m_info->capwin);
01008         if (brc == 0) rc = phFAIL; else rc = phSUCCESS;
01009         phPRINT_RC(rc,"DestroyWindow","DestroyWindow failed (0x%08x).",brc);
01010         
01011         brc = DestroyWindow(this->m_info->window);
01012         if (brc == 0) rc = phFAIL; else rc = phSUCCESS;
01013         phPRINT_RC(rc,"DestroyWindow","DestroyWindow failed (0x%08x).",brc);
01014     
01015         brc = UnregisterClass((LPCWSTR)this->m_info->window_class_name,
01016                               this->m_info->instance);
01017         if (brc == 0) rc = phFAIL; else rc = phSUCCESS;
01018         phPRINT_RC(rc,"UnregisterClass","UnregisterClass failed (0x%08x)",brc);
01019 
01020         phFree(this->m_info->window_class_name);
01021         phFree(this->m_info->d_lpbi);
01022         phFree(this->m_info);
01023     }
01024     
01025     phTHIS_UNLOCK(locked);
01026     
01027     return phSUCCESS;
01028 error:
01029     phTHIS_ERROR_UNLOCK(locked);
01030 
01031     return phFAIL;
01032 }
01033 
01034 /* ---------------------------------------------------------------------- */
01035 int64_t VFWSource::handle_message( phVFWHandlerParameters params )
01036 {
01037     phFUNCTION("VFWSource::handle_message")
01038     int     locked  = 0;
01039     LRESULT retrc   = 0;
01040     HWND    hw      = params->window;
01041     UINT    message = params->message;
01042     WPARAM  wp      = params->wp;
01043     LPARAM  lp      = params->lp;
01044     int     message_handled = 0;
01045     int     close_window    = 0;
01046 
01047     phTHIS_LOCK(locked);
01048     /* http://msdn.microsoft.com/library/default.asp?url=/library/en-us/
01049             winui/winui/windowsuserinterface/windowing/windows/
01050             windowreference/windowmessages/wm_size.asp
01051      */
01052     switch (message)
01053     {
01054         case WM_DESTROY:
01055             /*phPROGRESS("WM_DESTROY\n");*/
01056             close_window = 1;
01057             break;
01058             
01059         case WM_CLOSE:
01060             /*phPROGRESS("WM_CLOSE\n");*/
01061             close_window = 1;
01062             break;
01063             
01064         case WM_CHAR:
01065             DEBUG_PRINT("WM_CHAR\n");
01066             /* if key pressed is ESC/Q/q then close the window */
01067             if ((wp == 27) || (wp == 'q') || (wp == 'Q'))
01068             {
01069                 message_handled = close_window = 1;
01070             }
01071             break;
01072 
01073         case WM_ACTIVATE:
01074         {
01075             /* activation flag */
01076             int fActive = LOWORD(wp);
01077             /* minimized flag */
01078             BOOL fMinimized = (BOOL) HIWORD(wp);
01079             /* window handle */
01080             HWND hwndPrevious = (HWND) lp;
01081 
01082             DEBUG_PRINT("WM_ACTIVATE(%d,%d,%d)\n",fActive,fMinimized,hwndPrevious);
01083         }
01084         case WM_PAINT:
01085         {
01086             DEBUG_PRINT("WM_PAINT\n");
01087         }
01088             break;
01089         case WM_USER_REDRAW:
01090         {
01091             DEBUG_PRINT("WM_USER_REDRAW\n");
01092         }
01093             break;
01094         case WM_USER_UPDATE:
01095         {
01096             DEBUG_PRINT("WM_UPDATE\n");
01097         }
01098             break;
01099 
01100         case WM_USER_MOVE:
01101         {
01102             int32_t xPos = (int32_t)(short) LOWORD(lp);
01103             int32_t yPos = (int32_t)(short) HIWORD(lp);
01104             DEBUG_PRINT("WM_USER_MOVE(%d,%d)\n",xPos,yPos);
01105         }
01106             break;
01107         case WM_USER_RESIZE:
01108         {
01109             #if 0
01110             uint32_t width   = (uint32_t)(short) LOWORD(lp);
01111             uint32_t height  = (uint32_t)(short) HIWORD(lp);
01112             DEBUG_PRINT("WM_USER_RESIZE(%u,%u)\n",width,height);
01113             RECT rect;
01114             
01115             GetClientRect( this->m_info->window, &rect );
01116             //print_RECT(rect);
01117             DEBUG_PRINT("\n");
01118             #endif
01119         }
01120             break;
01121         case WM_USER_SHOW:
01122         {
01123             DEBUG_PRINT("WM_USER_SHOW\n");
01124         }
01125             break;
01126         case WM_USER_HIDE:
01127         {
01128             DEBUG_PRINT("WM_USER_HIDE\n");
01129         }
01130             break;
01131         
01132         case WM_CREATE:
01133         {
01134             /* structure with creation data */
01135             LPCREATESTRUCT lpcs = (LPCREATESTRUCT) lp;
01136         
01137             DEBUG_PRINT("WM_CREATE");
01138             //print_CREATESTRUCT(*lpcs);
01139             DEBUG_PRINT("\n");
01140         }
01141             break;
01142         case WM_KEYDOWN:
01143             DEBUG_PRINT("WM_KEYDOWN\n");
01144             break;
01145         case WM_KEYUP:
01146             DEBUG_PRINT("WM_KEYUP\n");
01147             break;
01148         case WM_SYSKEYDOWN:
01149             DEBUG_PRINT("WM_SYSKEYDOWN\n");
01150             break;
01151         case WM_SYSKEYUP:
01152             DEBUG_PRINT("WM_SYSKEYUP\n");
01153             break;
01154         case WM_ACTIVATEAPP:
01155         {
01156             /* activation flag */
01157             BOOL fActive = (BOOL) wp;
01158             /* thread identifier */
01159             DWORD dwThreadId = (DWORD) lp;
01160             DEBUG_PRINT("WM_ACTIVATEAPP(%d,%ld)\n",fActive,dwThreadId);
01161         }
01162             break;
01163         case WM_SHOWWINDOW:
01164         {
01165             DEBUG_PRINT("WM_SHOWWINDOW\n");
01166         }
01167             break;
01168         case WM_CANCELMODE:
01169             DEBUG_PRINT("WM_CANCELMODE\n");
01170             break;
01171         case WM_CHILDACTIVATE:
01172         {
01173             DEBUG_PRINT("WM_CHILDACTIVATE\n");
01174         }
01175             break;
01176         case WM_COMPACTING:
01177         {
01178             /* compacting ratio */
01179             WPARAM wCompactRatio = wp;
01180             DEBUG_PRINT("WM_COMPACTING(0x%08x)\n",wCompactRatio);
01181         }
01182             break;
01183         case WM_ENABLE:
01184         {
01185             /* enabled/disabled flag */
01186             BOOL fEnabled = (BOOL) wp;
01187             DEBUG_PRINT("WM_ENABLE(%d)\n",fEnabled);
01188         }
01189             break;
01190         case WM_ENTERSIZEMOVE:
01191             DEBUG_PRINT("WM_ENTERSIZEMOVE\n");
01192             break;
01193         case WM_EXITSIZEMOVE:
01194             DEBUG_PRINT("WM_EXITSIZEMOVE\n");
01195             break;
01196         case WM_GETICON:
01197         {
01198             WPARAM fType = wp;
01199             DEBUG_PRINT("WM_GETICON");
01200             DEBUG_PRINT("%s\n",(fType == ICON_BIG ? " ICON_BIG" : " ICON_SMALL"));
01201         }
01202             break;
01203         case WM_GETMINMAXINFO:
01204         {
01205             LPMINMAXINFO lpmmi = (LPMINMAXINFO) lp;
01206             DEBUG_PRINT("WM_GETMINMAXINFO");
01207             //print_MINMAXINFO(*lpmmi);
01208             DEBUG_PRINT("\n");
01209         }
01210             break;
01211         case WM_INPUTLANGCHANGE:
01212             DEBUG_PRINT("WM_INPUTLANGCHANGE\n");
01213             break;
01214         case WM_INPUTLANGCHANGEREQUEST:
01215             DEBUG_PRINT("WM_INPUTLANGCHANGEREQUEST\n");
01216             break;
01217         case WM_MOVE:
01218         {
01219             #if 0
01220             int32_t xPos = (int32_t)(short) LOWORD(lp);
01221             int32_t yPos = (int32_t)(short) HIWORD(lp);
01222             RECT rect;
01223             
01224             GetWindowRect( this->m_info->window, &rect );
01225             
01226             DEBUG_PRINT("WM_MOVE(%d,%d)(%d,%d)\n",
01227                       xPos,yPos,rect.left,rect.top);
01228 #endif
01229         }    
01230             break;
01231         case WM_MOVING:
01232         {
01233             /* edge of window to be moved */
01234             WPARAM fwSide = wp;
01235             /* screen coordinates of drag rectangle */
01236             LPRECT lprc = (LPRECT) lp;
01237         
01238             /*
01239             DEBUG_PRINT("WM_MOVING");
01240             print_RECT(*lprc);
01241             print_SIDE(fwSide);
01242             DEBUG_PRINT("\n");
01243             if (this->m_info->window != NULL)
01244             {
01245                 print_window_info(this->m_info->window);
01246             }
01247             */
01248         }
01249             break;
01250         case WM_NCACTIVATE:
01251         {
01252             DEBUG_PRINT("WM_NCACTIVATE\n");
01253         }
01254             break;
01255         case WM_NCCALCSIZE:
01256         {
01257             /* valid area flag */
01258             BOOL fCalcValidRects = (BOOL) wp;
01259 
01260             DEBUG_PRINT("WM_NCCALCSIZE");
01261             if (fCalcValidRects )
01262             {
01263                 /* size calculation data */
01264                 LPNCCALCSIZE_PARAMS lpncsp = (LPNCCALCSIZE_PARAMS)lp;
01265                 for (int i = 0; i < 3; i++ ) print_RECT(lpncsp->rgrc[i]);
01266                 //print_WINDOWPOS(*(lpncsp->lppos));
01267             }
01268             else
01269             {
01270                 /* new window coordinates */
01271                 LPRECT lpncsp = (LPRECT) lp;
01272                 //print_RECT(*lpncsp);
01273             }
01274             DEBUG_PRINT("\n");
01275             /*
01276             if (this->m_info->window != NULL)
01277             {
01278                 print_window_info(this->m_info->window);
01279             }
01280             */
01281         }
01282             break;
01283         case WM_NCCREATE:
01284             DEBUG_PRINT("WM_NCCREATE\n");
01285             break;
01286         case WM_NCDESTROY:
01287             DEBUG_PRINT("WM_NCDESTROY\n");
01288             break;
01289         case WM_NULL:
01290             DEBUG_PRINT("WM_NULL\n");
01291             break;
01292         case WM_PARENTNOTIFY:
01293             DEBUG_PRINT("WM_PARENTNOTIFY\n");
01294             break;
01295         case WM_QUERYDRAGICON:
01296             DEBUG_PRINT("WM_QUERYDRAGICON\n");
01297             break;
01298         case WM_QUERYOPEN:
01299             DEBUG_PRINT("WM_QUERYOPEN\n");
01300             break;
01301         case WM_SIZE:
01302         {
01303             RECT rect;
01304             uint32_t width = 0;
01305             uint32_t height = 0;
01306 #if 0 
01307             GetWindowRect( this->m_info->window, &rect );
01308 #else
01309             ::GetClientRect( this->m_info->window, &rect );
01310 #endif
01311             if ((this->m_info != NULL) && 
01312                 (this->m_info->window != NULL) &&
01313                 (this->m_info->capwin != NULL))
01314             {
01315                 ::SetWindowPos(this->m_info->capwin, NULL, 
01316                                0, 0, 
01317                                rect.right, rect.bottom,
01318                                SWP_NOZORDER | SWP_NOMOVE);
01319             }    
01320             width = rect.right - rect.left;
01321             height = rect.bottom - rect.top;
01322             DEBUG_PRINT("WM_SIZE(%u,%u)\n", width,height);
01323         }    
01324             break;
01325         case WM_SIZING:
01326         {
01327             int32_t width = 0;
01328             int32_t height= 0;
01329             /* edge of window to be moved */
01330             WPARAM fwSide = wp;
01331             /* screen coordinates of drag rectangle */
01332             LPRECT lprc = (LPRECT) lp;
01333         
01334             /*
01335             DEBUG_PRINT("WM_SIZING");
01336             print_RECT(*lprc);
01337             print_SIDE(fwSide);
01338             DEBUG_PRINT("\n");
01339             */
01340         }
01341             break;
01342         case WM_STYLECHANGED:
01343             DEBUG_PRINT("WM_STYLECHANGED\n");
01344             break;
01345         case WM_STYLECHANGING:
01346             DEBUG_PRINT("WM_STYLECHANGING\n");
01347             break;
01348         case WM_USERCHANGED:
01349             DEBUG_PRINT("WM_USERCHANGED\n");
01350             break;
01351         case WM_WINDOWPOSCHANGED:
01352         {
01353             LPWINDOWPOS lpwp = (LPWINDOWPOS)lp;
01354             DEBUG_PRINT("WM_WINDOWPOSCHANGED");
01355             //print_WINDOWPOS(*lpwp);
01356             DEBUG_PRINT("\n");
01357         }
01358             break;
01359         case WM_WINDOWPOSCHANGING:
01360         {
01361             LPWINDOWPOS lpwp = (LPWINDOWPOS)lp;
01362             DEBUG_PRINT("WM_WINDOWPOSCHANGING");
01363             //print_WINDOWPOS(*lpwp);
01364             DEBUG_PRINT("\n");
01365         }
01366             break;
01367         case WM_CAP_ABORT: DEBUG_PRINT("WM_CAP_ABORT\n"); break;
01368         case WM_CAP_DLG_VIDEOCOMPRESSION: DEBUG_PRINT("WM_CAP_DLG_VIDEOCOMPRESSION\n"); break;
01369         case WM_CAP_DLG_VIDEODISPLAY: DEBUG_PRINT("WM_CAP_DLG_VIDEODISPLAY\n"); break;
01370         case WM_CAP_DLG_VIDEOFORMAT: DEBUG_PRINT("WM_CAP_DLG_VIDEOFORMAT\n"); break;
01371         case WM_CAP_DLG_VIDEOSOURCE: DEBUG_PRINT("WM_CAP_DLG_VIDEOSOURCE\n"); break;
01372         case WM_CAP_DRIVER_CONNECT: DEBUG_PRINT("WM_CAP_DRIVER_CONNECT\n"); break;
01373         case WM_CAP_DRIVER_DISCONNECT: DEBUG_PRINT("WM_CAP_DRIVER_DISCONNECT\n"); break;
01374         case WM_CAP_DRIVER_GET_CAPS: DEBUG_PRINT("WM_CAP_DRIVER_GET_CAPS\n"); break;
01375         case WM_CAP_DRIVER_GET_NAME: DEBUG_PRINT("WM_CAP_DRIVER_GET_NAME\n"); break;
01376         case WM_CAP_DRIVER_GET_VERSION: DEBUG_PRINT("WM_CAP_DRIVER_GET_VERSION\n"); break;
01377         case WM_CAP_EDIT_COPY: DEBUG_PRINT("WM_CAP_EDIT_COPY\n"); break;
01378         case WM_CAP_FILE_ALLOCATE: DEBUG_PRINT("WM_CAP_FILE_ALLOCATE\n"); break;
01379         case WM_CAP_FILE_GET_CAPTURE_FILE: DEBUG_PRINT("WM_CAP_FILE_GET_CAPTURE_FILE\n"); break;
01380         case WM_CAP_FILE_SAVEAS: DEBUG_PRINT("WM_CAP_FILE_SAVEAS\n"); break;
01381         case WM_CAP_FILE_SAVEDIB: DEBUG_PRINT("WM_CAP_FILE_SAVEDIB\n"); break;
01382         case WM_CAP_FILE_SET_CAPTURE_FILE: DEBUG_PRINT("WM_CAP_FILE_SET_CAPTURE_FILE\n"); break;
01383         case WM_CAP_FILE_SET_INFOCHUNK: DEBUG_PRINT("WM_CAP_FILE_SET_INFOCHUNK\n"); break;
01384         case WM_CAP_GET_AUDIOFORMAT: DEBUG_PRINT("WM_CAP_GET_AUDIOFORMAT\n"); break;
01385         case WM_CAP_GET_MCI_DEVICE: DEBUG_PRINT("WM_CAP_GET_MCI_DEVICE\n"); break;
01386         case WM_CAP_GET_SEQUENCE_SETUP: DEBUG_PRINT("WM_CAP_GET_SEQUENCE_SETUP\n"); break;
01387         case WM_CAP_GET_STATUS: DEBUG_PRINT("WM_CAP_GET_STATUS\n"); break;
01388         case WM_CAP_GET_USER_DATA: DEBUG_PRINT("WM_CAP_GET_USER_DATA\n"); break;
01389         case WM_CAP_GET_VIDEOFORMAT: DEBUG_PRINT("WM_CAP_GET_VIDEOFORMAT\n"); break;
01390         case WM_CAP_GRAB_FRAME: DEBUG_PRINT("WM_CAP_GRAB_FRAME\n"); break;
01391         case WM_CAP_GRAB_FRAME_NOSTOP: DEBUG_PRINT("WM_CAP_GRAB_FRAME_NOSTOP\n"); break;
01392         case WM_CAP_PAL_AUTOCREATE: DEBUG_PRINT("WM_CAP_PAL_AUTOCREATE\n"); break;
01393         case WM_CAP_PAL_MANUALCREATE: DEBUG_PRINT("WM_CAP_PAL_MANUALCREATE\n"); break;
01394         case WM_CAP_PAL_OPEN: DEBUG_PRINT("WM_CAP_PAL_OPEN\n"); break;
01395         case WM_CAP_PAL_PASTE: DEBUG_PRINT("WM_CAP_PAL_PASTE\n"); break;
01396         case WM_CAP_PAL_SAVE: DEBUG_PRINT("WM_CAP_PAL_SAVE\n"); break;
01397         case WM_CAP_SEQUENCE: DEBUG_PRINT("WM_CAP_SEQUENCE\n"); break;
01398         case WM_CAP_SEQUENCE_NOFILE: DEBUG_PRINT("WM_CAP_SEQUENCE_NOFILE\n"); break;
01399         case WM_CAP_SET_AUDIOFORMAT: DEBUG_PRINT("WM_CAP_SET_AUDIOFORMAT\n"); break;
01400         case WM_CAP_SET_CALLBACK_CAPCONTROL: DEBUG_PRINT("WM_CAP_SET_CALLBACK_CAPCONTROL\n"); break;
01401         case WM_CAP_SET_CALLBACK_ERROR: DEBUG_PRINT("WM_CAP_SET_CALLBACK_ERROR\n"); break;
01402         case WM_CAP_SET_CALLBACK_FRAME: DEBUG_PRINT("WM_CAP_SET_CALLBACK_FRAME\n"); break;
01403         case WM_CAP_SET_CALLBACK_STATUS: DEBUG_PRINT("WM_CAP_SET_CALLBACK_STATUS\n"); break;
01404         case WM_CAP_SET_CALLBACK_VIDEOSTREAM: DEBUG_PRINT("WM_CAP_SET_CALLBACK_VIDEOSTREAM\n"); break;
01405         case WM_CAP_SET_CALLBACK_WAVESTREAM: DEBUG_PRINT("WM_CAP_SET_CALLBACK_WAVESTREAM\n"); break;
01406         case WM_CAP_SET_CALLBACK_YIELD: DEBUG_PRINT("WM_CAP_SET_CALLBACK_YIELD\n"); break;
01407         case WM_CAP_SET_MCI_DEVICE: DEBUG_PRINT("WM_CAP_SET_MCI_DEVICE\n"); break;
01408         case WM_CAP_SET_OVERLAY: DEBUG_PRINT("WM_CAP_SET_OVERLAY\n"); break;
01409         case WM_CAP_SET_PREVIEW: DEBUG_PRINT("WM_CAP_SET_PREVIEW\n"); break;
01410         case WM_CAP_SET_PREVIEWRATE: DEBUG_PRINT("WM_CAP_SET_PREVIEWRATE\n"); break;
01411         case WM_CAP_SET_SCALE: DEBUG_PRINT("WM_CAP_SET_SCALE\n"); break;
01412         case WM_CAP_SET_SCROLL: DEBUG_PRINT("WM_CAP_SET_SCROLL\n"); break;
01413         case WM_CAP_SET_SEQUENCE_SETUP: DEBUG_PRINT("WM_CAP_SET_SEQUENCE_SETUP\n"); break;
01414         case WM_CAP_SET_USER_DATA: DEBUG_PRINT("WM_CAP_SET_USER_DATA\n"); break;
01415         case WM_CAP_SET_VIDEOFORMAT: DEBUG_PRINT("WM_CAP_SET_VIDEOFORMAT\n"); break;
01416         case WM_CAP_SINGLE_FRAME: DEBUG_PRINT("WM_CAP_SINGLE_FRAME\n"); break;
01417         case WM_CAP_SINGLE_FRAME_CLOSE: DEBUG_PRINT("WM_CAP_SINGLE_FRAME_CLOSE\n"); break;
01418         case WM_CAP_SINGLE_FRAME_OPEN: DEBUG_PRINT("WM_CAP_SINGLE_FRAME_OPEN\n"); break;
01419         case WM_CAP_STOP: DEBUG_PRINT("WM_CAP_STOP\n"); break;
01420 
01421         default:
01422             break;
01423     }
01424 
01425     if (close_window)
01426     {
01427 
01428         this->setRunning(0);
01429         this->wakeup();
01430         message_handled = 1;
01431     }
01432 
01433     if (message_handled != 1)
01434     {
01435         DEBUG_PRINT("DefWindowProc(wnd:%d msg:%u wp:%d lp:%d)\n",hw,message,wp,lp);
01436         retrc = DefWindowProc(hw,message,wp,lp);
01437     }
01438 
01439     phTHIS_UNLOCK(locked);
01440 
01441     return retrc;
01442 error:
01443     phTHIS_ERROR_UNLOCK(locked);
01444 
01445     return phFAIL;
01446 }
01447 
01448 /* ---------------------------------------------------------------------- */
01449 int VFWSource::set_callbacks()
01450 {
01451     phFUNCTION("VFWSource::set_callbacks")
01452     BOOL    brc;
01453     int     locked = 0;
01454     
01455     phTHIS_LOCK(locked);
01456 
01457     if ((this->m_info != NULL) && 
01458         (this->m_info->capwin != NULL) &&
01459         (this->m_info->window != NULL))
01460     {
01461         /* Set all the callbacks */
01462         brc = capSetCallbackOnError   (this->m_info->capwin,  
01463                                        phVFWSource_ErrorCallbackProc); 
01464         if (brc == 0) rc = phFAIL; else rc = phSUCCESS;
01465         phPRINT_RC(rc,"capSetCallbackOnError","capSetCallbackOnError failed (0x%08x).",brc);
01466 
01467         brc = capSetCallbackOnStatus  (this->m_info->capwin, 
01468                                        phVFWSource_StatusCallbackProc); 
01469         if (brc == 0) rc = phFAIL; else rc = phSUCCESS;
01470         phPRINT_RC(rc,"capSetCallbackOnStatus","capSetCallbackOnStatus failed (0x%08x).",brc);
01471 
01472         brc = capSetCallbackOnCapControl(this->m_info->capwin, 
01473                                          phVFWSource_ControlCallbackProc); 
01474         if (brc == 0) rc = phFAIL; else rc = phSUCCESS;
01475         phPRINT_RC(rc,"capSetCallbackOnCapControl","capSetCallbackOnCapControl failed (0x%08x).",brc);
01476 
01477         brc = capSetCallbackOnVideoStream(this->m_info->capwin, 
01478                                           phVFWSource_VidStreamCallbackProc); 
01479         if (brc == 0) rc = phFAIL; else rc = phSUCCESS;
01480         phPRINT_RC(rc,"capSetCallbackOnVideoStream","capSetCallbackOnVideoStream failed (0x%08x).",brc);
01481 
01482         brc = capSetCallbackOnFrame(this->m_info->capwin, 
01483                                     phVFWSource_FrameCallbackProc); 
01484         if (brc == 0) rc = phFAIL; else rc = phSUCCESS;
01485         phPRINT_RC(rc,"capSetCallbackOnFrame","capSetCallbackOnFrame failed (0x%08x).",brc);
01486 
01487         brc = capSetCallbackOnWaveStream(this->m_info->capwin, 
01488                                          phVFWSource_WaveStreamCallbackProc); 
01489         if (brc == 0) rc = phFAIL; else rc = phSUCCESS;
01490         phPRINT_RC(rc,"capSetCallbackOnWaveStream","capSetCallbackOnWaveStream failed (0x%08x).",brc);
01491     }    
01492 
01493     phTHIS_UNLOCK(locked);
01494 
01495     return phSUCCESS;
01496 error:
01497     phTHIS_ERROR_UNLOCK(locked);
01498 
01499     return phSUCCESS;
01500 }
01501 
01502 /* ---------------------------------------------------------------------- */
01503 int VFWSource::remove_callbacks()
01504 {
01505     phFUNCTION("VFWSource::remove_callbacks")
01506     
01507     BOOL    brc;
01508     int     locked = 0;
01509 
01510     phTHIS_LOCK(locked);
01511 
01512     if ((this->m_info != NULL) && 
01513         (this->m_info->capwin != NULL) &&
01514         (this->m_info->window != NULL))
01515     {
01516         brc = capSetCallbackOnError         (this->m_info->capwin, NULL);
01517         brc = capSetCallbackOnStatus        (this->m_info->capwin, NULL);
01518         brc = capSetCallbackOnCapControl    (this->m_info->capwin, NULL);
01519         brc = capSetCallbackOnVideoStream   (this->m_info->capwin, NULL);
01520         brc = capSetCallbackOnFrame         (this->m_info->capwin, NULL);
01521     }    
01522 
01523     phTHIS_UNLOCK(locked);
01524 
01525     return phSUCCESS;
01526 error:
01527     phTHIS_ERROR_UNLOCK(locked);
01528 
01529     return phSUCCESS;
01530 }
01531 
01532 /* ---------------------------------------------------------------------- */
01533 int VFWSource::list_devices()
01534 {
01535     phFUNCTION("VFWSource::list_devices")
01536     
01537     BOOL        brc;
01538     int         locked = 0;
01539     int         i   = 0;
01540     wchar_t     szDeviceName[80];
01541     wchar_t     szDeviceVersion[80];
01542     int         count = 0;
01543 
01544     phTHIS_LOCK(locked);
01545 
01546     for (i = 0; i < 10; i++) 
01547     {
01548         brc = capGetDriverDescription  (i, 
01549                 (LPWSTR)szDeviceName, 
01550                 sizeof (szDeviceName), 
01551                 (LPWSTR)szDeviceVersion, 
01552                 sizeof (szDeviceVersion));
01553         if (brc)
01554         {
01555             //DEBUG_PRINT("%d:%s:%s\n",i,szDeviceName,szDeviceVersion);
01556             DEBUG_PRINT("%d:%s:%s\n",i,szDeviceName,szDeviceVersion);
01557             count++;
01558         }
01559     } 
01560 
01561     phTHIS_UNLOCK(locked);
01562 
01563     return count;
01564 error:
01565     phTHIS_ERROR_UNLOCK(locked);
01566     return phFAIL;
01567 }
01568 /* ---------------------------------------------------------------------- */
01569 int VFWSource::connect_device(int index)
01570 {
01571     phFUNCTION("VFWSource::connect_device")
01572         BOOL            brc;
01573     wchar_t         driverName[256];
01574     wchar_t         driverVersion[256];
01575     int             locked = 0;
01576 
01577     phTHIS_LOCK(locked);
01578 
01579     if ((this->m_info != NULL) && (this->m_info->window != NULL))
01580     {
01581         /* If the current device index is the one being chosen, don't
01582          * disconnect and reconnect */
01583         if (index != this->m_info->device)
01584         {
01585             if (this->m_info->device != -1)
01586             {
01587                 rc = this->disconnect_device();
01588                 phPRINT_RC(rc,NULL,"disconnect_device");
01589             }   
01590 
01591             /* 
01592              * 1.) Get Driver description
01593              * 2.) Connect to the driver
01594              * 3.) Set the window text to the driver name
01595              * 4.) Get, Adjust and Set the setup of the driver
01596              * 5.) Get the driver capabilities
01597              * 6.) Get the driver status
01598              * 7.) Set the callbacks
01599              * 8.) Set the video format 
01600              */
01601 
01602             /* now set the text of the window to the driver's name */
01603             brc = ::capGetDriverDescriptionW( index, 
01604                     (LPWSTR)driverName, 
01605                     sizeof(driverName), 
01606                     (LPWSTR)driverVersion,
01607                     sizeof(driverVersion) );
01608             if (brc == 0) rc = phFAIL; else rc = phSUCCESS;
01609             phCHECK_RC(rc,"capGetDriverDescription",
01610                     "capGetDriverDescription=%d failed (because there is no device at index %d ?).",
01611                     brc, index);
01612 
01613             /* Connect to the specified driver */
01614             brc = capDriverConnect (this->m_info->capwin, index);
01615             if (brc == 0) rc = phFAIL; else rc = phSUCCESS;
01616             phCHECK_RC(rc,"capDriverConnect","capDriverConnect failed (0x%08x).",brc);
01617 
01618             this->m_info->connected = 1;
01619 
01620             /* store the index of the device being used */
01621             this->m_info->device = index;
01622 
01623             brc = ::SetWindowText(this->m_info->window,(LPCWSTR)driverName);
01624             if (brc == 0) rc = phFAIL; else rc = phSUCCESS;
01625             phPRINT_RC(rc,"SetWindowText","SetWindowText (0x%08x)",brc);
01626 
01627             /* get the description */
01628             phMemcpy(this->m_info->d_name,driverName,256);
01629             phMemcpy(this->m_info->d_version,driverVersion,256);
01630 
01631             /* Get the capture setup */
01632             brc = capCaptureGetSetup(this->m_info->capwin,
01633                     &(this->m_info->d_setup),
01634                     sizeof(CAPTUREPARMS));
01635             if (brc == 0) rc = phFAIL; else rc = phSUCCESS;
01636             phPRINT_RC(rc,"capDriverGetDescription","capDriverGetDescription (0x%08x)",brc);
01637 
01638             /* Adjust the setup */
01639             this->m_info->d_setup.fAbortLeftMouse   = FALSE;
01640             this->m_info->d_setup.fAbortRightMouse  = FALSE;
01641             this->m_info->d_setup.fYield            = TRUE;
01642             this->m_info->d_setup.fCaptureAudio     = FALSE;
01643             this->m_info->d_setup.wPercentDropForError = 100;
01644 
01645             /* Set the parameters of the capture setup */
01646             brc = capCaptureSetSetup(this->m_info->capwin,
01647                     &(this->m_info->d_setup),
01648                                      sizeof(CAPTUREPARMS));
01649             if (brc == 0) rc = phFAIL; else rc = phSUCCESS;
01650             phPRINT_RC(rc,"capDriverGetDescription","capDriverGetDescription (0x%08x)",brc);
01651             
01652             /* Get the capabilities */
01653             brc = capDriverGetCaps(this->m_info->capwin,
01654                                    &this->m_info->d_caps,
01655                                    sizeof(CAPDRIVERCAPS));
01656             if (brc == 0) rc = phFAIL; else rc = phSUCCESS;
01657             phPRINT_RC(rc,"capDriverGetCaps","capDriverGetCaps (0x%08x)",brc);
01658             
01659             /* resize the capture window to match the size of the driver */
01660             brc = capGetStatus(this->m_info->capwin, 
01661                                &this->m_info->d_status, 
01662                                sizeof (CAPSTATUS));
01663             if (brc == 0) rc = phFAIL; else rc = phSUCCESS;
01664             phPRINT_RC(rc,"capGetStatus","capGetStatus (0x%08x)",brc);
01665 
01666             /* Resize the window to match the size of the captured image
01667              * and then ... */
01668             ::SetWindowPos(this->m_info->window, NULL, 0, 0, 
01669                            this->m_info->d_status.uiImageWidth, 
01670                            this->m_info->d_status.uiImageHeight, 
01671                            SWP_NOZORDER | SWP_NOMOVE);
01672                
01673             rc = this->set_callbacks();
01674             phPRINT_RC(rc,NULL,"set_callbacks (0x%08x)",brc);
01675      
01676             /* ... Enable the preview */
01677 //            capPreview(this->m_info->capwin, FALSE);
01678 //            capPreviewRate(this->m_info->capwin,66);
01679 
01680             rc = this->setVideoFormat( this->m_width,this->m_height, phImageRGB24 );
01681             phPRINT_RC(rc,NULL,"this->setVideoFormat (0x%08x)",brc);
01682         }
01683     }
01684     
01685     if ((this->m_info != NULL) && (this->m_info->device == -1))
01686     {
01687         brc = ::SetWindowText(this->m_info->window,(LPCWSTR)"No Drivers");
01688         if (brc == 0) rc = phFAIL; else rc = phSUCCESS;
01689         phPRINT_RC(rc,"SetWindowText","SetWindowText (0x%08x)",brc);
01690     }    
01691     
01692     phTHIS_UNLOCK(locked);
01693 
01694     return phSUCCESS;
01695     
01696 error:
01697     phTHIS_ERROR_UNLOCK(locked);
01698     
01699     if (this->m_info != NULL)
01700     {
01701         this->m_info->device = -1;
01702     }
01703 
01704     return phFAIL;
01705 }
01706 
01707 /* ---------------------------------------------------------------------- */
01708 int VFWSource::disconnect_device()
01709 {
01710     phFUNCTION("VFWSource::disconnect_device")
01711     BOOL    brc;
01712     int     locked = 0;
01713     
01714     phTHIS_LOCK(locked);
01715 
01716     if ((this->m_info != NULL) && (this->m_info->window != NULL))
01717     {
01718         rc = this->device_stop();
01719         phPRINT_RC(rc,NULL,"device_stop");
01720 
01721         if ((this->m_info->device != -1) && (this->m_info->connected))
01722         {
01723             ::SetLastError(ERROR_SUCCESS);
01724             brc = capDriverDisconnect(this->m_info->capwin);
01725             if ((brc == 0) && (GetLastError() != ERROR_SUCCESS)) 
01726                 rc = phFAIL; 
01727             else 
01728                 rc = phSUCCESS;
01729             phPRINT_RC(rc,"capDriverDisconnect","capDriverDisconnect failed (0x%08x).",brc);
01730 
01731             this->m_info->connected = 0;
01732             this->m_info->device = -1;
01733         }   
01734         
01735         phMemset(&this->m_info->d_status,0, sizeof (CAPSTATUS));
01736 
01737         brc = ::SetWindowText(this->m_info->window,(LPCWSTR)"No Drivers");
01738         if (brc == 0) rc = phFAIL; else rc = phSUCCESS;
01739         phPRINT_RC(rc,"SetWindowText","SetWindowText (0x%08x)",brc);
01740     }    
01741     
01742     phTHIS_UNLOCK(locked);
01743 
01744     return phSUCCESS;
01745 error:
01746     phTHIS_ERROR_UNLOCK(locked);
01747 
01748     return phSUCCESS;
01749 }
01750 
01751 /* ---------------------------------------------------------------------- */
01752 int VFWSource::device_start()
01753 {           
01754     phFUNCTION("VFWSource::device_start");
01755 
01756     int     locked  = 0;
01757     BOOL    brc     = FALSE;
01758 
01759     phTHIS_LOCK(locked);
01760 
01761     if ((this->m_info != NULL) && 
01762         (this->m_info->started == 0) &&
01763         (this->m_info->window != NULL) &&
01764         (this->m_info->capwin != NULL) &&
01765         (this->m_info->device >= 0))
01766     {
01767         brc = capCaptureSequenceNoFile(this->m_info->capwin);
01768         if (brc == 0) rc = phFAIL; else rc = phSUCCESS;
01769         phPRINT_RC(rc,"capCaptureSequence","capCaptureSequence failed (0x%08x).",brc);
01770 
01771         if (rc != phFAIL)
01772             this->m_info->started = 1;
01773     }
01774 
01775     phTHIS_UNLOCK(locked);
01776 
01777     return phSUCCESS;
01778 error:
01779     phTHIS_ERROR_UNLOCK(locked);
01780     
01781     return phFAIL;
01782 }
01783 
01784 /* ---------------------------------------------------------------------- */
01785 int VFWSource::device_stop()
01786 {           
01787     phFUNCTION("VFWSource::device_stop");
01788 
01789     int     locked  = 0;
01790     BOOL    brc     = FALSE;
01791 
01792     phTHIS_LOCK(locked);
01793 
01794     if ((this->m_info != NULL) && 
01795         (this->m_info->started == 1) &&
01796         (this->m_info->window != NULL) &&
01797         (this->m_info->capwin != NULL) &&
01798         (this->m_info->device >= 0))
01799     {
01800         brc = capCaptureAbort(this->m_info->capwin);
01801         if (brc == 0) rc = phFAIL; else rc = phSUCCESS;
01802         phPRINT_RC(rc,"capCaptureAbort","capCaptureAbort failed (0x%08x).",brc);
01803 
01804         if (rc != phFAIL)
01805             this->m_info->started = 0;
01806     }
01807 
01808     phTHIS_UNLOCK(locked);
01809 
01810     return phSUCCESS;
01811 error:
01812     phTHIS_ERROR_UNLOCK(locked);
01813     
01814     return phFAIL;
01815 }
01816 
01817 /* ---------------------------------------------------------------------- */
01818 int VFWSource::setVideoFormat( uint32_t w, uint32_t h, int32_t f )
01819 {
01820     phFUNCTION("VFWSource::setVideoFormat");
01821 
01822     int             locked  = 0;
01823     LPBITMAPINFO    lpbi    = NULL;
01824     int             restart = 0;
01825     DWORD           dwSize;
01826     BOOL            brc     = FALSE;
01827 
01828     phTHIS_LOCK(locked);
01829 
01830     if ((this->m_info != NULL) && 
01831         (this->m_info->window != NULL) &&
01832         (this->m_info->capwin != NULL) &&
01833         (this->m_info->device >= 0))
01834     {
01835         if (this->m_info->started)
01836         {
01837             rc = this->device_stop();
01838             phPRINT_RC(rc,NULL,"device_stop");
01839             restart = 1;
01840         }
01841 
01842         switch (f)
01843         {
01844             /* --------------------------------------------------- */
01845             case phImageGREY8:
01846                 break;
01847             /* --------------------------------------------------- */
01848             case phImageBGR24:
01849             case phImageRGB24:
01850                 break;
01851             /* --------------------------------------------------- */
01852             case phImageBGRA32:
01853             case phImageRGBA32:
01854                 break;
01855             /* --------------------------------------------------- */
01856             /* if multiple formats are specified or the format is 
01857              * invalid, then phImageRGB24 is used */
01858             default:
01859                 this->m_private_format = this->m_format = f = phImageRGB24;
01860         }
01861 
01862         dwSize = capGetVideoFormatSize(this->m_info->capwin);
01863 
01864         lpbi = (LPBITMAPINFO)phCalloc(1,dwSize);
01865         phPRINT_PTR(lpbi,"phCalloc","phCalloc failed.");
01866         
01867         brc = capGetVideoFormat(this->m_info->capwin, lpbi, dwSize); 
01868         if (brc == 0) rc = phFAIL; else rc = phSUCCESS;
01869         phPRINT_RC(rc,"capGetVideoFormat","capGetVideoFormat (0x%08x)",brc);
01870 
01871         lpbi->bmiHeader.biSize          = dwSize; 
01872         lpbi->bmiHeader.biWidth         = w; 
01873         lpbi->bmiHeader.biHeight        = h; 
01874         lpbi->bmiHeader.biPlanes        = 1;
01875         lpbi->bmiHeader.biBitCount      = phImageFormatToDepth(f) * 8; 
01876         lpbi->bmiHeader.biCompression   = BI_RGB;
01877         lpbi->bmiHeader.biSizeImage     = w * h * phImageFormatToDepth(f); 
01878         lpbi->bmiHeader.biClrUsed       = 0; 
01879         lpbi->bmiHeader.biClrImportant  = 0; 
01880 
01881         brc = capSetVideoFormat(this->m_info->capwin, lpbi, dwSize);
01882         if (brc == 0) rc = phFAIL; else rc = phSUCCESS;
01883         phPRINT_RC(rc,"capSetVideoFormat","capSetVideoFormat (0x%08x)",brc);
01884 
01885         if (rc != phFAIL)
01886         {
01887             if (this->m_info->d_lpbi != NULL) phFree(this->m_info->d_lpbi);
01888 
01889             this->m_info->d_lpbi = lpbi;
01890         }
01891         else
01892         {
01893             phFree(lpbi);
01894         }
01895 
01896         if (restart)
01897         {
01898             rc = this->device_start();
01899             phPRINT_RC(rc,NULL,"device_start");
01900         }
01901     }
01902 
01903     phTHIS_UNLOCK(locked);
01904 
01905     return phSUCCESS;
01906 
01907 error:
01908     phTHIS_ERROR_UNLOCK(locked);
01909 
01910     return phFAIL;
01911 }
01912 
01913 /* ---------------------------------------------------------------------- */
01914 int VFWSource::open(char *path)
01915 {
01916     phFUNCTION("VFWSource::open")
01917 
01918     rc = this->lock();
01919     phPRINT_RC(rc,NULL,"this->lock()");
01920    
01921     /* device is already open, close it */
01922     if (this->isOpen())
01923     {
01924         rc = this->close();
01925         phPRINT_RC(rc,NULL,"this->close()");
01926     }
01927   
01928     if (path != NULL)
01929     {
01930         rc = this->setPath( path );
01931         phPRINT_RC(rc,NULL,"this->setPath( path:%s )",path);
01932     }
01933   
01934     /* If the device isn't already open....*/
01935     /* open the device */
01936     /* Find out info the device is capable of */
01937     /* ... apply all of the current settings to the device */
01938     /* ... set the device as open */
01939 
01940     rc = this->unlock();
01941     phPRINT_RC(rc,NULL,"this->unlock()");
01942     
01943     return phSUCCESS;
01944 #if 0
01945 error:
01946     rc = this->unlock();
01947     phPRINT_RC(rc,NULL,"this->unlock()");
01948     
01949     return phFAIL;
01950 #endif
01951 }
01952 
01953 /* ---------------------------------------------------------------------- */
01954 int VFWSource::isOpen() 
01955 { 
01956     return this->isRunning();
01957 }    
01958 
01959 /* ---------------------------------------------------------------------- */
01960 int VFWSource::close()
01961 {
01962     phFUNCTION("VFWSource::close")
01963    
01964     rc = this->lock();
01965     phPRINT_RC(rc,NULL,"this->lock()");
01966 
01967     /* Close the device and reset all the parameters */
01968     
01969 #if 0
01970 success:
01971 #endif
01972     rc = this->unlock();
01973     phPRINT_RC(rc,NULL,"this->unlock()");
01974     
01975     return phSUCCESS;
01976     
01977 #if 0
01978 error:
01979     rc = this->unlock();
01980     phPRINT_RC(rc,NULL,"this->unlock()");
01981     
01982     return phFAIL;
01983 #endif
01984 }
01985 
01986 /* ---------------------------------------------------------------------- */
01987 /* m_settings and this are locked upon entry */
01988 /* ---------------------------------------------------------------------- */
01989 int VFWSource::onApplySettings()
01990 {
01991     phFUNCTION("VFWSource::onApplySettings")
01992     int retrc = phSUCCESS;
01993     int locked = 0;
01994     int set_locked = 0;
01995 
01996     int ch_init = 0;
01997     int ch_b = 0;
01998     int ch_hue = 0;
01999     int ch_color = 0;
02000     int ch_con = 0;
02001     int ch_white = 0;
02002     int ch_channel = 0;
02003     int ch_h = 0;
02004     int ch_w = 0;
02005     int ch_f = 0;
02006     int ch_p = 0;
02007     
02008     ch_init = ph_int32_array_find(this->m_changed_array, phCHANGE_INIT,NULL);
02009     /* 
02010      * this->m_changed_array contains the list of changes that are to 
02011      *  be applied.
02012      *
02013      * This method will call phImageCapture::onApplySettings which will empty
02014      * the array so that settings are applied only once.
02015      */
02016     
02017     /* Copy the image settings into the VFW structure */
02018     ch_b = ph_int32_array_find(this->m_changed_array,       phCHANGE_BRIGHTNESS,
02019                             NULL);
02020     ch_hue = ph_int32_array_find(this->m_changed_array,     phCHANGE_HUE,
02021                             NULL);
02022     ch_color = ph_int32_array_find(this->m_changed_array,   phCHANGE_COLOR,
02023                             NULL);
02024     ch_con = ph_int32_array_find(this->m_changed_array,     phCHANGE_CONTRAST,
02025                             NULL);
02026     ch_white = ph_int32_array_find(this->m_changed_array,   phCHANGE_WHITENESS,
02027                             NULL);
02028     if (ch_init > 0) ch_b = ch_hue = ch_color = ch_con = ch_white = 1;
02029     if ((ch_b > 0) || (ch_hue > 0) || (ch_color > 0) || 
02030         (ch_con > 0) || (ch_white > 0))
02031     {
02032 #if 0
02033         this->m_changed_settings = 1;
02034         if (ch_b > 0)
02035             this->m_settings.brightness   = this->m_brightness;
02036         if (ch_hue > 0)
02037             this->m_settings.hue          = this->m_hue;
02038         if (ch_color > 0)
02039             this->m_settings.colour       = this->m_color;
02040         if (ch_con > 0)
02041             this->m_settings.contrast     = this->m_contrast;
02042         if (ch_white > 0)
02043             this->m_settings.whiteness    = this->m_whiteness;
02044 #endif
02045     }
02046  
02047     /*--------------------------------------------------------------------*
02048      *--------------------------------------------------------------------*/
02049     ch_channel = ph_int32_array_find(this->m_changed_array,phCHANGE_CHANNEL,
02050                                     NULL);
02051     if ((ch_channel > 0) || (ch_init > 0))
02052     {
02053         this->m_changed_channel = 1;
02054     }
02055     /* else, the channel is < 0 or the current chn # */
02056     
02057     /* settings that require the capture to not be in progress for the 
02058      * VFWSource settings changes to be applied */
02059     ch_h = ph_int32_array_find(this->m_changed_array, phCHANGE_HEIGHT, NULL);
02060     ch_w = ph_int32_array_find(this->m_changed_array, phCHANGE_WIDTH, NULL);
02061     ch_f = ph_int32_array_find(this->m_changed_array, phCHANGE_FORMAT, NULL);
02062 
02063     if (ch_init > 0) ch_h = ch_w = ch_f = 1;
02064 
02065     if ((ch_h > 0) || (ch_w > 0) || (ch_f > 0))
02066     {
02067         /* if the retrc variable isn't set to 1, then copy these 
02068          * into the private values for the VFWSource class */
02069         /* Settings not applied until restart */
02070 //        if ((!this->isRunning()) && (this->m_hw_mmapped == 0))
02071         if (this->isRunning())
02072         {
02073             int changed_image_dimensions = 0;
02074 
02075             uint32_t width  = 0;
02076             uint32_t height = 0;
02077 
02078             if ((this->m_info != NULL) && (this->m_info->d_lpbi != NULL))
02079             {
02080                 width  = this->m_info->d_lpbi->bmiHeader.biWidth;
02081                 height = this->m_info->d_lpbi->bmiHeader.biHeight;
02082                 height = height * (height < 0 ? -1 : 1);
02083             }
02084             
02085             /* use OR/|| because sometimes the change must be forced
02086              * to actually apply the settings */
02087             if ((ch_w > 0) || (width != this->m_width) ||
02088                 (ch_h > 0) || (height != this->m_height))
02089             {
02090                 changed_image_dimensions = 1;
02091             }
02092 
02093             /* use OR/|| because sometimes the change must be forced
02094              * to actually apply the settings */
02095             if ((ch_f > 0) || (this->m_private_format != this->m_format))
02096             {
02097                 int32_t f = this->m_format;
02098                 int32_t validFormats = (phImageRGB24 |
02099                                         phImageBGR24 |
02100                                         phImageRGBA32 | 
02101                                         phImageBGRA32 |
02102                                         phImageGREY8);
02103                 changed_image_dimensions = 1;
02104                 
02105                 /* make sure any special flags are removed */
02106                 f &= validFormats;
02107                 
02108                
02109                 
02110                 this->m_private_format = this->m_format = f;
02111             }
02112 
02113             /* if any of the fields changed, then apply the changes
02114              * to the device if it's open and set the new image size */
02115             if (changed_image_dimensions == 1)
02116             {
02117             #if 0
02118                 phIMAGE_SIZE_IN_BYTES(this->m_image_size,
02119                                       this->m_captureSpec.width,
02120                                       this->m_captureSpec.height,
02121                                       this->m_private_format );
02122             #endif
02123                 rc = this->setVideoFormat(  this->m_width, 
02124                                             this->m_height, 
02125                                             this->m_format );
02126                 phPRINT_RC(rc,NULL,"setVideoFormat");
02127 
02128                 this->m_changed_settings = 1;
02129             }
02130         }
02131         else
02132         {
02133             retrc = 1;
02134         }
02135     }
02136     
02137     ch_p = ph_int32_array_find(this->m_changed_array, phCHANGE_PATH, NULL);
02138     if ((ch_p > 0) || (ch_init > 0))
02139     {
02140         /* this->m_path is used in 'open', no special VFWSource
02141          * settings have to be applied here */
02142         retrc = 1;
02143     }
02144 
02145     /* if the device is open, apply the settings... */
02146     /* can really only apply the settings if the device is open */
02147     /* until the device is open we're merely saving the values */
02148         /* TODO: if reopening and stopping of the thread is necessary
02149          * then this is likely the place to do it */
02150 
02151 
02152         /* The value m_changed_settings is persistent across calls to 
02153          * applySettings in the case the settings aren't applied 
02154          * in one call of applySettings */
02155         if (this->m_changed_settings == 1)
02156         {
02157             /* Apply the picture  settings */
02158             this->m_changed_settings = 0;
02159         }
02160  
02161         /* The value m_changed_channel is persistent across calls to 
02162          * applySettings in the case the settings aren't applied 
02163          * in one call of applySettings */
02164         if (this->m_changed_channel == 1)
02165         {
02166             /* get channel: fills the structure's fields with default values*/
02167         
02168             /* set image source and TV norm */
02169             
02170             /* set channel */
02171 
02172             this->m_changed_channel = 0;
02173         }   
02174     
02175     rc = this->phImageCapture::onApplySettings();
02176     phCHECK_RC(rc,NULL,"this->phImageCapture::onApplySettings() failed.");
02177  
02178     return retrc;
02179 error:
02180     return phFAIL;
02181 }
02182 /* ---------------------------------------------------------------------- */
02183 int VFWSource::wakeup()
02184 {
02185     phFUNCTION("VFWSource::wakeup()")
02186     
02187     if ((this->m_info != NULL) && (this->m_info->window != NULL))
02188     {
02189         BOOL brc = TRUE;
02190         brc = ::PostMessage(this->m_info->window,
02191                             WM_QUIT,
02192                             NULL, NULL);
02193         if (brc == 0) rc = phFAIL; else rc = phSUCCESS;
02194         phPRINT_RC(rc,"PostMessage","PostMessage (0x%08x)",brc);
02195     }
02196     /*
02197     rc = this->phImageWindow::wakeup();
02198     phPRINT_RC(rc,NULL,"this->phImageWindow::wakeup()");
02199     */  
02200     return phSUCCESS;
02201 }       
02202 
02203 /* ---------------------------------------------------------------------- */
02204 int VFWSource::cleanup()
02205 {
02206     phFUNCTION("VFWSource::cleanup()")
02207    
02208     rc = this->lock();
02209     phPRINT_RC(rc,NULL,"this->lock()");
02210     
02211     rc = this->phImageCapture::cleanup();
02212     phPRINT_RC(rc,NULL,"this->phImageCapture::cleanup()");
02213     
02214     rc = this->unlock();
02215     phPRINT_RC(rc,NULL,"this->unlock()");
02216     
02217     return phSUCCESS;
02218 }
02219  
02220 /* ---------------------------------------------------------------------- */
02221 int VFWSource::gui_show()
02222 {
02223     phFUNCTION("VFWSource::gui_show")
02224     BOOL brc = TRUE;
02225     int locked = 0;
02226     int retrc = phSUCCESS;
02227     
02228     phTHIS_LOCK(locked);
02229 
02230     if ((this->m_info != NULL) && (this->m_info->window != NULL))
02231     {
02232         if (this->m_show_first)
02233         {
02234             brc = ShowWindow(this->m_info->window,SW_SHOWNORMAL);
02235             if (brc == 0) rc = phFAIL; else rc = phSUCCESS;
02236 
02237             brc = SetWindowPos(this->m_info->window,
02238                                HWND_TOP,
02239                                10,10,320,240,
02240                                SWP_NOCOPYBITS | 
02241                                SWP_NOSIZE | 
02242                                SWP_NOMOVE |
02243                                SWP_SHOWWINDOW);
02244             if (brc == 0) rc = phFAIL; else rc = phSUCCESS;
02245 
02246             SetActiveWindow(this->m_info->window);
02247                 
02248             brc = SetForegroundWindow(this->m_info->window);
02249             if (brc == 0) rc = phFAIL; else rc = phSUCCESS;
02250 
02251             this->m_show_first = 0;
02252         }
02253         else
02254         {
02255             brc = ShowWindow(this->m_info->window,SW_SHOW);
02256             if (brc == 0) rc = phFAIL; else rc = phSUCCESS;
02257         }
02258             
02259         brc = ShowWindow(this->m_info->capwin,SW_SHOW);
02260         if (brc == 0) rc = phFAIL; else rc = phSUCCESS;
02261 
02262         SetFocus(this->m_info->capwin);
02263     }
02264     else
02265         retrc = 1;
02266 
02267     phTHIS_UNLOCK(locked);
02268     
02269     return retrc;
02270 
02271 error:
02272     phTHIS_ERROR_UNLOCK(locked);
02273     
02274     return phFAIL;
02275 }
02276 
02277 /* ---------------------------------------------------------------------- */
02278 int VFWSource::gui_hide()
02279 {
02280     phFUNCTION("VFWSource::gui_hide")
02281     BOOL brc = TRUE;
02282     int locked = 0;
02283     int retrc = phSUCCESS;
02284     
02285     phTHIS_LOCK(locked);
02286     
02287     if (this->m_info != NULL)
02288     {
02289         brc = ShowWindow(this->m_info->window,SW_HIDE);
02290         brc = ShowWindow(this->m_info->capwin,SW_HIDE);
02291     }
02292     else
02293         retrc = 1;
02294 
02295     phTHIS_UNLOCK(locked);
02296     
02297     return retrc;
02298 
02299 error:
02300     phTHIS_ERROR_UNLOCK(locked);
02301     
02302     return phFAIL;
02303 }
02304 
02305 
02306 /* ---------------------------------------------------------------------- */
02307 int VFWSource::run()
02308 {
02309     phFUNCTION("VFWSource::run")
02310     MSG         msg;
02311     BOOL        brc = TRUE;
02312     LRESULT     lrc = 0;
02313     int         device = -1;
02314     int         total_devices = 0;
02315     
02316     phImage     *output_buffer  = this->getImage();
02317     
02318     uint32_t i = 0;
02319 
02320     /* Setup */
02321     rc = this->init_window();
02322     phCHECK_RC(rc,NULL,"this->init_window");
02323     
02324     total_devices = rc = this->list_devices();
02325     phPRINT_RC(rc,NULL,"list_Devices");
02326     
02327     /* Convert the device path to a number for VFW */
02328     if (this->getPath() != NULL)
02329         device = atoi(this->getPath());
02330     if ((device < 0) || (device >= total_devices)) rc = phFAIL; else rc = phSUCCESS;
02331     phCHECK_RC(rc,NULL,"device index out of range:%d",device);
02332 
02333     rc = this->connect_device(device);
02334     phCHECK_RC(rc,NULL,"this->connect_device(%d)",device);
02335 
02336     rc = this->device_start();
02337     phCHECK_RC(rc,NULL,"this->device_start()");
02338 
02339 #if 0
02340     /* .) Set the variables for remote viewing */
02341     rc = this->gui_show();
02342     phCHECK_RC(rc,NULL,"this->gui_show()");
02343 #endif
02344     /* Release the thread that spawned this one */
02345     /* Everything has been copied and everything is ready to start */
02346     rc = this->signal_running();
02347     phPRINT_RC(rc,NULL,"this->signal_running");
02348     
02349     DEBUG_PRINT("Thread Started\n");
02350     
02351     #if 0
02352     brc = capDlgVideoSource(this->m_info->window);
02353     if (brc == 0) rc = phFAIL; else rc = phSUCCESS;
02354     phPRINT_RC(rc,"capDlgVideoSource","capDlgVideoSource");
02355     #endif
02356     print_CAPTUREPARMS(this->m_info->d_setup);
02357     print_CAPDRIVERCAPS(this->m_info->d_caps);
02358     print_CAPSTATUS(this->m_info->d_status);
02359 
02360     while (this->isRunning())
02361     {
02362         //brc = ::GetMessage(&msg,NULL,0,0);
02363         brc = ::GetMessage(&msg,this->m_info->window,0,0);
02364 
02365         if (brc == -1)
02366         {
02367             if (GetLastError() == ERROR_INVALID_WINDOW_HANDLE)
02368             {
02369                 this->setRunning(0);
02370                 continue;
02371             }
02372             else
02373             {
02374                 phPRINT_RC(phFAIL,"GetMessage","GetMessage failed.");
02375             }
02376         }
02377         else
02378         {
02379             brc = TranslateMessage(&msg);
02380             lrc = DispatchMessage(&msg);
02381         }
02382     }
02383         
02384     DEBUG_PRINT("Thread returning cleanly\n");
02385    
02386     rc = this->device_stop();
02387     phCHECK_RC(rc,NULL,"this->device_stop()");
02388 
02389     rc = this->gui_hide();
02390     phPRINT_RC(rc,NULL,"this->gui_hide()");
02391     
02392     rc = this->disconnect_device();
02393     phPRINT_RC(rc,NULL,"this->disconnect_device()");
02394     
02395     rc = this->destroy_window();
02396     phPRINT_RC(rc,NULL,"this->init_window");
02397     
02398     return phSUCCESS;
02399     
02400 error:
02401     phPROGRESS("Thread returning with error\n");
02402     
02403     rc = this->gui_hide();
02404     phPRINT_RC(rc,NULL,"this->gui_hide()");
02405     
02406     rc = this->destroy_window();
02407     phPRINT_RC(rc,NULL,"this->init_window");
02408     
02409     rc = this->signal_error();
02410     phPRINT_RC(rc,NULL,"this->signal_error");
02411     
02412     return phFAIL;
02413 }
02414 




Copyright (C) 2002 - 2007 Philip D.S. Thoren ( pthoren@users.sourceforge.net )
University Of Massachusetts at Lowell
Robotics Lab
SourceForge.net Logo

Generated on Sat Jun 16 02:44:03 2007 for phission by  doxygen 1.4.4