From: Ray Chason Date: Sat, 19 Nov 2022 14:14:54 +0000 (-0500) Subject: Restore compatibility with Qt 4 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=890853a03de2367e99b39514188a8e2bcf59f47d;p=nethack Restore compatibility with Qt 4 The test system is Slackware 14.2, which uses Qt 4.8.7. * WANT_WIN_QT4 is defined, and has the expected meaning. Qt 5 is still the default. * The QT_NO_SOUND macro now excludes all headers and declarations relating to sound; the multimedia package is not needed to build (on any Qt 4, 5 or 6). * A new function, nh_qsprintf, replaces QString::asprintf, for Qt older than 5.5. These versions do not have QString::asprintf. * DYNAMIC_STATUSLINES is disabled for Qt older than 5.9. These versions do not have QSplitter::replaceWidget. --- diff --git a/sys/unix/hints/include/multiw-2.370 b/sys/unix/hints/include/multiw-2.370 index b3dc021e6..9579608f5 100644 --- a/sys/unix/hints/include/multiw-2.370 +++ b/sys/unix/hints/include/multiw-2.370 @@ -106,6 +106,11 @@ ifndef WANT_WIN_QT ifdef WANT_WIN_ALL WANT_WIN_QT=1 endif +ifdef WANT_WIN_QT4 +ifndef WANT_WIN_QT +WANT_WIN_QT=1 +endif # not WANT_WIN_QT +endif # WANT_WIN_QT4 ifdef WANT_WIN_QT5 ifndef WANT_WIN_QT WANT_WIN_QT=1 @@ -120,11 +125,19 @@ endif # not def WANT_WIN_QT ifdef WANT_WIN_QT # WANT_WIN_QT5 is the default +ifndef WANT_WIN_QT4 ifndef WANT_WIN_QT5 ifndef WANT_WIN_QT6 WANT_WIN_QT5=1 endif # not WANT_WIN_QT6 endif # not WANT_WIN_QT5 +endif # not WANT_WIN_QT4 +ifdef WANT_WIN_QT4 +#Slackware 14.2 puts Qt4 here +#if your Qt4 is elsewhere, change this to match +QT4DIR=/usr/lib64/qt +QTDIR=$(QT4DIR) +endif # WANT_WIN_QT4 endif # WANT_WIN_QT ifdef WANT_WIN_QT diff --git a/sys/unix/hints/linux.370 b/sys/unix/hints/linux.370 index d7adbf90e..69e9e8993 100755 --- a/sys/unix/hints/linux.370 +++ b/sys/unix/hints/linux.370 @@ -154,6 +154,10 @@ endif # WANT_WIN_X11 ifdef WANT_WIN_QT LINK = $(CXX) +ifdef WANT_WIN_QT4 +QTCXXFLAGS += $(sort $(shell PKG_CONFIG_PATH=$(QTDIR)/lib/pkgconfig pkg-config QtGui --cflags)) -DQT_NO_SOUND=1 +WINLIB += $(shell PKG_CONFIG_PATH=$(QTDIR)/lib/pkgconfig pkg-config QtGui --libs) +endif # WANT_WIN_QT4 ifdef WANT_WIN_QT5 QTCXXFLAGS += $(sort $(shell PKG_CONFIG_PATH=$(QTDIR)/lib/pkgconfig pkg-config Qt5Gui Qt5Widgets Qt5Multimedia --cflags)) WINLIB += $(shell PKG_CONFIG_PATH=$(QTDIR)/lib/pkgconfig pkg-config Qt5Gui Qt5Widgets Qt5Multimedia --libs) diff --git a/win/Qt/qt_bind.cpp b/win/Qt/qt_bind.cpp index 98057aea8..f1c752526 100644 --- a/win/Qt/qt_bind.cpp +++ b/win/Qt/qt_bind.cpp @@ -11,6 +11,7 @@ extern "C" { #include "qt_pre.h" #include #include +#if defined(USER_SOUNDS) && !defined(QT_NO_SOUND) #if QT_VERSION < 0x050000 #include #elif QT_VERSION < 0x060000 @@ -21,6 +22,7 @@ extern "C" { #include #include #endif /* QT_VERSION */ +#endif /* USER_SOUNDS && !QT_NO_SOUND */ #include "qt_post.h" #include "qt_bind.h" #include "qt_click.h" @@ -446,7 +448,7 @@ void NetHackQtBind::qt_display_file(const char *filename, boolean must_exist) } if (complain) { - QString message = QString::asprintf("File not found: %s\n",filename); + QString message = nh_qsprintf("File not found: %s\n",filename); QMessageBox::warning(NULL, "File Error", message, QMessageBox::Ignore); } } @@ -1118,7 +1120,9 @@ struct window_procs Qt_procs = { #ifndef WIN32 extern "C" void play_usersound(const char *, int); +#if defined(USER_SOUNDS) && !defined(QT_NO_SOUND) QSoundEffect *effect = NULL; +#endif /* called from core, sounds.c */ void diff --git a/win/Qt/qt_glyph.cpp b/win/Qt/qt_glyph.cpp index abb1a7254..98691bea7 100644 --- a/win/Qt/qt_glyph.cpp +++ b/win/Qt/qt_glyph.cpp @@ -63,10 +63,10 @@ NetHackQtGlyphs::NetHackQtGlyphs() if (!tile_file) { tilesok = FALSE; - QString msg = QString::asprintf("Cannot load '%s'.", - user_tiles ? tile_list[0] - // mismatched quotes match format - : "nhtiles.bmp' or 'x11tiles"); + QString msg = nh_qsprintf("Cannot load '%s'.", + user_tiles ? tile_list[0] + // mismatched quotes match format + : "nhtiles.bmp' or 'x11tiles"); QMessageBox::warning(0, "IO Error", msg); } else { if (img.width() % tiles_per_row) { diff --git a/win/Qt/qt_icon.cpp b/win/Qt/qt_icon.cpp index 2c07ccbce..488584f0c 100644 --- a/win/Qt/qt_icon.cpp +++ b/win/Qt/qt_icon.cpp @@ -35,6 +35,7 @@ extern "C" { #endif #include "qt_post.h" #include "qt_icon.h" +#include "qt_str.h" namespace nethack_qt_ { @@ -106,7 +107,7 @@ void NetHackQtLabelledIcon::setLabel(const QString& t, long v, long cv, if (v==NoNum) { buf = ""; } else { - buf = QString::asprintf("%ld", v); + buf = nh_qsprintf("%ld", v); } setLabel(t + buf + tail, cv < prev_value); prev_value=cv; diff --git a/win/Qt/qt_main.cpp b/win/Qt/qt_main.cpp index f61f70d1e..43cdb1567 100644 --- a/win/Qt/qt_main.cpp +++ b/win/Qt/qt_main.cpp @@ -13,7 +13,7 @@ extern "C" { #include #if QT_VERSION >= 0x060000 #include -#else +#elif QT_VERSION >= 0x050000 #include #endif @@ -463,7 +463,7 @@ aboutMsg() *p = '\0'; /* it's also long; break it into two pieces */ (void) strsubst(vbuf, " - ", "\n- "); - QString msg = QString::asprintf( + QString msg = nh_qsprintf( // format "NetHack-Qt is a version of NetHack built using" // no newline #ifdef KDE @@ -1034,7 +1034,7 @@ void NetHackQtMainWindow::doQuit(bool) // nethack's #quit command itself) but this routine is unconditional // in case someone wants to change that #ifdef MACOS - QString info = QString::asprintf("This will end your NetHack session.%s", + QString info = nh_qsprintf("This will end your NetHack session.%s", !g.program_state.something_worth_saving ? "" : "\n(Cancel quitting and use the Save command" "\nto save your current game.)"); diff --git a/win/Qt/qt_main.h b/win/Qt/qt_main.h index e2eaacad4..6925d156e 100644 --- a/win/Qt/qt_main.h +++ b/win/Qt/qt_main.h @@ -17,7 +17,9 @@ // Allow changing 'statuslines:2' to 'statuslines:3' or vice versa // while the game is running; deletes and re-creates the status window. // [Used in qt_bind.cpp and qt_main.cpp, but not referenced in qt_stat.cpp.] +#if QT_VERSION >= QT_VERSION_CHECK(5, 9, 0) #define DYNAMIC_STATUSLINES +#endif // NetHackQtBind::notify() doesn't see ^V on OSX #ifdef MACOS diff --git a/win/Qt/qt_menu.cpp b/win/Qt/qt_menu.cpp index ad2160d2b..06605fcd8 100644 --- a/win/Qt/qt_menu.cpp +++ b/win/Qt/qt_menu.cpp @@ -383,8 +383,8 @@ void NetHackQtMenuWindow::PadMenuColumns(bool split_descr) QFontMetrics fm(table->font()); QString col0width_str = ""; if (biggestcount > 0L) - col0width_str = QString::asprintf("%*ld", std::max(countdigits, 1), - biggestcount); + col0width_str = nh_qsprintf("%*ld", std::max(countdigits, 1), + biggestcount); int col0width_int = (int) fm.QFM_WIDTH(col0width_str) + MENU_WIDTH_SLOP; if (col0width_int > table->columnWidth(0)) WidenColumn(0, col0width_int); @@ -427,7 +427,7 @@ void NetHackQtMenuWindow::PadMenuColumns(bool split_descr) QString Amt = ""; long amt = count(row); // fetch item(row,0) as a number if (amt > 0L) - Amt = QString::asprintf("%*ld", countdigits, amt); + Amt = nh_qsprintf("%*ld", countdigits, amt); cnt->setText(Amt); } @@ -470,8 +470,7 @@ void NetHackQtMenuWindow::UpdateCountColumn(long newcount) } else { biggestcount = std::max(biggestcount, newcount); QString num; - num = QString::asprintf("%*ld", std::max(countdigits, 1), - biggestcount); + num = nh_qsprintf("%*ld", std::max(countdigits, 1), biggestcount); int numlen = (int) num.length(); if (numlen % 2) ++numlen; @@ -903,7 +902,7 @@ void NetHackQtMenuWindow::ToggleSelect(int row, bool already_toggled) amt = count(row); // fetch item(row,0) as a number QString Amt = ""; if (amt > 0L) - Amt = QString::asprintf("%*ld", countdigits, amt); + Amt = nh_qsprintf("%*ld", countdigits, amt); countfield->setText(Amt); // store right-justified value } ClearCount(); // blank out 'countstr' and reset 'counting' diff --git a/win/Qt/qt_rip.cpp b/win/Qt/qt_rip.cpp index bcf105688..cb2873dba 100644 --- a/win/Qt/qt_rip.cpp +++ b/win/Qt/qt_rip.cpp @@ -36,7 +36,7 @@ tryload(QPixmap& pm, const char* fn) { if (!pm.load(fn)) { QString msg; - msg = QString::asprintf("Cannot load \"%s\"", fn); + msg = nh_qsprintf("Cannot load \"%s\"", fn); QMessageBox::warning(NetHackQtBind::mainWidget(), "IO Error", msg); } } diff --git a/win/Qt/qt_stat.cpp b/win/Qt/qt_stat.cpp index 522e9ef37..00c796a74 100644 --- a/win/Qt/qt_stat.cpp +++ b/win/Qt/qt_stat.cpp @@ -643,8 +643,7 @@ void NetHackQtStatusWindow::HitpointBar() geoH.setRight(std::min(lox + pxl_health - 1, hix)); hpbar_health.setGeometry(geoH); w = geoH.right() - geoH.left() + 1; // might yield 0 (ie, if dead) - styleH = QString::asprintf(styleformat, barcolors[colorindx][0], - w, w); + styleH = nh_qsprintf(styleformat, barcolors[colorindx][0], w, w); hpbar_health.setStyleSheet(styleH); // when healing, having the old injury-side shown while the new // health-side expands pushes the injury farther right and it's @@ -657,8 +656,7 @@ void NetHackQtStatusWindow::HitpointBar() geoI.setRight(hix); hpbar_injury.setGeometry(geoI); w = geoI.right() - geoI.left() + 1; - styleI = QString::asprintf(styleformat, barcolors[colorindx][1], - w, w); + styleI = nh_qsprintf(styleformat, barcolors[colorindx][1], w, w); hpbar_injury.setStyleSheet(styleI); if (geoI.left() != oldleft) hpbar_injury.move(geoI.left(), geoI.top()); @@ -676,8 +674,7 @@ void NetHackQtStatusWindow::HitpointBar() geoH.setRight(hix); hpbar_health.setGeometry(geoH); w = geoH.right() - geoH.left() + 1; - styleH = QString::asprintf(styleformat, barcolors[colorindx][0], - w, w); + styleH = nh_qsprintf(styleformat, barcolors[colorindx][0], w, w); hpbar_health.setStyleSheet(styleH); hpbar_health.show(); @@ -728,13 +725,13 @@ void NetHackQtStatusWindow::updateStats() int st = ACURR(A_STR); if (st > STR18(100)) { - buf = QString::asprintf("Str:%d", st - 100); // 19..25 + buf = nh_qsprintf("Str:%d", st - 100); // 19..25 } else if (st == STR18(100)) { - buf = QString::asprintf("Str:18/**"); // 18/100 + buf = nh_qsprintf("Str:18/**"); // 18/100 } else if (st > 18) { - buf = QString::asprintf("Str:18/%02d", st - 18); // 18/01..18/99 + buf = nh_qsprintf("Str:18/%02d", st - 18); // 18/01..18/99 } else { - buf = QString::asprintf("Str:%d", st); // 3..18 + buf = nh_qsprintf("Str:%d", st); // 3..18 } str.setLabel(buf, NetHackQtLabelledIcon::NoNum, (long) st); dex.setLabel("Dex:", (long) ACURR(A_DEX)); @@ -824,8 +821,8 @@ void NetHackQtStatusWindow::updateStats() } QString buf2; char buf3[BUFSZ]; - buf2 = QString::asprintf("%s the %s", upstart(strcpy(buf3, g.plname)), - buf.toLatin1().constData()); + buf2 = nh_qsprintf("%s the %s", upstart(strcpy(buf3, g.plname)), + buf.toLatin1().constData()); name.setLabel(buf2, NetHackQtLabelledIcon::NoNum, u.ulevel); if (!describe_level(buf3, 0)) { @@ -843,13 +840,13 @@ void NetHackQtStatusWindow::updateStats() level.setCompareMode(NeitherIsBetter); if (Upolyd) { // You're a monster! - buf = QString::asprintf("/%d", u.mhmax); + buf = nh_qsprintf("/%d", u.mhmax); hp.setLabel("HP:", std::max((long) u.mh, 0L), buf); level.setLabel("HD:", (long) mons[u.umonnum].mlevel); // hit dice // Exp points are not shown when HD is displayed instead of Xp level } else { // You're normal. - buf = QString::asprintf("/%d", u.uhpmax); + buf = nh_qsprintf("/%d", u.uhpmax); hp.setLabel("HP:", std::max((long) u.uhp, 0L), buf); // if Exp points are to be displayed, append them to Xp level; // up/down highlighting becomes tricky--don't try very hard; @@ -860,11 +857,10 @@ void NetHackQtStatusWindow::updateStats() for (int i = ::flags.showexp ? 0 : 3; i < 4; ++i) { // passes 0,1,2 are with Exp, 3 is without Exp and always fits if (i < 3) { - buf = QString::asprintf("%s%ld/%ld", lvllbl[i], - (long) u.ulevel, u.uexp); + buf = nh_qsprintf("%s%ld/%ld", lvllbl[i], (long) u.ulevel, + u.uexp); } else { - buf = QString::asprintf("%s%ld", lvllbl[i - 3], - (long) u.ulevel); + buf = nh_qsprintf("%s%ld", lvllbl[i - 3], (long) u.ulevel); } // +2: allow a couple of pixels at either end to be clipped off if (fm.size(0, buf).width() <= (2 + level.label->width() + 2)) @@ -884,7 +880,7 @@ void NetHackQtStatusWindow::updateStats() was_polyd = Upolyd ? true : false; had_exp = (::flags.showexp && !was_polyd) ? true : false; - buf = QString::asprintf("/%d", u.uenmax); + buf = nh_qsprintf("/%d", u.uenmax); power.setLabel("Pow:", (long) u.uen, buf); ac.setLabel("AC:", (long) u.uac); // gold prefix used to be "Au:", tty uses "$:"; never too wide to fit; @@ -910,7 +906,7 @@ void NetHackQtStatusWindow::updateStats() : (u.ualign.type == A_NONE) ? "unaligned" : "other?"; } - qtext = QString::asprintf("%sly aligned", text); + qtext = nh_qsprintf("%sly aligned", text); align.setIcon(*pxmp, qtext.toLower()); align.setLabel(QString(text)); // without this, the ankh pixmap shifts from centered to left @@ -948,7 +944,7 @@ void NetHackQtStatusWindow::updateStats() static const char *const scrlbl[3] = { "Score:", "Scr:", "S:" }; QFontMetrics fm(score.label->font()); for (int i = 0; i < 3; ++i) { - buf = QString::asprintf("%s%ld", scrlbl[i], pts); + buf = nh_qsprintf("%s%ld", scrlbl[i], pts); // +2: allow couple of pixels at either end to be clipped off if (fm.size(0, buf).width() <= (2 + score.width() + 2)) break; diff --git a/win/Qt/qt_str.cpp b/win/Qt/qt_str.cpp index 1a6de3f90..764dd07bd 100644 --- a/win/Qt/qt_str.cpp +++ b/win/Qt/qt_str.cpp @@ -6,6 +6,7 @@ #include #include +#include #include "qt_str.h" namespace nethack_qt_ { @@ -80,4 +81,20 @@ int cp437(int ch) return cp437table[(unsigned char)ch]; } +QString +nh_qsprintf(const char *format, ...) +{ + QString msg; + std::va_list args; + + va_start(args, format); +#if QT_VERSION >= QT_VERSION_CHECK(5, 5, 0) + msg = QString::vasprintf(format, args); +#else + msg.vsprintf(format, args); +#endif + va_end(args); + return msg; +} + } // namespace nethack_qt_ diff --git a/win/Qt/qt_str.h b/win/Qt/qt_str.h index 2d5449363..9bc8f66e0 100644 --- a/win/Qt/qt_str.h +++ b/win/Qt/qt_str.h @@ -19,6 +19,13 @@ extern QString nh_capitalize_words(const QString& str); // Map symbol conversion extern int cp437(int ch); +// sprintf +extern QString nh_qsprintf(const char *format, ...) +#if defined(__GNUC__) && (__GNUC__ >= 2) + __attribute__((format(printf, 1, 2))) +#endif +; + } // namespace nethack_qt_ #endif diff --git a/win/Qt/qt_xcmd.cpp b/win/Qt/qt_xcmd.cpp index 541fa1354..4310ad249 100644 --- a/win/Qt/qt_xcmd.cpp +++ b/win/Qt/qt_xcmd.cpp @@ -294,7 +294,7 @@ NetHackQtExtCmdRequestor::NetHackQtExtCmdRequestor(QWidget *parent) : QString btn_lbl = extcmdlist[i].ef_txt; if (btn_lbl == "wait") btn_lbl += " (rest)"; - QString btn_tip = QString::asprintf(" %s ", extcmdlist[i].ef_desc); + QString btn_tip = nh_qsprintf(" %s ", extcmdlist[i].ef_desc); QPushButton *pb = new QPushButton(btn_lbl, grid); pb->setMinimumSize(butw, pb->sizeHint().height()); // force the button to have fixed width or it can move around a