From 76d2bc3e7f3111f7a01d80e26556628f0df8b4a7 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sat, 19 Sep 2009 06:43:45 +0000 Subject: [PATCH] Removed outdated OS/2 support --HG-- extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/trunk%403810 --- README | 2 +- README.OS2 | 278 --- Watcom-OS2.zip | Bin 63017 -> 0 bytes docs.html | 7 - include/SDL.h | 2 +- include/SDL_config.h.default | 2 - include/SDL_config.h.in | 6 - include/SDL_config_os2.h | 145 -- include/SDL_thread.h | 14 +- include/begin_code.h | 16 - src/SDL.c | 73 +- src/audio/dart/SDL_dart.c | 448 ---- src/audio/dart/SDL_dart.h | 66 - src/events/SDL_events.c | 18 - src/events/SDL_sysevents.h | 4 - src/joystick/os2/SDL_sysjoystick.c | 698 ------- src/joystick/os2/joyos2.h | 179 -- src/loadso/os2/SDL_sysloadso.c | 77 - src/power/SDL_power.c | 4 - src/power/os2/SDL_syspower.c | 135 -- src/thread/SDL_thread_c.h | 2 - src/thread/os2/SDL_syscond.c | 223 -- src/thread/os2/SDL_syscond_c.h | 23 - src/thread/os2/SDL_sysmutex.c | 107 - src/thread/os2/SDL_syssem.c | 194 -- src/thread/os2/SDL_systhread.c | 105 - src/thread/os2/SDL_systhread_c.h | 28 - src/timer/os2/SDL_systimer.c | 235 --- src/video/SDL_sysvideo.h | 3 - src/video/SDL_video.c | 3 - src/video/os2fslib/SDL_os2fslib.c | 3122 ---------------------------- src/video/os2fslib/SDL_os2fslib.h | 72 - src/video/os2fslib/SDL_vkeys.h | 75 - 33 files changed, 8 insertions(+), 6358 deletions(-) delete mode 100644 README.OS2 delete mode 100644 Watcom-OS2.zip delete mode 100644 include/SDL_config_os2.h delete mode 100644 src/audio/dart/SDL_dart.c delete mode 100644 src/audio/dart/SDL_dart.h delete mode 100644 src/joystick/os2/SDL_sysjoystick.c delete mode 100644 src/joystick/os2/joyos2.h delete mode 100644 src/loadso/os2/SDL_sysloadso.c delete mode 100644 src/power/os2/SDL_syspower.c delete mode 100644 src/thread/os2/SDL_syscond.c delete mode 100644 src/thread/os2/SDL_syscond_c.h delete mode 100644 src/thread/os2/SDL_sysmutex.c delete mode 100644 src/thread/os2/SDL_syssem.c delete mode 100644 src/thread/os2/SDL_systhread.c delete mode 100644 src/thread/os2/SDL_systhread_c.h delete mode 100644 src/timer/os2/SDL_systimer.c delete mode 100644 src/video/os2fslib/SDL_os2fslib.c delete mode 100644 src/video/os2fslib/SDL_os2fslib.h delete mode 100644 src/video/os2fslib/SDL_vkeys.h diff --git a/README b/README index ef9a76825..bc5570f93 100644 --- a/README +++ b/README @@ -15,7 +15,7 @@ and 2D framebuffer across multiple platforms. The current version supports Linux, Windows, Windows CE, BeOS, MacOS, Mac OS X, FreeBSD, NetBSD, OpenBSD, BSD/OS, Solaris, IRIX, and QNX. The code contains support for Dreamcast, Atari, AIX, OSF/Tru64, -RISC OS, SymbianOS, and OS/2, but these are not officially supported. +RISC OS, SymbianOS, but these are not officially supported. SDL is written in C, but works with C++ natively, and has bindings to several other languages, including Ada, C#, Eiffel, Erlang, Euphoria, diff --git a/README.OS2 b/README.OS2 deleted file mode 100644 index 5718c5fef..000000000 --- a/README.OS2 +++ /dev/null @@ -1,278 +0,0 @@ - -=========== -SDL on OS/2 -=========== - -Last updated on May. 1, 2006. - - -1. How to compile? ------------------- - -To compile this, you'll need the followings installed: -- The OS/2 Developer's Toolkit -- The OpenWatcom compiler - (http://www.openwatcom.org) -- The FSLib library - (ftp://ftp.netlabs.org/pub/SDL) - -First of all, you have to unzip the Watcom-OS2.zip file. This will result in a -file called "makefile" and a file called "setvars.cmd" in this folder (and some -more files...). - -Please edit the second, fourth and fifth lines of setvars.cmd file -to set the folders where the toolkit, the OW compiler and the FSLib are. -You won't need NASM yet (The Netwide Assembler), you can leave that line. -Run setvars.cmd, and you should get a shell in which you can -compile SDL. - -Check the "makefile" file. There is a line in there which determines if the -resulting SDL.DLL will be a 'debug' or a 'release' build. The 'debug' version -is full of printf()'s, so if something goes wrong, its output can help a lot -for debugging. - -Then run "wmake". -This should create the SDL.DLL and the corresponding SDL.LIB file here. - -To test applications, it's a good idea to use the 'debug' build of SDL, and -redirect the standard output and standard error output to files, to see what -happens internally in SDL. -(like: testsprite >stdout.txt 2>stderr.txt) - -To rebuild SDL, use the following commands in this folder: -wmake clean -wmake - - - -2. How to compile the testapps? -------------------------------- - -Once you have SDL.DLL compiled, navigate into the 'test' folder, copy in there -the newly built SDL.DLL, and copy in there FSLib.DLL. - -Then run "wmake" in there to compile some of the testapps. - - - -3. What is missing? -------------------- - -The following things are missing from this SDL implementation: -- MMX, SSE and 3DNOW! optimized video blitters? -- HW Video surfaces -- OpenGL support - - - -4. Special Keys / Full-Screen support -------------------------------------- - -There are two special hot-keys implemented: -- Alt+Home switches between fullscreen and windowed mode -- Alt+End simulates closing the window (can be used as a Panic key) -Only the LEFT Alt key will work. - - - -5. Joysticks on SDL/2 ---------------------- - -The Joystick detection only works for standard joysticks (2 buttons, 2 axes -and the like). Therefore, if you use a non-standard joystick, you should -specify its features in the SDL_OS2_JOYSTICK environment variable in a batch -file or CONFIG.SYS, so SDL applications can provide full capability to your -device. The syntax is: - -SET SDL_OS2_JOYSTICK=[JOYSTICK_NAME] [AXES] [BUTTONS] [HATS] [BALLS] - -So, it you have a Gravis GamePad with 4 axes, 2 buttons, 2 hats and 0 balls, -the line should be: - -SET SDL_OS2_JOYSTICK=Gravis_GamePad 4 2 2 0 - -If you want to add spaces in your joystick name, just surround it with -quotes or double-quotes: - -SET SDL_OS2_JOYSTICK='Gravis GamePad' 4 2 2 0 - -or - -SET SDL_OS2_JOYSTICK="Gravis GamePad" 4 2 2 0 - - Notive However that Balls and Hats are not supported under OS/2, and the -value will be ignored... but it is wise to define these correctly because -in the future those can be supported. - Also the number of buttons is limited to 2 when using two joysticks, -4 when using one joystick with 4 axes, 6 when using a joystick with 3 axes -and 8 when using a joystick with 2 axes. Notice however these are limitations -of the Joystick Port hardware, not OS/2. - - - -6. Proportional windows ------------------------ - -For some SDL applications it can be handy to have proportional windows, so -the windows will keep their aspect ratio when resized. -This can be achieved in two ways: - -- Before starting the given SDL application, set the - SDL_USE_PROPORTIONAL_WINDOW environment variable to something, e.g.: - - SET SDL_USE_PROPORTIONAL_WINDOW=1 - dosbox.exe - -- If you have a HOME environment variable set, then SDL will look for a file - in there called ".sdl.proportionals". If that file contains the name of the - currently running SDL executable, then that process will have proportional - windows automatically. - - Please note that this file is created automatically with default values - at the first run. - - - -7. Audio in SDL applications ----------------------------- - -Audio effects are one of the most important features in games. Creating audio -effects in sync with the game and without hickups and pauses in the audio are -very important things. - -However there are multithreaded SDL applications that have tight loops as their -main logic loop. This kills performance in OS/2, and takes too much CPU from -other threads in the same process, for example from the thread to create the -sound effects. - -For this reason, the OS/2 port of SDL can be instructed to run the audio thread -in high priority, which makes sure that there will be enough time for the -processing of the audio data. - -At default, SDL/2 runs the audio thread at ForegroundServer+0 priority. Well -written and well behaving SDL applications should work well in this mode. -For other applications, you can tell SDL/2 to run the audio thread at -TimeCritical priority by setting an env.variable before starting the SDL app: - - SET SDL_USE_TIMECRITICAL_AUDIO=1 - -Please note that this is a bit risky, because if the SDL application runs a -tight infinite loop in this thread, this will make the whole system -unresponsive, so use it with care, and only for applications that need it! - - - -8. Next steps... ----------------- - -Things to do: -- Implement missing stuffs (look for 'TODO' string in source code!) -- Finish video driver (the 'wincommon' can be a good example for missing - things like application icon and so on...) -- Enable MMX/SSE/SSE2 acceleration functions - - - -9. Contacts ------------ - - You can contact the developers for bugs: - - Area Developer email - General (Audio/Video/System) Doodle doodle@scenergy.dfmk.hu - CDROM and Joystick Caetano daniel@caetano.eng.br - - Notice however that SDL/2 is 'in development' stage so ... if you want to help, -please, be our guest and contact us! - - - -10. Changelog of the OS/2 port ------------------------------- - -Version 1.2 - 2006-05-01 - Doodle - - Modified makefile system to have only one makefile - - Included FSLib headers, DLL and LIB file - -Version 1.2 - 2006-02-26 - Doodle - - Updated the official SDL version with the OS/2 specific changes. - - Added support for real unicode keycode conversion. - -Version 1.2.7 - 2006-01-20 - Doodle - - Added support for selectively using timecritical priority for - audio threads by SDL_USE_TIMECRITICAL_AUDIO environment variable. - (e.g.: - SET SDL_USE_TIMECRITICAL_AUDIO=1 - dosbox.exe - ) - -Version 1.2.7 - 2005-12-22 - Doodle - - Added support for proportional SDL windows. - There are two ways to have proportional (aspect-keeping) windows for - a given SDL application: Either set the SDL_USE_PROPORTIONAL_WINDOW - environment variable to something before starting the application - (e.g.: - SET SDL_USE_PROPORTIONAL_WINDOW=1 - dosbox.exe - ) - or, if you have the HOME environment variable set, then SDL.DLL will - create a file in that directory called .sdl.proportionals, and you can - put there the name of executable files that will be automatically made - proportional. - -Version 1.2.7 - 2005-10-14 - Doodle - - Enabled Exception handler code in FSLib to be able to restore original - desktop video mode in case the application crashes. - - Added the missing FSLib_Uninitialize() call into SDL. - (The lack of it did not cause problems, but it's cleaner this way.) - - Fixed a mouse problem in Fullscreen mode where any mouse click - re-centered the mouse. - -Version 1.2.7 - 2005-10-09 - Doodle - - Implemented window icon support - -Version 1.2.7 - 2005-10-03 - Doodle - - Reworked semaphore support again - - Tuned thread priorities - -Version 1.2.7 - 2005-10-02 - Doodle - - Added support for custom mouse pointers - - Fixed WM_CLOSE processing: give a chance to SDL app to ask user... - - Added support for MMX-accelerated audio mixers - - Other small fixes - -Version 1.2.7 - 2005-09-12 - Doodle - - Small fixes for DosBox incorporated into public release - - Fixed semaphore support (SDL_syssem.c) - - Fixed FSLib to have good clipping in scaled window mode, - and to prevent occasional desktop freezes. - -Version 1.2.7 - 2004-09-08a - Caetano - - Improved joystick support (general verifications about hardware). - - Added support up to 8 buttons in 2 axes joysticks and 6 buttons in 3 axes joysticks. - - Added support to environment variable SDL_OS2_JOYSTICK to specify a joystick. - - Improved Joystick test to handle every type of joystick and display only relevant information. - - Merged with Doodle 2004-09-08 - - Little tid up in README.OS2 - - Added explanation about SDL_OS2_JOYSTICK environment variable on README.OS2 - -Version 1.2.7 - 2004-09-07 - Caetano - - Merged with changes in headers for GCC compiling. - - Added Joystick support using basic IBM GAME$ support, allowing it to work with all joystick drivers since OS/2 2.1. - - Improved joystick detection (hacked!). OS/2 do not allow real joystick detection, so... - - Modified makefile in test to compile "testjoystick". Anyway, it's useless, since it seems to cause a lot of trouble in OS/2 (because os video routines, not Joystick support). - - Created separated Joystick test program to test only joystick functions. - - Improved joystick auto-centering. - - Improved the coordinate correction routine to use two scale factors for each axis. - -Version 1.2.7 - 2004-07-05 - Caetano - - Corrected the time returned by status in CDROM support (it was incorrect) - - Added the testcdrom.c and corrected the linking directive (it was causing an error) - -Version 1.2.7 - 2004-07-02a - Caetano - - Corrected a little problem in a comment at SDL-1.2.7\test\torturethread.c, line 18 (missing */, nested comment) - - Added CDROM support to tree (SDL-1.2.7\src\cdrom\os2\SDL_syscdrom.c) - - Modified makefile (SDL-1.2.7\src\makefiles.wat and SDL-1.2.7\watcom.mif) to build with CDROM support - - Added the "extra" SDL_types.h forgotten in 2004-07-02 version. - - diff --git a/Watcom-OS2.zip b/Watcom-OS2.zip deleted file mode 100644 index 603210f4b5be271749d4188c5279495be0917c4b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 63017 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 z z28Z(Shg9$mQ_=2Pg?FRui034ucLTJ)MqGY0BmNm|k&Jj{+#EodTs?u|l|g$+%Jt^P zI?wmQWbHZbJgx(8&*oTPZX(IiLps`$8FVaWu(7Ct^7Xu>6Qdy%7ft`m@IqPO9|KD2 zZ;c#CI0P&r-m}0JuuIuQ+(}98!p$~Z5L^rQJ*?w|C-0FH@P%}kJ2HsjJLB=4`k>Sn z!##)}Y20UgS&l`2SKlOY5;=A>0zXhjwdsNesPK{U)0ozEQMWkI;s4C|bL0Lf)~JA= zz>s01HXqu9g_ysGN^YGLAO0;5EgNz8`54@9D=?q*SqD64l@|daZ4KwdiHBZ>02|N% z$_pmCOG7?gOOO01-hFZC)nM@UuwX9yVdH5l8&9#Wh3iprMv5Jj)L6sF{uKbjSIql# z_b8iZsiI{jrP{=%yy<{sb+ci$MlN63cwSw%DG<6;*h0M^^2*7oWaHrZA|8$5JiGv} zmy7k;c--fVaL!vOnelD1a|h2EpKmn2uI$H)O_2nF0++cjiT5yT@k6pDpL=upjD~ip z+5a|EemXRh9zH?>@gD~;wX0E2%6m!qz=2|v9|Kaxr~9AS8hi)6pC@iV`nT$mQJZET z-LAi=ph;(#q%XM}cSZQh1O7Jh_O*Zb*780BP3i;uorB4MTI4%n6)#mRGwJaF&6%Ay zuv=NxOIU9uydhMHid{>2uPLBG72rzr980bMA{)^HD=)9s0qF~~=oQvX zu;yiw%gzN+oEQZNHXGVXo=$=MCFL_#=%$+*(nhW-ou*)^)2=-^(x)?8ym8qcTOjS) z&aaq=1(0CbJbTITuIAGl&KcdA0eVSEH(owLaVF(*Q?G_a3Yk9(P&fd!doJK~k5j;2w$8a&~Y}fusBR^u7anxxt9tea~}Tqw(o<6sPa| zKE6LY2L;M^R|W##L?fTEGXf@e9Dq6UG!BGsb_N2!<4K2S`b#hyDHfG)d>DC_h3Ex* z^i&>i63n94pFiawS$bN5b&s?hapAo3#u1#i{jbScaSl202%gkCc3(f!FGU^kV8Dy` zbp^hj!!I9x^-3{EzJ)lu6VL4uo!8GvYrVz1^TSl<^*AZwhz|)6jyJkXFxPeMD4zYyXvU%-F*q)@M48`SD#_m-`RZ=nS*B!I{%+seNj>*MAJ!UTz!%BRV)3)7mtHV zh3VRLP!Gxj8Pr_oPh87nAi8|RepA!YrW!oG) zYrvT%5=AYxbqCKxbShuGm)&Htk`Hc56&#tgN5d&U#p#M(y1nKW`5e`{0o?(98KLzW zjNke(hq9KqOm{?SIoC}MG#7^51V;3GAr0AC!ilSqwKW{UB<4oNJ1L}gD4jV${jwFY zbB@DZ2=Of)iDj37W8iK8g#9nYVnz92Mb(r=oyDrOl-OBJ_2H=~4qaTNv#_*jStFqD zFnE6$-f*w7hV#D!YhSdMdlp>r|Dj{@k>T^r(vD(Z2Jk8)wk^Z4J^l(%c4n#f4UF4iz&pIlZ(J^*-sH9%#qQSF;_u48gv%1a$|t;JLyE7?=2 zP{%}ASN=W?Qk-I9kFOzpwd6F4PO&pd9UYT$ER}?h=e-35s&se}kIMAzYCKqHsr6Fa zP3uN6TGu?(#m5PX?g?O(NZbMZb3RcBL60B>jhi5(g-W3em!Dn18bm4CGT2Ti#`7%R zI>aQD(e`}{)!V2E)eiWqo9)_4MpmOUSflOl0+dNS4a~pXl3dN11GHw zE&I&dmHiJ8Rj$+jv%*s*l{}{JUWko;59If(->VihQ?Fc8ZUcG)fW{;-Lmg0bFVZ_` ztAKR?6H$m`c=v5ZH61b1d`@kWPSx7MwfmXs1OYasR_9GGAQ=XV$b|L1CMQxeNf^KDa1Psx=RQ26 zocZkizB7$yy52wY;s;#^H9rzH2elaRfXVT!&g3X=*^dPbq0gKPAE5dMT61Fy3{DuG z1-3u?BUi0lyvVvtJ)hQx*+*mBKN%tW9mNLMbrcweIR1Z zqIvZ4yli>1j?9C&2HY`eks{`Aj+Y*UsKqp@XbRsIQRO@79*h9E3#_Z)|NCGZbEBti zIPuEic}e7o-JhZYCwZUz^)SlFrk=w~6g)pLVci^Lsi`bA0OS)XG2utCcOH4(gtS^i zK%6Bv&{z3Y`sYoyI&VxC9{^qxAzUQPJMf+w4R|x@IPe_ByWheb*GA#p_9dnqInwvM z36YRAus=n44Yl6!t~&g-l1Q&LphEL3GOcZB6b~(^Vi#+9pllm;>J5rjwMYNBX_B89IiO!v-b%K=W+G$$K z?HYAN;Hd0KPT;)&#PBN!lbi=`Hj#C=cT@nc<0#KfC-Cb&`IG`FD=}qiXv#{z0zJ0Y zdA&}`>se%S2+~A|SHtbPpMja;UBOX6HMv#*RO3I7l_Y(8ngJ_5!-2KaByzjvghLhm zit~D*_%{aX?_r=yOf^facrm5_JOtNs!2%EFR8MoNr@=dKDez9eg5}g38y>m=>k_tx z@wsX6I=n?bqV(0uRpc}|+nPC6Q1IFnRVmXscd9ti8|Um#t)1%ZPun*6u_d|~^GR=< z>tZT@!a|nl{O5~I5yH7Mq(W7F!&}Z&X*3&tpmc--LqK1NaHR1^aS%XMcX(J5&fP0 z+oaz^5uC>b3uI5Dj)$lZN&B7kn%UBe-X#;A?T|q0S)wLbDm~*|GLgq42KZc(HXK7*QZJG-p!D)&g1vM|A#j`YmzMf zzu>9b81Igxo})VHgr|?5=79g}&g-dCq-V`oi~ko){ymb~x@tBzqCKSNn#k!X-lU8M zpj9ksz0#Ga5E*xBk0%oOkN07eHJQ)3ZU&^Ojw!O);qDOu%}AGneBo-+DBnq7#&AC5 zTl^nTdr(n$$>9`N8YfOjyZY4KH0~666hdMzo%W@^;c@w2oq3yRn%V6yJWoS z4N7@@t{h6>ZjsbN5zk{eK&Z!)&wPet{^DZqnm}%jXEmSpg>=;ypX_ej8I{wjNzL_t zrG3Dp-T}0BxB&m&V17-oJjA2S{2pYtUAy!FDe7pJ9+CSE6jd@el4E#@pGKJqrSVQ8 z?=*ZQ>b=YP^oEmCFU04>nXUW`bE90PPj_G1buWr=6`3^h0@Gvf#Q|2 z#z<3kzTe8@X(I15Hk3jJX=lVK-sOSC&i)w^zu0Sb-b|B%mL$ED>Z~7| zDovGbIypy>i%luV>KNMoxIRM> z0KJaNg~{YNL|&lc%3ZFb8fC#4Jmf%ZnK(Z)`Ke^`@nTnBKpYKmI=y29@5-6UIawq# z*{`^sNamh;3+si;?$OL-j$?gJSK%Oi$?`LxNC)Xi0@8UlWpN5;lfqO|_yB=26q-n( z;4MrbH=O+&q>7%biM+7^1yJNTTzli>HN7~=p!_v->&gU*AI|XRDI{T}|Z#(-X(dX>17d_7YV$p?Q z-N?AJQXIfiB;t~tNY2WSgqCC7MDs~%nF3Gxk%!)?$E`}dIY3@1puovGp;b3;Is^0q zddHitot0VgYv){Nx$b1T7nCH3M$AM<66GZW-Qy@9hjf76yD~{$JkZk|XKX*zLbL2!kbp6y0c-09#K7t(Q9h!2lr_+2=pCccY%2yWQwR+jEpU zxpt=eXDITp3#T%1bZF_Pb?-s&M}aVPA?XkjBy>NH_Ygk2RUN)S&}WSm^;yYI$zv%k*h+DnnI#_0YLuHL(V zBOV25U{d*shGHDb3_2Z2eQJ*a+AJAh5qx-!C+(7q0c!u6?j@3br5-O8!OVTDB1l_n zwr-wc2QTNY1RL-Gy-GdI%dG53v%J!WWf#KAUfmkSdGnJ{Afo~A4^?qi&g^vnorlLZ z4&aw?)V~c-3ytow!M0k=vrz$UuPg)5@-FNHcfh!(1KK;S*Z5o;+A!Re9NzSj@oBsr z(fABUv9aFher|vwA}>D7P##T*$m30NrAbFGWVi(UT4<9Fe)!^}aENN?^3#3r2EyC4 zbtOgdpWHybBbw1(no)7xNN0bcv0(&a?>!K(Rfbu^_;eh`c@}T2q6RIyXG83*qmcx8 zMxhY1jqXnY2LL0`prV8baM`N-us=wF|9NUKt4pv@4;Q zcKwqhL%aT0*C6e?ZFpmJX4|s%8@#b?+g8W6ZFFo~9XsjRwrzIQv2EMv_#1ogd+#~- zJ9mw-R?R>4tg2Zxo&s37dmq7>l4iMO0D{ci@H4IBaC}m_5jDB&3&|i5PE7V(-&bUa zTUGviE6564Cviclp%i`eVFxXVe$ZcpS8tsU6C6eB5 zgz8Ntu-1K0vwq?J`{7~?Kc40A6ca_s9?QbLfGy8TU!yV()<|Kik z;a3fsm@&)Bn1)Hvy0EG*%_A?OEH)K~bxZMDvc$}7pvQByg~ttl(e z(BJG)&z(wQa#z}jZBH!_9Qqer+j#B9If3$ZjslD6Q|{z=hPZy(^#)_q6KS&Tx{2Wi zilLGQOlr;>=L4OndD2-og9S=*G43XBPVxC=d(@gCBhFN>6ZU&1kW03jOGx8>A*gA)JPu>)NunygZETj+I;EvUsK@Y*={&luc@Foc zHi1MZAxJ8})hZ?!d3}GVOq1SEFve$iQJi=5fi?VW6SBBL_EB3zUaU%mItfew+gTFjemURJt}EB+*Bg;< z_s{ewzM(3%8K0*tpw&TFkV`yc*(dDP0n0dClC$v$jaUU!6@v|8^ev|s;7`quq95Eh z4JuhEY%k*s6>~O6>dIpNUT~;g9lAIY9X27f5cCrXW{^49ZJ=F6h}xgU&&jlhF%L`N zV+s?5_9!N4CyS^j_&Av`{U^WFK4H_K%&HL}^B4)@aN9p}Zn3b30XIQbZ4g{YzZ9t= zjy1wY8;ufAWh>J1rpPD_vq~5yuRhx?PEBwex;&KcUZ6V={iL*i4>C->Q&Z)07X6|a zG4>;SBFX`LStQW_KV#2)Gw^JAYTG|Jy1vXM^=CYe5~;7t67A;0aP*b7vJq8?>#FAK z4I!DvZhRI$4QgN{8))k8WM+kwq|@*a3*%TkU5M%kqa=;Pgz(I6gSH6S%SO%kEk)38 z^Y=NJe{M30XuJk-u6DOU=9IRW&g8CL$5RshX`1RNzqh2s z!Gw)i{>j0kP)Hm|*ji_O@JBvMIiN)9OY(5r0w(y(_)v`0{J~ri6A@?nWmaVu zgKhDxM%8H4Sr&`sr%Mg=6{?DtNc$@!@2oN=3=eeZ`ZW=KKZS;zTb~t_N^0i{5zd@9 zUA?1m@ZFQ81rD$JAFc%gPWoEBH%{K3_6m)|Ez#^wy=X&@8b7ocXYDfH;C-s+oniGT zincHV%>bvh9uyVcicZ>*!txw4%sGN0Y>H@v!yf()8wtaywzkg}#Og4%Upj2CxARD5 zh~PILgk}%ACp}HBC9E;1iRpTeCKkCQ8A=R}Mf3{g7b4V1avYX-Uoo+=BT5^(m&Moq zgKTN9&O|D4>A1=EWm4NA`nk~5%&U<3qgi7H;=|7LkeL426W{Hk7bY55xGd7C67UOvZ~TzIg+n;lzZz@YRHoF5i*YuvJzg^^&Pe`#pgQ=f@kcu1cs2V*>b%8IOfc&q}Bx|3n-; zT}bRHrq}}G(llmC$fihqIcU}rJ@@7D4353OnV~6hIT^Uu+Ir|SR#4B&S9(QR%{gce zdM2i$q|{wD3D~sTz^;BzoBW_(=FwrFXHDupGq>~rRVUhZX5a)$*@^?YfyMkNYAe?k}DFMh^RdMB3jnxQPoG%CA7K0?=MTg==rPS z9d^MC4#_d9p^MQtd6apYXD6r_Rk3`3b*oCShcZ(ghVi?5ceBgojJ&a;fG@cxp@Q%& zFR8XC46Tc&-gt9k_1dZGB7=&j>?3T-S8gj~%4pJ*^nq5)p#CyG4%W2EXUrw;@I9!n zsolk==V0B-x6ur2T!N9`VC?*6ofsG@zn7sj8mGR>X-Yk54l8625i)D6vtX~pbsW75 z0!vGy3%>N&W3WVqV3S9P!zUM4y*iBL@&-y|w_wa*$5iLCTl32wF+LIguqFp~V5S{l zT|ZNSJrdj7J!b{3Qev=wbpv_xxTM45o(AD%2xa-U#%C#@tPz=iB0vwLB8;6gy;M@9 zjr#e7qfA|KI=R@pE-vnENtZI z-R$bl{HjEr{$jGl&YROWC+yAd@VU6R+E44fs#okM-bsJxY4pd5nzP`6b;}%d{Naw# z9zRxh)~p84eJ#0grqn{`X8w<_BqB%&#pQVsqvEebGLUVx0eS+jW^ir>Y3`R!sb!;% zb*c=wu_$H>14uRC?Vs;tYHTB%L3cdg1>LDI-ELNFCam_pa~u;0-nif({Ls*lc-qA~ zK~V?;hNTdqXC+hdF~n+u1XY{~^FINO!{4Ni+{AE2Lc(1Ub{;J(7k?(Fv5k4~wIEKM zhF6pC(l_arbYhLga3ANVDh z_j#vPr3NLF9x%4y#XV0rl&)O$mKWp&i?bI3+;!)}ys(hU`DU3ODV5(5e(&08x($08 z3_cvW2?~hv7iN~vgez^$mh&MDsE4_Vykp>g2*QYsn;1PpRB(|-w&WZq`EE;;jEt`{(MRLN*DR=OTCtWb2dMS(dMQbBH$HR(tPqB$3 z$FOl*94{tJ&MCsOMz{?D)dl7|UXa`+5086WSVsc(JyT7#32~NX0~y}l{8NuDp#mY9 zsMp0VNYSONFa87Hhp`J6#%5{l)53lM*{c7vXJmK%P?2P;yv#*bgk|053`V5kbB08A zpOZ0SpgXiG#D{fvSXXTzv+;xYVZ>l5*5J|Ej;_X>&??iMK5Z)=!~+YUJVwwHHgqW@ z7{TSuz~dGbi%ZHnWf}(EVo4OF!eR6I?o#;B)Be%gDxLz;S{@0PIL8yc zeFh>BbqoaGyLNlrLd$h~+(H`H?FJL)gn0`&yqyJOS|!zc!QI+hjmm+&#j;+;4C~mr zcD>=17bKmTEjQJt^P`LT zWYtCJy15QW(P1JN)o}xUo6f)}S5BA!o5PX^9FxVtLnNkEW65qEST6sw30sf1Vra~J zMZqjnkED?Pgx)QiFXx$YY-d80vX*$^`HcuCVCDC2Cc~Lggw5?>l^wN2;rSS$6KG&^ zJ!3On1a?qtmwRaxDhtb$c)Giiu#PR&#IU}L&OhI1Kb;tU#gX2jJ$?=Vj9 ztPKNpi~VmK*bO}S91@$&IWr=OtNG8(47MP)*IYSr7wg}Q(X{3Edi$!R0V&h3enduu zSG!uUNh20+%>c{fu7bYBDp!3hMeY1}%SqRL;vbbt);M+4@bS(!)=d8A2$F7u=NqTB z71`bk9m#g*RSu>nn5Q_iE-oTIc$Akwyxs_;=%%YK1|ocsBLvkAt7y~ti` z*oCoG_<_KUss{254eF zfyGRo0q8K_7X*NJykNrXhkt0%Ml+e4c7`}l7#agxP&~epJWIC?%_Ra*T~c-RJ4IeT z;ZJt_Y`T3!Jr2<$(>0;?&uQIWs%X(aiUs?`*NM&)$@}gl@G1fY*7Ln4Je-k(jXh;d zPP%_7>aS{7qJe6zY8TVxf4z*+{V5H9L=mg1?#bPQ()#xP8FpB?P|Pl>9^S;q!v&4O z@SK%_NjVIPh;3qNfmwJ&F0D}>&P$r_*!3i?f|lOa>Cbtf^v%ls>v`8-hpn?5L7WMx z?B@LRhUd!^oI#4Bv@~7%w&A`|)XB=3WV2^uBFsQ~t^m2v3nP8clbT>TUUXqG=kf|aH@$Atg_)w5Bi)0ecTYfLW@!pWoILcU7byd_f<_Ga2T$!Q_v6Be=aX|Rk zjsFYO&9JSP)%gKmLrZEGSd%*0w;a~iPB04$wCC>V2Jsg@H~=h@mrvr?yvuT8L_n8Q zQ3Iimk!#_s5S#~nb4 z5h@JL={PNfB&gSKTCWIkedG}?$$}8$p~UktLsZ&0B}KZ$J*(Ll0Wg>e;c;}^`cacW zH;M7q8hgMH99t1y#6Iq*4ZldcOAt-_?c}H3Do$@FHat%}S6&Ai{>0oQ#Ll)tqP*eD zZH@(+p`tGAiAtope3xAT5zzQM-+RU1Kr0Bhf?t-cQ0E zb<*$NbcYvLepz(Zq_LuR4_GhLN(*ETu(3pk_f)P?94K$6Sla%9ar`%jI*l`en&Vsj z`*>y_Lxv>uQ|;t)R@drVo{fVi;^d6ABKua0Y(8YMH~gY}t z_I;xT)5BeB*{1E4fR3b^Eo?Z1_LM_`>-XWHJq1H{OpRS>2Kq3Dbiuf}0;B@Y2KJy_ z$a6{S(9o^>qyDN7$Sh7mHVz`(U4K~pq0($lb1dAJ`D&!%YtZKQl{JS3Z+Kkls zmET|ycdH&`wID9fq;#+Kux*E@XN(C2`J?`q`jMoCUqZLAG~B@ zTX9C$7s!sk&17i820_;`E_*Y&^phL|TmWM^6YG7rn|;^7E556BStL%M*=mq-koXY>9adglW_666nAeJpQVb-Hol*a2!;=9e4= zDTPx9^-iCqfkn;2T1B}D`=7aKxQ9TB_p6X8E(E*{kG`R|Zg=)9G|K#i@1Slqn8%&7 z>QUzOB)>d*2?M6;UImOn^F|xk&qHT_>3^PI4KIjLp3Skon}_N}weutqioMKwpuUU{ zX1D1Q@cmH7={f4?a4F>7I^cF3QdMjvU7|JHpnE!>bES60P$>bx*BZH2q z(~gZX4ZVjL<@;4#Ki!NF(bh1d`epxv@fvtNt$vO8f|ly{qJ|0sJ7%8|zm#IYx|bxVTwH{29+ItHI}4XS(q)>rRKWNf~W3==Pd9 z_ue~cG#7k%^cip`kNW}r`_orbRZJ)YvQXbeukZdVn<*sRNuEUZvi^ozxQKbv!gPJH z6jeax8*$8qzF09F+b~2Di$jkTEyM<~)kncqKs&xGq@jFe@CL?c+~6-5W|T+ibtQk? zLz?n{t`|HjGz$kx$uNP06OcB*JqUtY_j12EyARo;F_>vSF`eP;eqKUa4@Js?TJ9(_ zy`z^!L?}Bm6lEQUs#eHr3^3lM&c;Hg5e_~+JaV?U-qoE^y=;M+``yx> zbA|vumtoClUcv@u>6$W0XptM772;LEhsg^uWYYh;O}?pG#9Iez7fmtCHnLBU!6kP+ z1B33!W&hmlnl;}W?3t_eJ}V9CcAw}Q!689TNU)4#;#UmZ7kZZnkuJYzj>xl8#;CU? zzH8hc7SOs0vJEp%k+BIW>ovFMY+=UuPc*liak%7XdKpi|vJ3>_{&}s_qOXQ&45&w( zjl(pYhC<}PCa0(lzAt<*Rk`U{+LfNJcIF44EPaPAc2IYf`5BbqrlxV7YeZqWI}C8U z?T`+2nE>b9b&gQoP-D$5W^5Tl0$|+oM_8ahE^lnkT9w_dXAWz6aMeIDI&Sc(aA5bG zzP33gha`Hk=}oqdHhG#kG^>gVA&ObX@njCW{gZD0_dSbuHFP!8#dQ{1ne($YbTwCH zIXTyA3r5t7$3G-oMHMl|Vy?+`^-T?P`W#Yq%qz;1C2Mmmops&X73du5%Ql!5_`*hh z9de^J^wre0E1I0tq3cCGQ!9!p!+aUppB7?jAyA%6DNA<89O@d}G#rk*JwFPYKpP_h z8vsy6hsO!iUQ?Olna8slG^Q}CH^{xeFL(!)TPBLL*)3oz{Ps2 z!KaF?=Wx0XLq{a4Nrt({(qd&TH*e9)g5K4!BAeCMQR^6*T5L$EUv}aihl#qIzt1zjPd#AN zNuI85!YFZW>5`~7fxReB_FQCouc#0+vX~fP8d8?u!=R^~kTvLNLfV&6OJ2k!ge|AW z{XNhEQ{SbHVsx{#w03S)Q8|Xh&CC!J=oTk@9Q0tb-fJx%;KGz4!?{=|1>m>mgoV5R zY?TAky$sDShsbki&H|S-fFA-oBJw^h1dgYmJ3cxS?)~5cPQ!U?m1~YomYMpapJ7t$ z6X;Du{)~u+1OZ1C(EeV#sjLJPi4qSqcUq19Z7S?Gg#e--!uxKZOTI=M5~<}(h+<_` zS-)9n9hB2(zi$clUK!uAF}tm<<2zC}6lD)R7R+n_%ja@T)>;A`I*977})Kkgnkq<(|`BRlxQZ`>A7>NFK#>kekygDY=cZRWe~O|3RN4 za|HL?Mm{VuZ@zVgzNO#qF>iK*yjbGZ66mn@#95$FOLg)4< zd0bCxD_9J@ILp;mmMZNXx_cYo_e2vM1=5BK5zTYr$SLnUNpJ@gPWSEXx_r-iSMD3z zZIv5T{K?bDtv6T=0p7vuQ{8>tQ{CgfzhjOj-&uMh8MVQ5rM4=DUUZR>=<8Zw&|Tvt zs=J$PIsw+-ChS;^jhSq)=LjpM#WY1v78oZoxP3)Js1~G|Qd(C6hmGznwb+q(iK9Xk zX(Eep#~p{aNz@|I*^`4N5s~Y~*>u)UTn~$zXHcRVU{k8=Cc}4)xiq)h9-`k(fu5%_ zAtcs9TYK*h1w-R^^&RQscQCd~vJ9;D$mFs+-x&G)XW{-x^zLvjz*T|`Vx_=_v%Y8O zYnW_n?v|}k?bzVq^1O+ds9)4=QxouN)$xZb=AODh6IM|!VQV0GV~fhLPiL`vPl+H- z%h7Ju)lXclsOs0h)Q{1tEwaafQIpwjs`ugp-?=;N_HpVRWw1F-M9QJ;7j+DOm$im1 z5^FA_Xf_$GG6c3%2Dv8e|Jf-V3hO6Y)#0kqAzAL>9i)jWnv& zJu_6MdfCC-+}aL^akrxnJ`HoLKp5@)?aNRLX)rT>vwsmszRt3Z%OPgG@34{OLgmYP zXB(6OU3bJ7-W@3`9@a>vkI}uX%c8FW%&@oyq4w7+DEgL@BqRfZZUsGWEWi?1L+CX* zUV}I|=sdtBW{1Jtii@)EVsy#jt*;s~73PX4_!3N`a6n0zydNXo?YzW;r|7bMA;sVjd<3jjiCE~?D z1F3OD)^f>*9`t=&v`A%yAc@vlU_4r5Ny&X07OT+84 z6P}B~#a0*Q-Xib}MooilqFPZ8o6GwHX$l?m;~}jMj!RgAJiZ_rN-4M2`uJPzWX88p zE7j-i>92i67e?*5E_cN9$@N_+DhMKlJEAtrosu%Uma~Z+o&v)dh-YQ85v{%tz90K% z{X;?DprW3X9U@cq^&yu52$#}OJN)x?j~lQEsV&qyGZuENZ3aQVyghGw+IStP95BHU zfNbl1`GF(;z%Z6|i)g}_WRT7QdXQ8Q1pD(}mFW%!6#CU8%Q28y=U8I{a#R05L2KvM|zr&Ul8ZCT$Ehv)ZxycODl=-1fRA$JUoV*Ky$EE z7|W;ZP?sBmj5xVTO8LoBu)XRpg)vCl#Sl}CP5-I;vA3W`GU~k!%6ca%n zQ5E#NZzwVkjIp#Z8(}t+=~$T(G%6(mi>t|k0ljz}z`Zs_0ZMd+7sT-3JIu{i00#|H zcVd3q&PH+@JY9p=wGr}bKP#83&|HT-aoAX(G}+TXVY)c-^L*8_4r`1m(5vn z?grrE1vYk;2}tEdQuSXwtV!R;msKP5Z4!Q^vxYenKdOs5j*{Md#4ca6f6#6V@Ong% zk{neAjqh&dEk4_OgW(}N63xf|x*p5&$@)-Aagx!A@gwxPp4H?xkk@O`@wH#D1JQ=^ zB#Jo_qEGtyHA7P`Q8dJFCEpe;H`fOWg6#e&`M%Ro_>;Ra3{n6Q5iqwBZaE@5{D$GMoSfDq7v*V zhEPd2@(OI2MQK33?IST!i}3=p%K~ukXX$aAGb!o=O^_tbab{$b#yG{;?$?w8k0>zKZ++;>-9E3>^psVUw+=C8a1EbjCEX~wiOeiP$6(qhtqfx~(tei1 zuW`uc&kea4V4Y9o*CSW~Bft)Xfl<@<;u#upb_ENxpc+{r+;n?_v}^;8-spLk*XpMz z7-f1Df3icuZ(wC9jkd96u{UCOCY98z7+61G%Y9h!lGF#%5Bu%{V2gH6-h#qK9s>m2 zAXFUVc*USIO`vpgfFuybIyu)&SjiM1VV!J|GnA8(INg=QmZ67Bt2KI?2ngypg+P~VS8U0yI{Z-~( z22Fp(JXK^tOuCU=5^VmazZw-yj2sIKjGENb^sc|6_dFpNnir!m6Bhgi@<55)QD#@U zi+d;$W#uN3-G2$?P7z7?5VI?VF+y6kGDQN9ZX{;f)$mG3%tkIcZd$%S@d%PA9c8=Y zL+@*lf@3PeU>wJw4xgQuUzSB4g0F$hTXD@?RH6%6HfBrBlw2V~3KtZNHHgsuEY&Dw6G?Cj1|(YGinSNhYP zSL4z^DutEO>lOvka+3Rv_3$@owm>*nNi&*|`UVQG((ags=Wdd{yRncqY>@q!`xBuc z6*&FRIQcFN8apEO6okg6I;sZ`apJaB+8i)wn@xJ5VyYP8?AjGCkG$sDib`7FS5I?h zd-bt}%2s;LhE@z?t1l~N7hSgEIOob+_CPy=2@$(XTH|Y-+tY?n(XD~lV^k5WFzKLdTI!Zl^ z^Up$*e>nXd_uHhEw!$nZoi?5ugc$_+o6`Y^ z{~w9lSQ`IL<7kAVB7f2NU-B|(Tz)_hEff(-Kaffcyw;Gd!Ej#~IImhihSD-uKU!-kh9qpJEUcfMXgxEo^3td=x()hnkhL zR6Z)`6LFt89R|uz8&Zgy`kP~-sF4nuMT-GYkgWDN+X2LSrCLK8ndaE?U zTqg10=qz%3x@e7Hd^R>0VbDGmi0HY5v>ViFKB^87UDW;61$|x274v8;U(od5K<9*7 z+H6URQzf+}eXy51X-Q4Dd-6UEf{JmcWg;(~ISE5TW^YZQ=g8xan(YXVfor9i-m$1J zeOv_exf4SYpIdKovZ|2%UR=}TOlJ`pt~=6fHU=_GvxV(070|C``y=J z72&@!;7GKHP4##cVFw5Rw4?l0*pUIYM%JcgmNuq;hrX^`OSGX|OO(S>UG!4Z)_$D> z>2u1!Q7nrc!O+&VzCd!9A-1|j_~WP8*qWg@P^-Xr$*Yoz+s*$YHi=HDh22n)e=0o2 z`}lTuGh%FYhg;wvI!oxKUOgJ@lN)&g701_+g%g3;Wof}2B!n*1bP5!4;#L$_fnsNb zdScSx4L~w>UlO7fqkQ%qjkjZha6H+upK9up$XwY%X1DLx1IZaQCTl)}Gw2Q2al-g} z5p)!R*c^CoA)+#SK#se!z3ec@SUiF6oJ8(r1pm7YiM##T(@fTy%6_Gv`4>Bl*nYd^ z+0tb;b1!QZWc}6zH1#0=cUl-wWDsPa2E`RJBNT}dQ+$-bH}SoTQP`vXPoe%G$+g;+ z)sbt>-u5qxari_`ww)%U;DS*Teqy`B$9qT@2CGblhZF)ok$1D8_6TPGku}t*IPlI!SQQY;j9f4=AT`CgDG91KQf#-)6w3A1z(_CM_bsc zqsh$`N)2v(Xm%4D^Xa#863vpcNB(rQx1@&c)}SCS%j_#ksoo_sZ{JD_ZjhNL)LvC2 zNz!l5Q0Vv*YR+f1E!y3Eveu0uORd0Wiv)>D3szrKw%pU|T{ zzY?RVsE7uy-*-gUV59o3oLyZv$t$J@wcubB>$(~Wb;fO*RgSXL)Qu~lU(W$+S;0X6 zN4%^%z$Q&%QH~BweL3IoVmsraG6ghc%xKz0QIX0XU=_ndsyc z(oY)v0anEQ@{r`>KjHB_KLi#gZDz@Itc68{^Qe7K05R2o2?QK(U3~(AHC7+$_HWD-4Xz$qY4p(BXz=R`2%R` z);%zuTw_O_1+?YoMxk3DjUx;mx{#v>xysIpA(~1=r8F%MbfYxmQ^*F=*d@u6OXh5N zBiEh=JOtYV0KOK5C`!&*$k`*DfZ^&+z48)KOF<3%Pp-yg|bil55O1i#sb?{T&GUsX?GTBWvxKt*iS?y>6 zIa>EvJL|R@6HW|_-}n^UP?WWod&4n7AcIb7h8PqBZ$v9XR0TGB(yKnm{g}`Gc{;D`h%G(`UDNjV6n7--Q?^ecqS~6>76SoDdTQ6=r65RLbE?JwOu214V5G|# z?{y|f*R@ZlU9derVFhNlc;w}^`*qxYHj-}?bG2A|0U+<030k^{$F|J-#6y7LJSuDt7s&zqPUl;{*TKjx4p2Tw&5 zyE2a-6GcbaC{UXKVkoB#UpqI?BQ%Fm6s&1&6xz*CIu7%W?82IUOK~H0t%+*-cIuhY zs_WQJ{_MClg*mrB_c_$AnY#4XI>M$?3E36N-ELFq<^!%F94N2M>R z_565*r%_TJ*Cltk050~8fW1!USj>APFV^_$_u;=DAOIQQV(RR|__yDG z`TW=G)uAE!uN!;z&1VxX$TMXJ1po*k{+WmW*7;x6w1EDfJNrvkt6E#HGogK488{NJ zS`1tWi;q}9pD%r9l1vq1X{jHGKRnlrA*d;4JN5ghG5zMMeykIWU*j_6d&bp$ORX^z z^r3Aw0LlmF$21ZHI<%Aq6R`s~h)ayBDQh}c4nHnNC1b11HwoRdM5~u>Ka&0(ic+Da|w$x1Uk&i}=;n)o?hg7`;Jwn8qf|IV6 z->D@5Yblt%o^>E=M4}WuVd0P4h@N zdVIVsUHXP3$UN-qe&Mzu{AaDUt;@qcV7Aj3W-zVPb&LC~!>kAAW-Da4SII&&FMoWw zb7gzwdgXcD$6wZ;uZiB@6i=TAQg9wKOk*tGdc(*br60i}#S(m4Vl9+U*fl%+R0XyD z@cPY95RD*|T+C6irI3TnVDkOpDZ;{H1SJTQM5V=cF?#I;Ce01(o@{la&>SdF80}6} zD5z*F6O~#tnMcpQ$1hn!Xk|x(+D;NxCK8{v8por*gDJ{@fMP=Y-)RZ~fc~$9MFM;Y z{dN3jA)}@W1pJ+~|0w^nzxk{6hgy2$N8SSfBFjJki2tKZ1ZW9l{~zUlwmIKzZ2m_1 zYXJCnl>giU{bK^i-zdR*|82tm?1X^-?1cUu<3ERx|90aqOQcTzH^$#12@vofmi%WU z`|p;>oB{r=tpx)9ZfpPDi2o$Kf2n^38s7l^H~j$tf79PT2>*99fdAvhU(qnU1^hRK u{2#&iPxAQJ-&+Ec{#*B7R00J2O(lvlK#0HM3 -

