From f0ab2e9b78bca914288321a2b66c28929b1b5fab Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 25 Dec 2025 03:44:23 +0100 Subject: [PATCH] Extended the screenshot functionality to allow taking both raw and (renderer/resize-)processed screenshots, to both file and clipboard, made the functionality available on the toolbar as well, and moved the recently added "Force interpretation" button to the end of the toolbar. --- src/include/86box/plat.h | 1 + src/include/86box/video.h | 3 ++ src/qt/icons/copy_raw_screenshot.ico | Bin 0 -> 9622 bytes src/qt/icons/copy_screenshot.ico | Bin 0 -> 9622 bytes src/qt/icons/take_raw_screenshot.ico | Bin 0 -> 9622 bytes src/qt/icons/take_screenshot.ico | Bin 0 -> 9622 bytes src/qt/languages/ca-ES.po | 9 ++++ src/qt/languages/cs-CZ.po | 9 ++++ src/qt/languages/de-DE.po | 9 ++++ src/qt/languages/es-ES.po | 9 ++++ src/qt/languages/fi-FI.po | 9 ++++ src/qt/languages/fr-FR.po | 11 ++++- src/qt/languages/hr-HR.po | 9 ++++ src/qt/languages/it-IT.po | 11 ++++- src/qt/languages/ja-JP.po | 11 ++++- src/qt/languages/ko-KR.po | 11 ++++- src/qt/languages/nb-NO.po | 9 ++++ src/qt/languages/nl-NL.po | 11 ++++- src/qt/languages/pl-PL.po | 9 ++++ src/qt/languages/pt-BR.po | 9 ++++ src/qt/languages/pt-PT.po | 9 ++++ src/qt/languages/ru-RU.po | 11 ++++- src/qt/languages/sk-SK.po | 9 ++++ src/qt/languages/sl-SI.po | 9 ++++ src/qt/languages/sv-SE.po | 9 ++++ src/qt/languages/tr-TR.po | 9 ++++ src/qt/languages/uk-UA.po | 11 ++++- src/qt/languages/vi-VN.po | 9 ++++ src/qt/languages/zh-CN.po | 9 ++++ src/qt/languages/zh-TW.po | 9 ++++ src/qt/qt_mainwindow.cpp | 30 ++++++++++++ src/qt/qt_mainwindow.hpp | 3 ++ src/qt/qt_mainwindow.ui | 48 ++++++++++++++++-- src/qt/qt_openglrenderer.cpp | 21 ++++++++ src/qt/qt_platform.cpp | 37 ++++++++++++++ src/qt/qt_rendererstack.cpp | 49 +++++++++++++++++-- src/qt/qt_softwarerenderer.cpp | 70 +++++++++++++++++---------- src/qt/qt_softwarerenderer.hpp | 10 ++-- src/qt/qt_vulkanwindowrenderer.cpp | 39 +++++++++++++++ src/qt_resources.qrc | 4 ++ src/unix/unix_sdl.c | 2 +- src/video/video.c | 5 +- 42 files changed, 503 insertions(+), 49 deletions(-) create mode 100644 src/qt/icons/copy_raw_screenshot.ico create mode 100644 src/qt/icons/copy_screenshot.ico create mode 100644 src/qt/icons/take_raw_screenshot.ico create mode 100644 src/qt/icons/take_screenshot.ico diff --git a/src/include/86box/plat.h b/src/include/86box/plat.h index 2d28ec9bc..316825f10 100644 --- a/src/include/86box/plat.h +++ b/src/include/86box/plat.h @@ -153,6 +153,7 @@ extern void plat_language_code_r(int id, char *outbuf, int len); extern void plat_get_cpu_string(char *outbuf, uint8_t len); extern void plat_set_thread_name(void *thread, const char *name); extern void plat_break(void); +extern void plat_send_to_clipboard(unsigned char *rgb, int width, int height); /* Resource management. */ extern wchar_t *plat_get_string(int id); diff --git a/src/include/86box/video.h b/src/include/86box/video.h index b94bdf415..b7f86ac18 100644 --- a/src/include/86box/video.h +++ b/src/include/86box/video.h @@ -145,6 +145,9 @@ typedef struct monitor_t { int mon_renderedframes; atomic_int mon_actualrenderedframes; atomic_int mon_screenshots; + atomic_int mon_screenshots_clipboard; + atomic_int mon_screenshots_raw; + atomic_int mon_screenshots_raw_clipboard; uint32_t *mon_pal_lookup; int *mon_cga_palette; int mon_pal_lookup_static; /* Whether it should not be freed by the API. */ diff --git a/src/qt/icons/copy_raw_screenshot.ico b/src/qt/icons/copy_raw_screenshot.ico new file mode 100644 index 0000000000000000000000000000000000000000..80626be20ac6530e8fcc5b4c05b10406201d5545 GIT binary patch literal 9622 zcmeHMJ&zqV6!p_aL2w1v%XKdedj_-JEzu6FW;X!!xD8OHYuOEc)c?jY0 z<8=S~2O<25x+hQ4{r4Y+@YP2lTwJ94pAq*L`hJQSTmm80!-Z#v`v*$|*PP8siQ$LW z?bxdyecKoVaV!>(>kb-Z1#^tibLIHoh=ExAv3U7{A$`wZ#qbNd(Y}D@D!%J_4CUHshdhx$T zyo@-Ek_TU&`22KW_E{>3o>z)Fe_)UWuftE<>D^iR*1zAic5`lR+W z#`>D`qZLm)<`AZ5cyn_TkH=&D>E+85liS&KsxWrWrs9~h`?DDDb}`=K(ROLNf|q(L z`xy71B6ZHK-xdyl1S4v+YiKCL|v-(F8=@Hnr9H_%6{E=|&+ zafLpQ#~c#7=$l$^x9H=#$6UyGzeS(Z*jx|UzEU5$m10_`#~ZZzQuJaFeyw!%Wj<=o z%&zy!MTJLB!<5g@q&Z&dRlkHsw1GbE1KJCS>#vPRV^(~BpRg)C>LbQfLHD%(3$I7% zukgNUui+eQ?KP@1ytzGts2Pu#)<1DiUoYWhOzlS;tM(%9N7|F@{aLXm5l)3MOQyap zue{%fL%a*;@raG6TeS1o?Ji;1*Rmb4*WEr$`xcJS;VDe})|WU-|3}L799fz}bMreT zZ@8Z5y`pbn`~6ORr#TE;bHUaC+?2I|@!HSm#i{+z_pLd!7b1qG#^yT2@*U#7h0z;V zi-UEl*MzF@i6z~_CN7dx_D9|~Iac7;*vvh#_g(Vh8jXXxR^Xd{^pket?++O}bL>$! z8pBHbrha5h`@J8>AV(|ly?*Xjb`QOLD*JsJhs{^cqosYD&$xQNUcdH3aTqSROgFJN z;2Rdz=4aqJ*v6u|G8b7#Tlsv6!6J@&FV;QBfgdzs3ZQ8EkIbaB>;c!!b5x?IE&X|hqG5W!Px&Z*yX^k zagMvknT+2LE@01KI)`=qaQT1vw`ZXJzOPvmwvW8$)H*27GvJh|k9@E36eaemlrL_d|ngSwiVXHr?|H>IJ)&ox>3_@ z^djAMq<&aSjGya%{cfRRvE=!u-{|r>kJK7GcR9C_ zdn-Q$LPN`H4Fm30%;I3zcc{5rxnGZVdQb8%+3Bc##9$q{#Xo>Le2@tEAc4;YoJiNO X<7u`#hO<9m_%6}5Yfwadr=a}}jH2PI literal 0 HcmV?d00001 diff --git a/src/qt/icons/copy_screenshot.ico b/src/qt/icons/copy_screenshot.ico new file mode 100644 index 0000000000000000000000000000000000000000..5ea6bc7057b21cd8dc51799798935edbb77f0273 GIT binary patch literal 9622 zcmeI1ziwqU5XOC#6)S`gTWqmiQc@!E0NDzOw?HWn5^u1A+*4BW2wPAf3d)GBaw~WV zic~34$`p~z{A_9g?FlMp@&Av}Mc z>%Y7g!q3+B;zh21_kIXpeh|XhS+4(Ret($l$L3>?hLGD$g_q{{50+?Lb21l7?7FV$ zdvS5$`$ib}QP4>&hE7s28yG#8{BLh>Q=9!s{?hc5mvngbCWfD4md}4r?eNRL>wmeOLrRM z;XFq68QX5se#3r6`QG-Zcc^II*65|Q2k(>_k1(}2mG!B9kDJ=GR+zu3ITr?)dgs-a z09jXM?-HKuv<5qiQKCNcoyWtctYyUq9)9+xxt|KV6(4QFlb!Gedt>2UiqGSX;+xoS z#k(awe27INjIHs>kDO}}mTZ>dBVQGbgV*5sQsZf_cI_!Y>cmDI64^*=9Eu+7y>MdZ z^Qd#Bj<2`tvFyR`<(vaL3$XXk)FtwFb&ztg_e1#-9~e``9AdEZKk4E=QVtKk)>)&r zgfn+$0ABEjG1~`lSwzi5K?5w+cn$In}LWfUGbZ&iNcj^B~S+`!M*VEiE_3u_a*XA_h_2-@Ji(QK& zVQVdDpYeMJ>r(2cp znLMV%0A!jp*e!gWrRtO2Rt=vpO7#6%C@gFwYV&j9$J}A{KJsnh>n@?O#1@R!_^40X z`}Ej6*!XLF7({V^tD-!-uJ0V`8(>f16U&^K+wz@8L{_0U*AIOc};~wlz#_tDbCNE8N59|2h^8fO0AA#0hy0-1u z+WLLWTdUeD@V z6M*>TD@{9lG(~M*`~A+h^NjCA4E@-ZF-msIAK&Zi>(o|rb0?LEZz_f+KYOzFea@~T z*eXXf^%l1U-rw(uV=jhSe)CoCXz?qCnjagu_g&U-Q&$YFF_`1`e7dWMTXX00hrj18 zG3@^aeqx|B^LO75eJmCO@g9>uc}p}Nn$Mb__B00;!+xK~p1SOh;m?^q-W62`Q~dhw z5D%OZwZZN0!)gZuDfXtUl=V-$NXWYhXg7H*EBJ{8K8a#e-Rno-{502>EF8bae5*E` z_1|@MfR0~z)#I=BDg7?;YtLDu-*)~9Z~VU0?@y`|-`nE%Yn8d?{c7d!&o+D#|Jv_z zGai(({`8G54Q?w2&)whKbbqVg?E%qD#bVHRyw`OM1MZg348_*2np^WQh+!+}27CCI xWCPsDG)=Dl+}S^XI{QH)*bfr+vjGe0#^kU~c875Cn~D7{(Uu#di1s@L@+aDqGo}Cl literal 0 HcmV?d00001 diff --git a/src/qt/icons/take_raw_screenshot.ico b/src/qt/icons/take_raw_screenshot.ico new file mode 100644 index 0000000000000000000000000000000000000000..b33735a8327b4b05f1e31c16f3260e675c2641aa GIT binary patch literal 9622 zcmeHMv5p)?5bcvKpAdl^IB@0*2`%vf=ZNn>1Qws*!0e7h;?N@C8xR2!8R2E{5f?Zj zL?$CZUcc8}uco@Edv|V^z(!kAxu&bD-m9+e?HSuCU8MWz(W3-=mA<{7(pM>^$B)bS zw+AWx0^gG-W&HZHlwN$E($!TN|Af515c>sk@CbzBhe^+o_YunuwXM~58N2ku?W{eV zZ+`5}C+0~ijEKi)ViE(v9!H<$%l|9qZ*O-K=A<0w9L5jwSp#EoKH@-_^JNd^3s?Em zG-I%iL-`ASR2nf3_s5qd zllKg+n|$B!zM{Or9rcOId}hnu-gO+8U7tVg8*L9e-cO3v`64QOl6=-Mh-WVSjImT4 zy02oaFb%K8;(4WfhqzZz+Kk)7q)&dsW3K8F7IAo>CbJxOF*|rI7JEmm%~Y(g7j?3Z z4qmPge$__2&DO9Ca|7R^#sOZpK6F5LXRNbY^8hc_$NMLbQ4hPi*_1k2bH-Y6ug3ax zp9wSLM64BfIhWN~4x z^x-O<5O;(4KObHTX2 zdGeX?`vRkK+nSwo<{IQ{V{4wm0bi5~Tk(2tN6R_#v>Y63jtqvsh=bqXaXk!j38$T> zUvsb$=YX%p<~vjBaU+fnK65DK?O~%C{{29ny&N6H#I`WW{=p@ zrdK|e{}?OWvS*-yh%fG=VY7bkN9=bmC+0_daS)4nyz@Da=U#s_=eEsjv58Nynr%Hx zpXSTV{HOf1|09Vf>m9zKrgVw*-Gg3~{xA1y=)XbiTjc%y{qGLT@31TAbEv+#xizcpW5v6N&!g|*=x=kDb++~RZ??K4iNm{9y2R<%%sA!H_UoBz zz&wRHlqy%_h{5;!NEO%CARJo8l(m!^j2}}&ZoTJ*G0N4qhdAVqHrB`rjDNK59`}U$ zTlM@yHHcp|8b8-YaUA$Z+-RVGm$HsLW>1yBuZ97?=L)08FRsZrW#xy>I7jeTYiA7u ze*OF3!h)N(k7;nel}+V}AL`g=8;(0{I<;x+X8 z&v|h4YM|e9k2rsxs~Q47zp*JEL#|deFYfp~t~pxZx)K9piQ`+Ge*gN$XIvH2jwAOS z`H4%Z@S7f}4<&N>r|Qg>>x_FM?6vD>yz#evsCc-}R>g5g{^g41{bCJkRcB)#UOofm z49$Nxvh(2QL+ki2ZR8L?3eG~F;#*p)VYnB{l^x;Kej^Ts`L_4ohvx63i~WvgUHtoS z+I0u|{HR>kL1jFBroD5}#wfP>JsskWbp*cX&d+g9&x;^)XrA^g=MFR-=-pB8aZV@v fClEp}q4%H{&^yb7jJL>r2aJD!_wUQ=r!C(Hr*OfV literal 0 HcmV?d00001 diff --git a/src/qt/icons/take_screenshot.ico b/src/qt/icons/take_screenshot.ico new file mode 100644 index 0000000000000000000000000000000000000000..66f83ebbdf5d7872df04967b2bd66f17cf798632 GIT binary patch literal 9622 zcmeI1ziu5x6voF&goP-QB1O8mq(tHYoQmf_E)b7E0r#$iET!ZTQly}wwCH?0c#Kpo zQRpZTm-Ef;Z~ggrW_|6eNU?NBIzBV!&-a})$^s<+rfCd^xV)d|t|TUzBokGOmA(yuTv$%gBjoAdL1<<#ptJ!ebk??J9X2+hG`H zY2lomowfW$c?`$Mb72Z&v)SChAs_qI)zugi@xvteguz^ST9dCDG*`at@uTLWiSOlO zCw~~OF=`zXA93Jy`M0XgFz(0)m;GxG2tKWuxA^f1BMZ62wDOmpqw;-tK6OgV&K|@C zA3l$r=0!Qgk>9G{eDI0@x>1XcU+qYXpvEtx;MLc!^ zf`<<*om-8cBLBw_Y2lLVn6hC9Pq`UOI66?nq_u8gw(v5R_9d*3b$`slJPg3$?R8OJS~7Bc^H=mi*-R@UW{s#XF{O z9BUUm)zib2PXivWjT~&!dB~DBkh%9RIFb_+Z4m*u3@$9Pg#~EXNDaM35De zUdX4M)_(D!Jtu5826bU%?HV5%AL~zD^W2BBj-H-|yb5`?lME5JiTJB$r@(CW-HI!8 z`6`6(*0*t&K8(FP5YObsxxdf4M?Pb4ZqfQ4^@JF-)#W_(Oc0~rGZ)L5Yry7l{C)~& z@>dS6eRvL>dY5Mb$K#pf6M^O$_|UTJz0&e2CVz{_lUA-o`v4!D%gf98orO&~`eq_v z^*CDi%F&Q7*Dc&AX1+gYy~NSNr`C+GJqmk0j2bRDT6<{WQ%?(j#-2FV!FON$+MGsz zYW;TKn7M*OHSJr!FyL5E_av>^@2>c{|J*~s5hj97*#3RR-s`_O=s$N5c*#YBy(_-s zv^eDV0l#9sU*d1o@41@8(YhPBP1t#4d}_eHuNEhmF|Whc^K*np_0kXTcPl5r=KN_s z62wo%(?7lQ<(JL-!5kkt=gA&&YX}d)$=WqO^pcO5$Ef{meTX~MP>!Q-PeP7r|6@-( z>rKSIkG#Ks{$qyKJ?tdpbqM#cLH}@h7>5o#o(}B%I}lsy#qP4(X0E?`H1FMq-JWwA zb>({I-`SkYH&wcU)3teC#+-2G8syhd4%+iIcMN^sdqSKzG6rkKcn$C`ar2$)#emJ- z0}kx2y+$SlWZI6H6H{9r`O}$Y458+py*U;mS23+?ZZuB1f&aGN{{B{4G8ur~k z&wh!2-hZoxJ@@ZDXzgEh)iVe;I(TKL{)aw)^7H<6xAxk^m4#fm{XUKlTk6Rq<{jU8J%ikT2eb*cgKNIu_UyDEQM{DA# zV;9ZYSi*xpVhbF~WB#$Ub7&qi4{^q#Db$nCB+r6ebPp%lXKp6S=h?%V|0adgHN38S zI8zN!-qO^-nNj@t`T6{8T4z8p)ax1yX~olhp(hq#YcNyt&iy~hw4?<4m^VEhw!|Ne0LD)aphXl7r_ literal 0 HcmV?d00001 diff --git a/src/qt/languages/ca-ES.po b/src/qt/languages/ca-ES.po index 75e0a593d..314b12e3e 100644 --- a/src/qt/languages/ca-ES.po +++ b/src/qt/languages/ca-ES.po @@ -210,6 +210,15 @@ msgstr "&Actualitza icones a la barra d'estat" msgid "Take s&creenshot" msgstr "Desa captura de &pantalla" +msgid "Take &raw screenshot" +msgstr "Desa captura en &brut de pantalla" + +msgid "C&opy screenshot" +msgstr "C&opia captura de pantalla" + +msgid "Copy r&aw screenshot" +msgstr "Copy captura en b&rut de pantalla" + msgid "S&ound" msgstr "S&o" diff --git a/src/qt/languages/cs-CZ.po b/src/qt/languages/cs-CZ.po index dbb0d2826..041992219 100644 --- a/src/qt/languages/cs-CZ.po +++ b/src/qt/languages/cs-CZ.po @@ -210,6 +210,15 @@ msgstr "&Aktualizovat ikony stavového řádku" msgid "Take s&creenshot" msgstr "Pořídit &screenshot" +msgid "Take &raw screenshot" +msgstr "Pořídit &surový screenshot" + +msgid "C&opy screenshot" +msgstr "Z&kopírovát screenshot" + +msgid "Copy r&aw screenshot" +msgstr "Zkopírovát s&urový screenshot" + msgid "S&ound" msgstr "&Zvuk" diff --git a/src/qt/languages/de-DE.po b/src/qt/languages/de-DE.po index e426d1e2d..634069dd7 100644 --- a/src/qt/languages/de-DE.po +++ b/src/qt/languages/de-DE.po @@ -210,6 +210,15 @@ msgstr "&Statusleistenicons aktualisieren" msgid "Take s&creenshot" msgstr "S&creenshot aufnehmen" +msgid "Take &raw screenshot" +msgstr "&Roh-Screenshot aufnehmen" + +msgid "C&opy screenshot" +msgstr "Screenshot k&opieren" + +msgid "Copy r&aw screenshot" +msgstr "R&oh-Screenshot kopieren" + msgid "S&ound" msgstr "&Ton" diff --git a/src/qt/languages/es-ES.po b/src/qt/languages/es-ES.po index 53bd643b2..de155cf7a 100644 --- a/src/qt/languages/es-ES.po +++ b/src/qt/languages/es-ES.po @@ -210,6 +210,15 @@ msgstr "&Actualizar iconos en barra de estado" msgid "Take s&creenshot" msgstr "Tomar cap&tura" +msgid "Take &raw screenshot" +msgstr "Tomar captura &plana" + +msgid "C&opy screenshot" +msgstr "C&opiar captura" + +msgid "Copy r&aw screenshot" +msgstr "Copiar captura p&lana" + msgid "S&ound" msgstr "S&onido" diff --git a/src/qt/languages/fi-FI.po b/src/qt/languages/fi-FI.po index 0db30bede..d43b70192 100644 --- a/src/qt/languages/fi-FI.po +++ b/src/qt/languages/fi-FI.po @@ -210,6 +210,15 @@ msgstr "&Päivitä tilapalkin kuvakkeita" msgid "Take s&creenshot" msgstr "Ota &kuvakaappaus" +msgid "Take &raw screenshot" +msgstr "Ota &raaka kuvakaapus" + +msgid "C&opy screenshot" +msgstr "K&opia kuvakaapaus" + +msgid "Copy r&aw screenshot" +msgstr "Kopia r&aaka kuvakaapaus" + msgid "S&ound" msgstr "&Ääni" diff --git a/src/qt/languages/fr-FR.po b/src/qt/languages/fr-FR.po index 6a5628f29..aa550e5f3 100644 --- a/src/qt/languages/fr-FR.po +++ b/src/qt/languages/fr-FR.po @@ -208,7 +208,16 @@ msgid "&Update status bar icons" msgstr "Mettre à jour la barre de stat&us" msgid "Take s&creenshot" -msgstr "Copie d'é&cran" +msgstr "Faire copie d'é&cran" + +msgid "Take &raw screenshot" +msgstr "Faire copie &brute d'écran" + +msgid "C&opy screenshot" +msgstr "C&opier copie d'écran" + +msgid "Copy r&aw screenshot" +msgstr "Copier copie b&rute d'écran" msgid "S&ound" msgstr "S&on" diff --git a/src/qt/languages/hr-HR.po b/src/qt/languages/hr-HR.po index 5261ab338..882da52b5 100644 --- a/src/qt/languages/hr-HR.po +++ b/src/qt/languages/hr-HR.po @@ -212,6 +212,15 @@ msgstr "&Ažuriraj ikone statusnog redka" msgid "Take s&creenshot" msgstr "Napravi &snimku zaslona" +msgid "Take &raw screenshot" +msgstr "Napravi &neobrađenu snimku zaslona" + +msgid "C&opy screenshot" +msgstr "K&opiraj snimku zalsona" + +msgid "Copy r&aw screenshot" +msgstr "Kopiraj n&eobrađenu snimku zaslona" + msgid "S&ound" msgstr "&Zvuk" diff --git a/src/qt/languages/it-IT.po b/src/qt/languages/it-IT.po index 67937b089..36621b840 100644 --- a/src/qt/languages/it-IT.po +++ b/src/qt/languages/it-IT.po @@ -210,6 +210,15 @@ msgstr "&Aggiorna icone della barra di stato" msgid "Take s&creenshot" msgstr "&Cattura schermata" +msgid "Take &raw screenshot" +msgstr "Cattura &grezza della schermata" + +msgid "C&opy screenshot" +msgstr "C&opia cattura della schermata" + +msgid "Copy r&aw screenshot" +msgstr "Copia cattura g&rezza della schermata" + msgid "S&ound" msgstr "A&udio" @@ -1420,7 +1429,7 @@ msgid "Don't overwrite" msgstr "Non sovrascrivere" msgid "Raw image" -msgstr "Immagine RAW" +msgstr "Immagine grezza" msgid "HDI image" msgstr "Immagine HDI" diff --git a/src/qt/languages/ja-JP.po b/src/qt/languages/ja-JP.po index cfd44daba..d9eba2646 100644 --- a/src/qt/languages/ja-JP.po +++ b/src/qt/languages/ja-JP.po @@ -211,6 +211,15 @@ msgstr "ステータスバーのアイコンを更新(&U)" msgid "Take s&creenshot" msgstr "スクリーンショットを撮る(&C)" +msgid "Take &raw screenshot" +msgstr "生のスクリーンショットを撮る(&R)" + +msgid "C&opy screenshot" +msgstr "スクリーンショットをコピーする(&O)" + +msgid "Copy r&aw screenshot" +msgstr "生のスクリーンショットをコピーする(&A)" + msgid "S&ound" msgstr "サウンド(&O)" @@ -1421,7 +1430,7 @@ msgid "Don't overwrite" msgstr "上書きしない" msgid "Raw image" -msgstr "Rawイメージ" +msgstr "生のイメージ" msgid "HDI image" msgstr "HDIイメージ" diff --git a/src/qt/languages/ko-KR.po b/src/qt/languages/ko-KR.po index e49476e40..51b77209d 100644 --- a/src/qt/languages/ko-KR.po +++ b/src/qt/languages/ko-KR.po @@ -204,6 +204,15 @@ msgstr "상태 바 아이콘 갱신하기(&U)" msgid "Take s&creenshot" msgstr "스크린샷 찍기(&C)" +msgid "Take &raw screenshot" +msgstr "원본 스크린샷 찍기(&R)" + +msgid "C&opy screenshot" +msgstr "스크린샷 복사하세요(&O)" + +msgid "Copy r&aw screenshot" +msgstr "원본 스크린샷 복사하세요(&A)" + msgid "S&ound" msgstr "사운드(&O)" @@ -1414,7 +1423,7 @@ msgid "Don't overwrite" msgstr "덮어쓰지 않음" msgid "Raw image" -msgstr "Raw 이미지" +msgstr "원본 이미지" msgid "HDI image" msgstr "HDI 이미지" diff --git a/src/qt/languages/nb-NO.po b/src/qt/languages/nb-NO.po index 5b2748210..4da9f6073 100644 --- a/src/qt/languages/nb-NO.po +++ b/src/qt/languages/nb-NO.po @@ -204,6 +204,15 @@ msgstr "&Oppdater statuslinjeikoner" msgid "Take s&creenshot" msgstr "Ta s&kjermbilde" +msgid "Take &raw screenshot" +msgstr "Ta &rå skjermbilde" + +msgid "C&opy screenshot" +msgstr "K&opiera skjermbilde" + +msgid "Copy r&aw screenshot" +msgstr "Kopiera r&å skjermbilde" + msgid "S&ound" msgstr "L&yd" diff --git a/src/qt/languages/nl-NL.po b/src/qt/languages/nl-NL.po index 88a0964ec..abaae4a98 100644 --- a/src/qt/languages/nl-NL.po +++ b/src/qt/languages/nl-NL.po @@ -202,7 +202,16 @@ msgid "&Update status bar icons" msgstr "&Statusbalkpictogrammen bijwerken" msgid "Take s&creenshot" -msgstr "Maak een schermafbeelding" +msgstr "Maak een s&chermafbeelding" + +msgid "Take &raw screenshot" +msgstr "Maak een &ruw schermafbeelding" + +msgid "C&opy screenshot" +msgstr "K&opieer een schermafbeelding" + +msgid "Copy r&aw screenshot" +msgstr "Kopieer een r&uw schermafbeelding" msgid "S&ound" msgstr "&Geluid" diff --git a/src/qt/languages/pl-PL.po b/src/qt/languages/pl-PL.po index 43b89a8da..02a24fa2c 100644 --- a/src/qt/languages/pl-PL.po +++ b/src/qt/languages/pl-PL.po @@ -211,6 +211,15 @@ msgstr "&Aktualizuj ikony na pasku statusu" msgid "Take s&creenshot" msgstr "Zrób &zrzut ekranu" +msgid "Take &raw screenshot" +msgstr "Zrób &surowy zrzut ekranu" + +msgid "C&opy screenshot" +msgstr "S&kopiuj zrzut ekranu" + +msgid "Copy r&aw screenshot" +msgstr "Skopiuj s&urowy zrzut ekranu" + msgid "S&ound" msgstr "Dź&więk" diff --git a/src/qt/languages/pt-BR.po b/src/qt/languages/pt-BR.po index 04b96c62d..02e13e571 100644 --- a/src/qt/languages/pt-BR.po +++ b/src/qt/languages/pt-BR.po @@ -204,6 +204,15 @@ msgstr "&Atualizar ícones da barra de status" msgid "Take s&creenshot" msgstr "Capturar &tela" +msgid "Take &raw screenshot" +msgstr "Fazer captura &bruta da tela" + +msgid "C&opy screenshot" +msgstr "C&opiar captura da tela" + +msgid "Copy r&aw screenshot" +msgstr "Copiar captura b&ruta da tela" + msgid "S&ound" msgstr "&Som" diff --git a/src/qt/languages/pt-PT.po b/src/qt/languages/pt-PT.po index f81d1ec94..5b3aaecec 100644 --- a/src/qt/languages/pt-PT.po +++ b/src/qt/languages/pt-PT.po @@ -211,6 +211,15 @@ msgstr "&Atualizar ícones da barra de estado" msgid "Take s&creenshot" msgstr "Gravar imagem de &ecrã" +msgid "Take &raw screenshot" +msgstr "Gravar imagem &bruta de ecrã" + +msgid "C&opy screenshot" +msgstr "Copiar imagem de ecrã" + +msgid "Copy r&aw screenshot" +msgstr "Copiar imagem b&ruta de ecrã" + msgid "S&ound" msgstr "&Som" diff --git a/src/qt/languages/ru-RU.po b/src/qt/languages/ru-RU.po index ce3fe75a3..9e16f6c28 100644 --- a/src/qt/languages/ru-RU.po +++ b/src/qt/languages/ru-RU.po @@ -211,6 +211,15 @@ msgstr "&Обновление значков строки состояния" msgid "Take s&creenshot" msgstr "Сделать с&криншот" +msgid "Take &raw screenshot" +msgstr "Сделать &сырой скриншот" + +msgid "C&opy screenshot" +msgstr "С&копировать скриншот" + +msgid "Copy r&aw screenshot" +msgstr "Скопировать с&ырой скриншот" + msgid "S&ound" msgstr "&Звук" @@ -1433,7 +1442,7 @@ msgid "Don't overwrite" msgstr "Не перезаписывать" msgid "Raw image" -msgstr "RAW образ" +msgstr "Сырой образ" msgid "HDI image" msgstr "Образ HDI" diff --git a/src/qt/languages/sk-SK.po b/src/qt/languages/sk-SK.po index f049c3f48..0310f6938 100644 --- a/src/qt/languages/sk-SK.po +++ b/src/qt/languages/sk-SK.po @@ -210,6 +210,15 @@ msgstr "&Aktualizovať ikony na stavovom riadku" msgid "Take s&creenshot" msgstr "Urobiť snímku &obrazovky" +msgid "Take &raw screenshot" +msgstr "Urobiť &surovú snímku obrazovky" + +msgid "C&opy screenshot" +msgstr "S&kopírovať snímku obrazovky" + +msgid "Copy r&aw screenshot" +msgstr "Skopírovať s&urovú snímku obrazovky" + msgid "S&ound" msgstr "&Zvuk" diff --git a/src/qt/languages/sl-SI.po b/src/qt/languages/sl-SI.po index d6a4c20ea..4e31b36da 100644 --- a/src/qt/languages/sl-SI.po +++ b/src/qt/languages/sl-SI.po @@ -212,6 +212,15 @@ msgstr "&Posodabljaj ikone statusne vrstice" msgid "Take s&creenshot" msgstr "&Zajemi posnetek zaslona" +msgid "Take &raw screenshot" +msgstr "Zajemi &neobdelan posnetek zaslona" + +msgid "C&opy screenshot" +msgstr "K&opiraj posnetek zaslona" + +msgid "Copy r&aw screenshot" +msgstr "Kopriaj n&eobdelan posenetk zaslona" + msgid "S&ound" msgstr "Z&vok" diff --git a/src/qt/languages/sv-SE.po b/src/qt/languages/sv-SE.po index 4e626a47b..d937828f9 100644 --- a/src/qt/languages/sv-SE.po +++ b/src/qt/languages/sv-SE.po @@ -204,6 +204,15 @@ msgstr "&Uppdatera statusfältets ikoner" msgid "Take s&creenshot" msgstr "Tag s&kärmbild" +msgid "Take &raw screenshot" +msgstr "Tag &rå skärmbild" + +msgid "C&opy screenshot" +msgstr "Kopiera skärmbild" + +msgid "Copy r&aw screenshot" +msgstr "Kopera r&å skärmbild" + msgid "S&ound" msgstr "L&jud" diff --git a/src/qt/languages/tr-TR.po b/src/qt/languages/tr-TR.po index 91301e0b3..f2a21f5d2 100644 --- a/src/qt/languages/tr-TR.po +++ b/src/qt/languages/tr-TR.po @@ -204,6 +204,15 @@ msgstr "Durum &çubuğu simgelerini güncelle" msgid "Take s&creenshot" msgstr "&Ekran görüntüsü al" +msgid "Take &raw screenshot" +msgstr "Ekran &ham görüntüsü al" + +msgid "C&opy screenshot" +msgstr "Ekran görüntüsü k&opyala" + +msgid "Copy r&aw screenshot" +msgstr "Ekran h&am görüntüsü kopyala" + msgid "S&ound" msgstr "&Ses" diff --git a/src/qt/languages/uk-UA.po b/src/qt/languages/uk-UA.po index 49eac891c..f9ff3e467 100644 --- a/src/qt/languages/uk-UA.po +++ b/src/qt/languages/uk-UA.po @@ -212,6 +212,15 @@ msgstr "&Обновлення значків рядка стану" msgid "Take s&creenshot" msgstr "Зробити &знімок" +msgid "Take &raw screenshot" +msgstr "Зробити &сирий знімок" + +msgid "C&opy screenshot" +msgstr "С&копійовати знімок" + +msgid "Copy r&aw screenshot" +msgstr "Скопійовати с&ирий знімок" + msgid "S&ound" msgstr "&Звук" @@ -1422,7 +1431,7 @@ msgid "Don't overwrite" msgstr "Не перезаписувати" msgid "Raw image" -msgstr "RAW образ" +msgstr "Сирий образ" msgid "HDI image" msgstr "Образ HDI" diff --git a/src/qt/languages/vi-VN.po b/src/qt/languages/vi-VN.po index 0471fa1f0..e4d7a806d 100644 --- a/src/qt/languages/vi-VN.po +++ b/src/qt/languages/vi-VN.po @@ -204,6 +204,15 @@ msgstr "Cậ&p nhật biểu tượng thanh trạng thái" msgid "Take s&creenshot" msgstr "Chụp &màn hình" +msgid "Take &raw screenshot" +msgstr "Chụp màn hình &thô" + +msgid "C&opy screenshot" +msgstr "S&ao chép ảnh chụp màn hình" + +msgid "Copy r&aw screenshot" +msgstr "Sao chép ảnh chụp màn hình t&hô" + msgid "S&ound" msgstr "&Âm thanh" diff --git a/src/qt/languages/zh-CN.po b/src/qt/languages/zh-CN.po index cf31d6975..cea569a6f 100644 --- a/src/qt/languages/zh-CN.po +++ b/src/qt/languages/zh-CN.po @@ -204,6 +204,15 @@ msgstr "更新状态栏图标(&U)" msgid "Take s&creenshot" msgstr "截图(&C)" +msgid "Take &raw screenshot" +msgstr "原始截图(&R)" + +msgid "C&opy screenshot" +msgstr "复制截图(&O)" + +msgid "Copy r&aw screenshot" +msgstr "复制原始截图(&A)" + msgid "S&ound" msgstr "声音(&O)" diff --git a/src/qt/languages/zh-TW.po b/src/qt/languages/zh-TW.po index 156dbb2fe..ddb879c8f 100644 --- a/src/qt/languages/zh-TW.po +++ b/src/qt/languages/zh-TW.po @@ -204,6 +204,15 @@ msgstr "更新狀態列圖示(&U)" msgid "Take s&creenshot" msgstr "擷圖(&C)" +msgid "Take &raw screenshot" +msgstr "原始擷圖(&R)" + +msgid "C&opy screenshot" +msgstr "複製擷圖(&O)" + +msgid "Copy r&aw screenshot" +msgstr "複製原始擷圖(&A)" + msgid "S&ound" msgstr "聲音(&O)" diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index cd7523985..cce6d9c95 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -2263,6 +2263,36 @@ MainWindow::on_actionTake_screenshot_triggered() device_force_redraw(); } +void +MainWindow::on_actionTake_raw_screenshot_triggered() +{ + startblit(); + for (auto &monitor : monitors) + ++monitor.mon_screenshots_raw; + endblit(); + device_force_redraw(); +} + +void +MainWindow::on_actionCopy_screenshot_triggered() +{ + startblit(); + for (auto &monitor : monitors) + ++monitor.mon_screenshots_clipboard; + endblit(); + device_force_redraw(); +} + +void +MainWindow::on_actionCopy_raw_screenshot_triggered() +{ + startblit(); + for (auto &monitor : monitors) + ++monitor.mon_screenshots_raw_clipboard; + endblit(); + device_force_redraw(); +} + void MainWindow::on_actionMute_Unmute_triggered() { diff --git a/src/qt/qt_mainwindow.hpp b/src/qt/qt_mainwindow.hpp index a31900767..e1c0c7409 100644 --- a/src/qt/qt_mainwindow.hpp +++ b/src/qt/qt_mainwindow.hpp @@ -132,6 +132,9 @@ private slots: void on_actionHide_tool_bar_triggered(); void on_actionUpdate_status_bar_icons_triggered(); void on_actionTake_screenshot_triggered(); + void on_actionTake_raw_screenshot_triggered(); + void on_actionCopy_screenshot_triggered(); + void on_actionCopy_raw_screenshot_triggered(); void toggleFullscreenUI(); void on_actionMute_Unmute_triggered(); void on_actionSound_gain_triggered(); diff --git a/src/qt/qt_mainwindow.ui b/src/qt/qt_mainwindow.ui index 777455d5b..27501d0b9 100644 --- a/src/qt/qt_mainwindow.ui +++ b/src/qt/qt_mainwindow.ui @@ -70,8 +70,6 @@ - - @@ -80,6 +78,8 @@ + + @@ -106,6 +106,10 @@ + + + + @@ -295,8 +299,6 @@ false - - @@ -306,6 +308,13 @@ + + + + + + + @@ -749,6 +758,37 @@ Ctrl+F11 + + + :/menuicons/qt/icons/take_screenshot.ico:/menuicons/qt/icons/take_screenshot.ico + + + + + Take &raw screenshot + + + + :/menuicons/qt/icons/take_raw_screenshot.ico:/menuicons/qt/icons/take_raw_screenshot.ico + + + + + C&opy screenshot + + + + :/menuicons/qt/icons/copy_screenshot.ico:/menuicons/qt/icons/copy_screenshot.ico + + + + + Copy r&aw screenshot + + + + :/menuicons/qt/icons/copy_raw_screenshot.ico:/menuicons/qt/icons/copy_raw_screenshot.ico + diff --git a/src/qt/qt_openglrenderer.cpp b/src/qt/qt_openglrenderer.cpp index 8e01bfe6c..22e400c65 100644 --- a/src/qt/qt_openglrenderer.cpp +++ b/src/qt/qt_openglrenderer.cpp @@ -26,6 +26,7 @@ extern MainWindow *main_window; #include #include #include +#include #include #include #include @@ -1147,6 +1148,8 @@ OpenGLRenderer::finalize() isFinalized = true; } +extern void take_screenshot_clipboard_monitor(int sx, int sy, int sw, int sh, int i); + void OpenGLRenderer::onBlit(int buf_idx, int x, int y, int w, int h) { @@ -1184,6 +1187,10 @@ OpenGLRenderer::onBlit(int buf_idx, int x, int y, int w, int h) if (video_framerate == -1) render(); + + if (monitors[r_monitor_index].mon_screenshots_raw_clipboard) { + take_screenshot_clipboard_monitor(x, y, w, h, r_monitor_index); + } } std::vector> @@ -1725,6 +1732,20 @@ OpenGLRenderer::render() monitors[r_monitor_index].mon_screenshots--; free(rgb); } + if (monitors[r_monitor_index].mon_screenshots_clipboard) { + int width = destination.width(), height = destination.height(); + + unsigned char *rgb = (unsigned char *) calloc(1, (size_t) width * height * 4); + + glw.glFinish(); + glw.glReadPixels(window_rect.x, window_rect.y, width, height, GL_RGB, GL_UNSIGNED_BYTE, rgb); + + QImage image((uchar*)rgb, width, height, width * 3, QImage::Format_RGB888); + QClipboard *clipboard = QApplication::clipboard(); + clipboard->setImage(image.mirrored(false, true), QClipboard::Clipboard); + monitors[r_monitor_index].mon_screenshots_clipboard--; + free(rgb); + } glw.glDisable(GL_FRAMEBUFFER_SRGB); diff --git a/src/qt/qt_platform.cpp b/src/qt/qt_platform.cpp index 37653c5a3..9fd16d3f1 100644 --- a/src/qt/qt_platform.cpp +++ b/src/qt/qt_platform.cpp @@ -30,8 +30,11 @@ #include +#include +#include #include #include +#include #include #include #include @@ -978,3 +981,37 @@ plat_break(void) raise(SIGTRAP); #endif } + +static unsigned char *rgb_ = NULL; +static int width_ = 0; +static int height_ = 0; +static volatile int waiting = 0; + +static void +send_to_clipboard(void) +{ + unsigned char *rgb = (unsigned char *) calloc(1, height_ * width_ * 4); + memcpy(rgb, rgb_, height_ * width_ * 3); + QImage image(rgb, width_, height_, width_ * 3, QImage::Format_RGB888); + QClipboard *clipboard = QApplication::clipboard(); + clipboard->setImage(image, QClipboard::Clipboard); + free(rgb); + waiting = 0; +} + +void +plat_send_to_clipboard(unsigned char *rgb, int width, int height) +{ + rgb_ = rgb; + width_ = width; + height_ = height; + waiting = 1; + + QTimer::singleShot(0, main_window, &send_to_clipboard); + while (waiting) + ; + + height_ = 0; + width_ = 0; + rgb_ = NULL; +} diff --git a/src/qt/qt_rendererstack.cpp b/src/qt/qt_rendererstack.cpp index 41d17d897..99a6bf649 100644 --- a/src/qt/qt_rendererstack.cpp +++ b/src/qt/qt_rendererstack.cpp @@ -33,6 +33,9 @@ #include #include +#include +#include + #include #include #ifdef TOUCH_PR @@ -66,9 +69,12 @@ # include #endif +#include + extern "C" { #include <86box/86box.h> #include <86box/config.h> +#include <86box/path.h> #include <86box/plat.h> #include <86box/video.h> #include <86box/mouse.h> @@ -87,6 +93,8 @@ extern MainWindow *main_window; HWND rw_hwnd; #endif +static unsigned char *screenshot_rgb = NULL; + RendererStack::RendererStack(QWidget *parent, int monitor_index) : QWidget(parent) , boxLayout(new QBoxLayout(QBoxLayout::TopToBottom, this)) @@ -158,12 +166,20 @@ RendererStack::RendererStack(QWidget *parent, int monitor_index) if (monitor_index == 0) mouse_set_raw(raw); + + screenshot_rgb = (unsigned char *) calloc(1, (size_t) 2048 * 2048 * 4); } RendererStack::~RendererStack() { + if (screenshot_rgb != NULL) { + free(screenshot_rgb); + screenshot_rgb = NULL; + } + while (QApplication::overrideCursor()) QApplication::restoreOverrideCursor(); + delete ui; } @@ -372,11 +388,7 @@ RendererStack::createRenderer(Renderer renderer) auto sw = new SoftwareRenderer(this); rendererWindow = sw; connect(this, &RendererStack::blitToRenderer, sw, &SoftwareRenderer::onBlit, Qt::QueuedConnection); -#ifdef __HAIKU__ current.reset(sw); -#else - current.reset(this->createWindowContainer(sw)); -#endif } break; case Renderer::OpenGL3: @@ -460,6 +472,32 @@ RendererStack::createRenderer(Renderer renderer) } } +uint32_t *screenshot_buf = NULL; + +void +take_screenshot_clipboard_monitor(int sx, int sy, int sw, int sh, int i) +{ + uint32_t temp = 0x00000000; + + for (int y = 0; y < sh; ++y) { + for (int x = 0; x < sw; ++x) { + if (screenshot_buf == NULL) + memset(&(screenshot_rgb[(y * sw * 3) + (x * 3)]), 0x00, 3); + else { + temp = screenshot_buf[((sy + y) * 2048) + sx + x]; + screenshot_rgb[(y * sw * 3) + (x * 3)] = (temp >> 16) & 0xff; + screenshot_rgb[(y * sw * 3) + (x * 3) + 1] = (temp >> 8) & 0xff; + screenshot_rgb[(y * sw * 3) + (x * 3) + 2] = temp & 0xff; + } + } + } + + QImage image(screenshot_rgb, sw, sh, sw * 3, QImage::Format_RGB888); + QClipboard *clipboard = QApplication::clipboard(); + clipboard->setImage(image, QClipboard::Clipboard); + monitors[i].mon_screenshots_raw_clipboard--; +} + // called from blitter thread void RendererStack::blit(int x, int y, int w, int h) @@ -478,10 +516,11 @@ RendererStack::blit(int x, int y, int w, int h) video_copy(scanline, &(monitors[m_monitor_index].target_buffer->line[y1][x]), w * 4); } - if (monitors[m_monitor_index].mon_screenshots && !rendererTakesScreenshots) { + if (monitors[m_monitor_index].mon_screenshots_raw) { video_screenshot_monitor((uint32_t *) imagebits, x, y, 2048, m_monitor_index); } video_blit_complete_monitor(m_monitor_index); + screenshot_buf = (uint32_t *) imagebits; emit blitToRenderer(currentBuf, sx, sy, sw, sh); currentBuf = (currentBuf + 1) % imagebufs.size(); } diff --git a/src/qt/qt_softwarerenderer.cpp b/src/qt/qt_softwarerenderer.cpp index 0a4492a3e..d9e217ed3 100644 --- a/src/qt/qt_softwarerenderer.cpp +++ b/src/qt/qt_softwarerenderer.cpp @@ -18,21 +18,19 @@ */ #include "qt_softwarerenderer.hpp" #include +#include #include #include extern "C" { #include <86box/86box.h> +#include <86box/path.h> +#include <86box/plat.h> #include <86box/video.h> } SoftwareRenderer::SoftwareRenderer(QWidget *parent) -#ifdef __HAIKU__ : QWidget(parent) -#else - : QWindow(parent->windowHandle()) - , m_backingStore(new QBackingStore(this)) -#endif { RendererCommon::parentWidget = parent; @@ -42,25 +40,23 @@ SoftwareRenderer::SoftwareRenderer(QWidget *parent) buf_usage = std::vector(2); buf_usage[0].clear(); buf_usage[1].clear(); -#ifdef __HAIKU__ this->setMouseTracking(true); -#endif } -#ifdef __HAIKU__ void SoftwareRenderer::paintEvent(QPaintEvent *event) { (void) event; onPaint(this); } -#endif void SoftwareRenderer::render() { +#ifdef __HAIKU__ if (!isExposed()) return; +#endif QRect rect(0, 0, width(), height()); m_backingStore->beginPaint(rect); @@ -78,6 +74,8 @@ SoftwareRenderer::exposeEvent(QExposeEvent *event) render(); } +extern void take_screenshot_clipboard_monitor(int sx, int sy, int sw, int sh, int i); + void SoftwareRenderer::onBlit(int buf_idx, int x, int y, int w, int h) { @@ -94,24 +92,52 @@ SoftwareRenderer::onBlit(int buf_idx, int x, int y, int w, int h) if (source != origSource) onResize(this->width(), this->height()); -#ifdef __HAIKU__ + update(); -#else - render(); -#endif + + if (monitors[r_monitor_index].mon_screenshots) { + char path[1024]; + char fn[256]; + + memset(fn, 0, sizeof(fn)); + memset(path, 0, sizeof(path)); + + path_append_filename(path, usr_path, SCREENSHOT_PATH); + + if (!plat_dir_check(path)) + plat_dir_create(path); + + path_slash(path); + strcat(path, "Monitor_"); + snprintf(&path[strlen(path)], 42, "%d_", r_monitor_index + 1); + + plat_tempfile(fn, NULL, (char *) ".png"); + strcat(path, fn); + + QPixmap pixmap(RendererCommon::parentWidget->size()); + RendererCommon::parentWidget->render(&pixmap); + QImage image = pixmap.toImage(); + image.save(path, "png"); + monitors[r_monitor_index].mon_screenshots--; + } + if (monitors[r_monitor_index].mon_screenshots_clipboard) { + QPixmap pixmap(RendererCommon::parentWidget->size()); + RendererCommon::parentWidget->render(&pixmap); + QImage image = pixmap.toImage(); + QClipboard *clipboard = QApplication::clipboard(); + clipboard->setImage(image, QClipboard::Clipboard); + monitors[r_monitor_index].mon_screenshots_clipboard--; + } + if (monitors[r_monitor_index].mon_screenshots_raw_clipboard) { + take_screenshot_clipboard_monitor(x, y, w, h, r_monitor_index); + } } void SoftwareRenderer::resizeEvent(QResizeEvent *event) { onResize(width(), height()); -#ifdef __HAIKU__ QWidget::resizeEvent(event); -#else - QWindow::resizeEvent(event); - m_backingStore->resize(event->size()); - render(); -#endif } bool @@ -119,11 +145,7 @@ SoftwareRenderer::event(QEvent *event) { bool res = false; if (!eventDelegate(event, res)) -#ifdef __HAIKU__ return QWidget::event(event); -#else - return QWindow::event(event); -#endif return res; } @@ -142,9 +164,7 @@ SoftwareRenderer::onPaint(QPaintDevice *device) #endif painter.setCompositionMode(QPainter::CompositionMode_Plus); painter.drawImage(destination, *images[cur_image], source); -#ifndef __HAIKU__ painter.end(); -#endif } std::vector> diff --git a/src/qt/qt_softwarerenderer.hpp b/src/qt/qt_softwarerenderer.hpp index e80410956..a2b11c012 100644 --- a/src/qt/qt_softwarerenderer.hpp +++ b/src/qt/qt_softwarerenderer.hpp @@ -11,21 +11,19 @@ #include "qt_renderercommon.hpp" class SoftwareRenderer : -#ifdef __HAIKU__ public QWidget, -#else - public QWindow, -#endif public RendererCommon { Q_OBJECT public: explicit SoftwareRenderer(QWidget *parent = nullptr); -#ifdef __HAIKU__ void paintEvent(QPaintEvent *event) override; -#endif +#ifdef __HAIKU__ void exposeEvent(QExposeEvent *event) override; +#else + void exposeEvent(QExposeEvent *event); +#endif std::vector> getBuffers() override; diff --git a/src/qt/qt_vulkanwindowrenderer.cpp b/src/qt/qt_vulkanwindowrenderer.cpp index 79dbc8f87..ce6b464ee 100644 --- a/src/qt/qt_vulkanwindowrenderer.cpp +++ b/src/qt/qt_vulkanwindowrenderer.cpp @@ -32,6 +32,8 @@ ****************************************************************************/ #include "qt_vulkanwindowrenderer.hpp" +#include +#include #include #include @@ -46,6 +48,8 @@ extern "C" { # include <86box/86box.h> +# include <86box/path.h> +# include <86box/plat.h> # include <86box/video.h> } # if 0 @@ -861,6 +865,8 @@ VulkanWindowRenderer::event(QEvent *event) return res; } +extern void take_screenshot_clipboard_monitor(int sx, int sy, int sw, int sh, int i); + void VulkanWindowRenderer::onBlit(int buf_idx, int x, int y, int w, int h) { @@ -873,6 +879,39 @@ VulkanWindowRenderer::onBlit(int buf_idx, int x, int y, int w, int h) this->pixelRatio = devicePixelRatio(); onResize(this->width(), this->height()); } + + if (monitors[r_monitor_index].mon_screenshots) { + char path[1024]; + char fn[256]; + + memset(fn, 0, sizeof(fn)); + memset(path, 0, sizeof(path)); + + path_append_filename(path, usr_path, SCREENSHOT_PATH); + + if (!plat_dir_check(path)) + plat_dir_create(path); + + path_slash(path); + strcat(path, "Monitor_"); + snprintf(&path[strlen(path)], 42, "%d_", r_monitor_index + 1); + + plat_tempfile(fn, NULL, (char *) ".png"); + strcat(path, fn); + + QImage image = this->grab(); + image.save(path, "png"); + monitors[r_monitor_index].mon_screenshots--; + } + if (monitors[r_monitor_index].mon_screenshots_clipboard) { + QImage image = this->grab(); + QClipboard *clipboard = QApplication::clipboard(); + clipboard->setImage(image, QClipboard::Clipboard); + monitors[r_monitor_index].mon_screenshots_clipboard--; + } + if (monitors[r_monitor_index].mon_screenshots_raw_clipboard) { + take_screenshot_clipboard_monitor(x, y, w, h, r_monitor_index); + } } uint32_t diff --git a/src/qt_resources.qrc b/src/qt_resources.qrc index dda79c0b3..4b069cb3f 100644 --- a/src/qt_resources.qrc +++ b/src/qt_resources.qrc @@ -71,6 +71,10 @@ qt/icons/interpreter.ico qt/icons/recompiler.ico qt/icons/new_vm.ico + qt/icons/take_screenshot.ico + qt/icons/take_raw_screenshot.ico + qt/icons/copy_screenshot.ico + qt/icons/copy_raw_screenshot.ico qt/icons/warning.ico diff --git a/src/unix/unix_sdl.c b/src/unix/unix_sdl.c index 8d3a71002..fdd31d901 100644 --- a/src/unix/unix_sdl.c +++ b/src/unix/unix_sdl.c @@ -156,7 +156,7 @@ sdl_blit_shim(int x, int y, int w, int h, int monitor_index) for (int row = 0; row < h; ++row) video_copy(&(((uint8_t *) pixeldata)[row * 2048 * sizeof(uint32_t)]), &(buffer32->line[y + row][x]), w * sizeof(uint32_t)); - if (monitors[monitor_index].mon_screenshots) + if (monitors[monitor_index].mon_screenshots_raw) video_screenshot((uint32_t *) pixeldata, 0, 0, 2048); blitreq = 1; diff --git a/src/video/video.c b/src/video/video.c index 4c4256a89..c1d096270 100644 --- a/src/video/video.c +++ b/src/video/video.c @@ -376,7 +376,7 @@ video_screenshot_monitor(uint32_t *buf, int start_x, int start_y, int row_len, i video_take_screenshot_monitor((const char *) path, buf, start_x, start_y, row_len, monitor_index); png_destroy_write_struct(&png_ptr[monitor_index], &info_ptr[monitor_index]); - atomic_fetch_sub(&monitors[monitor_index].mon_screenshots, 1); + atomic_fetch_sub(&monitors[monitor_index].mon_screenshots_raw, 1); } void @@ -814,6 +814,9 @@ video_monitor_init(int index) monitors[index].mon_vid_type = VIDEO_FLAG_TYPE_NONE; atomic_init(&doresize_monitors[index], 0); atomic_init(&monitors[index].mon_screenshots, 0); + atomic_init(&monitors[index].mon_screenshots_clipboard, 0); + atomic_init(&monitors[index].mon_screenshots_raw, 0); + atomic_init(&monitors[index].mon_screenshots_raw_clipboard, 0); if (index >= 1) ui_init_monitor(index); monitors[index].mon_blit_data_ptr->blit_thread = thread_create(blit_thread, monitors[index].mon_blit_data_ptr);