wrc: Load translations from mo files instead of po.
diff --git a/Make.rules.in b/Make.rules.in
index 993d47e..7c4a65c 100644
--- a/Make.rules.in
+++ b/Make.rules.in
@@ -17,7 +17,7 @@
 ALLCFLAGS    = $(INCLUDES) $(DEFS) $(DLLFLAGS) $(EXTRACFLAGS) $(CPPFLAGS) $(CFLAGS) $(MODCFLAGS)
 ALLLINTFLAGS = $(INCLUDES) $(DEFS) $(LINTFLAGS)
 IDLFLAGS     = $(INCLUDES) $(DEFS) $(EXTRAIDLFLAGS)
-RCFLAGS      = --nostdinc --po-dir=$(top_srcdir)/po $(TARGETFLAGS) $(INCLUDES) $(DEFS) $(EXTRARCFLAGS)
+RCFLAGS      = --nostdinc $(PORCFLAGS) $(TARGETFLAGS) $(INCLUDES) $(DEFS) $(EXTRARCFLAGS)
 
 IDL_GEN_C_SRCS  = $(IDL_C_SRCS:.idl=_c.c) $(IDL_I_SRCS:.idl=_i.c) \
                   $(IDL_P_SRCS:.idl=_p.c) $(IDL_S_SRCS:.idl=_s.c)
@@ -189,9 +189,9 @@
 msg.pot: $(WMC)
 	$(LDPATH) $(WMC) -O pot -o $@ $(MC_SRCS)
 
-$(MC_SRCS:.mc=.res): $(WMC) $(ALL_PO_FILES)
+$(MC_SRCS:.mc=.res): $(WMC) $(ALL_MO_FILES)
 $(RC_SRCS:.rc=.res): $(WRC)
-$(PO_SRCS:.rc=.res): $(ALL_PO_FILES)
+$(PO_SRCS:.rc=.res): $(ALL_MO_FILES)
 
 # Misc. rules
 
diff --git a/Make.vars.in b/Make.vars.in
index d082d98..100594b 100644
--- a/Make.vars.in
+++ b/Make.vars.in
@@ -53,8 +53,8 @@
 MSGFMT          = @MSGFMT@
 CROSSTARGET     = @CROSSTARGET@
 LINGUAS         = @LINGUAS@
-ALL_PO_FILES    = $(LINGUAS:%=@top_srcdir@/po/%.po)
 ALL_MO_FILES    = $(LINGUAS:%=@top_builddir@/po/%.mo)
+PORCFLAGS       = @PORCFLAGS@
 CROSSAR         = $(CROSSTARGET)-ar
 CROSSRANLIB     = $(CROSSTARGET)-ranlib
 MKINSTALLDIRS   = $(top_srcdir)/tools/mkinstalldirs -m 755
diff --git a/configure b/configure
index 9bf8db6..37d8cba 100755
--- a/configure
+++ b/configure
@@ -604,6 +604,7 @@
 
 ac_subst_vars='LTLIBOBJS
 LIBOBJS
+PORCFLAGS
 LINGUAS
 ALL_TEST_RESOURCES
 LDAPLIBS
@@ -15432,7 +15433,7 @@
 	@echo timestamp > \$@
 
 ALL_POT_FILES =$ALL_POT_FILES
-\$(ALL_PO_FILES): \$(srcdir)/po/wine.pot
+\$(LINGUAS:%=$srcdir/po/%.po): \$(srcdir)/po/wine.pot
 	msgmerge -q \$@ \$(srcdir)/po/wine.pot | msgattrib --no-obsolete -o \$@.new && mv \$@.new \$@
 \$(srcdir)/po/wine.pot: \$(ALL_POT_FILES)
 	msgcat -o \$@ \$(ALL_POT_FILES)"
@@ -15440,7 +15441,11 @@
 
 if test "$MSGFMT" != false
 then
+    PORCFLAGS="--po-dir=\$(top_builddir)/po"
+
     wine_fn_append_rule ALL_MAKEFILE_DEPENDS "__builddeps__: \$(ALL_MO_FILES)"
+else
+    LINGUAS=
 fi
 
 if test "x$enable_tools" != xno
diff --git a/configure.ac b/configure.ac
index 67bf4a5..4b1f718 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3066,7 +3066,7 @@
 	@echo timestamp > \$[@]
 
 ALL_POT_FILES =$ALL_POT_FILES
