Release 970120

Sun Jan 19 11:46:48 1997  Alexandre Julliard  <julliard@lrc.epfl.ch>

	* [loader/module.c]
	Fixed LoadModule() to always call the DLL initialization code.

	* [windows/event.c]
	Moved all the keyboard stuff to windows/keyboard.c

	* [tools/build.c]
	Fixed Win32 register functions.

Sat Jan 18 22:24:41 1997  David Makepeace  <D.Makepeace@mailbox.uq.oz.au>

        * [tools/makedep.c]
        Fixed bug which causes SEGV on Solaris x86.

Fri Jan 17 18:32:27 1997  Frans van Dorsselaer <dorssel@rulhmpc49.LeidenUniv.nl>

	* [controls/edit.c]
	Implemented WM_UNDO, WM_CONTEXTMENU (temporary using WM_RBUTTONUP),
	WM_COMMAND, WM_INITPOPUPMENU, WM_SYSKEYDOWN.
	Fixed EM_SETSEL and some minor bugs (features).
	Hence: fully functional undo and a win95 menu with the right mouse
		button.

	* [include/resources.h] [resources/TODO] [resources/sysres_??.rc]
	Added a context menu for the edit control.
	Translations, please ...

Fri Jan	17 08:29:52 1997  David Faure <david.faure@ifhamy.insa-lyon.fr>

	* [windows/event.c]
	Move EVENT_ToAscii to windows/keyboard.c (where name ToAscii)
	Fixed Keypad keys 0-9 and . in EVENT_event_to_vkey.
	Added 3-state handling of toggle keys (CapsLock, NumLock) in order
	to make them work with any X server.
	Toggle keys now generate WM_KEYDOWN and WM_KEYUP on each pressing.

	* [include/keyboard.h]
	Totally replaced the file (formerly containing the vkcase definitions)
	by the declaration of 'extern' variables contained by event.c and used
	by keyboard.c
	
	* [windows/keyboard.c]
	Started to rewrite VkKeyScan and MapVirtualKey, to make them use the 
	table keyc2vkey or X functions only.
	ToAscii : added keypad 0-9 and . special case.
	Changed toggle keys active mask from 0x80 to 0x1.

	* [misc/keyboard.c]
	File deleted. Contents moved to windows/keyboard.c.

	* [misc/main.c]
	Added putenv XKB_DISABLE to disable XKB extension (which, when
	present, causes AltGr to change keyboard group instead of being a
	modifier).

Tue Jan 14 22:56:43 1997  Philippe De Muyter  <phdm@info.ucl.ac.be>

	* [windows/event.c]
	Do not assume NumLockMask is Mod2Mask, but compute it by scanning
	output of XGetModifierMapping for XK_Num_Lock.