OS/2 Notes

- -
-

- Projects for building SDL on OS/2 with OpenWatcom have been contributed by Doodle. See the file README.OS2 in the SDL source distribution for details. -

- [separator] diff --git a/include/SDL.h b/include/SDL.h index afd9b77ca..8db1a1405 100644 --- a/include/SDL.h +++ b/include/SDL.h @@ -39,7 +39,7 @@ and 2D framebuffer across multiple platforms. The current version supports Linux, Windows, Windows CE, BeOS, MacOS, Mac OS X, FreeBSD, NetBSD, OpenBSD, BSD/OS, Solaris, IRIX, and QNX. The code contains support for Dreamcast, Atari, AIX, OSF/Tru64, -RISC OS, SymbianOS, and OS/2, but these are not officially supported. +RISC OS, SymbianOS, but these are not officially supported. SDL is written in C, but works with C++ natively, and has bindings to several other languages, including Ada, C#, Eiffel, Erlang, Euphoria, diff --git a/include/SDL_config.h.default b/include/SDL_config.h.default index d72d7e585..1966cb447 100644 --- a/include/SDL_config.h.default +++ b/include/SDL_config.h.default @@ -36,8 +36,6 @@ #include "SDL_config_macosx.h" #elif defined(__WIN32__) #include "SDL_config_win32.h" -#elif defined(__OS2__) -#include "SDL_config_os2.h" #else #include "SDL_config_minimal.h" #endif /* platform config */ diff --git a/include/SDL_config.h.in b/include/SDL_config.h.in index 8307c92da..4b3fb55e4 100644 --- a/include/SDL_config.h.in +++ b/include/SDL_config.h.in @@ -214,7 +214,6 @@ #undef SDL_JOYSTICK_LINUX #undef SDL_JOYSTICK_MINT #undef SDL_JOYSTICK_NDS -#undef SDL_JOYSTICK_OS2 #undef SDL_JOYSTICK_RISCOS #undef SDL_JOYSTICK_WINMM #undef SDL_JOYSTICK_USBHID @@ -230,14 +229,12 @@ #undef SDL_LOADSO_DLOPEN #undef SDL_LOADSO_DUMMY #undef SDL_LOADSO_LDG -#undef SDL_LOADSO_OS2 #undef SDL_LOADSO_WIN32 /* Enable various threading systems */ #undef SDL_THREAD_BEOS #undef SDL_THREAD_DC #undef SDL_THREAD_NDS -#undef SDL_THREAD_OS2 #undef SDL_THREAD_PTH #undef SDL_THREAD_PTHREAD #undef SDL_THREAD_PTHREAD_RECURSIVE_MUTEX @@ -251,7 +248,6 @@ #undef SDL_TIMER_DUMMY #undef SDL_TIMER_MINT #undef SDL_TIMER_NDS -#undef SDL_TIMER_OS2 #undef SDL_TIMER_RISCOS #undef SDL_TIMER_UNIX #undef SDL_TIMER_WIN32 @@ -268,7 +264,6 @@ #undef SDL_VIDEO_DRIVER_GEM #undef SDL_VIDEO_DRIVER_NANOX #undef SDL_VIDEO_DRIVER_NDS -#undef SDL_VIDEO_DRIVER_OS2FS #undef SDL_VIDEO_DRIVER_PHOTON #undef SDL_VIDEO_DRIVER_QNXGF #undef SDL_VIDEO_DRIVER_PS2GS @@ -315,7 +310,6 @@ #undef SDL_POWER_LINUX #undef SDL_POWER_WINDOWS #undef SDL_POWER_MACOSX -#undef SDL_POWER_OS2 #undef SDL_POWER_BEOS #undef SDL_POWER_NINTENDODS #undef SDL_POWER_HARDWIRED diff --git a/include/SDL_config_os2.h b/include/SDL_config_os2.h deleted file mode 100644 index c6f05f33e..000000000 --- a/include/SDL_config_os2.h +++ /dev/null @@ -1,145 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2009 Sam Lantinga - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - Sam Lantinga - slouken@libsdl.org -*/ - -#ifndef _SDL_config_os2_h -#define _SDL_config_os2_h - -#include "SDL_platform.h" - -/* This is a set of defines to configure the SDL features */ - -#if !defined(_STDINT_H_) && (!defined(HAVE_STDINT_H) || !_HAVE_STDINT_H) -typedef signed char int8_t; -typedef unsigned char uint8_t; -typedef signed short int16_t; -typedef unsigned short uint16_t; -typedef signed int int32_t; -typedef unsigned int uint32_t; -typedef unsigned int size_t; -typedef unsigned long uintptr_t; -typedef signed long long int64_t; -typedef unsigned long long uint64_t; -#endif /* !_STDINT_H_ && !HAVE_STDINT_H */ - -#define SIZEOF_VOIDP 4 -#define SDL_HAS_64BIT_TYPE 1 - -/* Use Watcom's LIBC */ -#define HAVE_LIBC 1 - -/* Useful headers */ -#define HAVE_SYS_TYPES_H 1 -#define HAVE_STDIO_H 1 -#define STDC_HEADERS 1 -#define HAVE_STDLIB_H 1 -#define HAVE_STDARG_H 1 -#define HAVE_MALLOC_H 1 -#define HAVE_MEMORY_H 1 -#define HAVE_STRING_H 1 -#define HAVE_STRINGS_H 1 -#define HAVE_INTTYPES_H 1 -#define HAVE_STDINT_H 1 -#define HAVE_CTYPE_H 1 -#define HAVE_MATH_H 1 -#define HAVE_SIGNAL_H 1 - -/* C library functions */ -#define HAVE_MALLOC 1 -#define HAVE_CALLOC 1 -#define HAVE_REALLOC 1 -#define HAVE_FREE 1 -#define HAVE_ALLOCA 1 -#define HAVE_GETENV 1 -#define HAVE_PUTENV 1 -#define HAVE_UNSETENV 1 -#define HAVE_QSORT 1 -#define HAVE_ABS 1 -#define HAVE_BCOPY 1 -#define HAVE_MEMSET 1 -#define HAVE_MEMCPY 1 -#define HAVE_MEMMOVE 1 -#define HAVE_MEMCMP 1 -#define HAVE_STRLEN 1 -#define HAVE_STRLCPY 1 -#define HAVE_STRLCAT 1 -#define HAVE_STRDUP 1 -#define HAVE__STRREV 1 -#define HAVE__STRUPR 1 -#define HAVE__STRLWR 1 -#define HAVE_INDEX 1 -#define HAVE_RINDEX 1 -#define HAVE_STRCHR 1 -#define HAVE_STRRCHR 1 -#define HAVE_STRSTR 1 -#define HAVE_ITOA 1 -#define HAVE__LTOA 1 -#define HAVE__UITOA 1 -#define HAVE__ULTOA 1 -#define HAVE_STRTOL 1 -#define HAVE__I64TOA 1 -#define HAVE__UI64TOA 1 -#define HAVE_STRTOLL 1 -#define HAVE_STRTOD 1 -#define HAVE_ATOI 1 -#define HAVE_ATOF 1 -#define HAVE_STRCMP 1 -#define HAVE_STRNCMP 1 -#define HAVE_STRICMP 1 -#define HAVE_STRCASECMP 1 -#define HAVE_SSCANF 1 -#define HAVE_SNPRINTF 1 -#define HAVE_VSNPRINTF 1 -#define HAVE_SETJMP 1 -#define HAVE_CLOCK_GETTIME 1 - -/* Enable various audio drivers */ -#define SDL_AUDIO_DRIVER_DART 1 -#define SDL_AUDIO_DRIVER_DISK 1 -#define SDL_AUDIO_DRIVER_DUMMY 1 - -/* Enable various input drivers */ -#define SDL_JOYSTICK_OS2 1 -#define SDL_HAPTIC_DUMMY 1 - -/* Enable various shared object loading systems */ -#define SDL_LOADSO_OS2 1 - -/* Enable various threading systems */ -#define SDL_THREAD_OS2 1 - -/* Enable various timer systems */ -#define SDL_TIMER_OS2 1 - -/* Enable various video drivers */ -#define SDL_VIDEO_DRIVER_DUMMY 1 -#define SDL_VIDEO_DRIVER_OS2FS 1 - -/* Enable OpenGL support */ -/* Nothing here yet for OS/2... :( */ - -/* Enable system power support */ -#define SDL_POWER_OS2 1 - -/* Enable assembly routines where available */ -#define SDL_ASSEMBLY_ROUTINES 1 - -#endif /* _SDL_config_os2_h */ diff --git a/include/SDL_thread.h b/include/SDL_thread.h index 1a8b13f2e..f0cd5bfee 100644 --- a/include/SDL_thread.h +++ b/include/SDL_thread.h @@ -48,9 +48,9 @@ struct SDL_Thread; typedef struct SDL_Thread SDL_Thread; /* Create a thread */ -#if (defined(__WIN32__) && !defined(HAVE_LIBC)) || defined(__OS2__) +#if defined(__WIN32__) && !defined(HAVE_LIBC) /* - We compile SDL into a DLL on OS/2. This means, that it's the DLL which + We compile SDL into a DLL. This means, that it's the DLL which creates a new thread for the calling process with the SDL_CreateThread() API. There is a problem with this, that only the RTL of the SDL.DLL will be initialized for those threads, and not the RTL of the calling application! @@ -67,11 +67,7 @@ typedef struct SDL_Thread SDL_Thread; #include /* This has _beginthread() and _endthread() defined! */ #endif -#ifdef __OS2__ -typedef int (*pfnSDL_CurrentBeginThread) (void (*func) (void *), void *, - unsigned, void *arg); -typedef void (*pfnSDL_CurrentEndThread) (void); -#elif __GNUC__ +#ifdef __GNUC__ typedef unsigned long (__cdecl * pfnSDL_CurrentBeginThread) (void *, unsigned, unsigned (__stdcall * @@ -96,9 +92,7 @@ SDL_CreateThread(int (SDLCALL * f) (void *), void *data, pfnSDL_CurrentBeginThread pfnBeginThread, pfnSDL_CurrentEndThread pfnEndThread); -#ifdef __OS2__ -#define SDL_CreateThread(fn, data) SDL_CreateThread(fn, data, _beginthread, _endthread) -#elif defined(_WIN32_WCE) +#if defined(_WIN32_WCE) #define SDL_CreateThread(fn, data) SDL_CreateThread(fn, data, NULL, NULL) #else #define SDL_CreateThread(fn, data) SDL_CreateThread(fn, data, _beginthreadex, _endthreadex) diff --git a/include/begin_code.h b/include/begin_code.h index 33e8e5348..e3183ba64 100644 --- a/include/begin_code.h +++ b/include/begin_code.h @@ -49,16 +49,6 @@ # else # define DECLSPEC __declspec(dllexport) # endif -# elif defined(__OS2__) -# ifdef __WATCOMC__ -# ifdef BUILD_SDL -# define DECLSPEC __declspec(dllexport) -# else -# define DECLSPEC -# endif -# else -# define DECLSPEC -# endif # else # if defined(__GNUC__) && __GNUC__ >= 4 # define DECLSPEC __attribute__ ((visibility("default"))) @@ -73,14 +63,8 @@ #if defined(__WIN32__) && !defined(__GNUC__) #define SDLCALL __cdecl #else -#ifdef __OS2__ -/* But on OS/2, we use the _System calling convention */ -/* to be compatible with every compiler */ -#define SDLCALL _System -#else #define SDLCALL #endif -#endif #endif /* SDLCALL */ /* Removed DECLSPEC on Symbian OS because SDL cannot be a DLL in EPOC */ diff --git a/src/SDL.c b/src/SDL.c index ae87fc96d..b06dbfb83 100644 --- a/src/SDL.c +++ b/src/SDL.c @@ -277,76 +277,7 @@ SDL_GetRevision(void) return SDL_REVISION; } -#if defined(__OS2__) -/* Building for OS/2 */ -#ifdef __WATCOMC__ - -#define INCL_DOSERRORS -#define INCL_DOSEXCEPTIONS -#include - -/* Exception handler to prevent the Audio thread hanging, making a zombie process! */ -ULONG _System -SDL_Main_ExceptionHandler(PEXCEPTIONREPORTRECORD pERepRec, - PEXCEPTIONREGISTRATIONRECORD pERegRec, - PCONTEXTRECORD pCtxRec, PVOID p) -{ - if (pERepRec->fHandlerFlags & EH_EXIT_UNWIND) - return XCPT_CONTINUE_SEARCH; - if (pERepRec->fHandlerFlags & EH_UNWINDING) - return XCPT_CONTINUE_SEARCH; - if (pERepRec->fHandlerFlags & EH_NESTED_CALL) - return XCPT_CONTINUE_SEARCH; - - /* Do cleanup at every fatal exception! */ - if (((pERepRec->ExceptionNum & XCPT_SEVERITY_CODE) == - XCPT_FATAL_EXCEPTION) && (pERepRec->ExceptionNum != XCPT_BREAKPOINT) - && (pERepRec->ExceptionNum != XCPT_SINGLE_STEP)) { - if (SDL_initialized & SDL_INIT_AUDIO) { - /* This removes the zombie audio thread in case of emergency. */ -#ifdef DEBUG_BUILD - printf - ("[SDL_Main_ExceptionHandler] : Calling SDL_CloseAudio()!\n"); -#endif - SDL_CloseAudio(); - } - } - return (XCPT_CONTINUE_SEARCH); -} - - -EXCEPTIONREGISTRATIONRECORD SDL_Main_xcpthand = - { 0, SDL_Main_ExceptionHandler }; - -/* The main DLL entry for DLL Initialization and Uninitialization: */ -unsigned _System -LibMain(unsigned hmod, unsigned termination) -{ - if (termination) { -#ifdef DEBUG_BUILD -/* printf("[SDL DLL Unintialization] : Removing exception handler\n"); */ -#endif - DosUnsetExceptionHandler(&SDL_Main_xcpthand); - return 1; - } else { -#ifdef DEBUG_BUILD - /* Make stdout and stderr unbuffered! */ - setbuf(stdout, NULL); - setbuf(stderr, NULL); -#endif - /* Fire up exception handler */ -#ifdef DEBUG_BUILD -/* printf("[SDL DLL Initialization] : Setting exception handler\n"); */ -#endif - /* Set exception handler */ - DosSetExceptionHandler(&SDL_Main_xcpthand); - - return 1; - } -} -#endif /* __WATCOMC__ */ - -#elif defined(__WIN32__) +#if defined(__WIN32__) #if !defined(HAVE_LIBC) || (defined(__WATCOMC__) && defined(BUILD_DLL)) /* Need to include DllMain() on Watcom C for some reason.. */ @@ -368,6 +299,6 @@ _DllMainCRTStartup(HANDLE hModule, } #endif /* building DLL with Watcom C */ -#endif /* OS/2 elif __WIN32__ */ +#endif /* __WIN32__ */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/audio/dart/SDL_dart.c b/src/audio/dart/SDL_dart.c deleted file mode 100644 index 9593aa00d..000000000 --- a/src/audio/dart/SDL_dart.c +++ /dev/null @@ -1,448 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2009 Sam Lantinga - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - Sam Lantinga - slouken@libsdl.org -*/ -#include "SDL_config.h" - -/* Allow access to a raw mixing buffer */ - -#include "SDL_timer.h" -#include "SDL_audio.h" -#include "../SDL_audio_c.h" -#include "SDL_dart.h" - -// Buffer states: -#define BUFFER_EMPTY 0 -#define BUFFER_USED 1 - -typedef struct _tMixBufferDesc -{ - int iBufferUsage; // BUFFER_EMPTY or BUFFER_USED - SDL_AudioDevice *pSDLAudioDevice; -} tMixBufferDesc, *pMixBufferDesc; - - -//--------------------------------------------------------------------- -// DARTEventFunc -// -// This function is called by DART, when an event occurs, like end of -// playback of a buffer, etc... -//--------------------------------------------------------------------- -static LONG APIENTRY -DARTEventFunc(ULONG ulStatus, PMCI_MIX_BUFFER pBuffer, ULONG ulFlags) -{ - if (ulFlags && MIX_WRITE_COMPLETE) { // Playback of buffer completed! - - // Get pointer to buffer description - pMixBufferDesc pBufDesc; - - if (pBuffer) { - pBufDesc = (pMixBufferDesc) (*pBuffer).ulUserParm; - - if (pBufDesc) { - SDL_AudioDevice *pSDLAudioDevice = pBufDesc->pSDLAudioDevice; - // Set the buffer to be empty - pBufDesc->iBufferUsage = BUFFER_EMPTY; - // And notify DART feeder thread that it will have to work a bit. - if (pSDLAudioDevice) - DosPostEventSem(pSDLAudioDevice-> - hidden->hevAudioBufferPlayed); - } - } - } - return TRUE; -} - - -static int -DART_OpenDevice(_THIS, const char *devname, int iscapture) -{ - SDL_AudioFormat test_format = SDL_FirstAudioFormat(_this->spec.format); - int valid_datatype = 0; - MCI_AMP_OPEN_PARMS AmpOpenParms; - int iDeviceOrd = 0; // Default device to be used - int bOpenShared = 1; // Try opening it shared - int iBits = 16; // Default is 16 bits signed - int iFreq = 44100; // Default is 44KHz - int iChannels = 2; // Default is 2 channels (Stereo) - int iNumBufs = 2; // Number of audio buffers: 2 - int iBufSize; - int iOpenMode; - int iSilence; - int rc; - - /* Initialize all variables that we clean on shutdown */ - _this->hidden = (struct SDL_PrivateAudioData *) - SDL_malloc((sizeof *_this->hidden)); - if (_this->hidden == NULL) { - SDL_OutOfMemory(); - return 0; - } - SDL_memset(_this->hidden, 0, (sizeof *_this->hidden)); - - // First thing is to try to open a given DART device! - SDL_memset(&AmpOpenParms, 0, sizeof(MCI_AMP_OPEN_PARMS)); - // pszDeviceType should contain the device type in low word, and device ordinal in high word! - AmpOpenParms.pszDeviceType = - (PSZ) (MCI_DEVTYPE_AUDIO_AMPMIX | (iDeviceOrd << 16)); - - iOpenMode = MCI_WAIT | MCI_OPEN_TYPE_ID; - if (bOpenShared) - iOpenMode |= MCI_OPEN_SHAREABLE; - - rc = mciSendCommand(0, MCI_OPEN, iOpenMode, (PVOID) & AmpOpenParms, 0); - if (rc != MCIERR_SUCCESS) { // No audio available?? - DART_CloseDevice(_this); - SDL_SetError("DART: Couldn't open audio device."); - return 0; - } - // Save the device ID we got from DART! - // We will use this in the next calls! - _this->hidden->iCurrDeviceOrd = iDeviceOrd = AmpOpenParms.usDeviceID; - - // Determine the audio parameters from the AudioSpec - if (_this->spec.channels > 4) - _this->spec.channels = 4; - - while ((!valid_datatype) && (test_format)) { - _this->spec.format = test_format; - valid_datatype = 1; - switch (test_format) { - case AUDIO_U8: - // Unsigned 8 bit audio data - iSilence = 0x80; - _this->hidden->iCurrBits = iBits = 8; - break; - - case AUDIO_S16LSB: - // Signed 16 bit audio data - iSilence = 0x00; - _this->hidden->iCurrBits = iBits = 16; - break; - - // !!! FIXME: int32? - - default: - valid_datatype = 0; - test_format = SDL_NextAudioFormat(); - break; - } - } - - if (!valid_datatype) { // shouldn't happen, but just in case... - // Close DART, and exit with error code! - DART_CloseDevice(_this); - SDL_SetError("Unsupported audio format"); - return 0; - } - - _this->hidden->iCurrFreq = iFreq = _this->spec.freq; - _this->hidden->iCurrChannels = iChannels = _this->spec.channels; - /* Update the fragment size as size in bytes */ - SDL_CalculateAudioSpec(&_this->spec); - _this->hidden->iCurrBufSize = iBufSize = _this->spec.size; - - // Now query this device if it supports the given freq/bits/channels! - SDL_memset(&(_this->hidden->MixSetupParms), 0, - sizeof(MCI_MIXSETUP_PARMS)); - _this->hidden->MixSetupParms.ulBitsPerSample = iBits; - _this->hidden->MixSetupParms.ulFormatTag = MCI_WAVE_FORMAT_PCM; - _this->hidden->MixSetupParms.ulSamplesPerSec = iFreq; - _this->hidden->MixSetupParms.ulChannels = iChannels; - _this->hidden->MixSetupParms.ulFormatMode = MCI_PLAY; - _this->hidden->MixSetupParms.ulDeviceType = MCI_DEVTYPE_WAVEFORM_AUDIO; - _this->hidden->MixSetupParms.pmixEvent = DARTEventFunc; - rc = mciSendCommand(iDeviceOrd, MCI_MIXSETUP, - MCI_WAIT | MCI_MIXSETUP_QUERYMODE, - &(_this->hidden->MixSetupParms), 0); - if (rc != MCIERR_SUCCESS) { // The device cannot handle this format! - // Close DART, and exit with error code! - DART_CloseDevice(_this); - SDL_SetError("Audio device doesn't support requested audio format"); - return 0; - } - // The device can handle this format, so initialize! - rc = mciSendCommand(iDeviceOrd, MCI_MIXSETUP, - MCI_WAIT | MCI_MIXSETUP_INIT, - &(_this->hidden->MixSetupParms), 0); - if (rc != MCIERR_SUCCESS) { // The device could not be opened! - // Close DART, and exit with error code! - DART_CloseDevice(_this); - SDL_SetError("Audio device could not be set up"); - return 0; - } - // Ok, the device is initialized. - // Now we should allocate buffers. For this, we need a place where - // the buffer descriptors will be: - _this->hidden->pMixBuffers = - (MCI_MIX_BUFFER *) SDL_malloc(sizeof(MCI_MIX_BUFFER) * iNumBufs); - if (!(_this->hidden->pMixBuffers)) { // Not enough memory! - // Close DART, and exit with error code! - DART_CloseDevice(_this); - SDL_OutOfMemory(); - return 0; - } - // Now that we have the place for buffer list, we can ask DART for the - // buffers! - _this->hidden->BufferParms.ulNumBuffers = iNumBufs; // Number of buffers - _this->hidden->BufferParms.ulBufferSize = iBufSize; // each with this size - _this->hidden->BufferParms.pBufList = _this->hidden->pMixBuffers; // getting descriptorts into this list - // Allocate buffers! - rc = mciSendCommand(iDeviceOrd, MCI_BUFFER, - MCI_WAIT | MCI_ALLOCATE_MEMORY, - &(_this->hidden->BufferParms), 0); - if ((rc != MCIERR_SUCCESS) - || (iNumBufs != _this->hidden->BufferParms.ulNumBuffers) - || (_this->hidden->BufferParms.ulBufferSize == 0)) { // Could not allocate memory! - // Close DART, and exit with error code! - DART_CloseDevice(_this); - SDL_SetError("DART could not allocate buffers"); - return 0; - } - _this->hidden->iCurrNumBufs = iNumBufs; - - // Ok, we have all the buffers allocated, let's mark them! - { - int i; - for (i = 0; i < iNumBufs; i++) { - pMixBufferDesc pBufferDesc = - (pMixBufferDesc) SDL_malloc(sizeof(tMixBufferDesc));; - // Check if this buffer was really allocated by DART - if ((!(_this->hidden->pMixBuffers[i].pBuffer)) - || (!pBufferDesc)) { // Wrong buffer! - DART_CloseDevice(_this); - SDL_SetError("Error at internal buffer check"); - return 0; - } - pBufferDesc->iBufferUsage = BUFFER_EMPTY; - pBufferDesc->pSDLAudioDevice = _this; - - _this->hidden->pMixBuffers[i].ulBufferLength = - _this->hidden->BufferParms.ulBufferSize; - _this->hidden->pMixBuffers[i].ulUserParm = (ULONG) pBufferDesc; // User parameter: Description of buffer - _this->hidden->pMixBuffers[i].ulFlags = 0; // Some stuff should be flagged here for DART, like end of - // audio data, but as we will continously send - // audio data, there will be no end.:) - SDL_memset(_this->hidden->pMixBuffers[i].pBuffer, iSilence, - iBufSize); - } - } - _this->hidden->iNextFreeBuffer = 0; - _this->hidden->iLastPlayedBuf = -1; - // Create event semaphore - if (DosCreateEventSem - (NULL, &(_this->hidden->hevAudioBufferPlayed), 0, FALSE) != NO_ERROR) - { - DART_CloseDevice(_this); - SDL_SetError("Could not create event semaphore"); - return 0; - } - - return 1; -} - -static void -DART_ThreadInit(_THIS) -{ - /* Increase the priority of this thread to make sure that - the audio will be continuous all the time! */ -#ifdef USE_DOSSETPRIORITY - if (SDL_getenv("SDL_USE_TIMECRITICAL_AUDIO")) { -#ifdef DEBUG_BUILD - printf - ("[DART_ThreadInit] : Setting priority to TimeCritical+0! (TID%d)\n", - SDL_ThreadID()); -#endif - DosSetPriority(PRTYS_THREAD, PRTYC_TIMECRITICAL, 0, 0); - } else { -#ifdef DEBUG_BUILD - printf - ("[DART_ThreadInit] : Setting priority to ForegroundServer+0! (TID%d)\n", - SDL_ThreadID()); -#endif - DosSetPriority(PRTYS_THREAD, PRTYC_FOREGROUNDSERVER, 0, 0); - } -#endif -} - -/* This function waits until it is possible to write a full sound buffer */ -static void -DART_WaitDevice(_THIS) -{ - int i; - pMixBufferDesc pBufDesc; - ULONG ulPostCount; - - DosResetEventSem(_this->hidden->hevAudioBufferPlayed, &ulPostCount); - // If there is already an empty buffer, then return now! - for (i = 0; i < _this->hidden->iCurrNumBufs; i++) { - pBufDesc = (pMixBufferDesc) _this->hidden->pMixBuffers[i].ulUserParm; - if (pBufDesc->iBufferUsage == BUFFER_EMPTY) - return; - } - // If there is no empty buffer, wait for one to be empty! - DosWaitEventSem(_this->hidden->hevAudioBufferPlayed, 1000); // Wait max 1 sec!!! Important! - return; -} - -static void -DART_PlayDevice(_THIS) -{ - int iFreeBuf = _this->hidden->iNextFreeBuffer; - pMixBufferDesc pBufDesc; - - pBufDesc = - (pMixBufferDesc) _this->hidden->pMixBuffers[iFreeBuf].ulUserParm; - pBufDesc->iBufferUsage = BUFFER_USED; - // Send it to DART to be queued - _this->hidden->MixSetupParms.pmixWrite(_this->hidden-> - MixSetupParms.ulMixHandle, - &(_this-> - hidden->pMixBuffers[iFreeBuf]), - 1); - - _this->hidden->iLastPlayedBuf = iFreeBuf; - iFreeBuf = (iFreeBuf + 1) % _this->hidden->iCurrNumBufs; - _this->hidden->iNextFreeBuffer = iFreeBuf; -} - -static Uint8 * -DART_GetDeviceBuf(_THIS) -{ - int iFreeBuf; - Uint8 *pResult; - pMixBufferDesc pBufDesc; - - if (_this) { - if (_this->hidden) { - iFreeBuf = _this->hidden->iNextFreeBuffer; - pBufDesc = - (pMixBufferDesc) _this->hidden-> - pMixBuffers[iFreeBuf].ulUserParm; - - if (pBufDesc) { - if (pBufDesc->iBufferUsage == BUFFER_EMPTY) { - pResult = _this->hidden->pMixBuffers[iFreeBuf].pBuffer; - return pResult; - } - } else - printf("[DART_GetDeviceBuf] : ERROR! pBufDesc = %p\n", - pBufDesc); - } else - printf("[DART_GetDeviceBuf] : ERROR! _this->hidden = %p\n", - _this->hidden); - } else - printf("[DART_GetDeviceBuf] : ERROR! _this = %p\n", _this); - return NULL; -} - -static void -DART_WaitDone(_THIS) -{ - pMixBufferDesc pBufDesc; - ULONG ulPostCount = 0; - APIRET rc = NO_ERROR; - - pBufDesc = (pMixBufferDesc) - _this->hidden->pMixBuffers[_this->hidden->iLastPlayedBuf].ulUserParm; - - while ((pBufDesc->iBufferUsage != BUFFER_EMPTY) && (rc == NO_ERROR)) { - DosResetEventSem(_this->hidden->hevAudioBufferPlayed, &ulPostCount); - rc = DosWaitEventSem(_this->hidden->hevAudioBufferPlayed, 1000); // 1 sec timeout! Important! - } -} - -static void -DART_CloseDevice(_THIS) -{ - MCI_GENERIC_PARMS GenericParms; - int rc; - int i; - - if (_this->hidden != NULL) { - // Stop DART playback - if (_this->hidden->iCurrDeviceOrd) { - rc = mciSendCommand(_this->hidden->iCurrDeviceOrd, MCI_STOP, - MCI_WAIT, &GenericParms, 0); -#ifdef SFX_DEBUG_BUILD - if (rc != MCIERR_SUCCESS) { - printf("Could not stop DART playback!\n"); - fflush(stdout); - } -#endif - } - // Close event semaphore - if (_this->hidden->hevAudioBufferPlayed) { - DosCloseEventSem(_this->hidden->hevAudioBufferPlayed); - _this->hidden->hevAudioBufferPlayed = 0; - } - // Free memory of buffer descriptions - for (i = 0; i < _this->hidden->iCurrNumBufs; i++) { - SDL_free((void *) (_this->hidden->pMixBuffers[i].ulUserParm)); - _this->hidden->pMixBuffers[i].ulUserParm = 0; - } - _this->hidden->iCurrNumBufs = 0; - - // Deallocate buffers - if (_this->hidden->iCurrDeviceOrd) { - rc = mciSendCommand(_this->hidden->iCurrDeviceOrd, MCI_BUFFER, - MCI_WAIT | MCI_DEALLOCATE_MEMORY, - &(_this->hidden->BufferParms), 0); - } - // Free bufferlist - if (_this->hidden->pMixBuffers != NULL) { - SDL_free(_this->hidden->pMixBuffers); - _this->hidden->pMixBuffers = NULL; - } - // Close dart - if (_this->hidden->iCurrDeviceOrd) { - rc = mciSendCommand(_this->hidden->iCurrDeviceOrd, MCI_CLOSE, - MCI_WAIT, &(GenericParms), 0); - } - _this->hidden->iCurrDeviceOrd = 0; - - SDL_free(_this->hidden); - _this->hidden = NULL; - } -} - - -static int -DART_Init(SDL_AudioDriverImpl * impl) -{ - /* Set the function pointers */ - impl->OpenDevice = DART_OpenDevice; - impl->ThreadInit = DART_ThreadInit; - impl->WaitDevice = DART_WaitDevice; - impl->GetDeviceBuf = DART_GetDeviceBuf; - impl->PlayDevice = DART_PlayDevice; - impl->WaitDone = DART_WaitDone; - impl->CloseDevice = DART_CloseDevice; - impl->OnlyHasDefaultOutputDevice = 1; /* !!! FIXME: is this right? */ - - return 1; -} - - -AudioBootStrap DART_bootstrap = { - "dart", "OS/2 Direct Audio RouTines (DART)", DART_Init, 0 -}; - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/audio/dart/SDL_dart.h b/src/audio/dart/SDL_dart.h deleted file mode 100644 index 5ad79c750..000000000 --- a/src/audio/dart/SDL_dart.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2009 Sam Lantinga - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - Sam Lantinga - slouken@libsdl.org -*/ -#include "SDL_config.h" - -#ifndef _SDL_dart_h -#define _SDL_dart_h - -#define INCL_TYPES -#define INCL_DOSSEMAPHORES -#define INCL_DOSRESOURCES -#define INCL_DOSMISC -#define INCL_DOSERRORS -#define INCL_DOSPROCESS - -#define INCL_OS2MM -#define INCL_MMIOOS2 -#define INCL_MCIOS2 -#include -#include // DART stuff and MMIO stuff - -#include "../SDL_sysaudio.h" - -/* Hidden "this" pointer for the audio functions */ -#define _THIS SDL_AudioDevice *_this - -/* The DirectSound objects */ -struct SDL_PrivateAudioData -{ - int iCurrDeviceOrd; - int iCurrFreq; - int iCurrBits; - int iCurrChannels; - int iCurrNumBufs; - int iCurrBufSize; - - int iLastPlayedBuf; - int iNextFreeBuffer; - - MCI_BUFFER_PARMS BufferParms; // Sound buffer parameters - MCI_MIX_BUFFER *pMixBuffers; // Sound buffers - MCI_MIXSETUP_PARMS MixSetupParms; // Mixer setup parameters - HEV hevAudioBufferPlayed; // Event semaphore to indicate that an audio buffer has been played by DART -}; - -#endif /* _SDL_dart_h */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/events/SDL_events.c b/src/events/SDL_events.c index 4bc7e216a..088a3d33e 100644 --- a/src/events/SDL_events.c +++ b/src/events/SDL_events.c @@ -84,29 +84,11 @@ SDL_Unlock_EventThread(void) } } -#ifdef __OS2__ -/* - * We'll increase the priority of GobbleEvents thread, so it will process - * events in time for sure! For this, we need the DosSetPriority() API - * from the os2.h include file. - */ -#define INCL_DOSPROCESS -#include -#include -#endif - static int SDLCALL SDL_GobbleEvents(void *unused) { event_thread = SDL_ThreadID(); -#ifdef __OS2__ -#ifdef USE_DOSSETPRIORITY - /* Increase thread priority, so it will process events in time for sure! */ - DosSetPriority(PRTYS_THREAD, PRTYC_REGULAR, +16, 0); -#endif -#endif - while (SDL_EventQ.active) { SDL_VideoDevice *_this = SDL_GetVideoDevice(); diff --git a/src/events/SDL_sysevents.h b/src/events/SDL_sysevents.h index 9941b1c44..97e26cd78 100644 --- a/src/events/SDL_sysevents.h +++ b/src/events/SDL_sysevents.h @@ -33,8 +33,4 @@ #define CANT_THREAD_EVENTS #endif -#ifdef __OS2__ /* The OS/2 event loop runs in a separate thread */ -#define MUST_THREAD_EVENTS -#endif - /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/joystick/os2/SDL_sysjoystick.c b/src/joystick/os2/SDL_sysjoystick.c deleted file mode 100644 index bce4ab84d..000000000 --- a/src/joystick/os2/SDL_sysjoystick.c +++ /dev/null @@ -1,698 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2009 Sam Lantinga - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - Sam Lantinga - slouken@libsdl.org -*/ -#include "SDL_config.h" - -#ifdef SDL_JOYSTICK_OS2 - -/* OS/2 Joystick driver, contributed by Daniel Caetano */ - -#include - -#define INCL_DOSDEVICES -#define INCL_DOSDEVIOCTL -#define INCL_DOSMEMMGR -#include -#include "joyos2.h" - -#include "SDL_joystick.h" -#include "SDL_events.h" -#include "../SDL_sysjoystick.h" -#include "../SDL_joystick_c.h" - -HFILE hJoyPort = NULL; /* Joystick GAME$ Port Address */ -#define MAX_JOYSTICKS 2 /* Maximum of two joysticks */ -#define MAX_AXES 4 /* each joystick can have up to 4 axes */ -#define MAX_BUTTONS 8 /* 8 buttons */ -#define MAX_HATS 0 /* 0 hats - OS/2 doesn't support it */ -#define MAX_BALLS 0 /* and 0 balls - OS/2 doesn't support it */ -#define AXIS_MIN -32768 /* minimum value for axes coordinate */ -#define AXIS_MAX 32767 /* maximum value for axes coordinate */ -#define MAX_JOYNAME 128 /* Joystick name may have 128 characters */ -/* limit axes to 256 possible positions to filter out noise */ -#define JOY_AXIS_THRESHOLD (((AXIS_MAX)-(AXIS_MIN))/256) -/* Calc Button Flag for buttons A to D */ -#define JOY_BUTTON_FLAG(n) (1< MAX_JOYSTICKS) - maxdevs = MAX_JOYSTICKS; - -/* Defines min/max axes values (callibration) */ - ulDataLen = sizeof(stGameCalib); - rc = DosDevIOCtl(hJoyPort, IOCTL_CAT_USER, GAME_GET_CALIB, - NULL, 0, NULL, &stGameCalib, ulDataLen, &ulDataLen); - if (rc != 0) { - joyPortClose(&hJoyPort); - SDL_SetError("Could not read callibration data."); - return -1; - } - -/* Determine how many joysticks are active */ - numdevs = 0; /* Points no device */ - ucNewJoystickMask = 0x0F; /* read all 4 joystick axis */ - ulDataLen = sizeof(ucNewJoystickMask); - rc = DosDevIOCtl(hJoyPort, IOCTL_CAT_USER, GAME_PORT_RESET, - &ucNewJoystickMask, ulDataLen, &ulDataLen, NULL, 0, - NULL); - if (rc == 0) { - ulDataLen = sizeof(stJoyStatus); - rc = DosDevIOCtl(hJoyPort, IOCTL_CAT_USER, GAME_PORT_GET, - NULL, 0, NULL, &stJoyStatus, ulDataLen, &ulDataLen); - if (rc != 0) { - joyPortClose(&hJoyPort); - SDL_SetError("Could not call joystick port."); - return -1; - } - ulLastTick = stJoyStatus.ulJs_Ticks; - while (stJoyStatus.ulJs_Ticks == ulLastTick) { - rc = DosDevIOCtl(hJoyPort, IOCTL_CAT_USER, GAME_PORT_GET, - NULL, 0, NULL, &stJoyStatus, ulDataLen, - &ulDataLen); - } - if ((stJoyStatus.ucJs_JoyStickMask & 0x03) > 0) - numdevs++; - if (((stJoyStatus.ucJs_JoyStickMask >> 2) & 0x03) > 0) - numdevs++; - } - - if (numdevs > maxdevs) - numdevs = maxdevs; - -/* If *any* joystick was detected... Let's configure SDL for them */ - if (numdevs > 0) { - /* Verify if it is a "user defined" joystick */ - if (joyGetEnv(&joycfg)) { - GAME_3POS_STRUCT *axis[4]; - axis[0] = &stGameCalib.Ax; - axis[1] = &stGameCalib.Ay; - axis[2] = &stGameCalib.Bx; - axis[3] = &stGameCalib.By; - /* Say it has one device only (user defined is always one device only) */ - numdevs = 1; - /* Define Device 0 as... */ - SYS_JoyData[0].id = 0; - /* Define Number of Axes... up to 4 */ - if (joycfg.axes > MAX_AXES) - joycfg.axes = MAX_AXES; - SYS_JoyData[0].axes = joycfg.axes; - /* Define number of buttons... 8 if 2 axes, 6 if 3 axes and 4 if 4 axes */ - maxbut = MAX_BUTTONS; - if (joycfg.axes > 2) - maxbut -= ((joycfg.axes - 2) << 1); /* MAX_BUTTONS - 2*(axes-2) */ - if (joycfg.buttons > maxbut) - joycfg.buttons = maxbut; - SYS_JoyData[0].buttons = joycfg.buttons; - /* Define number of hats */ - if (joycfg.hats > MAX_HATS) - joycfg.hats = MAX_HATS; - SYS_JoyData[0].hats = joycfg.hats; - /* Define number of balls */ - if (joycfg.balls > MAX_BALLS) - joycfg.balls = MAX_BALLS; - SYS_JoyData[0].balls = joycfg.balls; - /* Initialize Axes Callibration Values */ - for (i = 0; i < joycfg.axes; i++) { - SYS_JoyData[0].axes_min[i] = axis[i]->lower; - SYS_JoyData[0].axes_med[i] = axis[i]->centre; - SYS_JoyData[0].axes_max[i] = axis[i]->upper; - } - /* Initialize Buttons 5 to 8 structures */ - if (joycfg.buttons >= 5) - SYS_JoyData[0].buttoncalc[0] = - ((axis[2]->lower + axis[3]->centre) >> 1); - if (joycfg.buttons >= 6) - SYS_JoyData[0].buttoncalc[1] = - ((axis[3]->lower + axis[3]->centre) >> 1); - if (joycfg.buttons >= 7) - SYS_JoyData[0].buttoncalc[2] = - ((axis[2]->upper + axis[3]->centre) >> 1); - if (joycfg.buttons >= 8) - SYS_JoyData[0].buttoncalc[3] = - ((axis[3]->upper + axis[3]->centre) >> 1); - /* Intialize Joystick Name */ - SDL_strlcpy(SYS_JoyData[0].szDeviceName, joycfg.name, - SDL_arraysize(SYS_JoyData[0].szDeviceName)); - } - /* Default Init ... autoconfig */ - else { - /* if two devices were detected... configure as Joy1 4 axis and Joy2 2 axis */ - if (numdevs == 2) { - /* Define Device 0 as 4 axes, 4 buttons */ - SYS_JoyData[0].id = 0; - SYS_JoyData[0].axes = 4; - SYS_JoyData[0].buttons = 4; - SYS_JoyData[0].hats = 0; - SYS_JoyData[0].balls = 0; - SYS_JoyData[0].axes_min[0] = stGameCalib.Ax.lower; - SYS_JoyData[0].axes_med[0] = stGameCalib.Ax.centre; - SYS_JoyData[0].axes_max[0] = stGameCalib.Ax.upper; - SYS_JoyData[0].axes_min[1] = stGameCalib.Ay.lower; - SYS_JoyData[0].axes_med[1] = stGameCalib.Ay.centre; - SYS_JoyData[0].axes_max[1] = stGameCalib.Ay.upper; - SYS_JoyData[0].axes_min[2] = stGameCalib.Bx.lower; - SYS_JoyData[0].axes_med[2] = stGameCalib.Bx.centre; - SYS_JoyData[0].axes_max[2] = stGameCalib.Bx.upper; - SYS_JoyData[0].axes_min[3] = stGameCalib.By.lower; - SYS_JoyData[0].axes_med[3] = stGameCalib.By.centre; - SYS_JoyData[0].axes_max[3] = stGameCalib.By.upper; - /* Define Device 1 as 2 axes, 2 buttons */ - SYS_JoyData[1].id = 1; - SYS_JoyData[1].axes = 2; - SYS_JoyData[1].buttons = 2; - SYS_JoyData[1].hats = 0; - SYS_JoyData[1].balls = 0; - SYS_JoyData[1].axes_min[0] = stGameCalib.Bx.lower; - SYS_JoyData[1].axes_med[0] = stGameCalib.Bx.centre; - SYS_JoyData[1].axes_max[0] = stGameCalib.Bx.upper; - SYS_JoyData[1].axes_min[1] = stGameCalib.By.lower; - SYS_JoyData[1].axes_med[1] = stGameCalib.By.centre; - SYS_JoyData[1].axes_max[1] = stGameCalib.By.upper; - } - /* One joystick only? */ - else { - /* If it is joystick A... */ - if ((stJoyStatus.ucJs_JoyStickMask & 0x03) > 0) { - /* Define Device 0 as 2 axes, 4 buttons */ - SYS_JoyData[0].id = 0; - SYS_JoyData[0].axes = 2; - SYS_JoyData[0].buttons = 4; - SYS_JoyData[0].hats = 0; - SYS_JoyData[0].balls = 0; - SYS_JoyData[0].axes_min[0] = stGameCalib.Ax.lower; - SYS_JoyData[0].axes_med[0] = stGameCalib.Ax.centre; - SYS_JoyData[0].axes_max[0] = stGameCalib.Ax.upper; - SYS_JoyData[0].axes_min[1] = stGameCalib.Ay.lower; - SYS_JoyData[0].axes_med[1] = stGameCalib.Ay.centre; - SYS_JoyData[0].axes_max[1] = stGameCalib.Ay.upper; - } - /* If not, it is joystick B */ - else { - /* Define Device 1 as 2 axes, 2 buttons */ - SYS_JoyData[0].id = 1; - SYS_JoyData[0].axes = 2; - SYS_JoyData[0].buttons = 2; - SYS_JoyData[0].hats = 0; - SYS_JoyData[0].balls = 0; - SYS_JoyData[0].axes_min[0] = stGameCalib.Bx.lower; - SYS_JoyData[0].axes_med[0] = stGameCalib.Bx.centre; - SYS_JoyData[0].axes_max[0] = stGameCalib.Bx.upper; - SYS_JoyData[0].axes_min[1] = stGameCalib.By.lower; - SYS_JoyData[0].axes_med[1] = stGameCalib.By.centre; - SYS_JoyData[0].axes_max[1] = stGameCalib.By.upper; - } - } - /* Hack to define Joystick Port Names */ - if (numdevs > maxdevs) - numdevs = maxdevs; - for (i = 0; i < numdevs; i++) - SDL_snprintf(SYS_JoyData[i].szDeviceName, - SDL_arraysize(SYS_JoyData[i].szDeviceName), - "Default Joystick %c", 'A' + SYS_JoyData[i].id); - - } - } -/* Return the number of devices found */ - return (numdevs); -} - - -/***********************************************************/ -/* Function to get the device-dependent name of a joystick */ -/***********************************************************/ -const char * -SDL_SYS_JoystickName(int index) -{ -/* No need to verify if device exists, already done in upper layer */ - return (SYS_JoyData[index].szDeviceName); -} - - - -/******************************************************************************/ -/* Function to open a joystick for use. */ -/* The joystick to open is specified by the index field of the joystick. */ -/* This should fill the nbuttons and naxes fields of the joystick structure. */ -/* It returns 0, or -1 if there is an error. */ -/******************************************************************************/ -int -SDL_SYS_JoystickOpen(SDL_Joystick * joystick) -{ - int index; /* Index shortcut for index in joystick structure */ - int i; /* Generic Counter */ - -/* allocate memory for system specific hardware data */ - joystick->hwdata = - (struct joystick_hwdata *) SDL_malloc(sizeof(*joystick->hwdata)); - if (joystick->hwdata == NULL) { - SDL_OutOfMemory(); - return (-1); - } -/* Reset Hardware Data */ - SDL_memset(joystick->hwdata, 0, sizeof(*joystick->hwdata)); - -/* ShortCut Pointer */ - index = joystick->index; -/* Define offsets and scales for all axes */ - joystick->hwdata->id = SYS_JoyData[index].id; - for (i = 0; i < MAX_AXES; ++i) { - if ((i < 2) || i < SYS_JoyData[index].axes) { - joystick->hwdata->transaxes[i].offset = - ((AXIS_MAX + AXIS_MIN) >> 1) - SYS_JoyData[index].axes_med[i]; - //joystick->hwdata->transaxes[i].scale = (float)((AXIS_MAX - AXIS_MIN)/(SYS_JoyData[index].axes_max[i]-SYS_JoyData[index].axes_min[i])); - joystick->hwdata->transaxes[i].scale1 = - (float) abs((AXIS_MIN / SYS_JoyData[index].axes_min[i])); - joystick->hwdata->transaxes[i].scale2 = - (float) abs((AXIS_MAX / SYS_JoyData[index].axes_max[i])); - } else { - joystick->hwdata->transaxes[i].offset = 0; - //joystick->hwdata->transaxes[i].scale = 1.0; /* Just in case */ - joystick->hwdata->transaxes[i].scale1 = 1.0; /* Just in case */ - joystick->hwdata->transaxes[i].scale2 = 1.0; /* Just in case */ - } - } - -/* fill nbuttons, naxes, and nhats fields */ - joystick->nbuttons = SYS_JoyData[index].buttons; - joystick->naxes = SYS_JoyData[index].axes; -/* joystick->nhats = SYS_JoyData[index].hats; */ - joystick->nhats = 0; /* No support for hats at this time */ -/* joystick->nballs = SYS_JoyData[index].balls; */ - joystick->nballs = 0; /* No support for balls at this time */ - return 0; -} - - - -/***************************************************************************/ -/* Function to update the state of a joystick - called as a device poll. */ -/* This function shouldn't update the joystick structure directly, */ -/* but instead should call SDL_PrivateJoystick*() to deliver events */ -/* and update joystick device state. */ -/***************************************************************************/ -void -SDL_SYS_JoystickUpdate(SDL_Joystick * joystick) -{ - APIRET rc; /* Generic OS/2 return code */ - int index; /* index shortcurt to joystick index */ - int i; /* Generic counter */ - int normbut; /* Number of buttons reported by joystick */ - int corr; /* Correction for button names */ - Sint16 value, change; /* Values used to update axis values */ - struct _transaxes *transaxes; /* Shortcut for Correction structure */ - Uint32 pos[MAX_AXES]; /* Vector to inform the Axis status */ - ULONG ulDataLen; /* Size of data */ - GAME_STATUS_STRUCT stGameStatus; /* Joystick Status Structure */ - - ulDataLen = sizeof(stGameStatus); - rc = DosDevIOCtl(hJoyPort, IOCTL_CAT_USER, GAME_GET_STATUS, - NULL, 0, NULL, &stGameStatus, ulDataLen, &ulDataLen); - if (rc != 0) { - SDL_SetError("Could not read joystick status."); - return; /* Could not read data */ - } - -/* Shortcut pointer */ - index = joystick->index; -/* joystick motion events */ - - if (SYS_JoyData[index].id == 0) { - pos[0] = stGameStatus.curdata.A.x; - pos[1] = stGameStatus.curdata.A.y; - if (SYS_JoyData[index].axes >= 3) - pos[2] = stGameStatus.curdata.B.x; - else - pos[2] = 0; - if (SYS_JoyData[index].axes >= 4) - pos[3] = stGameStatus.curdata.B.y; - else - pos[3] = 0; - pos[4] = 0; /* OS/2 basic drivers do not support more than 4 axes joysticks */ - pos[5] = 0; - } else if (SYS_JoyData[index].id == 1) { - pos[0] = stGameStatus.curdata.B.x; - pos[1] = stGameStatus.curdata.B.y; - pos[2] = 0; - pos[3] = 0; - pos[4] = 0; - pos[5] = 0; - } - -/* Corrects the movements using the callibration */ - transaxes = joystick->hwdata->transaxes; - for (i = 0; i < joystick->naxes; i++) { - value = pos[i] + transaxes[i].offset; - if (value < 0) { - value *= transaxes[i].scale1; - if (value > 0) - value = AXIS_MIN; - } else { - value *= transaxes[i].scale2; - if (value < 0) - value = AXIS_MAX; - } - change = (value - joystick->axes[i]); - if ((change < -JOY_AXIS_THRESHOLD) || (change > JOY_AXIS_THRESHOLD)) { - SDL_PrivateJoystickAxis(joystick, (Uint8) i, (Sint16) value); - } - } - -/* joystick button A to D events */ - if (SYS_JoyData[index].id == 1) - corr = 2; - else - corr = 0; - normbut = 4; /* Number of normal buttons */ - if (joystick->nbuttons < normbut) - normbut = joystick->nbuttons; - for (i = corr; (i - corr) < normbut; ++i) { - /* - Button A: 1110 0000 - Button B: 1101 0000 - Button C: 1011 0000 - Button D: 0111 0000 - */ - if ((~stGameStatus.curdata.butMask) >> 4 & JOY_BUTTON_FLAG(i)) { - if (!joystick->buttons[i - corr]) { - SDL_PrivateJoystickButton(joystick, (Uint8) (i - corr), - SDL_PRESSED); - } - } else { - if (joystick->buttons[i - corr]) { - SDL_PrivateJoystickButton(joystick, (Uint8) (i - corr), - SDL_RELEASED); - } - } - } - -/* Joystick button E to H buttons */ - /* - Button E: Axis 2 X Left - Button F: Axis 2 Y Up - Button G: Axis 2 X Right - Button H: Axis 2 Y Down - */ - if (joystick->nbuttons >= 5) { - if (stGameStatus.curdata.B.x < SYS_JoyData[index].buttoncalc[0]) - SDL_PrivateJoystickButton(joystick, (Uint8) 4, SDL_PRESSED); - else - SDL_PrivateJoystickButton(joystick, (Uint8) 4, SDL_RELEASED); - } - if (joystick->nbuttons >= 6) { - if (stGameStatus.curdata.B.y < SYS_JoyData[index].buttoncalc[1]) - SDL_PrivateJoystickButton(joystick, (Uint8) 5, SDL_PRESSED); - else - SDL_PrivateJoystickButton(joystick, (Uint8) 5, SDL_RELEASED); - } - if (joystick->nbuttons >= 7) { - if (stGameStatus.curdata.B.x > SYS_JoyData[index].buttoncalc[2]) - SDL_PrivateJoystickButton(joystick, (Uint8) 6, SDL_PRESSED); - else - SDL_PrivateJoystickButton(joystick, (Uint8) 6, SDL_RELEASED); - } - if (joystick->nbuttons >= 8) { - if (stGameStatus.curdata.B.y > SYS_JoyData[index].buttoncalc[3]) - SDL_PrivateJoystickButton(joystick, (Uint8) 7, SDL_PRESSED); - else - SDL_PrivateJoystickButton(joystick, (Uint8) 7, SDL_RELEASED); - } - -/* joystick hat events */ -/* Not Supported under OS/2 */ -/* joystick ball events */ -/* Not Supported under OS/2 */ -} - - - -/******************************************/ -/* Function to close a joystick after use */ -/******************************************/ -void -SDL_SYS_JoystickClose(SDL_Joystick * joystick) -{ - if (joystick->hwdata != NULL) { - /* free system specific hardware data */ - SDL_free(joystick->hwdata); - } -} - - - -/********************************************************************/ -/* Function to perform any system-specific joystick related cleanup */ -/********************************************************************/ -void -SDL_SYS_JoystickQuit(void) -{ - joyPortClose(&hJoyPort); -} - - - -/************************/ -/************************/ -/* OS/2 Implementations */ -/************************/ -/************************/ - - -/*****************************************/ -/* Open Joystick Port, if not opened yet */ -/*****************************************/ -APIRET -joyPortOpen(HFILE * hGame) -{ - APIRET rc; /* Generic Return Code */ - ULONG ulAction; /* ? */ - ULONG ulVersion; /* Version of joystick driver */ - ULONG ulDataLen; /* Size of version data */ - -/* Verifies if joyport is not already open... */ - if (*hGame != NULL) - return 0; -/* Open GAME$ for read */ - rc = DosOpen((PSZ) GAMEPDDNAME, hGame, &ulAction, 0, FILE_READONLY, - FILE_OPEN, OPEN_ACCESS_READONLY | OPEN_SHARE_DENYNONE, NULL); - if (rc != 0) { - SDL_SetError("Could not open Joystick Port."); - return -1; - } - -/* Get Joystick Driver Version... must be 2.0 or higher */ - ulVersion = 0; - ulDataLen = sizeof(ulVersion); - rc = DosDevIOCtl(*hGame, IOCTL_CAT_USER, GAME_GET_VERSION, - NULL, 0, NULL, &ulVersion, ulDataLen, &ulDataLen); - if (rc != 0) { - joyPortClose(hGame); - SDL_SetError("Could not get Joystick Driver version."); - return -1; - } - if (ulVersion < GAME_VERSION) { - joyPortClose(hGame); - SDL_SetError - ("Driver too old. At least IBM driver version 2.0 required."); - return -1; - } - return 0; -} - - - -/****************************/ -/* Close JoyPort, if opened */ -/****************************/ -void -joyPortClose(HFILE * hGame) -{ - if (*hGame != NULL) - DosClose(*hGame); - *hGame = NULL; -} - - - -/***************************/ -/* Get SDL Joystick EnvVar */ -/***************************/ -int -joyGetEnv(struct _joycfg *joydata) -{ - char *joyenv; /* Pointer to tested character */ - char tempnumber[5]; /* Temporary place to put numeric texts */ - - joyenv = SDL_getenv("SDL_OS2_JOYSTICK"); - if (joyenv == NULL) - return 0; -/* Joystick Environment is defined! */ - while (*joyenv == ' ' && *joyenv != 0) - joyenv++; /* jump spaces... */ -/* If the string name starts with '... get if fully */ - if (*joyenv == '\'') - joyenv += - joyGetData(++joyenv, joydata->name, '\'', sizeof(joydata->name)); -/* If not, get it until the next space */ - else if (*joyenv == '\"') - joyenv += - joyGetData(++joyenv, joydata->name, '\"', sizeof(joydata->name)); - else - joyenv += - joyGetData(joyenv, joydata->name, ' ', sizeof(joydata->name)); -/* Now get the number of axes */ - while (*joyenv == ' ' && *joyenv != 0) - joyenv++; /* jump spaces... */ - joyenv += joyGetData(joyenv, tempnumber, ' ', sizeof(tempnumber)); - joydata->axes = atoi(tempnumber); -/* Now get the number of buttons */ - while (*joyenv == ' ' && *joyenv != 0) - joyenv++; /* jump spaces... */ - joyenv += joyGetData(joyenv, tempnumber, ' ', sizeof(tempnumber)); - joydata->buttons = atoi(tempnumber); -/* Now get the number of hats */ - while (*joyenv == ' ' && *joyenv != 0) - joyenv++; /* jump spaces... */ - joyenv += joyGetData(joyenv, tempnumber, ' ', sizeof(tempnumber)); - joydata->hats = atoi(tempnumber); -/* Now get the number of balls */ - while (*joyenv == ' ' && *joyenv != 0) - joyenv++; /* jump spaces... */ - joyenv += joyGetData(joyenv, tempnumber, ' ', sizeof(tempnumber)); - joydata->balls = atoi(tempnumber); - return 1; -} - - - -/************************************************************************/ -/* Get a text from in the string starting in joyenv until it finds */ -/* the stopchar or maxchars is reached. The result is placed in name. */ -/************************************************************************/ -int -joyGetData(char *joyenv, char *name, char stopchar, size_t maxchars) -{ - char *nameptr; /* Pointer to the selected character */ - int chcnt = 0; /* Count how many characters where copied */ - - nameptr = name; - while (*joyenv != stopchar && *joyenv != 0) { - if (nameptr < (name + (maxchars - 1))) { - *nameptr = *joyenv; /* Only copy if smaller than maximum */ - nameptr++; - } - chcnt++; - joyenv++; - } - if (*joyenv == stopchar) { - joyenv++; /* Jump stopchar */ - chcnt++; - } - *nameptr = 0; /* Mark last byte */ - return chcnt; -} - -#endif /* SDL_JOYSTICK_OS2 */ -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/joystick/os2/joyos2.h b/src/joystick/os2/joyos2.h deleted file mode 100644 index 0ceace1bc..000000000 --- a/src/joystick/os2/joyos2.h +++ /dev/null @@ -1,179 +0,0 @@ -/*****************************************************************************/ -/* */ -/* COPYRIGHT Copyright (C) 1995 IBM Corporation */ -/* */ -/* The following IBM OS/2 source code is provided to you solely for */ -/* the purpose of assisting you in your development of OS/2 device */ -/* drivers. You may use this code in accordance with the IBM License */ -/* Agreement provided in the IBM Device Driver Source Kit for OS/2. This */ -/* Copyright statement may not be removed. */ -/* */ -/*****************************************************************************/ -#ifndef JOYOS2_H -#define JOYOS2_H - -/****** GAMEPORT.SYS joystick definitions, start *****************************/ -#define GAME_VERSION 0x20 /* 2.0 First IBM version */ -#define GAMEPDDNAME "GAME$ " -#define IOCTL_CAT_USER 0x80 -#define GAME_PORT_GET 0x20 /* read GAMEPORT.SYS values */ -#define GAME_PORT_RESET 0x60 /* reset joystick mask with given value */ - -#pragma pack(1) /* pack structure size is 1 byte */ -typedef struct -{ /* GAMEPORT.SYS structure */ - USHORT usJs_AxCnt; /* Joystick_A X position */ - USHORT usJs_AyCnt; /* Joystick_A Y position */ - USHORT usJs_BxCnt; /* Joystick_B X position */ - USHORT usJs_ByCnt; /* Joystick_B Y position */ - USHORT usJs_ButtonA1Cnt; /* button A1 press count */ - USHORT usJs_ButtonA2Cnt; /* button A2 press count */ - USHORT usJs_ButtonB1Cnt; /* button B1 press count */ - USHORT usJs_ButtonB2Cnt; /* button B2 press count */ - UCHAR ucJs_JoyStickMask; /* mask of connected joystick pots */ - UCHAR ucJs_ButtonStatus; /* bits of switches down */ - ULONG ulJs_Ticks; /* joystick clock ticks */ -} GAME_PORT_STRUCT; -#pragma pack() /*reset to normal pack size */ -/****** GAMEPORT.SYS joystick definitions, end *******************************/ - - -/****************************************************************************/ -#define GAME_GET_VERSION 0x01 -#define GAME_GET_PARMS 0x02 -#define GAME_SET_PARMS 0x03 -#define GAME_GET_CALIB 0x04 -#define GAME_SET_CALIB 0x05 -#define GAME_GET_DIGSET 0x06 -#define GAME_SET_DIGSET 0x07 -#define GAME_GET_STATUS 0x10 -#define GAME_GET_STATUS_BUTWAIT 0x11 -#define GAME_GET_STATUS_SAMPWAIT 0x12 -/****************************************************************************/ - -/****************************************************************************/ -// bit masks for each axis -#define JOY_AX_BIT 0x01 -#define JOY_AY_BIT 0x02 -#define JOY_A_BITS (JOY_AX_BIT|JOY_AY_BIT) -#define JOY_BX_BIT 0x04 -#define JOY_BY_BIT 0x08 -#define JOY_B_BITS (JOY_BX_BIT|JOY_BY_BIT) -#define JOY_ALLPOS_BITS (JOY_A_BITS|JOY_B_BITS) - -// bit masks for each button -#define JOY_BUT1_BIT 0x10 -#define JOY_BUT2_BIT 0x20 -#define JOY_BUT3_BIT 0x40 -#define JOY_BUT4_BIT 0x80 -#define JOY_ALL_BUTS (JOY_BUT1_BIT|JOY_BUT2_BIT|JOY_BUT3_BIT|JOY_BUT4_BIT) -/****************************************************************************/ - -/****************************************************************************/ -// 1-D position struct used for each axis -typedef SHORT GAME_POS; /* some data formats require signed values */ - -// simple 2-D position for each joystick -typedef struct -{ - GAME_POS x; - GAME_POS y; -} -GAME_2DPOS_STRUCT; - -// struct defining the instantaneous state of both sticks and all buttons -typedef struct -{ - GAME_2DPOS_STRUCT A; - GAME_2DPOS_STRUCT B; - USHORT butMask; -} -GAME_DATA_STRUCT; - -// struct to be used for calibration and digital response on each axis -typedef struct -{ - GAME_POS lower; - GAME_POS centre; - GAME_POS upper; -} -GAME_3POS_STRUCT; -/****************************************************************************/ - -/****************************************************************************/ -// status struct returned to OS/2 applications: -// current data for all sticks as well as button counts since last read -typedef struct -{ - GAME_DATA_STRUCT curdata; - USHORT b1cnt; - USHORT b2cnt; - USHORT b3cnt; - USHORT b4cnt; -} -GAME_STATUS_STRUCT; -/****************************************************************************/ - -/****************************************************************************/ -/* in use bitmasks originating in 0.2b */ -#define GAME_USE_BOTH_OLDMASK 0x01 /* for backward compat with bool */ -#define GAME_USE_X_NEWMASK 0x02 -#define GAME_USE_Y_NEWMASK 0x04 -#define GAME_USE_X_EITHERMASK (GAME_USE_X_NEWMASK|GAME_USE_BOTH_OLDMASK) -#define GAME_USE_Y_EITHERMASK (GAME_USE_Y_NEWMASK|GAME_USE_BOTH_OLDMASK) -#define GAME_USE_BOTH_NEWMASK (GAME_USE_X_NEWMASK|GAME_USE_Y_NEWMASK) - -/* only timed sampling implemented in version 1.0 */ -#define GAME_MODE_TIMED 1 /* timed sampling */ -#define GAME_MODE_REQUEST 2 /* request driven sampling */ - -/* only raw implemented in version 1.0 */ -#define GAME_DATA_FORMAT_RAW 1 /* [l,c,r] */ -#define GAME_DATA_FORMAT_SIGNED 2 /* [-l,0,+r] */ -#define GAME_DATA_FORMAT_BINARY 3 /* {-1,0,+1} */ -#define GAME_DATA_FORMAT_SCALED 4 /* [-10,+10] */ - -// parameters defining the operation of the driver -typedef struct -{ - USHORT useA; /* new bitmasks: see above */ - USHORT useB; - USHORT mode; /* see consts above */ - USHORT format; /* see consts above */ - USHORT sampDiv; /* samp freq = 32 / n */ - USHORT scale; /* scaling factor */ - USHORT res1; /* must be 0 */ - USHORT res2; /* must be 0 */ -} -GAME_PARM_STRUCT; -/****************************************************************************/ - -/****************************************************************************/ -// calibration values for each axis: -// - upper limit on value to be considered in lower range -// - centre value -// - lower limit on value to be considered in upper range -typedef struct -{ - GAME_3POS_STRUCT Ax; - GAME_3POS_STRUCT Ay; - GAME_3POS_STRUCT Bx; - GAME_3POS_STRUCT By; -} -GAME_CALIB_STRUCT; -/****************************************************************************/ - -/****************************************************************************/ -// struct defining the digital response values for all axes -typedef struct -{ - GAME_3POS_STRUCT Ax; - GAME_3POS_STRUCT Ay; - GAME_3POS_STRUCT Bx; - GAME_3POS_STRUCT By; -} -GAME_DIGSET_STRUCT; -/****************************************************************************/ - -#endif -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/loadso/os2/SDL_sysloadso.c b/src/loadso/os2/SDL_sysloadso.c deleted file mode 100644 index 2fe9b55cc..000000000 --- a/src/loadso/os2/SDL_sysloadso.c +++ /dev/null @@ -1,77 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2009 Sam Lantinga - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - Sam Lantinga - slouken@libsdl.org -*/ -#include "SDL_config.h" - -#ifdef SDL_LOADSO_OS2 - -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -/* System dependent library loading routines */ - -#include -#define INCL_DOSERRORS -#define INCL_DOSMODULEMGR -#include - -#include "SDL_loadso.h" - -void * -SDL_LoadObject(const char *sofile) -{ - HMODULE handle = NULL; - char buf[512]; - APIRET ulrc = DosLoadModule(buf, sizeof(buf), (char *) sofile, &handle); - - /* Generate an error message if all loads failed */ - if ((ulrc != NO_ERROR) || (handle == NULL)) - SDL_SetError("Failed loading %s: %s", sofile, buf); - - return ((void *) handle); -} - -void * -SDL_LoadFunction(void *handle, const char *name) -{ - const char *loaderror = "Unknown error"; - void *symbol = NULL; - APIRET ulrc = - DosQueryProcAddr((HMODULE) handle, 0, (char *) name, &symbol); - if (ulrc == ERROR_INVALID_HANDLE) - loaderror = "Invalid module handle"; - else if (ulrc == ERROR_INVALID_NAME) - loaderror = "Symbol not found"; - - if (symbol == NULL) - SDL_SetError("Failed loading %s: %s", name, loaderror); - - return (symbol); -} - -void -SDL_UnloadObject(void *handle) -{ - if (handle != NULL) - DosFreeModule((HMODULE) handle); -} - -#endif /* SDL_LOADSO_OS2 */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/power/SDL_power.c b/src/power/SDL_power.c index ed8ca73f5..9e7ea6f38 100644 --- a/src/power/SDL_power.c +++ b/src/power/SDL_power.c @@ -34,7 +34,6 @@ SDL_bool SDL_GetPowerInfo_Linux_proc_acpi(SDL_PowerState *, int *, int *); SDL_bool SDL_GetPowerInfo_Linux_proc_apm(SDL_PowerState *, int *, int *); SDL_bool SDL_GetPowerInfo_Windows(SDL_PowerState *, int *, int *); SDL_bool SDL_GetPowerInfo_MacOSX(SDL_PowerState *, int *, int *); -SDL_bool SDL_GetPowerInfo_OS2(SDL_PowerState *, int *, int *); SDL_bool SDL_GetPowerInfo_BeOS(SDL_PowerState *, int *, int *); SDL_bool SDL_GetPowerInfo_NintendoDS(SDL_PowerState *, int *, int *); @@ -65,9 +64,6 @@ static SDL_GetPowerInfo_Impl implementations[] = { #ifdef SDL_POWER_MACOSX /* handles Mac OS X, Darwin, iPhone. */ SDL_GetPowerInfo_MacOSX, #endif -#ifdef SDL_POWER_OS2 /* handles OS/2, Warp, eComStation. */ - SDL_GetPowerInfo_OS2, -#endif #ifdef SDL_POWER_NINTENDODS /* handles Nintendo DS. */ SDL_GetPowerInfo_NintendoDS, #endif diff --git a/src/power/os2/SDL_syspower.c b/src/power/os2/SDL_syspower.c deleted file mode 100644 index 401f4c2c8..000000000 --- a/src/power/os2/SDL_syspower.c +++ /dev/null @@ -1,135 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2009 Sam Lantinga - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - Sam Lantinga - slouken@libsdl.org -*/ -#include "SDL_config.h" - -/* !!! FIXME: - * Please note that this code has not been tested (or even compiled!). It - * should, in theory, run on any version of OS/2, and work with any system - * that has APM.SYS loaded. I don't know if ACPI.SYS works. - */ - -#ifndef SDL_POWER_DISABLED -#ifdef SDL_POWER_OS2 - -#define INCL_DOSFILEMGR -#define INCL_DOSDEVICES -#define INCL_DOSDEVIOCTL -#define INCL_DOSERRORS -#include - -#include "SDL_power.h" - -typedef struct -{ - USHORT len; - USHORT flags; - UCHAR ac_status; - UCHAR battery_status; - UCHAR battery_life; - UCHAR battery_time_form; - USHORT battery_time; - UCHAR battery_flags; -} PowerStatus; -extern int CompilerAssertPowerStatus[(sizeof(PowerStatus) == 10) ? 1 : -1]; - - -SDL_bool -SDL_GetPowerInfo_OS2(SDL_PowerState * state, int *seconds, int *percent) -{ - PowerStatus status; - HFILE hfile = 0; - ULONG action = 0; - APIRET rc = 0; - - *state = SDL_POWERSTATE_UNKNOWN; - *percent = -1; - *seconds = -1; - - /* open the power management device */ - rc = DosOpen("APM$", &hfile, &action, 0, FILE_NORMAL, FILE_OPEN, - OPEN_ACCESS_READONLY | OPEN_SHARE_DENYNONE, 0); - - if (rc == NO_ERROR) { - USHORT iorc = 0; - ULONG iorclen = sizeof(iorc); - ULONG statuslen = sizeof(status); - - SDL_memset(&status, '\0', sizeof(status)); - status.len = sizeof(status); - - rc = DosDevIOCtl(hfile, IOCTL_POWER, POWER_GETPOWERSTATUS, &status, - statuslen, &statuslen, &iorc, iorclen, &iorclen); - DosClose(hfile); - - /* (status.flags & 0x1) == power subsystem enabled. */ - if ((rc == NO_ERROR) && (status.flags & 0x1)) { - if (statuslen == 7) { /* older OS/2 APM driver? Less fields. */ - status.battery_time_form = 0xFF; - status.battery_time = 0; - if (status.battery_status == 0xFF) { - status.battery_flags = 0xFF; - } else { - status.battery_flags = (1 << status.battery_status); - } - } - - if (status.battery_flags == 0xFF) { /* unknown state */ - *state = SDL_POWERSTATE_UNKNOWN; - } else if (status.battery_flags & (1 << 7)) { /* no battery */ - *state = SDL_POWERSTATE_NO_BATTERY; - } else if (status.battery_flags & (1 << 3)) { /* charging */ - *state = SDL_POWERSTATE_CHARGING; - need_details = SDL_TRUE; - } else if (status.ac_status == 1) { - *state = SDL_POWERSTATE_CHARGED; /* on AC, not charging. */ - need_details = SDL_TRUE; - } else { - *state = SDL_POWERSTATE_ON_BATTERY; /* not on AC. */ - need_details = SDL_TRUE; - } - - if (need_details) { - const int pct = (int) status.battery_life; - const int secs = (int) status.battery_time; - - if (pct != 0xFF) { /* 255 == unknown */ - *percent = (pct > 100) ? 100 : pct; - } - - if (status.battery_time_form == 0xFF) { /* unknown */ - *seconds = -1; - } else if (status.battery_time_form == 1) { /* minutes */ - *seconds = secs * 60; - } else { - *seconds = secs; - } - } - } - } - - return SDL_TRUE; /* always the definitive answer on OS/2. */ -} - -#endif /* SDL_POWER_OS2 */ -#endif /* SDL_POWER_DISABLED */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/thread/SDL_thread_c.h b/src/thread/SDL_thread_c.h index e895a3487..80bce186a 100644 --- a/src/thread/SDL_thread_c.h +++ b/src/thread/SDL_thread_c.h @@ -33,8 +33,6 @@ #include "dc/SDL_systhread_c.h" #elif SDL_THREAD_EPOC #include "epoc/SDL_systhread_c.h" -#elif SDL_THREAD_OS2 -#include "os2/SDL_systhread_c.h" #elif SDL_THREAD_PTH #include "pth/SDL_systhread_c.h" #elif SDL_THREAD_PTHREAD diff --git a/src/thread/os2/SDL_syscond.c b/src/thread/os2/SDL_syscond.c deleted file mode 100644 index a6e8c434a..000000000 --- a/src/thread/os2/SDL_syscond.c +++ /dev/null @@ -1,223 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2009 Sam Lantinga - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - Sam Lantinga - slouken@libsdl.org -*/ -#include "SDL_config.h" - -/* An implementation of condition variables using semaphores and mutexes */ -/* - This implementation borrows heavily from the BeOS condition variable - implementation, written by Christopher Tate and Owen Smith. Thanks! - */ - -#include "SDL_thread.h" - -struct SDL_cond -{ - SDL_mutex *lock; - int waiting; - int signals; - SDL_sem *wait_sem; - SDL_sem *wait_done; -}; - -/* Create a condition variable */ -DECLSPEC SDL_cond *SDLCALL -SDL_CreateCond(void) -{ - SDL_cond *cond; - - cond = (SDL_cond *) SDL_malloc(sizeof(SDL_cond)); - if (cond) { - cond->lock = SDL_CreateMutex(); - cond->wait_sem = SDL_CreateSemaphore(0); - cond->wait_done = SDL_CreateSemaphore(0); - cond->waiting = cond->signals = 0; - if (!cond->lock || !cond->wait_sem || !cond->wait_done) { - SDL_DestroyCond(cond); - cond = NULL; - } - } else { - SDL_OutOfMemory(); - } - return (cond); -} - -/* Destroy a condition variable */ -DECLSPEC void SDLCALL -SDL_DestroyCond(SDL_cond * cond) -{ - if (cond) { - if (cond->wait_sem) { - SDL_DestroySemaphore(cond->wait_sem); - } - if (cond->wait_done) { - SDL_DestroySemaphore(cond->wait_done); - } - if (cond->lock) { - SDL_DestroyMutex(cond->lock); - } - SDL_free(cond); - } -} - -/* Restart one of the threads that are waiting on the condition variable */ -DECLSPEC int SDLCALL -SDL_CondSignal(SDL_cond * cond) -{ - if (!cond) { - SDL_SetError("Passed a NULL condition variable"); - return -1; - } - - /* If there are waiting threads not already signalled, then - signal the condition and wait for the thread to respond. - */ - SDL_LockMutex(cond->lock); - if (cond->waiting > cond->signals) { - ++cond->signals; - SDL_SemPost(cond->wait_sem); - SDL_UnlockMutex(cond->lock); - SDL_SemWait(cond->wait_done); - } else { - SDL_UnlockMutex(cond->lock); - } - - return 0; -} - -/* Restart all threads that are waiting on the condition variable */ -DECLSPEC int SDLCALL -SDL_CondBroadcast(SDL_cond * cond) -{ - if (!cond) { - SDL_SetError("Passed a NULL condition variable"); - return -1; - } - - /* If there are waiting threads not already signalled, then - signal the condition and wait for the thread to respond. - */ - SDL_LockMutex(cond->lock); - if (cond->waiting > cond->signals) { - int i, num_waiting; - - num_waiting = (cond->waiting - cond->signals); - cond->signals = cond->waiting; - for (i = 0; i < num_waiting; ++i) { - SDL_SemPost(cond->wait_sem); - } - /* Now all released threads are blocked here, waiting for us. - Collect them all (and win fabulous prizes!) :-) - */ - SDL_UnlockMutex(cond->lock); - for (i = 0; i < num_waiting; ++i) { - SDL_SemWait(cond->wait_done); - } - } else { - SDL_UnlockMutex(cond->lock); - } - - return 0; -} - -/* Wait on the condition variable for at most 'ms' milliseconds. - The mutex must be locked before entering this function! - The mutex is unlocked during the wait, and locked again after the wait. - -Typical use: - -Thread A: - SDL_LockMutex(lock); - while ( ! condition ) { - SDL_CondWait(cond); - } - SDL_UnlockMutex(lock); - -Thread B: - SDL_LockMutex(lock); - ... - condition = true; - ... - SDL_UnlockMutex(lock); - */ -DECLSPEC int SDLCALL -SDL_CondWaitTimeout(SDL_cond * cond, SDL_mutex * mutex, Uint32 ms) -{ - int retval; - - if (!cond) { - SDL_SetError("Passed a NULL condition variable"); - return -1; - } - - /* Obtain the protection mutex, and increment the number of waiters. - This allows the signal mechanism to only perform a signal if there - are waiting threads. - */ - SDL_LockMutex(cond->lock); - ++cond->waiting; - SDL_UnlockMutex(cond->lock); - - /* Unlock the mutex, as is required by condition variable semantics */ - SDL_UnlockMutex(mutex); - - /* Wait for a signal */ - if (ms == SDL_MUTEX_MAXWAIT) { - retval = SDL_SemWait(cond->wait_sem); - } else { - retval = SDL_SemWaitTimeout(cond->wait_sem, ms); - } - - /* Let the signaler know we have completed the wait, otherwise - the signaler can race ahead and get the condition semaphore - if we are stopped between the mutex unlock and semaphore wait, - giving a deadlock. See the following URL for details: - http://www-classic.be.com/aboutbe/benewsletter/volume_III/Issue40.html - */ - SDL_LockMutex(cond->lock); - if (cond->signals > 0) { - /* If we timed out, we need to eat a condition signal */ - if (retval > 0) { - SDL_SemWait(cond->wait_sem); - } - /* We always notify the signal thread that we are done */ - SDL_SemPost(cond->wait_done); - - /* Signal handshake complete */ - --cond->signals; - } - --cond->waiting; - SDL_UnlockMutex(cond->lock); - - /* Lock the mutex, as is required by condition variable semantics */ - SDL_LockMutex(mutex); - - return retval; -} - -/* Wait on the condition variable forever */ -DECLSPEC int SDLCALL -SDL_CondWait(SDL_cond * cond, SDL_mutex * mutex) -{ - return SDL_CondWaitTimeout(cond, mutex, SDL_MUTEX_MAXWAIT); -} - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/thread/os2/SDL_syscond_c.h b/src/thread/os2/SDL_syscond_c.h deleted file mode 100644 index 5ba245f12..000000000 --- a/src/thread/os2/SDL_syscond_c.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2009 Sam Lantinga - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - Sam Lantinga - slouken@libsdl.org -*/ -#include "SDL_config.h" -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/thread/os2/SDL_sysmutex.c b/src/thread/os2/SDL_sysmutex.c deleted file mode 100644 index 475537e83..000000000 --- a/src/thread/os2/SDL_sysmutex.c +++ /dev/null @@ -1,107 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2009 Sam Lantinga - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - Sam Lantinga - slouken@libsdl.org -*/ -#include "SDL_config.h" - -/* Mutex functions using the OS/2 API */ - -#define INCL_DOSERRORS -#define INCL_DOSSEMAPHORES -#include - -#include "SDL_mutex.h" - - -struct SDL_mutex -{ - HMTX hmtxID; -}; - -/* Create a mutex */ -DECLSPEC SDL_mutex *SDLCALL -SDL_CreateMutex(void) -{ - SDL_mutex *mutex; - APIRET ulrc; - - /* Allocate mutex memory */ - mutex = (SDL_mutex *) SDL_malloc(sizeof(*mutex)); - if (mutex) { - /* Create the mutex, with initial value signaled */ - ulrc = DosCreateMutexSem(NULL, // Create unnamed semaphore - &(mutex->hmtxID), // Pointer to handle - 0L, // Flags: create it private (not shared) - FALSE); // Initial value: unowned - if (ulrc != NO_ERROR) { - SDL_SetError("Couldn't create mutex"); - SDL_free(mutex); - mutex = NULL; - } - } else { - SDL_OutOfMemory(); - } - return (mutex); -} - -/* Free the mutex */ -DECLSPEC void SDLCALL -SDL_DestroyMutex(SDL_mutex * mutex) -{ - if (mutex) { - if (mutex->hmtxID) { - DosCloseMutexSem(mutex->hmtxID); - mutex->hmtxID = 0; - } - SDL_free(mutex); - } -} - -/* Lock the mutex */ -DECLSPEC int SDLCALL -SDL_mutexP(SDL_mutex * mutex) -{ - if (mutex == NULL) { - SDL_SetError("Passed a NULL mutex"); - return -1; - } - if (DosRequestMutexSem(mutex->hmtxID, SEM_INDEFINITE_WAIT) != NO_ERROR) { - SDL_SetError("Couldn't wait on mutex"); - return -1; - } - return (0); -} - -/* Unlock the mutex */ -DECLSPEC int SDLCALL -SDL_mutexV(SDL_mutex * mutex) -{ - if (mutex == NULL) { - SDL_SetError("Passed a NULL mutex"); - return -1; - } - if (DosReleaseMutexSem(mutex->hmtxID) != NO_ERROR) { - SDL_SetError("Couldn't release mutex"); - return -1; - } - return (0); -} - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/thread/os2/SDL_syssem.c b/src/thread/os2/SDL_syssem.c deleted file mode 100644 index b6eb3e8b1..000000000 --- a/src/thread/os2/SDL_syssem.c +++ /dev/null @@ -1,194 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2009 Sam Lantinga - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - Sam Lantinga - slouken@libsdl.org -*/ -#include "SDL_config.h" - -/* Semaphore functions using the OS/2 API */ - -#define INCL_DOS -#define INCL_DOSERRORS -#define INCL_DOSSEMAPHORES -#include - -#include "SDL_thread.h" -#include "SDL_timer.h" - - -struct SDL_semaphore -{ - HMTX id; - HEV changed; - Uint32 value; -}; - - -/* Create a semaphore */ -DECLSPEC SDL_sem *SDLCALL -SDL_CreateSemaphore(Uint32 initial_value) -{ - SDL_sem *sem; - ULONG ulrc; - - /* Allocate sem memory */ - sem = (SDL_sem *) SDL_malloc(sizeof(*sem)); - if (sem) { - /* Create the mutex semaphore */ - ulrc = DosCreateMutexSem(NULL, &(sem->id), 0, TRUE); - if (ulrc) { - SDL_SetError("Couldn't create semaphore"); - SDL_free(sem); - sem = NULL; - } else { - DosCreateEventSem(NULL, &(sem->changed), 0, FALSE); - sem->value = initial_value; - DosReleaseMutexSem(sem->id); - } - } else { - SDL_OutOfMemory(); - } - return (sem); -} - -/* Free the semaphore */ -DECLSPEC void SDLCALL -SDL_DestroySemaphore(SDL_sem * sem) -{ - if (sem) { - if (sem->id) { - DosCloseEventSem(sem->changed); - DosCloseMutexSem(sem->id); - sem->id = 0; - } - SDL_free(sem); - } -} - -DECLSPEC int SDLCALL -SDL_SemWaitTimeout(SDL_sem * sem, Uint32 timeout) -{ - ULONG ulrc; - - if (!sem) { - SDL_SetError("Passed a NULL sem"); - return -1; - } - - if (timeout == SDL_MUTEX_MAXWAIT) { - while (1) { - ulrc = DosRequestMutexSem(sem->id, SEM_INDEFINITE_WAIT); - if (ulrc) { - /* if error waiting mutex */ - SDL_SetError("DosRequestMutexSem() failed"); - return -1; - } else if (sem->value) { - sem->value--; - DosReleaseMutexSem(sem->id); - return 0; - } else { - ULONG ulPostCount; - DosResetEventSem(sem->changed, &ulPostCount); - DosReleaseMutexSem(sem->id); - /* continue waiting until somebody posts the semaphore */ - DosWaitEventSem(sem->changed, SEM_INDEFINITE_WAIT); - } - } - } else if (timeout == 0) { - ulrc = DosRequestMutexSem(sem->id, SEM_INDEFINITE_WAIT); - if (ulrc == NO_ERROR) { - if (sem->value) { - sem->value--; - DosReleaseMutexSem(sem->id); - return 0; - } else { - DosReleaseMutexSem(sem->id); - return SDL_MUTEX_TIMEDOUT; - } - } else { - SDL_SetError("DosRequestMutexSem() failed"); - return -1; - } - } else { - ulrc = DosRequestMutexSem(sem->id, SEM_INDEFINITE_WAIT); - if (ulrc) { - /* if error waiting mutex */ - SDL_SetError("DosRequestMutexSem() failed"); - return -1; - } else if (sem->value) { - sem->value--; - DosReleaseMutexSem(sem->id); - return 0; - } else { - ULONG ulPostCount; - DosResetEventSem(sem->changed, &ulPostCount); - DosReleaseMutexSem(sem->id); - /* continue waiting until somebody posts the semaphore */ - ulrc = DosWaitEventSem(sem->changed, timeout); - if (ulrc == NO_ERROR) - return 0; - else - return SDL_MUTEX_TIMEDOUT; - } - } - /* never reached */ - return -1; -} - -DECLSPEC int SDLCALL -SDL_SemTryWait(SDL_sem * sem) -{ - return SDL_SemWaitTimeout(sem, 0); -} - -DECLSPEC int SDLCALL -SDL_SemWait(SDL_sem * sem) -{ - return SDL_SemWaitTimeout(sem, SDL_MUTEX_MAXWAIT); -} - -/* Returns the current count of the semaphore */ -DECLSPEC Uint32 SDLCALL -SDL_SemValue(SDL_sem * sem) -{ - if (!sem) { - SDL_SetError("Passed a NULL sem"); - return 0; - } - return sem->value; -} - -DECLSPEC int SDLCALL -SDL_SemPost(SDL_sem * sem) -{ - if (!sem) { - SDL_SetError("Passed a NULL sem"); - return -1; - } - if (DosRequestMutexSem(sem->id, SEM_INDEFINITE_WAIT)) { - SDL_SetError("DosRequestMutexSem() failed"); - return -1; - } - sem->value++; - DosPostEventSem(sem->changed); - DosReleaseMutexSem(sem->id); - return 0; -} - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/thread/os2/SDL_systhread.c b/src/thread/os2/SDL_systhread.c deleted file mode 100644 index 02e800dae..000000000 --- a/src/thread/os2/SDL_systhread.c +++ /dev/null @@ -1,105 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2009 Sam Lantinga - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - Sam Lantinga - slouken@libsdl.org -*/ -#include "SDL_config.h" - -/* OS/2 thread management routines for SDL */ - -#include -#define INCL_DOSERRORS -#define INCL_DOSPROCESS -#include - -#include "SDL_thread.h" -#include "../SDL_systhread.h" -#include "../SDL_thread_c.h" - -typedef struct ThreadStartParms -{ - void *args; - pfnSDL_CurrentEndThread pfnCurrentEndThread; -} tThreadStartParms, *pThreadStartParms; - -static void -threadfunc(void *pparm) -{ - pThreadStartParms pThreadParms = pparm; - pfnSDL_CurrentEndThread pfnCurrentEndThread = NULL; - - // Call the thread function! - SDL_RunThread(pThreadParms->args); - - // Get the current endthread we have to use! - if (pThreadParms) { - pfnCurrentEndThread = pThreadParms->pfnCurrentEndThread; - SDL_free(pThreadParms); - } - // Call endthread! - if (pfnCurrentEndThread) - (*pfnCurrentEndThread) (); -} - -int -SDL_SYS_CreateThread(SDL_Thread * thread, void *args, - pfnSDL_CurrentBeginThread pfnBeginThread, - pfnSDL_CurrentEndThread pfnEndThread) -{ - pThreadStartParms pThreadParms = SDL_malloc(sizeof(tThreadStartParms)); - if (!pThreadParms) { - SDL_SetError("Not enough memory to create thread"); - return (-1); - } - // Save the function which we will have to call to clear the RTL of calling app! - pThreadParms->pfnCurrentEndThread = pfnEndThread; - // Also save the real parameters we have to pass to thread function - pThreadParms->args = args; - // Start the thread using the runtime library of calling app! - thread->threadid = thread->handle = - (*pfnBeginThread) (threadfunc, NULL, 512 * 1024, pThreadParms); - if ((int) thread->threadid <= 0) { - SDL_SetError("Not enough resources to create thread"); - return (-1); - } - return (0); -} - -void -SDL_SYS_SetupThread(void) -{ - return; -} - -DECLSPEC Uint32 SDLCALL -SDL_ThreadID(void) -{ - PTIB tib; - DosGetInfoBlocks(&tib, NULL); - return ((Uint32) (tib->tib_ptib2->tib2_ultid)); -} - -void -SDL_SYS_WaitThread(SDL_Thread * thread) -{ - TID tid = thread->handle; - DosWaitThread(&tid, DCWW_WAIT); -} - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/thread/os2/SDL_systhread_c.h b/src/thread/os2/SDL_systhread_c.h deleted file mode 100644 index c84acd244..000000000 --- a/src/thread/os2/SDL_systhread_c.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2009 Sam Lantinga - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - Sam Lantinga - slouken@libsdl.org -*/ -#include "SDL_config.h" - -#define INCL_DOSPROCESS -#include - -typedef TID SYS_ThreadHandle; -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/timer/os2/SDL_systimer.c b/src/timer/os2/SDL_systimer.c deleted file mode 100644 index 4a72104a8..000000000 --- a/src/timer/os2/SDL_systimer.c +++ /dev/null @@ -1,235 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2009 Sam Lantinga - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - Sam Lantinga - slouken@libsdl.org -*/ -#include "SDL_config.h" - -#ifdef SDL_TIMER_OS2 - -#define INCL_DOSMISC -#define INCL_DOSERRORS -#define INCL_DOSSEMAPHORES -#define INCL_DOSDATETIME -#define INCL_DOSPROCESS -#define INCL_DOSPROFILE -#define INCL_DOSEXCEPTIONS -#include - -#include "SDL_thread.h" -#include "SDL_timer.h" -#include "../SDL_timer_c.h" - - -#define TIME_WRAP_VALUE (~(DWORD)0) - -/* The first high-resolution ticks value of the application */ -static long long hires_start_ticks; -/* The number of ticks per second of the high-resolution performance counter */ -static ULONG hires_ticks_per_second; - -void -SDL_StartTicks(void) -{ - DosTmrQueryFreq(&hires_ticks_per_second); - DosTmrQueryTime((PQWORD) & hires_start_ticks); -} - -DECLSPEC Uint32 SDLCALL -SDL_GetTicks(void) -{ - long long hires_now; - ULONG ticks = ticks; - - DosTmrQueryTime((PQWORD) & hires_now); -/* - hires_now -= hires_start_ticks; - hires_now *= 1000; - hires_now /= hires_ticks_per_second; -*/ - /* inline asm to avoid runtime inclusion */ - /* *INDENT-OFF* */ - _asm { - push edx - push eax - mov eax, dword ptr hires_now - mov edx, dword ptr hires_now + 4 - sub eax, dword ptr hires_start_ticks - sbb edx, dword ptr hires_start_ticks + 4 - mov ebx, 1000 - mov ecx, edx - mul ebx - push eax - push edx - mov eax, ecx - mul ebx - pop eax - add edx, eax - pop eax - mov ebx, dword ptr hires_ticks_per_second - div ebx - mov dword ptr ticks, eax - pop edx - pop eax - } - /* *INDENT-ON* */ - - return ticks; - -} - -/* High resolution sleep, originally made by Ilya Zakharevich */ -DECLSPEC void SDLCALL -SDL_Delay(Uint32 ms) -{ - /* This is similar to DosSleep(), but has 8ms granularity in time-critical - threads even on Warp3. */ - HEV hevEvent1 = 0; /* Event semaphore handle */ - HTIMER htimerEvent1 = 0; /* Timer handle */ - APIRET rc = NO_ERROR; /* Return code */ - int ret = 1; - ULONG priority = 0, nesting; /* Shut down the warnings */ - PPIB pib; - PTIB tib; - char *e = NULL; - APIRET badrc; - int switch_priority = 50; - - DosCreateEventSem(NULL, /* Unnamed */ - &hevEvent1, /* Handle of semaphore returned */ - DC_SEM_SHARED, /* Shared needed for DosAsyncTimer */ - FALSE); /* Semaphore is in RESET state */ - - if (ms >= switch_priority) - switch_priority = 0; - if (switch_priority) { - if (DosGetInfoBlocks(&tib, &pib) != NO_ERROR) - switch_priority = 0; - else { - /* In Warp3, to switch scheduling to 8ms step, one needs to do - DosAsyncTimer() in time-critical thread. On laters versions, - more and more cases of wait-for-something are covered. - - It turns out that on Warp3fp42 it is the priority at the time - of DosAsyncTimer() which matters. Let's hope that this works - with later versions too... XXXX - */ - priority = (tib->tib_ptib2->tib2_ulpri); - if ((priority & 0xFF00) == 0x0300) /* already time-critical */ - switch_priority = 0; - /* Make us time-critical. Just modifying TIB is not enough... */ - /* tib->tib_ptib2->tib2_ulpri = 0x0300; */ - /* We do not want to run at high priority if a signal causes us - to longjmp() out of this section... */ - if (DosEnterMustComplete(&nesting)) - switch_priority = 0; - else - DosSetPriority(PRTYS_THREAD, PRTYC_TIMECRITICAL, 0, 0); - } - } - - if ((badrc = DosAsyncTimer(ms, (HSEM) hevEvent1, /* Semaphore to post */ - &htimerEvent1))) /* Timer handler (returned) */ - e = "DosAsyncTimer"; - - if (switch_priority && tib->tib_ptib2->tib2_ulpri == 0x0300) { - /* Nobody switched priority while we slept... Ignore errors... */ - /* tib->tib_ptib2->tib2_ulpri = priority; *//* Get back... */ - if (! - (rc = DosSetPriority(PRTYS_THREAD, (priority >> 8) & 0xFF, 0, 0))) - rc = DosSetPriority(PRTYS_THREAD, 0, priority & 0xFF, 0); - } - if (switch_priority) - rc = DosExitMustComplete(&nesting); /* Ignore errors */ - - /* The actual blocking call is made with "normal" priority. This way we - should not bother with DosSleep(0) etc. to compensate for us interrupting - higher-priority threads. The goal is to prohibit the system spending too - much time halt()ing, not to run us "no matter what". */ - if (!e) /* Wait for AsyncTimer event */ - badrc = DosWaitEventSem(hevEvent1, SEM_INDEFINITE_WAIT); - - if (e); /* Do nothing */ - else if (badrc == ERROR_INTERRUPT) - ret = 0; - else if (badrc) - e = "DosWaitEventSem"; - if ((rc = DosCloseEventSem(hevEvent1)) && !e) { /* Get rid of semaphore */ - e = "DosCloseEventSem"; - badrc = rc; - } - if (e) { - SDL_SetError("[SDL_Delay] : Had error in %s(), rc is 0x%x\n", e, - badrc); - } -} - -/* Data to handle a single periodic alarm */ -static int timer_alive = 0; -static SDL_Thread *timer = NULL; - -static int SDLCALL -RunTimer(void *unused) -{ - DosSetPriority(PRTYS_THREAD, PRTYC_TIMECRITICAL, 0, 0); - while (timer_alive) { - if (SDL_timer_running) { - SDL_ThreadedTimerCheck(); - } - SDL_Delay(10); - } - return (0); -} - -/* This is only called if the event thread is not running */ -int -SDL_SYS_TimerInit(void) -{ - timer_alive = 1; - timer = SDL_CreateThread(RunTimer, NULL); - if (timer == NULL) - return (-1); - return (SDL_SetTimerThreaded(1)); -} - -void -SDL_SYS_TimerQuit(void) -{ - timer_alive = 0; - if (timer) { - SDL_WaitThread(timer, NULL); - timer = NULL; - } -} - -int -SDL_SYS_StartTimer(void) -{ - SDL_SetError("Internal logic error: OS/2 uses threaded timer"); - return (-1); -} - -void -SDL_SYS_StopTimer(void) -{ - return; -} - -#endif /* SDL_TIMER_OS2 */ -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/SDL_sysvideo.h b/src/video/SDL_sysvideo.h index 3d0ac7937..f828de709 100644 --- a/src/video/SDL_sysvideo.h +++ b/src/video/SDL_sysvideo.h @@ -395,9 +395,6 @@ extern VideoBootStrap DC_bootstrap; #if SDL_VIDEO_DRIVER_RISCOS extern VideoBootStrap RISCOS_bootstrap; #endif -#if SDL_VIDEO_DRIVER_OS2FS -extern VideoBootStrap OS2FSLib_bootstrap; -#endif #if SDL_VIDEO_DRIVER_UIKIT extern VideoBootStrap UIKIT_bootstrap; #endif diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c index 14e603d74..2f8ce810b 100644 --- a/src/video/SDL_video.c +++ b/src/video/SDL_video.c @@ -109,9 +109,6 @@ static VideoBootStrap *bootstrap[] = { #if SDL_VIDEO_DRIVER_RISCOS &RISCOS_bootstrap, #endif -#if SDL_VIDEO_DRIVER_OS2FS - &OS2FSLib_bootstrap, -#endif #if SDL_VIDEO_DRIVER_NDS &NDS_bootstrap, #endif diff --git a/src/video/os2fslib/SDL_os2fslib.c b/src/video/os2fslib/SDL_os2fslib.c deleted file mode 100644 index 9c2ba79ab..000000000 --- a/src/video/os2fslib/SDL_os2fslib.c +++ /dev/null @@ -1,3122 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2009 Sam Lantinga - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - Sam Lantinga - slouken@libsdl.org -*/ -#include "SDL_config.h" - -#define _ULS_CALLCONV_ -#define CALLCONV _System -#include // Unicode API -#include // Unicode API (codepage conversion) - -#include -#include - -#include "SDL_video.h" -#include "SDL_mouse.h" -#include "../SDL_sysvideo.h" -#include "../SDL_pixels_c.h" -#include "../../events/SDL_events_c.h" - -#include "SDL_os2fslib.h" - -static ULONG ulFCFToUse = - FCF_TITLEBAR | - FCF_SYSMENU | - FCF_MINBUTTON | - FCF_MAXBUTTON | FCF_NOBYTEALIGN | FCF_SIZEBORDER | FCF_TASKLIST; - -static int bMouseCaptured = 0; -static int bMouseCapturable = 0; -static HPOINTER hptrGlobalPointer = NULL; -static HPOINTER hptrCurrentIcon = NULL; -static int iWindowSizeX = 320; -static int iWindowSizeY = 200; -static int bWindowResized = 0; - -#pragma pack(1) -typedef struct BMPINFO -{ - BITMAPINFO; - RGB clr; -} BMPINFO, *PBMPINFO; -#pragma pack() - - -// Backdoors: -DECLSPEC void SDLCALL -SDL_OS2FSLIB_SetFCFToUse(ULONG ulFCF) -{ - ulFCFToUse = ulFCF; -} - -// Configuration defines: - -// We have to report empty alpha mask, otherwise SDL will select -// alpha blitters, and this will have unwanted results, as we don't -// support alpha channel in FSLib yet. -#define REPORT_EMPTY_ALPHA_MASK - -// Experimental: Move every FSLib_BitBlt() call into window message -// processing function. -// This may fix dirt left on desktop. Or not. -//#define BITBLT_IN_WINMESSAGEPROC - -// Experimental-2: Use WinLockWindowUpdate() in around bitblts! -// This is not enabled, because it seems to cause more problems -// than good. -//#define USE_WINLOCKWINDOWUPDATE_AROUND_BITBLTS - -// Use the following to show resized image instead of black stuff -// even if the surface is resizable. -//#define RESIZE_EVEN_IF_RESIZABLE - -/* The translation table from a VK keysym to a SDL keysym */ -static SDLKey HWScanKeyMap[256]; -static SDL_keysym *TranslateKey(int vkey, int chcode, int scancode, - SDL_keysym * keysym, int iPressed); -static int iShiftIsPressed; - -#ifdef BITBLT_IN_WINMESSAGEPROC -#define WM_UPDATERECTSREQUEST WM_USER+50 -#endif - -#ifdef USE_WINLOCKWINDOWUPDATE_AROUND_BITBLTS -#define FSLIB_BITBLT(hwnd, buffer, top, left, width, height) \ - { \ - WinLockWindowUpdate(HWND_DESKTOP, HWND_DESKTOP); \ - FSLib_BitBlt(hwnd, buffer, top, left, width, height); \ - WinLockWindowUpdate(HWND_DESKTOP, NULL); \ - } -#else -#define FSLIB_BITBLT(hwnd, buffer, top, left, width, height) \ - FSLib_BitBlt(hwnd, buffer, top, left, width, height); -#endif - -///////////////////////////////////////////////////////////////////// -// -// SetAccessableWindowPos -// -// Same as WinSetWindowPos(), but takes care for the window to be -// always on the screen, the titlebar will be accessable everytime. -// -///////////////////////////////////////////////////////////////////// -static BOOL -SetAccessableWindowPos(HWND hwnd, HWND hwndInsertBehind, - LONG x, LONG y, LONG cx, LONG cy, ULONG fl) -{ - SWP swpDesktop, swp; - // Get desktop area - WinQueryWindowPos(HWND_DESKTOP, &swpDesktop); - - if ((fl & SWP_MOVE) && (fl & SWP_SIZE)) { - // If both moving and sizing, then change size and pos now!! - if (x + cx > swpDesktop.cx) - x = swpDesktop.cx - cx; - if (x < 0) - x = 0; - if (y < 0) - y = 0; - if (y + cy > swpDesktop.cy) - y = swpDesktop.cy - cy; - return WinSetWindowPos(hwnd, hwndInsertBehind, x, y, cx, cy, fl); - } else if (fl & SWP_MOVE) { - // Just moving - WinQueryWindowPos(hwnd, &swp); - if (x + swp.cx > swpDesktop.cx) - x = swpDesktop.cx - swp.cx; - if (x < 0) - x = 0; - if (y < 0) - y = 0; - if (y + swp.cy > swpDesktop.cy) - y = swpDesktop.cy - swp.cy; - return WinSetWindowPos(hwnd, hwndInsertBehind, x, y, cx, cy, fl); - } else if (fl & SWP_SIZE) { - // Just sizing - WinQueryWindowPos(hwnd, &swp); - x = swp.x; - y = swp.y; - if (x + cx > swpDesktop.cx) - x = swpDesktop.cx - cx; - if (x < 0) - x = 0; - if (y < 0) - y = 0; - if (y + cy > swpDesktop.cy) - y = swpDesktop.cy - cy; - return WinSetWindowPos(hwnd, hwndInsertBehind, x, y, cx, cy, - fl | SWP_MOVE); - } else - return WinSetWindowPos(hwnd, hwndInsertBehind, x, y, cx, cy, fl); -} - -static UniChar -NativeCharToUniChar(int chcode) -{ - UniChar ucResult = (UniChar) chcode; - int rc; - UconvObject ucoTemp; - char achFrom[2]; - char *pchFrom; - size_t iFromCount; - UniChar aucTo[10]; - UniChar *pucTo; - size_t iToCount; - size_t iNonIdentical; - - // Create unicode convert object - rc = UniCreateUconvObject(L"", &ucoTemp); - if (rc != ULS_SUCCESS) { - // Could not create convert object! - return ucResult; - } - // Convert language code string to unicode string - achFrom[0] = (char) chcode; - achFrom[1] = 0; - iFromCount = sizeof(char) * 2; - iToCount = sizeof(UniChar) * 2; - pucTo = &(aucTo[0]); - pchFrom = &(achFrom[0]); - - rc = UniUconvToUcs(ucoTemp, - &pchFrom, - &iFromCount, &pucTo, &iToCount, &iNonIdentical); - - if (rc != ULS_SUCCESS) { - // Could not convert language code to UCS string! - UniFreeUconvObject(ucoTemp); - return ucResult; - } - - UniFreeUconvObject(ucoTemp); - -#ifdef DEBUG_BUILD - printf("%02x converted to %02x\n", (int) chcode, (int) (aucTo[0])); -#endif - - return aucTo[0]; -} - -///////////////////////////////////////////////////////////////////// -// -// TranslateKey -// -// This creates SDL Keycodes from VK_ and hardware scan codes -// -///////////////////////////////////////////////////////////////////// -static SDL_keysym * -TranslateKey(int vkey, int chcode, int scancode, SDL_keysym * keysym, - int iPressed) -{ - keysym->scancode = (unsigned char) scancode; - keysym->mod = KMOD_NONE; - keysym->unicode = 0; - - if (iPressed && SDL_TranslateUNICODE) { - if (chcode) - keysym->unicode = NativeCharToUniChar(chcode); - else - keysym->unicode = vkey; - } - - keysym->sym = HWScanKeyMap[scancode]; - - // Now stuffs based on state of shift key(s)! - if (vkey == VK_SHIFT) { - iShiftIsPressed = iPressed; - } - - if ((iShiftIsPressed) && (SDL_TranslateUNICODE)) { - // Change syms, if Unicode stuff is required - // I think it's silly, but it's SDL... - switch (keysym->sym) { - case SDLK_BACKQUOTE: - keysym->sym = '~'; - break; - case SDLK_1: - keysym->sym = SDLK_EXCLAIM; - break; - case SDLK_2: - keysym->sym = SDLK_AT; - break; - case SDLK_3: - keysym->sym = SDLK_HASH; - break; - case SDLK_4: - keysym->sym = SDLK_DOLLAR; - break; - case SDLK_5: - keysym->sym = '%'; - break; - case SDLK_6: - keysym->sym = SDLK_CARET; - break; - case SDLK_7: - keysym->sym = SDLK_AMPERSAND; - break; - case SDLK_8: - keysym->sym = SDLK_ASTERISK; - break; - case SDLK_9: - keysym->sym = SDLK_LEFTPAREN; - break; - case SDLK_0: - keysym->sym = SDLK_RIGHTPAREN; - break; - case SDLK_MINUS: - keysym->sym = SDLK_UNDERSCORE; - break; - case SDLK_PLUS: - keysym->sym = SDLK_EQUALS; - break; - - case SDLK_LEFTBRACKET: - keysym->sym = '{'; - break; - case SDLK_RIGHTBRACKET: - keysym->sym = '}'; - break; - - case SDLK_SEMICOLON: - keysym->sym = SDLK_COLON; - break; - case SDLK_QUOTE: - keysym->sym = SDLK_QUOTEDBL; - break; - case SDLK_BACKSLASH: - keysym->sym = '|'; - break; - - case SDLK_COMMA: - keysym->sym = SDLK_LESS; - break; - case SDLK_PERIOD: - keysym->sym = SDLK_GREATER; - break; - case SDLK_SLASH: - keysym->sym = SDLK_QUESTION; - break; - - default: - break; - } - } - return keysym; -} - -#define CONVERTMOUSEPOSITION() \ - /* We have to inverse the mouse position, because every non-os/2 system */ \ - /* has a coordinate system where the (0;0) is the top-left corner, */ \ - /* while on os/2 it's the bottom left corner! */ \ - if (FSLib_QueryFSMode(hwnd)) \ - { \ - /* We're in FS mode! */ \ - /* In FS mode our window is as big as fullscreen mode, but not necessary as */ \ - /* big as the source buffer (can be bigger) */ \ - /* So, limit mouse pos to source buffer size! */ \ - if (ppts->x<0) ppts->x = 0; \ - if (ppts->y<0) ppts->y = 0; \ - if (ppts->x>=pVideo->hidden->SrcBufferDesc.uiXResolution) ppts->x = pVideo->hidden->SrcBufferDesc.uiXResolution-1; \ - if (ppts->y>=pVideo->hidden->SrcBufferDesc.uiYResolution) ppts->y = pVideo->hidden->SrcBufferDesc.uiYResolution-1; \ - pVideo->hidden->iSkipWMMOUSEMOVE++; /* Don't take next WM_MOUSEMOVE into account! */ \ - ptl.x = ppts->x; ptl.y = ppts->y; \ - WinMapWindowPoints(pVideo->hidden->hwndClient, HWND_DESKTOP, &ptl, 1); \ - WinSetPointerPos(HWND_DESKTOP, ptl.x, ptl.y); \ - /* Then convert OS/2 position to SDL position */ \ - ppts->y = pVideo->hidden->SrcBufferDesc.uiYResolution - ppts->y - 1; \ - } else \ - { \ - SWP swpClient; \ - /* We're in windowed mode! */ \ - WinQueryWindowPos(pVideo->hidden->hwndClient, &swpClient); \ - /* Convert OS/2 mouse position to SDL position, and also scale it! */ \ - (ppts->x) = (ppts->x) * pVideo->hidden->SrcBufferDesc.uiXResolution / swpClient.cx; \ - (ppts->y) = (ppts->y) * pVideo->hidden->SrcBufferDesc.uiYResolution / swpClient.cy; \ - (ppts->y) = pVideo->hidden->SrcBufferDesc.uiYResolution - (ppts->y) - 1; \ - } - - - -///////////////////////////////////////////////////////////////////// -// -// WndProc -// -// This is the message processing window procedure for the -// SDLWindowClass, which is the client window in our application. -// It handles switching back and away from the app (taking care of -// going out and back to and from fullscreen mode), sending keystrokes -// and mouse events to where it has to be sent, etc... -// -///////////////////////////////////////////////////////////////////// -static MRESULT EXPENTRY -WndProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2) -{ - HPS ps; - RECTL rcl; - SDL_VideoDevice *pVideo = NULL; - - switch (msg) { - case WM_CHAR: // Keypress notification -#ifdef DEBUG_BUILD -// printf("WM_CHAR\n"); fflush(stdout); -#endif - pVideo = WinQueryWindowPtr(hwnd, 0); - if (pVideo) { - /* - // We skip repeated keys: - if (CHARMSG(&msg)->cRepeat>1) - { - #ifdef DEBUG_BUILD - // printf("Repeated key (%d), skipping...\n", CHARMSG(&msg)->cRepeat); fflush(stdout); - #endif - return (MRESULT) TRUE; - } - */ - - // If it's not repeated, then let's see if its pressed or released! - if (SHORT1FROMMP(mp1) & KC_KEYUP) { - // A key has been released - SDL_keysym keysym; - -#ifdef DEBUG_BUILD -// printf("WM_CHAR, keyup, code is [0x%0x]\n", CHAR4FROMMP(mp1)); // HW scan code -#endif - - // One problem is with F1, which gets only the keyup message because - // it is a system key. - // So, when we get keyup message, we simulate keydown too! - // UPDATE: - // This problem should be solved now, that the accelerator keys are - // disabled for this window! - /* - if (SHORT2FROMMP(mp2)==VK_F1) - { - SDL_PrivateKeyboard(SDL_PRESSED, TranslateKey(SHORT2FROMMP(mp2), // VK_ code - SHORT1FROMMP(mp2), // Character code - CHAR4FROMMP(mp1), // HW Scan code - &keysym,0)); - } */ - - SDL_PrivateKeyboard(SDL_RELEASED, TranslateKey(SHORT2FROMMP(mp2), // VK_ code - SHORT1FROMMP(mp2), // Character code - CHAR4FROMMP(mp1), // HW Scan code - &keysym, 0)); - - } else { - // A key has been pressed - SDL_keysym keysym; - -#ifdef DEBUG_BUILD -// printf("WM_CHAR, keydown, code is [0x%0x]\n", CHAR4FROMMP(mp1)); // HW scan code -#endif - // Check for fastkeys: ALT+HOME to toggle FS mode - // ALT+END to close app - if ((SHORT1FROMMP(mp1) & KC_ALT) && - (SHORT2FROMMP(mp2) == VK_HOME)) { -#ifdef DEBUG_BUILD - printf(" Pressed ALT+HOME!\n"); - fflush(stdout); -#endif - // Only switch between fullscreen and back if it's not - // a resizable mode! - if ((!pVideo->hidden->pSDLSurface) || - ((pVideo->hidden->pSDLSurface) - && - ((pVideo->hidden-> - pSDLSurface->flags & SDL_RESIZABLE) == 0))) - FSLib_ToggleFSMode(hwnd, !FSLib_QueryFSMode(hwnd)); -#ifdef DEBUG_BUILD - else - printf(" Resizable mode, so discarding ALT+HOME!\n"); - fflush(stdout); -#endif - } else if ((SHORT1FROMMP(mp1) & KC_ALT) && - (SHORT2FROMMP(mp2) == VK_END)) { -#ifdef DEBUG_BUILD - printf(" Pressed ALT+END!\n"); - fflush(stdout); -#endif - // Close window, and get out of loop! - // Also send event to SDL application, but we won't - // wait for it to be processed! - SDL_PrivateQuit(); - WinPostMsg(hwnd, WM_QUIT, 0, 0); - } else { - - SDL_PrivateKeyboard(SDL_PRESSED, TranslateKey(SHORT2FROMMP(mp2), // VK_ code - SHORT1FROMMP(mp2), // Character code - CHAR4FROMMP(mp1), // HW Scan code - &keysym, - 1)); - - } - } - } - return (MRESULT) TRUE; - - case WM_TRANSLATEACCEL: - { - PQMSG pqmsg; - pqmsg = (PQMSG) mp1; - if (mp1) { - if (pqmsg->msg == WM_CHAR) { - // WM_CHAR message! - // Let's filter the ALT keypress and all other acceleration keys! - return (MRESULT) FALSE; - } - } - break; // Default processing (pass to parent until frame control) - } - - case WM_PAINT: // Window redraw! -#ifdef DEBUG_BUILD - printf("WM_PAINT (0x%x)\n", hwnd); - fflush(stdout); -#endif - ps = WinBeginPaint(hwnd, 0, &rcl); - pVideo = FSLib_GetUserParm(hwnd); - if (pVideo) { - if (!pVideo->hidden->pSDLSurface) { - RECTL rclRect; - // So, don't blit now! -#ifdef DEBUG_BUILD - printf("WM_PAINT : Skipping blit while resizing (Pre!)!\n"); - fflush(stdout); -#endif - WinQueryWindowRect(hwnd, &rclRect); - // Fill with black - WinFillRect(ps, &rclRect, CLR_BLACK); - } else { - if (DosRequestMutexSem - (pVideo->hidden->hmtxUseSrcBuffer, 1000) == NO_ERROR) { - int iTop, iLeft, iWidth, iHeight; - int iXScaleError, iYScaleError; - int iXScaleError2, iYScaleError2; - SWP swp; - - // Re-blit the modified area! - // For this, we have to calculate the points, scaled! - WinQueryWindowPos(hwnd, &swp); -#ifdef DEBUG_BUILD - printf - ("WM_PAINT : WinSize: %d %d, BufSize: %d %d\n", - swp.cx, swp.cy, - pVideo->hidden->SrcBufferDesc.uiXResolution, - pVideo->hidden->SrcBufferDesc.uiYResolution); - fflush(stdout); -#endif - -#ifndef RESIZE_EVEN_IF_RESIZABLE - // But only blit if the window is not resizable, or if - // the window is resizable and the source buffer size is the - // same as the destination buffer size! - if ((!pVideo->hidden->pSDLSurface) || - ((pVideo->hidden->pSDLSurface) && - (pVideo->hidden->pSDLSurface->flags & SDL_RESIZABLE) - && - ((swp.cx != - pVideo->hidden->SrcBufferDesc.uiXResolution) - || (swp.cy != - pVideo->hidden->SrcBufferDesc.uiYResolution)) - && (!FSLib_QueryFSMode(hwnd)))) { - RECTL rclRect; - // Resizable surface and in resizing! - // So, don't blit now! -#ifdef DEBUG_BUILD - printf("WM_PAINT : Skipping blit while resizing!\n"); - fflush(stdout); -#endif - WinQueryWindowRect(hwnd, &rclRect); - // Fill with black - WinFillRect(ps, &rclRect, CLR_BLACK); - } else -#endif - { - - iXScaleError = - (pVideo->hidden->SrcBufferDesc.uiXResolution - - 1) / swp.cx; - iYScaleError = - (pVideo->hidden->SrcBufferDesc.uiYResolution - - 1) / swp.cy; - if (iXScaleError < 0) - iXScaleError = 0; - if (iYScaleError < 0) - iYScaleError = 0; - iXScaleError2 = - (swp.cx - - 1) / - (pVideo->hidden->SrcBufferDesc.uiXResolution); - iYScaleError2 = - (swp.cy - - 1) / - (pVideo->hidden->SrcBufferDesc.uiYResolution); - if (iXScaleError2 < 0) - iXScaleError2 = 0; - if (iYScaleError2 < 0) - iYScaleError2 = 0; - - iTop = - (swp.cy - - rcl.yTop) * - pVideo->hidden->SrcBufferDesc.uiYResolution / - swp.cy - iYScaleError; - iLeft = - rcl.xLeft * - pVideo->hidden->SrcBufferDesc.uiXResolution / - swp.cx - iXScaleError; - iWidth = - ((rcl.xRight - - rcl.xLeft) * - pVideo->hidden->SrcBufferDesc.uiXResolution + - swp.cx - 1) / swp.cx + 2 * iXScaleError; - iHeight = - ((rcl.yTop - - rcl.yBottom) * - pVideo->hidden->SrcBufferDesc.uiYResolution + - swp.cy - 1) / swp.cy + 2 * iYScaleError; - - iWidth += iXScaleError2; - iHeight += iYScaleError2; - - if (iTop < 0) - iTop = 0; - if (iLeft < 0) - iLeft = 0; - if (iTop + iHeight > - pVideo->hidden->SrcBufferDesc.uiYResolution) - iHeight = - pVideo->hidden->SrcBufferDesc.uiYResolution - - iTop; - if (iLeft + iWidth > - pVideo->hidden->SrcBufferDesc.uiXResolution) - iWidth = - pVideo->hidden->SrcBufferDesc.uiXResolution - - iLeft; - -#ifdef DEBUG_BUILD - printf - ("WM_PAINT : BitBlt: %d %d -> %d %d (Buf %d x %d)\n", - iTop, iLeft, iWidth, iHeight, - pVideo->hidden->SrcBufferDesc.uiXResolution, - pVideo->hidden->SrcBufferDesc.uiYResolution); - fflush(stdout); -#endif - - FSLIB_BITBLT(hwnd, - pVideo->hidden->pchSrcBuffer, - iTop, iLeft, iWidth, iHeight); - } - - DosReleaseMutexSem(pVideo->hidden->hmtxUseSrcBuffer); - } - } - } -#ifdef DEBUG_BUILD - else { - printf("WM_PAINT : No pVideo!\n"); - fflush(stdout); - } -#endif - WinEndPaint(ps); -#ifdef DEBUG_BUILD - printf("WM_PAINT : Done.\n"); - fflush(stdout); -#endif - return 0; - - case WM_SIZE: - { -#ifdef DEBUG_BUILD - printf("WM_SIZE : (%d %d)\n", - SHORT1FROMMP(mp2), SHORT2FROMMP(mp2)); - fflush(stdout); -#endif - iWindowSizeX = SHORT1FROMMP(mp2); - iWindowSizeY = SHORT2FROMMP(mp2); - bWindowResized = 1; - - // Make sure the window will be redrawn - WinInvalidateRegion(hwnd, NULL, TRUE); - } - break; - - case WM_FSLIBNOTIFICATION: -#ifdef DEBUG_BUILD - printf("WM_FSLIBNOTIFICATION\n"); - fflush(stdout); -#endif - if ((int) mp1 == FSLN_TOGGLEFSMODE) { - // FS mode changed, reblit image! - pVideo = FSLib_GetUserParm(hwnd); - if (pVideo) { - if (!pVideo->hidden->pSDLSurface) { - // Resizable surface and in resizing! - // So, don't blit now! -#ifdef DEBUG_BUILD - printf - ("WM_FSLIBNOTIFICATION : Can not blit if there is no surface, doing nothing.\n"); - fflush(stdout); -#endif - } else { - if (DosRequestMutexSem - (pVideo->hidden->hmtxUseSrcBuffer, - 1000) == NO_ERROR) { - if (pVideo->hidden->pSDLSurface) { -#ifndef RESIZE_EVEN_IF_RESIZABLE - SWP swp; - - // But only blit if the window is not resizable, or if - // the window is resizable and the source buffer size is the - // same as the destination buffer size! - WinQueryWindowPos(hwnd, &swp); - if ((!pVideo->hidden->pSDLSurface) || - ((pVideo->hidden->pSDLSurface) && - (pVideo->hidden-> - pSDLSurface->flags & SDL_RESIZABLE) - && - ((swp.cx != - pVideo->hidden-> - SrcBufferDesc.uiXResolution) - || (swp.cy != - pVideo->hidden->SrcBufferDesc. - uiYResolution)) - && (!FSLib_QueryFSMode(hwnd)))) { - // Resizable surface and in resizing! - // So, don't blit now! -#ifdef DEBUG_BUILD - printf - ("WM_FSLIBNOTIFICATION : Cannot blit while resizing, doing nothing.\n"); - fflush(stdout); -#endif - } else -#endif - { -#ifdef DEBUG_BUILD - printf("WM_FSLIBNOTIFICATION : Blitting!\n"); - fflush(stdout); -#endif - FSLIB_BITBLT(hwnd, - pVideo->hidden->pchSrcBuffer, 0, - 0, - pVideo->hidden-> - SrcBufferDesc.uiXResolution, - pVideo->hidden->SrcBufferDesc. - uiYResolution); - } - } -#ifdef DEBUG_BUILD - else - printf - ("WM_FSLIBNOTIFICATION : No public surface!\n"); - fflush(stdout); -#endif - - DosReleaseMutexSem(pVideo->hidden->hmtxUseSrcBuffer); - } - } - } - } - return (MPARAM) 1; - - case WM_ACTIVATE: -#ifdef DEBUG_BUILD - printf("WM_ACTIVATE\n"); - fflush(stdout); -#endif - - pVideo = FSLib_GetUserParm(hwnd); - if (pVideo) { - pVideo->hidden->fInFocus = (int) mp1; - if (pVideo->hidden->fInFocus) { - // Went into focus - if ((pVideo->hidden->iMouseVisible) - && (!bMouseCaptured)) - WinSetPointer(HWND_DESKTOP, - WinQuerySysPointer(HWND_DESKTOP, - SPTR_ARROW, FALSE)); - else - WinSetPointer(HWND_DESKTOP, NULL); - - if (bMouseCapturable) { - // Re-capture the mouse, if we captured it before! - WinSetCapture(HWND_DESKTOP, hwnd); - bMouseCaptured = 1; - { - SWP swpClient; - POINTL ptl; - // Center the mouse to the middle of the window! - WinQueryWindowPos(pVideo->hidden->hwndClient, - &swpClient); - ptl.x = 0; - ptl.y = 0; - WinMapWindowPoints(pVideo->hidden->hwndClient, - HWND_DESKTOP, &ptl, 1); - pVideo->hidden->iSkipWMMOUSEMOVE++; /* Don't take next WM_MOUSEMOVE into account! */ - WinSetPointerPos(HWND_DESKTOP, - ptl.x + swpClient.cx / 2, - ptl.y + swpClient.cy / 2); - } - } - } else { - // Went out of focus - WinSetPointer(HWND_DESKTOP, - WinQuerySysPointer(HWND_DESKTOP, - SPTR_ARROW, FALSE)); - - if (bMouseCaptured) { - // Release the mouse - WinSetCapture(HWND_DESKTOP, hwnd); - bMouseCaptured = 0; - } - } - } -#ifdef DEBUG_BUILD - printf("WM_ACTIVATE done\n"); - fflush(stdout); -#endif - - break; - - case WM_BUTTON1DOWN: -#ifdef DEBUG_BUILD - printf("WM_BUTTON1DOWN\n"); - fflush(stdout); -#endif - - pVideo = FSLib_GetUserParm(hwnd); - if (pVideo) { - SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_LEFT, 0, 0); // Don't report mouse movement! - - if (bMouseCapturable) { - // We should capture the mouse! - if (!bMouseCaptured) { - WinSetCapture(HWND_DESKTOP, hwnd); - WinSetPointer(HWND_DESKTOP, NULL); - bMouseCaptured = 1; - { - SWP swpClient; - POINTL ptl; - // Center the mouse to the middle of the window! - WinQueryWindowPos(pVideo->hidden->hwndClient, - &swpClient); - ptl.x = 0; - ptl.y = 0; - WinMapWindowPoints(pVideo->hidden->hwndClient, - HWND_DESKTOP, &ptl, 1); - pVideo->hidden->iSkipWMMOUSEMOVE++; /* Don't take next WM_MOUSEMOVE into account! */ - WinSetPointerPos(HWND_DESKTOP, - ptl.x + swpClient.cx / 2, - ptl.y + swpClient.cy / 2); - } - } - } - } - break; - case WM_BUTTON1UP: -#ifdef DEBUG_BUILD - printf("WM_BUTTON1UP\n"); - fflush(stdout); -#endif - SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_LEFT, 0, 0); // Don't report mouse movement! - break; - case WM_BUTTON2DOWN: -#ifdef DEBUG_BUILD - printf("WM_BUTTON2DOWN\n"); - fflush(stdout); -#endif - - pVideo = FSLib_GetUserParm(hwnd); - if (pVideo) { - SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_RIGHT, 0, 0); // Don't report mouse movement! - - if (bMouseCapturable) { - // We should capture the mouse! - if (!bMouseCaptured) { - WinSetCapture(HWND_DESKTOP, hwnd); - WinSetPointer(HWND_DESKTOP, NULL); - bMouseCaptured = 1; - { - SWP swpClient; - POINTL ptl; - // Center the mouse to the middle of the window! - WinQueryWindowPos(pVideo->hidden->hwndClient, - &swpClient); - ptl.x = 0; - ptl.y = 0; - WinMapWindowPoints(pVideo->hidden->hwndClient, - HWND_DESKTOP, &ptl, 1); - pVideo->hidden->iSkipWMMOUSEMOVE++; /* Don't take next WM_MOUSEMOVE into account! */ - WinSetPointerPos(HWND_DESKTOP, - ptl.x + swpClient.cx / 2, - ptl.y + swpClient.cy / 2); - } - } - } - - } - break; - case WM_BUTTON2UP: -#ifdef DEBUG_BUILD - printf("WM_BUTTON2UP\n"); - fflush(stdout); -#endif - SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_RIGHT, 0, 0); // Don't report mouse movement! - break; - case WM_BUTTON3DOWN: -#ifdef DEBUG_BUILD - printf("WM_BUTTON3DOWN\n"); - fflush(stdout); -#endif - - pVideo = FSLib_GetUserParm(hwnd); - if (pVideo) { - SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_MIDDLE, 0, 0); // Don't report mouse movement! - - if (bMouseCapturable) { - // We should capture the mouse! - if (!bMouseCaptured) { - WinSetCapture(HWND_DESKTOP, hwnd); - WinSetPointer(HWND_DESKTOP, NULL); - bMouseCaptured = 1; - { - SWP swpClient; - POINTL ptl; - // Center the mouse to the middle of the window! - WinQueryWindowPos(pVideo->hidden->hwndClient, - &swpClient); - ptl.x = 0; - ptl.y = 0; - WinMapWindowPoints(pVideo->hidden->hwndClient, - HWND_DESKTOP, &ptl, 1); - pVideo->hidden->iSkipWMMOUSEMOVE++; /* Don't take next WM_MOUSEMOVE into account! */ - WinSetPointerPos(HWND_DESKTOP, - ptl.x + swpClient.cx / 2, - ptl.y + swpClient.cy / 2); - } - } - } - } - break; - case WM_BUTTON3UP: -#ifdef DEBUG_BUILD - printf("WM_BUTTON3UP\n"); - fflush(stdout); -#endif - SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_MIDDLE, 0, 0); // Don't report mouse movement! - break; - case WM_MOUSEMOVE: -#ifdef DEBUG_BUILD -// printf("WM_MOUSEMOVE\n"); fflush(stdout); -#endif - - pVideo = FSLib_GetUserParm(hwnd); - if (pVideo) { - if (pVideo->hidden->iSkipWMMOUSEMOVE) { - pVideo->hidden->iSkipWMMOUSEMOVE--; - } else { - POINTS *ppts = (POINTS *) (&mp1); - POINTL ptl; - - if (bMouseCaptured) { - SWP swpClient; - - WinQueryWindowPos(pVideo->hidden->hwndClient, &swpClient); - - // Send relative mouse position, and re-center the mouse - // Reposition the mouse to the center of the screen/window - SDL_PrivateMouseMotion(0, // Buttons not changed - 1, // Relative position - ppts->x - - (swpClient.cx / 2), - (swpClient.cy / 2) - ppts->y); - - ptl.x = 0; - ptl.y = 0; - WinMapWindowPoints(pVideo->hidden->hwndClient, - HWND_DESKTOP, &ptl, 1); - pVideo->hidden->iSkipWMMOUSEMOVE++; /* Don't take next WM_MOUSEMOVE into account! */ - // Center the mouse to the middle of the window! - WinSetPointerPos(HWND_DESKTOP, - ptl.x + swpClient.cx / 2, - ptl.y + swpClient.cy / 2); - } else { - CONVERTMOUSEPOSITION(); - - // Send absolute mouse position - SDL_PrivateMouseMotion(0, // Buttons not changed - 0, // Absolute position - ppts->x, ppts->y); - } - } - if ((pVideo->hidden->iMouseVisible) && (!bMouseCaptured)) { -#ifdef DEBUG_BUILD -// printf("WM_MOUSEMOVE : ptr = %p\n", hptrGlobalPointer); fflush(stdout); -#endif - - if (hptrGlobalPointer) - WinSetPointer(HWND_DESKTOP, hptrGlobalPointer); - else - WinSetPointer(HWND_DESKTOP, - WinQuerySysPointer(HWND_DESKTOP, - SPTR_ARROW, FALSE)); - } else { - WinSetPointer(HWND_DESKTOP, NULL); - } - } -#ifdef DEBUG_BUILD -// printf("WM_MOUSEMOVE done\n"); fflush(stdout); -#endif - - return (MRESULT) FALSE; - case WM_CLOSE: // Window close -#ifdef DEBUG_BUILD - printf("WM_CLOSE\n"); - fflush(stdout); -#endif - - pVideo = FSLib_GetUserParm(hwnd); - if (pVideo) { - // Send Quit message to the SDL application! - SDL_PrivateQuit(); - return 0; - } - break; - -#ifdef BITBLT_IN_WINMESSAGEPROC - case WM_UPDATERECTSREQUEST: - pVideo = FSLib_GetUserParm(hwnd); - if ((pVideo) && (pVideo->hidden->pSDLSurface)) { - if (DosRequestMutexSem - (pVideo->hidden->hmtxUseSrcBuffer, - SEM_INDEFINITE_WAIT) == NO_ERROR) { - int numrects; - SDL_Rect *rects; - int i; - SWP swp; - - numrects = (int) mp1; - rects = (SDL_Rect *) mp2; - - WinQueryWindowPos(hwnd, &swp); -#ifndef RESIZE_EVEN_IF_RESIZABLE - if ((!pVideo->hidden->pSDLSurface) || - ((pVideo->hidden->pSDLSurface) && - (pVideo->hidden->pSDLSurface->flags & SDL_RESIZABLE) - && - ((swp.cx != pVideo->hidden->SrcBufferDesc.uiXResolution) - || (swp.cy != - pVideo->hidden->SrcBufferDesc.uiYResolution)) - && (!FSLib_QueryFSMode(hwnd)))) { - // Resizable surface and in resizing! - // So, don't blit now! -#ifdef DEBUG_BUILD - printf - ("[WM_UPDATERECTSREQUEST] : Skipping blit while resizing!\n"); - fflush(stdout); -#endif - } else -#endif - { -#ifdef DEBUG_BUILD - printf("[WM_UPDATERECTSREQUEST] : Blitting!\n"); - fflush(stdout); -#endif - - // Blit the changed areas - for (i = 0; i < numrects; i++) - FSLIB_BITBLT(hwnd, - pVideo->hidden->pchSrcBuffer, - rects[i].y, rects[i].x, - rects[i].w, rects[i].h); - } - DosReleaseMutexSem(pVideo->hidden->hmtxUseSrcBuffer); - } - } - return 0; -#endif - - default: -#ifdef DEBUG_BUILD - printf("Unhandled: %x\n", msg); - fflush(stdout); -#endif - - break; - } - // Run the default window procedure for unhandled stuffs - return WinDefWindowProc(hwnd, msg, mp1, mp2); -} - -///////////////////////////////////////////////////////////////////// -// -// FrameWndProc -// -// This is the message processing window procedure for the -// frame window of SDLWindowClass. -// -///////////////////////////////////////////////////////////////////// -static MRESULT EXPENTRY -FrameWndProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2) -{ - PFNWP pOldFrameProc; - MRESULT result; - PTRACKINFO ti; - int cx, cy, ncx, ncy; - RECTL rclTemp; - PSWP pswpTemp; - - SDL_VideoDevice *pVideo = NULL; - - pVideo = (SDL_VideoDevice *) WinQueryWindowULong(hwnd, QWL_USER); - - pOldFrameProc = pVideo->hidden->pfnOldFrameProc; - - if ((pVideo->hidden->bProportionalResize) && - (msg == WM_ADJUSTWINDOWPOS) && - (!FSLib_QueryFSMode(pVideo->hidden->hwndClient))) { - pswpTemp = (PSWP) mp1; - - /* Resizing? */ - if (pswpTemp->fl & SWP_SIZE) { - /* Calculate client size */ - rclTemp.xLeft = pswpTemp->x; - rclTemp.xRight = pswpTemp->x + pswpTemp->cx; - rclTemp.yBottom = pswpTemp->y; - rclTemp.yTop = pswpTemp->y + pswpTemp->cy; - WinCalcFrameRect(hwnd, &rclTemp, TRUE); - - ncx = cx = rclTemp.xRight - rclTemp.xLeft; - ncy = cy = rclTemp.yTop - rclTemp.yBottom; - - /* Calculate new size to keep it proportional */ - - if ((pVideo->hidden->ulResizingFlag & TF_LEFT) - || (pVideo->hidden->ulResizingFlag & TF_RIGHT)) { - /* The window is resized horizontally */ - ncy = - pVideo->hidden->SrcBufferDesc.uiYResolution * cx / - pVideo->hidden->SrcBufferDesc.uiXResolution; - } else if ((pVideo->hidden->ulResizingFlag & TF_TOP) - || (pVideo->hidden->ulResizingFlag & TF_BOTTOM)) { - /* The window is resized vertically */ - ncx = - pVideo->hidden->SrcBufferDesc.uiXResolution * cy / - pVideo->hidden->SrcBufferDesc.uiYResolution; - } - - /* Calculate back frame coordinates */ - rclTemp.xLeft = pswpTemp->x; - rclTemp.xRight = pswpTemp->x + ncx; - rclTemp.yBottom = pswpTemp->y; - rclTemp.yTop = pswpTemp->y + ncy; - WinCalcFrameRect(hwnd, &rclTemp, FALSE); - - /* Store new size/position info */ - pswpTemp->cx = rclTemp.xRight - rclTemp.xLeft; - - if (!(pVideo->hidden->ulResizingFlag & TF_TOP)) { - pswpTemp->y = - pswpTemp->y + pswpTemp->cy - (rclTemp.yTop - - rclTemp.yBottom); - pswpTemp->cy = rclTemp.yTop - rclTemp.yBottom; - } else { - pswpTemp->cy = rclTemp.yTop - rclTemp.yBottom; - } - } - } - - result = (*pOldFrameProc) (hwnd, msg, mp1, mp2); - - if ((pVideo->hidden->bProportionalResize) && (msg == WM_QUERYTRACKINFO)) { - ti = (PTRACKINFO) mp2; - - /* Store the direction of resizing */ - if ((ti->fs & TF_LEFT) || (ti->fs & TF_RIGHT) || - (ti->fs & TF_TOP) || (ti->fs & TF_BOTTOM)) - pVideo->hidden->ulResizingFlag = ti->fs; - } - - return result; -} - -///////////////////////////////////////////////////////////////////// -// -// PMThreadFunc -// -// This function implements the PM-Thread, which initializes the -// application window itself, the DIVE, and start message processing. -// -///////////////////////////////////////////////////////////////////// -int iNumOfPMThreadInstances = 0; // Global! -static void -PMThreadFunc(void *pParm) -{ - SDL_VideoDevice *pVideo = pParm; - HAB hab; - HMQ hmq; - QMSG msg; - ULONG fcf; - -#ifdef DEBUG_BUILD - printf("[PMThreadFunc] : Starting\n"); - fflush(stdout); -#endif - - iNumOfPMThreadInstances++; - - // Initialize PM, create a message queue. - - hab = WinInitialize(0); - hmq = WinCreateMsgQueue(hab, 0); - if (hmq == 0) { -#ifdef DEBUG_BUILD - printf("[PMThreadFunc] : Could not create message queue!\n"); - printf - (" It might be that the application using SDL is not a PM app!\n"); - fflush(stdout); -#endif - pVideo->hidden->iPMThreadStatus = 2; - } else { - int rc; - RECTL rectl; - - fcf = ulFCFToUse; // Get from global setting - -#ifdef DEBUG_BUILD - printf("[PMThreadFunc] : FSLib_CreateWindow()!\n"); - fflush(stdout); -#endif - - rc = FSLib_CreateWindow(HWND_DESKTOP, 0, &fcf, - "SDL Application", - NULLHANDLE, 0, - &(pVideo->hidden->SrcBufferDesc), - WndProc, - &(pVideo->hidden->hwndClient), - &(pVideo->hidden->hwndFrame)); - -#ifdef DEBUG_BUILD - printf("[PMThreadFunc] : FSLib_CreateWindow() rc = %d\n", rc); - fflush(stdout); -#endif - - if (!rc) { -#ifdef DEBUG_BUILD - printf("[PMThreadFunc] : Could not create FSLib window!\n"); - fflush(stdout); -#endif - pVideo->hidden->iPMThreadStatus = 3; - } else { -#ifdef DEBUG_BUILD - printf("[PMThreadFunc] : FSLib_AddUserParm()!\n"); - fflush(stdout); -#endif - - // Store pVideo pointer in window data for client window, so - // it will know the instance to which it belongs to. - FSLib_AddUserParm(pVideo->hidden->hwndClient, pVideo); - - // Now set default image width height and fourcc! -#ifdef DEBUG_BUILD - printf("[PMThreadFunc] : SetWindowPos()!\n"); - fflush(stdout); -#endif - - // Set the position and size of the main window, - // and make it visible! - // Calculate frame window size from client window size - rectl.xLeft = 0; - rectl.yBottom = 0; - rectl.xRight = pVideo->hidden->SrcBufferDesc.uiXResolution; // Noninclusive - rectl.yTop = pVideo->hidden->SrcBufferDesc.uiYResolution; // Noninclusive - WinCalcFrameRect(pVideo->hidden->hwndFrame, &rectl, FALSE); - - SetAccessableWindowPos(pVideo->hidden->hwndFrame, - HWND_TOP, - (WinQuerySysValue - (HWND_DESKTOP, - SV_CXSCREEN) - (rectl.xRight - - rectl.xLeft)) / 2, - (WinQuerySysValue - (HWND_DESKTOP, - SV_CYSCREEN) - (rectl.yTop - - rectl.yBottom)) / 2, - (rectl.xRight - rectl.xLeft), - (rectl.yTop - rectl.yBottom), - SWP_SIZE | SWP_ACTIVATE | SWP_SHOW | - SWP_MOVE); - - // Subclass frame procedure and store old window proc address - pVideo->hidden->pfnOldFrameProc = - WinSubclassWindow(pVideo->hidden->hwndFrame, FrameWndProc); - WinSetWindowULong(pVideo->hidden->hwndFrame, QWL_USER, - (ULONG) pVideo); - -#ifdef DEBUG_BUILD - printf("[PMThreadFunc] : Entering message loop\n"); - fflush(stdout); -#endif - pVideo->hidden->iPMThreadStatus = 1; - - while (WinGetMsg(hab, (PQMSG) & msg, 0, 0, 0)) - WinDispatchMsg(hab, (PQMSG) & msg); - -#ifdef DEBUG_BUILD - printf("[PMThreadFunc] : Leaving message loop\n"); - fflush(stdout); -#endif - // We should release the captured the mouse! - if (bMouseCaptured) { - WinSetCapture(HWND_DESKTOP, NULLHANDLE); - bMouseCaptured = 0; - } - // Destroy our window - WinDestroyWindow(pVideo->hidden->hwndFrame); - pVideo->hidden->hwndFrame = NULL; - // Show pointer to make sure it will not be left hidden. - WinSetPointer(HWND_DESKTOP, - WinQuerySysPointer(HWND_DESKTOP, SPTR_ARROW, - FALSE)); - WinShowPointer(HWND_DESKTOP, TRUE); - } - // Uninitialize PM - WinDestroyMsgQueue(hmq); - // All done! - pVideo->hidden->iPMThreadStatus = 0; - } - WinTerminate(hab); - /* Commented out, should not be needed anymore, because we send it - from WM_CLOSE. - // Notify SDL that it should really die now... - SDL_PrivateQuit(); SDL_PrivateQuit(); SDL_PrivateQuit(); //... :)) - */ -#ifdef DEBUG_BUILD - printf("[PMThreadFunc] : End, status is %d!\n", - pVideo->hidden->iPMThreadStatus); - fflush(stdout); -#endif - - iNumOfPMThreadInstances--; - - // HACK to prevent zombie and hanging SDL applications, which does not take - // care of closing the window for some reason: - // There are some apps which do not process messages, so do a lot of things - // without noticing that the application should close. To close these, - // I've thought about the following: - // If the window is closed (the execution came here), I wait a bit to - // give time to the app to finish its execution. If it does not, I kill it - // using DosExit(). Brute force, but should work. - if (pVideo->hidden->iPMThreadStatus == 0) { - DosSleep(5000); // Wait 5 secs - // If a new PM thread has been spawned (reinitializing video mode), then all right. - // Otherwise, we have a problem, the app doesn't want to stop. Kill! - if (iNumOfPMThreadInstances == 0) { -#ifdef DEBUG_BUILD - printf - ("[PMThreadFunc] : It seems that the application haven't terminated itself\n"); - fflush(stdout); - printf - ("[PMThreadFunc] : in the last 5 seconds, so we go berserk.\n"); - fflush(stdout); - printf - ("[PMThreadFunc] : Brute force mode. :) Killing process! Dieeeee...\n"); - fflush(stdout); -#endif - DosExit(EXIT_PROCESS, -1); - } - } - _endthread(); -} - -struct WMcursor -{ - HBITMAP hbm; - HPOINTER hptr; - char *pchData; -}; - -/* Free a window manager cursor */ -void -os2fslib_FreeWMCursor(_THIS, WMcursor * cursor) -{ - if (cursor) { - GpiDeleteBitmap(cursor->hbm); - WinDestroyPointer(cursor->hptr); - SDL_free(cursor->pchData); - SDL_free(cursor); - } -} - -/* Local functions to convert the SDL cursor mask into OS/2 format */ -static void -memnot(Uint8 * dst, Uint8 * src, int len) -{ - while (len-- > 0) - *dst++ = ~*src++; -} - -static void -memxor(Uint8 * dst, Uint8 * src1, Uint8 * src2, int len) -{ - while (len-- > 0) - *dst++ = (*src1++) ^ (*src2++); -} - -/* Create a black/white window manager cursor */ -WMcursor * -os2fslib_CreateWMCursor_Win(_THIS, Uint8 * data, Uint8 * mask, - int w, int h, int hot_x, int hot_y) -{ - HPOINTER hptr; - HBITMAP hbm; - BITMAPINFOHEADER bmih; - BMPINFO bmi; - HPS hps; - char *pchTemp; - char *xptr, *aptr; - int maxx, maxy; - int i, run, pad; - WMcursor *pResult; - - maxx = WinQuerySysValue(HWND_DESKTOP, SV_CXPOINTER); - maxy = WinQuerySysValue(HWND_DESKTOP, SV_CYPOINTER); - - // Check for max size! - if ((w > maxx) || (h > maxy)) - return (WMcursor *) NULL; - - pResult = (WMcursor *) SDL_malloc(sizeof(WMcursor)); - if (!pResult) - return (WMcursor *) NULL; - - pchTemp = (char *) SDL_malloc((maxx + 7) / 8 * maxy * 2); - if (!pchTemp) { - SDL_free(pResult); - return (WMcursor *) NULL; - } - - SDL_memset(pchTemp, 0, (maxx + 7) / 8 * maxy * 2); - - hps = WinGetPS(_this->hidden->hwndClient); - - bmi.cbFix = sizeof(BITMAPINFOHEADER); - bmi.cx = maxx; - bmi.cy = 2 * maxy; - bmi.cPlanes = 1; - bmi.cBitCount = 1; - bmi.argbColor[0].bBlue = 0x00; - bmi.argbColor[0].bGreen = 0x00; - bmi.argbColor[0].bRed = 0x00; - bmi.argbColor[1].bBlue = 0x00; - bmi.argbColor[1].bGreen = 0x00; - bmi.argbColor[1].bRed = 0xff; - - SDL_memset(&bmih, 0, sizeof(BITMAPINFOHEADER)); - bmih.cbFix = sizeof(BITMAPINFOHEADER); - bmih.cx = maxx; - bmih.cy = 2 * maxy; - bmih.cPlanes = 1; - bmih.cBitCount = 1; - - run = (w + 7) / 8; - pad = (maxx + 7) / 8 - run; - - for (i = 0; i < h; i++) { - xptr = pchTemp + (maxx + 7) / 8 * (maxy - 1 - i); - aptr = pchTemp + (maxx + 7) / 8 * (maxy + maxy - 1 - i); - memxor(xptr, data, mask, run); - xptr += run; - data += run; - memnot(aptr, mask, run); - mask += run; - aptr += run; - SDL_memset(xptr, 0, pad); - xptr += pad; - SDL_memset(aptr, ~0, pad); - aptr += pad; - } - pad += run; - for (i = h; i < maxy; i++) { - xptr = pchTemp + (maxx + 7) / 8 * (maxy - 1 - i); - aptr = pchTemp + (maxx + 7) / 8 * (maxy + maxy - 1 - i); - - SDL_memset(xptr, 0, (maxx + 7) / 8); - xptr += (maxx + 7) / 8; - SDL_memset(aptr, ~0, (maxx + 7) / 8); - aptr += (maxx + 7) / 8; - } - - hbm = - GpiCreateBitmap(hps, (PBITMAPINFOHEADER2) & bmih, CBM_INIT, - (PBYTE) pchTemp, (PBITMAPINFO2) & bmi); - hptr = WinCreatePointer(HWND_DESKTOP, hbm, TRUE, hot_x, maxy - hot_y - 1); - -#ifdef DEBUG_BUILD - printf("HotSpot : %d ; %d\n", hot_x, hot_y); - printf("HPS returned : %x\n", (ULONG) hps); - printf("HBITMAP returned : %x\n", (ULONG) hbm); - printf("HPOINTER returned: %x\n", (ULONG) hptr); -#endif - - WinReleasePS(hps); - -#ifdef DEBUG_BUILD - printf("[CreateWMCursor] : ptr = %p\n", hptr); - fflush(stdout); -#endif - - pResult->hptr = hptr; - pResult->hbm = hbm; - pResult->pchData = pchTemp; - -#ifdef DEBUG_BUILD - printf("[CreateWMCursor] : ptr = %p return.\n", hptr); - fflush(stdout); -#endif - - return (WMcursor *) pResult; -} - -WMcursor * -os2fslib_CreateWMCursor_FS(_THIS, Uint8 * data, Uint8 * mask, - int w, int h, int hot_x, int hot_y) -{ -#ifdef DEBUG_BUILD - printf("[CreateWMCursor_FS] : returning pointer NULL\n"); - fflush(stdout); -#endif - - // In FS mode we'll use software cursor - return (WMcursor *) NULL; -} - -/* Show the specified cursor, or hide if cursor is NULL */ -int -os2fslib_ShowWMCursor(_THIS, WMcursor * cursor) -{ -#ifdef DEBUG_BUILD - printf("[ShowWMCursor] : ptr = %p\n", cursor); - fflush(stdout); -#endif - - if (cursor) { - WinSetPointer(HWND_DESKTOP, cursor->hptr); - hptrGlobalPointer = cursor->hptr; - _this->hidden->iMouseVisible = 1; - } else { - WinSetPointer(HWND_DESKTOP, FALSE); - hptrGlobalPointer = NULL; - _this->hidden->iMouseVisible = 0; - } - -#ifdef DEBUG_BUILD - printf("[ShowWMCursor] : ptr = %p, DONE\n", cursor); - fflush(stdout); -#endif - - return 1; -} - -/* Warp the window manager cursor to (x,y) - If NULL, a mouse motion event is posted internally. - */ -void -os2fslib_WarpWMCursor(_THIS, Uint16 x, Uint16 y) -{ - LONG lx, ly; - SWP swpClient; - POINTL ptlPoints; - WinQueryWindowPos(_this->hidden->hwndClient, &swpClient); - ptlPoints.x = swpClient.x; - ptlPoints.y = swpClient.y; - WinMapWindowPoints(_this->hidden->hwndFrame, HWND_DESKTOP, &ptlPoints, 1); - lx = ptlPoints.x + - (x * swpClient.cx) / _this->hidden->SrcBufferDesc.uiXResolution; - ly = ptlPoints.y + swpClient.cy - - ((y * swpClient.cy) / _this->hidden->SrcBufferDesc.uiYResolution) - 1; - - SDL_PrivateMouseMotion(0, // Buttons not changed - 0, // Absolute position - x, y); - - WinSetPointerPos(HWND_DESKTOP, lx, ly); - -} - -/* If not NULL, this is called when a mouse motion event occurs */ -void -os2fslib_MoveWMCursor(_THIS, int x, int y) -{ - /* - SDL_Rect rect; - - #ifdef DEBUG_BUILD - printf("[MoveWMCursor] : at %d ; %d\n", x, y); fflush(stdout); - #endif - - rect.x = x; - rect.y = y; - rect.w = 32; - rect.h = 32; - os2fslib_UpdateRects(_this, 1, &rect); - // TODO! - */ -} - -/* Determine whether the mouse should be in relative mode or not. - This function is called when the input grab state or cursor - visibility state changes. - If the cursor is not visible, and the input is grabbed, the - driver can place the mouse in relative mode, which may result - in higher accuracy sampling of the pointer motion. - */ -void -os2fslib_CheckMouseMode(_THIS) -{ -} - -static void -os2fslib_PumpEvents(_THIS) -{ - // Notify SDL that if window has been resized! - if ((_this->hidden->pSDLSurface) && - (_this->hidden->pSDLSurface->flags & SDL_RESIZABLE) && - ((_this->hidden->SrcBufferDesc.uiXResolution != iWindowSizeX) || - (_this->hidden->SrcBufferDesc.uiYResolution != iWindowSizeY)) && - (iWindowSizeX > 0) && (iWindowSizeY > 0)) { - static time_t prev_time; - time_t curr_time; - - curr_time = time(NULL); - if ((difftime(curr_time, prev_time) >= 0.25) || (bWindowResized)) { - // Make sure we won't flood the event queue with resize events, - // only send them at 250 msecs! - // (or when the window is resized) -#ifdef DEBUG_BUILD - printf - ("[os2fslib_PumpEvents] : Calling PrivateResize (%d %d).\n", - iWindowSizeX, iWindowSizeY); - fflush(stdout); -#endif - // Tell SDL the new size - SDL_PrivateResize(iWindowSizeX, iWindowSizeY); - prev_time = curr_time; - bWindowResized = 0; - } - } -} - -/* We don't actually allow hardware surfaces other than the main one */ -static int -os2fslib_AllocHWSurface(_THIS, SDL_Surface * surface) -{ - return (-1); -} - -static void -os2fslib_FreeHWSurface(_THIS, SDL_Surface * surface) -{ - return; -} - -/* We need to wait for vertical retrace on page flipped displays */ -static int -os2fslib_LockHWSurface(_THIS, SDL_Surface * surface) -{ - return (0); -} - -static void -os2fslib_UnlockHWSurface(_THIS, SDL_Surface * surface) -{ - return; -} - -static int -os2fslib_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color * colors) -{ - printf("[os2fslib_SetColors] : TODO!\n"); - fflush(stdout); - // TODO: Implement paletted modes - return (1); -} - -static void -os2fslib_DestroyIcon(HWND hwndFrame) -{ - if (hptrCurrentIcon) { - WinDestroyPointer(hptrCurrentIcon); - hptrCurrentIcon = NULL; - - WinSendMsg(hwndFrame, WM_SETICON, NULL, NULL); - } - -} - -/* Set the window icon image */ -void -os2fslib_SetIcon(_THIS, SDL_Surface * icon, Uint8 * mask) -{ - HWND hwndFrame; - SDL_Surface *icon_rgb; - HPOINTER hptrIcon; - HBITMAP hbm; - BITMAPINFOHEADER bmih; - BMPINFO bmi; - HPS hps; - char *pchTemp; - char *pptr, *mptr, *dptr, *dmptr; - int maxx, maxy, w, h, x, y; - SDL_Rect bounds; - -#ifdef DEBUG_BUILD - printf("[os2fslib_SetIcon] : Creating and setting new icon\n"); - fflush(stdout); -#endif - - hwndFrame = WinQueryWindow(_this->hidden->hwndClient, QW_PARENT); - - // Make sure the old icon resource will be free'd! - os2fslib_DestroyIcon(hwndFrame); - - if ((!icon) || (!mask)) - return; - - w = icon->w; - h = icon->h; - - maxx = WinQuerySysValue(HWND_DESKTOP, SV_CXICON); - maxy = WinQuerySysValue(HWND_DESKTOP, SV_CYICON); - - // Check for max size! - if ((w > maxx) || (h > maxy)) - return; - - pchTemp = (char *) SDL_malloc(w * h * 2 * 4); - if (!pchTemp) - return; - - SDL_memset(pchTemp, 0, w * h * 2 * 4); - - // Convert surface to RGB, if it's not RGB yet! - icon_rgb = SDL_CreateRGBSurface(SDL_SWSURFACE, icon->w, icon->h, - 32, 0, 0, 0, 0); - if (icon_rgb == NULL) { - SDL_free(pchTemp); - return; - } - bounds.x = 0; - bounds.y = 0; - bounds.w = icon->w; - bounds.h = icon->h; - if (SDL_LowerBlit(icon, &bounds, icon_rgb, &bounds) < 0) { - SDL_FreeSurface(icon_rgb); - SDL_free(pchTemp); - return; - } - - /* Copy pixels upside-down from RGB surface into BMP, masked with the icon mask */ - - // Pixels - pptr = (char *) (icon_rgb->pixels); - // Mask - mptr = mask; - - for (y = 0; y < h; y++) { - unsigned char uchMaskByte; - - // Destination - dptr = pchTemp + w * 4 * (h - y - 1); - // Destination mask - dmptr = pchTemp + w * h * 4 + w * 4 * (h - y - 1); - - for (x = 0; x < w; x++) { - if (x % 8 == 0) { - uchMaskByte = (unsigned char) (*mptr); - mptr++; - } else - uchMaskByte <<= 1; - - if (uchMaskByte & 0x80) { - // Copy RGB - *dptr++ = *pptr++; - *dptr++ = *pptr++; - *dptr++ = *pptr++; - *dptr++ = *pptr++; - - *dmptr++ = 0; - *dmptr++ = 0; - *dmptr++ = 0; - *dmptr++ = 0; - } else { - // Set pixels to fully transparent - *dptr++ = 0; - pptr++; - *dptr++ = 0; - pptr++; - *dptr++ = 0; - pptr++; - *dptr++ = 0; - pptr++; - - *dmptr++ = 255; - *dmptr++ = 255; - *dmptr++ = 255; - *dmptr++ = 255; - } - } - } - - // There is no more need for the RGB surface - SDL_FreeSurface(icon_rgb); - - hps = WinGetPS(_this->hidden->hwndClient); - - bmi.cbFix = sizeof(BITMAPINFOHEADER); - bmi.cx = w; - bmi.cy = 2 * h; - bmi.cPlanes = 1; - bmi.cBitCount = 32; - - SDL_memset(&bmih, 0, sizeof(BITMAPINFOHEADER)); - bmih.cbFix = sizeof(BITMAPINFOHEADER); - bmih.cx = w; - bmih.cy = 2 * h; - bmih.cPlanes = 1; - bmih.cBitCount = 32; - - hbm = - GpiCreateBitmap(hps, (PBITMAPINFOHEADER2) & bmih, CBM_INIT, - (PBYTE) pchTemp, (PBITMAPINFO2) & bmi); - hptrIcon = WinCreatePointer(HWND_DESKTOP, hbm, FALSE, 0, 0); - - WinReleasePS(hps); - - // Free pixel array - SDL_free(pchTemp); - - // Change icon in frame window - WinSendMsg(hwndFrame, WM_SETICON, (MPARAM) hptrIcon, NULL); - - /* - // Change icon in switchlist - // Seems like it's not needed, the WM_SETICON already does it. - { - PID pidFrame; - HSWITCH hswitchFrame; - SWCNTRL swctl; - - WinQueryWindowProcess(hwndFrame, &pidFrame, NULL); - hswitchFrame = WinQuerySwitchHandle(hwndFrame, pidFrame); - WinQuerySwitchEntry(hswitchFrame, &swctl); - - swctl.hwndIcon = hptrIcon; - - WinChangeSwitchEntry(hswitchFrame, &swctl); - } - */ - - // Store icon handle in global variable - hptrCurrentIcon = hptrIcon; -} - -// ------------------------ REAL FUNCTIONS ----------------- - - -static void -os2fslib_SetCursorManagementFunctions(_THIS, int iForWindowedMode) -{ - if (iForWindowedMode) { - _this->FreeWMCursor = os2fslib_FreeWMCursor; - _this->CreateWMCursor = os2fslib_CreateWMCursor_Win; - _this->ShowWMCursor = os2fslib_ShowWMCursor; - _this->WarpWMCursor = os2fslib_WarpWMCursor; - _this->MoveWMCursor = os2fslib_MoveWMCursor; - _this->CheckMouseMode = NULL; //os2fslib_CheckMouseMode; - } else { - // We'll have software mouse cursor in FS mode! - _this->FreeWMCursor = os2fslib_FreeWMCursor; - _this->CreateWMCursor = os2fslib_CreateWMCursor_FS; - _this->ShowWMCursor = os2fslib_ShowWMCursor; - _this->WarpWMCursor = os2fslib_WarpWMCursor; - _this->MoveWMCursor = os2fslib_MoveWMCursor; - _this->CheckMouseMode = NULL; //os2fslib_CheckMouseMode; - } -} - -static void -os2fslib_InitOSKeymap(_THIS) -{ - int i; - - iShiftIsPressed = 0; - - /* Map the VK and CH keysyms */ - for (i = 0; i <= 255; ++i) - HWScanKeyMap[i] = SDLK_UNKNOWN; - - // First line of keyboard: - HWScanKeyMap[0x1] = SDLK_ESCAPE; - HWScanKeyMap[0x3b] = SDLK_F1; - HWScanKeyMap[0x3c] = SDLK_F2; - HWScanKeyMap[0x3d] = SDLK_F3; - HWScanKeyMap[0x3e] = SDLK_F4; - HWScanKeyMap[0x3f] = SDLK_F5; - HWScanKeyMap[0x40] = SDLK_F6; - HWScanKeyMap[0x41] = SDLK_F7; - HWScanKeyMap[0x42] = SDLK_F8; - HWScanKeyMap[0x43] = SDLK_F9; - HWScanKeyMap[0x44] = SDLK_F10; - HWScanKeyMap[0x57] = SDLK_F11; - HWScanKeyMap[0x58] = SDLK_F12; - HWScanKeyMap[0x5d] = SDLK_PRINT; - HWScanKeyMap[0x46] = SDLK_SCROLLOCK; - HWScanKeyMap[0x5f] = SDLK_PAUSE; - - // Second line of keyboard: - HWScanKeyMap[0x29] = SDLK_BACKQUOTE; - HWScanKeyMap[0x2] = SDLK_1; - HWScanKeyMap[0x3] = SDLK_2; - HWScanKeyMap[0x4] = SDLK_3; - HWScanKeyMap[0x5] = SDLK_4; - HWScanKeyMap[0x6] = SDLK_5; - HWScanKeyMap[0x7] = SDLK_6; - HWScanKeyMap[0x8] = SDLK_7; - HWScanKeyMap[0x9] = SDLK_8; - HWScanKeyMap[0xa] = SDLK_9; - HWScanKeyMap[0xb] = SDLK_0; - HWScanKeyMap[0xc] = SDLK_MINUS; - HWScanKeyMap[0xd] = SDLK_EQUALS; - HWScanKeyMap[0xe] = SDLK_BACKSPACE; - HWScanKeyMap[0x68] = SDLK_INSERT; - HWScanKeyMap[0x60] = SDLK_HOME; - HWScanKeyMap[0x62] = SDLK_PAGEUP; - HWScanKeyMap[0x45] = SDLK_NUMLOCK; - HWScanKeyMap[0x5c] = SDLK_KP_DIVIDE; - HWScanKeyMap[0x37] = SDLK_KP_MULTIPLY; - HWScanKeyMap[0x4a] = SDLK_KP_MINUS; - - // Third line of keyboard: - HWScanKeyMap[0xf] = SDLK_TAB; - HWScanKeyMap[0x10] = SDLK_q; - HWScanKeyMap[0x11] = SDLK_w; - HWScanKeyMap[0x12] = SDLK_e; - HWScanKeyMap[0x13] = SDLK_r; - HWScanKeyMap[0x14] = SDLK_t; - HWScanKeyMap[0x15] = SDLK_y; - HWScanKeyMap[0x16] = SDLK_u; - HWScanKeyMap[0x17] = SDLK_i; - HWScanKeyMap[0x18] = SDLK_o; - HWScanKeyMap[0x19] = SDLK_p; - HWScanKeyMap[0x1a] = SDLK_LEFTBRACKET; - HWScanKeyMap[0x1b] = SDLK_RIGHTBRACKET; - HWScanKeyMap[0x1c] = SDLK_RETURN; - HWScanKeyMap[0x69] = SDLK_DELETE; - HWScanKeyMap[0x65] = SDLK_END; - HWScanKeyMap[0x67] = SDLK_PAGEDOWN; - HWScanKeyMap[0x47] = SDLK_KP7; - HWScanKeyMap[0x48] = SDLK_KP8; - HWScanKeyMap[0x49] = SDLK_KP9; - HWScanKeyMap[0x4e] = SDLK_KP_PLUS; - - // Fourth line of keyboard: - HWScanKeyMap[0x3a] = SDLK_CAPSLOCK; - HWScanKeyMap[0x1e] = SDLK_a; - HWScanKeyMap[0x1f] = SDLK_s; - HWScanKeyMap[0x20] = SDLK_d; - HWScanKeyMap[0x21] = SDLK_f; - HWScanKeyMap[0x22] = SDLK_g; - HWScanKeyMap[0x23] = SDLK_h; - HWScanKeyMap[0x24] = SDLK_j; - HWScanKeyMap[0x25] = SDLK_k; - HWScanKeyMap[0x26] = SDLK_l; - HWScanKeyMap[0x27] = SDLK_SEMICOLON; - HWScanKeyMap[0x28] = SDLK_QUOTE; - HWScanKeyMap[0x2b] = SDLK_BACKSLASH; - HWScanKeyMap[0x4b] = SDLK_KP4; - HWScanKeyMap[0x4c] = SDLK_KP5; - HWScanKeyMap[0x4d] = SDLK_KP6; - - // Fifth line of keyboard: - HWScanKeyMap[0x2a] = SDLK_LSHIFT; - HWScanKeyMap[0x56] = SDLK_WORLD_1; // Code 161, letter i' on hungarian keyboard - HWScanKeyMap[0x2c] = SDLK_z; - HWScanKeyMap[0x2d] = SDLK_x; - HWScanKeyMap[0x2e] = SDLK_c; - HWScanKeyMap[0x2f] = SDLK_v; - HWScanKeyMap[0x30] = SDLK_b; - HWScanKeyMap[0x31] = SDLK_n; - HWScanKeyMap[0x32] = SDLK_m; - HWScanKeyMap[0x33] = SDLK_COMMA; - HWScanKeyMap[0x34] = SDLK_PERIOD; - HWScanKeyMap[0x35] = SDLK_SLASH; - HWScanKeyMap[0x36] = SDLK_RSHIFT; - HWScanKeyMap[0x61] = SDLK_UP; - HWScanKeyMap[0x4f] = SDLK_KP1; - HWScanKeyMap[0x50] = SDLK_KP2; - HWScanKeyMap[0x51] = SDLK_KP3; - HWScanKeyMap[0x5a] = SDLK_KP_ENTER; - - // Sixth line of keyboard: - HWScanKeyMap[0x1d] = SDLK_LCTRL; - HWScanKeyMap[0x7e] = SDLK_LSUPER; // Windows key - HWScanKeyMap[0x38] = SDLK_LALT; - HWScanKeyMap[0x39] = SDLK_SPACE; - HWScanKeyMap[0x5e] = SDLK_RALT; // Actually, altgr on my keyboard... - HWScanKeyMap[0x7f] = SDLK_RSUPER; - HWScanKeyMap[0x7c] = SDLK_MENU; - HWScanKeyMap[0x5b] = SDLK_RCTRL; - HWScanKeyMap[0x63] = SDLK_LEFT; - HWScanKeyMap[0x66] = SDLK_DOWN; - HWScanKeyMap[0x64] = SDLK_RIGHT; - HWScanKeyMap[0x52] = SDLK_KP0; - HWScanKeyMap[0x53] = SDLK_KP_PERIOD; -} - - -/* Iconify the window. - This function returns 1 if there is a window manager and the - window was actually iconified, it returns 0 otherwise. - */ -int -os2fslib_IconifyWindow(_THIS) -{ - HAB hab; - HMQ hmq; - ERRORID hmqerror; - - // If there is no more window, nothing we can do! - if (_this->hidden->iPMThreadStatus != 1) - return 0; - - // Cannot do anything in fullscreen mode! - if (FSLib_QueryFSMode(_this->hidden->hwndClient)) - return 0; - - // Make sure this thread is prepared for using the Presentation Manager! - hab = WinInitialize(0); - hmq = WinCreateMsgQueue(hab, 0); - // Remember if there was an error at WinCreateMsgQueue(), because we don't - // want to destroy somebody else's queue later. :) - hmqerror = WinGetLastError(hab); - - WinSetWindowPos(_this->hidden->hwndFrame, HWND_TOP, - 0, 0, 0, 0, SWP_MINIMIZE); - - // Now destroy the message queue, if we've created it! - if (ERRORIDERROR(hmqerror) == 0) - WinDestroyMsgQueue(hmq); - - return 1; -} - -static SDL_GrabMode -os2fslib_GrabInput(_THIS, SDL_GrabMode mode) -{ - HAB hab; - HMQ hmq; - ERRORID hmqerror; - - - // If there is no more window, nothing we can do! - if (_this->hidden->iPMThreadStatus != 1) - return SDL_GRAB_OFF; - - // Make sure this thread is prepared for using the Presentation Manager! - hab = WinInitialize(0); - hmq = WinCreateMsgQueue(hab, 0); - // Remember if there was an error at WinCreateMsgQueue(), because we don't - // want to destroy somebody else's queue later. :) - hmqerror = WinGetLastError(hab); - - - if (mode == SDL_GRAB_OFF) { -#ifdef DEBUG_BUILD - printf("[os2fslib_GrabInput] : Releasing mouse\n"); - fflush(stdout); -#endif - - // Release the mouse - bMouseCapturable = 0; - if (bMouseCaptured) { - WinSetCapture(HWND_DESKTOP, NULLHANDLE); - bMouseCaptured = 0; - } - } else { -#ifdef DEBUG_BUILD - printf("[os2fslib_GrabInput] : Capturing mouse\n"); - fflush(stdout); -#endif - - // Capture the mouse - bMouseCapturable = 1; - if (WinQueryFocus(HWND_DESKTOP) == _this->hidden->hwndClient) { - WinSetCapture(HWND_DESKTOP, _this->hidden->hwndClient); - bMouseCaptured = 1; - { - SWP swpClient; - POINTL ptl; - // Center the mouse to the middle of the window! - WinQueryWindowPos(_this->hidden->hwndClient, &swpClient); - ptl.x = 0; - ptl.y = 0; - WinMapWindowPoints(_this->hidden->hwndClient, - HWND_DESKTOP, &ptl, 1); - _this->hidden->iSkipWMMOUSEMOVE++; /* Don't take next WM_MOUSEMOVE into account! */ - WinSetPointerPos(HWND_DESKTOP, - ptl.x + swpClient.cx / 2, - ptl.y + swpClient.cy / 2); - } - } - } - - // Now destroy the message queue, if we've created it! - if (ERRORIDERROR(hmqerror) == 0) - WinDestroyMsgQueue(hmq); - - return mode; -} - -/* Set the title and icon text */ -static void -os2fslib_SetCaption(_THIS, const char *title, const char *icon) -{ - HAB hab; - HMQ hmq; - ERRORID hmqerror; - - // If there is no more window, nothing we can do! - if (_this->hidden->iPMThreadStatus != 1) - return; - - // Make sure this thread is prepared for using the Presentation Manager! - hab = WinInitialize(0); - hmq = WinCreateMsgQueue(hab, 0); - // Remember if there was an error at WinCreateMsgQueue(), because we don't - // want to destroy somebody else's queue later. :) - hmqerror = WinGetLastError(hab); - - WinSetWindowText(_this->hidden->hwndFrame, (char *) title); - - // Now destroy the message queue, if we've created it! - if (ERRORIDERROR(hmqerror) == 0) - WinDestroyMsgQueue(hmq); -} - -static int -os2fslib_ToggleFullScreen(_THIS, int on) -{ -#ifdef DEBUG_BUILD - printf("[os2fslib_ToggleFullScreen] : %d\n", on); - fflush(stdout); -#endif - // If there is no more window, nothing we can do! - if (_this->hidden->iPMThreadStatus != 1) - return 0; - - FSLib_ToggleFSMode(_this->hidden->hwndClient, on); - /* Cursor manager functions to Windowed/FS mode */ - os2fslib_SetCursorManagementFunctions(_this, !on); - return 1; -} - -/* This is called after the video mode has been set, to get the - initial mouse state. It should queue events as necessary to - properly represent the current mouse focus and position. - */ -static void -os2fslib_UpdateMouse(_THIS) -{ - POINTL ptl; - HAB hab; - HMQ hmq; - ERRORID hmqerror; - SWP swpClient; - - // If there is no more window, nothing we can do! - if (_this->hidden->iPMThreadStatus != 1) - return; - - - // Make sure this thread is prepared for using the Presentation Manager! - hab = WinInitialize(0); - hmq = WinCreateMsgQueue(hab, 0); - // Remember if there was an error at WinCreateMsgQueue(), because we don't - // want to destroy somebody else's queue later. :) - hmqerror = WinGetLastError(hab); - - - - if (_this->hidden->fInFocus) { - // If our app is in focus - SDL_PrivateAppActive(1, SDL_APPMOUSEFOCUS); - SDL_PrivateAppActive(1, SDL_APPINPUTFOCUS); - SDL_PrivateAppActive(1, SDL_APPACTIVE); - WinQueryPointerPos(HWND_DESKTOP, &ptl); - WinMapWindowPoints(HWND_DESKTOP, _this->hidden->hwndClient, &ptl, 1); - WinQueryWindowPos(_this->hidden->hwndClient, &swpClient); - // Convert OS/2 mouse position to SDL position, and also scale it! - ptl.x = - ptl.x * _this->hidden->SrcBufferDesc.uiXResolution / swpClient.cx; - ptl.y = - ptl.y * _this->hidden->SrcBufferDesc.uiYResolution / swpClient.cy; - ptl.y = _this->hidden->SrcBufferDesc.uiYResolution - ptl.y - 1; - SDL_PrivateMouseMotion(0, 0, (Sint16) (ptl.x), (Sint16) (ptl.y)); - } else { - // If we're not in focus - SDL_PrivateAppActive(0, SDL_APPMOUSEFOCUS); - SDL_PrivateAppActive(0, SDL_APPINPUTFOCUS); - SDL_PrivateAppActive(0, SDL_APPACTIVE); - SDL_PrivateMouseMotion(0, 0, (Sint16) - 1, (Sint16) - 1); - } - - // Now destroy the message queue, if we've created it! - if (ERRORIDERROR(hmqerror) == 0) - WinDestroyMsgQueue(hmq); - -} - -/* This pointer should exist in the native video subsystem and should - point to an appropriate update function for the current video mode - */ -static void -os2fslib_UpdateRects(_THIS, int numrects, SDL_Rect * rects) -{ - // If there is no more window, nothing we can do! - if (_this->hidden->iPMThreadStatus != 1) - return; - -#ifdef BITBLT_IN_WINMESSAGEPROC - WinSendMsg(_this->hidden->hwndClient, - WM_UPDATERECTSREQUEST, (MPARAM) numrects, (MPARAM) rects); -#else - if (DosRequestMutexSem - (_this->hidden->hmtxUseSrcBuffer, SEM_INDEFINITE_WAIT) == NO_ERROR) { - int i; - - if (_this->hidden->pSDLSurface) { -#ifndef RESIZE_EVEN_IF_RESIZABLE - SWP swp; - // But only blit if the window is not resizable, or if - // the window is resizable and the source buffer size is the - // same as the destination buffer size! - WinQueryWindowPos(_this->hidden->hwndClient, &swp); - if ((_this->hidden->pSDLSurface) && - (_this->hidden->pSDLSurface->flags & SDL_RESIZABLE) && - ((swp.cx != _this->hidden->SrcBufferDesc.uiXResolution) || - (swp.cy != _this->hidden->SrcBufferDesc.uiYResolution)) - && (!FSLib_QueryFSMode(_this->hidden->hwndClient))) { - // Resizable surface and in resizing! - // So, don't blit now! -#ifdef DEBUG_BUILD - printf("[UpdateRects] : Skipping blit while resizing!\n"); - fflush(stdout); -#endif - } else -#endif - { - /* - // Blit the whole window - FSLIB_BITBLT(_this->hidden->hwndClient, _this->hidden->pchSrcBuffer, - 0, 0, - _this->hidden->SrcBufferDesc.uiXResolution, - _this->hidden->SrcBufferDesc.uiYResolution); - */ -#ifdef DEBUG_BUILD - printf("[os2fslib_UpdateRects] : Blitting!\n"); - fflush(stdout); -#endif - - // Blit the changed areas - for (i = 0; i < numrects; i++) - FSLIB_BITBLT(_this->hidden->hwndClient, - _this->hidden->pchSrcBuffer, - rects[i].y, rects[i].x, rects[i].w, - rects[i].h); - } - } -#ifdef DEBUG_BUILD - else - printf("[os2fslib_UpdateRects] : No public surface!\n"); - fflush(stdout); -#endif - DosReleaseMutexSem(_this->hidden->hmtxUseSrcBuffer); - } -#ifdef DEBUG_BUILD - else - printf("[os2fslib_UpdateRects] : Error in mutex!\n"); - fflush(stdout); -#endif -#endif -} - - -/* Reverse the effects VideoInit() -- called if VideoInit() fails - or if the application is shutting down the video subsystem. - */ -static void -os2fslib_VideoQuit(_THIS) -{ -#ifdef DEBUG_BUILD - printf("[os2fslib_VideoQuit]\n"); - fflush(stdout); -#endif - // Close PM stuff if running! - if (_this->hidden->iPMThreadStatus == 1) { - int iTimeout; - WinPostMsg(_this->hidden->hwndFrame, WM_QUIT, (MPARAM) 0, (MPARAM) 0); - // HACK: We had this line before: - //DosWaitThread((TID *) &(_this->hidden->tidPMThread), DCWW_WAIT); - // We don't use it, because the PMThread will never stop, or if it stops, - // it will kill the whole process as a emergency fallback. - // So, we only check for the iPMThreadStatus stuff! -#ifdef DEBUG_BUILD - printf("[os2fslib_VideoQuit] : Waiting for PM thread to die\n"); - fflush(stdout); -#endif - - iTimeout = 0; - while ((_this->hidden->iPMThreadStatus == 1) && (iTimeout < 100)) { - iTimeout++; - DosSleep(64); - } - -#ifdef DEBUG_BUILD - printf("[os2fslib_VideoQuit] : End of wait.\n"); - fflush(stdout); -#endif - - if (_this->hidden->iPMThreadStatus == 1) { -#ifdef DEBUG_BUILD - printf("[os2fslib_VideoQuit] : Killing PM thread!\n"); - fflush(stdout); -#endif - - _this->hidden->iPMThreadStatus = 0; - DosKillThread(_this->hidden->tidPMThread); - - if (_this->hidden->hwndFrame) { -#ifdef DEBUG_BUILD - printf("[os2fslib_VideoQuit] : Destroying PM window!\n"); - fflush(stdout); -#endif - - WinDestroyWindow(_this->hidden->hwndFrame); - _this->hidden->hwndFrame = NULL; - } - } - - } - // Free result of an old ListModes() call, because there is - // no FreeListModes() call in SDL! - if (_this->hidden->pListModesResult) { - SDL_free(_this->hidden->pListModesResult); - _this->hidden->pListModesResult = NULL; - } - // Free list of available fullscreen modes - if (_this->hidden->pAvailableFSLibVideoModes) { - FSLib_FreeVideoModeList(_this->hidden->pAvailableFSLibVideoModes); - _this->hidden->pAvailableFSLibVideoModes = NULL; - } - // Free application icon if we had one - if (hptrCurrentIcon) { - WinDestroyPointer(hptrCurrentIcon); - hptrCurrentIcon = NULL; - } -} - -/* Set the requested video mode, returning a surface which will be - set to the SDL_VideoSurface. The width and height will already - be verified by ListModes(), and the video subsystem is free to - set the mode to a supported bit depth different from the one - specified -- the desired bpp will be emulated with a shadow - surface if necessary. If a new mode is returned, this function - should take care of cleaning up the current mode. - */ -static SDL_Surface * -os2fslib_SetVideoMode(_THIS, SDL_Surface * current, - int width, int height, int bpp, Uint32 flags) -{ - static int bFirstCall = 1; - FSLib_VideoMode_p pModeInfo, pModeInfoFound; - FSLib_VideoMode TempModeInfo; - HAB hab; - HMQ hmq; - ERRORID hmqerror; - RECTL rectl; - SDL_Surface *pResult; - - // If there is no more window, nothing we can do! - if (_this->hidden->iPMThreadStatus != 1) - return NULL; - -#ifdef DEBUG_BUILD - printf - ("[os2fslib_SetVideoMode] : Request for %dx%d @ %dBPP, flags=0x%x\n", - width, height, bpp, flags); - fflush(stdout); -#endif - - // We don't support palette modes! - if (bpp == 8) - bpp = 32; - - // Also, we don't support resizable modes in fullscreen mode. - if (flags & SDL_RESIZABLE) - flags &= ~SDL_FULLSCREEN; - - // No double buffered mode - if (flags & SDL_DOUBLEBUF) - flags &= ~SDL_DOUBLEBUF; - - // And, we don't support HWSURFACE yet. - if (flags & SDL_HWSURFACE) { - flags &= ~SDL_HWSURFACE; - flags |= SDL_SWSURFACE; - } -#ifdef DEBUG_BUILD - printf - ("[os2fslib_SetVideoMode] : Changed request to %dx%d @ %dBPP, flags=0x%x\n", - width, height, bpp, flags); - fflush(stdout); -#endif - - // First check if there is such a video mode they want! - pModeInfoFound = NULL; - - // For fullscreen mode we don't support every resolution! - // So, go through the video modes, and check for such a resolution! - pModeInfoFound = NULL; - pModeInfo = _this->hidden->pAvailableFSLibVideoModes; - - while (pModeInfo) { - // Check all available fullscreen modes for this resolution - if ((pModeInfo->uiXResolution == width) && (pModeInfo->uiYResolution == height) && (pModeInfo->uiBPP != 8)) // palettized modes not yet supported - { - // If good resolution, try to find the exact BPP, or at least - // something similar... - if (!pModeInfoFound) - pModeInfoFound = pModeInfo; - else if ((pModeInfoFound->uiBPP != bpp) && - (pModeInfoFound->uiBPP < pModeInfo->uiBPP)) - pModeInfoFound = pModeInfo; - } - pModeInfo = pModeInfo->pNext; - } - - // If we did not find a good fullscreen mode, then try a similar - if (!pModeInfoFound) { -#ifdef DEBUG_BUILD - printf - ("[os2fslib_SetVideoMode] : Requested video mode not found, looking for a similar one!\n"); - fflush(stdout); -#endif - // Go through the video modes again, and find a similar resolution! - pModeInfo = _this->hidden->pAvailableFSLibVideoModes; - while (pModeInfo) { - // Check all available fullscreen modes for this resolution - if ((pModeInfo->uiXResolution >= width) && - (pModeInfo->uiYResolution >= height) && - (pModeInfo->uiBPP == bpp)) { - if (!pModeInfoFound) - pModeInfoFound = pModeInfo; - else if (((pModeInfoFound->uiXResolution - - width) * (pModeInfoFound->uiYResolution - - height)) > - ((pModeInfo->uiXResolution - - width) * (pModeInfo->uiYResolution - height))) { - // Found a mode which is closer than the current one - pModeInfoFound = pModeInfo; - } - } - pModeInfo = pModeInfo->pNext; - } - } - // If we did not find a good fullscreen mode, then return NULL - if (!pModeInfoFound) { -#ifdef DEBUG_BUILD - printf("[os2fslib_SetVideoMode] : Requested video mode not found!\n"); - fflush(stdout); -#endif - return NULL; - } -#ifdef DEBUG_BUILD - printf("[os2fslib_SetVideoMode] : Found mode!\n"); - fflush(stdout); -#endif - - // We'll possibly adjust the structure, so copy out the values - // into TempModeInfo! - SDL_memcpy(&TempModeInfo, pModeInfoFound, sizeof(TempModeInfo)); - pModeInfoFound = &TempModeInfo; - - if (flags & SDL_RESIZABLE) { -#ifdef DEBUG_BUILD - printf - ("[os2fslib_SetVideoMode] : Requested mode is resizable, changing width/height\n"); - fflush(stdout); -#endif - // Change width and height to requested one! - TempModeInfo.uiXResolution = width; - TempModeInfo.uiYResolution = height; - TempModeInfo.uiScanLineSize = width * ((TempModeInfo.uiBPP + 7) / 8); - } - // We can try create new surface! - - // Make sure this thread is prepared for using the Presentation Manager! - hab = WinInitialize(0); - hmq = WinCreateMsgQueue(hab, 0); - // Remember if there was an error at WinCreateMsgQueue(), because we don't - // want to destroy somebody else's queue later. :) - hmqerror = WinGetLastError(hab); - - - - if (DosRequestMutexSem - (_this->hidden->hmtxUseSrcBuffer, SEM_INDEFINITE_WAIT) == NO_ERROR) { -#ifdef DEBUG_BUILD - printf("[os2fslib_SetVideoMode] : Creating new SW surface\n"); - fflush(stdout); -#endif - - // Create new software surface! - pResult = SDL_CreateRGBSurface(SDL_SWSURFACE, - pModeInfoFound->uiXResolution, - pModeInfoFound->uiYResolution, - pModeInfoFound->uiBPP, ((unsigned int) - pModeInfoFound-> - PixelFormat. - ucRedMask) - << pModeInfoFound->PixelFormat. - ucRedPosition, ((unsigned int) - pModeInfoFound-> - PixelFormat. - ucGreenMask) - << pModeInfoFound->PixelFormat. - ucGreenPosition, ((unsigned int) - pModeInfoFound-> - PixelFormat. - ucBlueMask) - << pModeInfoFound->PixelFormat. - ucBluePosition, ((unsigned int) - pModeInfoFound-> - PixelFormat. - ucAlphaMask) - << pModeInfoFound->PixelFormat. - ucAlphaPosition); - - if (pResult == NULL) { - DosReleaseMutexSem(_this->hidden->hmtxUseSrcBuffer); - SDL_OutOfMemory(); - return NULL; - } -#ifdef DEBUG_BUILD - printf("[os2fslib_SetVideoMode] : Adjusting pixel format\n"); - fflush(stdout); -#endif - - // Adjust pixel format mask! - pResult->format->Rmask = - ((unsigned int) pModeInfoFound-> - PixelFormat.ucRedMask) << pModeInfoFound->PixelFormat. - ucRedPosition; - pResult->format->Rshift = pModeInfoFound->PixelFormat.ucRedPosition; - pResult->format->Rloss = pModeInfoFound->PixelFormat.ucRedAdjust; - pResult->format->Gmask = - ((unsigned int) pModeInfoFound-> - PixelFormat.ucGreenMask) << pModeInfoFound->PixelFormat. - ucGreenPosition; - pResult->format->Gshift = pModeInfoFound->PixelFormat.ucGreenPosition; - pResult->format->Gloss = pModeInfoFound->PixelFormat.ucGreenAdjust; - pResult->format->Bmask = - ((unsigned int) pModeInfoFound-> - PixelFormat.ucBlueMask) << pModeInfoFound->PixelFormat. - ucBluePosition; - pResult->format->Bshift = pModeInfoFound->PixelFormat.ucBluePosition; - pResult->format->Bloss = pModeInfoFound->PixelFormat.ucBlueAdjust; - pResult->format->Amask = - ((unsigned int) pModeInfoFound-> - PixelFormat.ucAlphaMask) << pModeInfoFound->PixelFormat. - ucAlphaPosition; - pResult->format->Ashift = pModeInfoFound->PixelFormat.ucAlphaPosition; - pResult->format->Aloss = pModeInfoFound->PixelFormat.ucAlphaAdjust; - -#ifdef REPORT_EMPTY_ALPHA_MASK - pResult->format->Amask = - pResult->format->Ashift = pResult->format->Aloss = 0; -#endif - - // Adjust surface flags - pResult->flags |= (flags & SDL_FULLSCREEN); - pResult->flags |= (flags & SDL_RESIZABLE); - - // It might be that the software surface pitch is not the same as - // the pitch we have, so adjust that! - pModeInfoFound->uiScanLineSize = pResult->pitch; - - // Store new source buffer parameters! - SDL_memcpy(&(_this->hidden->SrcBufferDesc), pModeInfoFound, - sizeof(*pModeInfoFound)); - _this->hidden->pchSrcBuffer = pResult->pixels; - -#ifdef DEBUG_BUILD - printf("[os2fslib_SetVideoMode] : Telling FSLib the stuffs\n"); - fflush(stdout); -#endif - - // Tell the FSLib window the new source image format - FSLib_SetSrcBufferDesc(_this->hidden->hwndClient, - &(_this->hidden->SrcBufferDesc)); - - if (((flags & SDL_RESIZABLE) == 0) || (bFirstCall)) { - bFirstCall = 0; -#ifdef DEBUG_BUILD - printf("[os2fslib_SetVideoMode] : Modifying window size\n"); - fflush(stdout); -#endif - - // Calculate frame window size from client window size - rectl.xLeft = 0; - rectl.yBottom = 0; - rectl.xRight = pModeInfoFound->uiXResolution; // Noninclusive - rectl.yTop = pModeInfoFound->uiYResolution; // Noninclusive - WinCalcFrameRect(_this->hidden->hwndFrame, &rectl, FALSE); - - // Set the new size of the main window - SetAccessableWindowPos(_this->hidden->hwndFrame, - HWND_TOP, - 0, 0, - (rectl.xRight - rectl.xLeft), - (rectl.yTop - rectl.yBottom), - SWP_SIZE | SWP_ACTIVATE | SWP_SHOW); - } - // Set fullscreen mode flag, and switch to fullscreen if needed! - if (flags & SDL_FULLSCREEN) { -#ifdef DEBUG_BUILD - printf - ("[os2fslib_SetVideoMode] : Also trying to switch to fullscreen\n"); - fflush(stdout); -#endif - FSLib_ToggleFSMode(_this->hidden->hwndClient, 1); - /* Cursor manager functions to FS mode */ - os2fslib_SetCursorManagementFunctions(_this, 0); - } else { -#ifdef DEBUG_BUILD - printf - ("[os2fslib_SetVideoMode] : Also trying to switch to desktop mode\n"); - fflush(stdout); -#endif - FSLib_ToggleFSMode(_this->hidden->hwndClient, 0); - /* Cursor manager functions to Windowed mode */ - os2fslib_SetCursorManagementFunctions(_this, 1); - } - - _this->hidden->pSDLSurface = pResult; - - DosReleaseMutexSem(_this->hidden->hmtxUseSrcBuffer); - } else { -#ifdef DEBUG_BUILD - printf("[os2fslib_SetVideoMode] : Could not get hmtxUseSrcBuffer!\n"); - fflush(stdout); -#endif - - pResult = NULL; - } - - // As we have the new surface, we don't need the current one anymore! - if ((pResult) && (current)) { -#ifdef DEBUG_BUILD - printf("[os2fslib_SetVideoMode] : Freeing old surface\n"); - fflush(stdout); -#endif - SDL_FreeSurface(current); - } - // Redraw window - WinInvalidateRegion(_this->hidden->hwndClient, NULL, TRUE); - - // Now destroy the message queue, if we've created it! - if (ERRORIDERROR(hmqerror) == 0) { -#ifdef DEBUG_BUILD - printf("[os2fslib_SetVideoMode] : Destroying message queue\n"); - fflush(stdout); -#endif - WinDestroyMsgQueue(hmq); - } -#ifdef DEBUG_BUILD - printf("[os2fslib_SetVideoMode] : Done\n"); - fflush(stdout); -#endif - - /* We're done */ - - // Return with the new surface! - return pResult; -} - -/* List the available video modes for the given pixel format, sorted - from largest to smallest. - */ -static SDL_Rect ** -os2fslib_ListModes(_THIS, SDL_PixelFormat * format, Uint32 flags) -{ -#ifdef DEBUG_BUILD - printf("[os2fslib_ListModes] : ListModes of %d Bpp\n", - format->BitsPerPixel); -#endif - // Destroy result of previous call, if there is any - if (_this->hidden->pListModesResult) { - SDL_free(_this->hidden->pListModesResult); - _this->hidden->pListModesResult = NULL; - } - // For resizable and windowed mode we support every resolution! - if ((flags & SDL_RESIZABLE) && ((flags & SDL_FULLSCREEN) == 0)) - return (SDL_Rect **) - 1; - - // Check if they need fullscreen or non-fullscreen video modes! - if ((flags & SDL_FULLSCREEN) == 0) { - // For windowed mode we support every resolution! - return (SDL_Rect **) - 1; - } else { - FSLib_VideoMode_p pFSMode; - // For fullscreen mode we don't support every resolution! - // Now create a new list - pFSMode = _this->hidden->pAvailableFSLibVideoModes; - while (pFSMode) { - if (pFSMode->uiBPP == format->BitsPerPixel) { - SDL_Rect *pRect = (SDL_Rect *) SDL_malloc(sizeof(SDL_Rect)); - if (pRect) { - // Fill description - pRect->x = 0; - pRect->y = 0; - pRect->w = pFSMode->uiXResolution; - pRect->h = pFSMode->uiYResolution; -#ifdef DEBUG_BUILD -// printf("!!! Seems to be good!\n"); -// printf("F: %dx%d\n", pRect->w, pRect->h); -#endif - // And insert into list of pRects - if (!(_this->hidden->pListModesResult)) { -#ifdef DEBUG_BUILD -// printf("!!! Inserting to beginning\n"); -#endif - - // We're the first one to be inserted! - _this->hidden->pListModesResult = - (SDL_Rect **) SDL_malloc(2 * sizeof(SDL_Rect *)); - if (_this->hidden->pListModesResult) { - _this->hidden->pListModesResult[0] = pRect; - _this->hidden->pListModesResult[1] = NULL; - } else { - SDL_free(pRect); - } - } else { - // We're not the first ones, so find the place where we - // have to insert ourselves - SDL_Rect **pNewList; - int iPlace, iNumOfSlots, i; - -#ifdef DEBUG_BUILD -// printf("!!! Searching where to insert\n"); -#endif - - iPlace = -1; - iNumOfSlots = 1; // Count the last NULL too! - for (i = 0; _this->hidden->pListModesResult[i]; i++) { - iNumOfSlots++; - if (iPlace == -1) { - if ((_this->hidden->pListModesResult[i]->w * - _this->hidden->pListModesResult[i]->h) < - (pRect->w * pRect->h)) { - iPlace = i; - } - } - } - if (iPlace == -1) - iPlace = iNumOfSlots - 1; - -#ifdef DEBUG_BUILD -// printf("!!! From %d slots, it will be at %d\n", iNumOfSlots, iPlace); -#endif - - pNewList = (SDL_Rect **) - SDL_realloc(_this->hidden->pListModesResult, - (iNumOfSlots + - 1) * sizeof(SDL_Rect *)); - if (pNewList) { - for (i = iNumOfSlots; i > iPlace; i--) - pNewList[i] = pNewList[i - 1]; - pNewList[iPlace] = pRect; - _this->hidden->pListModesResult = pNewList; - } else { - SDL_free(pRect); - } - } - } - } - pFSMode = pFSMode->pNext; - } - } -#ifdef DEBUG_BUILD -// printf("Returning list\n"); -#endif - return _this->hidden->pListModesResult; -} - -/* Initialize the native video subsystem, filling 'vformat' with the - "best" display pixel format, returning 0 or -1 if there's an error. - */ -static int -os2fslib_VideoInit(_THIS, SDL_PixelFormat * vformat) -{ - FSLib_VideoMode_p pDesktopMode; - -#ifdef DEBUG_BUILD - printf("[os2fslib_VideoInit] : Enter\n"); - fflush(stdout); -#endif - - // Report the best pixel format. For this, - // we'll use the current desktop format. - pDesktopMode = FSLib_GetDesktopVideoMode(); - if (!pDesktopMode) { - SDL_SetError("Could not query desktop video mode!"); -#ifdef DEBUG_BUILD - printf - ("[os2fslib_VideoInit] : Could not query desktop video mode!\n"); -#endif - return -1; - } - - /* Determine the current screen size */ - _this->info.current_w = pDesktopMode->uiXResolution; - _this->info.current_h = pDesktopMode->uiYResolution; - - /* Determine the screen depth */ - vformat->BitsPerPixel = pDesktopMode->uiBPP; - vformat->BytesPerPixel = (vformat->BitsPerPixel + 7) / 8; - - vformat->Rmask = - ((unsigned int) pDesktopMode->PixelFormat. - ucRedMask) << pDesktopMode->PixelFormat.ucRedPosition; - vformat->Rshift = pDesktopMode->PixelFormat.ucRedPosition; - vformat->Rloss = pDesktopMode->PixelFormat.ucRedAdjust; - vformat->Gmask = - ((unsigned int) pDesktopMode-> - PixelFormat.ucGreenMask) << pDesktopMode->PixelFormat. - ucGreenPosition; - vformat->Gshift = pDesktopMode->PixelFormat.ucGreenPosition; - vformat->Gloss = pDesktopMode->PixelFormat.ucGreenAdjust; - vformat->Bmask = - ((unsigned int) pDesktopMode-> - PixelFormat.ucBlueMask) << pDesktopMode->PixelFormat.ucBluePosition; - vformat->Bshift = pDesktopMode->PixelFormat.ucBluePosition; - vformat->Bloss = pDesktopMode->PixelFormat.ucBlueAdjust; - vformat->Amask = - ((unsigned int) pDesktopMode-> - PixelFormat.ucAlphaMask) << pDesktopMode->PixelFormat. - ucAlphaPosition; - vformat->Ashift = pDesktopMode->PixelFormat.ucAlphaPosition; - vformat->Aloss = pDesktopMode->PixelFormat.ucAlphaAdjust; - -#ifdef REPORT_EMPTY_ALPHA_MASK - vformat->Amask = vformat->Ashift = vformat->Aloss = 0; -#endif - - // Fill in some window manager capabilities - _this->info.wm_available = 1; - - // Initialize some internal variables - _this->hidden->pListModesResult = NULL; - _this->hidden->fInFocus = 0; - _this->hidden->iSkipWMMOUSEMOVE = 0; - _this->hidden->iMouseVisible = 1; - - if (getenv("SDL_USE_PROPORTIONAL_WINDOW")) - _this->hidden->bProportionalResize = 1; - else { - PPIB pib; - PTIB tib; - char *pchFileName, *pchTemp; - char achConfigFile[CCHMAXPATH]; - FILE *hFile; - - /* No environment variable to have proportional window. - * Ok, let's check if this executable is in config file! - */ - _this->hidden->bProportionalResize = 0; - - DosGetInfoBlocks(&tib, &pib); - pchTemp = pchFileName = pib->pib_pchcmd; - while (*pchTemp) { - if (*pchTemp == '\\') - pchFileName = pchTemp + 1; - pchTemp++; - } - if (getenv("HOME")) { - sprintf(achConfigFile, "%s\\.sdl.proportionals", getenv("HOME")); - hFile = fopen(achConfigFile, "rt"); - if (!hFile) { - /* Seems like the file cannot be opened or does not exist. - * Let's try to create it with defaults! - */ - hFile = fopen(achConfigFile, "wt"); - if (hFile) { - fprintf(hFile, - "; This file is a config file of SDL/2, containing\n"); - fprintf(hFile, - "; the list of executables that must have proportional\n"); - fprintf(hFile, "; windows.\n"); - fprintf(hFile, ";\n"); - fprintf(hFile, - "; You can add executable filenames into this file,\n"); - fprintf(hFile, - "; one under the other. If SDL finds that a given\n"); - fprintf(hFile, - "; program is in this list, then that application\n"); - fprintf(hFile, - "; will have proportional windows, just like if\n"); - fprintf(hFile, - "; the SET SDL_USE_PROPORTIONAL_WINDOW env. variable\n"); - fprintf(hFile, - "; would have been set for that process.\n"); - fprintf(hFile, ";\n"); - fprintf(hFile, "\n"); - fprintf(hFile, "dosbox.exe\n"); - fclose(hFile); - } - - hFile = fopen(achConfigFile, "rt"); - } - - if (hFile) { - while (fgets(achConfigFile, sizeof(achConfigFile), hFile)) { - /* Cut \n from end of string */ - - while (achConfigFile[strlen(achConfigFile) - 1] - == '\n') - achConfigFile[strlen(achConfigFile) - 1] = 0; - - /* Compare... */ - if (stricmp(achConfigFile, pchFileName) == 0) { - /* Found it in config file! */ - _this->hidden->bProportionalResize = 1; - break; - } - } - fclose(hFile); - } - } - } - - DosCreateMutexSem(NULL, &(_this->hidden->hmtxUseSrcBuffer), 0, FALSE); - - // Now create our window with a default size - - // For this, we select the first available fullscreen mode as - // current window size! - SDL_memcpy(&(_this->hidden->SrcBufferDesc), - _this->hidden->pAvailableFSLibVideoModes, - sizeof(_this->hidden->SrcBufferDesc)); - // Allocate new video buffer! - _this->hidden->pchSrcBuffer = - (char *) SDL_malloc(_this->hidden-> - pAvailableFSLibVideoModes->uiScanLineSize * - _this->hidden-> - pAvailableFSLibVideoModes->uiYResolution); - if (!_this->hidden->pchSrcBuffer) { -#ifdef DEBUG_BUILD - printf - ("[os2fslib_VideoInit] : Yikes, not enough memory for new video buffer!\n"); - fflush(stdout); -#endif - SDL_SetError("Not enough memory for new video buffer!\n"); - return -1; - } - // For this, we need a message processing thread. - // We'll create a new thread for this, which will do everything - // what is related to PM - _this->hidden->iPMThreadStatus = 0; - _this->hidden->tidPMThread = - _beginthread(PMThreadFunc, NULL, 65536, (void *) _this); - if (_this->hidden->tidPMThread <= 0) { -#ifdef DEBUG_BUILD - printf("[os2fslib_VideoInit] : Could not create PM thread!\n"); -#endif - SDL_SetError("Could not create PM thread"); - return -1; - } -#ifdef USE_DOSSETPRIORITY - // Burst the priority of PM Thread! - DosSetPriority(PRTYS_THREAD, PRTYC_TIMECRITICAL, 0, - _this->hidden->tidPMThread); -#endif - // Wait for the PM thread to initialize! - while (_this->hidden->iPMThreadStatus == 0) - DosSleep(32); - // If the PM thread could not set up everything, then - // report an error! - if (_this->hidden->iPMThreadStatus != 1) { -#ifdef DEBUG_BUILD - printf("[os2fslib_VideoInit] : PMThread reported an error : %d\n", - _this->hidden->iPMThreadStatus); -#endif - SDL_SetError("Error initializing PM thread"); - return -1; - } - - return 0; -} - - -static void -os2fslib_DeleteDevice(_THIS) -{ -#ifdef DEBUG_BUILD - printf("[os2fslib_DeleteDevice]\n"); - fflush(stdout); -#endif - // Free used memory - FSLib_FreeVideoModeList(_this->hidden->pAvailableFSLibVideoModes); - if (_this->hidden->pListModesResult) - SDL_free(_this->hidden->pListModesResult); - if (_this->hidden->pchSrcBuffer) - SDL_free(_this->hidden->pchSrcBuffer); - DosCloseMutexSem(_this->hidden->hmtxUseSrcBuffer); - SDL_free(_this->hidden); - SDL_free(_this); - FSLib_Uninitialize(); -} - -static int -os2fslib_Available(void) -{ - - // If we can run, it means that we could load FSLib, - // so we assume that it's available then! - return 1; -} - -static void -os2fslib_MorphToPM() -{ - PPIB pib; - PTIB tib; - - DosGetInfoBlocks(&tib, &pib); - - // Change flag from VIO to PM: - if (pib->pib_ultype == 2) - pib->pib_ultype = 3; -} - -static SDL_VideoDevice * -os2fslib_CreateDevice(int devindex) -{ - SDL_VideoDevice *device; - -#ifdef DEBUG_BUILD - printf("[os2fslib_CreateDevice] : Enter\n"); - fflush(stdout); -#endif - - /* Initialize all variables that we clean on shutdown */ - device = (SDL_VideoDevice *) SDL_malloc(sizeof(SDL_VideoDevice)); - if (device) { - SDL_memset(device, 0, (sizeof *device)); - // Also allocate memory for private data - device->hidden = (struct SDL_PrivateVideoData *) - SDL_malloc((sizeof(struct SDL_PrivateVideoData))); - } - if ((device == NULL) || (device->hidden == NULL)) { - SDL_OutOfMemory(); - if (device) - SDL_free(device); - return NULL; - } - SDL_memset(device->hidden, 0, (sizeof *device->hidden)); - - /* Set the function pointers */ -#ifdef DEBUG_BUILD - printf("[os2fslib_CreateDevice] : VideoInit is %p\n", os2fslib_VideoInit); - fflush(stdout); -#endif - - /* Initialization/Query functions */ - device->VideoInit = os2fslib_VideoInit; - device->ListModes = os2fslib_ListModes; - device->SetVideoMode = os2fslib_SetVideoMode; - device->ToggleFullScreen = os2fslib_ToggleFullScreen; - device->UpdateMouse = os2fslib_UpdateMouse; - device->CreateYUVOverlay = NULL; - device->SetColors = os2fslib_SetColors; - device->UpdateRects = os2fslib_UpdateRects; - device->VideoQuit = os2fslib_VideoQuit; - /* Hardware acceleration functions */ - device->AllocHWSurface = os2fslib_AllocHWSurface; - device->CheckHWBlit = NULL; - device->FillHWRect = NULL; - device->SetHWColorKey = NULL; - device->SetHWAlpha = NULL; - device->LockHWSurface = os2fslib_LockHWSurface; - device->UnlockHWSurface = os2fslib_UnlockHWSurface; - device->FlipHWSurface = NULL; - device->FreeHWSurface = os2fslib_FreeHWSurface; - /* Window manager functions */ - device->SetCaption = os2fslib_SetCaption; - device->SetIcon = os2fslib_SetIcon; - device->IconifyWindow = os2fslib_IconifyWindow; - device->GrabInput = os2fslib_GrabInput; - device->GetWMInfo = NULL; - /* Cursor manager functions to Windowed mode */ - os2fslib_SetCursorManagementFunctions(device, 1); - /* Event manager functions */ - device->InitOSKeymap = os2fslib_InitOSKeymap; - device->PumpEvents = os2fslib_PumpEvents; - /* The function used to dispose of this structure */ - device->free = os2fslib_DeleteDevice; - - // Make sure we'll be able to use Win* API even if the application - // was linked to be a VIO application! - os2fslib_MorphToPM(); - - // Now initialize FSLib, and query available video modes! - if (!FSLib_Initialize()) { - // Could not initialize FSLib! -#ifdef DEBUG_BUILD - printf("[os2fslib_CreateDevice] : Could not initialize FSLib!\n"); -#endif - SDL_SetError("Could not initialize FSLib!"); - SDL_free(device->hidden); - SDL_free(device); - return NULL; - } - device->hidden->pAvailableFSLibVideoModes = FSLib_GetVideoModeList(); - - return device; -} - -VideoBootStrap OS2FSLib_bootstrap = { - "os2fslib", "OS/2 Video Output using FSLib", - os2fslib_Available, os2fslib_CreateDevice -}; - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/os2fslib/SDL_os2fslib.h b/src/video/os2fslib/SDL_os2fslib.h deleted file mode 100644 index 47a7fe2d4..000000000 --- a/src/video/os2fslib/SDL_os2fslib.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2009 Sam Lantinga - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - Sam Lantinga - slouken@libsdl.org -*/ -#include "SDL_config.h" - -#ifndef _SDL_os2fslib_h -#define _SDL_os2fslib_h - - -// OS2 specific includes -#define INCL_TYPES -#define INCL_DOS -#define INCL_DOSERRORS -#define INCL_DOSPROCESS -#define INCL_WIN -#define INCL_GPI -#include - -#include - -/* Hidden "this" pointer for the video functions */ -#define _THIS SDL_VideoDevice *_this - -/* Private display data */ -struct SDL_PrivateVideoData -{ - FSLib_VideoMode_p pAvailableFSLibVideoModes; - SDL_Rect **pListModesResult; // Allocated memory to return list of modes for os2fslib_ListModes() API - - FSLib_VideoMode SrcBufferDesc; // Description of current source image buffer - char *pchSrcBuffer; // The source image buffer itself - SDL_Surface *pSDLSurface; // The SDL surface describing the buffer - HMTX hmtxUseSrcBuffer; // Mutex semaphore to manipulate src buffer - HWND hwndFrame, hwndClient; // Window handle of frame and client - int iPMThreadStatus; // 0: Not running - // 1: Running - // Other: Not running, had an error - int tidPMThread; // Thread ID of PM Thread - int fInFocus; // True if we're in focus! - int iSkipWMMOUSEMOVE; // Number of WM_MOUSEMOVE messages to skip! - int iMouseVisible; // - - PFNWP pfnOldFrameProc; // Old window frame procedure - int bProportionalResize; // 0: No proportional resizing - // 1: Do proportional resizing - ULONG ulResizingFlag; // First resizing flag value -}; - -/* OS/2 specific backdoor function to be able to set FrameControlFlags of */ -/* the SDL window before creating it. */ -extern DECLSPEC void SDLCALL SDL_OS2FSLIB_SetFCFToUse(ULONG ulFCF); - -#endif /* _SDL_os2fslib_h */ -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/os2fslib/SDL_vkeys.h b/src/video/os2fslib/SDL_vkeys.h deleted file mode 100644 index 9ec9efafd..000000000 --- a/src/video/os2fslib/SDL_vkeys.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2009 Sam Lantinga - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - Sam Lantinga - slouken@libsdl.org -*/ - -#ifndef VK_0 -#define VK_0 '0' -#define VK_1 '1' -#define VK_2 '2' -#define VK_3 '3' -#define VK_4 '4' -#define VK_5 '5' -#define VK_6 '6' -#define VK_7 '7' -#define VK_8 '8' -#define VK_9 '9' -#define VK_A 'A' -#define VK_B 'B' -#define VK_C 'C' -#define VK_D 'D' -#define VK_E 'E' -#define VK_F 'F' -#define VK_G 'G' -#define VK_H 'H' -#define VK_I 'I' -#define VK_J 'J' -#define VK_K 'K' -#define VK_L 'L' -#define VK_M 'M' -#define VK_N 'N' -#define VK_O 'O' -#define VK_P 'P' -#define VK_Q 'Q' -#define VK_R 'R' -#define VK_S 'S' -#define VK_T 'T' -#define VK_U 'U' -#define VK_V 'V' -#define VK_W 'W' -#define VK_X 'X' -#define VK_Y 'Y' -#define VK_Z 'Z' -#endif /* VK_0 */ - -/* These keys haven't been defined, but were experimentally determined */ -#define VK_SEMICOLON 0xBA -#define VK_EQUALS 0xBB -#define VK_COMMA 0xBC -#define VK_MINUS 0xBD -#define VK_PERIOD 0xBE -#define VK_SLASH 0xBF -#define VK_GRAVE 0xC0 -#define VK_LBRACKET 0xDB -#define VK_BACKSLASH 0xDC -#define VK_RBRACKET 0xDD -#define VK_APOSTROPHE 0xDE -#define VK_BACKTICK 0xDF -/* vi: set ts=4 sw=4 expandtab: */