Merge branch '86Box:master' into net-add-tap-backend
This commit is contained in:
@@ -144,23 +144,6 @@ plat_cdrom_ext_medium_changed(void *local)
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
plat_cdrom_get_audio_tracks(void *local, int *st_track, int *end, TMSF *lead_out)
|
||||
{
|
||||
dummy_cdrom_ioctl_t *ioctl = (dummy_cdrom_ioctl_t *) local;
|
||||
|
||||
plat_cdrom_read_toc(ioctl);
|
||||
|
||||
*st_track = 1;
|
||||
*end = 1;
|
||||
lead_out->min = 0;
|
||||
lead_out->sec = 0;
|
||||
lead_out->fr = 2;
|
||||
|
||||
dummy_cdrom_ioctl_log("plat_cdrom_get_audio_tracks(): %02i, %02i, %02i:%02i:%02i\n",
|
||||
*st_track, *end, lead_out->min, lead_out->sec, lead_out->fr);
|
||||
}
|
||||
|
||||
/* This replaces both Info and EndInfo, they are specified by a variable. */
|
||||
int
|
||||
plat_cdrom_get_audio_track_info(void *local, UNUSED(int end), int track, int *track_num, TMSF *start, uint8_t *attr)
|
||||
@@ -218,18 +201,14 @@ plat_cdrom_get_sector_size(UNUSED(void *local), UNUSED(uint32_t sector))
|
||||
}
|
||||
|
||||
int
|
||||
plat_cdrom_read_sector(void *local, uint8_t *buffer, int raw, uint32_t sector)
|
||||
plat_cdrom_read_sector(void *local, uint8_t *buffer, uint32_t sector)
|
||||
{
|
||||
dummy_cdrom_ioctl_t *ioctl = (dummy_cdrom_ioctl_t *) local;
|
||||
|
||||
plat_cdrom_open(ioctl);
|
||||
|
||||
if (raw)
|
||||
/* Raw */
|
||||
dummy_cdrom_ioctl_log("Raw\n");
|
||||
else
|
||||
/* Cooked */
|
||||
dummy_cdrom_ioctl_log("Cooked\n");
|
||||
/* Raw */
|
||||
dummy_cdrom_ioctl_log("Raw\n");
|
||||
|
||||
plat_cdrom_close(ioctl);
|
||||
|
||||
|
||||
@@ -43,10 +43,12 @@ Q_IMPORT_PLUGIN(QWindowsVistaStylePlugin)
|
||||
#endif
|
||||
|
||||
#ifdef Q_OS_WINDOWS
|
||||
# include "qt_rendererstack.hpp"
|
||||
# include "qt_winrawinputfilter.hpp"
|
||||
# include "qt_winmanagerfilter.hpp"
|
||||
# include <86box/win.h>
|
||||
# include <shobjidl.h>
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
extern "C" {
|
||||
@@ -81,6 +83,7 @@ extern QElapsedTimer elapsed_timer;
|
||||
extern MainWindow *main_window;
|
||||
|
||||
extern "C" {
|
||||
#include <86box/keyboard.h>
|
||||
#include <86box/timer.h>
|
||||
#include <86box/nvr.h>
|
||||
extern int qt_nvr_save(void);
|
||||
@@ -88,6 +91,177 @@ extern int qt_nvr_save(void);
|
||||
|
||||
void qt_set_sequence_auto_mnemonic(bool b);
|
||||
|
||||
#ifdef Q_OS_WINDOWS
|
||||
static void
|
||||
keyboard_getkeymap()
|
||||
{
|
||||
const LPCSTR keyName = "SYSTEM\\CurrentControlSet\\Control\\Keyboard Layout";
|
||||
const LPCSTR valueName = "Scancode Map";
|
||||
unsigned char buf[32768];
|
||||
DWORD bufSize;
|
||||
HKEY hKey;
|
||||
int j;
|
||||
UINT32 *bufEx2;
|
||||
int scMapCount;
|
||||
UINT16 *bufEx;
|
||||
int scancode_unmapped;
|
||||
int scancode_mapped;
|
||||
|
||||
/* First, prepare the default scan code map list which is 1:1.
|
||||
* Remappings will be inserted directly into it.
|
||||
* 512 bytes so this takes less memory, bit 9 set means E0
|
||||
* prefix.
|
||||
*/
|
||||
for (j = 0; j < 512; j++)
|
||||
scancode_map[j] = j;
|
||||
|
||||
/* Get the scan code remappings from:
|
||||
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout */
|
||||
bufSize = 32768;
|
||||
if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, keyName, 0, 1, &hKey) == ERROR_SUCCESS) {
|
||||
if (RegQueryValueExA(hKey, valueName, NULL, NULL, buf, &bufSize) == ERROR_SUCCESS) {
|
||||
bufEx2 = (UINT32 *) buf;
|
||||
scMapCount = bufEx2[2];
|
||||
if ((bufSize != 0) && (scMapCount != 0)) {
|
||||
bufEx = (UINT16 *) (buf + 12);
|
||||
for (j = 0; j < scMapCount * 2; j += 2) {
|
||||
/* Each scan code is 32-bit: 16 bits of remapped scan code,
|
||||
and 16 bits of original scan code. */
|
||||
scancode_unmapped = bufEx[j + 1];
|
||||
scancode_mapped = bufEx[j];
|
||||
|
||||
scancode_unmapped = convert_scan_code(scancode_unmapped);
|
||||
scancode_mapped = convert_scan_code(scancode_mapped);
|
||||
|
||||
/* Ignore source scan codes with prefixes other than E1
|
||||
that are not E1 1D. */
|
||||
if (scancode_unmapped != 0xFFFF)
|
||||
scancode_map[scancode_unmapped] = scancode_mapped;
|
||||
}
|
||||
}
|
||||
}
|
||||
RegCloseKey(hKey);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
win_keyboard_handle(uint32_t scancode, int up, int e0, int e1)
|
||||
{
|
||||
/* If it's not a scan code that starts with 0xE1 */
|
||||
if (e1) {
|
||||
if (scancode == 0x1D) {
|
||||
scancode = scancode_map[0x100]; /* Translate E1 1D to 0x100 (which would
|
||||
otherwise be E0 00 but that is invalid
|
||||
anyway).
|
||||
Also, take a potential mapping into
|
||||
account. */
|
||||
} else
|
||||
scancode = 0xFFFF;
|
||||
if (scancode != 0xFFFF)
|
||||
keyboard_input(!up, scancode);
|
||||
} else {
|
||||
if (e0)
|
||||
scancode |= 0x100;
|
||||
|
||||
/* Translate the scan code to 9-bit */
|
||||
scancode = convert_scan_code(scancode);
|
||||
|
||||
/* Remap it according to the list from the Registry */
|
||||
if ((scancode < (sizeof(scancode_map) / sizeof(scancode_map[0]))) && (scancode != scancode_map[scancode])) {
|
||||
// pclog("Scan code remap: %03X -> %03X\n", scancode, scancode_map[scancode]);
|
||||
scancode = scancode_map[scancode];
|
||||
}
|
||||
|
||||
/* If it's not 0xFFFF, send it to the emulated
|
||||
keyboard.
|
||||
We use scan code 0xFFFF to mean a mapping that
|
||||
has a prefix other than E0 and that is not E1 1D,
|
||||
which is, for our purposes, invalid. */
|
||||
|
||||
/* Translate right CTRL to left ALT if the user has so
|
||||
chosen. */
|
||||
if ((scancode == 0x11d) && rctrl_is_lalt)
|
||||
scancode = 0x038;
|
||||
|
||||
/* Normal scan code pass through, pass it through as is if
|
||||
it's not an invalid scan code. */
|
||||
if (scancode != 0xFFFF)
|
||||
keyboard_input(!up, scancode);
|
||||
|
||||
main_window->checkFullscreenHotkey();
|
||||
}
|
||||
}
|
||||
|
||||
static LRESULT CALLBACK
|
||||
emu_LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
LPKBDLLHOOKSTRUCT lpKdhs = (LPKBDLLHOOKSTRUCT) lParam;
|
||||
/* Checks if CTRL was pressed. */
|
||||
BOOL bCtrlDown = GetAsyncKeyState (VK_CONTROL) >> ((sizeof(SHORT) * 8) - 1);
|
||||
BOOL is_over_window = (GetForegroundWindow() == ((HWND) main_window->winId()));
|
||||
BOOL ret = TRUE;
|
||||
|
||||
static int last = 0;
|
||||
|
||||
if (show_second_monitors) for (int monitor_index = 1; monitor_index < MONITORS_NUM; monitor_index++) {
|
||||
const auto &secondaryRenderer = main_window->renderers[monitor_index];
|
||||
is_over_window = is_over_window || ((secondaryRenderer != nullptr) &&
|
||||
(GetForegroundWindow() == ((HWND) secondaryRenderer->winId())));
|
||||
}
|
||||
|
||||
if ((nCode < 0) || (nCode != HC_ACTION) || !is_over_window)
|
||||
return CallNextHookEx(NULL, nCode, wParam, lParam);
|
||||
else if ((lpKdhs->scanCode == 0x01) && (lpKdhs->flags & LLKHF_ALTDOWN) &&
|
||||
!(lpKdhs->flags & (LLKHF_UP | LLKHF_EXTENDED)))
|
||||
ret = TRUE;
|
||||
else if ((lpKdhs->scanCode == 0x01) && bCtrlDown && !(lpKdhs->flags & (LLKHF_UP | LLKHF_EXTENDED)))
|
||||
ret = TRUE;
|
||||
else if ((lpKdhs->scanCode == 0x0f) && (lpKdhs->flags & LLKHF_ALTDOWN) &&
|
||||
!(lpKdhs->flags & (LLKHF_UP | LLKHF_EXTENDED)))
|
||||
ret = TRUE;
|
||||
else if ((lpKdhs->scanCode == 0x0f) && bCtrlDown && !(lpKdhs->flags & (LLKHF_UP | LLKHF_EXTENDED)))
|
||||
ret = TRUE;
|
||||
else if ((lpKdhs->scanCode == 0x39) && (lpKdhs->flags & LLKHF_ALTDOWN) &&
|
||||
!(lpKdhs->flags & (LLKHF_UP | LLKHF_EXTENDED)))
|
||||
ret = TRUE;
|
||||
else if ((lpKdhs->scanCode == 0x3e) && (lpKdhs->flags & LLKHF_ALTDOWN) &&
|
||||
!(lpKdhs->flags & (LLKHF_UP | LLKHF_EXTENDED)))
|
||||
ret = TRUE;
|
||||
else if ((lpKdhs->scanCode == 0x49) && bCtrlDown && !(lpKdhs->flags & LLKHF_UP))
|
||||
ret = TRUE;
|
||||
else if ((lpKdhs->scanCode >= 0x5b) && (lpKdhs->scanCode <= 0x5d) && (lpKdhs->flags & LLKHF_EXTENDED))
|
||||
ret = TRUE;
|
||||
else
|
||||
ret = CallNextHookEx(NULL, nCode, wParam, lParam);
|
||||
|
||||
if (lpKdhs->scanCode == 0x00000045) {
|
||||
if ((lpKdhs->flags & LLKHF_EXTENDED) && (lpKdhs->vkCode == 0x00000090)) {
|
||||
/* NumLock. */
|
||||
lpKdhs->flags &= ~LLKHF_EXTENDED;
|
||||
} else if (!(lpKdhs->flags & LLKHF_EXTENDED) && (lpKdhs->vkCode == 0x00000013)) {
|
||||
/* Pause - send E1 1D. */
|
||||
win_keyboard_handle(0xe1, 0, 0, 0);
|
||||
win_keyboard_handle(0x1d, LLKHF_UP, 0, 0);
|
||||
}
|
||||
} else if (!last && (lpKdhs->scanCode == 0x00000036))
|
||||
/* Non-fake right shift. */
|
||||
lpKdhs->flags &= ~LLKHF_EXTENDED;
|
||||
|
||||
if (lpKdhs->scanCode == 0x00000236)
|
||||
last = 1;
|
||||
else if (last && (lpKdhs->scanCode == 0x00000036))
|
||||
last = 0;
|
||||
|
||||
win_keyboard_handle(lpKdhs->scanCode, lpKdhs->flags & LLKHF_UP, lpKdhs->flags & LLKHF_EXTENDED, 0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef Q_OS_WINDOWS
|
||||
static HHOOK llhook = NULL;
|
||||
#endif
|
||||
|
||||
void
|
||||
main_thread_fn()
|
||||
{
|
||||
@@ -149,7 +323,7 @@ main_thread_fn()
|
||||
if (dopause)
|
||||
ack_pause();
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||
plat_delay_ms(1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -157,7 +331,7 @@ main_thread_fn()
|
||||
for (uint8_t i = 1; i < GFXCARD_MAX; i ++) {
|
||||
if (gfxcard[i]) {
|
||||
ui_deinit_monitor(i);
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(500));
|
||||
plat_delay_ms(500);
|
||||
}
|
||||
}
|
||||
QTimer::singleShot(0, QApplication::instance(), []() { QApplication::processEvents(); QApplication::instance()->quit(); });
|
||||
@@ -176,6 +350,7 @@ main(int argc, char *argv[])
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
|
||||
QApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
|
||||
#endif
|
||||
|
||||
QApplication app(argc, argv);
|
||||
QLocale::setDefault(QLocale::C);
|
||||
|
||||
@@ -193,6 +368,13 @@ main(int argc, char *argv[])
|
||||
#endif
|
||||
elapsed_timer.start();
|
||||
|
||||
for (size_t i = 0; i < sizeof(scancode_map) / sizeof(scancode_map[0]); i++)
|
||||
scancode_map[i] = i;
|
||||
|
||||
#ifdef Q_OS_WINDOWS
|
||||
keyboard_getkeymap();
|
||||
#endif
|
||||
|
||||
if (!pc_init(argc, argv)) {
|
||||
return 0;
|
||||
}
|
||||
@@ -340,6 +522,21 @@ main(int argc, char *argv[])
|
||||
});
|
||||
}
|
||||
|
||||
/* Force raw input if a debugger is present. */
|
||||
if (IsDebuggerPresent()) {
|
||||
pclog("WARNING: Debugged detected, forcing raw input\n");
|
||||
hook_enabled = 0;
|
||||
}
|
||||
|
||||
if (hook_enabled) {
|
||||
/* Yes, low-level hooks *DO* work with raw input, at least global ones. */
|
||||
llhook = SetWindowsHookEx(WH_KEYBOARD_LL, emu_LowLevelKeyboardProc, NULL, 0);
|
||||
atexit([] () -> void {
|
||||
if (llhook)
|
||||
UnhookWindowsHookEx(llhook);
|
||||
});
|
||||
}
|
||||
|
||||
/* Setup raw input */
|
||||
auto rawInputFilter = WindowsRawInputFilter::Register(main_window);
|
||||
if (rawInputFilter) {
|
||||
@@ -392,7 +589,6 @@ main(int argc, char *argv[])
|
||||
/* Initialize the rendering window, or fullscreen. */
|
||||
QTimer::singleShot(0, &app, [] {
|
||||
pc_reset_hard_init();
|
||||
main_thread = new std::thread(main_thread_fn);
|
||||
|
||||
/* Set the PAUSE mode depending on the renderer. */
|
||||
#ifdef USE_VNC
|
||||
@@ -401,6 +597,8 @@ main(int argc, char *argv[])
|
||||
else
|
||||
#endif
|
||||
plat_pause(0);
|
||||
|
||||
main_thread = new std::thread(main_thread_fn);
|
||||
});
|
||||
|
||||
const auto ret = app.exec();
|
||||
|
||||
@@ -336,16 +336,20 @@ MediaHistoryManager::removeMissingImages(device_index_list_t &device_history)
|
||||
continue;
|
||||
}
|
||||
|
||||
char temp[MAX_IMAGE_PATH_LEN -1] = { 0 };
|
||||
char temp[MAX_IMAGE_PATH_LEN * 2] = { 0 };
|
||||
|
||||
if (path_abs(checked_path.toUtf8().data())) {
|
||||
if (checked_path.length() > (MAX_IMAGE_PATH_LEN - 1))
|
||||
fatal("removeMissingImages(): checked_path.length() > 2047\n");
|
||||
fatal("removeMissingImages(): checked_path.length() > %i\n", MAX_IMAGE_PATH_LEN - 1);
|
||||
else
|
||||
snprintf(temp, (MAX_IMAGE_PATH_LEN - 1), "%s", checked_path.toUtf8().constData());
|
||||
} else
|
||||
snprintf(temp, (MAX_IMAGE_PATH_LEN - 1), "%s%s%s", usr_path,
|
||||
path_get_slash(usr_path), checked_path.toUtf8().constData());
|
||||
} else {
|
||||
if ((strlen(usr_path) + strlen(path_get_slash(usr_path)) + checked_path.length()) > (MAX_IMAGE_PATH_LEN - 1))
|
||||
fatal("removeMissingImages(): Combined absolute path length > %i\n", MAX_IMAGE_PATH_LEN - 1);
|
||||
else
|
||||
snprintf(temp, (MAX_IMAGE_PATH_LEN - 1), "%s%s%s", usr_path,
|
||||
path_get_slash(usr_path), checked_path.toUtf8().constData());
|
||||
}
|
||||
path_normalize(temp);
|
||||
|
||||
QString qstr = QString::fromUtf8(temp);
|
||||
|
||||
@@ -524,7 +524,8 @@ MediaMenu::cdromMute(int i)
|
||||
void
|
||||
MediaMenu::cdromMount(int i, const QString &filename)
|
||||
{
|
||||
QByteArray fn = filename.toUtf8().data();
|
||||
QByteArray fn = filename.toUtf8().data();
|
||||
int was_empty = cdrom_is_empty(i);
|
||||
|
||||
cdrom_exit(i);
|
||||
|
||||
@@ -542,9 +543,14 @@ MediaMenu::cdromMount(int i, const QString &filename)
|
||||
cdrom_image_open(&(cdrom[i]), fn.data());
|
||||
|
||||
/* Signal media change to the emulated machine. */
|
||||
if (cdrom[i].insert)
|
||||
if (cdrom[i].insert) {
|
||||
cdrom[i].insert(cdrom[i].priv);
|
||||
|
||||
/* The drive was previously empty, transition directly to UNIT ATTENTION. */
|
||||
if (was_empty)
|
||||
cdrom[i].insert(cdrom[i].priv);
|
||||
}
|
||||
|
||||
if (strlen(cdrom[i].image_path) > 0)
|
||||
ui_sb_update_icon_state(SB_CDROM | i, 0);
|
||||
else
|
||||
|
||||
@@ -160,6 +160,7 @@ SettingsPorts::on_pushButtonSerialPassThru4_clicked()
|
||||
DeviceConfig::ConfigureDevice(&serial_passthrough_device, 4, qobject_cast<Settings *>(Settings::settings));
|
||||
}
|
||||
|
||||
#if 0
|
||||
void
|
||||
SettingsPorts::on_pushButtonSerialPassThru5_clicked()
|
||||
{
|
||||
@@ -177,6 +178,7 @@ SettingsPorts::on_pushButtonSerialPassThru7_clicked()
|
||||
{
|
||||
DeviceConfig::ConfigureDevice(&serial_passthrough_device, 7, qobject_cast<Settings *>(Settings::settings));
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
SettingsPorts::on_checkBoxSerialPassThru1_clicked(bool checked)
|
||||
@@ -220,4 +222,4 @@ SettingsPorts::on_checkBoxSerialPassThru7_clicked(bool checked)
|
||||
{
|
||||
ui->pushButtonSerialPassThru7->setEnabled(checked);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -19,45 +19,23 @@ public:
|
||||
#if 0
|
||||
private slots:
|
||||
void on_checkBoxSerialPassThru7_clicked(bool checked);
|
||||
|
||||
private slots:
|
||||
void on_checkBoxSerialPassThru6_clicked(bool checked);
|
||||
|
||||
private slots:
|
||||
void on_checkBoxSerialPassThru5_clicked(bool checked);
|
||||
#endif
|
||||
|
||||
private slots:
|
||||
void on_checkBoxSerialPassThru4_clicked(bool checked);
|
||||
|
||||
private slots:
|
||||
void on_checkBoxSerialPassThru3_clicked(bool checked);
|
||||
|
||||
private slots:
|
||||
void on_checkBoxSerialPassThru2_clicked(bool checked);
|
||||
|
||||
private slots:
|
||||
void on_checkBoxSerialPassThru1_clicked(bool checked);
|
||||
|
||||
private slots:
|
||||
#if 0
|
||||
void on_pushButtonSerialPassThru7_clicked();
|
||||
|
||||
private slots:
|
||||
void on_pushButtonSerialPassThru6_clicked();
|
||||
|
||||
private slots:
|
||||
void on_pushButtonSerialPassThru5_clicked();
|
||||
|
||||
private slots:
|
||||
#endif
|
||||
void on_pushButtonSerialPassThru4_clicked();
|
||||
|
||||
private slots:
|
||||
void on_pushButtonSerialPassThru3_clicked();
|
||||
|
||||
private slots:
|
||||
void on_pushButtonSerialPassThru2_clicked();
|
||||
|
||||
private slots:
|
||||
void on_pushButtonSerialPassThru1_clicked();
|
||||
|
||||
private slots:
|
||||
|
||||
@@ -56,10 +56,22 @@ extern "C" {
|
||||
#include <86box/network.h>
|
||||
#include <86box/machine_status.h>
|
||||
|
||||
#ifdef Q_OS_WINDOWS
|
||||
# include <86box/win.h>
|
||||
#endif
|
||||
|
||||
void
|
||||
plat_delay_ms(uint32_t count)
|
||||
{
|
||||
#ifdef Q_OS_WINDOWS
|
||||
// On Win32 the accuracy of Sleep() depends on the timer resolution, which can be set by calling timeBeginPeriod
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/timeapi/nf-timeapi-timebeginperiod
|
||||
timeBeginPeriod(1);
|
||||
Sleep(count);
|
||||
timeEndPeriod(1);
|
||||
#else
|
||||
QThread::msleep(count);
|
||||
#endif
|
||||
}
|
||||
|
||||
wchar_t *
|
||||
|
||||
@@ -44,6 +44,8 @@
|
||||
#include <86box/plat.h>
|
||||
#include <86box/86box.h>
|
||||
|
||||
extern void win_keyboard_handle(uint32_t scancode, int up, int e0, int e1);
|
||||
|
||||
#include <array>
|
||||
#include <memory>
|
||||
|
||||
@@ -64,8 +66,10 @@ WindowsRawInputFilter::Register(MainWindow *window)
|
||||
.hwndTarget = nullptr}
|
||||
};
|
||||
|
||||
if (RegisterRawInputDevices(rid, 2, sizeof(rid[0])) == FALSE)
|
||||
return std::unique_ptr<WindowsRawInputFilter>(nullptr);
|
||||
if (hook_enabled && (RegisterRawInputDevices(&(rid[1]), 1, sizeof(rid[0])) == FALSE))
|
||||
return std::unique_ptr<WindowsRawInputFilter>(nullptr);
|
||||
else if (!hook_enabled && (RegisterRawInputDevices(rid, 2, sizeof(rid[0])) == FALSE))
|
||||
return std::unique_ptr<WindowsRawInputFilter>(nullptr);
|
||||
|
||||
std::unique_ptr<WindowsRawInputFilter> inputfilter(new WindowsRawInputFilter(window));
|
||||
|
||||
@@ -80,11 +84,6 @@ WindowsRawInputFilter::WindowsRawInputFilter(MainWindow *window)
|
||||
connect(menu, &QMenu::aboutToShow, this, [=]() { menus_open++; });
|
||||
connect(menu, &QMenu::aboutToHide, this, [=]() { menus_open--; });
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < sizeof(scancode_map) / sizeof(scancode_map[0]); i++)
|
||||
scancode_map[i] = i;
|
||||
|
||||
keyboard_getkeymap();
|
||||
}
|
||||
|
||||
WindowsRawInputFilter::~WindowsRawInputFilter()
|
||||
@@ -100,7 +99,10 @@ WindowsRawInputFilter::~WindowsRawInputFilter()
|
||||
.hwndTarget = NULL}
|
||||
};
|
||||
|
||||
RegisterRawInputDevices(rid, 2, sizeof(rid[0]));
|
||||
if (hook_enabled)
|
||||
RegisterRawInputDevices(&(rid[1]), 1, sizeof(rid[0]));
|
||||
else
|
||||
RegisterRawInputDevices(rid, 2, sizeof(rid[0]));
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -158,10 +160,8 @@ WindowsRawInputFilter::handle_input(HRAWINPUT input)
|
||||
mouse_handle(raw);
|
||||
break;
|
||||
case RIM_TYPEHID:
|
||||
{
|
||||
win_joystick_handle(raw);
|
||||
break;
|
||||
}
|
||||
win_joystick_handle(raw);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -171,125 +171,10 @@ WindowsRawInputFilter::handle_input(HRAWINPUT input)
|
||||
void
|
||||
WindowsRawInputFilter::keyboard_handle(PRAWINPUT raw)
|
||||
{
|
||||
USHORT scancode;
|
||||
|
||||
RAWKEYBOARD rawKB = raw->data.keyboard;
|
||||
scancode = rawKB.MakeCode;
|
||||
|
||||
/* If it's not a scan code that starts with 0xE1 */
|
||||
if ((rawKB.Flags & RI_KEY_E1)) {
|
||||
if (rawKB.MakeCode == 0x1D) {
|
||||
scancode = scancode_map[0x100]; /* Translate E1 1D to 0x100 (which would
|
||||
otherwise be E0 00 but that is invalid
|
||||
anyway).
|
||||
Also, take a potential mapping into
|
||||
account. */
|
||||
} else
|
||||
scancode = 0xFFFF;
|
||||
if (scancode != 0xFFFF)
|
||||
keyboard_input(!(rawKB.Flags & RI_KEY_BREAK), scancode);
|
||||
} else {
|
||||
if (rawKB.Flags & RI_KEY_E0)
|
||||
scancode |= 0x100;
|
||||
|
||||
/* Translate the scan code to 9-bit */
|
||||
scancode = convert_scan_code(scancode);
|
||||
|
||||
/* Remap it according to the list from the Registry */
|
||||
if ((scancode < (sizeof(scancode_map) / sizeof(scancode_map[0]))) && (scancode != scancode_map[scancode])) {
|
||||
pclog("Scan code remap: %03X -> %03X\n", scancode, scancode_map[scancode]);
|
||||
scancode = scancode_map[scancode];
|
||||
}
|
||||
|
||||
/* If it's not 0xFFFF, send it to the emulated
|
||||
keyboard.
|
||||
We use scan code 0xFFFF to mean a mapping that
|
||||
has a prefix other than E0 and that is not E1 1D,
|
||||
which is, for our purposes, invalid. */
|
||||
|
||||
/* Translate right CTRL to left ALT if the user has so
|
||||
chosen. */
|
||||
if ((scancode == 0x11d) && rctrl_is_lalt)
|
||||
scancode = 0x038;
|
||||
|
||||
/* Normal scan code pass through, pass it through as is if
|
||||
it's not an invalid scan code. */
|
||||
if (scancode != 0xFFFF)
|
||||
keyboard_input(!(rawKB.Flags & RI_KEY_BREAK), scancode);
|
||||
|
||||
window->checkFullscreenHotkey();
|
||||
}
|
||||
}
|
||||
|
||||
/* This is so we can disambiguate scan codes that would otherwise conflict and get
|
||||
passed on incorrectly. */
|
||||
UINT16
|
||||
WindowsRawInputFilter::convert_scan_code(UINT16 scan_code)
|
||||
{
|
||||
if ((scan_code & 0xff00) == 0xe000)
|
||||
scan_code = (scan_code & 0xff) | 0x0100;
|
||||
|
||||
if (scan_code == 0xE11D)
|
||||
scan_code = 0x0100;
|
||||
/* E0 00 is sent by some USB keyboards for their special keys, as it is an
|
||||
invalid scan code (it has no untranslated set 2 equivalent), we mark it
|
||||
appropriately so it does not get passed through. */
|
||||
else if ((scan_code > 0x01FF) || (scan_code == 0x0100))
|
||||
scan_code = 0xFFFF;
|
||||
|
||||
return scan_code;
|
||||
}
|
||||
|
||||
void
|
||||
WindowsRawInputFilter::keyboard_getkeymap()
|
||||
{
|
||||
const LPCSTR keyName = "SYSTEM\\CurrentControlSet\\Control\\Keyboard Layout";
|
||||
const LPCSTR valueName = "Scancode Map";
|
||||
unsigned char buf[32768];
|
||||
DWORD bufSize;
|
||||
HKEY hKey;
|
||||
int j;
|
||||
UINT32 *bufEx2;
|
||||
int scMapCount;
|
||||
UINT16 *bufEx;
|
||||
int scancode_unmapped;
|
||||
int scancode_mapped;
|
||||
|
||||
/* First, prepare the default scan code map list which is 1:1.
|
||||
* Remappings will be inserted directly into it.
|
||||
* 512 bytes so this takes less memory, bit 9 set means E0
|
||||
* prefix.
|
||||
*/
|
||||
for (j = 0; j < 512; j++)
|
||||
scancode_map[j] = j;
|
||||
|
||||
/* Get the scan code remappings from:
|
||||
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout */
|
||||
bufSize = 32768;
|
||||
if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, keyName, 0, 1, &hKey) == ERROR_SUCCESS) {
|
||||
if (RegQueryValueExA(hKey, valueName, NULL, NULL, buf, &bufSize) == ERROR_SUCCESS) {
|
||||
bufEx2 = (UINT32 *) buf;
|
||||
scMapCount = bufEx2[2];
|
||||
if ((bufSize != 0) && (scMapCount != 0)) {
|
||||
bufEx = (UINT16 *) (buf + 12);
|
||||
for (j = 0; j < scMapCount * 2; j += 2) {
|
||||
/* Each scan code is 32-bit: 16 bits of remapped scan code,
|
||||
and 16 bits of original scan code. */
|
||||
scancode_unmapped = bufEx[j + 1];
|
||||
scancode_mapped = bufEx[j];
|
||||
|
||||
scancode_unmapped = convert_scan_code(scancode_unmapped);
|
||||
scancode_mapped = convert_scan_code(scancode_mapped);
|
||||
|
||||
/* Ignore source scan codes with prefixes other than E1
|
||||
that are not E1 1D. */
|
||||
if (scancode_unmapped != 0xFFFF)
|
||||
scancode_map[scancode_unmapped] = scancode_mapped;
|
||||
}
|
||||
}
|
||||
}
|
||||
RegCloseKey(hKey);
|
||||
}
|
||||
win_keyboard_handle(rawKB.MakeCode, (rawKB.Flags & RI_KEY_BREAK),
|
||||
(rawKB.Flags & RI_KEY_E0), (rawKB.Flags & RI_KEY_E1));
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -61,7 +61,6 @@ public:
|
||||
|
||||
private:
|
||||
MainWindow *window;
|
||||
uint16_t scancode_map[768];
|
||||
int buttons = 0;
|
||||
int dx = 0;
|
||||
int dy = 0;
|
||||
@@ -73,8 +72,6 @@ private:
|
||||
void handle_input(HRAWINPUT input);
|
||||
void keyboard_handle(PRAWINPUT raw);
|
||||
void mouse_handle(PRAWINPUT raw);
|
||||
static UINT16 convert_scan_code(UINT16 scan_code);
|
||||
void keyboard_getkeymap();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "ntddcdrm.h"
|
||||
#include "ntddscsi.h"
|
||||
#include <stdarg.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
@@ -72,12 +73,19 @@ win_cdrom_ioctl_log(const char *fmt, ...)
|
||||
# define win_cdrom_ioctl_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
static void
|
||||
plat_cdrom_close_handle(win_cdrom_ioctl_t *ioctl)
|
||||
{
|
||||
if (ioctl->handle != NULL)
|
||||
CloseHandle(ioctl->handle);
|
||||
}
|
||||
|
||||
static int
|
||||
plat_cdrom_open(void *local)
|
||||
{
|
||||
win_cdrom_ioctl_t *ioctl = (win_cdrom_ioctl_t *) local;
|
||||
|
||||
plat_cdrom_close(local);
|
||||
plat_cdrom_close_handle(local);
|
||||
|
||||
ioctl->handle = CreateFileW((LPCWSTR) ioctl->path, GENERIC_READ | GENERIC_WRITE,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
|
||||
@@ -107,20 +115,47 @@ plat_cdrom_load(void *local)
|
||||
static int
|
||||
plat_cdrom_read_normal_toc(win_cdrom_ioctl_t *ioctl, uint8_t *toc_buf)
|
||||
{
|
||||
long size = 0;
|
||||
long size = 0;
|
||||
PCDROM_TOC_FULL_TOC_DATA cur_full_toc = NULL;
|
||||
|
||||
memset(toc_buf, 0x00, 65536);
|
||||
|
||||
cur_full_toc = (PCDROM_TOC_FULL_TOC_DATA) calloc(1, 65536);
|
||||
if (ioctl->blocks_num != 0) {
|
||||
memset(ioctl->cur_rti, 0x00, ioctl->blocks_num * 11);
|
||||
ioctl->blocks_num = 0;
|
||||
}
|
||||
|
||||
ioctl->cur_read_toc_ex.Format = CDROM_READ_TOC_EX_FORMAT_TOC;
|
||||
win_cdrom_ioctl_log("cur_read_toc_ex.Format = %i\n", ioctl->cur_read_toc_ex.Format);
|
||||
ioctl->cur_read_toc_ex.Msf = 1;
|
||||
ioctl->cur_read_toc_ex.SessionTrack = 0;
|
||||
|
||||
plat_cdrom_open(ioctl);
|
||||
int temp = DeviceIoControl(ioctl->handle, IOCTL_CDROM_READ_TOC, NULL, 0, toc_buf, 65535, (LPDWORD) &size, NULL);
|
||||
int temp = DeviceIoControl(ioctl->handle, IOCTL_CDROM_READ_TOC_EX, &ioctl->cur_read_toc_ex, 65535,
|
||||
cur_full_toc, 65535, (LPDWORD) &size, NULL);
|
||||
plat_cdrom_close(ioctl);
|
||||
#ifdef ENABLE_WIN_CDROM_IOCTL_LOG
|
||||
win_cdrom_ioctl_log("temp = %i\n", temp);
|
||||
|
||||
if (temp != 0) {
|
||||
int length = ((cur_full_toc->Length[0] << 8) | cur_full_toc->Length[1]) + 2;
|
||||
memcpy(toc_buf, cur_full_toc, length);
|
||||
}
|
||||
|
||||
free(cur_full_toc);
|
||||
|
||||
#ifdef ENABLE_WIN_CDROM_IOCTL_LOG
|
||||
PCDROM_TOC toc = (PCDROM_TOC) toc_buf;
|
||||
const int tracks_num = (((toc->Length[0] << 8) | toc->Length[1]) - 2) / 8;
|
||||
win_cdrom_ioctl_log("%i tracks\n", tracks_num);
|
||||
for (int i = 0; i < tracks_num; i++)
|
||||
win_cdrom_ioctl_log("Track %03i: Point %02X\n", i, (int) toc->TrackData[i].TrackNumber);
|
||||
|
||||
win_cdrom_ioctl_log("%i tracks: %02X %02X %02X %02X\n",
|
||||
tracks_num, toc_buf[0], toc_buf[1], toc_buf[2], toc_buf[3]);
|
||||
|
||||
for (int i = 0; i < tracks_num; i++) {
|
||||
uint8_t *t = (uint8_t *) &toc->TrackData[i];
|
||||
win_cdrom_ioctl_log("Track %03i: %02X %02X %02X %02X %02X %02X %02X %02X\n",
|
||||
i, t[0], t[1], t[2], t[3], t[4], t[5], t[6], t[7]);
|
||||
}
|
||||
#endif
|
||||
|
||||
return temp;
|
||||
@@ -130,10 +165,10 @@ static void
|
||||
plat_cdrom_read_raw_toc(win_cdrom_ioctl_t *ioctl)
|
||||
{
|
||||
long size = 0;
|
||||
int status;
|
||||
PCDROM_TOC_FULL_TOC_DATA cur_full_toc = NULL;
|
||||
|
||||
memset(ioctl->cur_rti, 0x00, 65536);
|
||||
|
||||
cur_full_toc = (PCDROM_TOC_FULL_TOC_DATA) calloc(1, 65536);
|
||||
if (ioctl->blocks_num != 0) {
|
||||
memset(ioctl->cur_rti, 0x00, ioctl->blocks_num * 11);
|
||||
@@ -143,11 +178,11 @@ plat_cdrom_read_raw_toc(win_cdrom_ioctl_t *ioctl)
|
||||
ioctl->cur_read_toc_ex.Format = CDROM_READ_TOC_EX_FORMAT_FULL_TOC;
|
||||
win_cdrom_ioctl_log("cur_read_toc_ex.Format = %i\n", ioctl->cur_read_toc_ex.Format);
|
||||
ioctl->cur_read_toc_ex.Msf = 1;
|
||||
ioctl->cur_read_toc_ex.SessionTrack = 1;
|
||||
ioctl->cur_read_toc_ex.SessionTrack = 0;
|
||||
|
||||
plat_cdrom_open(ioctl);
|
||||
status = DeviceIoControl(ioctl->handle, IOCTL_CDROM_READ_TOC_EX, &ioctl->cur_read_toc_ex, 65535,
|
||||
cur_full_toc, 65535, (LPDWORD) &size, NULL);
|
||||
int status = DeviceIoControl(ioctl->handle, IOCTL_CDROM_READ_TOC_EX, &ioctl->cur_read_toc_ex, 65535,
|
||||
cur_full_toc, 65535, (LPDWORD) &size, NULL);
|
||||
plat_cdrom_close(ioctl);
|
||||
win_cdrom_ioctl_log("status = %i\n", status);
|
||||
|
||||
@@ -156,15 +191,21 @@ plat_cdrom_read_raw_toc(win_cdrom_ioctl_t *ioctl)
|
||||
memcpy(ioctl->cur_rti, cur_full_toc->Descriptors, ioctl->blocks_num * 11);
|
||||
}
|
||||
|
||||
free(cur_full_toc);
|
||||
|
||||
#ifdef ENABLE_WIN_CDROM_IOCTL_LOG
|
||||
win_cdrom_ioctl_log("%i blocks\n", ioctl->blocks_num);
|
||||
uint8_t *u = (uint8_t *) cur_full_toc;
|
||||
|
||||
win_cdrom_ioctl_log("%i blocks: %02X %02X %02X %02X\n",
|
||||
ioctl->blocks_num, u[0], u[1], u[2], u[3]);
|
||||
|
||||
raw_track_info_t *rti = (raw_track_info_t *) ioctl->cur_rti;
|
||||
for (int i = 0; i < ioctl->blocks_num; i++)
|
||||
win_cdrom_ioctl_log("Block %03i: Session %03i, Point %02X\n", i, (int) rti[i].session, (int) rti[i].point);
|
||||
for (int i = 0; i < ioctl->blocks_num; i++) {
|
||||
uint8_t *t = (uint8_t *) &rti[i];
|
||||
win_cdrom_ioctl_log("Block %03i: %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n",
|
||||
i, t[0], t[1], t[2], t[3], t[4], t[5], t[6], t[7], t[8], t[9], t[10]);
|
||||
}
|
||||
#endif
|
||||
|
||||
free(cur_full_toc);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -206,7 +247,7 @@ plat_cdrom_is_track_audio(void *local, uint32_t sector)
|
||||
|
||||
win_cdrom_ioctl_log("F: %i, L: %i, C: %i (%i), c: %02X, A: %08X, S: %08X\n",
|
||||
toc->FirstTrack, toc->LastTrack, cur_td->TrackNumber, c,
|
||||
cur_td->Control, track_addr, sector);
|
||||
cur_td->Control, cur_addr, sector);
|
||||
|
||||
if ((cur_td->TrackNumber >= toc->FirstTrack) && (cur_td->TrackNumber <= toc->LastTrack) &&
|
||||
(sector >= cur_addr) && (sector < next_addr)) {
|
||||
@@ -343,35 +384,20 @@ plat_cdrom_ext_medium_changed(void *local)
|
||||
memcpy(toc, new_toc, 65535);
|
||||
if (memcmp(ioctl->path, ioctl->old_path, sizeof(ioctl->path)) != 0)
|
||||
memcpy(ioctl->old_path, ioctl->path, sizeof(ioctl->path));
|
||||
} else if (memcmp(&(new_ltd->Address[1]), &(cur_ltd->Address[1]), 3))
|
||||
} else if (memcmp(&(new_ltd->Address[1]), &(cur_ltd->Address[1]), 3)) {
|
||||
/* The TOC has changed. */
|
||||
ioctl->toc_valid = 1;
|
||||
memcpy(toc, new_toc, 65535);
|
||||
if (memcmp(ioctl->path, ioctl->old_path, sizeof(ioctl->path)) != 0)
|
||||
memcpy(ioctl->old_path, ioctl->path, sizeof(ioctl->path));
|
||||
ret = 1;
|
||||
}
|
||||
|
||||
win_cdrom_ioctl_log("plat_cdrom_ext_medium_changed(): %i\n", ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
plat_cdrom_get_audio_tracks(void *local, int *st_track, int *end, TMSF *lead_out)
|
||||
{
|
||||
win_cdrom_ioctl_t *ioctl = (win_cdrom_ioctl_t *) local;
|
||||
PCDROM_TOC toc = (PCDROM_TOC) ioctl->cur_toc;
|
||||
|
||||
plat_cdrom_read_toc(ioctl);
|
||||
|
||||
PTRACK_DATA ltd = &toc->TrackData[toc->LastTrack];
|
||||
|
||||
*st_track = 1;
|
||||
*end = toc->LastTrack;
|
||||
lead_out->min = ltd->Address[1];
|
||||
lead_out->sec = ltd->Address[2];
|
||||
lead_out->fr = ltd->Address[3];
|
||||
|
||||
win_cdrom_ioctl_log("plat_cdrom_get_audio_tracks(): %02i, %02i, %02i:%02i:%02i\n",
|
||||
*st_track, *end, lead_out->min, lead_out->sec, lead_out->fr);
|
||||
}
|
||||
|
||||
/* This replaces both Info and EndInfo, they are specified by a variable. */
|
||||
int
|
||||
plat_cdrom_get_audio_track_info(void *local, UNUSED(int end), int track, int *track_num, TMSF *start, uint8_t *attr)
|
||||
@@ -458,38 +484,61 @@ plat_cdrom_get_sector_size(void *local, UNUSED(uint32_t sector))
|
||||
}
|
||||
|
||||
int
|
||||
plat_cdrom_read_sector(void *local, uint8_t *buffer, int raw, uint32_t sector)
|
||||
plat_cdrom_read_sector(void *local, uint8_t *buffer, uint32_t sector)
|
||||
{
|
||||
win_cdrom_ioctl_t * ioctl = (win_cdrom_ioctl_t *) local;
|
||||
int status;
|
||||
long size = 0;
|
||||
int buflen = raw ? RAW_SECTOR_SIZE : COOKED_SECTOR_SIZE;
|
||||
typedef struct SCSI_PASS_THROUGH_DIRECT_BUF {
|
||||
SCSI_PASS_THROUGH_DIRECT spt;
|
||||
ULONG Filler;
|
||||
UCHAR SenseBuf[32];
|
||||
} SCSI_PASS_THROUGH_DIRECT_BUF;
|
||||
|
||||
win_cdrom_ioctl_t * ioctl = (win_cdrom_ioctl_t *) local;
|
||||
int sc_offs = (sector == 0xffffffff) ? 0 : 2352;
|
||||
unsigned long int unused = 0;
|
||||
int ret;
|
||||
SCSI_PASS_THROUGH_DIRECT_BUF req;
|
||||
|
||||
memset(&req, 0x00, sizeof(req));
|
||||
req.Filler = 0;
|
||||
req.spt.Length = sizeof(SCSI_PASS_THROUGH_DIRECT);
|
||||
req.spt.CdbLength = 12;
|
||||
req.spt.DataIn = SCSI_IOCTL_DATA_IN;
|
||||
req.spt.SenseInfoOffset = offsetof(SCSI_PASS_THROUGH_DIRECT_BUF, SenseBuf);
|
||||
req.spt.SenseInfoLength = sizeof(req.SenseBuf);
|
||||
req.spt.TimeOutValue = 6;
|
||||
req.spt.DataTransferLength = 2368;
|
||||
req.spt.DataBuffer = buffer;
|
||||
|
||||
/* Fill in the CDB. */
|
||||
req.spt.Cdb[0] = 0xbe; /* READ CD */
|
||||
req.spt.Cdb[1] = 0x00; /* DAP = 0, Any Sector Type. */
|
||||
req.spt.Cdb[2] = (sector >> 24) & 0xff;
|
||||
req.spt.Cdb[3] = (sector >> 16) & 0xff;
|
||||
req.spt.Cdb[4] = (sector >> 8) & 0xff;
|
||||
req.spt.Cdb[5] = sector & 0xff; /* Starting Logical Block Address. */
|
||||
req.spt.Cdb[6] = 0x00;
|
||||
req.spt.Cdb[7] = 0x00;
|
||||
req.spt.Cdb[8] = 0x01; /* Transfer Length. */
|
||||
/* If sector is FFFFFFFF, only return the subchannel. */
|
||||
req.spt.Cdb[9] = (sector == 0xffffffff) ? 0x00 : 0xf8;
|
||||
req.spt.Cdb[10] = 0x02;
|
||||
req.spt.Cdb[11] = 0x00;
|
||||
|
||||
plat_cdrom_open(ioctl);
|
||||
|
||||
if (raw) {
|
||||
/* Raw */
|
||||
win_cdrom_ioctl_log("Raw\n");
|
||||
RAW_READ_INFO in;
|
||||
in.DiskOffset.LowPart = sector * COOKED_SECTOR_SIZE;
|
||||
in.DiskOffset.HighPart = 0;
|
||||
in.SectorCount = 1;
|
||||
in.TrackMode = CDDA;
|
||||
status = DeviceIoControl(ioctl->handle, IOCTL_CDROM_RAW_READ, &in, sizeof(in),
|
||||
buffer, buflen, (LPDWORD) &size, NULL);
|
||||
} else {
|
||||
/* Cooked */
|
||||
win_cdrom_ioctl_log("Cooked\n");
|
||||
int success = 0;
|
||||
DWORD newPos = SetFilePointer(ioctl->handle, sector * COOKED_SECTOR_SIZE, 0, FILE_BEGIN);
|
||||
if (newPos != 0xFFFFFFFF)
|
||||
success = ReadFile(ioctl->handle, buffer, buflen, (LPDWORD) &size, NULL);
|
||||
status = (success != 0);
|
||||
}
|
||||
ret = DeviceIoControl(ioctl->handle, IOCTL_SCSI_PASS_THROUGH_DIRECT, &req, sizeof(req), &req, sizeof(req),
|
||||
&unused, NULL);
|
||||
plat_cdrom_close(ioctl);
|
||||
win_cdrom_ioctl_log("ReadSector status=%d, sector=%d, size=%" PRId64 ".\n", status, sector, (long long) size);
|
||||
|
||||
return (status > 0) ? (size == buflen) : -1;
|
||||
/* Construct raw subchannel data from Q only. */
|
||||
if (ret && (req.spt.DataTransferLength >= 2368))
|
||||
for (int i = 11; i >= 0; i--)
|
||||
for (int j = 7; j >= 0; j--)
|
||||
buffer[2352 + (i * 8) + j] = ((buffer[sc_offs + i] >> (7 - j)) & 0x01) << 6;
|
||||
|
||||
win_cdrom_ioctl_log("plat_cdrom_read_scsi_direct: ret = %d, req.spt.DataTransferLength = %lu\n",
|
||||
ret, req.spt.DataTransferLength);
|
||||
win_cdrom_ioctl_log("Sense: %08X, %08X\n", req.spt.SenseInfoLength, req.spt.SenseInfoOffset);
|
||||
return ret && (req.spt.DataTransferLength >= 2368);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -508,10 +557,8 @@ plat_cdrom_close(void *local)
|
||||
{
|
||||
win_cdrom_ioctl_t *ioctl = (win_cdrom_ioctl_t *) local;
|
||||
|
||||
if (ioctl->handle != NULL) {
|
||||
CloseHandle(ioctl->handle);
|
||||
ioctl->handle = NULL;
|
||||
}
|
||||
plat_cdrom_close_handle(ioctl);
|
||||
ioctl->handle = NULL;
|
||||
}
|
||||
|
||||
int
|
||||
|
||||
Reference in New Issue
Block a user