Sync to Wine-20050930:
Rein Klazes <wijn@wanadoo.nl>
- When scrolling, first update the new position of the control before
  calling UpdateWindow().
Alexandre Julliard <julliard@winehq.org>
- Fixed gcc 4.0 warnings.
- We are no longer generating .dbg.c files.
Krzysztof Foltman <wdev@foltman.com>
- Reimplementation of EM_LINELENGTH.
- Some attempt at documentation of double-linked list of
  ME_DisplayItem's.
- Optional destinations in stylesheets are now skipped properly (and
  not treated as the "proper" styles as they were before).
- EOF condition in the middle of the stylesheet is no longer putting
  the reader into infinite loop,
- Half-full input buffers don't trigger EOF anymore (although it
  could, in theory, break some apps, I find it unlikely - and the
  change makes Out from Boneville installer display license properly).
Marcus Meissner <marcus@jet.franken.de>
- The last argument to MultiByteToWideChar is wide character count and
  not the buffer size in bytes. Fixed all places where it was wrong.
Modified: trunk/reactos/lib/riched20/editor.c
Modified: trunk/reactos/lib/riched20/editor.h
Modified: trunk/reactos/lib/riched20/editstr.h
Modified: trunk/reactos/lib/riched20/reader.c
Modified: trunk/reactos/lib/riched20/row.c
Modified: trunk/reactos/lib/riched20/style.c
Modified: trunk/reactos/lib/riched20/writer.c

Modified: trunk/reactos/lib/riched20/editor.c
--- trunk/reactos/lib/riched20/editor.c	2005-10-08 17:15:42 UTC (rev 18344)
+++ trunk/reactos/lib/riched20/editor.c	2005-10-08 17:17:27 UTC (rev 18345)
@@ -515,9 +515,9 @@
 ME_StreamInFill(ME_InStream *stream)
 {
   stream->editstream->dwError = stream->editstream->pfnCallback(stream->editstream->dwCookie,
-                                                                stream->buffer,
+                                                                (BYTE *)stream->buffer,
                                                                 sizeof(stream->buffer),
-                                                                &stream->dwSize);
+                                                                (LONG *)&stream->dwSize);
   stream->dwUsed = 0;
 }
 
@@ -1097,7 +1097,7 @@
   SCROLLINFO si;
   ME_TextEditor *editor = (ME_TextEditor *)GetWindowLongW(hWnd, 0);
   
-  TRACE("hWnd %p msg %d (%s) %08x %08lx\n",
+  TRACE("hWnd %p msg %04x (%s) %08x %08lx\n",
         hWnd, msg, get_msg_name(msg), wParam, lParam);
   
   switch(msg) {
@@ -1188,7 +1188,7 @@
     UINT from, to;
     PUINT pfrom = wParam ? (PUINT)wParam : &from;
     PUINT pto = lParam ? (PUINT)lParam : &to;
-    ME_GetSelection(editor, pfrom, pto);
+    ME_GetSelection(editor, (int *)pfrom, (int *)pto);
     if ((*pfrom|*pto) & 0xFFFF0000)
       return -1;
     return MAKELONG(*pfrom,*pto);
@@ -1359,13 +1359,14 @@
     if (nPos<0)
       nPos = 0;
     if (nPos != editor->nScrollPosY) {
+      int dy = editor->nScrollPosY - nPos;
+      editor->nScrollPosY = nPos;
+      SetScrollPos(hWnd, SB_VERT, nPos, TRUE);
       if (editor->bRedraw)
       {
-        ScrollWindow(hWnd, 0, editor->nScrollPosY-nPos, NULL, NULL);
-        SetScrollPos(hWnd, SB_VERT, nPos, TRUE);
+        ScrollWindow(hWnd, 0, dy, NULL, NULL);
         UpdateWindow(hWnd);
       }
-      editor->nScrollPosY = nPos;
     }
     return TRUE; /* Should return false if a single line richedit control */
   }
@@ -1622,7 +1623,7 @@
   case EM_LINELENGTH:
   {
     ME_DisplayItem *item, *item_end;
-    int nChars = 0;
+    int nChars = 0, nThisLineOfs = 0, nNextLineOfs = 0;
     
     if (wParam > ME_GetTextLength(editor))
       return 0;
@@ -1633,17 +1634,13 @@
     }
     item = ME_FindItemAtOffset(editor, diRun, wParam, NULL);
     item = ME_RowStart(item);
-    item_end = ME_RowEnd(item);
-    if (!item_end)
-    {
-      /* Empty buffer, no runs */
-      nChars = 0;
-    }
+    nThisLineOfs = ME_CharOfsFromRunOfs(editor, ME_FindItemFwd(item, diRun), 0);
+    item_end = ME_FindItemFwd(item, diStartRow);
+    if (item_end)
+      nNextLineOfs = ME_CharOfsFromRunOfs(editor, ME_FindItemFwd(item_end, diRun), 0);
     else
-    {
-      nChars = ME_CharOfsFromRunOfs(editor, item_end, ME_StrLen(item_end->member.run.strText));
-      nChars -= ME_CharOfsFromRunOfs(editor, item, 0);
-    }
+      nNextLineOfs = ME_FindItemFwd(item, diParagraphOrEnd)->member.para.nCharOfs-1;
+    nChars = nNextLineOfs - nThisLineOfs;
     TRACE("EM_LINELENGTH(%d)==%d\n",wParam, nChars);
     return nChars;
   }