-\$(ALL_PO_FILES): \$(srcdir)/po/wine.pot
+\$(LINGUAS:%=$srcdir/po/%.po): \$(srcdir)/po/wine.pot
 	msgmerge -q \$[@] \$(srcdir)/po/wine.pot | msgattrib --no-obsolete -o \$[@].new && mv \$[@].new \$[@]
 \$(srcdir)/po/wine.pot: \$(ALL_POT_FILES)
 	msgcat -o \$[@] \$(ALL_POT_FILES)])
@@ -3074,7 +3074,10 @@
 
 if test "$MSGFMT" != false
 then
+    AC_SUBST([PORCFLAGS],["--po-dir=\$(top_builddir)/po"])
     WINE_APPEND_RULE([ALL_MAKEFILE_DEPENDS],[__builddeps__: \$(ALL_MO_FILES)])
+else
+    LINGUAS=
 fi
 
 if test "x$enable_tools" != xno
diff --git a/tools/wrc/po.c b/tools/wrc/po.c
index fd55ba4..9cb2b42 100644
--- a/tools/wrc/po.c
+++ b/tools/wrc/po.c
@@ -19,6 +19,7 @@
  */
 
 #include "config.h"
+#include "wine/port.h"
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -43,6 +44,16 @@
 
 static resource_t *new_top, *new_tail;
 