Tue Jan 14 15:49:49 1997  Marcus Meissner <msmeissn@cip.informatik.uni-erlangen.de>

	* [loader/pe_*.c] [include/peexe.h] [include/resource32.h]
	  [debugger/*.c]
	General clean up.
	Changed defines/structures to match Windows NT SDK.

	* [loader/main.c]
	Don't crash on empty command-line.

	* [windows/winpos.c]
	winpos.c made win32 clean.

	* [misc/ntdll.c]
	Some string conversion additions.

	* [files/file.c]
	GetFileAttributes/GetTempFileName fixed.

	* [misc/ver.c]
	VerInstallFile implemented.

Mon Jan 13 15:03:11 1997  Philippe De Muyter  <phdm@info.ucl.ac.be>

	* [tools/build.c]: Use PREFIX also in stabs messages.

Mon Jan 13 10:40:33 1997  John Harvey <john@division.co.uk>

	* [graphics/win16drv/*] [include/win16drv.h]
	Many fixes and some new features.

	* [graphics/x11drv/font.c] [graphics/x11drv/init.c]
	  [include/x11drv.h] [objects/font.c]
	GetTextMetrics() moved to graphics driver.

	* [if1632/gdi.spec] [misc/fontengine.c] [misc/Makefile.in]
	New dummy EngineEnumerateFont, EngineRealizeFont functions.

	* [include/windows.h]
	TEXTFORM16 and FONTINFO16 structure definitions moved here from
	include/win16drv.h
diff --git a/debugger/types.c b/debugger/types.c
index 581d096..0b26d50 100644
--- a/debugger/types.c
+++ b/debugger/types.c
@@ -11,8 +11,11 @@
 #include <stdlib.h>
 
 #include <assert.h>
+#ifndef __EMX__
 #include <sys/mman.h>
+#endif
 #include <fcntl.h>
+#include <sys/types.h>
 #include <sys/stat.h>
 #include <limits.h>
 #include <strings.h>
@@ -28,6 +31,9 @@
 
 #define NR_TYPE_HASH 521
 
+int		  DEBUG_nchar;
+static int	  DEBUG_maxchar = 1024;
+
 struct en_values
 {
   struct en_values* next;
@@ -177,6 +183,32 @@
   return dt;
 }
 
+static
+struct datatype *
+DEBUG_LookupDataType(enum debug_type xtype, int hash, const char * typename)
+{
+  struct datatype * dt = NULL;
+
+  if( typename != NULL )
+    {
+      for( dt = type_hash_table[hash]; dt; dt = dt->next )
+	{
+	  if( xtype != dt->type || dt->name == NULL 
+	      || dt->name[0] != typename[0])
+	    {
+	      continue;
+	    }
+	  	  
+	  if( strcmp(dt->name, typename) == 0 )
+	    {
+	      return dt;
+	    }
+	}
+    }
+
+  return dt;
+}
+
 struct datatype *
 DEBUG_NewDataType(enum debug_type xtype, const char * typename)
 {
@@ -195,22 +227,7 @@
       hash = type_hash(typename);
     }
 
-  if( typename != NULL )
-    {
-      for( dt = type_hash_table[hash]; dt; dt = dt->next )
-	{
-	  if( xtype != dt->type || dt->name == NULL 
-	      || dt->name[0] != typename[0])
-	    {
-	      continue;
-	    }
-	  	  
-	  if( strcmp(dt->name, typename) == 0 )
-	    {
-	      return dt;
-	    }
-	}
-    }
+  dt = DEBUG_LookupDataType(xtype, hash, typename);
 
   if( dt == NULL )
     {
@@ -347,6 +364,11 @@
   switch(addr->type->type)
     {
     case BASIC:
+      if (!DBG_CHECK_READ_PTR( addr,  addr->type->un.basic.basic_size)) 
+	{
+	  return 0;
+	}
+
       memcpy(&rtn, (char *) addr->off, addr->type->un.basic.basic_size);
       if(    (addr->type->un.basic.b_signed)
 	  && ((addr->type->un.basic.basic_size & 3) != 0)
@@ -495,6 +517,12 @@
 DEBUG_SetStructSize(struct datatype * dt, int size)
 {
   assert(dt->type == STRUCT);
+
+  if( dt->un.structure.members != NULL )
+    {
+      return FALSE;
+    }
+
   dt->un.structure.size = size;
   dt->un.structure.members = NULL;
 
@@ -710,7 +738,8 @@
  *
  * Implementation of the 'print' command.
  */
-void DEBUG_Print( const DBG_ADDR *addr, int count, char format, int level )
+void
+DEBUG_Print( const DBG_ADDR *addr, int count, char format, int level )
 {
   DBG_ADDR	  addr1;
   int		  i;
@@ -728,9 +757,20 @@
   if( addr->type == NULL )
     {
       fprintf(stderr, "Unable to evaluate expression\n");
-      return;
+      goto leave;
     }
   
+  if( level == 0 )
+    {
+      DEBUG_nchar = 0;
+    }
+
+  if( DEBUG_nchar > DEBUG_maxchar )
+    {
+      fprintf(stderr, "...");
+      goto leave;
+    }
+
   if( format == 'i' || format == 's' || format == 'w' || format == 'b' )
     {
       fprintf( stderr, "Format specifier '%c' is meaningless in 'print' command\n", format );
@@ -746,20 +786,25 @@
       DEBUG_PrintBasic(addr, 1, format);
       break;
     case STRUCT:
-      fprintf(stderr, "{");
+      DEBUG_nchar += fprintf(stderr, "{");
       for(m = addr->type->un.structure.members; m; m = m->next)
 	{
 	  addr1 = *addr;
 	  DEBUG_FindStructElement(&addr1, m->name,
 				  (int *) &value);
-	  fprintf(stderr, "%s=", m->name);
+	  DEBUG_nchar += fprintf(stderr, "%s=", m->name);
 	  DEBUG_Print(&addr1, 1, format, level + 1);
 	  if( m->next != NULL )
 	    {
-	      fprintf(stderr, ", ");
+	      DEBUG_nchar += fprintf(stderr, ", ");
+	    }
+	  if( DEBUG_nchar > DEBUG_maxchar )
+	    {
+	      fprintf(stderr, "...}");
+	      goto leave;
 	    }
 	}
-      fprintf(stderr, "}");
+      DEBUG_nchar += fprintf(stderr, "}");
       break;
     case ARRAY:
       /*
@@ -772,28 +817,39 @@
 	   * Special handling for character arrays.
 	   */
 	  pnt = (char *) addr->off;
-	  fprintf(stderr, "\"");
+	  DEBUG_nchar += fprintf(stderr, "\"");
 	  for( i=addr->type->un.array.start; i < addr->type->un.array.end; i++ )
 	    {
 	      fputc(*pnt++, stderr);
+	      DEBUG_nchar++;
+	      if( DEBUG_nchar > DEBUG_maxchar )
+		{
+		  fprintf(stderr, "...\"");
+		  goto leave;
+		}
 	    }
-	  fprintf(stderr, "\"");
+	  DEBUG_nchar += fprintf(stderr, "\"");
 	  break;
 	}
       addr1 = *addr;
       addr1.type = addr->type->un.array.basictype;
-      fprintf(stderr, "{");
+      DEBUG_nchar += fprintf(stderr, "{");
       for( i=addr->type->un.array.start; i <= addr->type->un.array.end; i++ )
 	{
 	  DEBUG_Print(&addr1, 1, format, level + 1);
 	  addr1.off += size;
 	  if( i == addr->type->un.array.end )
 	    {
-	      fprintf(stderr, "}");
+	      DEBUG_nchar += fprintf(stderr, "}");
 	    }
 	  else
 	    {
-	      fprintf(stderr, ", ");
+	      DEBUG_nchar += fprintf(stderr, ", ");
+	    }
+	  if( DEBUG_nchar > DEBUG_maxchar )
+	    {
+	      fprintf(stderr, "...}");
+	      goto leave;
 	    }
 	}
       break;
@@ -802,8 +858,157 @@
       break;
     }
 
+leave:
+
   if( level == 0 )
     {
-      fprintf(stderr, "\n");
+      DEBUG_nchar += fprintf(stderr, "\n");
     }
+  return;
 }
