diff --git a/base/applications/cmdutils/CMakeLists.txt b/base/applications/cmdutils/CMakeLists.txt index a64f6ad523a..a559623b7e4 100644 --- a/base/applications/cmdutils/CMakeLists.txt +++ b/base/applications/cmdutils/CMakeLists.txt @@ -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) diff --git a/base/applications/cmdutils/doskey/doskey.rc b/base/applications/cmdutils/doskey/doskey.rc index c302f555706..52e969bfdc3 100644 --- a/base/applications/cmdutils/doskey/doskey.rc +++ b/base/applications/cmdutils/doskey/doskey.rc @@ -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 diff --git a/base/applications/cmdutils/find/find.rc b/base/applications/cmdutils/find/find.rc index ae1c5059842..5c054330d9d 100644 --- a/base/applications/cmdutils/find/find.rc +++ b/base/applications/cmdutils/find/find.rc @@ -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 diff --git a/base/applications/cmdutils/mode/CMakeLists.txt b/base/applications/cmdutils/mode/CMakeLists.txt new file mode 100644 index 00000000000..354c426dd2b --- /dev/null +++ b/base/applications/cmdutils/mode/CMakeLists.txt @@ -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 index 00000000000..aa49431ea95 --- /dev/null +++ b/base/applications/cmdutils/mode/mode.c @@ -0,0 +1,551 @@ +/* + * ReactOS mode console command + * + * mode.c + * + * Copyright (C) 2002 Robert Dickenson + * + * 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 +#include + +#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 index 00000000000..33c5a85f202 --- /dev/null +++ b/base/applications/cmdutils/mode/mode.rc @@ -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 diff --git a/base/applications/cmdutils/more/CMakeLists.txt b/base/applications/cmdutils/more/CMakeLists.txt index f3d49efd5cc..28fab89b700 100644 --- a/base/applications/cmdutils/more/CMakeLists.txt +++ b/base/applications/cmdutils/more/CMakeLists.txt @@ -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) diff --git a/base/applications/cmdutils/more/more.rc b/base/applications/cmdutils/more/more.rc index ce96958212f..4d04db0baf4 100644 --- a/base/applications/cmdutils/more/more.rc +++ b/base/applications/cmdutils/more/more.rc @@ -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 /* UTF-8 */ diff --git a/base/applications/cmdutils/xcopy/rsrc.rc b/base/applications/cmdutils/xcopy/rsrc.rc index 13a1969cdeb..106e3027905 100644 --- a/base/applications/cmdutils/xcopy/rsrc.rc +++ b/base/applications/cmdutils/xcopy/rsrc.rc @@ -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 diff --git a/base/shell/cmd/lang/es-ES.rc b/base/shell/cmd/lang/es-ES.rc index 6a30490f408..7d6cb2c5715 100644 --- a/base/shell/cmd/lang/es-ES.rc +++ b/base/shell/cmd/lang/es-ES.rc @@ -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\ diff --git a/base/shell/cmd/lang/fr-FR.rc b/base/shell/cmd/lang/fr-FR.rc index 48dc63b7e6e..ac720b802ff 100644 --- a/base/shell/cmd/lang/fr-FR.rc +++ b/base/shell/cmd/lang/fr-FR.rc @@ -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\ diff --git a/base/shell/cmd/lang/hu-HU.rc b/base/shell/cmd/lang/hu-HU.rc index e628a1f73be..bc1ef3fdfed 100644 --- a/base/shell/cmd/lang/hu-HU.rc +++ b/base/shell/cmd/lang/hu-HU.rc @@ -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\ diff --git a/base/shell/cmd/lang/id-ID.rc b/base/shell/cmd/lang/id-ID.rc index 5346a6f92a5..d5b707998dc 100644 --- a/base/shell/cmd/lang/id-ID.rc +++ b/base/shell/cmd/lang/id-ID.rc @@ -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\ diff --git a/base/shell/cmd/lang/it-IT.rc b/base/shell/cmd/lang/it-IT.rc index acfe18070a8..ac71fd92c17 100644 --- a/base/shell/cmd/lang/it-IT.rc +++ b/base/shell/cmd/lang/it-IT.rc @@ -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\ diff --git a/base/shell/cmd/lang/no-NO.rc b/base/shell/cmd/lang/no-NO.rc index 557a49b18c0..c189bd61383 100644 --- a/base/shell/cmd/lang/no-NO.rc +++ b/base/shell/cmd/lang/no-NO.rc @@ -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\ diff --git a/base/shell/cmd/lang/pl-PL.rc b/base/shell/cmd/lang/pl-PL.rc index 2c3d1fffc42..88d49b18ac3 100644 --- a/base/shell/cmd/lang/pl-PL.rc +++ b/base/shell/cmd/lang/pl-PL.rc @@ -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\ diff --git a/base/shell/cmd/lang/ru-RU.rc b/base/shell/cmd/lang/ru-RU.rc index b762569a072..6d7925996e0 100644 --- a/base/shell/cmd/lang/ru-RU.rc +++ b/base/shell/cmd/lang/ru-RU.rc @@ -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\ diff --git a/base/shell/cmd/lang/sv-SE.rc b/base/shell/cmd/lang/sv-SE.rc index b9671865bdf..ecdd380d697 100644 --- a/base/shell/cmd/lang/sv-SE.rc +++ b/base/shell/cmd/lang/sv-SE.rc @@ -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\ diff --git a/cmake/msvc.cmake b/cmake/msvc.cmake index 16949003343..f091215e58b 100644 --- a/cmake/msvc.cmake +++ b/cmake/msvc.cmake @@ -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 diff --git a/dll/win32/msv1_0/msv1_0.c b/dll/win32/msv1_0/msv1_0.c index ec63a04368d..046f48f097d 100644 --- a/dll/win32/msv1_0/msv1_0.c +++ b/dll/win32/msv1_0/msv1_0.c @@ -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; - } - - /* Check the password */ - if ((UserInfo->All.UserAccountControl & USER_PASSWORD_NOT_REQUIRED) == 0) - { - Status = MsvpCheckPassword(&(LogonInfo->Password), - UserInfo); - if (!NT_SUCCESS(Status)) + if (AccountExpires.QuadPart != 0 && + LogonTime.QuadPart >= AccountExpires.QuadPart) { - TRACE("MsvpCheckPassword failed (Status %08lx)\n", Status); + ERR("Account expired!\n"); + *SubStatus = STATUS_ACCOUNT_EXPIRED; + Status = STATUS_ACCOUNT_RESTRICTION; goto done; } +#endif + + /* 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) + { + 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; } diff --git a/drivers/input/i8042prt/pnp.c b/drivers/input/i8042prt/pnp.c index 3d707850b46..3cb70cab767 100644 --- a/drivers/input/i8042prt/pnp.c +++ b/drivers/input/i8042prt/pnp.c @@ -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 diff --git a/drivers/usb/usbd/usbd.c b/drivers/usb/usbd/usbd.c index 958f017f3da..f551ea9c332 100644 --- a/drivers/usb/usbd/usbd.c +++ b/drivers/usb/usbd/usbd.c @@ -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: * diff --git a/ntoskrnl/io/pnpmgr/pnpmgr.c b/ntoskrnl/io/pnpmgr/pnpmgr.c index 5f41772f890..5c18437a6f6 100644 --- a/ntoskrnl/io/pnpmgr/pnpmgr.c +++ b/ntoskrnl/io/pnpmgr/pnpmgr.c @@ -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; diff --git a/win32ss/user/ntuser/menu.c b/win32ss/user/ntuser/menu.c index 93108bf09d1..3ca411e65ba 100644 --- a/win32ss/user/ntuser/menu.c +++ b/win32ss/user/ntuser/menu.c @@ -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; - - if (!(MenuObject = UserGetMenuObject(hMenu))) - { - EngSetLastError(ERROR_INVALID_MENU_HANDLE); - RETURN(FALSE); - } - - if (pmbi->cbSize != sizeof(MENUBARINFO)) - { - EngSetLastError(ERROR_INVALID_PARAMETER); - RETURN(FALSE); - } - - kmbi.cbSize = sizeof(MENUBARINFO); - kmbi.fBarFocused = FALSE; - kmbi.fFocused = FALSE; - kmbi.hwndMenu = NULL; + } switch (idObject) { - 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); - - if (!(MenuObject = UserGetMenuObject(hMenuChk))) - { - ERR("Window does not have a Popup Menu!\n"); + 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); - } - - 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); + } + // 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 (Res) - { - NTSTATUS Status = MmCopyToCaller(pmbi, &kmbi, sizeof(MENUBARINFO)); - if (! NT_SUCCESS(Status)) - { - SetLastNtError(Status); - RETURN(FALSE); - } - } - RETURN(Res); + + if (!hMenu) + RETURN(FALSE); + + _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.hMenu = hMenu; + kmbi.hwndMenu = NULL; + //kmbi.fBarFocused = top_popup_hmenu == hMenu; + if (idItem) + { + PMENU_OBJECT SubMenuObject; + kmbi.fFocused = Menu->MenuInfo.FocusedItem == idItem-1; + + if ( kmbi.fFocused && Menu->MenuItemList->hSubMenu ) + { + SubMenuObject = UserGetMenuObject(Menu->MenuItemList->hSubMenu); + if (SubMenuObject) kmbi.hwndMenu = SubMenuObject->MenuInfo.Wnd; + } + } +/* else + { + kmbi.fFocused = kmbi.fBarFocused; + } +*/ + _SEH2_TRY + { + RtlCopyMemory(pmbi, &kmbi, sizeof(MENUBARINFO)); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + Status = _SEH2_GetExceptionCode(); + } + _SEH2_END + + if (!NT_SUCCESS(Status)) + { + SetLastNtError(Status); + RETURN(FALSE); + } + + 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_); diff --git a/win32ss/user/ntuser/window.c b/win32ss/user/ntuser/window.c index 11ab709d167..9d6e4717697 100644 --- a/win32ss/user/ntuser/window.c +++ b/win32ss/user/ntuser/window.c @@ -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; diff --git a/win32ss/user/user32/windows/menu.c b/win32ss/user/user32/windows/menu.c index f99b8256393..d51492201c3 100644 --- a/win32ss/user/user32/windows/menu.c +++ b/win32ss/user/user32/windows/menu.c @@ -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 ); diff --git a/win32ss/user/winsrv/consrv/condrv/graphics.c b/win32ss/user/winsrv/consrv/condrv/graphics.c index 8932d3856be..3d2805b558f 100644 --- a/win32ss/user/winsrv/consrv/condrv/graphics.c +++ b/win32ss/user/winsrv/consrv/condrv/graphics.c @@ -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; } diff --git a/win32ss/user/winsrv/consrv/condrv/text.c b/win32ss/user/winsrv/consrv/condrv/text.c index 5c1ab108d7e..afe3afe661b 100644 --- a/win32ss/user/winsrv/consrv/condrv/text.c +++ b/win32ss/user/winsrv/consrv/condrv/text.c @@ -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); } diff --git a/win32ss/user/winsrv/consrv/frontends/gui/graphics.c b/win32ss/user/winsrv/consrv/frontends/gui/graphics.c index 3ac9cc24b66..69808518b94 100644 --- a/win32ss/user/winsrv/consrv/frontends/gui/graphics.c +++ b/win32ss/user/winsrv/consrv/frontends/gui/graphics.c @@ -16,19 +16,100 @@ /* 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. diff --git a/win32ss/user/winsrv/consrv/frontends/gui/guisettings.h b/win32ss/user/winsrv/consrv/frontends/gui/guisettings.h index 5041dadedc1..88265cf61e8 100644 --- a/win32ss/user/winsrv/consrv/frontends/gui/guisettings.h +++ b/win32ss/user/winsrv/consrv/frontends/gui/guisettings.h @@ -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) */ diff --git a/win32ss/user/winsrv/consrv/frontends/gui/guiterm.c b/win32ss/user/winsrv/consrv/frontends/gui/guiterm.c index acc870b40eb..e01dbdade3f 100644 --- a/win32ss/user/winsrv/consrv/frontends/gui/guiterm.c +++ b/win32ss/user/winsrv/consrv/frontends/gui/guiterm.c @@ -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)); diff --git a/win32ss/user/winsrv/consrv/frontends/gui/text.c b/win32ss/user/winsrv/consrv/frontends/gui/text.c index 79d5d9b46ff..d39fe614553 100644 --- a/win32ss/user/winsrv/consrv/frontends/gui/text.c +++ b/win32ss/user/winsrv/consrv/frontends/gui/text.c @@ -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. diff --git a/win32ss/user/winsrv/consrv/settings.c b/win32ss/user/winsrv/consrv/settings.c index f765e853d19..1775d1d3e79 100644 --- a/win32ss/user/winsrv/consrv/settings.c +++ b/win32ss/user/winsrv/consrv/settings.c @@ -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) {