+struct mo_file
+{
+    unsigned int magic;
+    unsigned int revision;
+    unsigned int count;
+    unsigned int msgid_off;
+    unsigned int msgstr_off;
+    /* ... rest of file data here */
+};
+
 static int is_english( const language_t *lan )
 {
     return lan->id == LANG_ENGLISH && lan->sub == SUBLANG_DEFAULT;
@@ -393,20 +404,6 @@
 
 #ifndef HAVE_LIBGETTEXTPO
 
-static const char *get_msgstr( const char *msgid, const char *context, int *found )
-{
-    if (context) (*found)++;
-    return msgid;
-}
-
-static void load_po_file( const char *name )
-{
-}
-
-static void free_po_file(void)
-{
-}
-
 void write_pot_file( const char *outname )
 {
     error( "PO files not supported in this wrc build\n" );
@@ -419,8 +416,6 @@
 
 #else  /* HAVE_LIBGETTEXTPO */
 
-static po_file_t po_file;
-
 static void po_xerror( int severity, po_message_t message,
                        const char *filename, size_t lineno, size_t column,
                        int multiline_p, const char *message_text )
@@ -473,35 +468,6 @@
     return msg;
 }
 
-static const char *get_msgstr( const char *msgid, const char *context, int *found )
-{
-    const char *ret = msgid;
-    po_message_t msg;
-    po_message_iterator_t iterator;
-
-    msg = find_message( po_file, msgid, context, &iterator );
-    if (msg && !po_message_is_fuzzy( msg ))
-    {
-        ret = po_message_msgstr( msg );
-        if (!ret[0]) ret = msgid;  /* ignore empty strings */
-        else (*found)++;
-    }
-    po_message_iterator_free( iterator );
-    return ret;
-}
-
-static void load_po_file( const char *name )
-{
-    if (!(po_file = po_file_read( name, &po_xerror_handler )))
-        error( "cannot load po file '%s'\n", name );
-}
-
-static void free_po_file(void)
-{
-    po_file_free( po_file );
-    po_file = NULL;
-}
-
 static void add_po_string( po_file_t po, const string_t *msgid, const string_t *msgstr,
                            const language_t *lang )
 {
@@ -820,6 +786,108 @@
 
 #endif  /* HAVE_LIBGETTEXTPO */
 
+static struct mo_file *mo_file;
+
+static void byteswap( unsigned int *data, unsigned int count )
+{
+    unsigned int i;
+
+    for (i = 0; i < count; i++)
+        data[i] = data[i] >> 24 | (data[i] >> 8 & 0xff00) | (data[i] << 8 & 0xff0000) | data[i] << 24;
+}
+
+static void load_mo_file( const char *name )
+{
+    struct stat st;
+    int res, fd;
+
+    fd = open( name, O_RDONLY | O_BINARY );
+    if (fd == -1) fatal_perror( "Failed to open %s", name );
+    fstat( fd, &st );
+    mo_file = xmalloc( st.st_size );
+    res = read( fd, mo_file, st.st_size );
+    if (res == -1) fatal_perror( "Failed to read %s", name );
+    else if (res != st.st_size) error( "Failed to read %s\n", name );
+    close( fd );
+
+    /* sanity checks */
+
+    if (st.st_size < sizeof(*mo_file))
+        error( "%s is not a valid .mo file\n", name );
+    if (mo_file->magic == 0xde120495)
+        byteswap( &mo_file->revision, 4 );
+    else if (mo_file->magic != 0x950412de)
+        error( "%s is not a valid .mo file\n", name );
+    if ((mo_file->revision >> 16) > 1)
+        error( "%s: unsupported file version %x\n", name, mo_file->revision );
+    if (mo_file->msgid_off >= st.st_size ||
+        mo_file->msgstr_off >= st.st_size ||
+        st.st_size < sizeof(*mo_file) + 2 * 8 * mo_file->count)
+        error( "%s: corrupted file\n", name );
+
+    if (mo_file->magic == 0xde120495)
+    {
+        byteswap( (unsigned int *)((char *)mo_file + mo_file->msgid_off), 2 * mo_file->count );
+        byteswap( (unsigned int *)((char *)mo_file + mo_file->msgstr_off), 2 * mo_file->count );
+    }
+}
+
+static void free_mo_file(void)
+{
+    free( mo_file );
+    mo_file = NULL;
+}
+
+static inline const char *get_mo_msgid( int index )
+{
+    const char *base = (const char *)mo_file;
+    const unsigned int *offsets = (const unsigned int *)(base + mo_file->msgid_off);
+    return base + offsets[2 * index + 1];
+}
+
+static inline const char *get_mo_msgstr( int index )
+{
+    const char *base = (const char *)mo_file;
+    const unsigned int *offsets = (const unsigned int *)(base + mo_file->msgstr_off);
+    return base + offsets[2 * index + 1];
+}
+
+static const char *get_msgstr( const char *msgid, const char *context, int *found )
+{
+    int pos, res, min, max;
+    const char *ret = msgid;
+    char *id = NULL;
+
+    if (!mo_file)  /* strings containing a context still need to be transformed */
+    {
+        if (context) (*found)++;
+        return ret;
+    }
+
+    if (context) id = strmake( "%s%c%s", context, 4, msgid );
+    min = 0;
+    max = mo_file->count - 1;
+    while (min <= max)
+    {
+        pos = (min + max) / 2;
+        res = strcmp( get_mo_msgid(pos), msgid );
+        if (!res)
+        {
+            const char *str = get_mo_msgstr( pos );
+            if (str[0])  /* ignore empty strings */
+            {
+                ret = str;
+                (*found)++;
+            }
+            break;
+        }
+        if (res > 0) max = pos - 1;
+        else min = pos + 1;
+    }
+    free( id );
+    return ret;
+}
+
 static string_t *translate_string( string_t *str, int *found )
 {
     string_t *new;
@@ -988,6 +1056,12 @@
     for (res = resource_top; res; res = res->next) if (is_english( res->lan )) break;
     if (!res) return;
 
+    if (!po_dir)  /* run through the translation process to remove msg contexts */
+    {
+        translate_resources( new_language( LANG_ENGLISH, SUBLANG_DEFAULT ));
+        goto done;
+    }
+
     new_top = new_tail = NULL;
 
     name = strmake( "%s/LINGUAS", po_dir );
@@ -1008,15 +1082,16 @@
             if (i == sizeof(languages)/sizeof(languages[0]))
                 error( "unknown language '%s'\n", tok );
 
-            name = strmake( "%s/%s.po", po_dir, tok );
-            load_po_file( name );
+            name = strmake( "%s/%s.mo", po_dir, tok );
+            load_mo_file( name );
             translate_resources( new_language(languages[i].id, languages[i].sub) );
-            free_po_file();
+            free_mo_file();
             free( name );
         }
     }
     fclose( f );
 
+done:
     /* prepend the translated resources to the global list */
     if (new_tail)
     {
diff --git a/tools/wrc/wrc.c b/tools/wrc/wrc.c
index 2eb5380..7d5ad89 100644
--- a/tools/wrc/wrc.c
+++ b/tools/wrc/wrc.c
@@ -562,7 +562,7 @@
             output_name = NULL;
             exit(0);
 	}
-        if (po_dir) add_translations( po_dir );
+        add_translations( po_dir );
 
 	/* Convert the internal lists to binary data */
 	resources2res(resource_top);
diff --git a/tools/wrc/wrc.man.in b/tools/wrc/wrc.man.in
index cfdf800..ed1fd82 100644
--- a/tools/wrc/wrc.man.in
+++ b/tools/wrc/wrc.man.in
@@ -108,9 +108,9 @@
 be discovered with this option.
 .TP
 .I \fB\-\-po-dir=\fIdir\fR
-Enable the generation of resource translations based on po files
+Enable the generation of resource translations based on mo files
 loaded from the specified directory. That directory must follow the
-gettext convention, in particular in must contain one .po file for
+gettext convention, in particular in must contain one .mo file for
 each language, and a LINGUAS file listing the available languages.
 .TP
 .I \fB\-r\fR