@@ -1849,13 +1846,14 @@
       break;
     }
     if (nPos != editor->nScrollPosY) {
+      int dy = editor->nScrollPosY - nPos;
+      editor->nScrollPosY = nPos;
+      SetScrollPos(hWnd, SB_VERT, nPos, TRUE);
       if (editor->bRedraw)
       {
-        ScrollWindow(hWnd, 0, editor->nScrollPosY-nPos, NULL, NULL);
-        SetScrollPos(hWnd, SB_VERT, nPos, TRUE);
+        ScrollWindow(hWnd, 0, dy, NULL, NULL);
         UpdateWindow(hWnd);
       }
-      editor->nScrollPosY = nPos;
     }
     break;
   }
@@ -1872,13 +1870,14 @@
     if (nPos<0)
       nPos = 0;
     if (nPos != editor->nScrollPosY) {
+      int dy = editor->nScrollPosY - nPos;
+      editor->nScrollPosY = nPos;
+      SetScrollPos(hWnd, SB_VERT, nPos, TRUE);
       if (editor->bRedraw)
       {
-        ScrollWindow(hWnd, 0, editor->nScrollPosY-nPos, NULL, NULL);
-        SetScrollPos(hWnd, SB_VERT, nPos, TRUE);
+        ScrollWindow(hWnd, 0, dy, NULL, NULL);
         UpdateWindow(hWnd);
       }
-      editor->nScrollPosY = nPos;
     }
     break;
   }

Modified: trunk/reactos/lib/riched20/editor.h
--- trunk/reactos/lib/riched20/editor.h	2005-10-08 17:15:42 UTC (rev 18344)
+++ trunk/reactos/lib/riched20/editor.h	2005-10-08 17:17:27 UTC (rev 18345)
@@ -98,7 +98,7 @@
 /* row.c */
 ME_DisplayItem *ME_FindRowStart(ME_Context *c, ME_DisplayItem *run, int nRelPos);
 ME_DisplayItem *ME_RowStart(ME_DisplayItem *item);
-ME_DisplayItem *ME_RowEnd(ME_DisplayItem *item);
+/* ME_DisplayItem *ME_RowEnd(ME_DisplayItem *item); */
 void ME_RenumberParagraphs(ME_DisplayItem *item); /* TODO */
 ME_DisplayItem *ME_FindRowWithNumber(ME_TextEditor *editor, int nRow);
 int ME_RowNumberFromCharOfs(ME_TextEditor *editor, int nOfs);

Modified: trunk/reactos/lib/riched20/editstr.h
--- trunk/reactos/lib/riched20/editstr.h	2005-10-08 17:15:42 UTC (rev 18344)
+++ trunk/reactos/lib/riched20/editstr.h	2005-10-08 17:17:27 UTC (rev 18345)
@@ -161,6 +161,18 @@
   int nYPos;
 } ME_Row;
 
