Release 940706
Sun, 3 Jul 1994 20:15:56 +0100 (BST) David Metcalfe <david@prism.demon.co.uk>
* [controls/edit.c]
Bug fixes and tidying up. Preliminary tab stop support
(doesn't work yet).
* [windows/dialog.c]
Reversed order of buttons in CheckRadioButtons so that all
buttons are now displayed.
Tue Jul 5 18:30:24 1994 Alexandre Julliard (julliard@lamisun.epfl.ch)
* [include/options.h] [misc/main.c] [windows/win.c]
Removed nosaveunders option, replaced by handling
the CS_SAVEBITS flag.
* [windows/class.c]
Modified the fix for negative size in class extra bytes to
avoid modifying the caller's data.
* [windows/dc.c]
Bug fix: system font must be a proportional font.
Fixed a bug that caused the default pen to not be selected
correctly in a DC.
* [windows/graphics.c]
Bug fix in GRAPH_DrawArc(). Thanks to Adriano Azevedo for
noticing it.
* [windows/painting.c]
Removed incorrect selecting of default objects in BeginPaint()
(no longer needed because of the fix in dc.c).
Jul 4, 94 martin2@trgcorp.solucorp.qc.ca (Martin Ayotte)
* [misc/mmsystem.c]
* [misc/audio.c]
Add more code to interface '/dev/dsp'.
* New file [misc/mcicda.c]
Create an MCI_DEVTYPE_CD_AUDIO driver connected to '/dev/sbpcd'.
* New file [misc/mmaux.c]
Stubs to make a future driver connected to '/dev/mixer'.
* [windows/win.c]
Temporary patch to CreateWindowEx() for reseting negative
coordinates to 0,0 ; because 'soundrec.exe' give negative values
and I need it to work on MMSYSTEM ... :-)
* [miscemu/int2f.c]
add a stub 'do_int2f_16' (function 0x16) for DMPI server.
Mon Jun 20 10:08:40 BST 1994 William Smith (wos@dcs.warwick.ac.uk)
* include/comm.h
New file -- some definitions that were in comm.c now need to
be shared with misc/dos_fs.c
* misc/comm.c
Some definitions moved into include/comm.h
* misc/dos_fs.c (DOS_GetEquipment):
Fixed error in equipment -- bitwise or of two values should
be used instead of logical or. Also added code to correctly
report the number of serial and parallel devices.
diff --git a/ChangeLog b/ChangeLog
index 0e61684..adcba41 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,72 @@
----------------------------------------------------------------------
+Sun, 3 Jul 1994 20:15:56 +0100 (BST) David Metcalfe <david@prism.demon.co.uk>
+
+ * [controls/edit.c]
+ Bug fixes and tidying up. Preliminary tab stop support
+ (doesn't work yet).
+
+ * [windows/dialog.c]
+ Reversed order of buttons in CheckRadioButtons so that all
+ buttons are now displayed.
+
+Tue Jul 5 18:30:24 1994 Alexandre Julliard (julliard@lamisun.epfl.ch)
+
+ * [include/options.h] [misc/main.c] [windows/win.c]
+ Removed nosaveunders option, replaced by handling
+ the CS_SAVEBITS flag.
+
+ * [windows/class.c]
+ Modified the fix for negative size in class extra bytes to
+ avoid modifying the caller's data.
+
+ * [windows/dc.c]
+ Bug fix: system font must be a proportional font.
+ Fixed a bug that caused the default pen to not be selected
+ correctly in a DC.
+
+ * [windows/graphics.c]
+ Bug fix in GRAPH_DrawArc(). Thanks to Adriano Azevedo for
+ noticing it.
+
+ * [windows/painting.c]
+ Removed incorrect selecting of default objects in BeginPaint()
+ (no longer needed because of the fix in dc.c).
+
+Jul 4, 94 martin2@trgcorp.solucorp.qc.ca (Martin Ayotte)
+
+ * [misc/mmsystem.c]
+ * [misc/audio.c]
+ Add more code to interface '/dev/dsp'.
+
+ * New file [misc/mcicda.c]
+ Create an MCI_DEVTYPE_CD_AUDIO driver connected to '/dev/sbpcd'.
+
+ * New file [misc/mmaux.c]
+ Stubs to make a future driver connected to '/dev/mixer'.
+
+ * [windows/win.c]
+ Temporary patch to CreateWindowEx() for reseting negative
+ coordinates to 0,0 ; because 'soundrec.exe' give negative values
+ and I need it to work on MMSYSTEM ... :-)
+
+ * [miscemu/int2f.c]
+ add a stub 'do_int2f_16' (function 0x16) for DMPI server.
+
+Mon Jun 20 10:08:40 BST 1994 William Smith (wos@dcs.warwick.ac.uk)
+
+ * include/comm.h
+ New file -- some definitions that were in comm.c now need to
+ be shared with misc/dos_fs.c
+
+ * misc/comm.c
+ Some definitions moved into include/comm.h
+
+ * misc/dos_fs.c (DOS_GetEquipment):
+ Fixed error in equipment -- bitwise or of two values should
+ be used instead of logical or. Also added code to correctly
+ report the number of serial and parallel devices.
+
+----------------------------------------------------------------------
Mon Jun 20 14:26:41 1994 Bob Amstadt (bob@pooh)
* [objects/bitmap.c]
diff --git a/controls/edit.c b/controls/edit.c
index 3aff8f8..2a1c12c 100644
--- a/controls/edit.c
+++ b/controls/edit.c
@@ -67,6 +67,8 @@
int DeletedLength; /* length of deleted text */
int DeletedCurrLine; /* starting line from which text was deleted */
int DeletedCurrCol; /* starting col from which text was deleted */
+ int NumTabStops; /* number of tab stops in buffer hTabStops */
+ HANDLE hTabStops; /* handle of tab stops buffer */
} EDITSTATE;
@@ -79,6 +81,9 @@
#define CurrChar (EDIT_TextLine(hwnd, es->CurrLine) + es->CurrCol)
#define SelMarked(es) (es->SelBegLine != 0 || es->SelBegCol != 0 || \
es->SelEndLine != 0 || es->SelEndCol != 0)
+#define ROUNDUP(numer, denom) ((numer % denom) \
+ ? (((numer + denom) / denom) * denom) \
+ : numer)
/* macros to access window styles */
#define IsAutoVScroll() (wndPtr->dwStyle & ES_AUTOVSCROLL)
@@ -104,14 +109,16 @@
void EDIT_PaintMsg(HWND hwnd);
HANDLE EDIT_GetTextLine(HWND hwnd, int selection);
char *EDIT_TextLine(HWND hwnd, int sel);
-int EDIT_LineLength(EDITSTATE *es, char *str, int len);
+int EDIT_StrLength(EDITSTATE *es, char *str, int len, int pcol);
+int EDIT_LineLength(HWND hwnd, int num);
void EDIT_WriteTextLine(HWND hwnd, RECT *rc, int y);
void EDIT_WriteText(HWND hwnd, char *lp, int off, int len, int row,
int col, RECT *rc, BOOL blank, BOOL reverse);
HANDLE EDIT_GetStr(EDITSTATE *es, char *lp, int off, int len, int *diff);
void EDIT_CharMsg(HWND hwnd, WORD wParam);
void EDIT_KeyTyped(HWND hwnd, short ch);
-int EDIT_CharWidth(EDITSTATE *es, short ch);
+int EDIT_CharWidth(EDITSTATE *es, short ch, int pcol);
+int EDIT_GetNextTabStop(EDITSTATE *es, int pcol);
void EDIT_Forward(HWND hwnd);
void EDIT_Downward(HWND hwnd);
void EDIT_Upward(HWND hwnd);
@@ -162,6 +169,7 @@
void *EDIT_TextAddr(EDITSTATE *es, unsigned int handle);
unsigned int EDIT_TextReAlloc(EDITSTATE *es, unsigned int handle, int bytes);
void EDIT_SetHandleMsg(HWND hwnd, WORD wParam);
+LONG EDIT_SetTabStopsMsg(HWND hwnd, WORD wParam, LONG lParam);
void swap(int *a, int *b);
@@ -295,7 +303,7 @@
break;
case EM_SETTABSTOPS:
- printf("edit: cannot process EM_SETTABSTOPS message\n");
+ lResult = EDIT_SetTabStopsMsg(hwnd, wParam, lParam);
break;
case EM_SETWORDBREAKPROC:
@@ -451,7 +459,7 @@
/* --- text buffer */
es->localheap = &HEAP_LocalFindHeap(createStruct->hInstance)->free_list;
es->MaxTextLen = MAXTEXTLEN + 1;
- if (!(es->hText))
+ if (!(createStruct->lpszName))
{
es->textlen = EditBufLen(wndPtr) + 1;
es->hText = EDIT_TextAlloc(es, EditBufLen(wndPtr) + 2);
@@ -464,15 +472,18 @@
if (strlen(createStruct->lpszName) < EditBufLen(wndPtr))
{
es->hText = EDIT_TextAlloc(es, EditBufLen(wndPtr) + 2);
- es->textlen = EditBufLen(wndPtr) + 1;
+ text = EDIT_TextAddr(es, es->hText);
+ strcpy(text, createStruct->lpszName);
*(text + es->textlen) = '\0';
+ es->textlen = EditBufLen(wndPtr) + 1;
}
else
{
es->hText = EDIT_TextAlloc(es, strlen(createStruct->lpszName) + 2);
+ text = EDIT_TextAddr(es, es->hText);
+ strcpy(text, createStruct->lpszName);
es->textlen = strlen(createStruct->lpszName) + 1;
}
- text = EDIT_TextAddr(es, es->hText);
*(text + es->textlen + 1) = '\0';
EDIT_BuildTextPointers(hwnd);
}
@@ -524,6 +535,8 @@
es->hFont = 0;
es->hDeletedText = 0;
es->DeletedLength = 0;
+ es->NumTabStops = 0;
+ es->hTabStops = EDIT_HEAP_ALLOC(sizeof(int));
/* allocate space for a line full of blanks to speed up */
/* line filling */
@@ -608,14 +621,15 @@
/* advance through current line */
while (*cp && *cp != '\n')
{
- len += charWidths[*cp]; /* width of line in pixels */
+ len += EDIT_CharWidth(es, *cp, len); /* width of line in pixels */
cp++;
}
es->textwidth = max(es->textwidth, len);
if (*cp)
cp++; /* skip '\n' */
}
- off = (unsigned int)(cp - text); /* offset of beginning of line */
+
+ off = (unsigned int)(cp - text);
*(textPtrs + es->wlines) = off;
}
@@ -722,27 +736,46 @@
/*********************************************************************
- * EDIT_LineLength
+ * EDIT_StrLength
*
- * Return length of line _str_ of length _len_ characters in pixels.
+ * Return length of string _str_ of length _len_ characters in pixels.
+ * The current column offset in pixels _pcol_ is required to calculate
+ * the width of a tab.
*/
-int EDIT_LineLength(EDITSTATE *es, char *str, int len)
+int EDIT_StrLength(EDITSTATE *es, char *str, int len, int pcol)
{
int i, plen = 0;
- short *charWidths = (short *)EDIT_HEAP_ADDR(es->hCharWidths);
for (i = 0; i < len; i++)
- plen += charWidths[*(str + i)];
+ plen += EDIT_CharWidth(es, *(str + i), pcol + plen);
#ifdef DEBUG_EDIT
- printf("EDIT_LineLength: returning %d\n", plen);
+ printf("EDIT_StrLength: returning %d\n", plen);
#endif
return plen;
}
/*********************************************************************
+ * EDIT_LineLength
+ *
+ * Return length of line _num_ in characters.
+ */
+
+int EDIT_LineLength(HWND hwnd, int num)
+{
+ WND *wndPtr = WIN_FindWndPtr(hwnd);
+ EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
+ char *cp = EDIT_TextLine(hwnd, num);
+ char *cp1;
+
+ cp1 = strchr(cp, '\n');
+ return cp1 ? (int)(cp1 - cp) : strlen(cp);
+}
+
+
+/*********************************************************************
* EDIT_WriteTextLine
*
* Write the line of text at offset _y_ in text buffer to a window.
@@ -812,7 +845,7 @@
if ((hLine = EDIT_GetTextLine(hwnd, y)) == 0)
return;
lp = (unsigned char *)EDIT_HEAP_ADDR(hLine);
- lnlen = EDIT_LineLength(es, lp, strlen(lp));
+ lnlen = EDIT_StrLength(es, lp, strlen(lp), 0);
lnlen1 = lnlen;
/* build the line to display */
@@ -852,7 +885,7 @@
TRUE, TRUE);
else if (y == sbl)
{
- col = EDIT_LineLength(es, lp, sbc);
+ col = EDIT_StrLength(es, lp, sbc, 0);
if (col > (es->wleft + rc.left))
{
len = min(col - off, rc.right - off);
@@ -862,7 +895,7 @@
}
if (y == sel)
{
- col = EDIT_LineLength(es, lp, sec);
+ col = EDIT_StrLength(es, lp, sec, 0);
if (col < (es->wleft + rc.right))
{
len = min(col - off, rc.right - off);
@@ -890,7 +923,7 @@
}
else if (y == sel)
{
- col = EDIT_LineLength(es, lp, sec);
+ col = EDIT_StrLength(es, lp, sec, 0);
if (col < (es->wleft + rc.right))
{
len = min(col - off, rc.right - off);
@@ -930,14 +963,15 @@
{
HDC hdc;
HANDLE hStr;
- char *str, *blanks;
- int diff, num_spaces;
+ char *str, *cp, *cp1;
+ int diff, num_spaces, tabwidth, scol;
HRGN hrgnClip;
COLORREF oldTextColor, oldBkgdColor;
HFONT oldfont;
WND *wndPtr = WIN_FindWndPtr(hwnd);
EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
short *charWidths = (short *)EDIT_HEAP_ADDR(es->hCharWidths);
+ char *blanks = (char *)EDIT_HEAP_ADDR(es->hBlankLine);
#ifdef DEBUG_EDIT
printf("EDIT_WriteText lp=%s, off=%d, len=%d, row=%d, col=%d, reverse=%d\n", lp, off, len, row, col, reverse);
@@ -963,7 +997,31 @@
SetTextColor(hdc, oldBkgdColor);
}
- TextOut(hdc, col - diff, row * es->txtht, str, strlen(str));
+ if (!(cp = strchr(str, VK_TAB)))
+ TextOut(hdc, col - diff, row * es->txtht, str, strlen(str));
+ else
+ {
+ TextOut(hdc, col - diff, row * es->txtht, str, (int)(cp - str));
+ scol = EDIT_StrLength(es, str, (int)(cp - str), 0);
+ tabwidth = EDIT_CharWidth(es, VK_TAB, scol);
+ num_spaces = tabwidth / charWidths[32] + 1;
+ TextOut(hdc, scol, row * es->txtht, blanks, num_spaces);
+ cp++;
+ scol += tabwidth;
+
+ while (cp1 = strchr(cp, VK_TAB))
+ {
+ TextOut(hdc, scol, row * es->txtht, cp, (int)(cp1 - cp));
+ scol = EDIT_StrLength(es, cp, (int)(cp1 - cp), scol);
+ tabwidth = EDIT_CharWidth(es, VK_TAB, scol);
+ num_spaces = tabwidth / charWidths[32] + 1;
+ TextOut(hdc, scol, row * es->txtht, blanks, num_spaces);
+ cp = ++cp1;
+ scol += tabwidth;
+ }
+
+ TextOut(hdc, scol, row * es->txtht, cp, strlen(cp));
+ }
if (reverse)
{
@@ -976,7 +1034,6 @@
{
if ((rc->right - col) > len)
{
- blanks = EDIT_HEAP_ADDR(es->hBlankLine);
num_spaces = (rc->right - col - len) / charWidths[32];
TextOut(hdc, col + len, row * es->txtht, blanks, num_spaces);
}
@@ -1003,9 +1060,8 @@
{
HANDLE hStr;
char *str;
- int ch = 0, i = 0, j, tmp;
+ int ch = 0, i = 0, j, s_i;
int ch1;
- short *charWidths = (short *)EDIT_HEAP_ADDR(es->hCharWidths);
#ifdef DEBUG_EDIT
printf("EDIT_GetStr %s %d %d\n", lp, off, len);
@@ -1013,19 +1069,23 @@
while (i < off)
{
- i += charWidths[*(lp + ch)];
+ s_i = i;
+ i += EDIT_CharWidth(es, *(lp + ch), i);
ch++;
}
/* if stepped past _off_, go back a character */
if (i - off)
- i -= charWidths[*(lp + --ch)];
+ {
+ i = s_i;
+ ch--;
+ }
*diff = off - i;
ch1 = ch;
while (i < len + off)
{
- i += charWidths[*(lp + ch)];
+ i += EDIT_CharWidth(es, *(lp + ch), i);
ch++;
}
@@ -1102,7 +1162,7 @@
return;
}
- if (*currchar == '\0')
+ if (*currchar == '\0' && IsMultiLine())
{
/* insert a newline at end of text */
*currchar = '\n';
@@ -1145,13 +1205,13 @@
if (IsMultiLine() && es->wlines > 1)
{
es->textwidth = max(es->textwidth,
- EDIT_LineLength(es, EDIT_TextLine(hwnd, es->CurrLine),
+ EDIT_StrLength(es, EDIT_TextLine(hwnd, es->CurrLine),
(int)(EDIT_TextLine(hwnd, es->CurrLine + 1) -
- EDIT_TextLine(hwnd, es->CurrLine))));
+ EDIT_TextLine(hwnd, es->CurrLine)), 0));
}
else
es->textwidth = max(es->textwidth,
- EDIT_LineLength(es, text, strlen(text)));
+ EDIT_StrLength(es, text, strlen(text), 0));
EDIT_WriteTextLine(hwnd, NULL, es->wtop + es->WndRow);
if (ch == '\n')
@@ -1177,14 +1237,15 @@
}
/* test end of window */
- if (es->WndCol >= ClientWidth(wndPtr) - EDIT_CharWidth(es, ch))
+ if (es->WndCol >= ClientWidth(wndPtr) -
+ EDIT_CharWidth(es, ch, es->WndCol + es->wleft))
{
/* TODO:- Word wrap to be handled here */
/* if (!(currchar == text + es->MaxTextLen - 2)) */
EDIT_KeyHScroll(hwnd, SB_LINEDOWN);
}
- es->WndCol += EDIT_CharWidth(es, ch);
+ es->WndCol += EDIT_CharWidth(es, ch, es->WndCol + es->wleft);
es->CurrCol++;
SetCaretPos(es->WndCol, es->WndRow * es->txtht);
ShowCaret(hwnd);
@@ -1196,13 +1257,46 @@
* EDIT_CharWidth
*
* Return the width of the given character in pixels.
+ * The current column offset in pixels _pcol_ is required to calculate
+ * the width of a tab.
*/
-int EDIT_CharWidth(EDITSTATE *es, short ch)
+int EDIT_CharWidth(EDITSTATE *es, short ch, int pcol)
{
short *charWidths = (short *)EDIT_HEAP_ADDR(es->hCharWidths);
- return (charWidths[ch]);
+ if (ch != VK_TAB)
+ return (charWidths[ch]);
+ else
+ return (EDIT_GetNextTabStop(es, pcol) - pcol);
+}
+
+
+/*********************************************************************
+ * EDIT_GetNextTabStop
+ *
+ * Return the next tab stop beyond _pcol_.
+ */
+
+int EDIT_GetNextTabStop(EDITSTATE *es, int pcol)
+{
+ int i;
+ int baseUnitWidth = LOWORD(GetDialogBaseUnits());
+ unsigned short *tabstops = EDIT_HEAP_ADDR(es->hTabStops);
+
+ if (es->NumTabStops == 0)
+ return ROUNDUP(pcol, 8);
+ else if (es->NumTabStops == 1)
+ return ROUNDUP(pcol, *tabstops * baseUnitWidth / 4);
+ else
+ {
+ for (i = 0; i < es->NumTabStops; i++)
+ {
+ if (*(tabstops + i) * baseUnitWidth / 4 >= pcol)
+ return (*(tabstops + i) * baseUnitWidth / 4);
+ }
+ return pcol;
+ }
}
@@ -1217,9 +1311,8 @@
WND *wndPtr = WIN_FindWndPtr(hwnd);
EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
char *text = EDIT_TextAddr(es, es->hText);
- char *cc = CurrChar + 1;
- if (*cc == '\0')
+ if (*CurrChar == '\0')
return;
if (*CurrChar == '\n')
@@ -1229,7 +1322,7 @@
}
else
{
- es->WndCol += EDIT_CharWidth(es, *CurrChar);
+ es->WndCol += EDIT_CharWidth(es, *CurrChar, es->WndCol + es->wleft);
es->CurrCol++;
if (es->WndCol >= ClientWidth(wndPtr))
EDIT_KeyHScroll(hwnd, SB_LINEDOWN);
@@ -1309,7 +1402,7 @@
if (es->CurrCol)
{
--es->CurrCol;
- es->WndCol -= EDIT_CharWidth(es, *CurrChar);
+ es->WndCol -= EDIT_CharWidth(es, *CurrChar, es->WndCol + es->wleft);
if (es->WndCol < 0)
EDIT_KeyHScroll(hwnd, SB_LINEUP);
}
@@ -1336,7 +1429,7 @@
while (*CurrChar && *CurrChar != '\n')
{
- es->WndCol += EDIT_CharWidth(es, *CurrChar);
+ es->WndCol += EDIT_CharWidth(es, *CurrChar, es->WndCol + es->wleft);
es->CurrCol++;
}
@@ -1382,15 +1475,13 @@
{
WND *wndPtr = WIN_FindWndPtr(hwnd);
EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
+ int len = EDIT_LineLength(hwnd, es->CurrLine);
+ char *cp = EDIT_TextLine(hwnd, es->CurrLine);
char currpel;
- char *cp = EDIT_TextLine(hwnd, es->CurrLine);
- char *cp1 = strchr(cp, '\n');
- int len = cp1 ? (int)(cp1 - cp) : 0;
-
es->CurrCol = min(len, es->CurrCol);
- es->WndCol = min(EDIT_LineLength(es, cp, len) - es->wleft, es->WndCol);
- currpel = EDIT_LineLength(es, cp, es->CurrCol);
+ es->WndCol = min(EDIT_StrLength(es, cp, len, 0) - es->wleft, es->WndCol);
+ currpel = EDIT_StrLength(es, cp, es->CurrCol, 0);
if (es->wleft > currpel)
{
@@ -1848,7 +1939,6 @@
if (es->wtop + ClientHeight(wndPtr, es) >= es->wlines)
return;
es->wtop++;
- printf("Scroll line down: wtop=%d\n", es->wtop);
}
else
{
@@ -1856,7 +1946,6 @@
if (es->wtop == 0)
return;
--es->wtop;
- printf("Scroll line up: wtop=%d\n", es->wtop);
}
if (IsWindowVisible(hwnd))
@@ -1974,7 +2063,7 @@
void EDIT_LButtonDownMsg(HWND hwnd, WORD wParam, LONG lParam)
{
- char *cp, *cp1;
+ char *cp;
int len;
BOOL end = FALSE;
WND *wndPtr = WIN_FindWndPtr(hwnd);
@@ -1995,12 +2084,10 @@
es->CurrLine = es->wtop + es->WndRow;
cp = EDIT_TextLine(hwnd, es->CurrLine);
- cp1 = strchr(cp, '\n');
- len = cp1 ? (int)(cp1 - cp) : 0;
-
+ len = EDIT_LineLength(hwnd, es->CurrLine);
es->WndCol = LOWORD(lParam);
- if (es->WndCol > EDIT_LineLength(es, cp, len) - es->wleft || end)
- es->WndCol = EDIT_LineLength(es, cp, len) - es->wleft;
+ if (es->WndCol > EDIT_StrLength(es, cp, len, 0) - es->wleft || end)
+ es->WndCol = EDIT_StrLength(es, cp, len, 0) - es->wleft;
es->CurrCol = EDIT_PixelToChar(hwnd, es->CurrLine, &(es->WndCol));
ButtonDown = TRUE;
@@ -2040,11 +2127,10 @@
int EDIT_PixelToChar(HWND hwnd, int row, int *pixel)
{
- int ch = 0, i = 0;
+ int ch = 0, i = 0, s_i;
char *text;
WND *wndPtr = WIN_FindWndPtr(hwnd);
EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
- short *charWidths = (short *)EDIT_HEAP_ADDR(es->hCharWidths);
#ifdef DEBUG_EDIT
printf("EDIT_PixelToChar: row=%d, pixel=%d\n", row, *pixel);
@@ -2053,13 +2139,17 @@
text = EDIT_TextLine(hwnd, row);
while (i < *pixel)
{
- i += charWidths[*(text + ch)];
+ s_i = i;
+ i += EDIT_CharWidth(es, *(text + ch), i);
ch++;
}
/* if stepped past _pixel_, go back a character */
if (i - *pixel)
- i -= charWidths[*(text + ch)];
+ {
+ i = s_i;
+ --ch;
+ }
*pixel = i;
return ch;
}
@@ -2154,8 +2244,8 @@
es->wtop = es->SelEndLine;
es->WndRow = 0;
}
- es->WndCol = EDIT_LineLength(es, EDIT_TextLine(hwnd, es->SelEndLine),
- es->SelEndCol) - es->wleft;
+ es->WndCol = EDIT_StrLength(es, EDIT_TextLine(hwnd, es->SelEndLine),
+ es->SelEndCol, 0) - es->wleft;
}
InvalidateRect(hwnd, NULL, TRUE);
UpdateWindow(hwnd);
@@ -2202,8 +2292,10 @@
}
*line = lineno - 1;
*col = off - (int)(cp1 - text);
+#if 0
if (*(text + *col) == '\0')
(*col)--;
+#endif
}
@@ -2238,8 +2330,8 @@
es->wtop = es->SelBegLine;
es->WndRow = 0;
}
- es->WndCol = EDIT_LineLength(es, bbl - es->SelBegCol,
- es->SelBegCol) - es->wleft;
+ es->WndCol = EDIT_StrLength(es, bbl - es->SelBegCol,
+ es->SelBegCol, 0) - es->wleft;
EDIT_BuildTextPointers(hwnd);
es->PaintBkgd = TRUE;
@@ -2329,7 +2421,7 @@
void EDIT_ExtendSel(HWND hwnd, int x, int y)
{
int bbl, bel, bbc, bec;
- char *cp, *cp1;
+ char *cp;
int len;
BOOL end = FALSE;
WND *wndPtr = WIN_FindWndPtr(hwnd);
@@ -2342,8 +2434,7 @@
bbl = es->SelEndLine;
bbc = es->SelEndCol;
cp = EDIT_TextLine(hwnd, es->wtop + y / es->txtht);
- cp1 = strchr(cp, '\n');
- len = cp1 ? (int)(cp1 - cp) : 0;
+ len = EDIT_LineLength(hwnd, es->wtop + y / es->txtht);
es->WndRow = y / es->txtht;
if (es->WndRow > es->wlines - es->wtop - 1)
@@ -2358,8 +2449,8 @@
es->SelEndLine = es->CurrLine;
es->WndCol = x;
- if (es->WndCol > EDIT_LineLength(es, cp, len) - es->wleft || end)
- es->WndCol = EDIT_LineLength(es, cp, len) - es->wleft;
+ if (es->WndCol > EDIT_StrLength(es, cp, len, 0) - es->wleft || end)
+ es->WndCol = EDIT_StrLength(es, cp, len, 0) - es->wleft;
es->CurrCol = EDIT_PixelToChar(hwnd, es->CurrLine, &(es->WndCol));
es->SelEndCol = es->CurrCol - 1;
@@ -2404,7 +2495,7 @@
{
RECT rc;
int scol, ecol;
- char *cp, *cp1;
+ char *cp;
HDC hdc;
HBRUSH hbrush, holdbrush;
int olddm;
@@ -2425,15 +2516,12 @@
/* get length of line if end == -1 */
if (end == -1)
- {
- cp1 = strchr(cp, '\n');
- end = cp1 ? (int)(cp1 - cp) : 0;
- }
+ end = EDIT_LineLength(hwnd, y);
- scol = EDIT_LineLength(es, cp, start);
+ scol = EDIT_StrLength(es, cp, start, 0);
if (scol > rc.right) return;
if (scol < rc.left) scol = rc.left;
- ecol = EDIT_LineLength(es, cp, end);
+ ecol = EDIT_StrLength(es, cp, end, 0);
if (ecol < rc.left) return;
if (ecol > rc.right) ecol = rc.right;
@@ -2551,8 +2639,8 @@
EDIT_GetLineCol(hwnd, (int)((CurrChar + len) - text), &(es->CurrLine),
&(es->CurrCol));
es->WndRow = es->CurrLine - es->wtop;
- es->WndCol = EDIT_LineLength(es, EDIT_TextLine(hwnd, es->CurrLine),
- es->CurrCol) - es->wleft;
+ es->WndCol = EDIT_StrLength(es, EDIT_TextLine(hwnd, es->CurrLine),
+ es->CurrCol, 0) - es->wleft;
}
@@ -2669,8 +2757,8 @@
ReleaseDC(hwnd, hdc);
es->WndRow = (es->CurrLine - es->wtop) / es->txtht;
- es->WndCol = EDIT_LineLength(es, EDIT_TextLine(hwnd, es->CurrLine),
- es->CurrCol) - es->wleft;
+ es->WndCol = EDIT_StrLength(es, EDIT_TextLine(hwnd, es->CurrLine),
+ es->CurrCol, 0) - es->wleft;
InvalidateRect(hwnd, NULL, TRUE);
es->PaintBkgd = TRUE;
@@ -2741,8 +2829,8 @@
EDIT_GetLineCol(hwnd, (int)((CurrChar + es->DeletedLength) - text),
&(es->CurrLine), &(es->CurrCol));
es->WndRow = es->CurrLine - es->wtop;
- es->WndCol = EDIT_LineLength(es, EDIT_TextLine(hwnd, es->CurrLine),
- es->CurrCol) - es->wleft;
+ es->WndCol = EDIT_StrLength(es, EDIT_TextLine(hwnd, es->CurrLine),
+ es->CurrCol, 0) - es->wleft;
es->SelEndLine = es->CurrLine;
es->SelEndCol = es->CurrCol;
@@ -2826,6 +2914,35 @@
/*********************************************************************
+ * EM_SETTABSTOPS message function
+ */
+
+LONG EDIT_SetTabStopsMsg(HWND hwnd, WORD wParam, LONG lParam)
+{
+ unsigned short *tabstops;
+ WND *wndPtr = WIN_FindWndPtr(hwnd);
+ EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
+
+ es->NumTabStops = wParam;
+ if (wParam == 0)
+ es->hTabStops = EDIT_HEAP_REALLOC(es->hTabStops, 1);
+ else if (wParam == 1)
+ {
+ es->hTabStops = EDIT_HEAP_REALLOC(es->hTabStops, 1);
+ tabstops = (unsigned short *)EDIT_HEAP_ADDR(es->hTabStops);
+ *tabstops = (unsigned short)lParam;
+ }
+ else
+ {
+ es->hTabStops = EDIT_HEAP_REALLOC(es->hTabStops, wParam);
+ tabstops = (unsigned short *)EDIT_HEAP_ADDR(es->hTabStops);
+ memcpy(tabstops, (unsigned short *)lParam, wParam);
+ }
+ return 0L;
+}
+
+
+/*********************************************************************
* Utility functions
*/
diff --git a/controls/listbox.c b/controls/listbox.c
index 196cb9b..8b7af56 100644
--- a/controls/listbox.c
+++ b/controls/listbox.c
@@ -1151,7 +1151,7 @@
{
if (DOS_ValidDrive(x))
{
- sprintf(temp, "[-%c-]", 'A'+x);
+ sprintf(temp, "[-%c-]", 'a'+x);
if ( (wRet = ListBoxAddString(hwnd, temp)) == LB_ERR)
break;
}
diff --git a/include/comm.h b/include/comm.h
new file mode 100644
index 0000000..7f74685
--- /dev/null
+++ b/include/comm.h
@@ -0,0 +1,21 @@
+/*
+ * Communications header
+ *
+ * 93 Erik Bos (erik@trashcan.hacktic.nl)
+ */
+
+#ifndef COMM_H
+#define COMM_H
+
+
+#define MAX_PORTS 16
+
+struct DosDeviceStruct {
+ char *devicename; /* /dev/cua1 */
+ int fd;
+ int suspended;
+ int unget;
+ int unget_byte;
+};
+
+#endif /* COMM_H */
diff --git a/include/mmsystem.h b/include/mmsystem.h
index de39b93..feb2eda 100644
--- a/include/mmsystem.h
+++ b/include/mmsystem.h
@@ -8,6 +8,11 @@
typedef LPSTR HPSTR; /* a huge version of LPSTR */
typedef LPCSTR HPCSTR; /* a huge version of LPCSTR */
+#define MAXWAVEDRIVERS 10
+#define MAXMIDIDRIVERS 10
+#define MAXAUXDRIVERS 10
+#define MAXMCIDRIVERS 32
+
#define MAXPNAMELEN 32 /* max product name length (including NULL) */
#define MAXERRORLENGTH 128 /* max error text length (including NULL) */
@@ -166,7 +171,7 @@
#define WAVE_FORMAT_QUERY 0x0001
#define WAVE_ALLOWSYNC 0x0002
-typedef struct {
+typedef struct wavehdr_tag {
LPSTR lpData; /* pointer to locked data buffer */
DWORD dwBufferLength; /* length of data buffer */
DWORD dwBytesRecorded; /* used for input only */
@@ -764,8 +769,10 @@
#define MCIERR_CUSTOM_DRIVER_BASE (MCIERR_BASE + 256)
-#define MCI_OPEN 0x0803
-#define MCI_CLOSE 0x0804
+#define MCI_OPEN_DRIVER 0x0801
+#define MCI_CLOSE_DRIVER 0x0802
+#define MCI_OPEN 0x0803
+#define MCI_CLOSE 0x0804
#define MCI_ESCAPE 0x0805
#define MCI_PLAY 0x0806
#define MCI_SEEK 0x0807
@@ -1389,6 +1396,126 @@
* Linux MMSYSTEM Internals & Sample Audio Drivers
*/
+#define DRVM_INIT 100
+#define WODM_INIT DRVM_INIT
+#define WIDM_INIT DRVM_INIT
+#define MODM_INIT DRVM_INIT
+#define MIDM_INIT DRVM_INIT
+#define AUXM_INIT DRVM_INIT
+
+#define WODM_GETNUMDEVS 3
+#define WODM_GETDEVCAPS 4
+#define WODM_OPEN 5
+#define WODM_CLOSE 6
+#define WODM_PREPARE 7
+#define WODM_UNPREPARE 8
+#define WODM_WRITE 9
+#define WODM_PAUSE 10
+#define WODM_RESTART 11
+#define WODM_RESET 12
+#define WODM_GETPOS 13
+#define WODM_GETPITCH 14
+#define WODM_SETPITCH 15
+#define WODM_GETVOLUME 16
+#define WODM_SETVOLUME 17
+#define WODM_GETPLAYBACKRATE 18
+#define WODM_SETPLAYBACKRATE 19
+#define WODM_BREAKLOOP 20
+
+#define WIDM_GETNUMDEVS 50
+#define WIDM_GETDEVCAPS 51
+#define WIDM_OPEN 52
+#define WIDM_CLOSE 53
+#define WIDM_PREPARE 54
+#define WIDM_UNPREPARE 55
+#define WIDM_ADDBUFFER 56
+#define WIDM_START 57
+#define WIDM_STOP 58
+#define WIDM_RESET 59
+#define WIDM_GETPOS 60
+
+#define MODM_GETNUMDEVS 1
+#define MODM_GETDEVCAPS 2
+#define MODM_OPEN 3
+#define MODM_CLOSE 4
+#define MODM_PREPARE 5
+#define MODM_UNPREPARE 6
+#define MODM_DATA 7
+#define MODM_LONGDATA 8
+#define MODM_RESET 9
+#define MODM_GETVOLUME 10
+#define MODM_SETVOLUME 11
+#define MODM_CACHEPATCHES 12
+#define MODM_CACHEDRUMPATCHES 13
+
+#define MIDM_GETNUMDEVS 53
+#define MIDM_GETDEVCAPS 54
+#define MIDM_OPEN 55
+#define MIDM_CLOSE 56
+#define MIDM_PREPARE 57
+#define MIDM_UNPREPARE 58
+#define MIDM_ADDBUFFER 59
+#define MIDM_START 60
+#define MIDM_STOP 61
+#define MIDM_RESET 62
+
+#define AUXDM_GETNUMDEVS 3
+#define AUXDM_GETDEVCAPS 4
+#define AUXDM_GETVOLUME 5
+#define AUXDM_SETVOLUME 6
+
+#define MCI_MAX_DEVICE_TYPE_LENGTH 80
+
+#define MCI_FALSE (MCI_STRING_OFFSET + 19)
+#define MCI_TRUE (MCI_STRING_OFFSET + 20)
+
+#define MCI_FORMAT_RETURN_BASE MCI_FORMAT_MILLISECONDS_S
+#define MCI_FORMAT_MILLISECONDS_S (MCI_STRING_OFFSET + 21)
+#define MCI_FORMAT_HMS_S (MCI_STRING_OFFSET + 22)
+#define MCI_FORMAT_MSF_S (MCI_STRING_OFFSET + 23)
+#define MCI_FORMAT_FRAMES_S (MCI_STRING_OFFSET + 24)
+#define MCI_FORMAT_SMPTE_24_S (MCI_STRING_OFFSET + 25)
+#define MCI_FORMAT_SMPTE_25_S (MCI_STRING_OFFSET + 26)
+#define MCI_FORMAT_SMPTE_30_S (MCI_STRING_OFFSET + 27)
+#define MCI_FORMAT_SMPTE_30DROP_S (MCI_STRING_OFFSET + 28)
+#define MCI_FORMAT_BYTES_S (MCI_STRING_OFFSET + 29)
+#define MCI_FORMAT_SAMPLES_S (MCI_STRING_OFFSET + 30)
+#define MCI_FORMAT_TMSF_S (MCI_STRING_OFFSET + 31)
+
+#define MCI_VD_FORMAT_TRACK_S (MCI_VD_OFFSET + 5)
+
+#define WAVE_FORMAT_PCM_S (MCI_WAVE_OFFSET + 0)
+#define WAVE_MAPPER_S (MCI_WAVE_OFFSET + 1)
+
+#define MCI_SEQ_MAPPER_S (MCI_SEQ_OFFSET + 5)
+#define MCI_SEQ_FILE_S (MCI_SEQ_OFFSET + 6)
+#define MCI_SEQ_MIDI_S (MCI_SEQ_OFFSET + 7)
+#define MCI_SEQ_SMPTE_S (MCI_SEQ_OFFSET + 8)
+#define MCI_SEQ_FORMAT_SONGPTR_S (MCI_SEQ_OFFSET + 9)
+#define MCI_SEQ_NONE_S (MCI_SEQ_OFFSET + 10)
+#define MIDIMAPPER_S (MCI_SEQ_OFFSET + 11)
+
+#define MCI_RESOURCE_RETURNED 0x00010000 /* resource ID */
+#define MCI_COLONIZED3_RETURN 0x00020000 /* colonized ID, 3 bytes data */
+#define MCI_COLONIZED4_RETURN 0x00040000 /* colonized ID, 4 bytes data */
+#define MCI_INTEGER_RETURNED 0x00080000 /* integer conversion needed */
+#define MCI_RESOURCE_DRIVER 0x00100000 /* driver owns returned resource */
+
+#define MCI_NO_COMMAND_TABLE 0xFFFF
+
+#define MCI_COMMAND_HEAD 0
+#define MCI_STRING 1
+#define MCI_INTEGER 2
+#define MCI_END_COMMAND 3
+#define MCI_RETURN 4
+#define MCI_FLAG 5
+#define MCI_END_COMMAND_LIST 6
+#define MCI_RECT 7
+#define MCI_CONSTANT 8
+#define MCI_END_CONSTANT 9
+
+#define MAKEMCIRESOURCE(wRet, wRes) MAKELRESULT((wRet), (wRes))
+
typedef struct {
DWORD dwCallback;
DWORD dwInstance;
@@ -1397,6 +1524,56 @@
} PORTALLOC;
typedef PORTALLOC FAR *LPPORTALLOC;
+typedef struct {
+ HWAVE hWave;
+ LPWAVEFORMAT lpFormat;
+ DWORD dwCallBack;
+ DWORD dwInstance;
+ } WAVEOPENDESC;
+typedef WAVEOPENDESC FAR *LPWAVEOPENDESC;
+
+typedef struct {
+ HMIDI hMidi;
+ DWORD dwCallback;
+ DWORD dwInstance;
+ } MIDIOPENDESC;
+typedef MIDIOPENDESC FAR *LPMIDIOPENDESC;
+
+typedef struct {
+ UINT wDelay;
+ UINT wResolution;
+ LPTIMECALLBACK lpFunction;
+ DWORD dwUser;
+ UINT wFlags;
+ } TIMEREVENT;
+typedef TIMEREVENT FAR *LPTIMEREVENT;
+
+typedef struct {
+ UINT wDeviceID; /* device ID */
+ LPSTR lpstrParams; /* parameter string for entry in SYSTEM.INI */
+ UINT wCustomCommandTable; /* custom command table (0xFFFF if none) */
+ /* filled in by the driver */
+ UINT wType; /* driver type */
+ /* filled in by the driver */
+ } MCI_OPEN_DRIVER_PARMS;
+typedef MCI_OPEN_DRIVER_PARMS FAR * LPMCI_OPEN_DRIVER_PARMS;
+
+DWORD WINAPI mciGetDriverData(UINT uDeviceID);
+BOOL WINAPI mciSetDriverData(UINT uDeviceID, DWORD dwData);
+UINT WINAPI mciDriverYield(UINT uDeviceID);
+BOOL WINAPI mciDriverNotify(HWND hwndCallback, UINT uDeviceID,
+ UINT uStatus);
+UINT WINAPI mciLoadCommandResource(HINSTANCE hInstance,
+ LPCSTR lpResName, UINT uType);
+BOOL WINAPI mciFreeCommandResource(UINT uTable);
+
+#define DCB_NULL 0x0000
+#define DCB_WINDOW 0x0001 /* dwCallback is a HWND */
+#define DCB_TASK 0x0002 /* dwCallback is a HTASK */
+#define DCB_FUNCTION 0x0003 /* dwCallback is a FARPROC */
+#define DCB_TYPEMASK 0x0007
+#define DCB_NOSWITCH 0x0008 /* don't switch stacks for callback */
+
BOOL DriverCallback(DWORD dwCallBack, UINT uFlags, HANDLE hDev,
WORD wMsg, DWORD dwUser, DWORD dwParam1, DWORD dwParam2);
DWORD auxMessage(WORD wDevID, WORD wMsg, DWORD dwUser,
diff --git a/include/options.h b/include/options.h
index 5003b9f..3caf1fd 100644
--- a/include/options.h
+++ b/include/options.h
@@ -15,7 +15,6 @@
int usePrivateMap;
int synchronous;
int nobackingstore;
- int nosaveunders;
short cmdShow;
int relay_debug;
int debug;
diff --git a/include/windows.h b/include/windows.h
index 5281abd..c389455 100644
--- a/include/windows.h
+++ b/include/windows.h
@@ -2790,8 +2790,8 @@
Fc(BOOL,LineTo,HDC,a,short,b,short,c)
Fc(WORD,GetInternalWindowPos,HWND,a,LPRECT,b,LPPOINT,c)
Fc(LONG,_llseek,INT,a,LONG,b,INT,c)
-Fc(INT,_lread,INT,a,LPSTR,b,INT,c)
-Fc(INT,_lwrite,INT,a,LPSTR,b,INT,c)
+Fc(INT,_lread,INT,a,LPSTR,b,WORD,c)
+Fc(INT,_lwrite,INT,a,LPSTR,b,WORD,c)
Fc(int,FillRect,HDC,a,LPRECT,b,HBRUSH,c)
Fc(DWORD,MoveTo,HDC,a,short,b,short,c)
Fc(BOOL,CheckMenuItem,HMENU,a,WORD,b,WORD,c)
diff --git a/loader/main.c b/loader/main.c
index 8161854..459e7bc 100644
--- a/loader/main.c
+++ b/loader/main.c
@@ -264,7 +264,10 @@
strncpy(filename, Argv[0], p - Argv[0]);
filename[p - Argv[0]] = '\0';
strcat(WindowsPath, ";");
- strcat(WindowsPath, filename);
+ if (strchr(filename, '/'))
+ strcat(WindowsPath, GetDosFileName(filename));
+ else
+ strcat(WindowsPath, filename);
}
if ((hInstMain = LoadImage(Argv[0], EXE, 1)) < 32) {
diff --git a/misc/Imakefile b/misc/Imakefile
index 5967031..09d194c 100644
--- a/misc/Imakefile
+++ b/misc/Imakefile
@@ -16,7 +16,9 @@
keyboard.c \
lstr.c \
main.c \
+ mcicda.c \
message.c \
+ mmaux.c \
mmsystem.c \
network.c \
profile.c \
diff --git a/misc/audio.c b/misc/audio.c
index 008029f..153223f 100644
--- a/misc/audio.c
+++ b/misc/audio.c
@@ -4,20 +4,109 @@
* Copyright 1994 Martin Ayotte
*/
+#define DEBUG_MCIWAVE
+
static char Copyright[] = "Copyright Martin Ayotte, 1994";
#include "stdio.h"
-#include "windows.h"
#include "win.h"
#include "user.h"
#include "driver.h"
#include "mmsystem.h"
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <linux/soundcard.h>
+
+#define SOUND_DEV "/dev/dsp"
+
+#ifdef SOUND_VERSION
+#define IOCTL(a,b,c) ioctl(a,b,&c)
+#else
+#define IOCTL(a,b,c) (c = ioctl(a,b,c) )
+#endif
+
+#define MAX_WAVOUTDRV 2
+#define MAX_WAVINDRV 2
+#define MAX_MCIWAVDRV 2
+
+typedef struct {
+ int unixdev;
+ int state;
+ DWORD bufsize;
+ WAVEOPENDESC waveDesc;
+ WORD wFlags;
+ PCMWAVEFORMAT Format;
+ LPWAVEHDR lpQueueHdr;
+ DWORD dwTotalPlayed;
+ } LINUX_WAVEOUT;
+
+typedef struct {
+ int unixdev;
+ int state;
+ DWORD bufsize; /* Linux '/dev/dsp' give us that size */
+ WAVEOPENDESC waveDesc;
+ WORD wFlags;
+ PCMWAVEFORMAT Format;
+ LPWAVEHDR lpQueueHdr;
+ DWORD dwTotalRecorded;
+ } LINUX_WAVEIN;
+
+typedef struct {
+ int nUseCount; /* Incremented for each shared open */
+ BOOL fShareable; /* TRUE if first open was shareable */
+ WORD wNotifyDeviceID; /* MCI device ID with a pending notification */
+ HANDLE hCallback; /* Callback handle for pending notification */
+ int hFile; /* file handle open as Element */
+ MCI_WAVE_OPEN_PARMS openParms;
+ PCMWAVEFORMAT WaveFormat;
+ WAVEHDR WaveHdr;
+ } LINUX_MCIWAVE;
+
+static LINUX_WAVEOUT WOutDev[MAX_WAVOUTDRV];
+static LINUX_WAVEIN WInDev[MAX_WAVOUTDRV];
+static LINUX_MCIWAVE MCIWavDev[MAX_MCIWAVDRV];
+
+DWORD WAVE_mciOpen(DWORD dwFlags, LPMCI_WAVE_OPEN_PARMS lpParms);
+DWORD WAVE_mciClose(UINT wDevID, DWORD dwParam, LPMCI_GENERIC_PARMS lpParms);
+DWORD WAVE_mciPlay(UINT wDevID, DWORD dwFlags, LPMCI_PLAY_PARMS lpParms);
+DWORD WAVE_mciRecord(UINT wDevID, DWORD dwFlags, LPMCI_RECORD_PARMS lpParms);
+DWORD WAVE_mciStop(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms);
+DWORD WAVE_mciPause(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms);
+DWORD WAVE_mciResume(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms);
+DWORD WAVE_mciSet(UINT wDevID, DWORD dwFlags, LPMCI_SET_PARMS lpParms);
+DWORD WAVE_mciStatus(UINT wDevID, DWORD dwFlags, LPMCI_STATUS_PARMS lpParms);
+DWORD WAVE_mciGetDevCaps(UINT wDevID, DWORD dwFlags, LPMCI_GETDEVCAPS_PARMS lpParms);
+DWORD WAVE_mciInfo(UINT wDevID, DWORD dwFlags, LPMCI_INFO_PARMS lpParms);
+
+DWORD wodGetDevCaps(WORD wDevID, LPWAVEOUTCAPS lpCaps, DWORD dwSize);
+DWORD wodOpen(WORD wDevID, LPWAVEOPENDESC lpDesc, DWORD dwFlags);
+DWORD wodClose(WORD wDevID);
+DWORD wodWrite(WORD wDevID, LPWAVEHDR lpWaveHdr, DWORD dwSize);
+DWORD wodPrepare(WORD wDevID, LPWAVEHDR lpWaveHdr, DWORD dwSize);
+DWORD wodUnprepare(WORD wDevID, LPWAVEHDR lpWaveHdr, DWORD dwSize);
+
+
+/**************************************************************************
+* WAVE_NotifyClient [internal]
+*/
+DWORD WAVE_NotifyClient(UINT wDevID, WORD wMsg,
+ DWORD dwParam1, DWORD dwParam2)
+{
+ if (WInDev[wDevID].wFlags != DCB_NULL && !DriverCallback(
+ WInDev[wDevID].waveDesc.dwCallBack, WInDev[wDevID].wFlags,
+ WInDev[wDevID].waveDesc.hWave, wMsg,
+ WInDev[wDevID].waveDesc.dwInstance, dwParam1, dwParam2)) {
+ printf("WAVE_NotifyClient // can't notify client !\n");
+ return MMSYSERR_NOERROR;
+ }
+}
+
/**************************************************************************
* AUDIO_DriverProc [sample driver]
*/
-LRESULT AUDIO_DriverProc(DWORD dwDevID, HDRVR hDriv, WORD wMsg,
+LRESULT WAVE_DriverProc(DWORD dwDevID, HDRVR hDriv, WORD wMsg,
DWORD dwParam1, DWORD dwParam2)
{
switch(wMsg) {
@@ -43,17 +132,1320 @@
return (LRESULT)DRVCNF_RESTART;
case DRV_REMOVE:
return (LRESULT)DRVCNF_RESTART;
+ case MCI_OPEN_DRIVER:
+ case MCI_OPEN:
+ return WAVE_mciOpen(dwParam1, (LPMCI_WAVE_OPEN_PARMS)dwParam2);
+ case MCI_CLOSE_DRIVER:
+ case MCI_CLOSE:
+ return WAVE_mciClose(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)dwParam2);
+ case MCI_PLAY:
+ return WAVE_mciPlay(dwDevID, dwParam1, (LPMCI_PLAY_PARMS)dwParam2);
+ case MCI_RECORD:
+ return WAVE_mciRecord(dwDevID, dwParam1, (LPMCI_RECORD_PARMS)dwParam2);
+ case MCI_STOP:
+ return WAVE_mciStop(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)dwParam2);
+ case MCI_SET:
+ return WAVE_mciSet(dwDevID, dwParam1, (LPMCI_SET_PARMS)dwParam2);
+ case MCI_PAUSE:
+ return WAVE_mciPause(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)dwParam2);
+ case MCI_RESUME:
+ return WAVE_mciResume(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)dwParam2);
+ case MCI_STATUS:
+ return WAVE_mciStatus(dwDevID, dwParam1, (LPMCI_STATUS_PARMS)dwParam2);
+ case MCI_GETDEVCAPS:
+ return WAVE_mciGetDevCaps(dwDevID, dwParam1, (LPMCI_GETDEVCAPS_PARMS)dwParam2);
+ case MCI_INFO:
+ return WAVE_mciInfo(dwDevID, dwParam1, (LPMCI_INFO_PARMS)dwParam2);
default:
return DefDriverProc(dwDevID, hDriv, wMsg, dwParam1, dwParam2);
}
}
/**************************************************************************
+* WAVE_mciOpen */
+DWORD WAVE_mciOpen(DWORD dwFlags, LPMCI_WAVE_OPEN_PARMS lpParms)
+{
+ int hFile;
+ UINT wDevID;
+ OFSTRUCT OFstruct;
+ LPPCMWAVEFORMAT lpWaveFormat;
+ WAVEOPENDESC WaveDesc;
+ DWORD dwRet;
+ char str[128];
+ LPSTR ptr;
+#ifdef DEBUG_MCIWAVE
+ printf("WAVE_mciOpen(%08X, %08X)\n", dwFlags, lpParms);
+#endif
+ if (lpParms == NULL) return MCIERR_INTERNAL;
+ wDevID = lpParms->wDeviceID;
+ if (MCIWavDev[wDevID].nUseCount > 0) {
+ /* The driver already open on this channel */
+ /* If the driver was opened shareable before and this open specifies */
+ /* shareable then increment the use count */
+ if (MCIWavDev[wDevID].fShareable && (dwFlags & MCI_OPEN_SHAREABLE))
+ ++MCIWavDev[wDevID].nUseCount;
+ else
+ return MCIERR_MUST_USE_SHAREABLE;
+ }
+ else {
+ MCIWavDev[wDevID].nUseCount = 1;
+ MCIWavDev[wDevID].fShareable = dwFlags & MCI_OPEN_SHAREABLE;
+ }
+ if (dwFlags & MCI_OPEN_ELEMENT) {
+ printf("WAVE_mciOpen // MCI_OPEN_ELEMENT '%s' !\n",
+ lpParms->lpstrElementName);
+ printf("WAVE_mciOpen // cdw='%s'\n", DOS_GetCurrentDir(DOS_GetDefaultDrive()));
+ if (strlen(lpParms->lpstrElementName) > 0) {
+ strcpy(str, lpParms->lpstrElementName);
+ AnsiUpper(str);
+ MCIWavDev[wDevID].hFile = _lopen(str, OF_READWRITE);
+ if (MCIWavDev[wDevID].hFile < 1) {
+ MCIWavDev[wDevID].hFile = 0;
+ printf("WAVE_mciOpen // can't find file='%s' !\n", str);
+ return MCIERR_FILE_NOT_FOUND;
+ }
+ }
+ else
+ MCIWavDev[wDevID].hFile = 0;
+ }
+ printf("WAVE_mciOpen // hFile=%u\n", MCIWavDev[wDevID].hFile);
+ memcpy(&MCIWavDev[wDevID].openParms, lpParms, sizeof(MCI_WAVE_OPEN_PARMS));
+ MCIWavDev[wDevID].wNotifyDeviceID = lpParms->wDeviceID;
+ lpWaveFormat = &MCIWavDev[wDevID].WaveFormat;
+ WaveDesc.hWave = 0;
+ WaveDesc.lpFormat = (LPWAVEFORMAT)lpWaveFormat;
+ lpWaveFormat->wf.wFormatTag = WAVE_FORMAT_PCM;
+ lpWaveFormat->wBitsPerSample = 8;
+ lpWaveFormat->wf.nChannels = 1;
+ lpWaveFormat->wf.nSamplesPerSec = 11025;
+ lpWaveFormat->wf.nAvgBytesPerSec = 11025;
+ lpWaveFormat->wf.nBlockAlign = 1;
+ dwRet = wodMessage(0, WODM_OPEN, 0, (DWORD)&WaveDesc, CALLBACK_NULL);
+ dwRet = widMessage(0, WIDM_OPEN, 0, (DWORD)&WaveDesc, CALLBACK_NULL);
+ return 0;
+}
+
+/**************************************************************************
+* WAVE_mciClose [internal]
+*/
+DWORD WAVE_mciClose(UINT wDevID, DWORD dwParam, LPMCI_GENERIC_PARMS lpParms)
+{
+ DWORD dwRet;
+#ifdef DEBUG_MCIWAVE
+ printf("WAVE_mciClose(%u, %08X, %08X);\n", wDevID, dwParam, lpParms);
+#endif
+ MCIWavDev[wDevID].nUseCount--;
+ if (MCIWavDev[wDevID].nUseCount == 0) {
+ if (MCIWavDev[wDevID].hFile != 0) {
+ close(MCIWavDev[wDevID].hFile);
+ MCIWavDev[wDevID].hFile = 0;
+ }
+ dwRet = wodMessage(0, WODM_CLOSE, 0, 0L, 0L);
+ if (dwRet != MMSYSERR_NOERROR) return MCIERR_INTERNAL;
+ dwRet = widMessage(0, WIDM_CLOSE, 0, 0L, 0L);
+ if (dwRet != MMSYSERR_NOERROR) return MCIERR_INTERNAL;
+ }
+ return 0;
+}
+
+
+/**************************************************************************
+* WAVE_mciPlay [internal]
+*/
+DWORD WAVE_mciPlay(UINT wDevID, DWORD dwFlags, LPMCI_PLAY_PARMS lpParms)
+{
+ int count;
+ int start, end;
+ LPWAVEHDR lpWaveHdr;
+ DWORD dwRet;
+#ifdef DEBUG_MCIWAVE
+ printf("WAVE_mciPlay(%u, %08X, %08X);\n", wDevID, dwFlags, lpParms);
+#endif
+ if (MCIWavDev[wDevID].hFile == 0) {
+ printf("WAVE_mciPlay // can't find file='%s' !\n",
+ MCIWavDev[wDevID].openParms.lpstrElementName);
+ return MCIERR_FILE_NOT_FOUND;
+ }
+ start = 1; end = 99999;
+ if (dwFlags & MCI_FROM) {
+ start = lpParms->dwFrom;
+ printf("WAVE_mciPlay // MCI_FROM=%d \n", start);
+ }
+ if (dwFlags & MCI_TO) {
+ end = lpParms->dwTo;
+ printf("WAVE_mciPlay // MCI_TO=%d \n", end);
+ }
+/*
+ if (dwFlags & MCI_NOTIFY) {
+ printf("WAVE_mciPlay // MCI_NOTIFY %08X !\n", lpParms->dwCallback);
+ switch(fork()) {
+ case -1:
+ printf("WAVE_mciPlay // Can't 'fork' process !\n");
+ break;
+ case 0:
+ break;
+ default:
+ printf("WAVE_mciPlay // process started ! return to caller...\n");
+ return 0;
+ }
+ }
+*/
+ lpWaveHdr = &MCIWavDev[wDevID].WaveHdr;
+ lpWaveHdr->lpData = (LPSTR) malloc(64000);
+ lpWaveHdr->dwBufferLength = 32000;
+ lpWaveHdr->dwUser = 0L;
+ lpWaveHdr->dwFlags = 0L;
+ lpWaveHdr->dwLoops = 0L;
+ dwRet = wodMessage(0, WODM_PREPARE, 0, (DWORD)lpWaveHdr, sizeof(WAVEHDR));
+ printf("WAVE_mciPlay // after WODM_PREPARE \n");
+ while(TRUE) {
+/* printf("WAVE_mciPlay // before 'read' hFile=%u lpData=%08X dwBufferLength=%u\n",
+ MCIWavDev[wDevID].hFile, lpWaveHdr->lpData, lpWaveHdr->dwBufferLength); */
+ count = _lread(MCIWavDev[wDevID].hFile, lpWaveHdr->lpData, lpWaveHdr->dwBufferLength);
+ if (count < 1) break;
+ lpWaveHdr->dwBytesRecorded = count;
+ printf("WAVE_mciPlay // before WODM_WRITE lpWaveHdr=%08X dwBytesRecorded=%u\n",
+ lpWaveHdr, lpWaveHdr->dwBytesRecorded);
+ dwRet = wodMessage(0, WODM_WRITE, 0, (DWORD)lpWaveHdr, sizeof(WAVEHDR));
+ }
+ printf("WAVE_mciPlay // before WODM_UNPREPARE \n");
+ dwRet = wodMessage(0, WODM_UNPREPARE, 0, (DWORD)lpWaveHdr, sizeof(WAVEHDR));
+ printf("WAVE_mciPlay // after WODM_UNPREPARE \n");
+ if (lpWaveHdr->lpData != NULL) {
+ free(lpWaveHdr->lpData);
+ lpWaveHdr->lpData = NULL;
+ }
+ if (dwFlags & MCI_NOTIFY) {
+#ifdef DEBUG_MCIWAVE
+ printf("WAVE_mciPlay // MCI_NOTIFY_SUCCESSFUL %08X !\n", lpParms->dwCallback);
+#endif
+ mciDriverNotify((HWND)LOWORD(lpParms->dwCallback),
+ MCIWavDev[wDevID].wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL);
+ }
+ return 0;
+}
+
+
+/**************************************************************************
+* WAVE_mciRecord [internal]
+*/
+DWORD WAVE_mciRecord(UINT wDevID, DWORD dwFlags, LPMCI_RECORD_PARMS lpParms)
+{
+ int count;
+ int start, end;
+ LPWAVEHDR lpWaveHdr;
+ DWORD dwRet;
+#ifdef DEBUG_MCIWAVE
+ printf("WAVE_mciRecord(%u, %08X, %08X);\n", wDevID, dwFlags, lpParms);
+#endif
+ if (MCIWavDev[wDevID].hFile == 0) {
+ printf("WAVE_mciRecord // can't find file='%s' !\n",
+ MCIWavDev[wDevID].openParms.lpstrElementName);
+ return MCIERR_FILE_NOT_FOUND;
+ }
+ start = 1; end = 99999;
+ if (dwFlags & MCI_FROM) {
+ start = lpParms->dwFrom;
+ printf("WAVE_mciRecord // MCI_FROM=%d \n", start);
+ }
+ if (dwFlags & MCI_TO) {
+ end = lpParms->dwTo;
+ printf("WAVE_mciRecord // MCI_TO=%d \n", end);
+ }
+ lpWaveHdr = &MCIWavDev[wDevID].WaveHdr;
+ lpWaveHdr->lpData = (LPSTR) malloc(64000);
+ lpWaveHdr->dwBufferLength = 32000;
+ lpWaveHdr->dwUser = 0L;
+ lpWaveHdr->dwFlags = 0L;
+ lpWaveHdr->dwLoops = 0L;
+ dwRet = widMessage(0, WIDM_PREPARE, 0, (DWORD)lpWaveHdr, sizeof(WAVEHDR));
+ printf("WAVE_mciRecord // after WIDM_PREPARE \n");
+ while(TRUE) {
+ lpWaveHdr->dwBytesRecorded = 0;
+ dwRet = widMessage(0, WIDM_START, 0, 0L, 0L);
+ printf("WAVE_mciRecord // after WIDM_START lpWaveHdr=%08X dwBytesRecorded=%u\n",
+ lpWaveHdr, lpWaveHdr->dwBytesRecorded);
+ if (lpWaveHdr->dwBytesRecorded == 0) break;
+ }
+ printf("WAVE_mciRecord // before WIDM_UNPREPARE \n");
+ dwRet = widMessage(0, WIDM_UNPREPARE, 0, (DWORD)lpWaveHdr, sizeof(WAVEHDR));
+ printf("WAVE_mciRecord // after WIDM_UNPREPARE \n");
+ if (lpWaveHdr->lpData != NULL) {
+ free(lpWaveHdr->lpData);
+ lpWaveHdr->lpData = NULL;
+ }
+ if (dwFlags & MCI_NOTIFY) {
+#ifdef DEBUG_MCIWAVE
+ printf("WAVE_mciRecord // MCI_NOTIFY_SUCCESSFUL %08X !\n", lpParms->dwCallback);
+#endif
+ mciDriverNotify((HWND)LOWORD(lpParms->dwCallback),
+ MCIWavDev[wDevID].wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL);
+ }
+ return 0;
+}
+
+
+/**************************************************************************
+* WAVE_mciStop [internal]
+*/
+DWORD WAVE_mciStop(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
+{
+#ifdef DEBUG_MCIWAVE
+ printf("WAVE_mciStop(%u, %08X, %08X);\n", wDevID, dwFlags, lpParms);
+#endif
+ if (lpParms == NULL) return MCIERR_INTERNAL;
+ return 0;
+}
+
+
+/**************************************************************************
+* WAVE_mciPause [internal]
+*/
+DWORD WAVE_mciPause(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
+{
+#ifdef DEBUG_MCIWAVE
+ printf("WAVE_mciPause(%u, %08X, %08X);\n", wDevID, dwFlags, lpParms);
+#endif
+ if (lpParms == NULL) return MCIERR_INTERNAL;
+ return 0;
+}
+
+
+/**************************************************************************
+* WAVE_mciResume [internal]
+*/
+DWORD WAVE_mciResume(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
+{
+#ifdef DEBUG_MCIWAVE
+ printf("WAVE_mciResume(%u, %08X, %08X);\n", wDevID, dwFlags, lpParms);
+#endif
+ if (lpParms == NULL) return MCIERR_INTERNAL;
+ return 0;
+}
+
+
+/**************************************************************************
+* WAVE_mciSet [internal]
+*/
+DWORD WAVE_mciSet(UINT wDevID, DWORD dwFlags, LPMCI_SET_PARMS lpParms)
+{
+#ifdef DEBUG_MCIWAVE
+ printf("WAVE_mciSet(%u, %08X, %08X);\n", wDevID, dwFlags, lpParms);
+#endif
+ if (lpParms == NULL) return MCIERR_INTERNAL;
+#ifdef DEBUG_MCIWAVE
+ printf("WAVE_mciSet // dwTimeFormat=%08X\n", lpParms->dwTimeFormat);
+ printf("WAVE_mciSet // dwAudio=%08X\n", lpParms->dwAudio);
+#endif
+ if (dwFlags & MCI_SET_TIME_FORMAT) {
+ switch (lpParms->dwTimeFormat) {
+ case MCI_FORMAT_MILLISECONDS:
+ printf("WAVE_mciSet // MCI_FORMAT_MILLISECONDS !\n");
+ break;
+ case MCI_FORMAT_BYTES:
+ printf("WAVE_mciSet // MCI_FORMAT_BYTES !\n");
+ break;
+ case MCI_FORMAT_SAMPLES:
+ printf("WAVE_mciSet // MCI_FORMAT_SAMPLES !\n");
+ break;
+ default:
+ printf("WAVE_mciSet // bad time format !\n");
+ return MCIERR_BAD_TIME_FORMAT;
+ }
+ }
+ if (dwFlags & MCI_SET_VIDEO) return MCIERR_UNSUPPORTED_FUNCTION;
+ if (dwFlags & MCI_SET_DOOR_OPEN) return MCIERR_UNSUPPORTED_FUNCTION;
+ if (dwFlags & MCI_SET_DOOR_CLOSED) return MCIERR_UNSUPPORTED_FUNCTION;
+ if (dwFlags & MCI_SET_AUDIO) {
+ printf("WAVE_mciSet // MCI_SET_AUDIO !\n");
+ }
+ if (dwFlags && MCI_SET_ON) {
+ printf("WAVE_mciSet // MCI_SET_ON !\n");
+ if (dwFlags && MCI_SET_AUDIO_LEFT) {
+ printf("WAVE_mciSet // MCI_SET_AUDIO_LEFT !\n");
+ }
+ if (dwFlags && MCI_SET_AUDIO_RIGHT) {
+ printf("WAVE_mciSet // MCI_SET_AUDIO_RIGHT !\n");
+ }
+ }
+ if (dwFlags & MCI_SET_OFF) {
+ printf("WAVE_mciSet // MCI_SET_OFF !\n");
+ }
+ if (dwFlags & MCI_WAVE_INPUT) {
+ printf("WAVE_mciSet // MCI_WAVE_INPUT !\n");
+ }
+ if (dwFlags & MCI_WAVE_OUTPUT) {
+ printf("WAVE_mciSet // MCI_WAVE_OUTPUT !\n");
+ }
+ if (dwFlags & MCI_WAVE_SET_ANYINPUT) {
+ printf("WAVE_mciSet // MCI_WAVE_SET_ANYINPUT !\n");
+ }
+ if (dwFlags & MCI_WAVE_SET_ANYOUTPUT) {
+ printf("WAVE_mciSet // MCI_WAVE_SET_ANYOUTPUT !\n");
+ }
+ if (dwFlags & MCI_WAVE_SET_AVGBYTESPERSEC) {
+ printf("WAVE_mciSet // MCI_WAVE_SET_AVGBYTESPERSEC !\n");
+ }
+ if (dwFlags & MCI_WAVE_SET_BITSPERSAMPLE) {
+ printf("WAVE_mciSet // MCI_WAVE_SET_BITSPERSAMPLE !\n");
+ }
+ if (dwFlags & MCI_WAVE_SET_BLOCKALIGN) {
+ printf("WAVE_mciSet // MCI_WAVE_SET_BLOCKALIGN !\n");
+ }
+ if (dwFlags & MCI_WAVE_SET_CHANNELS) {
+ printf("WAVE_mciSet // MCI_WAVE_SET_CHANNELS !\n");
+ }
+ if (dwFlags & MCI_WAVE_SET_FORMATTAG) {
+ printf("WAVE_mciSet // MCI_WAVE_SET_FORMATTAG !\n");
+ }
+ if (dwFlags & MCI_WAVE_SET_SAMPLESPERSEC) {
+ printf("WAVE_mciSet // MCI_WAVE_SET_SAMPLESPERSEC !\n");
+ }
+ return 0;
+}
+
+
+/**************************************************************************
+* WAVE_mciStatus [internal]
+*/
+DWORD WAVE_mciStatus(UINT wDevID, DWORD dwFlags, LPMCI_STATUS_PARMS lpParms)
+{
+#ifdef DEBUG_MCIWAVE
+ printf("WAVE_mciStatus(%u, %08X, %08X);\n", wDevID, dwFlags, lpParms);
+#endif
+ if (lpParms == NULL) return MCIERR_INTERNAL;
+ if (dwFlags & MCI_STATUS_ITEM) {
+ switch(lpParms->dwItem) {
+ case MCI_STATUS_CURRENT_TRACK:
+ lpParms->dwReturn = 1;
+ break;
+ case MCI_STATUS_LENGTH:
+ lpParms->dwReturn = 5555;
+ if (dwFlags & MCI_TRACK) {
+ lpParms->dwTrack = 1;
+ lpParms->dwReturn = 2222;
+ }
+ break;
+ case MCI_STATUS_MODE:
+ lpParms->dwReturn = MCI_MODE_STOP;
+ break;
+ case MCI_STATUS_MEDIA_PRESENT:
+ printf("WAVE_mciStatus // MCI_STATUS_MEDIA_PRESENT !\n");
+ lpParms->dwReturn = TRUE;
+ break;
+ case MCI_STATUS_NUMBER_OF_TRACKS:
+ lpParms->dwReturn = 1;
+ break;
+ case MCI_STATUS_POSITION:
+ lpParms->dwReturn = 3333;
+ if (dwFlags & MCI_STATUS_START) {
+ lpParms->dwItem = 1;
+ }
+ if (dwFlags & MCI_TRACK) {
+ lpParms->dwTrack = 1;
+ lpParms->dwReturn = 777;
+ }
+ break;
+ case MCI_STATUS_READY:
+ printf("WAVE_mciStatus // MCI_STATUS_READY !\n");
+ lpParms->dwReturn = TRUE;
+ break;
+ case MCI_STATUS_TIME_FORMAT:
+ printf("WAVE_mciStatus // MCI_STATUS_TIME_FORMAT !\n");
+ lpParms->dwReturn = MCI_FORMAT_MILLISECONDS;
+ break;
+ case MCI_WAVE_INPUT:
+ printf("WAVE_mciStatus // MCI_WAVE_INPUT !\n");
+ lpParms->dwReturn = 0;
+ break;
+ case MCI_WAVE_OUTPUT:
+ printf("WAVE_mciStatus // MCI_WAVE_OUTPUT !\n");
+ lpParms->dwReturn = 0;
+ break;
+ case MCI_WAVE_STATUS_AVGBYTESPERSEC:
+ printf("WAVE_mciStatus // MCI_WAVE_STATUS_AVGBYTESPERSEC !\n");
+ lpParms->dwReturn = 22050;
+ break;
+ case MCI_WAVE_STATUS_BITSPERSAMPLE:
+ printf("WAVE_mciStatus // MCI_WAVE_STATUS_BITSPERSAMPLE !\n");
+ lpParms->dwReturn = 8;
+ break;
+ case MCI_WAVE_STATUS_BLOCKALIGN:
+ printf("WAVE_mciStatus // MCI_WAVE_STATUS_BLOCKALIGN !\n");
+ lpParms->dwReturn = 1;
+ break;
+ case MCI_WAVE_STATUS_CHANNELS:
+ printf("WAVE_mciStatus // MCI_WAVE_STATUS_CHANNELS !\n");
+ lpParms->dwReturn = 1;
+ break;
+ case MCI_WAVE_STATUS_FORMATTAG:
+ printf("WAVE_mciStatus // MCI_WAVE_FORMATTAG !\n");
+ lpParms->dwReturn = WAVE_FORMAT_PCM;
+ break;
+ case MCI_WAVE_STATUS_LEVEL:
+ printf("WAVE_mciStatus // MCI_WAVE_STATUS_LEVEL !\n");
+ lpParms->dwReturn = 0xAAAA5555;
+ break;
+ case MCI_WAVE_STATUS_SAMPLESPERSEC:
+ printf("WAVE_mciStatus // MCI_WAVE_STATUS_SAMPLESPERSEC !\n");
+ lpParms->dwReturn = 22050;
+ break;
+ default:
+ printf("WAVE_mciStatus // unknowm command %04X !\n", lpParms->dwItem);
+ return MCIERR_UNRECOGNIZED_COMMAND;
+ }
+ }
+ if (dwFlags & MCI_NOTIFY) {
+ printf("WAVE_mciStatus // MCI_NOTIFY_SUCCESSFUL %08X !\n", lpParms->dwCallback);
+ mciDriverNotify((HWND)LOWORD(lpParms->dwCallback),
+ MCIWavDev[wDevID].wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL);
+ }
+ return 0;
+}
+
+/**************************************************************************
+* WAVE_mciGetDevCaps [internal]
+*/
+DWORD WAVE_mciGetDevCaps(UINT wDevID, DWORD dwFlags,
+ LPMCI_GETDEVCAPS_PARMS lpParms)
+{
+ printf("WAVE_mciGetDevCaps(%u, %08X, %08X);\n", wDevID, dwFlags, lpParms);
+ if (lpParms == NULL) return MCIERR_INTERNAL;
+ if (dwFlags & MCI_GETDEVCAPS_ITEM) {
+ switch(lpParms->dwItem) {
+ case MCI_GETDEVCAPS_CAN_RECORD:
+ lpParms->dwReturn = TRUE;
+ break;
+ case MCI_GETDEVCAPS_HAS_AUDIO:
+ lpParms->dwReturn = TRUE;
+ break;
+ case MCI_GETDEVCAPS_HAS_VIDEO:
+ lpParms->dwReturn = FALSE;
+ break;
+ case MCI_GETDEVCAPS_DEVICE_TYPE:
+ lpParms->dwReturn = MCI_DEVTYPE_WAVEFORM_AUDIO;
+ break;
+ case MCI_GETDEVCAPS_USES_FILES:
+ lpParms->dwReturn = TRUE;
+ break;
+ case MCI_GETDEVCAPS_COMPOUND_DEVICE:
+ lpParms->dwReturn = TRUE;
+ break;
+ case MCI_GETDEVCAPS_CAN_EJECT:
+ lpParms->dwReturn = FALSE;
+ break;
+ case MCI_GETDEVCAPS_CAN_PLAY:
+ lpParms->dwReturn = TRUE;
+ break;
+ case MCI_GETDEVCAPS_CAN_SAVE:
+ lpParms->dwReturn = FALSE;
+ break;
+ case MCI_WAVE_GETDEVCAPS_INPUTS:
+ lpParms->dwReturn = 1;
+ break;
+ case MCI_WAVE_GETDEVCAPS_OUTPUTS:
+ lpParms->dwReturn = 1;
+ break;
+ default:
+ return MCIERR_UNRECOGNIZED_COMMAND;
+ }
+ }
+ return 0;
+}
+
+/**************************************************************************
+* WAVE_mciInfo [internal]
+*/
+DWORD WAVE_mciInfo(UINT wDevID, DWORD dwFlags, LPMCI_INFO_PARMS lpParms)
+{
+ printf("WAVE_mciInfo(%u, %08X, %08X);\n", wDevID, dwFlags, lpParms);
+ if (lpParms == NULL) return MCIERR_INTERNAL;
+ lpParms->lpstrReturn = NULL;
+ switch(dwFlags) {
+ case MCI_INFO_PRODUCT:
+ lpParms->lpstrReturn = "Linux Sound System 0.5";
+ break;
+ case MCI_INFO_FILE:
+ lpParms->lpstrReturn = "FileName";
+ break;
+ case MCI_WAVE_INPUT:
+ lpParms->lpstrReturn = "Linux Sound System 0.5";
+ break;
+ case MCI_WAVE_OUTPUT:
+ lpParms->lpstrReturn = "Linux Sound System 0.5";
+ break;
+ default:
+ return MCIERR_UNRECOGNIZED_COMMAND;
+ }
+ if (lpParms->lpstrReturn != NULL)
+ lpParms->dwRetSize = strlen(lpParms->lpstrReturn);
+ else
+ lpParms->dwRetSize = 0;
+ return 0;
+}
+
+
+/*-----------------------------------------------------------------------*/
+
+
+/**************************************************************************
+* wodGetDevCaps [internal]
+*/
+DWORD wodGetDevCaps(WORD wDevID, LPWAVEOUTCAPS lpCaps, DWORD dwSize)
+{
+ int audio;
+ int smplrate;
+ int samplesize = 16;
+ int dsp_stereo = 1;
+ int bytespersmpl;
+ printf("wodGetDevCaps(%u, %08X, %u);\n", wDevID, lpCaps, dwSize);
+ if (lpCaps == NULL) return MMSYSERR_NOTENABLED;
+ audio = open (SOUND_DEV, O_WRONLY, 0);
+ if (audio == -1) return MMSYSERR_NOTENABLED;
+ lpCaps->wMid = 0xFF; /* Manufac ID */
+ lpCaps->wPid = 0x01; /* Product ID */
+ strcpy(lpCaps->szPname, "Linux WAV Driver");
+ lpCaps->dwFormats = 0;
+ lpCaps->dwSupport = 0;
+ lpCaps->wChannels = (IOCTL(audio, SNDCTL_DSP_STEREO, dsp_stereo) != 0) ? 1 : 2;
+ bytespersmpl = (IOCTL(audio, SNDCTL_DSP_SAMPLESIZE, samplesize) != 0) ? 1 : 2;
+ smplrate = 44100;
+ if (IOCTL(audio, SNDCTL_DSP_SPEED, smplrate) == 0) {
+ lpCaps->dwFormats |= WAVE_FORMAT_4M08;
+ if (lpCaps->wChannels > 1) lpCaps->dwFormats |= WAVE_FORMAT_4S08;
+ if (bytespersmpl > 1) {
+ lpCaps->dwFormats |= WAVE_FORMAT_4M16;
+ if (lpCaps->wChannels > 1) lpCaps->dwFormats |= WAVE_FORMAT_4S16;
+ }
+ }
+ smplrate = 22050;
+ if (IOCTL(audio, SNDCTL_DSP_SPEED, smplrate) == 0) {
+ lpCaps->dwFormats |= WAVE_FORMAT_2M08;
+ if (lpCaps->wChannels > 1) lpCaps->dwFormats |= WAVE_FORMAT_2S08;
+ if (bytespersmpl > 1) {
+ lpCaps->dwFormats |= WAVE_FORMAT_2M16;
+ if (lpCaps->wChannels > 1) lpCaps->dwFormats |= WAVE_FORMAT_2S16;
+ }
+ }
+ smplrate = 11025;
+ if (IOCTL(audio, SNDCTL_DSP_SPEED, smplrate) == 0) {
+ lpCaps->dwFormats |= WAVE_FORMAT_1M08;
+ if (lpCaps->wChannels > 1) lpCaps->dwFormats |= WAVE_FORMAT_1S08;
+ if (bytespersmpl > 1) {
+ lpCaps->dwFormats |= WAVE_FORMAT_1M16;
+ if (lpCaps->wChannels > 1) lpCaps->dwFormats |= WAVE_FORMAT_1S16;
+ }
+ }
+ close(audio);
+ printf("wodGetDevCaps // dwFormats = %08X\n", lpCaps->dwFormats);
+ return MMSYSERR_NOERROR;
+}
+
+
+/**************************************************************************
+* wodOpen [internal]
+*/
+DWORD wodOpen(WORD wDevID, LPWAVEOPENDESC lpDesc, DWORD dwFlags)
+{
+ int audio;
+ int abuf_size;
+ int smplrate;
+ int samplesize;
+ int dsp_stereo;
+ printf("wodOpen(%u, %08X, %08X);\n", wDevID, lpDesc, dwFlags);
+ if (lpDesc == NULL) {
+ printf("Linux 'wodOpen' // Invalid Parameter !\n");
+ return MMSYSERR_INVALPARAM;
+ }
+ if (wDevID >= MAX_WAVOUTDRV) {
+ printf("Linux 'wodOpen' // MAX_WAVOUTDRV reached !\n");
+ return MMSYSERR_ALLOCATED;
+ }
+ WOutDev[wDevID].unixdev = 0;
+ audio = open (SOUND_DEV, O_WRONLY, 0);
+ if (audio == -1) {
+ printf("Linux 'wodOpen' // can't open !\n");
+ return MMSYSERR_NOTENABLED;
+ }
+ IOCTL(audio, SNDCTL_DSP_GETBLKSIZE, abuf_size);
+ if (abuf_size < 4096 || abuf_size > 65536) {
+ if (abuf_size == -1)
+ printf("Linux 'wodOpen' // IOCTL can't 'SNDCTL_DSP_GETBLKSIZE' !\n");
+ else
+ printf("Linux 'wodOpen' // SNDCTL_DSP_GETBLKSIZE Invalid bufsize !\n");
+ return MMSYSERR_NOTENABLED;
+ }
+ WOutDev[wDevID].wFlags = HIWORD(dwFlags & CALLBACK_TYPEMASK);
+ switch(WOutDev[wDevID].wFlags) {
+ case DCB_NULL:
+ printf("Linux 'wodOpen' // CALLBACK_NULL !\n");
+ break;
+ case DCB_WINDOW:
+ printf("Linux 'wodOpen' // CALLBACK_WINDOW !\n");
+ break;
+ case DCB_TASK:
+ printf("Linux 'wodOpen' // CALLBACK_TASK !\n");
+ break;
+ case DCB_FUNCTION:
+ printf("Linux 'wodOpen' // CALLBACK_FUNCTION !\n");
+ break;
+ }
+ WOutDev[wDevID].lpQueueHdr = NULL;
+ WOutDev[wDevID].unixdev = audio;
+ WOutDev[wDevID].dwTotalPlayed = 0;
+ WOutDev[wDevID].bufsize = abuf_size;
+ memcpy(&WOutDev[wDevID].waveDesc, lpDesc, sizeof(WAVEOPENDESC));
+ if (lpDesc->lpFormat->wFormatTag != WAVE_FORMAT_PCM) {
+ printf("Linux 'wodOpen' // Bad format %04X !\n",
+ lpDesc->lpFormat->wFormatTag);
+ return WAVERR_BADFORMAT;
+ }
+ memcpy(&WOutDev[wDevID].Format, lpDesc->lpFormat, sizeof(PCMWAVEFORMAT));
+ if (WOutDev[wDevID].Format.wf.nChannels == 0) return WAVERR_BADFORMAT;
+ if (WOutDev[wDevID].Format.wf.nSamplesPerSec == 0) return WAVERR_BADFORMAT;
+ if (WOutDev[wDevID].Format.wBitsPerSample == 0) {
+ WOutDev[wDevID].Format.wBitsPerSample = 8 *
+ (WOutDev[wDevID].Format.wf.nAvgBytesPerSec /
+ WOutDev[wDevID].Format.wf.nSamplesPerSec) /
+ WOutDev[wDevID].Format.wf.nChannels;
+ }
+ samplesize = WOutDev[wDevID].Format.wBitsPerSample;
+ smplrate = WOutDev[wDevID].Format.wf.nSamplesPerSec;
+ dsp_stereo = (WOutDev[wDevID].Format.wf.nChannels > 1) ? TRUE : FALSE;
+ IOCTL(audio, SNDCTL_DSP_SPEED, smplrate);
+ IOCTL(audio, SNDCTL_DSP_SAMPLESIZE, samplesize);
+ IOCTL(audio, SNDCTL_DSP_STEREO, dsp_stereo);
+ printf("Linux 'wodOpen' // wBitsPerSample=%u !\n",
+ WOutDev[wDevID].Format.wBitsPerSample);
+ printf("Linux 'wodOpen' // nSamplesPerSec=%u !\n",
+ WOutDev[wDevID].Format.wf.nSamplesPerSec);
+ printf("Linux 'wodOpen' // nChannels=%u !\n",
+ WOutDev[wDevID].Format.wf.nChannels);
+ if (WAVE_NotifyClient(wDevID, WOM_OPEN, 0L, 0L) != MMSYSERR_NOERROR) {
+ printf("Linux 'wodOpen' // can't notify client !\n");
+ return MMSYSERR_INVALPARAM;
+ }
+ return MMSYSERR_NOERROR;
+}
+
+/**************************************************************************
+* wodClose [internal]
+*/
+DWORD wodClose(WORD wDevID)
+{
+ printf("wodClose(%u);\n", wDevID);
+ if (WOutDev[wDevID].unixdev == 0) {
+ printf("Linux 'wodClose' // can't close !\n");
+ return MMSYSERR_NOTENABLED;
+ }
+ close(WOutDev[wDevID].unixdev);
+ WOutDev[wDevID].unixdev = 0;
+ WOutDev[wDevID].bufsize = 0;
+ if (WAVE_NotifyClient(wDevID, WOM_CLOSE, 0L, 0L) != MMSYSERR_NOERROR) {
+ printf("Linux 'wodClose' // can't notify client !\n");
+ return MMSYSERR_INVALPARAM;
+ }
+ return MMSYSERR_NOERROR;
+}
+
+/**************************************************************************
+* wodWrite [internal]
+*/
+DWORD wodWrite(WORD wDevID, LPWAVEHDR lpWaveHdr, DWORD dwSize)
+{
+ printf("wodWrite(%u, %08X, %08X);\n", wDevID, lpWaveHdr, dwSize);
+ if (WOutDev[wDevID].unixdev == 0) {
+ printf("Linux 'wodWrite' // can't play !\n");
+ return MMSYSERR_NOTENABLED;
+ }
+ if (lpWaveHdr->lpData == NULL) return WAVERR_UNPREPARED;
+ if (!(lpWaveHdr->dwFlags & WHDR_PREPARED)) return WAVERR_UNPREPARED;
+ if (lpWaveHdr->dwFlags & WHDR_INQUEUE) return WAVERR_STILLPLAYING;
+ lpWaveHdr->dwFlags &= ~WHDR_DONE;
+ lpWaveHdr->dwFlags |= WHDR_INQUEUE;
+ printf("wodWrite() // dwBytesRecorded %u !\n", lpWaveHdr->dwBytesRecorded);
+ if (write (WOutDev[wDevID].unixdev, lpWaveHdr->lpData,
+ lpWaveHdr->dwBytesRecorded) != lpWaveHdr->dwBytesRecorded) {
+ return MMSYSERR_NOTENABLED;
+ }
+ lpWaveHdr->dwFlags &= ~WHDR_INQUEUE;
+ lpWaveHdr->dwFlags |= WHDR_DONE;
+ if (WAVE_NotifyClient(wDevID, WOM_DONE, 0L, 0L) != MMSYSERR_NOERROR) {
+ printf("Linux 'wodWrite' // can't notify client !\n");
+ return MMSYSERR_INVALPARAM;
+ }
+ return MMSYSERR_NOERROR;
+}
+
+/**************************************************************************
+* wodPrepare [internal]
+*/
+DWORD wodPrepare(WORD wDevID, LPWAVEHDR lpWaveHdr, DWORD dwSize)
+{
+ printf("wodPrepare(%u, %08X, %08X);\n", wDevID, lpWaveHdr, dwSize);
+ if (WOutDev[wDevID].unixdev == 0) {
+ printf("Linux 'wodPrepare' // can't prepare !\n");
+ return MMSYSERR_NOTENABLED;
+ }
+ if (WOutDev[wDevID].lpQueueHdr != NULL) {
+ printf("Linux 'wodPrepare' // already prepare !\n");
+ return MMSYSERR_NOTENABLED;
+ }
+ WOutDev[wDevID].dwTotalPlayed = 0;
+ WOutDev[wDevID].lpQueueHdr = lpWaveHdr;
+ if (lpWaveHdr->dwFlags & WHDR_INQUEUE) return WAVERR_STILLPLAYING;
+ lpWaveHdr->dwFlags |= WHDR_PREPARED;
+ lpWaveHdr->dwFlags &= ~WHDR_DONE;
+ return MMSYSERR_NOERROR;
+}
+
+/**************************************************************************
+* wodUnprepare [internal]
+*/
+DWORD wodUnprepare(WORD wDevID, LPWAVEHDR lpWaveHdr, DWORD dwSize)
+{
+ printf("wodUnprepare(%u, %08X, %08X);\n", wDevID, lpWaveHdr, dwSize);
+ if (WOutDev[wDevID].unixdev == 0) {
+ printf("Linux 'wodUnprepare' // can't unprepare !\n");
+ return MMSYSERR_NOTENABLED;
+ }
+ return MMSYSERR_NOERROR;
+}
+
+/**************************************************************************
+* wodRestart [internal]
+*/
+DWORD wodRestart(WORD wDevID)
+{
+ printf("wodRestart(%u);\n", wDevID);
+ if (WOutDev[wDevID].unixdev == 0) {
+ printf("Linux 'wodRestart' // can't restart !\n");
+ return MMSYSERR_NOTENABLED;
+ }
+ return MMSYSERR_NOERROR;
+}
+
+/**************************************************************************
+* wodReset [internal]
+*/
+DWORD wodReset(WORD wDevID)
+{
+ printf("wodReset(%u);\n", wDevID);
+ if (WOutDev[wDevID].unixdev == 0) {
+ printf("Linux 'wodReset' // can't reset !\n");
+ return MMSYSERR_NOTENABLED;
+ }
+ return MMSYSERR_NOERROR;
+}
+
+
+/**************************************************************************
+* wodGetPosition [internal]
+*/
+DWORD wodGetPosition(WORD wDevID, LPMMTIME lpTime, DWORD uSize)
+{
+ int time;
+ printf("wodGetPosition(%u, %08X, %u);\n", wDevID, lpTime, uSize);
+ if (WOutDev[wDevID].unixdev == 0) {
+ printf("Linux 'wodGetPosition' // can't get pos !\n");
+ return MMSYSERR_NOTENABLED;
+ }
+ if (lpTime == NULL) return MMSYSERR_INVALPARAM;
+TryAGAIN:
+ switch(lpTime->wType) {
+ case TIME_BYTES:
+ lpTime->u.cb = WOutDev[wDevID].dwTotalPlayed;
+ printf("wodGetPosition // TIME_BYTES=%u\n", lpTime->u.cb);
+ break;
+ case TIME_SAMPLES:
+ lpTime->u.sample = WOutDev[wDevID].dwTotalPlayed * 8 /
+ WOutDev[wDevID].Format.wBitsPerSample;
+ printf("wodGetPosition // TIME_SAMPLES=%u\n", lpTime->u.sample);
+ break;
+ case TIME_MS:
+ lpTime->u.ms = WOutDev[wDevID].dwTotalPlayed /
+ (WOutDev[wDevID].Format.wf.nAvgBytesPerSec / 1000);
+ printf("wodGetPosition // TIME_MS=%u\n", lpTime->u.ms);
+ break;
+ case TIME_SMPTE:
+ time = WOutDev[wDevID].dwTotalPlayed /
+ (WOutDev[wDevID].Format.wf.nAvgBytesPerSec / 1000);
+ lpTime->u.smpte.hour = time / 108000;
+ time -= lpTime->u.smpte.hour * 108000;
+ lpTime->u.smpte.min = time / 1800;
+ time -= lpTime->u.smpte.min * 1800;
+ lpTime->u.smpte.sec = time / 30;
+ time -= lpTime->u.smpte.sec * 30;
+ lpTime->u.smpte.frame = time;
+ lpTime->u.smpte.fps = 30;
+ printf("wodGetPosition // TIME_SMPTE=%02u:%02u:%02u:%02u\n",
+ lpTime->u.smpte.hour, lpTime->u.smpte.min,
+ lpTime->u.smpte.sec, lpTime->u.smpte.frame);
+ break;
+ default:
+ printf("wodGetPosition() format not supported ! use TIME_MS !\n");
+ lpTime->wType = TIME_MS;
+ goto TryAGAIN;
+ }
+ return MMSYSERR_NOERROR;
+}
+
+/**************************************************************************
+* wodSetVolume [internal]
+*/
+DWORD wodSetVolume(WORD wDevID, DWORD dwParam)
+{
+ int mixer;
+ int volume = 50;
+ printf("wodSetVolume(%u, %08X);\n", wDevID, dwParam);
+ if (WOutDev[wDevID].unixdev == 0) {
+ printf("Linux 'wodSetVolume' // can't set volume !\n");
+ return MMSYSERR_NOTENABLED;
+ }
+ if ((mixer = open("/dev/mixer", O_RDWR)) < 0) {
+ printf("Linux 'wodSetVolume' // mixer device not available !\n");
+ return MMSYSERR_NOTENABLED;
+ }
+ if (ioctl(mixer, SOUND_MIXER_WRITE_PCM, &volume) == -1) {
+ printf("Linux 'wodSetVolume' // unable set mixer !\n");
+ return MMSYSERR_NOTENABLED;
+ }
+ close(mixer);
+ return MMSYSERR_NOERROR;
+}
+
+
+/**************************************************************************
* wodMessage [sample driver]
*/
DWORD wodMessage(WORD wDevID, WORD wMsg, DWORD dwUser,
DWORD dwParam1, DWORD dwParam2)
{
+ printf("wodMessage(%u, %04X, %08X, %08X, %08X);\n",
+ wDevID, wMsg, dwUser, dwParam1, dwParam2);
+ switch(wMsg) {
+ case WODM_OPEN:
+ return wodOpen(wDevID, (LPWAVEOPENDESC)dwParam1, dwParam2);
+ case WODM_CLOSE:
+ return wodClose(wDevID);
+ case WODM_WRITE:
+ return wodWrite(wDevID, (LPWAVEHDR)dwParam1, dwParam2);
+ case WODM_PAUSE:
+ return 0L;
+ case WODM_GETPOS:
+ return wodGetPosition(wDevID, (LPMMTIME)dwParam1, dwParam2);
+ case WODM_BREAKLOOP:
+ return 0L;
+ case WODM_PREPARE:
+ return wodPrepare(wDevID, (LPWAVEHDR)dwParam1, dwParam2);
+ case WODM_UNPREPARE:
+ return wodUnprepare(wDevID, (LPWAVEHDR)dwParam1, dwParam2);
+ case WODM_GETDEVCAPS:
+ return wodGetDevCaps(wDevID, (LPWAVEOUTCAPS)dwParam1, dwParam2);
+ case WODM_GETNUMDEVS:
+ return 1L;
+ case WODM_GETPITCH:
+ return 0L;
+ case WODM_SETPITCH:
+ return 0L;
+ case WODM_GETPLAYBACKRATE:
+ return 0L;
+ case WODM_SETPLAYBACKRATE:
+ return 0L;
+ case WODM_GETVOLUME:
+ return 0L;
+ case WODM_SETVOLUME:
+ return wodSetVolume(wDevID, dwParam1);
+ case WODM_RESTART:
+ return wodRestart(wDevID);
+ case WODM_RESET:
+ return wodReset(wDevID);
+ }
+ return MMSYSERR_NOTSUPPORTED;
+}
+
+
+/*-----------------------------------------------------------------------*/
+
+/**************************************************************************
+* widGetDevCaps [internal]
+*/
+DWORD widGetDevCaps(WORD wDevID, LPWAVEINCAPS lpCaps, DWORD dwSize)
+{
+ int audio;
+ int smplrate;
+ int samplesize = 16;
+ int dsp_stereo = 1;
+ int bytespersmpl;
+ printf("widGetDevCaps(%u, %08X, %u);\n", wDevID, lpCaps, dwSize);
+ if (lpCaps == NULL) return MMSYSERR_NOTENABLED;
+ audio = open (SOUND_DEV, O_RDONLY, 0);
+ if (audio == -1) return MMSYSERR_NOTENABLED;
+ lpCaps->wMid = 0xFF; /* Manufac ID */
+ lpCaps->wPid = 0x01; /* Product ID */
+ strcpy(lpCaps->szPname, "Linux WAV Driver");
+ lpCaps->dwFormats = 0;
+ lpCaps->wChannels = (IOCTL(audio, SNDCTL_DSP_STEREO, dsp_stereo) != 0) ? 1 : 2;
+ bytespersmpl = (IOCTL(audio, SNDCTL_DSP_SAMPLESIZE, samplesize) != 0) ? 1 : 2;
+ smplrate = 44100;
+ if (IOCTL(audio, SNDCTL_DSP_SPEED, smplrate) == 0) {
+ lpCaps->dwFormats |= WAVE_FORMAT_4M08;
+ if (lpCaps->wChannels > 1) lpCaps->dwFormats |= WAVE_FORMAT_4S08;
+ if (bytespersmpl > 1) {
+ lpCaps->dwFormats |= WAVE_FORMAT_4M16;
+ if (lpCaps->wChannels > 1) lpCaps->dwFormats |= WAVE_FORMAT_4S16;
+ }
+ }
+ smplrate = 22050;
+ if (IOCTL(audio, SNDCTL_DSP_SPEED, smplrate) == 0) {
+ lpCaps->dwFormats |= WAVE_FORMAT_2M08;
+ if (lpCaps->wChannels > 1) lpCaps->dwFormats |= WAVE_FORMAT_2S08;
+ if (bytespersmpl > 1) {
+ lpCaps->dwFormats |= WAVE_FORMAT_2M16;
+ if (lpCaps->wChannels > 1) lpCaps->dwFormats |= WAVE_FORMAT_2S16;
+ }
+ }
+ smplrate = 11025;
+ if (IOCTL(audio, SNDCTL_DSP_SPEED, smplrate) == 0) {
+ lpCaps->dwFormats |= WAVE_FORMAT_1M08;
+ if (lpCaps->wChannels > 1) lpCaps->dwFormats |= WAVE_FORMAT_1S08;
+ if (bytespersmpl > 1) {
+ lpCaps->dwFormats |= WAVE_FORMAT_1M16;
+ if (lpCaps->wChannels > 1) lpCaps->dwFormats |= WAVE_FORMAT_1S16;
+ }
+ }
+ close(audio);
+ printf("widGetDevCaps // dwFormats = %08X\n", lpCaps->dwFormats);
+ return MMSYSERR_NOERROR;
+}
+
+
+/**************************************************************************
+* widOpen [internal]
+*/
+DWORD widOpen(WORD wDevID, LPWAVEOPENDESC lpDesc, DWORD dwFlags)
+{
+ int audio;
+ int abuf_size;
+ int smplrate;
+ int samplesize;
+ int dsp_stereo;
+ printf("widOpen(%u, %08X, %08X);\n", wDevID, lpDesc, dwFlags);
+ if (lpDesc == NULL) {
+ printf("Linux 'widOpen' // Invalid Parameter !\n");
+ return MMSYSERR_INVALPARAM;
+ }
+ if (wDevID >= MAX_WAVINDRV) {
+ printf("Linux 'widOpen' // MAX_WAVINDRV reached !\n");
+ return MMSYSERR_ALLOCATED;
+ }
+ WInDev[wDevID].unixdev = 0;
+ audio = open (SOUND_DEV, O_RDONLY, 0);
+ if (audio == -1) {
+ printf("Linux 'widOpen' // can't open !\n");
+ return MMSYSERR_NOTENABLED;
+ }
+ IOCTL(audio, SNDCTL_DSP_GETBLKSIZE, abuf_size);
+ if (abuf_size < 4096 || abuf_size > 65536) {
+ if (abuf_size == -1)
+ printf("Linux 'widOpen' // IOCTL can't 'SNDCTL_DSP_GETBLKSIZE' !\n");
+ else
+ printf("Linux 'widOpen' // SNDCTL_DSP_GETBLKSIZE Invalid bufsize !\n");
+ return MMSYSERR_NOTENABLED;
+ }
+ WInDev[wDevID].wFlags = HIWORD(dwFlags & CALLBACK_TYPEMASK);
+ switch(WInDev[wDevID].wFlags) {
+ case DCB_NULL:
+ printf("Linux 'widOpen' // CALLBACK_NULL !\n");
+ break;
+ case DCB_WINDOW:
+ printf("Linux 'widOpen' // CALLBACK_WINDOW !\n");
+ break;
+ case DCB_TASK:
+ printf("Linux 'widOpen' // CALLBACK_TASK !\n");
+ break;
+ case DCB_FUNCTION:
+ printf("Linux 'widOpen' // CALLBACK_FUNCTION !\n");
+ break;
+ }
+ WInDev[wDevID].lpQueueHdr = NULL;
+ WInDev[wDevID].unixdev = audio;
+ WInDev[wDevID].bufsize = abuf_size;
+ WInDev[wDevID].dwTotalRecorded = 0;
+ memcpy(&WInDev[wDevID].waveDesc, lpDesc, sizeof(WAVEOPENDESC));
+ if (lpDesc->lpFormat->wFormatTag != WAVE_FORMAT_PCM) {
+ printf("Linux 'widOpen' // Bad format %04X !\n",
+ lpDesc->lpFormat->wFormatTag);
+ return WAVERR_BADFORMAT;
+ }
+ memcpy(&WInDev[wDevID].Format, lpDesc->lpFormat, sizeof(PCMWAVEFORMAT));
+ WInDev[wDevID].Format.wBitsPerSample = 8; /* <-------------- */
+ if (WInDev[wDevID].Format.wf.nChannels == 0) return WAVERR_BADFORMAT;
+ if (WInDev[wDevID].Format.wf.nSamplesPerSec == 0) return WAVERR_BADFORMAT;
+ if (WInDev[wDevID].Format.wBitsPerSample == 0) {
+ WInDev[wDevID].Format.wBitsPerSample = 8 *
+ (WInDev[wDevID].Format.wf.nAvgBytesPerSec /
+ WInDev[wDevID].Format.wf.nSamplesPerSec) /
+ WInDev[wDevID].Format.wf.nChannels;
+ }
+ samplesize = WInDev[wDevID].Format.wBitsPerSample;
+ smplrate = WInDev[wDevID].Format.wf.nSamplesPerSec;
+ dsp_stereo = (WInDev[wDevID].Format.wf.nChannels > 1) ? TRUE : FALSE;
+ IOCTL(audio, SNDCTL_DSP_SPEED, smplrate);
+ IOCTL(audio, SNDCTL_DSP_SAMPLESIZE, samplesize);
+ IOCTL(audio, SNDCTL_DSP_STEREO, dsp_stereo);
+#ifdef DEBUG_MCIWAVE
+ printf("Linux 'widOpen' // wBitsPerSample=%u !\n",
+ WInDev[wDevID].Format.wBitsPerSample);
+ printf("Linux 'widOpen' // nSamplesPerSec=%u !\n",
+ WInDev[wDevID].Format.wf.nSamplesPerSec);
+ printf("Linux 'widOpen' // nChannels=%u !\n",
+ WInDev[wDevID].Format.wf.nChannels);
+ printf("Linux 'widOpen' // nAvgBytesPerSec=%u\n",
+ WInDev[wDevID].Format.wf.nAvgBytesPerSec);
+#endif
+ if (WAVE_NotifyClient(wDevID, WIM_OPEN, 0L, 0L) != MMSYSERR_NOERROR) {
+ printf("Linux 'widOpen' // can't notify client !\n");
+ return MMSYSERR_INVALPARAM;
+ }
+ return MMSYSERR_NOERROR;
+}
+
+/**************************************************************************
+* widClose [internal]
+*/
+DWORD widClose(WORD wDevID)
+{
+ printf("widClose(%u);\n", wDevID);
+ if (WInDev[wDevID].unixdev == 0) {
+ printf("Linux 'widClose' // can't close !\n");
+ return MMSYSERR_NOTENABLED;
+ }
+ close(WInDev[wDevID].unixdev);
+ WInDev[wDevID].unixdev = 0;
+ WInDev[wDevID].bufsize = 0;
+ if (WAVE_NotifyClient(wDevID, WIM_CLOSE, 0L, 0L) != MMSYSERR_NOERROR) {
+ printf("Linux 'widClose' // can't notify client !\n");
+ return MMSYSERR_INVALPARAM;
+ }
+ return MMSYSERR_NOERROR;
+}
+
+/**************************************************************************
+* widAddBuffer [internal]
+*/
+DWORD widAddBuffer(WORD wDevID, LPWAVEHDR lpWaveHdr, DWORD dwSize)
+{
+ int count = 1;
+ LPWAVEHDR lpWIHdr;
+ printf("widAddBuffer(%u, %08X, %08X);\n", wDevID, lpWaveHdr, dwSize);
+ if (WInDev[wDevID].unixdev == 0) {
+ printf("Linux 'widAddBuffer' // can't do it !\n");
+ return MMSYSERR_NOTENABLED;
+ }
+ if (WInDev[wDevID].lpQueueHdr == NULL ||
+ !(lpWaveHdr->dwFlags & WHDR_PREPARED)) {
+ printf("Linux 'widAddBuffer' // never been prepared !\n");
+ return WAVERR_UNPREPARED;
+ }
+ if ((lpWaveHdr->dwFlags & WHDR_INQUEUE) &&
+ (WInDev[wDevID].lpQueueHdr != lpWaveHdr)) {
+ /* except if it's the one just prepared ... */
+ printf("Linux 'widAddBuffer' // header already in use !\n");
+ return WAVERR_STILLPLAYING;
+ }
+ lpWaveHdr->dwFlags |= WHDR_PREPARED;
+ lpWaveHdr->dwFlags |= WHDR_INQUEUE;
+ lpWaveHdr->dwFlags &= ~WHDR_DONE;
+ lpWaveHdr->dwBytesRecorded = 0;
+ /* added to the queue, except if it's the one just prepared ... */
+ if (WInDev[wDevID].lpQueueHdr != lpWaveHdr) {
+ lpWIHdr = WInDev[wDevID].lpQueueHdr;
+ while (lpWIHdr->lpNext != NULL) {
+ lpWIHdr = lpWIHdr->lpNext;
+ count++;
+ }
+ lpWIHdr->lpNext = lpWaveHdr;
+ count++;
+ }
+ printf("widAddBuffer // buffer added ! (now %u in queue)\n", count);
+ return MMSYSERR_NOERROR;
+}
+
+/**************************************************************************
+* widPrepare [internal]
+*/
+DWORD widPrepare(WORD wDevID, LPWAVEHDR lpWaveHdr, DWORD dwSize)
+{
+ printf("widPrepare(%u, %08X, %08X);\n", wDevID, lpWaveHdr, dwSize);
+ if (WInDev[wDevID].unixdev == 0) {
+ printf("Linux 'widPrepare' // can't prepare !\n");
+ return MMSYSERR_NOTENABLED;
+ }
+ if (WInDev[wDevID].lpQueueHdr != NULL) {
+ printf("Linux 'widPrepare' // already prepare !\n");
+ return WAVERR_BADFORMAT;
+ }
+ WInDev[wDevID].dwTotalRecorded = 0;
+ WInDev[wDevID].lpQueueHdr = lpWaveHdr;
+ if (lpWaveHdr->dwFlags & WHDR_INQUEUE) return WAVERR_STILLPLAYING;
+ lpWaveHdr->dwFlags |= WHDR_PREPARED;
+ lpWaveHdr->dwFlags |= WHDR_INQUEUE;
+ lpWaveHdr->dwFlags &= ~WHDR_DONE;
+ lpWaveHdr->dwBytesRecorded = 0;
+ printf("Linux 'widPrepare' // header prepared !\n");
+ return MMSYSERR_NOERROR;
+}
+
+/**************************************************************************
+* widUnprepare [internal]
+*/
+DWORD widUnprepare(WORD wDevID, LPWAVEHDR lpWaveHdr, DWORD dwSize)
+{
+ printf("widUnprepare(%u, %08X, %08X);\n", wDevID, lpWaveHdr, dwSize);
+ if (WInDev[wDevID].unixdev == 0) {
+ printf("Linux 'widUnprepare' // can't unprepare !\n");
+ return MMSYSERR_NOTENABLED;
+ }
+ lpWaveHdr->dwFlags &= ~WHDR_PREPARED;
+ lpWaveHdr->dwFlags &= ~WHDR_INQUEUE;
+ lpWaveHdr->dwFlags |= WHDR_DONE;
+ WInDev[wDevID].lpQueueHdr = NULL;
+ printf("Linux 'widUnprepare' // all headers unprepared !\n");
+ return MMSYSERR_NOERROR;
+}
+
+/**************************************************************************
+* widStart [internal]
+*/
+DWORD widStart(WORD wDevID)
+{
+ int count = 1;
+ LPWAVEHDR lpWIHdr;
+ printf("widStart(%u);\n", wDevID);
+ if (WInDev[wDevID].unixdev == 0) {
+ printf("Linux 'widStart' // can't start recording !\n");
+ return MMSYSERR_NOTENABLED;
+ }
+ if (WInDev[wDevID].lpQueueHdr == NULL ||
+ WInDev[wDevID].lpQueueHdr->lpData == NULL) {
+ printf("Linux 'widStart' // never been prepared !\n");
+ return WAVERR_UNPREPARED;
+ }
+ lpWIHdr = WInDev[wDevID].lpQueueHdr;
+ while(lpWIHdr != NULL) {
+ lpWIHdr->dwBufferLength &= 0xFFFF;
+ printf("widStart // recording buf#%u=%08X size=%u \n",
+ count, lpWIHdr->lpData, lpWIHdr->dwBufferLength);
+ fflush(stdout);
+ read (WInDev[wDevID].unixdev, lpWIHdr->lpData,
+ lpWIHdr->dwBufferLength);
+ lpWIHdr->dwBytesRecorded = lpWIHdr->dwBufferLength;
+ WInDev[wDevID].dwTotalRecorded += lpWIHdr->dwBytesRecorded;
+ lpWIHdr->dwFlags &= ~WHDR_INQUEUE;
+ lpWIHdr->dwFlags |= WHDR_DONE;
+ if (WAVE_NotifyClient(wDevID, WIM_DATA, (DWORD)lpWIHdr, 0L) !=
+ MMSYSERR_NOERROR) {
+ printf("Linux 'widStart' // can't notify client !\n");
+ return MMSYSERR_INVALPARAM;
+ }
+ lpWIHdr = lpWIHdr->lpNext;
+ count++;
+ }
+ printf("widStart // end of recording !\n");
+ fflush(stdout);
+ return MMSYSERR_NOERROR;
+}
+
+/**************************************************************************
+* widStop [internal]
+*/
+DWORD widStop(WORD wDevID)
+{
+ printf("widStop(%u);\n", wDevID);
+ if (WInDev[wDevID].unixdev == 0) {
+ printf("Linux 'widStop' // can't stop !\n");
+ return MMSYSERR_NOTENABLED;
+ }
+ return MMSYSERR_NOERROR;
+}
+
+/**************************************************************************
+* widReset [internal]
+*/
+DWORD widReset(WORD wDevID)
+{
+ printf("widReset(%u);\n", wDevID);
+ if (WInDev[wDevID].unixdev == 0) {
+ printf("Linux 'widReset' // can't reset !\n");
+ return MMSYSERR_NOTENABLED;
+ }
+ return MMSYSERR_NOERROR;
+}
+
+/**************************************************************************
+* widGetPosition [internal]
+*/
+DWORD widGetPosition(WORD wDevID, LPMMTIME lpTime, DWORD uSize)
+{
+ int time;
+#ifdef DEBUG_MCIWAVE
+ printf("widGetPosition(%u, %08X, %u);\n", wDevID, lpTime, uSize);
+#endif
+ if (WInDev[wDevID].unixdev == 0) {
+ printf("Linux 'widGetPosition' // can't get pos !\n");
+ return MMSYSERR_NOTENABLED;
+ }
+ if (lpTime == NULL) return MMSYSERR_INVALPARAM;
+TryAGAIN:
+#ifdef DEBUG_MCIWAVE
+ printf("widGetPosition // wType=%04X !\n", lpTime->wType);
+ printf("widGetPosition // wBitsPerSample=%u\n",
+ WInDev[wDevID].Format.wBitsPerSample);
+ printf("widGetPosition // nSamplesPerSec=%u\n",
+ WInDev[wDevID].Format.wf.nSamplesPerSec);
+ printf("widGetPosition // nChannels=%u\n",
+ WInDev[wDevID].Format.wf.nChannels);
+ printf("widGetPosition // nAvgBytesPerSec=%u\n",
+ WInDev[wDevID].Format.wf.nAvgBytesPerSec);
+ fflush(stdout);
+#endif
+ switch(lpTime->wType) {
+ case TIME_BYTES:
+ lpTime->u.cb = WInDev[wDevID].dwTotalRecorded;
+ printf("widGetPosition // TIME_BYTES=%u\n", lpTime->u.cb);
+ break;
+ case TIME_SAMPLES:
+ lpTime->u.sample = WInDev[wDevID].dwTotalRecorded * 8 /
+ WInDev[wDevID].Format.wBitsPerSample;
+ printf("widGetPosition // TIME_SAMPLES=%u\n", lpTime->u.sample);
+ break;
+ case TIME_MS:
+ lpTime->u.ms = WInDev[wDevID].dwTotalRecorded /
+ (WInDev[wDevID].Format.wf.nAvgBytesPerSec / 1000);
+ printf("widGetPosition // TIME_MS=%u\n", lpTime->u.ms);
+ break;
+ case TIME_SMPTE:
+ time = WInDev[wDevID].dwTotalRecorded /
+ (WInDev[wDevID].Format.wf.nAvgBytesPerSec / 1000);
+ lpTime->u.smpte.hour = time / 108000;
+ time -= lpTime->u.smpte.hour * 108000;
+ lpTime->u.smpte.min = time / 1800;
+ time -= lpTime->u.smpte.min * 1800;
+ lpTime->u.smpte.sec = time / 30;
+ time -= lpTime->u.smpte.sec * 30;
+ lpTime->u.smpte.frame = time;
+ lpTime->u.smpte.fps = 30;
+ printf("widGetPosition // TIME_SMPTE=%02u:%02u:%02u:%02u\n",
+ lpTime->u.smpte.hour, lpTime->u.smpte.min,
+ lpTime->u.smpte.sec, lpTime->u.smpte.frame);
+ break;
+ default:
+ printf("widGetPosition() format not supported ! use TIME_MS !\n");
+ lpTime->wType = TIME_MS;
+ goto TryAGAIN;
+ }
+ return MMSYSERR_NOERROR;
}
/**************************************************************************
@@ -62,15 +1454,39 @@
DWORD widMessage(WORD wDevID, WORD wMsg, DWORD dwUser,
DWORD dwParam1, DWORD dwParam2)
{
+ printf("widMessage(%u, %04X, %08X, %08X, %08X);\n",
+ wDevID, wMsg, dwUser, dwParam1, dwParam2);
+ switch(wMsg) {
+ case WIDM_OPEN:
+ return widOpen(wDevID, (LPWAVEOPENDESC)dwParam1, dwParam2);
+ case WIDM_CLOSE:
+ return widClose(wDevID);
+ case WIDM_ADDBUFFER:
+ return widAddBuffer(wDevID, (LPWAVEHDR)dwParam1, dwParam2);
+ case WIDM_PREPARE:
+ return widPrepare(wDevID, (LPWAVEHDR)dwParam1, dwParam2);
+ case WIDM_UNPREPARE:
+ return widUnprepare(wDevID, (LPWAVEHDR)dwParam1, dwParam2);
+ case WIDM_GETDEVCAPS:
+ return widGetDevCaps(wDevID, (LPWAVEINCAPS)dwParam1, dwParam2);
+ case WIDM_GETNUMDEVS:
+ return 1L;
+ case WIDM_GETPOS:
+ return widGetPosition(wDevID, (LPMMTIME)dwParam1, dwParam2);
+ case WIDM_RESET:
+ return widReset(wDevID);
+ case WIDM_START:
+ return widStart(wDevID);
+ case WIDM_STOP:
+ return widStop(wDevID);
+ }
+ return MMSYSERR_NOTSUPPORTED;
}
-/**************************************************************************
-* auxMessage [sample driver]
-*/
-DWORD auxMessage(WORD wDevID, WORD wMsg, DWORD dwUser,
- DWORD dwParam1, DWORD dwParam2)
-{
-}
+
+/*-----------------------------------------------------------------------*/
+
+
/**************************************************************************
* midMessage [sample driver]
@@ -78,6 +1494,7 @@
DWORD midMessage(WORD wDevID, WORD wMsg, DWORD dwUser,
DWORD dwParam1, DWORD dwParam2)
{
+ return MMSYSERR_NOTENABLED;
}
/**************************************************************************
@@ -86,12 +1503,7 @@
DWORD modMessage(WORD wDevID, WORD wMsg, DWORD dwUser,
DWORD dwParam1, DWORD dwParam2)
{
+ return MMSYSERR_NOTENABLED;
}
-/*
-BOOL DriverCallback(DWORD dwCallBack, UINT uFlags, HANDLE hDev,
- WORD wMsg, DWORD dwUser, DWORD dwParam1, DWORD dwParam2);
-*/
-
-
diff --git a/misc/comm.c b/misc/comm.c
index 8f7f9bc..4c6edfb 100644
--- a/misc/comm.c
+++ b/misc/comm.c
@@ -18,21 +18,12 @@
#include "wine.h"
#include "windows.h"
+#include "comm.h"
/* #define DEBUG_COMM /* */
-#define MAX_PORTS 16
-
int commerror = 0, eventmask = 0;
-struct DosDeviceStruct {
- char *devicename; /* /dev/cua1 */
- int fd;
- int suspended;
- int unget;
- int unget_byte;
-};
-
struct DosDeviceStruct COM[MAX_PORTS];
struct DosDeviceStruct LPT[MAX_PORTS];
diff --git a/misc/dos_fs.c b/misc/dos_fs.c
index dc3b1bb..bb1d3e5 100644
--- a/misc/dos_fs.c
+++ b/misc/dos_fs.c
@@ -27,6 +27,7 @@
#include "msdos.h"
#include "prototypes.h"
#include "autoconf.h"
+#include "comm.h"
/* #define DEBUG /* */
@@ -170,6 +171,11 @@
{
WORD equipment;
int diskdrives = 0;
+ int parallelports = 0;
+ int serialports = 0;
+ int x;
+ extern struct DosDeviceStruct COM[MAX_PORTS];
+ extern struct DosDeviceStruct LPT[MAX_PORTS];
/* borrowed from Ralph Brown's interrupt lists
@@ -190,6 +196,12 @@
bit 1: =1 if math co-processor
bit 0: =1 if diskette available for boot
*/
+/* Currently the only of these bits correctly set are:
+ bits 15-14 } Added by William Owen Smith,
+ bits 11-9 } wos@dcs.warwick.ac.uk
+ bits 7-6
+ bit 2 (always set)
+*/
if (DosDrives[0].rootdir != NULL)
diskdrives++;
@@ -197,8 +209,27 @@
diskdrives++;
if (diskdrives)
diskdrives--;
+
+ for (x=0; x!=MAX_PORTS; x++) {
+ if (COM[x].devicename)
+ serialports++;
+ if (LPT[x].devicename)
+ parallelports++;
+ }
+ if (serialports > 7) /* 3 bits -- maximum value = 7 */
+ serialports=7;
+ if (parallelports > 3) /* 2 bits -- maximum value = 3 */
+ parallelports=3;
- equipment = (diskdrives << 6) || 0x02;
+ equipment = (diskdrives << 6) | (serialports << 9) |
+ (parallelports << 14) | 0x02;
+
+#ifdef DEBUG
+ fprintf(stderr, "DOS_GetEquipment : diskdrives = %d serialports = %d "
+ "parallelports = %d\n"
+ "DOS_GetEquipment : equipment = %d\n",
+ diskdrives, serialports, parallelports, equipment);
+#endif
return (equipment);
}
diff --git a/misc/file.c b/misc/file.c
index e5d7271..29ed173 100644
--- a/misc/file.c
+++ b/misc/file.c
@@ -61,7 +61,7 @@
/***************************************************************************
_lread
***************************************************************************/
-INT _lread (INT hFile, LPSTR lpBuffer, INT wBytes)
+INT _lread (INT hFile, LPSTR lpBuffer, WORD wBytes)
{
int result;
@@ -81,7 +81,7 @@
/****************************************************************************
_lwrite
****************************************************************************/
-INT _lwrite (INT hFile, LPSTR lpBuffer, INT wBytes)
+INT _lwrite (INT hFile, LPSTR lpBuffer, WORD wBytes)
{
int result;
diff --git a/misc/main.c b/misc/main.c
index f238568..4e94a7a 100644
--- a/misc/main.c
+++ b/misc/main.c
@@ -53,7 +53,6 @@
FALSE, /* usePrivateMap */
FALSE, /* synchronous */
FALSE, /* no backing store */
- FALSE, /* no save unders */
SW_SHOWNORMAL, /* cmdShow */
FALSE
};
@@ -69,7 +68,6 @@
{ "-privatemap", ".privatemap", XrmoptionNoArg, (caddr_t)"on" },
{ "-synchronous", ".synchronous", XrmoptionNoArg, (caddr_t)"on" },
{ "-nobackingstore",".nobackingstore", XrmoptionNoArg, (caddr_t)"on" },
- { "-nosaveunders", ".nosaveunders", XrmoptionNoArg, (caddr_t)"on" },
{ "-spy", ".spy", XrmoptionSepArg, (caddr_t)NULL },
{ "-debug", ".debug", XrmoptionNoArg, (caddr_t)"on" },
{ "-relaydbg", ".relaydbg", XrmoptionNoArg, (caddr_t)"on" }
@@ -90,7 +88,6 @@
" -privatemap Use a private color map\n" \
" -synchronous Turn on synchronous display mode\n" \
" -nobackingstore Turn off backing store\n" \
- " -nosaveunders Turn off saveunders\n" \
" -spy file Turn on message spying to the specified file\n" \
" -relaydbg Display call relay information\n"
@@ -245,8 +242,6 @@
Options.usePrivateMap = TRUE;
if (MAIN_GetResource( db, ".synchronous", &value ))
Options.synchronous = TRUE;
- if (MAIN_GetResource( db, ".nosaveunders", &value ))
- Options.nosaveunders = TRUE;
if (MAIN_GetResource( db, ".nobackingstore", &value ))
Options.nobackingstore = TRUE;
if (MAIN_GetResource( db, ".relaydbg", &value ))
@@ -297,16 +292,11 @@
else
win_attr.backing_store = Always;
- if (Options.nosaveunders)
- win_attr.save_under = FALSE;
- else
- win_attr.save_under = TRUE;
-
rootWindow = XCreateWindow( display, DefaultRootWindow(display),
desktopX, desktopY, width, height, 0,
CopyFromParent, InputOutput, CopyFromParent,
- CWEventMask | CWCursor | CWSaveUnder |
- CWBackingStore, &win_attr );
+ CWEventMask | CWCursor |
+ CWBackingStore, &win_attr );
/* Set window manager properties */
diff --git a/misc/mcicda.c b/misc/mcicda.c
new file mode 100644
index 0000000..55497be
--- /dev/null
+++ b/misc/mcicda.c
@@ -0,0 +1,859 @@
+/*
+ * Sample MCI CDAUDIO Wine Driver for Linux
+ *
+ * Copyright 1994 Martin Ayotte
+ */
+
+static char Copyright[] = "Copyright Martin Ayotte, 1994";
+
+/*
+#define DEBUG_CDAUDIO
+*/
+
+#include "stdio.h"
+#include "win.h"
+#include "user.h"
+#include "driver.h"
+#include "mmsystem.h"
+
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <linux/soundcard.h>
+#include <linux/cdrom.h>
+
+#define SOUND_DEV "/dev/dsp"
+#define CDAUDIO_DEV "/dev/sbpcd"
+
+#ifdef SOUND_VERSION
+#define IOCTL(a,b,c) ioctl(a,b,&c)
+#else
+#define IOCTL(a,b,c) (c = ioctl(a,b,c) )
+#endif
+
+#define MAX_CDAUDIODRV 2
+#define MAX_CDAUDIO_TRACKS 256
+
+#define CDFRAMES_PERSEC 75
+#define CDFRAMES_PERMIN 4500
+#define SECONDS_PERMIN 60
+
+typedef struct {
+ int nUseCount; /* Incremented for each shared open */
+ BOOL fShareable; /* TRUE if first open was shareable */
+ WORD wNotifyDeviceID; /* MCI device ID with a pending notification */
+ HANDLE hCallback; /* Callback handle for pending notification */
+ MCI_OPEN_PARMS openParms;
+ DWORD dwTimeFormat;
+ int unixdev;
+ struct cdrom_subchnl sc;
+ int mode;
+ UINT nCurTrack;
+ DWORD dwCurFrame;
+ UINT nTracks;
+ DWORD dwTotalLen;
+ LPDWORD lpdwTrackLen;
+ LPDWORD lpdwTrackPos;
+ DWORD dwFirstOffset;
+ } LINUX_CDAUDIO;
+
+static LINUX_CDAUDIO CDADev[MAX_CDAUDIODRV];
+
+UINT CDAUDIO_GetNumberOfTracks(UINT wDevID);
+BOOL CDAUDIO_GetTracksInfo(UINT wDevID);
+BOOL CDAUDIO_GetCDStatus(UINT wDevID);
+DWORD CDAUDIO_CalcTime(UINT wDevID, DWORD dwFormatType, DWORD dwFrame);
+
+
+/*-----------------------------------------------------------------------*/
+
+
+/**************************************************************************
+* CDAUDIO_mciOpen [internal]
+*/
+DWORD CDAUDIO_mciOpen(DWORD dwFlags, LPMCI_OPEN_PARMS lpParms)
+{
+ UINT wDevID;
+ int cdrom;
+#ifdef DEBUG_CDAUDIO
+ printf("CDAUDIO_mciOpen(%08X, %08X);\n", dwFlags, lpParms);
+#endif
+ if (lpParms == NULL) return MCIERR_INTERNAL;
+ wDevID = lpParms->wDeviceID;
+ if (CDADev[wDevID].nUseCount > 0) {
+ /* The driver already open on this channel */
+ /* If the driver was% op, ened shareable before and this open specifies */
+ /* shareable then increment the use count */
+ if (CDADev[wDevID].fShareable && (dwFlags & MCI_OPEN_SHAREABLE))
+ ++CDADev[wDevID].nUseCount;
+ else
+ return MCIERR_MUST_USE_SHAREABLE;
+ }
+ else {
+ CDADev[wDevID].nUseCount = 1;
+ CDADev[wDevID].fShareable = dwFlags & MCI_OPEN_SHAREABLE;
+ }
+ if (dwFlags & MCI_OPEN_ELEMENT) {
+ printf("CDAUDIO_mciOpen // MCI_OPEN_ELEMENT !\n");
+/* return MCIERR_NO_ELEMENT_ALLOWED; */
+ }
+ memcpy(&CDADev[wDevID].openParms, lpParms, sizeof(MCI_OPEN_PARMS));
+ CDADev[wDevID].wNotifyDeviceID = lpParms->wDeviceID;
+ CDADev[wDevID].unixdev = open (CDAUDIO_DEV, O_RDONLY, 0);
+ if (CDADev[wDevID].unixdev == -1) {
+ printf("CDAUDIO_mciOpen // can't open '%s' !\n", CDAUDIO_DEV);
+ return MCIERR_HARDWARE;
+ }
+ CDADev[wDevID].mode = 0;
+ CDADev[wDevID].dwTimeFormat = MCI_FORMAT_TMSF;
+ CDADev[wDevID].nCurTrack = 0;
+ CDADev[wDevID].nTracks = 0;
+ CDADev[wDevID].dwTotalLen = 0;
+ CDADev[wDevID].dwFirstOffset = 0;
+ CDADev[wDevID].lpdwTrackLen = NULL;
+ CDADev[wDevID].lpdwTrackPos = NULL;
+ if (!CDAUDIO_GetTracksInfo(wDevID)) {
+ printf("CDAUDIO_mciOpen // error reading TracksInfo !\n");
+/* return MCIERR_INTERNAL; */
+ }
+ if (dwFlags & MCI_NOTIFY) {
+ printf("CDAUDIO_mciOpen // MCI_NOTIFY_SUCCESSFUL %08X !\n", lpParms->dwCallback);
+ mciDriverNotify((HWND)LOWORD(lpParms->dwCallback),
+ CDADev[wDevID].wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL);
+ }
+ return 0;
+}
+
+/**************************************************************************
+* CDAUDIO_mciClose [internal]
+*/
+DWORD CDAUDIO_mciClose(UINT wDevID, DWORD dwParam, LPMCI_GENERIC_PARMS lpParms)
+{
+#ifdef DEBUG_CDAUDIO
+ printf("CDAUDIO_mciClose(%u, %08X, %08X);\n", wDevID, dwParam, lpParms);
+#endif
+ if (CDADev[wDevID].lpdwTrackLen != NULL) free(CDADev[wDevID].lpdwTrackLen);
+ if (CDADev[wDevID].lpdwTrackPos != NULL) free(CDADev[wDevID].lpdwTrackPos);
+ close(CDADev[wDevID].unixdev);
+}
+
+/**************************************************************************
+* CDAUDIO_mciGetDevCaps [internal]
+*/
+DWORD CDAUDIO_mciGetDevCaps(UINT wDevID, DWORD dwFlags,
+ LPMCI_GETDEVCAPS_PARMS lpParms)
+{
+#ifdef DEBUG_CDAUDIO
+ printf("CDAUDIO_mciGetDevCaps(%u, %08X, %08X);\n", wDevID, dwFlags, lpParms);
+#endif
+ if (lpParms == NULL) return MCIERR_INTERNAL;
+ if (dwFlags & MCI_GETDEVCAPS_ITEM) {
+ printf("CDAUDIO_mciGetDevCaps // MCI_GETDEVCAPS_ITEM dwItem=%08X);\n",
+ lpParms->dwItem);
+ switch(lpParms->dwItem) {
+ case MCI_GETDEVCAPS_CAN_RECORD:
+ lpParms->dwReturn = FALSE;
+ break;
+ case MCI_GETDEVCAPS_HAS_AUDIO:
+ lpParms->dwReturn = TRUE;
+ break;
+ case MCI_GETDEVCAPS_HAS_VIDEO:
+ lpParms->dwReturn = FALSE;
+ break;
+ case MCI_GETDEVCAPS_DEVICE_TYPE:
+ lpParms->dwReturn = MCI_DEVTYPE_CD_AUDIO;
+ break;
+ case MCI_GETDEVCAPS_USES_FILES:
+ lpParms->dwReturn = FALSE;
+ break;
+ case MCI_GETDEVCAPS_COMPOUND_DEVICE:
+ lpParms->dwReturn = FALSE;
+ break;
+ case MCI_GETDEVCAPS_CAN_EJECT:
+ lpParms->dwReturn = TRUE;
+ break;
+ case MCI_GETDEVCAPS_CAN_PLAY:
+ lpParms->dwReturn = TRUE;
+ break;
+ case MCI_GETDEVCAPS_CAN_SAVE:
+ lpParms->dwReturn = FALSE;
+ break;
+ default:
+ return MCIERR_UNRECOGNIZED_COMMAND;
+ }
+ }
+ printf("CDAUDIO_mciGetDevCaps // lpParms->dwReturn=%08X);\n", lpParms->dwReturn);
+ return 0;
+}
+
+/**************************************************************************
+* CDAUDIO_mciInfo [internal]
+*/
+DWORD CDAUDIO_mciInfo(UINT wDevID, DWORD dwFlags, LPMCI_INFO_PARMS lpParms)
+{
+#ifdef DEBUG_CDAUDIO
+ printf("CDAUDIO_mciInfo(%u, %08X, %08X);\n", wDevID, dwFlags, lpParms);
+#endif
+ if (lpParms == NULL) return MCIERR_INTERNAL;
+ lpParms->lpstrReturn = NULL;
+ switch(dwFlags) {
+ case MCI_INFO_PRODUCT:
+ lpParms->lpstrReturn = "Linux CDROM 0.5";
+ break;
+ default:
+ return MCIERR_UNRECOGNIZED_COMMAND;
+ }
+ if (lpParms->lpstrReturn != NULL)
+ lpParms->dwRetSize = strlen(lpParms->lpstrReturn);
+ else
+ lpParms->dwRetSize = 0;
+ return 0;
+}
+
+/**************************************************************************
+* CDAUDIO_mciStatus [internal]
+*/
+DWORD CDAUDIO_mciStatus(UINT wDevID, DWORD dwFlags, LPMCI_STATUS_PARMS lpParms)
+{
+#ifdef DEBUG_CDAUDIO
+ printf("CDAUDIO_mciStatus(%u, %08X, %08X);\n", wDevID, dwFlags, lpParms);
+#endif
+ if (lpParms == NULL) return MCIERR_INTERNAL;
+ if (CDADev[wDevID].unixdev == 0) return MMSYSERR_NOTENABLED;
+ if (dwFlags & MCI_NOTIFY) {
+#ifdef DEBUG_CDAUDIO
+ printf("CDAUDIO_mciStatus // MCI_NOTIFY_SUCCESSFUL %08X !\n", lpParms->dwCallback);
+#endif
+ mciDriverNotify((HWND)LOWORD(lpParms->dwCallback),
+ CDADev[wDevID].wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL);
+ }
+ if (dwFlags & MCI_STATUS_ITEM) {
+ switch(lpParms->dwItem) {
+ case MCI_STATUS_CURRENT_TRACK:
+ if (!CDAUDIO_GetCDStatus(wDevID)) return MCIERR_INTERNAL;
+ lpParms->dwReturn = CDADev[wDevID].nCurTrack;
+#ifdef DEBUG_CDAUDIO
+ printf("CDAUDIO_mciStatus // CURRENT_TRACK=%u!\n", lpParms->dwReturn);
+#endif
+ return 0;
+ case MCI_STATUS_LENGTH:
+ if (CDADev[wDevID].nTracks == 0) {
+ if (!CDAUDIO_GetTracksInfo(wDevID)) {
+ printf("CDAUDIO_mciStatus // error reading TracksInfo !\n");
+ return MCIERR_INTERNAL;
+ }
+ }
+ if (dwFlags & MCI_TRACK) {
+ printf("CDAUDIO_mciStatus // MCI_TRACK #%u LENGTH=??? !\n",
+ lpParms->dwTrack);
+ if (lpParms->dwTrack > CDADev[wDevID].nTracks)
+ return MCIERR_OUTOFRANGE;
+ lpParms->dwReturn = CDADev[wDevID].lpdwTrackLen[lpParms->dwTrack];
+ }
+ else
+ lpParms->dwReturn = CDADev[wDevID].dwTotalLen;
+ lpParms->dwReturn = CDAUDIO_CalcTime(wDevID,
+ CDADev[wDevID].dwTimeFormat, lpParms->dwReturn);
+ printf("CDAUDIO_mciStatus // LENGTH=%u !\n", lpParms->dwReturn);
+ return 0;
+ case MCI_STATUS_MODE:
+ if (!CDAUDIO_GetCDStatus(wDevID)) return MCIERR_INTERNAL;
+ lpParms->dwReturn = CDADev[wDevID].mode;
+#ifdef DEBUG_CDAUDIO
+ printf("CDAUDIO_mciStatus // MCI_STATUS_MODE=%08X !\n",
+ lpParms->dwReturn);
+#endif
+ return 0;
+ case MCI_STATUS_MEDIA_PRESENT:
+ lpParms->dwReturn = (CDADev[wDevID].nTracks > 0) ? TRUE : FALSE;
+ if (lpParms->dwReturn == FALSE)
+ printf("CDAUDIO_mciStatus // MEDIA_NOT_PRESENT !\n");
+ else
+ printf("CDAUDIO_mciStatus // MCI_STATUS_MEDIA_PRESENT !\n");
+ return 0;
+ case MCI_STATUS_NUMBER_OF_TRACKS:
+ lpParms->dwReturn = CDAUDIO_GetNumberOfTracks(wDevID);
+ printf("CDAUDIO_mciStatus // MCI_STATUS_NUMBER_OF_TRACKS = %u !\n",
+ lpParms->dwReturn);
+ if (lpParms->dwReturn == (WORD)-1) return MCIERR_INTERNAL;
+ return 0;
+ case MCI_STATUS_POSITION:
+ if (!CDAUDIO_GetCDStatus(wDevID)) return MCIERR_INTERNAL;
+ lpParms->dwReturn = CDADev[wDevID].dwCurFrame;
+ if (dwFlags & MCI_STATUS_START) {
+ lpParms->dwReturn = CDADev[wDevID].dwFirstOffset;
+#ifdef DEBUG_CDAUDIO
+ printf("CDAUDIO_mciStatus // get MCI_STATUS_START !\n");
+#endif
+ }
+ if (dwFlags & MCI_TRACK) {
+ if (lpParms->dwTrack > CDADev[wDevID].nTracks)
+ return MCIERR_OUTOFRANGE;
+ lpParms->dwReturn = CDADev[wDevID].lpdwTrackPos[lpParms->dwTrack - 1];
+#ifdef DEBUG_CDAUDIO
+ printf("CDAUDIO_mciStatus // get MCI_TRACK #%u !\n", lpParms->dwTrack);
+#endif
+ }
+ lpParms->dwReturn = CDAUDIO_CalcTime(wDevID,
+ CDADev[wDevID].dwTimeFormat, lpParms->dwReturn);
+#ifdef DEBUG_CDAUDIO
+ printf("CDAUDIO_mciStatus // MCI_STATUS_POSITION=%08X !\n",
+ lpParms->dwReturn);
+#endif
+ return 0;
+ case MCI_STATUS_READY:
+ printf("CDAUDIO_mciStatus // MCI_STATUS_READY !\n");
+ lpParms->dwReturn = TRUE;
+ return 0;
+ case MCI_STATUS_TIME_FORMAT:
+ printf("CDAUDIO_mciStatus // MCI_STATUS_TIME_FORMAT !\n");
+ lpParms->dwReturn = MCI_FORMAT_MILLISECONDS;
+ return 0;
+ default:
+ printf("CDAUDIO_mciStatus // unknowm command %04X !\n", lpParms->dwItem);
+ return MCIERR_UNRECOGNIZED_COMMAND;
+ }
+ }
+ printf("CDAUDIO_mciStatus // not MCI_STATUS_ITEM !\n");
+ return 0;
+}
+
+
+/**************************************************************************
+* CDAUDIO_CalcTime [internal]
+*/
+DWORD CDAUDIO_CalcTime(UINT wDevID, DWORD dwFormatType, DWORD dwFrame)
+{
+ DWORD dwTime = 0;
+ UINT wTrack;
+ UINT wMinutes;
+ UINT wSeconds;
+ UINT wFrames;
+#ifdef DEBUG_CDAUDIO
+ printf("CDAUDIO_CalcTime(%u, %08X, %lu);\n", wDevID, dwFormatType, dwFrame);
+#endif
+TryAGAIN:
+ switch (dwFormatType) {
+ case MCI_FORMAT_MILLISECONDS:
+ dwTime = dwFrame / CDFRAMES_PERSEC * 1000;
+#ifdef DEBUG_CDAUDIO
+ printf("CDAUDIO_CalcTime // MILLISECONDS %u\n", dwTime);
+#endif
+ break;
+ case MCI_FORMAT_MSF:
+ wMinutes = dwFrame / CDFRAMES_PERMIN;
+ wSeconds = (dwFrame - CDFRAMES_PERMIN * wMinutes) / CDFRAMES_PERSEC;
+ wFrames = dwFrame - CDFRAMES_PERMIN * wMinutes -
+ CDFRAMES_PERSEC * wSeconds;
+ dwTime = MCI_MAKE_MSF(wMinutes, wSeconds, wFrames);
+#ifdef DEBUG_CDAUDIO
+ printf("CDAUDIO_CalcTime // MSF %02u:%02u:%02u -> dwTime=%u\n",
+ wMinutes, wSeconds, wFrames, dwTime);
+#endif
+ break;
+ case MCI_FORMAT_TMSF:
+ for (wTrack = 0; wTrack < CDADev[wDevID].nTracks; wTrack++) {
+/* dwTime += CDADev[wDevID].lpdwTrackLen[wTrack - 1];
+ printf("Adding trk#%u curpos=%u \n", dwTime);
+ if (dwTime >= dwFrame) break; */
+ if (CDADev[wDevID].lpdwTrackPos[wTrack - 1] >= dwFrame) break;
+ }
+ wMinutes = dwFrame / CDFRAMES_PERMIN;
+ wSeconds = (dwFrame - CDFRAMES_PERMIN * wMinutes) / CDFRAMES_PERSEC;
+ wFrames = dwFrame - CDFRAMES_PERMIN * wMinutes -
+ CDFRAMES_PERSEC * wSeconds;
+ dwTime = MCI_MAKE_TMSF(wTrack, wMinutes, wSeconds, wFrames);
+#ifdef DEBUG_CDAUDIO
+ printf("CDAUDIO_CalcTime // %02u-%02u:%02u:%02u\n",
+ wTrack, wMinutes, wSeconds, wFrames);
+#endif
+ break;
+ default:
+ /* unknown format ! force TMSF ! ... */
+ dwFormatType = MCI_FORMAT_TMSF;
+ goto TryAGAIN;
+ }
+ return dwTime;
+}
+
+
+/**************************************************************************
+* CDAUDIO_CalcFrame [internal]
+*/
+DWORD CDAUDIO_CalcFrame(UINT wDevID, DWORD dwFormatType, DWORD dwTime)
+{
+ DWORD dwFrame = 0;
+ UINT wTrack;
+#ifdef DEBUG_CDAUDIO
+ printf("CDAUDIO_CalcFrame(%u, %08X, %lu);\n", wDevID, dwFormatType, dwTime);
+#endif
+TryAGAIN:
+ switch (dwFormatType) {
+ case MCI_FORMAT_MILLISECONDS:
+ dwFrame = dwTime * CDFRAMES_PERSEC / 1000;
+#ifdef DEBUG_CDAUDIO
+ printf("CDAUDIO_CalcFrame // MILLISECONDS %u\n", dwFrame);
+#endif
+ break;
+ case MCI_FORMAT_MSF:
+#ifdef DEBUG_CDAUDIO
+ printf("CDAUDIO_CalcFrame // MSF %02u:%02u:%02u\n",
+ MCI_MSF_MINUTE(dwTime), MCI_MSF_SECOND(dwTime),
+ MCI_MSF_FRAME(dwTime));
+#endif
+ dwFrame += CDFRAMES_PERMIN * MCI_MSF_MINUTE(dwTime);
+ dwFrame += CDFRAMES_PERSEC * MCI_MSF_SECOND(dwTime);
+ dwFrame += MCI_MSF_FRAME(dwTime);
+ break;
+ case MCI_FORMAT_TMSF:
+ wTrack = MCI_TMSF_TRACK(dwTime);
+#ifdef DEBUG_CDAUDIO
+ printf("CDAUDIO_CalcFrame // TMSF %02u-%02u:%02u:%02u\n",
+ MCI_TMSF_TRACK(dwTime), MCI_TMSF_MINUTE(dwTime),
+ MCI_TMSF_SECOND(dwTime), MCI_TMSF_FRAME(dwTime));
+ printf("CDAUDIO_CalcFrame // TMSF trackpos[%u]=%u\n",
+ wTrack, CDADev[wDevID].lpdwTrackPos[wTrack - 1]);
+#endif
+ dwFrame = CDADev[wDevID].lpdwTrackPos[wTrack - 1];
+ dwFrame += CDFRAMES_PERMIN * MCI_TMSF_MINUTE(dwTime);
+ dwFrame += CDFRAMES_PERSEC * MCI_TMSF_SECOND(dwTime);
+ dwFrame += MCI_TMSF_FRAME(dwTime);
+ break;
+ default:
+ /* unknown format ! force TMSF ! ... */
+ dwFormatType = MCI_FORMAT_TMSF;
+ goto TryAGAIN;
+ }
+ return dwFrame;
+}
+
+
+/**************************************************************************
+* CDAUDIO_GetNumberOfTracks [internal]
+*/
+UINT CDAUDIO_GetNumberOfTracks(UINT wDevID)
+{
+ struct cdrom_tochdr hdr;
+ if (CDADev[wDevID].nTracks == 0) {
+ if (ioctl(CDADev[wDevID].unixdev, CDROMREADTOCHDR, &hdr)) {
+ printf("GetNumberOfTracks(%u) // Error occured !\n", wDevID);
+ return (WORD)-1;
+ }
+ CDADev[wDevID].nTracks = hdr.cdth_trk1;
+ }
+ return CDADev[wDevID].nTracks;
+}
+
+/**************************************************************************
+* CDAUDIO_GetNumberOfTracks [internal]
+*/
+BOOL CDAUDIO_GetTracksInfo(UINT wDevID)
+{
+ int i, length;
+ int start, last_start;
+ int total_length = 0;
+ struct cdrom_tocentry entry;
+ if (CDADev[wDevID].nTracks == 0) {
+ if (CDAUDIO_GetNumberOfTracks(wDevID) == (WORD)-1) return FALSE;
+ }
+ if (CDADev[wDevID].lpdwTrackLen != NULL)
+ free(CDADev[wDevID].lpdwTrackLen);
+ CDADev[wDevID].lpdwTrackLen = (LPDWORD)malloc(
+ (CDADev[wDevID].nTracks + 1) * sizeof(DWORD));
+ if (CDADev[wDevID].lpdwTrackPos != NULL)
+ free(CDADev[wDevID].lpdwTrackPos);
+ CDADev[wDevID].lpdwTrackPos = (LPDWORD)malloc(
+ (CDADev[wDevID].nTracks + 1) * sizeof(DWORD));
+ if (CDADev[wDevID].lpdwTrackLen == NULL ||
+ CDADev[wDevID].lpdwTrackPos == NULL) {
+ printf("CDAUDIO_GetTracksInfo // error allocating track table !\n");
+ return FALSE;
+ }
+ memset(CDADev[wDevID].lpdwTrackLen, 0,
+ (CDADev[wDevID].nTracks + 1) * sizeof(DWORD));
+ memset(CDADev[wDevID].lpdwTrackPos, 0,
+ (CDADev[wDevID].nTracks + 1) * sizeof(DWORD));
+ for (i = 0; i <= CDADev[wDevID].nTracks; i++) {
+ if (i == CDADev[wDevID].nTracks)
+ entry.cdte_track = CDROM_LEADOUT;
+ else
+ entry.cdte_track = i + 1;
+ entry.cdte_format = CDROM_MSF;
+ if (ioctl(CDADev[wDevID].unixdev, CDROMREADTOCENTRY, &entry)) {
+ printf("CDAUDIO_GetTracksInfo // error read entry\n");
+ return FALSE;
+ }
+ start = CDFRAMES_PERSEC * (SECONDS_PERMIN *
+ entry.cdte_addr.msf.minute + entry.cdte_addr.msf.second) +
+ entry.cdte_addr.msf.frame;
+ if (i == 0) {
+ CDADev[wDevID].dwFirstOffset = last_start = start;
+ printf("CDAUDIO_GetTracksInfo // dwFirstOffset=%u\n", start);
+ }
+ else {
+ length = start - last_start;
+ last_start = start;
+ start = last_start - length;
+ total_length += length;
+ CDADev[wDevID].lpdwTrackLen[i - 1] = length;
+ CDADev[wDevID].lpdwTrackPos[i - 1] = start;
+ printf("CDAUDIO_GetTracksInfo // track #%u start=%u len=%u\n",
+ i, start, length);
+ }
+ }
+ CDADev[wDevID].dwTotalLen = total_length;
+ printf("CDAUDIO_GetTracksInfo // total_len=%u\n", total_length);
+ return TRUE;
+}
+
+
+/**************************************************************************
+* CDAUDIO_GetNumberOfTracks [internal]
+*/
+BOOL CDAUDIO_GetCDStatus(UINT wDevID)
+{
+ int oldmode = CDADev[wDevID].mode;
+ CDADev[wDevID].sc.cdsc_format = CDROM_MSF;
+ if (ioctl(CDADev[wDevID].unixdev, CDROMSUBCHNL, &CDADev[wDevID].sc)) {
+#ifdef DEBUG_CDAUDIO
+ printf("CDAUDIO_GetCDStatus // opened or no_media !\n");
+#endif
+ CDADev[wDevID].mode = MCI_MODE_OPEN;
+ return TRUE;
+ }
+ switch (CDADev[wDevID].sc.cdsc_audiostatus) {
+ case CDROM_AUDIO_INVALID:
+ printf("CDAUDIO_GetCDStatus // device doesn't support status !\n");
+ return FALSE;
+ case CDROM_AUDIO_NO_STATUS:
+ CDADev[wDevID].mode = MCI_MODE_STOP;
+#ifdef DEBUG_CDAUDIO
+ printf("CDAUDIO_GetCDStatus // MCI_MODE_STOP !\n");
+#endif
+ break;
+ case CDROM_AUDIO_PLAY:
+ CDADev[wDevID].mode = MCI_MODE_PLAY;
+#ifdef DEBUG_CDAUDIO
+ printf("CDAUDIO_GetCDStatus // MCI_MODE_PLAY !\n");
+#endif
+ break;
+ case CDROM_AUDIO_PAUSED:
+ CDADev[wDevID].mode = MCI_MODE_PAUSE;
+#ifdef DEBUG_CDAUDIO
+ printf("CDAUDIO_GetCDStatus // MCI_MODE_PAUSE !\n");
+#endif
+ break;
+ default:
+ printf("CDAUDIO_GetCDStatus // status=%02X !\n",
+ CDADev[wDevID].sc.cdsc_audiostatus);
+ }
+ CDADev[wDevID].nCurTrack = CDADev[wDevID].sc.cdsc_trk;
+ CDADev[wDevID].dwCurFrame =
+ CDFRAMES_PERMIN * CDADev[wDevID].sc.cdsc_absaddr.msf.minute +
+ CDFRAMES_PERSEC * CDADev[wDevID].sc.cdsc_absaddr.msf.second +
+ CDADev[wDevID].sc.cdsc_absaddr.msf.frame;
+#ifdef DEBUG_CDAUDIO
+ printf("CDAUDIO_GetCDStatus // %02u-%02u:%02u:%02u \n",
+ CDADev[wDevID].sc.cdsc_trk,
+ CDADev[wDevID].sc.cdsc_absaddr.msf.minute,
+ CDADev[wDevID].sc.cdsc_absaddr.msf.second,
+ CDADev[wDevID].sc.cdsc_absaddr.msf.frame);
+#endif
+ if (oldmode != CDADev[wDevID].mode && oldmode == MCI_MODE_OPEN) {
+ if (!CDAUDIO_GetTracksInfo(wDevID)) {
+ printf("CDAUDIO_GetCDStatus // error updating TracksInfo !\n");
+ return MCIERR_INTERNAL;
+ }
+ }
+ return TRUE;
+}
+
+/**************************************************************************
+* CDAUDIO_mciPlay [internal]
+*/
+DWORD CDAUDIO_mciPlay(UINT wDevID, DWORD dwFlags, LPMCI_PLAY_PARMS lpParms)
+{
+ int start, end;
+ struct cdrom_msf msf;
+#ifdef DEBUG_CDAUDIO
+ printf("CDAUDIO_mciPlay(%u, %08X, %08X);\n", wDevID, dwFlags, lpParms);
+#endif
+ if (lpParms == NULL) return MCIERR_INTERNAL;
+ if (CDADev[wDevID].unixdev == 0) return MMSYSERR_NOTENABLED;
+ start = 0; end = CDADev[wDevID].dwTotalLen;
+ CDADev[wDevID].nCurTrack = 1;
+ if (dwFlags & MCI_FROM) {
+ start = CDAUDIO_CalcFrame(wDevID,
+ CDADev[wDevID].dwTimeFormat, lpParms->dwFrom);
+#ifdef DEBUG_CDAUDIO
+ printf("CDAUDIO_mciPlay // MCI_FROM=%08X -> %u \n",
+ lpParms->dwFrom, start);
+#endif
+ }
+ if (dwFlags & MCI_TO) {
+ end = CDAUDIO_CalcFrame(wDevID,
+ CDADev[wDevID].dwTimeFormat, lpParms->dwTo);
+#ifdef DEBUG_CDAUDIO
+ printf("CDAUDIO_mciPlay // MCI_TO=%08X -> %u \n",
+ lpParms->dwTo, end);
+#endif
+ }
+ start += CDADev[wDevID].dwFirstOffset;
+ end += CDADev[wDevID].dwFirstOffset;
+ msf.cdmsf_min0 = start / CDFRAMES_PERMIN;
+ msf.cdmsf_sec0 = (start % CDFRAMES_PERMIN) / CDFRAMES_PERSEC;
+ msf.cdmsf_frame0 = start % CDFRAMES_PERSEC;
+ msf.cdmsf_min1 = end / CDFRAMES_PERMIN;
+ msf.cdmsf_sec1 = (end % CDFRAMES_PERMIN) / CDFRAMES_PERSEC;
+ msf.cdmsf_frame1 = end % CDFRAMES_PERSEC;
+ if (ioctl(CDADev[wDevID].unixdev, CDROMSTART)) {
+ printf("CDAUDIO_mciPlay // motor doesn't start !\n");
+ return MCIERR_HARDWARE;
+ }
+ if (ioctl(CDADev[wDevID].unixdev, CDROMPLAYMSF, &msf)) {
+ printf("CDAUDIO_mciPlay // device doesn't play !\n");
+ return MCIERR_HARDWARE;
+ }
+#ifdef DEBUG_CDAUDIO
+ printf("CDAUDIO_mciPlay // msf = %d:%d:%d %d:%d:%d\n",
+ msf.cdmsf_min0, msf.cdmsf_sec0, msf.cdmsf_frame0,
+ msf.cdmsf_min1, msf.cdmsf_sec1, msf.cdmsf_frame1);
+#endif
+ CDADev[wDevID].mode = MCI_MODE_PLAY;
+ if (dwFlags & MCI_NOTIFY) {
+ printf("CDAUDIO_mciPlay // MCI_NOTIFY_SUCCESSFUL %08X !\n", lpParms->dwCallback);
+ mciDriverNotify((HWND)LOWORD(lpParms->dwCallback),
+ CDADev[wDevID].wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL);
+ }
+ return 0;
+}
+
+/**************************************************************************
+* CDAUDIO_mciStop [internal]
+*/
+DWORD CDAUDIO_mciStop(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
+{
+#ifdef DEBUG_CDAUDIO
+ printf("CDAUDIO_mciStop(%u, %08X, %08X);\n", wDevID, dwFlags, lpParms);
+#endif
+ if (lpParms == NULL) return MCIERR_INTERNAL;
+ if (ioctl(CDADev[wDevID].unixdev, CDROMSTOP)) return MCIERR_HARDWARE;
+ CDADev[wDevID].mode = MCI_MODE_STOP;
+ if (dwFlags & MCI_NOTIFY) {
+ printf("CDAUDIO_mciStop // MCI_NOTIFY_SUCCESSFUL %08X !\n", lpParms->dwCallback);
+ mciDriverNotify((HWND)LOWORD(lpParms->dwCallback),
+ CDADev[wDevID].wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL);
+ }
+ return 0;
+}
+
+/**************************************************************************
+* CDAUDIO_mciPause [internal]
+*/
+DWORD CDAUDIO_mciPause(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
+{
+#ifdef DEBUG_CDAUDIO
+ printf("CDAUDIO_mciPause(%u, %08X, %08X);\n", wDevID, dwFlags, lpParms);
+#endif
+ if (lpParms == NULL) return MCIERR_INTERNAL;
+ if (ioctl(CDADev[wDevID].unixdev, CDROMPAUSE)) return MCIERR_HARDWARE;
+ CDADev[wDevID].mode = MCI_MODE_PAUSE;
+ if (dwFlags & MCI_NOTIFY) {
+ printf("CDAUDIO_mciPause // MCI_NOTIFY_SUCCESSFUL %08X !\n", lpParms->dwCallback);
+ mciDriverNotify((HWND)LOWORD(lpParms->dwCallback),
+ CDADev[wDevID].wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL);
+ }
+ return 0;
+}
+
+/**************************************************************************
+* CDAUDIO_mciResume [internal]
+*/
+DWORD CDAUDIO_mciResume(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
+{
+#ifdef DEBUG_CDAUDIO
+ printf("CDAUDIO_mciResume(%u, %08X, %08X);\n", wDevID, dwFlags, lpParms);
+#endif
+ if (lpParms == NULL) return MCIERR_INTERNAL;
+ if (ioctl(CDADev[wDevID].unixdev, CDROMRESUME)) return MCIERR_HARDWARE;
+ CDADev[wDevID].mode = MCI_MODE_STOP;
+ if (dwFlags & MCI_NOTIFY) {
+ printf("CDAUDIO_mciResume // MCI_NOTIFY_SUCCESSFUL %08X !\n", lpParms->dwCallback);
+ mciDriverNotify((HWND)LOWORD(lpParms->dwCallback),
+ CDADev[wDevID].wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL);
+ }
+ return 0;
+}
+
+/**************************************************************************
+* CDAUDIO_mciSeek [internal]
+*/
+DWORD CDAUDIO_mciSeek(UINT wDevID, DWORD dwFlags, LPMCI_SEEK_PARMS lpParms)
+{
+ DWORD dwRet;
+ MCI_PLAY_PARMS PlayParms;
+#ifdef DEBUG_CDAUDIO
+ printf("CDAUDIO_mciSeek(%u, %08X, %08X);\n", wDevID, dwFlags, lpParms);
+#endif
+ if (lpParms == NULL) return MCIERR_INTERNAL;
+ if (ioctl(CDADev[wDevID].unixdev, CDROMRESUME)) return MCIERR_HARDWARE;
+ CDADev[wDevID].mode = MCI_MODE_SEEK;
+ switch(dwFlags) {
+ case MCI_SEEK_TO_START:
+ PlayParms.dwFrom = 0;
+ break;
+ case MCI_SEEK_TO_END:
+ PlayParms.dwFrom = CDADev[wDevID].dwTotalLen;
+ break;
+ case MCI_TO:
+ PlayParms.dwFrom = lpParms->dwTo;
+ break;
+ }
+ dwRet = CDAUDIO_mciPlay(wDevID, MCI_WAIT | MCI_FROM, &PlayParms);
+ if (dwRet != 0) return dwRet;
+ dwRet = CDAUDIO_mciStop(wDevID, MCI_WAIT, (LPMCI_GENERIC_PARMS)&PlayParms);
+ if (dwFlags & MCI_NOTIFY) {
+ printf("CDAUDIO_mciSeek // MCI_NOTIFY_SUCCESSFUL %08X !\n", lpParms->dwCallback);
+ mciDriverNotify((HWND)LOWORD(lpParms->dwCallback),
+ CDADev[wDevID].wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL);
+ }
+ return dwRet;
+}
+
+
+/**************************************************************************
+* CDAUDIO_mciSet [internal]
+*/
+DWORD CDAUDIO_mciSet(UINT wDevID, DWORD dwFlags, LPMCI_SET_PARMS lpParms)
+{
+#ifdef DEBUG_CDAUDIO
+ printf("CDAUDIO_mciSet(%u, %08X, %08X);\n", wDevID, dwFlags, lpParms);
+#endif
+ if (lpParms == NULL) return MCIERR_INTERNAL;
+/*
+ printf("CDAUDIO_mciSet // dwTimeFormat=%08X\n", lpParms->dwTimeFormat);
+ printf("CDAUDIO_mciSet // dwAudio=%08X\n", lpParms->dwAudio);
+*/
+ if (dwFlags & MCI_SET_TIME_FORMAT) {
+ switch (lpParms->dwTimeFormat) {
+ case MCI_FORMAT_MILLISECONDS:
+#ifdef DEBUG_CDAUDIO
+ printf("CDAUDIO_mciSet // MCI_FORMAT_MILLISECONDS !\n");
+#endif
+ break;
+ case MCI_FORMAT_MSF:
+#ifdef DEBUG_CDAUDIO
+ printf("CDAUDIO_mciSet // MCI_FORMAT_MSF !\n");
+#endif
+ break;
+ case MCI_FORMAT_TMSF:
+#ifdef DEBUG_CDAUDIO
+ printf("CDAUDIO_mciSet // MCI_FORMAT_TMSF !\n");
+#endif
+ break;
+ default:
+ printf("CDAUDIO_mciSet // bad time format !\n");
+ return MCIERR_BAD_TIME_FORMAT;
+ }
+ CDADev[wDevID].dwTimeFormat = lpParms->dwTimeFormat;
+ }
+ if (dwFlags & MCI_SET_DOOR_OPEN) {
+ printf("CDAUDIO_mciSet // MCI_SET_DOOR_OPEN !\n");
+ if (ioctl(CDADev[wDevID].unixdev, CDROMEJECT)) return MCIERR_HARDWARE;
+ CDADev[wDevID].nTracks = 0;
+ }
+ if (dwFlags & MCI_SET_DOOR_CLOSED) {
+ printf("CDAUDIO_mciSet // MCI_SET_DOOR_CLOSED !\n");
+ if (ioctl(CDADev[wDevID].unixdev, CDROMEJECT)) return MCIERR_HARDWARE;
+ CDADev[wDevID].nTracks = 0;
+ }
+ if (dwFlags & MCI_SET_VIDEO) return MCIERR_UNSUPPORTED_FUNCTION;
+ if (dwFlags & MCI_SET_ON) return MCIERR_UNSUPPORTED_FUNCTION;
+ if (dwFlags & MCI_SET_OFF) return MCIERR_UNSUPPORTED_FUNCTION;
+ if (dwFlags & MCI_NOTIFY) {
+ printf("CDAUDIO_mciSet // MCI_NOTIFY_SUCCESSFUL %08X !\n", lpParms->dwCallback);
+ mciDriverNotify((HWND)LOWORD(lpParms->dwCallback),
+ CDADev[wDevID].wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL);
+ }
+ return 0;
+}
+
+
+/**************************************************************************
+* CDAUDIO_DriverProc [sample driver]
+*/
+LRESULT CDAUDIO_DriverProc(DWORD dwDevID, HDRVR hDriv, WORD wMsg,
+ DWORD dwParam1, DWORD dwParam2)
+{
+ switch(wMsg) {
+ case DRV_LOAD:
+ return (LRESULT)1L;
+ case DRV_FREE:
+ return (LRESULT)1L;
+ case DRV_OPEN:
+ case MCI_OPEN_DRIVER:
+ case MCI_OPEN:
+ return CDAUDIO_mciOpen(dwParam1, (LPMCI_OPEN_PARMS)dwParam2);
+ case DRV_CLOSE:
+ case MCI_CLOSE_DRIVER:
+ case MCI_CLOSE:
+ return CDAUDIO_mciClose(dwDevID, dwParam1,
+ (LPMCI_GENERIC_PARMS)dwParam2);
+ case DRV_ENABLE:
+ return (LRESULT)1L;
+ case DRV_DISABLE:
+ return (LRESULT)1L;
+ case DRV_QUERYCONFIGURE:
+ return (LRESULT)1L;
+ case DRV_CONFIGURE:
+ MessageBox((HWND)NULL, "Sample MultiMedia Linux Driver !",
+ "MMLinux Driver", MB_OK);
+ return (LRESULT)1L;
+ case DRV_INSTALL:
+ return (LRESULT)DRVCNF_RESTART;
+ case DRV_REMOVE:
+ return (LRESULT)DRVCNF_RESTART;
+ case MCI_GETDEVCAPS:
+ return CDAUDIO_mciGetDevCaps(dwDevID, dwParam1,
+ (LPMCI_GETDEVCAPS_PARMS)dwParam2);
+ case MCI_INFO:
+ return CDAUDIO_mciInfo(dwDevID, dwParam1,
+ (LPMCI_INFO_PARMS)dwParam2);
+ case MCI_STATUS:
+ return CDAUDIO_mciStatus(dwDevID, dwParam1,
+ (LPMCI_STATUS_PARMS)dwParam2);
+ case MCI_SET:
+ return CDAUDIO_mciSet(dwDevID, dwParam1,
+ (LPMCI_SET_PARMS)dwParam2);
+ case MCI_PLAY:
+ return CDAUDIO_mciPlay(dwDevID, dwParam1,
+ (LPMCI_PLAY_PARMS)dwParam2);
+ case MCI_STOP:
+ return CDAUDIO_mciStop(dwDevID, dwParam1,
+ (LPMCI_GENERIC_PARMS)dwParam2);
+ case MCI_PAUSE:
+ return CDAUDIO_mciPause(dwDevID, dwParam1,
+ (LPMCI_GENERIC_PARMS)dwParam2);
+ case MCI_RESUME:
+ return CDAUDIO_mciResume(dwDevID, dwParam1,
+ (LPMCI_GENERIC_PARMS)dwParam2);
+ case MCI_SEEK:
+ return CDAUDIO_mciSeek(dwDevID, dwParam1,
+ (LPMCI_SEEK_PARMS)dwParam2);
+ case MCI_SET_DOOR_OPEN:
+ printf("CDAUDIO_DriverProc // MCI_SET_DOOR_OPEN !\n");
+ if (ioctl(CDADev[dwDevID].unixdev, CDROMEJECT)) return MCIERR_HARDWARE;
+ CDADev[dwDevID].nTracks = 0;
+ return 0;
+ case MCI_SET_DOOR_CLOSED:
+ printf("CDAUDIO_DriverProc // MCI_SET_DOOR_CLOSED !\n");
+ if (ioctl(CDADev[dwDevID].unixdev, CDROMEJECT, 1)) return MCIERR_HARDWARE;
+ CDADev[dwDevID].nTracks = 0;
+ return 0;
+ default:
+ return DefDriverProc(dwDevID, hDriv, wMsg, dwParam1, dwParam2);
+ }
+}
+
+
+/*-----------------------------------------------------------------------*/
+
diff --git a/misc/mmaux.c b/misc/mmaux.c
new file mode 100644
index 0000000..64627d8
--- /dev/null
+++ b/misc/mmaux.c
@@ -0,0 +1,116 @@
+/*
+ * Sample AUXILARY Wine Driver for Linux
+ *
+ * Copyright 1994 Martin Ayotte
+ */
+
+static char Copyright[] = "Copyright Martin Ayotte, 1994";
+
+#include "stdio.h"
+#include "win.h"
+#include "user.h"
+#include "driver.h"
+#include "mmsystem.h"
+
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <linux/soundcard.h>
+
+#define SOUND_DEV "/dev/dsp"
+#define MIXER_DEV "/dev/mixer"
+
+#ifdef SOUND_VERSION
+#define IOCTL(a,b,c) ioctl(a,b,&c)
+#else
+#define IOCTL(a,b,c) (c = ioctl(a,b,c) )
+#endif
+
+
+/*-----------------------------------------------------------------------*/
+
+
+/**************************************************************************
+* AUX_GetDevCaps [internal]
+*/
+DWORD AUX_GetDevCaps(WORD wDevID, LPAUXCAPS lpCaps, DWORD dwSize)
+{
+ int mixer;
+ int volume;
+ printf("AUX_GetDevCaps(%u, %08X, %u);\n", wDevID, lpCaps, dwSize);
+ if (lpCaps == NULL) return MMSYSERR_NOTENABLED;
+ if ((mixer = open(MIXER_DEV, O_RDWR)) < 0) {
+ printf("AUX_GetDevCaps // mixer device not available !\n");
+ return MMSYSERR_NOTENABLED;
+ }
+ if (ioctl(mixer, SOUND_MIXER_READ_LINE, &volume) == -1) {
+ printf("AUX_GetDevCaps // unable read mixer !\n");
+ return MMSYSERR_NOTENABLED;
+ }
+ close(mixer);
+ return MMSYSERR_NOERROR;
+}
+
+
+/**************************************************************************
+* AUX_GetVolume [internal]
+*/
+DWORD AUX_GetVolume(WORD wDevID, DWORD dwParam)
+{
+ int mixer;
+ int volume;
+ printf("AUX_GetVolume(%u, %08X);\n", wDevID, dwParam);
+ if ((mixer = open(MIXER_DEV, O_RDWR)) < 0) {
+ printf("Linux 'AUX_GetVolume' // mixer device not available !\n");
+ return MMSYSERR_NOTENABLED;
+ }
+ if (ioctl(mixer, SOUND_MIXER_READ_LINE, &volume) == -1) {
+ printf("Linux 'AUX_GetVolume' // unable read mixer !\n");
+ return MMSYSERR_NOTENABLED;
+ }
+ close(mixer);
+ return MMSYSERR_NOERROR;
+}
+
+/**************************************************************************
+* AUX_SetVolume [internal]
+*/
+DWORD AUX_SetVolume(WORD wDevID, DWORD dwParam)
+{
+ int mixer;
+ int volume = 50;
+ printf("AUX_SetVolume(%u, %08X);\n", wDevID, dwParam);
+ if ((mixer = open(MIXER_DEV, O_RDWR)) < 0) {
+ printf("Linux 'AUX_SetVolume' // mixer device not available !\n");
+ return MMSYSERR_NOTENABLED;
+ }
+ if (ioctl(mixer, SOUND_MIXER_WRITE_LINE, &volume) == -1) {
+ printf("Linux 'AUX_SetVolume' // unable set mixer !\n");
+ return MMSYSERR_NOTENABLED;
+ }
+ close(mixer);
+ return MMSYSERR_NOERROR;
+}
+
+
+/**************************************************************************
+* auxMessage [sample driver]
+*/
+DWORD auxMessage(WORD wDevID, WORD wMsg, DWORD dwUser,
+ DWORD dwParam1, DWORD dwParam2)
+{
+ printf("auxMessage(%u, %04X, %08X, %08X, %08X);\n",
+ wDevID, wMsg, dwUser, dwParam1, dwParam2);
+ switch(wMsg) {
+ case AUXDM_GETDEVCAPS:
+ return AUX_GetDevCaps(wDevID, (LPAUXCAPS)dwParam1, dwParam2);
+ case AUXDM_GETNUMDEVS:
+ return 0L;
+ case AUXDM_GETVOLUME:
+ return AUX_GetVolume(wDevID, dwParam1);
+ case AUXDM_SETVOLUME:
+ return AUX_SetVolume(wDevID, dwParam1);
+ }
+ return MMSYSERR_NOTSUPPORTED;
+}
+
+
diff --git a/misc/mmsystem.c b/misc/mmsystem.c
index 90fc2de..da5ad6f 100644
--- a/misc/mmsystem.c
+++ b/misc/mmsystem.c
@@ -7,7 +7,10 @@
static char Copyright[] = "Copyright Martin Ayotte, 1993";
#include "stdio.h"
+#include <fcntl.h>
+#include <sys/ioctl.h>
#include "win.h"
+#include "user.h"
#include "driver.h"
#include "mmsystem.h"
@@ -31,6 +34,8 @@
static LPTIMERENTRY lpTimerList = NULL;
+static MCI_OPEN_DRIVER_PARMS mciDrv[MAXMCIDRIVERS];
+
UINT WINAPI midiGetErrorText(UINT uError, LPSTR lpText, UINT uSize);
UINT WINAPI waveGetErrorText(UINT uError, LPSTR lpText, UINT uSize);
@@ -50,9 +55,67 @@
*/
BOOL WINAPI sndPlaySound(LPCSTR lpszSoundName, UINT uFlags)
{
- printf("EMPTY STUB !!! sndPlaySound // SoundName='%s' uFlags=%04X !\n",
- lpszSoundName, uFlags);
- return 0;
+ int hFile;
+ int count;
+ WAVEHDR WaveHdr;
+ PCMWAVEFORMAT WaveFormat;
+ WAVEOPENDESC WaveDesc;
+ DWORD dwRet;
+ char str[128];
+ LPSTR ptr;
+ printf("sndPlaySound // SoundName='%s' uFlags=%04X !\n",
+ lpszSoundName, uFlags);
+ if (lpszSoundName == NULL) {
+ printf("sndPlaySound // Stop !\n");
+ return FALSE;
+ }
+ hFile = open(lpszSoundName, O_RDONLY);
+ if (hFile == 0) {
+ printf("sndPlaySound // searching in SystemSound List !\n");
+ GetProfileString("Sounds", (LPSTR)lpszSoundName, "", str, sizeof(str));
+ if (strlen(str) == 0) return FALSE;
+ if ((ptr = strchr(str, ',')) != NULL) *ptr = '\0';
+ hFile = open(str, O_RDONLY);
+ if (hFile == 0) {
+ printf("sndPlaySound // can't find SystemSound='%s' !\n", str);
+ return FALSE;
+ }
+ }
+ WaveDesc.hWave = 0;
+ WaveDesc.lpFormat = (LPWAVEFORMAT)&WaveFormat;
+ WaveFormat.wf.wFormatTag = WAVE_FORMAT_PCM;
+ WaveFormat.wBitsPerSample = 8;
+ WaveFormat.wf.nChannels = 1;
+ WaveFormat.wf.nSamplesPerSec = 11025;
+ WaveFormat.wf.nAvgBytesPerSec = 11025;
+ WaveFormat.wf.nBlockAlign = 1;
+ dwRet = wodMessage(0, WODM_OPEN, 0, (DWORD)&WaveDesc, CALLBACK_NULL);
+ if (dwRet != MMSYSERR_NOERROR) {
+ printf("sndPlaySound // can't open WaveOut device !\n");
+ return FALSE;
+ }
+ WaveHdr.lpData = (LPSTR) malloc(64000);
+ WaveHdr.dwBufferLength = 64000;
+ WaveHdr.dwUser = 0L;
+ WaveHdr.dwFlags = 0L;
+ WaveHdr.dwLoops = 0L;
+ dwRet = wodMessage(0, WODM_PREPARE, 0, (DWORD)&WaveHdr, sizeof(WAVEHDR));
+ if (dwRet != MMSYSERR_NOERROR) {
+ printf("sndPlaySound // can't prepare WaveOut device !\n");
+ return FALSE;
+ }
+ while(TRUE) {
+ count = read(hFile, WaveHdr.lpData, WaveHdr.dwBufferLength);
+ if (count == 0) break;
+ WaveHdr.dwBytesRecorded = count;
+ wodMessage(0, WODM_WRITE, 0, (DWORD)&WaveHdr, sizeof(WAVEHDR));
+ }
+ wodMessage(0, WODM_UNPREPARE, 0, (DWORD)&WaveHdr, sizeof(WAVEHDR));
+ wodMessage(0, WODM_CLOSE, 0, 0L, 0L);
+ free(WaveHdr.lpData);
+ close(hFile);
+
+ return TRUE;
}
/**************************************************************************
@@ -87,7 +150,23 @@
BOOL DriverCallback(DWORD dwCallBack, UINT uFlags, HANDLE hDev,
WORD wMsg, DWORD dwUser, DWORD dwParam1, DWORD dwParam2)
{
- printf("EMPTY STUB !!! DriverCallback() !\n");
+ printf("DriverCallback(%08X, %04X, %04X, %04X, %08X, %08X, %08X); !\n",
+ dwCallBack, uFlags, hDev, wMsg, dwUser, dwParam1, dwParam2);
+ switch(uFlags & DCB_TYPEMASK) {
+ case DCB_NULL:
+ printf("DriverCallback() // CALLBACK_NULL !\n");
+ break;
+ case DCB_WINDOW:
+ printf("DriverCallback() // CALLBACK_WINDOW !\n");
+ break;
+ case DCB_TASK:
+ printf("DriverCallback() // CALLBACK_TASK !\n");
+ break;
+ case DCB_FUNCTION:
+ printf("DriverCallback() // CALLBACK_FUNCTION !\n");
+ break;
+ }
+ return TRUE;
}
/**************************************************************************
@@ -170,8 +249,11 @@
*/
UINT WINAPI auxGetNumDevs()
{
+ UINT count = 0;
printf("auxGetNumDevs !\n");
- return 0;
+ count += auxMessage(0, AUXDM_GETNUMDEVS, 0L, 0L, 0L);
+ printf("auxGetNumDevs return %u \n", count);
+ return count;
}
/**************************************************************************
@@ -474,25 +556,32 @@
/**************************************************************************
-* mciWaveOpen [internal]
+* mciDriverNotify [MMSYSTEM.711]
*/
-DWORD mciWaveOpen(UINT wDevID, DWORD dwParam, LPMCI_WAVE_OPEN_PARMS lpParms)
+BOOL WINAPI mciDriverNotify(HWND hWndCallBack, UINT wDevID, UINT wStatus)
{
- if (lpParms == NULL) return MCIERR_INTERNAL;
- printf("mciWaveOpen(%04X, %08X, %08X)\n", wDevID, dwParam, lpParms);
- return MCIERR_INTERNAL;
+ printf("mciDriverNotify(%04X, %u, %04X)\n", hWndCallBack, wDevID, wStatus);
+ PostMessage(hWndCallBack, MM_MCINOTIFY, wStatus,
+ MAKELONG(mciDrv[wDevID].wDeviceID, 0));
+ return TRUE;
}
-
/**************************************************************************
* mciOpen [internal]
*/
-DWORD mciOpen(UINT wDevID, DWORD dwParam, LPMCI_OPEN_PARMS lpParms)
+DWORD mciOpen(DWORD dwParam, LPMCI_OPEN_PARMS lpParms)
{
char str[128];
DWORD dwDevTyp = 0;
+ UINT wDevID = 1;
+ printf("mciOpen(%08X, %08X)\n", dwParam, lpParms);
if (lpParms == NULL) return MCIERR_INTERNAL;
- printf("mciOpen(%04X, %08X, %08X)\n", wDevID, dwParam, lpParms);
+ while(mciDrv[wDevID].wType != 0) {
+ if (++wDevID >= MAXMCIDRIVERS) {
+ printf("MCI_OPEN // MAXMCIDRIVERS reached !\n");
+ return MCIERR_INTERNAL;
+ }
+ }
if (dwParam & MCI_OPEN_TYPE) {
if (lpParms->lpstrDeviceType == NULL) return MCIERR_INTERNAL;
if (dwParam & MCI_OPEN_TYPE_ID) {
@@ -519,13 +608,17 @@
dwDevTyp = MCI_DEVTYPE_ANIMATION;
}
}
+ mciDrv[wDevID].wType = dwDevTyp;
+ mciDrv[wDevID].wDeviceID = 1;
+ lpParms->wDeviceID = wDevID;
+ printf("MCI_OPEN // wDeviceID=%04X !\n", lpParms->wDeviceID);
switch(dwDevTyp) {
case MCI_DEVTYPE_CD_AUDIO:
- printf("MCI_OPEN // No SEQUENCER yet !\n");
- return MCIERR_DEVICE_NOT_INSTALLED;
+ return CDAUDIO_DriverProc(0, 0, MCI_OPEN_DRIVER,
+ dwParam, (DWORD)lpParms);
case MCI_DEVTYPE_WAVEFORM_AUDIO:
- printf("MCI_OPEN // No WAVEAUDIO yet !\n");
- return MCIERR_DEVICE_NOT_INSTALLED;
+ return WAVE_DriverProc(0, 0, MCI_OPEN_DRIVER,
+ dwParam, (DWORD)lpParms);
case MCI_DEVTYPE_SEQUENCER:
printf("MCI_OPEN // No SEQUENCER yet !\n");
return MCIERR_DEVICE_NOT_INSTALLED;
@@ -539,19 +632,36 @@
printf("MCI_OPEN // Invalid Device Name '%08X' !\n", lpParms->lpstrDeviceType);
return MCIERR_INVALID_DEVICE_NAME;
}
- lpParms->wDeviceID = ++mciActiveDev;
- printf("MCI_OPEN // wDeviceID=%04X !\n", lpParms->wDeviceID);
- return 0;
- }
- if (dwParam & MCI_OPEN_ELEMENT) {
- printf("MCI_OPEN // Element !\n");
- printf("MCI_OPEN // Elem=%s' !\n", lpParms->lpstrElementName);
}
return MCIERR_INTERNAL;
}
/**************************************************************************
+* mciClose [internal]
+*/
+DWORD mciClose(UINT wDevID, DWORD dwParam, LPMCI_GENERIC_PARMS lpParms)
+{
+ DWORD dwRet = MCIERR_INTERNAL;
+ printf("mciClose(%u, %08X, %08X)\n", wDevID, dwParam, lpParms);
+ switch(mciDrv[wDevID].wType) {
+ case MCI_DEVTYPE_CD_AUDIO:
+ dwRet = CDAUDIO_DriverProc(mciDrv[wDevID].wDeviceID, 0,
+ MCI_CLOSE, dwParam, (DWORD)lpParms);
+ break;
+ case MCI_DEVTYPE_WAVEFORM_AUDIO:
+ dwRet = WAVE_DriverProc(mciDrv[wDevID].wDeviceID, 0,
+ MCI_CLOSE, dwParam, (DWORD)lpParms);
+ break;
+ default:
+ printf("mciClose() // unknown type=%04X !\n", mciDrv[wDevID].wType);
+ }
+ mciDrv[wDevID].wType = 0;
+ return dwRet;
+}
+
+
+/**************************************************************************
* mciSound [internal]
*/
DWORD mciSound(UINT wDevID, DWORD dwParam, LPMCI_SOUND_PARMS lpParms)
@@ -563,106 +673,36 @@
}
-/**************************************************************************
-* mciGetDevCaps [internal]
-*/
-DWORD mciGetDevCaps(UINT wDevID, DWORD dwParam, LPMCI_GETDEVCAPS_PARMS lpParms)
-{
- if (lpParms == NULL) return MCIERR_INTERNAL;
- lpParms->dwReturn = 0;
- return 0;
-}
-
-
-/**************************************************************************
-* mciInfo [internal]
-*/
-DWORD mciInfo(UINT wDevID, DWORD dwParam, LPMCI_INFO_PARMS lpParms)
-{
- if (lpParms == NULL) return MCIERR_INTERNAL;
- lpParms->lpstrReturn = NULL;
- lpParms->dwRetSize = 0;
- return 0;
-}
-
-
-/**************************************************************************
-* mciStatus [internal]
-*/
-DWORD mciStatus(UINT wDevID, DWORD dwParam, LPMCI_STATUS_PARMS lpParms)
-{
- if (lpParms == NULL) return MCIERR_INTERNAL;
- return 0;
-}
-
-
-/**************************************************************************
-* mciPlay [internal]
-*/
-DWORD mciPlay(UINT wDevID, DWORD dwParam, LPMCI_PLAY_PARMS lpParms)
-{
- if (lpParms == NULL) return MCIERR_INTERNAL;
- return 0;
-}
-
-
-/**************************************************************************
-* mciRecord [internal]
-*/
-DWORD mciRecord(UINT wDevID, DWORD dwParam, LPMCI_RECORD_PARMS lpParms)
-{
- if (lpParms == NULL) return MCIERR_INTERNAL;
- return 0;
-}
-
-
-/**************************************************************************
-* mciClose [internal]
-*/
-DWORD mciClose(UINT wDevID)
-{
- return 0;
-}
-
/**************************************************************************
* mciSendCommand [MMSYSTEM.701]
*/
DWORD mciSendCommand(UINT wDevID, UINT wMsg, DWORD dwParam1, DWORD dwParam2)
{
+ HDRVR hDrv = 0;
+#ifdef DEBUG_MCI
printf("mciSendCommand(%04X, %04X, %08X, %08X)\n",
wDevID, wMsg, dwParam1, dwParam2);
+#endif
switch(wMsg) {
case MCI_OPEN:
- printf("mciSendCommand // MCI_OPEN !\n");
- if (dwParam1 & MCI_WAVE_OPEN_BUFFER)
- return mciWaveOpen(wDevID, dwParam1,
- (LPMCI_WAVE_OPEN_PARMS)dwParam2);
- else
- return mciOpen(wDevID, dwParam1, (LPMCI_OPEN_PARMS)dwParam2);
- case MCI_PLAY:
- printf("mciSendCommand // MCI_PLAY !\n");
- return mciPlay(wDevID, dwParam1, (LPMCI_PLAY_PARMS)dwParam2);
- case MCI_RECORD:
- printf("mciSendCommand // MCI_RECORD !\n");
- return mciRecord(wDevID, dwParam1, (LPMCI_RECORD_PARMS)dwParam2);
+ return mciOpen(dwParam1, (LPMCI_OPEN_PARMS)dwParam2);
case MCI_CLOSE:
- printf("mciSendCommand // MCI_CLOSE !\n");
- return mciClose(wDevID);
- case MCI_SOUND:
- printf("mciSendCommand // MCI_SOUND !\n");
- return mciSound(wDevID, dwParam1, (LPMCI_SOUND_PARMS)dwParam2);
- case MCI_STATUS:
- printf("mciSendCommand // MCI_STATUS !\n");
- return mciStatus(wDevID, dwParam1, (LPMCI_STATUS_PARMS)dwParam2);
- case MCI_INFO:
- printf("mciSendCommand // MCI_INFO !\n");
- return mciInfo(wDevID, dwParam1, (LPMCI_INFO_PARMS)dwParam2);
- case MCI_GETDEVCAPS:
- printf("mciSendCommand // MCI_GETDEVCAPS !\n");
- return mciGetDevCaps(wDevID, dwParam1, (LPMCI_GETDEVCAPS_PARMS)dwParam2);
+ return mciClose(wDevID, dwParam1, (LPMCI_GENERIC_PARMS)dwParam2);
+ default:
+ switch(mciDrv[wDevID].wType) {
+ case MCI_DEVTYPE_CD_AUDIO:
+ return CDAUDIO_DriverProc(mciDrv[wDevID].wDeviceID, hDrv,
+ wMsg, dwParam1, dwParam2);
+ case MCI_DEVTYPE_WAVEFORM_AUDIO:
+ return WAVE_DriverProc(mciDrv[wDevID].wDeviceID, hDrv,
+ wMsg, dwParam1, dwParam2);
+ default:
+ printf("mciSendCommand() // unknown type=%04X !\n",
+ mciDrv[wDevID].wType);
+ }
}
- return MCIERR_DEVICE_NOT_INSTALLED;
+ return MMSYSERR_INVALPARAM;
}
/**************************************************************************
@@ -670,7 +710,13 @@
*/
UINT mciGetDeviceID (LPCSTR lpstrName)
{
+ char str[128];
printf("mciGetDeviceID(%s)\n", lpstrName);
+ if (lpstrName != NULL) {
+ strcpy(str, lpstrName);
+ AnsiUpper(str);
+ if (strcmp(str, "ALL") == 0) return MCI_ALL_DEVICE_ID;
+ }
return 0;
}
@@ -1046,8 +1092,11 @@
*/
UINT WINAPI waveOutGetNumDevs()
{
+ UINT count = 0;
printf("waveOutGetNumDevs\n");
- return 1;
+ count += wodMessage(0, WODM_GETNUMDEVS, 0L, 0L, 0L);
+ printf("waveOutGetNumDevs return %u \n", count);
+ return count;
}
/**************************************************************************
@@ -1056,7 +1105,7 @@
UINT WINAPI waveOutGetDevCaps(UINT uDeviceID, WAVEOUTCAPS FAR* lpCaps, UINT uSize)
{
printf("waveOutGetDevCaps\n");
- return MMSYSERR_INVALHANDLE;
+ return wodMessage(uDeviceID, WODM_GETDEVCAPS, 0L, (DWORD)lpCaps, uSize);
}
/**************************************************************************
@@ -1144,20 +1193,42 @@
UINT WINAPI waveOutOpen(HWAVEOUT FAR* lphWaveOut, UINT uDeviceID,
const LPWAVEFORMAT lpFormat, DWORD dwCallback, DWORD dwInstance, DWORD dwFlags)
{
+ HWAVE hWaveOut;
+ LPWAVEOPENDESC lpDesc;
+ DWORD dwRet;
+ BOOL bMapperFlg = FALSE;
printf("waveOutOpen(%08X, %d, %08X, %08X, %08X, %08X);\n",
lphWaveOut, uDeviceID, lpFormat, dwCallback, dwInstance, dwFlags);
if (dwFlags & WAVE_FORMAT_QUERY) {
- printf("waveOutOpen // WAVE_FORMAT_QUERY !\n");
- if (uDeviceID == (UINT)WAVE_MAPPER) {
- printf("waveOutOpen // No WAVE_MAPPER supported yet !\n");
- return MMSYSERR_BADDEVICEID;
- }
+ printf("waveOutOpen // WAVE_FORMAT_QUERY requested !\n");
+ }
+ if (uDeviceID == (UINT)WAVE_MAPPER) {
+ printf("waveOutOpen // WAVE_MAPPER mode requested !\n");
+ bMapperFlg = TRUE;
+ uDeviceID = 0;
}
if (lpFormat == NULL) return WAVERR_BADFORMAT;
- if (lphWaveOut != NULL) *lphWaveOut = 0;
- if (lphWaveOut != NULL) *lphWaveOut = ++mciActiveDev;
- return 0;
-/* return MMSYSERR_BADDEVICEID;*/
+ hWaveOut = GlobalAlloc(GMEM_MOVEABLE, sizeof(WAVEOPENDESC));
+ if (lphWaveOut != NULL) *lphWaveOut = hWaveOut;
+ lpDesc = (LPWAVEOPENDESC) GlobalLock(hWaveOut);
+ if (lpDesc == NULL) return MMSYSERR_NOMEM;
+ lpDesc->hWave = hWaveOut;
+ lpDesc->lpFormat = lpFormat;
+ lpDesc->dwCallBack = dwCallback;
+ lpDesc->dwInstance = dwInstance;
+ while(uDeviceID < MAXWAVEDRIVERS) {
+ dwRet = wodMessage(uDeviceID, WODM_OPEN,
+ lpDesc->dwInstance, (DWORD)lpDesc, 0L);
+ if (dwRet == MMSYSERR_NOERROR) break;
+ if (!bMapperFlg) break;
+ uDeviceID++;
+ printf("waveOutOpen // WAVE_MAPPER mode ! try next driver...\n");
+ }
+ if (dwFlags & WAVE_FORMAT_QUERY) {
+ printf("waveOutOpen // End of WAVE_FORMAT_QUERY !\n");
+ waveOutClose(hWaveOut);
+ }
+ return dwRet;
}
/**************************************************************************
@@ -1165,8 +1236,11 @@
*/
UINT WINAPI waveOutClose(HWAVEOUT hWaveOut)
{
- printf("waveOutClose\n");
- return MMSYSERR_INVALHANDLE;
+ LPWAVEOPENDESC lpDesc;
+ printf("waveOutClose(%04X)\n", hWaveOut);
+ lpDesc = (LPWAVEOPENDESC) GlobalLock(hWaveOut);
+ if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
+ return wodMessage(0, WODM_CLOSE, lpDesc->dwInstance, 0L, 0L);
}
/**************************************************************************
@@ -1175,8 +1249,13 @@
UINT WINAPI waveOutPrepareHeader(HWAVEOUT hWaveOut,
WAVEHDR FAR* lpWaveOutHdr, UINT uSize)
{
- printf("waveOutPrepareHeader\n");
- return MMSYSERR_INVALHANDLE;
+ LPWAVEOPENDESC lpDesc;
+ printf("waveOutPrepareHeader(%04X, %08X, %u);\n",
+ hWaveOut, lpWaveOutHdr, uSize);
+ lpDesc = (LPWAVEOPENDESC) GlobalLock(hWaveOut);
+ if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
+ return wodMessage(0, WODM_PREPARE, lpDesc->dwInstance,
+ (DWORD)lpWaveOutHdr, uSize);
}
/**************************************************************************
@@ -1185,8 +1264,13 @@
UINT WINAPI waveOutUnprepareHeader(HWAVEOUT hWaveOut,
WAVEHDR FAR* lpWaveOutHdr, UINT uSize)
{
- printf("waveOutUnprepareHeader\n");
- return MMSYSERR_INVALHANDLE;
+ LPWAVEOPENDESC lpDesc;
+ printf("waveOutUnprepareHeader(%04X, %08X, %u);\n",
+ hWaveOut, lpWaveOutHdr, uSize);
+ lpDesc = (LPWAVEOPENDESC) GlobalLock(hWaveOut);
+ if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
+ return wodMessage(0, WODM_PREPARE, lpDesc->dwInstance,
+ (DWORD)lpWaveOutHdr, uSize);
}
/**************************************************************************
@@ -1194,8 +1278,12 @@
*/
UINT WINAPI waveOutWrite(HWAVEOUT hWaveOut, WAVEHDR FAR* lpWaveOutHdr, UINT uSize)
{
- printf("waveOutWrite\n");
- return MMSYSERR_INVALHANDLE;
+ LPWAVEOPENDESC lpDesc;
+ printf("waveOutWrite(%04X, %08X, %u);\n", hWaveOut, lpWaveOutHdr, uSize);
+ lpDesc = (LPWAVEOPENDESC) GlobalLock(hWaveOut);
+ if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
+ return wodMessage(0, WODM_WRITE, lpDesc->dwInstance,
+ (DWORD)lpWaveOutHdr, uSize);
}
/**************************************************************************
@@ -1203,7 +1291,7 @@
*/
UINT WINAPI waveOutPause(HWAVEOUT hWaveOut)
{
- printf("waveOutPause\n");
+ printf("waveOutPause(%04X)\n", hWaveOut);
return MMSYSERR_INVALHANDLE;
}
@@ -1212,7 +1300,7 @@
*/
UINT WINAPI waveOutRestart(HWAVEOUT hWaveOut)
{
- printf("waveOutRestart\n");
+ printf("waveOutRestart(%04X)\n", hWaveOut);
return MMSYSERR_INVALHANDLE;
}
@@ -1221,17 +1309,21 @@
*/
UINT WINAPI waveOutReset(HWAVEOUT hWaveOut)
{
- printf("waveOutReset\n");
+ printf("waveOutReset(%04X)\n", hWaveOut);
return MMSYSERR_INVALHANDLE;
}
/**************************************************************************
* waveOutGetPosition [MMSYSTEM.412]
*/
-UINT WINAPI waveOutGetPosition(HWAVEOUT hWaveOut, MMTIME FAR* lpInfo, UINT uSize)
+UINT WINAPI waveOutGetPosition(HWAVEOUT hWaveOut, MMTIME FAR* lpTime, UINT uSize)
{
- printf("waveOutGetPosition\n");
- return MMSYSERR_INVALHANDLE;
+ LPWAVEOPENDESC lpDesc;
+ printf("waveOutGetPosition(%04X, %08X, %u);\n", hWaveOut, lpTime, uSize);
+ lpDesc = (LPWAVEOPENDESC) GlobalLock(hWaveOut);
+ if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
+ return wodMessage(0, WODM_GETPOS, lpDesc->dwInstance,
+ (DWORD)lpTime, (DWORD)uSize);
}
/**************************************************************************
@@ -1293,7 +1385,7 @@
*/
UINT WINAPI waveOutBreakLoop(HWAVEOUT hWaveOut)
{
- printf("waveOutBreakLoop\n");
+ printf("waveOutBreakLoop(%04X)\n", hWaveOut);
return MMSYSERR_INVALHANDLE;
}
@@ -1319,8 +1411,11 @@
*/
UINT WINAPI waveInGetNumDevs()
{
+ UINT count = 0;
printf("waveInGetNumDevs\n");
- return 0;
+ count += widMessage(0, WIDM_GETNUMDEVS, 0L, 0L, 0L);
+ printf("waveInGetNumDevs return %u \n", count);
+ return count;
}
@@ -1330,7 +1425,7 @@
UINT WINAPI waveInGetDevCaps(UINT uDeviceID, WAVEINCAPS FAR* lpCaps, UINT uSize)
{
printf("waveInGetDevCaps\n");
- return MMSYSERR_INVALHANDLE;
+ return widMessage(uDeviceID, WIDM_GETDEVCAPS, 0L, (DWORD)lpCaps, uSize);
}
@@ -1350,18 +1445,42 @@
UINT WINAPI waveInOpen(HWAVEIN FAR* lphWaveIn, UINT uDeviceID,
const LPWAVEFORMAT lpFormat, DWORD dwCallback, DWORD dwInstance, DWORD dwFlags)
{
+ HWAVE hWaveIn;
+ LPWAVEOPENDESC lpDesc;
+ DWORD dwRet;
+ BOOL bMapperFlg = FALSE;
printf("waveInOpen(%08X, %d, %08X, %08X, %08X, %08X);\n",
lphWaveIn, uDeviceID, lpFormat, dwCallback, dwInstance, dwFlags);
if (dwFlags & WAVE_FORMAT_QUERY) {
- printf("waveInOpen // WAVE_FORMAT_QUERY !\n");
- if (uDeviceID == (UINT)WAVE_MAPPER) {
- printf("waveInOpen // No WAVE_MAPPER supported yet !\n");
- return MMSYSERR_BADDEVICEID;
- }
+ printf("waveInOpen // WAVE_FORMAT_QUERY requested !\n");
}
- if (lphWaveIn != NULL) *lphWaveIn = 0;
+ if (uDeviceID == (UINT)WAVE_MAPPER) {
+ printf("waveInOpen // WAVE_MAPPER mode requested !\n");
+ bMapperFlg = TRUE;
+ uDeviceID = 0;
+ }
if (lpFormat == NULL) return WAVERR_BADFORMAT;
- return MMSYSERR_BADDEVICEID;
+ hWaveIn = GlobalAlloc(GMEM_MOVEABLE, sizeof(WAVEOPENDESC));
+ if (lphWaveIn != NULL) *lphWaveIn = hWaveIn;
+ lpDesc = (LPWAVEOPENDESC) GlobalLock(hWaveIn);
+ if (lpDesc == NULL) return MMSYSERR_NOMEM;
+ lpDesc->hWave = hWaveIn;
+ lpDesc->lpFormat = lpFormat;
+ lpDesc->dwCallBack = dwCallback;
+ lpDesc->dwInstance = dwInstance;
+ while(uDeviceID < MAXWAVEDRIVERS) {
+ dwRet = widMessage(uDeviceID, WIDM_OPEN,
+ lpDesc->dwInstance, (DWORD)lpDesc, 0L);
+ if (dwRet == MMSYSERR_NOERROR) break;
+ if (!bMapperFlg) break;
+ uDeviceID++;
+ printf("waveInOpen // WAVE_MAPPER mode ! try next driver...\n");
+ }
+ if (dwFlags & WAVE_FORMAT_QUERY) {
+ printf("waveInOpen // End of WAVE_FORMAT_QUERY !\n");
+ waveInClose(hWaveIn);
+ }
+ return dwRet;
}
@@ -1370,8 +1489,11 @@
*/
UINT WINAPI waveInClose(HWAVEIN hWaveIn)
{
- printf("waveInClose\n");
- return MMSYSERR_INVALHANDLE;
+ LPWAVEOPENDESC lpDesc;
+ printf("waveInClose(%04X)\n", hWaveIn);
+ lpDesc = (LPWAVEOPENDESC) GlobalLock(hWaveIn);
+ if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
+ return widMessage(0, WIDM_CLOSE, lpDesc->dwInstance, 0L, 0L);
}
@@ -1381,8 +1503,18 @@
UINT WINAPI waveInPrepareHeader(HWAVEIN hWaveIn,
WAVEHDR FAR* lpWaveInHdr, UINT uSize)
{
- printf("waveInPrepareHeader\n");
- return MMSYSERR_INVALHANDLE;
+ LPWAVEOPENDESC lpDesc;
+ printf("waveInPrepareHeader(%04X, %08X, %u);\n",
+ hWaveIn, lpWaveInHdr, uSize);
+ lpDesc = (LPWAVEOPENDESC) GlobalLock(hWaveIn);
+ if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
+ if (lpWaveInHdr == NULL) return MMSYSERR_INVALHANDLE;
+ lpWaveInHdr->lpNext = NULL;
+ lpWaveInHdr->dwBytesRecorded = 0;
+ printf("waveInPrepareHeader // lpData=%08X size=%u \n",
+ lpWaveInHdr->lpData, lpWaveInHdr->dwBufferLength);
+ return widMessage(0, WIDM_PREPARE, lpDesc->dwInstance,
+ (DWORD)lpWaveInHdr, uSize);
}
@@ -1392,20 +1524,36 @@
UINT WINAPI waveInUnprepareHeader(HWAVEIN hWaveIn,
WAVEHDR FAR* lpWaveInHdr, UINT uSize)
{
- printf("waveInUnprepareHeader\n");
- return MMSYSERR_INVALHANDLE;
+ LPWAVEOPENDESC lpDesc;
+ printf("waveInUnprepareHeader(%04X, %08X, %u);\n",
+ hWaveIn, lpWaveInHdr, uSize);
+ lpDesc = (LPWAVEOPENDESC) GlobalLock(hWaveIn);
+ if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
+ USER_HEAP_FREE(HIWORD((DWORD)lpWaveInHdr->lpData));
+ lpWaveInHdr->lpData = NULL;
+ lpWaveInHdr->lpNext = NULL;
+ return widMessage(0, WIDM_PREPARE, lpDesc->dwInstance,
+ (DWORD)lpWaveInHdr, uSize);
}
-
/**************************************************************************
* waveInAddBuffer [MMSYSTEM.508]
*/
UINT WINAPI waveInAddBuffer(HWAVEIN hWaveIn,
WAVEHDR FAR* lpWaveInHdr, UINT uSize)
{
- printf("waveInAddBuffer\n");
- return 0;
+ LPWAVEOPENDESC lpDesc;
+ printf("waveInAddBuffer(%04X, %08X, %u);\n", hWaveIn, lpWaveInHdr, uSize);
+ lpDesc = (LPWAVEOPENDESC) GlobalLock(hWaveIn);
+ if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
+ if (lpWaveInHdr == NULL) return MMSYSERR_INVALHANDLE;
+ lpWaveInHdr->lpNext = NULL;
+ lpWaveInHdr->dwBytesRecorded = 0;
+ printf("waveInAddBuffer // lpData=%08X size=%u \n",
+ lpWaveInHdr->lpData, lpWaveInHdr->dwBufferLength);
+ return widMessage(0, WIDM_ADDBUFFER, lpDesc->dwInstance,
+ (DWORD)lpWaveInHdr, uSize);
}
@@ -1414,8 +1562,11 @@
*/
UINT WINAPI waveInStart(HWAVEIN hWaveIn)
{
- printf("waveInStart\n");
- return MMSYSERR_INVALHANDLE;
+ LPWAVEOPENDESC lpDesc;
+ printf("waveInStart(%04X)\n", hWaveIn);
+ lpDesc = (LPWAVEOPENDESC) GlobalLock(hWaveIn);
+ if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
+ return widMessage(0, WIDM_START, lpDesc->dwInstance, 0L, 0L);
}
@@ -1424,8 +1575,11 @@
*/
UINT WINAPI waveInStop(HWAVEIN hWaveIn)
{
- printf("waveInStop\n");
- return MMSYSERR_INVALHANDLE;
+ LPWAVEOPENDESC lpDesc;
+ printf("waveInStop(%04X)\n", hWaveIn);
+ lpDesc = (LPWAVEOPENDESC) GlobalLock(hWaveIn);
+ if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
+ return widMessage(0, WIDM_STOP, lpDesc->dwInstance, 0L, 0L);
}
@@ -1434,18 +1588,25 @@
*/
UINT WINAPI waveInReset(HWAVEIN hWaveIn)
{
- printf("waveInReset\n");
- return MMSYSERR_INVALHANDLE;
+ LPWAVEOPENDESC lpDesc;
+ printf("waveInReset(%04X)\n", hWaveIn);
+ lpDesc = (LPWAVEOPENDESC) GlobalLock(hWaveIn);
+ if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
+ return widMessage(0, WIDM_RESET, lpDesc->dwInstance, 0L, 0L);
}
/**************************************************************************
* waveInGetPosition [MMSYSTEM.512]
*/
-UINT WINAPI waveInGetPosition(HWAVEIN hWaveIn, MMTIME FAR* lpInfo, UINT uSize)
+UINT WINAPI waveInGetPosition(HWAVEIN hWaveIn, MMTIME FAR* lpTime, UINT uSize)
{
- printf("waveInGetPosition\n");
- return MMSYSERR_INVALHANDLE;
+ LPWAVEOPENDESC lpDesc;
+ printf("waveInGetPosition(%04X, %08X, %u);\n", hWaveIn, lpTime, uSize);
+ lpDesc = (LPWAVEOPENDESC) GlobalLock(hWaveIn);
+ if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
+ return widMessage(0, WIDM_GETPOS, lpDesc->dwInstance,
+ (DWORD)lpTime, (DWORD)uSize);
}
@@ -1455,6 +1616,7 @@
UINT WINAPI waveInGetID(HWAVEIN hWaveIn, UINT FAR* lpuDeviceID)
{
printf("waveInGetID\n");
+ if (lpuDeviceID == NULL) return MMSYSERR_INVALPARAM;
return 0;
}
@@ -1540,7 +1702,7 @@
printf("timeSetEvent(%u, %u, %08X, %08X, %04X);\n",
wDelay, wResol, lpFunc, dwUser, wFlags);
if (!mmTimeStarted) StartMMTime();
- lpNewTimer = malloc(sizeof(TIMERENTRY));
+ lpNewTimer = (LPTIMERENTRY) malloc(sizeof(TIMERENTRY));
if (lpNewTimer == NULL) return 0;
while (lpTimer != NULL) {
wNewID = max(wNewID, lpTimer->wTimerID);
@@ -1628,8 +1790,10 @@
*/
HMMIO WINAPI mmioOpen(LPSTR szFileName, MMIOINFO FAR* lpmmioinfo, DWORD dwOpenFlags)
{
+ int hFile;
printf("mmioOpen('%s', %08X, %08X);\n", szFileName, lpmmioinfo, dwOpenFlags);
- return 0;
+ hFile = _lopen(szFileName, dwOpenFlags);
+ return (HMMIO)hFile;
}
@@ -1640,6 +1804,7 @@
UINT WINAPI mmioClose(HMMIO hmmio, UINT uFlags)
{
printf("mmioClose(%04X, %04X);\n", hmmio, uFlags);
+ _lclose(hmmio);
return 0;
}
@@ -1651,6 +1816,7 @@
LONG WINAPI mmioRead(HMMIO hmmio, HPSTR pch, LONG cch)
{
printf("mmioRead\n");
+ _lread(hmmio, pch, cch);
return 0;
}
@@ -1815,8 +1981,10 @@
*/
LRESULT WINAPI DrvSendMessage(HDRVR hDriver, WORD msg, LPARAM lParam1, LPARAM lParam2)
{
+ DWORD dwDevID = 0;
printf("DrvSendMessage(%04X, %04X, %08X, %08X);\n",
hDriver, msg, lParam1, lParam2);
+ return CDAUDIO_DriverProc(dwDevID, hDriver, msg, lParam1, lParam2);
}
/**************************************************************************
diff --git a/miscemu/int2f.c b/miscemu/int2f.c
index 0a7d14e..046337c 100644
--- a/miscemu/int2f.c
+++ b/miscemu/int2f.c
@@ -3,6 +3,9 @@
#include "msdos.h"
#include "wine.h"
+int do_int2f_16(struct sigcontext_struct *context);
+
+
int do_int2f(struct sigcontext_struct *context)
{
switch((context->sc_eax >> 8) & 0xff)
@@ -12,17 +15,41 @@
return 1;
case 0x16:
- switch(context->sc_eax & 0xff)
- {
- case 0x00: /* windows enhanced mode install check */
- /* don't return anything as we're running in standard mode */
- return 1;
-
- default:
- }
+ return do_int2f_16(context);
default:
IntBarf(0x2f, context);
};
return 1;
}
+
+
+int do_int2f_16(struct sigcontext_struct *context)
+{
+ switch(context->sc_eax & 0xff) {
+ case 0x00:
+ /* return 'major/minor' for MSWin 3.1 */
+ printf("do_int2f_16 // return 'major/minor' for MSWin 3.1 !\n");
+ context->sc_eax = 0x0310;
+ return 1;
+ case 0x86:
+ /* operating in protected mode under DPMI */
+ printf("do_int2f_16 // operating in protected mode under DPMI !\n");
+ context->sc_eax = 0x0000;
+ return 1;
+ case 0x87:
+ printf("do_int2f_16 // return DPMI flags !\n");
+ context->sc_eax = 0x0000; /* DPMI Installed */
+ context->sc_ebx = 0x0001; /* 32bits available */
+ context->sc_ecx = 0x04; /* processor 486 */
+ context->sc_edx = 0x0100; /* DPMI major/minor */
+ context->sc_esi = 0; /* # of para. of DOS */
+ /* extended private data */
+ return 1;
+ default:
+ IntBarf(0x2f, context);
+ }
+ return 1;
+}
+
+
diff --git a/windows/class.c b/windows/class.c
index 753ee0d..622afe1 100644
--- a/windows/class.c
+++ b/windows/class.c
@@ -91,7 +91,8 @@
{
CLASS * newClass, * prevClassPtr;
HCLASS handle, prevClass;
-
+ int classExtra;
+
#ifdef DEBUG_CLASS
printf( "RegisterClass: wndproc=%08x hinst=%d name='%s' background %x\n",
class->lpfnWndProc, class->hInstance, class->lpszClassName,
@@ -110,20 +111,18 @@
if (!(prevClassPtr->wc.style & CS_GLOBALCLASS)) return 0;
}
- /* bug for bug compatible */
-
- if (class->cbClsExtra < 0) class->cbClsExtra = 0;
- if (class->cbWndExtra < 0) class->cbWndExtra = 0;
-
/* Create class */
- handle = USER_HEAP_ALLOC( GMEM_MOVEABLE, sizeof(CLASS)+class->cbClsExtra );
+ classExtra = (class->cbClsExtra < 0) ? 0 : class->cbClsExtra;
+ handle = USER_HEAP_ALLOC( GMEM_MOVEABLE, sizeof(CLASS) + classExtra );
if (!handle) return 0;
newClass = (CLASS *) USER_HEAP_ADDR( handle );
- newClass->hNext = firstClass;
- newClass->wMagic = CLASS_MAGIC;
- newClass->cWindows = 0;
- newClass->wc = *class;
+ newClass->hNext = firstClass;
+ newClass->wMagic = CLASS_MAGIC;
+ newClass->cWindows = 0;
+ newClass->wc = *class;
+ newClass->wc.cbWndExtra = (class->cbWndExtra < 0) ? 0 : class->cbWndExtra;
+ newClass->wc.cbClsExtra = classExtra;
if (newClass->wc.style & CS_GLOBALCLASS)
newClass->atomName = GlobalAddAtom( class->lpszClassName );
@@ -147,7 +146,7 @@
}
}
- if (class->cbClsExtra) memset( newClass->wExtra, 0, class->cbClsExtra );
+ if (classExtra) memset( newClass->wExtra, 0, classExtra );
firstClass = handle;
return newClass->atomName;
}
diff --git a/windows/dc.c b/windows/dc.c
index 947372d..056329a 100644
--- a/windows/dc.c
+++ b/windows/dc.c
@@ -105,7 +105,6 @@
SelectObject( hdc, dc->w.hFont );
XSetGraphicsExposures( XT_display, dc->u.x.gc, False );
CLIPPING_SetDeviceClipping( dc );
- FONT_SelectObject(dc, STOCK_SYSTEM_FIXED_FONT, NULL);
}
@@ -204,7 +203,7 @@
if (!dc->u.x.font.fstruct)
{
- FONT_SelectObject(dc, STOCK_SYSTEM_FIXED_FONT, NULL);
+ FONT_SelectObject(dc, STOCK_SYSTEM_FONT, NULL);
}
val.function = DC_XROPfunction[dc->w.ROPmode-1];
val.foreground = dc->w.textPixel;
@@ -235,6 +234,7 @@
#endif
memcpy( &newdc->w, &dc->w, sizeof(dc->w) );
+ memcpy( &newdc->u.x.pen, &dc->u.x.pen, sizeof(dc->u.x.pen) );
newdc->saveLevel = 0;
newdc->w.flags |= DC_SAVED;
diff --git a/windows/dialog.c b/windows/dialog.c
index 7edc656..47ad5b4 100644
--- a/windows/dialog.c
+++ b/windows/dialog.c
@@ -595,13 +595,13 @@
*/
void CheckRadioButton( HWND hwndDlg, WORD firstID, WORD lastID, WORD checkID )
{
- HWND button = GetDlgItem( hwndDlg, firstID );
+ HWND button = GetDlgItem( hwndDlg, lastID );
while (button != 0)
{
WND * wndPtr = WIN_FindWndPtr( button );
if (!wndPtr) break;
SendMessage( button, BM_SETCHECK, (wndPtr->wIDmenu == checkID), 0 );
- if (wndPtr->wIDmenu == lastID) break;
+ if (wndPtr->wIDmenu == firstID) break;
button = wndPtr->hwndNext;
}
}
diff --git a/windows/graphics.c b/windows/graphics.c
index 0d2392f..c21eff3 100644
--- a/windows/graphics.c
+++ b/windows/graphics.c
@@ -153,6 +153,8 @@
(double)(xend-xcenter)*(bottom-top) );
diff_angle = end_angle - start_angle;
if (diff_angle < 0.0) diff_angle += 2*PI;
+ if (left > right) swap_int( &left, &right );
+ if (top > bottom) swap_int( &top, &bottom );
XDrawArc( display, dc->u.x.drawable, dc->u.x.gc,
dc->w.DCOrgX + left, dc->w.DCOrgY + top,
diff --git a/windows/painting.c b/windows/painting.c
index 65a17ca..abac9b5 100644
--- a/windows/painting.c
+++ b/windows/painting.c
@@ -45,13 +45,6 @@
if (!(wndPtr->flags & WIN_ERASE_UPDATERGN)) lps->fErase = TRUE;
else lps->fErase = !SendMessage( hwnd, WM_ERASEBKGND, lps->hdc, 0 );
- /*
- * a BeginPaint should return with these objects set by default
- */
- SelectObject(lps->hdc, STOCK_BLACK_PEN);
- SelectObject(lps->hdc, STOCK_WHITE_BRUSH);
- SelectObject(lps->hdc, STOCK_SYSTEM_FONT);
-
return lps->hdc;
}
diff --git a/windows/win.c b/windows/win.c
index cc11dd1..d768512 100644
--- a/windows/win.c
+++ b/windows/win.c
@@ -253,7 +253,10 @@
exStyle, className, windowName, style, x, y, width, height,
parent, menu, instance, data);
#endif
-
+ /* 'soundrec.exe' has negative position !
+ Why ? For now, here a patch : */
+ if (x < 0) x = 0;
+ if (y < 0) y = 0;
if (x == CW_USEDEFAULT) x = y = 0;
if (width == CW_USEDEFAULT)
{
@@ -366,24 +369,15 @@
else
win_attr.backing_store = Always;
- if (Options.nosaveunders)
- win_attr.save_under = FALSE;
- else
- win_attr.save_under = TRUE;
+ win_attr.save_under = ((classPtr->wc.style & CS_SAVEBITS) != 0);
-
- /* set the background of all windows to be white, just like
- * MS-Windows does (hopefully!)
- */
- win_attr.background_pixel = WhitePixelOfScreen(screen);
-
wndPtr->window = XCreateWindow( display, parentPtr->window,
x + parentPtr->rectClient.left - parentPtr->rectWindow.left,
y + parentPtr->rectClient.top - parentPtr->rectWindow.top,
width, height, 0,
CopyFromParent, InputOutput, CopyFromParent,
CWEventMask | CWOverrideRedirect | CWColormap |
- CWSaveUnder | CWBackingStore | CWBackPixel, &win_attr );
+ CWSaveUnder | CWBackingStore, &win_attr );
XStoreName( display, wndPtr->window, windowName );