Sync with trunk r62529.
authorDavid Quintana <gigaherz@gmail.com>
Tue, 18 Mar 2014 14:39:04 +0000 (14:39 +0000)
committerDavid Quintana <gigaherz@gmail.com>
Tue, 18 Mar 2014 14:39:04 +0000 (14:39 +0000)
svn path=/branches/shell-experiments/; revision=62530

33 files changed:
base/applications/cmdutils/CMakeLists.txt
base/applications/cmdutils/doskey/doskey.rc
base/applications/cmdutils/find/find.rc
base/applications/cmdutils/mode/CMakeLists.txt [new file with mode: 0644]
base/applications/cmdutils/mode/mode.c [new file with mode: 0644]
base/applications/cmdutils/mode/mode.rc [new file with mode: 0644]
base/applications/cmdutils/more/CMakeLists.txt
base/applications/cmdutils/more/more.rc
base/applications/cmdutils/xcopy/rsrc.rc
base/shell/cmd/lang/es-ES.rc
base/shell/cmd/lang/fr-FR.rc
base/shell/cmd/lang/hu-HU.rc
base/shell/cmd/lang/id-ID.rc
base/shell/cmd/lang/it-IT.rc
base/shell/cmd/lang/no-NO.rc
base/shell/cmd/lang/pl-PL.rc
base/shell/cmd/lang/ru-RU.rc
base/shell/cmd/lang/sv-SE.rc
cmake/msvc.cmake
dll/win32/msv1_0/msv1_0.c
drivers/input/i8042prt/pnp.c
drivers/usb/usbd/usbd.c
ntoskrnl/io/pnpmgr/pnpmgr.c
win32ss/user/ntuser/menu.c
win32ss/user/ntuser/window.c
win32ss/user/user32/windows/menu.c
win32ss/user/winsrv/consrv/condrv/graphics.c
win32ss/user/winsrv/consrv/condrv/text.c
win32ss/user/winsrv/consrv/frontends/gui/graphics.c
win32ss/user/winsrv/consrv/frontends/gui/guisettings.h
win32ss/user/winsrv/consrv/frontends/gui/guiterm.c
win32ss/user/winsrv/consrv/frontends/gui/text.c
win32ss/user/winsrv/consrv/settings.c

index a64f6ad..a559623 100644 (file)
@@ -4,6 +4,7 @@ add_subdirectory(find)
 add_subdirectory(help)
 add_subdirectory(hostname)
 add_subdirectory(lodctr)
+add_subdirectory(mode)
 add_subdirectory(more)
 add_subdirectory(reg)
 add_subdirectory(taskkill)
index c302f55..52e969b 100644 (file)
@@ -2,7 +2,7 @@
 
 #include "doskey.h"
 
-#define REACTOS_STR_FILE_DESCRIPTION  "W32 doskey command"
+#define REACTOS_STR_FILE_DESCRIPTION  "ReactOS Doskey Command"
 #define REACTOS_STR_INTERNAL_NAME     "doskey"
 #define REACTOS_STR_ORIGINAL_FILENAME "doskey.exe"
 #include <reactos/version.rc>
index ae1c505..5c05433 100644 (file)
@@ -2,7 +2,7 @@
 
 #include "resource.h"
 
-#define REACTOS_STR_FILE_DESCRIPTION  "W32 find command"
+#define REACTOS_STR_FILE_DESCRIPTION  "ReactOS Find Command"
 #define REACTOS_STR_INTERNAL_NAME     "find"
 #define REACTOS_STR_ORIGINAL_FILENAME "find.exe"
 #include <reactos/version.rc>
diff --git a/base/applications/cmdutils/mode/CMakeLists.txt b/base/applications/cmdutils/mode/CMakeLists.txt
new file mode 100644 (file)
index 0000000..354c426
--- /dev/null
@@ -0,0 +1,7 @@
+
+add_executable(mode mode.c mode.rc)
+set_module_type(mode win32cui UNICODE)
+set_target_properties(mode PROPERTIES SUFFIX ".com")
+
+add_importlibs(mode user32 msvcrt kernel32)
+add_cd_file(TARGET mode DESTINATION reactos/system32 FOR all)
diff --git a/base/applications/cmdutils/mode/mode.c b/base/applications/cmdutils/mode/mode.c
new file mode 100644 (file)
index 0000000..aa49431
--- /dev/null
@@ -0,0 +1,551 @@
+/*
+ *  ReactOS mode console command
+ *
+ *  mode.c
+ *
+ *  Copyright (C) 2002  Robert Dickenson <robd@reactos.org>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <windows.h>
+#include <stdio.h>
+
+#define MAX_PORTNAME_LEN 20
+#define MAX_COMPORT_NUM  10
+#define MAX_COMPARAM_LEN 20
+
+#define NUM_ELEMENTS(a) (sizeof(a)/sizeof(a[0]))
+#define ASSERT(a)
+
+const WCHAR* const usage_strings[] =
+{
+    L"Device Status:     MODE [device] [/STATUS]",
+    L"Select code page:  MODE CON[:] CP SELECT=yyy",
+    L"Code page status:  MODE CON[:] CP [/STATUS]",
+    L"Display mode:      MODE CON[:] [COLS=c] [LINES=n]",
+    L"Typematic rate:    MODE CON[:] [RATE=r DELAY=d]",
+    L"Redirect printing: MODE LPTn[:]=COMm[:]",
+    L"Serial port:       MODE COMm[:] [BAUD=b] [PARITY=p] [DATA=d] [STOP=s]\n" \
+    L"                            [to=on|off] [xon=on|off] [odsr=on|off]\n"    \
+    L"                            [octs=on|off] [dtr=on|off|hs]\n"             \
+    L"                            [rts=on|off|hs|tg] [idsr=on|off]",
+};
+
+const WCHAR* const parity_strings[] =
+{
+    L"None",    // default
+    L"Odd",     // only symbol in this set to have a 'd' in it
+    L"Even",    // ... 'v' in it
+    L"Mark",    // ... 'm' in it
+    L"Space"    // ... 's' and/or a 'c' in it
+};
+
+const WCHAR* const control_strings[] = { L"OFF", L"ON", L"HANDSHAKE", L"TOGGLE" };
+
+const WCHAR* const stopbit_strings[] = { L"1", L"1.5", L"2" };
+
+
+int Usage()
+{
+    int i;
+
+    wprintf(L"\nConfigures system devices.\n\n");
+    for (i = 0; i < NUM_ELEMENTS(usage_strings); i++)
+    {
+        wprintf(L"%s\n", usage_strings[i]);
+    }
+    wprintf(L"\n");
+    return 0;
+}
+
+int QueryDevices()
+{
+    WCHAR buffer[20240];
+    int len;
+    WCHAR* ptr = buffer;
+
+    *ptr = L'\0';
+    if (QueryDosDeviceW(NULL, buffer, NUM_ELEMENTS(buffer)))
+    {
+        while (*ptr != L'\0')
+        {
+            len = wcslen(ptr);
+            if (wcsstr(ptr, L"COM"))
+            {
+                wprintf(L"    Found serial device - %s\n", ptr);
+            }
+            else if (wcsstr(ptr, L"PRN"))
+            {
+                wprintf(L"    Found printer device - %s\n", ptr);
+            }
+            else if (wcsstr(ptr, L"LPT"))
+            {
+                wprintf(L"    Found parallel device - %s\n", ptr);
+            }
+            else
+            {
+                // wprintf(L"    Found other device - %s\n", ptr);
+            }
+            ptr += (len+1);
+        }
+    }
+    else
+    {
+        wprintf(L"    ERROR: QueryDosDeviceW(...) failed: 0x%lx\n", GetLastError());
+    }
+    return 1;
+}
+
+int ShowParallelStatus(int nPortNum)
+{
+    WCHAR buffer[250];
+    WCHAR szPortName[MAX_PORTNAME_LEN];
+
+    swprintf(szPortName, L"LPT%d", nPortNum);
+    wprintf(L"\nStatus for device LPT%d:\n", nPortNum);
+    wprintf(L"-----------------------\n");
+    if (QueryDosDeviceW(szPortName, buffer, NUM_ELEMENTS(buffer)))
+    {
+        WCHAR* ptr = wcsrchr(buffer, L'\\');
+        if (ptr != NULL)
+        {
+            if (0 == wcscmp(szPortName, ++ptr))
+            {
+                wprintf(L"    Printer output is not being rerouted.\n");
+            }
+            else
+            {
+                wprintf(L"    Printer output is being rerouted to serial port %s\n", ptr);
+            }
+            return 0;
+        }
+        else
+        {
+            wprintf(L"    QueryDosDeviceW(%s) returned unrecognised form %s.\n", szPortName, buffer);
+        }
+    }
+    else
+    {
+        wprintf(L"    ERROR: QueryDosDeviceW(%s) failed: 0x%lx\n", szPortName, GetLastError());
+    }
+    return 1;
+}
+
+int ShowConsoleStatus()
+{
+    DWORD dwKbdDelay;
+    DWORD dwKbdSpeed;
+    CONSOLE_SCREEN_BUFFER_INFO ConsoleScreenBufferInfo;
+    HANDLE hConsoleOutput = GetStdHandle(STD_OUTPUT_HANDLE);
+
+    wprintf(L"\nStatus for device CON:\n");
+    wprintf(L"-----------------------\n");
+    if (GetConsoleScreenBufferInfo(hConsoleOutput, &ConsoleScreenBufferInfo))
+    {
+        wprintf(L"    Lines:          %d\n", ConsoleScreenBufferInfo.dwSize.Y);
+        wprintf(L"    Columns:        %d\n", ConsoleScreenBufferInfo.dwSize.X);
+    }
+    if (SystemParametersInfo(SPI_GETKEYBOARDDELAY, 0, &dwKbdDelay, 0))
+    {
+        wprintf(L"    Keyboard delay: %ld\n", dwKbdDelay);
+    }
+    if (SystemParametersInfo(SPI_GETKEYBOARDSPEED, 0, &dwKbdSpeed, 0))
+    {
+        wprintf(L"    Keyboard rate:  %ld\n", dwKbdSpeed);
+    }
+    wprintf(L"    Code page:      %d\n", GetConsoleOutputCP());
+    return 0;
+}
+
+static
+BOOL SerialPortQuery(int nPortNum, LPDCB pDCB, LPCOMMTIMEOUTS pCommTimeouts, BOOL bWrite)
+{
+    BOOL result;
+    HANDLE hPort;
+    WCHAR szPortName[MAX_PORTNAME_LEN];
+
+    ASSERT(pDCB);
+    ASSERT(pCommTimeouts);
+
+    swprintf(szPortName, L"COM%d", nPortNum);
+    hPort = CreateFileW(szPortName,
+                        GENERIC_READ | GENERIC_WRITE,
+                        0,     // exclusive
+                        NULL,  // sec attr
+                        OPEN_EXISTING,
+                        0,     // no attributes
+                        NULL); // no template
+
+    if (hPort == INVALID_HANDLE_VALUE)
+    {
+        wprintf(L"Illegal device name - %s\n", szPortName);
+        wprintf(L"Last error = 0x%lx\n", GetLastError());
+        return FALSE;
+    }
+
+    result = bWrite ? SetCommState(hPort, pDCB)
+                    : GetCommState(hPort, pDCB);
+    if (!result)
+    {
+        wprintf(L"Failed to %s the status for device COM%d:\n", bWrite ? L"set" : L"get", nPortNum);
+        CloseHandle(hPort);
+        return FALSE;
+    }
+
+    result = bWrite ? SetCommTimeouts(hPort, pCommTimeouts)
+                    : GetCommTimeouts(hPort, pCommTimeouts);
+    if (!result)
+    {
+        wprintf(L"Failed to %s Timeout status for device COM%d:\n", bWrite ? L"set" : L"get", nPortNum);
+        CloseHandle(hPort);
+        return FALSE;
+    }
+    CloseHandle(hPort);
+    return TRUE;
+}
+
+int ShowSerialStatus(int nPortNum)
+{
+    DCB dcb;
+    COMMTIMEOUTS CommTimeouts;
+
+    if (!SerialPortQuery(nPortNum, &dcb, &CommTimeouts, FALSE))
+    {
+        return 1;
+    }
+    if (dcb.Parity > NUM_ELEMENTS(parity_strings))
+    {
+        wprintf(L"ERROR: Invalid value for Parity Bits %d:\n", dcb.Parity);
+        dcb.Parity = 0;
+    }
+    if (dcb.StopBits > NUM_ELEMENTS(stopbit_strings))
+    {
+        wprintf(L"ERROR: Invalid value for Stop Bits %d:\n", dcb.StopBits);
+        dcb.StopBits = 0;
+    }
+    wprintf(L"\nStatus for device COM%d:\n", nPortNum);
+    wprintf(L"-----------------------\n");
+    wprintf(L"    Baud:            %ld\n", dcb.BaudRate);
+    wprintf(L"    Parity:          %s\n", parity_strings[dcb.Parity]);
+    wprintf(L"    Data Bits:       %d\n", dcb.ByteSize);
+    wprintf(L"    Stop Bits:       %s\n", stopbit_strings[dcb.StopBits]);
+    wprintf(L"    Timeout:         %s\n", CommTimeouts.ReadIntervalTimeout ? L"ON" : L"OFF");
+    wprintf(L"    XON/XOFF:        %s\n", dcb.fOutX           ? L"ON" : L"OFF");
+    wprintf(L"    CTS handshaking: %s\n", dcb.fOutxCtsFlow    ? L"ON" : L"OFF");
+    wprintf(L"    DSR handshaking: %s\n", dcb.fOutxDsrFlow    ? L"ON" : L"OFF");
+    wprintf(L"    DSR sensitivity: %s\n", dcb.fDsrSensitivity ? L"ON" : L"OFF");
+    wprintf(L"    DTR circuit:     %s\n", control_strings[dcb.fDtrControl]);
+    wprintf(L"    RTS circuit:     %s\n", control_strings[dcb.fRtsControl]);
+    return 0;
+}
+
+int SetParallelState(int nPortNum)
+{
+    WCHAR szPortName[MAX_PORTNAME_LEN];
+    WCHAR szTargetPath[MAX_PORTNAME_LEN];
+
+    swprintf(szPortName, L"LPT%d", nPortNum);
+    swprintf(szTargetPath, L"COM%d", nPortNum);
+    if (!DefineDosDeviceW(DDD_REMOVE_DEFINITION, szPortName, szTargetPath))
+    {
+        wprintf(L"SetParallelState(%d) - DefineDosDevice(%s) failed: 0x%lx\n", nPortNum, szPortName, GetLastError());
+    }
+    return 0;
+}
+
+/*
+    \??\COM1
+    \Device\NamedPipe\Spooler\LPT1
+BOOL DefineDosDevice(
+  DWORD dwFlags,         // options
+  LPCTSTR lpDeviceName,  // device name
+  LPCTSTR lpTargetPath   // path string
+);
+DWORD QueryDosDevice(
+  LPCTSTR lpDeviceName, // MS-DOS device name string
+  LPTSTR lpTargetPath,  // query results buffer
+  DWORD ucchMax         // maximum size of buffer
+);
+ */
+
+int SetConsoleState()
+{
+/*
+    "Select code page:  MODE CON[:] CP SELECT=yyy",
+    "Code page status:  MODE CON[:] CP [/STATUS]",
+    "Display mode:      MODE CON[:] [COLS=c] [LINES=n]",
+    "Typematic rate:    MODE CON[:] [RATE=r DELAY=d]",
+ */
+    return 0;
+}
+
+static
+int ExtractModeSerialParams(const WCHAR* param)
+{
+    if (wcsstr(param, L"OFF"))
+        return 0;
+    else if (wcsstr(param, L"ON"))
+        return 1;
+    else if (wcsstr(param, L"HS"))
+        return 2;
+    else if (wcsstr(param, L"TG"))
+        return 3;
+
+    return -1;
+}
+
+int SetSerialState(int nPortNum, int args, WCHAR *argv[])
+{
+    int arg;
+    int value;
+    DCB dcb;
+    COMMTIMEOUTS CommTimeouts;
+    WCHAR buf[MAX_COMPARAM_LEN+1];
+
+    if (SerialPortQuery(nPortNum, &dcb, &CommTimeouts, FALSE))
+    {
+        for (arg = 2; arg < args; arg++)
+        {
+            if (wcslen(argv[arg]) > MAX_COMPARAM_LEN)
+            {
+                wprintf(L"Invalid parameter (too long) - %s\n", argv[arg]);
+                return 1;
+            }
+            wcscpy(buf, argv[arg]);
+            _wcslwr(buf);
+            if (wcsstr(buf, L"baud="))
+            {
+                wscanf(buf+5, L"%lu", &dcb.BaudRate);
+            }
+            else if (wcsstr(buf, L"parity="))
+            {
+                if (wcschr(buf, L'D'))
+                    dcb.Parity = 1;
+                else if (wcschr(buf, L'V'))
+                    dcb.Parity = 2;
+                else if (wcschr(buf, L'M'))
+                    dcb.Parity = 3;
+                else if (wcschr(buf, L'S'))
+                    dcb.Parity = 4;
+                else
+                    dcb.Parity = 0;
+            }
+            else if (wcsstr(buf, L"data="))
+            {
+                wscanf(buf+5, L"%lu", &dcb.ByteSize);
+            }
+            else if (wcsstr(buf, L"stop="))
+            {
+                if (wcschr(buf, L'5'))
+                    dcb.StopBits = 1;
+                else if (wcschr(buf, L'2'))
+                    dcb.StopBits = 2;
+                else
+                    dcb.StopBits = 0;
+            }
+            else if (wcsstr(buf, L"to=")) // to=on|off
+            {
+                value = ExtractModeSerialParams(buf);
+                if (value != -1)
+                {
+                }
+                else
+                {
+                    goto invalid_serial_parameter;
+                }
+            }
+            else if (wcsstr(buf, L"xon=")) // xon=on|off
+            {
+                value = ExtractModeSerialParams(buf);
+                if (value != -1)
+                {
+                    dcb.fOutX = value;
+                    dcb.fInX = value;
+                }
+                else
+                {
+                    goto invalid_serial_parameter;
+                }
+            }
+            else if (wcsstr(buf, L"odsr=")) // odsr=on|off
+            {
+                value = ExtractModeSerialParams(buf);
+                if (value != -1)
+                {
+                    dcb.fOutxDsrFlow = value;
+                }
+                else
+                {
+                    goto invalid_serial_parameter;
+                }
+            }
+            else if (wcsstr(buf, L"octs=")) // octs=on|off
+            {
+                value = ExtractModeSerialParams(buf);
+                if (value != -1)
+                {
+                    dcb.fOutxCtsFlow = value;
+                }
+                else
+                {
+                    goto invalid_serial_parameter;
+                }
+            }
+            else if (wcsstr(buf, L"dtr=")) // dtr=on|off|hs
+            {
+                value = ExtractModeSerialParams(buf);
+                if (value != -1)
+                {
+                    dcb.fDtrControl = value;
+                }
+                else
+                {
+                    goto invalid_serial_parameter;
+                }
+            }
+            else if (wcsstr(buf, L"rts=")) // rts=on|off|hs|tg
+            {
+                value = ExtractModeSerialParams(buf);
+                if (value != -1)
+                {
+                    dcb.fRtsControl = value;
+                }
+                else
+                {
+                    goto invalid_serial_parameter;
+                }
+            }
+            else if (wcsstr(buf, L"idsr=")) // idsr=on|off
+            {
+                value = ExtractModeSerialParams(buf);
+                if (value != -1)
+                {
+                    dcb.fDsrSensitivity = value;
+                }
+                else
+                {
+                    goto invalid_serial_parameter;
+                }
+            }
+            else
+            {
+invalid_serial_parameter:;
+                wprintf(L"Invalid parameter - %s\n", buf);
+                return 1;
+            }
+        }
+        SerialPortQuery(nPortNum, &dcb, &CommTimeouts, TRUE);
+    }
+    return 0;
+}
+
+int find_portnum(const WCHAR* cmdverb)
+{
+    int portnum = -1;
+
+    if (cmdverb[3] >= L'0' && cmdverb[3] <= L'9')
+    {
+        portnum = cmdverb[3] - L'0';
+        if (cmdverb[4] >= L'0' && cmdverb[4] <= L'9')
+        {
+            portnum *= 10;
+            portnum += cmdverb[4] - L'0';
+        }
+    }
+    return portnum;
+}
+
+int wmain(int argc, WCHAR* argv[])
+{
+    int nPortNum;
+    WCHAR param1[MAX_COMPARAM_LEN+1];
+    WCHAR param2[MAX_COMPARAM_LEN+1];
+
+    if (argc > 1)
+    {
+        if (wcslen(argv[1]) > MAX_COMPARAM_LEN)
+        {
+            wprintf(L"Invalid parameter (too long) - %s\n", argv[1]);
+            return 1;
+        }
+        wcscpy(param1, argv[1]);
+        _wcslwr(param1);
+        if (argc > 2)
+        {
+            if (wcslen(argv[2]) > MAX_COMPARAM_LEN)
+            {
+                wprintf(L"Invalid parameter (too long) - %s\n", argv[2]);
+                return 1;
+            }
+            wcscpy(param2, argv[2]);
+            _wcslwr(param2);
+        }
+        else
+        {
+            param2[0] = L'\0';
+        }
+        if (wcsstr(param1, L"/?") || wcsstr(param1, L"-?"))
+        {
+            return Usage();
+        }
+        else if (wcsstr(param1, L"/status"))
+        {
+            goto show_status;
+        }
+        else if (wcsstr(param1, L"lpt"))
+        {
+            nPortNum = find_portnum(param1);
+            if (nPortNum != -1)
+                return ShowParallelStatus(nPortNum);
+        }
+        else if (wcsstr(param1, L"con"))
+        {
+            return ShowConsoleStatus();
+        }
+        else if (wcsstr(param1, L"com"))
+        {
+            nPortNum = find_portnum(param1);
+            if (nPortNum != -1)
+            {
+                if (param2[0] == L'\0' || wcsstr(param2, L"/status"))
+                {
+                    return ShowSerialStatus(nPortNum);
+                }
+                else
+                {
+                    return SetSerialState(nPortNum, argc, argv);
+                }
+            }
+        }
+        wprintf(L"Invalid parameter - %s\n", param1);
+        return 1;
+    }
+    else
+    {
+show_status:;
+
+        QueryDevices();
+/*
+        ShowParallelStatus(1);
+        for (nPortNum = 0; nPortNum < MAX_COMPORT_NUM; nPortNum++)
+        {
+            ShowSerialStatus(nPortNum + 1);
+        }
+        ShowConsoleStatus();
+ */
+    }
+    return 0;
+}
diff --git a/base/applications/cmdutils/mode/mode.rc b/base/applications/cmdutils/mode/mode.rc
new file mode 100644 (file)
index 0000000..33c5a85
--- /dev/null
@@ -0,0 +1,5 @@
+
+#define REACTOS_STR_FILE_DESCRIPTION    "ReactOS Mode Utility"
+#define REACTOS_STR_INTERNAL_NAME       "mode"
+#define REACTOS_STR_ORIGINAL_FILENAME   "mode.com"
+#include <reactos/version.rc>
index f3d49ef..28fab89 100644 (file)
@@ -1,5 +1,7 @@
 
 add_executable(more more.c more.rc)
 set_module_type(more win32cui)
