Merge pull request #1417 from emoose/xnotify-fixes
[Kernel] Make XamShow*UI exports send XN_SYS_UI notifications, & small XNotifyListener fix.
This commit is contained in:
commit
9d924950cc
|
@ -111,6 +111,9 @@ dword_result_t XamShowMessageBoxUI(dword_t user_index, lpwstring_t title_ptr,
|
|||
buttons.push_back(button);
|
||||
}
|
||||
|
||||
// Broadcast XN_SYS_UI = true
|
||||
kernel_state()->BroadcastNotification(0x9, true);
|
||||
|
||||
uint32_t chosen_button;
|
||||
if (cvars::headless) {
|
||||
// Auto-pick the focused button.
|
||||
|
@ -144,6 +147,9 @@ dword_result_t XamShowMessageBoxUI(dword_t user_index, lpwstring_t title_ptr,
|
|||
}
|
||||
*result_ptr = chosen_button;
|
||||
|
||||
// Broadcast XN_SYS_UI = false
|
||||
kernel_state()->BroadcastNotification(0x9, false);
|
||||
|
||||
if (overlapped) {
|
||||
kernel_state()->CompleteOverlappedImmediate(overlapped, X_ERROR_SUCCESS);
|
||||
return X_ERROR_IO_PENDING;
|
||||
|
@ -232,6 +238,9 @@ dword_result_t XamShowKeyboardUI(dword_t user_index, dword_t flags,
|
|||
return X_ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
// Broadcast XN_SYS_UI = true
|
||||
kernel_state()->BroadcastNotification(0x9, true);
|
||||
|
||||
if (cvars::headless) {
|
||||
// Redirect default_text back into the buffer.
|
||||
std::memset(buffer, 0, buffer_length * 2);
|
||||
|
@ -239,6 +248,9 @@ dword_result_t XamShowKeyboardUI(dword_t user_index, dword_t flags,
|
|||
xe::store_and_swap<std::wstring>(buffer, default_text.value());
|
||||
}
|
||||
|
||||
// Broadcast XN_SYS_UI = false
|
||||
kernel_state()->BroadcastNotification(0x9, false);
|
||||
|
||||
if (overlapped) {
|
||||
kernel_state()->CompleteOverlappedImmediate(overlapped, X_ERROR_SUCCESS);
|
||||
return X_ERROR_IO_PENDING;
|
||||
|
@ -269,6 +281,9 @@ dword_result_t XamShowKeyboardUI(dword_t user_index, dword_t flags,
|
|||
out_text = out_text.substr(0, buffer_length - 1);
|
||||
xe::store_and_swap<std::wstring>(buffer, out_text);
|
||||
|
||||
// Broadcast XN_SYS_UI = false
|
||||
kernel_state()->BroadcastNotification(0x9, false);
|
||||
|
||||
if (overlapped) {
|
||||
kernel_state()->CompleteOverlappedImmediate(overlapped, X_ERROR_SUCCESS);
|
||||
return X_ERROR_IO_PENDING;
|
||||
|
@ -300,6 +315,10 @@ dword_result_t XamShowDeviceSelectorUI(dword_t user_index, dword_t content_type,
|
|||
break;
|
||||
}
|
||||
|
||||
// Broadcast XN_SYS_UI = true followed by XN_SYS_UI = false
|
||||
kernel_state()->BroadcastNotification(0x9, true);
|
||||
kernel_state()->BroadcastNotification(0x9, false);
|
||||
|
||||
if (overlapped) {
|
||||
kernel_state()->CompleteOverlappedImmediate(overlapped, X_ERROR_SUCCESS);
|
||||
return X_ERROR_IO_PENDING;
|
||||
|
|
|
@ -36,14 +36,7 @@ void XNotifyListener::EnqueueNotification(XNotificationID id, uint32_t data) {
|
|||
}
|
||||
|
||||
auto global_lock = global_critical_region_.Acquire();
|
||||
if (notifications_.count(id)) {
|
||||
// Already exists. Overwrite.
|
||||
notifications_[id] = data;
|
||||
} else {
|
||||
// New.
|
||||
notification_count_++;
|
||||
notifications_.insert({id, data});
|
||||
}
|
||||
notifications_.push_back(std::pair<XNotificationID, uint32_t>(id, data));
|
||||
wait_handle_->Set();
|
||||
}
|
||||
|
||||
|
@ -51,14 +44,13 @@ bool XNotifyListener::DequeueNotification(XNotificationID* out_id,
|
|||
uint32_t* out_data) {
|
||||
auto global_lock = global_critical_region_.Acquire();
|
||||
bool dequeued = false;
|
||||
if (notification_count_) {
|
||||
if (notifications_.size()) {
|
||||
dequeued = true;
|
||||
auto it = notifications_.begin();
|
||||
*out_id = it->first;
|
||||
*out_data = it->second;
|
||||
notifications_.erase(it);
|
||||
notification_count_--;
|
||||
if (!notification_count_) {
|
||||
if (!notifications_.size()) {
|
||||
wait_handle_->Reset();
|
||||
}
|
||||
}
|
||||
|
@ -69,17 +61,22 @@ bool XNotifyListener::DequeueNotification(XNotificationID id,
|
|||
uint32_t* out_data) {
|
||||
auto global_lock = global_critical_region_.Acquire();
|
||||
bool dequeued = false;
|
||||
if (notification_count_) {
|
||||
auto it = notifications_.find(id);
|
||||
if (it != notifications_.end()) {
|
||||
if (!notifications_.size()) {
|
||||
return dequeued;
|
||||
}
|
||||
|
||||
for (auto it = notifications_.begin(); it != notifications_.end(); ++it) {
|
||||
if (it->first != id) {
|
||||
continue;
|
||||
}
|
||||
|
||||
dequeued = true;
|
||||
*out_data = it->second;
|
||||
notifications_.erase(it);
|
||||
notification_count_--;
|
||||
if (!notification_count_) {
|
||||
if (!notifications_.size()) {
|
||||
wait_handle_->Reset();
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
return dequeued;
|
||||
}
|
||||
|
@ -88,8 +85,8 @@ bool XNotifyListener::Save(ByteStream* stream) {
|
|||
SaveObject(stream);
|
||||
|
||||
stream->Write(mask_);
|
||||
stream->Write(notification_count_);
|
||||
if (notification_count_) {
|
||||
stream->Write(notifications_.size());
|
||||
if (notifications_.size()) {
|
||||
for (auto pair : notifications_) {
|
||||
stream->Write<uint32_t>(pair.first);
|
||||
stream->Write<uint32_t>(pair.second);
|
||||
|
@ -107,12 +104,12 @@ object_ref<XNotifyListener> XNotifyListener::Restore(KernelState* kernel_state,
|
|||
notify->RestoreObject(stream);
|
||||
notify->Initialize(stream->Read<uint64_t>());
|
||||
|
||||
notify->notification_count_ = stream->Read<size_t>();
|
||||
for (size_t i = 0; i < notify->notification_count_; i++) {
|
||||
auto notification_count_ = stream->Read<size_t>();
|
||||
for (size_t i = 0; i < notification_count_; i++) {
|
||||
std::pair<XNotificationID, uint32_t> pair;
|
||||
pair.first = stream->Read<uint32_t>();
|
||||
pair.second = stream->Read<uint32_t>();
|
||||
notify->notifications_.insert(pair);
|
||||
notify->notifications_.push_back(pair);
|
||||
}
|
||||
|
||||
return object_ref<XNotifyListener>(notify);
|
||||
|
|
|
@ -48,8 +48,7 @@ class XNotifyListener : public XObject {
|
|||
private:
|
||||
std::unique_ptr<xe::threading::Event> wait_handle_;
|
||||
xe::global_critical_region global_critical_region_;
|
||||
std::unordered_map<XNotificationID, uint32_t> notifications_;
|
||||
size_t notification_count_ = 0;
|
||||
std::vector<std::pair<XNotificationID, uint32_t>> notifications_;
|
||||
uint64_t mask_ = 0;
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue