home *** CD-ROM | disk | FTP | other *** search
- /*
- * QCAMTEST.C - Sample source code demonstrating the use of the
- * QuickCam OS/2 Parallel Port Device Driver.
- */
- #define INCL_WIN
- #define INCL_DOS
- #define INCL_GPI
- #include <os2.h>
- #include <stdio.h>
- #include <stdarg.h>
- #include <string.h>
- #include "qcamdd.h"
-
- /*
- * User defined messages.
- */
- #define WM_USER_POSITION WM_USER+1
- #define WM_USER_SIZE WM_USER+2
- #define WM_USER_UPDATE WM_USER+3
-
- /*
- * Function prototypes.
- */
- static MRESULT EXPENTRY QtestWndProc(HWND,ULONG,MPARAM,MPARAM);
- static void GetImage(HWND hWnd);
- static void UpdateImage(HWND hWnd);
- static LONG FormatMsgBox(HWND hwnd_PO, PSZ Format_String, ...);
- static USHORT InitCamera(void);
- static HBITMAP GetFrame(HPS hps,HAB hab);
- static USHORT UpdateFrame(void);
- static void TermCamera(void);
- static USHORT SetCameraBrightness(UCHAR brightness);
- static USHORT SetCameraContrast(UCHAR contrast);
- static USHORT SetCameraBalance(UCHAR balance);
- static USHORT SetCameraTransferMode(UCHAR mode);
- static USHORT SetCameraPixelDepth(UCHAR depth);
-
- /*
- * Global variables.
- */
- HAB habMain; // Anchor block
- HWND hWndScreen; // Image display window
- HWND hWndClient; // Queue handler
- HPS hpsFrame=NULLHANDLE; // Image presentation space
-
- HMTX hmtxPS=NULLHANDLE; // Control access to camera
- RECTL rctlClient; // Used to size windows
- USHORT SkipFrame=FALSE; // Pace the image updates
- ULONG FrameWidth=QCAM_MAX_WIDTH; // Default size of the image
- ULONG FrameHeight=QCAM_MAX_HEIGHT;
- UCHAR Brightness=QCAM_DEF_BRIGHT; // Current brightness setting
-
- HFILE CamHandle; // OS "handle" to quickcam
- ULONG OpenAction; // Action taken on open
- ULONG BytesRead=0L; // Image size returned by Read
- ULONG BufLength=0L; // Size of buffer obtained
- ULONG BufRetLen=0L; // Size of length variable
- UCHAR *BufAddress=NULL; // Address of buffer obtained
- ULONG ParmLength=0L; // Size of parameter passed
- ULONG ParmRetLen=0L; // Size of parameter variable
- APIRET RC; // Return code
-
- /*
- * For updating the camera settings.
- */
- QCAM_SETTINGS QcamSetup; // Camera setup structure
- USHORT QcamRequest; // Request what setups to do
-
- /*
- * For creating a bitmap.
- */
- HDC hdcMemory; // Build a memory "device
- HPS hpsMemory; // context" to store images
- BITMAPINFOHEADER2 BitmapNew; // from the camera
- struct _MYBITMAP
- {
- BITMAPINFOHEADER2 Header;
- RGB2 Palette[QCAM_MAX_PALETTE];
- } Bitmap;
-
-
- /*
- * QuickCam test for OS/2 Parallel Port Device Driver mainline.
- */
- int main(void)
- {
- HMQ hmq; // Message queue
- QMSG qmsg; // Queue message structure
- CHAR szClientClass[]="QTEST"; // Class name
- ULONG flFrameFlags= FCF_TITLEBAR | // Window characteristics
- FCF_SYSMENU |
- FCF_BORDER |
- FCF_SHELLPOSITION |
- FCF_TASKLIST;
-
- /*
- * Initialize the camera. // CAMERA CODE!!!
- */
- if (InitCamera()==QCAM_ERROR)
- {
- return(1);
- }
-
- /*
- * Create a standard window.
- */
- habMain=WinInitialize(0);
- hmq=WinCreateMsgQueue(habMain,0);
- WinRegisterClass(habMain,szClientClass,(PFNWP)QtestWndProc,0,0);
- hWndScreen=WinCreateStdWindow
- (HWND_DESKTOP,0,&flFrameFlags,szClientClass,
- "QuickCam Device Driver Test Program",
- 0,0,1,&hWndClient);
-
- /*
- * Set the initial window size to the default maximums.
- */
- WinPostMsg(hWndClient,WM_USER_SIZE,0L,0L);
-
- /*
- * Process messages for window until user quits.
- */
- if (WinStartTimer(habMain,hWndClient,1,1000L))
- {
- while(WinGetMsg(habMain,&qmsg,0,0,0))
- {
- WinDispatchMsg(habMain,&qmsg);
- }
- WinStopTimer(habMain,hWndClient,1);
- }
-
- /*
- * Cleanup and exit.
- */
- TermCamera(); // CAMERA CODE!!!
- WinDestroyWindow(hWndScreen);
- WinDestroyMsgQueue(hmq);
- WinTerminate(habMain);
-
- /*
- * Exit the process.
- */
- return(0);
- }
-
-
- /*
- * Deal with messages to this window.
- */
- MRESULT EXPENTRY QtestWndProc (HWND hWnd,ULONG msg,MPARAM mp1,MPARAM mp2)
- {
- HPS hps; // Handle to presentation space
- BOOL bHandled=TRUE; // Message handled flag
- MRESULT mReturn=0; // Return code
- SWP winpos; // Position structure
- POINTL ulPoints[4]; // Used to size window
-
- switch (msg)
- {
- case WM_CREATE:
- /*
- * Get a mutually exclusive semaphore for use later.
- */
- DosCreateMutexSem((PSZ)NULL,&hmtxPS,0UL,FALSE);
-
- /*
- * Start getting the camera image in the window.
- */
- GetImage(hWnd); // CAMERA CODE!!!
-
- /*
- * Make the window visible.
- */
- WinShowWindow(hWnd,TRUE);
- break;
-
- case WM_USER_UPDATE:
- /*
- * Posted by the UpdateImage function. Indicates that
- * a new image is in the memory presentation space,
- * so ensure that we have to do a redraw.
- */
- WinQueryWindowRect(hWnd,&rctlClient);
- WinInvalidateRect(hWnd,&rctlClient,TRUE);
- break;
-
- case WM_USER_SIZE:
- /*
- * Set to client window to the current frame size.
- */
- WinQueryTaskSizePos(habMain,0,&winpos);
- WinSetWindowPos(hWndScreen,NULLHANDLE,winpos.x,
- winpos.y,FrameWidth,FrameHeight,
- SWP_SHOW|SWP_MOVE|SWP_SIZE);
- break;
-
- case WM_CHAR:
- /*
- * Adjust the brightness.
- */
- if ((CHARMSG(&msg)->fs & KC_KEYUP)==0)
- {
- if (CHARMSG(&msg)->fs & KC_CHAR)
- {
- switch (CHARMSG(&msg)->chr)
- {
- /*
- * Increase brightness.
- */
- case '+': Brightness+=5;
- SetCameraBrightness(Brightness);
- break;
-
- /*
- * Decrease brightness.
- */
- case '-': Brightness-=5;
- SetCameraBrightness(Brightness);
- break;
-
- default: break;
- }
- }
- }
- break;
-
- case WM_TIMER:
- /*
- * Update the picture once a second. Paced by
- * the PC ability to deliver frames.
- */
- if (SkipFrame==FALSE)
- {
- UpdateImage(hWnd); // CAMERA CODE
- }
- else {
- SkipFrame=FALSE;
- }
- break;
-
- case WM_PAINT:
- /*
- * Redraw the image on the desktop.
- */
- WinQueryWindowRect(hWnd,&rctlClient);
- hps=WinBeginPaint(hWnd,NULLHANDLE,&rctlClient);
- if (hpsFrame!=NULLHANDLE)
- {
- /*
- * Setup the points array.
- */
- ulPoints[0].x=0;
- ulPoints[0].y=0;
- ulPoints[1].x=FrameWidth;
- ulPoints[1].y=FrameHeight;
- ulPoints[2].x=0;
- ulPoints[2].y=0;
- ulPoints[3].x=FrameWidth;
- ulPoints[3].y=FrameHeight;
-
- /*
- * Blast the image to the screen.
- */
- if (GpiBitBlt(hps,hpsFrame,4L,ulPoints,
- ROP_SRCCOPY,BBO_IGNORE)!=GPI_OK)
- {
- FormatMsgBox(HWND_DESKTOP,
- "Bitmap Copy Failed.");
- }
- }
- WinEndPaint(hps);
- break;
-
- case WM_ERASEBACKGROUND:
- /*
- * Don't do anything.
- */
- mReturn=MRFROMLONG(1L);
- break;
-
- default:
- /*
- * Let default processing take place.
- */
- bHandled=FALSE;
- break;
- }
-
- /*
- * If nothing was done, call the default processor.
- */
- if (!bHandled)
- {
- mReturn=WinDefWindowProc(hWnd,msg,mp1,mp2);
- }
- return (mReturn);
- }
-
-
- /*
- * Get the first image from the camera.
- */
- void GetImage(HWND hWnd)
- {
- HPS hps=WinGetPS(hWnd);
-
- /*
- * Get a frame buffer from the camera with the initial image.
- */
- if ((hpsFrame=GetFrame(hps,habMain))!=0) // CAMERA CODE!!!
- {
- /*
- * Post a message to the caller's queue that image has been
- * updated.
- */
- WinPostMsg(hWnd,WM_USER_UPDATE,0L,0L);
- }
-
- WinReleasePS(hps);
- }
-
-
- /*
- * Update with the next image from the camera.
- */
- void UpdateImage(HWND hWnd)
- {
- /*
- * Obtain the semaphore to ensure that we are not doing an update
- * already. If the semaphore is not available within 10ms do not
- * start another update.
- */
- if (DosRequestMutexSem(hmtxPS,10L)==0)
- {
- /*
- * Have to sepaphore, so its OK to grab the next frame from
- * the camera.
- */
- if (UpdateFrame()==QCAM_OK) // CAMERA CODE!!!
- {
- /*
- * Post a message to the caller's queue that image
- * has been updated.
- */
- WinPostMsg(hWnd,WM_USER_UPDATE,0L,0L);
- }
-
- /*
- * OK to give up the semaphore now.
- */
- DosReleaseMutexSem(hmtxPS);
- }
- else {
- /*
- * PC can't keep up so slow it down a bit.
- */
- SkipFrame=TRUE;
- }
- }
-
-
- /*
- * This is a handy function for displaying messages.
- */
- LONG FormatMsgBox(HWND hwnd_PO, PSZ Format_String, ...)
- {
- va_list Arg_List;
- PVOID Buffer_Pointer;
- PSZ String_Buffer;
- LONG Item_Count;
- LONG Return_Code;
-
- Return_Code=DosAllocMem(&Buffer_Pointer,1024,fALLOC);
-
- if (Return_Code != 0)
- {
- return 0L;
- }
-
- String_Buffer=(PSZ) Buffer_Pointer;
- va_start(Arg_List,Format_String);
- Item_Count=vsprintf(String_Buffer,Format_String,Arg_List);
-
- WinMessageBox(HWND_DESKTOP,hwnd_PO,String_Buffer,
- " ",
- 1001, ( MB_OK | MB_NOICON | MB_MOVEABLE ));
-
- if (!Return_Code)
- {
- DosFreeMem(Buffer_Pointer);
- }
- return Item_Count;
- }
-
-
- /*=============================================================================
- *
- * Camera specific functions follow.
- *
- *===========================================================================*/
-
- /*
- * If the device driver can be "opened" initialize tha camera to its
- * default settings.
- */
- USHORT InitCamera(void)
- {
- /*
- * Attempt to "open" the QuickCam device driver.
- */
- RC=DosOpen(QCAM_OPEN_NAME, // Device driver name
- &CamHandle, // Pointer to handle
- &OpenAction, // Pointer to open action
- QCAM_OPEN_SIZE, // Not required
- QCAM_OPEN_ATTRIBUTE, // Not Required
- QCAM_OPEN_FLAG, // Open device
- QCAM_OPEN_MODE, // Fail on error
- QCAM_OPEN_EABUF); // No extended attributes
-
- if (RC!=0)
- {
- /*
- * Open failed.
- */
- return QCAM_ERROR;
- }
-
- /*
- * Send the initialize command. This will return the camera settings
- * in the QcamSetup structure.
- */
- QcamRequest=QCAM_INITIALIZE;
- RC=DosDevIOCtl(CamHandle,
- QCAM_IOCTL_CATEGORY, // Category used for Qcam
- QCAM_IOCTL_SET_CAMERA, // Set camera function
- &QcamRequest, // Operations to do
- sizeof(USHORT), // Size of the request var.
- &ParmRetLen, // Not used
- &QcamSetup, // Settings struct. address
- sizeof(QCAM_SETTINGS), // Size of settings struct.
- &BufRetLen); // Not used
-
- if (RC!=0)
- {
- FormatMsgBox(HWND_DESKTOP,"Initialize Camera Failed [%4x].",RC);
- return QCAM_ERROR;
- }
-
- /*
- * Make sure camera is in EVERY_PIXEL transfer mode.
- */
- if (QcamSetup.transfer_mode!=QCAM_EVERY_PIXEL)
- {
- if (SetCameraTransferMode(QCAM_EVERY_PIXEL)==QCAM_ERROR)
- {
- return QCAM_ERROR;
- }
- }
-
- /*
- * Make sure the camera is in 6-bits per pixel mode.
- */
- if (QcamSetup.depth!=QCAM_DEPTH_64GRAYS)
- {
- if (SetCameraPixelDepth(QCAM_DEPTH_64GRAYS)==QCAM_ERROR)
- {
- return QCAM_ERROR;
- }
- }
-
- /*
- * Set the brightness to the default value.
- */
- if (SetCameraBrightness(Brightness)==QCAM_ERROR)
- {
- return QCAM_ERROR;
- }
-
- /*
- * Set the contrast to the default value.
- */
- if (SetCameraContrast(QCAM_DEF_CONTRAST)==QCAM_ERROR)
- {
- return QCAM_ERROR;
- }
-
- /*
- * Initialize went OK.
- */
- return QCAM_OK;
- }
-
-
- /*
- * Allocate a maximally size frame buffer and fill it with an image
- * from the camera.
- */
- HBITMAP GetFrame(HPS hps,HAB hab)
- {
- SIZEL size;
- HBITMAP hbm;
- UCHAR i;
-
- /*
- * Allocate a buffer for the frame data.
- */
- RC=DosDevIOCtl(CamHandle,
- QCAM_IOCTL_CATEGORY,
- QCAM_IOCTL_ALLOC_BUF,
- &BufLength,
- sizeof(ULONG),
- &ParmRetLen,
- &BufAddress,
- sizeof(UCHAR *),
- &BufRetLen);
- if (RC!=0)
- {
- /*
- * Allocate failed.
- */
- return NULL;
- }
-
- /*
- * Fill the buffer allocated with an image from the camera.
- */
- RC=DosDevIOCtl(CamHandle,
- QCAM_IOCTL_CATEGORY, // Category used for Qcam
- QCAM_IOCTL_GET_FRAME, // Get frame function
- &BufLength, // Return frame size here
- sizeof(ULONG), // Size of FrameLength variable
- &ParmRetLen, // Not used
- &BufAddress, // Buffer pointer address
- sizeof(UCHAR *), // Size of BufAddress pointer
- &BufRetLen); // Not used
- if (RC!=0)
- {
- /*
- * Read failed.
- */
- return NULL;
- }
-
- /*
- * Open a memory Device Context and create a Presentation Space
- * associated with it.
- */
- size.cx=0;
- size.cy=0;
- hdcMemory=DevOpenDC(hab,OD_MEMORY,"*",0L,NULL,0L);
- hpsMemory=GpiCreatePS(hab,hdcMemory,&size,
- PU_PELS|GPIF_DEFAULT|GPIT_MICRO|GPIA_ASSOC);
-
- /*
- * Create a bitmap in the memory presentation space.
- */
- memset(&BitmapNew,0,sizeof(BITMAPINFOHEADER2));
- BitmapNew.cbFix=sizeof(BITMAPINFOHEADER2);
- BitmapNew.cx=320;
- BitmapNew.cy=240;
- BitmapNew.cPlanes=1;
- BitmapNew.cBitCount=8;
- hbm=GpiCreateBitmap(hps,&BitmapNew,0L,NULL,NULL);
-
- /*
- * Select bitmap into the memory presentation space.
- */
- GpiSetBitmap(hpsMemory,hbm);
-
- /*
- * Set bitmap bits from the camera.
- */
- memset(&Bitmap.Header,0,sizeof(BITMAPINFOHEADER2));
- Bitmap.Header.cbFix=sizeof(BITMAPINFOHEADER2);
- Bitmap.Header.cx=320;
- Bitmap.Header.cy=240;
- Bitmap.Header.cPlanes=1;
- Bitmap.Header.cBitCount=8;
- Bitmap.Header.cclrUsed=64;
- for (i=0; i<QCAM_MAX_PALETTE; i++)
- {
- /*
- * Create an evenly distributed 64-grays palette.
- */
- Bitmap.Palette[QCAM_MAX_PALETTE-1-i].fcOptions=0;
- Bitmap.Palette[QCAM_MAX_PALETTE-1-i].bRed=i<<2;
- Bitmap.Palette[QCAM_MAX_PALETTE-1-i].bGreen=i<<2;
- Bitmap.Palette[QCAM_MAX_PALETTE-1-i].bBlue=i<<2;
- }
- GpiSetBitmapBits(hpsMemory,0L,240L,BufAddress,(PBITMAPINFO2)&Bitmap);
-
- /*
- * Return the handle to the memory presentation space created.
- */
- return hpsMemory;
- }
-
-
- /*
- * Update the image in the frame buffer.
- */
- USHORT UpdateFrame(void)
- {
- /*
- * Fill the buffer allocated with the next image from the camera.
- */
- RC=DosDevIOCtl(CamHandle,
- QCAM_IOCTL_CATEGORY, // Category used for Qcam
- QCAM_IOCTL_GET_FRAME, // Get frame function
- &BufLength, // Return frame size here
- sizeof(ULONG), // Size of FrameLength variable
- &ParmRetLen, // Not used
- &BufAddress, // Buffer pointer address
- sizeof(UCHAR *), // Size of BufAddress pointer
- &BufRetLen); // Not used
- if (RC==0)
- {
- /*
- * Update the bitmap with the next image.
- */
- GpiSetBitmapBits(hpsMemory,0L,FrameHeight,
- BufAddress,(PBITMAPINFO2)&Bitmap);
- return QCAM_OK;
- }
-
- return QCAM_ERROR;
- }
-
-
- /*
- * Free the frame and close the device.
- */
- void TermCamera(void)
- {
- DosDevIOCtl(CamHandle,
- QCAM_IOCTL_CATEGORY, // Category used for Qcam
- QCAM_IOCTL_FREE_BUF, // Free buffer function
- &BufLength, // Return frame size here
- sizeof(ULONG), // Size of FrameLength variable
- &ParmRetLen, // Not used
- &BufAddress, // Buffer address
- sizeof(UCHAR *), // Size of BufAddress pointer
- &BufRetLen); // Not used
-
- DosClose(CamHandle);
- }
-
-
- /*
- * Adjust the camera brightness.
- */
- USHORT SetCameraBrightness(UCHAR brightness)
- {
- QcamRequest=QCAM_SET_EXPOSURE;
- QcamSetup.exposure=brightness;
- RC=DosDevIOCtl(CamHandle,
- QCAM_IOCTL_CATEGORY, // Category used for Qcam
- QCAM_IOCTL_SET_CAMERA, // Set camera function
- &QcamRequest, // Operations to do
- sizeof(USHORT), // Size of the request variable
- &ParmRetLen, // Not used
- &QcamSetup, // Settings structure address
- sizeof(QCAM_SETTINGS), // Size of settings structure
- &BufRetLen); // Not used
- if (RC!=0)
- {
- FormatMsgBox(HWND_DESKTOP,"Set Brightness Failed [%4x].",RC);
- return QCAM_ERROR;
- }
- /*
- * Set brightness went OK.
- */
- return QCAM_OK;
- }
-
-
- /*
- * Adjust the camera contrast.
- */
- USHORT SetCameraContrast(UCHAR contrast)
- {
- QcamRequest=QCAM_SET_CONTRAST;
- QcamSetup.contrast=contrast;
- RC=DosDevIOCtl(CamHandle,
- QCAM_IOCTL_CATEGORY, // Category used for Qcam
- QCAM_IOCTL_SET_CAMERA, // Set camera function
- &QcamRequest, // Operations to do
- sizeof(USHORT), // Size of the request variable
- &ParmRetLen, // Not used
- &QcamSetup, // Settings structure address
- sizeof(QCAM_SETTINGS), // Size of settings structure
- &BufRetLen); // Not used
- if (RC!=0)
- {
- FormatMsgBox(HWND_DESKTOP,"Set Contrast Failed [%4x].",RC);
- return QCAM_ERROR;
- }
- /*
- * Set contrast went OK.
- */
- return QCAM_OK;
- }
-
-
- /*
- * Set the camera transfer mode.
- */
- USHORT SetCameraTransferMode(UCHAR mode)
- {
- QcamRequest=QCAM_SET_TRANS_MODE;
- QcamSetup.transfer_mode=mode;
- RC=DosDevIOCtl(CamHandle,
- QCAM_IOCTL_CATEGORY, // Category used for Qcam
- QCAM_IOCTL_SET_CAMERA, // Set camera function
- &QcamRequest, // Operations to do
- sizeof(USHORT), // Size of the request variable
- &ParmRetLen, // Not used
- &QcamSetup, // Settings structure address
- sizeof(QCAM_SETTINGS), // Size of settings structure
- &BufRetLen); // Not used
- if (RC!=0)
- {
- FormatMsgBox(HWND_DESKTOP,"Set Transfer Mode Failed [%4x].",RC);
- return QCAM_ERROR;
- }
- /*
- * Set transfer mode went OK.
- */
- return QCAM_OK;
- }
-
-
- /*
- * Set the camera pixel depth.
- */
- USHORT SetCameraPixelDepth(UCHAR depth)
- {
- QcamRequest=QCAM_SET_DEPTH;
- QcamSetup.depth=depth;
- RC=DosDevIOCtl(CamHandle,
- QCAM_IOCTL_CATEGORY, // Category used for Qcam
- QCAM_IOCTL_SET_CAMERA, // Set camera function
- &QcamRequest, // Operations to do
- sizeof(USHORT), // Size of the request variable
- &ParmRetLen, // Not used
- &QcamSetup, // Settings structure address
- sizeof(QCAM_SETTINGS), // Size of settings structure
- &BufRetLen); // Not used
- if (RC!=0)
- {
- FormatMsgBox(HWND_DESKTOP,"Set Depth Failed [%4x].",RC);
- return QCAM_ERROR;
- }
- /*
- * Set depth went OK.
- */
- return QCAM_OK;
- }
-