home *** CD-ROM | disk | FTP | other *** search
- /******************************************************************************
- * *
- * Name: MMINK.C *
- * *
- * Copyright : COPYRIGHT IBM CORPORATION, 1993 *
- * LICENSED MATERIAL - PROGRAM PROPERTY OF IBM *
- * *
- * Description: This program loads a predefined bitmap in client window and *
- * allows user to record the audio synchronized with stroke *
- * data. Also allows to play it back. *
- * *
- * Execution Instruction: MMINK *
- * *
- * Hardware Requirement: Audio I/O device. *
- * *
- * Software Requirement: IBM OS/2 V2.1, Pen for OS/2 V1.0, and MMPM/2 V1.1 *
- * *
- * Subroutine Names and their function: *
- * *
- * main : main drive routine *
- * *
- * ClientWinProc : Client window procedure which has a bitmap in client *
- * area and handles the annotation menu item. *
- * *
- * AudioDlgProc: Audio dialog procedure which handles the recording and *
- * playing back of the recorded voice and strokes. *
- * *
- * DISCLAIMER OF WARRANTIES. The following [enclosed] code is *
- * sample code created by IBM Corporation. This sample code is not *
- * part of any standard or IBM product and is provided to you solely *
- * for the purpose of assisting you in the development of your *
- * applications. The code is provided "AS IS", without *
- * warranty of any kind. IBM shall not be liable for any damages *
- * arising out of your use of the sample code, even if they have been *
- * advised of the possibility of such damages. *
- * *
- ******************************************************************************/
-
- /******************************************************************************
- * Note: You may notice slow inking during the recording of audio and ink on *
- * slower machines. This is a result of MMINK being designed as a single *
- * threaded application. Performance should improve by modifying the *
- * application to use a multi-threaded model. The choice of a single thread *
- * was made in order to increase the readability and simplicity the source *
- * code. *
- ******************************************************************************/
-
- #define INCL_WIN
- #define INCL_ERRORS
- #define INCL_GPI
- #define INCL_DOS
- #define INCL_CIRCULARSLIDER
- #include <os2.h>
- #include <string.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <os2me.h>
- #include <penpm.h>
- #include <sw.h>
- #include "mmink.h"
-
- /*****************************************************************************
- * *
- * Subroutine Name : main *
- * *
- * Function: Main procedure to create the client window, process the window *
- * messages, and exits the program. *
- * *
- * Parameters: None. *
- * *
- *****************************************************************************/
- VOID main(VOID)
- {
- ULONG flFrameFlags = FCF_SIZEBORDER | FCF_MINMAX | FCF_TITLEBAR |
- FCF_ICON | FCF_MENU | FCF_TASKLIST;
- QMSG qmsg;
- HMQ hmq;
- USHORT i;
- CHAR achClass[] = "MMINK";
-
- hab = WinInitialize(0UL);
- hmq = WinCreateMsgQueue(hab, 0);
-
- WinRegisterClass(hab,
- achClass,
- ClientWinProc,
- CS_SYNCPAINT,
- 0);
-
- hwndFrame = WinCreateStdWindow(HWND_DESKTOP,
- WS_VISIBLE,
- &flFrameFlags,
- achClass,
- NULL,
- 0UL,
- 0UL,
- ID_MMINK,
- &hwndClient);
-
- WinSetWindowPos(hwndFrame,
- HWND_TOP,
- (WinQuerySysValue(HWND_DESKTOP, SV_CXSCREEN) - CLIENTCX) / 2,
- (WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN) - CLIENTCY) / 2,
- CLIENTCX,
- CLIENTCY,
- SWP_SIZE | SWP_MOVE | SWP_ACTIVATE | SWP_SHOW);
-
- /************************************************************************
- * When the modeless Audio dialog window ends, it makes the WinGetMsg *
- * false. So, add a flag which is TRUE when user clicks Exit menu item. *
- ************************************************************************/
- while (!fFinish)
- {
- while (WinGetMsg(hab, &qmsg, 0UL, 0UL, 0UL))
- WinDispatchMsg( hab, &qmsg );
- }
-
- WinDestroyWindow(hwndFrame);
- WinDestroyMsgQueue( hmq );
- WinTerminate( hab );
- DosExit(1, 0);
- }
-
- /*****************************************************************************
- * *
- * Subroutine Name : ClientWinProc *
- * *
- * Function: Window procedure of the main client window. *
- * Process all messages and menu items in this window. *
- * *
- * Parameters: HWND hwnd *
- * ULONG msg *
- * MAPRAM mp1 *
- * MPARAM mp2 *
- * *
- * Pen message processed: WM_RECO *
- * *
- *****************************************************************************/
- MRESULT EXPENTRY ClientWinProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
- {
- CHAR err[80];
- static HDC hdc;
- static HPS hpsMem;
- HPS hps;
- static HBITMAP hbm;
- static BITMAPINFOHEADER2 bmhData;
- static SIZEL sizel;
- POINTL aptl[4];
- RECTL rcl;
- static LONG lCx, lCy;
-
- switch (msg)
- {
- case WM_CREATE:
- /*******************************************************************
- * . Get the menu handle to enable/disable the ANNOTATE menu item *
- * . Get the memory device context, create the presentation space, *
- * and load predefined bitmap. *
- * . Get the bitmap information. *
- *******************************************************************/
- hwndMenu = WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT),
- FID_MENU);
- hdc = DevOpenDC(hab,
- OD_MEMORY,
- "*", /* No device info */
- 0L,
- (PDEVOPENDATA) NULL,
- NULLHANDLE);
-
- sizel.cx = sizel.cy = 0;
- hpsMem = GpiCreatePS(hab,
- hdc,
- &sizel,
- PU_PELS | GPIT_MICRO | GPIA_ASSOC | GPIF_DEFAULT);
-
- hbm = GpiLoadBitmap(hpsMem,
- NULLHANDLE,
- IDB_MMINK,
- 0L, /* NO stretch in X and Y direction */
- 0L);
- GpiSetBitmap(hpsMem, hbm);
-
- /* Get the bitmap information */
- bmhData.cbFix = sizeof(bmhData);
- GpiQueryBitmapInfoHeader(hbm, &bmhData);
- sizel.cx = bmhData.cx;
- sizel.cy = bmhData.cy;
- return FALSE;
-
- case WM_SIZE:
- if ( hwndAudio )
- {
- WinSendMsg ( hwndAudio, WM_COMMAND, (MPARAM) AUDIOCTL_STOP, (MPARAM) 0 );
- };
- lCx = SHORT1FROMMP(mp2);
- lCy = SHORT2FROMMP(mp2);
- if ( hwndInk )
- {
- WinQueryWindowRect ( hwnd, &rcl );
- WinSetWindowPos ( hwndInk,
- HWND_TOP,
- 0,
- 0,
- rcl.xRight,
- rcl.yTop,
- SWP_MOVE | SWP_SIZE );
- }
- else
- WinInvalidateRect ( hwnd, NULL, TRUE );
- return FALSE;
-
- case WM_PAINT:
- {
- RECTL rctl;
-
- hps = WinBeginPaint(hwnd, (ULONG) NULL, (PRECTL) &rctl);
-
- /* Target coordinate */
- aptl[0].x = rctl.xLeft;
- aptl[0].y = rctl.yBottom;
- aptl[1].x = rctl.xRight;
- aptl[1].y = rctl.yTop;
-
- /* Source Coordinate */
- aptl[2].x = rctl.xLeft * sizel.cx / lCx;
- aptl[2].y = rctl.yBottom * sizel.cy / lCy;
- aptl[3].x = rctl.xRight * sizel.cx / lCx;
- aptl[3].y = rctl.yTop * sizel.cy / lCy;
-
- GpiBitBlt(hps,
- hpsMem,
- 4L,
- aptl,
- ROP_SRCCOPY,
- BBO_IGNORE);
-
- WinEndPaint(hps);
- return FALSE;
- }
-
- case WM_RECO:
- {
- RECODATA rcData;
-
- /******************************************************************
- * Process the uppercase 'A' gesture as if the Annotate menu item *
- * is selected. *
- ******************************************************************/
- rcData = * (RECODATA *) PVOIDFROMMP(mp2);
- if ((rcData.virtual_id == VIRTUAL_ID) && (rcData.char_code == UPPERA))
- {
- WinPostMsg(hwnd, WM_COMMAND, MPFROMSHORT(IDM_ANNOT), NULL);
- return((MRESULT) RECO_PROCESSED);
- }
- return(FALSE);
- }
-
- case WM_COMMAND:
- switch(SHORT1FROMMP(mp1))
- {
- case IDM_ANNOT:
- /*************************************************************
- * Disable this menu item, it will be enabled later when the *
- * dialog box is closed. *
- *************************************************************/
- WinSendMsg(hwndMenu,
- MM_SETITEMATTR,
- MPFROM2SHORT(IDM_ANNOT, TRUE),
- MPFROM2SHORT(MIA_DISABLED, MIA_DISABLED));
-
- hwndInk = InitTimedInk(hwnd, &CurrMMTime);
- if ( !hwndInk )
- {
- SetText(hwnd, err, "Failed to initialize timed Ink.",
- "Errors", 0,
- (ULONG) MB_ERROR | MB_OK, TRUE);
- WinPostMsg(hwnd, WM_CLOSE, NULL, NULL);
- }
- else
- hwndAudio = WinLoadDlg(HWND_DESKTOP,
- hwnd,
- AudioDlgProc,
- 0UL,
- IDD_AUDIO,
- 0UL);
- return FALSE;
-
- case IDM_EXIT:
- fFinish = TRUE;
- WinPostMsg(hwnd, WM_CLOSE, NULL, NULL);
- return FALSE;
- }
- return FALSE;
-
- case WM_CLOSE:
- GpiDestroyPS(hpsMem);
- DevCloseDC(hdc);
- GpiDeleteBitmap(hbm);
- break;
-
- default:
- break;
-
- } /* end of switch */
-
- return(WinDefWindowProc(hwnd, msg, mp1, mp2));
- }
-
- /*****************************************************************************
- * *
- * Subroutine Name : SetText *
- * *
- * Function: Error message is given in a message box if fMessage is TRUE. *
- * This function put a text and number in ASCII in an array *
- * so that the sprintf C function is not used. *
- * *
- * Parameters: HWND hwnd *
- * PSZ pszArray:arrary which will have the error message *
- * PSZ pszStr: error message *
- * PSZ pszTitle: title of the message box *
- * ULONG ulRc: error code *
- * ULONG ulFlags: flags for the message box *
- * BOOL fMessage: give message box or not *
- * *
- * All parameters are input. *
- * *
- *****************************************************************************/
- VOID SetText(HWND hwnd, PSZ pszArray, PSZ pszStr, PSZ pszTitle, ULONG ulRc,
- ULONG ulFlags, BOOL fMessage)
- {
- PSZ pszTemp;
-
- strcpy(pszArray, pszStr);
- pszTemp = pszArray + strlen(pszArray);
- _itoa(ulRc, pszTemp, 10);
- *(pszTemp + 3) = '\0';
-
- if (fMessage)
- {
- WinMessageBox(HWND_DESKTOP,
- hwnd,
- pszArray,
- pszTitle,
- 0,
- ulFlags);
- }
-
- }
-
- /*****************************************************************************
- * *
- * Subroutine Name : AudioDlgProc *
- * *
- * Function: Window procedure of the audio dialog window. *
- * Process all messages and button messages in this window. *
- * *
- * Parameters: HWND hwnd *
- * ULONG msg *
- * MAPRAM mp1 *
- * MPARAM mp2 *
- * *
- *****************************************************************************/
- MRESULT EXPENTRY AudioDlgProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
- {
- static SHORT sAudioLevel = 100;
- static USHORT usTotTime = 0;
- static SBCDATA sbc = { 14, 0, 0, 100, 50, 1, 100 };
- static BTNCDATA bBut;
- SHORT rc;
- CHAR err[80];
- HPS hps;
- static SHORT currentMode = IDLE_MODE;
- ULONG ulReturn, i;
- static USHORT usPos = 0;
- USHORT usNotifyCode; /* notification message code */
- SHORT sWmControlID; /* WM_CONTROL id */
- USHORT usTime; /* Duration and Elapsed Time in second */
-
- switch (msg)
- {
- case WM_COMMAND:
- {
- switch (SHORT1FROMMP(mp1))
- {
- case AUDIOCTL_PLAY:
- /******************************************************************
- * User clicks the PLAY button after recording. *
- * If any old stroke in window, erase it. *
- * Acquire the audio device. *
- * Play the recorded audio data. *
- * For stroke data, convert sensor resolution to screen resolution*
- * Enable STOP buttons and disable the other buttons. *
- ******************************************************************/
- {
- PSTROKEDATA pStroke;
-
- if (ulReturn = mmsrvAcquire())
- {
- SetText(hwnd, err, "Error during Acquire, rc = ",
- "MMPM/2 Error", ulReturn,
- (ULONG) MB_ERROR | MB_OK, TRUE);
- return FALSE;
- }
-
- if (ulReturn = mmsrvPlay(hwnd))
- {
- SetText(hwnd, err, "Error during Playback, rc = ",
- "Audio Error", ulReturn,
- (ULONG) MB_ERROR | MB_OK, TRUE);
- return FALSE;
- }
-
- usPos = 0;
- currentMode = PLAYING_MODE;
-
- PlayTimedInk ( hwndInk );
- WinSetDlgItemText(hwnd,
- AUDIOCTL_INFO,
- "Playing voice & handwriting.");
-
- /***********************************************************
- * Disable the PLAY and RECORD buttons but enable STOP but *
- ***********************************************************/
- WinEnableWindow(WinWindowFromID(hwnd, AUDIOCTL_PLAY), FALSE);
- WinEnableWindow(WinWindowFromID(hwnd, AUDIOCTL_REC), FALSE);
- WinEnableWindow(WinWindowFromID(hwnd, AUDIOCTL_STOP), TRUE);
- break;
- } /* of case AUDIOCTL_PLAY */
-
- case AUDIOCTL_REC:
- /******************************************************************
- * User clicks the RECORD button. *
- * If any old stroke in window, erase it. *
- * Acquire the audio device. *
- * Record the audio data. *
- * Enable STOP buttons and disable the other buttons. *
- ******************************************************************/
- {
- if (ulReturn = mmsrvAcquire())
- {
- SetText(hwnd, err, "Error during Acquire, rc = ",
- "MMPM/2 Error", ulReturn,
- (ULONG) MB_ERROR | MB_OK, TRUE);
- return FALSE;
- }
-
- if (ulReturn = mmsrvRecord(hwnd))
- {
- SetText(hwnd, err, "Error during Recording, rc = ",
- "Audio Error", ulReturn,
- (ULONG) MB_ERROR | MB_OK, TRUE);
- return FALSE;
- }
- usPos = 0;
- currentMode = RECORDING_MODE;
- WinSetDlgItemText(hwnd,
- AUDIOCTL_INFO,
- "Recording voice & handwriting.");
-
- RecordTimedInk(hwndInk);
-
- /************************************************************
- * Enable the STOP button, but disables the PLAY and RECORD *
- * buttons. *
- ************************************************************/
- WinEnableWindow(WinWindowFromID(hwnd, AUDIOCTL_STOP), TRUE);
- WinEnableWindow(WinWindowFromID(hwnd, AUDIOCTL_REC), FALSE);
- WinEnableWindow(WinWindowFromID(hwnd, AUDIOCTL_PLAY), FALSE);
- break;
- } /* of case AUDIOCTL_REC */
-
- case AUDIOCTL_STOP:
- /******************************************************************
- * User clicks the STOP button while recording or playing. *
- * Depending upon the mode (playing or recording), set correct *
- * text in INFO field of dialog box. *
- * Stop recording/playing auiod data. *
- ******************************************************************/
- {
- StopTimedInk(hwndInk);
- switch (currentMode)
- {
- case RECORDING_MODE:
- {
- WinSetDlgItemText(hwnd,
- AUDIOCTL_INFO,
- "Stopping voice/pen recording.");
- break;
- } /* of case RECORDING_MODE */
-
- case PLAYING_MODE:
- {
- WinSetDlgItemText(hwnd,
- AUDIOCTL_INFO,
- "Stopping voice/pen playback.");
- break;
- } /* of case PLAYING_MODE */
- } /* of switch(currentMode) */
-
- (void) mmsrvStop();
- currentMode = IDLE_MODE;
- break;
-
- } /* of case AUDIOCTL_STOP */
- } /* of switch(SHORT1FROMMP(mp1)) */
- return FALSE;
- } /* of case WM_COMMAND */
-
- case MM_MCINOTIFY:
- /*********************************************************************
- * This message is sent from MMPM/2 system when the MMPM/2 device *
- * successfully completes the action indicated by media message or *
- * when an error occurs. * *
- *********************************************************************/
- {
- USHORT usNotifyCode;
- USHORT usReceivedMessage;
-
- StopTimedInk ( hwndInk );
-
- usNotifyCode = SHORT1FROMMP(mp1);
- usReceivedMessage = SHORT2FROMMP(mp2);
- WinSetDlgItemText(hwnd,
- AUDIOCTL_ELAP,
- "Elapsed: 0");
- WinSetDlgItemText(hwnd,
- AUDIOCTL_INFO,
- "");
- if (usNotifyCode == MCI_NOTIFY_SUCCESSFUL
- || usNotifyCode == MCI_NOTIFY_SUPERSEDED
- || usNotifyCode == MCI_NOTIFY_ABORTED)
- {
- if (ulReturn = mmsrvRelease())
- {
- SetText(hwnd, err, "Error during Release, rc = ",
- "MMPM/2 Error", ulReturn,
- (ULONG) MB_ERROR | MB_OK, TRUE);
- return FALSE;
- };
- if (usReceivedMessage == MCI_RECORD)
- {
- if (usPos == 0)
- WinEnableWindow(WinWindowFromID(hwnd, AUDIOCTL_PLAY),
- FALSE);
- else
- {
- usTime = usPos / 10;
- SetText(hwnd, err, "Duration: ",
- NULL, usTime,
- (ULONG) NULL, FALSE);
- WinSetDlgItemText(hwnd, AUDIOCTL_DUR, err);
- };
- };
- }
- else
- {
- SetText(hwnd, err, "Play/Record could not succeed",
- "Audio Error", 0,
- (ULONG) MB_ERROR | MB_OK, TRUE);
- }; /* of else */
-
- for (i = AUDIOCTL_PLAY; i < AUDIOCTL_STOP; i++)
- WinEnableWindow(WinWindowFromID(hwnd, i),
- TRUE);
-
- WinEnableWindow(WinWindowFromID(hwnd, AUDIOCTL_STOP),
- FALSE);
- return FALSE;
- } /* of case MM_MCINOTIFY */
-
- /**********************************************************************
- * This message is sent from multi media device for every one tenth *
- * second while audio data is played or recorded. This one tenth of *
- * time interval was done in mmsrvOpen(). *
- **********************************************************************/
- case MM_MCIPOSITIONCHANGE:
- {
- usPos++;
- usTime = usPos / 10;
-
- switch (currentMode)
- {
- case RECORDING_MODE:
- {
- SetText(hwnd, err, "Duration: ",
- NULL, usTime,
- (ULONG) NULL, FALSE);
- WinSetDlgItemText(hwnd, AUDIOCTL_DUR, err);
-
- SetText(hwnd, err, "Elapsed: ",
- NULL, usTime,
- (ULONG) NULL, FALSE);
- WinSetDlgItemText(hwnd, AUDIOCTL_ELAP, err);
- CurrMMTime = (MMTIME) mp2;
- break;
- }
-
- case PLAYING_MODE:
- {
- SetText(hwnd, err, "Duration: ",
- NULL, usTime,
- (ULONG) NULL, FALSE);
- WinSetDlgItemText(hwnd, AUDIOCTL_DUR, err);
- SetText(hwnd, err, "Elapsed: ",
- NULL, usTime,
- (ULONG) NULL, FALSE);
- WinSetDlgItemText(hwnd, AUDIOCTL_ELAP, err);
-
- CurrMMTime = (MMTIME) mp2;
- InkTimedInk ( hwndInk, (MMTIME) mp2 );
-
- break;
- }
- } /* end of switch(currentMode) */
- return FALSE;
- } /* of case MM_MCIPOSITIONCHANGE */
-
- case WM_HSCROLL:
- {
- switch (SHORT2FROMMP(mp2))
- {
- case SB_LINELEFT:
- sAudioLevel = max(0, sAudioLevel - 1);
- break;
-
- case SB_LINERIGHT:
- sAudioLevel = min(100, sAudioLevel + 1);
- break;
-
- case SB_PAGELEFT:
- sAudioLevel = max(0, sAudioLevel - 10);
- break;
-
- case SB_PAGERIGHT:
- sAudioLevel = min(100, sAudioLevel + 10);
- break;
-
- case SB_SLIDERTRACK:
- sAudioLevel = SHORT1FROMMP(mp2);
- break;
-
- case SB_ENDSCROLL:
- case SB_SLIDERPOSITION:
- mmsrvSetVolume((USHORT) sAudioLevel);
- return FALSE;
- } /* of switch(SHORT2FROMMP... */
-
- WinSendDlgItemMsg(hwnd,
- AUDIOCTL_SCRL,
- SBM_SETPOS,
- MPFROMSHORT(sAudioLevel),
- NULL);
-
- SetText(hwnd, err, "Volume: ",
- NULL, sAudioLevel,
- (ULONG) NULL, FALSE);
- WinSetDlgItemText(hwnd, AUDIOCTL_VOL, err);
- return FALSE;
-
- } /* of case WM_HSCROLL */
-
-
- case WM_INITDLG:
- {
- HWND hwndVol;
-
- fAudioAvail = TRUE;
-
- /* volume control scroll bar
- WinCreateWindow(hwnd,
- WC_SCROLLBAR,
- NULL,
- WS_VISIBLE | WS_SYNCPAINT | SBS_HORZ,
- (ANWINSIZE / 2),
- 38,
- (ANWINSIZE - 20) / 2,
- 18,
- hwnd,
- HWND_TOP,
- AUDIOCTL_SCRL,
- &sbc,
- NULL); */
-
- /* give slider position */
- WinSendDlgItemMsg(hwnd,
- AUDIOCTL_SCRL,
- SBM_SETPOS,
- MPFROMSHORT(sAudioLevel),
- NULL);
-
- /* Initial setup for recording */
- currentMode = IDLE_MODE;
- usTotTime = 0;
-
- mmsrvOpen(hwnd);
-
- WinEnableWindow(WinWindowFromID(hwnd, AUDIOCTL_PLAY), FALSE);
- WinEnableWindow(WinWindowFromID(hwnd, AUDIOCTL_REC), TRUE);
- WinEnableWindow(WinWindowFromID(hwnd, AUDIOCTL_STOP), FALSE);
- return (FALSE);
- } /* of case WM_CREATE */
-
- case WM_CLOSE:
- {
- mmsrvClose();
- DestroyTimedInk ( hwndInk );
- fAudioActive = FALSE;
- WinSetFocus(HWND_DESKTOP, hwndClient);
-
- /*******************************************************************
- * Enable the Voice & Ink menu item. *
- *******************************************************************/
- WinSendMsg(hwndMenu,
- MM_SETITEMATTR,
- MPFROM2SHORT(IDM_ANNOT, TRUE),
- MPFROM2SHORT(MIA_DISABLED, FALSE));
-
- WinDestroyWindow(hwnd);
- return(FALSE);
- } /* of case WM_CLOSE */
- } /* of switch(msg) */
-
- return (WinDefDlgProc(hwnd, msg, mp1, mp2));
- }
-
-