+set_target_properties(more PROPERTIES SUFFIX ".com")
+
 add_importlibs(more user32 msvcrt kernel32)
 add_cd_file(TARGET more DESTINATION reactos/system32 FOR all)
index ce96958..4d04db0 100644 (file)
@@ -2,9 +2,9 @@
 
 #include "resource.h"
 
-#define REACTOS_STR_FILE_DESCRIPTION  "W32 more command"
+#define REACTOS_STR_FILE_DESCRIPTION  "ReactOS More Command"
 #define REACTOS_STR_INTERNAL_NAME     "more"
-#define REACTOS_STR_ORIGINAL_FILENAME "more.exe"
+#define REACTOS_STR_ORIGINAL_FILENAME "more.com"
 #include <reactos/version.rc>
 
 /* UTF-8 */
index 13a1969..106e302 100644 (file)
@@ -20,7 +20,7 @@
 
 LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
 
-#define REACTOS_STR_FILE_DESCRIPTION  "xcopy command"
+#define REACTOS_STR_FILE_DESCRIPTION  "ReactOS Xcopy Command"
 #define REACTOS_STR_INTERNAL_NAME     "xcopy"
 #define REACTOS_STR_ORIGINAL_FILENAME "xcopy.exe"
 #include <reactos/version.rc>
index 6a30490..7d6cb2c 100644 (file)
@@ -182,7 +182,7 @@ ajustes previos anteponiendo a cualquier modificador - (hyphen)--por ejemplo, /-
     STRING_DIR_HELP3 " El volumen en la unidad %c no tiene etiqueta.\n"
     STRING_DIR_HELP4 " El volumen Serial Number is %04X-%04X\n"
     STRING_DIR_HELP5 "\n     Total de archivos mostrados:\n%16i archivo(s)% 14s bytes\n"
-    STRING_DIR_HELP6 "%16i Directorio(s)% 15s bytes\n"
+    STRING_DIR_HELP6 "%16i Directorio(s)% 15s bytes libres\n"
     STRING_DIR_HELP7 "\n Directorio %s\n\n"
     STRING_DIR_HELP8 "%16i archivo(s)% 14s bytes\n"
     STRING_DIRSTACK_HELP1 "Almacena el directorio actual para usarlo por el comando, \n\
index 48dc63b..ac720b8 100644 (file)
@@ -192,7 +192,7 @@ Modifier les paramètres mémorisés avec un - (tiret)--par exemple, /-W.\n"
     STRING_DIR_HELP3 " Le lecteur %c n'a pas de nom de volume\n"
     STRING_DIR_HELP4 " Le numéro de série du volume est %04X-%04X\n"
     STRING_DIR_HELP5 "\n   Total de fichiers listés :\n%16i Fichier(s)% 14s octets\n"
-    STRING_DIR_HELP6 "%16i Rep(s)% 15s octets\n"
+    STRING_DIR_HELP6 "%16i Rep(s)% 15s octets libres\n"
     STRING_DIR_HELP7 "\n Répertoire de %s\n\n"
     STRING_DIR_HELP8 "%16i Fichier(s)% 14s octets\n"
     STRING_DIRSTACK_HELP1 "Stocke le répertoire courant pour utilisation avec la commande POPD,\n\
index e628a1f..bc1ef3f 100644 (file)
@@ -170,7 +170,7 @@ A kapcsolók a DIRCMD környezeti változóban is lehetnek.\n"
     STRING_DIR_HELP3 " A (%c) meghajtóban található kötetnek nincs címkéje.\n"
     STRING_DIR_HELP4 " A kötet sorozatszáma: %04X-%04X\n"
     STRING_DIR_HELP5 "\n     Összes állomány:\n%16i Állomány(ok)% 14s bájt\n"
-    STRING_DIR_HELP6 "%16i Mappa %15s bájt"
+    STRING_DIR_HELP6 "%16i Mappa %15s bájt szabad"
     STRING_DIR_HELP7 "\n %s tartalma\n\n"
     STRING_DIR_HELP8 "%16i Állomány %14s bájt\n"
     STRING_DIRSTACK_HELP1 "Megjegyzi az aktuális mappát, majd átvált egy máasikra.\n\n\
index 5346a6f..d5b7079 100644 (file)
@@ -181,7 +181,7 @@ preset dengan mengawali setiap saklar dengan - (minus)--contohnya, /-W.\n"
     STRING_DIR_HELP3 " Volume di drive %c tidak berlabel.\n"
     STRING_DIR_HELP4 " Nomor Seri Volume adalah %04X-%04X\n"
     STRING_DIR_HELP5 "\n     Total File Didaftar:\n%16i File% 14s byte\n"