+
+int
+DEBUG_DumpTypes()
+{
+  struct datatype * dt = NULL;
+  struct member * m;
+  int hash;
+  int nm;
+  char * name;
+  char * member_name;
+
+  for(hash = 0; hash < NR_TYPE_HASH + 1; hash++)
+    {
+      for( dt = type_hash_table[hash]; dt; dt = dt->next )
+	{
+	  name =  "none";
+	  if( dt->name != NULL )
+	    {
+	      name = dt->name;
+	    }
+	  switch(dt->type)
+	    {
+	    case BASIC:
+	      fprintf(stderr, "0x%p - BASIC(%s)\n",
+		      dt, name);
+	      break;
+	    case POINTER:
+	      fprintf(stderr, "0x%p - POINTER(%s)(%p)\n",
+		      dt, name, dt->un.pointer.pointsto);
+	      break;
+	    case STRUCT:
+	      member_name = "none";
+	      nm = 0;
+	      if( dt->un.structure.members != NULL
+		  && dt->un.structure.members->name != NULL )
+		{
+		  member_name = dt->un.structure.members->name;
+		  for( m = dt->un.structure.members; m; m = m->next)
+		    {
+		      nm++;
+		    }
+		}
+	      fprintf(stderr, "0x%p - STRUCT(%s) %d %d %s\n", dt, name,
+		      dt->un.structure.size, nm, member_name);
+	      break;
+	    case ARRAY:
+	      fprintf(stderr, "0x%p - ARRAY(%s)(%p)\n",
+		      dt, name, dt->un.array.basictype);
+	      break;
+	    case ENUM:
+	      fprintf(stderr, "0x%p - ENUM(%s)\n",
+		      dt, name);
+	      break;
+	    case BITFIELD:
+	      fprintf(stderr, "0x%p - BITFIELD(%s)\n", dt, name);
+	      break;
+	    case FUNC:
+	      fprintf(stderr, "0x%p - FUNC(%s)(%p)\n",
+		      dt, name, dt->un.funct.rettype);
+	      break;
+	    case CONST:
+	    case TYPEDEF:
+	      fprintf(stderr, "What???\n");
+	      break;
+	    }
+	}
+    }
+  return TRUE;
+}
+
+
+enum debug_type DEBUG_GetType(struct datatype * dt)
+{
+  return dt->type;
+}
+
+struct datatype *
+DEBUG_TypeCast(enum debug_type type, const char * name)
+{
+  int			  hash;
+  struct datatype	* rtn;
+
+  /*
+   * The last bucket is special, and is used to hold typeless names.
+   */
+  if( name == NULL )
+    {
+      hash = NR_TYPE_HASH;
+    }
+  else
+    {
+      hash = type_hash(name);
+    }
+
+  rtn = DEBUG_LookupDataType(type, hash, name);
+
+  return rtn;
+
+}
+
+int
+DEBUG_PrintTypeCast(struct datatype * dt)
+{
+  char		* name;
+
+  name =  "none";
+  if( dt->name != NULL )
+    {
+      name = dt->name;
+    }
+
+  switch(dt->type)
+    {
+    case BASIC:
+      fprintf(stderr, "%s", name);
+      break;
+    case POINTER:
+      DEBUG_PrintTypeCast(dt->un.pointer.pointsto);
+      fprintf(stderr, "*");
+      break;
+    case STRUCT:
+      fprintf(stderr, "struct %s", name);
+      break;
+    case ARRAY:
+      fprintf(stderr, "%s[]", name);
+      break;
+    case ENUM:
+      fprintf(stderr, "enum %s", name);
+      break;
+    case BITFIELD:
+      fprintf(stderr, "unsigned %s", name);
+      break;
+    case FUNC:
+      DEBUG_PrintTypeCast(dt->un.funct.rettype);
+      fprintf(stderr, "(*%s)()", name);
+      break;
+    case CONST:
+    case TYPEDEF:
+      fprintf(stderr, "What???\n");
+      break;
+    }
+
+  return TRUE;
+}
+
+