+/* the display item list layout is like this:
+ * - the document consists of paragraphs
+ * - each paragraph contains at least one run, the last run in the paragraph
+ *   is an end-of-paragraph run
+ * - each formatted paragraph contains at least one row, which corresponds
+ *   to a screen line (that's why there are no rows in an unformatted
+ *   paragraph
+ * - the paragraphs contain "shortcut" pointers to the previous and the next
+ *   paragraph, that makes iteration over paragraphs faster 
+ * - the list starts with diTextStart and ends with diTextEnd
+ */
+
 typedef struct tagME_DisplayItem
 {
   ME_DIType type;
@@ -212,7 +224,7 @@
   EDITSTREAM *editstream;
   DWORD dwSize;
   DWORD dwUsed;
-  BYTE buffer[STREAMIN_BUFFER_SIZE];
+  char buffer[STREAMIN_BUFFER_SIZE];
 };
 typedef struct tagME_InStream ME_InStream;
 

Modified: trunk/reactos/lib/riched20/reader.c
--- trunk/reactos/lib/riched20/reader.c	2005-10-08 17:15:42 UTC (rev 18344)
+++ trunk/reactos/lib/riched20/reader.c	2005-10-08 17:17:27 UTC (rev 18345)
@@ -127,10 +127,13 @@
 
 	TRACE("\n");
 
-	/* if the last buffer wasn't full, it's EOF */
+	/* Doc says, that if the last buffer wasn't full, it's EOF.
+	Actually, that's not true. */
+/*
 	if (stream->dwSize > 0 && stream->dwSize == stream->dwUsed
             && stream->dwSize < sizeof(stream->buffer))
 		return EOF;
+*/
 	if (stream->dwSize <= stream->dwUsed)
 	{
                 ME_StreamInFill(stream);
@@ -1089,12 +1092,15 @@
 	RTFStyleElt	*sep, *sepLast;
 	char		buf[rtfBufSiz], *bp;
 	const char	*fn = "ReadStyleSheet";
+	int             real_style;
 
 	TRACE("\n");
 
 	for (;;)
 	{
 		RTFGetToken (info);
+		if (info->rtfClass == rtfEOF)
+			break;
 		if (RTFCheckCM (info, rtfGroup, rtfEndGroup))
 			break;
 		sp = New (RTFStyle);
@@ -1112,6 +1118,7 @@
 		info->styleList = sp;
 		if (!RTFCheckCM (info, rtfGroup, rtfBeginGroup))
 			RTFPanic (info,"%s: missing \"{\"", fn);
+		real_style = TRUE;
 		for (;;)
 		{
 			RTFGetToken (info);
@@ -1120,8 +1127,15 @@
 				break;
 			if (info->rtfClass == rtfControl)
 			{
-				if (RTFCheckMM (info, rtfSpecialChar, rtfOptDest))
-					continue;	/* ignore "\*" */
+				if (RTFCheckMM (info, rtfSpecialChar, rtfOptDest)) {
+					RTFGetToken(info);
+					RTFPanic(info, "%s: skipping optional destination", fn);
+					RTFSkipGroup(info);
+					info->rtfClass = rtfGroup;
+					info->rtfMajor = rtfEndGroup;
+					real_style = FALSE;
+					break; /* ignore "\*" */
+				}
 				if (RTFCheckMM (info, rtfParAttr, rtfStyleNum))
 				{
 					sp->rtfSNum = info->rtfParam;
@@ -1178,6 +1192,7 @@
 				 * This passes over "{\*\keycode ... }, among
 				 * other things. A temporary (perhaps) hack.
 				 */
+                                RTFPanic(info, "%s: skipping begin", fn);
 				RTFSkipGroup (info);
 				continue;
 			}
@@ -1207,31 +1222,33 @@
 							fn, info->rtfTextBuf);
 			}
 		}
-		RTFGetToken (info);
-		if (!RTFCheckCM (info, rtfGroup, rtfEndGroup))
-			RTFPanic (info, "%s: missing \"}\"", fn);
-
-		/*
-		 * Check over the style structure.  A name is a must.
-		 * If no style number was specified, check whether it's the
-		 * Normal style (in which case it's given style number
-		 * rtfNormalStyleNum).  Note that some "normal" style names
-		 * just begin with "Normal" and can have other stuff following,
-		 * e.g., "Normal,Times 10 point".  Ugh.
-		 *
-		 * Some German RTF writers use "Standard" instead of "Normal".
-		 */
-		if (sp->rtfSName == NULL)
-			RTFPanic (info,"%s: missing style name", fn);
-		if (sp->rtfSNum < 0)
-		{
-			if (strncmp (buf, "Normal", 6) != 0
-				&& strncmp (buf, "Standard", 8) != 0)
-				RTFPanic (info,"%s: missing style number", fn);
-			sp->rtfSNum = rtfNormalStyleNum;
+		if (real_style) {
+			RTFGetToken (info);
+			if (!RTFCheckCM (info, rtfGroup, rtfEndGroup))
+				RTFPanic (info, "%s: missing \"}\"", fn);
+			/*
+			 * Check over the style structure.  A name is a must.
+			 * If no style number was specified, check whether it's the
+			 * Normal style (in which case it's given style number
+			 * rtfNormalStyleNum).  Note that some "normal" style names
+			 * just begin with "Normal" and can have other stuff following,
+			 * e.g., "Normal,Times 10 point".  Ugh.
+			 *
+			 * Some German RTF writers use "Standard" instead of "Normal".
+			 */
+			if (sp->rtfSName == NULL)
+				RTFPanic (info,"%s: missing style name", fn);
+			if (sp->rtfSNum < 0)
+			{
+				if (strncmp (buf, "Normal", 6) != 0
+					&& strncmp (buf, "Standard", 8) != 0)
+					RTFPanic (info,"%s: missing style number", fn);
+				sp->rtfSNum = rtfNormalStyleNum;
+			}
+			if (sp->rtfSNextPar == -1)	/* if \snext not given, */
+				sp->rtfSNextPar = sp->rtfSNum;	/* next is itself */
 		}
-		if (sp->rtfSNextPar == -1)	/* if \snext not given, */
-			sp->rtfSNextPar = sp->rtfSNum;	/* next is itself */
+		/* otherwise we're just dealing with fake end group from skipped group */
 	}
 	RTFRouteToken (info);	/* feed "}" back to router */
 }
