mirror of
https://github.com/bsnes-emu/bsnes.git
synced 2025-08-26 05:45:05 +02:00
Update to v106r57 release.
byuu says: I've added tool tips to hiro for Windows, GTK, and Qt. I'm unsure how to add them for Cocoa. I wasted am embarrassing ~14 hours implementing tool tips from scratch on Windows, because the `TOOLTIPS_CLASS` widget just absolutely refused to show up, no matter what I tried. As such, they're not quite 100% native, but I would really appreciate any patch submissions to help improve my implementation. I added tool tips to all of the confusing settings in bsnes. And of course, for those of you who don't like them, there's a configuration file setting to turn them off globally. I also improved Mega Drive handling of the Game Genie a bit, and restructured the way the Settings class works in bsnes. Starting now, I'm feature-freezing bsnes and higan. From this point forward: - polishing up and fixing bugs caused by the ruby/hiro changes - adding DRC to XAudio2, and maybe exclusive mode to WGL - correcting FEoEZ (English) to load and work again out of the box Once that's done, a final beta of bsnes will go out, I'll fix any reported bugs that I'm able to, and then v107 should be ready. This time with higan being functional, but marked as v107 beta. v108 will restore higan to production status again, alongside bsnes.
This commit is contained in:
@@ -2,13 +2,6 @@
|
||||
|
||||
namespace hiro {
|
||||
|
||||
vector<pWindow*> pApplication::windows;
|
||||
|
||||
#if defined(DISPLAY_XORG)
|
||||
XlibDisplay* pApplication::display = nullptr;
|
||||
bool pApplication::xdgScreenSaver = false;
|
||||
#endif
|
||||
|
||||
auto pApplication::run() -> void {
|
||||
while(!Application::state().quit) {
|
||||
Application::doMain();
|
||||
@@ -22,7 +15,7 @@ auto pApplication::pendingEvents() -> bool {
|
||||
|
||||
auto pApplication::processEvents() -> void {
|
||||
while(pendingEvents()) gtk_main_iteration_do(false);
|
||||
for(auto& window : windows) window->_synchronizeGeometry();
|
||||
for(auto& window : state().windows) window->_synchronizeGeometry();
|
||||
}
|
||||
|
||||
auto pApplication::quit() -> void {
|
||||
@@ -30,21 +23,54 @@ auto pApplication::quit() -> void {
|
||||
if(gtk_main_level()) gtk_main_quit();
|
||||
|
||||
#if defined(DISPLAY_XORG)
|
||||
XCloseDisplay(display);
|
||||
display = nullptr;
|
||||
if(state().display) {
|
||||
if(state().screenSaverXDG && state().screenSaverWindow) {
|
||||
//this needs to run synchronously, so that XUnmapWindow() won't happen before xdg-screensaver is finished
|
||||
execute("xdg-screensaver", "resume", string{"0x", hex(state().screenSaverWindow)});
|
||||
XUnmapWindow(state().display, state().screenSaverWindow);
|
||||
state().screenSaverWindow = 0;
|
||||
}
|
||||
XCloseDisplay(state().display);
|
||||
state().display = nullptr;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
auto pApplication::setScreenSaver(bool screenSaver) -> void {
|
||||
#if defined(DISPLAY_XORG)
|
||||
for(auto& window : windows) window->_setScreenSaver(screenSaver);
|
||||
if(state().screenSaverXDG && state().screenSaverWindow) {
|
||||
invoke("xdg-screensaver", screenSaver ? "resume" : "suspend", string{"0x", hex(state().screenSaverWindow)});
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
auto pApplication::state() -> State& {
|
||||
static State state;
|
||||
return state;
|
||||
}
|
||||
|
||||
auto pApplication::initialize() -> void {
|
||||
#if defined(DISPLAY_XORG)
|
||||
display = XOpenDisplay(nullptr);
|
||||
xdgScreenSaver = (bool)execute("xdg-screensaver", "--version").output.find("xdg-screensaver");
|
||||
state().display = XOpenDisplay(nullptr);
|
||||
state().screenSaverXDG = (bool)execute("xdg-screensaver", "--version").output.find("xdg-screensaver");
|
||||
|
||||
if(state().screenSaverXDG) {
|
||||
auto screen = DefaultScreen(state().display);
|
||||
auto rootWindow = RootWindow(state().display, screen);
|
||||
XSetWindowAttributes attributes{};
|
||||
attributes.background_pixel = BlackPixel(state().display, screen);
|
||||
attributes.border_pixel = 0;
|
||||
attributes.override_redirect = true;
|
||||
state().screenSaverWindow = XCreateWindow(state().display, rootWindow,
|
||||
0, 0, 1, 1, 0, DefaultDepth(state().display, screen),
|
||||
InputOutput, DefaultVisual(state().display, screen),
|
||||
CWBackPixel | CWBorderPixel | CWOverrideRedirect, &attributes
|
||||
);
|
||||
//note: hopefully xdg-screensaver does not require the window to be mapped ...
|
||||
//if it does, we're in trouble: a small 1x1 black pixel window will be visible in said case
|
||||
XMapWindow(state().display, state().screenSaverWindow);
|
||||
XFlush(state().display);
|
||||
}
|
||||
#endif
|
||||
|
||||
//set WM_CLASS to Application::name()
|
||||
|
@@ -11,12 +11,17 @@ struct pApplication {
|
||||
|
||||
static auto initialize() -> void;
|
||||
|
||||
static vector<pWindow*> windows;
|
||||
struct State {
|
||||
vector<pWindow*> windows;
|
||||
|
||||
#if defined(DISPLAY_XORG)
|
||||
static XlibDisplay* display;
|
||||
static bool xdgScreenSaver;
|
||||
#endif
|
||||
#if defined(DISPLAY_XORG)
|
||||
XlibDisplay* display = nullptr;
|
||||
XlibWindow screenSaverWindow = 0;
|
||||
bool screenSaverXDG = false;
|
||||
#endif
|
||||
};
|
||||
|
||||
static auto state() -> State&;
|
||||
};
|
||||
|
||||
}
|
||||
|
@@ -8,7 +8,7 @@ auto pKeyboard::poll() -> vector<bool> {
|
||||
vector<bool> result;
|
||||
char state[256];
|
||||
#if defined(DISPLAY_XORG)
|
||||
XQueryKeymap(pApplication::display, state);
|
||||
XQueryKeymap(pApplication::state().display, state);
|
||||
#endif
|
||||
for(auto& code : settings.keycodes) {
|
||||
result.append(_pressed(state, code));
|
||||
@@ -19,7 +19,7 @@ auto pKeyboard::poll() -> vector<bool> {
|
||||
auto pKeyboard::pressed(unsigned code) -> bool {
|
||||
char state[256];
|
||||
#if defined(DISPLAY_XORG)
|
||||
XQueryKeymap(pApplication::display, state);
|
||||
XQueryKeymap(pApplication::state().display, state);
|
||||
#endif
|
||||
return _pressed(state, code);
|
||||
}
|
||||
@@ -226,8 +226,8 @@ auto pKeyboard::_translate(unsigned code) -> signed {
|
||||
auto pKeyboard::initialize() -> void {
|
||||
auto append = [](unsigned lo, unsigned hi = 0) {
|
||||
#if defined(DISPLAY_XORG)
|
||||
lo = lo ? (uint8_t)XKeysymToKeycode(pApplication::display, lo) : 0;
|
||||
hi = hi ? (uint8_t)XKeysymToKeycode(pApplication::display, hi) : 0;
|
||||
lo = lo ? (uint8_t)XKeysymToKeycode(pApplication::state().display, lo) : 0;
|
||||
hi = hi ? (uint8_t)XKeysymToKeycode(pApplication::state().display, hi) : 0;
|
||||
#endif
|
||||
settings.keycodes.append(lo | (hi << 8));
|
||||
};
|
||||
|
@@ -13,7 +13,7 @@ auto pMouse::position() -> Position {
|
||||
XlibWindow root, child;
|
||||
int rootx, rooty, winx, winy;
|
||||
unsigned int mask;
|
||||
XQueryPointer(pApplication::display, DefaultRootWindow(pApplication::display), &root, &child, &rootx, &rooty, &winx, &winy, &mask);
|
||||
XQueryPointer(pApplication::state().display, DefaultRootWindow(pApplication::state().display), &root, &child, &rootx, &rooty, &winx, &winy, &mask);
|
||||
return {rootx, rooty};
|
||||
#endif
|
||||
}
|
||||
@@ -31,7 +31,7 @@ auto pMouse::pressed(Mouse::Button button) -> bool {
|
||||
XlibWindow root, child;
|
||||
int rootx, rooty, winx, winy;
|
||||
unsigned int mask;
|
||||
XQueryPointer(pApplication::display, DefaultRootWindow(pApplication::display), &root, &child, &rootx, &rooty, &winx, &winy, &mask);
|
||||
XQueryPointer(pApplication::state().display, DefaultRootWindow(pApplication::state().display), &root, &child, &rootx, &rooty, &winx, &winy, &mask);
|
||||
switch(button) {
|
||||
case Mouse::Button::Left: return mask & Button1Mask;
|
||||
case Mouse::Button::Middle: return mask & Button2Mask;
|
||||
|
@@ -13,6 +13,7 @@ auto pSizable::minimumSize() const -> Size {
|
||||
}
|
||||
|
||||
auto pSizable::setGeometry(Geometry geometry) -> void {
|
||||
self().doSize();
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -6,7 +6,9 @@ auto pWidget::construct() -> void {
|
||||
if(!gtkWidget) return;
|
||||
if(auto window = self().parentWindow(true)) {
|
||||
if(window->self()) window->self()->_append(self());
|
||||
setEnabled(self().enabled(true));
|
||||
setFont(self().font(true));
|
||||
setToolTip(self().toolTip());
|
||||
setVisible(self().visible(true));
|
||||
}
|
||||
}
|
||||
@@ -58,7 +60,11 @@ auto pWidget::setGeometry(Geometry geometry) -> void {
|
||||
locked = false;
|
||||
}
|
||||
}
|
||||
self().doSize();
|
||||
pSizable::setGeometry(geometry);
|
||||
}
|
||||
|
||||
auto pWidget::setToolTip(const string& toolTip) -> void {
|
||||
gtk_widget_set_tooltip_text(gtkWidget, toolTip);
|
||||
}
|
||||
|
||||
auto pWidget::setVisible(bool visible) -> void {
|
||||
|
@@ -11,6 +11,7 @@ struct pWidget : pSizable {
|
||||
auto setFocused() -> void override;
|
||||
auto setFont(const Font& font) -> void override;
|
||||
auto setGeometry(Geometry geometry) -> void override;
|
||||
auto setToolTip(const string& toolTip) -> void;
|
||||
auto setVisible(bool visible) -> void override;
|
||||
|
||||
GtkWidget* gtkWidget = nullptr;
|
||||
|
@@ -100,7 +100,6 @@ static auto Window_keyRelease(GtkWidget* widget, GdkEventKey* event, pWindow* p)
|
||||
}
|
||||
|
||||
static auto Window_realize(GtkWidget* widget, pWindow* p) -> void {
|
||||
p->_setScreenSaver(Application::screenSaver());
|
||||
}
|
||||
|
||||
static auto Window_sizeAllocate(GtkWidget* widget, GtkAllocation* allocation, pWindow* p) -> void {
|
||||
@@ -130,7 +129,6 @@ static auto Window_stateEvent(GtkWidget* widget, GdkEvent* event, pWindow* p) ->
|
||||
}
|
||||
|
||||
static auto Window_unrealize(GtkWidget* widget, pWindow* p) -> void {
|
||||
p->_setScreenSaver(true);
|
||||
}
|
||||
|
||||
auto pWindow::construct() -> void {
|
||||
@@ -209,13 +207,13 @@ auto pWindow::construct() -> void {
|
||||
g_object_set_data(G_OBJECT(widget), "hiro::window", (gpointer)this);
|
||||
g_object_set_data(G_OBJECT(formContainer), "hiro::window", (gpointer)this);
|
||||
|
||||
pApplication::windows.append(this);
|
||||
pApplication::state().windows.append(this);
|
||||
}
|
||||
|
||||
auto pWindow::destruct() -> void {
|
||||
for(uint offset : range(pApplication::windows.size())) {
|
||||
if(pApplication::windows[offset] == this) {
|
||||
pApplication::windows.remove(offset);
|
||||
for(uint offset : range(pApplication::state().windows.size())) {
|
||||
if(pApplication::state().windows[offset] == this) {
|
||||
pApplication::state().windows.remove(offset);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -495,19 +493,6 @@ auto pWindow::_setMenuVisible(bool visible) -> void {
|
||||
gtk_widget_set_visible(gtkMenu, visible);
|
||||
}
|
||||
|
||||
auto pWindow::_setScreenSaver(bool screenSaver) -> void {
|
||||
if(!gtk_widget_get_realized(widget)) return;
|
||||
|
||||
#if defined(DISPLAY_XORG)
|
||||
if(pApplication::xdgScreenSaver) {
|
||||
if(this->screenSaver != screenSaver) {
|
||||
this->screenSaver = screenSaver;
|
||||
invoke("xdg-screensaver", screenSaver ? "resume" : "suspend", string{"0x", hex(handle())});
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
auto pWindow::_setStatusEnabled(bool enabled) -> void {
|
||||
gtk_widget_set_sensitive(gtkStatus, enabled);
|
||||
}
|
||||
|
@@ -35,7 +35,6 @@ struct pWindow : pObject {
|
||||
auto _append(mMenu& menu) -> void;
|
||||
auto _menuHeight() const -> int;
|
||||
auto _menuTextHeight() const -> int;
|
||||
auto _setScreenSaver(bool screenSaver) -> void;
|
||||
auto _setIcon(const string& basename) -> bool;
|
||||
auto _setMenuEnabled(bool enabled) -> void;
|
||||
auto _setMenuFont(const Font& font) -> void;
|
||||
|
Reference in New Issue
Block a user