-    STRING_DIR_HELP6 "%16i Dir% 15s byte\n"
+    STRING_DIR_HELP6 "%16i Dir% 15s byte tersisa\n"
     STRING_DIR_HELP7 "\n Direktori %s\n\n"
     STRING_DIR_HELP8 "%16i File% 14s byte\n"
     STRING_DIRSTACK_HELP1 "Menyimpan direktori sekarang untuk digunakan oleh perintah POPD, lalu\n\
index acfe180..ac71fd9 100644 (file)
@@ -178,7 +178,7 @@ le selezioni preimpostate mettendo - (trattino) prima della selezione per esempi
     STRING_DIR_HELP3 " Il Volume nel disco %c non ha etichetta.\n"
     STRING_DIR_HELP4 " Il numero di serie del Volume è %04X-%04X\n"
     STRING_DIR_HELP5 "\n     Numero dei file elencati:\n%16i % 14s byte\n"
-    STRING_DIR_HELP6 "%16i Cartelle% 15s byte\n"
+    STRING_DIR_HELP6 "%16i Cartelle% 15s byte liberi\n"
     STRING_DIR_HELP7 "\n Cartelle di %s\n\n"
     STRING_DIR_HELP8 "%16i File% 14s byte\n"
     STRING_DIRSTACK_HELP1 "Salva la cartella corrente per l'uso con il comando POPD, poi\n\
index 557a49b..c189bd6 100644 (file)
@@ -179,7 +179,7 @@ forhåndsinnstilte brytere ved å sette en bindestrek (-) foran, for eksempel, /
     STRING_DIR_HELP3 " Volumet i stasjon %c er uten navn.\n"
     STRING_DIR_HELP4 " Volumserienummeret er %04X-%04X\n"
     STRING_DIR_HELP5 "\n     Totalt filer listet:\n%16i fil(er)% 14s byte\n"
-    STRING_DIR_HELP6 "%16i mappe(r)% 15s byte\n"
+    STRING_DIR_HELP6 "%16i mappe(r)% 15s byte ledig\n"
     STRING_DIR_HELP7 "\n mappe av %s\n\n"
     STRING_DIR_HELP8 "%16i fil(er)% 14s byte\n"
     STRING_DIRSTACK_HELP1 "Lagrer gjeldende mappe for bruk av POPD kommando, og\n\
index 2c3d1ff..88d49b1 100644 (file)
@@ -187,7 +187,7 @@ odwrócić działanie parametrów przedrostkiem - (myślnik)-- na przykład, /-W
     STRING_DIR_HELP3 " Wolumin w napędzie %c nie posiada etykiety.\n"
     STRING_DIR_HELP4 " Numer seryjny woluminu to: %04X-%04X\n"
     STRING_DIR_HELP5 "\n     Ogółem wyświetonych:\n%16i plik(ów)% 14s bajtów\n"
-    STRING_DIR_HELP6 "%16i katalog(ów)% 15s bajtów\n"
+    STRING_DIR_HELP6 "%16i katalog(ów)% 15s bajtów wolne\n"
     STRING_DIR_HELP7 "\n katalog %s\n\n"
     STRING_DIR_HELP8 "%16i plik(ów)% 14s bajtów\n"
     STRING_DIRSTACK_HELP1 "Przechowuje obecny katalog dla potrzeb komendy POPD, następnie\n\
index b762569..6d79259 100644 (file)
@@ -180,7 +180,7 @@ DELAY [/m]n\n\n\
     STRING_DIR_HELP3 " Том в устройстве %c не имеет метки.\n"
     STRING_DIR_HELP4 " Серийный номер тома: %04X-%04X\n"
     STRING_DIR_HELP5 "\n     Всего:\n%16i Файл(ов)% 14s байт\n"
-    STRING_DIR_HELP6 "%16i Dir(s)% 15s байт\n"
+    STRING_DIR_HELP6 "%16i Dir(s)% 15s байт свободно\n"
     STRING_DIR_HELP7 "\n Каталог of %s\n\n"
     STRING_DIR_HELP8 "%16i файл(ов)% 14s байт\n"
     STRING_DIRSTACK_HELP1 "Сохраняет текущую директорию для использования командой POPD, затем\n\
index b967186..ecdd380 100644 (file)
@@ -179,7 +179,7 @@ förinställda växlar med ett bindestreck (-) före, till exempel, /-W.\n"
     STRING_DIR_HELP3 " Volumet i enhet %c är utan namn.\n"
     STRING_DIR_HELP4 " Volymens serienummer är %04X-%04X\n"
     STRING_DIR_HELP5 "\n     Totalt filer listet:\n%16i fil(är)% 14s byte\n"
-    STRING_DIR_HELP6 "%16i mapp(ar)% 15s byte\n"
+    STRING_DIR_HELP6 "%16i mapp(ar)% 15s byte ledigt\n"
     STRING_DIR_HELP7 "\n mapp av %s\n\n"
     STRING_DIR_HELP8 "%16i fil(er)% 14s byte\n"
     STRING_DIRSTACK_HELP1 "Sparar aktuell mapp for användning av POPD kommandot, och\n\
index 1694900..f091215 100644 (file)
@@ -302,7 +302,7 @@ function(spec2def _dllname _spec_file)
 endfunction()
 
 macro(macro_mc FLAG FILE)
-    set(COMMAND_MC ${CMAKE_MC_COMPILER} ${FLAG} -r ${REACTOS_BINARY_DIR}/include/reactos -h ${REACTOS_BINARY_DIR}/include/reactos ${CMAKE_CURRENT_SOURCE_DIR}/${FILE}.mc)
+    set(COMMAND_MC ${CMAKE_MC_COMPILER} ${FLAG} -b ${CMAKE_CURRENT_SOURCE_DIR}/${FILE}.mc -r ${REACTOS_BINARY_DIR}/include/reactos -h ${REACTOS_BINARY_DIR}/include/reactos)
 endmacro()
 
 #pseh workaround
index ec63a04..046f48f 100644 (file)
@@ -966,6 +966,10 @@ LsaApLogonUser(IN PLSA_CLIENT_REQUEST ClientRequest,
     PSAMPR_USER_INFO_BUFFER UserInfo = NULL;
     UNICODE_STRING LogonServer;
     BOOLEAN SessionCreated = FALSE;
+    LARGE_INTEGER LogonTime;
+//    LARGE_INTEGER AccountExpires;
+    LARGE_INTEGER PasswordMustChange;
+    LARGE_INTEGER PasswordLastSet;
     NTSTATUS Status;
 
     TRACE("()\n");
@@ -1005,6 +1009,10 @@ LsaApLogonUser(IN PLSA_CLIENT_REQUEST ClientRequest,
         return STATUS_NOT_IMPLEMENTED;
     }
 
+    /* Get the logon time */
+    NtQuerySystemTime(&LogonTime);
+
+    /* Get the domain SID */
     Status = GetDomainSid(&AccountDomainSid);
     if (!NT_SUCCESS(Status))
     {
@@ -1080,9 +1088,20 @@ LsaApLogonUser(IN PLSA_CLIENT_REQUEST ClientRequest,
         goto done;
     }
 
-
     TRACE("UserName: %S\n", UserInfo->All.UserName.Buffer);
 
+    /* Check the password */
+    if ((UserInfo->All.UserAccountControl & USER_PASSWORD_NOT_REQUIRED) == 0)
+    {
+        Status = MsvpCheckPassword(&(LogonInfo->Password),
+                                   UserInfo);
+        if (!NT_SUCCESS(Status))
+        {
+            TRACE("MsvpCheckPassword failed (Status %08lx)\n", Status);
+            goto done;
+        }
+    }
+
     /* Check account restrictions for non-administrator accounts */
     if (RelativeIds.Element[0] != DOMAIN_USER_RID_ADMIN)
     {
@@ -1098,29 +1117,48 @@ LsaApLogonUser(IN PLSA_CLIENT_REQUEST ClientRequest,
         /* Check if the account has been locked */
         if (UserInfo->All.UserAccountControl & USER_ACCOUNT_AUTO_LOCKED)
         {
-            ERR("Account disabled!\n");
+            ERR("Account locked!\n");
             *SubStatus = STATUS_ACCOUNT_LOCKED_OUT;
             Status = STATUS_ACCOUNT_RESTRICTION;
             goto done;
         }
 
-        /* FIXME: more checks */
-//            *SubStatus = STATUS_PASSWORD_EXPIRED;
-//            *SubStatus = STATUS_INVALID_LOGON_HOURS;
-//            *SubStatus = STATUS_INVALID_WORKSTATION;
+#if 0
+        /* Check if the account expired */
+        AccountExpires.LowPart = UserInfo->All.AccountExpires.LowPart;
+        AccountExpires.HighPart = UserInfo->All.AccountExpires.HighPart;
 
-    }
+        if (AccountExpires.QuadPart != 0 &&
+            LogonTime.QuadPart >= AccountExpires.QuadPart)
+        {
+            ERR("Account expired!\n");
+            *SubStatus = STATUS_ACCOUNT_EXPIRED;
+            Status = STATUS_ACCOUNT_RESTRICTION;
+            goto done;
+        }
+#endif
 
-    /* Check the password */
-    if ((UserInfo->All.UserAccountControl & USER_PASSWORD_NOT_REQUIRED) == 0)
-    {
-        Status = MsvpCheckPassword(&(LogonInfo->Password),
-                                   UserInfo);
-        if (!NT_SUCCESS(Status))
+        /* Check if the password expired */
+        PasswordMustChange.LowPart = UserInfo->All.PasswordMustChange.LowPart;
+        PasswordMustChange.HighPart = UserInfo->All.PasswordMustChange.HighPart;
+        PasswordLastSet.LowPart = UserInfo->All.PasswordLastSet.LowPart;
+        PasswordLastSet.HighPart = UserInfo->All.PasswordLastSet.HighPart;
+
+        if (LogonTime.QuadPart >= PasswordMustChange.QuadPart)
         {
-            TRACE("MsvpCheckPassword failed (Status %08lx)\n", Status);
+            ERR("Password expired!\n");
+            if (PasswordLastSet.QuadPart == 0)
+                *SubStatus = STATUS_PASSWORD_MUST_CHANGE;
+            else
+                *SubStatus = STATUS_PASSWORD_EXPIRED;
+
+            Status = STATUS_ACCOUNT_RESTRICTION;
             goto done;
         }
+
+        /* FIXME: more checks */
+        // STATUS_INVALID_LOGON_HOURS;
+        // STATUS_INVALID_WORKSTATION;
     }
 
     /* Return logon information */
@@ -1220,7 +1258,7 @@ done:
         Status = STATUS_LOGON_FAILURE;
     }
 
-    TRACE("LsaApLogonUser done (Status %08lx)\n", Status);
+    TRACE("LsaApLogonUser done (Status 0x%08lx  SubStatus 0x%08lx)\n", Status, *SubStatus);
 
     return Status;
 }
index 3d70785..3cb70ca 100644 (file)
@@ -437,6 +437,7 @@ StartProcedure(
         Status = EnableInterrupts(DeviceExtension, FlagsToDisable, FlagsToEnable);
         if (!NT_SUCCESS(Status))
         {
+            WARN_(I8042PRT, "EnableInterrupts failed: %lx\n", Status);
             DeviceExtension->Flags &= ~(KEYBOARD_PRESENT | MOUSE_PRESENT);
             return Status;
         }
@@ -454,6 +455,10 @@ StartProcedure(
         {
             DeviceExtension->Flags |= KEYBOARD_INITIALIZED;
         }
+        else
+        {
+            WARN_(I8042PRT, "i8042ConnectKeyboardInterrupt failed: %lx\n", Status);
+        }
     }
 
     if (DeviceExtension->Flags & MOUSE_PRESENT &&
@@ -467,7 +472,11 @@ StartProcedure(
         {
             DeviceExtension->Flags |= MOUSE_INITIALIZED;
         }
-
+        else
+        {
+            WARN_(I8042PRT, "i8042ConnectMouseInterrupt failed: %lx\n", Status);
+        }
+        
         /* Start the mouse */
         Irql = KeAcquireInterruptSpinLock(DeviceExtension->HighestDIRQLInterrupt);
         i8042IsrWritePort(DeviceExtension, MOU_CMD_RESET, CTRL_WRITE_MOUSE);
@@ -533,7 +542,7 @@ i8042PnpStartDevice(
             {
                 if (ResourceDescriptor->u.Port.Length == 1)
                 {
-                    /* We assume that the first ressource will
+                    /* We assume that the first resource will
                      * be the control port and the second one
                      * will be the data port...
                      */
@@ -551,8 +560,8 @@ i8042PnpStartDevice(
                     }
                     else
                     {
-                        WARN_(I8042PRT, "Too much I/O ranges provided: 0x%lx\n", ResourceDescriptor->u.Port.Length);
-                        return STATUS_INVALID_PARAMETER;
+                        /* FIXME: implement PS/2 Active Multiplexing */
+                        ERR_(I8042PRT, "Unhandled I/O ranges provided: 0x%lx\n", ResourceDescriptor->u.Port.Length);
                     }
                 }
                 else
index 958f017..f551ea9 100644 (file)
@@ -17,7 +17,7 @@
  * Notes:
  *    This driver was obsoleted in Windows XP and most functions
  *    became pure stubs. But some of them were retained for backward
- *    compatibilty with existing drivers.
+ *    compatibility with existing drivers.
  *
  *    Preserved functions:
  *
index 5f41772..5c18437 100644 (file)
@@ -648,7 +648,7 @@ IopStartDevice2(IN PDEVICE_OBJECT DeviceObject)
     
     ASSERT(!(DeviceNode->Flags & DNF_DISABLED));
 
-    /* Build the I/O stack locaiton */
+    /* Build the I/O stack location */
     RtlZeroMemory(&Stack, sizeof(IO_STACK_LOCATION));
     Stack.MajorFunction = IRP_MJ_PNP;
     Stack.MinorFunction = IRP_MN_START_DEVICE;
index 93108bf..3ca411e 100644 (file)
@@ -271,7 +271,7 @@ IntCreateMenu(PHANDLE Handle, BOOL IsMenuBar)
    Menu->MenuInfo.dwMenuData = 0; /* Default */
    Menu->MenuInfo.Self = *Handle;
    Menu->MenuInfo.FocusedItem = NO_SELECTED_ITEM;
-   Menu->MenuInfo.Flags = (IsMenuBar ? 0 : MF_POPUP);
+   Menu->MenuInfo.Flags = (IsMenuBar ? 0 : MNF_POPUP);
    Menu->MenuInfo.Wnd = NULL;
    Menu->MenuInfo.WndOwner = NULL;
    Menu->MenuInfo.Height = 0;
@@ -454,7 +454,17 @@ IntSetMenuInfo(PMENU_OBJECT Menu, PROSMENUINFO lpmi)
       Menu->MenuInfo.dwStyle = lpmi->dwStyle;
    if(lpmi->fMask & MIM_APPLYTOSUBMENUS)
    {
-      /* FIXME */
+      int i;
+      PMENU_ITEM item = Menu->MenuItemList;
+      for ( i = Menu->MenuInfo.MenuItemCount; i; i--, item = item->Next)
+      {
+         if ( item->hSubMenu )
+         {
+            PMENU_OBJECT SubMenu;
+            if (!(SubMenu = UserGetMenuObject(item->hSubMenu))) continue;
+            IntSetMenuInfo( SubMenu, lpmi);
+         }
+      }
    }
    if (sizeof(MENUINFO) < lpmi->cbSize)
    {
@@ -741,7 +751,7 @@ IntSetMenuItemInfo(PMENU_OBJECT MenuObject, PMENU_ITEM MenuItem, PROSMENUITEMINF
          SubMenuObject = UserGetMenuObject(MenuItem->hSubMenu);
          if (SubMenuObject != NULL)
          {
-            SubMenuObject->MenuInfo.Flags |= MF_POPUP;
+            SubMenuObject->MenuInfo.Flags |= MNF_POPUP;
          }
       }
    }
@@ -775,7 +785,7 @@ IntSetMenuItemInfo(PMENU_OBJECT MenuObject, PMENU_ITEM MenuItem, PROSMENUITEMINF
       }
       else
       {
-         if (0 == (MenuObject->MenuInfo.Flags & MF_SYSMENU))
+         if (0 == (MenuObject->MenuInfo.Flags & MNF_SYSDESKMN))
          {
             MenuItem->fType |= MF_SEPARATOR;
          }
@@ -1724,6 +1734,50 @@ CLEANUP:
    END_CLEANUP;
 }
 
+BOOL FASTCALL
+IntGetMenuItemRect(
+   PWND pWnd,
+   PMENU_OBJECT Menu,
+   UINT uItem,
+   PRECTL Rect)
+{
+   LONG XMove, YMove;
+   PMENU_ITEM MenuItem;
+   int p = 0;
+
+   if (!pWnd)
+   {
+      HWND hWnd = Menu->MenuInfo.Wnd;
+      if (!(pWnd = UserGetWindowObject(hWnd))) return FALSE;
+   }
+                   
+   if ((p = IntGetMenuItemByFlag(Menu, uItem, MF_BYPOSITION, NULL, &MenuItem, NULL)) > -1)
+        *Rect = MenuItem->Rect;
+   else
+   {
+      ERR("Failed Item Lookup! %d\n", p);
+      return FALSE;
+   }
+
+   if (Menu->MenuInfo.Flags & MNF_POPUP)
+   {
+     XMove = pWnd->rcClient.left;
+     YMove = pWnd->rcClient.top;
+   }
+   else
+   {
+     XMove = pWnd->rcWindow.left;
+     YMove = pWnd->rcWindow.top;
+   }
+
+   Rect->left   += XMove;
+   Rect->top    += YMove;
+   Rect->right  += XMove;
+   Rect->bottom += YMove;
+
+   return TRUE;
+}
+
 /*
  * @implemented
  */
@@ -1734,219 +1788,126 @@ NtUserGetMenuBarInfo(
    LONG idItem,
    PMENUBARINFO pmbi)
 {
-   BOOL Res = TRUE;
-   PMENU_OBJECT MenuObject;
-   PMENU_ITEM mi;
-   PWND WindowObject;
+   PWND pWnd;
    HMENU hMenu;
-   POINT Offset;
-   RECTL Rect;
    MENUBARINFO kmbi;
+   BOOL Ret;
+   NTSTATUS Status = STATUS_SUCCESS;
+   PMENU_OBJECT Menu = NULL;
    DECLARE_RETURN(BOOL);
 
    TRACE("Enter NtUserGetMenuBarInfo\n");
    UserEnterShared();
 
-   if (!(WindowObject = UserGetWindowObject(hwnd)))
-     {
+   if (!(pWnd = UserGetWindowObject(hwnd)))
+   {
         EngSetLastError(ERROR_INVALID_WINDOW_HANDLE);
         RETURN(FALSE);
-     }
+   }
 
-   hMenu = (HMENU)(DWORD_PTR)WindowObject->IDMenu;
+   switch (idObject)
+   {
+    case OBJID_CLIENT:
+        if (!pWnd->pcls->fnid)
+            RETURN(FALSE);
+        if (pWnd->pcls->fnid != FNID_MENU)
+        {
+            WARN("called on invalid window: %d\n", pWnd->pcls->fnid);
+            EngSetLastError(ERROR_INVALID_MENU_HANDLE);
+            RETURN(FALSE);
+        }
+        // Windows does this! Wine checks for Atom and uses GetWindowLongPtrW.
+        hMenu = (HMENU)co_IntSendMessage(hwnd, MN_GETHMENU, 0, 0);
+        break;
+    case OBJID_MENU:
+        hMenu = UlongToHandle(pWnd->IDMenu);
+        break;
+    case OBJID_SYSMENU:
+        if (!(pWnd->style & WS_SYSMENU)) RETURN(FALSE);
+        Menu = IntGetSystemMenu(pWnd, FALSE, FALSE);
+        hMenu = Menu->MenuInfo.Self;
+        break;
+    default:
+        RETURN(FALSE);
+   }
 
-   if (!(MenuObject = UserGetMenuObject(hMenu)))
-     {
-       EngSetLastError(ERROR_INVALID_MENU_HANDLE);
-       RETURN(FALSE);
-     }
+   if (!hMenu)
+      RETURN(FALSE);
 
-   if (pmbi->cbSize != sizeof(MENUBARINFO))
-     {
+   _SEH2_TRY
+   {
+       kmbi.cbSize = pmbi->cbSize;
+   }
+   _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+   {
+       kmbi.cbSize = 0;
+   }
+   _SEH2_END
+
+   if (kmbi.cbSize != sizeof(MENUBARINFO))
+   {
        EngSetLastError(ERROR_INVALID_PARAMETER);
        RETURN(FALSE);
-     }
+   }
+
+   if (!Menu) Menu = UserGetMenuObject(hMenu);
+   if (!Menu)
+       RETURN(FALSE);
+
+   if (idItem < 0 || idItem > Menu->MenuInfo.MenuItemCount)
+       RETURN(FALSE);
+
+   RECTL_vSetEmptyRect(&kmbi.rcBar);
+
+   if (idItem == 0)
+   {
+      Ret = IntGetMenuItemRect(pWnd, Menu, -1, &kmbi.rcBar);
+      kmbi.rcBar.right = kmbi.rcBar.left + Menu->MenuInfo.Width;
+      kmbi.rcBar.bottom = kmbi.rcBar.top + Menu->MenuInfo.Height;
+      ERR("idItem 0 %d\n",Ret);
+   }
+   else
+   {
+      Ret = IntGetMenuItemRect(pWnd, Menu, idItem-1, &kmbi.rcBar);
+      ERR("idItem X %d\n", Ret);
+   }
 
-   kmbi.cbSize = sizeof(MENUBARINFO);
-   kmbi.fBarFocused = FALSE;
-   kmbi.fFocused = FALSE;
+   kmbi.hMenu = hMenu;
    kmbi.hwndMenu = NULL;
+   //kmbi.fBarFocused = top_popup_hmenu == hMenu;
+   if (idItem)
+   {
+       PMENU_OBJECT SubMenuObject;
+       kmbi.fFocused = Menu->MenuInfo.FocusedItem == idItem-1;
 
-   switch (idObject)
+       if ( kmbi.fFocused && Menu->MenuItemList->hSubMenu )
+       {
+          SubMenuObject = UserGetMenuObject(Menu->MenuItemList->hSubMenu); 
+          if (SubMenuObject) kmbi.hwndMenu = SubMenuObject->MenuInfo.Wnd;
+       }
+   }
+/*   else
    {
-      case OBJID_MENU:
-      {
-         PMENU_OBJECT SubMenuObject;
-         kmbi.hMenu = hMenu;
-         if (idItem) /* Non-Zero-Based. */
-           {
-              if (IntGetMenuItemByFlag(MenuObject, idItem-1, MF_BYPOSITION, NULL, &mi, NULL) > -1)
-                   kmbi.rcBar = mi->Rect;
-              else
-                {
-                   Res = FALSE;
-                   break;
-                }
-           }
-         else
-           {
-              /* If items is zero we assume info for the menu itself. */
-              if (!(IntGetClientOrigin(WindowObject, &Offset)))
-                {
-                   Res = FALSE;
-                   break;
-                }
-              Rect.left = Offset.x;
-              Rect.right = Offset.x + MenuObject->MenuInfo.Width;
-              Rect.bottom = Offset.y;
-              Rect.top = Offset.y - MenuObject->MenuInfo.Height;
-              kmbi.rcBar = Rect;
-              TRACE("Rect top = %d bottom = %d left = %d right = %d \n",
-                       Rect.top, Rect.bottom, Rect.left, Rect.right);
-           }
-         if (idItem)
-           {
-              if (idItem-1 == MenuObject->MenuInfo.FocusedItem)
-                    kmbi.fFocused = TRUE;
-           }
-         if (MenuObject->MenuInfo.FocusedItem != NO_SELECTED_ITEM)
-               kmbi.fBarFocused = TRUE;
-
-         if (MenuObject->MenuItemList)
-         {
-         SubMenuObject = UserGetMenuObject(MenuObject->MenuItemList->hSubMenu);
-         if(SubMenuObject) kmbi.hwndMenu = SubMenuObject->MenuInfo.Wnd;
-         }
-         TRACE("OBJID_MENU, idItem = %d\n",idItem);
-         break;
-      }
-      case OBJID_CLIENT:
-      {
-         PMENU_OBJECT SubMenuObject, XSubMenuObject;
-         HMENU hMenuChk;
-         // Windows does this! Wine checks for Atom and uses GetWindowLongPtrW.
-         hMenuChk = (HMENU)co_IntSendMessage(hwnd, MN_GETHMENU, 0, 0);
+       kmbi.fFocused = kmbi.fBarFocused;
+   }
+*/
+   _SEH2_TRY
+   {
+      RtlCopyMemory(pmbi, &kmbi, sizeof(MENUBARINFO));
+   }
+   _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+   {
+      Status = _SEH2_GetExceptionCode();
+   }
+   _SEH2_END
 
-         if (!(MenuObject = UserGetMenuObject(hMenuChk)))
-         {
-            ERR("Window does not have a Popup Menu!\n");
-            EngSetLastError(ERROR_INVALID_MENU_HANDLE);
-            RETURN(FALSE);
-         }
+   if (!NT_SUCCESS(Status))
+   {
+      SetLastNtError(Status);
+      RETURN(FALSE);
+   }
 
-         SubMenuObject = UserGetMenuObject(MenuObject->MenuItemList->hSubMenu);
-         if(SubMenuObject) kmbi.hMenu = SubMenuObject->MenuInfo.Self;
-         else
-           {
-              Res = FALSE;
-              ERR("OBJID_CLIENT, No SubMenu!\n");
-              break;
-           }
-         if (idItem)
-           {
-              if (IntGetMenuItemByFlag(SubMenuObject, idItem-1, MF_BYPOSITION, NULL, &mi, NULL) > -1)
-                   kmbi.rcBar = mi->Rect;
-              else
-                {
-                   Res = FALSE;
-                   break;
-                }
-           }
-         else
-           {
-              PWND SubWinObj;
-              if (!(SubWinObj = UserGetWindowObject(SubMenuObject->MenuInfo.Wnd)))
-                {
-                   Res = FALSE;
-                   break;
-                }
-              if (!(IntGetClientOrigin(SubWinObj, &Offset)))
-                {
-                   Res = FALSE;
-                   break;
-                }
-              Rect.left = Offset.x;
-              Rect.right = Offset.x + SubMenuObject->MenuInfo.Width;
-              Rect.top = Offset.y;
-              Rect.bottom = Offset.y + SubMenuObject->MenuInfo.Height;
-              kmbi.rcBar = Rect;
-           }
-         if (idItem)
-           {
-              if (idItem-1 == SubMenuObject->MenuInfo.FocusedItem)
-                   kmbi.fFocused = TRUE;
-           }
-         if (SubMenuObject->MenuInfo.FocusedItem != NO_SELECTED_ITEM)
-               kmbi.fBarFocused = TRUE;
-         XSubMenuObject = UserGetMenuObject(SubMenuObject->MenuItemList->hSubMenu);
-         if (XSubMenuObject) kmbi.hwndMenu = XSubMenuObject->MenuInfo.Wnd;
-         TRACE("OBJID_CLIENT, idItem = %d\n",idItem);
-         break;
-      }
-      case OBJID_SYSMENU:
-      {
-         PMENU_OBJECT SysMenuObject, SubMenuObject;
-         if(!(SysMenuObject = IntGetSystemMenu(WindowObject, FALSE, FALSE)))
-         {
-           Res = FALSE;
-           break;
-         }
-         kmbi.hMenu = SysMenuObject->MenuInfo.Self;
-         if (idItem)
-           {
-              if (IntGetMenuItemByFlag(SysMenuObject, idItem-1, MF_BYPOSITION, NULL, &mi, NULL) > -1)
-                   kmbi.rcBar = mi->Rect;
-              else
-                {
-                   Res = FALSE;
-                   break;
-                }
-           }
-         else
-           {
-              PWND SysWinObj;
-              if (!(SysWinObj = UserGetWindowObject(SysMenuObject->MenuInfo.Wnd)))
-                {
-                   Res = FALSE;
-                   break;
-                }
-              if (!(IntGetClientOrigin(SysWinObj, &Offset)))
-                {
-                   Res = FALSE;
-                   break;
-                }
-              Rect.left = Offset.x;
-              Rect.right = Offset.x + SysMenuObject->MenuInfo.Width;
-              Rect.top = Offset.y;
-              Rect.bottom = Offset.y + SysMenuObject->MenuInfo.Height;
-              kmbi.rcBar = Rect;
-           }
-         if (idItem)
-           {
-              if (idItem-1 == SysMenuObject->MenuInfo.FocusedItem)
-                    kmbi.fFocused = TRUE;
-           }
-         if (SysMenuObject->MenuInfo.FocusedItem != NO_SELECTED_ITEM)
-               kmbi.fBarFocused = TRUE;
-         SubMenuObject = UserGetMenuObject(SysMenuObject->MenuItemList->hSubMenu);
-         if(SubMenuObject) kmbi.hwndMenu = SubMenuObject->MenuInfo.Wnd;
-         TRACE("OBJID_SYSMENU, idItem = %d\n",idItem);
-         break;
-      }
-      default:
-         Res = FALSE;
-         ERR("Unknown idObject = %d, idItem = %d\n",idObject,idItem);
-   }
-   if (Res)
-     {
-        NTSTATUS Status = MmCopyToCaller(pmbi, &kmbi, sizeof(MENUBARINFO));
-        if (! NT_SUCCESS(Status))
-          {
-            SetLastNtError(Status);
-            RETURN(FALSE);
-          }
-     }
-   RETURN(Res);
+   RETURN(TRUE);
 
 CLEANUP:
    TRACE("Leave NtUserGetMenuBarInfo, ret=%i\n",_ret_);
@@ -2002,9 +1963,9 @@ NtUserGetMenuItemRect(
    PWND ReferenceWnd;
    LONG XMove, YMove;
    RECTL Rect;
-   NTSTATUS Status;
    PMENU_OBJECT Menu;
    PMENU_ITEM MenuItem;
+   NTSTATUS Status = STATUS_SUCCESS;
    DECLARE_RETURN(BOOL);
 
    TRACE("Enter NtUserGetMenuItemRect\n");
@@ -2029,7 +1990,7 @@ NtUserGetMenuItemRect(
 
    if (!(ReferenceWnd = UserGetWindowObject(hWnd))) RETURN( FALSE);
 
-   if(MenuItem->hSubMenu)
+   if (Menu->MenuInfo.Flags & MNF_POPUP)
    {
      XMove = ReferenceWnd->rcClient.left;
      YMove = ReferenceWnd->rcClient.top;
@@ -2045,13 +2006,22 @@ NtUserGetMenuItemRect(
    Rect.right  += XMove;
    Rect.bottom += YMove;
 
-   Status = MmCopyToCaller(lprcItem, &Rect, sizeof(RECT));
-   if (! NT_SUCCESS(Status))
+   _SEH2_TRY
+   {
+      RtlCopyMemory(lprcItem, &Rect, sizeof(RECTL));
+   }
+   _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+   {
+      Status = _SEH2_GetExceptionCode();
+   }
+   _SEH2_END
+
+   if (!NT_SUCCESS(Status))
    {
       SetLastNtError(Status);
-      RETURN( FALSE);
+      RETURN(FALSE);
    }
-   RETURN( TRUE);
+   RETURN(TRUE);
 
 CLEANUP:
    TRACE("Leave NtUserGetMenuItemRect, ret=%i\n",_ret_);
index 11ab709..9d6e471 100644 (file)
@@ -931,7 +931,7 @@ IntGetSystemMenu(PWND Window, BOOL bRevert, BOOL RetMenu)
          if(NewMenu)
          {
             Window->SystemMenu = NewMenu->MenuInfo.Self;
-            NewMenu->MenuInfo.Flags |= MF_SYSMENU;
+            NewMenu->MenuInfo.Flags |= MNF_SYSDESKMN;
             NewMenu->MenuInfo.Wnd = Window->head.h;
             ret = NewMenu;
             //IntReleaseMenuObject(NewMenu);
@@ -950,7 +950,7 @@ IntGetSystemMenu(PWND Window, BOOL bRevert, BOOL RetMenu)
             UserDestroyMenu(hSysMenu);
             return NULL;
          }
-         SysMenu->MenuInfo.Flags |= MF_SYSMENU;
+         SysMenu->MenuInfo.Flags |= MNF_SYSDESKMN;
          SysMenu->MenuInfo.Wnd = Window->head.h;
          hNewMenu = co_IntLoadSysMenuTemplate();
          if(!hNewMenu)
@@ -970,7 +970,8 @@ IntGetSystemMenu(PWND Window, BOOL bRevert, BOOL RetMenu)
          NewMenu = IntCloneMenu(Menu);
          if(NewMenu)
          {
-            NewMenu->MenuInfo.Flags |= MF_SYSMENU | MF_POPUP;
+            NewMenu->MenuInfo.Flags |= MNF_SYSDESKMN | MNF_POPUP;
+            NewMenu->MenuInfo.dwStyle = MNS_CHECKORBMP;
             IntReleaseMenuObject(NewMenu);
             UserSetMenuDefaultItem(NewMenu, SC_CLOSE, FALSE);
 
@@ -1426,7 +1427,7 @@ IntSetSystemMenu(PWND Window, PMENU_OBJECT Menu)
       OldMenu = IntGetMenuObject(Window->SystemMenu);
       if(OldMenu)
       {
-         OldMenu->MenuInfo.Flags &= ~ MF_SYSMENU;
+         OldMenu->MenuInfo.Flags &= ~ MNF_SYSDESKMN;
          IntReleaseMenuObject(OldMenu);
       }
    }
@@ -1435,7 +1436,7 @@ IntSetSystemMenu(PWND Window, PMENU_OBJECT Menu)
    {
       /* FIXME: Check window style, propably return FALSE? */
       Window->SystemMenu = Menu->MenuInfo.Self;
-      Menu->MenuInfo.Flags |= MF_SYSMENU;
+      Menu->MenuInfo.Flags |= MNF_SYSDESKMN;
    }
    else
       Window->SystemMenu = (HMENU)0;
index f99b825..d514922 100644 (file)
@@ -36,6 +36,9 @@ WINE_DEFAULT_DEBUG_CHANNEL(menu);
 #define TPM_BUTTONDOWN         0x40000000              /* menu was clicked before tracking */
 #define TPM_POPUPMENU           0x20000000              /* menu is a popup menu */
 
+/*  top and bottom margins for popup menus */
+#define MENU_TOP_MARGIN 3
+#define MENU_BOTTOM_MARGIN 2
 
 #define MENU_TYPE_MASK (MF_STRING | MF_BITMAP | MF_OWNERDRAW | MF_SEPARATOR)
 
@@ -46,10 +49,10 @@ WINE_DEFAULT_DEBUG_CHANNEL(menu);
 #define IS_MAGIC_BITMAP(id) ((id) && ((INT_PTR)(id) < 12) && ((INT_PTR)(id) >= -1))
 
 #define IS_SYSTEM_MENU(MenuInfo)  \
-       (0 == ((MenuInfo)->Flags & MF_POPUP) && 0 != ((MenuInfo)->Flags & MF_SYSMENU))
+       (0 == ((MenuInfo)->Flags & MNF_POPUP) && 0 != ((MenuInfo)->Flags & MNF_SYSDESKMN))
 
 #define IS_SYSTEM_POPUP(MenuInfo) \
-       (0 != ((MenuInfo)->Flags & MF_POPUP) && 0 != ((MenuInfo)->Flags & MF_SYSMENU))
+       (0 != ((MenuInfo)->Flags & MNF_POPUP) && 0 != ((MenuInfo)->Flags & MNF_SYSDESKMN))
 
 #define IS_BITMAP_ITEM(flags) (MF_BITMAP == MENU_ITEM_TYPE(flags))
 
@@ -507,6 +510,7 @@ static UINT FASTCALL MenuFindItemByKey(HWND WndOwner, PROSMENUINFO MenuInfo,
   PROSMENUITEMINFO Items, ItemInfo;
   LRESULT MenuChar;
   UINT i;
+  WORD Flags = 0;
 
   TRACE("\tlooking for '%c' (0x%02x) in [%p]\n", (char) Key, Key, MenuInfo);
 
@@ -546,8 +550,11 @@ static UINT FASTCALL MenuFindItemByKey(HWND WndOwner, PROSMENUINFO MenuInfo,
           }
       }
 
+      Flags |= MenuInfo->Flags & MNF_POPUP ? MF_POPUP : 0;
+      Flags |= MenuInfo->Flags & MNF_SYSDESKMN ? MF_SYSMENU : 0;
+
       MenuChar = SendMessageW(WndOwner, WM_MENUCHAR,
-                              MAKEWPARAM(Key, MenuInfo->Flags), (LPARAM) MenuInfo->Self);
+                              MAKEWPARAM(Key, Flags), (LPARAM) MenuInfo->Self);
       if (HIWORD(MenuChar) == MNC_EXECUTE) return LOWORD(MenuChar);
       if (HIWORD(MenuChar) == MNC_CLOSE) return (UINT)(-2);
     }
@@ -1299,7 +1306,7 @@ static void FASTCALL MenuDrawMenuItem(HWND hWnd, PROSMENUINFO MenuInfo, HWND Wnd
         HBITMAP bm;
         INT y = rect.top + rect.bottom;
         RECT rc = rect;
-        int checked = FALSE;
+        BOOL checked = FALSE;
         UINT check_bitmap_width = GetSystemMetrics( SM_CXMENUCHECK );
         UINT check_bitmap_height = GetSystemMetrics( SM_CYMENUCHECK );
         /* Draw the check mark
@@ -1547,6 +1554,7 @@ static BOOL FASTCALL MenuShowPopup(HWND hwndOwner, HMENU hmenu, UINT id, UINT fl
     POINT pt;
     HMONITOR monitor;
     MONITORINFO info;
+    DWORD ex_style = 0; 
 
     TRACE("owner=%p hmenu=%p id=0x%04x x=0x%04x y=0x%04x xa=0x%04x ya=0x%04x\n",
           hwndOwner, hmenu, id, x, y, xanchor, yanchor);
@@ -1588,6 +1596,11 @@ static BOOL FASTCALL MenuShowPopup(HWND hwndOwner, HMENU hmenu, UINT id, UINT fl
     info.cbSize = sizeof(info);
     GetMonitorInfoW( monitor, &info );
 
+    if (flags & TPM_LAYOUTRTL) 
+    {                               
+        ex_style = WS_EX_LAYOUTRTL; 
+        flags ^= TPM_RIGHTALIGN;
+    } 
     if( flags & TPM_RIGHTALIGN ) x -= width;
     if( flags & TPM_CENTERALIGN ) x -= width / 2;
 
@@ -1615,7 +1628,7 @@ static BOOL FASTCALL MenuShowPopup(HWND hwndOwner, HMENU hmenu, UINT id, UINT fl
     if( y < info.rcMonitor.top ) y = info.rcMonitor.top;
 
     /* NOTE: In Windows, top menu popup is not owned. */
-    MenuInfo.Wnd = CreateWindowExW( 0, WC_MENU, NULL,
+    MenuInfo.Wnd = CreateWindowExW( ex_style, WC_MENU, NULL,
                                   WS_POPUP, x, y, width, height,
                                   hwndOwner, 0, (HINSTANCE) GetWindowLongPtrW(hwndOwner, GWLP_HINSTANCE),
                                  (LPVOID) MenuInfo.Self);
@@ -1650,7 +1663,7 @@ static void FASTCALL MenuSelectItem(HWND hwndOwner, PROSMENUINFO hmenu, UINT wIn
 
      if (!hmenu || !hmenu->MenuItemCount || !hmenu->Wnd) return;
     if (hmenu->FocusedItem == wIndex) return;
-    if (hmenu->Flags & MF_POPUP) hdc = GetDC(hmenu->Wnd);
+    if (hmenu->Flags & MNF_POPUP) hdc = GetDC(hmenu->Wnd);
     else hdc = GetDCEx(hmenu->Wnd, 0, DCX_CACHE | DCX_WINDOW);
     if (!top_popup) {
         top_popup = hmenu->Wnd;
@@ -1671,7 +1684,7 @@ static void FASTCALL MenuSelectItem(HWND hwndOwner, PROSMENUINFO hmenu, UINT wIn
             MenuSetRosMenuItemInfo(hmenu->Self, hmenu->FocusedItem, &ItemInfo);
         }
         MenuDrawMenuItem(hmenu->Wnd, hmenu, hwndOwner, hdc, &ItemInfo,
-                       hmenu->Height, ! (hmenu->Flags & MF_POPUP),
+                       hmenu->Height, !(hmenu->Flags & MNF_POPUP),
                        ODA_SELECT);
     }
 
@@ -1688,20 +1701,24 @@ static void FASTCALL MenuSelectItem(HWND hwndOwner, PROSMENUINFO hmenu, UINT wIn
                 ItemInfo.fState |= MF_HILITE;
                 MenuSetRosMenuItemInfo(hmenu->Self, hmenu->FocusedItem, &ItemInfo);
                 MenuDrawMenuItem(hmenu->Wnd, hmenu, hwndOwner, hdc,
-                               &ItemInfo, hmenu->Height, ! (hmenu->Flags & MF_POPUP),
+                               &ItemInfo, hmenu->Height, !(hmenu->Flags & MNF_POPUP),
                                ODA_SELECT);
             }
             if (sendMenuSelect)
             {
-                SendMessageW(hwndOwner, WM_MENUSELECT,
-                           MAKELONG(ItemInfo.hSubMenu ? wIndex : ItemInfo.wID,
-                                    ItemInfo.fType | ItemInfo.fState | MF_MOUSESELECT |
-                                    (hmenu->Flags & (MF_SYSMENU|MF_POPUP))), (LPARAM) hmenu->Self);
+                WPARAM wParam = MAKEWPARAM( ItemInfo.hSubMenu ? wIndex : ItemInfo.wID, 
+                                            ItemInfo.fType | ItemInfo.fState |
+                                           (ItemInfo.hSubMenu ? MF_POPUP : 0) |
+                                           (hmenu->Flags & MNF_SYSDESKMN ? MF_SYSMENU : 0 ) );
+
+                SendMessageW(hwndOwner, WM_MENUSELECT, wParam, (LPARAM) hmenu->Self);
             }
         }
     }
-    else if (sendMenuSelect) {
-        if(topmenu) {
+    else if (sendMenuSelect) 
+    {
+        if(topmenu) 
+        {
             int pos;
             pos = MenuFindSubMenu(&topmenu, hmenu->Self);
             if (pos != NO_SELECTED_ITEM)
@@ -1709,11 +1726,11 @@ static void FASTCALL MenuSelectItem(HWND hwndOwner, PROSMENUINFO hmenu, UINT wIn
                 if (MenuGetRosMenuInfo(&TopMenuInfo, topmenu)
                     && MenuGetRosMenuItemInfo(topmenu, pos, &ItemInfo))
                 {
-                    SendMessageW(hwndOwner, WM_MENUSELECT,
-                               MAKELONG(Pos, ItemInfo.fType | ItemInfo.fState
-                                             | MF_MOUSESELECT
-                                             | (TopMenuInfo.Flags & MF_SYSMENU)),
-                               (LPARAM) topmenu);
+                    WPARAM wParam = MAKEWPARAM( Pos, ItemInfo.fType | ItemInfo.fState |
+                                               (ItemInfo.hSubMenu ? MF_POPUP : 0) |
+                                               (TopMenuInfo.Flags & MNF_SYSDESKMN ? MF_SYSMENU : 0 ) );
+
+                    SendMessageW(hwndOwner, WM_MENUSELECT, wParam, (LPARAM) topmenu);
                 }
             }
         }
@@ -1995,11 +2012,11 @@ PopupMenuWndProcW(HWND Wnd, UINT Message, WPARAM wParam, LPARAM lParam)
  *
  * NOTE: flags is equivalent to the mtOption field
  */
-static LPCSTR MENU_ParseResource( LPCSTR res, HMENU hMenu, BOOL unicode )
+static LPCSTR MENU_ParseResource( LPCSTR res, HMENU hMenu)
 {
     WORD flags, id = 0;
     HMENU hSubMenu;
-    LPCSTR str;
+    LPCWSTR str;
     BOOL end = FALSE;
 
     do
@@ -2016,46 +2033,19 @@ static LPCSTR MENU_ParseResource( LPCSTR res, HMENU hMenu, BOOL unicode )
             id = GET_WORD(res);
             res += sizeof(WORD);
         }
-        str = res;
-        if(!unicode)
-            res += strlen(str) + 1;
-        else
-            res += (strlenW((LPCWSTR)str) + 1) * sizeof(WCHAR);
+        str = (LPCWSTR)res;
+        res += (strlenW(str) + 1) * sizeof(WCHAR);
+
         if (flags & MF_POPUP)
         {
             hSubMenu = CreatePopupMenu();
             if(!hSubMenu) return NULL;
-            if(!(res = MENU_ParseResource(res, hSubMenu, unicode)))
-                return NULL;
-            if(!unicode)
-                AppendMenuA(hMenu, flags, (UINT)hSubMenu, str);
-            else
-                AppendMenuW(hMenu, flags, (UINT)hSubMenu, (LPCWSTR)str);
+            if(!(res = MENU_ParseResource(res, hSubMenu))) return NULL;
+            AppendMenuW(hMenu, flags, (UINT_PTR)hSubMenu, (LPCWSTR)str);
         }
         else  /* Not a popup */
         {
-            if(!unicode)
-            {
-                if (*str == 0)
-                    flags = MF_SEPARATOR;
-            }
-            else
-            {
-                if (*(LPCWSTR)str == 0)
-                    flags = MF_SEPARATOR;
-            }
-
-            if (flags & MF_SEPARATOR)
-            {
-                if (!(flags & (MF_GRAYED | MF_DISABLED)))
-                    flags |= MF_GRAYED | MF_DISABLED;
-            }
-
-            if(!unicode)
-                AppendMenuA(hMenu, flags, id, *str ? str : NULL);
-            else
-                AppendMenuW(hMenu, flags, id,
-                    *(LPCWSTR)str ? (LPCWSTR)str : NULL);
+            AppendMenuW(hMenu, flags, id, *(LPCWSTR)str ? (LPCWSTR)str : NULL);
         }
     } while(!end);
     return res;
@@ -2071,10 +2061,10 @@ static LPCSTR MENU_ParseResource( LPCSTR res, HMENU hMenu, BOOL unicode )
 static LPCSTR MENUEX_ParseResource(LPCSTR res, HMENU hMenu)
 {
     WORD resinfo;
-    MENUITEMINFOW mii;
-
     do
     {
+        MENUITEMINFOW mii;
+
         mii.cbSize = sizeof(mii);
         mii.fMask = MIIM_STATE | MIIM_ID | MIIM_TYPE;
         mii.fType = GET_DWORD(res);
@@ -2114,13 +2104,12 @@ static LPCSTR MENUEX_ParseResource(LPCSTR res, HMENU hMenu)
                 return NULL;
             }
             mii.fMask |= MIIM_SUBMENU;
-            /*mii.wID = (UINT)mii.hSubMenu;*/
         }
-        else if (!mii.dwTypeData[0])
+        else if (!mii.dwTypeData[0] && !(mii.fType & MF_SEPARATOR))
+        {
             mii.fType |= MF_SEPARATOR;
-
-        if (!InsertMenuItemW(hMenu, -1, MF_BYPOSITION, &mii))
-            ERR("InsertMenuItemW failed\n");
+        }
+        InsertMenuItemW(hMenu, -1, MF_BYPOSITION, &mii);
     } while (!(resinfo & MF_END));
     return res;
 }
@@ -2327,7 +2316,7 @@ MenuShowSubPopup(HWND WndOwner, PROSMENUINFO MenuInfo, BOOL SelectFirst, UINT Fl
   if (0 == (Flags & TPM_NONOTIFY))
     {
       SendMessageW(WndOwner, WM_INITMENUPOPUP, (WPARAM) ItemInfo.hSubMenu,
-                   MAKELONG(MenuInfo->FocusedItem, IS_SYSTEM_MENU(MenuInfo)));
+                   MAKELPARAM(MenuInfo->FocusedItem, IS_SYSTEM_MENU(MenuInfo)));
     }
 
   if (! MenuGetRosMenuItemInfo(MenuInfo->Self, MenuInfo->FocusedItem, &ItemInfo))
@@ -2340,7 +2329,7 @@ MenuShowSubPopup(HWND WndOwner, PROSMENUINFO MenuInfo, BOOL SelectFirst, UINT Fl
   /* correct item if modified as a reaction to WM_INITMENUPOPUP message */
   if (0 == (ItemInfo.fState & MF_HILITE))
     {
-      if (0 != (MenuInfo->Flags & MF_POPUP))
+      if (0 != (MenuInfo->Flags & MNF_POPUP))
         {
           Dc = GetDC(MenuInfo->Wnd);
         }
@@ -2354,7 +2343,7 @@ MenuShowSubPopup(HWND WndOwner, PROSMENUINFO MenuInfo, BOOL SelectFirst, UINT Fl
       ItemInfo.fState |= MF_HILITE;
       MenuSetRosMenuItemInfo(MenuInfo->Self, MenuInfo->FocusedItem, &ItemInfo);
       MenuDrawMenuItem(MenuInfo->Wnd, MenuInfo, WndOwner, Dc, &ItemInfo, MenuInfo->Height,
-                       ! (MenuInfo->Flags & MF_POPUP), ODA_DRAWENTIRE);
+                       ! (MenuInfo->Flags & MNF_POPUP), ODA_DRAWENTIRE);
       ReleaseDC(MenuInfo->Wnd, Dc);
     }
 
@@ -2372,38 +2361,47 @@ MenuShowSubPopup(HWND WndOwner, PROSMENUINFO MenuInfo, BOOL SelectFirst, UINT Fl
     {
       MenuInitSysMenuPopup(ItemInfo.hSubMenu, GetWindowLongPtrW(MenuInfo->Wnd, GWL_STYLE),
                            GetClassLongPtrW(MenuInfo->Wnd, GCL_STYLE), HTSYSMENU);
-
+      if (Flags & TPM_LAYOUTRTL) Rect.left;
       NcGetSysPopupPos(MenuInfo->Wnd, &Rect);
       Rect.top = Rect.bottom;
       Rect.right = GetSystemMetrics(SM_CXSIZE);
       Rect.bottom = GetSystemMetrics(SM_CYSIZE);
     }
   else
-    {
+  {
       GetWindowRect(MenuInfo->Wnd, &Rect);
-      if (0 != (MenuInfo->Flags & MF_POPUP))
-       {
-          Rect.left += ItemInfo.Rect.right - GetSystemMetrics(SM_CXBORDER);
-          Rect.top += ItemInfo.Rect.top - 3;
+      if (0 != (MenuInfo->Flags & MNF_POPUP))
+      {
+          if(Flags & TPM_LAYOUTRTL)
+             Rect.left += GetSystemMetrics(SM_CXBORDER);
+          else
+             Rect.left += ItemInfo.Rect.right- GetSystemMetrics(SM_CXBORDER);
+          Rect.top += ItemInfo.Rect.top - MENU_TOP_MARGIN;//3;
           Rect.right = ItemInfo.Rect.left - ItemInfo.Rect.right + GetSystemMetrics(SM_CXBORDER);
-          Rect.bottom = ItemInfo.Rect.top - ItemInfo.Rect.bottom - 3 - 2
-                                                    - GetSystemMetrics(SM_CYBORDER);
-        }
+          Rect.bottom = ItemInfo.Rect.top - ItemInfo.Rect.bottom - MENU_TOP_MARGIN - MENU_BOTTOM_MARGIN/*2*/
+                                                     - GetSystemMetrics(SM_CYBORDER);
+      }
       else
-        {
-          Rect.left += ItemInfo.Rect.left;
+      {
+          if(Flags & TPM_LAYOUTRTL)
+              Rect.left += Rect.right - ItemInfo.Rect.left;
+          else
+              Rect.left += ItemInfo.Rect.left;
           Rect.top += ItemInfo.Rect.bottom;
           Rect.right = ItemInfo.Rect.right - ItemInfo.Rect.left;
           Rect.bottom = ItemInfo.Rect.bottom - ItemInfo.Rect.top;
-        }
-    }
+      }
+  }
+
+  /* use default alignment for submenus */
+  Flags &= ~(TPM_CENTERALIGN | TPM_RIGHTALIGN | TPM_VCENTERALIGN | TPM_BOTTOMALIGN);
 
   MenuShowPopup(WndOwner, ItemInfo.hSubMenu, MenuInfo->FocusedItem, Flags,
                 Rect.left, Rect.top, Rect.right, Rect.bottom );
   if (SelectFirst && MenuGetRosMenuInfo(&SubMenuInfo, ItemInfo.hSubMenu))
-    {
+  {
       MenuMoveSelection(WndOwner, &SubMenuInfo, ITEM_NEXT);
-    }
+  }
 
   Ret = ItemInfo.hSubMenu;
   MenuCleanupRosMenuItemInfo(&ItemInfo);
@@ -2484,7 +2482,7 @@ MenuSwitchTracking(MTRACKER* Mt, PROSMENUINFO PtMenuInfo, UINT Index, UINT wFlag
 
   if (MenuGetRosMenuInfo(&TopMenuInfo, Mt->TopMenu) &&
       Mt->TopMenu != PtMenuInfo->Self &&
-      0 == ((PtMenuInfo->Flags | TopMenuInfo.Flags) & MF_POPUP))
+      0 == ((PtMenuInfo->Flags | TopMenuInfo.Flags) & MNF_POPUP))
     {
       /* both are top level menus (system and menu-bar) */
       MenuHideSubPopups(Mt->OwnerWnd, &TopMenuInfo, FALSE, wFlags);
@@ -2540,17 +2538,20 @@ MenuExecFocusedItem(MTRACKER *Mt, PROSMENUINFO MenuInfo, UINT Flags)
             do not send a message to the owner */
           if (0 == (Flags & TPM_RETURNCMD))
            {
-              if (0 != (MenuInfo->Flags & MF_SYSMENU))
+              if (0 != (MenuInfo->Flags & MNF_SYSDESKMN))
                 {
                   PostMessageW(Mt->OwnerWnd, WM_SYSCOMMAND, ItemInfo.wID,
                                MAKELPARAM((SHORT) Mt->Pt.x, (SHORT) Mt->Pt.y));
                 }
               else
                 {
-                  if (MenuInfo->dwStyle & MNS_NOTIFYBYPOS)
-                      PostMessageW(Mt->OwnerWnd, WM_MENUCOMMAND,
-                                                 MenuInfo->FocusedItem,
-                                                       (LPARAM)MenuInfo->Self);
+                  BOOL ret;
+                  ROSMENUINFO topmenuI;
+                  ret = MenuGetRosMenuInfo(&topmenuI, Mt->TopMenu);
+                  DWORD dwStyle = MenuInfo->dwStyle | (ret ? topmenuI.dwStyle : 0);
+
+                  if (dwStyle & MNS_NOTIFYBYPOS)
+                      PostMessageW(Mt->OwnerWnd, WM_MENUCOMMAND, MenuInfo->FocusedItem, (LPARAM)MenuInfo->Self);
                   else
                     PostMessageW(Mt->OwnerWnd, WM_COMMAND, ItemInfo.wID, 0);
                 }
@@ -2726,7 +2727,7 @@ MenuPtMenu(HMENU Menu, POINT Pt)
 
   /* check the current window (avoiding WM_HITTEST) */
   Ht = DefWndNCHitTest(MenuInfo.Wnd, Pt);
-  if (0 != (MenuInfo.Flags & MF_POPUP))
+  if (0 != (MenuInfo.Flags & MNF_POPUP))
     {
       if (HTNOWHERE != Ht && HTERROR != Ht)
         {
@@ -2977,20 +2978,20 @@ MenuSuspendPopup(MTRACKER* Mt, UINT uMsg)
 
     switch( uMsg )
     {
-       case WM_KEYDOWN:
-            PeekMessageW( &msg, 0, 0, 0, PM_NOYIELD | PM_NOREMOVE);
-            if( msg.message == WM_KEYUP || msg.message == WM_PAINT )
-            {
-                PeekMessageW( &msg, 0, 0, 0, PM_NOYIELD | PM_REMOVE);
-                PeekMessageW( &msg, 0, 0, 0, PM_NOYIELD | PM_NOREMOVE);
-                if( msg.message == WM_KEYDOWN &&
-                   (msg.wParam == VK_LEFT || msg.wParam == VK_RIGHT))
-                {
-                    Mt->TrackFlags |= TF_SUSPENDPOPUP;
-                    return TRUE;
-                }
-            }
-            break;
+    case WM_KEYDOWN:
+        PeekMessageW( &msg, 0, 0, 0, PM_NOYIELD | PM_NOREMOVE);
+        if( msg.message == WM_KEYUP || msg.message == WM_PAINT )
+        {
+            PeekMessageW( &msg, 0, 0, 0, PM_NOYIELD | PM_REMOVE);
+            PeekMessageW( &msg, 0, 0, 0, PM_NOYIELD | PM_NOREMOVE);
+            if( msg.message == WM_KEYDOWN &&
+                (msg.wParam == VK_LEFT || msg.wParam == VK_RIGHT))
+            {
+                 Mt->TrackFlags |= TF_SUSPENDPOPUP;
+                 return TRUE;
+            }
+        }
+        break;
     }
     /* failures go through this */
     Mt->TrackFlags &= ~TF_SUSPENDPOPUP;
@@ -3012,7 +3013,7 @@ MenuKeyEscape(MTRACKER *Mt, UINT Flags)
   if (Mt->CurrentMenu != Mt->TopMenu)
     {
       if (MenuGetRosMenuInfo(&MenuInfo, Mt->CurrentMenu)
-          && 0 != (MenuInfo.Flags & MF_POPUP))
+          && 0 != (MenuInfo.Flags & MNF_POPUP))
         {
           MenuPrev = MenuTmp = Mt->TopMenu;
 
@@ -3084,7 +3085,7 @@ MenuKeyLeft(MTRACKER* Mt, UINT Flags)
     {
       return;
     }
-  if ((MenuPrev == Mt->TopMenu) && !(TopMenuInfo.Flags & MF_POPUP))
+  if ((MenuPrev == Mt->TopMenu) && !(TopMenuInfo.Flags & MNF_POPUP))
     {
       /* move menu bar selection if no more popups are left */
 
@@ -3124,7 +3125,7 @@ static void FASTCALL MenuKeyRight(MTRACKER *Mt, UINT Flags)
          Mt->CurrentMenu, Mt->TopMenu);
 
     if (! MenuGetRosMenuInfo(&MenuInfo, Mt->TopMenu)) return;
-    if ((MenuInfo.Flags & MF_POPUP) || (Mt->CurrentMenu != Mt->TopMenu))
+    if ((MenuInfo.Flags & MNF_POPUP) || (Mt->CurrentMenu != Mt->TopMenu))
     {
       /* If already displaying a popup, try to display sub-popup */
 
@@ -3154,7 +3155,7 @@ static void FASTCALL MenuKeyRight(MTRACKER *Mt, UINT Flags)
        return;
     }
 
-    if (!(MenuInfo.Flags & MF_POPUP)) /* menu bar tracking */
+    if (!(MenuInfo.Flags & MNF_POPUP)) /* menu bar tracking */
     {
       if (Mt->CurrentMenu != Mt->TopMenu)
         {
@@ -3265,7 +3266,7 @@ static INT FASTCALL MenuTrackMenu(HMENU hmenu, UINT wFlags, INT x, INT y,
                 }
                 if (!enterIdleSent)
                 {
-                  HWND win = MenuInfo.Flags & MF_POPUP ? MenuInfo.Wnd : NULL;
+                  HWND win = MenuInfo.Flags & MNF_POPUP ? MenuInfo.Wnd : NULL;
                   enterIdleSent = TRUE;
                   SendMessageW( mt.OwnerWnd, WM_ENTERIDLE, MSGF_MENU, (LPARAM) win);
                 }
@@ -3384,7 +3385,7 @@ static INT FASTCALL MenuTrackMenu(HMENU hmenu, UINT wFlags, INT x, INT y,
                     case VK_DOWN: /* If on menu bar, pull-down the menu */
                         if (MenuGetRosMenuInfo(&MenuInfo, mt.CurrentMenu))
                         {
-                            if (!(MenuInfo.Flags & MF_POPUP))
+                            if (!(MenuInfo.Flags & MNF_POPUP))
                             {
                                 if (MenuGetRosMenuInfo(&MenuInfo, mt.TopMenu))
                                     mt.CurrentMenu = MenuShowSubPopup(mt.OwnerWnd, &MenuInfo, TRUE, wFlags);
@@ -3507,16 +3508,15 @@ static INT FASTCALL MenuTrackMenu(HMENU hmenu, UINT wFlags, INT x, INT y,
             {
                 MenuHideSubPopups(mt.OwnerWnd, &MenuInfo, FALSE, wFlags);
 
-                if (MenuInfo.Flags & MF_POPUP)
+                if (MenuInfo.Flags & MNF_POPUP)
                 {
                     IntNotifyWinEvent(EVENT_SYSTEM_MENUPOPUPEND, MenuInfo.Wnd, OBJID_CLIENT, CHILDID_SELF, 0);
                     DestroyWindow(MenuInfo.Wnd);
                     MenuInfo.Wnd = NULL;
 
-                    if (!(MenuInfo.Flags & TPM_NONOTIFY))
+                    if (!(wFlags & TPM_NONOTIFY))
                       SendMessageW( mt.OwnerWnd, WM_UNINITMENUPOPUP, (WPARAM)mt.TopMenu,
                                  MAKELPARAM(0, IS_SYSTEM_MENU(&MenuInfo)) );
-
                 }
                 MenuSelectItem( mt.OwnerWnd, &MenuInfo, NO_SELECTED_ITEM, FALSE, 0 );
             }
@@ -3584,7 +3584,7 @@ static BOOL FASTCALL MenuInitTracking(HWND hWnd, HMENU hMenu, BOOL bPopup, UINT
 
     IntNotifyWinEvent( EVENT_SYSTEM_MENUSTART,
                        hWnd,
-                       MenuInfo.Flags & MF_SYSMENU ? OBJID_SYSMENU : OBJID_MENU,
+                       MenuInfo.Flags & MNF_SYSDESKMN ? OBJID_SYSMENU : OBJID_MENU,
                        CHILDID_SELF, 0);
     return TRUE;
 }
@@ -3615,6 +3615,7 @@ VOID MenuTrackMouseMenuBar( HWND hWnd, ULONG ht, POINT pt)
 
     TRACE("wnd=%p ht=0x%04x (%ld,%ld)\n", hWnd, ht, pt.x, pt.y);
 
+    if (GetWindowLongW( hWnd, GWL_EXSTYLE ) & WS_EX_LAYOUTRTL) wFlags |= TPM_LAYOUTRTL;
     if (IsMenu(hMenu))
     {
         /* map point to parent client coordinates */
@@ -3716,6 +3717,7 @@ BOOL WINAPI TrackPopupMenuEx( HMENU Menu, UINT Flags, int x, int y,
     /* ReactOS Check */
     if (!ValidateHwnd(Wnd))
     {
+       /* invalid window see wine menu.c test_menu_trackpopupmenu line 3146 */
        return FALSE;
     }
 
@@ -4815,7 +4817,7 @@ LoadMenuIndirectW(CONST MENUTEMPLATE *lpMenuTemplate)
       offset = GET_WORD(p);
       p += sizeof(WORD) + offset;
       if (!(hMenu = CreateMenu())) return 0;
-      if (!MENU_ParseResource(p, hMenu, TRUE))
+      if (!MENU_ParseResource(p, hMenu))
       {
         DestroyMenu(hMenu);
         return 0;
@@ -4897,7 +4899,7 @@ ModifyMenuA(
 
   if(!MenuGetRosMenuItemInfo( hMnu, uPosition, &rmii)) return FALSE;
 
-  if ((rmii.hSubMenu) && (uFlags & MF_POPUP) && (rmii.hSubMenu != (HMENU)uIDNewItem))
+  if (rmii.hSubMenu && (uFlags & MF_POPUP) && (rmii.hSubMenu != (HMENU)uIDNewItem))
     NtUserDestroyMenu( rmii.hSubMenu );   /* ModifyMenu() spec */
 
   MenuCleanupRosMenuItemInfo( &rmii );
@@ -4944,7 +4946,7 @@ ModifyMenuW(
 
   if(!MenuGetRosMenuItemInfo( hMnu, uPosition, &rmii)) return FALSE;
 
-  if ((rmii.hSubMenu) && (uFlags & MF_POPUP) && (rmii.hSubMenu != (HMENU)uIDNewItem))
+  if (rmii.hSubMenu && (uFlags & MF_POPUP) && (rmii.hSubMenu != (HMENU)uIDNewItem))
     NtUserDestroyMenu( rmii.hSubMenu );   /* ModifyMenu() spec */
 
   MenuCleanupRosMenuItemInfo( &rmii );
index 8932d38..3d2805b 100644 (file)
@@ -88,7 +88,8 @@ GRAPHICS_BUFFER_Initialize(OUT PCONSOLE_SCREEN_BUFFER* Buffer,
     /* We do not use anything else than uncompressed bitmaps */
     if (GraphicsInfo->Info.lpBitMapInfo->bmiHeader.biCompression != BI_RGB)
     {
-        DPRINT1("biCompression == %d != BI_RGB, correct that!\n", GraphicsInfo->Info.lpBitMapInfo->bmiHeader.biCompression);
+        DPRINT1("biCompression == %d != BI_RGB, fix that!\n",
+                GraphicsInfo->Info.lpBitMapInfo->bmiHeader.biCompression);
         GraphicsInfo->Info.lpBitMapInfo->bmiHeader.biCompression = BI_RGB;
     }
 
index 5c1ab10..afe3afe 100644 (file)
@@ -585,6 +585,78 @@ ConioWriteConsole(PCONSOLE Console,
     return STATUS_SUCCESS;
 }
 
+NTSTATUS NTAPI
+ConDrvChangeScreenBufferAttributes(IN PCONSOLE Console,
+                                   IN PTEXTMODE_SCREEN_BUFFER Buffer,
+                                   IN USHORT NewScreenAttrib,
+                                   IN USHORT NewPopupAttrib)
+{
+    DWORD X, Y, Length;
+    PCHAR_INFO Ptr;
+
+    COORD  TopLeft = {0};
+    ULONG  NumCodesToWrite = Buffer->ScreenBufferSize.X * Buffer->ScreenBufferSize.Y;
+    USHORT OldScreenAttrib = Buffer->ScreenDefaultAttrib;
+
+    if (Console == NULL || Buffer == NULL)
+    {
+        return STATUS_INVALID_PARAMETER;
+    }
+
+    /* Validity check */
+    ASSERT(Console == Buffer->Header.Console);
+
+    X = TopLeft.X;
+    Y = (TopLeft.Y + Buffer->VirtualY) % Buffer->ScreenBufferSize.Y;
+    Length = NumCodesToWrite;
+    // Ptr = ConioCoordToPointer(Buffer, X, Y); // Doesn't work
+    // Ptr = &Buffer->Buffer[X + Y * Buffer->ScreenBufferSize.X]; // May work
+
+    while (Length--)
+    {
+        // Ptr = ConioCoordToPointer(Buffer, X, Y); // Doesn't work either
+        Ptr = &Buffer->Buffer[X + Y * Buffer->ScreenBufferSize.X];
+
+        /*
+         * Change the current colors only if they are the old ones.
+         */
+
+        /* Foreground color */
+        if ((Ptr->Attributes & 0x0F) == (OldScreenAttrib & 0x0F))
+            Ptr->Attributes = (Ptr->Attributes & 0xFFF0) | (NewScreenAttrib & 0x0F);
+
+        /* Background color */
+        if ((Ptr->Attributes & 0xF0) == (OldScreenAttrib & 0xF0))
+            Ptr->Attributes = (Ptr->Attributes & 0xFF0F) | (NewScreenAttrib & 0xF0);
+
+        // ++Ptr;
+
+        if (++X == Buffer->ScreenBufferSize.X)
+        {
+            X = 0;
+
+            if (++Y == Buffer->ScreenBufferSize.Y)
+            {
+                Y = 0;
+            }
+        }
+    }
+
+    /* Save foreground and background colors for both screen and popup */
+    Buffer->ScreenDefaultAttrib = (NewScreenAttrib & 0x00FF);
+    Buffer->PopupDefaultAttrib  = (NewPopupAttrib  & 0x00FF);
+
+    /* Refresh the display if needed */
+    if ((PCONSOLE_SCREEN_BUFFER)Buffer == Console->ActiveBuffer)
+    {
+        SMALL_RECT UpdateRect;
+        ConioComputeUpdateRect(Buffer, &UpdateRect, &TopLeft, NumCodesToWrite);
+        TermDrawRegion(Console, &UpdateRect);
+    }
+
+    return STATUS_SUCCESS;
+}
+
 
 /* PUBLIC DRIVER APIS *********************************************************/
 
@@ -947,7 +1019,6 @@ ConDrvWriteConsoleOutputString(IN PCONSOLE Console,
     PWCHAR tmpString = NULL;
     DWORD X, Y, Length; // , Written = 0;
     ULONG CodeSize;
-    SMALL_RECT UpdateRect;
     PCHAR_INFO Ptr;
 
     if (Console == NULL || Buffer == NULL ||
@@ -1046,6 +1117,7 @@ ConDrvWriteConsoleOutputString(IN PCONSOLE Console,
 
     if ((PCONSOLE_SCREEN_BUFFER)Buffer == Console->ActiveBuffer)
     {
+        SMALL_RECT UpdateRect;
         ConioComputeUpdateRect(Buffer, &UpdateRect, WriteCoord, NumCodesToWrite);
         TermDrawRegion(Console, &UpdateRect);
     }
@@ -1071,7 +1143,6 @@ ConDrvFillConsoleOutput(IN PCONSOLE Console,
 {
     DWORD X, Y, Length; // , Written = 0;
     PCHAR_INFO Ptr;
-    SMALL_RECT UpdateRect;
 
     if (Console == NULL || Buffer == NULL || Code == NULL ||
         WriteCoord == NULL /* || CodesWritten == NULL */)
@@ -1144,6 +1215,7 @@ ConDrvFillConsoleOutput(IN PCONSOLE Console,
 
     if ((PCONSOLE_SCREEN_BUFFER)Buffer == Console->ActiveBuffer)
     {
+        SMALL_RECT UpdateRect;
         ConioComputeUpdateRect(Buffer, &UpdateRect, WriteCoord, NumCodesToWrite);
         TermDrawRegion(Console, &UpdateRect);
     }
index 3ac9cc2..6980851 100644 (file)
 /* FUNCTIONS ******************************************************************/
 
 VOID
-GuiCopyFromGraphicsBuffer(PGRAPHICS_SCREEN_BUFFER Buffer)
+GuiCopyFromGraphicsBuffer(PGRAPHICS_SCREEN_BUFFER Buffer,
+                          PGUI_CONSOLE_DATA GuiData)
 {
     /*
      * This function supposes that the system clipboard was opened.
      */
 
-    // PCONSOLE Console = Buffer->Header.Console;
+    PCONSOLE Console = Buffer->Header.Console;
 
-    UNIMPLEMENTED;
+    HDC hMemDC;
+    HBITMAP  hBitmapTarget, hBitmapOld;
+    HPALETTE hPalette, hPaletteOld;
+    ULONG selWidth, selHeight;
+
+    if (Buffer->BitMap == NULL) return;
+
+    selWidth  = Console->Selection.srSelection.Right - Console->Selection.srSelection.Left + 1;
+    selHeight = Console->Selection.srSelection.Bottom - Console->Selection.srSelection.Top + 1;
+    DPRINT1("Selection is (%d|%d) to (%d|%d)\n",
+           Console->Selection.srSelection.Left,
+           Console->Selection.srSelection.Top,
+           Console->Selection.srSelection.Right,
+           Console->Selection.srSelection.Bottom);
+
+    hMemDC = CreateCompatibleDC(GuiData->hMemDC);
+    if (hMemDC == NULL) return;
+
+    /* Allocate a bitmap to be given to the clipboard, so it will not be freed here */
+    hBitmapTarget = CreateCompatibleBitmap(GuiData->hMemDC, selWidth, selHeight);
+    if (hBitmapTarget == NULL)
+    {
+        DeleteDC(hMemDC);
+        return;
+    }
+
+    /* Select the new bitmap */
+    hBitmapOld = SelectObject(hMemDC, hBitmapTarget);
+
+    /* Change the palette in hMemDC if the current palette does exist */
+    if (Buffer->PaletteHandle == NULL)
+        hPalette = GuiData->hSysPalette;
+    else
+        hPalette = Buffer->PaletteHandle;
+
+    if (hPalette) hPaletteOld = SelectPalette(hMemDC, hPalette, FALSE);
+
+    /* Grab the mutex */
+    NtWaitForSingleObject(Buffer->Mutex, FALSE, NULL);
+
+    // The equivalent of a SetDIBitsToDevice call...
+    // It seems to be broken: it does not copy the tail of the bitmap.
+    // http://wiki.allegro.cc/index.php?title=StretchDIBits
+#if 0
+    StretchDIBits(hMemDC,
+                  0, 0,
+                  selWidth, selHeight,
+                  Console->Selection.srSelection.Left,
+                  Console->Selection.srSelection.Top,
+                  selWidth, selHeight,
+                  Buffer->BitMap,
+                  Buffer->BitMapInfo,
+                  Buffer->BitMapUsage,
+                  SRCCOPY);
+#else
+    SetDIBitsToDevice(hMemDC,
+                      /* Coordinates / size of the repainted rectangle, in the framebuffer's frame */
+                      0, 0,
+                      selWidth, selHeight,
+                      /* Coordinates / size of the corresponding image portion, in the graphics screen-buffer's frame */
+                      Console->Selection.srSelection.Left,
+                      Console->Selection.srSelection.Top,
+                      0,
+                      Buffer->ScreenBufferSize.Y, // == Buffer->BitMapInfo->bmiHeader.biHeight
+                      Buffer->BitMap,
+                      Buffer->BitMapInfo,
+                      Buffer->BitMapUsage);
+#endif
+
+    /* Release the mutex */
+    NtReleaseMutant(Buffer->Mutex, NULL);
+
+    /* Restore the palette and the old bitmap */
+    if (hPalette) SelectPalette(hMemDC, hPaletteOld, FALSE);
+    SelectObject(hMemDC, hBitmapOld);
+
+    EmptyClipboard();
+    SetClipboardData(CF_BITMAP, hBitmapTarget);
+
+    DeleteDC(hMemDC);
 }
 
 VOID
-GuiPasteToGraphicsBuffer(PGRAPHICS_SCREEN_BUFFER Buffer)
+GuiPasteToGraphicsBuffer(PGRAPHICS_SCREEN_BUFFER Buffer,
+                         PGUI_CONSOLE_DATA GuiData)
 {
     /*
      * This function supposes that the system clipboard was opened.
index 5041dad..88265cf 100644 (file)
@@ -52,7 +52,7 @@ typedef struct _GUI_CONSOLE_DATA
 
     HWND hWindow;               /* Handle to the console's window            */
     HDC  hMemDC;                /* Memory DC holding the console framebuffer */
-    HBITMAP hBitmap;            /* Console framebuffer                       */
+    HBITMAP  hBitmap;           /* Console framebuffer                       */
     HPALETTE hSysPalette;       /* Handle to the original system palette     */
 
     HICON hIcon;                /* Handle to the console's icon (big)   */
index acc870b..e01dbda 100644 (file)
@@ -1333,8 +1333,12 @@ Quit:
         return 0;
 }
 
-VOID GuiCopyFromTextModeBuffer(PTEXTMODE_SCREEN_BUFFER Buffer);
-VOID GuiCopyFromGraphicsBuffer(PGRAPHICS_SCREEN_BUFFER Buffer);
+VOID
+GuiCopyFromTextModeBuffer(PTEXTMODE_SCREEN_BUFFER Buffer,
+                          PGUI_CONSOLE_DATA GuiData);
+VOID
+GuiCopyFromGraphicsBuffer(PGRAPHICS_SCREEN_BUFFER Buffer,
+                          PGUI_CONSOLE_DATA GuiData);
 
 static VOID
 GuiConsoleCopy(PGUI_CONSOLE_DATA GuiData)
@@ -1346,11 +1350,11 @@ GuiConsoleCopy(PGUI_CONSOLE_DATA GuiData)
 
         if (GetType(Buffer) == TEXTMODE_BUFFER)
         {
-            GuiCopyFromTextModeBuffer((PTEXTMODE_SCREEN_BUFFER)Buffer);
+            GuiCopyFromTextModeBuffer((PTEXTMODE_SCREEN_BUFFER)Buffer, GuiData);
         }
         else /* if (GetType(Buffer) == GRAPHICS_BUFFER) */
         {
-            GuiCopyFromGraphicsBuffer((PGRAPHICS_SCREEN_BUFFER)Buffer);
+            GuiCopyFromGraphicsBuffer((PGRAPHICS_SCREEN_BUFFER)Buffer, GuiData);
         }
 
         CloseClipboard();
@@ -1361,8 +1365,12 @@ GuiConsoleCopy(PGUI_CONSOLE_DATA GuiData)
     }
 }
 
-VOID GuiPasteToTextModeBuffer(PTEXTMODE_SCREEN_BUFFER Buffer);
-VOID GuiPasteToGraphicsBuffer(PGRAPHICS_SCREEN_BUFFER Buffer);
+VOID
+GuiPasteToTextModeBuffer(PTEXTMODE_SCREEN_BUFFER Buffer,
+                         PGUI_CONSOLE_DATA GuiData);
+VOID
+GuiPasteToGraphicsBuffer(PGRAPHICS_SCREEN_BUFFER Buffer,
+                         PGUI_CONSOLE_DATA GuiData);
 
 static VOID
 GuiConsolePaste(PGUI_CONSOLE_DATA GuiData)
@@ -1373,11 +1381,11 @@ GuiConsolePaste(PGUI_CONSOLE_DATA GuiData)
 
         if (GetType(Buffer) == TEXTMODE_BUFFER)
         {
-            GuiPasteToTextModeBuffer((PTEXTMODE_SCREEN_BUFFER)Buffer);
+            GuiPasteToTextModeBuffer((PTEXTMODE_SCREEN_BUFFER)Buffer, GuiData);
         }
         else /* if (GetType(Buffer) == GRAPHICS_BUFFER) */
         {
-            GuiPasteToGraphicsBuffer((PGRAPHICS_SCREEN_BUFFER)Buffer);
+            GuiPasteToGraphicsBuffer((PGRAPHICS_SCREEN_BUFFER)Buffer, GuiData);
         }
 
         CloseClipboard();
@@ -1909,6 +1917,8 @@ GuiConsoleWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
                 EnableMenuItem(hMenu, ID_SYSTEM_EDIT_COPY , MF_BYCOMMAND |
                                ((Console->Selection.dwFlags & CONSOLE_SELECTION_IN_PROGRESS) &&
                                 (Console->Selection.dwFlags & CONSOLE_SELECTION_NOT_EMPTY) ? MF_ENABLED : MF_GRAYED));
+                // FIXME: Following whether the active screen buffer is text-mode
+                // or graphics-mode, search for CF_UNICODETEXT or CF_BITMAP formats.
                 EnableMenuItem(hMenu, ID_SYSTEM_EDIT_PASTE, MF_BYCOMMAND |
                                (!(Console->Selection.dwFlags & CONSOLE_SELECTION_IN_PROGRESS) &&
                                 IsClipboardFormatAvailable(CF_UNICODETEXT) ? MF_ENABLED : MF_GRAYED));
index 79d5d9b..d39fe61 100644 (file)
@@ -30,7 +30,8 @@ COLORREF RGBFromAttrib2(PCONSOLE Console, WORD Attribute)
 }
 
 VOID
-GuiCopyFromTextModeBuffer(PTEXTMODE_SCREEN_BUFFER Buffer)
+GuiCopyFromTextModeBuffer(PTEXTMODE_SCREEN_BUFFER Buffer,
+                          PGUI_CONSOLE_DATA GuiData)
 {
     /*
      * This function supposes that the system clipboard was opened.
@@ -72,12 +73,16 @@ GuiCopyFromTextModeBuffer(PTEXTMODE_SCREEN_BUFFER Buffer)
     size += 1; /* Null-termination */
     size *= sizeof(WCHAR);
 
-    /* Allocate memory, it will be passed to the system and may not be freed here */
+    /* Allocate some memory area to be given to the clipboard, so it will not be freed here */
     hData = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, size);
     if (hData == NULL) return;
 
     data = GlobalLock(hData);
-    if (data == NULL) return;
+    if (data == NULL)
+    {
+        GlobalFree(hData);
+        return;
+    }
 
     DPRINT("Copying %dx%d selection\n", selWidth, selHeight);
     dstPos = data;
@@ -121,7 +126,8 @@ GuiCopyFromTextModeBuffer(PTEXTMODE_SCREEN_BUFFER Buffer)
 }
 
 VOID
-GuiPasteToTextModeBuffer(PTEXTMODE_SCREEN_BUFFER Buffer)
+GuiPasteToTextModeBuffer(PTEXTMODE_SCREEN_BUFFER Buffer,
+                         PGUI_CONSOLE_DATA GuiData)
 {
     /*
      * This function supposes that the system clipboard was opened.
index f765e85..1775d1d 100644 (file)
@@ -436,7 +436,11 @@ ConSrvGetDefaultSettings(IN OUT PCONSOLE_INFO ConsoleInfo,
     }
 }
 
-
+NTSTATUS NTAPI
+ConDrvChangeScreenBufferAttributes(IN PCONSOLE Console,
+                                   IN PTEXTMODE_SCREEN_BUFFER Buffer,
+                                   IN USHORT NewScreenAttrib,
+                                   IN USHORT NewPopupAttrib);
 /*
  * NOTE: This function explicitely references Console->ActiveBuffer.
  * It is possible that it should go into some frontend...
@@ -455,26 +459,10 @@ ConSrvApplyUserSettings(IN PCONSOLE Console,
     Console->QuickEdit  = ConsoleInfo->QuickEdit;
     Console->InsertMode = ConsoleInfo->InsertMode;
 
-    /*
-     * Apply foreground and background colors for both screen and popup
-     * and copy the new palette.
-     */
-    if (GetType(ActiveBuffer) == TEXTMODE_BUFFER)
-    {
-        PTEXTMODE_SCREEN_BUFFER Buffer = (PTEXTMODE_SCREEN_BUFFER)ActiveBuffer;
-
-        Buffer->ScreenDefaultAttrib = ConsoleInfo->ScreenAttrib;
-        Buffer->PopupDefaultAttrib  = ConsoleInfo->PopupAttrib;
-    }
-    else // if (Console->ActiveBuffer->Header.Type == GRAPHICS_BUFFER)
-    {
-    }
-
+    /* Copy the new console palette */
     // FIXME: Possible buffer overflow if s_colors is bigger than pConInfo->Colors.
     memcpy(Console->Colors, ConsoleInfo->Colors, sizeof(s_Colors));
 
-    // TODO: Really update the screen attributes as FillConsoleOutputAttribute does.
-
     /* Apply cursor size */
     ActiveBuffer->CursorInfo.bVisible = (ConsoleInfo->CursorSize != 0);
     ActiveBuffer->CursorInfo.dwSize   = min(max(ConsoleInfo->CursorSize, 0), 100);
@@ -537,6 +525,12 @@ ConSrvApplyUserSettings(IN PCONSOLE Console,
 
             if (SizeChanged) TermResizeTerminal(Console);
         }
+
+        /* Apply foreground and background colors for both screen and popup */
+        ConDrvChangeScreenBufferAttributes(Console,
+                                           Buffer,
+                                           ConsoleInfo->ScreenAttrib,
+                                           ConsoleInfo->PopupAttrib);
     }
     else // if (GetType(ActiveBuffer) == GRAPHICS_BUFFER)
     {