@@ -2755,7 +2772,7 @@
         int length;
 
         length = MultiByteToWideChar(info->codePage, 0, info->cpOutputBuffer,
-                                     info->dwCPOutputCount, buffer, bufferMax);
+                                     info->dwCPOutputCount, buffer, bufferMax/sizeof(WCHAR));
         info->dwCPOutputCount = 0;
 
         RTFPutUnicodeString(info, buffer, length);

Modified: trunk/reactos/lib/riched20/row.c
--- trunk/reactos/lib/riched20/row.c	2005-10-08 17:15:42 UTC (rev 18344)
+++ trunk/reactos/lib/riched20/row.c	2005-10-08 17:17:27 UTC (rev 18345)
@@ -77,13 +77,14 @@
   return ME_FindItemBackOrHere(item, diStartRow);
 }
 
+/*
 ME_DisplayItem *ME_RowEnd(ME_DisplayItem *item) {
   ME_DisplayItem *item2 = ME_FindItemFwd(item, diStartRowOrParagraphOrEnd);
   if (!item2) return NULL;
   return ME_FindItemBack(item, diRun);
 }
+*/
 
-
 ME_DisplayItem *
 ME_FindRowWithNumber(ME_TextEditor *editor, int nRow)
 {

Modified: trunk/reactos/lib/riched20/style.c
--- trunk/reactos/lib/riched20/style.c	2005-10-08 17:15:42 UTC (rev 18344)
+++ trunk/reactos/lib/riched20/style.c	2005-10-08 17:17:27 UTC (rev 18345)
@@ -52,7 +52,7 @@
     CopyMemory(to, f, sizeof(CHARFORMATA)-sizeof(f->szFaceName));
     /* convert face name */
     if (f->dwMask & CFM_FACE)
-      MultiByteToWideChar(0, 0, f->szFaceName, -1, to->szFaceName, sizeof(to->szFaceName));
+      MultiByteToWideChar(0, 0, f->szFaceName, -1, to->szFaceName, sizeof(to->szFaceName)/sizeof(WCHAR));
     /* copy the rest of the 2A structure to 2W */
     CopyMemory(1+((CHARFORMATW *)to), f+1, sizeof(CHARFORMAT2A)-sizeof(CHARFORMATA));
     to->cbSize = sizeof(CHARFORMAT2W);

Modified: trunk/reactos/lib/riched20/writer.c
--- trunk/reactos/lib/riched20/writer.c	2005-10-08 17:15:42 UTC (rev 18344)
+++ trunk/reactos/lib/riched20/writer.c	2005-10-08 17:17:27 UTC (rev 18345)
@@ -55,7 +55,7 @@
       on initial random nWritten value, which is usually >STREAMOUT_BUFFER_SIZE */
     nRemaining = editor->pStream->pos - nStart;
     nWritten = 0xDEADBEEF;
-    stream->dwError = stream->pfnCallback(stream->dwCookie, editor->pStream->buffer + nStart,
+    stream->dwError = stream->pfnCallback(stream->dwCookie, (LPBYTE)editor->pStream->buffer + nStart,
                                           editor->pStream->pos - nStart, &nWritten);
     TRACE("error=%lu written=%lu\n", stream->dwError, nWritten);
     if (nWritten > (editor->pStream->pos - nStart) || nWritten<0) {
@@ -86,7 +86,7 @@
 
 
 static BOOL
-ME_StreamOutMove(ME_TextEditor *editor, BYTE *buffer, int len)
+ME_StreamOutMove(ME_TextEditor *editor, const char *buffer, int len)
 {
   ME_OutStream *pStream = editor->pStream;
   
@@ -599,8 +599,8 @@
       nChars--;
     } else {
       BOOL unknown = FALSE;
-      BYTE letter[3];
-      
+      char letter[3];
+
       /* FIXME: In the MS docs for WideCharToMultiByte there is a big list of
        * codepages including CP_SYMBOL for which the last parameter must be set
        * to NULL for the function to succeed. But in Wine we need to care only
@@ -610,7 +610,7 @@
                                    (editor->pStream->nCodePage == CP_SYMBOL) ? NULL : &unknown);
       if (unknown)
         pos += sprintf(buffer + pos, "\\u%d?", (short)*text);
-      else if (*letter < 128) {
+      else if ((BYTE)*letter < 128) {
         if (*letter == '{' || *letter == '}' || *letter == '\\')
           buffer[pos++] = '\\';
         buffer[pos++] = *letter;
@@ -720,7 +720,7 @@
   ME_DisplayItem *item = ME_FindItemAtOffset(editor, diRun, nStart, &nStart);
   int nLen;
   UINT nCodePage = CP_ACP;
-  BYTE *buffer = NULL;
+  char *buffer = NULL;
   int nBufLen = 0;
   BOOL success = TRUE;
 
@@ -738,15 +738,15 @@
       nLen = nChars;
 
     if (item->member.run.nFlags & MERF_ENDPARA) {
-      WCHAR szEOL[] = { '\r', '\n' };
+      static const WCHAR szEOL[2] = { '\r', '\n' };
       
       if (dwFormat & SF_UNICODE)
-        success = ME_StreamOutMove(editor, (BYTE *)szEOL, 4);
+        success = ME_StreamOutMove(editor, (const char *)szEOL, sizeof(szEOL));
       else
         success = ME_StreamOutMove(editor, "\r\n", 2);
     } else {
       if (dwFormat & SF_UNICODE)
-        success = ME_StreamOutMove(editor, (BYTE *)(item->member.run.strText->szData + nStart),
+        success = ME_StreamOutMove(editor, (const char *)(item->member.run.strText->szData + nStart),
                                    sizeof(WCHAR) * nLen);
       else {
         int nSize;
@@ -756,7 +756,7 @@
         if (nSize > nBufLen) {
           if (buffer)
             FREE_OBJ(buffer);
-          buffer = ALLOC_N_OBJ(BYTE, nSize);
+          buffer = ALLOC_N_OBJ(char, nSize);
           nBufLen = nSize;
         }
         WideCharToMultiByte(nCodePage, 0, item->member.run.strText->szData + nStart,